1 /** @file
2  *  @brief Internal APIs for Bluetooth AICS.
3  */
4 
5 /*
6  * Copyright (c) 2020 Bose Corporation
7  * Copyright (c) 2020 Nordic Semiconductor ASA
8  *
9  * SPDX-License-Identifier: Apache-2.0
10  */
11 
12 #ifndef ZEPHYR_INCLUDE_BLUETOOTH_AUDIO_AICS_INTERNAL_
13 #define ZEPHYR_INCLUDE_BLUETOOTH_AUDIO_AICS_INTERNAL_
14 #include <stdbool.h>
15 #include <stdint.h>
16 
17 #include <zephyr/autoconf.h>
18 #include <zephyr/bluetooth/bluetooth.h>
19 #include <zephyr/bluetooth/gatt.h>
20 #include <zephyr/kernel.h>
21 #include <zephyr/sys/atomic.h>
22 #include <zephyr/types.h>
23 
24 #if defined(CONFIG_BT_AICS)
25 #define BT_AICS_MAX_DESC_SIZE CONFIG_BT_AICS_MAX_INPUT_DESCRIPTION_SIZE
26 #else
27 #define BT_AICS_MAX_DESC_SIZE 1
28 #endif /* CONFIG_BT_AICS */
29 
30 /* AICS opcodes */
31 #define BT_AICS_OPCODE_SET_GAIN                    0x01
32 #define BT_AICS_OPCODE_UNMUTE                      0x02
33 #define BT_AICS_OPCODE_MUTE                        0x03
34 #define BT_AICS_OPCODE_SET_MANUAL                  0x04
35 #define BT_AICS_OPCODE_SET_AUTO                    0x05
36 
37 /* AICS status */
38 #define BT_AICS_STATUS_INACTIVE                    0x00
39 #define BT_AICS_STATUS_ACTIVE                      0x01
40 
41 #define BT_AICS_INPUT_MODE_IMMUTABLE(gain_mode) \
42 	((gain_mode) == BT_AICS_MODE_MANUAL_ONLY || (gain_mode) == BT_AICS_MODE_AUTO_ONLY)
43 
44 #define BT_AICS_INPUT_MODE_SETTABLE(gain_mode) \
45 	((gain_mode) == BT_AICS_MODE_AUTO || (gain_mode) == BT_AICS_MODE_MANUAL)
46 
47 struct bt_aics_control {
48 	uint8_t opcode;
49 	uint8_t counter;
50 } __packed;
51 
52 struct bt_aics_gain_control {
53 	struct bt_aics_control cp;
54 	int8_t gain_setting;
55 } __packed;
56 
57 enum bt_aics_client_flag {
58 	BT_AICS_CLIENT_FLAG_BUSY,
59 	BT_AICS_CLIENT_FLAG_CP_RETRIED,
60 	BT_AICS_CLIENT_FLAG_DESC_WRITABLE,
61 	BT_AICS_CLIENT_FLAG_ACTIVE,
62 
63 	BT_AICS_CLIENT_FLAG_NUM_FLAGS, /* keep as last */
64 };
65 
66 struct bt_aics_client {
67 	uint8_t change_counter;
68 	uint8_t gain_mode;
69 
70 	uint16_t start_handle;
71 	uint16_t end_handle;
72 	uint16_t state_handle;
73 	uint16_t gain_handle;
74 	uint16_t type_handle;
75 	uint16_t status_handle;
76 	uint16_t control_handle;
77 	uint16_t desc_handle;
78 	struct bt_gatt_subscribe_params state_sub_params;
79 	struct bt_gatt_subscribe_params status_sub_params;
80 	struct bt_gatt_subscribe_params desc_sub_params;
81 
82 	struct bt_aics_gain_control cp_val;
83 	struct bt_gatt_write_params write_params;
84 	struct bt_gatt_read_params read_params;
85 	struct bt_gatt_discover_params discover_params;
86 	struct bt_aics_cb *cb;
87 	struct bt_conn *conn;
88 
89 	ATOMIC_DEFINE(flags, BT_AICS_CLIENT_FLAG_NUM_FLAGS);
90 };
91 
92 struct bt_aics_state {
93 	int8_t gain;
94 	uint8_t mute;
95 	uint8_t gain_mode;
96 	uint8_t change_counter;
97 } __packed;
98 
99 struct bt_aics_gain_settings {
100 	uint8_t units;
101 	int8_t minimum;
102 	int8_t maximum;
103 } __packed;
104 
105 enum bt_aics_notify {
106 	AICS_NOTIFY_STATE,
107 	AICS_NOTIFY_DESCRIPTION,
108 	AICS_NOTIFY_STATUS,
109 	AICS_NOTIFY_NUM,
110 };
111 
112 struct bt_aics_server {
113 	struct bt_aics_state state;
114 	struct bt_aics_gain_settings gain_settings;
115 	bool initialized;
116 	uint8_t type;
117 	uint8_t status;
118 	struct bt_aics *inst;
119 	char description[BT_AICS_MAX_DESC_SIZE];
120 	struct bt_aics_cb *cb;
121 
122 	struct bt_gatt_service *service_p;
123 
124 	ATOMIC_DEFINE(notify, AICS_NOTIFY_NUM);
125 	struct k_work_delayable notify_work;
126 };
127 
128 /* Struct used as a common type for the api */
129 struct bt_aics {
130 	bool client_instance;
131 	union {
132 		struct bt_aics_server srv;
133 		struct bt_aics_client cli;
134 	};
135 
136 };
137 
138 uint8_t aics_client_notify_handler(struct bt_conn *conn,
139 				   struct bt_gatt_subscribe_params *params,
140 				   const void *data, uint16_t length);
141 int bt_aics_client_register(struct bt_aics *inst);
142 int bt_aics_client_unregister(struct bt_aics *inst);
143 int bt_aics_client_state_get(struct bt_aics *inst);
144 int bt_aics_client_gain_setting_get(struct bt_aics *inst);
145 int bt_aics_client_type_get(struct bt_aics *inst);
146 int bt_aics_client_status_get(struct bt_aics *inst);
147 int bt_aics_client_unmute(struct bt_aics *inst);
148 int bt_aics_client_mute(struct bt_aics *inst);
149 int bt_aics_client_manual_gain_set(struct bt_aics *inst);
150 int bt_aics_client_automatic_gain_set(struct bt_aics *inst);
151 int bt_aics_client_gain_set(struct bt_aics *inst, int8_t gain);
152 int bt_aics_client_description_get(struct bt_aics *inst);
153 int bt_aics_client_description_set(struct bt_aics *inst,
154 				   const char *description);
155 
156 #endif /* ZEPHYR_INCLUDE_BLUETOOTH_AUDIO_AICS_INTERNAL_ */
157