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);
163 log_debug(
"Called into pre 5.17 %s", __func__);
165 cleanup_all_service(service, no_svc);
166 return ACE_STATUS_OK;
169status_t pre5170_bleReadCharacteristic(
173 log_debug(
"Called into pre 5.17 %s", __func__);
176 aipcHandles_t handle;
178 status = getSessionInfo(session_handle, &handle);
179 if (status != ACE_STATUS_OK) {
180 log_error(
"[%s()]: Couldn't get session info. Result: %d", __func__, status);
181 return ACE_STATUS_BAD_PARAM;
184 acebt_gattc_read_chars_req_data_t data;
185 serialize_gattc_read_chars_req(&data, (uint32_t)conn_handle, chars_value);
186 log_debug(
"[%s()]: Serialize request, status: %d", __func__, data.status);
188 status = aipc_invoke_sync_call(ACE_BT_BLE_GATT_CLIENT_READ_CHARS_API, &data, data.size);
189 if (status != ACE_STATUS_OK) {
190 log_error(
"[%s()]: Failed to send AIPC call. Status: %d", __func__, status);
195status_t pre5170_bleWriteCharacteristics(
199 log_debug(
"Called into pre 5.17 %s", __func__);
202 aipcHandles_t handle;
204 status = getSessionInfo(session_handle, &handle);
205 if (status != ACE_STATUS_OK) {
206 log_error(
"[%s()]: Couldn't get session info. Result: %d", __func__, status);
207 return ACE_STATUS_BAD_PARAM;
213 serialize_gattc_write_char_req(
214 (uint32_t)conn_handle, chars_value, &out_data, &out_len, request_type
217 if (out_data == NULL) {
218 log_error(
"[%s()]: Failed serialize_gattc_write_char_req", __func__);
219 return ACE_STATUS_GENERAL_ERROR;
222 status = aipc_invoke_sync_call(ACE_BT_BLE_GATT_CLIENT_WRITE_CHARS_API, out_data, out_len);
223 if (status != ACE_STATUS_OK) {
224 log_error(
"[%s()]: Failed to send AIPC call. Status: %d", __func__, status);
228 shadow_aceAlloc_free(out_data);
237 log_debug(
"Called into pre 5.17 %s", __func__);
240 aipcHandles_t handle;
242 status = getSessionInfo(session_handle, &handle);
243 if (status != ACE_STATUS_OK) {
244 log_error(
"[%s()]: Couldn't get session info. Result: %d", __func__, status);
245 return ACE_STATUS_BAD_PARAM;
251 serialize_gattc_write_desc_req(
252 (uint32_t)conn_handle, &chars_value->gattDescriptor, &out_data, &out_len, request_type
254 if (out_data == NULL) {
255 log_error(
"[%s()]: serialize_gattc_write_desc_req() failed", __func__);
256 return ACE_STATUS_GENERAL_ERROR;
259 status = aipc_invoke_sync_call(ACE_BT_BLE_GATT_CLIENT_WRITE_DESC_API, out_data, out_len);
260 if (status == ACE_STATUS_OK) {
261 status = ((
const gattc_write_desc_data_t*)out_data)->status;
263 log_error(
"[%s()]: Failed to send AIPC call. Status: %d", __func__, status);
264 status = ACE_STATUS_BAD_PARAM;
267 shadow_aceAlloc_free(out_data);
276 log_debug(
"Called into pre 5.17 %s", __func__);
279 aipcHandles_t handle;
281 status = getSessionInfo(session_handle, &handle);
282 if (status != ACE_STATUS_OK) {
283 log_error(
"[%s()]: Couldn't get session info. Result: %d", __func__, status);
284 return ACE_STATUS_BAD_PARAM;
287 gattc_set_notify_data_t data;
288 serialize_ble_set_notify(&data, (uint32_t)conn_handle, chars_value, enable);
290 status = aipc_invoke_sync_call(ACE_BT_BLE_GATT_CLIENT_SET_NOTIFY_API, &data, data.size);
291 if (status != ACE_STATUS_OK) {
292 log_error(
"[%s()]: Failed to send AIPC call. Status: %d", __func__, status);
296 struct aceBT_gattDescRec_t* desc_rec = NULL;
297 STAILQ_FOREACH(desc_rec, &chars_value.descList, link) {
298 if (desc_rec->value.is_set && desc_rec->value.is_notify)
break;
301 if (desc_rec == NULL) {
303 "[%s()]: Couldn't find CCCD descriptor. Are you sure this characteristic supports "
307 return ACE_STATUS_BAD_PARAM;
311 uint8_t subscription[2];
312 uint16_t le = htole16((uint16_t)enable);
313 memcpy(subscription, &le,
sizeof(le));
316 chars_value.gattDescriptor.gattRecord.handle = desc_rec->value.gattRecord.handle;
317 chars_value.gattDescriptor.blobValue.data = malloc(
sizeof(subscription));
318 if (chars_value.gattDescriptor.blobValue.data == NULL) {
319 log_error(
"[%s()]: Couldn't allocate memory for CCCD descriptor?", __func__);
320 return ACE_STATUS_OUT_OF_MEMORY;
322 chars_value.gattDescriptor.blobValue.offset = 0;
323 chars_value.gattDescriptor.blobValue.size =
sizeof(subscription);
324 memcpy(chars_value.gattDescriptor.blobValue.data, subscription,
sizeof(subscription));
326 status = shim_bleWriteDescriptor(
327 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_bleGattsService_t bleGattsService_t
Structure for a GATT Server service.
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.