Line data Source code
1 1 : /*
2 : * Copyright (c) 2020 Siddharth Chandrasekaran <siddharth@embedjournal.com>
3 : *
4 : * SPDX-License-Identifier: Apache-2.0
5 : */
6 :
7 : /**
8 : * @file
9 : * @brief Open Supervised Device Protocol (OSDP) public API header file.
10 : */
11 :
12 : #ifndef ZEPHYR_INCLUDE_MGMT_OSDP_H_
13 : #define ZEPHYR_INCLUDE_MGMT_OSDP_H_
14 :
15 : #include <zephyr/kernel.h>
16 : #include <stdint.h>
17 :
18 : #include <zephyr/sys/slist.h>
19 :
20 : #ifdef __cplusplus
21 : extern "C" {
22 : #endif
23 :
24 1 : #define OSDP_CMD_TEXT_MAX_LEN 32 /**< Max length of text for text command */
25 1 : #define OSDP_CMD_KEYSET_KEY_MAX_LEN 32 /**< Max length of key data for keyset command */
26 1 : #define OSDP_EVENT_MAX_DATALEN 64 /**< Max length of event data */
27 :
28 : /**
29 : * @brief Command sent from CP to Control digital output of PD.
30 : */
31 1 : struct osdp_cmd_output {
32 : /**
33 : * Output number.
34 : *
35 : * 0 = First Output, 1 = Second Output, etc.
36 : */
37 1 : uint8_t output_no;
38 : /**
39 : * Control code.
40 : *
41 : * - 0 - NOP – do not alter this output
42 : * - 1 - set the permanent state to OFF, abort timed operation (if any)
43 : * - 2 - set the permanent state to ON, abort timed operation (if any)
44 : * - 3 - set the permanent state to OFF, allow timed operation to complete
45 : * - 4 - set the permanent state to ON, allow timed operation to complete
46 : * - 5 - set the temporary state to ON, resume perm state on timeout
47 : * - 6 - set the temporary state to OFF, resume permanent state on timeout
48 : */
49 1 : uint8_t control_code;
50 : /**
51 : * Time in units of 100 ms
52 : */
53 1 : uint16_t timer_count;
54 : };
55 :
56 : /**
57 : * @brief LED Colors as specified in OSDP for the on_color/off_color parameters.
58 : */
59 1 : enum osdp_led_color_e {
60 : OSDP_LED_COLOR_NONE, /**< No color */
61 : OSDP_LED_COLOR_RED, /**< Red */
62 : OSDP_LED_COLOR_GREEN, /**< Green */
63 : OSDP_LED_COLOR_AMBER, /**< Amber */
64 : OSDP_LED_COLOR_BLUE, /**< Blue */
65 : OSDP_LED_COLOR_SENTINEL /**< Max value */
66 : };
67 :
68 : /**
69 : * @brief LED params sub-structure. Part of LED command. See @ref osdp_cmd_led.
70 : */
71 1 : struct osdp_cmd_led_params {
72 : /** Control code.
73 : *
74 : * Temporary Control Code:
75 : * - 0 - NOP - do not alter this LED's temporary settings.
76 : * - 1 - Cancel any temporary operation and display this LED's permanent state immediately.
77 : * - 2 - Set the temporary state as given and start timer immediately.
78 : *
79 : * Permanent Control Code:
80 : * - 0 - NOP - do not alter this LED's permanent settings.
81 : * - 1 - Set the permanent state as given.
82 : */
83 1 : uint8_t control_code;
84 : /**
85 : * The ON duration of the flash, in units of 100 ms.
86 : */
87 1 : uint8_t on_count;
88 : /**
89 : * The OFF duration of the flash, in units of 100 ms.
90 : */
91 1 : uint8_t off_count;
92 : /**
93 : * Color to set during the ON timer (see @ref osdp_led_color_e).
94 : */
95 1 : uint8_t on_color;
96 : /**
97 : * Color to set during the OFF timer (see @ref osdp_led_color_e).
98 : */
99 1 : uint8_t off_color;
100 : /**
101 : * Time in units of 100 ms (only for temporary mode).
102 : */
103 1 : uint16_t timer_count;
104 : };
105 :
106 : /**
107 : * @brief Sent from CP to PD to control the behaviour of it's on-board LEDs
108 : */
109 1 : struct osdp_cmd_led {
110 : /**
111 : * Reader number. 0 = First Reader, 1 = Second Reader, etc.
112 : */
113 1 : uint8_t reader;
114 : /**
115 : * LED number. 0 = first LED, 1 = second LED, etc.
116 : */
117 1 : uint8_t led_number;
118 : /**
119 : * Ephemeral LED status descriptor.
120 : */
121 1 : struct osdp_cmd_led_params temporary;
122 : /**
123 : * Permanent LED status descriptor.
124 : */
125 1 : struct osdp_cmd_led_params permanent;
126 : };
127 :
128 : /**
129 : * @brief Sent from CP to control the behaviour of a buzzer in the PD.
130 : */
131 1 : struct osdp_cmd_buzzer {
132 : /**
133 : * Reader number. 0 = First Reader, 1 = Second Reader, etc.
134 : */
135 1 : uint8_t reader;
136 : /**
137 : * Control code.
138 : * - 0 - no tone
139 : * - 1 - off
140 : * - 2 - default tone
141 : * - 3+ - TBD
142 : */
143 1 : uint8_t control_code;
144 : /**
145 : * The ON duration of the sound, in units of 100 ms.
146 : */
147 1 : uint8_t on_count;
148 : /**
149 : * The OFF duration of the sound, in units of 100 ms.
150 : */
151 1 : uint8_t off_count;
152 : /**
153 : * The number of times to repeat the ON/OFF cycle; 0: forever.
154 : */
155 1 : uint8_t rep_count;
156 : };
157 :
158 : /**
159 : * @brief Command to manipulate any display units that the PD supports.
160 : */
161 1 : struct osdp_cmd_text {
162 : /**
163 : * Reader number. 0 = First Reader, 1 = Second Reader, etc.
164 : */
165 1 : uint8_t reader;
166 : /**
167 : * Control code.
168 : * - 1 - permanent text, no wrap
169 : * - 2 - permanent text, with wrap
170 : * - 3 - temp text, no wrap
171 : * - 4 - temp text, with wrap
172 : */
173 1 : uint8_t control_code;
174 : /**
175 : * Duration to display temporary text, in seconds
176 : */
177 1 : uint8_t temp_time;
178 : /**
179 : * Row to display the first character (1-indexed)
180 : */
181 1 : uint8_t offset_row;
182 : /**
183 : * Column to display the first character (1-indexed)
184 : */
185 1 : uint8_t offset_col;
186 : /**
187 : * Number of characters in the string
188 : */
189 1 : uint8_t length;
190 : /**
191 : * The string to display
192 : */
193 1 : uint8_t data[OSDP_CMD_TEXT_MAX_LEN];
194 : };
195 :
196 : /**
197 : * @brief Sent in response to a COMSET command. Set communication parameters to
198 : * PD. Must be stored in PD non-volatile memory.
199 : */
200 1 : struct osdp_cmd_comset {
201 : /**
202 : * Unit ID to which this PD will respond after the change takes effect.
203 : */
204 1 : uint8_t address;
205 : /**
206 : * Baud rate.
207 : *
208 : * Valid values: 9600, 19200, 38400, 115200, 230400.
209 : */
210 1 : uint32_t baud_rate;
211 : };
212 :
213 : /**
214 : * @brief This command transfers an encryption key from the CP to a PD.
215 : *
216 : * @param type Type of keys:
217 : * - 0x01 – Secure Channel Base Key
218 : * @param length Number of bytes of key data - (Key Length in bits + 7) / 8
219 : * @param data Key data
220 : */
221 1 : struct osdp_cmd_keyset {
222 : /**
223 : * Type of keys:
224 : * - 0x01 – Secure Channel Base Key
225 : */
226 1 : uint8_t type;
227 : /**
228 : * Number of bytes of key data - (Key Length in bits + 7) / 8
229 : */
230 1 : uint8_t length;
231 : /**
232 : * Key data
233 : */
234 1 : uint8_t data[OSDP_CMD_KEYSET_KEY_MAX_LEN];
235 : };
236 :
237 : /**
238 : * @brief OSDP application exposed commands
239 : */
240 1 : enum osdp_cmd_e {
241 : OSDP_CMD_OUTPUT = 1, /**< Output control command */
242 : OSDP_CMD_LED, /**< Reader LED control command */
243 : OSDP_CMD_BUZZER, /**< Reader buzzer control command */
244 : OSDP_CMD_TEXT, /**< Reader text output command */
245 : OSDP_CMD_KEYSET, /**< Encryption Key Set Command */
246 : OSDP_CMD_COMSET, /**< PD Communication Configuration Command */
247 : OSDP_CMD_SENTINEL /**< Max command value */
248 : };
249 :
250 : /**
251 : * @brief OSDP Command Structure. This is a wrapper for all individual OSDP
252 : * commands.
253 : */
254 1 : struct osdp_cmd {
255 : /** @cond INTERNAL_HIDDEN */
256 : sys_snode_t node;
257 : /** @endcond */
258 : /**
259 : * Command ID.
260 : * Used to select specific commands in union.
261 : */
262 1 : enum osdp_cmd_e id;
263 : /** Command */
264 : union {
265 1 : struct osdp_cmd_led led; /**< LED command structure */
266 1 : struct osdp_cmd_buzzer buzzer; /**< Buzzer command structure */
267 1 : struct osdp_cmd_text text; /**< Text command structure */
268 1 : struct osdp_cmd_output output; /**< Output command structure */
269 1 : struct osdp_cmd_comset comset; /**< Comset command structure */
270 1 : struct osdp_cmd_keyset keyset; /**< Keyset command structure */
271 1 : };
272 : };
273 :
274 : /**
275 : * @brief Various card formats that a PD can support. This is sent to CP
276 : * when a PD must report a card read.
277 : */
278 1 : enum osdp_event_cardread_format_e {
279 : OSDP_CARD_FMT_RAW_UNSPECIFIED, /**< Unspecified card format */
280 : OSDP_CARD_FMT_RAW_WIEGAND, /**< Wiegand card format */
281 : OSDP_CARD_FMT_ASCII, /**< ASCII card format */
282 : OSDP_CARD_FMT_SENTINEL /**< Max card format value */
283 : };
284 :
285 : /**
286 : * @brief OSDP event cardread
287 : *
288 : * @note When @a format is set to OSDP_CARD_FMT_RAW_UNSPECIFIED or
289 : * OSDP_CARD_FMT_RAW_WIEGAND, the length is expressed in bits. OTOH, when it is
290 : * set to OSDP_CARD_FMT_ASCII, the length is in bytes. The number of bytes to
291 : * read from the @a data field must be interpreted accordingly.
292 : */
293 1 : struct osdp_event_cardread {
294 : /**
295 : * Reader number. 0 = First Reader, 1 = Second Reader, etc.
296 : */
297 1 : int reader_no;
298 : /**
299 : * Format of the card being read.
300 : */
301 1 : enum osdp_event_cardread_format_e format;
302 : /**
303 : * Direction of data in @a data array.
304 : * - 0 - Forward
305 : * - 1 - Backward
306 : */
307 1 : int direction;
308 : /**
309 : * Length of card data in bytes or bits depending on @a format
310 : */
311 1 : int length;
312 : /**
313 : * Card data of @a length bytes or bits bits depending on @a format
314 : */
315 1 : uint8_t data[OSDP_EVENT_MAX_DATALEN];
316 : };
317 :
318 : /**
319 : * @brief OSDP Event Keypad
320 : */
321 1 : struct osdp_event_keypress {
322 : /**
323 : * Reader number.
324 : * In context of readers attached to current PD, this number indicated this number. This is
325 : * not supported by LibOSDP.
326 : */
327 1 : int reader_no;
328 : /**
329 : * Length of keypress data in bytes
330 : */
331 1 : int length;
332 : /**
333 : * Keypress data of @a length bytes
334 : */
335 1 : uint8_t data[OSDP_EVENT_MAX_DATALEN];
336 : };
337 :
338 : /**
339 : * @brief OSDP PD Events
340 : */
341 1 : enum osdp_event_type {
342 : OSDP_EVENT_CARDREAD, /**< Card read event */
343 : OSDP_EVENT_KEYPRESS, /**< Keypad press event */
344 : OSDP_EVENT_SENTINEL /**< Max event value */
345 : };
346 :
347 : /**
348 : * @brief OSDP Event structure.
349 : */
350 1 : struct osdp_event {
351 : /** @cond INTERNAL_HIDDEN */
352 : sys_snode_t node;
353 : /** @endcond */
354 : /**
355 : * Event type.
356 : * Used to select specific event in union.
357 : */
358 1 : enum osdp_event_type type;
359 : /** Event */
360 : union {
361 1 : struct osdp_event_keypress keypress; /**< Keypress event structure */
362 1 : struct osdp_event_cardread cardread; /**< Card read event structure */
363 1 : };
364 : };
365 :
366 : /**
367 : * @brief Callback for PD command notifications. After it has been registered
368 : * with `osdp_pd_set_command_callback`, this method is invoked when the PD
369 : * receives a command from the CP.
370 : *
371 : * @param arg pointer that will was passed to the arg param of
372 : * `osdp_pd_set_command_callback`.
373 : * @param cmd pointer to the received command.
374 : *
375 : * @retval 0 if LibOSDP must send a `osdp_ACK` response
376 : * @retval -ve if LibOSDP must send a `osdp_NAK` response
377 : * @retval +ve and modify the passed `struct osdp_cmd *cmd` if LibOSDP must send
378 : * a specific response. This is useful for sending manufacturer specific
379 : * reply ``osdp_MFGREP``.
380 : */
381 1 : typedef int (*pd_command_callback_t)(void *arg, struct osdp_cmd *cmd);
382 :
383 : /**
384 : * @brief Callback for CP event notifications. After it has been registered with
385 : * `osdp_cp_set_event_callback`, this method is invoked when the CP receives an
386 : * event from the PD.
387 : *
388 : * @param arg Opaque pointer provided by the application during callback
389 : * registration.
390 : * @param pd the offset (0-indexed) of this PD in kconfig `OSDP_PD_ADDRESS_LIST`
391 : * @param ev pointer to osdp_event struct (filled by libosdp).
392 : *
393 : * @retval 0 on handling the event successfully.
394 : * @retval -ve on errors.
395 : */
396 1 : typedef int (*cp_event_callback_t)(void *arg, int pd, struct osdp_event *ev);
397 :
398 : #if defined(CONFIG_OSDP_MODE_PD) || defined(__DOXYGEN__)
399 :
400 : /**
401 : * @name Peripheral Device mode APIs
402 : * @note These are only available when @kconfig{CONFIG_OSDP_MODE_PD} is enabled.
403 : * @{
404 : */
405 :
406 : /**
407 : * @brief Set callback method for PD command notification. This callback is
408 : * invoked when the PD receives a command from the CP.
409 : *
410 : * @param cb The callback function's pointer
411 : * @param arg A pointer that will be passed as the first argument of `cb`
412 : */
413 1 : void osdp_pd_set_command_callback(pd_command_callback_t cb, void *arg);
414 :
415 : /**
416 : * @brief API to notify PD events to CP. These events are sent to the CP as an
417 : * alternate response to a POLL command.
418 : *
419 : * @param event pointer to event struct. Must be filled by application.
420 : *
421 : * @retval 0 on success
422 : * @retval -1 on failure
423 : */
424 1 : int osdp_pd_notify_event(const struct osdp_event *event);
425 :
426 : /**
427 : * @}
428 : */
429 :
430 : #else /* CONFIG_OSDP_MODE_PD */
431 :
432 : /**
433 : * @brief Generic command enqueue API.
434 : *
435 : * @param pd the offset (0-indexed) of this PD in kconfig `OSDP_PD_ADDRESS_LIST`
436 : * @param cmd command pointer. Must be filled by application.
437 : *
438 : * @retval 0 on success
439 : * @retval -1 on failure
440 : *
441 : * @note This method only adds the command on to a particular PD's command
442 : * queue. The command itself can fail due to various reasons.
443 : */
444 : int osdp_cp_send_command(int pd, struct osdp_cmd *cmd);
445 :
446 :
447 : /**
448 : * @brief Set callback method for CP event notification. This callback is
449 : * invoked when the CP receives an event from the PD.
450 : *
451 : * @param cb The callback function's pointer
452 : * @param arg A pointer that will be passed as the first argument of `cb`
453 : */
454 : void osdp_cp_set_event_callback(cp_event_callback_t cb, void *arg);
455 :
456 : #endif /* CONFIG_OSDP_MODE_PD */
457 :
458 : #if defined(CONFIG_OSDP_SC_ENABLED) || defined(__DOXYGEN__)
459 :
460 : /**
461 : * @name OSDP Secure Channel APIs
462 : * @note These are only available when @kconfig{CONFIG_OSDP_SC_ENABLED} is
463 : * enabled.
464 : * @{
465 : */
466 :
467 : /**
468 : * Get the current SC status mask.
469 : * @return SC status mask
470 : */
471 1 : uint32_t osdp_get_sc_status_mask(void);
472 :
473 : /**
474 : * @}
475 : */
476 :
477 : #endif
478 :
479 : #ifdef __cplusplus
480 : }
481 : #endif
482 :
483 : #endif /* ZEPHYR_INCLUDE_MGMT_OSDP_H_ */
|