Skip to content
Merged
41 changes: 27 additions & 14 deletions main/ble.c
Original file line number Diff line number Diff line change
Expand Up @@ -411,7 +411,7 @@ static void ble_update_cache(ble_device_t *dev)
free(db);
return;
}

/* Find all characteristics and cache them */
for (i = 0; i < count; i++)
{
Expand All @@ -423,8 +423,19 @@ static void ble_update_cache(ble_device_t *dev)
else if (db[i].type == ESP_GATT_DB_CHARACTERISTIC)
{
esp_uuid_to_bt_uuid(db[i].uuid, characteristic_uuid);

uint8_t index = 0;

for (ble_characteristic_t *cur = service->characteristics;
cur != NULL; cur = cur->next)
{
if (ble_uuid_equal(cur->uuid, characteristic_uuid))
index++;
}

characteristic = ble_device_characteristic_add(service,
characteristic_uuid, db[i].attribute_handle, db[i].properties);
characteristic_uuid, index, db[i].attribute_handle,
db[i].properties);
}
else if (db[i].type == ESP_GATT_DB_DESCRIPTOR &&
db[i].uuid.len == ESP_UUID_LEN_16 &&
Expand Down Expand Up @@ -461,7 +472,7 @@ int ble_foreach_characteristic(mac_addr_t mac,
characteristic = characteristic->next)
{
cb(mac, service->uuid, characteristic->uuid,
characteristic->properties);
characteristic->index, characteristic->properties);
}
}

Expand All @@ -470,7 +481,7 @@ int ble_foreach_characteristic(mac_addr_t mac,
}

int ble_characteristic_read(mac_addr_t mac, ble_uuid_t service_uuid,
ble_uuid_t characteristic_uuid)
ble_uuid_t characteristic_uuid, uint8_t index)
{
ble_device_t *device;
ble_service_t *service;
Expand All @@ -486,7 +497,7 @@ int ble_characteristic_read(mac_addr_t mac, ble_uuid_t service_uuid,
goto Exit;

if (!(characteristic = ble_device_characteristic_find_by_uuid(service,
characteristic_uuid)))
characteristic_uuid, index)))
{
goto Exit;
}
Expand All @@ -504,7 +515,8 @@ int ble_characteristic_read(mac_addr_t mac, ble_uuid_t service_uuid,
}

int ble_characteristic_write(mac_addr_t mac, ble_uuid_t service_uuid,
ble_uuid_t characteristic_uuid, const uint8_t *value, size_t value_len)
ble_uuid_t characteristic_uuid, uint8_t index, const uint8_t *value,
size_t value_len)
{
ble_device_t *device;
ble_service_t *service;
Expand All @@ -520,7 +532,7 @@ int ble_characteristic_write(mac_addr_t mac, ble_uuid_t service_uuid,
goto Exit;

if (!(characteristic = ble_device_characteristic_find_by_uuid(service,
characteristic_uuid)))
characteristic_uuid, index)))
{
goto Exit;
}
Expand All @@ -540,7 +552,7 @@ int ble_characteristic_write(mac_addr_t mac, ble_uuid_t service_uuid,
}

int ble_characteristic_notify_register(mac_addr_t mac, ble_uuid_t service_uuid,
ble_uuid_t characteristic_uuid)
ble_uuid_t characteristic_uuid, uint8_t index)
{
uint16_t enable = htole16(0x1);
ble_device_t *device;
Expand All @@ -557,7 +569,7 @@ int ble_characteristic_notify_register(mac_addr_t mac, ble_uuid_t service_uuid,
goto Exit;

if (!(characteristic = ble_device_characteristic_find_by_uuid(service,
characteristic_uuid)))
characteristic_uuid, index)))
{
goto Exit;
}
Expand Down Expand Up @@ -589,7 +601,7 @@ int ble_characteristic_notify_register(mac_addr_t mac, ble_uuid_t service_uuid,
}

