• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  ****************************************************************************************
3  *
4  * @file ndcs.c
5  *
6  * @brief Next DST Change Service 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 "ndcs.h"
43 #include "ble_prf_types.h"
44 #include "ble_prf_utils.h"
45 #include "utility.h"
46 
47 #define INDEX_7 7
48 /*
49  * ENUMERATIONS
50  ****************************************************************************************
51  */
52 /**@brief Next DST Change Service Attributes Indexes. */
53 enum {
54     // Next DST Change Service
55     NDCS_IDX_SVC,
56 
57     // Time with DST
58     NDCS_IDX_TIME_DST_CHAR,
59     NDCS_IDX_TIME_DST_VAL,
60 
61     NDCS_IDX_NB
62 };
63 
64 /*
65  * STRUCTURES
66  *****************************************************************************************
67  */
68 /**@brief Next DST Change Service environment variable. */
69 struct ndcs_env_t {
70     uint16_t        char_mask;      /**< Mask of supported characteristics. */
71     uint16_t        start_hdl;      /**< Next DST Change Service start handle. */
72     ndcs_time_dst_t time_with_dst;  /**< Time with DST value. */
73 };
74 /*
75  * LOCAL FUNCTION DECLARATION
76  *****************************************************************************************
77  */
78 static sdk_err_t   ndcs_init(void);
79 static void        ndcs_read_att_cb(uint8_t conidx, const gatts_read_req_cb_t *p_param);
80 static void        ndcs_time_with_dst_read_handler(gatts_read_cfm_t *p_cfm, uint8_t *p_encode_buffer);
81 
82 /*
83  * LOCAL VARIABLE DEFINITIONS
84  *****************************************************************************************
85  */
86 static struct ndcs_env_t s_ndcs_env;
87 
88 /**@brief Full NDCS Database Description - Used to add attributes into the database. */
89 static const attm_desc_t ndcs_attr_tab[NDCS_IDX_NB] = {
90     // NDCS Service Declaration
91     [NDCS_IDX_SVC] = {BLE_ATT_DECL_PRIMARY_SERVICE, READ_PERM_UNSEC, 0, 0},
92 
93     // Time with DST Characteristic Declaration
94     [NDCS_IDX_TIME_DST_CHAR]    = {BLE_ATT_DECL_CHARACTERISTIC, READ_PERM_UNSEC, 0, 0},
95     // Time with DST Characteristic Declaration value
96     [NDCS_IDX_TIME_DST_VAL]     = {
97         BLE_ATT_CHAR_TIME_WITH_DST,
98         READ_PERM(AUTH),
99         ATT_VAL_LOC_USER,
100         NDCS_TIME_WITH_DST_VAL_LEN
101     },
102 };
103 
104 /**@brief NDCS Task interface required by profile manager. */
105 static ble_prf_manager_cbs_t ndcs_tack_cbs = {
106     (prf_init_func_t) ndcs_init,
107     NULL,
108     NULL
109 };
110 
111 /**@brief NDCS Task Callbacks. */
112 static gatts_prf_cbs_t ndcs_cb_func = {
113     ndcs_read_att_cb,
114     NULL,
115     NULL,
116     NULL
117 };
118 
119 /**@brief NDCS Information. */
120 static const prf_server_info_t ndcs_prf_info = {
121     .max_connection_nb = NDCS_CONNECTION_MAX,
122     .manager_cbs       = &ndcs_tack_cbs,
123     .gatts_prf_cbs     = &ndcs_cb_func
124 };
125 
126 /*
127  * LOCAL FUNCTION DEFINITIONS
128  *****************************************************************************************
129  */
130 /**
131  *****************************************************************************************
132  * @brief Initialize Next DST Change service and create db in att
133  *
134  * @return Error code to know if profile initialization succeed or not.
135  *****************************************************************************************
136  */
ndcs_init(void)137 static sdk_err_t ndcs_init(void)
138 {
139     // The start hanlde must be set with PRF_INVALID_HANDLE to be allocated automatically by BLE Stack.
140     uint16_t          start_hdl      = PRF_INVALID_HANDLE;
141     const uint8_t     ndcs_svc_uuid[] = BLE_ATT_16_TO_16_ARRAY(BLE_ATT_SVC_NEXT_DST_CHANGE);
142     sdk_err_t         error_code;
143     gatts_create_db_t gatts_db;
144 
145     error_code = memset_s(&gatts_db, sizeof(gatts_db), 0, sizeof(gatts_db));
146     if (error_code < 0) {
147         return error_code;
148     }
149 
150     gatts_db.shdl                 = &start_hdl;
151     gatts_db.uuid                 = ndcs_svc_uuid;
152     gatts_db.attr_tab_cfg         = (uint8_t *)&(s_ndcs_env.char_mask);
153     gatts_db.max_nb_attr          = NDCS_IDX_NB;
154     gatts_db.srvc_perm            = 0;
155     gatts_db.attr_tab_type        = SERVICE_TABLE_TYPE_16;
156     gatts_db.attr_tab.attr_tab_16 = ndcs_attr_tab;
157 
158     error_code = ble_gatts_srvc_db_create(&gatts_db);
159     if (SDK_SUCCESS == error_code) {
160         s_ndcs_env.start_hdl = *gatts_db.shdl;
161     }
162 
163     return error_code;
164 }
165 
166 /**
167  *****************************************************************************************
168  * @brief Handles reception of the attribute info request message.
169  *
170  * @param[in] conn_idx: Connection index
171  * @param[in] p_param:  The parameters of the read request.
172  *****************************************************************************************
173  */
ndcs_read_att_cb(uint8_t conn_idx,const gatts_read_req_cb_t * p_param)174 static void ndcs_read_att_cb(uint8_t conn_idx, const gatts_read_req_cb_t *p_param)
175 {
176     gatts_read_cfm_t  cfm;
177     uint8_t           handle    = p_param->handle;
178     uint8_t           tab_index = prf_find_idx_by_handle(handle,
179                                   s_ndcs_env.start_hdl,
180                                   NDCS_IDX_NB,
181                                   (uint8_t *)&s_ndcs_env.char_mask);
182     cfm.handle = handle;
183     cfm.status = BLE_SUCCESS;
184 
185     switch (tab_index) {
186         case NDCS_IDX_TIME_DST_VAL: {
187             uint8_t encoded_buffer[NDCS_TIME_WITH_DST_VAL_LEN];
188             ndcs_time_with_dst_read_handler(&cfm, encoded_buffer);
189             break;
190         }
191 
192         default:
193             cfm.length = 0;
194             cfm.status = BLE_ATT_ERR_INVALID_HANDLE;
195             break;
196     }
197 
198     ble_gatts_read_cfm(conn_idx, &cfm);
199 }
200 
201 /**
202  *****************************************************************************************
203  * @brief Handle Time with DSP Time read event.
204  *
205  * @param[out] p_cfm:           Pointer to GATT read attribute result description.
206  * @param[out] p_encode_buffer: Pointer to encoded data will be written.
207  *****************************************************************************************
208  */
ndcs_time_with_dst_read_handler(gatts_read_cfm_t * p_cfm,uint8_t * p_encode_buffer)209 static void ndcs_time_with_dst_read_handler(gatts_read_cfm_t *p_cfm, uint8_t *p_encode_buffer)
210 {
211     prf_pack_date_time(p_encode_buffer, &s_ndcs_env.time_with_dst.date_time);
212 
213     p_encode_buffer[INDEX_7] = s_ndcs_env.time_with_dst.dst_offset;
214 
215     p_cfm->length = NDCS_TIME_WITH_DST_VAL_LEN;
216     p_cfm->value  = p_encode_buffer;
217 }
218 
219 /*
220  * GLOBAL FUNCTION DEFINITIONS
221  *****************************************************************************************
222  */
ndcs_day_time_update(prf_date_time_t * p_day_time)223 void ndcs_day_time_update(prf_date_time_t *p_day_time)
224 {
225     uint8_t ret;
226 
227     ret = memcpy_s(&s_ndcs_env.time_with_dst.date_time, sizeof(prf_date_time_t),
228                    p_day_time, sizeof(prf_date_time_t));
229     if (ret < 0) {
230         return ret;
231     }
232 }
233 
ndcs_dst_offset_update(ndcs_dst_offset_t dst_offset)234 void ndcs_dst_offset_update(ndcs_dst_offset_t dst_offset)
235 {
236     s_ndcs_env.time_with_dst.dst_offset = dst_offset;
237 }
238 
ndcs_service_init(uint8_t char_mask)239 sdk_err_t ndcs_service_init(uint8_t char_mask)
240 {
241     s_ndcs_env.char_mask = char_mask;
242 
243     return ble_server_prf_add(&ndcs_prf_info);
244 }
245