Added basic BLE code.

Mon, 17 Apr 2023 14:54:35 +0200

author
Michiel Broek <mbroek@mbse.eu>
date
Mon, 17 Apr 2023 14:54:35 +0200
changeset 31
ec5c7794dcd6
parent 30
7448b8dd4288
child 32
84e54b14e7db

Added basic BLE code.

main/CMakeLists.txt file | annotate | diff | comparison | revisions
main/ble_adv.c file | annotate | diff | comparison | revisions
main/ble_adv.h file | annotate | diff | comparison | revisions
main/ble_gap.c file | annotate | diff | comparison | revisions
main/ble_gap.h file | annotate | diff | comparison | revisions
main/ble_gatts.c file | annotate | diff | comparison | revisions
main/ble_gatts.h file | annotate | diff | comparison | revisions
main/config.h file | annotate | diff | comparison | revisions
main/iotbalkon.c file | annotate | diff | comparison | revisions
main/task_ble.c file | annotate | diff | comparison | revisions
main/task_ble.h file | annotate | diff | comparison | revisions
--- a/main/CMakeLists.txt	Sun Apr 16 12:27:12 2023 +0200
+++ b/main/CMakeLists.txt	Mon Apr 17 14:54:35 2023 +0200
@@ -1,5 +1,5 @@
 if(CONFIG_ENABLE_BLE_GATT)
-    set(srcs config.c iotbalkon.c task_bmp280.c task_ina219.c task_apds9930.c task_wifi.c task_mqtt.c task_ble.c task_out.c xutil.c nvsio.c)
+    set(srcs config.c iotbalkon.c task_bmp280.c task_ina219.c task_apds9930.c task_wifi.c task_mqtt.c task_ble.c task_out.c xutil.c nvsio.c ble_adv.c ble_gap.c ble_gatts.c)
 else()
     set(srcs config.c iotbalkon.c task_bmp280.c task_ina219.c task_apds9930.c task_wifi.c task_mqtt.c task_out.c xutil.c nvsio.c)
 endif()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main/ble_adv.c	Mon Apr 17 14:54:35 2023 +0200
