diff -rU8 -N nm.trunk/src/modem-manager/Makefile.am NetworkManager_MBM/src/modem-manager/Makefile.am
--- nm.trunk/src/modem-manager/Makefile.am	2008-11-25 18:48:48.000000000 +0100
+++ NetworkManager_MBM/src/modem-manager/Makefile.am	2008-11-24 21:34:34.000000000 +0100
@@ -8,16 +8,18 @@
 
 libmodem_manager_la_SOURCES = \
 	nm-cdma-modem.c \
 	nm-cdma-modem.h \
 	nm-gsm-modem.c \
 	nm-gsm-modem.h \
 	nm-gsm-modem-hso.c \
 	nm-gsm-modem-hso.h \
+	nm-gsm-modem-mbm.c \
+	nm-gsm-modem-mbm.h \
 	nm-modem-device.c \
 	nm-modem-device.h \
 	nm-modem-manager.h \
 	nm-modem-manager.c \
 	nm-modem-types.h
 
 libmodem_manager_la_CPPFLAGS = \
 	$(DBUS_CFLAGS)
diff -rU8 -N nm.trunk/src/modem-manager/Makefile.in NetworkManager_MBM/src/modem-manager/Makefile.in
diff -rU8 -N nm.trunk/src/modem-manager/nm-gsm-modem.c NetworkManager_MBM/src/modem-manager/nm-gsm-modem.c
--- nm.trunk/src/modem-manager/nm-gsm-modem.c	2008-11-25 18:48:48.000000000 +0100
+++ NetworkManager_MBM/src/modem-manager/nm-gsm-modem.c	2008-11-24 21:34:33.000000000 +0100
@@ -14,25 +14,27 @@
 G_DEFINE_TYPE (NMGsmModem, nm_gsm_modem, NM_TYPE_MODEM_DEVICE)
 
 #define NM_GSM_MODEM_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_GSM_MODEM, NMGsmModemPrivate))
 
 enum {
 	MODEM_STATE_BEGIN,
 	MODEM_STATE_ENABLE,
 	MODEM_STATE_SET_PIN,
+	MODEM_STATE_SET_PUK,
 	MODEM_STATE_SET_APN,
 	MODEM_STATE_SET_BAND,
 	MODEM_STATE_SET_NETWORK_MODE,
 	MODEM_STATE_REGISTER,
 	MODEM_STATE_FAILED,
 };
 
 typedef struct {
 	int modem_state;
+	int reason;
 } NMGsmModemPrivate;
 
 NMDevice *
 nm_gsm_modem_new (const char *path,
 			   const char *data_device,
 			   const char *driver)
 {
 	g_return_val_if_fail (path != NULL, NULL);
@@ -73,41 +75,70 @@
 {
 	NMGsmModem *modem = NM_GSM_MODEM (user_data);
 	NMGsmModemPrivate *priv = NM_GSM_MODEM_GET_PRIVATE (modem);
 	NMSettingGsm *setting;
 	const char *secret = NULL;
 	const char *secret_name = NULL;
 	gboolean retry_secret = FALSE;
 	GError *error = NULL;
+	static int bTriedPUK = 0;   /* Testing: assuming only one modem is connection phase and stuck on PUK */
 
 	setting = NM_SETTING_GSM (get_setting (modem, NM_TYPE_SETTING_GSM));
 
 	if (call_id)
 		dbus_g_proxy_end_call (proxy, call_id, &error, G_TYPE_INVALID);
 
+	if (!setting)
+		return;
+		
+
 	if (error) {
 		g_debug ("%s", dbus_g_error_get_name (error));
 
 		if (dbus_g_error_has_name (error, MM_MODEM_ERROR_SIM_PIN)) {
 			secret = setting->pin;
 			secret_name = NM_SETTING_GSM_PIN;
 			priv->modem_state = MODEM_STATE_SET_PIN;
 		} else if (dbus_g_error_has_name (error, MM_MODEM_ERROR_SIM_PUK)) {
+			g_debug("MM_MODEM_ERROR_SIM_PUK");
+			if (setting->pin == NULL) {
+				g_debug("pin == NULL");
+				nm_device_state_changed (NM_DEVICE (modem), NM_DEVICE_STATE_NEED_AUTH, NM_DEVICE_STATE_REASON_NONE);
+				nm_act_request_request_connection_secrets (nm_device_get_act_request (NM_DEVICE (modem)),
+					NM_SETTING_GSM_SETTING_NAME,
+					retry_secret,
+					SECRETS_CALLER_GSM,
+					NM_SETTING_GSM_PIN,
+					NULL);
+			}
+			if (bTriedPUK) {
+				g_debug("fail with PUK");
+				priv->modem_state = MODEM_STATE_FAILED;
+				priv->reason = NM_DEVICE_STATE_REASON_GSM_PUK_CHECK_FAILED;
+				bTriedPUK = 0;
+			} else {
+				bTriedPUK = 1;
 			secret = setting->puk;
 			secret_name = NM_SETTING_GSM_PUK;
-			priv->modem_state = MODEM_STATE_SET_PIN;
+				priv->modem_state = MODEM_STATE_SET_PUK;
+			}
 		} else if (dbus_g_error_has_name (error, MM_MODEM_ERROR_SIM_WRONG)) {
 			g_free (setting->pin);
 			setting->pin = NULL;
 			secret_name = NM_SETTING_GSM_PIN;
 			retry_secret = TRUE;
 			priv->modem_state = MODEM_STATE_SET_PIN;
+		} else if (dbus_g_error_has_name (error, MM_MODEM_ERROR_WRONG_PASSWORD)) {
+			priv->modem_state = MODEM_STATE_FAILED;
+			priv->reason = NM_DEVICE_STATE_REASON_GSM_PIN_CHECK_FAILED;
+			g_debug("pin check failed");
 		}
 
+
 		/* FIXME: Hacks to ignore failures of setting band and network mode for now
 		   since only Huawei module supports it. Remove when ModemManager rules.
 		*/
 		else if (dbus_g_error_has_name (error, MM_MODEM_ERROR_OPERATION_NOT_SUPPORTED) &&
 			    (priv->modem_state == MODEM_STATE_SET_BAND ||
 				priv->modem_state == MODEM_STATE_SET_NETWORK_MODE)) {
 
 			nm_warning ("Modem does not support setting %s, ignoring",
@@ -147,21 +178,45 @@
 											   retry_secret,
 											   SECRETS_CALLER_GSM,
 											   secret_name,
 											   NULL);
 
 		}
 		break;
 
+	case MODEM_STATE_SET_PUK:
+		g_debug("set_puk");
+		if (setting->puk) {
+			g_debug("got puk");
+			priv->modem_state = MODEM_STATE_ENABLE;
+			dbus_g_proxy_begin_call (get_proxy (modem, MM_DBUS_INTERFACE_MODEM_GSM_CARD),
+								"SendPuk", state_machine,
+								modem, NULL,
+								G_TYPE_STRING, setting->puk,
+								G_TYPE_STRING, setting->pin,
+								G_TYPE_INVALID);
+		} else {
+			g_debug("secret_name = %s", secret_name);
+			nm_device_state_changed (NM_DEVICE (modem), NM_DEVICE_STATE_NEED_AUTH, NM_DEVICE_STATE_REASON_NONE);
+			nm_act_request_request_connection_secrets (nm_device_get_act_request (NM_DEVICE (modem)),
+				NM_SETTING_GSM_SETTING_NAME,
+				retry_secret,
+				SECRETS_CALLER_GSM,
+				secret_name,
+				NULL);
+
+		}
+		break;
+
 	case MODEM_STATE_ENABLE:
 		priv->modem_state = MODEM_STATE_SET_APN;
 		if (setting->apn)
 			dbus_g_proxy_begin_call (get_proxy (modem, MM_DBUS_INTERFACE_MODEM_GSM_NETWORK),
-								"SetAPN", state_machine,
+								"SetApn", state_machine,
 								modem, NULL,
 								G_TYPE_STRING, setting->apn,
 								G_TYPE_INVALID);
 		else
 			goto again;
 
 		break;
 	case MODEM_STATE_SET_APN:
@@ -196,30 +251,32 @@
 									   "Register", state_machine,
 									   modem, NULL, 120000,
 									   G_TYPE_STRING, setting->network_id ? setting->network_id : "",
 									   G_TYPE_INVALID);
 		break;
 
 	case MODEM_STATE_REGISTER:
 		nm_modem_device_connect (NM_MODEM_DEVICE (modem), setting->number);
+		bTriedPUK = 0;
 		break;
 	case MODEM_STATE_FAILED:
 	default:
-		nm_device_state_changed (NM_DEVICE (modem), NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_NONE);
+		nm_device_state_changed (NM_DEVICE (modem), NM_DEVICE_STATE_FAILED, priv->reason);
 		break;
 	}
 }
 
 static NMActStageReturn
 real_act_stage1_prepare (NMDevice *device, NMDeviceStateReason *reason)
 {
 	NMGsmModemPrivate *priv = NM_GSM_MODEM_GET_PRIVATE (device);
 
 	priv->modem_state = MODEM_STATE_BEGIN;
+	priv->reason = NM_DEVICE_STATE_REASON_NONE;
 	state_machine (NULL, NULL, device);
 
 	return NM_ACT_STAGE_RETURN_POSTPONE;
 }
 
 static NMConnection *
 real_get_best_auto_connection (NMDevice *dev,
                                GSList *connections,
diff -rU8 -N nm.trunk/src/modem-manager/nm-gsm-modem-hso.c NetworkManager_MBM/src/modem-manager/nm-gsm-modem-hso.c
--- nm.trunk/src/modem-manager/nm-gsm-modem-hso.c	2008-11-25 18:48:48.000000000 +0100
+++ NetworkManager_MBM/src/modem-manager/nm-gsm-modem-hso.c	2008-11-24 21:34:33.000000000 +0100
@@ -60,16 +60,17 @@
 	g_return_val_if_fail (data_device != NULL, NULL);
 	g_return_val_if_fail (driver != NULL, NULL);
 
 	device = (NMDevice *) g_object_new (NM_TYPE_GSM_MODEM_HSO,
 								 NM_DEVICE_INTERFACE_UDI, path,
 								 NM_DEVICE_INTERFACE_IFACE, data_device,
 								 NM_DEVICE_INTERFACE_DRIVER, driver,
 								 NM_DEVICE_INTERFACE_MANAGED, TRUE,
+                                                                 NM_MODEM_DEVICE_PATH, path,
 								 NULL);
 
 	if (device) {
 		NMGsmModemHsoPrivate *priv;
 
 		priv = NM_GSM_MODEM_HSO_GET_PRIVATE (device);
 		priv->netdev_iface = get_network_device (device);
 		if (!priv->netdev_iface) {
diff -rU8 -N nm.trunk/src/modem-manager/nm-gsm-modem-mbm.c NetworkManager_MBM/src/modem-manager/nm-gsm-modem-mbm.c
--- nm.trunk/src/modem-manager/nm-gsm-modem-mbm.c	1970-01-01 01:00:00.000000000 +0100
+++ NetworkManager_MBM/src/modem-manager/nm-gsm-modem-mbm.c	2008-11-24 21:34:33.000000000 +0100
@@ -0,0 +1,327 @@
+/*
+    Additions to NetworkManager, network-manager-applet and modemmanager
+    for supporting Ericsson modules like F3507g.
+
+    Author: Per Hallsmark <per@hallsmark.se>
+            Bjorn Runaker <bjorn.runaker@ericsson.com>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include "nm-gsm-modem-mbm.h"
+#include "nm-device-private.h"
+#include "nm-device-interface.h"
+#include "NetworkManagerSystem.h"
+#include "nm-setting-connection.h"
+#include "nm-setting-gsm.h"
+#include "nm-modem-types.h"
+#include "nm-utils.h"
+
+G_DEFINE_TYPE (NMGsmModemMbm, nm_gsm_modem_mbm, NM_TYPE_GSM_MODEM)
+
+#define NM_GSM_MODEM_MBM_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_GSM_MODEM_MBM, NMGsmModemMbmPrivate))
+
+typedef struct {
+	char *netdev_iface;
+	NMIP4Config  *pending_ip4_config;
+} NMGsmModemMbmPrivate;
+
+#define MBM_SECRETS_TRIES "gsm-secrets-tries"
+
+static NMActStageReturn
+   (*old_real_act_stage1_prepare) (NMDevice *device, NMDeviceStateReason *reason) = NULL;
+
+static char *
+get_network_device (NMDevice *device)
+{
+	char *result = NULL;
+	GError *error = NULL;
+	GValue value = { 0, };
+
+	if (!dbus_g_proxy_call (nm_modem_device_get_proxy (NM_MODEM_DEVICE (device), "org.freedesktop.DBus.Properties"),
+					    "Get", &error,
+					    G_TYPE_STRING, MM_DBUS_INTERFACE_MODEM_GSM_MBM,
+					    G_TYPE_STRING, "NetworkDevice",
+					    G_TYPE_INVALID,
+					    G_TYPE_VALUE, &value,
+					    G_TYPE_INVALID)) {
+		nm_warning ("Could not get MBM device's network interface: %s", error->message);
+		g_error_free (error);
+	} else {
+		if (G_VALUE_HOLDS_STRING (&value))
+			result = g_value_dup_string (&value);
+		else
+			nm_warning ("Could not get MBM device's network interface: wrong type '%s'",
+					  G_VALUE_TYPE_NAME (&value));
+
+		g_value_unset (&value);
+	}
+
+	return result;
+}
+
+NMDevice *
+nm_gsm_modem_mbm_new (const char *path,
+				  const char *data_device,
+				  const char *driver)
+{
+	NMDevice *device;
+
+	g_return_val_if_fail (path != NULL, NULL);
+	g_return_val_if_fail (data_device != NULL, NULL);
+	g_return_val_if_fail (driver != NULL, NULL);
+
+	device = (NMDevice *) g_object_new (NM_TYPE_GSM_MODEM_MBM,
+								 NM_DEVICE_INTERFACE_UDI, path,
+								 NM_DEVICE_INTERFACE_IFACE, data_device,
+								 NM_DEVICE_INTERFACE_DRIVER, driver,
+								 NM_DEVICE_INTERFACE_MANAGED, TRUE,
+                                                                 NM_MODEM_DEVICE_PATH, path,
+								 NULL);
+
+	if (device) {
+		NMGsmModemMbmPrivate *priv;
+
+		priv = NM_GSM_MODEM_MBM_GET_PRIVATE (device);
+		priv->netdev_iface = get_network_device (device);
+		if (!priv->netdev_iface) {
+			g_object_unref (device);
+			device = NULL;
+		}
+	}
+
+	return device;
+}
+
+/*****************************************************************************/
+static NMSetting *
+get_setting (NMGsmModemMbm *modem, GType setting_type)
+{
+	NMActRequest *req;
+	NMSetting *setting = NULL;
+
+	req = nm_device_get_act_request (NM_DEVICE (modem));
+	if (req) {
+		NMConnection *connection;
+
+		connection = nm_act_request_get_connection (req);
+		if (connection)
+			setting = nm_connection_get_setting (connection, setting_type);
+	}
+
+	return setting;
+}
+
+
+static void
+mbm_auth_done (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data)
+{
+	GError *error = NULL;
+
+	if (dbus_g_proxy_end_call (proxy, call_id, &error, G_TYPE_INVALID)) {
+
+
+	} else {
+/* return value not needed		nm_warning ("Setting username
+ * and password failed: %s", error->message);*/
+		g_error_free (error);
+	}
+}
+
+static NMActStageReturn
+real_act_stage1_prepare (NMDevice *device, NMDeviceStateReason *reason)
+{
+	NMActRequest *req;
+	NMConnection *connection;
+	const char *setting_name;
+	GPtrArray *hints = NULL;
+	const char *hint1 = NULL, *hint2 = NULL;
+	guint32 tries;
+	NMSettingGsm *s_gsm;
+
+	g_debug("real_act_stage2_config");
+
+	req = nm_device_get_act_request (device);
+	g_assert (req);
+	connection = nm_act_request_get_connection (req);
+	g_assert (connection);
+
+	setting_name = nm_connection_need_secrets (connection, &hints);
+	g_debug("setting_name = %s", setting_name?setting_name:"");
+
+	if (hints) {
+		if (hints->len > 0)
+			hint1 = g_ptr_array_index (hints, 0);
+		if (hints->len > 1)
+			hint2 = g_ptr_array_index (hints, 1);
+		g_debug("hints->len = %d", hints->len);
+	}
+
+	nm_device_state_changed (device, NM_DEVICE_STATE_NEED_AUTH, NM_DEVICE_STATE_REASON_NONE);
+
+	tries = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (connection), MBM_SECRETS_TRIES));
+	nm_act_request_request_connection_secrets (req,
+		setting_name,
+		tries ? TRUE : FALSE,
+		SECRETS_CALLER_GSM,
+		NM_SETTING_GSM_PASSWORD,
+		NULL);
+
+	g_object_set_data (G_OBJECT (connection), MBM_SECRETS_TRIES, GUINT_TO_POINTER (++tries));
+
+	s_gsm = NM_SETTING_GSM (get_setting (NM_GSM_MODEM_MBM (device), NM_TYPE_SETTING_GSM));
+
+	g_debug("s_gsm->username = %s,  s_gsm->password = %s, s_gsm->pin = %s, bE=%d",  s_gsm->username,  s_gsm->password, s_gsm->pin, s_gsm->lock);
+
+	dbus_g_proxy_begin_call (nm_modem_device_get_proxy (NM_MODEM_DEVICE (device), MM_DBUS_INTERFACE_MODEM_GSM_NETWORK),
+				 "SetUserPass", mbm_auth_done,
+				 device, NULL,
+				 G_TYPE_STRING, s_gsm->username ? s_gsm->username : "",
+				 G_TYPE_STRING, s_gsm->password ? s_gsm->password : "",
+				 G_TYPE_STRING, s_gsm->pin ? s_gsm->pin : "",
+				 G_TYPE_UINT, s_gsm->lock,
+				 G_TYPE_INVALID);
+	if (hints)
+		g_ptr_array_free (hints, TRUE);
+
+
+	g_debug("MBM version of  real_act_stage1_prepare");
+
+	if (old_real_act_stage1_prepare)
+		return (*old_real_act_stage1_prepare)(device, reason);
+	else
+		return NM_ACT_STAGE_RETURN_SUCCESS;
+}
+
+static NMActStageReturn
+real_act_stage2_config (NMDevice *device, NMDeviceStateReason *reason)
+{
+	NMGsmModemMbmPrivate *priv = NM_GSM_MODEM_MBM_GET_PRIVATE (device);
+
+	nm_device_set_ip_iface (device, priv->netdev_iface);
+	g_warning("%s %s: setting ip_iface to %s\n", __FILE__, __FUNCTION__, priv->netdev_iface);
+
+//	nm_device_activate_schedule_stage3_ip_config_start (device);
+
+	return NM_ACT_STAGE_RETURN_SUCCESS;
+}
+
+#if 0
+static NMActStageReturn
+real_act_stage4_get_ip4_config (NMDevice *device,
+                                NMIP4Config **config,
+                                NMDeviceStateReason *reason)
+{
+	NMGsmModemMbmPrivate *priv = NM_GSM_MODEM_MBM_GET_PRIVATE (device);
+
+	*config = priv->pending_ip4_config;
+        priv->pending_ip4_config = NULL;
+
+        return NM_ACT_STAGE_RETURN_SUCCESS;
+}
+#endif
+
+static void
+real_deactivate (NMDevice *device)
+{
+	NMGsmModemMbmPrivate *priv = NM_GSM_MODEM_MBM_GET_PRIVATE (device);
+
+	if (priv->pending_ip4_config) {
+                g_object_unref (priv->pending_ip4_config);
+                priv->pending_ip4_config = NULL;
+        }
+
+	if (priv->netdev_iface) {
+		nm_system_device_flush_ip4_routes_with_iface (priv->netdev_iface);
+		nm_system_device_flush_ip4_addresses_with_iface (priv->netdev_iface);
+		nm_system_device_set_up_down_with_iface (priv->netdev_iface, FALSE, NULL);
+	}
+	nm_device_set_ip_iface (device, NULL);
+
+	if (NM_DEVICE_CLASS (nm_gsm_modem_mbm_parent_class)->deactivate)
+		NM_DEVICE_CLASS (nm_gsm_modem_mbm_parent_class)->deactivate (device);
+}
+
+static gboolean
+real_hw_is_up (NMDevice *device)
+{
+	NMGsmModemMbmPrivate *priv = NM_GSM_MODEM_MBM_GET_PRIVATE (device);
+
+	if (priv->netdev_iface)
+		return nm_system_device_is_up_with_iface (priv->netdev_iface);
+
+	return TRUE;
+}
+
+static gboolean
+real_hw_bring_up (NMDevice *device, gboolean *no_firmware)
+{
+	NMGsmModemMbmPrivate *priv = NM_GSM_MODEM_MBM_GET_PRIVATE (device);
+
+	if (priv->netdev_iface)
+		return nm_system_device_set_up_down_with_iface (priv->netdev_iface, TRUE, no_firmware);
+
+	return TRUE;
+}
+
+static void
+real_connect (NMModemDevice *modem, const char *number)
+{
+	nm_device_activate_schedule_stage2_device_config (NM_DEVICE (modem));
+}
+
+/*****************************************************************************/
+
+static void
+nm_gsm_modem_mbm_init (NMGsmModemMbm *self)
+{
+}
+
+static void
+finalize (GObject *object)
+{
+	NMGsmModemMbmPrivate *priv = NM_GSM_MODEM_MBM_GET_PRIVATE (object);
+
+	g_free (priv->netdev_iface);
+
+	G_OBJECT_CLASS (nm_gsm_modem_mbm_parent_class)->finalize (object);
+}
+
+static void
+nm_gsm_modem_mbm_class_init (NMGsmModemMbmClass *klass)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS (klass);
+	NMDeviceClass *device_class = NM_DEVICE_CLASS (klass);
+	NMModemDeviceClass *modem_class = NM_MODEM_DEVICE_CLASS (klass);
+
+	g_type_class_add_private (object_class, sizeof (NMGsmModemMbmPrivate));
+
+	object_class->finalize = finalize;
+
+	old_real_act_stage1_prepare = device_class->act_stage1_prepare;
+	device_class->act_stage1_prepare = real_act_stage1_prepare;
+	
+	device_class->act_stage2_config = real_act_stage2_config;
+#if 0
+	device_class->act_stage4_get_ip4_config = real_act_stage4_get_ip4_config;
+#endif
+	device_class->deactivate = real_deactivate;
+	device_class->hw_is_up = real_hw_is_up;
+	device_class->hw_bring_up = real_hw_bring_up;
+
+	modem_class->connect = real_connect;
+}
diff -rU8 -N nm.trunk/src/modem-manager/nm-gsm-modem-mbm.h NetworkManager_MBM/src/modem-manager/nm-gsm-modem-mbm.h
--- nm.trunk/src/modem-manager/nm-gsm-modem-mbm.h	1970-01-01 01:00:00.000000000 +0100
+++ NetworkManager_MBM/src/modem-manager/nm-gsm-modem-mbm.h	2008-11-24 21:34:34.000000000 +0100
@@ -0,0 +1,53 @@
+/*
+    Additions to NetworkManager, network-manager-applet and modemmanager
+    for supporting Ericsson modules like F3507g.
+
+    Author: Per Hallsmark <per@hallsmark.se>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#ifndef NM_GSM_MODEM_MBM_H
+#define NM_GSM_MODEM_MBM_H
+
+#include <nm-gsm-modem.h>
+
+G_BEGIN_DECLS
+
+#define NM_TYPE_GSM_MODEM_MBM            (nm_gsm_modem_mbm_get_type ())
+#define NM_GSM_MODEM_MBM(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_GSM_MODEM_MBM, NMGsmModemMbm))
+#define NM_GSM_MODEM_MBM_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass),  NM_TYPE_GSM_MODEM_MBM, NMGsmModemMbmClass))
+#define NM_IS_GSM_MODEM_MBM(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_GSM_MODEM_MBM))
+#define NM_IS_GSM_MODEM_MBM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),  NM_TYPE_GSM_MODEM_MBM))
+#define NM_GSM_MODEM_MBM_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj),  NM_TYPE_GSM_MODEM_MBM, NMGsmModemMbmClass))
+
+typedef struct {
+	NMGsmModem parent;
+} NMGsmModemMbm;
+
+typedef struct {
+	NMGsmModemClass parent;
+} NMGsmModemMbmClass;
+
+GType nm_gsm_modem_mbm_get_type (void);
+
+NMDevice *nm_gsm_modem_mbm_new (const char *path, const char *data_device,
+						  const char *driver);
+
+G_END_DECLS
+
+#endif /* NM_GSM_MODEM_MBM_H */
diff -rU8 -N nm.trunk/src/modem-manager/nm-modem-device.c NetworkManager_MBM/src/modem-manager/nm-modem-device.c
--- nm.trunk/src/modem-manager/nm-modem-device.c	2008-11-25 18:48:48.000000000 +0100
+++ NetworkManager_MBM/src/modem-manager/nm-modem-device.c	2008-11-24 21:34:33.000000000 +0100
@@ -189,28 +189,30 @@
 
 		*reason = NM_DEVICE_STATE_REASON_PPP_START_FAILED;
 		ret = NM_ACT_STAGE_RETURN_FAILURE;
 	}
 
 	return ret;
 }
 
