diff --git a/components/bt/bluedroid/api/esp_gap_bt_api.c b/components/bt/bluedroid/api/esp_gap_bt_api.c index 49302d0233..5c9f132349 100644 --- a/components/bt/bluedroid/api/esp_gap_bt_api.c +++ b/components/bt/bluedroid/api/esp_gap_bt_api.c @@ -141,4 +141,41 @@ uint8_t *esp_bt_gap_resolve_eir_data(uint8_t *eir, esp_bt_eir_type_t type, uint8 return BTM_CheckEirData(eir, type, length); } + +esp_err_t esp_bt_gap_set_cod(esp_bt_cod_t cod, esp_bt_cod_mode_t mode) +{ + btc_msg_t msg; + btc_gap_bt_args_t arg; + + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + switch (mode) { + case ESP_BT_SET_COD_MAJOR_MINOR: + case ESP_BT_SET_COD_SERVICE_CLASS: + case ESP_BT_CLR_COD_SERVICE_CLASS: + case ESP_BT_SET_COD_ALL: + case ESP_BT_INIT_COD: + break; + default: + return ESP_ERR_INVALID_ARG; + break; + } + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BT; + msg.act = BTC_GAP_BT_ACT_SET_COD; + + arg.set_cod.mode = mode; + memcpy(&arg.set_cod.cod, &cod, sizeof(esp_bt_cod_t)); + return (btc_transfer_context(&msg, &arg, sizeof(btc_gap_bt_args_t), NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + + +esp_err_t esp_bt_gap_get_cod(esp_bt_cod_t *cod) +{ + return btc_gap_bt_get_cod(cod); +} + #endif /* #if BTC_GAP_BT_INCLUDED == TRUE */ diff --git a/components/bt/bluedroid/api/include/esp_gap_bt_api.h b/components/bt/bluedroid/api/include/esp_gap_bt_api.h index d61e3ce967..5df259460d 100644 --- a/components/bt/bluedroid/api/include/esp_gap_bt_api.h +++ b/components/bt/bluedroid/api/include/esp_gap_bt_api.h @@ -23,6 +23,23 @@ extern "C" { #endif +/// Class of device +typedef struct { + uint32_t reserved_2: 2; /*!< undefined */ + uint32_t minor: 6; /*!< minor class */ + uint32_t major: 5; /*!< major class */ + uint32_t service: 11; /*!< service class */ + uint32_t reserved_8: 8; /*!< undefined */ +} esp_bt_cod_t; + +/// class of device settings +typedef enum { + ESP_BT_SET_COD_MAJOR_MINOR = 0x01, /*!< overwrite major, minor class */ + ESP_BT_SET_COD_SERVICE_CLASS = 0x02, /*!< set the bits in the input, the current bit will remain */ + ESP_BT_CLR_COD_SERVICE_CLASS = 0x04, /*!< clear the bits in the input, others will remain */ + ESP_BT_SET_COD_ALL = 0x08, /*!< overwrite major, minor, set the bits in service class */ + ESP_BT_INIT_COD = 0x0a, /*!< overwrite major, minor, and service class */ +} esp_bt_cod_mode_t; /// Discoverability and Connectability mode typedef enum { @@ -174,6 +191,7 @@ typedef union { esp_bd_addr_t bda; /*!< remote bluetooth device address*/ esp_bt_status_t stat; /*!< service search status */ } rmt_srvc_rec; /*!< specific service record from remote device parameter struct */ + } esp_bt_gap_cb_param_t; /** @@ -258,7 +276,7 @@ esp_err_t esp_bt_gap_register_callback(esp_bt_gap_cb_t callback); * @return * - ESP_OK : Succeed * - ESP_ERR_INVALID_ARG: if argument invalid - * - ESP_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled * - ESP_FAIL: others */ esp_err_t esp_bt_gap_set_scan_mode(esp_bt_scan_mode_t mode); @@ -274,7 +292,7 @@ esp_err_t esp_bt_gap_set_scan_mode(esp_bt_scan_mode_t mode); * * @return * - ESP_OK : Succeed - * - ESP_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled * - ESP_ERR_INVALID_ARG: if invalid parameters are provided * - ESP_FAIL: others */ @@ -286,7 +304,7 @@ esp_err_t esp_bt_gap_start_discovery(esp_bt_inq_mode_t mode, uint8_t inq_len, ui * * @return * - ESP_OK : Succeed - * - ESP_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled * - ESP_FAIL: others */ esp_err_t esp_bt_gap_cancel_discovery(void); @@ -297,7 +315,7 @@ esp_err_t esp_bt_gap_cancel_discovery(void); * * @return * - ESP_OK : Succeed - * - ESP_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled * - ESP_FAIL: others */ esp_err_t esp_bt_gap_get_remote_services(esp_bd_addr_t remote_bda); @@ -309,7 +327,7 @@ esp_err_t esp_bt_gap_get_remote_services(esp_bd_addr_t remote_bda); * esp_bt_gap_cb_t will is called with ESP_BT_GAP_RMT_SRVC_REC_EVT after service discovery ends * @return * - ESP_OK : Succeed - * - ESP_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled * - ESP_FAIL: others */ esp_err_t esp_bt_gap_get_remote_service_record(esp_bd_addr_t remote_bda, esp_bt_uuid_t *uuid); @@ -326,6 +344,34 @@ esp_err_t esp_bt_gap_get_remote_service_record(esp_bd_addr_t remote_bda, esp_bt_ */ uint8_t *esp_bt_gap_resolve_eir_data(uint8_t *eir, esp_bt_eir_type_t type, uint8_t *length); +/** + * @brief This function is called to set class of device. + * esp_bt_gap_cb_t will is 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 + * + * @return + * - ESP_OK : Succeed + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_ERR_INVALID_ARG: if param is invalid + * - ESP_FAIL: others + */ +esp_err_t esp_bt_gap_set_cod(esp_bt_cod_t cod, esp_bt_cod_mode_t mode); + +/** + * @brief This function is called to get class of device. + * + * @param[out] cod - class of device + * + * @return + * - ESP_OK : Succeed + * - ESP_FAIL: others + */ +esp_err_t esp_bt_gap_get_cod(esp_bt_cod_t *cod); + #ifdef __cplusplus } #endif diff --git a/components/bt/bluedroid/bta/include/utl.h b/components/bt/bluedroid/bta/include/utl.h index eab971e7dc..74653c26e0 100644 --- a/components/bt/bluedroid/bta/include/utl.h +++ b/components/bt/bluedroid/bta/include/utl.h @@ -136,6 +136,21 @@ extern void utl_freebuf(void **p); *******************************************************************************/ extern BOOLEAN utl_set_device_class(tBTA_UTL_COD *p_cod, UINT8 cmd); +/******************************************************************************* +** +** Function utl_get_device_class +** +** Description This function get the local Device Class. +** +** Parameters: +** p_cod - Pointer to the device class to get to +** +** +** Returns TRUE if successful, Otherwise FALSE +** +*******************************************************************************/ +extern BOOLEAN utl_get_device_class(tBTA_UTL_COD *p_cod); + /******************************************************************************* ** ** Function utl_isintstr diff --git a/components/bt/bluedroid/bta/sys/utl.c b/components/bt/bluedroid/bta/sys/utl.c index d464086ad6..c0b7bcd8b5 100644 --- a/components/bt/bluedroid/bta/sys/utl.c +++ b/components/bt/bluedroid/bta/sys/utl.c @@ -235,6 +235,37 @@ BOOLEAN utl_set_device_class(tBTA_UTL_COD *p_cod, UINT8 cmd) return FALSE; } +/******************************************************************************* +** +** Function utl_get_device_class +** +** Description This function get the local Device Class. +** +** Parameters: +** p_cod - Pointer to the device class to get to +** +** +** Returns TRUE if successful, Otherwise FALSE +** +*******************************************************************************/ +BOOLEAN utl_get_device_class(tBTA_UTL_COD *p_cod) +{ + UINT8 *dev; + UINT16 service; + UINT8 minor, major; + + dev = BTM_ReadDeviceClass(); + BTM_COD_SERVICE_CLASS( service, dev ); + BTM_COD_MINOR_CLASS(minor, dev ); + BTM_COD_MAJOR_CLASS(major, dev ); + + p_cod->minor = minor; + p_cod->major = major; + p_cod->service = service; + + return TRUE; +} + /******************************************************************************* ** ** Function utl_isintstr diff --git a/components/bt/bluedroid/btc/profile/std/gap/btc_gap_bt.c b/components/bt/bluedroid/btc/profile/std/gap/btc_gap_bt.c index 2a972089e2..aef3e10ded 100644 --- a/components/bt/bluedroid/btc/profile/std/gap/btc_gap_bt.c +++ b/components/bt/bluedroid/btc/profile/std/gap/btc_gap_bt.c @@ -567,6 +567,33 @@ static void search_services_copy_cb(btc_msg_t *msg, void *p_dest, void *p_src) } } +static void btc_gap_bt_set_cod(btc_gap_bt_args_t *arg) +{ + tBTA_UTL_COD p_cod; + esp_bt_cod_t *cod = &(arg->set_cod.cod); + p_cod.minor = cod->minor << 2; + p_cod.major = cod->major; + p_cod.service = cod->service << 5; + bool ret = utl_set_device_class(&p_cod, arg->set_cod.mode); + if (!ret){ + LOG_ERROR("%s set class of device failed!",__func__); + } +} + +esp_err_t btc_gap_bt_get_cod(esp_bt_cod_t *cod) +{ + tBTA_UTL_COD p_cod; + bool ret = utl_get_device_class(&p_cod); + if (!ret){ + LOG_ERROR("%s get class of device failed!",__func__); + return ESP_BT_STATUS_FAIL; + } + cod->minor = p_cod.minor >> 2; + cod->major = p_cod.major; + cod->service = p_cod.service >> 5; + return ESP_BT_STATUS_SUCCESS; +} + void btc_gap_bt_call_handler(btc_msg_t *msg) { btc_gap_bt_args_t *arg = (btc_gap_bt_args_t *)msg->arg; @@ -604,6 +631,10 @@ void btc_gap_bt_call_handler(btc_msg_t *msg) btc_gap_bt_search_service_record(msg->aid, msg->arg); break; } + case BTC_GAP_BT_ACT_SET_COD: { + btc_gap_bt_set_cod(msg->arg); + break; + } default: break; } diff --git a/components/bt/bluedroid/btc/profile/std/include/btc_gap_bt.h b/components/bt/bluedroid/btc/profile/std/include/btc_gap_bt.h index 01b0709652..440fb4e053 100644 --- a/components/bt/bluedroid/btc/profile/std/include/btc_gap_bt.h +++ b/components/bt/bluedroid/btc/profile/std/include/btc_gap_bt.h @@ -19,6 +19,7 @@ #include "esp_bt_defs.h" #include "esp_gap_bt_api.h" #include "btc_task.h" +#include "utl.h" #if (BTC_GAP_BT_INCLUDED == TRUE) @@ -32,6 +33,7 @@ typedef enum { BTC_GAP_BT_ACT_SEARCH_SERVICES, BTC_GAP_BT_ACT_GET_REMOTE_SERVICE_RECORD, BTC_GAP_BT_ACT_SEARCH_SERVICE_RECORD, + BTC_GAP_BT_ACT_SET_COD, } btc_gap_bt_act_t; /* btc_bt_gap_args_t */ @@ -56,12 +58,20 @@ typedef union { bt_bdaddr_t bda; esp_bt_uuid_t uuid; } get_rmt_srv_rcd; + + // BTC_GAP_BT_ACT_SET_COD + struct set_cod_args { + esp_bt_cod_t cod; + esp_bt_cod_mode_t mode; + } set_cod; + } btc_gap_bt_args_t; void btc_gap_bt_call_handler(btc_msg_t *msg); void btc_gap_bt_busy_level_updated(uint8_t bl_flags); +esp_err_t btc_gap_bt_get_cod(esp_bt_cod_t *cod); #endif /* #if BTC_GAP_BT_INCLUDED */ #endif /* __BTC_GAP_BT_H__ */