diff --git a/introspection/mm-modem-gsm-card.xml b/introspection/mm-modem-gsm-card.xml
index 708d5c9..51c5a71 100644
--- a/introspection/mm-modem-gsm-card.xml
+++ b/introspection/mm-modem-gsm-card.xml
@@ -28,6 +28,19 @@
       </arg>
     </method>
 
+    <method name="GetOperatorId">
+      <tp:docstring>
+	Get the id of the operator from the SIM card.
+      </tp:docstring>
+      <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+      <annotation name="org.freedesktop.DBus.GLib.CSymbol" value="impl_gsm_modem_get_operator_id"/>
+      <arg name="imsi" type="s" direction="out">
+	<tp:docstring>
+	  The operator ID.
+	</tp:docstring>
+      </arg>
+    </method>
+
     <method name="SendPuk">
       <tp:docstring>
 	Send the PUK and a new PIN to unlock the SIM card.
diff --git a/src/mm-generic-gsm.c b/src/mm-generic-gsm.c
index 8c155e2..e3cda5f 100644
--- a/src/mm-generic-gsm.c
+++ b/src/mm-generic-gsm.c
@@ -1111,6 +1111,61 @@ get_string_done (MMAtSerialPort *port,
 }
 
 static void
+get_mnc_length_done (MMAtSerialPort *port,
+                     GString *response,
+                     GError *error,
+                     gpointer user_data)
+{
+    MMCallbackInfo *info = (MMCallbackInfo *) user_data;
+    int mnc_len;
+    char *imsi = mm_callback_info_get_data (info, "imsi");
+    int ret;
+
+    if (error) {
+        info->error = g_error_copy (error);
+        mm_callback_info_schedule (info);
+        return;
+    }
+
+    ret = sscanf (response->str, "+CRSM:%*d,%*d,\"%d\"", &mnc_len);
+    if (ret)
+        mm_callback_info_set_result (info, g_strndup (imsi, 3 + mnc_len), g_free);
+    else
+        info->error = g_error_new_literal (MM_MODEM_ERROR,
+                                           MM_MODEM_ERROR_GENERAL,
+                                           "Could not parse the CRSM response");
+    
+    mm_callback_info_schedule (info);    
+}
+
+static void
+get_imsi_done (MMModem *modem,
+               const char *result,
+               GError *error,
+               gpointer user_data)
+{
+    MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (modem);
+    MMCallbackInfo *info = (MMCallbackInfo *) user_data;
+    char *command;
+    
+    if (error) {
+        info->error = g_error_copy (error);
+        mm_callback_info_schedule (info);
+        return;
+    }
+
+    mm_callback_info_set_data (info, "imsi", g_strdup (result), g_free);
+
+    command = g_strdup_printf ("+CRSM=%s,%s,0,0,4",
+                               MM_MODEM_GSM_CARD_SIM_READ_BIN_CMD,
+                               MM_MODEM_GSM_CARD_SIM_MNC_ADDR);
+    
+    mm_at_serial_port_queue_command_cached (priv->primary, command, 3, get_mnc_length_done, info);
+
+    g_free (command);
+}
+
+static void
 get_imei (MMModemGsmCard *modem,
           MMModemStringFn callback,
           gpointer user_data)
@@ -1135,6 +1190,19 @@ get_imsi (MMModemGsmCard *modem,
 }
 
 static void
+get_operator_id (MMModemGsmCard *modem,
+                 MMModemStringFn callback,
+                 gpointer user_data)
+{
+    MMCallbackInfo *info;
+
+    info = mm_callback_info_string_new (MM_MODEM (modem), callback, user_data);
+    mm_modem_gsm_card_get_imsi (MM_MODEM_GSM_CARD (modem),
+                                get_imsi_done,
+                                info);
+}
+
+static void
 get_card_info (MMModem *modem,
                MMModemInfoFn callback,
                gpointer user_data)
