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