app_manager.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420
  1. /*
  2. * Copyright (C) 2019 Intel Corporation. All rights reserved.
  3. * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. */
  5. #include "app_manager.h"
  6. #include "app_manager_host.h"
  7. #include "bh_platform.h"
  8. #include "bi-inc/attr_container.h"
  9. #include "event.h"
  10. #include "watchdog.h"
  11. #include "coap_ext.h"
  12. /* Queue of app manager */
  13. static bh_queue *g_app_mgr_queue;
  14. void *
  15. get_app_manager_queue()
  16. {
  17. return g_app_mgr_queue;
  18. }
  19. void
  20. app_manager_post_applets_update_event()
  21. {
  22. module_data *m_data;
  23. attr_container_t *attr_cont;
  24. request_t msg;
  25. int num = 0, i = 0;
  26. char *url = "/applets";
  27. if (!event_is_registered(url))
  28. return;
  29. if (!(attr_cont = attr_container_create("All Applets"))) {
  30. app_manager_printf("Post applets update event failed: "
  31. "allocate memory failed.");
  32. return;
  33. }
  34. os_mutex_lock(&module_data_list_lock);
  35. m_data = module_data_list;
  36. while (m_data) {
  37. num++;
  38. m_data = m_data->next;
  39. }
  40. if (!(attr_container_set_int(&attr_cont, "num", num))) {
  41. app_manager_printf("Post applets update event failed: "
  42. "set attr container key failed.");
  43. goto fail;
  44. }
  45. m_data = module_data_list;
  46. while (m_data) {
  47. char buf[32];
  48. i++;
  49. snprintf(buf, sizeof(buf), "%s%d", "applet", i);
  50. if (!(attr_container_set_string(&attr_cont, buf,
  51. m_data->module_name))) {
  52. app_manager_printf("Post applets update event failed: "
  53. "set attr applet name key failed.");
  54. goto fail;
  55. }
  56. snprintf(buf, sizeof(buf), "%s%d", "heap", i);
  57. if (!(attr_container_set_int(&attr_cont, buf, m_data->heap_size))) {
  58. app_manager_printf("Post applets update event failed: "
  59. "set attr heap key failed.");
  60. goto fail;
  61. }
  62. m_data = m_data->next;
  63. }
  64. memset(&msg, 0, sizeof(msg));
  65. msg.url = url;
  66. msg.action = COAP_EVENT;
  67. msg.payload = (char *)attr_cont;
  68. send_request_to_host(&msg);
  69. app_manager_printf("Post applets update event success!\n");
  70. attr_container_dump(attr_cont);
  71. fail:
  72. os_mutex_unlock(&module_data_list_lock);
  73. attr_container_destroy(attr_cont);
  74. }
  75. static int
  76. get_applets_count()
  77. {
  78. module_data *m_data;
  79. int num = 0;
  80. os_mutex_lock(&module_data_list_lock);
  81. m_data = module_data_list;
  82. while (m_data) {
  83. num++;
  84. m_data = m_data->next;
  85. }
  86. os_mutex_unlock(&module_data_list_lock);
  87. return num;
  88. }
  89. /* Query fw apps info if name = NULL, otherwise query specify app */
  90. static bool
  91. app_manager_query_applets(request_t *msg, const char *name)
  92. {
  93. module_data *m_data;
  94. attr_container_t *attr_cont;
  95. int num = 0, i = 0, len;
  96. bool ret = false, found = false;
  97. response_t response[1] = { 0 };
  98. attr_cont = attr_container_create("Applets Info");
  99. if (!attr_cont) {
  100. SEND_ERR_RESPONSE(msg->mid,
  101. "Query Applets failed: allocate memory failed.");
  102. return false;
  103. }
  104. os_mutex_lock(&module_data_list_lock);
  105. m_data = module_data_list;
  106. while (m_data) {
  107. num++;
  108. m_data = m_data->next;
  109. }
  110. if (name == NULL && !(attr_container_set_int(&attr_cont, "num", num))) {
  111. SEND_ERR_RESPONSE(
  112. msg->mid, "Query Applets failed: set attr container key failed.");
  113. goto fail;
  114. }
  115. m_data = module_data_list;
  116. while (m_data) {
  117. char buf[32];
  118. if (name == NULL) {
  119. i++;
  120. snprintf(buf, sizeof(buf), "%s%d", "applet", i);
  121. if (!(attr_container_set_string(&attr_cont, buf,
  122. m_data->module_name))) {
  123. SEND_ERR_RESPONSE(msg->mid, "Query Applets failed: "
  124. "set attr container key failed.");
  125. goto fail;
  126. }
  127. snprintf(buf, sizeof(buf), "%s%d", "heap", i);
  128. if (!(attr_container_set_int(&attr_cont, buf, m_data->heap_size))) {
  129. SEND_ERR_RESPONSE(msg->mid,
  130. "Query Applets failed: "
  131. "set attr container heap key failed.");
  132. goto fail;
  133. }
  134. }
  135. else if (!strcmp(name, m_data->module_name)) {
  136. found = true;
  137. if (!(attr_container_set_string(&attr_cont, "name",
  138. m_data->module_name))) {
  139. SEND_ERR_RESPONSE(msg->mid, "Query Applet failed: "
  140. "set attr container key failed.");
  141. goto fail;
  142. }
  143. if (!(attr_container_set_int(&attr_cont, "heap",
  144. m_data->heap_size))) {
  145. SEND_ERR_RESPONSE(msg->mid,
  146. "Query Applet failed: "
  147. "set attr container heap key failed.");
  148. goto fail;
  149. }
  150. }
  151. m_data = m_data->next;
  152. }
  153. if (name != NULL && !found) {
  154. SEND_ERR_RESPONSE(msg->mid,
  155. "Query Applet failed: the app is not found.");
  156. goto fail;
  157. }
  158. len = attr_container_get_serialize_length(attr_cont);
  159. make_response_for_request(msg, response);
  160. set_response(response, CONTENT_2_05, FMT_ATTR_CONTAINER, (char *)attr_cont,
  161. len);
  162. send_response_to_host(response);
  163. ret = true;
  164. app_manager_printf("Query Applets success!\n");
  165. attr_container_dump(attr_cont);
  166. fail:
  167. os_mutex_unlock(&module_data_list_lock);
  168. attr_container_destroy(attr_cont);
  169. return ret;
  170. }
  171. void
  172. applet_mgt_reqeust_handler(request_t *request, void *unused)
  173. {
  174. bh_message_t msg;
  175. /* deep copy, but not use app self heap, but use global heap */
  176. request_t *req = clone_request(request);
  177. if (!req)
  178. return;
  179. msg = bh_new_msg(RESTFUL_REQUEST, req, sizeof(*req), request_cleaner);
  180. if (!msg) {
  181. request_cleaner(req);
  182. return;
  183. }
  184. bh_post_msg2(get_app_manager_queue(), msg);
  185. }
  186. /* return -1 for error */
  187. static int
  188. get_module_type(char *kv_str)
  189. {
  190. int module_type = -1;
  191. char type_str[16] = { 0 };
  192. find_key_value(kv_str, strlen(kv_str), "type", type_str,
  193. sizeof(type_str) - 1, '&');
  194. if (strlen(type_str) == 0)
  195. module_type = Module_WASM_App;
  196. else if (strcmp(type_str, "jeff") == 0)
  197. module_type = Module_Jeff;
  198. else if (strcmp(type_str, "wasm") == 0)
  199. module_type = Module_WASM_App;
  200. else if (strcmp(type_str, "wasmlib") == 0)
  201. module_type = Module_WASM_Lib;
  202. return module_type;
  203. }
  204. #define APP_NAME_MAX_LEN 128
  205. /* Queue callback of App Manager */
  206. static void
  207. app_manager_queue_callback(void *message, void *arg)
  208. {
  209. request_t *request = (request_t *)bh_message_payload((bh_message_t)message);
  210. int mid = request->mid, module_type, offset;
  211. (void)arg;
  212. if ((offset =
  213. check_url_start(request->url, strlen(request->url), "/applet"))
  214. > 0) {
  215. module_type = get_module_type(request->url + offset);
  216. if (module_type == -1) {
  217. SEND_ERR_RESPONSE(mid,
  218. "Applet Management failed: invalid module type.");
  219. goto fail;
  220. }
  221. /* Install Applet */
  222. if (request->action == COAP_PUT) {
  223. if (get_applets_count() >= MAX_APP_INSTALLATIONS) {
  224. SEND_ERR_RESPONSE(
  225. mid,
  226. "Install Applet failed: exceed max app installations.");
  227. goto fail;
  228. }
  229. if (!request->payload) {
  230. SEND_ERR_RESPONSE(mid,
  231. "Install Applet failed: invalid payload.");
  232. goto fail;
  233. }
  234. if (g_module_interfaces[module_type]
  235. && g_module_interfaces[module_type]->module_install) {
  236. if (!g_module_interfaces[module_type]->module_install(request))
  237. goto fail;
  238. }
  239. }
  240. /* Uninstall Applet */
  241. else if (request->action == COAP_DELETE) {
  242. module_type = get_module_type(request->url + offset);
  243. if (module_type == -1) {
  244. SEND_ERR_RESPONSE(
  245. mid, "Uninstall Applet failed: invalid module type.");
  246. goto fail;
  247. }
  248. if (g_module_interfaces[module_type]
  249. && g_module_interfaces[module_type]->module_uninstall) {
  250. if (!g_module_interfaces[module_type]->module_uninstall(
  251. request))
  252. goto fail;
  253. }
  254. }
  255. /* Query Applets installed */
  256. else if (request->action == COAP_GET) {
  257. char name[APP_NAME_MAX_LEN] = { 0 };
  258. char *properties = request->url + offset;
  259. find_key_value(properties, strlen(properties), "name", name,
  260. sizeof(name) - 1, '&');
  261. if (strlen(name) > 0)
  262. app_manager_query_applets(request, name);
  263. else
  264. app_manager_query_applets(request, NULL);
  265. }
  266. else {
  267. SEND_ERR_RESPONSE(mid, "Invalid request of applet: invalid action");
  268. }
  269. }
  270. /* Event Register/Unregister */
  271. else if ((offset = check_url_start(request->url, strlen(request->url),
  272. "/event/"))
  273. > 0) {
  274. char url_buf[256] = { 0 };
  275. strncpy(url_buf, request->url + offset, sizeof(url_buf) - 1);
  276. if (!event_handle_event_request(request->action, url_buf, ID_HOST)) {
  277. SEND_ERR_RESPONSE(mid, "Handle event request failed.");
  278. goto fail;
  279. }
  280. send_error_response_to_host(mid, CONTENT_2_05, NULL); /* OK */
  281. }
  282. else {
  283. int i;
  284. for (i = 0; i < Module_Max; i++) {
  285. if (g_module_interfaces[i]
  286. && g_module_interfaces[i]->module_handle_host_url) {
  287. if (g_module_interfaces[i]->module_handle_host_url(request))
  288. break;
  289. }
  290. }
  291. }
  292. fail:
  293. return;
  294. }
  295. static void
  296. module_interfaces_init()
  297. {
  298. int i;
  299. for (i = 0; i < Module_Max; i++) {
  300. if (g_module_interfaces[i] && g_module_interfaces[i]->module_init)
  301. g_module_interfaces[i]->module_init();
  302. }
  303. }
  304. void
  305. app_manager_startup(host_interface *interface)
  306. {
  307. module_interfaces_init();
  308. /* Create queue of App Manager */
  309. g_app_mgr_queue = bh_queue_create();
  310. if (!g_app_mgr_queue)
  311. return;
  312. if (!module_data_list_init())
  313. goto fail1;
  314. if (!watchdog_startup())
  315. goto fail2;
  316. /* Initialize Host */
  317. app_manager_host_init(interface);
  318. am_register_resource("/app/", targeted_app_request_handler, ID_APP_MGR);
  319. /* /app/ and /event/ are both processed by applet_mgt_reqeust_handler */
  320. am_register_resource("/applet", applet_mgt_reqeust_handler, ID_APP_MGR);
  321. am_register_resource("/event/", applet_mgt_reqeust_handler, ID_APP_MGR);
  322. app_manager_printf("App Manager started.\n");
  323. /* Enter loop run */
  324. bh_queue_enter_loop_run(g_app_mgr_queue, app_manager_queue_callback, NULL);
  325. /* Destroy registered resources */
  326. am_cleanup_registeration(ID_APP_MGR);
  327. /* Destroy watchdog */
  328. watchdog_destroy();
  329. fail2:
  330. module_data_list_destroy();
  331. fail1:
  332. bh_queue_destroy(g_app_mgr_queue);
  333. }
  334. #include "module_config.h"
  335. module_interface *g_module_interfaces[Module_Max] = {
  336. #if ENABLE_MODULE_JEFF != 0
  337. &jeff_module_interface,
  338. #else
  339. NULL,
  340. #endif
  341. #if ENABLE_MODULE_WASM_APP != 0
  342. &wasm_app_module_interface,
  343. #else
  344. NULL,
  345. #endif
  346. #if ENABLE_MODULE_WASM_LIB != 0
  347. &wasm_lib_module_interface
  348. #else
  349. NULL
  350. #endif
  351. };