cinterion: add helper to build Cinterion band mask
This commit is contained in:
@@ -55,6 +55,9 @@ struct _MMBroadbandModemCinterionPrivate {
|
|||||||
|
|
||||||
/* Cached manual selection attempt */
|
/* Cached manual selection attempt */
|
||||||
gchar *manual_operator_id;
|
gchar *manual_operator_id;
|
||||||
|
|
||||||
|
/* Cached supported bands in Cinterion format */
|
||||||
|
guint supported_bands;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Setup relationship between the band bitmask in the modem and the bitmask
|
/* Setup relationship between the band bitmask in the modem and the bitmask
|
||||||
@@ -81,28 +84,6 @@ static const CinterionBand2G bands_2g[] = {
|
|||||||
{ "15", 4, { MM_MODEM_BAND_EGSM, MM_MODEM_BAND_DCS, MM_MODEM_BAND_PCS, MM_MODEM_BAND_G850 }}
|
{ "15", 4, { MM_MODEM_BAND_EGSM, MM_MODEM_BAND_DCS, MM_MODEM_BAND_PCS, MM_MODEM_BAND_G850 }}
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Setup relationship between the 3G band bitmask in the modem and the bitmask
|
|
||||||
* in ModemManager. */
|
|
||||||
typedef struct {
|
|
||||||
guint32 cinterion_band_flag;
|
|
||||||
MMModemBand mm_band;
|
|
||||||
} CinterionBand3G;
|
|
||||||
|
|
||||||
/* Table checked in HC25 (3G) reference. This table includes both 2G and 3G
|
|
||||||
* frequencies. Depending on which one is configured, one access technology or
|
|
||||||
* the other will be used. This may conflict with the allowed mode configuration
|
|
||||||
* set, so you shouldn't for example set 3G frequency bands, and then use a
|
|
||||||
* 2G-only allowed mode. */
|
|
||||||
static const CinterionBand3G bands_3g[] = {
|
|
||||||
{ (1 << 0), MM_MODEM_BAND_EGSM },
|
|
||||||
{ (1 << 1), MM_MODEM_BAND_DCS },
|
|
||||||
{ (1 << 2), MM_MODEM_BAND_PCS },
|
|
||||||
{ (1 << 3), MM_MODEM_BAND_G850 },
|
|
||||||
{ (1 << 4), MM_MODEM_BAND_U2100 },
|
|
||||||
{ (1 << 5), MM_MODEM_BAND_U1900 },
|
|
||||||
{ (1 << 6), MM_MODEM_BAND_U850 }
|
|
||||||
};
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* Unsolicited events enabling */
|
/* Unsolicited events enabling */
|
||||||
|
|
||||||
@@ -943,21 +924,25 @@ load_supported_bands_finish (MMIfaceModem *self,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
scfg_3g_test_ready (MMBaseModem *self,
|
scfg_3g_test_ready (MMBaseModem *_self,
|
||||||
GAsyncResult *res,
|
GAsyncResult *res,
|
||||||
GSimpleAsyncResult *simple)
|
GSimpleAsyncResult *simple)
|
||||||
{
|
{
|
||||||
|
MMBroadbandModemCinterion *self = MM_BROADBAND_MODEM_CINTERION (_self);
|
||||||
const gchar *response;
|
const gchar *response;
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
GArray *bands;
|
GArray *bands;
|
||||||
|
|
||||||
response = mm_base_modem_at_command_finish (self, res, &error);
|
response = mm_base_modem_at_command_finish (_self, res, &error);
|
||||||
if (!response)
|
if (!response)
|
||||||
g_simple_async_result_take_error (simple, error);
|
g_simple_async_result_take_error (simple, error);
|
||||||
else if (!mm_cinterion_parse_scfg_3g_test (response, &bands, &error))
|
else if (!mm_cinterion_parse_scfg_3g_test (response, &bands, &error))
|
||||||
g_simple_async_result_take_error (simple, error);
|
g_simple_async_result_take_error (simple, error);
|
||||||
else
|
else {
|
||||||
|
mm_cinterion_build_band (bands, 0, &self->priv->supported_bands, NULL);
|
||||||
|
g_assert (self->priv->supported_bands != 0);
|
||||||
g_simple_async_result_set_op_res_gpointer (simple, bands, (GDestroyNotify)g_array_unref);
|
g_simple_async_result_set_op_res_gpointer (simple, bands, (GDestroyNotify)g_array_unref);
|
||||||
|
}
|
||||||
|
|
||||||
g_simple_async_result_complete (simple);
|
g_simple_async_result_complete (simple);
|
||||||
g_object_unref (simple);
|
g_object_unref (simple);
|
||||||
@@ -1173,72 +1158,39 @@ scfg_set_ready (MMBaseModem *self,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
set_bands_3g (MMIfaceModem *self,
|
set_bands_3g (MMIfaceModem *_self,
|
||||||
GArray *bands_array,
|
GArray *bands_array,
|
||||||
GSimpleAsyncResult *result)
|
GSimpleAsyncResult *simple)
|
||||||
{
|
{
|
||||||
GArray *bands_array_final;
|
MMBroadbandModemCinterion *self = MM_BROADBAND_MODEM_CINTERION (_self);
|
||||||
guint cinterion_band = 0;
|
GError *error = NULL;
|
||||||
guint i;
|
guint band = 0;
|
||||||
gchar *bands_string;
|
|
||||||
gchar *cmd;
|
gchar *cmd;
|
||||||
|
|
||||||
/* The special case of ANY should be treated separately. */
|
if (!mm_cinterion_build_band (bands_array,
|
||||||
if (bands_array->len == 1 &&
|
self->priv->supported_bands,
|
||||||
g_array_index (bands_array, MMModemBand, 0) == MM_MODEM_BAND_ANY) {
|
&band,
|
||||||
/* We build an array with all bands to set; so that we use the same
|
&error)) {
|
||||||
* logic to build the cinterion_band, and so that we can log the list of
|
g_simple_async_result_take_error (simple, error);
|
||||||
* bands being set properly */
|
g_simple_async_result_complete_in_idle (simple);
|
||||||
bands_array_final = g_array_sized_new (FALSE, FALSE, sizeof (MMModemBand), G_N_ELEMENTS (bands_3g));
|
g_object_unref (simple);
|
||||||
for (i = 0; i < G_N_ELEMENTS (bands_3g); i++)
|
|
||||||
g_array_append_val (bands_array_final, bands_3g[i].mm_band);
|
|
||||||
} else
|
|
||||||
bands_array_final = g_array_ref (bands_array);
|
|
||||||
|
|
||||||
for (i = 0; i < G_N_ELEMENTS (bands_3g); i++) {
|
|
||||||
guint j;
|
|
||||||
|
|
||||||
for (j = 0; j < bands_array_final->len; j++) {
|
|
||||||
if (g_array_index (bands_array_final, MMModemBand, j) == bands_3g[i].mm_band) {
|
|
||||||
cinterion_band |= bands_3g[i].cinterion_band_flag;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bands_string = mm_common_build_bands_string ((MMModemBand *)bands_array_final->data,
|
|
||||||
bands_array_final->len);
|
|
||||||
g_array_unref (bands_array_final);
|
|
||||||
|
|
||||||
if (!cinterion_band) {
|
|
||||||
g_simple_async_result_set_error (result,
|
|
||||||
MM_CORE_ERROR,
|
|
||||||
MM_CORE_ERROR_UNSUPPORTED,
|
|
||||||
"The given band combination is not supported: '%s'",
|
|
||||||
bands_string);
|
|
||||||
g_simple_async_result_complete_in_idle (result);
|
|
||||||
g_object_unref (result);
|
|
||||||
g_free (bands_string);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
mm_dbg ("Setting new bands to use: '%s'", bands_string);
|
|
||||||
|
|
||||||
/* Following the setup:
|
/* Following the setup:
|
||||||
* AT^SCFG="Radion/Band",<rba>
|
* AT^SCFG="Radion/Band",<rba>
|
||||||
* We will set the preferred band equal to the allowed band, so that we force
|
* We will set the preferred band equal to the allowed band, so that we force
|
||||||
* the modem to connect at that specific frequency only. Note that we will be
|
* the modem to connect at that specific frequency only. Note that we will be
|
||||||
* passing a number here!
|
* passing a number here!
|
||||||
*/
|
*/
|
||||||
cmd = g_strdup_printf ("^SCFG=\"Radio/Band\",%u", cinterion_band);
|
cmd = g_strdup_printf ("^SCFG=\"Radio/Band\",%u", band);
|
||||||
mm_base_modem_at_command (MM_BASE_MODEM (self),
|
mm_base_modem_at_command (MM_BASE_MODEM (self),
|
||||||
cmd,
|
cmd,
|
||||||
15,
|
15,
|
||||||
FALSE,
|
FALSE,
|
||||||
(GAsyncReadyCallback)scfg_set_ready,
|
(GAsyncReadyCallback)scfg_set_ready,
|
||||||
result);
|
simple);
|
||||||
g_free (cmd);
|
g_free (cmd);
|
||||||
g_free (bands_string);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@@ -190,3 +190,49 @@ mm_cinterion_parse_scfg_3g_response (const gchar *response,
|
|||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/* Build Cinterion-specific band value */
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
mm_cinterion_build_band (GArray *bands,
|
||||||
|
guint supported,
|
||||||
|
guint *out_band,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
guint band = 0;
|
||||||
|
|
||||||
|
/* The special case of ANY should be treated separately. */
|
||||||
|
if (bands->len == 1 && g_array_index (bands, MMModemBand, 0) == MM_MODEM_BAND_ANY) {
|
||||||
|
band = supported;
|
||||||
|
} else {
|
||||||
|
guint i;
|
||||||
|
|
||||||
|
for (i = 0; i < G_N_ELEMENTS (bands_3g); i++) {
|
||||||
|
guint j;
|
||||||
|
|
||||||
|
for (j = 0; j < bands->len; j++) {
|
||||||
|
if (g_array_index (bands, MMModemBand, j) == bands_3g[i].mm_band) {
|
||||||
|
band |= bands_3g[i].cinterion_band_flag;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (band == 0) {
|
||||||
|
gchar *bands_string;
|
||||||
|
|
||||||
|
bands_string = mm_common_build_bands_string ((MMModemBand *)bands->data, bands->len);
|
||||||
|
g_set_error (error,
|
||||||
|
MM_CORE_ERROR,
|
||||||
|
MM_CORE_ERROR_FAILED,
|
||||||
|
"The given band combination is not supported: '%s'",
|
||||||
|
bands_string);
|
||||||
|
g_free (bands_string);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
*out_band = band;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
@@ -32,4 +32,12 @@ gboolean mm_cinterion_parse_scfg_3g_response (const gchar *response,
|
|||||||
GArray **bands,
|
GArray **bands,
|
||||||
GError **error);
|
GError **error);
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/* Build Cinterion-specific band value */
|
||||||
|
|
||||||
|
gboolean mm_cinterion_build_band (GArray *bands,
|
||||||
|
guint supported,
|
||||||
|
guint *out_band,
|
||||||
|
GError **error);
|
||||||
|
|
||||||
#endif /* MM_MODEM_HELPERS_CINTERION_H */
|
#endif /* MM_MODEM_HELPERS_CINTERION_H */
|
||||||
|
Reference in New Issue
Block a user