1dbba0e652e0ce23dd691df3c03979ec6e32c8db3Matthew Xie/****************************************************************************** 2dbba0e652e0ce23dd691df3c03979ec6e32c8db3Matthew Xie * 3dbba0e652e0ce23dd691df3c03979ec6e32c8db3Matthew Xie * Copyright (C) 1999-2013 Broadcom Corporation 4dbba0e652e0ce23dd691df3c03979ec6e32c8db3Matthew Xie * 5dbba0e652e0ce23dd691df3c03979ec6e32c8db3Matthew Xie * Licensed under the Apache License, Version 2.0 (the "License"); 6dbba0e652e0ce23dd691df3c03979ec6e32c8db3Matthew Xie * you may not use this file except in compliance with the License. 7dbba0e652e0ce23dd691df3c03979ec6e32c8db3Matthew Xie * You may obtain a copy of the License at: 8dbba0e652e0ce23dd691df3c03979ec6e32c8db3Matthew Xie * 9dbba0e652e0ce23dd691df3c03979ec6e32c8db3Matthew Xie * http://www.apache.org/licenses/LICENSE-2.0 10dbba0e652e0ce23dd691df3c03979ec6e32c8db3Matthew Xie * 11dbba0e652e0ce23dd691df3c03979ec6e32c8db3Matthew Xie * Unless required by applicable law or agreed to in writing, software 12dbba0e652e0ce23dd691df3c03979ec6e32c8db3Matthew Xie * distributed under the License is distributed on an "AS IS" BASIS, 13dbba0e652e0ce23dd691df3c03979ec6e32c8db3Matthew Xie * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14dbba0e652e0ce23dd691df3c03979ec6e32c8db3Matthew Xie * See the License for the specific language governing permissions and 15dbba0e652e0ce23dd691df3c03979ec6e32c8db3Matthew Xie * limitations under the License. 16dbba0e652e0ce23dd691df3c03979ec6e32c8db3Matthew Xie * 17dbba0e652e0ce23dd691df3c03979ec6e32c8db3Matthew Xie ******************************************************************************/ 182e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach 192e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach#include "bt_target.h" 205cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen#include "bt_utils.h" 21911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson#include "btcore/include/uuid.h" 222e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach#include "gatt_api.h" 232e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach#include "gatt_int.h" 24d7ffd64accbd50a27289a388856e56244ccbb5daMyles Watson#include "osi/include/osi.h" 25911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson#include "srvc_battery_int.h" 26911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson#include "srvc_eng_int.h" 272e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach 28911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson#define BA_MAX_CHAR_NUM 1 299ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson 309ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson/* max 3 descriptors, 1 desclration and 1 value */ 31911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson#define BA_MAX_ATTR_NUM (BA_MAX_CHAR_NUM * 5 + 1) 322e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach 332e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach#ifndef BATTER_LEVEL_PROP 34911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson#define BATTER_LEVEL_PROP (GATT_CHAR_PROP_BIT_READ | GATT_CHAR_PROP_BIT_NOTIFY) 352e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach#endif 362e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach 372e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach#ifndef BATTER_LEVEL_PERM 38911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson#define BATTER_LEVEL_PERM (GATT_PERM_READ) 392e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach#endif 402e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach 412e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre EisenbachtBATTERY_CB battery_cb; 422e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach 432e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach/******************************************************************************* 44ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * battery_valid_handle_range 45ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 46ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * validate a handle to be a DIS attribute handle or not. 47ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/ 48911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonbool battery_valid_handle_range(uint16_t handle) { 49911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson uint8_t i = 0; 50911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson tBA_INST* p_inst = &battery_cb.battery_inst[0]; 51911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 52911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson for (; i < BA_MAX_INT_NUM; i++, p_inst++) { 53911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (handle == p_inst->ba_level_hdl || handle == p_inst->clt_cfg_hdl || 54911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson handle == p_inst->rpt_ref_hdl || handle == p_inst->pres_fmt_hdl) { 55911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson return true; 562e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach } 57911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 58911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson return false; 592e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach} 602e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach/******************************************************************************* 61ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * battery_s_write_attr_value 62ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 63ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Process write DIS attribute request. 64ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/ 65911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonuint8_t battery_s_write_attr_value(uint8_t clcb_idx, tGATT_WRITE_REQ* p_value, 66911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson tGATT_STATUS* p_status) { 67911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson uint8_t *p = p_value->value, i; 68911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson uint16_t handle = p_value->handle; 69911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson tBA_INST* p_inst = &battery_cb.battery_inst[0]; 70911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson tGATT_STATUS st = GATT_NOT_FOUND; 71911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson tBA_WRITE_DATA cfg; 72911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson uint8_t act = SRVC_ACT_RSP; 73911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 74911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson for (i = 0; i < BA_MAX_INT_NUM; i++, p_inst++) { 75911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson /* read battery level */ 76911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (handle == p_inst->clt_cfg_hdl) { 77911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson memcpy(cfg.remote_bda, srvc_eng_cb.clcb[clcb_idx].bda, BD_ADDR_LEN); 78911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson STREAM_TO_UINT16(cfg.clt_cfg, p); 79911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 80911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (p_inst->p_cback) { 81911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_inst->pending_clcb_idx = clcb_idx; 82911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_inst->pending_evt = BA_WRITE_CLT_CFG_REQ; 83911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_inst->pending_handle = handle; 84911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson cfg.need_rsp = p_value->need_rsp; 85911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson act = SRVC_ACT_PENDING; 86911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 87911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson (*p_inst->p_cback)(p_inst->app_id, BA_WRITE_CLT_CFG_REQ, &cfg); 88911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 89911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } else /* all other handle is not writable */ 902e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach { 91911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson st = GATT_WRITE_NOT_PERMIT; 92911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson break; 932e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach } 94911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 95911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson *p_status = st; 962e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach 97911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson return act; 982e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach} 992e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach/******************************************************************************* 100ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * BA Attributes Database Server Request callback 101ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/ 102911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonuint8_t battery_s_read_attr_value(uint8_t clcb_idx, uint16_t handle, 103911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson UNUSED_ATTR tGATT_VALUE* p_value, 104911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson bool is_long, tGATT_STATUS* p_status) { 105911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson uint8_t i; 106911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson tBA_INST* p_inst = &battery_cb.battery_inst[0]; 107911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson tGATT_STATUS st = GATT_NOT_FOUND; 108911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson uint8_t act = SRVC_ACT_RSP; 109911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 110911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson for (i = 0; i < BA_MAX_INT_NUM; i++, p_inst++) { 111911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson /* read battery level */ 112911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (handle == p_inst->ba_level_hdl || handle == p_inst->clt_cfg_hdl || 113911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson handle == p_inst->rpt_ref_hdl || handle == p_inst->pres_fmt_hdl) { 114911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (is_long) st = GATT_NOT_LONG; 115911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 116911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (p_inst->p_cback) { 117911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (handle == p_inst->ba_level_hdl) 118911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_inst->pending_evt = BA_READ_LEVEL_REQ; 119911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (handle == p_inst->clt_cfg_hdl) 120911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_inst->pending_evt = BA_READ_CLT_CFG_REQ; 121911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (handle == p_inst->pres_fmt_hdl) 122911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_inst->pending_evt = BA_READ_PRE_FMT_REQ; 123911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (handle == p_inst->rpt_ref_hdl) 124911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_inst->pending_evt = BA_READ_RPT_REF_REQ; 125911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 126911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_inst->pending_clcb_idx = clcb_idx; 127911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_inst->pending_handle = handle; 128911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson act = SRVC_ACT_PENDING; 129911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 130911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson (*p_inst->p_cback)(p_inst->app_id, p_inst->pending_evt, NULL); 131911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } else /* application is not registered */ 132911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson st = GATT_ERR_UNLIKELY; 133911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson break; 1342e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach } 135911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson /* else attribute not found */ 136911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 1372e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach 138911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson *p_status = st; 139911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson return act; 1402e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach} 1412e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach 1422e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach/******************************************************************************* 143ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 144ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function battery_gatt_c_read_ba_req 145ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 146ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description Read remote device BA level attribute request. 147ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 148ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns void 149ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 150ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/ 151911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonbool battery_gatt_c_read_ba_req(UNUSED_ATTR uint16_t conn_id) { return true; } 1522e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach 1532e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach/******************************************************************************* 154ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 155ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function battery_c_cmpl_cback 156ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 157ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description Client operation complete callback. 158ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 159ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns void 160ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 161ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/ 162911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid battery_c_cmpl_cback(UNUSED_ATTR tSRVC_CLCB* p_clcb, 163911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson UNUSED_ATTR tGATTC_OPTYPE op, 164911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson UNUSED_ATTR tGATT_STATUS status, 165911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson UNUSED_ATTR tGATT_CL_COMPLETE* p_data) {} 1662e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach 1672e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach/******************************************************************************* 168ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 169ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function Battery_Instantiate 170ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 171ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description Instantiate a Battery service 172ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 173ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/ 174911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonuint16_t Battery_Instantiate(uint8_t app_id, tBA_REG_INFO* p_reg_info) { 175911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson uint16_t srvc_hdl = 0; 176911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson tGATT_STATUS status = GATT_ERROR; 177911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson tBA_INST* p_inst; 178911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 179911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (battery_cb.inst_id == BA_MAX_INT_NUM) { 180911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson GATT_TRACE_ERROR("MAX battery service has been reached"); 181911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson return 0; 182911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 183911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 184911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_inst = &battery_cb.battery_inst[battery_cb.inst_id]; 185911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 186911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson btgatt_db_element_t service[BA_MAX_ATTR_NUM] = {}; 187911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 188911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson bt_uuid_t service_uuid; 189911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson uuid_128_from_16(&service_uuid, UUID_SERVCLASS_BATTERY); 190911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson service[0].type = /* p_reg_info->is_pri */ BTGATT_DB_PRIMARY_SERVICE; 191911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson service[0].uuid = service_uuid; 192911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 193911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson bt_uuid_t char_uuid; 194911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson uuid_128_from_16(&char_uuid, GATT_UUID_BATTERY_LEVEL); 195911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson service[1].type = BTGATT_DB_CHARACTERISTIC; 196911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson service[1].uuid = char_uuid; 197911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson service[1].properties = GATT_CHAR_PROP_BIT_READ; 198911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (p_reg_info->ba_level_descr & BA_LEVEL_NOTIFY) 199911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson service[1].properties |= GATT_CHAR_PROP_BIT_NOTIFY; 200911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 201911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson int i = 2; 202911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (p_reg_info->ba_level_descr & BA_LEVEL_NOTIFY) { 203911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson bt_uuid_t desc_uuid; 204911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson uuid_128_from_16(&desc_uuid, GATT_UUID_CHAR_CLIENT_CONFIG); 205911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 206911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson service[i].type = BTGATT_DB_DESCRIPTOR; 207911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson service[i].uuid = desc_uuid; 208911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson service[i].permissions = (GATT_PERM_READ | GATT_PERM_WRITE); 209911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson i++; 210911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 211911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 212911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson /* need presentation format descriptor? */ 213911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (p_reg_info->ba_level_descr & BA_LEVEL_PRE_FMT) { 214911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson bt_uuid_t desc_uuid; 215911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson uuid_128_from_16(&desc_uuid, GATT_UUID_CHAR_PRESENT_FORMAT); 216911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 217911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson service[i].type = BTGATT_DB_DESCRIPTOR; 218911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson service[i].uuid = desc_uuid; 219911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson service[i].permissions = GATT_PERM_READ; 220911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson i++; 221911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 222911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 223911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson /* need presentation format descriptor? */ 224911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (p_reg_info->ba_level_descr & BA_LEVEL_RPT_REF) { 225911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson bt_uuid_t desc_uuid; 226911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson uuid_128_from_16(&desc_uuid, GATT_UUID_RPT_REF_DESCR); 227911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 228911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson service[i].type = BTGATT_DB_DESCRIPTOR; 229911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson service[i].uuid = desc_uuid; 230911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson service[i].permissions = GATT_PERM_READ; 231911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson i++; 232911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 233911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 234911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson GATTS_AddService(srvc_eng_cb.gatt_if, service, i); 235911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 236911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (status != GATT_SUCCESS) { 237911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson battery_cb.inst_id--; 238911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson GATT_TRACE_ERROR("%s: Failed to add battery servuce!", __func__); 239911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 240911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 241911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson battery_cb.inst_id++; 242911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 243911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_inst->app_id = app_id; 244911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_inst->p_cback = p_reg_info->p_cback; 245911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 246911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson srvc_hdl = service[0].attribute_handle; 247911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_inst->ba_level_hdl = service[1].attribute_handle; 248911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 249911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson i = 2; 250911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (p_reg_info->ba_level_descr & BA_LEVEL_NOTIFY) { 251911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_inst->clt_cfg_hdl = service[i].attribute_handle; 252911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson i++; 253911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 254911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 255911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (p_reg_info->ba_level_descr & BA_LEVEL_PRE_FMT) { 256911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_inst->pres_fmt_hdl = service[i].attribute_handle; 257911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson i++; 258911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 259911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 260911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (p_reg_info->ba_level_descr & BA_LEVEL_RPT_REF) { 261911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_inst->rpt_ref_hdl = service[i].attribute_handle; 262911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson i++; 263911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 264911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 265911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson return srvc_hdl; 2662e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach} 2672e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach/******************************************************************************* 268ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 269ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function Battery_Rsp 270ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 271ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description Respond to a battery service request 272ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 273ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/ 274911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid Battery_Rsp(uint8_t app_id, tGATT_STATUS st, uint8_t event, 275911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson tBA_RSP_DATA* p_rsp) { 276911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson tBA_INST* p_inst = &battery_cb.battery_inst[0]; 277911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson tGATTS_RSP rsp; 278911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson uint8_t* pp; 279911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 280911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson uint8_t i = 0; 281911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson while (i < BA_MAX_INT_NUM) { 282911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (p_inst->app_id == app_id && p_inst->ba_level_hdl != 0) break; 283911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson i++; 284911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 285911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 286911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (i == BA_MAX_INT_NUM) return; 287911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 288911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson memset(&rsp, 0, sizeof(tGATTS_RSP)); 289911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 290911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (p_inst->pending_evt == event) { 291911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson switch (event) { 292911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson case BA_READ_CLT_CFG_REQ: 293911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson rsp.attr_value.handle = p_inst->pending_handle; 294911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson rsp.attr_value.len = 2; 295911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson pp = rsp.attr_value.value; 296911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson UINT16_TO_STREAM(pp, p_rsp->clt_cfg); 297911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson srvc_sr_rsp(p_inst->pending_clcb_idx, st, &rsp); 298911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson break; 299911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 300911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson case BA_READ_LEVEL_REQ: 301911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson rsp.attr_value.handle = p_inst->pending_handle; 302911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson rsp.attr_value.len = 1; 303911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson pp = rsp.attr_value.value; 304911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson UINT8_TO_STREAM(pp, p_rsp->ba_level); 305911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson srvc_sr_rsp(p_inst->pending_clcb_idx, st, &rsp); 306911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson break; 307911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 308911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson case BA_WRITE_CLT_CFG_REQ: 309911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson srvc_sr_rsp(p_inst->pending_clcb_idx, st, NULL); 310911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson break; 311911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 312911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson case BA_READ_RPT_REF_REQ: 313911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson rsp.attr_value.handle = p_inst->pending_handle; 314911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson rsp.attr_value.len = 2; 315911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson pp = rsp.attr_value.value; 316911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson UINT8_TO_STREAM(pp, p_rsp->rpt_ref.rpt_id); 317911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson UINT8_TO_STREAM(pp, p_rsp->rpt_ref.rpt_type); 318911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson srvc_sr_rsp(p_inst->pending_clcb_idx, st, &rsp); 319911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson break; 320911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 321911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson default: 322911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson break; 3232e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach } 324911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_inst->pending_clcb_idx = 0; 325911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_inst->pending_evt = 0; 326911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_inst->pending_handle = 0; 327911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 328911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson return; 3292e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach} 3302e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach/******************************************************************************* 331ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 332ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function Battery_Notify 333ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 334ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description Send battery level notification 335ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 336ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/ 337911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid Battery_Notify(uint8_t app_id, BD_ADDR remote_bda, uint8_t battery_level) { 338911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson tBA_INST* p_inst = &battery_cb.battery_inst[0]; 339911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson uint8_t i = 0; 3402e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach 341911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson while (i < BA_MAX_INT_NUM) { 342911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (p_inst->app_id == app_id && p_inst->ba_level_hdl != 0) break; 343911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson i++; 344911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 3452e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach 346911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (i == BA_MAX_INT_NUM || p_inst->clt_cfg_hdl == 0) return; 3472e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach 348911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson srvc_sr_notify(remote_bda, p_inst->ba_level_hdl, 1, &battery_level); 3492e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach} 3502e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach/******************************************************************************* 351ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 352ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function Battery_ReadBatteryLevel 353ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 354ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description Read remote device Battery Level information. 355ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 356ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns void 357ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 358ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/ 359911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonbool Battery_ReadBatteryLevel(UNUSED_ATTR BD_ADDR peer_bda) { 360911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson /* to be implemented */ 361911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson return true; 3622e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach} 363