diff --git a/drivers/isimodem/voicecall.c b/drivers/isimodem/voicecall.c index ff1e2b58..be52c065 100644 --- a/drivers/isimodem/voicecall.c +++ b/drivers/isimodem/voicecall.c @@ -84,8 +84,8 @@ struct call_info { struct isi_voicecall { GIsiClient *client; - GIsiClient *primary; - GIsiClient *secondary; + GIsiClient *pn_call; + GIsiClient *pn_modem_call; struct isi_call_req_ctx *queue; struct isi_call calls[8]; void *control_req_irc; @@ -1425,6 +1425,8 @@ static void isi_dial(struct ofono_voicecall *ovc, enum ofono_clir_option clir, ofono_voicecall_cb_t cb, void *data) { + struct isi_voicecall *ivc = ofono_voicecall_get_data(ovc); + gboolean have_pn_call = g_isi_client_resource(ivc->client) == PN_CALL; unsigned char presentation; switch (clir) { @@ -1436,36 +1438,16 @@ static void isi_dial(struct ofono_voicecall *ovc, break; case OFONO_CLIR_OPTION_DEFAULT: default: - presentation = CALL_GSM_PRESENTATION_DEFAULT; - break; + presentation = have_pn_call ? CALL_GSM_PRESENTATION_DEFAULT : + CALL_MODEM_PROP_PRESENT_DEFAULT; } - isi_call_create_req(ovc, presentation, number->type, number->number, - cb, data); -} - -static void wg_dial(struct ofono_voicecall *ovc, - const struct ofono_phone_number *number, - enum ofono_clir_option clir, - ofono_voicecall_cb_t cb, void *data) -{ - unsigned char presentation; - - switch (clir) { - case OFONO_CLIR_OPTION_INVOCATION: - presentation = CALL_PRESENTATION_RESTRICTED; - break; - case OFONO_CLIR_OPTION_SUPPRESSION: - presentation = CALL_PRESENTATION_ALLOWED; - break; - case OFONO_CLIR_OPTION_DEFAULT: - default: - presentation = CALL_MODEM_PROP_PRESENT_DEFAULT; - break; - } - - isi_modem_call_create_req(ovc, presentation, number->type, + if (have_pn_call) + isi_call_create_req(ovc, presentation, number->type, number->number, cb, data); + else + isi_modem_call_create_req(ovc, presentation, number->type, + number->number, cb, data); } static void isi_answer(struct ofono_voicecall *ovc, ofono_voicecall_cb_t cb, @@ -1763,27 +1745,43 @@ static void isi_send_tones(struct ofono_voicecall *ovc, const char *tones, isi_call_dtmf_send_req(ovc, CALL_ID_ALL, tones, cb, data);; } -static void call_verify_cb(const GIsiMessage *msg, void *data) +static void subscribe_indications(GIsiClient *cl, void *data) +{ + g_isi_client_ind_subscribe(cl, CALL_STATUS_IND, isi_call_status_ind_cb, + data); + g_isi_client_ind_subscribe(cl, CALL_CONTROL_IND, isi_call_control_ind_cb, + data); + g_isi_client_ind_subscribe(cl, CALL_TERMINATED_IND, + isi_call_terminated_ind_cb, data); + g_isi_client_ind_subscribe(cl, CALL_GSM_NOTIFICATION_IND, + notification_ind_cb, data); + +} + +static void pn_call_verify_cb(const GIsiMessage *msg, void *data) { struct ofono_voicecall *ovc = data; struct isi_voicecall *ivc = ofono_voicecall_get_data(ovc); if (g_isi_msg_error(msg) < 0) { - ofono_voicecall_remove(ovc); + DBG("PN_CALL not reachable, removing client"); + g_isi_client_destroy(ivc->pn_call); + ivc->pn_call = NULL; + + if (ivc->pn_modem_call == NULL) + ofono_voicecall_remove(ovc); + return; } ISI_RESOURCE_DBG(msg); - g_isi_client_ind_subscribe(ivc->client, CALL_STATUS_IND, - isi_call_status_ind_cb, ovc); - g_isi_client_ind_subscribe(ivc->client, CALL_CONTROL_IND, - isi_call_control_ind_cb, ovc); - g_isi_client_ind_subscribe(ivc->client, CALL_TERMINATED_IND, - isi_call_terminated_ind_cb, ovc); + if (ivc == NULL || ivc->client != NULL) + return; - g_isi_client_ind_subscribe(ivc->client, CALL_GSM_NOTIFICATION_IND, - notification_ind_cb, ovc); + ivc->client = ivc->pn_call; + + subscribe_indications(ivc->client, ovc); if (!isi_call_status_req(ovc, CALL_ID_ALL, CALL_STATUS_MODE_ADDR_AND_ORIGIN, @@ -1793,8 +1791,41 @@ static void call_verify_cb(const GIsiMessage *msg, void *data) ofono_voicecall_register(ovc); } -static int probe_by_resource(struct ofono_voicecall *ovc, uint8_t resource, - void *user) +static void pn_modem_call_verify_cb(const GIsiMessage *msg, void *data) +{ + struct ofono_voicecall *ovc = data; + struct isi_voicecall *ivc = ofono_voicecall_get_data(ovc); + + if (g_isi_msg_error(msg) < 0) { + DBG("PN_MODEM_CALL not reachable, removing client"); + g_isi_client_destroy(ivc->pn_modem_call); + ivc->pn_modem_call = NULL; + + if (ivc->pn_call == NULL) + ofono_voicecall_remove(ovc); + + return; + } + + ISI_RESOURCE_DBG(msg); + + if (ivc == NULL || ivc->client != NULL) + return; + + ivc->client = ivc->pn_modem_call; + + subscribe_indications(ivc->client, ovc); + + if (!isi_call_status_req(ovc, CALL_ID_ALL, + CALL_STATUS_MODE_ADDR_AND_ORIGIN, + NULL, NULL)) + DBG("Failed to request call status"); + + ofono_voicecall_register(ovc); +} + +static int isi_probe(struct ofono_voicecall *ovc, unsigned int vendor, + void *user) { GIsiModem *modem = user; struct isi_voicecall *ivc; @@ -1807,31 +1838,28 @@ static int probe_by_resource(struct ofono_voicecall *ovc, uint8_t resource, for (id = 0; id <= 7; id++) ivc->calls[id].id = id; - ivc->client = g_isi_client_create(modem, resource); - if (ivc->client == NULL) { + ivc->pn_call = g_isi_client_create(modem, PN_CALL); + if (ivc->pn_call == NULL) { + g_free(ivc); + return -ENOMEM; + } + + ivc->pn_modem_call = g_isi_client_create(modem, PN_MODEM_CALL); + if (ivc->pn_call == NULL) { + g_isi_client_destroy(ivc->pn_call); g_free(ivc); return -ENOMEM; } ofono_voicecall_set_data(ovc, ivc); - g_isi_client_verify(ivc->client, call_verify_cb, ovc, NULL); + g_isi_client_verify(ivc->pn_call, pn_call_verify_cb, ovc, NULL); + g_isi_client_verify(ivc->pn_modem_call, pn_modem_call_verify_cb, + ovc, NULL); return 0; } -static int isi_probe(struct ofono_voicecall *ovc, unsigned int vendor, - void *user) -{ - return probe_by_resource(ovc, PN_CALL, user); -} - -static int wg_probe(struct ofono_voicecall *ovc, unsigned int vendor, - void *user) -{ - return probe_by_resource(ovc, PN_MODEM_CALL, user); -} - static void isi_remove(struct ofono_voicecall *call) { struct isi_voicecall *data = ofono_voicecall_get_data(call); @@ -1841,7 +1869,8 @@ static void isi_remove(struct ofono_voicecall *call) if (data == NULL) return; - g_isi_client_destroy(data->client); + g_isi_client_destroy(data->pn_call); + g_isi_client_destroy(data->pn_modem_call); g_free(data); } @@ -1865,34 +1894,12 @@ static struct ofono_voicecall_driver driver = { .send_tones = isi_send_tones, }; -static struct ofono_voicecall_driver wgdriver = { - .name = "wgmodem2.5", - .probe = wg_probe, - .remove = isi_remove, - .dial = wg_dial, - .answer = isi_answer, - .hangup_active = isi_hangup_current, - .hold_all_active = isi_hold_all_active, - .release_all_held = isi_release_all_held, - .set_udub = isi_set_udub, - .release_all_active = isi_release_all_active, - .release_specific = isi_release_specific, - .private_chat = isi_private_chat, - .create_multiparty = isi_create_multiparty, - .transfer = isi_transfer, - .deflect = isi_deflect, - .swap_without_accept = isi_swap_without_accept, - .send_tones = isi_send_tones, -}; - void isi_voicecall_init(void) { ofono_voicecall_driver_register(&driver); - ofono_voicecall_driver_register(&wgdriver); } void isi_voicecall_exit(void) { ofono_voicecall_driver_unregister(&driver); - ofono_voicecall_driver_unregister(&wgdriver); } diff --git a/plugins/isiusb.c b/plugins/isiusb.c index 69a6d603..1fa928cd 100644 --- a/plugins/isiusb.c +++ b/plugins/isiusb.c @@ -405,7 +405,6 @@ static void isiusb_pre_sim(struct ofono_modem *modem) ofono_sim_create(modem, 0, "isimodem", isi->modem); ofono_devinfo_create(modem, 0, "isimodem", isi->modem); ofono_voicecall_create(modem, 0, "isimodem", isi->modem); - ofono_voicecall_create(modem, 0, "wgmodem2.5", isi->modem); } static void isiusb_post_sim(struct ofono_modem *modem) diff --git a/plugins/u8500.c b/plugins/u8500.c index 3e9f22bd..18e7ff8d 100644 --- a/plugins/u8500.c +++ b/plugins/u8500.c @@ -436,7 +436,7 @@ static void u8500_pre_sim(struct ofono_modem *modem) ofono_sim_create(modem, 0, "isimodem", isi->modem); ofono_devinfo_create(modem, 0, "u8500", isi->modem); - ofono_voicecall_create(modem, 0, "wgmodem2.5", isi->modem); + ofono_voicecall_create(modem, 0, "isimodem", isi->modem); } static void u8500_post_sim(struct ofono_modem *modem)