broadband-modem: implement CDMA registration state and network supported properties

This commit is contained in:
Aleksander Morgado
2012-01-04 12:12:06 +01:00
parent 91e146e1fe
commit 11038be07f

View File

@@ -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);