cinterion: set and get allowed mode
The 2G-preferred and 3G-preferred modes are not supported on dual 2G/3G cinterion modems.
This commit is contained in:
@@ -39,6 +39,9 @@ typedef struct {
|
|||||||
gboolean only_geran;
|
gboolean only_geran;
|
||||||
gboolean only_utran;
|
gboolean only_utran;
|
||||||
gboolean both_geran_utran;
|
gboolean both_geran_utran;
|
||||||
|
|
||||||
|
/* Current allowed mode */
|
||||||
|
MMModemGsmAllowedMode allowed_mode;
|
||||||
} MMModemCinterionGsmPrivate;
|
} MMModemCinterionGsmPrivate;
|
||||||
|
|
||||||
MMModem *
|
MMModem *
|
||||||
@@ -248,6 +251,128 @@ get_access_technology (MMGenericGsm *gsm,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
get_allowed_mode (MMGenericGsm *gsm,
|
||||||
|
MMModemUIntFn callback,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
MMModemCinterionGsmPrivate *priv = MM_MODEM_CINTERION_GSM_GET_PRIVATE (gsm);
|
||||||
|
MMCallbackInfo *info;
|
||||||
|
|
||||||
|
info = mm_callback_info_uint_new (MM_MODEM (gsm), callback, user_data);
|
||||||
|
|
||||||
|
/* We just return cached value. For 3G devices we could try to ask the
|
||||||
|
* modem for the Access technology being used, and base 3G-only or 2G-only
|
||||||
|
* replies on that, but we wouldn't be covering all possible allowed modes
|
||||||
|
* anyway. */
|
||||||
|
mm_callback_info_set_result (info,
|
||||||
|
GUINT_TO_POINTER (priv->allowed_mode),
|
||||||
|
NULL);
|
||||||
|
mm_callback_info_schedule (info);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
set_allowed_mode_cb (MMAtSerialPort *port,
|
||||||
|
GString *response,
|
||||||
|
GError *error,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
MMCallbackInfo *info = (MMCallbackInfo *) user_data;
|
||||||
|
MMModemCinterionGsmPrivate *priv = MM_MODEM_CINTERION_GSM_GET_PRIVATE (info->modem);
|
||||||
|
|
||||||
|
if (error)
|
||||||
|
info->error = g_error_copy (error);
|
||||||
|
else
|
||||||
|
priv->allowed_mode = GPOINTER_TO_UINT (mm_callback_info_get_data (info, "new-mode"));
|
||||||
|
|
||||||
|
mm_callback_info_schedule (info);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
set_allowed_mode (MMGenericGsm *gsm,
|
||||||
|
MMModemGsmAllowedMode mode,
|
||||||
|
MMModemFn callback,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
MMModemCinterionGsmPrivate *priv = MM_MODEM_CINTERION_GSM_GET_PRIVATE (gsm);
|
||||||
|
MMCallbackInfo *info;
|
||||||
|
|
||||||
|
info = mm_callback_info_new (MM_MODEM (gsm), callback, user_data);
|
||||||
|
|
||||||
|
/* For dual 2G/3G devices... */
|
||||||
|
if (priv->both_geran_utran) {
|
||||||
|
GString *cmd;
|
||||||
|
MMAtSerialPort *port;
|
||||||
|
|
||||||
|
port = mm_generic_gsm_get_best_at_port (gsm, &info->error);
|
||||||
|
if (!port) {
|
||||||
|
mm_callback_info_schedule (info);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We will try to simulate the possible allowed modes here. The
|
||||||
|
* Cinterion devices do not seem to allow setting preferred access
|
||||||
|
* technology in 3G devices, but they allow restricting to a given
|
||||||
|
* one:
|
||||||
|
* - 2G-only is forced by forcing GERAN RAT (AcT=0)
|
||||||
|
* - 3G-only is forced by forcing UTRAN RAT (AcT=2)
|
||||||
|
* - for the remaining ones, we default to automatic selection of RAT,
|
||||||
|
* which is based on the quality of the connection.
|
||||||
|
*/
|
||||||
|
cmd = g_string_new ("+COPS=,,,");
|
||||||
|
if (mode == MM_MODEM_GSM_ALLOWED_MODE_3G_ONLY) {
|
||||||
|
g_string_append (cmd, "2");
|
||||||
|
} else if (mode == MM_MODEM_GSM_ALLOWED_MODE_2G_ONLY) {
|
||||||
|
g_string_append (cmd, "0");
|
||||||
|
} /* else, no AcT given, defaults to Auto */
|
||||||
|
|
||||||
|
mm_callback_info_set_data (info,
|
||||||
|
"new-mode",
|
||||||
|
GUINT_TO_POINTER (mode),
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
mm_at_serial_port_queue_command (port, cmd->str, 3, set_allowed_mode_cb, info);
|
||||||
|
g_string_free (cmd, TRUE);
|
||||||
|
mm_callback_info_schedule (info);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* For 3G-only devices, allow only 3G-related allowed modes */
|
||||||
|
if (priv->only_utran) {
|
||||||
|
switch (mode) {
|
||||||
|
case MM_MODEM_GSM_ALLOWED_MODE_3G_PREFERRED:
|
||||||
|
case MM_MODEM_GSM_ALLOWED_MODE_3G_ONLY:
|
||||||
|
case MM_MODEM_GSM_ALLOWED_MODE_ANY:
|
||||||
|
priv->allowed_mode = mode;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
info->error = g_error_new (MM_MODEM_ERROR,
|
||||||
|
MM_MODEM_ERROR_GENERAL,
|
||||||
|
"Cannot set desired allowed mode, "
|
||||||
|
"not a 2G device");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
mm_callback_info_schedule (info);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* For 2G devices, allow only 2G-related allowed modes */
|
||||||
|
switch (mode) {
|
||||||
|
case MM_MODEM_GSM_ALLOWED_MODE_2G_PREFERRED:
|
||||||
|
case MM_MODEM_GSM_ALLOWED_MODE_2G_ONLY:
|
||||||
|
case MM_MODEM_GSM_ALLOWED_MODE_ANY:
|
||||||
|
priv->allowed_mode = mode;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
info->error = g_error_new (MM_MODEM_ERROR,
|
||||||
|
MM_MODEM_ERROR_GENERAL,
|
||||||
|
"Cannot set desired allowed mode, "
|
||||||
|
"not a 3G device");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
mm_callback_info_schedule (info);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
enable_complete (MMGenericGsm *gsm,
|
enable_complete (MMGenericGsm *gsm,
|
||||||
GError *error,
|
GError *error,
|
||||||
@@ -259,7 +384,6 @@ enable_complete (MMGenericGsm *gsm,
|
|||||||
mm_generic_gsm_enable_complete (MM_GENERIC_GSM (info->modem), error, info);
|
mm_generic_gsm_enable_complete (MM_GENERIC_GSM (info->modem), error, info);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
get_supported_networks_cb (MMAtSerialPort *port,
|
get_supported_networks_cb (MMAtSerialPort *port,
|
||||||
GString *response,
|
GString *response,
|
||||||
@@ -348,6 +472,10 @@ mm_modem_cinterion_gsm_init (MMModemCinterionGsm *self)
|
|||||||
|
|
||||||
/* Set defaults */
|
/* Set defaults */
|
||||||
priv->sind_psinfo = TRUE; /* Initially, always try to get psinfo */
|
priv->sind_psinfo = TRUE; /* Initially, always try to get psinfo */
|
||||||
|
priv->allowed_mode = MM_MODEM_GSM_ALLOWED_MODE_ANY;
|
||||||
|
priv->only_geran = FALSE;
|
||||||
|
priv->only_utran = FALSE;
|
||||||
|
priv->both_geran_utran = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -359,6 +487,8 @@ mm_modem_cinterion_gsm_class_init (MMModemCinterionGsmClass *klass)
|
|||||||
g_type_class_add_private (object_class, sizeof (MMModemCinterionGsmPrivate));
|
g_type_class_add_private (object_class, sizeof (MMModemCinterionGsmPrivate));
|
||||||
|
|
||||||
gsm_class->do_enable_power_up_done = do_enable_power_up_done;
|
gsm_class->do_enable_power_up_done = do_enable_power_up_done;
|
||||||
|
gsm_class->set_allowed_mode = set_allowed_mode;
|
||||||
|
gsm_class->get_allowed_mode = get_allowed_mode;
|
||||||
gsm_class->get_access_technology = get_access_technology;
|
gsm_class->get_access_technology = get_access_technology;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user