From 633708b364c646595af3242c6d1a7b03b9a2359f Mon Sep 17 00:00:00 2001 From: ori inbar Date: Wed, 27 Mar 2013 15:14:51 -0500 Subject: serial: add support to optionally send line-feed at the end of AT commands. --- src/mm-at-serial-port.c | 40 ++++++++++++++++++++++++++++++++++------ src/mm-at-serial-port.h | 2 ++ src/mm-plugin.c | 19 +++++++++++++++++++ src/mm-plugin.h | 1 + src/mm-port-probe.c | 5 +++++ src/mm-port-probe.h | 1 + 6 files changed, 62 insertions(+), 6 deletions(-) mode change 100644 => 100755 src/mm-at-serial-port.c diff --git a/src/mm-at-serial-port.c b/src/mm-at-serial-port.c old mode 100644 new mode 100755 index 79626225..346221ab --- a/src/mm-at-serial-port.c +++ b/src/mm-at-serial-port.c @@ -33,6 +33,7 @@ enum { PROP_REMOVE_ECHO, PROP_INIT_SEQUENCE_ENABLED, PROP_INIT_SEQUENCE, + PROP_SEND_LF, LAST_PROP }; @@ -50,6 +51,7 @@ typedef struct { gboolean remove_echo; guint init_sequence_enabled; gchar **init_sequence; + gboolean send_lf; } MMAtSerialPortPrivate; /*****************************************************************************/ @@ -286,7 +288,7 @@ parse_unsolicited (MMSerialPort *port, GByteArray *response) /*****************************************************************************/ static GByteArray * -at_command_to_byte_array (const char *command, gboolean is_raw) +at_command_to_byte_array (const char *command, gboolean is_raw, gboolean send_lf) { GByteArray *buf; int cmdlen; @@ -294,7 +296,7 @@ at_command_to_byte_array (const char *command, gboolean is_raw) g_return_val_if_fail (command != NULL, NULL); cmdlen = strlen (command); - buf = g_byte_array_sized_new (cmdlen + 3); + buf = g_byte_array_sized_new (cmdlen + 4); if (!is_raw) { /* Make sure there's an AT in the front */ @@ -306,8 +308,15 @@ at_command_to_byte_array (const char *command, gboolean is_raw) if (!is_raw) { /* Make sure there's a trailing carriage return */ - if (command[cmdlen - 1] != '\r') - g_byte_array_append (buf, (const guint8 *) "\r", 1); + if ((cmdlen == 0) || + (command[cmdlen - 1] != '\r' && (cmdlen == 1 || command[cmdlen - 2] != '\r'))) + g_byte_array_append (buf, (const guint8 *) "\r", 1); + if (send_lf) { + /* Make sure there's a trailing line-feed */ + if ((cmdlen == 0) || + (command[cmdlen - 1] != '\n' && (cmdlen == 1 || command[cmdlen - 2] != '\n'))) + g_byte_array_append (buf, (const guint8 *) "\n", 1); + } } return buf; @@ -323,12 +332,13 @@ mm_at_serial_port_queue_command (MMAtSerialPort *self, gpointer user_data) { GByteArray *buf; + MMAtSerialPortPrivate *priv = MM_AT_SERIAL_PORT_GET_PRIVATE (self); g_return_if_fail (self != NULL); g_return_if_fail (MM_IS_AT_SERIAL_PORT (self)); g_return_if_fail (command != NULL); - buf = at_command_to_byte_array (command, is_raw); + buf = at_command_to_byte_array (command, is_raw, priv->send_lf); g_return_if_fail (buf != NULL); mm_serial_port_queue_command (MM_SERIAL_PORT (self), @@ -350,12 +360,13 @@ mm_at_serial_port_queue_command_cached (MMAtSerialPort *self, gpointer user_data) { GByteArray *buf; + MMAtSerialPortPrivate *priv = MM_AT_SERIAL_PORT_GET_PRIVATE (self); g_return_if_fail (self != NULL); g_return_if_fail (MM_IS_AT_SERIAL_PORT (self)); g_return_if_fail (command != NULL); - buf = at_command_to_byte_array (command, is_raw); + buf = at_command_to_byte_array (command, is_raw, priv->send_lf); g_return_if_fail (buf != NULL); mm_serial_port_queue_command_cached (MM_SERIAL_PORT (self), @@ -475,6 +486,9 @@ mm_at_serial_port_init (MMAtSerialPort *self) priv->remove_echo = TRUE; /* By default, run init sequence during first port opening */ priv->init_sequence_enabled = TRUE; + + /* By default, don't send line feed */ + priv->send_lf = FALSE; } static void @@ -494,6 +508,9 @@ set_property (GObject *object, guint prop_id, g_strfreev (priv->init_sequence); priv->init_sequence = g_value_dup_boxed (value); break; + case PROP_SEND_LF: + priv->send_lf = g_value_get_boolean (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -516,6 +533,9 @@ get_property (GObject *object, guint prop_id, case PROP_INIT_SEQUENCE: g_value_set_boxed (value, priv->init_sequence); break; + case PROP_SEND_LF: + g_value_set_boolean (value, priv->send_lf); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -590,4 +610,12 @@ mm_at_serial_port_class_init (MMAtSerialPortClass *klass) "Initialization sequence", G_TYPE_STRV, G_PARAM_READWRITE)); + + g_object_class_install_property + (object_class, PROP_SEND_LF, + g_param_spec_boolean (MM_AT_SERIAL_PORT_SEND_LF, + "Send LF", + "Send line-feed at the end of each AT command sent", + FALSE, + G_PARAM_READWRITE)); } diff --git a/src/mm-at-serial-port.h b/src/mm-at-serial-port.h index 02a5d33c..cf960a0f 100644 --- a/src/mm-at-serial-port.h +++ b/src/mm-at-serial-port.h @@ -69,6 +69,8 @@ typedef void (*MMAtSerialResponseFn) (MMAtSerialPort *port, #define MM_AT_SERIAL_PORT_INIT_SEQUENCE_ENABLED "init-sequence-enabled" #define MM_AT_SERIAL_PORT_INIT_SEQUENCE "init-sequence" +#define MM_AT_SERIAL_PORT_SEND_LF "send-lf" + struct _MMAtSerialPort { MMSerialPort parent; }; diff --git a/src/mm-plugin.c b/src/mm-plugin.c index 4b1ae8b0..2be183db 100644 --- a/src/mm-plugin.c +++ b/src/mm-plugin.c @@ -81,6 +81,7 @@ struct _MMPluginPrivate { MMPortProbeAtCommand *custom_at_probe; guint64 send_delay; gboolean remove_echo; + gboolean send_lf; /* Probing setup and/or post-probing filter. * Plugins may use this method to decide whether they support a given @@ -112,6 +113,7 @@ enum { PROP_CUSTOM_INIT, PROP_SEND_DELAY, PROP_REMOVE_ECHO, + PROP_SEND_LF, LAST_PROP }; @@ -753,6 +755,7 @@ mm_plugin_supports_port (MMPlugin *self, ctx->flags, self->priv->send_delay, self->priv->remove_echo, + self->priv->send_lf, self->priv->custom_at_probe, self->priv->custom_init, (GAsyncReadyCallback)port_probe_run_ready, @@ -888,6 +891,7 @@ mm_plugin_init (MMPlugin *self) /* Defaults */ self->priv->send_delay = 100000; self->priv->remove_echo = TRUE; + self->priv->send_lf = FALSE; } static void @@ -987,6 +991,10 @@ set_property (GObject *object, /* Construct only */ self->priv->remove_echo = g_value_get_boolean (value); break; + case PROP_SEND_LF: + /* Construct only */ + self->priv->send_lf = g_value_get_boolean (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -1068,6 +1076,9 @@ get_property (GObject *object, case PROP_REMOVE_ECHO: g_value_set_boolean (value, self->priv->remove_echo); break; + case PROP_SEND_LF: + g_value_set_boolean (value, self->priv->send_lf); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -1302,4 +1313,12 @@ mm_plugin_class_init (MMPluginClass *klass) "Remove echo out of the AT responses", TRUE, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + + g_object_class_install_property + (object_class, PROP_SEND_LF, + g_param_spec_boolean (MM_PLUGIN_SEND_LF, + "Send LF", + "Send line-feed at the end of each AT command sent", + FALSE, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); } diff --git a/src/mm-plugin.h b/src/mm-plugin.h index 37cac68d..08d81389 100644 --- a/src/mm-plugin.h +++ b/src/mm-plugin.h @@ -60,6 +60,7 @@ #define MM_PLUGIN_CUSTOM_AT_PROBE "custom-at-probe" #define MM_PLUGIN_SEND_DELAY "send-delay" #define MM_PLUGIN_REMOVE_ECHO "remove-echo" +#define MM_PLUGIN_SEND_LF "send-lf" typedef enum { MM_PLUGIN_SUPPORTS_PORT_UNSUPPORTED = 0x0, diff --git a/src/mm-port-probe.c b/src/mm-port-probe.c index 5833666f..77349250 100644 --- a/src/mm-port-probe.c +++ b/src/mm-port-probe.c @@ -85,6 +85,8 @@ typedef struct { guint64 at_send_delay; /* Flag to leave/remove echo in AT responses */ gboolean at_remove_echo; + /* Flag to send line-feed at the end of AT commands */ + gboolean at_send_lf; /* Number of times we tried to open the AT port */ guint at_open_tries; /* Custom initialization setup */ @@ -975,6 +977,7 @@ serial_open_at (MMPortProbe *self) g_object_set (task->serial, MM_SERIAL_PORT_SEND_DELAY, task->at_send_delay, MM_AT_SERIAL_PORT_REMOVE_ECHO, task->at_remove_echo, + MM_AT_SERIAL_PORT_SEND_LF, task->at_send_lf, MM_PORT_CARRIER_DETECT, FALSE, MM_SERIAL_PORT_SPEW_CONTROL, TRUE, NULL); @@ -1096,6 +1099,7 @@ mm_port_probe_run (MMPortProbe *self, MMPortProbeFlag flags, guint64 at_send_delay, gboolean at_remove_echo, + gboolean at_send_lf, const MMPortProbeAtCommand *at_custom_probe, const MMAsyncMethod *at_custom_init, GAsyncReadyCallback callback, @@ -1115,6 +1119,7 @@ mm_port_probe_run (MMPortProbe *self, task = g_new0 (PortProbeRunTask, 1); task->at_send_delay = at_send_delay; task->at_remove_echo = at_remove_echo; + task->at_send_lf = at_send_lf; task->flags = MM_PORT_PROBE_NONE; task->at_custom_probe = at_custom_probe; task->at_custom_init = at_custom_init ? (MMPortProbeAtCustomInit)at_custom_init->async : NULL; diff --git a/src/mm-port-probe.h b/src/mm-port-probe.h index 74a3420f..dfce77a8 100644 --- a/src/mm-port-probe.h +++ b/src/mm-port-probe.h @@ -106,6 +106,7 @@ void mm_port_probe_run (MMPortProbe *self, MMPortProbeFlag flags, guint64 at_send_delay, gboolean at_remove_echo, + gboolean at_send_lf, const MMPortProbeAtCommand *at_custom_probe, const MMAsyncMethod *at_custom_init, GAsyncReadyCallback callback, -- cgit v1.2.3