ported minimal code over from barhead
This commit is contained in:
parent
54c7a2d2d6
commit
d51d3633f2
2 changed files with 290 additions and 0 deletions
|
@ -1,6 +1,9 @@
|
|||
#ifndef __BAROS_H__
|
||||
#define __BAROS_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include "esp_event_base.h"
|
||||
|
||||
#define BAROS_BLE_SERVICE_PUMP_ENABLED (0x4200)
|
||||
#define BAROS_BLE_SERVICE_PUMP_STATE (0x4300)
|
||||
#define BAROS_BLE_SERVICE_PUMP_DURATION (0x4350)
|
||||
|
@ -10,4 +13,25 @@
|
|||
#define BAROS_CHAR_POUR (BAROS_BLE_SERVICE_BARBACK + 1) // 0x4401
|
||||
#define BAROS_CHAR_BUTTON (BAROS_BLE_SERVICE_BARBACK + 2) // 0x4402
|
||||
|
||||
typedef enum {
|
||||
BAROS_ROLE_BACK = 0,
|
||||
BAROS_ROLE_HEAD,
|
||||
BAROS_ROLE_ADMIN
|
||||
} baros_role_t;
|
||||
|
||||
typedef struct {
|
||||
const char *name;
|
||||
baros_role_t role;
|
||||
} baros_ble_cfg_t;
|
||||
|
||||
uint8_t baros_ble_init(baros_ble_cfg_t *cfg);
|
||||
|
||||
ESP_EVENT_DECLARE_BASE(EVENT_BAROS_BLE);
|
||||
|
||||
typedef enum {
|
||||
BAROS_BLE_DISC,
|
||||
BAROS_BLE_CONNECT,
|
||||
} baros_ble_event_t;
|
||||
|
||||
|
||||
#endif
|
||||
|
|
266
src/baros_ble.c
Normal file
266
src/baros_ble.c
Normal file
|
@ -0,0 +1,266 @@
|
|||
#include "freertos/FreeRTOS.h"
|
||||
#include "esp_system.h"
|
||||
#include "esp_nimble_hci.h"
|
||||
#include "nimble/nimble_port.h"
|
||||
#include "nimble/nimble_port_freertos.h"
|
||||
#include "host/ble_hs.h"
|
||||
#include "host/util/util.h"
|
||||
#include "services/gap/ble_svc_gap.h"
|
||||
#include "services/bas/ble_svc_bas.h"
|
||||
#include "esp_event_base.h"
|
||||
#include "esp_event.h"
|
||||
|
||||
#include "baros.h"
|
||||
|
||||
#define TAG "BOS_BLE"
|
||||
|
||||
ESP_EVENT_DEFINE_BASE(EVENT_BAROS_BLE);
|
||||
|
||||
static uint8_t blehr_addr_type;
|
||||
static uint16_t conn_handle;
|
||||
static const char *device_name;
|
||||
|
||||
static const struct ble_gatt_svc_def service_defs[] = {
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
static void ble_advertise(void);
|
||||
|
||||
static int ble_gap_event(struct ble_gap_event *event, void *arg) {
|
||||
switch (event->type) {
|
||||
case BLE_GAP_EVENT_DISC: {
|
||||
struct ble_hs_adv_fields fields;
|
||||
|
||||
ESP_ERROR_CHECK(ble_hs_adv_parse_fields(&fields, event->disc.data, event->disc.length_data));
|
||||
|
||||
ESP_LOGV(TAG, "DISCOVERY: %d", event->disc.length_data);
|
||||
|
||||
uint8_t addr[6];
|
||||
memcpy(&addr, (uint8_t*)&event->disc.addr + 1, 6);
|
||||
|
||||
ESP_LOGV(TAG, "addr: %02X:%02X:%02X:%02X:%02X:%02X", addr[5], addr[4], addr[3], addr[2], addr[1], addr[0]);
|
||||
|
||||
ESP_ERROR_CHECK(esp_event_post(EVENT_BAROS_BLE, BAROS_BLE_DISC, (void*)&event->disc, sizeof(struct ble_gap_disc_desc), 1000));
|
||||
|
||||
/*
|
||||
uint8_t *buf = (uint8_t*)malloc(event->disc.length_data);
|
||||
memcpy(buf, event->disc.data, event->disc.length_data);
|
||||
|
||||
printf("\ndata: ");
|
||||
for(uint8_t i = 0; i < event->disc.length_data; i++) {
|
||||
printf("0x%02X ", buf[i]);
|
||||
}
|
||||
printf("\n");
|
||||
*/
|
||||
|
||||
if(fields.name != NULL) {
|
||||
char *name = (char*)malloc(fields.name_len);
|
||||
memcpy(name, (uint8_t*)fields.name, fields.name_len);
|
||||
name[fields.name_len] = '\0';
|
||||
ESP_LOGV(TAG, "Name: %s", name);
|
||||
}
|
||||
|
||||
ESP_LOGV(TAG, "uuids: %d", fields.num_uuids16);
|
||||
|
||||
for (uint8_t i = 0; i < fields.num_uuids16; i++) {
|
||||
ESP_LOGV(TAG, "uuid: 0x%04X", fields.uuids16[i].value);
|
||||
|
||||
if (ble_uuid_u16(&fields.uuids16[i].u) == BLE_SVC_GAP_CHR_UUID16_DEVICE_NAME) {
|
||||
ESP_LOGV(TAG, "device has name");
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
case BLE_GAP_EVENT_CONNECT:
|
||||
/* A new connection was established or a connection attempt failed */
|
||||
conn_handle = event->connect.conn_handle;
|
||||
|
||||
ESP_LOGI(TAG, "connection %s; conn_handle: %d status=%d\n",
|
||||
event->connect.status == 0 ? "established" : "failed",
|
||||
conn_handle,
|
||||
event->connect.status
|
||||
);
|
||||
|
||||
// always keep advertising
|
||||
ble_advertise();
|
||||
|
||||
break;
|
||||
|
||||
case BLE_GAP_EVENT_DISCONNECT:
|
||||
ESP_LOGI(TAG, "disconnect; reason=%d\n", event->disconnect.reason);
|
||||
|
||||
/* Connection terminated; resume advertising */
|
||||
ble_advertise();
|
||||
|
||||
break;
|
||||
|
||||
case BLE_GAP_EVENT_ADV_COMPLETE:
|
||||
ESP_LOGI(TAG, "adv complete\n");
|
||||
|
||||
ble_advertise();
|
||||
break;
|
||||
|
||||
case BLE_GAP_EVENT_SUBSCRIBE:
|
||||
ESP_LOGI(TAG, "subscribe event; cur_notify=%d\n value handle; "
|
||||
"val_handle=%d\n",
|
||||
event->subscribe.cur_notify, event->subscribe.attr_handle);
|
||||
|
||||
break;
|
||||
|
||||
case BLE_GAP_EVENT_CONN_UPDATE:
|
||||
ESP_LOGI(TAG, "BLE_GAP_EVENT_CONN_UPDATE, conn_handle: %d status: %d",
|
||||
event->mtu.conn_handle,
|
||||
event->enc_change.status
|
||||
);
|
||||
|
||||
break;
|
||||
|
||||
|
||||
case BLE_GAP_EVENT_ENC_CHANGE:
|
||||
ESP_LOGI(TAG, "BLE_GAP_EVENT_ENC_CHANGE");
|
||||
|
||||
break;
|
||||
|
||||
case BLE_GAP_EVENT_MTU:
|
||||
ESP_LOGI(TAG, "mtu update event; conn_handle=%d mtu=%d\n",
|
||||
event->mtu.conn_handle,
|
||||
event->mtu.value);
|
||||
break;
|
||||
|
||||
case BLE_GAP_EVENT_NOTIFY_RX:
|
||||
ESP_LOGI(TAG, "BLE_GAP_EVENT_NOTIFY_RX; conn_handle=%d mtu=%d attr_handle=%d\n",
|
||||
event->mtu.conn_handle,
|
||||
event->mtu.value,
|
||||
event->notify_rx.attr_handle);
|
||||
|
||||
break;
|
||||
|
||||
case BLE_GAP_EVENT_NOTIFY_TX:
|
||||
ESP_LOGI(TAG, "BLE_GAP_EVENT_NOTIFY_TX; conn_handle=%d mtu=%d\n",
|
||||
event->mtu.conn_handle,
|
||||
event->mtu.value);
|
||||
break;
|
||||
|
||||
default:
|
||||
ESP_LOGW(TAG, "unhandled ble_gap_event; conn_handle=%d type=%d\n",
|
||||
event->mtu.conn_handle,
|
||||
event->type
|
||||
);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ble_advertise(void) {
|
||||
// check if already adverting
|
||||
if(ble_gap_adv_active()) return;
|
||||
|
||||
struct ble_gap_adv_params adv_params;
|
||||
struct ble_hs_adv_fields fields;
|
||||
int rc;
|
||||
|
||||
memset(&fields, 0, sizeof(fields));
|
||||
|
||||
fields.flags = BLE_HS_ADV_F_DISC_GEN | BLE_HS_ADV_F_BREDR_UNSUP;
|
||||
|
||||
fields.tx_pwr_lvl_is_present = 1;
|
||||
fields.tx_pwr_lvl = BLE_HS_ADV_TX_PWR_LVL_AUTO;
|
||||
|
||||
fields.name = (uint8_t *)device_name;
|
||||
fields.name_len = strlen(device_name);
|
||||
fields.name_is_complete = 1;
|
||||
|
||||
rc = ble_gap_adv_set_fields(&fields);
|
||||
if (rc != 0) {
|
||||
ESP_LOGE(TAG, "error setting advertisement data; rc=%d\n", rc);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Begin advertising */
|
||||
memset(&adv_params, 0, sizeof(adv_params));
|
||||
adv_params.conn_mode = BLE_GAP_CONN_MODE_UND;
|
||||
adv_params.disc_mode = BLE_GAP_DISC_MODE_GEN;
|
||||
rc = ble_gap_adv_start(blehr_addr_type, NULL, BLE_HS_FOREVER,
|
||||
&adv_params, ble_gap_event, NULL);
|
||||
if (rc != 0) {
|
||||
ESP_LOGE(TAG, "error enabling advertisement; rc=%d\n", rc);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
int ble_scan_start() {
|
||||
uint8_t addr_type;
|
||||
struct ble_gap_disc_params disc_params = {
|
||||
.filter_duplicates = 1,
|
||||
.passive = 1,
|
||||
.itvl = 0,
|
||||
.window = 0,
|
||||
.filter_policy = 0,
|
||||
.limited = 0,
|
||||
};
|
||||
|
||||
ESP_ERROR_CHECK(ble_hs_id_infer_auto(0, &addr_type));
|
||||
ble_gap_disc_cancel();
|
||||
ESP_ERROR_CHECK(ble_gap_disc(addr_type, 3000, &disc_params, ble_gap_event, &addr_type));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ble_scan_stop() {
|
||||
return ble_gap_disc_cancel();
|
||||
}
|
||||
|
||||
void nimble_host_task(void *param) {
|
||||
nimble_port_run();
|
||||
}
|
||||
|
||||
static void on_sync() {
|
||||
ESP_LOGI(TAG, "on_sync");
|
||||
|
||||
int err;
|
||||
|
||||
err = ble_hs_id_infer_auto(0, &blehr_addr_type);
|
||||
ESP_ERROR_CHECK(err);
|
||||
|
||||
uint8_t addr_val[6] = {0};
|
||||
err = ble_hs_id_copy_addr(blehr_addr_type, addr_val, NULL);
|
||||
ESP_ERROR_CHECK(err);
|
||||
|
||||
ble_advertise();
|
||||
}
|
||||
|
||||
static void on_reset(int reason) {
|
||||
ESP_LOGE(TAG, "on_reset, reason: %d", reason);
|
||||
}
|
||||
|
||||
uint8_t baros_ble_init(baros_ble_cfg_t *cfg) {
|
||||
esp_err_t err;
|
||||
|
||||
device_name = cfg->name;
|
||||
|
||||
//ESP_ERROR_CHECK(esp_nimble_hci_and_controller_init());
|
||||
|
||||
nimble_port_init();
|
||||
|
||||
ble_hs_cfg.sync_cb = on_sync;
|
||||
ble_hs_cfg.reset_cb = on_reset;
|
||||
|
||||
// initialize services
|
||||
err = ble_gatts_count_cfg(service_defs);
|
||||
ESP_ERROR_CHECK(err);
|
||||
|
||||
err = ble_gatts_add_svcs(service_defs);
|
||||
ESP_ERROR_CHECK(err);
|
||||
|
||||
ESP_LOGI(TAG, "Setting device name: %s", device_name);
|
||||
|
||||
err = ble_svc_gap_device_name_set(device_name);
|
||||
ESP_ERROR_CHECK(err);
|
||||
|
||||
vTaskDelay(500 / portTICK_PERIOD_MS);
|
||||
|
||||
nimble_port_freertos_init(nimble_host_task);
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in a new issue