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