diff --git a/include/baros.h b/include/baros.h index 27a625f..07ab6b3 100644 --- a/include/baros.h +++ b/include/baros.h @@ -2,21 +2,10 @@ #define __BAROS_H__ #include -#include "esp_event_base.h" - -#define BAROS_NAME_MAX_LEN ( 32) -#define BAROS_BLE_SERVICE_PUMP_ENABLED (0x4200) -#define BAROS_BLE_SERVICE_PUMP_STATE (0x4300) -#define BAROS_BLE_SERVICE_PUMP_DURATION (0x4350) - -#define BAROS_BLE_SERVICE_BARBACK (0x4400) - -#define BAROS_CHAR_BUTTON (BAROS_BLE_SERVICE_BARBACK + 1) // 0x4401 -#define BAROS_CHAR_NAME (BAROS_BLE_SERVICE_BARBACK + 2) // 0x4402 -#define BAROS_CHAR_POUR (BAROS_BLE_SERVICE_BARBACK + 3) // 0x4403 typedef enum { - BAROS_ROLE_BACK = 0, + BAROS_ROLE_NONE = 0, + BAROS_ROLE_BACK, BAROS_ROLE_HEAD, BAROS_ROLE_ADMIN } baros_role_t; @@ -26,19 +15,7 @@ typedef struct { baros_role_t role; } baros_cfg_t; -typedef struct { - const char *name; -} baros_ble_cfg_t; - -ESP_EVENT_DECLARE_BASE(EVENT_BAROS_BLE); - -typedef enum { - BAROS_BLE_DISC, - BAROS_BLE_CONNECT, -} baros_ble_event_t; - uint8_t baros_init(baros_cfg_t *cfg); -uint8_t baros_ble_init(baros_ble_cfg_t *cfg); #define BARBACK_BANNER "\n\ ▄▄▄▄▄▄▄▄▄▄ ▄▄▄▄▄▄▄▄▄▄▄ ▄▄▄▄▄▄▄▄▄▄▄ ▄▄▄▄▄▄▄▄▄▄ ▄▄▄▄▄▄▄▄▄▄▄ ▄▄▄▄▄▄▄▄▄▄▄ ▄ ▄\n\ diff --git a/include/baros_ble.h b/include/baros_ble.h new file mode 100644 index 0000000..768cb9a --- /dev/null +++ b/include/baros_ble.h @@ -0,0 +1,57 @@ +#ifndef __BAROS_BLE_H__ +#define __BAROS_BLE_H__ + +#include +#include "esp_event_base.h" + +#define BAROS_NAME_MAX_LEN ( 32) +#define BAROS_BLE_SERVICE_PUMP_ENABLED (0x4200) +#define BAROS_BLE_SERVICE_PUMP_STATE (0x4300) +#define BAROS_BLE_SERVICE_PUMP_DURATION (0x4350) + +#define BAROS_BLE_SERVICE_BARBACK (0x4400) + +#define BAROS_CHAR_BUTTON (BAROS_BLE_SERVICE_BARBACK + 1) // 0x4401 +#define BAROS_CHAR_NAME (BAROS_BLE_SERVICE_BARBACK + 2) // 0x4402 +#define BAROS_CHAR_POUR (BAROS_BLE_SERVICE_BARBACK + 3) // 0x4403 + +ESP_EVENT_DECLARE_BASE(EVENT_BAROS_BLE); + +#include "baros.h" + +typedef enum { + BAROS_BLE_DISC, + BAROS_BLE_CONNECT, +} baros_ble_event_t; + +typedef struct { + const char *name; + baros_role_t role; +} baros_ble_cfg_t; + +typedef struct { + char *name; + uint8_t name_len; + uint8_t mac[6]; + baros_role_t role; +} baros_ble_discovery_t; + +uint8_t baros_ble_init(baros_ble_cfg_t *cfg); + +typedef struct baros_list_node baros_list_node_t; + +struct baros_list_node { + baros_list_node_t *first; + baros_list_node_t *last; + baros_list_node_t *next; + baros_list_node_t *prev; + void *element; +}; + +typedef bool baros_list_find_element_callback(void *element); + +void *baros_list_find_element(baros_list_node_t *list, baros_list_find_element_callback *cb); +void *baros_list_find_node(baros_list_node_t *list, baros_list_find_element_callback *cb); +baros_list_node_t *baros_list_add(baros_list_node_t *list, void *element); + +#endif diff --git a/src/baros.c b/src/baros.c index 7517790..1611654 100644 --- a/src/baros.c +++ b/src/baros.c @@ -1,11 +1,67 @@ +#include +#include #include "baros.h" +#include "baros_ble.h" uint8_t baros_init(baros_cfg_t *cfg) { baros_ble_cfg_t ble_cfg = { - .name = cfg->name + .name = cfg->name, + .role = cfg->role }; baros_ble_init(&ble_cfg); return 0; } + +baros_list_node_t *baros_list_add(baros_list_node_t *list, void *element) { + baros_list_node_t *node = malloc(sizeof(baros_list_node_t)); + bzero(node, sizeof(baros_list_node_t)); + + node->element = element; + + if(list == NULL) { + node->first = node; + node->last = node; + + return node; + } + + baros_list_node_t *last = list->last; + + node->first = list->first; + node->prev = last; + + last->next = node; + + baros_list_node_t *next = node; + + while(next) { + next->last = node; + next = next->prev; + } + + return node; +} + +void *baros_list_find_node(baros_list_node_t *list, baros_list_find_element_callback *cb) { + baros_list_node_t *n = list->first; + + while(n) { + if(cb(n->element)) { + return n; + } + } + + return NULL; +} + +void *baros_list_find_element(baros_list_node_t *list, baros_list_find_element_callback *cb) { + baros_list_node_t *n = baros_list_find_node(list, cb); + + if(n) { + return n->element; + } + + return NULL; +} diff --git a/src/baros_ble.c b/src/baros_ble.c index e6b453d..7f99321 100644 --- a/src/baros_ble.c +++ b/src/baros_ble.c @@ -10,11 +10,12 @@ #include "services/gap/ble_svc_gap.h" #include "esp_bt.h" +#include "esp_mac.h" #include "esp_log.h" #include "esp_event_base.h" #include "baros.h" -#include "baros_ble_ota.h" +#include "baros_ble.h" #include "configulator.h" #define TAG "BOS_BLE" @@ -28,6 +29,8 @@ static uint16_t svc_handle_button; static uint16_t svc_handle_name; static const char *device_name = "BAROS"; +baros_role_t unit_role; + typedef struct { uint16_t conn_handle; } barback_ble_t; @@ -38,6 +41,8 @@ static int svc_access_system(uint16_t conn_handle, uint16_t attr_handle, struct static int barback_ble_char_access(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, void *arg); +baros_list_node_t *peer_list = NULL; + static const struct ble_gatt_svc_def service_defs[] = { { .type = BLE_GATT_SVC_TYPE_PRIMARY, @@ -108,6 +113,16 @@ static void ble_advertise(void) { fields.flags = BLE_HS_ADV_F_DISC_GEN | BLE_HS_ADV_F_BREDR_UNSUP; + ESP_LOGD(TAG, "unit role: %d", unit_role); + + fields.svc_data_uuid16 = (uint8_t[]){ + 0x66, + 0x66, + unit_role + }; + + fields.svc_data_uuid16_len = 3; + /* * Indicate that the TX power level field should be included; have the * stack fill this value automatically. This is done by assigning the @@ -202,6 +217,7 @@ static int svc_access_name(uint16_t conn_handle, uint16_t attr_handle, struct bl NULL ); + // FIXME this doesn't take effect err = ble_svc_gap_device_name_set(name); ESP_LOGI(TAG, "configulator: %p", configulator); @@ -225,26 +241,33 @@ static int ble_gap_event(struct ble_gap_event *event, void *arg) { ESP_ERROR_CHECK(ble_hs_adv_parse_fields(&fields, event->disc.data, event->disc.length_data)); - if(fields.name != NULL) { + if( + fields.svc_data_uuid16_len == 3 && + fields.svc_data_uuid16[0] == 0x66 && + fields.svc_data_uuid16[1] == 0x66 + ) { char *name = (char*)malloc(fields.name_len + 1); - snprintf(name, fields.name_len + 1, "%s", fields.name); - ESP_LOGI(TAG, "DISCOVERY: %s", name); + bzero(name, fields.name_len + 1); + memcpy(name, fields.name, fields.name_len); - // we'll party at any bar - if(strstr(name, "BAR") >= 0) { - ESP_LOGI(TAG, "Let's Party!"); - /* - * No longer want to automatically connect - * Actions can be taken based on discovery - uint8_t addr_type; - ble_gap_disc_cancel(); + baros_role_t role = fields.svc_data_uuid16[2]; - ESP_ERROR_CHECK(ble_hs_id_infer_auto(0, &addr_type)); - ESP_ERROR_CHECK(ble_gap_connect(addr_type, &event->disc.addr, 30000, NULL, ble_gap_event, NULL)); - */ + ESP_LOGD(TAG, "Discovery: %s", name); - esp_event_post(EVENT_BAROS_BLE, BAROS_BLE_DISC, name, fields.name_len + 1, portMAX_DELAY); + baros_ble_discovery_t *discovery = malloc(sizeof(baros_ble_discovery_t)); + + discovery->name_len = fields.name_len; + discovery->name = name; + discovery->role = role; + memcpy(discovery->mac, &event->disc.addr.val, 6); + + if(peer_list == NULL) { + peer_list = baros_list_add(NULL, discovery); + } else { + baros_list_add(peer_list, discovery); } + + esp_event_post(EVENT_BAROS_BLE, BAROS_BLE_DISC, discovery, sizeof(baros_ble_discovery_t), portMAX_DELAY); } return 0; @@ -347,7 +370,6 @@ void ble_init_buddy_client() { ESP_ERROR_CHECK(ble_gap_disc(addr_type, BLE_HS_FOREVER, &disc_params, ble_gap_event, &addr_type)); } - static void on_sync() { ESP_LOGI(TAG, "on_sync"); @@ -379,11 +401,17 @@ void nimble_host_task(void *param) { nimble_port_run(); } +uint8_t baros_ble_scan(baros_role_t role) { + return 0; +} + uint8_t baros_ble_init(baros_ble_cfg_t *cfg) { ESP_LOGV(TAG, "init"); esp_err_t err; + unit_role = cfg->role; + nimble_port_init(); ble_hs_cfg.sync_cb = on_sync;