sdk-hwV1.3/lichee/xr806/appos/project/demo/bluetooth/mesh_demo/main.c

308 lines
8.9 KiB
C
Executable File

/*
* Copyright (C) 2017 XRADIO TECHNOLOGY CO., LTD. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
* 3. Neither the name of XRADIO TECHNOLOGY CO., LTD. nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdio.h>
#include <string.h>
#include "kernel/os/os.h"
#include "common/framework/platform_init.h"
#include "ble/bluetooth/bluetooth.h"
#include "ble/bluetooth/mesh.h"
#include "ble/bluetooth/mesh/mesh_common.h"
#include "ble/bluetooth/mesh/generic_onoff_srv.h"
#include "ble/bluetooth/mesh/generic_onoff_cli.h"
#include "ble/bluetooth/mesh/transition.h"
#if PRJCONF_BLE_EN
#ifndef PRJCONF_BLE_ETF
#include "common/framework/bt_ctrl.h"
#endif
#endif
#if defined(CONFIG_BT_MESH_FRIEND)
#define MESH_FRIEND_FUNC_ENABLE 1
#endif
#define DEV_UUID_MATCH_1 'X'
#define DEV_UUID_MATCH_2 'R'
/***************Global Variable**************************/
static uint16_t primary_addr;
static uint16_t primary_net_idx;
static uint8_t g_onoff_value;
/* Disable OOB security for SILabs Android app */
static uint8_t dev_uuid[16] = { DEV_UUID_MATCH_1, DEV_UUID_MATCH_2, 0xdc, 0xdb };
/***************Publication Declarations**************************
* The publication messages are initialized to the
* the size of the opcode + content
*
* For publication, the message must be in static or global as
* it is re-transmitted several times. This occurs
* after the function that called bt_mesh_model_publish() has
* exited and the stack is no longer valid.
*
* Note that the additional 4 bytes for the AppMIC is not needed
* because it is added to a stack variable at the time a
* transmission occurs.
*
*****************************************************************/
BT_MESH_HEALTH_PUB_DEFINE(health_pub, 0);
BT_MESH_MODEL_PUB_DEFINE(gen_onoff_pub_srv, NULL, 4);
BT_MESH_MODEL_PUB_DEFINE(gen_onoff_pub_cli, NULL, 4);
/***************Model Processing*******************/
/***************Configuration Client Declaration*******************/
static struct bt_mesh_cfg_cli cfg_cli = {
};
/***************Health Configuration Declaration*******************/
static void healthsrv_attention_on(struct bt_mesh_model *model)
{
printf("*****attention_on*****\n");
}
static void healthsrv_attention_off(struct bt_mesh_model *model)
{
printf("*****attention_off*****\n");
}
static const struct bt_mesh_health_srv_cb health_srv_cb = {
.attn_on = healthsrv_attention_on,
.attn_off = healthsrv_attention_off,
};
static struct bt_mesh_health_srv health_srv = {
.cb = &health_srv_cb,
};
static void show_faults(uint8_t test_id, uint16_t cid, uint8_t *faults, size_t fault_count)
{
size_t i;
if (!fault_count) {
printf("Health Test ID 0x%02x Company ID 0x%04x: no faults\n", test_id, cid);
return;
}
printf("Health Test ID 0x%02x Company ID 0x%04x Fault Count %u:\n", test_id, cid, fault_count);
for (i = 0; i < fault_count; i++) {
printf("\t0x%02x\n", faults[i]);
}
}
static void health_current_status(struct bt_mesh_health_cli *cli, uint16_t addr,
uint8_t test_id, uint16_t cid, uint8_t *faults,
size_t fault_count)
{
printf("Health Current Status from 0x%04x\n", addr);
show_faults(test_id, cid, faults, fault_count);
}
static struct bt_mesh_health_cli health_cli = {
.current_status = health_current_status,
};
/***************Onoff Configuration Declaration*******************/
static void app_onoff_srv_set_cb(const struct bt_mesh_model *model, uint8_t onoff,
uint8_t target_onoff, const struct bt_mesh_transition_status *opt)
{
g_onoff_value = onoff;
printf("[app] onoff set(%d)", onoff);
if (opt) {
printf("target onoff(%d), total_steps(%d), steps(%d)",
target_onoff, opt->total_steps, opt->present_steps);
}
printf("\n");
}
static void app_onoff_srv_get_cb(const struct bt_mesh_model *model,
uint8_t *onoff)
{
printf("[app] onoff get(%d)\n", g_onoff_value);
*onoff = g_onoff_value;
}
static struct bt_mesh_gen_onoff_srv onoff_srv_user_data = {
.set_cb = app_onoff_srv_set_cb,
.get_cb = app_onoff_srv_get_cb,
};
void app_onoff_cli_status_cb(const struct bt_mesh_model *model, uint8_t present,
uint8_t target, const struct bt_mesh_transition_remain_time *opt)
{
printf("present onoff(%d), target onoff(%d)", present, target);
if (opt)
printf(", remain time(%d)", opt->remain_time);
printf("\n");
}
static struct bt_mesh_gen_onoff_cli onoff_cli_user_data = {
.status_cb = app_onoff_cli_status_cb
};
/****************Element Model Declarations*********************/
/*
* Element 0 Root Models
*/
static struct bt_mesh_model root_models[] = {
BT_MESH_MODEL_CFG_SRV,
BT_MESH_MODEL_CFG_CLI(&cfg_cli),
BT_MESH_MODEL_HEALTH_SRV(&health_srv, &health_pub),
BT_MESH_MODEL_HEALTH_CLI(&health_cli),
BT_MESH_MODEL_GEN_ONOFF_SRV(&onoff_srv_user_data, &gen_onoff_pub_srv),
BT_MESH_MODEL_GEN_ONOFF_CLI(&onoff_cli_user_data, &gen_onoff_pub_cli),
};
/*********Root and Secondary Element Declarations*********/
static struct bt_mesh_elem elements[] = {
BT_MESH_ELEM(0, root_models, BT_MESH_MODEL_NONE),
};
static const struct bt_mesh_comp comp = {
.cid = BT_COMP_ID_LF,
.elem = elements,
.elem_count = ARRAY_SIZE(elements),
};
/***************Provisioning Processing*******************/
static int output_number(bt_mesh_output_action_t action, uint32_t number)
{
printf("***** OOB number : %u\n", number);
return 0;
}
static int output_string(const char *str)
{
printf("***** OOB String : %s\n", str);
return 0;
}
static void prov_complete(uint16_t net_idx, uint16_t addr)
{
#if (CONFIG_BT_MESH_FRIEND)
#if (MESH_FRIEND_FUNC_ENABLE)
int err;
uint8_t frnd;
#endif
#endif
primary_addr = addr;
primary_net_idx = net_idx;
printf("***** Provisioning - complete\n");
printf("net_idx 0x%04x\naddr 0x%04x\n", net_idx, addr);
#if (CONFIG_BT_MESH_FRIEND)
#if (MESH_FRIEND_FUNC_ENABLE)
err = bt_mesh_cfg_friend_set(primary_net_idx, primary_addr, 1, &frnd);
if (err) {
printf("Unable to send Friend Get/Set (err %d)\n", err);
} else {
printf("Friend is set to 0x%02x\n", frnd);
}
#endif
#endif
}
static void prov_reset(void)
{
bt_mesh_prov_enable(BT_MESH_PROV_ADV | BT_MESH_PROV_GATT);
}
static const struct bt_mesh_prov prov = {
.uuid = dev_uuid,
.oob_info = (BT_MESH_PROV_OOB_NUMBER | BT_MESH_PROV_OOB_STRING),
.output_size = 6,
.output_actions = (BT_MESH_DISPLAY_NUMBER | BT_MESH_DISPLAY_STRING),
.output_number = output_number,
.output_string = output_string,
.complete = prov_complete,
.reset = prov_reset,
};
/****************Init Operation**************************/
static void bt_ready(int err)
{
struct bt_le_oob oob;
if (err) {
printf("bt_ready : Bluetooth init failed (err %d)\n", err);
return;
}
err = bt_mesh_init(&prov, &comp);
if (err) {
printf("bt_ready : Initializing mesh failed (err %d)\n", err);
return;
}
if (IS_ENABLED(CONFIG_SETTINGS)) {
settings_load();
}
/* Use identity address as device UUID */
if (bt_le_oob_get_local(BT_ID_DEFAULT, &oob)) {
printf("bt_ready : Identity Address unavailable\n");
} else {
memcpy(dev_uuid + 2, oob.addr.a.val, 6);
}
if (bt_mesh_is_provisioned()) {
printf("Mesh network restored from flash\n");
} else {
bt_mesh_prov_enable(BT_MESH_PROV_GATT | BT_MESH_PROV_ADV);
}
printf("bt_ready : Mesh initialized\n");
}
int main(void)
{
int err;
platform_init();
err = bt_ctrl_enable();
if (err) {
printf("Bluetooth controller init failed (err %d)\n", err);
return 0;
}
/* Initialize the Bluetooth Subsystem */
err = bt_enable(bt_ready);
if (err) {
printf("main : Bluetooth init failed (err %d)\n", err);
}
return 0;
}