Skip to content

Commit

Permalink
Advertisement messages publication to MQTT.
Browse files Browse the repository at this point in the history
(cherry picked from commit 2ffc175)
  • Loading branch information
robertcsakany committed Jan 23, 2019
1 parent bc995b7 commit 7010590
Show file tree
Hide file tree
Showing 9 changed files with 180 additions and 13 deletions.
20 changes: 20 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,26 @@ additional topics to help book-keeping:
* `<Peripheral MAC address>/Owner` - The name of the BLE2MQTT instance currently
connected to the peripheral, e.g. `BLE2MQTT-XXXX`, where `XXXX` are the last 2
octets of the ESP32's WiFi MAC address
## Advertisement

This application supports publishing all BLE advertisements over MQTT,
When the advertisement section is set inside ble section.
The push interval is the seconds between mqtt publications of advertisement messages.

* 0 means every message can be send
* -1 no message at all can be send
* other values the seconds between advertisements pusblished to mqtt.

```json
{
"ble": {
"advertisement" : {
"publishinterval": 5
}
}
```

The message itself the hexadecimal string value of message.

## Broadcasters

Expand Down
51 changes: 40 additions & 11 deletions main/ble.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <freertos/FreeRTOS.h>
#include <freertos/timers.h>
#include <string.h>
#include <time.h>

/* Constants */
#define INVALID_HANDLE 0
Expand Down Expand Up @@ -69,6 +70,8 @@ static ble_on_device_services_discovered_cb_t
static ble_on_device_characteristic_value_cb_t
on_device_characteristic_value_cb = NULL;
static ble_on_passkey_requested_cb_t on_passkey_requested_cb = NULL;
static ble_set_on_device_advertisement_cb_t on_device_advertisement_cb = NULL;


void ble_set_on_broadcaster_discovered_cb(ble_on_broadcaster_discovered_cb_t cb)
{
Expand Down Expand Up @@ -107,6 +110,11 @@ void ble_set_on_passkey_requested_cb(ble_on_passkey_requested_cb_t cb)
on_passkey_requested_cb = cb;
}

void ble_set_on_device_advertisement_cb(ble_set_on_device_advertisement_cb_t cb)
{
on_device_advertisement_cb = cb;
}

/* BLE Queue */
static void ble_operation_remove_by_mac(ble_operation_t **queue,
mac_addr_t mac)
Expand Down Expand Up @@ -299,6 +307,22 @@ int ble_services_scan(mac_addr_t mac)
return esp_ble_gattc_search_service(g_gattc_if, dev->conn_id, NULL);
}


int ble_advertisement_process_required(mac_addr_t mac, int interval_sec)
{
ble_device_t *dev = ble_device_find_by_mac(devices_list, mac);

if (!dev)
return -1;

if (dev->last_processed_adv_time + interval_sec < time(NULL)) {
time(&dev->last_processed_adv_time);
return 1;
}
return 0;
}


static void esp_uuid_to_bt_uuid(esp_bt_uuid_t esp, ble_uuid_t bt)
{
/* Bluetooth SIG Base UUID */
Expand Down Expand Up @@ -561,17 +585,22 @@ static void gap_cb(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param)

device = ble_device_find_by_mac(devices_list, param->scan_rst.bda);

/* Device already discovered, nothing to do*/
if (device)
break;

/* Cache device information */
ble_device_add(&devices_list, param->scan_rst.bda,
param->scan_rst.ble_addr_type, -1);

/* Notify app only on newly connected devices */
if(on_device_discovered_cb)
on_device_discovered_cb(param->scan_rst.bda);
if (!device) {
/* Cache device information */
device = ble_device_add(&devices_list, param->scan_rst.bda,
param->scan_rst.ble_addr_type, -1);

/* Notify app only on newly connected devices */
if(on_device_discovered_cb)
on_device_discovered_cb(param->scan_rst.bda);
}

/* All advertisement delegated to callback. Device have to be added */
if (on_device_advertisement_cb) {
on_device_advertisement_cb(param->scan_rst.bda,
param->scan_rst.ble_adv, param->scan_rst.adv_data_len,
param->scan_rst.rssi);
}

break;
}
Expand Down
5 changes: 5 additions & 0 deletions main/ble.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ 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);
typedef uint32_t (*ble_on_passkey_requested_cb_t)(mac_addr_t mac);
typedef void (*ble_set_on_device_advertisement_cb_t)(mac_addr_t mac, uint8_t *adv_data,
size_t adv_data_len, int rssi);

