qmi: activate default bearer context for LTE networks

When the modem attaches to an LTE network, a default bearer is
automatically negotiated using the "defalt profile" settings.  The
QMI modem, however, does not given any explicit indication that
the bearer exists; instead, we must assume its existence based on
the network registration state.

This patch extends the GPRS atom to signal the presence of a
default bearer when it detects network connectivity on an LTE
network.
This commit is contained in:
Jonas Bonn 2017-04-29 14:46:43 +02:00 committed by Denis Kenzior
parent 10854cb459
commit 4651a70285
1 changed files with 50 additions and 12 deletions

View File

@ -37,10 +37,11 @@ struct gprs_data {
struct qmi_service *nas; struct qmi_service *nas;
}; };
static bool extract_ss_info(struct qmi_result *result, int *status) static bool extract_ss_info(struct qmi_result *result, int *status, int *tech)
{ {
const struct qmi_nas_serving_system *ss; const struct qmi_nas_serving_system *ss;
uint16_t len; uint16_t len;
int i;
DBG(""); DBG("");
@ -53,9 +54,41 @@ static bool extract_ss_info(struct qmi_result *result, int *status)
else else
*status = NETWORK_REGISTRATION_STATUS_NOT_REGISTERED; *status = NETWORK_REGISTRATION_STATUS_NOT_REGISTERED;
*tech = -1;
for (i = 0; i < ss->radio_if_count; i++) {
DBG("radio in use %d", ss->radio_if[i]);
*tech = qmi_nas_rat_to_tech(ss->radio_if[i]);
}
return true; return true;
} }
static int handle_ss_info(struct qmi_result *result, struct ofono_gprs *gprs)
{
int status;
int tech;
DBG("");
if (!extract_ss_info(result, &status, &tech))
return -1;
if (status == NETWORK_REGISTRATION_STATUS_REGISTERED)
if (tech == ACCESS_TECHNOLOGY_EUTRAN) {
/* On LTE we are effectively always attached; and
* the default bearer is established as soon as the
* network is joined.
*/
/* FIXME: query default profile number and APN
* instead of assuming profile 1 and ""
*/
ofono_gprs_cid_activated(gprs, 1 , "");
}
return status;
}
static void ss_info_notify(struct qmi_result *result, void *user_data) static void ss_info_notify(struct qmi_result *result, void *user_data)
{ {
struct ofono_gprs *gprs = user_data; struct ofono_gprs *gprs = user_data;
@ -63,10 +96,10 @@ static void ss_info_notify(struct qmi_result *result, void *user_data)
DBG(""); DBG("");
if (!extract_ss_info(result, &status)) status = handle_ss_info(result, gprs);
return;
ofono_gprs_status_notify(gprs, status); if (status >= 0)
ofono_gprs_status_notify(gprs, status);
} }
static void attach_detach_cb(struct qmi_result *result, void *user_data) static void attach_detach_cb(struct qmi_result *result, void *user_data)
@ -125,22 +158,26 @@ error:
static void get_ss_info_cb(struct qmi_result *result, void *user_data) static void get_ss_info_cb(struct qmi_result *result, void *user_data)
{ {
struct cb_data *cbd = user_data; struct cb_data *cbd = user_data;
struct ofono_gprs *gprs = cbd->user;
ofono_gprs_status_cb_t cb = cbd->cb; ofono_gprs_status_cb_t cb = cbd->cb;
int status; int status;
DBG(""); DBG("");
if (qmi_result_set_error(result, NULL)) { if (qmi_result_set_error(result, NULL))
CALLBACK_WITH_FAILURE(cb, -1, cbd->data); goto error;
return;
}
if (!extract_ss_info(result, &status)) { status = handle_ss_info(result, gprs);
CALLBACK_WITH_FAILURE(cb, -1, cbd->data);
return; if (status < 0)
} goto error;
CALLBACK_WITH_SUCCESS(cb, status, cbd->data); CALLBACK_WITH_SUCCESS(cb, status, cbd->data);
return;
error:
CALLBACK_WITH_FAILURE(cb, -1, cbd->data);
} }
static void qmi_attached_status(struct ofono_gprs *gprs, static void qmi_attached_status(struct ofono_gprs *gprs,
@ -151,6 +188,7 @@ static void qmi_attached_status(struct ofono_gprs *gprs,
DBG(""); DBG("");
cbd->user = gprs;
if (qmi_service_send(data->nas, QMI_NAS_GET_SS_INFO, NULL, if (qmi_service_send(data->nas, QMI_NAS_GET_SS_INFO, NULL,
get_ss_info_cb, cbd, g_free) > 0) get_ss_info_cb, cbd, g_free) > 0)
return; return;