@@ -0,0 +1,82 @@
+/**
+ * @file ble_adv.c
+ * @brief BLE ADV service.
+ */
+
+#include "config.h"
+
+
+static const char *TAG = "ble_adv";
+
+#ifdef CONFIG_CODE_PRODUCTION
+#define IOTBALKON_DEVICE_NAME		"IOT_BALKON"
+#endif
+#ifdef CONFIG_CODE_TESTING
+#define IOTBALKON_DEVICE_NAME		"IOT_ESP32C3"
+#endif
+
+
+#define adv_config_flag      (1 << 0)
+static uint8_t adv_config_done = 0;
+
+static esp_ble_adv_params_t adv_params = {
+    .adv_int_min        = 0x20,
+    .adv_int_max        = 0x40,
+    .adv_type           = ADV_TYPE_IND,
+    .own_addr_type      = BLE_ADDR_TYPE_PUBLIC,
+    .channel_map        = ADV_CHNL_ALL,
+    .adv_filter_policy = ADV_FILTER_ALLOW_SCAN_ANY_CON_ANY,
+};
+
+
+esp_err_t ble_balkon_adv_config(void)
+{
+    esp_err_t	ret = ESP_OK;
+
+    esp_ble_adv_data_t adv_data = {
+        .set_scan_rsp = false,
+        .include_name = true,
+        .include_txpower = false,
+        .min_interval = 0x0006, //slave connection min interval, Time = min_interval * 1.25 msec
+        .max_interval = 0x0010, //slave connection max interval, Time = max_interval * 1.25 msec
+        .appearance = 0x00,
+        .manufacturer_len = 0,
+        .p_manufacturer_data =  NULL,
+        .service_data_len = 0,
+        .p_service_data = NULL,
+        .service_uuid_len = 0,
+        .p_service_uuid = NULL,
+        .flag = (ESP_BLE_ADV_FLAG_GEN_DISC | ESP_BLE_ADV_FLAG_BREDR_NOT_SPT),
+    };
+
+    esp_err_t set_dev_name_ret = esp_ble_gap_set_device_name(IOTBALKON_DEVICE_NAME);
+    if (set_dev_name_ret){
+	ESP_LOGE(TAG, "set device name failed, error code = %x", set_dev_name_ret);
+	return set_dev_name_ret;
+    }
+
+    //config adv data
+    ret = esp_ble_gap_config_adv_data(&adv_data);
+    if (ret){
+        ESP_LOGE(TAG, "config adv data failed, error code = %x", ret);
+    }
+    adv_config_done |= adv_config_flag;
+
+    return ret;
+}
+
+
+void ble_balkon_adv_start(void)
+{
+    esp_ble_gap_start_advertising(&adv_params);
+}
+
+
+void ble_balkon_adv_set_complete_handle(void)
+{
+    adv_config_done &= (~adv_config_flag);
+    if (adv_config_done == 0){
+        esp_ble_gap_start_advertising(&adv_params);
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main/ble_adv.h	Mon Apr 17 14:54:35 2023 +0200
@@ -0,0 +1,15 @@
+/**
+ * @file ble_adv.h
+ * @brief BLE Advertise services.
+ */
+
+#ifndef _BLE_ADV_H
+#define _BLE_ADV_H
+
+
+esp_err_t ble_balkon_adv_config(void);
+void ble_balkon_adv_start(void);
+void ble_balkon_adv_set_complete_handle(void);
+
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main/ble_gap.c	Mon Apr 17 14:54:35 2023 +0200
@@ -0,0 +1,58 @@
+/**
+ * @file ble_gap.c
+ * @brief BLE GAP service.
+ */
+
+#include "config.h"
+
+
+static const char *TAG = "ble_gap";
+
+static void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param)
+{
+    switch (event) {
+	case ESP_GAP_BLE_ADV_DATA_SET_COMPLETE_EVT:
+        	ble_balkon_adv_set_complete_handle();
+        	break;
+	case ESP_GAP_BLE_SCAN_RSP_DATA_SET_COMPLETE_EVT:
+        	break;
+	case ESP_GAP_BLE_ADV_START_COMPLETE_EVT:
+        	//advertising start complete event to indicate advertising start successfully or failed
+        	if (param->adv_start_cmpl.status != ESP_BT_STATUS_SUCCESS) {
+        	    ESP_LOGE(TAG, "Advertising start failed");
+        	}
+        	break;
+	case ESP_GAP_BLE_ADV_STOP_COMPLETE_EVT:
+        	if (param->adv_stop_cmpl.status != ESP_BT_STATUS_SUCCESS) {
+        	    ESP_LOGE(TAG, "Advertising stop failed");
+        	} else {
+        	    ESP_LOGI(TAG, "Stop adv successfully");
+        	}
+        	break;
+    	case ESP_GAP_BLE_UPDATE_CONN_PARAMS_EVT:
+        	ESP_LOGI(TAG, "update connection params status = %d, min_int = %d, max_int = %d,conn_int = %d,latency = %d, timeout = %d",
+                  param->update_conn_params.status,
+                  param->update_conn_params.min_int,
+                  param->update_conn_params.max_int,
+                  param->update_conn_params.conn_int,
+                  param->update_conn_params.latency,
+                  param->update_conn_params.timeout);
+        	break;
+    	default:
+		ESP_LOGI(TAG, "gap_event_handler(%d) unknown event", event);
+        	break;
+    }
+}
+
+
+void ble_balkon_gap_register(void)
+{
+    esp_err_t ret;
+
+    ret = esp_ble_gap_register_callback(gap_event_handler);
+    if (ret){
+        ESP_LOGE(TAG, "gap register error, error code = %x", ret);
+        return;
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main/ble_gap.h	Mon Apr 17 14:54:35 2023 +0200
@@ -0,0 +1,12 @@
+/**
+ * @file ble_gap.h
+ * @brief BLE GAP service.
+ */
+
+#ifndef _BLE_GAP_H
+#define _BLE_GAP_H
+
+
+void ble_balkon_gap_register(void);
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main/ble_gatts.c	Mon Apr 17 14:54:35 2023 +0200
@@ -0,0 +1,337 @@
+/**
+ * @file ble_gatts.c
+ * @brief BLE GATTS services.
+ */
+
+#include "config.h"
+
+static const char *TAG = "ble_gatts";
+
+#define PROFILE_NUM             1
+#define PROFILE_RGB_APP_ID      0
+#define PROFILE_RGB_NUM_HANDLE  3
+
+#ifdef USE_BATTERY
+/// characteristic presentation information
+struct char_pres_fmt
+{
+    uint16_t unit;		///< Unit (The Unit is a UUID)
+    uint16_t description;	///< Description
+    uint8_t format;
+    uint8_t exponent;
+    uint8_t name_space;		///< Name space
+};
+
+
+static const uint16_t primary_service_uuid = ESP_GATT_UUID_PRI_SERVICE;
+static const uint16_t character_declaration_uuid = ESP_GATT_UUID_CHAR_DECLARE;
+static const uint16_t character_client_config_uuid = ESP_GATT_UUID_CHAR_CLIENT_CONFIG;
+
+static const uint8_t char_prop_notify = ESP_GATT_CHAR_PROP_BIT_NOTIFY;
+static const uint8_t char_prop_read = ESP_GATT_CHAR_PROP_BIT_READ;
+static const uint8_t char_prop_read_notify = ESP_GATT_CHAR_PROP_BIT_READ|ESP_GATT_CHAR_PROP_BIT_NOTIFY;
+#endif
+
+uint8_t rgb_service_uuid[ESP_UUID_LEN_128] =        {0x00, 0x56, 0xa5, 0x97, 0xd2, 0xb7, 0x2e, 0x81, 0x57, 0x49, 0x00, 0x47, 0x6c, 0x55, 0x02, 0x3b};
+uint8_t rgb_characteristic_uuid[ESP_UUID_LEN_128] = {0x00, 0x56, 0xa5, 0x97, 0xd2, 0xb7, 0x2e, 0x81, 0x57, 0x49, 0x00, 0x47, 0x6c, 0x55, 0x02, 0x3c};
+
+static void gatts_profile_rgb_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param);
+
+struct gatts_profile_inst {
+    esp_gatts_cb_t gatts_cb;
+    uint16_t gatts_if;
+    uint16_t app_id;
+    uint16_t conn_id;
+    uint16_t service_handle;
+    esp_gatt_srvc_id_t service_id;
+    uint16_t char_handle;
+    esp_bt_uuid_t char_uuid;
+    esp_gatt_perm_t perm;
+    esp_gatt_char_prop_t property;
+};
+
+
+/********************/
+
+#ifdef USE_BATTERY
+/// battery Service
+static const uint16_t battary_svc = ESP_GATT_UUID_BATTERY_SERVICE_SVC;
+
+static const uint16_t bat_lev_uuid = ESP_GATT_UUID_BATTERY_LEVEL;
+static const uint8_t  bat_lev_ccc[2] ={ 0x00, 0x00};
+static const uint16_t char_format_uuid = ESP_GATT_UUID_CHAR_PRESENT_FORMAT;
+
+static uint8_t battary_lev = 50;
+
+/// Full HRS Database Description - Used to add attributes into the database
+static const esp_gatts_attr_db_t bas_att_db[BAS_IDX_NB] =
+{
+    // Battary Service Declaration
+    [BAS_IDX_SVC]               = {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&primary_service_uuid, ESP_GATT_PERM_READ,
+                                   sizeof(uint16_t), sizeof(battary_svc), (uint8_t *)&battary_svc}},
+
+    // Battary level Characteristic Declaration
+    [BAS_IDX_BATT_LVL_CHAR]     = {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&character_declaration_uuid, ESP_GATT_PERM_READ,
+                                   sizeof(uint8_t),sizeof(uint8_t), (uint8_t *)&char_prop_read_notify}},
+
+    // Battary level Characteristic Value
+    [BAS_IDX_BATT_LVL_VAL]      = {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&bat_lev_uuid, ESP_GATT_PERM_READ,
+                                   sizeof(uint8_t),sizeof(uint8_t), &battary_lev}},
+
+    // Battary level Characteristic - Client Characteristic Configuration Descriptor
+    [BAS_IDX_BATT_LVL_NTF_CFG]  = {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&character_client_config_uuid, ESP_GATT_PERM_READ|ESP_GATT_PERM_WRITE,
+                                   sizeof(uint16_t),sizeof(bat_lev_ccc), (uint8_t *)bat_lev_ccc}},
+
+    // Battary level report Characteristic Declaration
+    [BAS_IDX_BATT_LVL_PRES_FMT] = {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&char_format_uuid, ESP_GATT_PERM_READ,
+                                   sizeof(struct char_pres_fmt), 0, NULL}},
+};
+#endif
+
+
+
+/*******************/
+
+
+/* One gatt-based profile one app_id and one gatts_if, this array will store the gatts_if returned by ESP_GATTS_REG_EVT */
+static struct gatts_profile_inst gl_profile_tab[PROFILE_NUM] = {
+    [PROFILE_RGB_APP_ID] = {
+        .gatts_cb = gatts_profile_rgb_event_handler,
+        .gatts_if = ESP_GATT_IF_NONE,       /* Not get the gatt_if, so initial is ESP_GATT_IF_NONE */
+    }
+};
+
+static void create_rgb_service(esp_gatt_if_t gatts_if)
+{
+    gl_profile_tab[PROFILE_RGB_APP_ID].service_id.is_primary = true;
+    gl_profile_tab[PROFILE_RGB_APP_ID].service_id.id.inst_id = 0x00;
+    gl_profile_tab[PROFILE_RGB_APP_ID].service_id.id.uuid.len = ESP_UUID_LEN_128;
+    memcpy(gl_profile_tab[PROFILE_RGB_APP_ID].service_id.id.uuid.uuid.uuid128, rgb_service_uuid, ESP_UUID_LEN_128);
+
+    esp_ble_gatts_create_service(gatts_if, &gl_profile_tab[PROFILE_RGB_APP_ID].service_id, PROFILE_RGB_NUM_HANDLE);
+}
+
+static void start_rgb_service(esp_ble_gatts_cb_param_t *param)
+{
+    gl_profile_tab[PROFILE_RGB_APP_ID].service_handle = param->create.service_handle;
+    esp_ble_gatts_start_service(gl_profile_tab[PROFILE_RGB_APP_ID].service_handle);
+}
+
+static void add_rgb_characteristic(void)
+{
+    uint8_t char_value[] = {0x00};
+
+    esp_attr_value_t rgb_char_val =
+    {
+        .attr_max_len = sizeof(char_value),
+        .attr_len     = sizeof(char_value),
+        .attr_value   = char_value,
+    };
+
+    gl_profile_tab[PROFILE_RGB_APP_ID].char_uuid.len = ESP_UUID_LEN_128;
+    memcpy(gl_profile_tab[PROFILE_RGB_APP_ID].char_uuid.uuid.uuid128, rgb_characteristic_uuid, ESP_UUID_LEN_128);
+
+    esp_err_t add_char_ret = esp_ble_gatts_add_char(gl_profile_tab[PROFILE_RGB_APP_ID].service_handle, &gl_profile_tab[PROFILE_RGB_APP_ID].char_uuid,
+                                                    ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE,
+                                                    ESP_GATT_CHAR_PROP_BIT_WRITE,
+                                                    &rgb_char_val, NULL);
+    if (add_char_ret){
+        ESP_LOGE(TAG, "add char failed, error code =%x",add_char_ret);
+    }
+}
+
+static void handle_write_event(uint8_t * p_data, uint16_t len)
+{
+    uint8_t opcode = p_data[0];
+    ESP_LOGI(TAG, "opcode = 0x%x", opcode);
+    switch (opcode)
+    {
+        case 1:
+//            rgb_ctrl(RGB_RED, RGB_ON);
+//            rgb_ctrl(RGB_GREEN, RGB_OFF);
+//            rgb_ctrl(RGB_BLUE, RGB_OFF);
+            break;
+        case 2:
+//            rgb_ctrl(RGB_RED, RGB_OFF);
+//            rgb_ctrl(RGB_GREEN, RGB_ON);
+//            rgb_ctrl(RGB_BLUE, RGB_OFF);
+            break;
+        case 3:
+//            rgb_ctrl(RGB_RED, RGB_OFF);
+//            rgb_ctrl(RGB_GREEN, RGB_OFF);
+//            rgb_ctrl(RGB_BLUE, RGB_ON);
+            break;
+        case 4:
+//            rgb_ctrl(RGB_RED, RGB_OFF);
+//            rgb_ctrl(RGB_GREEN, RGB_OFF);
+//            rgb_ctrl(RGB_BLUE, RGB_OFF);
+            break;
+        default:
+            break;
+    }
+}
+
+
+static void gatts_profile_rgb_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param)
+{
+    ESP_LOGI(TAG, "gatts_profile_rgb_event_handler()");
+
+    switch (event) {
+    case ESP_GATTS_REG_EVT:
+        ESP_LOGI(TAG, "REGISTER_APP_EVT, status %d, app_id %d", param->reg.status, param->reg.app_id);
+        ble_balkon_adv_config();
+        create_rgb_service(gatts_if);
+        break;
+    case ESP_GATTS_READ_EVT: {
+        ESP_LOGI(TAG, "GATT_READ_EVT, conn_id %d, trans_id %lu, handle %d\n", param->read.conn_id, param->read.trans_id, param->read.handle);
+        break;
+    }
+    case ESP_GATTS_WRITE_EVT: {
+        ESP_LOGI(TAG, "GATT_WRITE_EVT, conn_id %d, trans_id %lu, handle %d", param->write.conn_id, param->write.trans_id, param->write.handle);
+        if (!param->write.is_prep){
+            ESP_LOGI(TAG, "GATT_WRITE_EVT, value len %d, value :", param->write.len);
+            esp_log_buffer_hex(TAG, param->write.value, param->write.len);
+            handle_write_event(param->write.value, param->write.len);
+        }
+        esp_gatt_status_t status = ESP_GATT_OK;
+        if (param->write.need_rsp){
+            if (!param->write.is_prep){
+                esp_ble_gatts_send_response(gatts_if, param->write.conn_id, param->write.trans_id, status, NULL);
+            }
+        }
+        break;
+    }
+    case ESP_GATTS_EXEC_WRITE_EVT:
+        ESP_LOGI(TAG,"ESP_GATTS_EXEC_WRITE_EVT");
+        break;
+    case ESP_GATTS_MTU_EVT:
+        ESP_LOGI(TAG, "ESP_GATTS_MTU_EVT, MTU %d", param->mtu.mtu);
+        break;
+    case ESP_GATTS_UNREG_EVT:
+        break;
+    case ESP_GATTS_CREATE_EVT:
+        ESP_LOGI(TAG, "CREATE_SERVICE_EVT, status %d,  service_handle %d", param->create.status, param->create.service_handle);
+        start_rgb_service(param);
+        add_rgb_characteristic();
+        break;
+    case ESP_GATTS_ADD_INCL_SRVC_EVT:
+        break;
+    case ESP_GATTS_ADD_CHAR_EVT: {
+        ESP_LOGI(TAG, "ADD_CHAR_EVT, status %d, attr_handle %d, service_handle %d",
+                param->add_char.status, param->add_char.attr_handle, param->add_char.service_handle);
+        break;
+    }
+    case ESP_GATTS_ADD_CHAR_DESCR_EVT:
+        ESP_LOGI(TAG, "ADD_DESCR_EVT, status %d, attr_handle %d, service_handle %d",
+                 param->add_char_descr.status, param->add_char_descr.attr_handle, param->add_char_descr.service_handle);
+        break;
+    case ESP_GATTS_DELETE_EVT:
+        break;
+    case ESP_GATTS_START_EVT:
+        ESP_LOGI(TAG, "SERVICE_START_EVT, status %d, service_handle %d", param->start.status, param->start.service_handle);
+        break;
+    case ESP_GATTS_STOP_EVT:
+        break;
+    case ESP_GATTS_CONNECT_EVT: {
+        esp_ble_conn_update_params_t conn_params = {0};
+        memcpy(conn_params.bda, param->connect.remote_bda, sizeof(esp_bd_addr_t));
+        /* For the IOS system, please reference the apple official documents about the ble connection parameters restrictions. */
+        conn_params.latency = 0;
+        conn_params.max_int = 0x20;    // max_int = 0x20*1.25ms = 40ms
+        conn_params.min_int = 0x10;    // min_int = 0x10*1.25ms = 20ms
+        conn_params.timeout = 400;    // timeout = 400*10ms = 4000ms
+        ESP_LOGI(TAG, "ESP_GATTS_CONNECT_EVT, conn_id %d, remote %02x:%02x:%02x:%02x:%02x:%02x:",
+                 param->connect.conn_id,
+                 param->connect.remote_bda[0], param->connect.remote_bda[1], param->connect.remote_bda[2],
+                 param->connect.remote_bda[3], param->connect.remote_bda[4], param->connect.remote_bda[5]);
+        gl_profile_tab[PROFILE_RGB_APP_ID].conn_id = param->connect.conn_id;
+        //start sent the update connection parameters to the peer device.
+        esp_ble_gap_update_conn_params(&conn_params);
+        break;
+    }
+    case ESP_GATTS_DISCONNECT_EVT:
+        ESP_LOGI(TAG, "ESP_GATTS_DISCONNECT_EVT, disconnect reason 0x%x", param->disconnect.reason);
+        ble_balkon_adv_start();
+        break;
+    case ESP_GATTS_CONF_EVT:
+        ESP_LOGI(TAG, "ESP_GATTS_CONF_EVT, status %d attr_handle %d", param->conf.status, param->conf.handle);
+        if (param->conf.status != ESP_GATT_OK){
+            esp_log_buffer_hex(TAG, param->conf.value, param->conf.len);
+        }
+        break;
+    case ESP_GATTS_OPEN_EVT:
+    case ESP_GATTS_CANCEL_OPEN_EVT:
+    case ESP_GATTS_CLOSE_EVT:
+    case ESP_GATTS_LISTEN_EVT:
+    case ESP_GATTS_CONGEST_EVT:
+    default:
+        break;
+    }
+}
+
+
+static void gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param)
+{
+    ESP_LOGI(TAG, "gatts_event_handler(%x)", event);
+
+    /* If event is register event, store the gatts_if for each profile */
+    if (event == ESP_GATTS_REG_EVT) {
+        if (param->reg.status == ESP_GATT_OK) {
+            gl_profile_tab[param->reg.app_id].gatts_if = gatts_if;
+        } else {
+            ESP_LOGI(TAG, "Reg app failed, app_id %04x, status %d", param->reg.app_id, param->reg.status);
+            return;
+        }
+    }
+
+    /* If the gatts_if equal to profile A, call profile A cb handler,
+     * so here call each profile's callback */
+    do {
+        int idx;
+        for (idx = 0; idx < PROFILE_NUM; idx++) {
+            if (gatts_if == ESP_GATT_IF_NONE || /* ESP_GATT_IF_NONE, not specify a certain gatt_if, need to call every profile cb function */
+                    gatts_if == gl_profile_tab[idx].gatts_if) {
+                if (gl_profile_tab[idx].gatts_cb) {
+                    gl_profile_tab[idx].gatts_cb(event, gatts_if, param);
+                }
+            }
+        }
+    } while (0);
+}
+
+
+/***************************************************************************************************************************/
+
+esp_err_t ble_balkon_gatts_register(void)
+{
+    esp_err_t ret = esp_ble_gatts_register_callback(gatts_event_handler);
+    if (ret){
+        ESP_LOGE(TAG, "gatts register error, error code = %x", ret);
+    }
+
+    return ret;
+}
+
+
+esp_err_t ble_balkon_gatts_app_register(void)
+{
+    esp_err_t ret = esp_ble_gatts_app_register(PROFILE_RGB_APP_ID);
+    if (ret){
+        ESP_LOGE(TAG, "gatts app register error, error code = %x", ret);
+    }
+
+    return ret;
+}
+
+
+esp_err_t ble_balkon_gatts_set_mtu(void)
+{
+    esp_err_t local_mtu_ret = esp_ble_gatt_set_local_mtu(500);
+    if (local_mtu_ret){
+	ESP_LOGE(TAG, "set local  MTU failed, error code = %x", local_mtu_ret);
+    }
+
+    return local_mtu_ret;
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main/ble_gatts.h	Mon Apr 17 14:54:35 2023 +0200
@@ -0,0 +1,28 @@
+/**
+ * @file ble_gatts.h
+ * @brief BLE GATTS services.
+ */
+
+#ifndef _BLE_GATTS_H
+#define _BLE_GATTS_H
+
+
+/// Battery Service Attributes Indexes
+enum
+{
+    BAS_IDX_SVC,
+
+    BAS_IDX_BATT_LVL_CHAR,
+    BAS_IDX_BATT_LVL_VAL,
+    BAS_IDX_BATT_LVL_NTF_CFG,
+    BAS_IDX_BATT_LVL_PRES_FMT,
+
+    BAS_IDX_NB,
+};
+
+
+esp_err_t ble_balkon_gatts_register(void);
+esp_err_t ble_balkon_gatts_app_register(void);
+esp_err_t ble_balkon_gatts_set_mtu(void);
+
+#endif
--- a/main/config.h	Sun Apr 16 12:27:12 2023 +0200
+++ b/main/config.h	Mon Apr 17 14:54:35 2023 +0200
@@ -40,6 +40,7 @@
 #include "esp_gatts_api.h"
 #include "esp_bt_defs.h"
 #include "esp_bt_main.h"
+#include "esp_gatt_common_api.h"
 #endif
 #include "nvs_flash.h"
 #include "lwip/err.h"
@@ -62,6 +63,9 @@
 #include "task_apds9930.h"
 #ifdef CONFIG_ENABLE_BLE_GATT
 #include "task_ble.h"
+#include "ble_adv.h"
+#include "ble_gap.h"
+#include "ble_gatts.h"
 #endif
 #include "task_wifi.h"
 #include "task_mqtt.h"
--- a/main/iotbalkon.c	Sun Apr 16 12:27:12 2023 +0200
+++ b/main/iotbalkon.c	Mon Apr 17 14:54:35 2023 +0200
@@ -421,10 +421,10 @@
     uint8_t	ds_time = DS_Time;
 
 
-    while (0) {
-	request_bmp280();
-	request_ina219();
-	request_apds9930();
+    while (1) {
+//	request_bmp280();
+//	request_ina219();
+//	request_apds9930();
 	vTaskDelay(5000 / portTICK_PERIOD_MS);
     }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main/task_ble.c	Mon Apr 17 14:54:35 2023 +0200
@@ -0,0 +1,82 @@
+/**
+ * @file task_ble.c
+ * @brief BLE task. Secure GATT server.
+ */
+
+#include "config.h"
+
+
+static const char *TAG = "task_ble";
+
+
+
+void task_ble( void * pvParameters )
+{
+    esp_err_t	ret;
+
+    ESP_LOGI(TAG, "Starting BLE task");
+
+    /*
+     * Initialize Bluetooth
+     */
+    ESP_ERROR_CHECK(esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT));
+
+    esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();
+    ret = esp_bt_controller_init(&bt_cfg);
+    if (ret) {
+        ESP_LOGE(TAG, "init controller failed: %s", esp_err_to_name(ret));
+        goto deadend;
+    }
+
+    ret = esp_bt_controller_enable(ESP_BT_MODE_BLE);
+    if (ret) {
+        ESP_LOGE(TAG, "enable controller failed: %s", esp_err_to_name(ret));
+        goto deadend;
+    }
+
+    ESP_LOGI(TAG, "init bluetooth");
+    ret = esp_bluedroid_init();
+    if (ret) {
+        ESP_LOGE(TAG, "init bluetooth failed: %s", esp_err_to_name(ret));
+        goto deadend;
+    }
+
+    ret = esp_bluedroid_enable();
+    if (ret) {
+        ESP_LOGE(TAG, "enable bluetooth failed: %s", esp_err_to_name(ret));
+        goto deadend;
+    }
+
+    ret = ble_balkon_gatts_register();
+    if (ret)
+	goto deadend;
+
+    ble_balkon_gap_register();
+
+    ret = ble_balkon_gatts_app_register();
+    if (ret)
+	goto deadend;
+
+    ret = ble_balkon_gatts_set_mtu();
+    if (ret)
+	goto deadend;
+
+    ESP_LOGI(TAG, "Start BLE done, enter loop");
+
+    for(;;) {
+
+
+	vTaskDelay(20 / portTICK_PERIOD_MS);
+    } /* for(;;) */
+
+
+    /*
+     * Error point for init errors.
+     */
+deadend:
+    ESP_LOGI(TAG, "Startup error loop");
+    for(;;) {
+	vTaskDelay(50 / portTICK_PERIOD_MS);
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main/task_ble.h	Mon Apr 17 14:54:35 2023 +0200
@@ -0,0 +1,18 @@
+/**
+ * @file task_ble.h
+ * @brief BLE task, secure GATT server.
+ */
+
+#ifndef _TASK_BLE_H
+#define _TASK_BLE_H
+
+
+
+/**
+ * @brief Main task for the ble_manager
+ * @param pvParameters Parameters for the task.
+ */
+void task_ble(void *pvParameters);
+
+
+#endif

mercurial