int ble_characteristic_notify_unregister(mac_addr_t mac,
ble_uuid_t service_uuid, ble_uuid_t characteristic_uuid)
ble_uuid_t service_uuid, ble_uuid_t characteristic_uuid, uint8_t index)
{
ble_device_t *device;
ble_service_t *service;
Expand All @@ -605,7 +617,7 @@ int ble_characteristic_notify_unregister(mac_addr_t mac,
goto Exit;

if (!(characteristic = ble_device_characteristic_find_by_uuid(service,
characteristic_uuid)))
characteristic_uuid, index)))
{
goto Exit;
}
Expand Down Expand Up @@ -710,7 +722,7 @@ static void gap_cb(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param)

if (param->scan_rst.search_evt != ESP_GAP_SEARCH_INQ_RES_EVT)
break;

/* Check if this device is a broadcaster */
broadcaster_ops_t *broadcaster_ops = broadcaster_ops_get(
param->scan_rst.ble_adv, param->scan_rst.adv_data_len);
Expand Down Expand Up @@ -939,7 +951,8 @@ static void esp_gattc_cb(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if,
&characteristic) && on_device_characteristic_value_cb)
{
on_device_characteristic_value_cb(device->mac, service->uuid,
characteristic->uuid, param->read.value, param->read.value_len);
characteristic->uuid, characteristic->index,
param->read.value, param->read.value_len);
}

xSemaphoreGiveRecursive(devices_list_semaphore);
Expand Down Expand Up @@ -981,7 +994,7 @@ static void esp_gattc_cb(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if,
&characteristic) && on_device_characteristic_value_cb)
{
on_device_characteristic_value_cb(device->mac, service->uuid,
characteristic->uuid, param->notify.value,
characteristic->uuid, characteristic->index, param->notify.value,
param->notify.value_len);
}

Expand Down
15 changes: 8 additions & 7 deletions main/ble.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,11 @@ typedef void (*ble_on_device_connected_cb_t)(mac_addr_t mac);
typedef void (*ble_on_device_disconnected_cb_t)(mac_addr_t mac);
typedef void (*ble_on_device_services_discovered_cb_t)(mac_addr_t mac);
typedef void (*ble_on_device_characteristic_found_cb_t)(mac_addr_t mac,
ble_uuid_t service_uuid, ble_uuid_t characteristic_uuid,
ble_uuid_t service_uuid, ble_uuid_t characteristic_uuid, uint8_t index,
uint8_t properties);
typedef void (*ble_on_device_characteristic_value_cb_t)(mac_addr_t mac,
ble_uuid_t service, ble_uuid_t characteristic, uint8_t *value,
size_t value_len);
ble_uuid_t service, ble_uuid_t characteristic, uint8_t index,
uint8_t *value, size_t value_len);
typedef uint32_t (*ble_on_passkey_requested_cb_t)(mac_addr_t mac);

/* Event handlers */
Expand Down Expand Up @@ -65,13 +65,14 @@ int ble_foreach_characteristic(mac_addr_t mac,
ble_on_device_characteristic_found_cb_t cb);

int ble_characteristic_read(mac_addr_t mac, ble_uuid_t service_uuid,
ble_uuid_t characteristic_uuid);
ble_uuid_t characteristic_uuid, uint8_t index);
int ble_characteristic_write(mac_addr_t mac, ble_uuid_t service_uuid,
ble_uuid_t characteristic_uuid, const uint8_t *value, size_t value_len);
ble_uuid_t characteristic_uuid, uint8_t index, const uint8_t *value,
size_t value_len);
int ble_characteristic_notify_register(mac_addr_t mac, ble_uuid_t service_uuid,
ble_uuid_t characteristic_uuid);
ble_uuid_t characteristic_uuid, uint8_t index);
int ble_characteristic_notify_unregister(mac_addr_t mac,
ble_uuid_t service_uuid, ble_uuid_t characteristic_uuid);
ble_uuid_t service_uuid, ble_uuid_t characteristic_uuid, uint8_t index);

/* Management */
ble_dev_t *ble_devices_list_get(size_t *number_of_devices);
Expand Down
55 changes: 33 additions & 22 deletions main/ble2mqtt.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ typedef struct {
mac_addr_t mac;
ble_uuid_t service;
ble_uuid_t characteristic;
uint8_t index;
} mqtt_ctx_t;

