Bluetooth GATT Service Exported Functions
- group BT_GATT_SERVICE_Exported_Functions
-
Functions
-
bool gatt_svc_add(T_SERVER_ID *p_out_service_id, uint8_t *p_database, uint16_t length, const T_FUN_GATT_EXT_SERVICE_CBS *p_srv_ext_cbs, P_FUN_GATT_EXT_SEND_DATA_CB p_srv_ext_send_data_cb)
-
Register specific service.
Example usage
//case 1 bool bass_add_service(uint8_t brs_num) { T_SERVER_ID service_id; uint16_t attr_tbl_size = sizeof(bass_attr_tbl); attr_tbl_size -= (BASS_BRS_CHAR_MAX_NUM - brs_num) * 3 * sizeof(T_ATTRIB_APPL); if (false == gatt_svc_add(&service_id, (uint8_t *)bass_attr_tbl, attr_tbl_size, &bass_cbs, bass_send_data_cb)) { PROTOCOL_PRINT_ERROR0("bass_add_service: failed"); return false; } p_bass->service_id = service_id; return true; } void bass_send_data_cb(T_EXT_SEND_DATA_RESULT result) { PROTOCOL_PRINT_INFO6("bass_send_data_cb: credits %d, conn_handle 0x%x, cid 0x%x, service_id %d, attr_idx %d, cause 0x%x", result.credits, result.conn_handle, result.cid, result.service_id, result.attrib_idx, result.cause); } //case 2 bool bass_add_service(uint8_t brs_num) { T_SERVER_ID service_id; uint16_t attr_tbl_size = sizeof(bass_attr_tbl); attr_tbl_size -= (BASS_BRS_CHAR_MAX_NUM - brs_num) * 3 * sizeof(T_ATTRIB_APPL); if (false == gatt_svc_add(&service_id, (uint8_t *)bass_attr_tbl, attr_tbl_size, &bass_cbs, NULL)) { PROTOCOL_PRINT_ERROR0("bass_add_service: failed"); return false; } p_bass->service_id = service_id; return true; }
Note
Add specific service information to gatt_svc_table struct, will be registered to GATT later.
- Parameters:
p_out_service_id -- [in] Service ID of specific service.
p_database -- [in] Database pointer of specific service.
length -- [in] Length of Database of specific service. T_FUN_GATT_EXT_SERVICE_CBS.
p_srv_ext_cbs -- [in] Service callback functions of specific service. P_FUN_GATT_EXT_SEND_DATA_CB.
-
p_srv_ext_send_data_cb -- [in] Callback functions for service to handle the result of send notification or indication.
NULL Application needs to handle PROFILE_EVT_SEND_DATA_COMPLETE directly.
Others Send result through the callback function p_srv_ext_send_data_cb.
- Return values:
true -- Add service success.
false -- Add service failed.
- Returns:
-
Operation result.
-
uint8_t gatt_svc_get_num(void)
-
Get the service table number registered by gatt_svc_add.
- Returns:
-
Registered service table number.
-
bool gatt_svc_read_confirm(uint16_t conn_handle, uint16_t cid, T_SERVER_ID service_id, uint16_t attrib_index, uint8_t *p_data, uint16_t data_len, uint16_t total_len, T_APP_RESULT cause)
-
Confirm from the application when receiving a read request from the client.
Example usage
T_APP_RESULT bass_attr_read_cb(uint16_t conn_handle, uint16_t cid, T_SERVER_ID service_id, uint16_t attrib_index, uint16_t offset, uint16_t *p_length, uint8_t **pp_value) { T_APP_RESULT cause = APP_RESULT_SUCCESS; uint8_t *p_data = NULL; uint16_t len; uint8_t source_id = bass_get_source_id(attrib_index, false); PROTOCOL_PRINT_INFO2("bass_attr_read_cb: attrib_index %d, offset %x", attrib_index, offset); if (source_id == BASS_INVALID_SOURCE_ID) { return APP_RESULT_ATTR_NOT_FOUND; } if (bass_brs_gen_char_data(source_id, &p_data, &len)) { if (offset > len) { cause = APP_RESULT_INVALID_OFFSET; } else { if (gatt_svc_read_confirm(conn_handle, cid, p_bass->service_id, attrib_index, p_data + offset, len - offset, len, APP_RESULT_SUCCESS)) { cause = APP_RESULT_PENDING; } } if (p_data) { ble_audio_mem_free(p_data); } } return (cause); }
Note
When using this API, the cause shall be set to APP_RESULT_PENDING in the attr_read_cb.
- Parameters:
conn_handle -- [in] Connection handle of the ACL link.
cid -- [in] Local CID assigned by Bluetooth Host.
service_id -- [in] Service ID.
attrib_index -- [in] Attribute index of the attribute to read confirm from the application.
p_data -- [in] Pointer to the read value.
data_len -- [in] The length of the read data.
total_len -- [in] The total length of the data to read.
cause -- [in] Cause for read confirm. T_APP_RESULT.
- Return values:
true -- Confirm from APP OK.
false -- Confirm from APP failed.
- Returns:
-
Operation result.
-
bool gatt_svc_write_confirm(uint16_t conn_handle, uint16_t cid, T_SERVER_ID service_id, uint16_t attrib_index, T_APP_RESULT cause)
-
Confirm from the application when receiving a write request from the client.
Example usageT_USER_CMD_PARSE_RESULT cmd_writeconf(T_USER_CMD_PARSED_VALUE *p_parse_value) { uint8_t conn_id = p_parse_value->dw_param[0]; uint16_t cid = p_parse_value->dw_param[1]; T_SERVER_ID service_id = p_parse_value->dw_param[2]; uint16_t attrib_index = p_parse_value->dw_param[3]; if (!gatt_svc_write_confirm(conn_id, cid, service_id, attrib_index, APP_RESULT_SUCCESS)) { return (RESULT_ERR); } return (RESULT_SUCESS); }
Note
If the process of writing the attribute value does not end immediately, the specific service will call gatt_svc_write_confirm, and the cause shall be set to APP_RESULT_PENDING in the attr_write_cb.
- Parameters:
conn_handle -- [in] Connection handle of the ACL link.
cid -- [in] Local CID assigned by Bluetooth Host.
service_id -- [in] Service ID.
attrib_index -- [in] Attribute index of the attribute to write confirm from the application.
cause -- [in] Write request APP handle result, APP_RESULT_SUCCESS or others.
- Return values:
true -- Confirm from APP OK.
false -- Confirm from APP failed.
- Returns:
-
Operation result.
-
bool gatt_svc_send_data(uint16_t conn_handle, uint16_t cid, T_SERVER_ID service_id, uint16_t attrib_index, uint8_t *p_data, uint16_t data_len, T_GATT_PDU_TYPE type)
-
Send notification or indication to peer device.
Example usage
bool bass_send_brs_notify(T_BLE_AUDIO_LINK *p_link, T_BASS_BRS_DB *p_db) { uint8_t *p_data = NULL; uint16_t len = 0; uint16_t attrib_idx; bool ret = true; attrib_idx = BASS_CHAR_BRS_INDEX + 3 * (p_db->brs_data.source_id - 1); if (bass_brs_gen_char_data(p_db->brs_data.source_id, &p_data, &len)) { if (len > p_link->mtu_size - 3) { len = p_link->mtu_size - 3; } if (gatt_svc_send_data(p_link->conn_handle, L2C_FIXED_CID_ATT, p_bass->service_id, attrib_idx, p_data, len, GATT_PDU_TYPE_NOTIFICATION) == false) { ret = false; } } if (p_data) { ble_audio_mem_free(p_data); } return ret; }
- Parameters:
conn_handle -- [in] Connection handle of the ACL link.
cid -- [in] Local CID assigned by Bluetooth Host.
service_id -- [in] Service ID.
attrib_index -- [in] Attribute index of characteristic.
p_data -- [in] Pointer to data to be sent.
data_len -- [in] Length of value to be sent, range: 0~(mtu_size - 3). uint16_t mtu_size is acquired by le_get_conn_param(GAP_PARAM_CONN_MTU_SIZE, &mtu_size, conn_id).
type -- [in] GATT PDU type.
- Return values:
true -- Success.
false -- Failed.
- Returns:
-
Data sent result.
-
bool gatt_svc_init(uint16_t mode, uint8_t svc_num)
-
Initialize the GATT Service mode and service number.
Example usage
//case 1: The parameter svc_num is 0. void app_ble_service_init(void) { uint8_t server_num = 1; server_register_app_cb(app_ble_service_general_srv_cb); server_init(server_num); gatt_svc_init(GATT_SVC_USE_NORMAL_SERVER, 0); } //case 2: The parameter svc_num is not 0. void app_ble_service_init(void) { uint8_t server_num = 1; gatt_svc_init(GATT_SVC_USE_NORMAL_SERVER, server_num); }
- Parameters:
mode -- [in] GATT Service mode: GATT Service Mode.
-
svc_num -- [in] Set the number of services that need to register.
0 Application shall call server_register_app_cb and server_init to register callback and set service number.
Others Application does not need to call server_register_app_cb and server_init.
- Return values:
true -- Success.
false -- Failed.
- Returns:
-
The result of initializing the GATT Service mode.
-
void gatt_svc_cfg_pending_num(T_GATT_SVC_PENDING_NUM num)
-
Set the Maximum pending packets in the Bluetooth GATT service module.
Example usagevoid test(void) { gatt_svc_init(GATT_SVC_USE_NORMAL_SERVER, server_num); T_GATT_SVC_PENDING_NUM num; num.notify_num = 20; num.ind_num = 10; gatt_svc_cfg_pending_num(num); }
- Parameters:
-
num -- [in] Pending packet number T_GATT_SVC_PENDING_NUM. The default number for notification is 10. The default number for indication is 5.
-
void gatt_svc_register_general_cb(P_FUNC_GATT_SVC_GENERAL_CB svc_cb)
-
Register GATT service general callback function.
Example usagevoid app_ble_service_init(void) { gatt_svc_init(GATT_SVC_USE_NORMAL_SERVER, 1); gatt_svc_register_general_cb(app_gatt_svc_general_cb); } void app_gatt_svc_general_cb(uint8_t type, void *p_data) { if (type == GATT_SVC_EVENT_REG_RESULT) { T_GATT_SVC_REG_RESULT *p_result = (T_GATT_SVC_REG_RESULT *)p_data; APP_PRINT_INFO1("GATT_SVC_EVENT_REG_RESULT: result 0x%x", p_result->result); } else if (type == GATT_SVC_EVENT_REG_AFTER_INIT_RESULT) { T_GATT_SVC_REG_AFTER_INIT_RESULT *p_result = (T_GATT_SVC_REG_AFTER_INIT_RESULT *)p_data; APP_PRINT_INFO2("GATT_SVC_EVENT_REG_AFTER_INIT_RESULT: service_id %d, cause 0x%x", p_result->service_id, p_result->cause); } }
- Parameters:
-
svc_cb -- [in] GATT Service general callback function: P_FUNC_GATT_SVC_GENERAL_CB.
-
bool gatt_svc_handle_profile_data_cmpl(uint16_t conn_handle, uint16_t cid, T_SERVER_ID service_id, uint16_t attrib_idx, uint16_t credits, uint16_t cause)
-
Handle profile send data complete event. Used when receiving the message PROFILE_EVT_SEND_DATA_COMPLETE.
Example usage
T_APP_RESULT app_bqb_ext_profile_callback(T_SERVER_ID service_id, void *p_data) { T_APP_RESULT app_result = APP_RESULT_SUCCESS; if (service_id == SERVICE_PROFILE_GENERAL_ID) { T_SERVER_EXT_APP_CB_DATA *p_param = (T_SERVER_EXT_APP_CB_DATA *)p_data; switch (p_param->eventId) { case PROFILE_EVT_SEND_DATA_COMPLETE: if (!gatt_svc_handle_profile_data_cmpl(p_param->event_data.send_data_result.conn_handle, p_param->event_data.send_data_result.cid, p_param->event_data.send_data_result.service_id, p_param->event_data.send_data_result.attrib_idx, p_param->event_data.send_data_result.credits, p_param->event_data.send_data_result.cause)) { APP_PRINT_ERROR0("gatt_svc_handle_profile_data_cmpl failed"); } break; default: break; } } }
Note
If the application uses the Bluetooth GATT Service module and the parameter svc_num of gatt_svc_init is 0, this function shall be called after receiving PROFILE_EVT_SEND_DATA_COMPLETE.
- Parameters:
conn_handle -- [in] Connection handle of the ACL link.
cid -- [in] Local CID assigned by Bluetooth Host.
service_id -- [in] Service ID.
attrib_idx -- [in] Attribute index of characteristic.
credits -- [in] Credits number.
cause -- [in] Cause of service send data.
- Return values:
true -- Success.
false -- Failed.
- Returns:
-
The result of handling the profile send data complete event.
-
bool gatt_svc_service_changed_indicate(uint16_t conn_handle, uint16_t cid, uint16_t start_handle, uint16_t end_handle)
-
Send service changed indication.
Example usagevoid test(void) { uint16_t start_handle = 0x0001; uint16_t end_handle = 0xFFFF; bool ret = gatt_svc_service_changed_indicate(conn_handle, cid, start_handle, end_handle); }
- Parameters:
conn_handle -- [in] Connection handle of the ACL link.
cid -- [in] Local Channel Identifier assigned by Bluetooth Host.
start_handle -- [in] Start of Affected Attribute Handle Range.
end_handle -- [in] End of Affected Attribute Handle Range.
- Return values:
true -- Sending request is successful.
false -- Sending request is failed.
- Returns:
-
The result of sending operation.
-
T_CHAR_UUID gatt_svc_find_char_uuid_by_index(const T_ATTRIB_APPL *p_srv, uint16_t index, uint16_t attr_num)
-
Find service characteristic uuid by attribute index.
Example usage
T_APP_RESULT tmas_attr_read_cb(uint16_t conn_handle, uint16_t cid, T_SERVER_ID service_id, uint16_t attrib_index, uint16_t offset, uint16_t *p_length, uint8_t **pp_value) { T_APP_RESULT cause = APP_RESULT_SUCCESS; PROTOCOL_PRINT_INFO2("tmas_attr_read_cb: attrib_index %d, offset %x", attrib_index, offset); T_CHAR_UUID char_uuid = gatt_svc_find_char_uuid_by_index(tmas_attr_tbl, attrib_index, sizeof(tmas_attr_tbl) / sizeof(T_ATTRIB_APPL)); if (char_uuid.uuid_size != UUID_16BIT_SIZE) { PROTOCOL_PRINT_ERROR1("tmas_attr_read_cb Error: attrib_index 0x%x", attrib_index); return APP_RESULT_ATTR_NOT_FOUND; } *p_length = 0; switch (char_uuid.uu.char_uuid16) { case TMAS_UUID_CHAR_ROLE: { *pp_value = (uint8_t *)&p_tmas->role; *p_length = 2; } break; default: cause = APP_RESULT_ATTR_NOT_FOUND; break; } return (cause); }
- Parameters:
p_srv -- [in] Pointer to service table: T_ATTRIB_APPL.
index -- [in] Attribute index of characteristic.
attr_num -- [in] Total attribute number of service.
- Returns:
-
The characteristic uuid. T_CHAR_UUID.
-
bool gatt_svc_find_char_index_by_uuid(const T_ATTRIB_APPL *p_srv, T_CHAR_UUID char_uuid, uint16_t attr_num, uint16_t *index)
-
Find service characteristic attribute index by uuid.
Example usage
bool ccp_send_all_notify(T_TBS_CB *p_entry, uint16_t update_cfg, uint16_t uuid, uint8_t *p_data, uint16_t data_len) { uint8_t i; uint16_t attrib_idx; T_CHAR_UUID char_uuid; char_uuid.index = 1; char_uuid.uuid_size = UUID_16BIT_SIZE; char_uuid.uu.char_uuid16 = uuid; if (!gatt_svc_find_char_index_by_uuid(p_entry->p_attr_tbl, char_uuid, p_entry->attr_num, &attrib_idx)) { PROTOCOL_PRINT_ERROR1("[CCP]ccp_send_all_notify: find index failed, uuid 0x%x", uuid); return false; } for (i = 0; i < MAX_BLE_LINK_NUM; i++) { if ((ble_audio_db.le_link[i].used == true) && (ble_audio_db.le_link[i].state == GAP_CONN_STATE_CONNECTED)) { T_LE_SRV_CFG *p_srv = ble_srv_find_by_srv_id(ble_audio_db.le_link[i].conn_handle, p_entry->service_id); if (p_srv != NULL && (p_srv->cccd_cfg[0] & update_cfg)) { if (tbs_send_notify(p_entry, ble_audio_db.le_link[i].conn_handle, attrib_idx, p_data, data_len) == false) { return false; } } } } return true; }
- Parameters:
p_srv -- [in] Pointer to service table. T_ATTRIB_APPL.
char_uuid -- [in] Service characteristic uuid.
attr_num -- [in] Total attribute number of service.
index -- [inout] Attribute index of characteristic.
- Return values:
true -- Success.
false -- Failed.
- Returns:
-
The result of finding service characteristic attribute index.
-
uint16_t gatt_svc_find_char_index_by_uuid16(const T_ATTRIB_APPL *p_srv, uint16_t char_uuid16, uint16_t attr_num)
-
Find service characteristic attribute index by uuid16.
Example usage
bool mics_send_mute_value_notify(uint16_t conn_handle, uint8_t *p_mute_value) { uint16_t attrib_idx = gatt_svc_find_char_index_by_uuid16(p_mics->p_mics_attr_tbl, MICS_UUID_CHAR_MUTE, p_mics->attr_num); return gatt_svc_send_data(conn_handle, L2C_FIXED_CID_ATT, p_mics->service_id, attrib_idx, p_mute_value, 1, GATT_PDU_TYPE_NOTIFICATION); }
- Parameters:
p_srv -- [in] Pointer to service table. T_ATTRIB_APPL.
char_uuid16 -- [in] Characteristic uuid16.
attr_num -- [in] Total attribute numer of service.
- Return values:
-
0 -- Find service characteristic attribute index failed.
- Returns:
-
The characteristic attribute index.
-
bool gatt_svc_add(T_SERVER_ID *p_out_service_id, uint8_t *p_database, uint16_t length, const T_FUN_GATT_EXT_SERVICE_CBS *p_srv_ext_cbs, P_FUN_GATT_EXT_SEND_DATA_CB p_srv_ext_send_data_cb)