Bluetooth: HFP_AG: Enable 3-way feature
Add a configuration `BT_HFP_AG_3WAY_CALL` to control the feature. Add a configuration `BT_HFP_AG_MAX_CALLS` to define supported maximum calls. Add a structure `struct bt_hfp_ag_call` to manage the call. Add the call object to callback `outgoing`, and`incoming`. Use call object to replace AG object for callbacks `incoming_held`, `ringing`, `accept`, `reject`, and `terminate`. Add callback `held` to notify the call held status. Use call object to replace AG object for function `bt_hfp_ag_hold_incoming`, `bt_hfp_ag_reject`, `bt_hfp_ag_accept`, `bt_hfp_ag_terminate`, `bt_hfp_ag_remote_ringing`, `bt_hfp_ag_remote_reject`, `bt_hfp_ag_remote_accept`, and `bt_hfp_ag_remote_terminate`. Signed-off-by: Lyle Zhu <lyle.zhu@nxp.com>
This commit is contained in:
parent
bbc0f1fa57
commit
94de015498
@ -42,6 +42,7 @@ enum bt_hfp_ag_indicator {
|
||||
#define BT_HFP_AG_CODEC_LC3_SWB 0x03
|
||||
|
||||
struct bt_hfp_ag;
|
||||
struct bt_hfp_ag_call;
|
||||
|
||||
/** @brief HFP profile AG application callback */
|
||||
struct bt_hfp_ag_cb {
|
||||
@ -117,9 +118,10 @@ struct bt_hfp_ag_cb {
|
||||
* new call is outgoing.
|
||||
*
|
||||
* @param ag HFP AG object.
|
||||
* @param call HFP AG call object.
|
||||
* @param number Dailing number
|
||||
*/
|
||||
void (*outgoing)(struct bt_hfp_ag *ag, const char *number);
|
||||
void (*outgoing)(struct bt_hfp_ag *ag, struct bt_hfp_ag_call *call, const char *number);
|
||||
|
||||
/** HF incoming Callback
|
||||
*
|
||||
@ -127,55 +129,74 @@ struct bt_hfp_ag_cb {
|
||||
* new call is incoming.
|
||||
*
|
||||
* @param ag HFP AG object.
|
||||
* @param call HFP AG call object.
|
||||
* @param number Incoming number
|
||||
*/
|
||||
void (*incoming)(struct bt_hfp_ag *ag, const char *number);
|
||||
void (*incoming)(struct bt_hfp_ag *ag, struct bt_hfp_ag_call *call, const char *number);
|
||||
|
||||
/** HF incoming call is held Callback
|
||||
*
|
||||
* If this callback is provided it will be called whenever the
|
||||
* incoming call is held but not accepted.
|
||||
*
|
||||
* @param ag HFP AG object.
|
||||
* @param call HFP AG call object.
|
||||
*/
|
||||
void (*incoming_held)(struct bt_hfp_ag *ag);
|
||||
void (*incoming_held)(struct bt_hfp_ag_call *call);
|
||||
|
||||
/** HF ringing Callback
|
||||
*
|
||||
* If this callback is provided it will be called whenever the
|
||||
* call is in the ringing
|
||||
*
|
||||
* @param ag HFP AG object.
|
||||
* @param call HFP AG call object.
|
||||
* @param in_bond true - in-bond ringing, false - No in-bond ringing
|
||||
*/
|
||||
void (*ringing)(struct bt_hfp_ag *ag, bool in_band);
|
||||
void (*ringing)(struct bt_hfp_ag_call *call, bool in_band);
|
||||
|
||||
/** HF call accept Callback
|
||||
*
|
||||
* If this callback is provided it will be called whenever the
|
||||
* call is accepted.
|
||||
*
|
||||
* @param ag HFP AG object.
|
||||
* @param call HFP AG call object.
|
||||
*/
|
||||
void (*accept)(struct bt_hfp_ag *ag);
|
||||
void (*accept)(struct bt_hfp_ag_call *call);
|
||||
|
||||
/** HF call held Callback
|
||||
*
|
||||
* If this callback is provided it will be called whenever the
|
||||
* call is held.
|
||||
*
|
||||
* @param call HFP AG call object.
|
||||
*/
|
||||
void (*held)(struct bt_hfp_ag_call *call);
|
||||
|
||||
/** HF call retrieve Callback
|
||||
*
|
||||
* If this callback is provided it will be called whenever the
|
||||
* call is retrieved.
|
||||
*
|
||||
* @param call HFP AG call object.
|
||||
*/
|
||||
void (*retrieve)(struct bt_hfp_ag_call *call);
|
||||
|
||||
/** HF call reject Callback
|
||||
*
|
||||
* If this callback is provided it will be called whenever the
|
||||
* call is rejected.
|
||||
*
|
||||
* @param ag HFP AG object.
|
||||
* @param call HFP AG call object.
|
||||
*/
|
||||
void (*reject)(struct bt_hfp_ag *ag);
|
||||
void (*reject)(struct bt_hfp_ag_call *call);
|
||||
|
||||
/** HF call terminate Callback
|
||||
*
|
||||
* If this callback is provided it will be called whenever the
|
||||
* call is terminated.
|
||||
*
|
||||
* @param ag HFP AG object.
|
||||
* @param call HFP AG call object.
|
||||
*/
|
||||
void (*terminate)(struct bt_hfp_ag *ag);
|
||||
void (*terminate)(struct bt_hfp_ag_call *call);
|
||||
|
||||
/** Supported codec Ids callback
|
||||
*
|
||||
@ -244,6 +265,23 @@ struct bt_hfp_ag_cb {
|
||||
* @param ag HFP AG object.
|
||||
*/
|
||||
void (*ecnr_turn_off)(struct bt_hfp_ag *ag);
|
||||
|
||||
/** HF explicit call transfer callback
|
||||
*
|
||||
* If this callback is provided it will be called whenever the
|
||||
* AT+CHLD=4 is sent from HF.
|
||||
* When the callback is notified, the application should connect
|
||||
* the two calls and disconnects the subscriber from both calls
|
||||
* (Explicit Call Transfer).
|
||||
* After the callback returned, the call objects will be invalid.
|
||||
* If the callback is NULL, the response result code of AT command
|
||||
* will be an AT ERROR.
|
||||
* If @kconfig{CONFIG_BT_HFP_AG_3WAY_CALL} is not enabled, the
|
||||
* callback will not be notified.
|
||||
*
|
||||
* @param ag HFP AG object.
|
||||
*/
|
||||
void (*explicit_call_transfer)(struct bt_hfp_ag *ag);
|
||||
};
|
||||
|
||||
/** @brief Register HFP AG profile
|
||||
@ -294,41 +332,61 @@ int bt_hfp_ag_remote_incoming(struct bt_hfp_ag *ag, const char *number);
|
||||
*
|
||||
* Put the incoming call on hold.
|
||||
*
|
||||
* @param ag HFP AG object.
|
||||
* @param call HFP AG call object.
|
||||
*
|
||||
* @return 0 in case of success or negative value in case of error.
|
||||
*/
|
||||
int bt_hfp_ag_hold_incoming(struct bt_hfp_ag *ag);
|
||||
int bt_hfp_ag_hold_incoming(struct bt_hfp_ag_call *call);
|
||||
|
||||
/** @brief Reject the incoming call
|
||||
*
|
||||
* Reject the incoming call.
|
||||
*
|
||||
* @param ag HFP AG object.
|
||||
* @param call HFP AG call object.
|
||||
*
|
||||
* @return 0 in case of success or negative value in case of error.
|
||||
*/
|
||||
int bt_hfp_ag_reject(struct bt_hfp_ag *ag);
|
||||
int bt_hfp_ag_reject(struct bt_hfp_ag_call *call);
|
||||
|
||||
/** @brief Accept the incoming call
|
||||
*
|
||||
* Accept the incoming call.
|
||||
*
|
||||
* @param ag HFP AG object.
|
||||
* @param call HFP AG call object.
|
||||
*
|
||||
* @return 0 in case of success or negative value in case of error.
|
||||
*/
|
||||
int bt_hfp_ag_accept(struct bt_hfp_ag *ag);
|
||||
int bt_hfp_ag_accept(struct bt_hfp_ag_call *call);
|
||||
|
||||
/** @brief Terminate the active/hold call
|
||||
*
|
||||
* Terminate the active/hold call.
|
||||
*
|
||||
* @param ag HFP AG object.
|
||||
* @param call HFP AG call object.
|
||||
*
|
||||
* @return 0 in case of success or negative value in case of error.
|
||||
*/
|
||||
int bt_hfp_ag_terminate(struct bt_hfp_ag *ag);
|
||||
int bt_hfp_ag_terminate(struct bt_hfp_ag_call *call);
|
||||
|
||||
/** @brief Retrieve the held call
|
||||
*
|
||||
* Retrieve the held call.
|
||||
*
|
||||
* @param call HFP AG call object.
|
||||
*
|
||||
* @return 0 in case of success or negative value in case of error.
|
||||
*/
|
||||
int bt_hfp_ag_retrieve(struct bt_hfp_ag_call *call);
|
||||
|
||||
/** @brief Hold the active call
|
||||
*
|
||||
* Hold the active call.
|
||||
*
|
||||
* @param call HFP AG call object.
|
||||
*
|
||||
* @return 0 in case of success or negative value in case of error.
|
||||
*/
|
||||
int bt_hfp_ag_hold(struct bt_hfp_ag_call *call);
|
||||
|
||||
/** @brief Dial a call
|
||||
*
|
||||
@ -345,41 +403,54 @@ int bt_hfp_ag_outgoing(struct bt_hfp_ag *ag, const char *number);
|
||||
*
|
||||
* Notify HFP Unit that the remote starts ringing.
|
||||
*
|
||||
* @param ag HFP AG object.
|
||||
* @param call HFP AG call object.
|
||||
*
|
||||
* @return 0 in case of success or negative value in case of error.
|
||||
*/
|
||||
int bt_hfp_ag_remote_ringing(struct bt_hfp_ag *ag);
|
||||
int bt_hfp_ag_remote_ringing(struct bt_hfp_ag_call *call);
|
||||
|
||||
/** @brief Notify HFP Unit that the remote rejects the call
|
||||
*
|
||||
* Notify HFP Unit that the remote rejects the call.
|
||||
*
|
||||
* @param ag HFP AG object.
|
||||
* @param call HFP AG call object.
|
||||
*
|
||||
* @return 0 in case of success or negative value in case of error.
|
||||
*/
|
||||
int bt_hfp_ag_remote_reject(struct bt_hfp_ag *ag);
|
||||
int bt_hfp_ag_remote_reject(struct bt_hfp_ag_call *call);
|
||||
|
||||
/** @brief Notify HFP Unit that the remote accepts the call
|
||||
*
|
||||
* Notify HFP Unit that the remote accepts the call.
|
||||
*
|
||||
* @param ag HFP AG object.
|
||||
* @param call HFP AG call object.
|
||||
*
|
||||
* @return 0 in case of success or negative value in case of error.
|
||||
*/
|
||||
int bt_hfp_ag_remote_accept(struct bt_hfp_ag *ag);
|
||||
int bt_hfp_ag_remote_accept(struct bt_hfp_ag_call *call);
|
||||
|
||||
/** @brief Notify HFP Unit that the remote terminates the active/hold call
|
||||
*
|
||||
* Notify HFP Unit that the remote terminates the active/hold call.
|
||||
*
|
||||
* @param call HFP AG call object.
|
||||
*
|
||||
* @return 0 in case of success or negative value in case of error.
|
||||
*/
|
||||
int bt_hfp_ag_remote_terminate(struct bt_hfp_ag_call *call);
|
||||
|
||||
/** @brief explicit call transfer
|
||||
*
|
||||
* Connects the two calls and disconnects the subscriber from
|
||||
* both calls (Explicit Call Transfer).
|
||||
* If @kconfig{CONFIG_BT_HFP_AG_3WAY_CALL} is not enabled, the error
|
||||
* `-ENOTSUP` will be returned if the function called.
|
||||
*
|
||||
* @param ag HFP AG object.
|
||||
*
|
||||
* @return 0 in case of success or negative value in case of error.
|
||||
*/
|
||||
int bt_hfp_ag_remote_terminate(struct bt_hfp_ag *ag);
|
||||
int bt_hfp_ag_explicit_call_transfer(struct bt_hfp_ag *ag);
|
||||
|
||||
/** @brief Set the HF microphone gain
|
||||
*
|
||||
|
||||
@ -228,11 +228,31 @@ config BT_HFP_AG_ECNR
|
||||
help
|
||||
This option enables EC and/or NR function for HFP AG
|
||||
|
||||
config BT_HFP_AG_3WAY_CALL
|
||||
bool "Three-way calling for HFP AG [EXPERIMENTAL]"
|
||||
help
|
||||
This option enables Three-way calling for HFP AG
|
||||
|
||||
config BT_HFP_AG_MAX_CALLS
|
||||
int "Maximum supported calls for HFP AG [EXPERIMENTAL]"
|
||||
default 2 if BT_HFP_AG_3WAY_CALL
|
||||
default 1
|
||||
range 1 2
|
||||
help
|
||||
This option sets maximum supported calls for HFP AG
|
||||
|
||||
config BT_HFP_AG_ECS
|
||||
bool "Enhanced call status for HFP AG [EXPERIMENTAL]"
|
||||
default y if BT_HFP_AG_3WAY_CALL
|
||||
help
|
||||
This option enables Enhanced call status for HFP AG
|
||||
|
||||
config BT_HFP_AG_ECC
|
||||
bool "Enhanced call control for HFP AG [EXPERIMENTAL]"
|
||||
default y if BT_HFP_AG_3WAY_CALL
|
||||
help
|
||||
This option enables Enhanced call control for HFP AG
|
||||
|
||||
config BT_HFP_AG_TX_BUF_COUNT
|
||||
int "Maximum number of TX buffers for HFP AG [EXPERIMENTAL]"
|
||||
default BT_RFCOMM_TX_MAX
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -46,18 +46,33 @@
|
||||
#define BT_HFP_AG_FEATURE_ECS_ENABLE 0
|
||||
#endif /* CONFIG_BT_HFP_AG_ECS*/
|
||||
|
||||
#if defined(CONFIG_BT_HFP_AG_3WAY_CALL)
|
||||
#define BT_HFP_AG_FEATURE_3WAY_CALL_ENABLE BT_HFP_AG_FEATURE_3WAY_CALL
|
||||
#define BT_HFP_AG_SDP_FEATURE_3WAY_CALL_ENABLE BT_HFP_AG_SDP_FEATURE_3WAY_CALL
|
||||
#else
|
||||
#define BT_HFP_AG_FEATURE_3WAY_CALL_ENABLE 0
|
||||
#define BT_HFP_AG_SDP_FEATURE_3WAY_CALL_ENABLE 0
|
||||
#endif /* CONFIG_BT_HFP_AG_3WAY_CALL */
|
||||
|
||||
#if defined(CONFIG_BT_HFP_AG_ECC)
|
||||
#define BT_HFP_AG_FEATURE_ECC_ENABLE BT_HFP_AG_FEATURE_ECC
|
||||
#else
|
||||
#define BT_HFP_AG_FEATURE_ECC_ENABLE 0
|
||||
#endif /* CONFIG_BT_HFP_AG_ECC */
|
||||
|
||||
/* HFP AG Supported features */
|
||||
#define BT_HFP_AG_SUPPORTED_FEATURES (\
|
||||
BT_HFP_AG_FEATURE_3WAY_CALL | \
|
||||
BT_HFP_AG_FEATURE_3WAY_CALL_ENABLE | \
|
||||
BT_HFP_AG_FEATURE_INBAND_RINGTONE | \
|
||||
BT_HFP_AG_FEATURE_EXT_ERR_ENABLE | \
|
||||
BT_HFP_AG_FEATURE_CODEC_NEG_ENABLE | \
|
||||
BT_HFP_AG_FEATURE_ECNR_ENABLE | \
|
||||
BT_HFP_AG_FEATURE_ECS_ENABLE)
|
||||
BT_HFP_AG_FEATURE_ECS_ENABLE | \
|
||||
BT_HFP_AG_FEATURE_ECC_ENABLE)
|
||||
|
||||
/* HFP AG Supported features in SDP */
|
||||
#define BT_HFP_AG_SDP_SUPPORTED_FEATURES (\
|
||||
BT_HFP_AG_SDP_FEATURE_3WAY_CALL | \
|
||||
BT_HFP_AG_SDP_FEATURE_3WAY_CALL_ENABLE | \
|
||||
BT_HFP_AG_SDP_FEATURE_INBAND_RINGTONE | \
|
||||
BT_HFP_AG_SDP_FEATURE_ECNR_ENABLE)
|
||||
|
||||
@ -69,8 +84,6 @@ enum {
|
||||
BT_HFP_AG_CCWA_ENABLE, /* Call Waiting notification */
|
||||
BT_HFP_AG_INBAND_RING, /* In-band ring */
|
||||
BT_HFP_AG_COPS_SET, /* Query Operator selection */
|
||||
BT_HFP_AG_INCOMING_CALL, /* Incoming call */
|
||||
BT_HFP_AG_INCOMING_HELD, /* Incoming call held */
|
||||
BT_HFP_AG_AUDIO_CONN, /* Audio connection */
|
||||
BT_HFP_AG_CODEC_CONN, /* Codec connection is ongoing */
|
||||
BT_HFP_AG_CODEC_CHANGED, /* Codec Id Changed */
|
||||
@ -81,6 +94,19 @@ enum {
|
||||
BT_HFP_AG_NUM_FLAGS,
|
||||
};
|
||||
|
||||
/* bt_hfp_ag_call flags: the flags defined here represent HFP AG parameters */
|
||||
enum {
|
||||
BT_HFP_AG_CALL_IN_USING, /* Object is in using */
|
||||
BT_HFP_AG_CALL_INCOMING, /* Incoming call */
|
||||
BT_HFP_AG_CALL_INCOMING_HELD, /* Incoming call held */
|
||||
BT_HFP_AG_CALL_OPEN_SCO, /* Open SCO */
|
||||
BT_HFP_AG_CALL_OUTGOING_3WAY, /* Outgoing 3 way call */
|
||||
BT_HFP_AG_CALL_INCOMING_3WAY, /* Incoming 3 way call */
|
||||
|
||||
/* Total number of flags - must be at the end of the enum */
|
||||
BT_HFP_AG_CALL_NUM_FLAGS,
|
||||
};
|
||||
|
||||
/* HFP HF Indicators */
|
||||
enum {
|
||||
HFP_HF_ENHANCED_SAFETY_IND = 1, /* Enhanced Safety */
|
||||
@ -103,21 +129,38 @@ typedef enum __packed {
|
||||
|
||||
typedef enum __packed {
|
||||
/** Call terminate */
|
||||
BT_HFP_CALL_TERMINATE,
|
||||
BT_HFP_CALL_TERMINATE = 1,
|
||||
/** Call outgoing */
|
||||
BT_HFP_CALL_OUTGOING,
|
||||
BT_HFP_CALL_OUTGOING = 2,
|
||||
/** Call incoming */
|
||||
BT_HFP_CALL_INCOMING,
|
||||
BT_HFP_CALL_INCOMING = 4,
|
||||
/** Call alerting */
|
||||
BT_HFP_CALL_ALERTING,
|
||||
BT_HFP_CALL_ALERTING = 8,
|
||||
/** Call active */
|
||||
BT_HFP_CALL_ACTIVE,
|
||||
BT_HFP_CALL_ACTIVE = 16,
|
||||
/** Call hold */
|
||||
BT_HFP_CALL_HOLD,
|
||||
BT_HFP_CALL_HOLD = 32,
|
||||
} bt_hfp_call_state_t;
|
||||
|
||||
#define AT_COPS_OPERATOR_MAX_LEN 16
|
||||
|
||||
struct bt_hfp_ag_call {
|
||||
struct bt_hfp_ag *ag;
|
||||
|
||||
char number[CONFIG_BT_HFP_AG_PHONE_NUMBER_MAX_LEN + 1];
|
||||
uint8_t type;
|
||||
|
||||
ATOMIC_DEFINE(flags, BT_HFP_AG_CALL_NUM_FLAGS);
|
||||
|
||||
/* HFP Call state */
|
||||
bt_hfp_call_state_t call_state;
|
||||
|
||||
/* Calling Line Identification notification */
|
||||
struct k_work_delayable ringing_work;
|
||||
|
||||
struct k_work_delayable deferred_work;
|
||||
};
|
||||
|
||||
struct bt_hfp_ag {
|
||||
struct bt_rfcomm_dlc rfcomm_dlc;
|
||||
char buffer[HF_MAX_BUF_LEN];
|
||||
@ -136,14 +179,6 @@ struct bt_hfp_ag {
|
||||
/* HFP Connection state */
|
||||
bt_hfp_state_t state;
|
||||
|
||||
/* HFP Call state */
|
||||
bt_hfp_call_state_t call_state;
|
||||
|
||||
/* Delayed work deferred tasks:
|
||||
* - call status cleanup.
|
||||
*/
|
||||
struct k_work_delayable deferred_work;
|
||||
|
||||
/* AG Indicators */
|
||||
uint8_t indicator_value[BT_HFP_AG_IND_MAX];
|
||||
uint32_t indicator;
|
||||
@ -157,17 +192,18 @@ struct bt_hfp_ag {
|
||||
uint8_t mode;
|
||||
char operator[AT_COPS_OPERATOR_MAX_LEN + 1];
|
||||
|
||||
/* calls */
|
||||
struct bt_hfp_ag_call calls[CONFIG_BT_HFP_AG_MAX_CALLS];
|
||||
|
||||
/* last dialing number and type */
|
||||
char last_number[CONFIG_BT_HFP_AG_PHONE_NUMBER_MAX_LEN + 1];
|
||||
uint8_t type;
|
||||
|
||||
/* SCO Connection Object */
|
||||
struct bt_sco_chan sco_chan;
|
||||
/* HFP TX pending */
|
||||
sys_slist_t tx_pending;
|
||||
|
||||
/* Dial number or incoming number */
|
||||
char number[CONFIG_BT_HFP_AG_PHONE_NUMBER_MAX_LEN + 1];
|
||||
|
||||
/* Calling Line Identification notification */
|
||||
struct k_work_delayable ringing_work;
|
||||
|
||||
/* Critical locker */
|
||||
struct k_sem lock;
|
||||
|
||||
|
||||
@ -182,3 +182,35 @@ enum hfp_hf_ag_indicators {
|
||||
#define BT_HFP_BTRH_ON_HOLD 0
|
||||
#define BT_HFP_BTRH_ACCEPTED 1
|
||||
#define BT_HFP_BTRH_REJECTED 2
|
||||
|
||||
/* HFP Call held status */
|
||||
/* No calls held */
|
||||
#define BT_HFP_CALL_HELD_NONE 0
|
||||
/* Call is placed on hold or active/held calls swapped
|
||||
* The AG has both an active AND a held call
|
||||
*/
|
||||
#define BT_HFP_CALL_HELD_ACTIVE_HELD 1
|
||||
/* Call on hold, no active call */
|
||||
#define BT_HFP_CALL_HELD_HELD 2
|
||||
|
||||
/* HFP AT+CHLD command value */
|
||||
/* Releases all held calls or sets User Determined User Busy
|
||||
* (UDUB) for a waiting call
|
||||
*/
|
||||
#define BT_HFP_CHLD_RELEASE_ALL 0
|
||||
/* Releases all active calls (if any exist) and accepts the
|
||||
* other (held or waiting) call.
|
||||
*/
|
||||
#define BT_HFP_CHLD_RELEASE_ACTIVE_ACCEPT_OTHER 1
|
||||
/* Places all active calls (if any exist) on hold and accepts
|
||||
* the other (held or waiting) call
|
||||
*/
|
||||
#define BT_HFP_CALL_HOLD_ACTIVE_ACCEPT_OTHER 2
|
||||
/* Adds a held call to the conversation */
|
||||
#define BT_HFP_CALL_ACTIVE_HELD 3
|
||||
/* Connects the two calls and disconnects the subscriber from
|
||||
* both calls (Explicit Call Transfer).
|
||||
* Support for this value and its associated functionality is
|
||||
* optional for the HF.
|
||||
*/
|
||||
#define BT_HFP_CALL_QUITE 4
|
||||
|
||||
Loading…
Reference in New Issue
Block a user