broadband-modem-qmi: implement CDMA registration checks for NAS < 1.8
This commit is contained in:
@@ -3882,6 +3882,230 @@ modem_3gpp_enable_unsolicited_registration_events (MMIfaceModem3gpp *self,
|
|||||||
unsolicited_registration_events_context_complete_and_free (ctx);
|
unsolicited_registration_events_context_complete_and_free (ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/* Registration checks (CDMA interface) */
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
MMBroadbandModemQmi *self;
|
||||||
|
QmiClientNas *client;
|
||||||
|
GSimpleAsyncResult *result;
|
||||||
|
} RunCdmaRegistrationChecksContext;
|
||||||
|
|
||||||
|
static void
|
||||||
|
run_cdma_registration_checks_context_complete_and_free (RunCdmaRegistrationChecksContext *ctx)
|
||||||
|
{
|
||||||
|
g_simple_async_result_complete (ctx->result);
|
||||||
|
g_object_unref (ctx->result);
|
||||||
|
g_object_unref (ctx->client);
|
||||||
|
g_object_unref (ctx->self);
|
||||||
|
g_slice_free (RunCdmaRegistrationChecksContext, ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
modem_cdma_run_registration_checks_finish (MMIfaceModemCdma *self,
|
||||||
|
GAsyncResult *res,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error);
|
||||||
|
}
|
||||||
|
|
||||||
|
static MMModemCdmaRegistrationState
|
||||||
|
qmi_registration_state_to_cdma_registration_state (QmiNasRegistrationState registration_state)
|
||||||
|
{
|
||||||
|
switch (registration_state) {
|
||||||
|
case QMI_NAS_REGISTRATION_STATE_REGISTERED:
|
||||||
|
return MM_MODEM_CDMA_REGISTRATION_STATE_REGISTERED;
|
||||||
|
case QMI_NAS_REGISTRATION_STATE_NOT_REGISTERED:
|
||||||
|
case QMI_NAS_REGISTRATION_STATE_NOT_REGISTERED_SEARCHING:
|
||||||
|
case QMI_NAS_REGISTRATION_STATE_REGISTRATION_DENIED:
|
||||||
|
case QMI_NAS_REGISTRATION_STATE_UNKNOWN:
|
||||||
|
default:
|
||||||
|
return MM_MODEM_3GPP_REGISTRATION_STATE_UNKNOWN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
common_process_serving_system_cdma (MMBroadbandModemQmi *self,
|
||||||
|
QmiMessageNasGetServingSystemOutput *response_output,
|
||||||
|
QmiIndicationNasServingSystemOutput *indication_output)
|
||||||
|
{
|
||||||
|
QmiNasRegistrationState registration_state;
|
||||||
|
QmiNasNetworkType selected_network;
|
||||||
|
GArray *radio_interfaces;
|
||||||
|
GArray *data_service_capabilities;
|
||||||
|
QmiNasServiceStatus hdr_status;
|
||||||
|
gboolean hdr_hybrid;
|
||||||
|
MMModemAccessTechnology mm_access_technologies;
|
||||||
|
MMModemCdmaRegistrationState mm_cdma1x_registration_state;
|
||||||
|
MMModemCdmaRegistrationState mm_evdo_registration_state;
|
||||||
|
guint16 sid;
|
||||||
|
guint16 nid;
|
||||||
|
|
||||||
|
if (response_output)
|
||||||
|
qmi_message_nas_get_serving_system_output_get_serving_system (
|
||||||
|
response_output,
|
||||||
|
®istration_state,
|
||||||
|
NULL, /* cs_attach_state */
|
||||||
|
NULL, /* ps_attach_state */
|
||||||
|
&selected_network,
|
||||||
|
&radio_interfaces,
|
||||||
|
NULL);
|
||||||
|
else
|
||||||
|
qmi_indication_nas_serving_system_output_get_serving_system (
|
||||||
|
indication_output,
|
||||||
|
®istration_state,
|
||||||
|
NULL, /* cs_attach_state */
|
||||||
|
NULL, /* ps_attach_state */
|
||||||
|
&selected_network,
|
||||||
|
&radio_interfaces,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
/* Only process 3GPP2 info */
|
||||||
|
if (selected_network != QMI_NAS_NETWORK_TYPE_3GPP2) {
|
||||||
|
mm_iface_modem_cdma_update_cdma1x_registration_state (MM_IFACE_MODEM_CDMA (self),
|
||||||
|
MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN,
|
||||||
|
0, 0);
|
||||||
|
mm_iface_modem_cdma_update_evdo_registration_state (MM_IFACE_MODEM_CDMA (self),
|
||||||
|
MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN);
|
||||||
|
mm_iface_modem_cdma_update_access_technologies (MM_IFACE_MODEM_CDMA (self),
|
||||||
|
MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get SID/NID */
|
||||||
|
if (response_output)
|
||||||
|
qmi_message_nas_get_serving_system_output_get_cdma_system_id (response_output, &sid, &nid, NULL);
|
||||||
|
else
|
||||||
|
qmi_indication_nas_serving_system_output_get_cdma_system_id (indication_output, &sid, &nid, NULL);
|
||||||
|
|
||||||
|
/* Build access technologies mask */
|
||||||
|
data_service_capabilities = NULL;
|
||||||
|
if (response_output)
|
||||||
|
qmi_message_nas_get_serving_system_output_get_data_service_capability (response_output,
|
||||||
|
&data_service_capabilities,
|
||||||
|
NULL);
|
||||||
|
else
|
||||||
|
qmi_indication_nas_serving_system_output_get_data_service_capability (indication_output,
|
||||||
|
&data_service_capabilities,
|
||||||
|
NULL);
|
||||||
|
if (data_service_capabilities)
|
||||||
|
mm_access_technologies =
|
||||||
|
qmi_data_capability_list_to_access_technologies (data_service_capabilities);
|
||||||
|
else
|
||||||
|
mm_access_technologies =
|
||||||
|
qmi_radio_interface_list_to_access_technologies (radio_interfaces);
|
||||||
|
|
||||||
|
/* TODO: Roaming flags */
|
||||||
|
|
||||||
|
/* Build registration states */
|
||||||
|
mm_cdma1x_registration_state = qmi_registration_state_to_cdma_registration_state (registration_state);
|
||||||
|
|
||||||
|
hdr_status = QMI_NAS_SERVICE_STATUS_NONE;
|
||||||
|
hdr_hybrid = FALSE;
|
||||||
|
if (response_output)
|
||||||
|
qmi_message_nas_get_serving_system_output_get_detailed_service_status (
|
||||||
|
response_output,
|
||||||
|
NULL, /* status */
|
||||||
|
NULL, /* capability */
|
||||||
|
&hdr_status,
|
||||||
|
&hdr_hybrid,
|
||||||
|
NULL, /* forbidden */
|
||||||
|
NULL);
|
||||||
|
else
|
||||||
|
qmi_indication_nas_serving_system_output_get_detailed_service_status (
|
||||||
|
indication_output,
|
||||||
|
NULL, /* status */
|
||||||
|
NULL, /* capability */
|
||||||
|
&hdr_status,
|
||||||
|
&hdr_hybrid,
|
||||||
|
NULL, /* forbidden */
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
if (hdr_hybrid &&
|
||||||
|
(hdr_status == QMI_NAS_SERVICE_STATUS_LIMITED ||
|
||||||
|
hdr_status == QMI_NAS_SERVICE_STATUS_AVAILABLE ||
|
||||||
|
hdr_status == QMI_NAS_SERVICE_STATUS_LIMITED_REGIONAL ||
|
||||||
|
hdr_status == QMI_NAS_SERVICE_STATUS_POWER_SAVE))
|
||||||
|
mm_evdo_registration_state = MM_MODEM_CDMA_REGISTRATION_STATE_REGISTERED;
|
||||||
|
else
|
||||||
|
mm_evdo_registration_state = MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN;
|
||||||
|
|
||||||
|
/* Report new registration states */
|
||||||
|
mm_iface_modem_cdma_update_cdma1x_registration_state (MM_IFACE_MODEM_CDMA (self),
|
||||||
|
mm_cdma1x_registration_state,
|
||||||
|
sid,
|
||||||
|
nid);
|
||||||
|
mm_iface_modem_cdma_update_evdo_registration_state (MM_IFACE_MODEM_CDMA (self),
|
||||||
|
mm_evdo_registration_state);
|
||||||
|
mm_iface_modem_cdma_update_access_technologies (MM_IFACE_MODEM_CDMA (self),
|
||||||
|
mm_access_technologies);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
get_serving_system_cdma_ready (QmiClientNas *client,
|
||||||
|
GAsyncResult *res,
|
||||||
|
RunCdmaRegistrationChecksContext *ctx)
|
||||||
|
{
|
||||||
|
QmiMessageNasGetServingSystemOutput *output;
|
||||||
|
GError *error = NULL;
|
||||||
|
|
||||||
|
output = qmi_client_nas_get_serving_system_finish (client, res, &error);
|
||||||
|
if (!output) {
|
||||||
|
g_prefix_error (&error, "QMI operation failed: ");
|
||||||
|
g_simple_async_result_take_error (ctx->result, error);
|
||||||
|
run_cdma_registration_checks_context_complete_and_free (ctx);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!qmi_message_nas_get_serving_system_output_get_result (output, &error)) {
|
||||||
|
g_prefix_error (&error, "Couldn't get serving system: ");
|
||||||
|
g_simple_async_result_take_error (ctx->result, error);
|
||||||
|
qmi_message_nas_get_serving_system_output_unref (output);
|
||||||
|
run_cdma_registration_checks_context_complete_and_free (ctx);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
common_process_serving_system_cdma (ctx->self, output, NULL);
|
||||||
|
|
||||||
|
qmi_message_nas_get_serving_system_output_unref (output);
|
||||||
|
g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE);
|
||||||
|
run_cdma_registration_checks_context_complete_and_free (ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
modem_cdma_run_registration_checks (MMIfaceModemCdma *self,
|
||||||
|
gboolean cdma1x_supported,
|
||||||
|
gboolean evdo_supported,
|
||||||
|
GAsyncReadyCallback callback,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
RunCdmaRegistrationChecksContext *ctx;
|
||||||
|
QmiClient *client = NULL;
|
||||||
|
|
||||||
|
if (!ensure_qmi_client (MM_BROADBAND_MODEM_QMI (self),
|
||||||
|
QMI_SERVICE_NAS, &client,
|
||||||
|
callback, user_data))
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Setup context */
|
||||||
|
ctx = g_slice_new0 (RunCdmaRegistrationChecksContext);
|
||||||
|
ctx->self = g_object_ref (self);
|
||||||
|
ctx->client = g_object_ref (client);
|
||||||
|
ctx->result = g_simple_async_result_new (G_OBJECT (self),
|
||||||
|
callback,
|
||||||
|
user_data,
|
||||||
|
modem_cdma_run_registration_checks);
|
||||||
|
|
||||||
|
/* TODO: Run Get System Info in NAS >= 1.8 */
|
||||||
|
|
||||||
|
qmi_client_nas_get_serving_system (ctx->client,
|
||||||
|
NULL,
|
||||||
|
10,
|
||||||
|
NULL,
|
||||||
|
(GAsyncReadyCallback)get_serving_system_cdma_ready,
|
||||||
|
ctx);
|
||||||
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* Setup/Cleanup unsolicited registration event handlers
|
/* Setup/Cleanup unsolicited registration event handlers
|
||||||
* (3GPP and CDMA interface) */
|
* (3GPP and CDMA interface) */
|
||||||
@@ -4935,7 +5159,7 @@ iface_modem_cdma_init (MMIfaceModemCdma *iface)
|
|||||||
iface->load_esn = modem_cdma_load_esn;
|
iface->load_esn = modem_cdma_load_esn;
|
||||||
iface->load_esn_finish = modem_cdma_load_esn_finish;
|
iface->load_esn_finish = modem_cdma_load_esn_finish;
|
||||||
|
|
||||||
/* Enabling steps */
|
/* Enabling/Disabling steps */
|
||||||
iface->setup_unsolicited_events = modem_cdma_setup_unsolicited_events;
|
iface->setup_unsolicited_events = modem_cdma_setup_unsolicited_events;
|
||||||
iface->setup_unsolicited_events_finish = modem_cdma_setup_cleanup_unsolicited_events_finish;
|
iface->setup_unsolicited_events_finish = modem_cdma_setup_cleanup_unsolicited_events_finish;
|
||||||
iface->cleanup_unsolicited_events = modem_cdma_cleanup_unsolicited_events;
|
iface->cleanup_unsolicited_events = modem_cdma_cleanup_unsolicited_events;
|
||||||
@@ -4944,6 +5168,10 @@ iface_modem_cdma_init (MMIfaceModemCdma *iface)
|
|||||||
iface->enable_unsolicited_events_finish = modem_cdma_enable_disable_unsolicited_events_finish;
|
iface->enable_unsolicited_events_finish = modem_cdma_enable_disable_unsolicited_events_finish;
|
||||||
iface->disable_unsolicited_events = modem_cdma_disable_unsolicited_events;
|
iface->disable_unsolicited_events = modem_cdma_disable_unsolicited_events;
|
||||||
iface->disable_unsolicited_events_finish = modem_cdma_enable_disable_unsolicited_events_finish;
|
iface->disable_unsolicited_events_finish = modem_cdma_enable_disable_unsolicited_events_finish;
|
||||||
|
|
||||||
|
/* Other actions */
|
||||||
|
iface->run_registration_checks = modem_cdma_run_registration_checks;
|
||||||
|
iface->run_registration_checks_finish = modem_cdma_run_registration_checks_finish;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
Reference in New Issue
Block a user