+#if 0
 static NMActStageReturn
 real_act_stage4_get_ip4_config (NMDevice *device,
                                 NMIP4Config **config,
                                 NMDeviceStateReason *reason)
 {
 	NMModemDevicePrivate *priv = NM_MODEM_DEVICE_GET_PRIVATE (device);
 
 	*config = priv->pending_ip4_config;
 	priv->pending_ip4_config = NULL;
 
 	return NM_ACT_STAGE_RETURN_SUCCESS;
 }
+#endif
 
 static void
 real_deactivate_quickly (NMDevice *device)
 {
 	NMModemDevicePrivate *priv = NM_MODEM_DEVICE_GET_PRIVATE (device);
 
 	nm_device_set_ip_iface (device, NULL);
 
@@ -334,17 +336,17 @@
 														    n_construct_params,
 														    construct_params);
 	if (!object)
 		return NULL;
 
 	priv = NM_MODEM_DEVICE_GET_PRIVATE (object);
 
 	if (!priv->path) {
-		g_warning ("DBus path not provided");
+		g_warning ("%s: DBus path not provided", __FILE__);
 		goto err;
 	}
 
 	priv->proxy = dbus_g_proxy_new_for_name (nm_dbus_manager_get_connection (priv->dbus_mgr),
 									 MM_DBUS_SERVICE, priv->path, MM_DBUS_INTERFACE_MODEM);
 
 	g_signal_connect (object, "state-changed", G_CALLBACK (device_state_changed), object);
 
