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/kernel.h> 11 #include <stdint.h> 12 13 #include <zephyr/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 #define OSDP_EVENT_MAX_DATALEN 64 22 23 /** 24 * @brief Command sent from CP to Control digital output of PD. 25 * 26 * @param output_no 0 = First Output, 1 = Second Output, etc. 27 * @param control_code One of the following: 28 * 0 - NOP – do not alter this output 29 * 1 - set the permanent state to OFF, abort timed operation (if any) 30 * 2 - set the permanent state to ON, abort timed operation (if any) 31 * 3 - set the permanent state to OFF, allow timed operation to complete 32 * 4 - set the permanent state to ON, allow timed operation to complete 33 * 5 - set the temporary state to ON, resume perm state on timeout 34 * 6 - set the temporary state to OFF, resume permanent state on timeout 35 * @param timer_count Time in units of 100 ms 36 */ 37 struct osdp_cmd_output { 38 uint8_t output_no; 39 uint8_t control_code; 40 uint16_t timer_count; 41 }; 42 43 /** 44 * @brief LED Colors as specified in OSDP for the on_color/off_color parameters. 45 */ 46 enum osdp_led_color_e { 47 OSDP_LED_COLOR_NONE, 48 OSDP_LED_COLOR_RED, 49 OSDP_LED_COLOR_GREEN, 50 OSDP_LED_COLOR_AMBER, 51 OSDP_LED_COLOR_BLUE, 52 OSDP_LED_COLOR_SENTINEL 53 }; 54 55 /** 56 * @brief LED params sub-structure. Part of LED command. See struct osdp_cmd_led 57 * 58 * @param control_code One of the following: 59 * Temporary Control Code: 60 * 0 - NOP - do not alter this LED's temporary settings 61 * 1 - Cancel any temporary operation and display this LED's permanent state 62 * immediately 63 * 2 - Set the temporary state as given and start timer immediately 64 * Permanent Control Code: 65 * 0 - NOP - do not alter this LED's permanent settings 66 * 1 - Set the permanent state as given 67 * @param on_count The ON duration of the flash, in units of 100 ms 68 * @param off_count The OFF duration of the flash, in units of 100 ms 69 * @param on_color Color to set during the ON timer (enum osdp_led_color_e) 70 * @param off_color Color to set during the OFF timer (enum osdp_led_color_e) 71 * @param timer_count Time in units of 100 ms (only for temporary mode) 72 */ 73 struct osdp_cmd_led_params { 74 uint8_t control_code; 75 uint8_t on_count; 76 uint8_t off_count; 77 uint8_t on_color; 78 uint8_t off_color; 79 uint16_t timer_count; 80 }; 81 82 /** 83 * @brief Sent from CP to PD to control the behaviour of it's on-board LEDs 84 * 85 * @param reader 0 = First Reader, 1 = Second Reader, etc. 86 * @param led_number 0 = first LED, 1 = second LED, etc. 87 * @param temporary ephemeral LED status descriptor 88 * @param permanent permanent LED status descriptor 89 */ 90 struct osdp_cmd_led { 91 uint8_t reader; 92 uint8_t led_number; 93 struct osdp_cmd_led_params temporary; 94 struct osdp_cmd_led_params permanent; 95 }; 96 97 /** 98 * @brief Sent from CP to control the behaviour of a buzzer in the PD. 99 * 100 * @param reader 0 = First Reader, 1 = Second Reader, etc. 101 * @param control_code 0: no tone, 1: off, 2: default tone, 3+ is TBD. 102 * @param on_count The ON duration of the flash, in units of 100 ms 103 * @param off_count The OFF duration of the flash, in units of 100 ms 104 * @param rep_count The number of times to repeat the ON/OFF cycle; 0: forever 105 */ 106 struct osdp_cmd_buzzer { 107 uint8_t reader; 108 uint8_t control_code; 109 uint8_t on_count; 110 uint8_t off_count; 111 uint8_t rep_count; 112 }; 113 114 /** 115 * @brief Command to manipulate any display units that the PD supports. 116 * 117 * @param reader 0 = First Reader, 1 = Second Reader, etc. 118 * @param control_code One of the following: 119 * 1 - permanent text, no wrap 120 * 2 - permanent text, with wrap 121 * 3 - temp text, no wrap 122 * 4 - temp text, with wrap 123 * @param temp_time duration to display temporary text, in seconds 124 * @param offset_row row to display the first character (1 indexed) 125 * @param offset_col column to display the first character (1 indexed) 126 * @param length Number of characters in the string 127 * @param data The string to display 128 */ 129 struct osdp_cmd_text { 130 uint8_t reader; 131 uint8_t control_code; 132 uint8_t temp_time; 133 uint8_t offset_row; 134 uint8_t offset_col; 135 uint8_t length; 136 uint8_t data[OSDP_CMD_TEXT_MAX_LEN]; 137 }; 138 139 /** 140 * @brief Sent in response to a COMSET command. Set communication parameters to 141 * PD. Must be stored in PD non-volatile memory. 142 * 143 * @param address Unit ID to which this PD will respond after the change takes 144 * effect. 145 * @param baud_rate baud rate value 9600/38400/115200 146 */ 147 struct osdp_cmd_comset { 148 uint8_t address; 149 uint32_t baud_rate; 150 }; 151 152 /** 153 * @brief This command transfers an encryption key from the CP to a PD. 154 * 155 * @param type Type of keys: 156 * - 0x01 – Secure Channel Base Key 157 * @param length Number of bytes of key data - (Key Length in bits + 7) / 8 158 * @param data Key data 159 */ 160 struct osdp_cmd_keyset { 161 uint8_t type; 162 uint8_t length; 163 uint8_t data[OSDP_CMD_KEYSET_KEY_MAX_LEN]; 164 }; 165 166 /** 167 * @brief OSDP application exposed commands 168 */ 169 enum osdp_cmd_e { 170 OSDP_CMD_OUTPUT = 1, 171 OSDP_CMD_LED, 172 OSDP_CMD_BUZZER, 173 OSDP_CMD_TEXT, 174 OSDP_CMD_KEYSET, 175 OSDP_CMD_COMSET, 176 OSDP_CMD_SENTINEL 177 }; 178 179 /** 180 * @brief OSDP Command Structure. This is a wrapper for all individual OSDP 181 * commands. 182 * 183 * @param id used to select specific commands in union. Type: enum osdp_cmd_e 184 * @param led LED command structure 185 * @param buzzer buzzer command structure 186 * @param text text command structure 187 * @param output output command structure 188 * @param comset comset command structure 189 * @param keyset keyset command structure 190 */ 191 struct osdp_cmd { 192 sys_snode_t node; 193 enum osdp_cmd_e id; 194 union { 195 struct osdp_cmd_led led; 196 struct osdp_cmd_buzzer buzzer; 197 struct osdp_cmd_text text; 198 struct osdp_cmd_output output; 199 struct osdp_cmd_comset comset; 200 struct osdp_cmd_keyset keyset; 201 }; 202 }; 203 204 /** 205 * @brief Various card formats that a PD can support. This is sent to CP 206 * when a PD must report a card read. 207 */ 208 enum osdp_event_cardread_format_e { 209 OSDP_CARD_FMT_RAW_UNSPECIFIED, 210 OSDP_CARD_FMT_RAW_WIEGAND, 211 OSDP_CARD_FMT_ASCII, 212 OSDP_CARD_FMT_SENTINEL 213 }; 214 215 /** 216 * @brief OSDP event cardread 217 * 218 * @param reader_no In context of readers attached to current PD, this number 219 * indicated this number. This is not supported by LibOSDP. 220 * @param format Format of the card being read. 221 * see `enum osdp_event_cardread_format_e` 222 * @param direction Card read direction of PD 0 - Forward; 1 - Backward 223 * @param length Length of card data in bytes or bits depending on `format` 224 * (see note). 225 * @param data Card data of `length` bytes or bits bits depending on `format` 226 * (see note). 227 * 228 * @note When `format` is set to OSDP_CARD_FMT_RAW_UNSPECIFIED or 229 * OSDP_CARD_FMT_RAW_WIEGAND, the length is expressed in bits. OTOH, when it is 230 * set to OSDP_CARD_FMT_ASCII, the length is in bytes. The number of bytes to 231 * read from the `data` field must be interpreted accordingly. 232 */ 233 struct osdp_event_cardread { 234 int reader_no; 235 enum osdp_event_cardread_format_e format; 236 int direction; 237 int length; 238 uint8_t data[OSDP_EVENT_MAX_DATALEN]; 239 }; 240 241 /** 242 * @brief OSDP Event Keypad 243 * 244 * @param reader_no In context of readers attached to current PD, this number 245 * indicated this number. This is not supported by LibOSDP. 246 * @param length Length of keypress data in bytes 247 * @param data keypress data of `length` bytes 248 */ 249 struct osdp_event_keypress { 250 int reader_no; 251 int length; 252 uint8_t data[OSDP_EVENT_MAX_DATALEN]; 253 }; 254 255 /** 256 * @brief OSDP PD Events 257 */ 258 enum osdp_event_type { 259 OSDP_EVENT_CARDREAD, 260 OSDP_EVENT_KEYPRESS, 261 OSDP_EVENT_SENTINEL 262 }; 263 264 /** 265 * @brief OSDP Event structure. 266 * 267 * @param type used to select specific event in union. See: enum osdp_event_type 268 * @param keypress keypress event structure 269 * @param cardread cardread event structure 270 */ 271 struct osdp_event { 272 sys_snode_t node; 273 enum osdp_event_type type; 274 union { 275 struct osdp_event_keypress keypress; 276 struct osdp_event_cardread cardread; 277 }; 278 }; 279 280 /** 281 * @brief Callback for PD command notifications. After it has been registered 282 * with `osdp_pd_set_command_callback`, this method is invoked when the PD 283 * receives a command from the CP. 284 * 285 * @param arg pointer that will was passed to the arg param of 286 * `osdp_pd_set_command_callback`. 287 * @param cmd pointer to the received command. 288 * 289 * @retval 0 if LibOSDP must send a `osdp_ACK` response 290 * @retval -ve if LibOSDP must send a `osdp_NAK` response 291 * @retval +ve and modify the passed `struct osdp_cmd *cmd` if LibOSDP must send 292 * a specific response. This is useful for sending manufacturer specific 293 * reply ``osdp_MFGREP``. 294 */ 295 typedef int (*pd_command_callback_t)(void *arg, struct osdp_cmd *cmd); 296 297 /** 298 * @brief Callback for CP event notifications. After it has been registered with 299 * `osdp_cp_set_event_callback`, this method is invoked when the CP receives an 300 * event from the PD. 301 * 302 * @param arg Opaque pointer provided by the application during callback 303 * registration. 304 * @param pd the offset (0-indexed) of this PD in kconfig `OSDP_PD_ADDRESS_LIST` 305 * @param ev pointer to osdp_event struct (filled by libosdp). 306 * 307 * @retval 0 on handling the event successfully. 308 * @retval -ve on errors. 309 */ 310 typedef int (*cp_event_callback_t)(void *arg, int pd, struct osdp_event *ev); 311 312 #ifdef CONFIG_OSDP_MODE_PD 313 314 /** 315 * @brief Set callback method for PD command notification. This callback is 316 * invoked when the PD receives a command from the CP. 317 * 318 * @param cb The callback function's pointer 319 * @param arg A pointer that will be passed as the first argument of `cb` 320 */ 321 void osdp_pd_set_command_callback(pd_command_callback_t cb, void *arg); 322 323 /** 324 * @brief API to notify PD events to CP. These events are sent to the CP as an 325 * alternate response to a POLL command. 326 * 327 * @param event pointer to event struct. Must be filled by application. 328 * 329 * @retval 0 on success 330 * @retval -1 on failure 331 */ 332 int osdp_pd_notify_event(const struct osdp_event *event); 333 334 #else /* CONFIG_OSDP_MODE_PD */ 335 336 /** 337 * @brief Generic command enqueue API. 338 * 339 * @param pd the offset (0-indexed) of this PD in kconfig `OSDP_PD_ADDRESS_LIST` 340 * @param cmd command pointer. Must be filled by application. 341 * 342 * @retval 0 on success 343 * @retval -1 on failure 344 * 345 * @note This method only adds the command on to a particular PD's command 346 * queue. The command itself can fail due to various reasons. 347 */ 348 int osdp_cp_send_command(int pd, struct osdp_cmd *cmd); 349 350 351 /** 352 * @brief Set callback method for CP event notification. This callback is 353 * invoked when the CP receives an event from the PD. 354 * 355 * @param cb The callback function's pointer 356 * @param arg A pointer that will be passed as the first argument of `cb` 357 */ 358 void osdp_cp_set_event_callback(cp_event_callback_t cb, void *arg); 359 360 #endif /* CONFIG_OSDP_MODE_PD */ 361 362 #ifdef CONFIG_OSDP_SC_ENABLED 363 364 uint32_t osdp_get_sc_status_mask(void); 365 366 #endif 367 368 #ifdef __cplusplus 369 } 370 #endif 371 372 #endif /* _OSDP_H_ */ 373