/* Event handlers */
void ble_set_on_broadcaster_discovered_cb(
Expand All @@ -42,6 +44,7 @@ void ble_set_on_device_services_discovered_cb(
void ble_set_on_device_characteristic_value_cb(
ble_on_device_characteristic_value_cb_t cb);
void ble_set_on_passkey_requested_cb(ble_on_passkey_requested_cb_t cb);
void ble_set_on_device_advertisement_cb(ble_set_on_device_advertisement_cb_t cb);

/* BLE Operations */
void ble_clear_bonding_info(void);
Expand All @@ -54,6 +57,8 @@ int ble_disconnect(mac_addr_t mac);
int ble_disconnect_all(void);

int ble_services_scan(mac_addr_t mac);
int ble_advertisement_process_required(mac_addr_t mac, int interval_sec);

int ble_foreach_characteristic(mac_addr_t mac,
ble_on_device_characteristic_found_cb_t cb);

Expand Down
75 changes: 75 additions & 0 deletions main/ble2mqtt.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <nvs.h>
#include <nvs_flash.h>
#include <string.h>
#include <time.h>

#define MAX_TOPIC_LEN 256
static const char *TAG = "BLE2MQTT";
Expand Down Expand Up @@ -262,6 +263,19 @@ static char *ble_topic(mac_addr_t mac, ble_uuid_t service_uuid,
return topic;
}

static char *ble_advertisement_topic(mac_addr_t mac, const char *subtopic)
{
static char topic[MAX_TOPIC_LEN];
int i;

i = snprintf(topic, MAX_TOPIC_LEN, "%s%s", config_mqtt_prefix_get(),
mactoa(mac));

snprintf(topic + i, MAX_TOPIC_LEN - i, "/%s", subtopic);

return topic;
}

static void ble_on_characteristic_removed(mac_addr_t mac, ble_uuid_t service_uuid,
ble_uuid_t characteristic_uuid, uint8_t properties)
{
Expand Down Expand Up @@ -383,6 +397,66 @@ static uint32_t ble_on_passkey_requested(mac_addr_t mac)
return passkey;
}

static void ble_on_device_advertisement(mac_addr_t mac, uint8_t *payload,
size_t payload_len, int rssi)
{
if (config_ble_publish_advertisement_interval() == -1)
{
return;
}

char *mac_str = strdup(mactoa(mac));
int adv_proc_req = ble_advertisement_process_required(mac, config_ble_publish_advertisement_interval());

if (adv_proc_req == 0)
{
ESP_LOGD(TAG, "No advertisement processing required: %s", mac_str);
}
else if (adv_proc_req == 1)
{
ESP_LOGI(TAG, "Processing advertisement: %s", mac_str);
char topic[MAX_TOPIC_LEN];


sprintf(topic, "%s/%s/%s", device_name_get(), mac_str, "Advertisement");
char *hex = chartohex(payload, payload_len);
size_t hex_len = strlen(hex);
char rssi_str[6];
sprintf(rssi_str, "%d", rssi);

ESP_LOGI(TAG, "Publishing: %s = %s RSSI: %s", topic, hex, rssi_str);
mqtt_publish(topic, (uint8_t *)hex, hex_len, config_mqtt_qos_get(),
config_mqtt_retained_get());


/*
char *topic;
topic = ble_advertisement_topic(mac, "Advertisement");
char *hex = chartohex(payload, payload_len);
size_t hex_len = strlen(hex);
char rssi_str[6];
sprintf(rssi_str, "%d", rssi);
ESP_LOGI(TAG, "Publishing: %s = %s RSSI: %s", topic, hex, rssi_str);
mqtt_publish(topic, (uint8_t *)hex, hex_len, config_mqtt_qos_get(),
config_mqtt_retained_get());
topic = ble_advertisement_topic(mac, "RSSI");
mqtt_publish(topic, (uint8_t *)rssi_str, strlen(rssi_str), config_mqtt_qos_get(),
config_mqtt_retained_get());
*/
}
else if (adv_proc_req == -1)
{
ESP_LOGE(TAG, "Failed to check advertisement interval: %s", mac_str);
}
free(mac_str);
}


void app_main()
{
/* Initialize NVS */
Expand Down Expand Up @@ -422,6 +496,7 @@ void app_main()
ble_set_on_device_characteristic_value_cb(
ble_on_device_characteristic_value);
ble_set_on_passkey_requested_cb(ble_on_passkey_requested);
ble_set_on_device_advertisement_cb(ble_on_device_advertisement);

/* Start by connecting to WiFi */
wifi_hostname_set(device_name_get());
Expand Down
17 changes: 17 additions & 0 deletions main/ble_utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,22 @@ static characteristic_type_t *ble_get_characteristic_types(ble_uuid_t uuid)
return ret;
}


char *chartohex(const uint8_t *data, size_t len)
{
static char buf[1024];
char *p = buf;
int i = 0;

for (; i < len; i++) {
p += sprintf(p, "%02hhX", data[i]);
}

*(p) = '\0';
return buf;

}

char *chartoa(ble_uuid_t uuid, const uint8_t *data, size_t len)
{
characteristic_type_t *types = ble_get_characteristic_types(uuid);
Expand Down Expand Up @@ -417,6 +433,7 @@ char *chartoa(ble_uuid_t uuid, const uint8_t *data, size_t len)
return buf;
}


uint8_t *atochar(ble_uuid_t uuid, const char *data, size_t len, size_t *ret_len)
{
characteristic_type_t *types = ble_get_characteristic_types(uuid);
Expand Down
2 changes: 2 additions & 0 deletions main/ble_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ typedef struct ble_device_t {
uint16_t conn_id;
ble_service_t *services;
uint8_t is_authenticating;
time_t last_processed_adv_time;
} ble_device_t;

/* Callback functions */
Expand All @@ -43,6 +44,7 @@ char *mactoa(mac_addr_t mac);
int atomac(const char *str, mac_addr_t mac);
char *uuidtoa(ble_uuid_t uuid);
int atouuid(const char *str, ble_uuid_t uuid);
char *chartohex(const uint8_t *data, size_t len);
char *chartoa(ble_uuid_t uuid, const uint8_t *data, size_t len);
uint8_t *atochar(ble_uuid_t uuid, const char *data, size_t len,
size_t *ret_len);
Expand Down
12 changes: 12 additions & 0 deletions main/config.c
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,18 @@ uint32_t config_ble_passkey_get(const char *mac)
return 0;
}

uint32_t config_ble_publish_advertisement_interval(void)
{
cJSON *ble = cJSON_GetObjectItemCaseSensitive(config, "ble");
cJSON *advertisement = cJSON_GetObjectItemCaseSensitive(ble, "advertisement");
cJSON *interval = cJSON_GetObjectItemCaseSensitive(advertisement, "publishinterval");

if (cJSON_IsNumber(interval))
return interval->valuedouble;

return -1;
}

/* MQTT Configuration*/
const char *config_mqtt_server_get(const char *param_name)
{
Expand Down
1 change: 1 addition & 0 deletions main/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ uint8_t config_ble_characteristic_should_include(const char *uuid);
uint8_t config_ble_service_should_include(const char *uuid);
uint8_t config_ble_should_connect(const char *mac);
uint32_t config_ble_passkey_get(const char *mac);
uint32_t config_ble_publish_advertisement_interval(void);

/* MQTT Configuration*/
const char *config_mqtt_host_get(void);
Expand Down
10 changes: 8 additions & 2 deletions main/wifi.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,16 +48,22 @@ static esp_err_t event_handler(void *ctx, system_event_t *event)
esp_wifi_connect();
break;
case SYSTEM_EVENT_STA_GOT_IP:
ESP_LOGD(TAG, "Got IP address: %s",
ESP_LOGI(TAG, "Got IP address: %s",
inet_ntoa(event->event_info.got_ip.ip_info.ip));
if (on_connected_cb)
on_connected_cb();
break;
case SYSTEM_EVENT_AP_STA_GOT_IP6:
ESP_LOGI(TAG, "Got IPV6 address: %s",
inet6_ntoa(event->event_info.got_ip6.ip6_info.ip));
break;
case SYSTEM_EVENT_STA_LOST_IP:
ESP_LOGD(TAG, "Lost IP address");
ESP_LOGI(TAG, "Lost IP address");
break;
case SYSTEM_EVENT_STA_CONNECTED:
ESP_LOGI(TAG, "Connected");
/* enable ipv6 */
tcpip_adapter_create_ip6_linklocal(TCPIP_ADAPTER_IF_STA);
break;
case SYSTEM_EVENT_STA_DISCONNECTED:
ESP_LOGI(TAG, "Disconnected");
Expand Down

0 comments on commit 7010590

Please sign in to comment.