Hi,

I use a huawei E3372 modem. It connects to GPRS using PPP. I am able to activate context and then deactivate it. After that, I am not able to reactivate the context. During deactivation, the AT channel used by PPP gets closed and nobody reopens it. During reactivation, the first AT command (AT+CGDCONT) fails. Channel shutting down occurs just after NO CARRIER is received on modem channel (channel is back to AT state) along with a bunch of wrong data. Here is the log:
Modem: < \r\nNO CARRIER\r\n~\377}#\200!}%}"} }$\210*~
Shutting down is detected in function received_data (gatio.c). Flags G_IO_HUP and G_IO_ERR are received.


I have done a patch in huawei plugin that correct the problem at least with my modem. The idea is for plugin to get notified when modem AT channel gets closed and when this happens to remove gprs-context, reopen modem AT channel and restart gprs-context driver. This is possible because all other drivers (sim, gprs, ...) use PCUI AT channel and not modem AT channel.
But I am not sure this is:
- the right place to do it (in plugin or in gprs-context driver). I choose plugin because there are some AT commands to send just after channel opening and this is a plugin job. - the right way to do it (removing the whole gprs-context driver might be too much). Please find attached my current patch. It might not apply exactly on HEAD of master. At this stage, this is more to have comment on my fix than to really send a patch proposal.

If you need more info on this problem, I should be able to send traces with AT debug. It does not help a lot and I had to add traces in gatchat module to investigate.

Best Regards,

Christophe
>From f840da4307634c98d6f1a100f0012d211521ed2a Mon Sep 17 00:00:00 2001
From: Christophe Ronco <c.ro...@kerlink.fr>
Date: Wed, 15 Feb 2017 12:11:13 +0100
Subject: [PATCH] huawei: reopen modem channel if it disconnects

On E3372 after a GPRS disconnection, modem AT channel (used by PPP) gets
disconnected (G_IO_HUP and G_IO_ERR is detected in received_data in gatio.c).
After that all connection attempts fail because we are not able to send
any AT commands on modem channel (it is closed).

With this patch, when this behavior is detected, we close gprs context
driver, reopen AT channel and gprs context driver.
---
 plugins/huawei.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 47 insertions(+), 7 deletions(-)

diff --git a/plugins/huawei.c b/plugins/huawei.c
index 5dc9bc3b..4f9b3956 100644
--- a/plugins/huawei.c
+++ b/plugins/huawei.c
@@ -78,6 +78,8 @@ enum {
 struct huawei_data {
 	GAtChat *modem;
 	GAtChat *pcui;
+	struct ofono_gprs *gprs;
+	struct ofono_gprs_context *gc;
 	gboolean have_sim;
 	int sim_state;
 	guint sysinfo_poll_source;
@@ -584,6 +586,45 @@ static GAtChat *open_device(struct ofono_modem *modem,
 	return chat;
 }
 
+static void modem_disconnect(gpointer user_data)
+{
+	struct ofono_modem *modem = user_data;
+	struct huawei_data *data = ofono_modem_get_data(modem);
+
+	DBG("");
+
+	ofono_warn("modem channel disconnected");
+
+	/* clean and close modem device */
+	g_at_chat_cancel_all(data->modem);
+	g_at_chat_unregister_all(data->modem);
+	g_at_chat_unref(data->modem);
+	data->modem = NULL;
+
+	/* close gprs context driver */
+	ofono_gprs_context_remove(data->gc);
+
+	/* reopen modem channel */
+	data->modem = open_device(modem, "Modem", "Modem: ");
+
+	if (data->modem == NULL) {
+		DBG("Can't reopen device");
+		return;
+	}
+
+	/* configure modem channel */
+	g_at_chat_set_disconnect_function(data->modem, modem_disconnect, modem);
+	g_at_chat_set_slave(data->modem, data->pcui);
+	g_at_chat_send(data->modem, "ATE0 +CMEE=1", NULL, NULL, NULL, NULL);
+
+	/* reopen gprs context driver */
+	data->gc = ofono_gprs_context_create(modem, OFONO_VENDOR_HUAWEI,
+						"atmodem", data->modem);
+
+	if (data->gprs && data->gc)
+		ofono_gprs_add_context(data->gprs, data->gc);
+}
+
 static int huawei_enable(struct ofono_modem *modem)
 {
 	struct huawei_data *data = ofono_modem_get_data(modem);
@@ -594,6 +635,8 @@ static int huawei_enable(struct ofono_modem *modem)
 	if (data->modem == NULL)
 		return -EINVAL;
 
+	g_at_chat_set_disconnect_function(data->modem, modem_disconnect, modem);
+
 	data->pcui = open_device(modem, "Pcui", "PCUI: ");
 	if (data->pcui == NULL) {
 		g_at_chat_unref(data->modem);
@@ -820,9 +863,6 @@ static void huawei_post_sim(struct ofono_modem *modem)
 	}
 
 	if (data->have_gsm == TRUE) {
-		struct ofono_gprs *gprs;
-		struct ofono_gprs_context *gc;
-
 		ofono_phonebook_create(modem, 0, "atmodem", data->pcui);
 		ofono_radio_settings_create(modem, 0,
 						"huaweimodem", data->pcui);
@@ -830,13 +870,13 @@ static void huawei_post_sim(struct ofono_modem *modem)
 		ofono_sms_create(modem, OFONO_VENDOR_HUAWEI,
 						"atmodem", data->pcui);
 
-		gprs = ofono_gprs_create(modem, OFONO_VENDOR_HUAWEI,
+		data->gprs = ofono_gprs_create(modem, OFONO_VENDOR_HUAWEI,
 						"atmodem", data->pcui);
-		gc = ofono_gprs_context_create(modem, OFONO_VENDOR_HUAWEI,
+		data->gc = ofono_gprs_context_create(modem, OFONO_VENDOR_HUAWEI,
 						"atmodem", data->modem);
 
-		if (gprs && gc)
-			ofono_gprs_add_context(gprs, gc);
+		if (data->gprs && data->gc)
+			ofono_gprs_add_context(data->gprs, data->gc);
 	}
 }
 
-- 
2.11.0


_______________________________________________
ofono mailing list
ofono@ofono.org
https://lists.ofono.org/mailman/listinfo/ofono

Reply via email to