spp_test_backend.c 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. /*
  2. * Copyright (c) 2019 Actions Semiconductor Co., Ltd
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. /**
  7. * @file
  8. * @brief OTA bluetooth SPP backend interface
  9. */
  10. #include <kernel.h>
  11. #include <string.h>
  12. #include <stream.h>
  13. #include <soc.h>
  14. #include <mem_manager.h>
  15. #include <spp_test_backend.h>
  16. #include <bt_manager.h>
  17. static struct spp_test_backend_t *g_test_backend;
  18. /*
  19. static void ttimer_handler(struct thread_timer *ttimer, void *expiry_fn_arg)
  20. {
  21. int count, ret;
  22. count = ring_buf_get(&g_test_backend->tx_ringbuf, g_test_backend->temp_buff, SPP_TX_RING_BUF_SIZE / 2);
  23. ret = stream_write(g_test_backend->sppble_stream, g_test_backend->temp_buff, count);
  24. if (count != ret)
  25. {
  26. SYS_LOG_ERR("SPP tx fail %d(%d)", ret, count);
  27. }
  28. thread_timer_start(ttimer, SPP_TRANSFER_TIMER_MS, 0);
  29. }
  30. */
  31. void spp_test_backend_init(void *init_param)
  32. {
  33. g_test_backend->sppble_stream = sppble_stream_create(init_param);
  34. if (!g_test_backend->sppble_stream) {
  35. SYS_LOG_ERR("stream_create failed");
  36. }
  37. }
  38. void spp_test_backend_exit(void)
  39. {
  40. SYS_LOG_DBG("");
  41. if (g_test_backend->sppble_stream) {
  42. stream_destroy(g_test_backend->sppble_stream);
  43. }
  44. mem_free(g_test_backend);
  45. /* avoid connect again after exit */
  46. g_test_backend = NULL;
  47. }
  48. int spp_test_backend_open(void)
  49. {
  50. int err = 0;
  51. SYS_LOG_DBG("open sppble_stream");
  52. if (!g_test_backend->sppble_stream_opened)
  53. {
  54. err = stream_open(g_test_backend->sppble_stream, MODE_IN_OUT);
  55. if (err)
  56. {
  57. SYS_LOG_ERR("stream_open Failed");
  58. }
  59. else
  60. {
  61. g_test_backend->sppble_stream_opened = 1;
  62. // g_test_backend->tx_buff = mem_malloc(SPP_TX_RING_BUF_SIZE);
  63. // g_test_backend->temp_buff = mem_malloc(SPP_TX_RING_BUF_SIZE / 2);
  64. // ring_buf_init(&g_test_backend->tx_ringbuf, SPP_TX_RING_BUF_SIZE, g_test_backend->tx_buff);
  65. // thread_timer_init(&g_test_backend->ttimer, ttimer_handler, NULL);
  66. // thread_timer_start(&g_test_backend->ttimer, SPP_TRANSFER_TIMER_MS, 0);
  67. }
  68. }
  69. return err;
  70. }
  71. int spp_test_backend_close(void)
  72. {
  73. int err = 0;
  74. SYS_LOG_DBG("close sppble_stream");
  75. if (g_test_backend->sppble_stream_opened)
  76. {
  77. err = stream_close(g_test_backend->sppble_stream);
  78. if (err)
  79. {
  80. SYS_LOG_ERR("stream_close Failed");
  81. }
  82. else
  83. {
  84. g_test_backend->sppble_stream_opened = 0;
  85. // thread_timer_stop(&g_test_backend->ttimer);
  86. // mem_free(g_test_backend->tx_buff);
  87. // mem_free(g_test_backend->temp_buff);
  88. }
  89. }
  90. return err;
  91. }
  92. int spp_test_backend_read(uint8_t *buf, uint32_t size, uint32_t timeout_ms)
  93. {
  94. int read_size, total_size = size;
  95. uint32_t prev_uptime, cur_uptime;
  96. uint8_t c;
  97. if (NULL == buf)
  98. {
  99. read_size = stream_tell(g_test_backend->sppble_stream);
  100. if (size > read_size)
  101. {
  102. size = read_size;
  103. }
  104. total_size = size;
  105. for (; 0 != size; size--)
  106. {
  107. stream_read(g_test_backend->sppble_stream, &c, 1);
  108. }
  109. }
  110. else
  111. {
  112. prev_uptime = k_uptime_get_32();
  113. while (size > 0) {
  114. read_size = stream_read(g_test_backend->sppble_stream, buf, size);
  115. if (read_size > 0)
  116. {
  117. size -= read_size;
  118. buf += read_size;
  119. }
  120. cur_uptime = k_uptime_get_32();
  121. if (cur_uptime - prev_uptime >= timeout_ms)
  122. break;
  123. os_sleep(1);
  124. }
  125. }
  126. if (size > 0)
  127. {
  128. read_size = total_size - size;
  129. SYS_LOG_DBG("need read %d bytes, but only got %d bytes", total_size, read_size);
  130. total_size = read_size;
  131. }
  132. return total_size;
  133. }
  134. int spp_test_backend_write(uint8_t *buf, uint32_t size, uint32_t timeout_ms)
  135. {
  136. int write_size, total_size = size;
  137. uint32_t prev_uptime, cur_uptime;
  138. prev_uptime = k_uptime_get_32();
  139. while (size > 0)
  140. {
  141. write_size = stream_write(g_test_backend->sppble_stream, buf, size);
  142. if (write_size > 0)
  143. {
  144. size -= write_size;
  145. buf += write_size;
  146. }
  147. cur_uptime = k_uptime_get_32();
  148. if (cur_uptime - prev_uptime >= timeout_ms)
  149. break;
  150. os_sleep(1);
  151. }
  152. if (size > 0)
  153. {
  154. write_size = total_size - size;
  155. SYS_LOG_ERR("write %d bytes, discard %d bytes", write_size, total_size - write_size);
  156. total_size = write_size;
  157. }
  158. return total_size;
  159. }
  160. int spp_test_backend_ioctl(int cmd, void *param0, void *param1)
  161. {
  162. return 0;
  163. }
  164. static void spp_test_connect_cb(int connected, uint8_t connect_type)
  165. {
  166. SYS_LOG_INF("connect: %d", connected);
  167. /* avoid connect again after exit */
  168. if (g_test_backend) {
  169. if (g_test_backend->cb) {
  170. if (connected)
  171. {
  172. spp_test_backend_open();
  173. }
  174. g_test_backend->cb(SPP_TEST_BACKEND_START_STATE, connected);
  175. if (!connected)
  176. {
  177. spp_test_backend_close();
  178. }
  179. }
  180. }
  181. }
  182. bool spp_test_backend_load_bt_init(spp_test_notify_cb_t cb, struct ota_backend_bt_init_param *param)
  183. {
  184. struct sppble_stream_init_param init_param;
  185. if (!g_test_backend)
  186. {
  187. g_test_backend = mem_malloc(sizeof(struct spp_test_backend_t));
  188. if (!g_test_backend) {
  189. SYS_LOG_ERR("malloc failed");
  190. return false;
  191. }
  192. }
  193. memset(g_test_backend, 0x0, sizeof(struct spp_test_backend_t));
  194. g_test_backend->type = OTA_BACKEND_TYPE_BLUETOOTH;
  195. g_test_backend->cb = cb;
  196. memset(&init_param, 0, sizeof(struct sppble_stream_init_param));
  197. init_param.spp_uuid = (uint8_t *)param->spp_uuid;
  198. init_param.gatt_attr = param->gatt_attr;
  199. init_param.attr_size = param->attr_size;
  200. init_param.tx_chrc_attr = param->tx_chrc_attr;
  201. init_param.tx_attr = param->tx_attr;
  202. init_param.tx_ccc_attr = param->tx_ccc_attr;
  203. init_param.rx_attr = param->rx_attr;
  204. init_param.connect_cb = spp_test_connect_cb;
  205. init_param.read_timeout = param->read_timeout; /* K_FOREVER, K_NO_WAIT, K_MSEC(ms) */
  206. init_param.write_timeout = param->write_timeout;
  207. /* Just call stream_create once, for register spp/ble service
  208. * not need call stream_destroy
  209. */
  210. spp_test_backend_init(&init_param);
  211. return true;
  212. }