Merge cros/upstream to cros/master
Contains the following commits:
8bc90b71 broadband-modem-qmi: Enable AT URCs and QMI indications (Dylan Van Assche)
438ff54d libmm-glib,tests: include string.h explicitly (Aleksander Morgado)
da0e610f modem-helpers-mbim: include string.h explicitly (Aleksander Morgado)
a9611c62 utils: import ptr array lookup with GEqualFunc from GLib 2.54 (Aleksander Morgado)
e1372a71 iface-modem: detect hotswap on all slots (Pavan Holla)
fbc16360 docs: add api index for 1.18 (Aleksander Morgado)
a4aba0a6 mmcli,sim: add preferred networks list to SIM properties (Teijo Kinnunen)
816beeff libmm-glib,modem-helpers,mm-base-sim: implement Sim.PreferredNetworks (Teijo Kinnunen)
c7d36667 shared-qmi: network registration cancellation logic with asserts disabled (Aleksander Morgado)
f10e4af9 libmm-glib,bearer-properties: fix 'allow roaming' comparison (Aleksander Morgado)
297a8c85 examples: sms: resolve PEP8 issues (Yegor Yefremov)
aba237df broadband-modem-qmi: allow lookup of QMI for data without SIO port (Aleksander Morgado)
381e2f38 base-modem: separate method to lookup exact port by name (Aleksander Morgado)
b8e076f9 kernel-device-udev: keep track of the client object (Aleksander Morgado)
1b35d74c kernel-device: add get_interface_number() method (Aleksander Morgado)
cc07d214 examples: network-scan: get rid of global variables (Yegor Yefremov)
62506034 build: improve releasing notes (Aleksander Morgado)
4a06a027 charsets: detect iconv() support in runtime (Aleksander Morgado)
8a8e0016 charsets: define common translit fallback character (Aleksander Morgado)
c84454c1 charsets: remove charset_hex_to_utf8() (Aleksander Morgado)
0ff3eb7e charsets: remove take_and_convert methods (Aleksander Morgado)
ab4c31ec cinterion: rework mno decoding to use str_to_utf8() (Aleksander Morgado)
6bc07b4b cinterion: rework band encoding to use str_to_utf8() (Aleksander Morgado)
16df1e17 helpers: rework normalize_operator() to use str_to_utf8() (Aleksander Morgado)
63fa9eee charsets,tests: update take_and_convert tests to str_from/to (Aleksander Morgado)
3ac248a7 cinterion: move sequence to set bands to private ctx (Aleksander Morgado)
e5363b54 charsets: use new str_from_utf8() instead of take_and_convert_to_current_charset() (Aleksander Morgado)
395ab06c charsets: use new bytearray_to_utf8() instead of hex_to_utf8() (Aleksander Morgado)
5ea4a591 charsets: use new bytearray_to_utf8() instead of byte_array_to_utf8() (Aleksander Morgado)
033e174e charsets: make charset_gsm_unpacked_to_utf8() private (Aleksander Morgado)
8bfdfb18 charsets: use new bytearray_from_utf8() instead of byte_array_append() (Aleksander Morgado)
75b37e16 charsets: make charset_utf8_to_unpacked_gsm() private (Aleksander Morgado)
9c613d33 charsets: new common APIs to convert from/to charsets and UTF-8 (Aleksander Morgado)
6f32c8d3 charsets: avoid //TRANSLIT when converting to/from charsets (Aleksander Morgado)
bc449cbe charsets: make translit optional in utf8_to_unpacked_gsm() (Aleksander Morgado)
5ce97abd charsets: make translit optional in gsm_unpacked_to_utf8() (Aleksander Morgado)
5480cb67 libmm-glib,tests: add ishexstr/hexstr2bin/bin2hexstr unit tests (Aleksander Morgado)
34de613d libmm-glib,common-helpers: make hexstr2bin() return a guint8 array (Aleksander Morgado)
6d8610d6 libmm-glib,common-helpers: ishexstr() fails on empty input string (Aleksander Morgado)
8c30a6b6 libmm-glib,common-helpers: hexstr2bin fails on empty input string (Aleksander Morgado)
a211981d libmm-glib,common-helpers: make hexstr2bin() accept input string length (Aleksander Morgado)
657cabcf libmm-glib,common-helpers: make hexstr2bin() return a GError (Aleksander Morgado)
dbdf67e9 charsets: remove unused charset_utf8_to_hex() method (Aleksander Morgado)
8b590721 charsets: don't allow quoting in byte_array_append() (Aleksander Morgado)
38a4a9c8 charsets: remove HEX charset type (Aleksander Morgado)
a025e83e charsets: define charset enum explicitly as flags (Aleksander Morgado)
19e5d5f9 build: post-release version bump to 1.17.0 (Aleksander Morgado)
7a5a49b7 release: bump version to 1.16.0 (Aleksander Morgado)
7a5eae2a NEWS: update for 1.16.0 (Aleksander Morgado)
bbd3638d build: require libqmi 1.28.0 (Aleksander Morgado)
a5462014 bearer-mbim: IP type may be reported as deactivated and still have IP settings (Aleksander Morgado)
Cq-Depend: chromium:2729495
Change-Id: Ib418fd49adc23055e82037d69469da794442425e
diff --git a/OWNERS b/OWNERS
new file mode 100644
index 0000000..131ce16
--- /dev/null
+++ b/OWNERS
@@ -0,0 +1,6 @@
+set noparent
+ejcaruso@chromium.org
+pholla@chromium.org
+andrewlassalle@chromium.org
+madhavadas@google.com
+vpalatin@chromium.org
diff --git a/PRESUBMIT.cfg b/PRESUBMIT.cfg
new file mode 100644
index 0000000..51d8dd6
--- /dev/null
+++ b/PRESUBMIT.cfg
@@ -0,0 +1,9 @@
+# This sample config file disables all of the ChromiumOS source style checks.
+# Comment out the disable-flags for any checks you want to leave enabled.
+
+[Hook Overrides]
+stray_whitespace_check: false
+long_line_check: false
+cros_license_check: false
+tab_check: false
+
diff --git a/README.chromium b/README.chromium
new file mode 100644
index 0000000..10c881e
--- /dev/null
+++ b/README.chromium
@@ -0,0 +1,20 @@
+DESCRIPTION="Broadband modem support daemon (new API)"
+HOMEPAGE="http://projects.gnome.org/NetworkManager/"
+UPSTREAM_REPO="git://anongit.freedesktop.org/ModemManager/ModemManager"
+LOCAL_GIT_REPO="https://chromium.googlesource.com/chromiumos/third_party/modemmanager-next.git"
+UPSTREAM_BUGSDB="https://bugzilla.gnome.org/enter_bug.cgi?product=NetworkManager"
+LOCAL_BUGSDB="http://crosbug.com"
+LICENSE="GPLv2"
+LICENSE_FILE="COPYING"
+
+Description:
+
+ModemManager provides a DBus interface to control broadband modem
+devices. The intended user is a network manager program, such as
+NetworkManager, flimflam, or shill.
+
+This repository mirrors the 0.6-api branch of the upstream repository
+while it is under active development as a branch.
+
+Local changes should be minimal, but support for particular modems may
+make it here before they make it upstream.
diff --git a/introspection/org.freedesktop.ModemManager1.Modem.Modem3gpp.xml b/introspection/org.freedesktop.ModemManager1.Modem.Modem3gpp.xml
index e741ae9..8abea6a 100644
--- a/introspection/org.freedesktop.ModemManager1.Modem.Modem3gpp.xml
+++ b/introspection/org.freedesktop.ModemManager1.Modem.Modem3gpp.xml
@@ -247,5 +247,28 @@
-->
<property name="InitialEpsBearerSettings" type="a{sv}" access="read" />
+ <!--
+ Profiles:
+
+ Profiles or contexts provisioned on the modem.
+
+ A list of dictionaries whose entries are:
+ <variablelist>
+ <varlistentry><term><literal>"profile-id"</literal></term>
+ <listitem><para>Unique identifier for this profile (signature <literal>"u"</literal>).</para></listitem></varlistentry>
+ <varlistentry><term><literal>"apn"</literal></term>
+ <listitem><para>Access Point Name, given as a string value (signature <literal>"s"</literal>).</para></listitem></varlistentry>
+ <varlistentry><term><literal>"auth-type"</literal></term>
+ <listitem><para>The authentication method to use, given as a <link linkend="MMBearerAllowedAuth">MMBearerAllowedAuth</link> value (signature <literal>"u"</literal>). Optional.</para></listitem></varlistentry>
+ <varlistentry><term><literal>"user"</literal></term>
+ <listitem><para>User name (if any) required by the network, given as a string value (signature <literal>"s"</literal>). Optional.</para></listitem></varlistentry>
+ <varlistentry><term><literal>"password"</literal></term>
+ <listitem><para>Password (if any) required by the network, given as a string value (signature <literal>"s"</literal>). Optional.</para></listitem></varlistentry>
+ </variablelist>
+
+ This is a read-only property.
+ -->
+ <property name="Profiles" type="aa{sv}" access="read" />
+
</interface>
</node>
diff --git a/plugins/generic/mm-plugin-generic.c b/plugins/generic/mm-plugin-generic.c
index f4c7342..209366a 100644
--- a/plugins/generic/mm-plugin-generic.c
+++ b/plugins/generic/mm-plugin-generic.c
@@ -58,6 +58,13 @@
GError **error)
{
#if defined WITH_QMI
+#if QMI_QRTR_SUPPORTED //TODO(crbug.com/1103840): Remove the ifdefs and upstream
+ return MM_BASE_MODEM (mm_broadband_modem_qmi_new (uid,
+ drivers,
+ mm_plugin_get_name (self),
+ vendor,
+ product));
+#endif
if (mm_port_probe_list_has_qmi_port (probes)) {
mm_obj_dbg (self, "QMI-powered generic modem found...");
return MM_BASE_MODEM (mm_broadband_modem_qmi_new (uid,
diff --git a/plugins/novatel/mm-broadband-modem-novatel-lte.c b/plugins/novatel/mm-broadband-modem-novatel-lte.c
index df33138..3748ac9 100644
--- a/plugins/novatel/mm-broadband-modem-novatel-lte.c
+++ b/plugins/novatel/mm-broadband-modem-novatel-lte.c
@@ -635,6 +635,49 @@
}
/*****************************************************************************/
+/* Initializing the modem (during first enabling) */
+
+static const MMBaseModemAtCommand modem_init_sequence[] = {
+ /* Init command. ITU rec v.250 (6.1.1) says:
+ * The DTE should not include additional commands on the same command line
+ * after the Z command because such commands may be ignored.
+ * So run ATZ alone.
+ */
+ { "Z", 6, FALSE, mm_base_modem_response_processor_no_result_continue },
+
+ /* Temporarily force the modem into LTE only mode to prevent it from falling
+ * back to 3G.
+ * TODO(benchan): Remove this constraint
+ */
+ { "$NWPREFMODE=30", 6, FALSE, mm_base_modem_response_processor_continue_on_error },
+
+ { NULL }
+};
+
+static gboolean
+enabling_modem_init_finish (MMBroadbandModem *self,
+ GAsyncResult *res,
+ GError **error)
+{
+ return !!mm_base_modem_at_command_full_finish (MM_BASE_MODEM (self), res, error);
+}
+
+static void
+enabling_modem_init (MMBroadbandModem *self,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ mm_base_modem_at_sequence_full (MM_BASE_MODEM (self),
+ mm_base_modem_peek_port_primary (MM_BASE_MODEM (self)),
+ modem_init_sequence,
+ NULL, /* response_processor_context */
+ NULL, /* response_processor_context_free */
+ NULL, /* cancellable */
+ callback,
+ user_data);
+}
+
+/*****************************************************************************/
MMBroadbandModemNovatelLte *
mm_broadband_modem_novatel_lte_new (const gchar *device,
@@ -649,6 +692,11 @@
MM_BASE_MODEM_PLUGIN, plugin,
MM_BASE_MODEM_VENDOR_ID, vendor_id,
MM_BASE_MODEM_PRODUCT_ID, product_id,
+ /* Temporarily allows only EPS network registration status */
+ /* TODO(benchan): Remove this constraint */
+ MM_IFACE_MODEM_3GPP_CS_NETWORK_SUPPORTED, FALSE,
+ MM_IFACE_MODEM_3GPP_PS_NETWORK_SUPPORTED, FALSE,
+ MM_IFACE_MODEM_3GPP_EPS_NETWORK_SUPPORTED, TRUE,
NULL);
}
@@ -695,4 +743,8 @@
static void
mm_broadband_modem_novatel_lte_class_init (MMBroadbandModemNovatelLteClass *klass)
{
+ MMBroadbandModemClass *broadband_modem_class = MM_BROADBAND_MODEM_CLASS (klass);
+
+ broadband_modem_class->enabling_modem_init = enabling_modem_init;
+ broadband_modem_class->enabling_modem_init_finish = enabling_modem_init_finish;
}
diff --git a/plugins/tests/test-fixture.c b/plugins/tests/test-fixture.c
index 29eb8d5..ac2d3e6 100644
--- a/plugins/tests/test-fixture.c
+++ b/plugins/tests/test-fixture.c
@@ -142,7 +142,7 @@
break;
/* Blocking wait */
- g_assert_cmpuint (wait_time, <=, 20);
+ g_assert_cmpuint (wait_time, <=, 120);
wait_time++;
sleep (1);
}
diff --git a/src/mm-base-manager.c b/src/mm-base-manager.c
index 4e866f8..f3f7e51 100644
--- a/src/mm-base-manager.c
+++ b/src/mm-base-manager.c
@@ -1263,6 +1263,73 @@
/*****************************************************************************/
+#if QMI_QRTR_SUPPORTED //TODO(crbug.com/1103840): Remove hacks before merging to upstream
+static void
+create_virtual_device (const gchar *id,
+ const gchar *plugin_name,
+ const gchar *const *ports,
+ MMBaseManager *self)
+{
+ MMPlugin *plugin;
+ MMDevice *device;
+ gchar *physdev_uid;
+ GError *error = NULL;
+
+ mm_obj_info (self, "Creating virtual device '%s'", id);
+
+ /* Create device and keep it listed in the Manager */
+ physdev_uid = g_strdup_printf ("/virtual/%s", id);
+ device = mm_device_new (physdev_uid, TRUE, TRUE, self->priv->object_manager);
+ g_hash_table_insert (self->priv->devices, physdev_uid, device);
+
+ /* Grab virtual ports */
+ mm_device_virtual_grab_ports (device, (const gchar **)ports);
+
+ /* Set plugin to use */
+ plugin = mm_plugin_manager_peek_plugin (self->priv->plugin_manager, plugin_name);
+ if (!plugin) {
+ error = g_error_new (MM_CORE_ERROR,
+ MM_CORE_ERROR_NOT_FOUND,
+ "Requested plugin '%s' not found",
+ plugin_name);
+ mm_obj_warn (self, "Couldn't set plugin for virtual device '%s': %s",
+ mm_device_get_uid (device),
+ error->message);
+ goto out;
+ }
+ mm_device_set_plugin (device, G_OBJECT (plugin));
+
+ /* Create modem */
+ if (!mm_device_create_modem (device, &error)) {
+ mm_obj_warn (self, "Couldn't create modem for virtual device '%s': %s",
+ mm_device_get_uid (device),
+ error->message);
+ goto out;
+ }
+
+ mm_obj_info (self, "Modem for virtual device '%s' successfully created",
+ mm_device_get_uid (device));
+
+out:
+
+ if (error) {
+ mm_device_remove_modem (device);
+ g_hash_table_remove (self->priv->devices, mm_device_get_uid (device));
+ g_error_free (error);
+ }
+}
+
+static gboolean
+create_fake_modem (MMBaseManager *self)
+{
+ const gchar *ports[] = { "qmi0", "rmnet_data0", NULL };
+
+ create_virtual_device ("fake", "generic", ports, self);
+
+ return FALSE;
+}
+#endif
+
MMBaseManager *
mm_base_manager_new (GDBusConnection *connection,
const gchar *plugin_dir,
@@ -1458,6 +1525,9 @@
error))
return FALSE;
}
+#if QMI_QRTR_SUPPORTED //TODO(crbug.com/1103840): Remove hacks before merging to upstream
+ g_timeout_add_seconds (3, (GSourceFunc)create_fake_modem, MM_BASE_MANAGER (initable));
+#endif
/* All good */
return TRUE;
diff --git a/src/mm-base-modem.c b/src/mm-base-modem.c
index 72b9b84..cfa50a2 100644
--- a/src/mm-base-modem.c
+++ b/src/mm-base-modem.c
@@ -288,6 +288,18 @@
port = base_modem_create_ignored_port (self, name);
else if (g_str_equal (subsys, "net"))
port = base_modem_create_net_port (self, name);
+#if QMI_QRTR_SUPPORTED //TODO(crbug.com/1103840): Remove hacks before merging to upstream
+ else if (g_str_has_prefix (subsys, "virtual") &&
+ g_str_has_prefix (name, "rmnet_data0")) {
+ mm_obj_info (self, "@@ %s: virtual net port = %s", __FUNCTION__, name);
+ port = base_modem_create_net_port (self, name);
+ }
+ else if (g_str_has_prefix (subsys, "virtual") &&
+ g_str_has_prefix (name, "qmi")) {
+ mm_obj_info (self, "@@ %s: virtual qmi port = %s", __FUNCTION__, name);
+ port = base_modem_create_usbmisc_port (self, name, ptype);
+ }
+#endif
else if (g_str_equal (subsys, "tty"))
port = base_modem_create_tty_port (self, name, kernel_device, ptype);
else if (g_str_equal (subsys, "usbmisc"))
diff --git a/src/mm-bearer-qmi.c b/src/mm-bearer-qmi.c
index 670fb80..e14c77e 100644
--- a/src/mm-bearer-qmi.c
+++ b/src/mm-bearer-qmi.c
@@ -412,6 +412,9 @@
CONNECT_STEP_IP_FAMILY_IPV4,
CONNECT_STEP_BIND_DATA_PORT_IPV4,
CONNECT_STEP_ENABLE_INDICATIONS_IPV4,
+#if QMI_QRTR_SUPPORTED //TODO(crbug.com/1103840): Remove hacks before merging to upstream
+ CONNECT_STEP_BIND_MUX_DATA_PORT_IPV4,
+#endif
CONNECT_STEP_START_NETWORK_IPV4,
CONNECT_STEP_GET_CURRENT_SETTINGS_IPV4,
CONNECT_STEP_IPV6,
@@ -419,6 +422,9 @@
CONNECT_STEP_IP_FAMILY_IPV6,
CONNECT_STEP_BIND_DATA_PORT_IPV6,
CONNECT_STEP_ENABLE_INDICATIONS_IPV6,
+#if QMI_QRTR_SUPPORTED //TODO(crbug.com/1103840): Remove hacks before merging to upstream
+ CONNECT_STEP_BIND_MUX_DATA_PORT_IPV6,
+#endif
CONNECT_STEP_START_NETWORK_IPV6,
CONNECT_STEP_GET_CURRENT_SETTINGS_IPV6,
CONNECT_STEP_LAST
@@ -553,6 +559,53 @@
static void connect_context_step (GTask *task);
+#if QMI_QRTR_SUPPORTED //TODO(crbug.com/1103840): Remove hacks before merging to upstream
+static void bind_mux_data_port_ready (QmiClientWds *client,
+ GAsyncResult *res,
+ GTask *task)
+{
+ MMBearerQmi *self;
+ ConnectContext *ctx;
+ GError *error = NULL;
+ QmiMessageWdsBindMuxDataPortOutput *output;
+
+ self = g_task_get_task_data (task);
+ ctx = g_task_get_task_data (task);
+ g_assert (ctx->running_ipv4 || ctx->running_ipv6);
+ g_assert (!(ctx->running_ipv4 && ctx->running_ipv6));
+
+ output = qmi_client_wds_bind_mux_data_port_finish (client, res, &error);
+ if (!output ||
+ !qmi_message_wds_bind_mux_data_port_output_get_result (output, &error)) {
+ mm_obj_info (self, "error: couldn't bind mux data port: %s\n", error->message);
+
+ if (ctx->running_ipv4)
+ ctx->error_ipv4 = error;
+ else
+ ctx->error_ipv6 = error;
+
+ ctx->step = CONNECT_STEP_LAST;
+ } else
+ ctx->step++;
+
+ if (output)
+ qmi_message_wds_bind_mux_data_port_output_unref (output);
+
+ connect_context_step (task);
+}
+
+static QmiMessageWdsBindMuxDataPortInput *
+build_bind_mux_data_port_input (void)
+{
+ QmiMessageWdsBindMuxDataPortInput *input;
+
+ input = qmi_message_wds_bind_mux_data_port_input_new ();
+ qmi_message_wds_bind_mux_data_port_input_set_endpoint_info (input, 0x4, 0x1, NULL);
+ qmi_message_wds_bind_mux_data_port_input_set_mux_id (input, 0x1, NULL);
+ return input;
+}
+#endif
+
static void
start_network_ready (QmiClientWds *client,
GAsyncResult *res,
@@ -1364,10 +1417,14 @@
* to request. If the LLP is raw-ip, we force Static IP, because not
* all DHCP clients support the raw-ip interfaces; otherwise default
* to DHCP as always. */
+#if QMI_QRTR_SUPPORTED //TODO(crbug.com/1103840): Remove hacks before merging to upstream
+ ctx->ip_method = MM_BEARER_IP_METHOD_STATIC;
+#else
if (mm_port_qmi_llp_is_raw_ip (ctx->qmi))
ctx->ip_method = MM_BEARER_IP_METHOD_STATIC;
else
ctx->ip_method = MM_BEARER_IP_METHOD_DHCP;
+#endif
mm_obj_dbg (self, "defaulting to use %s IP method", mm_bearer_ip_method_get_string (ctx->ip_method));
ctx->step++;
@@ -1462,6 +1519,24 @@
task);
return;
+#if QMI_QRTR_SUPPORTED //TODO(crbug.com/1103840): Remove hacks before merging to upstream
+ case CONNECT_STEP_BIND_MUX_DATA_PORT_IPV4: {
+ QmiMessageWdsBindMuxDataPortInput *input;
+
+ mm_obj_dbg (ctx->self, "Binding mux data port for IPv4...");
+
+ input = build_bind_mux_data_port_input ();
+ qmi_client_wds_bind_mux_data_port (ctx->client_ipv4,
+ input,
+ 10,
+ g_task_get_cancellable (task),
+ (GAsyncReadyCallback) bind_mux_data_port_ready,
+ task);
+ qmi_message_wds_bind_mux_data_port_input_unref (input);
+ return;
+ }
+#endif
+
case CONNECT_STEP_START_NETWORK_IPV4: {
QmiMessageWdsStartNetworkInput *input;
@@ -1573,6 +1648,24 @@
task);
return;
+#if QMI_QRTR_SUPPORTED //TODO(crbug.com/1103840): Remove hacks before merging to upstream
+ case CONNECT_STEP_BIND_MUX_DATA_PORT_IPV6: {
+ QmiMessageWdsBindMuxDataPortInput *input;
+
+ mm_obj_dbg (self, "Binding mux data port for IPv6...");
+
+ input = build_bind_mux_data_port_input ();
+ qmi_client_wds_bind_mux_data_port (ctx->client_ipv6,
+ input,
+ 10,
+ g_task_get_cancellable (task),
+ (GAsyncReadyCallback) bind_mux_data_port_ready,
+ task);
+ qmi_message_wds_bind_mux_data_port_input_unref (input);
+ return;
+ }
+#endif
+
case CONNECT_STEP_START_NETWORK_IPV6: {
QmiMessageWdsStartNetworkInput *input;
@@ -1712,7 +1805,13 @@
}
/* Each data port has a single QMI port associated */
+
+#if QMI_QRTR_SUPPORTED //TODO(crbug.com/1103840): Remove hacks before merging to upstream
+ qmi = mm_broadband_modem_qmi_get_port_qmi (MM_BROADBAND_MODEM_QMI (modem));
+#else
qmi = mm_broadband_modem_qmi_get_port_qmi_for_data (MM_BROADBAND_MODEM_QMI (modem), data, &sio_port, &error);
+#endif
+
if (!qmi) {
g_task_report_error (
self,
diff --git a/src/mm-broadband-modem-mbim.c b/src/mm-broadband-modem-mbim.c
index 4ee5b22..c524af4 100644
--- a/src/mm-broadband-modem-mbim.c
+++ b/src/mm-broadband-modem-mbim.c
@@ -84,6 +84,7 @@
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
@@ -3307,6 +3308,30 @@
update_access_technologies (self);
}
+static void
+basic_connect_notification_provisioned_contexts (MMBroadbandModemMbim *self,
+ MbimMessage *notification)
+{
+ MbimProvisionedContextElement **provisioned_contexts;
+ guint32 n_provisioned_contexts;
+ GList *profiles;
+
+ if (!mbim_message_provisioned_contexts_notification_parse (
+ notification,
+ &n_provisioned_contexts,
+ &provisioned_contexts,
+ NULL)) {
+ return;
+ }
+
+ profiles = mm_3gpp_profile_list_from_mbim_provisioned_contexts (
+ (const MbimProvisionedContextElement *const *)provisioned_contexts,
+ n_provisioned_contexts);
+ mbim_provisioned_context_element_array_free (provisioned_contexts);
+
+ mm_iface_modem_3gpp_update_profiles (MM_IFACE_MODEM_3GPP (self), profiles);
+}
+
static void add_sms_part (MMBroadbandModemMbim *self,
const MbimSmsPduReadRecord *pdu);
@@ -3362,6 +3387,10 @@
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);
+ break;
default:
/* Ignore */
break;
@@ -3627,7 +3656,7 @@
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",
@@ -3636,7 +3665,8 @@
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 */
@@ -3705,6 +3735,7 @@
self->priv->setup_flags &= ~PROCESS_NOTIFICATION_FLAG_SIGNAL_QUALITY;
self->priv->setup_flags &= ~PROCESS_NOTIFICATION_FLAG_CONNECT;
self->priv->setup_flags &= ~PROCESS_NOTIFICATION_FLAG_PACKET_SERVICE;
+ self->priv->setup_flags &= ~PROCESS_NOTIFICATION_FLAG_PROVISIONED_CONTEXTS;
if (self->priv->is_pco_supported)
self->priv->setup_flags &= ~PROCESS_NOTIFICATION_FLAG_PCO;
if (self->priv->is_lte_attach_status_supported)
@@ -3723,6 +3754,7 @@
self->priv->setup_flags |= PROCESS_NOTIFICATION_FLAG_CONNECT;
self->priv->setup_flags |= PROCESS_NOTIFICATION_FLAG_SUBSCRIBER_INFO;
self->priv->setup_flags |= PROCESS_NOTIFICATION_FLAG_PACKET_SERVICE;
+ self->priv->setup_flags |= PROCESS_NOTIFICATION_FLAG_PROVISIONED_CONTEXTS;
if (self->priv->is_pco_supported)
self->priv->setup_flags |= PROCESS_NOTIFICATION_FLAG_PCO;
if (self->priv->is_lte_attach_status_supported)
@@ -3801,7 +3833,7 @@
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",
@@ -3810,7 +3842,8 @@
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);
@@ -3819,11 +3852,12 @@
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)
@@ -3834,6 +3868,8 @@
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++;
}
@@ -4079,6 +4115,7 @@
if (is_sim_hot_swap_configured)
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_PROVISIONED_CONTEXTS;
if (self->priv->is_pco_supported)
self->priv->enable_flags &= ~PROCESS_NOTIFICATION_FLAG_PCO;
if (self->priv->is_lte_attach_status_supported)
@@ -4097,6 +4134,7 @@
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_PROVISIONED_CONTEXTS;
if (self->priv->is_pco_supported)
self->priv->enable_flags |= PROCESS_NOTIFICATION_FLAG_PCO;
if (self->priv->is_lte_attach_status_supported)
@@ -4487,6 +4525,86 @@
}
/*****************************************************************************/
+/* Load profiles (3GPP interface) */
+
+static gboolean
+modem_3gpp_load_profiles_finish (MMIfaceModem3gpp *self,
+ GAsyncResult *res,
+ GList **out_list,
+ GError **error)
+{
+ GTask *task;
+
+ task = G_TASK (res);
+ if (!g_task_propagate_boolean (task, error))
+ return FALSE;
+
+ if (out_list)
+ *out_list = mm_3gpp_profile_list_copy (g_task_get_task_data (task));
+ return TRUE;
+}
+
+static void
+provisioned_contexts_ready (MbimDevice *device,
+ GAsyncResult *res,
+ GTask *task)
+{
+ MbimMessage *response;
+ MbimProvisionedContextElement **provisioned_contexts;
+ guint32 n_provisioned_contexts;
+ GError *error = NULL;
+
+ 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,
+ &n_provisioned_contexts,
+ &provisioned_contexts,
+ &error)) {
+ GList *profiles;
+
+ profiles = mm_3gpp_profile_list_from_mbim_provisioned_contexts (
+ (const MbimProvisionedContextElement *const *)provisioned_contexts,
+ n_provisioned_contexts);
+ mbim_provisioned_context_element_array_free (provisioned_contexts);
+
+ g_task_set_task_data (task, profiles, (GDestroyNotify)mm_3gpp_profile_list_free);
+ g_task_return_boolean (task, TRUE);
+ } else
+ g_task_return_error (task, error);
+
+ g_object_unref (task);
+
+ if (response)
+ mbim_message_unref (response);
+}
+
+static void
+modem_3gpp_load_profiles (MMIfaceModem3gpp *self,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ MbimDevice *device;
+ MbimMessage *message;
+ GTask *task;
+
+ if (!peek_device (self, &device, callback, user_data))
+ return;
+
+ task = g_task_new (self, NULL, callback, user_data);
+
+ mm_obj_dbg (self, "loading provisioned contexts...");
+ message = mbim_message_provisioned_contexts_query_new (NULL);
+ mbim_device_command (device,
+ message,
+ 300,
+ NULL,
+ (GAsyncReadyCallback)provisioned_contexts_ready,
+ task);
+ mbim_message_unref (message);
+}
+
+/*****************************************************************************/
/* Check support (Signal interface) */
static gboolean
@@ -5767,6 +5885,8 @@
iface->register_in_network_finish = modem_3gpp_register_in_network_finish;
iface->scan_networks = modem_3gpp_scan_networks;
iface->scan_networks_finish = modem_3gpp_scan_networks_finish;
+ iface->load_profiles = modem_3gpp_load_profiles;
+ iface->load_profiles_finish = modem_3gpp_load_profiles_finish;
}
static void
diff --git a/src/mm-broadband-modem-qmi.c b/src/mm-broadband-modem-qmi.c
index 3a45213..f51146e 100644
--- a/src/mm-broadband-modem-qmi.c
+++ b/src/mm-broadband-modem-qmi.c
@@ -101,6 +101,10 @@
/* Index of the WDS profile used as initial EPS bearer */
guint16 default_attach_pdn;
+ /* The WDS profile for the initial EPS bearer is owned by ModemManager
+ * and can be modified */
+ gboolean mm_owned_attach_pdn;
+
/* 3GPP/CDMA registration helpers */
gchar *current_operator_id;
gchar *current_operator_description;
@@ -2575,6 +2579,223 @@
}
/*****************************************************************************/
+/* Load profiles (3GPP interface) */
+
+typedef struct {
+ QmiClientWds *client;
+ guint i;
+ GArray *profile_ids;
+ GList *profiles;
+} GetProfileListContext;
+
+static void
+get_profile_list_context_free (GetProfileListContext *ctx)
+{
+ g_object_unref (ctx->client);
+ g_array_unref (ctx->profile_ids);
+ g_list_free_full (ctx->profiles, (GDestroyNotify) qmi_message_wds_get_profile_settings_output_unref);
+ g_slice_free (GetProfileListContext, ctx);
+}
+
+static gboolean
+modem_3gpp_load_profiles_finish (MMIfaceModem3gpp *self,
+ GAsyncResult *res,
+ GList **out_list,
+ GError **error)
+{
+ GTask *task;
+
+ task = G_TASK (res);
+ if (!g_task_propagate_boolean (task, error))
+ return FALSE;
+
+ if (out_list)
+ *out_list = mm_3gpp_profile_list_copy (g_task_get_task_data (task));
+ return TRUE;
+}
+
+static void get_next_profile_settings (GTask *task);
+
+static void
+get_profile_settings_ready (QmiClientWds *client,
+ GAsyncResult *res,
+ GTask *task)
+{
+ GetProfileListContext *ctx;
+ QmiMessageWdsGetProfileSettingsOutput *output;
+ GError *error = NULL;
+
+ ctx = g_task_get_task_data (task);
+
+ output = qmi_client_wds_get_profile_settings_finish (client, res, &error);
+ if (!output) {
+ g_task_return_error (task, error);
+ g_object_unref (task);
+ return;
+ }
+
+ if (!qmi_message_wds_get_profile_settings_output_get_result (output, &error)) {
+ QmiWdsDsProfileError ds_profile_error;
+
+ if (g_error_matches (error,
+ QMI_PROTOCOL_ERROR,
+ QMI_PROTOCOL_ERROR_EXTENDED_INTERNAL) &&
+ qmi_message_wds_get_profile_settings_output_get_extended_error_code (
+ output,
+ &ds_profile_error,
+ NULL)) {
+ g_task_return_new_error (task,
+ QMI_PROTOCOL_ERROR,
+ QMI_PROTOCOL_ERROR_EXTENDED_INTERNAL,
+ "DS profile error: %s\n",
+ qmi_wds_ds_profile_error_get_string (ds_profile_error));
+ g_error_free (error);
+ } else {
+ g_task_return_error (task, error);
+ }
+
+ qmi_message_wds_get_profile_settings_output_unref (output);
+ g_object_unref (task);
+ return;
+ }
+
+ ctx->profiles = g_list_prepend (ctx->profiles, output);
+ ctx->i++;
+ get_next_profile_settings (task);
+}
+
+static void
+get_next_profile_settings (GTask *task)
+{
+ QmiMessageWdsGetProfileListOutputProfileListProfile *profile;
+ QmiMessageWdsGetProfileSettingsInput *input;
+ GetProfileListContext *ctx;
+
+ ctx = g_task_get_task_data (task);
+
+ if (ctx->i == ctx->profile_ids->len) {
+ g_task_set_task_data (task,
+ mm_3gpp_profile_list_from_qmi_profile_settings (ctx->profiles),
+ (GDestroyNotify) mm_3gpp_profile_list_free);
+ g_task_return_boolean (task, TRUE);
+ g_object_unref (task);
+ return;
+ }
+
+ profile = &g_array_index (ctx->profile_ids, QmiMessageWdsGetProfileListOutputProfileListProfile, ctx->i);
+
+ input = qmi_message_wds_get_profile_settings_input_new ();
+ qmi_message_wds_get_profile_settings_input_set_profile_id (
+ input,
+ profile->profile_type,
+ profile->profile_index,
+ NULL);
+ qmi_client_wds_get_profile_settings (ctx->client,
+ input,
+ 3,
+ NULL,
+ (GAsyncReadyCallback)get_profile_settings_ready,
+ task);
+ qmi_message_wds_get_profile_settings_input_unref (input);
+}
+
+static void
+get_profile_list_ready (QmiClientWds *client,
+ GAsyncResult *res,
+ GTask *task)
+{
+ GError *error = NULL;
+ QmiMessageWdsGetProfileListOutput *output;
+ GetProfileListContext *ctx;
+ GArray *profile_ids = NULL;
+
+ ctx = g_task_get_task_data (task);
+
+ output = qmi_client_wds_get_profile_list_finish (client, res, &error);
+ if (!output) {
+ g_task_return_error (task, error);
+ g_object_unref (task);
+ return;
+ }
+
+ if (!qmi_message_wds_get_profile_list_output_get_result (output, &error)) {
+ QmiWdsDsProfileError ds_profile_error;
+
+ if (g_error_matches (error,
+ QMI_PROTOCOL_ERROR,
+ QMI_PROTOCOL_ERROR_EXTENDED_INTERNAL) &&
+ qmi_message_wds_get_profile_list_output_get_extended_error_code (
+ output,
+ &ds_profile_error,
+ NULL)) {
+ g_task_return_new_error (task,
+ QMI_PROTOCOL_ERROR,
+ QMI_PROTOCOL_ERROR_EXTENDED_INTERNAL,
+ "DS profile error: %s\n",
+ qmi_wds_ds_profile_error_get_string (ds_profile_error));
+ g_error_free (error);
+ } else {
+ g_task_return_error (task, error);
+ }
+
+ qmi_message_wds_get_profile_list_output_unref (output);
+ g_object_unref (task);
+ return;
+ }
+
+ qmi_message_wds_get_profile_list_output_get_profile_list (output, &profile_ids, NULL);
+
+ if (!profile_ids || !profile_ids->len) {
+ /* No profiles to get details for. */
+ g_task_return_pointer (task, NULL, NULL);
+ g_object_unref (task);
+ return;
+ }
+
+ ctx->profile_ids = profile_ids;
+
+ get_next_profile_settings (task);
+}
+
+static void
+modem_3gpp_load_profiles (MMIfaceModem3gpp *_self,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ MMBroadbandModemQmi *self = MM_BROADBAND_MODEM_QMI (_self);
+ GTask *task;
+ QmiClient *client;
+ GetProfileListContext *ctx;
+ QmiMessageWdsGetProfileListInput *input;
+ GError *error = NULL;
+
+ task = g_task_new (self, NULL, callback, user_data);
+ client = mm_shared_qmi_peek_client (MM_SHARED_QMI (self),
+ QMI_SERVICE_WDS,
+ MM_PORT_QMI_FLAG_DEFAULT,
+ &error);
+ if (!client) {
+ g_task_return_error (task, error);
+ g_object_unref (task);
+ }
+
+ ctx = g_slice_new0 (GetProfileListContext);
+ ctx->client = g_object_ref (QMI_CLIENT_WDS (client));
+ g_task_set_task_data (task, ctx, (GDestroyNotify) get_profile_list_context_free);
+
+ input = qmi_message_wds_get_profile_list_input_new ();
+ qmi_message_wds_get_profile_list_input_set_profile_type (input, QMI_WDS_PROFILE_TYPE_3GPP, NULL);
+
+ qmi_client_wds_get_profile_list (ctx->client,
+ input,
+ 10,
+ NULL,
+ (GAsyncReadyCallback) get_profile_list_ready,
+ task);
+ qmi_message_wds_get_profile_list_input_unref (input);
+}
+
+/*****************************************************************************/
/* Registration checks (3GPP interface) */
static gboolean
@@ -7878,6 +8099,7 @@
SET_INITIAL_EPS_BEARER_SETTINGS_STEP_FIRST,
SET_INITIAL_EPS_BEARER_SETTINGS_STEP_LOAD_POWER_STATE,
SET_INITIAL_EPS_BEARER_SETTINGS_STEP_POWER_DOWN,
+ SET_INITIAL_EPS_BEARER_SETTINGS_STEP_CREATE_PROFILE,
SET_INITIAL_EPS_BEARER_SETTINGS_STEP_MODIFY_PROFILE,
SET_INITIAL_EPS_BEARER_SETTINGS_STEP_POWER_UP,
SET_INITIAL_EPS_BEARER_SETTINGS_STEP_LAST_SETTING,
@@ -7930,14 +8152,82 @@
}
static void
+set_initial_eps_bearer_set_lte_attach_pdn_ready (QmiClientWds *client,
+ GAsyncResult *res,
+ GTask *task)
+{
+ g_autoptr(QmiMessageWdsSetLteAttachPdnListOutput) output = NULL;
+ GError *error = NULL;
+ MMBroadbandModemQmi *self;
+ SetInitialEpsBearerSettingsContext *ctx;
+
+ self = g_task_get_source_object (task);
+ ctx = g_task_get_task_data (task);
+
+ output = qmi_client_wds_set_lte_attach_pdn_list_finish (client, res, &error);
+ if (!output) {
+ g_prefix_error (&error, "QMI operation failed: ");
+ g_task_return_error (task, error);
+ g_object_unref (task);
+ return;
+ }
+
+ if (!qmi_message_wds_set_lte_attach_pdn_list_output_get_result (output, &error)) {
+ g_prefix_error (&error, "Couldn't set the LTE attach PDN list: ");
+ g_task_return_error (task, error);
+ g_object_unref (task);
+ return;
+ }
+
+ self->priv->mm_owned_attach_pdn = TRUE;
+
+ ctx->step++;
+ set_initial_eps_bearer_settings_step (task);
+}
+
+static void
+set_initial_eps_bearer_set_lte_attach_pdn (GTask *task)
+{
+ g_autoptr(QmiMessageWdsSetLteAttachPdnListInput) input = NULL;
+ MMBroadbandModemQmi *self;
+ SetInitialEpsBearerSettingsContext *ctx;
+ GArray *pdn_list;
+
+ self = g_task_get_source_object (task);
+ ctx = g_task_get_task_data (task);
+
+ pdn_list = g_array_sized_new (FALSE, FALSE, sizeof (guint16), 1);
+ g_array_append_val (pdn_list, self->priv->default_attach_pdn);
+ //TODO re-add the list from wds_get_lte_attach_pdn_list ?
+
+ input = qmi_message_wds_set_lte_attach_pdn_list_input_new ();
+ qmi_message_wds_set_lte_attach_pdn_list_input_set_list (input,
+ pdn_list,
+ NULL);
+ g_array_unref (pdn_list);
+ qmi_message_wds_set_lte_attach_pdn_list_input_set_action (input,
+ QMI_WDS_ATTACH_PDN_LIST_ACTION_DETACH_OR_PDN_DISCONNECT,
+ NULL);
+
+ qmi_client_wds_set_lte_attach_pdn_list (ctx->client,
+ input,
+ 10,
+ NULL,
+ (GAsyncReadyCallback)set_initial_eps_bearer_set_lte_attach_pdn_ready,
+ task);
+}
+
+static void
set_initial_eps_bearer_modify_profile_ready (QmiClientWds *client,
GAsyncResult *res,
GTask *task)
{
g_autoptr(QmiMessageWdsModifyProfileOutput) output = NULL;
GError *error = NULL;
+ MMBroadbandModemQmi *self;
SetInitialEpsBearerSettingsContext *ctx;
+ self = g_task_get_source_object (task);
ctx = g_task_get_task_data (task);
output = qmi_client_wds_modify_profile_finish (client, res, &error);
@@ -7962,6 +8252,11 @@
return;
}
+ if (!self->priv->mm_owned_attach_pdn) {
+ set_initial_eps_bearer_set_lte_attach_pdn (task);
+ return;
+ }
+
ctx->step++;
set_initial_eps_bearer_settings_step (task);
}
@@ -8017,6 +8312,74 @@
}
static void
+set_initial_eps_bearer_create_profile_ready (QmiClientWds *client,
+ GAsyncResult *res,
+ GTask *task)
+{
+ g_autoptr(QmiMessageWdsCreateProfileOutput) output = NULL;
+ GError *error = NULL;
+ MMBroadbandModemQmi *self;
+ SetInitialEpsBearerSettingsContext *ctx;
+ QmiWdsProfileType profile_type;
+ guint8 index;
+
+ self = g_task_get_source_object (task);
+ ctx = g_task_get_task_data (task);
+
+ output = qmi_client_wds_create_profile_finish (client, res, &error);
+ if (!output) {
+ g_prefix_error (&error, "QMI operation failed: ");
+ g_task_return_error (task, error);
+ g_object_unref (task);
+ return;
+ }
+
+ if (!qmi_message_wds_create_profile_output_get_result (output, &error)) {
+ QmiWdsDsProfileError ds_profile_error;
+
+ if (g_error_matches (error, QMI_PROTOCOL_ERROR, QMI_PROTOCOL_ERROR_EXTENDED_INTERNAL) &&
+ qmi_message_wds_create_profile_output_get_extended_error_code (output, &ds_profile_error, NULL)) {
+ g_prefix_error (&error, "DS profile error: %s: ",
+ qmi_wds_ds_profile_error_get_string (ds_profile_error));
+ }
+ g_prefix_error (&error, "Couldn't create a new profile: ");
+ g_task_return_error (task, error);
+ g_object_unref (task);
+ return;
+ }
+
+ if (qmi_message_wds_create_profile_output_get_profile_identifier (output, &profile_type, &index, NULL))
+ self->priv->default_attach_pdn = index;
+
+ ctx->step++;
+ set_initial_eps_bearer_settings_step (task);
+}
+
+static void
+set_initial_eps_bearer_create_profile (GTask *task)
+{
+ g_autoptr(QmiMessageWdsCreateProfileInput) input = NULL;
+ SetInitialEpsBearerSettingsContext *ctx;
+
+ ctx = g_task_get_task_data (task);
+
+ input = qmi_message_wds_create_profile_input_new ();
+ qmi_message_wds_create_profile_input_set_profile_type (input,
+ QMI_WDS_PROFILE_TYPE_3GPP,
+ NULL);
+ qmi_message_wds_create_profile_input_set_profile_name (input,
+ MM_BROADBAND_MODEM_QMI_PROFILE_NAME,
+ NULL);
+
+ qmi_client_wds_create_profile (ctx->client,
+ input,
+ 10,
+ NULL,
+ (GAsyncReadyCallback)set_initial_eps_bearer_create_profile_ready,
+ task);
+}
+
+static void
set_initial_eps_bearer_power_down_ready (MMIfaceModem *self,
GAsyncResult *res,
GTask *task)
@@ -8088,8 +8451,18 @@
task);
return;
}
- ctx->step++;
- /* fall through */
+ if (self->priv->mm_owned_attach_pdn) {
+ ctx->step = SET_INITIAL_EPS_BEARER_SETTINGS_STEP_MODIFY_PROFILE;
+ set_initial_eps_bearer_settings_step (task);
+ return;
+ } else {
+ ctx->step++;
+ /* fall through */
+ }
+ case SET_INITIAL_EPS_BEARER_SETTINGS_STEP_CREATE_PROFILE:
+ mm_obj_dbg (self, "creating a profile for initial EPS bearer settings...");
+ set_initial_eps_bearer_create_profile (task);
+ return;
case SET_INITIAL_EPS_BEARER_SETTINGS_STEP_MODIFY_PROFILE:
mm_obj_dbg (self, "modifying initial EPS bearer settings profile...");
@@ -8173,6 +8546,9 @@
QmiWdsAuthentication auth;
gboolean flag;
MMBearerProperties *properties;
+ MMBroadbandModemQmi *self;
+
+ self = g_task_get_source_object (task);
output = qmi_client_wds_get_profile_settings_finish (client, res, &error);
if (!output) {
@@ -8196,6 +8572,12 @@
return;
}
+ self->priv->mm_owned_attach_pdn = FALSE;
+ if (qmi_message_wds_get_profile_settings_output_get_profile_name (output, &str, NULL)) {
+ if (g_strcmp0(str, MM_BROADBAND_MODEM_QMI_PROFILE_NAME) == 0)
+ self->priv->mm_owned_attach_pdn = TRUE;
+ }
+
properties = mm_bearer_properties_new ();
if (qmi_message_wds_get_profile_settings_output_get_apn_name (output, &str, NULL))
mm_bearer_properties_set_apn (properties, str);
@@ -10231,6 +10613,8 @@
iface->load_initial_eps_bearer_settings_finish = modem_3gpp_load_initial_eps_bearer_settings_finish;
iface->set_initial_eps_bearer_settings = modem_3gpp_set_initial_eps_bearer_settings;
iface->set_initial_eps_bearer_settings_finish = modem_3gpp_set_initial_eps_bearer_settings_finish;
+ iface->load_profiles = modem_3gpp_load_profiles;
+ iface->load_profiles_finish = modem_3gpp_load_profiles_finish;
}
static void
diff --git a/src/mm-broadband-modem-qmi.h b/src/mm-broadband-modem-qmi.h
index 9b71210..da794b6 100644
--- a/src/mm-broadband-modem-qmi.h
+++ b/src/mm-broadband-modem-qmi.h
@@ -25,6 +25,9 @@
#define MM_IS_BROADBAND_MODEM_QMI_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MM_TYPE_BROADBAND_MODEM_QMI))
#define MM_BROADBAND_MODEM_QMI_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MM_TYPE_BROADBAND_MODEM_QMI, MMBroadbandModemQmiClass))
+/* Chromium OS specific profile */
+#define MM_BROADBAND_MODEM_QMI_PROFILE_NAME "CrOS_attach_PDN"
+
typedef struct _MMBroadbandModemQmi MMBroadbandModemQmi;
typedef struct _MMBroadbandModemQmiClass MMBroadbandModemQmiClass;
typedef struct _MMBroadbandModemQmiPrivate MMBroadbandModemQmiPrivate;
diff --git a/src/mm-iface-modem-3gpp.c b/src/mm-iface-modem-3gpp.c
index 9389935..ec46adc 100644
--- a/src/mm-iface-modem-3gpp.c
+++ b/src/mm-iface-modem-3gpp.c
@@ -1829,6 +1829,62 @@
/*****************************************************************************/
+static GVariant *
+profiles_build_result (const GList *profiles)
+{
+ const GList *l;
+ GVariantBuilder builder;
+
+ g_variant_builder_init (&builder, G_VARIANT_TYPE ("aa{sv}"));
+
+ for (l = profiles; l; l = g_list_next (l)) {
+ const MM3gppProfile *profile = l->data;
+
+ g_variant_builder_open (&builder, G_VARIANT_TYPE ("a{sv}"));
+
+ g_variant_builder_add (&builder, "{sv}",
+ "profile-id", g_variant_new_uint32 (profile->profile_id));
+ if (profile->apn) {
+ g_variant_builder_add (&builder, "{sv}",
+ "apn", g_variant_new_string (profile->apn));
+ } else {
+ g_variant_builder_add (&builder, "{sv}", "apn", g_variant_new_string (""));
+ }
+ g_variant_builder_add (&builder, "{sv}",
+ "auth-type", g_variant_new_uint32 (profile->auth_type));
+ if (profile->username)
+ g_variant_builder_add (&builder, "{sv}",
+ "username", g_variant_new_string (profile->username));
+ if (profile->password)
+ g_variant_builder_add (&builder, "{sv}",
+ "password", g_variant_new_string (profile->password));
+ g_variant_builder_close (&builder);
+ }
+
+ return g_variant_ref_sink (g_variant_builder_end (&builder));
+}
+
+void
+mm_iface_modem_3gpp_update_profiles (MMIfaceModem3gpp *self,
+ const GList *profiles)
+{
+ MmGdbusModem3gpp *skeleton = NULL;
+ GVariant *variant;
+
+ g_object_get (self,
+ MM_IFACE_MODEM_3GPP_DBUS_SKELETON, &skeleton,
+ NULL);
+ if (!skeleton)
+ return;
+
+ variant = profiles_build_result (profiles);
+ mm_gdbus_modem3gpp_set_profiles (skeleton, variant);
+ g_variant_unref (variant);
+ g_object_unref (skeleton);
+}
+
+/*****************************************************************************/
+
typedef struct _DisablingContext DisablingContext;
static void interface_disabling_step (GTask *task);
@@ -2043,6 +2099,7 @@
ENABLING_STEP_SETUP_UNSOLICITED_REGISTRATION_EVENTS,
ENABLING_STEP_ENABLE_UNSOLICITED_REGISTRATION_EVENTS,
ENABLING_STEP_INITIAL_EPS_BEARER,
+ ENABLING_STEP_LOAD_PROFILES,
ENABLING_STEP_LAST
} EnablingStep;
@@ -2197,6 +2254,34 @@
}
static void
+load_profiles_ready (MMIfaceModem3gpp *self,
+ GAsyncResult *res,
+ GTask *task)
+{
+ gboolean success;
+ GList *profiles = NULL;
+ EnablingContext *ctx;
+ GError *error = NULL;
+
+ ctx = g_task_get_task_data (task);
+
+ success = MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->load_profiles_finish (self, res, &profiles, &error);
+ if (!success) {
+ mm_obj_dbg (self, "couldn't load initial profiles: '%s'", error->message);
+ g_error_free (error);
+ goto out;
+ }
+
+ mm_iface_modem_3gpp_update_profiles (self, profiles);
+ mm_3gpp_profile_list_free (profiles);
+
+out:
+ /* Go on to next step */
+ ctx->step++;
+ interface_enabling_step (task);
+}
+
+static void
interface_enabling_step (GTask *task)
{
MMIfaceModem3gpp *self;
@@ -2296,6 +2381,18 @@
ctx->step++;
} /* fall through */
+ case ENABLING_STEP_LOAD_PROFILES:
+ if (MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->load_profiles &&
+ MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->load_profiles_finish) {
+ MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->load_profiles (
+ self,
+ (GAsyncReadyCallback)load_profiles_ready,
+ task);
+ return;
+ }
+ /* Fall down to next step */
+ ctx->step++;
+
case ENABLING_STEP_LAST:
/* We are done without errors! */
g_task_return_boolean (task, TRUE);
@@ -2640,6 +2737,7 @@
mm_gdbus_modem3gpp_set_subscription_state (skeleton, MM_MODEM_3GPP_SUBSCRIPTION_STATE_UNKNOWN);
mm_gdbus_modem3gpp_set_pco (skeleton, NULL);
mm_gdbus_modem3gpp_set_initial_eps_bearer (skeleton, NULL);
+ mm_gdbus_modem3gpp_set_profiles (skeleton, NULL);
/* Bind our RegistrationState property */
g_object_bind_property (self, MM_IFACE_MODEM_3GPP_REGISTRATION_STATE,
diff --git a/src/mm-iface-modem-3gpp.h b/src/mm-iface-modem-3gpp.h
index 258e5c1..4982029 100644
--- a/src/mm-iface-modem-3gpp.h
+++ b/src/mm-iface-modem-3gpp.h
@@ -234,6 +234,15 @@
gboolean (* set_initial_eps_bearer_settings_finish) (MMIfaceModem3gpp *self,
GAsyncResult *res,
GError **error);
+
+ /* Get profiles or provisioned contexts from the modem as a list of MM3gppProfile */
+ void (* load_profiles) (MMIfaceModem3gpp *self,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+ gboolean (* load_profiles_finish) (MMIfaceModem3gpp *self,
+ GAsyncResult *res,
+ GList **out_list,
+ GError **error);
};
GType mm_iface_modem_3gpp_get_type (void);
@@ -293,6 +302,8 @@
void mm_iface_modem_3gpp_update_initial_eps_bearer (MMIfaceModem3gpp *self,
MMBearerProperties *properties);
void mm_iface_modem_3gpp_reload_initial_eps_bearer (MMIfaceModem3gpp *self);
+void mm_iface_modem_3gpp_update_profiles (MMIfaceModem3gpp *self,
+ const GList *profiles);
/* Run all registration checks */
void mm_iface_modem_3gpp_run_registration_checks (MMIfaceModem3gpp *self,
diff --git a/src/mm-modem-helpers-mbim.c b/src/mm-modem-helpers-mbim.c
index e418969..b70f379 100644
--- a/src/mm-modem-helpers-mbim.c
+++ b/src/mm-modem-helpers-mbim.c
@@ -207,6 +207,33 @@
/*****************************************************************************/
+GList *
+mm_3gpp_profile_list_from_mbim_provisioned_contexts (
+ const MbimProvisionedContextElement *const *contexts,
+ guint n_contexts)
+{
+ GList *profiles = NULL;
+ guint i;
+
+ for (i = 0; i < n_contexts; i++) {
+ MM3gppProfile *profile;
+
+ profile = g_slice_new0 (MM3gppProfile);
+ profile->profile_id = contexts[i]->context_id;
+ profile->apn = g_strdup (contexts[i]->access_string);
+ profile->username = g_strdup (contexts[i]->user_name);
+ profile->password = g_strdup (contexts[i]->password);
+ profile->auth_type =
+ mm_bearer_allowed_auth_from_mbim_auth_protocol (contexts[i]->auth_protocol);
+
+ profiles = g_list_prepend (profiles, profile);
+ }
+
+ return profiles;
+}
+
+/*****************************************************************************/
+
GError *
mm_mobile_equipment_error_from_mbim_nw_error (MbimNwError nw_error)
{
diff --git a/src/mm-modem-helpers-mbim.h b/src/mm-modem-helpers-mbim.h
index 9cebe95..02c4e6b 100644
--- a/src/mm-modem-helpers-mbim.h
+++ b/src/mm-modem-helpers-mbim.h
@@ -38,6 +38,9 @@
GList *mm_3gpp_network_info_list_from_mbim_providers (const MbimProvider *const *providers, guint n_providers);
+GList *mm_3gpp_profile_list_from_mbim_provisioned_contexts (const MbimProvisionedContextElement *const *contexts,
+ guint n_contexts);
+
GError *mm_mobile_equipment_error_from_mbim_nw_error (MbimNwError nw_error);
MMBearerAllowedAuth mm_bearer_allowed_auth_from_mbim_auth_protocol (MbimAuthProtocol auth_protocol);
diff --git a/src/mm-modem-helpers-qmi.c b/src/mm-modem-helpers-qmi.c
index e4bc7e2..6ab0adf 100644
--- a/src/mm-modem-helpers-qmi.c
+++ b/src/mm-modem-helpers-qmi.c
@@ -1540,6 +1540,40 @@
/*****************************************************************************/
+GList *
+mm_3gpp_profile_list_from_qmi_profile_settings (GList *profiles)
+{
+ GList *mm_profiles = NULL;
+ GList *iter;
+
+ for (iter = profiles; iter; iter = g_list_next (iter)) {
+ QmiMessageWdsGetProfileSettingsOutput *wds_profile;
+ MM3gppProfile *mm_profile;
+ const gchar *str;
+ guint8 context_number;
+ QmiWdsAuthentication auth;
+
+ wds_profile = iter->data;
+ mm_profile = g_slice_new0 (MM3gppProfile);
+ if (qmi_message_wds_get_profile_settings_output_get_apn_name (wds_profile, &str, NULL))
+ mm_profile->apn = g_strdup(str);
+ if (qmi_message_wds_get_profile_settings_output_get_pdp_context_number (wds_profile, &context_number, NULL))
+ mm_profile->profile_id = context_number;
+ if (qmi_message_wds_get_profile_settings_output_get_username (wds_profile, &str, NULL))
+ mm_profile->username = g_strdup(str);
+ if (qmi_message_wds_get_profile_settings_output_get_password (wds_profile, &str, NULL))
+ mm_profile->password = g_strdup(str);
+ if (qmi_message_wds_get_profile_settings_output_get_authentication (wds_profile, &auth, NULL))
+ mm_profile->auth_type = mm_bearer_allowed_auth_from_qmi_authentication (auth);
+
+ mm_profiles = g_list_prepend (mm_profiles, mm_profile);
+ }
+
+ return mm_profiles;
+}
+
+/*****************************************************************************/
+
/**
* The only case where we need to apply some logic to decide what the current
* capabilities are is when we have a multimode CDMA/EVDO+GSM/UMTS device, in
diff --git a/src/mm-modem-helpers-qmi.h b/src/mm-modem-helpers-qmi.h
index 829ac76..54d23ac 100644
--- a/src/mm-modem-helpers-qmi.h
+++ b/src/mm-modem-helpers-qmi.h
@@ -120,6 +120,9 @@
gboolean mm_bearer_ip_family_to_qmi_pdp_type (MMBearerIpFamily ip_family,
QmiWdsPdpType *out_pdp_type);
+/* Input is a GList of QmiMessageWdsGetProfileSettingsOutput. */
+GList *mm_3gpp_profile_list_from_qmi_profile_settings (GList *profile_list);
+
/*****************************************************************************/
/* QMI/OMA to MM translations */
diff --git a/src/mm-modem-helpers.c b/src/mm-modem-helpers.c
index b6b7f11..7ff7484 100644
--- a/src/mm-modem-helpers.c
+++ b/src/mm-modem-helpers.c
@@ -1771,6 +1771,41 @@
return list;
}
+static void
+mm_3gpp_profile_free (MM3gppProfile *profile)
+{
+ g_free (profile->apn);
+ g_free (profile->username);
+ g_free (profile->password);
+ g_slice_free (MM3gppProfile, profile);
+}
+
+void
+mm_3gpp_profile_list_free (GList *list)
+{
+ g_list_free_full (list, (GDestroyNotify) mm_3gpp_profile_free);
+}
+
+static MM3gppProfile *
+mm_3gpp_profile_copy (MM3gppProfile *profile)
+{
+ MM3gppProfile *copy;
+
+ copy = g_slice_new0 (MM3gppProfile);
+ copy->profile_id = profile->profile_id;
+ copy->apn = g_strdup (profile->apn);
+ copy->username = g_strdup (profile->username);
+ copy->password = g_strdup (profile->password);
+ copy->auth_type = profile->auth_type;
+ return copy;
+}
+
+GList *
+mm_3gpp_profile_list_copy (GList *list)
+{
+ return g_list_copy_deep (list, (GCopyFunc)mm_3gpp_profile_copy, NULL);
+}
+
/*************************************************************************/
static void
diff --git a/src/mm-modem-helpers.h b/src/mm-modem-helpers.h
index 806a8e7..785fd53 100644
--- a/src/mm-modem-helpers.h
+++ b/src/mm-modem-helpers.h
@@ -204,6 +204,16 @@
gboolean *out_cid_reused,
gboolean *out_cid_overwritten);
+typedef struct {
+ guint profile_id;
+ gchar *apn;
+ gchar *username;
+ gchar *password;
+ MMBearerAllowedAuth auth_type;
+} MM3gppProfile;
+void mm_3gpp_profile_list_free (GList *profiles);
+GList *mm_3gpp_profile_list_copy (GList *profiles);
+
/* AT+CGACT? (active PDP context query) response parser */
typedef struct {
guint cid;
diff --git a/src/mm-plugin.c b/src/mm-plugin.c
index 13b46a7..20b0124 100644
--- a/src/mm-plugin.c
+++ b/src/mm-plugin.c
@@ -50,7 +50,7 @@
G_IMPLEMENT_INTERFACE (MM_TYPE_LOG_OBJECT, log_object_iface_init))
/* Virtual port corresponding to the embedded modem */
-static const gchar *virtual_port[] = {"smd0", NULL};
+static const gchar *virtual_port[] = {"smd0", "rmnet_data0", "qmi0", NULL};
#define HAS_POST_PROBING_FILTERS(self) \
(self->priv->vendor_strings || \
@@ -1069,7 +1069,11 @@
g_clear_error (&inner_error);
} else if (!mm_base_modem_grab_port (modem,
kernel_device,
+#if QMI_QRTR_SUPPORTED //TODO(crbug.com/1103840): Remove hacks before merging to upstream
+ MM_PORT_TYPE_QMI,
+#else
MM_PORT_TYPE_AT,
+#endif
MM_PORT_SERIAL_AT_FLAG_NONE,
&inner_error)) {
mm_obj_warn (self, "could not grab virtual port %s: %s",
diff --git a/src/mm-port-qmi.c b/src/mm-port-qmi.c
index e3d99f7..61d42db 100644
--- a/src/mm-port-qmi.c
+++ b/src/mm-port-qmi.c
@@ -228,6 +228,10 @@
PORT_OPEN_STEP_FIRST,
PORT_OPEN_STEP_CHECK_OPENING,
PORT_OPEN_STEP_CHECK_ALREADY_OPEN,
+#if QMI_QRTR_SUPPORTED //TODO(b/118897479): Remove hacks before merging to upstream
+ PORT_OPEN_STEP_OPEN_QRTR_NODE,
+ PORT_OPEN_STEP_WAIT_FOR_SERVICES,
+#endif
PORT_OPEN_STEP_DEVICE_NEW,
PORT_OPEN_STEP_OPEN_WITHOUT_DATA_FORMAT,
PORT_OPEN_STEP_GET_KERNEL_DATA_FORMAT,
@@ -241,6 +245,10 @@
} PortOpenStep;
typedef struct {
+#if QMI_QRTR_SUPPORTED //TODO(b/118897479): Remove hacks before merging to upstream
+ QrtrBus *qrtr_bus;
+ QrtrNode *node;
+#endif
QmiDevice *device;
QmiClient *wda;
GError *error;
@@ -261,6 +269,10 @@
3, NULL, NULL, NULL);
g_clear_object (&ctx->wda);
g_clear_object (&ctx->device);
+#if QMI_QRTR_SUPPORTED //TODO(b/118897479): Remove hacks before merging to upstream
+ g_clear_object (&ctx->node);
+ g_clear_object (&ctx->qrtr_bus);
+#endif
g_slice_free (PortOpenContext, ctx);
}
@@ -475,6 +487,68 @@
port_open_step (task);
}
+#if QMI_QRTR_SUPPORTED //TODO(b/118897479): Remove hacks before merging to upstream
+static void
+qrtr_node_services_ready (QrtrNode *node,
+ GAsyncResult *res,
+ GTask *task)
+{
+ PortOpenContext *ctx;
+
+ ctx = g_task_get_task_data (task);
+ if (!qrtr_node_wait_for_services_finish (node, res, &ctx->error)) {
+ /* Error creating the device */
+ ctx->step = PORT_OPEN_STEP_LAST;
+ } else {
+ /* Go on to next step */
+ ctx->step++;
+ }
+ port_open_step (task);
+}
+static void
+qrtr_node_ready (GObject *unused,
+ GAsyncResult *res,
+ GTask *task)
+{
+ PortOpenContext *ctx;
+
+ ctx = g_task_get_task_data (task);
+
+ ctx->node = qrtr_bus_wait_for_node_finish (ctx->qrtr_bus, res, &ctx->error);
+ if (!ctx->node)
+ /* Error creating the node */
+ ctx->step = PORT_OPEN_STEP_LAST;
+ else
+ /* Go on to next step */
+ ctx->step++;
+ port_open_step (task);
+}
+
+static void
+qrtr_bus_ready (GObject *unused,
+ GAsyncResult *res,
+ GTask *task)
+{
+ PortOpenContext *ctx;
+
+ ctx = g_task_get_task_data (task);
+
+ ctx->qrtr_bus = qrtr_bus_new_finish (res, &ctx->error);
+ if (!ctx->qrtr_bus) {
+ /* Error creating the bus */
+ ctx->step = PORT_OPEN_STEP_LAST;
+ port_open_step (task);
+ } else {
+ qrtr_bus_wait_for_node (ctx->qrtr_bus,
+ 0,
+ 20,
+ g_task_get_cancellable (task),
+ (GAsyncReadyCallback) qrtr_node_ready,
+ task);
+ }
+}
+#endif
+
static void
port_open_step (GTask *task)
{
@@ -512,7 +586,57 @@
ctx->step++;
/* Fall through */
+#if QMI_QRTR_SUPPORTED //TODO(b/118897479): Remove hacks before merging to upstream
+ case PORT_OPEN_STEP_OPEN_QRTR_NODE:
+ self->priv->in_progress = TRUE;
+
+ mm_obj_info (self, "Creating QRTR bus and fetching node 0...");
+ qrtr_bus_new (20000,
+ g_task_get_cancellable (task),
+ (GAsyncReadyCallback) qrtr_bus_ready,
+ task);
+
+ return;
+
+ case PORT_OPEN_STEP_WAIT_FOR_SERVICES: {
+ GArray *services;
+ QmiService required_services[] = {
+ QMI_SERVICE_DMS,
+ QMI_SERVICE_WDA,
+ QMI_SERVICE_WDS,
+ QMI_SERVICE_NAS,
+ QMI_SERVICE_UIM,
+ QMI_SERVICE_PDC,
+ QMI_SERVICE_WMS
+ };
+
+ services = g_array_sized_new (FALSE,
+ FALSE,
+ sizeof (QmiService),
+ G_N_ELEMENTS (required_services));
+ g_array_append_vals (services,
+ required_services,
+ G_N_ELEMENTS (required_services));
+
+ mm_obj_info (self,"Waiting for services...");
+ qrtr_node_wait_for_services (ctx->node,
+ services,
+ 10000,
+ NULL,
+ (GAsyncReadyCallback) qrtr_node_services_ready,
+ task);
+ return;
+ }
+#endif
+
case PORT_OPEN_STEP_DEVICE_NEW: {
+#if QMI_QRTR_SUPPORTED //TODO(b/118897479): Remove hacks before merging to upstream
+ mm_obj_info (self, "Creating QMI device from QRTR node...");
+ qmi_device_new_from_node (ctx->node,
+ g_task_get_cancellable (task),
+ (GAsyncReadyCallback) qmi_device_new_ready,
+ task);
+#else
GFile *file;
gchar *fullpath;
@@ -532,6 +656,7 @@
g_free (fullpath);
g_object_unref (file);
+#endif
return;
}
diff --git a/tools/tests/Makefile.am b/tools/tests/Makefile.am
index c91675b..a93ffa9 100644
--- a/tools/tests/Makefile.am
+++ b/tools/tests/Makefile.am
@@ -31,7 +31,9 @@
-DTEST_SERVICES=\""$(abs_top_builddir)/tools/tests/services"\" \
$(NULL)
-TEST_PROGS += $(noinst_PROGRAMS)
+# Disable the test using python3 pygobject and gobject-introspection
+# as they are not ready (b/178312330).
+# TEST_PROGS += $(noinst_PROGRAMS)
test-wrapper.sh: test-wrapper.sh.in
@sed \