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 232fca4dadSMilanka Ringwald * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BLUEKITCHEN 242fca4dadSMilanka Ringwald * GMBH 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 38fe5a6c4eSMilanka Ringwald /** 39fe5a6c4eSMilanka Ringwald * @title Battery Service Client 40fe5a6c4eSMilanka Ringwald * 41fe5a6c4eSMilanka Ringwald */ 42fe5a6c4eSMilanka Ringwald 436bdecec7SMatthias Ringwald #ifndef BATTERY_SERVICE_CLIENT_H 446bdecec7SMatthias Ringwald #define BATTERY_SERVICE_CLIENT_H 456bdecec7SMatthias Ringwald 466bdecec7SMatthias Ringwald #include <stdint.h> 476bdecec7SMatthias Ringwald #include "btstack_defines.h" 486bdecec7SMatthias Ringwald #include "bluetooth.h" 496bdecec7SMatthias Ringwald #include "btstack_linked_list.h" 506bdecec7SMatthias Ringwald #include "ble/gatt_client.h" 516bdecec7SMatthias Ringwald 526bdecec7SMatthias Ringwald #if defined __cplusplus 536bdecec7SMatthias Ringwald extern "C" { 546bdecec7SMatthias Ringwald #endif 556bdecec7SMatthias Ringwald 561ea30d1bSMilanka Ringwald /** 571ea30d1bSMilanka Ringwald * @text The Battery Service Client connects to the Battery Services of a remote device 581ea30d1bSMilanka Ringwald * and queries its battery level values. Level updates are either received via notifications 591ea30d1bSMilanka Ringwald * (if supported by the remote Battery Service), or by manual polling. 601ea30d1bSMilanka Ringwald */ 611ea30d1bSMilanka Ringwald 626bdecec7SMatthias Ringwald #ifndef MAX_NUM_BATTERY_SERVICES 636bdecec7SMatthias Ringwald #define MAX_NUM_BATTERY_SERVICES 3 646bdecec7SMatthias Ringwald #endif 656bdecec7SMatthias Ringwald 666bdecec7SMatthias Ringwald #if MAX_NUM_BATTERY_SERVICES > 8 676bdecec7SMatthias Ringwald #error "Maximum number of Battery Services exceeded" 686bdecec7SMatthias Ringwald #endif 696bdecec7SMatthias Ringwald 706bdecec7SMatthias Ringwald 716bdecec7SMatthias Ringwald typedef enum { 726bdecec7SMatthias Ringwald BATTERY_SERVICE_CLIENT_STATE_IDLE, 736bdecec7SMatthias Ringwald BATTERY_SERVICE_CLIENT_STATE_W2_QUERY_SERVICE, 746bdecec7SMatthias Ringwald BATTERY_SERVICE_CLIENT_STATE_W4_SERVICE_RESULT, 75813fc1b9SMilanka Ringwald BATTERY_SERVICE_CLIENT_STATE_W2_QUERY_CHARACTERISTICS, 766bdecec7SMatthias Ringwald BATTERY_SERVICE_CLIENT_STATE_W4_CHARACTERISTIC_RESULT, 777594dd72SMilanka Ringwald 78813fc1b9SMilanka Ringwald #ifdef ENABLE_TESTING_SUPPORT 79813fc1b9SMilanka Ringwald BATTERY_SERVICE_CLIENT_STATE_W2_QUERY_CHARACTERISTIC_DESCRIPTORS, 80813fc1b9SMilanka Ringwald BATTERY_SERVICE_CLIENT_STATE_W4_CHARACTERISTIC_DESCRIPTORS_RESULT, 81813fc1b9SMilanka Ringwald #endif 827594dd72SMilanka Ringwald 83813fc1b9SMilanka Ringwald BATTERY_SERVICE_CLIENT_STATE_W2_REGISTER_NOTIFICATION, 84813fc1b9SMilanka Ringwald BATTERY_SERVICE_CLIENT_STATE_W4_NOTIFICATION_REGISTERED, 857594dd72SMilanka Ringwald BATTERY_SERVICE_CLIENT_STATE_CONNECTED, 86*814908c5SMatthias Ringwald BATTERY_SERVICE_CLIENT_STATE_W4_CHARACTERISTIC_VALUE_READ, 877594dd72SMilanka Ringwald 887594dd72SMilanka Ringwald #ifdef ENABLE_TESTING_SUPPORT 897594dd72SMilanka Ringwald BATTERY_SERVICE_CLIENT_W2_READ_CHARACTERISTIC_CONFIGURATION, 907594dd72SMilanka Ringwald BATTERY_SERVICE_CLIENT_W4_CHARACTERISTIC_CONFIGURATION_RESULT, 917594dd72SMilanka Ringwald #endif 926bdecec7SMatthias Ringwald } battery_service_client_state_t; 936bdecec7SMatthias Ringwald 946bdecec7SMatthias Ringwald 956bdecec7SMatthias Ringwald typedef struct { 966bdecec7SMatthias Ringwald // service 976bdecec7SMatthias Ringwald uint16_t start_handle; 986bdecec7SMatthias Ringwald uint16_t end_handle; 996bdecec7SMatthias Ringwald 1006bdecec7SMatthias Ringwald // characteristic 1016bdecec7SMatthias Ringwald uint16_t properties; 1026bdecec7SMatthias Ringwald uint16_t value_handle; 1036bdecec7SMatthias Ringwald 1047594dd72SMilanka Ringwald #ifdef ENABLE_TESTING_SUPPORT 1057594dd72SMilanka Ringwald uint16_t ccc_handle; 1067594dd72SMilanka Ringwald #endif 1077594dd72SMilanka Ringwald 1086bdecec7SMatthias Ringwald gatt_client_notification_t notification_listener; 1096bdecec7SMatthias Ringwald } battery_service_t; 1106bdecec7SMatthias Ringwald 1116bdecec7SMatthias Ringwald 1126bdecec7SMatthias Ringwald typedef struct { 1136bdecec7SMatthias Ringwald btstack_linked_item_t item; 1146bdecec7SMatthias Ringwald 1156bdecec7SMatthias Ringwald hci_con_handle_t con_handle; 1166bdecec7SMatthias Ringwald uint16_t cid; 1176bdecec7SMatthias Ringwald battery_service_client_state_t state; 1186bdecec7SMatthias Ringwald btstack_packet_handler_t client_handler; 1196bdecec7SMatthias Ringwald 1206bdecec7SMatthias Ringwald uint32_t poll_interval_ms; 1216bdecec7SMatthias Ringwald 1226bdecec7SMatthias Ringwald uint8_t num_instances; 1236bdecec7SMatthias Ringwald battery_service_t services[MAX_NUM_BATTERY_SERVICES]; 1246bdecec7SMatthias Ringwald 1256bdecec7SMatthias Ringwald // used for discovering characteristics and polling 1266d1993e0SMilanka Ringwald uint8_t service_index; 1276bdecec7SMatthias Ringwald uint8_t poll_bitmap; 1286bdecec7SMatthias Ringwald uint8_t need_poll_bitmap; 1296bdecec7SMatthias Ringwald uint8_t polled_service_index; 1306bdecec7SMatthias Ringwald btstack_timer_source_t poll_timer; 1316bdecec7SMatthias Ringwald } battery_service_client_t; 1326bdecec7SMatthias Ringwald 1336bdecec7SMatthias Ringwald /* API_START */ 1346bdecec7SMatthias Ringwald 1356bdecec7SMatthias Ringwald 1366bdecec7SMatthias Ringwald /** 1376bdecec7SMatthias Ringwald * @brief Initialize Battery Service. 1386bdecec7SMatthias Ringwald */ 1396bdecec7SMatthias Ringwald void battery_service_client_init(void); 1406bdecec7SMatthias Ringwald 1416bdecec7SMatthias Ringwald /** 1426bdecec7SMatthias Ringwald * @brief Connect to Battery Services of remote device. The client will try to register for notifications. 1436bdecec7SMatthias Ringwald * If notifications are not supported by remote Battery Service, the client will poll battery level 1446bdecec7SMatthias Ringwald * If poll_interval_ms is 0, polling is disabled, and only notifications will be received. 1456bdecec7SMatthias Ringwald * In either case, the battery level is received via GATTSERVICE_SUBEVENT_BATTERY_SERVICE_LEVEL event. 146*814908c5SMatthias Ringwald * The battery level is reported as percentage, i.e. 100 = full and it is valid if the ATT status is equal to ATT_ERROR_SUCCESS, 1476bdecec7SMatthias Ringwald * see ATT errors (see bluetooth.h) for other values. 1486bdecec7SMatthias Ringwald * 1496bdecec7SMatthias Ringwald * For manual polling, see battery_service_client_read_battery_level below. 1506bdecec7SMatthias Ringwald * 1516bdecec7SMatthias Ringwald * Event GATTSERVICE_SUBEVENT_BATTERY_SERVICE_CONNECTED is emitted with status ERROR_CODE_SUCCESS on success, otherwise 1526bdecec7SMatthias 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). 1536bdecec7SMatthias Ringwald * This event event also returns number of battery instances found on remote server, as well as poll bitmap that indicates which indexes 1546bdecec7SMatthias Ringwald * of services require polling, i.e. they do not support notification on battery level change, 1556bdecec7SMatthias Ringwald * 1566bdecec7SMatthias Ringwald * @param con_handle 1576bdecec7SMatthias Ringwald * @param packet_handler 1586bdecec7SMatthias Ringwald * @param poll_interval_ms or 0 to disable polling 1596bdecec7SMatthias Ringwald * @param battery_service_cid 1606bdecec7SMatthias 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 1616bdecec7SMatthias Ringwald */ 1626bdecec7SMatthias 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); 1636bdecec7SMatthias Ringwald 1646bdecec7SMatthias Ringwald /** 1656bdecec7SMatthias Ringwald * @brief Read battery level for service with given index. Event GATTSERVICE_SUBEVENT_BATTERY_SERVICE_LEVEL is 1666bdecec7SMatthias Ringwald * received with battery level (unit is in percentage, i.e. 100 = full). The battery level is valid if the ATTT status 1676bdecec7SMatthias Ringwald * is equal to ATT_ERROR_SUCCESS, see ATT errors (see bluetooth.h) for other values. 1686bdecec7SMatthias Ringwald * @param battery_service_cid 1696bdecec7SMatthias Ringwald * @param service_index 1706bdecec7SMatthias Ringwald * @return status 1716bdecec7SMatthias Ringwald */ 1726bdecec7SMatthias Ringwald uint8_t battery_service_client_read_battery_level(uint16_t battery_service_cid, uint8_t service_index); 1736bdecec7SMatthias Ringwald 1746bdecec7SMatthias Ringwald /** 1756bdecec7SMatthias Ringwald * @brief Disconnect from Battery Service. 1766bdecec7SMatthias Ringwald * @param battery_service_cid 1776bdecec7SMatthias Ringwald * @return status 1786bdecec7SMatthias Ringwald */ 1796bdecec7SMatthias Ringwald uint8_t battery_service_client_disconnect(uint16_t battery_service_cid); 1806bdecec7SMatthias Ringwald 1816bdecec7SMatthias Ringwald /** 1826bdecec7SMatthias Ringwald * @brief De-initialize Battery Service. 1836bdecec7SMatthias Ringwald */ 1846bdecec7SMatthias Ringwald void battery_service_client_deinit(void); 1856bdecec7SMatthias Ringwald 1866bdecec7SMatthias Ringwald /* API_END */ 1876bdecec7SMatthias Ringwald 1886bdecec7SMatthias Ringwald #if defined __cplusplus 1896bdecec7SMatthias Ringwald } 1906bdecec7SMatthias Ringwald #endif 1916bdecec7SMatthias Ringwald 1926bdecec7SMatthias Ringwald #endif 193