I have written an application in C using Bluez that implements a peripheral (a GATT server). I managed to advertise and make my peripheral work. Reading a characteristic works fine, notifying works fine and even a Write Without Reponse works. However, what doesn't work is the WRITE WITH RESPONSE. When I do that from an Android app (nrfConnect), I receive a ERR UNLIKELY (code 14). Looks like the 'response' that belongs to a write with response is not sent.
I thought I was doing the right thing by doing:
g_dbus_method_invocation_return_value(invocation, g_variant_new ("()"));
...but apparently it is not what Bluez is expecting. What should I do to make Bluez send the 'response' that belongs to a 'Write with response'?
Here is my code:
static void bluez_characteristic_method_call(GDBusConnection *conn,
const gchar *sender,
const gchar *path,
const gchar *interface,
const gchar *method,
GVariant *params,
GDBusMethodInvocation *invocation,
void *userdata) {
log_debug(TAG, "local characteristic method called: %s", method);
LocalCharacteristic *characteristic = (LocalCharacteristic *) userdata;
g_assert(characteristic != NULL);
Application *application = characteristic->application;
g_assert(application != NULL);
if (g_str_equal(method, "ReadValue")) {
g_assert(g_str_equal(g_variant_get_type_string(params), "(a{sv})"));
GVariant *result = g_variant_new_fixed_array(G_VARIANT_TYPE_BYTE,
characteristic->value->data,
characteristic->value->len,
sizeof(guint8));
g_dbus_method_invocation_return_value(invocation, g_variant_new_tuple(&result, 1));
return;
} else if (g_str_equal(method, "WriteValue")) {
g_assert(g_str_equal(g_variant_get_type_string(params), "(aya{sv})"));
GVariant *valueVariant, *optionsVariant;
g_variant_get(params, "(@ay@a{sv})", &valueVariant, &optionsVariant);
// Copy byte array and store it
size_t data_length = 0;
guint8 *data = (guint8 *) g_variant_get_fixed_array(valueVariant, &data_length, sizeof(guint8));
GByteArray *byteArray = g_byte_array_sized_new(data_length);
g_byte_array_append(byteArray, data, data_length);
binc_characteristic_set_value(characteristic, byteArray);
// Send properties changed signal with new value
binc_application_notify(application, characteristic->service_uuid, characteristic->uuid, byteArray);
// Send a response for a Write With Response
g_dbus_method_invocation_return_value(invocation, g_variant_new ("()"));
} else if...
....
}