• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  ****************************************************************************************
3  *
4  * @file gls_db.c
5  *
6  * @brief Glucose Service Database 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 "gls_db.h"
43 
44 /*
45  * STRUCTURES
46  *****************************************************************************************
47  */
48 /**@brief Glucose Service record structure. */
49 struct gls_db_single_rec_t {
50     bool        is_recorded;
51     gls_rec_t   record;
52 };
53 
54 /**@brief Glucose Service Database environment variable. */
55 struct gls_db_env_t {
56     struct gls_db_single_rec_t  database[GLS_DB_RECORDS_MAX];  /**< Glucose Service measurement values \
57                                                                     records database. */
58     uint8_t                     rec_index[GLS_DB_RECORDS_MAX]; /**< Glucose Service measurement values record indexs. */
59     uint16_t                    num_records;     /**< Number of  measurement values records in database. */
60 };
61 
62 /*
63  * LOCAL VARIABLE DEFINITIONS
64  ****************************************************************************************
65  */
66 static struct gls_db_env_t s_gls_db_env;
67 
68 /*
69  * LOCAL FUNCTION DEFINITIONS
70  ****************************************************************************************
71  */
72 /**
73  *****************************************************************************************
74  * @brief Get number of records which are less or equal to setting value.
75  *
76  * @param[in] p_filter: Pointer to filter parameters.
77  *
78  * @return Number of records.
79  *****************************************************************************************
80  */
gls_db_le_or_eq_record_num_get(gls_racp_filter_t * p_filter)81 uint16_t gls_db_le_or_eq_record_num_get(gls_racp_filter_t *p_filter)
82 {
83     gls_rec_t gls_res;
84     uint16_t  num_get = 0;
85 
86     for (uint8_t i = 0; i < s_gls_db_env.num_records; i++) {
87         if (!gls_db_record_get(i, &gls_res)) {
88             return num_get;
89         }
90         if (GLS_RACP_FILTER_SEQ_NUMBER == p_filter->racp_filter_type) {
91             if (p_filter->val.seq_num.max >= gls_res.meas_val.sequence_number) {
92                 num_get++;
93             }
94         } else if (GLS_RACP_FILTER_USER_FACING_TIME == p_filter->racp_filter_type) {
95             if (-1 != gls_racp_user_time_compare(&p_filter->val.time.max,
96                                                  &gls_res.meas_val.base_time)) {
97                 num_get++;
98             }
99         }
100     }
101 
102     return num_get;
103 }
104 
105 /**
106  *****************************************************************************************
107  * @brief Get number of records which are greater or equal to setting value.
108  *
109  * @param[in] p_filter: Pointer to filter parameters.
110  *
111  * @return Number of records.
112  *****************************************************************************************
113  */
gls_db_gt_or_eq_record_num_get(gls_racp_filter_t * p_filter)114 uint16_t gls_db_gt_or_eq_record_num_get(gls_racp_filter_t *p_filter)
115 {
116     gls_rec_t gls_res;
117     uint16_t  num_get = 0;
118 
119     for (uint8_t i = 0; i < s_gls_db_env.num_records; i++) {
120         if (gls_db_record_get(i, &gls_res)) {
121             return num_get;
122         }
123         if (GLS_RACP_FILTER_SEQ_NUMBER == p_filter->racp_filter_type) {
124             if (p_filter->val.seq_num.min <= gls_res.meas_val.sequence_number) {
125                 num_get++;
126             }
127         } else if (GLS_RACP_FILTER_USER_FACING_TIME == p_filter->racp_filter_type) {
128             if (-1 != gls_racp_user_time_compare(&gls_res.meas_val.base_time,
129                                                  &p_filter->val.time.min)) {
130                 num_get++;
131             }
132         }
133     }
134 }
135 
136 /**
137  *****************************************************************************************
138  * @brief Get number of records which are within range of setting value.
139  *
140  * @param[in] p_filter: Pointer to filter parameters.
141  *
142  * @return Number of records.
143  *****************************************************************************************
144  */
gls_db_within_range_record_num_get(gls_racp_filter_t * p_filter)145 uint16_t gls_db_within_range_record_num_get(gls_racp_filter_t *p_filter)
146 {
147     gls_rec_t gls_res;
148     uint16_t  num_get = 0;
149 
150     for (uint8_t i = 0; i < s_gls_db_env.num_records; i++) {
151         if (gls_db_record_get(i, &gls_res)) {
152             return num_get;
153         }
154         if (GLS_RACP_FILTER_SEQ_NUMBER == p_filter->racp_filter_type) {
155             if ((gls_res.meas_val.sequence_number >= p_filter->val.seq_num.min) && \
156                     (gls_res.meas_val.sequence_number <= p_filter->val.seq_num.max)) {
157                 num_get++;
158             }
159         } else if (GLS_RACP_FILTER_USER_FACING_TIME == p_filter->racp_filter_type) {
160             if ((-1 != gls_racp_user_time_compare(&gls_res.meas_val.base_time, &p_filter->val.time.min)) && \
161                     (-1 != gls_racp_user_time_compare(&p_filter->val.time.max, &gls_res.meas_val.base_time))) {
162                 num_get++;
163             }
164         }
165     }
166 
167     return num_get;
168 }
169 
170 /*
171  * GLOBAL FUNCTION DEFINITIONS
172  ****************************************************************************************
173  */
gls_db_init(void)174 void gls_db_init(void)
175 {
176     for (uint8_t i = 0; i < GLS_DB_RECORDS_MAX; i++) {
177         s_gls_db_env.database[i].is_recorded = false;
178         s_gls_db_env.rec_index[i]            = 0xFF;
179     }
180 
181     s_gls_db_env.num_records = 0;
182 }
183 
gls_db_record_add(gls_rec_t * p_rec)184 bool gls_db_record_add(gls_rec_t *p_rec)
185 {
186     uint8_t i = 0;
187 
188     if (GLS_DB_RECORDS_MAX <= s_gls_db_env.num_records) {
189         return false;
190     }
191 
192     for (i = 0; i < GLS_DB_RECORDS_MAX; i++) {
193         if (!s_gls_db_env.database[i].is_recorded) {
194             s_gls_db_env.database[i].is_recorded = true;
195             s_gls_db_env.database[i].record      = *p_rec;
196             s_gls_db_env.rec_index[s_gls_db_env.num_records] = i;
197             s_gls_db_env.num_records++;
198             return true;
199         }
200     }
201 
202     return false;
203 }
204 
gls_db_record_delete(uint8_t rec_idx)205 bool gls_db_record_delete(uint8_t rec_idx)
206 {
207     if (rec_idx >= s_gls_db_env.num_records) {
208         return false;
209     }
210 
211     s_gls_db_env.database[s_gls_db_env.rec_index[rec_idx]].is_recorded = false;
212 
213     s_gls_db_env.num_records--;
214 
215     for (uint8_t i = rec_idx; i < s_gls_db_env.num_records; i++) {
216         s_gls_db_env.rec_index[i] = s_gls_db_env.rec_index[i + 1];
217     }
218 
219     return true;
220 }
221 
gls_db_records_num_get(void)222 uint16_t gls_db_records_num_get(void)
223 {
224     return s_gls_db_env.num_records;
225 }
226 
gls_db_filter_records_num_get(gls_racp_filter_t * p_filter)227 uint16_t gls_db_filter_records_num_get(gls_racp_filter_t *p_filter)
228 {
229     uint16_t  num_get = 0;
230 
231     switch (p_filter->racp_operator) {
232         case GLS_RACP_OPERATOR_ALL_RECS:
233             num_get = s_gls_db_env.num_records;
234             break;
235 
236         case GLS_RACP_OPERATOR_LE_OR_EQ:
237             num_get = gls_db_le_or_eq_record_num_get(p_filter);
238             break;
239 
240         case GLS_RACP_OPERATOR_GT_OR_EQ:
241             num_get = gls_db_gt_or_eq_record_num_get(p_filter);
242             break;
243 
244         case GLS_RACP_OPERATOR_WITHIN_RANGE_OF:
245             num_get = gls_db_within_range_record_num_get(p_filter);
246             break;
247 
248         case GLS_RACP_OPERATOR_FIRST_REC:
249         case GLS_RACP_OPERATOR_LAST_REC:
250             if (s_gls_db_env.num_records != 0) {
251                 num_get = 1;
252             }
253             break;
254 
255         default:
256             break;
257     }
258 
259     return num_get;
260 }
261 
gls_db_record_get(uint8_t rec_idx,gls_rec_t * p_rec)262 bool gls_db_record_get(uint8_t rec_idx, gls_rec_t *p_rec)
263 {
264     if (rec_idx >= s_gls_db_env.num_records) {
265         return false;
266     }
267 
268     *p_rec = s_gls_db_env.database[s_gls_db_env.rec_index[rec_idx]].record;
269 
270     return true;
271 }
272 
gls_db_record_clear(void)273 void gls_db_record_clear(void)
274 {
275     for (uint8_t i = 0; i < GLS_DB_RECORDS_MAX; i++) {
276         s_gls_db_env.database[i].is_recorded = false;
277         s_gls_db_env.rec_index[i]            = 0xFF;
278     }
279 
280     s_gls_db_env.num_records = 0;
281 }
282 
283