1 /**
2  * Copyright (c) 2019 Oticon A/S
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 /**
7  * @brief Service B.3
8  *
9  *  This code is auto-generated from the Excel Workbook
10  *  'GATT_Test_Databases.xlsm' Sheet: 'Large Database 2'
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 /**
20  *  @brief UUID for the Service B.3
21  */
22 #define BT_UUID_SERVICE_B_3             BT_UUID_DECLARE_16(0xa00b)
23 
24 /**
25  *  @brief UUID for the Value V6 Characteristic
26  */
27 #define BT_UUID_VALUE_V6                BT_UUID_DECLARE_16(0xb006)
28 
29 static uint8_t   value_v6_value = 0x06;
30 static struct bt_gatt_indicate_params ind_params;
31 static bool   value_v6_ntf_active;
32 static bool   value_v6_ind_active;
33 
34 /**
35  * @brief Attribute read call back for the Value V6 attribute
36  *
37  * @param conn   The connection that is requesting to read
38  * @param attr   The attribute that's being read
39  * @param buf    Buffer to place the read result in
40  * @param len    Length of data to read
41  * @param offset Offset to start reading from
42  *
43  * @return       Number of bytes read, or in case of an error - BT_GATT_ERR()
44  *               with a specific ATT error code.
45  */
read_value_v6(struct bt_conn * conn,const struct bt_gatt_attr * attr,void * buf,uint16_t len,uint16_t offset)46 static ssize_t read_value_v6(struct bt_conn *conn,
47 			     const struct bt_gatt_attr *attr, void *buf,
48 			     uint16_t len, uint16_t offset)
49 {
50 	const uint8_t *value = attr->user_data;
51 
52 	return bt_gatt_attr_read(conn, attr, buf, len, offset, value,
53 				 sizeof(value_v6_value));
54 }
55 
56 /**
57  * @brief Attribute write call back for the Value V6 attribute
58  *
59  * @param conn   The connection that is requesting to write
60  * @param attr   The attribute that's being written
61  * @param buf    Buffer with the data to write
62  * @param len    Number of bytes in the buffer
63  * @param offset Offset to start writing from
64  * @param flags  Flags (BT_GATT_WRITE_*)
65  *
66  * @return       Number of bytes written, or in case of an error - BT_GATT_ERR()
67  *               with a specific ATT error code.
68  */
write_value_v6(struct bt_conn * conn,const struct bt_gatt_attr * attr,const void * buf,uint16_t len,uint16_t offset,uint8_t flags)69 static ssize_t write_value_v6(struct bt_conn *conn,
70 			      const struct bt_gatt_attr *attr, const void *buf,
71 			      uint16_t len, uint16_t offset, uint8_t flags)
72 {
73 	uint8_t *value = attr->user_data;
74 
75 	if (offset >= sizeof(value_v6_value)) {
76 		return BT_GATT_ERR(BT_ATT_ERR_INVALID_OFFSET);
77 	}
78 	if (offset + len > sizeof(value_v6_value)) {
79 		return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN);
80 	}
81 
82 	memcpy(value + offset, buf, len);
83 
84 	return len;
85 }
86 
87 /**
88  * @brief Descriptor configuration change call back for the Value V6 attribute
89  *
90  * @param attr  The attribute whose descriptor configuration has changed
91  * @param value The new value of the descriptor configuration
92  */
value_v6_ccc_cfg_changed(const struct bt_gatt_attr * attr,uint16_t value)93 static void value_v6_ccc_cfg_changed(const struct bt_gatt_attr *attr,
94 				     uint16_t value)
95 {
96 	value_v6_ntf_active = value == BT_GATT_CCC_NOTIFY;
97 	value_v6_ind_active = value == BT_GATT_CCC_INDICATE;
98 }
99 
100 static struct bt_gatt_attr service_b_3_2_attrs[] = {
101 	BT_GATT_H_PRIMARY_SERVICE(BT_UUID_SERVICE_B_3, 0x70),
102 	BT_GATT_H_CHARACTERISTIC(BT_UUID_VALUE_V6,
103 		BT_GATT_CHRC_READ | BT_GATT_CHRC_WRITE_WITHOUT_RESP |
104 		BT_GATT_CHRC_WRITE | BT_GATT_CHRC_NOTIFY |
105 		BT_GATT_CHRC_INDICATE,
106 		BT_GATT_PERM_READ | BT_GATT_PERM_WRITE,
107 		read_value_v6, write_value_v6, &value_v6_value, 0x71),
108 	BT_GATT_H_CCC(value_v6_ccc_cfg, value_v6_ccc_cfg_changed, 0x73)
109 };
110 
111 static struct bt_gatt_service service_b_3_2_svc =
112 		    BT_GATT_SERVICE(service_b_3_2_attrs);
113 
114 /**
115  * @brief Register the Service B.3 and all its Characteristics...
116  */
service_b_3_2_init(void)117 void service_b_3_2_init(void)
118 {
119 	bt_gatt_service_register(&service_b_3_2_svc);
120 }
121 
122 /**
123  * @brief Un-Register the Service B.3 and all its Characteristics...
124  */
service_b_3_2_remove(void)125 void service_b_3_2_remove(void)
126 {
127 	bt_gatt_service_unregister(&service_b_3_2_svc);
128 }
129 
130 /**
131  * @brief Generate notification for 'Value V6' attribute, if notifications are
132  *        enabled.
133  */
service_b_3_2_value_v6_notify(void)134 void service_b_3_2_value_v6_notify(void)
135 {
136 	if (!value_v6_ntf_active) {
137 		return;
138 	}
139 
140 	bt_gatt_notify(NULL, &service_b_3_2_attrs[1], &value_v6_value,
141 		       sizeof(value_v6_value));
142 }
143 
144 /**
145  * @brief Indication call back for 'Value V6' attribute
146  *
147  * @param conn The connection for which the indication was generated
148  * @param attr The attribute that generated the indication
149  * @param err  The error code from the indicate attempt, 0 if no error or
150  *             BT_GATT_ERR() with a specific ATT error code.
151  */
value_v6_indicate_cb(struct bt_conn * conn,struct bt_gatt_indicate_params * params,uint8_t err)152 static void value_v6_indicate_cb(struct bt_conn *conn,
153 				 struct bt_gatt_indicate_params *params,
154 				 uint8_t err)
155 {
156 	printk("Indication for attribute 'Value V6' %s\n",
157 	       (err) ? "failed" : "succeded");
158 }
159 
160 /**
161  * @brief Generate indication for 'Value V6' attribute, if indications are
162  *        enabled.
163  */
service_b_3_2_value_v6_indicate(void)164 void service_b_3_2_value_v6_indicate(void)
165 {
166 	if (!value_v6_ind_active) {
167 		return;
168 	}
169 	/*
170 	 * NOTE: Zephyr doesn't automatically bump up the attribute pointer for
171 	 *   indications as it does for notifications.
172 	 */
173 	ind_params.attr = &service_b_3_2_attrs[2];
174 	ind_params.func = value_v6_indicate_cb;
175 	ind_params.destroy = NULL;
176 	ind_params.data = &value_v6_value;
177 	ind_params.len = sizeof(value_v6_value);
178 
179 	bt_gatt_indicate(NULL, &ind_params);
180 }
181