esp-idf/examples/bluetooth/esp_ble_mesh/aligenie_demo/main/aligenie_demo.c

1345 wiersze
58 KiB
C
Czysty Wina Historia

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

/* AliGenie - Example
This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <math.h>
#include "esp_log.h"
#include "nvs_flash.h"
#include "mbedtls/sha256.h"
#include "esp_ble_mesh_common_api.h"
#include "esp_ble_mesh_networking_api.h"
#include "esp_ble_mesh_provisioning_api.h"
#include "esp_ble_mesh_config_model_api.h"
#include "esp_ble_mesh_health_model_api.h"
#include "esp_ble_mesh_generic_model_api.h"
#include "esp_ble_mesh_lighting_model_api.h"
#include "esp_ble_mesh_time_scene_model_api.h"
#include "esp_ble_mesh_local_data_operation_api.h"
#include "board.h"
#include "genie_mesh.h"
#include "ble_mesh_example_init.h"
#include "ble_mesh_example_nvs.h"
static const char *TAG = "genie_demo";
#define MESH_ELEM_COUNT 1
#define MESH_ELEM_STATE_COUNT MESH_ELEM_COUNT
nvs_handle_t NVS_HANDLE;
elem_state_t g_elem_state[MESH_ELEM_STATE_COUNT] = {0};
model_powerup_t g_powerup[MESH_ELEM_STATE_COUNT] = {0};
static uint8_t static_val[16] = {0x64, 0xda, 0x19, 0x8f, 0x58, 0xea, 0x55, 0x85,
0x75, 0x84, 0x0d, 0xbf, 0x4f, 0x6e, 0x36, 0x8f
};
static uint8_t dev_uuid[16] = {
0xA8, 0x01, // CID
0x71, // PID Bit0-3 ble adv version, 0x01
// bit4: One machine one secret
// bit5: Support OTA
// bit6~7
// 00BLE4.0
// 01BLE4.2
// 10BLE5.0
// 11BLE5.0 above
0x7F, 0x2C, 0x00, 0x00, // ProductID // 00002C7F
0xda, 0x91, 0x01, 0x7a, 0xfa, 0x28, // MAC Address // 28fa7a0191da
#if GENIE_VENDOR_MODEL_VERSION == 0
0x00, // Feature Flag bit7-1uuid version, version 0
// bit0 0: unprovisioned adv
// 1: silent adv
#elif GENIE_VENDOR_MODEL_VERSION == 1
0x02, // Feature Flag bit7-1uuidversion, version 1
// bit0 0: unprovisioned adv
// 1: silent adv
#endif
0x00, 0x00, // RFU
};
static esp_ble_mesh_cfg_srv_t config_server = {
.relay = ESP_BLE_MESH_RELAY_ENABLED,
.beacon = ESP_BLE_MESH_BEACON_ENABLED,
#if defined(CONFIG_BLE_MESH_FRIEND)
.friend_state = ESP_BLE_MESH_FRIEND_ENABLED,
#else
.friend_state = ESP_BLE_MESH_FRIEND_NOT_SUPPORTED,
#endif
#if defined(CONFIG_BLE_MESH_GATT_PROXY_SERVER)
.gatt_proxy = ESP_BLE_MESH_GATT_PROXY_ENABLED,
#else
.gatt_proxy = ESP_BLE_MESH_GATT_PROXY_NOT_SUPPORTED,
#endif
.default_ttl = 7,
/* 3 transmissions with 20ms interval */
.net_transmit = ESP_BLE_MESH_TRANSMIT(2, 20),
/* 3 transmissions with 20ms interval */
.relay_retransmit = ESP_BLE_MESH_TRANSMIT(2, 20),
};
uint8_t test_ids[1] = {0x00};
/** ESP BLE Mesh Health Server Model Context */
ESP_BLE_MESH_MODEL_PUB_DEFINE(health_pub, 2 + 11, ROLE_NODE);
static esp_ble_mesh_health_srv_t health_server = {
.health_test.id_count = 1,
.health_test.test_ids = test_ids,
};
#ifdef CONFIG_MESH_MODEL_GEN_ONOFF_SRV
ESP_BLE_MESH_MODEL_PUB_DEFINE(onoff_pub_0, 2 + 3, ROLE_NODE);
static esp_ble_mesh_gen_onoff_srv_t onoff_server_0 = {
.rsp_ctrl.get_auto_rsp = ESP_BLE_MESH_SERVER_AUTO_RSP,
.rsp_ctrl.set_auto_rsp = ESP_BLE_MESH_SERVER_AUTO_RSP,
};
#endif
#ifdef CONFIG_MESH_MODEL_LIGHTNESS_SRV
/* Light Lightness state related context */
static esp_ble_mesh_light_lightness_state_t lightness_state;
/* Light Lightness Server related context */
ESP_BLE_MESH_MODEL_PUB_DEFINE(lightness_pub, 2 + 5, ROLE_NODE);
static esp_ble_mesh_light_lightness_srv_t lightness_server = {
.rsp_ctrl.get_auto_rsp = ESP_BLE_MESH_SERVER_AUTO_RSP,
.rsp_ctrl.set_auto_rsp = ESP_BLE_MESH_SERVER_AUTO_RSP,
.state = &lightness_state,
};
/* Light Lightness Setup Server related context */
ESP_BLE_MESH_MODEL_PUB_DEFINE(lightness_setup_pub, 2 + 5, ROLE_NODE);
static esp_ble_mesh_light_lightness_setup_srv_t lightness_setup_server = {
.rsp_ctrl.get_auto_rsp = ESP_BLE_MESH_SERVER_AUTO_RSP,
.rsp_ctrl.set_auto_rsp = ESP_BLE_MESH_SERVER_AUTO_RSP,
.state = &lightness_state,
};
#endif
#ifdef CONFIG_MESH_MODEL_CTL_SRV
/* Light CTL state related context */
static esp_ble_mesh_light_ctl_state_t ctl_state;
/* Light CTL Server related context */
ESP_BLE_MESH_MODEL_PUB_DEFINE(ctl_pub, 2 + 9, ROLE_NODE);
static esp_ble_mesh_light_ctl_srv_t ctl_server = {
.rsp_ctrl.get_auto_rsp = ESP_BLE_MESH_SERVER_AUTO_RSP,
.rsp_ctrl.set_auto_rsp = ESP_BLE_MESH_SERVER_AUTO_RSP,
.state = &ctl_state,
};
/* Light CTL Setup Server related context */
ESP_BLE_MESH_MODEL_PUB_DEFINE(ctl_setup_pub, 2 + 6, ROLE_NODE);
static esp_ble_mesh_light_ctl_setup_srv_t ctl_setup_server = {
.rsp_ctrl.get_auto_rsp = ESP_BLE_MESH_SERVER_AUTO_RSP,
.rsp_ctrl.set_auto_rsp = ESP_BLE_MESH_SERVER_AUTO_RSP,
.state = &ctl_state,
};
#endif
#ifdef CONFIG_MESH_MODEL_HSL_SRV
/* Light HSL state related context */
static esp_ble_mesh_light_hsl_state_t hsl_state;
/* Light HSL Server related context */
ESP_BLE_MESH_MODEL_PUB_DEFINE(hsl_pub, 2 + 9, ROLE_NODE);
static esp_ble_mesh_light_hsl_srv_t hsl_server = {
.rsp_ctrl.get_auto_rsp = ESP_BLE_MESH_SERVER_AUTO_RSP,
.rsp_ctrl.set_auto_rsp = ESP_BLE_MESH_SERVER_AUTO_RSP,
.state = &hsl_state,
};
/* Light HSL Setup Server related context */
ESP_BLE_MESH_MODEL_PUB_DEFINE(hsl_setup_pub, 2 + 9, ROLE_NODE);
static esp_ble_mesh_light_hsl_setup_srv_t hsl_setup_server = {
.rsp_ctrl.get_auto_rsp = ESP_BLE_MESH_SERVER_AUTO_RSP,
.rsp_ctrl.set_auto_rsp = ESP_BLE_MESH_SERVER_AUTO_RSP,
.state = &hsl_state,
};
#endif
static esp_ble_mesh_model_t root_models[] = {
ESP_BLE_MESH_MODEL_CFG_SRV(&config_server),
ESP_BLE_MESH_MODEL_HEALTH_SRV(&health_server, &health_pub),
#ifdef CONFIG_MESH_MODEL_GEN_ONOFF_SRV
ESP_BLE_MESH_MODEL_GEN_ONOFF_SRV(&onoff_pub_0, &onoff_server_0),
#endif
#ifdef CONFIG_MESH_MODEL_LIGHTNESS_SRV
ESP_BLE_MESH_MODEL_LIGHT_LIGHTNESS_SRV(&lightness_pub, &lightness_server),
ESP_BLE_MESH_MODEL_LIGHT_LIGHTNESS_SETUP_SRV(&lightness_setup_pub, &lightness_setup_server),
#endif
#ifdef CONFIG_MESH_MODEL_CTL_SRV
ESP_BLE_MESH_MODEL_LIGHT_CTL_SRV(&ctl_pub, &ctl_server),
ESP_BLE_MESH_MODEL_LIGHT_CTL_SETUP_SRV(&ctl_setup_pub, &ctl_setup_server),
#endif
#ifdef CONFIG_MESH_MODEL_HSL_SRV
ESP_BLE_MESH_MODEL_LIGHT_HSL_SRV(&hsl_pub, &hsl_server),
ESP_BLE_MESH_MODEL_LIGHT_HSL_SETUP_SRV(&hsl_setup_pub, &hsl_setup_server),
#endif
};
/** @def g_vendor_model_alibaba_op
*
* @brief vendor model operations struct
*
*/
static esp_ble_mesh_model_op_t g_vendor_model_alibaba_op[] = {
ESP_BLE_MESH_MODEL_OP(GENIE_MESSAGE_OP_ATTR_GET_STATUS, 2),
ESP_BLE_MESH_MODEL_OP(GENIE_MESSAGE_OP_ATTR_SET_ACK, 2),
ESP_BLE_MESH_MODEL_OP(GENIE_MESSAGE_OP_ATTR_SET_UNACK, 2),
ESP_BLE_MESH_MODEL_OP(GENIE_MESSAGE_OP_ATTR_STATUS, 1),
ESP_BLE_MESH_MODEL_OP(GENIE_MESSAGE_OP_ATTR_INDICATION, 1),
ESP_BLE_MESH_MODEL_OP(GENIE_MESSAGE_OP_ATTR_CONFIRMATION, 1),
ESP_BLE_MESH_MODEL_OP(GENIE_MESSAGE_OP_ATTR_TRANSPARENT_MSG, 1),
ESP_BLE_MESH_MODEL_OP_END,
};
static esp_ble_mesh_model_t ali_vnd_models[] = {
ESP_BLE_MESH_VENDOR_MODEL(CID_ALIBABA, GENIE_VENDOR_MODEL_SRV_ID, g_vendor_model_alibaba_op, NULL, NULL),
};
ESP_BLE_MESH_MODEL_PUB_DEFINE(onoff_pub_1, 2 + 3, ROLE_NODE);
static esp_ble_mesh_gen_onoff_srv_t onoff_server_1 = {
.rsp_ctrl.get_auto_rsp = ESP_BLE_MESH_SERVER_RSP_BY_APP,
.rsp_ctrl.set_auto_rsp = ESP_BLE_MESH_SERVER_RSP_BY_APP,
};
ESP_BLE_MESH_MODEL_PUB_DEFINE(onoff_pub_2, 2 + 3, ROLE_NODE);
static esp_ble_mesh_gen_onoff_srv_t onoff_server_2 = {
.rsp_ctrl.get_auto_rsp = ESP_BLE_MESH_SERVER_AUTO_RSP,
.rsp_ctrl.set_auto_rsp = ESP_BLE_MESH_SERVER_RSP_BY_APP,
};
static esp_ble_mesh_model_t extend_model_0[] = {
ESP_BLE_MESH_MODEL_GEN_ONOFF_SRV(&onoff_pub_1, &onoff_server_1),
};
static esp_ble_mesh_model_t extend_model_1[] = {
ESP_BLE_MESH_MODEL_GEN_ONOFF_SRV(&onoff_pub_2, &onoff_server_2),
};
esp_ble_mesh_elem_t elements[] = {
ESP_BLE_MESH_ELEMENT(0, root_models, ali_vnd_models),
ESP_BLE_MESH_ELEMENT(0, extend_model_0, ESP_BLE_MESH_MODEL_NONE),
ESP_BLE_MESH_ELEMENT(0, extend_model_1, ESP_BLE_MESH_MODEL_NONE),
};
static esp_ble_mesh_comp_t composition = {
.cid = CID_ALIBABA,
.elements = elements,
.element_count = ARRAY_SIZE(elements),
};
/* Disable OOB security for SILabs Android app */
static esp_ble_mesh_prov_t provision = {
.uuid = dev_uuid,
.static_val = static_val,
.static_val_len = 16,
.output_size = 0, // not support output OOB
.output_actions = ESP_BLE_MESH_NO_OUTPUT,
.input_size = 0, // not support Input OOB
.input_actions = ESP_BLE_MESH_NO_INPUT,
};
static void light_color_set(uint16_t lightness, uint16_t hue, uint16_t saturation);
void set_silent_broadcast(void)
{
dev_uuid[13] |= GENIE_UNPROV_ADV_FEATURE_SILENT_ADV;
}
void set_unprovision_broadcast(void)
{
dev_uuid[13] &= ~GENIE_UNPROV_ADV_FEATURE_SILENT_ADV;
}
void user_prov_complete(uint16_t net_idx, uint16_t addr)
{
ENTER_FUNC();
// todo: add custom code
}
void user_prov_reset(void)
{
ENTER_FUNC();
// todo: add custom code
esp_restart();
}
void reset_light_para(void)
{
ENTER_FUNC();
uint8_t i = 0;
while (i < MESH_ELEM_STATE_COUNT) {
#ifdef CONFIG_MESH_SIMPLE_MODLE
g_elem_state[i].state.onoff[VALUE_TYPE_CUR] = GENIE_ONOFF_DEFAULT;
g_elem_state[i].state.onoff[VALUE_TYPE_TAR] = GENIE_ONOFF_DEFAULT;
#ifdef CONFIG_MESH_MODEL_LIGHTNESS_SRV
g_elem_state[i].state.actual[VALUE_TYPE_CUR] = GENIE_LIGHTNESS_DEFAULT;
g_elem_state[i].state.actual[VALUE_TYPE_TAR] = GENIE_LIGHTNESS_DEFAULT;
#endif
#ifdef CONFIG_MESH_MODEL_CTL_SRV
g_elem_state[i].state.temp[VALUE_TYPE_CUR] = GENIE_CTL_TEMP_DEFAULT;
g_elem_state[i].state.temp[VALUE_TYPE_TAR] = GENIE_CTL_TEMP_DEFAULT;
#endif
#ifdef CONFIG_MESH_MODEL_TRANS
g_elem_state[i].state.trans = 0;
g_elem_state[i].state.delay = 0;
g_elem_state[i].state.trans_start_time = 0;
g_elem_state[i].state.trans_end_time = 0;
#endif
#ifdef CONFIG_MESH_MODEL_LIGHTNESS_SRV
g_elem_state[i].powerup.last_actual = GENIE_LIGHTNESS_DEFAULT;
g_powerup [i].last_actual = GENIE_LIGHTNESS_DEFAULT;
#endif
#ifdef CONFIG_MESH_MODEL_CTL_SRV
g_elem_state[i].powerup.last_temp = GENIE_CTL_TEMP_DEFAULT;
g_powerup [i].last_temp = GENIE_CTL_TEMP_DEFAULT;
#endif
#endif
i++;
}
ble_mesh_nvs_store(NVS_HANDLE, POWERUP_KEY, g_powerup, sizeof(g_powerup));
}
void save_light_state(elem_state_t *p_elem)
{
ENTER_FUNC();
#ifdef CONFIG_MESH_MODEL_LIGHTNESS_SRV
if (p_elem->state.actual[VALUE_TYPE_CUR] != 0) {
p_elem->powerup.last_actual = p_elem->state.actual[VALUE_TYPE_CUR];
g_powerup[p_elem->elem_index].last_actual = p_elem->state.actual[VALUE_TYPE_CUR];
}
ESP_LOGD(TAG, "elem %d, actual %d", p_elem->elem_index, g_powerup[p_elem->elem_index].last_actual);
#endif
#ifdef CONFIG_MESH_MODEL_CTL_SRV
p_elem->powerup.last_temp = p_elem->state.temp[VALUE_TYPE_CUR];
g_powerup[p_elem->elem_index].last_temp = p_elem->state.temp[VALUE_TYPE_CUR];
ESP_LOGD(TAG, "elem %d, temp %d", p_elem->elem_index, g_powerup[p_elem->elem_index].last_temp);
#endif
ble_mesh_nvs_store(NVS_HANDLE, POWERUP_KEY, g_powerup, sizeof(g_powerup));
}
void load_light_state(void)
{
ENTER_FUNC();
uint8_t i = 0;
bool exist = false;
esp_err_t ret = ESP_OK;
ret = ble_mesh_nvs_restore(NVS_HANDLE, POWERUP_KEY, g_powerup, sizeof(g_powerup), &exist);
if (ret == ESP_OK) {
while (i < MESH_ELEM_STATE_COUNT) {
memcpy(&g_elem_state[i].powerup, &g_powerup[i], sizeof(model_powerup_t));
#ifdef CONFIG_MESH_MODEL_LIGHTNESS_SRV
ESP_LOGI(TAG, "elem %d, actual %d", i, g_powerup[i].last_actual);
if (g_powerup[i].last_actual) {
g_elem_state[i].state.actual[VALUE_TYPE_TAR] = g_powerup[i].last_actual;
}
#endif
#ifdef CONFIG_MESH_MODEL_CTL_SRV
ESP_LOGI(TAG, "elem %d, temp %d", i, g_powerup[i].last_temp);
if (g_powerup[i].last_temp) {
g_elem_state[i].state.temp[VALUE_TYPE_TAR] = g_powerup[i].last_temp;
}
#endif
#ifdef CONFIG_MESH_MODEL_GEN_ONOFF_SRV
#ifdef CONFIG_MESH_MODEL_LIGHTNESS_SRV
if (g_elem_state[i].state.actual[VALUE_TYPE_TAR] == 0) {
g_elem_state[i].state.onoff[VALUE_TYPE_TAR] = 0;
} else {
g_elem_state[i].state.onoff[VALUE_TYPE_TAR] = 1;
}
#endif
#ifdef CONFIG_MESH_MODEL_TRANS
if (g_elem_state[i].state.onoff[VALUE_TYPE_TAR] == 0) {
g_elem_state[i].state.trans = 0;
g_elem_state[i].state.delay = 0;
g_elem_state[i].state.trans_start_time = 0;
g_elem_state[i].state.trans_end_time = 0;
} else {
g_elem_state[i].state.trans = 0x41;
g_elem_state[i].state.delay = 100;
g_elem_state[i].state.trans_start_time = k_uptime_get() + g_elem_state[i].state.delay * 5;
g_elem_state[i].state.trans_end_time = g_elem_state[i].state.trans_start_time + get_transition_time(g_elem_state[i].state.trans);
}
#endif
#endif
i++;
}
}
}
void user_genie_event_handle(genie_event_t event, void *p_arg)
{
genie_event_t next_event = event;
ESP_LOGD(TAG, "event: %02d, %p", event, p_arg);
switch (event) {
case GENIE_EVT_RESET_BY_REPEAT_NOTIFY:
ESP_LOGI(TAG, "GENIE_EVT_RESET_BY_REPEAT_NOTIFY");
light_driver_breath_start(0, 255, 0); /**< green blink */
break;
case GENIE_EVT_SW_RESET:
case GENIE_EVT_HW_RESET_START:
ESP_LOGI(TAG, "GENIE_EVT_HW_RESET_START");
light_driver_breath_start(0, 255, 0); /**< green blink */
ble_mesh_nvs_erase(NVS_HANDLE, LIGHT_STATUS_STORE_KEY); // erase led status
reset_light_para();
break;
case GENIE_EVT_SDK_MESH_INIT:
ESP_LOGI(TAG, "GENIE_EVT_SDK_MESH_INIT");
break;
case GENIE_EVT_SDK_MESH_PROV_SUCCESS:
ESP_LOGI(TAG, "GENIE_EVT_SDK_MESH_PROV_SUCCESS");
g_elem_state[0].state.onoff[VALUE_TYPE_TAR] = 1;
g_indication_flag |= INDICATION_FLAG_ONOFF;
#ifdef CONFIG_MESH_MODEL_LIGHTNESS_SRV
g_elem_state[0].state.actual[VALUE_TYPE_TAR] = 0xFFFE;
g_indication_flag |= INDICATION_FLAG_LIGHTNESS;
#endif
#ifdef CONFIG_MESH_MODEL_CTL_SRV
g_elem_state[0].state.temp[VALUE_TYPE_TAR] = 0xFFFE;
g_indication_flag |= INDICATION_FLAG_CTL;
#endif
ESP_LOGI(TAG, "light_driver_breath_stop %s", __FUNCTION__);
light_driver_breath_stop();
// update led status
genie_event(GENIE_EVT_SDK_ANALYZE_MSG, &g_elem_state[0]);
break;
#ifdef CONFIG_MESH_MODEL_TRANS
case GENIE_EVT_SDK_TRANS_CYCLE:
#endif
case GENIE_EVT_SDK_ACTION_DONE: {
ESP_LOGI(TAG, "GENIE_EVT_SDK_ACTION_DONE");
elem_state_t *p_elem = (elem_state_t *)p_arg;
#ifdef CONFIG_MESH_MODEL_HSL_SRV
ESP_LOGI(TAG, "hue: %d, saturation: %d, lightness: %d", p_elem->state.hue[VALUE_TYPE_CUR], p_elem->state.saturation[VALUE_TYPE_CUR], p_elem->state.lightness[VALUE_TYPE_CUR]);
board_led_hsl(p_elem->elem_index, p_elem->state.hue[VALUE_TYPE_CUR], p_elem->state.saturation[VALUE_TYPE_CUR], p_elem->state.lightness[VALUE_TYPE_CUR]);
#endif
#ifdef CONFIG_MESH_MODEL_CTL_SRV
ESP_LOGI(TAG, "temperature: %d", p_elem->state.temp[VALUE_TYPE_CUR]);
board_led_temperature(p_elem->elem_index, p_elem->state.temp[VALUE_TYPE_CUR]);
#endif
#ifdef CONFIG_MESH_MODEL_LIGHTNESS_SRV
ESP_LOGI(TAG, "lightness actual: %d", p_elem->state.actual[VALUE_TYPE_CUR]);
board_led_lightness(p_elem->elem_index, p_elem->state.actual[VALUE_TYPE_CUR]);
#endif
#ifdef CONFIG_MESH_MODEL_GEN_ONOFF_SRV
ESP_LOGI(TAG, "onoff: %d", p_elem->state.onoff[VALUE_TYPE_CUR]);
board_led_switch(p_elem->elem_index, p_elem->state.onoff[VALUE_TYPE_CUR]);
#endif
if (event == GENIE_EVT_SDK_ACTION_DONE) {
save_light_state(p_elem);
}
break;
}
case GENIE_EVT_HW_RESET_DONE:
ESP_LOGI(TAG, "GENIE_EVT_HW_RESET_DONE");
ble_mesh_nvs_erase(NVS_HANDLE, LIGHT_STATUS_STORE_KEY); // erase led status
// esp_restart();
break;
case GENIE_EVT_APP_FAC_QUIT:
ESP_LOGI(TAG, "GENIE_EVT_APP_FAC_QUIT");
break;
case GENIE_EVT_BUTTON_TAP:
ESP_LOGI(TAG, "GENIE_EVT_BUTTON_TAP");
g_elem_state[0].state.onoff[VALUE_TYPE_TAR] = !g_elem_state[0].state.onoff[VALUE_TYPE_TAR];
#ifdef CONFIG_MESH_MODEL_VENDOR_SRV
g_indication_flag |= INDICATION_FLAG_ONOFF;
#endif
// update led status
next_event = GENIE_EVT_SDK_ANALYZE_MSG;
p_arg = &g_elem_state[0];
break;
case GENIE_EVT_SDK_COLOR_ACTION: {
ESP_LOGI(TAG, "GENIE_EVT_SDK_COLOR_ACTION");
#ifdef CONFIG_MESH_MODEL_HSL_SRV
uint8_t *p_data = p_arg;
uint16_t lightness = *p_data++;
lightness += (*p_data++ << 8);
uint16_t hue = *p_data++;
hue += (*p_data++ << 8);
uint16_t saturation = *p_data++;
saturation += (*p_data++ << 8);
light_color_set(lightness, hue, saturation);
#endif
break;
}
default:
ESP_LOGD(TAG, "unhandle this event: %2d", event);
break;
}
if (next_event != event) {
// send event to genie event loop
genie_event(next_event, p_arg);
}
}
esp_err_t local_operation(uint16_t app_idx)
{
ESP_LOGD(TAG, "app_idx: %d, primary element address: %d", app_idx, esp_ble_mesh_get_primary_element_address());
ESP_ERROR_CHECK(esp_ble_mesh_model_subscribe_group_addr(esp_ble_mesh_get_primary_element_address(), BLE_MESH_CID_NVAL, ESP_BLE_MESH_MODEL_ID_HEALTH_SRV, GENIE_LIGHT_GROUP_ADDR));
ESP_ERROR_CHECK(esp_ble_mesh_model_subscribe_group_addr(esp_ble_mesh_get_primary_element_address(), BLE_MESH_CID_NVAL, ESP_BLE_MESH_MODEL_ID_HEALTH_SRV, GENIE_ALL_GROUP_ADDR));
ESP_ERROR_CHECK(esp_ble_mesh_node_bind_app_key_to_local_model(esp_ble_mesh_get_primary_element_address(), BLE_MESH_CID_NVAL, ESP_BLE_MESH_MODEL_ID_HEALTH_SRV, app_idx));
#ifdef CONFIG_MESH_MODEL_GEN_ONOFF_SRV
ESP_ERROR_CHECK(esp_ble_mesh_model_subscribe_group_addr(esp_ble_mesh_get_primary_element_address(), BLE_MESH_CID_NVAL, ESP_BLE_MESH_MODEL_ID_GEN_ONOFF_SRV, GENIE_LIGHT_GROUP_ADDR));
ESP_ERROR_CHECK(esp_ble_mesh_model_subscribe_group_addr(esp_ble_mesh_get_primary_element_address(), BLE_MESH_CID_NVAL, ESP_BLE_MESH_MODEL_ID_GEN_ONOFF_SRV, GENIE_ALL_GROUP_ADDR));
ESP_ERROR_CHECK(esp_ble_mesh_node_bind_app_key_to_local_model(esp_ble_mesh_get_primary_element_address(), BLE_MESH_CID_NVAL, ESP_BLE_MESH_MODEL_ID_GEN_ONOFF_SRV, app_idx));
ESP_ERROR_CHECK(esp_ble_mesh_model_subscribe_group_addr(esp_ble_mesh_get_primary_element_address() + 1, BLE_MESH_CID_NVAL, ESP_BLE_MESH_MODEL_ID_GEN_ONOFF_SRV, GENIE_LIGHT_GROUP_ADDR));
ESP_ERROR_CHECK(esp_ble_mesh_model_subscribe_group_addr(esp_ble_mesh_get_primary_element_address() + 1, BLE_MESH_CID_NVAL, ESP_BLE_MESH_MODEL_ID_GEN_ONOFF_SRV, GENIE_ALL_GROUP_ADDR));
ESP_ERROR_CHECK(esp_ble_mesh_node_bind_app_key_to_local_model(esp_ble_mesh_get_primary_element_address() + 1, BLE_MESH_CID_NVAL, ESP_BLE_MESH_MODEL_ID_GEN_ONOFF_SRV, app_idx));
ESP_ERROR_CHECK(esp_ble_mesh_model_subscribe_group_addr(esp_ble_mesh_get_primary_element_address() + 2, BLE_MESH_CID_NVAL, ESP_BLE_MESH_MODEL_ID_GEN_ONOFF_SRV, GENIE_LIGHT_GROUP_ADDR));
ESP_ERROR_CHECK(esp_ble_mesh_model_subscribe_group_addr(esp_ble_mesh_get_primary_element_address() + 2, BLE_MESH_CID_NVAL, ESP_BLE_MESH_MODEL_ID_GEN_ONOFF_SRV, GENIE_ALL_GROUP_ADDR));
ESP_ERROR_CHECK(esp_ble_mesh_node_bind_app_key_to_local_model(esp_ble_mesh_get_primary_element_address() + 2, BLE_MESH_CID_NVAL, ESP_BLE_MESH_MODEL_ID_GEN_ONOFF_SRV, app_idx));
#endif
#ifdef CONFIG_MESH_MODEL_LIGHTNESS_SRV
ESP_ERROR_CHECK(esp_ble_mesh_model_subscribe_group_addr(esp_ble_mesh_get_primary_element_address(), BLE_MESH_CID_NVAL, ESP_BLE_MESH_MODEL_ID_LIGHT_LIGHTNESS_SRV, GENIE_LIGHT_GROUP_ADDR));
ESP_ERROR_CHECK(esp_ble_mesh_model_subscribe_group_addr(esp_ble_mesh_get_primary_element_address(), BLE_MESH_CID_NVAL, ESP_BLE_MESH_MODEL_ID_LIGHT_LIGHTNESS_SRV, GENIE_ALL_GROUP_ADDR));
ESP_ERROR_CHECK(esp_ble_mesh_node_bind_app_key_to_local_model(esp_ble_mesh_get_primary_element_address(), BLE_MESH_CID_NVAL, ESP_BLE_MESH_MODEL_ID_LIGHT_LIGHTNESS_SRV, app_idx));
ESP_ERROR_CHECK(esp_ble_mesh_model_subscribe_group_addr(esp_ble_mesh_get_primary_element_address(), BLE_MESH_CID_NVAL, ESP_BLE_MESH_MODEL_ID_LIGHT_LIGHTNESS_SETUP_SRV, GENIE_LIGHT_GROUP_ADDR));
ESP_ERROR_CHECK(esp_ble_mesh_model_subscribe_group_addr(esp_ble_mesh_get_primary_element_address(), BLE_MESH_CID_NVAL, ESP_BLE_MESH_MODEL_ID_LIGHT_LIGHTNESS_SETUP_SRV, GENIE_ALL_GROUP_ADDR));
ESP_ERROR_CHECK(esp_ble_mesh_node_bind_app_key_to_local_model(esp_ble_mesh_get_primary_element_address(), BLE_MESH_CID_NVAL, ESP_BLE_MESH_MODEL_ID_LIGHT_LIGHTNESS_SETUP_SRV, app_idx));
#endif
#ifdef CONFIG_MESH_MODEL_CTL_SRV
ESP_ERROR_CHECK(esp_ble_mesh_model_subscribe_group_addr(esp_ble_mesh_get_primary_element_address(), BLE_MESH_CID_NVAL, ESP_BLE_MESH_MODEL_ID_LIGHT_CTL_SRV, GENIE_LIGHT_GROUP_ADDR));
ESP_ERROR_CHECK(esp_ble_mesh_model_subscribe_group_addr(esp_ble_mesh_get_primary_element_address(), BLE_MESH_CID_NVAL, ESP_BLE_MESH_MODEL_ID_LIGHT_CTL_SRV, GENIE_ALL_GROUP_ADDR));
ESP_ERROR_CHECK(esp_ble_mesh_node_bind_app_key_to_local_model(esp_ble_mesh_get_primary_element_address(), BLE_MESH_CID_NVAL, ESP_BLE_MESH_MODEL_ID_LIGHT_CTL_SRV, app_idx));
ESP_ERROR_CHECK(esp_ble_mesh_model_subscribe_group_addr(esp_ble_mesh_get_primary_element_address(), BLE_MESH_CID_NVAL, ESP_BLE_MESH_MODEL_ID_LIGHT_CTL_SETUP_SRV, GENIE_LIGHT_GROUP_ADDR));
ESP_ERROR_CHECK(esp_ble_mesh_model_subscribe_group_addr(esp_ble_mesh_get_primary_element_address(), BLE_MESH_CID_NVAL, ESP_BLE_MESH_MODEL_ID_LIGHT_CTL_SETUP_SRV, GENIE_ALL_GROUP_ADDR));
ESP_ERROR_CHECK(esp_ble_mesh_node_bind_app_key_to_local_model(esp_ble_mesh_get_primary_element_address(), BLE_MESH_CID_NVAL, ESP_BLE_MESH_MODEL_ID_LIGHT_CTL_SETUP_SRV, app_idx));
#endif
#ifdef CONFIG_MESH_MODEL_HSL_SRV
ESP_ERROR_CHECK(esp_ble_mesh_model_subscribe_group_addr(esp_ble_mesh_get_primary_element_address(), BLE_MESH_CID_NVAL, ESP_BLE_MESH_MODEL_ID_LIGHT_HSL_SRV, GENIE_LIGHT_GROUP_ADDR));
ESP_ERROR_CHECK(esp_ble_mesh_model_subscribe_group_addr(esp_ble_mesh_get_primary_element_address(), BLE_MESH_CID_NVAL, ESP_BLE_MESH_MODEL_ID_LIGHT_HSL_SRV, GENIE_ALL_GROUP_ADDR));
ESP_ERROR_CHECK(esp_ble_mesh_node_bind_app_key_to_local_model(esp_ble_mesh_get_primary_element_address(), BLE_MESH_CID_NVAL, ESP_BLE_MESH_MODEL_ID_LIGHT_HSL_SRV, app_idx));
ESP_ERROR_CHECK(esp_ble_mesh_model_subscribe_group_addr(esp_ble_mesh_get_primary_element_address(), BLE_MESH_CID_NVAL, ESP_BLE_MESH_MODEL_ID_LIGHT_HSL_SETUP_SRV, GENIE_LIGHT_GROUP_ADDR));
ESP_ERROR_CHECK(esp_ble_mesh_model_subscribe_group_addr(esp_ble_mesh_get_primary_element_address(), BLE_MESH_CID_NVAL, ESP_BLE_MESH_MODEL_ID_LIGHT_HSL_SETUP_SRV, GENIE_ALL_GROUP_ADDR));
ESP_ERROR_CHECK(esp_ble_mesh_node_bind_app_key_to_local_model(esp_ble_mesh_get_primary_element_address(), BLE_MESH_CID_NVAL, ESP_BLE_MESH_MODEL_ID_LIGHT_HSL_SETUP_SRV, app_idx));
#endif
ESP_ERROR_CHECK(esp_ble_mesh_model_subscribe_group_addr(esp_ble_mesh_get_primary_element_address(), CID_ALIBABA, GENIE_VENDOR_MODEL_SRV_ID, GENIE_LIGHT_GROUP_ADDR));
ESP_ERROR_CHECK(esp_ble_mesh_model_subscribe_group_addr(esp_ble_mesh_get_primary_element_address(), CID_ALIBABA, GENIE_VENDOR_MODEL_SRV_ID, GENIE_ALL_GROUP_ADDR));
ESP_ERROR_CHECK(esp_ble_mesh_node_bind_app_key_to_local_model(esp_ble_mesh_get_primary_element_address(), CID_ALIBABA, GENIE_VENDOR_MODEL_SRV_ID, app_idx));
return ESP_OK;
}
#ifdef CONFIG_MESH_MODEL_HSL_SRV
void bind_onoff_with_hsl(elem_state_t *p_elem, value_type_t type)
{
ENTER_FUNC();
model_state_t *p_state = &p_elem->state;
ESP_LOGI(TAG, "hsl tar(%d, %d, %d)", p_state->hue[VALUE_TYPE_TAR], p_state->saturation[VALUE_TYPE_TAR], p_state->lightness[VALUE_TYPE_TAR]);
if (type == VALUE_TYPE_TAR) {
if (p_state->onoff[VALUE_TYPE_TAR] == 0) {
//turn on
p_state->onoff[VALUE_TYPE_TAR] = 1;
#ifdef CONFIG_MESH_MODEL_VENDOR_SRV
g_indication_flag |= INDICATION_FLAG_ONOFF;
#endif
}
} else if (type == VALUE_TYPE_CUR) {
}
}
#endif
#ifdef CONFIG_MESH_MODEL_CTL_SRV
void bind_onoff_with_ctl(elem_state_t *p_elem, value_type_t type)
{
ENTER_FUNC();
model_state_t *p_state = &p_elem->state;
// ESP_LOGI(TAG, "temperature cur(%d) tar(%d)", p_state->temp[VALUE_TYPE_CUR], p_state->temp[VALUE_TYPE_TAR]);
if (type == VALUE_TYPE_TAR) {
if (p_state->onoff[VALUE_TYPE_TAR] == 0) {
//turn on
p_state->onoff[VALUE_TYPE_TAR] = 1;
#ifdef CONFIG_MESH_MODEL_VENDOR_SRV
g_indication_flag |= INDICATION_FLAG_ONOFF;
#endif
}
} else if (type == VALUE_TYPE_CUR) {
}
}
#endif
#ifdef CONFIG_MESH_MODEL_LIGHTNESS_SRV
void bind_onoff_with_lightness(elem_state_t *p_elem, value_type_t type)
{
ENTER_FUNC();
model_state_t *p_state = &p_elem->state;
ESP_LOGI(TAG, "lightness cur(%d) tar(%d)", p_state->actual[VALUE_TYPE_CUR], p_state->actual[VALUE_TYPE_TAR]);
if (type == VALUE_TYPE_TAR) {
if (p_state->actual[VALUE_TYPE_CUR] == 0 && p_state->actual[VALUE_TYPE_TAR] != 0) {
//turn on
p_state->onoff[VALUE_TYPE_TAR] = 1;
#ifdef CONFIG_MESH_MODEL_VENDOR_SRV
g_indication_flag |= INDICATION_FLAG_ONOFF;
#endif
} else if (p_state->actual[VALUE_TYPE_CUR] != 1 && p_state->actual[VALUE_TYPE_TAR] == 0) {
//turn off
p_state->onoff[VALUE_TYPE_TAR] = 0;
#ifdef CONFIG_MESH_MODEL_VENDOR_SRV
g_indication_flag |= INDICATION_FLAG_ONOFF;
#endif
}
} else if (type == VALUE_TYPE_CUR) {
if (p_state->actual[VALUE_TYPE_CUR] == 0 && p_state->actual[VALUE_TYPE_TAR] == 0) {
//turn off
p_state->onoff[VALUE_TYPE_CUR] = 0;
#ifdef CONFIG_MESH_MODEL_VENDOR_SRV
g_indication_flag |= INDICATION_FLAG_ONOFF;
#endif
}
}
}
void bind_lightness_with_onoff(elem_state_t *p_elem, value_type_t type)
{
ENTER_FUNC();
model_state_t *p_state = &p_elem->state;
ESP_LOGI(TAG, "onoff cur(%d) tar(%d)", p_state->onoff[VALUE_TYPE_CUR], p_state->onoff[VALUE_TYPE_TAR]);
if (type == VALUE_TYPE_TAR) {
#ifdef CONFIG_MESH_MODEL_GEN_ONOFF_SRV
if (p_state->onoff[VALUE_TYPE_CUR] == 0 && p_state->onoff[VALUE_TYPE_TAR] == 1) {
//turn on, set default lightness
#ifdef CONFIG_MESH_SIMPLE_MODLE
if (p_elem->powerup.last_actual) {
p_state->actual[VALUE_TYPE_TAR] = p_elem->powerup.last_actual;
} else {
p_state->actual[VALUE_TYPE_TAR] = GENIE_LIGHTNESS_DEFAULT;
}
#endif
#ifdef CONFIG_MESH_MODEL_VENDOR_SRV
g_indication_flag |= INDICATION_FLAG_LIGHTNESS;
#endif
} else if (p_state->onoff[VALUE_TYPE_CUR] == 1 && p_state->onoff[VALUE_TYPE_TAR] == 0) {
//turn off, set zero
p_state->actual[VALUE_TYPE_TAR] = 0;
#ifdef CONFIG_MESH_MODEL_VENDOR_SRV
g_indication_flag |= INDICATION_FLAG_LIGHTNESS;
#endif
}
#endif
} else if (type == VALUE_TYPE_CUR) {
}
ESP_LOGI(TAG, "actual cur(%d) tar(%d)", p_state->actual[VALUE_TYPE_CUR], p_state->actual[VALUE_TYPE_TAR]);
}
#endif
#ifdef CONFIG_MESH_MODEL_CTL_SRV
void bind_ctl_with_onoff(elem_state_t *p_elem, value_type_t type)
{
ENTER_FUNC();
model_state_t *p_state = &p_elem->state;
ESP_LOGI(TAG, "onoff cur(%d) tar(%d)", p_state->onoff[VALUE_TYPE_CUR], p_state->onoff[VALUE_TYPE_TAR]);
if (type == VALUE_TYPE_TAR) {
#ifdef CONFIG_MESH_MODEL_GEN_ONOFF_SRV
if (p_state->onoff[VALUE_TYPE_CUR] == 0 && p_state->onoff[VALUE_TYPE_TAR] == 1) {
#ifdef CONFIG_MESH_SIMPLE_MODLE
//turn on, check temperature
ESP_LOGI(TAG, "temp cur(%d) tar(%d)", p_state->temp[VALUE_TYPE_CUR], p_state->temp[VALUE_TYPE_TAR]);
if (p_state->temp[VALUE_TYPE_CUR] != p_state->temp[VALUE_TYPE_TAR]) {
if (p_elem->powerup.last_temp) {
p_state->temp[VALUE_TYPE_TAR] = p_elem->powerup.last_temp;
} else {
p_state->temp[VALUE_TYPE_TAR] = GENIE_CTL_TEMP_DEFAULT;
}
#ifdef CONFIG_MESH_MODEL_VENDOR_SRV
g_indication_flag |= INDICATION_FLAG_CTL;
#endif
}
#endif
}
#endif
} else if (type == VALUE_TYPE_CUR) {
}
ESP_LOGI(TAG, "temp cur(%04x) tar(%04x)", p_state->temp[VALUE_TYPE_CUR], p_state->temp[VALUE_TYPE_TAR]);
}
#endif
#ifdef CONFIG_MESH_MODEL_HSL_SRV
static void light_color_set(uint16_t lightness, uint16_t hue, uint16_t saturation)
{
ENTER_FUNC();
ESP_LOGI(TAG, "hue: %d, saturation: %d, lightness: %d", hue, saturation, lightness);
g_elem_state[0].state.hue[VALUE_TYPE_TAR] = hue;
g_elem_state[0].state.saturation[VALUE_TYPE_TAR] = saturation;
g_elem_state[0].state.lightness[VALUE_TYPE_TAR] = lightness;
if (g_elem_state[0].state.hue[VALUE_TYPE_CUR] != g_elem_state[0].state.hue[VALUE_TYPE_TAR] || g_elem_state[0].state.saturation[VALUE_TYPE_CUR] != g_elem_state[0].state.saturation[VALUE_TYPE_TAR]
|| g_elem_state[0].state.lightness[VALUE_TYPE_CUR] != g_elem_state[0].state.lightness[VALUE_TYPE_TAR]) {
g_indication_flag |= INDICATION_FLAG_HSL;
/* Change corresponding binded states in root element */
bind_onoff_with_hsl(&g_elem_state[0], VALUE_TYPE_TAR);
if (esp_ble_mesh_node_is_provisioned()) {
// update led status
genie_event(GENIE_EVT_SDK_ANALYZE_MSG, &g_elem_state[0]);
}
}
}
#endif
#ifdef CONFIG_MESH_MODEL_CTL_SRV
static void light_ctl_set(uint32_t opcode, esp_ble_mesh_model_t *model,
esp_ble_mesh_msg_ctx_t *ctx,
uint16_t lightness, uint16_t temperature, uint16_t delta_uv)
{
ENTER_FUNC();
ESP_LOGI(TAG, "lightness 0x%d", lightness);
if (opcode == ESP_BLE_MESH_MODEL_OP_LIGHT_CTL_SET) {
esp_ble_mesh_server_model_send_msg(model, ctx, ESP_BLE_MESH_MODEL_OP_LIGHT_CTL_STATUS,
sizeof(lightness), (uint8_t *)&lightness);
}
g_elem_state[0].state.actual[VALUE_TYPE_TAR] = lightness;
g_elem_state[0].state.temp[VALUE_TYPE_TAR] = temperature;
if (g_elem_state[0].state.actual[VALUE_TYPE_CUR] != g_elem_state[0].state.actual[VALUE_TYPE_TAR] || g_elem_state[0].state.temp[VALUE_TYPE_CUR] != g_elem_state[0].state.temp[VALUE_TYPE_TAR]) {
g_indication_flag |= INDICATION_FLAG_LIGHTNESS;
g_indication_flag |= INDICATION_FLAG_CTL;
esp_ble_mesh_server_model_send_msg(model, ctx, ESP_BLE_MESH_MODEL_OP_LIGHT_CTL_STATUS,
sizeof(g_elem_state[0].state.temp[VALUE_TYPE_CUR]), (uint8_t *)&g_elem_state[0].state.temp[VALUE_TYPE_CUR]);
/* Change corresponding binded states in root element */
bind_onoff_with_ctl(&g_elem_state[0], VALUE_TYPE_TAR);
if (esp_ble_mesh_node_is_provisioned()) {
// update led status
genie_event(GENIE_EVT_SDK_ANALYZE_MSG, &g_elem_state[0]);
}
}
}
#endif
#ifdef CONFIG_MESH_MODEL_LIGHTNESS_SRV
static void light_lightness_actual_set(uint32_t opcode, esp_ble_mesh_model_t *model,
esp_ble_mesh_msg_ctx_t *ctx,
uint16_t lightness)
{
ENTER_FUNC();
ESP_LOGI(TAG, "lightness %d", lightness);
if (opcode == ESP_BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_SET) {
esp_ble_mesh_server_model_send_msg(model, ctx, ESP_BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_STATUS,
sizeof(lightness), (uint8_t *)&lightness);
}
g_elem_state[0].state.actual[VALUE_TYPE_TAR] = lightness;
if (g_elem_state[0].state.actual[VALUE_TYPE_CUR] != g_elem_state[0].state.actual[VALUE_TYPE_TAR]) {
g_indication_flag |= INDICATION_FLAG_LIGHTNESS;
esp_ble_mesh_server_model_send_msg(model, ctx, ESP_BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_STATUS,
sizeof(g_elem_state[0].state.actual[VALUE_TYPE_CUR]), (uint8_t *)&g_elem_state[0].state.actual[VALUE_TYPE_CUR]);
/* Change corresponding binded states in root element */
bind_onoff_with_lightness(&g_elem_state[0], VALUE_TYPE_TAR);
if (esp_ble_mesh_node_is_provisioned()) {
// update led status
genie_event(GENIE_EVT_SDK_ANALYZE_MSG, &g_elem_state[0]);
}
}
}
static void light_lightness_linear_set(uint32_t opcode, esp_ble_mesh_model_t *model,
esp_ble_mesh_msg_ctx_t *ctx,
uint16_t lightness)
{
ENTER_FUNC();
ESP_LOGI(TAG, "lightness 0x%d", lightness);
if (opcode == ESP_BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_LINEAR_SET) {
esp_ble_mesh_server_model_send_msg(model, ctx, ESP_BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_LINEAR_STATUS,
sizeof(lightness), (uint8_t *)&lightness);
}
g_elem_state[0].state.linear[VALUE_TYPE_TAR] = lightness;
if (g_elem_state[0].state.linear[VALUE_TYPE_CUR] != g_elem_state[0].state.linear[VALUE_TYPE_TAR]) {
g_indication_flag |= INDICATION_FLAG_LIGHTNESS;
esp_ble_mesh_server_model_send_msg(model, ctx, ESP_BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_LINEAR_STATUS,
sizeof(g_elem_state[0].state.linear[VALUE_TYPE_CUR]), (uint8_t *)&g_elem_state[0].state.linear[VALUE_TYPE_CUR]);
/* Change corresponding binded states in root element */
bind_onoff_with_lightness(&g_elem_state[0], VALUE_TYPE_TAR);
if (esp_ble_mesh_node_is_provisioned()) {
// update led status
genie_event(GENIE_EVT_SDK_ANALYZE_MSG, &g_elem_state[0]);
}
}
}
#endif
static void light_onoff_set(esp_ble_mesh_model_t *model,
esp_ble_mesh_msg_ctx_t *ctx, uint8_t onoff)
{
ENTER_FUNC();
uint16_t primary_addr = esp_ble_mesh_get_primary_element_address();
uint8_t elem_count = esp_ble_mesh_get_element_count();
elem_state_t *led_state = NULL;
g_elem_state[0].state.onoff[VALUE_TYPE_TAR] = onoff;
if (g_elem_state[0].state.onoff[VALUE_TYPE_CUR] != g_elem_state[0].state.onoff[VALUE_TYPE_TAR]) {
g_indication_flag |= INDICATION_FLAG_ONOFF;
// g_elem_state[0].state.onoff[VALUE_TYPE_CUR] = g_elem_state[0].state.onoff[VALUE_TYPE_TAR];
if (ESP_BLE_MESH_ADDR_IS_UNICAST(ctx->recv_dst)) {
for (uint8_t i = 0; i < elem_count; i++) {
if (ctx->recv_dst == (primary_addr + i)) {
led_state = &g_elem_state[i];
}
}
} else if (ESP_BLE_MESH_ADDR_IS_GROUP(ctx->recv_dst)) {
if (esp_ble_mesh_is_model_subscribed_to_group(model, ctx->recv_dst)) {
led_state = &g_elem_state[model->element->element_addr - primary_addr];
}
} else if (ctx->recv_dst == 0xFFFF) {
led_state = &g_elem_state[model->element->element_addr - primary_addr];
}
if (led_state != NULL) {
ESP_LOGI(TAG, "led onoff 0x%d", g_elem_state[0].state.onoff[VALUE_TYPE_TAR]);
#ifdef CONFIG_MESH_MODEL_LIGHTNESS_SRV
// update lightness
bind_lightness_with_onoff(&g_elem_state[0], VALUE_TYPE_TAR);
#endif
#ifdef CONFIG_MESH_MODEL_CTL_SRV
// update ctl
bind_ctl_with_onoff(&g_elem_state[0], VALUE_TYPE_TAR);
#endif
// update led status
genie_event(GENIE_EVT_SDK_ANALYZE_MSG, &g_elem_state[0]);
}
}
}
static void prov_complete(uint16_t net_idx, uint16_t addr, uint8_t flags, uint32_t iv_index)
{
ENTER_FUNC();
ESP_LOGI(TAG, "net_idx: 0x%04x, addr: 0x%04x", net_idx, addr);
ESP_LOGI(TAG, "flags: 0x%02x, iv_index: 0x%08x", flags, iv_index);
}
static void example_ble_mesh_provisioning_cb(esp_ble_mesh_prov_cb_event_t event,
esp_ble_mesh_prov_cb_param_t *param)
{
switch (event) {
case ESP_BLE_MESH_PROV_REGISTER_COMP_EVT:
ESP_LOGI(TAG, "ESP_BLE_MESH_PROV_REGISTER_COMP_EVT, err_code %d", param->prov_register_comp.err_code);
break;
case ESP_BLE_MESH_NODE_PROV_ENABLE_COMP_EVT:
ESP_LOGI(TAG, "ESP_BLE_MESH_NODE_PROV_ENABLE_COMP_EVT, err_code %d", param->node_prov_enable_comp.err_code);
// send event to genie event loop
genie_event(GENIE_EVT_SDK_MESH_INIT, &param->node_prov_enable_comp.err_code);
if (param->node_prov_enable_comp.err_code == -EALREADY) {
// genie mesh init
genie_mesh_init();
}
break;
case ESP_BLE_MESH_NODE_PROV_DISABLE_COMP_EVT:
ESP_LOGI(TAG, "ESP_BLE_MESH_NODE_PROV_DISABLE_COMP_EVT");
break;
case ESP_BLE_MESH_NODE_PROV_LINK_OPEN_EVT:
ESP_LOGI(TAG, "ESP_BLE_MESH_NODE_PROV_LINK_OPEN_EVT, bearer %s",
param->node_prov_link_open.bearer == ESP_BLE_MESH_PROV_ADV ? "PB-ADV" : "PB-GATT");
// send event to genie event loop
genie_event(GENIE_EVT_SDK_MESH_PROV_START, NULL);
break;
case ESP_BLE_MESH_NODE_PROV_LINK_CLOSE_EVT:
ESP_LOGI(TAG, "ESP_BLE_MESH_NODE_PROV_LINK_CLOSE_EVT, bearer %s",
param->node_prov_link_close.bearer == ESP_BLE_MESH_PROV_ADV ? "PB-ADV" : "PB-GATT");
break;
case ESP_BLE_MESH_NODE_PROV_COMPLETE_EVT: // already have configuration when device restart, and provisioning completed.
ESP_LOGI(TAG, "ESP_BLE_MESH_NODE_PROV_COMPLETE_EVT");
ESP_LOG_BUFFER_HEX("NetKey: ", param->node_prov_complete.net_key, 16);
ESP_LOGI(TAG, "net_idx 0x%04x, NetKey: %s, Primary address: 0x%04x", param->node_prov_complete.net_idx,
util_hex2str(param->node_prov_complete.net_key, 16), param->node_prov_complete.addr);
prov_complete(param->node_prov_complete.net_idx, param->node_prov_complete.addr,
param->node_prov_complete.flags, param->node_prov_complete.iv_index);
user_prov_complete(param->node_prov_complete.net_idx, param->node_prov_complete.addr);
break;
case ESP_BLE_MESH_NODE_PROV_RESET_EVT:
ESP_LOGI(TAG, "ESP_BLE_MESH_NODE_PROV_RESET_EVT");
// send event to genie event loop
genie_event(GENIE_EVT_SW_RESET, NULL);
user_prov_reset();
break;
case ESP_BLE_MESH_NODE_SET_UNPROV_DEV_NAME_COMP_EVT:
ESP_LOGI(TAG, "ESP_BLE_MESH_NODE_SET_UNPROV_DEV_NAME_COMP_EVT, err_code %d", param->node_set_unprov_dev_name_comp.err_code);
break;
case ESP_BLE_MESH_PROVISIONER_STORE_NODE_COMP_DATA_COMP_EVT:
ESP_LOGI(TAG, "ESP_BLE_MESH_PROVISIONER_STORE_NODE_COMP_DATA_COMP_EVT, err_code %d", param->provisioner_store_node_comp_data_comp.err_code);
break;
case ESP_BLE_MESH_MODEL_SUBSCRIBE_GROUP_ADDR_COMP_EVT:
ESP_LOGI(TAG, "ESP_BLE_MESH_MODEL_SUBSCRIBE_GROUP_ADDR_COMP_EVT, err_code %d, element_addr 0x%04x, company_id 0x%04x, model_id 0x%04x, group_addr 0x%04x",
param->model_sub_group_addr_comp.err_code, param->model_sub_group_addr_comp.element_addr,
param->model_sub_group_addr_comp.company_id, param->model_sub_group_addr_comp.model_id,
param->model_sub_group_addr_comp.group_addr);
break;
case ESP_BLE_MESH_NODE_BIND_APP_KEY_TO_MODEL_COMP_EVT:
ESP_LOGI(TAG, "ESP_BLE_MESH_NODE_BIND_APP_KEY_TO_MODEL_COMP_EVT, err_code %d, element_addr 0x%04x, company_id 0x%04x, model_id 0x%04x, app_idx 0x%04x",
param->node_bind_app_key_to_model_comp.err_code, param->node_bind_app_key_to_model_comp.element_addr,
param->node_bind_app_key_to_model_comp.company_id, param->node_bind_app_key_to_model_comp.model_id,
param->node_bind_app_key_to_model_comp.app_idx);
break;
default:
ESP_LOGI(TAG, "event %d", event);
break;
}
}
static void example_ble_mesh_config_server_cb(esp_ble_mesh_cfg_server_cb_event_t event,
esp_ble_mesh_cfg_server_cb_param_t *param)
{
if (event == ESP_BLE_MESH_CFG_SERVER_STATE_CHANGE_EVT) {
switch (param->ctx.recv_op) {
case ESP_BLE_MESH_MODEL_OP_NET_KEY_ADD:
ESP_LOGI(TAG, "ESP_BLE_MESH_MODEL_OP_NET_KEY_ADD");
ESP_LOGI(TAG, "net_idx 0x%04x, NetKey: %s",
param->value.state_change.netkey_add.net_idx,
util_hex2str(param->value.state_change.netkey_add.net_key, 16));
break;
case ESP_BLE_MESH_MODEL_OP_NET_KEY_UPDATE:
ESP_LOGI(TAG, "ESP_BLE_MESH_MODEL_OP_NET_KEY_UPDATE");
break;
case ESP_BLE_MESH_MODEL_OP_NET_KEY_DELETE:
ESP_LOGI(TAG, "ESP_BLE_MESH_MODEL_OP_NET_KEY_DELETE");
break;
case ESP_BLE_MESH_MODEL_OP_APP_KEY_ADD:
ESP_LOGI(TAG, "ESP_BLE_MESH_MODEL_OP_APP_KEY_ADD");
ESP_LOGI(TAG, "net_idx 0x%04x, app_idx 0x%04x, AppKey: %s",
param->value.state_change.appkey_add.net_idx, param->value.state_change.appkey_add.app_idx,
util_hex2str(param->value.state_change.appkey_add.app_key, 16));
// send event to genie event loop
genie_event(GENIE_EVT_SDK_APPKEY_ADD, &param->value.state_change.appkey_add.app_idx);
#if GENIE_VENDOR_MODEL_VERSION == 0
#elif GENIE_VENDOR_MODEL_VERSION == 1
// local bind AppKEY and Subcribe Group Address
local_operation(param->value.state_change.appkey_add.app_idx);
// genie mesh init
genie_mesh_init();
#endif
break;
case ESP_BLE_MESH_MODEL_OP_APP_KEY_UPDATE:
ESP_LOGI(TAG, "ESP_BLE_MESH_MODEL_OP_APP_KEY_UPDATE");
break;
case ESP_BLE_MESH_MODEL_OP_APP_KEY_DELETE:
ESP_LOGI(TAG, "ESP_BLE_MESH_MODEL_OP_APP_KEY_DELETE");
break;
case ESP_BLE_MESH_MODEL_OP_MODEL_APP_BIND:
ESP_LOGI(TAG, "ESP_BLE_MESH_MODEL_OP_MODEL_APP_BIND");
ESP_LOGI(TAG, "elem_addr 0x%04x, app_idx 0x%04x, cid 0x%04x, mod_id 0x%04x",
param->value.state_change.mod_app_bind.element_addr,
param->value.state_change.mod_app_bind.app_idx,
param->value.state_change.mod_app_bind.company_id,
param->value.state_change.mod_app_bind.model_id);
break;
case ESP_BLE_MESH_MODEL_OP_MODEL_SUB_ADD:
ESP_LOGI(TAG, "ESP_BLE_MESH_MODEL_OP_MODEL_SUB_ADD");
ESP_LOGI(TAG, "elem_addr 0x%04x, sub_addr 0x%04x, cid 0x%04x, mod_id 0x%04x",
param->value.state_change.mod_sub_add.element_addr,
param->value.state_change.mod_sub_add.sub_addr,
param->value.state_change.mod_sub_add.company_id,
param->value.state_change.mod_sub_add.model_id);
#if GENIE_VENDOR_MODEL_VERSION == 0
// genie mesh init
genie_mesh_init();
#elif GENIE_VENDOR_MODEL_VERSION == 1
#endif
break;
case ESP_BLE_MESH_MODEL_OP_MODEL_SUB_DELETE:
ESP_LOGI(TAG, "ESP_BLE_MESH_MODEL_OP_MODEL_SUB_DELETE");
break;
case ESP_BLE_MESH_MODEL_OP_HEARTBEAT_PUB_SET:
ESP_LOGI(TAG, "ESP_BLE_MESH_MODEL_OP_HEARTBEAT_PUB_SET");
break;
case ESP_BLE_MESH_MODEL_OP_HEARTBEAT_SUB_SET:
ESP_LOGI(TAG, "ESP_BLE_MESH_MODEL_OP_HEARTBEAT_SUB_SET");
break;
default:
ESP_LOGW(TAG, "%s, event %d", __FUNCTION__, event);
break;
}
}
}
static void example_ble_mesh_generic_server_cb(esp_ble_mesh_generic_server_cb_event_t event,
esp_ble_mesh_generic_server_cb_param_t *param)
{
ESP_LOGD(TAG, "event 0x%02x, opcode 0x%04x, src 0x%04x, dst 0x%04x",
event, param->ctx.recv_op, param->ctx.addr, param->ctx.recv_dst);
switch (event) {
case ESP_BLE_MESH_GENERIC_SERVER_STATE_CHANGE_EVT:
ESP_LOGI(TAG, "ESP_BLE_MESH_GENERIC_SERVER_STATE_CHANGE_EVT");
if (param->ctx.recv_op == ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_SET ||
param->ctx.recv_op == ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_SET_UNACK) {
light_onoff_set(param->model, &param->ctx, param->value.state_change.onoff_set.onoff);
/* Update bound states second way */
// light_lightness_actual_set(param->ctx.recv_op, param->model,
// &param->ctx, param->value.state_change.onoff_set.onoff);
}
break;
case ESP_BLE_MESH_GENERIC_SERVER_RECV_GET_MSG_EVT:
ESP_LOGI(TAG, "ESP_BLE_MESH_GENERIC_SERVER_RECV_GET_MSG_EVT");
if (param->ctx.recv_op == ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_GET) {
esp_ble_mesh_gen_onoff_srv_t *srv = param->model->user_data;
ESP_LOGI(TAG, "onoff: 0x%02x", srv->state.onoff);
esp_ble_mesh_server_model_send_msg(param->model, &param->ctx,
ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_STATUS, sizeof(srv->state.onoff), &srv->state.onoff);
}
break;
case ESP_BLE_MESH_GENERIC_SERVER_RECV_SET_MSG_EVT:
ESP_LOGI(TAG, "ESP_BLE_MESH_GENERIC_SERVER_RECV_SET_MSG_EVT");
if (param->ctx.recv_op == ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_SET ||
param->ctx.recv_op == ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_SET_UNACK) {
ESP_LOGI(TAG, "onoff 0x%02x, tid 0x%02x", param->value.set.onoff.onoff, param->value.set.onoff.tid);
if (param->value.set.onoff.op_en) {
ESP_LOGI(TAG, "trans_time 0x%02x, delay 0x%02x",
param->value.set.onoff.trans_time, param->value.set.onoff.delay);
}
esp_ble_mesh_gen_onoff_srv_t *srv = param->model->user_data;
if (param->value.set.onoff.op_en == false) {
srv->state.onoff = param->value.set.onoff.onoff;
} else {
/* TODO: Delay and state transition */
srv->state.onoff = param->value.set.onoff.onoff;
}
g_indication_flag |= INDICATION_FLAG_ONOFF;
if (param->ctx.recv_op == ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_SET) {
esp_ble_mesh_server_model_send_msg(param->model, &param->ctx,
ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_STATUS, sizeof(srv->state.onoff), &srv->state.onoff);
}
light_onoff_set(param->model, &param->ctx, srv->state.onoff);
}
break;
default:
ESP_LOGW(TAG, "Unknown Generic Server event 0x%02x", event);
break;
}
}
static void example_ble_mesh_lighting_server_cb(esp_ble_mesh_lighting_server_cb_event_t event,
esp_ble_mesh_lighting_server_cb_param_t *param)
{
#ifdef CONFIG_MESH_MODEL_LIGHTNESS_SRV
uint16_t lightness;
#endif
#ifdef CONFIG_MESH_MODEL_CTL_SRV
uint16_t temperature;
uint16_t delta_uv;
#endif
esp_ble_mesh_server_state_value_t state = {0};
ESP_LOGD(TAG, "event 0x%02x, opcode 0x%04x, src 0x%04x, dst 0x%04x",
event, param->ctx.recv_op, param->ctx.addr, param->ctx.recv_dst);
switch (event) {
case ESP_BLE_MESH_LIGHTING_SERVER_STATE_CHANGE_EVT:
switch (param->ctx.recv_op) {
#ifdef CONFIG_MESH_MODEL_LIGHTNESS_SRV
/*!< Light Lightness Message Opcode */
case ESP_BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_SET:
case ESP_BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_SET_UNACK: {
/* Light Lightness Server Model - Primary Element */
ESP_LOGI(TAG, "lightness actual %d", param->value.state_change.lightness_set.lightness);
/* Update bound states */
lightness = param->value.state_change.lightness_set.lightness;
state.light_lightness_linear.lightness = convert_lightness_actual_to_linear(lightness);
esp_ble_mesh_server_model_update_state(lightness_server.model, ESP_BLE_MESH_LIGHT_LIGHTNESS_LINEAR_STATE, &state);
state.gen_onoff.onoff = lightness ? LED_ON : LED_OFF;
esp_ble_mesh_server_model_update_state(onoff_server_0.model, ESP_BLE_MESH_GENERIC_ONOFF_STATE, &state);
/* Update bound states second way */
light_lightness_actual_set(param->ctx.recv_op, param->model,
&param->ctx, lightness);
break;
}
case ESP_BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_LINEAR_SET:
case ESP_BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_LINEAR_SET_UNACK: {
/* Light Lightness Server Model - Primary Element */
ESP_LOGI(TAG, "lightness linear %d", param->value.state_change.lightness_linear_set.lightness);
/* Update bound states */
lightness = convert_lightness_linear_to_actual(param->value.state_change.lightness_linear_set.lightness);
state.light_lightness_actual.lightness = lightness;
esp_ble_mesh_server_model_update_state(lightness_server.model, ESP_BLE_MESH_LIGHT_LIGHTNESS_ACTUAL_STATE, &state);
state.gen_onoff.onoff = lightness ? LED_ON : LED_OFF;
esp_ble_mesh_server_model_update_state(onoff_server_0.model, ESP_BLE_MESH_GENERIC_ONOFF_STATE, &state);
/* Update bound states second way */
light_lightness_linear_set(param->ctx.recv_op, param->model,
&param->ctx, lightness);
break;
}
/*!< Light Lightness Setup Message Opcode */
case ESP_BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_DEFAULT_SET:
case ESP_BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_DEFAULT_SET_UNACK:
/* Light Lightness Setup Server Model - Primary Element */
ESP_LOGI(TAG, "lightness default %d", param->value.state_change.lightness_default_set.lightness);
break;
case ESP_BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_RANGE_SET:
case ESP_BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_RANGE_SET_UNACK:
/* Light Lightness Setup Server Model - Primary Element */
ESP_LOGI(TAG, "lightness min %d, max %d",
param->value.state_change.lightness_range_set.range_min,
param->value.state_change.lightness_range_set.range_max);
break;
#endif
#ifdef CONFIG_MESH_MODEL_CTL_SRV
/*!< Light CTL Message Opcode */
case ESP_BLE_MESH_MODEL_OP_LIGHT_CTL_SET:
case ESP_BLE_MESH_MODEL_OP_LIGHT_CTL_SET_UNACK:
/* Light CTL Server Model - Primary Element */
ESP_LOGI(TAG, "lightness 0x%04x, temperature 0x%04x, delta uv 0x%04x",
param->value.state_change.ctl_set.lightness,
param->value.state_change.ctl_set.temperature,
param->value.state_change.ctl_set.delta_uv);
/* Update bound states */
lightness = param->value.state_change.ctl_set.lightness;
temperature = param->value.state_change.ctl_set.temperature;
delta_uv = param->value.state_change.ctl_set.delta_uv;
state.light_lightness_actual.lightness = lightness;
esp_ble_mesh_server_model_update_state(lightness_server.model, ESP_BLE_MESH_LIGHT_LIGHTNESS_ACTUAL_STATE, &state);
state.light_lightness_linear.lightness = convert_lightness_actual_to_linear(lightness);
esp_ble_mesh_server_model_update_state(lightness_server.model, ESP_BLE_MESH_LIGHT_LIGHTNESS_LINEAR_STATE, &state);
state.gen_onoff.onoff = lightness ? LED_ON : LED_OFF;
esp_ble_mesh_server_model_update_state(onoff_server_0.model, ESP_BLE_MESH_GENERIC_ONOFF_STATE, &state);
/* Update bound states second way */
light_ctl_set(param->ctx.recv_op, param->model,
&param->ctx, lightness, temperature, delta_uv);
break;
case ESP_BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_SET:
case ESP_BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_SET_UNACK:
/* Light CTL Temperature Server Model - Secondary Element */
ESP_LOGI(TAG, "temperature 0x%04x, delta uv 0x%04x",
param->value.state_change.ctl_temp_set.temperature,
param->value.state_change.ctl_temp_set.delta_uv);
break;
/*!< Light CTL Setup Message Opcode */
case ESP_BLE_MESH_MODEL_OP_LIGHT_CTL_DEFAULT_SET:
case ESP_BLE_MESH_MODEL_OP_LIGHT_CTL_DEFAULT_SET_UNACK:
/* Light CTL Setup Server Model - Primary Element */
ESP_LOGI(TAG, "lightness 0x%04x, temperature 0x%04x, delta uv 0x%04x",
param->value.state_change.ctl_default_set.lightness,
param->value.state_change.ctl_default_set.temperature,
param->value.state_change.ctl_default_set.delta_uv);
break;
case ESP_BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_RANGE_SET:
case ESP_BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_RANGE_SET_UNACK:
/* Light CTL Setup Server Model - Primary Element */
ESP_LOGI(TAG, "temperature min 0x%04x, max 0x%04x",
param->value.state_change.ctl_temp_range_set.range_min,
param->value.state_change.ctl_temp_range_set.range_max);
break;
#endif
}
break;
default:
ESP_LOGE(TAG, "Unknown Lighting Server event 0x%02x", event);
break;
}
}
static void example_ble_mesh_custom_model_cb(esp_ble_mesh_model_cb_event_t event,
esp_ble_mesh_model_cb_param_t *param)
{
ESP_LOGD(TAG, "event 0x%02x", event);
switch (event) {
case ESP_BLE_MESH_MODEL_OPERATION_EVT:
ESP_LOGD(TAG, "ESP_BLE_MESH_MODEL_OPERATION_EVT");
ESP_LOGD(TAG, "opcode: 0x%06x", param->model_operation.opcode);
genie_model_dispatch(param->model_operation.opcode, param->model_operation.model,
param->model_operation.ctx, param->model_operation.msg, param->model_operation.length);
break;
case ESP_BLE_MESH_MODEL_SEND_COMP_EVT:
ESP_LOGD(TAG, "ESP_BLE_MESH_MODEL_SEND_COMP_EVT");
ESP_LOGD(TAG, "opcode: 0x%06x", param->model_send_comp.opcode);
if (param->model_send_comp.err_code) {
ESP_LOGE(TAG, "Failed to send message: 0x%06x, err: %d", param->model_send_comp.opcode, param->model_send_comp.err_code);
break;
}
break;
case ESP_BLE_MESH_MODEL_PUBLISH_COMP_EVT:
ESP_LOGD(TAG, "ESP_BLE_MESH_MODEL_PUBLISH_COMP_EVT");
break;
case ESP_BLE_MESH_CLIENT_MODEL_RECV_PUBLISH_MSG_EVT:
ESP_LOGD(TAG, "ESP_BLE_MESH_CLIENT_MODEL_RECV_PUBLISH_MSG_EVT");
break;
case ESP_BLE_MESH_CLIENT_MODEL_SEND_TIMEOUT_EVT:
ESP_LOGD(TAG, "ESP_BLE_MESH_CLIENT_MODEL_SEND_TIMEOUT_EVT");
break;
case ESP_BLE_MESH_MODEL_PUBLISH_UPDATE_EVT:
ESP_LOGD(TAG, "ESP_BLE_MESH_MODEL_PUBLISH_UPDATE_EVT");
break;
case ESP_BLE_MESH_SERVER_MODEL_UPDATE_STATE_COMP_EVT:
ESP_LOGD(TAG, "ESP_BLE_MESH_SERVER_MODEL_UPDATE_STATE_COMP_EVT");
ESP_LOGD(TAG, "result %d, model id 0x%04x, type 0x%02x",
param->server_model_update_state.err_code,
param->server_model_update_state.model->model_id,
param->server_model_update_state.type);
break;
case ESP_BLE_MESH_MODEL_EVT_MAX:
ESP_LOGW(TAG, "ESP_BLE_MESH_MODEL_EVT_MAX");
break;
default:
break;
}
}
static esp_err_t ble_mesh_init(void)
{
esp_err_t err;
ESP_ERROR_CHECK(esp_ble_mesh_register_prov_callback(example_ble_mesh_provisioning_cb));
ESP_ERROR_CHECK(esp_ble_mesh_register_config_server_callback(example_ble_mesh_config_server_cb));
ESP_ERROR_CHECK(esp_ble_mesh_register_generic_server_callback(example_ble_mesh_generic_server_cb));
ESP_ERROR_CHECK(esp_ble_mesh_register_lighting_server_callback(example_ble_mesh_lighting_server_cb));
ESP_ERROR_CHECK(esp_ble_mesh_register_custom_model_callback(example_ble_mesh_custom_model_cb));
err = esp_ble_mesh_init(&provision, &composition);
if (err) {
ESP_LOGE(TAG, "Initializing mesh failed (err %d)", err);
return err;
}
ESP_ERROR_CHECK(esp_ble_mesh_node_prov_enable(ESP_BLE_MESH_PROV_ADV | ESP_BLE_MESH_PROV_GATT));
if (esp_ble_mesh_node_is_provisioned()) {
ESP_LOGW(TAG, "node already provisioned");
} else {
ESP_LOGW(TAG, "node not provisioned");
light_driver_breath_start(0, 255, 0); /**< green blink */
}
return err;
}
void config_triples(void)
{
// AuthValue = SHA256(Product ID,MAC,Secret)
char *authvalue_string = NULL;
asprintf(&authvalue_string, "%08x,%s,%s", CONFIG_TRIPLES_PRODUCT_ID, CONFIG_TRIPLES_DEVICE_NAME, CONFIG_TRIPLES_DEVICE_SECRET);
ESP_LOGI(TAG, "authvalue_string: %s", authvalue_string);
uint8_t sha256_out[32] = {0};
mbedtls_sha256_ret((const unsigned char *)authvalue_string, strlen(authvalue_string), sha256_out, 0);
memcpy(static_val, sha256_out, 16);
provision.static_val = static_val;
uint8_t product_id[4];
mac_str2hex(authvalue_string, product_id);
swap_buf(dev_uuid + 3, product_id, 4);
uint8_t ali_mac_address[6];
mac_str2hex(CONFIG_TRIPLES_DEVICE_NAME, ali_mac_address);
swap_buf(dev_uuid + 7, ali_mac_address, 6);
ali_mac_address[5] -= 2;
esp_base_mac_addr_set(ali_mac_address);
free(authvalue_string);
}
void app_main(void)
{
esp_err_t err;
esp_log_level_set("genie_event", ESP_LOG_DEBUG);
ESP_LOGI(TAG, "Initializing...");
board_init();
err = nvs_flash_init();
if (err == ESP_ERR_NVS_NO_FREE_PAGES) {
ESP_LOGI(TAG, "nvs_flash_erase...");
ESP_ERROR_CHECK(nvs_flash_erase());
err = nvs_flash_init();
}
ESP_ERROR_CHECK(err);
/* Open nvs namespace for storing/restoring mesh example info */
err = ble_mesh_nvs_open(&NVS_HANDLE);
if (err) {
ESP_LOGE(TAG, "ble_mesh_nvs_open failed (err %d)", err);
return;
}
#ifdef CONFIG_GENIE_RESET_BY_REPEAT
genie_reset_by_repeat_init();
#endif
config_triples();
err = bluetooth_init();
if (err) {
ESP_LOGE(TAG, "esp32_bluetooth_init failed (err %d)", err);
return;
}
/* Initialize the Bluetooth Mesh Subsystem */
err = ble_mesh_init();
if (err) {
ESP_LOGE(TAG, "Bluetooth mesh init failed (err %d)", err);
}
}