APP Stereo_Multilink_Dongle Application Note
V1.1
2024/03/26
Revision History
Version |
Date |
Description |
---|---|---|
V1.0.0.0 |
2021/10/21 |
Stable release |
V1.0.0.1 |
2024/01/19 |
Modify contents |
V1.1 |
2024/03/26 |
Adjust document format |
Table List
Figure List
Glossary
1 Introduction
The purpose of this document is to give an overview of setting stereo multilink’s tpoll and htpoll, the source can be gaming dongle or phone.
1.1 Background Knowledge
A piconet consists of 2-8 Bluetooth devices, with one as the master and the others as slave.
Both the master and slave can be in either the Sniff mode or the active mode.
In active mode, the master poll the slave, and the slave responds to the polling.
When the master poll, it tx first and then rx, while the slave rx first and then tx.
There are two types of polling time strategies: tpoll uses interval, htpoll uses duty cycle.
The tpoll is the uncertain bandwidth, whereas htpoll ensures more certain bandwidth.
Htpoll is a higher priority than tpoll. If both are set, htpoll take effect.
Htpoll is commonly used among Realtek devices, such as in the B2B or Bud to a gaming dongle.
Since phone do not support htpoll, usually bud use htpoll and phone use tpoll in B2S.
1.2 Tpoll Rules
Pri |
Global State |
B2s-per-link’s Tpoll |
---|---|---|
1 |
flash update |
is_active_link ? 16:(40+2*index) |
2 |
data capture |
is_active_link ? tpoll_from_tool:(40+2*index) |
3 |
gaming dongle |
is_active_link ? 12:(40+2*index) |
4 |
call |
is_active_link ? (40+2*index):28 |
5 |
audio |
in_lea_stream ? (is_active_link ? 110:(40+2*index)):(is_active_link ? 26:28) |
6 |
linkback |
is_linkback_one ? 16 : 120 |
7 |
idle |
40+2*index |
1.3 Htpoll Rules
Note: If dongle is in a2dp, it maybe is calling or playing music. Set htpoll only when has a2dp.
Dongle State |
Phone State |
Dongle Htpoll |
Phone Htpoll |
---|---|---|---|
a2dp |
sco |
16/6 |
set as ref |
a2dp |
a2dp |
16/8 |
- |
a2dp |
idle |
58/50 |
- |
a2dp |
no-link |
30/22 |
- |
idle/no-link |
a2dp |
- |
58/50 |
2 Source Code Overview
This section discribes the main parts of setting stereo multilink’s tpoll and htpoll, the source can be gaming dongle or phone.
2.1 Setting Tpoll
void app_bt_policy_qos_param_update(uint8_t *bd_addr, T_BP_TPOLL_EVENT event)
{
T_APP_BR_LINK *p_link;
app_bt_policy_update_tpoll_context(bd_addr, event);
if (app_link_get_b2s_link_num() == 0)
{
return;
}
if (tpoll_ctx.need_reset)
{
p_link = app_link_find_b2s_link(bd_addr);
if (p_link != NULL)
{
app_bt_policy_set_tpoll(p_link->id, p_link->tpoll_value);
}
return;
}
if (tpoll_ctx.in_flash_update)
{
app_bt_policy_set_both_tpoll(flash_update_idx, TPOLL_FLASH_UPDATE_ACTIVE, TPOLL_IDLE);
}
#if F_APP_SPP_CAPTURE_DSP_DATA_1 ||F_APP_SPP_CAPTURE_DSP_DATA_2
else if (tpoll_ctx.in_data_capture)
{
app_bt_policy_set_both_tpoll(data_capture_idx, data_capture_tpoll, TPOLL_IDLE);
}
#endif
#if F_APP_GAMING_DONGLE_SUPPORT
else if (tpoll_ctx.in_dongle_spp || tpoll_ctx.in_dongle_a2dp)
{
app_bt_policy_set_both_tpoll(dongle_idx, TPOLL_DONGLE_ACTIVE, TPOLL_IDLE);
}
#endif
else if (tpoll_ctx.in_sco)
{
app_bt_policy_set_both_tpoll(...hfp_active_idx, TPOLL_SCO_ACTIVE, TPOLL_SCO_INACTIVE);
}
else if (tpoll_ctx.in_a2dp)
{
#if F_APP_LEA_SUPPORT
if (tpoll_ctx.in_lea_streaming)
{
app_bt_policy_set_both_tpoll(...a2dp_active_idx, TPOLL_LEA_A2DP_ACTIVE, TPOLL_IDLE);
}
else
#endif
{
app_bt_policy_set_both_tpoll(...a2dp_active_idx,TPOLL_A2DP_ACTIVE,TPOLL_A2DP_INACTIVE);
}
}
else if (tpoll_ctx.in_linkback)
{
for (uint8_t i = 0; i < MAX_BR_LINK_NUM; i++)
{
if (app_link_check_b2s_link_by_id(i))
{
if (linkback_active_node_judge_cur_conn_addr(app_db.br_link[i].bd_addr))
{
app_bt_policy_set_tpoll(i, TPOLL_LINKBACK_ACTIVE);
}
else
{
app_bt_policy_set_tpoll(i, TPOLL_LINKBACK_INACTIVE);
}
}
}
}
else
{
for (uint8_t i = 0; i < MAX_BR_LINK_NUM; i++)
{
if (app_link_check_b2s_link_by_id(i))
{
app_bt_policy_set_tpoll(i, TPOLL_IDLE);
}
}
}
}
2.2 Setting Htpoll
void app_dongle_htpoll_control(T_APP_DONGLE_HTPOLL_EVENT event)
{
......
if (p_dongle_link != NULL)
{
if (is_streaming)
{
if (app_hfp_sco_is_connected() == false)
{
if (connected_device_num == 1)
{
/* dongle a2dp + phone no link : 30/22 */
setting = GAMING_SETTING_LINKBACK;
}
else if (connected_device_num > 1)
{
if (p_dongle_link->streaming_fg &&
(p_non_dongle_link && p_non_dongle_link->streaming_fg))
{
/* dongle a2dp + phone a2dp : 16/8 */
setting = GAMING_SETTING_MULTI_SRC_MIX_PLAYING;
}
else
{
/* dongle a2dp + phone idle : 58/50 */
/* dongle idle + phone a2dp : 58/50 */
setting = GAMING_SETTING_MULTI_SRC_PLAYING;
}
}
}
else
{
/* dongle a2dp + phone sco : 16/6 */
setting = GAMING_SETTING_MULTI_SRC_MIX_PLAYING_WITH_SCO;
}
}
}
/* there is a lack of dongle no link + phone a2dp !!! */
......
SET_HTOPLL:
if (setting != GAMING_SETTING_NONE)
{
if (htpoll_active)
{
/* clear current active and set new one */
bt_link_traffic_qos_clear(htpoll_active_addr);
/* dongle a2dp + phone sco */
if (setting == GAMING_SETTING_MULTI_SRC_MIX_PLAYING_WITH_SCO)
{
if (p_non_dongle_link != NULL)
{
/* set phone as reference */
bt_link_periodic_traffic_set(p_non_dongle_link->bd_addr);
}
/* set dongle htpoll */
bt_link_periodic_sync_traffic_qos_set(target_addr, interval, rsvd_slot);
}
else
{
/* other case set */
bt_link_periodic_traffic_qos_set(target_addr, interval, rsvd_slot, false);
}
}
else
{
/* first or after clear to set htpoll */
bt_link_periodic_traffic_qos_set(target_addr, interval, rsvd_slot, false);
}
}
else
{
if (htpoll_active)
{
/* clear htpoll */
bt_link_traffic_qos_clear(htpoll_active_addr);
htpoll_active = false;
}
}
}