resource_reg.c 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. /*
  2. * Copyright (C) 2019 Intel Corporation. All rights reserved.
  3. * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. */
  5. #include "native_interface.h"
  6. #include "app_manager.h"
  7. #include "app_manager_export.h"
  8. #include "bi-inc/shared_utils.h"
  9. #include "bi-inc/attr_container.h"
  10. #include "coap_ext.h"
  11. typedef struct _app_res_register {
  12. struct _app_res_register *next;
  13. char *url;
  14. void (*request_handler)(request_t *, void *);
  15. uint32 register_id;
  16. } app_res_register_t;
  17. static app_res_register_t *g_resources = NULL;
  18. void
  19. module_request_handler(request_t *request, void *user_data)
  20. {
  21. unsigned int mod_id = (unsigned int)(uintptr_t)user_data;
  22. bh_message_t msg;
  23. module_data *m_data;
  24. request_t *req;
  25. /* Check module name */
  26. m_data = module_data_list_lookup_id(mod_id);
  27. if (!m_data) {
  28. return;
  29. }
  30. if (m_data->wd_timer.is_interrupting) {
  31. return;
  32. }
  33. req = clone_request(request);
  34. if (!req) {
  35. return;
  36. }
  37. /* Set queue message and send to applet's queue */
  38. msg = bh_new_msg(RESTFUL_REQUEST, req, sizeof(*req), request_cleaner);
  39. if (!msg) {
  40. request_cleaner(req);
  41. return;
  42. }
  43. if (!bh_post_msg2(m_data->queue, msg)) {
  44. return;
  45. }
  46. app_manager_printf("Send request to app %s success.\n",
  47. m_data->module_name);
  48. }
  49. void
  50. targeted_app_request_handler(request_t *request, void *unused)
  51. {
  52. char applet_name[128] = { 0 };
  53. int offset;
  54. char *url = request->url;
  55. module_data *m_data;
  56. offset = check_url_start(request->url, strlen(request->url), "/app/");
  57. if (offset <= 0) {
  58. return;
  59. }
  60. strncpy(applet_name, request->url + offset, sizeof(applet_name) - 1);
  61. char *p = strchr(applet_name, '/');
  62. if (p) {
  63. *p = 0;
  64. }
  65. else
  66. return;
  67. app_manager_printf("Send request to applet: %s\n", applet_name);
  68. request->url = p + 1;
  69. /* Check module name */
  70. m_data = module_data_list_lookup(applet_name);
  71. if (!m_data) {
  72. SEND_ERR_RESPONSE(request->mid,
  73. "Send request to applet failed: invalid applet name");
  74. goto end;
  75. }
  76. module_request_handler(request, (void *)(uintptr_t)m_data->id);
  77. end:
  78. request->url = url;
  79. }
  80. void
  81. am_send_response(response_t *response)
  82. {
  83. module_data *m_data;
  84. // if the receiver is not any of modules, just forward it to the host
  85. m_data = module_data_list_lookup_id(response->reciever);
  86. if (!m_data) {
  87. send_response_to_host(response);
  88. }
  89. else {
  90. response_t *resp_for_send = clone_response(response);
  91. if (!resp_for_send) {
  92. return;
  93. }
  94. bh_message_t msg = bh_new_msg(RESTFUL_RESPONSE, resp_for_send,
  95. sizeof(*resp_for_send), response_cleaner);
  96. if (!msg) {
  97. response_cleaner(resp_for_send);
  98. return;
  99. }
  100. if (!bh_post_msg2(m_data->queue, msg)) {
  101. return;
  102. }
  103. }
  104. }
  105. void *
  106. am_dispatch_request(request_t *request)
  107. {
  108. app_res_register_t *r = g_resources;
  109. while (r) {
  110. if (check_url_start(request->url, strlen(request->url), r->url) > 0) {
  111. r->request_handler(request, (void *)(uintptr_t)r->register_id);
  112. return r;
  113. }
  114. r = r->next;
  115. }
  116. return NULL;
  117. }
  118. bool
  119. am_register_resource(const char *url,
  120. void (*request_handler)(request_t *, void *),
  121. uint32 register_id)
  122. {
  123. app_res_register_t *r = g_resources;
  124. int register_num = 0;
  125. while (r) {
  126. if (strcmp(r->url, url) == 0) {
  127. return false;
  128. }
  129. if (r->register_id == register_id)
  130. register_num++;
  131. r = r->next;
  132. }
  133. if (strlen(url) > RESOUCE_EVENT_URL_LEN_MAX)
  134. return false;
  135. if (register_num >= RESOURCE_REGISTRATION_NUM_MAX)
  136. return false;
  137. r = (app_res_register_t *)APP_MGR_MALLOC(sizeof(app_res_register_t));
  138. if (r == NULL)
  139. return false;
  140. memset(r, 0, sizeof(*r));
  141. r->url = bh_strdup(url);
  142. if (r->url == NULL) {
  143. APP_MGR_FREE(r);
  144. return false;
  145. }
  146. r->request_handler = request_handler;
  147. r->next = g_resources;
  148. r->register_id = register_id;
  149. g_resources = r;
  150. return true;
  151. }
  152. void
  153. am_cleanup_registeration(uint32 register_id)
  154. {
  155. app_res_register_t *r = g_resources;
  156. app_res_register_t *prev = NULL;
  157. while (r) {
  158. app_res_register_t *next = r->next;
  159. if (register_id == r->register_id) {
  160. if (prev)
  161. prev->next = next;
  162. else
  163. g_resources = next;
  164. APP_MGR_FREE(r->url);
  165. APP_MGR_FREE(r);
  166. }
  167. else
  168. /* if r is freed, should not change prev. Only set prev to r
  169. when r isn't freed. */
  170. prev = r;
  171. r = next;
  172. }
  173. }