tBTM_SCO_CB *p_conn_cb, tBTM_SCO_CB *p_disc_cb);
extern void btm_reject_sco_link(UINT16 sco_inx );
extern void btm_sco_chk_pend_rolechange (UINT16 hci_handle);
+extern void btm_sco_disc_chk_pend_for_modechange (UINT16 hci_handle);
+
#else
#define btm_accept_sco_link(sco_inx, p_setup, p_conn_cb, p_disc_cb)
#define btm_reject_sco_link(sco_inx)
BTM_PM_ST_HOLD = BTM_PM_STS_HOLD,
BTM_PM_ST_SNIFF = BTM_PM_STS_SNIFF,
BTM_PM_ST_PARK = BTM_PM_STS_PARK,
- BTM_PM_ST_PENDING = BTM_PM_STS_PENDING
+ BTM_PM_ST_PENDING = BTM_PM_STS_PENDING,
+ BTM_PM_ST_INVALID = 0xFF
};
typedef UINT8 tBTM_PM_STATE;
extern void btm_pm_proc_mode_change (UINT8 hci_status, UINT16 hci_handle, UINT8 mode,
UINT16 interval);
extern void btm_pm_proc_ssr_evt (UINT8 *p, UINT16 evt_len);
+extern tBTM_STATUS btm_read_power_mode_state (BD_ADDR remote_bda,
+ tBTM_PM_STATE *pmState);
#if BTM_SCO_INCLUDED == TRUE
extern void btm_sco_chk_pend_unpark (UINT8 hci_status, UINT16 hci_handle);
#else
/*******************************************************************************
**
+** Function btm_read_power_mode_state
+**
+** Description This returns the current pm state for a specific
+** ACL connection.
+**
+** Input Param remote_bda - device address of desired ACL connection
+**
+** Output Param pmState - address where the current pm state is copied into.
+** BTM_PM_ST_ACTIVE
+** BTM_PM_ST_HOLD
+** BTM_PM_ST_SNIFF
+** BTM_PM_ST_PARK
+** BTM_PM_ST_PENDING
+** (valid only if return code is BTM_SUCCESS)
+**
+** Returns BTM_SUCCESS if successful,
+** BTM_UNKNOWN_ADDR if bd addr is not active or bad
+**
+*******************************************************************************/
+tBTM_STATUS btm_read_power_mode_state (BD_ADDR remote_bda, tBTM_PM_STATE *pmState)
+{
+ int acl_ind = btm_pm_find_acl_ind(remote_bda);
+
+ if( acl_ind == MAX_L2CAP_LINKS)
+ return (BTM_UNKNOWN_ADDR);
+
+ *pmState = btm_cb.pm_mode_db[acl_ind].state;
+ return BTM_SUCCESS;
+}
+
+/*******************************************************************************
+**
** Function BTM_SetSsrParams
**
** Description This sends the given SSR parameters for the given ACL
(*btm_cb.pm_reg_db[yy].cback)( p->remote_addr, mode, interval, hci_status);
}
}
+#if BTM_SCO_INCLUDED == TRUE
+ /*check if sco disconnect is waiting for the mode change */
+ btm_sco_disc_chk_pend_for_modechange(hci_handle);
+#endif
/* If mode change was because of an active role switch or change link key */
btm_cont_rswitch(p, btm_find_dev(p->remote_addr), hci_status);
#define SCO_ST_DISCONNECTING 5
#define SCO_ST_PEND_UNPARK 6
#define SCO_ST_PEND_ROLECHANGE 7
+#define SCO_ST_PEND_MODECHANGE 8
/********************************************************************************/
/* L O C A L F U N C T I O N P R O T O T Y P E S */
/*******************************************************************************
**
+** Function btm_sco_disc_chk_pend_for_modechange
+**
+** Description This function is called by btm when there is a mode change
+** event to see if there are SCO disconnect commands waiting for the mode change.
+**
+** Returns void
+**
+*******************************************************************************/
+void btm_sco_disc_chk_pend_for_modechange (UINT16 hci_handle)
+{
+#if (BTM_MAX_SCO_LINKS>0)
+ tSCO_CONN *p = &btm_cb.sco_cb.sco_db[0];
+
+ BTM_TRACE_DEBUG("%s: hci_handle 0x%04x, p->state 0x%02x", __func__,
+ hci_handle, p->state);
+
+ for (UINT16 xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++)
+ {
+ if ((p->state == SCO_ST_PEND_MODECHANGE) &&
+ (BTM_GetHCIConnHandle (p->esco.data.bd_addr, BT_TRANSPORT_BR_EDR)) == hci_handle)
+
+ {
+ BTM_TRACE_DEBUG("%s: SCO Link handle 0x%04x", __func__, p->hci_handle);
+ BTM_RemoveSco(xx);
+ }
+ }
+#endif
+}
+
+/*******************************************************************************
+**
** Function btm_sco_conn_req
**
** Description This function is called by BTIF when an SCO connection
#if (BTM_MAX_SCO_LINKS>0)
tSCO_CONN *p = &btm_cb.sco_cb.sco_db[sco_inx];
UINT16 tempstate;
+ tBTM_PM_STATE state = BTM_PM_ST_INVALID;
+
+ BTM_TRACE_DEBUG("%s", __func__);
/* Validity check */
if ((sco_inx >= BTM_MAX_SCO_LINKS) || (p->state == SCO_ST_UNUSED))
return (BTM_SUCCESS);
}
+ if ((btm_read_power_mode_state(p->esco.data.bd_addr, &state) == BTM_SUCCESS)
+ && state == BTM_PM_ST_PENDING)
+ {
+ BTM_TRACE_DEBUG("%s: BTM_PM_ST_PENDING for ACL mapped with SCO Link 0x%04x",
+ __func__, p->hci_handle);
+ p->state = SCO_ST_PEND_MODECHANGE;
+ return (BTM_CMD_STARTED);
+ }
+
tempstate = p->state;
p->state = SCO_ST_DISCONNECTING;