16bdecec7SMatthias Ringwald /* 26bdecec7SMatthias Ringwald * Copyright (C) 2021 BlueKitchen GmbH 36bdecec7SMatthias Ringwald * 46bdecec7SMatthias Ringwald * Redistribution and use in source and binary forms, with or without 56bdecec7SMatthias Ringwald * modification, are permitted provided that the following conditions 66bdecec7SMatthias Ringwald * are met: 76bdecec7SMatthias Ringwald * 86bdecec7SMatthias Ringwald * 1. Redistributions of source code must retain the above copyright 96bdecec7SMatthias Ringwald * notice, this list of conditions and the following disclaimer. 106bdecec7SMatthias Ringwald * 2. Redistributions in binary form must reproduce the above copyright 116bdecec7SMatthias Ringwald * notice, this list of conditions and the following disclaimer in the 126bdecec7SMatthias Ringwald * documentation and/or other materials provided with the distribution. 136bdecec7SMatthias Ringwald * 3. Neither the name of the copyright holders nor the names of 146bdecec7SMatthias Ringwald * contributors may be used to endorse or promote products derived 156bdecec7SMatthias Ringwald * from this software without specific prior written permission. 166bdecec7SMatthias Ringwald * 4. Any redistribution, use, or modification is done solely for 176bdecec7SMatthias Ringwald * personal benefit and not for any commercial purpose or for 186bdecec7SMatthias Ringwald * monetary gain. 196bdecec7SMatthias Ringwald * 206bdecec7SMatthias Ringwald * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS 216bdecec7SMatthias Ringwald * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 226bdecec7SMatthias Ringwald * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 236bdecec7SMatthias Ringwald * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS 246bdecec7SMatthias Ringwald * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 256bdecec7SMatthias Ringwald * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 266bdecec7SMatthias Ringwald * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 276bdecec7SMatthias Ringwald * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 286bdecec7SMatthias Ringwald * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 296bdecec7SMatthias Ringwald * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 306bdecec7SMatthias Ringwald * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 316bdecec7SMatthias Ringwald * SUCH DAMAGE. 326bdecec7SMatthias Ringwald * 336bdecec7SMatthias Ringwald * Please inquire about commercial licensing options at 346bdecec7SMatthias Ringwald * [email protected] 356bdecec7SMatthias Ringwald * 366bdecec7SMatthias Ringwald */ 376bdecec7SMatthias Ringwald 386bdecec7SMatthias Ringwald #ifndef BATTERY_SERVICE_CLIENT_H 396bdecec7SMatthias Ringwald #define BATTERY_SERVICE_CLIENT_H 406bdecec7SMatthias Ringwald 416bdecec7SMatthias Ringwald #include <stdint.h> 426bdecec7SMatthias Ringwald #include "btstack_defines.h" 436bdecec7SMatthias Ringwald #include "bluetooth.h" 446bdecec7SMatthias Ringwald #include "btstack_linked_list.h" 456bdecec7SMatthias Ringwald #include "ble/gatt_client.h" 466bdecec7SMatthias Ringwald 476bdecec7SMatthias Ringwald 486bdecec7SMatthias Ringwald #if defined __cplusplus 496bdecec7SMatthias Ringwald extern "C" { 506bdecec7SMatthias Ringwald #endif 516bdecec7SMatthias Ringwald 526bdecec7SMatthias Ringwald #ifndef MAX_NUM_BATTERY_SERVICES 536bdecec7SMatthias Ringwald #define MAX_NUM_BATTERY_SERVICES 3 546bdecec7SMatthias Ringwald #endif 556bdecec7SMatthias Ringwald 566bdecec7SMatthias Ringwald #if MAX_NUM_BATTERY_SERVICES > 8 576bdecec7SMatthias Ringwald #error "Maximum number of Battery Services exceeded" 586bdecec7SMatthias Ringwald #endif 596bdecec7SMatthias Ringwald 606bdecec7SMatthias Ringwald 616bdecec7SMatthias Ringwald typedef enum { 626bdecec7SMatthias Ringwald BATTERY_SERVICE_CLIENT_STATE_IDLE, 636bdecec7SMatthias Ringwald BATTERY_SERVICE_CLIENT_STATE_W2_QUERY_SERVICE, 646bdecec7SMatthias Ringwald BATTERY_SERVICE_CLIENT_STATE_W4_SERVICE_RESULT, 65813fc1b9SMilanka Ringwald BATTERY_SERVICE_CLIENT_STATE_W2_QUERY_CHARACTERISTICS, 666bdecec7SMatthias Ringwald BATTERY_SERVICE_CLIENT_STATE_W4_CHARACTERISTIC_RESULT, 67*7594dd72SMilanka Ringwald 68813fc1b9SMilanka Ringwald #ifdef ENABLE_TESTING_SUPPORT 69813fc1b9SMilanka Ringwald BATTERY_SERVICE_CLIENT_STATE_W2_QUERY_CHARACTERISTIC_DESCRIPTORS, 70813fc1b9SMilanka Ringwald BATTERY_SERVICE_CLIENT_STATE_W4_CHARACTERISTIC_DESCRIPTORS_RESULT, 71813fc1b9SMilanka Ringwald #endif 72*7594dd72SMilanka Ringwald 73813fc1b9SMilanka Ringwald BATTERY_SERVICE_CLIENT_STATE_W2_REGISTER_NOTIFICATION, 74813fc1b9SMilanka Ringwald BATTERY_SERVICE_CLIENT_STATE_W4_NOTIFICATION_REGISTERED, 75*7594dd72SMilanka Ringwald BATTERY_SERVICE_CLIENT_STATE_CONNECTED, 76*7594dd72SMilanka Ringwald 77*7594dd72SMilanka Ringwald #ifdef ENABLE_TESTING_SUPPORT 78*7594dd72SMilanka Ringwald BATTERY_SERVICE_CLIENT_W2_READ_CHARACTERISTIC_CONFIGURATION, 79*7594dd72SMilanka Ringwald BATTERY_SERVICE_CLIENT_W4_CHARACTERISTIC_CONFIGURATION_RESULT, 80*7594dd72SMilanka Ringwald #endif 816bdecec7SMatthias Ringwald } battery_service_client_state_t; 826bdecec7SMatthias Ringwald 836bdecec7SMatthias Ringwald 846bdecec7SMatthias Ringwald typedef struct { 856bdecec7SMatthias Ringwald // service 866bdecec7SMatthias Ringwald uint16_t start_handle; 876bdecec7SMatthias Ringwald uint16_t end_handle; 886bdecec7SMatthias Ringwald 896bdecec7SMatthias Ringwald // characteristic 906bdecec7SMatthias Ringwald uint16_t properties; 916bdecec7SMatthias Ringwald uint16_t value_handle; 926bdecec7SMatthias Ringwald 93*7594dd72SMilanka Ringwald #ifdef ENABLE_TESTING_SUPPORT 94*7594dd72SMilanka Ringwald uint16_t ccc_handle; 95*7594dd72SMilanka Ringwald #endif 96*7594dd72SMilanka Ringwald 976bdecec7SMatthias Ringwald gatt_client_notification_t notification_listener; 986bdecec7SMatthias Ringwald } battery_service_t; 996bdecec7SMatthias Ringwald 1006bdecec7SMatthias Ringwald 1016bdecec7SMatthias Ringwald typedef struct { 1026bdecec7SMatthias Ringwald btstack_linked_item_t item; 1036bdecec7SMatthias Ringwald 1046bdecec7SMatthias Ringwald hci_con_handle_t con_handle; 1056bdecec7SMatthias Ringwald uint16_t cid; 1066bdecec7SMatthias Ringwald battery_service_client_state_t state; 1076bdecec7SMatthias Ringwald btstack_packet_handler_t client_handler; 1086bdecec7SMatthias Ringwald 1096bdecec7SMatthias Ringwald uint32_t poll_interval_ms; 1106bdecec7SMatthias Ringwald 1116bdecec7SMatthias Ringwald uint8_t num_instances; 1126bdecec7SMatthias Ringwald battery_service_t services[MAX_NUM_BATTERY_SERVICES]; 1136bdecec7SMatthias Ringwald 1146bdecec7SMatthias Ringwald // used for discovering characteristics and polling 1156d1993e0SMilanka Ringwald uint8_t service_index; 1166bdecec7SMatthias Ringwald uint8_t poll_bitmap; 1176bdecec7SMatthias Ringwald uint8_t need_poll_bitmap; 1186bdecec7SMatthias Ringwald uint8_t polled_service_index; 1196bdecec7SMatthias Ringwald btstack_timer_source_t poll_timer; 1206bdecec7SMatthias Ringwald } battery_service_client_t; 1216bdecec7SMatthias Ringwald 1226bdecec7SMatthias Ringwald /* API_START */ 1236bdecec7SMatthias Ringwald 1246bdecec7SMatthias Ringwald 1256bdecec7SMatthias Ringwald /** 1266bdecec7SMatthias Ringwald * @brief Initialize Battery Service. 1276bdecec7SMatthias Ringwald */ 1286bdecec7SMatthias Ringwald void battery_service_client_init(void); 1296bdecec7SMatthias Ringwald 1306bdecec7SMatthias Ringwald /** 1316bdecec7SMatthias Ringwald * @brief Connect to Battery Services of remote device. The client will try to register for notifications. 1326bdecec7SMatthias Ringwald * If notifications are not supported by remote Battery Service, the client will poll battery level 1336bdecec7SMatthias Ringwald * If poll_interval_ms is 0, polling is disabled, and only notifications will be received. 1346bdecec7SMatthias Ringwald * In either case, the battery level is received via GATTSERVICE_SUBEVENT_BATTERY_SERVICE_LEVEL event. 1356bdecec7SMatthias Ringwald * The battery level is reported as percentage, i.e. 100 = full and it is valid if the ATTT status is equal to ATT_ERROR_SUCCESS, 1366bdecec7SMatthias Ringwald * see ATT errors (see bluetooth.h) for other values. 1376bdecec7SMatthias Ringwald * 1386bdecec7SMatthias Ringwald * For manual polling, see battery_service_client_read_battery_level below. 1396bdecec7SMatthias Ringwald * 1406bdecec7SMatthias Ringwald * Event GATTSERVICE_SUBEVENT_BATTERY_SERVICE_CONNECTED is emitted with status ERROR_CODE_SUCCESS on success, otherwise 1416bdecec7SMatthias Ringwald * GATT_CLIENT_IN_WRONG_STATE, ERROR_CODE_UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE if no battery service is found, or ATT errors (see bluetooth.h). 1426bdecec7SMatthias Ringwald * This event event also returns number of battery instances found on remote server, as well as poll bitmap that indicates which indexes 1436bdecec7SMatthias Ringwald * of services require polling, i.e. they do not support notification on battery level change, 1446bdecec7SMatthias Ringwald * 1456bdecec7SMatthias Ringwald * @param con_handle 1466bdecec7SMatthias Ringwald * @param packet_handler 1476bdecec7SMatthias Ringwald * @param poll_interval_ms or 0 to disable polling 1486bdecec7SMatthias Ringwald * @param battery_service_cid 1496bdecec7SMatthias Ringwald * @return status ERROR_CODE_SUCCESS on success, otherwise ERROR_CODE_COMMAND_DISALLOWED if there is already a client associated with con_handle, or BTSTACK_MEMORY_ALLOC_FAILED 1506bdecec7SMatthias Ringwald */ 1516bdecec7SMatthias Ringwald uint8_t battery_service_client_connect(hci_con_handle_t con_handle, btstack_packet_handler_t packet_handler, uint32_t poll_interval_ms, uint16_t * battery_service_cid); 1526bdecec7SMatthias Ringwald 1536bdecec7SMatthias Ringwald /** 1546bdecec7SMatthias Ringwald * @brief Read battery level for service with given index. Event GATTSERVICE_SUBEVENT_BATTERY_SERVICE_LEVEL is 1556bdecec7SMatthias Ringwald * received with battery level (unit is in percentage, i.e. 100 = full). The battery level is valid if the ATTT status 1566bdecec7SMatthias Ringwald * is equal to ATT_ERROR_SUCCESS, see ATT errors (see bluetooth.h) for other values. 1576bdecec7SMatthias Ringwald * @param battery_service_cid 1586bdecec7SMatthias Ringwald * @param service_index 1596bdecec7SMatthias Ringwald * @return status 1606bdecec7SMatthias Ringwald */ 1616bdecec7SMatthias Ringwald uint8_t battery_service_client_read_battery_level(uint16_t battery_service_cid, uint8_t service_index); 1626bdecec7SMatthias Ringwald 1636bdecec7SMatthias Ringwald /** 1646bdecec7SMatthias Ringwald * @brief Disconnect from Battery Service. 1656bdecec7SMatthias Ringwald * @param battery_service_cid 1666bdecec7SMatthias Ringwald * @return status 1676bdecec7SMatthias Ringwald */ 1686bdecec7SMatthias Ringwald uint8_t battery_service_client_disconnect(uint16_t battery_service_cid); 1696bdecec7SMatthias Ringwald 1706bdecec7SMatthias Ringwald /** 1716bdecec7SMatthias Ringwald * @brief De-initialize Battery Service. 1726bdecec7SMatthias Ringwald */ 1736bdecec7SMatthias Ringwald void battery_service_client_deinit(void); 1746bdecec7SMatthias Ringwald 1756bdecec7SMatthias Ringwald /* API_END */ 1766bdecec7SMatthias Ringwald 1776bdecec7SMatthias Ringwald #if defined __cplusplus 1786bdecec7SMatthias Ringwald } 1796bdecec7SMatthias Ringwald #endif 1806bdecec7SMatthias Ringwald 1816bdecec7SMatthias Ringwald #endif 182