From 282b254a5d07de45a8fc5ccb30667a3e9cf8d486 Mon Sep 17 00:00:00 2001 From: Denis Kenzior Date: Wed, 4 Nov 2015 23:08:06 -0600 Subject: [PATCH] rilmodem: Rework call-forwarding requests --- drivers/rilmodem/call-forwarding.c | 262 ++++++++++++++++------------- 1 file changed, 144 insertions(+), 118 deletions(-) diff --git a/drivers/rilmodem/call-forwarding.c b/drivers/rilmodem/call-forwarding.c index 7965e7d5..286727ba 100644 --- a/drivers/rilmodem/call-forwarding.c +++ b/drivers/rilmodem/call-forwarding.c @@ -38,7 +38,6 @@ #include #include "gril.h" -#include "grilrequest.h" #include "grilreply.h" #include "grilunsol.h" @@ -46,38 +45,11 @@ #include "common.h" -enum cf_action { - CF_ACTION_DISABLE, - CF_ACTION_ENABLE, - CF_ACTION_INTERROGATE, - CF_ACTION_REGISTRATION, - CF_ACTION_ERASURE, -}; - struct forw_data { GRil *ril; - enum cf_action last_action; int last_cls; }; -static const char *cf_action_to_string(enum cf_action action) -{ - switch (action) { - case CF_ACTION_DISABLE: - return "DISABLE"; - case CF_ACTION_ENABLE: - return "ENABLE"; - case CF_ACTION_INTERROGATE: - return "INTERROGATE"; - case CF_ACTION_REGISTRATION: - return "REGISTRATION"; - case CF_ACTION_ERASURE: - return "ERASURE"; - } - - return NULL; -} - static void ril_query_call_fwd_cb(struct ril_msg *message, gpointer user_data) { struct cb_data *cbd = user_data; @@ -123,116 +95,132 @@ static void ril_set_forward_cb(struct ril_msg *message, gpointer user_data) ofono_call_forwarding_set_cb_t cb = cbd->cb; struct forw_data *fd = ofono_call_forwarding_get_data(cbd->user); - if (message->error == RIL_E_SUCCESS) { - g_ril_print_response_no_args(fd->ril, message); - CALLBACK_WITH_SUCCESS(cb, cbd->data); - } else { - ofono_error("%s: CF %s failed; rild error: %s", __func__, - cf_action_to_string(fd->last_action), - ril_error_to_string(message->error)); + if (message->error != RIL_E_SUCCESS) { + ofono_error("%s: failed; rild error: %s", __func__, + ril_error_to_string(message->error)); CALLBACK_WITH_FAILURE(cb, cbd->data); } + + g_ril_print_response_no_args(fd->ril, message); + CALLBACK_WITH_SUCCESS(cb, cbd->data); } -static int ril_send_forward_cmd(int type, int cls, - const struct ofono_phone_number *number, - int time, - struct cb_data *cbd, - enum cf_action action) -{ - struct ofono_call_forwarding *cf = cbd->user; - struct forw_data *fd = ofono_call_forwarding_get_data(cf); - struct parcel rilp; - struct req_call_fwd fwd_req; - int ret = 0, request; - GRilResponseFunc response_func; - if (action == CF_ACTION_INTERROGATE) { - request = RIL_REQUEST_QUERY_CALL_FORWARD_STATUS; - response_func = ril_query_call_fwd_cb; - } else { - request = RIL_REQUEST_SET_CALL_FORWARD; - response_func = ril_set_forward_cb; - } +/* + * Modem seems to respond with error to all queries or settings made with + * bearer class BEARER_CLASS_DEFAULT. Design decision: If given class is + * BEARER_CLASS_DEFAULT let's map it to SERVICE_CLASS_NONE as with it e.g. + * ./send-ussd '*21*#' returns cls:53 i.e. 1+4+16+32 as + * service class. +*/ +#define FIXUP_CLS() \ + if (cls == BEARER_CLASS_DEFAULT) \ + cls = SERVICE_CLASS_NONE \ - DBG("%s - %s", ril_request_id_to_string(request), - cf_action_to_string(action)); +/* + * Activation/deactivation/erasure actions, have no number associated with them, + * but apparently rild expects a number anyway. So fields need to be filled. + * Otherwise there is no response. + */ +#define APPEND_DUMMY_NUMBER() \ + parcel_w_int32(&rilp, 0x81); \ + parcel_w_string(&rilp, "1234567890") \ - /* - * Modem seems to respond with error to all queries - * or settings made with bearer class - * BEARER_CLASS_DEFAULT. Design decision: If given - * class is BEARER_CLASS_DEFAULT let's map it to - * SERVICE_CLASS_NONE as with it e.g. ./send-ussd '*21*#' - * returns cls:53 i.e. 1+4+16+32 as service class. - */ - if (cls == BEARER_CLASS_DEFAULT) - cls = SERVICE_CLASS_NONE; - - fd->last_action = action; - fd->last_cls = cls; - - fwd_req.action = (int) action; - fwd_req.type = type; - fwd_req.cls = cls; - fwd_req.number = number; - - /* - * time has no real meaing for action commands other - * then registration, so if not needed, set arbitrary - * 60s time so rild doesn't return an error. - */ - if (time == -1) - fwd_req.time = 60; - else - fwd_req.time = time; - - g_ril_request_call_fwd(fd->ril, &fwd_req, &rilp); - - ret = g_ril_send(fd->ril, request, &rilp, response_func, cbd, g_free); - if (ret == 0) - ofono_error("%s: CF action %s failed", __func__, - cf_action_to_string(action)); - return ret; -} +/* + * Time has no real meaing for action commands other then registration, so + * if not needed, set arbitrary 60s time so rild doesn't return an error. + */ +#define APPEND_DUMMY_TIME() \ + parcel_w_int32(&rilp, 60); static void ril_activate(struct ofono_call_forwarding *cf, int type, int cls, ofono_call_forwarding_set_cb_t cb, void *data) { + struct forw_data *fd = ofono_call_forwarding_get_data(cf); struct cb_data *cbd = cb_data_new(cb, data, cf); + struct parcel rilp; - if (ril_send_forward_cmd(type, cls, NULL, -1, cbd, - CF_ACTION_ENABLE) == 0) { - CALLBACK_WITH_FAILURE(cb, cbd->data); - g_free(cbd); - } + FIXUP_CLS(); + + parcel_init(&rilp); + + parcel_w_int32(&rilp, 1); /* Activation: 1 */ + parcel_w_int32(&rilp, type); + parcel_w_int32(&rilp, cls); + APPEND_DUMMY_NUMBER(); + APPEND_DUMMY_TIME(); + + g_ril_append_print_buf(fd->ril, "(action: 1, type: %d cls: %d " + "number type: %d number: %s time: %d)", + type, cls, 0x81, "1234567890", 60); + + if (g_ril_send(fd->ril, RIL_REQUEST_SET_CALL_FORWARD, + &rilp, ril_set_forward_cb, cbd, g_free) > 0) + return; + + CALLBACK_WITH_FAILURE(cb, cbd->data); + g_free(cbd); } static void ril_erasure(struct ofono_call_forwarding *cf, int type, int cls, ofono_call_forwarding_set_cb_t cb, void *data) { + struct forw_data *fd = ofono_call_forwarding_get_data(cf); struct cb_data *cbd = cb_data_new(cb, data, cf); + struct parcel rilp; - if (ril_send_forward_cmd(type, cls, NULL, -1, cbd, - CF_ACTION_ERASURE) == 0) { - CALLBACK_WITH_FAILURE(cb, cbd->data); - g_free(cbd); - } + FIXUP_CLS(); + + parcel_init(&rilp); + + parcel_w_int32(&rilp, 4); /* Erasure: 4 */ + parcel_w_int32(&rilp, type); + parcel_w_int32(&rilp, cls); + APPEND_DUMMY_NUMBER(); + APPEND_DUMMY_TIME(); + + g_ril_append_print_buf(fd->ril, "(action: 4, type: %d cls: %d " + "number type: %d number: %s time: %d)", + type, cls, 0x81, "1234567890", 60); + + if (g_ril_send(fd->ril, RIL_REQUEST_SET_CALL_FORWARD, + &rilp, ril_set_forward_cb, cbd, g_free) > 0) + return; + + CALLBACK_WITH_FAILURE(cb, cbd->data); + g_free(cbd); } static void ril_deactivate(struct ofono_call_forwarding *cf, int type, int cls, ofono_call_forwarding_set_cb_t cb, void *data) { + struct forw_data *fd = ofono_call_forwarding_get_data(cf); struct cb_data *cbd = cb_data_new(cb, data, cf); + struct parcel rilp; - if (ril_send_forward_cmd(type, cls, NULL, -1, cbd, - CF_ACTION_DISABLE) == 0) { - CALLBACK_WITH_FAILURE(cb, cbd->data); - g_free(cbd); - } + FIXUP_CLS(); + + parcel_init(&rilp); + + parcel_w_int32(&rilp, 0); /* Deactivation: 0 */ + parcel_w_int32(&rilp, type); + parcel_w_int32(&rilp, cls); + APPEND_DUMMY_NUMBER(); + APPEND_DUMMY_TIME(); + + g_ril_append_print_buf(fd->ril, "(action: 0, type: %d cls: %d " + "number type: %d number: %s time: %d)", + type, cls, 0x81, "1234567890", 60); + + if (g_ril_send(fd->ril, RIL_REQUEST_SET_CALL_FORWARD, + &rilp, ril_set_forward_cb, cbd, g_free) > 0) + return; + + CALLBACK_WITH_FAILURE(cb, cbd->data); + g_free(cbd); } static void ril_registration(struct ofono_call_forwarding *cf, int type, @@ -241,26 +229,64 @@ static void ril_registration(struct ofono_call_forwarding *cf, int type, int time, ofono_call_forwarding_set_cb_t cb, void *data) { + struct forw_data *fd = ofono_call_forwarding_get_data(cf); struct cb_data *cbd = cb_data_new(cb, data, cf); + struct parcel rilp; - if (ril_send_forward_cmd(type, cls, number, time, cbd, - CF_ACTION_REGISTRATION) == 0) { - CALLBACK_WITH_FAILURE(cb, cbd->data); - g_free(cbd); - } + FIXUP_CLS(); + + parcel_init(&rilp); + + parcel_w_int32(&rilp, 3); /* Registration: 3 */ + parcel_w_int32(&rilp, type); + parcel_w_int32(&rilp, cls); + parcel_w_int32(&rilp, number->type); + parcel_w_string(&rilp, number->number); + parcel_w_int32(&rilp, time); + + g_ril_append_print_buf(fd->ril, "(action: 3, type: %d cls: %d " + "number type: %d number: %s time: %d)", + type, cls, number->type, number->number, + time); + + if (g_ril_send(fd->ril, RIL_REQUEST_SET_CALL_FORWARD, + &rilp, ril_set_forward_cb, cbd, g_free) > 0) + return; + + CALLBACK_WITH_FAILURE(cb, cbd->data); + g_free(cbd); } static void ril_query(struct ofono_call_forwarding *cf, int type, int cls, ofono_call_forwarding_query_cb_t cb, void *data) { + struct forw_data *fd = ofono_call_forwarding_get_data(cf); struct cb_data *cbd = cb_data_new(cb, data, cf); + struct parcel rilp; - if (ril_send_forward_cmd(type, cls, NULL, -1, cbd, - CF_ACTION_INTERROGATE) == 0) { - CALLBACK_WITH_FAILURE(cb, 0, NULL, cbd->data); - g_free(cbd); - } + FIXUP_CLS(); + + parcel_init(&rilp); + + parcel_w_int32(&rilp, 2); /* Interrogation: 2 */ + parcel_w_int32(&rilp, type); + parcel_w_int32(&rilp, cls); + APPEND_DUMMY_NUMBER(); + APPEND_DUMMY_TIME(); + + g_ril_append_print_buf(fd->ril, "(action: 2, type: %d cls: %d " + "number type: %d number: %s time: %d)", + type, cls, 0x81, "1234567890", 60); + + fd->last_cls = cls; + + if (g_ril_send(fd->ril, RIL_REQUEST_QUERY_CALL_FORWARD_STATUS, + &rilp, ril_query_call_fwd_cb, cbd, g_free) > 0) + return; + + CALLBACK_WITH_FAILURE(cb, 0, NULL, cbd->data); + g_free(cbd); } static gboolean ril_delayed_register(gpointer user_data)