@@ -418,17 +420,19 @@
 	/* Virtual methods */
 	object_class->constructor = constructor;
 	object_class->set_property = set_property;
 	object_class->get_property = get_property;
 	object_class->finalize = finalize;
 
 	device_class->get_generic_capabilities = real_get_generic_capabilities;
 	device_class->act_stage2_config = real_act_stage2_config;
+#if 0
 	device_class->act_stage4_get_ip4_config = real_act_stage4_get_ip4_config;
+#endif
 	device_class->deactivate_quickly = real_deactivate_quickly;
 
 	klass->connect = real_connect;
 
 	/* Properties */
 	g_object_class_install_property
 		(object_class, PROP_PATH,
 		 g_param_spec_string (NM_MODEM_DEVICE_PATH,
diff -rU8 -N nm.trunk/src/modem-manager/nm-modem-manager.c NetworkManager_MBM/src/modem-manager/nm-modem-manager.c
--- nm.trunk/src/modem-manager/nm-modem-manager.c	2008-11-25 18:48:48.000000000 +0100
+++ NetworkManager_MBM/src/modem-manager/nm-modem-manager.c	2008-11-24 21:34:33.000000000 +0100
@@ -1,15 +1,16 @@
 /* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */
 
 #include <string.h>
 #include "nm-modem-manager.h"
 #include "nm-modem-device.h"
 #include "nm-gsm-modem.h"
 #include "nm-gsm-modem-hso.h"
+#include "nm-gsm-modem-mbm.h"
 #include "nm-cdma-modem.h"
 #include "nm-dbus-manager.h"
 #include "nm-utils.h"
 #include "nm-modem-types.h"
 
 #define MODEM_POKE_INTERVAL 120000
 
 G_DEFINE_TYPE (NMModemManager, nm_modem_manager, G_TYPE_OBJECT)
@@ -143,16 +144,24 @@
 	if (!data_device || !strlen (data_device)) {
 		nm_warning ("Modem with path %s has unknown data device, ignoring", path);
 		return;
 	}
 
 	if (modem_type == MM_MODEM_TYPE_GSM) {
 		if (!strcmp (driver, "hso"))
 			device = nm_gsm_modem_hso_new (path, data_device, driver);
+		else if (!strcmp (driver, "mbm"))
+			device = nm_gsm_modem_mbm_new (path, data_device, driver);
+#if 1
+/* this should really not be here, remove when patches which announce themself as mb
+   instead of mbm stop floating around */
+		else if (!strcmp (driver, "mb"))
+			device = nm_gsm_modem_mbm_new (path, data_device, driver);
+#endif
 		else
 			device = nm_gsm_modem_new (path, data_device, driver);
 	} else if (modem_type == MM_MODEM_TYPE_CDMA)
 		device = nm_cdma_modem_new (path, data_device, driver);
 	else
 		g_error ("Invalid modem type");
 
 	g_free (data_device);
@@ -226,17 +235,17 @@
 			g_free (path);
 		}
 
 		g_ptr_array_free (modems, TRUE);
 	}
 }
 
 static void