static const char *device_name_get(void)
Expand Down Expand Up @@ -299,7 +300,7 @@ static void ble_publish_connected(mac_addr_t mac, uint8_t is_connected)
if (is_connected)
{
const char *device_name = device_name_get();

/* Subscribe for other devices claiming this device is disconnected */
mqtt_subscribe(topic, config_mqtt_qos_get(), _ble_on_mqtt_connected_cb,
strdup(mactoa(mac)), free);
Expand All @@ -312,13 +313,14 @@ static void ble_publish_connected(mac_addr_t mac, uint8_t is_connected)
}

static mqtt_ctx_t *ble_ctx_gen(mac_addr_t mac, ble_uuid_t service,
ble_uuid_t characteristic)
ble_uuid_t characteristic, uint8_t index)
{
mqtt_ctx_t *ctx = malloc(sizeof(mqtt_ctx_t));

memcpy(ctx->mac, mac, sizeof(mac_addr_t));
memcpy(ctx->service, service, sizeof(ble_uuid_t));
memcpy(ctx->characteristic, characteristic, sizeof(ble_uuid_t));
ctx->index = index;

return ctx;
}
Expand Down Expand Up @@ -381,17 +383,20 @@ static char *ble_topic_suffix(char *base, uint8_t is_get)
}

static char *ble_topic(mac_addr_t mac, ble_uuid_t service_uuid,
ble_uuid_t characteristic_uuid)
ble_uuid_t characteristic_uuid, uint8_t index)
{
static char topic[MAX_TOPIC_LEN];
int i;
int i = 0;

i = snprintf(topic, MAX_TOPIC_LEN, "%s" MAC_FMT "/%s",
i += snprintf(topic + i, MAX_TOPIC_LEN, "%s" MAC_FMT "/%s",
config_mqtt_prefix_get(), MAC_PARAM(mac),
ble_service_name_get(service_uuid));
snprintf(topic + i, MAX_TOPIC_LEN - i, "/%s",
i += snprintf(topic + i, MAX_TOPIC_LEN - i, "/%s",
ble_characteristic_name_get(characteristic_uuid));

if (index > 0)
i += snprintf(topic + i, MAX_TOPIC_LEN - i, "_%u", index);

return topic;
}

Expand All @@ -412,7 +417,8 @@ static void ble_on_mqtt_get(const char *topic, const uint8_t *payload,
ESP_LOGD(TAG, "Got read request: %s", topic);
mqtt_ctx_t *data = (mqtt_ctx_t *)ctx;

ble_characteristic_read(data->mac, data->service, data->characteristic);
ble_characteristic_read(data->mac, data->service, data->characteristic,
data->index);
}

static void ble_on_mqtt_set(const char *topic, const uint8_t *payload,
Expand All @@ -425,10 +431,11 @@ static void ble_on_mqtt_set(const char *topic, const uint8_t *payload,
len, &buf_len);

ble_characteristic_write(data->mac, data->service, data->characteristic,
buf, buf_len);
data->index, buf, buf_len);

/* Issue a read request to get latest value */
ble_characteristic_read(data->mac, data->service, data->characteristic);
ble_characteristic_read(data->mac, data->service, data->characteristic,
data->index);
}

static void _ble_on_mqtt_get(const char *topic, const uint8_t *payload,
Expand All @@ -437,11 +444,12 @@ static void _ble_on_mqtt_set(const char *topic, const uint8_t *payload,
size_t len, void *ctx);

static void ble_on_characteristic_found(mac_addr_t mac, ble_uuid_t service_uuid,
ble_uuid_t characteristic_uuid, uint8_t properties)
ble_uuid_t characteristic_uuid, uint8_t index, uint8_t properties)
{
ESP_LOGD(TAG, "Found new characteristic: service: " UUID_FMT
", characteristic: " UUID_FMT ", properties: 0x%x",
UUID_PARAM(service_uuid), UUID_PARAM(characteristic_uuid), properties);
", characteristic: " UUID_FMT ", index: %u, properties: 0x%x",
UUID_PARAM(service_uuid), UUID_PARAM(characteristic_uuid), index,
properties);
char *topic;

if (!config_ble_service_should_include(uuidtoa(service_uuid)) ||
Expand All @@ -450,30 +458,30 @@ static void ble_on_characteristic_found(mac_addr_t mac, ble_uuid_t service_uuid,
return;
}

topic = ble_topic(mac, service_uuid, characteristic_uuid);
topic = ble_topic(mac, service_uuid, characteristic_uuid, index);

/* Characteristic is readable */
if (properties & CHAR_PROP_READ)
{
mqtt_subscribe(ble_topic_suffix(topic, 1), config_mqtt_qos_get(),
_ble_on_mqtt_get, ble_ctx_gen(mac, service_uuid,
characteristic_uuid), free);
ble_characteristic_read(mac, service_uuid, characteristic_uuid);
characteristic_uuid, index), free);
ble_characteristic_read(mac, service_uuid, characteristic_uuid, index);
}

