Update bt_discovery demo and README

1. Use bt_app_gap_init function
2. Add Security Simple Pair doc
3. Update README

Update SPP demo

1. Add input module for bt_spp_initiator demo to show the security simple pair features
2. Update README of bt_spp_acceptor and bt_spp_initiator demo.

Format comment in esp_a2dp_api.h

Format comment in esp_avrc_api.h

Format comment in esp_spp_api.h

Fix bt_discovery build err

Update HFP API guide error

Remove BTA_AV_DEBUG

Remove Trailing Whitespace & End of Files
This commit is contained in:
weitianhua 2020-09-15 14:44:03 +08:00
parent 6938f7b30f
commit c347b0a937
26 changed files with 1215 additions and 312 deletions

View File

@ -151,9 +151,11 @@ typedef union {
typedef void (* esp_a2d_cb_t)(esp_a2d_cb_event_t event, esp_a2d_cb_param_t *param);
/**
* @brief A2DP profile data callback function
* @param[in] buf : data received from A2DP source device and is PCM format decoder from SBC decoder;
* @brief A2DP sink data callback function
*
* @param[in] buf : pointer to the data received from A2DP source device and is PCM format decoded from SBC decoder;
* buf references to a static memory block and can be overwritten by upcoming data
*
* @param[in] len : size(in bytes) in buf
*/
typedef void (* esp_a2d_sink_data_cb_t)(const uint8_t *buf, uint32_t len);
@ -191,7 +193,7 @@ esp_err_t esp_a2d_register_callback(esp_a2d_cb_t callback);
* @brief Register A2DP sink data output function; For now the output is PCM data stream decoded
* from SBC format. This function should be called only after esp_bluedroid_enable()
* completes successfully, used only by A2DP sink. The callback is invoked in the context
* of A2DP sink task whose stack size is configurable through menuconfig
* of A2DP sink task whose stack size is configurable through menuconfig.
*
* @param[in] callback: A2DP sink data callback function
*
@ -209,7 +211,8 @@ esp_err_t esp_a2d_sink_register_data_callback(esp_a2d_sink_data_cb_t callback);
* @brief Initialize the bluetooth A2DP sink module. This function should be called
* after esp_bluedroid_enable() completes successfully, and ESP_A2D_PROF_STATE_EVT
* with ESP_A2D_INIT_SUCCESS will reported to the APP layer. Note: A2DP can work independently.
* If you want to use AVRC together, you should initiate AVRC first.
* If you want to use AVRC together, you should initiate AVRC first. This
* function should be called after esp_bluedroid_enable() completes successfully.
*
* @return
* - ESP_OK: if the initialization request is sent successfully
@ -227,7 +230,7 @@ esp_err_t esp_a2d_sink_init(void);
* and ESP_A2D_PROF_STATE_EVT with ESP_A2D_DEINIT_SUCCESS will reported to APP layer.
*
* @return
* - ESP_OK: success
* - ESP_OK: if the deinitialization request is sent successfully
* - ESP_INVALID_STATE: if bluetooth stack is not yet enabled
* - ESP_FAIL: others
*
@ -237,12 +240,13 @@ esp_err_t esp_a2d_sink_deinit(void);
/**
*
* @brief Connect to remote bluetooth A2DP source device, must after esp_a2d_sink_init()
* @brief Connect to remote bluetooth A2DP source device. This API must be called after
* esp_a2d_sink_init() and before esp_a2d_sink_deinit().
*
* @param[in] remote_bda: remote bluetooth device address
*
* @return
* - ESP_OK: connect request is sent to lower layer
* - ESP_OK: connect request is sent to lower layer successfully
* - ESP_INVALID_STATE: if bluetooth stack is not yet enabled
* - ESP_FAIL: others
*
@ -252,11 +256,13 @@ esp_err_t esp_a2d_sink_connect(esp_bd_addr_t remote_bda);
/**
*
* @brief Disconnect from the remote A2DP source device
* @brief Disconnect from the remote A2DP source device. This API must be called after
* esp_a2d_sink_init() and before esp_a2d_sink_deinit().
*
* @param[in] remote_bda: remote bluetooth device address
*
* @return
* - ESP_OK: disconnect request is sent to lower layer
* - ESP_OK: disconnect request is sent to lower layer successfully
* - ESP_INVALID_STATE: if bluetooth stack is not yet enabled
* - ESP_FAIL: others
*
@ -266,11 +272,13 @@ esp_err_t esp_a2d_sink_disconnect(esp_bd_addr_t remote_bda);
/**
*
* @brief media control commands; this API can be used for both A2DP sink and source
* @brief Media control commands. This API can be used for both A2DP sink and source
* and must be called after esp_a2d_sink_init() and before esp_a2d_sink_deinit().
*
* @param[in] ctrl: control commands for A2DP data channel
*
* @return
* - ESP_OK: control command is sent to lower layer
* - ESP_OK: control command is sent to lower layer successfully
* - ESP_INVALID_STATE: if bluetooth stack is not yet enabled
* - ESP_FAIL: others
*
@ -280,13 +288,14 @@ esp_err_t esp_a2d_media_ctrl(esp_a2d_media_ctrl_t ctrl);
/**
*
* @brief Initialize the bluetooth A2DP source module. This function should be called
* @brief Initialize the bluetooth A2DP source module. A2DP can work independently.
* If you want to use AVRC together, you should initiate AVRC first. This function should be called
* after esp_bluedroid_enable() completes successfully, and ESP_A2D_PROF_STATE_EVT
* with ESP_A2D_INIT_SUCCESS will reported to the APP layer. Note: A2DP can work independently.
* If you want to use AVRC together, you should initiate AVRC first.
*
* @return
* - ESP_OK: if the initialization request is sent successfully
* - ESP_OK: if the initialization request is sent to lower layer successfully
* - ESP_INVALID_STATE: if bluetooth stack is not yet enabled
* - ESP_FAIL: others
*
@ -310,10 +319,10 @@ esp_err_t esp_a2d_source_deinit(void);
/**
* @brief Register A2DP source data input function; For now the input is PCM data stream.
* @brief Register A2DP source data input function. For now, the input shoule be PCM data stream.
* This function should be called only after esp_bluedroid_enable() completes
* successfully. The callback is invoked in the context of A2DP source task whose
* stack size is configurable through menuconfig
* stack size is configurable through menuconfig.
*
* @param[in] callback: A2DP source data callback function
*
@ -328,12 +337,13 @@ esp_err_t esp_a2d_source_register_data_callback(esp_a2d_source_data_cb_t callbac
/**
*
* @brief Connect to remote A2DP sink device, must after esp_a2d_source_init()
* @brief Connect to remote A2DP sink device. This API must be called
* after esp_a2d_source_init() and before esp_a2d_source_deinit().
*
* @param[in] remote_bda: remote bluetooth device address
*
* @return
* - ESP_OK: connect request is sent to lower layer
* - ESP_OK: connect request is sent to lower layer successfully
* - ESP_INVALID_STATE: if bluetooth stack is not yet enabled
* - ESP_FAIL: others
*
@ -343,7 +353,8 @@ esp_err_t esp_a2d_source_connect(esp_bd_addr_t remote_bda);
/**
*
* @brief Disconnect from the remote A2DP sink device
* @brief Disconnect from the remote A2DP sink device. This API must be called
* after esp_a2d_source_init() and before esp_a2d_source_deinit().
*
* @param[in] remote_bda: remote bluetooth device address
* @return

View File

@ -400,14 +400,18 @@ typedef union {
/**
* @brief AVRCP controller callback function type
*
* @param event : Event type
*
* @param param : Pointer to callback parameter union
*/
typedef void (* esp_avrc_ct_cb_t)(esp_avrc_ct_cb_event_t event, esp_avrc_ct_cb_param_t *param);
/**
* @brief AVRCP target callback function type
*
* @param event : Event type
*
* @param param : Pointer to callback parameter union
*/
typedef void (* esp_avrc_tg_cb_t)(esp_avrc_tg_cb_event_t event, esp_avrc_tg_cb_param_t *param);
@ -415,7 +419,7 @@ typedef void (* esp_avrc_tg_cb_t)(esp_avrc_tg_cb_event_t event, esp_avrc_tg_cb_p
/**
* @brief Register application callbacks to AVRCP module. This function should be
* called after esp_bluedroid_enable() completes successfully
* called after esp_bluedroid_enable() completes successfully.
*
* @param[in] callback: AVRCP controller callback function
*
@ -459,9 +463,12 @@ esp_err_t esp_avrc_ct_deinit(void);
* @brief Send player application settings command to AVRCP target. This function should be called
* after ESP_AVRC_CT_CONNECTION_STATE_EVT is received and AVRCP connection is established.
*
* @param[in] tl : transaction label, 0 to 15, consecutive commands should use different values.
* @param[in] tl : transaction label, 0 to 15, consecutive commands should use different values
*
* @param[in] attr_id : player application setting attribute IDs from one of esp_avrc_ps_attr_ids_t
*
* @param[in] value_id : attribute value defined for the specific player application setting attribute
*
* @return
* - ESP_OK: success
* - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled
@ -472,9 +479,10 @@ esp_err_t esp_avrc_ct_send_set_player_value_cmd(uint8_t tl, uint8_t attr_id, uin
/**
* @brief Send GetCapabilities PDU to AVRCP target to retrieve remote device's supported
* notification event_ids. This function should be called after
* ESP_AVRC_CT_CONNECTION_STATE_EVT is received and AVRCP connection is established
* ESP_AVRC_CT_CONNECTION_STATE_EVT is received and AVRCP connection is established.
*
* @param[in] tl : transaction label, 0 to 15, consecutive commands should use different values
*
* @param[in] tl : transaction label, 0 to 15, consecutive commands should use different values.
* @return
* - ESP_OK: success
* - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled
@ -483,13 +491,15 @@ esp_err_t esp_avrc_ct_send_set_player_value_cmd(uint8_t tl, uint8_t attr_id, uin
esp_err_t esp_avrc_ct_send_get_rn_capabilities_cmd(uint8_t tl);
/**
* @brief Send register notification command to AVRCP target, This function should be called after
* ESP_AVRC_CT_CONNECTION_STATE_EVT is received and AVRCP connection is established
* @brief Send register notification command to AVRCP target. This function should be called after
* ESP_AVRC_CT_CONNECTION_STATE_EVT is received and AVRCP connection is established.
*
* @param[in] tl : transaction label, 0 to 15, consecutive commands should use different values.
*
* @param[in] event_id : id of events, e.g. ESP_AVRC_RN_PLAY_STATUS_CHANGE, ESP_AVRC_RN_TRACK_CHANGE, etc.
*
* @param[in] event_parameter : playback interval for ESP_AVRC_RN_PLAY_POS_CHANGED;
* For other events , value of this parameter is ignored.
* For other events , value of this parameter is ignored.
* @return
* - ESP_OK: success
* - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled
@ -499,11 +509,13 @@ esp_err_t esp_avrc_ct_send_get_rn_capabilities_cmd(uint8_t tl);
esp_err_t esp_avrc_ct_send_register_notification_cmd(uint8_t tl, uint8_t event_id, uint32_t event_parameter);
/**
* @brief Send set absolute volume command to AVRCP target, This function should be called after
* ESP_AVRC_CT_CONNECTION_STATE_EVT is received and AVRCP connection is established
* @brief Send set absolute volume command to AVRCP target. This function should be called after
* ESP_AVRC_CT_CONNECTION_STATE_EVT is received and AVRCP connection is established.
*
* @param[in] tl : transaction label, 0 to 15, consecutive commands should use different values
*
* @param[in] tl : transaction label, 0 to 15, consecutive commands should use different values.
* @param[in] volume : volume, 0 to 0x7f, means 0% to 100%
*
* @return
* - ESP_OK: success
* - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled
@ -513,10 +525,11 @@ esp_err_t esp_avrc_ct_send_register_notification_cmd(uint8_t tl, uint8_t event_i
esp_err_t esp_avrc_ct_send_set_absolute_volume_cmd(uint8_t tl, uint8_t volume);
/**
* @brief Send metadata command to AVRCP target, This function should be called after
* ESP_AVRC_CT_CONNECTION_STATE_EVT is received and AVRCP connection is established
* @brief Send metadata command to AVRCP target. This function should be called after
* ESP_AVRC_CT_CONNECTION_STATE_EVT is received and AVRCP connection is established.
*
* @param[in] tl : transaction label, 0 to 15, consecutive commands should use different values.
*
* @param[in] attr_mask : mask of attributes, e.g. ESP_AVRC_MD_ATTR_ID_TITLE | ESP_AVRC_MD_ATTR_ID_ARTIST.
*
* @return
@ -528,11 +541,13 @@ esp_err_t esp_avrc_ct_send_metadata_cmd(uint8_t tl, uint8_t attr_mask);
/**
* @brief Send passthrough command to AVRCP target, This function should be called after
* ESP_AVRC_CT_CONNECTION_STATE_EVT is received and AVRCP connection is established
* @brief Send passthrough command to AVRCP target. This function should be called after
* ESP_AVRC_CT_CONNECTION_STATE_EVT is received and AVRCP connection is established.
*
* @param[in] tl : transaction label, 0 to 15, consecutive commands should use different values.
*
* @param[in] key_code : passthrough command code, e.g. ESP_AVRC_PT_CMD_PLAY, ESP_AVRC_PT_CMD_STOP, etc.
*
* @param[in] key_state : passthrough command key state, ESP_AVRC_PT_CMD_STATE_PRESSED or
* ESP_AVRC_PT_CMD_STATE_RELEASED
*
@ -545,8 +560,8 @@ esp_err_t esp_avrc_ct_send_passthrough_cmd(uint8_t tl, uint8_t key_code, uint8_t
/**
* @brief Register application callbacks to AVRCP target module; This function should be
* called after esp_bluedroid_enable() completes successfully
* @brief Register application callbacks to AVRCP target module. This function should be
* called after esp_bluedroid_enable() completes successfully.
*
* @param[in] callback: AVRCP target callback function
*
@ -594,7 +609,7 @@ esp_err_t esp_avrc_tg_deinit(void);
* it covers all of the passthrough commands that can possibly be supported.
* For filter type ESP_AVRC_PSTH_FILTER_SUPPORT_COMMANDS, the retrieved command set covers the
* passthrough commands selected to be supported according to current configuration. The
* configuration can be changed using esp_avrc_tg_set_psth_cmd_filter()
* configuration can be changed using esp_avrc_tg_set_psth_cmd_filter().
*
* @return
* - ESP_OK: success
@ -609,6 +624,7 @@ esp_err_t esp_avrc_tg_get_psth_cmd_filter(esp_avrc_psth_filter_t filter, esp_avr
* @brief Set the filter of remote passthrough commands on AVRC target. Filter is given by
* filter type and bit mask for the passthrough commands. This function should be called
* after esp_avrc_tg_init().
*
* If filter type is ESP_AVRC_PSTH_FILTER_SUPPORT_CMD, the passthrough commands which
* are set "1" as given in cmd_set will generate ESP_AVRC_CT_PASSTHROUGH_RSP_EVT callback
* event and are auto-accepted in the protocol stack, other commands are replied with response
@ -616,7 +632,8 @@ esp_err_t esp_avrc_tg_get_psth_cmd_filter(esp_avrc_psth_filter_t filter, esp_avr
* command set. The allowed command set can be retrieved using esp_avrc_tg_get_psth_cmd_filter()
* with filter type "ESP_AVRC_PSTH_FILTER_ALLOWED_CMD".
*
* Filter type "ESP_AVRC_PSTH_FILTER_ALLOWED_CMD" does not apply to this function
* Filter type "ESP_AVRC_PSTH_FILTER_ALLOWED_CMD" does not apply to this function.
*
* @return
* - ESP_OK: success
* - ESP_ERR_INVALID_STATE: if bluetooth stack is not enabled
@ -628,31 +645,34 @@ esp_err_t esp_avrc_tg_get_psth_cmd_filter(esp_avrc_psth_filter_t filter, esp_avr
esp_err_t esp_avrc_tg_set_psth_cmd_filter(esp_avrc_psth_filter_t filter, const esp_avrc_psth_bit_mask_t *cmd_set);
/**
* @brief Operate on the type esp_avrc_psth_bit_mask_t with regard to a specific PASSTHROUGH command
* @brief Operate on the type esp_avrc_psth_bit_mask_t with regard to a specific PASSTHROUGH command.
*
* @param[in] op: operation requested on the bit mask field
*
* @param[in] psth: pointer to passthrough command bit mask structure
*
* @param[in] cmd: passthrough command code
*
* @return For operation ESP_AVRC_BIT_MASK_OP_SET or ESP_AVRC_BIT_MASK_OP_CLEAR, return
* true for a successful operation, otherwise return false
* true for a successful operation, otherwise return false.
* For operation ESP_AVRC_BIT_MASK_OP_TEST, return true if the corresponding bit
* is set, otherwise false
* is set, otherwise false.
*
*/
bool esp_avrc_psth_bit_mask_operation(esp_avrc_bit_mask_op_t op, esp_avrc_psth_bit_mask_t *psth,
esp_avrc_pt_cmd_t cmd);
bool esp_avrc_psth_bit_mask_operation(esp_avrc_bit_mask_op_t op, esp_avrc_psth_bit_mask_t *psth, esp_avrc_pt_cmd_t cmd);
/**
*
* @brief Get the requested event notification capabilies on local AVRC target. The capability is returned
* in a bit mask representation in evt_set. This function should be called after
* esp_avrc_tg_init().
* in a bit mask representation in evt_set. This function should be called after esp_avrc_tg_init().
*
* For capability type "ESP_AVRC_RN_CAP_ALLOWED_EVT, the retrieved event set is constant and
* it covers all of the notifcation events that can possibly be supported with current
* implementation.
*
* For capability type ESP_AVRC_RN_CAP_SUPPORTED_EVT, the event set covers the notification
* events selected to be supported under current configuration, The configuration can be
* changed using esp_avrc_tg_set_rn_evt_cap()
* changed using esp_avrc_tg_set_rn_evt_cap().
*
* @return
* - ESP_OK: success
@ -677,15 +697,19 @@ esp_err_t esp_avrc_tg_get_rn_evt_cap(esp_avrc_rn_evt_cap_t cap, esp_avrc_rn_evt_
esp_err_t esp_avrc_tg_set_rn_evt_cap(const esp_avrc_rn_evt_cap_mask_t *evt_set);
/**
* @brief Operate on the type esp_avrc_rn_evt_cap_mask_t with regard to a specific event
* @brief Operate on the type esp_avrc_rn_evt_cap_mask_t with regard to a specific event.
*
* @param[in] op: operation requested on the bit mask field
*
* @param[in] events: pointer to event notification capability bit mask structure
*
* @param[in] event_id: notification event code
*
* @return For operation ESP_AVRC_BIT_MASK_OP_SET or ESP_AVRC_BIT_MASK_OP_CLEAR, return
* true for a successful operation, otherwise return false
* true for a successful operation, otherwise return false.
*
* For operation ESP_AVRC_BIT_MASK_OP_TEST, return true if the corresponding bit
* is set, otherwise false
* is set, otherwise false.
*
*/
bool esp_avrc_rn_evt_bit_mask_operation(esp_avrc_bit_mask_op_t op, esp_avrc_rn_evt_cap_mask_t *events,
@ -694,11 +718,13 @@ bool esp_avrc_rn_evt_bit_mask_operation(esp_avrc_bit_mask_op_t op, esp_avrc_rn_e
/**
*
* @brief Send RegisterNotification Response to remote AVRCP controller. Local event notification
* capability can be set using esp_avrc_tg_set_rn_evt_cap(),
* in a bit mask representation in evt_set. This function should be called after
* esp_avrc_tg_init()
* capability can be set using esp_avrc_tg_set_rn_evt_cap(), in a bit mask representation
* in evt_set. This function should be called after esp_avrc_tg_init().
*
* @param[in] event_id: notification event ID that remote AVRCP CT registers
*
* @param[in] rsp: notification response code
*
* @param[in] param: parameters included in the specific notification
*
* @return

View File

@ -36,6 +36,7 @@ const uint8_t *esp_bt_dev_get_address(void);
/**
* @brief Set bluetooth device name. This function should be called after esp_bluedroid_enable()
* completes successfully.
*
* A BR/EDR/LE device type shall have a single Bluetooth device name which shall be
* identical irrespective of the physical channel used to perform the name discovery procedure.
*

View File

@ -22,7 +22,7 @@ extern "C" {
#endif
/**
* @brief Bluetooth stack status type, to indicate whether the bluetooth stack is ready
* @brief Bluetooth stack status type, to indicate whether the bluetooth stack is ready.
*/
typedef enum {
ESP_BLUEDROID_STATUS_UNINITIALIZED = 0, /*!< Bluetooth not initialized */
@ -39,7 +39,7 @@ typedef enum {
esp_bluedroid_status_t esp_bluedroid_get_status(void);
/**
* @brief Enable bluetooth, must after esp_bluedroid_init()
* @brief Enable bluetooth, must after esp_bluedroid_init().
*
* @return
* - ESP_OK : Succeed
@ -48,7 +48,7 @@ esp_bluedroid_status_t esp_bluedroid_get_status(void);
esp_err_t esp_bluedroid_enable(void);
/**
* @brief Disable bluetooth, must prior to esp_bluedroid_deinit()
* @brief Disable bluetooth, must prior to esp_bluedroid_deinit().
*
* @return
* - ESP_OK : Succeed
@ -57,7 +57,7 @@ esp_err_t esp_bluedroid_enable(void);
esp_err_t esp_bluedroid_disable(void);
/**
* @brief Init and alloc the resource for bluetooth, must be prior to every bluetooth stuff
* @brief Init and alloc the resource for bluetooth, must be prior to every bluetooth stuff.
*
* @return
* - ESP_OK : Succeed
@ -66,7 +66,7 @@ esp_err_t esp_bluedroid_disable(void);
esp_err_t esp_bluedroid_init(void);
/**
* @brief Deinit and free the resource for bluetooth, must be after every bluetooth stuff
* @brief Deinit and free the resource for bluetooth, must be after every bluetooth stuff.
*
* @return
* - ESP_OK : Succeed

View File

@ -77,9 +77,9 @@ typedef enum {
/// Bluetooth Device Property Descriptor
typedef struct {
esp_bt_gap_dev_prop_type_t type; /*!< device property type */
int len; /*!< device property value length */
void *val; /*!< device property value */
esp_bt_gap_dev_prop_type_t type; /*!< Device property type */
int len; /*!< Device property value length */
void *val; /*!< Device property value */
} esp_bt_gap_dev_prop_t;
/// Extended Inquiry Response data type
@ -153,7 +153,7 @@ typedef enum {
#define ESP_BT_IO_CAP_IO 1 /*!< DisplayYesNo */ /* relate to BTM_IO_CAP_IO in stack/btm_api.h */
#define ESP_BT_IO_CAP_IN 2 /*!< KeyboardOnly */ /* relate to BTM_IO_CAP_IN in stack/btm_api.h */
#define ESP_BT_IO_CAP_NONE 3 /*!< NoInputNoOutput */ /* relate to BTM_IO_CAP_NONE in stack/btm_api.h */
typedef uint8_t esp_bt_io_cap_t; /*!< combination of the io capability */
typedef uint8_t esp_bt_io_cap_t; /*!< Combination of the IO Capability */
/* BTM Power manager modes */
@ -201,25 +201,25 @@ typedef enum {
/** Bluetooth Device Discovery state */
typedef enum {
ESP_BT_GAP_DISCOVERY_STOPPED, /*!< device discovery stopped */
ESP_BT_GAP_DISCOVERY_STARTED, /*!< device discovery started */
ESP_BT_GAP_DISCOVERY_STOPPED, /*!< Device discovery stopped */
ESP_BT_GAP_DISCOVERY_STARTED, /*!< Device discovery started */
} esp_bt_gap_discovery_state_t;
/// BT GAP callback events
typedef enum {
ESP_BT_GAP_DISC_RES_EVT = 0, /*!< device discovery result event */
ESP_BT_GAP_DISC_STATE_CHANGED_EVT, /*!< discovery state changed event */
ESP_BT_GAP_RMT_SRVCS_EVT, /*!< get remote services event */
ESP_BT_GAP_RMT_SRVC_REC_EVT, /*!< get remote service record event */
ESP_BT_GAP_AUTH_CMPL_EVT, /*!< AUTH complete event */
ESP_BT_GAP_DISC_RES_EVT = 0, /*!< Device discovery result event */
ESP_BT_GAP_DISC_STATE_CHANGED_EVT, /*!< Discovery state changed event */
ESP_BT_GAP_RMT_SRVCS_EVT, /*!< Get remote services event */
ESP_BT_GAP_RMT_SRVC_REC_EVT, /*!< Get remote service record event */
ESP_BT_GAP_AUTH_CMPL_EVT, /*!< Authentication complete event */
ESP_BT_GAP_PIN_REQ_EVT, /*!< Legacy Pairing Pin code request */
ESP_BT_GAP_CFM_REQ_EVT, /*!< Simple Pairing User Confirmation request. */
ESP_BT_GAP_KEY_NOTIF_EVT, /*!< Simple Pairing Passkey Notification */
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_READ_REMOTE_NAME_EVT, /*!< read Remote Name event */
ESP_BT_GAP_CFM_REQ_EVT, /*!< Security Simple Pairing User Confirmation request. */
ESP_BT_GAP_KEY_NOTIF_EVT, /*!< Security Simple Pairing Passkey Notification */
ESP_BT_GAP_KEY_REQ_EVT, /*!< Security 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_READ_REMOTE_NAME_EVT, /*!< Read Remote Name event */
ESP_BT_GAP_MODE_CHG_EVT,
ESP_BT_GAP_REMOVE_BOND_DEV_COMPLETE_EVT, /*!< remove bond device complete event */
ESP_BT_GAP_QOS_CMPL_EVT, /*!< QOS complete event */
@ -379,14 +379,18 @@ typedef union {
/**
* @brief bluetooth GAP callback function type
*
* @param event : Event type
*
* @param param : Pointer to callback parameter
*/
typedef void (* esp_bt_gap_cb_t)(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *param);
/**
* @brief get major service field of COD
*
* @param[in] cod: Class of Device
*
* @return major service bits
*/
static inline uint32_t esp_bt_gap_get_cod_srvc(uint32_t cod)
@ -396,7 +400,9 @@ static inline uint32_t esp_bt_gap_get_cod_srvc(uint32_t cod)
/**
* @brief get major device field of COD
*
* @param[in] cod: Class of Device
*
* @return major device bits
*/
static inline uint32_t esp_bt_gap_get_cod_major_dev(uint32_t cod)
@ -406,7 +412,9 @@ static inline uint32_t esp_bt_gap_get_cod_major_dev(uint32_t cod)
/**
* @brief get minor service field of COD
*
* @param[in] cod: Class of Device
*
* @return minor service bits
*/
static inline uint32_t esp_bt_gap_get_cod_minor_dev(uint32_t cod)
@ -416,7 +424,9 @@ static inline uint32_t esp_bt_gap_get_cod_minor_dev(uint32_t cod)
/**
* @brief get format type of COD
*
* @param[in] cod: Class of Device
*
* @return format type
*/
static inline uint32_t esp_bt_gap_get_cod_format_type(uint32_t cod)
@ -426,7 +436,9 @@ static inline uint32_t esp_bt_gap_get_cod_format_type(uint32_t cod)
/**
* @brief decide the integrity of COD
*
* @param[in] cod: Class of Device
*
* @return
* - true if cod is valid
* - false otherise
@ -455,6 +467,7 @@ esp_err_t esp_bt_gap_register_callback(esp_bt_gap_cb_t callback);
* be called after esp_bluedroid_enable() completes successfully
*
* @param[in] c_mode : one of the enums of esp_bt_connection_mode_t
*
* @param[in] d_mode : one of the enums of esp_bt_discovery_mode_t
*
* @return
@ -466,14 +479,16 @@ esp_err_t esp_bt_gap_register_callback(esp_bt_gap_cb_t callback);
esp_err_t esp_bt_gap_set_scan_mode(esp_bt_connection_mode_t c_mode, esp_bt_discovery_mode_t d_mode);
/**
* @brief This function starts Inquiry and Name Discovery. It should be called after esp_bluedroid_enable() completes successfully.
* @brief This function starts Inquiry and Name Discovery. This function should be called after esp_bluedroid_enable() completes successfully.
* When Inquiry is halted and cached results do not contain device name, then Name Discovery will connect to the peer target to get the device name.
* esp_bt_gap_cb_t will be called with ESP_BT_GAP_DISC_STATE_CHANGED_EVT when Inquriry is started or Name Discovery is completed.
* esp_bt_gap_cb_t will be called with ESP_BT_GAP_DISC_RES_EVT each time the two types of discovery results are got.
*
* @param[in] mode - Inquiry mode
*
* @param[in] inq_len - Inquiry duration in 1.28 sec units, ranging from 0x01 to 0x30. This parameter only specifies the total duration of the Inquiry process,
* - when this time expires, Inquiry will be halted.
*
* @param[in] num_rsps - Number of responses that can be received before the Inquiry is halted, value 0 indicates an unlimited number of responses.
*
* @return
@ -498,7 +513,7 @@ esp_err_t esp_bt_gap_cancel_discovery(void);
/**
* @brief Start SDP to get remote services. This function should be called after esp_bluedroid_enable() completes successfully.
* esp_bt_gap_cb_t will be called with ESP_BT_GAP_RMT_SRVCS_EVT after service discovery ends
* esp_bt_gap_cb_t will be called with ESP_BT_GAP_RMT_SRVCS_EVT after service discovery ends.
*
* @return
* - ESP_OK : Succeed
@ -509,7 +524,7 @@ esp_err_t esp_bt_gap_get_remote_services(esp_bd_addr_t remote_bda);
/**
* @brief Start SDP to look up the service matching uuid on the remote device. This function should be called after
* esp_bluedroid_enable() completes successfully
* esp_bluedroid_enable() completes successfully.
*
* esp_bt_gap_cb_t will be called with ESP_BT_GAP_RMT_SRVC_REC_EVT after service discovery ends
* @return
@ -547,12 +562,11 @@ esp_err_t esp_bt_gap_config_eir_data(esp_bt_eir_data_t *eir_data);
/**
* @brief This function is called to set class of device.
* esp_bt_gap_cb_t will be called with ESP_BT_GAP_SET_COD_EVT after set COD ends
* Some profile have special restrictions on class of device,
* changes may cause these profile do not work
* The structure esp_bt_gap_cb_t will be called with ESP_BT_GAP_SET_COD_EVT after set COD ends.
* Some profile have special restrictions on class of device, changes may cause these profile do not work.
*
* @param[in] cod - class of device
* @param[in] mode - setting mode
* @param[in] mode - setting mode
*
* @return
* - ESP_OK : Succeed
@ -577,7 +591,7 @@ esp_err_t esp_bt_gap_get_cod(esp_bt_cod_t *cod);
* @brief This function is called to read RSSI delta by address after connected. The RSSI value returned by ESP_BT_GAP_READ_RSSI_DELTA_EVT.
*
*
* @param[in] remote_addr - remote device address, corresponding to a certain connection handle.
* @param[in] remote_addr - remote device address, corresponding to a certain connection handle
* @return
* - ESP_OK : Succeed
* - ESP_FAIL: others
@ -601,7 +615,7 @@ esp_err_t esp_bt_gap_remove_bond_device(esp_bd_addr_t bd_addr);
* @brief Get the device number from the security database list of peer device.
* It will return the device bonded number immediately.
*
* @return - >= 0 : bonded devices number.
* @return - >= 0 : bonded devices number
* - ESP_FAIL : failed
*
*/
@ -610,6 +624,7 @@ int esp_bt_gap_get_bond_device_num(void);
/**
* @brief Get the device from the security database list of peer device.
* It will return the device bonded information immediately.
*
* @param[inout] dev_num: Indicate the dev_list array(buffer) size as input.
* If dev_num is large enough, it means the actual number as output.
* Suggest that dev_num value equal to esp_ble_get_bond_device_num().
@ -632,7 +647,9 @@ esp_err_t esp_bt_gap_get_bond_device_list(int *dev_num, esp_bd_addr_t *dev_list)
* will be ignored, and ESP_BT_GAP_PIN_REQ_EVT will come when control
* requests for pin code.
* Else, will use fixed pin code and not callback to users.
*
* @param[in] pin_code_len: Length of pin_code
*
* @param[in] pin_code: Pin_code
*
* @return - ESP_OK : success
@ -646,8 +663,11 @@ esp_err_t esp_bt_gap_set_pin(esp_bt_pin_type_t pin_type, uint8_t pin_code_len, e
* when ESP_BT_GAP_PIN_REQ_EVT is coming.
*
* @param[in] bd_addr: BD address of the peer
*
* @param[in] accept: Pin_code reply successful or declined.
*
* @param[in] pin_code_len: Length of pin_code
*
* @param[in] pin_code: Pin_code
*
* @return - ESP_OK : success
@ -661,7 +681,9 @@ esp_err_t esp_bt_gap_pin_reply(esp_bd_addr_t bd_addr, bool accept, uint8_t pin_c
* @brief Set a GAP security parameter value. Overrides the default value.
*
* @param[in] param_type : the type of the param which is to be set
*
* @param[in] value : the param value
*
* @param[in] len : the length of the param value
*
* @return - ESP_OK : success
@ -676,9 +698,10 @@ esp_err_t esp_bt_gap_set_security_param(esp_bt_sp_param_t param_type,
* @brief Reply the key value to the peer device in the legacy connection stage.
*
* @param[in] bd_addr : BD address of the peer
*
* @param[in] accept : passkey entry successful or declined.
* @param[in] passkey : passkey value, must be a 6 digit number,
* can be lead by 0.
*
* @param[in] passkey : passkey value, must be a 6 digit number, can be lead by 0.
*
* @return - ESP_OK : success
* - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled
@ -692,7 +715,8 @@ esp_err_t esp_bt_gap_ssp_passkey_reply(esp_bd_addr_t bd_addr, bool accept, uint3
* @brief Reply the confirm value to the peer device in the legacy connection stage.
*
* @param[in] bd_addr : BD address of the peer device
* @param[in] accept : numbers to compare are the same or different.
*
* @param[in] accept : numbers to compare are the same or different
*
* @return - ESP_OK : success
* - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled

View File

@ -75,7 +75,7 @@ typedef union
* @brief ESP_HS_CONNECTION_STATE_EVT
*/
struct hf_conn_stat_param {
esp_bd_addr_t remote_bda; /*!< remote bluetooth device address */
esp_bd_addr_t remote_bda; /*!< Remote bluetooth device address */
esp_hf_connection_state_t state; /*!< Connection state */
uint32_t peer_feat; /*!< HF supported features */
uint32_t chld_feat; /*!< AG supported features on call hold and multiparty services */
@ -85,31 +85,31 @@ typedef union
* @brief ESP_HF_AUDIO_STATE_EVT
*/
struct hf_audio_stat_param {
esp_bd_addr_t remote_addr; /*!< remote bluetooth device address */
esp_hf_audio_state_t state; /*!< audio connection state */
esp_bd_addr_t remote_addr; /*!< Remote bluetooth device address */
esp_hf_audio_state_t state; /*!< Audio connection state */
} audio_stat; /*!< AG callback param of ESP_HF_AUDIO_STATE_EVT */
/**
* @brief ESP_HF_BVRA_RESPONSE_EVT
*/
struct hf_vra_rep_param {
esp_bd_addr_t remote_addr; /*!< remote bluetooth device address */
esp_hf_vr_state_t value; /*!< voice recognition state */
esp_bd_addr_t remote_addr; /*!< Remote bluetooth device address */
esp_hf_vr_state_t value; /*!< Voice recognition state */
} vra_rep; /*!< AG callback param of ESP_HF_BVRA_RESPONSE_EVT */
/**
* @brief ESP_HF_VOLUME_CONTROL_EVT
*/
struct hf_volume_control_param {
esp_hf_volume_type_t type; /*!< volume control target, speaker or microphone */
int volume; /*!< gain, ranges from 0 to 15 */
esp_hf_volume_type_t type; /*!< Volume control target, speaker or microphone */
int volume; /*!< Gain, ranges from 0 to 15 */
} volume_control; /*!< AG callback param of ESP_HF_VOLUME_CONTROL_EVT */
/**
* @brief ESP_HF_UNAT_RESPOSNE_EVT
*/
struct hf_unat_rep_param {
char *unat; /*!< unknown AT command string */
char *unat; /*!< Unknown AT command string */
}unat_rep; /*!< AG callback param of ESP_HF_UNAT_RESPONSE_EVT */
/**
@ -166,9 +166,11 @@ typedef union
/**
* @brief AG incoming data callback function, the callback is useful in case of
* Voice Over HCI.
*
* @param[in] buf : pointer to incoming data(payload of HCI synchronous data packet), the
* buffer is allocated inside bluetooth protocol stack and will be released after
* invoke of the callback is finished.
*
* @param[in] len : size(in bytes) in buf
*/
typedef void (* esp_hf_incoming_data_cb_t)(const uint8_t *buf, uint32_t len);
@ -183,7 +185,9 @@ typedef void (* esp_hf_incoming_data_cb_t)(const uint8_t *buf, uint32_t len);
* @param[in] buf : pointer to incoming data(payload of HCI synchronous data packet), the
* buffer is allocated inside bluetooth protocol stack and will be released after
* invoke of the callback is finished.
*
* @param[in] len : size(in bytes) in buf
*
* @param[out] length of data successfully read
*/
typedef uint32_t (* esp_hf_outgoing_data_cb_t) (uint8_t *buf, uint32_t len);
@ -201,8 +205,8 @@ typedef void (* esp_hf_cb_t) (esp_hf_cb_event_t event, esp_hf_cb_param_t *param)
** ESP HF API
************************************************************************************/
/**
* @brief Register application callback function to HFP AG module. This function should be called
* only after esp_bluedroid_enable() completes successfully, used by HFP AG
* @brief Register application callback function to HFP AG module.
* This function should be called only after esp_bluedroid_enable() completes successfully.
*
* @param[in] callback: HFP AG event callback function
*
@ -216,10 +220,11 @@ esp_err_t esp_bt_hf_register_callback(esp_hf_cb_t callback);
/**
*
* @brief Initialize the bluetooth HF AG module. This function should be called
* after esp_bluedroid_enable() completes successfully
* @brief Initialize the bluetooth HF AG module.
* This function should be called after esp_bluedroid_enable() completes successfully.
*
* @param[in] remote_addr: remote bluetooth device address
*
* @return
* - ESP_OK: if the initialization request is sent successfully
* - ESP_INVALID_STATE: if bluetooth stack is not yet enabled
@ -230,10 +235,11 @@ esp_err_t esp_bt_hf_init(esp_bd_addr_t remote_addr);
/**
*
* @brief De-initialize for HF AG module. This function
* should be called only after esp_bluedroid_enable() completes successfully
* @brief De-initialize for HF AG module.
* This function should be called only after esp_bluedroid_enable() completes successfully.
*
* @param[in] remote_addr: remote bluetooth device address
*
* @return
* - ESP_OK: success
* - ESP_INVALID_STATE: if bluetooth stack is not yet enabled
@ -244,7 +250,8 @@ esp_err_t esp_bt_hf_deinit(esp_bd_addr_t remote_addr);
/**
*
* @brief Connect to remote bluetooth HFP client device, must after esp_bt_hf_init()
* @brief To establish a Service Level Connection to remote bluetooth HFP client device.
* This function must be called after esp_bt_hf_init() and before esp_bt_hf_deinit().
*
* @param[in] remote_bda: remote bluetooth HFP client device address
*
@ -258,9 +265,11 @@ esp_err_t esp_bt_hf_connect(esp_bd_addr_t remote_bda);
/**
*
* @brief Disconnect from the remote HFP client
* @brief Disconnect from the remote HFP client. This function must be called
* after esp_bt_hf_init() and before esp_bt_hf_deinit().
*
* @param[in] remote_bda: remote bluetooth device address
*
* @return
* - ESP_OK: disconnect request is sent to lower layer
* - ESP_INVALID_STATE: if bluetooth stack is not yet enabled
@ -271,10 +280,11 @@ esp_err_t esp_bt_hf_disconnect(esp_bd_addr_t remote_bda);
/**
*
* @brief Create audio connection with remote HFP client. As a precondition to use this API,
* Service Level Connection shall exist between HF client and AG.
* @brief Create audio connection with remote HFP client.
* As a precondition to use this API, Service Level Connection shall exist with HFP client.
*
* @param[in] remote_bda: remote bluetooth device address
*
* @return
* - ESP_OK: disconnect request is sent to lower layer
* - ESP_INVALID_STATE: if bluetooth stack is not yet enabled
@ -286,8 +296,10 @@ esp_err_t esp_bt_hf_connect_audio(esp_bd_addr_t remote_bda);
/**
*
* @brief Release the established audio connection with remote HFP client.
* As a precondition to use this API, Service Level Connection shall exist with HFP client.
*
* @param[in] remote_bda: remote bluetooth device address
*
* @return
* - ESP_OK: disconnect request is sent to lower layer
* - ESP_INVALID_STATE: if bluetooth stack is not yet enabled
@ -298,10 +310,11 @@ esp_err_t esp_bt_hf_disconnect_audio(esp_bd_addr_t remote_bda);
/**
*
* @brief Response of Volume Recognition Command(AT+VRA) from HFP client. As a precondition to use this API,
* Service Level Connection shall exist with HFP client.
* @brief Response of Volume Recognition Command(AT+VRA) from HFP client.
* As a precondition to use this API, Service Level Connection shall exist with HFP client.
*
* @param[in] remote_bda: the device address of voice recognization initiator
*
* @param[in] value: 0 - voice recognition disabled, 1- voice recognition enabled
*
* @return
@ -314,11 +327,13 @@ esp_err_t esp_bt_hf_vra(esp_bd_addr_t remote_bda, esp_hf_vr_state_t value);
/**
*
* @brief Volume synchronization with HFP client. As a precondition to use this API,
* Service Level Connection shall exist with HFP client.
* @brief Volume synchronization with HFP client.
* As a precondition to use this API, Service Level Connection shall exist with HFP client.
*
* @param[in] remote_bda: remote bluetooth device address
*
* @param[in] type: volume control target, speaker or microphone
*
* @param[in] volume: gain of the speaker of microphone, ranges 0 to 15
*
* @return
@ -332,9 +347,10 @@ esp_err_t esp_bt_hf_volume_control(esp_bd_addr_t remote_bda, esp_hf_volume_contr
/**
*
* @brief Handle Unknown AT command from HFP Client.
* As a precondition to use this API, Service Level Connection shall exist between AG and HF Client.
* As a precondition to use this API, Service Level Connection shall exist with HFP client.
*
* @param[in] remote_addr: remote bluetooth device address
*
* @param[in] unat: User AT command response to HF Client.
* It will response "ERROR" by default if unat is NULL.
* @return
@ -348,7 +364,7 @@ esp_err_t esp_hf_unat_response(esp_bd_addr_t remote_addr, char *unat);
/**
*
* @brief Unsolicited send extend AT error code to HFP Client.
* As a precondition to use this API, Service Level Connection shall exist between AG and HF Client.
* As a precondition to use this API, Service Level Connection shall exist with HFP client.
*
* @param[in] remote_bda: remote bluetooth device address
* @param[in] response_code: AT command response code
@ -364,7 +380,7 @@ esp_err_t esp_bt_hf_cmee_response(esp_bd_addr_t remote_bda, esp_hf_at_response_c
/**
*
* @brief Usolicited send device status notificationto HFP Client.
* As a precondition to use this API, Service Level Connection shall exist between AG and HF Client
* As a precondition to use this API, Service Level Connection shall exist with HFP client.
*
* @param[in] remote_addr: remote bluetooth device address
* @param[in] call_state: call state
@ -384,7 +400,7 @@ esp_err_t esp_bt_hf_indchange_notification(esp_bd_addr_t remote_addr, esp_hf_cal
/**
*
* @brief Response to device individual indicatiors to HFP Client.
* As a precondition to use this API, Service Level Connection shall exist between AG and HF Client.
* As a precondition to use this API, Service Level Connection shall exist with HFP client.
*
* @param[in] remote_addr: remote bluetooth device address
* @param[in] call_state: call state
@ -409,7 +425,7 @@ esp_err_t esp_bt_hf_cind_response(esp_bd_addr_t remote_addr,
/**
*
* @brief Reponse for AT+COPS command from HF Client.
* As a precondition to use this API, Service Level Connection shall exist with HFP Client.
* As a precondition to use this API, Service Level Connection shall exist with HFP client.
*
* @param[in] remote_addr: remote bluetooth device address
* @param[in] name: current operator name
@ -424,7 +440,7 @@ esp_err_t esp_bt_hf_cops_response(esp_bd_addr_t remote_addr, char *name);
/**
*
* @brief Response to AT+CLCC command from HFP Client.
* As a precondition to use this API, Service Level Connection shall exist between AG and HF Client.
* As a precondition to use this API, Service Level Connection shall exist with HFP client.
*
* @param[in] remote_addr: remote bluetooth device address
* @param[in] index: the index of current call
@ -447,7 +463,7 @@ esp_err_t esp_bt_hf_clcc_response(esp_bd_addr_t remote_addr, int index, esp_hf_c
/**
*
* @brief Response for AT+CNUM command from HF Client.
* As a precondition to use this API, Service Level Connection shall exist with AG.
* As a precondition to use this API, Service Level Connection shall exist with HFP client.
*
* @param[in] remote_addr: remote bluetooth device address
* @param[in] number: registration number
@ -463,7 +479,7 @@ esp_err_t esp_bt_hf_cnum_response(esp_bd_addr_t remote_addr, char *number, esp_h
/**
*
* @brief Inform HF Client that AG Provided in-band ring tone or not.
* As a precondition to use this API, Service Level Connection shall exist with AG.
* As a precondition to use this API, Service Level Connection shall exist with HFP client.
*
* @param[in] remote_addr: remote bluetooth device address
* @param[in] state: in-band ring tone state
@ -478,7 +494,7 @@ esp_err_t esp_bt_hf_bsir(esp_bd_addr_t remote_addr, esp_hf_in_band_ring_state_t
/**
*
* @brief Answer Incoming Call from AG.
* As a precondition to use this API, Service Level Connection shall exist with AG.
* As a precondition to use this API, Service Level Connection shall exist with HFP client.
*
* @param[in] remote_addr: remote bluetooth device address
* @param[in] num_active: the number of active call
@ -500,7 +516,7 @@ esp_err_t esp_bt_hf_answer_call(esp_bd_addr_t remote_addr, int num_active, int n
/**
*
* @brief Reject Incoming Call from AG.
* As a precondition to use this API, Service Level Connection shall exist with AG.
* As a precondition to use this API, Service Level Connection shall exist with HFP client.
*
* @param[in] remote_addr: remote bluetooth device address
* @param[in] num_active: the number of active call
@ -521,8 +537,8 @@ esp_err_t esp_bt_hf_reject_call(esp_bd_addr_t remote_addr, int num_active, int n
/**
*
* @brief Reject incoming call from AG.
* As a precondition to use this API, Service Level Connection shall exist with AG.
* @brief Initiate a call from AG.
* As a precondition to use this API, Service Level Connection shall exist with HFP client.
*
* @param[in] remote_addr: remote bluetooth device address
* @param[in] num_active: the number of active call
@ -544,7 +560,7 @@ esp_err_t esp_bt_hf_out_call(esp_bd_addr_t remote_addr, int num_active, int num_
/**
*
* @brief End an ongoing call.
* As a precondition to use this API, Service Level Connection shall exist with AG.
* As a precondition to use this API, Service Level Connection shall exist with HFP client.
*
* @param[in] remote_addr: remote bluetooth device address
* @param[in] num_active: the number of active call
@ -564,8 +580,8 @@ esp_err_t esp_bt_hf_end_call(esp_bd_addr_t remote_addr, int num_active, int num_
char *number, esp_hf_call_addr_type_t call_addr_type);
/**
* @brief Register AG data output function; the callback is only used in
* the case that Voice Over HCI is enabled.
* @brief Register AG data output function.
* The callback is only used in the case that Voice Over HCI is enabled.
*
* @param[in] recv: HFP client incoming data callback function
* @param[in] send: HFP client outgoing data callback function
@ -580,10 +596,11 @@ esp_err_t esp_bt_hf_register_data_callback(esp_hf_incoming_data_cb_t recv, esp_h
/**
* @brief Trigger the lower-layer to fetch and send audio data. This function is only
* only used in the case that Voice Over HCI is enabled. Precondition is that
* the HFP audio connection is connected. After this function is called, lower
* layer will invoke esp_hf_client_outgoing_data_cb_t to fetch data
* @brief Trigger the lower-layer to fetch and send audio data.
*
* This function is only used in the case that Voice Over HCI is enabled.
* As a precondition to use this API, Service Level Connection shall exist with HFP client.
* After this function is called, lower layer will invoke esp_hf_client_outgoing_data_cb_t to fetch data
*
*/
void esp_hf_outgoing_data_ready(void);

View File

@ -101,33 +101,33 @@ typedef union {
* @brief ESP_HF_CLIENT_CONNECTION_STATE_EVT
*/
struct hf_client_conn_stat_param {
esp_hf_client_connection_state_t state; /*!< HF connection state */
uint32_t peer_feat; /*!< AG supported features */
uint32_t chld_feat; /*!< AG supported features on call hold and multiparty services */
esp_bd_addr_t remote_bda; /*!< remote bluetooth device address */
} conn_stat; /*!< HF callback param of ESP_HF_CLIENT_CONNECTION_STATE_EVT */
esp_hf_client_connection_state_t state; /*!< HF connection state */
uint32_t peer_feat; /*!< AG supported features */
uint32_t chld_feat; /*!< AG supported features on call hold and multiparty services */
esp_bd_addr_t remote_bda; /*!< remote bluetooth device address */
} conn_stat; /*!< HF callback param of ESP_HF_CLIENT_CONNECTION_STATE_EVT */
/**
* @brief ESP_HF_CLIENT_AUDIO_STATE_EVT
*/
struct hf_client_audio_stat_param {
esp_hf_client_audio_state_t state; /*!< audio connection state */
esp_bd_addr_t remote_bda; /*!< remote bluetooth device address */
} audio_stat; /*!< HF callback param of ESP_HF_CLIENT_AUDIO_STATE_EVT */
esp_hf_client_audio_state_t state; /*!< audio connection state */
esp_bd_addr_t remote_bda; /*!< remote bluetooth device address */
} audio_stat; /*!< HF callback param of ESP_HF_CLIENT_AUDIO_STATE_EVT */
/**
* @brief ESP_HF_CLIENT_BVRA_EVT
*/
struct hf_client_bvra_param {
esp_hf_vr_state_t value; /*!< voice recognition state */
} bvra; /*!< HF callback param of ESP_HF_CLIENT_BVRA_EVT */
esp_hf_vr_state_t value; /*!< voice recognition state */
} bvra; /*!< HF callback param of ESP_HF_CLIENT_BVRA_EVT */
/**
* @brief ESP_HF_CLIENT_CIND_SERVICE_AVAILABILITY_EVT
*/
struct hf_client_service_availability_param {
esp_hf_network_state_t status; /*!< service availability status */
} service_availability; /*!< HF callback param of ESP_HF_CLIENT_CIND_SERVICE_AVAILABILITY_EVT */
esp_hf_network_state_t status; /*!< service availability status */
} service_availability; /*!< HF callback param of ESP_HF_CLIENT_CIND_SERVICE_AVAILABILITY_EVT */
/**
* @brief ESP_HF_CLIENT_CIND_ROAMING_STATUS_EVT
@ -270,8 +270,11 @@ typedef void (* esp_hf_client_incoming_data_cb_t)(const uint8_t *buf, uint32_t l
* @param[in] buf : pointer to incoming data(payload of HCI synchronous data packet), the
* buffer is allocated inside bluetooth protocol stack and will be released after
* invoke of the callback is finished.
*
* @param[in] len : size(in bytes) in buf
*
* @param[out] length of data successfully read
*
*/
typedef uint32_t (* esp_hf_client_outgoing_data_cb_t)(uint8_t *buf, uint32_t len);
@ -285,8 +288,8 @@ typedef uint32_t (* esp_hf_client_outgoing_data_cb_t)(uint8_t *buf, uint32_t len
typedef void (* esp_hf_client_cb_t)(esp_hf_client_cb_event_t event, esp_hf_client_cb_param_t *param);
/**
* @brief Register application callback function to HFP client module. This function should be called
* only after esp_bluedroid_enable() completes successfully, used by HFP client
* @brief Register application callback function to HFP client module.
* This function should be called only after esp_bluedroid_enable() completes successfully.
*
* @param[in] callback: HFP client event callback function
*
@ -300,8 +303,8 @@ esp_err_t esp_hf_client_register_callback(esp_hf_client_cb_t callback);
/**
*
* @brief Initialize the bluetooth HFP client module. This function should be called
* after esp_bluedroid_enable() completes successfully
* @brief Initialize the bluetooth HFP client module.
* This function should be called after esp_bluedroid_enable() completes successfully.
*
* @return
* - ESP_OK: if the initialization request is sent successfully
@ -313,8 +316,8 @@ esp_err_t esp_hf_client_init(void);
/**
*
* @brief De-initialize for HFP client module. This function
* should be called only after esp_bluedroid_enable() completes successfully
* @brief De-initialize for HFP client module.
* This function should be called only after esp_bluedroid_enable() completes successfully.
*
* @return
* - ESP_OK: success
@ -326,7 +329,8 @@ esp_err_t esp_hf_client_deinit(void);
/**
*
* @brief Connect to remote bluetooth HFP audio gateway(AG) device, must after esp_hf_client_init()
* @brief Establish a Service Level Connection to remote bluetooth HFP audio gateway(AG) device.
* This function must be called after esp_hf_client_init() and before esp_hf_client_deinit().
*
* @param[in] remote_bda: remote bluetooth device address
*
@ -340,9 +344,11 @@ esp_err_t esp_hf_client_connect(esp_bd_addr_t remote_bda);
/**
*
* @brief Disconnect from the remote HFP audio gateway
* @brief Disconnect from the remote HFP audio gateway.
* This function must be called after esp_hf_client_init() and before esp_hf_client_deinit().
*
* @param[in] remote_bda: remote bluetooth device address
*
* @return
* - ESP_OK: disconnect request is sent to lower layer
* - ESP_INVALID_STATE: if bluetooth stack is not yet enabled
@ -353,8 +359,8 @@ esp_err_t esp_hf_client_disconnect(esp_bd_addr_t remote_bda);
/**
*
* @brief Create audio connection with remote HFP AG. As a precondition to use this API,
* Service Level Connection shall exist with AG
* @brief Create audio connection with remote HFP AG.
* As a precondition to use this API, Service Level Connection shall exist with AG.
*
* @param[in] remote_bda: remote bluetooth device address
* @return
@ -368,6 +374,7 @@ esp_err_t esp_hf_client_connect_audio(esp_bd_addr_t remote_bda);
/**
*
* @brief Release the established audio connection with remote HFP AG.
* As a precondition to use this API, Service Level Connection shall exist with AG.
*
* @param[in] remote_bda: remote bluetooth device address
* @return
@ -380,8 +387,8 @@ esp_err_t esp_hf_client_disconnect_audio(esp_bd_addr_t remote_bda);
/**
*
* @brief Enable voice recognition in the AG. As a precondition to use this API,
* Service Level Connection shall exist with AG
* @brief Enable voice recognition in the AG.
* As a precondition to use this API, Service Level Connection shall exist with AG.
*
* @return
* - ESP_OK: disconnect request is sent to lower layer
@ -393,8 +400,8 @@ esp_err_t esp_hf_client_start_voice_recognition(void);
/**
*
* @brief Disable voice recognition in the AG. As a precondition to use this API,
* Service Level Connection shall exist with AG
* @brief Disable voice recognition in the AG.
* As a precondition to use this API, Service Level Connection shall exist with AG.
*
* @return
* - ESP_OK: disconnect request is sent to lower layer
@ -406,8 +413,8 @@ esp_err_t esp_hf_client_stop_voice_recognition(void);
/**
*
* @brief Volume synchronization with AG. As a precondition to use this API,
* Service Level Connection shall exist with AG
* @brief Volume synchronization with AG.
* As a precondition to use this API, Service Level Connection shall exist with AG.
*
* @param[in] type: volume control target, speaker or microphone
* @param[in] volume: gain of the speaker of microphone, ranges 0 to 15
@ -422,9 +429,8 @@ esp_err_t esp_hf_client_volume_update(esp_hf_volume_control_target_t type, int v
/**
*
* @brief Place a call with a specified number, if number is NULL, last called number is
* called. As a precondition to use this API, Service Level Connection shall
* exist with AG
* @brief Place a call with a specified number, if number is NULL, last called number is called.
* As a precondition to use this API, Service Level Connection shall exist with AG.
*
* @param[in] number: number string of the call. If NULL, the last number is called(aka re-dial)
*
@ -438,8 +444,8 @@ esp_err_t esp_hf_client_dial(const char *number);
/**
*
* @brief Place a call with number specified by location(speed dial). As a precondition,
* to use this API, Service Level Connection shall exist with AG
* @brief Place a call with number specified by location(speed dial).
* As a precondition to use this API, Service Level Connection shall exist with AG.
*
* @param[in] location: location of the number in the memory
*
@ -455,7 +461,7 @@ esp_err_t esp_hf_client_dial_memory(int location);
/**
*
* @brief Send call hold and multiparty commands, or enhanced call control commands(Use AT+CHLD).
* As a precondition to use this API, Service Level Connection shall exist with AG
* As a precondition to use this API, Service Level Connection shall exist with AG.
*
* @param[in] chld: AT+CHLD call hold and multiparty handling AT command.
* @param[in] idx: used in Enhanced Call Control Mechanisms, used if chld is
@ -472,7 +478,7 @@ esp_err_t esp_hf_client_send_chld_cmd(esp_hf_chld_type_t chld, int idx);
/**
*
* @brief Send response and hold action command(Send AT+BTRH command)
* As a precondition to use this API, Service Level Connection shall exist with AG
* As a precondition to use this API, Service Level Connection shall exist with AG.
*
* @param[in] btrh: response and hold action to send
*
@ -486,8 +492,8 @@ esp_err_t esp_hf_client_send_btrh_cmd(esp_hf_btrh_cmd_t btrh);
/**
*
* @brief Answer an incoming call(send ATA command). As a precondition to use this API,
* Service Level Connection shall exist with AG
* @brief Answer an incoming call(send ATA command).
* As a precondition to use this API, Service Level Connection shall exist with AG.
*
* @return
* - ESP_OK: disconnect request is sent to lower layer
@ -499,8 +505,8 @@ esp_err_t esp_hf_client_answer_call(void);
/**
*
* @brief Reject an incoming call(send AT+CHUP command), As a precondition to use this API,
* Service Level Connection shall exist with AG
* @brief Reject an incoming call(send AT+CHUP command).
* As a precondition to use this API, Service Level Connection shall exist with AG.
*
* @return
* - ESP_OK: disconnect request is sent to lower layer
@ -512,8 +518,8 @@ esp_err_t esp_hf_client_reject_call(void);
/**
*
* @brief Query list of current calls in AG(send AT+CLCC command), As a precondition to use this API,
* Service Level Connection shall exist with AG
* @brief Query list of current calls in AG(send AT+CLCC command).
* As a precondition to use this API, Service Level Connection shall exist with AG.
*
* @return
* - ESP_OK: disconnect request is sent to lower layer
@ -525,8 +531,8 @@ esp_err_t esp_hf_client_query_current_calls(void);
/**
*
* @brief Query the name of currently selected network operator in AG(use AT+COPS commands)
* As a precondition to use this API, Service Level Connection shall exist with AG
* @brief Query the name of currently selected network operator in AG(use AT+COPS commands).
* As a precondition to use this API, Service Level Connection shall exist with AG.
*
* @return
* - ESP_OK: disconnect request is sent to lower layer
@ -552,7 +558,7 @@ esp_err_t esp_hf_client_retrieve_subscriber_info(void);
/**
*
* @brief Transmit DTMF codes during an ongoing call(use AT+VTS commands)
* As a precondition to use this API, Service Level Connection shall exist with AG
* As a precondition to use this API, Service Level Connection shall exist with AG.
*
* @param[in] code: dtmf code, single ascii character in the set 0-9, #, *, A-D
*
@ -566,9 +572,8 @@ esp_err_t esp_hf_client_send_dtmf(char code);
/**
*
* @brief Request a phone number from AG corresponding to last voice tag recorded
* (send AT+BINP command). As a precondition to use this API, Service Level
* Connection shall exist with AG
* @brief Request a phone number from AG corresponding to last voice tag recorded (send AT+BINP command).
* As a precondition to use this API, Service Level Connection shall exist with AG.
*
* @return
* - ESP_OK: disconnect request is sent to lower layer
@ -580,7 +585,7 @@ esp_err_t esp_hf_client_request_last_voice_tag_number(void);
/**
*
* @brief Disable echo cancellation and noise reduction in the AG (use AT+NREC=0 command)
* @brief Disable echo cancellation and noise reduction in the AG (use AT+NREC=0 command).
* As a precondition to use this API, Service Level Connection shall exist with AG
*
* @return
@ -597,6 +602,7 @@ esp_err_t esp_hf_client_send_nrec(void);
* the case that Voice Over HCI is enabled.
*
* @param[in] recv: HFP client incoming data callback function
*
* @param[in] send: HFP client outgoing data callback function
*
* @return
@ -609,10 +615,11 @@ esp_err_t esp_hf_client_register_data_callback(esp_hf_client_incoming_data_cb_t
esp_hf_client_outgoing_data_cb_t send);
/**
* @brief Trigger the lower-layer to fetch and send audio data. This function is only
* only used in the case that Voice Over HCI is enabled. Precondition is that
* the HFP audio connection is connected. After this function is called, lower
* layer will invoke esp_hf_client_outgoing_data_cb_t to fetch data
* @brief Trigger the lower-layer to fetch and send audio data.
* This function is only only used in the case that Voice Over HCI is enabled. After this
* function is called, lower layer will invoke esp_hf_client_outgoing_data_cb_t to fetch data.
*
* As a precondition to use this API, Service Level Connection shall exist with AG.
*
*/
void esp_hf_client_outgoing_data_ready(void);
@ -625,6 +632,7 @@ void esp_hf_client_outgoing_data_ready(void);
* @param[in] src_sps: original samples per second(source audio data, i.e. 48000, 32000,
* 16000, 44100, 22050, 11025)
* @param[in] bits: number of bits per pcm sample (16)
*
* @param[in] channels: number of channels (i.e. mono(1), stereo(2)...)
*/
void esp_hf_client_pcm_resample_init(uint32_t src_sps, uint32_t bits, uint32_t channels);
@ -639,7 +647,9 @@ void esp_hf_client_pcm_resample_deinit(void);
* samples. This can only be used in the case that Voice Over HCI is enabled.
*
* @param[in] src: pointer to the buffer where the original sampling PCM are stored
*
* @param[in] in_bytes: length of the input PCM sample buffer in byte
*
* @param[in] dst: pointer to the buffer which is to be used to store the converted PCM samples
*
* @return number of samples converted

View File

@ -33,7 +33,12 @@ typedef enum {
ESP_SPP_NO_CONNECTION, /*!< connection may have been closed */
} esp_spp_status_t;
/* Security Setting Mask, Suggest to use ESP_SPP_SEC_NONE, ESP_SPP_SEC_AUTHORIZE or ESP_SPP_SEC_AUTHENTICATE only.*/
/* Security Setting Mask
Use these three mask mode:
1. ESP_SPP_SEC_NONE
2. ESP_SPP_SEC_AUTHENTICATE
3. (ESP_SPP_SEC_ENCRYPT|ESP_SPP_SEC_AUTHENTICATE)
*/
#define ESP_SPP_SEC_NONE 0x0000 /*!< No security. relate to BTA_SEC_NONE in bta/bta_api.h */
#define ESP_SPP_SEC_AUTHORIZE 0x0001 /*!< Authorization required (only needed for out going connection ) relate to BTA_SEC_AUTHORIZE in bta/bta_api.h*/
#define ESP_SPP_SEC_AUTHENTICATE 0x0012 /*!< Authentication required. relate to BTA_SEC_AUTHENTICATE in bta/bta_api.h*/
@ -90,7 +95,7 @@ typedef union {
*/
struct spp_uninit_evt_param {
esp_spp_status_t status; /*!< status */
} uninit; /*!< SPP callback param of SPP_UNINIT_EVT */
} uninit; /*!< SPP callback param of SPP_UNINIT_EVT */
/**
* @brief SPP_DISCOVERY_COMP_EVT
@ -146,7 +151,7 @@ typedef union {
*/
struct spp_srv_stop_evt_param {
esp_spp_status_t status; /*!< status */
} srv_stop; /*!< SPP callback param of ESP_SPP_SRV_STOP_EVT */
} srv_stop; /*!< SPP callback param of ESP_SPP_SRV_STOP_EVT */
/**
* @brief ESP_SPP_CL_INIT_EVT
@ -189,15 +194,17 @@ typedef union {
} esp_spp_cb_param_t; /*!< SPP callback parameter union type */
/**
* @brief SPP callback function type
* @brief SPP callback function type.
* When handle ESP_SPP_DATA_IND_EVT, it is strongly recommended to cache incoming data, and process them in
* other lower priority application task rather than in this callback directly.
*
* @param event: Event type
* @param param: Point to callback parameter, currently is union type
*/
typedef void (esp_spp_cb_t)(esp_spp_cb_event_t event, esp_spp_cb_param_t *param);
/**
* @brief This function is called to init callbacks
* with SPP module.
* @brief This function is called to init callbacks with SPP module.
*
* @param[in] callback: pointer to the init callback function.
*
@ -208,7 +215,9 @@ typedef void (esp_spp_cb_t)(esp_spp_cb_event_t event, esp_spp_cb_param_t *param)
esp_err_t esp_spp_register_callback(esp_spp_cb_t callback);
/**
* @brief This function is called to init SPP.
* @brief This function is called to init SPP module.
* When the operation is completed, the callback function will be called with ESP_SPP_INIT_EVT.
* This function should be called after esp_bluedroid_enable() completes successfully.
*
* @param[in] mode: Choose the mode of SPP, ESP_SPP_MODE_CB or ESP_SPP_MODE_VFS.
*
@ -219,7 +228,11 @@ esp_err_t esp_spp_register_callback(esp_spp_cb_t callback);
esp_err_t esp_spp_init(esp_spp_mode_t mode);
/**
* @brief This function is called to uninit SPP.
* @brief This function is called to uninit SPP module.
* The operation will close all active SPP connection first, then the callback function will be called
* with ESP_SPP_CLOSE_EVT, and the number of ESP_SPP_CLOSE_EVT is equal to the number of connection.
* When the operation is completed, the callback function will be called with ESP_SPP_UNINIT_EVT.
* This function should be called after esp_spp_init() completes successfully.
*
* @return
* - ESP_OK: success
@ -229,10 +242,9 @@ esp_err_t esp_spp_deinit(void);
/**
* @brief This function is called to performs service discovery for
* the services provided by the given peer device. When the
* operation is complete the callback function will be called
* with a ESP_SPP_DISCOVERY_COMP_EVT.
* @brief This function is called to performs service discovery for the services provided by the given peer device.
* When the operation is completed, the callback function will be called with ESP_SPP_DISCOVERY_COMP_EVT.
* This funciton must be called after esp_spp_init() successful and before esp_spp_deinit().
*
* @param[in] bd_addr: Remote device bluetooth device address.
*
@ -244,10 +256,9 @@ esp_err_t esp_spp_start_discovery(esp_bd_addr_t bd_addr);
/**
* @brief This function makes an SPP connection to a remote BD Address.
* When the connection is initiated or failed to initiate,
* the callback is called with ESP_SPP_CL_INIT_EVT.
* When the connection is established or failed,
* the callback is called with ESP_SPP_OPEN_EVT.
* When the connection is initiated or failed to initiate, the callback is called with ESP_SPP_CL_INIT_EVT.
* When the connection is established or failed, the callback is called with ESP_SPP_OPEN_EVT.
* This funciton must be called after esp_spp_init() successful and before esp_spp_deinit().
*
* @param[in] sec_mask: Security Setting Mask. Suggest to use ESP_SPP_SEC_NONE, ESP_SPP_SEC_AUTHORIZE or ESP_SPP_SEC_AUTHENTICATE only.
* @param[in] role: Master or slave.
@ -258,11 +269,12 @@ esp_err_t esp_spp_start_discovery(esp_bd_addr_t bd_addr);
* - ESP_OK: success
* - other: failed
*/
esp_err_t esp_spp_connect(esp_spp_sec_t sec_mask,
esp_spp_role_t role, uint8_t remote_scn, esp_bd_addr_t peer_bd_addr);
esp_err_t esp_spp_connect(esp_spp_sec_t sec_mask, esp_spp_role_t role, uint8_t remote_scn, esp_bd_addr_t peer_bd_addr);
/**
* @brief This function closes an SPP connection.
* When the operation is completed, the callback function will be called with ESP_SPP_CLOSE_EVT.
* This funciton must be called after esp_spp_init() successful and before esp_spp_deinit().
*
* @param[in] handle: The connection handle.
*
@ -275,10 +287,9 @@ esp_err_t esp_spp_disconnect(uint32_t handle);
/**
* @brief This function create a SPP server and starts listening for an
* SPP connection request from a remote Bluetooth device.
* When the server is started successfully, the callback is called
* with ESP_SPP_START_EVT.
* When the connection is established, the callback is called
* with ESP_SPP_SRV_OPEN_EVT.
* When the server is started successfully, the callback is called with ESP_SPP_START_EVT.
* When the connection is established, the callback is called with ESP_SPP_SRV_OPEN_EVT.
* This funciton must be called after esp_spp_init() successful and before esp_spp_deinit().
*
* @param[in] sec_mask: Security Setting Mask. Suggest to use ESP_SPP_SEC_NONE, ESP_SPP_SEC_AUTHORIZE or ESP_SPP_SEC_AUTHENTICATE only.
* @param[in] role: Master or slave.
@ -290,13 +301,14 @@ esp_err_t esp_spp_disconnect(uint32_t handle);
* - ESP_OK: success
* - other: failed
*/
esp_err_t esp_spp_start_srv(esp_spp_sec_t sec_mask,
esp_spp_role_t role, uint8_t local_scn, const char *name);
esp_err_t esp_spp_start_srv(esp_spp_sec_t sec_mask, esp_spp_role_t role, uint8_t local_scn, const char *name);
/**
* @brief This function stops a SPP server
* When the server is stopped successfully, the callback is called
* with ESP_SPP_SRV_STOP_EVT.
* @brief This function stops a SPP server.
* The operation will close all active SPP connection first, then the callback function will be called
* with ESP_SPP_CLOSE_EVT, and the number of ESP_SPP_CLOSE_EVT is equal to the number of connection.
* When the operation is completed, the callback is called with ESP_SPP_SRV_STOP_EVT.
* This funciton must be called after esp_spp_init() successful and before esp_spp_deinit().
*
* @return
* - ESP_OK: success
@ -306,6 +318,11 @@ esp_err_t esp_spp_stop_srv(void);
/**
* @brief This function is used to write data, only for ESP_SPP_MODE_CB.
* When this function need to be called repeatedly, it is strongly recommended to call this function again after
* the previous event ESP_SPP_WRITE_EVT is received and the parameter 'cong' is equal to false. If the previous event
* ESP_SPP_WRITE_EVT with parameter 'cong' is equal to true, the function can only be called again when the event
* ESP_SPP_CONG_EVT with parameter 'cong' equal to false is received.
* This funciton must be called after an connection between initiator and acceptor has been established.
*
* @param[in] handle: The connection handle.
* @param[in] len: The length of the data written.
@ -320,6 +337,7 @@ esp_err_t esp_spp_write(uint32_t handle, int len, uint8_t *p_data);
/**
* @brief This function is used to register VFS.
* For now, SPP only supports write, read and close.
*
* @return
* - ESP_OK: success

View File

@ -273,7 +273,7 @@ static void bta_av_save_addr(tBTA_AV_SCB *p_scb, const BD_ADDR b)
APPL_TRACE_DEBUG("bta_av_save_addr r:%d, s:%d",
p_scb->recfg_sup, p_scb->suspend_sup);
if (bdcmp(p_scb->peer_addr, b) != 0) {
APPL_TRACE_ERROR("reset flags");
APPL_TRACE_WARNING("reset flags");
/* a new addr, reset the supported flags */
p_scb->recfg_sup = TRUE;
p_scb->suspend_sup = TRUE;

View File

@ -198,10 +198,6 @@ tBTA_AV_CB bta_av_cb;
tBTA_AV_CB *bta_av_cb_ptr;
#endif
#if (defined(BTA_AV_DEBUG) && BTA_AV_DEBUG == TRUE)
static char *bta_av_st_code(UINT8 state);
#endif
/*******************************************************************************
**
** Function bta_av_timer_cback
@ -414,27 +410,18 @@ void bta_av_conn_cback(UINT8 handle, BD_ADDR bd_addr, UINT8 event, tAVDT_CTRL *p
if (AVDT_DISCONNECT_IND_EVT == event) {
p_scb = bta_av_addr_to_scb(bd_addr);
}
#if (defined(BTA_AV_DEBUG) && BTA_AV_DEBUG == TRUE)
else if (AVDT_CONNECT_IND_EVT == event) {
APPL_TRACE_DEBUG("CONN_IND is ACP:%d\n", p_data->hdr.err_param);
}
#endif
if (/*((p_scb && (p_scb->role & BTA_AV_ROLE_AD_ACP)) ||
//(AVDT_CONNECT_IND_EVT == event && AVDT_ACP == p_data->hdr.err_param))
(AVDT_CONNECT_IND_EVT == event))&& */
(p_msg = (tBTA_AV_STR_MSG *) osi_malloc((UINT16) (sizeof(tBTA_AV_STR_MSG)))) != NULL) {
if ((p_msg = (tBTA_AV_STR_MSG *) osi_malloc((UINT16) (sizeof(tBTA_AV_STR_MSG)))) != NULL) {
p_msg->hdr.event = evt;
p_msg->hdr.layer_specific = event;
p_msg->hdr.offset = p_data->hdr.err_param;
bdcpy(p_msg->bd_addr, bd_addr);
#if (defined(BTA_AV_DEBUG) && BTA_AV_DEBUG == TRUE)
if (p_scb) {
APPL_TRACE_DEBUG("scb hndl x%x, role x%x\n", p_scb->hndl, p_scb->role);
}
#endif
APPL_TRACE_DEBUG("conn_cback bd_addr:%02x-%02x-%02x-%02x-%02x-%02x\n",
bd_addr[0], bd_addr[1],
bd_addr[2], bd_addr[3],
@ -442,7 +429,6 @@ void bta_av_conn_cback(UINT8 handle, BD_ADDR bd_addr, UINT8 event, tAVDT_CTRL *p
bta_sys_sendmsg(p_msg);
}
}
}
#if AVDT_REPORTING == TRUE
@ -1188,12 +1174,7 @@ void bta_av_sm_execute(tBTA_AV_CB *p_cb, UINT16 event, tBTA_AV_DATA *p_data)
tBTA_AV_ST_TBL state_table;
UINT8 action;
#if (defined(BTA_AV_DEBUG) && BTA_AV_DEBUG == TRUE)
APPL_TRACE_EVENT("AV event=0x%x(%s) state=%d(%s)\n",
event, bta_av_evt_code(event), p_cb->state, bta_av_st_code(p_cb->state));
#else
APPL_TRACE_EVENT("AV event=0x%x state=%d\n", event, p_cb->state);
#endif
/* look up the state table for the current state */
state_table = bta_av_st_tbl[p_cb->state];
@ -1231,19 +1212,11 @@ BOOLEAN bta_av_hdl_event(BT_HDR *p_msg)
}
if (event >= first_event) {
#if (defined(BTA_AV_DEBUG) && BTA_AV_DEBUG == TRUE)
APPL_TRACE_VERBOSE("AV nsm event=0x%x(%s)\n", event, bta_av_evt_code(event));
#else
APPL_TRACE_VERBOSE("AV nsm event=0x%x\n", event);
#endif
/* non state machine events */
(*bta_av_nsm_act[event - BTA_AV_FIRST_NSM_EVT]) ((tBTA_AV_DATA *) p_msg);
} else if (event >= BTA_AV_FIRST_SM_EVT && event <= BTA_AV_LAST_SM_EVT) {
#if (defined(BTA_AV_DEBUG) && BTA_AV_DEBUG == TRUE)
APPL_TRACE_VERBOSE("AV sm event=0x%x(%s)\n", event, bta_av_evt_code(event));
#else
APPL_TRACE_VERBOSE("AV sm event=0x%x\n", event);
#endif
/* state machine events */
bta_av_sm_execute(&bta_av_cb, p_msg->event, (tBTA_AV_DATA *) p_msg);
} else {
@ -1260,24 +1233,6 @@ BOOLEAN bta_av_hdl_event(BT_HDR *p_msg)
/*****************************************************************************
** Debug Functions
*****************************************************************************/
#if (defined(BTA_AV_DEBUG) && BTA_AV_DEBUG == TRUE)
/*******************************************************************************
**
** Function bta_av_st_code
**
** Description
**
** Returns char *
**
*******************************************************************************/
UNUSED_ATTR static char *bta_av_st_code(UINT8 state)
{
switch (state) {
case BTA_AV_INIT_ST: return "INIT";
case BTA_AV_OPEN_ST: return "OPEN";
default: return "unknown";
}
}
/*******************************************************************************
**
** Function bta_av_evt_code
@ -1357,6 +1312,71 @@ char *bta_av_evt_code(UINT16 evt_code)
default: return "unknown";
}
}
#endif
/*******************************************************************************
**
** Function bta_av_action_code
**
** Description
**
** Returns char *
**
*******************************************************************************/
char *bta_av_action_code(UINT16 action_code)
{
switch (action_code) {
case 0: return "BTA_AV_DO_DISC";
case 1: return "BTA_AV_CLEANUP";
case 2: return "BTA_AV_FREE_SDB";
case 3: return "BTA_AV_CONFIG_IND";
case 4: return "BTA_AV_DISCONNECT_REQ";
case 5: return "BTA_AV_SECURITY_REQ";
case 6: return "BTA_AV_SECURITY_RSP";
case 7: return "BTA_AV_SETCONFIG_RSP";
case 8: return "BTA_AV_ST_RC_TIMER";
case 9: return "BTA_AV_STR_OPENED";
case 10: return "BTA_AV_SECURITY_IND";
case 11: return "BTA_AV_SECURITY_CFM";
case 12: return "BTA_AV_DO_CLOSE";
case 13: return "BTA_AV_CONNECT_REQ";
case 14: return "BTA_AV_SDP_FAILED";
case 15: return "BTA_AV_DISC_RESULTS";
case 16: return "BTA_AV_DISC_RES_AS_ACP";
case 17: return "BTA_AV_OPEN_FAILED";
case 18: return "BTA_AV_GETCAP_RESULTS";
case 19: return "BTA_AV_SETCONFIG_REJ";
case 20: return "BTA_AV_DISCOVER_REQ";
case 21: return "BTA_AV_CONN_FAILED";
case 22: return "BTA_AV_DO_START";
case 23: return "BTA_AV_STR_STOPPED";
case 24: return "BTA_AV_RECONFIG";
case 25: return "BTA_AV_DATA_PATH";
case 26: return "BTA_AV_START_OK";
case 27: return "BTA_AV_START_FAILED";
case 28: return "BTA_AV_STR_CLOSED";
case 29: return "BTA_AV_CLR_CONG";
case 30: return "BTA_AV_SUSPEND_CFM";
case 31: return "BTA_AV_RCFG_STR_OK";
case 32: return "BTA_AV_RCFG_FAILED";
case 33: return "BTA_AV_RCFG_CONNECT";
case 34: return "BTA_AV_RCFG_DISCNTD";
case 35: return "BTA_AV_SUSPEND_CONT";
case 36: return "BTA_AV_RCFG_CFM";
case 37: return "BTA_AV_RCFG_OPEN";
case 38: return "BTA_AV_SECURITY_REJ";
case 39: return "BTA_AV_OPEN_RC";
case 40: return "BTA_AV_CHK_2ND_START";
case 41: return "BTA_AV_SAVE_CAPS";
case 42: return "BTA_AV_SET_USE_RC";
case 43: return "BTA_AV_CCO_CLOSE";
case 44: return "BTA_AV_SWITCH_ROLE";
case 45: return "BTA_AV_ROLE_RES";
case 46: return "BTA_AV_DELAY_CO";
case 47: return "BTA_AV_OPEN_AT_INC";
case 48: return "BTA_AV_OPEN_FAIL_SDP";
case 49: return "NULL";
default: return "unknown";
}
}
#endif /* BTA_AV_INCLUDED */

View File

@ -355,11 +355,7 @@ static const tBTA_AV_SST_TBL bta_av_sst_tbl[] = {
bta_av_sst_closing
};
#if (defined(BTA_AV_DEBUG) && BTA_AV_DEBUG == TRUE)
static char *bta_av_sst_code(UINT8 state);
#endif
/*******************************************************************************
**
@ -423,12 +419,8 @@ void bta_av_ssm_execute(tBTA_AV_SCB *p_scb, UINT16 event, tBTA_AV_DATA *p_data)
}
}
#if (defined(BTA_AV_DEBUG) && BTA_AV_DEBUG == TRUE)
APPL_TRACE_VERBOSE("AV Sevent(0x%x)=0x%x(%s) state=%d(%s)",
p_scb->hndl, event, bta_av_evt_code(event), p_scb->state, bta_av_sst_code(p_scb->state));
#else
APPL_TRACE_VERBOSE("AV Sevent=0x%x state=%d", event, p_scb->state);
#endif
/* look up the state table for the current state */
state_table = bta_av_sst_tbl[p_scb->state];
@ -441,6 +433,7 @@ void bta_av_ssm_execute(tBTA_AV_SCB *p_scb, UINT16 event, tBTA_AV_DATA *p_data)
/* execute action functions */
for (i = 0; i < BTA_AV_SACTIONS; i++) {
if ((action = state_table[event][i]) != BTA_AV_SIGNORE) {
APPL_TRACE_VERBOSE("AV Sevent(0x%x)=%d(%s)", p_scb->hndl, event, bta_av_action_code(action));
(*p_scb->p_act_tbl[action])(p_scb, p_data);
} else {
break;
@ -555,7 +548,6 @@ void bta_av_set_scb_sst_incoming (tBTA_AV_SCB *p_scb)
/*****************************************************************************
** Debug Functions
*****************************************************************************/
#if (defined(BTA_AV_DEBUG) && BTA_AV_DEBUG == TRUE)
/*******************************************************************************
**
** Function bta_av_sst_code
@ -578,5 +570,4 @@ UNUSED_ATTR static char *bta_av_sst_code(UINT8 state)
}
}
#endif
#endif /* BTA_AV_INCLUDED */

View File

@ -33,7 +33,6 @@
#if (BTA_AV_INCLUDED == TRUE)
#define BTA_AV_DEBUG TRUE
/*****************************************************************************
** Constants
*****************************************************************************/
@ -593,15 +592,16 @@ extern void bta_av_set_scb_sst_incoming (tBTA_AV_SCB *p_scb);
extern tBTA_AV_LCB *bta_av_find_lcb(BD_ADDR addr, UINT8 op);
/* debug functions */
extern char *bta_av_evt_code(UINT16 evt_code);
extern char *bta_av_action_code(UINT16 action_code);
/* main functions */
extern void bta_av_api_deregister(tBTA_AV_DATA *p_data);
extern void bta_av_dup_audio_buf(tBTA_AV_SCB *p_scb, BT_HDR *p_buf);
extern void bta_av_sm_execute(tBTA_AV_CB *p_cb, UINT16 event, tBTA_AV_DATA *p_data);
extern void bta_av_ssm_execute(tBTA_AV_SCB *p_scb, UINT16 event, tBTA_AV_DATA *p_data);
extern BOOLEAN bta_av_hdl_event(BT_HDR *p_msg);
#if (defined(BTA_AV_DEBUG) && BTA_AV_DEBUG == TRUE)
extern char *bta_av_evt_code(UINT16 evt_code);
#endif
extern BOOLEAN bta_av_switch_if_needed(tBTA_AV_SCB *p_scb);
extern BOOLEAN bta_av_link_role_ok(tBTA_AV_SCB *p_scb, UINT8 bits);
extern BOOLEAN bta_av_is_rcfg_sst(tBTA_AV_SCB *p_scb);

View File

@ -304,7 +304,7 @@ esp_err_t esp_bredr_tx_power_set(esp_power_level_t min_power_level, esp_power_le
esp_err_t esp_bredr_tx_power_get(esp_power_level_t *min_power_level, esp_power_level_t *max_power_level);
/**
* @brief set default SCO data path
* @brief Set default SCO data path
* Should be called after controller is enabled, and before (e)SCO link is established
* @param data_path: SCO data path
* @return ESP_OK - success, other - failed

View File

@ -1,17 +1,43 @@
| Supported Targets | ESP32 |
| ----------------- | ----- |
ESP-IDF BT-INQUIRY demo
======================
# ESP-IDF BT-INQUIRY demo
Demo of Classic Bluetooth Device and Service Discovery
This is the demo for user to use ESP_APIs to perform inquiry to search for a target device and then performs service search via SDP.
Options choose step:`
1. `idf.py menuconfig`
2. enter menuconfig `Component config`, choose `Bluetooth`
3. enter menu Bluetooth, choose `Classic Bluetooth` and do not choose `Release DRAM from Classic BT controller`
4. choose your options.
## How to use example
### Hardware Required
This example is designed to run on commonly available ESP32 development board, e.g. ESP32-DevKitC.
### Configure the project
```
idf.py menuconfig
```
### Build and Flash
Build the project and flash it to the board, then run monitor tool to view serial output:
```
idf.py -p PORT flash monitor
```
(Replace PORT with the name of the serial port to use.)
(To exit the serial monitor, type ``Ctrl-]``.)
See the [Getting Started Guide](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/index.html) for full steps to configure and use ESP-IDF to build projects.
## Example Description
After the program started, the device will start inquiry to search for a device with Major device type "PHONE" in the Class of Device Field. Then it will cancel the inquiry and started to perform service discovering on this remote device.
## Trouble shooting
- Some old BT device doesn't place their device name in EIR, but new devices place their device name in EIR. Users can obtain the peer device name in `bt_app_gap_cb` `ESP_BT_GAP_DISC_RES_EVT` event handler or resolve it in EIR just like the function `get_name_from_eir` does.
- ESP32 places its device name in EIR by default.

View File

@ -191,13 +191,16 @@ static void update_device_info(esp_bt_gap_cb_param_t *param)
}
}
void bt_app_gap_init(void)
static void bt_app_gap_init(void)
{
app_gap_cb_t *p_dev = &m_dev_info;
memset(p_dev, 0, sizeof(app_gap_cb_t));
/* start to discover nearby Bluetooth devices */
p_dev->state = APP_GAP_STATE_DEVICE_DISCOVERING;
}
void bt_app_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *param)
static void bt_app_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *param)
{
app_gap_cb_t *p_dev = &m_dev_info;
char bda_str[18];
@ -249,23 +252,20 @@ void bt_app_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *param)
return;
}
void bt_app_gap_start_up(void)
static void bt_app_gap_start_up(void)
{
char *dev_name = "ESP_GAP_INQRUIY";
esp_bt_dev_set_device_name(dev_name);
/* set discoverable and connectable mode, wait to be connected */
esp_bt_gap_set_scan_mode(ESP_BT_CONNECTABLE, ESP_BT_GENERAL_DISCOVERABLE);
/* register GAP callback function */
esp_bt_gap_register_callback(bt_app_gap_cb);
/* inititialize device information and status */
app_gap_cb_t *p_dev = &m_dev_info;
memset(p_dev, 0, sizeof(app_gap_cb_t));
/* set discoverable and connectable mode, wait to be connected */
esp_bt_gap_set_scan_mode(ESP_BT_CONNECTABLE, ESP_BT_GENERAL_DISCOVERABLE);
/* inititialize device information and status */
bt_app_gap_init();
/* start to discover nearby Bluetooth devices */
p_dev->state = APP_GAP_STATE_DEVICE_DISCOVERING;
esp_bt_gap_start_discovery(ESP_BT_INQ_MODE_GENERAL_INQUIRY, 10, 0);
}

View File

@ -0,0 +1,179 @@
# ESP32 Classic Bluetooth Security - Secure Simple Pairing
This document briefly describes how the device io capability and security mask affect the process of the Secure Simple Pairing. It will help you figure out how to set the parameter when calling `esp_bt_gap_set_security_param`, or the parameter `sec_mask` when you want to establish a connection associate a certain profile, for example, an SPP connection.
## IO Capability
Input and output capabilities of a device are combined to generate its IO capabilities. The input capabilities are described in Table 1 The output capabilities are described in Table 2. Table 3 shows the combination of Input and Output Capability, which are defined as `ESP_BT_IO_CAP_OUT`, `ESP_BT_IO_CAP_IO`, `ESP_BT_IO_CAP_IN` and `ESP_BT_IO_CAP_NONE` in `esp_gap_bt_api.h`.
| Input Capability | Description |
| ---------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| No input | Device does not have the ability to indicate 'yes' or 'no' |
| Yes / No | Device has at least two buttons that can be easily mapped to 'yes' and 'no' or the device has a mechanism whereby the user can indicate either 'yes' or 'no' (see note below). |
| Keyboard | Device has a numeric keyboard that can input the numbers '0' through '9' and a confirmation. Device also has two buttons that can be easily mapped to 'yes' and 'no' or the device has a mechanism whereby the user can indicate either 'yes' or 'no' (see Note below). |
*Table 1 User Input Capability*
**Note**: 'yes' could be indicated by pressing a button within a certain time limit otherwise 'no' would be assumed.
| Output Capability | Description |
| ----------------- | ----------------------------------------------------------------------------------- |
| No output | Device does not have the ability to display or communicate a 6 digit decimal number |
| Numeric output | Device has the ability to display or communicate a 6 digit decimal number |
*Table 2 User Output Capability*
| | No Output | Numeric Output |
| -------- | -------------------------------------- | --------------------------------- |
| No input | NoInputNoOutput (`ESP_BT_IO_CAP_NONE`) | DisplayOnly (`ESP_BT_IO_CAP_OUT`) |
| Yes / No | NoInputNoOutput (`ESP_BT_IO_CAP_NONE`) | DisplayYesNo (`ESP_BT_IO_CAP_IO`) |
| Keyboard | KeyboardOnly (`ESP_BT_IO_CAP_IN`) | DisplayYesNo (`ESP_BT_IO_CAP_IO`) |
*Table 3 IO Capability Mapping*
## Secure Simple Pairing
The primary goal of Secure Simple Pairing is to simplify the pairing procedure for the user. Secondary goals are to protect against passive eavesdropping and man-in-the-middle (MITM) attacks (active eavesdropping). It uses four association models referred to as Numeric Comparison, Just Works, Out Of Band, and Passkey Entry.
* Numeric Comparison: both devices are capable of displaying a six digit number and both are capable of having the user enter "yes" or "no"
* Just Works: at least one of the devices does not have a display capable of displaying a six digit number nor does it have a keyboard capable of entering six decimal digits
* Out Of Band: use Out of Band mechanism to discover the devices and transfer cryptographic numbers
* Passkey Entry: one device has input capability but does not have the capability to display six digits and the other device has output capabilities.
**Note**: Just Works can be considered as a special kind of Numeric Comparison with automatic accept allowed.
There are four stages defined in the Secure Simple Pairing LM process:
* IO Capability exchange
* Public key exchange
* Authentication stage 1
* Authentication stage 2
### IO Capability Exchange
The IO_Capability_Request_Reply command is used to reply to an IO Capability Request event from the controller, and specifies the current I/O capabilities of the host. The content of this command is shown as Table 4.
| Command | OCF | Command Parameters | Return Parameters |
| ------------------------------- | ------ | ------------------------------------------------------------------------------ | ------------------ |
| HCI_IO_Capability_Request_Reply | 0x002B | BD_ADDR,<br>IO_Capability,<br>OOB_Data_Present,<br>Authentication_Requirements | Status,<br>BD_ADDR |
*Table 4 IO_Capability_Request_Reply command*
### Authentication Requirements
If an authenticated link key is not required by the Host, the Authentication Requirements parameter may be set to one of the following:
* MITM Protection Not Required No Bonding
* MITM Protection Not Required Dedicated Bonding
* MITM Protection Not Required General Bonding
**Note**: If both Hosts set the Authentication_Requirements parameter to one of the above values, the Link Managers shall use the numeric comparison authentication procedure and the hosts shall use the Just Works Association Model.
If an authenticated link key is required by the Host, the Authentication Requirements parameter shall be set to one of the following:
* MITM Protection Required No Bonding
* MITM Protection Required Dedicated Bonding
* MITM Protection Required General Bonding
**Note**: In addition, the following requirements apply:
1. If one or both hosts set the Authentication Requirements parameter to one of the above values, the Link Managers shall use the IO_Capability parameter to determine the authentication procedure.
2. A Host that sets the Authentication_Requirements parameter to one of the above values shall verify that the resulting Link Key type meets the security requirements requested.
### IO Capability and Authentication Procedure Mapping
If one or both devices have set the Authentication_Requirements parameter to one of the MITM Protection Required options, the IO capabilities are mapped to the authentication method as defined in the following table. A host has set the MITM Protection Required options shall verify that the resulting Link Key is an Authenticated Combination Key.
<table>
<tr>
<th ></th>
<th colspan = "4" bgcolor="#1FB0E6">Responder</th>
</tr>
<tr>
<th bgcolor="#C8E6F8">Initiator</th>
<th bgcolor="#1FB0E6">DisplayOnly</th>
<th bgcolor="#1FB0E6">DisplayYesNo</th>
<th bgcolor="#1FB0E6">KeyboardOnly</th>
<th bgcolor="#1FB0E6">NoInputNoOutput</th>
</tr>
<tr>
<th bgcolor="#C8E6F8">DisplayOnly</th>
<td>Just Works<br><br>Unauthenticated</td>
<td>Just Works<br><br>Unauthenticated</td>
<td>Passkey Entry<br><br>Authenticated</td>
<td>Just Works<br><br>Unauthenticated</td>
</tr>
<tr>
<th bgcolor="#C8E6F8">DisplayYesNo</th>
<td>Just Works<br><br>Unauthenticated</td>
<td>Numeric Comparison<br><br>Authenticated</td>
<td>Passkey Entry<br><br>Authenticated</td>
<td>Just Works<br><br>Unauthenticated</td>
</tr>
<tr>
<th bgcolor="#C8E6F8">KeyboardOnly</th>
<td>Passkey Entry<br><br>Authenticated</td>
<td>Passkey Entry<br><br>Authenticated</td>
<td>Passkey Entry(both need enter)<br><br>Authenticated</td>
<td>Just Works<br><br>Unauthenticated</td>
</tr>
<tr>
<th bgcolor="#C8E6F8">NoInputNoOutput</th>
<td>Just Works<br><br>Unauthenticated</td>
<td>Just Works<br><br>Unauthenticated</td>
<td>Just Works<br><br>Unauthenticated</td>
<td>Just Works<br><br>Unauthenticated</td>
</tr>
</table>
*Table 5 IO Capability and Authentication Procedure Mapping*
## Security Mask
Security Mask has two function. First, to decide whether or not required MITM protection for Authentication_Requirements parameter. Second, to set the security level for authentication stage. On ESP32, the Security Masks for A2DP and HFP are hard coded with `BTA_SEC_AUTHENTICATE` and `(BTA_SEC_AUTHENTICATE|BTA_SEC_ENCRYPT)`. The following table shows `sec_mask` value for SPP and its definition in BTA layer of ESP32 Bluetooth stack.
| SPP sec_mask | BTA layer sec_mask | value | Description |
| -------------------------- | ---------------------- | ------ | ----------------------------------------------------------------------------------------- |
| `ESP_SPP_SEC_NONE` | `BTA_SEC_NONE` | 0x0000 | No security |
| `ESP_SPP_SEC_AUTHORIZE` | `BTA_SEC_AUTHORIZE` | 0x0001 | Authorization required (only needed for out going connection)<br>(not support) |
| `ESP_SPP_SEC_AUTHENTICATE` | `BTA_SEC_AUTHENTICATE` | 0x0012 | Authentication required |
| `ESP_SPP_SEC_ENCRYPT` | `BTA_SEC_ENCRYPT` | 0x0024 | Encryption required |
| `ESP_SPP_SEC_MODE4_LEVEL4` | `BTA_SEC_MODE4_LEVEL4` | 0x0040 | Mode 4 level 4 service, i.e. incoming/outgoing MITM and P-256 encryption<br>(not support) |
| `ESP_SPP_SEC_MITM` | `BTA_SEC_MITM` | 0x3000 | Man-In-The_Middle protection |
| `ESP_SPP_SEC_IN_16_DIGITS` | `BTA_SEC_IN_16_DIGITS` | 0x4000 | Min 16 digit for pin code |
*Table 6 ESP32 SPP Security Mask*
**Note**:
1. When `ESP_SPP_SEC_AUTHENTICATE` is set, then Security Manager set `ESP_SPP_SEC_MITM` automatically.
2. When `ESP_SPP_SEC_ENCRYPT` is set, then Security Manager set `ESP_SPP_SEC_AUTHENTICATE` automatically.
## Security Mode 4
The ESP32 Security Manager supports Security Mode 4 which means that it enforces security requirements before it attempts to access services offered by a remote device and before it grants access to services it offers to remote devices. Security Mode 4 has 4 level of security.
<table>
<tr>
<th width='200'>Security Level Required for Service</th>
<th>Link Key type required for remote devices</th>
<th width='200'>Comments</th>
<th width='200'>IO Capability & Security Mask Setting</th>
</tr>
<tr>
<td><b>Level 4(not support)</b><br>* MITM protection required<br>* Encryption required<br>* User interaction acceptable</td>
<td>Authenticated (P-256 based Secure Simple Pairing and Secure Authentication)</td>
<td>Highest Security Only possible when both devices support Secure Connections</td>
<td>/</td>
</tr>
<tr>
<td><b>Level 3</b><br>* MITM protection required<br>* Encryption required<br>* User interaction acceptable</td>
<td>Authenticated</td>
<td>High Security</td>
<td>IO: >= DisplayYesNo <br>Mask: ESP_SPP_SEC_MITM | BTA_SEC_ENCRYPT</td>
</tr>
<tr>
<td><b>Level 2</b><br>* MITM protection not necessary<br>* Encryption desired</td>
<td>Unauthenticated</td>
<td>Medium Security</td>
<td>IO: >= DisplayYesNo <br>Mask: BTA_SEC_ENCRYPT</td>
</tr>
<tr>
<td><b>Level 1</b><br>* MITM protection not necessary<br>* Encryption desired<br>* Minimal user interaction desired</td>
<td>Unauthenticated</td>
<td>Low Security</td>
<td>IO: >= NoInputNoOutput <br>Mask: BTA_SEC_ENCRYPT</td>
</tr>
<tr>
<td><b>Level 0</b><br>* MITM protection not necessary<br>* Encryption not necessary<br>* No user interaction desired</td>
<td>None</td>
<td>Permitted only for SDP and service data sent via either L2CAP fixed signaling channels or the L2CAP connectionless channel to PSMs that correspond to service class UUIDs which are allowed to utilize Level 0.</td>
<td>/</td>
</tr>
</table>
*Table 7 Security Mode 4 Security Level mapping to link key requirements*
**Note**: Security Mode 4 always requires **authentication** and **encryption** over establishment of L2CAP connection on ESP32.
ESP32 Secure Simple Pairing performs legacy authentication which means mutual authentication is achieved by first performing the authentication procedure in one direction and then immediately performing the authentication procedure in the opposite direction. So, when the initiator does not require MITM protection, the generated link key type in this direction is unauthenticated. In other direction, if the responder need MITM protection and have the `sec_mask` of `ESP_SPP_SEC_AUTHENTICATE`, then the unauthenticated link key will be regenerated and upgraded to an authenticated one. Each time the link key is regenerated, user will receive a `ESP_BT_GAP_AUTH_CMPL_EVT` event.

View File

@ -1,19 +1,46 @@
| Supported Targets | ESP32 |
| ----------------- | ----- |
ESP-IDF BT-SPP-ACCEPTOR demo
======================
## ESP-IDF BT-SPP-ACCEPTOR demo
Demo of SPP acceptor role
This is the demo for user to use ESP_APIs to create a **Serial Port Protocol** (**SPP**) acceptor and we aggregate **Secure Simple Pair** (**SSP**) into this demo to show how to use SPP when creating your own APPs.
This is the demo for user to use ESP_APIs to create a SPP acceptor.
## How to use example
Options choose step:
1. `idf.py menuconfig`
2. enter menuconfig `Component config`, choose `Bluetooth`
3. enter menu Bluetooth, choose `Classic Bluetooth" and "SPP Profile`
4. choose your options.
### Hardware Required
Then set `SPP_SHOW_MODE` as `SPP_SHOW_DATA` or `SPP_SHOW_SPEED` in code(should be same with bt_spp_initator).
This example is designed to run on commonly available ESP32 development board, e.g. ESP32-DevKitC.
After the program started, bt_spp_initator will connect it and send data.
To operate it should be connected to an SPP Initiator running on a smartphone or on another ESP32 development board.
### Configure the project
```
idf.py menuconfig
```
### Build and Flash
Build the project and flash it to the board, then run monitor tool to view serial output:
```
idf.py -p PORT flash monitor
```
(Replace PORT with the name of the serial port to use.)
(To exit the serial monitor, type ``Ctrl-]``.)
See the [Getting Started Guide](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/index.html) for full steps to configure and use ESP-IDF to build projects.
## Example Description
After the program started, `bt_spp_initator` will connect it and send data.
## Trouble shooting
- Acceptor is expected to start before `bt_spp_initator` start.
- To see the information of data, users shall set `SPP_SHOW_MODE` as `SPP_SHOW_DATA` or `SPP_SHOW_SPEED` in code(should be same with `bt_spp_initator`).
- We also show the Security Simple Pair in this SPP demo. Users can set the IO Capability and Security Mode for their device (security level is fixed level 4). The default security mode of this demo is `ESP_SPP_SEC_AUTHENTICATE` which support MITM (Man In The Middle) protection. For more information about Security Simple Pair on ESP32, please refer to [ESP32_SSP](./ESP32_SSP.md).

View File

@ -1,20 +1,121 @@
| Supported Targets | ESP32 |
| ----------------- | ----- |
# ESP-IDF BT-SPP-INITATOR demo
ESP-IDF BT-SPP-INITATOR demo
======================
This is the demo for user to use ESP_APIs to create a **Serial Port Protocol** (**SPP**) initiator and we aggregate **Secure Simple Pair** (**SSP**) into this demo to show how to use SPP when creating your own APPs.
Demo of SPP initator role
## How to use example
This is the demo for user to use ESP_APIs to create a SPP initator.
### Hardware Required
Options choose step:
1. `idf.py menuconfig`
2. enter menuconfig `Component config`, choose `Bluetooth`
3. enter menu Bluetooth, choose `Classic Bluetooth` and `SPP Profile`
4. choose your options.
This example is designed to run on commonly available ESP32 development board, e.g. ESP32-DevKitC. To operate it should be connected to an SPP Acceptor running on another device.
Then set `SPP_SHOW_MODE` as `SPP_SHOW_DATA` or `SPP_SHOW_SPEED` in code(should be same with bt_spp_acceptor).
### Configure the project
After the program started, It will connect to bt_spp_acceptor and send data.
```
idf.py menuconfig
```
In `menuconfig` path: `Coponent config --> Bluetooth--> Bluedroid Options -->SPP` and `Coponent config --> Bluetooth--> Bluedroid Options -->Secure Simple Pair`.
### Build and Flash
Build the project and flash it to the board, then run monitor tool to view serial output:
```
idf.py -p PORT flash monitor
```
(Replace PORT with the name of the serial port to use.)
(To exit the serial monitor, type ``Ctrl-]``.)
See the [Getting Started Guide](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/index.html) for full steps to configure and use ESP-IDF to build projects.
### Example Output
When you run this example and the IO capability is `ESP_IO_CAP_IO` or `ESP_IO_CAP_IN` , the commands help table prints the following at the very beginning:
```
########################################################################
Supported commands are as follows, arguments are embraced with < and >
spp h; -- show command manual
Use this cmmand table if the IO Capability of local device set as IO_CAP_IO.
spp ok; -- manual Numeric Confirmation.
Use this cmmand table if the IO Capability of local device set as IO_CAP_IN.
spp key <auth key>; -- manual Passkey. (e.g. spp key 136245;)
########################################################################
```
**Note:**
- Only after SPP service is initialized and a service level connection exists between an Initiator and Acceptor device, could other commands be available.
- This command help table will print out in monitor whenever you type `spp h;` or if you input a command that is not required by the command parse rule.
- Commands should always start with `spp` and end with `;` or the example will not responds.
- The command you typed will not echo in monitor.
### Situation under `ESP_IO_CAP_IN`
The log in terminal will indicate you to input the passkey to initiate the connection of SPP.
```
I (2244) SPP_INITIATOR_DEMO: ESP_BT_GAP_DISC_RES_EVT
I (2244) SPP_INITIATOR_DEMO: ......
I (2394) SPP_INITIATOR_DEMO: ESP_BT_GAP_DISC_RES_EVT
I (2404) SPP_INITIATOR_DEMO: ......
I (2404) SPP_INITIATOR_DEMO: ESP_SPP_ACCEPTOR
I (2414) SPP_INITIATOR_DEMO: ESP_BT_GAP_DISC_STATE_CHANGED_EVT
I (3274) SPP_INITIATOR_DEMO: ESP_SPP_DISCOVERY_COMP_EVT status=0 scn_num=1
I (3284) SPP_INITIATOR_DEMO: ESP_SPP_CL_INIT_EVT
I (3454) SPP_INITIATOR_DEMO: ESP_BT_GAP_KEY_REQ_EVT Please enter passkey!
W (3454) SPP_INITIATOR_DEMO: To input the key, type `spp key xxxxxx;`
```
### Situation under `ESP_IO_CAP_IO`
The log in terminal will indicate you to confirm the number to initiate the connection of SPP.
```
I (2342) SPP_INITIATOR_DEMO: ESP_BT_GAP_DISC_RES_EVT
I (2342) SPP_INITIATOR_DEMO: 30 ae a4 80 18 32
I (2342) SPP_INITIATOR_DEMO: ESP_SPP_ACCEPTOR
I (2352) SPP_INITIATOR_DEMO: ESP_BT_GAP_DISC_STATE_CHANGED_EVT
I (3212) SPP_INITIATOR_DEMO: ESP_SPP_DISCOVERY_COMP_EVT status=0 scn_num=1
I (3222) SPP_INITIATOR_DEMO: ESP_SPP_CL_INIT_EVT
I (3392) SPP_INITIATOR_DEMO: ESP_BT_GAP_CFM_REQ_EVT Please compare the numeric value: 864115
W (3392) SPP_INITIATOR_DEMO: To confirm the value, type `spp ok;`
```
**Note:**
Whether you should passkey or confirm the number also depends on the IO capability of the peer device. And whether the two device are already paired before.
## Troubleshouting
- Set `SPP_SHOW_MODE` as `SPP_SHOW_DATA` or `SPP_SHOW_SPEED` in code (should be same with bt_spp_acceptor).
- After the program started, It will connect to bt_spp_acceptor and send data.
- We haven't do the same update to `bt_acceptor_demo` for the sake of reducing the size of ESP_IDF, but transplanting of input module is supported.
- We also show the Security Simple Pair in this SPP demo. Users can set the IO Capability and Security Mode for their device (security level is fixed level 4). The default security mode of this demo is `ESP_SPP_SEC_AUTHENTICATE` which support MITM (Man In The Middle) protection. For more information about Security Simple Pair on ESP32, please refer to [ESP32_SSP](../bt_spp_acceptor/ESP32_SSP.md).
## Example Breakdown
To clearly show how the SSP aggregate with the SPP , we use the Commands and Effects scheme to illustrate the process of secure paring and connection establishment.
- The example will respond to user command through UART console. Please go to `console_uart.c` for the configuration details.
- If you want to update the command table, please refer to `app_spp_msg_set.c`.
- If you want to update the command parse rules, please refer to `app_spp_msg_prs.c`.
- If you want to update the responses of HF Unit or want to update the log, please refer to `bt_app_spp.c`.
- Task configuration part is in `example_spp_initiator_demo.c`.

View File

@ -1,2 +1,5 @@
idf_component_register(SRCS "example_spp_initiator_demo.c"
SRCS "app_spp_msg_prs.c"
SRCS "app_spp_msg_set.c"
SRCS "console_uart.c"
INCLUDE_DIRS ".")

View File

@ -0,0 +1,164 @@
/*
This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
#include <ctype.h>
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <stdlib.h>
#include "app_spp_msg_prs.h"
#include "app_spp_msg_set.h"
#define SPP_MSG_HDR_LEN (4)
const static char spp_msg_hdr[SPP_MSG_HDR_LEN] = {'s', 'p', 'p', ' '};
#define SPP_MSG_TAIL_LEN (1)
const static char spp_msg_tail[SPP_MSG_TAIL_LEN] = {';'};
void spp_msg_parser_reset_state(spp_msg_prs_cb_t *prs)
{
prs->state = SPP_MSG_PRS_IDLE;
prs->cnt = 0;
prs->h_idx = 0;
prs->t_idx = 0;
}
void spp_msg_parser_register_callback(spp_msg_prs_cb_t *prs, spp_msg_callback cb)
{
prs->callback = cb;
}
spp_msg_prs_err_t spp_msg_parse(char c, spp_msg_prs_cb_t *prs)
{
spp_msg_prs_err_t err = SPP_MSG_PRS_ERR_IN_PROGRESS;
switch (prs->state) {
case SPP_MSG_PRS_IDLE:
{
if (c == spp_msg_hdr[0]) {
prs->state = SPP_MSG_PRS_HDR;
prs->buf[0] = c;
prs->cnt = 1;
prs->h_idx = 1;
} else {
err = SPP_MSG_PRS_ERR_HDR_UNDETECTED;
}
break;
}
case SPP_MSG_PRS_HDR:
{
if (c == spp_msg_hdr[prs->h_idx]) {
prs->buf[prs->cnt++] = c;
if (++(prs->h_idx) == SPP_MSG_HDR_LEN) {
prs->state = SPP_MSG_PRS_PAYL;
prs->t_idx = 0;
}
} else {
spp_msg_parser_reset_state(prs);
err = SPP_MSG_PRS_ERR_HDR_SYNC_FAILED;
}
break;
}
case SPP_MSG_PRS_PAYL:
{
prs->buf[prs->cnt++] = c;
if (c == spp_msg_tail[prs->t_idx]) {
if (++(prs->t_idx) == SPP_MSG_TAIL_LEN) {
prs->buf[prs->cnt] = '\0';
prs->callback(prs->buf, prs->cnt);
spp_msg_parser_reset_state(prs);
err = SPP_MSG_PRS_ERR_OK;
break;
}
} else {
prs->t_idx = 0;
}
if (prs->cnt >= SPP_MSG_LEN_MAX-1) {
spp_msg_parser_reset_state(prs);
err = SPP_MSG_PRS_ERR_BUF_OVERFLOW;
}
break;
}
}
return err;
}
void spp_msg_split_args(char *start, char *end, char **argv, int *argn)
{
if (argn == NULL || *argn == 0) {
return;
}
memset(argv, 0, (*argn) * sizeof(void *));
int max_argn = *argn;
*argn = 0;
char *p = start;
for (int i = 0; i < max_argn; ++i) {
while (isspace((int)*p) && p != end) {
++p;
}
if (p == end) {
return;
}
argv[i] = p++;
++(*argn);
while (!isspace((int)*p) && p != end) {
++p;
}
if (p == end) {
return;
} else {
*p = '\0';
++p;
}
}
}
void spp_msg_args_parser(char *buf, int len)
{
char *argv[SPP_MSG_ARGS_MAX];
int argn = SPP_MSG_ARGS_MAX;
char *start = buf + SPP_MSG_HDR_LEN;
// set the command terminator to '\0'
char *end = buf + len - SPP_MSG_TAIL_LEN;
*end = '\0';
spp_msg_split_args(start, end, argv, &argn);
if (argn == 0) {
return;
}
bool cmd_supported = false;
spp_msg_hdl_t *cmd_tbl = spp_get_cmd_tbl();
size_t cmd_tbl_size = spp_get_cmd_tbl_size();
for (int i = 0; i < cmd_tbl_size; ++i) {
spp_msg_hdl_t *hdl = &cmd_tbl[i];
if (strcmp(argv[0], hdl->str) == 0) {
if (hdl->handler) {
hdl->handler(argn, argv);
cmd_supported = true;
break;
}
}
}
if (!cmd_supported) {
printf("unsupported command\n");
spp_msg_show_usage();
}
return;
}

View File

@ -0,0 +1,47 @@
/*
This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
#ifndef __APP_SPP_MSG_PRS_H__
#define __APP_SPP_MSG_PRS_H__
typedef enum {
SPP_MSG_PRS_ERR_OK = 0, // a complete message is finished
SPP_MSG_PRS_ERR_IN_PROGRESS, // message parsing is in progress
SPP_MSG_PRS_ERR_HDR_UNDETECTED, // header not detected
SPP_MSG_PRS_ERR_HDR_SYNC_FAILED, // failed to sync header
SPP_MSG_PRS_ERR_BUF_OVERFLOW, // exceeds the buffer size: SPP_MSG_LEN_MAX
} spp_msg_prs_err_t;
typedef enum {
SPP_MSG_PRS_IDLE = 0,
SPP_MSG_PRS_HDR,
SPP_MSG_PRS_PAYL,
} spp_msg_prs_state_t;
typedef void (*spp_msg_callback)(char *buf, int len);
#define SPP_MSG_LEN_MAX (128)
typedef struct {
spp_msg_prs_state_t state;
char buf[SPP_MSG_LEN_MAX + 1];
int cnt;
int h_idx;
int t_idx;
spp_msg_callback callback;
} spp_msg_prs_cb_t;
void spp_msg_parser_reset_state(spp_msg_prs_cb_t *prs);
void spp_msg_parser_register_callback(spp_msg_prs_cb_t *prs, spp_msg_callback cb);
spp_msg_prs_err_t spp_msg_parse(char c, spp_msg_prs_cb_t *prs);
void spp_msg_show_usage(void);
#endif /* __APP_SPP_MSG_PRS_H__*/

View File

@ -0,0 +1,68 @@
/*
This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
#include <stdio.h>
# include <stdlib.h>
#include <string.h>
#include "esp_spp_api.h"
#include "esp_gap_bt_api.h"
#include "app_spp_msg_set.h"
extern esp_bd_addr_t peer_bd_addr;
void spp_msg_show_usage(void)
{
printf("########################################################################\n");
printf("Supported commands are as follows, arguments are embraced with < and >\n");
printf("spp h; -- show command manual\n\n");
printf("Use this cmmand table if the IO Capability of local device set as IO_CAP_IO.\n");
printf("spp ok; -- manual Numeric Confirmation.\n\n");
printf("Use this cmmand table if the IO Capability of local device set as IO_CAP_IN.\n");
printf("spp key <auth key>; -- manual Passkey. (e.g. spp key 136245;)\n\n");
printf("########################################################################\n");
}
#define SPP_CMD_HANDLER(cmd) static void spp_##cmd##_handler(int argn, char **argv)
SPP_CMD_HANDLER(help)
{
spp_msg_show_usage();
}
SPP_CMD_HANDLER(ok)
{
esp_bt_gap_ssp_confirm_reply(peer_bd_addr, true);
}
SPP_CMD_HANDLER(key)
{
if (argn != 2) {
printf("Insufficient number of arguments");
} else {
printf("Input Paring Key: %s\n", argv[1]);
int passkey = atoi(argv[1]);
esp_bt_gap_ssp_passkey_reply(peer_bd_addr, true, passkey);
}
}
static spp_msg_hdl_t spp_cmd_tbl[] = {
{0, "h", spp_help_handler},
{5, "ok", spp_ok_handler},
{10, "key", spp_key_handler},
};
spp_msg_hdl_t *spp_get_cmd_tbl(void)
{
return spp_cmd_tbl;
}
size_t spp_get_cmd_tbl_size(void)
{
return sizeof(spp_cmd_tbl) / sizeof(spp_msg_hdl_t);
}

View File

@ -0,0 +1,26 @@
/*
This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
#ifndef __APP_SPP_MSG_SET_H__
#define __APP_SPP_MSG_SET_H__
#define SPP_MSG_ARGS_MAX (5)
typedef void (* spp_cmd_handler)(int argn, char **argv);
typedef struct {
uint16_t opcode;
const char *str;
spp_cmd_handler handler;
} spp_msg_hdl_t;
extern spp_msg_hdl_t *spp_get_cmd_tbl(void);
extern size_t spp_get_cmd_tbl_size(void);
void spp_msg_show_usage(void);
#endif /* __APP_SPP_MSG_SET_H__*/

View File

@ -0,0 +1,119 @@
/*
This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
#include "driver/uart.h"
#include "freertos/xtensa_api.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "esp_log.h"
#include "console_uart.h"
#include "app_spp_msg_prs.h"
#define CONSOLE_UART_NUM UART_NUM_0
static QueueHandle_t uart_queue;
static spp_msg_prs_cb_t spp_msg_parser;
static const uart_config_t uart_cfg = {
.baud_rate = 115200, //1.5M
.data_bits = UART_DATA_8_BITS,
.parity = UART_PARITY_DISABLE,
.stop_bits = UART_STOP_BITS_1,
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
.rx_flow_ctrl_thresh = 127,
};
extern void spp_msg_args_parser(char *buf, int len);
void spp_msg_handler(char *buf, int len)
{
ESP_LOGE(TAG_CNSL, "Command [%s]", buf);
spp_msg_args_parser(buf, len);
}
static void console_uart_task(void *pvParameters)
{
int len;
uart_event_t event;
spp_msg_prs_cb_t *parser = &spp_msg_parser;
spp_msg_parser_reset_state(parser);
spp_msg_parser_register_callback(parser, spp_msg_handler);
spp_msg_show_usage();
#define TMP_BUF_LEN 128
uint8_t tmp_buf[128] = {0};
for (;;) {
//Waiting for UART event.
if (xQueueReceive(uart_queue, (void * )&event, (portTickType)portMAX_DELAY)) {
switch (event.type) {
//Event of UART receving data
case UART_DATA:
{
len = uart_read_bytes(CONSOLE_UART_NUM, tmp_buf, TMP_BUF_LEN, 0);
for (int i = 0; i < len; i++) {
spp_msg_parse(tmp_buf[i], parser);
}
break;
}
//Event of HW FIFO overflow detected
case UART_FIFO_OVF:
{
ESP_LOGI(TAG_CNSL, "hw fifo overflow");
break;
}
//Event of UART ring buffer full
case UART_BUFFER_FULL:
{
ESP_LOGI(TAG_CNSL, "ring buffer full");
break;
}
//Event of UART RX break detected
case UART_BREAK:
{
ESP_LOGI(TAG_CNSL, "uart rx break");
break;
}
//Event of UART parity check error
case UART_PARITY_ERR:
{
ESP_LOGI(TAG_CNSL, "uart parity error");
break;
}
//Event of UART frame error
case UART_FRAME_ERR:
{
ESP_LOGI(TAG_CNSL, "uart frame error");
break;
}
//Others
default:
break;
}
}
}
vTaskDelete(NULL);
}
esp_err_t console_uart_init(void)
{
esp_err_t ret;
ret = uart_param_config(CONSOLE_UART_NUM, &uart_cfg);
if (ret != ESP_OK) {
ESP_LOGE(TAG_CNSL, "Uart %d initialize err %04x", CONSOLE_UART_NUM, ret);
return ret;
}
uart_set_pin(CONSOLE_UART_NUM, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
uart_driver_install(CONSOLE_UART_NUM, 1024, 1024, 8, &uart_queue, 0);
xTaskCreate(console_uart_task, "uTask", 2048, NULL, 8, NULL);
return ESP_OK;
}

View File

@ -0,0 +1,19 @@
/*
This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
#ifndef __CONSOLE_UART_H__
#define __CONSOLE_UART_H__
#define TAG_CNSL "CNSL"
/**
* @brief configure uart console for command input and process
*/
esp_err_t console_uart_init(void);
#endif /* __CONSOLE_UART_H__ */

View File

@ -20,6 +20,7 @@
#include "esp_gap_bt_api.h"
#include "esp_bt_device.h"
#include "esp_spp_api.h"
#include "console_uart.h"
#include "time.h"
#include "sys/time.h"
@ -39,7 +40,7 @@ static long data_num = 0;
static const esp_spp_sec_t sec_mask = ESP_SPP_SEC_AUTHENTICATE;
static const esp_spp_role_t role_master = ESP_SPP_ROLE_MASTER;
static esp_bd_addr_t peer_bd_addr;
esp_bd_addr_t peer_bd_addr = {0};
static uint8_t peer_bdname_len;
static char peer_bdname[ESP_BT_GAP_MAX_BDNAME_LEN + 1];
static const char remote_device_name[] = "ESP_SPP_ACCEPTOR";
@ -223,13 +224,15 @@ static void esp_bt_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *pa
#if (CONFIG_BT_SSP_ENABLED == true)
case ESP_BT_GAP_CFM_REQ_EVT:
ESP_LOGI(SPP_TAG, "ESP_BT_GAP_CFM_REQ_EVT Please compare the numeric value: %d", param->cfm_req.num_val);
esp_bt_gap_ssp_confirm_reply(param->cfm_req.bda, true);
ESP_LOGW(SPP_TAG, "To confirm the value, type `spp ok;`");
break;
case ESP_BT_GAP_KEY_NOTIF_EVT:
ESP_LOGI(SPP_TAG, "ESP_BT_GAP_KEY_NOTIF_EVT passkey:%d", param->key_notif.passkey);
ESP_LOGW(SPP_TAG, "Waiting responce...");
break;
case ESP_BT_GAP_KEY_REQ_EVT:
ESP_LOGI(SPP_TAG, "ESP_BT_GAP_KEY_REQ_EVT Please enter passkey!");
ESP_LOGW(SPP_TAG, "To input the key, type `spp key xxxxxx;`");
break;
#endif
@ -296,8 +299,11 @@ void app_main(void)
#if (CONFIG_BT_SSP_ENABLED == true)
/* Set default parameters for Secure Simple Pairing */
esp_bt_sp_param_t param_type = ESP_BT_SP_IOCAP_MODE;
esp_bt_io_cap_t iocap = ESP_BT_IO_CAP_IO;
esp_bt_io_cap_t iocap = ESP_BT_IO_CAP_IN;
esp_bt_gap_set_security_param(param_type, &iocap, sizeof(uint8_t));
if (iocap == ESP_BT_IO_CAP_IN || iocap == ESP_BT_IO_CAP_IO) {
console_uart_init();
}
#endif
/*