[PATCH] plugins: rm unecessary sleep from ril plugin
by Tony Espy
---
plugins/ril.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/plugins/ril.c b/plugins/ril.c
index 8ccf01a..7820be4 100644
--- a/plugins/ril.c
+++ b/plugins/ril.c
@@ -145,7 +145,6 @@ static void ril_radio_state_changed(struct ril_msg *message, gpointer user_data)
if (rd->ofono_online) {
ofono_error("%s: radio self-powered off!",
__func__);
- sleep(5);
exit(1);
}
break;
--
2.1.4
5 years, 1 month
[PATCH 2/2] build: add support for test-rilmodem-sms
by Tony Espy
---
Makefile.am | 14 +++++++++++++-
1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/Makefile.am b/Makefile.am
index fba25ba..1cdfc1f 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -740,7 +740,8 @@ unit_objects =
unit_tests = unit/test-common unit/test-util unit/test-idmap \
unit/test-simutil unit/test-stkutil \
unit/test-sms unit/test-cdmasms \
- unit/test-rilmodem-cs
+ unit/test-rilmodem-cs \
+ unit/test-rilmodem-sms
noinst_PROGRAMS = $(unit_tests) \
unit/test-sms-root unit/test-mux unit/test-caif
@@ -801,6 +802,17 @@ unit_test_rilmodem_cs_LDADD = gdbus/libgdbus-internal.la $(builtin_libadd) \
@GLIB_LIBS@ @DBUS_LIBS@ -ldl
unit_objects += $(unit_test_rilmodem_cs_OBJECTS)
+unit_test_rilmodem_sms_SOURCES = unit/test-rilmodem-sms.c $(gril_sources) \
+ src/log.c src/common.c src/util.c \
+ gatchat/ringbuffer.h gatchat/ringbuffer.c \
+ drivers/rilmodem/sms.c \
+ unit/rilmodem-test-server.h \
+ unit/rilmodem-test-server.c \
+ src/simutil.c
+unit_test_rilmodem_sms_LDADD = gdbus/libgdbus-internal.la $(builtin_libadd) \
+ @GLIB_LIBS@ @DBUS_LIBS@ -ldl
+unit_objects += $(unit_test_rilmodem_sms_OBJECTS)
+
TESTS = $(unit_tests)
if TOOLS
--
2.1.4
5 years, 1 month
[PATCH 1/2] unit: add new test-rilmodem-sms
by Tony Espy
---
unit/rilmodem-test-server.c | 198 ++++++++++++++++++++++++++++++++
unit/rilmodem-test-server.h | 40 +++++++
unit/test-rilmodem-sms.c | 267 ++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 505 insertions(+)
create mode 100644 unit/rilmodem-test-server.c
create mode 100644 unit/rilmodem-test-server.h
create mode 100644 unit/test-rilmodem-sms.c
diff --git a/unit/rilmodem-test-server.c b/unit/rilmodem-test-server.c
new file mode 100644
index 0000000..a09e22c
--- /dev/null
+++ b/unit/rilmodem-test-server.c
@@ -0,0 +1,198 @@
+/*
+ *
+ * oFono - Open Source Telephony
+ *
+ * Copyright (C) 2015 Canonical Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#define _GNU_SOURCE
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <unistd.h>
+
+#include <ofono/types.h>
+
+#include <gril.h>
+
+#include "rilmodem-test-server.h"
+
+#define MAX_REQUEST_SIZE 4096
+
+static int server_sk;
+static ConnectFunc connect_func;
+static GIOChannel *server_io;
+static const struct rilmodem_test_data *rtd;
+
+/* Warning: length is stored in network order */
+struct rsp_hdr {
+ uint32_t length;
+ uint32_t unsolicited;
+ uint32_t serial;
+ uint32_t error;
+};
+
+static gboolean read_server(gpointer data)
+{
+ GIOStatus status;
+ gsize offset, rbytes, wbytes;
+ gchar *buf, *bufp;
+ uint32_t req_serial;
+ struct rsp_hdr rsp;
+
+ buf = g_malloc0(MAX_REQUEST_SIZE);
+
+ status = g_io_channel_read_chars(server_io, buf, MAX_REQUEST_SIZE,
+ &rbytes, NULL);
+ g_assert(status == G_IO_STATUS_NORMAL);
+
+ g_assert(rbytes == rtd->req_size);
+
+ /* validate len, and request_id */
+ g_assert(!memcmp(buf, rtd->req_data, (sizeof(uint32_t) * 2)));
+
+ /*
+ * header: size (uint32), reqid (uin32), serial (uint32)
+ * header size == 16 ( excludes sizeof(size) )
+ */
+
+ /* advance past request_no */
+ bufp = buf + (sizeof(uint32_t) * 2);
+
+ req_serial = (uint32_t) *bufp;
+
+ /* advance past serial_no */
+ bufp += sizeof(uint32_t);
+
+ /* validate the rest of the parcel... */
+ offset = (sizeof(uint32_t) * 3);
+ g_assert(!memcmp(bufp, rtd->req_data + offset,
+ rtd->req_size - offset));
+
+ /* Length does not include the length field. Network order. */
+ rsp.length = htonl(sizeof(rsp) - sizeof(rsp.length) + rtd->rsp_size);
+ rsp.unsolicited = 0;
+ rsp.serial = req_serial;
+ rsp.error = rtd->rsp_error;
+
+ /* copy header */
+ memcpy(buf, &rsp, sizeof(rsp));
+
+ if (rtd->rsp_size) {
+ bufp = buf + sizeof(rsp);
+
+ memcpy(bufp, rtd->rsp_data, rtd->rsp_size);
+ }
+
+
+ status = g_io_channel_write_chars(server_io,
+ buf,
+ sizeof(rsp) + rtd->rsp_size,
+ &wbytes, NULL);
+
+ /* FIXME: assert wbytes is correct */
+
+ g_assert(status == G_IO_STATUS_NORMAL);
+
+ g_free(buf);
+ g_io_channel_unref(server_io);
+
+ return FALSE;
+}
+
+static gboolean on_socket_connected(GIOChannel *chan, GIOCondition cond,
+ gpointer data)
+{
+ struct sockaddr saddr;
+ unsigned int len = sizeof(saddr);
+ int fd;
+ GIOStatus status;
+
+ g_assert(cond == G_IO_IN);
+
+ fd = accept(server_sk, &saddr, &len);
+ g_assert(fd != -1);
+
+ server_io = g_io_channel_unix_new(fd);
+ g_assert(server_io != NULL);
+
+ if (connect_func)
+ connect_func(data);
+
+ status = g_io_channel_set_encoding(server_io, NULL, NULL);
+ g_assert(status == G_IO_STATUS_NORMAL);
+
+ g_io_channel_set_buffered(server_io, FALSE);
+ g_io_channel_set_close_on_unref(server_io, TRUE);
+
+ g_idle_add(read_server, data);
+
+ return FALSE;
+}
+
+void rilmodem_test_server_close(void)
+{
+ g_assert(server_sk);
+ close(server_sk);
+ server_sk = 0;
+}
+
+void rilmodem_test_server_create(ConnectFunc connect,
+ const struct rilmodem_test_data *test_data,
+ void *data)
+{
+ GIOChannel *io;
+ struct sockaddr_un addr;
+ int retval;
+
+ g_assert(server_sk == 0);
+
+ connect_func = connect;
+ rtd = test_data;
+
+ server_sk = socket(AF_UNIX, SOCK_STREAM, 0);
+ g_assert(server_sk);
+
+ memset(&addr, 0, sizeof(addr));
+ addr.sun_family = AF_UNIX;
+ strncpy(addr.sun_path, RIL_SERVER_SOCK_PATH, sizeof(addr.sun_path) - 1);
+
+ /* Unlink any existing socket for this session */
+ unlink(addr.sun_path);
+
+ retval = bind(server_sk, (struct sockaddr *) &addr, sizeof(addr));
+ g_assert(retval >= 0);
+
+ retval = listen(server_sk, 0);
+ g_assert(retval >= 0);
+
+ io = g_io_channel_unix_new(server_sk);
+ g_assert(io != NULL);
+
+ g_io_channel_set_close_on_unref(io, TRUE);
+ g_io_channel_set_flags(io, G_IO_FLAG_NONBLOCK, NULL);
+
+ g_io_add_watch_full(io, G_PRIORITY_DEFAULT,
+ G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
+ on_socket_connected, data, NULL);
+
+ g_io_channel_unref(io);
+}
diff --git a/unit/rilmodem-test-server.h b/unit/rilmodem-test-server.h
new file mode 100644
index 0000000..ba8b43c
--- /dev/null
+++ b/unit/rilmodem-test-server.h
@@ -0,0 +1,40 @@
+/*
+ *
+ * oFono - Open Source Telephony
+ *
+ * Copyright (C) 2015 Canonical Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#define RIL_SERVER_SOCK_PATH "/tmp/unittestril"
+
+struct rilmodem_test_data {
+ const unsigned char *req_data;
+
+ const size_t req_size;
+
+ uint32_t rsp_error;
+ const unsigned char *rsp_data;
+ const size_t rsp_size;
+};
+
+typedef void (*ConnectFunc)(void *data);
+
+void rilmodem_test_server_close(void);
+
+void rilmodem_test_server_create(ConnectFunc connect,
+ const struct rilmodem_test_data *test_data,
+ void *data);
diff --git a/unit/test-rilmodem-sms.c b/unit/test-rilmodem-sms.c
new file mode 100644
index 0000000..0e3bff3
--- /dev/null
+++ b/unit/test-rilmodem-sms.c
@@ -0,0 +1,267 @@
+/*
+ *
+ * oFono - Open Source Telephony
+ *
+ * Copyright (C) 2015 Canonical Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#define _GNU_SOURCE
+#include <assert.h>
+#include <errno.h>
+#include <glib.h>
+#include <stdio.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <unistd.h>
+
+#include <ofono/modem.h>
+#include <ofono/types.h>
+#include <ofono/sms.h>
+#include <gril.h>
+
+#include "common.h"
+#include "ril_constants.h"
+#include "rilmodem-test-server.h"
+
+static GMainLoop *mainloop;
+
+static const struct ofono_sms_driver *smsdriver;
+
+struct rilmodem_sms_data {
+ GRil *ril;
+ struct ofono_modem *modem;
+ gconstpointer test_data;
+ struct ofono_sms *sms;
+};
+
+typedef gboolean (*StartFunc)(gpointer data);
+
+struct sms_data {
+ StartFunc start_func;
+ const struct ofono_phone_number ph;
+ gint param_int1;
+ gint param_int2;
+
+ struct rilmodem_test_data rtd;
+ enum ofono_error_type error_type;
+ gint cb_int1;
+ gint cb_int2;
+};
+
+static void sca_query_callback(const struct ofono_error *error,
+ const struct ofono_phone_number *ph,
+ gpointer data)
+{
+ struct rilmodem_sms_data *rsd = data;
+ const struct sms_data *sd = rsd->test_data;
+
+ g_assert(error->type == sd->error_type);
+
+ if (error->type == OFONO_ERROR_TYPE_NO_ERROR) {
+ g_assert(ph->type == sd->ph.type);
+ g_assert(strcmp(ph->number, sd->ph.number) == 0);
+ }
+
+ g_main_loop_quit(mainloop);
+}
+
+static gboolean trigger_sca_query(gpointer data)
+{
+ struct rilmodem_sms_data *rsd = data;
+
+ g_assert(smsdriver->sca_query != NULL);
+ smsdriver->sca_query(rsd->sms, sca_query_callback, rsd);
+
+ return FALSE;
+}
+
+/* RIL_REQUEST_GET_SMSC_ADDRESS */
+static const guchar req_get_smsc_address_parcel_1[] = {
+ 0x00, 0x00, 0x00, 0x08, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+
+/*
+ * RIL_REQUEST_GET_SMSC_ADDRESS reply with the following data:
+ *
+ * {type=145,number=34607003110}
+ */
+static const guchar rsp_get_smsc_address_data_1[] = {
+ 0x12, 0x00, 0x00, 0x00, 0x22, 0x00, 0x2b, 0x00, 0x33, 0x00, 0x34, 0x00,
+ 0x36, 0x00, 0x30, 0x00, 0x37, 0x00, 0x30, 0x00, 0x30, 0x00, 0x33, 0x00,
+ 0x31, 0x00, 0x31, 0x00, 0x30, 0x00, 0x22, 0x00, 0x2c, 0x00, 0x31, 0x00,
+ 0x34, 0x00, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+static const struct sms_data testdata_sca_query_valid_1 = {
+ .start_func = trigger_sca_query,
+ .ph = { .number = "34607003110", .type = 145 },
+ .rtd = {
+ .req_data = req_get_smsc_address_parcel_1,
+ .req_size = sizeof(req_get_smsc_address_parcel_1),
+ .rsp_data = rsp_get_smsc_address_data_1,
+ .rsp_size = sizeof(rsp_get_smsc_address_data_1),
+ .rsp_error = RIL_E_SUCCESS,
+ },
+ .cb_int1 = 1,
+ .error_type = OFONO_ERROR_TYPE_NO_ERROR,
+};
+
+/* TODO: Did these get removed upstream? */
+
+/* Declarations && Re-implementations of core functions. */
+void ril_sms_exit(void);
+void ril_sms_init(void);
+
+struct ofono_sms {
+ void *driver_data;
+};
+
+struct ofono_sms *ofono_sms_create(struct ofono_modem *modem,
+ unsigned int vendor,
+ const char *driver,
+ void *data)
+{
+ struct rilmodem_sms_data *rsd = data;
+ struct ofono_sms *sms = g_new0(struct ofono_sms, 1);
+ int retval;
+
+ retval = smsdriver->probe(sms, OFONO_RIL_VENDOR_AOSP, rsd->ril);
+ g_assert(retval == 0);
+
+ return sms;
+}
+
+int ofono_sms_driver_register(const struct ofono_sms_driver *d)
+{
+ if (smsdriver == NULL)
+ smsdriver = d;
+
+ return 0;
+}
+
+void ofono_sms_set_data(struct ofono_sms *sms, void *data)
+{
+ sms->driver_data = data;
+}
+
+void *ofono_sms_get_data(struct ofono_sms *sms)
+{
+ return sms->driver_data;
+}
+
+void ofono_sms_register(struct ofono_sms *sms)
+{
+ ;
+}
+
+void ofono_sms_driver_unregister(const struct ofono_sms_driver *d)
+{
+ ;
+}
+
+void ofono_sms_deliver_notify(struct ofono_sms *sms, const unsigned char *pdu,
+ int len, int tpdu_len)
+{
+ ;
+}
+
+void ofono_sms_status_notify(struct ofono_sms *sms, const unsigned char *pdu,
+ int len, int tpdu_len)
+{
+ ;
+}
+
+static void server_connect_cb(gpointer data)
+{
+ struct rilmodem_sms_data *rsd = data;
+ const struct sms_data *sd = rsd->test_data;
+
+ /* This causes local impl of _create() to call driver's probe func. */
+ rsd->sms = ofono_sms_create(NULL, OFONO_RIL_VENDOR_AOSP,
+ "rilmodem", rsd);
+
+ /* add_idle doesn't work, read blocks main loop!!! */
+ g_assert(sd->start_func(rsd) == FALSE);
+}
+
+#if BYTE_ORDER == LITTLE_ENDIAN
+
+/*
+ * This unit test:
+ * - does some test data setup
+ * - configures a dummy server socket
+ * - creates a new gril client instance
+ * - triggers a connect to the dummy
+ * server socket
+ * - starts a mainloop
+ */
+static void test_sms_func(gconstpointer data)
+{
+ const struct sms_data *sd = data;
+ struct rilmodem_sms_data *rsd;
+
+ ril_sms_init();
+
+ rsd = g_new0(struct rilmodem_sms_data, 1);
+
+ rsd->test_data = sd;
+
+ rilmodem_test_server_create(&server_connect_cb, &sd->rtd, rsd);
+
+ rsd->ril = g_ril_new(RIL_SERVER_SOCK_PATH, OFONO_RIL_VENDOR_AOSP);
+ g_assert(rsd->ril != NULL);
+
+ mainloop = g_main_loop_new(NULL, FALSE);
+
+ g_main_loop_run(mainloop);
+ g_main_loop_unref(mainloop);
+
+ smsdriver->remove(rsd->sms);
+ g_ril_unref(rsd->ril);
+ g_free(rsd);
+
+ rilmodem_test_server_close();
+
+ ril_sms_exit();
+}
+
+#endif
+
+int main(int argc, char **argv)
+{
+ g_test_init(&argc, &argv, NULL);
+
+/*
+ * As all our architectures are little-endian except for
+ * PowerPC, and the Binder wire-format differs slightly
+ * depending on endian-ness, the following guards against test
+ * failures when run on PowerPC.
+ */
+#if BYTE_ORDER == LITTLE_ENDIAN
+ g_test_add_data_func("/testrilmodemsms/sca_query/valid/1",
+ &testdata_sca_query_valid_1,
+ test_sms_func);
+
+#endif
+ return g_test_run();
+}
--
2.1.4
5 years, 1 month
[PATCH] emulator: fail when SCO connection setup fails
by Simon Fels
---
src/emulator.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/src/emulator.c b/src/emulator.c
index 4c81a39..0a5c67e 100644
--- a/src/emulator.c
+++ b/src/emulator.c
@@ -1683,6 +1683,7 @@ int ofono_emulator_start_codec_negotiation(struct ofono_emulator *em,
{
char buf[64];
unsigned char codec;
+ int err;
if (em == NULL)
return -EINVAL;
@@ -1707,7 +1708,11 @@ int ofono_emulator_start_codec_negotiation(struct ofono_emulator *em,
* already have a negotiated codec we can proceed here
* without doing any negotiation again.
*/
- ofono_handsfree_card_connect_sco(em->card);
+ err = ofono_handsfree_card_connect_sco(em->card);
+ if (err < 0) {
+ ofono_error("SCO connection failed");
+ return err;
+ }
return 0;
}
--
2.5.0
5 years, 1 month
[PATCH] gobi: Add missing _GNU_SOURCE
by Petr Vorel
as we're using O_CLOEXEC
Signed-off-by: Petr Vorel <petr.vorel(a)gmail.com>
---
plugins/gobi.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/plugins/gobi.c b/plugins/gobi.c
index 4daa459..061ee04 100644
--- a/plugins/gobi.c
+++ b/plugins/gobi.c
@@ -23,6 +23,7 @@
#include <config.h>
#endif
+#define _GNU_SOURCE
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
--
1.8.0
5 years, 2 months
[PATCH 1/2] configure.ac: rewrite support for backtrace detection
by Petr Vorel
Signed-off-by: Petr Vorel <petr.vorel(a)gmail.com>
---
configure.ac | 4 ++++
src/log.c | 8 ++++----
2 files changed, 8 insertions(+), 4 deletions(-)
diff --git a/configure.ac b/configure.ac
index b8d42c8..b6183a1 100644
--- a/configure.ac
+++ b/configure.ac
@@ -245,3 +245,7 @@ AC_DEFINE_UNQUOTED(CONFIGDIR, "${configdir}",
AC_OUTPUT(Makefile include/version.h src/ofono.service ofono.pc \
dundee/dundee.service)
+
+dnl Check for backtrace() support
+AC_CHECK_HEADERS(execinfo.h)
+AC_CHECK_FUNCS(backtrace)
diff --git a/src/log.c b/src/log.c
index 6331b0d..0d55d6e 100644
--- a/src/log.c
+++ b/src/log.c
@@ -30,7 +30,7 @@
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
-#ifdef __GLIBC__
+#ifdef HAVE_EXECINFO_H
#include <execinfo.h>
#endif
#include <dlfcn.h>
@@ -115,7 +115,7 @@ void ofono_debug(const char *format, ...)
va_end(ap);
}
-#ifdef __GLIBC__
+#ifdef HAVE_BACKTRACE
static void print_backtrace(unsigned int offset)
{
void *frames[99];
@@ -309,7 +309,7 @@ int __ofono_log_init(const char *program, const char *debug,
if (detach == FALSE)
option |= LOG_PERROR;
-#ifdef __GLIBC__
+#ifdef HAVE_BACKTRACE
signal_setup(signal_handler);
#endif
@@ -326,7 +326,7 @@ void __ofono_log_cleanup(void)
closelog();
-#ifdef __GLIBC__
+#ifdef HAVE_BACKTRACE
signal_setup(SIG_DFL);
#endif
--
2.6.2
5 years, 2 months
[PATCH 0/7] Support for mtk modems
by Alfonso Sanchez-Beato
This patch series add support for MediaTek modems. The mtkmodem driver
is heavily based on rilmodem.
Alfonso Sanchez-Beato (7):
gitignore: Ignore rilmodem-cs test binary
include: Add flag for drivers that watch SIM state
modem: Add flag for drivers that watch SIM state
rilmodem: Export functions needed by mtkmodem
mtkmodem: Add mtkmodem driver
mtk: Plugin for mtkmodems
build: Add mtkmodem driver and mtk plugin
.gitignore | 1 +
Makefile.am | 19 +
drivers/mtkmodem/gprs.c | 188 ++++
drivers/mtkmodem/mtk_constants.h | 84 ++
drivers/mtkmodem/mtkmodem.c | 58 ++
drivers/mtkmodem/mtkmodem.h | 32 +
drivers/mtkmodem/mtkreply.c | 98 +++
drivers/mtkmodem/mtkreply.h | 43 +
drivers/mtkmodem/mtkrequest.c | 163 ++++
drivers/mtkmodem/mtkrequest.h | 143 ++++
drivers/mtkmodem/mtksettings.c | 261 ++++++
drivers/mtkmodem/mtksettings.h | 43 +
drivers/mtkmodem/mtkunsol.c | 199 +++++
drivers/mtkmodem/mtkunsol.h | 59 ++
drivers/mtkmodem/mtkutil.c | 143 ++++
drivers/mtkmodem/mtkutil.h | 47 +
drivers/mtkmodem/radio-settings.c | 193 +++++
drivers/mtkmodem/voicecall.c | 155 ++++
drivers/rilmodem/radio-settings.c | 21 +-
drivers/rilmodem/radio-settings.h | 46 +
drivers/rilmodem/voicecall.c | 18 +-
drivers/rilmodem/voicecall.h | 4 +
include/modem.h | 4 +
plugins/mtk.c | 1704 +++++++++++++++++++++++++++++++++++++
src/modem.c | 38 +-
25 files changed, 3735 insertions(+), 29 deletions(-)
create mode 100644 drivers/mtkmodem/gprs.c
create mode 100644 drivers/mtkmodem/mtk_constants.h
create mode 100644 drivers/mtkmodem/mtkmodem.c
create mode 100644 drivers/mtkmodem/mtkmodem.h
create mode 100644 drivers/mtkmodem/mtkreply.c
create mode 100644 drivers/mtkmodem/mtkreply.h
create mode 100644 drivers/mtkmodem/mtkrequest.c
create mode 100644 drivers/mtkmodem/mtkrequest.h
create mode 100644 drivers/mtkmodem/mtksettings.c
create mode 100644 drivers/mtkmodem/mtksettings.h
create mode 100644 drivers/mtkmodem/mtkunsol.c
create mode 100644 drivers/mtkmodem/mtkunsol.h
create mode 100644 drivers/mtkmodem/mtkutil.c
create mode 100644 drivers/mtkmodem/mtkutil.h
create mode 100644 drivers/mtkmodem/radio-settings.c
create mode 100644 drivers/mtkmodem/voicecall.c
create mode 100644 drivers/rilmodem/radio-settings.h
create mode 100644 plugins/mtk.c
--
2.5.0
5 years, 2 months
Udevng plugin seems to fail sometimes?
by John Ernberg
Hi,
I am using oFono in an embedded environment, and I seem to have
encountered a problem with the udevng plugin. It seems that the
udev_monitor sometimes fails to init, so when the modem in the
environment has started, oFono cannot find it. I can see the modem with
'lsusb' if I log in to the embedded system, but when I list the modems
in oFono I get an empty list.
I have verified that when this happens udev is running in the system,
and that a sane file descriptor is received when creating the IOChannel
used for the monitor. Yet, the channel is closed almost immediately. My
best guess is that udev sends some sort of HUP.
oFono is started automatically by systemd, but in a much later target
than udev.
The issue appears too sporadically to be able to debug this properly, so
I am wondering if anyone else has seen this issue?
While trying to understand myself exactly what is going on I haven't
managed to come across anything on google, or in other programs' source
code, suggesting that the setup code for the monitor is doing something
wrong. So, I also wonder if anyone has any suggestions on what kind of
traces I shall try to print to gain an understanding of what is happening?
Thank you in advance for any assistance.
Best regards // John Ernberg
5 years, 2 months
[PATCH 1/3] include: Add initial attach APN type
by Alfonso Sanchez-Beato
The initial attach APN is used in LTE for signalling and to be able to
register to the network (default EPS bearer). Some operators request
users to configure this APN, so we need to add this APN type to ofono.
---
include/gprs-context.h | 1 +
include/gprs.h | 5 +++++
2 files changed, 6 insertions(+)
diff --git a/include/gprs-context.h b/include/gprs-context.h
index ed27e66..9dae5f4 100644
--- a/include/gprs-context.h
+++ b/include/gprs-context.h
@@ -46,6 +46,7 @@ enum ofono_gprs_context_type {
OFONO_GPRS_CONTEXT_TYPE_MMS,
OFONO_GPRS_CONTEXT_TYPE_WAP,
OFONO_GPRS_CONTEXT_TYPE_IMS,
+ OFONO_GPRS_CONTEXT_TYPE_IA,
};
enum ofono_gprs_auth_method {
diff --git a/include/gprs.h b/include/gprs.h
index 6c46d18..03849aa 100644
--- a/include/gprs.h
+++ b/include/gprs.h
@@ -27,6 +27,7 @@ extern "C" {
#endif
#include <ofono/types.h>
+#include <ofono/gprs-context.h>
struct ofono_gprs;
struct ofono_gprs_context;
@@ -45,6 +46,10 @@ struct ofono_gprs_driver {
ofono_gprs_cb_t cb, void *data);
void (*attached_status)(struct ofono_gprs *gprs,
ofono_gprs_status_cb_t cb, void *data);
+ void (*set_ia_apn)(struct ofono_gprs *gprs, const char *apn,
+ enum ofono_gprs_proto proto, const char *user,
+ const char *passwd, const char *mccmnc,
+ ofono_gprs_cb_t cb, void *data);
};
enum gprs_suspend_cause {
--
2.5.0
5 years, 2 months
[PATCH 1/2 v3] unit: add new test rilmodem-cs
by Tony Espy
This commit adds a new style of build-time/unit test to
rilmodem. These tests setup a dummy server socket and
attach a gril instance to it. This allows rilmodem
call-settings atom functions to be tested directly,
validating request parcels received by the server-side,
and callbacks that happen in response to canned responses
sent by the server-side.
---
unit/test-rilmodem-cs.c | 694 ++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 694 insertions(+)
create mode 100644 unit/test-rilmodem-cs.c
diff --git a/unit/test-rilmodem-cs.c b/unit/test-rilmodem-cs.c
new file mode 100644
index 0000000..6d16286
--- /dev/null
+++ b/unit/test-rilmodem-cs.c
@@ -0,0 +1,694 @@
+/*
+ *
+ * oFono - Open Source Telephony
+ *
+ * Copyright (C) 2015 Canonical Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#define _GNU_SOURCE
+#include <assert.h>
+#include <errno.h>
+#include <glib.h>
+#include <stdio.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <unistd.h>
+
+#include <ofono/modem.h>
+#include <ofono/types.h>
+#include <ofono/call-settings.h>
+#include <gril.h>
+
+#include "common.h"
+#include "ril_constants.h"
+
+#define MAX_REQUEST_SIZE 4096
+
+static GMainLoop *mainloop;
+
+static const struct ofono_call_settings_driver *csdriver;
+
+struct rilmodemcs_data {
+ GRil *ril;
+ int sk;
+ gint server_watch;
+ GIOChannel *server_io;
+ struct ofono_modem *modem;
+ gconstpointer test_data;
+ struct ofono_call_settings *cs;
+};
+
+/* Warning: length is stored in network order */
+struct rsp_hdr {
+ uint32_t length;
+ uint32_t unsolicited;
+ uint32_t serial;
+ uint32_t error;
+};
+
+typedef gboolean (*StartFunc)(gpointer data);
+
+struct cs_data {
+ StartFunc start_func;
+ gint param_int1;
+ gint param_int2;
+
+ const guchar *parcel_data;
+
+ const gsize parcel_size;
+
+ uint32_t rsp_error;
+ const guchar *rsp_data;
+ const gsize rsp_size;
+ enum ofono_error_type error_type;
+ gint cb_int1;
+ gint cb_int2;
+};
+
+static void status_query_callback(const struct ofono_error *error, int status,
+ gpointer data)
+{
+ struct rilmodemcs_data *rcsd = data;
+ const struct cs_data *csd = rcsd->test_data;
+
+ g_assert(error->type == csd->error_type);
+
+ if (error->type == OFONO_ERROR_TYPE_NO_ERROR)
+ g_assert(status == csd->cb_int1);
+
+ g_main_loop_quit(mainloop);
+}
+
+static void clir_query_callback(const struct ofono_error *error, int override,
+ int network, gpointer data)
+{
+ struct rilmodemcs_data *rcsd = data;
+ const struct cs_data *csd = rcsd->test_data;
+
+ g_assert(error->type == csd->error_type);
+
+ if (error->type == OFONO_ERROR_TYPE_NO_ERROR) {
+ g_assert(override == csd->cb_int1);
+ g_assert(network == csd->cb_int2);
+ }
+
+ g_main_loop_quit(mainloop);
+}
+
+static void set_callback(const struct ofono_error *error, gpointer data)
+{
+ struct rilmodemcs_data *rcsd = data;
+ const struct cs_data *csd = rcsd->test_data;
+
+ g_assert(error->type == csd->error_type);
+
+ g_main_loop_quit(mainloop);
+}
+
+static gboolean trigger_clip_query(gpointer data)
+{
+ struct rilmodemcs_data *rcsd = data;
+
+ g_assert(csdriver->clip_query != NULL);
+ csdriver->clip_query(rcsd->cs, status_query_callback, rcsd);
+
+ return FALSE;
+}
+
+static gboolean trigger_cw_query(gpointer data)
+{
+ struct rilmodemcs_data *rcsd = data;
+
+ g_assert(csdriver->cw_query != NULL);
+
+ /* cls is explicitly ignored by rilmodem; just use 0 */
+ csdriver->cw_query(rcsd->cs, 0, status_query_callback, rcsd);
+
+ return FALSE;
+}
+
+static gboolean trigger_cw_set(gpointer data)
+{
+ struct rilmodemcs_data *rcsd = data;
+ const struct cs_data *csd = rcsd->test_data;
+
+ g_assert(csdriver->cw_set != NULL);
+
+ csdriver->cw_set(rcsd->cs, csd->param_int1, csd->param_int2,
+ set_callback, rcsd);
+
+ return FALSE;
+}
+
+static gboolean trigger_clir_query(gpointer data)
+{
+ struct rilmodemcs_data *rcsd = data;
+
+ g_assert(csdriver->clir_query != NULL);
+ csdriver->clir_query(rcsd->cs, clir_query_callback, rcsd);
+
+ return FALSE;
+}
+
+static gboolean trigger_clir_set(gpointer data)
+{
+ struct rilmodemcs_data *rcsd = data;
+ const struct cs_data *csd = rcsd->test_data;
+
+ g_assert(csdriver->clir_set != NULL);
+ csdriver->clir_set(rcsd->cs, csd->param_int1, set_callback, rcsd);
+
+ return FALSE;
+}
+
+/* RIL_REQUEST_QUERY_CLIP */
+static const guchar req_clip_query_parcel_1[] = {
+ 0x00, 0x00, 0x00, 0x08, 0x37, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+/* reply data for QUErY_CLIP: 0x01 = 'CLIP provisioned' */
+static const guchar rsp_clip_query_data_1[] = {
+ 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00
+};
+
+static const struct cs_data testdata_clip_query_valid_1 = {
+ .start_func = trigger_clip_query,
+ .parcel_data = req_clip_query_parcel_1,
+ .parcel_size = sizeof(req_clip_query_parcel_1),
+ .rsp_data = rsp_clip_query_data_1,
+ .rsp_size = sizeof(rsp_clip_query_data_1),
+ .rsp_error = RIL_E_SUCCESS,
+ .cb_int1 = 1,
+ .error_type = OFONO_ERROR_TYPE_NO_ERROR,
+};
+
+/* reply data for QUErY_CLIP: invalid num_params=0x02' */
+static const guchar rsp_clip_query_data_2[] = {
+ 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00
+};
+
+/* reply parse error causes status to be returned as -1 */
+static const struct cs_data testdata_clip_query_invalid_1 = {
+ .start_func = trigger_clip_query,
+ .parcel_data = req_clip_query_parcel_1,
+ .parcel_size = sizeof(req_clip_query_parcel_1),
+ .rsp_data = rsp_clip_query_data_2,
+ .rsp_size = sizeof(rsp_clip_query_data_2),
+ .cb_int1 = -1,
+ .rsp_error = RIL_E_SUCCESS,
+ .error_type = OFONO_ERROR_TYPE_FAILURE,
+};
+
+/* error triggered by RIL reply error */
+static const struct cs_data testdata_clip_query_invalid_2 = {
+ .start_func = trigger_clip_query,
+ .parcel_data = req_clip_query_parcel_1,
+ .parcel_size = sizeof(req_clip_query_parcel_1),
+ .rsp_error = RIL_E_GENERIC_FAILURE,
+ .error_type = OFONO_ERROR_TYPE_FAILURE,
+};
+
+/* RIL_REQUEST_QUERY_CALL_WAITING */
+static const guchar req_cw_query_parcel_1[] = {
+ 0x00, 0x00, 0x00, 0x10, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+/* reply data for QUErY_CALL_WAITING: 1='enabled' 3='data|voice' */
+static const guchar rsp_cw_query_data_1[] = {
+ 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x3, 0x00, 0x00, 0x00
+};
+
+static const struct cs_data testdata_cw_query_valid_1 = {
+ .start_func = trigger_cw_query,
+ .parcel_data = req_cw_query_parcel_1,
+ .parcel_size = sizeof(req_cw_query_parcel_1),
+ .rsp_data = rsp_cw_query_data_1,
+ .rsp_size = sizeof(rsp_cw_query_data_1),
+ .rsp_error = RIL_E_SUCCESS,
+ .cb_int1 = 3,
+ .error_type = OFONO_ERROR_TYPE_NO_ERROR,
+};
+
+/* reply data for QUErY_CALL_WAITING: invalid num_params=0x00' */
+static const guchar rsp_cw_query_data_2[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00
+};
+
+/* reply parse error causes status to be returned as -1 */
+static const struct cs_data testdata_cw_query_invalid_1 = {
+ .start_func = trigger_cw_query,
+ .parcel_data = req_cw_query_parcel_1,
+ .parcel_size = sizeof(req_cw_query_parcel_1),
+ .rsp_data = rsp_cw_query_data_2,
+ .rsp_size = sizeof(rsp_cw_query_data_2),
+ .cb_int1 = -1,
+ .rsp_error = RIL_E_SUCCESS,
+ .error_type = OFONO_ERROR_TYPE_FAILURE,
+};
+
+/* GENERIC_FAILURE returned in RIL reply */
+static const struct cs_data testdata_cw_query_invalid_2 = {
+ .start_func = trigger_cw_query,
+ .parcel_data = req_cw_query_parcel_1,
+ .parcel_size = sizeof(req_cw_query_parcel_1),
+ .rsp_data = rsp_cw_query_data_2,
+ .rsp_size = sizeof(rsp_cw_query_data_2),
+ .cb_int1 = -1,
+ .rsp_error = RIL_E_GENERIC_FAILURE,
+ .error_type = OFONO_ERROR_TYPE_FAILURE,
+};
+
+/* RIL_REQUEST_SET_CALL_WAITING: enabled cls=BEARER_CLASS_DEFAULT (7) */
+/* Note - driver atom checks for cls=7, and changes to cls=1 */
+static const guchar req_cw_set_enabled_parcel_1[] = {
+ 0x00, 0x00, 0x00, 0x14, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00
+};
+
+static const struct cs_data testdata_cw_set_valid_1 = {
+ .start_func = trigger_cw_set,
+ .param_int1 = 1,
+ .param_int2 = BEARER_CLASS_DEFAULT,
+ .parcel_data = req_cw_set_enabled_parcel_1,
+ .parcel_size = sizeof(req_cw_set_enabled_parcel_1),
+ .rsp_error = RIL_E_SUCCESS,
+ .error_type = OFONO_ERROR_TYPE_NO_ERROR,
+};
+
+/* RIL_REQUEST_SET_CALL_WAITING: disabled cls=0 */
+static const guchar req_cw_set_disabled_parcel_2[] = {
+ 0x00, 0x00, 0x00, 0x14, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+/* GENERIC_FAILURE returned in RIL reply */
+static const struct cs_data testdata_cw_set_invalid_1 = {
+ .start_func = trigger_cw_set,
+ .param_int1 = 0,
+ .param_int2 = 0,
+ .parcel_data = req_cw_set_disabled_parcel_2,
+ .parcel_size = sizeof(req_cw_set_disabled_parcel_2),
+ .rsp_error = RIL_E_GENERIC_FAILURE,
+ .error_type = OFONO_ERROR_TYPE_FAILURE,
+};
+
+/* RIL_REQUEST_GET_CLIR */
+static const guchar req_clir_query_parcel_1[] = {
+ 0x00, 0x00, 0x00, 0x08, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+/* reply data for GET_CLIR: m=2 n=4; see TS 27.007 Section 7.7 */
+static const guchar rsp_clir_query_data_1[] = {
+ 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00
+};
+
+static const struct cs_data testdata_clir_query_valid_1 = {
+ .start_func = trigger_clir_query,
+ .parcel_data = req_clir_query_parcel_1,
+ .parcel_size = sizeof(req_clir_query_parcel_1),
+ .rsp_data = rsp_clir_query_data_1,
+ .rsp_size = sizeof(rsp_clir_query_data_1),
+ .cb_int1 = 2,
+ .cb_int2 = 4,
+ .rsp_error = RIL_E_SUCCESS,
+ .error_type = OFONO_ERROR_TYPE_NO_ERROR,
+};
+
+/* invalid reply data for GET_CLIR: num params is 3 instead of 2 */
+static const guchar rsp_clir_query_data_2[] = {
+ 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00
+};
+static const struct cs_data testdata_clir_query_invalid_1 = {
+ .start_func = trigger_clir_query,
+ .parcel_data = req_clir_query_parcel_1,
+ .parcel_size = sizeof(req_clir_query_parcel_1),
+ .rsp_data = rsp_clir_query_data_2,
+ .rsp_size = sizeof(rsp_clir_query_data_2),
+ .rsp_error = RIL_E_SUCCESS,
+ .error_type = OFONO_ERROR_TYPE_FAILURE,
+};
+
+/* RIL_REQUEST_SET_CLIR: mode=DEFAULT */
+static const guchar req_clir_set_mode0_parcel_1[] = {
+ 0x00, 0x00, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+static const struct cs_data testdata_clir_set_valid_1 = {
+ .start_func = trigger_clir_set,
+ .param_int1 = OFONO_CLIR_OPTION_DEFAULT,
+ .parcel_data = req_clir_set_mode0_parcel_1,
+ .parcel_size = sizeof(req_clir_set_mode0_parcel_1),
+ .rsp_error = RIL_E_SUCCESS,
+ .error_type = OFONO_ERROR_TYPE_NO_ERROR,
+};
+
+/* RIL_REQUEST_SET_CLIR: mode=INVOCATION */
+static const guchar req_clir_set_mode0_parcel_2[] = {
+ 0x00, 0x00, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00
+};
+
+/* GENERIC_FAILURE returned in RIL reply */
+static const struct cs_data testdata_clir_set_invalid_1 = {
+ .start_func = trigger_clir_set,
+ .param_int1 = OFONO_CLIR_OPTION_INVOCATION,
+ .parcel_data = req_clir_set_mode0_parcel_2,
+ .parcel_size = sizeof(req_clir_set_mode0_parcel_2),
+ .rsp_error = RIL_E_GENERIC_FAILURE,
+ .error_type = OFONO_ERROR_TYPE_FAILURE,
+};
+
+/* Declarations && Re-implementations of core functions. */
+void ril_call_settings_exit(void);
+void ril_call_settings_init(void);
+
+struct ofono_call_settings {
+ void *driver_data;
+};
+
+struct ofono_call_settings *ofono_call_settings_create(struct ofono_modem *modem,
+ unsigned int vendor,
+ const char *driver,
+ void *data)
+{
+ struct rilmodemcs_data *rcsd = data;
+ struct ofono_call_settings *cs = g_new0(struct ofono_call_settings, 1);
+ int retval;
+
+ retval = csdriver->probe(cs, OFONO_RIL_VENDOR_AOSP, rcsd->ril);
+ g_assert(retval == 0);
+
+ return cs;
+}
+
+int ofono_call_settings_driver_register(const struct ofono_call_settings_driver *d)
+{
+ if (csdriver == NULL)
+ csdriver = d;
+
+ return 0;
+}
+
+void ofono_call_settings_set_data(struct ofono_call_settings *cs, void *data)
+{
+ cs->driver_data = data;
+}
+
+void *ofono_call_settings_get_data(struct ofono_call_settings *cs)
+{
+ return cs->driver_data;
+}
+
+void ofono_call_settings_register(struct ofono_call_settings *cs)
+{
+ ;
+}
+
+void ofono_call_settings_driver_unregister(const struct ofono_call_settings_driver *d)
+{
+ ;
+}
+
+/*
+ * As all our architectures are little-endian except for
+ * PowerPC, and the Binder wire-format differs slightly
+ * depending on endian-ness, the following guards against test
+ * failures when run on PowerPC.
+ */
+#if BYTE_ORDER == LITTLE_ENDIAN
+
+static gboolean read_server(gpointer data)
+{
+ GIOStatus status;
+ struct rilmodemcs_data *rcsd = data;
+ gsize offset, rbytes, wbytes;
+ gchar *buf, *bufp;
+ uint32_t req_serial;
+ struct rsp_hdr rsp;
+
+ /*
+ * FIXME: separate out verification from here, so read_server doesn't
+ * need to know about cs_data.
+ */
+ const struct cs_data *csd = rcsd->test_data;
+
+ buf = g_malloc0(MAX_REQUEST_SIZE);
+
+ status = g_io_channel_read_chars(rcsd->server_io, buf, MAX_REQUEST_SIZE,
+ &rbytes, NULL);
+ g_assert(status == G_IO_STATUS_NORMAL);
+ g_assert(rbytes == csd->parcel_size);
+
+ /* validate len, and request_id */
+ g_assert(!memcmp(buf, csd->parcel_data, (sizeof(uint32_t) * 2)));
+
+ /*
+ * header: size (uint32), reqid (uin32), serial (uint32)
+ * header size == 16 ( excludes sizeof(size) )
+ */
+
+ /* advance past request_no */
+ bufp = buf + (sizeof(uint32_t) * 2);
+
+ req_serial = (uint32_t) *bufp;
+
+ /* advance past serial_no */
+ bufp += sizeof(uint32_t);
+
+ /* validate the rest of the parcel... */
+ offset = (sizeof(uint32_t) * 3);
+ g_assert(!memcmp(bufp, csd->parcel_data + offset,
+ csd->parcel_size - offset));
+
+ /* Length does not include the length field. Network order. */
+ rsp.length = htonl(sizeof(rsp) - sizeof(rsp.length) + csd->rsp_size);
+ rsp.unsolicited = 0;
+ rsp.serial = req_serial;
+ rsp.error = csd->rsp_error;
+
+ /* copy header */
+ memcpy(buf, &rsp, sizeof(rsp));
+
+ if (csd->rsp_size) {
+ bufp = buf + sizeof(rsp);
+
+ memcpy(bufp, csd->rsp_data, csd->rsp_size);
+ }
+
+
+ status = g_io_channel_write_chars(rcsd->server_io,
+ buf,
+ sizeof(rsp) + csd->rsp_size,
+ &wbytes, NULL);
+
+ /* FIXME: assert wbytes is correct */
+
+ g_assert(status == G_IO_STATUS_NORMAL);
+
+ g_free(buf);
+ g_io_channel_unref(rcsd->server_io);
+
+ return FALSE;
+}
+
+static gboolean on_socket_connected(GIOChannel *chan, GIOCondition cond,
+ gpointer data)
+{
+ struct rilmodemcs_data *rcsd = data;
+ const struct cs_data *csd = rcsd->test_data;
+ struct sockaddr saddr;
+ unsigned int len = sizeof(saddr);
+ int fd;
+ GIOChannel *server_io = NULL;
+ GIOStatus status;
+
+ g_assert(cond == G_IO_IN);
+
+ fd = accept(rcsd->sk, &saddr, &len);
+ g_assert(fd != -1);
+
+ server_io = g_io_channel_unix_new(fd);
+ g_assert(server_io != NULL);
+
+ /* This causes local impl of _create() to call driver's probe func. */
+ rcsd->cs = ofono_call_settings_create(NULL, OFONO_RIL_VENDOR_AOSP,
+ "rilmodem", rcsd);
+
+ /* add_idle doesn't work, read blocks main loop!!! */
+ g_assert(csd->start_func(rcsd) == FALSE);
+
+ status = g_io_channel_set_encoding(server_io, NULL, NULL);
+ g_assert(status == G_IO_STATUS_NORMAL);
+
+ g_io_channel_set_buffered(server_io, FALSE);
+ g_io_channel_set_close_on_unref(server_io, TRUE);
+
+ rcsd->server_io = server_io;
+
+ g_idle_add(read_server, rcsd);
+
+ /* single-shot callback */
+ return FALSE;
+}
+
+static void create_server_socket(const char *sock_path,
+ struct rilmodemcs_data *rcsd)
+{
+ GIOChannel *io;
+ struct sockaddr_un addr;
+ int retval;
+
+ rcsd->sk = socket(AF_UNIX, SOCK_STREAM, 0);
+ g_assert(rcsd->sk);
+
+ memset(&addr, 0, sizeof(addr));
+ addr.sun_family = AF_UNIX;
+ strncpy(addr.sun_path, sock_path, sizeof(addr.sun_path) - 1);
+
+ /* Unlink any existing socket for this session */
+ unlink(addr.sun_path);
+
+ retval = bind(rcsd->sk, (struct sockaddr *) &addr, sizeof(addr));
+ g_assert(retval >= 0);
+
+ retval = listen(rcsd->sk, 0);
+ g_assert(retval >= 0);
+
+ io = g_io_channel_unix_new(rcsd->sk);
+ g_assert(io != NULL);
+
+ g_io_channel_set_close_on_unref(io, TRUE);
+ g_io_channel_set_flags(io, G_IO_FLAG_NONBLOCK, NULL);
+
+ rcsd->server_watch = g_io_add_watch_full(io,
+ G_PRIORITY_DEFAULT,
+ G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
+ on_socket_connected, rcsd, NULL);
+
+ g_io_channel_unref(io);
+}
+
+/*
+ * This unit test:
+ * - does some test data setup
+ * - configures a dummy server socket
+ * - on_socket_connected: callback for
+ * incoming socket connects
+ * - creates a new gril client instance
+ * - triggers a connect to the dummy
+ * server socket
+ * - starts a mainloop
+ */
+static void test_cs_func(gconstpointer data)
+{
+ const struct cs_data *csd = data;
+ struct rilmodemcs_data *rcsd;
+
+ ril_call_settings_init();
+
+ rcsd = g_new0(struct rilmodemcs_data, 1);
+
+ rcsd->test_data = csd;
+
+ create_server_socket("/tmp/unittestril", rcsd);
+
+ rcsd->ril = g_ril_new("/tmp/unittestril", OFONO_RIL_VENDOR_AOSP);
+ g_assert(rcsd->ril != NULL);
+
+ mainloop = g_main_loop_new(NULL, FALSE);
+
+ g_main_loop_run(mainloop);
+ g_main_loop_unref(mainloop);
+
+ csdriver->remove(rcsd->cs);
+ g_ril_unref(rcsd->ril);
+ g_free(rcsd);
+
+ ril_call_settings_exit();
+}
+
+#endif
+
+int main(int argc, char **argv)
+{
+ g_test_init(&argc, &argv, NULL);
+
+/*
+ * As all our architectures are little-endian except for
+ * PowerPC, and the Binder wire-format differs slightly
+ * depending on endian-ness, the following guards against test
+ * failures when run on PowerPC.
+ */
+#if BYTE_ORDER == LITTLE_ENDIAN
+ g_test_add_data_func("/testrilmodemcs/clip_query/valid/1",
+ &testdata_clip_query_valid_1,
+ test_cs_func);
+
+ g_test_add_data_func("/testrilmodemcs/clip_query/invalid/1",
+ &testdata_clip_query_invalid_1,
+ test_cs_func);
+
+ g_test_add_data_func("/testrilmodemcs/clip_query/invalid/2",
+ &testdata_clip_query_invalid_2,
+ test_cs_func);
+
+ g_test_add_data_func("/testrilmodemcs/cw_query/valid/1",
+ &testdata_cw_query_valid_1,
+ test_cs_func);
+
+ g_test_add_data_func("/testrilmodemcs/cw_query/invalid/1",
+ &testdata_cw_query_invalid_1,
+ test_cs_func);
+
+ g_test_add_data_func("/testrilmodemcs/cw_query/invalid/2",
+ &testdata_cw_query_invalid_2,
+ test_cs_func);
+
+ g_test_add_data_func("/testrilmodemcs/cw_set/valid/1",
+ &testdata_cw_set_valid_1,
+ test_cs_func);
+
+ g_test_add_data_func("/testrilmodemcs/cw_set/invalid/1",
+ &testdata_cw_set_invalid_1,
+ test_cs_func);
+
+ g_test_add_data_func("/testrilmodemcs/clir_query/valid/1",
+ &testdata_clir_query_valid_1,
+ test_cs_func);
+
+ g_test_add_data_func("/testrilmodemcs/clir_query/invalid/1",
+ &testdata_clir_query_invalid_1,
+ test_cs_func);
+
+ g_test_add_data_func("/testrilmodemcs/clir_set/valid/1",
+ &testdata_clir_set_valid_1,
+ test_cs_func);
+
+ g_test_add_data_func("/testrilmodemcs/clir_set/invalid/1",
+ &testdata_clir_set_invalid_1,
+ test_cs_func);
+
+#endif
+ return g_test_run();
+}
--
2.1.4
5 years, 2 months