123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800 |
- /*
- * Copyright (c) 2017 Actions Semi Co., Ltd.
- *
- * SPDX-License-Identifier: Apache-2.0
- */
- /**
- * @file
- * @brief btsrvice avrcp
- */
- #define SYS_LOG_DOMAIN "btsrv_avrcp"
- #include "btsrv_os_common.h"
- #include "btsrv_inner.h"
- #define AVRCP_CTRL_PASS_CHECK_INTERVAL 5 /* 5ms */
- #define AVRCP_WAIT_ACCEPT_PUSH_TIMEOUT 500 /* 500ms */
- #define AVRCP_CTRL_PASS_DELAY_RELEASE_TIME 5 /* 5ms */
- #define AVRCP_GET_POS_TIMEOUT 2000 /* 2000ms */
- enum {
- AVRCP_PASS_STATE_IDLE,
- AVRCP_PASS_STATE_WAIT_ACCEPT_PUSH,
- AVRCP_PASS_STATE_WAIT_DELAY_RELEASE,
- AVRCP_PASS_STATE_CONTINUE_START,
- };
- static btsrv_avrcp_callback_t *avrcp_user_callback;
- static struct thread_timer sync_volume_timer;
- static struct thread_timer ctrl_pass_timer;
- struct btsrv_avrcp_stack_cb {
- struct bt_conn *conn;
- union {
- uint8_t event_id;
- uint8_t op_id;
- uint8_t cmd;
- };
- uint8_t status;
- uint32_t pos;
- uint32_t len;
- };
- static void _btsrv_avrcp_ctrl_connected_cb(struct bt_conn *conn)
- {
- btsrv_event_notify(MSG_BTSRV_CONNECT, MSG_BTSRV_AVRCP_CONNECTED, conn);
- }
- static void _btsrv_avrcp_ctrl_disconnected_cb(struct bt_conn *conn)
- {
- /* TODO: Disconnected process order: btsrv_tws->btsrv_avrcp->btsrv_connect */
- btsrv_event_notify(MSG_BTSRV_CONNECT, MSG_BTSRV_AVRCP_DISCONNECTED, conn);
- }
- static void _btsrv_avrcp_ctrl_event_notify_cb(struct bt_conn *conn, uint8_t event_id, uint8_t status)
- {
- struct btsrv_avrcp_stack_cb param;
- param.conn = conn;
- param.event_id = event_id;
- param.status = status;
- btsrv_event_notify_malloc(MSG_BTSRV_AVRCP, MSG_BTSRV_AVRCP_NOTIFY_CB, (uint8_t *)¶m, sizeof(param), 0);
- }
- static void btsrv_avrcp_ctrl_event_notify_proc(void *in_param)
- {
- int cb_ev = -1;
- struct btsrv_avrcp_stack_cb *param = in_param;
- struct bt_conn *conn = param->conn;
- uint8_t event_id = param->event_id;
- uint8_t status = param->status;
- #ifdef CONFIG_BT_A2DP
- uint32_t start_time = 0;
- uint32_t delay_time = btsrv_volume_sync_delay_ms();
- #endif
- SYS_LOG_INF("Avrcp event notify 0x%x %d %d", hostif_bt_conn_get_handle(conn), event_id, status);
- if (event_id != BT_AVRCP_EVENT_PLAYBACK_STATUS_CHANGED &&
- event_id != BT_AVRCP_EVENT_VOLUME_CHANGED &&
- event_id != BT_AVRCP_EVENT_TRACK_CHANGED) {
- SYS_LOG_WRN("avrcp is NULL or event_id %d not care\n", event_id);
- return;
- }
- #ifdef CONFIG_BT_A2DP
- if (event_id == BT_AVRCP_EVENT_VOLUME_CHANGED &&
- ((btsrv_rdm_a2dp_get_actived() == conn &&
- btsrv_rdm_is_a2dp_stream_open(conn))
- #ifdef CONFIG_BT_A2DP_TRS
- || btsrv_rdm_get_trs_mode(conn)
- #endif
- )) {
- #ifdef CONFIG_BT_A2DP_TRS
- if (btsrv_rdm_get_trs_mode(conn)) {
- if (avrcp_user_callback->trs_set_volume_cb)
- avrcp_user_callback->trs_set_volume_cb(hostif_bt_conn_get_handle(conn), status);
- }
- else
- #endif
- {
- btsrv_rdm_get_a2dp_start_time(conn, &start_time);
- if (start_time && (os_uptime_get_32() - start_time) > delay_time
- && !thread_timer_is_running(&sync_volume_timer)) {
- avrcp_user_callback->set_volume_cb(hostif_bt_conn_get_handle(conn), status);
- }
- }
- return;
- }
- #else
- if (event_id == BT_AVRCP_EVENT_VOLUME_CHANGED &&
- btsrv_rdm_avrcp_get_actived() == conn){
- avrcp_user_callback->set_volume_cb(hostif_bt_conn_get_handle(conn), status);
- return;
- }
- #endif
- else if (event_id == BT_AVRCP_EVENT_TRACK_CHANGED){
- cb_ev = BTSRV_AVRCP_TRACK_CHANGE;
- }
- else if(event_id == BT_AVRCP_EVENT_PLAYBACK_STATUS_CHANGED) {
- switch (status) {
- case BT_AVRCP_PLAYBACK_STATUS_STOPPED:
- cb_ev = BTSRV_AVRCP_STOPED;
- break;
- case BT_AVRCP_PLAYBACK_STATUS_PLAYING:
- cb_ev = BTSRV_AVRCP_PLAYING;
- break;
- case BT_AVRCP_PLAYBACK_STATUS_PAUSED:
- cb_ev = BTSRV_AVRCP_PAUSED;
- break;
- case BT_AVRCP_PLAYBACK_STATUS_FWD_SEEK:
- case BT_AVRCP_PLAYBACK_STATUS_REV_SEEK:
- case BT_AVRCP_PLAYBACK_STATUS_ERROR:
- break;
- }
- }
- if (cb_ev > 0 && btsrv_rdm_avrcp_get_actived() == conn) {
- avrcp_user_callback->event_cb(hostif_bt_conn_get_handle(conn), cb_ev, NULL);
- }
- }
- static void _btsrv_avrcp_ctrl_get_volume_cb(struct bt_conn *conn, uint8_t *volume)
- {
- avrcp_user_callback->get_volume_cb(hostif_bt_conn_get_handle(conn), volume);
- SYS_LOG_INF("Avrcp remote reg notify get vol %d", (*volume));
- }
- static void _btsrv_avrcp_ctrl_pass_ctrl_cb(struct bt_conn *conn, uint8_t op_id, uint8_t state)
- {
- struct btsrv_avrcp_stack_cb param;
- param.conn = conn;
- param.op_id = op_id;
- param.status = state;
- btsrv_event_notify_malloc(MSG_BTSRV_AVRCP, MSG_BTSRV_AVRCP_PASS_CTRL_CB, (uint8_t *)¶m, sizeof(param), 0);
- }
- static void _btsrv_avrcp_get_play_state_cb(struct bt_conn *conn, uint8_t cmd,
- uint32_t *song_len, uint32_t *song_pos, uint8_t *play_state)
- {
- struct btsrv_avrcp_stack_cb param;
- if (cmd) {
- /* Receive get play state command, set output value. */
- //*song_len = 0x1234;
- //*song_pos = 0x1111;
- //*play_state = 1;
- return;
- }
- param.conn = conn;
- param.cmd = cmd,
- param.status = (*play_state);
- param.len = (*song_len);
- param.pos = (*song_pos);
- btsrv_event_notify_malloc(MSG_BTSRV_AVRCP, MSG_BTSRV_AVRCP_PLAY_STATE_CB, (uint8_t *)¶m, sizeof(param), 0);
- }
- static void btsrv_avrcp_play_state_proc(void *in_param)
- {
- struct btsrv_avrcp_stack_cb *param = in_param;
- struct bt_conn *conn = param->conn;
- uint32_t pos = param->pos;
- if (btsrv_rdm_avrcp_get_getting_pos_time(conn) == 1) {
- btsrv_rdm_avrcp_set_getting_pos_time(conn, 0);
- if (btsrv_rdm_avrcp_get_actived() == conn) {
- avrcp_user_callback->event_cb(hostif_bt_conn_get_handle(conn), BTSRV_AVRCP_PLAYBACK_POS, &pos);
- }
- }
- }
- static void btsrv_avrcp_ctrl_rsp_pass_proc(struct bt_conn *conn, uint8_t op_id, uint8_t state)
- {
- struct btsrv_rdm_avrcp_pass_info *info;
- if (state != BT_AVRCP_RSP_STATE_PASS_THROUGH_PUSHED) {
- return;
- }
- info = btsrv_rdm_avrcp_get_pass_info(conn);
- if (!info) {
- return;
- }
- if (info->op_id == op_id && info->pass_state == AVRCP_PASS_STATE_WAIT_ACCEPT_PUSH) {
- info->pass_state = AVRCP_PASS_STATE_WAIT_DELAY_RELEASE;
- info->op_time = os_uptime_get_32();
- }
- }
- static void btsrv_avrcp_ctrl_pass_ctrl_proc(void *in_param)
- {
- struct btsrv_avrcp_stack_cb *param = in_param;
- struct bt_conn *conn = param->conn;
- uint8_t op_id = param->op_id;
- uint8_t state = param->status;
- #ifdef CONFIG_BT_A2DP_TRS
- if (btsrv_trs_avrcp_ctrl_pass_ctrl_cb(conn, op_id, state) == true) {
- SYS_LOG_INF("trs op_id 0x%x state 0x%x", op_id, state);
- return;
- }
- #endif
- SYS_LOG_INF("op_id 0x%x state 0x%x", op_id, state);
- if (state == BT_AVRCP_RSP_STATE_PASS_THROUGH_PUSHED ||
- state == BT_AVRCP_RSP_STATE_PASS_THROUGH_RELEASED) {
- btsrv_avrcp_ctrl_rsp_pass_proc(conn, op_id, state);
- } else if (btsrv_rdm_avrcp_get_actived() == conn) {
- uint8_t cmd;
- switch(op_id){
- case AVRCP_OPERATION_ID_PLAY:
- cmd = BTSRV_AVRCP_CMD_PLAY;
- break;
- case AVRCP_OPERATION_ID_PAUSE:
- cmd = BTSRV_AVRCP_CMD_PAUSE;
- break;
- case AVRCP_OPERATION_ID_VOLUME_UP:
- cmd = BTSRV_AVRCP_CMD_VOLUMEUP;
- break;
- case AVRCP_OPERATION_ID_VOLUME_DOWN:
- cmd = BTSRV_AVRCP_CMD_VOLUMEDOWN;
- break;
- case AVRCP_OPERATION_ID_MUTE:
- cmd = BTSRV_AVRCP_CMD_MUTE;
- break;
- default:
- SYS_LOG_ERR("op_id 0x%x not support", op_id);
- return;
- }
- avrcp_user_callback->pass_ctrl_cb(hostif_bt_conn_get_handle(conn), cmd, state);
- }
- }
- static void _btsrv_avrcp_ctrl_update_id3_info_cb(struct bt_conn *conn, struct id3_info * info)
- {
- if (btsrv_rdm_avrcp_get_actived() == conn) {
- avrcp_user_callback->event_cb(hostif_bt_conn_get_handle(conn), BTSRV_AVRCP_UPDATE_ID3_INFO, info);
- }
- }
- static void _btsrv_avrcp_ctrl_playback_pos_cb(struct bt_conn *conn, uint32_t pos)
- {
- struct btsrv_avrcp_stack_cb param;
- param.conn = conn;
- param.pos = pos;
- btsrv_event_notify_malloc(MSG_BTSRV_AVRCP, MSG_BTSRV_AVRCP_PLAYBACK_POS_CB, (uint8_t *)¶m, sizeof(param), 0);
- }
- static void btsrv_avrcp_ctrl_playback_pos_proc(void *in_param)
- {
- struct btsrv_avrcp_stack_cb *param = in_param;
- struct bt_conn *conn = param->conn;
- uint32_t pos = param->pos;
- if (btsrv_rdm_avrcp_get_getting_pos_time(conn) == 1) {
- btsrv_rdm_avrcp_set_getting_pos_time(conn, 0);
- if (btsrv_rdm_avrcp_get_actived() == conn) {
- avrcp_user_callback->event_cb(hostif_bt_conn_get_handle(conn), BTSRV_AVRCP_PLAYBACK_POS, &pos);
- }
- }
- }
- static const struct bt_avrcp_app_cb btsrv_avrcp_ctrl_cb = {
- .connected = _btsrv_avrcp_ctrl_connected_cb,
- .disconnected = _btsrv_avrcp_ctrl_disconnected_cb,
- .notify = _btsrv_avrcp_ctrl_event_notify_cb,
- .pass_ctrl = _btsrv_avrcp_ctrl_pass_ctrl_cb,
- .get_play_status = _btsrv_avrcp_get_play_state_cb,
- .get_volume = _btsrv_avrcp_ctrl_get_volume_cb,
- .update_id3_info = _btsrv_avrcp_ctrl_update_id3_info_cb,
- .playback_pos = _btsrv_avrcp_ctrl_playback_pos_cb,
- };
- static void btsrv_avrcp_ctrl_pass_timer_start_stop(bool start)
- {
- if (start) {
- if (!thread_timer_is_running(&ctrl_pass_timer)) {
- thread_timer_start(&ctrl_pass_timer, AVRCP_CTRL_PASS_CHECK_INTERVAL, AVRCP_CTRL_PASS_CHECK_INTERVAL);
- }
- } else {
- if (thread_timer_is_running(&ctrl_pass_timer)) {
- thread_timer_stop(&ctrl_pass_timer);
- }
- }
- }
- static void connected_dev_cb_check_ctrl_pass(struct bt_conn *base_conn, uint8_t tws_dev, void *cb_param)
- {
- int *need_timer = cb_param;
- struct btsrv_rdm_avrcp_pass_info *info;
- uint32_t time, check_timeout = 0;
- if (tws_dev) {
- return;
- }
- info = btsrv_rdm_avrcp_get_pass_info(base_conn);
- if (!info) {
- SYS_LOG_ERR("not connected??\n");
- return;
- }
- if (info->op_id == 0 ||
- info->pass_state == AVRCP_PASS_STATE_IDLE ||
- info->pass_state == AVRCP_PASS_STATE_CONTINUE_START) {
- return;
- }
- *need_timer = 1;
- time = os_uptime_get_32();
- if (info->pass_state == AVRCP_PASS_STATE_WAIT_ACCEPT_PUSH) {
- check_timeout = AVRCP_WAIT_ACCEPT_PUSH_TIMEOUT;
- } else if (info->pass_state == AVRCP_PASS_STATE_WAIT_DELAY_RELEASE) {
- check_timeout = AVRCP_CTRL_PASS_DELAY_RELEASE_TIME;
- }
- if ((time - info->op_time) > check_timeout) {
- hostif_bt_avrcp_ct_pass_through_cmd(base_conn, info->op_id, false);
- info->pass_state = AVRCP_PASS_STATE_IDLE;
- info->op_id = 0;
- }
- }
- static void btsrv_avrcp_ctrl_pass_timer_handler(struct thread_timer *ttimer, void *expiry_fn_arg)
- {
- int need_timer = 0;
- btsrv_rdm_get_connected_dev(connected_dev_cb_check_ctrl_pass, &need_timer);
- if (!need_timer) {
- btsrv_avrcp_ctrl_pass_timer_start_stop(false);
- }
- }
- #define AVRCP_SYNC_TO_REMOTE_INTERVAL 300
- static uint32_t avrcp_pre_sync_vol_time;
- static void btsrv_avrcp_sync_volume_timer_handler(struct thread_timer *ttimer, void *expiry_fn_arg)
- {
- uint8_t volume;
- struct bt_conn *avrcp_conn = btsrv_rdm_avrcp_get_actived();
- avrcp_user_callback->get_volume_cb(hostif_bt_conn_get_handle(avrcp_conn), &volume);
- SYS_LOG_INF("Avrcp sync vol local to remote vol %d", volume);
- avrcp_pre_sync_vol_time = os_uptime_get_32();
- //if (!btsrv_is_pts_test()) {
- hostif_bt_avrcp_tg_notify_change(avrcp_conn, volume);
- //}
- }
- int btsrv_avrcp_init(btsrv_avrcp_callback_t *cb)
- {
- hostif_bt_avrcp_cttg_register_cb((struct bt_avrcp_app_cb *)&btsrv_avrcp_ctrl_cb);
- avrcp_user_callback = cb;
- thread_timer_init(&sync_volume_timer, btsrv_avrcp_sync_volume_timer_handler, NULL);
- thread_timer_init(&ctrl_pass_timer, btsrv_avrcp_ctrl_pass_timer_handler, NULL);
- #ifdef CONFIG_BT_A2DP_TRS
- btsrv_trs_avrcp_init(cb);
- #endif
- return 0;
- }
- int btsrv_avrcp_deinit(void)
- {
- btsrv_avrcp_ctrl_pass_timer_start_stop(false);
- if (thread_timer_is_running(&sync_volume_timer)) {
- thread_timer_stop(&sync_volume_timer);
- }
- #ifdef CONFIG_BT_A2DP_TRS
- btsrv_trs_avrcp_deinit();
- #endif
- return 0;
- }
- int btsrv_avrcp_disconnect(struct bt_conn *conn)
- {
- if (conn && btsrv_rdm_is_avrcp_connected(conn)) {
- SYS_LOG_INF("avrcp_disconnect\n");
- hostif_bt_avrcp_cttg_disconnect(conn);
- }
- #ifdef CONFIG_BT_A2DP_TRS
- struct thread_timer *trs_discover_timer = btsrv_rdm_get_trs_discover_timer(conn);
- if(trs_discover_timer && thread_timer_is_running(trs_discover_timer))
- thread_timer_stop(trs_discover_timer);
- #endif
- return 0;
- }
- int btsrv_avrcp_connect(struct bt_conn *conn)
- {
- int ret = 0;
- if (!hostif_bt_avrcp_cttg_connect(conn)) {
- SYS_LOG_INF("Connect avrcp\n");
- ret = 0;
- } else {
- SYS_LOG_ERR("Connect avrcp failed\n");
- ret = -1;
- }
- return ret;
- }
- int btsrv_avrcp_sync_vol(void)
- {
- uint32_t start_time = 0, diff, curr_time;
- uint32_t delay_time = btsrv_volume_sync_delay_ms();
- if (thread_timer_is_running(&sync_volume_timer)) {
- return -1;
- }
- struct bt_conn *avrcp_conn = btsrv_rdm_avrcp_get_actived();
- curr_time = os_uptime_get_32();
- btsrv_rdm_get_a2dp_start_time(avrcp_conn, &start_time);
- diff = curr_time - start_time;
- if (diff >= delay_time) {
- diff = curr_time - avrcp_pre_sync_vol_time;
- if (diff >= AVRCP_SYNC_TO_REMOTE_INTERVAL) {
- btsrv_avrcp_sync_volume_timer_handler(NULL, NULL);
- } else {
- thread_timer_start(&sync_volume_timer, (AVRCP_SYNC_TO_REMOTE_INTERVAL - diff), 0);
- }
- } else {
- thread_timer_start(&sync_volume_timer, (delay_time - diff), 0);
- }
- return 0;
- }
- static int btsrv_avrcp_ct_pass_through_cmd(struct bt_conn *conn,
- uint8_t opid, bool continue_cmd, bool push)
- {
- int ret = 0;
- struct btsrv_rdm_avrcp_pass_info *info;
- info = btsrv_rdm_avrcp_get_pass_info(conn);
- if (!info) {
- return -EIO;
- }
- if (continue_cmd) {
- if ((push && info->pass_state != AVRCP_PASS_STATE_IDLE) ||
- (!push && info->pass_state != AVRCP_PASS_STATE_CONTINUE_START)) {
- SYS_LOG_INF("Pass busy %d op_id 0x%x", info->pass_state, info->op_id);
- ret = -EBUSY;
- goto pass_exit;
- }
- if (push) {
- info->pass_state = AVRCP_PASS_STATE_CONTINUE_START;
- info->op_id = opid;
- } else {
- info->pass_state = AVRCP_PASS_STATE_IDLE;
- info->op_id = 0;
- }
- ret = hostif_bt_avrcp_ct_pass_through_cmd(conn, opid, push);
- } else {
- if (info->pass_state != AVRCP_PASS_STATE_IDLE) {
- SYS_LOG_INF("Pass busy %d op_id 0x%x", info->pass_state, info->op_id);
- ret = -EBUSY;
- goto pass_exit;
- }
- info->pass_state = AVRCP_PASS_STATE_WAIT_ACCEPT_PUSH;
- info->op_id = opid;
- info->op_time = os_uptime_get_32();
- btsrv_avrcp_ctrl_pass_timer_start_stop(true);
- ret = hostif_bt_avrcp_ct_pass_through_cmd(conn, opid, push);
- }
- pass_exit:
- return ret;
- }
- static int _btsrv_avrcp_controller_process(btsrv_avrcp_cmd_e cmd)
- {
- uint8_t op_id = 0;
- bool push = true, continue_cmd = false;
- int status = 0;
- struct bt_conn *avrcp_conn = btsrv_rdm_avrcp_get_actived();
- switch (cmd) {
- case BTSRV_AVRCP_CMD_PLAY:
- op_id = AVRCP_OPERATION_ID_PLAY;
- break;
- case BTSRV_AVRCP_CMD_PAUSE:
- op_id = AVRCP_OPERATION_ID_PAUSE;
- break;
- case BTSRV_AVRCP_CMD_STOP:
- op_id = AVRCP_OPERATION_ID_STOP;
- break;
- case BTSRV_AVRCP_CMD_FORWARD:
- op_id = AVRCP_OPERATION_ID_FORWARD;
- break;
- case BTSRV_AVRCP_CMD_BACKWARD:
- op_id = AVRCP_OPERATION_ID_BACKWARD;
- break;
- case BTSRV_AVRCP_CMD_VOLUMEUP:
- op_id = AVRCP_OPERATION_ID_VOLUME_UP;
- break;
- case BTSRV_AVRCP_CMD_VOLUMEDOWN:
- op_id = AVRCP_OPERATION_ID_VOLUME_DOWN;
- break;
- case BTSRV_AVRCP_CMD_MUTE:
- op_id = AVRCP_OPERATION_ID_MUTE;
- break;
- case BTSRV_AVRCP_CMD_FAST_FORWARD_START:
- op_id = AVRCP_OPERATION_ID_FAST_FORWARD;
- continue_cmd = true;
- push = true;
- break;
- case BTSRV_AVRCP_CMD_FAST_FORWARD_STOP:
- op_id = AVRCP_OPERATION_ID_FAST_FORWARD;
- continue_cmd = true;
- push = false;
- break;
- case BTSRV_AVRCP_CMD_FAST_BACKWARD_START:
- op_id = AVRCP_OPERATION_ID_REWIND;
- continue_cmd = true;
- push = true;
- break;
- case BTSRV_AVRCP_CMD_FAST_BACKWARD_STOP:
- op_id = AVRCP_OPERATION_ID_REWIND;
- continue_cmd = true;
- push = false;
- break;
- case BTSRV_AVRCP_CMD_REPEAT_SINGLE:
- case BTSRV_AVRCP_CMD_REPEAT_ALL_TRACK:
- case BTSRV_AVRCP_CMD_REPEAT_OFF:
- case BTSRV_AVRCP_CMD_SHUFFLE_ON:
- case BTSRV_AVRCP_CMD_SHUFFLE_OFF:
- default:
- SYS_LOG_ERR("cmd 0x%02x not support\n", cmd);
- return -EINVAL;
- }
- status = btsrv_avrcp_ct_pass_through_cmd(avrcp_conn, op_id, continue_cmd, push);
- if (status < 0) {
- SYS_LOG_ERR("0x%x failed status %d conn 0x%x",
- cmd, status, hostif_bt_conn_get_handle(avrcp_conn));
- } else {
- SYS_LOG_INF("0x%x ok conn 0x%x", cmd, hostif_bt_conn_get_handle(avrcp_conn));
- }
- return status;
- }
- static int _btsrv_avrcp_get_id3_info()
- {
- int status = 0;
- struct bt_conn *avrcp_conn = btsrv_rdm_avrcp_get_actived();
- if(!avrcp_conn) {
- return -EINVAL;
- }
- status = hostif_bt_avrcp_ct_get_id3_info(avrcp_conn);
- return status;
- }
- bool btsrv_avrcp_is_support_get_playback_pos(void)
- {
- struct bt_conn *avrcp_conn = btsrv_rdm_avrcp_get_actived();
- if(!avrcp_conn) {
- return false;
- }
- return hostif_bt_avrcp_ct_check_event_support(avrcp_conn, BT_AVRCP_EVENT_PLAYBACK_POS_CHANGED);
- }
- static int btsrv_avrcp_get_playback_pos(void)
- {
- int status = 0;
- struct bt_conn *avrcp_conn = btsrv_rdm_avrcp_get_actived();
- if(!avrcp_conn) {
- return -EINVAL;
- }
- if (btsrv_rdm_avrcp_get_getting_pos_time(avrcp_conn)) {
- return -EBUSY;
- }
- status = hostif_bt_avrcp_ct_get_playback_pos(avrcp_conn);
- if (status == 0) {
- btsrv_rdm_avrcp_set_getting_pos_time(avrcp_conn, 1);
- }
- return status;
- }
- static int btsrv_avrcp_set_absolute_volume(uint32_t param)
- {
- union {
- uint8_t c_param[4]; /* 0:dev_type, 1:len, 2~3:data */
- int32_t i_param;
- } value;
- struct bt_conn *avrcp_conn = NULL;
- value.i_param = (int32_t)param;
- if (value.c_param[0] == BTSRV_DEVICE_PLAYER) {
- #ifdef CONFIG_BT_A2DP_TRS
- avrcp_conn = btsrv_rdm_trs_avrcp_get_actived();
- #endif
- } else if (value.c_param[0] == BTSRV_DEVICE_PHONE) {
- avrcp_conn = btsrv_rdm_avrcp_get_actived();
- }
- if(!avrcp_conn) {
- return -EIO;
- }
- return hostif_bt_avrcp_ct_set_absolute_volume(avrcp_conn, (uint32_t)value.i_param);
- }
- static int btsrv_avrcp_get_play_status(void)
- {
- int status;
- struct bt_conn *br_conn = btsrv_rdm_avrcp_get_connected_dev();
- if (br_conn == NULL) {
- return -EIO;
- }
- if (btsrv_rdm_avrcp_get_getting_pos_time(br_conn)) {
- return -EBUSY;
- }
- status = hostif_bt_avrcp_ct_get_play_status(br_conn);
- if (status == 0) {
- btsrv_rdm_avrcp_set_getting_pos_time(br_conn, 1);
- }
- return status;
- }
- #ifdef CONFIG_BT_A2DP_TRS
- static void btsrv_a2dp_trs_discover_timer_handler(struct thread_timer *ttimer, void *expiry_fn_arg)
- {
- struct bt_conn *br_conn = (struct bt_conn *)expiry_fn_arg;
- int ret;
- SYS_LOG_INF("trs discover timer.");
- if ((!br_conn) && (!btsrv_rdm_get_trs_mode(br_conn))) {
- SYS_LOG_ERR("conn invalid.");
- return;
- }
- if (btsrv_rdm_is_a2dp_connected(br_conn)) {
- SYS_LOG_INF("a2dp already init.");
- return;
- }
- ret = bt_a2dp_discover(br_conn, BT_A2DP_CH_SOURCE);
- SYS_LOG_INF("ret %d.",ret);
- }
- #endif
- int btsrv_avrcp_process(struct app_msg *msg)
- {
- struct bt_conn *conn;
- #ifdef CONFIG_BT_A2DP_TRS
- int trs_cmd = _btsrv_get_msg_param_cmd(msg);
- struct thread_timer *trs_discover_timer;
- if (MSG_BTSRV_AVRCP_CONNECTED == trs_cmd) {
- conn = (struct bt_conn *)(msg->ptr);
- if (conn && btsrv_rdm_get_trs_mode(conn)) {
- bt_pts_avrcp_ct_register_notification(conn);
- if (!btsrv_rdm_is_a2dp_connected(conn)) {
- trs_discover_timer = btsrv_rdm_get_trs_discover_timer(conn);
- if(trs_discover_timer){
- if(!thread_timer_is_running(trs_discover_timer)){
- thread_timer_init(trs_discover_timer, btsrv_a2dp_trs_discover_timer_handler
- , (void *)conn);
- thread_timer_start(trs_discover_timer, 1000, 0);
- }
- }
- }
- }
- } else if (MSG_BTSRV_AVRCP_DISCONNECTED == trs_cmd) {
- conn = (struct bt_conn *)(msg->ptr);
- if (conn && btsrv_rdm_get_trs_mode(conn)) {
- trs_discover_timer = btsrv_rdm_get_trs_discover_timer(conn);
- if (trs_discover_timer && thread_timer_is_running(trs_discover_timer))
- thread_timer_stop(trs_discover_timer);
- }
- }
- #endif
- switch (_btsrv_get_msg_param_cmd(msg)) {
- case MSG_BTSRV_AVRCP_START:
- SYS_LOG_INF("btsrv avrcp start");
- btsrv_avrcp_init(msg->ptr);
- break;
- case MSG_BTSRV_AVRCP_STOP:
- SYS_LOG_INF("btsrv avrcp stop");
- btsrv_avrcp_deinit();
- break;
- case MSG_BTSRV_AVRCP_CONNECT_TO:
- SYS_LOG_INF("btsrv avrcp connect");
- conn = btsrv_rdm_find_conn_by_addr(msg->ptr);
- if (conn) {
- btsrv_avrcp_connect(conn);
- }
- break;
- case MSG_BTSRV_AVRCP_DISCONNECT:
- SYS_LOG_INF("btsrv avrcp disconnect");
- conn = btsrv_rdm_find_conn_by_addr(msg->ptr);
- if (conn) {
- btsrv_avrcp_disconnect(conn);
- }
- break;
- case MSG_BTSRV_AVRCP_SEND_CMD:
- SYS_LOG_INF("btsrv avrcp send cmd %d\n", msg->value);
- _btsrv_avrcp_controller_process(msg->value);
- break;
- case MSG_BTSRV_AVRCP_GET_ID3_INFO:
- SYS_LOG_INF("btsrv avrcp ID3 info");
- _btsrv_avrcp_get_id3_info();
- break;
- case MSG_BTSRV_AVRCP_GET_PLAYBACK_POS:
- SYS_LOG_INF("btsrv avrcp get playback pos");
- btsrv_avrcp_get_playback_pos();
- break;
- case MSG_BTSRV_AVRCP_SET_ABSOLUTE_VOLUME:
- SYS_LOG_INF("btsrv avrcp set abs volume 0x%x\n", msg->value);
- btsrv_avrcp_set_absolute_volume((uint32_t)msg->value);
- break;
- case MSG_BTSRV_AVRCP_CONNECTED:
- avrcp_user_callback->event_cb(hostif_bt_conn_get_handle(msg->ptr), BTSRV_AVRCP_CONNECTED, NULL);
- break;
- case MSG_BTSRV_AVRCP_DISCONNECTED:
- avrcp_user_callback->event_cb(hostif_bt_conn_get_handle(msg->ptr), BTSRV_AVRCP_DISCONNECTED, NULL);
- break;
- case MSG_BTSRV_AVRCP_NOTIFY_CB:
- btsrv_avrcp_ctrl_event_notify_proc(msg->ptr);
- break;
- case MSG_BTSRV_AVRCP_PASS_CTRL_CB:
- btsrv_avrcp_ctrl_pass_ctrl_proc(msg->ptr);
- break;
- case MSG_BTSRV_AVRCP_PLAYBACK_POS_CB:
- btsrv_avrcp_ctrl_playback_pos_proc(msg->ptr);
- break;
- case MSG_BTSRV_AVRCP_SYNC_VOLUME:
- SYS_LOG_INF("btsrv avrcp sync volume");
- if (btsrv_rdm_get_dev_role() != BTSRV_TWS_SLAVE) {
- btsrv_avrcp_sync_vol();
- }
- break;
- case MSG_BTSRV_AVRCP_GET_PLAY_STATE:
- SYS_LOG_INF("btsrv avrcp get play state");
- btsrv_avrcp_get_play_status();
- break;
- case MSG_BTSRV_AVRCP_PLAY_STATE_CB:
- btsrv_avrcp_play_state_proc(msg->ptr);
- break;
- default:
- break;
- }
- return 0;
- }
|