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