Implement DCD disabling for serial base class.

Turn DCD detection off for certain Huawei modems that don't report it
correctly.
This commit is contained in:
Tambet Ingo
2009-01-13 11:27:41 +02:00
parent 50d2a8b80c
commit 6018ff81ba
3 changed files with 51 additions and 10 deletions

View File

@@ -60,6 +60,21 @@ list_supported_udis (MMPlugin *plugin, LibHalContext *hal_ctx)
return supported; return supported;
} }
static int
get_product (LibHalContext *hal_ctx, const char *udi)
{
char *parent_udi;
int product = 0;
parent_udi = libhal_device_get_property_string (hal_ctx, udi, "info.parent", NULL);
if (parent_udi) {
product = libhal_device_get_property_int (hal_ctx, parent_udi, "usb.product_id", NULL);
libhal_free_string (parent_udi);
}
return product;
}
static gboolean static gboolean
supports_udi (MMPlugin *plugin, LibHalContext *hal_ctx, const char *udi) supports_udi (MMPlugin *plugin, LibHalContext *hal_ctx, const char *udi)
{ {
@@ -78,7 +93,7 @@ supports_udi (MMPlugin *plugin, LibHalContext *hal_ctx, const char *udi)
int product; int product;
vendor = libhal_device_get_property_int (hal_ctx, parent_udi, "usb.vendor_id", NULL); vendor = libhal_device_get_property_int (hal_ctx, parent_udi, "usb.vendor_id", NULL);
product = libhal_device_get_property_int (hal_ctx, parent_udi, "usb.product_id", NULL); product = get_product (hal_ctx, udi);
if (vendor == 0x12d1 && (product == 0x1001 || product == 0x1003 || product == 0x1004)) if (vendor == 0x12d1 && (product == 0x1001 || product == 0x1003 || product == 0x1004))
supported = TRUE; supported = TRUE;
@@ -174,13 +189,17 @@ create_modem (MMPlugin *plugin, LibHalContext *hal_ctx, const char *udi)
driver = get_driver_name (hal_ctx, udi); driver = get_driver_name (hal_ctx, udi);
g_return_val_if_fail (driver != NULL, NULL); g_return_val_if_fail (driver != NULL, NULL);
monitor_device = get_monitor_device (hal_ctx, udi); if (get_product (hal_ctx, udi) == 0x1001) {
g_debug ("Got monitor device: %s", monitor_device); /* This modem is handled by generic GSM device with carrier detection turned off */
modem = mm_generic_gsm_new (data_device, driver);
modem = MM_MODEM (mm_modem_huawei_new (data_device, monitor_device, driver)); g_object_set (G_OBJECT (modem), MM_SERIAL_CARRIER_DETECT, FALSE, NULL);
} else {
monitor_device = get_monitor_device (hal_ctx, udi);
modem = mm_modem_huawei_new (data_device, monitor_device, driver);
libhal_free_string (monitor_device);
}
libhal_free_string (data_device); libhal_free_string (data_device);
libhal_free_string (monitor_device);
libhal_free_string (driver); libhal_free_string (driver);
return modem; return modem;

View File

@@ -29,6 +29,7 @@ enum {
PROP_PARITY, PROP_PARITY,
PROP_STOPBITS, PROP_STOPBITS,
PROP_SEND_DELAY, PROP_SEND_DELAY,
PROP_CARRIER_DETECT,
LAST_PROP LAST_PROP
}; };
@@ -57,6 +58,7 @@ typedef struct {
char parity; char parity;
guint stopbits; guint stopbits;
guint64 send_delay; guint64 send_delay;
gboolean carrier_detect;
guint queue_schedule; guint queue_schedule;
guint watch_id; guint watch_id;
@@ -688,16 +690,20 @@ mm_serial_flash (MMSerial *self,
gboolean gboolean
mm_serial_is_connected (MMSerial *self) mm_serial_is_connected (MMSerial *self)
{ {
int fd; MMSerialPrivate *priv;
int mcs = 0; int mcs = 0;
g_return_val_if_fail (MM_IS_SERIAL (self), FALSE); g_return_val_if_fail (MM_IS_SERIAL (self), FALSE);
fd = MM_SERIAL_GET_PRIVATE (self)->fd; priv = MM_SERIAL_GET_PRIVATE (self);
if (fd == 0)
if (!priv->carrier_detect)
return FALSE; return FALSE;
if (ioctl (fd, TIOCMGET, &mcs) < 0) if (priv->fd == 0)
return FALSE;
if (ioctl (priv->fd, TIOCMGET, &mcs) < 0)
return FALSE; return FALSE;
return mcs & TIOCM_CAR ? TRUE : FALSE; return mcs & TIOCM_CAR ? TRUE : FALSE;
@@ -715,6 +721,7 @@ mm_serial_init (MMSerial *self)
priv->parity = 'n'; priv->parity = 'n';
priv->stopbits = 1; priv->stopbits = 1;
priv->send_delay = 1000; priv->send_delay = 1000;
priv->carrier_detect = TRUE;
priv->queue = g_queue_new (); priv->queue = g_queue_new ();
priv->command = g_string_new_len ("AT", SERIAL_BUF_SIZE); priv->command = g_string_new_len ("AT", SERIAL_BUF_SIZE);
@@ -772,6 +779,9 @@ set_property (GObject *object, guint prop_id,
case PROP_SEND_DELAY: case PROP_SEND_DELAY:
priv->send_delay = g_value_get_uint64 (value); priv->send_delay = g_value_get_uint64 (value);
break; break;
case PROP_CARRIER_DETECT:
priv->carrier_detect = g_value_get_boolean (value);
break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break; break;
@@ -803,6 +813,9 @@ get_property (GObject *object, guint prop_id,
case PROP_SEND_DELAY: case PROP_SEND_DELAY:
g_value_set_uint64 (value, priv->send_delay); g_value_set_uint64 (value, priv->send_delay);
break; break;
case PROP_CARRIER_DETECT:
g_value_set_boolean (value, priv->carrier_detect);
break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break; break;
@@ -889,4 +902,12 @@ mm_serial_class_init (MMSerialClass *klass)
"Send delay", "Send delay",
0, G_MAXUINT64, 0, 0, G_MAXUINT64, 0,
G_PARAM_READWRITE)); G_PARAM_READWRITE));
g_object_class_install_property
(object_class, PROP_CARRIER_DETECT,
g_param_spec_boolean (MM_SERIAL_CARRIER_DETECT,
"CarrierDetect",
"Has carrier detect",
TRUE,
G_PARAM_READWRITE));
} }

View File

@@ -19,6 +19,7 @@
#define MM_SERIAL_PARITY "parity" #define MM_SERIAL_PARITY "parity"
#define MM_SERIAL_STOPBITS "stopbits" #define MM_SERIAL_STOPBITS "stopbits"
#define MM_SERIAL_SEND_DELAY "send-delay" #define MM_SERIAL_SEND_DELAY "send-delay"
#define MM_SERIAL_CARRIER_DETECT "carrier-detect"
typedef struct _MMSerial MMSerial; typedef struct _MMSerial MMSerial;
typedef struct _MMSerialClass MMSerialClass; typedef struct _MMSerialClass MMSerialClass;