btsrv_avrcp.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800
  1. /*
  2. * Copyright (c) 2017 Actions Semi Co., Ltd.
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. /**
  7. * @file
  8. * @brief btsrvice avrcp
  9. */
  10. #define SYS_LOG_DOMAIN "btsrv_avrcp"
  11. #include "btsrv_os_common.h"
  12. #include "btsrv_inner.h"
  13. #define AVRCP_CTRL_PASS_CHECK_INTERVAL 5 /* 5ms */
  14. #define AVRCP_WAIT_ACCEPT_PUSH_TIMEOUT 500 /* 500ms */
  15. #define AVRCP_CTRL_PASS_DELAY_RELEASE_TIME 5 /* 5ms */
  16. #define AVRCP_GET_POS_TIMEOUT 2000 /* 2000ms */
  17. enum {
  18. AVRCP_PASS_STATE_IDLE,
  19. AVRCP_PASS_STATE_WAIT_ACCEPT_PUSH,
  20. AVRCP_PASS_STATE_WAIT_DELAY_RELEASE,
  21. AVRCP_PASS_STATE_CONTINUE_START,
  22. };
  23. static btsrv_avrcp_callback_t *avrcp_user_callback;
  24. static struct thread_timer sync_volume_timer;
  25. static struct thread_timer ctrl_pass_timer;
  26. struct btsrv_avrcp_stack_cb {
  27. struct bt_conn *conn;
  28. union {
  29. uint8_t event_id;
  30. uint8_t op_id;
  31. uint8_t cmd;
  32. };
  33. uint8_t status;
  34. uint32_t pos;
  35. uint32_t len;
  36. };
  37. static void _btsrv_avrcp_ctrl_connected_cb(struct bt_conn *conn)
  38. {
  39. btsrv_event_notify(MSG_BTSRV_CONNECT, MSG_BTSRV_AVRCP_CONNECTED, conn);
  40. }
  41. static void _btsrv_avrcp_ctrl_disconnected_cb(struct bt_conn *conn)
  42. {
  43. /* TODO: Disconnected process order: btsrv_tws->btsrv_avrcp->btsrv_connect */
  44. btsrv_event_notify(MSG_BTSRV_CONNECT, MSG_BTSRV_AVRCP_DISCONNECTED, conn);
  45. }
  46. static void _btsrv_avrcp_ctrl_event_notify_cb(struct bt_conn *conn, uint8_t event_id, uint8_t status)
  47. {
  48. struct btsrv_avrcp_stack_cb param;
  49. param.conn = conn;
  50. param.event_id = event_id;
  51. param.status = status;
  52. btsrv_event_notify_malloc(MSG_BTSRV_AVRCP, MSG_BTSRV_AVRCP_NOTIFY_CB, (uint8_t *)&param, sizeof(param), 0);
  53. }
  54. static void btsrv_avrcp_ctrl_event_notify_proc(void *in_param)
  55. {
  56. int cb_ev = -1;
  57. struct btsrv_avrcp_stack_cb *param = in_param;
  58. struct bt_conn *conn = param->conn;
  59. uint8_t event_id = param->event_id;
  60. uint8_t status = param->status;
  61. #ifdef CONFIG_BT_A2DP
  62. uint32_t start_time = 0;
  63. uint32_t delay_time = btsrv_volume_sync_delay_ms();
  64. #endif
  65. SYS_LOG_INF("Avrcp event notify 0x%x %d %d", hostif_bt_conn_get_handle(conn), event_id, status);
  66. if (event_id != BT_AVRCP_EVENT_PLAYBACK_STATUS_CHANGED &&
  67. event_id != BT_AVRCP_EVENT_VOLUME_CHANGED &&
  68. event_id != BT_AVRCP_EVENT_TRACK_CHANGED) {
  69. SYS_LOG_WRN("avrcp is NULL or event_id %d not care\n", event_id);
  70. return;
  71. }
  72. #ifdef CONFIG_BT_A2DP
  73. if (event_id == BT_AVRCP_EVENT_VOLUME_CHANGED &&
  74. ((btsrv_rdm_a2dp_get_actived() == conn &&
  75. btsrv_rdm_is_a2dp_stream_open(conn))
  76. #ifdef CONFIG_BT_A2DP_TRS
  77. || btsrv_rdm_get_trs_mode(conn)
  78. #endif
  79. )) {
  80. #ifdef CONFIG_BT_A2DP_TRS
  81. if (btsrv_rdm_get_trs_mode(conn)) {
  82. if (avrcp_user_callback->trs_set_volume_cb)
  83. avrcp_user_callback->trs_set_volume_cb(hostif_bt_conn_get_handle(conn), status);
  84. }
  85. else
  86. #endif
  87. {
  88. btsrv_rdm_get_a2dp_start_time(conn, &start_time);
  89. if (start_time && (os_uptime_get_32() - start_time) > delay_time
  90. && !thread_timer_is_running(&sync_volume_timer)) {
  91. avrcp_user_callback->set_volume_cb(hostif_bt_conn_get_handle(conn), status);
  92. }
  93. }
  94. return;
  95. }
  96. #else
  97. if (event_id == BT_AVRCP_EVENT_VOLUME_CHANGED &&
  98. btsrv_rdm_avrcp_get_actived() == conn){
  99. avrcp_user_callback->set_volume_cb(hostif_bt_conn_get_handle(conn), status);
  100. return;
  101. }
  102. #endif
  103. else if (event_id == BT_AVRCP_EVENT_TRACK_CHANGED){
  104. cb_ev = BTSRV_AVRCP_TRACK_CHANGE;
  105. }
  106. else if(event_id == BT_AVRCP_EVENT_PLAYBACK_STATUS_CHANGED) {
  107. switch (status) {
  108. case BT_AVRCP_PLAYBACK_STATUS_STOPPED:
  109. cb_ev = BTSRV_AVRCP_STOPED;
  110. break;
  111. case BT_AVRCP_PLAYBACK_STATUS_PLAYING:
  112. cb_ev = BTSRV_AVRCP_PLAYING;
  113. break;
  114. case BT_AVRCP_PLAYBACK_STATUS_PAUSED:
  115. cb_ev = BTSRV_AVRCP_PAUSED;
  116. break;
  117. case BT_AVRCP_PLAYBACK_STATUS_FWD_SEEK:
  118. case BT_AVRCP_PLAYBACK_STATUS_REV_SEEK:
  119. case BT_AVRCP_PLAYBACK_STATUS_ERROR:
  120. break;
  121. }
  122. }
  123. if (cb_ev > 0 && btsrv_rdm_avrcp_get_actived() == conn) {
  124. avrcp_user_callback->event_cb(hostif_bt_conn_get_handle(conn), cb_ev, NULL);
  125. }
  126. }
  127. static void _btsrv_avrcp_ctrl_get_volume_cb(struct bt_conn *conn, uint8_t *volume)
  128. {
  129. avrcp_user_callback->get_volume_cb(hostif_bt_conn_get_handle(conn), volume);
  130. SYS_LOG_INF("Avrcp remote reg notify get vol %d", (*volume));
  131. }
  132. static void _btsrv_avrcp_ctrl_pass_ctrl_cb(struct bt_conn *conn, uint8_t op_id, uint8_t state)
  133. {
  134. struct btsrv_avrcp_stack_cb param;
  135. param.conn = conn;
  136. param.op_id = op_id;
  137. param.status = state;
  138. btsrv_event_notify_malloc(MSG_BTSRV_AVRCP, MSG_BTSRV_AVRCP_PASS_CTRL_CB, (uint8_t *)&param, sizeof(param), 0);
  139. }
  140. static void _btsrv_avrcp_get_play_state_cb(struct bt_conn *conn, uint8_t cmd,
  141. uint32_t *song_len, uint32_t *song_pos, uint8_t *play_state)
  142. {
  143. struct btsrv_avrcp_stack_cb param;
  144. if (cmd) {
  145. /* Receive get play state command, set output value. */
  146. //*song_len = 0x1234;
  147. //*song_pos = 0x1111;
  148. //*play_state = 1;
  149. return;
  150. }
  151. param.conn = conn;
  152. param.cmd = cmd,
  153. param.status = (*play_state);
  154. param.len = (*song_len);
  155. param.pos = (*song_pos);
  156. btsrv_event_notify_malloc(MSG_BTSRV_AVRCP, MSG_BTSRV_AVRCP_PLAY_STATE_CB, (uint8_t *)&param, sizeof(param), 0);
  157. }
  158. static void btsrv_avrcp_play_state_proc(void *in_param)
  159. {
  160. struct btsrv_avrcp_stack_cb *param = in_param;
  161. struct bt_conn *conn = param->conn;
  162. uint32_t pos = param->pos;
  163. if (btsrv_rdm_avrcp_get_getting_pos_time(conn) == 1) {
  164. btsrv_rdm_avrcp_set_getting_pos_time(conn, 0);
  165. if (btsrv_rdm_avrcp_get_actived() == conn) {
  166. avrcp_user_callback->event_cb(hostif_bt_conn_get_handle(conn), BTSRV_AVRCP_PLAYBACK_POS, &pos);
  167. }
  168. }
  169. }
  170. static void btsrv_avrcp_ctrl_rsp_pass_proc(struct bt_conn *conn, uint8_t op_id, uint8_t state)
  171. {
  172. struct btsrv_rdm_avrcp_pass_info *info;
  173. if (state != BT_AVRCP_RSP_STATE_PASS_THROUGH_PUSHED) {
  174. return;
  175. }
  176. info = btsrv_rdm_avrcp_get_pass_info(conn);
  177. if (!info) {
  178. return;
  179. }
  180. if (info->op_id == op_id && info->pass_state == AVRCP_PASS_STATE_WAIT_ACCEPT_PUSH) {
  181. info->pass_state = AVRCP_PASS_STATE_WAIT_DELAY_RELEASE;
  182. info->op_time = os_uptime_get_32();
  183. }
  184. }
  185. static void btsrv_avrcp_ctrl_pass_ctrl_proc(void *in_param)
  186. {
  187. struct btsrv_avrcp_stack_cb *param = in_param;
  188. struct bt_conn *conn = param->conn;
  189. uint8_t op_id = param->op_id;
  190. uint8_t state = param->status;
  191. #ifdef CONFIG_BT_A2DP_TRS
  192. if (btsrv_trs_avrcp_ctrl_pass_ctrl_cb(conn, op_id, state) == true) {
  193. SYS_LOG_INF("trs op_id 0x%x state 0x%x", op_id, state);
  194. return;
  195. }
  196. #endif
  197. SYS_LOG_INF("op_id 0x%x state 0x%x", op_id, state);
  198. if (state == BT_AVRCP_RSP_STATE_PASS_THROUGH_PUSHED ||
  199. state == BT_AVRCP_RSP_STATE_PASS_THROUGH_RELEASED) {
  200. btsrv_avrcp_ctrl_rsp_pass_proc(conn, op_id, state);
  201. } else if (btsrv_rdm_avrcp_get_actived() == conn) {
  202. uint8_t cmd;
  203. switch(op_id){
  204. case AVRCP_OPERATION_ID_PLAY:
  205. cmd = BTSRV_AVRCP_CMD_PLAY;
  206. break;
  207. case AVRCP_OPERATION_ID_PAUSE:
  208. cmd = BTSRV_AVRCP_CMD_PAUSE;
  209. break;
  210. case AVRCP_OPERATION_ID_VOLUME_UP:
  211. cmd = BTSRV_AVRCP_CMD_VOLUMEUP;
  212. break;
  213. case AVRCP_OPERATION_ID_VOLUME_DOWN:
  214. cmd = BTSRV_AVRCP_CMD_VOLUMEDOWN;
  215. break;
  216. case AVRCP_OPERATION_ID_MUTE:
  217. cmd = BTSRV_AVRCP_CMD_MUTE;
  218. break;
  219. default:
  220. SYS_LOG_ERR("op_id 0x%x not support", op_id);
  221. return;
  222. }
  223. avrcp_user_callback->pass_ctrl_cb(hostif_bt_conn_get_handle(conn), cmd, state);
  224. }
  225. }
  226. static void _btsrv_avrcp_ctrl_update_id3_info_cb(struct bt_conn *conn, struct id3_info * info)
  227. {
  228. if (btsrv_rdm_avrcp_get_actived() == conn) {
  229. avrcp_user_callback->event_cb(hostif_bt_conn_get_handle(conn), BTSRV_AVRCP_UPDATE_ID3_INFO, info);
  230. }
  231. }
  232. static void _btsrv_avrcp_ctrl_playback_pos_cb(struct bt_conn *conn, uint32_t pos)
  233. {
  234. struct btsrv_avrcp_stack_cb param;
  235. param.conn = conn;
  236. param.pos = pos;
  237. btsrv_event_notify_malloc(MSG_BTSRV_AVRCP, MSG_BTSRV_AVRCP_PLAYBACK_POS_CB, (uint8_t *)&param, sizeof(param), 0);
  238. }
  239. static void btsrv_avrcp_ctrl_playback_pos_proc(void *in_param)
  240. {
  241. struct btsrv_avrcp_stack_cb *param = in_param;
  242. struct bt_conn *conn = param->conn;
  243. uint32_t pos = param->pos;
  244. if (btsrv_rdm_avrcp_get_getting_pos_time(conn) == 1) {
  245. btsrv_rdm_avrcp_set_getting_pos_time(conn, 0);
  246. if (btsrv_rdm_avrcp_get_actived() == conn) {
  247. avrcp_user_callback->event_cb(hostif_bt_conn_get_handle(conn), BTSRV_AVRCP_PLAYBACK_POS, &pos);
  248. }
  249. }
  250. }
  251. static const struct bt_avrcp_app_cb btsrv_avrcp_ctrl_cb = {
  252. .connected = _btsrv_avrcp_ctrl_connected_cb,
  253. .disconnected = _btsrv_avrcp_ctrl_disconnected_cb,
  254. .notify = _btsrv_avrcp_ctrl_event_notify_cb,
  255. .pass_ctrl = _btsrv_avrcp_ctrl_pass_ctrl_cb,
  256. .get_play_status = _btsrv_avrcp_get_play_state_cb,
  257. .get_volume = _btsrv_avrcp_ctrl_get_volume_cb,
  258. .update_id3_info = _btsrv_avrcp_ctrl_update_id3_info_cb,
  259. .playback_pos = _btsrv_avrcp_ctrl_playback_pos_cb,
  260. };
  261. static void btsrv_avrcp_ctrl_pass_timer_start_stop(bool start)
  262. {
  263. if (start) {
  264. if (!thread_timer_is_running(&ctrl_pass_timer)) {
  265. thread_timer_start(&ctrl_pass_timer, AVRCP_CTRL_PASS_CHECK_INTERVAL, AVRCP_CTRL_PASS_CHECK_INTERVAL);
  266. }
  267. } else {
  268. if (thread_timer_is_running(&ctrl_pass_timer)) {
  269. thread_timer_stop(&ctrl_pass_timer);
  270. }
  271. }
  272. }
  273. static void connected_dev_cb_check_ctrl_pass(struct bt_conn *base_conn, uint8_t tws_dev, void *cb_param)
  274. {
  275. int *need_timer = cb_param;
  276. struct btsrv_rdm_avrcp_pass_info *info;
  277. uint32_t time, check_timeout = 0;
  278. if (tws_dev) {
  279. return;
  280. }
  281. info = btsrv_rdm_avrcp_get_pass_info(base_conn);
  282. if (!info) {
  283. SYS_LOG_ERR("not connected??\n");
  284. return;
  285. }
  286. if (info->op_id == 0 ||
  287. info->pass_state == AVRCP_PASS_STATE_IDLE ||
  288. info->pass_state == AVRCP_PASS_STATE_CONTINUE_START) {
  289. return;
  290. }
  291. *need_timer = 1;
  292. time = os_uptime_get_32();
  293. if (info->pass_state == AVRCP_PASS_STATE_WAIT_ACCEPT_PUSH) {
  294. check_timeout = AVRCP_WAIT_ACCEPT_PUSH_TIMEOUT;
  295. } else if (info->pass_state == AVRCP_PASS_STATE_WAIT_DELAY_RELEASE) {
  296. check_timeout = AVRCP_CTRL_PASS_DELAY_RELEASE_TIME;
  297. }
  298. if ((time - info->op_time) > check_timeout) {
  299. hostif_bt_avrcp_ct_pass_through_cmd(base_conn, info->op_id, false);
  300. info->pass_state = AVRCP_PASS_STATE_IDLE;
  301. info->op_id = 0;
  302. }
  303. }
  304. static void btsrv_avrcp_ctrl_pass_timer_handler(struct thread_timer *ttimer, void *expiry_fn_arg)
  305. {
  306. int need_timer = 0;
  307. btsrv_rdm_get_connected_dev(connected_dev_cb_check_ctrl_pass, &need_timer);
  308. if (!need_timer) {
  309. btsrv_avrcp_ctrl_pass_timer_start_stop(false);
  310. }
  311. }
  312. #define AVRCP_SYNC_TO_REMOTE_INTERVAL 300
  313. static uint32_t avrcp_pre_sync_vol_time;
  314. static void btsrv_avrcp_sync_volume_timer_handler(struct thread_timer *ttimer, void *expiry_fn_arg)
  315. {
  316. uint8_t volume;
  317. struct bt_conn *avrcp_conn = btsrv_rdm_avrcp_get_actived();
  318. avrcp_user_callback->get_volume_cb(hostif_bt_conn_get_handle(avrcp_conn), &volume);
  319. SYS_LOG_INF("Avrcp sync vol local to remote vol %d", volume);
  320. avrcp_pre_sync_vol_time = os_uptime_get_32();
  321. //if (!btsrv_is_pts_test()) {
  322. hostif_bt_avrcp_tg_notify_change(avrcp_conn, volume);
  323. //}
  324. }
  325. int btsrv_avrcp_init(btsrv_avrcp_callback_t *cb)
  326. {
  327. hostif_bt_avrcp_cttg_register_cb((struct bt_avrcp_app_cb *)&btsrv_avrcp_ctrl_cb);
  328. avrcp_user_callback = cb;
  329. thread_timer_init(&sync_volume_timer, btsrv_avrcp_sync_volume_timer_handler, NULL);
  330. thread_timer_init(&ctrl_pass_timer, btsrv_avrcp_ctrl_pass_timer_handler, NULL);
  331. #ifdef CONFIG_BT_A2DP_TRS
  332. btsrv_trs_avrcp_init(cb);
  333. #endif
  334. return 0;
  335. }
  336. int btsrv_avrcp_deinit(void)
  337. {
  338. btsrv_avrcp_ctrl_pass_timer_start_stop(false);
  339. if (thread_timer_is_running(&sync_volume_timer)) {
  340. thread_timer_stop(&sync_volume_timer);
  341. }
  342. #ifdef CONFIG_BT_A2DP_TRS
  343. btsrv_trs_avrcp_deinit();
  344. #endif
  345. return 0;
  346. }
  347. int btsrv_avrcp_disconnect(struct bt_conn *conn)
  348. {
  349. if (conn && btsrv_rdm_is_avrcp_connected(conn)) {
  350. SYS_LOG_INF("avrcp_disconnect\n");
  351. hostif_bt_avrcp_cttg_disconnect(conn);
  352. }
  353. #ifdef CONFIG_BT_A2DP_TRS
  354. struct thread_timer *trs_discover_timer = btsrv_rdm_get_trs_discover_timer(conn);
  355. if(trs_discover_timer && thread_timer_is_running(trs_discover_timer))
  356. thread_timer_stop(trs_discover_timer);
  357. #endif
  358. return 0;
  359. }
  360. int btsrv_avrcp_connect(struct bt_conn *conn)
  361. {
  362. int ret = 0;
  363. if (!hostif_bt_avrcp_cttg_connect(conn)) {
  364. SYS_LOG_INF("Connect avrcp\n");
  365. ret = 0;
  366. } else {
  367. SYS_LOG_ERR("Connect avrcp failed\n");
  368. ret = -1;
  369. }
  370. return ret;
  371. }
  372. int btsrv_avrcp_sync_vol(void)
  373. {
  374. uint32_t start_time = 0, diff, curr_time;
  375. uint32_t delay_time = btsrv_volume_sync_delay_ms();
  376. if (thread_timer_is_running(&sync_volume_timer)) {
  377. return -1;
  378. }
  379. struct bt_conn *avrcp_conn = btsrv_rdm_avrcp_get_actived();
  380. curr_time = os_uptime_get_32();
  381. btsrv_rdm_get_a2dp_start_time(avrcp_conn, &start_time);
  382. diff = curr_time - start_time;
  383. if (diff >= delay_time) {
  384. diff = curr_time - avrcp_pre_sync_vol_time;
  385. if (diff >= AVRCP_SYNC_TO_REMOTE_INTERVAL) {
  386. btsrv_avrcp_sync_volume_timer_handler(NULL, NULL);
  387. } else {
  388. thread_timer_start(&sync_volume_timer, (AVRCP_SYNC_TO_REMOTE_INTERVAL - diff), 0);
  389. }
  390. } else {
  391. thread_timer_start(&sync_volume_timer, (delay_time - diff), 0);
  392. }
  393. return 0;
  394. }
  395. static int btsrv_avrcp_ct_pass_through_cmd(struct bt_conn *conn,
  396. uint8_t opid, bool continue_cmd, bool push)
  397. {
  398. int ret = 0;
  399. struct btsrv_rdm_avrcp_pass_info *info;
  400. info = btsrv_rdm_avrcp_get_pass_info(conn);
  401. if (!info) {
  402. return -EIO;
  403. }
  404. if (continue_cmd) {
  405. if ((push && info->pass_state != AVRCP_PASS_STATE_IDLE) ||
  406. (!push && info->pass_state != AVRCP_PASS_STATE_CONTINUE_START)) {
  407. SYS_LOG_INF("Pass busy %d op_id 0x%x", info->pass_state, info->op_id);
  408. ret = -EBUSY;
  409. goto pass_exit;
  410. }
  411. if (push) {
  412. info->pass_state = AVRCP_PASS_STATE_CONTINUE_START;
  413. info->op_id = opid;
  414. } else {
  415. info->pass_state = AVRCP_PASS_STATE_IDLE;
  416. info->op_id = 0;
  417. }
  418. ret = hostif_bt_avrcp_ct_pass_through_cmd(conn, opid, push);
  419. } else {
  420. if (info->pass_state != AVRCP_PASS_STATE_IDLE) {
  421. SYS_LOG_INF("Pass busy %d op_id 0x%x", info->pass_state, info->op_id);
  422. ret = -EBUSY;
  423. goto pass_exit;
  424. }
  425. info->pass_state = AVRCP_PASS_STATE_WAIT_ACCEPT_PUSH;
  426. info->op_id = opid;
  427. info->op_time = os_uptime_get_32();
  428. btsrv_avrcp_ctrl_pass_timer_start_stop(true);
  429. ret = hostif_bt_avrcp_ct_pass_through_cmd(conn, opid, push);
  430. }
  431. pass_exit:
  432. return ret;
  433. }
  434. static int _btsrv_avrcp_controller_process(btsrv_avrcp_cmd_e cmd)
  435. {
  436. uint8_t op_id = 0;
  437. bool push = true, continue_cmd = false;
  438. int status = 0;
  439. struct bt_conn *avrcp_conn = btsrv_rdm_avrcp_get_actived();
  440. switch (cmd) {
  441. case BTSRV_AVRCP_CMD_PLAY:
  442. op_id = AVRCP_OPERATION_ID_PLAY;
  443. break;
  444. case BTSRV_AVRCP_CMD_PAUSE:
  445. op_id = AVRCP_OPERATION_ID_PAUSE;
  446. break;
  447. case BTSRV_AVRCP_CMD_STOP:
  448. op_id = AVRCP_OPERATION_ID_STOP;
  449. break;
  450. case BTSRV_AVRCP_CMD_FORWARD:
  451. op_id = AVRCP_OPERATION_ID_FORWARD;
  452. break;
  453. case BTSRV_AVRCP_CMD_BACKWARD:
  454. op_id = AVRCP_OPERATION_ID_BACKWARD;
  455. break;
  456. case BTSRV_AVRCP_CMD_VOLUMEUP:
  457. op_id = AVRCP_OPERATION_ID_VOLUME_UP;
  458. break;
  459. case BTSRV_AVRCP_CMD_VOLUMEDOWN:
  460. op_id = AVRCP_OPERATION_ID_VOLUME_DOWN;
  461. break;
  462. case BTSRV_AVRCP_CMD_MUTE:
  463. op_id = AVRCP_OPERATION_ID_MUTE;
  464. break;
  465. case BTSRV_AVRCP_CMD_FAST_FORWARD_START:
  466. op_id = AVRCP_OPERATION_ID_FAST_FORWARD;
  467. continue_cmd = true;
  468. push = true;
  469. break;
  470. case BTSRV_AVRCP_CMD_FAST_FORWARD_STOP:
  471. op_id = AVRCP_OPERATION_ID_FAST_FORWARD;
  472. continue_cmd = true;
  473. push = false;
  474. break;
  475. case BTSRV_AVRCP_CMD_FAST_BACKWARD_START:
  476. op_id = AVRCP_OPERATION_ID_REWIND;
  477. continue_cmd = true;
  478. push = true;
  479. break;
  480. case BTSRV_AVRCP_CMD_FAST_BACKWARD_STOP:
  481. op_id = AVRCP_OPERATION_ID_REWIND;
  482. continue_cmd = true;
  483. push = false;
  484. break;
  485. case BTSRV_AVRCP_CMD_REPEAT_SINGLE:
  486. case BTSRV_AVRCP_CMD_REPEAT_ALL_TRACK:
  487. case BTSRV_AVRCP_CMD_REPEAT_OFF:
  488. case BTSRV_AVRCP_CMD_SHUFFLE_ON:
  489. case BTSRV_AVRCP_CMD_SHUFFLE_OFF:
  490. default:
  491. SYS_LOG_ERR("cmd 0x%02x not support\n", cmd);
  492. return -EINVAL;
  493. }
  494. status = btsrv_avrcp_ct_pass_through_cmd(avrcp_conn, op_id, continue_cmd, push);
  495. if (status < 0) {
  496. SYS_LOG_ERR("0x%x failed status %d conn 0x%x",
  497. cmd, status, hostif_bt_conn_get_handle(avrcp_conn));
  498. } else {
  499. SYS_LOG_INF("0x%x ok conn 0x%x", cmd, hostif_bt_conn_get_handle(avrcp_conn));
  500. }
  501. return status;
  502. }
  503. static int _btsrv_avrcp_get_id3_info()
  504. {
  505. int status = 0;
  506. struct bt_conn *avrcp_conn = btsrv_rdm_avrcp_get_actived();
  507. if(!avrcp_conn) {
  508. return -EINVAL;
  509. }
  510. status = hostif_bt_avrcp_ct_get_id3_info(avrcp_conn);
  511. return status;
  512. }
  513. bool btsrv_avrcp_is_support_get_playback_pos(void)
  514. {
  515. struct bt_conn *avrcp_conn = btsrv_rdm_avrcp_get_actived();
  516. if(!avrcp_conn) {
  517. return false;
  518. }
  519. return hostif_bt_avrcp_ct_check_event_support(avrcp_conn, BT_AVRCP_EVENT_PLAYBACK_POS_CHANGED);
  520. }
  521. static int btsrv_avrcp_get_playback_pos(void)
  522. {
  523. int status = 0;
  524. struct bt_conn *avrcp_conn = btsrv_rdm_avrcp_get_actived();
  525. if(!avrcp_conn) {
  526. return -EINVAL;
  527. }
  528. if (btsrv_rdm_avrcp_get_getting_pos_time(avrcp_conn)) {
  529. return -EBUSY;
  530. }
  531. status = hostif_bt_avrcp_ct_get_playback_pos(avrcp_conn);
  532. if (status == 0) {
  533. btsrv_rdm_avrcp_set_getting_pos_time(avrcp_conn, 1);
  534. }
  535. return status;
  536. }
  537. static int btsrv_avrcp_set_absolute_volume(uint32_t param)
  538. {
  539. union {
  540. uint8_t c_param[4]; /* 0:dev_type, 1:len, 2~3:data */
  541. int32_t i_param;
  542. } value;
  543. struct bt_conn *avrcp_conn = NULL;
  544. value.i_param = (int32_t)param;
  545. if (value.c_param[0] == BTSRV_DEVICE_PLAYER) {
  546. #ifdef CONFIG_BT_A2DP_TRS
  547. avrcp_conn = btsrv_rdm_trs_avrcp_get_actived();
  548. #endif
  549. } else if (value.c_param[0] == BTSRV_DEVICE_PHONE) {
  550. avrcp_conn = btsrv_rdm_avrcp_get_actived();
  551. }
  552. if(!avrcp_conn) {
  553. return -EIO;
  554. }
  555. return hostif_bt_avrcp_ct_set_absolute_volume(avrcp_conn, (uint32_t)value.i_param);
  556. }
  557. static int btsrv_avrcp_get_play_status(void)
  558. {
  559. int status;
  560. struct bt_conn *br_conn = btsrv_rdm_avrcp_get_connected_dev();
  561. if (br_conn == NULL) {
  562. return -EIO;
  563. }
  564. if (btsrv_rdm_avrcp_get_getting_pos_time(br_conn)) {
  565. return -EBUSY;
  566. }
  567. status = hostif_bt_avrcp_ct_get_play_status(br_conn);
  568. if (status == 0) {
  569. btsrv_rdm_avrcp_set_getting_pos_time(br_conn, 1);
  570. }
  571. return status;
  572. }
  573. #ifdef CONFIG_BT_A2DP_TRS
  574. static void btsrv_a2dp_trs_discover_timer_handler(struct thread_timer *ttimer, void *expiry_fn_arg)
  575. {
  576. struct bt_conn *br_conn = (struct bt_conn *)expiry_fn_arg;
  577. int ret;
  578. SYS_LOG_INF("trs discover timer.");
  579. if ((!br_conn) && (!btsrv_rdm_get_trs_mode(br_conn))) {
  580. SYS_LOG_ERR("conn invalid.");
  581. return;
  582. }
  583. if (btsrv_rdm_is_a2dp_connected(br_conn)) {
  584. SYS_LOG_INF("a2dp already init.");
  585. return;
  586. }
  587. ret = bt_a2dp_discover(br_conn, BT_A2DP_CH_SOURCE);
  588. SYS_LOG_INF("ret %d.",ret);
  589. }
  590. #endif
  591. int btsrv_avrcp_process(struct app_msg *msg)
  592. {
  593. struct bt_conn *conn;
  594. #ifdef CONFIG_BT_A2DP_TRS
  595. int trs_cmd = _btsrv_get_msg_param_cmd(msg);
  596. struct thread_timer *trs_discover_timer;
  597. if (MSG_BTSRV_AVRCP_CONNECTED == trs_cmd) {
  598. conn = (struct bt_conn *)(msg->ptr);
  599. if (conn && btsrv_rdm_get_trs_mode(conn)) {
  600. bt_pts_avrcp_ct_register_notification(conn);
  601. if (!btsrv_rdm_is_a2dp_connected(conn)) {
  602. trs_discover_timer = btsrv_rdm_get_trs_discover_timer(conn);
  603. if(trs_discover_timer){
  604. if(!thread_timer_is_running(trs_discover_timer)){
  605. thread_timer_init(trs_discover_timer, btsrv_a2dp_trs_discover_timer_handler
  606. , (void *)conn);
  607. thread_timer_start(trs_discover_timer, 1000, 0);
  608. }
  609. }
  610. }
  611. }
  612. } else if (MSG_BTSRV_AVRCP_DISCONNECTED == trs_cmd) {
  613. conn = (struct bt_conn *)(msg->ptr);
  614. if (conn && btsrv_rdm_get_trs_mode(conn)) {
  615. trs_discover_timer = btsrv_rdm_get_trs_discover_timer(conn);
  616. if (trs_discover_timer && thread_timer_is_running(trs_discover_timer))
  617. thread_timer_stop(trs_discover_timer);
  618. }
  619. }
  620. #endif
  621. switch (_btsrv_get_msg_param_cmd(msg)) {
  622. case MSG_BTSRV_AVRCP_START:
  623. SYS_LOG_INF("btsrv avrcp start");
  624. btsrv_avrcp_init(msg->ptr);
  625. break;
  626. case MSG_BTSRV_AVRCP_STOP:
  627. SYS_LOG_INF("btsrv avrcp stop");
  628. btsrv_avrcp_deinit();
  629. break;
  630. case MSG_BTSRV_AVRCP_CONNECT_TO:
  631. SYS_LOG_INF("btsrv avrcp connect");
  632. conn = btsrv_rdm_find_conn_by_addr(msg->ptr);
  633. if (conn) {
  634. btsrv_avrcp_connect(conn);
  635. }
  636. break;
  637. case MSG_BTSRV_AVRCP_DISCONNECT:
  638. SYS_LOG_INF("btsrv avrcp disconnect");
  639. conn = btsrv_rdm_find_conn_by_addr(msg->ptr);
  640. if (conn) {
  641. btsrv_avrcp_disconnect(conn);
  642. }
  643. break;
  644. case MSG_BTSRV_AVRCP_SEND_CMD:
  645. SYS_LOG_INF("btsrv avrcp send cmd %d\n", msg->value);
  646. _btsrv_avrcp_controller_process(msg->value);
  647. break;
  648. case MSG_BTSRV_AVRCP_GET_ID3_INFO:
  649. SYS_LOG_INF("btsrv avrcp ID3 info");
  650. _btsrv_avrcp_get_id3_info();
  651. break;
  652. case MSG_BTSRV_AVRCP_GET_PLAYBACK_POS:
  653. SYS_LOG_INF("btsrv avrcp get playback pos");
  654. btsrv_avrcp_get_playback_pos();
  655. break;
  656. case MSG_BTSRV_AVRCP_SET_ABSOLUTE_VOLUME:
  657. SYS_LOG_INF("btsrv avrcp set abs volume 0x%x\n", msg->value);
  658. btsrv_avrcp_set_absolute_volume((uint32_t)msg->value);
  659. break;
  660. case MSG_BTSRV_AVRCP_CONNECTED:
  661. avrcp_user_callback->event_cb(hostif_bt_conn_get_handle(msg->ptr), BTSRV_AVRCP_CONNECTED, NULL);
  662. break;
  663. case MSG_BTSRV_AVRCP_DISCONNECTED:
  664. avrcp_user_callback->event_cb(hostif_bt_conn_get_handle(msg->ptr), BTSRV_AVRCP_DISCONNECTED, NULL);
  665. break;
  666. case MSG_BTSRV_AVRCP_NOTIFY_CB:
  667. btsrv_avrcp_ctrl_event_notify_proc(msg->ptr);
  668. break;
  669. case MSG_BTSRV_AVRCP_PASS_CTRL_CB:
  670. btsrv_avrcp_ctrl_pass_ctrl_proc(msg->ptr);
  671. break;
  672. case MSG_BTSRV_AVRCP_PLAYBACK_POS_CB:
  673. btsrv_avrcp_ctrl_playback_pos_proc(msg->ptr);
  674. break;
  675. case MSG_BTSRV_AVRCP_SYNC_VOLUME:
  676. SYS_LOG_INF("btsrv avrcp sync volume");
  677. if (btsrv_rdm_get_dev_role() != BTSRV_TWS_SLAVE) {
  678. btsrv_avrcp_sync_vol();
  679. }
  680. break;
  681. case MSG_BTSRV_AVRCP_GET_PLAY_STATE:
  682. SYS_LOG_INF("btsrv avrcp get play state");
  683. btsrv_avrcp_get_play_status();
  684. break;
  685. case MSG_BTSRV_AVRCP_PLAY_STATE_CB:
  686. btsrv_avrcp_play_state_proc(msg->ptr);
  687. break;
  688. default:
  689. break;
  690. }
  691. return 0;
  692. }