Merge ~alfonsosanchezbeato/snappy-hwe-snaps/+git/modem-manager:workaround-lp1685116 into ~snappy-hwe-team/snappy-hwe-snaps/+git/modem-manager:modem-manager/xenial/1.6.2

Proposed by Alfonso Sanchez-Beato
Status: Merged
Approved by: Simon Fels
Approved revision: 5ee7111e1e145a94631875d3cec81f70f46a16b6
Merged at revision: 882bc071ad093e2cf306893be1f186a91c7d2287
Proposed branch: ~alfonsosanchezbeato/snappy-hwe-snaps/+git/modem-manager:workaround-lp1685116
Merge into: ~snappy-hwe-team/snappy-hwe-snaps/+git/modem-manager:modem-manager/xenial/1.6.2
Diff against target: 164 lines (+100/-1)
2 files modified
plugins/dell/mm-plugin-dell.c (+8/-0)
src/mm-broadband-modem-mbim.c (+92/-1)
Reviewer Review Type Date Requested Status
Simon Fels Approve
System Enablement Bot continuous-integration Approve
Review via email: mp+322937@code.launchpad.net

Commit message

Reset the modem on MBIM NOT_OPENED error for HL7588

Reset the modem for said condition so connection can be recovered
after resuming from S4 (hibernate).

Description of the change

Reset the modem on MBIM NOT_OPENED error for HL7588

Reset the modem for said condition so connection can be recovered
after resuming from S4 (hibernate).