/* Characteristic is writable */
if (properties & (CHAR_PROP_WRITE | CHAR_PROP_WRITE_NR))
{
mqtt_subscribe(ble_topic_suffix(topic, 0), config_mqtt_qos_get(),
_ble_on_mqtt_set, ble_ctx_gen(mac, service_uuid,
characteristic_uuid), free);
characteristic_uuid, index), free);
}

/* Characteristic can notify / indicate on changes */
if (properties & (CHAR_PROP_NOTIFY | CHAR_PROP_INDICATE))
{
ble_characteristic_notify_register(mac, service_uuid,
characteristic_uuid);
characteristic_uuid, index);
}
}

Expand All @@ -484,10 +492,10 @@ static void ble_on_device_services_discovered(mac_addr_t mac)
}

static void ble_on_device_characteristic_value(mac_addr_t mac,
ble_uuid_t service, ble_uuid_t characteristic, uint8_t *value,
size_t value_len)
ble_uuid_t service, ble_uuid_t characteristic, uint8_t index,
uint8_t *value, size_t value_len)
{
char *topic = ble_topic(mac, service, characteristic);
char *topic = ble_topic(mac, service, characteristic, index);
char *payload = chartoa(characteristic, value, value_len);
size_t payload_len = strlen(payload);

Expand Down Expand Up @@ -565,6 +573,7 @@ typedef struct {
mac_addr_t mac;
ble_uuid_t service;
ble_uuid_t characteristic;
uint8_t index;
uint8_t *value;
size_t value_len;
} ble_device_characteristic_value;
Expand Down Expand Up @@ -635,6 +644,7 @@ static void ble2mqtt_handle_event(event_t *event)
event->ble_device_characteristic_value.mac,
event->ble_device_characteristic_value.service,
event->ble_device_characteristic_value.characteristic,
event->ble_device_characteristic_value.index,
event->ble_device_characteristic_value.value,
event->ble_device_characteristic_value.value_len);
free(event->ble_device_characteristic_value.value);
Expand Down Expand Up @@ -858,8 +868,8 @@ static void _ble_on_device_services_discovered(mac_addr_t mac)
}

static void _ble_on_device_characteristic_value(mac_addr_t mac,
ble_uuid_t service, ble_uuid_t characteristic, uint8_t *value,
size_t value_len)
ble_uuid_t service, ble_uuid_t characteristic, uint8_t index,
uint8_t *value, size_t value_len)
{
event_t *event = malloc(sizeof(*event));

Expand All @@ -872,6 +882,7 @@ static void _ble_on_device_characteristic_value(mac_addr_t mac,
event->ble_device_characteristic_value.value = malloc(value_len);
memcpy(event->ble_device_characteristic_value.value, value, value_len);
event->ble_device_characteristic_value.value_len = value_len;
event->ble_device_characteristic_value.index = index;

ESP_LOGD(TAG, "Queuing event BLE_DEVICE_CHARACTERISTIC_VALUE (" MAC_FMT ", "
UUID_FMT ", %p, %u)", MAC_PARAM(mac), UUID_PARAM(characteristic), value,
Expand Down
Loading