app_manager_host.c 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324
  1. /*
  2. * Copyright (C) 2019 Intel Corporation. All rights reserved.
  3. * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. */
  5. #include "bh_platform.h"
  6. #include "app_manager_host.h"
  7. #include "app_manager.h"
  8. #include "app_manager_export.h"
  9. #include "coap_ext.h"
  10. /* host communication interface */
  11. static host_interface host_commu;
  12. /* IMRTLink Two leading bytes */
  13. static unsigned char leadings[] = { (unsigned char)0x12, (unsigned char)0x34 };
  14. /* IMRTLink Receiving Phase */
  15. typedef enum recv_phase_t {
  16. Phase_Non_Start,
  17. Phase_Leading,
  18. Phase_Type,
  19. Phase_Size,
  20. Phase_Payload,
  21. Phase_Ignoring
  22. } recv_phase_t;
  23. /* IMRTLink Receive Context */
  24. typedef struct recv_context_t {
  25. recv_phase_t phase;
  26. bh_link_msg_t message;
  27. int size_in_phase;
  28. } recv_context_t;
  29. /* Current IMRTLink receive context */
  30. static recv_context_t recv_ctx;
  31. /* Lock for device write */
  32. static korp_mutex host_lock;
  33. static bool enable_log = false;
  34. static bool
  35. is_little_endian()
  36. {
  37. long i = 0x01020304;
  38. unsigned char *c = (unsigned char *)&i;
  39. return (*c == 0x04) ? true : false;
  40. }
  41. static void
  42. exchange32(uint8 *pData)
  43. {
  44. uint8 value = *pData;
  45. *pData = *(pData + 3);
  46. *(pData + 3) = value;
  47. value = *(pData + 1);
  48. *(pData + 1) = *(pData + 2);
  49. *(pData + 2) = value;
  50. }
  51. /* return:
  52. * 1: complete message received
  53. * 0: incomplete message received
  54. */
  55. static int
  56. on_imrt_link_byte_arrive(unsigned char ch, recv_context_t *ctx)
  57. {
  58. if (ctx->phase == Phase_Non_Start) {
  59. ctx->message.payload_size = 0;
  60. if (ctx->message.payload) {
  61. APP_MGR_FREE(ctx->message.payload);
  62. ctx->message.payload = NULL;
  63. }
  64. if (ch == leadings[0]) {
  65. if (enable_log)
  66. app_manager_printf("##On byte arrive: got leading 0\n");
  67. ctx->phase = Phase_Leading;
  68. }
  69. return 0;
  70. }
  71. else if (ctx->phase == Phase_Leading) {
  72. if (ch == leadings[1]) {
  73. if (enable_log)
  74. app_manager_printf("##On byte arrive: got leading 1\n");
  75. ctx->phase = Phase_Type;
  76. }
  77. else
  78. ctx->phase = Phase_Non_Start;
  79. return 0;
  80. }
  81. else if (ctx->phase == Phase_Type) {
  82. if (ctx->size_in_phase++ == 0) {
  83. if (enable_log)
  84. app_manager_printf("##On byte arrive: got type 0\n");
  85. ctx->message.message_type = ch;
  86. }
  87. else {
  88. if (enable_log)
  89. app_manager_printf("##On byte arrive: got type 1\n");
  90. ctx->message.message_type |= (ch << 8);
  91. ctx->message.message_type = ntohs(ctx->message.message_type);
  92. ctx->phase = Phase_Size;
  93. ctx->size_in_phase = 0;
  94. }
  95. return 0;
  96. }
  97. else if (ctx->phase == Phase_Size) {
  98. unsigned char *p = (unsigned char *)&ctx->message.payload_size;
  99. if (enable_log)
  100. app_manager_printf("##On byte arrive: got payload_size, byte %d\n",
  101. ctx->size_in_phase);
  102. p[ctx->size_in_phase++] = ch;
  103. if (ctx->size_in_phase == sizeof(ctx->message.payload_size)) {
  104. ctx->message.payload_size = ntohl(ctx->message.payload_size);
  105. ctx->phase = Phase_Payload;
  106. if (enable_log)
  107. app_manager_printf("##On byte arrive: payload_size: %d\n",
  108. ctx->message.payload_size);
  109. if (ctx->message.payload) {
  110. APP_MGR_FREE(ctx->message.payload);
  111. ctx->message.payload = NULL;
  112. }
  113. /* message completion */
  114. if (ctx->message.payload_size == 0) {
  115. ctx->phase = Phase_Non_Start;
  116. if (enable_log)
  117. app_manager_printf("##On byte arrive: receive end, "
  118. "payload_size is 0.\n");
  119. return 1;
  120. }
  121. if (ctx->message.message_type != INSTALL_WASM_APP) {
  122. ctx->message.payload =
  123. (char *)APP_MGR_MALLOC(ctx->message.payload_size);
  124. if (!ctx->message.payload) {
  125. ctx->phase = Phase_Non_Start;
  126. return 0;
  127. }
  128. }
  129. ctx->phase = Phase_Payload;
  130. ctx->size_in_phase = 0;
  131. }
  132. return 0;
  133. }
  134. else if (ctx->phase == Phase_Payload) {
  135. if (ctx->message.message_type == INSTALL_WASM_APP) {
  136. int received_size;
  137. module_on_install_request_byte_arrive_func module_on_install =
  138. g_module_interfaces[Module_WASM_App]->module_on_install;
  139. ctx->size_in_phase++;
  140. if (module_on_install != NULL) {
  141. if (module_on_install(ch, ctx->message.payload_size,
  142. &received_size)) {
  143. if (received_size == ctx->message.payload_size) {
  144. /* whole wasm app received */
  145. ctx->phase = Phase_Non_Start;
  146. return 1;
  147. }
  148. }
  149. else {
  150. /* receive or handle fail */
  151. if (ctx->size_in_phase < ctx->message.payload_size) {
  152. ctx->phase = Phase_Ignoring;
  153. }
  154. else {
  155. ctx->phase = Phase_Non_Start;
  156. ctx->size_in_phase = 0;
  157. }
  158. return 0;
  159. }
  160. }
  161. else {
  162. ctx->phase = Phase_Non_Start;
  163. ctx->size_in_phase = 0;
  164. return 0;
  165. }
  166. }
  167. else {
  168. ctx->message.payload[ctx->size_in_phase++] = ch;
  169. if (ctx->size_in_phase == ctx->message.payload_size) {
  170. ctx->phase = Phase_Non_Start;
  171. if (enable_log)
  172. app_manager_printf("##On byte arrive: receive end, "
  173. "payload_size is %d.\n",
  174. ctx->message.payload_size);
  175. return 1;
  176. }
  177. return 0;
  178. }
  179. }
  180. else if (ctx->phase == Phase_Ignoring) {
  181. ctx->size_in_phase++;
  182. if (ctx->size_in_phase == ctx->message.payload_size) {
  183. if (ctx->message.payload)
  184. APP_MGR_FREE(ctx->message.payload);
  185. memset(ctx, 0, sizeof(*ctx));
  186. return 0;
  187. }
  188. }
  189. return 0;
  190. }
  191. int
  192. aee_host_msg_callback(void *msg, uint32_t msg_len)
  193. {
  194. unsigned char *p = msg, *p_end = p + msg_len;
  195. /*app_manager_printf("App Manager receive %d bytes from Host\n", msg_len);*/
  196. for (; p < p_end; p++) {
  197. int ret = on_imrt_link_byte_arrive(*p, &recv_ctx);
  198. if (ret == 1) {
  199. if (recv_ctx.message.payload) {
  200. int msg_type = recv_ctx.message.message_type;
  201. if (msg_type == REQUEST_PACKET) {
  202. request_t request;
  203. memset(&request, 0, sizeof(request));
  204. if (!unpack_request(recv_ctx.message.payload,
  205. recv_ctx.message.payload_size,
  206. &request))
  207. continue;
  208. request.sender = ID_HOST;
  209. am_dispatch_request(&request);
  210. }
  211. else {
  212. app_manager_printf("unexpected host msg type: %d\n",
  213. msg_type);
  214. }
  215. APP_MGR_FREE(recv_ctx.message.payload);
  216. recv_ctx.message.payload = NULL;
  217. recv_ctx.message.payload_size = 0;
  218. }
  219. memset(&recv_ctx, 0, sizeof(recv_ctx));
  220. }
  221. }
  222. return 0;
  223. }
  224. bool
  225. app_manager_host_init(host_interface *interface)
  226. {
  227. if (os_mutex_init(&host_lock) != 0) {
  228. return false;
  229. }
  230. memset(&recv_ctx, 0, sizeof(recv_ctx));
  231. host_commu.init = interface->init;
  232. host_commu.send = interface->send;
  233. host_commu.destroy = interface->destroy;
  234. if (host_commu.init != NULL) {
  235. if (!host_commu.init()) {
  236. os_mutex_destroy(&host_lock);
  237. return false;
  238. }
  239. }
  240. return true;
  241. }
  242. int
  243. app_manager_host_send_msg(int msg_type, const char *buf, int size)
  244. {
  245. /* send an IMRT LINK message contains the buf as payload */
  246. if (host_commu.send != NULL) {
  247. int size_s = size, n;
  248. char header[16];
  249. os_mutex_lock(&host_lock);
  250. /* leading bytes */
  251. bh_memcpy_s(header, 2, leadings, 2);
  252. /* message type */
  253. /* TODO: check if use network byte order!!! */
  254. *((uint16 *)(header + 2)) = htons(msg_type);
  255. /* payload length */
  256. if (is_little_endian())
  257. exchange32((uint8 *)&size_s);
  258. bh_memcpy_s(header + 4, 4, &size_s, 4);
  259. n = host_commu.send(NULL, header, 8);
  260. if (n != 8) {
  261. os_mutex_unlock(&host_lock);
  262. return 0;
  263. }
  264. /* payload */
  265. n = host_commu.send(NULL, buf, size);
  266. os_mutex_unlock(&host_lock);
  267. app_manager_printf("sent %d bytes to host\n", n);
  268. return n;
  269. }
  270. else {
  271. app_manager_printf("no send api provided\n");
  272. }
  273. return 0;
  274. }