btsrv_sco.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658
  1. /*
  2. * Copyright (c) 2017 Actions Semi Co., Ltd.
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. /**
  7. * @file
  8. * @brief btsrvice sco
  9. */
  10. #define SYS_LOG_DOMAIN "btsrv_sco"
  11. #include "btsrv_os_common.h"
  12. #include "btsrv_inner.h"
  13. /* WAIT TODO: Not ready work with two sco link as the same time */
  14. //#define DECODE_PLAYBACK_MCU 1
  15. #define BTSPEECH_SCO_PACKET_SIZE (60) /* bytes */
  16. #define SCO_EXCEPT_CACHE_SIZE (60)
  17. #define SCO_CHECK_DROP_MUTE_FRAME_CNT (50) /* Check drop mute frame number */
  18. static btsrv_sco_callback sco_user_callback;
  19. struct btsrv_sco_context_info {
  20. struct bt_conn *sco_conn;
  21. uint8_t last_seq_no : 3;
  22. uint8_t first_frame : 1;
  23. uint8_t mute_frame : 1;
  24. uint8_t check_mute_finish : 1;
  25. uint8_t drop_flag : 1;
  26. uint8_t sco_rx_last_pkg_status_flag;
  27. uint16_t sco_rx_pkt_cache_len;
  28. uint8_t *sco_rx_cache;
  29. uint16_t frame_cnt;
  30. uint16_t frame_cached_len;
  31. uint16_t drop_frame;
  32. uint16_t sco_except_cache_len;
  33. uint8_t *sco_except_cache;
  34. };
  35. static struct btsrv_sco_context_info sco_context_info;
  36. static struct btsrv_sco_context_info *sco_context;
  37. static void _btsrv_sco_connected_cb(struct bt_conn *conn, uint8_t err)
  38. {
  39. if (hostif_bt_conn_get_type(conn) != BT_CONN_TYPE_SCO)
  40. return;
  41. /* ref for bt servcie process MSG_BTSRV_SCO_CONNECTED,
  42. * need unref conn after process MSG_BTSRV_SCO_CONNECTED.
  43. */
  44. hostif_bt_conn_ref(conn);
  45. btsrv_event_notify_ext(MSG_BTSRV_SCO, MSG_BTSRV_SCO_CONNECTED, conn, err);
  46. }
  47. static void _btsrv_sco_disconnected_cb(struct bt_conn *conn, uint8_t reason)
  48. {
  49. if (hostif_bt_conn_get_type(conn) != BT_CONN_TYPE_SCO)
  50. return;
  51. /* ref for bt servcie process MSG_BTSRV_SCO_DISCONNECTED,
  52. * need unref conn after process MSG_BTSRV_SCO_DISCONNECTED.
  53. */
  54. hostif_bt_conn_ref(conn);
  55. btsrv_event_notify_ext(MSG_BTSRV_SCO, MSG_BTSRV_SCO_DISCONNECTED, conn, reason);
  56. }
  57. static void _btsrv_sco_security_changed_cb(struct bt_conn *conn, bt_security_t level, enum bt_security_err err)
  58. {
  59. if (hostif_bt_conn_get_type(conn) != BT_CONN_TYPE_SCO)
  60. return;
  61. }
  62. static int _btsrv_sco_mscb_seq_convert(uint8_t seq)
  63. {
  64. const uint8_t msbc_head_flag[4] = {0x08, 0x38, 0xc8, 0xf8};
  65. int i;
  66. for (i = 0; i < ARRAY_SIZE(msbc_head_flag); i++) {
  67. if (seq == msbc_head_flag[i]) {
  68. return i;
  69. }
  70. }
  71. return -1;
  72. }
  73. #ifdef DECODE_PLAYBACK_MCU
  74. static int _btsrv_sco_insert_package(uint8_t *data, uint8_t len, int num)
  75. {
  76. SYS_LOG_INF("lost %d packages\n", num);
  77. while (num > 0) {
  78. data[0] = 0;
  79. data[1] = 1;
  80. sco_user_callback(BTSRV_SCO_DATA_INDICATED, data, BTSPEECH_SCO_PACKET_SIZE);
  81. sco_context->last_seq_no = (sco_context->last_seq_no & 0x03) + 1;
  82. num--;
  83. }
  84. return 0;
  85. }
  86. #endif
  87. static int _btsrv_find_really_msbc_pkt(uint8_t *data_buf, uint16_t pkt_length)
  88. {
  89. uint8_t i;
  90. uint8_t valid_len;
  91. uint8_t remain_len;
  92. for(i=3; i < (pkt_length - 2); i++)
  93. {
  94. if((data_buf[i] == 0xad) && (data_buf[i+1] == 0x00) && (data_buf[i+2] == 0x00))
  95. {
  96. remain_len = i - 2;
  97. valid_len = pkt_length - i + 2;
  98. memcpy(sco_context->sco_except_cache + sco_context->sco_except_cache_len, (uint8_t *)&data_buf[i-2], valid_len);
  99. sco_context->sco_except_cache_len += valid_len;
  100. //printk("get flag:%d_%d\n", remain_len, valid_len);
  101. return 0;
  102. }
  103. }
  104. return -1;
  105. }
  106. static int _btsrv_read_msbc_pkt(uint8_t *data, uint16_t pkt_length)
  107. {
  108. int ret = -1;
  109. if((data[2] == 0xad) && (data[3] == 0x00) && (data[4] == 0x00))
  110. {
  111. sco_context->sco_except_cache_len = 0;
  112. ret = 0;
  113. goto exit;
  114. }
  115. //printk("wrong head:%d_%d\n", pkt_length, sco_context->sco_except_cache_len);
  116. if (sco_context->sco_except_cache_len > 0) {
  117. uint8_t remain_len;
  118. uint8_t start_len;
  119. uint8_t temp_buf[120];
  120. memset(temp_buf, 0, 120);
  121. start_len = sco_context->sco_except_cache_len;
  122. remain_len = pkt_length - sco_context->sco_except_cache_len;
  123. memcpy(temp_buf, sco_context->sco_except_cache, sco_context->sco_except_cache_len);
  124. sco_context->sco_except_cache_len = 0;
  125. memcpy(&temp_buf[start_len], data, remain_len);
  126. //printf("get pkt:%d_%d\n", remain_len, start_len);
  127. _btsrv_find_really_msbc_pkt(data, pkt_length);
  128. memcpy(data, temp_buf, pkt_length);
  129. ret = 0;
  130. goto exit;
  131. }
  132. if (_btsrv_find_really_msbc_pkt(data, pkt_length) < 0) {
  133. //printk("wrong pkt:%d\n", pkt_length);
  134. memset(data, 0, pkt_length);
  135. ret = 0;
  136. }
  137. exit:
  138. return ret;
  139. }
  140. static void _btsrv_sco_convert_data_to_media(uint8_t *data, uint8_t len, uint8_t pkg_flag, uint8_t codec_id)
  141. {
  142. uint16_t seq_no = 0;
  143. if (len != BTSPEECH_SCO_PACKET_SIZE) {
  144. SYS_LOG_ERR("len error %d codec_id %d\n", len, codec_id);
  145. return;
  146. }
  147. if (codec_id == BT_CODEC_ID_MSBC) {
  148. if (pkg_flag) {
  149. seq_no = (sco_context->last_seq_no & 0x03) + 1;
  150. } else if (data[1] == 0) {
  151. pkg_flag = 1;
  152. } else {
  153. seq_no = _btsrv_sco_mscb_seq_convert(data[1]) + 1;
  154. }
  155. } else {
  156. seq_no = (sco_context->last_seq_no & 0x03) + 1;
  157. }
  158. #ifdef DECODE_PLAYBACK_MCU
  159. if (codec_id == BT_CODEC_ID_MSBC) {
  160. if (system_check_low_latencey_mode()) {
  161. if (sco_context->first_frame) {
  162. _btsrv_sco_insert_package(data, len, 2);
  163. sco_context->first_frame = 0;
  164. sco_context->drop_frame = 2;
  165. } else if(sco_context->drop_frame != 0){
  166. if(sco_context->drop_flag) {
  167. sco_context->drop_frame--;
  168. sco_context->drop_flag = 0;
  169. return;
  170. } else {
  171. sco_context->drop_flag = 1;
  172. }
  173. }
  174. }
  175. data[0] = 0;
  176. data[1] = pkg_flag;
  177. /* print_buffer((void *)data, 1, BTSPEECH_SCO_PACKET_SIZE, 16, -1); */
  178. sco_user_callback(BTSRV_SCO_DATA_INDICATED, data, BTSPEECH_SCO_PACKET_SIZE);
  179. } else {
  180. uint8_t send_data[62];
  181. send_data[0] = 0;
  182. send_data[1] = pkg_flag;
  183. memcpy(&send_data[2], data, BTSPEECH_SCO_PACKET_SIZE);
  184. /* print_buffer((void *)send_data, 1, BTSPEECH_SCO_PACKET_SIZE + 2, 16, -1); */
  185. sco_user_callback(BTSRV_SCO_DATA_INDICATED, send_data, BTSPEECH_SCO_PACKET_SIZE + 2);
  186. }
  187. #else
  188. if (codec_id == BT_CODEC_ID_MSBC) {
  189. uint8_t send_data[68];
  190. uint16_t offset = 0;
  191. *(uint16_t *)&send_data[offset] = pkg_flag;
  192. offset += 2;
  193. *(uint16_t *)&send_data[offset] = sco_context->frame_cnt;
  194. offset += 2;
  195. *(uint16_t *)&send_data[offset]= len - 2;
  196. offset += 2;
  197. *(uint16_t *)&send_data[offset]= 2;
  198. offset += 2;
  199. memcpy(&send_data[offset], &data[2], len - 2);
  200. /* print_buffer((void *)data, 1, BTSPEECH_SCO_PACKET_SIZE, 16, -1); */
  201. sco_user_callback(BTSRV_SCO_DATA_INDICATED, send_data, sizeof(send_data));
  202. } else {
  203. uint8_t send_data[68];
  204. uint16_t offset = 0;
  205. *(uint16_t *)&send_data[offset] = pkg_flag;
  206. offset += 2;
  207. *(uint16_t *)&send_data[offset] = sco_context->frame_cnt;
  208. offset += 2;
  209. *(uint16_t *)&send_data[offset]= len;
  210. offset += 2;
  211. *(uint16_t *)&send_data[offset]= 0;
  212. offset += 2;
  213. memcpy(&send_data[offset], data, len);
  214. //print_buffer((void *)send_data, 1, sizeof(send_data), 16, -1);
  215. sco_user_callback(BTSRV_SCO_DATA_INDICATED, send_data, sizeof(send_data));
  216. }
  217. #endif
  218. sco_context->last_seq_no = seq_no;
  219. }
  220. static void _btsrv_sco_save_data_to_cache(uint8_t *data, uint8_t len, uint8_t pkg_status_flag, uint8_t codec_id)
  221. {
  222. if (!sco_context->sco_rx_cache) {
  223. SYS_LOG_ERR("Drop sco data");
  224. return;
  225. }
  226. #if 0
  227. if (codec_id == BT_CODEC_ID_MSBC) {
  228. if (sco_context->sco_rx_pkt_cache_len != 0 && _btsrv_sco_mscb_seq_convert(data[1]) >= 0) {
  229. sco_context->sco_rx_pkt_cache_len = 0;
  230. } else if (sco_context->sco_rx_pkt_cache_len == 0 && _btsrv_sco_mscb_seq_convert(data[1]) < 0) {
  231. return;
  232. }
  233. }
  234. #endif
  235. if (sco_context->sco_rx_pkt_cache_len != 0) {
  236. if (pkg_status_flag == 0 && sco_context->sco_rx_last_pkg_status_flag == 0) {
  237. memcpy(sco_context->sco_rx_cache + sco_context->sco_rx_pkt_cache_len, data, len);
  238. sco_context->sco_rx_last_pkg_status_flag = pkg_status_flag;
  239. } else {
  240. if (sco_context->sco_rx_last_pkg_status_flag == 0) {
  241. memset(sco_context->sco_rx_cache, 0, sco_context->sco_rx_pkt_cache_len);
  242. }
  243. memset(sco_context->sco_rx_cache + sco_context->sco_rx_pkt_cache_len, 0, len);
  244. sco_context->sco_rx_last_pkg_status_flag = pkg_status_flag;
  245. pkg_status_flag = 1;
  246. }
  247. } else {
  248. if (pkg_status_flag == 0) {
  249. memcpy(sco_context->sco_rx_cache + sco_context->sco_rx_pkt_cache_len, data, len);
  250. } else {
  251. memset(sco_context->sco_rx_cache, 0, len);
  252. }
  253. sco_context->sco_rx_last_pkg_status_flag = pkg_status_flag;
  254. }
  255. sco_context->sco_rx_pkt_cache_len += len;
  256. while (sco_context->sco_rx_pkt_cache_len >= BTSPEECH_SCO_PACKET_SIZE) {
  257. int ret = 0;
  258. if (codec_id == BT_CODEC_ID_MSBC) {
  259. ret = _btsrv_read_msbc_pkt(sco_context->sco_rx_cache, BTSPEECH_SCO_PACKET_SIZE);
  260. if (ret) {
  261. memset(sco_context->sco_rx_cache, 0, BTSPEECH_SCO_PACKET_SIZE);
  262. pkg_status_flag = 1;
  263. ret = 0;
  264. }
  265. }
  266. if (ret == 0) {
  267. _btsrv_sco_convert_data_to_media(sco_context->sco_rx_cache, BTSPEECH_SCO_PACKET_SIZE, pkg_status_flag, codec_id);
  268. }
  269. sco_context->sco_rx_pkt_cache_len -= BTSPEECH_SCO_PACKET_SIZE;
  270. memcpy(sco_context->sco_rx_cache, sco_context->sco_rx_cache + BTSPEECH_SCO_PACKET_SIZE, sco_context->sco_rx_pkt_cache_len);
  271. }
  272. }
  273. #ifdef CONFIG_DEBUG_DATA_RATE
  274. static uint32_t start_time_stamp;
  275. static inline void _btsrv_sco_debug_reset(void)
  276. {
  277. start_time_stamp = 0;
  278. }
  279. static inline void _btsrv_sco_debug_data_rate(uint8_t len, uint8_t pkg_flag, uint8_t fill_zero)
  280. {
  281. static int received_data;
  282. static int frame_cnt;
  283. static int err_frame_cnt;
  284. if (!start_time_stamp) {
  285. frame_cnt = 0;
  286. err_frame_cnt = 0;
  287. received_data = 0;
  288. start_time_stamp = k_cycle_get_32();
  289. }
  290. received_data += len;
  291. frame_cnt++;
  292. if (pkg_flag && (fill_zero == 0)) {
  293. err_frame_cnt++;
  294. }
  295. if ((k_cycle_get_32() - start_time_stamp) > 5 * sys_clock_hw_cycles_per_sec()) {
  296. if (start_time_stamp != 0) {
  297. SYS_LOG_INF("sco data rate: %d b/s frame cnt (%d / %d) error rate %d %%\n",
  298. received_data / 5, err_frame_cnt, frame_cnt, err_frame_cnt * 100 / frame_cnt);
  299. }
  300. frame_cnt = 0;
  301. err_frame_cnt = 0;
  302. received_data = 0;
  303. start_time_stamp = k_cycle_get_32();
  304. }
  305. }
  306. #endif
  307. static bool _btsrv_sco_check_mute_frame(uint8_t *data, uint8_t len)
  308. {
  309. if (data[6] == 0 && data[7] == 0 && data[8] == 0 && data[9] == 0) {
  310. return true;
  311. }
  312. return false;
  313. }
  314. static void _btsrv_sco_data_avaliable_cb(struct bt_conn *conn, uint8_t *data, uint8_t len, uint8_t pkg_flag)
  315. {
  316. uint8_t codec_id = 0, sample_rate = 0, fill_zero = 0;
  317. struct bt_conn *base_conn = btsrv_rdm_get_base_conn_by_sco(conn);
  318. if ((btsrv_rdm_hfp_get_actived_sco() != conn && base_conn != btsrv_rdm_get_tws_by_role(BTSRV_TWS_MASTER)
  319. && base_conn != btsrv_rdm_get_tws_by_role(BTSRV_TWS_SLAVE)) || !base_conn) {
  320. return;
  321. }
  322. if(base_conn == btsrv_rdm_get_tws_by_role(BTSRV_TWS_MASTER) && sco_context->sco_conn){
  323. btsrv_event_notify_malloc(MSG_BTSRV_TWS, MSG_BTSRV_TWS_SCO_DATA, data, len,len);
  324. return;
  325. }
  326. btsrv_rdm_hfp_get_codec_info(base_conn, &codec_id, &sample_rate);
  327. if (codec_id != BT_CODEC_ID_MSBC && codec_id != BT_CODEC_ID_CVSD) {
  328. SYS_LOG_ERR("error codec id %d\n", codec_id);
  329. return;
  330. }
  331. if (conn == btsrv_rdm_hfp_get_actived_sco()) {
  332. sco_context->frame_cached_len += len;
  333. if (sco_context->frame_cached_len >= BTSPEECH_SCO_PACKET_SIZE) {
  334. sco_context->frame_cnt++;
  335. sco_context->frame_cached_len -= BTSPEECH_SCO_PACKET_SIZE;
  336. }
  337. if (sco_context->frame_cnt < SCO_CHECK_DROP_MUTE_FRAME_CNT && !sco_context->check_mute_finish) {
  338. if (!sco_context->mute_frame) {
  339. if (_btsrv_sco_check_mute_frame(data, len)) {
  340. sco_context->mute_frame = 1;
  341. } else {
  342. SYS_LOG_DBG("drop frame %d", sco_context->frame_cnt);
  343. return;
  344. }
  345. } else {
  346. if (!_btsrv_sco_check_mute_frame(data, len)) {
  347. pkg_flag = 1;
  348. fill_zero = 1;
  349. SYS_LOG_INF("fill zero %d", sco_context->frame_cnt);
  350. }
  351. }
  352. } else {
  353. sco_context->check_mute_finish = 1;
  354. }
  355. }
  356. #ifdef CONFIG_DEBUG_DATA_RATE
  357. _btsrv_sco_debug_data_rate(len, pkg_flag, fill_zero);
  358. #endif
  359. if (len == BTSPEECH_SCO_PACKET_SIZE) {
  360. int ret = 0;
  361. if (codec_id == BT_CODEC_ID_MSBC) {
  362. ret = _btsrv_read_msbc_pkt(data, len);
  363. if (ret) {
  364. memset(data, 0, len);
  365. pkg_flag = 1;
  366. ret = 0;
  367. }
  368. }
  369. if (ret == 0) {
  370. _btsrv_sco_convert_data_to_media(data, len, pkg_flag, codec_id);
  371. }
  372. } else {
  373. _btsrv_sco_save_data_to_cache(data, len, pkg_flag, codec_id);
  374. }
  375. }
  376. static struct bt_conn_cb sco_conn_callbacks = {
  377. .connected = _btsrv_sco_connected_cb,
  378. .disconnected = _btsrv_sco_disconnected_cb,
  379. .security_changed = _btsrv_sco_security_changed_cb,
  380. .rx_sco_data = _btsrv_sco_data_avaliable_cb,
  381. };
  382. static void btsrv_sco_disconnect_timer_handler(struct thread_timer *ttimer, void *expiry_fn_arg)
  383. {
  384. struct bt_conn *sco_conn = (struct bt_conn *)expiry_fn_arg;
  385. struct bt_conn *br_conn = hostif_bt_conn_get_acl_conn_by_sco(sco_conn);
  386. struct bt_conn *second_br_conn = btsrv_rdm_hfp_get_second_dev();
  387. int other_state = btsrv_rdm_hfp_get_state(second_br_conn);
  388. if(br_conn && (br_conn != btsrv_rdm_hfp_get_actived() ||
  389. second_br_conn == NULL || other_state > BTSRV_HFP_STATE_LINKED)){
  390. hostif_bt_conn_ref(sco_conn);
  391. int err = hostif_bt_conn_disconnect(sco_conn, BT_HCI_ERR_REMOTE_USER_TERM_CONN);
  392. if (err) {
  393. SYS_LOG_INF("Disconnection failed (err %d)\n", err);
  394. }else
  395. btsrv_rdm_hfp_set_sco_state(br_conn,BTSRV_SCO_STATE_DISCONNECT);
  396. hostif_bt_conn_unref(sco_conn);
  397. SYS_LOG_INF("");
  398. }
  399. }
  400. void btsrv_sco_disconnect(struct bt_conn *sco_conn){
  401. uint32_t creat_time = -1,diff;
  402. struct thread_timer *sco_disconnect_timer = NULL;
  403. struct bt_conn *br_conn = hostif_bt_conn_get_acl_conn_by_sco(sco_conn);
  404. if(br_conn){
  405. btsrv_rdm_get_sco_creat_time(br_conn, &creat_time);
  406. diff = os_uptime_get_32() - creat_time;
  407. sco_disconnect_timer = btsrv_rdm_get_sco_disconnect_timer(br_conn);
  408. if (creat_time > 0 && diff > 500){
  409. if(sco_disconnect_timer && thread_timer_is_running(sco_disconnect_timer))
  410. thread_timer_stop(sco_disconnect_timer);
  411. hostif_bt_conn_ref(sco_conn);
  412. int err = hostif_bt_conn_disconnect(sco_conn, BT_HCI_ERR_REMOTE_USER_TERM_CONN);
  413. if (err) {
  414. SYS_LOG_INF("Disconnection failed (err %d)\n", err);
  415. }else
  416. btsrv_rdm_hfp_set_sco_state(br_conn,BTSRV_SCO_STATE_DISCONNECT);
  417. hostif_bt_conn_unref(sco_conn);
  418. SYS_LOG_INF("");
  419. }else if(sco_disconnect_timer){
  420. if(!thread_timer_is_running(sco_disconnect_timer)){
  421. thread_timer_init(sco_disconnect_timer, btsrv_sco_disconnect_timer_handler
  422. , (void *)sco_conn);
  423. thread_timer_start(sco_disconnect_timer, 500-diff, 0);
  424. }
  425. }
  426. }
  427. }
  428. static void _btsrv_sco_connected(struct bt_conn *conn)
  429. {
  430. struct bt_conn *br_conn;
  431. int hfp_state;
  432. if (sco_context) {
  433. br_conn = hostif_bt_conn_get_acl_conn_by_sco(conn);
  434. if ((br_conn == NULL) || (btsrv_rdm_sco_connected(br_conn, conn) < 0)) {
  435. return;
  436. }
  437. hfp_state = btsrv_rdm_hfp_get_state(br_conn);
  438. SYS_LOG_INF("other_state %d\n", hfp_state);
  439. SYS_LOG_INF("allow %d\n", btsrv_allow_sco_connect());
  440. if (!btsrv_allow_sco_connect()/* || (hfp_state == BTSRV_HFP_STATE_CALL_INCOMING)*/) {
  441. /* disconnect sco if upper application(ota) not allow */
  442. hostif_bt_conn_ref(conn);
  443. btsrv_sco_disconnect(conn);
  444. btsrv_hfp_rejected(conn);
  445. btsrv_rdm_set_sco_connected_reject(br_conn, 1);
  446. return;
  447. } else {
  448. btsrv_rdm_set_sco_connected_reject(br_conn, 0);
  449. }
  450. if(btsrv_rdm_get_hfp_role(br_conn) == BTSRV_HFP_ROLE_HF)
  451. btsrv_hfp_set_status(br_conn, BTSRV_HFP_STATE_SCO_ESTABLISHED);
  452. else
  453. btsrv_hfp_ag_set_status(br_conn, BTSRV_HFP_STATE_SCO_ESTABLISHED);
  454. if (br_conn == btsrv_rdm_hfp_get_actived()
  455. || br_conn == btsrv_rdm_get_tws_by_role(BTSRV_TWS_SLAVE)) {
  456. if (!sco_context->sco_conn) {
  457. hostif_bt_conn_ref(conn);
  458. sco_context->sco_conn = conn;
  459. } else {
  460. btsrv_sco_disconnect(sco_context->sco_conn);
  461. sco_context->sco_conn = conn;
  462. hostif_bt_conn_ref(conn);
  463. }
  464. sco_context->sco_rx_last_pkg_status_flag = 0;
  465. sco_context->sco_rx_pkt_cache_len = 0;
  466. sco_context->first_frame = 1;
  467. sco_context->drop_flag = 0;
  468. sco_context->mute_frame = 0;
  469. sco_context->check_mute_finish = 0;
  470. sco_context->frame_cnt = 0;
  471. sco_context->frame_cached_len = 0;
  472. sco_context->last_seq_no = 0;
  473. sco_context->sco_except_cache_len = 0;
  474. #ifdef CONFIG_DEBUG_DATA_RATE
  475. _btsrv_sco_debug_reset();
  476. #endif
  477. } else {
  478. /* disconnect sco for deactive dev */
  479. if (br_conn != btsrv_rdm_get_tws_by_role(BTSRV_TWS_MASTER)) {
  480. hostif_bt_conn_ref(conn);
  481. btsrv_sco_disconnect(conn);
  482. } else {
  483. //just ref conn,this conn will be send to tws and save in tws_manager->tws_session->sco_conn
  484. hostif_bt_conn_ref(conn);
  485. btsrv_event_notify(MSG_BTSRV_TWS, MSG_BTSRV_SCO_CONNECTED, conn);
  486. }
  487. }
  488. }
  489. }
  490. static void _btsrv_sco_disconnected(struct bt_conn *conn)
  491. {
  492. struct bt_conn *br_conn = btsrv_rdm_get_base_conn_by_sco(conn);
  493. if (br_conn == NULL) {
  494. SYS_LOG_WRN("conn not recorded\n");
  495. return;
  496. }
  497. struct thread_timer *sco_disconnect_timer = btsrv_rdm_get_sco_disconnect_timer(br_conn);
  498. if(sco_disconnect_timer && thread_timer_is_running(sco_disconnect_timer))
  499. thread_timer_stop(sco_disconnect_timer);
  500. if (!btsrv_rdm_is_sco_connected_reject(br_conn)) {
  501. if(btsrv_rdm_get_hfp_role(br_conn) == BTSRV_HFP_ROLE_HF)
  502. btsrv_hfp_set_status(br_conn, BTSRV_HFP_STATE_SCO_RELEASED);
  503. else
  504. btsrv_hfp_ag_set_status(br_conn, BTSRV_HFP_STATE_SCO_RELEASED);
  505. if(br_conn == btsrv_rdm_get_tws_by_role(BTSRV_TWS_MASTER)){
  506. btsrv_event_notify(MSG_BTSRV_TWS, MSG_BTSRV_SCO_DISCONNECTED, conn);
  507. }
  508. }
  509. btsrv_rdm_set_sco_connected_reject(br_conn, 0);
  510. btsrv_rdm_sco_disconnected(conn);
  511. hostif_bt_conn_unref(conn);
  512. if (sco_context && sco_context->sco_conn == conn) {
  513. sco_context->sco_conn = NULL;
  514. }
  515. }
  516. static int _btsrv_sco_init(btsrv_sco_callback cb)
  517. {
  518. sco_context = &sco_context_info;
  519. #if CONFIG_MEDIA
  520. sco_context->sco_rx_cache = media_mem_get_cache_pool(RX_SCO, AUDIO_STREAM_VOICE);
  521. sco_context->sco_except_cache = bt_mem_malloc(SCO_EXCEPT_CACHE_SIZE);
  522. if (!sco_context->sco_except_cache) {
  523. return -1;
  524. }
  525. #endif
  526. hostif_bt_conn_cb_register((struct bt_conn_cb *)&sco_conn_callbacks);
  527. sco_user_callback = cb;
  528. return 0;
  529. }
  530. static int _btsrv_sco_deinit(void)
  531. {
  532. if (sco_context->sco_except_cache) {
  533. bt_mem_free(sco_context->sco_except_cache);
  534. }
  535. sco_context = NULL;
  536. sco_user_callback = NULL;
  537. return 0;
  538. }
  539. int btsrv_sco_process(struct app_msg *msg)
  540. {
  541. switch (_btsrv_get_msg_param_cmd(msg)) {
  542. case MSG_BTSRV_SCO_START:
  543. SYS_LOG_INF("MSG_BTSRV_SCO_START\n");
  544. _btsrv_sco_init(msg->ptr);
  545. break;
  546. case MSG_BTSRV_SCO_STOP:
  547. SYS_LOG_INF("MSG_BTSRV_SCO_STOP\n");
  548. _btsrv_sco_deinit();
  549. break;
  550. case MSG_BTSRV_SCO_CONNECTED:
  551. SYS_LOG_INF("MSG_BTSRV_SCO_CONNECTED\n");
  552. _btsrv_sco_connected(msg->ptr);
  553. hostif_bt_conn_unref(msg->ptr); /* unref conn for ref in _btsrv_sco_connected_cb */
  554. break;
  555. case MSG_BTSRV_SCO_DISCONNECTED:
  556. SYS_LOG_INF("MSG_BTSRV_SCO_DISCONNECTED\n");
  557. _btsrv_sco_disconnected(msg->ptr);
  558. hostif_bt_conn_unref(msg->ptr); /* unref conn for ref in _btsrv_sco_disconnected_cb */
  559. break;
  560. }
  561. return 0;
  562. }
  563. struct bt_conn *btsrv_sco_get_conn(void)
  564. {
  565. if (sco_context)
  566. return sco_context->sco_conn;
  567. return NULL;
  568. }