Loading system/btif/src/btif_a2dp_control.cc +3 −3 Original line number Diff line number Diff line Loading @@ -44,13 +44,13 @@ static void btif_a2dp_ctrl_cb(tUIPC_CH_ID ch_id, tUIPC_EVENT event); static tA2DP_CTRL_CMD a2dp_cmd_pending = A2DP_CTRL_CMD_NONE; void btif_a2dp_control_init(void) { UIPC_Init(NULL); UIPC_Init(NULL, UIPC_USER_A2DP); UIPC_Open(UIPC_CH_ID_AV_CTRL, btif_a2dp_ctrl_cb); } void btif_a2dp_control_cleanup(void) { /* This calls blocks until UIPC is fully closed */ UIPC_Close(UIPC_CH_ID_ALL); UIPC_Close(UIPC_CH_ID_ALL, UIPC_USER_A2DP); } static void btif_a2dp_recv_ctrl_data(void) { Loading @@ -64,7 +64,7 @@ static void btif_a2dp_recv_ctrl_data(void) { /* detach on ctrl channel means audioflinger process was terminated */ if (n == 0) { APPL_TRACE_WARNING("%s: CTRL CH DETACHED", __func__); UIPC_Close(UIPC_CH_ID_AV_CTRL); UIPC_Close(UIPC_CH_ID_AV_CTRL, UIPC_USER_A2DP); return; } Loading system/btif/src/btif_a2dp_source.cc +1 −1 Original line number Diff line number Diff line Loading @@ -655,7 +655,7 @@ static void btif_a2dp_source_audio_tx_stop_event(void) { alarm_free(btif_a2dp_source_cb.media_alarm); btif_a2dp_source_cb.media_alarm = nullptr; UIPC_Close(UIPC_CH_ID_AV_AUDIO); UIPC_Close(UIPC_CH_ID_AV_AUDIO, UIPC_USER_A2DP); /* * Try to send acknowldegment once the media stream is Loading system/btif/src/btif_av.cc +65 −19 Original line number Diff line number Diff line Loading @@ -363,12 +363,38 @@ class BtifAvSource { const RawAddress& ActivePeer() const { return active_peer_; } bool SetActivePeer(const RawAddress& peer_address) { if (active_peer_ == peer_address) return true; // Nothing has changed if (bta_av_co_set_active_peer(peer_address)) { if (peer_address.IsEmpty()) { BTIF_TRACE_EVENT("%s: peer address is empty, shutdown the audio source", __func__); if (!bta_av_co_set_active_peer(peer_address)) { BTIF_TRACE_WARNING("%s: unable to set active peer to empty in BtaAvCo", __func__); } btif_a2dp_source_shutdown(); active_peer_ = peer_address; return true; } BtifAvPeer* peer = FindPeer(peer_address); if (peer != nullptr && !peer->IsConnected()) { BTIF_TRACE_ERROR("%s: Error setting %s as active Source peer", __func__, peer->PeerAddress().ToString().c_str()); return false; } if (!bta_av_co_set_active_peer(peer_address)) { BTIF_TRACE_ERROR("%s: unable to set active peer to %s in BtaAvCo", __func__, peer_address.ToString().c_str()); return false; } bool should_startup = active_peer_.IsEmpty(); active_peer_ = peer_address; if (should_startup) { BTIF_TRACE_EVENT("%s: active peer is empty, startup the Audio source", __func__); btif_a2dp_source_startup(); } return true; } const std::map<RawAddress, BtifAvPeer*>& Peers() const { return peers_; } Loading Loading @@ -436,12 +462,39 @@ class BtifAvSink { const RawAddress& ActivePeer() const { return active_peer_; } bool SetActivePeer(const RawAddress& peer_address) { if (bta_av_co_set_active_peer(peer_address)) { if (active_peer_ == peer_address) return true; // Nothing has changed if (peer_address.IsEmpty()) { BTIF_TRACE_EVENT("%s: peer address is empty, shutdown the audio sink", __func__); if (!bta_av_co_set_active_peer(peer_address)) { BTIF_TRACE_WARNING("%s: unable to set active peer to empty in BtaAvCo", __func__); } btif_a2dp_sink_shutdown(); active_peer_ = peer_address; return true; } BtifAvPeer* peer = FindPeer(peer_address); if (peer != nullptr && !peer->IsConnected()) { BTIF_TRACE_ERROR("%s: Error setting %s as active Sink peer", __func__, peer->PeerAddress().ToString().c_str()); return false; } if (!bta_av_co_set_active_peer(peer_address)) { BTIF_TRACE_ERROR("%s: unable to set active peer to %s in BtaAvCo", __func__, peer_address.ToString().c_str()); return false; } bool should_startup = active_peer_.IsEmpty(); active_peer_ = peer_address; if (should_startup) { BTIF_TRACE_EVENT("%s: active peer is empty, startup the Audio source", __func__); btif_a2dp_source_startup(); } return true; } const std::map<RawAddress, BtifAvPeer*>& Peers() const { return peers_; } Loading Loading @@ -2371,28 +2424,21 @@ static void set_active_peer_int(uint8_t peer_sep, BTIF_TRACE_EVENT("%s: peer_sep=%s (%d) peer_address=%s", __func__, (peer_sep == AVDT_TSEP_SRC) ? "Source" : "Sink", peer_sep, peer_address.ToString().c_str()); BtifAvPeer* peer = nullptr; if (peer_sep == AVDT_TSEP_SNK) { peer = btif_av_source.FindPeer(peer_address); if (peer != nullptr && peer->IsConnected()) { if (!btif_av_source.SetActivePeer(peer_address)) { BTIF_TRACE_ERROR("%s: Error setting %s as active Sink peer", __func__, peer_address.ToString().c_str()); } return; } } if (peer_sep == AVDT_TSEP_SRC) { peer = btif_av_sink.FindPeer(peer_address); if (peer != nullptr && peer->IsConnected()) { if (!btif_av_sink.SetActivePeer(peer_address)) { BTIF_TRACE_ERROR("%s: Error setting %s as active Source peer", __func__, peer_address.ToString().c_str()); } return; } } // If reached here, we could not set the active peer BTIF_TRACE_ERROR("%s: Cannot set active %s peer to %s: peer not %s", __func__, (peer_sep == AVDT_TSEP_SRC) ? "Source" : "Sink", Loading system/udrv/include/uipc.h +47 −50 Original line number Diff line number Diff line Loading @@ -37,6 +37,13 @@ typedef enum { UIPC_TX_DATA_READY_EVT = 0x0010 } tUIPC_EVENT; /* UIPC users */ typedef enum { UIPC_USER_A2DP = 0, UIPC_USER_HEARING_AID = 1, UIPC_USER_NUM = 2 } tUIPC_USER; /* * UIPC IOCTL Requests */ Loading @@ -55,72 +62,62 @@ typedef void(tUIPC_RCV_CBACK)( const char* dump_uipc_event(tUIPC_EVENT event); /******************************************************************************* * * Function UIPC_Init * * Description Initialize UIPC module /** * Initialize UIPC module * * Returns void * ******************************************************************************/ void UIPC_Init(void*); * @param user User ID who uses UIPC */ void UIPC_Init(void*, int user); /******************************************************************************* * * Function UIPC_Open /** * Open a UIPC channel * * Description Open UIPC interface * * Returns void * ******************************************************************************/ * @param ch_id Channel ID * @param p_cback Callback handler * @return true on success, otherwise false */ bool UIPC_Open(tUIPC_CH_ID ch_id, tUIPC_RCV_CBACK* p_cback); /******************************************************************************* /** * Closes a channel in UIPC or the entire UIPC module * * Function UIPC_Close * * Description Close UIPC interface * * Returns void * ******************************************************************************/ void UIPC_Close(tUIPC_CH_ID ch_id); * @param ch_id Channel ID; if ch_id is UIPC_CH_ID_ALL, then cleanup UIPC * @param user User ID who uses UIPC */ void UIPC_Close(tUIPC_CH_ID ch_id, int user); /******************************************************************************* * * Function UIPC_Send * * Description Called to transmit a message over UIPC. * * Returns void /** * Send a message over UIPC * ******************************************************************************/ * @param ch_id Channel ID * @param msg_evt Message event type * @param p_buf Buffer for the message * @param msglen Message length * @return true on success, otherwise false */ bool UIPC_Send(tUIPC_CH_ID ch_id, uint16_t msg_evt, const uint8_t* p_buf, uint16_t msglen); /******************************************************************************* * * Function UIPC_Read * * Description Called to read a message from UIPC. /** * Read a message from UIPC * * Returns void * ******************************************************************************/ * @param ch_id Channel ID * @param p_msg_evt Message event type * @param p_buf Buffer for the message * @param len Bytes to read * @return true on success, otherwise false */ uint32_t UIPC_Read(tUIPC_CH_ID ch_id, uint16_t* p_msg_evt, uint8_t* p_buf, uint32_t len); /******************************************************************************* * * Function UIPC_Ioctl /** * Control the UIPC parameter * * Description Called to control UIPC. * * Returns void * ******************************************************************************/ * @param ch_id Channel ID * @param request Request type * @param param Optional parameters * @return true on success, otherwise false */ bool UIPC_Ioctl(tUIPC_CH_ID ch_id, uint32_t request, void* param); #endif /* UIPC_H */ system/udrv/ulinux/uipc.cc +28 −3 Original line number Diff line number Diff line Loading @@ -39,6 +39,7 @@ #include <sys/un.h> #include <unistd.h> #include <mutex> #include <set> #include "audio_a2dp_hw/include/audio_a2dp_hw.h" #include "bt_common.h" Loading Loading @@ -93,6 +94,7 @@ typedef struct { int signal_fds[2]; tUIPC_CHAN ch[UIPC_CH_NUM]; std::set<int> active_users; } tUIPC_MAIN; /***************************************************************************** Loading Loading @@ -247,6 +249,8 @@ void uipc_main_cleanup(void) { /* close any open channels */ for (i = 0; i < UIPC_CH_NUM; i++) uipc_close_ch_locked(i); uipc_main.active_users.clear(); } /* check pending events in read task */ Loading Loading @@ -548,8 +552,17 @@ void uipc_stop_main_server_thread(void) { ** ******************************************************************************/ void UIPC_Init(UNUSED_ATTR void* p_data) { void UIPC_Init(UNUSED_ATTR void* p_data, int user) { BTIF_TRACE_DEBUG("UIPC_Init"); if (user < 0 || user >= UIPC_USER_NUM) { BTIF_TRACE_ERROR("UIPC_Close : invalid user ID %d", user); return; } std::lock_guard<std::recursive_mutex> lock(uipc_main.mutex); auto result_insert = uipc_main.active_users.insert(user); if ((uipc_main.active_users.size() != 1) || !result_insert.second) { return; } uipc_main_init(); uipc_start_main_server_thread(); Loading Loading @@ -601,15 +614,27 @@ bool UIPC_Open(tUIPC_CH_ID ch_id, tUIPC_RCV_CBACK* p_cback) { ** ******************************************************************************/ void UIPC_Close(tUIPC_CH_ID ch_id) { void UIPC_Close(tUIPC_CH_ID ch_id, int user) { BTIF_TRACE_DEBUG("UIPC_Close : ch_id %d", ch_id); if (user < 0 || user >= UIPC_USER_NUM) { BTIF_TRACE_ERROR("UIPC_Close : invalid user ID %d", user); return; } /* special case handling uipc shutdown */ if (ch_id != UIPC_CH_ID_ALL) { std::lock_guard<std::recursive_mutex> lock(uipc_main.mutex); uipc_close_locked(ch_id); return; } if (uipc_main.active_users.erase(user) == 0) { return; } if (!uipc_main.active_users.empty()) { return; } BTIF_TRACE_DEBUG("UIPC_Close : waiting for shutdown to complete"); uipc_stop_main_server_thread(); BTIF_TRACE_DEBUG("UIPC_Close : shutdown complete"); Loading Loading
system/btif/src/btif_a2dp_control.cc +3 −3 Original line number Diff line number Diff line Loading @@ -44,13 +44,13 @@ static void btif_a2dp_ctrl_cb(tUIPC_CH_ID ch_id, tUIPC_EVENT event); static tA2DP_CTRL_CMD a2dp_cmd_pending = A2DP_CTRL_CMD_NONE; void btif_a2dp_control_init(void) { UIPC_Init(NULL); UIPC_Init(NULL, UIPC_USER_A2DP); UIPC_Open(UIPC_CH_ID_AV_CTRL, btif_a2dp_ctrl_cb); } void btif_a2dp_control_cleanup(void) { /* This calls blocks until UIPC is fully closed */ UIPC_Close(UIPC_CH_ID_ALL); UIPC_Close(UIPC_CH_ID_ALL, UIPC_USER_A2DP); } static void btif_a2dp_recv_ctrl_data(void) { Loading @@ -64,7 +64,7 @@ static void btif_a2dp_recv_ctrl_data(void) { /* detach on ctrl channel means audioflinger process was terminated */ if (n == 0) { APPL_TRACE_WARNING("%s: CTRL CH DETACHED", __func__); UIPC_Close(UIPC_CH_ID_AV_CTRL); UIPC_Close(UIPC_CH_ID_AV_CTRL, UIPC_USER_A2DP); return; } Loading
system/btif/src/btif_a2dp_source.cc +1 −1 Original line number Diff line number Diff line Loading @@ -655,7 +655,7 @@ static void btif_a2dp_source_audio_tx_stop_event(void) { alarm_free(btif_a2dp_source_cb.media_alarm); btif_a2dp_source_cb.media_alarm = nullptr; UIPC_Close(UIPC_CH_ID_AV_AUDIO); UIPC_Close(UIPC_CH_ID_AV_AUDIO, UIPC_USER_A2DP); /* * Try to send acknowldegment once the media stream is Loading
system/btif/src/btif_av.cc +65 −19 Original line number Diff line number Diff line Loading @@ -363,12 +363,38 @@ class BtifAvSource { const RawAddress& ActivePeer() const { return active_peer_; } bool SetActivePeer(const RawAddress& peer_address) { if (active_peer_ == peer_address) return true; // Nothing has changed if (bta_av_co_set_active_peer(peer_address)) { if (peer_address.IsEmpty()) { BTIF_TRACE_EVENT("%s: peer address is empty, shutdown the audio source", __func__); if (!bta_av_co_set_active_peer(peer_address)) { BTIF_TRACE_WARNING("%s: unable to set active peer to empty in BtaAvCo", __func__); } btif_a2dp_source_shutdown(); active_peer_ = peer_address; return true; } BtifAvPeer* peer = FindPeer(peer_address); if (peer != nullptr && !peer->IsConnected()) { BTIF_TRACE_ERROR("%s: Error setting %s as active Source peer", __func__, peer->PeerAddress().ToString().c_str()); return false; } if (!bta_av_co_set_active_peer(peer_address)) { BTIF_TRACE_ERROR("%s: unable to set active peer to %s in BtaAvCo", __func__, peer_address.ToString().c_str()); return false; } bool should_startup = active_peer_.IsEmpty(); active_peer_ = peer_address; if (should_startup) { BTIF_TRACE_EVENT("%s: active peer is empty, startup the Audio source", __func__); btif_a2dp_source_startup(); } return true; } const std::map<RawAddress, BtifAvPeer*>& Peers() const { return peers_; } Loading Loading @@ -436,12 +462,39 @@ class BtifAvSink { const RawAddress& ActivePeer() const { return active_peer_; } bool SetActivePeer(const RawAddress& peer_address) { if (bta_av_co_set_active_peer(peer_address)) { if (active_peer_ == peer_address) return true; // Nothing has changed if (peer_address.IsEmpty()) { BTIF_TRACE_EVENT("%s: peer address is empty, shutdown the audio sink", __func__); if (!bta_av_co_set_active_peer(peer_address)) { BTIF_TRACE_WARNING("%s: unable to set active peer to empty in BtaAvCo", __func__); } btif_a2dp_sink_shutdown(); active_peer_ = peer_address; return true; } BtifAvPeer* peer = FindPeer(peer_address); if (peer != nullptr && !peer->IsConnected()) { BTIF_TRACE_ERROR("%s: Error setting %s as active Sink peer", __func__, peer->PeerAddress().ToString().c_str()); return false; } if (!bta_av_co_set_active_peer(peer_address)) { BTIF_TRACE_ERROR("%s: unable to set active peer to %s in BtaAvCo", __func__, peer_address.ToString().c_str()); return false; } bool should_startup = active_peer_.IsEmpty(); active_peer_ = peer_address; if (should_startup) { BTIF_TRACE_EVENT("%s: active peer is empty, startup the Audio source", __func__); btif_a2dp_source_startup(); } return true; } const std::map<RawAddress, BtifAvPeer*>& Peers() const { return peers_; } Loading Loading @@ -2371,28 +2424,21 @@ static void set_active_peer_int(uint8_t peer_sep, BTIF_TRACE_EVENT("%s: peer_sep=%s (%d) peer_address=%s", __func__, (peer_sep == AVDT_TSEP_SRC) ? "Source" : "Sink", peer_sep, peer_address.ToString().c_str()); BtifAvPeer* peer = nullptr; if (peer_sep == AVDT_TSEP_SNK) { peer = btif_av_source.FindPeer(peer_address); if (peer != nullptr && peer->IsConnected()) { if (!btif_av_source.SetActivePeer(peer_address)) { BTIF_TRACE_ERROR("%s: Error setting %s as active Sink peer", __func__, peer_address.ToString().c_str()); } return; } } if (peer_sep == AVDT_TSEP_SRC) { peer = btif_av_sink.FindPeer(peer_address); if (peer != nullptr && peer->IsConnected()) { if (!btif_av_sink.SetActivePeer(peer_address)) { BTIF_TRACE_ERROR("%s: Error setting %s as active Source peer", __func__, peer_address.ToString().c_str()); } return; } } // If reached here, we could not set the active peer BTIF_TRACE_ERROR("%s: Cannot set active %s peer to %s: peer not %s", __func__, (peer_sep == AVDT_TSEP_SRC) ? "Source" : "Sink", Loading
system/udrv/include/uipc.h +47 −50 Original line number Diff line number Diff line Loading @@ -37,6 +37,13 @@ typedef enum { UIPC_TX_DATA_READY_EVT = 0x0010 } tUIPC_EVENT; /* UIPC users */ typedef enum { UIPC_USER_A2DP = 0, UIPC_USER_HEARING_AID = 1, UIPC_USER_NUM = 2 } tUIPC_USER; /* * UIPC IOCTL Requests */ Loading @@ -55,72 +62,62 @@ typedef void(tUIPC_RCV_CBACK)( const char* dump_uipc_event(tUIPC_EVENT event); /******************************************************************************* * * Function UIPC_Init * * Description Initialize UIPC module /** * Initialize UIPC module * * Returns void * ******************************************************************************/ void UIPC_Init(void*); * @param user User ID who uses UIPC */ void UIPC_Init(void*, int user); /******************************************************************************* * * Function UIPC_Open /** * Open a UIPC channel * * Description Open UIPC interface * * Returns void * ******************************************************************************/ * @param ch_id Channel ID * @param p_cback Callback handler * @return true on success, otherwise false */ bool UIPC_Open(tUIPC_CH_ID ch_id, tUIPC_RCV_CBACK* p_cback); /******************************************************************************* /** * Closes a channel in UIPC or the entire UIPC module * * Function UIPC_Close * * Description Close UIPC interface * * Returns void * ******************************************************************************/ void UIPC_Close(tUIPC_CH_ID ch_id); * @param ch_id Channel ID; if ch_id is UIPC_CH_ID_ALL, then cleanup UIPC * @param user User ID who uses UIPC */ void UIPC_Close(tUIPC_CH_ID ch_id, int user); /******************************************************************************* * * Function UIPC_Send * * Description Called to transmit a message over UIPC. * * Returns void /** * Send a message over UIPC * ******************************************************************************/ * @param ch_id Channel ID * @param msg_evt Message event type * @param p_buf Buffer for the message * @param msglen Message length * @return true on success, otherwise false */ bool UIPC_Send(tUIPC_CH_ID ch_id, uint16_t msg_evt, const uint8_t* p_buf, uint16_t msglen); /******************************************************************************* * * Function UIPC_Read * * Description Called to read a message from UIPC. /** * Read a message from UIPC * * Returns void * ******************************************************************************/ * @param ch_id Channel ID * @param p_msg_evt Message event type * @param p_buf Buffer for the message * @param len Bytes to read * @return true on success, otherwise false */ uint32_t UIPC_Read(tUIPC_CH_ID ch_id, uint16_t* p_msg_evt, uint8_t* p_buf, uint32_t len); /******************************************************************************* * * Function UIPC_Ioctl /** * Control the UIPC parameter * * Description Called to control UIPC. * * Returns void * ******************************************************************************/ * @param ch_id Channel ID * @param request Request type * @param param Optional parameters * @return true on success, otherwise false */ bool UIPC_Ioctl(tUIPC_CH_ID ch_id, uint32_t request, void* param); #endif /* UIPC_H */
system/udrv/ulinux/uipc.cc +28 −3 Original line number Diff line number Diff line Loading @@ -39,6 +39,7 @@ #include <sys/un.h> #include <unistd.h> #include <mutex> #include <set> #include "audio_a2dp_hw/include/audio_a2dp_hw.h" #include "bt_common.h" Loading Loading @@ -93,6 +94,7 @@ typedef struct { int signal_fds[2]; tUIPC_CHAN ch[UIPC_CH_NUM]; std::set<int> active_users; } tUIPC_MAIN; /***************************************************************************** Loading Loading @@ -247,6 +249,8 @@ void uipc_main_cleanup(void) { /* close any open channels */ for (i = 0; i < UIPC_CH_NUM; i++) uipc_close_ch_locked(i); uipc_main.active_users.clear(); } /* check pending events in read task */ Loading Loading @@ -548,8 +552,17 @@ void uipc_stop_main_server_thread(void) { ** ******************************************************************************/ void UIPC_Init(UNUSED_ATTR void* p_data) { void UIPC_Init(UNUSED_ATTR void* p_data, int user) { BTIF_TRACE_DEBUG("UIPC_Init"); if (user < 0 || user >= UIPC_USER_NUM) { BTIF_TRACE_ERROR("UIPC_Close : invalid user ID %d", user); return; } std::lock_guard<std::recursive_mutex> lock(uipc_main.mutex); auto result_insert = uipc_main.active_users.insert(user); if ((uipc_main.active_users.size() != 1) || !result_insert.second) { return; } uipc_main_init(); uipc_start_main_server_thread(); Loading Loading @@ -601,15 +614,27 @@ bool UIPC_Open(tUIPC_CH_ID ch_id, tUIPC_RCV_CBACK* p_cback) { ** ******************************************************************************/ void UIPC_Close(tUIPC_CH_ID ch_id) { void UIPC_Close(tUIPC_CH_ID ch_id, int user) { BTIF_TRACE_DEBUG("UIPC_Close : ch_id %d", ch_id); if (user < 0 || user >= UIPC_USER_NUM) { BTIF_TRACE_ERROR("UIPC_Close : invalid user ID %d", user); return; } /* special case handling uipc shutdown */ if (ch_id != UIPC_CH_ID_ALL) { std::lock_guard<std::recursive_mutex> lock(uipc_main.mutex); uipc_close_locked(ch_id); return; } if (uipc_main.active_users.erase(user) == 0) { return; } if (!uipc_main.active_users.empty()) { return; } BTIF_TRACE_DEBUG("UIPC_Close : waiting for shutdown to complete"); uipc_stop_main_server_thread(); BTIF_TRACE_DEBUG("UIPC_Close : shutdown complete"); Loading