1*042d53a7SEvalZero /*
2*042d53a7SEvalZero * Licensed to the Apache Software Foundation (ASF) under one
3*042d53a7SEvalZero * or more contributor license agreements. See the NOTICE file
4*042d53a7SEvalZero * distributed with this work for additional information
5*042d53a7SEvalZero * regarding copyright ownership. The ASF licenses this file
6*042d53a7SEvalZero * to you under the Apache License, Version 2.0 (the
7*042d53a7SEvalZero * "License"); you may not use this file except in compliance
8*042d53a7SEvalZero * with the License. You may obtain a copy of the License at
9*042d53a7SEvalZero *
10*042d53a7SEvalZero * http://www.apache.org/licenses/LICENSE-2.0
11*042d53a7SEvalZero *
12*042d53a7SEvalZero * Unless required by applicable law or agreed to in writing,
13*042d53a7SEvalZero * software distributed under the License is distributed on an
14*042d53a7SEvalZero * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15*042d53a7SEvalZero * KIND, either express or implied. See the License for the
16*042d53a7SEvalZero * specific language governing permissions and limitations
17*042d53a7SEvalZero * under the License.
18*042d53a7SEvalZero */
19*042d53a7SEvalZero
20*042d53a7SEvalZero #include <assert.h>
21*042d53a7SEvalZero #include "os/mynewt.h"
22*042d53a7SEvalZero #include "mesh/mesh.h"
23*042d53a7SEvalZero #include "console/console.h"
24*042d53a7SEvalZero #include "hal/hal_system.h"
25*042d53a7SEvalZero #include "hal/hal_gpio.h"
26*042d53a7SEvalZero #include "bsp/bsp.h"
27*042d53a7SEvalZero #include "shell/shell.h"
28*042d53a7SEvalZero
29*042d53a7SEvalZero /* BLE */
30*042d53a7SEvalZero #include "nimble/ble.h"
31*042d53a7SEvalZero #include "host/ble_hs.h"
32*042d53a7SEvalZero #include "services/gap/ble_svc_gap.h"
33*042d53a7SEvalZero #include "mesh/glue.h"
34*042d53a7SEvalZero
35*042d53a7SEvalZero #define BT_DBG_ENABLED (MYNEWT_VAL(BLE_MESH_DEBUG))
36*042d53a7SEvalZero
37*042d53a7SEvalZero /* Company ID */
38*042d53a7SEvalZero #define CID_VENDOR 0x05C3
39*042d53a7SEvalZero #define STANDARD_TEST_ID 0x00
40*042d53a7SEvalZero #define TEST_ID 0x01
41*042d53a7SEvalZero static int recent_test_id = STANDARD_TEST_ID;
42*042d53a7SEvalZero
43*042d53a7SEvalZero #define FAULT_ARR_SIZE 2
44*042d53a7SEvalZero
45*042d53a7SEvalZero static bool has_reg_fault = true;
46*042d53a7SEvalZero
47*042d53a7SEvalZero static struct bt_mesh_cfg_srv cfg_srv = {
48*042d53a7SEvalZero .relay = BT_MESH_RELAY_DISABLED,
49*042d53a7SEvalZero .beacon = BT_MESH_BEACON_ENABLED,
50*042d53a7SEvalZero #if MYNEWT_VAL(BLE_MESH_FRIEND)
51*042d53a7SEvalZero .frnd = BT_MESH_FRIEND_ENABLED,
52*042d53a7SEvalZero #else
53*042d53a7SEvalZero .gatt_proxy = BT_MESH_GATT_PROXY_NOT_SUPPORTED,
54*042d53a7SEvalZero #endif
55*042d53a7SEvalZero #if MYNEWT_VAL(BLE_MESH_GATT_PROXY)
56*042d53a7SEvalZero .gatt_proxy = BT_MESH_GATT_PROXY_ENABLED,
57*042d53a7SEvalZero #else
58*042d53a7SEvalZero .gatt_proxy = BT_MESH_GATT_PROXY_NOT_SUPPORTED,
59*042d53a7SEvalZero #endif
60*042d53a7SEvalZero .default_ttl = 7,
61*042d53a7SEvalZero
62*042d53a7SEvalZero /* 3 transmissions with 20ms interval */
63*042d53a7SEvalZero .net_transmit = BT_MESH_TRANSMIT(2, 20),
64*042d53a7SEvalZero .relay_retransmit = BT_MESH_TRANSMIT(2, 20),
65*042d53a7SEvalZero };
66*042d53a7SEvalZero
67*042d53a7SEvalZero static int
fault_get_cur(struct bt_mesh_model * model,uint8_t * test_id,uint16_t * company_id,uint8_t * faults,uint8_t * fault_count)68*042d53a7SEvalZero fault_get_cur(struct bt_mesh_model *model,
69*042d53a7SEvalZero uint8_t *test_id,
70*042d53a7SEvalZero uint16_t *company_id,
71*042d53a7SEvalZero uint8_t *faults,
72*042d53a7SEvalZero uint8_t *fault_count)
73*042d53a7SEvalZero {
74*042d53a7SEvalZero uint8_t reg_faults[FAULT_ARR_SIZE] = { [0 ... FAULT_ARR_SIZE-1] = 0xff };
75*042d53a7SEvalZero
76*042d53a7SEvalZero console_printf("fault_get_cur() has_reg_fault %u\n", has_reg_fault);
77*042d53a7SEvalZero
78*042d53a7SEvalZero *test_id = recent_test_id;
79*042d53a7SEvalZero *company_id = CID_VENDOR;
80*042d53a7SEvalZero
81*042d53a7SEvalZero *fault_count = min(*fault_count, sizeof(reg_faults));
82*042d53a7SEvalZero memcpy(faults, reg_faults, *fault_count);
83*042d53a7SEvalZero
84*042d53a7SEvalZero return 0;
85*042d53a7SEvalZero }
86*042d53a7SEvalZero
87*042d53a7SEvalZero static int
fault_get_reg(struct bt_mesh_model * model,uint16_t company_id,uint8_t * test_id,uint8_t * faults,uint8_t * fault_count)88*042d53a7SEvalZero fault_get_reg(struct bt_mesh_model *model,
89*042d53a7SEvalZero uint16_t company_id,
90*042d53a7SEvalZero uint8_t *test_id,
91*042d53a7SEvalZero uint8_t *faults,
92*042d53a7SEvalZero uint8_t *fault_count)
93*042d53a7SEvalZero {
94*042d53a7SEvalZero if (company_id != CID_VENDOR) {
95*042d53a7SEvalZero return -BLE_HS_EINVAL;
96*042d53a7SEvalZero }
97*042d53a7SEvalZero
98*042d53a7SEvalZero console_printf("fault_get_reg() has_reg_fault %u\n", has_reg_fault);
99*042d53a7SEvalZero
100*042d53a7SEvalZero *test_id = recent_test_id;
101*042d53a7SEvalZero
102*042d53a7SEvalZero if (has_reg_fault) {
103*042d53a7SEvalZero uint8_t reg_faults[FAULT_ARR_SIZE] = { [0 ... FAULT_ARR_SIZE-1] = 0xff };
104*042d53a7SEvalZero
105*042d53a7SEvalZero *fault_count = min(*fault_count, sizeof(reg_faults));
106*042d53a7SEvalZero memcpy(faults, reg_faults, *fault_count);
107*042d53a7SEvalZero } else {
108*042d53a7SEvalZero *fault_count = 0;
109*042d53a7SEvalZero }
110*042d53a7SEvalZero
111*042d53a7SEvalZero return 0;
112*042d53a7SEvalZero }
113*042d53a7SEvalZero
114*042d53a7SEvalZero static int
fault_clear(struct bt_mesh_model * model,uint16_t company_id)115*042d53a7SEvalZero fault_clear(struct bt_mesh_model *model, uint16_t company_id)
116*042d53a7SEvalZero {
117*042d53a7SEvalZero if (company_id != CID_VENDOR) {
118*042d53a7SEvalZero return -BLE_HS_EINVAL;
119*042d53a7SEvalZero }
120*042d53a7SEvalZero
121*042d53a7SEvalZero has_reg_fault = false;
122*042d53a7SEvalZero
123*042d53a7SEvalZero return 0;
124*042d53a7SEvalZero }
125*042d53a7SEvalZero
126*042d53a7SEvalZero static int
fault_test(struct bt_mesh_model * model,uint8_t test_id,uint16_t company_id)127*042d53a7SEvalZero fault_test(struct bt_mesh_model *model, uint8_t test_id, uint16_t company_id)
128*042d53a7SEvalZero {
129*042d53a7SEvalZero if (company_id != CID_VENDOR) {
130*042d53a7SEvalZero return -BLE_HS_EINVAL;
131*042d53a7SEvalZero }
132*042d53a7SEvalZero
133*042d53a7SEvalZero if (test_id != STANDARD_TEST_ID && test_id != TEST_ID) {
134*042d53a7SEvalZero return -BLE_HS_EINVAL;
135*042d53a7SEvalZero }
136*042d53a7SEvalZero
137*042d53a7SEvalZero recent_test_id = test_id;
138*042d53a7SEvalZero has_reg_fault = true;
139*042d53a7SEvalZero bt_mesh_fault_update(bt_mesh_model_elem(model));
140*042d53a7SEvalZero
141*042d53a7SEvalZero return 0;
142*042d53a7SEvalZero }
143*042d53a7SEvalZero
144*042d53a7SEvalZero static const struct bt_mesh_health_srv_cb health_srv_cb = {
145*042d53a7SEvalZero .fault_get_cur = &fault_get_cur,
146*042d53a7SEvalZero .fault_get_reg = &fault_get_reg,
147*042d53a7SEvalZero .fault_clear = &fault_clear,
148*042d53a7SEvalZero .fault_test = &fault_test,
149*042d53a7SEvalZero };
150*042d53a7SEvalZero
151*042d53a7SEvalZero static struct bt_mesh_health_srv health_srv = {
152*042d53a7SEvalZero .cb = &health_srv_cb,
153*042d53a7SEvalZero };
154*042d53a7SEvalZero
155*042d53a7SEvalZero static struct bt_mesh_model_pub health_pub;
156*042d53a7SEvalZero
157*042d53a7SEvalZero static void
health_pub_init(void)158*042d53a7SEvalZero health_pub_init(void)
159*042d53a7SEvalZero {
160*042d53a7SEvalZero health_pub.msg = BT_MESH_HEALTH_FAULT_MSG(0);
161*042d53a7SEvalZero }
162*042d53a7SEvalZero
163*042d53a7SEvalZero static struct bt_mesh_model_pub gen_level_pub;
164*042d53a7SEvalZero static struct bt_mesh_model_pub gen_onoff_pub;
165*042d53a7SEvalZero
166*042d53a7SEvalZero static uint8_t gen_on_off_state;
167*042d53a7SEvalZero static int16_t gen_level_state;
168*042d53a7SEvalZero
gen_onoff_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx)169*042d53a7SEvalZero static void gen_onoff_status(struct bt_mesh_model *model,
170*042d53a7SEvalZero struct bt_mesh_msg_ctx *ctx)
171*042d53a7SEvalZero {
172*042d53a7SEvalZero struct os_mbuf *msg = NET_BUF_SIMPLE(3);
173*042d53a7SEvalZero uint8_t *status;
174*042d53a7SEvalZero
175*042d53a7SEvalZero console_printf("#mesh-onoff STATUS\n");
176*042d53a7SEvalZero
177*042d53a7SEvalZero bt_mesh_model_msg_init(msg, BT_MESH_MODEL_OP_2(0x82, 0x04));
178*042d53a7SEvalZero status = net_buf_simple_add(msg, 1);
179*042d53a7SEvalZero *status = gen_on_off_state;
180*042d53a7SEvalZero
181*042d53a7SEvalZero if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) {
182*042d53a7SEvalZero console_printf("#mesh-onoff STATUS: send status failed\n");
183*042d53a7SEvalZero }
184*042d53a7SEvalZero
185*042d53a7SEvalZero os_mbuf_free_chain(msg);
186*042d53a7SEvalZero }
187*042d53a7SEvalZero
gen_onoff_get(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)188*042d53a7SEvalZero static void gen_onoff_get(struct bt_mesh_model *model,
189*042d53a7SEvalZero struct bt_mesh_msg_ctx *ctx,
190*042d53a7SEvalZero struct os_mbuf *buf)
191*042d53a7SEvalZero {
192*042d53a7SEvalZero console_printf("#mesh-onoff GET\n");
193*042d53a7SEvalZero
194*042d53a7SEvalZero gen_onoff_status(model, ctx);
195*042d53a7SEvalZero }
196*042d53a7SEvalZero
gen_onoff_set(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)197*042d53a7SEvalZero static void gen_onoff_set(struct bt_mesh_model *model,
198*042d53a7SEvalZero struct bt_mesh_msg_ctx *ctx,
199*042d53a7SEvalZero struct os_mbuf *buf)
200*042d53a7SEvalZero {
201*042d53a7SEvalZero console_printf("#mesh-onoff SET\n");
202*042d53a7SEvalZero
203*042d53a7SEvalZero gen_on_off_state = buf->om_data[0];
204*042d53a7SEvalZero hal_gpio_write(LED_2, !gen_on_off_state);
205*042d53a7SEvalZero
206*042d53a7SEvalZero gen_onoff_status(model, ctx);
207*042d53a7SEvalZero }
208*042d53a7SEvalZero
gen_onoff_set_unack(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)209*042d53a7SEvalZero static void gen_onoff_set_unack(struct bt_mesh_model *model,
210*042d53a7SEvalZero struct bt_mesh_msg_ctx *ctx,
211*042d53a7SEvalZero struct os_mbuf *buf)
212*042d53a7SEvalZero {
213*042d53a7SEvalZero console_printf("#mesh-onoff SET-UNACK\n");
214*042d53a7SEvalZero
215*042d53a7SEvalZero gen_on_off_state = buf->om_data[0];
216*042d53a7SEvalZero hal_gpio_write(LED_2, !gen_on_off_state);
217*042d53a7SEvalZero }
218*042d53a7SEvalZero
219*042d53a7SEvalZero static const struct bt_mesh_model_op gen_onoff_op[] = {
220*042d53a7SEvalZero { BT_MESH_MODEL_OP_2(0x82, 0x01), 0, gen_onoff_get },
221*042d53a7SEvalZero { BT_MESH_MODEL_OP_2(0x82, 0x02), 2, gen_onoff_set },
222*042d53a7SEvalZero { BT_MESH_MODEL_OP_2(0x82, 0x03), 2, gen_onoff_set_unack },
223*042d53a7SEvalZero BT_MESH_MODEL_OP_END,
224*042d53a7SEvalZero };
225*042d53a7SEvalZero
gen_level_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx)226*042d53a7SEvalZero static void gen_level_status(struct bt_mesh_model *model,
227*042d53a7SEvalZero struct bt_mesh_msg_ctx *ctx)
228*042d53a7SEvalZero {
229*042d53a7SEvalZero struct os_mbuf *msg = NET_BUF_SIMPLE(4);
230*042d53a7SEvalZero
231*042d53a7SEvalZero console_printf("#mesh-level STATUS\n");
232*042d53a7SEvalZero
233*042d53a7SEvalZero bt_mesh_model_msg_init(msg, BT_MESH_MODEL_OP_2(0x82, 0x08));
234*042d53a7SEvalZero net_buf_simple_add_le16(msg, gen_level_state);
235*042d53a7SEvalZero
236*042d53a7SEvalZero if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) {
237*042d53a7SEvalZero console_printf("#mesh-level STATUS: send status failed\n");
238*042d53a7SEvalZero }
239*042d53a7SEvalZero
240*042d53a7SEvalZero os_mbuf_free_chain(msg);
241*042d53a7SEvalZero }
242*042d53a7SEvalZero
gen_level_get(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)243*042d53a7SEvalZero static void gen_level_get(struct bt_mesh_model *model,
244*042d53a7SEvalZero struct bt_mesh_msg_ctx *ctx,
245*042d53a7SEvalZero struct os_mbuf *buf)
246*042d53a7SEvalZero {
247*042d53a7SEvalZero console_printf("#mesh-level GET\n");
248*042d53a7SEvalZero
249*042d53a7SEvalZero gen_level_status(model, ctx);
250*042d53a7SEvalZero }
251*042d53a7SEvalZero
gen_level_set(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)252*042d53a7SEvalZero static void gen_level_set(struct bt_mesh_model *model,
253*042d53a7SEvalZero struct bt_mesh_msg_ctx *ctx,
254*042d53a7SEvalZero struct os_mbuf *buf)
255*042d53a7SEvalZero {
256*042d53a7SEvalZero int16_t level;
257*042d53a7SEvalZero
258*042d53a7SEvalZero level = (int16_t) net_buf_simple_pull_le16(buf);
259*042d53a7SEvalZero console_printf("#mesh-level SET: level=%d\n", level);
260*042d53a7SEvalZero
261*042d53a7SEvalZero gen_level_status(model, ctx);
262*042d53a7SEvalZero
263*042d53a7SEvalZero gen_level_state = level;
264*042d53a7SEvalZero console_printf("#mesh-level: level=%d\n", gen_level_state);
265*042d53a7SEvalZero }
266*042d53a7SEvalZero
gen_level_set_unack(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)267*042d53a7SEvalZero static void gen_level_set_unack(struct bt_mesh_model *model,
268*042d53a7SEvalZero struct bt_mesh_msg_ctx *ctx,
269*042d53a7SEvalZero struct os_mbuf *buf)
270*042d53a7SEvalZero {
271*042d53a7SEvalZero int16_t level;
272*042d53a7SEvalZero
273*042d53a7SEvalZero level = (int16_t) net_buf_simple_pull_le16(buf);
274*042d53a7SEvalZero console_printf("#mesh-level SET-UNACK: level=%d\n", level);
275*042d53a7SEvalZero
276*042d53a7SEvalZero gen_level_state = level;
277*042d53a7SEvalZero console_printf("#mesh-level: level=%d\n", gen_level_state);
278*042d53a7SEvalZero }
279*042d53a7SEvalZero
gen_delta_set(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)280*042d53a7SEvalZero static void gen_delta_set(struct bt_mesh_model *model,
281*042d53a7SEvalZero struct bt_mesh_msg_ctx *ctx,
282*042d53a7SEvalZero struct os_mbuf *buf)
283*042d53a7SEvalZero {
284*042d53a7SEvalZero int16_t delta_level;
285*042d53a7SEvalZero
286*042d53a7SEvalZero delta_level = (int16_t) net_buf_simple_pull_le16(buf);
287*042d53a7SEvalZero console_printf("#mesh-level DELTA-SET: delta_level=%d\n", delta_level);
288*042d53a7SEvalZero
289*042d53a7SEvalZero gen_level_status(model, ctx);
290*042d53a7SEvalZero
291*042d53a7SEvalZero gen_level_state += delta_level;
292*042d53a7SEvalZero console_printf("#mesh-level: level=%d\n", gen_level_state);
293*042d53a7SEvalZero }
294*042d53a7SEvalZero
gen_delta_set_unack(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)295*042d53a7SEvalZero static void gen_delta_set_unack(struct bt_mesh_model *model,
296*042d53a7SEvalZero struct bt_mesh_msg_ctx *ctx,
297*042d53a7SEvalZero struct os_mbuf *buf)
298*042d53a7SEvalZero {
299*042d53a7SEvalZero int16_t delta_level;
300*042d53a7SEvalZero
301*042d53a7SEvalZero delta_level = (int16_t) net_buf_simple_pull_le16(buf);
302*042d53a7SEvalZero console_printf("#mesh-level DELTA-SET: delta_level=%d\n", delta_level);
303*042d53a7SEvalZero
304*042d53a7SEvalZero gen_level_state += delta_level;
305*042d53a7SEvalZero console_printf("#mesh-level: level=%d\n", gen_level_state);
306*042d53a7SEvalZero }
307*042d53a7SEvalZero
gen_move_set(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)308*042d53a7SEvalZero static void gen_move_set(struct bt_mesh_model *model,
309*042d53a7SEvalZero struct bt_mesh_msg_ctx *ctx,
310*042d53a7SEvalZero struct os_mbuf *buf)
311*042d53a7SEvalZero {
312*042d53a7SEvalZero }
313*042d53a7SEvalZero
gen_move_set_unack(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)314*042d53a7SEvalZero static void gen_move_set_unack(struct bt_mesh_model *model,
315*042d53a7SEvalZero struct bt_mesh_msg_ctx *ctx,
316*042d53a7SEvalZero struct os_mbuf *buf)
317*042d53a7SEvalZero {
318*042d53a7SEvalZero }
319*042d53a7SEvalZero
320*042d53a7SEvalZero static const struct bt_mesh_model_op gen_level_op[] = {
321*042d53a7SEvalZero { BT_MESH_MODEL_OP_2(0x82, 0x05), 0, gen_level_get },
322*042d53a7SEvalZero { BT_MESH_MODEL_OP_2(0x82, 0x06), 3, gen_level_set },
323*042d53a7SEvalZero { BT_MESH_MODEL_OP_2(0x82, 0x07), 3, gen_level_set_unack },
324*042d53a7SEvalZero { BT_MESH_MODEL_OP_2(0x82, 0x09), 5, gen_delta_set },
325*042d53a7SEvalZero { BT_MESH_MODEL_OP_2(0x82, 0x0a), 5, gen_delta_set_unack },
326*042d53a7SEvalZero { BT_MESH_MODEL_OP_2(0x82, 0x0b), 3, gen_move_set },
327*042d53a7SEvalZero { BT_MESH_MODEL_OP_2(0x82, 0x0c), 3, gen_move_set_unack },
328*042d53a7SEvalZero BT_MESH_MODEL_OP_END,
329*042d53a7SEvalZero };
330*042d53a7SEvalZero
331*042d53a7SEvalZero static struct bt_mesh_model root_models[] = {
332*042d53a7SEvalZero BT_MESH_MODEL_CFG_SRV(&cfg_srv),
333*042d53a7SEvalZero BT_MESH_MODEL_HEALTH_SRV(&health_srv, &health_pub),
334*042d53a7SEvalZero BT_MESH_MODEL(BT_MESH_MODEL_ID_GEN_ONOFF_SRV, gen_onoff_op,
335*042d53a7SEvalZero &gen_onoff_pub, NULL),
336*042d53a7SEvalZero BT_MESH_MODEL(BT_MESH_MODEL_ID_GEN_LEVEL_SRV, gen_level_op,
337*042d53a7SEvalZero &gen_level_pub, NULL),
338*042d53a7SEvalZero };
339*042d53a7SEvalZero
340*042d53a7SEvalZero static struct bt_mesh_model_pub vnd_model_pub;
341*042d53a7SEvalZero
vnd_model_recv(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct os_mbuf * buf)342*042d53a7SEvalZero static void vnd_model_recv(struct bt_mesh_model *model,
343*042d53a7SEvalZero struct bt_mesh_msg_ctx *ctx,
344*042d53a7SEvalZero struct os_mbuf *buf)
345*042d53a7SEvalZero {
346*042d53a7SEvalZero struct os_mbuf *msg = NET_BUF_SIMPLE(3);
347*042d53a7SEvalZero
348*042d53a7SEvalZero console_printf("#vendor-model-recv\n");
349*042d53a7SEvalZero
350*042d53a7SEvalZero console_printf("data:%s len:%d\n", bt_hex(buf->om_data, buf->om_len),
351*042d53a7SEvalZero buf->om_len);
352*042d53a7SEvalZero
353*042d53a7SEvalZero bt_mesh_model_msg_init(msg, BT_MESH_MODEL_OP_3(0x01, CID_VENDOR));
354*042d53a7SEvalZero os_mbuf_append(msg, buf->om_data, buf->om_len);
355*042d53a7SEvalZero
356*042d53a7SEvalZero if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) {
357*042d53a7SEvalZero console_printf("#vendor-model-recv: send rsp failed\n");
358*042d53a7SEvalZero }
359*042d53a7SEvalZero
360*042d53a7SEvalZero os_mbuf_free_chain(msg);
361*042d53a7SEvalZero }
362*042d53a7SEvalZero
363*042d53a7SEvalZero static const struct bt_mesh_model_op vnd_model_op[] = {
364*042d53a7SEvalZero { BT_MESH_MODEL_OP_3(0x01, CID_VENDOR), 0, vnd_model_recv },
365*042d53a7SEvalZero BT_MESH_MODEL_OP_END,
366*042d53a7SEvalZero };
367*042d53a7SEvalZero
368*042d53a7SEvalZero static struct bt_mesh_model vnd_models[] = {
369*042d53a7SEvalZero BT_MESH_MODEL_VND(CID_VENDOR, BT_MESH_MODEL_ID_GEN_ONOFF_SRV, vnd_model_op,
370*042d53a7SEvalZero &vnd_model_pub, NULL),
371*042d53a7SEvalZero };
372*042d53a7SEvalZero
373*042d53a7SEvalZero static struct bt_mesh_elem elements[] = {
374*042d53a7SEvalZero BT_MESH_ELEM(0, root_models, vnd_models),
375*042d53a7SEvalZero };
376*042d53a7SEvalZero
377*042d53a7SEvalZero static const struct bt_mesh_comp comp = {
378*042d53a7SEvalZero .cid = CID_VENDOR,
379*042d53a7SEvalZero .elem = elements,
380*042d53a7SEvalZero .elem_count = ARRAY_SIZE(elements),
381*042d53a7SEvalZero };
382*042d53a7SEvalZero
output_number(bt_mesh_output_action_t action,uint32_t number)383*042d53a7SEvalZero static int output_number(bt_mesh_output_action_t action, uint32_t number)
384*042d53a7SEvalZero {
385*042d53a7SEvalZero console_printf("OOB Number: %lu\n", number);
386*042d53a7SEvalZero
387*042d53a7SEvalZero return 0;
388*042d53a7SEvalZero }
389*042d53a7SEvalZero
prov_complete(u16_t net_idx,u16_t addr)390*042d53a7SEvalZero static void prov_complete(u16_t net_idx, u16_t addr)
391*042d53a7SEvalZero {
392*042d53a7SEvalZero console_printf("Local node provisioned, primary address 0x%04x\n", addr);
393*042d53a7SEvalZero }
394*042d53a7SEvalZero
395*042d53a7SEvalZero static const uint8_t dev_uuid[16] = MYNEWT_VAL(BLE_MESH_DEV_UUID);
396*042d53a7SEvalZero
397*042d53a7SEvalZero static const struct bt_mesh_prov prov = {
398*042d53a7SEvalZero .uuid = dev_uuid,
399*042d53a7SEvalZero .output_size = 4,
400*042d53a7SEvalZero .output_actions = BT_MESH_DISPLAY_NUMBER | BT_MESH_BEEP | BT_MESH_VIBRATE | BT_MESH_BLINK,
401*042d53a7SEvalZero .output_number = output_number,
402*042d53a7SEvalZero .complete = prov_complete,
403*042d53a7SEvalZero };
404*042d53a7SEvalZero
405*042d53a7SEvalZero static void
blemesh_on_reset(int reason)406*042d53a7SEvalZero blemesh_on_reset(int reason)
407*042d53a7SEvalZero {
408*042d53a7SEvalZero BLE_HS_LOG(ERROR, "Resetting state; reason=%d\n", reason);
409*042d53a7SEvalZero }
410*042d53a7SEvalZero
411*042d53a7SEvalZero static void
blemesh_on_sync(void)412*042d53a7SEvalZero blemesh_on_sync(void)
413*042d53a7SEvalZero {
414*042d53a7SEvalZero int err;
415*042d53a7SEvalZero ble_addr_t addr;
416*042d53a7SEvalZero
417*042d53a7SEvalZero console_printf("Bluetooth initialized\n");
418*042d53a7SEvalZero
419*042d53a7SEvalZero /* Use NRPA */
420*042d53a7SEvalZero err = ble_hs_id_gen_rnd(1, &addr);
421*042d53a7SEvalZero assert(err == 0);
422*042d53a7SEvalZero err = ble_hs_id_set_rnd(addr.val);
423*042d53a7SEvalZero assert(err == 0);
424*042d53a7SEvalZero
425*042d53a7SEvalZero err = bt_mesh_init(addr.type, &prov, &comp);
426*042d53a7SEvalZero if (err) {
427*042d53a7SEvalZero console_printf("Initializing mesh failed (err %d)\n", err);
428*042d53a7SEvalZero return;
429*042d53a7SEvalZero }
430*042d53a7SEvalZero
431*042d53a7SEvalZero #if (MYNEWT_VAL(BLE_MESH_SHELL))
432*042d53a7SEvalZero shell_register_default_module("mesh");
433*042d53a7SEvalZero #endif
434*042d53a7SEvalZero
435*042d53a7SEvalZero console_printf("Mesh initialized\n");
436*042d53a7SEvalZero
437*042d53a7SEvalZero if (IS_ENABLED(CONFIG_SETTINGS)) {
438*042d53a7SEvalZero settings_load();
439*042d53a7SEvalZero }
440*042d53a7SEvalZero
441*042d53a7SEvalZero if (bt_mesh_is_provisioned()) {
442*042d53a7SEvalZero printk("Mesh network restored from flash\n");
443*042d53a7SEvalZero }
444*042d53a7SEvalZero }
445*042d53a7SEvalZero
446*042d53a7SEvalZero int
main(int argc,char ** argv)447*042d53a7SEvalZero main(int argc, char **argv)
448*042d53a7SEvalZero {
449*042d53a7SEvalZero
450*042d53a7SEvalZero #ifdef ARCH_sim
451*042d53a7SEvalZero mcu_sim_parse_args(argc, argv);
452*042d53a7SEvalZero #endif
453*042d53a7SEvalZero
454*042d53a7SEvalZero /* Initialize OS */
455*042d53a7SEvalZero sysinit();
456*042d53a7SEvalZero
457*042d53a7SEvalZero /* Initialize the NimBLE host configuration. */
458*042d53a7SEvalZero ble_hs_cfg.reset_cb = blemesh_on_reset;
459*042d53a7SEvalZero ble_hs_cfg.sync_cb = blemesh_on_sync;
460*042d53a7SEvalZero ble_hs_cfg.store_status_cb = ble_store_util_status_rr;
461*042d53a7SEvalZero
462*042d53a7SEvalZero hal_gpio_init_out(LED_2, 0);
463*042d53a7SEvalZero
464*042d53a7SEvalZero health_pub_init();
465*042d53a7SEvalZero
466*042d53a7SEvalZero while (1) {
467*042d53a7SEvalZero os_eventq_run(os_eventq_dflt_get());
468*042d53a7SEvalZero }
469*042d53a7SEvalZero return 0;
470*042d53a7SEvalZero }
471