MeshX 0.3
This repository provides an implementation for Bluetooth Low Energy (BLE) Mesh network nodes. The project allows you to create BLE mesh nodes that can communicate with each other, enabling the development of smart home solutions or other IoT-based applications.
Loading...
Searching...
No Matches
meshx_light_cwww_client.c
Go to the documentation of this file.
1
24#include "meshx_common.h"
25#include "meshx_control_task.h"
26#include "meshx_nvs.h"
27#include "meshx_api.h"
28
29#if CONFIG_LIGHT_CWWW_CLIENT_COUNT > 0
31
32#if CONFIG_ENABLE_CONFIG_SERVER
33#include "meshx_config_server.h"
34
38#define CONFIG_SERVER_CB_MASK \
39 CONTROL_TASK_MSG_EVT_PUB_ADD \
40 | CONTROL_TASK_MSG_EVT_SUB_ADD \
41 | CONTROL_TASK_MSG_EVT_APP_KEY_BIND
42#endif /* CONFIG_ENABLE_CONFIG_SERVER */
43
47#if defined(__MESHX_CONTROL_TASK__)
48#define CONTROL_TASK_MSG_CODE_EVT_MASK \
49 CONTROL_TASK_MSG_EVT_TO_BLE_SET_ON_OFF \
50 | CONTROL_TASK_MSG_EVT_TO_BLE_SET_CTL
51#endif /* __MESHX_CONTROL_TASK__ */
52
53#define MOD_LCC MODULE_ID_ELEMENT_LIGHT_CWWWW_CLIENT
54#define CWWW_CLI_MESHX_ONOFF_ENABLE_CB true
55#define CWWW_CLI_EL_STATE_CH_EVT_MASK CONTROL_TASK_MSG_EVT_EL_STATE_CH_SET_ON_OFF | CONTROL_TASK_MSG_EVT_EL_STATE_CH_SET_CTL
56
57#define IS_EL_IN_RANGE(_element_id) ((_element_id) >= cwww_client_element_init_ctrl.element_id_start && (_element_id) < cwww_client_element_init_ctrl.element_id_end)
58#define GET_RELATIVE_EL_IDX(_element_id) ((_element_id) - cwww_client_element_init_ctrl.element_id_start)
59#define CWWW_CLI_EL(_el_id) cwww_client_element_init_ctrl.el_list[_el_id]
60
62
63#if CWWW_CLI_MESHX_ONOFF_ENABLE_CB
64
65static meshx_err_t meshx_cwww_cli_send_onoff_msg( const dev_struct_t *pdev, uint16_t element_id, uint8_t set_get, uint8_t ack);
66static meshx_err_t meshx_cwww_cli_send_ctl_msg( const dev_struct_t *pdev, uint16_t element_id, uint8_t set_get, uint8_t is_temp_range, uint8_t ack);
79static meshx_err_t cwww_client_on_off_state_change_handler(
80 const meshx_on_off_cli_el_msg_t *param)
81{
82 uint16_t element_id = param->model.el_id;
83
84 size_t rel_el_id = GET_RELATIVE_EL_IDX(element_id);
85 meshx_cwww_client_model_ctx_t *el_ctx = CWWW_CLI_EL(rel_el_id).cwww_cli_ctx;
88 err = meshx_gen_on_off_state_change_handle(param, &el_ctx->prev_state, &el_ctx->state);
89 if(err == MESHX_SUCCESS)
90 {
91 app_notify.err_code = param->err_code;
92 app_notify.state_change.on_off.state = el_ctx->prev_state.on_off;
93
94 err = meshx_send_msg_to_app(element_id,
98 &app_notify);
99 if (err != MESHX_SUCCESS)
100 {
101 MESHX_LOGE(MOD_LCC, "Failed to send CWWW state change message: (%d)", err);
102 }
103 }
104 return err;
105}
106
118
119static meshx_err_t cwww_light_ctl_state_change_handler(
120 const meshx_ctl_cli_el_msg_t *param)
121{
122 uint16_t element_id = param->model.el_id;
123
124 size_t rel_el_id = GET_RELATIVE_EL_IDX(element_id);
125 meshx_cwww_client_model_ctx_t *el_ctx = CWWW_CLI_EL(rel_el_id).cwww_cli_ctx;
128
129 if(param->err_code == MESHX_SUCCESS)
130 {
131 CWWW_CLI_EL(rel_el_id).element_model_init |= MESHX_BIT(CWWW_CLI_SIG_L_CTL_MODEL_ID);
132
133 err = meshx_light_ctl_state_change_handle(param, &el_ctx->prev_ctl_state, &el_ctx->ctl_state);
134 if (err == MESHX_SUCCESS)
135 {
136 MESHX_LOGD(MOD_LCC, "PUBLISH: light|temp : %d|%d",
139
140 app_notify.err_code = param->err_code;
141 if(param->err_code == MESHX_SUCCESS)
142 {
143 app_notify.state_change.ctl.delta_uv = el_ctx->prev_ctl_state.delta_uv;
148 }
149
150 err = meshx_send_msg_to_app(element_id,
154 &app_notify);
155 if (err != MESHX_SUCCESS)
156 {
157 MESHX_LOGE(MOD_LCC, "Failed to send CWWW state change message: (%d)", err);
158 }
159 }
160 }
161 return err;
162}
174
175static meshx_err_t meshx_cwww_client_element_state_change_handler(
176 const dev_struct_t *pdev,
178 const meshx_ptr_t params
179)
180{
181 if (!pdev || !params)
182 {
183 return MESHX_INVALID_ARG;
184 }
186 uint16_t element_id = ((const meshx_on_off_cli_el_msg_t *)params)->model.el_id;
187 if (!IS_EL_IN_RANGE(element_id))
188 {
189 return MESHX_SUCCESS;
190 }
191 switch (evt)
192 {
194 err = cwww_client_on_off_state_change_handler(
195 (meshx_on_off_cli_el_msg_t *)params);
196 break;
198 err = cwww_light_ctl_state_change_handler(
199 (meshx_ctl_cli_el_msg_t *)params);
200 break;
201 default:
202 err = MESHX_FAIL;
203 }
204 if(err == MESHX_SUCCESS)
205 {
207 if (err != MESHX_SUCCESS)
208 {
209 MESHX_LOGE(MOD_LCC, "Failed to set cwww client element context: (%d)", err);
210 }
211 }
212 return err;
213}
214
215#if CONFIG_ENABLE_CONFIG_SERVER
226static meshx_err_t cwww_client_config_srv_cb (
227 const dev_struct_t *pdev,
229 const meshx_config_srv_cb_param_t *params)
230{
231 MESHX_UNUSED(pdev);
232 meshx_cwww_client_model_ctx_t *el_ctx = NULL;
233 size_t rel_el_id = 0;
234 uint16_t element_id = 0;
235 uint16_t base_el_id = 0;
236 bool nvs_save = false;
237 meshx_get_base_element_id(&base_el_id);
238
239 switch (evt)
240 {
242 element_id = params->state_change.mod_app_bind.element_addr - base_el_id;
243 if (!IS_EL_IN_RANGE(element_id))
244 break;
245 rel_el_id = GET_RELATIVE_EL_IDX(element_id);
246 el_ctx = CWWW_CLI_EL(rel_el_id).cwww_cli_ctx;
247 el_ctx->app_id = params->state_change.appkey_add.app_idx;
248 nvs_save = true;
249 break;
252 element_id = params->state_change.mod_pub_set.element_addr - base_el_id;
253 if (!IS_EL_IN_RANGE(element_id))
254 break;
255 rel_el_id = GET_RELATIVE_EL_IDX(element_id);
256 el_ctx = CWWW_CLI_EL(rel_el_id).cwww_cli_ctx;
259 el_ctx->app_id = params->state_change.mod_pub_set.app_idx;
260 nvs_save = true;
261 MESHX_LOGI(MOD_LCC, "PUB_ADD: %d, %d, 0x%X, 0x%X", element_id, rel_el_id, el_ctx->pub_addr, el_ctx->app_id);
262 break;
263 default:
264 break;
265 }
266 if (nvs_save)
267 {
269 if (err != MESHX_SUCCESS)
270 {
271 MESHX_LOGE(MOD_LCC, "Failed to set cwww client element context: (%d)", err);
272 }
273 }
274 return MESHX_SUCCESS;
275}
276#endif /* CONFIG_ENABLE_CONFIG_SERVER */
277
278#if defined(__MESHX_CONTROL_TASK__)
279
290static meshx_err_t cwww_cli_prov_srv_msg_handle(const dev_struct_t *pdev, control_task_msg_evt_t evt, const void *params)
291{
292 if(!pdev)
293 return MESHX_INVALID_ARG;
294
295 MESHX_UNUSED(params);
297
299 {
300 for(uint16_t i = cwww_client_element_init_ctrl.element_id_start; i < cwww_client_element_init_ctrl.element_id_end; i++)
301 {
303 }
304 }
305 else
306 {
307 MESHX_LOGW(MOD_LCC, "Unhandled event: %d", evt);
308 }
309 return err;
310}
311
327static meshx_err_t meshx_cwww_cli_send_onoff_msg(
328 const dev_struct_t *pdev,
329 uint16_t element_id,
330 uint8_t set_get,
331 uint8_t ack)
332{
333 if (!pdev || !IS_EL_IN_RANGE(element_id))
334 return MESHX_INVALID_ARG;
335
337 size_t rel_el_id = GET_RELATIVE_EL_IDX(element_id);
338 meshx_onoff_client_model_t *model = CWWW_CLI_EL(rel_el_id).onoff_cli_model;
339
340 meshx_cwww_client_model_ctx_t *el_ctx = CWWW_CLI_EL(rel_el_id).cwww_cli_ctx;
341 uint16_t opcode = MESHX_MODEL_OP_GEN_ONOFF_GET;
342
343 if (MESHX_GEN_ON_OFF_CLI_MSG_SET == set_get)
344 {
346 }
347
348 MESHX_LOGD(MOD_LCC, "OPCODE: %p", (void *)(uint32_t)opcode);
349
350 meshx_gen_onoff_send_params_t params = {
351 .element_id = element_id,
352 .model = model,
353 .opcode = opcode,
354 .addr = el_ctx->pub_addr,
355 .net_idx = pdev->meshx_store.net_key_id,
356 .app_idx = el_ctx->app_id,
357 .state = el_ctx->state.on_off,
358 .tid = el_ctx->tid
359 };
360 /* Send message to the relay client */
361 err = meshx_onoff_client_send_msg(&params);
362 if (err)
363 {
364 MESHX_LOGE(MOD_LCC, "Cwww Client Send Message failed: (%d)", err);
365 }
366 else
367 {
368 el_ctx->tid++;
370 {
371 el_ctx->prev_state.on_off = el_ctx->state.on_off;
372 el_ctx->state.on_off = !el_ctx->state.on_off;
373 }
374 }
375 return err;
376}
377
392static meshx_err_t meshx_cwww_cli_send_ctl_msg(
393 const dev_struct_t *pdev,
394 uint16_t element_id,
395 uint8_t set_get,
396 uint8_t is_temp_range,
397 uint8_t ack)
398{
399 if (!pdev || !IS_EL_IN_RANGE(element_id))
400 return MESHX_INVALID_ARG;
401
403 size_t rel_el_id = GET_RELATIVE_EL_IDX(element_id);
404 meshx_cwww_client_model_ctx_t *el_ctx = CWWW_CLI_EL(rel_el_id).cwww_cli_ctx;
405 meshx_light_ctl_client_model_t *model = CWWW_CLI_EL(rel_el_id).ctl_cli_model;
406
408 .model = model,
410 .element_id = element_id,
411 .tid = el_ctx->tid,
412 .app_idx = el_ctx->app_id,
413 .addr = el_ctx->pub_addr,
414 .net_idx = pdev->meshx_store.net_key_id,
415 };
416
417 if(is_temp_range == false)
418 {
419 if( MESHX_LIGHT_CTL_CLI_MSG_SET == set_get)
420 {
422 }
423
424 MESHX_LOGD(MOD_LCC, "OPCODE: %p", (void *)(uint32_t)params.opcode);
425
426 params.delta_uv = el_ctx->ctl_state.delta_uv;
427 params.lightness = el_ctx->ctl_state.lightness;
428 params.temperature = el_ctx->ctl_state.temperature;
429
430 /* Send message to the cwww client */
431 err = meshx_light_ctl_client_send_msg(&params);
432 if (err)
433 {
434 MESHX_LOGE(MOD_LCC, "Cwww Client Send Message failed: (%d)", err);
435 }
436 else
437 {
438 el_ctx->tid++;
440 {
441 el_ctx->prev_ctl_state.delta_uv = el_ctx->ctl_state.delta_uv;
444 }
445 }
446 }
447 else
448 {
450 /* If set operation, change opcode accordingly */
451 if( MESHX_LIGHT_CTL_CLI_MSG_SET == set_get)
452 {
454 }
455
456 MESHX_LOGD(MOD_LCC, "OPCODE: %p", (void *)(uint32_t)params.opcode);
457
458 params.temp_range_max = el_ctx->ctl_state.temp_range_max;
459 params.temp_range_min = el_ctx->ctl_state.temp_range_min;
460
461 /* Send message to the cwww client */
463 if (err)
464 {
465 MESHX_LOGE(MOD_LCC, "Cwww Client Send Message failed: (%d)", err);
466 }
467 else
468 {
470 {
473 }
474 }
475 }
476 return err;
477}
478
489static meshx_err_t meshx_cwww_client_element_to_ble_handler(
490 const dev_struct_t *pdev,
492 const void *params)
493{
494 if (!pdev || !params)
495 return MESHX_INVALID_ARG;
496 MESHX_UNUSED(pdev);
497 bool is_temp_range = false;
499 const meshx_cwww_client_msg_t *msg = (const meshx_cwww_client_msg_t *)params;
500 MESHX_LOGD(MOD_LCC, "EVT: %p, el_id: %d, set_get: %d, ack: %d",
501 (void *)evt, msg->element_id, msg->set_get, msg->ack);
502
503 if (!IS_EL_IN_RANGE(msg->element_id))
504 {
505 return MESHX_INVALID_ARG;
506 }
507 if (CWWW_CLI_EL(GET_RELATIVE_EL_IDX(msg->element_id)).cwww_cli_ctx->pub_addr == MESHX_ADDR_UNASSIGNED)
508 {
509 MESHX_LOGW(MOD_LCC, "No publish address set for element: %d", msg->element_id);
510 return MESHX_INVALID_STATE;
511 }
513 {
514 err = meshx_cwww_cli_send_onoff_msg(
515 pdev,
516 msg->element_id,
517 msg->set_get,
518 msg->ack
519 );
520 if (err != MESHX_SUCCESS)
521 {
522 MESHX_LOGE(MOD_LCC, "CWWW Client Control Task: Set OnOff failed (%p)", (void *)err);
523 return err;
524 }
525 }
527 {
528 size_t rel_el_id = msg->element_id - cwww_client_element_init_ctrl.element_id_start;
529 meshx_cwww_client_model_ctx_t *el_ctx = CWWW_CLI_EL(rel_el_id).cwww_cli_ctx;
530 /* Set new context value as per msg sent */
531 el_ctx->ctl_state.delta_uv = (msg->arg_bmap & CWWW_ARG_BMAP_DELTA_UV_SET) ? msg->delta_uv : el_ctx->ctl_state.delta_uv;
532 el_ctx->ctl_state.lightness = (msg->arg_bmap & CWWW_ARG_BMAP_LIGHTNESS_SET) ? msg->lightness : el_ctx->ctl_state.lightness;
533 el_ctx->ctl_state.temperature = (msg->arg_bmap & CWWW_ARG_BMAP_TEMPERATURE_SET) ? msg->temperature : el_ctx->ctl_state.temperature;
534 el_ctx->ctl_state.temp_range_max = (msg->arg_bmap & CWWW_ARG_BMAP_TEMPERATURE_RANGE_SET_MAX) ? msg->temp_range_max : el_ctx->ctl_state.temp_range_max;
535 el_ctx->ctl_state.temp_range_min = (msg->arg_bmap & CWWW_ARG_BMAP_TEMPERATURE_RANGE_SET_MIN) ? msg->temp_range_min : el_ctx->ctl_state.temp_range_min;
537 err = meshx_cwww_cli_send_ctl_msg(
538 pdev,
539 msg->element_id,
540 msg->set_get,
541 is_temp_range,
542 msg->ack
543 );
544 if (err != MESHX_SUCCESS)
545 {
546 MESHX_LOGE(MOD_LCC, "CWWW Client Control Task: Set CTL failed (%p)", (void *)err);
547 return err;
548 }
549 }
550 return err;
551}
552#endif /* __MESHX_CONTROL_TASK__ */
553
554#if CONFIG_ENABLE_UNIT_TEST
555
559typedef enum cwww_cli_cmd
560{
561 /* ONOFF UT COMMANDS */
562 CWWW_CLI_UT_CMD_ONOFF_GET = 0,
563 CWWW_CLI_UT_CMD_ONOFF_SET,
564 CWWW_CLI_UT_CMD_ONOFF_SET_UNACK,
565 /* CTL UT COMMANDS */
566 CWWW_CLI_UT_CMD_CTL_GET,
567 CWWW_CLI_UT_CMD_CTL_SET,
568 CWWW_CLI_UT_CMD_CTL_SET_UNACK,
569 CWWW_CLI_UT_CMD_LIGHTNESS_SET,
570 CWWW_CLI_UT_CMD_LIGHTNESS_SET_UNACK,
571 CWWW_CLI_UT_CMD_TEMPERATURE_SET,
572 CWWW_CLI_UT_CMD_TEMPERATURE_SET_UNACK,
573 CWWW_CLI_UT_CMD_DELTA_UV_SET,
574 CWWW_CLI_UT_CMD_DELTA_UV_SET_UNACK,
575 CWWW_CLI_UT_CMD_TEMPERATURE_RANGE_SET,
576 CWWW_CLI_UT_CMD_TEMPERATURE_RANGE_SET_UNACK,
577 CWWW_CLI_MAX_CMD
578} cwww_cli_cmd_t;
579
595static meshx_err_t cwww_cli_unit_test_cb_handler(int cmd_id, int argc, char **argv)
596{
598 meshx_cwww_client_msg_t msg = {0};
599 msg.element_id = UT_GET_ARG(0, uint16_t, argv);
600 cwww_cli_cmd_t cmd = (cwww_cli_cmd_t)cmd_id;
601
602 MESHX_LOGD(MOD_LCC, "argc|cmd_id: %d|%d", argc, cmd_id);
603 if (argc < 1 || cmd_id >= CWWW_CLI_MAX_CMD)
604 {
605 MESHX_LOGE(MOD_LCC, "CWW Client Unit Test: Invalid number of arguments");
606 return MESHX_INVALID_ARG;
607 }
608
609 control_task_msg_evt_to_ble_t msg_evt = CONTROL_TASK_MSG_EVT_TO_BLE_MAX;
610 switch (cmd)
611 {
612 case CWWW_CLI_UT_CMD_ONOFF_GET:
613 /* ut 1 0 1 <el_id> */
614 msg.ack = CWWW_CLI_MSG_ACK;
617 break;
618 case CWWW_CLI_UT_CMD_ONOFF_SET:
619 /* ut 1 1 1 <el_id> */
620 case CWWW_CLI_UT_CMD_ONOFF_SET_UNACK:
621 /* ut 1 2 1 <el_id> */
625 msg.ack = cmd == CWWW_CLI_UT_CMD_ONOFF_SET ? CWWW_CLI_MSG_ACK : CWWW_CLI_MSG_NO_ACK;
626 break;
627 case CWWW_CLI_UT_CMD_CTL_GET:
628 /* ut 1 3 1 <el_id> */
632 break;
633 case CWWW_CLI_UT_CMD_CTL_SET:
634 /* ut 1 4 4 <el_id> <temp> <light> <delta_uv> */
635 case CWWW_CLI_UT_CMD_CTL_SET_UNACK:
636 /* ut 1 5 4 <el_id> <temp> <light> <delta_uv> */
637 if (argc >= 2)
638 msg.temperature = UT_GET_ARG(1, uint16_t, argv);
639 if (argc >= 3)
640 msg.lightness = UT_GET_ARG(2, uint16_t, argv);
641 if (argc >= 4)
642 msg.delta_uv = UT_GET_ARG(3, uint16_t, argv);
646 msg.ack = cmd == CWWW_CLI_UT_CMD_CTL_SET ? CWWW_CLI_MSG_ACK : CWWW_CLI_MSG_NO_ACK;
647 break;
648 case CWWW_CLI_UT_CMD_LIGHTNESS_SET:
649 /* ut 1 6 2 <el_id> <light> */
650 case CWWW_CLI_UT_CMD_LIGHTNESS_SET_UNACK:
651 /* ut 1 7 2 <el_id> <light> */
652 if (argc >= 2)
653 msg.lightness = UT_GET_ARG(1, uint16_t, argv);
657 msg.ack = cmd == CWWW_CLI_UT_CMD_LIGHTNESS_SET ? CWWW_CLI_MSG_ACK : CWWW_CLI_MSG_NO_ACK;
658 break;
659 case CWWW_CLI_UT_CMD_TEMPERATURE_SET:
660 /* ut 1 8 2 <el_id> <temp> */
661 case CWWW_CLI_UT_CMD_TEMPERATURE_SET_UNACK:
662 /* ut 1 9 2 <el_id> <temp> */
663 if (argc >= 2)
664 msg.temperature = UT_GET_ARG(1, uint16_t, argv);
668 msg.ack = cmd == CWWW_CLI_UT_CMD_TEMPERATURE_SET ? CWWW_CLI_MSG_ACK : CWWW_CLI_MSG_NO_ACK;
669 break;
670 case CWWW_CLI_UT_CMD_DELTA_UV_SET:
671 /* ut 1 10 2 <el_id> <delta_uv> */
672 case CWWW_CLI_UT_CMD_DELTA_UV_SET_UNACK:
673 /* ut 1 11 2 <el_id> <delta_uv> */
674 if (argc >= 2)
675 msg.delta_uv = UT_GET_ARG(1, uint16_t, argv);
679 msg.ack = cmd == CWWW_CLI_UT_CMD_DELTA_UV_SET ? CWWW_CLI_MSG_ACK : CWWW_CLI_MSG_NO_ACK;
680 break;
681 case CWWW_CLI_UT_CMD_TEMPERATURE_RANGE_SET:
682 /* ut 1 12 3 <el_id> <min> <max> */
683 case CWWW_CLI_UT_CMD_TEMPERATURE_RANGE_SET_UNACK:
684 /* ut 1 13 3 <el_id> <min> <max> */
685 if (argc >= 2)
686 msg.temp_range_min = UT_GET_ARG(1, uint16_t, argv);
687 if (argc >= 3)
688 msg.temp_range_max = UT_GET_ARG(2, uint16_t, argv);
692 msg.ack = cmd == CWWW_CLI_UT_CMD_TEMPERATURE_RANGE_SET ? CWWW_CLI_MSG_ACK : CWWW_CLI_MSG_NO_ACK;
693 break;
694 default:
695 MESHX_LOGE(MOD_LCC, "CWWW Client Unit Test: Invalid command");
696 return MESHX_INVALID_ARG;
697 }
698
699 err = control_task_msg_publish(CONTROL_TASK_MSG_CODE_TO_BLE, msg_evt, &msg, sizeof(msg));
700 if (err)
701 {
702 MESHX_LOGE(MOD_LCC, "CWWW Client Unit Test: Command %d failed", cmd);
703 }
704 return err;
705}
706
707#endif /* CONFIG_ENABLE_UNIT_TEST */
708
709#endif /* CWWW_CLI_MESHX_ONOFF_ENABLE_CB */
710
725{
726 if(!n_max)
727 return MESHX_INVALID_ARG;
728
730
731 cwww_client_element_init_ctrl.element_cnt = n_max;
732 cwww_client_element_init_ctrl.element_id_end = 0;
733 cwww_client_element_init_ctrl.element_id_start = 0;
734
738 {
739 MESHX_LOGE(MOD_LCC, "Failed to allocate memory for cwww client elements");
740 return MESHX_NO_MEM;
741 }
742
743 for (size_t i = 0; i < cwww_client_element_init_ctrl.element_cnt; i++)
744 {
747 {
748 MESHX_LOGE(MOD_LCC, "Failed to allocate memory for cwww client context");
749 return MESHX_NO_MEM;
750 }
751 err = meshx_on_off_client_create(&CWWW_CLI_EL(i).onoff_cli_model,
752 &CWWW_CLI_EL(i).cwww_cli_sig_model_list[CWWW_CLI_SIG_ONOFF_MODEL_ID]);
753 if (err)
754 {
755 MESHX_LOGE(MOD_LCC, "Meshx On Off Client create failed (Err : 0x%x)", err);
756 return err;
757 }
758 CWWW_CLI_EL(i).onoff_cli_model->meshx_sig
759 = &CWWW_CLI_EL(i).cwww_cli_sig_model_list[CWWW_CLI_SIG_ONOFF_MODEL_ID];
760
761 err = meshx_light_ctl_client_create(&CWWW_CLI_EL(i).ctl_cli_model,
762 &CWWW_CLI_EL(i).cwww_cli_sig_model_list[CWWW_CLI_SIG_L_CTL_MODEL_ID]);
763 if (err)
764 {
765 MESHX_LOGE(MOD_LCC, "Meshx CTL Client create failed (Err : 0x%x)", err);
766 return err;
767 }
768 CWWW_CLI_EL(i).ctl_cli_model->meshx_sig
769 = &CWWW_CLI_EL(i).cwww_cli_sig_model_list[CWWW_CLI_SIG_L_CTL_MODEL_ID];
770 }
771 return MESHX_SUCCESS;
772}
773
783{
785 {
786 MESHX_LOGE(MOD_LCC, "CWWW element list not initialized");
787 return MESHX_INVALID_STATE;
788 }
789
791 {
792 for (size_t i = 0; i < n_max; i++)
793 {
795 {
797 CWWW_CLI_EL(i).cwww_cli_ctx = NULL;
798 }
799 }
801 cwww_client_element_init_ctrl.el_list = NULL;
802 }
803 cwww_client_element_init_ctrl.element_cnt = 0;
804 cwww_client_element_init_ctrl.element_id_end = 0;
805 cwww_client_element_init_ctrl.element_id_start = 0;
806
807 return MESHX_SUCCESS;
808}
809
826{
827 if (!pdev)
828 return MESHX_INVALID_STATE;
829
831 if (err)
832 {
833 MESHX_LOGE(MOD_LCC, "Failed to initialize cwww element structures: (%d)", err);
835 return err;
836 }
837 return MESHX_SUCCESS;
838}
839
854static meshx_err_t meshx_add_cwww_cli_model_to_element_list(dev_struct_t *pdev, uint16_t *start_idx, uint16_t n_max)
855{
856 if (!pdev || !start_idx || !n_max)
857 return MESHX_INVALID_ARG;
858
859 if ((n_max + *start_idx) > CONFIG_MAX_ELEMENT_COUNT)
860 {
861 MESHX_LOGE(MOD_LCC, "No of elements limit reached");
862 return MESHX_NO_MEM;
863 }
865
866 cwww_client_element_init_ctrl.element_id_start = *start_idx;
867
868 for (uint16_t i = *start_idx; i < (n_max + *start_idx) && (i - *start_idx) < CWWW_CLI_MODEL_SIG_CNT; i++)
869 {
870 if (i == 0)
871 continue;
873 i,
874 pdev->elements,
875 CWWW_CLI_EL(i - *start_idx).cwww_cli_sig_model_list,
876 NULL,
879 if (err)
880 {
881 MESHX_LOGE(MOD_LCC, "Failed to add element to composition: (%d)", err);
882 return err;
883 }
885 CWWW_CLI_EL(i - *start_idx).cwww_cli_ctx,
887 if (err != MESHX_SUCCESS)
888 {
889 MESHX_LOGW(MOD_LCC, "Failed to get cwww cli element context: (0x%x)", err);
890 }
891 }
892 /* Increment the index for further registrations */
893 cwww_client_element_init_ctrl.element_id_end = *start_idx += n_max;
894 return MESHX_SUCCESS;
895}
896
912
921
932{
933 if (!IS_EL_IN_RANGE(element_id))
934 {
935 MESHX_LOGE(MOD_LCC, "Invalid element id: %d", element_id);
936 return MESHX_INVALID_ARG;
937 }
938 meshx_cwww_client_msg_t msg = {0};
939 msg.ack = CWWW_CLI_MSG_ACK;
941 msg.element_id = element_id;
942
943 if (model_id != CWWW_CLI_SIG_ID_MAX)
944 {
945 MESHX_LOGD(MOD_LCC, "Sending GET for model: %d", model_id);
946 if(model_id == CWWW_CLI_SIG_L_CTL_MODEL_ID)
947 {
951 &msg,
952 sizeof(msg));
953 }
954 else
955 {
959 &msg,
960 sizeof(msg));
961 }
962 }
963 else
964 {
965 for(model_id = CWWW_CLI_SIG_ONOFF_MODEL_ID; model_id < CWWW_CLI_SIG_ID_MAX; model_id++)
966 {
967
968 MESHX_LOGD(MOD_LCC, "Sending GET for model: %d", model_id);
969 if(model_id == CWWW_CLI_SIG_L_CTL_MODEL_ID)
970 {
974 &msg,
975 sizeof(msg));
976 }
977 else
978 {
982 &msg,
983 sizeof(msg));
984 }
985 }
986 }
987 return MESHX_SUCCESS;
988}
989
999{
1000 meshx_err_t err;
1001
1002 err = meshx_dev_create_cwww_model_space(pdev, element_cnt);
1003 if (err)
1004 {
1005 MESHX_LOGE(MOD_LCC, "CWWW Model space create failed: (%d)", err);
1006 return err;
1007 }
1008
1009 err = meshx_add_cwww_cli_model_to_element_list(pdev, (uint16_t *)&pdev->element_idx, element_cnt);
1010 if (err)
1011 {
1012 MESHX_LOGE(MOD_LCC, "CWWW Model add to element create failed: (%d)", err);
1013 return err;
1014 }
1015
1016 err = meshx_on_off_client_init();
1017 if (err)
1018 {
1019 MESHX_LOGE(MOD_LCC, "meshx_onoff_client_init failed: (%d)", err);
1020 return err;
1021 }
1022
1024 if (err)
1025 {
1026 MESHX_LOGE(MOD_LCC, "meshx_light_ctl_client_init failed: (%d)", err);
1027 return err;
1028 }
1029
1030#if CONFIG_ENABLE_CONFIG_SERVER
1032 (config_srv_cb_t) &cwww_client_config_srv_cb,
1034 if (err)
1035 {
1036 MESHX_LOGE(MOD_LCC, "Light CWWW config server callback reg failed: (%d)", err);
1037 return err;
1038 }
1039#endif /* CONFIG_ENABLE_CONFIG_SERVER */
1040
1041#if defined(__MESHX_CONTROL_TASK__)
1042 /* Register control task callback */
1044 if (err)
1045 {
1046 MESHX_LOGE(MOD_LCC, "control task callback reg failed: (%d)", err);
1047 return err;
1048 }
1049 /* Register element state change callback */
1051 if (err)
1052 {
1053 MESHX_LOGE(MOD_LCC, "element state change callback reg failed: (%d)", err);
1054 return err;
1055 }
1056 /* Register freshboot control task callback */
1058 (prov_srv_cb_t)&cwww_cli_prov_srv_msg_handle);
1059 if (err)
1060 {
1061 MESHX_LOGE(MOD_LCC, "control task callback reg failed: (%d)", err);
1062 return err;
1063 }
1064
1065#endif /* __MESHX_CONTROL_TASK__ */
1066#if CONFIG_ENABLE_UNIT_TEST
1067 err = register_unit_test(MODULE_ID_ELEMENT_LIGHT_CWWWW_CLIENT, &cwww_cli_unit_test_cb_handler);
1068 if (err)
1069 {
1070 MESHX_LOGE(MOD_LCC, "unit_test reg failed: (%d)", err);
1071 return err;
1072 }
1073#endif /* CONFIG_ENABLE_UNIT_TEST */
1074
1075 return MESHX_SUCCESS;
1076}
1077
1079
1080#endif /* CONFIG_LIGHT_CWWW_CLIENT_COUNT */
This file contains the API definitions for the MeshX application.
meshx_err_t meshx_send_msg_to_app(uint16_t element_id, uint16_t element_type, uint16_t func_id, uint16_t msg_len, const void *msg)
Sends a message to the BLE Mesh application.
Definition meshx_api.c:96
@ MESHX_ELEMENT_TYPE_LIGHT_CWWW_CLIENT
Definition meshx_api.h:47
#define MESHX_ELEMENT_FUNC_ID_LIGHT_CWWW_CLIENT_ONN_OFF
Definition meshx_api.h:28
struct meshx_api_light_cwww_client_evt meshx_api_light_cwww_client_evt_t
Structure defines the payload for MESHX_ELEMENT_TYPE_LIGHT_CWWW_CLIENT.
#define MESHX_ELEMENT_FUNC_ID_LIGHT_CWWW_CLIENT_CTL
Definition meshx_api.h:29
meshx_err_t meshx_plat_add_element_to_composition(uint16_t index, meshx_ptr_t p_element_list, meshx_ptr_t p_sig_models, meshx_ptr_t p_ven_models, uint8_t sig_cnt, uint8_t ven_cnt)
Adds an element to the BLE Mesh composition.
meshx_err_t meshx_get_base_element_id(uint16_t *base_el_id)
Retrieves the base element ID for the BLE Mesh platform.
#define MESHX_MODEL_OP_LIGHT_CTL_SET
void * meshx_ptr_t
#define MESHX_MODEL_OP_GEN_ONOFF_SET_UNACK
#define MESHX_ADDR_UNASSIGNED
#define MESHX_MODEL_OP_GEN_ONOFF_GET
#define MESHX_MODEL_OP_LIGHT_CTL_TEMPERATURE_RANGE_SET_UNACK
#define MESHX_MODEL_OP_GEN_ONOFF_SET
#define MESHX_BIT(nr)
#define MESHX_MODEL_OP_LIGHT_CTL_SET_UNACK
#define MESHX_MODEL_OP_LIGHT_CTL_TEMPERATURE_RANGE_GET
#define MESHX_MODEL_OP_LIGHT_CTL_GET
#define MESHX_MODEL_OP_LIGHT_CTL_TEMPERATURE_RANGE_SET
struct meshx_config_srv_cb_param meshx_config_srv_cb_param_t
control_task_msg_handle_t config_srv_cb_t
control_task_msg_handle_t prov_srv_cb_t
Common application definitions and includes for BLE Mesh Node.
#define REG_MESHX_ELEMENT_FN(_name, _type, _fn)
Register an element composition function.
struct dev_struct dev_struct_t
Structure representing the device composition and elements.
#define CONFIG_MAX_ELEMENT_COUNT
Total Element Count in the Composition.
Header file for the meshxuction configuration server model.
meshx_err_t meshx_config_server_cb_reg(config_srv_cb_t cb, uint32_t config_evt_bmap)
Registers a configuration server callback for specific events.
Header file for the control task in the BLE mesh node application.
CONTROL_TASK_MSG_EVT_SYSTEM_FRESH_BOOT
enum __packed control_task_msg_evt_to_ble control_task_msg_evt_to_ble_t
Enumeration for control task message events to BLE.
CONTROL_TASK_MSG_EVT_TO_BLE_SET_CTL
uint32_t control_task_msg_evt_t
Type definition for control task message event.
meshx_err_t(* control_task_msg_handle_t)(dev_struct_t *pdev, control_task_msg_evt_t evt, void *params)
Function pointer type for control task message handler.
CONTROL_TASK_MSG_EVT_EL_STATE_CH_SET_ON_OFF
@ CONTROL_TASK_MSG_CODE_EL_STATE_CH
@ CONTROL_TASK_MSG_CODE_TO_BLE
CONTROL_TASK_MSG_EVT_EL_STATE_CH_SET_CTL
CONTROL_TASK_MSG_EVT_PUB_ADD
CONTROL_TASK_MSG_EVT_APP_KEY_BIND
CONTROL_TASK_MSG_EVT_TO_BLE_SET_ON_OFF
meshx_err_t control_task_msg_publish(control_task_msg_code_t msg_code, control_task_msg_evt_t msg_evt, const void *msg_evt_params, size_t sizeof_msg_evt_params)
Publish a control task message.
CONTROL_TASK_MSG_EVT_PUB_DEL
meshx_err_t control_task_msg_subscribe(control_task_msg_code_t msg_code, control_task_msg_evt_t evt_bmap, control_task_msg_handle_t callback)
Subscribe to a control task message.
#define MESHX_CALOC
Definition meshx_err.h:28
#define MESHX_UNUSED(x)
Definition meshx_err.h:15
meshx_err_t
MeshX Error Codes.
Definition meshx_err.h:39
@ MESHX_SUCCESS
Definition meshx_err.h:40
@ MESHX_INVALID_ARG
Definition meshx_err.h:42
@ MESHX_FAIL
Definition meshx_err.h:41
@ MESHX_INVALID_STATE
Definition meshx_err.h:45
@ MESHX_NO_MEM
Definition meshx_err.h:44
#define MESHX_FREE
Definition meshx_err.h:32
struct meshx_ctl_cli_el_msg meshx_ctl_cli_el_msg_t
Structure to hold the On/Off Server to element message.
meshx_err_t meshx_light_ctl_state_change_handle(const meshx_ctl_cli_el_msg_t *param, meshx_ctl_el_state_t *p_ctl_prev_state, const meshx_ctl_el_state_t *p_ctl_next_state)
Handles state changes for the Light CTL client element.
meshx_err_t meshx_light_ctl_client_create(meshx_light_ctl_client_model_t **p_model, void *p_sig_model)
Creates and initializes a Generic Light Client model instance.
meshx_err_t meshx_light_ctl_client_init()
Initialize the Light CTL Client model.
#define MESHX_LIGHT_CTL_CLI_MSG_SET
meshx_err_t meshx_light_ctl_temp_range_client_send_msg(meshx_gen_ctl_send_params_t *params)
Sends a Light CTL Temperature Range message from the client model.
struct meshx_gen_ctl_send_params meshx_gen_ctl_send_params_t
Structure to hold the parameters for sending a Generic Ctl message.
meshx_err_t meshx_light_ctl_client_send_msg(meshx_gen_ctl_send_params_t *params)
Sends a Light CTL (Color Temperature Lightness) message from the Light CTL Client model.
meshx_model_interface_t meshx_light_ctl_client_model_t
Structure representing the Light CTL (Color Temperature Lightness) client model in MeshX.
#define CWWW_CLI_EL_STATE_CH_EVT_MASK
#define CONFIG_SERVER_CB_MASK
Configuration server callback event mask for cwww server.
static meshx_err_t meshx_cwww_cli_el_state_change_reg_cb()
meshx_err_t create_cwww_client_elements(dev_struct_t *pdev, uint16_t element_cnt)
Create Dynamic CW-WW Model Elements.
#define CWWW_CLI_EL(_el_id)
#define GET_RELATIVE_EL_IDX(_element_id)
static meshx_err_t meshx_cwww_cli_reg_app_req_cb()
Registers a callback handler for CW-WW application requests.
#define MOD_LCC
meshx_err_t meshx_cwww_el_get_state(uint16_t element_id, cwww_cli_sig_id_t model_id)
Retrieves the current state of the CW/WW (Cool White/Warm White) light element for the specified elem...
static meshx_err_t meshx_element_struct_init(uint16_t n_max)
Initializes the CW-WW client model.
#define IS_EL_IN_RANGE(_element_id)
static meshx_err_t meshx_dev_create_cwww_model_space(dev_struct_t const *pdev, uint16_t n_max)
Creates a CW-WW model space for the given device.
static meshx_err_t meshx_add_cwww_cli_model_to_element_list(dev_struct_t *pdev, uint16_t *start_idx, uint16_t n_max)
This function adds the CW-WW client models to the element list of the specified device....
static meshx_cwww_client_elements_ctrl_t cwww_client_element_init_ctrl
Implementation of the CW-WW (Cool White - Warm White) client model for BLE Mesh.
#define CWWW_CLI_MSG_ACK
Acknowledgment message type.
struct cwww_client_msg meshx_cwww_client_msg_t
Structure to hold the cwww client message sent from APP layer.
#define CWWW_ARG_BMAP_LIGHTNESS_SET
struct cwww_client_element_ctrl meshx_cwww_client_elements_ctrl_t
Structure to hold the cwww client elements.
#define CWWW_CLI_MSG_GET
Message type for getting CW-WW client state.
meshx_err_t create_cwww_client_elements(dev_struct_t *pdev, uint16_t element_cnt)
Create Dynamic CW-WW Model Elements.
#define CWWW_ARG_BMAP_DELTA_UV_SET
struct cwww_client_element meshx_cwww_client_elements_t
Structure to hold the cwww client element.
#define CWWW_CLI_MSG_SET
Message type for setting CW-WW client state.
#define CWWW_CLI_MODEL_VEN_CNT
Number of Vendor models in a CW-WW model element.
#define CWWW_ARG_BMAP_TEMPERATURE_SET
#define CWWW_ARG_BMAP_TEMPERATURE_RANGE_SET_MIN
#define CWWW_CLI_MSG_NO_ACK
Non-acknowledgment message type.
cwww_cli_sig_id_t
Enumeration of CW-WW SIG model IDs.
#define CWWW_CLI_MODEL_SIG_CNT
Number of SIG models in a CW-WW model element.
#define CWWW_ARG_BMAP_CTL_SET
Argument bitmap for setting the CW-WW client control state.
#define CWWW_ARG_BMAP_ONOFF_SET
#define CWWW_ARG_BMAP_TEMPERATURE_RANGE_SET_MAX
struct cwww_cli_ctx meshx_cwww_client_model_ctx_t
Structure to hold the context of the cwww client.
#define CWWW_ARG_BMAP_TEMPERATURE_RANGE_SET
Argument bitmap for setting the temperature range.
#define MESHX_LOGW(module_id, format,...)
Definition meshx_log.h:87
#define MESHX_LOGI(module_id, format,...)
Definition meshx_log.h:100
#define MESHX_LOGE(module_id, format,...)
Definition meshx_log.h:73
#define MESHX_LOGD(module_id, format,...)
Definition meshx_log.h:113
Header file for MeshX Non-Volatile Storage (NVS) operations.
meshx_err_t meshx_nvs_element_ctx_set(uint16_t element_id, const void *blob, size_t blob_size)
Store the context of a specific element to NVS.
Definition meshx_nvs.c:444
meshx_err_t meshx_nvs_element_ctx_get(uint16_t element_id, void *blob, size_t blob_size)
Retrieve the context of a specific element from NVS.
Definition meshx_nvs.c:424
meshx_err_t meshx_prov_srv_reg_el_client_cb(prov_srv_cb_t cb)
Register a callback function for provisioning events.
#define CONTROL_TASK_MSG_CODE_EVT_MASK
static meshx_err_t meshx_element_struct_deinit(void)
Deinitializes the mesh element structure.
@ MODULE_ID_ELEMENT_LIGHT_CWWWW_CLIENT
Definition module_id.h:25
Structure to hold the context of the cwww client.
meshx_on_off_cli_state_t state
meshx_ctl_el_state_t prev_ctl_state
meshx_ctl_el_state_t ctl_state
meshx_on_off_cli_state_t prev_state
meshx_app_store_t meshx_store
size_t element_idx
MESHX_ELEMENT elements[MAX_ELE_CNT]
struct meshx_api_light_cwww_client_evt::@347235105244230326232000270243372246073133053316::@202375373323027037070222212050326072162342057303 on_off
struct meshx_api_light_cwww_client_evt::@347235105244230326232000270243372246073133053316::@153162234125000074275266213156212277206313354032 ctl
union meshx_api_light_cwww_client_evt::@347235105244230326232000270243372246073133053316 state_change
uint16_t net_key_id
meshx_cfg_srv_state_change_t state_change
meshx_state_change_cfg_model_app_bind_t mod_app_bind
meshx_state_change_cfg_mod_pub_set_t mod_pub_set
meshx_state_change_cfg_appkey_add_t appkey_add
meshx_err_t register_unit_test(module_id_t module_id, module_callback_t callback)
Register a unit test for a specific module.
Definition unit_test.c:149
#define UT_GET_ARG(_x, _type, _argv)
Macro to extract an argument from the argument list.
Definition unit_test.h:27