aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore2
-rw-r--r--Makefile.am2
-rw-r--r--configure.ac3
-rw-r--r--libqcdm/Makefile.am2
-rw-r--r--libqcdm/src/Makefile.am42
-rw-r--r--libqcdm/src/com.c62
-rw-r--r--libqcdm/src/com.h25
-rw-r--r--libqcdm/src/commands.c497
-rw-r--r--libqcdm/src/commands.h235
-rw-r--r--libqcdm/src/dm-commands.h254
-rw-r--r--libqcdm/src/error.c86
-rw-r--r--libqcdm/src/error.h52
-rw-r--r--libqcdm/src/libqcdm.ver6
-rw-r--r--libqcdm/src/nv-items.h35
-rw-r--r--libqcdm/src/result-private.h41
-rw-r--r--libqcdm/src/result.c206
-rw-r--r--libqcdm/src/result.h42
-rw-r--r--libqcdm/src/utils.c309
-rw-r--r--libqcdm/src/utils.h54
-rw-r--r--libqcdm/tests/Makefile.am30
-rw-r--r--libqcdm/tests/test-qcdm-com.c771
-rw-r--r--libqcdm/tests/test-qcdm-com.h41
-rw-r--r--libqcdm/tests/test-qcdm-crc.c65
-rw-r--r--libqcdm/tests/test-qcdm-crc.h25
-rw-r--r--libqcdm/tests/test-qcdm-escaping.c124
-rw-r--r--libqcdm/tests/test-qcdm-escaping.h26
-rw-r--r--libqcdm/tests/test-qcdm-result.c71
-rw-r--r--libqcdm/tests/test-qcdm-result.h26
-rw-r--r--libqcdm/tests/test-qcdm.c107
-rw-r--r--plugins/mm-modem-anydata-cdma.c28
-rw-r--r--plugins/mm-modem-gobi-gsm.c9
-rw-r--r--plugins/mm-modem-hso.c38
-rw-r--r--plugins/mm-modem-huawei-cdma.c24
-rw-r--r--plugins/mm-modem-huawei-gsm.c62
-rw-r--r--plugins/mm-modem-mbm.c117
-rw-r--r--plugins/mm-modem-nokia.c14
-rw-r--r--plugins/mm-modem-novatel-gsm.c20
-rw-r--r--plugins/mm-modem-option.c16
-rw-r--r--plugins/mm-modem-sierra-cdma.c26
-rw-r--r--plugins/mm-modem-sierra-gsm.c8
-rw-r--r--plugins/mm-modem-zte.c46
-rw-r--r--plugins/mm-plugin-huawei.c21
-rw-r--r--src/Makefile.am10
-rw-r--r--src/mm-at-serial-port.c324
-rw-r--r--src/mm-at-serial-port.h85
-rw-r--r--src/mm-generic-cdma.c96
-rw-r--r--src/mm-generic-cdma.h4
-rw-r--r--src/mm-generic-gsm.c231
-rw-r--r--src/mm-generic-gsm.h6
-rw-r--r--src/mm-manager.c12
-rw-r--r--src/mm-modem-base.c4
-rw-r--r--src/mm-plugin-base.c54
-rw-r--r--src/mm-qcdm-serial-port.c176
-rw-r--r--src/mm-qcdm-serial-port.h66
-rw-r--r--src/mm-serial-port.c349
-rw-r--r--src/mm-serial-port.h81
56 files changed, 4517 insertions, 651 deletions
diff --git a/.gitignore b/.gitignore
index f6d2d811..e7db0a8a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -33,6 +33,8 @@ test/lsudev
src/tests/test-modem-helpers
policy/org.freedesktop.modem-manager.policy
+libqcdm/tests/test-qcdm
+
po/Makefile.in.in
po/POTFILES
po/stamp-it
diff --git a/Makefile.am b/Makefile.am
index a25308df..c2639508 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -19,7 +19,7 @@ all: $(GENERATED_FILES)
CLEANFILES = $(GENERATED_FILES)
endif
-SUBDIRS = marshallers src plugins introspection po test
+SUBDIRS = marshallers libqcdm src plugins introspection po policy test
if WITH_POLKIT
SUBDIRS += policy
diff --git a/configure.ac b/configure.ac
index d636cea5..6f6621d7 100644
--- a/configure.ac
+++ b/configure.ac
@@ -113,6 +113,9 @@ NM_COMPILER_WARNINGS
AC_CONFIG_FILES([
Makefile
marshallers/Makefile
+libqcdm/Makefile
+libqcdm/src/Makefile
+libqcdm/tests/Makefile
src/Makefile
src/tests/Makefile
plugins/Makefile
diff --git a/libqcdm/Makefile.am b/libqcdm/Makefile.am
new file mode 100644
index 00000000..77f28d7a
--- /dev/null
+++ b/libqcdm/Makefile.am
@@ -0,0 +1,2 @@
+SUBDIRS=src tests
+
diff --git a/libqcdm/src/Makefile.am b/libqcdm/src/Makefile.am
new file mode 100644
index 00000000..5cc05682
--- /dev/null
+++ b/libqcdm/src/Makefile.am
@@ -0,0 +1,42 @@
+noinst_LTLIBRARIES = libqcdm.la libqcdm-test.la
+
+
+libqcdm_la_CPPFLAGS = \
+ $(MM_CFLAGS)
+
+libqcdm_la_SOURCES = \
+ dm-commands.h \
+ nv-items.h \
+ com.c \
+ com.h \
+ commands.c \
+ commands.h \
+ error.c \
+ error.h \
+ result.c \
+ result.h \
+ result-private.h \
+ utils.c \
+ utils.h
+
+libqcdm_la_LIBADD = \
+ $(MM_LIBS)
+
+libqcdm_la_LDFLAGS = -Wl,--version-script=$(srcdir)/libqcdm.ver \
+ -version-info "0:0:0"
+
+
+###########################################
+# Test library without symbol versioning
+###########################################
+
+libqcdm_test_la_CPPFLAGS = \
+ $(MM_CFLAGS)
+
+libqcdm_test_la_SOURCES = \
+ utils.c \
+ utils.h
+
+libqcdm_test_la_LIBADD = \
+ $(MM_LIBS)
+
diff --git a/libqcdm/src/com.c b/libqcdm/src/com.c
new file mode 100644
index 00000000..59f2c6f8
--- /dev/null
+++ b/libqcdm/src/com.c
@@ -0,0 +1,62 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * Copyright (C) 2010 Red Hat, Inc.
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <errno.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <string.h>
+#include <termio.h>
+
+#include "com.h"
+#include "error.h"
+
+gboolean
+qcdm_port_setup (int fd, GError **error)
+{
+ struct termio stbuf;
+
+ g_type_init ();
+
+ errno = 0;
+ memset (&stbuf, 0, sizeof (struct termio));
+ if (ioctl (fd, TCGETA, &stbuf) != 0) {
+ g_set_error (error,
+ QCDM_SERIAL_ERROR, QCDM_SERIAL_CONFIG_FAILED,
+ "TCGETA error: %d", errno);
+ }
+
+ stbuf.c_cflag &= ~(CBAUD | CSIZE | CSTOPB | CLOCAL | PARENB);
+ stbuf.c_iflag &= ~(HUPCL | IUTF8 | IUCLC | ISTRIP | IXON | ICRNL);
+ stbuf.c_oflag &= ~(OPOST | OCRNL | ONLCR | OLCUC | ONLRET);
+ stbuf.c_lflag &= ~(ICANON | ISIG | IEXTEN | ECHO | ECHOE | ECHOK | ECHONL);
+ stbuf.c_lflag &= ~(NOFLSH | XCASE | TOSTOP | ECHOPRT | ECHOCTL | ECHOKE);
+ stbuf.c_cc[VMIN] = 1;
+ stbuf.c_cc[VTIME] = 0;
+ stbuf.c_cc[VEOF] = 1;
+ stbuf.c_cflag |= (B115200 | CS8 | CREAD | 0 | 0); /* No parity, 1 stop bit */
+
+ errno = 0;
+ if (ioctl (fd, TCSETA, &stbuf) < 0) {
+ g_set_error (error,
+ QCDM_SERIAL_ERROR, QCDM_SERIAL_CONFIG_FAILED,
+ "TCSETA error: %d", errno);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
diff --git a/libqcdm/src/com.h b/libqcdm/src/com.h
new file mode 100644
index 00000000..97561d03
--- /dev/null
+++ b/libqcdm/src/com.h
@@ -0,0 +1,25 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * Copyright (C) 2010 Red Hat, Inc.
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef LIBQCDM_COM_H
+#define LIBQCDM_COM_H
+
+#include <glib.h>
+
+gboolean qcdm_port_setup (int fd, GError **error);
+
+#endif /* LIBQCDM_COM_H */
diff --git a/libqcdm/src/commands.c b/libqcdm/src/commands.c
new file mode 100644
index 00000000..611a0b1d
--- /dev/null
+++ b/libqcdm/src/commands.c
@@ -0,0 +1,497 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * Copyright (C) 2010 Red Hat, Inc.
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <string.h>
+
+#include "commands.h"
+#include "error.h"
+#include "dm-commands.h"
+#include "nv-items.h"
+#include "result-private.h"
+#include "utils.h"
+
+/*
+ * utils_bin2hexstr
+ *
+ * Convert a byte-array into a hexadecimal string.
+ *
+ * Code originally by Alex Larsson <alexl@redhat.com> and
+ * copyright Red Hat, Inc. under terms of the LGPL.
+ *
+ */
+static char *
+bin2hexstr (const guint8 *bytes, int len)
+{
+ static char hex_digits[] = "0123456789abcdef";
+ char *result;
+ int i;
+ gsize buflen = (len * 2) + 1;
+
+ g_return_val_if_fail (bytes != NULL, NULL);
+ g_return_val_if_fail (len > 0, NULL);
+ g_return_val_if_fail (len < 4096, NULL); /* Arbitrary limit */
+
+ result = g_malloc0 (buflen);
+ for (i = 0; i < len; i++) {
+ result[2*i] = hex_digits[(bytes[i] >> 4) & 0xf];
+ result[2*i+1] = hex_digits[bytes[i] & 0xf];
+ }
+ result[buflen - 1] = '\0';
+ return result;
+}
+
+static gboolean
+check_command (const char *buf, gsize len, guint8 cmd, gsize min_len, GError **error)
+{
+ if (len < 1) {
+ g_set_error (error, QCDM_COMMAND_ERROR, QCDM_COMMAND_MALFORMED_RESPONSE,
+ "DM command response malformed (must be at least 1 byte in length)");
+ return FALSE;
+ }
+
+ switch (buf[0]) {
+ case DIAG_CMD_BAD_CMD:
+ g_set_error (error, QCDM_COMMAND_ERROR, QCDM_COMMAND_BAD_COMMAND,
+ "DM command %d unknown or unimplemented by the device",
+ cmd);
+ return FALSE;
+ case DIAG_CMD_BAD_PARM:
+ g_set_error (error, QCDM_COMMAND_ERROR, QCDM_COMMAND_BAD_PARAMETER,
+ "DM command %d contained invalid parameter",
+ cmd);
+ return FALSE;
+ case DIAG_CMD_BAD_LEN:
+ g_set_error (error, QCDM_COMMAND_ERROR, QCDM_COMMAND_BAD_LENGTH,
+ "DM command %d was the wrong size",
+ cmd);
+ return FALSE;
+ case DIAG_CMD_BAD_DEV:
+ g_set_error (error, QCDM_COMMAND_ERROR, QCDM_COMMAND_NOT_ACCEPTED,
+ "DM command %d was not accepted by the device",
+ cmd);
+ return FALSE;
+ case DIAG_CMD_BAD_MODE:
+ g_set_error (error, QCDM_COMMAND_ERROR, QCDM_COMMAND_BAD_MODE,
+ "DM command %d not allowed in the current device mode",
+ cmd);
+ return FALSE;
+ default:
+ break;
+ }
+
+ if (buf[0] != cmd) {
+ g_set_error (error, QCDM_COMMAND_ERROR, QCDM_COMMAND_UNEXPECTED,
+ "Unexpected DM command response (expected %d, got %d)",
+ cmd, buf[0]);
+ return FALSE;
+ }
+
+ if (len < min_len) {
+ g_set_error (error, QCDM_COMMAND_ERROR, QCDM_COMMAND_BAD_LENGTH,
+ "DM command %d response not long enough (got %zu, expected "
+ "at least %zu).", cmd, len, min_len);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/**********************************************************************/
+
+gsize
+qcdm_cmd_version_info_new (char *buf, gsize len, GError **error)
+{
+ char cmdbuf[3];
+ DMCmdHeader *cmd = (DMCmdHeader *) &cmdbuf[0];
+
+ g_return_val_if_fail (buf != NULL, 0);
+ g_return_val_if_fail (len >= sizeof (*cmd) + DIAG_TRAILER_LEN, 0);
+
+ memset (cmd, 0, sizeof (cmd));
+ cmd->code = DIAG_CMD_VERSION_INFO;
+
+ return dm_encapsulate_buffer (cmdbuf, sizeof (*cmd), sizeof (cmdbuf), buf, len);
+}
+
+QCDMResult *
+qcdm_cmd_version_info_result (const char *buf, gsize len, GError **error)
+{
+ QCDMResult *result = NULL;
+ DMCmdVersionInfoRsp *rsp = (DMCmdVersionInfoRsp *) buf;
+ char tmp[12];
+
+ g_return_val_if_fail (buf != NULL, NULL);
+
+ if (!check_command (buf, len, DIAG_CMD_VERSION_INFO, sizeof (DMCmdVersionInfoRsp), error))
+ return NULL;
+
+ result = qcdm_result_new ();
+
+ memset (tmp, 0, sizeof (tmp));
+ g_assert (sizeof (rsp->comp_date) <= sizeof (tmp));
+ memcpy (tmp, rsp->comp_date, sizeof (rsp->comp_date));
+ qcdm_result_add_string (result, QCDM_CMD_VERSION_INFO_ITEM_COMP_DATE, tmp);
+
+ memset (tmp, 0, sizeof (tmp));
+ g_assert (sizeof (rsp->comp_time) <= sizeof (tmp));
+ memcpy (tmp, rsp->comp_time, sizeof (rsp->comp_time));
+ qcdm_result_add_string (result, QCDM_CMD_VERSION_INFO_ITEM_COMP_TIME, tmp);
+
+ memset (tmp, 0, sizeof (tmp));
+ g_assert (sizeof (rsp->rel_date) <= sizeof (tmp));
+ memcpy (tmp, rsp->rel_date, sizeof (rsp->rel_date));
+ qcdm_result_add_string (result, QCDM_CMD_VERSION_INFO_ITEM_RELEASE_DATE, tmp);
+
+ memset (tmp, 0, sizeof (tmp));
+ g_assert (sizeof (rsp->rel_time) <= sizeof (tmp));
+ memcpy (tmp, rsp->rel_time, sizeof (rsp->rel_time));
+ qcdm_result_add_string (result, QCDM_CMD_VERSION_INFO_ITEM_RELEASE_TIME, tmp);
+
+ memset (tmp, 0, sizeof (tmp));
+ g_assert (sizeof (rsp->model) <= sizeof (tmp));
+ memcpy (tmp, rsp->model, sizeof (rsp->model));
+ qcdm_result_add_string (result, QCDM_CMD_VERSION_INFO_ITEM_MODEL, tmp);
+
+ return result;
+}
+
+/**********************************************************************/
+
+gsize
+qcdm_cmd_esn_new (char *buf, gsize len, GError **error)
+{
+ char cmdbuf[3];
+ DMCmdHeader *cmd = (DMCmdHeader *) &cmdbuf[0];
+
+ g_return_val_if_fail (buf != NULL, 0);
+ g_return_val_if_fail (len >= sizeof (*cmd) + DIAG_TRAILER_LEN, 0);
+
+ memset (cmd, 0, sizeof (cmd));
+ cmd->code = DIAG_CMD_ESN;
+
+ return dm_encapsulate_buffer (cmdbuf, sizeof (*cmd), sizeof (cmdbuf), buf, len);
+}
+
+QCDMResult *
+qcdm_cmd_esn_result (const char *buf, gsize len, GError **error)
+{
+ QCDMResult *result = NULL;
+ DMCmdEsnRsp *rsp = (DMCmdEsnRsp *) buf;
+ char *tmp;
+ guint8 swapped[4];
+
+ g_return_val_if_fail (buf != NULL, NULL);
+
+ if (!check_command (buf, len, DIAG_CMD_ESN, sizeof (DMCmdEsnRsp), error))
+ return NULL;
+
+ result = qcdm_result_new ();
+
+ /* Convert the ESN from binary to a hex string; it's LE so we have to
+ * swap it to get the correct ordering.
+ */
+ swapped[0] = rsp->esn[3];
+ swapped[1] = rsp->esn[2];
+ swapped[2] = rsp->esn[1];
+ swapped[3] = rsp->esn[0];
+
+ tmp = bin2hexstr (&swapped[0], sizeof (swapped));
+ qcdm_result_add_string (result, QCDM_CMD_ESN_ITEM_ESN, tmp);
+ g_free (tmp);
+
+ return result;
+}
+
+/**********************************************************************/
+
+gsize
+qcdm_cmd_cdma_status_new (char *buf, gsize len, GError **error)
+{
+ char cmdbuf[3];
+ DMCmdHeader *cmd = (DMCmdHeader *) &cmdbuf[0];
+
+ g_return_val_if_fail (buf != NULL, 0);
+ g_return_val_if_fail (len >= sizeof (*cmd) + DIAG_TRAILER_LEN, 0);
+
+ memset (cmd, 0, sizeof (cmd));
+ cmd->code = DIAG_CMD_STATUS;
+
+ return dm_encapsulate_buffer (cmdbuf, sizeof (*cmd), sizeof (cmdbuf), buf, len);
+}
+
+QCDMResult *
+qcdm_cmd_cdma_status_result (const char *buf, gsize len, GError **error)
+{
+ QCDMResult *result = NULL;
+ DMCmdStatusRsp *rsp = (DMCmdStatusRsp *) buf;
+ char *tmp;
+ guint8 swapped[4];
+ guint32 tmp_num;
+
+ g_return_val_if_fail (buf != NULL, NULL);
+
+ if (!check_command (buf, len, DIAG_CMD_STATUS, sizeof (DMCmdStatusRsp), error))
+ return NULL;
+
+ result = qcdm_result_new ();
+
+ /* Convert the ESN from binary to a hex string; it's LE so we have to
+ * swap it to get the correct ordering.
+ */
+ swapped[0] = rsp->esn[3];
+ swapped[1] = rsp->esn[2];
+ swapped[2] = rsp->esn[1];
+ swapped[3] = rsp->esn[0];
+
+ tmp = bin2hexstr (&swapped[0], sizeof (swapped));
+ qcdm_result_add_string (result, QCDM_CMD_CDMA_STATUS_ITEM_ESN, tmp);
+ g_free (tmp);
+
+ tmp_num = (guint32) GUINT16_FROM_LE (rsp->cdma_rx_state);
+ qcdm_result_add_uint32 (result, QCDM_CMD_CDMA_STATUS_ITEM_RX_STATE, tmp_num);
+
+ tmp_num = (guint32) GUINT16_FROM_LE (rsp->entry_reason);
+ qcdm_result_add_uint32 (result, QCDM_CMD_CDMA_STATUS_ITEM_ENTRY_REASON, tmp_num);
+
+ tmp_num = (guint32) GUINT16_FROM_LE (rsp->curr_chan);
+ qcdm_result_add_uint32 (result, QCDM_CMD_CDMA_STATUS_ITEM_CURRENT_CHANNEL, tmp_num);
+
+ qcdm_result_add_uint8 (result, QCDM_CMD_CDMA_STATUS_ITEM_CODE_CHANNEL, rsp->cdma_code_chan);
+
+ tmp_num = (guint32) GUINT16_FROM_LE (rsp->pilot_base);
+ qcdm_result_add_uint32 (result, QCDM_CMD_CDMA_STATUS_ITEM_PILOT_BASE, tmp_num);
+
+ tmp_num = (guint32) GUINT16_FROM_LE (rsp->sid);
+ qcdm_result_add_uint32 (result, QCDM_CMD_CDMA_STATUS_ITEM_SID, tmp_num);
+
+ tmp_num = (guint32) GUINT16_FROM_LE (rsp->nid);
+ qcdm_result_add_uint32 (result, QCDM_CMD_CDMA_STATUS_ITEM_NID, tmp_num);
+
+ return result;
+}
+
+/**********************************************************************/
+
+gsize
+qcdm_cmd_sw_version_new (char *buf, gsize len, GError **error)
+{
+ char cmdbuf[3];
+ DMCmdHeader *cmd = (DMCmdHeader *) &cmdbuf[0];
+
+ g_return_val_if_fail (buf != NULL, 0);
+ g_return_val_if_fail (len >= sizeof (*cmd) + DIAG_TRAILER_LEN, 0);
+
+ memset (cmd, 0, sizeof (cmd));
+ cmd->code = DIAG_CMD_SW_VERSION;
+
+ return dm_encapsulate_buffer (cmdbuf, sizeof (*cmd), sizeof (cmdbuf), buf, len);
+}
+
+QCDMResult *
+qcdm_cmd_sw_version_result (const char *buf, gsize len, GError **error)
+{
+ QCDMResult *result = NULL;
+ DMCmdSwVersionRsp *rsp = (DMCmdSwVersionRsp *) buf;
+ char tmp[25];
+
+ g_return_val_if_fail (buf != NULL, NULL);
+
+ if (!check_command (buf, len, DIAG_CMD_SW_VERSION, sizeof (*rsp), error))
+ return NULL;
+
+ result = qcdm_result_new ();
+
+ memset (tmp, 0, sizeof (tmp));
+ g_assert (sizeof (rsp->version) <= sizeof (tmp));
+ memcpy (tmp, rsp->version, sizeof (rsp->version));
+ qcdm_result_add_string (result, QCDM_CMD_SW_VERSION_ITEM_VERSION, tmp);
+
+ memset (tmp, 0, sizeof (tmp));
+ g_assert (sizeof (rsp->comp_date) <= sizeof (tmp));
+ memcpy (tmp, rsp->comp_date, sizeof (rsp->comp_date));
+ qcdm_result_add_string (result, QCDM_CMD_SW_VERSION_ITEM_COMP_DATE, tmp);
+
+ memset (tmp, 0, sizeof (tmp));
+ g_assert (sizeof (rsp->comp_time) <= sizeof (tmp));
+ memcpy (tmp, rsp->comp_time, sizeof (rsp->comp_time));
+ qcdm_result_add_string (result, QCDM_CMD_SW_VERSION_ITEM_COMP_TIME, tmp);
+
+ return result;
+}
+
+/**********************************************************************/
+
+gsize
+qcdm_cmd_nv_get_mdn_new (char *buf, gsize len, guint8 profile, GError **error)
+{
+ char cmdbuf[sizeof (DMCmdNVReadWrite) + 2];
+ DMCmdNVReadWrite *cmd = (DMCmdNVReadWrite *) &cmdbuf[0];
+ DMNVItemMdn *req;
+
+ g_return_val_if_fail (buf != NULL, 0);
+ g_return_val_if_fail (len >= sizeof (*cmd) + DIAG_TRAILER_LEN, 0);
+
+ memset (cmd, 0, sizeof (*cmd));
+ cmd->code = DIAG_CMD_NV_READ;
+ cmd->nv_item = GUINT16_TO_LE (DIAG_NV_DIR_NUMBER);
+
+ req = (DMNVItemMdn *) &cmd->data[0];
+ req->profile = profile;
+
+ return dm_encapsulate_buffer (cmdbuf, sizeof (*cmd), sizeof (cmdbuf), buf, len);
+}
+
+QCDMResult *
+qcdm_cmd_nv_get_mdn_result (const char *buf, gsize len, GError **error)
+{
+ QCDMResult *result = NULL;
+ DMCmdNVReadWrite *rsp = (DMCmdNVReadWrite *) buf;
+ DMNVItemMdn *mdn;
+ char tmp[11];
+
+ g_return_val_if_fail (buf != NULL, NULL);
+
+ if (!check_command (buf, len, DIAG_CMD_NV_READ, sizeof (DMCmdNVReadWrite), error))
+ return NULL;
+
+ mdn = (DMNVItemMdn *) &rsp->data[0];
+
+ result = qcdm_result_new ();
+
+ qcdm_result_add_uint8 (result, QCDM_CMD_NV_GET_MDN_ITEM_PROFILE, mdn->profile);
+
+ memset (tmp, 0, sizeof (tmp));
+ g_assert (sizeof (mdn->mdn) <= sizeof (tmp));
+ memcpy (tmp, mdn->mdn, sizeof (mdn->mdn));
+ qcdm_result_add_string (result, QCDM_CMD_NV_GET_MDN_ITEM_MDN, tmp);
+
+ return result;
+}
+
+/**********************************************************************/
+
+gsize
+qcdm_cmd_cm_subsys_state_info_new (char *buf, gsize len, GError **error)
+{
+ char cmdbuf[sizeof (DMCmdSubsysHeader) + 2];
+ DMCmdSubsysHeader *cmd = (DMCmdSubsysHeader *) &cmdbuf[0];
+
+ g_return_val_if_fail (buf != NULL, 0);
+ g_return_val_if_fail (len >= sizeof (*cmd) + DIAG_TRAILER_LEN, 0);
+
+ memset (cmd, 0, sizeof (cmd));
+ cmd->code = DIAG_CMD_SUBSYS;
+ cmd->subsys_id = DIAG_SUBSYS_CM;
+ cmd->subsys_cmd = GUINT16_TO_LE (DIAG_SUBSYS_CM_STATE_INFO);
+
+ return dm_encapsulate_buffer (cmdbuf, sizeof (*cmd), sizeof (cmdbuf), buf, len);
+}
+
+QCDMResult *
+qcdm_cmd_cm_subsys_state_info_result (const char *buf, gsize len, GError **error)
+{
+ QCDMResult *result = NULL;
+ DMCmdSubsysCMStateInfoRsp *rsp = (DMCmdSubsysCMStateInfoRsp *) buf;
+ guint32 tmp_num;
+
+ g_return_val_if_fail (buf != NULL, NULL);
+
+ if (!check_command (buf, len, DIAG_CMD_SUBSYS, sizeof (DMCmdSubsysCMStateInfoRsp), error))
+ return NULL;
+
+ result = qcdm_result_new ();
+
+ tmp_num = (guint32) GUINT32_FROM_LE (rsp->call_state);
+ qcdm_result_add_uint32 (result, QCDM_CMD_CM_SUBSYS_STATE_INFO_ITEM_CALL_STATE, tmp_num);
+
+ tmp_num = (guint32) GUINT32_FROM_LE (rsp->oper_mode);
+ qcdm_result_add_uint32 (result, QCDM_CMD_CM_SUBSYS_STATE_INFO_ITEM_OPERATING_MODE, tmp_num);
+
+ tmp_num = (guint32) GUINT32_FROM_LE (rsp->system_mode);
+ qcdm_result_add_uint32 (result, QCDM_CMD_CM_SUBSYS_STATE_INFO_ITEM_SYSTEM_MODE, tmp_num);
+
+ tmp_num = (guint32) GUINT32_FROM_LE (rsp->mode_pref);
+ qcdm_result_add_uint32 (result, QCDM_CMD_CM_SUBSYS_STATE_INFO_ITEM_MODE_PREF, tmp_num);
+
+ tmp_num = (guint32) GUINT32_FROM_LE (rsp->band_pref);
+ qcdm_result_add_uint32 (result, QCDM_CMD_CM_SUBSYS_STATE_INFO_ITEM_BAND_PREF, tmp_num);
+
+ tmp_num = (guint32) GUINT32_FROM_LE (rsp->roam_pref);
+ qcdm_result_add_uint32 (result, QCDM_CMD_CM_SUBSYS_STATE_INFO_ITEM_ROAM_PREF, tmp_num);
+
+ tmp_num = (guint32) GUINT32_FROM_LE (rsp->srv_domain_pref);
+ qcdm_result_add_uint32 (result, QCDM_CMD_CM_SUBSYS_STATE_INFO_ITEM_SERVICE_DOMAIN_PREF, tmp_num);
+
+ tmp_num = (guint32) GUINT32_FROM_LE (rsp->acq_order_pref);
+ qcdm_result_add_uint32 (result, QCDM_CMD_CM_SUBSYS_STATE_INFO_ITEM_ACQ_ORDER_PREF, tmp_num);
+
+ tmp_num = (guint32) GUINT32_FROM_LE (rsp->hybrid_pref);
+ qcdm_result_add_uint32 (result, QCDM_CMD_CM_SUBSYS_STATE_INFO_ITEM_HYBRID_PREF, tmp_num);
+
+ tmp_num = (guint32) GUINT32_FROM_LE (rsp->network_sel_mode_pref);
+ qcdm_result_add_uint32 (result, QCDM_CMD_CM_SUBSYS_STATE_INFO_ITEM_NETWORK_SELECTION_PREF, tmp_num);
+
+ return result;
+}
+
+/**********************************************************************/
+
+gsize
+qcdm_cmd_hdr_subsys_state_info_new (char *buf, gsize len, GError **error)
+{
+ char cmdbuf[sizeof (DMCmdSubsysHeader) + 2];
+ DMCmdSubsysHeader *cmd = (DMCmdSubsysHeader *) &cmdbuf[0];
+
+ g_return_val_if_fail (buf != NULL, 0);
+ g_return_val_if_fail (len >= sizeof (*cmd) + DIAG_TRAILER_LEN, 0);
+
+ memset (cmd, 0, sizeof (cmd));
+ cmd->code = DIAG_CMD_SUBSYS;
+ cmd->subsys_id = DIAG_SUBSYS_HDR;
+ cmd->subsys_cmd = GUINT16_TO_LE (DIAG_SUBSYS_HDR_STATE_INFO);
+
+ return dm_encapsulate_buffer (cmdbuf, sizeof (*cmd), sizeof (cmdbuf), buf, len);
+}
+
+QCDMResult *
+qcdm_cmd_hdr_subsys_state_info_result (const char *buf, gsize len, GError **error)
+{
+ QCDMResult *result = NULL;
+ DMCmdSubsysHDRStateInfoRsp *rsp = (DMCmdSubsysHDRStateInfoRsp *) buf;
+
+ g_return_val_if_fail (buf != NULL, NULL);
+
+ if (!check_command (buf, len, DIAG_CMD_SUBSYS, sizeof (DMCmdSubsysHDRStateInfoRsp), error))
+ return NULL;
+
+ result = qcdm_result_new ();
+
+ qcdm_result_add_uint8 (result, QCDM_CMD_HDR_SUBSYS_STATE_INFO_ITEM_AT_STATE, rsp->at_state);
+ qcdm_result_add_uint8 (result, QCDM_CMD_HDR_SUBSYS_STATE_INFO_ITEM_SESSION_STATE, rsp->session_state);
+ qcdm_result_add_uint8 (result, QCDM_CMD_HDR_SUBSYS_STATE_INFO_ITEM_ALMP_STATE, rsp->almp_state);
+ qcdm_result_add_uint8 (result, QCDM_CMD_HDR_SUBSYS_STATE_INFO_ITEM_INIT_STATE, rsp->init_state);
+ qcdm_result_add_uint8 (result, QCDM_CMD_HDR_SUBSYS_STATE_INFO_ITEM_IDLE_STATE, rsp->idle_state);
+ qcdm_result_add_uint8 (result, QCDM_CMD_HDR_SUBSYS_STATE_INFO_ITEM_CONNECTED_STATE, rsp->connected_state);
+ qcdm_result_add_uint8 (result, QCDM_CMD_HDR_SUBSYS_STATE_INFO_ITEM_ROUTE_UPDATE_STATE, rsp->route_update_state);
+ qcdm_result_add_uint8 (result, QCDM_CMD_HDR_SUBSYS_STATE_INFO_ITEM_OVERHEAD_MSG_STATE, rsp->overhead_msg_state);
+ qcdm_result_add_uint8 (result, QCDM_CMD_HDR_SUBSYS_STATE_INFO_ITEM_HDR_HYBRID_MODE, rsp->hdr_hybrid_mode);
+
+ return result;
+}
+
+/**********************************************************************/
+
diff --git a/libqcdm/src/commands.h b/libqcdm/src/commands.h
new file mode 100644
index 00000000..f1b6f77e
--- /dev/null
+++ b/libqcdm/src/commands.h
@@ -0,0 +1,235 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * Copyright (C) 2010 Red Hat, Inc.
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef LIBQCDM_COMMANDS_H
+#define LIBQCDM_COMMANDS_H
+
+#include <glib.h>
+
+#include "result.h"
+
+/**********************************************************************/
+
+#define QCDM_CMD_VERSION_INFO_ITEM_COMP_DATE "comp-date"
+#define QCDM_CMD_VERSION_INFO_ITEM_COMP_TIME "comp-time"
+#define QCDM_CMD_VERSION_INFO_ITEM_RELEASE_DATE "release-date"
+#define QCDM_CMD_VERSION_INFO_ITEM_RELEASE_TIME "release-time"
+#define QCDM_CMD_VERSION_INFO_ITEM_MODEL "model"
+
+gsize qcdm_cmd_version_info_new (char *buf,
+ gsize len,
+ GError **error);
+
+QCDMResult *qcdm_cmd_version_info_result (const char *buf,
+ gsize len,
+ GError **error);
+
+/**********************************************************************/
+
+#define QCDM_CMD_ESN_ITEM_ESN "esn"
+
+gsize qcdm_cmd_esn_new (char *buf,
+ gsize len,
+ GError **error);
+
+QCDMResult *qcdm_cmd_esn_result (const char *buf,
+ gsize len,
+ GError **error);
+
+/**********************************************************************/
+
+/* Values for QCDM_CMD_CDMA_STATUS_ITEM_RX_STATE */
+enum {
+ QCDM_CMD_CDMA_STATUS_RX_STATE_NO_SERVICE = 0,
+ QCDM_CMD_CDMA_STATUS_RX_STATE_IDLE = 1,
+ QCDM_CMD_CDMA_STATUS_RX_STATE_ACCESS = 2,
+ QCDM_CMD_CDMA_STATUS_RX_STATE_PAGING = 3,
+ QCDM_CMD_CDMA_STATUS_RX_STATE_TRAFFIC = 4,
+};
+
+#define QCDM_CMD_CDMA_STATUS_ITEM_ESN "esn"
+#define QCDM_CMD_CDMA_STATUS_ITEM_RX_STATE "rx-state"
+#define QCDM_CMD_CDMA_STATUS_ITEM_ENTRY_REASON "entry-reason"
+#define QCDM_CMD_CDMA_STATUS_ITEM_CURRENT_CHANNEL "current-channel"
+#define QCDM_CMD_CDMA_STATUS_ITEM_CODE_CHANNEL "code-channel"
+#define QCDM_CMD_CDMA_STATUS_ITEM_PILOT_BASE "pilot-base"
+#define QCDM_CMD_CDMA_STATUS_ITEM_SID "sid"
+#define QCDM_CMD_CDMA_STATUS_ITEM_NID "nid"
+
+gsize qcdm_cmd_cdma_status_new (char *buf,
+ gsize len,
+ GError **error);
+
+QCDMResult *qcdm_cmd_cdma_status_result (const char *buf,
+ gsize len,
+ GError **error);
+
+/**********************************************************************/
+
+/* NOTE: this command does not appear to be implemented in recent
+ * devices and probably returns (QCDM_COMMAND_ERROR, QCDM_COMMAND_BAD_COMMAND).
+ */
+
+#define QCDM_CMD_SW_VERSION_ITEM_VERSION "version"
+#define QCDM_CMD_SW_VERSION_ITEM_COMP_DATE "comp-date"
+#define QCDM_CMD_SW_VERSION_ITEM_COMP_TIME "comp-time"
+
+gsize qcdm_cmd_sw_version_new (char *buf,
+ gsize len,
+ GError **error);
+
+QCDMResult *qcdm_cmd_sw_version_result (const char *buf,
+ gsize len,
+ GError **error);
+
+/**********************************************************************/
+
+#define QCDM_CMD_NV_GET_MDN_ITEM_PROFILE "profile"
+#define QCDM_CMD_NV_GET_MDN_ITEM_MDN "mdn"
+
+gsize qcdm_cmd_nv_get_mdn_new (char *buf,
+ gsize len,
+ guint8 profile,
+ GError **error);
+
+QCDMResult *qcdm_cmd_nv_get_mdn_result (const char *buf,
+ gsize len,
+ GError **error);
+
+/**********************************************************************/
+
+/* Values for QCDM_CMD_CM_SUBSYS_STATE_INFO_ITEM_OPERATING_MODE */
+enum {
+ QCDM_CMD_CM_SUBSYS_STATE_INFO_OPERATING_MODE_ONLINE = 5
+};
+
+/* Values for QCDM_CMD_CM_SUBSYS_STATE_INFO_ITEM_SYSTEM_MODE */
+enum {
+ QCDM_CMD_CM_SUBSYS_STATE_INFO_SYSTEM_MODE_NO_SERVICE = 0,
+ QCDM_CMD_CM_SUBSYS_STATE_INFO_SYSTEM_MODE_AMPS = 1,
+ QCDM_CMD_CM_SUBSYS_STATE_INFO_SYSTEM_MODE_CDMA = 2,
+ QCDM_CMD_CM_SUBSYS_STATE_INFO_SYSTEM_MODE_HDR = 4,
+ QCDM_CMD_CM_SUBSYS_STATE_INFO_SYSTEM_MODE_WCDMA = 5
+};
+
+#define QCDM_CMD_CM_SUBSYS_STATE_INFO_ITEM_CALL_STATE "call-state"
+#define QCDM_CMD_CM_SUBSYS_STATE_INFO_ITEM_OPERATING_MODE "operating-mode"
+#define QCDM_CMD_CM_SUBSYS_STATE_INFO_ITEM_SYSTEM_MODE "system-mode"
+#define QCDM_CMD_CM_SUBSYS_STATE_INFO_ITEM_MODE_PREF "mode-pref"
+#define QCDM_CMD_CM_SUBSYS_STATE_INFO_ITEM_BAND_PREF "band-pref"
+#define QCDM_CMD_CM_SUBSYS_STATE_INFO_ITEM_ROAM_PREF "roam-pref"
+#define QCDM_CMD_CM_SUBSYS_STATE_INFO_ITEM_SERVICE_DOMAIN_PREF "service-domain-pref"
+#define QCDM_CMD_CM_SUBSYS_STATE_INFO_ITEM_ACQ_ORDER_PREF "acq-order-pref"
+#define QCDM_CMD_CM_SUBSYS_STATE_INFO_ITEM_HYBRID_PREF "hybrid-pref"
+#define QCDM_CMD_CM_SUBSYS_STATE_INFO_ITEM_NETWORK_SELECTION_PREF "network-selection-pref"
+
+gsize qcdm_cmd_cm_subsys_state_info_new (char *buf,
+ gsize len,
+ GError **error);
+
+QCDMResult *qcdm_cmd_cm_subsys_state_info_result (const char *buf,
+ gsize len,
+ GError **error);
+
+/**********************************************************************/
+
+/* Values for QCDM_CMD_HDR_SUBSYS_STATE_INFO_ITEM_AT_STATE */
+enum {
+ QCDM_CMD_HDR_SUBSYS_STATE_INFO_AT_STATE_INACTIVE = 0,
+ QCDM_CMD_HDR_SUBSYS_STATE_INFO_AT_STATE_ACQUISITION = 1,
+ QCDM_CMD_HDR_SUBSYS_STATE_INFO_AT_STATE_SYNC = 2,
+ QCDM_CMD_HDR_SUBSYS_STATE_INFO_AT_STATE_IDLE = 3,
+ QCDM_CMD_HDR_SUBSYS_STATE_INFO_AT_STATE_ACCESS = 4,
+ QCDM_CMD_HDR_SUBSYS_STATE_INFO_AT_STATE_CONNECTED = 5
+};
+
+/* Values for QCDM_CMD_HDR_SUBSYS_STATE_INFO_ITEM_SESSION_STATE */
+enum {
+ QCDM_CMD_HDR_SUBSYS_STATE_INFO_SESSION_STATE_CLOSED = 0,
+ QCDM_CMD_HDR_SUBSYS_STATE_INFO_SESSION_STATE_SETUP = 1,
+ QCDM_CMD_HDR_SUBSYS_STATE_INFO_SESSION_STATE_AT_INIT = 2, /* initiated by Access Terminal */
+ QCDM_CMD_HDR_SUBSYS_STATE_INFO_SESSION_STATE_AN_INIT = 3, /* initiated by Access Node */
+ QCDM_CMD_HDR_SUBSYS_STATE_INFO_SESSION_STATE_OPEN = 4,
+ QCDM_CMD_HDR_SUBSYS_STATE_INFO_SESSION_STATE_CLOSING = 5
+};
+
+/* Values for QCDM_CMD_HDR_SUBSYS_STATE_INFO_ITEM_ALMP_STATE (TIA-856-A section 9.2.1) */
+enum {
+ QCDM_CMD_HDR_SUBSYS_STATE_INFO_ALMP_STATE_INACTIVE = 0, /* initial state */
+ QCDM_CMD_HDR_SUBSYS_STATE_INFO_ALMP_STATE_INIT = 1, /* terminal has yet to acquire network */
+ QCDM_CMD_HDR_SUBSYS_STATE_INFO_ALMP_STATE_IDLE = 2, /* network acquired but no connection */
+ QCDM_CMD_HDR_SUBSYS_STATE_INFO_ALMP_STATE_CONNECTED = 3, /* open connection to the network */
+};
+
+/* Values for QCDM_CMD_HDR_SUBSYS_STATE_INFO_ITEM_INIT_STATE (TIA-856-A section 9.3.1) */
+enum {
+ QCDM_CMD_HDR_SUBSYS_STATE_INFO_INIT_STATE_INACTIVE = 0, /* protocol waiting for ACTIVATE command */
+ QCDM_CMD_HDR_SUBSYS_STATE_INFO_INIT_STATE_NET_DETERMINE = 1, /* choosing a network to operate on */
+ QCDM_CMD_HDR_SUBSYS_STATE_INFO_INIT_STATE_ACQUISITION = 2, /* acquiring Forward Pilot Channel */
+ QCDM_CMD_HDR_SUBSYS_STATE_INFO_INIT_STATE_SYNC = 3, /* synchronizing to Control Channel */
+};
+
+/* Values for QCDM_CMD_HDR_SUBSYS_STATE_INFO_ITEM_IDLE_STATE (TIA-856-A section 9.4.1) */
+enum {
+ QCDM_CMD_HDR_SUBSYS_STATE_INFO_IDLE_STATE_INACTIVE = 0, /* protocol waiting for ACTIVATE command */
+ QCDM_CMD_HDR_SUBSYS_STATE_INFO_IDLE_STATE_SLEEP = 1, /* sleeping */
+ QCDM_CMD_HDR_SUBSYS_STATE_INFO_IDLE_STATE_MONITOR = 2, /* monitoring the Control Channel */
+ QCDM_CMD_HDR_SUBSYS_STATE_INFO_IDLE_STATE_SETUP = 3, /* setting up a connection */
+};
+
+/* Values for QCDM_CMD_HDR_SUBSYS_STATE_INFO_ITEM_CONNECTED_STATE (TIA-856-A section 9.6.1) */
+enum {
+ QCDM_CMD_HDR_SUBSYS_STATE_INFO_CONNECTED_STATE_INACTIVE = 0, /* protocol waiting for ACTIVATE command */
+ QCDM_CMD_HDR_SUBSYS_STATE_INFO_CONNECTED_STATE_OPEN = 1, /* connection is open */
+ QCDM_CMD_HDR_SUBSYS_STATE_INFO_CONNECTED_STATE_CLOSING = 2, /* connection is closed */
+};
+
+/* Values for QCDM_CMD_HDR_SUBSYS_STATE_INFO_ITEM_ROUTE_UPDATE (TIA-856-A section 9.7.1) */
+enum {
+ QCDM_CMD_HDR_SUBSYS_STATE_INFO_ROUTE_UPDATE_STATE_INACTIVE = 0,
+ QCDM_CMD_HDR_SUBSYS_STATE_INFO_ROUTE_UPDATE_STATE_IDLE = 1,
+ QCDM_CMD_HDR_SUBSYS_STATE_INFO_ROUTE_UPDATE_STATE_CONNECTED = 2,
+};
+
+/* Values for QCDM_CMD_HDR_SUBSYS_STATE_INFO_ITEM_OVERHEAD_MSG (TIA-856-A section 9.9.1) */
+enum {
+ QCDM_CMD_HDR_SUBSYS_STATE_INFO_OVERHEAD_MSG_STATE_INIT = 0,
+ QCDM_CMD_HDR_SUBSYS_STATE_INFO_OVERHEAD_MSG_STATE_INACTIVE = 1,
+ QCDM_CMD_HDR_SUBSYS_STATE_INFO_OVERHEAD_MSG_STATE_ACTIVE = 2,
+};
+
+#define QCDM_CMD_HDR_SUBSYS_STATE_INFO_ITEM_AT_STATE "at-state" /* State of Access Terminal */
+#define QCDM_CMD_HDR_SUBSYS_STATE_INFO_ITEM_SESSION_STATE "session-state" /* Current session state */
+#define QCDM_CMD_HDR_SUBSYS_STATE_INFO_ITEM_ALMP_STATE "almp-state" /* Air Link Management Protocol (ALMP) state */
+#define QCDM_CMD_HDR_SUBSYS_STATE_INFO_ITEM_INIT_STATE "init-state" /* Initialization State Protocol (ISP) state */
+#define QCDM_CMD_HDR_SUBSYS_STATE_INFO_ITEM_IDLE_STATE "idle-state" /* Idle State Protocol (IDP) state */
+#define QCDM_CMD_HDR_SUBSYS_STATE_INFO_ITEM_CONNECTED_STATE "connected-state" /* Connected State Protocol (CSP) state */
+#define QCDM_CMD_HDR_SUBSYS_STATE_INFO_ITEM_ROUTE_UPDATE_STATE "route-update-state" /* Route Update Protocol (RUP) state */
+#define QCDM_CMD_HDR_SUBSYS_STATE_INFO_ITEM_OVERHEAD_MSG_STATE "overhead-msg-state"
+#define QCDM_CMD_HDR_SUBSYS_STATE_INFO_ITEM_HDR_HYBRID_MODE "hdr-hybrid-mode"
+
+gsize qcdm_cmd_hdr_subsys_state_info_new (char *buf,
+ gsize len,
+ GError **error);
+
+QCDMResult *qcdm_cmd_hdr_subsys_state_info_result (const char *buf,
+ gsize len,
+ GError **error);
+
+/**********************************************************************/
+
+#endif /* LIBQCDM_COMMANDS_H */
diff --git a/libqcdm/src/dm-commands.h b/libqcdm/src/dm-commands.h
new file mode 100644
index 00000000..bad9e932
--- /dev/null
+++ b/libqcdm/src/dm-commands.h
@@ -0,0 +1,254 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * Copyright (C) 2010 Red Hat, Inc.
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef LIBQCDM_DM_COMMANDS_H
+#define LIBQCDM_DM_COMMANDS_H
+
+enum {
+ DIAG_CMD_VERSION_INFO = 0, /* Version info */
+ DIAG_CMD_ESN = 1, /* ESN */
+ DIAG_CMD_PEEKB = 2, /* Peek byte */
+ DIAG_CMD_PEEKW = 3, /* Peek word */
+ DIAG_CMD_PEEKD = 4, /* Peek dword */
+ DIAG_CMD_POKEB = 5, /* Poke byte */
+ DIAG_CMD_POKEW = 6, /* Poke word */
+ DIAG_CMD_POKED = 7, /* Poke dword */
+ DIAG_CMD_OUTP = 8, /* Byte output */
+ DIAG_CMD_OUTPW = 9, /* Word output */
+ DIAG_CMD_INP = 10, /* Byte input */
+ DIAG_CMD_INPW = 11, /* Word input */
+ DIAG_CMD_STATUS = 12, /* Station status */
+ DIAG_CMD_LOGMASK = 15, /* Set logging mask */
+ DIAG_CMD_LOG = 16, /* Log packet */
+ DIAG_CMD_NV_PEEK = 17, /* Peek NV memory */
+ DIAG_CMD_NV_POKE = 18, /* Poke NV memory */
+ DIAG_CMD_BAD_CMD = 19, /* Invalid command (response) */
+ DIAG_CMD_BAD_PARM = 20, /* Invalid parameter (response) */
+ DIAG_CMD_BAD_LEN = 21, /* Invalid packet length (response) */
+ DIAG_CMD_BAD_DEV = 22, /* Not accepted by the device (response) */
+ DIAG_CMD_BAD_MODE = 24, /* Not allowed in this mode (response) */
+ DIAG_CMD_TAGRAPH = 25, /* Info for TA power and voice graphs */
+ DIAG_CMD_MARKOV = 26, /* Markov stats */
+ DIAG_CMD_MARKOV_RESET = 27, /* Reset Markov stats */
+ DIAG_CMD_DIAG_VER = 28, /* Diagnostic Monitor version */
+ DIAG_CMD_TIMESTAMP = 29, /* Return a timestamp */
+ DIAG_CMD_TA_PARM = 30, /* Set TA parameters */
+ DIAG_CMD_MESSAGE = 31, /* Request for msg report */
+ DIAG_CMD_HS_KEY = 32, /* Handset emulation -- keypress */
+ DIAG_CMD_HS_LOCK = 33, /* Handset emulation -- lock or unlock */
+ DIAG_CMD_HS_SCREEN = 34, /* Handset emulation -- display request */
+ DIAG_CMD_PARM_SET = 36, /* Parameter download */
+ DIAG_CMD_NV_READ = 38, /* Read NV item */
+ DIAG_CMD_NV_WRITE = 39, /* Write NV item */
+ DIAG_CMD_CONTROL = 41, /* Mode change request */
+ DIAG_CMD_ERR_READ = 42, /* Error record retreival */
+ DIAG_CMD_ERR_CLEAR = 43, /* Error record clear */
+ DIAG_CMD_SER_RESET = 44, /* Symbol error rate counter reset */
+ DIAG_CMD_SER_REPORT = 45, /* Symbol error rate counter report */
+ DIAG_CMD_TEST = 46, /* Run a specified test */
+ DIAG_CMD_GET_DIPSW = 47, /* Retreive the current DIP switch setting */
+ DIAG_CMD_SET_DIPSW = 48, /* Write new DIP switch setting */
+ DIAG_CMD_VOC_PCM_LB = 49, /* Start/Stop Vocoder PCM loopback */
+ DIAG_CMD_VOC_PKT_LB = 50, /* Start/Stop Vocoder PKT loopback */
+ DIAG_CMD_ORIG = 53, /* Originate a call */
+ DIAG_CMD_END = 54, /* End a call */
+ DIAG_CMD_SW_VERSION = 56, /* Get software version */
+ DIAG_CMD_DLOAD = 58, /* Switch to downloader */
+ DIAG_CMD_TMOB = 59, /* Test Mode Commands and FTM commands*/
+ DIAG_CMD_STATE = 63, /* Current state of the phone */
+ DIAG_CMD_PILOT_SETS = 64, /* Return all current sets of pilots */
+ DIAG_CMD_SPC = 65, /* Send the Service Programming Code to unlock */
+ DIAG_CMD_BAD_SPC_MODE = 66, /* Invalid NV read/write because SP is locked */
+ DIAG_CMD_PARM_GET2 = 67, /* (obsolete) */
+ DIAG_CMD_SERIAL_CHG = 68, /* Serial mode change */
+ DIAG_CMD_PASSWORD = 70, /* Send password to unlock secure operations */
+ DIAG_CMD_BAD_SEC_MODE = 71, /* Operation not allowed in this security state */
+ DIAG_CMD_PRL_WRITE = 72, /* Write PRL */
+ DIAG_CMD_PRL_READ = 73, /* Read PRL */
+ DIAG_CMD_SUBSYS = 75, /* Subsystem commands */
+ DIAG_CMD_FEATURE_QUERY = 81,
+ DIAG_CMD_SMS_READ = 83, /* Read SMS message out of NV memory */
+ DIAG_CMD_SMS_WRITE = 84, /* Write SMS message into NV memory */
+ DIAG_CMD_SUP_FER = 85, /* Frame Error Rate info on multiple channels */
+ DIAG_CMD_SUP_WALSH_CODES = 86, /* Supplemental channel walsh codes */
+ DIAG_CMD_SET_MAX_SUP_CH = 87, /* Sets the maximum # supplemental channels */
+ DIAG_CMD_PARM_GET_IS95B = 88, /* Get parameters including SUPP and MUX2 */
+ DIAG_CMD_FS_OP = 89, /* Embedded File System (EFS) operations */
+ DIAG_CMD_AKEY_VERIFY = 90, /* AKEY Verification */
+ DIAG_CMD_HS_BMP_SCREEN = 91, /* Handset Emulation -- Bitmap screen */
+ DIAG_CMD_CONFIG_COMM = 92, /* Configure communications */
+ DIAG_CMD_EXT_LOGMASK = 93, /* Extended logmask for > 32 bits */
+ DIAG_CMD_EVENT_REPORT = 96, /* Static Event reporting */
+ DIAG_CMD_STREAMING_CONFIG = 97, /* Load balancing etc */
+ DIAG_CMD_PARM_RETRIEVE = 98, /* Parameter retrieval */
+ DIAG_CMD_STATUS_SNAPSHOT = 99, /* Status snapshot */
+ DIAG_CMD_RPC = 100, /* Used for RPC */
+ DIAG_CMD_GET_PROPERTY = 101,
+ DIAG_CMD_PUT_PROPERTY = 102,
+ DIAG_CMD_GET_GUID = 103, /* GUID requests */
+ DIAG_CMD_USER_CMD = 104, /* User callbacks */
+ DIAG_CMD_GET_PERM_PROPERTY = 105,
+ DIAG_CMD_PUT_PERM_PROPERTY = 106,
+ DIAG_CMD_PERM_USER_CMD = 107, /* Permanent user callbacks */
+ DIAG_CMD_GPS_SESS_CTRL = 108, /* GPS session control */
+ DIAG_CMD_GPS_GRID = 109, /* GPS search grid */
+ DIAG_CMD_GPS_STATISTICS = 110,
+ DIAG_CMD_TUNNEL = 111, /* Tunneling command code */
+ DIAG_CMD_RAM_RW = 112, /* Calibration RAM control using DM */
+ DIAG_CMD_CPU_RW = 113, /* Calibration CPU control using DM */
+ DIAG_CMD_SET_FTM_TEST_MODE = 114, /* Field (or Factory?) Test Mode */
+};
+
+/* Subsystem IDs used with DIAG_CMD_SUBSYS; these often obsolete many of
+ * the original DM commands.
+ */
+enum {
+ DIAG_SUBSYS_HDR = 5, /* High Data Rate (ie, EVDO) */
+ DIAG_SUBSYS_GPS = 13,
+ DIAG_SUBSYS_SMS = 14,
+ DIAG_SUBSYS_CM = 15, /* Call manager */
+ DIAG_SUBSYS_NW_CONTROL_6500 = 50, /* for Novatel Wireless MSM6500-based devices */
+ DIAG_SUBSYS_NW_CONTROL_6800 = 250 /* for Novatel Wireless MSM6800-based devices */
+};
+
+/* HDR subsystem command codes */
+enum {
+ DIAG_SUBSYS_HDR_STATE_INFO = 8, /* Gets EVDO state */
+};
+
+enum {
+ DIAG_SUBSYS_CM_STATE_INFO = 0, /* Gets Call Manager state */
+};
+
+/* NW_CONTROL subsystem command codes (only for Novatel Wireless devices) */
+enum {
+ DIAG_SUBSYS_NW_CONTROL_AT_REQUEST = 3, /* AT commands via diag */
+ DIAG_SUBSYS_NW_CONTROL_AT_RESPONSE = 4,
+ DIAG_SUBSYS_NW_CONTROL_MODEM_STATUS = 7, /* Modem status */
+ DIAG_SUBSYS_NW_CONTROL_ERI = 8, /* Extended Roaming Indicator */
+ DIAG_SUBSYS_NW_CONTROL_PRL = 12,
+};
+
+enum {
+ DIAG_SUBSYS_NW_CONTROL_MODEM_STATUS_CDMA = 7,
+ DIAG_SUBSYS_NW_CONTROL_MODEM_STATUS_WCDMA = 20,
+};
+
+/* Generic DM command header */
+struct DMCmdHeader {
+ guint8 code;
+} __attribute__ ((packed));
+typedef struct DMCmdHeader DMCmdHeader;
+
+/* DIAG_CMD_SUBSYS */
+struct DMCmdSubsysHeader {
+ guint8 code;
+ guint8 subsys_id;
+ guint16 subsys_cmd;
+} __attribute__ ((packed));
+typedef struct DMCmdSubsysHeader DMCmdSubsysHeader;
+
+/* DIAG_CMD_NV_READ / DIAG_CMD_NV_WRITE */
+struct DMCmdNVReadWrite {
+ guint8 code;
+ guint16 nv_item;
+ guint8 data[128];
+ guint16 status;
+} __attribute__ ((packed));
+typedef struct DMCmdNVReadWrite DMCmdNVReadWrite;
+
+/* DIAG_CMD_VERSION_INFO */
+struct DMCmdVersionInfoRsp {
+ guint8 code;
+ char comp_date[11];
+ char comp_time[8];
+ char rel_date[11];
+ char rel_time[8];
+ char model[8];
+ guint8 _unknown[8];
+} __attribute__ ((packed));
+typedef struct DMCmdVersionInfoRsp DMCmdVersionInfoRsp;
+
+/* DIAG_CMD_ESN */
+struct DMCmdEsnRsp {
+ guint8 code;
+ guint8 esn[4];
+} __attribute__ ((packed));
+typedef struct DMCmdEsnRsp DMCmdEsnRsp;
+
+/* DIAG_CMD_STATUS */
+struct DMCmdStatusRsp {
+ guint8 code;
+ guint8 _unknown[3];
+ guint8 esn[4];
+ guint8 _unknown2[2];
+ guint8 _unknown3[8];
+ guint8 _unknown4[4];
+ guint16 cdma_rx_state;
+ guint16 entry_reason;
+ guint8 _unknown5[8];
+ guint16 curr_chan;
+ guint8 cdma_code_chan;
+ guint16 pilot_base;
+ guint16 sid;
+ guint16 nid;
+ guint8 _unknown6[5];
+} __attribute__ ((packed));
+typedef struct DMCmdStatusRsp DMCmdStatusRsp;
+
+/* DIAG_CMD_SW_VERSION */
+struct DMCmdSwVersionRsp {
+ guint8 code;
+ char version[20];
+ char comp_date[11];
+ char comp_time[8];
+} __attribute__ ((packed));
+typedef struct DMCmdSwVersionRsp DMCmdSwVersionRsp;
+
+/* DIAG_SUBSYS_CM_STATE_INFO subsys command */
+struct DMCmdSubsysCMStateInfoRsp {
+ DMCmdSubsysHeader header;
+ guint32 call_state;
+ guint32 oper_mode;
+ guint32 system_mode;
+ guint32 mode_pref;
+ guint32 band_pref;
+ guint32 roam_pref;
+ guint32 srv_domain_pref;
+ guint32 acq_order_pref;
+ guint32 hybrid_pref;
+ guint32 network_sel_mode_pref;
+} __attribute__ ((packed));
+typedef struct DMCmdSubsysCMStateInfoRsp DMCmdSubsysCMStateInfoRsp;
+
+/* DIAG_SUBSYS_HDR_STATE_INFO subsys command */
+struct DMCmdSubsysHDRStateInfoRsp {
+ DMCmdSubsysHeader header;
+ guint8 at_state;
+ guint8 session_state;
+ guint8 almp_state;
+ guint8 init_state;
+ guint8 idle_state;
+ guint8 connected_state;
+ guint8 route_update_state;
+ guint8 overhead_msg_state;
+ guint8 hdr_hybrid_mode;
+} __attribute__ ((packed));
+typedef struct DMCmdSubsysHDRStateInfoRsp DMCmdSubsysHDRStateInfoRsp;
+
+#endif /* LIBQCDM_DM_COMMANDS_H */
+
diff --git a/libqcdm/src/error.c b/libqcdm/src/error.c
new file mode 100644
index 00000000..bf16b56a
--- /dev/null
+++ b/libqcdm/src/error.c
@@ -0,0 +1,86 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * Copyright (C) 2010 Red Hat, Inc.
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "error.h"
+
+#define ENUM_ENTRY(NAME, DESC) { NAME, "" #NAME "", DESC }
+
+GQuark
+qcdm_serial_error_quark (void)
+{
+ static GQuark ret = 0;
+
+ if (ret == 0)
+ ret = g_quark_from_static_string ("qcdm-serial-error");
+
+ return ret;
+}
+
+GType
+qcdm_serial_error_get_type (void)
+{
+ static GType etype = 0;
+
+ if (etype == 0) {
+ static const GEnumValue values[] = {
+ ENUM_ENTRY (QCDM_SERIAL_CONFIG_FAILED, "SerialConfigFailed"),
+ { 0, 0, 0 }
+ };
+
+ etype = g_enum_register_static ("QcdmSerialError", values);
+ }
+
+ return etype;
+}
+
+/***************************************************************/
+
+GQuark
+qcdm_command_error_quark (void)
+{
+ static GQuark ret = 0;
+
+ if (ret == 0)
+ ret = g_quark_from_static_string ("qcdm-command-error");
+
+ return ret;
+}
+
+GType
+qcdm_command_error_get_type (void)
+{
+ static GType etype = 0;
+
+ if (etype == 0) {
+ static const GEnumValue values[] = {
+ ENUM_ENTRY (QCDM_COMMAND_MALFORMED_RESPONSE, "QcdmCommandMalformedResponse"),
+ ENUM_ENTRY (QCDM_COMMAND_UNEXPECTED, "QcdmCommandUnexpected"),
+ ENUM_ENTRY (QCDM_COMMAND_BAD_LENGTH, "QcdmCommandBadLength"),
+ ENUM_ENTRY (QCDM_COMMAND_BAD_COMMAND, "QcdmCommandBadCommand"),
+ ENUM_ENTRY (QCDM_COMMAND_BAD_PARAMETER, "QcdmCommandBadParameter"),
+ ENUM_ENTRY (QCDM_COMMAND_NOT_ACCEPTED, "QcdmCommandNotAccepted"),
+ ENUM_ENTRY (QCDM_COMMAND_BAD_MODE, "QcdmCommandBadMode"),
+ { 0, 0, 0 }
+ };
+
+ etype = g_enum_register_static ("QcdmCommandError", values);
+ }
+
+ return etype;
+}
+
+
diff --git a/libqcdm/src/error.h b/libqcdm/src/error.h
new file mode 100644
index 00000000..7098fcbe
--- /dev/null
+++ b/libqcdm/src/error.h
@@ -0,0 +1,52 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * Copyright (C) 2010 Red Hat, Inc.
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef LIBQCDM_ERROR_H
+#define LIBQCDM_ERROR_H
+
+#include <glib.h>
+#include <glib-object.h>
+
+enum {
+ QCDM_SERIAL_CONFIG_FAILED = 0,
+};
+
+#define QCDM_SERIAL_ERROR (qcdm_serial_error_quark ())
+#define QCDM_TYPE_SERIAL_ERROR (qcdm_serial_error_get_type ())
+
+GQuark qcdm_serial_error_quark (void);
+GType qcdm_serial_error_get_type (void);
+
+
+enum {
+ QCDM_COMMAND_MALFORMED_RESPONSE = 0,
+ QCDM_COMMAND_UNEXPECTED = 1,
+ QCDM_COMMAND_BAD_LENGTH = 2,
+ QCDM_COMMAND_BAD_COMMAND = 3,
+ QCDM_COMMAND_BAD_PARAMETER = 4,
+ QCDM_COMMAND_NOT_ACCEPTED = 5,
+ QCDM_COMMAND_BAD_MODE = 6
+};
+
+#define QCDM_COMMAND_ERROR (qcdm_command_error_quark ())
+#define QCDM_TYPE_COMMAND_ERROR (qcdm_command_error_get_type ())
+
+GQuark qcdm_command_error_quark (void);
+GType qcdm_command_error_get_type (void);
+
+#endif /* LIBQCDM_ERROR_H */
+
diff --git a/libqcdm/src/libqcdm.ver b/libqcdm/src/libqcdm.ver
new file mode 100644
index 00000000..b1567e20
--- /dev/null
+++ b/libqcdm/src/libqcdm.ver
@@ -0,0 +1,6 @@
+{
+global:
+ nm_vpn_connection_new;
+local:
+ *;
+};
diff --git a/libqcdm/src/nv-items.h b/libqcdm/src/nv-items.h
new file mode 100644
index 00000000..6f058121
--- /dev/null
+++ b/libqcdm/src/nv-items.h
@@ -0,0 +1,35 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * Copyright (C) 2010 Red Hat, Inc.
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef LIBQCDM_NV_ITEMS_H
+#define LIBQCDM_NV_ITEMS_H
+
+enum {
+ DIAG_NV_DIR_NUMBER = 178, /* Mobile Directory Number (MDN) */
+};
+
+
+/* DIAG_NV_DIR_NUMBER */
+struct DMNVItemMdn {
+ guint8 profile;
+ guint8 mdn[10];
+} __attribute__ ((packed));
+typedef struct DMNVItemMdn DMNVItemMdn;
+
+
+#endif /* LIBQCDM_NV_ITEMS_H */
+
diff --git a/libqcdm/src/result-private.h b/libqcdm/src/result-private.h
new file mode 100644
index 00000000..2a5fd5db
--- /dev/null
+++ b/libqcdm/src/result-private.h
@@ -0,0 +1,41 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * Copyright (C) 2010 Red Hat, Inc.
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef LIBQCDM_RESULT_PRIVATE_H
+#define LIBQCDM_RESULT_PRIVATE_H
+
+#include <glib.h>
+#include "result.h"
+
+QCDMResult *qcdm_result_new (void);
+
+/* For these functions, 'key' *must* be a constant, not allocated and freed */
+
+void qcdm_result_add_string (QCDMResult *result,
+ const char *key,
+ const char *str);
+
+void qcdm_result_add_uint8 (QCDMResult *result,
+ const char *key,
+ guint8 num);
+
+void qcdm_result_add_uint32 (QCDMResult *result,
+ const char *key,
+ guint32 num);
+
+#endif /* LIBQCDM_RESULT_PRIVATE_H */
+
diff --git a/libqcdm/src/result.c b/libqcdm/src/result.c
new file mode 100644
index 00000000..37898f39
--- /dev/null
+++ b/libqcdm/src/result.c
@@ -0,0 +1,206 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * Copyright (C) 2010 Red Hat, Inc.
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <string.h>
+#include <glib.h>
+
+#include "result.h"
+#include "result-private.h"
+#include "error.h"
+
+struct QCDMResult {
+ guint32 refcount;
+ GHashTable *hash;
+};
+
+
+static void
+gvalue_destroy (gpointer data)
+{
+ GValue *value = (GValue *) data;
+
+ g_value_unset (value);
+ g_slice_free (GValue, value);
+}
+
+QCDMResult *
+qcdm_result_new (void)
+{
+ QCDMResult *result;
+
+ g_type_init ();
+
+ result = g_malloc0 (sizeof (QCDMResult));
+ result->hash = g_hash_table_new_full (g_str_hash, g_str_equal,
+ NULL, gvalue_destroy);
+ result->refcount = 1;
+ return result;
+}
+
+QCDMResult *
+qcdm_result_ref (QCDMResult *result)
+{
+ g_return_val_if_fail (result != NULL, NULL);
+ g_return_val_if_fail (result->refcount > 0, NULL);
+
+ result->refcount++;
+ return result;
+}
+
+void
+qcdm_result_unref (QCDMResult *result)
+{
+ g_return_if_fail (result != NULL);
+ g_return_if_fail (result->refcount > 0);
+
+ result->refcount--;
+ if (result->refcount == 0) {
+ g_hash_table_destroy (result->hash);
+ memset (result, 0, sizeof (QCDMResult));
+ g_free (result);
+ }
+}
+
+
+void
+qcdm_result_add_string (QCDMResult *result,
+ const char *key,
+ const char *str)
+{
+ GValue *val;
+
+ g_return_if_fail (result != NULL);
+ g_return_if_fail (result->refcount > 0);
+ g_return_if_fail (key != NULL);
+ g_return_if_fail (str != NULL);
+
+ val = g_slice_new0 (GValue);
+ g_value_init (val, G_TYPE_STRING);
+ g_value_set_string (val, str);
+
+ g_hash_table_insert (result->hash, (gpointer) key, val);
+}
+
+gboolean
+qcdm_result_get_string (QCDMResult *result,
+ const char *key,
+ const char **out_val)
+{
+ GValue *val;
+
+ g_return_val_if_fail (result != NULL, FALSE);
+ g_return_val_if_fail (result->refcount > 0, FALSE);
+ g_return_val_if_fail (key != NULL, FALSE);
+ g_return_val_if_fail (out_val != NULL, FALSE);
+ g_return_val_if_fail (*out_val == NULL, FALSE);
+
+ val = g_hash_table_lookup (result->hash, key);
+ if (!val)
+ return FALSE;
+
+ g_warn_if_fail (G_VALUE_HOLDS_STRING (val));
+ if (!G_VALUE_HOLDS_STRING (val))
+ return FALSE;
+
+ *out_val = g_value_get_string (val);
+ return TRUE;
+}
+
+void
+qcdm_result_add_uint8 (QCDMResult *result,
+ const char *key,
+ guint8 num)
+{
+ GValue *val;
+
+ g_return_if_fail (result != NULL);
+ g_return_if_fail (result->refcount > 0);
+ g_return_if_fail (key != NULL);
+
+ val = g_slice_new0 (GValue);
+ g_value_init (val, G_TYPE_UCHAR);
+ g_value_set_uchar (val, (unsigned char) num);
+
+ g_hash_table_insert (result->hash, (gpointer) key, val);
+}
+
+gboolean
+qcdm_result_get_uint8 (QCDMResult *result,
+ const char *key,
+ guint8 *out_val)
+{
+ GValue *val;
+
+ g_return_val_if_fail (result != NULL, FALSE);
+ g_return_val_if_fail (result->refcount > 0, FALSE);
+ g_return_val_if_fail (key != NULL, FALSE);
+ g_return_val_if_fail (out_val != NULL, FALSE);
+
+ val = g_hash_table_lookup (result->hash, key);
+ if (!val)
+ return FALSE;
+
+ g_warn_if_fail (G_VALUE_HOLDS_UCHAR (val));
+ if (!G_VALUE_HOLDS_UCHAR (val))
+ return FALSE;
+
+ *out_val = (guint8) g_value_get_uchar (val);
+ return TRUE;
+}
+
+void
+qcdm_result_add_uint32 (QCDMResult *result,
+ const char *key,
+ guint32 num)
+{
+ GValue *val;
+
+ g_return_if_fail (result != NULL);
+ g_return_if_fail (result->refcount > 0);
+ g_return_if_fail (key != NULL);
+
+ val = g_slice_new0 (GValue);
+ g_value_init (val, G_TYPE_UINT);
+ g_value_set_uint (val, num);
+
+ g_hash_table_insert (result->hash, (gpointer) key, val);
+}
+
+gboolean
+qcdm_result_get_uint32 (QCDMResult *result,
+ const char *key,
+ guint32 *out_val)
+{
+ GValue *val;
+
+ g_return_val_if_fail (result != NULL, FALSE);
+ g_return_val_if_fail (result->refcount > 0, FALSE);
+ g_return_val_if_fail (key != NULL, FALSE);
+ g_return_val_if_fail (out_val != NULL, FALSE);
+
+ val = g_hash_table_lookup (result->hash, key);
+ if (!val)
+ return FALSE;
+
+ g_warn_if_fail (G_VALUE_HOLDS_UINT (val));
+ if (!G_VALUE_HOLDS_UINT (val))
+ return FALSE;
+
+ *out_val = (guint32) g_value_get_uint (val);
+ return TRUE;
+}
+
diff --git a/libqcdm/src/result.h b/libqcdm/src/result.h
new file mode 100644
index 00000000..4912b07c
--- /dev/null
+++ b/libqcdm/src/result.h
@@ -0,0 +1,42 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * Copyright (C) 2010 Red Hat, Inc.
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef LIBQCDM_RESULT_H
+#define LIBQCDM_RESULT_H
+
+#include <glib.h>
+
+typedef struct QCDMResult QCDMResult;
+
+gboolean qcdm_result_get_string (QCDMResult *result,
+ const char *key,
+ const char **out_val);
+
+gboolean qcdm_result_get_uint8 (QCDMResult *result,
+ const char *key,
+ guint8 *out_val);
+
+gboolean qcdm_result_get_uint32 (QCDMResult *result,
+ const char *key,
+ guint32 *out_val);
+
+QCDMResult *qcdm_result_ref (QCDMResult *result);
+
+void qcdm_result_unref (QCDMResult *result);
+
+#endif /* LIBQCDM_RESULT_H */
+
diff --git a/libqcdm/src/utils.c b/libqcdm/src/utils.c
new file mode 100644
index 00000000..ab281557
--- /dev/null
+++ b/libqcdm/src/utils.c
@@ -0,0 +1,309 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * Copyright (C) 2010 Red Hat, Inc.
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <malloc.h>
+#include <fcntl.h>
+#include <string.h>
+
+#include "utils.h"
+
+/* QCDM protocol frames are pseudo Async HDLC frames which end with a 3-byte
+ * trailer. This trailer consists of the 16-bit CRC of the frame plus an ending
+ * "async control character" whose value is 0x7E. The frame *and* the CRC are
+ * escaped before adding the trailing control character so that the control
+ * character (0x7E) and the escape marker (0x7D) are never seen in the frame.
+ */
+
+/* Table of CRCs for each possible byte, with a generator polynomial of 0x8408 */
+const guint16 crc_table[256] = {
+ 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
+ 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
+ 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
+ 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
+ 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
+ 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
+ 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
+ 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
+ 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
+ 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
+ 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
+ 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
+ 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
+ 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
+ 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
+ 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
+ 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
+ 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
+ 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
+ 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
+ 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
+ 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
+ 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
+ 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
+ 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
+ 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
+ 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
+ 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
+ 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
+ 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
+ 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
+ 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
+};
+
+/* Calculate the CRC for a buffer using a seed of 0xffff */
+guint16
+crc16 (const char *buffer, gsize len)
+{
+ guint16 crc = 0xffff;
+
+ while (len--)
+ crc = crc_table[(crc ^ *buffer++) & 0xff] ^ (crc >> 8);
+ return ~crc;
+}
+
+#define DIAG_ESC_CHAR 0x7D /* Escape sequence 1st character value */
+#define DIAG_ESC_MASK 0x20 /* Escape sequence complement value */
+
+/* Performs DM escaping on inbuf putting the result into outbuf, and returns
+ * the final length of the buffer.
+ */
+gsize
+dm_escape (const char *inbuf,
+ gsize inbuf_len,
+ char *outbuf,
+ gsize outbuf_len)
+{
+ const char *src = inbuf;
+ char *dst = outbuf;
+ size_t i = inbuf_len;
+
+ g_return_val_if_fail (inbuf != NULL, 0);
+ g_return_val_if_fail (inbuf_len > 0, 0);
+ g_return_val_if_fail (outbuf != NULL, 0);
+ g_return_val_if_fail (outbuf_len > inbuf_len, 0);
+
+ /* Since escaping potentially doubles the # of bytes, short-circuit the
+ * length check if destination buffer is clearly large enough. Note the
+ *
+ */
+ if (outbuf_len <= inbuf_len << 1) {
+ size_t outbuf_required = inbuf_len + 1; /* +1 for the trailing control char */
+
+ /* Each escaped character takes up two bytes in the output buffer */
+ while (i--) {
+ if (*src == DIAG_CONTROL_CHAR || *src == DIAG_ESC_CHAR)
+ outbuf_required++;
+ src++;
+ }
+
+ if (outbuf_len < outbuf_required)
+ return 0;
+ }
+
+ /* Do the actual escaping. Replace both the control character and
+ * the escape character in the source buffer with the following sequence:
+ *
+ * <escape_char> <src_byte ^ escape_mask>
+ */
+ src = inbuf;
+ i = inbuf_len;
+ while (i--) {
+ if (*src == DIAG_CONTROL_CHAR || *src == DIAG_ESC_CHAR) {
+ *dst++ = DIAG_ESC_CHAR;
+ *dst++ = *src ^ DIAG_ESC_MASK;
+ } else
+ *dst++ = *src;
+ src++;
+ }
+
+ return (dst - outbuf);
+}
+
+gsize
+dm_unescape (const char *inbuf,
+ gsize inbuf_len,
+ char *outbuf,
+ gsize outbuf_len,
+ gboolean *escaping)
+{
+ size_t i, outsize;
+
+ g_return_val_if_fail (inbuf_len > 0, 0);
+ g_return_val_if_fail (outbuf_len >= inbuf_len, 0);
+ g_return_val_if_fail (escaping != NULL, 0);
+
+ for (i = 0, outsize = 0; i < inbuf_len; i++) {
+ if (*escaping) {
+ outbuf[outsize++] = inbuf[i] ^ DIAG_ESC_MASK;
+ *escaping = FALSE;
+ } else if (inbuf[i] == DIAG_ESC_CHAR)
+ *escaping = TRUE;
+ else
+ outbuf[outsize++] = inbuf[i];
+
+ /* About to overrun output buffer size */
+ if (outsize >= outbuf_len)
+ return 0;
+ }
+
+ return outsize;
+}
+
+/**
+ * dm_encapsulate_buffer:
+ * @inbuf: buffer in which a valid QCDM packet exists
+ * @cmd_len: size of the QCDM packet contained in @inbuf
+ * @inbuf_len: total size of @inbuf itself (not just the packet)
+ * @outbuf: buffer in which to put the encapsulated QCDM packet
+ * @outbuf_len: total size of @outbuf
+ *
+ * Escapes and CRCs a QCDM packet, and finally adds the trailing control
+ * character that denotes the end of the QCDM packet.
+ *
+ * Returns: size of the encapsulated QCDM command writted to @outbuf.
+ **/
+gsize
+dm_encapsulate_buffer (char *inbuf,
+ gsize cmd_len,
+ gsize inbuf_len,
+ char *outbuf,
+ gsize outbuf_len)
+{
+ guint16 crc;
+ gsize escaped_len;
+
+ g_return_val_if_fail (inbuf != NULL, 0);
+ g_return_val_if_fail (cmd_len >= 1, 0);
+ g_return_val_if_fail (inbuf_len >= cmd_len + 2, 0); /* space for CRC */
+ g_return_val_if_fail (outbuf != NULL, 0);
+
+ crc = GUINT16_TO_LE (crc16 (inbuf, cmd_len));
+ inbuf[cmd_len++] = crc & 0xFF;
+ inbuf[cmd_len++] = (crc >> 8) & 0xFF;
+
+ escaped_len = dm_escape (inbuf, cmd_len, outbuf, outbuf_len);
+ g_return_val_if_fail (outbuf_len > escaped_len, 0);
+ outbuf[escaped_len++] = DIAG_CONTROL_CHAR;
+
+ return escaped_len;
+}
+
+/**
+ * dm_decapsulate_buffer:
+ * @inbuf: buffer in which to look for a QCDM packet
+ * @inbuf_len: length of valid data in @inbuf
+ * @outbuf: buffer in which to put decapsulated QCDM packet
+ * @outbuf_len: max size of @outbuf
+ * @out_decap_len: on success, size of the decapsulated QCDM packet
+ * @out_used: on either success or failure, amount of data used; caller should
+ * discard this much data from @inbuf before the next call to this function
+ * @out_need_more: when TRUE, indicates that more data is required before
+ * and determination about a valid QCDM packet can be made; caller should add
+ * more data to @inbuf before calling this function again.
+ *
+ * Attempts to retrieve, unescape, and CRC-check a QCDM packet from the given
+ * buffer.
+ *
+ * Returns: FALSE on error (packet was invalid or malformed, or the CRC check
+ * failed, etc) and places number of bytes to discard from @inbuf in @out_used.
+ * When TRUE, either more data is required (in which case @out_need_more will
+ * be TRUE), or a QCDM packet was successfully retrieved from @inbuf and the
+ * decapsulated packet of length @out_decap_len was placed into @outbuf. In
+ * all cases the caller should advance the buffer by the number of bytes
+ * returned in @out_used before calling this function again.
+ **/
+gboolean
+dm_decapsulate_buffer (const char *inbuf,
+ gsize inbuf_len,
+ char *outbuf,
+ gsize outbuf_len,
+ gsize *out_decap_len,
+ gsize *out_used,
+ gboolean *out_need_more)
+{
+ gboolean escaping = FALSE;
+ gsize i, pkt_len = 0, unesc_len;
+ guint16 crc, pkt_crc;
+
+ g_return_val_if_fail (inbuf != NULL, FALSE);
+ g_return_val_if_fail (outbuf != NULL, FALSE);
+ g_return_val_if_fail (outbuf_len > 0, FALSE);
+ g_return_val_if_fail (out_decap_len != NULL, FALSE);
+ g_return_val_if_fail (out_used != NULL, FALSE);
+ g_return_val_if_fail (out_need_more != NULL, FALSE);
+
+ *out_decap_len = 0;
+ *out_used = 0;
+ *out_need_more = FALSE;
+
+ if (inbuf_len < 4) {
+ *out_need_more = TRUE;
+ return TRUE;
+ }
+
+ /* Find the async control character */
+ for (i = 0; i < inbuf_len; i++) {
+ if (inbuf[i] == DIAG_CONTROL_CHAR) {
+ /* If the control character shows up in a position before a valid
+ * QCDM packet length (4), the packet is malformed.
+ */
+ if (i < 3) {
+ /* Tell the caller to advance the buffer past the control char */
+ *out_used = i + 1;
+ return FALSE;
+ }
+
+ pkt_len = i;
+ break;
+ }
+ }
+
+ /* No control char yet, need more data */
+ if (!pkt_len) {
+ *out_need_more = TRUE;
+ return TRUE;
+ }
+
+ /* Unescape first; note that pkt_len */
+ unesc_len = dm_unescape (inbuf, pkt_len, outbuf, outbuf_len, &escaping);
+ if (!unesc_len) {
+ /* Tell the caller to advance the buffer past the control char */
+ *out_used = pkt_len + 1;
+ return FALSE;
+ }
+
+ if (escaping) {
+ *out_need_more = TRUE;
+ return TRUE;
+ }
+
+ /* Check the CRC of the packet's data */
+ crc = crc16 (outbuf, unesc_len - 2);
+ pkt_crc = *((guint16 *) &outbuf[pkt_len - 2]);
+ if (crc != GUINT_FROM_LE (pkt_crc)) {
+ *out_used = pkt_len + 1; /* packet + CRC + 0x7E */
+ return FALSE;
+ }
+
+ *out_used = pkt_len + 1; /* packet + CRC + 0x7E */
+ *out_decap_len = unesc_len - 2; /* decap_len should not include the CRC */
+ return TRUE;
+}
+
diff --git a/libqcdm/src/utils.h b/libqcdm/src/utils.h
new file mode 100644
index 00000000..5fccf7f9
--- /dev/null
+++ b/libqcdm/src/utils.h
@@ -0,0 +1,54 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * Copyright (C) 2010 Red Hat, Inc.
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef UTILS_H
+#define UTILS_H
+
+#include <glib.h>
+
+#define DIAG_CONTROL_CHAR 0x7E
+#define DIAG_TRAILER_LEN 3
+
+guint16 crc16 (const char *buffer, gsize len);
+
+gsize dm_escape (const char *inbuf,
+ gsize inbuf_len,
+ char *outbuf,
+ gsize outbuf_len);
+
+gsize dm_unescape (const char *inbuf,
+ gsize inbuf_len,
+ char *outbuf,
+ gsize outbuf_len,
+ gboolean *escaping);
+
+gsize dm_encapsulate_buffer (char *inbuf,
+ gsize cmd_len,
+ gsize inbuf_len,
+ char *outbuf,
+ gsize outbuf_len);
+
+gboolean dm_decapsulate_buffer (const char *inbuf,
+ gsize inbuf_len,
+ char *outbuf,
+ gsize outbuf_len,
+ gsize *out_decap_len,
+ gsize *out_used,
+ gboolean *out_need_more);
+
+#endif /* UTILS_H */
+
diff --git a/libqcdm/tests/Makefile.am b/libqcdm/tests/Makefile.am
new file mode 100644
index 00000000..3d1b7ba5
--- /dev/null
+++ b/libqcdm/tests/Makefile.am
@@ -0,0 +1,30 @@
+INCLUDES = \
+ -I$(top_srcdir)/libqcdm/src
+
+noinst_PROGRAMS = test-qcdm
+
+test_qcdm_SOURCES = \
+ test-qcdm-crc.c \
+ test-qcdm-crc.h \
+ test-qcdm-escaping.c \
+ test-qcdm-escaping.h \
+ test-qcdm-com.c \
+ test-qcdm-com.h \
+ test-qcdm-result.c \
+ test-qcdm-result.h \
+ test-qcdm.c
+
+test_qcdm_CPPFLAGS = \
+ $(MM_CFLAGS)
+
+test_qcdm_LDADD = \
+ $(top_builddir)/libqcdm/src/libqcdm.la \
+ $(MM_LIBS)
+
+if WITH_TESTS
+
+check-local: test-qcdm
+ $(abs_builddir)/test-qcdm
+
+endif
+
diff --git a/libqcdm/tests/test-qcdm-com.c b/libqcdm/tests/test-qcdm-com.c
new file mode 100644
index 00000000..aeec6377
--- /dev/null
+++ b/libqcdm/tests/test-qcdm-com.c
@@ -0,0 +1,771 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * Copyright (C) 2010 Red Hat, Inc.
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <glib.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <termios.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+#include "test-qcdm-com.h"
+#include "com.h"
+#include "utils.h"
+#include "result.h"
+#include "commands.h"
+#include "error.h"
+
+typedef struct {
+ char *port;
+ int fd;
+ struct termios old_t;
+ gboolean debug;
+} TestComData;
+
+gpointer
+test_com_setup (const char *port)
+{
+ TestComData *d;
+ int ret;
+
+ d = g_malloc0 (sizeof (TestComData));
+ g_assert (d);
+
+ if (getenv ("SERIAL_DEBUG"))
+ d->debug = TRUE;
+
+ errno = 0;
+ d->fd = open (port, O_RDWR | O_EXCL | O_NONBLOCK | O_NOCTTY);
+ if (d->fd < 0)
+ g_warning ("%s: open failed: (%d) %s", port, errno, strerror (errno));
+ g_assert (d->fd >= 0);
+
+ ret = ioctl (d->fd, TIOCEXCL);
+ if (ret) {
+ g_warning ("%s: lock failed: (%d) %s", port, errno, strerror (errno));
+ close (d->fd);
+ d->fd = -1;
+ }
+ g_assert (ret == 0);
+
+ ret = ioctl (d->fd, TCGETA, &d->old_t);
+ if (ret) {
+ g_warning ("%s: old termios failed: (%d) %s", port, errno, strerror (errno));
+ close (d->fd);
+ d->fd = -1;
+ }
+ g_assert (ret == 0);
+
+ d->port = g_strdup (port);
+ return d;
+}
+
+void
+test_com_teardown (gpointer user_data)
+{
+ TestComData *d = user_data;
+
+ g_assert (d);
+
+ g_free (d->port);
+ close (d->fd);
+ g_free (d);
+}
+
+static void
+print_buf (const char *detail, const char *buf, gsize len)
+{
+ int i = 0;
+ gboolean newline = FALSE;
+
+ g_print ("%s (%zu) ", detail, len);
+ for (i = 0; i < len; i++) {
+ g_print ("0x%02x ", buf[i] & 0xFF);
+ if (((i + 1) % 12) == 0) {
+ g_print ("\n");
+ newline = TRUE;
+ } else
+ newline = FALSE;
+ }
+
+ if (!newline)
+ g_print ("\n");
+}
+
+static gboolean
+send_command (TestComData *d, char *buf, gsize len)
+{
+ int status;
+ int eagain_count = 1000;
+ gsize i = 0;
+
+ if (d->debug)
+ print_buf (">>>", buf, len);
+
+ while (i < len) {
+ errno = 0;
+ status = write (d->fd, &buf[i], 1);
+ if (status < 0) {
+ if (errno == EAGAIN) {
+ eagain_count--;
+ if (eagain_count <= 0)
+ return FALSE;
+ } else
+ g_assert (errno == 0);
+ } else
+ i++;
+
+ usleep (1000);
+ }
+
+ return TRUE;
+}
+
+static gsize
+wait_reply (TestComData *d, char *buf, gsize len)
+{
+ fd_set in;
+ int result;
+ struct timeval timeout = { 1, 0 };
+ char readbuf[1024];
+ ssize_t bytes_read;
+ int total = 0, retries = 0;
+ gsize decap_len = 0;
+
+ FD_ZERO (&in);
+ FD_SET (d->fd, &in);
+ result = select (d->fd + 1, &in, NULL, NULL, &timeout);
+ if (result != 1 || !FD_ISSET (d->fd, &in))
+ return 0;
+
+ do {
+ errno = 0;
+ bytes_read = read (d->fd, &readbuf[total], 1);
+ if ((bytes_read == 0) || (errno == EAGAIN)) {
+ /* Haven't gotten the async control char yet */
+ if (retries > 20)
+ return 0; /* 2 seconds, give up */
+
+ /* Otherwise wait a bit and try again */
+ usleep (100000);
+ retries++;
+ continue;
+ } else if (bytes_read == 1) {
+ gboolean more = FALSE, success;
+ gsize used = 0;
+
+ total++;
+ decap_len = 0;
+ success = dm_decapsulate_buffer (readbuf, total, buf, len, &decap_len, &used, &more);
+
+ /* Discard used data */
+ if (used > 0) {
+ total -= used;
+ memmove (readbuf, &readbuf[used], total);
+ }
+
+ if (success && !more) {
+ /* Success; we have a packet */
+ break;
+ }
+ } else {
+ /* Some error occurred */
+ return 0;
+ }
+ } while (total < sizeof (readbuf));
+
+ if (d->debug) {
+ print_buf ("<<<", readbuf, total);
+ print_buf ("D<<", buf, decap_len);
+ }
+
+ return decap_len;
+}
+
+void
+test_com_port_init (void *f, void *data)
+{
+ TestComData *d = data;
+ GError *error = NULL;
+ gboolean success;
+
+ success = qcdm_port_setup (d->fd, &error);
+ if (!success) {
+ g_warning ("%s: error setting up port: (%d) %s",
+ d->port,
+ error ? error->code : -1,
+ error && error->message ? error->message : "(unknown)");
+ }
+ g_assert (success);
+}
+
+void
+test_com_version_info (void *f, void *data)
+{
+ TestComData *d = data;
+ gboolean success;
+ GError *error = NULL;
+ char buf[512];
+ const char *str;
+ gint len;
+ QCDMResult *result;
+ gsize reply_len;
+
+ len = qcdm_cmd_version_info_new (buf, sizeof (buf), NULL);
+ g_assert (len == 4);
+
+ /* Send the command */
+ success = send_command (d, buf, len);
+ g_assert (success);
+
+ /* Get a response */
+ reply_len = wait_reply (d, buf, sizeof (buf));
+
+ /* Parse the response into a result structure */
+ result = qcdm_cmd_version_info_result (buf, reply_len, &error);
+ g_assert (result);
+
+ g_print ("\n");
+
+ str = NULL;
+ qcdm_result_get_string (result, QCDM_CMD_VERSION_INFO_ITEM_COMP_DATE, &str);
+ g_message ("%s: Compiled Date: %s", __func__, str);
+
+ str = NULL;
+ qcdm_result_get_string (result, QCDM_CMD_VERSION_INFO_ITEM_COMP_TIME, &str);
+ g_message ("%s: Compiled Time: %s", __func__, str);
+
+ str = NULL;
+ qcdm_result_get_string (result, QCDM_CMD_VERSION_INFO_ITEM_RELEASE_DATE, &str);
+ g_message ("%s: Release Date: %s", __func__, str);
+
+ str = NULL;
+ qcdm_result_get_string (result, QCDM_CMD_VERSION_INFO_ITEM_RELEASE_TIME, &str);
+ g_message ("%s: Release Time: %s", __func__, str);
+
+ str = NULL;
+ qcdm_result_get_string (result, QCDM_CMD_VERSION_INFO_ITEM_MODEL, &str);
+ g_message ("%s: Model: %s", __func__, str);
+
+ qcdm_result_unref (result);
+}
+
+void
+test_com_esn (void *f, void *data)
+{
+ TestComData *d = data;
+ gboolean success;
+ GError *error = NULL;
+ char buf[512];
+ const char *str;
+ gint len;
+ QCDMResult *result;
+ gsize reply_len;
+
+ len = qcdm_cmd_esn_new (buf, sizeof (buf), NULL);
+ g_assert (len == 4);
+
+ /* Send the command */
+ success = send_command (d, buf, len);
+ g_assert (success);
+
+ /* Get a response */
+ reply_len = wait_reply (d, buf, sizeof (buf));
+
+ /* Parse the response into a result structure */
+ result = qcdm_cmd_esn_result (buf, reply_len, &error);
+ g_assert (result);
+
+ g_print ("\n");
+
+ str = NULL;
+ qcdm_result_get_string (result, QCDM_CMD_ESN_ITEM_ESN, &str);
+ g_message ("%s: ESN: %s", __func__, str);
+
+ qcdm_result_unref (result);
+}
+
+void
+test_com_mdn (void *f, void *data)
+{
+ TestComData *d = data;
+ gboolean success;
+ GError *error = NULL;
+ char buf[512];
+ const char *str;
+ gint len;
+ QCDMResult *result;
+ gsize reply_len;
+
+ len = qcdm_cmd_nv_get_mdn_new (buf, sizeof (buf), 0, NULL);
+ g_assert (len > 0);
+
+ /* Send the command */
+ success = send_command (d, buf, len);
+ g_assert (success);
+
+ /* Get a response */
+ reply_len = wait_reply (d, buf, sizeof (buf));
+
+ /* Parse the response into a result structure */
+ result = qcdm_cmd_nv_get_mdn_result (buf, reply_len, &error);
+ g_assert (result);
+
+ g_print ("\n");
+
+ str = NULL;
+ qcdm_result_get_string (result, QCDM_CMD_NV_GET_MDN_ITEM_MDN, &str);
+ g_message ("%s: MDN: %s", __func__, str);
+
+ qcdm_result_unref (result);
+}
+
+void
+test_com_status (void *f, void *data)
+{
+ TestComData *d = data;
+ gboolean success;
+ GError *error = NULL;
+ char buf[100];
+ const char *str;
+ gint len;
+ QCDMResult *result;
+ gsize reply_len;
+ guint32 n32;
+ guint8 n8;
+
+ len = qcdm_cmd_cdma_status_new (buf, sizeof (buf), NULL);
+ g_assert (len == 4);
+
+ /* Send the command */
+ success = send_command (d, buf, len);
+ g_assert (success);
+
+ /* Get a response */
+ reply_len = wait_reply (d, buf, sizeof (buf));
+
+ /* Parse the response into a result structure */
+ result = qcdm_cmd_cdma_status_result (buf, reply_len, &error);
+ g_assert (result);
+
+ g_print ("\n");
+
+ str = NULL;
+ qcdm_result_get_string (result, QCDM_CMD_CDMA_STATUS_ITEM_ESN, &str);
+ g_message ("%s: ESN: %s", __func__, str);
+
+ n32 = 0;
+ qcdm_result_get_uint32 (result, QCDM_CMD_CDMA_STATUS_ITEM_RX_STATE, &n32);
+ g_message ("%s: CDMA RX State: %u", __func__, n32);
+
+ n32 = 0;
+ qcdm_result_get_uint32 (result, QCDM_CMD_CDMA_STATUS_ITEM_ENTRY_REASON, &n32);
+ g_message ("%s: Entry Reason: %u", __func__, n32);
+
+ n32 = 0;
+ qcdm_result_get_uint32 (result, QCDM_CMD_CDMA_STATUS_ITEM_CURRENT_CHANNEL, &n32);
+ g_message ("%s: Current Channel: %u", __func__, n32);
+
+ n8 = 0;
+ qcdm_result_get_uint8 (result, QCDM_CMD_CDMA_STATUS_ITEM_CODE_CHANNEL, &n8);
+ g_message ("%s: Code Channel: %u", __func__, n8);
+
+ n32 = 0;
+ qcdm_result_get_uint32 (result, QCDM_CMD_CDMA_STATUS_ITEM_PILOT_BASE, &n32);
+ g_message ("%s: Pilot Base: %u", __func__, n32);
+
+ n32 = 0;
+ qcdm_result_get_uint32 (result, QCDM_CMD_CDMA_STATUS_ITEM_SID, &n32);
+ g_message ("%s: CDMA System ID: %u", __func__, n32);
+
+ n32 = 0;
+ qcdm_result_get_uint32 (result, QCDM_CMD_CDMA_STATUS_ITEM_NID, &n32);
+ g_message ("%s: CDMA Network ID: %u", __func__, n32);
+
+ qcdm_result_unref (result);
+}
+
+void
+test_com_sw_version (void *f, void *data)
+{
+ TestComData *d = data;
+ gboolean success;
+ GError *error = NULL;
+ char buf[100];
+ gint len;
+ QCDMResult *result;
+ gsize reply_len;
+
+ len = qcdm_cmd_sw_version_new (buf, sizeof (buf), NULL);
+ g_assert (len == 4);
+
+ /* Send the command */
+ success = send_command (d, buf, len);
+ g_assert (success);
+
+ /* Get a response */
+ reply_len = wait_reply (d, buf, sizeof (buf));
+
+ /* Parse the response into a result structure */
+ result = qcdm_cmd_sw_version_result (buf, reply_len, &error);
+
+ /* Recent devices don't appear to implement this command */
+ g_assert (result == NULL);
+ g_assert_error (error, QCDM_COMMAND_ERROR, QCDM_COMMAND_BAD_COMMAND);
+
+/*
+ str = NULL;
+ qcdm_result_get_string (result, QCDM_CMD_SW_VERSION_ITEM_VERSION, &str);
+ g_message ("%s: SW Version: %s", __func__, str);
+
+ str = NULL;
+ qcdm_result_get_string (result, QCDM_CMD_SW_VERSION_ITEM_COMP_DATE, &str);
+ g_message ("%s: Compiled Date: %s", __func__, str);
+
+ str = NULL;
+ qcdm_result_get_string (result, QCDM_CMD_SW_VERSION_ITEM_COMP_TIME, &str);
+ g_message ("%s: Compiled Time: %s", __func__, str);
+
+ qcdm_result_unref (result);
+*/
+}
+
+void
+test_com_cm_subsys_state_info (void *f, void *data)
+{
+ TestComData *d = data;
+ gboolean success;
+ GError *error = NULL;
+ char buf[100];
+ gint len;
+ QCDMResult *result;
+ gsize reply_len;
+ guint32 n32;
+ const char *detail;
+
+ len = qcdm_cmd_cm_subsys_state_info_new (buf, sizeof (buf), NULL);
+ g_assert (len == 7);
+
+ /* Send the command */
+ success = send_command (d, buf, len);
+ g_assert (success);
+
+ /* Get a response */
+ reply_len = wait_reply (d, buf, sizeof (buf));
+
+ /* Parse the response into a result structure */
+ result = qcdm_cmd_cm_subsys_state_info_result (buf, reply_len, &error);
+ g_assert (result);
+
+ g_print ("\n");
+
+ n32 = 0;
+ qcdm_result_get_uint32 (result, QCDM_CMD_CM_SUBSYS_STATE_INFO_ITEM_CALL_STATE, &n32);
+ g_message ("%s: Call State: %u", __func__, n32);
+
+ n32 = 0;
+ detail = NULL;
+ qcdm_result_get_uint32 (result, QCDM_CMD_CM_SUBSYS_STATE_INFO_ITEM_OPERATING_MODE, &n32);
+ switch (n32) {
+ case QCDM_CMD_CM_SUBSYS_STATE_INFO_OPERATING_MODE_ONLINE:
+ detail = "online";
+ break;
+ default:
+ detail = "unknown";
+ break;
+ }
+ g_message ("%s: Operating Mode: %u (%s)", __func__, n32, detail);
+
+ n32 = 0;
+ detail = NULL;
+ qcdm_result_get_uint32 (result, QCDM_CMD_CM_SUBSYS_STATE_INFO_ITEM_SYSTEM_MODE, &n32);
+ switch (n32) {
+ case QCDM_CMD_CM_SUBSYS_STATE_INFO_SYSTEM_MODE_NO_SERVICE:
+ detail = "no service";
+ break;
+ case QCDM_CMD_CM_SUBSYS_STATE_INFO_SYSTEM_MODE_AMPS:
+ detail = "AMPS";
+ break;
+ case QCDM_CMD_CM_SUBSYS_STATE_INFO_SYSTEM_MODE_CDMA:
+ detail = "CDMA";
+ break;
+ case QCDM_CMD_CM_SUBSYS_STATE_INFO_SYSTEM_MODE_HDR:
+ detail = "HDR/EVDO";
+ break;
+ case QCDM_CMD_CM_SUBSYS_STATE_INFO_SYSTEM_MODE_WCDMA:
+ detail = "WCDMA";
+ break;
+ default:
+ detail = "unknown";
+ break;
+ }
+ g_message ("%s: System Mode: %u (%s)", __func__, n32, detail);
+
+ n32 = 0;
+ qcdm_result_get_uint32 (result, QCDM_CMD_CM_SUBSYS_STATE_INFO_ITEM_MODE_PREF, &n32);
+ g_message ("%s: Mode Preference: %u", __func__, n32);
+
+ n32 = 0;
+ qcdm_result_get_uint32 (result, QCDM_CMD_CM_SUBSYS_STATE_INFO_ITEM_BAND_PREF, &n32);
+ g_message ("%s: Band Preference: %u", __func__, n32);
+
+ n32 = 0;
+ qcdm_result_get_uint32 (result, QCDM_CMD_CM_SUBSYS_STATE_INFO_ITEM_ROAM_PREF, &n32);
+ g_message ("%s: Roam Preference: %u", __func__, n32);
+
+ n32 = 0;
+ qcdm_result_get_uint32 (result, QCDM_CMD_CM_SUBSYS_STATE_INFO_ITEM_SERVICE_DOMAIN_PREF, &n32);
+ g_message ("%s: Service Domain Preference: %u", __func__, n32);
+
+ n32 = 0;
+ qcdm_result_get_uint32 (result, QCDM_CMD_CM_SUBSYS_STATE_INFO_ITEM_ACQ_ORDER_PREF, &n32);
+ g_message ("%s: Acquisition Order Preference: %u", __func__, n32);
+
+ n32 = 0;
+ qcdm_result_get_uint32 (result, QCDM_CMD_CM_SUBSYS_STATE_INFO_ITEM_HYBRID_PREF, &n32);
+ g_message ("%s: Hybrid Preference: %u", __func__, n32);
+
+ n32 = 0;
+ qcdm_result_get_uint32 (result, QCDM_CMD_CM_SUBSYS_STATE_INFO_ITEM_NETWORK_SELECTION_PREF, &n32);
+ g_message ("%s: Network Selection Preference: %u", __func__, n32);
+
+ qcdm_result_unref (result);
+}
+
+void
+test_com_hdr_subsys_state_info (void *f, void *data)
+{
+ TestComData *d = data;
+ gboolean success;
+ GError *error = NULL;
+ char buf[100];
+ gint len;
+ QCDMResult *result;
+ gsize reply_len;
+ guint8 num;
+ const char *detail;
+
+ len = qcdm_cmd_hdr_subsys_state_info_new (buf, sizeof (buf), NULL);
+ g_assert (len == 7);
+
+ /* Send the command */
+ success = send_command (d, buf, len);
+ g_assert (success);
+
+ /* Get a response */
+ reply_len = wait_reply (d, buf, sizeof (buf));
+
+ /* Parse the response into a result structure */
+ result = qcdm_cmd_hdr_subsys_state_info_result (buf, reply_len, &error);
+ if (!result) {
+ /* 1x-only devices won't implement the HDR subsystem of course */
+ g_assert_error (error, QCDM_COMMAND_ERROR, QCDM_COMMAND_BAD_COMMAND);
+ g_message ("%s: device does not implement the HDR subsystem", __func__);
+ return;
+ }
+ g_assert (result);
+
+ g_print ("\n");
+
+ num = 0;
+ detail = NULL;
+ qcdm_result_get_uint8 (result, QCDM_CMD_HDR_SUBSYS_STATE_INFO_ITEM_AT_STATE, &num);
+ switch (num) {
+ case QCDM_CMD_HDR_SUBSYS_STATE_INFO_AT_STATE_INACTIVE:
+ detail = "inactive";
+ break;
+ case QCDM_CMD_HDR_SUBSYS_STATE_INFO_AT_STATE_ACQUISITION:
+ detail = "acquisition";
+ break;
+ case QCDM_CMD_HDR_SUBSYS_STATE_INFO_AT_STATE_SYNC:
+ detail = "sync";
+ break;
+ case QCDM_CMD_HDR_SUBSYS_STATE_INFO_AT_STATE_IDLE:
+ detail = "idle";
+ break;
+ case QCDM_CMD_HDR_SUBSYS_STATE_INFO_AT_STATE_ACCESS:
+ detail = "access";
+ break;
+ case QCDM_CMD_HDR_SUBSYS_STATE_INFO_AT_STATE_CONNECTED:
+ detail = "connected";
+ break;
+ default:
+ detail = "unknown";
+ break;
+ }
+ g_message ("%s: AT State: %u (%s)", __func__, num, detail);
+
+ num = 0;
+ detail = NULL;
+ qcdm_result_get_uint8 (result, QCDM_CMD_HDR_SUBSYS_STATE_INFO_ITEM_SESSION_STATE, &num);
+ switch (num) {
+ case QCDM_CMD_HDR_SUBSYS_STATE_INFO_SESSION_STATE_CLOSED:
+ detail = "closed";
+ break;
+ case QCDM_CMD_HDR_SUBSYS_STATE_INFO_SESSION_STATE_SETUP:
+ detail = "setup";
+ break;
+ case QCDM_CMD_HDR_SUBSYS_STATE_INFO_SESSION_STATE_AT_INIT:
+ detail = "AT init";
+ break;
+ case QCDM_CMD_HDR_SUBSYS_STATE_INFO_SESSION_STATE_AN_INIT:
+ detail = "AN init";
+ break;
+ case QCDM_CMD_HDR_SUBSYS_STATE_INFO_SESSION_STATE_OPEN:
+ detail = "open";
+ break;
+ case QCDM_CMD_HDR_SUBSYS_STATE_INFO_SESSION_STATE_CLOSING:
+ detail = "closing";
+ break;
+ default:
+ detail = "unknown";
+ break;
+ }
+ g_message ("%s: Session State: %u (%s)", __func__, num, detail);
+
+ num = 0;
+ detail = NULL;
+ qcdm_result_get_uint8 (result, QCDM_CMD_HDR_SUBSYS_STATE_INFO_ITEM_ALMP_STATE, &num);
+ switch (num) {
+ case QCDM_CMD_HDR_SUBSYS_STATE_INFO_ALMP_STATE_INACTIVE:
+ detail = "inactive";
+ break;
+ case QCDM_CMD_HDR_SUBSYS_STATE_INFO_ALMP_STATE_INIT:
+ detail = "init";
+ break;
+ case QCDM_CMD_HDR_SUBSYS_STATE_INFO_ALMP_STATE_IDLE:
+ detail = "idle";
+ break;
+ case QCDM_CMD_HDR_SUBSYS_STATE_INFO_ALMP_STATE_CONNECTED:
+ detail = "connected";
+ break;
+ default:
+ detail = "unknown";
+ break;
+ }
+ g_message ("%s: ALMP State: %u (%s)", __func__, num, detail);
+
+ num = 0;
+ detail = NULL;
+ qcdm_result_get_uint8 (result, QCDM_CMD_HDR_SUBSYS_STATE_INFO_ITEM_INIT_STATE, &num);
+ switch (num) {
+ case QCDM_CMD_HDR_SUBSYS_STATE_INFO_INIT_STATE_INACTIVE:
+ detail = "inactive";
+ break;
+ case QCDM_CMD_HDR_SUBSYS_STATE_INFO_INIT_STATE_NET_DETERMINE:
+ detail = "searching";
+ break;
+ case QCDM_CMD_HDR_SUBSYS_STATE_INFO_INIT_STATE_ACQUISITION:
+ detail = "acquisition";
+ break;
+ case QCDM_CMD_HDR_SUBSYS_STATE_INFO_INIT_STATE_SYNC:
+ detail = "sync";
+ break;
+ default:
+ detail = "unknown";
+ break;
+ }
+ g_message ("%s: Init State: %u (%s)", __func__, num, detail);
+
+ num = 0;
+ detail = NULL;
+ qcdm_result_get_uint8 (result, QCDM_CMD_HDR_SUBSYS_STATE_INFO_ITEM_IDLE_STATE, &num);
+ switch (num) {
+ case QCDM_CMD_HDR_SUBSYS_STATE_INFO_IDLE_STATE_INACTIVE:
+ detail = "inactive";
+ break;
+ case QCDM_CMD_HDR_SUBSYS_STATE_INFO_IDLE_STATE_SLEEP:
+ detail = "sleep";
+ break;
+ case QCDM_CMD_HDR_SUBSYS_STATE_INFO_IDLE_STATE_MONITOR:
+ detail = "monitor";
+ break;
+ case QCDM_CMD_HDR_SUBSYS_STATE_INFO_IDLE_STATE_SETUP:
+ detail = "setup";
+ break;
+ default:
+ detail = "unknown";
+ break;
+ }
+ g_message ("%s: Idle State: %u (%s)", __func__, num, detail);
+
+ num = 0;
+ detail = NULL;
+ qcdm_result_get_uint8 (result, QCDM_CMD_HDR_SUBSYS_STATE_INFO_ITEM_CONNECTED_STATE, &num);
+ switch (num) {
+ case QCDM_CMD_HDR_SUBSYS_STATE_INFO_CONNECTED_STATE_INACTIVE:
+ detail = "inactive";
+ break;
+ case QCDM_CMD_HDR_SUBSYS_STATE_INFO_CONNECTED_STATE_OPEN:
+ detail = "open";
+ break;
+ case QCDM_CMD_HDR_SUBSYS_STATE_INFO_CONNECTED_STATE_CLOSING:
+ detail = "closing";
+ break;
+ default:
+ detail = "unknown";
+ break;
+ }
+ g_message ("%s: Connected State: %u (%s)", __func__, num, detail);
+
+ num = 0;
+ detail = NULL;
+ qcdm_result_get_uint8 (result, QCDM_CMD_HDR_SUBSYS_STATE_INFO_ITEM_ROUTE_UPDATE_STATE, &num);
+ switch (num) {
+ case QCDM_CMD_HDR_SUBSYS_STATE_INFO_ROUTE_UPDATE_STATE_INACTIVE:
+ detail = "inactive";
+ break;
+ case QCDM_CMD_HDR_SUBSYS_STATE_INFO_ROUTE_UPDATE_STATE_IDLE:
+ detail = "idle";
+ break;
+ case QCDM_CMD_HDR_SUBSYS_STATE_INFO_ROUTE_UPDATE_STATE_CONNECTED:
+ detail = "connected";
+ break;
+ default:
+ detail = "unknown";
+ break;
+ }
+ g_message ("%s: Route Update State: %u (%s)", __func__, num, detail);
+
+ num = 0;
+ detail = NULL;
+ qcdm_result_get_uint8 (result, QCDM_CMD_HDR_SUBSYS_STATE_INFO_ITEM_OVERHEAD_MSG_STATE, &num);
+ switch (num) {
+ case QCDM_CMD_HDR_SUBSYS_STATE_INFO_OVERHEAD_MSG_STATE_INIT:
+ detail = "initial";
+ break;
+ case QCDM_CMD_HDR_SUBSYS_STATE_INFO_OVERHEAD_MSG_STATE_INACTIVE:
+ detail = "inactive";
+ break;
+ case QCDM_CMD_HDR_SUBSYS_STATE_INFO_OVERHEAD_MSG_STATE_ACTIVE:
+ detail = "active";
+ break;
+ default:
+ detail = "unknown";
+ break;
+ }
+ g_message ("%s: Overhead Msg State: %u (%s)", __func__, num, detail);
+
+ num = 0;
+ qcdm_result_get_uint8 (result, QCDM_CMD_HDR_SUBSYS_STATE_INFO_ITEM_HDR_HYBRID_MODE, &num);
+ g_message ("%s: HDR Hybrid Mode: %u", __func__, num);
+
+ qcdm_result_unref (result);
+}
+
diff --git a/libqcdm/tests/test-qcdm-com.h b/libqcdm/tests/test-qcdm-com.h
new file mode 100644
index 00000000..6c9b6e0a
--- /dev/null
+++ b/libqcdm/tests/test-qcdm-com.h
@@ -0,0 +1,41 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * Copyright (C) 2010 Red Hat, Inc.
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef TEST_QCDM_COM_H
+#define TEST_QCDM_COM_H
+
+gpointer test_com_setup (const char *port);
+void test_com_teardown (gpointer d);
+
+void test_com_port_init (void *f, void *data);
+
+void test_com_version_info (void *f, void *data);
+
+void test_com_esn (void *f, void *data);
+
+void test_com_mdn (void *f, void *data);
+
+void test_com_status (void *f, void *data);
+
+void test_com_sw_version (void *f, void *data);
+
+void test_com_cm_subsys_state_info (void *f, void *data);
+
+void test_com_hdr_subsys_state_info (void *f, void *data);
+
+#endif /* TEST_QCDM_COM_H */
+
diff --git a/libqcdm/tests/test-qcdm-crc.c b/libqcdm/tests/test-qcdm-crc.c
new file mode 100644
index 00000000..0cb3e863
--- /dev/null
+++ b/libqcdm/tests/test-qcdm-crc.c
@@ -0,0 +1,65 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * Copyright (C) 2010 Red Hat, Inc.
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <glib.h>
+#include <string.h>
+
+#include "test-qcdm-crc.h"
+#include "utils.h"
+
+void
+test_crc16_2 (void *f, void *data)
+{
+ static const char buf[] = {
+ 0x26, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00
+ };
+ guint16 crc;
+ guint16 expected = 0x6D69;
+
+ /* CRC check */
+ crc = crc16 (buf, sizeof (buf));
+ g_assert (crc == expected);
+}
+
+void
+test_crc16_1 (void *f, void *data)
+{
+ static const char buf[] = {
+ 0x4b, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
+ 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x3f,
+ 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff
+ };
+ guint16 crc;
+ guint16 expected = 0x097A;
+
+ /* CRC check */
+ crc = crc16 (buf, sizeof (buf));
+ g_assert (crc == expected);
+}
+
diff --git a/libqcdm/tests/test-qcdm-crc.h b/libqcdm/tests/test-qcdm-crc.h
new file mode 100644
index 00000000..91b95a08
--- /dev/null
+++ b/libqcdm/tests/test-qcdm-crc.h
@@ -0,0 +1,25 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * Copyright (C) 2010 Red Hat, Inc.
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef TEST_QCDM_CRC_H
+#define TEST_QCDM_CRC_H
+
+void test_crc16_2 (void *f, void *data);
+void test_crc16_1 (void *f, void *data);
+
+#endif /* TEST_QCDM_CRC_H */
+
diff --git a/libqcdm/tests/test-qcdm-escaping.c b/libqcdm/tests/test-qcdm-escaping.c
new file mode 100644
index 00000000..fb5fb82a
--- /dev/null
+++ b/libqcdm/tests/test-qcdm-escaping.c
@@ -0,0 +1,124 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * Copyright (C) 2010 Red Hat, Inc.
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <glib.h>
+#include <string.h>
+
+#include "test-qcdm-escaping.h"
+#include "utils.h"
+
+static const char data1[] = {
+ 0x70, 0x68, 0x6f, 0x6e, 0x65, 0x66, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65,
+ 0x0a, 0x6e, 0x6f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f,
+ 0x6e, 0x74, 0x6f, 0x70, 0x68, 0x6f, 0x6e, 0x65, 0x0a, 0x70, 0x68, 0x6f,
+ 0x6e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7e, 0x7d, 0x7e, 0x7d, 0x7e, 0x6e,
+ 0x6b, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x0a, 0x6f, 0x70,
+ 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x6c,
+ 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x0a, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74,
+ 0x69, 0x6f, 0x6e, 0x6e, 0x6f, 0x74, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72,
+ 0x74, 0x65, 0x64, 0x0a, 0x70, 0x68, 0x73, 0x69, 0x6d, 0x70, 0x69, 0x6e,
+ 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x0a, 0x70, 0x68, 0x66,
+ 0x73, 0x69, 0x6d, 0x70, 0x69, 0x6e, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72,
+ 0x65, 0x64, 0x0a, 0x70, 0x68, 0x66, 0x73, 0x69, 0x6d, 0x70, 0x75, 0x6b,
+ 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x0a, 0x73, 0x69, 0x6d,
+ 0x6e, 0x6f, 0x74, 0x69, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x65, 0x64, 0x0a,
+ 0x73, 0x69, 0x6d, 0x70, 0x69, 0x6e, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72,
+ 0x65, 0x64, 0x0a, 0x73, 0x69, 0x6d, 0x70, 0x75, 0x6b, 0x72, 0x65, 0x71,
+ 0x75, 0x69, 0x72, 0x65, 0x64, 0x0a, 0x73, 0x69, 0x6d, 0x66, 0x61, 0x69,
+ 0x6c, 0x75, 0x72, 0x65, 0x0a, 0x73, 0x69, 0x6d, 0x62, 0x75, 0x73, 0x79,
+ 0x0a, 0x73, 0x69, 0x6d, 0x77, 0x72, 0x6f, 0x6e, 0x67, 0x0a, 0x69, 0x6e,
+ 0x63, 0x6f, 0x72, 0x72, 0x65, 0x63, 0x74, 0x70, 0x61, 0x73, 0x73, 0x77,
+ 0x6f, 0x72, 0x64, 0x0a, 0x73, 0x69, 0x6d, 0x70, 0x69, 0x6e, 0x32, 0x72,
+ 0x65, 0x71, 0x75, 0x69
+};
+
+static const char expected1[] = {
+ 0x70, 0x68, 0x6f, 0x6e, 0x65, 0x66, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65,
+ 0x0a, 0x6e, 0x6f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f,
+ 0x6e, 0x74, 0x6f, 0x70, 0x68, 0x6f, 0x6e, 0x65, 0x0a, 0x70, 0x68, 0x6f,
+ 0x6e, 0x7d, 0x5e, 0x7d, 0x5e, 0x7d, 0x5e, 0x7d, 0x5d, 0x7d, 0x5d, 0x7d,
+ 0x5e, 0x7d, 0x5d, 0x7d, 0x5e, 0x7d, 0x5d, 0x7d, 0x5e, 0x6e, 0x6b, 0x72,
+ 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x0a, 0x6f, 0x70, 0x65, 0x72,
+ 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x6c, 0x6c, 0x6f,
+ 0x77, 0x65, 0x64, 0x0a, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f,
+ 0x6e, 0x6e, 0x6f, 0x74, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65,
+ 0x64, 0x0a, 0x70, 0x68, 0x73, 0x69, 0x6d, 0x70, 0x69, 0x6e, 0x72, 0x65,
+ 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x0a, 0x70, 0x68, 0x66, 0x73, 0x69,
+ 0x6d, 0x70, 0x69, 0x6e, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64,
+ 0x0a, 0x70, 0x68, 0x66, 0x73, 0x69, 0x6d, 0x70, 0x75, 0x6b, 0x72, 0x65,
+ 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x0a, 0x73, 0x69, 0x6d, 0x6e, 0x6f,
+ 0x74, 0x69, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x65, 0x64, 0x0a, 0x73, 0x69,
+ 0x6d, 0x70, 0x69, 0x6e, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64,
+ 0x0a, 0x73, 0x69, 0x6d, 0x70, 0x75, 0x6b, 0x72, 0x65, 0x71, 0x75, 0x69,
+ 0x72, 0x65, 0x64, 0x0a, 0x73, 0x69, 0x6d, 0x66, 0x61, 0x69, 0x6c, 0x75,
+ 0x72, 0x65, 0x0a, 0x73, 0x69, 0x6d, 0x62, 0x75, 0x73, 0x79, 0x0a, 0x73,
+ 0x69, 0x6d, 0x77, 0x72, 0x6f, 0x6e, 0x67, 0x0a, 0x69, 0x6e, 0x63, 0x6f,
+ 0x72, 0x72, 0x65, 0x63, 0x74, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72,
+ 0x64, 0x0a, 0x73, 0x69, 0x6d, 0x70, 0x69, 0x6e, 0x32, 0x72, 0x65, 0x71,
+ 0x75, 0x69
+};
+
+void
+test_escape1 (void *f, void *data)
+{
+ char escaped[1024];
+ gsize len;
+
+ /* Ensure that escaping in general works */
+ len = dm_escape (data1, sizeof (data1), escaped, sizeof (escaped));
+ g_assert (len == 266);
+ g_assert (len == sizeof (expected1));
+ g_assert (memcmp (escaped, expected1, len) == 0);
+}
+
+static const char data2[] = {
+ 0x4b, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
+ 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x3f,
+ 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff
+};
+
+void
+test_escape2 (void *f, void *data)
+{
+ char escaped[1024];
+ gsize len;
+
+ /* Ensure that escaping data that doesn't need escaping works */
+ len = dm_escape (data2, sizeof (data2), escaped, sizeof (escaped));
+ g_assert (len == sizeof (data2));
+ g_assert (memcmp (escaped, data2, len) == 0);
+}
+
+void
+test_escape_unescape (void *f, void *data)
+{
+ char escaped[512];
+ char unescaped[512];
+ gsize len, unlen;
+ gboolean escaping = FALSE;
+
+ /* Ensure that escaping data that needs escaping, and then unescaping it,
+ * produces the exact same data as was originally escaped.
+ */
+ len = dm_escape (data1, sizeof (data1), escaped, sizeof (escaped));
+ unlen = dm_unescape (escaped, len, unescaped, sizeof (unescaped), &escaping);
+
+ g_assert (unlen == sizeof (data1));
+ g_assert (memcmp (unescaped, data1, unlen) == 0);
+}
+
diff --git a/libqcdm/tests/test-qcdm-escaping.h b/libqcdm/tests/test-qcdm-escaping.h
new file mode 100644
index 00000000..91706ee2
--- /dev/null
+++ b/libqcdm/tests/test-qcdm-escaping.h
@@ -0,0 +1,26 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * Copyright (C) 2010 Red Hat, Inc.
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef TEST_QCDM_ESCAPING_H
+#define TEST_QCDM_ESCAPING_H
+
+void test_escape1 (void *f, void *data);
+void test_escape2 (void *f, void *data);
+void test_escape_unescape (void *f, void *data);
+
+#endif /* TEST_QCDM_ESCAPING_H */
+
diff --git a/libqcdm/tests/test-qcdm-result.c b/libqcdm/tests/test-qcdm-result.c
new file mode 100644
index 00000000..87f264b0
--- /dev/null
+++ b/libqcdm/tests/test-qcdm-result.c
@@ -0,0 +1,71 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * Copyright (C) 2010 Red Hat, Inc.
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <glib.h>
+#include <string.h>
+
+#include "test-qcdm-result.h"
+#include "result.h"
+#include "result-private.h"
+
+#define TEST_TAG "test"
+
+void
+test_result_string (void *f, void *data)
+{
+ const char *str = "foobarblahblahblah";
+ const char *tmp = NULL;
+ QCDMResult *result;
+
+ result = qcdm_result_new ();
+ qcdm_result_add_string (result, TEST_TAG, str);
+
+ qcdm_result_get_string (result, TEST_TAG, &tmp);
+ g_assert (tmp);
+ g_assert (strcmp (tmp, str) == 0);
+
+ qcdm_result_unref (result);
+}
+
+void
+test_result_uint32 (void *f, void *data)
+{
+ guint32 num = 0xDEADBEEF;
+ guint32 tmp = 0;
+ QCDMResult *result;
+
+ result = qcdm_result_new ();
+ qcdm_result_add_uint32 (result, TEST_TAG, num);
+
+ qcdm_result_get_uint32 (result, TEST_TAG, &tmp);
+ g_assert (tmp == num);
+}
+
+void
+test_result_uint8 (void *f, void *data)
+{
+ guint8 num = 0x1E;
+ guint8 tmp = 0;
+ QCDMResult *result;
+
+ result = qcdm_result_new ();
+ qcdm_result_add_uint8 (result, TEST_TAG, num);
+
+ qcdm_result_get_uint8 (result, TEST_TAG, &tmp);
+ g_assert (tmp == num);
+}
+
diff --git a/libqcdm/tests/test-qcdm-result.h b/libqcdm/tests/test-qcdm-result.h
new file mode 100644
index 00000000..20d6cec0
--- /dev/null
+++ b/libqcdm/tests/test-qcdm-result.h
@@ -0,0 +1,26 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * Copyright (C) 2010 Red Hat, Inc.
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef TEST_QCDM_RESULT_H
+#define TEST_QCDM_RESULT_H
+
+void test_result_string (void *f, void *data);
+void test_result_uint32 (void *f, void *data);
+void test_result_uint8 (void *f, void *data);
+
+#endif /* TEST_QCDM_RESULT_H */
+
diff --git a/libqcdm/tests/test-qcdm.c b/libqcdm/tests/test-qcdm.c
new file mode 100644
index 00000000..e5e3b42a
--- /dev/null
+++ b/libqcdm/tests/test-qcdm.c
@@ -0,0 +1,107 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * Copyright (C) 2010 Red Hat, Inc.
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <glib.h>
+#include <string.h>
+
+#include "test-qcdm-crc.h"
+#include "test-qcdm-escaping.h"
+#include "test-qcdm-com.h"
+#include "test-qcdm-result.h"
+
+typedef struct {
+ gpointer com_data;
+} TestData;
+
+typedef void (*TCFunc)(void);
+
+#define TESTCASE(t, d) g_test_create_case (#t, 0, d, NULL, (TCFunc) t, NULL)
+
+static TestData *
+test_data_new (const char *port)
+{
+ TestData *d;
+
+ d = g_malloc0 (sizeof (TestData));
+ g_assert (d);
+
+ if (port)
+ d->com_data = test_com_setup (port);
+
+ return d;
+}
+
+static void
+test_data_free (TestData *d)
+{
+ if (d->com_data)
+ test_com_teardown (d->com_data);
+
+ g_free (d);
+}
+
+int main (int argc, char **argv)
+{
+ GTestSuite *suite;
+ TestData *data;
+ int i;
+ const char *port = NULL;
+ gint result;
+
+ g_test_init (&argc, &argv, NULL);
+
+ /* See if we got passed a serial port for live testing */
+ for (i = 0; i < argc; i++) {
+ if (!strcmp (argv[i], "--port")) {
+ /* Make sure there's actually a port in the next arg */
+ g_assert (argc > i + 1);
+ port = argv[++i];
+ }
+ }
+
+ data = test_data_new (port);
+
+ suite = g_test_get_root ();
+
+ g_test_suite_add (suite, TESTCASE (test_crc16_1, NULL));
+ g_test_suite_add (suite, TESTCASE (test_crc16_2, NULL));
+ g_test_suite_add (suite, TESTCASE (test_escape1, NULL));
+ g_test_suite_add (suite, TESTCASE (test_escape2, NULL));
+ g_test_suite_add (suite, TESTCASE (test_escape_unescape, NULL));
+ g_test_suite_add (suite, TESTCASE (test_result_string, NULL));
+ g_test_suite_add (suite, TESTCASE (test_result_uint32, NULL));
+ g_test_suite_add (suite, TESTCASE (test_result_uint8, NULL));
+
+ /* Live tests */
+ if (port) {
+ g_test_suite_add (suite, TESTCASE (test_com_port_init, data->com_data));
+ g_test_suite_add (suite, TESTCASE (test_com_version_info, data->com_data));
+ g_test_suite_add (suite, TESTCASE (test_com_esn, data->com_data));
+ g_test_suite_add (suite, TESTCASE (test_com_mdn, data->com_data));
+ g_test_suite_add (suite, TESTCASE (test_com_status, data->com_data));
+ g_test_suite_add (suite, TESTCASE (test_com_sw_version, data->com_data));
+ g_test_suite_add (suite, TESTCASE (test_com_cm_subsys_state_info, data->com_data));
+ g_test_suite_add (suite, TESTCASE (test_com_hdr_subsys_state_info, data->com_data));
+ }
+
+ result = g_test_run ();
+
+ test_data_free (data);
+
+ return result;
+}
+
diff --git a/plugins/mm-modem-anydata-cdma.c b/plugins/mm-modem-anydata-cdma.c
index f6528ec2..eb5495eb 100644
--- a/plugins/mm-modem-anydata-cdma.c
+++ b/plugins/mm-modem-anydata-cdma.c
@@ -112,7 +112,7 @@ int_from_match_item (GMatchInfo *match_info, guint32 num, gint *val)
}
static void
-evdo_state_done (MMSerialPort *port,
+evdo_state_done (MMAtSerialPort *port,
GString *response,
GError *error,
gpointer user_data)
@@ -191,7 +191,7 @@ evdo_state_done (MMSerialPort *port,
}
static void
-state_done (MMSerialPort *port,
+state_done (MMAtSerialPort *port,
GString *response,
GError *error,
gpointer user_data)
@@ -265,7 +265,7 @@ state_done (MMSerialPort *port,
mm_generic_cdma_query_reg_state_set_callback_1x_state (info, reg_state);
/* Try for EVDO state too */
- mm_serial_port_queue_command (port, "*HSTATE?", 3, evdo_state_done, info);
+ mm_at_serial_port_queue_command (port, "*HSTATE?", 3, evdo_state_done, info);
}
static void
@@ -274,10 +274,10 @@ query_registration_state (MMGenericCdma *cdma,
gpointer user_data)
{
MMCallbackInfo *info;
- MMSerialPort *primary, *secondary, *port;
+ MMAtSerialPort *primary, *secondary, *port;
- port = primary = mm_generic_cdma_get_port (cdma, MM_PORT_TYPE_PRIMARY);
- secondary = mm_generic_cdma_get_port (cdma, MM_PORT_TYPE_SECONDARY);
+ port = primary = mm_generic_cdma_get_at_port (cdma, MM_PORT_TYPE_PRIMARY);
+ secondary = mm_generic_cdma_get_at_port (cdma, MM_PORT_TYPE_SECONDARY);
info = mm_generic_cdma_query_reg_state_callback_info_new (cdma, callback, user_data);
@@ -293,7 +293,7 @@ query_registration_state (MMGenericCdma *cdma,
port = secondary;
}
- mm_serial_port_queue_command (port, "*STATE?", 3, state_done, info);
+ mm_at_serial_port_queue_command (port, "*STATE?", 3, state_done, info);
}
/*****************************************************************************/
@@ -310,22 +310,22 @@ grab_port (MMModem *modem,
GRegex *regex;
port = mm_generic_cdma_grab_port (MM_GENERIC_CDMA (modem), subsys, name, suggested_type, user_data, error);
- if (port && MM_IS_SERIAL_PORT (port)) {
+ if (port && MM_IS_AT_SERIAL_PORT (port)) {
/* Data state notifications */
/* Data call has connected */
regex = g_regex_new ("\\r\\n\\*ACTIVE:(.*)\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
- mm_serial_port_add_unsolicited_msg_handler (MM_SERIAL_PORT (port), regex, NULL, NULL, NULL);
+ mm_at_serial_port_add_unsolicited_msg_handler (MM_AT_SERIAL_PORT (port), regex, NULL, NULL, NULL);
g_regex_unref (regex);
/* Data call disconnected */
regex = g_regex_new ("\\r\\n\\*INACTIVE:(.*)\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
- mm_serial_port_add_unsolicited_msg_handler (MM_SERIAL_PORT (port), regex, NULL, NULL, NULL);
+ mm_at_serial_port_add_unsolicited_msg_handler (MM_AT_SERIAL_PORT (port), regex, NULL, NULL, NULL);
g_regex_unref (regex);
/* Modem is now dormant */
regex = g_regex_new ("\\r\\n\\*DORMANT:(.*)\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
- mm_serial_port_add_unsolicited_msg_handler (MM_SERIAL_PORT (port), regex, NULL, NULL, NULL);
+ mm_at_serial_port_add_unsolicited_msg_handler (MM_AT_SERIAL_PORT (port), regex, NULL, NULL, NULL);
g_regex_unref (regex);
/* Abnomral state notifications
@@ -336,17 +336,17 @@ grab_port (MMModem *modem,
/* Network acquisition fail */
regex = g_regex_new ("\\r\\n\\*OFFLINE:(.*)\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
- mm_serial_port_add_unsolicited_msg_handler (MM_SERIAL_PORT (port), regex, NULL, NULL, NULL);
+ mm_at_serial_port_add_unsolicited_msg_handler (MM_AT_SERIAL_PORT (port), regex, NULL, NULL, NULL);
g_regex_unref (regex);
/* Registration fail */
regex = g_regex_new ("\\r\\n\\*REGREQ:(.*)\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
- mm_serial_port_add_unsolicited_msg_handler (MM_SERIAL_PORT (port), regex, NULL, NULL, NULL);
+ mm_at_serial_port_add_unsolicited_msg_handler (MM_AT_SERIAL_PORT (port), regex, NULL, NULL, NULL);
g_regex_unref (regex);
/* Authentication fail */
regex = g_regex_new ("\\r\\n\\*AUTHREQ:(.*)\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
- mm_serial_port_add_unsolicited_msg_handler (MM_SERIAL_PORT (port), regex, NULL, NULL, NULL);
+ mm_at_serial_port_add_unsolicited_msg_handler (MM_AT_SERIAL_PORT (port), regex, NULL, NULL, NULL);
g_regex_unref (regex);
}
diff --git a/plugins/mm-modem-gobi-gsm.c b/plugins/mm-modem-gobi-gsm.c
index 7ea9f8f4..566d0c82 100644
--- a/plugins/mm-modem-gobi-gsm.c
+++ b/plugins/mm-modem-gobi-gsm.c
@@ -23,6 +23,7 @@
#include "mm-errors.h"
#include "mm-callback-info.h"
#include "mm-modem-gsm-card.h"
+#include "mm-at-serial-port.h"
static void modem_init (MMModem *modem_class);
static void modem_gsm_card_init (MMModemGsmCard *gsm_card_class);
@@ -51,7 +52,7 @@ mm_modem_gobi_gsm_new (const char *device,
/*****************************************************************************/
static void
-get_string_done (MMSerialPort *port,
+get_string_done (MMAtSerialPort *port,
GString *response,
GError *error,
gpointer user_data)
@@ -75,13 +76,13 @@ get_imsi (MMModemGsmCard *modem,
MMModemStringFn callback,
gpointer user_data)
{
- MMSerialPort *primary;
+ MMAtSerialPort *primary;
MMCallbackInfo *info;
info = mm_callback_info_string_new (MM_MODEM (modem), callback, user_data);
- primary = mm_generic_gsm_get_port (MM_GENERIC_GSM (modem), MM_PORT_TYPE_PRIMARY);
+ primary = mm_generic_gsm_get_at_port (MM_GENERIC_GSM (modem), MM_PORT_TYPE_PRIMARY);
g_assert (primary);
- mm_serial_port_queue_command_cached (primary, "+CIMI", 3, get_string_done, info);
+ mm_at_serial_port_queue_command_cached (primary, "+CIMI", 3, get_string_done, info);
}
static void
diff --git a/plugins/mm-modem-hso.c b/plugins/mm-modem-hso.c
index 9e96226b..4fe6fd03 100644
--- a/plugins/mm-modem-hso.c
+++ b/plugins/mm-modem-hso.c
@@ -105,7 +105,7 @@ hso_get_cid (MMModemHso *self)
}
static void
-auth_done (MMSerialPort *port,
+auth_done (MMAtSerialPort *port,
GString *response,
GError *error,
gpointer user_data)
@@ -133,11 +133,11 @@ static void
_internal_hso_modem_authenticate (MMModemHso *self, MMCallbackInfo *info)
{
MMModemHsoPrivate *priv = MM_MODEM_HSO_GET_PRIVATE (self);
- MMSerialPort *primary;
+ MMAtSerialPort *primary;
gint cid;
char *command;
- primary = mm_generic_gsm_get_port (MM_GENERIC_GSM (self), MM_PORT_TYPE_PRIMARY);
+ primary = mm_generic_gsm_get_at_port (MM_GENERIC_GSM (self), MM_PORT_TYPE_PRIMARY);
g_assert (primary);
cid = hso_get_cid (self);
@@ -153,7 +153,7 @@ _internal_hso_modem_authenticate (MMModemHso *self, MMCallbackInfo *info)
}
- mm_serial_port_queue_command (primary, command, 3, auth_done, info);
+ mm_at_serial_port_queue_command (primary, command, 3, auth_done, info);
g_free (command);
}
@@ -210,7 +210,7 @@ connect_pending_done (MMModemHso *self)
}
static void
-connection_enabled (MMSerialPort *port,
+connection_enabled (MMAtSerialPort *port,
GMatchInfo *match_info,
gpointer user_data)
{
@@ -242,7 +242,7 @@ connection_enabled (MMSerialPort *port,
#define IGNORE_ERRORS_TAG "ignore-errors"
static void
-hso_call_control_done (MMSerialPort *port,
+hso_call_control_done (MMAtSerialPort *port,
GString *response,
GError *error,
gpointer user_data)
@@ -264,15 +264,15 @@ hso_call_control (MMModemHso *self,
{
MMCallbackInfo *info;
char *command;
- MMSerialPort *primary;
+ MMAtSerialPort *primary;
info = mm_callback_info_new (MM_MODEM (self), callback, user_data);
mm_callback_info_set_data (info, IGNORE_ERRORS_TAG, GUINT_TO_POINTER (ignore_errors), NULL);
command = g_strdup_printf ("AT_OWANCALL=%d,%d,1", hso_get_cid (self), activate ? 1 : 0);
- primary = mm_generic_gsm_get_port (MM_GENERIC_GSM (self), MM_PORT_TYPE_PRIMARY);
+ primary = mm_generic_gsm_get_at_port (MM_GENERIC_GSM (self), MM_PORT_TYPE_PRIMARY);
g_assert (primary);
- mm_serial_port_queue_command (primary, command, 3, hso_call_control_done, info);
+ mm_at_serial_port_queue_command (primary, command, 3, hso_call_control_done, info);
g_free (command);
}
@@ -444,7 +444,7 @@ ip4_config_invoke (MMCallbackInfo *info)
}
static void
-get_ip4_config_done (MMSerialPort *port,
+get_ip4_config_done (MMAtSerialPort *port,
GString *response,
GError *error,
gpointer user_data)
@@ -507,20 +507,20 @@ get_ip4_config (MMModem *modem,
{
MMCallbackInfo *info;
char *command;
- MMSerialPort *primary;
+ MMAtSerialPort *primary;
info = mm_callback_info_new_full (modem, ip4_config_invoke, G_CALLBACK (callback), user_data);
command = g_strdup_printf ("AT_OWANDATA=%d", hso_get_cid (MM_MODEM_HSO (modem)));
- primary = mm_generic_gsm_get_port (MM_GENERIC_GSM (modem), MM_PORT_TYPE_PRIMARY);
+ primary = mm_generic_gsm_get_at_port (MM_GENERIC_GSM (modem), MM_PORT_TYPE_PRIMARY);
g_assert (primary);
- mm_serial_port_queue_command (primary, command, 3, get_ip4_config_done, info);
+ mm_at_serial_port_queue_command (primary, command, 3, get_ip4_config_done, info);
g_free (command);
}
/*****************************************************************************/
static void
-disconnect_owancall_done (MMSerialPort *port,
+disconnect_owancall_done (MMAtSerialPort *port,
GString *response,
GError *error,
gpointer user_data)
@@ -535,16 +535,16 @@ do_disconnect (MMGenericGsm *gsm,
gpointer user_data)
{
MMCallbackInfo *info;
- MMSerialPort *primary;
+ MMAtSerialPort *primary;
char *command;
info = mm_callback_info_new (MM_MODEM (gsm), callback, user_data);
- primary = mm_generic_gsm_get_port (gsm, MM_PORT_TYPE_PRIMARY);
+ primary = mm_generic_gsm_get_at_port (gsm, MM_PORT_TYPE_PRIMARY);
g_assert (primary);
command = g_strdup_printf ("AT_OWANCALL=%d,0,0", cid);
- mm_serial_port_queue_command (primary, command, 3, disconnect_owancall_done, info);
+ mm_at_serial_port_queue_command (primary, command, 3, disconnect_owancall_done, info);
g_free (command);
}
@@ -671,13 +671,13 @@ grab_port (MMModem *modem,
if (!port)
goto out;
- if (MM_IS_SERIAL_PORT (port)) {
+ if (MM_IS_AT_SERIAL_PORT (port)) {
g_object_set (G_OBJECT (port), MM_SERIAL_PORT_SEND_DELAY, (guint64) 10000, NULL);
if (ptype == MM_PORT_TYPE_PRIMARY) {
GRegex *regex;
regex = g_regex_new ("_OWANCALL: (\\d),\\s*(\\d)\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
- mm_serial_port_add_unsolicited_msg_handler (MM_SERIAL_PORT (port), regex, connection_enabled, modem, NULL);
+ mm_at_serial_port_add_unsolicited_msg_handler (MM_AT_SERIAL_PORT (port), regex, connection_enabled, modem, NULL);
g_regex_unref (regex);
}
}
diff --git a/plugins/mm-modem-huawei-cdma.c b/plugins/mm-modem-huawei-cdma.c
index 19b731a8..b164e675 100644
--- a/plugins/mm-modem-huawei-cdma.c
+++ b/plugins/mm-modem-huawei-cdma.c
@@ -82,7 +82,7 @@ parse_quality (const char *str, const char *detail)
}
static void
-handle_1x_quality_change (MMSerialPort *port,
+handle_1x_quality_change (MMAtSerialPort *port,
GMatchInfo *match_info,
gpointer user_data)
{
@@ -99,9 +99,9 @@ handle_1x_quality_change (MMSerialPort *port,
}
static void
-handle_evdo_quality_change (MMSerialPort *port,
- GMatchInfo *match_info,
- gpointer user_data)
+handle_evdo_quality_change (MMAtSerialPort *port,
+ GMatchInfo *match_info,
+ gpointer user_data)
{
MMModemHuaweiCdma *self = MM_MODEM_HUAWEI_CDMA (user_data);
char *str;
@@ -152,7 +152,7 @@ uint_from_match_item (GMatchInfo *match_info, guint32 num, guint32 *val)
}
static void
-sysinfo_done (MMSerialPort *port,
+sysinfo_done (MMAtSerialPort *port,
GString *response,
GError *error,
gpointer user_data)
@@ -239,10 +239,10 @@ query_registration_state (MMGenericCdma *cdma,
gpointer user_data)
{
MMCallbackInfo *info;
- MMSerialPort *primary, *secondary, *port;
+ MMAtSerialPort *primary, *secondary, *port;
- port = primary = mm_generic_cdma_get_port (cdma, MM_PORT_TYPE_PRIMARY);
- secondary = mm_generic_cdma_get_port (cdma, MM_PORT_TYPE_SECONDARY);
+ port = primary = mm_generic_cdma_get_at_port (cdma, MM_PORT_TYPE_PRIMARY);
+ secondary = mm_generic_cdma_get_at_port (cdma, MM_PORT_TYPE_SECONDARY);
info = mm_generic_cdma_query_reg_state_callback_info_new (cdma, callback, user_data);
@@ -258,7 +258,7 @@ query_registration_state (MMGenericCdma *cdma,
port = secondary;
}
- mm_serial_port_queue_command (port, "^SYSINFO", 3, sysinfo_done, info);
+ mm_at_serial_port_queue_command (port, "^SYSINFO", 3, sysinfo_done, info);
}
/*****************************************************************************/
@@ -275,14 +275,14 @@ grab_port (MMModem *modem,
GRegex *regex;
port = mm_generic_cdma_grab_port (MM_GENERIC_CDMA (modem), subsys, name, suggested_type, user_data, error);
- if (port && MM_IS_SERIAL_PORT (port)) {
+ if (port && MM_IS_AT_SERIAL_PORT (port)) {
gboolean evdo0 = FALSE, evdoA = FALSE;
g_object_set (G_OBJECT (port), MM_PORT_CARRIER_DETECT, FALSE, NULL);
/* 1x signal level */
regex = g_regex_new ("\\r\\n\\^RSSILVL:(\\d+)\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
- mm_serial_port_add_unsolicited_msg_handler (MM_SERIAL_PORT (port), regex, handle_1x_quality_change, modem, NULL);
+ mm_at_serial_port_add_unsolicited_msg_handler (MM_AT_SERIAL_PORT (port), regex, handle_1x_quality_change, modem, NULL);
g_regex_unref (regex);
g_object_get (G_OBJECT (modem),
@@ -293,7 +293,7 @@ grab_port (MMModem *modem,
if (evdo0 || evdoA) {
/* EVDO signal level */
regex = g_regex_new ("\\r\\n\\^HRSSILVL:(\\d+)\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
- mm_serial_port_add_unsolicited_msg_handler (MM_SERIAL_PORT (port), regex, handle_evdo_quality_change, modem, NULL);
+ mm_at_serial_port_add_unsolicited_msg_handler (MM_AT_SERIAL_PORT (port), regex, handle_evdo_quality_change, modem, NULL);
g_regex_unref (regex);
}
}
diff --git a/plugins/mm-modem-huawei-gsm.c b/plugins/mm-modem-huawei-gsm.c
index b0d6a16e..b2677414 100644
--- a/plugins/mm-modem-huawei-gsm.c
+++ b/plugins/mm-modem-huawei-gsm.c
@@ -25,7 +25,7 @@
#include "mm-modem-gsm-network.h"
#include "mm-errors.h"
#include "mm-callback-info.h"
-#include "mm-serial-port.h"
+#include "mm-at-serial-port.h"
#include "mm-serial-parsers.h"
static void modem_init (MMModem *modem_class);
@@ -104,7 +104,7 @@ parse_syscfg (MMModemHuaweiGsm *self,
}
static void
-set_allowed_mode_done (MMSerialPort *port,
+set_allowed_mode_done (MMAtSerialPort *port,
GString *response,
GError *error,
gpointer user_data)
@@ -118,7 +118,7 @@ set_allowed_mode_done (MMSerialPort *port,
}
static void
-set_allowed_mode_get_done (MMSerialPort *port,
+set_allowed_mode_get_done (MMAtSerialPort *port,
GString *response,
GError *error,
gpointer user_data)
@@ -163,7 +163,7 @@ set_allowed_mode_get_done (MMSerialPort *port,
}
command = g_strdup_printf ("AT^SYSCFG=%d,%d,%X,%d,%d", a, b, band, u1, u2);
- mm_serial_port_queue_command (port, command, 3, set_allowed_mode_done, info);
+ mm_at_serial_port_queue_command (port, command, 3, set_allowed_mode_done, info);
g_free (command);
}
}
@@ -176,22 +176,22 @@ set_allowed_mode (MMGenericGsm *gsm,
gpointer user_data)
{
MMCallbackInfo *info;
- MMSerialPort *primary;
+ MMAtSerialPort *primary;
info = mm_callback_info_new (MM_MODEM (gsm), callback, user_data);
mm_callback_info_set_data (info, "mode", GUINT_TO_POINTER (mode), NULL);
- primary = mm_generic_gsm_get_port (MM_GENERIC_GSM (gsm), MM_PORT_TYPE_PRIMARY);
+ primary = mm_generic_gsm_get_at_port (MM_GENERIC_GSM (gsm), MM_PORT_TYPE_PRIMARY);
g_assert (primary);
/* Get current configuration first so we don't change band and other
* stuff when updating the mode.
*/
- mm_serial_port_queue_command (primary, "AT^SYSCFG?", 3, set_allowed_mode_get_done, info);
+ mm_at_serial_port_queue_command (primary, "AT^SYSCFG?", 3, set_allowed_mode_get_done, info);
}
static void
-get_allowed_mode_done (MMSerialPort *port,
+get_allowed_mode_done (MMAtSerialPort *port,
GString *response,
GError *error,
gpointer user_data)
@@ -216,16 +216,16 @@ get_allowed_mode (MMGenericGsm *gsm,
gpointer user_data)
{
MMCallbackInfo *info;
- MMSerialPort *primary;
+ MMAtSerialPort *primary;
info = mm_callback_info_uint_new (MM_MODEM (gsm), callback, user_data);
- primary = mm_generic_gsm_get_port (gsm, MM_PORT_TYPE_PRIMARY);
+ primary = mm_generic_gsm_get_at_port (gsm, MM_PORT_TYPE_PRIMARY);
g_assert (primary);
- mm_serial_port_queue_command (primary, "AT^SYSCFG?", 3, get_allowed_mode_done, info);
+ mm_at_serial_port_queue_command (primary, "AT^SYSCFG?", 3, get_allowed_mode_done, info);
}
static void
-set_band_done (MMSerialPort *port,
+set_band_done (MMAtSerialPort *port,
GString *response,
GError *error,
gpointer user_data)
@@ -244,7 +244,7 @@ set_band_done (MMSerialPort *port,
}
static void
-set_band_get_done (MMSerialPort *port,
+set_band_get_done (MMAtSerialPort *port,
GString *response,
GError *error,
gpointer user_data)
@@ -286,7 +286,7 @@ set_band_get_done (MMSerialPort *port,
}
command = g_strdup_printf ("AT^SYSCFG=%d,%d,%X,%d,%d", a, b, band, u1, u2);
- mm_serial_port_queue_command (port, command, 3, set_band_done, info);
+ mm_at_serial_port_queue_command (port, command, 3, set_band_done, info);
g_free (command);
}
}
@@ -299,7 +299,7 @@ set_band (MMModemGsmNetwork *modem,
gpointer user_data)
{
MMCallbackInfo *info;
- MMSerialPort *primary;
+ MMAtSerialPort *primary;
info = mm_callback_info_new (MM_MODEM (modem), callback, user_data);
@@ -310,9 +310,9 @@ set_band (MMModemGsmNetwork *modem,
case MM_MODEM_GSM_BAND_U2100:
case MM_MODEM_GSM_BAND_PCS:
mm_callback_info_set_data (info, "band", GUINT_TO_POINTER (band), NULL);
- primary = mm_generic_gsm_get_port (MM_GENERIC_GSM (modem), MM_PORT_TYPE_PRIMARY);
+ primary = mm_generic_gsm_get_at_port (MM_GENERIC_GSM (modem), MM_PORT_TYPE_PRIMARY);
g_assert (primary);
- mm_serial_port_queue_command (primary, "AT^SYSCFG?", 3, set_band_get_done, info);
+ mm_at_serial_port_queue_command (primary, "AT^SYSCFG?", 3, set_band_get_done, info);
return;
default:
info->error = g_error_new_literal (MM_MODEM_ERROR, MM_MODEM_ERROR_GENERAL, "Invalid band.");
@@ -323,7 +323,7 @@ set_band (MMModemGsmNetwork *modem,
}
static void
-get_band_done (MMSerialPort *port,
+get_band_done (MMAtSerialPort *port,
GString *response,
GError *error,
gpointer user_data)
@@ -348,7 +348,7 @@ get_band (MMModemGsmNetwork *modem,
gpointer user_data)
{
MMModemHuaweiGsmPrivate *priv = MM_MODEM_HUAWEI_GSM_GET_PRIVATE (modem);
- MMSerialPort *primary;
+ MMAtSerialPort *primary;
if (priv->band != MM_MODEM_GSM_BAND_ANY) {
/* have cached mode (from an unsolicited message). Use that */
@@ -362,16 +362,16 @@ get_band (MMModemGsmNetwork *modem,
MMCallbackInfo *info;
info = mm_callback_info_uint_new (MM_MODEM (modem), callback, user_data);
- primary = mm_generic_gsm_get_port (MM_GENERIC_GSM (modem), MM_PORT_TYPE_PRIMARY);
+ primary = mm_generic_gsm_get_at_port (MM_GENERIC_GSM (modem), MM_PORT_TYPE_PRIMARY);
g_assert (primary);
- mm_serial_port_queue_command (primary, "AT^SYSCFG?", 3, get_band_done, info);
+ mm_at_serial_port_queue_command (primary, "AT^SYSCFG?", 3, get_band_done, info);
}
}
/* Unsolicited message handlers */
static void
-handle_signal_quality_change (MMSerialPort *port,
+handle_signal_quality_change (MMAtSerialPort *port,
GMatchInfo *match_info,
gpointer user_data)
{
@@ -395,7 +395,7 @@ handle_signal_quality_change (MMSerialPort *port,
}
static void
-handle_mode_change (MMSerialPort *port,
+handle_mode_change (MMAtSerialPort *port,
GMatchInfo *match_info,
gpointer user_data)
{
@@ -439,7 +439,7 @@ handle_mode_change (MMSerialPort *port,
}
static void
-handle_status_change (MMSerialPort *port,
+handle_status_change (MMAtSerialPort *port,
GMatchInfo *match_info,
gpointer user_data)
{
@@ -491,34 +491,34 @@ grab_port (MMModem *modem,
}
if (usbif == 0) {
- if (!mm_generic_gsm_get_port (gsm, MM_PORT_TYPE_PRIMARY))
+ if (!mm_generic_gsm_get_at_port (gsm, MM_PORT_TYPE_PRIMARY))
ptype = MM_PORT_TYPE_PRIMARY;
} else if (suggested_type == MM_PORT_TYPE_SECONDARY) {
- if (!mm_generic_gsm_get_port (gsm, MM_PORT_TYPE_SECONDARY))
+ if (!mm_generic_gsm_get_at_port (gsm, MM_PORT_TYPE_SECONDARY))
ptype = MM_PORT_TYPE_SECONDARY;
}
port = mm_generic_gsm_grab_port (gsm, subsys, name, ptype, error);
- if (port && MM_IS_SERIAL_PORT (port)) {
+ if (port && MM_IS_AT_SERIAL_PORT (port)) {
GRegex *regex;
g_object_set (G_OBJECT (port), MM_PORT_CARRIER_DETECT, FALSE, NULL);
regex = g_regex_new ("\\r\\n\\^RSSI:(\\d+)\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
- mm_serial_port_add_unsolicited_msg_handler (MM_SERIAL_PORT (port), regex, handle_signal_quality_change, modem, NULL);
+ mm_at_serial_port_add_unsolicited_msg_handler (MM_AT_SERIAL_PORT (port), regex, handle_signal_quality_change, modem, NULL);
g_regex_unref (regex);
regex = g_regex_new ("\\r\\n\\^MODE:(\\d),(\\d)\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
- mm_serial_port_add_unsolicited_msg_handler (MM_SERIAL_PORT (port), regex, handle_mode_change, modem, NULL);
+ mm_at_serial_port_add_unsolicited_msg_handler (MM_AT_SERIAL_PORT (port), regex, handle_mode_change, modem, NULL);
g_regex_unref (regex);
regex = g_regex_new ("\\r\\n\\^DSFLOWRPT:(.+)\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
- mm_serial_port_add_unsolicited_msg_handler (MM_SERIAL_PORT (port), regex, handle_status_change, modem, NULL);
+ mm_at_serial_port_add_unsolicited_msg_handler (MM_AT_SERIAL_PORT (port), regex, handle_status_change, modem, NULL);
g_regex_unref (regex);
regex = g_regex_new ("\\r\\n\\^BOOT:.+\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
- mm_serial_port_add_unsolicited_msg_handler (MM_SERIAL_PORT (port), regex, NULL, modem, NULL);
+ mm_at_serial_port_add_unsolicited_msg_handler (MM_AT_SERIAL_PORT (port), regex, NULL, modem, NULL);
g_regex_unref (regex);
}
diff --git a/plugins/mm-modem-mbm.c b/plugins/mm-modem-mbm.c
index 7070f728..aa648cb6 100644
--- a/plugins/mm-modem-mbm.c
+++ b/plugins/mm-modem-mbm.c
@@ -117,11 +117,11 @@ register_done (gpointer user_data)
MMModemMbm *self = MM_MODEM_MBM (reg_data->modem);
MMModemMbmPrivate *priv = MM_MODEM_MBM_GET_PRIVATE (self);
MMModemGsmNetwork *parent_modem_iface;
- MMSerialPort *primary;
+ MMAtSerialPort *primary;
priv->reg_id = 0;
- primary = mm_generic_gsm_get_port (MM_GENERIC_GSM (self), MM_PORT_TYPE_PRIMARY);
+ primary = mm_generic_gsm_get_at_port (MM_GENERIC_GSM (self), MM_PORT_TYPE_PRIMARY);
g_assert (primary);
parent_modem_iface = g_type_interface_peek_parent (MM_MODEM_GSM_NETWORK_GET_INTERFACE (self));
@@ -174,7 +174,7 @@ mbm_parse_allowed_mode (MMModemGsmAllowedMode network_mode)
}
static void
-mbm_set_allowed_mode_done (MMSerialPort *port,
+mbm_set_allowed_mode_done (MMAtSerialPort *port,
GString *response,
GError *error,
gpointer user_data)
@@ -195,19 +195,19 @@ set_allowed_mode (MMGenericGsm *gsm,
{
MMCallbackInfo *info;
char *command;
- MMSerialPort *primary;
+ MMAtSerialPort *primary;
info = mm_callback_info_new (MM_MODEM (gsm), callback, user_data);
- primary = mm_generic_gsm_get_port (gsm, MM_PORT_TYPE_PRIMARY);
+ primary = mm_generic_gsm_get_at_port (gsm, MM_PORT_TYPE_PRIMARY);
g_assert (primary);
command = g_strdup_printf ("+CFUN=%d", mbm_parse_allowed_mode (mode));
- mm_serial_port_queue_command (primary, command, 3, mbm_set_allowed_mode_done, info);
+ mm_at_serial_port_queue_command (primary, command, 3, mbm_set_allowed_mode_done, info);
g_free (command);
}
static void
-mbm_erinfo_received (MMSerialPort *port,
+mbm_erinfo_received (MMAtSerialPort *port,
GMatchInfo *info,
gpointer user_data)
{
@@ -249,7 +249,7 @@ mbm_erinfo_received (MMSerialPort *port,
}
static void
-get_allowed_mode_done (MMSerialPort *port,
+get_allowed_mode_done (MMAtSerialPort *port,
GString *response,
GError *error,
gpointer user_data)
@@ -286,12 +286,12 @@ get_allowed_mode (MMGenericGsm *gsm,
gpointer user_data)
{
MMCallbackInfo *info;
- MMSerialPort *primary;
+ MMAtSerialPort *primary;
info = mm_callback_info_uint_new (MM_MODEM (gsm), callback, user_data);
- primary = mm_generic_gsm_get_port (gsm, MM_PORT_TYPE_PRIMARY);
+ primary = mm_generic_gsm_get_at_port (gsm, MM_PORT_TYPE_PRIMARY);
g_assert (primary);
- mm_serial_port_queue_command (primary, "CFUN?", 3, get_allowed_mode_done, info);
+ mm_at_serial_port_queue_command (primary, "CFUN?", 3, get_allowed_mode_done, info);
}
/*****************************************************************************/
@@ -339,7 +339,7 @@ simple_connect (MMModemSimple *simple,
/*****************************************************************************/
static void
-mbm_enable_done (MMSerialPort *port,
+mbm_enable_done (MMAtSerialPort *port,
GString *response,
GError *error,
gpointer user_data)
@@ -347,14 +347,14 @@ mbm_enable_done (MMSerialPort *port,
MMCallbackInfo *info = (MMCallbackInfo *) user_data;
/* Start unsolicited signal strength and access technology responses */
- mm_serial_port_queue_command (port, "+CMER=3,0,0,1", 3, NULL, NULL);
- mm_serial_port_queue_command (port, "*ERINFO=1", 3, NULL, NULL);
+ mm_at_serial_port_queue_command (port, "+CMER=3,0,0,1", 3, NULL, NULL);
+ mm_at_serial_port_queue_command (port, "*ERINFO=1", 3, NULL, NULL);
mm_generic_gsm_enable_complete (MM_GENERIC_GSM (info->modem), error, info);
}
static void
-mbm_enap0_done (MMSerialPort *port,
+mbm_enap0_done (MMAtSerialPort *port,
GString *response,
GError *error,
gpointer user_data)
@@ -367,12 +367,12 @@ mbm_enap0_done (MMSerialPort *port,
priv->network_mode = MBM_NETWORK_MODE_ANY;
command = g_strdup_printf ("+CFUN=%d", priv->network_mode);
- mm_serial_port_queue_command (port, command, 3, mbm_enable_done, info);
+ mm_at_serial_port_queue_command (port, command, 3, mbm_enable_done, info);
g_free (command);
}
static void
-mbm_init_done (MMSerialPort *port,
+mbm_init_done (MMAtSerialPort *port,
GString *response,
GError *error,
gpointer user_data)
@@ -388,17 +388,17 @@ mbm_init_done (MMSerialPort *port,
if (!priv->network_mode)
priv->network_mode = MBM_NETWORK_MODE_ANY;
- mm_serial_port_queue_command (port, "*ENAP=0", 3, mbm_enap0_done, info);
+ mm_at_serial_port_queue_command (port, "*ENAP=0", 3, mbm_enap0_done, info);
}
static void
-do_init (MMSerialPort *port, MMCallbackInfo *info)
+do_init (MMAtSerialPort *port, MMCallbackInfo *info)
{
- mm_serial_port_queue_command (port, "&F E0 V1 X4 &C1 +CMEE=1", 3, mbm_init_done, info);
+ mm_at_serial_port_queue_command (port, "&F E0 V1 X4 &C1 +CMEE=1", 3, mbm_init_done, info);
}
static void
-mbm_emrdy_done (MMSerialPort *port,
+mbm_emrdy_done (MMAtSerialPort *port,
GString *response,
GError *error,
gpointer user_data)
@@ -421,18 +421,18 @@ do_enable (MMGenericGsm *self, MMModemFn callback, gpointer user_data)
{
MMModemMbmPrivate *priv = MM_MODEM_MBM_GET_PRIVATE (self);
MMCallbackInfo *info;
- MMSerialPort *primary;
+ MMAtSerialPort *primary;
info = mm_callback_info_new (MM_MODEM (self), callback, user_data);
- primary = mm_generic_gsm_get_port (self, MM_PORT_TYPE_PRIMARY);
+ primary = mm_generic_gsm_get_at_port (self, MM_PORT_TYPE_PRIMARY);
g_assert (primary);
if (priv->have_emrdy) {
/* Modem is ready, no need to check EMRDY */
do_init (primary, info);
} else
- mm_serial_port_queue_command (primary, "*EMRDY?", 5, mbm_emrdy_done, info);
+ mm_at_serial_port_queue_command (primary, "*EMRDY?", 5, mbm_emrdy_done, info);
}
typedef struct {
@@ -442,7 +442,7 @@ typedef struct {
} DisableInfo;
static void
-disable_unsolicited_done (MMSerialPort *port,
+disable_unsolicited_done (MMAtSerialPort *port,
GString *response,
GError *error,
gpointer user_data)
@@ -461,7 +461,7 @@ disable (MMModem *modem,
MMModemFn callback,
gpointer user_data)
{
- MMSerialPort *primary;
+ MMAtSerialPort *primary;
DisableInfo *info;
info = g_malloc0 (sizeof (DisableInfo));
@@ -469,11 +469,11 @@ disable (MMModem *modem,
info->user_data = user_data;
info->modem = modem;
- primary = mm_generic_gsm_get_port (MM_GENERIC_GSM (modem), MM_PORT_TYPE_PRIMARY);
+ primary = mm_generic_gsm_get_at_port (MM_GENERIC_GSM (modem), MM_PORT_TYPE_PRIMARY);
g_assert (primary);
/* Turn off unsolicited responses */
- mm_serial_port_queue_command (primary, "+CMER=0;*ERINFO=0", 5, disable_unsolicited_done, info);
+ mm_at_serial_port_queue_command (primary, "+CMER=0;*ERINFO=0", 5, disable_unsolicited_done, info);
}
static void
@@ -499,11 +499,11 @@ do_disconnect (MMGenericGsm *gsm,
MMModemFn callback,
gpointer user_data)
{
- MMSerialPort *primary;
+ MMAtSerialPort *primary;
- primary = mm_generic_gsm_get_port (gsm, MM_PORT_TYPE_PRIMARY);
+ primary = mm_generic_gsm_get_at_port (gsm, MM_PORT_TYPE_PRIMARY);
g_assert (primary);
- mm_serial_port_queue_command (primary, "*ENAP=0", 3, NULL, NULL);
+ mm_at_serial_port_queue_command (primary, "*ENAP=0", 3, NULL, NULL);
MM_GENERIC_GSM_CLASS (mm_modem_mbm_parent_class)->do_disconnect (gsm, cid, callback, user_data);
}
@@ -511,7 +511,7 @@ do_disconnect (MMGenericGsm *gsm,
/*****************************************************************************/
static void
-mbm_emrdy_received (MMSerialPort *port,
+mbm_emrdy_received (MMAtSerialPort *port,
GMatchInfo *info,
gpointer user_data)
{
@@ -519,7 +519,7 @@ mbm_emrdy_received (MMSerialPort *port,
}
static void
-mbm_pacsp_received (MMSerialPort *port,
+mbm_pacsp_received (MMAtSerialPort *port,
GMatchInfo *info,
gpointer user_data)
{
@@ -527,7 +527,7 @@ mbm_pacsp_received (MMSerialPort *port,
}
static void
-mbm_ciev_received (MMSerialPort *port,
+mbm_ciev_received (MMAtSerialPort *port,
GMatchInfo *info,
gpointer user_data)
{
@@ -570,7 +570,7 @@ mbm_do_connect_done (MMModemMbm *self, gboolean success)
}
static void
-mbm_e2nap_received (MMSerialPort *port,
+mbm_e2nap_received (MMAtSerialPort *port,
GMatchInfo *info,
gpointer user_data)
{
@@ -598,7 +598,7 @@ mbm_e2nap_received (MMSerialPort *port,
}
static void
-enap_poll_response (MMSerialPort *port,
+enap_poll_response (MMAtSerialPort *port,
GString *response,
GError *error,
gpointer user_data)
@@ -633,20 +633,21 @@ static gboolean
enap_poll (gpointer user_data)
{
MMCallbackInfo *info = (MMCallbackInfo *) user_data;
- MMSerialPort *port = mm_generic_gsm_get_port (MM_GENERIC_GSM (info->modem), MM_PORT_TYPE_PRIMARY);
+ MMAtSerialPort *port;
+ port = mm_generic_gsm_get_at_port (MM_GENERIC_GSM (info->modem), MM_PORT_TYPE_PRIMARY);
g_assert (port);
- mm_serial_port_queue_command (port, "AT*ENAP?", 3, enap_poll_response, user_data);
+ mm_at_serial_port_queue_command (port, "AT*ENAP?", 3, enap_poll_response, user_data);
/* we cancel this in the _done function if all is fine */
return TRUE;
}
static void
-enap_done (MMSerialPort *port,
- GString *response,
- GError *error,
- gpointer user_data)
+enap_done (MMAtSerialPort *port,
+ GString *response,
+ GError *error,
+ gpointer user_data)
{
MMCallbackInfo *info = (MMCallbackInfo *) user_data;
guint tid;
@@ -662,7 +663,7 @@ enap_done (MMSerialPort *port,
}
static void
-mbm_auth_done (MMSerialPort *port,
+mbm_auth_done (MMAtSerialPort *port,
GString *response,
GError *error,
gpointer user_data)
@@ -679,10 +680,10 @@ mbm_auth_done (MMSerialPort *port,
cid = mm_generic_gsm_get_cid (modem);
- mm_serial_port_queue_command (port, "AT*E2NAP=1", 3, NULL, NULL);
+ mm_at_serial_port_queue_command (port, "AT*E2NAP=1", 3, NULL, NULL);
command = g_strdup_printf ("AT*ENAP=1,%d", cid);
- mm_serial_port_queue_command (port, command, 3, enap_done, user_data);
+ mm_at_serial_port_queue_command (port, command, 3, enap_done, user_data);
g_free (command);
}
@@ -692,9 +693,9 @@ mbm_modem_authenticate (MMModemMbm *self,
const char *password,
gpointer user_data)
{
- MMSerialPort *primary;
+ MMAtSerialPort *primary;
- primary = mm_generic_gsm_get_port (MM_GENERIC_GSM (self), MM_PORT_TYPE_PRIMARY);
+ primary = mm_generic_gsm_get_at_port (MM_GENERIC_GSM (self), MM_PORT_TYPE_PRIMARY);
g_assert (primary);
if (username || password) {
@@ -705,7 +706,7 @@ mbm_modem_authenticate (MMModemMbm *self,
username ? username : "",
password ? password : "");
- mm_serial_port_queue_command (primary, command, 3, mbm_auth_done, user_data);
+ mm_at_serial_port_queue_command (primary, command, 3, mbm_auth_done, user_data);
g_free (command);
} else
mbm_auth_done (primary, NULL, NULL, user_data);
@@ -765,47 +766,47 @@ grab_port (MMModem *modem,
if (!strcmp (subsys, "tty")) {
if (suggested_type == MM_PORT_TYPE_UNKNOWN) {
- if (!mm_generic_gsm_get_port (gsm, MM_PORT_TYPE_PRIMARY))
+ if (!mm_generic_gsm_get_at_port (gsm, MM_PORT_TYPE_PRIMARY))
ptype = MM_PORT_TYPE_PRIMARY;
- else if (!mm_generic_gsm_get_port (gsm, MM_PORT_TYPE_SECONDARY))
+ else if (!mm_generic_gsm_get_at_port (gsm, MM_PORT_TYPE_SECONDARY))
ptype = MM_PORT_TYPE_SECONDARY;
} else
ptype = suggested_type;
}
port = mm_generic_gsm_grab_port (gsm, subsys, name, ptype, error);
- if (port && MM_IS_SERIAL_PORT (port)) {
+ if (port && MM_IS_AT_SERIAL_PORT (port)) {
GRegex *regex;
if (ptype == MM_PORT_TYPE_PRIMARY) {
regex = g_regex_new ("\\r\\n\\*E2NAP: (\\d)\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
- mm_serial_port_add_unsolicited_msg_handler (MM_SERIAL_PORT (port), regex, mbm_e2nap_received, modem, NULL);
+ mm_at_serial_port_add_unsolicited_msg_handler (MM_AT_SERIAL_PORT (port), regex, mbm_e2nap_received, modem, NULL);
g_regex_unref (regex);
}
regex = g_regex_new ("\\r\\n\\*EMRDY: \\d\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
- mm_serial_port_add_unsolicited_msg_handler (MM_SERIAL_PORT (port), regex, mbm_emrdy_received, modem, NULL);
+ mm_at_serial_port_add_unsolicited_msg_handler (MM_AT_SERIAL_PORT (port), regex, mbm_emrdy_received, modem, NULL);
g_regex_unref (regex);
regex = g_regex_new ("\\r\\n\\+PACSP(\\d)\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
- mm_serial_port_add_unsolicited_msg_handler (MM_SERIAL_PORT (port), regex, mbm_pacsp_received, modem, NULL);
+ mm_at_serial_port_add_unsolicited_msg_handler (MM_AT_SERIAL_PORT (port), regex, mbm_pacsp_received, modem, NULL);
g_regex_unref (regex);
regex = g_regex_new ("\\r\\n\\+CIEV: (\\d),(\\d)\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
- mm_serial_port_add_unsolicited_msg_handler (MM_SERIAL_PORT (port), regex, mbm_ciev_received, modem, NULL);
+ mm_at_serial_port_add_unsolicited_msg_handler (MM_AT_SERIAL_PORT (port), regex, mbm_ciev_received, modem, NULL);
g_regex_unref (regex);
/* also consume unsolicited mbm messages we are not interested in them - see LP: #416418 */
regex = g_regex_new ("\\R\\*ESTKSMENU:.*\\R", G_REGEX_RAW | G_REGEX_OPTIMIZE | G_REGEX_MULTILINE | G_REGEX_NEWLINE_CRLF, G_REGEX_MATCH_NEWLINE_CRLF, NULL);
- mm_serial_port_add_unsolicited_msg_handler (MM_SERIAL_PORT (port), regex, NULL, NULL, NULL);
+ mm_at_serial_port_add_unsolicited_msg_handler (MM_AT_SERIAL_PORT (port), regex, NULL, NULL, NULL);
g_regex_unref (regex);
regex = g_regex_new ("\\r\\n\\*EMWI: (\\d),(\\d).*\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
- mm_serial_port_add_unsolicited_msg_handler (MM_SERIAL_PORT (port), regex, NULL, NULL, NULL);
+ mm_at_serial_port_add_unsolicited_msg_handler (MM_AT_SERIAL_PORT (port), regex, NULL, NULL, NULL);
g_regex_unref (regex);
regex = g_regex_new ("\\r\\n\\*ERINFO:\\s*(\\d),(\\d),(\\d).*\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
- mm_serial_port_add_unsolicited_msg_handler (MM_SERIAL_PORT (port), regex, mbm_erinfo_received, modem, NULL);
+ mm_at_serial_port_add_unsolicited_msg_handler (MM_AT_SERIAL_PORT (port), regex, mbm_erinfo_received, modem, NULL);
g_regex_unref (regex);
}
diff --git a/plugins/mm-modem-nokia.c b/plugins/mm-modem-nokia.c
index 677a089d..eb90287a 100644
--- a/plugins/mm-modem-nokia.c
+++ b/plugins/mm-modem-nokia.c
@@ -56,19 +56,19 @@ grab_port (MMModem *modem,
MMPort *port = NULL;
if (suggested_type == MM_PORT_TYPE_UNKNOWN) {
- if (!mm_generic_gsm_get_port (gsm, MM_PORT_TYPE_PRIMARY))
+ if (!mm_generic_gsm_get_at_port (gsm, MM_PORT_TYPE_PRIMARY))
ptype = MM_PORT_TYPE_PRIMARY;
- else if (!mm_generic_gsm_get_port (gsm, MM_PORT_TYPE_SECONDARY))
+ else if (!mm_generic_gsm_get_at_port (gsm, MM_PORT_TYPE_SECONDARY))
ptype = MM_PORT_TYPE_SECONDARY;
} else
ptype = suggested_type;
port = mm_generic_gsm_grab_port (gsm, subsys, name, ptype, error);
- if (port && MM_IS_SERIAL_PORT (port)) {
- mm_serial_port_set_response_parser (MM_SERIAL_PORT (port),
- mm_serial_parser_v1_e1_parse,
- mm_serial_parser_v1_e1_new (),
- mm_serial_parser_v1_e1_destroy);
+ if (port && MM_IS_AT_SERIAL_PORT (port)) {
+ mm_at_serial_port_set_response_parser (MM_AT_SERIAL_PORT (port),
+ mm_serial_parser_v1_e1_parse,
+ mm_serial_parser_v1_e1_new (),
+ mm_serial_parser_v1_e1_destroy);
}
return !!port;
diff --git a/plugins/mm-modem-novatel-gsm.c b/plugins/mm-modem-novatel-gsm.c
index c8c28d1f..72c929d3 100644
--- a/plugins/mm-modem-novatel-gsm.c
+++ b/plugins/mm-modem-novatel-gsm.c
@@ -49,26 +49,26 @@ mm_modem_novatel_gsm_new (const char *device,
/*****************************************************************************/
static void
-dmat_callback2 (MMSerialPort *port,
+dmat_callback2 (MMAtSerialPort *port,
GString *response,
GError *error,
gpointer user_data)
{
- mm_serial_port_close (port);
+ mm_serial_port_close (MM_SERIAL_PORT (port));
}
static void
-dmat_callback (MMSerialPort *port,
+dmat_callback (MMAtSerialPort *port,
GString *response,
GError *error,
gpointer user_data)
{
if (error) {
/* Try it again */
- if (mm_serial_port_open (port, NULL))
- mm_serial_port_queue_command (port, "$NWDMAT=1", 2, dmat_callback2, NULL);
+ if (mm_serial_port_open (MM_SERIAL_PORT (port), NULL))
+ mm_at_serial_port_queue_command (port, "$NWDMAT=1", 2, dmat_callback2, NULL);
} else
- mm_serial_port_close (port);
+ mm_serial_port_close (MM_SERIAL_PORT (port));
}
static gboolean
@@ -84,18 +84,18 @@ grab_port (MMModem *modem,
MMPort *port = NULL;
if (suggested_type == MM_PORT_TYPE_UNKNOWN) {
- if (!mm_generic_gsm_get_port (gsm, MM_PORT_TYPE_PRIMARY))
+ if (!mm_generic_gsm_get_at_port (gsm, MM_PORT_TYPE_PRIMARY))
ptype = MM_PORT_TYPE_PRIMARY;
- else if (!mm_generic_gsm_get_port (gsm, MM_PORT_TYPE_SECONDARY))
+ else if (!mm_generic_gsm_get_at_port (gsm, MM_PORT_TYPE_SECONDARY))
ptype = MM_PORT_TYPE_SECONDARY;
} else
ptype = suggested_type;
port = mm_generic_gsm_grab_port (gsm, subsys, name, ptype, error);
- if (port && MM_IS_SERIAL_PORT (port) && (ptype == MM_PORT_TYPE_PRIMARY)) {
+ if (port && MM_IS_AT_SERIAL_PORT (port) && (ptype == MM_PORT_TYPE_PRIMARY)) {
/* Flip secondary ports to AT mode */
if (mm_serial_port_open (MM_SERIAL_PORT (port), NULL))
- mm_serial_port_queue_command (MM_SERIAL_PORT (port), "$NWDMAT=1", 2, dmat_callback, NULL);
+ mm_at_serial_port_queue_command (MM_AT_SERIAL_PORT (port), "$NWDMAT=1", 2, dmat_callback, NULL);
}
return !!port;
diff --git a/plugins/mm-modem-option.c b/plugins/mm-modem-option.c
index a7faf4d3..42cd927c 100644
--- a/plugins/mm-modem-option.c
+++ b/plugins/mm-modem-option.c
@@ -87,7 +87,7 @@ real_do_enable_power_up_done (MMGenericGsm *gsm,
}
static void
-get_allowed_mode_done (MMSerialPort *port,
+get_allowed_mode_done (MMAtSerialPort *port,
GString *response,
GError *error,
gpointer user_data)
@@ -138,16 +138,16 @@ get_allowed_mode (MMGenericGsm *gsm,
gpointer user_data)
{
MMCallbackInfo *info;
- MMSerialPort *primary;
+ MMAtSerialPort *primary;
info = mm_callback_info_uint_new (MM_MODEM (gsm), callback, user_data);
- primary = mm_generic_gsm_get_port (gsm, MM_PORT_TYPE_PRIMARY);
+ primary = mm_generic_gsm_get_at_port (gsm, MM_PORT_TYPE_PRIMARY);
g_assert (primary);
- mm_serial_port_queue_command (primary, "AT_OPSYS?", 3, get_allowed_mode_done, info);
+ mm_at_serial_port_queue_command (primary, "AT_OPSYS?", 3, get_allowed_mode_done, info);
}
static void
-set_allowed_mode_done (MMSerialPort *port,
+set_allowed_mode_done (MMAtSerialPort *port,
GString *response,
GError *error,
gpointer user_data)
@@ -167,7 +167,7 @@ set_allowed_mode (MMGenericGsm *gsm,
gpointer user_data)
{
MMCallbackInfo *info;
- MMSerialPort *primary;
+ MMAtSerialPort *primary;
char *command;
int i;
@@ -193,9 +193,9 @@ set_allowed_mode (MMGenericGsm *gsm,
}
command = g_strdup_printf ("AT_OPSYS=%d,2", i);
- primary = mm_generic_gsm_get_port (gsm, MM_PORT_TYPE_PRIMARY);
+ primary = mm_generic_gsm_get_at_port (gsm, MM_PORT_TYPE_PRIMARY);
g_assert (primary);
- mm_serial_port_queue_command (primary, command, 3, set_allowed_mode_done, info);
+ mm_at_serial_port_queue_command (primary, command, 3, set_allowed_mode_done, info);
g_free (command);
}
diff --git a/plugins/mm-modem-sierra-cdma.c b/plugins/mm-modem-sierra-cdma.c
index 4f3140b7..f2fb4e09 100644
--- a/plugins/mm-modem-sierra-cdma.c
+++ b/plugins/mm-modem-sierra-cdma.c
@@ -110,7 +110,7 @@ sys_mode_has_service (SysMode mode)
}
static void
-status_done (MMSerialPort *port,
+status_done (MMAtSerialPort *port,
GString *response,
GError *error,
gpointer user_data)
@@ -293,11 +293,11 @@ query_registration_state (MMGenericCdma *cdma,
gpointer user_data)
{
MMCallbackInfo *info;
- MMSerialPort *primary, *secondary;
- MMSerialPort *port;
+ MMAtSerialPort *primary, *secondary;
+ MMAtSerialPort *port;
- port = primary = mm_generic_cdma_get_port (cdma, MM_PORT_TYPE_PRIMARY);
- secondary = mm_generic_cdma_get_port (cdma, MM_PORT_TYPE_SECONDARY);
+ port = primary = mm_generic_cdma_get_at_port (cdma, MM_PORT_TYPE_PRIMARY);
+ secondary = mm_generic_cdma_get_at_port (cdma, MM_PORT_TYPE_SECONDARY);
info = mm_generic_cdma_query_reg_state_callback_info_new (cdma, callback, user_data);
@@ -313,11 +313,11 @@ query_registration_state (MMGenericCdma *cdma,
port = secondary;
}
- mm_serial_port_queue_command (port, "!STATUS", 3, status_done, info);
+ mm_at_serial_port_queue_command (port, "!STATUS", 3, status_done, info);
}
static void
-pcstate_done (MMSerialPort *port,
+pcstate_done (MMAtSerialPort *port,
GString *response,
GError *error,
gpointer user_data)
@@ -334,14 +334,14 @@ post_enable (MMGenericCdma *cdma,
gpointer user_data)
{
MMCallbackInfo *info;
- MMSerialPort *primary;
+ MMAtSerialPort *primary;
info = mm_callback_info_new (MM_MODEM (cdma), callback, user_data);
- primary = mm_generic_cdma_get_port (cdma, MM_PORT_TYPE_PRIMARY);
+ primary = mm_generic_cdma_get_at_port (cdma, MM_PORT_TYPE_PRIMARY);
g_assert (primary);
- mm_serial_port_queue_command (primary, "!pcstate=1", 5, pcstate_done, info);
+ mm_at_serial_port_queue_command (primary, "!pcstate=1", 5, pcstate_done, info);
}
static void
@@ -350,14 +350,14 @@ post_disable (MMGenericCdma *cdma,
gpointer user_data)
{
MMCallbackInfo *info;
- MMSerialPort *primary;
+ MMAtSerialPort *primary;
info = mm_callback_info_new (MM_MODEM (cdma), callback, user_data);
- primary = mm_generic_cdma_get_port (cdma, MM_PORT_TYPE_PRIMARY);
+ primary = mm_generic_cdma_get_at_port (cdma, MM_PORT_TYPE_PRIMARY);
g_assert (primary);
- mm_serial_port_queue_command (primary, "!pcstate=0", 5, pcstate_done, info);
+ mm_at_serial_port_queue_command (primary, "!pcstate=0", 5, pcstate_done, info);
}
/*****************************************************************************/
diff --git a/plugins/mm-modem-sierra-gsm.c b/plugins/mm-modem-sierra-gsm.c
index ce4bca6d..02be144f 100644
--- a/plugins/mm-modem-sierra-gsm.c
+++ b/plugins/mm-modem-sierra-gsm.c
@@ -104,22 +104,22 @@ grab_port (MMModem *modem,
MMPort *port;
if (suggested_type == MM_PORT_TYPE_UNKNOWN) {
- if (!mm_generic_gsm_get_port (gsm, MM_PORT_TYPE_PRIMARY))
+ if (!mm_generic_gsm_get_at_port (gsm, MM_PORT_TYPE_PRIMARY))
ptype = MM_PORT_TYPE_PRIMARY;
- else if (!mm_generic_gsm_get_port (gsm, MM_PORT_TYPE_SECONDARY))
+ else if (!mm_generic_gsm_get_at_port (gsm, MM_PORT_TYPE_SECONDARY))
ptype = MM_PORT_TYPE_SECONDARY;
} else
ptype = suggested_type;
port = mm_generic_gsm_grab_port (gsm, subsys, name, ptype, error);
- if (port && MM_IS_SERIAL_PORT (port)) {
+ if (port && MM_IS_AT_SERIAL_PORT (port)) {
GRegex *regex;
g_object_set (G_OBJECT (port), MM_PORT_CARRIER_DETECT, FALSE, NULL);
regex = g_regex_new ("\\r\\n\\+PACSP0\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
- mm_serial_port_add_unsolicited_msg_handler (MM_SERIAL_PORT (port), regex, NULL, NULL, NULL);
+ mm_at_serial_port_add_unsolicited_msg_handler (MM_AT_SERIAL_PORT (port), regex, NULL, NULL, NULL);
g_regex_unref (regex);
}
diff --git a/plugins/mm-modem-zte.c b/plugins/mm-modem-zte.c
index cb5f8054..a4abe47b 100644
--- a/plugins/mm-modem-zte.c
+++ b/plugins/mm-modem-zte.c
@@ -53,7 +53,7 @@ mm_modem_zte_new (const char *device,
}
static void
-zte_access_tech_changed (MMSerialPort *port,
+zte_access_tech_changed (MMAtSerialPort *port,
GMatchInfo *info,
gpointer user_data)
{
@@ -89,7 +89,7 @@ zte_access_tech_changed (MMSerialPort *port,
/* Modem class override functions */
/*****************************************************************************/
-static void cpms_try_done (MMSerialPort *port,
+static void cpms_try_done (MMAtSerialPort *port,
GString *response,
GError *error,
gpointer user_data);
@@ -100,17 +100,17 @@ cpms_timeout_cb (gpointer user_data)
MMCallbackInfo *info = user_data;
MMModem *modem = info->modem;
MMModemZtePrivate *priv = MM_MODEM_ZTE_GET_PRIVATE (modem);
- MMSerialPort *primary;
+ MMAtSerialPort *primary;
priv->cpms_timeout = 0;
- primary = mm_generic_gsm_get_port (MM_GENERIC_GSM (modem), MM_PORT_TYPE_PRIMARY);
- mm_serial_port_queue_command (primary, "+CPMS?", 10, cpms_try_done, info);
+ primary = mm_generic_gsm_get_at_port (MM_GENERIC_GSM (modem), MM_PORT_TYPE_PRIMARY);
+ mm_at_serial_port_queue_command (primary, "+CPMS?", 10, cpms_try_done, info);
return FALSE;
}
static void
-cpms_try_done (MMSerialPort *port,
+cpms_try_done (MMAtSerialPort *port,
GString *response,
GError *error,
gpointer user_data)
@@ -136,7 +136,7 @@ cpms_try_done (MMSerialPort *port,
}
static void
-init_modem_done (MMSerialPort *port,
+init_modem_done (MMAtSerialPort *port,
GString *response,
GError *error,
gpointer user_data)
@@ -148,7 +148,7 @@ init_modem_done (MMSerialPort *port,
* done during probing, but if the device has a PIN enabled it won't
* accept the +CPMS? during the probe and we have to do it here.
*/
- mm_serial_port_queue_command (port, "+CPMS?", 10, cpms_try_done, info);
+ mm_at_serial_port_queue_command (port, "+CPMS?", 10, cpms_try_done, info);
}
static void enable_flash_done (MMSerialPort *port,
@@ -156,7 +156,7 @@ static void enable_flash_done (MMSerialPort *port,
gpointer user_data);
static void
-pre_init_done (MMSerialPort *port,
+pre_init_done (MMAtSerialPort *port,
GString *response,
GError *error,
gpointer user_data)
@@ -169,12 +169,12 @@ pre_init_done (MMSerialPort *port,
if ( !priv->init_retried
&& g_error_matches (error, MM_SERIAL_ERROR, MM_SERIAL_RESPONSE_TIMEOUT)) {
priv->init_retried = TRUE;
- enable_flash_done (port, NULL, user_data);
+ enable_flash_done (MM_SERIAL_PORT (port), NULL, user_data);
} else
mm_generic_gsm_enable_complete (MM_GENERIC_GSM (info->modem), error, info);
} else {
/* Finish the initialization */
- mm_serial_port_queue_command (port, "Z E0 V1 X4 &C1 +CMEE=1;+CFUN=1;", 10, init_modem_done, info);
+ mm_at_serial_port_queue_command (port, "Z E0 V1 X4 &C1 +CMEE=1;+CFUN=1;", 10, init_modem_done, info);
}
}
@@ -186,7 +186,7 @@ enable_flash_done (MMSerialPort *port, GError *error, gpointer user_data)
if (error)
mm_generic_gsm_enable_complete (MM_GENERIC_GSM (info->modem), error, info);
else
- mm_serial_port_queue_command (port, "E0 V1", 3, pre_init_done, user_data);
+ mm_at_serial_port_queue_command (MM_AT_SERIAL_PORT (port), "E0 V1", 3, pre_init_done, user_data);
}
static void
@@ -194,15 +194,15 @@ do_enable (MMGenericGsm *modem, MMModemFn callback, gpointer user_data)
{
MMModemZtePrivate *priv = MM_MODEM_ZTE_GET_PRIVATE (modem);
MMCallbackInfo *info;
- MMSerialPort *primary;
+ MMAtSerialPort *primary;
priv->init_retried = FALSE;
- primary = mm_generic_gsm_get_port (modem, MM_PORT_TYPE_PRIMARY);
+ primary = mm_generic_gsm_get_at_port (modem, MM_PORT_TYPE_PRIMARY);
g_assert (primary);
info = mm_callback_info_new (MM_MODEM (modem), callback, user_data);
- mm_serial_port_flash (primary, 100, enable_flash_done, info);
+ mm_serial_port_flash (MM_SERIAL_PORT (primary), 100, enable_flash_done, info);
}
static void
@@ -233,41 +233,41 @@ grab_port (MMModem *modem,
MMPort *port = NULL;
if (suggested_type == MM_PORT_TYPE_UNKNOWN) {
- if (!mm_generic_gsm_get_port (gsm, MM_PORT_TYPE_PRIMARY))
+ if (!mm_generic_gsm_get_at_port (gsm, MM_PORT_TYPE_PRIMARY))
ptype = MM_PORT_TYPE_PRIMARY;
- else if (!mm_generic_gsm_get_port (gsm, MM_PORT_TYPE_SECONDARY))
+ else if (!mm_generic_gsm_get_at_port (gsm, MM_PORT_TYPE_SECONDARY))
ptype = MM_PORT_TYPE_SECONDARY;
} else
ptype = suggested_type;
port = mm_generic_gsm_grab_port (gsm, subsys, name, ptype, error);
- if (port && MM_IS_SERIAL_PORT (port)) {
+ if (port && MM_IS_AT_SERIAL_PORT (port)) {
GRegex *regex;
g_object_set (port, MM_PORT_CARRIER_DETECT, FALSE, NULL);
regex = g_regex_new ("\\r\\n\\+ZUSIMR:(.*)\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
- mm_serial_port_add_unsolicited_msg_handler (MM_SERIAL_PORT (port), regex, NULL, NULL, NULL);
+ mm_at_serial_port_add_unsolicited_msg_handler (MM_AT_SERIAL_PORT (port), regex, NULL, NULL, NULL);
g_regex_unref (regex);
/* Unsolicted operator display */
regex = g_regex_new ("\\r\\n\\+ZDONR: (.*)\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
- mm_serial_port_add_unsolicited_msg_handler (MM_SERIAL_PORT (port), regex, NULL, NULL, NULL);
+ mm_at_serial_port_add_unsolicited_msg_handler (MM_AT_SERIAL_PORT (port), regex, NULL, NULL, NULL);
g_regex_unref (regex);
/* Current network and service domain */
regex = g_regex_new ("\\r\\n\\+ZPASR:\\s*(.*)\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
- mm_serial_port_add_unsolicited_msg_handler (MM_SERIAL_PORT (port), regex, zte_access_tech_changed, modem, NULL);
+ mm_at_serial_port_add_unsolicited_msg_handler (MM_AT_SERIAL_PORT (port), regex, zte_access_tech_changed, modem, NULL);
g_regex_unref (regex);
/* SIM request to Build Main Menu */
regex = g_regex_new ("\\r\\n\\+ZPSTM: (.*)\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
- mm_serial_port_add_unsolicited_msg_handler (MM_SERIAL_PORT (port), regex, NULL, NULL, NULL);
+ mm_at_serial_port_add_unsolicited_msg_handler (MM_AT_SERIAL_PORT (port), regex, NULL, NULL, NULL);
g_regex_unref (regex);
/* SIM request to Rebuild Main Menu */
regex = g_regex_new ("\\r\\n\\+ZEND\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
- mm_serial_port_add_unsolicited_msg_handler (MM_SERIAL_PORT (port), regex, NULL, NULL, NULL);
+ mm_at_serial_port_add_unsolicited_msg_handler (MM_AT_SERIAL_PORT (port), regex, NULL, NULL, NULL);
g_regex_unref (regex);
}
diff --git a/plugins/mm-plugin-huawei.c b/plugins/mm-plugin-huawei.c
index 96edc086..bee7d40f 100644
--- a/plugins/mm-plugin-huawei.c
+++ b/plugins/mm-plugin-huawei.c
@@ -26,6 +26,7 @@
#include "mm-modem-huawei-gsm.h"
#include "mm-modem-huawei-cdma.h"
#include "mm-serial-parsers.h"
+#include "mm-at-serial-port.h"
G_DEFINE_TYPE (MMPluginHuawei, mm_plugin_huawei, MM_TYPE_PLUGIN_BASE)
@@ -69,7 +70,7 @@ probe_result (MMPluginBase *base,
#define TAG_SUPPORTS_INFO "huawei-supports-info"
typedef struct {
- MMSerialPort *serial;
+ MMAtSerialPort *serial;
guint id;
gboolean secondary;
} HuaweiSupportsInfo;
@@ -106,7 +107,7 @@ probe_secondary_supported (gpointer user_data)
}
static void
-probe_secondary_handle_msg (MMSerialPort *port,
+probe_secondary_handle_msg (MMAtSerialPort *port,
GMatchInfo *match_info,
gpointer user_data)
{
@@ -135,12 +136,12 @@ probe_secondary_timeout (gpointer user_data)
}
static void
-add_regex (MMSerialPort *port, const char *match, gpointer user_data)
+add_regex (MMAtSerialPort *port, const char *match, gpointer user_data)
{
GRegex *regex;
regex = g_regex_new (match, G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
- mm_serial_port_add_unsolicited_msg_handler (port, regex, probe_secondary_handle_msg, user_data, NULL);
+ mm_at_serial_port_add_unsolicited_msg_handler (port, regex, probe_secondary_handle_msg, user_data, NULL);
g_regex_unref (regex);
}
@@ -208,13 +209,13 @@ supports_port (MMPluginBase *base,
/* Listen for Huawei-specific unsolicited messages */
info = g_malloc0 (sizeof (HuaweiSupportsInfo));
- info->serial = mm_serial_port_new (name, MM_PORT_TYPE_PRIMARY);
+ info->serial = mm_at_serial_port_new (name, MM_PORT_TYPE_PRIMARY);
g_object_set (G_OBJECT (info->serial), MM_PORT_CARRIER_DETECT, FALSE, NULL);
- mm_serial_port_set_response_parser (info->serial,
- mm_serial_parser_v1_parse,
- mm_serial_parser_v1_new (),
- mm_serial_parser_v1_destroy);
+ mm_at_serial_port_set_response_parser (info->serial,
+ mm_serial_parser_v1_parse,
+ mm_serial_parser_v1_new (),
+ mm_serial_parser_v1_destroy);
add_regex (info->serial, "\\r\\n\\^RSSI:(\\d+)\\r\\n", task);
add_regex (info->serial, "\\r\\n\\^MODE:(\\d),(\\d)\\r\\n", task);
@@ -227,7 +228,7 @@ supports_port (MMPluginBase *base,
g_object_set_data_full (G_OBJECT (task), TAG_SUPPORTS_INFO,
info, huawei_supports_info_destroy);
- if (!mm_serial_port_open (info->serial, &error)) {
+ if (!mm_serial_port_open (MM_SERIAL_PORT (info->serial), &error)) {
g_warning ("%s: (Huawei) %s: couldn't open serial port: (%d) %s",
__func__, name,
error ? error->code : -1,
diff --git a/src/Makefile.am b/src/Makefile.am
index a695f374..3d938063 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)\"
@@ -27,6 +28,7 @@ modem_manager_LDADD = \
$(MM_LIBS) \
$(GUDEV_LIBS) \
$(top_builddir)/marshallers/libmarshallers.la \
+ $(top_builddir)/libqcdm/src/libqcdm.la \
$(builddir)/libmodem-helpers.la
if WITH_POLKIT
@@ -59,12 +61,16 @@ modem_manager_SOURCES = \
mm-modem.h \
mm-port.c \
mm-port.h \
- mm-modem-base.c \
- mm-modem-base.h \
mm-serial-port.c \
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 \
+ mm-modem-base.h \
mm-generic-cdma.c \
mm-generic-cdma.h \
mm-generic-gsm.c \
diff --git a/src/mm-at-serial-port.c b/src/mm-at-serial-port.c
new file mode 100644
index 00000000..40fbd448
--- /dev/null
+++ b/src/mm-at-serial-port.c
@@ -0,0 +1,324 @@
+/* -*- 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 Red Hat, Inc.
+ */
+
+#define _GNU_SOURCE /* for strcasestr() */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+#include "mm-at-serial-port.h"
+#include "mm-errors.h"
+#include "mm-options.h"
+
+G_DEFINE_TYPE (MMAtSerialPort, mm_at_serial_port, MM_TYPE_SERIAL_PORT)
+
+#define MM_AT_SERIAL_PORT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), MM_TYPE_AT_SERIAL_PORT, MMAtSerialPortPrivate))
+
+typedef struct {
+ /* Response parser data */
+ MMAtSerialResponseParserFn response_parser_fn;
+ gpointer response_parser_user_data;
+ GDestroyNotify response_parser_notify;
+ GSList *unsolicited_msg_handlers;
+} MMAtSerialPortPrivate;
+
+
+/*****************************************************************************/
+
+void
+mm_at_serial_port_set_response_parser (MMAtSerialPort *self,
+ MMAtSerialResponseParserFn fn,
+ gpointer user_data,
+ GDestroyNotify notify)
+{
+ MMAtSerialPortPrivate *priv = MM_AT_SERIAL_PORT_GET_PRIVATE (self);
+
+ g_return_if_fail (MM_IS_AT_SERIAL_PORT (self));
+
+ if (priv->response_parser_notify)
+ priv->response_parser_notify (priv->response_parser_user_data);
+
+ priv->response_parser_fn = fn;
+ priv->response_parser_user_data = user_data;
+ priv->response_parser_notify = notify;
+}
+
+static gboolean
+parse_response (MMSerialPort *port, GByteArray *response, GError **error)
+{
+ MMAtSerialPort *self = MM_AT_SERIAL_PORT (port);
+ MMAtSerialPortPrivate *priv = MM_AT_SERIAL_PORT_GET_PRIVATE (self);
+ gboolean found;
+ GString *string;
+
+ g_return_val_if_fail (priv->response_parser_fn != NULL, FALSE);
+
+ /* Construct the string that AT-parsing functions expect */
+ string = g_string_sized_new (response->len + 1);
+ g_string_append_len (string, (const char *) response->data, response->len);
+
+ /* Parse it */
+ found = priv->response_parser_fn (priv->response_parser_user_data, string, error);
+
+ /* And copy it back into the response array after the parser has removed
+ * matches and cleaned it up.
+ */
+ if (response->len)
+ g_byte_array_remove_range (response, 0, response->len);
+ g_byte_array_append (response, (const guint8 *) string->str, string->len);
+ g_string_free (string, TRUE);
+ return found;
+}
+
+static void
+handle_response (MMSerialPort *port,
+ GByteArray *response,
+ GError *error,
+ GCallback callback,
+ gpointer callback_data)
+{
+ MMAtSerialPort *self = MM_AT_SERIAL_PORT (port);
+ MMAtSerialResponseFn response_callback = (MMAtSerialResponseFn) callback;
+ GString *string;
+
+ /* Convert to a string and call the callback */
+ string = g_string_sized_new (response->len + 1);
+ g_string_append_len (string, (const char *) response->data, response->len);
+ response_callback (self, string, error, callback_data);
+ g_string_free (string, TRUE);
+}
+
+/*****************************************************************************/
+
+typedef struct {
+ GRegex *regex;
+ MMAtSerialUnsolicitedMsgFn callback;
+ gpointer user_data;
+ GDestroyNotify notify;
+} MMAtUnsolicitedMsgHandler;
+
+void
+mm_at_serial_port_add_unsolicited_msg_handler (MMAtSerialPort *self,
+ GRegex *regex,
+ MMAtSerialUnsolicitedMsgFn callback,
+ gpointer user_data,
+ GDestroyNotify notify)
+{
+ MMAtUnsolicitedMsgHandler *handler;
+ MMAtSerialPortPrivate *priv;
+
+ g_return_if_fail (MM_IS_AT_SERIAL_PORT (self));
+ g_return_if_fail (regex != NULL);
+
+ handler = g_slice_new (MMAtUnsolicitedMsgHandler);
+ handler->regex = g_regex_ref (regex);
+ handler->callback = callback;
+ handler->user_data = user_data;
+ handler->notify = notify;
+
+ priv = MM_AT_SERIAL_PORT_GET_PRIVATE (self);
+ priv->unsolicited_msg_handlers = g_slist_append (priv->unsolicited_msg_handlers, handler);
+}
+
+static gboolean
+remove_eval_cb (const GMatchInfo *match_info,
+ GString *result,
+ gpointer user_data)
+{
+ int *result_len = (int *) user_data;
+ int start;
+ int end;
+
+ if (g_match_info_fetch_pos (match_info, 0, &start, &end))
+ *result_len -= (end - start);
+
+ return FALSE;
+}
+
+static void
+parse_unsolicited (MMSerialPort *port, GByteArray *response)
+{
+ MMAtSerialPort *self = MM_AT_SERIAL_PORT (port);
+ MMAtSerialPortPrivate *priv = MM_AT_SERIAL_PORT_GET_PRIVATE (self);
+ GSList *iter;
+
+ for (iter = priv->unsolicited_msg_handlers; iter; iter = iter->next) {
+ MMAtUnsolicitedMsgHandler *handler = (MMAtUnsolicitedMsgHandler *) iter->data;
+ GMatchInfo *match_info;
+ gboolean matches;
+
+ matches = g_regex_match_full (handler->regex,
+ (const char *) response->data,
+ response->len,
+ 0, 0, &match_info, NULL);
+ if (handler->callback) {
+ while (g_match_info_matches (match_info)) {
+ handler->callback (self, match_info, handler->user_data);
+ g_match_info_next (match_info, NULL);
+ }
+ }
+
+ g_match_info_free (match_info);
+
+ if (matches) {
+ /* Remove matches */
+ char *str;
+ int result_len = response->len;
+
+ str = g_regex_replace_eval (handler->regex,
+ (const char *) response->data,
+ response->len,
+ 0, 0,
+ remove_eval_cb, &result_len, NULL);
+
+ g_byte_array_remove_range (response, 0, response->len);
+ g_byte_array_append (response, (const guint8 *) str, result_len);
+ g_free (str);
+ }
+ }
+}
+
+/*****************************************************************************/
+
+static GByteArray *
+at_command_to_byte_array (const char *command)
+{
+ GByteArray *buf;
+ int cmdlen;
+
+ g_return_val_if_fail (command != NULL, NULL);
+
+ cmdlen = strlen (command);
+ buf = g_byte_array_sized_new (cmdlen + 3);
+
+ /* Make sure there's an AT in the front */
+ if (!g_str_has_prefix (command, "AT"))
+ g_byte_array_append (buf, (const guint8 *) "AT", 2);
+ g_byte_array_append (buf, (const guint8 *) command, cmdlen);
+
+ /* Make sure there's a trailing carriage return */
+ if (command[cmdlen] != '\r')
+ g_byte_array_append (buf, (const guint8 *) "\r", 1);
+
+ return buf;
+}
+
+void
+mm_at_serial_port_queue_command (MMAtSerialPort *self,
+ const char *command,
+ guint32 timeout_seconds,
+ MMAtSerialResponseFn callback,
+ gpointer user_data)
+{
+ GByteArray *buf;
+
+ 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);
+ g_return_if_fail (buf != NULL);
+
+ mm_serial_port_queue_command (MM_SERIAL_PORT (self),
+ buf,
+ TRUE,
+ timeout_seconds,
+ G_CALLBACK (callback),
+ user_data);
+}
+
+void
+mm_at_serial_port_queue_command_cached (MMAtSerialPort *self,
+ const char *command,
+ guint32 timeout_seconds,
+ MMAtSerialResponseFn callback,
+ gpointer user_data)
+{
+ GByteArray *buf;
+
+ 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);
+ g_return_if_fail (buf != NULL);
+
+ mm_serial_port_queue_command_cached (MM_SERIAL_PORT (self),
+ buf,
+ TRUE,
+ timeout_seconds,
+ G_CALLBACK (callback),
+ user_data);
+}
+
+/*****************************************************************************/
+
+MMAtSerialPort *
+mm_at_serial_port_new (const char *name, MMPortType ptype)
+{
+ return MM_AT_SERIAL_PORT (g_object_new (MM_TYPE_AT_SERIAL_PORT,
+ MM_PORT_DEVICE, name,
+ MM_PORT_SUBSYS, MM_PORT_SUBSYS_TTY,
+ MM_PORT_TYPE, ptype,
+ NULL));
+}
+
+static void
+mm_at_serial_port_init (MMAtSerialPort *self)
+{
+}
+
+static void
+finalize (GObject *object)
+{
+ MMAtSerialPort *self = MM_AT_SERIAL_PORT (object);
+ MMAtSerialPortPrivate *priv = MM_AT_SERIAL_PORT_GET_PRIVATE (self);
+
+ while (priv->unsolicited_msg_handlers) {
+ MMAtUnsolicitedMsgHandler *handler = (MMAtUnsolicitedMsgHandler *) priv->unsolicited_msg_handlers->data;
+
+ if (handler->notify)
+ handler->notify (handler->user_data);
+
+ g_regex_unref (handler->regex);
+ g_slice_free (MMAtUnsolicitedMsgHandler, handler);
+ priv->unsolicited_msg_handlers = g_slist_delete_link (priv->unsolicited_msg_handlers,
+ priv->unsolicited_msg_handlers);
+ }
+
+ if (priv->response_parser_notify)
+ priv->response_parser_notify (priv->response_parser_user_data);
+
+ G_OBJECT_CLASS (mm_at_serial_port_parent_class)->finalize (object);
+}
+
+static void
+mm_at_serial_port_class_init (MMAtSerialPortClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ MMSerialPortClass *port_class = MM_SERIAL_PORT_CLASS (klass);
+
+ g_type_class_add_private (object_class, sizeof (MMAtSerialPortPrivate));
+
+ /* Virtual methods */
+ object_class->finalize = finalize;
+
+ port_class->parse_unsolicited = parse_unsolicited;
+ port_class->parse_response = parse_response;
+ port_class->handle_response = handle_response;
+}
diff --git a/src/mm-at-serial-port.h b/src/mm-at-serial-port.h
new file mode 100644
index 00000000..5d5f13f2
--- /dev/null
+++ b/src/mm-at-serial-port.h
@@ -0,0 +1,85 @@
+/* -*- 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_AT_SERIAL_PORT_H
+#define MM_AT_SERIAL_PORT_H
+
+#include <glib.h>
+#include <glib/gtypes.h>
+#include <glib-object.h>
+
+#include "mm-serial-port.h"
+
+#define MM_TYPE_AT_SERIAL_PORT (mm_at_serial_port_get_type ())
+#define MM_AT_SERIAL_PORT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MM_TYPE_AT_SERIAL_PORT, MMAtSerialPort))
+#define MM_AT_SERIAL_PORT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MM_TYPE_AT_SERIAL_PORT, MMAtSerialPortClass))
+#define MM_IS_AT_SERIAL_PORT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MM_TYPE_AT_SERIAL_PORT))
+#define MM_IS_AT_SERIAL_PORT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MM_TYPE_AT_SERIAL_PORT))
+#define MM_AT_SERIAL_PORT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MM_TYPE_AT_SERIAL_PORT, MMAtSerialPortClass))
+
+typedef struct _MMAtSerialPort MMAtSerialPort;
+typedef struct _MMAtSerialPortClass MMAtSerialPortClass;
+
+typedef gboolean (*MMAtSerialResponseParserFn) (gpointer user_data,
+ GString *response,
+ GError **error);
+
+typedef void (*MMAtSerialUnsolicitedMsgFn) (MMAtSerialPort *port,
+ GMatchInfo *match_info,
+ gpointer user_data);
+
+typedef void (*MMAtSerialResponseFn) (MMAtSerialPort *port,
+ GString *response,
+ GError *error,
+ gpointer user_data);
+
+struct _MMAtSerialPort {
+ MMSerialPort parent;
+};
+
+struct _MMAtSerialPortClass {
+ MMSerialPortClass parent;
+};
+
+GType mm_at_serial_port_get_type (void);
+
+MMAtSerialPort *mm_at_serial_port_new (const char *name, MMPortType ptype);
+
+void mm_at_serial_port_add_unsolicited_msg_handler (MMAtSerialPort *self,
+ GRegex *regex,
+ MMAtSerialUnsolicitedMsgFn callback,
+ gpointer user_data,
+ GDestroyNotify notify);
+
+void mm_at_serial_port_set_response_parser (MMAtSerialPort *self,
+ MMAtSerialResponseParserFn fn,
+ gpointer user_data,
+ GDestroyNotify notify);
+
+void mm_at_serial_port_queue_command (MMAtSerialPort *self,
+ const char *command,
+ guint32 timeout_seconds,
+ MMAtSerialResponseFn callback,
+ gpointer user_data);
+
+void mm_at_serial_port_queue_command_cached (MMAtSerialPort *self,
+ const char *command,
+ guint32 timeout_seconds,
+ MMAtSerialResponseFn callback,
+ gpointer user_data);
+
+#endif /* MM_AT_SERIAL_PORT_H */
+
diff --git a/src/mm-generic-cdma.c b/src/mm-generic-cdma.c
index ff156412..4d558c3e 100644
--- a/src/mm-generic-cdma.c
+++ b/src/mm-generic-cdma.c
@@ -23,7 +23,7 @@
#include "mm-generic-cdma.h"
#include "mm-modem-cdma.h"
#include "mm-modem-simple.h"
-#include "mm-serial-port.h"
+#include "mm-at-serial-port.h"
#include "mm-errors.h"
#include "mm-callback-info.h"
#include "mm-serial-parsers.h"
@@ -67,8 +67,8 @@ typedef struct {
guint reg_state_changed_id;
MMCallbackInfo *simple_connect_info;
- MMSerialPort *primary;
- MMSerialPort *secondary;
+ MMAtSerialPort *primary;
+ MMAtSerialPort *secondary;
MMPort *data;
} MMGenericCdmaPrivate;
@@ -148,22 +148,22 @@ mm_generic_cdma_grab_port (MMGenericCdma *self,
}
port = mm_modem_base_add_port (MM_MODEM_BASE (self), subsys, name, ptype);
- if (port && MM_IS_SERIAL_PORT (port)) {
+ if (port && MM_IS_AT_SERIAL_PORT (port)) {
g_object_set (G_OBJECT (port), MM_PORT_CARRIER_DETECT, FALSE, NULL);
- mm_serial_port_set_response_parser (MM_SERIAL_PORT (port),
- mm_serial_parser_v1_parse,
- mm_serial_parser_v1_new (),
- mm_serial_parser_v1_destroy);
+ mm_at_serial_port_set_response_parser (MM_AT_SERIAL_PORT (port),
+ mm_serial_parser_v1_parse,
+ mm_serial_parser_v1_new (),
+ mm_serial_parser_v1_destroy);
if (ptype == MM_PORT_TYPE_PRIMARY) {
- priv->primary = MM_SERIAL_PORT (port);
+ priv->primary = MM_AT_SERIAL_PORT (port);
if (!priv->data) {
priv->data = port;
g_object_notify (G_OBJECT (self), MM_MODEM_DATA_DEVICE);
}
check_valid (self);
} else if (ptype == MM_PORT_TYPE_SECONDARY)
- priv->secondary = MM_SERIAL_PORT (port);
+ priv->secondary = MM_AT_SERIAL_PORT (port);
} else {
/* Net device (if any) is the preferred data port */
if (!priv->data || MM_IS_SERIAL_PORT (priv->data)) {
@@ -215,9 +215,9 @@ release_port (MMModem *modem, const char *subsys, const char *name)
check_valid (MM_GENERIC_CDMA (modem));
}
-MMSerialPort *
-mm_generic_cdma_get_port (MMGenericCdma *modem,
- MMPortType ptype)
+MMAtSerialPort *
+mm_generic_cdma_get_at_port (MMGenericCdma *modem,
+ MMPortType ptype)
{
g_return_val_if_fail (MM_IS_GENERIC_CDMA (modem), NULL);
g_return_val_if_fail (ptype != MM_PORT_TYPE_UNKNOWN, NULL);
@@ -359,11 +359,11 @@ enable_all_done (MMModem *modem, GError *error, gpointer user_data)
info->error = g_error_copy (error);
else {
/* Try to enable XON/XOFF flow control */
- mm_serial_port_queue_command (priv->primary, "+IFC=1,1", 3, NULL, NULL);
+ mm_at_serial_port_queue_command (priv->primary, "+IFC=1,1", 3, NULL, NULL);
/* Open up the second port, if one exists */
if (priv->secondary) {
- if (!mm_serial_port_open (priv->secondary, &info->error)) {
+ if (!mm_serial_port_open (MM_SERIAL_PORT (priv->secondary), &info->error)) {
g_assert (info->error);
goto out;
}
@@ -383,7 +383,7 @@ out:
}
static void
-enable_error_reporting_done (MMSerialPort *port,
+enable_error_reporting_done (MMAtSerialPort *port,
GString *response,
GError *error,
gpointer user_data)
@@ -402,7 +402,7 @@ enable_error_reporting_done (MMSerialPort *port,
}
static void
-init_done (MMSerialPort *port,
+init_done (MMAtSerialPort *port,
GString *response,
GError *error,
gpointer user_data)
@@ -422,7 +422,7 @@ init_done (MMSerialPort *port,
FIXME: It's mandatory by spec, so it really shouldn't be optional. Figure
out which CDMA modems have problems with it and implement plugin for them.
*/
- mm_serial_port_queue_command (port, "+CMEE=1", 3, enable_error_reporting_done, user_data);
+ mm_at_serial_port_queue_command (port, "+CMEE=1", 3, enable_error_reporting_done, user_data);
}
}
@@ -442,7 +442,7 @@ flash_done (MMSerialPort *port, GError *error, gpointer user_data)
return;
}
- mm_serial_port_queue_command (port, "Z E0 V1 X4 &C1", 3, init_done, user_data);
+ mm_at_serial_port_queue_command (MM_AT_SERIAL_PORT (port), "Z E0 V1 X4 &C1", 3, init_done, user_data);
}
static void
@@ -456,7 +456,7 @@ enable (MMModem *modem,
info = mm_callback_info_new (modem, callback, user_data);
- if (!mm_serial_port_open (priv->primary, &info->error)) {
+ if (!mm_serial_port_open (MM_SERIAL_PORT (priv->primary), &info->error)) {
g_assert (info->error);
mm_callback_info_schedule (info);
return;
@@ -466,7 +466,7 @@ enable (MMModem *modem,
MM_MODEM_STATE_ENABLING,
MM_MODEM_STATE_REASON_NONE);
- mm_serial_port_flash (priv->primary, 100, flash_done, info);
+ mm_serial_port_flash (MM_SERIAL_PORT (priv->primary), 100, flash_done, info);
}
static void
@@ -492,7 +492,7 @@ disable_all_done (MMModem *modem, GError *error, gpointer user_data)
MMGenericCdma *self = MM_GENERIC_CDMA (info->modem);
MMGenericCdmaPrivate *priv = MM_GENERIC_CDMA_GET_PRIVATE (self);
- mm_serial_port_close (priv->primary);
+ mm_serial_port_close (MM_SERIAL_PORT (priv->primary));
mm_modem_set_state (modem, MM_MODEM_STATE_DISABLED, MM_MODEM_STATE_REASON_NONE);
priv->cdma_1x_reg_state = MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN;
@@ -549,20 +549,20 @@ disable (MMModem *modem,
NULL);
if (priv->secondary)
- mm_serial_port_close (priv->secondary);
+ mm_serial_port_close (MM_SERIAL_PORT (priv->secondary));
mm_modem_set_state (MM_MODEM (info->modem),
MM_MODEM_STATE_DISABLING,
MM_MODEM_STATE_REASON_NONE);
if (mm_port_get_connected (MM_PORT (priv->primary)))
- mm_serial_port_flash (priv->primary, 1000, disable_flash_done, info);
+ mm_serial_port_flash (MM_SERIAL_PORT (priv->primary), 1000, disable_flash_done, info);
else
- disable_flash_done (priv->primary, NULL, info);
+ disable_flash_done (MM_SERIAL_PORT (priv->primary), NULL, info);
}
static void
-dial_done (MMSerialPort *port,
+dial_done (MMAtSerialPort *port,
GString *response,
GError *error,
gpointer user_data)
@@ -601,7 +601,7 @@ connect (MMModem *modem,
info = mm_callback_info_new (modem, callback, user_data);
command = g_strconcat ("DT", number, NULL);
- mm_serial_port_queue_command (priv->primary, command, 90, dial_done, info);
+ mm_at_serial_port_queue_command (priv->primary, command, 90, dial_done, info);
g_free (command);
}
@@ -651,7 +651,7 @@ disconnect (MMModem *modem,
NULL);
mm_modem_set_state (modem, MM_MODEM_STATE_DISCONNECTING, MM_MODEM_STATE_REASON_NONE);
- mm_serial_port_flash (priv->primary, 1000, disconnect_flash_done, info);
+ mm_serial_port_flash (MM_SERIAL_PORT (priv->primary), 1000, disconnect_flash_done, info);
}
static void
@@ -681,7 +681,7 @@ strip_response (const char *resp, const char *cmd)
}
static void
-get_version_done (MMSerialPort *port,
+get_version_done (MMAtSerialPort *port,
GString *response,
GError *error,
gpointer user_data)
@@ -699,7 +699,7 @@ get_version_done (MMSerialPort *port,
}
static void
-get_model_done (MMSerialPort *port,
+get_model_done (MMAtSerialPort *port,
GString *response,
GError *error,
gpointer user_data)
@@ -715,7 +715,7 @@ get_model_done (MMSerialPort *port,
}
static void
-get_manufacturer_done (MMSerialPort *port,
+get_manufacturer_done (MMAtSerialPort *port,
GString *response,
GError *error,
gpointer user_data)
@@ -737,7 +737,7 @@ get_card_info (MMModem *modem,
{
MMGenericCdmaPrivate *priv = MM_GENERIC_CDMA_GET_PRIVATE (modem);
MMCallbackInfo *info;
- MMSerialPort *port = priv->primary;
+ MMAtSerialPort *port = priv->primary;
info = mm_callback_info_new_full (MM_MODEM (modem),
card_info_invoke,
@@ -756,9 +756,9 @@ get_card_info (MMModem *modem,
port = priv->secondary;
}
- mm_serial_port_queue_command_cached (port, "+GMI", 3, get_manufacturer_done, info);
- mm_serial_port_queue_command_cached (port, "+GMM", 3, get_model_done, info);
- mm_serial_port_queue_command_cached (port, "+GMR", 3, get_version_done, info);
+ mm_at_serial_port_queue_command_cached (port, "+GMI", 3, get_manufacturer_done, info);
+ mm_at_serial_port_queue_command_cached (port, "+GMM", 3, get_model_done, info);
+ mm_at_serial_port_queue_command_cached (port, "+GMR", 3, get_version_done, info);
}
/*****************************************************************************/
@@ -796,7 +796,7 @@ mm_generic_cdma_update_evdo_quality (MMGenericCdma *self, guint32 quality)
#define CSQ2_TRIED "csq?-tried"
static void
-get_signal_quality_done (MMSerialPort *port,
+get_signal_quality_done (MMAtSerialPort *port,
GString *response,
GError *error,
gpointer user_data)
@@ -814,7 +814,7 @@ get_signal_quality_done (MMSerialPort *port,
* try the other command if the first one fails.
*/
mm_callback_info_set_data (info, CSQ2_TRIED, GUINT_TO_POINTER (1), NULL);
- mm_serial_port_queue_command (port, "+CSQ?", 3, get_signal_quality_done, info);
+ mm_at_serial_port_queue_command (port, "+CSQ?", 3, get_signal_quality_done, info);
return;
}
} else {
@@ -856,7 +856,7 @@ get_signal_quality (MMModemCdma *modem,
{
MMGenericCdmaPrivate *priv = MM_GENERIC_CDMA_GET_PRIVATE (modem);
MMCallbackInfo *info;
- MMSerialPort *port = priv->primary;
+ MMAtSerialPort *port = priv->primary;
if (mm_port_get_connected (MM_PORT (priv->primary))) {
if (!priv->secondary) {
@@ -870,11 +870,11 @@ get_signal_quality (MMModemCdma *modem,
}
info = mm_callback_info_uint_new (MM_MODEM (modem), callback, user_data);
- mm_serial_port_queue_command (port, "+CSQ", 3, get_signal_quality_done, info);
+ mm_at_serial_port_queue_command (port, "+CSQ", 3, get_signal_quality_done, info);
}
static void
-get_string_done (MMSerialPort *port,
+get_string_done (MMAtSerialPort *port,
GString *response,
GError *error,
gpointer user_data)
@@ -900,7 +900,7 @@ get_esn (MMModemCdma *modem,
MMGenericCdmaPrivate *priv = MM_GENERIC_CDMA_GET_PRIVATE (modem);
MMCallbackInfo *info;
GError *error;
- MMSerialPort *port = priv->primary;
+ MMAtSerialPort *port = priv->primary;
if (mm_port_get_connected (MM_PORT (priv->primary))) {
if (!priv->secondary) {
@@ -916,7 +916,7 @@ get_esn (MMModemCdma *modem,
}
info = mm_callback_info_string_new (MM_MODEM (modem), callback, user_data);
- mm_serial_port_queue_command_cached (port, "+GSN", 3, get_string_done, info);
+ mm_at_serial_port_queue_command_cached (port, "+GSN", 3, get_string_done, info);
}
static void
@@ -1000,7 +1000,7 @@ convert_sid (const char *sid)
}
static void
-serving_system_done (MMSerialPort *port,
+serving_system_done (MMAtSerialPort *port,
GString *response,
GError *error,
gpointer user_data)
@@ -1119,7 +1119,7 @@ get_serving_system (MMModemCdma *modem,
MMGenericCdmaPrivate *priv = MM_GENERIC_CDMA_GET_PRIVATE (modem);
MMCallbackInfo *info;
GError *error;
- MMSerialPort *port = priv->primary;
+ MMAtSerialPort *port = priv->primary;
if (mm_port_get_connected (MM_PORT (priv->primary))) {
if (!priv->secondary) {
@@ -1139,7 +1139,7 @@ get_serving_system (MMModemCdma *modem,
G_CALLBACK (callback),
user_data);
- mm_serial_port_queue_command (port, "+CSS?", 3, serving_system_done, info);
+ mm_at_serial_port_queue_command (port, "+CSS?", 3, serving_system_done, info);
}
#define CDMA_1X_STATE_TAG "cdma-1x-reg-state"
@@ -1301,7 +1301,7 @@ reg_state_css_response (MMModemCdma *cdma,
}
static void
-get_analog_digital_done (MMSerialPort *port,
+get_analog_digital_done (MMAtSerialPort *port,
GString *response,
GError *error,
gpointer user_data)
@@ -1368,7 +1368,7 @@ get_registration_state (MMModemCdma *modem,
{
MMGenericCdmaPrivate *priv = MM_GENERIC_CDMA_GET_PRIVATE (modem);
MMCallbackInfo *info;
- MMSerialPort *port = priv->primary;
+ MMAtSerialPort *port = priv->primary;
if (mm_port_get_connected (MM_PORT (priv->primary))) {
if (!priv->secondary) {
@@ -1383,7 +1383,7 @@ get_registration_state (MMModemCdma *modem,
}
info = mm_generic_cdma_query_reg_state_callback_info_new (MM_GENERIC_CDMA (modem), callback, user_data);
- mm_serial_port_queue_command (port, "+CAD?", 3, get_analog_digital_done, info);
+ mm_at_serial_port_queue_command (port, "+CAD?", 3, get_analog_digital_done, info);
}
/*****************************************************************************/
diff --git a/src/mm-generic-cdma.h b/src/mm-generic-cdma.h
index 5b4a0b65..dd3aba69 100644
--- a/src/mm-generic-cdma.h
+++ b/src/mm-generic-cdma.h
@@ -20,7 +20,7 @@
#include "mm-modem.h"
#include "mm-modem-base.h"
#include "mm-modem-cdma.h"
-#include "mm-serial-port.h"
+#include "mm-at-serial-port.h"
#include "mm-callback-info.h"
#define MM_TYPE_GENERIC_CDMA (mm_generic_cdma_get_type ())
@@ -80,7 +80,7 @@ MMPort * mm_generic_cdma_grab_port (MMGenericCdma *self,
gpointer user_data,
GError **error);
-MMSerialPort *mm_generic_cdma_get_port (MMGenericCdma *modem, MMPortType ptype);
+MMAtSerialPort *mm_generic_cdma_get_at_port (MMGenericCdma *modem, MMPortType ptype);
void mm_generic_cdma_update_cdma1x_quality (MMGenericCdma *self, guint32 quality);
void mm_generic_cdma_update_evdo_quality (MMGenericCdma *self, guint32 quality);
diff --git a/src/mm-generic-gsm.c b/src/mm-generic-gsm.c
index cab564ae..f6e97c3f 100644
--- a/src/mm-generic-gsm.c
+++ b/src/mm-generic-gsm.c
@@ -26,6 +26,7 @@
#include "mm-modem-simple.h"
#include "mm-errors.h"
#include "mm-callback-info.h"
+#include "mm-at-serial-port.h"
#include "mm-serial-parsers.h"
#include "mm-modem-helpers.h"
#include "mm-options.h"
@@ -83,27 +84,27 @@ typedef struct {
guint32 signal_quality;
gint cid;
- MMSerialPort *primary;
- MMSerialPort *secondary;
+ MMAtSerialPort *primary;
+ MMAtSerialPort *secondary;
MMPort *data;
} MMGenericGsmPrivate;
-static void get_registration_status (MMSerialPort *port, MMCallbackInfo *info);
-static void read_operator_code_done (MMSerialPort *port,
+static void get_registration_status (MMAtSerialPort *port, MMCallbackInfo *info);
+static void read_operator_code_done (MMAtSerialPort *port,
GString *response,
GError *error,
gpointer user_data);
-static void read_operator_name_done (MMSerialPort *port,
+static void read_operator_name_done (MMAtSerialPort *port,
GString *response,
GError *error,
gpointer user_data);
-static void reg_state_changed (MMSerialPort *port,
+static void reg_state_changed (MMAtSerialPort *port,
GMatchInfo *match_info,
gpointer user_data);
-static void get_reg_status_done (MMSerialPort *port,
+static void get_reg_status_done (MMAtSerialPort *port,
GString *response,
GError *error,
gpointer user_data);
@@ -196,7 +197,7 @@ error_for_unlock_required (const char *unlock)
}
static void
-pin_check_done (MMSerialPort *port,
+pin_check_done (MMAtSerialPort *port,
GString *response,
GError *error,
gpointer user_data)
@@ -255,7 +256,7 @@ mm_generic_gsm_check_pin (MMGenericGsm *modem,
priv = MM_GENERIC_GSM_GET_PRIVATE (modem);
info = mm_callback_info_new (MM_MODEM (modem), callback, user_data);
- mm_serial_port_queue_command (priv->primary, "+CPIN?", 3, pin_check_done, info);
+ mm_at_serial_port_queue_command (priv->primary, "+CPIN?", 3, pin_check_done, info);
}
/*****************************************************************************/
@@ -341,7 +342,7 @@ initial_pin_check_done (MMModem *modem, GError *error, gpointer user_data)
} else {
priv->pin_checked = TRUE;
if (close_port)
- mm_serial_port_close (priv->primary);
+ mm_serial_port_close (MM_SERIAL_PORT (priv->primary));
check_valid (MM_GENERIC_GSM (modem));
}
}
@@ -357,7 +358,7 @@ initial_pin_check (MMGenericGsm *self)
g_return_if_fail (priv->primary != NULL);
- if (mm_serial_port_open (priv->primary, &error))
+ if (mm_serial_port_open (MM_SERIAL_PORT (priv->primary), &error))
mm_generic_gsm_check_pin (self, initial_pin_check_done, GUINT_TO_POINTER (TRUE));
else {
g_warning ("%s: failed to open serial port: (%d) %s",
@@ -393,26 +394,26 @@ mm_generic_gsm_grab_port (MMGenericGsm *self,
g_return_val_if_fail (!strcmp (subsys, "net") || !strcmp (subsys, "tty"), FALSE);
port = mm_modem_base_add_port (MM_MODEM_BASE (self), subsys, name, ptype);
- if (port && MM_IS_SERIAL_PORT (port)) {
+ if (port && MM_IS_AT_SERIAL_PORT (port)) {
GPtrArray *array;
int i;
- mm_serial_port_set_response_parser (MM_SERIAL_PORT (port),
- mm_serial_parser_v1_parse,
- mm_serial_parser_v1_new (),
- mm_serial_parser_v1_destroy);
+ mm_at_serial_port_set_response_parser (MM_AT_SERIAL_PORT (port),
+ mm_serial_parser_v1_parse,
+ mm_serial_parser_v1_new (),
+ mm_serial_parser_v1_destroy);
/* Set up CREG unsolicited message handlers */
array = mm_gsm_creg_regex_get (FALSE);
for (i = 0; i < array->len; i++) {
regex = g_ptr_array_index (array, i);
- mm_serial_port_add_unsolicited_msg_handler (MM_SERIAL_PORT (port), regex, reg_state_changed, self, NULL);
+ mm_at_serial_port_add_unsolicited_msg_handler (MM_AT_SERIAL_PORT (port), regex, reg_state_changed, self, NULL);
}
mm_gsm_creg_regex_destroy (array);
if (ptype == MM_PORT_TYPE_PRIMARY) {
- priv->primary = MM_SERIAL_PORT (port);
+ priv->primary = MM_AT_SERIAL_PORT (port);
if (!priv->data) {
priv->data = port;
g_object_notify (G_OBJECT (self), MM_MODEM_DATA_DEVICE);
@@ -422,7 +423,7 @@ mm_generic_gsm_grab_port (MMGenericGsm *self,
initial_pin_check (self);
} else if (ptype == MM_PORT_TYPE_SECONDARY)
- priv->secondary = MM_SERIAL_PORT (port);
+ priv->secondary = MM_AT_SERIAL_PORT (port);
} else {
/* Net device (if any) is the preferred data port */
if (!priv->data || MM_IS_SERIAL_PORT (priv->data)) {
@@ -496,7 +497,7 @@ release_port (MMModem *modem, const char *subsys, const char *name)
}
static void
-reg_poll_response (MMSerialPort *port,
+reg_poll_response (MMAtSerialPort *port,
GString *response,
GError *error,
gpointer user_data)
@@ -512,7 +513,7 @@ periodic_poll_cb (gpointer user_data)
{
MMGenericGsm *self = MM_GENERIC_GSM (user_data);
MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (self);
- MMSerialPort *port = priv->primary;
+ MMAtSerialPort *port = priv->primary;
if (mm_port_get_connected (MM_PORT (priv->primary))) {
if (!priv->secondary)
@@ -523,15 +524,15 @@ periodic_poll_cb (gpointer user_data)
}
if (priv->creg_poll)
- mm_serial_port_queue_command (port, "+CREG?", 10, reg_poll_response, self);
+ mm_at_serial_port_queue_command (port, "+CREG?", 10, reg_poll_response, self);
if (priv->cgreg_poll)
- mm_serial_port_queue_command (port, "+CGREG?", 10, reg_poll_response, self);
+ mm_at_serial_port_queue_command (port, "+CGREG?", 10, reg_poll_response, self);
return TRUE; /* continue running */
}
static void
-cgreg1_done (MMSerialPort *port,
+cgreg1_done (MMAtSerialPort *port,
GString *response,
GError *error,
gpointer user_data)
@@ -551,13 +552,13 @@ cgreg1_done (MMSerialPort *port,
priv->poll_id = g_timeout_add_seconds (10, periodic_poll_cb, info->modem);
}
/* Success; get initial state */
- mm_serial_port_queue_command (port, "+CGREG?", 10, reg_poll_response, info->modem);
+ mm_at_serial_port_queue_command (port, "+CGREG?", 10, reg_poll_response, info->modem);
}
mm_callback_info_schedule (info);
}
static void
-cgreg2_done (MMSerialPort *port,
+cgreg2_done (MMAtSerialPort *port,
GString *response,
GError *error,
gpointer user_data)
@@ -570,10 +571,10 @@ cgreg2_done (MMSerialPort *port,
if (info->error) {
g_clear_error (&info->error);
/* Try CGREG=1 instead */
- mm_serial_port_queue_command (port, "+CGREG=1", 3, cgreg1_done, info);
+ mm_at_serial_port_queue_command (port, "+CGREG=1", 3, cgreg1_done, info);
} else {
/* Success; get initial state */
- mm_serial_port_queue_command (port, "+CGREG?", 10, reg_poll_response, info->modem);
+ mm_at_serial_port_queue_command (port, "+CGREG?", 10, reg_poll_response, info->modem);
/* All done */
mm_callback_info_schedule (info);
@@ -585,7 +586,7 @@ cgreg2_done (MMSerialPort *port,
}
static void
-creg1_done (MMSerialPort *port,
+creg1_done (MMAtSerialPort *port,
GString *response,
GError *error,
gpointer user_data)
@@ -605,10 +606,10 @@ creg1_done (MMSerialPort *port,
priv->poll_id = g_timeout_add_seconds (10, periodic_poll_cb, info->modem);
}
/* Success; get initial state */
- mm_serial_port_queue_command (port, "+CREG?", 10, reg_poll_response, info->modem);
+ mm_at_serial_port_queue_command (port, "+CREG?", 10, reg_poll_response, info->modem);
/* Now try to set up CGREG messages */
- mm_serial_port_queue_command (port, "+CGREG=2", 3, cgreg2_done, info);
+ mm_at_serial_port_queue_command (port, "+CGREG=2", 3, cgreg2_done, info);
} else {
/* Modem got removed */
mm_callback_info_schedule (info);
@@ -616,7 +617,7 @@ creg1_done (MMSerialPort *port,
}
static void
-creg2_done (MMSerialPort *port,
+creg2_done (MMAtSerialPort *port,
GString *response,
GError *error,
gpointer user_data)
@@ -628,13 +629,13 @@ creg2_done (MMSerialPort *port,
if (info->modem) {
if (info->error) {
g_clear_error (&info->error);
- mm_serial_port_queue_command (port, "+CREG=1", 3, creg1_done, info);
+ mm_at_serial_port_queue_command (port, "+CREG=1", 3, creg1_done, info);
} else {
/* Success; get initial state */
- mm_serial_port_queue_command (port, "+CREG?", 10, reg_poll_response, info->modem);
+ mm_at_serial_port_queue_command (port, "+CREG?", 10, reg_poll_response, info->modem);
/* Now try to set up CGREG messages */
- mm_serial_port_queue_command (port, "+CGREG=2", 3, cgreg2_done, info);
+ mm_at_serial_port_queue_command (port, "+CGREG=2", 3, cgreg2_done, info);
}
} else {
/* Modem got removed */
@@ -691,7 +692,7 @@ mm_generic_gsm_enable_complete (MMGenericGsm *self,
* messages to the secondary port but not the primary.
*/
if (priv->secondary) {
- if (!mm_serial_port_open (priv->secondary, &error)) {
+ if (!mm_serial_port_open (MM_SERIAL_PORT (priv->secondary), &error)) {
if (mm_options_debug ()) {
g_warning ("%s: error opening secondary port: (%d) %s",
__func__,
@@ -702,14 +703,14 @@ mm_generic_gsm_enable_complete (MMGenericGsm *self,
}
/* Try to enable XON/XOFF flow control */
- mm_serial_port_queue_command (priv->primary, "+IFC=1,1", 3, NULL, NULL);
+ mm_at_serial_port_queue_command (priv->primary, "+IFC=1,1", 3, NULL, NULL);
/* Get allowed mode */
if (MM_GENERIC_GSM_GET_CLASS (self)->get_allowed_mode)
MM_GENERIC_GSM_GET_CLASS (self)->get_allowed_mode (self, get_allowed_mode_done, NULL);
/* Set up unsolicited registration notifications */
- mm_serial_port_queue_command (priv->primary, "+CREG=2", 3, creg2_done, info);
+ mm_at_serial_port_queue_command (priv->primary, "+CREG=2", 3, creg2_done, info);
}
static void
@@ -723,7 +724,7 @@ real_do_enable_power_up_done (MMGenericGsm *self,
}
static void
-enable_done (MMSerialPort *port,
+enable_done (MMAtSerialPort *port,
GString *response,
GError *error,
gpointer user_data)
@@ -742,7 +743,7 @@ enable_done (MMSerialPort *port,
}
static void
-init_done (MMSerialPort *port,
+init_done (MMAtSerialPort *port,
GString *response,
GError *error,
gpointer user_data)
@@ -758,15 +759,15 @@ init_done (MMSerialPort *port,
/* Ensure echo is off after the init command; some modems ignore the
* E0 when it's in the same like as ATZ (Option GIO322).
*/
- mm_serial_port_queue_command (port, "E0 +CMEE=1", 2, NULL, NULL);
+ mm_at_serial_port_queue_command (port, "E0 +CMEE=1", 2, NULL, NULL);
g_object_get (G_OBJECT (info->modem), MM_GENERIC_GSM_INIT_CMD_OPTIONAL, &cmd, NULL);
- mm_serial_port_queue_command (port, cmd, 2, NULL, NULL);
+ mm_at_serial_port_queue_command (port, cmd, 2, NULL, NULL);
g_free (cmd);
g_object_get (G_OBJECT (info->modem), MM_GENERIC_GSM_POWER_UP_CMD, &cmd, NULL);
if (cmd && strlen (cmd))
- mm_serial_port_queue_command (port, cmd, 5, enable_done, user_data);
+ mm_at_serial_port_queue_command (port, cmd, 5, enable_done, user_data);
else
enable_done (port, NULL, NULL, user_data);
g_free (cmd);
@@ -784,7 +785,7 @@ enable_flash_done (MMSerialPort *port, GError *error, gpointer user_data)
}
g_object_get (G_OBJECT (info->modem), MM_GENERIC_GSM_INIT_CMD, &cmd, NULL);
- mm_serial_port_queue_command (port, cmd, 3, init_done, user_data);
+ mm_at_serial_port_queue_command (MM_AT_SERIAL_PORT (port), cmd, 3, init_done, user_data);
g_free (cmd);
}
@@ -795,7 +796,7 @@ real_do_enable (MMGenericGsm *self, MMModemFn callback, gpointer user_data)
MMCallbackInfo *info;
info = mm_callback_info_new (MM_MODEM (self), callback, user_data);
- mm_serial_port_flash (priv->primary, 100, enable_flash_done, info);
+ mm_serial_port_flash (MM_SERIAL_PORT (priv->primary), 100, enable_flash_done, info);
}
static void
@@ -821,7 +822,7 @@ enable (MMModem *modem,
/* First, reset the previously used CID */
priv->cid = -1;
- if (!mm_serial_port_open (priv->primary, &error)) {
+ if (!mm_serial_port_open (MM_SERIAL_PORT (priv->primary), &error)) {
MMCallbackInfo *info;
g_assert (error);
@@ -838,7 +839,7 @@ enable (MMModem *modem,
}
static void
-disable_done (MMSerialPort *port,
+disable_done (MMAtSerialPort *port,
GString *response,
GError *error,
gpointer user_data)
@@ -849,7 +850,7 @@ disable_done (MMSerialPort *port,
if (!info->error) {
MMGenericGsm *self = MM_GENERIC_GSM (info->modem);
- mm_serial_port_close (port);
+ mm_serial_port_close (MM_SERIAL_PORT (port));
mm_modem_set_state (MM_MODEM (info->modem),
MM_MODEM_STATE_DISABLED,
MM_MODEM_STATE_REASON_NONE);
@@ -888,9 +889,9 @@ disable_flash_done (MMSerialPort *port,
g_object_get (G_OBJECT (info->modem), MM_GENERIC_GSM_POWER_DOWN_CMD, &cmd, NULL);
if (cmd && strlen (cmd))
- mm_serial_port_queue_command (port, cmd, 5, disable_done, user_data);
+ mm_at_serial_port_queue_command (MM_AT_SERIAL_PORT (port), cmd, 5, disable_done, user_data);
else
- disable_done (port, NULL, NULL, user_data);
+ disable_done (MM_AT_SERIAL_PORT (port), NULL, NULL, user_data);
g_free (cmd);
}
@@ -927,8 +928,8 @@ disable (MMModem *modem,
_internal_update_access_technology (self, MM_MODEM_GSM_ACCESS_TECH_UNKNOWN);
/* Close the secondary port if its open */
- if (priv->secondary && mm_serial_port_is_open (priv->secondary))
- mm_serial_port_close (priv->secondary);
+ if (priv->secondary && mm_serial_port_is_open (MM_SERIAL_PORT (priv->secondary)))
+ mm_serial_port_close (MM_SERIAL_PORT (priv->secondary));
info = mm_callback_info_new (modem, callback, user_data);
@@ -944,13 +945,13 @@ disable (MMModem *modem,
MM_MODEM_STATE_REASON_NONE);
if (mm_port_get_connected (MM_PORT (priv->primary)))
- mm_serial_port_flash (priv->primary, 1000, disable_flash_done, info);
+ mm_serial_port_flash (MM_SERIAL_PORT (priv->primary), 1000, disable_flash_done, info);
else
- disable_flash_done (priv->primary, NULL, info);
+ disable_flash_done (MM_SERIAL_PORT (priv->primary), NULL, info);
}
static void
-get_string_done (MMSerialPort *port,
+get_string_done (MMAtSerialPort *port,
GString *response,
GError *error,
gpointer user_data)
@@ -974,7 +975,7 @@ get_imei (MMModemGsmCard *modem,
MMCallbackInfo *info;
info = mm_callback_info_string_new (MM_MODEM (modem), callback, user_data);
- mm_serial_port_queue_command_cached (priv->primary, "+CGSN", 3, get_string_done, info);
+ mm_at_serial_port_queue_command_cached (priv->primary, "+CGSN", 3, get_string_done, info);
}
static void
@@ -986,7 +987,7 @@ get_imsi (MMModemGsmCard *modem,
MMCallbackInfo *info;
info = mm_callback_info_string_new (MM_MODEM (modem), callback, user_data);
- mm_serial_port_queue_command_cached (priv->primary, "+CIMI", 3, get_string_done, info);
+ mm_at_serial_port_queue_command_cached (priv->primary, "+CIMI", 3, get_string_done, info);
}
static void
@@ -1017,7 +1018,7 @@ strip_tag (const char *str, const char *tag)
}
static void
-get_version_done (MMSerialPort *port,
+get_version_done (MMAtSerialPort *port,
GString *response,
GError *error,
gpointer user_data)
@@ -1034,7 +1035,7 @@ get_version_done (MMSerialPort *port,
}
static void
-get_model_done (MMSerialPort *port,
+get_model_done (MMAtSerialPort *port,
GString *response,
GError *error,
gpointer user_data)
@@ -1049,7 +1050,7 @@ get_model_done (MMSerialPort *port,
}
static void
-get_manufacturer_done (MMSerialPort *port,
+get_manufacturer_done (MMAtSerialPort *port,
GString *response,
GError *error,
gpointer user_data)
@@ -1076,9 +1077,9 @@ get_card_info (MMModem *modem,
G_CALLBACK (callback),
user_data);
- mm_serial_port_queue_command_cached (priv->primary, "+CGMI", 3, get_manufacturer_done, info);
- mm_serial_port_queue_command_cached (priv->primary, "+CGMM", 3, get_model_done, info);
- mm_serial_port_queue_command_cached (priv->primary, "+CGMR", 3, get_version_done, info);
+ mm_at_serial_port_queue_command_cached (priv->primary, "+CGMI", 3, get_manufacturer_done, info);
+ mm_at_serial_port_queue_command_cached (priv->primary, "+CGMM", 3, get_model_done, info);
+ mm_at_serial_port_queue_command_cached (priv->primary, "+CGMR", 3, get_version_done, info);
}
#define PIN_CLOSE_PORT_TAG "close-port"
@@ -1094,14 +1095,18 @@ pin_puk_recheck_done (MMModem *modem, GError *error, gpointer user_data)
*/
info->error = mm_modem_check_removed (modem, error);
- if (modem && close_port)
- mm_serial_port_close (MM_GENERIC_GSM_GET_PRIVATE (modem)->primary);
+ if (modem && close_port) {
+ MMSerialPort *port;
+
+ port = MM_SERIAL_PORT (MM_GENERIC_GSM_GET_PRIVATE (modem)->primary);
+ mm_serial_port_close (port);
+ }
mm_callback_info_schedule (info);
}
static void
-send_puk_done (MMSerialPort *port,
+send_puk_done (MMAtSerialPort *port,
GString *response,
GError *error,
gpointer user_data)
@@ -1113,7 +1118,7 @@ send_puk_done (MMSerialPort *port,
info->error = g_error_copy (error);
mm_callback_info_schedule (info);
if (close_port)
- mm_serial_port_close (port);
+ mm_serial_port_close (MM_SERIAL_PORT (port));
return;
}
@@ -1143,11 +1148,11 @@ send_puk (MMModemGsmCard *modem,
"Cannot unlock device while connected");
mm_callback_info_schedule (info);
return;
- } else if (!mm_serial_port_is_open (priv->primary)) {
+ } else if (!mm_serial_port_is_open (MM_SERIAL_PORT (priv->primary))) {
/* Modem may not be enabled yet, which sometimes can't be done until
* the device has been unlocked.
*/
- if (!mm_serial_port_open (priv->primary, &info->error)) {
+ if (!mm_serial_port_open (MM_SERIAL_PORT (priv->primary), &info->error)) {
mm_callback_info_schedule (info);
return;
}
@@ -1157,12 +1162,12 @@ send_puk (MMModemGsmCard *modem,
}
command = g_strdup_printf ("+CPIN=\"%s\",\"%s\"", puk, pin);
- mm_serial_port_queue_command (connected ? priv->secondary : priv->primary, command, 3, send_puk_done, info);
+ mm_at_serial_port_queue_command (connected ? priv->secondary : priv->primary, command, 3, send_puk_done, info);
g_free (command);
}
static void
-send_pin_done (MMSerialPort *port,
+send_pin_done (MMAtSerialPort *port,
GString *response,
GError *error,
gpointer user_data)
@@ -1174,7 +1179,7 @@ send_pin_done (MMSerialPort *port,
info->error = g_error_copy (error);
mm_callback_info_schedule (info);
if (close_port)
- mm_serial_port_close (port);
+ mm_serial_port_close (MM_SERIAL_PORT (port));
return;
}
@@ -1203,11 +1208,11 @@ send_pin (MMModemGsmCard *modem,
"Cannot unlock device while connected");
mm_callback_info_schedule (info);
return;
- } else if (!mm_serial_port_is_open (priv->primary)) {
+ } else if (!mm_serial_port_is_open (MM_SERIAL_PORT (priv->primary))) {
/* Modem may not be enabled yet, which sometimes can't be done until
* the device has been unlocked.
*/
- if (!mm_serial_port_open (priv->primary, &info->error)) {
+ if (!mm_serial_port_open (MM_SERIAL_PORT (priv->primary), &info->error)) {
mm_callback_info_schedule (info);
return;
}
@@ -1217,12 +1222,12 @@ send_pin (MMModemGsmCard *modem,
}
command = g_strdup_printf ("+CPIN=\"%s\"", pin);
- mm_serial_port_queue_command (connected ? priv->secondary : priv->primary, command, 3, send_pin_done, info);
+ mm_at_serial_port_queue_command (connected ? priv->secondary : priv->primary, command, 3, send_pin_done, info);
g_free (command);
}
static void
-enable_pin_done (MMSerialPort *port,
+enable_pin_done (MMAtSerialPort *port,
GString *response,
GError *error,
gpointer user_data)
@@ -1247,12 +1252,12 @@ enable_pin (MMModemGsmCard *modem,
info = mm_callback_info_new (MM_MODEM (modem), callback, user_data);
command = g_strdup_printf ("+CLCK=\"SC\",%d,\"%s\"", enabled ? 1 : 0, pin);
- mm_serial_port_queue_command (priv->primary, command, 3, enable_pin_done, info);
+ mm_at_serial_port_queue_command (priv->primary, command, 3, enable_pin_done, info);
g_free (command);
}
static void
-change_pin_done (MMSerialPort *port,
+change_pin_done (MMAtSerialPort *port,
GString *response,
GError *error,
gpointer user_data)
@@ -1277,7 +1282,7 @@ change_pin (MMModemGsmCard *modem,
info = mm_callback_info_new (MM_MODEM (modem), callback, user_data);
command = g_strdup_printf ("+CPWD=\"SC\",\"%s\",\"%s\"", old_pin, new_pin);
- mm_serial_port_queue_command (priv->primary, command, 3, change_pin_done, info);
+ mm_at_serial_port_queue_command (priv->primary, command, 3, change_pin_done, info);
g_free (command);
}
@@ -1351,7 +1356,7 @@ parse_operator (const char *reply)
}
static void
-read_operator_code_done (MMSerialPort *port,
+read_operator_code_done (MMAtSerialPort *port,
GString *response,
GError *error,
gpointer user_data)
@@ -1367,7 +1372,7 @@ read_operator_code_done (MMSerialPort *port,
}
static void
-read_operator_name_done (MMSerialPort *port,
+read_operator_name_done (MMAtSerialPort *port,
GString *response,
GError *error,
gpointer user_data)
@@ -1432,8 +1437,8 @@ mm_generic_gsm_set_reg_status (MMGenericGsm *modem,
if (status == MM_MODEM_GSM_NETWORK_REG_STATUS_HOME ||
status == MM_MODEM_GSM_NETWORK_REG_STATUS_ROAMING) {
- mm_serial_port_queue_command (priv->primary, "+COPS=3,2;+COPS?", 3, read_operator_code_done, modem);
- mm_serial_port_queue_command (priv->primary, "+COPS=3,0;+COPS?", 3, read_operator_name_done, modem);
+ mm_at_serial_port_queue_command (priv->primary, "+COPS=3,2;+COPS?", 3, read_operator_code_done, modem);
+ mm_at_serial_port_queue_command (priv->primary, "+COPS=3,0;+COPS?", 3, read_operator_name_done, modem);
mm_modem_gsm_network_get_signal_quality (MM_MODEM_GSM_NETWORK (modem), got_signal_quality, NULL);
} else
reg_info_updated (MM_GENERIC_GSM (modem), FALSE, 0, TRUE, NULL, TRUE, NULL);
@@ -1505,7 +1510,7 @@ reg_status_updated (MMGenericGsm *self, int new_value, GError **error)
}
static void
-reg_state_changed (MMSerialPort *port,
+reg_state_changed (MMAtSerialPort *port,
GMatchInfo *match_info,
gpointer user_data)
{
@@ -1630,7 +1635,7 @@ handle_reg_status_response (MMGenericGsm *self,
}
static void
-get_reg_status_done (MMSerialPort *port,
+get_reg_status_done (MMAtSerialPort *port,
GString *response,
GError *error,
gpointer user_data)
@@ -1681,13 +1686,13 @@ reg_done:
}
static void
-get_registration_status (MMSerialPort *port, MMCallbackInfo *info)
+get_registration_status (MMAtSerialPort *port, MMCallbackInfo *info)
{
- mm_serial_port_queue_command (port, "+CREG?", 10, get_reg_status_done, info);
+ mm_at_serial_port_queue_command (port, "+CREG?", 10, get_reg_status_done, info);
}
static void
-register_done (MMSerialPort *port,
+register_done (MMAtSerialPort *port,
GString *response,
GError *error,
gpointer user_data)
@@ -1774,7 +1779,7 @@ do_register (MMModemGsmNetwork *modem,
* the +COPS response is never received.
*/
mm_callback_info_ref (info);
- mm_serial_port_queue_command (priv->primary, command, 120, register_done, info);
+ mm_at_serial_port_queue_command (priv->primary, command, 120, register_done, info);
g_free (command);
}
@@ -1837,7 +1842,7 @@ mm_generic_gsm_connect_complete (MMGenericGsm *modem,
}
static void
-connect_report_done (MMSerialPort *port,
+connect_report_done (MMAtSerialPort *port,
GString *response,
GError *error,
gpointer user_data)
@@ -1868,7 +1873,7 @@ connect_report_done (MMSerialPort *port,
}
static void
-connect_done (MMSerialPort *port,
+connect_done (MMAtSerialPort *port,
GString *response,
GError *error,
gpointer user_data)
@@ -1880,7 +1885,7 @@ connect_done (MMSerialPort *port,
info->error = g_error_copy (error);
/* Try to get more information why it failed */
priv = MM_GENERIC_GSM_GET_PRIVATE (info->modem);
- mm_serial_port_queue_command (priv->primary, "+CEER", 3, connect_report_done, info);
+ mm_at_serial_port_queue_command (priv->primary, "+CEER", 3, connect_report_done, info);
} else
mm_generic_gsm_connect_complete (MM_GENERIC_GSM (info->modem), NULL, info);
}
@@ -1914,7 +1919,7 @@ connect (MMModem *modem,
} else
command = g_strconcat ("DT", number, NULL);
- mm_serial_port_queue_command (priv->primary, command, 60, connect_done, info);
+ mm_at_serial_port_queue_command (priv->primary, command, 60, connect_done, info);
g_free (command);
}
@@ -1948,7 +1953,7 @@ disconnect_done (MMModem *modem,
}
static void
-disconnect_cgact_done (MMSerialPort *port,
+disconnect_cgact_done (MMAtSerialPort *port,
GString *response,
GError *error,
gpointer user_data)
@@ -1986,7 +1991,7 @@ disconnect_flash_done (MMSerialPort *port,
command = g_strdup_printf ("+CGACT=0");
}
- mm_serial_port_queue_command (port, command, 3, disconnect_cgact_done, info);
+ mm_at_serial_port_queue_command (MM_AT_SERIAL_PORT (port), command, 3, disconnect_cgact_done, info);
g_free (command);
}
@@ -2000,7 +2005,7 @@ real_do_disconnect (MMGenericGsm *self,
MMCallbackInfo *info;
info = mm_callback_info_new (MM_MODEM (self), callback, user_data);
- mm_serial_port_flash (priv->primary, 1000, disconnect_flash_done, info);
+ mm_serial_port_flash (MM_SERIAL_PORT (priv->primary), 1000, disconnect_flash_done, info);
}
static void
@@ -2040,7 +2045,7 @@ gsm_network_scan_invoke (MMCallbackInfo *info)
}
static void
-scan_done (MMSerialPort *port,
+scan_done (MMAtSerialPort *port,
GString *response,
GError *error,
gpointer user_data)
@@ -2072,7 +2077,7 @@ scan (MMModemGsmNetwork *modem,
G_CALLBACK (callback),
user_data);
- mm_serial_port_queue_command (priv->primary, "+COPS=?", 120, scan_done, info);
+ mm_at_serial_port_queue_command (priv->primary, "+COPS=?", 120, scan_done, info);
}
/* SetApn */
@@ -2080,7 +2085,7 @@ scan (MMModemGsmNetwork *modem,
#define APN_CID_TAG "generic-gsm-cid"
static void
-set_apn_done (MMSerialPort *port,
+set_apn_done (MMAtSerialPort *port,
GString *response,
GError *error,
gpointer user_data)
@@ -2098,7 +2103,7 @@ set_apn_done (MMSerialPort *port,
}
static void
-cid_range_read (MMSerialPort *port,
+cid_range_read (MMAtSerialPort *port,
GString *response,
GError *error,
gpointer user_data)
@@ -2158,13 +2163,13 @@ cid_range_read (MMSerialPort *port,
mm_callback_info_set_data (info, APN_CID_TAG, GINT_TO_POINTER (cid), NULL);
command = g_strdup_printf ("+CGDCONT=%d,\"IP\",\"%s\"", cid, apn);
- mm_serial_port_queue_command (port, command, 3, set_apn_done, info);
+ mm_at_serial_port_queue_command (port, command, 3, set_apn_done, info);
g_free (command);
}
}
static void
-existing_apns_read (MMSerialPort *port,
+existing_apns_read (MMAtSerialPort *port,
GString *response,
GError *error,
gpointer user_data)
@@ -2231,7 +2236,7 @@ done:
mm_callback_info_schedule (info);
else {
/* APN not configured on the card. Get the allowed CID range */
- mm_serial_port_queue_command_cached (port, "+CGDCONT=?", 3, cid_range_read, info);
+ mm_at_serial_port_queue_command_cached (port, "+CGDCONT=?", 3, cid_range_read, info);
}
}
@@ -2248,7 +2253,7 @@ set_apn (MMModemGsmNetwork *modem,
mm_callback_info_set_data (info, "apn", g_strdup (apn), g_free);
/* Start by searching if the APN is already in card */
- mm_serial_port_queue_command (priv->primary, "+CGDCONT?", 3, existing_apns_read, info);
+ mm_at_serial_port_queue_command (priv->primary, "+CGDCONT?", 3, existing_apns_read, info);
}
/* GetSignalQuality */
@@ -2319,7 +2324,7 @@ mm_generic_gsm_update_signal_quality (MMGenericGsm *self, guint32 quality)
}
static void
-get_signal_quality_done (MMSerialPort *port,
+get_signal_quality_done (MMAtSerialPort *port,
GString *response,
GError *error,
gpointer user_data)
@@ -2379,7 +2384,7 @@ get_signal_quality (MMModemGsmNetwork *modem,
}
info = mm_callback_info_uint_new (MM_MODEM (modem), callback, user_data);
- mm_serial_port_queue_command (connected ? priv->secondary : priv->primary, "+CSQ", 3, get_signal_quality_done, info);
+ mm_at_serial_port_queue_command (connected ? priv->secondary : priv->primary, "+CSQ", 3, get_signal_quality_done, info);
}
/*****************************************************************************/
@@ -2520,7 +2525,7 @@ set_allowed_mode (MMModemGsmNetwork *net,
/* MMModemGsmSms interface */
static void
-sms_send_done (MMSerialPort *port,
+sms_send_done (MMAtSerialPort *port,
GString *response,
GError *error,
gpointer user_data)
@@ -2547,7 +2552,7 @@ sms_send (MMModemGsmSms *modem,
MMCallbackInfo *info;
char *command;
gboolean connected;
- MMSerialPort *port = NULL;
+ MMAtSerialPort *port = NULL;
info = mm_callback_info_new (MM_MODEM (modem), callback, user_data);
@@ -2566,16 +2571,16 @@ sms_send (MMModemGsmSms *modem,
}
/* FIXME: use the PDU mode instead */
- mm_serial_port_queue_command (port, "AT+CMGF=1", 3, NULL, NULL);
+ mm_at_serial_port_queue_command (port, "AT+CMGF=1", 3, NULL, NULL);
command = g_strdup_printf ("+CMGS=\"%s\"\r%s\x1a", number, text);
- mm_serial_port_queue_command (port, command, 10, sms_send_done, info);
+ mm_at_serial_port_queue_command (port, command, 10, sms_send_done, info);
g_free (command);
}
-MMSerialPort *
-mm_generic_gsm_get_port (MMGenericGsm *modem,
- MMPortType ptype)
+MMAtSerialPort *
+mm_generic_gsm_get_at_port (MMGenericGsm *modem,
+ MMPortType ptype)
{
g_return_val_if_fail (MM_IS_GENERIC_GSM (modem), NULL);
g_return_val_if_fail (ptype != MM_PORT_TYPE_UNKNOWN, NULL);
diff --git a/src/mm-generic-gsm.h b/src/mm-generic-gsm.h
index 9aef615e..2ef81c3c 100644
--- a/src/mm-generic-gsm.h
+++ b/src/mm-generic-gsm.h
@@ -20,7 +20,7 @@
#include "mm-modem-gsm.h"
#include "mm-modem-gsm-network.h"
#include "mm-modem-base.h"
-#include "mm-serial-port.h"
+#include "mm-at-serial-port.h"
#include "mm-callback-info.h"
#define MM_TYPE_GENERIC_GSM (mm_generic_gsm_get_type ())
@@ -148,8 +148,8 @@ void mm_generic_gsm_check_pin (MMGenericGsm *modem,
MMModemFn callback,
gpointer user_data);
-MMSerialPort *mm_generic_gsm_get_port (MMGenericGsm *modem,
- MMPortType ptype);
+MMAtSerialPort *mm_generic_gsm_get_at_port (MMGenericGsm *modem,
+ MMPortType ptype);
MMPort *mm_generic_gsm_grab_port (MMGenericGsm *modem,
const char *subsys,
diff --git a/src/mm-manager.c b/src/mm-manager.c
index 389acba1..9576766c 100644
--- a/src/mm-manager.c
+++ b/src/mm-manager.c
@@ -520,7 +520,7 @@ device_added (MMManager *manager, GUdevDevice *device)
/* ignore VTs */
if (strncmp (name, "tty", 3) == 0 && isdigit (name[3]))
- return;
+ return;
if (find_modem_for_port (manager, subsys, name))
return;
@@ -633,12 +633,18 @@ mm_manager_start (MMManager *manager)
priv = MM_MANAGER_GET_PRIVATE (manager);
devices = g_udev_client_query_by_subsystem (priv->udev, "tty");
- for (iter = devices; iter; iter = g_list_next (iter))
+ for (iter = devices; iter; iter = g_list_next (iter)) {
device_added (manager, G_UDEV_DEVICE (iter->data));
+ g_object_unref (G_OBJECT (iter->data));
+ }
+ g_list_free (devices);
devices = g_udev_client_query_by_subsystem (priv->udev, "net");
- for (iter = devices; iter; iter = g_list_next (iter))
+ for (iter = devices; iter; iter = g_list_next (iter)) {
device_added (manager, G_UDEV_DEVICE (iter->data));
+ g_object_unref (G_OBJECT (iter->data));
+ }
+ g_list_free (devices);
}
static void
diff --git a/src/mm-modem-base.c b/src/mm-modem-base.c
index 890c55c7..8af9bd14 100644
--- a/src/mm-modem-base.c
+++ b/src/mm-modem-base.c
@@ -21,7 +21,7 @@
#include "mm-modem-base.h"
#include "mm-modem.h"
-#include "mm-serial-port.h"
+#include "mm-at-serial-port.h"
#include "mm-errors.h"
#include "mm-options.h"
#include "mm-properties-changed-signal.h"
@@ -115,7 +115,7 @@ mm_modem_base_add_port (MMModemBase *self,
}
if (!strcmp (subsys, "tty"))
- port = MM_PORT (mm_serial_port_new (name, ptype));
+ port = MM_PORT (mm_at_serial_port_new (name, ptype));
else if (!strcmp (subsys, "net")) {
port = MM_PORT (g_object_new (MM_TYPE_PORT,
MM_PORT_DEVICE, name,
diff --git a/src/mm-plugin-base.c b/src/mm-plugin-base.c
index 4b74feb7..7547fe21 100644
--- a/src/mm-plugin-base.c
+++ b/src/mm-plugin-base.c
@@ -26,7 +26,7 @@
#include <gudev/gudev.h>
#include "mm-plugin-base.h"
-#include "mm-serial-port.h"
+#include "mm-at-serial-port.h"
#include "mm-serial-parsers.h"
#include "mm-errors.h"
#include "mm-marshal.h"
@@ -95,7 +95,7 @@ typedef struct {
guint32 open_tries;
guint full_id;
- MMSerialPort *probe_port;
+ MMAtSerialPort *probe_port;
guint32 probed_caps;
ProbeState probe_state;
guint probe_id;
@@ -428,7 +428,7 @@ probe_complete (MMPluginBaseSupportsTask *task)
}
static void
-parse_response (MMSerialPort *port,
+parse_response (MMAtSerialPort *port,
GString *response,
GError *error,
gpointer user_data);
@@ -441,7 +441,7 @@ real_handle_probe_response (MMPluginBase *self,
const GError *error)
{
MMPluginBaseSupportsTaskPrivate *task_priv = MM_PLUGIN_BASE_SUPPORTS_TASK_GET_PRIVATE (task);
- MMSerialPort *port = task_priv->probe_port;
+ MMAtSerialPort *port = task_priv->probe_port;
gboolean ignore_error = FALSE;
/* Some modems (Huawei E160g) won't respond to +GCAP with no SIM, but
@@ -455,7 +455,7 @@ real_handle_probe_response (MMPluginBase *self,
/* Try GCAP again */
if (task_priv->probe_state < PROBE_STATE_GCAP_TRY3) {
task_priv->probe_state++;
- mm_serial_port_queue_command (port, "+GCAP", 3, parse_response, task);
+ mm_at_serial_port_queue_command (port, "+GCAP", 3, parse_response, task);
} else {
/* Otherwise, if all the GCAP tries timed out, ignore the port
* as it's probably not an AT-capable port.
@@ -509,19 +509,19 @@ real_handle_probe_response (MMPluginBase *self,
switch (task_priv->probe_state) {
case PROBE_STATE_GCAP_TRY2:
case PROBE_STATE_GCAP_TRY3:
- mm_serial_port_queue_command (port, "+GCAP", 3, parse_response, task);
+ mm_at_serial_port_queue_command (port, "+GCAP", 3, parse_response, task);
break;
case PROBE_STATE_ATI:
/* After the last GCAP attempt, try ATI */
- mm_serial_port_queue_command (port, "I", 3, parse_response, task);
+ mm_at_serial_port_queue_command (port, "I", 3, parse_response, task);
break;
case PROBE_STATE_CPIN:
/* After the ATI attempt, try CPIN */
- mm_serial_port_queue_command (port, "+CPIN?", 3, parse_response, task);
+ mm_at_serial_port_queue_command (port, "+CPIN?", 3, parse_response, task);
break;
case PROBE_STATE_CGMM:
/* After the CPIN attempt, try CGMM */
- mm_serial_port_queue_command (port, "+CGMM", 3, parse_response, task);
+ mm_at_serial_port_queue_command (port, "+CGMM", 3, parse_response, task);
break;
default:
/* Probably not GSM or CDMA */
@@ -565,7 +565,7 @@ handle_probe_response (gpointer user_data)
}
static void
-parse_response (MMSerialPort *port,
+parse_response (MMAtSerialPort *port,
GString *response,
GError *error,
gpointer user_data)
@@ -595,7 +595,7 @@ parse_response (MMSerialPort *port,
static void flash_done (MMSerialPort *port, GError *error, gpointer user_data);
static void
-custom_init_response (MMSerialPort *port,
+custom_init_response (MMAtSerialPort *port,
GString *response,
GError *error,
gpointer user_data)
@@ -607,7 +607,7 @@ custom_init_response (MMSerialPort *port,
task_priv->custom_init_tries++;
if (task_priv->custom_init_tries < task_priv->custom_init_max_tries) {
/* Try the custom command again */
- flash_done (port, NULL, user_data);
+ flash_done (MM_SERIAL_PORT (port), NULL, user_data);
return;
} else if (task_priv->custom_init_fail_if_timeout) {
/* Fail the probe if the plugin wanted it and the command timed out */
@@ -619,7 +619,7 @@ custom_init_response (MMSerialPort *port,
}
/* Otherwise proceed to probing */
- mm_serial_port_queue_command (port, "+GCAP", 3, parse_response, user_data);
+ mm_at_serial_port_queue_command (port, "+GCAP", 3, parse_response, user_data);
}
static void
@@ -633,14 +633,14 @@ flash_done (MMSerialPort *port, GError *error, gpointer user_data)
if (task_priv->custom_init) {
if (!delay_secs)
delay_secs = 3;
- mm_serial_port_queue_command (port,
- task_priv->custom_init,
- delay_secs,
- custom_init_response,
- user_data);
+ mm_at_serial_port_queue_command (MM_AT_SERIAL_PORT (port),
+ task_priv->custom_init,
+ delay_secs,
+ custom_init_response,
+ user_data);
} else {
/* Otherwise start normal probing */
- custom_init_response (port, NULL, NULL, user_data);
+ custom_init_response (MM_AT_SERIAL_PORT (port), NULL, NULL, user_data);
}
}
@@ -653,7 +653,7 @@ try_open (gpointer user_data)
task_priv->open_id = 0;
- if (!mm_serial_port_open (task_priv->probe_port, &error)) {
+ if (!mm_serial_port_open (MM_SERIAL_PORT (task_priv->probe_port), &error)) {
if (++task_priv->open_tries > 4) {
/* took too long to open the port; give up */
g_warning ("(%s): failed to open after 4 tries.",
@@ -682,7 +682,7 @@ try_open (gpointer user_data)
g_debug ("(%s): probe requested by plugin '%s'",
g_udev_device_get_name (port),
mm_plugin_get_name (MM_PLUGIN (task_priv->plugin)));
- mm_serial_port_flash (task_priv->probe_port, 100, flash_done, task);
+ mm_serial_port_flash (MM_SERIAL_PORT (task_priv->probe_port), 100, flash_done, task);
}
return FALSE;
@@ -694,7 +694,7 @@ mm_plugin_base_probe_port (MMPluginBase *self,
GError **error)
{
MMPluginBaseSupportsTaskPrivate *task_priv = MM_PLUGIN_BASE_SUPPORTS_TASK_GET_PRIVATE (task);
- MMSerialPort *serial;
+ MMAtSerialPort *serial;
const char *name;
GUdevDevice *port;
@@ -707,7 +707,7 @@ mm_plugin_base_probe_port (MMPluginBase *self,
name = g_udev_device_get_name (port);
g_assert (name);
- serial = mm_serial_port_new (name, MM_PORT_TYPE_PRIMARY);
+ serial = mm_at_serial_port_new (name, MM_PORT_TYPE_PRIMARY);
if (serial == NULL) {
g_set_error_literal (error, MM_MODEM_ERROR, MM_MODEM_ERROR_GENERAL,
"Failed to create new serial port.");
@@ -719,10 +719,10 @@ mm_plugin_base_probe_port (MMPluginBase *self,
MM_PORT_CARRIER_DETECT, FALSE,
NULL);
- mm_serial_port_set_response_parser (serial,
- mm_serial_parser_v1_parse,
- mm_serial_parser_v1_new (),
- mm_serial_parser_v1_destroy);
+ mm_at_serial_port_set_response_parser (serial,
+ mm_serial_parser_v1_parse,
+ mm_serial_parser_v1_new (),
+ mm_serial_parser_v1_destroy);
/* Open the port */
task_priv->probe_port = serial;
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 */
+
diff --git a/src/mm-serial-port.c b/src/mm-serial-port.c
index 2134751f..29505a21 100644
--- a/src/mm-serial-port.c
+++ b/src/mm-serial-port.c
@@ -1,4 +1,3 @@
-/* -*- 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
@@ -55,16 +54,7 @@ typedef struct {
GHashTable *reply_cache;
GIOChannel *channel;
GQueue *queue;
- GString *command;
- GString *response;
-
- gboolean connected;
-
- /* Response parser data */
- MMSerialResponseParserFn response_parser_fn;
- gpointer response_parser_user_data;
- GDestroyNotify response_parser_notify;
- GSList *unsolicited_msg_handlers;
+ GByteArray *response;
struct termios old_t;
@@ -165,33 +155,6 @@ mm_serial_port_print_config (MMSerialPort *port, const char *detail)
}
#endif
-typedef struct {
- GRegex *regex;
- MMSerialUnsolicitedMsgFn callback;
- gpointer user_data;
- GDestroyNotify notify;
-} MMUnsolicitedMsgHandler;
-
-static void
-mm_serial_port_set_cached_reply (MMSerialPort *self,
- const char *command,
- const char *reply)
-{
- if (reply)
- g_hash_table_insert (MM_SERIAL_PORT_GET_PRIVATE (self)->reply_cache,
- g_strdup (command),
- g_strdup (reply));
- else
- g_hash_table_remove (MM_SERIAL_PORT_GET_PRIVATE (self)->reply_cache, command);
-}
-
-static const char *
-mm_serial_port_get_cached_reply (MMSerialPort *self,
- const char *command)
-{
- return (char *) g_hash_table_lookup (MM_SERIAL_PORT_GET_PRIVATE (self)->reply_cache, command);
-}
-
static int
parse_baudrate (guint i)
{
@@ -327,7 +290,7 @@ parse_stopbits (guint i)
}
static gboolean
-config_fd (MMSerialPort *self, GError **error)
+real_config_fd (MMSerialPort *self, int fd, GError **error)
{
MMSerialPortPrivate *priv = MM_SERIAL_PORT_GET_PRIVATE (self);
struct termio stbuf;
@@ -342,7 +305,7 @@ config_fd (MMSerialPort *self, GError **error)
stopbits = parse_stopbits (priv->stopbits);
memset (&stbuf, 0, sizeof (struct termio));
- if (ioctl (priv->fd, TCGETA, &stbuf) != 0) {
+ if (ioctl (fd, TCGETA, &stbuf) != 0) {
g_warning ("%s (%s): TCGETA error: %d",
__func__,
mm_port_get_device (MM_PORT (self)),
@@ -366,7 +329,7 @@ config_fd (MMSerialPort *self, GError **error)
stbuf.c_cflag &= ~(CBAUD | CSIZE | CSTOPB | PARENB | CRTSCTS);
stbuf.c_cflag |= (speed | bits | CREAD | 0 | parity | stopbits | CLOCAL);
- if (ioctl (priv->fd, TCSETA, &stbuf) < 0) {
+ if (ioctl (fd, TCSETA, &stbuf) < 0) {
g_set_error (error,
MM_MODEM_ERROR,
MM_MODEM_ERROR_GENERAL,
@@ -417,13 +380,13 @@ serial_debug (MMSerialPort *self, const char *prefix, const char *buf, int len)
static gboolean
mm_serial_port_send_command (MMSerialPort *self,
- const char *command,
+ GByteArray *command,
GError **error)
{
MMSerialPortPrivate *priv = MM_SERIAL_PORT_GET_PRIVATE (self);
- const char *s;
- int status;
+ int status, i = 0;
int eagain_count = 1000;
+ const guint8 *p;
if (priv->fd < 0) {
g_set_error (error, MM_SERIAL_ERROR, MM_SERIAL_SEND_FAILED,
@@ -437,21 +400,15 @@ mm_serial_port_send_command (MMSerialPort *self,
return FALSE;
}
- g_string_truncate (priv->command, g_str_has_prefix (command, "AT") ? 0 : 2);
- g_string_append (priv->command, command);
-
- if (command[strlen (command)] != '\r')
- g_string_append_c (priv->command, '\r');
-
- serial_debug (self, "-->", priv->command->str, -1);
+ serial_debug (self, "-->", (const char *) command->data, command->len);
/* Only accept about 3 seconds of EAGAIN */
if (priv->send_delay > 0)
eagain_count = 3000000 / priv->send_delay;
- s = priv->command->str;
- while (*s) {
- status = write (priv->fd, s, 1);
+ while (i < command->len) {
+ p = &command->data[i];
+ status = write (priv->fd, p, 1);
if (status < 0) {
if (errno == EAGAIN) {
eagain_count--;
@@ -466,18 +423,46 @@ mm_serial_port_send_command (MMSerialPort *self,
break;
}
} else
- s++;
+ i++;
if (priv->send_delay)
usleep (priv->send_delay);
}
- return *s == '\0';
+ return i == command->len;
+}
+
+static void
+mm_serial_port_set_cached_reply (MMSerialPort *self,
+ const GByteArray *command,
+ const GByteArray *response)
+{
+ MMSerialPortPrivate *priv = MM_SERIAL_PORT_GET_PRIVATE (self);
+
+ g_return_if_fail (self != NULL);
+ g_return_if_fail (MM_IS_SERIAL_PORT (self));
+ g_return_if_fail (command != NULL);
+
+ if (response) {
+ GByteArray *cmd_copy = g_byte_array_sized_new (command->len);
+ GByteArray *rsp_copy = g_byte_array_sized_new (response->len);
+
+ g_byte_array_append (cmd_copy, command->data, command->len);
+ g_byte_array_append (rsp_copy, response->data, response->len);
+ g_hash_table_insert (priv->reply_cache, cmd_copy, rsp_copy);
+ } else
+ g_hash_table_remove (MM_SERIAL_PORT_GET_PRIVATE (self)->reply_cache, command);
+}
+
+static const GByteArray *
+mm_serial_port_get_cached_reply (MMSerialPort *self, GByteArray *command)
+{
+ return (const GByteArray *) g_hash_table_lookup (MM_SERIAL_PORT_GET_PRIVATE (self)->reply_cache, command);
}
typedef struct {
- char *command;
- MMSerialResponseFn callback;
+ GByteArray *command;
+ GCallback callback;
gpointer user_data;
guint32 timeout;
gboolean cached;
@@ -520,19 +505,26 @@ mm_serial_port_got_response (MMSerialPort *self, GError *error)
info = (MMQueueData *) g_queue_pop_head (priv->queue);
if (info) {
if (info->cached && !error)
- mm_serial_port_set_cached_reply (self, info->command, priv->response->str);
-
- if (info->callback)
- info->callback (self, priv->response, error, info->user_data);
+ mm_serial_port_set_cached_reply (self, info->command, priv->response);
+
+ if (info->callback) {
+ g_warn_if_fail (MM_SERIAL_PORT_GET_CLASS (self)->handle_response != NULL);
+ MM_SERIAL_PORT_GET_CLASS (self)->handle_response (self,
+ priv->response,
+ error,
+ info->callback,
+ info->user_data);
+ }
- g_free (info->command);
+ g_byte_array_free (info->command, TRUE);
g_slice_free (MMQueueData, info);
}
if (error)
g_error_free (error);
- g_string_truncate (priv->response, 0);
+ if (priv->response->len)
+ g_byte_array_remove_range (priv->response, 0, priv->response->len);
if (!g_queue_is_empty (priv->queue))
mm_serial_port_schedule_queue_process (self);
}
@@ -572,10 +564,10 @@ mm_serial_port_queue_process (gpointer data)
return FALSE;
if (info->cached) {
- const char *cached = mm_serial_port_get_cached_reply (self, info->command);
+ const GByteArray *cached = mm_serial_port_get_cached_reply (self, info->command);
if (cached) {
- g_string_append (priv->response, cached);
+ g_byte_array_append (priv->response, cached->data, cached->len);
mm_serial_port_got_response (self, NULL);
return FALSE;
}
@@ -596,111 +588,16 @@ mm_serial_port_queue_process (gpointer data)
return FALSE;
}
-void
-mm_serial_port_add_unsolicited_msg_handler (MMSerialPort *self,
- GRegex *regex,
- MMSerialUnsolicitedMsgFn callback,
- gpointer user_data,
- GDestroyNotify notify)
-{
- MMUnsolicitedMsgHandler *handler;
- MMSerialPortPrivate *priv;
-
- g_return_if_fail (MM_IS_SERIAL_PORT (self));
- g_return_if_fail (regex != NULL);
-
- handler = g_slice_new (MMUnsolicitedMsgHandler);
- handler->regex = g_regex_ref (regex);
- handler->callback = callback;
- handler->user_data = user_data;
- handler->notify = notify;
-
- priv = MM_SERIAL_PORT_GET_PRIVATE (self);
- priv->unsolicited_msg_handlers = g_slist_append (priv->unsolicited_msg_handlers, handler);
-}
-
-void
-mm_serial_port_set_response_parser (MMSerialPort *self,
- MMSerialResponseParserFn fn,
- gpointer user_data,
- GDestroyNotify notify)
-{
- MMSerialPortPrivate *priv = MM_SERIAL_PORT_GET_PRIVATE (self);
-
- g_return_if_fail (MM_IS_SERIAL_PORT (self));
-
- if (priv->response_parser_notify)
- priv->response_parser_notify (priv->response_parser_user_data);
-
- priv->response_parser_fn = fn;
- priv->response_parser_user_data = user_data;
- priv->response_parser_notify = notify;
-}
-
-static gboolean
-remove_eval_cb (const GMatchInfo *match_info,
- GString *result,
- gpointer user_data)
-{
- int *result_len = (int *) user_data;
- int start;
- int end;
-
- if (g_match_info_fetch_pos (match_info, 0, &start, &end))
- *result_len -= (end - start);
-
- return FALSE;
-}
-
-static void
-parse_unsolicited_messages (MMSerialPort *self,
- GString *response)
-{
- MMSerialPortPrivate *priv = MM_SERIAL_PORT_GET_PRIVATE (self);
- GSList *iter;
-
- for (iter = priv->unsolicited_msg_handlers; iter; iter = iter->next) {
- MMUnsolicitedMsgHandler *handler = (MMUnsolicitedMsgHandler *) iter->data;
- GMatchInfo *match_info;
- gboolean matches;
-
- matches = g_regex_match_full (handler->regex, response->str, response->len, 0, 0, &match_info, NULL);
- if (handler->callback) {
- while (g_match_info_matches (match_info)) {
- handler->callback (self, match_info, handler->user_data);
- g_match_info_next (match_info, NULL);
- }
- }
-
- g_match_info_free (match_info);
-
- if (matches) {
- /* Remove matches */
- char *str;
- int result_len = response->len;
-
- str = g_regex_replace_eval (handler->regex, response->str, response->len, 0, 0,
- remove_eval_cb, &result_len, NULL);
-
- g_string_truncate (response, 0);
- g_string_append_len (response, str, result_len);
- g_free (str);
- }
- }
-}
-
static gboolean
parse_response (MMSerialPort *self,
- GString *response,
+ GByteArray *response,
GError **error)
{
- MMSerialPortPrivate *priv = MM_SERIAL_PORT_GET_PRIVATE (self);
+ if (MM_SERIAL_PORT_GET_CLASS (self)->parse_unsolicited)
+ MM_SERIAL_PORT_GET_CLASS (self)->parse_unsolicited (self, response);
- g_return_val_if_fail (priv->response_parser_fn != NULL, FALSE);
-
- parse_unsolicited_messages (self, response);
-
- return priv->response_parser_fn (priv->response_parser_user_data, response, error);
+ g_return_val_if_fail (MM_SERIAL_PORT_GET_CLASS (self)->parse_response, FALSE);
+ return MM_SERIAL_PORT_GET_CLASS (self)->parse_response (self, response, error);
}
static gboolean
@@ -715,13 +612,15 @@ data_available (GIOChannel *source,
GIOStatus status;
if (condition & G_IO_HUP) {
- g_string_truncate (priv->response, 0);
+ if (priv->response->len)
+ g_byte_array_remove_range (priv->response, 0, priv->response->len);
mm_serial_port_close (self);
return FALSE;
}
if (condition & G_IO_ERR) {
- g_string_truncate (priv->response, 0);
+ if (priv->response->len)
+ g_byte_array_remove_range (priv->response, 0, priv->response->len);
return TRUE;
}
@@ -745,14 +644,14 @@ data_available (GIOChannel *source,
if (bytes_read > 0) {
serial_debug (self, "<--", buf, bytes_read);
- g_string_append_len (priv->response, buf, bytes_read);
+ g_byte_array_append (priv->response, (const guint8 *) buf, bytes_read);
}
- /* Make sure the string doesn't grow too long */
+ /* Make sure the response doesn't grow too long */
if (priv->response->len > SERIAL_BUF_SIZE) {
/* Notify listeners and then trim the buffer */
g_signal_emit_by_name (self, "buffer-full", priv->response);
- g_string_erase (priv->response, 0, (SERIAL_BUF_SIZE / 2));
+ g_byte_array_remove_range (priv->response, 0, (SERIAL_BUF_SIZE / 2));
}
if (parse_response (self, priv->response, &err))
@@ -843,7 +742,8 @@ mm_serial_port_open (MMSerialPort *self, GError **error)
return FALSE;
}
- if (!config_fd (self, error)) {
+ g_warn_if_fail (MM_SERIAL_PORT_GET_CLASS (self)->config_fd);
+ if (!MM_SERIAL_PORT_GET_CLASS (self)->config_fd (self, priv->fd, error)) {
close (priv->fd);
priv->fd = -1;
return FALSE;
@@ -875,6 +775,7 @@ void
mm_serial_port_close (MMSerialPort *self)
{
MMSerialPortPrivate *priv;
+ int i;
g_return_if_fail (MM_IS_SERIAL_PORT (self));
@@ -907,14 +808,24 @@ mm_serial_port_close (MMSerialPort *self)
close (priv->fd);
priv->fd = -1;
}
+
+ /* Clear the command queue */
+ for (i = 0; i < g_queue_get_length (priv->queue); i++) {
+ MMQueueData *item = g_queue_peek_nth (priv->queue, i);
+
+ g_byte_array_free (item->command, TRUE);
+ g_slice_free (MMQueueData, item);
+ }
+ g_queue_clear (priv->queue);
}
static void
internal_queue_command (MMSerialPort *self,
- const char *command,
+ GByteArray *command,
+ gboolean take_command,
gboolean cached,
guint32 timeout_seconds,
- MMSerialResponseFn callback,
+ GCallback callback,
gpointer user_data)
{
MMSerialPortPrivate *priv = MM_SERIAL_PORT_GET_PRIVATE (self);
@@ -924,7 +835,12 @@ internal_queue_command (MMSerialPort *self,
g_return_if_fail (command != NULL);
info = g_slice_new0 (MMQueueData);
- info->command = g_strdup (command);
+ if (take_command)
+ info->command = command;
+ else {
+ info->command = g_byte_array_sized_new (command->len);
+ g_byte_array_append (info->command, command->data, command->len);
+ }
info->cached = cached;
info->timeout = timeout_seconds;
info->callback = callback;
@@ -932,7 +848,7 @@ internal_queue_command (MMSerialPort *self,
/* Clear the cached value for this command if not asking for cached value */
if (!cached)
- mm_serial_port_set_cached_reply (self, command, NULL);
+ mm_serial_port_set_cached_reply (self, info->command, NULL);
g_queue_push_tail (priv->queue, info);
@@ -942,22 +858,24 @@ internal_queue_command (MMSerialPort *self,
void
mm_serial_port_queue_command (MMSerialPort *self,
- const char *command,
+ GByteArray *command,
+ gboolean take_command,
guint32 timeout_seconds,
- MMSerialResponseFn callback,
+ GCallback callback,
gpointer user_data)
{
- internal_queue_command (self, command, FALSE, timeout_seconds, callback, user_data);
+ internal_queue_command (self, command, take_command, FALSE, timeout_seconds, callback, user_data);
}
void
mm_serial_port_queue_command_cached (MMSerialPort *self,
- const char *command,
+ GByteArray *command,
+ gboolean take_command,
guint32 timeout_seconds,
- MMSerialResponseFn callback,
+ GCallback callback,
gpointer user_data)
{
- internal_queue_command (self, command, TRUE, timeout_seconds, callback, user_data);
+ internal_queue_command (self, command, take_command, TRUE, timeout_seconds, callback, user_data);
}
typedef struct {
@@ -1133,12 +1051,54 @@ mm_serial_port_new (const char *name, MMPortType ptype)
NULL));
}
+static gboolean
+ba_equal (gconstpointer v1, gconstpointer v2)
+{
+ const GByteArray *a = v1;
+ const GByteArray *b = v2;
+
+ if (!a && b)
+ return -1;
+ else if (a && !b)
+ return 1;
+ else if (!a && !b)
+ return 0;
+
+ g_assert (a && b);
+ if (a->len < b->len)
+ return -1;
+ else if (a->len > b->len)
+ return 1;
+
+ g_assert (a->len == b->len);
+ return !memcmp (a->data, b->data, a->len);
+}
+
+static guint
+ba_hash (gconstpointer v)
+{
+ /* 31 bit hash function */
+ const GByteArray *array = v;
+ guint32 i, h = (const signed char) array->data[0];
+
+ for (i = 1; i < array->len; i++)
+ h = (h << 5) - h + (const signed char) array->data[i];
+
+ return h;
+}
+
+static void
+ba_free (gpointer v)
+{
+ g_byte_array_free ((GByteArray *) v, TRUE);
+}
+
static void
mm_serial_port_init (MMSerialPort *self)
{
MMSerialPortPrivate *priv = MM_SERIAL_PORT_GET_PRIVATE (self);
- priv->reply_cache = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
+ priv->reply_cache = g_hash_table_new_full (ba_hash, ba_equal, ba_free, ba_free);
priv->fd = -1;
priv->baud = 57600;
@@ -1148,8 +1108,7 @@ mm_serial_port_init (MMSerialPort *self)
priv->send_delay = 1000;
priv->queue = g_queue_new ();
- priv->command = g_string_new_len ("AT", SERIAL_BUF_SIZE);
- priv->response = g_string_sized_new (SERIAL_BUF_SIZE);
+ priv->response = g_byte_array_sized_new (500);
}
static void
@@ -1223,24 +1182,8 @@ finalize (GObject *object)
MMSerialPortPrivate *priv = MM_SERIAL_PORT_GET_PRIVATE (self);
g_hash_table_destroy (priv->reply_cache);
+ g_byte_array_free (priv->response, TRUE);
g_queue_free (priv->queue);
- g_string_free (priv->command, TRUE);
- g_string_free (priv->response, TRUE);
-
- while (priv->unsolicited_msg_handlers) {
- MMUnsolicitedMsgHandler *handler = (MMUnsolicitedMsgHandler *) priv->unsolicited_msg_handlers->data;
-
- if (handler->notify)
- handler->notify (handler->user_data);
-
- g_regex_unref (handler->regex);
- g_slice_free (MMUnsolicitedMsgHandler, handler);
- priv->unsolicited_msg_handlers = g_slist_delete_link (priv->unsolicited_msg_handlers,
- priv->unsolicited_msg_handlers);
- }
-
- if (priv->response_parser_notify)
- priv->response_parser_notify (priv->response_parser_user_data);
G_OBJECT_CLASS (mm_serial_port_parent_class)->finalize (object);
}
@@ -1258,6 +1201,8 @@ mm_serial_port_class_init (MMSerialPortClass *klass)
object_class->dispose = dispose;
object_class->finalize = finalize;
+ klass->config_fd = real_config_fd;
+
/* Properties */
g_object_class_install_property
(object_class, PROP_BAUD,
diff --git a/src/mm-serial-port.h b/src/mm-serial-port.h
index dd5a6689..6835d8bf 100644
--- a/src/mm-serial-port.h
+++ b/src/mm-serial-port.h
@@ -39,19 +39,6 @@
typedef struct _MMSerialPort MMSerialPort;
typedef struct _MMSerialPortClass MMSerialPortClass;
-typedef gboolean (*MMSerialResponseParserFn) (gpointer user_data,
- GString *response,
- GError **error);
-
-typedef void (*MMSerialUnsolicitedMsgFn) (MMSerialPort *port,
- GMatchInfo *match_info,
- gpointer user_data);
-
-typedef void (*MMSerialResponseFn) (MMSerialPort *port,
- GString *response,
- GError *error,
- gpointer user_data);
-
typedef void (*MMSerialFlashFn) (MMSerialPort *port,
GError *error,
gpointer user_data);
@@ -63,48 +50,72 @@ struct _MMSerialPort {
struct _MMSerialPortClass {
MMPortClass parent;
+<<<<<<< HEAD
+ /* Called for subclasses to parse unsolicited responses. If any recognized
+ * unsolicited response is found, it should be removed from the 'response'
+ * byte array before returning.
+ */
+ void (*parse_unsolicited) (MMSerialPort *self, GByteArray *response);
+
+ /* Called to parse the device's response to a command or determine if the
+ * response was an error response. If the response indicates an error, an
+ * appropriate error should be returned in the 'error' argument. The
+ * function should return FALSE if there is not enough data yet to determine
+ * the device's reply (whether success *or* error), and should return TRUE
+ * when the device's response has been recognized and parsed.
+ */
+ gboolean (*parse_response) (MMSerialPort *self,
+ GByteArray *response,
+ GError **error);
+
+ /* Called after parsing to allow the command response to be delivered to
+ * it's callback to be handled.
+ */
+ void (*handle_response) (MMSerialPort *self,
+ GByteArray *response,
+ GError *error,
+ GCallback callback,
+ gpointer callback_data);
+
+ /* Called to configure the serial port after it's opened. On error, should
+ * return FALSE and set 'error' as appropriate.
+ */
+ gboolean (*config_fd) (MMSerialPort *self, int fd, GError **error);
+
/* Signals */
- void (*buffer_full) (MMSerialPort *port, const GString *buffer);
+ void (*buffer_full) (MMSerialPort *port, const GByteArray *buffer);
};
GType mm_serial_port_get_type (void);
MMSerialPort *mm_serial_port_new (const char *name, MMPortType ptype);
-void mm_serial_port_add_unsolicited_msg_handler (MMSerialPort *self,
- GRegex *regex,
- MMSerialUnsolicitedMsgFn callback,
- gpointer user_data,
- GDestroyNotify notify);
-
-void mm_serial_port_set_response_parser (MMSerialPort *self,
- MMSerialResponseParserFn fn,
- gpointer user_data,
- GDestroyNotify notify);
-
gboolean mm_serial_port_is_open (MMSerialPort *self);
gboolean mm_serial_port_open (MMSerialPort *self,
GError **error);
void mm_serial_port_close (MMSerialPort *self);
+
+gboolean mm_serial_port_flash (MMSerialPort *self,
+ guint32 flash_time,
+ MMSerialFlashFn callback,
+ gpointer user_data);
+void mm_serial_port_flash_cancel (MMSerialPort *self);
+
void mm_serial_port_queue_command (MMSerialPort *self,
- const char *command,
+ GByteArray *command,
+ gboolean take_command,
guint32 timeout_seconds,
- MMSerialResponseFn callback,
+ GCallback callback,
gpointer user_data);
void mm_serial_port_queue_command_cached (MMSerialPort *self,
- const char *command,
+ GByteArray *command,
+ gboolean take_command,
guint32 timeout_seconds,
- MMSerialResponseFn callback,
+ GCallback callback,
gpointer user_data);
-gboolean mm_serial_port_flash (MMSerialPort *self,
- guint32 flash_time,
- MMSerialFlashFn callback,
- gpointer user_data);
-void mm_serial_port_flash_cancel (MMSerialPort *self);
-
#endif /* MM_SERIAL_PORT_H */