1#include <kindlebt/compat_ace_implementations.h>
10#include <kindlebt/compat_ace_handler.h>
11#include <kindlebt/compat_ace_internals.h>
12#include <kindlebt/compat_ace_shims.h>
13#include <kindlebt/compat_ace_utils.h>
14#include <kindlebt/compat_acealloc.h>
24 uint16_t cback_mask = 0;
25 if (p_callbacks == NULL || p_callbacks->size == 0)
return cback_mask;
26 cback_mask |= p_callbacks->on_ble_gattc_service_registered_cb
27 ? ACEBT_IPC_CBACK_MASK_GATTC_SERVICE_REGISTERED
29 cback_mask |= p_callbacks->on_ble_gattc_service_discovered_cb
30 ? ACEBT_IPC_CBACK_MASK_GATTC_SERVICE_DISCOVERED
32 cback_mask |= p_callbacks->on_ble_gattc_read_characteristics_cb
33 ? ACEBT_IPC_CBACK_MASK_GATTC_SERVICE_READ_CHARS
35 cback_mask |= p_callbacks->on_ble_gattc_write_characteristics_cb
36 ? ACEBT_IPC_CBACK_MASK_GATTC_SERVICE_WRITE_CHARS
38 cback_mask |= p_callbacks->notify_characteristics_cb
39 ? ACEBT_IPC_CBACK_MASK_GATTC_SERVICE_NOTIFY_CHARS
41 cback_mask |= p_callbacks->on_ble_gattc_write_descriptor_cb
42 ? ACEBT_IPC_CBACK_MASK_GATTC_SERVICE_DESC_WRITE
44 cback_mask |= p_callbacks->on_ble_gattc_read_descriptor_cb
45 ? ACEBT_IPC_CBACK_MASK_GATTC_SERVICE_DESC_READ
47 cback_mask |= p_callbacks->on_ble_gattc_get_gatt_db_cb ? ACEBT_IPC_CBACK_MASK_GATTC_GET_DB : 0;
49 p_callbacks->on_ble_gattc_execute_write_cb ? ACEBT_IPC_CBACK_MASK_GATTC_EXECUTE_WRITE : 0;
53status_t pre5170_bleRegisterGattClient(
58 aipcHandles_t aipc_handle;
59 registerCbackGattcData_t manager_callbacks;
61 status = getSessionInfo(session_handle, &aipc_handle);
62 if (status != ACE_STATUS_OK) {
63 log_error(
"[%s()]: Couldn't get session info. Result %d", __func__, status);
64 return ACE_STATUS_BAD_PARAM;
67 dump_aipc_handle(aipc_handle);
69 mask = create_client_callback_mask(callbacks);
73 uint32_t temp_aipc = (aipc_handle.server_id << 16) + aipc_handle.callback_server_id;
74 log_debug(
"[%s()]: temp_aipc %u (0x%04x)", __func__, temp_aipc, temp_aipc);
75 aceBt_serializeGattcRegisterData(&manager_callbacks, temp_aipc, mask, app_id);
76 log_debug(
"[%s()]: Register GATT Client session handle %p", __func__, session_handle);
78 dump_registerCbackGattcData(&manager_callbacks);
80 status = registerBTClientData(session_handle, CALLBACK_INDEX_BLE_GATT_CLIENT, (
void*)callbacks);
81 log_debug(
"[%s()]: registerBTClientData step. Result: %d", __func__, status);
82 if (status != ACEBT_STATUS_SUCCESS)
return status;
84 status = registerBTEvtHandler(
85 session_handle, pre5170_gattc_cb_handler, ACE_BT_CALLBACK_GATTC_INIT,
86 ACE_BT_CALLBACK_GATTC_MAX
88 log_debug(
"[%s()]: registerBTEvtHandler step. Result: %d", __func__, status);
89 if (status != ACEBT_STATUS_SUCCESS)
return status;
91 status = aipc_invoke_sync_call(
92 ACE_BT_BLE_REGISTER_GATT_CLIENT_API, (
void*)&manager_callbacks, manager_callbacks.size
94 if (status != ACE_STATUS_OK) {
96 "[%s()]: failed to register gatt client callbacks with server! result: %d", __func__,
99 registerBTClientData(session_handle, CALLBACK_INDEX_BLE_GATT_CLIENT, NULL);
100 registerBTEvtHandler(
101 session_handle, NULL, ACE_BT_CALLBACK_GATTC_INIT, ACE_BT_CALLBACK_GATTC_MAX
112 status = getSessionInfo(session_handle, &unregister.h1);
113 if (status != ACE_STATUS_OK) {
114 log_error(
"[%s()]: Couldn't get session info. Result %d", __func__, status);
115 return ACE_STATUS_BAD_PARAM;
118 dump_aipc_handle(unregister.h1);
120 unregister.h2 = unregister.h1;
121 unregister.size =
sizeof(unregister);
124 aipc_invoke_sync_call(ACE_BT_BLE_UNREGISTER_GATT_CLIENT_API, &unregister, unregister.size);
125 if (status != ACE_STATUS_OK) {
126 log_error(
"[%s()]: Failed to send AIPC call %d", __func__, status);
133 log_debug(
"Called into pre 5.17 %s", __func__);
136 request_disc_all_svc_t data;
138 serialize_gattc_disc_all_svc(&data, (uint32_t)conn_handle);
139 status = aipc_invoke_sync_call(ACE_BT_BLE_GATT_CLIENT_DISC_ALL_SVC_API, &data, data.size);
140 if (status != ACE_STATUS_OK) {
141 log_error(
"[%s()]: Failed to send AIPC call. Status: %d", __func__, status);
143 return data.out_status;
147 log_debug(
"Called into pre 5.17 %s", __func__);
150 gattc_get_db_data_t data;
152 serialize_ble_get_db_req(&data, (uint32_t)conn_handle, NULL);
153 dump_gattc_get_db_data_t(&data);
155 status = aipc_invoke_sync_call(ACE_BT_BLE_GATT_CLIENT_GET_SERVICE_API, &data, data.size);
156 if (status != ACE_STATUS_OK) {
157 log_error(
"[%s()]: Failed to send AIPC call. Status: %d", __func__, status);
162status_t pre5170_bleReadCharacteristic(
166 log_debug(
"Called into pre 5.17 %s", __func__);
169 aipcHandles_t handle;
171 status = getSessionInfo(session_handle, &handle);
172 if (status != ACE_STATUS_OK) {
173 log_error(
"[%s()]: Couldn't get session info. Result: %d", __func__, status);
174 return ACE_STATUS_BAD_PARAM;
177 acebt_gattc_read_chars_req_data_t data;
178 serialize_gattc_read_chars_req(&data, (uint32_t)conn_handle, chars_value);
179 log_debug(
"[%s()]: Serialize request, status: %d", __func__, data.status);
181 status = aipc_invoke_sync_call(ACE_BT_BLE_GATT_CLIENT_READ_CHARS_API, &data, data.size);
182 if (status != ACE_STATUS_OK) {
183 log_error(
"[%s()]: Failed to send AIPC call. Status: %d", __func__, status);
188status_t pre5170_bleWriteCharacteristics(
192 log_debug(
"Called into pre 5.17 %s", __func__);
195 aipcHandles_t handle;
197 status = getSessionInfo(session_handle, &handle);
198 if (status != ACE_STATUS_OK) {
199 log_error(
"[%s()]: Couldn't get session info. Result: %d", __func__, status);
200 return ACE_STATUS_BAD_PARAM;
206 serialize_gattc_write_char_req(
207 (uint32_t)conn_handle, chars_value, &out_data, &out_len, request_type
210 if (out_data == NULL) {
211 log_error(
"[%s()]: Failed serialize_gattc_write_char_req", __func__);
212 return ACE_STATUS_GENERAL_ERROR;
215 status = aipc_invoke_sync_call(ACE_BT_BLE_GATT_CLIENT_WRITE_CHARS_API, out_data, out_len);
216 if (status != ACE_STATUS_OK) {
217 log_error(
"[%s()]: Failed to send AIPC call. Status: %d", __func__, status);
221 shadow_aceAlloc_free(out_data);
230 log_debug(
"Called into pre 5.17 %s", __func__);
233 aipcHandles_t handle;
235 status = getSessionInfo(session_handle, &handle);
236 if (status != ACE_STATUS_OK) {
237 log_error(
"[%s()]: Couldn't get session info. Result: %d", __func__, status);
238 return ACE_STATUS_BAD_PARAM;
244 serialize_gattc_write_desc_req(
245 (uint32_t)conn_handle, &chars_value->gattDescriptor, &out_data, &out_len, request_type
247 if (out_data == NULL) {
248 log_error(
"[%s()]: serialize_gattc_write_desc_req() failed", __func__);
249 return ACE_STATUS_GENERAL_ERROR;
252 status = aipc_invoke_sync_call(ACE_BT_BLE_GATT_CLIENT_WRITE_DESC_API, out_data, out_len);
253 if (status == ACE_STATUS_OK) {
254 status = ((
const gattc_write_desc_data_t*)out_data)->status;
256 log_error(
"[%s()]: Failed to send AIPC call. Status: %d", __func__, status);
257 status = ACE_STATUS_BAD_PARAM;
260 shadow_aceAlloc_free(out_data);
269 log_debug(
"Called into pre 5.17 %s", __func__);
272 aipcHandles_t handle;
274 status = getSessionInfo(session_handle, &handle);
275 if (status != ACE_STATUS_OK) {
276 log_error(
"[%s()]: Couldn't get session info. Result: %d", __func__, status);
277 return ACE_STATUS_BAD_PARAM;
280 gattc_set_notify_data_t data;
281 serialize_ble_set_notify(&data, (uint32_t)conn_handle, chars_value, enable);
283 status = aipc_invoke_sync_call(ACE_BT_BLE_GATT_CLIENT_SET_NOTIFY_API, &data, data.size);
284 if (status != ACE_STATUS_OK) {
285 log_error(
"[%s()]: Failed to send AIPC call. Status: %d", __func__, status);
289 struct aceBT_gattDescRec_t* desc_rec = NULL;
290 STAILQ_FOREACH(desc_rec, &chars_value.descList, link) {
291 if (desc_rec->value.is_set && desc_rec->value.is_notify)
break;
294 if (desc_rec == NULL) {
296 "[%s()]: Couldn't find CCCD descriptor. Are you sure this characteristic supports "
300 return ACE_STATUS_BAD_PARAM;
304 uint8_t subscription[2];
305 uint16_t le = htole16((uint16_t)enable);
306 memcpy(subscription, &le,
sizeof(le));
309 chars_value.gattDescriptor.gattRecord.handle = desc_rec->value.gattRecord.handle;
310 chars_value.gattDescriptor.blobValue.data = malloc(
sizeof(subscription));
311 if (chars_value.gattDescriptor.blobValue.data == NULL) {
312 log_error(
"[%s()]: Couldn't allocate memory for CCCD descriptor?", __func__);
313 return ACE_STATUS_OUT_OF_MEMORY;
315 chars_value.gattDescriptor.blobValue.offset = 0;
316 chars_value.gattDescriptor.blobValue.size =
sizeof(subscription);
317 memcpy(chars_value.gattDescriptor.blobValue.data, subscription,
sizeof(subscription));
319 status = shim_bleWriteDescriptor(
320 session_handle, conn_handle, &chars_value, ACEBT_BLE_WRITE_TYPE_RESP_REQUIRED
aceBT_bleGattClientCallbacks_t bleGattClientCallbacks_t
Callback struct of GATT Client Bluetooth operations.
aceBt_bleAppId_t bleAppId_t
BLE application type.
aceBT_responseType_t responseType_t
Type of write operation for a BLE characteristic.
ace_status_t status_t
Bluetooth API status codes.
aceBT_bleConnHandle bleConnHandle
Connection handle for the lifetime of a Bluetooth connection.
aceBT_sessionHandle sessionHandle
Session handle for the lifetime of the Bluetooth application.
aceBT_bleGattCharacteristicsValue_t bleGattCharacteristicsValue_t
BLE GATT Characteristic.