serial: rework 'connected' logic
So many modems just don't implement carrier detect that it makes the previous 'connected' logic useless, so base it off connect/disconnect and fix up a few places that didn't check connect status before trying to send commands. Also ensure the serial port is unlocked for PPP to use when connected.
This commit is contained in:
@@ -455,7 +455,7 @@ enable (MMModem *modem,
|
|||||||
} else {
|
} else {
|
||||||
mm_serial_port_queue_command (primary, "+CREG=0", 100, NULL, NULL);
|
mm_serial_port_queue_command (primary, "+CREG=0", 100, NULL, NULL);
|
||||||
mm_generic_gsm_pending_registration_stop (MM_GENERIC_GSM (modem));
|
mm_generic_gsm_pending_registration_stop (MM_GENERIC_GSM (modem));
|
||||||
if (mm_serial_port_is_connected (primary))
|
if (mm_port_get_connected (MM_PORT (primary)))
|
||||||
mm_serial_port_flash (primary, 1000, disable_flash_done, info);
|
mm_serial_port_flash (primary, 1000, disable_flash_done, info);
|
||||||
else
|
else
|
||||||
disable_flash_done (primary, info);
|
disable_flash_done (primary, info);
|
||||||
|
@@ -133,7 +133,7 @@ enable (MMModem *modem,
|
|||||||
g_assert (primary);
|
g_assert (primary);
|
||||||
|
|
||||||
if (!do_enable) {
|
if (!do_enable) {
|
||||||
if (mm_serial_port_is_connected (primary))
|
if (mm_port_get_connected (MM_PORT (primary)))
|
||||||
mm_serial_port_flash (primary, 1000, disable_flash_done, info);
|
mm_serial_port_flash (primary, 1000, disable_flash_done, info);
|
||||||
else
|
else
|
||||||
disable_flash_done (primary, info);
|
disable_flash_done (primary, info);
|
||||||
|
@@ -115,7 +115,7 @@ enable (MMModem *modem,
|
|||||||
g_assert (primary);
|
g_assert (primary);
|
||||||
|
|
||||||
if (!do_enable) {
|
if (!do_enable) {
|
||||||
if (mm_serial_port_is_connected (primary))
|
if (mm_port_get_connected (MM_PORT (primary)))
|
||||||
mm_serial_port_flash (primary, 1000, disable_flash_done, info);
|
mm_serial_port_flash (primary, 1000, disable_flash_done, info);
|
||||||
else
|
else
|
||||||
disable_flash_done (primary, info);
|
disable_flash_done (primary, info);
|
||||||
|
@@ -134,7 +134,7 @@ enable (MMModem *modem,
|
|||||||
g_assert (primary);
|
g_assert (primary);
|
||||||
|
|
||||||
if (!do_enable) {
|
if (!do_enable) {
|
||||||
if (mm_serial_port_is_connected (primary))
|
if (mm_port_get_connected (MM_PORT (primary)))
|
||||||
mm_serial_port_flash (primary, 1000, disable_flash_done, info);
|
mm_serial_port_flash (primary, 1000, disable_flash_done, info);
|
||||||
else
|
else
|
||||||
disable_flash_done (primary, info);
|
disable_flash_done (primary, info);
|
||||||
|
@@ -54,6 +54,7 @@ mm_modem_error_get_type (void)
|
|||||||
static const GEnumValue values[] = {
|
static const GEnumValue values[] = {
|
||||||
ENUM_ENTRY (MM_MODEM_ERROR_GENERAL, "General"),
|
ENUM_ENTRY (MM_MODEM_ERROR_GENERAL, "General"),
|
||||||
ENUM_ENTRY (MM_MODEM_ERROR_OPERATION_NOT_SUPPORTED, "OperationNotSupported"),
|
ENUM_ENTRY (MM_MODEM_ERROR_OPERATION_NOT_SUPPORTED, "OperationNotSupported"),
|
||||||
|
ENUM_ENTRY (MM_MODEM_ERROR_CONNECTED, "Connected"),
|
||||||
{ 0, 0, 0 }
|
{ 0, 0, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -20,7 +20,8 @@ GType mm_serial_error_get_type (void);
|
|||||||
|
|
||||||
enum {
|
enum {
|
||||||
MM_MODEM_ERROR_GENERAL = 0,
|
MM_MODEM_ERROR_GENERAL = 0,
|
||||||
MM_MODEM_ERROR_OPERATION_NOT_SUPPORTED = 1
|
MM_MODEM_ERROR_OPERATION_NOT_SUPPORTED = 1,
|
||||||
|
MM_MODEM_ERROR_CONNECTED = 2
|
||||||
};
|
};
|
||||||
|
|
||||||
#define MM_MODEM_ERROR (mm_modem_error_quark ())
|
#define MM_MODEM_ERROR (mm_modem_error_quark ())
|
||||||
|
@@ -20,6 +20,7 @@ typedef struct {
|
|||||||
char *plugin;
|
char *plugin;
|
||||||
char *device;
|
char *device;
|
||||||
|
|
||||||
|
guint32 signal_quality;
|
||||||
guint32 ip_method;
|
guint32 ip_method;
|
||||||
gboolean valid;
|
gboolean valid;
|
||||||
|
|
||||||
@@ -238,10 +239,15 @@ dial_done (MMSerialPort *port,
|
|||||||
GError *error,
|
GError *error,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
|
MMGenericCdmaPrivate *priv;
|
||||||
MMCallbackInfo *info = (MMCallbackInfo *) user_data;
|
MMCallbackInfo *info = (MMCallbackInfo *) user_data;
|
||||||
|
|
||||||
if (error)
|
if (error)
|
||||||
info->error = g_error_copy (error);
|
info->error = g_error_copy (error);
|
||||||
|
else {
|
||||||
|
priv = MM_GENERIC_CDMA_GET_PRIVATE (info->modem);
|
||||||
|
mm_port_set_connected (priv->data, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
mm_callback_info_schedule (info);
|
mm_callback_info_schedule (info);
|
||||||
}
|
}
|
||||||
@@ -265,7 +271,12 @@ connect (MMModem *modem,
|
|||||||
static void
|
static void
|
||||||
disconnect_flash_done (MMSerialPort *port, gpointer user_data)
|
disconnect_flash_done (MMSerialPort *port, gpointer user_data)
|
||||||
{
|
{
|
||||||
mm_callback_info_schedule ((MMCallbackInfo *) user_data);
|
MMCallbackInfo *info = (MMCallbackInfo *) user_data;
|
||||||
|
MMGenericCdmaPrivate *priv;
|
||||||
|
|
||||||
|
priv = MM_GENERIC_CDMA_GET_PRIVATE (info->modem);
|
||||||
|
mm_port_set_connected (priv->data, FALSE);
|
||||||
|
mm_callback_info_schedule (info);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -370,6 +381,7 @@ get_signal_quality_done (MMSerialPort *port,
|
|||||||
GError *error,
|
GError *error,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
|
MMGenericCdmaPrivate *priv;
|
||||||
MMCallbackInfo *info = (MMCallbackInfo *) user_data;
|
MMCallbackInfo *info = (MMCallbackInfo *) user_data;
|
||||||
char *reply = response->str;
|
char *reply = response->str;
|
||||||
|
|
||||||
@@ -391,6 +403,8 @@ get_signal_quality_done (MMSerialPort *port,
|
|||||||
/* Normalize the quality */
|
/* Normalize the quality */
|
||||||
quality = CLAMP (quality, 0, 31) * 100 / 31;
|
quality = CLAMP (quality, 0, 31) * 100 / 31;
|
||||||
|
|
||||||
|
priv = MM_GENERIC_CDMA_GET_PRIVATE (info->modem);
|
||||||
|
priv->signal_quality = quality;
|
||||||
mm_callback_info_set_result (info, GUINT_TO_POINTER (quality), NULL);
|
mm_callback_info_set_result (info, GUINT_TO_POINTER (quality), NULL);
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
@@ -408,6 +422,14 @@ get_signal_quality (MMModemCdma *modem,
|
|||||||
{
|
{
|
||||||
MMGenericCdmaPrivate *priv = MM_GENERIC_CDMA_GET_PRIVATE (modem);
|
MMGenericCdmaPrivate *priv = MM_GENERIC_CDMA_GET_PRIVATE (modem);
|
||||||
MMCallbackInfo *info;
|
MMCallbackInfo *info;
|
||||||
|
gboolean connected;
|
||||||
|
|
||||||
|
connected = mm_port_get_connected (MM_PORT (priv->primary));
|
||||||
|
if (connected && !priv->secondary) {
|
||||||
|
g_message ("Returning saved signal quality %d", priv->signal_quality);
|
||||||
|
callback (MM_MODEM (modem), priv->signal_quality, NULL, user_data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
info = mm_callback_info_uint_new (MM_MODEM (modem), callback, user_data);
|
info = mm_callback_info_uint_new (MM_MODEM (modem), callback, user_data);
|
||||||
/* Prefer secondary port for signal strength */
|
/* Prefer secondary port for signal strength */
|
||||||
@@ -443,6 +465,17 @@ get_esn (MMModemCdma *modem,
|
|||||||
{
|
{
|
||||||
MMGenericCdmaPrivate *priv = MM_GENERIC_CDMA_GET_PRIVATE (modem);
|
MMGenericCdmaPrivate *priv = MM_GENERIC_CDMA_GET_PRIVATE (modem);
|
||||||
MMCallbackInfo *info;
|
MMCallbackInfo *info;
|
||||||
|
gboolean connected;
|
||||||
|
GError *error;
|
||||||
|
|
||||||
|
connected = mm_port_get_connected (MM_PORT (priv->primary));
|
||||||
|
if (connected && !priv->secondary) {
|
||||||
|
error = g_error_new_literal (MM_MODEM_ERROR, MM_MODEM_ERROR_CONNECTED,
|
||||||
|
"Cannot get ESN while connected");
|
||||||
|
callback (MM_MODEM (modem), NULL, error, user_data);
|
||||||
|
g_error_free (error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
info = mm_callback_info_string_new (MM_MODEM (modem), callback, user_data);
|
info = mm_callback_info_string_new (MM_MODEM (modem), callback, user_data);
|
||||||
mm_serial_port_queue_command_cached (priv->primary, "+GSN", 3, get_string_done, info);
|
mm_serial_port_queue_command_cached (priv->primary, "+GSN", 3, get_string_done, info);
|
||||||
@@ -522,6 +555,17 @@ get_serving_system (MMModemCdma *modem,
|
|||||||
{
|
{
|
||||||
MMGenericCdmaPrivate *priv = MM_GENERIC_CDMA_GET_PRIVATE (modem);
|
MMGenericCdmaPrivate *priv = MM_GENERIC_CDMA_GET_PRIVATE (modem);
|
||||||
MMCallbackInfo *info;
|
MMCallbackInfo *info;
|
||||||
|
gboolean connected;
|
||||||
|
GError *error;
|
||||||
|
|
||||||
|
connected = mm_port_get_connected (MM_PORT (priv->primary));
|
||||||
|
if (connected && !priv->secondary) {
|
||||||
|
error = g_error_new_literal (MM_MODEM_ERROR, MM_MODEM_ERROR_CONNECTED,
|
||||||
|
"Cannot get serving system while connected");
|
||||||
|
callback (modem, 0, 0, 0, error, user_data);
|
||||||
|
g_error_free (error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
info = mm_callback_info_new_full (MM_MODEM (modem),
|
info = mm_callback_info_new_full (MM_MODEM (modem),
|
||||||
serving_system_invoke,
|
serving_system_invoke,
|
||||||
|
@@ -23,7 +23,6 @@ typedef struct {
|
|||||||
|
|
||||||
gboolean valid;
|
gboolean valid;
|
||||||
|
|
||||||
char *data_device;
|
|
||||||
char *oper_code;
|
char *oper_code;
|
||||||
char *oper_name;
|
char *oper_name;
|
||||||
guint32 ip_method;
|
guint32 ip_method;
|
||||||
@@ -406,7 +405,7 @@ enable (MMModem *modem,
|
|||||||
if (!do_enable) {
|
if (!do_enable) {
|
||||||
mm_generic_gsm_pending_registration_stop (MM_GENERIC_GSM (modem));
|
mm_generic_gsm_pending_registration_stop (MM_GENERIC_GSM (modem));
|
||||||
|
|
||||||
if (mm_serial_port_is_connected (priv->primary))
|
if (mm_port_get_connected (MM_PORT (priv->primary)))
|
||||||
mm_serial_port_flash (priv->primary, 1000, disable_flash_done, info);
|
mm_serial_port_flash (priv->primary, 1000, disable_flash_done, info);
|
||||||
else
|
else
|
||||||
disable_flash_done (priv->primary, info);
|
disable_flash_done (priv->primary, info);
|
||||||
@@ -976,17 +975,19 @@ connect_done (MMSerialPort *port,
|
|||||||
GError *error,
|
GError *error,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
MMGenericGsmPrivate *priv;
|
|
||||||
MMCallbackInfo *info = (MMCallbackInfo *) user_data;
|
MMCallbackInfo *info = (MMCallbackInfo *) user_data;
|
||||||
|
MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (info->modem);
|
||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
info->error = g_error_copy (error);
|
info->error = g_error_copy (error);
|
||||||
/* Try to get more information why it failed */
|
/* Try to get more information why it failed */
|
||||||
priv = MM_GENERIC_GSM_GET_PRIVATE (info->modem);
|
priv = MM_GENERIC_GSM_GET_PRIVATE (info->modem);
|
||||||
mm_serial_port_queue_command (priv->primary, "+CEER", 3, connect_report_done, info);
|
mm_serial_port_queue_command (priv->primary, "+CEER", 3, connect_report_done, info);
|
||||||
} else
|
} else {
|
||||||
/* Done */
|
/* Done */
|
||||||
|
mm_port_set_connected (priv->data, TRUE);
|
||||||
mm_callback_info_schedule (info);
|
mm_callback_info_schedule (info);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -1023,7 +1024,11 @@ connect (MMModem *modem,
|
|||||||
static void
|
static void
|
||||||
disconnect_flash_done (MMSerialPort *port, gpointer user_data)
|
disconnect_flash_done (MMSerialPort *port, gpointer user_data)
|
||||||
{
|
{
|
||||||
mm_callback_info_schedule ((MMCallbackInfo *) user_data);
|
MMCallbackInfo *info = (MMCallbackInfo *) user_data;
|
||||||
|
MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (info->modem);
|
||||||
|
|
||||||
|
mm_port_set_connected (priv->data, FALSE);
|
||||||
|
mm_callback_info_schedule (info);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -1361,7 +1366,7 @@ get_signal_quality (MMModemGsmNetwork *modem,
|
|||||||
MMCallbackInfo *info;
|
MMCallbackInfo *info;
|
||||||
gboolean connected;
|
gboolean connected;
|
||||||
|
|
||||||
connected = mm_serial_port_is_connected (priv->primary);
|
connected = mm_port_get_connected (MM_PORT (priv->primary));
|
||||||
if (connected && !priv->secondary) {
|
if (connected && !priv->secondary) {
|
||||||
g_message ("Returning saved signal quality %d", priv->signal_quality);
|
g_message ("Returning saved signal quality %d", priv->signal_quality);
|
||||||
callback (MM_MODEM (modem), priv->signal_quality, NULL, user_data);
|
callback (MM_MODEM (modem), priv->signal_quality, NULL, user_data);
|
||||||
@@ -1408,14 +1413,14 @@ sms_send (MMModemGsmSms *modem,
|
|||||||
info = mm_callback_info_new (MM_MODEM (modem), callback, user_data);
|
info = mm_callback_info_new (MM_MODEM (modem), callback, user_data);
|
||||||
|
|
||||||
priv = MM_GENERIC_GSM_GET_PRIVATE (info->modem);
|
priv = MM_GENERIC_GSM_GET_PRIVATE (info->modem);
|
||||||
connected = mm_serial_port_is_connected (priv->primary);
|
connected = mm_port_get_connected (MM_PORT (priv->primary));
|
||||||
if (connected)
|
if (connected)
|
||||||
port = priv->secondary;
|
port = priv->secondary;
|
||||||
else
|
else
|
||||||
port = priv->primary;
|
port = priv->primary;
|
||||||
|
|
||||||
if (!port) {
|
if (!port) {
|
||||||
info->error = g_error_new_literal (MM_MODEM_ERROR, MM_MODEM_ERROR_GENERAL,
|
info->error = g_error_new_literal (MM_MODEM_ERROR, MM_MODEM_ERROR_CONNECTED,
|
||||||
"Cannot send SMS while connected");
|
"Cannot send SMS while connected");
|
||||||
mm_callback_info_schedule (info);
|
mm_callback_info_schedule (info);
|
||||||
return;
|
return;
|
||||||
@@ -1827,7 +1832,6 @@ finalize (GObject *object)
|
|||||||
mm_generic_gsm_pending_registration_stop (MM_GENERIC_GSM (object));
|
mm_generic_gsm_pending_registration_stop (MM_GENERIC_GSM (object));
|
||||||
|
|
||||||
g_free (priv->driver);
|
g_free (priv->driver);
|
||||||
g_free (priv->data_device);
|
|
||||||
g_free (priv->oper_code);
|
g_free (priv->oper_code);
|
||||||
g_free (priv->oper_name);
|
g_free (priv->oper_name);
|
||||||
|
|
||||||
|
@@ -28,6 +28,7 @@ enum {
|
|||||||
PROP_SUBSYS,
|
PROP_SUBSYS,
|
||||||
PROP_TYPE,
|
PROP_TYPE,
|
||||||
PROP_CARRIER_DETECT,
|
PROP_CARRIER_DETECT,
|
||||||
|
PROP_CONNECTED,
|
||||||
|
|
||||||
LAST_PROP
|
LAST_PROP
|
||||||
};
|
};
|
||||||
@@ -39,6 +40,7 @@ typedef struct {
|
|||||||
MMPortSubsys subsys;
|
MMPortSubsys subsys;
|
||||||
MMPortType ptype;
|
MMPortType ptype;
|
||||||
gboolean carrier_detect;
|
gboolean carrier_detect;
|
||||||
|
gboolean connected;
|
||||||
} MMPortPrivate;
|
} MMPortPrivate;
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
@@ -117,6 +119,30 @@ mm_port_get_carrier_detect (MMPort *self)
|
|||||||
return MM_PORT_GET_PRIVATE (self)->carrier_detect;
|
return MM_PORT_GET_PRIVATE (self)->carrier_detect;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
mm_port_get_connected (MMPort *self)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (self != NULL, FALSE);
|
||||||
|
g_return_val_if_fail (MM_IS_PORT (self), FALSE);
|
||||||
|
|
||||||
|
return MM_PORT_GET_PRIVATE (self)->connected;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
mm_port_set_connected (MMPort *self, gboolean connected)
|
||||||
|
{
|
||||||
|
MMPortPrivate *priv;
|
||||||
|
|
||||||
|
g_return_if_fail (self != NULL);
|
||||||
|
g_return_if_fail (MM_IS_PORT (self));
|
||||||
|
|
||||||
|
priv = MM_PORT_GET_PRIVATE (self);
|
||||||
|
if (priv->connected != connected) {
|
||||||
|
priv->connected = connected;
|
||||||
|
g_object_notify (G_OBJECT (self), MM_PORT_CONNECTED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -146,6 +172,9 @@ set_property (GObject *object, guint prop_id,
|
|||||||
case PROP_CARRIER_DETECT:
|
case PROP_CARRIER_DETECT:
|
||||||
priv->carrier_detect = g_value_get_boolean (value);
|
priv->carrier_detect = g_value_get_boolean (value);
|
||||||
break;
|
break;
|
||||||
|
case PROP_CONNECTED:
|
||||||
|
priv->connected = 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;
|
||||||
@@ -171,6 +200,9 @@ get_property (GObject *object, guint prop_id,
|
|||||||
case PROP_CARRIER_DETECT:
|
case PROP_CARRIER_DETECT:
|
||||||
g_value_set_boolean (value, priv->carrier_detect);
|
g_value_set_boolean (value, priv->carrier_detect);
|
||||||
break;
|
break;
|
||||||
|
case PROP_CONNECTED:
|
||||||
|
g_value_set_boolean (value, priv->connected);
|
||||||
|
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;
|
||||||
@@ -235,4 +267,12 @@ mm_port_class_init (MMPortClass *klass)
|
|||||||
"Has Carrier Detect",
|
"Has Carrier Detect",
|
||||||
TRUE,
|
TRUE,
|
||||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
|
G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
|
||||||
|
|
||||||
|
g_object_class_install_property
|
||||||
|
(object_class, PROP_CONNECTED,
|
||||||
|
g_param_spec_boolean (MM_PORT_CONNECTED,
|
||||||
|
"Connected",
|
||||||
|
"Is connected for data and not usable for control",
|
||||||
|
FALSE,
|
||||||
|
G_PARAM_READWRITE));
|
||||||
}
|
}
|
||||||
|
@@ -48,6 +48,7 @@ typedef enum {
|
|||||||
#define MM_PORT_SUBSYS "subsys"
|
#define MM_PORT_SUBSYS "subsys"
|
||||||
#define MM_PORT_TYPE "type"
|
#define MM_PORT_TYPE "type"
|
||||||
#define MM_PORT_CARRIER_DETECT "carrier-detect"
|
#define MM_PORT_CARRIER_DETECT "carrier-detect"
|
||||||
|
#define MM_PORT_CONNECTED "connected"
|
||||||
|
|
||||||
typedef struct _MMPort MMPort;
|
typedef struct _MMPort MMPort;
|
||||||
typedef struct _MMPortClass MMPortClass;
|
typedef struct _MMPortClass MMPortClass;
|
||||||
@@ -70,5 +71,9 @@ MMPortType mm_port_get_port_type (MMPort *self);
|
|||||||
|
|
||||||
gboolean mm_port_get_carrier_detect (MMPort *self);
|
gboolean mm_port_get_carrier_detect (MMPort *self);
|
||||||
|
|
||||||
|
gboolean mm_port_get_connected (MMPort *self);
|
||||||
|
|
||||||
|
void mm_port_set_connected (MMPort *self, gboolean connected);
|
||||||
|
|
||||||
#endif /* MM_PORT_H */
|
#endif /* MM_PORT_H */
|
||||||
|
|
||||||
|
@@ -58,6 +58,8 @@ typedef struct {
|
|||||||
GString *command;
|
GString *command;
|
||||||
GString *response;
|
GString *response;
|
||||||
|
|
||||||
|
gboolean connected;
|
||||||
|
|
||||||
/* Response parser data */
|
/* Response parser data */
|
||||||
MMSerialResponseParserFn response_parser_fn;
|
MMSerialResponseParserFn response_parser_fn;
|
||||||
gpointer response_parser_user_data;
|
gpointer response_parser_user_data;
|
||||||
@@ -328,7 +330,7 @@ mm_serial_port_send_command (MMSerialPort *self,
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mm_serial_port_is_connected (self)) {
|
if (mm_port_get_connected (MM_PORT (self))) {
|
||||||
g_set_error (error, MM_SERIAL_ERROR, MM_SERIAL_SEND_FAILED,
|
g_set_error (error, MM_SERIAL_ERROR, MM_SERIAL_SEND_FAILED,
|
||||||
"%s", "Sending command failed: device is connected");
|
"%s", "Sending command failed: device is connected");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@@ -864,26 +866,35 @@ mm_serial_port_flash (MMSerialPort *self,
|
|||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
/*****************************************************************************/
|
||||||
mm_serial_port_is_connected (MMSerialPort *self)
|
|
||||||
|
static void
|
||||||
|
port_connected (MMSerialPort *self, GParamSpec *pspec, gpointer user_data)
|
||||||
{
|
{
|
||||||
MMSerialPortPrivate *priv;
|
MMSerialPortPrivate *priv = MM_SERIAL_PORT_GET_PRIVATE (self);
|
||||||
int mcs = 0;
|
gboolean connected;
|
||||||
|
|
||||||
g_return_val_if_fail (MM_IS_SERIAL_PORT (self), FALSE);
|
|
||||||
|
|
||||||
priv = MM_SERIAL_PORT_GET_PRIVATE (self);
|
|
||||||
|
|
||||||
if (!mm_port_get_carrier_detect (MM_PORT (self)))
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
if (priv->fd < 0)
|
if (priv->fd < 0)
|
||||||
return FALSE;
|
return;
|
||||||
|
|
||||||
if (ioctl (priv->fd, TIOCMGET, &mcs) < 0)
|
/* When the port is connected, drop the serial port lock so PPP can do
|
||||||
return FALSE;
|
* something with the port. When the port is disconnected, grab the lock
|
||||||
|
* again.
|
||||||
|
*/
|
||||||
|
connected = mm_port_get_connected (MM_PORT (self));
|
||||||
|
|
||||||
return mcs & TIOCM_CAR ? TRUE : FALSE;
|
if (ioctl (priv->fd, (connected ? TIOCNXCL : TIOCEXCL)) < 0) {
|
||||||
|
g_warning ("%s: (%s) could not %s serial port lock: (%d) %s",
|
||||||
|
__func__,
|
||||||
|
mm_port_get_device (MM_PORT (self)),
|
||||||
|
connected ? "drop" : "re-acquire",
|
||||||
|
errno,
|
||||||
|
strerror (errno));
|
||||||
|
if (!connected) {
|
||||||
|
// FIXME: do something here, maybe try again in a few seconds or
|
||||||
|
// close the port and error out?
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
@@ -915,6 +926,8 @@ mm_serial_port_init (MMSerialPort *self)
|
|||||||
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);
|
||||||
priv->response = g_string_sized_new (SERIAL_BUF_SIZE);
|
priv->response = g_string_sized_new (SERIAL_BUF_SIZE);
|
||||||
|
|
||||||
|
g_signal_connect (self, "notify::" MM_PORT_CONNECTED, G_CALLBACK (port_connected), NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@@ -99,7 +99,5 @@ guint mm_serial_port_flash (MMSerialPort *self,
|
|||||||
MMSerialFlashFn callback,
|
MMSerialFlashFn callback,
|
||||||
gpointer user_data);
|
gpointer user_data);
|
||||||
|
|
||||||
gboolean mm_serial_port_is_connected (MMSerialPort *self);
|
|
||||||
|
|
||||||
#endif /* MM_SERIAL_PORT_H */
|
#endif /* MM_SERIAL_PORT_H */
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user