1 /** @file
2  *  @brief Internal APIs for Bluetooth Handsfree profile handling.
3  */
4 
5 /*
6  * Copyright (c) 2015-2016 Intel Corporation
7  * Copyright 2024 NXP
8  *
9  * SPDX-License-Identifier: Apache-2.0
10  */
11 
12 #include "hfp_internal.h"
13 
14 #if defined(CONFIG_BT_HFP_AG_EXT_ERR)
15 #define BT_HFP_AG_FEATURE_EXT_ERR_ENABLE BT_HFP_AG_FEATURE_EXT_ERR
16 #else
17 #define BT_HFP_AG_FEATURE_EXT_ERR_ENABLE 0
18 #endif /* CONFIG_BT_HFP_AG_EXT_ERR */
19 
20 #if defined(CONFIG_BT_HFP_AG_CODEC_NEG)
21 #define BT_HFP_AG_FEATURE_CODEC_NEG_ENABLE BT_HFP_AG_FEATURE_CODEC_NEG
22 #else
23 #define BT_HFP_AG_FEATURE_CODEC_NEG_ENABLE 0
24 #endif /* CONFIG_BT_HFP_AG_CODEC_NEG */
25 
26 #if defined(CONFIG_BT_HFP_AG_ECNR)
27 #define BT_HFP_AG_FEATURE_ECNR_ENABLE BT_HFP_AG_FEATURE_ECNR
28 #define BT_HFP_AG_SDP_FEATURE_ECNR_ENABLE BT_HFP_AG_SDP_FEATURE_ECNR
29 #else
30 #define BT_HFP_AG_FEATURE_ECNR_ENABLE 0
31 #define BT_HFP_AG_SDP_FEATURE_ECNR_ENABLE 0
32 #endif /* CONFIG_BT_HFP_AG_CODEC_NEG */
33 
34 #if defined(CONFIG_BT_HFP_AG_ECS)
35 #define BT_HFP_AG_FEATURE_ECS_ENABLE BT_HFP_AG_FEATURE_ECS
36 #else
37 #define BT_HFP_AG_FEATURE_ECS_ENABLE 0
38 #endif /* CONFIG_BT_HFP_AG_ECS*/
39 
40 #if defined(CONFIG_BT_HFP_AG_3WAY_CALL)
41 #define BT_HFP_AG_FEATURE_3WAY_CALL_ENABLE BT_HFP_AG_FEATURE_3WAY_CALL
42 #define BT_HFP_AG_SDP_FEATURE_3WAY_CALL_ENABLE BT_HFP_AG_SDP_FEATURE_3WAY_CALL
43 #else
44 #define BT_HFP_AG_FEATURE_3WAY_CALL_ENABLE 0
45 #define BT_HFP_AG_SDP_FEATURE_3WAY_CALL_ENABLE 0
46 #endif /* CONFIG_BT_HFP_AG_3WAY_CALL */
47 
48 #if defined(CONFIG_BT_HFP_AG_ECC)
49 #define BT_HFP_AG_FEATURE_ECC_ENABLE BT_HFP_AG_FEATURE_ECC
50 #else
51 #define BT_HFP_AG_FEATURE_ECC_ENABLE 0
52 #endif /* CONFIG_BT_HFP_AG_ECC */
53 
54 #if defined(CONFIG_BT_HFP_AG_VOICE_RECG)
55 #define BT_HFP_AG_FEATURE_VOICE_RECG_ENABLE BT_HFP_AG_FEATURE_VOICE_RECG
56 #define BT_HFP_AG_SDP_FEATURE_VOICE_RECG_ENABLE BT_HFP_AG_SDP_FEATURE_VOICE_RECG
57 #else
58 #define BT_HFP_AG_FEATURE_VOICE_RECG_ENABLE 0
59 #define BT_HFP_AG_SDP_FEATURE_VOICE_RECG_ENABLE 0
60 #endif /* CONFIG_BT_HFP_AG_VOICE_RECG */
61 
62 #if defined(CONFIG_BT_HFP_AG_ENH_VOICE_RECG)
63 #define BT_HFP_AG_FEATURE_ENH_VOICE_RECG_ENABLE BT_HFP_AG_FEATURE_ENH_VOICE_RECG
64 #define BT_HFP_AG_SDP_FEATURE_ENH_VOICE_RECG_ENABLE BT_HFP_AG_SDP_FEATURE_ENH_VOICE_RECG
65 #else
66 #define BT_HFP_AG_FEATURE_ENH_VOICE_RECG_ENABLE 0
67 #define BT_HFP_AG_SDP_FEATURE_ENH_VOICE_RECG_ENABLE 0
68 #endif /* CONFIG_BT_HFP_AG_ENH_VOICE_RECG */
69 
70 #if defined(CONFIG_BT_HFP_AG_VOICE_RECG_TEXT)
71 #define BT_HFP_AG_FEATURE_VOICE_RECG_TEXT_ENABLE BT_HFP_AG_FEATURE_VOICE_RECG_TEXT
72 #define BT_HFP_AG_SDP_FEATURE_VOICE_RECG_TEXT_ENABLE BT_HFP_AG_SDP_FEATURE_VOICE_RECG_TEXT
73 #else
74 #define BT_HFP_AG_FEATURE_VOICE_RECG_TEXT_ENABLE 0
75 #define BT_HFP_AG_SDP_FEATURE_VOICE_RECG_TEXT_ENABLE 0
76 #endif /* CONFIG_BT_HFP_AG_VOICE_RECG_TEXT */
77 
78 #if defined(CONFIG_BT_HFP_AG_VOICE_TAG)
79 #define BT_HFP_AG_FEATURE_VOICE_TAG_ENABLE BT_HFP_AG_FEATURE_VOICE_TAG
80 #define BT_HFP_AG_SDP_FEATURE_VOICE_TAG_ENABLE BT_HFP_AG_SDP_FEATURE_VOICE_TAG
81 #else
82 #define BT_HFP_AG_FEATURE_VOICE_TAG_ENABLE 0
83 #define BT_HFP_AG_SDP_FEATURE_VOICE_TAG_ENABLE 0
84 #endif /* CONFIG_BT_HFP_AG_VOICE_TAG */
85 
86 #if defined(CONFIG_BT_HFP_AG_HF_INDICATORS)
87 #define BT_HFP_AG_FEATURE_HF_IND_ENABLE BT_HFP_AG_FEATURE_HF_IND
88 #else
89 #define BT_HFP_AG_FEATURE_HF_IND_ENABLE 0
90 #endif /* CONFIG_BT_HFP_HF_HF_INDICATORS */
91 
92 #if defined(CONFIG_BT_HFP_AG_REJECT_CALL)
93 #define BT_HFP_AG_FEATURE_REJECT_CALL_ENABLE BT_HFP_AG_FEATURE_REJECT_CALL
94 #else
95 #define BT_HFP_AG_FEATURE_REJECT_CALL_ENABLE 0
96 #endif /* CONFIG_BT_HFP_AG_REJECT_CALL */
97 
98 /* HFP AG Supported features */
99 #define BT_HFP_AG_SUPPORTED_FEATURES (\
100 	BT_HFP_AG_FEATURE_3WAY_CALL_ENABLE | \
101 	BT_HFP_AG_FEATURE_INBAND_RINGTONE | \
102 	BT_HFP_AG_FEATURE_EXT_ERR_ENABLE | \
103 	BT_HFP_AG_FEATURE_CODEC_NEG_ENABLE | \
104 	BT_HFP_AG_FEATURE_ECNR_ENABLE | \
105 	BT_HFP_AG_FEATURE_ECS_ENABLE | \
106 	BT_HFP_AG_FEATURE_ECC_ENABLE | \
107 	BT_HFP_AG_FEATURE_VOICE_RECG_ENABLE | \
108 	BT_HFP_AG_FEATURE_ENH_VOICE_RECG_ENABLE | \
109 	BT_HFP_AG_FEATURE_VOICE_RECG_TEXT_ENABLE | \
110 	BT_HFP_AG_FEATURE_VOICE_TAG_ENABLE | \
111 	BT_HFP_AG_FEATURE_HF_IND_ENABLE | \
112 	BT_HFP_AG_FEATURE_REJECT_CALL_ENABLE)
113 
114 /* HFP AG Supported features in SDP */
115 #define BT_HFP_AG_SDP_SUPPORTED_FEATURES (\
116 	BT_HFP_AG_SDP_FEATURE_3WAY_CALL_ENABLE | \
117 	BT_HFP_AG_SDP_FEATURE_INBAND_RINGTONE | \
118 	BT_HFP_AG_SDP_FEATURE_ECNR_ENABLE | \
119 	BT_HFP_AG_SDP_FEATURE_VOICE_RECG_ENABLE | \
120 	BT_HFP_AG_SDP_FEATURE_ENH_VOICE_RECG_ENABLE | \
121 	BT_HFP_AG_SDP_FEATURE_VOICE_RECG_TEXT_ENABLE | \
122 	BT_HFP_AG_SDP_FEATURE_VOICE_TAG_ENABLE)
123 
124 /* bt_hfp_ag flags: the flags defined here represent HFP AG parameters */
125 enum {
126 	BT_HFP_AG_CMEE_ENABLE,   /* Extended Audio Gateway Error Result Code */
127 	BT_HFP_AG_CMER_ENABLE,   /* Indicator Events Reporting */
128 	BT_HFP_AG_CLIP_ENABLE,   /* Calling Line Identification notification */
129 	BT_HFP_AG_CCWA_ENABLE,   /* Call Waiting notification */
130 	BT_HFP_AG_INBAND_RING,   /* In-band ring */
131 	BT_HFP_AG_COPS_SET,      /* Query Operator selection */
132 	BT_HFP_AG_AUDIO_CONN,    /* Audio connection */
133 	BT_HFP_AG_CODEC_CONN,    /* Codec connection is ongoing */
134 	BT_HFP_AG_CODEC_CHANGED, /* Codec Id Changed */
135 	BT_HFP_AG_TX_ONGOING,    /* TX is ongoing */
136 	BT_HFP_AG_CREATING_SCO,  /* SCO is creating */
137 	BT_HFP_AG_VRE_ACTIVATE,  /* VRE is activated */
138 	BT_HFP_AG_VRE_R2A,       /* HF is ready to accept audio */
139 	BT_HGP_AG_ONGOING_CALLS, /* Waiting ongoing calls */
140 
141 	/* Total number of flags - must be at the end of the enum */
142 	BT_HFP_AG_NUM_FLAGS,
143 };
144 
145 /* bt_hfp_ag_call flags: the flags defined here represent HFP AG parameters */
146 enum {
147 	BT_HFP_AG_CALL_IN_USING,      /* Object is in using */
148 	BT_HFP_AG_CALL_INCOMING,      /* Incoming call */
149 	BT_HFP_AG_CALL_INCOMING_HELD, /* Incoming call held */
150 	BT_HFP_AG_CALL_OPEN_SCO,      /* Open SCO */
151 	BT_HFP_AG_CALL_OUTGOING_3WAY, /* Outgoing 3 way call */
152 	BT_HFP_AG_CALL_INCOMING_3WAY, /* Incoming 3 way call */
153 	BT_HFP_AG_CALL_ALERTING,      /* Pending for alerting */
154 
155 	/* Total number of flags - must be at the end of the enum */
156 	BT_HFP_AG_CALL_NUM_FLAGS,
157 };
158 
159 typedef enum __packed {
160 	/** Session disconnected */
161 	BT_HFP_DISCONNECTED,
162 	/** Session in connecting state */
163 	BT_HFP_CONNECTING,
164 	/** Session in config state, HFP configuration */
165 	BT_HFP_CONFIG,
166 	/** Session ready for upper layer traffic on it */
167 	BT_HFP_CONNECTED,
168 	/** Session in disconnecting state */
169 	BT_HFP_DISCONNECTING,
170 } bt_hfp_state_t;
171 
172 typedef enum __packed {
173 	/** Call terminate */
174 	BT_HFP_CALL_TERMINATE = 1,
175 	/** Call outgoing */
176 	BT_HFP_CALL_OUTGOING = 2,
177 	/** Call incoming */
178 	BT_HFP_CALL_INCOMING = 4,
179 	/** Call alerting */
180 	BT_HFP_CALL_ALERTING = 8,
181 	/** Call active */
182 	BT_HFP_CALL_ACTIVE = 16,
183 	/** Call hold */
184 	BT_HFP_CALL_HOLD = 32,
185 } bt_hfp_call_state_t;
186 
187 #define AT_COPS_OPERATOR_MAX_LEN 16
188 
189 struct bt_hfp_ag_call {
190 	struct bt_hfp_ag *ag;
191 
192 	char number[CONFIG_BT_HFP_AG_PHONE_NUMBER_MAX_LEN + 1];
193 	uint8_t type;
194 
195 	ATOMIC_DEFINE(flags, BT_HFP_AG_CALL_NUM_FLAGS);
196 
197 	/* HFP Call state */
198 	bt_hfp_call_state_t call_state;
199 
200 	/* Calling Line Identification notification */
201 	struct k_work_delayable ringing_work;
202 
203 	struct k_work_delayable deferred_work;
204 };
205 
206 struct bt_hfp_ag {
207 	struct bt_rfcomm_dlc rfcomm_dlc;
208 	char buffer[HF_MAX_BUF_LEN];
209 	uint32_t hf_features;
210 	uint32_t ag_features;
211 
212 	/* HF Supported Codec Ids*/
213 	uint32_t hf_codec_ids;
214 	uint8_t selected_codec_id;
215 
216 	ATOMIC_DEFINE(flags, BT_HFP_AG_NUM_FLAGS);
217 
218 	/* ACL Connection Object */
219 	struct bt_conn *acl_conn;
220 
221 	/* HFP Connection state */
222 	bt_hfp_state_t state;
223 
224 	/* AG Indicators */
225 	uint8_t indicator_value[BT_HFP_AG_IND_MAX];
226 	uint32_t indicator;
227 
228 	/* HF Indicators */
229 	uint32_t hf_indicators_of_ag;
230 	uint32_t hf_indicators_of_hf;
231 	uint32_t hf_indicators;
232 
233 	/* operator */
234 	uint8_t mode;
235 	char operator[AT_COPS_OPERATOR_MAX_LEN + 1];
236 
237 	/* calls */
238 	struct bt_hfp_ag_call calls[CONFIG_BT_HFP_AG_MAX_CALLS];
239 
240 	/* ongoing calls */
241 	struct bt_hfp_ag_ongoing_call ongoing_calls[CONFIG_BT_HFP_AG_MAX_CALLS];
242 	size_t ongoing_call_count;
243 	/* ongoing calls work */
244 	struct k_work_delayable ongoing_call_work;
245 
246 	/* last dialing number and type */
247 	char last_number[CONFIG_BT_HFP_AG_PHONE_NUMBER_MAX_LEN + 1];
248 	uint8_t type;
249 
250 	/* SCO Connection Object */
251 	struct bt_sco_chan sco_chan;
252 
253 	/* SCO connect */
254 	struct bt_conn *sco_conn;
255 
256 	/* HFP TX pending */
257 	sys_slist_t tx_pending;
258 
259 	/* Critical locker */
260 	struct k_sem lock;
261 
262 	/* TX work */
263 	struct k_work_delayable tx_work;
264 };
265