broadband-modem-mbim: implement profile management support

We use the "Provisioned Contexts" message support to add and edit
profiles.

We also use the same message, with context-type set to "none" to
attempt deleting it, although that doesn't seem to be fully supported
by all modems. E.g. the EM7345 (FIH7160_V1.1_MODEM_01.1349.12) will
still report contexts 'deleted' in this way, with the context-type set
to "none".º
This commit is contained in:
Aleksander Morgado
2021-04-29 10:13:22 +00:00
parent 49b63cc62b
commit 72879e4095
3 changed files with 590 additions and 13 deletions
+522 -13
View File
@@ -35,6 +35,7 @@
#include "mm-bearer-list.h"
#include "mm-iface-modem.h"
#include "mm-iface-modem-3gpp.h"
#include "mm-iface-modem-3gpp-profile-manager.h"
#include "mm-iface-modem-3gpp-ussd.h"
#include "mm-iface-modem-location.h"
#include "mm-iface-modem-messaging.h"
@@ -46,14 +47,15 @@
# include "mm-shared-qmi.h"
#endif
static void iface_modem_init (MMIfaceModem *iface);
static void iface_modem_3gpp_init (MMIfaceModem3gpp *iface);
static void iface_modem_3gpp_ussd_init (MMIfaceModem3gppUssd *iface);
static void iface_modem_location_init (MMIfaceModemLocation *iface);
static void iface_modem_messaging_init (MMIfaceModemMessaging *iface);
static void iface_modem_signal_init (MMIfaceModemSignal *iface);
static void iface_modem_init (MMIfaceModem *iface);
static void iface_modem_3gpp_init (MMIfaceModem3gpp *iface);
static void iface_modem_3gpp_profile_manager_init (MMIfaceModem3gppProfileManager *iface);
static void iface_modem_3gpp_ussd_init (MMIfaceModem3gppUssd *iface);
static void iface_modem_location_init (MMIfaceModemLocation *iface);
static void iface_modem_messaging_init (MMIfaceModemMessaging *iface);
static void iface_modem_signal_init (MMIfaceModemSignal *iface);
#if defined WITH_QMI && QMI_MBIM_QMUX_SUPPORTED
static void shared_qmi_init (MMSharedQmi *iface);
static void shared_qmi_init (MMSharedQmi *iface);
#endif
#if defined WITH_QMI && QMI_MBIM_QMUX_SUPPORTED
@@ -64,6 +66,7 @@ static MMIfaceModemSignal *iface_modem_signal_parent;
G_DEFINE_TYPE_EXTENDED (MMBroadbandModemMbim, mm_broadband_modem_mbim, MM_TYPE_BROADBAND_MODEM, 0,
G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM, iface_modem_init)
G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_3GPP, iface_modem_3gpp_init)
G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_3GPP_PROFILE_MANAGER, iface_modem_3gpp_profile_manager_init)
G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_3GPP_USSD, iface_modem_3gpp_ussd_init)
G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_LOCATION, iface_modem_location_init)
G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_MESSAGING, iface_modem_messaging_init)
@@ -84,6 +87,7 @@ typedef enum {
PROCESS_NOTIFICATION_FLAG_PCO = 1 << 6,
PROCESS_NOTIFICATION_FLAG_USSD = 1 << 7,
PROCESS_NOTIFICATION_FLAG_LTE_ATTACH_STATUS = 1 << 8,
PROCESS_NOTIFICATION_FLAG_PROVISIONED_CONTEXTS = 1 << 9,
} ProcessNotificationFlag;
#if defined WITH_QMI && QMI_MBIM_QMUX_SUPPORTED
@@ -106,6 +110,7 @@ struct _MMBroadbandModemMbimPrivate {
gchar *caps_hardware_info;
/* Supported features */
gboolean is_profile_management_supported;
gboolean is_pco_supported;
gboolean is_lte_attach_status_supported;
gboolean is_ussd_supported;
@@ -2339,6 +2344,16 @@ query_device_services_ready (MbimDevice *device,
service = mbim_uuid_to_service (&device_services[i]->device_service_id);
if (service == MBIM_SERVICE_BASIC_CONNECT) {
for (j = 0; j < device_services[i]->cids_count; j++) {
if (device_services[i]->cids[j] == MBIM_CID_BASIC_CONNECT_PROVISIONED_CONTEXTS) {
mm_obj_dbg (self, "Profile management is supported");
self->priv->is_profile_management_supported = TRUE;
}
}
continue;
}
if (service == MBIM_SERVICE_MS_BASIC_CONNECT_EXTENSIONS) {
for (j = 0; j < device_services[i]->cids_count; j++) {
if (device_services[i]->cids[j] == MBIM_CID_MS_BASIC_CONNECT_EXTENSIONS_PCO) {
@@ -3421,6 +3436,15 @@ basic_connect_notification_packet_service (MMBroadbandModemMbim *self,
update_access_technologies (self);
}
static void
basic_connect_notification_provisioned_contexts (MMBroadbandModemMbim *self,
MbimMessage *notification)
{
/* We don't even attempt to parse the indication, we just need to notify that
* something changed to the upper layers */
mm_iface_modem_3gpp_profile_manager_updated (MM_IFACE_MODEM_3GPP_PROFILE_MANAGER (self));
}
static void add_sms_part (MMBroadbandModemMbim *self,
const MbimSmsPduReadRecord *pdu);
@@ -3476,6 +3500,9 @@ basic_connect_notification (MMBroadbandModemMbim *self,
if (self->priv->setup_flags & PROCESS_NOTIFICATION_FLAG_PACKET_SERVICE)
basic_connect_notification_packet_service (self, notification);
break;
case MBIM_CID_BASIC_CONNECT_PROVISIONED_CONTEXTS:
if (self->priv->setup_flags & PROCESS_NOTIFICATION_FLAG_PROVISIONED_CONTEXTS)
basic_connect_notification_provisioned_contexts (self, notification);
default:
/* Ignore */
break;
@@ -3740,7 +3767,9 @@ common_setup_cleanup_unsolicited_events_sync (MMBroadbandModemMbim *self,
if (!device)
return;
mm_obj_dbg (self, "supported notifications: signal (%s), registration (%s), sms (%s), connect (%s), subscriber (%s), packet (%s), pco (%s), ussd (%s), lte attach status (%s)",
mm_obj_dbg (self, "supported notifications: signal (%s), registration (%s), sms (%s), "
"connect (%s), subscriber (%s), packet (%s), pco (%s), ussd (%s), "
"lte attach status (%s), provisioned contexts (%s)",
self->priv->setup_flags & PROCESS_NOTIFICATION_FLAG_SIGNAL_QUALITY ? "yes" : "no",
self->priv->setup_flags & PROCESS_NOTIFICATION_FLAG_REGISTRATION_UPDATES ? "yes" : "no",
self->priv->setup_flags & PROCESS_NOTIFICATION_FLAG_SMS_READ ? "yes" : "no",
@@ -3749,7 +3778,8 @@ common_setup_cleanup_unsolicited_events_sync (MMBroadbandModemMbim *self,
self->priv->setup_flags & PROCESS_NOTIFICATION_FLAG_PACKET_SERVICE ? "yes" : "no",
self->priv->setup_flags & PROCESS_NOTIFICATION_FLAG_PCO ? "yes" : "no",
self->priv->setup_flags & PROCESS_NOTIFICATION_FLAG_USSD ? "yes" : "no",
self->priv->setup_flags & PROCESS_NOTIFICATION_FLAG_LTE_ATTACH_STATUS ? "yes" : "no");
self->priv->setup_flags & PROCESS_NOTIFICATION_FLAG_LTE_ATTACH_STATUS ? "yes" : "no",
self->priv->setup_flags & PROCESS_NOTIFICATION_FLAG_PROVISIONED_CONTEXTS ? "yes" : "no");
if (setup) {
/* Don't re-enable it if already there */
@@ -3914,7 +3944,9 @@ common_enable_disable_unsolicited_events (MMBroadbandModemMbim *self,
if (!peek_device (self, &device, callback, user_data))
return;
mm_obj_dbg (self, "enabled notifications: signal (%s), registration (%s), sms (%s), connect (%s), subscriber (%s), packet (%s), pco (%s), ussd (%s), lte attach status (%s)",
mm_obj_dbg (self, "enabled notifications: signal (%s), registration (%s), sms (%s), "
"connect (%s), subscriber (%s), packet (%s), pco (%s), ussd (%s), "
"lte attach status (%s), provisioned contexts (%s)",
self->priv->enable_flags & PROCESS_NOTIFICATION_FLAG_SIGNAL_QUALITY ? "yes" : "no",
self->priv->enable_flags & PROCESS_NOTIFICATION_FLAG_REGISTRATION_UPDATES ? "yes" : "no",
self->priv->enable_flags & PROCESS_NOTIFICATION_FLAG_SMS_READ ? "yes" : "no",
@@ -3923,7 +3955,8 @@ common_enable_disable_unsolicited_events (MMBroadbandModemMbim *self,
self->priv->enable_flags & PROCESS_NOTIFICATION_FLAG_PACKET_SERVICE ? "yes" : "no",
self->priv->enable_flags & PROCESS_NOTIFICATION_FLAG_PCO ? "yes" : "no",
self->priv->enable_flags & PROCESS_NOTIFICATION_FLAG_USSD ? "yes" : "no",
self->priv->enable_flags & PROCESS_NOTIFICATION_FLAG_LTE_ATTACH_STATUS ? "yes" : "no");
self->priv->enable_flags & PROCESS_NOTIFICATION_FLAG_LTE_ATTACH_STATUS ? "yes" : "no",
self->priv->enable_flags & PROCESS_NOTIFICATION_FLAG_PROVISIONED_CONTEXTS ? "yes" : "no");
entries = g_new0 (MbimEventEntry *, 5);
@@ -3932,11 +3965,12 @@ common_enable_disable_unsolicited_events (MMBroadbandModemMbim *self,
self->priv->enable_flags & PROCESS_NOTIFICATION_FLAG_REGISTRATION_UPDATES ||
self->priv->enable_flags & PROCESS_NOTIFICATION_FLAG_CONNECT ||
self->priv->enable_flags & PROCESS_NOTIFICATION_FLAG_SUBSCRIBER_INFO ||
self->priv->enable_flags & PROCESS_NOTIFICATION_FLAG_PACKET_SERVICE) {
self->priv->enable_flags & PROCESS_NOTIFICATION_FLAG_PACKET_SERVICE ||
self->priv->enable_flags & PROCESS_NOTIFICATION_FLAG_PROVISIONED_CONTEXTS) {
entries[n_entries] = g_new (MbimEventEntry, 1);
memcpy (&(entries[n_entries]->device_service_id), MBIM_UUID_BASIC_CONNECT, sizeof (MbimUuid));
entries[n_entries]->cids_count = 0;
entries[n_entries]->cids = g_new0 (guint32, 5);
entries[n_entries]->cids = g_new0 (guint32, 6);
if (self->priv->enable_flags & PROCESS_NOTIFICATION_FLAG_SIGNAL_QUALITY)
entries[n_entries]->cids[entries[n_entries]->cids_count++] = MBIM_CID_BASIC_CONNECT_SIGNAL_STATE;
if (self->priv->enable_flags & PROCESS_NOTIFICATION_FLAG_REGISTRATION_UPDATES)
@@ -3947,6 +3981,8 @@ common_enable_disable_unsolicited_events (MMBroadbandModemMbim *self,
entries[n_entries]->cids[entries[n_entries]->cids_count++] = MBIM_CID_BASIC_CONNECT_SUBSCRIBER_READY_STATUS;
if (self->priv->enable_flags & PROCESS_NOTIFICATION_FLAG_PACKET_SERVICE)
entries[n_entries]->cids[entries[n_entries]->cids_count++] = MBIM_CID_BASIC_CONNECT_PACKET_SERVICE;
if (self->priv->enable_flags & PROCESS_NOTIFICATION_FLAG_PROVISIONED_CONTEXTS)
entries[n_entries]->cids[entries[n_entries]->cids_count++] = MBIM_CID_BASIC_CONNECT_PROVISIONED_CONTEXTS;
n_entries++;
}
@@ -4844,6 +4880,445 @@ modem_signal_load_values (MMIfaceModemSignal *self,
task);
}
/*****************************************************************************/
/* Check support (3GPP profile management interface) */
static gboolean
modem_3gpp_profile_manager_check_support_finish (MMIfaceModem3gppProfileManager *self,
GAsyncResult *res,
GError **error)
{
return g_task_propagate_boolean (G_TASK (res), error);
}
static void
modem_3gpp_profile_manager_check_support (MMIfaceModem3gppProfileManager *_self,
GAsyncReadyCallback callback,
gpointer user_data)
{
MMBroadbandModemMbim *self = MM_BROADBAND_MODEM_MBIM (_self);
GTask *task;
task = g_task_new (self, NULL, callback, user_data);
if (mm_iface_modem_is_3gpp (MM_IFACE_MODEM (self)) && self->priv->is_profile_management_supported)
g_task_return_boolean (task, TRUE);
else
g_task_return_boolean (task, FALSE);
g_object_unref (task);
}
/*****************************************************************************/
/* Setup/Cleanup unsolicited event handlers (3gppProfileManager interface) */
static gboolean
common_setup_cleanup_unsolicited_events_3gpp_profile_manager_finish (MMIfaceModem3gppProfileManager *self,
GAsyncResult *res,
GError **error)
{
return common_setup_cleanup_unsolicited_events_finish (MM_BROADBAND_MODEM_MBIM (self), res, error);
}
static void
cleanup_unsolicited_events_3gpp_profile_manager (MMIfaceModem3gppProfileManager *_self,
GAsyncReadyCallback callback,
gpointer user_data)
{
MMBroadbandModemMbim *self = MM_BROADBAND_MODEM_MBIM (_self);
self->priv->setup_flags &= ~PROCESS_NOTIFICATION_FLAG_PROVISIONED_CONTEXTS;
common_setup_cleanup_unsolicited_events (self, FALSE, callback, user_data);
}
static void
setup_unsolicited_events_3gpp_profile_manager (MMIfaceModem3gppProfileManager *_self,
GAsyncReadyCallback callback,
gpointer user_data)
{
MMBroadbandModemMbim *self = MM_BROADBAND_MODEM_MBIM (_self);
self->priv->setup_flags |= PROCESS_NOTIFICATION_FLAG_PROVISIONED_CONTEXTS;
common_setup_cleanup_unsolicited_events (self, TRUE, callback, user_data);
}
/*****************************************************************************/
/* Enable/Disable unsolicited event handlers (3gppProfileManager interface) */
static gboolean
common_enable_disable_unsolicited_events_3gpp_profile_manager_finish (MMIfaceModem3gppProfileManager *self,
GAsyncResult *res,
GError **error)
{
return common_enable_disable_unsolicited_events_finish (MM_BROADBAND_MODEM_MBIM (self), res, error);
}
static void
disable_unsolicited_events_3gpp_profile_manager (MMIfaceModem3gppProfileManager *_self,
GAsyncReadyCallback callback,
gpointer user_data)
{
MMBroadbandModemMbim *self = MM_BROADBAND_MODEM_MBIM (_self);
self->priv->enable_flags &= ~PROCESS_NOTIFICATION_FLAG_PROVISIONED_CONTEXTS;
common_enable_disable_unsolicited_events (self, callback, user_data);
}
static void
enable_unsolicited_events_3gpp_profile_manager (MMIfaceModem3gppProfileManager *_self,
GAsyncReadyCallback callback,
gpointer user_data)
{
MMBroadbandModemMbim *self = MM_BROADBAND_MODEM_MBIM (_self);
self->priv->enable_flags |= PROCESS_NOTIFICATION_FLAG_PROVISIONED_CONTEXTS;
common_enable_disable_unsolicited_events (self, callback, user_data);
}
/*****************************************************************************/
/* Check format (3gppProfileManager interface) */
static gboolean
modem_3gpp_profile_manager_check_format_finish (MMIfaceModem3gppProfileManager *self,
GAsyncResult *res,
gboolean *new_id,
gint *min_profile_id,
gint *max_profile_id,
GEqualFunc *apn_cmp,
MM3gppProfileCmpFlags *profile_cmp_flags,
GError **error)
{
if (!g_task_propagate_boolean (G_TASK (res), error)) {
g_assert_not_reached ();
return FALSE;
}
if (new_id)
*new_id = TRUE;
if (min_profile_id)
*min_profile_id = 1;
if (max_profile_id)
*max_profile_id = G_MAXINT - 1;
/* use default string comparison method */
if (apn_cmp)
*apn_cmp = NULL;
/* we don't support IP type in the profiles */
if (profile_cmp_flags)
*profile_cmp_flags = MM_3GPP_PROFILE_CMP_FLAGS_NO_IP_TYPE;
return TRUE;
}
static void
modem_3gpp_profile_manager_check_format (MMIfaceModem3gppProfileManager *self,
MMBearerIpFamily ip_type,
GAsyncReadyCallback callback,
gpointer user_data)
{
GTask *task;
task = g_task_new (self, NULL, callback, user_data);
g_task_return_boolean (task, TRUE);
g_object_unref (task);
}
/*****************************************************************************/
/* List profiles (3GPP profile management interface) */
typedef struct {
GList *profiles;
} ListProfilesContext;
static void
list_profiles_context_free (ListProfilesContext *ctx)
{
mm_3gpp_profile_list_free (ctx->profiles);
g_slice_free (ListProfilesContext, ctx);
}
static gboolean
modem_3gpp_profile_manager_list_profiles_finish (MMIfaceModem3gppProfileManager *self,
GAsyncResult *res,
GList **out_profiles,
GError **error)
{
ListProfilesContext *ctx;
if (!g_task_propagate_boolean (G_TASK (res), error))
return FALSE;
ctx = g_task_get_task_data (G_TASK (res));
if (out_profiles)
*out_profiles = g_steal_pointer (&ctx->profiles);
return TRUE;
}
static MM3gppProfile *
provisioned_context_element_to_3gpp_profile (MbimProvisionedContextElement *element)
{
MM3gppProfile *profile;
MMBearerApnType apn_type;
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)));
/* compression unused, and ip-type not provided */
return profile;
}
static void
profile_manager_provisioned_contexts_query_ready (MbimDevice *device,
GAsyncResult *res,
GTask *task)
{
ListProfilesContext *ctx;
GError *error = NULL;
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);
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;
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
g_task_return_error (task, error);
g_object_unref (task);
}
static void
modem_3gpp_profile_manager_list_profiles (MMIfaceModem3gppProfileManager *self,
GAsyncReadyCallback callback,
gpointer user_data)
{
MbimDevice *device;
GTask *task;
g_autoptr(MbimMessage) message = NULL;
if (!peek_device (self, &device, callback, user_data))
return;
task = g_task_new (self, NULL, callback, user_data);
mm_obj_dbg (self, "querying provisioned contexts...");
message = mbim_message_provisioned_contexts_query_new (NULL);
mbim_device_command (device,
message,
10,
NULL,
(GAsyncReadyCallback)profile_manager_provisioned_contexts_query_ready,
task);
}
/*****************************************************************************/
/* Store profile (3GPP profile management interface) */
static gint
modem_3gpp_profile_manager_store_profile_finish (MMIfaceModem3gppProfileManager *self,
GAsyncResult *res,
GError **error)
{
if (!g_task_propagate_boolean (G_TASK (res), error))
return MM_3GPP_PROFILE_ID_UNKNOWN;
return GPOINTER_TO_INT (g_task_get_task_data (G_TASK (res)));
}
static void
profile_manager_provisioned_contexts_set_ready (MbimDevice *device,
GAsyncResult *res,
GTask *task)
{
GError *error = NULL;
g_autoptr(MbimMessage) response = NULL;
response = mbim_device_command_finish (device, res, &error);
if (response && mbim_message_response_get_result (response, MBIM_MESSAGE_TYPE_COMMAND_DONE, &error))
g_task_return_boolean (task, TRUE);
else
g_task_return_error (task, error);
g_object_unref (task);
}
static void
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;
if (!peek_device (self, &device, callback, user_data))
return;
task = g_task_new (self, NULL, callback, user_data);
profile_id = mm_3gpp_profile_get_profile_id (profile);
g_assert (profile_id != MM_3GPP_PROFILE_ID_UNKNOWN);
g_task_set_task_data (task, GINT_TO_POINTER (profile_id), NULL);
apn = mm_3gpp_profile_get_apn (profile);
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_task_return_error (task, error);
g_object_unref (task);
return;
}
context_type_uuid = mbim_uuid_from_context_type (context_type);
apn_type_str = mm_bearer_apn_type_build_string_from_mask (apn_type);
user = mm_3gpp_profile_get_user (profile);
password = mm_3gpp_profile_get_password (profile);
allowed_auth = mm_3gpp_profile_get_allowed_auth (profile);
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_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);
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);
return;
}
mbim_device_command (device,
message,
10,
NULL,
(GAsyncReadyCallback)profile_manager_provisioned_contexts_set_ready,
task);
}
/*****************************************************************************/
/* Delete profile (3GPP profile management interface) */
static gboolean
modem_3gpp_profile_manager_delete_profile_finish (MMIfaceModem3gppProfileManager *self,
GAsyncResult *res,
GError **error)
{
return g_task_propagate_boolean (G_TASK (res), error);
}
static void
profile_manager_provisioned_contexts_reset_ready (MbimDevice *device,
GAsyncResult *res,
GTask *task)
{
GError *error = NULL;
g_autoptr(MbimMessage) response = NULL;
response = mbim_device_command_finish (device, res, &error);
if (response && mbim_message_response_get_result (response, MBIM_MESSAGE_TYPE_COMMAND_DONE, &error))
g_task_return_boolean (task, TRUE);
else
g_task_return_error (task, error);
g_object_unref (task);
}
static void
modem_3gpp_profile_manager_delete_profile (MMIfaceModem3gppProfileManager *self,
MM3gppProfile *profile,
GAsyncReadyCallback callback,
gpointer user_data)
{
MbimDevice *device;
GTask *task;
GError *error = NULL;
gint profile_id;
g_autoptr(MbimMessage) message = NULL;
if (!peek_device (self, &device, callback, user_data))
return;
task = g_task_new (self, NULL, callback, user_data);
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);
message = mbim_message_provisioned_contexts_set_new (profile_id,
mbim_uuid_from_context_type (MBIM_CONTEXT_TYPE_NONE),
"", /* access string */
"", /* user */
"", /* pass */
MBIM_COMPRESSION_NONE,
MBIM_AUTH_PROTOCOL_NONE,
"", /* provider id */
&error);
if (error) {
g_task_return_error (task, error);
g_object_unref (task);
return;
}
mbim_device_command (device,
message,
10,
NULL,
(GAsyncReadyCallback)profile_manager_provisioned_contexts_reset_ready,
task);
}
/*****************************************************************************/
/* Check if USSD supported (3GPP/USSD interface) */
@@ -5887,6 +6362,40 @@ iface_modem_3gpp_init (MMIfaceModem3gpp *iface)
iface->scan_networks_finish = modem_3gpp_scan_networks_finish;
}
static void
iface_modem_3gpp_profile_manager_init (MMIfaceModem3gppProfileManager *iface)
{
/* Initialization steps */
iface->check_support = modem_3gpp_profile_manager_check_support;
iface->check_support_finish = modem_3gpp_profile_manager_check_support_finish;
/* Enabling steps */
iface->setup_unsolicited_events = setup_unsolicited_events_3gpp_profile_manager;
iface->setup_unsolicited_events_finish = common_setup_cleanup_unsolicited_events_3gpp_profile_manager_finish;
iface->enable_unsolicited_events = enable_unsolicited_events_3gpp_profile_manager;
iface->enable_unsolicited_events_finish = common_enable_disable_unsolicited_events_3gpp_profile_manager_finish;
/* Disabling steps */
iface->cleanup_unsolicited_events = cleanup_unsolicited_events_3gpp_profile_manager;
iface->cleanup_unsolicited_events_finish = common_setup_cleanup_unsolicited_events_3gpp_profile_manager_finish;
iface->disable_unsolicited_events = disable_unsolicited_events_3gpp_profile_manager;
iface->disable_unsolicited_events_finish = common_enable_disable_unsolicited_events_3gpp_profile_manager_finish;
/* Additional actions */
iface->list_profiles = modem_3gpp_profile_manager_list_profiles;
iface->list_profiles_finish = modem_3gpp_profile_manager_list_profiles_finish;
iface->check_format = modem_3gpp_profile_manager_check_format;
iface->check_format_finish = modem_3gpp_profile_manager_check_format_finish;
iface->check_activated_profile = NULL;
iface->check_activated_profile_finish = NULL;
iface->deactivate_profile = NULL;
iface->deactivate_profile_finish = NULL;
iface->store_profile = modem_3gpp_profile_manager_store_profile;
iface->store_profile_finish = modem_3gpp_profile_manager_store_profile_finish;
iface->delete_profile = modem_3gpp_profile_manager_delete_profile;
iface->delete_profile_finish = modem_3gpp_profile_manager_delete_profile_finish;
}
static void
iface_modem_3gpp_ussd_init (MMIfaceModem3gppUssd *iface)
{
+64
View File
@@ -408,6 +408,70 @@ mm_bearer_allowed_auth_to_mbim_auth_protocol (MMBearerAllowedAuth bearer_auth,
/*****************************************************************************/
MMBearerApnType
mm_bearer_apn_type_from_mbim_context_type (MbimContextType context_type)
{
switch (context_type) {
case MBIM_CONTEXT_TYPE_INTERNET:
return MM_BEARER_APN_TYPE_DEFAULT;
case MBIM_CONTEXT_TYPE_VPN:
return MM_BEARER_APN_TYPE_PRIVATE;
case MBIM_CONTEXT_TYPE_VOICE:
return MM_BEARER_APN_TYPE_VOICE;
case MBIM_CONTEXT_TYPE_PURCHASE:
return MM_BEARER_APN_TYPE_MANAGEMENT;
case MBIM_CONTEXT_TYPE_IMS:
return MM_BEARER_APN_TYPE_IMS;
case MBIM_CONTEXT_TYPE_MMS:
return MM_BEARER_APN_TYPE_MMS;
case MBIM_CONTEXT_TYPE_INVALID:
case MBIM_CONTEXT_TYPE_NONE:
case MBIM_CONTEXT_TYPE_LOCAL:
case MBIM_CONTEXT_TYPE_VIDEO_SHARE:
/* some types unused right now */
default:
return MM_BEARER_APN_TYPE_NONE;
}
}
MbimContextType
mm_bearer_apn_type_to_mbim_context_type (MMBearerApnType apn_type,
gpointer log_object,
GError **error)
{
g_autofree gchar *str = NULL;
/* NOTE: the input is a BITMASK, so we try to find a "best match" */
if (apn_type == MM_BEARER_APN_TYPE_NONE) {
mm_obj_dbg (log_object, "using default (internet) APN type");
return MBIM_CONTEXT_TYPE_INTERNET;
}
if (apn_type & MM_BEARER_APN_TYPE_DEFAULT)
return MBIM_CONTEXT_TYPE_INTERNET;
if (apn_type & MM_BEARER_APN_TYPE_IMS)
return MBIM_CONTEXT_TYPE_IMS;
if (apn_type & MM_BEARER_APN_TYPE_MMS)
return MBIM_CONTEXT_TYPE_MMS;
if (apn_type &MM_BEARER_APN_TYPE_MANAGEMENT)
return MBIM_CONTEXT_TYPE_PURCHASE;
if (apn_type & MM_BEARER_APN_TYPE_VOICE)
return MBIM_CONTEXT_TYPE_VOICE;
if (apn_type & MM_BEARER_APN_TYPE_PRIVATE)
return MBIM_CONTEXT_TYPE_VPN;
str = mm_bearer_apn_type_build_string_from_mask (apn_type);
g_set_error (error,
MM_CORE_ERROR,
MM_CORE_ERROR_UNSUPPORTED,
"Unsupported APN types (%s)",
str);
return MBIM_CONTEXT_TYPE_NONE;
}
/*****************************************************************************/
MMBearerIpFamily
mm_bearer_ip_family_from_mbim_context_ip_type (MbimContextIpType ip_type)
{
+4
View File
@@ -47,6 +47,10 @@ MbimAuthProtocol mm_bearer_allowed_auth_to_mbim_auth_protocol (MMBearerAllo
MMBearerIpFamily mm_bearer_ip_family_from_mbim_context_ip_type (MbimContextIpType ip_type);
MbimContextIpType mm_bearer_ip_family_to_mbim_context_ip_type (MMBearerIpFamily ip_family,
GError **error);
MMBearerApnType mm_bearer_apn_type_from_mbim_context_type (MbimContextType context_type);
MbimContextType mm_bearer_apn_type_to_mbim_context_type (MMBearerApnType apn_type,
gpointer log_object,
GError **error);
/*****************************************************************************/
/* MBIM/SMS to MM translations */