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 #if defined __cplusplus 486bdecec7SMatthias Ringwald extern "C" { 496bdecec7SMatthias Ringwald #endif 506bdecec7SMatthias Ringwald 51*1ea30d1bSMilanka Ringwald /** 52*1ea30d1bSMilanka Ringwald * @text The Battery Service Client connects to the Battery Services of a remote device 53*1ea30d1bSMilanka Ringwald * and queries its battery level values. Level updates are either received via notifications 54*1ea30d1bSMilanka Ringwald * (if supported by the remote Battery Service), or by manual polling. 55*1ea30d1bSMilanka Ringwald */ 56*1ea30d1bSMilanka Ringwald 576bdecec7SMatthias Ringwald #ifndef MAX_NUM_BATTERY_SERVICES 586bdecec7SMatthias Ringwald #define MAX_NUM_BATTERY_SERVICES 3 596bdecec7SMatthias Ringwald #endif 606bdecec7SMatthias Ringwald 616bdecec7SMatthias Ringwald #if MAX_NUM_BATTERY_SERVICES > 8 626bdecec7SMatthias Ringwald #error "Maximum number of Battery Services exceeded" 636bdecec7SMatthias Ringwald #endif 646bdecec7SMatthias Ringwald 656bdecec7SMatthias Ringwald 666bdecec7SMatthias Ringwald typedef enum { 676bdecec7SMatthias Ringwald BATTERY_SERVICE_CLIENT_STATE_IDLE, 686bdecec7SMatthias Ringwald BATTERY_SERVICE_CLIENT_STATE_W2_QUERY_SERVICE, 696bdecec7SMatthias Ringwald BATTERY_SERVICE_CLIENT_STATE_W4_SERVICE_RESULT, 70813fc1b9SMilanka Ringwald BATTERY_SERVICE_CLIENT_STATE_W2_QUERY_CHARACTERISTICS, 716bdecec7SMatthias Ringwald BATTERY_SERVICE_CLIENT_STATE_W4_CHARACTERISTIC_RESULT, 727594dd72SMilanka Ringwald 73813fc1b9SMilanka Ringwald #ifdef ENABLE_TESTING_SUPPORT 74813fc1b9SMilanka Ringwald BATTERY_SERVICE_CLIENT_STATE_W2_QUERY_CHARACTERISTIC_DESCRIPTORS, 75813fc1b9SMilanka Ringwald BATTERY_SERVICE_CLIENT_STATE_W4_CHARACTERISTIC_DESCRIPTORS_RESULT, 76813fc1b9SMilanka Ringwald #endif 777594dd72SMilanka Ringwald 78813fc1b9SMilanka Ringwald BATTERY_SERVICE_CLIENT_STATE_W2_REGISTER_NOTIFICATION, 79813fc1b9SMilanka Ringwald BATTERY_SERVICE_CLIENT_STATE_W4_NOTIFICATION_REGISTERED, 807594dd72SMilanka Ringwald BATTERY_SERVICE_CLIENT_STATE_CONNECTED, 817594dd72SMilanka Ringwald 827594dd72SMilanka Ringwald #ifdef ENABLE_TESTING_SUPPORT 837594dd72SMilanka Ringwald BATTERY_SERVICE_CLIENT_W2_READ_CHARACTERISTIC_CONFIGURATION, 847594dd72SMilanka Ringwald BATTERY_SERVICE_CLIENT_W4_CHARACTERISTIC_CONFIGURATION_RESULT, 857594dd72SMilanka Ringwald #endif 866bdecec7SMatthias Ringwald } battery_service_client_state_t; 876bdecec7SMatthias Ringwald 886bdecec7SMatthias Ringwald 896bdecec7SMatthias Ringwald typedef struct { 906bdecec7SMatthias Ringwald // service 916bdecec7SMatthias Ringwald uint16_t start_handle; 926bdecec7SMatthias Ringwald uint16_t end_handle; 936bdecec7SMatthias Ringwald 946bdecec7SMatthias Ringwald // characteristic 956bdecec7SMatthias Ringwald uint16_t properties; 966bdecec7SMatthias Ringwald uint16_t value_handle; 976bdecec7SMatthias Ringwald 987594dd72SMilanka Ringwald #ifdef ENABLE_TESTING_SUPPORT 997594dd72SMilanka Ringwald uint16_t ccc_handle; 1007594dd72SMilanka Ringwald #endif 1017594dd72SMilanka Ringwald 1026bdecec7SMatthias Ringwald gatt_client_notification_t notification_listener; 1036bdecec7SMatthias Ringwald } battery_service_t; 1046bdecec7SMatthias Ringwald 1056bdecec7SMatthias Ringwald 1066bdecec7SMatthias Ringwald typedef struct { 1076bdecec7SMatthias Ringwald btstack_linked_item_t item; 1086bdecec7SMatthias Ringwald 1096bdecec7SMatthias Ringwald hci_con_handle_t con_handle; 1106bdecec7SMatthias Ringwald uint16_t cid; 1116bdecec7SMatthias Ringwald battery_service_client_state_t state; 1126bdecec7SMatthias Ringwald btstack_packet_handler_t client_handler; 1136bdecec7SMatthias Ringwald 1146bdecec7SMatthias Ringwald uint32_t poll_interval_ms; 1156bdecec7SMatthias Ringwald 1166bdecec7SMatthias Ringwald uint8_t num_instances; 1176bdecec7SMatthias Ringwald battery_service_t services[MAX_NUM_BATTERY_SERVICES]; 1186bdecec7SMatthias Ringwald 1196bdecec7SMatthias Ringwald // used for discovering characteristics and polling 1206d1993e0SMilanka Ringwald uint8_t service_index; 1216bdecec7SMatthias Ringwald uint8_t poll_bitmap; 1226bdecec7SMatthias Ringwald uint8_t need_poll_bitmap; 1236bdecec7SMatthias Ringwald uint8_t polled_service_index; 1246bdecec7SMatthias Ringwald btstack_timer_source_t poll_timer; 1256bdecec7SMatthias Ringwald } battery_service_client_t; 1266bdecec7SMatthias Ringwald 1276bdecec7SMatthias Ringwald /* API_START */ 1286bdecec7SMatthias Ringwald 1296bdecec7SMatthias Ringwald 1306bdecec7SMatthias Ringwald /** 1316bdecec7SMatthias Ringwald * @brief Initialize Battery Service. 1326bdecec7SMatthias Ringwald */ 1336bdecec7SMatthias Ringwald void battery_service_client_init(void); 1346bdecec7SMatthias Ringwald 1356bdecec7SMatthias Ringwald /** 1366bdecec7SMatthias Ringwald * @brief Connect to Battery Services of remote device. The client will try to register for notifications. 1376bdecec7SMatthias Ringwald * If notifications are not supported by remote Battery Service, the client will poll battery level 1386bdecec7SMatthias Ringwald * If poll_interval_ms is 0, polling is disabled, and only notifications will be received. 1396bdecec7SMatthias Ringwald * In either case, the battery level is received via GATTSERVICE_SUBEVENT_BATTERY_SERVICE_LEVEL event. 1406bdecec7SMatthias 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, 1416bdecec7SMatthias Ringwald * see ATT errors (see bluetooth.h) for other values. 1426bdecec7SMatthias Ringwald * 1436bdecec7SMatthias Ringwald * For manual polling, see battery_service_client_read_battery_level below. 1446bdecec7SMatthias Ringwald * 1456bdecec7SMatthias Ringwald * Event GATTSERVICE_SUBEVENT_BATTERY_SERVICE_CONNECTED is emitted with status ERROR_CODE_SUCCESS on success, otherwise 1466bdecec7SMatthias 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). 1476bdecec7SMatthias Ringwald * This event event also returns number of battery instances found on remote server, as well as poll bitmap that indicates which indexes 1486bdecec7SMatthias Ringwald * of services require polling, i.e. they do not support notification on battery level change, 1496bdecec7SMatthias Ringwald * 1506bdecec7SMatthias Ringwald * @param con_handle 1516bdecec7SMatthias Ringwald * @param packet_handler 1526bdecec7SMatthias Ringwald * @param poll_interval_ms or 0 to disable polling 1536bdecec7SMatthias Ringwald * @param battery_service_cid 1546bdecec7SMatthias 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 1556bdecec7SMatthias Ringwald */ 1566bdecec7SMatthias 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); 1576bdecec7SMatthias Ringwald 1586bdecec7SMatthias Ringwald /** 1596bdecec7SMatthias Ringwald * @brief Read battery level for service with given index. Event GATTSERVICE_SUBEVENT_BATTERY_SERVICE_LEVEL is 1606bdecec7SMatthias Ringwald * received with battery level (unit is in percentage, i.e. 100 = full). The battery level is valid if the ATTT status 1616bdecec7SMatthias Ringwald * is equal to ATT_ERROR_SUCCESS, see ATT errors (see bluetooth.h) for other values. 1626bdecec7SMatthias Ringwald * @param battery_service_cid 1636bdecec7SMatthias Ringwald * @param service_index 1646bdecec7SMatthias Ringwald * @return status 1656bdecec7SMatthias Ringwald */ 1666bdecec7SMatthias Ringwald uint8_t battery_service_client_read_battery_level(uint16_t battery_service_cid, uint8_t service_index); 1676bdecec7SMatthias Ringwald 1686bdecec7SMatthias Ringwald /** 1696bdecec7SMatthias Ringwald * @brief Disconnect from Battery Service. 1706bdecec7SMatthias Ringwald * @param battery_service_cid 1716bdecec7SMatthias Ringwald * @return status 1726bdecec7SMatthias Ringwald */ 1736bdecec7SMatthias Ringwald uint8_t battery_service_client_disconnect(uint16_t battery_service_cid); 1746bdecec7SMatthias Ringwald 1756bdecec7SMatthias Ringwald /** 1766bdecec7SMatthias Ringwald * @brief De-initialize Battery Service. 1776bdecec7SMatthias Ringwald */ 1786bdecec7SMatthias Ringwald void battery_service_client_deinit(void); 1796bdecec7SMatthias Ringwald 1806bdecec7SMatthias Ringwald /* API_END */ 1816bdecec7SMatthias Ringwald 1826bdecec7SMatthias Ringwald #if defined __cplusplus 1836bdecec7SMatthias Ringwald } 1846bdecec7SMatthias Ringwald #endif 1856bdecec7SMatthias Ringwald 1866bdecec7SMatthias Ringwald #endif 187