diff mbox series

[v2,2/4,qmimodem,voicecall] Implement call answer

Message ID 20240326102054.30946-2-adam@piggz.co.uk (mailing list archive)
State Superseded
Headers show
Series [v2,1/4,qmimodem,voicecall] Implement call dialing | expand

Commit Message

Adam Pigg March 26, 2024, 10:19 a.m. UTC
The answer function set up the parameters for a call to the service
function QMI_VOICE_ANSWER_CALL.  The only parameter is the call-id.
anser_cb will then be called which retrieves the call-id and checks
the status of the result.
---
 drivers/qmimodem/voice.h     |  9 ++++
 drivers/qmimodem/voicecall.c | 99 ++++++++++++++++++++++++++++++++++++
 2 files changed, 108 insertions(+)

Comments

Denis Kenzior March 27, 2024, 6:38 p.m. UTC | #1
Hi Adam,

On 3/26/24 05:19, Adam Pigg wrote:
> The answer function set up the parameters for a call to the service
> function QMI_VOICE_ANSWER_CALL.  The only parameter is the call-id.
> anser_cb will then be called which retrieves the call-id and checks
> the status of the result.
> ---
>   drivers/qmimodem/voice.h     |  9 ++++
>   drivers/qmimodem/voicecall.c | 99 ++++++++++++++++++++++++++++++++++++
>   2 files changed, 108 insertions(+)
> 

Some CI reported info:

0002-Implement-call-answer.patch:122: WARNING: Prefer using '"%s...", __func__' 
to using 'answer', this function's name, in a string

