fota-server.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681
  1. /*
  2. * Copyright (C) 2018-2021 Alibaba Group Holding Limited
  3. */
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <stdbool.h>
  7. #include <unistd.h>
  8. #include <string.h>
  9. #include <signal.h>
  10. #include <pthread.h>
  11. #include <dbus/dbus.h>
  12. #include <dbus_new_helpers.h>
  13. #include <fota.h>
  14. #include <fota_debug.h>
  15. static int should_dispatch;
  16. struct fota_dbus_object_desc obj_dsc;
  17. int fota_dbus_signal_version(fota_server_t *fota, const char *str)
  18. {
  19. DBusMessage *msg;
  20. DBusMessageIter iter;
  21. dbus_uint32_t serial = 0;
  22. DBusConnection *conn = fota->conn;
  23. char *_str = (char *)str;
  24. fota_log(LOG_DEBUG, "Enter %s\n", __func__);
  25. msg = dbus_message_new_signal(FOTA_DBUS_PATH,
  26. FOTA_DBUS_INTERFACE, FOTA_DBUS_SIGNAL_VERSION);
  27. if (NULL == msg) {
  28. fota_log(LOG_ERR, "Message Null\n");
  29. return -1;
  30. }
  31. dbus_message_iter_init_append(msg, &iter);
  32. if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &_str)) {
  33. fota_log(LOG_ERR, "Out Of Memory!\n");
  34. return -1;
  35. }
  36. if (!dbus_connection_send(conn, msg, &serial)) {
  37. fota_log(LOG_ERR, "Out Of Memory!\n");
  38. return -1;
  39. }
  40. dbus_connection_flush(conn);
  41. dbus_message_unref(msg);
  42. return 0;
  43. }
  44. int fota_dbus_signal_download(fota_server_t *fota, const char *str)
  45. {
  46. DBusMessage *msg;
  47. DBusMessageIter iter;
  48. dbus_uint32_t serial = 0;
  49. DBusConnection *conn = fota->conn;
  50. char *_str = (char *)str;
  51. fota_log(LOG_DEBUG, "Enter %s\n", __func__);
  52. msg = dbus_message_new_signal(FOTA_DBUS_PATH,
  53. FOTA_DBUS_INTERFACE, FOTA_DBUS_SIGNAL_DOWNLOAD);
  54. if (NULL == msg) {
  55. fota_log(LOG_ERR, "Message Null\n");
  56. return -1;
  57. }
  58. dbus_message_iter_init_append(msg, &iter);
  59. if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &_str)) {
  60. fota_log(LOG_ERR, "Out Of Memory!\n");
  61. return -1;
  62. }
  63. if (!dbus_connection_send(conn, msg, &serial)) {
  64. fota_log(LOG_ERR, "Out Of Memory!\n");
  65. return -1;
  66. }
  67. dbus_connection_flush(conn);
  68. dbus_message_unref(msg);
  69. return 0;
  70. }
  71. int fota_dbus_signal_end(fota_server_t *fota, const char *str)
  72. {
  73. DBusMessage *msg;
  74. DBusMessageIter iter;
  75. dbus_uint32_t serial = 0;
  76. DBusConnection *conn = fota->conn;
  77. char *_str = (char *)str;
  78. fota_log(LOG_DEBUG, "Enter %s\n", __func__);
  79. msg = dbus_message_new_signal(FOTA_DBUS_PATH,
  80. FOTA_DBUS_INTERFACE, FOTA_DBUS_SIGNAL_END);
  81. if (NULL == msg) {
  82. fota_log(LOG_ERR, "Message Null\n");
  83. return -1;
  84. }
  85. dbus_message_iter_init_append(msg, &iter);
  86. if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &_str)) {
  87. fota_log(LOG_ERR, "Out Of Memory!\n");
  88. return -1;
  89. }
  90. if (!dbus_connection_send(conn, msg, &serial)) {
  91. fota_log(LOG_ERR, "Out Of Memory!\n");
  92. return -1;
  93. }
  94. dbus_connection_flush(conn);
  95. dbus_message_unref(msg);
  96. return 0;
  97. }
  98. int fota_dbus_signal_restart(fota_server_t *fota, const char *str)
  99. {
  100. DBusMessage *msg;
  101. DBusMessageIter iter;
  102. dbus_uint32_t serial = 0;
  103. DBusConnection *conn = fota->conn;
  104. char *_str = (char *)str;
  105. fota_log(LOG_DEBUG, "Enter %s\n", __func__);
  106. msg = dbus_message_new_signal(FOTA_DBUS_PATH,
  107. FOTA_DBUS_INTERFACE, FOTA_DBUS_SIGNAL_RESTART);
  108. if (NULL == msg) {
  109. fota_log(LOG_ERR, "Message Null\n");
  110. return -1;
  111. }
  112. dbus_message_iter_init_append(msg, &iter);
  113. if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &_str)) {
  114. fota_log(LOG_ERR, "Out Of Memory!\n");
  115. return -1;
  116. }
  117. if (!dbus_connection_send(conn, msg, &serial)) {
  118. fota_log(LOG_ERR, "Out Of Memory!\n");
  119. return -1;
  120. }
  121. dbus_connection_flush(conn);
  122. dbus_message_unref(msg);
  123. return 0;
  124. }
  125. void fotax_event(fotax_t *fotax, fotax_event_e event, const char *json)
  126. {
  127. fota_server_t *fota_server = (fota_server_t *)fotax->private;
  128. switch (event) {
  129. case FOTAX_EVENT_VERSION:
  130. fota_log(LOG_DEBUG, "%s,%d,%s\n", __func__, __LINE__, json);
  131. fota_dbus_signal_version(fota_server, json);
  132. break;
  133. case FOTAX_EVENT_DOWNLOAD:
  134. fota_log(LOG_DEBUG, "%s,%d,%s\n", __func__, __LINE__, json);
  135. fota_dbus_signal_download(fota_server, json);
  136. break;
  137. case FOTAX_EVENT_END:
  138. fota_log(LOG_DEBUG, "%s,%d,%s\n", __func__, __LINE__, json);
  139. fota_dbus_signal_end(fota_server, json);
  140. break;
  141. case FOTAX_EVENT_RESTART:
  142. fota_log(LOG_DEBUG, "%s,%d,%s\n", __func__, __LINE__, json);
  143. fota_dbus_signal_restart(fota_server, json);
  144. break;
  145. default: break;
  146. }
  147. }
  148. int fota_dbus_method_start(DBusMessage *msg, fota_server_t *fota)
  149. {
  150. int ret_val;
  151. DBusMessage *reply;
  152. DBusMessageIter iter;
  153. dbus_uint32_t serial = 0;
  154. DBusConnection *conn = fota->conn;
  155. fota_log(LOG_DEBUG, "Enter %s\n", __func__);
  156. ret_val = fotax_start(&fota->fotax);
  157. if (ret_val == 0) {
  158. fota->fotax.fotax_event_cb = fotax_event;
  159. fota->fotax.private = fota;
  160. }
  161. reply = dbus_message_new_method_return(msg);
  162. dbus_message_iter_init_append(reply, &iter);
  163. if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret_val)) {
  164. fota_log(LOG_ERR, "Out Of Memory!\n");
  165. return -1;
  166. }
  167. if (!dbus_connection_send(conn, reply, &serial)) {
  168. fota_log(LOG_ERR, "Out Of Memory!\n");
  169. return -1;
  170. }
  171. dbus_connection_flush(conn);
  172. dbus_message_unref(reply);
  173. return 0;
  174. }
  175. int fota_dbus_method_stop(DBusMessage *msg, fota_server_t *fota)
  176. {
  177. int ret_val;
  178. DBusMessage *reply;
  179. DBusMessageIter iter;
  180. dbus_uint32_t serial = 0;
  181. DBusConnection *conn = fota->conn;
  182. fota_log(LOG_DEBUG, "Enter %s\n", __func__);
  183. ret_val = fotax_stop(&fota->fotax);
  184. reply = dbus_message_new_method_return(msg);
  185. dbus_message_iter_init_append(reply, &iter);
  186. if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret_val)) {
  187. fota_log(LOG_ERR, "Out Of Memory!\n");
  188. return -1;
  189. }
  190. if (!dbus_connection_send(conn, reply, &serial)) {
  191. fota_log(LOG_ERR, "Out Of Memory!\n");
  192. return -1;
  193. }
  194. dbus_connection_flush(conn);
  195. dbus_message_unref(reply);
  196. return 0;
  197. }
  198. int fota_dbus_method_get_state(DBusMessage *msg, fota_server_t *fota)
  199. {
  200. DBusMessage *reply;
  201. DBusMessageIter iter;
  202. dbus_uint32_t serial = 0;
  203. DBusConnection *conn = fota->conn;
  204. char ret_str[10];
  205. char *str = (char *)&ret_str;
  206. fota_log(LOG_DEBUG, "Enter %s\n", __func__);
  207. memset(&ret_str, 0, sizeof(ret_str));
  208. int ret = fotax_get_state(&fota->fotax);
  209. // 版本检测,下载状态,停止状态,空闲状态
  210. if (ret == FOTAX_INIT) {
  211. strncpy(ret_str, "idle", sizeof(ret_str) - 1);
  212. } else if (ret == FOTAX_DOWNLOAD ) {
  213. strncpy(ret_str, "download", sizeof(ret_str) - 1);
  214. } else if (ret == FOTAX_ABORT ) {
  215. strncpy(ret_str, "abort", sizeof(ret_str) - 1);
  216. } else if (ret == FOTAX_FINISH ) {
  217. strncpy(ret_str, "finish", sizeof(ret_str) - 1);
  218. } else {
  219. strncpy(ret_str, "", sizeof(ret_str) - 1);
  220. }
  221. reply = dbus_message_new_method_return(msg);
  222. dbus_message_iter_init_append(reply, &iter);
  223. if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &str)) {
  224. fota_log(LOG_ERR, "Out Of Memory!\n");
  225. return -1;
  226. }
  227. if (!dbus_connection_send(conn, reply, &serial)) {
  228. fota_log(LOG_ERR, "Out Of Memory!\n");
  229. return -1;
  230. }
  231. dbus_connection_flush(conn);
  232. dbus_message_unref(reply);
  233. return 0;
  234. }
  235. int fota_dbus_method_version_check(DBusMessage *msg, fota_server_t *fota)
  236. {
  237. int ret_val;
  238. DBusMessage *reply;
  239. DBusMessageIter iter;
  240. dbus_uint32_t serial = 0;
  241. DBusConnection *conn = fota->conn;
  242. fota_log(LOG_DEBUG, "Enter %s\n", __func__);
  243. ret_val = fotax_version_check(&fota->fotax);
  244. reply = dbus_message_new_method_return(msg);
  245. dbus_message_iter_init_append(reply, &iter);
  246. if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret_val)) {
  247. fota_log(LOG_ERR, "Out Of Memory!\n");
  248. return -1;
  249. }
  250. if (!dbus_connection_send(conn, reply, &serial)) {
  251. fota_log(LOG_ERR, "Out Of Memory!\n");
  252. return -1;
  253. }
  254. dbus_connection_flush(conn);
  255. dbus_message_unref(reply);
  256. return 0;
  257. }
  258. int fota_dbus_method_download(DBusMessage *msg, fota_server_t *fota)
  259. {
  260. int ret_val;
  261. DBusMessage *reply;
  262. DBusMessageIter iter;
  263. dbus_uint32_t serial = 0;
  264. DBusConnection *conn = fota->conn;
  265. fota_log(LOG_DEBUG, "Enter %s\n", __func__);
  266. ret_val = fotax_download(&fota->fotax);
  267. reply = dbus_message_new_method_return(msg);
  268. dbus_message_iter_init_append(reply, &iter);
  269. if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret_val)) {
  270. fota_log(LOG_ERR, "Out Of Memory!\n");
  271. return -1;
  272. }
  273. if (!dbus_connection_send(conn, reply, &serial)) {
  274. fota_log(LOG_ERR, "Out Of Memory!\n");
  275. return -1;
  276. }
  277. dbus_connection_flush(conn);
  278. dbus_message_unref(reply);
  279. return 0;
  280. }
  281. int fota_dbus_method_restart(DBusMessage *msg, fota_server_t *fota)
  282. {
  283. int ret_val;
  284. DBusMessage *reply;
  285. DBusMessageIter iter;
  286. dbus_uint32_t serial = 0;
  287. DBusConnection *conn = fota->conn;
  288. double _millisecond;
  289. int millisecond;
  290. fota_log(LOG_DEBUG, "Enter %s\n", __func__);
  291. dbus_message_iter_init(msg, &iter);
  292. // printf("type = %d\n", dbus_message_iter_get_arg_type(&iter));
  293. // if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_INT32) {
  294. // fota_log(LOG_ERR, "not int\n");
  295. // }
  296. dbus_message_iter_get_basic(&iter, &_millisecond);
  297. millisecond = (int)_millisecond;
  298. printf("millisecond = %d\n", millisecond);
  299. ret_val = fotax_restart(&fota->fotax, millisecond);
  300. reply = dbus_message_new_method_return(msg);
  301. dbus_message_iter_init_append(reply, &iter);
  302. if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret_val)) {
  303. fota_log(LOG_ERR, "Out Of Memory!\n");
  304. return -1;
  305. }
  306. if (!dbus_connection_send(conn, reply, &serial)) {
  307. fota_log(LOG_ERR, "Out Of Memory!\n");
  308. return -1;
  309. }
  310. dbus_connection_flush(conn);
  311. dbus_message_unref(reply);
  312. return 0;
  313. }
  314. int fota_dbus_method_size(DBusMessage *msg, fota_server_t *fota)
  315. {
  316. int64_t ret_val;
  317. DBusMessage *reply;
  318. DBusMessageIter iter;
  319. dbus_uint32_t serial = 0;
  320. DBusConnection *conn = fota->conn;
  321. char *name;
  322. fota_log(LOG_DEBUG, "Enter %s\n", __func__);
  323. dbus_message_iter_init(msg, &iter);
  324. dbus_message_iter_get_basic(&iter, &name);
  325. printf("name = %s\n", name);
  326. ret_val = fotax_get_size(&fota->fotax, name);
  327. reply = dbus_message_new_method_return(msg);
  328. dbus_message_iter_init_append(reply, &iter);
  329. if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT64, &ret_val)) {
  330. fota_log(LOG_ERR, "Out Of Memory!\n");
  331. return -1;
  332. }
  333. if (!dbus_connection_send(conn, reply, &serial)) {
  334. fota_log(LOG_ERR, "Out Of Memory!\n");
  335. return -1;
  336. }
  337. dbus_connection_flush(conn);
  338. dbus_message_unref(reply);
  339. return 0;
  340. }
  341. static void msg_method_handler(DBusMessage *msg, fota_server_t *fota)
  342. {
  343. const char *member;
  344. fota_log(LOG_INFO, "Enter %s\n", __func__);
  345. member = dbus_message_get_member(msg);
  346. fota_log(LOG_INFO, "method call: %s\n", member);
  347. for (int i = 0; ; i++) {
  348. if (fota_dbus_global_methods[i].dbus_method == NULL) {
  349. fota_log(LOG_ERR, "not method call\n");
  350. break;
  351. }
  352. if (!strcmp(fota_dbus_global_methods[i].dbus_method, member)) {
  353. fota_dbus_global_methods[i].function(msg, fota);
  354. break;
  355. }
  356. }
  357. }
  358. static DBusHandlerResult message_handler(DBusConnection *connection,
  359. DBusMessage *message, void *user_data)
  360. {
  361. const char *method;
  362. const char *path;
  363. const char *interface;
  364. method = dbus_message_get_member(message);
  365. path = dbus_message_get_path(message);
  366. interface = dbus_message_get_interface(message);
  367. if (!method || !path || !interface) {
  368. return -1;
  369. }
  370. if (!strncmp(FOTA_DBUS_INTROSPECTION_METHOD, method, 50) &&
  371. !strncmp(FOTA_DBUS_INTROSPECTION_INTERFACE, interface, 50)) {
  372. fota_dbus_introspect(message, &obj_dsc, (fota_server_t *)user_data);
  373. } else if(!strncmp(FOTA_DBUS_INTERFACE, interface, 50)) {
  374. msg_method_handler(message, (fota_server_t *)user_data);
  375. } else {
  376. fota_log(LOG_ERR, "message error\n");
  377. }
  378. return DBUS_HANDLER_RESULT_HANDLED;
  379. }
  380. int fota_dbus_ctrl_iface_init(fota_server_t *fota)
  381. {
  382. DBusObjectPathVTable vtable = {
  383. NULL, &message_handler,
  384. NULL, NULL, NULL, NULL
  385. };
  386. if (!dbus_connection_register_object_path(fota->conn, FOTA_DBUS_PATH, &vtable, fota)) {
  387. fota_log(LOG_ERR, "dbus_connection_register_object_path error\n");
  388. return -1;
  389. }
  390. return 0;
  391. }
  392. static dbus_bool_t add_watch(DBusWatch *watch, void *data)
  393. {
  394. int fd;
  395. unsigned int flags;
  396. fota_server_t *fota = (fota_server_t *)data;
  397. if (!dbus_watch_get_enabled(watch)) {
  398. return TRUE;
  399. }
  400. flags = dbus_watch_get_flags(watch);
  401. fd = dbus_watch_get_unix_fd(watch);
  402. if (flags & DBUS_WATCH_READABLE) {
  403. fota->watch_rfd = fd;
  404. fota->watch = watch;
  405. }
  406. return TRUE;
  407. }
  408. static void wakeup_main(void *data)
  409. {
  410. should_dispatch = 1;
  411. }
  412. static int integrate_dbus_watch(fota_server_t *fota)
  413. {
  414. if (!dbus_connection_set_watch_functions(fota->conn, add_watch, NULL, NULL, fota, NULL)) {
  415. fota_log(LOG_ERR, "dbus_connection_set_watch_functions error\n");
  416. return -1;
  417. }
  418. dbus_connection_set_wakeup_main_function(fota->conn, wakeup_main,
  419. fota, NULL);
  420. return 0;
  421. }
  422. static void dispatch_data(DBusConnection *con)
  423. {
  424. while (dbus_connection_get_dispatch_status(con) ==
  425. DBUS_DISPATCH_DATA_REMAINS)
  426. dbus_connection_dispatch(con);
  427. }
  428. static void process_watch(fota_server_t *fota, DBusWatch *watch)
  429. {
  430. dbus_connection_ref(fota->conn);
  431. should_dispatch = 0;
  432. dbus_watch_handle(watch, DBUS_WATCH_READABLE);
  433. if (should_dispatch) {
  434. dispatch_data(fota->conn);
  435. should_dispatch = 0;
  436. }
  437. dbus_connection_unref(fota->conn);
  438. }
  439. static void process_watch_read(fota_server_t *fota, DBusWatch *watch)
  440. {
  441. process_watch(fota, watch);
  442. }
  443. void fota_loop_run(fota_server_t *fota)
  444. {
  445. int sockfd;
  446. fd_set rset;
  447. int retval;
  448. integrate_dbus_watch(fota);
  449. sockfd = fota->watch_rfd;
  450. FD_ZERO(&rset);
  451. FD_SET(sockfd, &rset);
  452. while (1) {
  453. retval = select(sockfd + 1, &rset, NULL, NULL, NULL);
  454. if (retval == -1) {
  455. fota_log(LOG_ERR, "select error\n");
  456. } else if (retval) {
  457. process_watch_read(fota, fota->watch);
  458. } else {
  459. fota_log(LOG_ERR, "select timeout\n");
  460. // timeout
  461. }
  462. }
  463. }
  464. int fota_dbus_init(fota_server_t *fota)
  465. {
  466. int ret;
  467. DBusError err;
  468. DBusConnection *conn;
  469. dbus_error_init(&err);
  470. conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err);
  471. obj_dsc.connection = conn;
  472. fota->conn = conn;
  473. fota_dbus_register_desc();
  474. fota_dbus_ctrl_iface_init(fota);
  475. if (dbus_error_is_set(&err)) {
  476. fota_log(LOG_ERR, "Connection Error (%s)\n", err.message);
  477. dbus_error_free(&err);
  478. }
  479. if (conn == NULL) {
  480. exit(1);
  481. }
  482. ret = dbus_bus_request_name(conn, FOTA_DBUS_SERVER, DBUS_NAME_FLAG_DO_NOT_QUEUE, &err);
  483. if (dbus_error_is_set(&err)) {
  484. fota_log(LOG_ERR, "Name Error (%s)\n", err.message);
  485. dbus_error_free(&err);
  486. }
  487. if (ret != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
  488. fota_log(LOG_ERR, "Error: Service has been started already\n");
  489. exit(1);
  490. }
  491. /////////////////////////////////////////////////////////////////////
  492. dbus_bus_add_match(conn,
  493. "type='method_call',interface='org.fota.interface'",
  494. &err);
  495. dbus_connection_flush(conn);
  496. if (dbus_error_is_set(&err)) {
  497. fota_log(LOG_ERR, "Match Error (%s)\n", err.message);
  498. exit(1);
  499. }
  500. return 0;
  501. }
  502. void fota_dbus_deinit(fota_server_t *fota)
  503. {
  504. DBusError err;
  505. dbus_error_init(&err);
  506. dbus_bus_release_name(fota->conn, FOTA_DBUS_SERVER, &err);
  507. }