diff options
author | Dan Williams <dcbw@redhat.com> | 2010-02-23 11:41:40 -0800 |
---|---|---|
committer | Dan Williams <dcbw@redhat.com> | 2010-02-23 11:41:40 -0800 |
commit | 7a0373afee63eeb9e677f61ccd19fd4aed549ac9 (patch) | |
tree | 59df954f8edafee289eca574873dbfdf96f9ab42 /src | |
parent | bc3ac7bae507f2b264a5f616613c051fa0378d8b (diff) |
qcdm: add serial port subclass skeleton
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile.am | 4 | ||||
-rw-r--r-- | src/mm-qcdm-serial-port.c | 176 | ||||
-rw-r--r-- | src/mm-qcdm-serial-port.h | 66 |
3 files changed, 246 insertions, 0 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index e5884268..15b91bd5 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -16,6 +16,7 @@ sbin_PROGRAMS = modem-manager modem_manager_CPPFLAGS = \ $(MM_CFLAGS) \ $(GUDEV_CFLAGS) \ + $(top_srcdir) \ -I${top_builddir}/marshallers \ -DPLUGINDIR=\"$(pkglibdir)\" @@ -23,6 +24,7 @@ modem_manager_LDADD = \ $(MM_LIBS) \ $(GUDEV_LIBS) \ $(top_builddir)/marshallers/libmarshallers.la \ + $(top_builddir)/libqcdm/src/libqcdm.la \ $(builddir)/libmodem-helpers.la modem_manager_SOURCES = \ @@ -39,6 +41,8 @@ modem_manager_SOURCES = \ mm-serial-port.h \ mm-at-serial-port.c \ mm-at-serial-port.h \ + mm-qcdm-serial-port.c \ + mm-qcdm-serial-port.h \ mm-serial-parsers.c \ mm-serial-parsers.h \ mm-modem-base.c \ diff --git a/src/mm-qcdm-serial-port.c b/src/mm-qcdm-serial-port.c new file mode 100644 index 00000000..51d7c189 --- /dev/null +++ b/src/mm-qcdm-serial-port.c @@ -0,0 +1,176 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * 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: + * + * Copyright (C) 2008 - 2009 Novell, Inc. + * Copyright (C) 2009 - 2010 Red Hat, Inc. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> + +#include "mm-qcdm-serial-port.h" +#include "mm-errors.h" +#include "mm-options.h" +#include "libqcdm/src/com.h" +#include "libqcdm/src/utils.h" + +G_DEFINE_TYPE (MMQcdmSerialPort, mm_qcdm_serial_port, MM_TYPE_SERIAL_PORT) + +#define MM_QCDM_SERIAL_PORT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), MM_TYPE_QCDM_SERIAL_PORT, MMQcdmSerialPortPrivate)) + +typedef struct { + gboolean foo; +} MMQcdmSerialPortPrivate; + + +/*****************************************************************************/ + +static gboolean +parse_response (MMSerialPort *port, GByteArray *response, GError **error) +{ + int i; + + /* Look for the QCDM packet termination character; if we found it, treat + * the buffer as a qcdm command. + */ + for (i = 0; i < response->len; i++) { + if (response->data[i] == 0x7E) + return TRUE; + } + + /* Otherwise, need more data from the device */ + return FALSE; +} + +static void +handle_response (MMSerialPort *port, + GByteArray *response, + GError *error, + GCallback callback, + gpointer callback_data) +{ + MMQcdmSerialResponseFn response_callback = (MMQcdmSerialResponseFn) callback; + GByteArray *unescaped = NULL; + gboolean escaping = FALSE; + GError *dm_error = NULL; + + if (!error) { + unescaped = g_byte_array_sized_new (response->len); + unescaped->len = dm_unescape ((const char *) response->data, response->len, + (char *) unescaped->data, unescaped->len, + &escaping); + if (unescaped->len == 0) { + g_set_error_literal (&dm_error, 0, 0, "Failed to unescape QCDM packet."); + g_byte_array_free (unescaped, TRUE); + unescaped = NULL; + } + } + + response_callback (MM_QCDM_SERIAL_PORT (port), + unescaped, + dm_error ? dm_error : error, + callback_data); + + if (unescaped) + g_byte_array_free (unescaped, TRUE); +} + +/*****************************************************************************/ + +void +mm_qcdm_serial_port_queue_command (MMQcdmSerialPort *self, + GByteArray *command, + guint32 timeout_seconds, + MMQcdmSerialResponseFn callback, + gpointer user_data) +{ + g_return_if_fail (self != NULL); + g_return_if_fail (MM_IS_QCDM_SERIAL_PORT (self)); + g_return_if_fail (command != NULL); + + /* 'command' is expected to be already CRC-ed and escaped */ + mm_serial_port_queue_command (MM_SERIAL_PORT (self), + command, + TRUE, + timeout_seconds, + G_CALLBACK (callback), + user_data); +} + +void +mm_qcdm_serial_port_queue_command_cached (MMQcdmSerialPort *self, + GByteArray *command, + guint32 timeout_seconds, + MMQcdmSerialResponseFn callback, + gpointer user_data) +{ + g_return_if_fail (self != NULL); + g_return_if_fail (MM_IS_QCDM_SERIAL_PORT (self)); + g_return_if_fail (command != NULL); + + /* 'command' is expected to be already CRC-ed and escaped */ + mm_serial_port_queue_command_cached (MM_SERIAL_PORT (self), + command, + TRUE, + timeout_seconds, + G_CALLBACK (callback), + user_data); +} + +/*****************************************************************************/ + +static gboolean +config_fd (MMSerialPort *port, int fd, GError **error) +{ + return qcdm_port_setup (fd, error); +} + +/*****************************************************************************/ + +MMQcdmSerialPort * +mm_qcdm_serial_port_new (const char *name, MMPortType ptype) +{ + return MM_QCDM_SERIAL_PORT (g_object_new (MM_TYPE_QCDM_SERIAL_PORT, + MM_PORT_DEVICE, name, + MM_PORT_SUBSYS, MM_PORT_SUBSYS_TTY, + MM_PORT_TYPE, ptype, + NULL)); +} + +static void +mm_qcdm_serial_port_init (MMQcdmSerialPort *self) +{ +} + +static void +finalize (GObject *object) +{ + G_OBJECT_CLASS (mm_qcdm_serial_port_parent_class)->finalize (object); +} + +static void +mm_qcdm_serial_port_class_init (MMQcdmSerialPortClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + MMSerialPortClass *port_class = MM_SERIAL_PORT_CLASS (klass); + + g_type_class_add_private (object_class, sizeof (MMQcdmSerialPortPrivate)); + + /* Virtual methods */ + object_class->finalize = finalize; + + port_class->parse_response = parse_response; + port_class->handle_response = handle_response; + port_class->config_fd = config_fd; +} diff --git a/src/mm-qcdm-serial-port.h b/src/mm-qcdm-serial-port.h new file mode 100644 index 00000000..e70e124b --- /dev/null +++ b/src/mm-qcdm-serial-port.h @@ -0,0 +1,66 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * 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: + * + * Copyright (C) 2008 - 2009 Novell, Inc. + * Copyright (C) 2009 - 2010 Red Hat, Inc. + */ + +#ifndef MM_QCDM_SERIAL_PORT_H +#define MM_QCDM_SERIAL_PORT_H + +#include <glib.h> +#include <glib/gtypes.h> +#include <glib-object.h> + +#include "mm-serial-port.h" + +#define MM_TYPE_QCDM_SERIAL_PORT (mm_qcdm_serial_port_get_type ()) +#define MM_QCDM_SERIAL_PORT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MM_TYPE_QCDM_SERIAL_PORT, MMQcdmSerialPort)) +#define MM_QCDM_SERIAL_PORT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MM_TYPE_QCDM_SERIAL_PORT, MMQcdmSerialPortClass)) +#define MM_IS_QCDM_SERIAL_PORT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MM_TYPE_QCDM_SERIAL_PORT)) +#define MM_IS_QCDM_SERIAL_PORT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MM_TYPE_QCDM_SERIAL_PORT)) +#define MM_QCDM_SERIAL_PORT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MM_TYPE_QCDM_SERIAL_PORT, MMQcdmSerialPortClass)) + +typedef struct _MMQcdmSerialPort MMQcdmSerialPort; +typedef struct _MMQcdmSerialPortClass MMQcdmSerialPortClass; + +typedef void (*MMQcdmSerialResponseFn) (MMQcdmSerialPort *port, + GByteArray *response, + GError *error, + gpointer user_data); + +struct _MMQcdmSerialPort { + MMSerialPort parent; +}; + +struct _MMQcdmSerialPortClass { + MMSerialPortClass parent; +}; + +GType mm_qcdm_serial_port_get_type (void); + +MMQcdmSerialPort *mm_qcdm_serial_port_new (const char *name, MMPortType ptype); + +void mm_qcdm_serial_port_queue_command (MMQcdmSerialPort *self, + GByteArray *command, + guint32 timeout_seconds, + MMQcdmSerialResponseFn callback, + gpointer user_data); + +void mm_qcdm_serial_port_queue_command_cached (MMQcdmSerialPort *self, + GByteArray *command, + guint32 timeout_seconds, + MMQcdmSerialResponseFn callback, + gpointer user_data); + +#endif /* MM_QCDM_SERIAL_PORT_H */ + |