diff --git a/android/gatt.c b/android/gatt.c
index d421547..e508bf1 100644
--- a/android/gatt.c
+++ b/android/gatt.c
send_app_connect_notify(conn, GATT_FAILURE);
}
-#define READ_INIT -3
-#define READ_PENDING -2
-#define READ_FAILED -1
+enum pend_req_state {
+ REQUEST_INIT,
+ REQUEST_PENDING,
+ REQUEST_DONE,
+};
struct pending_request {
uint16_t handle;
uint8_t *filter_value;
uint16_t filter_vlen;
+
+ enum pend_req_state state;
+ uint8_t error;
};
static void destroy_pending_request(void *data)
}
case ATT_OP_READ_BLOB_REQ:
val = queue_pop_head(device->pending_requests);
- if (!val || val->length < 0) {
- error = ATT_ECODE_ATTR_NOT_FOUND;
+ if (val->error) {
+ error = val->error;
goto done;
}
break;
case ATT_OP_READ_REQ:
val = queue_pop_head(device->pending_requests);
- if (!val || val->length < 0) {
- error = ATT_ECODE_ATTR_NOT_FOUND;
+ if (val->error) {
+ error = val->error;
goto done;
}
}
case ATT_OP_EXEC_WRITE_REQ:
val = queue_pop_head(device->pending_requests);
- if (!val) {
- error = ATT_ECODE_ATTR_NOT_FOUND;
- break;
+ if (val->error) {
+ error = val->error;
+ goto done;
}
len = enc_exec_write_resp(rsp);
break;
case ATT_OP_WRITE_REQ:
val = queue_pop_head(device->pending_requests);
- if (!val) {
- error = ATT_ECODE_ATTR_NOT_FOUND;
- break;
+ if (val->error) {
+ error = val->error;
+ goto done;
}
len = enc_write_resp(rsp);
break;
case ATT_OP_PREP_WRITE_REQ:
val = queue_pop_head(device->pending_requests);
- if (!val) {
- error = ATT_ECODE_ATTR_NOT_FOUND;
- break;
+ if (val->error) {
+ error = val->error;
+ goto done;
}
len = enc_prep_write_resp(val->handle, val->offset, val->value,
{
const struct pending_request *pending_request = data;
- return pending_request->length == READ_PENDING;
+ return pending_request->state == REQUEST_PENDING;
}
static bool match_dev_request_by_handle(const void *data, const void *user_data)
process_data->opcode,
&process_data->device->bdaddr,
&value, &value_len)) {
- resp_data->length = READ_FAILED;
+ resp_data->state = REQUEST_DONE;
+ resp_data->error = ATT_ECODE_UNLIKELY;
return;
}
resp_data->value = malloc0(value_len);
if (!resp_data->value) {
/* If data cannot be copied, act like when read fails */
- resp_data->length = READ_FAILED;
+ resp_data->state = REQUEST_DONE;
+ resp_data->error = ATT_ECODE_INSUFF_RESOURCES;
return;
}
memcpy(resp_data->value, value, value_len);
resp_data->length = value_len;
- } else if (resp_data->length == READ_INIT) {
- resp_data->length = READ_PENDING;
+ } else if (resp_data->state == REQUEST_INIT) {
+ resp_data->state = REQUEST_PENDING;
}
}
goto done;
}
- if (status)
- goto done;
-
entry = queue_find(dev->pending_requests, match_dev_request_by_handle,
UINT_TO_PTR(handle));
if (!entry) {
entry->handle = handle;
entry->offset = offset;
entry->length = len;
+ entry->state = REQUEST_DONE;
+ entry->error = status;
if (!len)
goto done;
entry->value = malloc0(len);
if (!entry->value) {
- /* send_dev_pending_request on empty queue sends error resp. */
- queue_remove(dev->pending_requests, entry);
- destroy_pending_request(entry);
+ entry->error = ATT_ECODE_INSUFF_RESOURCES;
goto done;
}
}
entry->handle = handle;
- entry->length = READ_INIT;
+ entry->state = REQUEST_INIT;
if (!queue_push_tail(device->pending_requests, entry)) {
queue_remove_all(device->pending_requests, NULL, NULL,
return ATT_ECODE_INSUFF_RESOURCES;
}
- data->length = READ_INIT;
+ data->state = REQUEST_INIT;
data->handle = handle;
queue_push_tail(device->pending_requests, data);
}
data->offset = offset;
data->handle = handle;
- data->length = READ_INIT;
+ data->state = REQUEST_INIT;
if (!queue_push_tail(dev->pending_requests, data)) {
free(data);
return ATT_ECODE_INSUFF_RESOURCES;
return ATT_ECODE_INSUFF_RESOURCES;
}
- data->length = READ_INIT;
+ data->state = REQUEST_INIT;
data->handle = handle;
data->filter_vlen = search_vlen;
memcpy(data->filter_value, search_value, search_vlen);
entry->value = malloc0(strlen(name));
if (!entry->value) {
- queue_remove(dev->pending_requests, entry);
- free(entry);
- return;
+ entry->error = ATT_ECODE_INSUFF_RESOURCES;
+ goto done;
}
entry->length = strlen(name);
} else if (handle == gap_srvc_data.appear) {
entry->value = malloc0(2);
if (!entry->value) {
- queue_remove(dev->pending_requests, entry);
- free(entry);
- return;
+ entry->error = ATT_ECODE_INSUFF_RESOURCES;
+ goto done;
}
put_le16(APPEARANCE_GENERIC_PHONE, entry->value);
} else if (handle == gap_srvc_data.priv) {
entry->value = malloc0(1);
if (!entry->value) {
- queue_remove(dev->pending_requests, entry);
- free(entry);
- return;
+ entry->error = ATT_ECODE_INSUFF_RESOURCES;
+ goto done;
}
*entry->value = PERIPHERAL_PRIVACY_DISABLE;
entry->length = sizeof(uint8_t);
+ } else {
+ entry->error = ATT_ECODE_ATTR_NOT_FOUND;
}
entry->offset = offset;
+
+done:
+ entry->state = REQUEST_DONE;
}
static void register_gap_service(void)
entry->value = malloc0(strlen(buf));
if (!entry->value) {
- queue_remove(dev->pending_requests, entry);
- free(entry);
- return;
+ entry->error = ATT_ECODE_UNLIKELY;
+ goto done;
}
entry->length = strlen(buf);
memcpy(entry->value, buf, entry->length);
entry->offset = offset;
+
+done:
+ entry->state = REQUEST_DONE;
}
static void register_device_info_service(void)