broadband-modem-sierra: load own numbers via ~NAMVAL?0 for CDMA

Sierra CDMA devices don't always have QCDM ports, or if they do,
they aren't always usable.  Try Sierra-proprietary commands for
loading the modem's MDN and fall back to QCDM if that fails.
This commit is contained in:
Dan Williams
2013-01-08 11:01:34 -06:00
parent f7d55a688a
commit 48b36b1afa

View File

@@ -40,6 +40,8 @@ static void iface_modem_init (MMIfaceModem *iface);
static void iface_modem_cdma_init (MMIfaceModemCdma *iface); static void iface_modem_cdma_init (MMIfaceModemCdma *iface);
static void iface_modem_time_init (MMIfaceModemTime *iface); static void iface_modem_time_init (MMIfaceModemTime *iface);
static MMIfaceModem *iface_modem_parent;
G_DEFINE_TYPE_EXTENDED (MMBroadbandModemSierra, mm_broadband_modem_sierra, MM_TYPE_BROADBAND_MODEM, 0, G_DEFINE_TYPE_EXTENDED (MMBroadbandModemSierra, mm_broadband_modem_sierra, MM_TYPE_BROADBAND_MODEM, 0,
G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM, iface_modem_init) G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM, iface_modem_init)
G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_CDMA, iface_modem_cdma_init) G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_CDMA, iface_modem_cdma_init)
@@ -435,6 +437,122 @@ set_allowed_modes (MMIfaceModem *self,
g_free (command); g_free (command);
} }
/*****************************************************************************/
/* Load own numbers (Modem interface) */
static GStrv
modem_load_own_numbers_finish (MMIfaceModem *self,
GAsyncResult *res,
GError **error)
{
if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error))
return NULL;
return g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res));
}
static void
parent_load_own_numbers_ready (MMIfaceModem *self,
GAsyncResult *res,
GSimpleAsyncResult *simple)
{
GError *error = NULL;
GStrv numbers;
numbers = iface_modem_parent->load_own_numbers_finish (self, res, &error);
if (error)
g_simple_async_result_take_error (simple, error);
else
g_simple_async_result_set_op_res_gpointer (simple, numbers, NULL);
g_simple_async_result_complete (simple);
g_object_unref (simple);
}
#define MDN_TAG "MDN: "
static void
own_numbers_ready (MMBaseModem *self,
GAsyncResult *res,
GSimpleAsyncResult *simple)
{
const gchar *response, *p;
const gchar *numbers[2] = { NULL, NULL };
gchar mdn[15];
guint i;
response = mm_base_modem_at_command_finish (self, res, NULL);
if (!response)
goto fallback;
p = strstr (response, MDN_TAG);
if (!p)
goto fallback;
response = p + strlen (MDN_TAG);
while (isspace (*response))
response++;
for (i = 0; i < (sizeof (mdn) - 1) && isdigit (response[i]); i++)
mdn[i] = response[i];
mdn[i] = '\0';
numbers[0] = &mdn[0];
/* MDNs are 10 digits in length */
if (i != 10) {
mm_warn ("Failed to parse MDN: expected 10 digits, got %d", i);
goto fallback;
}
g_simple_async_result_set_op_res_gpointer (simple,
g_strdupv ((gchar **) numbers),
NULL);
g_simple_async_result_complete (simple);
g_object_unref (simple);
return;
fallback:
/* Fall back to parent method */
iface_modem_parent->load_own_numbers (
MM_IFACE_MODEM (self),
(GAsyncReadyCallback)parent_load_own_numbers_ready,
simple);
}
static void
modem_load_own_numbers (MMIfaceModem *self,
GAsyncReadyCallback callback,
gpointer user_data)
{
GSimpleAsyncResult *result;
mm_dbg ("loading own numbers (Sierra)...");
result = g_simple_async_result_new (G_OBJECT (self),
callback,
user_data,
modem_load_own_numbers);
/* 3GPP modems can just run parent's own number loading */
if (mm_iface_modem_is_3gpp (self)) {
iface_modem_parent->load_own_numbers (
self,
(GAsyncReadyCallback)parent_load_own_numbers_ready,
result);
return;
}
/* CDMA modems try AT~NAMVAL?0 first, then fall back to parent for
* loading own number from NV memory with QCDM.
*/
mm_base_modem_at_command (
MM_BASE_MODEM (self),
"~NAMVAL?0",
3,
FALSE,
(GAsyncReadyCallback)own_numbers_ready,
result);
}
/*****************************************************************************/ /*****************************************************************************/
/* Create Bearer (Modem interface) */ /* Create Bearer (Modem interface) */
@@ -1153,6 +1271,8 @@ mm_broadband_modem_sierra_init (MMBroadbandModemSierra *self)
static void static void
iface_modem_init (MMIfaceModem *iface) iface_modem_init (MMIfaceModem *iface)
{ {
iface_modem_parent = g_type_interface_peek_parent (iface);
mm_common_sierra_peek_parent_interfaces (iface); mm_common_sierra_peek_parent_interfaces (iface);
iface->load_allowed_modes = load_allowed_modes; iface->load_allowed_modes = load_allowed_modes;
@@ -1161,6 +1281,8 @@ iface_modem_init (MMIfaceModem *iface)
iface->set_allowed_modes_finish = set_allowed_modes_finish; iface->set_allowed_modes_finish = set_allowed_modes_finish;
iface->load_access_technologies = load_access_technologies; iface->load_access_technologies = load_access_technologies;
iface->load_access_technologies_finish = load_access_technologies_finish; iface->load_access_technologies_finish = load_access_technologies_finish;
iface->load_own_numbers = modem_load_own_numbers;
iface->load_own_numbers_finish = modem_load_own_numbers_finish;
iface->reset = modem_reset; iface->reset = modem_reset;
iface->reset_finish = modem_reset_finish; iface->reset_finish = modem_reset_finish;
iface->load_power_state = mm_common_sierra_load_power_state; iface->load_power_state = mm_common_sierra_load_power_state;