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_relay_server.c
Go to the documentation of this file.
1
12
14#include "meshx_nvs.h"
15#include "meshx_api.h"
16
17#if CONFIG_RELAY_SERVER_COUNT > 0
18
19#if CONFIG_ENABLE_CONFIG_SERVER
20#include "meshx_config_server.h"
21
25#define CONFIG_SERVER_CB_MASK \
26 CONTROL_TASK_MSG_EVT_PUB_ADD \
27 | CONTROL_TASK_MSG_EVT_SUB_ADD | CONTROL_TASK_MSG_EVT_APP_KEY_BIND
28#endif /* CONFIG_ENABLE_CONFIG_SERVER */
29
30#define CONTROL_TASK_EVT_MASK CONTROL_TASK_MSG_EVT_EL_STATE_CH_SET_ON_OFF
31
32#define CONTROL_TASK_MSG_EVT_TO_BLE_GEN_SRV_MASK CONTROL_TASK_MSG_EVT_TO_BLE_SET_ON_OFF_SRV
33
39#define GET_RELATIVE_EL_IDX(_element_id) ((_element_id) - (relay_element_init_ctrl.element_id_start))
40
46#define IS_EL_IN_RANGE(_element_id) ((_element_id) >= relay_element_init_ctrl.element_id_start && (_element_id) < relay_element_init_ctrl.element_id_end)
47#define RELAY_SRV_EL(_el_id) relay_element_init_ctrl.el_list[_el_id]
52
53#if CONFIG_ENABLE_CONFIG_SERVER
54
68 const dev_struct_t *pdev,
70 const meshx_config_srv_cb_param_t *params)
71{
72 MESHX_UNUSED(pdev);
73 meshx_relay_srv_model_ctx_t *el_ctx = NULL;
74 size_t rel_el_id = 0;
75 uint16_t element_id = 0;
76 uint16_t base_el_id = 0;
77 bool nvs_save = false;
78 meshx_get_base_element_id(&base_el_id);
80 switch (evt)
81 {
83 element_id = params->state_change.mod_app_bind.element_addr - base_el_id;
85 if (!IS_EL_IN_RANGE(element_id))
86 break;
87 rel_el_id = GET_RELATIVE_EL_IDX(element_id);
88 el_ctx = RELAY_SRV_EL(rel_el_id).srv_ctx;
89 el_ctx->app_id = params->state_change.appkey_add.app_idx;
90 nvs_save = true;
91 break;
94 element_id = params->state_change.mod_pub_set.element_addr - base_el_id;
96 if (!IS_EL_IN_RANGE(element_id))
97 break;
98 rel_el_id = GET_RELATIVE_EL_IDX(element_id);
99 el_ctx = RELAY_SRV_EL(rel_el_id).srv_ctx;
102 el_ctx->app_id = params->state_change.mod_pub_set.app_idx;
103 MESHX_LOGI(MODULE_ID_ELEMENT_SWITCH_RELAY_SERVER, "PUB_ADD: %d, %d, 0x%X, 0x%X", element_id, rel_el_id, el_ctx->pub_addr, el_ctx->app_id);
104 nvs_save = true;
105 break;
106 default:
107 break;
108 }
109 if (nvs_save)
110 {
111 meshx_err_t err = meshx_nvs_element_ctx_set(element_id, el_ctx, sizeof(meshx_relay_srv_model_ctx_t));
112 if (err != MESHX_SUCCESS)
113 {
114 MESHX_LOGE(MODULE_ID_ELEMENT_SWITCH_RELAY_SERVER, "Failed to set relay server element context: (%d)", err);
115 }
116 }
117 return MESHX_SUCCESS;
118}
119#endif /* CONFIG_ENABLE_CONFIG_SERVER */
120
136{
137 if (!n_max)
138 return MESHX_INVALID_ARG;
139
140 if (relay_element_init_ctrl.el_list)
141 {
142 MESHX_LOGW(MODULE_ID_ELEMENT_SWITCH_RELAY_SERVER, "Relay element list already initialized");
143 return MESHX_INVALID_STATE;
144 }
145
147
148 relay_element_init_ctrl.element_cnt = n_max;
149 relay_element_init_ctrl.element_id_end = 0;
150 relay_element_init_ctrl.element_id_start = 0;
151
154
155 if (!relay_element_init_ctrl.el_list)
156 return MESHX_NO_MEM;
157
158 for (size_t i = 0; i < relay_element_init_ctrl.element_cnt; i++)
159 {
160 RELAY_SRV_EL(i).srv_ctx =
162
163 if (!RELAY_SRV_EL(i).srv_ctx)
164 return MESHX_NO_MEM;
165
166 err = meshx_on_off_server_create(&RELAY_SRV_EL(i).onoff_srv_model,
167 &RELAY_SRV_EL(i).relay_srv_model_list[RELAY_SIG_ONOFF_MODEL_ID]);
168 if (err)
169 {
170 MESHX_LOGE(MODULE_ID_ELEMENT_SWITCH_RELAY_SERVER, "Meshx On Off Server create failed (Err : 0x%x)", err);
171 return err;
172 }
173 RELAY_SRV_EL(i).onoff_srv_model->meshx_sig
174 = &RELAY_SRV_EL(i).relay_srv_model_list[RELAY_SIG_ONOFF_MODEL_ID];
175 }
176
177 return err;
178}
179
193{
194 if (!relay_element_init_ctrl.element_cnt || !relay_element_init_ctrl.el_list)
195 {
196 MESHX_LOGE(MODULE_ID_ELEMENT_SWITCH_RELAY_SERVER, "Relay element list not initialized");
197 return MESHX_INVALID_STATE;
198 }
199
200 meshx_err_t err;
201
202 for (size_t i = 0; i < relay_element_init_ctrl.element_cnt; i++)
203 {
204 if (RELAY_SRV_EL(i).srv_ctx)
205 {
206 MESHX_FREE(RELAY_SRV_EL(i).srv_ctx);
207 RELAY_SRV_EL(i).srv_ctx = NULL;
208 }
209 err = meshx_on_off_server_delete(&RELAY_SRV_EL(i).onoff_srv_model);
210 if (err)
211 MESHX_LOGE(MODULE_ID_ELEMENT_SWITCH_RELAY_SERVER, "Meshx On Off Server delete failed (Err : 0x%x)", err);
212 }
213
214 if (relay_element_init_ctrl.el_list)
215 {
217 relay_element_init_ctrl.el_list = NULL;
218 }
219
220 return MESHX_SUCCESS;
221}
222
232{
234 if (err)
235 {
236 MESHX_LOGE(MODULE_ID_ELEMENT_SWITCH_RELAY_SERVER, "Relay Model space create failed: (%d)", err);
238 return err;
239 }
240 return MESHX_SUCCESS;
241}
242
251static meshx_err_t meshx_restore_model_states(uint16_t element_id)
252{
253 uint16_t model_id = 0;
255 meshx_relay_srv_model_ctx_t const *el_ctx = RELAY_SRV_EL(element_id).srv_ctx;
256 for (size_t i = 0; i < RELAY_SRV_MODEL_SIG_CNT; i++)
257 {
258 err = meshx_get_model_id(RELAY_SRV_EL(element_id).onoff_srv_model->meshx_sig,
259 &model_id);
260 if (err)
261 {
262 MESHX_LOGE(MODULE_ID_ELEMENT_SWITCH_RELAY_SERVER, "Failed to get model ID (err: 0x%x)", err);
263 return err;
264 }
265
266 if (model_id == MESHX_MODEL_ID_GEN_ONOFF_SRV)
267 {
268 err = meshx_gen_on_off_srv_state_restore(RELAY_SRV_EL(element_id).onoff_srv_model->meshx_sig,
269 el_ctx->state);
270 if (err)
271 {
272 MESHX_LOGE(MODULE_ID_ELEMENT_SWITCH_RELAY_SERVER, "Failed to restore on-off server state (err: 0x%x)", err);
273 return err;
274 }
275 }
276 }
277 return err;
278}
279
289static meshx_err_t meshx_add_relay_srv_model_to_element_list(dev_struct_t *pdev, uint16_t *start_idx, uint16_t n_max)
290{
291 if (!pdev)
292 return MESHX_INVALID_STATE;
293
294 if ((n_max + *start_idx) > CONFIG_MAX_ELEMENT_COUNT)
295 {
296 MESHX_LOGE(MODULE_ID_ELEMENT_SWITCH_RELAY_SERVER, "No of elements limit reached");
297 return MESHX_NO_MEM;
298 }
299
301 relay_element_init_ctrl.element_id_start = *start_idx;
302
303 for (uint16_t i = *start_idx; i < (n_max + *start_idx); i++)
304 {
305
306 if (i == 0)
307 continue;
309 i,
310 pdev->elements,
311 RELAY_SRV_EL(i - *start_idx).relay_srv_model_list,
312 NULL,
315 if (err)
316 {
317 MESHX_LOGE(MODULE_ID_ELEMENT_SWITCH_RELAY_SERVER, "Failed to add element to composition: (%d)", err);
318 return err;
319 }
321 i,
322 RELAY_SRV_EL(i - *start_idx).srv_ctx,
324 if (err != MESHX_SUCCESS)
325 {
326 MESHX_LOGW(MODULE_ID_ELEMENT_SWITCH_RELAY_SERVER, "Failed to get relay element context: (0x%x)", err);
327 }
328 else
329 {
330 err = meshx_restore_model_states(i - *start_idx);
331 if (err != MESHX_SUCCESS)
332 {
333 MESHX_LOGW(MODULE_ID_ELEMENT_SWITCH_RELAY_SERVER, "Failed to restore relay model states: (0x%x)", err);
334 }
335 }
336 }
337 relay_element_init_ctrl.element_id_end = (*start_idx += n_max);
338 return MESHX_SUCCESS;
339}
340
352{
353 MESHX_UNUSED(pdev);
354 MESHX_UNUSED(evt);
355 size_t rel_el_id = 0;
357 meshx_relay_srv_model_ctx_t *el_ctx = NULL;
358 const meshx_on_off_srv_el_msg_t *p_onoff_srv = (meshx_on_off_srv_el_msg_t *)params;
360 uint16_t element_id = p_onoff_srv->model.el_id;
361
362 if (!IS_EL_IN_RANGE(element_id))
363 return MESHX_SUCCESS;
364
365 rel_el_id = GET_RELATIVE_EL_IDX(element_id);
366 el_ctx = RELAY_SRV_EL(rel_el_id).srv_ctx;
367
368 el_ctx->state.on_off = p_onoff_srv->on_off_state;
369
370 err = meshx_nvs_element_ctx_set(element_id, el_ctx, sizeof(meshx_relay_srv_model_ctx_t));
371 if (err != MESHX_SUCCESS)
372 MESHX_LOGE(MODULE_ID_ELEMENT_SWITCH_RELAY_SERVER, "Failed to set relay element context: (%d)", err);
373
374 state.on_off = el_ctx->state.on_off;
376 element_id,
380 &state);
381 if (err != MESHX_SUCCESS)
382 MESHX_LOGE(MODULE_ID_ELEMENT_SWITCH_RELAY_SERVER, "Failed to send relay state change message: (%d)", err);
383
384 return MESHX_SUCCESS;
385}
386
397{
398 MESHX_UNUSED(params);
399
400 size_t rel_el_id = 0;
401 meshx_gen_srv_cb_param_t gen_srv_send;
403
404 switch (evt)
405 {
407 for (size_t el_id = relay_element_init_ctrl.element_id_start; el_id < relay_element_init_ctrl.element_id_end; el_id++)
408 {
409 rel_el_id = GET_RELATIVE_EL_IDX(el_id);
410
411 err = meshx_gen_on_off_srv_send_pack_create(
412 RELAY_SRV_EL(rel_el_id).onoff_srv_model->meshx_sig,
413 (uint16_t)el_id,
415 RELAY_SRV_EL(rel_el_id).srv_ctx->app_id,
416 RELAY_SRV_EL(rel_el_id).srv_ctx->pub_addr,
417 RELAY_SRV_EL(rel_el_id).srv_ctx->state.on_off,
418 &gen_srv_send
419 );
420
421 if ((err != MESHX_SUCCESS)
422 || (gen_srv_send.ctx.dst_addr == MESHX_ADDR_UNASSIGNED)
423 || (gen_srv_send.ctx.app_idx == MESHX_KEY_UNUSED))
424 {
425 continue;
426 }
427
430 &gen_srv_send
431 );
432 if (err)
433 {
434 MESHX_LOGE(MODULE_ID_ELEMENT_SWITCH_RELAY_SERVER, "Failed to send ONOFF status message (Err: %x)", err);
435 return err;
436 }
437 }
438 break;
439
440 default:
441 MESHX_LOGW(MODULE_ID_ELEMENT_SWITCH_RELAY_SERVER, "Unhandled event: %d", evt);
442 break;
443 }
444 return MESHX_SUCCESS;
445}
446
462 const dev_struct_t *pdev,
465{
467 return MESHX_SUCCESS;
468
469 uint16_t element_id = params->model.el_id;
470
471 if (!IS_EL_IN_RANGE(element_id))
472 return MESHX_SUCCESS;
473
474 meshx_err_t err = meshx_gen_on_off_srv_status_send(
475 &params->model,
476 &params->ctx,
478 );
479 if(err)
480 {
481 MESHX_LOGE(MODULE_ID_MODEL_SERVER, "Mesh Model msg send failed (err: 0x%x)", err);
482 return MESHX_ERR_PLAT;
483 }
484
485 ESP_UNUSED(pdev);
486 return MESHX_SUCCESS;
487}
488
498{
499 meshx_err_t err;
500 err = meshx_dev_create_relay_model_space(element_cnt);
501 if (err)
502 {
503 MESHX_LOGE(MODULE_ID_ELEMENT_SWITCH_RELAY_SERVER, "Relay Model create failed: (%d)", err);
504 return err;
505 }
506 err = meshx_add_relay_srv_model_to_element_list(pdev, (uint16_t *)&pdev->element_idx, element_cnt);
507 if (err)
508 {
509 MESHX_LOGE(MODULE_ID_ELEMENT_SWITCH_RELAY_SERVER, "Relay Model create failed: (%d)", err);
510 return err;
511 }
512#if CONFIG_ENABLE_CONFIG_SERVER
516 if (err)
517 {
518 MESHX_LOGE(MODULE_ID_ELEMENT_SWITCH_RELAY_SERVER, "Relay Model configserver callback reg failed: (%d)", err);
519 return err;
520 }
521#endif /* CONFIG_ENABLE_CONFIG_SERVER */
526 if (err)
527 {
528 MESHX_LOGE(MODULE_ID_ELEMENT_SWITCH_RELAY_SERVER, "Failed to register control task callback: (%d)", err);
529 return err;
530 }
531
533 if (err)
534 {
535 MESHX_LOGE(MODULE_ID_ELEMENT_SWITCH_RELAY_SERVER, "Failed to register control task callback: (%d)", err);
536 return err;
537 }
542 if (err)
543 {
544 MESHX_LOGE(MODULE_ID_ELEMENT_SWITCH_RELAY_SERVER, "Failed to register control task callback: (%d)", err);
545 return err;
546 }
547 err = meshx_on_off_server_init();
548 if (err)
549 {
550 MESHX_LOGE(MODULE_ID_ELEMENT_SWITCH_RELAY_SERVER, "meshx_on_off_server_init failed: (%d)", err);
551 return err;
552 }
553 return MESHX_SUCCESS;
554}
555
557
558#endif /* CONFIG_RELAY_SERVER_COUNT > 0 */
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
struct meshx_api_relay_server_evt meshx_api_relay_server_evt_t
Structure defines the payload for MESHX_ELEMENT_TYPE_RELAY_SERVER.
@ MESHX_ELEMENT_TYPE_RELAY_SERVER
Definition meshx_api.h:44
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_model_id(meshx_ptr_t p_model, uint16_t *model_id)
Retrieve the model ID of a generic server model.
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_KEY_UNUSED
#define MESHX_ADDR_UNASSIGNED
#define MESHX_MODEL_ID_GEN_ONOFF_SRV
struct meshx_config_srv_cb_param meshx_config_srv_cb_param_t
control_task_msg_handle_t config_srv_cb_t
struct meshx_gen_srv_cb_param meshx_gen_srv_cb_param_t
control_task_msg_handle_t prov_srv_cb_t
#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.
CONTROL_TASK_MSG_EVT_TO_BLE_SET_ON_OFF_SRV
enum __packed control_task_msg_evt_to_ble control_task_msg_evt_to_ble_t
Enumeration for control task message events to BLE.
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_CODE_EL_STATE_CH
@ CONTROL_TASK_MSG_CODE_TO_BLE
CONTROL_TASK_MSG_EVT_PUB_ADD
CONTROL_TASK_MSG_EVT_EN_NODE_PROV
CONTROL_TASK_MSG_EVT_APP_KEY_BIND
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 CONTROL_TASK_EVT_MASK
#define CONTROL_TASK_MSG_EVT_TO_BLE_GEN_SRV_MASK
static meshx_err_t meshx_api_control_task_handler(const dev_struct_t *pdev, const control_task_msg_evt_t evt, const void *params)
CW-WW server model event handler.
#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_ERR_PLAT
Definition meshx_err.h:43
@ MESHX_INVALID_STATE
Definition meshx_err.h:45
@ MESHX_NO_MEM
Definition meshx_err.h:44
#define MESHX_FREE
Definition meshx_err.h:32
meshx_err_t meshx_gen_srv_send_msg_to_ble(control_task_msg_evt_to_ble_t evt, const meshx_gen_srv_cb_param_t *params)
Sends a message to the BLE subsystem via the control task.
#define CONFIG_SERVER_CB_MASK
Configuration server callback event mask for cwww server.
#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_server_cb(prov_srv_cb_t cb)
Register a callback function for provisioning events.
static relay_client_element_ctrl_t relay_element_init_ctrl
static meshx_err_t meshx_api_control_task_handler(dev_struct_t const *pdev, control_task_msg_evt_t evt, void *params)
Callback function for relay server model events.
static meshx_err_t meshx_relay_srv_msg_send_handler(const dev_struct_t *pdev, control_task_msg_evt_to_ble_t evt, meshx_gen_srv_cb_param_t *params)
Handles the BLE message sending for the Generic OnOff Server model.
#define GET_RELATIVE_EL_IDX(_element_id)
Get the relative index of an element ID.
static meshx_err_t relay_prov_control_task_handler(dev_struct_t const *pdev, control_task_msg_evt_t evt, void const *params)
Callback function for relay server model events for Provisioning events.
static meshx_err_t meshx_restore_model_states(uint16_t element_id)
Restore saved relay model states.
static meshx_err_t meshx_add_relay_srv_model_to_element_list(dev_struct_t *pdev, uint16_t *start_idx, uint16_t n_max)
Add relay server models to the element list.
static meshx_err_t relay_server_config_srv_cb(const dev_struct_t *pdev, control_task_msg_evt_t evt, const meshx_config_srv_cb_param_t *params)
Callback function for configuration server events.
static meshx_err_t meshx_dev_create_relay_model_space(uint16_t n_max)
Create relay model space.
static meshx_err_t meshx_element_struct_deinit(void)
Deinitializes the mesh element structure by freeing allocated memory.
#define RELAY_SRV_EL(_el_id)
static meshx_err_t meshx_element_struct_init(uint16_t n_max)
Initialize the mesh element structure by allocating memory for various components.
#define IS_EL_IN_RANGE(_element_id)
Check if an element ID is within range.
meshx_err_t meshx_create_relay_elements(dev_struct_t *pdev, uint16_t element_cnt)
Create Dynamic Relay Model Elements.
Header file for the Relay Server Model.
struct meshx_relay_element_ctrl meshx_relay_element_ctrl_t
Structure to manage relay element initialization.
#define RELAY_SRV_MODEL_VEN_CNT
struct meshx_relay_srv_model_ctx meshx_relay_srv_model_ctx_t
Structure to hold the relay server save restore context.
@ RELAY_SIG_ONOFF_MODEL_ID
#define RELAY_SRV_MODEL_SIG_CNT
meshx_err_t meshx_create_relay_elements(dev_struct_t *pdev, uint16_t element_cnt)
Create Dynamic Relay Model Elements.
struct meshx_relay_element meshx_relay_element_t
Structure to manage relay element models.
@ MODULE_ID_ELEMENT_SWITCH_RELAY_SERVER
Definition module_id.h:28
@ MODULE_ID_MODEL_SERVER
Definition module_id.h:30
meshx_app_store_t meshx_store
size_t element_idx
MESHX_ELEMENT elements[MAX_ELE_CNT]
uint16_t net_key_id
meshx_cfg_srv_state_change_t state_change
uint16_t dst_addr
meshx_gen_srv_state_change_t state_change
meshx_on_off_srv_el_state_t state
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_state_change_gen_onoff_set_t onoff_set