| /* main.c - Application main entry point */ |
| |
| /* |
| * Copyright (c) 2017 Intel Corporation |
| * |
| * SPDX-License-Identifier: Apache-2.0 |
| */ |
| |
| #include <misc/printk.h> |
| |
| #include <bluetooth/bluetooth.h> |
| #include <bluetooth/mesh.h> |
| |
| #include "board.h" |
| |
| #define CID_INTEL 0x0002 |
| |
| #define MAX_FAULT 24 |
| |
| static bool has_reg_fault = true; |
| |
| static struct bt_mesh_cfg_srv cfg_srv = { |
| .relay = BT_MESH_RELAY_DISABLED, |
| .beacon = BT_MESH_BEACON_DISABLED, |
| #if defined(CONFIG_BT_MESH_FRIEND) |
| #if defined(CONFIG_BT_MESH_LOW_POWER) |
| .frnd = BT_MESH_FRIEND_DISABLED, |
| #else |
| .frnd = BT_MESH_FRIEND_ENABLED, |
| #endif |
| #else |
| .frnd = BT_MESH_FRIEND_NOT_SUPPORTED, |
| #endif |
| #if defined(CONFIG_BT_MESH_GATT_PROXY) |
| .gatt_proxy = BT_MESH_GATT_PROXY_ENABLED, |
| #else |
| .gatt_proxy = BT_MESH_GATT_PROXY_NOT_SUPPORTED, |
| #endif |
| .default_ttl = 7, |
| |
| /* 3 transmissions with 20ms interval */ |
| .net_transmit = BT_MESH_TRANSMIT(2, 20), |
| .relay_retransmit = BT_MESH_TRANSMIT(2, 20), |
| }; |
| |
| static int fault_get_cur(struct bt_mesh_model *model, u8_t *test_id, |
| u16_t *company_id, u8_t *faults, u8_t *fault_count) |
| { |
| u8_t reg_faults[MAX_FAULT] = { [0 ... (MAX_FAULT - 1)] = 0xff }; |
| |
| printk("fault_get_cur() has_reg_fault %u\n", has_reg_fault); |
| |
| *test_id = 0x00; |
| *company_id = CID_INTEL; |
| memcpy(faults, reg_faults, sizeof(reg_faults)); |
| *fault_count = sizeof(reg_faults); |
| |
| return 0; |
| } |
| |
| static int fault_get_reg(struct bt_mesh_model *model, u16_t company_id, |
| u8_t *test_id, u8_t *faults, u8_t *fault_count) |
| { |
| if (company_id != CID_INTEL) { |
| return -EINVAL; |
| } |
| |
| printk("fault_get_reg() has_reg_fault %u\n", has_reg_fault); |
| |
| *test_id = 0x00; |
| |
| if (has_reg_fault) { |
| u8_t reg_faults[MAX_FAULT] = { [0 ... (MAX_FAULT - 1)] = 0xff }; |
| |
| memcpy(faults, reg_faults, sizeof(reg_faults)); |
| *fault_count = sizeof(reg_faults); |
| } else { |
| *fault_count = 0; |
| } |
| |
| return 0; |
| } |
| |
| static int fault_clear(struct bt_mesh_model *model, uint16_t company_id) |
| { |
| if (company_id != CID_INTEL) { |
| return -EINVAL; |
| } |
| |
| has_reg_fault = false; |
| |
| return 0; |
| } |
| |
| static int fault_test(struct bt_mesh_model *model, uint8_t test_id, |
| uint16_t company_id) |
| { |
| if (company_id != CID_INTEL) { |
| return -EINVAL; |
| } |
| |
| has_reg_fault = true; |
| bt_mesh_fault_update(model->elem); |
| |
| return 0; |
| } |
| |
| static const struct bt_mesh_health_srv_cb health_srv_cb = { |
| .fault_get_cur = fault_get_cur, |
| .fault_get_reg = fault_get_reg, |
| .fault_clear = fault_clear, |
| .fault_test = fault_test, |
| }; |
| |
| static struct bt_mesh_health_srv health_srv = { |
| .cb = &health_srv_cb, |
| }; |
| |
| static struct bt_mesh_model_pub health_pub = { |
| .msg = BT_MESH_HEALTH_FAULT_MSG(MAX_FAULT), |
| }; |
| |
| static struct bt_mesh_model root_models[] = { |
| BT_MESH_MODEL_CFG_SRV(&cfg_srv), |
| BT_MESH_MODEL_HEALTH_SRV(&health_srv, &health_pub), |
| }; |
| |
| static int vnd_publish(struct bt_mesh_model *mod) |
| { |
| printk("Vendor publish\n"); |
| return 0; |
| } |
| |
| static struct bt_mesh_model_pub vnd_pub = { |
| .update = vnd_publish, |
| .msg = NET_BUF_SIMPLE(4), |
| }; |
| |
| static struct bt_mesh_model_pub vnd_pub2 = { |
| .msg = NET_BUF_SIMPLE(4), |
| }; |
| |
| static const struct bt_mesh_model_op vnd_ops[] = { |
| BT_MESH_MODEL_OP_END, |
| }; |
| |
| static struct bt_mesh_model vnd_models[] = { |
| BT_MESH_MODEL_VND(CID_INTEL, 0x1234, vnd_ops, &vnd_pub, NULL), |
| BT_MESH_MODEL_VND(CID_INTEL, 0x4321, vnd_ops, &vnd_pub2, NULL), |
| }; |
| |
| static struct bt_mesh_elem elements[] = { |
| BT_MESH_ELEM(0, root_models, vnd_models), |
| }; |
| |
| static const struct bt_mesh_comp comp = { |
| .cid = CID_INTEL, |
| .elem = elements, |
| .elem_count = ARRAY_SIZE(elements), |
| }; |
| |
| #if 0 |
| static int output_number(bt_mesh_output_action_t action, uint32_t number) |
| { |
| printk("OOB Number: %u\n", number); |
| |
| board_output_number(action, number); |
| |
| return 0; |
| } |
| #endif |
| |
| static void prov_complete(u16_t net_idx, u16_t addr) |
| { |
| board_prov_complete(); |
| |
| if (IS_ENABLED(CONFIG_BT_MESH_IV_UPDATE_TEST)) { |
| bt_mesh_iv_update_test(true); |
| } |
| } |
| |
| static void prov_reset(void) |
| { |
| bt_mesh_prov_enable(BT_MESH_PROV_ADV | BT_MESH_PROV_GATT); |
| } |
| |
| static const u8_t dev_uuid[16] = { 0xdd, 0xdd }; |
| |
| static const struct bt_mesh_prov prov = { |
| .uuid = dev_uuid, |
| #if 0 |
| .output_size = 4, |
| .output_actions = BT_MESH_DISPLAY_NUMBER, |
| .output_number = output_number, |
| #endif |
| .complete = prov_complete, |
| .reset = prov_reset, |
| }; |
| |
| static void bt_ready(int err) |
| { |
| if (err) { |
| printk("Bluetooth init failed (err %d)\n", err); |
| return; |
| } |
| |
| printk("Bluetooth initialized\n"); |
| |
| board_init(); |
| |
| err = bt_mesh_init(&prov, &comp); |
| if (err) { |
| printk("Initializing mesh failed (err %d)\n", err); |
| return; |
| } |
| |
| /* Initialize publication messages with dummy data */ |
| net_buf_simple_init(vnd_pub.msg, 0); |
| net_buf_simple_add_le32(vnd_pub.msg, UINT32_MAX); |
| net_buf_simple_init(vnd_pub2.msg, 0); |
| net_buf_simple_add_le32(vnd_pub2.msg, UINT32_MAX); |
| |
| bt_mesh_prov_enable(BT_MESH_PROV_ADV | BT_MESH_PROV_GATT); |
| |
| printk("Mesh initialized\n"); |
| } |
| |
| void main(void) |
| { |
| int err; |
| |
| printk("Initializing...\n"); |
| |
| /* Initialize the Bluetooth Subsystem */ |
| err = bt_enable(bt_ready); |
| if (err) { |
| printk("Bluetooth init failed (err %d)\n", err); |
| } |
| } |