To post a comment you must log in.
Revision history for this message
System Enablement Bot (system-enablement-ci-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
Simon Fels (morphis) :
Revision history for this message
System Enablement Bot (system-enablement-ci-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
Simon Fels (morphis) wrote :

LGTM

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/plugins/dell/mm-plugin-dell.c b/plugins/dell/mm-plugin-dell.c
2index 37de392..69aca81 100644
3--- a/plugins/dell/mm-plugin-dell.c
4+++ b/plugins/dell/mm-plugin-dell.c
5@@ -258,6 +258,13 @@ custom_init_step (CustomInitContext *ctx)
6
7 #if defined WITH_MBIM
8 /* If device has a MBIM port, don't run anything else, as we don't care */
9+ /* CANONICAL We need the AT ports for the Sierra HL7588 workarounds. Anyway,
10+ * doing this was not a great idea as actually probing or not the ports
11+ * depended on a race condition (bug LP: #1685722). Leaving this commented
12+ * out to not forget about this and rethink in case we can remove the
13+ * workarounds. TODO upstream?
14+ */
15+#if 0
16 if (mm_port_probe_list_has_mbim_port (mm_device_peek_port_probe_list (mm_port_probe_peek_device (ctx->probe)))) {
17 mm_dbg ("(Dell) no need to run custom init in (%s): device has MBIM port",
18 mm_port_get_device (MM_PORT (ctx->port)));
19@@ -268,6 +275,7 @@ custom_init_step (CustomInitContext *ctx)
20 return;
21 }
22 #endif
23+#endif
24
25 if (ctx->gmi_retries > 0) {
26 ctx->gmi_retries--;
27diff --git a/src/mm-broadband-modem-mbim.c b/src/mm-broadband-modem-mbim.c
28index d68d7cb..49d0643 100644
29--- a/src/mm-broadband-modem-mbim.c
30+++ b/src/mm-broadband-modem-mbim.c
31@@ -20,6 +20,10 @@
32 #include <string.h>
33 #include <unistd.h>
34 #include <ctype.h>
35+#include <sys/types.h>
36+#include <sys/stat.h>
37+#include <fcntl.h>
38+#include <errno.h>
39
40 #include "mm-modem-helpers-mbim.h"
41 #include "mm-broadband-modem-mbim.h"
42@@ -75,6 +79,10 @@ struct _MMBroadbandModemMbimPrivate {
43 ProcessNotificationFlag setup_flags;
44 ProcessNotificationFlag enable_flags;
45
46+ /* Process function errors */
47+ guint function_error_id;
48+ guint already_reset;
49+
50 /* 3GPP registration helpers */
51 gchar *current_operator_id;
52 gchar *current_operator_name;
53@@ -2261,6 +2269,76 @@ device_notification_cb (MbimDevice *device,
54 }
55 }
56
57+#define VID_SIERRA_HL7588 0x413C
58+#define PID_SIERRA_HL7588 0x81C8
59+
60+static unsigned
61+get_uint_property (GObject *obj, const gchar *property_name)
62+{
63+ GValue value = G_VALUE_INIT;
64+
65+ g_value_init (&value, G_TYPE_UINT);
66+ g_object_get_property (obj, property_name, &value);
67+ return g_value_get_uint (&value);
68+}
69+
70+static void
71+function_error_cb (MbimDevice *device,
72+ GError *function_error,
73+ MMBroadbandModemMbim *self)
74+{
75+ /* If a NOT_OPENED error is received for the Sierra HL7588, chances are that
76+ * we are just out of hibernate and the modem is in a bad state. To recover,
77+ * we send a reset command to the modem. At this point MM serial ports
78+ * could be closed due to hangups being received, so we resort to open
79+ * directly the port and sending the raw command. The reset makes the
80+ * current MM instance disappear and a new one is created, in a good state.
81+ */
82+ if (g_error_matches (function_error,
83+ MBIM_PROTOCOL_ERROR, MBIM_PROTOCOL_ERROR_NOT_OPENED)
84+ && VID_SIERRA_HL7588 == get_uint_property (G_OBJECT (self),
85+ MM_BASE_MODEM_VENDOR_ID)
86+ && PID_SIERRA_HL7588 == get_uint_property (G_OBJECT (self),
87+ MM_BASE_MODEM_PRODUCT_ID)) {
88+ int fd;
89+ ssize_t written;
90+ const char reset_cmd[] = "AT+CFUN=16\r";
91+ MMPortSerialAt *at_port;
92+ char port_name[128];
93+
94+ /* Sending reset only once, as the command resets the HW and forces the
95+ * creation of a new modem object.
96+ */
97+ if (self->priv->already_reset)
98+ return;
99+
100+ mm_dbg ("NOT_OPENED received for Sierra HL7588");
101+
102+ at_port = mm_base_modem_peek_best_at_port (MM_BASE_MODEM (self), NULL);
103+ if (at_port)
104+ snprintf (port_name, sizeof port_name, "/dev/%s",
105+ mm_port_get_device (MM_PORT (at_port)));
106+ else
107+ strcpy (port_name, "/dev/ttyACM0");
108+
109+ fd = open (port_name, O_RDWR);
110+ if (fd == -1) {
111+ mm_dbg ("Error cannot open port: %s (%d)", strerror (errno), errno);
112+ return;
113+ }
114+ written = write (fd, reset_cmd, sizeof reset_cmd - 1);
115+ if (written == -1) {
116+ mm_dbg ("Error cannot write: %s (%d)", strerror (errno), errno);
117+ close (fd);
118+ return;
119+ }
120+ mm_dbg ("Written %s (%zd) on %s", reset_cmd, written, port_name);
121+
122+ close (fd);
123+ self->priv->already_reset = TRUE;
124+ }
125+}
126+
127 static gboolean
128 common_setup_cleanup_unsolicited_events_finish (MMBroadbandModemMbim *self,
129 GAsyncResult *res,
130@@ -2295,13 +2373,20 @@ common_setup_cleanup_unsolicited_events (MMBroadbandModemMbim *self,
131 self->priv->setup_flags & PROCESS_NOTIFICATION_FLAG_PACKET_SERVICE ? "yes" : "no");
132
133 if (setup) {
134- /* Don't re-enable it if already there */
135+ /* Don't re-enable signals if already there */
136 if (!self->priv->notification_id)
137 self->priv->notification_id =
138 g_signal_connect (device,
139 MBIM_DEVICE_SIGNAL_INDICATE_STATUS,
140 G_CALLBACK (device_notification_cb),
141 self);
142+
143+ if (!self->priv->function_error_id)
144+ self->priv->function_error_id =
145+ g_signal_connect (device,
146+ MBIM_DEVICE_SIGNAL_ERROR,
147+ G_CALLBACK (function_error_cb),
148+ self);
149 } else {
150 /* Don't remove the signal if there are still listeners interested */
151 if (self->priv->setup_flags == PROCESS_NOTIFICATION_FLAG_NONE &&
152@@ -2310,6 +2395,12 @@ common_setup_cleanup_unsolicited_events (MMBroadbandModemMbim *self,
153 g_signal_handler_disconnect (device, self->priv->notification_id);
154 self->priv->notification_id = 0;
155 }
156+
157+ if (self->priv->function_error_id &&
158+ g_signal_handler_is_connected (device, self->priv->function_error_id)) {
159+ g_signal_handler_disconnect (device, self->priv->function_error_id);
160+ self->priv->function_error_id = 0;
161+ }
162 }
163
164 g_simple_async_result_complete_in_idle (result);

Subscribers

People subscribed via source and target branches