Message ID | 20240402212625.5348-3-adam@piggz.co.uk (mailing list archive) |
---|---|
State | Superseded, archived |
Headers | show |
Series | [v3,1/4] qmimodem: voicecall: Implement call dialing | expand |
Hi Adam, On 4/2/24 16:25, Adam Pigg wrote: > 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 paramters typo: 'paramters' > being the call-id. > > end_call_cb will then be called and will parse out the call-id and check > for success. > --- > drivers/qmimodem/voice.h | 1 + > drivers/qmimodem/voicecall.c | 84 +++++++++++++++++++++++++++++++++++- > 2 files changed, 84 insertions(+), 1 deletion(-) > <snip> > +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 = cb_data_new(cb, data); > + struct qmi_param *param = NULL; > + > + static const uint8_t QMI_VOICE_END_CALL_ID = 0x01; > + > + DBG(""); > + cbd->user = vc; > + > + param = qmi_param_new(); As mentioned before, qmi_param_new() can't fail, so feel free to drop !param check > + if (!param) > + goto error; > + > + if (!qmi_param_append_uint8(param, QMI_VOICE_END_CALL_ID, id)) > + goto error; > + > + if (qmi_service_send(vd->voice, QMI_VOICE_END_CALL, param, end_call_cb, > + cbd, l_free) > 0) item M4 > + 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(""); item M1 > + for (uint32_t i = 0; i < L_ARRAY_SIZE(active); i++) { > + call = l_queue_find(vd->call_list, ofono_call_compare_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,7 +674,7 @@ static void create_voice_cb(struct qmi_service *service, void *user_data) > data->voice = qmi_service_ref(service); > > qmi_service_register(data->voice, QMI_VOICE_ALL_CALL_STATUS_IND, > - all_call_status_ind, vc, NULL); > + all_call_status_ind, vc, NULL); This belongs in patch 1. > > ofono_voicecall_register(vc); > } Regards, -Denis
diff --git a/drivers/qmimodem/voice.h b/drivers/qmimodem/voice.h index a524cf98..caedb079 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 8ee49acf..627719a8 100644 --- a/drivers/qmimodem/voicecall.c +++ b/drivers/qmimodem/voicecall.c @@ -572,6 +572,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 QMI_VOICE_END_RETURN_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, QMI_VOICE_END_RETURN_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 = cb_data_new(cb, data); + struct qmi_param *param = NULL; + + static const uint8_t QMI_VOICE_END_CALL_ID = 0x01; + + DBG(""); + cbd->user = vc; + + param = qmi_param_new(); + if (!param) + goto error; + + if (!qmi_param_append_uint8(param, QMI_VOICE_END_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_compare_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,7 +674,7 @@ static void create_voice_cb(struct qmi_service *service, void *user_data) data->voice = qmi_service_ref(service); qmi_service_register(data->voice, QMI_VOICE_ALL_CALL_STATUS_IND, - all_call_status_ind, vc, NULL); + all_call_status_ind, vc, NULL); ofono_voicecall_register(vc); } @@ -639,6 +719,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)