nRF Connect SDK API 0.1.0
Loading...
Searching...
No Matches
config_event.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2018 Nordic Semiconductor ASA
3 *
4 * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
5 */
6
7#ifndef _CONFIG_EVENT_H_
8#define _CONFIG_EVENT_H_
9
16#include <app_event_manager.h>
18#include "hid_report_desc.h"
19
20#ifdef __cplusplus
21extern "C" {
22#endif
23
24
26#define CONFIG_STATUS_LIST \
27 X(PENDING) \
28 X(GET_MAX_MOD_ID) \
29 X(GET_HWID) \
30 X(GET_BOARD_NAME) \
31 X(INDEX_PEERS) \
32 X(GET_PEER) \
33 X(SET) \
34 X(FETCH) \
35 X(SUCCESS) \
36 X(TIMEOUT) \
37 X(REJECT) \
38 X(WRITE_FAIL) \
39 X(DISCONNECTED) \
40 X(GET_PEERS_CACHE)
41
43#define X(name) _CONCAT(CONFIG_STATUS_, name),
45#undef X
46
48};
49
50/* Maximum length of fetched data. */
51#define CONFIG_CHANNEL_FETCHED_DATA_MAX_SIZE 16
52
53/* Config event, setup group macros */
54
55#define MOD_FIELD_POS 4
56#define MOD_FIELD_SIZE 4
57#define MOD_FIELD_MASK BIT_MASK(MOD_FIELD_SIZE)
58#define MOD_FIELD_SET(module) ((module & MOD_FIELD_MASK) << MOD_FIELD_POS)
59#define MOD_FIELD_GET(event_id) ((event_id >> MOD_FIELD_POS) & MOD_FIELD_MASK)
60
61#define OPT_FIELD_POS 0
62#define OPT_FIELD_SIZE 4
63#define OPT_FIELD_MASK BIT_MASK(OPT_FIELD_SIZE)
64#define OPT_FIELD_SET(option) ((option & OPT_FIELD_MASK) << OPT_FIELD_POS)
65#define OPT_FIELD_GET(event_id) ((event_id >> OPT_FIELD_POS) & OPT_FIELD_MASK)
66
67#define OPT_ID_GET(opt_field) (opt_field - 1)
68
69/* Common module option macros */
70#define MODULE_OPT_MODULE_DESCR 0x0
71
72/* Character used to inform about end of module description. */
73#define MODULE_DESCR_END_CHAR '\n'
74
75/* Description of the option representing module variant. */
76#define OPT_DESCR_MODULE_VARIANT "module_variant"
77
78/* Configuration channel local recipient. */
79#define CFG_CHAN_RECIPIENT_LOCAL 0x00
80
85 struct app_event_header header;
86
87 uint16_t transport_id;
89
90 /* Data exchanged with host. */
91 uint8_t event_id;
92 uint8_t recipient;
93 uint8_t status;
94 struct event_dyndata dyndata;
95};
96
98
99extern const uint8_t __start_config_channel_modules[];
100
101#define GEN_CONFIG_EVENT_HANDLERS(mod_name, opt_descr, config_set_fn, config_fetch_fn) \
102 BUILD_ASSERT(ARRAY_SIZE(opt_descr) > 0); \
103 BUILD_ASSERT(ARRAY_SIZE(opt_descr) <= OPT_FIELD_MASK); \
104 if (IS_ENABLED(CONFIG_DESKTOP_CONFIG_CHANNEL_ENABLE) && is_config_event(aeh)) { \
105 static const uint8_t module_id_in_section \
106 __attribute__((__section__("config_channel_modules"))) = 0; \
107 uint8_t config_module_id = \
108 &module_id_in_section - (uint8_t *)__start_config_channel_modules; \
109 static uint8_t cur_opt_descr; \
110 \
111 struct config_event *event = cast_config_event(aeh); \
112 \
113 uint8_t rsp_data_buf[CONFIG_CHANNEL_FETCHED_DATA_MAX_SIZE]; \
114 size_t rsp_data_size = 0; \
115 bool consume = false; \
116 \
117 /* Not for us. */ \
118 if (event->recipient != CFG_CHAN_RECIPIENT_LOCAL) { \
119 return false; \
120 } \
121 \
122 if (event->status == CONFIG_STATUS_SET) { \
123 if (MOD_FIELD_GET(event->event_id) == config_module_id) { \
124 BUILD_ASSERT(config_set_fn != NULL); \
125 (*config_set_fn)(OPT_ID_GET(OPT_FIELD_GET(event->event_id)), \
126 event->dyndata.data, \
127 event->dyndata.size); \
128 consume = true; \
129 } \
130 } else if (event->status == CONFIG_STATUS_FETCH) { \
131 if (MOD_FIELD_GET(event->event_id) == config_module_id) { \
132 if (OPT_FIELD_GET(event->event_id) == MODULE_OPT_MODULE_DESCR) {\
133 if (cur_opt_descr < ARRAY_SIZE(opt_descr) + 1) { \
134 const char *data_ptr; \
135 \
136 if (cur_opt_descr == 0) { \
137 data_ptr = mod_name; \
138 } else { \
139 data_ptr = opt_descr[cur_opt_descr - 1];\
140 } \
141 rsp_data_size = strlen(data_ptr); \
142 __ASSERT_NO_MSG(rsp_data_size <= \
143 sizeof(rsp_data_buf)); \
144 strncpy((char *) rsp_data_buf, data_ptr, \
145 rsp_data_size); \
146 cur_opt_descr++; \
147 } else { \
148 rsp_data_size = sizeof(uint8_t); \
149 rsp_data_buf[0] = MODULE_DESCR_END_CHAR; \
150 cur_opt_descr = 0; \
151 } \
152 } else { \
153 BUILD_ASSERT(config_fetch_fn != NULL); \
154 (*config_fetch_fn)(OPT_ID_GET( \
155 OPT_FIELD_GET(event->event_id)), \
156 rsp_data_buf, \
157 &rsp_data_size); \
158 } \
159 consume = true; \
160 } \
161 } \
162 \
163 if (consume) { \
164 struct config_event *rsp = new_config_event(rsp_data_size); \
165 \
166 rsp->transport_id = event->transport_id; \
167 rsp->recipient = event->recipient; \
168 rsp->event_id = event->event_id; \
169 rsp->status = CONFIG_STATUS_SUCCESS; \
170 rsp->is_request = false; \
171 \
172 if (rsp_data_size > 0) { \
173 memcpy(rsp->dyndata.data, rsp_data_buf, rsp_data_size); \
174 } \
175 \
176 APP_EVENT_SUBMIT(rsp); \
177 } \
178 \
179 return consume; \
180 }
181
182#ifdef __cplusplus
183}
184#endif
185
190#endif /* _CONFIG_EVENT_H_ */
Application Event Manager header.
Application Event Manager profiler tracer header.
#define APP_EVENT_TYPE_DYNDATA_DECLARE(ename)
Declare an event type with dynamic data size.
Definition: app_event_manager.h:154
config_status
Definition: config_event.h:42
@ CONFIG_STATUS_COUNT
Definition: config_event.h:47
#define CONFIG_STATUS_LIST
Config channel status list.
Definition: config_event.h:26
Header file HID report identifiers.
bool is_request
Definition: config_event.h:88
uint8_t status
Definition: config_event.h:93
struct app_event_header header
Definition: config_event.h:85
uint8_t recipient
Definition: config_event.h:92
uint16_t transport_id
Definition: config_event.h:87
uint8_t event_id
Definition: config_event.h:91
struct event_dyndata dyndata
Definition: config_event.h:94
Configuration channel event. Used to forward configuration channel request/response.
Definition: config_event.h:84