1 /*
2  * Copyright (c) 2020 Siddharth Chandrasekaran <siddharth@embedjournal.com>
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #ifndef _OSDP_H_
8 #define _OSDP_H_
9 
10 #include <zephyr.h>
11 #include <stdint.h>
12 
13 #include <sys/slist.h>
14 
15 #ifdef __cplusplus
16 extern "C" {
17 #endif
18 
19 #define OSDP_CMD_TEXT_MAX_LEN          32
20 #define OSDP_CMD_KEYSET_KEY_MAX_LEN    32
21 
22 /**
23  * @brief Various card formats that a PD can support. This is sent to CP
24  * when a PD must report a card read.
25  */
26 enum osdp_card_formats_e {
27 	OSDP_CARD_FMT_RAW_UNSPECIFIED,
28 	OSDP_CARD_FMT_RAW_WIEGAND,
29 	OSDP_CARD_FMT_ASCII,
30 	OSDP_CARD_FMT_SENTINEL
31 };
32 
33 /**
34  * @brief Command sent from CP to Control digital output of PD.
35  *
36  * @param output_no 0 = First Output, 1 = Second Output, etc.
37  * @param control_code One of the following:
38  *   0 - NOP – do not alter this output
39  *   1 - set the permanent state to OFF, abort timed operation (if any)
40  *   2 - set the permanent state to ON, abort timed operation (if any)
41  *   3 - set the permanent state to OFF, allow timed operation to complete
42  *   4 - set the permanent state to ON, allow timed operation to complete
43  *   5 - set the temporary state to ON, resume perm state on timeout
44  *   6 - set the temporary state to OFF, resume permanent state on timeout
45  * @param timer_count Time in units of 100 ms
46  */
47 struct osdp_cmd_output {
48 	uint8_t output_no;
49 	uint8_t control_code;
50 	uint16_t timer_count;
51 };
52 
53 /**
54  * @brief LED Colors as specified in OSDP for the on_color/off_color parameters.
55  */
56 enum osdp_led_color_e {
57 	OSDP_LED_COLOR_NONE,
58 	OSDP_LED_COLOR_RED,
59 	OSDP_LED_COLOR_GREEN,
60 	OSDP_LED_COLOR_AMBER,
61 	OSDP_LED_COLOR_BLUE,
62 	OSDP_LED_COLOR_SENTINEL
63 };
64 
65 /**
66  * @brief LED params sub-structure. Part of LED command. See struct osdp_cmd_led
67  *
68  * @param control_code One of the following:
69  * Temporary Control Code:
70  *   0 - NOP - do not alter this LED's temporary settings
71  *   1 - Cancel any temporary operation and display this LED's permanent state
72  *       immediately
73  *   2 - Set the temporary state as given and start timer immediately
74  * Permanent Control Code:
75  *   0 - NOP - do not alter this LED's permanent settings
76  *   1 - Set the permanent state as given
77  * @param on_count The ON duration of the flash, in units of 100 ms
78  * @param off_count The OFF duration of the flash, in units of 100 ms
79  * @param on_color Color to set during the ON timer (enum osdp_led_color_e)
80  * @param off_color Color to set during the OFF timer (enum osdp_led_color_e)
81  * @param timer_count Time in units of 100 ms (only for temporary mode)
82  */
83 struct osdp_cmd_led_params {
84 	uint8_t control_code;
85 	uint8_t on_count;
86 	uint8_t off_count;
87 	uint8_t on_color;
88 	uint8_t off_color;
89 	uint16_t timer_count;
90 };
91 
92 /**
93  * @brief Sent from CP to PD to control the behaviour of it's on-board LEDs
94  *
95  * @param reader 0 = First Reader, 1 = Second Reader, etc.
96  * @param led_number 0 = first LED, 1 = second LED, etc.
97  * @param temporary ephemeral LED status descriptor
98  * @param permanent permanent LED status descriptor
99  */
100 struct osdp_cmd_led {
101 	uint8_t reader;
102 	uint8_t led_number;
103 	struct osdp_cmd_led_params temporary;
104 	struct osdp_cmd_led_params permanent;
105 };
106 
107 /**
108  * @brief Sent from CP to control the behaviour of a buzzer in the PD.
109  *
110  * @param reader 0 = First Reader, 1 = Second Reader, etc.
111  * @param control_code 0: no tone, 1: off, 2: default tone, 3+ is TBD.
112  * @param on_count The ON duration of the flash, in units of 100 ms
113  * @param off_count The OFF duration of the flash, in units of 100 ms
114  * @param rep_count The number of times to repeat the ON/OFF cycle; 0: forever
115  */
116 struct osdp_cmd_buzzer {
117 	uint8_t reader;
118 	uint8_t control_code;
119 	uint8_t on_count;
120 	uint8_t off_count;
121 	uint8_t rep_count;
122 };
123 
124 /**
125  * @brief Command to manuplate any display units that the PD supports.
126  *
127  * @param reader 0 = First Reader, 1 = Second Reader, etc.
128  * @param control_code One of the following:
129  *   1 - permanent text, no wrap
130  *   2 - permanent text, with wrap
131  *   3 - temp text, no wrap
132  *   4 - temp text, with wrap
133  * @param temp_time duration to display temporary text, in seconds
134  * @param offset_row row to display the first character (1 indexed)
135  * @param offset_col column to display the first character (1 indexed)
136  * @param length Number of characters in the string
137  * @param data The string to display
138  */
139 struct osdp_cmd_text {
140 	uint8_t reader;
141 	uint8_t control_code;
142 	uint8_t temp_time;
143 	uint8_t offset_row;
144 	uint8_t offset_col;
145 	uint8_t length;
146 	uint8_t data[OSDP_CMD_TEXT_MAX_LEN];
147 };
148 
149 /**
150  * @brief Sent in response to a COMSET command. Set communication parameters to
151  * PD. Must be stored in PD non-volatile memory.
152  *
153  * @param address Unit ID to which this PD will respond after the change takes
154  *             effect.
155  * @param baud_rate baud rate value 9600/38400/115200
156  */
157 struct osdp_cmd_comset {
158 	uint8_t address;
159 	uint32_t baud_rate;
160 };
161 
162 /**
163  * @brief This command transfers an encryption key from the CP to a PD.
164  *
165  * @param type Type of keys:
166  *   - 0x01 – Secure Channel Base Key
167  * @param length Number of bytes of key data - (Key Length in bits + 7) / 8
168  * @param data Key data
169  */
170 struct osdp_cmd_keyset {
171 	uint8_t type;
172 	uint8_t length;
173 	uint8_t data[OSDP_CMD_KEYSET_KEY_MAX_LEN];
174 };
175 
176 /**
177  * @brief OSDP application exposed commands
178  */
179 enum osdp_cmd_e {
180 	OSDP_CMD_OUTPUT = 1,
181 	OSDP_CMD_LED,
182 	OSDP_CMD_BUZZER,
183 	OSDP_CMD_TEXT,
184 	OSDP_CMD_KEYSET,
185 	OSDP_CMD_COMSET,
186 	OSDP_CMD_SENTINEL
187 };
188 
189 /**
190  * @brief OSDP Command Structure. This is a wrapper for all individual OSDP
191  * commands.
192  *
193  * @param id used to select specific commands in union. Type: enum osdp_cmd_e
194  * @param led LED command structure
195  * @param buzzer buzzer command structure
196  * @param text text command structure
197  * @param output output command structure
198  * @param comset comset command structure
199  * @param keyset keyset command structure
200  */
201 struct osdp_cmd {
202 	sys_snode_t node;
203 	enum osdp_cmd_e id;
204 	union {
205 		struct osdp_cmd_led    led;
206 		struct osdp_cmd_buzzer buzzer;
207 		struct osdp_cmd_text   text;
208 		struct osdp_cmd_output output;
209 		struct osdp_cmd_comset comset;
210 		struct osdp_cmd_keyset keyset;
211 	};
212 };
213 
214 #ifdef CONFIG_OSDP_MODE_PD
215 
216 /**
217  * @param cmd pointer to a command structure that was received by the driver.
218  *
219  * @retval 0 on success.
220  * @retval -1 on failure.
221  */
222 int osdp_pd_get_cmd(struct osdp_cmd *cmd);
223 
224 #else /* CONFIG_OSDP_MODE_PD */
225 
226 int osdp_cp_set_callback_key_press(
227 	int (*cb)(int address, uint8_t key));
228 int osdp_cp_set_callback_card_read(
229 	int (*cb)(int address, int format, uint8_t *data, int len));
230 int osdp_cp_send_command(int pd, struct osdp_cmd *cmd);
231 
232 #endif /* CONFIG_OSDP_MODE_PD */
233 
234 #ifdef CONFIG_OSDP_SC_ENABLED
235 
236 uint32_t osdp_get_sc_status_mask(void);
237 
238 #endif
239 
240 #ifdef __cplusplus
241 }
242 #endif
243 
244 #endif	/* _OSDP_H_ */
245