@@ -3535,6 +3603,7 @@ modem_gsm_card_init (MMModemGsmCard *class)
 {
     class->get_imei = get_imei;
     class->get_imsi = get_imsi;
+    class->get_operator_id = get_operator_id;
     class->send_pin = send_pin;
     class->send_puk = send_puk;
     class->enable_pin = enable_pin;
diff --git a/src/mm-modem-gsm-card.c b/src/mm-modem-gsm-card.c
index 432a4a3..496965c 100644
--- a/src/mm-modem-gsm-card.c
+++ b/src/mm-modem-gsm-card.c
@@ -28,6 +28,9 @@ static void impl_gsm_modem_get_imei (MMModemGsmCard *modem,
 static void impl_gsm_modem_get_imsi (MMModemGsmCard *modem,
                                      DBusGMethodInvocation *context);
 
+static void impl_gsm_modem_get_operator_id (MMModemGsmCard *modem,
+                                            DBusGMethodInvocation *context);
+
 static void impl_gsm_modem_send_pin (MMModemGsmCard *modem,
                                      const char *pin,
                                      DBusGMethodInvocation *context);
@@ -131,6 +134,20 @@ mm_modem_gsm_card_get_imsi (MMModemGsmCard *self,
 }
 
 void
+mm_modem_gsm_card_get_operator_id (MMModemGsmCard *self,
+                                   MMModemStringFn callback,
+                                   gpointer user_data)
+{
+    g_return_if_fail (MM_IS_MODEM_GSM_CARD (self));
+    g_return_if_fail (callback != NULL);
+
+    if (MM_MODEM_GSM_CARD_GET_INTERFACE (self)->get_operator_id)
+        MM_MODEM_GSM_CARD_GET_INTERFACE (self)->get_operator_id (self, callback, user_data);
+    else
+        str_call_not_supported (self, callback, user_data);
+}
+
+void
 mm_modem_gsm_card_send_puk (MMModemGsmCard *self,
                             const char *puk,
                             const char *pin,
@@ -275,6 +292,43 @@ impl_gsm_modem_get_imsi (MMModemGsmCard *modem, DBusGMethodInvocation *context)
 
 /*****************************************************************************/
 
+static void
+operator_id_auth_cb (MMAuthRequest *req,
+                     GObject *owner,
+                     DBusGMethodInvocation *context,
+                     gpointer user_data)
+{
+    MMModemGsmCard *self = MM_MODEM_GSM_CARD (owner);
+    GError *error = NULL;
+
+    /* Return any authorization error, otherwise get the operator id */
+    if (!mm_modem_auth_finish (MM_MODEM (self), req, &error)) {
+        dbus_g_method_return_error (context, error);
+        g_error_free (error);
+    } else
+        mm_modem_gsm_card_get_operator_id (self, str_call_done, context);
+}
+
+static void
+impl_gsm_modem_get_operator_id (MMModemGsmCard *modem, DBusGMethodInvocation *context)
+{
+    GError *error = NULL;
+
+    /* Make sure the caller is authorized to get the operator id */
+    if (!mm_modem_auth_request (MM_MODEM (modem),
+                                MM_AUTHORIZATION_DEVICE_INFO,
+                                context,
+                                operator_id_auth_cb,
+                                NULL,
+                                NULL,
+                                &error)) {
+        dbus_g_method_return_error (context, error);
+        g_error_free (error);
+    }
+}
+
+/*****************************************************************************/
+
 typedef struct {
     char *puk;
     char *pin;
diff --git a/src/mm-modem-gsm-card.h b/src/mm-modem-gsm-card.h
index 4d690e6..92c7a65 100644
--- a/src/mm-modem-gsm-card.h
+++ b/src/mm-modem-gsm-card.h
@@ -27,6 +27,9 @@
 #define MM_MODEM_GSM_CARD_SUPPORTED_BANDS "supported-bands"
 #define MM_MODEM_GSM_CARD_SUPPORTED_MODES "supported-modes"
 
+#define MM_MODEM_GSM_CARD_SIM_READ_BIN_CMD "176"
+#define MM_MODEM_GSM_CARD_SIM_MNC_ADDR "28589"
+
 typedef struct _MMModemGsmCard MMModemGsmCard;
 
 struct _MMModemGsmCard {
@@ -41,6 +44,10 @@ struct _MMModemGsmCard {
                       MMModemStringFn callback,
                       gpointer user_data);
 
+    void (*get_operator_id) (MMModemGsmCard *self,
+                             MMModemStringFn callback,
+                             gpointer user_data);
+
     void (*send_puk) (MMModemGsmCard *self,
                       const char *puk,
                       const char *pin,
@@ -75,6 +82,10 @@ void mm_modem_gsm_card_get_imsi (MMModemGsmCard *self,
                                  MMModemStringFn callback,
                                  gpointer user_data);
 
+void mm_modem_gsm_card_get_operator_id (MMModemGsmCard *self,
+                                        MMModemStringFn callback,
+                                        gpointer user_data);
+
 void mm_modem_gsm_card_send_puk (MMModemGsmCard *self,
                                  const char *puk,
                                  const char *pin,
