1 /**
2 *****************************************************************************************
3 *
4 * @file ias.c
5 *
6 * @brief Tx Power Server Implementation.
7 *
8 *****************************************************************************************
9 * @attention
10 #####Copyright (c) 2019 GOODIX
11 All rights reserved.
12
13 Redistribution and use in source and binary forms, with or without
14 modification, are permitted provided that the following conditions are met:
15 * Redistributions of source code must retain the above copyright
16 notice, this list of conditions and the following disclaimer.
17 * Redistributions in binary form must reproduce the above copyright
18 notice, this list of conditions and the following disclaimer in the
19 documentation and/or other materials provided with the distribution.
20 * Neither the name of GOODIX nor the names of its contributors may be used
21 to endorse or promote products derived from this software without
22 specific prior written permission.
23
24 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
25 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
28 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
32 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34 POSSIBILITY OF SUCH DAMAGE.
35 *****************************************************************************************
36 */
37
38 /*
39 * INCLUDE FILES
40 *****************************************************************************************
41 */
42 #include "tps.h"
43 #include "ble_prf_types.h"
44 #include "ble_prf_utils.h"
45 #include "utility.h"
46 #define OFFSET_100 100
47 #define OFFSET_20 20
48 /*
49 * ENUMERATIONS
50 *****************************************************************************************
51 */
52 /**@brief Tx Power Service attributes index. */
53 enum tps_attr_idx_tag {
54 TPS_IDX_SVC,
55
56 TPS_IDX_TX_POWER_LVL_CHAR,
57 TPS_IDX_TX_POWER_LVL_VAL,
58
59 TPS_IDX_NB,
60 };
61
62 /*
63 * STRUCTURES
64 *****************************************************************************************
65 */
66 /**@brief Tx Power Service environment variable. */
67 struct tps_env_t {
68 tps_init_t tps_init; /**< Tx Power Service initialization variables. */
69 uint16_t start_hdl; /**< Tx Power Service start handle. */
70 };
71
72 /*
73 * LOCAL VARIABLE DEFINITIONS
74 *****************************************************************************************
75 */
76 static struct tps_env_t s_tps_env; /**< Tx Power Service initialization variables. */
77 static uint8_t s_char_mask = 0x07; /**< Features added into ATT database.
78 * bit0 - Tx Power Service Declaration
79 * bit1 - Tx Power Level Characteristic Declaration
80 * bit2 - Tx Power Level Characteristic Value
81 */
82
83 /**@brief TPS Database Description - Used to add attributes into the database. */
84 static const attm_desc_t tps_attr_tab[TPS_IDX_NB] = {
85 // Tx Power Service Declaration
86 [TPS_IDX_SVC] = {BLE_ATT_DECL_PRIMARY_SERVICE, READ_PERM_UNSEC, 0, 0},
87 // Tx Power Level Characteristic Declaration
88 [TPS_IDX_TX_POWER_LVL_CHAR] = {BLE_ATT_DECL_CHARACTERISTIC, READ_PERM_UNSEC, 0, 0},
89 // Tx Power Level Characteristic Value
90 [TPS_IDX_TX_POWER_LVL_VAL] = {BLE_ATT_CHAR_TX_POWER_LEVEL, READ_PERM_UNSEC, 0, sizeof(int8_t)},
91 };
92
93 /*
94 * LOCAL FUNCTION DECLARATIONS
95 *****************************************************************************************
96 */
97 static sdk_err_t tps_init(void);
98
99 /**@brief TPS Task interface required by profile manager. */
100 static ble_prf_manager_cbs_t tps_mgr_cbs = {
101 (prf_init_func_t)tps_init,
102 NULL,
103 NULL
104 };
105
106 /**@brief TPS GATT server Callbacks. */
107 static gatts_prf_cbs_t tps_gatts_cbs = {
108 NULL,
109 NULL,
110 NULL,
111 NULL
112 };
113
114 /**@brief TPS Information. */
115 static const prf_server_info_t tps_prf_info = {
116 /* There shall be only one connection on a device */
117 .max_connection_nb = 1,
118 .manager_cbs = &tps_mgr_cbs,
119 .gatts_prf_cbs = &tps_gatts_cbs
120 };
121
122 /*
123 * LOCAL FUNCTION DEFINITIONS
124 *****************************************************************************************
125 */
126 /**
127 *****************************************************************************************
128 * @brief Initialize TP service and create db in BLE Stack.
129 *
130 * @return BLE_ATT_ERR_NO_ERROR on success, otherwise error code.
131 *****************************************************************************************
132 */
tps_init(void)133 static sdk_err_t tps_init(void)
134 {
135 const uint8_t tps_svc_uuid[] = BLE_ATT_16_TO_16_ARRAY(BLE_ATT_SVC_TX_POWER);
136 gatts_create_db_t gatts_db;
137 sdk_err_t ret;
138 uint16_t start_hdl = PRF_INVALID_HANDLE; /* The start hanlde is an in/out
139 * parameter of ble_gatts_srvc_db_create().
140 * It must be set with PRF_INVALID_HANDLE
141 * to be allocated automatically by BLE Stack. */
142
143 ret = memset_s(&gatts_db, sizeof(gatts_db), 0, sizeof(gatts_db));
144 if (ret < 0) {
145 return ret;
146 }
147
148 gatts_db.shdl = &start_hdl;
149 gatts_db.uuid = (uint8_t *)tps_svc_uuid;
150 gatts_db.attr_tab_cfg = &s_char_mask;
151 gatts_db.max_nb_attr = TPS_IDX_NB;
152 gatts_db.srvc_perm = 0;
153 gatts_db.attr_tab_type = SERVICE_TABLE_TYPE_16;
154 gatts_db.attr_tab.attr_tab_16 = tps_attr_tab;
155
156 sdk_err_t error_code = ble_gatts_srvc_db_create(&gatts_db);
157 if (SDK_SUCCESS == error_code) {
158 s_tps_env.start_hdl = *gatts_db.shdl;
159
160 uint16_t handle = prf_find_handle_by_idx(TPS_IDX_TX_POWER_LVL_VAL, s_tps_env.start_hdl, &s_char_mask);
161 ble_gatts_value_set(handle, sizeof(uint8_t), 0, (uint8_t *)&s_tps_env.tps_init.initial_tx_power_level);
162 }
163
164 return error_code;
165 }
166
167 /*
168 * GLOBAL FUNCTION DEFINITIONS
169 *****************************************************************************************
170 */
tps_service_init(tps_init_t * p_tps_init)171 sdk_err_t tps_service_init(tps_init_t *p_tps_init)
172 {
173 if (p_tps_init == NULL) {
174 return SDK_ERR_POINTER_NULL;
175 }
176
177 s_tps_env.tps_init.initial_tx_power_level = p_tps_init->initial_tx_power_level;
178
179 return ble_server_prf_add(&tps_prf_info);
180 }
181
tps_tx_power_level_set(int8_t tx_power_level)182 sdk_err_t tps_tx_power_level_set(int8_t tx_power_level)
183 {
184 if (tx_power_level < -OFFSET_100 || tx_power_level > OFFSET_20) {
185 return SDK_ERR_INVALID_PARAM;
186 } else {
187 uint16_t handle = prf_find_handle_by_idx(TPS_IDX_TX_POWER_LVL_VAL, s_tps_env.start_hdl, &s_char_mask);
188
189 return ble_gatts_value_set(handle, sizeof(int8_t), 0, (uint8_t *)&tx_power_level);
190 }
191 }
192
193