dbus参考代码--在一个dbus方法中调用另外一个dbus服务端提供的方法

ゝ一纸荒年。 2022-02-26 09:54 599阅读 1赞

这是在网上的代码基础上修改的,主要是项目中用到了dbus的嵌套调用,所以写了测试代码。贴出来供参考。

转载请注明:http://blog.csdn.net/shanzhizi

  1. /********************************************************************************/
  2. /*
  3. * Example low-level D-Bus code.
  4. * Written by Matthew Johnson <dbus@matthew.ath.cx>
  5. *
  6. * This code has been released into the Public Domain.
  7. * You may do whatever you like with it.
  8. */
  9. #include <dbus/dbus.h>
  10. #include <stdbool.h>
  11. #include <unistd.h>
  12. #include <stdio.h>
  13. #include <stdlib.h>
  14. DBusConnection* g_conn;
  15. /**http://blog.csdn.net/shanzhizi
  16. * Connect to the DBUS bus and send a broadcast signal
  17. */
  18. void sendsignal(char* sigvalue)
  19. {
  20. DBusMessage* msg;
  21. DBusMessageIter args;
  22. DBusConnection* conn;
  23. DBusError err;
  24. int ret;
  25. dbus_uint32_t serial = 0;
  26. printf("Sending signal with value %s\n", sigvalue);
  27. // initialise the error value
  28. dbus_error_init(&err);
  29. // connect to the DBUS system bus, and check for errors
  30. conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err);
  31. if (dbus_error_is_set(&err)) {
  32. fprintf(stderr, "Connection Error (%s)\n", err.message);
  33. dbus_error_free(&err);
  34. }
  35. if (NULL == conn) {
  36. exit(1);
  37. }
  38. // register our name on the bus, and check for errors
  39. ret = dbus_bus_request_name(conn, "test.signal.source", DBUS_NAME_FLAG_REPLACE_EXISTING , &err);
  40. if (dbus_error_is_set(&err)) {
  41. fprintf(stderr, "Name Error (%s)\n", err.message);
  42. dbus_error_free(&err);
  43. }
  44. if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) {
  45. exit(1);
  46. }
  47. // create a signal & check for errors
  48. msg = dbus_message_new_signal("/test/signal/Object", // object name of the signal
  49. "test.signal.Type", // interface name of the signal
  50. "Test"); // name of the signal
  51. if (NULL == msg)
  52. {
  53. fprintf(stderr, "Message Null\n");
  54. exit(1);
  55. }
  56. // append arguments onto signal
  57. dbus_message_iter_init_append(msg, &args);
  58. if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &sigvalue)) {
  59. fprintf(stderr, "Out Of Memory!\n");
  60. exit(1);
  61. }
  62. // send the message and flush the connection
  63. if (!dbus_connection_send(conn, msg, &serial)) {
  64. fprintf(stderr, "Out Of Memory!\n");
  65. exit(1);
  66. }
  67. dbus_connection_flush(conn);
  68. printf("Signal Sent\n");
  69. // free the message
  70. dbus_message_unref(msg);
  71. }
  72. /**
  73. * Call a method on a remote object
  74. */
  75. void query(char* param)
  76. {
  77. DBusMessage* msg;
  78. DBusMessageIter args;
  79. DBusConnection* conn;
  80. DBusError err;
  81. DBusPendingCall* pending;
  82. int ret;
  83. char *stat = "";
  84. dbus_uint32_t level;
  85. printf("Calling remote method with %s\n", param);
  86. // initialiset the errors
  87. dbus_error_init(&err);
  88. // connect to the system bus and check for errors
  89. conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err);
  90. if (dbus_error_is_set(&err)) {
  91. fprintf(stderr, "Connection Error (%s)\n", err.message);
  92. dbus_error_free(&err);
  93. }
  94. if (NULL == conn) {
  95. exit(1);
  96. }
  97. // request our name on the bus
  98. ret = dbus_bus_request_name(conn, "ws.method.cgi", DBUS_NAME_FLAG_REPLACE_EXISTING , &err);
  99. if (dbus_error_is_set(&err)) {
  100. fprintf(stderr, "Name Error (%s)\n", err.message);
  101. dbus_error_free(&err);
  102. }
  103. if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) {
  104. exit(1);
  105. }
  106. // create a new method call and check for errors
  107. msg = dbus_message_new_method_call("ws.method.listen",// target for the method call
  108. "/ws/method/object", // object to call on
  109. "ws.method.Type", // interface to call on
  110. "Method"); // method name
  111. if (NULL == msg) {
  112. fprintf(stderr, "Message Null\n");
  113. exit(1);
  114. }
  115. // append arguments
  116. dbus_message_iter_init_append(msg, &args);
  117. if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, m)) {
  118. fprintf(stderr, "Out Of Memory!\n");
  119. exit(1);
  120. }
  121. // send message and get a handle for a reply
  122. if (!dbus_connection_send_with_reply (conn, msg, &pending, -1)) { // -1 is default timeout
  123. fprintf(stderr, "Out Of Memory!\n");
  124. exit(1);
  125. }
  126. if (NULL == pending) {
  127. fprintf(stderr, "Pending Call Null\n");
  128. exit(1);
  129. }
  130. dbus_connection_flush(conn);
  131. printf("Request Sent\n");
  132. // free message
  133. dbus_message_unref(msg);
  134. // block until we recieve a reply
  135. dbus_pending_call_block(pending);
  136. // get the reply message
  137. msg = dbus_pending_call_steal_reply(pending);
  138. if (NULL == msg) {
  139. fprintf(stderr, "Reply Null\n");
  140. exit(1);
  141. }
  142. // free the pending message handle
  143. dbus_pending_call_unref(pending);
  144. // read the parameters
  145. if (!dbus_message_iter_init(msg, &args))
  146. fprintf(stderr, "Message has no arguments!\n");
  147. else if (DBUS_TYPE_STRING != dbus_message_iter_get_arg_type(&args))
  148. fprintf(stderr, "Argument is not boolean!\n");
  149. else
  150. dbus_message_iter_get_basic(&args, &stat);
  151. if (!dbus_message_iter_next(&args))
  152. fprintf(stderr, "Message has too few arguments!\n");
  153. else if (DBUS_TYPE_UINT32 != dbus_message_iter_get_arg_type(&args))
  154. fprintf(stderr, "Argument is not int!\n");
  155. else
  156. dbus_message_iter_get_basic(&args, &level);
  157. printf("Got Reply: %s, %d\n", stat, level);
  158. // free reply
  159. dbus_message_unref(msg);
  160. }
  161. /**http://blog.csdn.net/shanzhizi
  162. * Call a method on a remote object
  163. */
  164. void igmp_query(DBusConnection* conn,char* param)
  165. {
  166. DBusMessage* msg;
  167. DBusMessageIter args;
  168. DBusPendingCall* pending;
  169. int ret;
  170. char *stat="";
  171. dbus_uint32_t level;
  172. // create a new method call and check for errors
  173. msg = dbus_message_new_method_call("ws.method.igmp",// target for the method call
  174. "/ws/method/object", // object to call on
  175. "ws.method.Type", // interface to call on
  176. "Method"); // method name
  177. if (NULL == msg) {
  178. fprintf(stderr, "Message Null\n");
  179. exit(1);
  180. }
  181. // append arguments
  182. dbus_message_iter_init_append(msg, &args);
  183. if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, m)) {
  184. fprintf(stderr, "Out Of Memory!\n");
  185. exit(1);
  186. }
  187. // send message and get a handle for a reply
  188. if (!dbus_connection_send_with_reply (conn, msg, &pending, -1)) { // -1 is default timeout
  189. fprintf(stderr, "Out Of Memory!\n");
  190. exit(1);
  191. }
  192. if (NULL == pending) {
  193. fprintf(stderr, "Pending Call Null\n");
  194. exit(1);
  195. }
  196. dbus_connection_flush(conn);
  197. printf("igmp Request Sent\n");
  198. // free message
  199. dbus_message_unref(msg);
  200. // block until we recieve a reply
  201. dbus_pending_call_block(pending);
  202. // get the reply message
  203. msg = dbus_pending_call_steal_reply(pending);
  204. if (NULL == msg) {
  205. fprintf(stderr, "Reply Null\n");
  206. exit(1);
  207. }
  208. // free the pending message handle
  209. dbus_pending_call_unref(pending);
  210. // read the parameters
  211. if (!dbus_message_iter_init(msg, &args))
  212. fprintf(stderr, "Message has no arguments!\n");
  213. else if (DBUS_TYPE_STRING != dbus_message_iter_get_arg_type(&args))
  214. fprintf(stderr, "Argument is not boolean!\n");
  215. else
  216. dbus_message_iter_get_basic(&args, &stat);
  217. if (!dbus_message_iter_next(&args))
  218. fprintf(stderr, "Message has too few arguments!\n");
  219. else if (DBUS_TYPE_UINT32 != dbus_message_iter_get_arg_type(&args))
  220. fprintf(stderr, "Argument is not int!\n");
  221. else
  222. dbus_message_iter_get_basic(&args, &level);
  223. printf("Got Reply: %s, %d\n", stat, level);
  224. // free reply
  225. dbus_message_unref(msg);
  226. }
  227. DBusMessage *reply_to_method_call(DBusMessage* msg, void *user_data)
  228. {
  229. DBusMessage* reply;
  230. DBusMessageIter args;
  231. bool stat = true;
  232. dbus_uint32_t level = 10;
  233. dbus_uint32_t serial = 0;
  234. char* param = "";
  235. char returnstr[30]="cgi server return";
  236. char *ssparam = returnstr;
  237. // read the arguments
  238. if (!dbus_message_iter_init(msg, &args))
  239. fprintf(stderr, "Message has no arguments!\n");
  240. else if (DBUS_TYPE_STRING != dbus_message_iter_get_arg_type(&args))
  241. fprintf(stderr, "Argument is not string!\n");
  242. else
  243. dbus_message_iter_get_basic(&args, m);
  244. printf("Method called with %s\n", param);
  245. igmp_query(g_conn,"igmp");
  246. // create a reply from the message
  247. reply = dbus_message_new_method_return(msg);
  248. // add the arguments to the reply
  249. /*dbus_message_iter_init_append(reply, &args);
  250. if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &ssparam)) {
  251. fprintf(stderr, "Out Of Memory!\n");
  252. exit(1);
  253. }
  254. printf("******************\n");
  255. if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_UINT32, &level)) {
  256. fprintf(stderr, "Out Of Memory!\n");
  257. exit(1);
  258. } */
  259. dbus_message_append_args (reply,
  260. DBUS_TYPE_STRING,&ssparam,
  261. DBUS_TYPE_UINT32,&level,
  262. DBUS_TYPE_INVALID);
  263. return reply;
  264. }
  265. DBusHandlerResult ws_dbus_message_handler_listen(DBusConnection *connection, DBusMessage *message, void *user_data)
  266. {
  267. DBusMessage *reply = NULL;
  268. const char * path =dbus_message_get_path(message);
  269. if(NULL==path){
  270. return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
  271. }
  272. if (strcmp(path,"/ws/method/object") == 0) {
  273. /*syslog_ax_dbus_dbg("npd obj path"WS_DBUS_METHOD_OBJPATH"\r\n");*/
  274. if (dbus_message_is_method_call(message,"ws.method.Type","Method")) {
  275. reply = reply_to_method_call(message,user_data);
  276. }else{
  277. printf("unknown method call\n");
  278. }
  279. }else{
  280. printf("unknown path call\n");;
  281. }
  282. if(reply){
  283. // send the reply && flush the connection
  284. if (!dbus_connection_send(connection, reply, NULL)) {
  285. return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
  286. }
  287. dbus_connection_flush(connection);
  288. // free the reply
  289. dbus_message_unref(reply);
  290. return DBUS_HANDLER_RESULT_HANDLED ;
  291. }else{
  292. return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
  293. }
  294. }
  295. DBusMessage *reply_to_method_call_igmp(DBusMessage* msg, void *user_data)
  296. {
  297. DBusMessage* reply;
  298. DBusMessageIter args;
  299. bool stat = true;
  300. dbus_uint32_t level = 20;
  301. dbus_uint32_t serial = 0;
  302. char* param = "";
  303. char returnstr[30]="igmp server return";
  304. char *ssparam = returnstr;
  305. // read the arguments
  306. if (!dbus_message_iter_init(msg, &args))
  307. fprintf(stderr, "Message has no arguments!\n");
  308. else if (DBUS_TYPE_STRING != dbus_message_iter_get_arg_type(&args))
  309. fprintf(stderr, "Argument is not string!\n");
  310. else
  311. dbus_message_iter_get_basic(&args, m);
  312. printf("Method called with %s\n", param);
  313. // create a reply from the message
  314. reply = dbus_message_new_method_return(msg);
  315. // add the arguments to the reply
  316. /*dbus_message_iter_init_append(reply, &args);
  317. if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &ssparam)) {
  318. fprintf(stderr, "Out Of Memory!\n");
  319. exit(1);
  320. }
  321. printf("******************\n");
  322. if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_UINT32, &level)) {
  323. fprintf(stderr, "Out Of Memory!\n");
  324. exit(1);
  325. } */
  326. dbus_message_append_args (reply,
  327. DBUS_TYPE_STRING,&ssparam,
  328. DBUS_TYPE_UINT32,&level,
  329. DBUS_TYPE_INVALID);
  330. return reply;
  331. }
  332. DBusHandlerResult ws_dbus_message_handler_igmp(DBusConnection *connection, DBusMessage *message, void *user_data)
  333. {
  334. DBusMessage *reply = NULL;
  335. const char * path =dbus_message_get_path(message);
  336. if(NULL==path){
  337. return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
  338. }
  339. if (strcmp(path,"/ws/method/object") == 0) {
  340. /*syslog_ax_dbus_dbg("npd obj path"WS_DBUS_METHOD_OBJPATH"\r\n");*/
  341. if (dbus_message_is_method_call(message,"ws.method.Type","Method")) {
  342. reply = reply_to_method_call_igmp(message,user_data);
  343. }else{
  344. printf("unknown method call\n");
  345. }
  346. }else{
  347. printf("unknown path call\n");
  348. }
  349. if(reply){
  350. // send the reply && flush the connection
  351. if (!dbus_connection_send(connection, reply, NULL)) {
  352. return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
  353. }
  354. dbus_connection_flush(connection);
  355. // free the reply
  356. dbus_message_unref(reply);
  357. return DBUS_HANDLER_RESULT_HANDLED ;
  358. }else{
  359. return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
  360. }
  361. }
  362. /**
  363. * Server that exposes a method call and waits for it to be called
  364. */
  365. void listen()
  366. {
  367. DBusMessage* msg;
  368. DBusMessage* reply;
  369. DBusMessageIter args;
  370. //DBusConnection* conn;
  371. DBusError err;
  372. int ret;
  373. char* param;
  374. printf("Listening for method calls\n");
  375. // initialise the error
  376. dbus_error_init(&err);
  377. // connect to the bus and check for errors
  378. g_conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err);
  379. if (dbus_error_is_set(&err)) {
  380. fprintf(stderr, "Connection Error (%s)\n", err.message);
  381. dbus_error_free(&err);
  382. }
  383. if (NULL == g_conn) {
  384. fprintf(stderr, "Connection Null\n");
  385. exit(1);
  386. }
  387. // request our name on the bus and check for errors
  388. ret = dbus_bus_request_name(g_conn, "ws.method.listen",
  389. DBUS_NAME_FLAG_REPLACE_EXISTING , &err);
  390. if (dbus_error_is_set(&err)) {
  391. fprintf(stderr, "Name Error (%s)\n", err.message);
  392. dbus_error_free(&err);
  393. }
  394. if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) {
  395. fprintf(stderr, "Not Primary Owner (%d)\n", ret);
  396. exit(1);
  397. }
  398. // loop, testing for new messages
  399. /*while (true) {
  400. // non blocking read of the next available message
  401. dbus_connection_read_write(conn, -1);
  402. msg = dbus_connection_pop_message(conn);
  403. // loop again if we haven't got a message
  404. if (NULL == msg) {
  405. sleep(1);
  406. continue;
  407. }
  408. // check this is a method call for the right interface & method
  409. if (dbus_message_is_method_call(msg, "test.method.Type", "Method"))
  410. {
  411. igmp_query(conn,"igmp");
  412. reply_to_method_call(msg, conn,"daemon return",201);
  413. }
  414. // free the message
  415. dbus_message_unref(msg);
  416. }*/
  417. // 设置处理消息的函数 56:
  418. if (!dbus_connection_add_filter (g_conn, ws_dbus_message_handler_listen, NULL, NULL)) {
  419. return;
  420. }
  421. // 分派消息的Loop
  422. while (dbus_connection_read_write_dispatch (g_conn, -1))
  423. sleep(0);
  424. }
  425. /**
  426. * Server that exposes a method call and waits for it to be called
  427. */
  428. void listen_igmp()
  429. {
  430. DBusMessage* msg;
  431. DBusMessage* reply;
  432. DBusMessageIter args;
  433. DBusConnection* conn;
  434. DBusError err;
  435. int ret;
  436. char* param;
  437. printf("Listening for method calls\n");
  438. // initialise the error
  439. dbus_error_init(&err);
  440. // connect to the bus and check for errors
  441. conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err);
  442. if (dbus_error_is_set(&err)) {
  443. fprintf(stderr, "Connection Error (%s)\n", err.message);
  444. dbus_error_free(&err);
  445. }
  446. if (NULL == conn) {
  447. fprintf(stderr, "Connection Null\n");
  448. exit(1);
  449. }
  450. // request our name on the bus and check for errors
  451. ret = dbus_bus_request_name(conn, "ws.method.igmp",
  452. DBUS_NAME_FLAG_REPLACE_EXISTING , &err);
  453. if (dbus_error_is_set(&err)) {
  454. fprintf(stderr, "Name Error (%s)\n", err.message);
  455. dbus_error_free(&err);
  456. }
  457. if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) {
  458. fprintf(stderr, "Not Primary Owner (%d)\n", ret);
  459. exit(1);
  460. }
  461. // 设置处理消息的函数 56:
  462. if (!dbus_connection_add_filter (conn, ws_dbus_message_handler_igmp, NULL, NULL)) {
  463. return;
  464. }
  465. // 分派消息的Loop
  466. while (dbus_connection_read_write_dispatch (conn, -1))
  467. sleep(0);
  468. }
  469. /**
  470. * Listens for signals on the bus
  471. */
  472. void receive()
  473. {
  474. DBusMessage* msg;
  475. DBusMessageIter args;
  476. DBusConnection* conn;
  477. DBusError err;
  478. int ret;
  479. char* sigvalue;
  480. printf("Listening for signals\n");
  481. // initialise the errors
  482. dbus_error_init(&err);
  483. // connect to the bus and check for errors
  484. conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err);
  485. if (dbus_error_is_set(&err)) {
  486. fprintf(stderr, "Connection Error (%s)\n", err.message);
  487. dbus_error_free(&err);
  488. }
  489. if (NULL == conn) {
  490. exit(1);
  491. }
  492. // request our name on the bus and check for errors
  493. ret = dbus_bus_request_name(conn, "test.signal.sink", DBUS_NAME_FLAG_REPLACE_EXISTING , &err);
  494. if (dbus_error_is_set(&err)) {
  495. fprintf(stderr, "Name Error (%s)\n", err.message);
  496. dbus_error_free(&err);
  497. }
  498. if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) {
  499. exit(1);
  500. }
  501. // add a rule for which messages we want to see
  502. dbus_bus_add_match(conn, "type='signal',interface='test.signal.Type'", &err); // see signals from the given interface
  503. dbus_connection_flush(conn);
  504. if (dbus_error_is_set(&err)) {
  505. fprintf(stderr, "Match Error (%s)\n", err.message);
  506. exit(1);
  507. }
  508. printf("Match rule sent\n");
  509. // loop listening for signals being emmitted
  510. while (true) {
  511. // non blocking read of the next available message
  512. dbus_connection_read_write(conn, 0);
  513. msg = dbus_connection_pop_message(conn);
  514. // loop again if we haven't read a message
  515. if (NULL == msg) {
  516. sleep(1);
  517. continue;
  518. }
  519. // check if the message is a signal from the correct interface and with the correct name
  520. if (dbus_message_is_signal(msg, "test.signal.Type", "Test")) {
  521. // read the parameters
  522. if (!dbus_message_iter_init(msg, &args))
  523. fprintf(stderr, "Message Has No Parameters\n");
  524. else if (DBUS_TYPE_STRING != dbus_message_iter_get_arg_type(&args))
  525. fprintf(stderr, "Argument is not string!\n");
  526. else
  527. dbus_message_iter_get_basic(&args, &sigvalue);
  528. printf("Got Signal with value %s\n", sigvalue);
  529. }
  530. // free the message
  531. dbus_message_unref(msg);
  532. }
  533. }
  534. int main(int argc, char** argv)
  535. {
  536. char* param = "no param";
  537. printf("#Kluter T1:argc=%d\n", argc);
  538. if (2 > argc)
  539. {
  540. printf ("Syntax: dbus-example [send|receive|listen|query] [<param>]\n");
  541. return 1;
  542. }
  543. if (3 >= argc && NULL != argv[2])
  544. param = argv[2];
  545. if (0 == strcmp(argv[1], "send"))
  546. sendsignal(param);
  547. else if (0 == strcmp(argv[1], "receive"))
  548. receive();
  549. else if (0 == strcmp(argv[1], "listen"))
  550. listen();
  551. else if (0 == strcmp(argv[1], "query"))
  552. query(param);
  553. else if(0 == strcmp(argv[1]),"listen_igmp")
  554. listen_igmp();
  555. else
  556. {
  557. printf ("Syntax: dbus-example [send|receive|listen|query] [<param>]\n");
  558. return 1;
  559. }
  560. return 0;
  561. }
  562. /****************************************************************************/

发表评论

表情:
评论列表 (有 0 条评论,599人围观)

还没有评论,来说两句吧...

相关阅读

    相关 dbus(dbus-daemon)

    如何高效的利用dbus做client-server架构 //如果要传回数据到client侧,假设处理过的数据为:your\_strcut\_tdealed\_with\_

    相关 dbus和qtdbus

    什么是D-Bus? D-Bus是一种消息总线系统,用于两个应用之间的通信。 对于进程间通信,D-Bus也可以管理应用的生命周期, Qt D-Bus D-Bus

    相关 DBus学习资料

    网上搜集的一些关于dbus学习的资料。尤其是“一个完整的DBus学习教程”这份资料非常有借鉴意义。另外DBus官方网站中dbus-tutorial这篇文章也非常值得学习。还有“