#ifndef _LE_USER_H_ #define _LE_USER_H_ #if defined __cplusplus extern "C" { #endif #include "btstack/ble_api.h" typedef void (*btstack_packet_handler_t)(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size); typedef int (*sm_stack_packet_handler_t)(uint8_t packet_type, uint8_t *packet, uint16_t size); typedef void (*ble_cbk_handler_t)(void); // Minimum/default MTU #define ATT_DEFAULT_MTU 23 #define BT_NAME_LEN_MAX 29 #define ADV_RSP_PACKET_MAX 31 // hci con handles (12 bit): 0x0000..0x0fff #define HCI_CON_HANDLE_INVALID 0xffff #define BTSTACK_EVENT_STATE 0x60 #define L2CAP_EVENT_CONNECTION_PARAMETER_UPDATE_RESPONSE 0x77 #define ATT_EVENT_MTU_EXCHANGE_COMPLETE 0xB5 #define ATT_EVENT_HANDLE_VALUE_INDICATION_COMPLETE 0xB6 #define ATT_EVENT_CAN_SEND_NOW 0xB7 #define SM_EVENT_JUST_WORKS_REQUEST 0xD0 #define SM_EVENT_PASSKEY_DISPLAY_NUMBER 0xD2 #define ATT_TRANSACTION_MODE_NONE 0x0 #define ATT_TRANSACTION_MODE_ACTIVE 0x1 #define ATT_TRANSACTION_MODE_EXECUTE 0x2 #define ATT_TRANSACTION_MODE_CANCEL 0x3 #define ATT_TRANSACTION_MODE_VALIDATE 0x4 #define GATT_CLIENT_CHARACTERISTICS_CONFIGURATION_NONE 0 #define GATT_CLIENT_CHARACTERISTICS_CONFIGURATION_NOTIFICATION 1 #define GATT_CLIENT_CHARACTERISTICS_CONFIGURATION_INDICATION 2 #define ATT_PROPERTY_BROADCAST 0x01 #define ATT_PROPERTY_READ 0x02 #define ATT_PROPERTY_WRITE_WITHOUT_RESPONSE 0x04 #define ATT_PROPERTY_WRITE 0x08 #define ATT_PROPERTY_NOTIFY 0x10 #define ATT_PROPERTY_INDICATE 0x20 #define GATT_EVENT_NOTIFICATION 0xA7 #define GATT_EVENT_INDICATION 0xA8 #define GATT_EVENT_CHARACTERISTIC_VALUE_QUERY_RESULT 0xA5 #define GATT_EVENT_LONG_CHARACTERISTIC_VALUE_QUERY_RESULT 0xA6 // #define GATT_EVENT_SERVICE_QUERY_RESULT 0xA1 // #define GATT_EVENT_CHARACTERISTIC_QUERY_RESULT 0xA2 // #define GATT_EVENT_QUERY_COMPLETE 0xA0 #define GAP_EVENT_ADVERTISING_REPORT 0xE2 // Authentication requirement flags #define SM_AUTHREQ_NO_BONDING 0x00 #define SM_AUTHREQ_BONDING 0x01 #define SM_AUTHREQ_MITM_PROTECTION 0x04 #define SM_AUTHREQ_SECURE_CONNECTION 0x08 #define SM_AUTHREQ_KEYPRESS 0x10 #define L2CAP_EVENT_CONNECTION_PARAMETER_UPDATE_RESPONSE 0x77 #define BT_OP_SUCCESS 0x00 #define BT_ERR_ADVERTISING_TIMEOUT 0x3C //-------------------------------------------- enum { HCI_STATE_OFF = 0, HCI_STATE_INITIALIZING, HCI_STATE_WORKING, HCI_STATE_HALTING, HCI_STATE_SLEEPING, HCI_STATE_FALLING_ASLEEP } ; // IO Capability Values typedef enum { IO_CAPABILITY_DISPLAY_ONLY = 0, IO_CAPABILITY_DISPLAY_YES_NO, IO_CAPABILITY_KEYBOARD_ONLY, IO_CAPABILITY_NO_INPUT_NO_OUTPUT, IO_CAPABILITY_KEYBOARD_DISPLAY, // not used by secure simple pairing } io_capability_t; struct ble_server_operation_t { int(*adv_enable)(void *priv, u32 enable); int(*disconnect)(void *priv); int(*get_buffer_vaild)(void *priv); int(*send_data)(void *priv, void *buf, u16 len); int(*regist_wakeup_send)(void *priv, void *cbk); int(*regist_recieve_cbk)(void *priv, void *cbk); int(*regist_state_cbk)(void *priv, void *cbk); int(*latency_enable)(void *priv, u32 enable); }; void ble_get_server_operation_table(struct ble_server_operation_t **interface_pt); struct ble_client_operation_t { int(*scan_enable)(void *priv, u32 enable); int(*disconnect)(void *priv); int(*get_buffer_vaild)(void *priv); int(*write_data)(void *priv, void *buf, u16 len); int(*read_do)(void *priv); int(*regist_wakeup_send)(void *priv, void *cbk); int(*regist_recieve_cbk)(void *priv, void *cbk); int(*regist_state_cbk)(void *priv, void *cbk); }; void ble_get_client_operation_table(struct ble_client_operation_t **interface_pt); typedef struct { //base info uint8_t type; ///< See SM_... uint8_t size; hci_con_handle_t con_handle; uint8_t addr_type; uint8_t address[6]; //extend info uint8_t data[4]; } sm_just_event_t; static inline uint32_t ble_min(uint32_t a, uint32_t b) { return a < b ? a : b; } //--------------------------------------------------------------------------------------------------- // ATT Client Read Callback for Dynamic Data // - if buffer == NULL, don't copy data, just return size of value // - if buffer != NULL, copy data and return number bytes copied // @param con_handle of hci le connection // @param attribute_handle to be read // @param offset defines start of attribute value // @param buffer // @param buffer_size typedef uint16_t (*att_read_callback_t)(uint16_t con_handle, uint16_t attribute_handle, uint16_t offset, uint8_t *buffer, uint16_t buffer_size); // ATT Client Write Callback for Dynamic Data // @param con_handle of hci le connection // @param attribute_handle to be written // @param transaction - ATT_TRANSACTION_MODE_NONE for regular writes, ATT_TRANSACTION_MODE_ACTIVE for prepared writes and ATT_TRANSACTION_MODE_EXECUTE // @param offset into the value - used for queued writes and long attributes // @param buffer // @param buffer_size // @param signature used for signed write commmands // @returns 0 if write was ok, ATT_ERROR_PREPARE_QUEUE_FULL if no space in queue, ATT_ERROR_INVALID_OFFSET if offset is larger than max buffer typedef int (*att_write_callback_t)(uint16_t con_handle, uint16_t attribute_handle, uint16_t transaction_mode, uint16_t offset, uint8_t *buffer, uint16_t buffer_size); //---------------------------------------- extern uint16_t little_endian_read_16(const uint8_t *buffer, int pos); extern uint32_t little_endian_read_24(const uint8_t *buffer, int pos); extern uint32_t little_endian_read_32(const uint8_t *buffer, int pos); //---------------------------------------- //-------------------------------------- static inline hci_con_handle_t hci_subevent_le_connection_update_complete_get_connection_handle(const uint8_t *event) { return little_endian_read_16(event, 4); } static inline uint16_t hci_subevent_le_connection_update_complete_get_conn_interval(const uint8_t *event) { return little_endian_read_16(event, 6); } static inline uint16_t hci_subevent_le_connection_update_complete_get_conn_latency(const uint8_t *event) { return little_endian_read_16(event, 8); } static inline uint16_t hci_subevent_le_connection_update_complete_get_supervision_timeout(const uint8_t *event) { return little_endian_read_16(event, 10); } static inline uint8_t hci_event_packet_get_type(const uint8_t *event) { return event[0]; } static inline uint8_t hci_event_le_meta_get_subevent_code(const uint8_t *event) { return event[2]; } static inline uint16_t att_event_mtu_exchange_complete_get_MTU(const uint8_t *event) { return little_endian_read_16(event, 4); } static inline uint8_t btstack_event_state_get_state(const uint8_t *event) { return event[2]; } static inline uint16_t hci_event_disconnection_complete_get_connection_handle(const uint8_t *event) { return little_endian_read_16(event, 3); } static inline hci_con_handle_t hci_subevent_le_connection_complete_get_connection_handle(const uint8_t *event) { return little_endian_read_16(event, 4); } static inline uint16_t hci_subevent_le_connection_complete_get_conn_interval(const uint8_t *event) { return little_endian_read_16(event, 14); } static inline hci_con_handle_t att_event_mtu_exchange_complete_get_handle(const uint8_t *event) { return little_endian_read_16(event, 2); } static inline hci_con_handle_t sm_event_just_works_request_get_handle(const uint8_t *event) { return little_endian_read_16(event, 2); } extern void ble_sm_setup_init(io_capability_t io_type, u8 auth_req, uint8_t min_key_size, u8 security_en); extern void sm_just_works_confirm(hci_con_handle_t con_handle); extern void sm_init(void); extern void sm_set_io_capabilities(io_capability_t io_capability); extern void sm_set_authentication_requirements(uint8_t auth_req); extern void sm_set_encryption_key_size_range(uint8_t min_size, uint8_t max_size); extern void sm_set_request_security(int enable); extern void sm_event_callback_set(void(*cbk_sm_ph)(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size)); extern void att_server_init(uint8_t const *db, att_read_callback_t read_callback, att_write_callback_t write_callback); extern void att_server_register_packet_handler(btstack_packet_handler_t handler); extern void hci_event_callback_set(void(*cbk_ph)(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size)); extern void ll_hci_connection_updata(u8 *data); #endif