From 979fce83a1985b8a43f1b8f49ed746710792375f Mon Sep 17 00:00:00 2001 From: Joey Hewitt Date: Thu, 14 Sep 2017 19:19:43 -0700 Subject: qmimodem: reimplement release_specific() Works better with inactive calls, I think. My testcase is rejecting an incoming call. Without this patch, caller gets abrupt call ended. With it, they get bounced to voicemail (or presumably whatever else the network/callee has configured) --- drivers/qmimodem/voice_generated.c | 26 ++++++++++++--------- drivers/qmimodem/voice_generated.h | 17 +++++++------- drivers/qmimodem/voicecall.c | 46 ++++++++++++++++++++++++++++++++------ 3 files changed, 63 insertions(+), 26 deletions(-) diff --git a/drivers/qmimodem/voice_generated.c b/drivers/qmimodem/voice_generated.c index 3440be43..3d26ab23 100644 --- a/drivers/qmimodem/voice_generated.c +++ b/drivers/qmimodem/voice_generated.c @@ -56,8 +56,8 @@ enum parse_error qmi_voice_dial_call_parse( return err; } -int qmi_voice_end_call( - struct qmi_voice_end_call_arg *arg, +int qmi_voice_manage_call( + struct qmi_voice_manage_call_arg *arg, struct qmi_service *service, qmi_result_func_t func, void *user_data, @@ -69,16 +69,22 @@ int qmi_voice_end_call( if (!param) goto error; + if (!qmi_param_append_uint8( + param, + 0x1, + arg->ss_call_type)) + goto error; + if (arg->call_id_set) { if (!qmi_param_append_uint8( param, - 0x1, + 0x10, arg->call_id)) goto error; } if (qmi_service_send(service, - 0x21, + 0x31, param, func, user_data, @@ -89,17 +95,15 @@ error: return 1; } -enum parse_error qmi_voice_end_call_parse( +enum parse_error qmi_voice_manage_call_parse( struct qmi_result *qmi_result, - struct qmi_voice_end_call_result *result) + struct qmi_voice_manage_call_result *result) { - int err = NONE; - /* optional */ - if (qmi_result_get_uint8(qmi_result, 0x10, &result->call_id)) - result->call_id_set = 1; + if (qmi_result_get_uint16(qmi_result, 0x10, &result->failcause)) + result->failcause_set = 1; - return err; + return NONE; } diff --git a/drivers/qmimodem/voice_generated.h b/drivers/qmimodem/voice_generated.h index 471b52ea..aa751b71 100644 --- a/drivers/qmimodem/voice_generated.h +++ b/drivers/qmimodem/voice_generated.h @@ -41,26 +41,27 @@ enum parse_error qmi_voice_dial_call_parse( struct qmi_result *qmi_result, struct qmi_voice_dial_call_result *result); -struct qmi_voice_end_call_arg { +struct qmi_voice_manage_call_arg { + uint8_t ss_call_type; bool call_id_set; uint8_t call_id; }; -int qmi_voice_end_call( - struct qmi_voice_end_call_arg *arg, +int qmi_voice_manage_call( + struct qmi_voice_manage_call_arg *arg, struct qmi_service *service, qmi_result_func_t func, void *user_data, qmi_destroy_func_t destroy); -struct qmi_voice_end_call_result { - bool call_id_set; - uint8_t call_id; +struct qmi_voice_manage_call_result { + bool failcause_set; + uint16_t failcause; }; -enum parse_error qmi_voice_end_call_parse( +enum parse_error qmi_voice_manage_call_parse( struct qmi_result *qmi_result, - struct qmi_voice_end_call_result *result); + struct qmi_voice_manage_call_result *result); struct qmi_voice_answer_call_arg { bool call_id_set; diff --git a/drivers/qmimodem/voicecall.c b/drivers/qmimodem/voicecall.c index 6b3caba4..d16613f3 100644 --- a/drivers/qmimodem/voicecall.c +++ b/drivers/qmimodem/voicecall.c @@ -336,13 +336,13 @@ err: g_free(cbd); } -static void end_cb(struct qmi_result *result, void *user_data) +static void manage_cb(struct qmi_result *result, void *user_data) { struct cb_data *cbd = user_data; struct ofono_voicecall *vc = cbd->user; ofono_voicecall_cb_t cb = cbd->cb; uint16_t error; - struct qmi_voice_end_call_result end_result; + struct qmi_voice_manage_call_result end_result; struct ofono_call *call; if (qmi_result_set_error(result, &error)) { @@ -351,7 +351,7 @@ static void end_cb(struct qmi_result *result, void *user_data) return; } - if (NONE != qmi_voice_end_call_parse(result, &end_result)) { + if (NONE != qmi_voice_manage_call_parse(result, &end_result)) { DBG("Received invalid Result"); CALLBACK_WITH_FAILURE(cb, cbd->data); return; @@ -365,31 +365,63 @@ static void release_specific(struct ofono_voicecall *vc, int id, { struct voicecall_data *vd = ofono_voicecall_get_data(vc); struct cb_data *cbd = cb_data_new(cb, data); - struct qmi_voice_end_call_arg arg; + struct qmi_voice_manage_call_arg arg; int i; + GSList *l; + struct ofono_call *call; DBG(""); cbd->user = vc; + l = g_slist_find_custom(vd->call_list, GINT_TO_POINTER(id), + ofono_call_compare_by_id); + if (l == NULL) { + ofono_error("invalid call id %d", id); + goto error; + } + + call = l->data; + arg.call_id_set = true; arg.call_id = id; + switch (call->status) { + case CALL_STATUS_ACTIVE: + case CALL_STATUS_DIALING: + case CALL_STATUS_ALERTING: + arg.ss_call_type = 9; // release specified call + break; + case CALL_STATUS_HELD: + case CALL_STATUS_INCOMING: + case CALL_STATUS_WAITING: + arg.ss_call_type = 1; // release held or waiting + break; + case CALL_STATUS_DISCONNECTED: + goto success; + } - if (!qmi_voice_end_call(&arg, + if (!qmi_voice_manage_call(&arg, vd->voice, - end_cb, + manage_cb, cbd, g_free)) return; +error: CALLBACK_WITH_FAILURE(cb, data); g_free(cbd); + return; + +success: + CALLBACK_WITH_SUCCESS(cb, data); + g_free(cbd); + return; } static void hangup_active(struct ofono_voicecall *vc, ofono_voicecall_cb_t cb, void *data) { struct voicecall_data *vd = ofono_voicecall_get_data(vc); - struct qmi_voice_end_call_arg arg; + struct qmi_voice_manage_call_arg arg; struct ofono_call *call; GSList *list = NULL; enum call_status active[] = { -- cgit v1.2.3