bearer-cdma: when specific RM protocol given to be used, ensure it is supported
If the requested RM protocol is not supported, the CDMA Bearer creation will fail.
This commit is contained in:
@@ -113,6 +113,7 @@ static void interface_initialization_step (InitAsyncContext *ctx);
|
||||
|
||||
typedef enum {
|
||||
INITIALIZATION_STEP_FIRST,
|
||||
INITIALIZATION_STEP_RM_PROTOCOL,
|
||||
INITIALIZATION_STEP_LAST
|
||||
} InitializationStep;
|
||||
|
||||
@@ -173,6 +174,55 @@ initable_init_finish (GAsyncInitable *initable,
|
||||
return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error);
|
||||
}
|
||||
|
||||
static void
|
||||
crm_range_ready (MMBaseModem *modem,
|
||||
GAsyncResult *res,
|
||||
InitAsyncContext *ctx)
|
||||
{
|
||||
GError *error = NULL;
|
||||
const gchar *response;
|
||||
|
||||
response = mm_base_modem_at_command_finish (modem, res, &error);
|
||||
if (error) {
|
||||
/* We should possibly take this error as fatal. If we were told to use a
|
||||
* specific Rm protocol, we must be able to check if it is supported. */
|
||||
g_simple_async_result_take_error (ctx->result, error);
|
||||
} else {
|
||||
MMModemCdmaRmProtocol min = MM_MODEM_CDMA_RM_PROTOCOL_UNKNOWN;
|
||||
MMModemCdmaRmProtocol max = MM_MODEM_CDMA_RM_PROTOCOL_UNKNOWN;
|
||||
|
||||
if (mm_cdma_parse_crm_range_response (response,
|
||||
&min, &max,
|
||||
&error)) {
|
||||
GEnumClass *enum_class;
|
||||
GEnumValue *value;
|
||||
|
||||
/* Check if value within the range */
|
||||
if (ctx->self->priv->rm_protocol >= min &&
|
||||
ctx->self->priv->rm_protocol <= max) {
|
||||
/* Fine, go on with next step */
|
||||
ctx->step++;
|
||||
interface_initialization_step (ctx);
|
||||
}
|
||||
|
||||
enum_class = G_ENUM_CLASS (g_type_class_ref (MM_TYPE_MODEM_CDMA_RM_PROTOCOL));
|
||||
value = g_enum_get_value (enum_class, ctx->self->priv->rm_protocol);
|
||||
g_assert (error == NULL);
|
||||
error = g_error_new (MM_CORE_ERROR,
|
||||
MM_CORE_ERROR_FAILED,
|
||||
"Requested RM protocol '%s' is not supported",
|
||||
value->value_nick);
|
||||
g_type_class_unref (enum_class);
|
||||
}
|
||||
|
||||
/* Failed, set as fatal as well */
|
||||
g_simple_async_result_take_error (ctx->result, error);
|
||||
}
|
||||
|
||||
g_simple_async_result_complete (ctx->result);
|
||||
init_async_context_free (ctx, TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
interface_initialization_step (InitAsyncContext *ctx)
|
||||
{
|
||||
@@ -181,6 +231,25 @@ interface_initialization_step (InitAsyncContext *ctx)
|
||||
/* Fall down to next step */
|
||||
ctx->step++;
|
||||
|
||||
case INITIALIZATION_STEP_RM_PROTOCOL:
|
||||
/* If a specific RM protocol is given, we need to check whether it is
|
||||
* supported. */
|
||||
if (ctx->self->priv->rm_protocol != MM_MODEM_CDMA_RM_PROTOCOL_UNKNOWN) {
|
||||
mm_base_modem_at_command_in_port (
|
||||
ctx->modem,
|
||||
ctx->port,
|
||||
"+CRM=?",
|
||||
3,
|
||||
TRUE, /* getting range, so reply can be cached */
|
||||
NULL, /* cancellable */
|
||||
(GAsyncReadyCallback)crm_range_ready,
|
||||
ctx);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Fall down to next step */
|
||||
ctx->step++;
|
||||
|
||||
case INITIALIZATION_STEP_LAST:
|
||||
/* We are done without errors! */
|
||||
g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE);
|
||||
|
@@ -1595,6 +1595,87 @@ mm_cdma_convert_sid (const gchar *sid)
|
||||
return (gint) tmp_sid;
|
||||
}
|
||||
|
||||
MMModemCdmaRmProtocol
|
||||
mm_cdma_get_rm_protocol_from_index (guint index,
|
||||
GError **error)
|
||||
{
|
||||
guint protocol;
|
||||
|
||||
/* just adding 1 from the index value should give us the enum */
|
||||
protocol = index + 1 ;
|
||||
if (protocol > MM_MODEM_CDMA_RM_PROTOCOL_STU_III) {
|
||||
g_set_error (error,
|
||||
MM_CORE_ERROR,
|
||||
MM_CORE_ERROR_FAILED,
|
||||
"Unexpected RM protocol index (%u)",
|
||||
index);
|
||||
protocol = MM_MODEM_CDMA_RM_PROTOCOL_UNKNOWN;
|
||||
}
|
||||
|
||||
return (MMModemCdmaRmProtocol)protocol;
|
||||
}
|
||||
|
||||
gboolean
|
||||
mm_cdma_parse_crm_range_response (const gchar *reply,
|
||||
MMModemCdmaRmProtocol *min,
|
||||
MMModemCdmaRmProtocol *max,
|
||||
GError **error)
|
||||
{
|
||||
gboolean result = FALSE;
|
||||
GRegex *r;
|
||||
|
||||
|
||||
/* Expected reply format is:
|
||||
* ---> AT+CRM=?
|
||||
* <--- +CRM: (0-2)
|
||||
*/
|
||||
|
||||
r = g_regex_new ("\\+CRM:\\s*\\((\\d+)-(\\d+)\\)",
|
||||
G_REGEX_DOLLAR_ENDONLY | G_REGEX_RAW,
|
||||
0, error);
|
||||
if (r) {
|
||||
GMatchInfo *match_info = NULL;
|
||||
|
||||
if (g_regex_match_full (r, reply, strlen (reply), 0, 0, &match_info, error)) {
|
||||
gchar *aux;
|
||||
guint min_val = 0;
|
||||
guint max_val = 0;
|
||||
|
||||
aux = g_match_info_fetch (match_info, 1);
|
||||
min_val = (guint) atoi (aux);
|
||||
g_free (aux);
|
||||
|
||||
aux = g_match_info_fetch (match_info, 2);
|
||||
max_val = (guint) atoi (aux);
|
||||
g_free (aux);
|
||||
|
||||
if (min_val == 0 ||
|
||||
max_val == 0 ||
|
||||
min_val >= max_val) {
|
||||
g_set_error (error,
|
||||
MM_CORE_ERROR,
|
||||
MM_CORE_ERROR_FAILED,
|
||||
"Couldn't parse CRM range: "
|
||||
"Unexpected range of RM protocols (%u,%u)",
|
||||
min_val,
|
||||
max_val);
|
||||
} else {
|
||||
*min = mm_cdma_get_rm_protocol_from_index (min_val, error);
|
||||
if (*min != MM_MODEM_CDMA_RM_PROTOCOL_UNKNOWN) {
|
||||
*max = mm_cdma_get_rm_protocol_from_index (max_val, error);
|
||||
if (*max != MM_MODEM_CDMA_RM_PROTOCOL_UNKNOWN)
|
||||
result = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
g_match_info_free (match_info);
|
||||
g_regex_unref (r);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
guint
|
||||
mm_count_bits_set (gulong number)
|
||||
{
|
||||
|
@@ -77,6 +77,14 @@ gboolean mm_cdma_parse_eri (const char *reply,
|
||||
guint32 *out_ind,
|
||||
const char **out_desc);
|
||||
|
||||
MMModemCdmaRmProtocol mm_cdma_get_rm_protocol_from_index (guint index,
|
||||
GError **error);
|
||||
|
||||
gboolean mm_cdma_parse_crm_range_response (const gchar *reply,
|
||||
MMModemCdmaRmProtocol *min,
|
||||
MMModemCdmaRmProtocol *max,
|
||||
GError **error);
|
||||
|
||||
gboolean mm_gsm_parse_cscs_support_response (const char *reply,
|
||||
MMModemCharset *out_charsets);
|
||||
|
||||
|
Reference in New Issue
Block a user