-modem_manager_appeared (NMModemManager *self)
+modem_manager_appeared (NMModemManager *self, gboolean enumerate_devices)
 {
 	NMModemManagerPrivate *priv = NM_MODEM_MANAGER_GET_PRIVATE (self);
 
 	if (priv->poke_id) {
 		g_source_remove (priv->poke_id);
 		priv->poke_id = 0;
 	}
 
@@ -248,17 +257,18 @@
 						    G_CALLBACK (modem_added), self,
 						    NULL);
 
 	dbus_g_proxy_add_signal (priv->proxy, "DeviceRemoved", G_TYPE_STRING, G_TYPE_INVALID);
 	dbus_g_proxy_connect_signal (priv->proxy, "DeviceRemoved",
 						    G_CALLBACK (modem_removed), self,
 						    NULL);
 
-	dbus_g_proxy_begin_call (priv->proxy, "EnumerateDevices", enumerate_devices_done, self, NULL, G_TYPE_INVALID);
+	if (enumerate_devices)
+		dbus_g_proxy_begin_call (priv->proxy, "EnumerateDevices", enumerate_devices_done, self, NULL, G_TYPE_INVALID);
 }
 
 static gboolean
 remove_one_modem (gpointer key, gpointer value, gpointer user_data)
 {
 	g_signal_emit (user_data, signals[DEVICE_REMOVED], 0, value);
 
 	return TRUE;
@@ -293,20 +303,23 @@
 
 	/* Can't handle the signal if its not from the modem service */
 	if (strcmp (MM_DBUS_SERVICE, name) != 0)
 		return;
 
 	old_owner_good = (old_owner && strlen (old_owner));
 	new_owner_good = (new_owner && strlen (new_owner));
 
-	if (!old_owner_good && new_owner_good)
+	if (!old_owner_good && new_owner_good) {
+		nm_info ("modem manager appeared");
+		modem_manager_appeared (NM_MODEM_MANAGER (user_data), FALSE);
+	} else if (old_owner_good && !new_owner_good) {
+		nm_info ("modem manager disappeared");
 		modem_manager_disappeared (NM_MODEM_MANAGER (user_data));
-	else if (old_owner_good && !new_owner_good)
-		modem_manager_appeared (NM_MODEM_MANAGER (user_data));
+	}
 }
 
 /*******************************************************/
 
 static void
 nm_modem_manager_init (NMModemManager *self)
 {
 	NMModemManagerPrivate *priv = NM_MODEM_MANAGER_GET_PRIVATE (self);
@@ -314,17 +327,17 @@
 	priv->modems = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
 	priv->dbus_mgr = nm_dbus_manager_get ();
 
 	g_signal_connect (priv->dbus_mgr, "name-owner-changed",
 	                  G_CALLBACK (nm_modem_manager_name_owner_changed),
 	                  self);
 
 	if (nm_dbus_manager_name_has_owner (priv->dbus_mgr, MM_DBUS_SERVICE))
-		modem_manager_appeared (self);
+		modem_manager_appeared (self, TRUE);
 	else
 		modem_manager_disappeared (self);
 }
 
 static void
 dispose (GObject *object)
 {
 	NMModemManagerPrivate *priv = NM_MODEM_MANAGER_GET_PRIVATE (object);
diff -rU8 -N nm.trunk/src/modem-manager/nm-modem-types.h NetworkManager_MBM/src/modem-manager/nm-modem-types.h
--- nm.trunk/src/modem-manager/nm-modem-types.h	2008-11-25 18:48:48.000000000 +0100
+++ NetworkManager_MBM/src/modem-manager/nm-modem-types.h	2008-11-24 21:34:34.000000000 +0100
@@ -7,16 +7,17 @@
 #define MM_DBUS_PATH                 "/org/freedesktop/ModemManager"
 #define MM_DBUS_INTERFACE            "org.freedesktop.ModemManager"
 #define MM_DBUS_INTERFACE_MODEM      "org.freedesktop.ModemManager.Modem"
 #define MM_DBUS_INTERFACE_MODEM_CDMA "org.freedesktop.ModemManager.Modem.Cdma"
 
 #define MM_DBUS_INTERFACE_MODEM_GSM_CARD    "org.freedesktop.ModemManager.Modem.Gsm.Card"
 #define MM_DBUS_INTERFACE_MODEM_GSM_NETWORK "org.freedesktop.ModemManager.Modem.Gsm.Network"
 #define MM_DBUS_INTERFACE_MODEM_GSM_HSO     "org.freedesktop.ModemManager.Modem.Gsm.Hso"
+#define MM_DBUS_INTERFACE_MODEM_GSM_MBM     "org.freedesktop.ModemManager.Modem.Gsm.Mbm"
 
 #define MM_MODEM_TYPE_UNKNOWN  0
 #define MM_MODEM_TYPE_GSM      1
 #define MM_MODEM_TYPE_CDMA     2
 
 /* Errors */
 
 #define MM_SERIAL_OPEN_FAILED MM_DBUS_INTERFACE_MODEM ".SerialOpenFailed"