> diff --git a/drivers/qmimodem/voice.h b/drivers/qmimodem/voice.h
> index 1a584f10..9c31297b 100644
> --- a/drivers/qmimodem/voice.h
> +++ b/drivers/qmimodem/voice.h
> @@ -54,6 +54,7 @@ enum qmi_ussd_user_required {
>   /* QMI service voice. Using an enum to prevent doublicated entries */
>   enum voice_commands {
>   	QMI_VOICE_DIAL_CALL =			0x20,
> +	QMI_VOICE_ANSWER_CALL =			0x22,
>   	QMI_VOICE_SUPS_NOTIFICATION_IND =	0x32,
>   	QMI_VOICE_SET_SUPS_SERVICE =		0x33,
>   	QMI_VOICE_GET_CALL_WAITING =		0x34,
> @@ -110,6 +111,14 @@ enum qmi_voice_call_type {
>   	QMI_VOICE_CALL_TYPE_VOICE_FORCE,
>   };
>   
> +enum qmi_voice_call_answer_param {
> +	QMI_VOICE_ANSWER_CALL_ID = 0x01,
> +};
> +
> +enum qmi_voice_call_answer_return {
> +	QMI_VOICE_ANSWER_RETURN_CALL_ID = 0x10,
> +};
> +

See earlier feedback about param / result defines / enums.

>   enum parse_error {
>   	NONE = 0,
>   	MISSING_MANDATORY = 1,
> diff --git a/drivers/qmimodem/voicecall.c b/drivers/qmimodem/voicecall.c
> index 55c7009a..7c6bc113 100644
> --- a/drivers/qmimodem/voicecall.c
> +++ b/drivers/qmimodem/voicecall.c
> @@ -97,6 +97,16 @@ struct qmi_voice_dial_call_result {
>   	uint8_t call_id;
>   };
>   
> +struct qmi_voice_answer_call_arg {
> +	bool call_id_set;
> +	uint8_t call_id;
> +};
> +
> +struct qmi_voice_answer_call_result {
> +	bool call_id_set;
> +	uint8_t call_id;
> +};
> +

Likely these structures are not needed.

>   int ofono_call_compare(const void *a, const void *b, void *data)
>   {
>   	const struct ofono_call *ca = a;
> @@ -533,6 +543,94 @@ error:
>   	l_free(param);
>   }
>   
> +enum parse_error qmi_voice_answer_call_parse(
> +	struct qmi_result *qmi_result,
> +	struct qmi_voice_answer_call_result *result)
> +{
> +	int err = NONE;
> +
> +	/* optional */
> +	if (qmi_result_get_uint8(qmi_result, QMI_VOICE_ANSWER_RETURN_CALL_ID, &result->call_id))
> +		result->call_id_set = 1;

Just inline this inside answer_cb()

> +
> +	return err;
> +}
> +
> +static void answer_cb(struct qmi_result *result, void *user_data)
> +{
> +	struct cb_data *cbd = user_data;
> +	ofono_voicecall_cb_t cb = cbd->cb;
> +	uint16_t error;
> +	struct qmi_voice_answer_call_result answer_result;
> +
> +	DBG("");
> +
> +	if (qmi_result_set_error(result, &error)) {
> +		DBG("QMI Error %d", error);
> +		CALLBACK_WITH_FAILURE(cb, cbd->data);
> +		return;
> +	}
> +
> +	/* TODO: what happens when calling it with no active call or wrong caller id? */
> +	if (qmi_voice_answer_call_parse(result, &answer_result) != NONE) {

That function doesn't actually return an error, so is this code block even needed?

> +		DBG("Received invalid Result");
> +		CALLBACK_WITH_FAILURE(cb, cbd->data);
> +		return;
> +	}
> +
> +	CALLBACK_WITH_SUCCESS(cb, cbd->data);
> +}
> +
> +static void answer(struct ofono_voicecall *vc, ofono_voicecall_cb_t cb, void *data)
> +{
> +	struct voicecall_data *vd = ofono_voicecall_get_data(vc);
> +	struct cb_data *cbd = cb_data_new(cb, data);
> +	struct qmi_voice_answer_call_arg arg;

No need for this, fill out qmi_param directly.

> +	struct ofono_call *call;
> +	struct qmi_param *param = NULL;
> +
> +	DBG("");
> +
> +	cbd->user = vc;
> +
> +	call = l_queue_find(vd->call_list,
> +					ofono_call_compare_by_status,
> +					L_UINT_TO_PTR(CALL_STATUS_INCOMING));
> +
> +	if (call == NULL) {
> +		DBG("Can not find a call to answer");
> +		goto error;
> +	}
> +
> +	arg.call_id_set = true;
> +	arg.call_id = call->id;
> +
> +	param = qmi_param_new();
> +	if (!param)
> +		goto error;
> +
> +	if (arg.call_id_set) {
> +		if (!qmi_param_append_uint8(
> +			param,
> +			QMI_VOICE_ANSWER_CALL_ID,
> +			arg.call_id))
> +			goto error;
> +	}
> +
> +	if (qmi_service_send(vd->voice,
> +		QMI_VOICE_ANSWER_CALL,
> +		param,
> +		answer_cb,
> +		cbd,
> +		l_free) > 0)

See doc/coding-style.txt item M4.

> +		return;
> +
> +error:
> +	CALLBACK_WITH_FAILURE(cb, data);
> +	l_free(cbd);
> +	l_free(param);
> +}
> +
>   static void create_voice_cb(struct qmi_service *service, void *user_data)
>   {
>   	struct ofono_voicecall *vc = user_data;
> @@ -598,6 +696,7 @@ static const struct ofono_voicecall_driver driver = {
>   	.probe		= qmi_voicecall_probe,
>   	.remove		= qmi_voicecall_remove,
>   	.dial		= dial,
> +	.answer		= answer,
>   };
>   
>   OFONO_ATOM_DRIVER_BUILTIN(voicecall, qmimodem, &driver)

Regards,
-Denis
diff mbox series

Patch

diff --git a/drivers/qmimodem/voice.h b/drivers/qmimodem/voice.h
index 1a584f10..9c31297b 100644
--- a/drivers/qmimodem/voice.h
+++ b/drivers/qmimodem/voice.h
@@ -54,6 +54,7 @@  enum qmi_ussd_user_required {
 /* QMI service voice. Using an enum to prevent doublicated entries */
 enum voice_commands {
 	QMI_VOICE_DIAL_CALL =			0x20,
+	QMI_VOICE_ANSWER_CALL =			0x22,
 	QMI_VOICE_SUPS_NOTIFICATION_IND =	0x32,
 	QMI_VOICE_SET_SUPS_SERVICE =		0x33,
 	QMI_VOICE_GET_CALL_WAITING =		0x34,
@@ -110,6 +111,14 @@  enum qmi_voice_call_type {
 	QMI_VOICE_CALL_TYPE_VOICE_FORCE,
 };
 
+enum qmi_voice_call_answer_param {
+	QMI_VOICE_ANSWER_CALL_ID = 0x01,
+};
+
+enum qmi_voice_call_answer_return {
+	QMI_VOICE_ANSWER_RETURN_CALL_ID = 0x10,
+};
+
 enum parse_error {
 	NONE = 0,
 	MISSING_MANDATORY = 1,
diff --git a/drivers/qmimodem/voicecall.c b/drivers/qmimodem/voicecall.c
index 55c7009a..7c6bc113 100644
--- a/drivers/qmimodem/voicecall.c
+++ b/drivers/qmimodem/voicecall.c
@@ -97,6 +97,16 @@  struct qmi_voice_dial_call_result {
 	uint8_t call_id;
 };
 
+struct qmi_voice_answer_call_arg {
+	bool call_id_set;
+	uint8_t call_id;
+};
+
+struct qmi_voice_answer_call_result {
+	bool call_id_set;
+	uint8_t call_id;
+};
+
 int ofono_call_compare(const void *a, const void *b, void *data)
 {
 	const struct ofono_call *ca = a;
@@ -533,6 +543,94 @@  error:
 	l_free(param);
 }
 
+enum parse_error qmi_voice_answer_call_parse(
+	struct qmi_result *qmi_result,
+	struct qmi_voice_answer_call_result *result)
+{
+	int err = NONE;
+
+	/* optional */
+	if (qmi_result_get_uint8(qmi_result, QMI_VOICE_ANSWER_RETURN_CALL_ID, &result->call_id))
+		result->call_id_set = 1;
+
+	return err;
+}
+
+static void answer_cb(struct qmi_result *result, void *user_data)
+{
+	struct cb_data *cbd = user_data;
+	ofono_voicecall_cb_t cb = cbd->cb;
+	uint16_t error;
+	struct qmi_voice_answer_call_result answer_result;
+
+	DBG("");
+
+	if (qmi_result_set_error(result, &error)) {
+		DBG("QMI Error %d", error);
+		CALLBACK_WITH_FAILURE(cb, cbd->data);
+		return;
+	}
+
+	/* TODO: what happens when calling it with no active call or wrong caller id? */
+	if (qmi_voice_answer_call_parse(result, &answer_result) != NONE) {
+		DBG("Received invalid Result");
+		CALLBACK_WITH_FAILURE(cb, cbd->data);
+		return;
+	}
+
+	CALLBACK_WITH_SUCCESS(cb, cbd->data);
+}
+
+static void answer(struct ofono_voicecall *vc, ofono_voicecall_cb_t cb, void *data)
+{
+	struct voicecall_data *vd = ofono_voicecall_get_data(vc);
+	struct cb_data *cbd = cb_data_new(cb, data);
+	struct qmi_voice_answer_call_arg arg;
+	struct ofono_call *call;
+	struct qmi_param *param = NULL;
+
+	DBG("");
+
+	cbd->user = vc;
+
+	call = l_queue_find(vd->call_list,
+					ofono_call_compare_by_status,
+					L_UINT_TO_PTR(CALL_STATUS_INCOMING));
+
+	if (call == NULL) {
+		DBG("Can not find a call to answer");
+		goto error;
+	}
+
+	arg.call_id_set = true;
+	arg.call_id = call->id;
+
+	param = qmi_param_new();
+	if (!param)
+		goto error;
+
+	if (arg.call_id_set) {
+		if (!qmi_param_append_uint8(
+			param,
+			QMI_VOICE_ANSWER_CALL_ID,
+			arg.call_id))
+			goto error;
+	}
+
+	if (qmi_service_send(vd->voice,
+		QMI_VOICE_ANSWER_CALL,
+		param,
+		answer_cb,
+		cbd,
+		l_free) > 0)
+		return;
+
+error:
+	CALLBACK_WITH_FAILURE(cb, data);
+	l_free(cbd);
+	l_free(param);
+}
+
 static void create_voice_cb(struct qmi_service *service, void *user_data)
 {
 	struct ofono_voicecall *vc = user_data;
@@ -598,6 +696,7 @@  static const struct ofono_voicecall_driver driver = {
 	.probe		= qmi_voicecall_probe,
 	.remove		= qmi_voicecall_remove,
 	.dial		= dial,
+	.answer		= answer,
 };
 
 OFONO_ATOM_DRIVER_BUILTIN(voicecall, qmimodem, &driver)