diff options
author | Dan Williams <dcbw@redhat.com> | 2013-02-08 09:32:08 -0600 |
---|---|---|
committer | Dan Williams <dcbw@redhat.com> | 2013-04-18 10:23:50 -0500 |
commit | b54423f6fb6938306fa2c8068855278797e515d9 (patch) | |
tree | dc4af07378ae22cc8f5889bc34db5fa0639b7323 | |
parent | 14031246ce05b1a282cfa0ec398ed8856d77e482 (diff) |
qcdm-serial-port: parse and emit log items to listeners
Handle unsolicited log items and emit them as signals that
listeners can use.
-rw-r--r-- | src/mm-qcdm-serial-port.c | 63 | ||||
-rw-r--r-- | src/mm-qcdm-serial-port.h | 8 |
2 files changed, 71 insertions, 0 deletions
diff --git a/src/mm-qcdm-serial-port.c b/src/mm-qcdm-serial-port.c index bce80519..bdece981 100644 --- a/src/mm-qcdm-serial-port.c +++ b/src/mm-qcdm-serial-port.c @@ -26,6 +26,7 @@ #include "libqcdm/src/com.h" #include "libqcdm/src/utils.h" #include "libqcdm/src/errors.h" +#include "libqcdm/src/log-items.h" #include "mm-log.h" G_DEFINE_TYPE (MMQcdmSerialPort, mm_qcdm_serial_port, MM_TYPE_SERIAL_PORT) @@ -36,6 +37,12 @@ typedef struct { gboolean foo; } MMQcdmSerialPortPrivate; +enum { + LOG_ITEM, + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = { 0 }; /*****************************************************************************/ @@ -72,6 +79,53 @@ parse_response (MMSerialPort *port, GByteArray *response, GError **error) return find_qcdm_start (response, NULL); } +static void +parse_unsolicited (MMSerialPort *port, GByteArray *response) +{ + GByteArray *unescaped = NULL; + guint8 *unescaped_buffer; + gsize used = 0; + gsize start = 0; + gboolean success = FALSE; + qcdmbool more = FALSE; + gsize unescaped_len = 0; + + if (!find_qcdm_start (response, &start)) + return; + + /* Quick check if it's a log item */ + if (start < 0 || response->data[start] != 0x10) + return; + + unescaped_buffer = g_malloc (1024); + success = dm_decapsulate_buffer ((const char *) response->data, + response->len, + (char *) unescaped_buffer, + 1024, + &unescaped_len, + &used, + &more); + if (!success || more) { + g_free (unescaped_buffer); + return; + } + + /* Successfully decapsulated the DM command */ + g_assert (unescaped_len <= 1024); + unescaped_buffer = g_realloc (unescaped_buffer, unescaped_len); + unescaped = g_byte_array_new_take (unescaped_buffer, unescaped_len); + + if (qcdm_is_log_item ((const char *) unescaped->data, unescaped->len, 0)) { + g_signal_emit (port, signals[LOG_ITEM], 0, + qcdm_get_log_item_code ((const char *) unescaped->data, unescaped->len), + unescaped); + /* Remove the log item from the buffer */ + g_byte_array_remove_range (response, 0, start + used); + } + + g_byte_array_unref (unescaped); +} + static gsize handle_response (MMSerialPort *port, GByteArray *response, @@ -274,7 +328,16 @@ mm_qcdm_serial_port_class_init (MMQcdmSerialPortClass *klass) object_class->finalize = finalize; port_class->parse_response = parse_response; + port_class->parse_unsolicited = parse_unsolicited; port_class->handle_response = handle_response; port_class->config_fd = config_fd; port_class->debug_log = debug_log; + + /* signals */ + signals[LOG_ITEM] = + g_signal_new (QCDM_SERIAL_PORT_LOG_ITEM, + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + 0, NULL, NULL, NULL, + G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_BYTE_ARRAY); } diff --git a/src/mm-qcdm-serial-port.h b/src/mm-qcdm-serial-port.h index b8e858bd..ae8be0b1 100644 --- a/src/mm-qcdm-serial-port.h +++ b/src/mm-qcdm-serial-port.h @@ -32,6 +32,9 @@ typedef struct _MMQcdmSerialPort MMQcdmSerialPort; typedef struct _MMQcdmSerialPortClass MMQcdmSerialPortClass; +/* Signals */ +#define QCDM_SERIAL_PORT_LOG_ITEM "log-item" + typedef void (*MMQcdmSerialResponseFn) (MMQcdmSerialPort *port, GByteArray *response, GError *error, @@ -43,6 +46,11 @@ struct _MMQcdmSerialPort { struct _MMQcdmSerialPortClass { MMSerialPortClass parent; + + /* Signals */ + void (*log_item) (MMQcdmSerialPort *port, + guint log_code, + const GByteArray *data); }; GType mm_qcdm_serial_port_get_type (void); |