/* * Copyright (c) 2020 Siddharth Chandrasekaran * * SPDX-License-Identifier: Apache-2.0 */ /** * @file * @brief Open Supervised Device Protocol (OSDP) public API header file. */ #ifndef _OSDP_H_ #define _OSDP_H_ #include #include #include #ifdef __cplusplus extern "C" { #endif #define OSDP_CMD_TEXT_MAX_LEN 32 /**< Max length of text for text command */ #define OSDP_CMD_KEYSET_KEY_MAX_LEN 32 /**< Max length of key data for keyset command */ #define OSDP_EVENT_MAX_DATALEN 64 /**< Max length of event data */ /** * @brief Command sent from CP to Control digital output of PD. */ struct osdp_cmd_output { /** * Output number. * * 0 = First Output, 1 = Second Output, etc. */ uint8_t output_no; /** * Control code. * * - 0 - NOP – do not alter this output * - 1 - set the permanent state to OFF, abort timed operation (if any) * - 2 - set the permanent state to ON, abort timed operation (if any) * - 3 - set the permanent state to OFF, allow timed operation to complete * - 4 - set the permanent state to ON, allow timed operation to complete * - 5 - set the temporary state to ON, resume perm state on timeout * - 6 - set the temporary state to OFF, resume permanent state on timeout */ uint8_t control_code; /** * Time in units of 100 ms */ uint16_t timer_count; }; /** * @brief LED Colors as specified in OSDP for the on_color/off_color parameters. */ enum osdp_led_color_e { OSDP_LED_COLOR_NONE, /**< No color */ OSDP_LED_COLOR_RED, /**< Red */ OSDP_LED_COLOR_GREEN, /**< Green */ OSDP_LED_COLOR_AMBER, /**< Amber */ OSDP_LED_COLOR_BLUE, /**< Blue */ OSDP_LED_COLOR_SENTINEL /**< Max value */ }; /** * @brief LED params sub-structure. Part of LED command. See @ref osdp_cmd_led. */ struct osdp_cmd_led_params { /** Control code. * * Temporary Control Code: * - 0 - NOP - do not alter this LED's temporary settings. * - 1 - Cancel any temporary operation and display this LED's permanent state immediately. * - 2 - Set the temporary state as given and start timer immediately. * * Permanent Control Code: * - 0 - NOP - do not alter this LED's permanent settings. * - 1 - Set the permanent state as given. */ uint8_t control_code; /** * The ON duration of the flash, in units of 100 ms. */ uint8_t on_count; /** * The OFF duration of the flash, in units of 100 ms. */ uint8_t off_count; /** * Color to set during the ON timer (see @ref osdp_led_color_e). */ uint8_t on_color; /** * Color to set during the OFF timer (see @ref osdp_led_color_e). */ uint8_t off_color; /** * Time in units of 100 ms (only for temporary mode). */ uint16_t timer_count; }; /** * @brief Sent from CP to PD to control the behaviour of it's on-board LEDs */ struct osdp_cmd_led { /** * Reader number. 0 = First Reader, 1 = Second Reader, etc. */ uint8_t reader; /** * LED number. 0 = first LED, 1 = second LED, etc. */ uint8_t led_number; /** * Ephemeral LED status descriptor. */ struct osdp_cmd_led_params temporary; /** * Permanent LED status descriptor. */ struct osdp_cmd_led_params permanent; }; /** * @brief Sent from CP to control the behaviour of a buzzer in the PD. */ struct osdp_cmd_buzzer { /** * Reader number. 0 = First Reader, 1 = Second Reader, etc. */ uint8_t reader; /** * Control code. * - 0 - no tone * - 1 - off * - 2 - default tone * - 3+ - TBD */ uint8_t control_code; /** * The ON duration of the sound, in units of 100 ms. */ uint8_t on_count; /** * The OFF duration of the sound, in units of 100 ms. */ uint8_t off_count; /** * The number of times to repeat the ON/OFF cycle; 0: forever. */ uint8_t rep_count; }; /** * @brief Command to manipulate any display units that the PD supports. */ struct osdp_cmd_text { /** * Reader number. 0 = First Reader, 1 = Second Reader, etc. */ uint8_t reader; /** * Control code. * - 1 - permanent text, no wrap * - 2 - permanent text, with wrap * - 3 - temp text, no wrap * - 4 - temp text, with wrap */ uint8_t control_code; /** * Duration to display temporary text, in seconds */ uint8_t temp_time; /** * Row to display the first character (1-indexed) */ uint8_t offset_row; /** * Column to display the first character (1-indexed) */ uint8_t offset_col; /** * Number of characters in the string */ uint8_t length; /** * The string to display */ uint8_t data[OSDP_CMD_TEXT_MAX_LEN]; }; /** * @brief Sent in response to a COMSET command. Set communication parameters to * PD. Must be stored in PD non-volatile memory. */ struct osdp_cmd_comset { /** * Unit ID to which this PD will respond after the change takes effect. */ uint8_t address; /** * Baud rate. * * Valid values: 9600, 19200, 38400, 115200, 230400. */ uint32_t baud_rate; }; /** * @brief This command transfers an encryption key from the CP to a PD. * * @param type Type of keys: * - 0x01 – Secure Channel Base Key * @param length Number of bytes of key data - (Key Length in bits + 7) / 8 * @param data Key data */ struct osdp_cmd_keyset { /** * Type of keys: * - 0x01 – Secure Channel Base Key */ uint8_t type; /** * Number of bytes of key data - (Key Length in bits + 7) / 8 */ uint8_t length; /** * Key data */ uint8_t data[OSDP_CMD_KEYSET_KEY_MAX_LEN]; }; /** * @brief OSDP application exposed commands */ enum osdp_cmd_e { OSDP_CMD_OUTPUT = 1, /**< Output control command */ OSDP_CMD_LED, /**< Reader LED control command */ OSDP_CMD_BUZZER, /**< Reader buzzer control command */ OSDP_CMD_TEXT, /**< Reader text output command */ OSDP_CMD_KEYSET, /**< Encryption Key Set Command */ OSDP_CMD_COMSET, /**< PD Communication Configuration Command */ OSDP_CMD_SENTINEL /**< Max command value */ }; /** * @brief OSDP Command Structure. This is a wrapper for all individual OSDP * commands. */ struct osdp_cmd { /** @cond INTERNAL_HIDDEN */ sys_snode_t node; /** @endcond */ /** * Command ID. * Used to select specific commands in union. */ enum osdp_cmd_e id; /** Command */ union { struct osdp_cmd_led led; /**< LED command structure */ struct osdp_cmd_buzzer buzzer; /**< Buzzer command structure */ struct osdp_cmd_text text; /**< Text command structure */ struct osdp_cmd_output output; /**< Output command structure */ struct osdp_cmd_comset comset; /**< Comset command structure */ struct osdp_cmd_keyset keyset; /**< Keyset command structure */ }; }; /** * @brief Various card formats that a PD can support. This is sent to CP * when a PD must report a card read. */ enum osdp_event_cardread_format_e { OSDP_CARD_FMT_RAW_UNSPECIFIED, /**< Unspecified card format */ OSDP_CARD_FMT_RAW_WIEGAND, /**< Wiegand card format */ OSDP_CARD_FMT_ASCII, /**< ASCII card format */ OSDP_CARD_FMT_SENTINEL /**< Max card format value */ }; /** * @brief OSDP event cardread * * @note When @a format is set to OSDP_CARD_FMT_RAW_UNSPECIFIED or * OSDP_CARD_FMT_RAW_WIEGAND, the length is expressed in bits. OTOH, when it is * set to OSDP_CARD_FMT_ASCII, the length is in bytes. The number of bytes to * read from the @a data field must be interpreted accordingly. */ struct osdp_event_cardread { /** * Reader number. 0 = First Reader, 1 = Second Reader, etc. */ int reader_no; /** * Format of the card being read. */ enum osdp_event_cardread_format_e format; /** * Direction of data in @a data array. * - 0 - Forward * - 1 - Backward */ int direction; /** * Length of card data in bytes or bits depending on @a format */ int length; /** * Card data of @a length bytes or bits bits depending on @a format */ uint8_t data[OSDP_EVENT_MAX_DATALEN]; }; /** * @brief OSDP Event Keypad */ struct osdp_event_keypress { /** * Reader number. * In context of readers attached to current PD, this number indicated this number. This is * not supported by LibOSDP. */ int reader_no; /** * Length of keypress data in bytes */ int length; /** * Keypress data of @a length bytes */ uint8_t data[OSDP_EVENT_MAX_DATALEN]; }; /** * @brief OSDP PD Events */ enum osdp_event_type { OSDP_EVENT_CARDREAD, /**< Card read event */ OSDP_EVENT_KEYPRESS, /**< Keypad press event */ OSDP_EVENT_SENTINEL /**< Max event value */ }; /** * @brief OSDP Event structure. */ struct osdp_event { /** @cond INTERNAL_HIDDEN */ sys_snode_t node; /** @endcond */ /** * Event type. * Used to select specific event in union. */ enum osdp_event_type type; /** Event */ union { struct osdp_event_keypress keypress; /**< Keypress event structure */ struct osdp_event_cardread cardread; /**< Card read event structure */ }; }; /** * @brief Callback for PD command notifications. After it has been registered * with `osdp_pd_set_command_callback`, this method is invoked when the PD * receives a command from the CP. * * @param arg pointer that will was passed to the arg param of * `osdp_pd_set_command_callback`. * @param cmd pointer to the received command. * * @retval 0 if LibOSDP must send a `osdp_ACK` response * @retval -ve if LibOSDP must send a `osdp_NAK` response * @retval +ve and modify the passed `struct osdp_cmd *cmd` if LibOSDP must send * a specific response. This is useful for sending manufacturer specific * reply ``osdp_MFGREP``. */ typedef int (*pd_command_callback_t)(void *arg, struct osdp_cmd *cmd); /** * @brief Callback for CP event notifications. After it has been registered with * `osdp_cp_set_event_callback`, this method is invoked when the CP receives an * event from the PD. * * @param arg Opaque pointer provided by the application during callback * registration. * @param pd the offset (0-indexed) of this PD in kconfig `OSDP_PD_ADDRESS_LIST` * @param ev pointer to osdp_event struct (filled by libosdp). * * @retval 0 on handling the event successfully. * @retval -ve on errors. */ typedef int (*cp_event_callback_t)(void *arg, int pd, struct osdp_event *ev); #if defined(CONFIG_OSDP_MODE_PD) || defined(__DOXYGEN__) /** * @name Peripheral Device mode APIs * @note These are only available when @kconfig{CONFIG_OSDP_MODE_PD} is enabled. * @{ */ /** * @brief Set callback method for PD command notification. This callback is * invoked when the PD receives a command from the CP. * * @param cb The callback function's pointer * @param arg A pointer that will be passed as the first argument of `cb` */ void osdp_pd_set_command_callback(pd_command_callback_t cb, void *arg); /** * @brief API to notify PD events to CP. These events are sent to the CP as an * alternate response to a POLL command. * * @param event pointer to event struct. Must be filled by application. * * @retval 0 on success * @retval -1 on failure */ int osdp_pd_notify_event(const struct osdp_event *event); /** * @} */ #else /* CONFIG_OSDP_MODE_PD */ /** * @brief Generic command enqueue API. * * @param pd the offset (0-indexed) of this PD in kconfig `OSDP_PD_ADDRESS_LIST` * @param cmd command pointer. Must be filled by application. * * @retval 0 on success * @retval -1 on failure * * @note This method only adds the command on to a particular PD's command * queue. The command itself can fail due to various reasons. */ int osdp_cp_send_command(int pd, struct osdp_cmd *cmd); /** * @brief Set callback method for CP event notification. This callback is * invoked when the CP receives an event from the PD. * * @param cb The callback function's pointer * @param arg A pointer that will be passed as the first argument of `cb` */ void osdp_cp_set_event_callback(cp_event_callback_t cb, void *arg); #endif /* CONFIG_OSDP_MODE_PD */ #if defined(CONFIG_OSDP_SC_ENABLED) || defined(__DOXYGEN__) /** * @name OSDP Secure Channel APIs * @note These are only available when @kconfig{CONFIG_OSDP_SC_ENABLED} is * enabled. * @{ */ /** * Get the current SC status mask. * @return SC status mask */ uint32_t osdp_get_sc_status_mask(void); /** * @} */ #endif #ifdef __cplusplus } #endif #endif /* _OSDP_H_ */