diff --git a/.DS_Store b/.DS_Store index 1e3f52b..e679439 100644 Binary files a/.DS_Store and b/.DS_Store differ diff --git a/partitions_custom.csv b/partitions_custom.csv index ecf102f..cf4c611 100644 --- a/partitions_custom.csv +++ b/partitions_custom.csv @@ -1,6 +1,6 @@ # Name, Type, SubType, Offset, Size, Flags nvs, data, nvs, 0x9000, 0x5000, otadata, data, ota, 0xe000, 0x2000, -app0, app, factory, 0x10000, 0x1E0000, -app1, app, ota_0, 0x1F0000, 0x1E0000, +app0, app, ota_0, 0x10000, 0x1E0000, +app1, app, ota_1, 0x1F0000, 0x1E0000, spiffs, data, spiffs, 0x3D0000, 0x20000, \ No newline at end of file diff --git a/platformio.ini b/platformio.ini index b27d08c..0a0acf7 100644 --- a/platformio.ini +++ b/platformio.ini @@ -17,7 +17,7 @@ lib_deps = siwats/ESPMegaPROR3@^2.9.4 monitor_speed = 115200 board_build.partitions = partitions_custom.csv board_upload.flash_size = 4MB -build_flags = -DCORE_DEBUG_LEVEL=0 -DSW_VERSION='"cud-dev-duct"' -DBOARD_MODEL='"ESPMegaPRO R3.3c"' -DAC_TYPE=AC_TYPE_DUCTED +build_flags = -DCORE_DEBUG_LEVEL=0 -DSW_VERSION='"cud-beacon-duct"' -DBOARD_MODEL='"ESPMegaPRO R3.3c"' -DAC_TYPE=AC_TYPE_DUCTED ; Ceiling A/C Variant (and newer ducted models) [env:satitm-ceiling] @@ -28,4 +28,4 @@ lib_deps = siwats/ESPMegaPROR3@^2.9.4 monitor_speed = 115200 board_build.partitions = partitions_custom.csv board_upload.flash_size = 4MB -build_flags = -DCORE_DEBUG_LEVEL=0 -DSW_VERSION='"cud-dev-ceiling"' -DBOARD_MODEL='"ESPMegaPRO R3.3c"' -DAC_TYPE=AC_TYPE_CEILING \ No newline at end of file +build_flags = -DCORE_DEBUG_LEVEL=0 -DSW_VERSION='"cud-beacon-ceiling"' -DBOARD_MODEL='"ESPMegaPRO R3.3c"' -DAC_TYPE=AC_TYPE_CEILING \ No newline at end of file diff --git a/src/esp_ibeacon_api.cpp b/src/esp_ibeacon_api.cpp new file mode 100644 index 0000000..2cce8dd --- /dev/null +++ b/src/esp_ibeacon_api.cpp @@ -0,0 +1,68 @@ +/* + * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ + + + +/**************************************************************************** +* +* This file is for iBeacon APIs. It supports both iBeacon encode and decode. +* +* iBeacon is a trademark of Apple Inc. Before building devices which use iBeacon technology, +* visit https://developer.apple.com/ibeacon/ to obtain a license. +* +****************************************************************************/ + +#include +#include +#include +#include + +#include "esp_gap_ble_api.h" +#include "esp_ibeacon_api.hpp" + + +const uint8_t uuid_zeros[ESP_UUID_LEN_128] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + +/* For iBeacon packet format, please refer to Apple "Proximity Beacon Specification" doc */ +/* Constant part of iBeacon data */ +esp_ble_ibeacon_head_t ibeacon_common_head = { + .flags = {0x02, 0x01, 0x06}, + .length = 0x1A, + .type = 0xFF, + .company_id = 0x004C, + .beacon_type = 0x1502 +}; + +/* Vendor part of iBeacon data*/ +esp_ble_ibeacon_vendor_t vendor_config = { + .proximity_uuid = ESP_UUID, + .major = ENDIAN_CHANGE_U16(ESP_MAJOR), //Major=ESP_MAJOR + .minor = ENDIAN_CHANGE_U16(ESP_MINOR), //Minor=ESP_MINOR + .measured_power = static_cast(0xC5) +}; + +bool esp_ble_is_ibeacon_packet (uint8_t *adv_data, uint8_t adv_data_len){ + bool result = false; + + if ((adv_data != NULL) && (adv_data_len == 0x1E)){ + if (!memcmp(adv_data, (uint8_t*)&ibeacon_common_head, sizeof(ibeacon_common_head))){ + result = true; + } + } + + return result; +} + +esp_err_t esp_ble_config_ibeacon_data (esp_ble_ibeacon_vendor_t *vendor_config, esp_ble_ibeacon_t *ibeacon_adv_data){ + if ((vendor_config == NULL) || (ibeacon_adv_data == NULL) || (!memcmp(vendor_config->proximity_uuid, uuid_zeros, sizeof(uuid_zeros)))){ + return ESP_ERR_INVALID_ARG; + } + + memcpy(&ibeacon_adv_data->ibeacon_head, &ibeacon_common_head, sizeof(esp_ble_ibeacon_head_t)); + memcpy(&ibeacon_adv_data->ibeacon_vendor, vendor_config, sizeof(esp_ble_ibeacon_vendor_t)); + + return ESP_OK; +} \ No newline at end of file diff --git a/src/esp_ibeacon_api.hpp b/src/esp_ibeacon_api.hpp new file mode 100644 index 0000000..173d1c3 --- /dev/null +++ b/src/esp_ibeacon_api.hpp @@ -0,0 +1,71 @@ +/* + * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ + + +/**************************************************************************** +* +* This file is for iBeacon definitions. It supports both iBeacon sender and receiver +* which is distinguished by macros IBEACON_SENDER and IBEACON_RECEIVER, +* +* iBeacon is a trademark of Apple Inc. Before building devices which use iBeacon technology, +* visit https://developer.apple.com/ibeacon/ to obtain a license. +* +****************************************************************************/ + +#include +#include +#include +#include + +#include "esp_gap_ble_api.h" +#include "esp_gattc_api.h" + +#define IBEACON_SENDER 0 +#define IBEACON_RECEIVER 1 +#define IBEACON_MODE CONFIG_IBEACON_MODE + +/* Major and Minor part are stored in big endian mode in iBeacon packet, + * need to use this macro to transfer while creating or processing + * iBeacon data */ +#define ENDIAN_CHANGE_U16(x) ((((x)&0xFF00)>>8) + (((x)&0xFF)<<8)) + +/* Espressif WeChat official account can be found using WeChat "Yao Yi Yao Zhou Bian", + * if device advertises using ESP defined UUID. + * Please refer to http://zb.weixin.qq.com for further information. */ +#define ESP_UUID {0xFD, 0xA5, 0x06, 0x93, 0xA4, 0xE2, 0x4F, 0xB1, 0xAF, 0xCF, 0xC6, 0xEB, 0x07, 0x64, 0x78, 0x25} +#define ESP_MAJOR 10167 +#define ESP_MINOR 61958 + + +typedef struct { + uint8_t flags[3]; + uint8_t length; + uint8_t type; + uint16_t company_id; + uint16_t beacon_type; +}__attribute__((packed)) esp_ble_ibeacon_head_t; + +typedef struct { + uint8_t proximity_uuid[16]; + uint16_t major; + uint16_t minor; + int8_t measured_power; +}__attribute__((packed)) esp_ble_ibeacon_vendor_t; + + +typedef struct { + esp_ble_ibeacon_head_t ibeacon_head; + esp_ble_ibeacon_vendor_t ibeacon_vendor; +}__attribute__((packed)) esp_ble_ibeacon_t; + + +/* For iBeacon packet format, please refer to Apple "Proximity Beacon Specification" doc */ +/* Constant part of iBeacon data */ +extern esp_ble_ibeacon_head_t ibeacon_common_head; + +bool esp_ble_is_ibeacon_packet (uint8_t *adv_data, uint8_t adv_data_len); + +esp_err_t esp_ble_config_ibeacon_data (esp_ble_ibeacon_vendor_t *vendor_config, esp_ble_ibeacon_t *ibeacon_adv_data); \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index 1521d55..d6cb8b0 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -36,6 +36,23 @@ CUDDisplay cudDisplay = CUDDisplay(&cud_display_conf); ESPMegaDisplayOTA cudDisplayOTA = ESPMegaDisplayOTA(); ESPMegaDisplayOTA internalDisplayOTA = ESPMegaDisplayOTA(); +static esp_ble_adv_params_t ble_adv_params = { + .adv_int_min = 0x20, + .adv_int_max = 0x40, + .adv_type = ADV_TYPE_NONCONN_IND, + .own_addr_type = BLE_ADDR_TYPE_PUBLIC, + .channel_map = ADV_CHNL_ALL, + .adv_filter_policy = ADV_FILTER_ALLOW_SCAN_ANY_CON_ANY, +}; + +esp_ble_ibeacon_vendor_t vendor_config_custom = { + .proximity_uuid = ESP_UUID, + .major = ENDIAN_CHANGE_U16(ESP_MAJOR), //Major=ESP_MAJOR + .minor = ENDIAN_CHANGE_U16(ESP_MINOR), //Minor=ESP_MINOR + .measured_power = static_cast(0xC5) +}; + + /************************************************ * End of Global Variables * ************************************************/ @@ -126,6 +143,26 @@ void setup() espmega.display->registerPageChangeCallback(pageChangeCallback); espmega.display->registerTouchCallback(touchCallback); #endif + + ESP_LOGI("CUD IoT OS", "Initializing iBeacon"); + esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT(); + ESP_LOGD("CUD IoT OS", "Configuring BT controller"); + esp_bt_controller_init(&bt_cfg); + ESP_LOGD("CUD IoT OS", "Enabling BT controller in BLE mode"); + esp_bt_controller_enable(ESP_BT_MODE_BLE); + ESP_LOGD("CUD IoT OS", "Initializing Bluedroid"); + esp_bluedroid_init(); + // ESP_LOGD("CUD IoT OS", "Enabling Bluedroid"); + // esp_bluedroid_enable(); + // ESP_LOGD("CUD IoT OS", "Registering GAP callback"); + // esp_ble_gap_register_callback(esp_gap_cb); + // ESP_LOGD("CUD IoT OS", "Configuring iBeacon data with UUID, Major: %d, Minor: %d", + // ENDIAN_CHANGE_U16(ESP_MAJOR), ENDIAN_CHANGE_U16(ESP_MINOR)); + // esp_ble_ibeacon_t ibeacon_adv_data; + // esp_ble_config_ibeacon_data(&vendor_config_custom, &ibeacon_adv_data); + // ESP_LOGD("CUD IoT OS", "Setting raw advertisement data"); + // esp_ble_gap_config_adv_data_raw((uint8_t *)&ibeacon_adv_data, sizeof(ibeacon_adv_data)); + ESP_LOGI("CUD IoT OS", "Initialization Complete"); } @@ -169,4 +206,40 @@ void touchCallback(uint8_t page, uint8_t component, uint8_t touchType) sprintf(buffer, "%d,%d,%d", page, component, touchType); espmega.iot->publishRelative("/tamper/touch", buffer); } -#endif \ No newline at end of file +#endif + +static void esp_gap_cb(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param) +{ + esp_err_t err; + + switch (event) { + case ESP_GAP_BLE_ADV_DATA_RAW_SET_COMPLETE_EVT:{ + ESP_LOGD("iBeacon", "Advertisement data set, starting advertising"); + esp_ble_gap_start_advertising(&ble_adv_params); + break; + } + case ESP_GAP_BLE_ADV_START_COMPLETE_EVT: + //adv start complete event to indicate adv start successfully or failed + if ((err = param->adv_start_cmpl.status) != ESP_BT_STATUS_SUCCESS) { + ESP_LOGE(DEMO_TAG, "Advertising start failed, error %s", esp_err_to_name(err)); + ESP_LOGE("iBeacon", "Advertising start failed with error code: %d", err); + } else { + ESP_LOGI(DEMO_TAG, "Advertising start successfully"); + ESP_LOGI("iBeacon", "iBeacon advertising started successfully"); + } + break; + case ESP_GAP_BLE_ADV_STOP_COMPLETE_EVT: + if ((err = param->adv_stop_cmpl.status) != ESP_BT_STATUS_SUCCESS){ + ESP_LOGE(DEMO_TAG, "Advertising stop failed, error %s", esp_err_to_name(err)); + ESP_LOGE("iBeacon", "Advertising stop failed with error code: %d", err); + } + else { + ESP_LOGI(DEMO_TAG, "Advertising stop successfully"); + ESP_LOGI("iBeacon", "iBeacon advertising stopped successfully"); + } + break; + default: + ESP_LOGV("iBeacon", "Unhandled GAP event: %d", event); + break; + } +} \ No newline at end of file diff --git a/src/main.hpp b/src/main.hpp index 3495415..6e1e53f 100644 --- a/src/main.hpp +++ b/src/main.hpp @@ -9,6 +9,7 @@ * */ #pragma once +#define CONFIG_ARDUINO_LOOP_STACK_SIZE 16384 #include #include #include @@ -16,6 +17,10 @@ #include #include "lcd_elements.hpp" #include "ir_codes.hpp" +#include +#include +#include "esp_ibeacon_api.hpp" +#include #include "display.hpp" #include "config.hpp" @@ -31,4 +36,6 @@ void handle_mqtt_message(char *topic, char *payload); #ifdef TAMPER_DETECTION void pageChangeCallback(uint8_t page); void touchCallback(uint8_t page, uint8_t component, uint8_t touchType); -#endif \ No newline at end of file +#endif + +static void esp_gap_cb(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param); \ No newline at end of file