esp_err_t esp_blufi_register_callbacks(esp_blufi_callbacks_t *callbacks)
{
if (esp_bluedroid_get_status() == ESP_BLUEDROID_STATUS_UNINITIALIZED) {
- return ESP_ERR_INVALID_STATE;
+ return ESP_ERR_INVALID_STATE;
}
-
+
if (callbacks == NULL) {
return ESP_FAIL;
}
btc_blufi_args_t arg;
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
- return ESP_ERR_INVALID_STATE;
+ return ESP_ERR_INVALID_STATE;
}
-
+
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_BLUFI;
msg.act = BTC_BLUFI_ACT_SEND_CFG_REPORT;
btc_msg_t msg;
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
- return ESP_ERR_INVALID_STATE;
+ return ESP_ERR_INVALID_STATE;
}
msg.sig = BTC_SIG_API_CALL;
btc_msg_t msg;
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
- return ESP_ERR_INVALID_STATE;
+ return ESP_ERR_INVALID_STATE;
}
-
+
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_BLUFI;
msg.act = BTC_BLUFI_ACT_DEINIT;
esp_bluedroid_status_t esp_bluedroid_get_status(void)
{
if (esp_already_init) {
- if (esp_already_enable) {
- return ESP_BLUEDROID_STATUS_ENABLED;
- } else {
- return ESP_BLUEDROID_STATUS_INITIALIZED;
- }
+ if (esp_already_enable) {
+ return ESP_BLUEDROID_STATUS_ENABLED;
+ } else {
+ return ESP_BLUEDROID_STATUS_INITIALIZED;
+ }
} else {
- return ESP_BLUEDROID_STATUS_UNINITIALIZED;
+ return ESP_BLUEDROID_STATUS_UNINITIALIZED;
}
}
esp_err_t esp_ble_gap_register_callback(esp_gap_ble_cb_t callback)
{
if (esp_bluedroid_get_status() == ESP_BLUEDROID_STATUS_UNINITIALIZED) {
- return ESP_ERR_INVALID_STATE;
+ return ESP_ERR_INVALID_STATE;
}
return (btc_profile_cb_set(BTC_PID_GAP_BLE, callback) == 0 ? ESP_OK : ESP_FAIL);
}
btc_ble_gap_args_t arg;
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
- return ESP_ERR_INVALID_STATE;
+ return ESP_ERR_INVALID_STATE;
}
if (adv_data == NULL) {
btc_ble_gap_args_t arg;
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
- return ESP_ERR_INVALID_STATE;
+ return ESP_ERR_INVALID_STATE;
}
if (scan_params == NULL) {
btc_ble_gap_args_t arg;
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
- return ESP_ERR_INVALID_STATE;
+ return ESP_ERR_INVALID_STATE;
}
msg.sig = BTC_SIG_API_CALL;
btc_msg_t msg;
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
- return ESP_ERR_INVALID_STATE;
+ return ESP_ERR_INVALID_STATE;
}
msg.sig = BTC_SIG_API_CALL;
btc_msg_t msg;
btc_ble_gap_args_t arg;
- if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
- return ESP_ERR_INVALID_STATE;
+ if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
+ return ESP_ERR_INVALID_STATE;
}
msg.sig = BTC_SIG_API_CALL;
btc_msg_t msg;
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
- return ESP_ERR_INVALID_STATE;
+ return ESP_ERR_INVALID_STATE;
}
msg.sig = BTC_SIG_API_CALL;
btc_ble_gap_args_t arg;
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
- return ESP_ERR_INVALID_STATE;
+ return ESP_ERR_INVALID_STATE;
}
msg.sig = BTC_SIG_API_CALL;
btc_ble_gap_args_t arg;
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
- return ESP_ERR_INVALID_STATE;
+ return ESP_ERR_INVALID_STATE;
}
msg.sig = BTC_SIG_API_CALL;
btc_ble_gap_args_t arg;
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
- return ESP_ERR_INVALID_STATE;
+ return ESP_ERR_INVALID_STATE;
}
msg.sig = BTC_SIG_API_CALL;
btc_ble_gap_args_t arg;
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
- return ESP_ERR_INVALID_STATE;
+ return ESP_ERR_INVALID_STATE;
}
msg.sig = BTC_SIG_API_CALL;
btc_ble_gap_args_t arg;
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
- return ESP_ERR_INVALID_STATE;
+ return ESP_ERR_INVALID_STATE;
}
-
+
if (strlen(name) > ESP_GAP_DEVICE_NAME_MAX) {
return ESP_ERR_INVALID_ARG;
}
esp_err_t esp_ble_gattc_register_callback(esp_gattc_cb_t callback)
{
if (esp_bluedroid_get_status() == ESP_BLUEDROID_STATUS_UNINITIALIZED) {
- return ESP_ERR_INVALID_STATE;
+ return ESP_ERR_INVALID_STATE;
}
-
+
if (callback == NULL) {
return ESP_FAIL;
}
btc_ble_gattc_args_t arg;
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
- return ESP_ERR_INVALID_STATE;
+ return ESP_ERR_INVALID_STATE;
}
-
+
if (app_id > ESP_APP_ID_MAX) {
return ESP_ERR_INVALID_ARG;
}
btc_ble_gattc_args_t arg;
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
- return ESP_ERR_INVALID_STATE;
+ return ESP_ERR_INVALID_STATE;
}
msg.sig = BTC_SIG_API_CALL;
btc_ble_gattc_args_t arg;
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
- return ESP_ERR_INVALID_STATE;
+ return ESP_ERR_INVALID_STATE;
}
-
+
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_GATTC;
msg.act = BTC_GATTC_ACT_OPEN;
btc_ble_gattc_args_t arg;
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
- return ESP_ERR_INVALID_STATE;
+ return ESP_ERR_INVALID_STATE;
}
msg.sig = BTC_SIG_API_CALL;
btc_ble_gattc_args_t arg;
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
- return ESP_ERR_INVALID_STATE;
+ return ESP_ERR_INVALID_STATE;
}
if ((mtu < ESP_GATT_DEF_BLE_MTU_SIZE) || (mtu > ESP_GATT_MAX_MTU_SIZE)) {
btc_ble_gattc_args_t arg;
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
- return ESP_ERR_INVALID_STATE;
+ return ESP_ERR_INVALID_STATE;
}
msg.sig = BTC_SIG_API_CALL;
btc_ble_gattc_args_t arg;
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
- return ESP_ERR_INVALID_STATE;
+ return ESP_ERR_INVALID_STATE;
}
msg.sig = BTC_SIG_API_CALL;
btc_ble_gattc_args_t arg;
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
- return ESP_ERR_INVALID_STATE;
+ return ESP_ERR_INVALID_STATE;
}
-
+
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_GATTC;
btc_ble_gattc_args_t arg;
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
- return ESP_ERR_INVALID_STATE;
+ return ESP_ERR_INVALID_STATE;
}
msg.sig = BTC_SIG_API_CALL;
btc_ble_gattc_args_t arg;
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
- return ESP_ERR_INVALID_STATE;
+ return ESP_ERR_INVALID_STATE;
}
msg.sig = BTC_SIG_API_CALL;
btc_ble_gattc_args_t arg;
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
- return ESP_ERR_INVALID_STATE;
+ return ESP_ERR_INVALID_STATE;
}
msg.sig = BTC_SIG_API_CALL;
esp_gatt_id_t *char_id,
uint16_t value_len,
uint8_t *value,
- esp_gatt_write_type_t write_type,
+ esp_gatt_write_type_t write_type,
esp_gatt_auth_req_t auth_req)
{
btc_msg_t msg;
btc_ble_gattc_args_t arg;
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
- return ESP_ERR_INVALID_STATE;
+ return ESP_ERR_INVALID_STATE;
}
msg.sig = BTC_SIG_API_CALL;
esp_gatt_id_t *descr_id,
uint16_t value_len,
uint8_t *value,
- esp_gatt_write_type_t write_type,
+ esp_gatt_write_type_t write_type,
esp_gatt_auth_req_t auth_req)
{
btc_msg_t msg;
btc_ble_gattc_args_t arg;
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
- return ESP_ERR_INVALID_STATE;
+ return ESP_ERR_INVALID_STATE;
}
-
+
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_GATTC;
msg.act = BTC_GATTC_ACT_WRITE_CHAR_DESCR;
btc_ble_gattc_args_t arg;
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
- return ESP_ERR_INVALID_STATE;
+ return ESP_ERR_INVALID_STATE;
}
msg.sig = BTC_SIG_API_CALL;
btc_ble_gattc_args_t arg;
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
- return ESP_ERR_INVALID_STATE;
+ return ESP_ERR_INVALID_STATE;
}
msg.sig = BTC_SIG_API_CALL;
btc_ble_gattc_args_t arg;
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
- return ESP_ERR_INVALID_STATE;
+ return ESP_ERR_INVALID_STATE;
}
msg.sig = BTC_SIG_API_CALL;
btc_ble_gattc_args_t arg;
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
- return ESP_ERR_INVALID_STATE;
+ return ESP_ERR_INVALID_STATE;
}
msg.sig = BTC_SIG_API_CALL;
#define COPY_TO_GATTS_ARGS(_gatt_args, _arg, _arg_type) memcpy(_gatt_args, _arg, sizeof(_arg_type))
+
esp_err_t esp_ble_gatts_register_callback(esp_gatts_cb_t callback)
{
if (esp_bluedroid_get_status() == ESP_BLUEDROID_STATUS_UNINITIALIZED) {
- return ESP_ERR_INVALID_STATE;
+ return ESP_ERR_INVALID_STATE;
}
return (btc_profile_cb_set(BTC_PID_GATTS, callback) == 0 ? ESP_OK : ESP_FAIL);
}
btc_ble_gatts_args_t arg;
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
- return ESP_ERR_INVALID_STATE;
+ return ESP_ERR_INVALID_STATE;
}
//if (app_id < ESP_APP_ID_MIN || app_id > ESP_APP_ID_MAX) {
btc_ble_gatts_args_t arg;
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
- return ESP_ERR_INVALID_STATE;
+ return ESP_ERR_INVALID_STATE;
}
-
+
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_GATTS;
msg.act = BTC_GATTS_ACT_APP_UNREGISTER;
btc_ble_gatts_args_t arg;
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
- return ESP_ERR_INVALID_STATE;
+ return ESP_ERR_INVALID_STATE;
}
msg.sig = BTC_SIG_API_CALL;
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gatts_args_t), NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
+esp_err_t esp_ble_gatts_create_attr_tab(const esp_gatts_attr_db_t *gatts_attr_db,
+ esp_gatt_if_t gatts_if,
+ uint8_t max_nb_attr,
+ uint8_t srvc_inst_id)
+{
+ btc_msg_t msg;
+ btc_ble_gatts_args_t arg;
+
+ msg.sig = BTC_SIG_API_CALL;
+ msg.pid = BTC_PID_GATTS;
+ msg.act = BTC_GATTS_ACT_CREATE_ATTR_TAB;
+ arg.create_attr_tab.gatts_if = gatts_if;
+ arg.create_attr_tab.max_nb_attr = max_nb_attr;
+ arg.create_attr_tab.srvc_inst_id = srvc_inst_id;
+ arg.create_attr_tab.gatts_attr_db = (esp_gatts_attr_db_t *)gatts_attr_db;
+
+ return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gatts_args_t), btc_gatts_arg_deep_copy)
+ == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
+}
+
esp_err_t esp_ble_gatts_add_included_service(uint16_t service_handle, uint16_t included_service_handle)
{
btc_ble_gatts_args_t arg;
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
- return ESP_ERR_INVALID_STATE;
+ return ESP_ERR_INVALID_STATE;
}
msg.sig = BTC_SIG_API_CALL;
esp_err_t esp_ble_gatts_add_char(uint16_t service_handle, esp_bt_uuid_t *char_uuid,
- esp_gatt_perm_t perm, esp_gatt_char_prop_t property)
+ esp_gatt_perm_t perm, esp_gatt_char_prop_t property, esp_attr_value_t *char_val,
+ esp_attr_control_t *control)
{
btc_msg_t msg;
btc_ble_gatts_args_t arg;
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
- return ESP_ERR_INVALID_STATE;
+ return ESP_ERR_INVALID_STATE;
}
-
+
+ memset(&arg, 0, sizeof(btc_ble_gatts_args_t));
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_GATTS;
msg.act = BTC_GATTS_ACT_ADD_CHAR;
arg.add_char.service_handle = service_handle;
arg.add_char.perm = perm;
arg.add_char.property = property;
+ if (char_val != NULL) {
+ arg.add_char.char_val.attr_max_len = char_val->attr_max_len;
+ arg.add_char.char_val.attr_len = char_val->attr_len;
+ arg.add_char.char_val.attr_value = char_val->attr_value;
+ }
+
+ if (control != NULL) {
+ arg.add_char.attr_control.auto_rsp = control->auto_rsp;
+ }
memcpy(&arg.add_char.char_uuid, char_uuid, sizeof(esp_bt_uuid_t));
- return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gatts_args_t), NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
+ return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gatts_args_t), btc_gatts_arg_deep_copy) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
esp_err_t esp_ble_gatts_add_char_descr (uint16_t service_handle,
esp_bt_uuid_t *descr_uuid,
- esp_gatt_perm_t perm)
+ esp_gatt_perm_t perm, esp_attr_value_t *char_descr_val,
+ esp_attr_control_t *control)
{
btc_msg_t msg;
btc_ble_gatts_args_t arg;
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
- return ESP_ERR_INVALID_STATE;
+ return ESP_ERR_INVALID_STATE;
}
+ memset(&arg, 0, sizeof(btc_ble_gatts_args_t));
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_GATTS;
msg.act = BTC_GATTS_ACT_ADD_CHAR_DESCR;
arg.add_descr.service_handle = service_handle;
arg.add_descr.perm = perm;
+
+ if (char_descr_val != NULL) {
+ arg.add_descr.descr_val.attr_max_len = char_descr_val->attr_max_len;
+ arg.add_descr.descr_val.attr_len = char_descr_val->attr_len;
+ arg.add_descr.descr_val.attr_value = char_descr_val->attr_value;
+ }
+
+ if (control != NULL) {
+ arg.add_descr.attr_control.auto_rsp = control->auto_rsp;
+ }
memcpy(&arg.add_descr.descr_uuid, descr_uuid, sizeof(esp_bt_uuid_t));
- return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gatts_args_t), NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
+ return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gatts_args_t), btc_gatts_arg_deep_copy) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
esp_err_t esp_ble_gatts_delete_service(uint16_t service_handle)
btc_ble_gatts_args_t arg;
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
- return ESP_ERR_INVALID_STATE;
+ return ESP_ERR_INVALID_STATE;
}
msg.sig = BTC_SIG_API_CALL;
btc_ble_gatts_args_t arg;
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
- return ESP_ERR_INVALID_STATE;
+ return ESP_ERR_INVALID_STATE;
}
msg.sig = BTC_SIG_API_CALL;
btc_ble_gatts_args_t arg;
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
- return ESP_ERR_INVALID_STATE;
+ return ESP_ERR_INVALID_STATE;
}
-
+
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_GATTS;
msg.act = BTC_GATTS_ACT_STOP_SERVICE;
btc_ble_gatts_args_t arg;
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
- return ESP_ERR_INVALID_STATE;
+ return ESP_ERR_INVALID_STATE;
}
msg.sig = BTC_SIG_API_CALL;
arg.send_ind.value_len = value_len;
arg.send_ind.value = value;
- return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gatts_args_t), btc_gatts_arg_deep_copy) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
+ return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gatts_args_t),
+ btc_gatts_arg_deep_copy) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
esp_err_t esp_ble_gatts_send_response(esp_gatt_if_t gatts_if, uint16_t conn_id, uint32_t trans_id,
btc_ble_gatts_args_t arg;
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
- return ESP_ERR_INVALID_STATE;
+ return ESP_ERR_INVALID_STATE;
}
msg.sig = BTC_SIG_API_CALL;
arg.send_rsp.status = status;
arg.send_rsp.rsp = rsp;
- return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gatts_args_t), btc_gatts_arg_deep_copy) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
+ return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gatts_args_t),
+ btc_gatts_arg_deep_copy) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
+}
+
+esp_err_t esp_ble_gatts_set_attr_value(uint16_t attr_handle, uint16_t length, const uint8_t *value)
+{
+ btc_msg_t msg;
+ btc_ble_gatts_args_t arg;
+
+ msg.sig = BTC_SIG_API_CALL;
+ msg.pid = BTC_PID_GATTS;
+ msg.act = BTC_GATTS_ACT_SET_ATTR_VALUE;
+ arg.set_attr_val.length = length;
+ arg.set_attr_val.value = (uint8_t *)value;
+
+ return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gatts_args_t),
+ btc_gatts_arg_deep_copy) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
+}
+
+esp_err_t esp_ble_gatts_get_attr_value(uint16_t attr_handle, uint16_t *length, const uint8_t **value)
+{
+ if (attr_handle == ESP_GATT_ILLEGAL_HANDLE) {
+ return ESP_FAIL;
+ }
+ btc_gatts_get_attr_value(attr_handle, length, (uint8_t **)value);
+ return ESP_OK;
}
esp_err_t esp_ble_gatts_open(esp_gatt_if_t gatts_if, esp_bd_addr_t remote_bda, bool is_direct)
btc_ble_gatts_args_t arg;
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
- return ESP_ERR_INVALID_STATE;
+ return ESP_ERR_INVALID_STATE;
}
msg.sig = BTC_SIG_API_CALL;
arg.open.is_direct = is_direct;
memcpy(&arg.open.remote_bda, remote_bda, sizeof(esp_bd_addr_t));
- return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gatts_args_t), NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
+ return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gatts_args_t), NULL)
+ == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
esp_err_t esp_ble_gatts_close(esp_gatt_if_t gatts_if, uint16_t conn_id)
btc_ble_gatts_args_t arg;
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
- return ESP_ERR_INVALID_STATE;
+ return ESP_ERR_INVALID_STATE;
}
-
+
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_GATTS;
msg.act = BTC_GATTS_ACT_CLOSE;
arg.close.conn_id = BTC_GATT_CREATE_CONN_ID(gatts_if, conn_id);
- return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gatts_args_t), NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
+ return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gatts_args_t), NULL)
+ == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
/// GAP BLE callback event type
typedef enum {
- ESP_GAP_BLE_ADV_DATA_SET_COMPLETE_EVT = 0, /*!< When advertising data set complete, the event comes */
- ESP_GAP_BLE_SCAN_RSP_DATA_SET_COMPLETE_EVT , /*!< When scan response data set complete, the event comes */
- ESP_GAP_BLE_SCAN_PARAM_SET_COMPLETE_EVT, /*!< When scan parameters set complete, the event comes */
- ESP_GAP_BLE_SCAN_RESULT_EVT, /*!< When one scan result ready, the event comes each time */
+ ESP_GAP_BLE_ADV_DATA_SET_COMPLETE_EVT = 0, /*!< When advertising data set complete, the event comes */
+ ESP_GAP_BLE_SCAN_RSP_DATA_SET_COMPLETE_EVT, /*!< When scan response data set complete, the event comes */
+ ESP_GAP_BLE_SCAN_PARAM_SET_COMPLETE_EVT, /*!< When scan parameters set complete, the event comes */
+ ESP_GAP_BLE_SCAN_RESULT_EVT, /*!< When one scan result ready, the event comes each time */
} esp_gap_ble_cb_event_t;
/// Advertising data maximum length
-#define ESP_BLE_ADV_DATA_LEN_MAX 31
+#define ESP_BLE_ADV_DATA_LEN_MAX 31
+/// Scan response data maximum length
+#define ESP_BLE_SCAN_RSP_DATA_LEN_MAX 31
/// The type of advertising data(not adv_type)
typedef enum {
- ESP_BLE_AD_TYPE_FLAG = 0x01,
- ESP_BLE_AD_TYPE_16SRV_PART = 0x02,
- ESP_BLE_AD_TYPE_16SRV_CMPL = 0x03,
- ESP_BLE_AD_TYPE_32SRV_PART = 0x04,
- ESP_BLE_AD_TYPE_32SRV_CMPL = 0x05,
- ESP_BLE_AD_TYPE_128SRV_PART = 0x06,
- ESP_BLE_AD_TYPE_128SRV_CMPL = 0x07,
- ESP_BLE_AD_TYPE_NAME_SHORT = 0x08,
- ESP_BLE_AD_TYPE_NAME_CMPL = 0x09,
- ESP_BLE_AD_TYPE_TX_PWR = 0x0A,
- ESP_BLE_AD_TYPE_DEV_CLASS = 0x0D,
- ESP_BLE_AD_TYPE_SM_TK = 0x10,
- ESP_BLE_AD_TYPE_SM_OOB_FLAG = 0x11,
- ESP_BLE_AD_TYPE_INT_RANGE = 0x12,
- ESP_BLE_AD_TYPE_SOL_SRV_UUID = 0x14,
- ESP_BLE_AD_TYPE_128SOL_SRV_UUID = 0x15,
- ESP_BLE_AD_TYPE_SERVICE_DATA = 0x16,
- ESP_BLE_AD_TYPE_PUBLIC_TARGET = 0x17,
- ESP_BLE_AD_TYPE_RANDOM_TARGET = 0x18,
- ESP_BLE_AD_TYPE_APPEARANCE = 0x19,
- ESP_BLE_AD_TYPE_ADV_INT = 0x1A,
- ESP_BLE_AD_TYPE_32SOL_SRV_UUID = 0x1B,
- ESP_BLE_AD_TYPE_32SERVICE_DATA = 0x1C,
- ESP_BLE_AD_TYPE_128SERVICE_DATA = 0x1D,
- ESP_BLE_AD_MANUFACTURER_SPECIFIC_TYPE = 0xFF,
+ ESP_BLE_AD_TYPE_FLAG = 0x01,
+ ESP_BLE_AD_TYPE_16SRV_PART = 0x02,
+ ESP_BLE_AD_TYPE_16SRV_CMPL = 0x03,
+ ESP_BLE_AD_TYPE_32SRV_PART = 0x04,
+ ESP_BLE_AD_TYPE_32SRV_CMPL = 0x05,
+ ESP_BLE_AD_TYPE_128SRV_PART = 0x06,
+ ESP_BLE_AD_TYPE_128SRV_CMPL = 0x07,
+ ESP_BLE_AD_TYPE_NAME_SHORT = 0x08,
+ ESP_BLE_AD_TYPE_NAME_CMPL = 0x09,
+ ESP_BLE_AD_TYPE_TX_PWR = 0x0A,
+ ESP_BLE_AD_TYPE_DEV_CLASS = 0x0D,
+ ESP_BLE_AD_TYPE_SM_TK = 0x10,
+ ESP_BLE_AD_TYPE_SM_OOB_FLAG = 0x11,
+ ESP_BLE_AD_TYPE_INT_RANGE = 0x12,
+ ESP_BLE_AD_TYPE_SOL_SRV_UUID = 0x14,
+ ESP_BLE_AD_TYPE_128SOL_SRV_UUID = 0x15,
+ ESP_BLE_AD_TYPE_SERVICE_DATA = 0x16,
+ ESP_BLE_AD_TYPE_PUBLIC_TARGET = 0x17,
+ ESP_BLE_AD_TYPE_RANDOM_TARGET = 0x18,
+ ESP_BLE_AD_TYPE_APPEARANCE = 0x19,
+ ESP_BLE_AD_TYPE_ADV_INT = 0x1A,
+ ESP_BLE_AD_TYPE_32SOL_SRV_UUID = 0x1B,
+ ESP_BLE_AD_TYPE_32SERVICE_DATA = 0x1C,
+ ESP_BLE_AD_TYPE_128SERVICE_DATA = 0x1D,
+ ESP_BLE_AD_MANUFACTURER_SPECIFIC_TYPE = 0xFF,
} esp_ble_adv_data_type;
/// Advertising mode
/// Advertising parameters
typedef struct {
- uint16_t adv_int_min; /*!< Minimum advertising interval for
- undirected and low duty cycle directed advertising.
- Range: 0x0020 to 0x4000 Default: N = 0x0800 (1.28 second)
- Time = N * 0.625 msec Time Range: 20 ms to 10.24 sec */
- uint16_t adv_int_max; /*!< Maximum advertising interval for
- undirected and low duty cycle directed advertising.
- Range: 0x0020 to 0x4000 Default: N = 0x0800 (1.28 second)
- Time = N * 0.625 msec Time Range: 20 ms to 10.24 sec Advertising max interval */
- esp_ble_adv_type_t adv_type; /*!< Advertising type */
- esp_ble_addr_type_t own_addr_type; /*!< Owner bluetooth device address type */
- esp_bd_addr_t peer_addr; /*!< Peer device bluetooth device address */
- esp_ble_addr_type_t peer_addr_type; /*!< Peer device bluetooth device address type */
- esp_ble_adv_channel_t channel_map; /*!< Advertising channel map */
- esp_ble_adv_filter_t adv_filter_policy; /*!< Advertising filter policy */
+ uint16_t adv_int_min; /*!< Minimum advertising interval for
+ undirected and low duty cycle directed advertising.
+ Range: 0x0020 to 0x4000 Default: N = 0x0800 (1.28 second)
+ Time = N * 0.625 msec Time Range: 20 ms to 10.24 sec */
+ uint16_t adv_int_max; /*!< Maximum advertising interval for
+ undirected and low duty cycle directed advertising.
+ Range: 0x0020 to 0x4000 Default: N = 0x0800 (1.28 second)
+ Time = N * 0.625 msec Time Range: 20 ms to 10.24 sec Advertising max interval */
+ esp_ble_adv_type_t adv_type; /*!< Advertising type */
+ esp_ble_addr_type_t own_addr_type; /*!< Owner bluetooth device address type */
+ esp_bd_addr_t peer_addr; /*!< Peer device bluetooth device address */
+ esp_ble_addr_type_t peer_addr_type; /*!< Peer device bluetooth device address type */
+ esp_ble_adv_channel_t channel_map; /*!< Advertising channel map */
+ esp_ble_adv_filter_t adv_filter_policy; /*!< Advertising filter policy */
} esp_ble_adv_params_t;
/// Advertising data content, according to "Supplement to the Bluetooth Core Specification"
typedef struct {
- bool set_scan_rsp; /*!< Set this advertising data as scan response or not*/
- bool include_name; /*!< Advertising data include device name or not */
- bool include_txpower; /*!< Advertising data include TX power */
- int min_interval; /*!< Advertising data show advertising min interval */
- int max_interval; /*!< Advertising data show advertising max interval */
- int appearance; /*!< External appearance of device */
- uint16_t manufacturer_len; /*!< Manufacturer data length */
- uint8_t *p_manufacturer_data; /*!< Manufacturer data point */
- uint16_t service_data_len; /*!< Service data length */
- uint8_t *p_service_data; /*!< Service data point */
- uint16_t service_uuid_len; /*!< Service uuid length */
- uint8_t *p_service_uuid; /*!< Service uuid array point */
- uint8_t flag; /*!< Advertising flag of discovery mode, see BLE_ADV_DATA_FLAG detail */
+ bool set_scan_rsp; /*!< Set this advertising data as scan response or not*/
+ bool include_name; /*!< Advertising data include device name or not */
+ bool include_txpower; /*!< Advertising data include TX power */
+ int min_interval; /*!< Advertising data show advertising min interval */
+ int max_interval; /*!< Advertising data show advertising max interval */
+ int appearance; /*!< External appearance of device */
+ uint16_t manufacturer_len; /*!< Manufacturer data length */
+ uint8_t *p_manufacturer_data; /*!< Manufacturer data point */
+ uint16_t service_data_len; /*!< Service data length */
+ uint8_t *p_service_data; /*!< Service data point */
+ uint16_t service_uuid_len; /*!< Service uuid length */
+ uint8_t *p_service_uuid; /*!< Service uuid array point */
+ uint8_t flag; /*!< Advertising flag of discovery mode, see BLE_ADV_DATA_FLAG detail */
} esp_ble_adv_data_t;
/// Own BD address source of the device
/// Ble scan type
typedef enum {
- BLE_SCAN_TYPE_PASSIVE = 0x0, /*!< Passive scan */
- BLE_SCAN_TYPE_ACTIVE = 0x1, /*!< Active scan */
+ BLE_SCAN_TYPE_PASSIVE = 0x0, /*!< Passive scan */
+ BLE_SCAN_TYPE_ACTIVE = 0x1, /*!< Active scan */
} esp_ble_scan_type_t;
/// Ble scan filter type
typedef enum {
- BLE_SCAN_FILTER_ALLOW_ALL = 0x0, /*!< Accept all :
- 1. advertisement packets except directed advertising packets not addressed to this device (default). */
+ BLE_SCAN_FILTER_ALLOW_ALL = 0x0, /*!< Accept all :
+ 1. advertisement packets except directed advertising packets not addressed to this device (default). */
BLE_SCAN_FILTER_ALLOW_ONLY_WLST = 0x1, /*!< Accept only :
- 1. advertisement packets from devices where the advertiser’s address is in the White list.
- 2. Directed advertising packets which are not addressed for this device shall be ignored. */
+ 1. advertisement packets from devices where the advertiser’s address is in the White list.
+ 2. Directed advertising packets which are not addressed for this device shall be ignored. */
BLE_SCAN_FILTER_ALLOW_UND_RPA_DIR = 0x2, /*!< Accept all :
- 1. undirected advertisement packets, and
- 2. directed advertising packets where the initiator address is a resolvable private address, and
- 3. directed advertising packets addressed to this device. */
+ 1. undirected advertisement packets, and
+ 2. directed advertising packets where the initiator address is a resolvable private address, and
+ 3. directed advertising packets addressed to this device. */
BLE_SCAN_FILTER_ALLOW_WLIST_PRA_DIR = 0x3, /*!< Accept all :
- 1. advertisement packets from devices where the advertiser’s address is in the White list, and
- 2. directed advertising packets where the initiator address is a resolvable private address, and
- 3. directed advertising packets addressed to this device.*/
+ 1. advertisement packets from devices where the advertiser’s address is in the White list, and
+ 2. directed advertising packets where the initiator address is a resolvable private address, and
+ 3. directed advertising packets addressed to this device.*/
} esp_ble_scan_filter_t;
/// Ble scan parameters
typedef struct {
- esp_ble_scan_type_t scan_type; /*!< Scan type */
- esp_ble_addr_type_t own_addr_type; /*!< Owner address type */
- esp_ble_scan_filter_t scan_filter_policy; /*!< Scan filter policy */
- uint16_t scan_interval; /*!< Scan interval. This is defined as the time interval from
- when the Controller started its last LE scan until it begins the subsequent LE scan.
- Range: 0x0004 to 0x4000 Default: 0x0010 (10 ms)
- Time = N * 0.625 msec
- Time Range: 2.5 msec to 10.24 seconds*/
- uint16_t scan_window; /*!< Scan window. The duration of the LE scan. LE_Scan_Window
- shall be less than or equal to LE_Scan_Interval
- Range: 0x0004 to 0x4000 Default: 0x0010 (10 ms)
- Time = N * 0.625 msec
- Time Range: 2.5 msec to 10240 msec */
+ esp_ble_scan_type_t scan_type; /*!< Scan type */
+ esp_ble_addr_type_t own_addr_type; /*!< Owner address type */
+ esp_ble_scan_filter_t scan_filter_policy; /*!< Scan filter policy */
+ uint16_t scan_interval; /*!< Scan interval. This is defined as the time interval from
+ when the Controller started its last LE scan until it begins the subsequent LE scan.
+ Range: 0x0004 to 0x4000 Default: 0x0010 (10 ms)
+ Time = N * 0.625 msec
+ Time Range: 2.5 msec to 10.24 seconds*/
+ uint16_t scan_window; /*!< Scan window. The duration of the LE scan. LE_Scan_Window
+ shall be less than or equal to LE_Scan_Interval
+ Range: 0x0004 to 0x4000 Default: 0x0010 (10 ms)
+ Time = N * 0.625 msec
+ Time Range: 2.5 msec to 10240 msec */
} esp_ble_scan_params_t;
/// Connection update parameters
typedef struct {
- esp_bd_addr_t bda; /*!< Bluetooth device address */
- uint16_t min_int; /*!< Min connection interval */
- uint16_t max_int; /*!< Max connection interval */
- uint16_t latency; /*!< Slave latency for the connection in number of connection events. Range: 0x0000 to 0x01F3 */
- uint16_t timeout; /*!< Supervision timeout for the LE Link. Range: 0x000A to 0x0C80.
- Mandatory Range: 0x000A to 0x0C80 Time = N * 10 msec
- Time Range: 100 msec to 32 seconds */
+ esp_bd_addr_t bda; /*!< Bluetooth device address */
+ uint16_t min_int; /*!< Min connection interval */
+ uint16_t max_int; /*!< Max connection interval */
+ uint16_t latency; /*!< Slave latency for the connection in number of connection events. Range: 0x0000 to 0x01F3 */
+ uint16_t timeout; /*!< Supervision timeout for the LE Link. Range: 0x000A to 0x0C80.
+ Mandatory Range: 0x000A to 0x0C80 Time = N * 10 msec
+ Time Range: 100 msec to 32 seconds */
} esp_ble_conn_update_params_t;
/// Sub Event of ESP_GAP_BLE_SCAN_RESULT_EVT
* result is scan response or advertising data or other
*/
typedef enum {
- ESP_BLE_EVT_CONN_ADV = 0x00, /*!< Connectable undirected advertising (ADV_IND) */
- ESP_BLE_EVT_CONN_DIR_ADV = 0x01, /*!< Connectable directed advertising (ADV_DIRECT_IND) */
- ESP_BLE_EVT_DISC_ADV = 0x02, /*!< Scannable undirected advertising (ADV_SCAN_IND) */
- ESP_BLE_EVT_NON_CONN_ADV = 0x03, /*!< Non connectable undirected advertising (ADV_NONCONN_IND) */
- ESP_BLE_EVT_SCAN_RSP = 0x04, /*!< Scan Response (SCAN_RSP) */
+ ESP_BLE_EVT_CONN_ADV = 0x00, /*!< Connectable undirected advertising (ADV_IND) */
+ ESP_BLE_EVT_CONN_DIR_ADV = 0x01, /*!< Connectable directed advertising (ADV_DIRECT_IND) */
+ ESP_BLE_EVT_DISC_ADV = 0x02, /*!< Scannable undirected advertising (ADV_SCAN_IND) */
+ ESP_BLE_EVT_NON_CONN_ADV = 0x03, /*!< Non connectable undirected advertising (ADV_NONCONN_IND) */
+ ESP_BLE_EVT_SCAN_RSP = 0x04, /*!< Scan Response (SCAN_RSP) */
} esp_ble_evt_type_t;
/**
* @brief ESP_GAP_BLE_ADV_DATA_SET_COMPLETE_EVT
*/
struct ble_adv_data_cmpl_evt_param {
- esp_bt_status_t status; /*!< Indicate the set advertising data operation success status */
- } adv_data_cmpl; /*!< Event parameter of ESP_GAP_BLE_ADV_DATA_SET_COMPLETE_EVT */
+ esp_bt_status_t status; /*!< Indicate the set advertising data operation success status */
+ } adv_data_cmpl; /*!< Event parameter of ESP_GAP_BLE_ADV_DATA_SET_COMPLETE_EVT */
/**
* @brief ESP_GAP_BLE_SCAN_RSP_DATA_SET_COMPLETE_EVT
*/
struct ble_scan_rsp_data_cmpl_evt_param {
- esp_bt_status_t status; /*!< Indicate the set scan response data operation success status */
- } scan_rsp_data_cmpl; /*!< Event parameter of ESP_GAP_BLE_SCAN_RSP_DATA_SET_COMPLETE_EVT */
+ esp_bt_status_t status; /*!< Indicate the set scan response data operation success status */
+ } scan_rsp_data_cmpl; /*!< Event parameter of ESP_GAP_BLE_SCAN_RSP_DATA_SET_COMPLETE_EVT */
/**
* @brief ESP_GAP_BLE_SCAN_PARAM_SET_COMPLETE_EVT
*/
struct ble_scan_param_cmpl_evt_param {
- esp_bt_status_t status; /*!< Indicate the set scan param operation success status */
- } scan_param_cmpl; /*!< Event parameter of ESP_GAP_BLE_SCAN_PARAM_SET_COMPLETE_EVT */
+ esp_bt_status_t status; /*!< Indicate the set scan param operation success status */
+ } scan_param_cmpl; /*!< Event parameter of ESP_GAP_BLE_SCAN_PARAM_SET_COMPLETE_EVT */
/**
* @brief ESP_GAP_BLE_SCAN_RESULT_EVT
*/
struct ble_scan_result_evt_param {
- esp_gap_search_evt_t search_evt; /*!< Search event type */
- esp_bd_addr_t bda; /*!< Bluetooth device address which has been searched */
- esp_bt_dev_type_t dev_type; /*!< Device type */
- esp_ble_addr_type_t ble_addr_type; /*!< Ble device address type */
- esp_ble_evt_type_t ble_evt_type; /*!< Ble scan result event type */
- int rssi; /*!< Searched device's RSSI */
- uint8_t ble_adv[ESP_BLE_ADV_DATA_LEN_MAX]; /*!< Received EIR */
- int flag; /*!< Advertising data flag bit */
- int num_resps; /*!< Scan result number */
- } scan_rst; /*!< Event parameter of ESP_GAP_BLE_SCAN_RESULT_EVT */
+ esp_gap_search_evt_t search_evt; /*!< Search event type */
+ esp_bd_addr_t bda; /*!< Bluetooth device address which has been searched */
+ esp_bt_dev_type_t dev_type; /*!< Device type */
+ esp_ble_addr_type_t ble_addr_type; /*!< Ble device address type */
+ esp_ble_evt_type_t ble_evt_type; /*!< Ble scan result event type */
+ int rssi; /*!< Searched device's RSSI */
+ uint8_t ble_adv[ESP_BLE_ADV_DATA_LEN_MAX + ESP_BLE_SCAN_RSP_DATA_LEN_MAX]; /*!< Received EIR */
+ int flag; /*!< Advertising data flag bit */
+ int num_resps; /*!< Scan result number */
+ } scan_rst; /*!< Event parameter of ESP_GAP_BLE_SCAN_RESULT_EVT */
} esp_ble_gap_cb_param_t;
/**
* @param[in] type - finding ADV data type
* @param[out] length - return the length of ADV data not including type
*
- * @return pointer of ADV data
+ * @return - ESP_OK : success
+ * - other : failed
*
*/
uint8_t *esp_ble_resolve_adv_data(uint8_t *adv_data, uint8_t type, uint8_t *length);
#endif
/// GATT INVALID UUID
-#define ESP_GATT_ILLEGAL_UUID 0
+#define ESP_GATT_ILLEGAL_UUID 0
+/// GATT INVALID HANDLE
+#define ESP_GATT_ILLEGAL_HANDLE 0
+/// GATT attribute max handle
+#define ESP_GATT_ATTR_HANDLE_MAX 100
+
/**@{
* All "ESP_GATT_UUID_xxx" is attribute types
*/
-#define ESP_GATT_UUID_PRI_SERVICE 0x2800
-#define ESP_GATT_UUID_SEC_SERVICE 0x2801
-#define ESP_GATT_UUID_INCLUDE_SERVICE 0x2802
-#define ESP_GATT_UUID_CHAR_DECLARE 0x2803 /* Characteristic Declaration*/
-
-#define ESP_GATT_UUID_CHAR_EXT_PROP 0x2900 /* Characteristic Extended Properties */
-#define ESP_GATT_UUID_CHAR_DESCRIPTION 0x2901 /* Characteristic User Description*/
-#define ESP_GATT_UUID_CHAR_CLIENT_CONFIG 0x2902 /* Client Characteristic Configuration */
-#define ESP_GATT_UUID_CHAR_SRVR_CONFIG 0x2903 /* Server Characteristic Configuration */
-#define ESP_GATT_UUID_CHAR_PRESENT_FORMAT 0x2904 /* Characteristic Presentation Format*/
-#define ESP_GATT_UUID_CHAR_AGG_FORMAT 0x2905 /* Characteristic Aggregate Format*/
-#define ESP_GATT_UUID_CHAR_VALID_RANGE 0x2906 /* Characteristic Valid Range */
-#define ESP_GATT_UUID_EXT_RPT_REF_DESCR 0x2907
-#define ESP_GATT_UUID_RPT_REF_DESCR 0x2908
+#define ESP_GATT_UUID_IMMEDIATE_ALERT_SVC 0x1802 /* Immediate alert Service*/
+#define ESP_GATT_UUID_LINK_LOSS_SVC 0x1803 /* Link Loss Service*/
+#define ESP_GATT_UUID_TX_POWER_SVC 0x1804 /* TX Power Service*/
+#define ESP_GATT_UUID_CURRENT_TIME_SVC 0x1805 /* Current Time Service Service*/
+#define ESP_GATT_UUID_REF_TIME_UPDATE_SVC 0x1806 /* Reference Time Update Service*/
+#define ESP_GATT_UUID_NEXT_DST_CHANGE_SVC 0x1807 /* Next DST Change Service*/
+#define ESP_GATT_UUID_GLUCOSE_SVC 0x1808 /* Glucose Service*/
+#define ESP_GATT_UUID_HEALTH_THERMOM_SVC 0x1809 /* Health Thermometer Service*/
+#define ESP_GATT_UUID_DEVICE_INFO_SVC 0x180A /* Device Information Service*/
+#define ESP_GATT_UUID_HEART_RATE_SVC 0x180D /* Heart Rate Service*/
+#define ESP_GATT_UUID_PHONE_ALERT_STATUS_SVC 0x180E /* Phone Alert Status Service*/
+#define ESP_GATT_UUID_BATTERY_SERVICE_SVC 0x180F /* Battery Service*/
+#define ESP_GATT_UUID_BLOOD_PRESSURE_SVC 0x1810 /* Blood Pressure Service*/
+#define ESP_GATT_UUID_ALERT_NTF_SVC 0x1811 /* Alert Notification Service*/
+#define ESP_GATT_UUID_HID_SVC 0x1812 /* HID Service*/
+#define ESP_GATT_UUID_SCAN_PARAMETERS_SVC 0x1813 /* Scan Parameters Service*/
+#define ESP_GATT_UUID_RUNNING_SPEED_CADENCE_SVC 0x1814 /* Running Speed and Cadence Service*/
+#define ESP_GATT_UUID_CYCLING_SPEED_CADENCE_SVC 0x1816 /* Cycling Speed and Cadence Service*/
+#define ESP_GATT_UUID_CYCLING_POWER_SVC 0x1818 /* Cycling Power Service*/
+#define ESP_GATT_UUID_LOCATION_AND_NAVIGATION_SVC 0x1819 /* Location and Navigation Service*/
+#define ESP_GATT_UUID_USER_DATA_SVC 0x181C /* User Data Service*/
+#define ESP_GATT_UUID_WEIGHT_SCALE_SVC 0x181D /* Weight Scale Service*/
+
+#define ESP_GATT_UUID_PRI_SERVICE 0x2800
+#define ESP_GATT_UUID_SEC_SERVICE 0x2801
+#define ESP_GATT_UUID_INCLUDE_SERVICE 0x2802
+#define ESP_GATT_UUID_CHAR_DECLARE 0x2803 /* Characteristic Declaration*/
+
+#define ESP_GATT_UUID_CHAR_EXT_PROP 0x2900 /* Characteristic Extended Properties */
+#define ESP_GATT_UUID_CHAR_DESCRIPTION 0x2901 /* Characteristic User Description*/
+#define ESP_GATT_UUID_CHAR_CLIENT_CONFIG 0x2902 /* Client Characteristic Configuration */
+#define ESP_GATT_UUID_CHAR_SRVR_CONFIG 0x2903 /* Server Characteristic Configuration */
+#define ESP_GATT_UUID_CHAR_PRESENT_FORMAT 0x2904 /* Characteristic Presentation Format*/
+#define ESP_GATT_UUID_CHAR_AGG_FORMAT 0x2905 /* Characteristic Aggregate Format*/
+#define ESP_GATT_UUID_CHAR_VALID_RANGE 0x2906 /* Characteristic Valid Range */
+#define ESP_GATT_UUID_EXT_RPT_REF_DESCR 0x2907
+#define ESP_GATT_UUID_RPT_REF_DESCR 0x2908
/* GAP Profile Attributes */
-#define ESP_GATT_UUID_GAP_DEVICE_NAME 0x2A00
-#define ESP_GATT_UUID_GAP_ICON 0x2A01
-#define ESP_GATT_UUID_GAP_PREF_CONN_PARAM 0x2A04
-#define ESP_GATT_UUID_GAP_CENTRAL_ADDR_RESOL 0x2AA6
+#define ESP_GATT_UUID_GAP_DEVICE_NAME 0x2A00
+#define ESP_GATT_UUID_GAP_ICON 0x2A01
+#define ESP_GATT_UUID_GAP_PREF_CONN_PARAM 0x2A04
+#define ESP_GATT_UUID_GAP_CENTRAL_ADDR_RESOL 0x2AA6
/* Attribute Profile Attribute UUID */
-#define ESP_GATT_UUID_GATT_SRV_CHGD 0x2A05
+#define ESP_GATT_UUID_GATT_SRV_CHGD 0x2A05
/* Link ESP_Loss Service */
-#define ESP_GATT_UUID_ALERT_LEVEL 0x2A06 /* Alert Level */
-#define ESP_GATT_UUID_TX_POWER_LEVEL 0x2A07 /* TX power level */
+#define ESP_GATT_UUID_ALERT_LEVEL 0x2A06 /* Alert Level */
+#define ESP_GATT_UUID_TX_POWER_LEVEL 0x2A07 /* TX power level */
/* Current Time Service */
-#define ESP_GATT_UUID_CURRENT_TIME 0x2A2B /* Current Time */
-#define ESP_GATT_UUID_LOCAL_TIME_INFO 0x2A0F /* Local time info */
-#define ESP_GATT_UUID_REF_TIME_INFO 0x2A14 /* reference time information */
+#define ESP_GATT_UUID_CURRENT_TIME 0x2A2B /* Current Time */
+#define ESP_GATT_UUID_LOCAL_TIME_INFO 0x2A0F /* Local time info */
+#define ESP_GATT_UUID_REF_TIME_INFO 0x2A14 /* reference time information */
/* Network availability Profile */
-#define ESP_GATT_UUID_NW_STATUS 0x2A18 /* network availability status */
-#define ESP_GATT_UUID_NW_TRIGGER 0x2A1A /* Network availability trigger */
+#define ESP_GATT_UUID_NW_STATUS 0x2A18 /* network availability status */
+#define ESP_GATT_UUID_NW_TRIGGER 0x2A1A /* Network availability trigger */
/* Phone alert */
-#define ESP_GATT_UUID_ALERT_STATUS 0x2A3F /* alert status */
-#define ESP_GATT_UUID_RINGER_CP 0x2A40 /* ringer control point */
-#define ESP_GATT_UUID_RINGER_SETTING 0x2A41 /* ringer setting */
+#define ESP_GATT_UUID_ALERT_STATUS 0x2A3F /* alert status */
+#define ESP_GATT_UUID_RINGER_CP 0x2A40 /* ringer control point */
+#define ESP_GATT_UUID_RINGER_SETTING 0x2A41 /* ringer setting */
/* Glucose Service */
-#define ESP_GATT_UUID_GM_MEASUREMENT 0x2A18
-#define ESP_GATT_UUID_GM_CONTEXT 0x2A34
-#define ESP_GATT_UUID_GM_CONTROL_POINT 0x2A52
-#define ESP_GATT_UUID_GM_FEATURE 0x2A51
+#define ESP_GATT_UUID_GM_MEASUREMENT 0x2A18
+#define ESP_GATT_UUID_GM_CONTEXT 0x2A34
+#define ESP_GATT_UUID_GM_CONTROL_POINT 0x2A52
+#define ESP_GATT_UUID_GM_FEATURE 0x2A51
/* device information characteristic */
-#define ESP_GATT_UUID_SYSTEM_ID 0x2A23
-#define ESP_GATT_UUID_MODEL_NUMBER_STR 0x2A24
-#define ESP_GATT_UUID_SERIAL_NUMBER_STR 0x2A25
-#define ESP_GATT_UUID_FW_VERSION_STR 0x2A26
-#define ESP_GATT_UUID_HW_VERSION_STR 0x2A27
-#define ESP_GATT_UUID_SW_VERSION_STR 0x2A28
-#define ESP_GATT_UUID_MANU_NAME 0x2A29
-#define ESP_GATT_UUID_IEEE_DATA 0x2A2A
-#define ESP_GATT_UUID_PNP_ID 0x2A50
+#define ESP_GATT_UUID_SYSTEM_ID 0x2A23
+#define ESP_GATT_UUID_MODEL_NUMBER_STR 0x2A24
+#define ESP_GATT_UUID_SERIAL_NUMBER_STR 0x2A25
+#define ESP_GATT_UUID_FW_VERSION_STR 0x2A26
+#define ESP_GATT_UUID_HW_VERSION_STR 0x2A27
+#define ESP_GATT_UUID_SW_VERSION_STR 0x2A28
+#define ESP_GATT_UUID_MANU_NAME 0x2A29
+#define ESP_GATT_UUID_IEEE_DATA 0x2A2A
+#define ESP_GATT_UUID_PNP_ID 0x2A50
/* HID characteristics */
-#define ESP_GATT_UUID_HID_INFORMATION 0x2A4A
-#define ESP_GATT_UUID_HID_REPORT_MAP 0x2A4B
-#define ESP_GATT_UUID_HID_CONTROL_POINT 0x2A4C
-#define ESP_GATT_UUID_HID_REPORT 0x2A4D
-#define ESP_GATT_UUID_HID_PROTO_MODE 0x2A4E
-#define ESP_GATT_UUID_HID_BT_KB_INPUT 0x2A22
-#define ESP_GATT_UUID_HID_BT_KB_OUTPUT 0x2A32
-#define ESP_GATT_UUID_HID_BT_MOUSE_INPUT 0x2A33
+#define ESP_GATT_UUID_HID_INFORMATION 0x2A4A
+#define ESP_GATT_UUID_HID_REPORT_MAP 0x2A4B
+#define ESP_GATT_UUID_HID_CONTROL_POINT 0x2A4C
+#define ESP_GATT_UUID_HID_REPORT 0x2A4D
+#define ESP_GATT_UUID_HID_PROTO_MODE 0x2A4E
+#define ESP_GATT_UUID_HID_BT_KB_INPUT 0x2A22
+#define ESP_GATT_UUID_HID_BT_KB_OUTPUT 0x2A32
+#define ESP_GATT_UUID_HID_BT_MOUSE_INPUT 0x2A33
+
+ /// Heart Rate Measurement
+#define ESP_GATT_HEART_RATE_MEAS 0x2A37
+/// Body Sensor Location
+#define ESP_GATT_BODY_SENSOR_LOCATION 0x2A38
+/// Heart Rate Control Point
+#define ESP_GATT_HEART_RATE_CNTL_POINT 0x2A39
/* Battery Service characteristics */
-#define ESP_GATT_UUID_BATTERY_LEVEL 0x2A19
+#define ESP_GATT_UUID_BATTERY_LEVEL 0x2A19
/* Sensor Service */
-#define ESP_GATT_UUID_SC_CONTROL_POINT 0x2A55
-#define ESP_GATT_UUID_SENSOR_LOCATION 0x2A5D
+#define ESP_GATT_UUID_SC_CONTROL_POINT 0x2A55
+#define ESP_GATT_UUID_SENSOR_LOCATION 0x2A5D
/* Runners speed and cadence service */
-#define ESP_GATT_UUID_RSC_MEASUREMENT 0x2A53
-#define ESP_GATT_UUID_RSC_FEATURE 0x2A54
+#define ESP_GATT_UUID_RSC_MEASUREMENT 0x2A53
+#define ESP_GATT_UUID_RSC_FEATURE 0x2A54
/* Cycling speed and cadence service */
-#define ESP_GATT_UUID_CSC_MEASUREMENT 0x2A5B
-#define ESP_GATT_UUID_CSC_FEATURE 0x2A5C
+#define ESP_GATT_UUID_CSC_MEASUREMENT 0x2A5B
+#define ESP_GATT_UUID_CSC_FEATURE 0x2A5C
/* Scan ESP_Parameter characteristics */
-#define ESP_GATT_UUID_SCAN_INT_WINDOW 0x2A4F
-#define ESP_GATT_UUID_SCAN_REFRESH 0x2A31
+#define ESP_GATT_UUID_SCAN_INT_WINDOW 0x2A4F
+#define ESP_GATT_UUID_SCAN_REFRESH 0x2A31
/**
* @}
*/
/// Attribute write data type from the client
typedef enum {
- ESP_GATT_PREP_WRITE_CANCEL = 0x00, /*!< Prepare write cancel */
- ESP_GATT_PREP_WRITE_EXEC = 0x01, /*!< Prepare write execute */
+ ESP_GATT_PREP_WRITE_CANCEL = 0x00, /*!< Prepare write cancel */
+ ESP_GATT_PREP_WRITE_EXEC = 0x01, /*!< Prepare write execute */
} esp_gatt_prep_write_type;
/**
* @brief Gatt Connection reason enum
*/
typedef enum {
- ESP_GATT_CONN_UNKNOWN = 0, /*!< Gatt connection unknown */
- ESP_GATT_CONN_L2C_FAILURE = 1, /*!< General L2cap failure */
- ESP_GATT_CONN_TIMEOUT = 0x08, /*!< Connection timeout */
- ESP_GATT_CONN_TERMINATE_PEER_USER = 0x13, /*!< Connection terminate by peer user */
- ESP_GATT_CONN_TERMINATE_LOCAL_HOST = 0x16, /*!< Connectionterminated by local host */
- ESP_GATT_CONN_FAIL_ESTABLISH = 0x3e, /*!< Connection fail to establish */
- ESP_GATT_CONN_LMP_TIMEOUT = 0x22, /*!< Connection fail for LMP response tout */
- ESP_GATT_CONN_CONN_CANCEL = 0x0100, /*!< L2CAP connection cancelled */
- ESP_GATT_CONN_NONE = 0x0101 /*!< No connection to cancel */
+ ESP_GATT_CONN_UNKNOWN = 0, /*!< Gatt connection unknown */
+ ESP_GATT_CONN_L2C_FAILURE = 1, /*!< General L2cap failure */
+ ESP_GATT_CONN_TIMEOUT = 0x08, /*!< Connection timeout */
+ ESP_GATT_CONN_TERMINATE_PEER_USER = 0x13, /*!< Connection terminate by peer user */
+ ESP_GATT_CONN_TERMINATE_LOCAL_HOST = 0x16, /*!< Connectionterminated by local host */
+ ESP_GATT_CONN_FAIL_ESTABLISH = 0x3e, /*!< Connection fail to establish */
+ ESP_GATT_CONN_LMP_TIMEOUT = 0x22, /*!< Connection fail for LMP response tout */
+ ESP_GATT_CONN_CONN_CANCEL = 0x0100, /*!< L2CAP connection cancelled */
+ ESP_GATT_CONN_NONE = 0x0101 /*!< No connection to cancel */
} esp_gatt_conn_reason_t;
/**
* @brief Gatt id, include uuid and instance id
*/
typedef struct {
- esp_bt_uuid_t uuid; /*!< UUID */
- uint8_t inst_id; /*!< Instance id */
+ esp_bt_uuid_t uuid; /*!< UUID */
+ uint8_t inst_id; /*!< Instance id */
} __attribute__((packed)) esp_gatt_id_t;
/**
* (uuid and instance id) and primary flag
*/
typedef struct {
- esp_gatt_id_t id; /*!< Gatt id, include uuid and instance */
- bool is_primary; /*!< This service is primary or not */
+ esp_gatt_id_t id; /*!< Gatt id, include uuid and instance */
+ bool is_primary; /*!< This service is primary or not */
} __attribute__((packed)) esp_gatt_srvc_id_t;
/**
* @brief Gatt authentication request type
*/
typedef enum {
- ESP_GATT_AUTH_REQ_NONE = 0,
- ESP_GATT_AUTH_REQ_NO_MITM = 1, /* unauthenticated encryption */
- ESP_GATT_AUTH_REQ_MITM = 2, /* authenticated encryption */
- ESP_GATT_AUTH_REQ_SIGNED_NO_MITM = 3,
- ESP_GATT_AUTH_REQ_SIGNED_MITM = 4,
+ ESP_GATT_AUTH_REQ_NONE = 0,
+ ESP_GATT_AUTH_REQ_NO_MITM = 1, /* unauthenticated encryption */
+ ESP_GATT_AUTH_REQ_MITM = 2, /* authenticated encryption */
+ ESP_GATT_AUTH_REQ_SIGNED_NO_MITM = 3,
+ ESP_GATT_AUTH_REQ_SIGNED_MITM = 4,
} esp_gatt_auth_req_t;
/**
/// GATT maximum attribute length
#define ESP_GATT_MAX_ATTR_LEN 600 //as same as GATT_MAX_ATTR_LEN
+
+/**
+ * @brief Attribute description (used to create database)
+ */
+ typedef struct
+ {
+ esp_bt_uuid_t uuid; /*!< Element UUID */
+ uint16_t perm; /*!< Attribute permission */
+ uint16_t max_length; /*!< Maximum length of the element*/
+ uint16_t length; /*!< Current length of the element*/
+ uint8_t* value; /*!< Element value array*/
+ }esp_attr_desc_t;
+
+
+/**
+ * @brief attribute auto respose flag
+ */
+typedef struct
+{
+#define ESP_GATT_RSP_BY_APP 0
+#define ESP_GATT_AUTO_RSP 1
+ uint8_t auto_rsp; /*!< need the app response to the client if need_rsp set to 1*/
+}esp_attr_control_t;
+
+
+/**
+ * @brief attribute type added to the gatt server database
+ */
+typedef struct
+{
+ esp_attr_control_t attr_control; /*!< The attribue control type*/
+ esp_attr_desc_t att_desc; /*!< The attribue type*/
+}esp_gatts_attr_db_t;
+
+
+/**
+ * @brief set the attribute value type
+ */
+typedef struct
+{
+ uint16_t attr_max_len; /*!< attribute max value length */
+ uint16_t attr_len; /*!< attribute current value length */
+ uint8_t *attr_value; /*!< the pointer to attribute value */
+}esp_attr_value_t;
+
+
+/**
+ * @brief Gatt include service entry element
+ */
+typedef struct
+{
+ uint16_t start_hdl; /*!< Gatt start handle value of included service */
+ uint16_t end_hdl; /*!< Gatt end handle value of included service */
+ uint16_t uuid; /*!< Gatt attribute value UUID of included service */
+}esp_gatts_incl_svc_desc_t; /*!< Gatt include service entry element */
+
+/**
+ * @brief Gatt include 128 bit service entry element
+ */
+typedef struct
+{
+ uint16_t start_hdl; /*!< Gatt start handle value of included 128 bit service */
+ uint16_t end_hdl; /*!< Gatt end handle value of included 128 bit service */
+}esp_gatts_incl128_svc_desc_t; /*!< Gatt include 128 bit service entry element */
+
+
+/**
+ * @brief Gatt characteristic entry element
+ */
+typedef struct
+{
+ uint8_t prop; /*!< Gatt attribute properties */
+ uint16_t attr_hdl; /*!< Gatt attribute handle */
+ esp_bt_uuid_t attr_uuid; /*!< Gatt attribute uuid typedle */
+}esp_gatts_char_desc_t; /*!< Gatt characteristic value descriptor */
+
+
/// Gatt attribute value
typedef struct {
- uint8_t value[ESP_GATT_MAX_ATTR_LEN]; /*!< Gatt attribute value */
- uint16_t handle; /*!< Gatt attribute handle */
- uint16_t offset; /*!< Gatt attribute value offset */
- uint16_t len; /*!< Gatt attribute value length */
- uint8_t auth_req; /*!< Gatt authentication request */
+ uint8_t value[ESP_GATT_MAX_ATTR_LEN]; /*!< Gatt attribute value */
+ uint16_t handle; /*!< Gatt attribute handle */
+ uint16_t offset; /*!< Gatt attribute value offset */
+ uint16_t len; /*!< Gatt attribute value length */
+ uint8_t auth_req; /*!< Gatt authentication request */
} esp_gatt_value_t;
/// GATT remote read request response type
typedef union {
- esp_gatt_value_t attr_value; /*!< Gatt attribute structure */
- uint16_t handle; /*!< Gatt attribute handle */
+ esp_gatt_value_t attr_value; /*!< Gatt attribute structure */
+ uint16_t handle; /*!< Gatt attribute handle */
} esp_gatt_rsp_t;
/**
* @brief Gatt write type
*/
typedef enum {
- ESP_GATT_WRITE_TYPE_NO_RSP = 1, /*!< Gatt write attribute need no response */
- ESP_GATT_WRITE_TYPE_RSP, /*!< Gatt write attribute need remote response */
+ ESP_GATT_WRITE_TYPE_NO_RSP = 1, /*!< Gatt write attribute need no response */
+ ESP_GATT_WRITE_TYPE_RSP, /*!< Gatt write attribute need remote response */
} esp_gatt_write_type_t;
#define ESP_GATT_IF_NONE 0xff /*!< If callback report gattc_if/gatts_if as this macro, means this event is not correspond to any app */
-typedef uint8_t esp_gatt_if_t; /*!< Gatt interface type, different application on GATT client use different gatt_if */
+typedef uint8_t esp_gatt_if_t; /*!< Gatt interface type, different application on GATT client use different gatt_if */
#ifdef __cplusplus
}
/// GATT Server callback function events
typedef enum {
- ESP_GATTS_REG_EVT = 0, /*!< When register application id, the event comes */
- ESP_GATTS_READ_EVT = 1, /*!< When gatt client request read operation, the event comes */
- ESP_GATTS_WRITE_EVT = 2, /*!< When gatt client request write operation, the event comes */
- ESP_GATTS_EXEC_WRITE_EVT = 3, /*!< When gatt client request execute write, the event comes */
- ESP_GATTS_MTU_EVT = 4, /*!< When set mtu complete, the event comes */
- ESP_GATTS_CONF_EVT = 5, /*!< When receive confirm, the event comes */
- ESP_GATTS_UNREG_EVT = 6, /*!< When unregister application id, the event comes */
- ESP_GATTS_CREATE_EVT = 7, /*!< When create service complete, the event comes */
- ESP_GATTS_ADD_INCL_SRVC_EVT = 8, /*!< When add included service complete, the event comes */
- ESP_GATTS_ADD_CHAR_EVT = 9, /*!< When add characteristic complete, the event comes */
- ESP_GATTS_ADD_CHAR_DESCR_EVT = 10, /*!< When add descriptor complete, the event comes */
- ESP_GATTS_DELETE_EVT = 11, /*!< When delete service complete, the event comes */
- ESP_GATTS_START_EVT = 12, /*!< When start service complete, the event comes */
- ESP_GATTS_STOP_EVT = 13, /*!< When stop service complete, the event comes */
- ESP_GATTS_CONNECT_EVT = 14, /*!< When gatt client connect, the event comes */
- ESP_GATTS_DISCONNECT_EVT = 15, /*!< When gatt client disconnect, the event comes */
- ESP_GATTS_OPEN_EVT = 16, /*!< When connect to peer, the event comes */
- ESP_GATTS_CANCEL_OPEN_EVT = 17, /*!< When disconnect from peer, the event comes */
- ESP_GATTS_CLOSE_EVT = 18, /*!< When gatt server close, the event comes */
- ESP_GATTS_LISTEN_EVT = 19, /*!< When gatt listen to be connected the event comes */
- ESP_GATTS_CONGEST_EVT = 20, /*!< When congest happen, the event comes */
- /* following is extra event */
- ESP_GATTS_RESPONSE_EVT = 21, /*!< When gatt send response complete, the event comes */
+ ESP_GATTS_REG_EVT = 0, /*!< When register application id, the event comes */
+ ESP_GATTS_READ_EVT = 1, /*!< When gatt client request read operation, the event comes */
+ ESP_GATTS_WRITE_EVT = 2, /*!< When gatt client request write operation, the event comes */
+ ESP_GATTS_EXEC_WRITE_EVT = 3, /*!< When gatt client request execute write, the event comes */
+ ESP_GATTS_MTU_EVT = 4, /*!< When set mtu complete, the event comes */
+ ESP_GATTS_CONF_EVT = 5, /*!< When receive confirm, the event comes */
+ ESP_GATTS_UNREG_EVT = 6, /*!< When unregister application id, the event comes */
+ ESP_GATTS_CREATE_EVT = 7, /*!< When create service complete, the event comes */
+ ESP_GATTS_ADD_INCL_SRVC_EVT = 8, /*!< When add included service complete, the event comes */
+ ESP_GATTS_ADD_CHAR_EVT = 9, /*!< When add characteristic complete, the event comes */
+ ESP_GATTS_ADD_CHAR_DESCR_EVT = 10, /*!< When add descriptor complete, the event comes */
+ ESP_GATTS_DELETE_EVT = 11, /*!< When delete service complete, the event comes */
+ ESP_GATTS_START_EVT = 12, /*!< When start service complete, the event comes */
+ ESP_GATTS_STOP_EVT = 13, /*!< When stop service complete, the event comes */
+ ESP_GATTS_CONNECT_EVT = 14, /*!< When gatt client connect, the event comes */
+ ESP_GATTS_DISCONNECT_EVT = 15, /*!< When gatt client disconnect, the event comes */
+ ESP_GATTS_OPEN_EVT = 16, /*!< When connect to peer, the event comes */
+ ESP_GATTS_CANCEL_OPEN_EVT = 17, /*!< When disconnect from peer, the event comes */
+ ESP_GATTS_CLOSE_EVT = 18, /*!< When gatt server close, the event comes */
+ ESP_GATTS_LISTEN_EVT = 19, /*!< When gatt listen to be connected the event comes */
+ ESP_GATTS_CONGEST_EVT = 20, /*!< When congest happen, the event comes */
+ /* following is extra event */
+ ESP_GATTS_RESPONSE_EVT = 21, /*!< When gatt send response complete, the event comes */
+ ESP_GATTS_CREAT_ATTR_TAB_EVT = 22,
+ ESP_GATTS_SET_ATTR_VAL_EVT = 23,
} esp_gatts_cb_event_t;
/**
* @brief ESP_GATTS_REG_EVT
*/
struct gatts_reg_evt_param {
- esp_gatt_status_t status; /*!< Operation status */
- uint16_t app_id; /*!< Application id which input in register API */
- } reg; /*!< Gatt server callback param of ESP_GATTS_REG_EVT */
+ esp_gatt_status_t status; /*!< Operation status */
+ uint16_t app_id; /*!< Application id which input in register API */
+ } reg; /*!< Gatt server callback param of ESP_GATTS_REG_EVT */
/**
* @brief ESP_GATTS_READ_EVT
*/
struct gatts_read_evt_param {
- uint16_t conn_id; /*!< Connection id */
- uint32_t trans_id; /*!< Transfer id */
- esp_bd_addr_t bda; /*!< The bluetooth device address which been read */
- uint16_t handle; /*!< The attribute handle */
- uint16_t offset; /*!< Offset of the value, if the value is too long */
- bool is_long; /*!< The value is too long or not */
- } read; /*!< Gatt server callback param of ESP_GATTS_READ_EVT */
+ uint16_t conn_id; /*!< Connection id */
+ uint32_t trans_id; /*!< Transfer id */
+ esp_bd_addr_t bda; /*!< The bluetooth device address which been read */
+ uint16_t handle; /*!< The attribute handle */
+ uint16_t offset; /*!< Offset of the value, if the value is too long */
+ bool is_long; /*!< The value is too long or not */
+ } read; /*!< Gatt server callback param of ESP_GATTS_READ_EVT */
/**
* @brief ESP_GATTS_WRITE_EVT
*/
struct gatts_write_evt_param {
- uint16_t conn_id; /*!< Connection id */
- uint32_t trans_id; /*!< Transfer id */
- esp_bd_addr_t bda; /*!< The bluetooth device address which been written */
- uint16_t handle; /*!< The attribute handle */
- uint16_t offset; /*!< Offset of the value, if the value is too long */
- bool need_rsp; /*!< The write operation need to do response */
- bool is_prep; /*!< This write operation is prepare write */
- uint16_t len; /*!< The write attribute value length */
- uint8_t *value; /*!< The write attribute value */
- } write; /*!< Gatt server callback param of ESP_GATTS_WRITE_EVT */
+ uint16_t conn_id; /*!< Connection id */
+ uint32_t trans_id; /*!< Transfer id */
+ esp_bd_addr_t bda; /*!< The bluetooth device address which been written */
+ uint16_t handle; /*!< The attribute handle */
+ uint16_t offset; /*!< Offset of the value, if the value is too long */
+ bool need_rsp; /*!< The write operation need to do response */
+ bool is_prep; /*!< This write operation is prepare write */
+ uint16_t len; /*!< The write attribute value length */
+ uint8_t *value; /*!< The write attribute value */
+ } write; /*!< Gatt server callback param of ESP_GATTS_WRITE_EVT */
/**
* @brief ESP_GATTS_EXEC_WRITE_EVT
*/
struct gatts_exec_write_evt_param {
- uint16_t conn_id; /*!< Connection id */
- uint32_t trans_id; /*!< Transfer id */
- esp_bd_addr_t bda; /*!< The bluetooth device address which been written */
-#define ESP_GATT_PREP_WRITE_CANCEL 0x00
-#define ESP_GATT_PREP_WRITE_EXEC 0x01
- uint8_t exec_write_flag; /*!< Execute write flag */
- } exec_write; /*!< Gatt server callback param of ESP_GATTS_EXEC_WRITE_EVT */
+ uint16_t conn_id; /*!< Connection id */
+ uint32_t trans_id; /*!< Transfer id */
+ esp_bd_addr_t bda; /*!< The bluetooth device address which been written */
+#define ESP_GATT_PREP_WRITE_CANCEL 0x00 /*!< Prepare write flag to indicate cancel prepare write */
+#define ESP_GATT_PREP_WRITE_EXEC 0x01 /*!< Prepare write flag to indicate execute prepare write */
+ uint8_t exec_write_flag; /*!< Execute write flag */
+ } exec_write; /*!< Gatt server callback param of ESP_GATTS_EXEC_WRITE_EVT */
/**
* @brief ESP_GATTS_MTU_EVT
*/
struct gatts_mtu_evt_param {
- uint16_t conn_id; /*!< Connection id */
- uint16_t mtu; /*!< MTU size */
- } mtu; /*!< Gatt server callback param of ESP_GATTS_MTU_EVT */
+ uint16_t conn_id; /*!< Connection id */
+ uint16_t mtu; /*!< MTU size */
+ } mtu; /*!< Gatt server callback param of ESP_GATTS_MTU_EVT */
/**
* @brief ESP_GATTS_CONF_EVT
*/
struct gatts_conf_evt_param {
- esp_gatt_status_t status; /*!< Operation status */
- uint16_t conn_id; /*!< Connection id */
- } conf; /*!< Gatt server callback param of ESP_GATTS_CONF_EVT (confirm) */
+ esp_gatt_status_t status; /*!< Operation status */
+ uint16_t conn_id; /*!< Connection id */
+ } conf; /*!< Gatt server callback param of ESP_GATTS_CONF_EVT (confirm) */
/**
* @brief ESP_GATTS_UNREG_EVT
* @brief ESP_GATTS_CREATE_EVT
*/
struct gatts_create_evt_param {
- esp_gatt_status_t status; /*!< Operation status */
- uint16_t service_handle; /*!< Service attribute handle */
- esp_gatt_srvc_id_t service_id; /*!< Service id, include service uuid and other information */
- } create; /*!< Gatt server callback param of ESP_GATTS_CREATE_EVT */
+ esp_gatt_status_t status; /*!< Operation status */
+ uint16_t service_handle; /*!< Service attribute handle */
+ esp_gatt_srvc_id_t service_id; /*!< Service id, include service uuid and other information */
+ } create; /*!< Gatt server callback param of ESP_GATTS_CREATE_EVT */
/**
* @brief ESP_GATTS_ADD_INCL_SRVC_EVT
*/
struct gatts_add_incl_srvc_evt_param {
- esp_gatt_status_t status; /*!< Operation status */
- uint16_t attr_handle; /*!< Included service attribute handle */
- uint16_t service_handle; /*!< Service attribute handle */
- } add_incl_srvc; /*!< Gatt server callback param of ESP_GATTS_ADD_INCL_SRVC_EVT */
+ esp_gatt_status_t status; /*!< Operation status */
+ uint16_t attr_handle; /*!< Included service attribute handle */
+ uint16_t service_handle; /*!< Service attribute handle */
+ } add_incl_srvc; /*!< Gatt server callback param of ESP_GATTS_ADD_INCL_SRVC_EVT */
/**
* @brief ESP_GATTS_ADD_CHAR_EVT
*/
struct gatts_add_char_evt_param {
- esp_gatt_status_t status; /*!< Operation status */
- uint16_t attr_handle; /*!< Characteristic attribute handle */
- uint16_t service_handle; /*!< Service attribute handle */
- esp_bt_uuid_t char_uuid; /*!< Characteristic uuid */
- } add_char; /*!< Gatt server callback param of ESP_GATTS_ADD_CHAR_EVT */
+ esp_gatt_status_t status; /*!< Operation status */
+ uint16_t attr_handle; /*!< Characteristic attribute handle */
+ uint16_t service_handle; /*!< Service attribute handle */
+ esp_bt_uuid_t char_uuid; /*!< Characteristic uuid */
+ } add_char; /*!< Gatt server callback param of ESP_GATTS_ADD_CHAR_EVT */
/**
* @brief ESP_GATTS_ADD_CHAR_DESCR_EVT
*/
struct gatts_add_char_descr_evt_param {
- esp_gatt_status_t status; /*!< Operation status */
- uint16_t attr_handle; /*!< Descriptor attribute handle */
- uint16_t service_handle; /*!< Service attribute handle */
- esp_bt_uuid_t char_uuid; /*!< Characteristic uuid */
- } add_char_descr; /*!< Gatt server callback param of ESP_GATTS_ADD_CHAR_DESCR_EVT */
+ esp_gatt_status_t status; /*!< Operation status */
+ uint16_t attr_handle; /*!< Descriptor attribute handle */
+ uint16_t service_handle; /*!< Service attribute handle */
+ esp_bt_uuid_t char_uuid; /*!< Characteristic uuid */
+ } add_char_descr; /*!< Gatt server callback param of ESP_GATTS_ADD_CHAR_DESCR_EVT */
/**
* @brief ESP_GATTS_DELETE_EVT
*/
struct gatts_delete_evt_param {
- esp_gatt_status_t status; /*!< Operation status */
- uint16_t service_handle; /*!< Service attribute handle */
- } del; /*!< Gatt server callback param of ESP_GATTS_DELETE_EVT */
+ esp_gatt_status_t status; /*!< Operation status */
+ uint16_t service_handle; /*!< Service attribute handle */
+ } del; /*!< Gatt server callback param of ESP_GATTS_DELETE_EVT */
/**
* @brief ESP_GATTS_START_EVT
*/
struct gatts_start_evt_param {
- esp_gatt_status_t status; /*!< Operation status */
- uint16_t service_handle; /*!< Service attribute handle */
- } start; /*!< Gatt server callback param of ESP_GATTS_START_EVT */
+ esp_gatt_status_t status; /*!< Operation status */
+ uint16_t service_handle; /*!< Service attribute handle */
+ } start; /*!< Gatt server callback param of ESP_GATTS_START_EVT */
/**
* @brief ESP_GATTS_STOP_EVT
*/
struct gatts_stop_evt_param {
- esp_gatt_status_t status; /*!< Operation status */
- uint16_t service_handle; /*!< Service attribute handle */
- } stop; /*!< Gatt server callback param of ESP_GATTS_STOP_EVT */
+ esp_gatt_status_t status; /*!< Operation status */
+ uint16_t service_handle; /*!< Service attribute handle */
+ } stop; /*!< Gatt server callback param of ESP_GATTS_STOP_EVT */
/**
* @brief ESP_GATTS_CONNECT_EVT
*/
struct gatts_connect_evt_param {
- uint16_t conn_id; /*!< Connection id */
- esp_bd_addr_t remote_bda; /*!< Remote bluetooth device address */
- bool is_connected; /*!< Indicate it is connected or not */
- } connect; /*!< Gatt server callback param of ESP_GATTS_CONNECT_EVT */
+ uint16_t conn_id; /*!< Connection id */
+ esp_bd_addr_t remote_bda; /*!< Remote bluetooth device address */
+ bool is_connected; /*!< Indicate it is connected or not */
+ } connect; /*!< Gatt server callback param of ESP_GATTS_CONNECT_EVT */
/**
* @brief ESP_GATTS_DISCONNECT_EVT
*/
struct gatts_disconnect_evt_param {
- uint16_t conn_id; /*!< Connection id */
- esp_bd_addr_t remote_bda; /*!< Remote bluetooth device address */
- bool is_connected; /*!< Indicate it is connected or not */
- } disconnect; /*!< Gatt server callback param of ESP_GATTS_DISCONNECT_EVT */
+ uint16_t conn_id; /*!< Connection id */
+ esp_bd_addr_t remote_bda; /*!< Remote bluetooth device address */
+ bool is_connected; /*!< Indicate it is connected or not */
+ } disconnect; /*!< Gatt server callback param of ESP_GATTS_DISCONNECT_EVT */
/**
* @brief ESP_GATTS_OPEN_EVT
* @brief ESP_GATTS_CONGEST_EVT
*/
struct gatts_congest_evt_param {
- uint16_t conn_id; /*!< Connection id */
- bool congested; /*!< Congested or not */
- } congest; /*!< Gatt server callback param of ESP_GATTS_CONGEST_EVT */
+ uint16_t conn_id; /*!< Connection id */
+ bool congested; /*!< Congested or not */
+ } congest; /*!< Gatt server callback param of ESP_GATTS_CONGEST_EVT */
/**
* @brief ESP_GATTS_RESPONSE_EVT
*/
struct gatts_rsp_evt_param {
- esp_gatt_status_t status; /*!< Operation status */
- uint16_t handle; /*!< Attribute handle which send response */
- } rsp; /*!< Gatt server callback param of ESP_GATTS_RESPONSE_EVT */
+ esp_gatt_status_t status; /*!< Operation status */
+ uint16_t handle; /*!< Attribute handle which send response */
+ } rsp; /*!< Gatt server callback param of ESP_GATTS_RESPONSE_EVT */
+
+ /**
+ * @brief ESP_GATTS_CREAT_ATTR_TAB_EVT
+ */
+ struct gatts_add_attr_tab_evt_param{
+ esp_gatt_status_t status; /*!< Operation status */
+ esp_bt_uuid_t svc_uuid; /*!< Service uuid type */
+ uint16_t num_handle; /*!< The number of the attribute handle to be added to the gatts database */
+ uint16_t *handles; /*!< The number to the handles */
+ } add_attr_tab; /*!< Gatt server callback param of ESP_GATTS_CREAT_ATTR_TAB_EVT */
+
+
+ /**
+ * @brief ESP_GATTS_SET_ATTR_VAL_EVT
+ */
+ struct gatts_set_attr_val_evt_param{
+ uint16_t srvc_handle; /*!< The service handle */
+ uint16_t attr_handle; /*!< The attribute handle */
+ esp_gatt_status_t status; /*!< Operation status*/
+ } set_attr_val; /*!< Gatt server callback param of ESP_GATTS_SET_ATTR_VAL_EVT */
+
} esp_ble_gatts_cb_param_t;
/**
esp_gatt_srvc_id_t *service_id, uint16_t num_handle);
-
+/**
+ * @brief Create a service attribute tab.
+ * @param[in] gatts_attr_db: the pointer to the service attr tab
+ * @param[in] gatts_if: GATT server access interface
+ * @param[in] max_nb_attr: the number of attribute to be added to the service database.
+ * @param[in] srvc_inst_id: the instance id of the service
+ *
+ * @return
+ * - ESP_OK : success
+ * - other : failed
+ *
+ */
+esp_err_t esp_ble_gatts_create_attr_tab(const esp_gatts_attr_db_t *gatts_attr_db,
+ esp_gatt_if_t gatts_if,
+ uint8_t max_nb_attr,
+ uint8_t srvc_inst_id);
/**
* @brief This function is called to add an included service. After included
* service is included, a callback event BTA_GATTS_ADD_INCL_SRVC_EVT
* @param[in] char_uuid : Characteristic UUID.
* @param[in] perm : Characteristic value declaration attribute permission.
* @param[in] property : Characteristic Properties
+ * @param[in] char_val : Characteristic value
+ * @param[in] control : attribute response control byte
*
* @return
* - ESP_OK : success
*
*/
esp_err_t esp_ble_gatts_add_char(uint16_t service_handle, esp_bt_uuid_t *char_uuid,
- esp_gatt_perm_t perm, esp_gatt_char_prop_t property);
+ esp_gatt_perm_t perm, esp_gatt_char_prop_t property, esp_attr_value_t *char_val,
+ esp_attr_control_t *control);
/**
* be added.
* @param[in] perm: descriptor access permission.
* @param[in] descr_uuid: descriptor UUID.
- *
+ * @param[in] char_descr_val : Characteristic descriptor value
+ * @param[in] control : attribute response control byte
* @return
* - ESP_OK : success
* - other : failed
*
*/
esp_err_t esp_ble_gatts_add_char_descr (uint16_t service_handle,
- esp_bt_uuid_t *descr_uuid,
- esp_gatt_perm_t perm);
+ esp_bt_uuid_t *descr_uuid,
+ esp_gatt_perm_t perm, esp_attr_value_t *char_descr_val,
+ esp_attr_control_t *control);
esp_gatt_status_t status, esp_gatt_rsp_t *rsp);
+/**
+ * @brief This function is called to set the attribute value by the application
+ *
+ * @param[in] attr_handle: the attribute handle which to be set
+ * @param[in] length: the value length
+ * @param[in] value: the pointer to the attribute value
+ *
+ * @return
+ * - ESP_OK : success
+ * - other : failed
+ *
+ */
+esp_err_t esp_ble_gatts_set_attr_value(uint16_t attr_handle, uint16_t length, const uint8_t *value);
+
+/**
+ * @brief Retrieve attribute value
+ *
+ * @param[in] attr_handle: Attribute handle.
+ * @param[out] length: pointer to the attribute value length
+ * @param[out] value: Pointer to attribute value payload, the value cannot be modified by user
+ *
+ * @return
+ * - ESP_OK : success
+ * - other : failed
+ *
+ */
+esp_err_t esp_ble_gatts_get_attr_value(uint16_t attr_handle, uint16_t *length, const uint8_t **value);
+
+
/**
* @brief Open a direct open connection or add a background auto connection
*
#include "bta_gatts_int.h"
#include "bta_gatts_co.h"
#include "btm_ble_api.h"
-// #include "btif/include/btif_debug_conn.h"
#include <string.h>
static void bta_gatts_nv_save_cback(BOOLEAN is_saved, tGATTS_HNDL_RANGE *p_hndl_range);
UINT16 attr_id = 0;
tBTA_GATTS cb_data;
+ tGATT_ATTR_VAL *p_attr_val = NULL;
+ tGATTS_ATTR_CONTROL *p_control = NULL;
+
+ if (p_msg->api_add_char_descr.attr_val.attr_max_len != 0) {
+ p_attr_val = &p_msg->api_add_char_descr.attr_val;
+ }
+
+ if (p_msg->api_add_char_descr.control.auto_rsp != 0) {
+ p_control = &p_msg->api_add_char_descr.control;
+ }
attr_id = GATTS_AddCharacteristic(p_msg->api_add_char.hdr.layer_specific,
&p_msg->api_add_char.char_uuid,
p_msg->api_add_char.perm,
- p_msg->api_add_char.property);
+ p_msg->api_add_char.property, p_attr_val, p_control);
cb_data.add_result.server_if = p_rcb->gatt_if;
cb_data.add_result.service_id = p_msg->api_add_incl_srvc.hdr.layer_specific;
cb_data.add_result.attr_id = attr_id;
(*p_rcb->p_cback)(BTA_GATTS_ADD_CHAR_EVT, &cb_data);
}
}
+
/*******************************************************************************
**
** Function bta_gatts_add_char_descr
tBTA_GATTS_RCB *p_rcb = &bta_gatts_cb.rcb[p_srvc_cb->rcb_idx];
UINT16 attr_id = 0;
tBTA_GATTS cb_data;
+ tGATT_ATTR_VAL *p_attr_val = NULL;
+ tGATTS_ATTR_CONTROL *p_control = NULL;
+
+ if (p_msg->api_add_char_descr.attr_val.attr_max_len != 0) {
+ p_attr_val = &p_msg->api_add_char_descr.attr_val;
+ }
+ if (p_msg->api_add_char_descr.control.auto_rsp != 0) {
+ p_control = &p_msg->api_add_char_descr.control;
+ }
attr_id = GATTS_AddCharDescriptor(p_msg->api_add_char_descr.hdr.layer_specific,
p_msg->api_add_char_descr.perm,
- &p_msg->api_add_char_descr.descr_uuid);
+ &p_msg->api_add_char_descr.descr_uuid, p_attr_val,
+ p_control);
cb_data.add_result.server_if = p_rcb->gatt_if;
cb_data.add_result.service_id = p_msg->api_add_incl_srvc.hdr.layer_specific;
}
}
+
+/*******************************************************************************
+**
+** Function bta_gatts_add_char_descr
+**
+** Description action function to add characteristic descriptor.
+**
+** Returns none.
+**
+*******************************************************************************/
+void bta_gatts_set_attr_value(tBTA_GATTS_SRVC_CB *p_srvc_cb, tBTA_GATTS_DATA *p_msg)
+{
+ tBTA_GATTS_RCB *p_rcb = &bta_gatts_cb.rcb[p_srvc_cb->rcb_idx];
+ UINT16 attr_id = 0;
+ tBTA_GATTS cb_data;
+ tBTA_GATT_STATUS gatts_status;
+ gatts_status = GATTS_SetAttributeValue(p_msg->api_add_char_descr.hdr.layer_specific,
+ p_msg->api_set_val.length,
+ p_msg->api_set_val.value);
+
+ cb_data.attr_val.server_if = p_rcb->gatt_if;
+ cb_data.attr_val.service_id = p_msg->api_set_val.hdr.layer_specific;
+ cb_data.attr_val.attr_id = attr_id;
+ cb_data.attr_val.status = gatts_status;
+
+ if (p_rcb->p_cback) {
+ (*p_rcb->p_cback)(BTA_GATTS_SET_ATTR_VAL_EVT, &cb_data);
+ }
+}
+
+void bta_gatts_get_attr_value(UINT16 attr_handle, UINT16 *length, UINT8 **value)
+{
+ GATTS_GetAttributeValue(attr_handle, length, value);
+}
+
/*******************************************************************************
**
** Function bta_gatts_delete_service
**
*******************************************************************************/
void BTA_GATTS_AddCharacteristic (UINT16 service_id, tBT_UUID *p_char_uuid,
- tBTA_GATT_PERM perm, tBTA_GATT_CHAR_PROP property)
+ tBTA_GATT_PERM perm, tBTA_GATT_CHAR_PROP property, tGATT_ATTR_VAL *attr_val,
+ tBTA_GATTS_ATTR_CONTROL *control)
{
tBTA_GATTS_API_ADD_CHAR *p_buf;
-
+ UINT16 len = 0;
+ if(attr_val != NULL){
+ len = attr_val->attr_len;
+ }
if ((p_buf = (tBTA_GATTS_API_ADD_CHAR *) GKI_getbuf(sizeof(tBTA_GATTS_API_ADD_CHAR))) != NULL) {
memset(p_buf, 0, sizeof(tBTA_GATTS_API_ADD_CHAR));
p_buf->hdr.layer_specific = service_id;
p_buf->perm = perm;
p_buf->property = property;
+ if(control !=NULL){
+ p_buf->control.auto_rsp = control->auto_rsp;
+ }
+ if(attr_val != NULL){
+ APPL_TRACE_DEBUG("!!!!!!attr_val->attr_len = %x\n",attr_val->attr_len);
+ APPL_TRACE_DEBUG("!!!!!!!attr_val->attr_max_len = %x\n",attr_val->attr_max_len);
+ p_buf->attr_val.attr_len = attr_val->attr_len;
+ p_buf->attr_val.attr_max_len = attr_val->attr_max_len;
+ p_buf->attr_val.attr_val = (uint8_t *)GKI_getbuf(len);
+ if(p_buf->attr_val.attr_val != NULL){
+ memcpy(p_buf->attr_val.attr_val, attr_val->attr_val, attr_val->attr_len);
+ }
+ }
if (p_char_uuid) {
memcpy(&p_buf->char_uuid, p_char_uuid, sizeof(tBT_UUID));
*******************************************************************************/
void BTA_GATTS_AddCharDescriptor (UINT16 service_id,
tBTA_GATT_PERM perm,
- tBT_UUID *p_descr_uuid)
+ tBT_UUID *p_descr_uuid, tBTA_GATT_ATTR_VAL *attr_val,
+ tBTA_GATTS_ATTR_CONTROL *control)
{
tBTA_GATTS_API_ADD_DESCR *p_buf;
- UINT16 len = sizeof(tBTA_GATTS_API_ADD_DESCR);
-
+ UINT16 len = 0;
+ if(attr_val != NULL) {
+ len = sizeof(tBTA_GATTS_API_ADD_DESCR) + attr_val->attr_len;
+ } else {
+ len = sizeof(tBTA_GATTS_API_ADD_DESCR);
+ }
if ((p_buf = (tBTA_GATTS_API_ADD_DESCR *) GKI_getbuf(len)) != NULL) {
memset(p_buf, 0, len);
if (p_descr_uuid) {
memcpy(&p_buf->descr_uuid, p_descr_uuid, sizeof(tBT_UUID));
}
+
+ if(attr_val->attr_len != 0) {
+ p_buf->attr_val.attr_len = attr_val->attr_len;
+ p_buf->attr_val.attr_max_len= attr_val->attr_max_len;
+ memcpy(p_buf->attr_val.attr_val, attr_val->attr_val, attr_val->attr_len);
+ }
+
+ if(control != NULL) {
+ p_buf->control.auto_rsp = control->auto_rsp;
+ }
bta_sys_sendmsg(p_buf);
}
return;
-
}
/*******************************************************************************
}
+void BTA_SetAttributeValue(UINT16 attr_handle, UINT16 length, UINT8 *value)
+{
+ tBTA_GATTS_API_SET_ATTR_VAL *p_buf;
+ if((p_buf = (tBTA_GATTS_API_SET_ATTR_VAL *)GKI_getbuf(
+ sizeof(tBTA_GATTS_API_SET_ATTR_VAL))) != NULL){
+ p_buf->hdr.event = BTA_GATTS_API_SET_ATTR_VAL_EVT;
+ p_buf->hdr.layer_specific = attr_handle;
+ p_buf->length = length;
+ if(value != NULL){
+ if((p_buf->value = (UINT8 *)GKI_getbuf(length)) != NULL){
+ memcpy(p_buf->value, value, length);
+ }
+ }
+
+ bta_sys_sendmsg(p_buf);
+ }
+
+}
+
+void BTA_GetAttributeValue(UINT16 attr_handle, UINT16 *length, UINT8 **value)
+{
+ bta_gatts_get_attr_value(attr_handle, length, value);
+}
/*******************************************************************************
**
case BTA_GATTS_API_RSP_EVT:
bta_gatts_send_rsp(p_cb, (tBTA_GATTS_DATA *) p_msg);
break;
-
+ case BTA_GATTS_API_SET_ATTR_VAL_EVT:{
+ UINT16 attr_id = ((tBTA_GATTS_DATA *) p_msg)->api_set_val.hdr.layer_specific;
+ p_srvc_cb = bta_gatts_find_srvc_cb_by_attr_id(p_cb, attr_id);
+ bta_gatts_set_attr_value(p_srvc_cb, (tBTA_GATTS_DATA *) p_msg);
+ break;
+ }
case BTA_GATTS_API_LISTEN_EVT:
bta_gatts_listen(p_cb, (tBTA_GATTS_DATA *) p_msg);
break;
-
-
case BTA_GATTS_API_ADD_INCL_SRVC_EVT:
case BTA_GATTS_API_ADD_CHAR_EVT:
case BTA_GATTS_API_ADD_DESCR_EVT:
case BTA_GATTS_API_DEL_SRVC_EVT:
case BTA_GATTS_API_START_SRVC_EVT:
case BTA_GATTS_API_STOP_SRVC_EVT:
-
p_srvc_cb = bta_gatts_find_srvc_cb_by_srvc_id(p_cb,
((tBTA_GATTS_DATA *)p_msg)->api_add_incl_srvc.hdr.layer_specific);
if (p_srvc_cb != NULL) {
bta_gatts_srvc_build_act[p_msg->event - BTA_GATTS_API_ADD_INCL_SRVC_EVT](p_srvc_cb, (tBTA_GATTS_DATA *) p_msg);
} else {
- APPL_TRACE_ERROR("service not created");
+ APPL_TRACE_ERROR("service not created\n");
}
break;
-
default:
break;
}
/* Client callback function events */
-#define BTA_GATTC_REG_EVT 0 /* GATT client is registered. */
-#define BTA_GATTC_DEREG_EVT 1 /* GATT client deregistered event */
-#define BTA_GATTC_OPEN_EVT 2 /* GATTC open request status event */
-#define BTA_GATTC_READ_CHAR_EVT 3 /* GATT read characteristic event */
-#define BTA_GATTC_WRITE_CHAR_EVT 4 /* GATT write characteristic or char descriptor event */
-#define BTA_GATTC_CLOSE_EVT 5 /* GATTC close request status event */
-#define BTA_GATTC_SEARCH_CMPL_EVT 6 /* GATT discovery complete event */
-#define BTA_GATTC_SEARCH_RES_EVT 7 /* GATT discovery result event */
-#define BTA_GATTC_READ_DESCR_EVT 8 /* GATT read characterisitc descriptor event */
-#define BTA_GATTC_WRITE_DESCR_EVT 9 /* GATT write characteristic descriptor event */
-#define BTA_GATTC_NOTIF_EVT 10 /* GATT attribute notification event */
-#define BTA_GATTC_PREP_WRITE_EVT 11 /* GATT prepare write event */
-#define BTA_GATTC_EXEC_EVT 12 /* execute write complete event */
-#define BTA_GATTC_ACL_EVT 13 /* ACL up event */
-#define BTA_GATTC_CANCEL_OPEN_EVT 14 /* cancel open event */
-#define BTA_GATTC_SRVC_CHG_EVT 15 /* service change event */
-#define BTA_GATTC_LISTEN_EVT 16 /* listen event */
-#define BTA_GATTC_ENC_CMPL_CB_EVT 17 /* encryption complete callback event */
-#define BTA_GATTC_CFG_MTU_EVT 18 /* configure MTU complete event */
-#define BTA_GATTC_ADV_DATA_EVT 19 /* ADV data event */
-#define BTA_GATTC_MULT_ADV_ENB_EVT 20 /* Enable Multi ADV event */
-#define BTA_GATTC_MULT_ADV_UPD_EVT 21 /* Update parameter event */
-#define BTA_GATTC_MULT_ADV_DATA_EVT 22 /* Multi ADV data event */
-#define BTA_GATTC_MULT_ADV_DIS_EVT 23 /* Disable Multi ADV event */
-#define BTA_GATTC_CONGEST_EVT 24 /* Congestion event */
-#define BTA_GATTC_BTH_SCAN_ENB_EVT 25 /* Enable batch scan event */
-#define BTA_GATTC_BTH_SCAN_CFG_EVT 26 /* Config storage event */
-#define BTA_GATTC_BTH_SCAN_RD_EVT 27 /* Batch scan reports read event */
-#define BTA_GATTC_BTH_SCAN_THR_EVT 28 /* Batch scan threshold event */
-#define BTA_GATTC_BTH_SCAN_PARAM_EVT 29 /* Batch scan param event */
-#define BTA_GATTC_BTH_SCAN_DIS_EVT 30 /* Disable batch scan event */
-#define BTA_GATTC_SCAN_FLT_CFG_EVT 31 /* Scan filter config event */
-#define BTA_GATTC_SCAN_FLT_PARAM_EVT 32 /* Param filter event */
-#define BTA_GATTC_SCAN_FLT_STATUS_EVT 33 /* Filter status event */
-#define BTA_GATTC_ADV_VSC_EVT 34 /* ADV VSC event */
+#define BTA_GATTC_REG_EVT 0 /* GATT client is registered. */
+#define BTA_GATTC_DEREG_EVT 1 /* GATT client deregistered event */
+#define BTA_GATTC_OPEN_EVT 2 /* GATTC open request status event */
+#define BTA_GATTC_READ_CHAR_EVT 3 /* GATT read characteristic event */
+#define BTA_GATTC_WRITE_CHAR_EVT 4 /* GATT write characteristic or char descriptor event */
+#define BTA_GATTC_CLOSE_EVT 5 /* GATTC close request status event */
+#define BTA_GATTC_SEARCH_CMPL_EVT 6 /* GATT discovery complete event */
+#define BTA_GATTC_SEARCH_RES_EVT 7 /* GATT discovery result event */
+#define BTA_GATTC_READ_DESCR_EVT 8 /* GATT read characterisitc descriptor event */
+#define BTA_GATTC_WRITE_DESCR_EVT 9 /* GATT write characteristic descriptor event */
+#define BTA_GATTC_NOTIF_EVT 10 /* GATT attribute notification event */
+#define BTA_GATTC_PREP_WRITE_EVT 11 /* GATT prepare write event */
+#define BTA_GATTC_EXEC_EVT 12 /* execute write complete event */
+#define BTA_GATTC_ACL_EVT 13 /* ACL up event */
+#define BTA_GATTC_CANCEL_OPEN_EVT 14 /* cancel open event */
+#define BTA_GATTC_SRVC_CHG_EVT 15 /* service change event */
+#define BTA_GATTC_LISTEN_EVT 16 /* listen event */
+#define BTA_GATTC_ENC_CMPL_CB_EVT 17 /* encryption complete callback event */
+#define BTA_GATTC_CFG_MTU_EVT 18 /* configure MTU complete event */
+#define BTA_GATTC_ADV_DATA_EVT 19 /* ADV data event */
+#define BTA_GATTC_MULT_ADV_ENB_EVT 20 /* Enable Multi ADV event */
+#define BTA_GATTC_MULT_ADV_UPD_EVT 21 /* Update parameter event */
+#define BTA_GATTC_MULT_ADV_DATA_EVT 22 /* Multi ADV data event */
+#define BTA_GATTC_MULT_ADV_DIS_EVT 23 /* Disable Multi ADV event */
+#define BTA_GATTC_CONGEST_EVT 24 /* Congestion event */
+#define BTA_GATTC_BTH_SCAN_ENB_EVT 25 /* Enable batch scan event */
+#define BTA_GATTC_BTH_SCAN_CFG_EVT 26 /* Config storage event */
+#define BTA_GATTC_BTH_SCAN_RD_EVT 27 /* Batch scan reports read event */
+#define BTA_GATTC_BTH_SCAN_THR_EVT 28 /* Batch scan threshold event */
+#define BTA_GATTC_BTH_SCAN_PARAM_EVT 29 /* Batch scan param event */
+#define BTA_GATTC_BTH_SCAN_DIS_EVT 30 /* Disable batch scan event */
+#define BTA_GATTC_SCAN_FLT_CFG_EVT 31 /* Scan filter config event */
+#define BTA_GATTC_SCAN_FLT_PARAM_EVT 32 /* Param filter event */
+#define BTA_GATTC_SCAN_FLT_STATUS_EVT 33 /* Filter status event */
+#define BTA_GATTC_ADV_VSC_EVT 34 /* ADV VSC event */
typedef UINT8 tBTA_GATTC_EVT;
typedef struct {
UINT16 unit; /* as UUIUD defined by SIG */
- UINT16 descr; /* as UUID as defined by SIG */
+ UINT16 descr; /* as UUID as defined by SIG */
tGATT_FORMAT format;
INT8 exp;
UINT8 name_spc; /* The name space of the description */
/* characteristic descriptor: server configuration value
*/
#define BTA_GATT_SVR_CONFIG_NONE GATT_SVR_CONFIG_NONE /* 0x0000 */
-#define BTA_GATT_SVR_CONFIG_BROADCAST GATT_SVR_CONFIG_BROADCAST /* 0x0001 */
+#define BTA_GATT_SVR_CONFIG_BROADCAST GATT_SVR_CONFIG_BROADCAST /* 0x0001 */
typedef UINT16 tBTA_GATT_SVR_CHAR_CONFIG;
/* Characteristic Aggregate Format attribute value
// btla-specific --
typedef struct {
- tBTA_GATTC_IF client_if;
- BD_ADDR remote_bda;
+ tBTA_GATTC_IF client_if;
+ BD_ADDR remote_bda;
} tBTA_GATTC_ENC_CMPL_CB;
typedef union {
/* Client callback function */
typedef void (tBTA_GATTC_CBACK)(tBTA_GATTC_EVT event, tBTA_GATTC *p_data);
-
/* GATT Server Data Structure */
/* Server callback function events */
#define BTA_GATTS_REG_EVT 0
#define BTA_GATTS_CLOSE_EVT 18
#define BTA_GATTS_LISTEN_EVT 19
#define BTA_GATTS_CONGEST_EVT 20
+#define BTA_GATTS_SET_ATTR_VAL_EVT 21
typedef UINT8 tBTA_GATTS_EVT;
typedef tGATT_IF tBTA_GATTS_IF;
#define BTA_GATT_PERM_WRITE_SIGNED GATT_PERM_WRITE_SIGNED /* bit 7 - 0x0080 */
#define BTA_GATT_PERM_WRITE_SIGNED_MITM GATT_PERM_WRITE_SIGNED_MITM /* bit 8 - 0x0100 */
typedef UINT16 tBTA_GATT_PERM;
+typedef tGATT_ATTR_VAL tBTA_GATT_ATTR_VAL;
+typedef tGATTS_ATTR_CONTROL tBTA_GATTS_ATTR_CONTROL;
#define BTA_GATTS_INVALID_APP 0xff
#define BTA_GATTS_INVALID_IF 0
/* definition of characteristic properties */
-#define BTA_GATT_CHAR_PROP_BIT_BROADCAST GATT_CHAR_PROP_BIT_BROADCAST /* 0x01 */
-#define BTA_GATT_CHAR_PROP_BIT_READ GATT_CHAR_PROP_BIT_READ /* 0x02 */
-#define BTA_GATT_CHAR_PROP_BIT_WRITE_NR GATT_CHAR_PROP_BIT_WRITE_NR /* 0x04 */
-#define BTA_GATT_CHAR_PROP_BIT_WRITE GATT_CHAR_PROP_BIT_WRITE /* 0x08 */
-#define BTA_GATT_CHAR_PROP_BIT_NOTIFY GATT_CHAR_PROP_BIT_NOTIFY /* 0x10 */
-#define BTA_GATT_CHAR_PROP_BIT_INDICATE GATT_CHAR_PROP_BIT_INDICATE /* 0x20 */
-#define BTA_GATT_CHAR_PROP_BIT_AUTH GATT_CHAR_PROP_BIT_AUTH /* 0x40 */
-#define BTA_GATT_CHAR_PROP_BIT_EXT_PROP GATT_CHAR_PROP_BIT_EXT_PROP /* 0x80 */
+#define BTA_GATT_CHAR_PROP_BIT_BROADCAST GATT_CHAR_PROP_BIT_BROADCAST /* 0x01 */
+#define BTA_GATT_CHAR_PROP_BIT_READ GATT_CHAR_PROP_BIT_READ /* 0x02 */
+#define BTA_GATT_CHAR_PROP_BIT_WRITE_NR GATT_CHAR_PROP_BIT_WRITE_NR /* 0x04 */
+#define BTA_GATT_CHAR_PROP_BIT_WRITE GATT_CHAR_PROP_BIT_WRITE /* 0x08 */
+#define BTA_GATT_CHAR_PROP_BIT_NOTIFY GATT_CHAR_PROP_BIT_NOTIFY /* 0x10 */
+#define BTA_GATT_CHAR_PROP_BIT_INDICATE GATT_CHAR_PROP_BIT_INDICATE /* 0x20 */
+#define BTA_GATT_CHAR_PROP_BIT_AUTH GATT_CHAR_PROP_BIT_AUTH /* 0x40 */
+#define BTA_GATT_CHAR_PROP_BIT_EXT_PROP GATT_CHAR_PROP_BIT_EXT_PROP /* 0x80 */
typedef UINT8 tBTA_GATT_CHAR_PROP;
#ifndef BTA_GATTC_CHAR_DESCR_MAX
typedef tGATTS_SRV_CHG_REQ tBTA_GATTS_SRV_CHG_REQ;
typedef tGATTS_SRV_CHG_RSP tBTA_GATTS_SRV_CHG_RSP;
-#define BTA_GATT_TRANSPORT_LE GATT_TRANSPORT_LE
-#define BTA_GATT_TRANSPORT_BR_EDR GATT_TRANSPORT_BR_EDR
+#define BTA_GATT_TRANSPORT_LE GATT_TRANSPORT_LE
+#define BTA_GATT_TRANSPORT_BR_EDR GATT_TRANSPORT_BR_EDR
#define BTA_GATT_TRANSPORT_LE_BR_EDR GATT_TRANSPORT_LE_BR_EDR
typedef UINT8 tBTA_GATT_TRANSPORT;
// btla-specific --
} tBTA_GATTS_ADD_RESULT;
+typedef struct{
+ tBTA_GATTS_IF server_if;
+ UINT16 service_id;
+ UINT16 attr_id;
+ tBTA_GATT_STATUS status;
+}tBAT_GATTS_ATTR_VAL_RESULT;
+
typedef struct {
tBTA_GATTS_IF server_if;
UINT16 service_id;
/* GATTS callback data */
typedef union {
- tBTA_GATTS_REG_OPER reg_oper;
- tBTA_GATTS_CREATE create;
- tBTA_GATTS_SRVC_OPER srvc_oper;
- tBTA_GATT_STATUS status; /* BTA_GATTS_LISTEN_EVT */
- tBTA_GATTS_ADD_RESULT add_result; /* add included service: BTA_GATTS_ADD_INCL_SRVC_EVT
- add char : BTA_GATTS_ADD_CHAR_EVT
- add char descriptor: BTA_GATTS_ADD_CHAR_DESCR_EVT */
- tBTA_GATTS_REQ req_data;
- tBTA_GATTS_CONN conn; /* BTA_GATTS_CONN_EVT */
- tBTA_GATTS_CONGEST congest; /* BTA_GATTS_CONGEST_EVT callback data */
- tBTA_GATTS_CONF confirm; /* BTA_GATTS_CONF_EVT callback data */
+ tBTA_GATTS_REG_OPER reg_oper;
+ tBTA_GATTS_CREATE create;
+ tBTA_GATTS_SRVC_OPER srvc_oper;
+ tBTA_GATT_STATUS status; /* BTA_GATTS_LISTEN_EVT */
+ tBTA_GATTS_ADD_RESULT add_result; /* add included service: BTA_GATTS_ADD_INCL_SRVC_EVT
+ add char : BTA_GATTS_ADD_CHAR_EVT
+ add char descriptor: BTA_GATTS_ADD_CHAR_DESCR_EVT */
+ tBAT_GATTS_ATTR_VAL_RESULT attr_val;
+ tBTA_GATTS_REQ req_data;
+ tBTA_GATTS_CONN conn; /* BTA_GATTS_CONN_EVT */
+ tBTA_GATTS_CONGEST congest; /* BTA_GATTS_CONGEST_EVT callback data */
+ tBTA_GATTS_CONF confirm; /* BTA_GATTS_CONF_EVT callback data */
} tBTA_GATTS;
/* GATTS enable callback function */
** Returns None
**
*******************************************************************************/
-extern void BTA_GATTS_AddCharacteristic (UINT16 service_id, tBT_UUID *p_char_uuid,
- tBTA_GATT_PERM perm, tBTA_GATT_CHAR_PROP property);
+extern void BTA_GATTS_AddCharacteristic (UINT16 service_id, tBT_UUID *p_char_uuid,
+ tBTA_GATT_PERM perm, tBTA_GATT_CHAR_PROP property, tGATT_ATTR_VAL *attr_val,
+ tBTA_GATTS_ATTR_CONTROL *control);
/*******************************************************************************
**
**
*******************************************************************************/
extern void BTA_GATTS_AddCharDescriptor (UINT16 service_id,
- tBTA_GATT_PERM perm,
- tBT_UUID *p_descr_uuid);
+ tBTA_GATT_PERM perm,
+ tBT_UUID *p_descr_uuid, tBTA_GATT_ATTR_VAL *attr_val,
+ tBTA_GATTS_ATTR_CONTROL *control);
/*******************************************************************************
**
tBTA_GATT_STATUS status, tBTA_GATTS_RSP *p_msg);
+
+/*******************************************************************************
+**
+** Function BTA_SetAttributeValue
+**
+** Description This function is called to set the attribute value in the gatt database
+**
+** Parameters attr_handle - the attribute value handle.
+** length - the value length which has been set to the attribute.
+** value - the pointer to the value
+**
+** Returns None
+**
+*******************************************************************************/
+extern void BTA_SetAttributeValue(UINT16 attr_handle, UINT16 length, UINT8 *value);
+
+
+/*******************************************************************************
+**
+** Function BTA_GetAttributeValue
+**
+** Description This function is called to get the attribute value in the gatt database
+**
+** Parameters attr_handle - the attribute value handle.
+** length - the value length which has been set to the attribute.
+** value - the pointer to the value
+**
+** Returns None
+**
+*******************************************************************************/
+extern void BTA_GetAttributeValue(UINT16 attr_handle, UINT16 *length, UINT8 **value);
+
/*******************************************************************************
**
** Function BTA_GATTS_Open
BTA_GATTS_API_START_SRVC_EVT,
BTA_GATTS_API_STOP_SRVC_EVT,
BTA_GATTS_API_RSP_EVT,
+ BTA_GATTS_API_SET_ATTR_VAL_EVT,
BTA_GATTS_API_OPEN_EVT,
BTA_GATTS_API_CANCEL_OPEN_EVT,
BTA_GATTS_API_CLOSE_EVT,
tBT_UUID char_uuid;
tBTA_GATT_PERM perm;
tBTA_GATT_CHAR_PROP property;
-
+ tBTA_GATTS_ATTR_CONTROL control;
+ tBTA_GATT_ATTR_VAL attr_val;
} tBTA_GATTS_API_ADD_CHAR;
typedef struct {
BT_HDR hdr;
UINT16 included_service_id;
-
} tBTA_GATTS_API_ADD_INCL_SRVC;
typedef struct {
- BT_HDR hdr;
- tBT_UUID descr_uuid;
- tBTA_GATT_PERM perm;
+ BT_HDR hdr;
+ tBT_UUID descr_uuid;
+ tBTA_GATT_PERM perm;
+ tBTA_GATTS_ATTR_CONTROL control;
+ tBTA_GATT_ATTR_VAL attr_val;
} tBTA_GATTS_API_ADD_DESCR;
typedef struct {
tBTA_GATTS_RSP *p_rsp;
} tBTA_GATTS_API_RSP;
+typedef struct{
+ BT_HDR hdr;
+ UINT16 length;
+ UINT8 *value;
+}tBTA_GATTS_API_SET_ATTR_VAL;
+
typedef struct {
BT_HDR hdr;
tBTA_GATT_TRANSPORT transport;
tBTA_GATTS_API_START api_start;
tBTA_GATTS_API_INDICATION api_indicate;
tBTA_GATTS_API_RSP api_rsp;
+ tBTA_GATTS_API_SET_ATTR_VAL api_set_val;
tBTA_GATTS_API_OPEN api_open;
tBTA_GATTS_API_CANCEL_OPEN api_cancel_open;
BOOLEAN in_use;
tBT_UUID app_uuid;
tBTA_GATTS_CBACK *p_cback;
- tBTA_GATTS_IF gatt_if;
+ tBTA_GATTS_IF gatt_if;
} tBTA_GATTS_RCB;
/* service registration control block */
extern void bta_gatts_add_include_srvc(tBTA_GATTS_SRVC_CB *p_srvc_cb, tBTA_GATTS_DATA *p_msg);
extern void bta_gatts_add_char(tBTA_GATTS_SRVC_CB *p_srvc_cb, tBTA_GATTS_DATA *p_msg);
extern void bta_gatts_add_char_descr(tBTA_GATTS_SRVC_CB *p_srvc_cb, tBTA_GATTS_DATA *p_msg);
+extern void bta_gatts_set_attr_value(tBTA_GATTS_SRVC_CB *p_srvc_cb, tBTA_GATTS_DATA *p_msg);
+extern void bta_gatts_get_attr_value(UINT16 attr_handle, UINT16 *length, UINT8 **value);
extern void bta_gatts_delete_service(tBTA_GATTS_SRVC_CB *p_srvc_cb, tBTA_GATTS_DATA *p_msg);
extern void bta_gatts_start_service(tBTA_GATTS_SRVC_CB *p_srvc_cb, tBTA_GATTS_DATA *p_msg);
extern void bta_gatts_stop_service(tBTA_GATTS_SRVC_CB *p_srvc_cb, tBTA_GATTS_DATA *p_msg);
tBTA_GATTS_RSP rsp;
LOG_DEBUG("blufi profile cb event = %x\n", event);
+
switch (event) {
case BTA_GATTS_REG_EVT:
LOG_DEBUG("REG: status %d, app_uuid %04x, gatt_if %d\n", p_data->reg_oper.status, p_data->reg_oper.uuid.uu.uuid16, p_data->reg_oper.server_if);
//add the frist blufi characteristic --> write characteristic
BTA_GATTS_AddCharacteristic(blufi_env.handle_srvc, &blufi_char_uuid_p2e,
(GATT_PERM_WRITE),
- (GATT_CHAR_PROP_BIT_WRITE));
+ (GATT_CHAR_PROP_BIT_WRITE),
+ NULL, NULL);
break;
case BTA_GATTS_ADD_CHAR_EVT:
switch (p_data->add_result.char_uuid.uu.uuid16) {
BTA_GATTS_AddCharacteristic(blufi_env.handle_srvc, &blufi_char_uuid_e2p,
(GATT_PERM_READ),
- (GATT_PERM_READ | GATT_CHAR_PROP_BIT_NOTIFY));
+ (GATT_PERM_READ | GATT_CHAR_PROP_BIT_NOTIFY),
+ NULL, NULL);
break;
case BLUFI_CHAR_E2P_UUID: /* ESP32 to Phone */
blufi_env.handle_char_e2p = p_data->add_result.attr_id;
BTA_GATTS_AddCharDescriptor (blufi_env.handle_srvc,
(GATT_PERM_READ | GATT_PERM_WRITE),
- &blufi_descr_uuid_e2p);
+ &blufi_descr_uuid_e2p,
+ NULL, NULL);
break;
default:
break;
#include "btc_manage.h"
#include "btc_gatts.h"
#include "btc_gatt_util.h"
-
+#include "future.h"
+#include "btc_main.h"
#include "esp_gatts_api.h"
#define A2C_GATTS_EVT(_bta_event) (_bta_event) //BTA TO BTC EVT
#define C2A_GATTS_EVT(_btc_event) (_btc_event) //BTC TO BTA EVT
+typedef struct {
+ future_t *complete_future;
+ uint16_t svc_start_hdl;
+ esp_bt_uuid_t svc_uuid;
+ bool is_tab_creat_svc;
+ uint8_t num_handle;
+ uint8_t handle_idx;
+ uint16_t handles[ESP_GATT_ATTR_HANDLE_MAX];
+} esp_btc_creat_tab_t;
+
+static esp_btc_creat_tab_t btc_creat_tab_env;
+
static inline void btc_gatts_cb_to_app(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param)
{
esp_gatts_cb_t btc_gatts_cb = (esp_gatts_cb_t)btc_profile_cb_get(BTC_PID_GATTS);
if (btc_gatts_cb) {
- btc_gatts_cb(event, gatts_if, param);
+ btc_gatts_cb(event, gatts_if, param);
}
}
}
}
break;
+
+ }
+ case BTC_GATTS_ACT_ADD_CHAR:{
+ if (src->add_char.char_val.attr_value != NULL){
+ dst->add_char.char_val.attr_value = (uint8_t *)GKI_getbuf(src->add_char.char_val.attr_len);
+ if(dst->add_char.char_val.attr_value != NULL){
+ memcpy(dst->add_char.char_val.attr_value, src->add_char.char_val.attr_value,
+ src->add_char.char_val.attr_len);
+ }else{
+ LOG_ERROR("%s %d no mem\n", __func__, msg->act);
+ }
+ }
+ break;
+ }
+ case BTC_GATTS_ACT_ADD_CHAR_DESCR:{
+ if(src->add_descr.descr_val.attr_value != NULL){
+ dst->add_descr.descr_val.attr_value = (uint8_t *)GKI_getbuf(src->add_descr.descr_val.attr_len);
+ if(dst->add_descr.descr_val.attr_value != NULL){
+ memcpy(dst->add_descr.descr_val.attr_value, src->add_descr.descr_val.attr_value,
+ src->add_descr.descr_val.attr_len);
+ }else{
+ LOG_ERROR("%s %d no mem\n", __func__, msg->act);
+ }
+ }
+ break;
+ }
+ case BTC_GATTS_ACT_CREATE_ATTR_TAB:{
+ uint8_t num_attr = src->create_attr_tab.max_nb_attr;
+ if(src->create_attr_tab.gatts_attr_db != NULL){
+ dst->create_attr_tab.gatts_attr_db = (esp_gatts_attr_db_t *)GKI_getbuf(sizeof(esp_gatts_attr_db_t)*num_attr);
+ if(dst->create_attr_tab.gatts_attr_db != NULL){
+ memcpy(dst->create_attr_tab.gatts_attr_db, src->create_attr_tab.gatts_attr_db,
+ sizeof(esp_gatts_attr_db_t)*num_attr);
+ }else{
+ LOG_ERROR("%s %d no mem\n",__func__, msg->act);
+ }
+ }
+ break;
+ }
+ case BTC_GATTS_ACT_SET_ATTR_VALUE:{
+ uint8_t len = src->set_attr_val.length;
+ if(src->set_attr_val.value){
+ dst->set_attr_val.value = (uint8_t *)GKI_getbuf(len);
+ if(dst->set_attr_val.value != NULL){
+ memcpy(dst->set_attr_val.value, src->set_attr_val.value, len);
+ }else{
+ LOG_ERROR("%s %d no mem\n",__func__, msg->act);
+ }
+ }
+ break;
}
default:
LOG_DEBUG("%s Unhandled deep copy %d\n", __func__, msg->act);
}
+static void btc_gatts_act_create_attr_tab(esp_gatts_attr_db_t *gatts_attr_db,
+ esp_gatt_if_t gatts_if,
+ uint8_t max_nb_attr,
+ uint8_t srvc_inst_id)
+{
+ uint16_t uuid = 0;
+ future_t *future_p;
+ esp_ble_gatts_cb_param_t param;
+
+ //set the attribute table create service flag to ture
+ btc_creat_tab_env.is_tab_creat_svc = true;
+ btc_creat_tab_env.num_handle = max_nb_attr;
+ for(int i = 0; i < max_nb_attr; i++){
+ if(gatts_attr_db[i].att_desc.uuid.len == ESP_UUID_LEN_16){
+ uuid = gatts_attr_db[i].att_desc.uuid.uuid.uuid16;
+ }
+ future_p = future_new();
+ if (future_p == NULL) {
+ LOG_ERROR("%s failed:no mem\n", __func__);
+ return ;
+ }
+ btc_creat_tab_env.complete_future = future_p;
+ btc_creat_tab_env.handle_idx = i;
+ switch(uuid)
+ {
+ case ESP_GATT_UUID_PRI_SERVICE:{
+ tBTA_GATT_SRVC_ID srvc_id;
+ esp_gatt_srvc_id_t esp_srvc_id;
+
+ esp_srvc_id.id.inst_id = srvc_inst_id;
+ memcpy(&esp_srvc_id.id.uuid, &gatts_attr_db[i].att_desc.uuid, sizeof(esp_bt_uuid_t));
+ btc_to_bta_srvc_id(&srvc_id, &esp_srvc_id);
+ BTA_GATTS_CreateService(gatts_if, &srvc_id.id.uuid,
+ srvc_inst_id, max_nb_attr, true);
+
+ if (future_await(future_p) == FUTURE_FAIL) {
+ LOG_ERROR("%s failed\n", __func__);
+ return;
+ }
+ break;
+ }
+ case ESP_GATT_UUID_SEC_SERVICE:{
+ tBTA_GATT_SRVC_ID srvc_id;
+ esp_gatt_srvc_id_t esp_srvc_id;
+
+ esp_srvc_id.id.inst_id = srvc_inst_id;
+ memcpy(&esp_srvc_id.id.uuid, &gatts_attr_db[i].att_desc.uuid, sizeof(esp_bt_uuid_t));
+ btc_to_bta_srvc_id(&srvc_id, &esp_srvc_id);
+ BTA_GATTS_CreateService(gatts_if, &srvc_id.id.uuid,
+ srvc_inst_id, max_nb_attr, false);
+ if (future_await(future_p) == FUTURE_FAIL) {
+ LOG_ERROR("%s failed\n", __func__);
+ return;
+ }
+ break;
+ }
+ case ESP_GATT_UUID_INCLUDE_SERVICE:{
+ esp_gatts_incl_svc_desc_t *incl_svc_desc = (esp_gatts_incl_svc_desc_t *)gatts_attr_db[i].att_desc.value;
+
+ if(incl_svc_desc!= NULL){
+ if(btc_creat_tab_env.svc_start_hdl != 0){
+ BTA_GATTS_AddIncludeService(btc_creat_tab_env.svc_start_hdl,
+ incl_svc_desc->start_hdl);
+
+ if (future_await(future_p) == FUTURE_FAIL) {
+ LOG_ERROR("%s failed\n", __func__);
+ return;
+ }
+ }
+ }
+ break;
+ }
+ case ESP_GATT_UUID_CHAR_DECLARE:{
+ uint16_t svc_hal = 0;
+ tBT_UUID bta_char_uuid;
+ tGATT_ATTR_VAL attr_val;
+ tBTA_GATT_PERM perm;
+ tBTA_GATTS_ATTR_CONTROL control;
+
+ if(btc_creat_tab_env.svc_start_hdl != 0){
+ svc_hal = btc_creat_tab_env.svc_start_hdl;
+ esp_gatts_char_desc_t *char_desc = (esp_gatts_char_desc_t *)gatts_attr_db[i].att_desc.value;
+ if(char_desc != NULL){
+ perm = gatts_attr_db[i+1].att_desc.perm;
+ attr_val.attr_len = gatts_attr_db[i+1].att_desc.length;
+ attr_val.attr_max_len = gatts_attr_db[i+1].att_desc.max_length;
+ btc_to_bta_uuid(&bta_char_uuid, &char_desc->attr_uuid);
+ attr_val.attr_val = gatts_attr_db[i+1].att_desc.value;
+ control.auto_rsp = gatts_attr_db[i+1].attr_control.auto_rsp;
+ BTA_GATTS_AddCharacteristic (svc_hal, &bta_char_uuid,
+ perm, char_desc->prop, &attr_val, &control);
+
+ if (future_await(future_p) == FUTURE_FAIL) {
+ LOG_ERROR("%s failed\n", __func__);
+ return;
+ }
+ }
+ }
+
+ break;
+ }
+ case ESP_GATT_UUID_CHAR_EXT_PROP:
+ case ESP_GATT_UUID_CHAR_DESCRIPTION:
+ case ESP_GATT_UUID_CHAR_CLIENT_CONFIG:
+ case ESP_GATT_UUID_CHAR_SRVR_CONFIG:
+ case ESP_GATT_UUID_CHAR_PRESENT_FORMAT:
+ case ESP_GATT_UUID_CHAR_AGG_FORMAT:
+ case ESP_GATT_UUID_CHAR_VALID_RANGE:
+ case ESP_GATT_UUID_EXT_RPT_REF_DESCR:
+ case ESP_GATT_UUID_RPT_REF_DESCR:{
+ uint16_t svc_hal = btc_creat_tab_env.svc_start_hdl;
+ tBT_UUID bta_char_uuid;
+ tGATT_ATTR_VAL attr_val;
+ tBTA_GATT_PERM perm = gatts_attr_db[i].att_desc.perm;
+ tBTA_GATTS_ATTR_CONTROL control;
+
+ if(svc_hal != 0){
+ attr_val.attr_len = gatts_attr_db[i].att_desc.length;
+ attr_val.attr_max_len = gatts_attr_db[i].att_desc.max_length;
+ attr_val.attr_val = gatts_attr_db[i].att_desc.value;
+ btc_to_bta_uuid(&bta_char_uuid, &gatts_attr_db[i].att_desc.uuid);
+ control.auto_rsp = gatts_attr_db[i].attr_control.auto_rsp;
+ BTA_GATTS_AddCharDescriptor(svc_hal, perm, &bta_char_uuid, &attr_val, &control);
+
+ if (future_await(future_p) == FUTURE_FAIL) {
+ LOG_ERROR("%s failed\n", __func__);
+ return;
+ }
+ }
+ break;
+ }
+ default:
+ break;
+ }
+
+
+ }
+
+ param.add_attr_tab.status = ESP_GATT_OK;
+ param.add_attr_tab.num_handle = max_nb_attr;
+ param.add_attr_tab.handles = btc_creat_tab_env.handles;
+ memcpy(¶m.add_attr_tab.svc_uuid, &btc_creat_tab_env.svc_uuid, sizeof(esp_bt_uuid_t));
+
+ btc_gatts_cb_to_app(ESP_GATTS_CREAT_ATTR_TAB_EVT, gatts_if, ¶m);
+ //reset the env after sent the data to app
+ memset(&btc_creat_tab_env, 0, sizeof(esp_btc_creat_tab_t));
+
+ //release the flag vaule to false after finish the service created.
+ btc_creat_tab_env.is_tab_creat_svc = false;
+}
+
+void btc_gatts_get_attr_value(uint16_t attr_handle, uint16_t *length, uint8_t **value)
+{
+
+ BTA_GetAttributeValue(attr_handle, length, value);
+}
+
static void btc_gatts_cb_param_copy_req(btc_msg_t *msg, void *p_dest, void *p_src)
{
GKI_freebuf(p_data->req_data.p_data);
}
break;
-
default:
break;
}
{
bt_status_t status;
btc_msg_t msg;
-
+
msg.sig = BTC_SIG_API_CB;
msg.pid = BTC_PID_GATTS;
msg.act = event;
+ if(btc_creat_tab_env.is_tab_creat_svc && btc_creat_tab_env.complete_future){
+ switch(event){
+ case BTA_GATTS_CREATE_EVT:{
+ //save the service handle to the btc module after used
+ //the attribute table method to creat a service
+ bta_to_btc_uuid(&btc_creat_tab_env.svc_uuid, &p_data->create.uuid);
+ uint8_t index = btc_creat_tab_env.handle_idx;
+ btc_creat_tab_env.svc_start_hdl = p_data->create.service_id;
+ btc_creat_tab_env.handles[index] = p_data->create.service_id;
+ break;
+ }
+ case BTA_GATTS_ADD_INCL_SRVC_EVT:{
+ uint8_t index = btc_creat_tab_env.handle_idx;
+ btc_creat_tab_env.handles[index] = p_data->add_result.attr_id;
+ break;
+ }
+ case BTA_GATTS_ADD_CHAR_EVT:{
+ uint8_t index = btc_creat_tab_env.handle_idx;
+ btc_creat_tab_env.handles[index] = p_data->add_result.attr_id - 1;
+ btc_creat_tab_env.handles[index+1] = p_data->add_result.attr_id;
+ break;
+ }
+ case BTA_GATTS_ADD_CHAR_DESCR_EVT:{
+ uint8_t index = btc_creat_tab_env.handle_idx;
+ btc_creat_tab_env.handles[index] = p_data->add_result.attr_id;
+ break;
+ }
+ default:
+ break;
+ }
+ future_ready(btc_creat_tab_env.complete_future, FUTURE_SUCCESS);
+ }
status = btc_transfer_context(&msg, p_data,
sizeof(tBTA_GATTS), btc_gatts_cb_param_copy_req);
srvc_id.is_primary);
break;
}
+ case BTC_GATTS_ACT_CREATE_ATTR_TAB:
+ btc_gatts_act_create_attr_tab(arg->create_attr_tab.gatts_attr_db,
+ arg->create_attr_tab.gatts_if,
+ arg->create_attr_tab.max_nb_attr,
+ arg->create_attr_tab.srvc_inst_id);
+ break;
case BTC_GATTS_ACT_DELETE_SERVICE:
BTA_GATTS_DeleteService(arg->delete_srvc.service_handle);
break;
btc_to_bta_uuid(&uuid, &arg->add_char.char_uuid);
BTA_GATTS_AddCharacteristic(arg->add_char.service_handle, &uuid,
- arg->add_char.perm, arg->add_char.property);
+ arg->add_char.perm, arg->add_char.property,
+ (tGATT_ATTR_VAL *)&arg->add_char.char_val,
+ (tBTA_GATTS_ATTR_CONTROL *)&arg->add_char.attr_control);
break;
}
case BTC_GATTS_ACT_ADD_CHAR_DESCR: {
tBT_UUID uuid;
btc_to_bta_uuid(&uuid, &arg->add_descr.descr_uuid);
- BTA_GATTS_AddCharDescriptor(arg->add_descr.service_handle, arg->add_descr.perm, &uuid);
+ BTA_GATTS_AddCharDescriptor(arg->add_descr.service_handle, arg->add_descr.perm, &uuid,
+ (tBTA_GATT_ATTR_VAL *)&arg->add_descr.descr_val,
+ (tBTA_GATTS_ATTR_CONTROL *)&arg->add_descr.attr_control);
break;
}
case BTC_GATTS_ACT_SEND_INDICATE:
btc_gatts_cb_to_app(ESP_GATTS_RESPONSE_EVT, BTC_GATT_GET_GATT_IF(arg->send_rsp.conn_id), ¶m);
break;
}
+ case BTC_GATTS_ACT_SET_ATTR_VALUE:
+
+ break;
case BTC_GATTS_ACT_OPEN: {
// Ensure device is in inquiry database
tBTA_GATT_TRANSPORT transport = BTA_GATT_TRANSPORT_LE;
param.create.service_id.is_primary = p_data->create.is_primary;
param.create.service_id.id.inst_id = p_data->create.svc_instance;
bta_to_btc_uuid(¶m.create.service_id.id.uuid, &p_data->create.uuid);
+
btc_gatts_cb_to_app(ESP_GATTS_CREATE_EVT, gatts_if, ¶m);
break;
case BTA_GATTS_ADD_INCL_SRVC_EVT:
gatts_if = p_data->srvc_oper.server_if;
param.del.status = p_data->srvc_oper.status;
param.del.service_handle = p_data->srvc_oper.service_id;
+
btc_gatts_cb_to_app(ESP_GATTS_DELETE_EVT, gatts_if, ¶m);
break;
case BTA_GATTS_START_EVT:
btc_gatts_cb_to_app(ESP_GATTS_DISCONNECT_EVT, gatts_if, ¶m);
break;
case BTA_GATTS_OPEN_EVT:
- // do nothing
+ // do nothing
case BTA_GATTS_CANCEL_OPEN_EVT:
- // do nothing
+ // do nothing
case BTA_GATTS_CLOSE_EVT:
- // do nothing
+ // do nothing
case BTA_GATTS_LISTEN_EVT:
// do nothing
break;
param.congest.congested = p_data->congest.congested;
btc_gatts_cb_to_app(ESP_GATTS_CONGEST_EVT, gatts_if, ¶m);
break;
+ case BTA_GATTS_SET_ATTR_VAL_EVT:
+ gatts_if = p_data->attr_val.server_if;
+ param.set_attr_val.srvc_handle = p_data->attr_val.service_id;
+ param.set_attr_val.attr_handle = p_data->attr_val.attr_id;
+ param.set_attr_val.status = p_data->attr_val.status;
+ btc_gatts_cb_to_app(ESP_GATTS_SET_ATTR_VAL_EVT, gatts_if, ¶m);
+ break;
default:
// do nothing
break;
BTC_GATTS_ACT_APP_REGISTER = 0,
BTC_GATTS_ACT_APP_UNREGISTER,
BTC_GATTS_ACT_CREATE_SERVICE,
+ BTC_GATTS_ACT_CREATE_ATTR_TAB,
BTC_GATTS_ACT_DELETE_SERVICE,
BTC_GATTS_ACT_START_SERVICE,
BTC_GATTS_ACT_STOP_SERVICE,
BTC_GATTS_ACT_ADD_CHAR_DESCR,
BTC_GATTS_ACT_SEND_INDICATE,
BTC_GATTS_ACT_SEND_RESPONSE,
+ BTC_GATTS_ACT_SET_ATTR_VALUE,
BTC_GATTS_ACT_OPEN,
BTC_GATTS_ACT_CLOSE,
} btc_gatts_act_t;
struct app_reg_args {
uint16_t app_id;
} app_reg;
+
//BTC_GATTS_ACT_APP_UNREGISTER,
struct app_unreg_args {
esp_gatt_if_t gatts_if;
} app_unreg;
+
//BTC_GATTS_ACT_CREATE_SERVICE,
struct create_srvc_args {
esp_gatt_if_t gatts_if;
esp_gatt_srvc_id_t service_id;
uint16_t num_handle;
} create_srvc;
+
+ //BTC_GATTS_ACT_CREATE_ATTR_TAB
+ struct create_attr_tab_args{
+ esp_gatt_if_t gatts_if;
+ uint8_t srvc_inst_id;
+ uint8_t max_nb_attr;
+ esp_gatts_attr_db_t *gatts_attr_db;
+ }create_attr_tab;
+
//BTC_GATTS_ACT_DELETE_SERVICE,
struct delete_srvc_args {
uint16_t service_handle;
} delete_srvc;
+
//BTC_GATTS_ACT_START_SERVICE,
struct start_srvc_args {
uint16_t service_handle;
} start_srvc;
+
//BTC_GATTS_ACT_STOP_SERVICE,
struct stop_srvc_args {
uint16_t service_handle;
} stop_srvc;
+
//BTC_GATTS_ACT_ADD_INCLUDE_SERVICE,
struct add_incl_srvc_args {
uint16_t service_handle;
uint16_t included_service_handle;
} add_incl_srvc;
+
//BTC_GATTS_ACT_ADD_CHAR,
struct add_char_args {
uint16_t service_handle;
esp_bt_uuid_t char_uuid;
esp_gatt_perm_t perm;
esp_gatt_char_prop_t property;
+ esp_attr_control_t attr_control;
+ esp_attr_value_t char_val;
} add_char;
+
//BTC_GATTS_ACT_ADD_CHAR_DESCR,
struct add_descr_args {
- uint16_t service_handle;
+ uint16_t service_handle;
esp_bt_uuid_t descr_uuid;
esp_gatt_perm_t perm;
+ esp_attr_control_t attr_control;
+ esp_attr_value_t descr_val;
} add_descr;
+
//BTC_GATTS_ACT_SEND_INDICATE,
struct send_indicate_args {
uint16_t conn_id;
uint16_t value_len;
uint8_t *value;
} send_ind;
+
//BTC_GATTS_ACT_SEND_RESPONSE,
struct send_rsp_args {
uint16_t conn_id;
esp_gatt_status_t status;
esp_gatt_rsp_t *rsp;
} send_rsp;
+
+ //BTC_GATTS_SET_ATTR_VALUE
+ struct set_attr_val_args{
+ uint16_t length;
+ uint8_t *value;
+ } set_attr_val;
+
//BTC_GATTS_ACT_OPEN,
struct open_args {
esp_gatt_if_t gatts_if;
esp_bd_addr_t remote_bda;
bool is_direct;
} open;
+
//BTC_GATTS_ACT_CLOSE,
struct close_args {
uint16_t conn_id;
} close;
+
} btc_ble_gatts_args_t;
void btc_gatts_call_handler(btc_msg_t *msg);
void btc_gatts_cb_handler(btc_msg_t *msg);
void btc_gatts_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src);
+void btc_gatts_get_attr_value(uint16_t attr_handle, uint16_t *length, uint8_t **value);
+
#endif /* __BTC_GATTS_H__ */
LOG_DEBUG("%s found unfinished packet for handle with start packet. Dropping old.\n", __func__);
LOG_DEBUG("partial_packet->len = %x, offset = %x\n", partial_packet->len, partial_packet->len);
- //for (int i = 0; i < partial_packet->len; i++) {
- // LOG_ERROR("%x", partial_packet->data[i]);
- //}
- //LOG_ERROR("\n");
+
hash_map_erase(partial_packets, (void *)(uintptr_t)handle);
- //buffer_allocator->free(partial_packet);
- //LOG_ERROR("+++++++++++++++++++\n");
+
+
}
uint16_t full_length = l2cap_length + L2CAP_HEADER_SIZE + HCI_ACL_PREAMBLE_SIZE;
*/
uuid.len = LEN_UUID_16;
uuid.uu.uuid16 = p_db_attr->uuid = GATT_UUID_GAP_DEVICE_NAME;
- p_db_attr->handle = GATTS_AddCharacteristic(service_handle, &uuid, GATT_PERM_READ, GATT_CHAR_PROP_BIT_READ);
+ p_db_attr->handle = GATTS_AddCharacteristic(service_handle, &uuid, GATT_PERM_READ, GATT_CHAR_PROP_BIT_READ,
+ NULL, NULL);
p_db_attr ++;
/* add Icon characteristic
p_db_attr->handle = GATTS_AddCharacteristic(service_handle,
&uuid,
GATT_PERM_READ,
- GATT_CHAR_PROP_BIT_READ);
+ GATT_CHAR_PROP_BIT_READ,
+ NULL, NULL);
p_db_attr ++;
#if ((defined BTM_PERIPHERAL_ENABLED) && (BTM_PERIPHERAL_ENABLED == TRUE))
p_db_attr->handle = GATTS_AddCharacteristic(service_handle,
&uuid,
GATT_PERM_READ,
- GATT_CHAR_PROP_BIT_READ);
+ GATT_CHAR_PROP_BIT_READ,
+ NULL, NULL);
p_db_attr ++;
#endif
uuid.len = LEN_UUID_16;
uuid.uu.uuid16 = p_db_attr->uuid = GATT_UUID_GAP_CENTRAL_ADDR_RESOL;
p_db_attr->handle = GATTS_AddCharacteristic(service_handle, &uuid,
- GATT_PERM_READ, GATT_CHAR_PROP_BIT_READ);
+ GATT_PERM_READ, GATT_CHAR_PROP_BIT_READ,
+ NULL, NULL);
p_db_attr->attr_value.addr_resolution = 0;
p_db_attr++;
tBT_UUID *p_app_uuid128;
- GATT_TRACE_API ("GATTS_CreateService" );
+ GATT_TRACE_API ("GATTS_CreateService\n" );
if (p_reg == NULL) {
- GATT_TRACE_ERROR ("Inavlid gatt_if=%d", gatt_if);
+ GATT_TRACE_ERROR ("Inavlid gatt_if=%d\n", gatt_if);
return (0);
}
if ((p_list = gatt_find_hdl_buffer_by_app_id(p_app_uuid128, p_svc_uuid, svc_inst)) != NULL) {
s_hdl = p_list->asgn_range.s_handle;
- GATT_TRACE_DEBUG ("Service already been created!!");
+ GATT_TRACE_DEBUG ("Service already been created!!\n");
} else {
if ( (p_svc_uuid->len == LEN_UUID_16) && (p_svc_uuid->uu.uuid16 == UUID_SERVCLASS_GATT_SERVER)) {
s_hdl = gatt_cb.hdl_cfg.gatt_start_hdl;
/* check for space */
if (num_handles > (0xFFFF - s_hdl + 1)) {
- GATT_TRACE_ERROR ("GATTS_ReserveHandles: no handles, s_hdl: %u needed: %u", s_hdl, num_handles);
+ GATT_TRACE_ERROR ("GATTS_ReserveHandles: no handles, s_hdl: %u needed: %u\n", s_hdl, num_handles);
return (0);
}
if ( (p_list = gatt_alloc_hdl_buffer()) == NULL) {
/* No free entry */
- GATT_TRACE_ERROR ("GATTS_ReserveHandles: no free handle blocks");
+ GATT_TRACE_ERROR ("GATTS_ReserveHandles: no free handle blocks\n");
return (0);
}
/* add a pending new service change item to the list */
if ( (p_buf = gatt_add_pending_new_srv_start(&p_list->asgn_range)) == NULL) {
/* No free entry */
- GATT_TRACE_ERROR ("gatt_add_pending_new_srv_start: no free blocks");
+ GATT_TRACE_ERROR ("gatt_add_pending_new_srv_start: no free blocks\n");
if (p_list) {
gatt_remove_an_item_from_list(p_list_info, p_list);
return (0);
}
- GATT_TRACE_DEBUG ("Add a new srv chg item");
+ GATT_TRACE_DEBUG ("Add a new srv chg item\n");
}
}
if (!gatts_init_service_db(&p_list->svc_db, p_svc_uuid, is_pri, s_hdl , num_handles)) {
- GATT_TRACE_ERROR ("GATTS_ReserveHandles: service DB initialization failed");
+ GATT_TRACE_ERROR ("GATTS_ReserveHandles: service DB initialization failed\n");
if (p_list) {
gatt_remove_an_item_from_list(p_list_info, p_list);
gatt_free_hdl_buffer(p_list);
return (0);
}
- GATT_TRACE_DEBUG ("GATTS_CreateService(success): handles needed:%u s_hdl=%u e_hdl=%u %s[%x] is_primary=%d",
- num_handles, p_list->asgn_range.s_handle , p_list->asgn_range.e_handle,
- ((p_list->asgn_range.svc_uuid.len == 2) ? "uuid16" : "uuid128" ),
- p_list->asgn_range.svc_uuid.uu.uuid16,
- p_list->asgn_range.is_primary);
-
return (s_hdl);
}
**
*******************************************************************************/
UINT16 GATTS_AddCharacteristic (UINT16 service_handle, tBT_UUID *p_char_uuid,
- tGATT_PERM perm, tGATT_CHAR_PROP property)
+ tGATT_PERM perm, tGATT_CHAR_PROP property,
+ tGATT_ATTR_VAL *attr_val, tGATTS_ATTR_CONTROL *control)
{
tGATT_HDL_LIST_ELEM *p_decl;
if ((p_decl = gatt_find_hdl_buffer_by_handle(service_handle)) == NULL) {
- GATT_TRACE_DEBUG("Service not created");
+ GATT_TRACE_DEBUG("Service not created\n");
return 0;
}
/* data validity checking */
if ( ((property & GATT_CHAR_PROP_BIT_AUTH) && !(perm & GATT_WRITE_SIGNED_PERM)) ||
((perm & GATT_WRITE_SIGNED_PERM) && !(property & GATT_CHAR_PROP_BIT_AUTH)) ) {
- GATT_TRACE_DEBUG("Invalid configuration property=0x%x perm=0x%x ", property, perm);
+ GATT_TRACE_DEBUG("Invalid configuration property=0x%x perm=0x%x\n ", property, perm);
return 0;
}
return gatts_add_characteristic(&p_decl->svc_db,
perm,
property,
- p_char_uuid);
+ p_char_uuid,
+ attr_val, control);
}
/*******************************************************************************
**
*******************************************************************************/
UINT16 GATTS_AddCharDescriptor (UINT16 service_handle,
tGATT_PERM perm,
- tBT_UUID *p_descr_uuid)
+ tBT_UUID *p_descr_uuid, tGATT_ATTR_VAL *attr_val, tGATTS_ATTR_CONTROL *control)
{
tGATT_HDL_LIST_ELEM *p_decl;
return gatts_add_char_descr(&p_decl->svc_db,
perm,
- p_descr_uuid);
+ p_descr_uuid,
+ attr_val, control);
}
/*******************************************************************************
gatt_add_a_srv_to_list(&gatt_cb.srv_list_info, &gatt_cb.srv_list[i_sreg]);
- GATT_TRACE_DEBUG ("allocated i_sreg=%d ", i_sreg);
+ GATT_TRACE_DEBUG ("allocated i_sreg=%d\n", i_sreg);
- GATT_TRACE_DEBUG ("s_hdl=%d e_hdl=%d type=0x%x svc_inst=%d sdp_hdl=0x%x",
+ GATT_TRACE_DEBUG ("s_hdl=%d e_hdl=%d type=0x%x svc_inst=%d sdp_hdl=0x%x\n",
p_sreg->s_hdl, p_sreg->e_hdl,
p_sreg->type, p_sreg->service_instance,
p_sreg->sdp_handle);
tGATT_REG *p_reg = gatt_get_regcb(gatt_if);
tGATT_TCB *p_tcb = gatt_get_tcb_by_idx(tcb_idx);
- GATT_TRACE_API ("GATTS_SendRsp: conn_id: %u trans_id: %u Status: 0x%04x",
+ GATT_TRACE_API ("GATTS_SendRsp: conn_id: %u trans_id: %u Status: 0x%04x\n",
conn_id, trans_id, status);
if ( (p_reg == NULL) || (p_tcb == NULL)) {
- GATT_TRACE_ERROR ("GATTS_SendRsp Unknown conn_id: %u ", conn_id);
+ GATT_TRACE_ERROR ("GATTS_SendRsp Unknown conn_id: %u\n", conn_id);
return (tGATT_STATUS) GATT_INVALID_CONN_ID;
}
if (p_tcb->sr_cmd.trans_id != trans_id) {
- GATT_TRACE_ERROR ("GATTS_SendRsp conn_id: %u waiting for op_code = %02x",
+ GATT_TRACE_ERROR ("GATTS_SendRsp conn_id: %u waiting for op_code = %02x\n",
conn_id, p_tcb->sr_cmd.op_code);
return (GATT_WRONG_STATE);
return cmd_sent;
}
+
+/*******************************************************************************
+**
+** Function GATTS_SetAttributeValue
+**
+** Description This function sends to set the attribute value .
+**
+** Parameter attr_handle:the attribute handle
+** length: the attribute length
+** value: the value to be set to the attribute in the database
+**
+** Returns GATT_SUCCESS if successfully sent; otherwise error code.
+**
+*******************************************************************************/
+tGATT_STATUS GATTS_SetAttributeValue(UINT16 attr_handle, UINT16 length, UINT8 *value)
+{
+ tGATT_STATUS status;
+ tGATT_HDL_LIST_ELEM *p_decl = NULL;
+
+ GATT_TRACE_DEBUG("GATTS_SetAttributeValue: attr_handle: %u length: %u \n",
+ attr_handle, length);
+
+ if ((p_decl = gatt_find_hdl_buffer_by_attr_handle(attr_handle)) == NULL) {
+ GATT_TRACE_DEBUG("Service not created\n");
+ return GATT_INVALID_HANDLE;
+ }
+
+ status = gatts_set_attribute_value(&p_decl->svc_db, attr_handle, length, value);
+ return status;
+
+}
+
+
+/*******************************************************************************
+**
+** Function GATTS_GetAttributeValue
+**
+** Description This function sends to set the attribute value .
+**
+** Parameter attr_handle: the attribute handle
+** length:the attribute value length in the database
+** value: the attribute value out put
+**
+** Returns GATT_SUCCESS if successfully sent; otherwise error code.
+**
+*******************************************************************************/
+tGATT_STATUS GATTS_GetAttributeValue(UINT16 attr_handle, UINT16 *length, UINT8 **value)
+{
+ tGATT_STATUS status;
+ tGATT_HDL_LIST_ELEM *p_decl;
+
+ GATT_TRACE_DEBUG("GATTS_GetAttributeValue: attr_handle: %u\n",
+ attr_handle);
+
+ if ((p_decl = gatt_find_hdl_buffer_by_attr_handle(attr_handle)) == NULL) {
+ GATT_TRACE_ERROR("Service not created\n");
+ return GATT_INVALID_HANDLE;
+ }
+
+ status = gatts_get_attribute_value(&p_decl->svc_db, attr_handle, length, value);
+ return status;
+}
+
/*******************************************************************************/
/* GATT Profile Srvr Functions */
/*******************************************************************************/
break;
}
}
- GATT_TRACE_API ("allocated gatt_if=%d", gatt_if);
+ GATT_TRACE_API ("allocated gatt_if=%d\n", gatt_if);
return gatt_if;
}
GATT_StartIf(gatt_cb.gatt_if);
service_handle = GATTS_CreateService (gatt_cb.gatt_if , &uuid, 0, GATTP_MAX_ATTR_NUM, TRUE);
+ GATT_TRACE_ERROR ("GATTS_CreateService: handle of service handle%x", service_handle);
+
/* add Service Changed characteristic
*/
uuid.uu.uuid16 = gatt_cb.gattp_attr.uuid = GATT_UUID_GATT_SRV_CHGD;
gatt_cb.gattp_attr.service_change = 0;
gatt_cb.gattp_attr.handle =
- gatt_cb.handle_of_h_r = GATTS_AddCharacteristic(service_handle, &uuid, 0, GATT_CHAR_PROP_BIT_INDICATE);
+ gatt_cb.handle_of_h_r = GATTS_AddCharacteristic(service_handle, &uuid, 0, GATT_CHAR_PROP_BIT_INDICATE,
+ NULL, NULL);
- GATT_TRACE_DEBUG ("gatt_profile_db_init: handle of service changed%d",
- gatt_cb.handle_of_h_r );
+ GATT_TRACE_DEBUG ("gatt_profile_db_init: handle of service changed%d\n",
+ gatt_cb.handle_of_h_r);
/* start service
*/
status = GATTS_StartService (gatt_cb.gatt_if, service_handle, GATTP_TRANSPORT_SUPPORTED );
- GATT_TRACE_DEBUG ("gatt_profile_db_init: gatt_if=%d start status%d",
+ GATT_TRACE_DEBUG ("gatt_profile_db_init: gatt_if=%d start status%d\n",
gatt_cb.gatt_if, status);
}
GKI_init_q(&p_db->svc_buffer);
if (!allocate_svc_db_buf(p_db)) {
- GATT_TRACE_ERROR("gatts_init_service_db failed, no resources");
+ GATT_TRACE_ERROR("gatts_init_service_db failed, no resources\n");
return FALSE;
}
- GATT_TRACE_DEBUG("gatts_init_service_db");
- GATT_TRACE_DEBUG("s_hdl = %d num_handle = %d", s_hdl, num_handle );
+ GATT_TRACE_DEBUG("gatts_init_service_db\n");
+ GATT_TRACE_DEBUG("s_hdl = %d num_handle = %d\n", s_hdl, num_handle );
/* update service database information */
p_db->next_handle = s_hdl;
tBT_UUID *gatts_get_service_uuid (tGATT_SVC_DB *p_db)
{
if (!p_db || !p_db->p_attr_list) {
- GATT_TRACE_ERROR("service DB empty");
+ GATT_TRACE_ERROR("service DB empty\n");
return NULL;
} else {
}
if (!(perm & GATT_READ_ALLOWED)) {
- GATT_TRACE_ERROR( "GATT_READ_NOT_PERMIT");
+ GATT_TRACE_ERROR( "GATT_READ_NOT_PERMIT\n");
return GATT_READ_NOT_PERMIT;
}
if ((perm & GATT_READ_AUTH_REQUIRED ) && !(sec_flag & GATT_SEC_FLAG_LKEY_UNAUTHED) &&
!(sec_flag & BTM_SEC_FLAG_ENCRYPTED)) {
- GATT_TRACE_ERROR( "GATT_INSUF_AUTHENTICATION");
+ GATT_TRACE_ERROR( "GATT_INSUF_AUTHENTICATION\n");
return GATT_INSUF_AUTHENTICATION;
}
if ((perm & GATT_READ_MITM_REQUIRED ) && !(sec_flag & GATT_SEC_FLAG_LKEY_AUTHED)) {
- GATT_TRACE_ERROR( "GATT_INSUF_AUTHENTICATION: MITM Required");
+ GATT_TRACE_ERROR( "GATT_INSUF_AUTHENTICATION: MITM Required\n");
return GATT_INSUF_AUTHENTICATION;
}
if ((perm & GATT_READ_ENCRYPTED_REQUIRED ) && !(sec_flag & GATT_SEC_FLAG_ENCRYPTED)) {
- GATT_TRACE_ERROR( "GATT_INSUF_ENCRYPTION");
+ GATT_TRACE_ERROR( "GATT_INSUF_ENCRYPTION\n");
return GATT_INSUF_ENCRYPTION;
}
if ( (perm & GATT_READ_ENCRYPTED_REQUIRED) && (sec_flag & GATT_SEC_FLAG_ENCRYPTED) && (key_size < min_key_size)) {
- GATT_TRACE_ERROR( "GATT_INSUF_KEY_SIZE");
+ GATT_TRACE_ERROR( "GATT_INSUF_KEY_SIZE\n");
return GATT_INSUF_KEY_SIZE;
}
case GATT_UUID_CHAR_CLIENT_CONFIG:
case GATT_UUID_CHAR_SRVR_CONFIG:
case GATT_UUID_CHAR_PRESENT_FORMAT:
- GATT_TRACE_ERROR("GATT_NOT_LONG");
+ GATT_TRACE_ERROR("GATT_NOT_LONG\n");
return GATT_NOT_LONG;
default:
tGATT_STATUS status;
tGATT_ATTR16 *p_attr16 = (tGATT_ATTR16 *)p_attr;
- GATT_TRACE_DEBUG("read_attr_value uuid=0x%04x perm=0x%0x sec_flag=0x%x offset=%d read_long=%d",
+ GATT_TRACE_DEBUG("read_attr_value uuid=0x%04x perm=0x%0x sec_flag=0x%x offset=%d read_long=%d\n",
p_attr16->uuid,
p_attr16->permission,
sec_flag,
status = GATT_SUCCESS;
}
} else { /* characteristic description or characteristic value */
- status = GATT_PENDING;
+ if (p_attr16->control.auto_rsp == GATT_RSP_BY_STACK) {
+ GATT_TRACE_DEBUG("before characteristic description or characteristic value\n");
+ if (p_attr16->p_value != NULL && p_attr16->p_value->attr_val.attr_val != NULL) {
+ uint8_t *value = p_attr16->p_value->attr_val.attr_val + offset;
+ GATT_TRACE_DEBUG("after characteristic description or characteristic value\n");
+ if (mtu >= p_attr16->p_value->attr_val.attr_len) {
+ ARRAY_TO_STREAM(p, value, p_attr16->p_value->attr_val.attr_len);
+ } else {
+ ARRAY_TO_STREAM(p, value, mtu);
+ }
+ }
+ status = GATT_STACK_RSP;
+
+ } else {
+ status = GATT_PENDING;
+ }
}
*p_len = len;
status = read_attr_value ((void *)p_attr, 0, &p, FALSE, (UINT16)(*p_len - 2), &len, sec_flag, key_size);
- if (status == GATT_PENDING) {
+ if (status == GATT_PENDING || status == GATT_STACK_RSP) {
status = gatts_send_app_read_request(p_tcb, op_code, p_attr->handle, 0, trans_id);
/* one callback at a time */
*******************************************************************************/
UINT16 gatts_add_characteristic (tGATT_SVC_DB *p_db, tGATT_PERM perm,
tGATT_CHAR_PROP property,
- tBT_UUID *p_char_uuid)
+ tBT_UUID *p_char_uuid, tGATT_ATTR_VAL *attr_val, tGATTS_ATTR_CONTROL *control)
{
tGATT_ATTR16 *p_char_decl, *p_char_val;
tBT_UUID uuid = {LEN_UUID_16, {GATT_UUID_CHAR_DECLARE}};
- GATT_TRACE_DEBUG("gatts_add_characteristic perm=0x%0x property=0x%0x", perm, property);
+ GATT_TRACE_DEBUG("gatts_add_characteristic perm=0x%0x property=0x%0x\n", perm, property);
if ((p_char_decl = (tGATT_ATTR16 *)allocate_attr_in_db(p_db, &uuid, GATT_PERM_READ)) != NULL) {
if (!copy_extra_byte_in_db(p_db, (void **)&p_char_decl->p_value, sizeof(tGATT_CHAR_DECL))) {
p_char_decl->p_value->char_decl.property = property;
p_char_decl->p_value->char_decl.char_val_handle = p_char_val->handle;
+ if (control != NULL) {
+ p_char_val->control.auto_rsp = control->auto_rsp;
+ } else {
+ p_char_val->control.auto_rsp = GATT_RSP_DEFAULT;
- p_char_val->p_value = NULL;
+ }
+
+ if (attr_val != NULL) {
+ if (!copy_extra_byte_in_db(p_db, (void **)&p_char_val->p_value, sizeof(tGATT_ATTR_VAL))) {
+ deallocate_attr_in_db(p_db, p_char_val);
+ return 0;
+ }
+ GATT_TRACE_DEBUG("attr_val->attr_len = %x, attr_val->attr_max_len = %x\n", attr_val->attr_len, attr_val->attr_max_len);
+ GATT_TRACE_DEBUG("attribute handle = %x\n", p_char_val->handle);
+ p_char_val->p_value->attr_val.attr_len = attr_val->attr_len;
+ p_char_val->p_value->attr_val.attr_max_len = attr_val->attr_max_len;
+ p_char_val->p_value->attr_val.attr_val = GKI_getbuf(attr_val->attr_max_len);
+ if (p_char_val->p_value->attr_val.attr_val != NULL) {
+ GATT_TRACE_DEBUG("attribute value not NULL");
+ memcpy(p_char_val->p_value->attr_val.attr_val, attr_val->attr_val, attr_val->attr_len);
+ }
+ } else {
+ p_char_val->p_value = NULL;
+ }
return p_char_val->handle;
}
**
*******************************************************************************/
UINT16 gatts_add_char_descr (tGATT_SVC_DB *p_db, tGATT_PERM perm,
- tBT_UUID *p_descr_uuid)
+ tBT_UUID *p_descr_uuid, tGATT_ATTR_VAL *attr_val, tGATTS_ATTR_CONTROL *control)
{
tGATT_ATTR16 *p_char_dscptr;
- GATT_TRACE_DEBUG("gatts_add_char_descr uuid=0x%04x", p_descr_uuid->uu.uuid16);
+ GATT_TRACE_DEBUG("gatts_add_char_descr uuid=0x%04x\n", p_descr_uuid->uu.uuid16);
/* Add characteristic descriptors */
- if ((p_char_dscptr = (tGATT_ATTR16 *)allocate_attr_in_db(p_db,
- p_descr_uuid,
- perm))
- == NULL) {
+ if ((p_char_dscptr = (tGATT_ATTR16 *)allocate_attr_in_db(p_db, p_descr_uuid, perm)) == NULL) {
GATT_TRACE_DEBUG("gatts_add_char_descr Fail for adding char descriptors.");
return 0;
} else {
+ if (control != NULL) {
+ p_char_dscptr->control.auto_rsp = control->auto_rsp;
+ }
+ if (attr_val != NULL) {
+ if (!copy_extra_byte_in_db(p_db, (void **)&p_char_dscptr->p_value, sizeof(tGATT_ATTR_VAL))) {
+ deallocate_attr_in_db(p_db, p_char_dscptr);
+ return 0;
+ }
+ p_char_dscptr->p_value->attr_val.attr_len = attr_val->attr_len;
+ p_char_dscptr->p_value->attr_val.attr_max_len = attr_val->attr_max_len;
+ if (attr_val->attr_val != NULL) {
+ p_char_dscptr->p_value->attr_val.attr_val = GKI_getbuf(attr_val->attr_max_len);
+ if (p_char_dscptr->p_value->attr_val.attr_val != NULL) {
+ memset(p_char_dscptr->p_value->attr_val.attr_val, 0, attr_val->attr_max_len);
+ memcpy(p_char_dscptr->p_value->attr_val.attr_val, attr_val->attr_val, attr_val->attr_len);
+ }
+ }
+ }
return p_char_dscptr->handle;
}
}
+
+/*******************************************************************************
+**
+** Function gatts_set_attribute_value
+**
+** Description This function add the attribute value in the database
+**
+** Parameter p_db: database pointer.
+** attr_handle: the attribute handle
+** length: the attribute value length
+** value: the pointer to the data to be set to the attribute value in the database
+**
+** Returns Status of the operation.
+**
+*******************************************************************************/
+tGATT_STATUS gatts_set_attribute_value(tGATT_SVC_DB *p_db, UINT16 attr_handle,
+ UINT16 length, UINT8 *value)
+{
+ tGATT_ATTR16 *p_cur, *p_next;
+
+ if (p_db == NULL) {
+ GATT_TRACE_DEBUG("gatts_set_attribute_value Fail:p_db is NULL.\n");
+ return GATT_INVALID_PDU;
+ }
+ if (p_db->p_attr_list == NULL) {
+ GATT_TRACE_DEBUG("gatts_set_attribute_value Fail:p_db->p_attr_list is NULL.\n");
+ return GATT_INVALID_PDU;
+ }
+
+ p_cur = (tGATT_ATTR16 *) p_db->p_attr_list;
+ p_next = (tGATT_ATTR16 *) p_cur->p_next;
+
+
+ for (; p_cur != NULL; p_cur = p_next, p_next = (tGATT_ATTR16 *)p_next->p_next) {
+ if (p_cur->handle == attr_handle) {
+ if (p_cur->uuid_type == GATT_ATTR_UUID_TYPE_16) {
+ switch (p_cur->uuid) {
+ case GATT_UUID_CHAR_DECLARE:
+ case GATT_UUID_INCLUDE_SERVICE:
+ return GATT_NOT_FOUND;
+ default:
+ if (p_cur->p_value->attr_val.attr_max_len < length) {
+ GATT_TRACE_ERROR("gatts_set_attribute_vaule failt:Invalid value length");
+ } else {
+ memcpy(p_cur->p_value->attr_val.attr_val, value, length);
+ p_cur->p_value->attr_val.attr_len = length;
+ }
+ break;
+ }
+ } else {
+ if (p_cur->p_value->attr_val.attr_max_len < length) {
+ GATT_TRACE_ERROR("gatts_set_attribute_vaule failt:Invalid value length");
+ } else {
+ memcpy(p_cur->p_value->attr_val.attr_val, value, length);
+ p_cur->p_value->attr_val.attr_len = length;
+ }
+ }
+ break;
+ }
+ }
+
+ return GATT_SUCCESS;
+}
+
+
+/*******************************************************************************
+**
+** Function gatts_get_attribute_value
+**
+** Description This function get the attribute value in the database
+**
+** Parameter p_db: database pointer.
+** attr_handle: the attribute handle
+** length: the attribute value length
+** value: the pointer to the data to be get to the attribute value in the database
+**
+** Returns Status of the operation.
+**
+*******************************************************************************/
+tGATT_STATUS gatts_get_attribute_value(tGATT_SVC_DB *p_db, UINT16 attr_handle,
+ UINT16 *length, UINT8 **value)
+{
+ tGATT_ATTR16 *p_cur, *p_next;
+ GATT_TRACE_DEBUG("***********%s*************\n", __func__);
+ GATT_TRACE_DEBUG("attr_handle = %x\n", attr_handle);
+ if (p_db == NULL) {
+ GATT_TRACE_ERROR("gatts_get_attribute_value Fail:p_db is NULL.\n");
+ return GATT_INVALID_PDU;
+ }
+ if (p_db->p_attr_list == NULL) {
+ GATT_TRACE_ERROR("gatts_get_attribute_value Fail:p_db->p_attr_list is NULL.\n");
+ return GATT_INVALID_PDU;
+ }
+
+ p_cur = (tGATT_ATTR16 *) p_db->p_attr_list;
+ p_next = (tGATT_ATTR16 *) p_cur->p_next;
+
+
+ for (; p_cur != NULL; p_cur = p_next, p_next = (tGATT_ATTR16 *)p_next->p_next) {
+ LOG_ERROR("p_ur->handle = %x\n", p_cur->handle);
+ if (p_cur->handle == attr_handle) {
+
+ if (p_cur->uuid_type == GATT_ATTR_UUID_TYPE_16) {
+ switch (p_cur->uuid) {
+ case GATT_UUID_CHAR_DECLARE:
+ case GATT_UUID_INCLUDE_SERVICE:
+ break;
+ default:
+ if (p_cur->p_value->attr_val.attr_len != 0) {
+ *length = p_cur->p_value->attr_val.attr_len;
+ *value = p_cur->p_value->attr_val.attr_val;
+ return GATT_SUCCESS;
+ } else {
+ GATT_TRACE_ERROR("gatts_get_attribute_vaule failt:the value length is 0");
+ return GATT_INVALID_ATTR_LEN;
+ }
+ break;
+ }
+ } else {
+ if (p_cur->p_value->attr_val.attr_len != 0) {
+ *length = p_cur->p_value->attr_val.attr_len;
+ *value = p_cur->p_value->attr_val.attr_val;
+ return GATT_SUCCESS;
+ } else {
+ GATT_TRACE_ERROR("gatts_get_attribute_vaule failt:the value length is 0");
+ return GATT_INVALID_ATTR_LEN;
+ }
+
+ }
+
+ break;
+
+ }
+
+
+ }
+
+ return GATT_SUCCESS;
+}
+
+BOOLEAN gatts_is_auto_response(UINT16 attr_handle)
+{
+ tGATT_HDL_LIST_ELEM *p_decl = NULL;
+ BOOLEAN rsp = FALSE;
+ tGATT_SVC_DB *p_db = NULL;
+ if ((p_decl = gatt_find_hdl_buffer_by_attr_handle(attr_handle)) == NULL) {
+ GATT_TRACE_DEBUG("Service not created\n");
+ return rsp;
+ }
+
+ p_db = &p_decl->svc_db;
+
+ tGATT_ATTR16 *p_cur, *p_next;
+
+ if (p_db == NULL) {
+ GATT_TRACE_DEBUG("gatts_get_attribute_value Fail:p_db is NULL.\n");
+ return rsp;
+ }
+ if (p_db->p_attr_list == NULL) {
+ GATT_TRACE_DEBUG("gatts_get_attribute_value Fail:p_db->p_attr_list is NULL.\n");
+ return rsp;
+ }
+
+ p_cur = (tGATT_ATTR16 *) p_db->p_attr_list;
+ p_next = (tGATT_ATTR16 *) p_cur->p_next;
+
+ for (; p_cur != NULL && p_next != NULL;
+ p_cur = p_next, p_next = (tGATT_ATTR16 *)p_next->p_next) {
+ if (p_cur->handle == attr_handle) {
+ if (p_cur->p_value != NULL && p_cur->control.auto_rsp == GATT_RSP_BY_STACK) {
+ rsp = true;
+ return rsp;
+ }
+
+ }
+
+ }
+
+ return rsp;
+
+}
+
/*******************************************************************************/
/* Service Attribute Database Query Utility Functions */
/*******************************************************************************/
return status;
}
+tGATT_STATUS gatts_write_attr_value_by_handle(tGATT_SVC_DB *p_db,
+ UINT16 handle, UINT16 offset,
+ UINT8 *p_value, UINT16 len)
+{
+ tGATT_STATUS status = GATT_NOT_FOUND;
+ tGATT_ATTR16 *p_attr;
+
+ if (p_db && p_db->p_attr_list) {
+ p_attr = (tGATT_ATTR16 *)p_db->p_attr_list;
+
+ while (p_attr && handle >= p_attr->handle) {
+ if (p_attr->handle == handle ) {
+ if (p_attr->control.auto_rsp == GATT_RSP_BY_APP) {
+ return GATT_APP_RSP;
+ }
+
+ if (p_attr->p_value != NULL && (p_attr->p_value->attr_val.attr_max_len >
+ offset + len)) {
+ memcpy(p_attr->p_value->attr_val.attr_val + offset, p_value, len);
+ p_attr->p_value->attr_val.attr_len = len + offset;
+ return GATT_SUCCESS;
+ } else {
+ return GATT_NOT_LONG;
+ }
+ }
+
+ p_attr = (tGATT_ATTR16 *)p_attr->p_next;
+
+ }
+
+ }
+
+ return status;
+}
+
/*******************************************************************************
**
** Function gatts_read_attr_perm_check
return status;
}
+
+
/*******************************************************************************
**
** Function gatts_write_attr_perm_check
UINT16 len = sizeof(tGATT_ATTR128);
if (p_uuid == NULL) {
- GATT_TRACE_ERROR("illegal UUID");
+ GATT_TRACE_ERROR("illegal UUID\n");
return NULL;
}
len = sizeof(tGATT_ATTR32);
}
- GATT_TRACE_DEBUG("allocate attr %d bytes ", len);
+ GATT_TRACE_DEBUG("allocate attr %d bytes\n", len);
if (p_db->end_handle <= p_db->next_handle) {
- GATT_TRACE_DEBUG("handle space full. handle_max = %d next_handle = %d",
+ GATT_TRACE_DEBUG("handle space full. handle_max = %d next_handle = %d\n",
p_db->end_handle, p_db->next_handle);
return NULL;
}
if (p_db->mem_free < len) {
if (!allocate_svc_db_buf(p_db)) {
- GATT_TRACE_ERROR("allocate_attr_in_db failed, no resources");
+ GATT_TRACE_ERROR("allocate_attr_in_db failed, no resources\n");
return NULL;
}
}
}
if (p_attr16->uuid_type == GATT_ATTR_UUID_TYPE_16) {
- GATT_TRACE_DEBUG("=====> handle = [0x%04x] uuid16 = [0x%04x] perm=0x%02x ",
+ GATT_TRACE_DEBUG("=====> handle = [0x%04x] uuid16 = [0x%04x] perm=0x%02x\n",
p_attr16->handle, p_attr16->uuid, p_attr16->permission);
} else if (p_attr16->uuid_type == GATT_ATTR_UUID_TYPE_32) {
- GATT_TRACE_DEBUG("=====> handle = [0x%04x] uuid32 = [0x%08x] perm=0x%02x ",
+ GATT_TRACE_DEBUG("=====> handle = [0x%04x] uuid32 = [0x%08x] perm=0x%02x\n",
p_attr32->handle, p_attr32->uuid, p_attr32->permission);
} else {
- GATT_TRACE_DEBUG("=====> handle = [0x%04x] uuid128 = [0x%02x:0x%02x] perm=0x%02x ",
+ GATT_TRACE_DEBUG("=====> handle = [0x%04x] uuid128 = [0x%02x:0x%02x] perm=0x%02x\n",
p_attr128->handle, p_attr128->uuid[0], p_attr128->uuid[1],
p_attr128->permission);
}
return (void *)p_attr16;
}
+
+
/*******************************************************************************
**
** Function deallocate_attr_in_db
if (p_db->mem_free < len) {
if (!allocate_svc_db_buf(p_db)) {
- GATT_TRACE_ERROR("copy_extra_byte_in_db failed, no resources");
+ GATT_TRACE_ERROR("copy_extra_byte_in_db failed, no resources\n");
return FALSE;
}
}
GKI_freebuf (p_buf);
if (p_tcb != NULL) {
- GATT_TRACE_WARNING ("ATT - Ignored L2CAP data while in state: %d",
+ GATT_TRACE_WARNING ("ATT - Ignored L2CAP data while in state: %d\n",
gatt_get_ch_state(p_tcb));
}
}
}
}
} else {
- GATT_TRACE_ERROR ("ATT - Rcvd L2CAP data, unknown cmd: 0x%x", op_code);
+ GATT_TRACE_ERROR ("ATT - Rcvd L2CAP data, unknown cmd: 0x%x\n", op_code);
}
} else {
- GATT_TRACE_ERROR ("invalid data length, ignore");
+ GATT_TRACE_ERROR ("invalid data length, ignore\n");
}
GKI_freebuf (p_buf);
tGATT_STATUS ret_code = GATT_SUCCESS;
UNUSED(trans_id);
- GATT_TRACE_DEBUG("gatt_sr_process_app_rsp gatt_if=%d", gatt_if);
+ GATT_TRACE_DEBUG("gatt_sr_process_app_rsp gatt_if=%d\n", gatt_if);
gatt_sr_update_cback_cnt(p_tcb, gatt_if, FALSE, FALSE);
if (p_tcb->sr_cmd.p_rsp_msg == NULL) {
p_tcb->sr_cmd.p_rsp_msg = attp_build_sr_msg (p_tcb, (UINT8)(op_code + 1), (tGATT_SR_MSG *)p_msg);
} else {
- GATT_TRACE_ERROR("Exception!!! already has respond message");
+ GATT_TRACE_ERROR("Exception!!! already has respond message\n");
}
}
}
gatt_dequeue_sr_cmd(p_tcb);
}
- GATT_TRACE_DEBUG("gatt_sr_process_app_rsp ret_code=%d", ret_code);
+ GATT_TRACE_DEBUG("gatt_sr_process_app_rsp ret_code=%d\n", ret_code);
return ret_code;
}
#if GATT_CONFORMANCE_TESTING == TRUE
if (gatt_cb.enable_err_rsp && gatt_cb.req_op_code == op_code) {
- GATT_TRACE_DEBUG("Conformance tst: forced err rspvofr ReadMultiple: error status=%d", gatt_cb.err_status);
+ GATT_TRACE_DEBUG("Conformance tst: forced err rspvofr ReadMultiple: error status=%d\n", gatt_cb.err_status);
STREAM_TO_UINT16(handle, p);
** - discover characteristic by UUID
** - relationship discovery
**
-** Returns void
+** Returns void
**
*******************************************************************************/
void gatts_process_read_by_type_req(tGATT_TCB *p_tcb, UINT8 op_code, UINT16 len, UINT8 *p_data)
tGATT_SRV_LIST_ELEM *p_srv = NULL;
reason = gatts_validate_packet_format(op_code, &len, &p_data, &uuid, &s_hdl, &e_hdl);
-
+ GATT_TRACE_DEBUG("%s, op_code =%x, len = %x\n", __func__, op_code, len);
#if GATT_CONFORMANCE_TESTING == TRUE
if (gatt_cb.enable_err_rsp && gatt_cb.req_op_code == op_code) {
- GATT_TRACE_DEBUG("Conformance tst: forced err rsp for ReadByType: error status=%d", gatt_cb.err_status);
+ GATT_TRACE_DEBUG("Conformance tst: forced err rsp for ReadByType: error status=%d\n", gatt_cb.err_status);
gatt_send_error_rsp (p_tcb, gatt_cb.err_status, gatt_cb.req_op_code, s_hdl, FALSE);
if (reason == GATT_SUCCESS) {
if ((p_msg = (BT_HDR *)GKI_getbuf(msg_len)) == NULL) {
- GATT_TRACE_ERROR("gatts_process_find_info failed. no resources.");
+ GATT_TRACE_ERROR("gatts_process_find_info failed. no resources.\n");
reason = GATT_NO_RESOURCES;
} else {
p_msg->offset = L2CAP_MIN_OFFSET;
}
}
- if (reason != GATT_SUCCESS) {
+ if (reason != GATT_SUCCESS && reason != GATT_STACK_RSP) {
if (p_msg) {
GKI_freebuf(p_msg);
}
void gatts_process_write_req (tGATT_TCB *p_tcb, UINT8 i_rcb, UINT16 handle,
UINT8 op_code, UINT16 len, UINT8 *p_data)
{
- tGATTS_DATA sr_data;
- UINT32 trans_id;
- tGATT_STATUS status;
- UINT8 sec_flag, key_size, *p = p_data;
- tGATT_SR_REG *p_sreg;
- UINT16 conn_id;
-
+ UINT16 buf_len = (UINT16)(sizeof(BT_HDR) + p_tcb->payload_size + L2CAP_MIN_OFFSET);
+ tGATTS_DATA sr_data;
+ UINT32 trans_id;
+ tGATT_STATUS status;
+ UINT8 sec_flag, key_size, *p = p_data, *p_m;
+ tGATT_SR_REG *p_sreg;
+ UINT16 conn_id, offset = 0;
+ BT_HDR *p_msg = NULL;
memset(&sr_data, 0, sizeof(tGATTS_DATA));
+ if ((p_msg = (BT_HDR *)GKI_getbuf(buf_len)) == NULL) {
+ GATT_TRACE_ERROR("gatts_process_write_req failed. no resources.\n");
+ }
+
+ memset(p_msg, 0, buf_len);
+ p_m = (UINT8 *)(p_msg + 1) + L2CAP_MIN_OFFSET;
+ *p_m ++ = op_code + 1;
+ p_msg->len = 1;
+ buf_len = p_tcb->payload_size - 1;
+
switch (op_code) {
case GATT_REQ_PREPARE_WRITE:
sr_data.write_req.is_prep = TRUE;
STREAM_TO_UINT16(sr_data.write_req.offset, p);
+ UINT16_TO_STREAM(p_m, sr_data.write_req.is_prep);
+ offset = sr_data.write_req.offset;
len -= 2;
/* fall through */
case GATT_SIGN_CMD_WRITE:
case GATT_REQ_WRITE:
if (op_code == GATT_REQ_WRITE || op_code == GATT_REQ_PREPARE_WRITE) {
sr_data.write_req.need_rsp = TRUE;
+ if(op_code == GATT_REQ_PREPARE_WRITE){
+ memcpy(p_m, p, len);
+ p_msg->len += len;
+ }
}
sr_data.write_req.handle = handle;
sr_data.write_req.len = len;
if (len != 0 && p != NULL) {
memcpy (sr_data.write_req.value, p, len);
+
}
break;
}
sec_flag,
key_size);
+ p_msg->len += len;
if (status == GATT_SUCCESS) {
if ((trans_id = gatt_sr_enqueue_cmd(p_tcb, op_code, handle)) != 0) {
p_sreg = &gatt_cb.sr_reg[i_rcb];
conn_id = GATT_CREATE_CONN_ID(p_tcb->tcb_idx, p_sreg->gatt_if);
+ status = gatts_write_attr_value_by_handle(gatt_cb.sr_reg[i_rcb].p_db,
+ handle, offset, p, len);
gatt_sr_send_req_callback(conn_id,
trans_id,
GATTS_REQ_TYPE_WRITE,
&sr_data);
-
- status = GATT_PENDING;
+
+ if(status == GATT_SUCCESS){
+ attp_send_sr_msg(p_tcb, p_msg);
+ }else if(status == GATT_NOT_LONG){
+ gatt_send_error_rsp (p_tcb, status, op_code, handle, FALSE);
+ }
+ status = GATT_PENDING;
} else {
- GATT_TRACE_ERROR("max pending command, send error");
+ GATT_TRACE_ERROR("max pending command, send error\n");
status = GATT_BUSY; /* max pending command, application error */
}
}
static void gatts_process_read_req(tGATT_TCB *p_tcb, tGATT_SR_REG *p_rcb, UINT8 op_code,
UINT16 handle, UINT16 len, UINT8 *p_data)
{
- UINT16 buf_len = (UINT16)(sizeof(BT_HDR) + p_tcb->payload_size + L2CAP_MIN_OFFSET);
- tGATT_STATUS reason;
- BT_HDR *p_msg = NULL;
- UINT8 sec_flag, key_size, *p;
- UINT16 offset = 0, value_len = 0;
+ UINT16 buf_len = (UINT16)(sizeof(BT_HDR) + p_tcb->payload_size + L2CAP_MIN_OFFSET);
+ tGATT_STATUS reason;
+ BT_HDR *p_msg = NULL;
+ UINT8 sec_flag, key_size, *p;
+ UINT16 offset = 0, value_len = 0;
UNUSED (len);
if ((p_msg = (BT_HDR *)GKI_getbuf(buf_len)) == NULL) {
- GATT_TRACE_ERROR("gatts_process_find_info failed. no resources.");
+ GATT_TRACE_ERROR("gatts_process_find_info failed. no resources.\n");
reason = GATT_NO_RESOURCES;
} else {
p_msg->len += value_len;
}
- if (reason != GATT_SUCCESS) {
+ if (reason != GATT_SUCCESS && reason != GATT_PENDING) {
if (p_msg) {
GKI_freebuf(p_msg);
}
/* in theroy BUSY is not possible(should already been checked), protected check */
- if (reason != GATT_PENDING && reason != GATT_BUSY) {
+ if (reason != GATT_BUSY) {
gatt_send_error_rsp (p_tcb, reason, op_code, handle, FALSE);
}
} else {
tGATT_ATTR16 *p_attr;
if (len < 2) {
- GATT_TRACE_ERROR("Illegal PDU length, discard request");
+ GATT_TRACE_ERROR("Illegal PDU length, discard request\n");
status = GATT_INVALID_PDU;
} else {
STREAM_TO_UINT16(handle, p);
#if GATT_CONFORMANCE_TESTING == TRUE
gatt_cb.handle = handle;
if (gatt_cb.enable_err_rsp && gatt_cb.req_op_code == op_code) {
- GATT_TRACE_DEBUG("Conformance tst: forced err rsp: error status=%d", gatt_cb.err_status);
+ GATT_TRACE_DEBUG("Conformance tst: forced err rsp: error status=%d\n", gatt_cb.err_status);
gatt_send_error_rsp (p_tcb, gatt_cb.err_status, gatt_cb.req_op_code, handle, FALSE);
/* otherwise, ignore the pkt */
} else {
switch (op_code) {
- case GATT_REQ_READ_BY_GRP_TYPE: /* discover primary services */
- case GATT_REQ_FIND_TYPE_VALUE: /* discover service by UUID */
+ case GATT_REQ_READ_BY_GRP_TYPE: /* discover primary services */
+ case GATT_REQ_FIND_TYPE_VALUE: /* discover service by UUID */
gatts_process_primary_service_req (p_tcb, op_code, len, p_data);
break;
- case GATT_REQ_FIND_INFO:/* discover char descrptor */
+ case GATT_REQ_FIND_INFO: /* discover char descrptor */
gatts_process_find_info(p_tcb, op_code, len, p_data);
break;
- case GATT_REQ_READ_BY_TYPE: /* read characteristic value, char descriptor value */
+ case GATT_REQ_READ_BY_TYPE: /* read characteristic value, char descriptor value */
/* discover characteristic, discover char by UUID */
gatts_process_read_by_type_req(p_tcb, op_code, len, p_data);
break;
- case GATT_REQ_READ: /* read char/char descriptor value */
+ case GATT_REQ_READ: /* read char/char descriptor value */
case GATT_REQ_READ_BLOB:
- case GATT_REQ_WRITE: /* write char/char descriptor value */
+ case GATT_REQ_WRITE: /* write char/char descriptor value */
case GATT_CMD_WRITE:
case GATT_SIGN_CMD_WRITE:
case GATT_REQ_PREPARE_WRITE:
}
return NULL;
}
+
+/*******************************************************************************
+**
+** Function gatt_find_hdl_buffer_by_attr_handle
+**
+** Description Find handle range buffer by attribute handle.
+**
+** Returns Pointer to the buffer, NULL no buffer available
+**
+*******************************************************************************/
+tGATT_HDL_LIST_ELEM *gatt_find_hdl_buffer_by_attr_handle(UINT16 attr_handle)
+{
+ tGATT_HDL_LIST_INFO *p_list_info = &gatt_cb.hdl_list_info;
+ tGATT_HDL_LIST_ELEM *p_list = NULL;
+
+ p_list = p_list_info->p_first;
+
+ while (p_list != NULL) {
+ if (p_list->in_use && (p_list->asgn_range.s_handle <= attr_handle)
+ && (p_list->asgn_range.e_handle >= attr_handle)) {
+ return (p_list);
+ }
+ p_list = p_list->p_next;
+ }
+ return NULL;
+}
+
+
/*******************************************************************************
**
** Function gatt_find_hdl_buffer_by_app_id
p_reg = &gatt_cb.cl_rcb[ii - 1];
if (!p_reg->in_use) {
- GATT_TRACE_WARNING("gatt_if found but not in use.");
+ GATT_TRACE_WARNING("gatt_if found but not in use.\n");
return NULL;
}
#define GATT_GET_GATT_IF(conn_id) ((tGATT_IF)((UINT8) (conn_id)))
#define GATT_GET_SR_REG_PTR(index) (&gatt_cb.sr_reg[(UINT8) (index)]);
-#define GATT_TRANS_ID_MAX 0x0fffffff /* 4 MSB is reserved */
+#define GATT_TRANS_ID_MAX 0x0fffffff /* 4 MSB is reserved */
+#define GATT_RSP_BY_APP 0x00
+#define GATT_RSP_BY_STACK 0x01
+#define GATT_RSP_DEFAULT GATT_RSP_BY_APP //need to rsp by the app.
/* security action for GATT write and read request */
#define GATT_SEC_NONE 0
#define GATT_ATTR_OP_SPT_PREP_WRITE (0x00000001 << 10)
#define GATT_ATTR_OP_SPT_EXE_WRITE (0x00000001 << 11)
#define GATT_ATTR_OP_SPT_HDL_VALUE_CONF (0x00000001 << 12)
-#define GATT_ATTR_OP_SP_SIGN_WRITE (0x00000001 << 13)
+#define GATT_ATTR_OP_SP_SIGN_WRITE (0x00000001 << 13)
-#define GATT_INDEX_INVALID 0xff
+#define GATT_INDEX_INVALID 0xff
-#define GATT_PENDING_REQ_NONE 0
+#define GATT_PENDING_REQ_NONE 0
-#define GATT_WRITE_CMD_MASK 0xc0 /*0x1100-0000*/
-#define GATT_AUTH_SIGN_MASK 0x80 /*0x1000-0000*/
-#define GATT_AUTH_SIGN_LEN 12
+#define GATT_WRITE_CMD_MASK 0xc0 /*0x1100-0000*/
+#define GATT_AUTH_SIGN_MASK 0x80 /*0x1000-0000*/
+#define GATT_AUTH_SIGN_LEN 12
#define GATT_HDR_SIZE 3 /* 1B opcode + 2B handle */
tBT_UUID uuid; /* service declaration */
tGATT_CHAR_DECL char_decl; /* characteristic declaration */
tGATT_INCL_SRVC incl_handle; /* included service */
-
+ tGATT_ATTR_VAL attr_val;
} tGATT_ATTR_VALUE;
/* Attribute UUID type
/* 16 bits UUID Attribute in server database
*/
typedef struct {
- void *p_next; /* pointer to the next attribute,
- either tGATT_ATTR16 or tGATT_ATTR128 */
- tGATT_ATTR_VALUE *p_value;
- tGATT_ATTR_UUID_TYPE uuid_type;
- tGATT_PERM permission;
- UINT16 handle;
- UINT16 uuid;
+ void *p_next; /* pointer to the next attribute, either tGATT_ATTR16 or tGATT_ATTR128 */
+ tGATT_ATTR_VALUE *p_value;
+ tGATT_ATTR_UUID_TYPE uuid_type;
+ tGATT_PERM permission;
+ tGATTS_ATTR_CONTROL control;
+ UINT16 handle;
+ UINT16 uuid;
} tGATT_ATTR16;
/* 32 bits UUID Attribute in server database
*/
typedef struct {
- void *p_next; /* pointer to the next attribute,
- either tGATT_ATTR16, tGATT_ATTR32 or tGATT_ATTR128 */
- tGATT_ATTR_VALUE *p_value;
- tGATT_ATTR_UUID_TYPE uuid_type;
- tGATT_PERM permission;
- UINT16 handle;
- UINT32 uuid;
+ void *p_next; /* pointer to the next attribute, either tGATT_ATTR16, tGATT_ATTR32 or tGATT_ATTR128 */
+ tGATT_ATTR_VALUE *p_value;
+ tGATT_ATTR_UUID_TYPE uuid_type;
+ tGATT_PERM permission;
+ tGATTS_ATTR_CONTROL control;
+ UINT16 handle;
+ UINT32 uuid;
} tGATT_ATTR32;
/* 128 bits UUID Attribute in server database
*/
typedef struct {
- void *p_next; /* pointer to the next attribute,
- either tGATT_ATTR16 or tGATT_ATTR128 */
- tGATT_ATTR_VALUE *p_value;
- tGATT_ATTR_UUID_TYPE uuid_type;
- tGATT_PERM permission;
- UINT16 handle;
- UINT8 uuid[LEN_UUID_128];
+ void *p_next; /* pointer to the next attribute, either tGATT_ATTR16 or tGATT_ATTR128 */
+ tGATT_ATTR_VALUE *p_value;
+ tGATT_ATTR_UUID_TYPE uuid_type;
+ tGATT_PERM permission;
+ tGATTS_ATTR_CONTROL control;
+ UINT16 handle;
+ UINT8 uuid[LEN_UUID_128];
} tGATT_ATTR128;
/* Service Database definition
*/
typedef struct {
- void *p_attr_list; /* pointer to the first attribute,
- either tGATT_ATTR16 or tGATT_ATTR128 */
- UINT8 *p_free_mem; /* Pointer to free memory */
- BUFFER_Q svc_buffer; /* buffer queue used for service database */
- UINT32 mem_free; /* Memory still available */
- UINT16 end_handle; /* Last handle number */
- UINT16 next_handle; /* Next usable handle value */
+ void *p_attr_list; /* pointer to the first attribute, either tGATT_ATTR16 or tGATT_ATTR128 */
+ UINT8 *p_free_mem; /* Pointer to free memory */
+ BUFFER_Q svc_buffer; /* buffer queue used for service database */
+ UINT32 mem_free; /* Memory still available */
+ UINT16 end_handle; /* Last handle number */
+ UINT16 next_handle; /* Next usable handle value */
} tGATT_SVC_DB;
/* Data Structure used for GATT server */
/* A service registration information record consists of beginning and ending */
/* attribute handle, service UUID and a set of GATT server callback. */
typedef struct {
- tGATT_SVC_DB *p_db; /* pointer to the service database */
+ tGATT_SVC_DB *p_db; /* pointer to the service database */
tBT_UUID app_uuid; /* applicatino UUID */
- UINT32 sdp_handle; /* primamry service SDP handle */
+ UINT32 sdp_handle; /* primamry service SDP handle */
UINT16 service_instance; /* service instance number */
- UINT16 type; /* service type UUID, primary or secondary */
- UINT16 s_hdl; /* service starting handle */
- UINT16 e_hdl; /* service ending handle */
- tGATT_IF gatt_if; /* this service is belong to which application */
+ UINT16 type; /* service type UUID, primary or secondary */
+ UINT16 s_hdl; /* service starting handle */
+ UINT16 e_hdl; /* service ending handle */
+ tGATT_IF gatt_if; /* this service is belong to which application */
BOOLEAN in_use;
} tGATT_SR_REG;
tGATT_CH_STATE ch_state;
UINT8 ch_flags;
- tGATT_IF app_hold_link[GATT_MAX_APPS];
+ tGATT_IF app_hold_link[GATT_MAX_APPS];
/* server needs */
/* server response data */
TIMER_LIST_ENT conf_timer_ent; /* peer confirm to indication timer */
- UINT8 prep_cnt[GATT_MAX_APPS];
- UINT8 ind_count;
+ UINT8 prep_cnt[GATT_MAX_APPS];
+ UINT8 ind_count;
- tGATT_CMD_Q cl_cmd_q[GATT_CL_MAX_LCB];
- TIMER_LIST_ENT ind_ack_timer_ent; /* local app confirm to indication timer */
- UINT8 pending_cl_req;
- UINT8 next_slot_inq; /* index of next available slot in queue */
+ tGATT_CMD_Q cl_cmd_q[GATT_CL_MAX_LCB];
+ TIMER_LIST_ENT ind_ack_timer_ent; /* local app confirm to indication timer */
+ UINT8 pending_cl_req;
+ UINT8 next_slot_inq; /* index of next available slot in queue */
BOOLEAN in_use;
UINT8 tcb_idx;
/* reserved handle list */
extern tGATT_HDL_LIST_ELEM *gatt_find_hdl_buffer_by_app_id (tBT_UUID *p_app_uuid128, tBT_UUID *p_svc_uuid, UINT16 svc_inst);
extern tGATT_HDL_LIST_ELEM *gatt_find_hdl_buffer_by_handle(UINT16 handle);
+extern tGATT_HDL_LIST_ELEM *gatt_find_hdl_buffer_by_attr_handle(UINT16 attr_handle);
extern tGATT_HDL_LIST_ELEM *gatt_alloc_hdl_buffer(void);
extern void gatt_free_hdl_buffer(tGATT_HDL_LIST_ELEM *p);
extern BOOLEAN gatt_is_last_attribute(tGATT_SRV_LIST_INFO *p_list, tGATT_SRV_LIST_ELEM *p_start, tBT_UUID value);
/* gatt_db.c */
extern BOOLEAN gatts_init_service_db (tGATT_SVC_DB *p_db, tBT_UUID *p_service, BOOLEAN is_pri, UINT16 s_hdl, UINT16 num_handle);
extern UINT16 gatts_add_included_service (tGATT_SVC_DB *p_db, UINT16 s_handle, UINT16 e_handle, tBT_UUID service);
-extern UINT16 gatts_add_characteristic (tGATT_SVC_DB *p_db, tGATT_PERM perm, tGATT_CHAR_PROP property, tBT_UUID *p_char_uuid);
-extern UINT16 gatts_add_char_descr (tGATT_SVC_DB *p_db, tGATT_PERM perm, tBT_UUID *p_dscp_uuid);
+extern UINT16 gatts_add_characteristic (tGATT_SVC_DB *p_db, tGATT_PERM perm,
+ tGATT_CHAR_PROP property,
+ tBT_UUID *p_char_uuid, tGATT_ATTR_VAL *attr_val,
+ tGATTS_ATTR_CONTROL *control);
+extern UINT16 gatts_add_char_descr (tGATT_SVC_DB *p_db, tGATT_PERM perm,
+ tBT_UUID *p_dscp_uuid, tGATT_ATTR_VAL *attr_val,
+ tGATTS_ATTR_CONTROL *control);
+
+extern tGATT_STATUS gatts_set_attribute_value(tGATT_SVC_DB *p_db, UINT16 attr_handle,
+ UINT16 length, UINT8 *value);
+
+extern tGATT_STATUS gatts_get_attribute_value(tGATT_SVC_DB *p_db, UINT16 attr_handle,
+ UINT16 *length, UINT8 **value);
+extern BOOLEAN gatts_is_auto_response(UINT16 attr_handle);
extern tGATT_STATUS gatts_db_read_attr_value_by_type (tGATT_TCB *p_tcb, tGATT_SVC_DB *p_db, UINT8 op_code, BT_HDR *p_rsp, UINT16 s_handle,
UINT16 e_handle, tBT_UUID type, UINT16 *p_len, tGATT_SEC_FLAG sec_flag, UINT8 key_size, UINT32 trans_id, UINT16 *p_cur_handle);
extern tGATT_STATUS gatts_read_attr_value_by_handle(tGATT_TCB *p_tcb, tGATT_SVC_DB *p_db, UINT8 op_code, UINT16 handle, UINT16 offset,
UINT8 *p_value, UINT16 *p_len, UINT16 mtu, tGATT_SEC_FLAG sec_flag, UINT8 key_size, UINT32 trans_id);
+extern tGATT_STATUS gatts_write_attr_value_by_handle(tGATT_SVC_DB *p_db,
+ UINT16 handle, UINT16 offset,
+ UINT8 *p_value, UINT16 len);
extern tGATT_STATUS gatts_write_attr_perm_check (tGATT_SVC_DB *p_db, UINT8 op_code, UINT16 handle, UINT16 offset, UINT8 *p_data,
UINT16 len, tGATT_SEC_FLAG sec_flag, UINT8 key_size);
extern tGATT_STATUS gatts_read_attr_perm_check(tGATT_SVC_DB *p_db, BOOLEAN is_long, UINT16 handle, tGATT_SEC_FLAG sec_flag, UINT8 key_size);
#define GATT_ENCRYPED_NO_MITM 0x8d
#define GATT_NOT_ENCRYPTED 0x8e
#define GATT_CONGESTED 0x8f
+#define GATT_STACK_RSP 0x90
+#define GATT_APP_RSP 0x91
/* 0xE0 ~ 0xFC reserved for future use */
#define GATT_CCC_CFG_ERR 0xFD /* Client Characteristic Configuration Descriptor Improperly Configured */
/* MAX GATT MTU size
*/
#ifndef GATT_MAX_MTU_SIZE
-#define GATT_MAX_MTU_SIZE 517
+#define GATT_MAX_MTU_SIZE 517
#endif
/* max legth of an attribute value
*/
#ifndef GATT_MAX_ATTR_LEN
-#define GATT_MAX_ATTR_LEN 600
+#define GATT_MAX_ATTR_LEN 600
#endif
/* default GATT MTU size over LE link
*/
-#define GATT_DEF_BLE_MTU_SIZE 23
+#define GATT_DEF_BLE_MTU_SIZE 23
/* invalid connection ID
*/
-#define GATT_INVALID_CONN_ID 0xFFFF
+#define GATT_INVALID_CONN_ID 0xFFFF
#ifndef GATT_CL_MAX_LCB
-#define GATT_CL_MAX_LCB 12 // 22
+#define GATT_CL_MAX_LCB 12 // 22
#endif
#ifndef GATT_MAX_SCCB
-#define GATT_MAX_SCCB 10
+#define GATT_MAX_SCCB 10
#endif
/* GATT notification caching timer, default to be three seconds
*/
#ifndef GATTC_NOTIF_TIMEOUT
-#define GATTC_NOTIF_TIMEOUT 3
+#define GATTC_NOTIF_TIMEOUT 3
#endif
/*****************************************************************************
/* Attribute permissions
*/
-#define GATT_PERM_READ (1 << 0) /* bit 0 */
-#define GATT_PERM_READ_ENCRYPTED (1 << 1) /* bit 1 */
-#define GATT_PERM_READ_ENC_MITM (1 << 2) /* bit 2 */
-#define GATT_PERM_WRITE (1 << 4) /* bit 4 */
-#define GATT_PERM_WRITE_ENCRYPTED (1 << 5) /* bit 5 */
-#define GATT_PERM_WRITE_ENC_MITM (1 << 6) /* bit 6 */
-#define GATT_PERM_WRITE_SIGNED (1 << 7) /* bit 7 */
-#define GATT_PERM_WRITE_SIGNED_MITM (1 << 8) /* bit 8 */
+#define GATT_PERM_READ (1 << 0) /* bit 0 */
+#define GATT_PERM_READ_ENCRYPTED (1 << 1) /* bit 1 */
+#define GATT_PERM_READ_ENC_MITM (1 << 2) /* bit 2 */
+#define GATT_PERM_WRITE (1 << 4) /* bit 4 */
+#define GATT_PERM_WRITE_ENCRYPTED (1 << 5) /* bit 5 */
+#define GATT_PERM_WRITE_ENC_MITM (1 << 6) /* bit 6 */
+#define GATT_PERM_WRITE_SIGNED (1 << 7) /* bit 7 */
+#define GATT_PERM_WRITE_SIGNED_MITM (1 << 8) /* bit 8 */
typedef UINT16 tGATT_PERM;
#define GATT_ENCRYPT_KEY_SIZE_MASK (0xF000) /* the MS nibble of tGATT_PERM; key size 7=0; size 16=9 */
-#define GATT_READ_ALLOWED (GATT_PERM_READ | GATT_PERM_READ_ENCRYPTED | GATT_PERM_READ_ENC_MITM)
-#define GATT_READ_AUTH_REQUIRED (GATT_PERM_READ_ENCRYPTED)
-#define GATT_READ_MITM_REQUIRED (GATT_PERM_READ_ENC_MITM)
-#define GATT_READ_ENCRYPTED_REQUIRED (GATT_PERM_READ_ENCRYPTED | GATT_PERM_READ_ENC_MITM)
+#define GATT_READ_ALLOWED (GATT_PERM_READ | GATT_PERM_READ_ENCRYPTED | GATT_PERM_READ_ENC_MITM)
+#define GATT_READ_AUTH_REQUIRED (GATT_PERM_READ_ENCRYPTED)
+#define GATT_READ_MITM_REQUIRED (GATT_PERM_READ_ENC_MITM)
+#define GATT_READ_ENCRYPTED_REQUIRED (GATT_PERM_READ_ENCRYPTED | GATT_PERM_READ_ENC_MITM)
#define GATT_WRITE_ALLOWED (GATT_PERM_WRITE | GATT_PERM_WRITE_ENCRYPTED | GATT_PERM_WRITE_ENC_MITM | \
UINT8 value[GATT_MAX_ATTR_LEN]; /* the actual attribute value */
} tGATT_VALUE;
+typedef struct{
+ UINT16 attr_max_len;
+ UINT16 attr_len;
+ UINT8 *attr_val;
+}tGATT_ATTR_VAL;
+
+typedef struct{
+ uint8_t auto_rsp;
+}tGATTS_ATTR_CONTROL;
+
/* Union of the event data which is used in the server respond API to carry the server response information
*/
typedef union {
** characteristic failed.
**
*******************************************************************************/
-extern UINT16 GATTS_AddCharacteristic (UINT16 service_handle, tBT_UUID *char_uuid,
- tGATT_PERM perm, tGATT_CHAR_PROP property);
+extern UINT16 GATTS_AddCharacteristic (UINT16 service_handle, tBT_UUID *p_char_uuid,
+ tGATT_PERM perm, tGATT_CHAR_PROP property,
+ tGATT_ATTR_VAL *attr_val, tGATTS_ATTR_CONTROL *control);
/*******************************************************************************
**
**
*******************************************************************************/
extern UINT16 GATTS_AddCharDescriptor (UINT16 service_handle, tGATT_PERM perm,
- tBT_UUID *p_descr_uuid);
+ tBT_UUID *p_descr_uuid, tGATT_ATTR_VAL *attr_val,
+ tGATTS_ATTR_CONTROL *control);
/*******************************************************************************
**
tGATT_STATUS status, tGATTS_RSP *p_msg);
+/*******************************************************************************
+**
+** Function GATTS_SetAttributeValue
+**
+** Description This function sends to set the attribute value .
+**
+** Parameter attr_handle:the attribute handle
+** length: the attribute length
+** value: the value to be set to the attribute in the database
+**
+** Returns GATT_SUCCESS if sucessfully sent; otherwise error code.
+**
+*******************************************************************************/
+tGATT_STATUS GATTS_SetAttributeValue(UINT16 attr_handle, UINT16 length, UINT8 *value);
+
+
+/*******************************************************************************
+**
+** Function GATTS_GetAttributeValue
+**
+** Description This function sends to set the attribute value .
+**
+** Parameter attr_handle: the attribute handle
+** length:the attribute value length in the database
+** value: the attribute value out put
+**
+** Returns GATT_SUCCESS if sucessfully sent; otherwise error code.
+**
+*******************************************************************************/
+tGATT_STATUS GATTS_GetAttributeValue(UINT16 attr_handle, UINT16 *length, UINT8 **value);
+
+
+
/*******************************************************************************/
/* GATT Profile Client Functions */
/*******************************************************************************/
static const UINT8 smp_slave_entry_map[][SMP_STATE_MAX] = {
/* state name: Idle WaitApp SecReq Pair Wait Confirm Rand PublKey SCPhs1 Wait Wait SCPhs2 Wait DHKChk Enc Bond CrLocSc
Rsp Pend ReqRsp Cfm Exch Strt Cmtm Nonce Strt DHKChk Pend Pend OobData */
- /* PAIR_REQ */{ 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ /* PAIR_REQ */{ 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
/* PAIR_RSP */{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
/* CONFIRM */{ 0, 4, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
/* RAND */{ 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 },
BLUFI is a profile based GATT to config ESP32 WIFI to connect/disconnect AP or setup a softap and etc.
Use should concern these things:
1. The event sent from profile. Then you need to do something as the event indicate.
-2. Security reference. You can write your own Security functions such as symmetrical encryption/decryption and checksum functions.
-Even you can define the "Key Exchange/Negotiation" procedure.
+2. Security reference. You can write your own Security functions such as symmetrical encryption/decryption and checksum functions. Even you can define the "Key Exchange/Negotiation" procedure.
Application Example
-------------------
.. doxygendefine:: ESP_GATT_UUID_SCAN_INT_WINDOW
.. doxygendefine:: ESP_GATT_UUID_SCAN_REFRESH
.. doxygendefine:: ESP_GATT_ILLEGAL_UUID
+.. doxygendefine:: ESP_GATT_ILLEGAL_HANDLE
+.. doxygendefine:: ESP_GATT_ATTR_HANDLE_MAX
.. doxygendefine:: ESP_GATT_MAX_ATTR_LEN
.. doxygendefine:: ESP_GATT_IF_NONE
Structures
^^^^^^^^^^
+.. doxygenstruct:: esp_attr_desc_t
+ :members:
+
+.. doxygenstruct:: esp_attr_control_t
+ :members:
+
+.. doxygenstruct:: esp_gatts_attr_db_t
+ :members:
+
+.. doxygenstruct:: esp_attr_value_t
+ :members:
+
+.. doxygenstruct:: esp_gatts_incl_svc_desc_t
+ :members:
+
+.. doxygenstruct:: esp_gatts_incl128_svc_desc_t
+ :members:
+
+.. doxygenstruct:: esp_gatts_char_desc_t
+ :members:
+
.. doxygenstruct:: esp_gatt_value_t
:members:
.. doxygenstruct:: esp_ble_gatts_cb_param_t::gatts_add_char_descr_evt_param
:members:
+.. doxygenstruct:: esp_ble_gatts_cb_param_t::gatts_add_attr_tab_evt_param
+ :members:
+
.. doxygenstruct:: esp_ble_gatts_cb_param_t::gatts_delete_evt_param
:members:
.. doxygenstruct:: esp_ble_gatts_cb_param_t::gatts_rsp_evt_param
:members:
+.. doxygenstruct:: esp_ble_gatts_cb_param_t::gatts_set_attr_val_evt_param
+ :members:
+
Functions
^^^^^^^^^
.. doxygenfunction:: esp_ble_gatts_app_register
.. doxygenfunction:: esp_ble_gatts_app_unregister
.. doxygenfunction:: esp_ble_gatts_create_service
+.. doxygenfunction:: esp_ble_gatts_create_attr_tab
.. doxygenfunction:: esp_ble_gatts_add_included_service
.. doxygenfunction:: esp_ble_gatts_add_char
.. doxygenfunction:: esp_ble_gatts_add_char_descr
.. doxygenfunction:: esp_ble_gatts_stop_service
.. doxygenfunction:: esp_ble_gatts_send_indicate
.. doxygenfunction:: esp_ble_gatts_send_response
+.. doxygenfunction:: esp_ble_gatts_set_attr_value
+.. doxygenfunction:: esp_ble_gatts_get_attr_value
.. doxygenfunction:: esp_ble_gatts_open
.. doxygenfunction:: esp_ble_gatts_close
#define TEST_DEVICE_NAME "ESP_GATTS_DEMO"
#define TEST_MANUFACTURER_DATA_LEN 17
+
+#define GATTS_DEMO_CHAR_VAL_LEN_MAX 0x40
+
+uint8_t char1_str[] ={0x11,0x22,0x33};
+
+esp_attr_value_t gatts_demo_char1_val =
+{
+ .attr_max_len = GATTS_DEMO_CHAR_VAL_LEN_MAX,
+ .attr_len = sizeof(char1_str),
+ .attr_value = char1_str,
+};
+
+
static uint8_t test_service_uuid128[32] = {
/* LSB <--------------------------------------------------------------------------------> MSB */
//first uuid, 16bit, [12],[13] is the value
esp_ble_gatts_add_char(gl_profile_tab[PROFILE_A_APP_ID].service_handle, &gl_profile_tab[PROFILE_A_APP_ID].char_uuid,
ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE,
- ESP_GATT_CHAR_PROP_BIT_READ | ESP_GATT_CHAR_PROP_BIT_WRITE | ESP_GATT_CHAR_PROP_BIT_NOTIFY);
+ ESP_GATT_CHAR_PROP_BIT_READ | ESP_GATT_CHAR_PROP_BIT_WRITE | ESP_GATT_CHAR_PROP_BIT_NOTIFY,
+ &gatts_demo_char1_val, NULL);
break;
case ESP_GATTS_ADD_INCL_SRVC_EVT:
break;
- case ESP_GATTS_ADD_CHAR_EVT:
- ESP_LOGI(GATTS_TAG, "ADD_CHAR_EVT, status %d, attr_handle %d, service_handle %d\n",
- param->add_char.status, param->add_char.attr_handle, param->add_char.service_handle);
+ case ESP_GATTS_ADD_CHAR_EVT: {
+ uint16_t length = 0;
+ const uint8_t *prf_char;
+ ESP_LOGI(GATTS_TAG, "ADD_CHAR_EVT, status %d, attr_handle %d, service_handle %d\n",
+ param->add_char.status, param->add_char.attr_handle, param->add_char.service_handle);
gl_profile_tab[PROFILE_A_APP_ID].char_handle = param->add_char.attr_handle;
gl_profile_tab[PROFILE_A_APP_ID].descr_uuid.len = ESP_UUID_LEN_16;
gl_profile_tab[PROFILE_A_APP_ID].descr_uuid.uuid.uuid16 = ESP_GATT_UUID_CHAR_CLIENT_CONFIG;
+ esp_ble_gatts_get_attr_value(param->add_char.attr_handle, &length, &prf_char);
+
+ ESP_LOGI(GATTS_TAG, "the gatts demo char length = %x\n", length);
+ for(int i = 0; i < length; i++){
+ ESP_LOGI(GATTS_TAG, "prf_char[%x] =%x\n",i,prf_char[i]);
+ }
esp_ble_gatts_add_char_descr(gl_profile_tab[PROFILE_A_APP_ID].service_handle, &gl_profile_tab[PROFILE_A_APP_ID].descr_uuid,
- ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE);
+ ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE, NULL, NULL);
break;
+ }
case ESP_GATTS_ADD_CHAR_DESCR_EVT:
ESP_LOGI(GATTS_TAG, "ADD_DESCR_EVT, status %d, attr_handle %d, service_handle %d\n",
param->add_char.status, param->add_char.attr_handle, param->add_char.service_handle);
esp_ble_gatts_add_char(gl_profile_tab[PROFILE_A_APP_ID].service_handle, &gl_profile_tab[PROFILE_A_APP_ID].char_uuid,
ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE,
- ESP_GATT_CHAR_PROP_BIT_READ | ESP_GATT_CHAR_PROP_BIT_WRITE | ESP_GATT_CHAR_PROP_BIT_NOTIFY);
+ ESP_GATT_CHAR_PROP_BIT_READ | ESP_GATT_CHAR_PROP_BIT_WRITE | ESP_GATT_CHAR_PROP_BIT_NOTIFY,
+ NULL, NULL);
break;
case ESP_GATTS_ADD_INCL_SRVC_EVT:
break;
gl_profile_tab[PROFILE_A_APP_ID].descr_uuid.len = ESP_UUID_LEN_16;
gl_profile_tab[PROFILE_A_APP_ID].descr_uuid.uuid.uuid16 = ESP_GATT_UUID_CHAR_CLIENT_CONFIG;
esp_ble_gatts_add_char_descr(gl_profile_tab[PROFILE_A_APP_ID].service_handle, &gl_profile_tab[PROFILE_A_APP_ID].descr_uuid,
- ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE);
+ ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE,
+ NULL, NULL);
break;
case ESP_GATTS_ADD_CHAR_DESCR_EVT:
ESP_LOGI(GATTS_TAG, "ADD_DESCR_EVT, status %d, attr_handle %d, service_handle %d\n",
--- /dev/null
+#
+# This is a project Makefile. It is assumed the directory this Makefile resides in is a
+# project subdirectory.
+#
+
+PROJECT_NAME := gatt_server_table_creat_demo
+
+COMPONENT_ADD_INCLUDEDIRS := components/include
+
+include $(IDF_PATH)/make/project.mk
+
--- /dev/null
+ESP-IDF GATT SERVER create attribute table demo
+===============================================
+
+This is the demo for user to use ESP_APIs to create a GATT Server attribute table.
+The table is easy to use to create GATT server service database without use each "attribute create" functions.
+Actually, there are two way to create server service and characteristics.
+One is use the esp_gatts_create_service or esp_ble_gatts_add_char and etc.
+The other way is use esp_ble_gatts_create_attr_tab.
+The important things: the two ways cannot use in the same service, but can use in different service.
+
--- /dev/null
+#
+# Main Makefile. This is basically the same as a component makefile.
+#
+# This Makefile should, at the very least, just include $(SDK_PATH)/make/component_common.mk. By default,
+# this will take the sources in the src/ directory, compile them and link them into
+# lib(subdirectory_name).a in the build directory. This behaviour is entirely configurable,
+# please read the ESP-IDF documents if you need to do this.
+#
--- /dev/null
+// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+
+#include "freertos/FreeRTOS.h"
+#include "freertos/task.h"
+#include "freertos/event_groups.h"
+#include "esp_system.h"
+#include "esp_log.h"
+#include "nvs_flash.h"
+#include "bt.h"
+#include "bta_api.h"
+
+#include "esp_gap_ble_api.h"
+#include "esp_gatts_api.h"
+#include "esp_bt_defs.h"
+#include "esp_bt_main.h"
+#include "esp_bt_main.h"
+#include "gatts_table_creat_demo.h"
+
+
+#define HEART_PROFILE_NUM 1
+#define HEART_PROFILE_APP_IDX 0
+#define ESP_HEART_RATE_APP_ID 0x55
+#define SAMPLE_DEVICE_NAME "ESP_HEART_RATE"
+#define SAMPLE_MANUFACTURER_DATA_LEN 17
+#define HEART_RATE_SVC_INST_ID 0
+
+#define GATTS_DEMO_CHAR_VAL_LEN_MAX 0x40
+
+uint8_t char1_str[] ={0x11,0x22,0x33};
+
+uint16_t heart_rate_handle_table[HRS_IDX_NB];
+
+esp_attr_value_t gatts_demo_char1_val =
+{
+ .attr_max_len = GATTS_DEMO_CHAR_VAL_LEN_MAX,
+ .attr_len = sizeof(char1_str),
+ .attr_value = char1_str,
+};
+
+
+static uint8_t heart_rate_service_uuid[16] = {
+ /* LSB <--------------------------------------------------------------------------------> MSB */
+ //first uuid, 16bit, [12],[13] is the value
+ 0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80, 0x00, 0x10, 0x00, 0x00, 0x18, 0x0D, 0x00, 0x00,
+};
+
+
+static esp_ble_adv_data_t heart_rate_adv_config = {
+ .set_scan_rsp = false,
+ .include_name = true,
+ .include_txpower = true,
+ .min_interval = 0x20,
+ .max_interval = 0x40,
+ .appearance = 0x00,
+ .manufacturer_len = 0, //TEST_MANUFACTURER_DATA_LEN,
+ .p_manufacturer_data = NULL, //&test_manufacturer[0],
+ .service_data_len = 0,
+ .p_service_data = NULL,
+ .service_uuid_len = 32,
+ .p_service_uuid = heart_rate_service_uuid,
+ .flag = (ESP_BLE_ADV_FLAG_GEN_DISC | ESP_BLE_ADV_FLAG_BREDR_NOT_SPT),
+};
+
+static esp_ble_adv_params_t heart_rate_adv_params = {
+ .adv_int_min = 0x20,
+ .adv_int_max = 0x40,
+ .adv_type = ADV_TYPE_IND,
+ .own_addr_type = BLE_ADDR_TYPE_PUBLIC,
+ //.peer_addr =
+ //.peer_addr_type =
+ .channel_map = ADV_CHNL_ALL,
+ .adv_filter_policy = ADV_FILTER_ALLOW_SCAN_ANY_CON_ANY,
+};
+
+struct gatts_profile_inst {
+ esp_gatts_cb_t gatts_cb;
+ uint16_t gatts_if;
+ uint16_t app_id;
+ uint16_t conn_id;
+ uint16_t service_handle;
+ esp_gatt_srvc_id_t service_id;
+ uint16_t char_handle;
+ esp_bt_uuid_t char_uuid;
+ esp_gatt_perm_t perm;
+ esp_gatt_char_prop_t property;
+ uint16_t descr_handle;
+ esp_bt_uuid_t descr_uuid;
+};
+
+static void gatts_profile_event_handler(esp_gatts_cb_event_t event,
+ esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param);
+
+/* One gatt-based profile one app_id and one gatts_if, this array will store the gatts_if returned by ESP_GATTS_REG_EVT */
+static struct gatts_profile_inst heart_rate_profile_tab[HEART_PROFILE_NUM] = {
+ [HEART_PROFILE_APP_IDX] = {
+ .gatts_cb = gatts_profile_event_handler,
+ .gatts_if = ESP_GATT_IF_NONE, /* Not get the gatt_if, so initial is ESP_GATT_IF_NONE */
+ },
+
+};
+
+/*
+ * HTPT PROFILE ATTRIBUTES
+ ****************************************************************************************
+ */
+
+/// Full HRS Database Description - Used to add attributes into the database
+const esp_gatts_attr_db_t heart_rate_gatt_db[HRS_IDX_NB] =
+{
+ // Heart Rate Service Declaration
+ [HRS_IDX_SVC] = {{ESP_GATT_AUTO_RSP}, {
+ {ESP_UUID_LEN_16, {ESP_GATT_UUID_PRI_SERVICE}},
+ ESP_GATT_PERM_READ,
+ sizeof(heart_rate_svc),
+ sizeof(heart_rate_svc), (uint8_t *)&heart_rate_svc}},
+
+ // Heart Rate Measurement Characteristic Declaration
+ [HRS_IDX_HR_MEAS_CHAR] = {{ESP_GATT_AUTO_RSP}, {
+ {ESP_UUID_LEN_16, {ESP_GATT_UUID_CHAR_DECLARE}},
+ ESP_GATT_PERM_READ,
+ sizeof(heart_rate_meas_char),
+ sizeof(heart_rate_meas_char), (uint8_t *)&heart_rate_meas_char}},
+ // Heart Rate Measurement Characteristic Value
+ [HRS_IDX_HR_MEAS_VAL] = {{ESP_GATT_AUTO_RSP}, {
+ {ESP_UUID_LEN_16, {ESP_GATT_HEART_RATE_MEAS}},
+ ESP_GATT_PERM_READ,
+ HRPS_HT_MEAS_MAX_LEN,
+ 0, NULL}},
+
+ // Heart Rate Measurement Characteristic - Client Characteristic Configuration Descriptor
+ [HRS_IDX_HR_MEAS_NTF_CFG] = {{ESP_GATT_AUTO_RSP}, {
+ {ESP_UUID_LEN_16, {ESP_GATT_UUID_CHAR_SRVR_CONFIG}},
+ ESP_GATT_PERM_READ|ESP_GATT_PERM_WRITE,
+ sizeof(uint16_t),
+ 0, NULL}},
+
+ // Body Sensor Location Characteristic Declaration
+ [HRS_IDX_BOBY_SENSOR_LOC_CHAR] = {{ESP_GATT_AUTO_RSP}, {
+ {ESP_UUID_LEN_16, {ESP_GATT_UUID_CHAR_DECLARE}},
+ ESP_GATT_PERM_READ,
+ sizeof(heart_rate_body_sensor_loc_char),
+ sizeof(heart_rate_body_sensor_loc_char), (uint8_t *)&heart_rate_body_sensor_loc_char}},
+
+ // Body Sensor Location Characteristic Value
+ [HRS_IDX_BOBY_SENSOR_LOC_VAL] = {{ESP_GATT_AUTO_RSP}, {
+ {ESP_UUID_LEN_16, {ESP_GATT_BODY_SENSOR_LOCATION}},
+ ESP_GATT_PERM_READ,
+ sizeof(uint8_t),
+ 0, NULL}},
+
+ // Heart Rate Control Point Characteristic Declaration
+ [HRS_IDX_HR_CTNL_PT_CHAR] = {{ESP_GATT_AUTO_RSP}, {
+ {ESP_UUID_LEN_16, {ESP_GATT_UUID_CHAR_DECLARE}},
+ ESP_GATT_PERM_READ,
+ sizeof(heart_rate_cntl_point_char),
+ sizeof(heart_rate_cntl_point_char), (uint8_t *)&heart_rate_cntl_point_char}},
+
+ // Heart Rate Control Point Characteristic Value
+ [HRS_IDX_HR_CTNL_PT_VAL] = {{ESP_GATT_AUTO_RSP}, {
+ {ESP_UUID_LEN_16, {ESP_GATT_HEART_RATE_CNTL_POINT}},
+ ESP_GATT_PERM_WRITE,
+ sizeof(uint8_t),
+ 0, NULL}},
+};
+
+/*
+ * Heart Rate PROFILE ATTRIBUTES
+ ****************************************************************************************
+ */
+
+/// Heart Rate Sensor Service
+const uint16_t heart_rate_svc = ESP_GATT_UUID_HEART_RATE_SVC;
+
+/// Heart Rate Sensor Service - Heart Rate Measurement Characteristic
+const esp_gatts_char_desc_t heart_rate_meas_char =
+{
+ .prop = ESP_GATT_CHAR_PROP_BIT_NOTIFY,
+ .attr_hdl = 0,
+ .attr_uuid = {ESP_UUID_LEN_16, {ESP_GATT_HEART_RATE_MEAS}},
+};
+
+/// Heart Rate Sensor Service -Body Sensor Location characteristic
+const esp_gatts_char_desc_t heart_rate_body_sensor_loc_char =
+{
+ .prop = ESP_GATT_CHAR_PROP_BIT_READ,
+ .attr_hdl = 0,
+ .attr_uuid = {ESP_UUID_LEN_16, {ESP_GATT_BODY_SENSOR_LOCATION}},
+};
+
+/// Heart Rate Sensor Service - Heart Rate Control Point characteristic
+const esp_gatts_char_desc_t heart_rate_cntl_point_char =
+{
+ .prop = ESP_GATT_CHAR_PROP_BIT_WRITE,
+ .attr_hdl = 0,
+ .attr_uuid = {ESP_UUID_LEN_16, {ESP_GATT_HEART_RATE_CNTL_POINT}},
+};
+
+static void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param)
+{
+ LOG_ERROR("GAP_EVT, event %d\n", event);
+
+ switch (event) {
+ case ESP_GAP_BLE_ADV_DATA_SET_COMPLETE_EVT:
+ esp_ble_gap_start_advertising(&heart_rate_adv_params);
+ break;
+ default:
+ break;
+ }
+}
+
+static void gatts_profile_event_handler(esp_gatts_cb_event_t event,
+ esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param)
+{\r
+ LOG_ERROR("event = %x\n",event);
+ switch (event) {
+ case ESP_GATTS_REG_EVT:
+ LOG_INFO("%s %d\n", __func__, __LINE__);
+ esp_ble_gap_set_device_name(SAMPLE_DEVICE_NAME);
+ LOG_INFO("%s %d\n", __func__, __LINE__);
+ esp_ble_gap_config_adv_data(&heart_rate_adv_config);
+
+ LOG_INFO("%s %d\n", __func__, __LINE__);
+ esp_ble_gatts_create_attr_tab(heart_rate_gatt_db, gatts_if,
+ HRS_IDX_NB, HEART_RATE_SVC_INST_ID);
+ break;
+ case ESP_GATTS_READ_EVT:
+
+ break;
+ case ESP_GATTS_WRITE_EVT:
+ break;
+ case ESP_GATTS_EXEC_WRITE_EVT:
+ break;
+ case ESP_GATTS_MTU_EVT:
+ break;
+ case ESP_GATTS_CONF_EVT:
+ break;
+ case ESP_GATTS_UNREG_EVT:
+ break;
+ case ESP_GATTS_DELETE_EVT:
+ break;
+ case ESP_GATTS_START_EVT:
+ break;
+ case ESP_GATTS_STOP_EVT:
+ break;
+ case ESP_GATTS_CONNECT_EVT:
+ break;
+ case ESP_GATTS_DISCONNECT_EVT:
+ break;
+ case ESP_GATTS_OPEN_EVT:
+ break;
+ case ESP_GATTS_CANCEL_OPEN_EVT:
+ break;
+ case ESP_GATTS_CLOSE_EVT:
+ break;
+ case ESP_GATTS_LISTEN_EVT:
+ break;
+ case ESP_GATTS_CONGEST_EVT:
+ break;
+ case ESP_GATTS_CREAT_ATTR_TAB_EVT:{
+ LOG_ERROR("The number handle =%x\n",param->add_attr_tab.num_handle);
+ if(param->add_attr_tab.num_handle == HRS_IDX_NB){
+ memcpy(heart_rate_handle_table, param->add_attr_tab.handles,
+ sizeof(heart_rate_handle_table));
+ esp_ble_gatts_start_service(heart_rate_handle_table[HRS_IDX_SVC]);
+ }
+
+ break;
+ }
+
+ default:
+ break;
+ }
+}
+
+
+static void gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if,
+ esp_ble_gatts_cb_param_t *param)
+{
+ LOG_INFO("EVT %d, gatts if %d\n", event, gatts_if);
+
+ /* If event is register event, store the gatts_if for each profile */
+ if (event == ESP_GATTS_REG_EVT) {
+ if (param->reg.status == ESP_GATT_OK) {
+ heart_rate_profile_tab[HEART_PROFILE_APP_IDX].gatts_if = gatts_if;
+ } else {
+ LOG_INFO("Reg app failed, app_id %04x, status %d\n",
+ param->reg.app_id,
+ param->reg.status);
+ return;
+ }
+ }
+
+ do {
+ int idx;
+ for (idx = 0; idx < HEART_PROFILE_NUM; idx++) {
+ if (gatts_if == ESP_GATT_IF_NONE || /* ESP_GATT_IF_NONE, not specify a certain gatt_if, need to call every profile cb function */
+ gatts_if == heart_rate_profile_tab[idx].gatts_if) {
+ if (heart_rate_profile_tab[idx].gatts_cb) {
+ heart_rate_profile_tab[idx].gatts_cb(event, gatts_if, param);
+ }
+ }
+ }
+ } while (0);
+}
+
+void app_main()
+{
+ esp_err_t ret;
+
+ esp_bt_controller_init();
+ LOG_INFO("%s init bluetooth\n", __func__);
+ ret = esp_bluedroid_init();
+ if (ret) {
+ LOG_ERROR("%s init bluetooth failed\n", __func__);
+ return;
+ }
+ ret = esp_bluedroid_enable();
+ if (ret) {
+ LOG_ERROR("%s enable bluetooth failed\n", __func__);
+ return;
+ }
+
+ esp_ble_gatts_register_callback(gatts_event_handler);
+ esp_ble_gap_register_callback(gap_event_handler);
+ esp_ble_gatts_app_register(ESP_HEART_RATE_APP_ID);
+ return;
+}
--- /dev/null
+// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/*
+ * DEFINES
+ ****************************************************************************************
+ */
+
+#define HRPS_HT_MEAS_MAX_LEN (13)
+
+#define HRPS_MANDATORY_MASK (0x0F)
+#define HRPS_BODY_SENSOR_LOC_MASK (0x30)
+#define HRPS_HR_CTNL_PT_MASK (0xC0)
+
+
+///Attributes State Machine
+enum
+{
+ HRS_IDX_SVC,
+
+ HRS_IDX_HR_MEAS_CHAR,
+ HRS_IDX_HR_MEAS_VAL,
+ HRS_IDX_HR_MEAS_NTF_CFG,
+
+ HRS_IDX_BOBY_SENSOR_LOC_CHAR,
+ HRS_IDX_BOBY_SENSOR_LOC_VAL,
+
+ HRS_IDX_HR_CTNL_PT_CHAR,
+ HRS_IDX_HR_CTNL_PT_VAL,
+
+ HRS_IDX_NB,
+};
+
+
+extern const esp_gatts_attr_db_t heart_rate_gatt_db[HRS_IDX_NB];
+/// Heart Rate Sensor Service - only one instance for now
+extern const uint16_t heart_rate_svc;
+
+extern const esp_gatts_char_desc_t heart_rate_meas_char;
+extern const esp_gatts_char_desc_t heart_rate_body_sensor_loc_char;
+extern const esp_gatts_char_desc_t heart_rate_cntl_point_char;
--- /dev/null
+# Override some defaults so BT stack is enabled
+# in this example
+
+#
+# BT config
+#
+CONFIG_BT_ENABLED=y
+
+#
+# ESP32-specific config
+#
+CONFIG_ESP32_ENABLE_STACK_BT=y
+# CONFIG_ESP32_ENABLE_STACK_NONE is not set
+CONFIG_MEMMAP_BT=y