modemmanager-next/samsung: Check error when activation fails

Port code from old ModemManager to issue an %IER command when %IPDPACT
returns a failure, and pass the relevant error up the stack.

BUG=chromium-os:30656
TEST=With an AT&T SIM, try to connect with an bogus APN.
"mmcli -m 0 --simple-connect='apn=bogus'".
mmcli should return with error #MobileEquipment.Gprs.ServiceOptionNotSubscribed.

Change-Id: I8abb70185d488f32574f8abff2e5f7905ea4e935
diff --git a/plugins/samsung/mm-broadband-bearer-samsung.c b/plugins/samsung/mm-broadband-bearer-samsung.c
index 9ed908e..afac777 100644
--- a/plugins/samsung/mm-broadband-bearer-samsung.c
+++ b/plugins/samsung/mm-broadband-bearer-samsung.c
@@ -147,6 +147,61 @@
 }
 
 static void
+dial_3gpp_get_error_done (MMBaseModem *modem,
+                          GAsyncResult *res,
+                          DialContext *ctx)
+{
+    MMBroadbandBearerSamsung *self = ctx->self;
+    const gchar *response;
+    int activation_err;
+    GError *error = NULL;
+
+    response = mm_base_modem_at_command_finish (modem, res, &error);
+
+    if (error) {
+        g_simple_async_result_take_error (ctx->result, error);
+        dial_context_complete_and_free (ctx);
+        return;
+    }
+
+    response = mm_strip_tag (response, "%IER:");
+    if (sscanf (response, " %*d,%*d,%d", &activation_err) &&
+        (activation_err == 27 || activation_err == 33)) {
+        g_simple_async_result_set_error (ctx->result,
+                                         MM_MOBILE_EQUIPMENT_ERROR,
+                                         MM_MOBILE_EQUIPMENT_ERROR_GPRS_SERVICE_OPTION_NOT_SUBSCRIBED,
+                                         "Missing or unknown APN");
+    } else {
+        g_simple_async_result_set_error (ctx->result,
+                                         MM_CORE_ERROR,
+                                         MM_CORE_ERROR_FAILED,
+                                         "Call setup failed");
+    }
+
+    dial_context_complete_and_free (ctx);
+    self->priv->connected_cid = 0;
+    self->priv->pending_dial = NULL;
+}
+
+static void
+dial_3gpp_get_error (MMBroadbandBearerSamsung *self,
+                     DialContext *ctx)
+{
+    mm_dbg("checking what the error was");
+    if (ctx->timeout_id) {
+        g_source_remove (ctx->timeout_id);
+        ctx->timeout_id = 0;
+    }
+
+    mm_base_modem_at_command (ctx->modem,
+                              "%IER?",
+                              3,
+                              FALSE,
+                              (GAsyncReadyCallback)dial_3gpp_get_error_done,
+                              ctx);
+}
+
+static void
 disconnect_3gpp_done (MMBroadbandBearerSamsung *self,
                       DisconnectContext *result);
 
@@ -197,6 +252,11 @@
             break;
         case 3:
             /* activation failed */
+            if (self->priv->pending_dial == NULL) {
+                mm_warn ("Recieved %%IPDPACT failure while not connecting.");
+                return;
+            }
+            dial_3gpp_get_error (self, self->priv->pending_dial);
             break;
         default:
             mm_warn ("Unknown connect status %d", status);