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:
@@ -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;
|
||||||
|
Reference in New Issue
Block a user