#endif /*(BT_SSP_INCLUDED == TRUE)*/
+esp_err_t esp_bt_gap_set_afh_channels(esp_bt_gap_afh_channels channels)
+{
+ btc_msg_t msg;
+ btc_gap_bt_args_t arg;
+
+ if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
+ return ESP_ERR_INVALID_STATE;
+ }
+
+ msg.sig = BTC_SIG_API_CALL;
+ msg.pid = BTC_PID_GAP_BT;
+ msg.act = BTC_GAP_BT_ACT_SET_AFH_CHANNELS;
+
+ memcpy(&arg.set_afh_channels.channels, channels, ESP_BT_GAP_AFH_CHANNELS_LEN);
+ arg.set_afh_channels.channels[ESP_BT_GAP_AFH_CHANNELS_LEN -1] &= 0x7F;
+ return (btc_transfer_context(&msg, &arg, sizeof(btc_gap_bt_args_t), NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
+}
#endif /* #if BTC_GAP_BT_INCLUDED == TRUE */
ESP_BT_INIT_COD = 0x0a, /*!< overwrite major, minor, and service class */
} esp_bt_cod_mode_t;
+#define ESP_BT_GAP_AFH_CHANNELS_LEN 10
+typedef uint8_t esp_bt_gap_afh_channels[ESP_BT_GAP_AFH_CHANNELS_LEN];
+
+
/// Discoverability and Connectability mode
typedef enum {
ESP_BT_NON_CONNECTABLE, /*!< Non-connectable */
ESP_BT_GAP_KEY_REQ_EVT, /*!< Simple Pairing Passkey request */
ESP_BT_GAP_READ_RSSI_DELTA_EVT, /*!< read rssi event */
ESP_BT_GAP_CONFIG_EIR_DATA_EVT, /*!< config EIR data event */
+ ESP_BT_GAP_SET_AFH_CHANNELS_EVT, /*!< set AFH channels event */
ESP_BT_GAP_EVT_MAX,
} esp_bt_gap_cb_event_t;
struct key_req_param {
esp_bd_addr_t bda; /*!< remote bluetooth device address*/
} key_req; /*!< passkey request parameter struct */
+
+ /**
+ * @brief ESP_BT_GAP_SET_AFH_CHANNELS_EVT
+ */
+ struct set_afh_channels_param {
+ esp_bt_status_t stat; /*!< set AFH channel status */
+ } set_afh_channels;
} esp_bt_gap_cb_param_t;
/**
#endif /*(BT_SSP_INCLUDED == TRUE)*/
+/**
+* @brief Set the AFH channels
+*
+* @param[in] channles : The n th such field (in the range 0 to 78) contains the value for channel n :
+* Channel n is bad = 0
+* Channel n is unknown = 1
+* The most significant bit is reserved and shall be set to 0
+* At least 20 channels shall be marked as unknown
+*
+* @return - ESP_OK : success
+* - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled
+* - other : failed
+*
+*/
+esp_err_t esp_bt_gap_set_afh_channels(esp_bt_gap_afh_channels channles);
+
#ifdef __cplusplus
}
#endif
#endif /// CLASSIC_BT_INCLUDED
}
+/*******************************************************************************
+**
+** Function bta_dm_set_afh_channels
+**
+** Description Sets AFH channels
+**
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_dm_set_afh_channels (tBTA_DM_MSG *p_data)
+{
+#if CLASSIC_BT_INCLUDED
+ BTM_SetAfhChannels (p_data->set_afh_channels.channels, p_data->set_afh_channels.set_afh_cb);
+#endif /// CLASSIC_BT_INCLUDED
+}
+
void bta_dm_config_eir (tBTA_DM_MSG *p_data)
{
tBTA_DM_API_CONFIG_EIR *config_eir = &p_data->config_eir;
}
}
+#if (CLASSIC_BT_INCLUDED == TRUE)
+/*******************************************************************************
+**
+** Function BTA_DmSetAfhChannels
+**
+** Description This function sets the AFH channels
+**
+**
+** Returns void
+**
+*******************************************************************************/
+void BTA_DmSetAfhChannels(const uint8_t *channels, tBTA_CMPL_CB *set_afh_cb)
+{
+
+ tBTA_DM_API_SET_AFH_CHANNELS *p_msg;
+
+ if ((p_msg = (tBTA_DM_API_SET_AFH_CHANNELS *) osi_malloc(sizeof(tBTA_DM_API_SET_AFH_CHANNELS))) != NULL) {
+ p_msg->hdr.event = BTA_DM_API_SET_AFH_CHANNELS_EVT;
+
+ p_msg->set_afh_cb = set_afh_cb;
+ memcpy(p_msg->channels, channels, AFH_CHANNELS_LEN);
+
+ bta_sys_sendmsg(p_msg);
+ }
+
+
+}
+#endif /// CLASSIC_BT_INCLUDED == TRUE
+
#if (BLE_INCLUDED == TRUE)
void BTA_DmUpdateWhiteList(BOOLEAN add_remove, BD_ADDR remote_addr, tBLE_ADDR_TYPE addr_type, tBTA_ADD_WHITELIST_CBACK *add_wl_cb)
{
bta_dm_disable, /* BTA_DM_API_DISABLE_EVT */
bta_dm_set_dev_name, /* BTA_DM_API_SET_NAME_EVT */
bta_dm_config_eir, /* BTA_DM_API_CONFIG_EIR_EVT */
+ bta_dm_set_afh_channels, /* BTA_DM_API_SET_AFH_CHANNELS_EVT */
bta_dm_set_visibility, /* BTA_DM_API_SET_VISIBILITY_EVT */
bta_dm_acl_change, /* BTA_DM_ACL_CHANGE_EVT */
bta_dm_add_device, /* BTA_DM_API_ADD_DEVICE_EVT */
BTA_DM_API_DISABLE_EVT,
BTA_DM_API_SET_NAME_EVT,
BTA_DM_API_CONFIG_EIR_EVT,
+ BTA_DM_API_SET_AFH_CHANNELS_EVT,
BTA_DM_API_SET_VISIBILITY_EVT,
BTA_DM_ACL_CHANGE_EVT,
UINT8 data[];
}tBTA_DM_API_CONFIG_EIR;
+/* data type for BTA_DM_API_SET_AFH_CHANNELS_EVT */
+typedef struct {
+ BT_HDR hdr;
+ AFH_CHANNELS channels;
+ tBTA_CMPL_CB *set_afh_cb;
+}tBTA_DM_API_SET_AFH_CHANNELS;
+
#if (BLE_INCLUDED == TRUE)
typedef struct {
BT_HDR hdr;
tBTA_DM_API_SET_NAME set_name;
tBTA_DM_API_CONFIG_EIR config_eir;
+ tBTA_DM_API_SET_AFH_CHANNELS set_afh_channels;
+
#if (BLE_INCLUDED == TRUE)
tBTA_DM_API_UPDATE_WHITE_LIST white_list;
tBTA_DM_API_READ_ADV_TX_POWER read_tx_power;
extern void bta_dm_disable (tBTA_DM_MSG *p_data);
extern void bta_dm_set_dev_name (tBTA_DM_MSG *p_data);
extern void bta_dm_config_eir (tBTA_DM_MSG *p_data);
+extern void bta_dm_set_afh_channels (tBTA_DM_MSG *p_data);
extern void bta_dm_update_white_list(tBTA_DM_MSG *p_data);
extern void bta_dm_ble_read_adv_tx_power(tBTA_DM_MSG *p_data);
extern void bta_dm_ble_read_rssi(tBTA_DM_MSG *p_data);
typedef tBTM_RSSI_RESULTS tBTA_RSSI_RESULTS;
+typedef tBTM_SET_AFH_CHANNELS_RESULTS tBTA_SET_AFH_CHANNELS_RESULTS;
+
/* advertising channel map */
#define BTA_BLE_ADV_CHNL_37 BTM_BLE_ADV_CHNL_37
#define BTA_BLE_ADV_CHNL_38 BTM_BLE_ADV_CHNL_38
*******************************************************************************/
extern void BTA_DmConfigEir(tBTA_DM_EIR_CONF *eir_config);
+/*******************************************************************************
+**
+** Function BTA_DmSetAfhChannels
+**
+** Description This function sets the AFH channels
+**
+**
+** Returns void
+**
+*******************************************************************************/
+void BTA_DmSetAfhChannels(const uint8_t *channels, tBTA_CMPL_CB *set_afh_cb);
+
#if (BLE_INCLUDED == TRUE)
extern void BTA_DmUpdateWhiteList(BOOLEAN add_remove, BD_ADDR remote_addr, tBLE_ADDR_TYPE addr_type, tBTA_ADD_WHITELIST_CBACK *add_wl_cb);
case BTM_NO_RESOURCES:
esp_status = ESP_BT_STATUS_NOMEM;
break;
+ case BTM_ILLEGAL_VALUE:
+ esp_status = ESP_BT_STATUS_PARM_INVALID;
+ break;
case BTM_ERR_PROCESSING:
esp_status = ESP_BT_STATUS_PENDING;
break;
BTA_DmConfigEir(&eir_config);
}
+static void btc_gap_bt_set_afh_channels_cmpl_callback(void *p_data)
+{
+ tBTA_SET_AFH_CHANNELS_RESULTS *result = (tBTA_SET_AFH_CHANNELS_RESULTS *)p_data;
+ esp_bt_gap_cb_param_t param;
+ bt_status_t ret;
+ btc_msg_t msg;
+ msg.sig = BTC_SIG_API_CB;
+ msg.pid = BTC_PID_GAP_BT;
+ msg.act = BTC_GAP_BT_SET_AFH_CHANNELS_EVT;
+
+ param.set_afh_channels.stat = btc_btm_status_to_esp_status(result->status);
+
+ ret = btc_transfer_context(&msg, ¶m,
+ sizeof(esp_bt_gap_cb_param_t), NULL);
+
+ if (ret != BT_STATUS_SUCCESS) {
+ BTC_TRACE_ERROR("%s btc_transfer_context failed\n", __func__);
+ }
+}
+
+static void btc_gap_bt_set_afh_channels(btc_gap_bt_args_t *arg)
+{
+ BTA_DmSetAfhChannels(arg->set_afh_channels.channels, btc_gap_bt_set_afh_channels_cmpl_callback);
+}
+
void btc_gap_bt_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src)
{
switch (msg->act) {
btc_gap_bt_config_eir(arg);
break;
}
+
+ case BTC_GAP_BT_ACT_SET_AFH_CHANNELS: {
+ btc_gap_bt_set_afh_channels(arg);
+ break;
+ }
+
default:
break;
}
case BTC_GAP_BT_CONFIG_EIR_DATA_EVT:
case BTC_GAP_BT_AUTH_CMPL_EVT:
case BTC_GAP_BT_PIN_REQ_EVT:
+ case BTC_GAP_BT_SET_AFH_CHANNELS_EVT:
#if (BT_SSP_INCLUDED == TRUE)
case BTC_GAP_BT_CFM_REQ_EVT:
case BTC_GAP_BT_KEY_NOTIF_EVT:
break;
}
#endif ///BT_SSP_INCLUDED == TRUE
+ case BTC_GAP_BT_SET_AFH_CHANNELS_EVT:{
+ btc_gap_bt_cb_to_app(ESP_BT_GAP_SET_AFH_CHANNELS_EVT, (esp_bt_gap_cb_param_t *)msg->arg);
+ break;
+ }
default:
BTC_TRACE_ERROR("%s: Unhandled event (%d)!\n", __FUNCTION__, msg->act);
break;
BTC_GAP_BT_KEY_REQ_EVT,
BTC_GAP_BT_READ_RSSI_DELTA_EVT,
BTC_GAP_BT_CONFIG_EIR_DATA_EVT,
+ BTC_GAP_BT_SET_AFH_CHANNELS_EVT,
}btc_gap_bt_evt_t;
typedef enum {
BTC_GAP_BT_ACT_PASSKEY_REPLY,
BTC_GAP_BT_ACT_CONFIRM_REPLY,
BTC_GAP_BT_ACT_CONFIG_EIR,
+ BTC_GAP_BT_ACT_SET_AFH_CHANNELS,
} btc_gap_bt_act_t;
/* btc_bt_gap_args_t */
struct config_eir_args {
esp_bt_eir_data_t eir_data;
} config_eir;
+
+ // BTC_GAP_BT_ACT_SET_AFH_CHANNELS
+ struct set_afh_channels_args {
+ esp_bt_gap_afh_channels channels;
+ } set_afh_channels;
} btc_gap_bt_args_t;
void btc_gap_bt_call_handler(btc_msg_t *msg);
}
}
+#if (CLASSIC_BT_INCLUDED == TRUE)
+/*******************************************************************************
+**
+** Function BTM_SetAfhChannels
+**
+** Description This function is called to set AFH channels
+**
+** Returns status of the operation
+**
+*******************************************************************************/
+tBTM_STATUS BTM_SetAfhChannels (AFH_CHANNELS channels, tBTM_CMPL_CB *p_afh_channels_cmpl_cback)
+{
+ if (!controller_get_interface()->get_is_ready()) {
+ return (BTM_DEV_RESET);
+ }
+
+ /* Check if set afh already in progress */
+ if (btm_cb.devcb.p_afh_channels_cmpl_cb) {
+ return (BTM_NO_RESOURCES);
+ }
+
+ /* Save callback */
+ btm_cb.devcb.p_afh_channels_cmpl_cb = p_afh_channels_cmpl_cback;
+
+ if (!btsnd_hcic_set_afh_channels (channels)) {
+ return (BTM_NO_RESOURCES);
+ }
+
+ btu_start_timer (&btm_cb.devcb.afh_channels_timer, BTU_TTYPE_BTM_ACL, BTM_DEV_REPLY_TIMEOUT);
+ return BTM_CMD_STARTED;
+}
+
+/*******************************************************************************
+**
+** Function btm_set_afh_channels_complete
+**
+** Description This function is called when set AFH channels complete.
+** message is received from the HCI.
+**
+** Returns void
+**
+*******************************************************************************/
+void btm_set_afh_channels_complete (UINT8 *p)
+{
+ tBTM_CMPL_CB *p_cb = btm_cb.devcb.p_afh_channels_cmpl_cb;
+ tBTM_SET_AFH_CHANNELS_RESULTS results;
+
+ btu_free_timer (&btm_cb.devcb.afh_channels_timer);
+
+ /* If there was a callback address for set AFH channels, call it */
+ btm_cb.devcb.p_afh_channels_cmpl_cb = NULL;
+
+ if (p_cb) {
+ STREAM_TO_UINT8 (results.hci_status, p);
+
+ switch (results.hci_status){
+ case HCI_SUCCESS:
+ results.status = BTM_SUCCESS;
+ break;
+ case HCI_ERR_UNSUPPORTED_VALUE:
+ case HCI_ERR_ILLEGAL_PARAMETER_FMT:
+ results.status = BTM_ILLEGAL_VALUE;
+ break;
+ default:
+ results.status = BTM_ERR_PROCESSING;
+ break;
+ }
+ (*p_cb)(&results);
+ }
+}
+#endif /// CLASSIC_BT_INCLUDED == TRUE
\ No newline at end of file
TIMER_LIST_ENT tx_power_timer;
tBTM_CMPL_CB *p_tx_power_cmpl_cb;/* Callback function to be called */
+#if CLASSIC_BT_INCLUDED == TRUE
+TIMER_LIST_ENT afh_channels_timer;
+tBTM_CMPL_CB *p_afh_channels_cmpl_cb; /* Callback function to be called When */
+/* set AFH channels is completed */
+#endif
+
DEV_CLASS dev_class; /* Local device class */
#if BLE_INCLUDED == TRUE
void btm_vendor_specific_evt (UINT8 *p, UINT8 evt_len);
void btm_delete_stored_link_key_complete (UINT8 *p);
void btm_report_device_status (tBTM_DEV_STATUS status);
-
+void btm_set_afh_channels_complete (UINT8 *p);
/* Internal functions provided by btm_dev.c
**********************************************
case HCI_READ_INQ_TX_POWER_LEVEL:
btm_read_linq_tx_power_complete (p);
break;
+#if (CLASSIC_BT_INCLUDED == TRUE)
+ case HCI_SET_AFH_CHANNELS:
+ btm_set_afh_channels_complete(p);
+ break;
+#endif
#if (BLE_INCLUDED == TRUE)
/* BLE Commands sComplete*/
btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p);
}
+
+#if (CLASSIC_BT_INCLUDED == TRUE)
+BOOLEAN btsnd_hcic_set_afh_channels (AFH_CHANNELS channels)
+{
+ BT_HDR *p;
+ UINT8 *pp;
+
+ if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_SET_AFH_CHANNELS)) == NULL) {
+ return (FALSE);
+ }
+
+ pp = (UINT8 *)(p + 1);
+
+ p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_SET_AFH_CHANNELS;
+ p->offset = 0;
+
+ UINT16_TO_STREAM (pp, HCI_SET_AFH_CHANNELS);
+ UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_SET_AFH_CHANNELS);
+
+ ARRAY_TO_STREAM (pp, channels, HCIC_PARAM_SIZE_SET_AFH_CHANNELS);
+
+ btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p);
+ return (TRUE);
+}
+#endif /// CLASSIC_BT_INCLUDED == TRUE
\ No newline at end of file
#define COF_LEN 12
typedef UINT8 COF[COF_LEN]; /* ciphering offset number */
+#define AFH_CHANNELS_LEN 10
+typedef UINT8 AFH_CHANNELS[AFH_CHANNELS_LEN];
+
typedef struct {
UINT8 qos_flags; /* TBD */
UINT8 service_type; /* see below */
typedef uint8_t BD_ADDR[BD_ADDR_LEN];
#endif
+/* */
+
// From bd.c
/*****************************************************************************
BD_ADDR rem_bda;
} tBTM_LINK_QUALITY_RESULTS;
+/* Structure returned with set AFH channels event (in tBTM_CMPL_CB callback function)
+** in response to BTM_SetAfhChannels call.
+*/
+typedef struct {
+ tBTM_STATUS status;
+ UINT8 hci_status;
+} tBTM_SET_AFH_CHANNELS_RESULTS;
+
/* Structure returned with read inq tx power quality event (in tBTM_CMPL_CB callback function)
** in response to BTM_ReadInquiryRspTxPower call.
*/
*******************************************************************************/
//extern
tBTM_CONTRL_STATE BTM_PM_ReadControllerState(void);
+
+/*******************************************************************************
+**
+** Function BTM_SetAfhChannels
+**
+** Description This function is called to set AFH channels
+**
+** Returns status of the operation
+**
+*******************************************************************************/
+tBTM_STATUS BTM_SetAfhChannels (AFH_CHANNELS channels, tBTM_CMPL_CB *p_afh_channels_cmpl_cback);
+
/*
#ifdef __cplusplus
}
#define HCIC_WRITE_PARAM3_PARAM_OFF 0
+/* set AFH channels */
+BOOLEAN btsnd_hcic_set_afh_channels (AFH_CHANNELS channels);
#define HCIC_PARAM_SIZE_SET_AFH_CHANNELS 10
BOOLEAN btsnd_hcic_write_pin_type(UINT8 type); /* Write PIN Type */