1 /**
2 *******************************************************************************
3 *
4 * @file ble_prf_utils.c
5 *
6 * @brief Implementation of Profile Utilities
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 <stdint.h>
43 #include <stdbool.h>
44 #include "utility.h"
45 #include "ble_prf_utils.h"
46
47 #define OFFSET_2 2
48 #define OFFSET_3 3
49 #define OFFSET_4 4
50 #define OFFSET_5 5
51 #define OFFSET_6 6
52 #define VALUE_7 7
53 #define VALUE_8 8
54 /*
55 * GLOBAL FUNCTION DEFINITIONS
56 *******************************************************************************
57 */
prf_pack_char_pres_fmt(uint8_t * p_packed_val,const prf_char_pres_fmt_t * p_char_pres_fmt)58 void prf_pack_char_pres_fmt(uint8_t *p_packed_val,
59 const prf_char_pres_fmt_t *p_char_pres_fmt)
60 {
61 *p_packed_val = p_char_pres_fmt->format;
62 *(p_packed_val + 1) = p_char_pres_fmt->exponent;
63
64 htole16(p_packed_val + OFFSET_2, p_char_pres_fmt->unit);
65
66 *(p_packed_val + OFFSET_4) = p_char_pres_fmt->name_space;
67
68 htole16(p_packed_val + OFFSET_5, p_char_pres_fmt->description);
69 }
70
prf_unpack_char_pres_fmt(const uint8_t * p_packed_val,prf_char_pres_fmt_t * p_char_pres_fmt)71 void prf_unpack_char_pres_fmt(const uint8_t *p_packed_val,
72 prf_char_pres_fmt_t *p_char_pres_fmt)
73 {
74 p_char_pres_fmt->format = *p_packed_val;
75 p_char_pres_fmt->exponent = *(p_packed_val + 1);
76 p_char_pres_fmt->unit = le16toh(p_packed_val + OFFSET_2);
77 p_char_pres_fmt->name_space = *(p_packed_val + OFFSET_4);
78 p_char_pres_fmt->description = le16toh(p_packed_val + OFFSET_5);
79 }
80
prf_pack_date_time(uint8_t * p_packed_val,const prf_date_time_t * p_date_time)81 uint8_t prf_pack_date_time(uint8_t *p_packed_val,
82 const prf_date_time_t *p_date_time)
83 {
84 htole16(p_packed_val, p_date_time->year);
85 *(p_packed_val + OFFSET_2) = p_date_time->month;
86 *(p_packed_val + OFFSET_3) = p_date_time->day;
87 *(p_packed_val + OFFSET_4) = p_date_time->hour;
88 *(p_packed_val + OFFSET_5) = p_date_time->min;
89 *(p_packed_val + OFFSET_6) = p_date_time->sec;
90
91 return VALUE_7;
92 }
93
prf_unpack_date_time(const uint8_t * p_packed_val,prf_date_time_t * p_date_time)94 uint8_t prf_unpack_date_time(const uint8_t *p_packed_val,
95 prf_date_time_t *p_date_time)
96 {
97 p_date_time->year = le16toh(&(p_packed_val[0]));
98 p_date_time->month = p_packed_val[OFFSET_2];
99 p_date_time->day = p_packed_val[OFFSET_3];
100 p_date_time->hour = p_packed_val[OFFSET_4];
101 p_date_time->min = p_packed_val[OFFSET_5];
102 p_date_time->sec = p_packed_val[OFFSET_6];
103
104 return VALUE_7;
105 }
106
prf_find_idx_by_handle(uint16_t handle,uint16_t start_hdl,uint8_t char_nb,uint8_t * p_char_mask)107 uint8_t prf_find_idx_by_handle(uint16_t handle, uint16_t start_hdl,
108 uint8_t char_nb, uint8_t *p_char_mask)
109 {
110 uint16_t cur_hdl = start_hdl + 1;
111 uint8_t index = 0;
112 uint8_t byte = 0;
113 uint8_t bit = 0;
114
115 for (uint8_t i = 1; i < char_nb; i++) {
116 byte = i / VALUE_8;
117 bit = i % VALUE_8;
118 if ((p_char_mask[byte] >> bit) & 0x01) {
119 // check if value handle correspond to requested handle
120 if (cur_hdl == handle) {
121 index = i;
122 break;
123 }
124 cur_hdl++;
125 }
126 }
127
128 return index;
129 }
130
prf_find_handle_by_idx(uint8_t idx,uint16_t start_hdl,uint8_t * p_char_mask)131 uint16_t prf_find_handle_by_idx(uint8_t idx, uint16_t start_hdl,
132 uint8_t *p_char_mask)
133 {
134 uint16_t found_hdl = 0x0000; // Core spec: Reserved for future use
135 uint16_t cur_hdl = start_hdl;
136 uint8_t byte = 0;
137 uint8_t bit = 0;
138
139 if (!idx) {
140 found_hdl = start_hdl;
141 return found_hdl;
142 }
143
144 for (uint8_t i = 1; i <= idx; i++) {
145 byte = i / VALUE_8;
146 bit = i % VALUE_8;
147
148 if ((p_char_mask[byte] >> bit) & 0x01) {
149 cur_hdl++;
150
151 if (i == idx) {
152 found_hdl = cur_hdl;
153 }
154 }
155 }
156
157 return found_hdl;
158 }
159
prf_is_cccd_value_valid(uint16_t cccd_value)160 bool prf_is_cccd_value_valid(uint16_t cccd_value)
161 {
162 if (PRF_CLI_STOP_NTFIND == cccd_value || \
163 PRF_CLI_START_NTF == cccd_value || \
164 PRF_CLI_START_IND == cccd_value) {
165 return true;
166 }
167
168 return false;
169 }
170
prf_is_notification_enabled(uint16_t cccd_value)171 bool prf_is_notification_enabled(uint16_t cccd_value)
172 {
173 return ((cccd_value & PRF_CLI_START_NTF) != 0);
174 }
175
prf_is_indication_enabled(uint16_t cccd_value)176 bool prf_is_indication_enabled(uint16_t cccd_value)
177 {
178 return ((cccd_value & PRF_CLI_START_IND) != 0);
179 }
180
181