Index: ofono-1.11/drivers/atmodem/gprs-context.c
===================================================================
--- ofono-1.11.orig/drivers/atmodem/gprs-context.c  2012-09-11 13:09:25.000000000 +0300
+++ ofono-1.11/drivers/atmodem/gprs-context.c   2012-12-03 00:57:39.055590295 +0200
@@ -59,6 +59,8 @@
 struct gprs_context_data {
 	GAtChat *chat;
 	unsigned int active_context;
+	guint modem_ready_timeout;
+	char apn[OFONO_GPRS_MAX_APN_LENGTH + 1];
 	char username[OFONO_GPRS_MAX_USERNAME_LENGTH + 1];
 	char password[OFONO_GPRS_MAX_PASSWORD_LENGTH + 1];
 	GAtPPP *ppp;
@@ -219,13 +221,73 @@
 	CALLBACK_WITH_FAILURE(gcd->cb, gcd->cb_data);
 }
 
+static void activate_primary(struct ofono_gprs_context *gc)
+{
+	struct gprs_context_data *gcd = ofono_gprs_context_get_data(gc);
+
+	char buf[OFONO_GPRS_MAX_APN_LENGTH + 128];
+	int len;
+
+	DBG("cid %u", gcd->active_context);
+
+	len = snprintf(buf, sizeof(buf), "AT+CGDCONT=%u,\"IP\"", gcd->active_context);
+
+	if (gcd->apn)
+		snprintf(buf + len, sizeof(buf) - len - 3, ",\"%s\"", gcd->apn);
+
+	if (g_at_chat_send(gcd->chat, buf, none_prefix, at_cgdcont_cb, gc, NULL) > 0)
+		return;
+
+	CALLBACK_WITH_FAILURE(gcd->cb, gcd->cb_data);
+}
+
+static gboolean at_modem_not_ready_cb(gpointer user_data)
+{
+	struct ofono_gprs_context *gc = user_data;
+	struct gprs_context_data *gcd = ofono_gprs_context_get_data(gc);
+	GAtChat *chat = g_at_chat_get_slave(gcd->chat);
+
+	gcd->active_context = 0;
+	gcd->state = STATE_IDLE;
+	gcd->modem_ready_timeout = 0;
+
+	ofono_error("Modem not responding");
+	DBG("resetting modem...");
+	CALLBACK_WITH_FAILURE(gcd->cb, gcd->cb_data);
+
+	g_at_chat_send(chat, "AT+CFUN=1,1", none_prefix, NULL, NULL, NULL);
+
+	return FALSE;
+}
+
+static void at_modem_ready_cb(gboolean ok, GAtResult *result, gpointer user_data)
+{
+	struct ofono_gprs_context *gc = user_data;
+	struct gprs_context_data *gcd = ofono_gprs_context_get_data(gc);
+	if (gcd->modem_ready_timeout == 0)
+		return;  // Too late, modem already been reset
+	DBG("modem is ready");
+	g_source_remove(gcd->modem_ready_timeout);
+	activate_primary(gc);
+}
+
+static void at_activate_primary_with_check(struct ofono_gprs_context *gc)
+{
+	struct gprs_context_data *gcd = ofono_gprs_context_get_data(gc);
+	gcd->modem_ready_timeout = g_timeout_add_seconds(70, at_modem_not_ready_cb, gc);
+	g_at_chat_send(gcd->chat, "AT", none_prefix, at_modem_ready_cb, gc, NULL);
+}
+
+static void at_gprs_activate_primary_cb(gboolean ok, GAtResult *result, gpointer user_data)
+{
+	at_activate_primary_with_check(user_data);
+}
+
 static void at_gprs_activate_primary(struct ofono_gprs_context *gc,
 				const struct ofono_gprs_primary_context *ctx,
 				ofono_gprs_context_cb_t cb, void *data)
 {
 	struct gprs_context_data *gcd = ofono_gprs_context_get_data(gc);
-	char buf[OFONO_GPRS_MAX_APN_LENGTH + 128];
-	int len;
 
 	/* IPv6 support not implemented */
 	if (ctx->proto != OFONO_GPRS_PROTO_IP)
@@ -238,6 +300,7 @@
 	gcd->cb_data = data;
 	memcpy(gcd->username, ctx->username, sizeof(ctx->username));
 	memcpy(gcd->password, ctx->password, sizeof(ctx->password));
+	memcpy(gcd->apn, ctx->apn, sizeof(ctx->apn));
 
 	gcd->state = STATE_ENABLING;
 
@@ -258,19 +321,14 @@
 		 * needs to be send on the control port of course.
 		 *
 		 */
-		g_at_chat_send(chat, "AT+ZOPRT?", none_prefix,
-						NULL, NULL, NULL);
+		if (g_at_chat_send(chat, "AT+ZOPRT?", none_prefix,
+						at_gprs_activate_primary_cb, gc, NULL) > 0)
+			return;
+		goto error;
 	}
 
-	len = snprintf(buf, sizeof(buf), "AT+CGDCONT=%u,\"IP\"", ctx->cid);
-
-	if (ctx->apn)
-		snprintf(buf + len, sizeof(buf) - len - 3, ",\"%s\"",
-				ctx->apn);
-
-	if (g_at_chat_send(gcd->chat, buf, none_prefix,
-				at_cgdcont_cb, gc, NULL) > 0)
-		return;
+	at_activate_primary_with_check(gc);
+	return;
 
 error:
 	CALLBACK_WITH_FAILURE(cb, data);
