1 /**
2  * Copyright (c) 2019 Oticon A/S
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 /**
7  * @brief Service A
8  *
9  *  This code is auto-generated from the Excel Workbook
10  *  'GATT_Test_Databases.xlsm' Sheet: 'Large Database 1'
11  */
12 #include <zephyr/sys/byteorder.h>
13 #include <zephyr/sys/printk.h>
14 
15 #include <zephyr/bluetooth/gatt.h>
16 
17 #include "gatt_macs.h"
18 
19 extern struct bt_gatt_attr service_d_1_attrs[];
20 
21 /**
22  *  @brief UUID for the Service A
23  */
24 #define BT_UUID_SERVICE_A               BT_UUID_DECLARE_16(0xa00a)
25 
26 /**
27  *  @brief UUID for the Value V1 Characteristic
28  */
29 #define BT_UUID_VALUE_V1                BT_UUID_DECLARE_16(0xb001)
30 
31 /**
32  *  @brief UUID for the Value V2 Characteristic
33  */
34 #define BT_UUID_VALUE_V2                BT_UUID_DECLARE_16(0xb002)
35 
36 /**
37  *  @brief UUID for the Value V3 Characteristic
38  */
39 #define BT_UUID_VALUE_V3                BT_UUID_DECLARE_16(0xb003)
40 
41 static uint8_t   value_v1_value = 0x01;
42 static uint8_t   value_v2_value[] = {
43 	      '1', '1', '1', '1', '1', '2', '2', '2', '2', '2', '3', '3', '3',
44 	      '3', '3', '4', '4', '4', '4', '4', '5', '5', '5', '5', '5', '6',
45 	      '6', '6', '6', '6', '7', '7', '7', '7', '7', '8', '8', '8', '8',
46 	      '8', '9', '9', '9', '9', '9', '0', '0', '0', '0', '0', '1', '1',
47 	      '1', '1', '1', '2', '2', '2', '2', '2', '3', '3', '3', '3', '3',
48 	      '4', '4', '4', '4', '4', '5', '5', '5', '5', '5', '6', '6', '6',
49 	      '6', '6', '7', '7', '7', '7', '7', '8', '8', '8', '8', '8', '9',
50 	      '9', '9', '9', '9', '0', '0', '0', '0', '0', '1', '1', '1', '1',
51 	      '1', '2', '2', '2', '2', '2', '3', '3', '3', '3', '3', '4', '4',
52 	      '4', '4', '4', '5', '5', '5', '5', '5', '6', '6', '6', '6', '6',
53 	      '7', '7', '7', '7', '7', '8', '8', '8', '8', '8', '9', '9', '9',
54 	      '9', '9', '0', '0', '0', '0', '0', '1', '1', '1', '1', '1', '2',
55 	      '2', '2', '2', '2', '3', '3', '3', '3', '3', '4', '4', '4', '4',
56 	      '4', '5', '5', '5', '5', '5', '6', '6', '6', '6', '6', '7', '7',
57 	      '7', '7', '7', '8', '8', '8', '8', '8', '9', '9', '9', '9', '9',
58 	      '0', '0', '0', '0', '0', '1', '1', '1', '1', '1', '2', '2', '2',
59 	      '2', '2', '3', '3', '3', '3', '3', '4', '4', '4', '4', '4', '5',
60 	      '5', '5', '5', '5', '6', '6', '6', '6', '6', '7', '7', '7', '7',
61 	      '7', '8', '8', '8', '8', '8', '9', '9', '9', '9', '9', '0', '0',
62 	      '0', '0', '0', '1', '1', '1', '1', '1', '2', '2', '2', '2', '2',
63 	      '3', '3', '3', '3', '3', '4', '4', '4', '4', '4', '5', '5', '5',
64 	      '5', '5', '6', '6', '6', '6', '6', '7', '7', '7', '7', '7', '8',
65 	      '8', '8', '8', '8', '9', '9', '9', '9', '9', '0', '0', '0', '0',
66 	      '0', '1', '1', '1', '1', '1', '2', '2', '2', '2', '2', '3', '3',
67 	      '3', '3', '3', '4', '4', '4', '4', '4', '5', '5', '5', '5', '5',
68 	      '6', '6', '6', '6', '6', '7', '7', '7', '7', '7', '8', '8', '8',
69 	      '8', '8', '9', '9', '9', '9', '9', '0', '0', '0', '0', '0', '1',
70 	      '1', '1', '1', '1', '2', '2', '2', '2', '2', '3', '3', '3', '3',
71 	      '3', '4', '4', '4', '4', '4', '5', '5', '5', '5', '5', '6', '6',
72 	      '6', '6', '6', '7', '7', '7', '7', '7', '8', '8', '8', '8', '8',
73 	      '9', '9', '9', '9', '9', '0', '0', '0', '0', '0', '1', '1', '1',
74 	      '1', '1', '2', '2', '2', '2', '2', '3', '3', '3', '3', '3', '4',
75 	      '4', '4', '4', '4', '5', '5', '5', '5', '5', '6', '6', '6', '6',
76 	      '6', '7', '7', '7', '7', '7', '8', '8', '8', '8', '8', '9', '9',
77 	      '9', '9', '9', '0', '0', '0', '0', '0', '1', '1', '1', '1', '1',
78 	      '2', '2', '2', '2', '2', '3', '3', '3', '3', '3', '4', '4', '4',
79 	      '4', '4', '5', '5', '5', '5', '5', '6', '6', '6', '6', '6', '7',
80 	      '7', '7', '7', '7', '8', '8', '8', '8', '8', '9', '9', '9', '9',
81 	      '9', '0', '0', '0', '0', '0', '1', '2', '3', '4', '5', '6', '7',
82 	      '8', '9', '0', '1', '2', '\0'
83 };
84 static uint8_t   value_v2_1_value[] = {
85 	      '1', '1', '1', '1', '1', '2', '2', '2', '2', '2', '3', '3', '3',
86 	      '3', '3', '4', '4', '4', '4', '4', '5', '5', '5', '5', '5', '6',
87 	      '6', '6', '6', '6', '7', '7', '7', '7', '7', '8', '8', '8', '8',
88 	      '8', '9', '9', '9', '9', '9', '0', '0', '0', '0', '0', '\0'
89 };
90 static uint8_t   value_v3_value = 0x03;
91 
92 /**
93  * @brief Attribute read call back for the Value V1 attribute
94  *
95  * @param conn   The connection that is requesting to read
96  * @param attr   The attribute that's being read
97  * @param buf    Buffer to place the read result in
98  * @param len    Length of data to read
99  * @param offset Offset to start reading from
100  *
101  * @return       Number of bytes read, or in case of an error - BT_GATT_ERR()
102  *               with a specific ATT error code.
103  */
read_value_v1(struct bt_conn * conn,const struct bt_gatt_attr * attr,void * buf,uint16_t len,uint16_t offset)104 static ssize_t read_value_v1(struct bt_conn *conn,
105 			     const struct bt_gatt_attr *attr, void *buf,
106 			     uint16_t len, uint16_t offset)
107 {
108 	const uint8_t *value = attr->user_data;
109 
110 	return bt_gatt_attr_read(conn, attr, buf, len, offset, value,
111 				 sizeof(value_v1_value));
112 }
113 
114 /**
115  * @brief Attribute read call back for the Value V2 string attribute
116  *
117  * @param conn   The connection that is requesting to read
118  * @param attr   The attribute that's being read
119  * @param buf    Buffer to place the read result in
120  * @param len    Length of data to read
121  * @param offset Offset to start reading from
122  *
123  * @return       Number of bytes read, or in case of an error - BT_GATT_ERR()
124  *               with a specific ATT error code.
125  */
read_str_value(struct bt_conn * conn,const struct bt_gatt_attr * attr,void * buf,uint16_t len,uint16_t offset)126 static ssize_t read_str_value(struct bt_conn *conn,
127 			      const struct bt_gatt_attr *attr, void *buf,
128 			      uint16_t len, uint16_t offset)
129 {
130 	const char *value = attr->user_data;
131 
132 	return bt_gatt_attr_read(conn, attr, buf, len, offset, value,
133 				 strlen(value));
134 }
135 
136 /**
137  * @brief Attribute write call back for the Value V2 attribute
138  *
139  * @param conn   The connection that is requesting to write
140  * @param attr   The attribute that's being written
141  * @param buf    Buffer with the data to write
142  * @param len    Number of bytes in the buffer
143  * @param offset Offset to start writing from
144  * @param flags  Flags (BT_GATT_WRITE_*)
145  *
146  * @return       Number of bytes written, or in case of an error - BT_GATT_ERR()
147  *               with a specific ATT error code.
148  */
write_value_v2(struct bt_conn * conn,const struct bt_gatt_attr * attr,const void * buf,uint16_t len,uint16_t offset,uint8_t flags)149 static ssize_t write_value_v2(struct bt_conn *conn,
150 			      const struct bt_gatt_attr *attr, const void *buf,
151 			      uint16_t len, uint16_t offset, uint8_t flags)
152 {
153 	char *value = attr->user_data;
154 
155 	if (offset >= sizeof(value_v2_value)) {
156 		return BT_GATT_ERR(BT_ATT_ERR_INVALID_OFFSET);
157 	}
158 	if (offset + len > sizeof(value_v2_value)) {
159 		return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN);
160 	}
161 
162 	memcpy(value + offset, buf, len);
163 
164 	return len;
165 }
166 
167 /**
168  * @brief Attribute write call back for the Value V2 attribute
169  *
170  * @param conn   The connection that is requesting to write
171  * @param attr   The attribute that's being written
172  * @param buf    Buffer with the data to write
173  * @param len    Number of bytes in the buffer
174  * @param offset Offset to start writing from
175  * @param flags  Flags (BT_GATT_WRITE_*)
176  *
177  * @return       Number of bytes written, or in case of an error - BT_GATT_ERR()
178  *               with a specific ATT error code.
179  */
write_value_v2_1(struct bt_conn * conn,const struct bt_gatt_attr * attr,const void * buf,uint16_t len,uint16_t offset,uint8_t flags)180 static ssize_t write_value_v2_1(struct bt_conn *conn,
181 				const struct bt_gatt_attr *attr,
182 				const void *buf, uint16_t len, uint16_t offset,
183 				uint8_t flags)
184 {
185 	char *value = attr->user_data;
186 
187 	if (offset >= sizeof(value_v2_1_value)) {
188 		return BT_GATT_ERR(BT_ATT_ERR_INVALID_OFFSET);
189 	}
190 	if (offset + len > sizeof(value_v2_1_value)) {
191 		return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN);
192 	}
193 
194 	memcpy(value + offset, buf, len);
195 
196 	return len;
197 }
198 
199 /**
200  * @brief Attribute write call back for the Value V3 attribute
201  *
202  * @param conn   The connection that is requesting to write
203  * @param attr   The attribute that's being written
204  * @param buf    Buffer with the data to write
205  * @param len    Number of bytes in the buffer
206  * @param offset Offset to start writing from
207  * @param flags  Flags (BT_GATT_WRITE_*)
208  *
209  * @return       Number of bytes written, or in case of an error - BT_GATT_ERR()
210  *               with a specific ATT error code.
211  */
write_value_v3(struct bt_conn * conn,const struct bt_gatt_attr * attr,const void * buf,uint16_t len,uint16_t offset,uint8_t flags)212 static ssize_t write_value_v3(struct bt_conn *conn,
213 			      const struct bt_gatt_attr *attr, const void *buf,
214 			      uint16_t len, uint16_t offset, uint8_t flags)
215 {
216 	uint8_t *value = attr->user_data;
217 
218 	if (offset >= sizeof(value_v3_value)) {
219 		return BT_GATT_ERR(BT_ATT_ERR_INVALID_OFFSET);
220 	}
221 	if (offset + len > sizeof(value_v3_value)) {
222 		return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN);
223 	}
224 
225 	memcpy(value + offset, buf, len);
226 
227 	return len;
228 }
229 
230 static struct bt_gatt_attr service_a_1_attrs[] = {
231 	BT_GATT_H_PRIMARY_SERVICE(BT_UUID_SERVICE_A, 0x20),
232 	BT_GATT_H_INCLUDE_SERVICE(service_d_1_attrs, 0x21),
233 	BT_GATT_H_CHARACTERISTIC(BT_UUID_VALUE_V1,
234 		BT_GATT_CHRC_READ,
235 		BT_GATT_PERM_READ_ENCRYPT,
236 		read_value_v1, NULL, &value_v1_value, 0x22),
237 	BT_GATT_H_CHARACTERISTIC(BT_UUID_VALUE_V2,
238 		BT_GATT_CHRC_READ | BT_GATT_CHRC_WRITE,
239 		BT_GATT_PERM_READ | BT_GATT_PERM_WRITE,
240 		read_str_value, write_value_v2, &value_v2_value, 0x24),
241 	BT_GATT_H_CHARACTERISTIC(BT_UUID_VALUE_V2,
242 		BT_GATT_CHRC_WRITE,
243 		BT_GATT_PERM_WRITE,
244 		NULL, write_value_v2_1, &value_v2_1_value, 0x26),
245 	BT_GATT_H_CHARACTERISTIC(BT_UUID_VALUE_V3,
246 		BT_GATT_CHRC_WRITE,
247 		BT_GATT_PERM_WRITE,
248 		NULL, write_value_v3, &value_v3_value, 0x28)
249 };
250 
251 static struct bt_gatt_service service_a_1_svc =
252 		    BT_GATT_SERVICE(service_a_1_attrs);
253 
254 /**
255  * @brief Register the Service A and all its Characteristics...
256  */
service_a_1_init(void)257 void service_a_1_init(void)
258 {
259 	bt_gatt_service_register(&service_a_1_svc);
260 }
261 
262 /**
263  * @brief Un-Register the Service A and all its Characteristics...
264  */
service_a_1_remove(void)265 void service_a_1_remove(void)
266 {
267 	bt_gatt_service_unregister(&service_a_1_svc);
268 }
269