mirror of https://github.com/labapart/gattlib
gattlib: Change gattlib_read_char_by_uuid() to return an allocated buffer that fits GATT value size
parent
683efaaca4
commit
ceaa8a17e4
|
@ -31,9 +31,8 @@
|
|||
#include "gatt.h"
|
||||
|
||||
struct gattlib_result_read_uuid_t {
|
||||
void* buffer;
|
||||
size_t buffer_max_len;
|
||||
size_t buffer_len;
|
||||
void** buffer;
|
||||
size_t* buffer_len;
|
||||
gatt_read_cb_t callback;
|
||||
int completed;
|
||||
};
|
||||
|
@ -59,15 +58,24 @@ static void gattlib_result_read_uuid_cb(guint8 status, const guint8 *pdu, guint1
|
|||
|
||||
for (i = 0; i < list->num; i++) {
|
||||
uint8_t *value = list->data[i];
|
||||
size_t buffer_len = list->len - 2;
|
||||
|
||||
// Move the value to the beginning of the data
|
||||
value += 2;
|
||||
|
||||
gattlib_result->buffer_len = list->len - 2;
|
||||
|
||||
if (gattlib_result->callback) {
|
||||
gattlib_result->callback(value, gattlib_result->buffer_len);
|
||||
gattlib_result->callback(value, buffer_len);
|
||||
} else {
|
||||
memcpy(gattlib_result->buffer, value, MIN(gattlib_result->buffer_len, gattlib_result->buffer_max_len));
|
||||
void* buffer = malloc(buffer_len);
|
||||
if (buffer == NULL) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
// Copy value into the buffer
|
||||
memcpy(buffer, value, buffer_len);
|
||||
|
||||
*gattlib_result->buffer_len = buffer_len;
|
||||
*gattlib_result->buffer = buffer;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -95,7 +103,7 @@ void uuid_to_bt_uuid(uuid_t* uuid, bt_uuid_t* bt_uuid) {
|
|||
}
|
||||
|
||||
int gattlib_read_char_by_uuid(gatt_connection_t* connection, uuid_t* uuid,
|
||||
void* buffer, size_t* buffer_len)
|
||||
void **buffer, size_t* buffer_len)
|
||||
{
|
||||
gattlib_context_t* conn_context = connection->context;
|
||||
struct gattlib_result_read_uuid_t* gattlib_result;
|
||||
|
@ -108,29 +116,26 @@ int gattlib_read_char_by_uuid(gatt_connection_t* connection, uuid_t* uuid,
|
|||
return GATTLIB_OUT_OF_MEMORY;
|
||||
}
|
||||
gattlib_result->buffer = buffer;
|
||||
gattlib_result->buffer_max_len = *buffer_len;
|
||||
gattlib_result->buffer_len = 0;
|
||||
gattlib_result->buffer_len = buffer_len;
|
||||
gattlib_result->callback = NULL;
|
||||
gattlib_result->completed = FALSE;
|
||||
|
||||
uuid_to_bt_uuid(uuid, &bt_uuid);
|
||||
|
||||
gatt_read_char_by_uuid(conn_context->attrib, start, end, &bt_uuid,
|
||||
gattlib_result_read_uuid_cb, gattlib_result);
|
||||
gattlib_result_read_uuid_cb, gattlib_result);
|
||||
|
||||
// Wait for completion of the event
|
||||
while(gattlib_result->completed == FALSE) {
|
||||
g_main_context_iteration(g_gattlib_thread.loop_context, FALSE);
|
||||
}
|
||||
|
||||
*buffer_len = gattlib_result->buffer_len;
|
||||
|
||||
free(gattlib_result);
|
||||
return GATTLIB_SUCCESS;
|
||||
}
|
||||
|
||||
int gattlib_read_char_by_uuid_async(gatt_connection_t* connection, uuid_t* uuid,
|
||||
gatt_read_cb_t gatt_read_cb)
|
||||
gatt_read_cb_t gatt_read_cb)
|
||||
{
|
||||
gattlib_context_t* conn_context = connection->context;
|
||||
struct gattlib_result_read_uuid_t* gattlib_result;
|
||||
|
@ -143,7 +148,6 @@ int gattlib_read_char_by_uuid_async(gatt_connection_t* connection, uuid_t* uuid,
|
|||
return GATTLIB_OUT_OF_MEMORY;
|
||||
}
|
||||
gattlib_result->buffer = NULL;
|
||||
gattlib_result->buffer_max_len = 0;
|
||||
gattlib_result->buffer_len = 0;
|
||||
gattlib_result->callback = gatt_read_cb;
|
||||
gattlib_result->completed = FALSE;
|
||||
|
@ -151,7 +155,7 @@ int gattlib_read_char_by_uuid_async(gatt_connection_t* connection, uuid_t* uuid,
|
|||
uuid_to_bt_uuid(uuid, &bt_uuid);
|
||||
|
||||
guint id = gatt_read_char_by_uuid(conn_context->attrib, start, end, &bt_uuid,
|
||||
gattlib_result_read_uuid_cb, gattlib_result);
|
||||
gattlib_result_read_uuid_cb, gattlib_result);
|
||||
|
||||
if (id) {
|
||||
return GATTLIB_SUCCESS;
|
||||
|
|
|
@ -1048,7 +1048,7 @@ int gattlib_discover_desc(gatt_connection_t* connection, gattlib_descriptor_t**
|
|||
return GATTLIB_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
static int read_gatt_characteristic(struct dbus_characteristic *dbus_characteristic, void* buffer, size_t* buffer_len) {
|
||||
static int read_gatt_characteristic(struct dbus_characteristic *dbus_characteristic, void **buffer, size_t* buffer_len) {
|
||||
GVariant *out_value;
|
||||
GError *error = NULL;
|
||||
|
||||
|
@ -1070,11 +1070,16 @@ static int read_gatt_characteristic(struct dbus_characteristic *dbus_characteris
|
|||
gsize n_elements = 0;
|
||||
gconstpointer const_buffer = g_variant_get_fixed_array(out_value, &n_elements, sizeof(guchar));
|
||||
if (const_buffer) {
|
||||
n_elements = MIN(n_elements, *buffer_len);
|
||||
memcpy(buffer, const_buffer, n_elements);
|
||||
}
|
||||
*buffer = malloc(n_elements);
|
||||
if (*buffer == NULL) {
|
||||
return GATTLIB_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
*buffer_len = n_elements;
|
||||
*buffer_len = n_elements;
|
||||
memcpy(*buffer, const_buffer, n_elements);
|
||||
} else {
|
||||
*buffer_len = 0;
|
||||
}
|
||||
|
||||
g_object_unref(dbus_characteristic->gatt);
|
||||
|
||||
|
@ -1095,7 +1100,7 @@ static int read_battery_level(struct dbus_characteristic *dbus_characteristic, v
|
|||
}
|
||||
#endif
|
||||
|
||||
int gattlib_read_char_by_uuid(gatt_connection_t* connection, uuid_t* uuid, void* buffer, size_t* buffer_len) {
|
||||
int gattlib_read_char_by_uuid(gatt_connection_t* connection, uuid_t* uuid, void **buffer, size_t *buffer_len) {
|
||||
struct dbus_characteristic dbus_characteristic = get_characteristic_from_uuid(connection, uuid);
|
||||
if (dbus_characteristic.type == TYPE_NONE) {
|
||||
return GATTLIB_NOT_FOUND;
|
||||
|
|
|
@ -247,23 +247,24 @@ static gboolean characteristics_read(gpointer user_data)
|
|||
GAttrib *attrib = conn_context->attrib;
|
||||
|
||||
if (opt_uuid != NULL) {
|
||||
uint8_t buffer[0x100];
|
||||
uint8_t *buffer;
|
||||
uuid_t uuid;
|
||||
size_t len = sizeof(buffer);
|
||||
size_t buffer_len;
|
||||
int i, ret;
|
||||
|
||||
bt_uuid_to_uuid(opt_uuid, &uuid);
|
||||
|
||||
ret = gattlib_read_char_by_uuid(connection, &uuid, buffer, &len);
|
||||
ret = gattlib_read_char_by_uuid(connection, &uuid, &buffer, &buffer_len);
|
||||
if (ret) {
|
||||
return FALSE;
|
||||
} else {
|
||||
g_print("value: ");
|
||||
for (i = 0; i < len; i++) {
|
||||
for (i = 0; i < buffer_len; i++) {
|
||||
g_print("%02x ", buffer[i]);
|
||||
}
|
||||
g_print("\n");
|
||||
|
||||
free(buffer);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,7 +38,6 @@ static void usage(char *argv[]) {
|
|||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
uint8_t buffer[100];
|
||||
int i, ret;
|
||||
size_t len;
|
||||
gatt_connection_t* connection;
|
||||
|
@ -76,8 +75,9 @@ int main(int argc, char *argv[]) {
|
|||
}
|
||||
|
||||
if (g_operation == READ) {
|
||||
len = sizeof(buffer);
|
||||
ret = gattlib_read_char_by_uuid(connection, &g_uuid, buffer, &len);
|
||||
uint8_t *buffer;
|
||||
|
||||
ret = gattlib_read_char_by_uuid(connection, &g_uuid, (void **)&buffer, &len);
|
||||
if (ret == -1) {
|
||||
char uuid_str[MAX_LEN_UUID_STR + 1];
|
||||
|
||||
|
@ -92,8 +92,10 @@ int main(int argc, char *argv[]) {
|
|||
printf("%02x ", buffer[i]);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
free(buffer);
|
||||
} else {
|
||||
ret = gattlib_write_char_by_uuid(connection, &g_uuid, buffer, sizeof(buffer));
|
||||
ret = gattlib_write_char_by_uuid(connection, &g_uuid, &value_data, sizeof(value_data));
|
||||
if (ret == -1) {
|
||||
char uuid_str[MAX_LEN_UUID_STR + 1];
|
||||
|
||||
|
|
|
@ -116,7 +116,15 @@ typedef struct _gatt_connection_t {
|
|||
|
||||
typedef void (*gattlib_discovered_device_t)(const char* addr, const char* name);
|
||||
typedef void (*gatt_connect_cb_t)(gatt_connection_t* connection, void* user_data);
|
||||
typedef void* (*gatt_read_cb_t)(const void* buffer, size_t buffer_len);
|
||||
|
||||
/**
|
||||
* @brief Callback called when GATT characteristic read value has been received
|
||||
*
|
||||
* @param buffer contains the value to read.
|
||||
* @param buffer_len Length of the read data
|
||||
*
|
||||
*/
|
||||
typedef void* (*gatt_read_cb_t)(const void *buffer, size_t buffer_len);
|
||||
|
||||
/**
|
||||
* @brief Open Bluetooth adapter
|
||||
|
@ -179,7 +187,29 @@ int gattlib_discover_char(gatt_connection_t* connection, gattlib_characteristic_
|
|||
int gattlib_discover_desc_range(gatt_connection_t* connection, int start, int end, gattlib_descriptor_t** descriptors, int* descriptor_count);
|
||||
int gattlib_discover_desc(gatt_connection_t* connection, gattlib_descriptor_t** descriptors, int* descriptor_count);
|
||||
|
||||
int gattlib_read_char_by_uuid(gatt_connection_t* connection, uuid_t* uuid, void* buffer, size_t* buffer_len);
|
||||
/**
|
||||
* @brief Function to read GATT characteristic
|
||||
*
|
||||
* @note buffer is allocated by the function. It is the responsibility of the caller to free the buffer.
|
||||
*
|
||||
* @param connection Active GATT connection
|
||||
* @param uuid UUID of the GATT characteristic to read
|
||||
* @param buffer contains the value to read. It is allocated by the function.
|
||||
* @param buffer_len Length of the read data
|
||||
*
|
||||
* @return GATTLIB_SUCCESS on success or GATTLIB_* error code
|
||||
*/
|
||||
int gattlib_read_char_by_uuid(gatt_connection_t* connection, uuid_t* uuid, void** buffer, size_t* buffer_len);
|
||||
|
||||
/**
|
||||
* @brief Function to asynchronously read GATT characteristic
|
||||
*
|
||||
* @param connection Active GATT connection
|
||||
* @param uuid UUID of the GATT characteristic to read
|
||||
* @param gatt_read_cb is the callback to read when the GATT characteristic is available
|
||||
*
|
||||
* @return GATTLIB_SUCCESS on success or GATTLIB_* error code
|
||||
*/
|
||||
int gattlib_read_char_by_uuid_async(gatt_connection_t* connection, uuid_t* uuid, gatt_read_cb_t gatt_read_cb);
|
||||
|
||||
int gattlib_write_char_by_uuid(gatt_connection_t* connection, uuid_t* uuid, const void* buffer, size_t buffer_len);
|
||||
|
|
Loading…
Reference in New Issue