aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mm-broadband-modem-mbim.c406
-rw-r--r--src/mm-modem-helpers-mbim.c196
-rw-r--r--src/mm-modem-helpers-mbim.h27
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,