diff options
author | Adam Pigg <adam@piggz.co.uk> | 2024-04-21 20:49:05 +0100 |
---|---|---|
committer | Denis Kenzior <denkenz@gmail.com> | 2024-04-22 16:04:08 -0500 |
commit | 752d286a5ce3efc28a6b8a4c4dffb44d23d8d15b (patch) | |
tree | 2421da11951dd4daf7bfdd848899a4c86e969283 | |
parent | 3680df68459353dff4bd39dd47b222685e5713b3 (diff) | |
download | ofono-752d286a5ce3efc28a6b8a4c4dffb44d23d8d15b.tar.gz |
qmimodem: voicecall: Implement active call hangup
hangup_active iterates the current list of calls, looking for the first
active call and then calls release_specific. This then sets up the
parameters for a call to QMI_VOICE_END_CALL, with the only parameters
being the call-id.
end_call_cb will then be called and will parse out the call-id and check
for success.
-rw-r--r-- | drivers/qmimodem/voice.h | 1 | ||||
-rw-r--r-- | drivers/qmimodem/voicecall.c | 82 |
2 files changed, 83 insertions, 0 deletions
diff --git a/drivers/qmimodem/voice.h b/drivers/qmimodem/voice.h index a524cf987..caedb079b 100644 --- a/drivers/qmimodem/voice.h +++ b/drivers/qmimodem/voice.h @@ -51,6 +51,7 @@ enum voice_commands { QMI_VOICE_DIAL_CALL = 0x20, QMI_VOICE_ALL_CALL_STATUS_IND = 0x2e, QMI_VOICE_GET_ALL_CALL_INFO = 0x2f, + QMI_VOICE_END_CALL = 0x21, QMI_VOICE_ANSWER_CALL = 0x22, QMI_VOICE_SUPS_NOTIFICATION_IND = 0x32, QMI_VOICE_SET_SUPS_SERVICE = 0x33, diff --git a/drivers/qmimodem/voicecall.c b/drivers/qmimodem/voicecall.c index d65fb59b2..24c4f3f17 100644 --- a/drivers/qmimodem/voicecall.c +++ b/drivers/qmimodem/voicecall.c @@ -527,6 +527,86 @@ error: l_free(param); } +static void end_call_cb(struct qmi_result *result, void *user_data) +{ + struct cb_data *cbd = user_data; + ofono_voicecall_cb_t cb = cbd->cb; + uint16_t error; + uint8_t call_id; + + static const uint8_t RESULT_CALL_ID = 0x10; + + if (qmi_result_set_error(result, &error)) { + DBG("QMI Error %d", error); + CALLBACK_WITH_FAILURE(cb, cbd->data); + return; + } + + if (qmi_result_get_uint8(result, RESULT_CALL_ID, &call_id)) + DBG("Received end call result with call id %d", call_id); + + CALLBACK_WITH_SUCCESS(cb, cbd->data); +} + +static void release_specific(struct ofono_voicecall *vc, int id, + ofono_voicecall_cb_t cb, void *data) +{ + struct voicecall_data *vd = ofono_voicecall_get_data(vc); + struct cb_data *cbd; + struct qmi_param *param = NULL; + + static const uint8_t PARAM_CALL_ID = 0x01; + + DBG(""); + + param = qmi_param_new(); + cbd = cb_data_new(cb, data); + cbd->user = vc; + + if (!qmi_param_append_uint8(param, PARAM_CALL_ID, id)) + goto error; + + if (qmi_service_send(vd->voice, QMI_VOICE_END_CALL, param, end_call_cb, + cbd, l_free) > 0) + return; + +error: + CALLBACK_WITH_FAILURE(cb, data); + l_free(cbd); + l_free(param); +} + +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 ofono_call *call; + enum call_status active[] = { + CALL_STATUS_ACTIVE, + CALL_STATUS_DIALING, + CALL_STATUS_ALERTING, + CALL_STATUS_INCOMING, + }; + + DBG(""); + + for (uint32_t i = 0; i < L_ARRAY_SIZE(active); i++) { + call = l_queue_find(vd->call_list, ofono_call_match_by_status, + L_INT_TO_PTR(active[i])); + + if (call) + break; + } + + if (call == NULL) { + DBG("Can not find a call to hang up"); + CALLBACK_WITH_FAILURE(cb, data); + return; + } + + release_specific(vc, call->id, cb, data); +} + static void create_voice_cb(struct qmi_service *service, void *user_data) { struct ofono_voicecall *vc = user_data; @@ -594,6 +674,8 @@ static const struct ofono_voicecall_driver driver = { .remove = qmi_voicecall_remove, .dial = dial, .answer = answer, + .hangup_active = hangup_active, + .release_specific = release_specific, }; OFONO_ATOM_DRIVER_BUILTIN(voicecall, qmimodem, &driver) |