bt_manager_discover.c 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. /*
  2. * Copyright (c) 2019 Actions Semi Co., Inc.
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. /**
  7. * @file
  8. * @brief bt manager discover.
  9. */
  10. #define SYS_LOG_NO_NEWLINE
  11. #define SYS_LOG_DOMAIN "bt discover"
  12. #include <os_common_api.h>
  13. #include <zephyr.h>
  14. #include <stdlib.h>
  15. #include <stdio.h>
  16. #include <string.h>
  17. #include <msg_manager.h>
  18. #include <mem_manager.h>
  19. #include <bt_manager.h>
  20. #include "bt_manager_inner.h"
  21. #include <sys_event.h>
  22. #include <sys_manager.h>
  23. #include <btservice_api.h>
  24. #include <acts_bluetooth/host_interface.h>
  25. #include "bt_porting_inner.h"
  26. #define BT_DISCOVER_LIST_MAX 4
  27. struct bt_discover_list {
  28. bd_address_t addr;
  29. int8_t rssi;
  30. uint8_t valid:1;
  31. uint8_t wait_req_name:1;
  32. };
  33. struct bt_discover_info {
  34. uint8_t discovering:1;
  35. btsrv_discover_result_cb cb;
  36. struct bt_discover_list dev_list[BT_DISCOVER_LIST_MAX];
  37. } discover_info;
  38. static void bt_discover_check_finish(void);
  39. static OS_MUTEX_DEFINE(bt_discover_mutex);
  40. static struct bt_discover_info *p_discover = &discover_info;
  41. /*
  42. Minor Device Class field - Audio/Video Major Class
  43. 7 6 5 4 3 2 Minor Device Class bit no. of CoD
  44. 0 0 0 0 0 0 Uncategorized, code not assigned
  45. 0 0 0 0 0 1 Wearable Headset Device
  46. 0 0 0 0 1 0 Hands-free Device
  47. 0 0 0 0 1 1 (Reserved)
  48. 0 0 0 1 0 0 Microphone
  49. 0 0 0 1 0 1 Loudspeaker
  50. 0 0 0 1 1 0 Headphones
  51. 0 0 0 1 1 1 Portable Audio
  52. 0 0 1 0 0 0 Car audio
  53. 0 0 1 0 0 1 Set-top box
  54. 0 0 1 0 1 0 HiFi Audio Device
  55. 0 0 1 0 1 1 VCR
  56. 0 0 1 1 0 0 Video Camera
  57. 0 0 1 1 0 1 Camcorder
  58. 0 0 1 1 1 0 Video Monitor
  59. 0 0 1 1 1 1 Video Display and Loudspeaker
  60. 0 1 0 0 0 0 Video Conferencing
  61. 0 1 0 0 0 1 (Reserved)
  62. 0 1 0 0 1 0 Gaming/Toy
  63. */
  64. #define BT_COD_RENDERING_SERVICE_BTI (0x1 << 18)
  65. #define BT_COD_AUDIO_SERVICE_BTI (0x1 << 21)
  66. #define BT_COD_MAJOR_DC_MASK (0x1F00)
  67. #define BT_COD_MAJOR_DC_AUDIO (0x400)
  68. #define BT_COD_MAJOR_DC_WEARABLE (0x700)
  69. #define BT_COD_MINOR_DC_MASK (0xFC)
  70. static const uint8_t bt_support_mdc[] = {0x04, 0x14, 0x18, 0x1C, 0x20, 0x28};
  71. static bool bt_discover_transmit_check_device(int cod)
  72. {
  73. uint8_t mdc, i;
  74. #ifdef CONFIG_OTA_PRODUCT_SUPPORT
  75. if ((cod & BT_COD_MAJOR_DC_WEARABLE) != BT_COD_MAJOR_DC_WEARABLE) {
  76. return false;
  77. }
  78. #else
  79. if (!(cod & (BT_COD_AUDIO_SERVICE_BTI | BT_COD_RENDERING_SERVICE_BTI))) {
  80. return false;
  81. }
  82. if ((cod & BT_COD_MAJOR_DC_MASK) != BT_COD_MAJOR_DC_AUDIO) {
  83. return false;
  84. }
  85. #endif
  86. mdc = (uint8_t)(cod & BT_COD_MINOR_DC_MASK);
  87. for (i=0; i<sizeof(bt_support_mdc); i++) {
  88. if (mdc == bt_support_mdc[i]) {
  89. return true;
  90. }
  91. }
  92. return false;
  93. }
  94. static void bt_discover_add_list(struct btsrv_discover_result *result)
  95. {
  96. uint8_t i, idle_pos = 0xFF, weakest_pos = 0xFF, save_pos = 0xFF;
  97. int8_t weakest_rssi = 127;
  98. for (i=0; i<BT_DISCOVER_LIST_MAX; i++) {
  99. if (p_discover->dev_list[i].valid) {
  100. if (!memcmp(&p_discover->dev_list[i].addr, &result->addr, sizeof(result->addr))) {
  101. if (p_discover->dev_list[i].wait_req_name && result->len) {
  102. p_discover->dev_list[i].wait_req_name = 0;
  103. }
  104. if (result->rssi > p_discover->dev_list[i].rssi) {
  105. p_discover->dev_list[i].rssi = result->rssi;
  106. }
  107. return;
  108. }
  109. if (weakest_rssi > p_discover->dev_list[i].rssi) {
  110. weakest_rssi = p_discover->dev_list[i].rssi;
  111. weakest_pos = i;
  112. }
  113. } else {
  114. if (idle_pos == 0xFF) {
  115. idle_pos = i;
  116. }
  117. }
  118. }
  119. if (idle_pos != 0xFF) {
  120. save_pos = idle_pos;
  121. } else {
  122. if (result->rssi > weakest_rssi) {
  123. save_pos = weakest_pos;
  124. }
  125. }
  126. if (save_pos != 0xFF) {
  127. memcpy(&p_discover->dev_list[save_pos].addr, &result->addr, sizeof(result->addr));
  128. p_discover->dev_list[save_pos].valid = 1;
  129. p_discover->dev_list[save_pos].rssi = result->rssi;
  130. if (result->len) {
  131. p_discover->dev_list[save_pos].wait_req_name = 0;
  132. } else {
  133. p_discover->dev_list[save_pos].wait_req_name = 1;
  134. }
  135. }
  136. }
  137. static void bt_discover_remote_name_cb(bt_addr_t *addr, uint8_t *name)
  138. {
  139. int i;
  140. struct btsrv_discover_result result;
  141. os_mutex_lock(&bt_discover_mutex, OS_FOREVER);
  142. if (addr && name) {
  143. for (i=0; i<BT_DISCOVER_LIST_MAX; i++) {
  144. if (p_discover->dev_list[i].valid &&
  145. (!memcmp(&p_discover->dev_list[i].addr, addr, sizeof(bt_addr_t)))) {
  146. memset(&result, 0, sizeof(result));
  147. memcpy(&result.addr, addr, sizeof(bt_addr_t));
  148. result.len = strlen(name);
  149. result.name = name;
  150. result.rssi = p_discover->dev_list[i].rssi;
  151. if (p_discover->cb) {
  152. p_discover->cb(&result);
  153. }
  154. }
  155. }
  156. }
  157. bt_discover_check_finish();
  158. os_mutex_unlock(&bt_discover_mutex);
  159. }
  160. static void bt_discover_check_finish(void)
  161. {
  162. int i, ret;
  163. struct btsrv_discover_result result;
  164. for (i=0; i<BT_DISCOVER_LIST_MAX; i++) {
  165. if (p_discover->dev_list[i].valid) {
  166. if (p_discover->dev_list[i].wait_req_name) {
  167. SYS_LOG_INF("Req name %2x%2x%2x%2x%2x%2x", p_discover->dev_list[i].addr.val[5],
  168. p_discover->dev_list[i].addr.val[4], p_discover->dev_list[i].addr.val[3],
  169. p_discover->dev_list[i].addr.val[2], p_discover->dev_list[i].addr.val[1],
  170. p_discover->dev_list[i].addr.val[0]);
  171. p_discover->dev_list[i].wait_req_name = 0;
  172. ret = btif_br_remote_name_req(&p_discover->dev_list[i].addr, bt_discover_remote_name_cb);
  173. if (ret) {
  174. continue;
  175. } else {
  176. return;
  177. }
  178. }
  179. }
  180. }
  181. /* Discover all finish */
  182. memset(&result, 0, sizeof(result));
  183. p_discover->discovering = 0;
  184. result.discover_finish = 1;
  185. if (p_discover->cb) {
  186. p_discover->cb(&result);
  187. }
  188. p_discover->cb = NULL;
  189. }
  190. static void bt_discover_result_cb(void *result)
  191. {
  192. int cod;
  193. struct btsrv_discover_result *cb_result = result;
  194. os_mutex_lock(&bt_discover_mutex, OS_FOREVER);
  195. if (!p_discover->discovering) {
  196. goto cb_exit;
  197. }
  198. if (cb_result->discover_finish) {
  199. bt_discover_check_finish();
  200. } else {
  201. cod = (cb_result->cod[2]<<16) + (cb_result->cod[1]<<8) + cb_result->cod[0];
  202. if (!bt_discover_transmit_check_device(cod)) {
  203. goto cb_exit;
  204. }
  205. bt_discover_add_list(cb_result);
  206. if (p_discover->cb) {
  207. p_discover->cb(result);
  208. }
  209. }
  210. cb_exit:
  211. os_mutex_unlock(&bt_discover_mutex);
  212. }
  213. int bt_manager_br_start_discover(struct btsrv_discover_param *param)
  214. {
  215. int ret;
  216. struct btsrv_discover_param dis_param;
  217. os_mutex_lock(&bt_discover_mutex, OS_FOREVER);
  218. if (p_discover->discovering) {
  219. ret = -EBUSY;
  220. goto start_exit;
  221. }
  222. dis_param.length = param->length;
  223. dis_param.num_responses = param->num_responses;
  224. dis_param.cb = &bt_discover_result_cb;
  225. ret = btif_br_start_discover(&dis_param);
  226. if (ret == 0) {
  227. p_discover->cb = param->cb;
  228. p_discover->discovering = 1;
  229. memset(p_discover->dev_list, 0, sizeof(p_discover->dev_list));
  230. }
  231. start_exit:
  232. os_mutex_unlock(&bt_discover_mutex);
  233. return ret;
  234. }
  235. int bt_manager_br_stop_discover(void)
  236. {
  237. int ret = 0;
  238. os_mutex_lock(&bt_discover_mutex, OS_FOREVER);
  239. if (!p_discover->discovering) {
  240. goto stop_exit;
  241. }
  242. p_discover->discovering = 0;
  243. p_discover->cb = NULL;
  244. ret = btif_br_stop_discover();
  245. stop_exit:
  246. os_mutex_unlock(&bt_discover_mutex);
  247. return ret;
  248. }