/** * UNPUBLISHED PROPRIETARY SOURCE CODE * Copyright (c) 2016 MXCHIP Inc. * * The contents of this file may not be disclosed to third parties, copied or * duplicated in any form, in whole or in part, without the prior written * permission of MXCHIP Corporation. * */ /** @file * * MiCO Generic Attribute (GATT) Application Programming Interface */ #pragma once #include "mico.h" #include "gattdefs.h" #include "mico_bt_dev.h" #include "l2cdefs.h" #include "mico_bt_types.h" /** GATT Status Codes*/ enum mico_bt_gatt_status_e { MICO_BT_GATT_SUCCESS = 0x00, /**< Success */ MICO_BT_GATT_INVALID_HANDLE = 0x01, /**< Invalid Handle */ MICO_BT_GATT_READ_NOT_PERMIT = 0x02, /**< Read Not Permitted */ MICO_BT_GATT_WRITE_NOT_PERMIT = 0x03, /**< Write Not permitted */ MICO_BT_GATT_INVALID_PDU = 0x04, /**< Invalid PDU */ MICO_BT_GATT_INSUF_AUTHENTICATION = 0x05, /**< Insufficient Authentication */ MICO_BT_GATT_REQ_NOT_SUPPORTED = 0x06, /**< Request Not Supported */ MICO_BT_GATT_INVALID_OFFSET = 0x07, /**< Invalid Offset */ MICO_BT_GATT_INSUF_AUTHORIZATION = 0x08, /**< Insufficient Authorization */ MICO_BT_GATT_PREPARE_Q_FULL = 0x09, /**< Prepare Queue Full */ MICO_BT_GATT_NOT_FOUND = 0x0a, /**< Not Found */ MICO_BT_GATT_NOT_LONG = 0x0b, /**< Not Long Size */ MICO_BT_GATT_INSUF_KEY_SIZE = 0x0c, /**< Insufficient Key Size */ MICO_BT_GATT_INVALID_ATTR_LEN = 0x0d, /**< Invalid Attribute Length */ MICO_BT_GATT_ERR_UNLIKELY = 0x0e, /**< Error Unlikely */ MICO_BT_GATT_INSUF_ENCRYPTION = 0x0f, /**< Insufficient Encryption */ MICO_BT_GATT_UNSUPPORT_GRP_TYPE = 0x10, /**< Unsupported Group Type */ MICO_BT_GATT_INSUF_RESOURCE = 0x11, /**< Insufficient Resource */ MICO_BT_GATT_ILLEGAL_PARAMETER = 0x87, /**< Illegal Parameter */ MICO_BT_GATT_NO_RESOURCES = 0x80, /**< No Resources */ MICO_BT_GATT_INTERNAL_ERROR = 0x81, /**< Internal Error */ MICO_BT_GATT_WRONG_STATE = 0x82, /**< Wrong State */ MICO_BT_GATT_DB_FULL = 0x83, /**< DB Full */ MICO_BT_GATT_BUSY = 0x84, /**< Busy */ MICO_BT_GATT_ERROR = 0x85, /**< Error */ MICO_BT_GATT_CMD_STARTED = 0x86, /**< Command Started */ MICO_BT_GATT_PENDING = 0x88, /**< Pending */ MICO_BT_GATT_AUTH_FAIL = 0x89, /**< Authentication Fail */ MICO_BT_GATT_MORE = 0x8a, /**< More */ MICO_BT_GATT_INVALID_CFG = 0x8b, /**< Invalid Configuration */ MICO_BT_GATT_SERVICE_STARTED = 0x8c, /**< Service Started */ MICO_BT_GATT_ENCRYPED_MITM = MICO_BT_GATT_SUCCESS, /**< Encrypted MITM */ MICO_BT_GATT_ENCRYPED_NO_MITM = 0x8d, /**< Encrypted No MITM */ MICO_BT_GATT_NOT_ENCRYPTED = 0x8e, /**< Not Encrypted */ MICO_BT_GATT_CONGESTED = 0x8f, /**< Congested */ /* 0xE0 ~ 0xFC reserved for future use */ MICO_BT_GATT_CCC_CFG_ERR = 0xFD, /**< Improper Client Char Configuration */ MICO_BT_GATT_PRC_IN_PROGRESS = 0xFE, /**< Procedure Already in Progress */ MICO_BT_GATT_OUT_OF_RANGE = 0xFF, /**< Value Out of Range */ }; typedef uint8_t mico_bt_gatt_status_t; /**< GATT status (see #mico_bt_gatt_status_e) */ /** GATT Status Codes*/ enum mico_bt_gatt_app_interface_e { GATT_IF_FIXED_DB_GAP = 0x01, GATT_IF_FIXED_DB_APP = 0x02, GATT_IF_CLIENT = 0x03, }; typedef uint8_t mico_bt_gatt_app_interface_t; /**< GATT status (see #mico_bt_gatt_status_e) */ /** GATT Operation Codes */ #define GATT_RSP_ERROR 0x01 /**< Error Response */ #define GATT_REQ_MTU 0x02 /**< Exchange MTU Request */ #define GATT_RSP_MTU 0x03 /**< Exchange MTU Response */ #define GATT_REQ_FIND_INFO 0x04 /**< Find Information Request */ #define GATT_RSP_FIND_INFO 0x05 /**< Find Information Response */ #define GATT_REQ_FIND_TYPE_VALUE 0x06 /**< Find By Type Value Request */ #define GATT_RSP_FIND_TYPE_VALUE 0x07 /**< Find By Type Value Response */ #define GATT_REQ_READ_BY_TYPE 0x08 /**< Read By Type Request */ #define GATT_RSP_READ_BY_TYPE 0x09 /**< Read By Type Response */ #define GATT_REQ_READ 0x0A /**< Read Request */ #define GATT_RSP_READ 0x0B /**< Read Response */ #define GATT_REQ_READ_BLOB 0x0C /**< Read Blob Request */ #define GATT_RSP_READ_BLOB 0x0D /**< Read Blob Response */ #define GATT_REQ_READ_MULTI 0x0E /**< Read Multiple Request */ #define GATT_RSP_READ_MULTI 0x0F /**< Read Multiple Response */ #define GATT_REQ_READ_BY_GRP_TYPE 0x10 /**< Read By Group Type Request */ #define GATT_RSP_READ_BY_GRP_TYPE 0x11 /**< Read By Group Type Response */ #define GATT_REQ_WRITE 0x12 /**< Write Request */ #define GATT_RSP_WRITE 0x13 /**< Write Request */ #define GATT_CMD_WRITE 0x52 /**< Write Command */ #define GATT_REQ_PREPARE_WRITE 0x16 /**< Prepare Write Request */ #define GATT_RSP_PREPARE_WRITE 0x17 /**< Prepare Write Response */ #define GATT_REQ_EXEC_WRITE 0x18 /**< Execute Write Request */ #define GATT_RSP_EXEC_WRITE 0x19 /**< Execute Write Response */ #define GATT_HANDLE_VALUE_NOTIF 0x1B /**< Handle Value Notification */ #define GATT_HANDLE_VALUE_IND 0x1D /**< Handle Value Indication */ #define GATT_HANDLE_VALUE_CONF 0x1E /**< Handle Value Confirmation */ #define GATT_OP_CODE_MAX (GATT_HANDLE_VALUE_CONF + 1) /**< Maximum opcode value */ #define GATT_SIGN_CMD_WRITE 0xD2 /**< changed in V4.0 1101-0010 (signed write) see write cmd above*/ /** GATT Disconnection reason */ enum mico_bt_gatt_disconn_reason_e { GATT_CONN_UNKNOWN = 0, /**< Unknown reason */ GATT_CONN_L2C_FAILURE = 1, /**< General L2cap failure */ GATT_CONN_TIMEOUT = HCI_ERR_CONNECTION_TOUT, /**< Connection timeout */ GATT_CONN_TERMINATE_PEER_USER = HCI_ERR_PEER_USER, /**< Connection terminated by peer user */ GATT_CONN_TERMINATE_LOCAL_HOST = HCI_ERR_CONN_CAUSE_LOCAL_HOST, /**< Connection terminated by local host */ GATT_CONN_FAIL_ESTABLISH = HCI_ERR_CONN_FAILED_ESTABLISHMENT, /**< Connection fail to establish */ GATT_CONN_LMP_TIMEOUT = HCI_ERR_LMP_RESPONSE_TIMEOUT, /**< Connection fail due to LMP response tout */ GATT_CONN_CANCEL = L2CAP_CONN_CANCEL /**< L2CAP connection cancelled */ }; typedef uint16_t mico_bt_gatt_disconn_reason_t; /**< GATT disconnection reason (see #mico_bt_gatt_disconn_reason_e) */ /* default GATT MTU size over LE link */ #define GATT_DEF_BLE_MTU_SIZE 23 /* invalid connection ID */ #define GATT_INVALID_CONN_ID 0xFFFF /** characteristic descriptor: client configuration value */ enum mico_bt_gatt_client_char_config_e { GATT_CLIENT_CONFIG_NONE = 0x0000, /**< Does not allow both notifications and indications */ GATT_CLIENT_CONFIG_NOTIFICATION = 0x0001, /**< Allows notifications */ GATT_CLIENT_CONFIG_INDICATION = 0x0002 /**< Allows indications */ }; typedef uint16_t mico_bt_gatt_client_char_config_t; /**< GATT client config (see #mico_bt_gatt_client_char_config_e) */ /** characteristic descriptor: server configuration value */ #define GATT_SERVER_CONFIG_NONE 0x0000 /**< No broadcast */ #define GATT_SERVER_CONFIG_BROADCAST 0x0001 /**< Broadcast */ typedef uint16_t mico_bt_gatt_server_char_config_t; /**< GATT server config (see #mico_bt_gatt_server_char_config_e) */ /** GATT Characteristic Properties Mask */ enum mico_bt_gatt_char_properties_e { GATT_CHAR_PROPERTIES_BIT_BROADCAST = (1 << 0), /**< bit 0: Broadcast */ GATT_CHAR_PROPERTIES_BIT_READ = (1 << 1), /**< bit 1: Read */ GATT_CHAR_PROPERTIES_BIT_WRITE_NR = (1 << 2), /**< bit 2: Write (No Response) */ GATT_CHAR_PROPERTIES_BIT_WRITE = (1 << 3), /**< bit 3: Write */ GATT_CHAR_PROPERTIES_BIT_NOTIFY = (1 << 4), /**< bit 4: Notify */ GATT_CHAR_PROPERTIES_BIT_INDICATE = (1 << 5), /**< bit 5: Indicate */ GATT_CHAR_PROPERTIES_BIT_AUTH = (1 << 6), /**< bit 6: Authenticate */ GATT_CHAR_PROPERTIES_BIT_EXT_PROP = (1 << 7) /**< bit 7: Extended Properties */ }; typedef uint8_t mico_bt_gatt_char_properties_t; /**< GATT characteristic properties mask (see #mico_bt_gatt_char_properties_e) */ /************************************************************************* * Macros for parsing results GATT discovery results * (while handling GATT_DISCOVERY_RESULT_EVT) ****************************************************************************/ /* Discovery type: GATT_DISCOVER_SERVICES_ALL or GATT_DISCOVER_SERVICES_BY_UUID */ #define GATT_DISCOVERY_RESULT_SERVICE_START_HANDLE(p_event_data) (p_event_data->discovery_result.discovery_data.group_value.s_handle) #define GATT_DISCOVERY_RESULT_SERVICE_END_HANDLE(p_event_data) (p_event_data->discovery_result.discovery_data.group_value.e_handle) #define GATT_DISCOVERY_RESULT_SERVICE_UUID_LEN(p_event_data) (p_event_data->discovery_result.discovery_data.group_value.service_type.len) #define GATT_DISCOVERY_RESULT_SERVICE_UUID16(p_event_data) (p_event_data->discovery_result.discovery_data.group_value.service_type.uu.uuid16) #define GATT_DISCOVERY_RESULT_SERVICE_UUID32(p_event_data) (p_event_data->discovery_result.discovery_data.group_value.service_type.uu.uuid32) #define GATT_DISCOVERY_RESULT_SERVICE_UUID128(p_event_data) (p_event_data->discovery_result.discovery_data.group_value.service_type.uu.uuid128) /* Discovery type: GATT_DISCOVER_CHARACTERISTIC_DESCRIPTORS */ #define GATT_DISCOVERY_RESULT_CHARACTERISTIC_DESCRIPTOR_UUID_LEN(p_event_data) (p_event_data->discovery_result.discovery_data.char_descr_info.type.len) #define GATT_DISCOVERY_RESULT_CHARACTERISTIC_DESCRIPTOR_UUID16(p_event_data) (p_event_data->discovery_result.discovery_data.char_descr_info.type.uu.uuid16) #define GATT_DISCOVERY_RESULT_CHARACTERISTIC_DESCRIPTOR_UUID32(p_event_data) (p_event_data->discovery_result.discovery_data.char_descr_info.type.uu.uuid32) #define GATT_DISCOVERY_RESULT_CHARACTERISTIC_DESCRIPTOR_UUID128(p_event_data) (p_event_data->discovery_result.discovery_data.char_descr_info.type.uu.uuid128) #define GATT_DISCOVERY_RESULT_CHARACTERISTIC_DESCRIPTOR_VALUE_HANDLE(p_event_data) (p_event_data->discovery_result.discovery_data.char_descr_info.handle) /* Discovery type: GATT_DISCOVER_CHARACTERISTICS */ #define GATT_DISCOVERY_RESULT_CHARACTERISTIC_VALUE_HANDLE(p_event_data) (p_event_data->discovery_result.discovery_data.characteristic_declaration.val_handle) #define GATT_DISCOVERY_RESULT_CHARACTERISTIC_UUID_LEN(p_event_data) (p_event_data->discovery_result.discovery_data.characteristic_declaration.char_uuid.len) #define GATT_DISCOVERY_RESULT_CHARACTERISTIC_UUID16(p_event_data) (p_event_data->discovery_result.discovery_data.characteristic_declaration.char_uuid.uu.uuid16) #define GATT_DISCOVERY_RESULT_CHARACTERISTIC_UUID32(p_event_data) (p_event_data->discovery_result.discovery_data.characteristic_declaration.char_uuid.uu.uuid32) #define GATT_DISCOVERY_RESULT_CHARACTERISTIC_UUID128(p_event_data) (p_event_data->discovery_result.discovery_data.characteristic_declaration.char_uuid.uu.uuid128) /** Authentication requirement */ enum mico_bt_gatt_auth_req_e { GATT_AUTH_REQ_NONE = 0, /**< No Authentication Required */ GATT_AUTH_REQ_NO_MITM = 1, /**< Unauthenticated encryption (No MITM) */ GATT_AUTH_REQ_MITM = 2, /**< Authenticated encryption (MITM) */ GATT_AUTH_REQ_SIGNED_NO_MITM = 3, /**< Signed Data (No MITM) */ GATT_AUTH_REQ_SIGNED_MITM = 4 /**< Signed Data (MITM) */ }; typedef uint8_t mico_bt_gatt_auth_req_t; /**< GATT authentication requirement (see #mico_bt_gatt_auth_req_e)*/ /** Attribute value, used for GATT write operations, and read response callbacks */ typedef struct { uint16_t handle; /**< Attribute handle */ uint16_t offset; /**< Attribute value offset, ignored if not needed for a command */ uint16_t len; /**< Length of attribute value */ mico_bt_gatt_auth_req_t auth_req; /**< Authentication requirement (see @link mico_bt_gatt_auth_req_e mico_bt_gatt_auth_req_t @endlink) */ uint8_t value[1]; /**< The attribute value (actual length is specified by 'len') */ } mico_bt_gatt_value_t; /** GATT Write Execute request flags */ enum mico_bt_gatt_exec_flag_e { GATT_PREP_WRITE_CANCEL = 0x00, /**< GATT_PREP_WRITE_CANCEL */ GATT_PREP_WRITE_EXEC = 0x01 /**< GATT_PREP_WRITE_EXEC */ }; typedef uint8_t mico_bt_gatt_exec_flag_t; /**< GATT execute flag (see #mico_bt_gatt_exec_flag_e) */ /** Attribute read request */ typedef struct { uint16_t handle; /**< Handle of attribute to read */ uint16_t offset; /**< Offset to read */ mico_bool_t is_long; /**< TRUE if long read */ uint16_t *p_val_len; /**< input and output parameter for value length */ uint8_t *p_val; /**< Value pointer */ } mico_bt_gatt_read_t; /** Attribute write request */ typedef struct { uint16_t handle; /**< Handle of attribute to read */ mico_bool_t is_prep; /**< TRUE if this is a prepare write request */ uint16_t offset; /**< Offset to write */ uint16_t val_len; /**< Value length */ uint8_t *p_val; /**< Value pointer */ } mico_bt_gatt_write_t; /** Attribute information for GATT attribute requests */ typedef union { mico_bt_gatt_read_t read_req; /**< Parameters for GATTS_REQ_TYPE_READ */ mico_bt_gatt_write_t write_req; /**< Parameters for GATTS_REQ_TYPE_WRITE */ uint16_t handle; /**< Parameters for GATTS_REQ_TYPE_CONF */ uint16_t mtu; /**< Parameters for GATTS_REQ_TYPE_MTU */ mico_bt_gatt_exec_flag_t exec_write; /**< Parameters for GATTS_REQ_TYPE_WRITE_EXEC */ } mico_bt_gatt_request_data_t; /** GATT Attribute Request Type */ enum mico_bt_gatt_request_type_e { GATTS_REQ_TYPE_READ = 1, /**< Attribute read notification (attribute value internally read from GATT database) */ GATTS_REQ_TYPE_WRITE, /**< Attribute write notification (attribute value internally written to GATT database) */ GATTS_REQ_TYPE_PREP_WRITE, /**< Attribute Prepare Write Notification (Suspending write request before triggering actual execute write ) */ GATTS_REQ_TYPE_WRITE_EXEC, /**< Execute write request */ GATTS_REQ_TYPE_MTU, /**< MTU exchange information */ GATTS_REQ_TYPE_CONF, /**< Value confirmation */ }; typedef uint8_t mico_bt_gatt_request_type_t; /**< GATT Attribute Request Type (see #mico_bt_gatt_request_type_e) */ /** Discovery types */ enum mico_bt_gatt_discovery_type_e { GATT_DISCOVER_SERVICES_ALL = 1, /**< discover all services */ GATT_DISCOVER_SERVICES_BY_UUID, /**< discover service by UUID */ GATT_DISCOVER_INCLUDED_SERVICES, /**< discover an included service within a service */ GATT_DISCOVER_CHARACTERISTICS, /**< discover characteristics of a service with/without type requirement */ GATT_DISCOVER_CHARACTERISTIC_DESCRIPTORS, /**< discover characteristic descriptors of a character */ GATT_DISCOVER_MAX /* maximum discovery types */ }; typedef uint8_t mico_bt_gatt_discovery_type_t; /**< GATT Discovery type (see #mico_bt_gatt_discovery_type_e) */ /** Parameters used in a GATT Discovery */ typedef struct { mico_bt_uuid_t uuid; /**< Service or Characteristic UUID */ uint16_t s_handle; /**< Start handle for range to search */ uint16_t e_handle; /**< End handle for range to search */ }mico_bt_gatt_discovery_param_t; /** GATT Read Types */ enum mico_bt_gatt_read_type_e { GATT_READ_BY_TYPE = 1, /**< Read by Type (service or characteristic UUIDs) */ GATT_READ_BY_HANDLE, /**< Read by Handle */ GATT_READ_MULTIPLE, /**< Read Multiple (array of handles) */ GATT_READ_CHAR_VALUE, /**< Read Characteristic Value */ GATT_READ_PARTIAL, /**< Read Partial */ GATT_READ_MAX }; typedef uint8_t mico_bt_gatt_read_type_t; /**< GATT read type (see #mico_bt_gatt_read_type_e) */ /** Parameters for GATT_READ_BY_TYPE and GATT_READ_CHAR_VALUE */ typedef struct { mico_bt_gatt_auth_req_t auth_req; /**< Authentication requirement (see @link mico_bt_gatt_auth_req_e mico_bt_gatt_auth_req_t @endlink) */ uint16_t s_handle; /**< Starting handle */ uint16_t e_handle; /**< Ending handle */ mico_bt_uuid_t uuid; /**< uuid */ } mico_bt_gatt_read_by_type_t; #define GATT_MAX_READ_MULTI_HANDLES 10 /**< Max attributes allowed in one GATT_READ_MULTIPLE request */ /** Parameters for GATT_READ_MULTIPLE */ typedef struct { mico_bt_gatt_auth_req_t auth_req; /**< authentication requirement (see @link mico_bt_gatt_auth_req_e mico_bt_gatt_auth_req_t @endlink) */ uint16_t num_handles; /**< number of handles to read */ uint16_t handles[GATT_MAX_READ_MULTI_HANDLES]; /**< handles list to be read */ } mico_bt_gatt_read_multi_t; /** Parameters for GATT_READ_BY_HANDLE */ typedef struct { mico_bt_gatt_auth_req_t auth_req; /**< authentication requirement (see @link mico_bt_gatt_auth_req_e mico_bt_gatt_auth_req_t @endlink) */ uint16_t handle; /**< handle */ } mico_bt_gatt_read_by_handle_t; /** Parameters for GATT_READ_PARTIAL */ typedef struct { mico_bt_gatt_auth_req_t auth_req; /**< authentication requirement (see @link mico_bt_gatt_auth_req_e mico_bt_gatt_auth_req_t @endlink) */ uint16_t handle; /**< handle */ uint16_t offset; /**< offset */ } mico_bt_gatt_read_partial_t; /** Read request parameters - used when calling #mico_bt_gatt_send_read */ typedef union { mico_bt_gatt_read_by_type_t service; /**< Parameters for GATT_READ_BY_TYPE */ mico_bt_gatt_read_by_type_t char_type; /**< Parameters for GATT_READ_CHAR_VALUE */ mico_bt_gatt_read_multi_t read_multiple; /**< Parameters for GATT_READ_MULTIPLE */ mico_bt_gatt_read_by_handle_t by_handle; /**< Parameters for GATT_READ_BY_HANDLE */ mico_bt_gatt_read_partial_t partial; /**< Parameters for GATT_READ_PARTIAL */ } mico_bt_gatt_read_param_t; /** Write request types - used when calling #mico_bt_gatt_send_write */ enum mico_bt_gatt_write_type_e { GATT_WRITE_NO_RSP = 1, /**< Write without response */ GATT_WRITE, /**< Write with response */ GATT_WRITE_PREPARE /**< Prepare to write (call #mico_bt_gatt_send_execute_write to execute the write) */ }; typedef uint8_t mico_bt_gatt_write_type_t; /**< GATT write type (see #mico_bt_gatt_write_type_e) */ /** Response data for read operations */ typedef struct { uint16_t handle; /**< handle */ uint16_t len; /**< length of response data */ uint16_t offset; /**< offset */ uint8_t *p_data; /**< attribute data */ } mico_bt_gatt_data_t; /** Client Operation Complete response data (dependent on operation completed) */ typedef union { mico_bt_gatt_data_t att_value; /**< Response data for read operations (initiated using #mico_bt_gatt_send_read) */ uint16_t mtu; /**< Response data for configuration operations */ uint16_t handle; /**< Response data for write operations (initiated using #mico_bt_gatt_send_write) */ } mico_bt_gatt_operation_complete_rsp_t; /**< GATT operation complete response type */ /** GATT client operation type, used in client callback function */ enum mico_bt_gatt_optype_e { GATTC_OPTYPE_NONE = 0, /**< None */ GATTC_OPTYPE_DISCOVERY = 1, /**< Discovery */ GATTC_OPTYPE_READ = 2, /**< Read */ GATTC_OPTYPE_WRITE = 3, /**< Write */ GATTC_OPTYPE_EXE_WRITE = 4, /**< Execute Write */ GATTC_OPTYPE_CONFIG = 5, /**< Configure */ GATTC_OPTYPE_NOTIFICATION = 6, /**< Notification */ GATTC_OPTYPE_INDICATION = 7 /**< Indication */ }; /* GATT Client Operation Codes */ typedef uint8_t mico_bt_gatt_optype_t; /**< GATT operation type (see #mico_bt_gatt_optype_e) */ /** characteristic declaration */ typedef struct { mico_bt_gatt_char_properties_t characteristic_properties; /**< characteristic properties (see @link mico_bt_gatt_char_properties_e mico_bt_gatt_char_properties_t @endlink) */ uint16_t val_handle; /**< characteristic value attribute handle */ uint16_t handle; /**< characteristic declaration handle */ mico_bt_uuid_t char_uuid; /**< characteristic UUID type */ } mico_bt_gatt_char_declaration_t; /** GATT group value */ typedef struct { mico_bt_uuid_t service_type; /**< group type */ uint16_t s_handle; /**< starting handle of the group */ uint16_t e_handle; /**< ending handle of the group */ } mico_bt_gatt_group_value_t; /** included service attribute value */ typedef struct { mico_bt_uuid_t service_type; /**< included service UUID */ uint16_t handle; /**< included service handle */ uint16_t s_handle; /**< starting handle */ uint16_t e_handle; /**< ending handle */ } mico_bt_gatt_included_service_t; /** characteristic descriptor information */ typedef struct { mico_bt_uuid_t type; /**< descriptor UUID type */ uint16_t handle; /**< descriptor attribute handle */ }mico_bt_gatt_char_descr_info_t; /** * Discovery result data * Use GATT_DISCOVERY_RESULT_SERVICE_* or GATT_DISCOVERY_RESULT_CHARACTERISTIC_* macros to parse discovery data) */ typedef union { mico_bt_gatt_included_service_t included_service; /**< Result for GATT_DISCOVER_INCLUDED_SERVICES */ mico_bt_gatt_group_value_t group_value; /**< Result for GATT_DISCOVER_SERVICES_ALL or GATT_DISCOVER_SERVICES_BY_UUID */ mico_bt_gatt_char_declaration_t characteristic_declaration; /**< Result for GATT_DISCOVER_CHARACTERISTICS */ mico_bt_gatt_char_descr_info_t char_descr_info; /**< Result for GATT_DISCOVER_CHARACTERISTIC_DESCRIPTORS */ } mico_bt_gatt_discovery_data_t; #define GATT_LINK_IDLE_TIMEOUT_WHEN_NO_APP 0 /* start a idle timer for this duration when no application need to use the link */ #define GATT_LINK_NO_IDLE_TIMEOUT 0xFFFF #define GATT_INVALID_ACL_HANDLE 0xFFFF #define GATT_HANDLE_IS_VALID(x) ((x) != 0) typedef uint16_t mico_bt_gatt_appearance_t; /**< GATT appearance (see #gatt_appearance_e) */ /***************************************************************************** * GATT Database Defintions *****************************************************************************/ /* The permission bits (see Vol 3, Part F, 3.3.1.1) */ #define LEGATTDB_PERM_NONE (0x00) #define LEGATTDB_PERM_VARIABLE_LENGTH (0x1 << 0) #define LEGATTDB_PERM_READABLE (0x1 << 1) #define LEGATTDB_PERM_WRITE_CMD (0x1 << 2) #define LEGATTDB_PERM_WRITE_REQ (0x1 << 3) #define LEGATTDB_PERM_AUTH_READABLE (0x1 << 4) #define LEGATTDB_PERM_RELIABLE_WRITE (0x1 << 5) #define LEGATTDB_PERM_AUTH_WRITABLE (0x1 << 6) #define LEGATTDB_PERM_WRITABLE (LEGATTDB_PERM_WRITE_CMD | LEGATTDB_PERM_WRITE_REQ| LEGATTDB_PERM_AUTH_WRITABLE) #define LEGATTDB_PERM_MASK (0x7f) /* All the permission bits. */ #define LEGATTDB_PERM_SERVICE_UUID_128 (0x1 << 7) /* GATT Characteristic Properties */ #define LEGATTDB_CHAR_PROP_BROADCAST (0x1 << 0) #define LEGATTDB_CHAR_PROP_READ (0x1 << 1) #define LEGATTDB_CHAR_PROP_WRITE_NO_RESPONSE (0x1 << 2) #define LEGATTDB_CHAR_PROP_WRITE (0x1 << 3) #define LEGATTDB_CHAR_PROP_NOTIFY (0x1 << 4) #define LEGATTDB_CHAR_PROP_INDICATE (0x1 << 5) #define LEGATTDB_CHAR_PROP_AUTHD_WRITES (0x1 << 6) #define LEGATTDB_CHAR_PROP_EXTENDED (0x1 << 7) /* Conversion macros */ #define BIT16_TO_8( val ) \ (uint8_t)( (val) & 0xff),/* LSB */ \ (uint8_t)(( (val) >> 8 ) & 0xff) /* MSB */ /* UUID lengths */ #define LEGATTDB_UUID16_SIZE 2 #define LEGATTDB_UUID128_SIZE 16 /* Service and Characteristic macros */ #define ATTRIBUTE16( handle, permission, datalen, uuid ) \ BIT16_TO_8(handle), \ (uint8_t)(permission), \ (uint8_t)(datalen + 2), \ BIT16_TO_8(uuid) #define PRIMARY_SERVICE_UUID16(handle, service) \ BIT16_TO_8((uint16_t)(handle)), \ LEGATTDB_PERM_READABLE, \ 4, \ BIT16_TO_8((GATT_UUID_PRI_SERVICE)), \ BIT16_TO_8((service)) #define PRIMARY_SERVICE_UUID128(handle, service) \ BIT16_TO_8((uint16_t)(handle)), \ LEGATTDB_PERM_READABLE, \ 18, \ BIT16_TO_8(GATT_UUID_PRI_SERVICE), \ service #define SECONDARY_SERVICE_UUID16(handle, service) \ BIT16_TO_8((uint16_t)(handle)), \ LEGATTDB_PERM_READABLE, \ 4, \ BIT16_TO_8((GATT_UUID_SEC_SERVICE)), \ BIT16_TO_8((service)) #define SECONDARY_SERVICE_UUID128(handle, service) \ BIT16_TO_8((uint16_t)(handle)), \ LEGATTDB_PERM_READABLE, \ 18, \ BIT16_TO_8(GATT_UUID_SEC_SERVICE), \ service #define INCLUDE_SERVICE_UUID16(handle, service_handle, end_group_handle, service) \ BIT16_TO_8((uint16_t)(handle)), \ LEGATTDB_PERM_READABLE, \ 8, \ BIT16_TO_8(GATT_UUID_INCLUDE_SERVICE), \ BIT16_TO_8(service_handle), \ BIT16_TO_8(end_group_handle), \ BIT16_TO_8(service) #define INCLUDE_SERVICE_UUID128(handle, service_handle, end_group_handle)\ BIT16_TO_8((uint16_t)(handle)), \ LEGATTDB_PERM_READABLE, \ 6, \ BIT16_TO_8(GATT_UUID_INCLUDE_SERVICE), \ BIT16_TO_8(service_handle), \ BIT16_TO_8(end_group_handle) #define CHARACTERISTIC_UUID16(handle, handle_value, uuid, properties, permission) \ BIT16_TO_8((uint16_t)(handle)), \ LEGATTDB_PERM_READABLE, \ 0x07, \ BIT16_TO_8(GATT_UUID_CHAR_DECLARE), \ (uint8_t)(properties), \ BIT16_TO_8((uint16_t)(handle_value)), \ BIT16_TO_8(uuid), \ BIT16_TO_8((uint16_t)(handle_value)), \ (uint8_t)(permission), \ (uint8_t)(LEGATTDB_UUID16_SIZE), \ BIT16_TO_8(uuid) #define CHARACTERISTIC_UUID128(handle, handle_value, uuid, properties, permission) \ BIT16_TO_8((uint16_t)(handle)), \ LEGATTDB_PERM_READABLE, \ 21, \ BIT16_TO_8(GATT_UUID_CHAR_DECLARE), \ (uint8_t)(properties), \ BIT16_TO_8((uint16_t)(handle_value)), \ uuid, \ BIT16_TO_8((uint16_t)(handle_value)), \ (uint8_t)(permission | LEGATTDB_PERM_SERVICE_UUID_128), \ (uint8_t)(LEGATTDB_UUID128_SIZE), \ uuid #define CHARACTERISTIC_UUID16_WRITABLE(handle, handle_value, uuid, properties, permission) \ BIT16_TO_8((uint16_t)(handle)), \ LEGATTDB_PERM_READABLE, \ 0x07, \ BIT16_TO_8(GATT_UUID_CHAR_DECLARE), \ (uint8_t)(properties), \ BIT16_TO_8((uint16_t)(handle_value)), \ BIT16_TO_8(uuid), \ BIT16_TO_8((uint16_t)(handle_value)), \ (uint8_t)(permission), \ (uint8_t)(LEGATTDB_UUID16_SIZE), \ (uint8_t)(0), \ BIT16_TO_8(uuid) #define CHARACTERISTIC_UUID128_WRITABLE(handle, handle_value, uuid, properties, permission) \ BIT16_TO_8((uint16_t)(handle)), \ LEGATTDB_PERM_READABLE, \ 21, \ BIT16_TO_8(GATT_UUID_CHAR_DECLARE), \ (uint8_t)(properties), \ BIT16_TO_8((uint16_t)(handle_value)), \ uuid, \ BIT16_TO_8((uint16_t)(handle_value)), \ (uint8_t)(permission | LEGATTDB_PERM_SERVICE_UUID_128), \ (uint8_t)(LEGATTDB_UUID128_SIZE), \ (uint8_t)(0), \ uuid #define CHAR_DESCRIPTOR_UUID16_WRITABLE(handle, uuid, permission) \ BIT16_TO_8((uint16_t)(handle)), \ (uint8_t)(permission), \ (uint8_t)(LEGATTDB_UUID16_SIZE), \ (uint8_t)(0), \ BIT16_TO_8(uuid) #define CHAR_DESCRIPTOR_UUID16(handle, uuid, permission) \ BIT16_TO_8((uint16_t)(handle)), \ (uint8_t)(permission), \ (uint8_t)(LEGATTDB_UUID16_SIZE), \ BIT16_TO_8(uuid) /** GATT events */ typedef enum { GATT_CONNECTION_STATUS_EVT, /**< GATT connection status change. Event data: #mico_bt_gatt_connection_status_t */ GATT_OPERATION_CPLT_EVT, /**< GATT operation complete. Event data: #mico_bt_gatt_event_data_t */ GATT_DISCOVERY_RESULT_EVT, /**< GATT attribute discovery result. Event data: #mico_bt_gatt_discovery_result_t */ GATT_DISCOVERY_CPLT_EVT, /**< GATT attribute discovery complete. Event data: #mico_bt_gatt_event_data_t */ GATT_ATTRIBUTE_REQUEST_EVT /**< GATT attribute request (from remote client). Event data: #mico_bt_gatt_attribute_request_t */ } mico_bt_gatt_evt_t; /** Discovery result (used by GATT_DISCOVERY_RESULT_EVT notification) */ typedef struct { uint16_t conn_id; /**< ID of the connection */ mico_bt_gatt_discovery_type_t discovery_type; /**< Discovery type (see @link mico_bt_gatt_discovery_type_e mico_bt_gatt_discovery_type_t @endlink) */ mico_bt_gatt_discovery_data_t discovery_data; /**< Discovery data */ } mico_bt_gatt_discovery_result_t; /** Discovery Complete (used by GATT_DISCOVERY_CPLT_EVT notification) */ typedef struct { uint16_t conn_id; /**< ID of the connection */ mico_bt_gatt_discovery_type_t disc_type; /**< Discovery type (see @link mico_bt_gatt_discovery_type_e mico_bt_gatt_discovery_type_t @endlink) */ mico_bt_gatt_status_t status; /**< Status of operation */ } mico_bt_gatt_discovery_complete_t; /** Response to read/write/disc/config operations (used by GATT_OPERATION_CPLT_EVT notification) */ typedef struct { uint16_t conn_id; /**< ID of the connection */ mico_bt_gatt_optype_t op; /**< Type of operation completed (see @link mico_bt_gatt_optype_e mico_bt_gatt_optype_t @endlink) */ mico_bt_gatt_status_t status; /**< Status of operation */ mico_bt_gatt_operation_complete_rsp_t response_data; /**< Response data (dependent on optype) */ } mico_bt_gatt_operation_complete_t; /** GATT connection status (used by GATT_CONNECTION_STATUS_EVT notification) */ typedef struct { uint8_t *bd_addr; /**< Remote device address */ mico_bt_ble_address_type_t addr_type; /**< Remmote device address type */ uint16_t conn_id; /**< ID of the connection */ mico_bool_t connected; /**< TRUE if connected, FALSE if disconnected */ mico_bt_gatt_disconn_reason_t reason; /**< Reason code (see @link mico_bt_gatt_disconn_reason_e mico_bt_gatt_disconn_reason_t @endlink) */ mico_bt_transport_t transport; /**< Transport type of the connection */ uint8_t link_role; /**< Link role on this connection */ } mico_bt_gatt_connection_status_t; /** GATT attribute request (used by GATT_ATTRIBUTE_REQUEST_EVT notification) */ typedef struct { uint16_t conn_id; /**< ID of the connection */ mico_bt_gatt_request_type_t request_type; /**< Request type (see @link mico_bt_gatt_request_type_e mico_bt_gatt_request_type_t) */ mico_bt_gatt_request_data_t data; /**< Information about attribute being request (dependent on request type) */ } mico_bt_gatt_attribute_request_t; /** Stuctures for GATT event notifications */ typedef union { mico_bt_gatt_discovery_result_t discovery_result; /**< Data for GATT_DISCOVERY_RESULT_EVT */ mico_bt_gatt_discovery_complete_t discovery_complete; /**< Data for GATT_DISCOVERY_CPLT_EVT */ mico_bt_gatt_operation_complete_t operation_complete; /**< Data for GATT_OPERATION_CPLT_EVT */ mico_bt_gatt_connection_status_t connection_status; /**< Data for GATT_CONNECTION_STATUS_EVT */ mico_bt_gatt_attribute_request_t attribute_request; /**< Data for GATT_ATTRIBUTE_REQUEST_EVT */ } mico_bt_gatt_event_data_t; /** * GATT event notification callback * * Callback for GATT event notifications * Registered using mico_bt_gatt_register() * * @param event : Event ID * @param p_event_data : Event data * * @return Status of event handling */ typedef mico_bt_gatt_status_t mico_bt_gatt_cback_t(mico_bt_gatt_evt_t event, mico_bt_gatt_event_data_t *p_event_data); /***************************************************************************** * External Function Declarations ****************************************************************************/ #ifdef __cplusplus extern "C" { #endif /** * @addtogroup micobt_gatt Generic Attribute (GATT) * @ingroup micobt * * Generic Attribute (GATT) Functions. * * @{ */ /****************************************************************************/ /** * GATT Profile Server Functions * * @addtogroup server_api_functions Server * @ingroup micobt_gatt * * Server API Functions sub module for @b GATT. * * @{ */ /****************************************************************************/ /** * Function mico_bt_gatt_db_init * * Initialize the GATT database * * @param[in] p_gatt_db : First element in GATT database array * @param[in] gatt_db_size : Size (in bytes) of GATT database * * @return @link mico_bt_gatt_status_e mico_bt_gatt_status_t @endlink * */ mico_bt_gatt_status_t mico_bt_gatt_db_init (const uint8_t *p_gatt_db, uint16_t gatt_db_size); /** * * Function mico_bt_gatt_send_indication * * Send a handle value indication to a client * * @param[in] conn_id : connection identifier. * @param[in] attr_handle : Attribute handle of this handle value indication. * @param[in] val_len : Length of notification value passed, and return the length actually. * @param[in] p_val : Notification Value. * * @return @link mico_bt_gatt_status_e mico_bt_gatt_status_t @endlink * */ mico_bt_gatt_status_t mico_bt_gatt_send_indication (uint16_t conn_id, uint16_t attr_handle, uint16_t *val_len, uint8_t *p_val ); /** * Function mico_bt_gatt_send_notification * * Send a handle value notification to a client. * * @param[in] conn_id : connection identifier. * @param[in] attr_handle : Attribute handle of this handle value indication. * @param[in] val_len : Length of notification value passed, and return the length actually. * @param[in] p_val : Notification Value. * * @return @link mico_bt_gatt_status_e mico_bt_gatt_status_t @endlink * */ mico_bt_gatt_status_t mico_bt_gatt_send_notification (uint16_t conn_id, uint16_t attr_handle, uint16_t *val_len, uint8_t *p_val ); /** * Function mico_bt_gatt_send_response * * When application receives a Read Request, Write Request or Indication from the * peer it can reply synchronously or return a MICO_BT_GATT_PENDING result code * indicating to the stack that the message is not processed yet. In that case * application should call this function to send data or just a confirmation to * the peer. * * @param[in] status : Status of the operation to be send to the peer * @param[in] conn_id : Connection handle * @param[in] attr_handle : Attribute handle * @param[in] attr_len : Length of the attribute to send * @param[in] offset : Attribute value offset * @param[in] p_attr : Attribute Value * * @return @link mico_bt_gatt_status_e mico_bt_gatt_status_t @endlink */ mico_bt_gatt_status_t mico_bt_gatt_send_response(mico_bt_gatt_status_t status, uint16_t conn_id, uint16_t attr_handle, uint16_t attr_len, uint16_t offset, uint8_t* p_attr); /**@} server_api_functions */ /*****************************************************************************/ /** * GATT Profile Client Functions * * @addtogroup client_api_functions Client * @ingroup micobt_gatt * * @{ */ /*****************************************************************************/ /** * Function mico_bt_gatt_configure_mtu * * Configure the ATT MTU size for a connection on an LE * transport. * * @param[in] conn_id : GATT connection handle * @param[in] mtu : New MTU size * * @return @link mico_bt_gatt_status_e mico_bt_gatt_status_t @endlink */ mico_bt_gatt_status_t mico_bt_gatt_configure_mtu (uint16_t conn_id, uint16_t mtu); /** * Function mico_bt_gatt_send_discover * * Start an attribute discovery on an ATT server. * Discovery results are notified using GATT_DISCOVERY_RESULT_EVT ; * completion is notified using GATT_DISCOVERY_CPLT_EVT of #mico_bt_gatt_cback_t. * * @param[in] conn_id : GATT connection handle * @param[in] discovery_type : Discover type * @param[in] p_discovery_param : Discover parameter * * @return @link mico_bt_gatt_status_e mico_bt_gatt_status_t @endlink */ mico_bt_gatt_status_t mico_bt_gatt_send_discover (uint16_t conn_id, mico_bt_gatt_discovery_type_t discovery_type, mico_bt_gatt_discovery_param_t *p_discovery_param ); /** * Function mico_bt_gatt_send_read * * Read from remote ATT server. * Result is notified using GATT_OPERATION_CPLT_EVT of #mico_bt_gatt_cback_t. * * @param[in] conn_id : Connection handle * @param[in] type : Type of the read * @param[in] p_read : Pointer to the read request parameters * * @return @link mico_bt_gatt_status_e mico_bt_gatt_status_t @endlink * */ mico_bt_gatt_status_t mico_bt_gatt_send_read (uint16_t conn_id, mico_bt_gatt_read_type_t type, mico_bt_gatt_read_param_t *p_read); /** * Function mico_bt_gatt_send_write * * Write to remote ATT server. * Result is notified using GATT_OPERATION_CPLT_EVT of #mico_bt_gatt_cback_t. * * @param[in] conn_id : Connection handle * @param[in] type : Type of write * @param[in] p_write : Pointer to the write parameters * * @return @link mico_bt_gatt_status_e mico_bt_gatt_status_t @endlink */ mico_bt_gatt_status_t mico_bt_gatt_send_write (uint16_t conn_id, mico_bt_gatt_write_type_t type, mico_bt_gatt_value_t *p_write); /** * Function mico_bt_gatt_send_execute_write * * Send Execute Write request to remote ATT server. * * @param[in] conn_id : Connection handle * @param[in] is_execute : MICO_BT_TRUE to execute, MICO_BT_FALSE to cancel * * @return @link mico_bt_gatt_status_e mico_bt_gatt_status_t @endlink * */ mico_bt_gatt_status_t mico_bt_gatt_send_execute_write (uint16_t conn_id, mico_bool_t is_execute); /** * Function mico_bt_gatt_send_indication_confirm * * Send a handle value confirmation to remote ATT server. * (in response to GATTC_OPTYPE_INDICATION of #mico_bt_gatt_cback_t) * * @param[in] conn_id : Connection handle * @param[in] handle : Attribute handle * * @return @link mico_bt_gatt_status_e mico_bt_gatt_status_t @endlink */ mico_bt_gatt_status_t mico_bt_gatt_send_indication_confirm (uint16_t conn_id, uint16_t handle); /**@} client_api_functions */ /*****************************************************************************/ /** * GATT Profile Common Functions * * @addtogroup common_api_functions Common * @ingroup micobt_gatt * * @{ */ /*****************************************************************************/ /** * Function mico_bt_gatt_register * * Register an application callback for GATT. * * @param[in] gatt_if : The GATT application interface * @param[in] p_gatt_cback : The GATT notification callback * * @return @link mico_bt_gatt_status_e mico_bt_gatt_status_t @endlink * */ mico_bt_gatt_status_t mico_bt_gatt_register (mico_bt_gatt_app_interface_t gatt_if, mico_bt_gatt_cback_t *p_gatt_cback); /** * Function mico_bt_gatt_deregister * * Deregister an application callback for GATT. * * @param[in] gatt_if : The GATT application interface * * @return @link mico_bt_gatt_status_e mico_bt_gatt_status_t @endlink * */ mico_bt_gatt_status_t mico_bt_gatt_deregister (mico_bt_gatt_app_interface_t gatt_if); /** * Function mico_bt_gatt_le_connect * * Open GATT over LE connection to a remote device * Result is notified using GATT_CONNECTION_STATUS_EVT of #mico_bt_gatt_cback_t. * * @param[in] bd_addr : Remote device address * @param[in] bd_addr_type: Public or random address * @param[in] conn_mode : connection scan mode * @param[in] is_direct : Is direct connection or not * * @return TRUE : If connection started * FALSE : If connection start failure * */ mico_bool_t mico_bt_gatt_le_connect (mico_bt_device_address_t bd_addr, mico_bt_ble_address_type_t bd_addr_type, mico_bt_ble_conn_mode_t conn_mode, mico_bool_t is_direct); /** * Function mico_bt_gatt_bredr_connect * * Open GATT over BR/EDR connection to a remote device * Result is notified using GATT_CONNECTION_STATUS_EVT of #mico_bt_gatt_cback_t. * * @param[in] bd_addr : Remote device address * * @return TRUE : If connection started * FALSE : If connection start failure * */ mico_bool_t mico_bt_gatt_bredr_connect (mico_bt_device_address_t bd_addr); /** * Function mico_bt_gatt_cancel_connect * * Cancel initiating GATT connecton * * @param[in] bd_addr : Remote device addresss * @param[in] is_direct : Is direct connection or not * * @return TRUE : If connection started * FALSE : If connection start failure * */ mico_bool_t mico_bt_gatt_cancel_connect (mico_bt_device_address_t bd_addr, mico_bool_t is_direct); /** * Function mico_bt_gatt_disconnect * * Close the specified GATT connection. * Result is notified using GATT_CONNECTION_STATUS_EVT of #mico_bt_gatt_cback_t. * * @param[in] conn_id : GATT connection ID * * @return @link mico_bt_gatt_status_e mico_bt_gatt_status_t @endlink * */ mico_bt_gatt_status_t mico_bt_gatt_disconnect (uint16_t conn_id); /** * Function mico_bt_gatt_listen * * Start or stop LE advertisement and listen for connection. * * @param[in] start : TRUE to add device to whitelist / FALSE to remove * @param[in] bd_addr : Device to add/remove from whitelist * * @return TRUE : Success * FALSE : Failure * */ mico_bool_t mico_bt_gatt_listen (mico_bool_t start, mico_bt_device_address_t bd_addr); /**@} common_api_functions*/ #ifdef __cplusplus } #endif /**@} micobt_gatt */