• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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