broadband-modem: implement CDMA registration state and network supported properties
This commit is contained in:
@@ -19,6 +19,7 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <errno.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include <ModemManager.h>
|
#include <ModemManager.h>
|
||||||
@@ -64,6 +65,10 @@ enum {
|
|||||||
PROP_MODEM_3GPP_REGISTRATION_STATE,
|
PROP_MODEM_3GPP_REGISTRATION_STATE,
|
||||||
PROP_MODEM_3GPP_CS_NETWORK_SUPPORTED,
|
PROP_MODEM_3GPP_CS_NETWORK_SUPPORTED,
|
||||||
PROP_MODEM_3GPP_PS_NETWORK_SUPPORTED,
|
PROP_MODEM_3GPP_PS_NETWORK_SUPPORTED,
|
||||||
|
PROP_MODEM_CDMA_CDMA1X_REGISTRATION_STATE,
|
||||||
|
PROP_MODEM_CDMA_EVDO_REGISTRATION_STATE,
|
||||||
|
PROP_MODEM_CDMA_CDMA1X_NETWORK_SUPPORTED,
|
||||||
|
PROP_MODEM_CDMA_EVDO_NETWORK_SUPPORTED,
|
||||||
PROP_MODEM_SIMPLE_STATUS,
|
PROP_MODEM_SIMPLE_STATUS,
|
||||||
PROP_LAST
|
PROP_LAST
|
||||||
};
|
};
|
||||||
@@ -84,6 +89,10 @@ struct _MMBroadbandModemPrivate {
|
|||||||
MMModem3gppRegistrationState modem_3gpp_registration_state;
|
MMModem3gppRegistrationState modem_3gpp_registration_state;
|
||||||
gboolean modem_3gpp_cs_network_supported;
|
gboolean modem_3gpp_cs_network_supported;
|
||||||
gboolean modem_3gpp_ps_network_supported;
|
gboolean modem_3gpp_ps_network_supported;
|
||||||
|
MMModemCdmaRegistrationState modem_cdma_cdma1x_registration_state;
|
||||||
|
MMModemCdmaRegistrationState modem_cdma_evdo_registration_state;
|
||||||
|
gboolean modem_cdma_cdma1x_network_supported;
|
||||||
|
gboolean modem_cdma_evdo_network_supported;
|
||||||
MMCommonSimpleProperties *modem_simple_status;
|
MMCommonSimpleProperties *modem_simple_status;
|
||||||
|
|
||||||
/* Modem helpers */
|
/* Modem helpers */
|
||||||
@@ -2706,6 +2715,258 @@ load_esn (MMIfaceModemCdma *self,
|
|||||||
user_data);
|
user_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/* HDR state (CDMA) */
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
guint8 hybrid_mode;
|
||||||
|
guint8 session_state;
|
||||||
|
guint8 almp_state;
|
||||||
|
} HdrStateResults;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
MMBroadbandModem *self;
|
||||||
|
GSimpleAsyncResult *result;
|
||||||
|
MMQcdmSerialPort *qcdm;
|
||||||
|
} HdrStateContext;
|
||||||
|
|
||||||
|
static void
|
||||||
|
hdr_state_context_complete_and_free (HdrStateContext *ctx)
|
||||||
|
{
|
||||||
|
g_simple_async_result_complete (ctx->result);
|
||||||
|
g_object_unref (ctx->qcdm);
|
||||||
|
g_object_unref (ctx->result);
|
||||||
|
g_object_unref (ctx->self);
|
||||||
|
g_free (ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
get_hdr_state_finish (MMIfaceModemCdma *self,
|
||||||
|
GAsyncResult *res,
|
||||||
|
guint8 *hybrid_mode,
|
||||||
|
guint8 *session_state,
|
||||||
|
guint8 *almp_state,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
HdrStateResults *results;
|
||||||
|
|
||||||
|
if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
results = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res));
|
||||||
|
*hybrid_mode = results->hybrid_mode;
|
||||||
|
*session_state = results->session_state;
|
||||||
|
*almp_state = results->almp_state;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
get_hdr_state_ready (MMQcdmSerialPort *port,
|
||||||
|
GByteArray *response,
|
||||||
|
GError *error,
|
||||||
|
HdrStateContext *ctx)
|
||||||
|
{
|
||||||
|
QcdmResult *result;
|
||||||
|
HdrStateResults *results;
|
||||||
|
gint err = QCDM_SUCCESS;
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
g_simple_async_result_set_from_error (ctx->result, error);
|
||||||
|
hdr_state_context_complete_and_free (ctx);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Parse the response */
|
||||||
|
result = qcdm_cmd_hdr_subsys_state_info_result ((const gchar *) response->data,
|
||||||
|
response->len,
|
||||||
|
&err);
|
||||||
|
if (!result) {
|
||||||
|
g_simple_async_result_set_error (ctx->result,
|
||||||
|
MM_CORE_ERROR,
|
||||||
|
MM_CORE_ERROR_FAILED,
|
||||||
|
"Failed to parse HDR subsys state info command result: %d",
|
||||||
|
err);
|
||||||
|
hdr_state_context_complete_and_free (ctx);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Build results */
|
||||||
|
results = g_new0 (HdrStateResults, 1);
|
||||||
|
qcdm_result_get_u8 (result, QCDM_CMD_HDR_SUBSYS_STATE_INFO_ITEM_HDR_HYBRID_MODE, &results->hybrid_mode);
|
||||||
|
results->session_state = QCDM_CMD_HDR_SUBSYS_STATE_INFO_SESSION_STATE_CLOSED;
|
||||||
|
qcdm_result_get_u8 (result, QCDM_CMD_HDR_SUBSYS_STATE_INFO_ITEM_SESSION_STATE, &results->session_state);
|
||||||
|
results->almp_state = QCDM_CMD_HDR_SUBSYS_STATE_INFO_ALMP_STATE_INACTIVE;
|
||||||
|
qcdm_result_get_u8 (result, QCDM_CMD_HDR_SUBSYS_STATE_INFO_ITEM_ALMP_STATE, &results->almp_state);
|
||||||
|
qcdm_result_unref (result);
|
||||||
|
|
||||||
|
g_simple_async_result_set_op_res_gpointer (ctx->result, results, (GDestroyNotify)g_free);
|
||||||
|
hdr_state_context_complete_and_free (ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
get_hdr_state (MMIfaceModemCdma *self,
|
||||||
|
GAsyncReadyCallback callback,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
MMQcdmSerialPort *qcdm;
|
||||||
|
HdrStateContext *ctx;
|
||||||
|
GByteArray *hdrstate;
|
||||||
|
|
||||||
|
qcdm = mm_base_modem_get_port_qcdm (MM_BASE_MODEM (self));
|
||||||
|
if (!qcdm) {
|
||||||
|
g_simple_async_report_error_in_idle (G_OBJECT (self),
|
||||||
|
callback,
|
||||||
|
user_data,
|
||||||
|
MM_CORE_ERROR,
|
||||||
|
MM_CORE_ERROR_UNSUPPORTED,
|
||||||
|
"Cannot get HDR state without a QCDM port");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Setup context */
|
||||||
|
ctx = g_new0 (HdrStateContext, 1);
|
||||||
|
ctx->self = g_object_ref (self);
|
||||||
|
ctx->result = g_simple_async_result_new (G_OBJECT (self),
|
||||||
|
callback,
|
||||||
|
user_data,
|
||||||
|
get_hdr_state);
|
||||||
|
ctx->qcdm = g_object_ref (qcdm);
|
||||||
|
|
||||||
|
/* Setup command */
|
||||||
|
hdrstate = g_byte_array_sized_new (25);
|
||||||
|
hdrstate->len = qcdm_cmd_hdr_subsys_state_info_new ((gchar *) hdrstate->data, 25);
|
||||||
|
g_assert (hdrstate->len);
|
||||||
|
|
||||||
|
mm_qcdm_serial_port_queue_command (ctx->qcdm,
|
||||||
|
hdrstate,
|
||||||
|
3,
|
||||||
|
(MMQcdmSerialResponseFn)get_hdr_state_ready,
|
||||||
|
ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/* Call Manager state (CDMA) */
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
guint system_mode;
|
||||||
|
guint operating_mode;
|
||||||
|
} CallManagerStateResults;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
MMBroadbandModem *self;
|
||||||
|
GSimpleAsyncResult *result;
|
||||||
|
MMQcdmSerialPort *qcdm;
|
||||||
|
} CallManagerStateContext;
|
||||||
|
|
||||||
|
static void
|
||||||
|
call_manager_state_context_complete_and_free (CallManagerStateContext *ctx)
|
||||||
|
{
|
||||||
|
g_simple_async_result_complete (ctx->result);
|
||||||
|
g_object_unref (ctx->qcdm);
|
||||||
|
g_object_unref (ctx->result);
|
||||||
|
g_object_unref (ctx->self);
|
||||||
|
g_free (ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
get_call_manager_state_finish (MMIfaceModemCdma *self,
|
||||||
|
GAsyncResult *res,
|
||||||
|
guint *system_mode,
|
||||||
|
guint *operating_mode,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
CallManagerStateResults *results;
|
||||||
|
|
||||||
|
if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
results = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res));
|
||||||
|
*system_mode = results->system_mode;
|
||||||
|
*operating_mode = results->operating_mode;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
get_call_manager_state_ready (MMQcdmSerialPort *port,
|
||||||
|
GByteArray *response,
|
||||||
|
GError *error,
|
||||||
|
CallManagerStateContext *ctx)
|
||||||
|
{
|
||||||
|
QcdmResult *result;
|
||||||
|
CallManagerStateResults *results;
|
||||||
|
gint err = QCDM_SUCCESS;
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
g_simple_async_result_set_from_error (ctx->result, error);
|
||||||
|
call_manager_state_context_complete_and_free (ctx);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Parse the response */
|
||||||
|
result = qcdm_cmd_cm_subsys_state_info_result ((const gchar *) response->data,
|
||||||
|
response->len,
|
||||||
|
&err);
|
||||||
|
if (!result) {
|
||||||
|
g_simple_async_result_set_error (ctx->result,
|
||||||
|
MM_CORE_ERROR,
|
||||||
|
MM_CORE_ERROR_FAILED,
|
||||||
|
"Failed to parse CM subsys state info command result: %d",
|
||||||
|
err);
|
||||||
|
call_manager_state_context_complete_and_free (ctx);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Build results */
|
||||||
|
results = g_new0 (CallManagerStateResults, 1);
|
||||||
|
qcdm_result_get_u32 (result, QCDM_CMD_CM_SUBSYS_STATE_INFO_ITEM_OPERATING_MODE, &results->operating_mode);
|
||||||
|
qcdm_result_get_u32 (result, QCDM_CMD_CM_SUBSYS_STATE_INFO_ITEM_SYSTEM_MODE, &results->system_mode);
|
||||||
|
qcdm_result_unref (result);
|
||||||
|
|
||||||
|
g_simple_async_result_set_op_res_gpointer (ctx->result, results, (GDestroyNotify)g_free);
|
||||||
|
call_manager_state_context_complete_and_free (ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
get_call_manager_state (MMIfaceModemCdma *self,
|
||||||
|
GAsyncReadyCallback callback,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
MMQcdmSerialPort *qcdm;
|
||||||
|
CallManagerStateContext *ctx;
|
||||||
|
GByteArray *cmstate;
|
||||||
|
|
||||||
|
qcdm = mm_base_modem_get_port_qcdm (MM_BASE_MODEM (self));
|
||||||
|
if (!qcdm) {
|
||||||
|
g_simple_async_report_error_in_idle (G_OBJECT (self),
|
||||||
|
callback,
|
||||||
|
user_data,
|
||||||
|
MM_CORE_ERROR,
|
||||||
|
MM_CORE_ERROR_UNSUPPORTED,
|
||||||
|
"Cannot get call manager state without a QCDM port");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Setup context */
|
||||||
|
ctx = g_new0 (CallManagerStateContext, 1);
|
||||||
|
ctx->self = g_object_ref (self);
|
||||||
|
ctx->result = g_simple_async_result_new (G_OBJECT (self),
|
||||||
|
callback,
|
||||||
|
user_data,
|
||||||
|
get_call_manager_state);
|
||||||
|
ctx->qcdm = g_object_ref (qcdm);
|
||||||
|
|
||||||
|
/* Setup command */
|
||||||
|
cmstate = g_byte_array_sized_new (25);
|
||||||
|
cmstate->len = qcdm_cmd_cm_subsys_state_info_new ((gchar *) cmstate->data, 25);
|
||||||
|
g_assert (cmstate->len);
|
||||||
|
|
||||||
|
mm_qcdm_serial_port_queue_command (ctx->qcdm,
|
||||||
|
cmstate,
|
||||||
|
3,
|
||||||
|
(MMQcdmSerialResponseFn)get_call_manager_state_ready,
|
||||||
|
ctx);
|
||||||
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
@@ -3390,6 +3651,18 @@ set_property (GObject *object,
|
|||||||
case PROP_MODEM_3GPP_PS_NETWORK_SUPPORTED:
|
case PROP_MODEM_3GPP_PS_NETWORK_SUPPORTED:
|
||||||
self->priv->modem_3gpp_ps_network_supported = g_value_get_boolean (value);
|
self->priv->modem_3gpp_ps_network_supported = g_value_get_boolean (value);
|
||||||
break;
|
break;
|
||||||
|
case PROP_MODEM_CDMA_CDMA1X_REGISTRATION_STATE:
|
||||||
|
self->priv->modem_cdma_cdma1x_registration_state = g_value_get_enum (value);
|
||||||
|
break;
|
||||||
|
case PROP_MODEM_CDMA_EVDO_REGISTRATION_STATE:
|
||||||
|
self->priv->modem_cdma_evdo_registration_state = g_value_get_enum (value);
|
||||||
|
break;
|
||||||
|
case PROP_MODEM_CDMA_CDMA1X_NETWORK_SUPPORTED:
|
||||||
|
self->priv->modem_cdma_cdma1x_network_supported = g_value_get_boolean (value);
|
||||||
|
break;
|
||||||
|
case PROP_MODEM_CDMA_EVDO_NETWORK_SUPPORTED:
|
||||||
|
self->priv->modem_cdma_evdo_network_supported = g_value_get_boolean (value);
|
||||||
|
break;
|
||||||
case PROP_MODEM_SIMPLE_STATUS:
|
case PROP_MODEM_SIMPLE_STATUS:
|
||||||
g_clear_object (&self->priv->modem_simple_status);
|
g_clear_object (&self->priv->modem_simple_status);
|
||||||
self->priv->modem_simple_status = g_value_dup_object (value);
|
self->priv->modem_simple_status = g_value_dup_object (value);
|
||||||
@@ -3442,6 +3715,18 @@ get_property (GObject *object,
|
|||||||
case PROP_MODEM_3GPP_PS_NETWORK_SUPPORTED:
|
case PROP_MODEM_3GPP_PS_NETWORK_SUPPORTED:
|
||||||
g_value_set_boolean (value, self->priv->modem_3gpp_ps_network_supported);
|
g_value_set_boolean (value, self->priv->modem_3gpp_ps_network_supported);
|
||||||
break;
|
break;
|
||||||
|
case PROP_MODEM_CDMA_CDMA1X_REGISTRATION_STATE:
|
||||||
|
g_value_set_enum (value, self->priv->modem_cdma_cdma1x_registration_state);
|
||||||
|
break;
|
||||||
|
case PROP_MODEM_CDMA_EVDO_REGISTRATION_STATE:
|
||||||
|
g_value_set_enum (value, self->priv->modem_cdma_evdo_registration_state);
|
||||||
|
break;
|
||||||
|
case PROP_MODEM_CDMA_CDMA1X_NETWORK_SUPPORTED:
|
||||||
|
g_value_set_boolean (value, self->priv->modem_cdma_cdma1x_network_supported);
|
||||||
|
break;
|
||||||
|
case PROP_MODEM_CDMA_EVDO_NETWORK_SUPPORTED:
|
||||||
|
g_value_set_boolean (value, self->priv->modem_cdma_evdo_network_supported);
|
||||||
|
break;
|
||||||
case PROP_MODEM_SIMPLE_STATUS:
|
case PROP_MODEM_SIMPLE_STATUS:
|
||||||
g_value_set_object (value, self->priv->modem_simple_status);
|
g_value_set_object (value, self->priv->modem_simple_status);
|
||||||
break;
|
break;
|
||||||
@@ -3460,11 +3745,15 @@ mm_broadband_modem_init (MMBroadbandModem *self)
|
|||||||
MMBroadbandModemPrivate);
|
MMBroadbandModemPrivate);
|
||||||
self->priv->modem_state = MM_MODEM_STATE_UNKNOWN;
|
self->priv->modem_state = MM_MODEM_STATE_UNKNOWN;
|
||||||
self->priv->modem_current_capabilities = MM_MODEM_CAPABILITY_NONE;
|
self->priv->modem_current_capabilities = MM_MODEM_CAPABILITY_NONE;
|
||||||
self->priv->modem_3gpp_registration_state = MM_MODEM_3GPP_REGISTRATION_STATE_UNKNOWN;
|
|
||||||
self->priv->reg_regex = mm_3gpp_creg_regex_get (TRUE);
|
self->priv->reg_regex = mm_3gpp_creg_regex_get (TRUE);
|
||||||
self->priv->current_charset = MM_MODEM_CHARSET_UNKNOWN;
|
self->priv->current_charset = MM_MODEM_CHARSET_UNKNOWN;
|
||||||
|
self->priv->modem_3gpp_registration_state = MM_MODEM_3GPP_REGISTRATION_STATE_UNKNOWN;
|
||||||
self->priv->modem_3gpp_cs_network_supported = TRUE;
|
self->priv->modem_3gpp_cs_network_supported = TRUE;
|
||||||
self->priv->modem_3gpp_ps_network_supported = TRUE;
|
self->priv->modem_3gpp_ps_network_supported = TRUE;
|
||||||
|
self->priv->modem_cdma_cdma1x_registration_state = MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN;
|
||||||
|
self->priv->modem_cdma_evdo_registration_state = MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN;
|
||||||
|
self->priv->modem_cdma_cdma1x_network_supported = TRUE;
|
||||||
|
self->priv->modem_cdma_evdo_network_supported = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -3603,6 +3892,12 @@ iface_modem_cdma_init (MMIfaceModemCdma *iface)
|
|||||||
/* Initialization steps */
|
/* Initialization steps */
|
||||||
iface->load_esn = load_esn;
|
iface->load_esn = load_esn;
|
||||||
iface->load_esn_finish = load_esn_finish;
|
iface->load_esn_finish = load_esn_finish;
|
||||||
|
|
||||||
|
/* Additional actions */
|
||||||
|
iface->get_call_manager_state = get_call_manager_state;
|
||||||
|
iface->get_call_manager_state_finish = get_call_manager_state_finish;
|
||||||
|
iface->get_hdr_state = get_hdr_state;
|
||||||
|
iface->get_hdr_state_finish = get_hdr_state_finish;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -3675,6 +3970,22 @@ mm_broadband_modem_class_init (MMBroadbandModemClass *klass)
|
|||||||
PROP_MODEM_3GPP_PS_NETWORK_SUPPORTED,
|
PROP_MODEM_3GPP_PS_NETWORK_SUPPORTED,
|
||||||
MM_IFACE_MODEM_3GPP_PS_NETWORK_SUPPORTED);
|
MM_IFACE_MODEM_3GPP_PS_NETWORK_SUPPORTED);
|
||||||
|
|
||||||
|
g_object_class_override_property (object_class,
|
||||||
|
PROP_MODEM_CDMA_CDMA1X_REGISTRATION_STATE,
|
||||||
|
MM_IFACE_MODEM_CDMA_CDMA1X_REGISTRATION_STATE);
|
||||||
|
|
||||||
|
g_object_class_override_property (object_class,
|
||||||
|
PROP_MODEM_CDMA_EVDO_REGISTRATION_STATE,
|
||||||
|
MM_IFACE_MODEM_CDMA_EVDO_REGISTRATION_STATE);
|
||||||
|
|
||||||
|
g_object_class_override_property (object_class,
|
||||||
|
PROP_MODEM_CDMA_CDMA1X_NETWORK_SUPPORTED,
|
||||||
|
MM_IFACE_MODEM_CDMA_CDMA1X_NETWORK_SUPPORTED);
|
||||||
|
|
||||||
|
g_object_class_override_property (object_class,
|
||||||
|
PROP_MODEM_CDMA_EVDO_NETWORK_SUPPORTED,
|
||||||
|
MM_IFACE_MODEM_CDMA_EVDO_NETWORK_SUPPORTED);
|
||||||
|
|
||||||
g_object_class_override_property (object_class,
|
g_object_class_override_property (object_class,
|
||||||
PROP_MODEM_SIMPLE_STATUS,
|
PROP_MODEM_SIMPLE_STATUS,
|
||||||
MM_IFACE_MODEM_SIMPLE_STATUS);
|
MM_IFACE_MODEM_SIMPLE_STATUS);
|
||||||
|
Reference in New Issue
Block a user