rilmodem: Refactor ril_data_reg_cb

This commit is contained in:
Denis Kenzior 2015-12-03 10:03:35 -06:00
parent 80e1e92b76
commit c99a5303c9
2 changed files with 148 additions and 60 deletions

View File

@ -155,7 +155,13 @@ static void ril_data_reg_cb(struct ril_msg *message, gpointer user_data)
ofono_gprs_status_cb_t cb = cbd->cb; ofono_gprs_status_cb_t cb = cbd->cb;
struct ofono_gprs *gprs = cbd->user; struct ofono_gprs *gprs = cbd->user;
struct ril_gprs_data *gd = ofono_gprs_get_data(gprs); struct ril_gprs_data *gd = ofono_gprs_get_data(gprs);
struct reply_data_reg_state *reply; struct parcel rilp;
int num_str;
char **strv;
char *debug_str;
char *end;
int status;
int tech = -1;
gboolean attached = FALSE; gboolean attached = FALSE;
gboolean notify_status = FALSE; gboolean notify_status = FALSE;
int old_status; int old_status;
@ -169,27 +175,68 @@ static void ril_data_reg_cb(struct ril_msg *message, gpointer user_data)
goto error; goto error;
} }
reply = g_ril_reply_parse_data_reg_state(gd->ril, message); g_ril_init_parcel(message, &rilp);
if (reply == NULL) strv = parcel_r_strv(&rilp);
num_str = g_strv_length(strv);
if (strv == NULL)
goto error; goto error;
debug_str = g_strjoinv(",", strv);
g_ril_append_print_buf(gd->ril, "{%d,%s}", num_str, debug_str);
g_free(debug_str);
g_ril_print_response(gd->ril, message);
status = strtoul(strv[0], &end, 10);
if (end == strv[0] || *end != '\0')
goto error_free;
status = ril_util_registration_state_to_status(status);
if (status < 0)
goto error_free;
if (num_str >= 4) {
tech = strtoul(strv[3], &end, 10);
if (end == strv[3] || *end != '\0')
tech = -1;
if (g_ril_vendor(gd->ril) == OFONO_RIL_VENDOR_MTK) {
switch (tech) {
case MTK_RADIO_TECH_HSDPAP:
case MTK_RADIO_TECH_HSDPAP_UPA:
case MTK_RADIO_TECH_HSUPAP:
case MTK_RADIO_TECH_HSUPAP_DPA:
tech = RADIO_TECH_HSPAP;
break;
case MTK_RADIO_TECH_DC_DPA:
tech = RADIO_TECH_HSDPA;
break;
case MTK_RADIO_TECH_DC_UPA:
tech = RADIO_TECH_HSUPA;
break;
case MTK_RADIO_TECH_DC_HSDPAP:
case MTK_RADIO_TECH_DC_HSDPAP_UPA:
case MTK_RADIO_TECH_DC_HSDPAP_DPA:
case MTK_RADIO_TECH_DC_HSPAP:
tech = RADIO_TECH_HSPAP;
break;
}
}
}
/* /*
* There are three cases that can result in this callback * There are two cases that can result in this callback
* running: * running:
* *
* 1) The driver's probe() method was called, and thus an * 1) ril_gprs_state_change() is called due to an unsolicited
* internal call to ril_gprs_registration_status() is
* generated. No ofono cb exists.
*
* 2) ril_gprs_state_change() is called due to an unsolicited
* event from RILD. No ofono cb exists. * event from RILD. No ofono cb exists.
* *
* 3) The ofono code code calls the driver's attached_status() * 2) The ofono code code calls the driver's attached_status()
* function. A valid ofono cb exists. * function. A valid ofono cb exists.
*/ */
if (gd->rild_status != reply->reg_state.status) { if (gd->rild_status != status) {
gd->rild_status = reply->reg_state.status; gd->rild_status = status;
if (cb == NULL) if (cb == NULL)
notify_status = TRUE; notify_status = TRUE;
@ -200,15 +247,12 @@ static void ril_data_reg_cb(struct ril_msg *message, gpointer user_data)
* attached status set by the core GPRS code ( controlled * attached status set by the core GPRS code ( controlled
* by the ConnnectionManager's 'Powered' property ). * by the ConnnectionManager's 'Powered' property ).
*/ */
attached = (reply->reg_state.status == attached = status == NETWORK_REGISTRATION_STATUS_REGISTERED ||
NETWORK_REGISTRATION_STATUS_REGISTERED || status == NETWORK_REGISTRATION_STATUS_ROAMING;
reply->reg_state.status ==
NETWORK_REGISTRATION_STATUS_ROAMING);
if (attached && gd->ofono_attached == FALSE) { if (attached && gd->ofono_attached == FALSE) {
DBG("attached=true; ofono_attached=false; return !REGISTERED"); DBG("attached=true; ofono_attached=false; return !REGISTERED");
reply->reg_state.status = status = NETWORK_REGISTRATION_STATUS_NOT_REGISTERED;
NETWORK_REGISTRATION_STATUS_NOT_REGISTERED;
/* /*
* Further optimization so that if ril_status == * Further optimization so that if ril_status ==
@ -218,40 +262,12 @@ static void ril_data_reg_cb(struct ril_msg *message, gpointer user_data)
* As is, this results in unecessary status notify calls * As is, this results in unecessary status notify calls
* when nothing has changed. * when nothing has changed.
*/ */
if (notify_status && reply->reg_state.status == old_status) if (notify_status && status == old_status)
notify_status = FALSE; notify_status = FALSE;
} }
if (old_status == -1) {
ofono_gprs_register(gprs);
/* Different rild implementations use different events here */
g_ril_register(gd->ril,
gd->state_changed_unsol,
ril_gprs_state_change, gprs);
if (reply->max_cids == 0)
gd->max_cids = RIL_MAX_NUM_ACTIVE_DATA_CALLS;
else if (reply->max_cids < RIL_MAX_NUM_ACTIVE_DATA_CALLS)
gd->max_cids = reply->max_cids;
else
gd->max_cids = RIL_MAX_NUM_ACTIVE_DATA_CALLS;
DBG("Setting max cids to %d", gd->max_cids);
ofono_gprs_set_cid_range(gprs, 1, gd->max_cids);
/*
* This callback is a result of the inital call
* to probe(), so should return after registration.
*/
g_free(reply);
return;
}
/* Just need to notify ofono if it's already attached */ /* Just need to notify ofono if it's already attached */
if (notify_status) { if (notify_status) {
/* /*
* If network disconnect has occurred, call detached_notify() * If network disconnect has occurred, call detached_notify()
* instead of status_notify(). * instead of status_notify().
@ -262,26 +278,27 @@ static void ril_data_reg_cb(struct ril_msg *message, gpointer user_data)
NETWORK_REGISTRATION_STATUS_ROAMING)) { NETWORK_REGISTRATION_STATUS_ROAMING)) {
DBG("calling ofono_gprs_detached_notify()"); DBG("calling ofono_gprs_detached_notify()");
ofono_gprs_detached_notify(gprs); ofono_gprs_detached_notify(gprs);
reply->reg_state.tech = RADIO_TECH_UNKNOWN; tech = RADIO_TECH_UNKNOWN;
} else { } else {
DBG("calling ofono_gprs_status_notify()"); DBG("calling ofono_gprs_status_notify()");
ofono_gprs_status_notify(gprs, reply->reg_state.status); ofono_gprs_status_notify(gprs, status);
} }
} }
if (gd->tech != reply->reg_state.tech) { if (gd->tech != tech) {
gd->tech = reply->reg_state.tech; gd->tech = tech;
ofono_gprs_bearer_notify(gprs, ofono_gprs_bearer_notify(gprs, ril_tech_to_bearer_tech(tech));
ril_tech_to_bearer_tech(reply->reg_state.tech));
} }
if (cb) if (cb)
CALLBACK_WITH_SUCCESS(cb, reply->reg_state.status, cbd->data); CALLBACK_WITH_SUCCESS(cb, status, cbd->data);
g_free(reply);
return; return;
error_free:
g_strfreev(strv);
error: error:
/* /*
@ -317,6 +334,79 @@ void ril_gprs_registration_status(struct ofono_gprs *gprs,
} }
} }
static void query_max_cids_cb(struct ril_msg *message, gpointer user_data)
{
struct ofono_gprs *gprs = user_data;
struct ril_gprs_data *gd = ofono_gprs_get_data(gprs);
struct parcel rilp;
int num_str;
char **strv;
char *debug_str;
char *end;
int max_calls = 2;
if (message->error != RIL_E_SUCCESS) {
ofono_error("%s: DATA_REGISTRATION_STATE reply failure: %s",
__func__,
ril_error_to_string(message->error));
goto error;
}
g_ril_init_parcel(message, &rilp);
strv = parcel_r_strv(&rilp);
if (strv == NULL)
goto error;
num_str = g_strv_length(strv);
debug_str = g_strjoinv(",", strv);
g_ril_append_print_buf(gd->ril, "{%d,%s}", num_str, debug_str);
g_free(debug_str);
g_ril_print_response(gd->ril, message);
if (num_str < 6)
goto reg_atom;
max_calls = strtoul(strv[5], &end, 10);
if (end == strv[5] || *end != '\0')
goto error_free;
reg_atom:
g_strfreev(strv);
ofono_gprs_set_cid_range(gprs, 1, max_calls);
ofono_gprs_register(gprs);
return;
error_free:
g_strfreev(strv);
error:
ofono_error("Unable to query max CIDs");
ofono_gprs_remove(gprs);
}
static void query_max_cids(struct ofono_gprs *gprs)
{
struct ril_gprs_data *gd = ofono_gprs_get_data(gprs);
g_ril_register(gd->ril, gd->state_changed_unsol,
ril_gprs_state_change, gprs);
/*
* MTK modem does not return max_cids, string, so hard-code it
* here
*/
if (g_ril_vendor(gd->ril) == OFONO_RIL_VENDOR_MTK) {
ofono_gprs_set_cid_range(gprs, 1, 3);
ofono_gprs_register(gprs);
return;
}
if (g_ril_send(gd->ril, RIL_REQUEST_DATA_REGISTRATION_STATE, NULL,
query_max_cids_cb, gprs, NULL) < 0)
ofono_gprs_remove(gprs);
}
static void drop_data_call_cb(struct ril_msg *message, gpointer user_data) static void drop_data_call_cb(struct ril_msg *message, gpointer user_data)
{ {
struct ofono_gprs *gprs = user_data; struct ofono_gprs *gprs = user_data;
@ -329,7 +419,7 @@ static void drop_data_call_cb(struct ril_msg *message, gpointer user_data)
ril_error_to_string(message->error)); ril_error_to_string(message->error));
if (--(gd->pending_deact_req) == 0) if (--(gd->pending_deact_req) == 0)
ril_gprs_registration_status(gprs, NULL, NULL); query_max_cids(gprs);
} }
static int drop_data_call(struct ofono_gprs *gprs, int cid) static int drop_data_call(struct ofono_gprs *gprs, int cid)
@ -383,7 +473,7 @@ static void get_active_data_calls_cb(struct ril_msg *message,
end: end:
if (gd->pending_deact_req == 0) if (gd->pending_deact_req == 0)
ril_gprs_registration_status(gprs, NULL, NULL); query_max_cids(gprs);
} }
static void get_active_data_calls(struct ofono_gprs *gprs) static void get_active_data_calls(struct ofono_gprs *gprs)
@ -401,7 +491,6 @@ void ril_gprs_start(struct ril_gprs_driver_data *driver_data,
gd->ril = g_ril_clone(driver_data->gril); gd->ril = g_ril_clone(driver_data->gril);
gd->modem = driver_data->modem; gd->modem = driver_data->modem;
gd->ofono_attached = FALSE; gd->ofono_attached = FALSE;
gd->max_cids = 0;
gd->rild_status = -1; gd->rild_status = -1;
gd->tech = RADIO_TECH_UNKNOWN; gd->tech = RADIO_TECH_UNKNOWN;
/* AOSP RILD tracks data network state together with voice */ /* AOSP RILD tracks data network state together with voice */

View File

@ -25,7 +25,6 @@ struct ril_gprs_data {
GRil *ril; GRil *ril;
struct ofono_modem *modem; struct ofono_modem *modem;
gboolean ofono_attached; gboolean ofono_attached;
unsigned int max_cids;
int rild_status; int rild_status;
int tech; int tech;
int state_changed_unsol; int state_changed_unsol;