1 /* Bluetooth: Mesh Generic Server Models
2 *
3 * Copyright (c) 2018 Vikrant More
4 * Additional Copyright (c) 2018 Espressif Systems (Shanghai) PTE LTD
5 *
6 * SPDX-License-Identifier: Apache-2.0
7 */
8
9 #include <errno.h>
10
11 #include "btc_ble_mesh_generic_model.h"
12
13 #include "mesh_config.h"
14 #include "access.h"
15 #include "transport.h"
16 #include "model_opcode.h"
17 #include "state_transition.h"
18 #include "device_property.h"
19
20 #if CONFIG_BLE_MESH_GENERIC_SERVER
21
22 static bt_mesh_mutex_t generic_server_lock;
23
bt_mesh_generic_server_mutex_new(void)24 static inline void bt_mesh_generic_server_mutex_new(void)
25 {
26 if (!generic_server_lock.mutex) {
27 bt_mesh_mutex_create(&generic_server_lock);
28 }
29 }
30
31 #if CONFIG_BLE_MESH_DEINIT
bt_mesh_generic_server_mutex_free(void)32 static inline void bt_mesh_generic_server_mutex_free(void)
33 {
34 bt_mesh_mutex_free(&generic_server_lock);
35 }
36 #endif /* CONFIG_BLE_MESH_DEINIT */
37
bt_mesh_generic_server_lock(void)38 void bt_mesh_generic_server_lock(void)
39 {
40 bt_mesh_mutex_lock(&generic_server_lock);
41 }
42
bt_mesh_generic_server_unlock(void)43 void bt_mesh_generic_server_unlock(void)
44 {
45 bt_mesh_mutex_unlock(&generic_server_lock);
46 }
47
48 /* message handlers (Start) */
49
50 /* Generic OnOff Server message handlers */
send_gen_onoff_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,bool publish)51 static void send_gen_onoff_status(struct bt_mesh_model *model,
52 struct bt_mesh_msg_ctx *ctx,
53 bool publish)
54 {
55 struct bt_mesh_gen_onoff_srv *srv = model->user_data;
56 struct net_buf_simple *msg = NULL;
57 uint8_t length = 2 + 3;
58
59 if (ctx == NULL && publish == false) {
60 BT_ERR("%s, Invalid parameter", __func__);
61 return;
62 }
63
64 if (publish == false) {
65 msg = bt_mesh_alloc_buf(length + BLE_MESH_SERVER_TRANS_MIC_SIZE);
66 if (msg == NULL) {
67 BT_ERR("%s, Out of memory", __func__);
68 return;
69 }
70 } else {
71 msg = bt_mesh_server_get_pub_msg(model, length);
72 if (msg == NULL) {
73 return;
74 }
75 }
76
77 bt_mesh_model_msg_init(msg, BLE_MESH_MODEL_OP_GEN_ONOFF_STATUS);
78 net_buf_simple_add_u8(msg, srv->state.onoff);
79 if (srv->transition.counter) {
80 bt_mesh_server_calc_remain_time(&srv->transition);
81 net_buf_simple_add_u8(msg, srv->state.target_onoff);
82 net_buf_simple_add_u8(msg, srv->transition.remain_time);
83 }
84
85 if (publish == false) {
86 BLE_MESH_CHECK_SEND_STATUS(bt_mesh_model_send(model, ctx, msg, NULL, NULL));
87 bt_mesh_free_buf(msg);
88 } else {
89 BLE_MESH_CHECK_SEND_STATUS(bt_mesh_model_publish(model));
90 }
91 return;
92 }
93
gen_onoff_get(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)94 static void gen_onoff_get(struct bt_mesh_model *model,
95 struct bt_mesh_msg_ctx *ctx,
96 struct net_buf_simple *buf)
97 {
98 struct bt_mesh_gen_onoff_srv *srv = model->user_data;
99
100 if (srv == NULL) {
101 BT_ERR("%s, Invalid model user data", __func__);
102 return;
103 }
104
105 /* Callback the received message to the application layer */
106 if (srv->rsp_ctrl.get_auto_rsp == BLE_MESH_SERVER_RSP_BY_APP) {
107 bt_mesh_generic_server_cb_evt_to_btc(
108 BTC_BLE_MESH_EVT_GENERIC_SERVER_RECV_GET_MSG, model, ctx, NULL, 0);
109 return;
110 }
111
112 send_gen_onoff_status(model, ctx, false);
113 return;
114 }
115
gen_onoff_publish(struct bt_mesh_model * model)116 void gen_onoff_publish(struct bt_mesh_model *model)
117 {
118 if (model->user_data == NULL) {
119 BT_ERR("%s, Invalid model user data", __func__);
120 return;
121 }
122
123 send_gen_onoff_status(model, NULL, true);
124 return;
125 }
126
gen_onoff_set(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)127 static void gen_onoff_set(struct bt_mesh_model *model,
128 struct bt_mesh_msg_ctx *ctx,
129 struct net_buf_simple *buf)
130 {
131 struct bt_mesh_gen_onoff_srv *srv = model->user_data;
132 uint8_t tid = 0U, onoff = 0U, trans_time = 0U, delay = 0U;
133 bool optional = false;
134 int64_t now = 0;
135
136 if (srv == NULL) {
137 BT_ERR("%s, Invalid model user data", __func__);
138 return;
139 }
140
141 onoff = net_buf_simple_pull_u8(buf);
142 if (onoff > BLE_MESH_STATE_ON) {
143 BT_ERR("Invalid OnOff value 0x%02x", onoff);
144 return;
145 }
146 tid = net_buf_simple_pull_u8(buf);
147
148 if (bt_mesh_server_get_optional(model, ctx, buf, &trans_time, &delay, &optional)) {
149 return;
150 }
151
152 /* Callback the received message to the application layer */
153 if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_RSP_BY_APP) {
154 bt_mesh_gen_server_recv_set_msg_t set = {
155 .onoff_set.op_en = optional,
156 .onoff_set.onoff = onoff,
157 .onoff_set.tid = tid,
158 .onoff_set.trans_time = trans_time,
159 .onoff_set.delay = delay,
160 };
161 bt_mesh_generic_server_cb_evt_to_btc(
162 BTC_BLE_MESH_EVT_GENERIC_SERVER_RECV_SET_MSG, model, ctx, (const uint8_t *)&set, sizeof(set));
163 return;
164 }
165
166 if (bt_mesh_is_server_recv_last_msg(&srv->last, tid, ctx->addr, ctx->recv_dst, &now)) {
167 if (ctx->recv_op == BLE_MESH_MODEL_OP_GEN_ONOFF_SET) {
168 send_gen_onoff_status(model, ctx, false);
169 }
170 send_gen_onoff_status(model, NULL, true);
171 /* In this condition, no event will be callback to application layer */
172 return;
173 }
174
175 bt_mesh_generic_server_lock();
176
177 bt_mesh_server_stop_transition(&srv->transition);
178 bt_mesh_server_update_last_msg(&srv->last, tid, ctx->addr, ctx->recv_dst, &now);
179
180 srv->state.target_onoff = onoff;
181
182 if (srv->state.target_onoff != srv->state.onoff) {
183 generic_onoff_tt_values(srv, trans_time, delay);
184 } else {
185 bt_mesh_gen_server_state_change_t change = {
186 .gen_onoff_set.onoff = srv->state.onoff,
187 };
188 bt_mesh_generic_server_cb_evt_to_btc(
189 BTC_BLE_MESH_EVT_GENERIC_SERVER_STATE_CHANGE, model, ctx, (const uint8_t *)&change, sizeof(change));
190
191 if (ctx->recv_op == BLE_MESH_MODEL_OP_GEN_ONOFF_SET) {
192 send_gen_onoff_status(model, ctx, false);
193 }
194 send_gen_onoff_status(model, NULL, true);
195
196 bt_mesh_generic_server_unlock();
197 return;
198 }
199
200 /* Copy the ctx of the received message */
201 if (srv->transition.timer.work._reserved) {
202 memcpy(srv->transition.timer.work._reserved, ctx, sizeof(struct bt_mesh_msg_ctx));
203 }
204
205 /* For Instantaneous Transition */
206 if (srv->transition.counter == 0U) {
207 srv->state.onoff = srv->state.target_onoff;
208 }
209
210 srv->transition.just_started = true;
211 if (ctx->recv_op == BLE_MESH_MODEL_OP_GEN_ONOFF_SET) {
212 send_gen_onoff_status(model, ctx, false);
213 }
214 send_gen_onoff_status(model, NULL, true);
215
216 bt_mesh_generic_server_unlock();
217
218 bt_mesh_server_start_transition(&srv->transition);
219 return;
220 }
221
222 /* Generic Level Server message handlers */
send_gen_level_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,bool publish)223 static void send_gen_level_status(struct bt_mesh_model *model,
224 struct bt_mesh_msg_ctx *ctx,
225 bool publish)
226 {
227 struct bt_mesh_gen_level_srv *srv = model->user_data;
228 struct net_buf_simple *msg = NULL;
229 uint8_t length = 2 + 5;
230
231 if (ctx == NULL && publish == false) {
232 BT_ERR("%s, Invalid parameter", __func__);
233 return;
234 }
235
236 if (publish == false) {
237 msg = bt_mesh_alloc_buf(length + BLE_MESH_SERVER_TRANS_MIC_SIZE);
238 if (msg == NULL) {
239 BT_ERR("%s, Out of memory", __func__);
240 return;
241 }
242 } else {
243 msg = bt_mesh_server_get_pub_msg(model, length);
244 if (msg == NULL) {
245 return;
246 }
247 }
248
249 bt_mesh_model_msg_init(msg, BLE_MESH_MODEL_OP_GEN_LEVEL_STATUS);
250 net_buf_simple_add_le16(msg, srv->state.level);
251 if (srv->transition.counter) {
252 if (srv->state.move_start) {
253 if (srv->state.positive) {
254 net_buf_simple_add_le16(msg, INT16_MAX);
255 } else { /* 0 should not be possible */
256 net_buf_simple_add_le16(msg, INT16_MIN);
257 }
258 net_buf_simple_add_u8(msg, BLE_MESH_UNKNOWN_REMAIN_TIME);
259 } else {
260 bt_mesh_server_calc_remain_time(&srv->transition);
261 net_buf_simple_add_le16(msg, srv->state.target_level);
262 net_buf_simple_add_u8(msg, srv->transition.remain_time);
263 }
264 }
265
266 if (publish == false) {
267 BLE_MESH_CHECK_SEND_STATUS(bt_mesh_model_send(model, ctx, msg, NULL, NULL));
268 bt_mesh_free_buf(msg);
269 } else {
270 BLE_MESH_CHECK_SEND_STATUS(bt_mesh_model_publish(model));
271 }
272 return;
273 }
274
gen_level_get(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)275 static void gen_level_get(struct bt_mesh_model *model,
276 struct bt_mesh_msg_ctx *ctx,
277 struct net_buf_simple *buf)
278 {
279 struct bt_mesh_gen_level_srv *srv = model->user_data;
280
281 if (srv == NULL) {
282 BT_ERR("%s, Invalid model user data", __func__);
283 return;
284 }
285
286 /* Callback the received message to the application layer */
287 if (srv->rsp_ctrl.get_auto_rsp == BLE_MESH_SERVER_RSP_BY_APP) {
288 bt_mesh_generic_server_cb_evt_to_btc(
289 BTC_BLE_MESH_EVT_GENERIC_SERVER_RECV_GET_MSG, model, ctx, NULL, 0);
290 return;
291 }
292
293 send_gen_level_status(model, ctx, false);
294 return;
295 }
296
gen_level_publish(struct bt_mesh_model * model)297 void gen_level_publish(struct bt_mesh_model *model)
298 {
299 if (model->user_data == NULL) {
300 BT_ERR("%s, Invalid model user data", __func__);
301 return;
302 }
303
304 send_gen_level_status(model, NULL, true);
305 return;
306 }
307
gen_level_set(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)308 static void gen_level_set(struct bt_mesh_model *model,
309 struct bt_mesh_msg_ctx *ctx,
310 struct net_buf_simple *buf)
311 {
312 struct bt_mesh_gen_level_srv *srv = model->user_data;
313 uint8_t tid = 0U, trans_time = 0U, delay = 0U;
314 bool optional = false;
315 int16_t level = 0;
316 int64_t now = 0;
317
318 if (srv == NULL) {
319 BT_ERR("%s, Invalid model user data", __func__);
320 return;
321 }
322
323 level = (int16_t) net_buf_simple_pull_le16(buf);
324 tid = net_buf_simple_pull_u8(buf);
325
326 if (bt_mesh_server_get_optional(model, ctx, buf, &trans_time, &delay, &optional)) {
327 return;
328 }
329
330 /* Callback the received message to the application layer */
331 if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_RSP_BY_APP) {
332 bt_mesh_gen_server_recv_set_msg_t set = {
333 .level_set.op_en = optional,
334 .level_set.level = level,
335 .level_set.tid = tid,
336 .level_set.trans_time = trans_time,
337 .level_set.delay = delay,
338 };
339 bt_mesh_generic_server_cb_evt_to_btc(
340 BTC_BLE_MESH_EVT_GENERIC_SERVER_RECV_SET_MSG, model, ctx, (const uint8_t *)&set, sizeof(set));
341 return;
342 }
343
344 if (bt_mesh_is_server_recv_last_msg(&srv->last, tid, ctx->addr, ctx->recv_dst, &now)) {
345 if (ctx->recv_op == BLE_MESH_MODEL_OP_GEN_LEVEL_SET) {
346 send_gen_level_status(model, ctx, false);
347 }
348 send_gen_level_status(model, NULL, true);
349 /* In this condition, no event will be callback to application layer */
350 return;
351 }
352
353 bt_mesh_generic_server_lock();
354
355 bt_mesh_server_stop_transition(&srv->transition);
356 bt_mesh_server_update_last_msg(&srv->last, tid, ctx->addr, ctx->recv_dst, &now);
357
358 srv->state.target_level = level;
359
360 /**
361 * If the target state is equal to the current state, the transition
362 * shall not be started and is considered complete.
363 */
364 if (srv->state.target_level != srv->state.level) {
365 generic_level_tt_values(srv, trans_time, delay);
366 } else {
367 bt_mesh_gen_server_state_change_t change = {
368 .gen_level_set.level = srv->state.level,
369 };
370 bt_mesh_generic_server_cb_evt_to_btc(
371 BTC_BLE_MESH_EVT_GENERIC_SERVER_STATE_CHANGE, model, ctx, (const uint8_t *)&change, sizeof(change));
372
373 if (ctx->recv_op == BLE_MESH_MODEL_OP_GEN_LEVEL_SET) {
374 send_gen_level_status(model, ctx, false);
375 }
376 send_gen_level_status(model, NULL, true);
377
378 bt_mesh_generic_server_unlock();
379 return;
380 }
381
382 /* Copy the ctx of the received message */
383 if (srv->transition.timer.work._reserved) {
384 memcpy(srv->transition.timer.work._reserved, ctx, sizeof(struct bt_mesh_msg_ctx));
385 }
386
387 /* For Instantaneous Transition */
388 if (srv->transition.counter == 0U) {
389 srv->state.level = srv->state.target_level;
390 }
391
392 srv->transition.just_started = true;
393 if (ctx->recv_op == BLE_MESH_MODEL_OP_GEN_LEVEL_SET) {
394 send_gen_level_status(model, ctx, false);
395 }
396 send_gen_level_status(model, NULL, true);
397
398 bt_mesh_generic_server_unlock();
399
400 bt_mesh_server_start_transition(&srv->transition);
401 return;
402 }
403
gen_delta_set(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)404 static void gen_delta_set(struct bt_mesh_model *model,
405 struct bt_mesh_msg_ctx *ctx,
406 struct net_buf_simple *buf)
407 {
408 struct bt_mesh_gen_level_srv *srv = model->user_data;
409 uint8_t tid = 0U, trans_time = 0U, delay = 0U;
410 int32_t tmp32 = 0, delta = 0;
411 bool optional = false;
412 int64_t now = 0;
413
414 if (srv == NULL) {
415 BT_ERR("%s, Invalid model user data", __func__);
416 return;
417 }
418
419 delta = (int32_t)net_buf_simple_pull_le32(buf);
420 tid = net_buf_simple_pull_u8(buf);
421
422 if (bt_mesh_server_get_optional(model, ctx, buf, &trans_time, &delay, &optional)) {
423 return;
424 }
425
426 /* Callback the received message to the application layer */
427 if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_RSP_BY_APP) {
428 bt_mesh_gen_server_recv_set_msg_t set = {
429 .delta_set.op_en = optional,
430 .delta_set.delta_level = delta,
431 .delta_set.tid = tid,
432 .delta_set.trans_time = trans_time,
433 .delta_set.delay = delay,
434 };
435 bt_mesh_generic_server_cb_evt_to_btc(
436 BTC_BLE_MESH_EVT_GENERIC_SERVER_RECV_SET_MSG, model, ctx, (const uint8_t *)&set, sizeof(set));
437 return;
438 }
439
440 /**
441 * A number of Generic Delta Set and Generic Delta Set Unacknowledged
442 * messages with the same transaction identifier set in the TID field
443 * may be sent.
444 *
445 * A new transaction starts when the TID field value in the received
446 * message is different from the TID field value in the previously
447 * received message that was using the same source and destination
448 * addresses or from the most recently received message with the same
449 * TID field value that was received 6 or more seconds earlier.
450 */
451 if (bt_mesh_is_server_recv_last_msg(&srv->last, tid, ctx->addr, ctx->recv_dst, &now)) {
452 if (srv->state.last_delta == delta) {
453 if (ctx->recv_op == BLE_MESH_MODEL_OP_GEN_DELTA_SET) {
454 send_gen_level_status(model, ctx, false);
455 }
456 send_gen_level_status(model, NULL, true);
457 /* In this condition, no event will be callback to application layer */
458 return;
459 }
460
461 tmp32 = srv->state.last_level + delta;
462 } else {
463 /* Starts a new transaction */
464 srv->state.last_level = srv->state.level;
465 tmp32 = srv->state.level + delta;
466 }
467
468 bt_mesh_generic_server_lock();
469
470 bt_mesh_server_stop_transition(&srv->transition);
471 bt_mesh_server_update_last_msg(&srv->last, tid, ctx->addr, ctx->recv_dst, &now);
472
473 srv->state.last_delta = delta;
474 if (tmp32 < INT16_MIN) {
475 tmp32 = INT16_MIN;
476 } else if (tmp32 > INT16_MAX) {
477 tmp32 = INT16_MAX;
478 }
479 srv->state.target_level = tmp32;
480
481 /**
482 * If the target state is equal to the current state, the transition
483 * shall not be started and is considered complete.
484 */
485 if (srv->state.target_level != srv->state.level) {
486 generic_level_tt_values(srv, trans_time, delay);
487 } else {
488 bt_mesh_gen_server_state_change_t change = {
489 .gen_delta_set.level = srv->state.level,
490 };
491 bt_mesh_generic_server_cb_evt_to_btc(
492 BTC_BLE_MESH_EVT_GENERIC_SERVER_STATE_CHANGE, model, ctx, (const uint8_t *)&change, sizeof(change));
493
494 if (ctx->recv_op == BLE_MESH_MODEL_OP_GEN_DELTA_SET) {
495 send_gen_level_status(model, ctx, false);
496 }
497 send_gen_level_status(model, NULL, true);
498
499 bt_mesh_generic_server_unlock();
500 return;
501 }
502
503 /* Copy the ctx of the received message */
504 if (srv->transition.timer.work._reserved) {
505 memcpy(srv->transition.timer.work._reserved, ctx, sizeof(struct bt_mesh_msg_ctx));
506 }
507
508 /* For Instantaneous Transition */
509 if (srv->transition.counter == 0U) {
510 srv->state.level = srv->state.target_level;
511 }
512
513 srv->transition.just_started = true;
514 if (ctx->recv_op == BLE_MESH_MODEL_OP_GEN_DELTA_SET) {
515 send_gen_level_status(model, ctx, false);
516 }
517 send_gen_level_status(model, NULL, true);
518
519 bt_mesh_generic_server_unlock();
520
521 bt_mesh_server_start_transition(&srv->transition);
522 return;
523 }
524
gen_move_set(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)525 static void gen_move_set(struct bt_mesh_model *model,
526 struct bt_mesh_msg_ctx *ctx,
527 struct net_buf_simple *buf)
528 {
529 struct bt_mesh_gen_level_srv *srv = model->user_data;
530 uint8_t tid = 0U, trans_time = 0U, delay = 0U;
531 bool optional = false;
532 int16_t delta = 0;
533 int32_t tmp32 = 0;
534 int64_t now = 0;
535
536 if (srv == NULL) {
537 BT_ERR("%s, Invalid model user data", __func__);
538 return;
539 }
540
541 delta = (int16_t) net_buf_simple_pull_le16(buf);
542 tid = net_buf_simple_pull_u8(buf);
543
544 if (bt_mesh_server_get_optional(model, ctx, buf, &trans_time, &delay, &optional)) {
545 return;
546 }
547
548 /* Callback the received message to the application layer */
549 if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_RSP_BY_APP) {
550 bt_mesh_gen_server_recv_set_msg_t set = {
551 .move_set.op_en = optional,
552 .move_set.delta_level = delta,
553 .move_set.tid = tid,
554 .move_set.trans_time = trans_time,
555 .move_set.delay = delay,
556 };
557 bt_mesh_generic_server_cb_evt_to_btc(
558 BTC_BLE_MESH_EVT_GENERIC_SERVER_RECV_SET_MSG, model, ctx, (const uint8_t *)&set, sizeof(set));
559 return;
560 }
561
562 if (bt_mesh_is_server_recv_last_msg(&srv->last, tid, ctx->addr, ctx->recv_dst, &now)) {
563 if (ctx->recv_op == BLE_MESH_MODEL_OP_GEN_MOVE_SET) {
564 send_gen_level_status(model, ctx, false);
565 }
566 send_gen_level_status(model, NULL, true);
567 /* In this condition, no event will be callback to application layer */
568 return;
569 }
570
571 bt_mesh_generic_server_lock();
572
573 bt_mesh_server_stop_transition(&srv->transition);
574 bt_mesh_server_update_last_msg(&srv->last, tid, ctx->addr, ctx->recv_dst, &now);
575
576 srv->state.last_delta = delta;
577
578 tmp32 = srv->state.level + delta;
579 if (tmp32 < INT16_MIN) {
580 tmp32 = INT16_MIN;
581 } else if (tmp32 > INT16_MAX) {
582 tmp32 = INT16_MAX;
583 }
584 srv->state.target_level = tmp32;
585
586 /**
587 * If the target state is equal to the current state, the transition
588 * shall not be started and is considered complete.
589 */
590 if (srv->state.target_level != srv->state.level) {
591 generic_level_tt_values(srv, trans_time, delay);
592 } else {
593 bt_mesh_gen_server_state_change_t change = {
594 .gen_move_set.level = srv->state.level,
595 };
596 bt_mesh_generic_server_cb_evt_to_btc(
597 BTC_BLE_MESH_EVT_GENERIC_SERVER_STATE_CHANGE, model, ctx, (const uint8_t *)&change, sizeof(change));
598
599 if (ctx->recv_op == BLE_MESH_MODEL_OP_GEN_MOVE_SET) {
600 send_gen_level_status(model, ctx, false);
601 }
602 send_gen_level_status(model, NULL, true);
603 srv->state.move_start = false;
604
605 bt_mesh_generic_server_unlock();
606 return;
607 }
608
609 /* Copy the ctx of the received message */
610 if (srv->transition.timer.work._reserved) {
611 memcpy(srv->transition.timer.work._reserved, ctx, sizeof(struct bt_mesh_msg_ctx));
612 }
613
614 if (delta) {
615 srv->state.move_start = true;
616 srv->state.positive = (delta > 0) ? true : false;
617 }
618
619 srv->transition.just_started = true;
620 if (ctx->recv_op == BLE_MESH_MODEL_OP_GEN_MOVE_SET) {
621 send_gen_level_status(model, ctx, false);
622 }
623 send_gen_level_status(model, NULL, true);
624
625 bt_mesh_generic_server_unlock();
626
627 /**
628 * If (trans_time == 0) OR (delta == 0)
629 * 1. If the resulting Transition Time is equal to 0 or is undefined,
630 * the Generic Move Set command will not initiate any Generic Level
631 * state change.
632 * 2. When a Generic Level Server receives the message with a value of
633 * the Delta Level field equal to 0, it shall stop changing the
634 * Generic Level state. (if delta == 0, srv->state.target_level will
635 * equal to srv->state.level)
636 */
637 if (srv->transition.counter == 0U) {
638 srv->state.move_start = false;
639 bt_mesh_gen_server_state_change_t change = {
640 .gen_move_set.level = srv->state.level,
641 };
642 bt_mesh_generic_server_cb_evt_to_btc(
643 BTC_BLE_MESH_EVT_GENERIC_SERVER_STATE_CHANGE, model, ctx, (const uint8_t *)&change, sizeof(change));
644 return;
645 }
646
647 bt_mesh_server_start_transition(&srv->transition);
648 return;
649 }
650
651 /* Generic Default Transition Time Server message handlers */
send_gen_def_trans_time_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,bool publish)652 static void send_gen_def_trans_time_status(struct bt_mesh_model *model,
653 struct bt_mesh_msg_ctx *ctx,
654 bool publish)
655 {
656 struct bt_mesh_gen_def_trans_time_srv *srv = model->user_data;
657 struct net_buf_simple *msg = NULL;
658 uint8_t length = 2 + 1;
659
660 if (ctx == NULL && publish == false) {
661 BT_ERR("%s, Invalid parameter", __func__);
662 return;
663 }
664
665 if (publish == false) {
666 msg = bt_mesh_alloc_buf(length + BLE_MESH_SERVER_TRANS_MIC_SIZE);
667 if (msg == NULL) {
668 BT_ERR("%s, Out of memory", __func__);
669 return;
670 }
671 } else {
672 msg = bt_mesh_server_get_pub_msg(model, length);
673 if (msg == NULL) {
674 return;
675 }
676 }
677
678 bt_mesh_model_msg_init(msg, BLE_MESH_MODEL_OP_GEN_DEF_TRANS_TIME_STATUS);
679 net_buf_simple_add_u8(msg, srv->state.trans_time);
680
681 if (publish == false) {
682 BLE_MESH_CHECK_SEND_STATUS(bt_mesh_model_send(model, ctx, msg, NULL, NULL));
683 bt_mesh_free_buf(msg);
684 } else {
685 BLE_MESH_CHECK_SEND_STATUS(bt_mesh_model_publish(model));
686 }
687 return;
688 }
689
gen_def_trans_time_get(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)690 static void gen_def_trans_time_get(struct bt_mesh_model *model,
691 struct bt_mesh_msg_ctx *ctx,
692 struct net_buf_simple *buf)
693 {
694 struct bt_mesh_gen_def_trans_time_srv *srv = model->user_data;
695
696 if (srv == NULL) {
697 BT_ERR("%s, Invalid model user data", __func__);
698 return;
699 }
700
701 /* Callback the received message to the application layer */
702 if (srv->rsp_ctrl.get_auto_rsp == BLE_MESH_SERVER_RSP_BY_APP) {
703 bt_mesh_generic_server_cb_evt_to_btc(
704 BTC_BLE_MESH_EVT_GENERIC_SERVER_RECV_GET_MSG, model, ctx, NULL, 0);
705 return;
706 }
707
708 send_gen_def_trans_time_status(model, ctx, false);
709 return;
710 }
711
gen_def_trans_time_set(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)712 static void gen_def_trans_time_set(struct bt_mesh_model *model,
713 struct bt_mesh_msg_ctx *ctx,
714 struct net_buf_simple *buf)
715 {
716 struct bt_mesh_gen_def_trans_time_srv *srv = model->user_data;
717 uint8_t trans_time = 0U;
718
719 if (srv == NULL) {
720 BT_ERR("%s, Invalid model user data", __func__);
721 return;
722 }
723
724 trans_time = net_buf_simple_pull_u8(buf);
725 if ((trans_time & 0x3F) == 0x3F) {
726 BT_WARN("Invalid Transaction Number of Steps 0x3f");
727 return;
728 }
729
730 /* Callback the received message to the application layer */
731 if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_RSP_BY_APP) {
732 bt_mesh_gen_server_recv_set_msg_t set = {
733 .def_trans_time_set.trans_time = trans_time,
734 };
735 bt_mesh_generic_server_cb_evt_to_btc(
736 BTC_BLE_MESH_EVT_GENERIC_SERVER_RECV_SET_MSG, model, ctx, (const uint8_t *)&set, sizeof(set));
737 return;
738 }
739
740 if (srv->state.trans_time != trans_time) {
741 srv->state.trans_time = trans_time;
742 }
743
744 bt_mesh_gen_server_state_change_t change = {
745 .gen_def_trans_time_set.trans_time = trans_time,
746 };
747 bt_mesh_generic_server_cb_evt_to_btc(
748 BTC_BLE_MESH_EVT_GENERIC_SERVER_STATE_CHANGE, model, ctx, (const uint8_t *)&change, sizeof(change));
749
750 if (ctx->recv_op == BLE_MESH_MODEL_OP_GEN_DEF_TRANS_TIME_SET) {
751 send_gen_def_trans_time_status(model, ctx, false);
752 }
753 send_gen_def_trans_time_status(model, NULL, true);
754
755 return;
756 }
757
758 /* Generic Power OnOff Server message handlers */
send_gen_onpowerup_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,bool publish)759 static void send_gen_onpowerup_status(struct bt_mesh_model *model,
760 struct bt_mesh_msg_ctx *ctx,
761 bool publish)
762 {
763 struct net_buf_simple *msg = NULL;
764 uint8_t length = 2 + 1;
765
766 if (ctx == NULL && publish == false) {
767 BT_ERR("%s, Invalid parameter", __func__);
768 return;
769 }
770
771 if (publish == false) {
772 msg = bt_mesh_alloc_buf(length + BLE_MESH_SERVER_TRANS_MIC_SIZE);
773 if (msg == NULL) {
774 BT_ERR("%s, Out of memory", __func__);
775 return;
776 }
777 } else {
778 msg = bt_mesh_server_get_pub_msg(model, length);
779 if (msg == NULL) {
780 return;
781 }
782 }
783
784 bt_mesh_model_msg_init(msg, BLE_MESH_MODEL_OP_GEN_ONPOWERUP_STATUS);
785 switch (model->id) {
786 case BLE_MESH_MODEL_ID_GEN_POWER_ONOFF_SRV: {
787 struct bt_mesh_gen_power_onoff_srv *srv = model->user_data;
788 net_buf_simple_add_u8(msg, srv->state->onpowerup);
789 break;
790 }
791 case BLE_MESH_MODEL_ID_GEN_POWER_ONOFF_SETUP_SRV: {
792 struct bt_mesh_gen_power_onoff_setup_srv *srv = model->user_data;
793 net_buf_simple_add_u8(msg, srv->state->onpowerup);
794 break;
795 }
796 default:
797 BT_ERR("Invalid Generic Power OnOff Server 0x%04x", model->id);
798 if (publish == false) {
799 bt_mesh_free_buf(msg);
800 }
801 return;
802 }
803
804 if (publish == false) {
805 BLE_MESH_CHECK_SEND_STATUS(bt_mesh_model_send(model, ctx, msg, NULL, NULL));
806 bt_mesh_free_buf(msg);
807 } else {
808 BLE_MESH_CHECK_SEND_STATUS(bt_mesh_model_publish(model));
809 }
810 return;
811 }
812
gen_onpowerup_get(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)813 static void gen_onpowerup_get(struct bt_mesh_model *model,
814 struct bt_mesh_msg_ctx *ctx,
815 struct net_buf_simple *buf)
816 {
817 struct bt_mesh_gen_power_onoff_srv *srv = model->user_data;
818
819 if (srv == NULL || srv->state == NULL) {
820 BT_ERR("%s, Invalid model user data", __func__);
821 return;
822 }
823
824 /* Callback the received message to the application layer */
825 if (srv->rsp_ctrl.get_auto_rsp == BLE_MESH_SERVER_RSP_BY_APP) {
826 bt_mesh_generic_server_cb_evt_to_btc(
827 BTC_BLE_MESH_EVT_GENERIC_SERVER_RECV_GET_MSG, model, ctx, NULL, 0);
828 return;
829 }
830
831 send_gen_onpowerup_status(model, ctx, false);
832 return;
833 }
834
835 /* Generic Power OnOff Setup Server message handlers */
gen_onpowerup_publish(struct bt_mesh_model * model)836 void gen_onpowerup_publish(struct bt_mesh_model *model)
837 {
838 if (model->user_data == NULL) {
839 BT_ERR("%s, Invalid model user data", __func__);
840 return;
841 }
842
843 switch (model->id) {
844 case BLE_MESH_MODEL_ID_GEN_POWER_ONOFF_SRV: {
845 struct bt_mesh_gen_power_onoff_srv *srv = model->user_data;
846 if (srv->state == NULL) {
847 BT_ERR("Invalid Generic Power OnOff Server state");
848 return;
849 }
850 break;
851 }
852 case BLE_MESH_MODEL_ID_GEN_POWER_ONOFF_SETUP_SRV: {
853 struct bt_mesh_gen_power_onoff_setup_srv *srv = model->user_data;
854 if (srv->state == NULL) {
855 BT_ERR("Invalid Generic Power OnOff Setup Server state");
856 return;
857 }
858 break;
859 }
860 default:
861 BT_ERR("Invalid Generic Power OnOff Server 0x%04x", model->id);
862 return;
863 }
864
865 send_gen_onpowerup_status(model, NULL, true);
866 return;
867 }
868
gen_onpowerup_set(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)869 static void gen_onpowerup_set(struct bt_mesh_model *model,
870 struct bt_mesh_msg_ctx *ctx,
871 struct net_buf_simple *buf)
872 {
873 struct bt_mesh_gen_power_onoff_setup_srv *srv = model->user_data;
874 uint8_t onpowerup = 0U;
875
876 if (srv == NULL || srv->state == NULL) {
877 BT_ERR("%s, Invalid model user data", __func__);
878 return;
879 }
880
881 onpowerup = net_buf_simple_pull_u8(buf);
882 if (onpowerup > BLE_MESH_STATE_RESTORE) {
883 BT_WARN("Invalid OnPowerUp value 0x%02x", onpowerup);
884 return;
885 }
886
887 /* Callback the received message to the application layer */
888 if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_RSP_BY_APP) {
889 bt_mesh_gen_server_recv_set_msg_t set = {
890 .onpowerup_set.onpowerup = onpowerup,
891 };
892 bt_mesh_generic_server_cb_evt_to_btc(
893 BTC_BLE_MESH_EVT_GENERIC_SERVER_RECV_SET_MSG, model, ctx, (const uint8_t *)&set, sizeof(set));
894 return;
895 }
896
897 if (srv->state->onpowerup != onpowerup) {
898 srv->state->onpowerup = onpowerup;
899 }
900
901 bt_mesh_gen_server_state_change_t change = {
902 .gen_onpowerup_set.onpowerup = onpowerup,
903 };
904 bt_mesh_generic_server_cb_evt_to_btc(
905 BTC_BLE_MESH_EVT_GENERIC_SERVER_STATE_CHANGE, model, ctx, (const uint8_t *)&change, sizeof(change));
906
907 if (ctx->recv_op == BLE_MESH_MODEL_OP_GEN_ONPOWERUP_SET) {
908 send_gen_onpowerup_status(model, ctx, false);
909 }
910 send_gen_onpowerup_status(model, NULL, true);
911
912 return;
913 }
914
915 /* Generic Power Level Server message handlers */
send_gen_power_level_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,bool publish,uint16_t opcode)916 static void send_gen_power_level_status(struct bt_mesh_model *model,
917 struct bt_mesh_msg_ctx *ctx,
918 bool publish, uint16_t opcode)
919 {
920 struct net_buf_simple *msg = NULL;
921 uint8_t length = 2 + 5;
922
923 if (ctx == NULL && publish == false) {
924 BT_ERR("%s, Invalid parameter", __func__);
925 return;
926 }
927
928 if (publish == false) {
929 msg = bt_mesh_alloc_buf(length + BLE_MESH_SERVER_TRANS_MIC_SIZE);
930 if (msg == NULL) {
931 BT_ERR("%s, Out of memory", __func__);
932 return;
933 }
934 } else {
935 msg = bt_mesh_server_get_pub_msg(model, length);
936 if (msg == NULL) {
937 return;
938 }
939 }
940
941 bt_mesh_model_msg_init(msg, opcode);
942 switch (opcode) {
943 case BLE_MESH_MODEL_OP_GEN_POWER_LEVEL_STATUS:
944 case BLE_MESH_MODEL_OP_GEN_POWER_LAST_STATUS: {
945 struct bt_mesh_gen_power_level_srv *srv = model->user_data;
946 if (opcode == BLE_MESH_MODEL_OP_GEN_POWER_LEVEL_STATUS) {
947 net_buf_simple_add_le16(msg, srv->state->power_actual);
948 if (srv->transition.counter) {
949 bt_mesh_server_calc_remain_time(&srv->transition);
950 net_buf_simple_add_le16(msg, srv->state->target_power_actual);
951 net_buf_simple_add_u8(msg, srv->transition.remain_time);
952 }
953 } else if (opcode == BLE_MESH_MODEL_OP_GEN_POWER_LAST_STATUS) {
954 net_buf_simple_add_le16(msg, srv->state->power_last);
955 }
956 break;
957 }
958 case BLE_MESH_MODEL_OP_GEN_POWER_DEFAULT_STATUS:
959 if (model->id == BLE_MESH_MODEL_ID_GEN_POWER_LEVEL_SRV) {
960 struct bt_mesh_gen_power_level_srv *srv = model->user_data;
961 net_buf_simple_add_le16(msg, srv->state->power_default);
962 } else if (model->id == BLE_MESH_MODEL_ID_GEN_POWER_LEVEL_SETUP_SRV) {
963 struct bt_mesh_gen_power_level_setup_srv *srv = model->user_data;
964 net_buf_simple_add_le16(msg, srv->state->power_default);
965 }
966 break;
967 case BLE_MESH_MODEL_OP_GEN_POWER_RANGE_STATUS:
968 if (model->id == BLE_MESH_MODEL_ID_GEN_POWER_LEVEL_SRV) {
969 struct bt_mesh_gen_power_level_srv *srv = model->user_data;
970 net_buf_simple_add_u8(msg, srv->state->status_code);
971 net_buf_simple_add_le16(msg, srv->state->power_range_min);
972 net_buf_simple_add_le16(msg, srv->state->power_range_max);
973 } else if (model->id == BLE_MESH_MODEL_ID_GEN_POWER_LEVEL_SETUP_SRV) {
974 struct bt_mesh_gen_power_level_setup_srv *srv = model->user_data;
975 net_buf_simple_add_u8(msg, srv->state->status_code);
976 net_buf_simple_add_le16(msg, srv->state->power_range_min);
977 net_buf_simple_add_le16(msg, srv->state->power_range_max);
978 }
979 break;
980 default:
981 BT_WARN("Unknown Generic Power status opcode 0x%04x", opcode);
982 if (publish == false) {
983 bt_mesh_free_buf(msg);
984 }
985 return;
986 }
987
988 if (publish == false) {
989 BLE_MESH_CHECK_SEND_STATUS(bt_mesh_model_send(model, ctx, msg, NULL, NULL));
990 bt_mesh_free_buf(msg);
991 } else {
992 BLE_MESH_CHECK_SEND_STATUS(bt_mesh_model_publish(model));
993 }
994 return;
995 }
996
gen_power_level_get(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)997 static void gen_power_level_get(struct bt_mesh_model *model,
998 struct bt_mesh_msg_ctx *ctx,
999 struct net_buf_simple *buf)
1000 {
1001 struct bt_mesh_gen_power_level_srv *srv = model->user_data;
1002 uint16_t opcode = 0U;
1003
1004 if (srv == NULL || srv->state == NULL) {
1005 BT_ERR("%s, Invalid model user data", __func__);
1006 return;
1007 }
1008
1009 /* Callback the received message to the application layer */
1010 if (srv->rsp_ctrl.get_auto_rsp == BLE_MESH_SERVER_RSP_BY_APP) {
1011 bt_mesh_generic_server_cb_evt_to_btc(
1012 BTC_BLE_MESH_EVT_GENERIC_SERVER_RECV_GET_MSG, model, ctx, NULL, 0);
1013 return;
1014 }
1015
1016 switch (ctx->recv_op) {
1017 case BLE_MESH_MODEL_OP_GEN_POWER_LEVEL_GET:
1018 opcode = BLE_MESH_MODEL_OP_GEN_POWER_LEVEL_STATUS;
1019 break;
1020 case BLE_MESH_MODEL_OP_GEN_POWER_LAST_GET:
1021 opcode = BLE_MESH_MODEL_OP_GEN_POWER_LAST_STATUS;
1022 break;
1023 case BLE_MESH_MODEL_OP_GEN_POWER_DEFAULT_GET:
1024 opcode = BLE_MESH_MODEL_OP_GEN_POWER_DEFAULT_STATUS;
1025 break;
1026 case BLE_MESH_MODEL_OP_GEN_POWER_RANGE_GET:
1027 opcode = BLE_MESH_MODEL_OP_GEN_POWER_RANGE_STATUS;
1028 break;
1029 default:
1030 BT_WARN("Unknown Generic Power Get opcode 0x%04x", ctx->recv_op);
1031 return;
1032 }
1033
1034 send_gen_power_level_status(model, ctx, false, opcode);
1035 return;
1036 }
1037
gen_power_level_publish(struct bt_mesh_model * model,uint16_t opcode)1038 void gen_power_level_publish(struct bt_mesh_model *model, uint16_t opcode)
1039 {
1040 if (model->user_data == NULL) {
1041 BT_ERR("%s, Invalid model user data", __func__);
1042 return;
1043 }
1044
1045 switch (model->id) {
1046 case BLE_MESH_MODEL_ID_GEN_POWER_LEVEL_SRV: {
1047 struct bt_mesh_gen_power_level_srv *srv = model->user_data;
1048 if (srv->state == NULL) {
1049 BT_ERR("Invalid Generic Power Level Server state");
1050 return;
1051 }
1052 break;
1053 }
1054 case ESP_BLE_MESH_MODEL_ID_GEN_POWER_LEVEL_SETUP_SRV: {
1055 struct bt_mesh_gen_power_level_setup_srv *srv = model->user_data;
1056 if (srv->state == NULL) {
1057 BT_ERR("Invalid Generic Power Level Setup Server state");
1058 return;
1059 }
1060 break;
1061 }
1062 default:
1063 BT_ERR("Invalid Generic Power Level Server 0x%04x", model->id);
1064 return;
1065 }
1066
1067 send_gen_power_level_status(model, NULL, true, opcode);
1068 return;
1069 }
1070
gen_power_level_set(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)1071 static void gen_power_level_set(struct bt_mesh_model *model,
1072 struct bt_mesh_msg_ctx *ctx,
1073 struct net_buf_simple *buf)
1074 {
1075 struct bt_mesh_gen_power_level_srv *srv = model->user_data;
1076 uint8_t tid = 0U, trans_time = 0U, delay = 0U;
1077 bool optional = false;
1078 uint16_t power = 0U;
1079 int64_t now = 0;
1080
1081 if (srv == NULL || srv->state == NULL) {
1082 BT_ERR("%s, Invalid model user data", __func__);
1083 return;
1084 }
1085
1086 power = net_buf_simple_pull_le16(buf);
1087 tid = net_buf_simple_pull_u8(buf);
1088
1089 if (bt_mesh_server_get_optional(model, ctx, buf, &trans_time, &delay, &optional)) {
1090 return;
1091 }
1092
1093 /* Callback the received message to the application layer */
1094 if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_RSP_BY_APP) {
1095 bt_mesh_gen_server_recv_set_msg_t set = {
1096 .power_level_set.op_en = optional,
1097 .power_level_set.power = power,
1098 .power_level_set.tid = tid,
1099 .power_level_set.trans_time = trans_time,
1100 .power_level_set.delay = delay,
1101 };
1102 bt_mesh_generic_server_cb_evt_to_btc(
1103 BTC_BLE_MESH_EVT_GENERIC_SERVER_RECV_SET_MSG, model, ctx, (const uint8_t *)&set, sizeof(set));
1104 return;
1105 }
1106
1107 if (bt_mesh_is_server_recv_last_msg(&srv->last, tid, ctx->addr, ctx->recv_dst, &now)) {
1108 if (ctx->recv_op == BLE_MESH_MODEL_OP_GEN_POWER_LEVEL_SET) {
1109 send_gen_power_level_status(model, ctx, false, BLE_MESH_MODEL_OP_GEN_POWER_LEVEL_STATUS);
1110 }
1111 send_gen_power_level_status(model, NULL, true, BLE_MESH_MODEL_OP_GEN_POWER_LEVEL_STATUS);
1112 /* In this condition, no event will be callback to application layer */
1113 return;
1114 }
1115
1116 bt_mesh_generic_server_lock();
1117
1118 bt_mesh_server_stop_transition(&srv->transition);
1119 bt_mesh_server_update_last_msg(&srv->last, tid, ctx->addr, ctx->recv_dst, &now);
1120
1121 if (power) {
1122 if (srv->state->power_range_min && power < srv->state->power_range_min) {
1123 power = srv->state->power_range_min;
1124 } else if (srv->state->power_range_max && power > srv->state->power_range_max) {
1125 power = srv->state->power_range_max;
1126 }
1127 }
1128 srv->state->target_power_actual = power;
1129
1130 /* If the target state is equal to the current state, the transition
1131 * shall not be started and is considered complete.
1132 */
1133 if (srv->state->target_power_actual != srv->state->power_actual) {
1134 generic_power_level_tt_values(srv, trans_time, delay);
1135 } else {
1136 bt_mesh_gen_server_state_change_t change = {
1137 .gen_power_level_set.power = srv->state->power_actual,
1138 };
1139 bt_mesh_generic_server_cb_evt_to_btc(
1140 BTC_BLE_MESH_EVT_GENERIC_SERVER_STATE_CHANGE, model, ctx, (const uint8_t *)&change, sizeof(change));
1141
1142 if (ctx->recv_op == BLE_MESH_MODEL_OP_GEN_POWER_LEVEL_SET) {
1143 send_gen_power_level_status(model, ctx, false, BLE_MESH_MODEL_OP_GEN_POWER_LEVEL_STATUS);
1144 }
1145 send_gen_power_level_status(model, NULL, true, BLE_MESH_MODEL_OP_GEN_POWER_LEVEL_STATUS);
1146
1147 bt_mesh_generic_server_unlock();
1148 return;
1149 }
1150
1151 /* Copy the ctx of the received message */
1152 if (srv->transition.timer.work._reserved) {
1153 memcpy(srv->transition.timer.work._reserved, ctx, sizeof(struct bt_mesh_msg_ctx));
1154 }
1155
1156 /* For Instantaneous Transition */
1157 if (srv->transition.counter == 0U) {
1158 srv->state->power_actual = srv->state->target_power_actual;
1159 /* Whenever the Generic Power Actual state is changed to a non-zero value
1160 * as a result of a non-transactional message or a completed sequence of
1161 * transactional messages, the value of the Generic Power Last state shall
1162 * be set to the value of the Generic Power Actual state.
1163 */
1164 if (srv->state->power_actual) {
1165 srv->state->power_last = srv->state->power_actual;
1166 }
1167 }
1168
1169 srv->transition.just_started = true;
1170 if (ctx->recv_op == BLE_MESH_MODEL_OP_GEN_POWER_LEVEL_SET) {
1171 send_gen_power_level_status(model, ctx, false, BLE_MESH_MODEL_OP_GEN_POWER_LEVEL_STATUS);
1172 }
1173 send_gen_power_level_status(model, NULL, true, BLE_MESH_MODEL_OP_GEN_POWER_LEVEL_STATUS);
1174
1175 bt_mesh_generic_server_unlock();
1176
1177 bt_mesh_server_start_transition(&srv->transition);
1178 return;
1179 }
1180
1181 /* Generic Power Level Setup Server message handlers */
gen_power_default_set(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)1182 static void gen_power_default_set(struct bt_mesh_model *model,
1183 struct bt_mesh_msg_ctx *ctx,
1184 struct net_buf_simple *buf)
1185 {
1186 struct bt_mesh_gen_power_level_setup_srv *srv = model->user_data;
1187 uint16_t power = 0U;
1188
1189 if (srv == NULL || srv->state == NULL) {
1190 BT_ERR("%s, Invalid model user data", __func__);
1191 return;
1192 }
1193
1194 power = net_buf_simple_pull_le16(buf);
1195
1196 /* Callback the received message to the application layer */
1197 if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_RSP_BY_APP) {
1198 bt_mesh_gen_server_recv_set_msg_t set = {
1199 .power_default_set.power = power, /* Just callback the actual received value */
1200 };
1201 bt_mesh_generic_server_cb_evt_to_btc(
1202 BTC_BLE_MESH_EVT_GENERIC_SERVER_RECV_SET_MSG, model, ctx, (const uint8_t *)&set, sizeof(set));
1203 return;
1204 }
1205
1206 /**
1207 * Value 0x0000 has a special meaning defined: use the value of the
1208 * Generic Power Last state as the default value.
1209 */
1210 if (power == 0x0000) {
1211 power = srv->state->power_last;
1212 }
1213
1214 if (srv->state->power_default != power) {
1215 srv->state->power_default = power;
1216 }
1217
1218 bt_mesh_gen_server_state_change_t change = {
1219 .gen_power_default_set.power = power,
1220 };
1221 bt_mesh_generic_server_cb_evt_to_btc(
1222 BTC_BLE_MESH_EVT_GENERIC_SERVER_STATE_CHANGE, model, ctx, (const uint8_t *)&change, sizeof(change));
1223
1224 if (ctx->recv_op == BLE_MESH_MODEL_OP_GEN_POWER_DEFAULT_SET) {
1225 send_gen_power_level_status(model, ctx, false, BLE_MESH_MODEL_OP_GEN_POWER_DEFAULT_STATUS);
1226 }
1227 send_gen_power_level_status(model, NULL, true, BLE_MESH_MODEL_OP_GEN_POWER_DEFAULT_STATUS);
1228
1229 return;
1230 }
1231
gen_power_range_set(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)1232 static void gen_power_range_set(struct bt_mesh_model *model,
1233 struct bt_mesh_msg_ctx *ctx,
1234 struct net_buf_simple *buf)
1235 {
1236 struct bt_mesh_gen_power_level_setup_srv *srv = model->user_data;
1237 uint16_t range_min = 0U, range_max = 0U;
1238
1239 if (srv == NULL || srv->state == NULL) {
1240 BT_ERR("%s, Invalid model user data", __func__);
1241 return;
1242 }
1243
1244 range_min = net_buf_simple_pull_le16(buf);
1245 range_max = net_buf_simple_pull_le16(buf);
1246
1247 if (range_min > range_max) {
1248 BT_ERR("Range min 0x%04x is greater than range max 0x%04x",
1249 range_min, range_max);
1250 return;
1251 }
1252
1253 /* Callback the received message to the application layer */
1254 if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_RSP_BY_APP) {
1255 bt_mesh_gen_server_recv_set_msg_t set = {
1256 .power_range_set.range_min = range_min,
1257 .power_range_set.range_max = range_max,
1258 };
1259 bt_mesh_generic_server_cb_evt_to_btc(
1260 BTC_BLE_MESH_EVT_GENERIC_SERVER_RECV_SET_MSG, model, ctx, (const uint8_t *)&set, sizeof(set));
1261 return;
1262 }
1263
1264 if (range_min == 0x0000) {
1265 srv->state->status_code = BLE_MESH_CANNOT_SET_RANGE_MIN;
1266 } else if (range_max == 0x0000) {
1267 srv->state->status_code = BLE_MESH_CANNOT_SET_RANGE_MAX;
1268 } else {
1269 srv->state->status_code = BLE_MESH_RANGE_UPDATE_SUCCESS;
1270 }
1271
1272 if (range_min && srv->state->power_range_min != range_min) {
1273 srv->state->power_range_min = range_min;
1274 }
1275
1276 if (range_max && srv->state->power_range_max != range_max) {
1277 srv->state->power_range_max = range_max;
1278 }
1279
1280 bt_mesh_gen_server_state_change_t change = {
1281 .gen_power_range_set.range_min = srv->state->power_range_min,
1282 .gen_power_range_set.range_max = srv->state->power_range_max,
1283 };
1284 bt_mesh_generic_server_cb_evt_to_btc(
1285 BTC_BLE_MESH_EVT_GENERIC_SERVER_STATE_CHANGE, model, ctx, (const uint8_t *)&change, sizeof(change));
1286
1287 if (ctx->recv_op == BLE_MESH_MODEL_OP_GEN_POWER_RANGE_SET) {
1288 send_gen_power_level_status(model, ctx, false, BLE_MESH_MODEL_OP_GEN_POWER_RANGE_STATUS);
1289 }
1290 send_gen_power_level_status(model, NULL, true, BLE_MESH_MODEL_OP_GEN_POWER_RANGE_STATUS);
1291
1292 return;
1293 }
1294
1295 /* Generic Battery Server message handlers */
gen_battery_get(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)1296 static void gen_battery_get(struct bt_mesh_model *model,
1297 struct bt_mesh_msg_ctx *ctx,
1298 struct net_buf_simple *buf)
1299 {
1300 struct bt_mesh_gen_battery_srv *srv = model->user_data;
1301 NET_BUF_SIMPLE_DEFINE(msg, 2 + 8 + BLE_MESH_SERVER_TRANS_MIC_SIZE);
1302
1303 if (srv == NULL) {
1304 BT_ERR("%s, Invalid model user data", __func__);
1305 return;
1306 }
1307
1308 /* Callback the received message to the application layer */
1309 if (srv->rsp_ctrl.get_auto_rsp == BLE_MESH_SERVER_RSP_BY_APP) {
1310 bt_mesh_generic_server_cb_evt_to_btc(
1311 BTC_BLE_MESH_EVT_GENERIC_SERVER_RECV_GET_MSG, model, ctx, NULL, 0);
1312 return;
1313 }
1314
1315 bt_mesh_model_msg_init(&msg, BLE_MESH_MODEL_OP_GEN_BATTERY_STATUS);
1316 net_buf_simple_add_le32(&msg, srv->state.time_to_discharge << 8 | srv->state.battery_level);
1317 net_buf_simple_add_le32(&msg, srv->state.battery_flags << 24 | srv->state.time_to_charge);
1318
1319 BLE_MESH_CHECK_SEND_STATUS(bt_mesh_model_send(model, ctx, &msg, NULL, NULL));
1320 return;
1321 }
1322
1323 /* Generic Location Server message handlers */
send_gen_location_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,bool publish,uint16_t opcode)1324 static void send_gen_location_status(struct bt_mesh_model *model,
1325 struct bt_mesh_msg_ctx *ctx,
1326 bool publish, uint16_t opcode)
1327 {
1328 struct net_buf_simple *msg = NULL;
1329 uint8_t length = 1 + 10;
1330
1331 if (ctx == NULL && publish == false) {
1332 BT_ERR("%s, Invalid parameter", __func__);
1333 return;
1334 }
1335
1336 if (publish == false) {
1337 msg = bt_mesh_alloc_buf(length + BLE_MESH_SERVER_TRANS_MIC_SIZE);
1338 if (msg == NULL) {
1339 BT_ERR("%s, Out of memory", __func__);
1340 return;
1341 }
1342 } else {
1343 msg = bt_mesh_server_get_pub_msg(model, length);
1344 if (msg == NULL) {
1345 return;
1346 }
1347 }
1348
1349 bt_mesh_model_msg_init(msg, opcode);
1350 switch (opcode) {
1351 case BLE_MESH_MODEL_OP_GEN_LOC_GLOBAL_STATUS:
1352 if (model->id == BLE_MESH_MODEL_ID_GEN_LOCATION_SRV) {
1353 struct bt_mesh_gen_location_srv *srv = model->user_data;
1354 net_buf_simple_add_le32(msg, srv->state->global_latitude);
1355 net_buf_simple_add_le32(msg, srv->state->global_longitude);
1356 net_buf_simple_add_le16(msg, srv->state->global_altitude);
1357 } else if (model->id == BLE_MESH_MODEL_ID_GEN_LOCATION_SETUP_SRV) {
1358 struct bt_mesh_gen_location_setup_srv *srv = model->user_data;
1359 net_buf_simple_add_le32(msg, srv->state->global_latitude);
1360 net_buf_simple_add_le32(msg, srv->state->global_longitude);
1361 net_buf_simple_add_le16(msg, srv->state->global_altitude);
1362 }
1363 break;
1364 case BLE_MESH_MODEL_OP_GEN_LOC_LOCAL_STATUS:
1365 if (model->id == BLE_MESH_MODEL_ID_GEN_LOCATION_SRV) {
1366 struct bt_mesh_gen_location_srv *srv = model->user_data;
1367 net_buf_simple_add_le16(msg, srv->state->local_north);
1368 net_buf_simple_add_le16(msg, srv->state->local_east);
1369 net_buf_simple_add_le16(msg, srv->state->local_altitude);
1370 net_buf_simple_add_u8(msg, srv->state->floor_number);
1371 net_buf_simple_add_le16(msg, srv->state->uncertainty);
1372 } else if (model->id == BLE_MESH_MODEL_ID_GEN_LOCATION_SETUP_SRV) {
1373 struct bt_mesh_gen_location_setup_srv *srv = model->user_data;
1374 net_buf_simple_add_le16(msg, srv->state->local_north);
1375 net_buf_simple_add_le16(msg, srv->state->local_east);
1376 net_buf_simple_add_le16(msg, srv->state->local_altitude);
1377 net_buf_simple_add_u8(msg, srv->state->floor_number);
1378 net_buf_simple_add_le16(msg, srv->state->uncertainty);
1379 }
1380 break;
1381 default:
1382 BT_WARN("Unknown Generic Location status opcode 0x%04x", opcode);
1383 if (publish == false) {
1384 bt_mesh_free_buf(msg);
1385 }
1386 return;
1387 }
1388
1389 if (publish == false) {
1390 BLE_MESH_CHECK_SEND_STATUS(bt_mesh_model_send(model, ctx, msg, NULL, NULL));
1391 bt_mesh_free_buf(msg);
1392 } else {
1393 BLE_MESH_CHECK_SEND_STATUS(bt_mesh_model_publish(model));
1394 }
1395 return;
1396 }
1397
gen_location_get(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)1398 static void gen_location_get(struct bt_mesh_model *model,
1399 struct bt_mesh_msg_ctx *ctx,
1400 struct net_buf_simple *buf)
1401 {
1402 struct bt_mesh_gen_location_srv *srv = model->user_data;
1403 uint16_t opcode = 0U;
1404
1405 if (srv == NULL || srv->state == NULL) {
1406 BT_ERR("%s, Invalid model user data", __func__);
1407 return;
1408 }
1409
1410 /* Callback the received message to the application layer */
1411 if (srv->rsp_ctrl.get_auto_rsp == BLE_MESH_SERVER_RSP_BY_APP) {
1412 bt_mesh_generic_server_cb_evt_to_btc(
1413 BTC_BLE_MESH_EVT_GENERIC_SERVER_RECV_GET_MSG, model, ctx, NULL, 0);
1414 return;
1415 }
1416
1417 switch (ctx->recv_op) {
1418 case BLE_MESH_MODEL_OP_GEN_LOC_GLOBAL_GET:
1419 opcode = BLE_MESH_MODEL_OP_GEN_LOC_GLOBAL_STATUS;
1420 break;
1421 case BLE_MESH_MODEL_OP_GEN_LOC_LOCAL_GET:
1422 opcode = BLE_MESH_MODEL_OP_GEN_LOC_LOCAL_STATUS;
1423 break;
1424 default:
1425 BT_WARN("Unknown Generic Location Get opcode 0x%04x", ctx->recv_op);
1426 return;
1427 }
1428
1429 send_gen_location_status(model, ctx, false, opcode);
1430 return;
1431 }
1432
1433 /* Generic Location Setup Server message handlers */
gen_location_set(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)1434 static void gen_location_set(struct bt_mesh_model *model,
1435 struct bt_mesh_msg_ctx *ctx,
1436 struct net_buf_simple *buf)
1437 {
1438 struct bt_mesh_gen_location_setup_srv *srv = model->user_data;
1439 uint16_t opcode = 0U;
1440
1441 if (srv == NULL || srv->state == NULL) {
1442 BT_ERR("%s, Invalid model user data", __func__);
1443 return;
1444 }
1445
1446 switch (ctx->recv_op) {
1447 case BLE_MESH_MODEL_OP_GEN_LOC_GLOBAL_SET:
1448 case BLE_MESH_MODEL_OP_GEN_LOC_GLOBAL_SET_UNACK: {
1449 opcode = BLE_MESH_MODEL_OP_GEN_LOC_GLOBAL_STATUS;
1450 int32_t latitude = net_buf_simple_pull_le32(buf);
1451 int32_t longitude = net_buf_simple_pull_le32(buf);
1452 int16_t altitude = net_buf_simple_pull_le16(buf);
1453
1454 /* Callback the received message to the application layer */
1455 if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_RSP_BY_APP) {
1456 bt_mesh_gen_server_recv_set_msg_t set = {
1457 .loc_global_set.latitude = latitude,
1458 .loc_global_set.longitude = longitude,
1459 .loc_global_set.altitude = altitude,
1460 };
1461 bt_mesh_generic_server_cb_evt_to_btc(
1462 BTC_BLE_MESH_EVT_GENERIC_SERVER_RECV_SET_MSG, model, ctx, (const uint8_t *)&set, sizeof(set));
1463 return;
1464 }
1465
1466 if (latitude != 0x80000000) {
1467 srv->state->global_latitude = latitude;
1468 }
1469 if (longitude != 0x80000000) {
1470 srv->state->global_longitude = longitude;
1471 }
1472 if (altitude != 0x7FFF) {
1473 srv->state->global_altitude = altitude;
1474 }
1475
1476 bt_mesh_gen_server_state_change_t change = {
1477 .gen_loc_global_set.latitude = srv->state->global_latitude,
1478 .gen_loc_global_set.longitude = srv->state->global_longitude,
1479 .gen_loc_global_set.altitude = srv->state->global_altitude,
1480 };
1481 bt_mesh_generic_server_cb_evt_to_btc(
1482 BTC_BLE_MESH_EVT_GENERIC_SERVER_STATE_CHANGE, model, ctx, (const uint8_t *)&change, sizeof(change));
1483 break;
1484 }
1485 case BLE_MESH_MODEL_OP_GEN_LOC_LOCAL_SET:
1486 case BLE_MESH_MODEL_OP_GEN_LOC_LOCAL_SET_UNACK: {
1487 opcode = BLE_MESH_MODEL_OP_GEN_LOC_LOCAL_STATUS;
1488 uint16_t north = net_buf_simple_pull_le16(buf);
1489 uint16_t east = net_buf_simple_pull_le16(buf);
1490 uint16_t altitude = net_buf_simple_pull_le16(buf);
1491 uint8_t floor = net_buf_simple_pull_u8(buf);
1492 uint16_t uncertainty = net_buf_simple_pull_le16(buf);
1493
1494 /* Callback the received message to the application layer */
1495 if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_RSP_BY_APP) {
1496 bt_mesh_gen_server_recv_set_msg_t set = {
1497 .loc_local_set.north = north,
1498 .loc_local_set.east = east,
1499 .loc_local_set.altitude = altitude,
1500 .loc_local_set.floor_number = floor,
1501 .loc_local_set.uncertainty = uncertainty,
1502 };
1503 bt_mesh_generic_server_cb_evt_to_btc(
1504 BTC_BLE_MESH_EVT_GENERIC_SERVER_RECV_SET_MSG, model, ctx, (const uint8_t *)&set, sizeof(set));
1505 return;
1506 }
1507
1508 if (north != 0x8000) {
1509 srv->state->local_north = north;
1510 }
1511 if (east != 0x8000) {
1512 srv->state->local_east = east;
1513 }
1514 if (altitude != 0x7FFF) {
1515 srv->state->local_altitude = altitude;
1516 }
1517 if (floor != 0xFF) {
1518 srv->state->floor_number = floor;
1519 }
1520 srv->state->uncertainty = uncertainty;
1521
1522 bt_mesh_gen_server_state_change_t change = {
1523 .gen_loc_local_set.north = srv->state->local_north,
1524 .gen_loc_local_set.east = srv->state->local_east,
1525 .gen_loc_local_set.altitude = srv->state->local_altitude,
1526 .gen_loc_local_set.floor_number = srv->state->floor_number,
1527 .gen_loc_local_set.uncertainty = srv->state->uncertainty,
1528 };
1529 bt_mesh_generic_server_cb_evt_to_btc(
1530 BTC_BLE_MESH_EVT_GENERIC_SERVER_STATE_CHANGE, model, ctx, (const uint8_t *)&change, sizeof(change));
1531 break;
1532 }
1533 default:
1534 BT_WARN("Unknown Generic Location Set opcode 0x%04x", ctx->recv_op);
1535 return;
1536 }
1537
1538 if (ctx->recv_op == BLE_MESH_MODEL_OP_GEN_LOC_GLOBAL_SET ||
1539 ctx->recv_op == BLE_MESH_MODEL_OP_GEN_LOC_LOCAL_SET) {
1540 send_gen_location_status(model, ctx, false, opcode);
1541 }
1542 send_gen_location_status(model, NULL, true, opcode);
1543
1544 return;
1545 }
1546
1547 /* Generic User Property Server message handlers */
gen_get_user_property(struct bt_mesh_model * model,uint16_t property_id)1548 static struct bt_mesh_generic_property *gen_get_user_property(struct bt_mesh_model *model,
1549 uint16_t property_id)
1550 {
1551 struct bt_mesh_gen_user_prop_srv *srv = model->user_data;
1552 int i;
1553
1554 for (i = 0; i < srv->property_count; i++) {
1555 if (srv->properties[i].id == property_id) {
1556 return &srv->properties[i];
1557 }
1558 }
1559
1560 return NULL;
1561 }
1562
send_gen_user_prop_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,uint16_t property_id,bool publish)1563 static void send_gen_user_prop_status(struct bt_mesh_model *model,
1564 struct bt_mesh_msg_ctx *ctx,
1565 uint16_t property_id, bool publish)
1566 {
1567 struct bt_mesh_generic_property *property = NULL;
1568 struct net_buf_simple *msg = NULL;
1569 uint16_t length = 0U;
1570
1571 if (property_id == BLE_MESH_INVALID_DEVICE_PROPERTY_ID) {
1572 BT_ERR("Invalid User Property ID 0x%04x", property_id);
1573 return;
1574 }
1575
1576 property = gen_get_user_property(model, property_id);
1577 if (property == NULL) {
1578 BT_WARN("User property 0x%04x not exists", property_id);
1579 length = sizeof(property_id);
1580 } else {
1581 length = sizeof(property->id) + sizeof(property->user_access) + property->val->len;
1582 }
1583
1584 if (publish == false) {
1585 msg = bt_mesh_alloc_buf(1 + length + BLE_MESH_SERVER_TRANS_MIC_SIZE);
1586 if (msg == NULL) {
1587 BT_ERR("%s, Out of memory", __func__);
1588 return;
1589 }
1590 } else {
1591 msg = bt_mesh_server_get_pub_msg(model, 1 + length);
1592 if (msg == NULL) {
1593 return;
1594 }
1595 }
1596
1597 bt_mesh_model_msg_init(msg, BLE_MESH_MODEL_OP_GEN_USER_PROPERTY_STATUS);
1598 if (property == NULL) {
1599 net_buf_simple_add_le16(msg, property_id);
1600 } else {
1601 net_buf_simple_add_le16(msg, property->id);
1602 net_buf_simple_add_u8(msg, property->user_access);
1603 if ((ctx->recv_op == BLE_MESH_MODEL_OP_GEN_USER_PROPERTY_GET &&
1604 property->user_access != USER_ACCESS_PROHIBIT &&
1605 property->user_access != USER_ACCESS_WRITE) ||
1606 ((ctx->recv_op == BLE_MESH_MODEL_OP_GEN_USER_PROPERTY_SET ||
1607 ctx->recv_op == BLE_MESH_MODEL_OP_GEN_USER_PROPERTY_SET_UNACK) &&
1608 property->user_access != USER_ACCESS_PROHIBIT &&
1609 property->user_access != USER_ACCESS_READ)) {
1610 net_buf_simple_add_mem(msg, property->val->data, property->val->len);
1611 }
1612 }
1613
1614 if (publish == false) {
1615 BLE_MESH_CHECK_SEND_STATUS(bt_mesh_model_send(model, ctx, msg, NULL, NULL));
1616 bt_mesh_free_buf(msg);
1617 } else {
1618 BLE_MESH_CHECK_SEND_STATUS(bt_mesh_model_publish(model));
1619 }
1620 return;
1621 }
1622
gen_user_prop_get(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)1623 static void gen_user_prop_get(struct bt_mesh_model *model,
1624 struct bt_mesh_msg_ctx *ctx,
1625 struct net_buf_simple *buf)
1626 {
1627 struct bt_mesh_gen_user_prop_srv *srv = model->user_data;
1628
1629 if (srv == NULL || srv->property_count == 0U || srv->properties == NULL) {
1630 BT_ERR("%s, Invalid model user data", __func__);
1631 return;
1632 }
1633
1634 /* Callback the received message to the application layer */
1635 if (srv->rsp_ctrl.get_auto_rsp == BLE_MESH_SERVER_RSP_BY_APP) {
1636 /**
1637 * Also we can use __packed for esp_ble_mesh_gen_user_property_get_t,
1638 * and directly callback with buf->data & buf->len.
1639 */
1640 bt_mesh_gen_server_recv_get_msg_t get = {0};
1641 const uint8_t *param = NULL;
1642 size_t len = 0;
1643 if (ctx->recv_op == BLE_MESH_MODEL_OP_GEN_USER_PROPERTY_GET) {
1644 get.user_property_get.id = net_buf_simple_pull_le16(buf);
1645 param = (const uint8_t *)&get;
1646 len = sizeof(get);
1647 }
1648 bt_mesh_generic_server_cb_evt_to_btc(
1649 BTC_BLE_MESH_EVT_GENERIC_SERVER_RECV_GET_MSG, model, ctx, param, len);
1650 return;
1651 }
1652
1653 switch (ctx->recv_op) {
1654 case BLE_MESH_MODEL_OP_GEN_USER_PROPERTIES_GET: {
1655 struct net_buf_simple *msg = NULL;
1656 uint8_t i;
1657 msg = bt_mesh_alloc_buf(1 + srv->property_count * 2 + BLE_MESH_SERVER_TRANS_MIC_SIZE);
1658 if (msg == NULL) {
1659 BT_ERR("%s, Out of memory", __func__);
1660 return;
1661 }
1662 bt_mesh_model_msg_init(msg, BLE_MESH_MODEL_OP_GEN_USER_PROPERTIES_STATUS);
1663 for (i = 0U; i < srv->property_count; i++) {
1664 if (srv->properties[i].admin_access != ADMIN_NOT_USER_PROP &&
1665 srv->properties[i].manu_access != MANU_NOT_USER_PROP) {
1666 net_buf_simple_add_le16(msg, srv->properties[i].id);
1667 }
1668 }
1669 BLE_MESH_CHECK_SEND_STATUS(bt_mesh_model_send(model, ctx, msg, NULL, NULL));
1670 bt_mesh_free_buf(msg);
1671 return;
1672 }
1673 case BLE_MESH_MODEL_OP_GEN_USER_PROPERTY_GET: {
1674 uint16_t property_id = net_buf_simple_pull_le16(buf);
1675 send_gen_user_prop_status(model, ctx, property_id, false);
1676 return;
1677 }
1678 default:
1679 BT_WARN("Unknown Generic User Property Get opcode 0x%04x", ctx->recv_op);
1680 return;
1681 }
1682 }
1683
gen_user_prop_set(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)1684 static void gen_user_prop_set(struct bt_mesh_model *model,
1685 struct bt_mesh_msg_ctx *ctx,
1686 struct net_buf_simple *buf)
1687 {
1688 struct bt_mesh_gen_user_prop_srv *srv = model->user_data;
1689 struct bt_mesh_generic_property *property = NULL;
1690 uint16_t property_id = 0U;
1691 uint8_t expect_len = 0U;
1692
1693 if (srv == NULL || srv->property_count == 0U || srv->properties == NULL) {
1694 BT_ERR("%s, Invalid model user data", __func__);
1695 return;
1696 }
1697
1698 property_id = net_buf_simple_pull_le16(buf);
1699
1700 /* Callback the received message to the application layer */
1701 if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_RSP_BY_APP) {
1702 bt_mesh_gen_server_recv_set_msg_t set = {
1703 .user_property_set.id = property_id,
1704 .user_property_set.value = buf,
1705 };
1706 bt_mesh_generic_server_cb_evt_to_btc(
1707 BTC_BLE_MESH_EVT_GENERIC_SERVER_RECV_SET_MSG, model, ctx, (const uint8_t *)&set, sizeof(set));
1708 return;
1709 }
1710
1711 property = gen_get_user_property(model, property_id);
1712 if (property == NULL || property->user_access == USER_ACCESS_PROHIBIT ||
1713 property->user_access == USER_ACCESS_READ) {
1714 if (ctx->recv_op == BLE_MESH_MODEL_OP_GEN_USER_PROPERTY_SET) {
1715 send_gen_user_prop_status(model, ctx, property_id, false);
1716 }
1717 send_gen_user_prop_status(model, ctx, property_id, true);
1718 return;
1719 }
1720
1721 /* For BLE Mesh Model BQB test:
1722 * PTS will send Generic User Property Set/Set Unack messages with
1723 * invalid device property value length, these messages need to be
1724 * ignored, otherwise the test case will fail.
1725 */
1726 expect_len = bt_mesh_get_dev_prop_len(property_id);
1727 if (buf->len != expect_len) {
1728 BT_ERR("Invalid User Property 0x%04x length, expect %d, actual %d",
1729 property_id, expect_len, buf->len);
1730 return;
1731 }
1732
1733 net_buf_simple_reset(property->val);
1734 net_buf_simple_add_mem(property->val, buf->data, MIN(buf->len, property->val->size));
1735
1736 bt_mesh_gen_server_state_change_t change = {
1737 .gen_user_prop_set.id = property_id,
1738 .gen_user_prop_set.value = property->val,
1739 };
1740 bt_mesh_generic_server_cb_evt_to_btc(
1741 BTC_BLE_MESH_EVT_GENERIC_SERVER_STATE_CHANGE, model, ctx, (const uint8_t *)&change, sizeof(change));
1742
1743 if (ctx->recv_op == BLE_MESH_MODEL_OP_GEN_USER_PROPERTY_SET) {
1744 send_gen_user_prop_status(model, ctx, property_id, false);
1745 }
1746 send_gen_user_prop_status(model, ctx, property_id, true);
1747
1748 return;
1749 }
1750
1751 /* Generic Admin Property Server message handlers */
gen_get_admin_property(struct bt_mesh_model * model,uint16_t property_id)1752 static struct bt_mesh_generic_property *gen_get_admin_property(struct bt_mesh_model *model,
1753 uint16_t property_id)
1754 {
1755 struct bt_mesh_gen_admin_prop_srv *srv = model->user_data;
1756 int i;
1757
1758 for (i = 0; i < srv->property_count; i++) {
1759 if (srv->properties[i].id == property_id) {
1760 return &srv->properties[i];
1761 }
1762 }
1763
1764 return NULL;
1765 }
1766
send_gen_admin_prop_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,uint16_t property_id,bool publish)1767 static void send_gen_admin_prop_status(struct bt_mesh_model *model,
1768 struct bt_mesh_msg_ctx *ctx,
1769 uint16_t property_id, bool publish)
1770 {
1771 struct bt_mesh_generic_property *property = NULL;
1772 struct net_buf_simple *msg = NULL;
1773 uint16_t length = 0U;
1774
1775 if (property_id == BLE_MESH_INVALID_DEVICE_PROPERTY_ID) {
1776 BT_ERR("Invalid Admin Property ID 0x%04x", property_id);
1777 return;
1778 }
1779
1780 property = gen_get_admin_property(model, property_id);
1781 if (property == NULL) {
1782 BT_WARN("Admin property 0x%04x not exists", property_id);
1783 length = sizeof(property_id);
1784 } else {
1785 length = sizeof(property->id) + sizeof(property->admin_access) + property->val->len;
1786 }
1787
1788 if (publish == false) {
1789 msg = bt_mesh_alloc_buf(1 + length + BLE_MESH_SERVER_TRANS_MIC_SIZE);
1790 if (msg == NULL) {
1791 BT_ERR("%s, Out of memory", __func__);
1792 return;
1793 }
1794 } else {
1795 msg = bt_mesh_server_get_pub_msg(model, 1 + length);
1796 if (msg == NULL) {
1797 return;
1798 }
1799 }
1800
1801 bt_mesh_model_msg_init(msg, BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTY_STATUS);
1802 if (property == NULL) {
1803 net_buf_simple_add_le16(msg, property_id);
1804 } else {
1805 net_buf_simple_add_le16(msg, property->id);
1806 net_buf_simple_add_u8(msg, property->admin_access);
1807 if (ctx->recv_op != BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTY_GET ||
1808 property->admin_access != ADMIN_ACCESS_WRITE) {
1809 net_buf_simple_add_mem(msg, property->val->data, property->val->len);
1810 }
1811 }
1812
1813 if (publish == false) {
1814 BLE_MESH_CHECK_SEND_STATUS(bt_mesh_model_send(model, ctx, msg, NULL, NULL));
1815 bt_mesh_free_buf(msg);
1816 } else {
1817 BLE_MESH_CHECK_SEND_STATUS(bt_mesh_model_publish(model));
1818 }
1819 return;
1820 }
1821
gen_admin_prop_get(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)1822 static void gen_admin_prop_get(struct bt_mesh_model *model,
1823 struct bt_mesh_msg_ctx *ctx,
1824 struct net_buf_simple *buf)
1825 {
1826 struct bt_mesh_gen_admin_prop_srv *srv = model->user_data;
1827
1828 if (srv == NULL || srv->property_count == 0U || srv->properties == NULL) {
1829 BT_ERR("%s, Invalid model user data", __func__);
1830 return;
1831 }
1832
1833 /* Callback the received message to the application layer */
1834 if (srv->rsp_ctrl.get_auto_rsp == BLE_MESH_SERVER_RSP_BY_APP) {
1835 bt_mesh_gen_server_recv_get_msg_t get = {0};
1836 const uint8_t *param = NULL;
1837 size_t len = 0U;
1838 if (ctx->recv_op == BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTY_GET) {
1839 get.admin_property_get.id = net_buf_simple_pull_le16(buf);
1840 param = (const uint8_t *)&get;
1841 len = sizeof(get);
1842 }
1843 bt_mesh_generic_server_cb_evt_to_btc(
1844 BTC_BLE_MESH_EVT_GENERIC_SERVER_RECV_GET_MSG, model, ctx, param, len);
1845 return;
1846 }
1847
1848 switch (ctx->recv_op) {
1849 case BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTIES_GET: {
1850 struct net_buf_simple *msg = NULL;
1851 uint8_t i = 0U;
1852 msg = bt_mesh_alloc_buf(1 + srv->property_count * 2 + BLE_MESH_SERVER_TRANS_MIC_SIZE);
1853 if (msg == NULL) {
1854 BT_ERR("%s, Out of memory", __func__);
1855 return;
1856 }
1857 bt_mesh_model_msg_init(msg, BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTIES_STATUS);
1858 for (i = 0U; i < srv->property_count; i++) {
1859 net_buf_simple_add_le16(msg, srv->properties[i].id);
1860 }
1861 BLE_MESH_CHECK_SEND_STATUS(bt_mesh_model_send(model, ctx, msg, NULL, NULL));
1862 bt_mesh_free_buf(msg);
1863 return;
1864 }
1865 case BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTY_GET: {
1866 uint16_t property_id = net_buf_simple_pull_le16(buf);
1867 send_gen_admin_prop_status(model, ctx, property_id, false);
1868 return;
1869 }
1870 default:
1871 BT_WARN("Unknown Generic Admin Property Get opcode 0x%04x", ctx->recv_op);
1872 return;
1873 }
1874 }
1875
gen_admin_prop_set(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)1876 static void gen_admin_prop_set(struct bt_mesh_model *model,
1877 struct bt_mesh_msg_ctx *ctx,
1878 struct net_buf_simple *buf)
1879 {
1880 struct bt_mesh_gen_admin_prop_srv *srv = model->user_data;
1881 struct bt_mesh_generic_property *property = NULL;
1882 uint16_t property_id = 0U;
1883 uint8_t access = 0U;
1884
1885 if (srv == NULL || srv->property_count == 0U || srv->properties == NULL) {
1886 BT_ERR("%s, Invalid model user data", __func__);
1887 return;
1888 }
1889
1890 property_id = net_buf_simple_pull_le16(buf);
1891 access = net_buf_simple_pull_u8(buf);
1892 if (access > ADMIN_ACCESS_READ_WRITE) {
1893 BT_ERR("Invalid Admin Access 0x%02x", access);
1894 return;
1895 }
1896
1897 /* Callback the received message to the application layer */
1898 if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_RSP_BY_APP) {
1899 bt_mesh_gen_server_recv_set_msg_t set = {
1900 .admin_property_set.id = property_id,
1901 .admin_property_set.access = access,
1902 .admin_property_set.value = buf,
1903 };
1904 bt_mesh_generic_server_cb_evt_to_btc(
1905 BTC_BLE_MESH_EVT_GENERIC_SERVER_RECV_SET_MSG, model, ctx, (const uint8_t *)&set, sizeof(set));
1906 return;
1907 }
1908
1909 property = gen_get_admin_property(model, property_id);
1910 if (property == NULL) {
1911 if (ctx->recv_op == BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTY_SET) {
1912 send_gen_admin_prop_status(model, ctx, property_id, false);
1913 }
1914 send_gen_admin_prop_status(model, ctx, property_id, true);
1915 return;
1916 }
1917
1918 property->admin_access = access;
1919
1920 net_buf_simple_reset(property->val);
1921 net_buf_simple_add_mem(property->val, buf->data, MIN(buf->len, property->val->size));
1922
1923 bt_mesh_gen_server_state_change_t change = {
1924 .gen_admin_prop_set.id = property_id,
1925 .gen_admin_prop_set.access = property->admin_access,
1926 .gen_admin_prop_set.value = property->val,
1927 };
1928 bt_mesh_generic_server_cb_evt_to_btc(
1929 BTC_BLE_MESH_EVT_GENERIC_SERVER_STATE_CHANGE, model, ctx, (const uint8_t *)&change, sizeof(change));
1930
1931 if (ctx->recv_op == BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTY_SET) {
1932 send_gen_admin_prop_status(model, ctx, property_id, false);
1933 }
1934 send_gen_admin_prop_status(model, ctx, property_id, true);
1935
1936 return;
1937 }
1938
1939 /* Generic Manufacturer Property Server message handlers */
gen_get_manu_property(struct bt_mesh_model * model,uint16_t property_id)1940 static struct bt_mesh_generic_property *gen_get_manu_property(struct bt_mesh_model *model,
1941 uint16_t property_id)
1942 {
1943 struct bt_mesh_gen_manu_prop_srv *srv = model->user_data;
1944 int i;
1945
1946 for (i = 0; i < srv->property_count; i++) {
1947 if (srv->properties[i].id == property_id) {
1948 return &srv->properties[i];
1949 }
1950 }
1951
1952 return NULL;
1953 }
1954
send_gen_manu_prop_status(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,uint16_t property_id,bool publish)1955 static void send_gen_manu_prop_status(struct bt_mesh_model *model,
1956 struct bt_mesh_msg_ctx *ctx,
1957 uint16_t property_id, bool publish)
1958 {
1959 struct bt_mesh_generic_property *property = NULL;
1960 struct net_buf_simple *msg = NULL;
1961 uint16_t length = 0U;
1962
1963 if (property_id == BLE_MESH_INVALID_DEVICE_PROPERTY_ID) {
1964 BT_ERR("Invalid Manu Property ID 0x%04x", property_id);
1965 return;
1966 }
1967
1968 property = gen_get_manu_property(model, property_id);
1969 if (property == NULL) {
1970 BT_WARN("Manu property 0x%04x not exists", property_id);
1971 length = sizeof(property_id);
1972 } else {
1973 length = sizeof(property->id) + sizeof(property->manu_access) + property->val->len;
1974 }
1975
1976 if (publish == false) {
1977 msg = bt_mesh_alloc_buf(1 + length + BLE_MESH_SERVER_TRANS_MIC_SIZE);
1978 if (msg == NULL) {
1979 BT_ERR("%s, Out of memory", __func__);
1980 return;
1981 }
1982 } else {
1983 msg = bt_mesh_server_get_pub_msg(model, 1 + length);
1984 if (msg == NULL) {
1985 return;
1986 }
1987 }
1988
1989 bt_mesh_model_msg_init(msg, BLE_MESH_MODEL_OP_GEN_MANU_PROPERTY_STATUS);
1990 if (property == NULL) {
1991 net_buf_simple_add_le16(msg, property_id);
1992 } else {
1993 net_buf_simple_add_le16(msg, property->id);
1994 net_buf_simple_add_u8(msg, property->manu_access);
1995 net_buf_simple_add_mem(msg, property->val->data, property->val->len);
1996 }
1997
1998 if (publish == false) {
1999 BLE_MESH_CHECK_SEND_STATUS(bt_mesh_model_send(model, ctx, msg, NULL, NULL));
2000 bt_mesh_free_buf(msg);
2001 } else {
2002 BLE_MESH_CHECK_SEND_STATUS(bt_mesh_model_publish(model));
2003 }
2004 return;
2005 }
2006
gen_manu_prop_get(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)2007 static void gen_manu_prop_get(struct bt_mesh_model *model,
2008 struct bt_mesh_msg_ctx *ctx,
2009 struct net_buf_simple *buf)
2010 {
2011 struct bt_mesh_gen_manu_prop_srv *srv = model->user_data;
2012
2013 if (srv == NULL || srv->property_count == 0U || srv->properties == NULL) {
2014 BT_ERR("%s, Invalid model user data", __func__);
2015 return;
2016 }
2017
2018 /* Callback the received message to the application layer */
2019 if (srv->rsp_ctrl.get_auto_rsp == BLE_MESH_SERVER_RSP_BY_APP) {
2020 bt_mesh_gen_server_recv_get_msg_t get = {0};
2021 const uint8_t *param = NULL;
2022 size_t len = 0U;
2023 if (ctx->recv_op == BLE_MESH_MODEL_OP_GEN_MANU_PROPERTY_GET) {
2024 get.manu_property_get.id = net_buf_simple_pull_le16(buf);
2025 param = (const uint8_t *)&get;
2026 len = sizeof(get);
2027 }
2028 bt_mesh_generic_server_cb_evt_to_btc(
2029 BTC_BLE_MESH_EVT_GENERIC_SERVER_RECV_GET_MSG, model, ctx, param, len);
2030 return;
2031 }
2032
2033 switch (ctx->recv_op) {
2034 case BLE_MESH_MODEL_OP_GEN_MANU_PROPERTIES_GET: {
2035 struct net_buf_simple *msg = NULL;
2036 uint8_t i = 0U;
2037 msg = bt_mesh_alloc_buf(1 + srv->property_count * 2 + BLE_MESH_SERVER_TRANS_MIC_SIZE);
2038 if (msg == NULL) {
2039 BT_ERR("%s, Out of memory", __func__);
2040 return;
2041 }
2042 bt_mesh_model_msg_init(msg, BLE_MESH_MODEL_OP_GEN_MANU_PROPERTIES_STATUS);
2043 for (i = 0U; i < srv->property_count; i++) {
2044 net_buf_simple_add_le16(msg, srv->properties[i].id);
2045 }
2046 BLE_MESH_CHECK_SEND_STATUS(bt_mesh_model_send(model, ctx, msg, NULL, NULL));
2047 bt_mesh_free_buf(msg);
2048 return;
2049 }
2050 case BLE_MESH_MODEL_OP_GEN_MANU_PROPERTY_GET: {
2051 uint16_t property_id = net_buf_simple_pull_le16(buf);
2052 send_gen_manu_prop_status(model, ctx, property_id, false);
2053 return;
2054 }
2055 default:
2056 BT_WARN("Unknown Generic Manu Property Get opcode 0x%04x", ctx->recv_op);
2057 return;
2058 }
2059 }
2060
gen_manu_prop_set(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)2061 static void gen_manu_prop_set(struct bt_mesh_model *model,
2062 struct bt_mesh_msg_ctx *ctx,
2063 struct net_buf_simple *buf)
2064 {
2065 struct bt_mesh_gen_manu_prop_srv *srv = model->user_data;
2066 struct bt_mesh_generic_property *property = NULL;
2067 uint16_t property_id = 0U;
2068 uint8_t access = 0U;
2069
2070 if (srv == NULL || srv->property_count == 0U || srv->properties == NULL) {
2071 BT_ERR("%s, Invalid model user data", __func__);
2072 return;
2073 }
2074
2075 property_id = net_buf_simple_pull_le16(buf);
2076 access = net_buf_simple_pull_u8(buf);
2077 if (access > MANU_ACCESS_READ) {
2078 BT_ERR("Invalid Manu Access 0x%02x", access);
2079 return;
2080 }
2081
2082 /* Callback the received message to the application layer */
2083 if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_RSP_BY_APP) {
2084 bt_mesh_gen_server_recv_set_msg_t set = {
2085 .manu_property_set.id = property_id,
2086 .manu_property_set.access = access,
2087 };
2088 bt_mesh_generic_server_cb_evt_to_btc(
2089 BTC_BLE_MESH_EVT_GENERIC_SERVER_RECV_SET_MSG, model, ctx, (const uint8_t *)&set, sizeof(set));
2090 return;
2091 }
2092
2093 property = gen_get_manu_property(model, property_id);
2094 if (property == NULL) {
2095 if (ctx->recv_op == BLE_MESH_MODEL_OP_GEN_MANU_PROPERTY_SET) {
2096 send_gen_manu_prop_status(model, ctx, property_id, false);
2097 }
2098 send_gen_manu_prop_status(model, ctx, property_id, true);
2099 return;
2100 }
2101
2102 property->manu_access = access;
2103
2104 bt_mesh_gen_server_state_change_t change = {
2105 .gen_manu_prop_set.id = property_id,
2106 .gen_manu_prop_set.access = property->manu_access,
2107 };
2108 bt_mesh_generic_server_cb_evt_to_btc(
2109 BTC_BLE_MESH_EVT_GENERIC_SERVER_STATE_CHANGE, model, ctx, (const uint8_t *)&change, sizeof(change));
2110
2111 if (ctx->recv_op == BLE_MESH_MODEL_OP_GEN_MANU_PROPERTY_SET) {
2112 send_gen_manu_prop_status(model, ctx, property_id, false);
2113 }
2114 send_gen_manu_prop_status(model, ctx, property_id, true);
2115
2116 return;
2117 }
2118
2119 /* Generic Client Property Server message handlers */
search_prop_id_index(const uint16_t * array,uint8_t array_idx,uint16_t id)2120 static int search_prop_id_index(const uint16_t *array, uint8_t array_idx, uint16_t id)
2121 {
2122 static const uint16_t *start = NULL;
2123 uint8_t index = 0U;
2124 uint16_t temp = 0U;
2125
2126 if (start == NULL) {
2127 start = array;
2128 }
2129
2130 if (array_idx == 0U) {
2131 if (*array >= id) {
2132 return array - start;
2133 } else {
2134 return -1;
2135 }
2136 }
2137
2138 index = array_idx / 2;
2139 temp = array[index];
2140
2141 if (temp == id) {
2142 return array + index - start;
2143 } else if (temp > id) {
2144 return search_prop_id_index(array, index, id);
2145 } else {
2146 return search_prop_id_index(array + index + 1, array_idx - 1 - index, id);
2147 }
2148 }
2149
gen_client_prop_get(struct bt_mesh_model * model,struct bt_mesh_msg_ctx * ctx,struct net_buf_simple * buf)2150 static void gen_client_prop_get(struct bt_mesh_model *model,
2151 struct bt_mesh_msg_ctx *ctx,
2152 struct net_buf_simple *buf)
2153 {
2154 struct bt_mesh_gen_client_prop_srv *srv = model->user_data;
2155 struct net_buf_simple *sdu = NULL;
2156 uint16_t total_len = 5U;
2157 uint16_t property_id = 0U;
2158 int i, index = 0;
2159
2160 if (srv == NULL || srv->id_count == 0U || srv->property_ids == NULL) {
2161 BT_ERR("%s, Invalid model user data", __func__);
2162 return;
2163 }
2164
2165 /* Callback the received message to the application layer */
2166 if (srv->rsp_ctrl.get_auto_rsp == BLE_MESH_SERVER_RSP_BY_APP) {
2167 bt_mesh_gen_server_recv_get_msg_t get = {
2168 .client_properties_get.id = net_buf_simple_pull_le16(buf),
2169 };
2170 bt_mesh_generic_server_cb_evt_to_btc(
2171 BTC_BLE_MESH_EVT_GENERIC_SERVER_RECV_GET_MSG, model, ctx, (const uint8_t *)&get, sizeof(get));
2172 return;
2173 }
2174
2175 /* The sequence shall be in an ascending order of Property ID values and shall
2176 * start with a smallest Property ID that is greater than or equal to the value
2177 * of the Generic Client Property field of the Generic Client Properities Get
2178 * message that it is responding to.
2179 */
2180
2181 property_id = net_buf_simple_pull_le16(buf);
2182 index = search_prop_id_index(srv->property_ids, srv->id_count - 1, property_id);
2183 if (index < 0) {
2184 NET_BUF_SIMPLE_DEFINE(msg, 1 + BLE_MESH_SERVER_TRANS_MIC_SIZE);
2185 bt_mesh_model_msg_init(&msg, BLE_MESH_MODEL_OP_GEN_CLIENT_PROPERTIES_STATUS);
2186 BLE_MESH_CHECK_SEND_STATUS(bt_mesh_model_send(model, ctx, &msg, NULL, NULL));
2187 return;
2188 }
2189
2190 sdu = bt_mesh_alloc_buf(MIN(BLE_MESH_TX_SDU_MAX, BLE_MESH_SERVER_RSP_MAX_LEN));
2191 if (sdu == NULL) {
2192 BT_ERR("%s, Out of memory", __func__);
2193 return;
2194 }
2195
2196 bt_mesh_model_msg_init(sdu, BLE_MESH_MODEL_OP_GEN_CLIENT_PROPERTIES_STATUS);
2197 for (i = index; i < srv->id_count; i++) {
2198 total_len += sizeof(uint16_t);
2199 if (total_len > MIN(BLE_MESH_TX_SDU_MAX, BLE_MESH_SERVER_RSP_MAX_LEN)) {
2200 /* Add this in case the message is too long */
2201 BT_WARN("Too large generic client properties status");
2202 break;
2203 }
2204 net_buf_simple_add_le16(sdu, srv->property_ids[i]);
2205 }
2206
2207 BLE_MESH_CHECK_SEND_STATUS(bt_mesh_model_send(model, ctx, sdu, NULL, NULL));
2208 bt_mesh_free_buf(sdu);
2209 return;
2210 }
2211
2212 /* message handlers (End) */
2213
2214 /* Mapping of message handlers for Generic OnOff Server (0x1000) */
2215 const struct bt_mesh_model_op bt_mesh_gen_onoff_srv_op[] = {
2216 { BLE_MESH_MODEL_OP_GEN_ONOFF_GET, 0, gen_onoff_get },
2217 { BLE_MESH_MODEL_OP_GEN_ONOFF_SET, 2, gen_onoff_set },
2218 { BLE_MESH_MODEL_OP_GEN_ONOFF_SET_UNACK, 2, gen_onoff_set },
2219 BLE_MESH_MODEL_OP_END,
2220 };
2221
2222 /* Mapping of message handlers for Generic Level Server (0x1002) */
2223 const struct bt_mesh_model_op bt_mesh_gen_level_srv_op[] = {
2224 { BLE_MESH_MODEL_OP_GEN_LEVEL_GET, 0, gen_level_get },
2225 { BLE_MESH_MODEL_OP_GEN_LEVEL_SET, 3, gen_level_set },
2226 { BLE_MESH_MODEL_OP_GEN_LEVEL_SET_UNACK, 3, gen_level_set },
2227 { BLE_MESH_MODEL_OP_GEN_DELTA_SET, 5, gen_delta_set },
2228 { BLE_MESH_MODEL_OP_GEN_DELTA_SET_UNACK, 5, gen_delta_set },
2229 { BLE_MESH_MODEL_OP_GEN_MOVE_SET, 3, gen_move_set },
2230 { BLE_MESH_MODEL_OP_GEN_MOVE_SET_UNACK, 3, gen_move_set },
2231 BLE_MESH_MODEL_OP_END,
2232 };
2233
2234 /* Mapping of message handlers for Generic Default TT Server (0x1004) */
2235 const struct bt_mesh_model_op bt_mesh_gen_def_trans_time_srv_op[] = {
2236 { BLE_MESH_MODEL_OP_GEN_DEF_TRANS_TIME_GET, 0, gen_def_trans_time_get },
2237 { BLE_MESH_MODEL_OP_GEN_DEF_TRANS_TIME_SET, 1, gen_def_trans_time_set },
2238 { BLE_MESH_MODEL_OP_GEN_DEF_TRANS_TIME_SET_UNACK, 1, gen_def_trans_time_set },
2239 BLE_MESH_MODEL_OP_END,
2240 };
2241
2242 /* Mapping of message handlers for Generic Power OnOff Server (0x1006) */
2243 const struct bt_mesh_model_op bt_mesh_gen_power_onoff_srv_op[] = {
2244 { BLE_MESH_MODEL_OP_GEN_ONPOWERUP_GET, 0, gen_onpowerup_get },
2245 BLE_MESH_MODEL_OP_END,
2246 };
2247
2248 /* Mapping of message handlers for Generic Power OnOff Setup Server (0x1007) */
2249 const struct bt_mesh_model_op bt_mesh_gen_power_onoff_setup_srv_op[] = {
2250 { BLE_MESH_MODEL_OP_GEN_ONPOWERUP_SET, 1, gen_onpowerup_set },
2251 { BLE_MESH_MODEL_OP_GEN_ONPOWERUP_SET_UNACK, 1, gen_onpowerup_set },
2252 BLE_MESH_MODEL_OP_END,
2253 };
2254
2255 /* Mapping of message handlers for Generic Power Level Server (0x1009) */
2256 const struct bt_mesh_model_op bt_mesh_gen_power_level_srv_op[] = {
2257 { BLE_MESH_MODEL_OP_GEN_POWER_LEVEL_GET, 0, gen_power_level_get },
2258 { BLE_MESH_MODEL_OP_GEN_POWER_LEVEL_SET, 3, gen_power_level_set },
2259 { BLE_MESH_MODEL_OP_GEN_POWER_LEVEL_SET_UNACK, 3, gen_power_level_set },
2260 { BLE_MESH_MODEL_OP_GEN_POWER_LAST_GET, 0, gen_power_level_get },
2261 { BLE_MESH_MODEL_OP_GEN_POWER_DEFAULT_GET, 0, gen_power_level_get },
2262 { BLE_MESH_MODEL_OP_GEN_POWER_RANGE_GET, 0, gen_power_level_get },
2263 BLE_MESH_MODEL_OP_END,
2264 };
2265
2266 /* Mapping of message handlers for Generic Power Level Setup Server (0x100A) */
2267 const struct bt_mesh_model_op bt_mesh_gen_power_level_setup_srv_op[] = {
2268 { BLE_MESH_MODEL_OP_GEN_POWER_DEFAULT_SET, 2, gen_power_default_set },
2269 { BLE_MESH_MODEL_OP_GEN_POWER_DEFAULT_SET_UNACK, 2, gen_power_default_set },
2270 { BLE_MESH_MODEL_OP_GEN_POWER_RANGE_SET, 4, gen_power_range_set },
2271 { BLE_MESH_MODEL_OP_GEN_POWER_RANGE_SET_UNACK, 4, gen_power_range_set },
2272 BLE_MESH_MODEL_OP_END,
2273 };
2274
2275 /* Mapping of message handlers for Generic Battery Server (0x100C) */
2276 const struct bt_mesh_model_op bt_mesh_gen_battery_srv_op[] = {
2277 { BLE_MESH_MODEL_OP_GEN_BATTERY_GET, 0, gen_battery_get },
2278 BLE_MESH_MODEL_OP_END,
2279 };
2280
2281 /* Mapping of message handlers for Generic Location Server (0x100E) */
2282 const struct bt_mesh_model_op bt_mesh_gen_location_srv_op[] = {
2283 { BLE_MESH_MODEL_OP_GEN_LOC_GLOBAL_GET, 0, gen_location_get },
2284 { BLE_MESH_MODEL_OP_GEN_LOC_LOCAL_GET, 0, gen_location_get },
2285 BLE_MESH_MODEL_OP_END,
2286 };
2287
2288 /* Mapping of message handlers for Generic Location Setup Server (0x100F) */
2289 const struct bt_mesh_model_op bt_mesh_gen_location_setup_srv_op[] = {
2290 { BLE_MESH_MODEL_OP_GEN_LOC_GLOBAL_SET, 10, gen_location_set },
2291 { BLE_MESH_MODEL_OP_GEN_LOC_GLOBAL_SET_UNACK, 10, gen_location_set },
2292 { BLE_MESH_MODEL_OP_GEN_LOC_LOCAL_SET, 9, gen_location_set },
2293 { BLE_MESH_MODEL_OP_GEN_LOC_LOCAL_SET_UNACK, 9, gen_location_set },
2294 BLE_MESH_MODEL_OP_END,
2295 };
2296
2297 /* Mapping of message handlers for Generic User Property Server (0x1013) */
2298 const struct bt_mesh_model_op bt_mesh_gen_user_prop_srv_op[] = {
2299 { BLE_MESH_MODEL_OP_GEN_USER_PROPERTIES_GET, 0, gen_user_prop_get },
2300 { BLE_MESH_MODEL_OP_GEN_USER_PROPERTY_GET, 2, gen_user_prop_get },
2301 { BLE_MESH_MODEL_OP_GEN_USER_PROPERTY_SET, 3, gen_user_prop_set },
2302 { BLE_MESH_MODEL_OP_GEN_USER_PROPERTY_SET_UNACK, 3, gen_user_prop_set },
2303 BLE_MESH_MODEL_OP_END,
2304 };
2305
2306 /* Mapping of message handlers for Generic Admin Property Server (0x1011) */
2307 const struct bt_mesh_model_op bt_mesh_gen_admin_prop_srv_op[] = {
2308 { BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTIES_GET, 0, gen_admin_prop_get },
2309 { BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTY_GET, 2, gen_admin_prop_get },
2310 { BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTY_SET, 4, gen_admin_prop_set },
2311 { BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTY_SET_UNACK, 4, gen_admin_prop_set },
2312 BLE_MESH_MODEL_OP_END,
2313 };
2314
2315 /* Mapping of message handlers for Generic Manufacturer Property Server (0x1012) */
2316 const struct bt_mesh_model_op bt_mesh_gen_manu_prop_srv_op[] = {
2317 { BLE_MESH_MODEL_OP_GEN_MANU_PROPERTIES_GET, 0, gen_manu_prop_get },
2318 { BLE_MESH_MODEL_OP_GEN_MANU_PROPERTY_GET, 2, gen_manu_prop_get },
2319 { BLE_MESH_MODEL_OP_GEN_MANU_PROPERTY_SET, 3, gen_manu_prop_set },
2320 { BLE_MESH_MODEL_OP_GEN_MANU_PROPERTY_SET_UNACK, 3, gen_manu_prop_set },
2321 BLE_MESH_MODEL_OP_END,
2322 };
2323
2324 /* Mapping of message handlers for Generic Client Property Server (0x1014) */
2325 const struct bt_mesh_model_op bt_mesh_gen_client_prop_srv_op[] = {
2326 { BLE_MESH_MODEL_OP_GEN_CLIENT_PROPERTIES_GET, 2, gen_client_prop_get },
2327 BLE_MESH_MODEL_OP_END,
2328 };
2329
property_id_compare(const void * p1,const void * p2)2330 static inline int property_id_compare(const void *p1, const void *p2)
2331 {
2332 if (*(uint16_t *)p1 < * (uint16_t *)p2) {
2333 return -1;
2334 }
2335 if (*(uint16_t *)p1 > *(uint16_t *)p2) {
2336 return 1;
2337 }
2338 return 0;
2339 }
2340
generic_server_init(struct bt_mesh_model * model)2341 static int generic_server_init(struct bt_mesh_model *model)
2342 {
2343 if (model->user_data == NULL) {
2344 BT_ERR("Invalid Generic Server user data, model id 0x%04x", model->id);
2345 return -EINVAL;
2346 }
2347
2348 switch (model->id) {
2349 case BLE_MESH_MODEL_ID_GEN_ONOFF_SRV: {
2350 struct bt_mesh_gen_onoff_srv *srv = model->user_data;
2351 if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_AUTO_RSP) {
2352 bt_mesh_server_alloc_ctx(&srv->transition.timer.work);
2353 k_delayed_work_init(&srv->transition.timer, generic_onoff_work_handler);
2354 }
2355 srv->model = model;
2356 break;
2357 }
2358 case BLE_MESH_MODEL_ID_GEN_LEVEL_SRV: {
2359 struct bt_mesh_gen_level_srv *srv = model->user_data;
2360 if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_AUTO_RSP) {
2361 bt_mesh_server_alloc_ctx(&srv->transition.timer.work);
2362 k_delayed_work_init(&srv->transition.timer, generic_level_work_handler);
2363 }
2364 srv->model = model;
2365 break;
2366 }
2367 case BLE_MESH_MODEL_ID_GEN_DEF_TRANS_TIME_SRV: {
2368 struct bt_mesh_gen_def_trans_time_srv *srv = model->user_data;
2369 srv->model = model;
2370 break;
2371 }
2372 case BLE_MESH_MODEL_ID_GEN_POWER_ONOFF_SRV: {
2373 struct bt_mesh_gen_power_onoff_srv *srv = model->user_data;
2374 if (srv->state == NULL) {
2375 BT_ERR("Invalid Generic OnPowerUp State");
2376 return -EINVAL;
2377 }
2378 srv->model = model;
2379 break;
2380 }
2381 case BLE_MESH_MODEL_ID_GEN_POWER_ONOFF_SETUP_SRV: {
2382 struct bt_mesh_gen_power_onoff_setup_srv *srv = model->user_data;
2383 if (srv->state == NULL) {
2384 BT_ERR("Invalid Generic OnPowerUp State");
2385 return -EINVAL;
2386 }
2387 srv->model = model;
2388 break;
2389 }
2390 case BLE_MESH_MODEL_ID_GEN_POWER_LEVEL_SRV: {
2391 struct bt_mesh_gen_power_level_srv *srv = model->user_data;
2392 if (srv->state == NULL) {
2393 BT_ERR("Invalid Generic Power Level State");
2394 return -EINVAL;
2395 }
2396 if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_AUTO_RSP) {
2397 bt_mesh_server_alloc_ctx(&srv->transition.timer.work);
2398 k_delayed_work_init(&srv->transition.timer, generic_power_level_work_handler);
2399 }
2400 srv->model = model;
2401 break;
2402 }
2403 case BLE_MESH_MODEL_ID_GEN_POWER_LEVEL_SETUP_SRV: {
2404 struct bt_mesh_gen_power_level_setup_srv *srv = model->user_data;
2405 if (srv->state == NULL) {
2406 BT_ERR("Invalid Generic Power Level State");
2407 return -EINVAL;
2408 }
2409 srv->model = model;
2410 break;
2411 }
2412 case BLE_MESH_MODEL_ID_GEN_BATTERY_SRV: {
2413 struct bt_mesh_gen_battery_srv *srv = model->user_data;
2414 srv->model = model;
2415 break;
2416 }
2417 case BLE_MESH_MODEL_ID_GEN_LOCATION_SRV: {
2418 struct bt_mesh_gen_location_srv *srv = model->user_data;
2419 if (srv->state == NULL) {
2420 BT_ERR("Invalid Generic Location State");
2421 return -EINVAL;
2422 }
2423 srv->model = model;
2424 break;
2425 }
2426 case BLE_MESH_MODEL_ID_GEN_LOCATION_SETUP_SRV: {
2427 struct bt_mesh_gen_location_setup_srv *srv = model->user_data;
2428 if (srv->state == NULL) {
2429 BT_ERR("Invalid Generic Location State");
2430 return -EINVAL;
2431 }
2432 srv->model = model;
2433 break;
2434 }
2435 case BLE_MESH_MODEL_ID_GEN_USER_PROP_SRV: {
2436 struct bt_mesh_gen_user_prop_srv *srv = model->user_data;
2437 if (srv->property_count == 0U || srv->properties == NULL) {
2438 BT_ERR("Invalid Generic User Property State");
2439 return -EINVAL;
2440 }
2441 srv->model = model;
2442 break;
2443 }
2444 case BLE_MESH_MODEL_ID_GEN_ADMIN_PROP_SRV: {
2445 struct bt_mesh_gen_admin_prop_srv *srv = model->user_data;
2446 if (srv->property_count == 0U || srv->properties == NULL) {
2447 BT_ERR("Invalid Generic Admin Property State");
2448 return -EINVAL;
2449 }
2450 srv->model = model;
2451 break;
2452 }
2453 case BLE_MESH_MODEL_ID_GEN_MANUFACTURER_PROP_SRV: {
2454 struct bt_mesh_gen_manu_prop_srv *srv = model->user_data;
2455 if (srv->property_count == 0U || srv->properties == NULL) {
2456 BT_ERR("Invalid Generic Manufacturer Property State");
2457 return -EINVAL;
2458 }
2459 srv->model = model;
2460 break;
2461 }
2462 case BLE_MESH_MODEL_ID_GEN_CLIENT_PROP_SRV: {
2463 struct bt_mesh_gen_client_prop_srv *srv = model->user_data;
2464 if (srv->id_count == 0U || srv->property_ids == NULL) {
2465 BT_ERR("Invalid Generic Client Property State");
2466 return -EINVAL;
2467 }
2468 /* Quick sort the Client Property IDs in ascending order */
2469 qsort(srv->property_ids, srv->id_count, sizeof(uint16_t), property_id_compare);
2470 srv->model = model;
2471 break;
2472 }
2473 default:
2474 BT_WARN("Unknown Generic Server, model id 0x%04x", model->id);
2475 return -EINVAL;
2476 }
2477
2478 bt_mesh_generic_server_mutex_new();
2479
2480 return 0;
2481 }
2482
gen_onoff_srv_init(struct bt_mesh_model * model)2483 static int gen_onoff_srv_init(struct bt_mesh_model *model)
2484 {
2485 if (model->pub == NULL) {
2486 BT_ERR("Generic OnOff Server has no publication support");
2487 return -EINVAL;
2488 }
2489
2490 return generic_server_init(model);
2491 }
2492
gen_level_srv_init(struct bt_mesh_model * model)2493 static int gen_level_srv_init(struct bt_mesh_model *model)
2494 {
2495 if (model->pub == NULL) {
2496 BT_ERR("Generic Level Server has no publication support");
2497 return -EINVAL;
2498 }
2499
2500 return generic_server_init(model);
2501 }
2502
gen_def_trans_time_srv_init(struct bt_mesh_model * model)2503 static int gen_def_trans_time_srv_init(struct bt_mesh_model *model)
2504 {
2505 if (model->pub == NULL) {
2506 BT_ERR("Generic Default Trans Time Server has no publication support");
2507 return -EINVAL;
2508 }
2509
2510 return generic_server_init(model);
2511 }
2512
gen_power_onoff_srv_init(struct bt_mesh_model * model)2513 static int gen_power_onoff_srv_init(struct bt_mesh_model *model)
2514 {
2515 if (model->pub == NULL) {
2516 BT_ERR("Generic Power OnOff Server has no publication support");
2517 return -EINVAL;
2518 }
2519
2520 /* When this model is present on an element, the corresponding Generic
2521 * Power OnOff Setup Server model shall also be present.
2522 */
2523 struct bt_mesh_elem *element = bt_mesh_model_elem(model);
2524 if (bt_mesh_model_find(element, BLE_MESH_MODEL_ID_GEN_POWER_ONOFF_SETUP_SRV) == NULL) {
2525 BT_WARN("Generic Power OnOff Setup Server not present");
2526 /* Just give a warning here, continue with the initialization */
2527 }
2528 return generic_server_init(model);
2529 }
2530
gen_power_onoff_setup_srv_init(struct bt_mesh_model * model)2531 static int gen_power_onoff_setup_srv_init(struct bt_mesh_model *model)
2532 {
2533 return generic_server_init(model);
2534 }
2535
gen_power_level_srv_init(struct bt_mesh_model * model)2536 static int gen_power_level_srv_init(struct bt_mesh_model *model)
2537 {
2538 if (model->pub == NULL) {
2539 BT_ERR("Generic Power Level Server has no publication support");
2540 return -EINVAL;
2541 }
2542
2543 /* When this model is present on an Element, the corresponding Generic
2544 * Power Level Setup Server model shall also be present.
2545 */
2546 struct bt_mesh_elem *element = bt_mesh_model_elem(model);
2547 if (bt_mesh_model_find(element, BLE_MESH_MODEL_ID_GEN_POWER_LEVEL_SETUP_SRV) == NULL) {
2548 BT_WARN("Generic Power Level Setup Server not present");
2549 /* Just give a warning here, continue with the initialization */
2550 }
2551 return generic_server_init(model);
2552 }
2553
gen_power_level_setup_srv_init(struct bt_mesh_model * model)2554 static int gen_power_level_setup_srv_init(struct bt_mesh_model *model)
2555 {
2556 return generic_server_init(model);
2557 }
2558
gen_battery_srv_init(struct bt_mesh_model * model)2559 static int gen_battery_srv_init(struct bt_mesh_model *model)
2560 {
2561 if (model->pub == NULL) {
2562 BT_ERR("Generic Battery Server has no publication support");
2563 return -EINVAL;
2564 }
2565
2566 return generic_server_init(model);
2567 }
2568
gen_location_srv_init(struct bt_mesh_model * model)2569 static int gen_location_srv_init(struct bt_mesh_model *model)
2570 {
2571 if (model->pub == NULL) {
2572 BT_ERR("Generic Location Server has no publication support");
2573 return -EINVAL;
2574 }
2575
2576 return generic_server_init(model);
2577 }
2578
gen_location_setup_srv_init(struct bt_mesh_model * model)2579 static int gen_location_setup_srv_init(struct bt_mesh_model *model)
2580 {
2581 /* When this model is present on an Element, the corresponding Generic
2582 * Location Setup Server model shall also be present.
2583 */
2584 struct bt_mesh_elem *element = bt_mesh_model_elem(model);
2585 if (bt_mesh_model_find(element, BLE_MESH_MODEL_ID_GEN_LOCATION_SETUP_SRV) == NULL) {
2586 BT_WARN("Generic Location Setup Server not present");
2587 /* Just give a warning here, continue with the initialization */
2588 }
2589 return generic_server_init(model);
2590 }
2591
gen_user_prop_srv_init(struct bt_mesh_model * model)2592 static int gen_user_prop_srv_init(struct bt_mesh_model *model)
2593 {
2594 if (model->pub == NULL) {
2595 BT_ERR("Generic User Property Server has no publication support");
2596 return -EINVAL;
2597 }
2598
2599 return generic_server_init(model);
2600 }
2601
gen_admin_prop_srv_init(struct bt_mesh_model * model)2602 static int gen_admin_prop_srv_init(struct bt_mesh_model *model)
2603 {
2604 if (model->pub == NULL) {
2605 BT_ERR("Generic Admin Property Server has no publication support");
2606 return -EINVAL;
2607 }
2608
2609 return generic_server_init(model);
2610 }
2611
gen_manu_prop_srv_init(struct bt_mesh_model * model)2612 static int gen_manu_prop_srv_init(struct bt_mesh_model *model)
2613 {
2614 if (model->pub == NULL) {
2615 BT_ERR("Generic Manufacturer Property Server has no publication support");
2616 return -EINVAL;
2617 }
2618
2619 return generic_server_init(model);
2620 }
2621
gen_client_prop_srv_init(struct bt_mesh_model * model)2622 static int gen_client_prop_srv_init(struct bt_mesh_model *model)
2623 {
2624 if (model->pub == NULL) {
2625 BT_ERR("Generic Client Property Server has no publication support");
2626 return -EINVAL;
2627 }
2628
2629 return generic_server_init(model);
2630 }
2631
2632 #if CONFIG_BLE_MESH_DEINIT
generic_server_deinit(struct bt_mesh_model * model)2633 static int generic_server_deinit(struct bt_mesh_model *model)
2634 {
2635 if (model->user_data == NULL) {
2636 BT_ERR("Invalid Generic Server user data, model id 0x%04x", model->id);
2637 return -EINVAL;
2638 }
2639
2640 switch (model->id) {
2641 case BLE_MESH_MODEL_ID_GEN_ONOFF_SRV: {
2642 struct bt_mesh_gen_onoff_srv *srv = model->user_data;
2643 if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_AUTO_RSP) {
2644 bt_mesh_server_free_ctx(&srv->transition.timer.work);
2645 k_delayed_work_free(&srv->transition.timer);
2646 }
2647 break;
2648 }
2649 case BLE_MESH_MODEL_ID_GEN_LEVEL_SRV: {
2650 struct bt_mesh_gen_level_srv *srv = model->user_data;
2651 if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_AUTO_RSP) {
2652 bt_mesh_server_free_ctx(&srv->transition.timer.work);
2653 k_delayed_work_free(&srv->transition.timer);
2654 }
2655 break;
2656 }
2657 case BLE_MESH_MODEL_ID_GEN_POWER_LEVEL_SRV: {
2658 struct bt_mesh_gen_power_level_srv *srv = model->user_data;
2659 if (srv->state == NULL) {
2660 BT_ERR("Invalid Generic Power Level State");
2661 return -EINVAL;
2662 }
2663 if (srv->rsp_ctrl.set_auto_rsp == BLE_MESH_SERVER_AUTO_RSP) {
2664 bt_mesh_server_free_ctx(&srv->transition.timer.work);
2665 k_delayed_work_free(&srv->transition.timer);
2666 }
2667 break;
2668 }
2669 case BLE_MESH_MODEL_ID_GEN_DEF_TRANS_TIME_SRV:
2670 case BLE_MESH_MODEL_ID_GEN_POWER_ONOFF_SRV:
2671 case BLE_MESH_MODEL_ID_GEN_POWER_ONOFF_SETUP_SRV:
2672 case BLE_MESH_MODEL_ID_GEN_POWER_LEVEL_SETUP_SRV:
2673 case BLE_MESH_MODEL_ID_GEN_BATTERY_SRV:
2674 case BLE_MESH_MODEL_ID_GEN_LOCATION_SRV:
2675 case BLE_MESH_MODEL_ID_GEN_LOCATION_SETUP_SRV:
2676 case BLE_MESH_MODEL_ID_GEN_USER_PROP_SRV:
2677 case BLE_MESH_MODEL_ID_GEN_ADMIN_PROP_SRV:
2678 case BLE_MESH_MODEL_ID_GEN_MANUFACTURER_PROP_SRV:
2679 case BLE_MESH_MODEL_ID_GEN_CLIENT_PROP_SRV:
2680 break;
2681 default:
2682 BT_WARN("Unknown Generic Server, model id 0x%04x", model->id);
2683 return -EINVAL;
2684 }
2685
2686 bt_mesh_generic_server_mutex_free();
2687
2688 return 0;
2689 }
2690
gen_onoff_srv_deinit(struct bt_mesh_model * model)2691 static int gen_onoff_srv_deinit(struct bt_mesh_model *model)
2692 {
2693 if (model->pub == NULL) {
2694 BT_ERR("Generic OnOff Server has no publication support");
2695 return -EINVAL;
2696 }
2697
2698 return generic_server_deinit(model);
2699 }
2700
gen_level_srv_deinit(struct bt_mesh_model * model)2701 static int gen_level_srv_deinit(struct bt_mesh_model *model)
2702 {
2703 if (model->pub == NULL) {
2704 BT_ERR("Generic Level Server has no publication support");
2705 return -EINVAL;
2706 }
2707
2708 return generic_server_deinit(model);
2709 }
2710
gen_def_trans_time_srv_deinit(struct bt_mesh_model * model)2711 static int gen_def_trans_time_srv_deinit(struct bt_mesh_model *model)
2712 {
2713 if (model->pub == NULL) {
2714 BT_ERR("Generic Default Trans Time Server has no publication support");
2715 return -EINVAL;
2716 }
2717
2718 return generic_server_deinit(model);
2719 }
2720
gen_power_onoff_srv_deinit(struct bt_mesh_model * model)2721 static int gen_power_onoff_srv_deinit(struct bt_mesh_model *model)
2722 {
2723 if (model->pub == NULL) {
2724 BT_ERR("Generic Power OnOff Server has no publication support");
2725 return -EINVAL;
2726 }
2727
2728 return generic_server_deinit(model);
2729 }
2730
gen_power_onoff_setup_srv_deinit(struct bt_mesh_model * model)2731 static int gen_power_onoff_setup_srv_deinit(struct bt_mesh_model *model)
2732 {
2733 return generic_server_deinit(model);
2734 }
2735
gen_power_level_srv_deinit(struct bt_mesh_model * model)2736 static int gen_power_level_srv_deinit(struct bt_mesh_model *model)
2737 {
2738 if (model->pub == NULL) {
2739 BT_ERR("Generic Power Level Server has no publication support");
2740 return -EINVAL;
2741 }
2742
2743 return generic_server_deinit(model);
2744 }
2745
gen_power_level_setup_srv_deinit(struct bt_mesh_model * model)2746 static int gen_power_level_setup_srv_deinit(struct bt_mesh_model *model)
2747 {
2748 return generic_server_deinit(model);
2749 }
2750
gen_battery_srv_deinit(struct bt_mesh_model * model)2751 static int gen_battery_srv_deinit(struct bt_mesh_model *model)
2752 {
2753 if (model->pub == NULL) {
2754 BT_ERR("Generic Battery Server has no publication support");
2755 return -EINVAL;
2756 }
2757
2758 return generic_server_deinit(model);
2759 }
2760
gen_location_srv_deinit(struct bt_mesh_model * model)2761 static int gen_location_srv_deinit(struct bt_mesh_model *model)
2762 {
2763 if (model->pub == NULL) {
2764 BT_ERR("Generic Location Server has no publication support");
2765 return -EINVAL;
2766 }
2767
2768 return generic_server_deinit(model);
2769 }
2770
gen_location_setup_srv_deinit(struct bt_mesh_model * model)2771 static int gen_location_setup_srv_deinit(struct bt_mesh_model *model)
2772 {
2773 return generic_server_deinit(model);
2774 }
2775
gen_user_prop_srv_deinit(struct bt_mesh_model * model)2776 static int gen_user_prop_srv_deinit(struct bt_mesh_model *model)
2777 {
2778 if (model->pub == NULL) {
2779 BT_ERR("Generic User Property Server has no publication support");
2780 return -EINVAL;
2781 }
2782
2783 return generic_server_deinit(model);
2784 }
2785
gen_admin_prop_srv_deinit(struct bt_mesh_model * model)2786 static int gen_admin_prop_srv_deinit(struct bt_mesh_model *model)
2787 {
2788 if (model->pub == NULL) {
2789 BT_ERR("Generic Admin Property Server has no publication support");
2790 return -EINVAL;
2791 }
2792
2793 return generic_server_deinit(model);
2794 }
2795
gen_manu_prop_srv_deinit(struct bt_mesh_model * model)2796 static int gen_manu_prop_srv_deinit(struct bt_mesh_model *model)
2797 {
2798 if (model->pub == NULL) {
2799 BT_ERR("Generic Manufacturer Property Server has no publication support");
2800 return -EINVAL;
2801 }
2802
2803 return generic_server_deinit(model);
2804 }
2805
gen_client_prop_srv_deinit(struct bt_mesh_model * model)2806 static int gen_client_prop_srv_deinit(struct bt_mesh_model *model)
2807 {
2808 if (model->pub == NULL) {
2809 BT_ERR("Generic Client Property Server has no publication support");
2810 return -EINVAL;
2811 }
2812
2813 return generic_server_deinit(model);
2814 }
2815 #endif /* CONFIG_BLE_MESH_DEINIT */
2816
2817 const struct bt_mesh_model_cb bt_mesh_gen_onoff_srv_cb = {
2818 .init = gen_onoff_srv_init,
2819 #if CONFIG_BLE_MESH_DEINIT
2820 .deinit = gen_onoff_srv_deinit,
2821 #endif /* CONFIG_BLE_MESH_DEINIT */
2822 };
2823
2824 const struct bt_mesh_model_cb bt_mesh_gen_level_srv_cb = {
2825 .init = gen_level_srv_init,
2826 #if CONFIG_BLE_MESH_DEINIT
2827 .deinit = gen_level_srv_deinit,
2828 #endif /* CONFIG_BLE_MESH_DEINIT */
2829 };
2830
2831 const struct bt_mesh_model_cb bt_mesh_gen_def_trans_time_srv_cb = {
2832 .init = gen_def_trans_time_srv_init,
2833 #if CONFIG_BLE_MESH_DEINIT
2834 .deinit = gen_def_trans_time_srv_deinit,
2835 #endif /* CONFIG_BLE_MESH_DEINIT */
2836 };
2837
2838 const struct bt_mesh_model_cb bt_mesh_gen_power_onoff_srv_cb = {
2839 .init = gen_power_onoff_srv_init,
2840 #if CONFIG_BLE_MESH_DEINIT
2841 .deinit = gen_power_onoff_srv_deinit,
2842 #endif /* CONFIG_BLE_MESH_DEINIT */
2843 };
2844
2845 const struct bt_mesh_model_cb bt_mesh_gen_power_onoff_setup_srv_cb = {
2846 .init = gen_power_onoff_setup_srv_init,
2847 #if CONFIG_BLE_MESH_DEINIT
2848 .deinit = gen_power_onoff_setup_srv_deinit,
2849 #endif /* CONFIG_BLE_MESH_DEINIT */
2850 };
2851
2852 const struct bt_mesh_model_cb bt_mesh_gen_power_level_srv_cb = {
2853 .init = gen_power_level_srv_init,
2854 #if CONFIG_BLE_MESH_DEINIT
2855 .deinit = gen_power_level_srv_deinit,
2856 #endif /* CONFIG_BLE_MESH_DEINIT */
2857 };
2858
2859 const struct bt_mesh_model_cb bt_mesh_gen_power_level_setup_srv_cb = {
2860 .init = gen_power_level_setup_srv_init,
2861 #if CONFIG_BLE_MESH_DEINIT
2862 .deinit = gen_power_level_setup_srv_deinit,
2863 #endif /* CONFIG_BLE_MESH_DEINIT */
2864 };
2865
2866 const struct bt_mesh_model_cb bt_mesh_gen_battery_srv_cb = {
2867 .init = gen_battery_srv_init,
2868 #if CONFIG_BLE_MESH_DEINIT
2869 .deinit = gen_battery_srv_deinit,
2870 #endif /* CONFIG_BLE_MESH_DEINIT */
2871 };
2872
2873 const struct bt_mesh_model_cb bt_mesh_gen_location_srv_cb = {
2874 .init = gen_location_srv_init,
2875 #if CONFIG_BLE_MESH_DEINIT
2876 .deinit = gen_location_srv_deinit,
2877 #endif /* CONFIG_BLE_MESH_DEINIT */
2878 };
2879
2880 const struct bt_mesh_model_cb bt_mesh_gen_location_setup_srv_cb = {
2881 .init = gen_location_setup_srv_init,
2882 #if CONFIG_BLE_MESH_DEINIT
2883 .deinit = gen_location_setup_srv_deinit,
2884 #endif /* CONFIG_BLE_MESH_DEINIT */
2885 };
2886
2887 const struct bt_mesh_model_cb bt_mesh_gen_user_prop_srv_cb = {
2888 .init = gen_user_prop_srv_init,
2889 #if CONFIG_BLE_MESH_DEINIT
2890 .deinit = gen_user_prop_srv_deinit,
2891 #endif /* CONFIG_BLE_MESH_DEINIT */
2892 };
2893
2894 const struct bt_mesh_model_cb bt_mesh_gen_admin_prop_srv_cb = {
2895 .init = gen_admin_prop_srv_init,
2896 #if CONFIG_BLE_MESH_DEINIT
2897 .deinit = gen_admin_prop_srv_deinit,
2898 #endif /* CONFIG_BLE_MESH_DEINIT */
2899 };
2900
2901 const struct bt_mesh_model_cb bt_mesh_gen_manu_prop_srv_cb = {
2902 .init = gen_manu_prop_srv_init,
2903 #if CONFIG_BLE_MESH_DEINIT
2904 .deinit = gen_manu_prop_srv_deinit,
2905 #endif /* CONFIG_BLE_MESH_DEINIT */
2906 };
2907
2908 const struct bt_mesh_model_cb bt_mesh_gen_client_prop_srv_cb = {
2909 .init = gen_client_prop_srv_init,
2910 #if CONFIG_BLE_MESH_DEINIT
2911 .deinit = gen_client_prop_srv_deinit,
2912 #endif /* CONFIG_BLE_MESH_DEINIT */
2913 };
2914
2915 #endif /* CONFIG_BLE_MESH_GENERIC_SERVER */
2916