1 /**
2 ****************************************************************************************
3 *
4 * @file gls_racp.c
5 *
6 * @brief Glucose Record Access Control Point 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_racp.h"
43 #include "ble_prf_utils.h"
44 #include "utility.h"
45 #define SCALE_2 2
46 #define ADD_2 2
47 /*
48 * GLOBAL FUNCTION DEFINITIONS
49 ****************************************************************************************
50 */
gls_racp_user_time_compare(prf_date_time_t * p_compared_date_time,prf_date_time_t * p_base_date_time)51 int8_t gls_racp_user_time_compare(prf_date_time_t *p_compared_date_time, prf_date_time_t *p_base_date_time)
52 {
53 if (p_compared_date_time->year < p_base_date_time->year) {
54 return -1;
55 } else if (p_compared_date_time->year > p_base_date_time->year) {
56 return 1;
57 }
58
59 if (p_compared_date_time->month < p_base_date_time->month) {
60 return -1;
61 } else if (p_compared_date_time->month > p_base_date_time->month) {
62 return 1;
63 }
64
65 if (p_compared_date_time->day < p_base_date_time->day) {
66 return -1;
67 } else if (p_compared_date_time->day > p_base_date_time->day) {
68 return 1;
69 }
70
71 if (p_compared_date_time->hour < p_base_date_time->hour) {
72 return -1;
73 } else if (p_compared_date_time->hour > p_base_date_time->hour) {
74 return 1;
75 }
76
77 if (p_compared_date_time->min < p_base_date_time->min) {
78 return -1;
79 } else if (p_compared_date_time->min > p_base_date_time->min) {
80 return 1;
81 }
82
83 if (p_compared_date_time->sec < p_base_date_time->sec) {
84 return -1;
85 } else if (p_compared_date_time->sec > p_base_date_time->sec) {
86 return 1;
87 }
88
89 return 0;
90 }
91
gls_racp_req_decode(const uint8_t * p_data,uint16_t length,gls_racp_req_t * p_racp_req)92 gls_racp_operand_t gls_racp_req_decode(const uint8_t *p_data, uint16_t length, gls_racp_req_t *p_racp_req)
93 {
94 uint8_t index = 0;
95
96 p_racp_req->op_code = (gls_racp_op_code_t)p_data[index++];
97 p_racp_req->filter.racp_operator = (gls_racp_operator_t)p_data[index++];
98
99 if ((GLS_RACP_OP_ABORT_OP != p_racp_req->op_code) && \
100 (GLS_RACP_OPERATOR_ALL_RECS > p_racp_req->filter.racp_operator)) {
101 return GLS_RACP_RSP_INVALID_OPERATOR;
102 }
103
104 if (GLS_RACP_OPERATOR_LAST_REC < p_racp_req->filter.racp_operator) {
105 return GLS_RACP_RSP_OPERATOR_NOT_SUP;
106 }
107
108 if ((GLS_RACP_OPERATOR_LE_OR_EQ <= p_racp_req->filter.racp_operator) && \
109 ((GLS_RACP_OPERATOR_WITHIN_RANGE_OF) >= p_racp_req->filter.racp_operator)) {
110 if (length <= index) {
111 return GLS_RACP_RSP_INVALID_OPERAND;
112 } else {
113 p_racp_req->filter.racp_filter_type = (gls_racp_filter_type_t)p_data[index++];
114
115 if (GLS_RACP_FILTER_SEQ_NUMBER == p_racp_req->filter.racp_filter_type) {
116 if (GLS_RACP_OPERATOR_LE_OR_EQ == p_racp_req->filter.racp_operator) {
117 if (GLS_RACP_FILTER_SEQ_NUM_LEN != (length - index)) {
118 return GLS_RACP_RSP_INVALID_OPERAND;
119 } else {
120 p_racp_req->filter.val.seq_num.max = BUILD_U16(p_data[index], p_data[index + 1]);
121 }
122 } else if (GLS_RACP_OPERATOR_GT_OR_EQ == p_racp_req->filter.racp_operator) {
123 if (GLS_RACP_FILTER_SEQ_NUM_LEN != (length - index)) {
124 return GLS_RACP_RSP_INVALID_OPERAND;
125 } else {
126 p_racp_req->filter.val.seq_num.min = BUILD_U16(p_data[index], p_data[index + 1]);
127 }
128 } else if (GLS_RACP_OPERATOR_WITHIN_RANGE_OF == p_racp_req->filter.racp_operator) {
129 if (GLS_RACP_FILTER_SEQ_NUM_LEN * SCALE_2 != (length - index)) {
130 return GLS_RACP_RSP_INVALID_OPERAND;
131 } else {
132 p_racp_req->filter.val.seq_num.min = BUILD_U16(p_data[index], p_data[index + 1]);
133 p_racp_req->filter.val.seq_num.max = BUILD_U16(p_data[index + ADD_2], p_data[index + 3]);
134
135 if (p_racp_req->filter.val.seq_num.min > p_racp_req->filter.val.seq_num.max) {
136 return GLS_RACP_RSP_INVALID_OPERAND;
137 }
138 }
139 }
140 } else if (GLS_RACP_FILTER_USER_FACING_TIME == p_racp_req->filter.racp_filter_type) {
141 if (GLS_RACP_OPERATOR_LE_OR_EQ == p_racp_req->filter.racp_operator) {
142 if (GLS_RACP_FILTER_USER_TIME_LEN != (length - index)) {
143 return GLS_RACP_RSP_INVALID_OPERAND;
144 } else {
145 prf_unpack_date_time(&p_data[index], &p_racp_req->filter.val.time.max);
146 }
147 } else if (GLS_RACP_OPERATOR_GT_OR_EQ == p_racp_req->filter.racp_operator) {
148 if (GLS_RACP_FILTER_USER_TIME_LEN != (length - index)) {
149 return GLS_RACP_RSP_INVALID_OPERAND;
150 } else {
151 prf_unpack_date_time(&p_data[index], &p_racp_req->filter.val.time.min);
152 }
153 } else if (GLS_RACP_OPERATOR_WITHIN_RANGE_OF == p_racp_req->filter.racp_operator) {
154 if (GLS_RACP_FILTER_USER_TIME_LEN * SCALE_2 != (length - index)) {
155 return GLS_RACP_RSP_INVALID_OPERAND;
156 } else {
157 index += prf_unpack_date_time(&p_data[index], &p_racp_req->filter.val.time.min);
158 prf_unpack_date_time(&p_data[index], &p_racp_req->filter.val.time.max);
159
160 if (gls_racp_user_time_compare(&p_racp_req->filter.val.time.max,
161 &p_racp_req->filter.val.time.min) != -1) {
162 return GLS_RACP_RSP_INVALID_OPERAND;
163 }
164 }
165 }
166 } else {
167 return GLS_RACP_RSP_OPERAND_NOT_SUP;
168 }
169 }
170 } else if (length - index) != 0) {
171 return GLS_RACP_RSP_INVALID_OPERAND;
172 }
173
174 return GLS_RACP_RSP_VALID_DECODE;
175 }
176
gls_racp_rsp_encode(gls_racp_rsp_t * p_racp_rsp,uint8_t * p_encoded_buffer)177 uint16_t gls_racp_rsp_encode(gls_racp_rsp_t *p_racp_rsp, uint8_t *p_encoded_buffer)
178 {
179 uint16_t length = 0;
180
181 p_encoded_buffer[length++] = p_racp_rsp->op_code;
182 p_encoded_buffer[length++] = GLS_RACP_OPERATOR_NULL;
183
184 if (GLS_RACP_OP_REP_NB_OF_STRD_RECS == p_racp_rsp->op_code) {
185 p_encoded_buffer[length++] = LO_U16(p_racp_rsp->operand.num_of_record);
186 p_encoded_buffer[length++] = HI_U16(p_racp_rsp->operand.num_of_record);
187 } else {
188 p_encoded_buffer[length++] = p_racp_rsp->operand.rsp.op_code_req;
189 p_encoded_buffer[length++] = p_racp_rsp->operand.rsp.status;
190 }
191
192 return length;
193 }
194
195