diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/mm-broadband-modem-mbim.c | 406 | ||||
-rw-r--r-- | src/mm-modem-helpers-mbim.c | 196 | ||||
-rw-r--r-- | src/mm-modem-helpers-mbim.h | 27 |
3 files changed, 574 insertions, 55 deletions
diff --git a/src/mm-broadband-modem-mbim.c b/src/mm-broadband-modem-mbim.c index 93b74e60..e94b957b 100644 --- a/src/mm-broadband-modem-mbim.c +++ b/src/mm-broadband-modem-mbim.c @@ -116,6 +116,7 @@ struct _MMBroadbandModemMbimPrivate { /* Supported features */ gboolean is_profile_management_supported; + gboolean is_profile_management_ext_supported; gboolean is_pco_supported; gboolean is_lte_attach_info_supported; gboolean is_nr5g_registration_settings_supported; @@ -2632,6 +2633,9 @@ query_device_services_ready (MbimDevice *device, } else if (device_services[i]->cids[j] == MBIM_CID_MS_BASIC_CONNECT_EXTENSIONS_REGISTRATION_PARAMETERS) { mm_obj_dbg (self, "5GNR registration settings are supported"); self->priv->is_nr5g_registration_settings_supported = TRUE; + } else if (device_services[i]->cids[j] == MBIM_CID_MS_BASIC_CONNECT_EXTENSIONS_PROVISIONED_CONTEXTS) { + mm_obj_dbg (self, "Profile management extension is supported"); + self->priv->is_profile_management_ext_supported = TRUE; } } continue; @@ -6036,7 +6040,7 @@ enable_unsolicited_events_3gpp_profile_manager (MMIfaceModem3gppProfileManager * /* Check format (3gppProfileManager interface) */ static gboolean -modem_3gpp_profile_manager_check_format_finish (MMIfaceModem3gppProfileManager *self, +modem_3gpp_profile_manager_check_format_finish (MMIfaceModem3gppProfileManager *_self, GAsyncResult *res, gboolean *new_id, gint *min_profile_id, @@ -6045,6 +6049,8 @@ modem_3gpp_profile_manager_check_format_finish (MMIfaceModem3gppProfileManager MM3gppProfileCmpFlags *profile_cmp_flags, GError **error) { + MMBroadbandModemMbim *self = MM_BROADBAND_MODEM_MBIM (_self); + if (!g_task_propagate_boolean (G_TASK (res), error)) { g_assert_not_reached (); return FALSE; @@ -6059,11 +6065,17 @@ modem_3gpp_profile_manager_check_format_finish (MMIfaceModem3gppProfileManager /* use default string comparison method */ if (apn_cmp) *apn_cmp = NULL; - if (profile_cmp_flags) - *profile_cmp_flags = (MM_3GPP_PROFILE_CMP_FLAGS_NO_IP_TYPE | - MM_3GPP_PROFILE_CMP_FLAGS_NO_ACCESS_TYPE_PREFERENCE | - MM_3GPP_PROFILE_CMP_FLAGS_NO_ROAMING_ALLOWANCE | - MM_3GPP_PROFILE_CMP_FLAGS_NO_PROFILE_SOURCE); + if (profile_cmp_flags) { + if (!self->priv->is_profile_management_ext_supported) + *profile_cmp_flags = (MM_3GPP_PROFILE_CMP_FLAGS_NO_IP_TYPE | + MM_3GPP_PROFILE_CMP_FLAGS_NO_ACCESS_TYPE_PREFERENCE | + MM_3GPP_PROFILE_CMP_FLAGS_NO_ROAMING_ALLOWANCE | + MM_3GPP_PROFILE_CMP_FLAGS_NO_PROFILE_SOURCE); + else + /* when using the MS extensions, we support all IP type, access type + * preference, roaming allowance and profile source */ + *profile_cmp_flags = 0; + } return TRUE; } @@ -6132,6 +6144,60 @@ provisioned_context_element_to_3gpp_profile (MbimProvisionedContextElement *elem return profile; } +static MM3gppProfile * +provisioned_context_element_v2_to_3gpp_profile (MMBroadbandModemMbim *self, + MbimProvisionedContextElementV2 *element) +{ + MM3gppProfile *profile; + MMBearerApnType apn_type; + GError *error = NULL; + gboolean enabled; + MMBearerRoamingAllowance roaming_allowance; + MMBearerAccessTypePreference access_type_preference; + MMBearerProfileSource profile_source; + + apn_type = mm_bearer_apn_type_from_mbim_context_type (mbim_uuid_to_context_type (&element->context_type)); + if (apn_type == MM_BEARER_APN_TYPE_NONE) + return NULL; + + profile = mm_3gpp_profile_new (); + mm_3gpp_profile_set_profile_id (profile, element->context_id); + mm_3gpp_profile_set_apn (profile, element->access_string); + mm_3gpp_profile_set_apn_type (profile, apn_type); + mm_3gpp_profile_set_user (profile, element->user_name); + mm_3gpp_profile_set_password (profile, element->password); + mm_3gpp_profile_set_allowed_auth (profile, (mm_bearer_allowed_auth_from_mbim_auth_protocol (element->auth_protocol))); + + if (!mm_boolean_from_mbim_context_state (element->state, &enabled, &error)) { + mm_obj_dbg (self, "ignoring enable setting: %s", error->message); + g_clear_error (&error); + } else + mm_3gpp_profile_set_enabled (profile, enabled); + + roaming_allowance = mm_bearer_roaming_allowance_from_mbim_context_roaming_control (element->roaming, &error); + if (roaming_allowance == MM_BEARER_ROAMING_ALLOWANCE_NONE) { + mm_obj_dbg (self, "ignoring roaming allowance: %s", error->message); + g_clear_error (&error); + } else + mm_3gpp_profile_set_roaming_allowance (profile, roaming_allowance); + + if (!mm_bearer_access_type_preference_from_mbim_context_media_type (element->media_type, &access_type_preference, &error)) { + mm_obj_dbg (self, "ignoring access type preference: %s", error->message); + g_clear_error (&error); + } else + mm_3gpp_profile_set_access_type_preference (profile, access_type_preference); + + profile_source = mm_bearer_profile_source_from_mbim_context_source (element->source, &error); + if (profile_source == MM_BEARER_PROFILE_SOURCE_UNKNOWN) { + mm_obj_dbg (self, "ignoring profile source: %s", error->message); + g_clear_error (&error); + } else + mm_3gpp_profile_set_profile_source (profile, profile_source); + + /* compression unused, and ip-type not provided */ + return profile; +} + static void profile_manager_provisioned_contexts_query_ready (MbimDevice *device, GAsyncResult *res, @@ -6139,42 +6205,84 @@ profile_manager_provisioned_contexts_query_ready (MbimDevice *device, { ListProfilesContext *ctx; GError *error = NULL; + guint i; guint32 provisioned_contexts_count = 0; g_autoptr(MbimMessage) response = NULL; g_autoptr(MbimProvisionedContextElementArray) provisioned_contexts = NULL; - ctx = g_slice_new0 (ListProfilesContext); - g_task_set_task_data (task, ctx, (GDestroyNotify) list_profiles_context_free); + ctx = g_task_get_task_data (task); response = mbim_device_command_finish (device, res, &error); - if (response && - mbim_message_response_get_result (response, - MBIM_MESSAGE_TYPE_COMMAND_DONE, - &error) && - mbim_message_provisioned_contexts_response_parse (response, - &provisioned_contexts_count, - &provisioned_contexts, - &error)) { - guint i; + if (!response || + !mbim_message_response_get_result (response, MBIM_MESSAGE_TYPE_COMMAND_DONE, &error) || + !mbim_message_provisioned_contexts_response_parse (response, + &provisioned_contexts_count, + &provisioned_contexts, + &error)) { + g_task_return_error (task, error); + g_object_unref (task); + return; + } - for (i = 0; i < provisioned_contexts_count; i++) { - MM3gppProfile *profile; + for (i = 0; i < provisioned_contexts_count; i++) { + MM3gppProfile *profile; - profile = provisioned_context_element_to_3gpp_profile (provisioned_contexts[i]); - if (profile) - ctx->profiles = g_list_append (ctx->profiles, profile); - } - g_task_return_boolean (task, TRUE); - } else + profile = provisioned_context_element_to_3gpp_profile (provisioned_contexts[i]); + if (profile) + ctx->profiles = g_list_append (ctx->profiles, profile); + } + + g_task_return_boolean (task, TRUE); + g_object_unref (task); +} + +static void +profile_manager_provisioned_contexts_v2_query_ready (MbimDevice *device, + GAsyncResult *res, + GTask *task) +{ + MMBroadbandModemMbim *self; + ListProfilesContext *ctx; + GError *error = NULL; + guint i; + guint32 provisioned_contexts_count = 0; + g_autoptr(MbimMessage) response = NULL; + g_autoptr(MbimProvisionedContextElementV2Array) provisioned_contexts_v2 = NULL; + + self = g_task_get_source_object (task); + ctx = g_task_get_task_data (task); + + response = mbim_device_command_finish (device, res, &error); + if (!response || + !mbim_message_response_get_result (response, MBIM_MESSAGE_TYPE_COMMAND_DONE, &error) || + !mbim_message_ms_basic_connect_extensions_provisioned_contexts_response_parse (response, + &provisioned_contexts_count, + &provisioned_contexts_v2, + &error)) { g_task_return_error (task, error); + g_object_unref (task); + return; + } + + for (i = 0; i < provisioned_contexts_count; i++) { + MM3gppProfile *profile; + + profile = provisioned_context_element_v2_to_3gpp_profile (self, provisioned_contexts_v2[i]); + if (profile) + ctx->profiles = g_list_append (ctx->profiles, profile); + } + + g_task_return_boolean (task, TRUE); g_object_unref (task); } static void -modem_3gpp_profile_manager_list_profiles (MMIfaceModem3gppProfileManager *self, +modem_3gpp_profile_manager_list_profiles (MMIfaceModem3gppProfileManager *_self, GAsyncReadyCallback callback, gpointer user_data) { + MMBroadbandModemMbim *self = MM_BROADBAND_MODEM_MBIM (_self); + ListProfilesContext *ctx; MbimDevice *device; GTask *task; g_autoptr(MbimMessage) message = NULL; @@ -6183,10 +6291,23 @@ modem_3gpp_profile_manager_list_profiles (MMIfaceModem3gppProfileManager *self, return; task = g_task_new (self, NULL, callback, user_data); + ctx = g_slice_new0 (ListProfilesContext); + g_task_set_task_data (task, ctx, (GDestroyNotify) list_profiles_context_free); mm_obj_dbg (self, "querying provisioned contexts..."); - message = mbim_message_provisioned_contexts_query_new (NULL); + if (self->priv->is_profile_management_ext_supported) { + message = mbim_message_ms_basic_connect_extensions_provisioned_contexts_query_new (NULL); + mbim_device_command (device, + message, + 10, + NULL, + (GAsyncReadyCallback)profile_manager_provisioned_contexts_v2_query_ready, + task); + return; + } + + message = mbim_message_provisioned_contexts_query_new (NULL); mbim_device_command (device, message, 10, @@ -6226,25 +6347,26 @@ profile_manager_provisioned_contexts_set_ready (MbimDevice *device, } static void -modem_3gpp_profile_manager_store_profile (MMIfaceModem3gppProfileManager *self, +modem_3gpp_profile_manager_store_profile (MMIfaceModem3gppProfileManager *_self, MM3gppProfile *profile, GAsyncReadyCallback callback, gpointer user_data) { - MbimDevice *device; - GTask *task; - GError *error = NULL; - gint profile_id; - MMBearerApnType apn_type; - MMBearerAllowedAuth allowed_auth; - MbimAuthProtocol auth_protocol = MBIM_AUTH_PROTOCOL_NONE; - MbimContextType context_type; - const MbimUuid *context_type_uuid; - const gchar *apn; - const gchar *user; - const gchar *password; - g_autofree gchar *apn_type_str = NULL; - g_autoptr(MbimMessage) message = NULL; + MMBroadbandModemMbim *self = MM_BROADBAND_MODEM_MBIM (_self); + MbimDevice *device; + GTask *task; + GError *error = NULL; + gint profile_id; + MMBearerApnType apn_type; + MMBearerAllowedAuth allowed_auth; + MbimAuthProtocol auth_protocol = MBIM_AUTH_PROTOCOL_NONE; + MbimContextType context_type; + const MbimUuid *context_type_uuid; + const gchar *apn; + const gchar *user; + const gchar *password; + g_autofree gchar *apn_type_str = NULL; + g_autoptr(MbimMessage) message = NULL; if (!peek_device (self, &device, callback, user_data)) return; @@ -6260,6 +6382,7 @@ modem_3gpp_profile_manager_store_profile (MMIfaceModem3gppProfileManager *self, apn_type = mm_3gpp_profile_get_apn_type (profile); context_type = mm_bearer_apn_type_to_mbim_context_type (apn_type, self, &error); if (error) { + g_prefix_error (&error, "Failed to convert mbim context type from apn type: "); g_task_return_error (task, error); g_object_unref (task); return; @@ -6275,24 +6398,87 @@ modem_3gpp_profile_manager_store_profile (MMIfaceModem3gppProfileManager *self, if ((allowed_auth != MM_BEARER_ALLOWED_AUTH_UNKNOWN) || user || password) { auth_protocol = mm_bearer_allowed_auth_to_mbim_auth_protocol (allowed_auth, self, &error); if (error) { + g_prefix_error (&error, "Failed to convert mbim auth protocol from allowed auth: "); g_task_return_error (task, error); g_object_unref (task); return; } } - mm_obj_dbg (self, "storing profile '%d': apn '%s', apn type '%s'", - profile_id, apn, apn_type_str); + if (self->priv->is_profile_management_ext_supported) { + MbimContextIpType ip_type; + MbimContextState state; + MbimContextRoamingControl roaming; + MbimContextMediaType media_type; + MbimContextSource source; + + state = mm_boolean_to_mbim_context_state (mm_3gpp_profile_get_enabled (profile)); + + ip_type = mm_bearer_ip_family_to_mbim_context_ip_type (mm_3gpp_profile_get_ip_type (profile), &error); + if (error) { + g_prefix_error (&error, "Failed to convert mbim context ip type from ip type: "); + g_task_return_error (task, error); + g_object_unref (task); + return; + } + + if (!mm_bearer_roaming_allowance_to_mbim_context_roaming_control (mm_3gpp_profile_get_roaming_allowance (profile), self, &roaming, &error)) { + g_prefix_error (&error, "Failed to convert mbim context roaming control from roaming allowance: "); + g_task_return_error (task, error); + g_object_unref (task); + return; + } + + if (!mm_bearer_access_type_preference_to_mbim_context_media_type (mm_3gpp_profile_get_access_type_preference (profile), self, &media_type, &error)) { + g_prefix_error (&error, "Failed to convert mbim context media type from access type preference: "); + g_task_return_error (task, error); + g_object_unref (task); + return; + } + + if (!mm_bearer_profile_source_to_mbim_context_source (mm_3gpp_profile_get_profile_source (profile), self, &source, &error)) { + g_prefix_error (&error, "Failed to convert mbim context source from profile source: "); + g_task_return_error (task, error); + g_object_unref (task); + return; + } + + /* We don't pass the profile ID, because the MS extended version does + * not support it. This is extremely wrong, and I have no idea how we + * can make this work reliably. According to the documentation, the + * modem would choose automatically which profile to update based on + * the specified context type... but what if we have multiple contexts + * of the same type? */ + + mm_obj_dbg (self, "using MS extensions to manage provisioned contexts: updating profiles matching context type"); + mm_obj_dbg (self, "updating profiles with context type '%s'", mbim_context_type_get_string (context_type)); + message = mbim_message_ms_basic_connect_extensions_provisioned_contexts_set_new (MBIM_CONTEXT_OPERATION_DEFAULT, + context_type_uuid, + ip_type, + state, + roaming, + media_type, + source, + apn ? apn : "", + user ? user : "", + password ? password : "", + MBIM_COMPRESSION_NONE, + auth_protocol, + &error); + } else { + mm_obj_dbg (self, "storing profile '%d': apn '%s', apn type '%s'", + profile_id, apn, apn_type_str); + message = mbim_message_provisioned_contexts_set_new (profile_id, + context_type_uuid, + apn ? apn : "", + user ? user : "", + password ? password : "", + MBIM_COMPRESSION_NONE, + auth_protocol, + "", /* provider id */ + &error); + } - message = mbim_message_provisioned_contexts_set_new (profile_id, - context_type_uuid, - apn ? apn : "", - user ? user : "", - password ? password : "", - MBIM_COMPRESSION_NONE, - auth_protocol, - "", /* provider id */ - &error); if (error) { g_task_return_error (task, error); g_object_unref (task); @@ -6310,6 +6496,19 @@ modem_3gpp_profile_manager_store_profile (MMIfaceModem3gppProfileManager *self, /*****************************************************************************/ /* Delete profile (3GPP profile management interface) */ +typedef struct { + MbimDevice *device; + MM3gppProfile *profile; +} DeleteProfileContext; + +static void +delete_profile_context_free (DeleteProfileContext *ctx) +{ + g_object_unref (ctx->device); + g_object_unref (ctx->profile); + g_slice_free (DeleteProfileContext, ctx); +} + static gboolean modem_3gpp_profile_manager_delete_profile_finish (MMIfaceModem3gppProfileManager *self, GAsyncResult *res, @@ -6335,11 +6534,95 @@ profile_manager_provisioned_contexts_reset_ready (MbimDevice *device, } static void -modem_3gpp_profile_manager_delete_profile (MMIfaceModem3gppProfileManager *self, +list_profiles_delete_ready (MMIfaceModem3gppProfileManager *self, + GAsyncResult *res, + GTask *task) +{ + g_autoptr(MbimMessage) message = NULL; + DeleteProfileContext *ctx; + MbimContextType context_type; + const MbimUuid *context_type_uuid = NULL; + GError *error = NULL; + GList *profiles = NULL; + MM3gppProfile *found = NULL; + GList *l; + + ctx = g_task_get_task_data (task); + + if (!modem_3gpp_profile_manager_list_profiles_finish (self, res, &profiles, &error)) { + g_prefix_error (&error, "Couldn't list profiles during delete operation: "); + g_task_return_error (task, error); + g_object_unref (task); + return; + } + + /* look for the exact profile id match */ + for (l = profiles; l; l = g_list_next (l)) { + MM3gppProfile *profile; + + profile = MM_3GPP_PROFILE (l->data); + if (mm_3gpp_profile_get_profile_id (profile) == mm_3gpp_profile_get_profile_id (ctx->profile)) { + found = profile; + break; + } + } + + if (!found) { + g_task_return_new_error (task, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, + "Couldn't find profile with id '%u'", mm_3gpp_profile_get_profile_id (ctx->profile)); + g_object_unref (task); + g_list_free_full (profiles, g_object_unref); + return; + } + + context_type = mm_bearer_apn_type_to_mbim_context_type (mm_3gpp_profile_get_apn_type (found), self, &error); + if (error) { + g_prefix_error (&error, "Failed to convert mbim context type from apn type: "); + g_task_return_error (task, error); + g_object_unref (task); + g_list_free_full (profiles, g_object_unref); + return; + } + context_type_uuid = mbim_uuid_from_context_type (context_type); + g_list_free_full (profiles, g_object_unref); + + mm_obj_dbg (self, "using MS extensions to manage provisioned contexts: deleting profiles matching context type"); + mm_obj_dbg (self, "deleting profiles with context type '%s'", mbim_context_type_get_string (context_type)); + + message = mbim_message_ms_basic_connect_extensions_provisioned_contexts_set_new (MBIM_CONTEXT_OPERATION_DELETE, + context_type_uuid, + MBIM_CONTEXT_IP_TYPE_DEFAULT, + MBIM_CONTEXT_STATE_DISABLED, + MBIM_CONTEXT_ROAMING_CONTROL_ALLOW_ALL, + MBIM_CONTEXT_MEDIA_TYPE_ALL, + MBIM_CONTEXT_SOURCE_ADMIN, + "", /* access string */ + "", /* user */ + "", /* password */ + MBIM_COMPRESSION_NONE, + MBIM_AUTH_PROTOCOL_NONE, + &error); + if (error) { + g_task_return_error (task, error); + g_object_unref (task); + return; + } + + mbim_device_command (ctx->device, + message, + 10, + NULL, + (GAsyncReadyCallback)profile_manager_provisioned_contexts_reset_ready, + task); +} + +static void +modem_3gpp_profile_manager_delete_profile (MMIfaceModem3gppProfileManager *_self, MM3gppProfile *profile, GAsyncReadyCallback callback, gpointer user_data) { + MMBroadbandModemMbim *self = MM_BROADBAND_MODEM_MBIM (_self); MbimDevice *device; GTask *task; GError *error = NULL; @@ -6354,8 +6637,21 @@ modem_3gpp_profile_manager_delete_profile (MMIfaceModem3gppProfileManager *self, profile_id = mm_3gpp_profile_get_profile_id (profile); g_assert (profile_id != MM_3GPP_PROFILE_ID_UNKNOWN); - mm_obj_dbg (self, "deleting profile '%d'", profile_id); + if (self->priv->is_profile_management_ext_supported) { + DeleteProfileContext *ctx; + ctx = g_slice_new0 (DeleteProfileContext); + ctx->profile = g_object_ref (profile); + ctx->device = g_object_ref (device); + g_task_set_task_data (task, ctx, (GDestroyNotify)delete_profile_context_free); + + modem_3gpp_profile_manager_list_profiles (_self, + (GAsyncReadyCallback)list_profiles_delete_ready, + task); + return; + } + + mm_obj_dbg (self, "deleting profile '%d'", profile_id); message = mbim_message_provisioned_contexts_set_new (profile_id, mbim_uuid_from_context_type (MBIM_CONTEXT_TYPE_NONE), "", /* access string */ diff --git a/src/mm-modem-helpers-mbim.c b/src/mm-modem-helpers-mbim.c index 7502a82d..0afa9356 100644 --- a/src/mm-modem-helpers-mbim.c +++ b/src/mm-modem-helpers-mbim.c @@ -612,6 +612,202 @@ mm_bearer_ip_family_to_mbim_context_ip_type (MMBearerIpFamily ip_family, /*****************************************************************************/ +gboolean +mm_bearer_roaming_allowance_to_mbim_context_roaming_control (MMBearerRoamingAllowance mask, + gpointer log_object, + MbimContextRoamingControl *out_value, + GError **error) +{ + if (mask == MM_BEARER_ROAMING_ALLOWANCE_NONE) { + mm_obj_dbg (log_object, "using default (all) roaming allowance"); + *out_value = MBIM_CONTEXT_ROAMING_CONTROL_ALLOW_ALL; + } else if (mask == MM_BEARER_ROAMING_ALLOWANCE_HOME) + *out_value =MBIM_CONTEXT_ROAMING_CONTROL_HOME_ONLY; + else if (mask == MM_BEARER_ROAMING_ALLOWANCE_PARTNER) + *out_value =MBIM_CONTEXT_ROAMING_CONTROL_PARTNER_ONLY; + else if (mask == MM_BEARER_ROAMING_ALLOWANCE_NON_PARTNER) + *out_value =MBIM_CONTEXT_ROAMING_CONTROL_NON_PARTNER_ONLY; + else if (mask == (MM_BEARER_ROAMING_ALLOWANCE_HOME | MM_BEARER_ROAMING_ALLOWANCE_PARTNER)) + *out_value =MBIM_CONTEXT_ROAMING_CONTROL_HOME_AND_PARTNER; + else if (mask == (MM_BEARER_ROAMING_ALLOWANCE_HOME | MM_BEARER_ROAMING_ALLOWANCE_NON_PARTNER)) + *out_value =MBIM_CONTEXT_ROAMING_CONTROL_HOME_AND_NON_PARTNER; + else if (mask == (MM_BEARER_ROAMING_ALLOWANCE_PARTNER | MM_BEARER_ROAMING_ALLOWANCE_NON_PARTNER)) + *out_value =MBIM_CONTEXT_ROAMING_CONTROL_PARTNER_AND_NON_PARTNER; + else if (mask == (MM_BEARER_ROAMING_ALLOWANCE_HOME | MM_BEARER_ROAMING_ALLOWANCE_PARTNER | MM_BEARER_ROAMING_ALLOWANCE_NON_PARTNER)) + *out_value = MBIM_CONTEXT_ROAMING_CONTROL_ALLOW_ALL; + else { + g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_UNSUPPORTED, + "Unsupported roaming allowance mask: 0x%x", mask); + return FALSE; + } + + return TRUE; +} + +MMBearerRoamingAllowance +mm_bearer_roaming_allowance_from_mbim_context_roaming_control (MbimContextRoamingControl value, + GError **error) +{ + switch (value) { + case MBIM_CONTEXT_ROAMING_CONTROL_HOME_ONLY: + return MM_BEARER_ROAMING_ALLOWANCE_HOME; + case MBIM_CONTEXT_ROAMING_CONTROL_PARTNER_ONLY: + return MM_BEARER_ROAMING_ALLOWANCE_PARTNER; + case MBIM_CONTEXT_ROAMING_CONTROL_NON_PARTNER_ONLY: + return MM_BEARER_ROAMING_ALLOWANCE_NON_PARTNER; + case MBIM_CONTEXT_ROAMING_CONTROL_HOME_AND_PARTNER: + return (MM_BEARER_ROAMING_ALLOWANCE_HOME | MM_BEARER_ROAMING_ALLOWANCE_PARTNER); + case MBIM_CONTEXT_ROAMING_CONTROL_HOME_AND_NON_PARTNER: + return (MM_BEARER_ROAMING_ALLOWANCE_HOME | MM_BEARER_ROAMING_ALLOWANCE_NON_PARTNER); + case MBIM_CONTEXT_ROAMING_CONTROL_PARTNER_AND_NON_PARTNER: + return (MM_BEARER_ROAMING_ALLOWANCE_PARTNER | MM_BEARER_ROAMING_ALLOWANCE_NON_PARTNER); + case MBIM_CONTEXT_ROAMING_CONTROL_ALLOW_ALL: + return (MM_BEARER_ROAMING_ALLOWANCE_HOME | MM_BEARER_ROAMING_ALLOWANCE_PARTNER | MM_BEARER_ROAMING_ALLOWANCE_NON_PARTNER); + default: + g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_UNSUPPORTED, + "Unsupported roaming control value: 0x%x", value); + return MM_BEARER_ROAMING_ALLOWANCE_NONE; + } +} + +/*****************************************************************************/ + +gboolean +mm_bearer_access_type_preference_to_mbim_context_media_type (MMBearerAccessTypePreference value, + gpointer log_object, + MbimContextMediaType *out_value, + GError **error) +{ + switch (value) { + case MM_BEARER_ACCESS_TYPE_PREFERENCE_NONE: + mm_obj_dbg (log_object, "using default (cellular only) context media type"); + *out_value = MBIM_CONTEXT_MEDIA_TYPE_CELLULAR_ONLY; + return TRUE; + case MM_BEARER_ACCESS_TYPE_PREFERENCE_3GPP_ONLY: + *out_value = MBIM_CONTEXT_MEDIA_TYPE_CELLULAR_ONLY; + return TRUE; + case MM_BEARER_ACCESS_TYPE_PREFERENCE_3GPP_PREFERRED: + *out_value = MBIM_CONTEXT_MEDIA_TYPE_ALL; + return TRUE; + case MM_BEARER_ACCESS_TYPE_PREFERENCE_NON_3GPP_ONLY: + *out_value = MBIM_CONTEXT_MEDIA_TYPE_WIFI_ONLY; + return TRUE; + default: + g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_UNSUPPORTED, + "Unsupported roaming control value: 0x%x", value); + return FALSE; + } +} + +gboolean +mm_bearer_access_type_preference_from_mbim_context_media_type (MbimContextMediaType value, + MMBearerAccessTypePreference *out_value, + GError **error) +{ + switch (value) { + case MBIM_CONTEXT_MEDIA_TYPE_CELLULAR_ONLY: + *out_value = MM_BEARER_ACCESS_TYPE_PREFERENCE_3GPP_ONLY; + return TRUE; + case MBIM_CONTEXT_MEDIA_TYPE_WIFI_ONLY: + *out_value = MM_BEARER_ACCESS_TYPE_PREFERENCE_NON_3GPP_ONLY; + return TRUE; + case MBIM_CONTEXT_MEDIA_TYPE_ALL: + *out_value = MM_BEARER_ACCESS_TYPE_PREFERENCE_3GPP_PREFERRED; + return TRUE; + default: + g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_UNSUPPORTED, + "Unsupported roaming control value: 0x%x", value); + return FALSE; + } +} + +/*****************************************************************************/ + +gboolean +mm_boolean_from_mbim_context_state (MbimContextState value, + gboolean *out_value, + GError **error) +{ + switch (value) { + case MBIM_CONTEXT_STATE_DISABLED: + *out_value = FALSE; + return TRUE; + case MBIM_CONTEXT_STATE_ENABLED: + *out_value = TRUE; + return TRUE; + default: + g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_UNSUPPORTED, + "Unsupported context state value: 0x%x", value); + return FALSE; + } + +} + +MbimContextState +mm_boolean_to_mbim_context_state (gboolean value) +{ + return (value ? MBIM_CONTEXT_STATE_ENABLED: MBIM_CONTEXT_STATE_DISABLED); +} + +/*****************************************************************************/ + +MMBearerProfileSource +mm_bearer_profile_source_from_mbim_context_source (MbimContextSource value, + GError **error) +{ + switch (value) { + case MBIM_CONTEXT_SOURCE_ADMIN: + return MM_BEARER_PROFILE_SOURCE_ADMIN; + case MBIM_CONTEXT_SOURCE_USER: + return MM_BEARER_PROFILE_SOURCE_USER; + case MBIM_CONTEXT_SOURCE_OPERATOR: + return MM_BEARER_PROFILE_SOURCE_OPERATOR; + case MBIM_CONTEXT_SOURCE_MODEM: + return MM_BEARER_PROFILE_SOURCE_MODEM; + case MBIM_CONTEXT_SOURCE_DEVICE: + return MM_BEARER_PROFILE_SOURCE_DEVICE; + default: + g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_UNSUPPORTED, + "Unsupported context source value: 0x%x", value); + return MM_BEARER_PROFILE_SOURCE_UNKNOWN; + } +} + +gboolean +mm_bearer_profile_source_to_mbim_context_source (MMBearerProfileSource value, + gpointer log_object, + MbimContextSource *out_value, + GError **error) +{ + switch (value) { + case MM_BEARER_PROFILE_SOURCE_UNKNOWN: + mm_obj_dbg (log_object, "using default (admin) context source"); + *out_value = MBIM_CONTEXT_SOURCE_ADMIN; + return TRUE; + case MM_BEARER_PROFILE_SOURCE_ADMIN: + *out_value = MBIM_CONTEXT_SOURCE_ADMIN; + return TRUE; + case MM_BEARER_PROFILE_SOURCE_USER: + *out_value = MBIM_CONTEXT_SOURCE_USER; + return TRUE; + case MM_BEARER_PROFILE_SOURCE_OPERATOR: + *out_value = MBIM_CONTEXT_SOURCE_OPERATOR; + return TRUE; + case MM_BEARER_PROFILE_SOURCE_MODEM: + *out_value = MBIM_CONTEXT_SOURCE_MODEM; + return TRUE; + case MM_BEARER_PROFILE_SOURCE_DEVICE: + *out_value = MBIM_CONTEXT_SOURCE_DEVICE; + return TRUE; + default: + g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_UNSUPPORTED, + "Unsupported profile source value: 0x%x", value); + return FALSE; + } +} + +/*****************************************************************************/ + /* index in the array is the code point (8 possible values), and the actual * value is the lower limit of the error rate range. */ static const gdouble bit_error_rate_ranges[] = { 0.00, 0.20, 0.40, 0.80, 1.60, 3.20, 6.40, 12.80 }; diff --git a/src/mm-modem-helpers-mbim.h b/src/mm-modem-helpers-mbim.h index 909d0186..abf5413b 100644 --- a/src/mm-modem-helpers-mbim.h +++ b/src/mm-modem-helpers-mbim.h @@ -67,6 +67,33 @@ MbimContextType mm_bearer_apn_type_to_mbim_context_type (MMBearerApnT gpointer log_object, GError **error); +gboolean mm_bearer_roaming_allowance_to_mbim_context_roaming_control (MMBearerRoamingAllowance mask, + gpointer log_object, + MbimContextRoamingControl *out_value, + GError **error); +MMBearerRoamingAllowance mm_bearer_roaming_allowance_from_mbim_context_roaming_control (MbimContextRoamingControl value, + GError **error); + +gboolean mm_bearer_access_type_preference_to_mbim_context_media_type (MMBearerAccessTypePreference value, + gpointer log_object, + MbimContextMediaType *out_value, + GError **error); +gboolean mm_bearer_access_type_preference_from_mbim_context_media_type (MbimContextMediaType value, + MMBearerAccessTypePreference *out_value, + GError **error); + +gboolean mm_boolean_from_mbim_context_state (MbimContextState value, + gboolean *out_value, + GError **error); +MbimContextState mm_boolean_to_mbim_context_state (gboolean value); + +MMBearerProfileSource mm_bearer_profile_source_from_mbim_context_source (MbimContextSource value, + GError **error); +gboolean mm_bearer_profile_source_to_mbim_context_source (MMBearerProfileSource value, + gpointer log_object, + MbimContextSource *out_value, + GError **error); + gboolean mm_signal_error_rate_percentage_from_coded_value (guint coded_value, gdouble *out_percentage, gboolean is_gsm, |