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 3'
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 	if (offset + len > sizeof(value_v6_value))
78 		return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN);
79 
80 	memcpy(value + offset, buf, len);
81 
82 	return len;
83 }
84 
85 /**
86  * @brief Descriptor configuration change call back for the Value V6 attribute
87  *
88  * @param attr  The attribute whose descriptor configuration has changed
89  * @param value The new value of the descriptor configuration
90  */
value_v6_ccc_cfg_changed(const struct bt_gatt_attr * attr,uint16_t value)91 static void value_v6_ccc_cfg_changed(const struct bt_gatt_attr *attr,
92 				     uint16_t value)
93 {
94 	value_v6_ntf_active = value == BT_GATT_CCC_NOTIFY;
95 	value_v6_ind_active = value == BT_GATT_CCC_INDICATE;
96 }
97 
98 static struct bt_gatt_attr service_b_3_3_attrs[] = {
99 	BT_GATT_H_PRIMARY_SERVICE(BT_UUID_SERVICE_B_3, 0x50),
100 	BT_GATT_H_CHARACTERISTIC(BT_UUID_VALUE_V6,
101 		BT_GATT_CHRC_READ | BT_GATT_CHRC_WRITE_WITHOUT_RESP |
102 		BT_GATT_CHRC_WRITE | BT_GATT_CHRC_NOTIFY |
103 		BT_GATT_CHRC_INDICATE,
104 		BT_GATT_PERM_READ | BT_GATT_PERM_WRITE,
105 		read_value_v6, write_value_v6, &value_v6_value, 0x51),
106 	BT_GATT_H_CCC(value_v6_ccc_cfg, value_v6_ccc_cfg_changed, 0x53)
107 };
108 
109 static struct bt_gatt_service service_b_3_3_svc =
110 		    BT_GATT_SERVICE(service_b_3_3_attrs);
111 
112 /**
113  * @brief Register the Service B.3 and all its Characteristics...
114  */
service_b_3_3_init(void)115 void service_b_3_3_init(void)
116 {
117 	bt_gatt_service_register(&service_b_3_3_svc);
118 }
119 
120 /**
121  * @brief Un-Register the Service B.3 and all its Characteristics...
122  */
service_b_3_3_remove(void)123 void service_b_3_3_remove(void)
124 {
125 	bt_gatt_service_unregister(&service_b_3_3_svc);
126 }
127 
128 /**
129  * @brief Generate notification for 'Value V6' attribute, if notifications are
130  *        enabled.
131  */
service_b_3_3_value_v6_notify(void)132 void service_b_3_3_value_v6_notify(void)
133 {
134 	if (!value_v6_ntf_active) {
135 		return;
136 	}
137 
138 	bt_gatt_notify(NULL, &service_b_3_3_attrs[1], &value_v6_value,
139 		       sizeof(value_v6_value));
140 }
141 
142 /**
143  * @brief Indication call back for 'Value V6' attribute
144  *
145  * @param conn The connection for which the indication was generated
146  * @param attr The attribute that generated the indication
147  * @param err  The error code from the indicate attempt, 0 if no error or
148  *             BT_GATT_ERR() with a specific ATT error code.
149  */
value_v6_indicate_cb(struct bt_conn * conn,struct bt_gatt_indicate_params * params,uint8_t err)150 static void value_v6_indicate_cb(struct bt_conn *conn,
151 				 struct bt_gatt_indicate_params *params,
152 				 uint8_t err)
153 {
154 	printk("Indication for attribute 'Value V6' %s\n",
155 	       (err) ? "failed" : "succeeded");
156 }
157 
158 /**
159  * @brief Generate indication for 'Value V6' attribute, if indications are
160  *        enabled.
161  */
service_b_3_3_value_v6_indicate(void)162 void service_b_3_3_value_v6_indicate(void)
163 {
164 	if (!value_v6_ind_active) {
165 		return;
166 	}
167 	/*
168 	 * NOTE: Zephyr doesn't automatically bump up the attribute pointer for
169 	 *   indications as it does for notifications.
170 	 */
171 	ind_params.attr = &service_b_3_3_attrs[2];
172 	ind_params.func = value_v6_indicate_cb;
173 	ind_params.destroy = NULL;
174 	ind_params.data = &value_v6_value;
175 	ind_params.len = sizeof(value_v6_value);
176 
177 	bt_gatt_indicate(NULL, &ind_params);
178 }
179