temp/ofono: drop (MR 4356)

The ofono fork is no longer used and is outdated. Drop.
This commit is contained in:
Sicelo A. Mhlongo 2023-08-28 16:52:41 +02:00
parent b60b9624dc
commit 1199feabbd
No known key found for this signature in database
GPG key ID: 8642571587897EA1
16 changed files with 0 additions and 2868 deletions

View file

@ -1,358 +0,0 @@
From a7c777888aad5d3ba4671f56de83bd14f7e568e3 Mon Sep 17 00:00:00 2001
From: Alexander Couzens <lynxis@fe80.eu>
Date: Wed, 12 Jul 2017 21:00:00 +0200
Subject: [PATCH 1/5] common: create GList helper ofono_call_compare
replaces at_util_call_compare (atmodem) and
call_compare (rild).
Introduce a drivers/common directory to be used by drivers
to reduce the common code.
---
Makefile.am | 3 ++-
drivers/atmodem/atutil.c | 18 +++----------
drivers/atmodem/atutil.h | 1 -
drivers/atmodem/voicecall.c | 4 ++-
drivers/common/call_list.c | 43 ++++++++++++++++++++++++++++++++
drivers/common/call_list.h | 29 +++++++++++++++++++++
drivers/gemaltomodem/voicecall.c | 4 ++-
drivers/hfpmodem/voicecall.c | 4 ++-
drivers/huaweimodem/voicecall.c | 4 ++-
drivers/ifxmodem/voicecall.c | 4 ++-
drivers/rilmodem/voicecall.c | 18 +++----------
drivers/stemodem/voicecall.c | 4 ++-
12 files changed, 98 insertions(+), 38 deletions(-)
create mode 100644 drivers/common/call_list.c
create mode 100644 drivers/common/call_list.h
diff --git a/Makefile.am b/Makefile.am
index fbb0eff4..c57f4339 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -351,7 +351,8 @@ builtin_sources += drivers/atmodem/atmodem.h \
drivers/atmodem/gprs.c \
drivers/atmodem/gprs-context.c \
drivers/atmodem/gnss.c \
- drivers/atmodem/lte.c
+ drivers/atmodem/lte.c \
+ drivers/common/call_list.c
builtin_modules += nwmodem
builtin_sources += drivers/atmodem/atutil.h \
diff --git a/drivers/atmodem/atutil.c b/drivers/atmodem/atutil.c
index bbdb01c4..3ab930ad 100644
--- a/drivers/atmodem/atutil.c
+++ b/drivers/atmodem/atutil.c
@@ -36,6 +36,8 @@
#include <ofono/types.h>
#include <ofono/modem.h>
+#include <drivers/common/call_list.h>
+
#include "atutil.h"
#include "vendor.h"
@@ -105,20 +107,6 @@ gint at_util_call_compare_by_id(gconstpointer a, gconstpointer b)
return 0;
}
-gint at_util_call_compare(gconstpointer a, gconstpointer b)
-{
- const struct ofono_call *ca = a;
- const struct ofono_call *cb = b;
-
- if (ca->id < cb->id)
- return -1;
-
- if (ca->id > cb->id)
- return 1;
-
- return 0;
-}
-
GSList *at_util_parse_clcc(GAtResult *result, unsigned int *ret_mpty_ids)
{
GAtResultIter iter;
@@ -177,7 +165,7 @@ GSList *at_util_parse_clcc(GAtResult *result, unsigned int *ret_mpty_ids)
else
call->clip_validity = 2;
- l = g_slist_insert_sorted(l, call, at_util_call_compare);
+ l = g_slist_insert_sorted(l, call, ofono_call_compare);
if (mpty)
mpty_ids |= 1 << id;
diff --git a/drivers/atmodem/atutil.h b/drivers/atmodem/atutil.h
index fe2acb39..4a8e26cb 100644
--- a/drivers/atmodem/atutil.h
+++ b/drivers/atmodem/atutil.h
@@ -59,7 +59,6 @@ void decode_at_error(struct ofono_error *error, const char *final);
gint at_util_call_compare_by_status(gconstpointer a, gconstpointer b);
gint at_util_call_compare_by_phone_number(gconstpointer a, gconstpointer b);
gint at_util_call_compare_by_id(gconstpointer a, gconstpointer b);
-gint at_util_call_compare(gconstpointer a, gconstpointer b);
GSList *at_util_parse_clcc(GAtResult *result, unsigned int *mpty_ids);
gboolean at_util_parse_reg(GAtResult *result, const char *prefix,
int *mode, int *status,
diff --git a/drivers/atmodem/voicecall.c b/drivers/atmodem/voicecall.c
index 7ab6567f..5f5b9e45 100644
--- a/drivers/atmodem/voicecall.c
+++ b/drivers/atmodem/voicecall.c
@@ -33,6 +33,8 @@
#include <ofono/log.h>
#include <ofono/modem.h>
#include <ofono/voicecall.h>
+#include <drivers/common/call_list.h>
+
#include "vendor.h"
#include "gatchat.h"
@@ -131,7 +133,7 @@ static struct ofono_call *create_call(struct ofono_voicecall *vc, int type,
call->clip_validity = clip;
call->cnap_validity = CNAP_VALIDITY_NOT_AVAILABLE;
- d->calls = g_slist_insert_sorted(d->calls, call, at_util_call_compare);
+ d->calls = g_slist_insert_sorted(d->calls, call, ofono_call_compare);
return call;
}
diff --git a/drivers/common/call_list.c b/drivers/common/call_list.c
new file mode 100644
index 00000000..487b85e4
--- /dev/null
+++ b/drivers/common/call_list.c
@@ -0,0 +1,43 @@
+/*
+ *
+ * oFono - Open Source Telephony
+ *
+ * Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
+ * Copyright (C) 2019 Alexander Couzens <lynxis@fe80.eu>
+ *
+ * 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
+
+#include <glib.h>
+#include <ofono/types.h>
+
+gint ofono_call_compare(gconstpointer a, gconstpointer b)
+{
+ const struct ofono_call *ca = a;
+ const struct ofono_call *cb = b;
+
+ if (ca->id < cb->id)
+ return -1;
+
+ if (ca->id > cb->id)
+ return 1;
+
+ return 0;
+}
+
diff --git a/drivers/common/call_list.h b/drivers/common/call_list.h
new file mode 100644
index 00000000..2cca87b2
--- /dev/null
+++ b/drivers/common/call_list.h
@@ -0,0 +1,29 @@
+/*
+ *
+ * oFono - Open Source Telephony
+ *
+ * Copyright (C) 2019 Alexander Couzens <lynxis@fe80.eu>
+ *
+ * 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
+ *
+ */
+
+#ifndef __OFONO_DRIVER_COMMON_CALL_LIST
+#define __OFONO_DRIVER_COMMON_CALL_LIST
+
+#include <glib.h>
+
+gint ofono_call_compare(gconstpointer a, gconstpointer b);
+
+#endif /* __OFONO_DRIVER_COMMON_CALL_LIST */
diff --git a/drivers/gemaltomodem/voicecall.c b/drivers/gemaltomodem/voicecall.c
index ad6d78af..c17dd8c8 100644
--- a/drivers/gemaltomodem/voicecall.c
+++ b/drivers/gemaltomodem/voicecall.c
@@ -35,6 +35,8 @@
#include <ofono/modem.h>
#include <ofono/voicecall.h>
+#include <drivers/common/call_list.h>
+
#include "gatchat.h"
#include "gatresult.h"
@@ -363,7 +365,7 @@ static void gemalto_parse_slcc(GAtResult *result, GSList **l,
else
call->clip_validity = 0;
- *l = g_slist_insert_sorted(*l, call, at_util_call_compare);
+ *l = g_slist_insert_sorted(*l, call, ofono_call_compare);
if (ret_mpty)
*ret_mpty = mpty;
diff --git a/drivers/hfpmodem/voicecall.c b/drivers/hfpmodem/voicecall.c
index 69667f14..faa25c7f 100644
--- a/drivers/hfpmodem/voicecall.c
+++ b/drivers/hfpmodem/voicecall.c
@@ -35,6 +35,8 @@
#include <ofono/modem.h>
#include <ofono/voicecall.h>
+#include <drivers/common/call_list.h>
+
#include "common.h"
#include "hfp.h"
@@ -128,7 +130,7 @@ static struct ofono_call *create_call(struct ofono_voicecall *vc, int type,
call->phone_number.type = num_type;
}
- d->calls = g_slist_insert_sorted(d->calls, call, at_util_call_compare);
+ d->calls = g_slist_insert_sorted(d->calls, call, ofono_call_compare);
call->clip_validity = clip;
diff --git a/drivers/huaweimodem/voicecall.c b/drivers/huaweimodem/voicecall.c
index 3044f602..b0dfdbc7 100644
--- a/drivers/huaweimodem/voicecall.c
+++ b/drivers/huaweimodem/voicecall.c
@@ -34,6 +34,8 @@
#include <ofono/modem.h>
#include <ofono/voicecall.h>
+#include <drivers/common/call_list.h>
+
#include "gatchat.h"
#include "gatresult.h"
@@ -75,7 +77,7 @@ static struct ofono_call *create_call(struct ofono_voicecall *vc, int type,
call->clip_validity = clip;
- d->calls = g_slist_insert_sorted(d->calls, call, at_util_call_compare);
+ d->calls = g_slist_insert_sorted(d->calls, call, ofono_call_compare);
return call;
}
diff --git a/drivers/ifxmodem/voicecall.c b/drivers/ifxmodem/voicecall.c
index ae694e3a..b5db5d3e 100644
--- a/drivers/ifxmodem/voicecall.c
+++ b/drivers/ifxmodem/voicecall.c
@@ -34,6 +34,8 @@
#include <ofono/modem.h>
#include <ofono/voicecall.h>
+#include <drivers/common/call_list.h>
+
#include "gatchat.h"
#include "gatresult.h"
@@ -106,7 +108,7 @@ static struct ofono_call *create_call(struct ofono_voicecall *vc, int type,
call->clip_validity = clip;
- d->calls = g_slist_insert_sorted(d->calls, call, at_util_call_compare);
+ d->calls = g_slist_insert_sorted(d->calls, call, ofono_call_compare);
return call;
}
diff --git a/drivers/rilmodem/voicecall.c b/drivers/rilmodem/voicecall.c
index 13dc5071..5619c40f 100644
--- a/drivers/rilmodem/voicecall.c
+++ b/drivers/rilmodem/voicecall.c
@@ -38,6 +38,8 @@
#include <ofono/modem.h>
#include <ofono/voicecall.h>
+#include <drivers/common/call_list.h>
+
#include <gril/gril.h>
#include "common.h"
@@ -116,20 +118,6 @@ done:
ofono_voicecall_disconnected(vc, reqdata->id, reason, NULL);
}
-static int call_compare(gconstpointer a, gconstpointer b)
-{
- const struct ofono_call *ca = a;
- const struct ofono_call *cb = b;
-
- if (ca->id < cb->id)
- return -1;
-
- if (ca->id > cb->id)
- return 1;
-
- return 0;
-}
-
static void clcc_poll_cb(struct ril_msg *message, gpointer user_data)
{
struct ofono_voicecall *vc = user_data;
@@ -208,7 +196,7 @@ static void clcc_poll_cb(struct ril_msg *message, gpointer user_data)
call->id, call->status, call->type,
call->phone_number.number, call->name);
- calls = g_slist_insert_sorted(calls, call, call_compare);
+ calls = g_slist_insert_sorted(calls, call, ofono_call_compare);
}
no_calls:
diff --git a/drivers/stemodem/voicecall.c b/drivers/stemodem/voicecall.c
index 3fd3c1f4..7abb78eb 100644
--- a/drivers/stemodem/voicecall.c
+++ b/drivers/stemodem/voicecall.c
@@ -35,6 +35,8 @@
#include <ofono/modem.h>
#include <ofono/voicecall.h>
+#include <drivers/common/call_list.h>
+
#include "gatchat.h"
#include "gatresult.h"
#include "common.h"
@@ -127,7 +129,7 @@ static struct ofono_call *create_call(struct ofono_voicecall *vc, int type,
call->clip_validity = clip;
- d->calls = g_slist_insert_sorted(d->calls, call, at_util_call_compare);
+ d->calls = g_slist_insert_sorted(d->calls, call, ofono_call_compare);
return call;
}
--
2.24.1

View file

@ -1,312 +0,0 @@
From 4f8a3991c6f90fc5af980eff3aa296552638e73f Mon Sep 17 00:00:00 2001
From: Alexander Couzens <lynxis@fe80.eu>
Date: Tue, 25 Jul 2017 15:35:51 +0200
Subject: [PATCH 2/5] common,atmodem: move at_util_call_compare_by_status to
drivers/common
at_util_call_compare_by_status is used by several modem drivers.
---
drivers/atmodem/atutil.c | 11 -----------
drivers/atmodem/atutil.h | 1 -
drivers/atmodem/voicecall.c | 16 ++++++++--------
drivers/common/call_list.c | 10 ++++++++++
drivers/common/call_list.h | 1 +
drivers/hfpmodem/voicecall.c | 20 ++++++++++----------
drivers/huaweimodem/voicecall.c | 4 ++--
drivers/ifxmodem/voicecall.c | 10 +++++-----
8 files changed, 36 insertions(+), 37 deletions(-)
diff --git a/drivers/atmodem/atutil.c b/drivers/atmodem/atutil.c
index 3ab930ad..df42e60e 100644
--- a/drivers/atmodem/atutil.c
+++ b/drivers/atmodem/atutil.c
@@ -73,17 +73,6 @@ void decode_at_error(struct ofono_error *error, const char *final)
}
}
-gint at_util_call_compare_by_status(gconstpointer a, gconstpointer b)
-{
- const struct ofono_call *call = a;
- int status = GPOINTER_TO_INT(b);
-
- if (status != call->status)
- return 1;
-
- return 0;
-}
-
gint at_util_call_compare_by_phone_number(gconstpointer a, gconstpointer b)
{
const struct ofono_call *call = a;
diff --git a/drivers/atmodem/atutil.h b/drivers/atmodem/atutil.h
index 4a8e26cb..c26adcbd 100644
--- a/drivers/atmodem/atutil.h
+++ b/drivers/atmodem/atutil.h
@@ -56,7 +56,6 @@ enum at_util_charset {
typedef void (*at_util_sim_inserted_cb_t)(gboolean present, void *userdata);
void decode_at_error(struct ofono_error *error, const char *final);
-gint at_util_call_compare_by_status(gconstpointer a, gconstpointer b);
gint at_util_call_compare_by_phone_number(gconstpointer a, gconstpointer b);
gint at_util_call_compare_by_id(gconstpointer a, gconstpointer b);
GSList *at_util_parse_clcc(GAtResult *result, unsigned int *mpty_ids);
diff --git a/drivers/atmodem/voicecall.c b/drivers/atmodem/voicecall.c
index 5f5b9e45..4c495ce2 100644
--- a/drivers/atmodem/voicecall.c
+++ b/drivers/atmodem/voicecall.c
@@ -662,13 +662,13 @@ static void ring_notify(GAtResult *result, gpointer user_data)
/* See comment in CRING */
if (g_slist_find_custom(vd->calls,
GINT_TO_POINTER(CALL_STATUS_WAITING),
- at_util_call_compare_by_status))
+ ofono_call_compare_by_status))
return;
/* RING can repeat, ignore if we already have an incoming call */
if (g_slist_find_custom(vd->calls,
GINT_TO_POINTER(CALL_STATUS_INCOMING),
- at_util_call_compare_by_status))
+ ofono_call_compare_by_status))
return;
/* Generate an incoming call of unknown type */
@@ -700,13 +700,13 @@ static void cring_notify(GAtResult *result, gpointer user_data)
*/
if (g_slist_find_custom(vd->calls,
GINT_TO_POINTER(CALL_STATUS_WAITING),
- at_util_call_compare_by_status))
+ ofono_call_compare_by_status))
return;
/* CRING can repeat, ignore if we already have an incoming call */
if (g_slist_find_custom(vd->calls,
GINT_TO_POINTER(CALL_STATUS_INCOMING),
- at_util_call_compare_by_status))
+ ofono_call_compare_by_status))
return;
g_at_result_iter_init(&iter, result);
@@ -750,7 +750,7 @@ static void clip_notify(GAtResult *result, gpointer user_data)
l = g_slist_find_custom(vd->calls,
GINT_TO_POINTER(CALL_STATUS_INCOMING),
- at_util_call_compare_by_status);
+ ofono_call_compare_by_status);
if (l == NULL) {
ofono_error("CLIP for unknown call");
return;
@@ -812,7 +812,7 @@ static void cdip_notify(GAtResult *result, gpointer user_data)
l = g_slist_find_custom(vd->calls,
GINT_TO_POINTER(CALL_STATUS_INCOMING),
- at_util_call_compare_by_status);
+ ofono_call_compare_by_status);
if (l == NULL) {
ofono_error("CDIP for unknown call");
return;
@@ -861,7 +861,7 @@ static void cnap_notify(GAtResult *result, gpointer user_data)
l = g_slist_find_custom(vd->calls,
GINT_TO_POINTER(CALL_STATUS_INCOMING),
- at_util_call_compare_by_status);
+ ofono_call_compare_by_status);
if (l == NULL) {
ofono_error("CNAP for unknown call");
return;
@@ -915,7 +915,7 @@ static void ccwa_notify(GAtResult *result, gpointer user_data)
/* Some modems resend CCWA, ignore it the second time around */
if (g_slist_find_custom(vd->calls,
GINT_TO_POINTER(CALL_STATUS_WAITING),
- at_util_call_compare_by_status))
+ ofono_call_compare_by_status))
return;
g_at_result_iter_init(&iter, result);
diff --git a/drivers/common/call_list.c b/drivers/common/call_list.c
index 487b85e4..14fd9258 100644
--- a/drivers/common/call_list.c
+++ b/drivers/common/call_list.c
@@ -41,3 +41,13 @@ gint ofono_call_compare(gconstpointer a, gconstpointer b)
return 0;
}
+gint ofono_call_compare_by_status(gconstpointer a, gconstpointer b)
+{
+ const struct ofono_call *call = a;
+ int status = GPOINTER_TO_INT(b);
+
+ if (status != call->status)
+ return 1;
+
+ return 0;
+}
diff --git a/drivers/common/call_list.h b/drivers/common/call_list.h
index 2cca87b2..ffa9dce5 100644
--- a/drivers/common/call_list.h
+++ b/drivers/common/call_list.h
@@ -25,5 +25,6 @@
#include <glib.h>
gint ofono_call_compare(gconstpointer a, gconstpointer b);
+gint ofono_call_compare_by_status(gconstpointer a, gconstpointer b);
#endif /* __OFONO_DRIVER_COMMON_CALL_LIST */
diff --git a/drivers/hfpmodem/voicecall.c b/drivers/hfpmodem/voicecall.c
index faa25c7f..b463876b 100644
--- a/drivers/hfpmodem/voicecall.c
+++ b/drivers/hfpmodem/voicecall.c
@@ -86,12 +86,12 @@ static GSList *find_dialing(GSList *calls)
GSList *c;
c = g_slist_find_custom(calls, GINT_TO_POINTER(CALL_STATUS_DIALING),
- at_util_call_compare_by_status);
+ ofono_call_compare_by_status);
if (c == NULL)
c = g_slist_find_custom(calls,
GINT_TO_POINTER(CALL_STATUS_ALERTING),
- at_util_call_compare_by_status);
+ ofono_call_compare_by_status);
return c;
}
@@ -761,7 +761,7 @@ static void ccwa_notify(GAtResult *result, gpointer user_data)
/* CCWA can repeat, ignore if we already have an waiting call */
if (g_slist_find_custom(vd->calls,
GINT_TO_POINTER(CALL_STATUS_WAITING),
- at_util_call_compare_by_status))
+ ofono_call_compare_by_status))
return;
/* some phones may send extra CCWA after active call is ended
@@ -770,7 +770,7 @@ static void ccwa_notify(GAtResult *result, gpointer user_data)
*/
if (g_slist_find_custom(vd->calls,
GINT_TO_POINTER(CALL_STATUS_INCOMING),
- at_util_call_compare_by_status))
+ ofono_call_compare_by_status))
return;
@@ -813,7 +813,7 @@ static gboolean clip_timeout(gpointer user_data)
l = g_slist_find_custom(vd->calls,
GINT_TO_POINTER(CALL_STATUS_INCOMING),
- at_util_call_compare_by_status);
+ ofono_call_compare_by_status);
if (l == NULL)
return FALSE;
@@ -842,12 +842,12 @@ static void ring_notify(GAtResult *result, gpointer user_data)
/* RING can repeat, ignore if we already have an incoming call */
if (g_slist_find_custom(vd->calls,
GINT_TO_POINTER(CALL_STATUS_INCOMING),
- at_util_call_compare_by_status))
+ ofono_call_compare_by_status))
return;
waiting = g_slist_find_custom(vd->calls,
GINT_TO_POINTER(CALL_STATUS_WAITING),
- at_util_call_compare_by_status);
+ ofono_call_compare_by_status);
/* If we started receiving RINGS but have a waiting call, most
* likely all other calls were dropped and we just didn't get
@@ -892,7 +892,7 @@ static void clip_notify(GAtResult *result, gpointer user_data)
l = g_slist_find_custom(vd->calls,
GINT_TO_POINTER(CALL_STATUS_INCOMING),
- at_util_call_compare_by_status);
+ ofono_call_compare_by_status);
if (l == NULL) {
ofono_error("CLIP for unknown call");
@@ -1008,7 +1008,7 @@ static void ciev_callsetup_notify(struct ofono_voicecall *vc,
waiting = g_slist_find_custom(vd->calls,
GINT_TO_POINTER(CALL_STATUS_WAITING),
- at_util_call_compare_by_status);
+ ofono_call_compare_by_status);
/* This is a truly bizarre case not covered at all by the specification
* (yes, they are complete idiots). Here we assume the other side is
@@ -1087,7 +1087,7 @@ static void ciev_callsetup_notify(struct ofono_voicecall *vc,
{
GSList *o = g_slist_find_custom(vd->calls,
GINT_TO_POINTER(CALL_STATUS_DIALING),
- at_util_call_compare_by_status);
+ ofono_call_compare_by_status);
if (o) {
struct ofono_call *call = o->data;
diff --git a/drivers/huaweimodem/voicecall.c b/drivers/huaweimodem/voicecall.c
index b0dfdbc7..1043c84d 100644
--- a/drivers/huaweimodem/voicecall.c
+++ b/drivers/huaweimodem/voicecall.c
@@ -180,7 +180,7 @@ static void cring_notify(GAtResult *result, gpointer user_data)
/* CRING can repeat, ignore if we already have an incoming call */
if (g_slist_find_custom(vd->calls,
GINT_TO_POINTER(CALL_STATUS_INCOMING),
- at_util_call_compare_by_status))
+ ofono_call_compare_by_status))
return;
g_at_result_iter_init(&iter, result);
@@ -219,7 +219,7 @@ static void clip_notify(GAtResult *result, gpointer user_data)
l = g_slist_find_custom(vd->calls,
GINT_TO_POINTER(CALL_STATUS_INCOMING),
- at_util_call_compare_by_status);
+ ofono_call_compare_by_status);
if (l == NULL) {
ofono_error("CLIP for unknown call");
return;
diff --git a/drivers/ifxmodem/voicecall.c b/drivers/ifxmodem/voicecall.c
index b5db5d3e..42c1a82c 100644
--- a/drivers/ifxmodem/voicecall.c
+++ b/drivers/ifxmodem/voicecall.c
@@ -546,12 +546,12 @@ static void cring_notify(GAtResult *result, gpointer user_data)
*/
if (g_slist_find_custom(vd->calls,
GINT_TO_POINTER(CALL_STATUS_WAITING),
- at_util_call_compare_by_status))
+ ofono_call_compare_by_status))
return;
l = g_slist_find_custom(vd->calls,
GINT_TO_POINTER(CALL_STATUS_INCOMING),
- at_util_call_compare_by_status);
+ ofono_call_compare_by_status);
if (l == NULL) {
ofono_error("CRING received before XCALLSTAT!!!");
return;
@@ -590,7 +590,7 @@ static void clip_notify(GAtResult *result, gpointer user_data)
l = g_slist_find_custom(vd->calls,
GINT_TO_POINTER(CALL_STATUS_INCOMING),
- at_util_call_compare_by_status);
+ ofono_call_compare_by_status);
if (l == NULL) {
ofono_error("CLIP for unknown call");
return;
@@ -650,7 +650,7 @@ static void cnap_notify(GAtResult *result, gpointer user_data)
*/
l = g_slist_find_custom(vd->calls,
GINT_TO_POINTER(CALL_STATUS_INCOMING),
- at_util_call_compare_by_status);
+ ofono_call_compare_by_status);
if (l == NULL) {
ofono_error("CNAP for unknown call");
return;
@@ -696,7 +696,7 @@ static void ccwa_notify(GAtResult *result, gpointer user_data)
l = g_slist_find_custom(vd->calls,
GINT_TO_POINTER(CALL_STATUS_WAITING),
- at_util_call_compare_by_status);
+ ofono_call_compare_by_status);
if (l == NULL) {
ofono_error("CCWA received before XCALLSTAT!!!");
return;
--
2.24.1

View file

@ -1,157 +0,0 @@
From c8b26576fa5a661e4134d4cdbafdcb10ee582048 Mon Sep 17 00:00:00 2001
From: Alexander Couzens <lynxis@fe80.eu>
Date: Tue, 25 Jul 2017 15:39:36 +0200
Subject: [PATCH 3/5] common,atmodem: move at_util_call_compare_by_id to
drivers/common
at_util_call_compare_by_id is used by several modem drivers.
---
drivers/atmodem/atutil.c | 14 --------------
drivers/atmodem/atutil.h | 2 +-
drivers/common/call_list.c | 14 ++++++++++++++
drivers/common/call_list.h | 1 +
drivers/huaweimodem/voicecall.c | 6 +++---
drivers/ifxmodem/voicecall.c | 4 ++--
drivers/stemodem/voicecall.c | 2 +-
7 files changed, 22 insertions(+), 21 deletions(-)
diff --git a/drivers/atmodem/atutil.c b/drivers/atmodem/atutil.c
index df42e60e..335e9902 100644
--- a/drivers/atmodem/atutil.c
+++ b/drivers/atmodem/atutil.c
@@ -82,20 +82,6 @@ gint at_util_call_compare_by_phone_number(gconstpointer a, gconstpointer b)
sizeof(struct ofono_phone_number));
}
-gint at_util_call_compare_by_id(gconstpointer a, gconstpointer b)
-{
- const struct ofono_call *call = a;
- unsigned int id = GPOINTER_TO_UINT(b);
-
- if (id < call->id)
- return -1;
-
- if (id > call->id)
- return 1;
-
- return 0;
-}
-
GSList *at_util_parse_clcc(GAtResult *result, unsigned int *ret_mpty_ids)
{
GAtResultIter iter;
diff --git a/drivers/atmodem/atutil.h b/drivers/atmodem/atutil.h
index c26adcbd..1344c8e1 100644
--- a/drivers/atmodem/atutil.h
+++ b/drivers/atmodem/atutil.h
@@ -57,7 +57,7 @@ typedef void (*at_util_sim_inserted_cb_t)(gboolean present, void *userdata);
void decode_at_error(struct ofono_error *error, const char *final);
gint at_util_call_compare_by_phone_number(gconstpointer a, gconstpointer b);
-gint at_util_call_compare_by_id(gconstpointer a, gconstpointer b);
+gint ofono_call_compare_by_id(gconstpointer a, gconstpointer b);
GSList *at_util_parse_clcc(GAtResult *result, unsigned int *mpty_ids);
gboolean at_util_parse_reg(GAtResult *result, const char *prefix,
int *mode, int *status,
diff --git a/drivers/common/call_list.c b/drivers/common/call_list.c
index 14fd9258..8b871191 100644
--- a/drivers/common/call_list.c
+++ b/drivers/common/call_list.c
@@ -51,3 +51,17 @@ gint ofono_call_compare_by_status(gconstpointer a, gconstpointer b)
return 0;
}
+
+gint ofono_call_compare_by_id(gconstpointer a, gconstpointer b)
+{
+ const struct ofono_call *call = a;
+ unsigned int id = GPOINTER_TO_UINT(b);
+
+ if (id < call->id)
+ return -1;
+
+ if (id > call->id)
+ return 1;
+
+ return 0;
+}
diff --git a/drivers/common/call_list.h b/drivers/common/call_list.h
index ffa9dce5..a06c114f 100644
--- a/drivers/common/call_list.h
+++ b/drivers/common/call_list.h
@@ -26,5 +26,6 @@
gint ofono_call_compare(gconstpointer a, gconstpointer b);
gint ofono_call_compare_by_status(gconstpointer a, gconstpointer b);
+gint ofono_call_compare_by_id(gconstpointer a, gconstpointer b);
#endif /* __OFONO_DRIVER_COMMON_CALL_LIST */
diff --git a/drivers/huaweimodem/voicecall.c b/drivers/huaweimodem/voicecall.c
index 1043c84d..033352c3 100644
--- a/drivers/huaweimodem/voicecall.c
+++ b/drivers/huaweimodem/voicecall.c
@@ -348,7 +348,7 @@ static void conf_notify(GAtResult *result, gpointer user_data)
ofono_info("Call setup: id %d", call_id);
l = g_slist_find_custom(vd->calls, GINT_TO_POINTER(call_id),
- at_util_call_compare_by_id);
+ ofono_call_compare_by_id);
if (l == NULL) {
ofono_error("Received CONF for untracked call");
return;
@@ -385,7 +385,7 @@ static void conn_notify(GAtResult *result, gpointer user_data)
ofono_info("Call connect: id %d type %d", call_id, call_type);
l = g_slist_find_custom(vd->calls, GINT_TO_POINTER(call_id),
- at_util_call_compare_by_id);
+ ofono_call_compare_by_id);
if (l == NULL) {
ofono_error("Received CONN for untracked call");
return;
@@ -429,7 +429,7 @@ static void cend_notify(GAtResult *result, gpointer user_data)
call_id, duration, end_status);
l = g_slist_find_custom(vd->calls, GINT_TO_POINTER(call_id),
- at_util_call_compare_by_id);
+ ofono_call_compare_by_id);
if (l == NULL) {
ofono_error("Received CEND for untracked call");
return;
diff --git a/drivers/ifxmodem/voicecall.c b/drivers/ifxmodem/voicecall.c
index 42c1a82c..aa6504fa 100644
--- a/drivers/ifxmodem/voicecall.c
+++ b/drivers/ifxmodem/voicecall.c
@@ -136,7 +136,7 @@ static void xcallstat_notify(GAtResult *result, gpointer user_data)
return;
l = g_slist_find_custom(vd->calls, GINT_TO_POINTER(id),
- at_util_call_compare_by_id);
+ ofono_call_compare_by_id);
if (l == NULL && status != CALL_STATUS_DIALING &&
status != CALL_STATUS_INCOMING &&
@@ -774,7 +774,7 @@ static void xcolp_notify(GAtResult *result, gpointer user_data)
l = g_slist_find_custom(vd->calls,
GINT_TO_POINTER(call_id),
- at_util_call_compare_by_id);
+ ofono_call_compare_by_id);
if (l == NULL) {
ofono_error("XCOLP for unknown call");
return;
diff --git a/drivers/stemodem/voicecall.c b/drivers/stemodem/voicecall.c
index 7abb78eb..9f38acbf 100644
--- a/drivers/stemodem/voicecall.c
+++ b/drivers/stemodem/voicecall.c
@@ -463,7 +463,7 @@ static void ecav_notify(GAtResult *result, gpointer user_data)
* If it doesn't exists we make a new one
*/
l = g_slist_find_custom(vd->calls, GUINT_TO_POINTER(id),
- at_util_call_compare_by_id);
+ ofono_call_compare_by_id);
if (l)
existing_call = l->data;
--
2.24.1

View file

@ -1,451 +0,0 @@
From fe3f13481413ea648b488c90b500e40921d79dd9 Mon Sep 17 00:00:00 2001
From: Alexander Couzens <lynxis@fe80.eu>
Date: Tue, 25 Jul 2017 12:42:29 +0200
Subject: [PATCH 4/5] add call-list helper to manage voice call lists
Many drivers asks the modem for a complete call list of current calls.
These list of calls can be feeded into call-list which parse the
list and notify ofono for new calls.
---
Makefile.am | 9 +-
drivers/common/call_list.c | 91 ++++++++++++++
drivers/common/call_list.h | 22 +++-
unit/test-call-list.c | 251 +++++++++++++++++++++++++++++++++++++
4 files changed, 371 insertions(+), 2 deletions(-)
create mode 100644 unit/test-call-list.c
diff --git a/Makefile.am b/Makefile.am
index c57f4339..0f88c65b 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -907,7 +907,8 @@ unit_tests = unit/test-common unit/test-util \
unit/test-rilmodem-cs \
unit/test-rilmodem-sms \
unit/test-rilmodem-cb \
- unit/test-rilmodem-gprs
+ unit/test-rilmodem-gprs \
+ unit/test-call-list
noinst_PROGRAMS = $(unit_tests) \
unit/test-sms-root unit/test-mux unit/test-caif
@@ -945,6 +946,12 @@ unit_test_sms_root_SOURCES = unit/test-sms-root.c \
unit_test_sms_root_LDADD = @GLIB_LIBS@ $(ell_ldadd)
unit_objects += $(unit_test_sms_root_OBJECTS)
+unit_test_call_list_SOURCES = \
+ src/common.c src/util.c \
+ drivers/common/call_list.c unit/test-call-list.c
+unit_test_call_list_LDADD = @GLIB_LIBS@ $(ell_ldadd)
+unit_objects += $(unit_test_call_list_OBJECTS)
+
unit_test_mux_SOURCES = unit/test-mux.c $(gatchat_sources)
unit_test_mux_LDADD = @GLIB_LIBS@
unit_objects += $(unit_test_mux_OBJECTS)
diff --git a/drivers/common/call_list.c b/drivers/common/call_list.c
index 8b871191..bf638a21 100644
--- a/drivers/common/call_list.c
+++ b/drivers/common/call_list.c
@@ -27,6 +27,14 @@
#include <glib.h>
#include <ofono/types.h>
+#include <ofono/types.h>
+#include <ofono/log.h>
+#include <ofono/voicecall.h>
+
+#include "src/common.h"
+
+#include <drivers/common/call_list.h>
+
gint ofono_call_compare(gconstpointer a, gconstpointer b)
{
const struct ofono_call *ca = a;
@@ -65,3 +73,86 @@ gint ofono_call_compare_by_id(gconstpointer a, gconstpointer b)
return 0;
}
+
+void ofono_call_list_dial_callback(struct ofono_voicecall *vc,
+ GSList **call_list,
+ const struct ofono_phone_number *ph,
+ int call_id)
+{
+ struct ofono_call *call;
+ GSList *list;
+
+ /* check if call_id already present */
+ list = g_slist_find_custom(*call_list,
+ GINT_TO_POINTER(call_id),
+ ofono_call_compare_by_id);
+
+ if (list) {
+ return;
+ }
+
+ call = g_new0(struct ofono_call, 1);
+ call->id = call_id;
+
+ memcpy(&call->called_number, ph, sizeof(*ph));
+ call->direction = CALL_DIRECTION_MOBILE_ORIGINATED;
+ call->status = CALL_STATUS_DIALING;
+ call->type = 0; /* voice */
+
+ *call_list = g_slist_insert_sorted(*call_list,
+ call,
+ ofono_call_compare);
+ ofono_voicecall_notify(vc, call);
+}
+
+void ofono_call_list_notify(struct ofono_voicecall *vc,
+ GSList **call_list,
+ GSList *calls)
+{
+ GSList *old_calls = *call_list;
+ GSList *new_calls = calls;
+ struct ofono_call *new_call, *old_call;
+
+ while (old_calls || new_calls) {
+ old_call = old_calls ? old_calls->data : NULL;
+ new_call = new_calls ? new_calls->data : NULL;
+
+ /* we drop disconnected calls and treat them as not existent */
+ if (new_call && new_call->status == CALL_STATUS_DISCONNECTED) {
+ new_calls = new_calls->next;
+ calls = g_slist_remove(calls, new_call);
+ g_free(new_call);
+ continue;
+ }
+
+ if (old_call &&
+ (new_call == NULL ||
+ (new_call->id > old_call->id))) {
+ ofono_voicecall_disconnected(
+ vc,
+ old_call->id,
+ OFONO_DISCONNECT_REASON_UNKNOWN,
+ NULL);
+ old_calls = old_calls->next;
+ } else if (new_call &&
+ (old_call == NULL ||
+ (new_call->id < old_call->id))) {
+
+ /* new call, signal it */
+ if (new_call->type == 0)
+ ofono_voicecall_notify(vc, new_call);
+
+ new_calls = new_calls->next;
+ } else {
+ if (memcmp(new_call, old_call, sizeof(*new_call))
+ && new_call->type == 0)
+ ofono_voicecall_notify(vc, new_call);
+
+ new_calls = new_calls->next;
+ old_calls = old_calls->next;
+ }
+ }
+
+ g_slist_free_full(*call_list, g_free);
+ *call_list = calls;
+}
diff --git a/drivers/common/call_list.h b/drivers/common/call_list.h
index a06c114f..80d4ffab 100644
--- a/drivers/common/call_list.h
+++ b/drivers/common/call_list.h
@@ -2,7 +2,7 @@
*
* oFono - Open Source Telephony
*
- * Copyright (C) 2019 Alexander Couzens <lynxis@fe80.eu>
+ * Copyright (C) 2017,2019 Alexander Couzens <lynxis@fe80.eu>
*
* 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
@@ -24,8 +24,28 @@
#include <glib.h>
+struct ofono_voicecall;
+struct ofono_phone_number;
+
gint ofono_call_compare(gconstpointer a, gconstpointer b);
gint ofono_call_compare_by_status(gconstpointer a, gconstpointer b);
gint ofono_call_compare_by_id(gconstpointer a, gconstpointer b);
+/*
+ * Can be called by the driver in the dialing callback,
+ * when the new call id already known
+ */
+void ofono_call_list_dial_callback(struct ofono_voicecall *vc,
+ GSList **call_list,
+ const struct ofono_phone_number *ph,
+ int call_id);
+
+/*
+ * Called with a list of known calls e.g. clcc.
+ * Call list will take ownership of all ofono call within the calls.
+ */
+void ofono_call_list_notify(struct ofono_voicecall *vc,
+ GSList **call_list,
+ GSList *calls);
+
#endif /* __OFONO_DRIVER_COMMON_CALL_LIST */
diff --git a/unit/test-call-list.c b/unit/test-call-list.c
new file mode 100644
index 00000000..f67178da
--- /dev/null
+++ b/unit/test-call-list.c
@@ -0,0 +1,251 @@
+/*
+ *
+ * oFono - Open Source Telephony
+ *
+ * Copyright (C) 2017 Alexander Couzens <lynxis@fe80.eu>
+ *
+ * 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.
+ *
+ */
+
+
+#include <glib.h>
+#include <string.h>
+
+
+#include "../src/common.h"
+#include <ofono/types.h>
+#include <drivers/common/call_list.h>
+
+struct voicecall {
+};
+
+struct notified {
+ unsigned int id;
+ enum call_status status;
+};
+
+static struct notified notified_list[32];
+static int notified_idx;
+static int notified_check;
+
+void reset_notified(void)
+{
+ notified_idx = 0;
+ notified_check = 0;
+ memset(&notified_list, 0, sizeof(notified_list));
+}
+
+void ofono_voicecall_notify(struct ofono_voicecall *vc,
+ struct ofono_call *call)
+{
+ notified_list[notified_idx].id = call->id;
+ notified_list[notified_idx].status = call->status;
+ notified_idx++;
+}
+
+void ofono_voicecall_disconnected(struct ofono_voicecall *vc, int id,
+ enum ofono_disconnect_reason reason,
+ const struct ofono_error *error)
+{
+ notified_list[notified_idx].id = id;
+ notified_list[notified_idx].status = CALL_STATUS_DISCONNECTED;
+ notified_idx++;
+}
+
+static GSList *create_call(
+ GSList *calls,
+ unsigned int id,
+ enum call_status status,
+ enum call_direction direction)
+{
+ struct ofono_call *call = g_new0(struct ofono_call, 1);
+
+ call->id = id;
+ call->status = status;
+ call->direction = direction;
+
+ calls = g_slist_insert_sorted(calls, call, ofono_call_compare);
+
+ return calls;
+}
+
+static void assert_notified(unsigned int call_id, int call_status)
+{
+ g_assert(notified_idx >= notified_check);
+ g_assert(notified_list[notified_check].id == call_id);
+ g_assert(notified_list[notified_check].status == call_status);
+
+ notified_check++;
+}
+
+static void test_notify_disconnected(void)
+{
+ struct ofono_voicecall *vc = NULL;
+ struct ofono_phone_number ph;
+ GSList *call_list;
+ GSList *calls;
+
+ strcpy(ph.number, "004888123456");
+ ph.type = 0;
+
+ /* reset test */
+ reset_notified();
+ call_list = NULL;
+
+ /* fill disconnected call*/
+ calls = create_call(NULL, 1, CALL_STATUS_DISCONNECTED,
+ CALL_DIRECTION_MOBILE_TERMINATED);
+ ofono_call_list_notify(vc, &call_list, calls);
+
+ /* incoming call */
+ calls = create_call(NULL, 1, CALL_STATUS_DISCONNECTED,
+ CALL_DIRECTION_MOBILE_TERMINATED);
+ calls = create_call(calls, 1, CALL_STATUS_ALERTING,
+ CALL_DIRECTION_MOBILE_TERMINATED);
+ ofono_call_list_notify(vc, &call_list, calls);
+
+ /* answer call */
+ calls = create_call(NULL, 1, CALL_STATUS_ACTIVE,
+ CALL_DIRECTION_MOBILE_TERMINATED);
+ calls = create_call(calls, 1, CALL_STATUS_DISCONNECTED,
+ CALL_DIRECTION_MOBILE_TERMINATED);
+ ofono_call_list_notify(vc, &call_list, calls);
+
+ /* another call waiting */
+ calls = create_call(NULL, 1, CALL_STATUS_DISCONNECTED,
+ CALL_DIRECTION_MOBILE_TERMINATED);
+ calls = create_call(calls, 1, CALL_STATUS_ACTIVE,
+ CALL_DIRECTION_MOBILE_TERMINATED);
+ calls = create_call(calls, 2, CALL_STATUS_DISCONNECTED,
+ CALL_DIRECTION_MOBILE_TERMINATED);
+ calls = create_call(calls, 2, CALL_STATUS_WAITING,
+ CALL_DIRECTION_MOBILE_TERMINATED);
+ calls = create_call(calls, 2, CALL_STATUS_DISCONNECTED,
+ CALL_DIRECTION_MOBILE_TERMINATED);
+ ofono_call_list_notify(vc, &call_list, calls);
+
+ /* end all calls */
+ ofono_call_list_notify(vc, &call_list, NULL);
+
+ /* verify call history */
+ assert_notified(1, CALL_STATUS_ALERTING);
+ assert_notified(1, CALL_STATUS_ACTIVE);
+ assert_notified(2, CALL_STATUS_WAITING);
+ assert_notified(1, CALL_STATUS_DISCONNECTED);
+ assert_notified(2, CALL_STATUS_DISCONNECTED);
+
+ g_assert(notified_check == notified_idx);
+ g_slist_free_full(call_list, g_free);
+}
+
+static void test_notify(void)
+{
+ struct ofono_voicecall *vc = NULL;
+ struct ofono_phone_number ph;
+ GSList *call_list;
+ GSList *calls;
+
+ strcpy(ph.number, "004888123456");
+ ph.type = 0;
+
+ /* reset test */
+ reset_notified();
+ call_list = NULL;
+
+ /* incoming call */
+ calls = create_call(NULL, 1, CALL_STATUS_ALERTING,
+ CALL_DIRECTION_MOBILE_TERMINATED);
+ ofono_call_list_notify(vc, &call_list, calls);
+
+ /* answer call */
+ calls = create_call(NULL, 1, CALL_STATUS_ACTIVE,
+ CALL_DIRECTION_MOBILE_TERMINATED);
+ ofono_call_list_notify(vc, &call_list, calls);
+
+ /* another call waiting */
+ calls = create_call(NULL, 1, CALL_STATUS_ACTIVE,
+ CALL_DIRECTION_MOBILE_TERMINATED);
+ calls = create_call(calls, 2, CALL_STATUS_WAITING,
+ CALL_DIRECTION_MOBILE_TERMINATED);
+ ofono_call_list_notify(vc, &call_list, calls);
+
+ /* end all calls */
+ ofono_call_list_notify(vc, &call_list, NULL);
+
+ /* verify call history */
+ assert_notified(1, CALL_STATUS_ALERTING);
+ assert_notified(1, CALL_STATUS_ACTIVE);
+ assert_notified(2, CALL_STATUS_WAITING);
+ assert_notified(1, CALL_STATUS_DISCONNECTED);
+ assert_notified(2, CALL_STATUS_DISCONNECTED);
+
+ g_assert(notified_check == notified_idx);
+ g_slist_free_full(call_list, g_free);
+}
+
+static void test_dial_callback(void)
+{
+ struct ofono_voicecall *vc = NULL;
+ struct ofono_phone_number ph;
+ struct ofono_call *call;
+ GSList *call_list;
+
+ /* reset test */
+ reset_notified();
+ call_list = NULL;
+
+ strcpy(ph.number, "0099301234567890");
+ ph.type = 0;
+
+ ofono_call_list_dial_callback(vc, &call_list, &ph, 33);
+
+ call = call_list->data;
+
+ g_assert(strcmp(call->called_number.number, ph.number) == 0);
+ g_slist_free_full(call_list, g_free);
+}
+
+static void test_dial_callback_race(void)
+{
+ struct ofono_voicecall *vc = NULL;
+ struct ofono_phone_number ph;
+ GSList *call_list, *calls;
+
+ /* reset test */
+ reset_notified();
+ call_list = NULL;
+
+ strcpy(ph.number, "0099301234567890");
+ ph.type = 0;
+
+ /* outgoing call */
+ calls = create_call(NULL, 1, CALL_STATUS_DIALING,
+ CALL_DIRECTION_MOBILE_ORIGINATED);
+ ofono_call_list_notify(vc, &call_list, calls);
+ ofono_call_list_dial_callback(vc, &call_list, &ph, 1);
+
+ g_assert(call_list->next == NULL);
+
+ /* check how many items in the variable */
+ g_slist_free_full(call_list, g_free);
+}
+
+int main(int argc, char **argv)
+{
+ g_test_init(&argc, &argv, NULL);
+
+ g_test_add_func("/test-call-list/dial_callback", test_dial_callback);
+ g_test_add_func("/test-call-list/dial_callback_race", test_dial_callback_race);
+ g_test_add_func("/test-call-list/test_notify", test_notify);
+ g_test_add_func("/test-call-list/test_notify_disconnected",
+ test_notify_disconnected);
+ return g_test_run();
+}
--
2.24.1

View file

@ -1,919 +0,0 @@
From 0e1511de61af64b0ebbc4e4ea7919dd8c7fb3e16 Mon Sep 17 00:00:00 2001
From: Alexander Couzens <lynxis@fe80.eu>
Date: Tue, 25 Jul 2017 15:31:48 +0200
Subject: [PATCH 5/5] qmimodem: implement voice calls
The voice_generated.* files is an RFC how files should look like.
They aren't yet generated.
---
Makefile.am | 4 +-
drivers/qmimodem/qmi.h | 13 ++
drivers/qmimodem/voice.c | 86 ++++++++
drivers/qmimodem/voice.h | 29 +++
drivers/qmimodem/voice_generated.c | 209 +++++++++++++++++++
drivers/qmimodem/voice_generated.h | 113 +++++++++++
drivers/qmimodem/voicecall.c | 312 ++++++++++++++++++++++++++++-
7 files changed, 763 insertions(+), 3 deletions(-)
create mode 100644 drivers/qmimodem/voice.c
create mode 100644 drivers/qmimodem/voice_generated.c
create mode 100644 drivers/qmimodem/voice_generated.h
diff --git a/Makefile.am b/Makefile.am
index 0f88c65b..f863ad71 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -274,7 +274,8 @@ qmi_sources = drivers/qmimodem/qmi.h drivers/qmimodem/qmi.c \
drivers/qmimodem/pds.h \
drivers/qmimodem/common.h \
drivers/qmimodem/wda.h \
- drivers/qmimodem/voice.h
+ drivers/qmimodem/voice.h \
+ drivers/qmimodem/voice.c
builtin_modules += qmimodem
builtin_sources += $(qmi_sources) \
@@ -283,6 +284,7 @@ builtin_sources += $(qmi_sources) \
drivers/qmimodem/qmimodem.c \
drivers/qmimodem/devinfo.c \
drivers/qmimodem/voicecall.c \
+ drivers/qmimodem/voice_generated.c \
drivers/qmimodem/network-registration.c \
drivers/qmimodem/sim-legacy.c \
drivers/qmimodem/sim.c \
diff --git a/drivers/qmimodem/qmi.h b/drivers/qmimodem/qmi.h
index 2665c441..1202cb35 100644
--- a/drivers/qmimodem/qmi.h
+++ b/drivers/qmimodem/qmi.h
@@ -19,6 +19,9 @@
*
*/
+#ifndef __OFONO_QMI_QMI_H
+#define __OFONO_QMI_QMI_H
+
#include <stdbool.h>
#include <stdint.h>
@@ -174,3 +177,13 @@ uint16_t qmi_service_register(struct qmi_service *service,
void *user_data, qmi_destroy_func_t destroy);
bool qmi_service_unregister(struct qmi_service *service, uint16_t id);
bool qmi_service_unregister_all(struct qmi_service *service);
+
+
+/* FIXME: find a place for parse_error */
+enum parse_error {
+ NONE = 0,
+ MISSING_MANDATORY = 1,
+ INVALID_LENGTH = 2,
+};
+
+#endif /* __OFONO_QMI_QMI_H */
diff --git a/drivers/qmimodem/voice.c b/drivers/qmimodem/voice.c
new file mode 100644
index 00000000..76ef8203
--- /dev/null
+++ b/drivers/qmimodem/voice.c
@@ -0,0 +1,86 @@
+/*
+ *
+ * oFono - Open Source Telephony
+ *
+ * Copyright (C) 2017 Alexander Couzens <lynxis@fe80.eu>
+ *
+ * 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.
+ *
+ */
+
+#include <stdint.h>
+
+#include "voice.h"
+#include "src/common.h"
+
+#define _(X) case X: return #X
+
+const char *qmi_voice_call_state_name(enum qmi_voice_call_state value)
+{
+ switch (value) {
+ _(QMI_CALL_STATE_IDLE);
+ _(QMI_CALL_STATE_ORIG);
+ _(QMI_CALL_STATE_INCOMING);
+ _(QMI_CALL_STATE_CONV);
+ _(QMI_CALL_STATE_CC_IN_PROG);
+ _(QMI_CALL_STATE_ALERTING);
+ _(QMI_CALL_STATE_HOLD);
+ _(QMI_CALL_STATE_WAITING);
+ _(QMI_CALL_STATE_DISCONNECTING);
+ _(QMI_CALL_STATE_END);
+ _(QMI_CALL_STATE_SETUP);
+ }
+ return "QMI_CALL_STATE_<UNKNOWN>";
+}
+
+int qmi_to_ofono_status(uint8_t status, int *ret) {
+ int err = 0;
+ switch (status) {
+ case QMI_CALL_STATE_IDLE:
+ case QMI_CALL_STATE_END:
+ case QMI_CALL_STATE_DISCONNECTING:
+ *ret = CALL_STATUS_DISCONNECTED;
+ break;
+ case QMI_CALL_STATE_HOLD:
+ *ret = CALL_STATUS_HELD;
+ break;
+ case QMI_CALL_STATE_WAITING:
+ *ret = CALL_STATUS_WAITING;
+ break;
+ case QMI_CALL_STATE_ORIG:
+ *ret = CALL_STATUS_DIALING;
+ break;
+ case QMI_CALL_STATE_INCOMING:
+ *ret = CALL_STATUS_INCOMING;
+ break;
+ case QMI_CALL_STATE_CONV:
+ *ret = CALL_STATUS_ACTIVE;
+ break;
+ case QMI_CALL_STATE_CC_IN_PROG:
+ case QMI_CALL_STATE_SETUP:
+ /* FIXME: unsure if _SETUP is dialing or not */
+ *ret = CALL_STATUS_DIALING;
+ break;
+ case QMI_CALL_STATE_ALERTING:
+ *ret = CALL_STATUS_ALERTING;
+ break;
+ default:
+ err = 1;
+ }
+ return err;
+}
+
+uint8_t ofono_to_qmi_direction(enum call_direction ofono_direction) {
+ return ofono_direction + 1;
+}
+enum call_direction qmi_to_ofono_direction(uint8_t qmi_direction) {
+ return qmi_direction - 1;
+}
+
diff --git a/drivers/qmimodem/voice.h b/drivers/qmimodem/voice.h
index ca146491..bb98e693 100644
--- a/drivers/qmimodem/voice.h
+++ b/drivers/qmimodem/voice.h
@@ -15,6 +15,9 @@
*
*/
+#define QMI_VOICE_IND_ALL_STATUS 0x2e
+
+
#define QMI_VOICE_PARAM_USS_DATA 0x01
#define QMI_VOICE_PARAM_ASYNC_USSD_ERROR 0x10
@@ -55,8 +58,34 @@ enum voice_commands {
QMI_VOICE_ASYNC_ORIG_USSD = 0x43,
};
+enum qmi_voice_call_state {
+ QMI_CALL_STATE_IDLE = 0x0,
+ QMI_CALL_STATE_ORIG,
+ QMI_CALL_STATE_INCOMING,
+ QMI_CALL_STATE_CONV,
+ QMI_CALL_STATE_CC_IN_PROG,
+ QMI_CALL_STATE_ALERTING,
+ QMI_CALL_STATE_HOLD,
+ QMI_CALL_STATE_WAITING,
+ QMI_CALL_STATE_DISCONNECTING,
+ QMI_CALL_STATE_END,
+ QMI_CALL_STATE_SETUP
+};
+
+enum qmi_voice_call_type {
+ QMI_CALL_TYPE_VOICE = 0x0,
+ QMI_CALL_TYPE_VOICE_FORCE,
+};
+
struct qmi_ussd_data {
uint8_t dcs;
uint8_t length;
uint8_t data[0];
} __attribute__((__packed__));
+
+enum call_direction;
+
+const char *qmi_voice_call_state_name(enum qmi_voice_call_state value);
+uint8_t ofono_to_qmi_direction(enum call_direction ofono_direction);
+enum call_direction qmi_to_ofono_direction(uint8_t qmi_direction);
+int qmi_to_ofono_status(uint8_t status, int *ret);
diff --git a/drivers/qmimodem/voice_generated.c b/drivers/qmimodem/voice_generated.c
new file mode 100644
index 00000000..244a8d2d
--- /dev/null
+++ b/drivers/qmimodem/voice_generated.c
@@ -0,0 +1,209 @@
+
+#include <stdint.h>
+#include <string.h>
+#include <glib.h>
+
+#include "voice_generated.h"
+
+int qmi_voice_dial_call(
+ struct qmi_voice_dial_call_arg *arg,
+ struct qmi_service *service,
+ qmi_result_func_t func,
+ void *user_data,
+ qmi_destroy_func_t destroy)
+{
+ struct qmi_param *param = NULL;
+
+ param = qmi_param_new();
+ if (!param)
+ goto error;
+
+ if (arg->calling_number_set) {
+ if (!qmi_param_append(param,
+ 0x1,
+ strlen(arg->calling_number),
+ arg->calling_number))
+ goto error;
+ }
+
+ if (arg->call_type_set)
+ qmi_param_append_uint8(param, 0x10, arg->call_type);
+
+ if (qmi_service_send(service,
+ 0x20,
+ param,
+ func,
+ user_data,
+ destroy) > 0)
+ return 0;
+error:
+ g_free(param);
+ return 1;
+}
+
+enum parse_error qmi_voice_dial_call_parse(
+ struct qmi_result *qmi_result,
+ struct qmi_voice_dial_call_result *result)
+{
+ int err = NONE;
+
+ /* mandatory */
+ if (qmi_result_get_uint8(qmi_result, 0x10, &result->call_id))
+ result->call_id_set = 1;
+ else
+ err = MISSING_MANDATORY;
+
+ return err;
+}
+
+int qmi_voice_end_call(
+ struct qmi_voice_end_call_arg *arg,
+ struct qmi_service *service,
+ qmi_result_func_t func,
+ void *user_data,
+ qmi_destroy_func_t destroy)
+{
+ struct qmi_param *param = NULL;
+
+ param = qmi_param_new();
+ if (!param)
+ goto error;
+
+ if (arg->call_id_set) {
+ if (!qmi_param_append_uint8(
+ param,
+ 0x1,
+ arg->call_id))
+ goto error;
+ }
+
+ if (qmi_service_send(service,
+ 0x21,
+ param,
+ func,
+ user_data,
+ destroy) > 0)
+ return 0;
+error:
+ g_free(param);
+ return 1;
+}
+
+enum parse_error qmi_voice_end_call_parse(
+ struct qmi_result *qmi_result,
+ struct qmi_voice_end_call_result *result)
+{
+ int err = NONE;
+
+ /* optional */
+ if (qmi_result_get_uint8(qmi_result, 0x10, &result->call_id))
+ result->call_id_set = 1;
+
+ return err;
+}
+
+
+int qmi_voice_answer_call(
+ struct qmi_voice_answer_call_arg *arg,
+ struct qmi_service *service,
+ qmi_result_func_t func,
+ void *user_data,
+ qmi_destroy_func_t destroy)
+{
+ struct qmi_param *param = NULL;
+
+ param = qmi_param_new();
+ if (!param)
+ goto error;
+
+ if (arg->call_id_set) {
+ if (!qmi_param_append_uint8(
+ param,
+ 0x1,
+ arg->call_id))
+ goto error;
+ }
+
+ if (qmi_service_send(service,
+ 0x22,
+ param,
+ func,
+ user_data,
+ destroy) > 0)
+ return 0;
+error:
+ g_free(param);
+ return 1;
+}
+
+
+enum parse_error qmi_voice_answer_call_parse(
+ struct qmi_result *qmi_result,
+ struct qmi_voice_answer_call_result *result)
+{
+ int err = NONE;
+
+ /* optional */
+ if (qmi_result_get_uint8(qmi_result, 0x10, &result->call_id))
+ result->call_id_set = 1;
+
+ return err;
+}
+
+enum parse_error qmi_voice_ind_call_status(
+ struct qmi_result *qmi_result,
+ struct qmi_voice_all_call_status_ind *result)
+{
+ int err = NONE;
+ int offset;
+ uint16_t len;
+ const struct qmi_voice_remote_party_number *remote_party_number;
+ const struct qmi_voice_call_information *call_information;
+
+ /* mandatory */
+ call_information = qmi_result_get(qmi_result, 0x01, &len);
+ if (call_information)
+ {
+ /* verify the length */
+ if (len < sizeof(call_information->size))
+ return INVALID_LENGTH;
+
+ if (len != call_information->size * sizeof(struct qmi_voice_call_information_instance)
+ + sizeof(call_information->size))
+ return INVALID_LENGTH;
+ result->call_information_set = 1;
+ result->call_information = call_information;
+ } else
+ return MISSING_MANDATORY;
+
+ /* mandatory */
+ remote_party_number = qmi_result_get(qmi_result, 0x10, &len);
+ if (remote_party_number) {
+ const struct qmi_voice_remote_party_number_instance *instance;
+ int instance_size = sizeof(struct qmi_voice_remote_party_number_instance);
+ int i;
+
+ /* verify the length */
+ if (len < sizeof(remote_party_number->size))
+ return INVALID_LENGTH;
+
+ for (i = 0, offset = sizeof(remote_party_number->size);
+ offset <= len && i < 16 && i < remote_party_number->size; i++)
+ {
+ if (offset == len) {
+ break;
+ } else if (offset + instance_size > len) {
+ return INVALID_LENGTH;
+ }
+
+ instance = (void *)remote_party_number + offset;
+ result->remote_party_number[i] = instance;
+ offset += sizeof(struct qmi_voice_remote_party_number_instance) + instance->number_size;
+ }
+ result->remote_party_number_set = 1;
+ result->remote_party_number_size = remote_party_number->size;
+ } else
+ return MISSING_MANDATORY;
+
+ return err;
+}
diff --git a/drivers/qmimodem/voice_generated.h b/drivers/qmimodem/voice_generated.h
new file mode 100644
index 00000000..471b52ea
--- /dev/null
+++ b/drivers/qmimodem/voice_generated.h
@@ -0,0 +1,113 @@
+
+#ifndef __OFONO_QMI_VOICE_GENERATED_H
+#define __OFONO_QMI_VOICE_GENERATED_H
+
+#include "qmi.h"
+
+struct qmi_voice_remote_party_number_instance {
+ uint8_t call_id;
+ uint8_t presentation_indicator;
+ uint8_t number_size;
+ char number[0];
+} __attribute__((__packed__));
+
+struct qmi_voice_remote_party_number {
+ uint8_t size;
+ struct qmi_voice_remote_party_number_instance instance[0];
+} __attribute__((__packed__));
+
+/* generator / parser */
+
+struct qmi_voice_dial_call_arg {
+ bool calling_number_set;
+ const char *calling_number;
+ bool call_type_set;
+ uint8_t call_type;
+};
+
+int qmi_voice_dial_call(
+ struct qmi_voice_dial_call_arg *arg,
+ struct qmi_service *service,
+ qmi_result_func_t func,
+ void *user_data,
+ qmi_destroy_func_t destroy);
+
+struct qmi_voice_dial_call_result {
+ bool call_id_set;
+ uint8_t call_id;
+};
+
+enum parse_error qmi_voice_dial_call_parse(
+ struct qmi_result *qmi_result,
+ struct qmi_voice_dial_call_result *result);
+
+struct qmi_voice_end_call_arg {
+ bool call_id_set;
+ uint8_t call_id;
+};
+
+int qmi_voice_end_call(
+ struct qmi_voice_end_call_arg *arg,
+ struct qmi_service *service,
+ qmi_result_func_t func,
+ void *user_data,
+ qmi_destroy_func_t destroy);
+
+struct qmi_voice_end_call_result {
+ bool call_id_set;
+ uint8_t call_id;
+};
+
+enum parse_error qmi_voice_end_call_parse(
+ struct qmi_result *qmi_result,
+ struct qmi_voice_end_call_result *result);
+
+struct qmi_voice_answer_call_arg {
+ bool call_id_set;
+ uint8_t call_id;
+};
+
+int qmi_voice_answer_call(
+ struct qmi_voice_answer_call_arg *arg,
+ struct qmi_service *service,
+ qmi_result_func_t func,
+ void *user_data,
+ qmi_destroy_func_t destroy);
+
+struct qmi_voice_answer_call_result {
+ bool call_id_set;
+ uint8_t call_id;
+};
+
+enum parse_error qmi_voice_answer_call_parse(
+ struct qmi_result *qmi_result,
+ struct qmi_voice_answer_call_result *result);
+
+struct qmi_voice_call_information_instance {
+ uint8_t id;
+ uint8_t state;
+ uint8_t type;
+ uint8_t direction;
+ uint8_t mode;
+ uint8_t multipart_indicator;
+ uint8_t als;
+} __attribute__((__packed__));
+
+struct qmi_voice_call_information {
+ uint8_t size;
+ struct qmi_voice_call_information_instance instance[0];
+} __attribute__((__packed__)) ;
+
+struct qmi_voice_all_call_status_ind {
+ bool call_information_set;
+ const struct qmi_voice_call_information *call_information;
+ bool remote_party_number_set;
+ uint8_t remote_party_number_size;
+ const struct qmi_voice_remote_party_number_instance *remote_party_number[16];
+};
+
+enum parse_error qmi_voice_ind_call_status(
+ struct qmi_result *qmi_result,
+ struct qmi_voice_all_call_status_ind *result);
+
+#endif /* __OFONO_QMI_VOICE_GENERATED_H */
diff --git a/drivers/qmimodem/voicecall.c b/drivers/qmimodem/voicecall.c
index 52dd69b1..cfc6f0b9 100644
--- a/drivers/qmimodem/voicecall.c
+++ b/drivers/qmimodem/voicecall.c
@@ -3,6 +3,7 @@
* oFono - Open Source Telephony
*
* Copyright (C) 2011-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2017 Alexander Couzens <lynxis@fe80.eu>
*
* 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
@@ -23,20 +24,110 @@
#include <config.h>
#endif
+#include <string.h>
+
#include <ofono/log.h>
#include <ofono/modem.h>
#include <ofono/voicecall.h>
-#include "qmi.h"
+#include <drivers/common/call_list.h>
+#include "src/common.h"
+#include "qmi.h"
#include "qmimodem.h"
+#include "voice.h"
+#include "voice_generated.h"
+
+#ifndef ARRAY_SIZE
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+#endif
+
+
+/* qmi protocol */
+
+
+/* end of qmi */
struct voicecall_data {
struct qmi_service *voice;
uint16_t major;
uint16_t minor;
+ GSList *call_list;
+ struct voicecall_static *vs;
+ struct ofono_phone_number dialed;
};
+static void all_call_status_ind(struct qmi_result *result, void *user_data)
+{
+ struct ofono_voicecall *vc = user_data;
+ struct voicecall_data *vd = ofono_voicecall_get_data(vc);
+ GSList *calls = NULL;
+ int i;
+ int size = 0;
+ struct qmi_voice_all_call_status_ind status_ind;
+
+ if (qmi_voice_ind_call_status(result, &status_ind) != NONE) {
+ DBG("Parsing of all call status indication failed");
+ return;
+ }
+
+ if (!status_ind.remote_party_number_set || !status_ind.call_information_set) {
+ DBG("Some required fields are not set");
+ return;
+ }
+
+ size = status_ind.call_information->size;
+ if (!size) {
+ DBG("No call informations received!");
+ return;
+ }
+
+ /* expect we have valid fields for every call */
+ if (size != status_ind.remote_party_number_size) {
+ DBG("Not all fields have the same size");
+ return;
+ }
+
+ for (i = 0; i < size; i++) {
+ struct qmi_voice_call_information_instance call_info;
+ struct ofono_call *call;
+ const struct qmi_voice_remote_party_number_instance *remote_party = status_ind.remote_party_number[i];
+ int number_size;
+
+ call_info = status_ind.call_information->instance[i];
+ call = g_new0(struct ofono_call, 1);
+ call->id = call_info.id;
+ call->direction = qmi_to_ofono_direction(call_info.direction);
+
+ if (qmi_to_ofono_status(call_info.state, &call->status)) {
+ DBG("Ignore call id %d, because can not convert QMI state 0x%x to ofono.",
+ call_info.id, call_info.state);
+ continue;
+ }
+ DBG("Call %d in state %s(%d)",
+ call_info.id,
+ qmi_voice_call_state_name(call_info.state),
+ call_info.state);
+
+ call->type = 0; /* always voice */
+ number_size = remote_party->number_size;
+ if (number_size > OFONO_MAX_PHONE_NUMBER_LENGTH)
+ number_size = OFONO_MAX_PHONE_NUMBER_LENGTH;
+ strncpy(call->phone_number.number, remote_party->number,
+ number_size);
+ /* FIXME: set phone_number_type */
+
+ if (strlen(call->phone_number.number) > 0)
+ call->clip_validity = 0;
+ else
+ call->clip_validity = 2;
+
+ calls = g_slist_insert_sorted(calls, call, ofono_call_compare);
+ }
+
+ ofono_call_list_notify(vc, &vd->call_list, calls);
+}
+
static void create_voice_cb(struct qmi_service *service, void *user_data)
{
struct ofono_voicecall *vc = user_data;
@@ -58,6 +149,12 @@ static void create_voice_cb(struct qmi_service *service, void *user_data)
data->voice = qmi_service_ref(service);
+ /* FIXME: we should call indication_register to ensure we get notified on call events.
+ * We rely at the moment on the default value of notifications
+ */
+ qmi_service_register(data->voice, QMI_VOICE_IND_ALL_STATUS,
+ all_call_status_ind, vc, NULL);
+
ofono_voicecall_register(vc);
}
@@ -77,7 +174,6 @@ static int qmi_voicecall_probe(struct ofono_voicecall *vc,
create_voice_cb, vc, NULL);
return 0;
-
}
static void qmi_voicecall_remove(struct ofono_voicecall *vc)
@@ -92,13 +188,225 @@ static void qmi_voicecall_remove(struct ofono_voicecall *vc)
qmi_service_unref(data->voice);
+ g_slist_free_full(data->call_list, g_free);
+
g_free(data);
}
+static void dial_cb(struct qmi_result *result, void *user_data)
+{
+ struct cb_data *cbd = user_data;
+ struct ofono_voicecall *vc = cbd->user;
+ struct voicecall_data *vd = ofono_voicecall_get_data(vc);
+ ofono_voicecall_cb_t cb = cbd->cb;
+ uint16_t error;
+ struct qmi_voice_dial_call_result dial_result;
+
+ if (qmi_result_set_error(result, &error)) {
+ DBG("QMI Error %d", error);
+ CALLBACK_WITH_FAILURE(cb, cbd->data);
+ return;
+ }
+
+ if (NONE != qmi_voice_dial_call_parse(result, &dial_result)) {
+ DBG("Received invalid Result");
+ CALLBACK_WITH_FAILURE(cb, cbd->data);
+ return;
+ }
+
+ if (!dial_result.call_id_set) {
+ DBG("Didn't receive a call id");
+ CALLBACK_WITH_FAILURE(cb, cbd->data);
+ return;
+ }
+
+ DBG("New call QMI id %d", dial_result.call_id);
+ ofono_call_list_dial_callback(vc,
+ &vd->call_list,
+ &vd->dialed,
+ dial_result.call_id);
+
+
+ /* FIXME: create a timeout on this call_id */
+ CALLBACK_WITH_SUCCESS(cb, cbd->data);
+}
+
+static void dial(struct ofono_voicecall *vc, const struct ofono_phone_number *ph,
+ enum ofono_clir_option clir, ofono_voicecall_cb_t cb,
+ void *data)
+{
+ struct voicecall_data *vd = ofono_voicecall_get_data(vc);
+ struct cb_data *cbd = cb_data_new(cb, data);
+ struct qmi_voice_dial_call_arg arg;
+
+ cbd->user = vc;
+ arg.calling_number_set = true;
+ arg.calling_number = ph->number;
+ memcpy(&vd->dialed, ph, sizeof(*ph));
+
+ arg.call_type_set = true;
+ arg.call_type = QMI_CALL_TYPE_VOICE_FORCE;
+
+ if (!qmi_voice_dial_call(
+ &arg,
+ vd->voice,
+ dial_cb,
+ cbd,
+ g_free))
+ return;
+
+ CALLBACK_WITH_FAILURE(cb, data);
+ g_free(cbd);
+}
+
+static void answer_cb(struct qmi_result *result, void *user_data)
+{
+ struct cb_data *cbd = user_data;
+ ofono_voicecall_cb_t cb = cbd->cb;
+ uint16_t error;
+ struct qmi_voice_answer_call_result answer_result;
+
+ if (qmi_result_set_error(result, &error)) {
+ DBG("QMI Error %d", error);
+ CALLBACK_WITH_FAILURE(cb, cbd->data);
+ return;
+ }
+
+ /* TODO: what happens when calling it with no active call or wrong caller id? */
+ if (NONE != qmi_voice_answer_call_parse(result, &answer_result)) {
+ DBG("Received invalid Result");
+ CALLBACK_WITH_FAILURE(cb, cbd->data);
+ return;
+ }
+
+ CALLBACK_WITH_SUCCESS(cb, cbd->data);
+}
+
+static void answer(struct ofono_voicecall *vc, ofono_voicecall_cb_t cb, void *data)
+{
+ struct voicecall_data *vd = ofono_voicecall_get_data(vc);
+ struct cb_data *cbd = cb_data_new(cb, data);
+ struct qmi_voice_answer_call_arg arg;
+ struct ofono_call *call;
+ GSList *list;
+
+ DBG("");
+ cbd->user = vc;
+
+ list = g_slist_find_custom(vd->call_list,
+ GINT_TO_POINTER(CALL_STATUS_INCOMING),
+ ofono_call_compare_by_status);
+
+ if (list == NULL) {
+ DBG("Can not find a call to answer");
+ goto err;
+ }
+
+ call = list->data;
+
+ arg.call_id_set = true;
+ arg.call_id = call->id;
+
+ if (!qmi_voice_answer_call(
+ &arg,
+ vd->voice,
+ answer_cb,
+ cbd,
+ g_free))
+ return;
+err:
+ CALLBACK_WITH_FAILURE(cb, data);
+ g_free(cbd);
+}
+
+static void end_cb(struct qmi_result *result, void *user_data)
+{
+ struct cb_data *cbd = user_data;
+ ofono_voicecall_cb_t cb = cbd->cb;
+ uint16_t error;
+ struct qmi_voice_end_call_result end_result;
+
+ if (qmi_result_set_error(result, &error)) {
+ DBG("QMI Error %d", error);
+ CALLBACK_WITH_FAILURE(cb, cbd->data);
+ return;
+ }
+
+ if (NONE != qmi_voice_end_call_parse(result, &end_result)) {
+ DBG("Received invalid Result");
+ CALLBACK_WITH_FAILURE(cb, cbd->data);
+ return;
+ }
+
+ CALLBACK_WITH_SUCCESS(cb, cbd->data);
+}
+
+static void release_specific(struct ofono_voicecall *vc, int id,
+ ofono_voicecall_cb_t cb, void *data)
+{
+ struct voicecall_data *vd = ofono_voicecall_get_data(vc);
+ struct cb_data *cbd = cb_data_new(cb, data);
+ struct qmi_voice_end_call_arg arg;
+
+ DBG("");
+ cbd->user = vc;
+
+ arg.call_id_set = true;
+ arg.call_id = id;
+
+ if (!qmi_voice_end_call(&arg,
+ vd->voice,
+ end_cb,
+ cbd,
+ g_free))
+ return;
+
+ CALLBACK_WITH_FAILURE(cb, data);
+ g_free(cbd);
+}
+
+static void hangup_active(struct ofono_voicecall *vc,
+ ofono_voicecall_cb_t cb, void *data)
+{
+ struct voicecall_data *vd = ofono_voicecall_get_data(vc);
+ struct ofono_call *call;
+ GSList *list = NULL;
+ enum call_status active[] = {
+ CALL_STATUS_ACTIVE,
+ CALL_STATUS_DIALING,
+ CALL_STATUS_ALERTING,
+ CALL_STATUS_INCOMING,
+ };
+ int i;
+
+ DBG("");
+ for (i = 0; i < ARRAY_SIZE(active); i++) {
+ list = g_slist_find_custom(vd->call_list,
+ GINT_TO_POINTER(active[i]),
+ ofono_call_compare_by_status);
+
+ if (list)
+ break;
+ }
+
+ if (list == NULL) {
+ DBG("Can not find a call to hang up");
+ CALLBACK_WITH_FAILURE(cb, data);
+ return;
+ }
+
+ call = list->data;
+ release_specific(vc, call->id, cb, data);
+}
+
static const struct ofono_voicecall_driver driver = {
.name = "qmimodem",
.probe = qmi_voicecall_probe,
.remove = qmi_voicecall_remove,
+ .dial = dial,
+ .answer = answer,
+ .hangup_active = hangup_active,
+ .release_specific = release_specific,
};
void qmi_voicecall_init(void)
--
2.24.1

View file

@ -1,30 +0,0 @@
From d6f8723b8caa97a355ef7311dae3b8d630a2eb12 Mon Sep 17 00:00:00 2001
From: Alexander Akulich <akulichalexander@gmail.com>
Date: Thu, 22 Oct 2020 01:41:52 +0300
Subject: [PATCH] [qmimodem] Fix dialing to an international number
We can't just use ph->number because it has no leading '+' which is
crucial for a call (the operator says "The called number is not valid"
in case of a number without the plus).
Use phone_number_to_string() to get the valid number.
---
drivers/qmimodem/voicecall.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/qmimodem/voicecall.c b/drivers/qmimodem/voicecall.c
index cfc6f0b..e848c98 100644
--- a/drivers/qmimodem/voicecall.c
+++ b/drivers/qmimodem/voicecall.c
@@ -241,7 +241,7 @@ static void dial(struct ofono_voicecall *vc, const struct ofono_phone_number *ph
cbd->user = vc;
arg.calling_number_set = true;
- arg.calling_number = ph->number;
+ arg.calling_number = phone_number_to_string(ph);
memcpy(&vd->dialed, ph, sizeof(*ph));
arg.call_type_set = true;
--
2.26.2

View file

@ -1,247 +0,0 @@
From 306a3a6f19546b7b9b6b8df973d75710ce21bc3c Mon Sep 17 00:00:00 2001
From: Joey Hewitt <joey@joeyhewitt.com>
Date: Mon, 4 Sep 2017 23:51:07 -0700
Subject: [PATCH] qmimodem: implement DTMF
The TLVs are documented in GobiAPI. I pass 0xff for the call ID, as the
stock RIL appears to always do. I would guess it means "current foreground
call."
The call ID is returned in TLV 0x10, but I didn't implement parsing of
that.
Acked-by: Alexey Andreyev <aa13q@ya.ru>
diff --git a/drivers/qmimodem/voice_generated.c b/drivers/qmimodem/voice_generated.c
index aef79c4..b579043 100644
--- a/drivers/qmimodem/voice_generated.c
+++ b/drivers/qmimodem/voice_generated.c
@@ -216,3 +216,72 @@ enum parse_error qmi_voice_call_status(
return err;
}
+
+int qmi_voice_start_cont_dtmf(
+ struct qmi_voice_start_cont_dtmf_arg *arg,
+ struct qmi_service *service,
+ qmi_result_func_t func,
+ void *user_data,
+ qmi_destroy_func_t destroy)
+{
+ struct qmi_param *param = NULL;
+ uint8_t param_body[2];
+
+ param = qmi_param_new();
+ if (!param)
+ goto error;
+
+ param_body[0] = arg->call_id;
+ param_body[1] = arg->dtmf_char;
+
+ if (!qmi_param_append(
+ param,
+ 0x1,
+ sizeof(param_body),
+ param_body))
+ goto error;
+
+ if (qmi_service_send(service,
+ 0x29,
+ param,
+ func,
+ user_data,
+ destroy) > 0)
+ return 0;
+
+error:
+ g_free(param);
+ return 1;
+}
+
+int qmi_voice_stop_cont_dtmf(
+ struct qmi_voice_stop_cont_dtmf_arg *arg,
+ struct qmi_service *service,
+ qmi_result_func_t func,
+ void *user_data,
+ qmi_destroy_func_t destroy)
+{
+ struct qmi_param *param = NULL;
+
+ param = qmi_param_new();
+ if (!param)
+ goto error;
+
+ if (!qmi_param_append_uint8(
+ param,
+ 0x1,
+ arg->call_id))
+ goto error;
+
+ if (qmi_service_send(service,
+ 0x2a,
+ param,
+ func,
+ user_data,
+ destroy) > 0)
+ return 0;
+
+error:
+ g_free(param);
+ return 1;
+}
\ No newline at end of file
diff --git a/drivers/qmimodem/voice_generated.h b/drivers/qmimodem/voice_generated.h
index dc238ef..c627fe1 100644
--- a/drivers/qmimodem/voice_generated.h
+++ b/drivers/qmimodem/voice_generated.h
@@ -110,4 +110,27 @@ enum parse_error qmi_voice_call_status(
struct qmi_result *qmi_result,
struct qmi_voice_all_call_status_ind *result);
+struct qmi_voice_start_cont_dtmf_arg {
+ uint8_t call_id;
+ uint8_t dtmf_char;
+};
+
+int qmi_voice_start_cont_dtmf(
+ struct qmi_voice_start_cont_dtmf_arg *arg,
+ struct qmi_service *service,
+ qmi_result_func_t func,
+ void *user_data,
+ qmi_destroy_func_t destroy);
+
+struct qmi_voice_stop_cont_dtmf_arg {
+ uint8_t call_id;
+};
+
+int qmi_voice_stop_cont_dtmf(
+ struct qmi_voice_stop_cont_dtmf_arg *arg,
+ struct qmi_service *service,
+ qmi_result_func_t func,
+ void *user_data,
+ qmi_destroy_func_t destroy);
+
#endif /* __OFONO_QMI_VOICE_GENERATED_H */
diff --git a/drivers/qmimodem/voicecall.c b/drivers/qmimodem/voicecall.c
index bc8ac2b..5d8d35f 100644
--- a/drivers/qmimodem/voicecall.c
+++ b/drivers/qmimodem/voicecall.c
@@ -413,6 +413,110 @@ static void hangup_active(struct ofono_voicecall *vc,
release_specific(vc, call->id, cb, data);
}
+static void stop_cont_dtmf_cb(struct qmi_result *result, void *user_data)
+{
+ struct cb_data *cbd = user_data;
+ ofono_voicecall_cb_t cb = cbd->cb;
+
+ uint16_t error;
+
+ if (qmi_result_set_error(result, &error)) {
+ DBG("QMI Error %d", error);
+ CALLBACK_WITH_FAILURE(cb, cbd->data);
+ return;
+ }
+
+ CALLBACK_WITH_SUCCESS(cb, cbd->data);
+}
+
+static void start_cont_dtmf_cb(struct qmi_result *result, void *user_data)
+{
+ struct cb_data *cbd = user_data;
+ ofono_voicecall_cb_t cb = cbd->cb;
+ struct ofono_voicecall *vc = cbd->user;
+ struct voicecall_data *vd = ofono_voicecall_get_data(vc);
+ struct qmi_voice_stop_cont_dtmf_arg arg;
+ uint16_t error;
+
+ if (qmi_result_set_error(result, &error)) {
+ DBG("QMI Error %d", error);
+ CALLBACK_WITH_FAILURE(cb, cbd->data);
+ return;
+ }
+
+ arg.call_id = 0xff;
+
+ if (!qmi_voice_stop_cont_dtmf(&arg,
+ vd->voice,
+ stop_cont_dtmf_cb,
+ cbd,
+ g_free))
+ return;
+
+ CALLBACK_WITH_FAILURE(cb, cbd->data);
+}
+
+static void send_one_dtmf(struct ofono_voicecall *vc, const char dtmf,
+ ofono_voicecall_cb_t cb, void *data) {
+ struct qmi_voice_start_cont_dtmf_arg arg;
+ struct voicecall_data *vd = ofono_voicecall_get_data(vc);
+
+ arg.call_id = 0xff;
+ arg.dtmf_char = (uint8_t) dtmf;
+
+ struct cb_data *cbd = cb_data_new(cb, data);
+ cbd->user = vc;
+
+ if (!qmi_voice_start_cont_dtmf(&arg,
+ vd->voice,
+ start_cont_dtmf_cb,
+ cbd,
+ NULL))
+ return;
+
+ CALLBACK_WITH_FAILURE(cb, data);
+ g_free(cbd);
+}
+
+struct send_one_dtmf_cb_data {
+ const char *full_dtmf;
+ const char *next_dtmf;
+ struct ofono_voicecall *vc;
+};
+
+static void send_one_dtmf_cb(const struct ofono_error *error, void *data) {
+ struct cb_data *cbd = data;
+ ofono_voicecall_cb_t cb = cbd->cb;
+ struct send_one_dtmf_cb_data *send_one_dtmf_cb_data = cbd->user;
+
+ if (error->type != OFONO_ERROR_TYPE_NO_ERROR || *send_one_dtmf_cb_data->next_dtmf == 0) {
+ if (error->type == OFONO_ERROR_TYPE_NO_ERROR) {
+ CALLBACK_WITH_SUCCESS(cb, cbd->data);
+ } else {
+ CALLBACK_WITH_FAILURE(cb, cbd->data);
+ }
+ g_free((gpointer)send_one_dtmf_cb_data->full_dtmf);
+ g_free(send_one_dtmf_cb_data);
+ g_free(cbd);
+ } else {
+ send_one_dtmf(send_one_dtmf_cb_data->vc, *(send_one_dtmf_cb_data->next_dtmf++), send_one_dtmf_cb, data);
+ }
+}
+
+static void send_dtmf(struct ofono_voicecall *vc, const char *dtmf,
+ ofono_voicecall_cb_t cb, void *data)
+{
+ struct cb_data *cbd = cb_data_new(cb, data);
+ struct send_one_dtmf_cb_data *send_one_dtmf_cb_data = g_new(struct send_one_dtmf_cb_data, 1);
+
+ send_one_dtmf_cb_data->full_dtmf = g_strdup(dtmf);
+ send_one_dtmf_cb_data->next_dtmf = &send_one_dtmf_cb_data->full_dtmf[1];
+ send_one_dtmf_cb_data->vc = vc;
+ cbd->user = send_one_dtmf_cb_data;
+
+ send_one_dtmf(vc, *dtmf, send_one_dtmf_cb, cbd);
+}
+
static const struct ofono_voicecall_driver driver = {
.name = "qmimodem",
.probe = qmi_voicecall_probe,
@@ -421,6 +525,7 @@ static const struct ofono_voicecall_driver driver = {
.answer = answer,
.hangup_active = hangup_active,
.release_specific = release_specific,
+ .send_tones = send_dtmf,
};
void qmi_voicecall_init(void)

View file

@ -1,91 +0,0 @@
# Forked from Alpine for qmi voicecall support & smdpkt patches
pkgname=ofono
pkgver=9999
_pkgver=1.33
pkgrel=13
pkgdesc="Infrastructure for building mobile telephony (GSM/UMTS) applications [$_pkgver]"
url="https://01.org/ofono"
arch="armhf armv7 aarch64"
license="GPL-2.0-only"
depends="bluez mobile-broadband-provider-info"
makedepends="glib-dev dbus-dev ell-dev eudev-dev
linux-headers bsd-compat-headers
autoconf automake libtool"
subpackages="$pkgname-dev $pkgname-doc $pkgname-openrc $pkgname-scripts::noarch"
source="https://www.kernel.org/pub/linux/network/ofono/ofono-$_pkgver.tar.xz
fix-TEMP_FAILURE_RETRY.patch
skip-broken-test.patch
support-smdpkt.patch
wda-set-data-format.patch
0001-common-create-GList-helper-ofono_call_compare.patch
0002-common-atmodem-move-at_util_call_compare_by_status-t.patch
0003-common-atmodem-move-at_util_call_compare_by_id-to-dr.patch
0004-add-call-list-helper-to-manage-voice-call-lists.patch
0005-qmimodem-implement-voice-calls.patch
0006-qmimodem-Fix-dialing-to-an-international-number.patch
0007-qmimodem-implement-dtmf.patch
$pkgname.initd
$pkgname-auto-enable.initd
udev.rules
ofono-wheel.conf
"
builddir="$srcdir/$pkgname-$_pkgver"
prepare() {
default_prepare
autoreconf -fi
}
build() {
./configure \
--prefix=/usr \
--sysconfdir=/etc \
--localstatedir=/var \
--sbindir=/usr/sbin \
--enable-external-ell \
--enable-tools \
--enable-test \
--with-dbusconfdir=/usr/share
make
}
check() {
make -j1 check
}
package() {
make DESTDIR="$pkgdir" install
install -Dm755 tools/auto-enable "$pkgdir"/usr/bin/ofono-auto-enable
install -Dm644 plugins/ofono.rules "$pkgdir"/usr/lib/udev/rules.d/60-ofono.rules
install -Dm644 "$srcdir"/udev.rules "$pkgdir"/usr/lib/udev/rules.d/60-ofono-pmos.rules
install -Dm755 "$srcdir"/$pkgname.initd "$pkgdir"/etc/init.d/$pkgname
install -Dm755 "$srcdir"/$pkgname-auto-enable.initd "$pkgdir"/etc/init.d/$pkgname-auto-enable
install -Dm755 "$srcdir"/ofono-wheel.conf -t "$pkgdir"/usr/share/dbus-1/system.d/
}
scripts() {
pkgdesc="$pkgdesc (test scripts)"
depends="python3 py3-dbus py3-gobject3"
amove usr/lib/ofono/test
}
sha512sums="
8d88226aa2b43eca840c6330045ee7a96c91f6003b06fca5ea55b74fc229f0e0ba0c8d98f7945f8c23ec5a8e7057bffef6335c61842e245686e0ed7c5feda589 ofono-1.33.tar.xz
687a2fd592add40122b789073ab9970d6e966752fdecc4077afe1c1bba705fe541dd0e457094f1d9cde747c571b7810b5b1a30835a3f1869bcd810751d5bf76f fix-TEMP_FAILURE_RETRY.patch
777ab2e13eebd1ccbe12a304310a83b262a5d934207c6a8d410e75aff380838eed1a52f3c2fe0d80c1e7db7faa9b55bf17e78a1e1acd8cfb95a3c6aef49c5b67 skip-broken-test.patch
57c6896d44b5417aa4bfee4d14db01d5006a52f6ab5aa1a2fec367a5ccd1d676e3af13d29f237694c3fc1082654dbae4fdaa86825b541ce204a3a6988c03ac8b support-smdpkt.patch
80a0ea003c4dd3afd8bea7abbfa21b7045b28e46e0a7fcd908a2695999e29657e047eb8d346f81a41ad659e8ce5c4a0f752210594c7e3b7f3c7b04c366d2ddc5 wda-set-data-format.patch
ad25dcc34bf710287c9a03fdcd61f2f2fd675691f55be30dbe7c8421753aa857906dd23b2d4f7f752fbc62caf2857b00bf5eaa8916e62718d1da7d0abc083ca0 0001-common-create-GList-helper-ofono_call_compare.patch
7e2f7fb1e661cc9f2180c55c701823050328ee906171148e4ba200e6365f1c40382dab608e78e383e62c9029a6a41d7d7a18b971132df30839f625eb576cb080 0002-common-atmodem-move-at_util_call_compare_by_status-t.patch
1a55f558c2e3058eee7dae2a60538417ae0fc058f322f4740a0f46a080cc2fda2c8a8cd522d243ab8f0be2ea461ad7dc1c27d2e73bcaac5848d9c592d6386d8a 0003-common-atmodem-move-at_util_call_compare_by_id-to-dr.patch
3e0dce12bcb65d3c6db15cfd50058e793bf1f1ae6e330bf804565afde54614227746a8d4316ccd36093f22e2cc4f62e3a32e46276ab81a7b1f3a61f56984ed78 0004-add-call-list-helper-to-manage-voice-call-lists.patch
72d0f63c091d4b1fc5b405ec67e73f377887ee3dffd4791272122462bf4feaeec207de9b177632756e1f973a7bf7bde119c6ec6556568a6307287ba43998b7a0 0005-qmimodem-implement-voice-calls.patch
6dd4d5f829d66b5b9a13aed6d5a991a2cd3dee6db04a122bcc1d87d0eddc37637468bec58f9fe6027c89eac3b14411201d324150e6be4b103622340da6a599fe 0006-qmimodem-Fix-dialing-to-an-international-number.patch
7d28bcec2dc8b13003c05d74202aced9c86efe35447fbcb0f444fb04447fab8e80a47fa20a662aa0148d42c25333b3261e3cd570991deee9cdfd76effd24af7e 0007-qmimodem-implement-dtmf.patch
bc76c404a7de626210dbd78f659444567a95b6e6d8db0661d5d67ea361e2941ad55242d43a5957995817145d4d5323476fbc42d1830b20608a5e90a7a4ba1194 ofono.initd
54a2cb55547e77c22a98c4260f2e94d9327d5d98e1b604f9413a7380ae4489247a97561cc2ab39476bc6e6fb5e673dca8053218b18ac4626addb51ecb29f0167 ofono-auto-enable.initd
6149be86d6feeb63f8a16e067be5b148551b8121340c257d778aea2082fb09baf5bf479c57f87e3c24a4dc988da15a2f0dec8b4bf13f72e67e025933cb6986ff udev.rules
72cd0cd4bee1f885a990c84f7ed3ef27e0d9d2db37d9a486342204152cb02a67d5197e8014dfea59f1a95285c674695b3dc3cb2b53941781bcfc9b73d5580b1f ofono-wheel.conf
"

View file

@ -1,21 +0,0 @@
diff --git a/drivers/mbimmodem/mbim.c b/drivers/mbimmodem/mbim.c
index 54b18ac..5f924ca 100644
--- a/drivers/mbimmodem/mbim.c
+++ b/drivers/mbimmodem/mbim.c
@@ -41,6 +41,15 @@
#define HEADER_SIZE (sizeof(struct mbim_message_header) + \
sizeof(struct mbim_fragment_header))
+#ifndef TEMP_FAILURE_RETRY
+#define TEMP_FAILURE_RETRY(expression) \
+ (__extension__ \
+ ({ long int __result; \
+ do __result = (long int) (expression); \
+ while (__result == -1L && errno == EINTR); \
+ __result; }))
+#endif
+
const uint8_t mbim_uuid_basic_connect[] = {
0xa2, 0x89, 0xcc, 0x33, 0xbc, 0xbb, 0x8b, 0x4f, 0xb6, 0xb0,
0x13, 0x3e, 0xc2, 0xaa, 0xe6, 0xdf

View file

@ -1,9 +0,0 @@
#!/sbin/openrc-run
command="/usr/bin/ofono-auto-enable"
command_background=true
pidfile="/run/${RC_SVCNAME}.pid"
depend() {
need dbus
}

View file

@ -1,15 +0,0 @@
<!-- This configuration file specifies the required security policies
for oFono core daemon to work. -->
<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
<busconfig>
<!-- ofono.conf allows at_console policy to access the ofono -->
<!-- allow the wheel group as well -->
<policy group="wheel">
<allow send_destination="org.ofono"/>
</policy>
</busconfig>

View file

@ -1,16 +0,0 @@
#!/sbin/openrc-run
supervisor=supervise-daemon
name="oFono"
description="oFono mobile telephony daemon"
# libsmdpkt_wrapper.so may not be present (on devices that don't need it)
export LD_PRELOAD=/usr/lib/preload/libsmdpkt_wrapper.so
command="/usr/sbin/ofonod"
command_args="${OFONOD_OPTS}"
command_args_foreground="-n"
depend() {
need dbus
}

View file

@ -1,12 +0,0 @@
diff --git a/unit/test-stkutil.c b/unit/test-stkutil.c.new
index c595ac1c03..38e9455ba3 100644
--- a/unit/test-stkutil.c
+++ b/unit/test-stkutil.c.new
@@ -313,6 +313,7 @@ static inline void check_tone(const ofono_bool_t command,
static inline void check_ussd(const struct stk_ussd_string *command,
const char *test)
{
+ return; // Test currently broken
char *utf8 = ussd_decode(command->dcs, command->len, command->string);
check_common_text(utf8, test);
g_free(utf8);

View file

@ -1,102 +0,0 @@
From 7045385547867b629c80cbcadf68c1586b98c51c Mon Sep 17 00:00:00 2001
From: Joey Hewitt <joey@joeyhewitt.com>
Date: Fri, 19 Jul 2019 22:02:07 +0200
Subject: [PATCH] support smdpkt
---
plugins/udevng.c | 66 +++++++++++++++++++++++++++---------------------
1 file changed, 37 insertions(+), 29 deletions(-)
diff --git a/plugins/udevng.c b/plugins/udevng.c
index 34ac1cc0..0d594998 100644
--- a/plugins/udevng.c
+++ b/plugins/udevng.c
@@ -203,41 +203,46 @@ static gboolean setup_gobi(struct modem_info *modem)
DBG("%s", modem->syspath);
- for (list = modem->devices; list; list = list->next) {
- struct device_info *info = list->data;
+ if (modem->type != MODEM_TYPE_SERIAL) {
+ for (list = modem->devices; list; list = list->next) {
+ struct device_info *info = list->data;
- DBG("%s %s %s %s %s %s", info->devnode, info->interface,
- info->number, info->label,
- info->sysattr, info->subsystem);
+ DBG("%s %s %s %s %s %s", info->devnode, info->interface,
+ info->number, info->label,
+ info->sysattr, info->subsystem);
- if (g_strcmp0(info->subsystem, "usbmisc") == 0) /* cdc-wdm */
- qmi = info->devnode;
- else if (g_strcmp0(info->subsystem, "net") == 0) /* wwan */
- net = info->devnode;
- else if (g_strcmp0(info->subsystem, "tty") == 0) {
- if (g_strcmp0(info->interface, "255/255/255") == 0) {
- if (g_strcmp0(info->number, "00") == 0)
- diag = info->devnode; /* ec20 */
- else if (g_strcmp0(info->number, "01") == 0)
- diag = info->devnode; /* gobi */
- else if (g_strcmp0(info->number, "02") == 0)
- mdm = info->devnode; /* gobi */
- else if (g_strcmp0(info->number, "03") == 0)
- gps = info->devnode; /* gobi */
- } else if (g_strcmp0(info->interface, "255/0/0") == 0) {
- if (g_strcmp0(info->number, "01") == 0)
- gps = info->devnode; /* ec20 */
- if (g_strcmp0(info->number, "02") == 0)
- mdm = info->devnode; /* ec20 */
- /* ignore the 3rd device second AT/mdm iface */
+ if (g_strcmp0(info->subsystem, "usbmisc") == 0) /* cdc-wdm */
+ qmi = info->devnode;
+ else if (g_strcmp0(info->subsystem, "net") == 0) /* wwan */
+ net = info->devnode;
+ else if (g_strcmp0(info->subsystem, "tty") == 0) {
+ if (g_strcmp0(info->interface, "255/255/255") == 0) {
+ if (g_strcmp0(info->number, "00") == 0)
+ diag = info->devnode; /* ec20 */
+ else if (g_strcmp0(info->number, "01") == 0)
+ diag = info->devnode; /* gobi */
+ else if (g_strcmp0(info->number, "02") == 0)
+ mdm = info->devnode; /* gobi */
+ else if (g_strcmp0(info->number, "03") == 0)
+ gps = info->devnode; /* gobi */
+ } else if (g_strcmp0(info->interface, "255/0/0") == 0) {
+ if (g_strcmp0(info->number, "01") == 0)
+ gps = info->devnode; /* ec20 */
+ if (g_strcmp0(info->number, "02") == 0)
+ mdm = info->devnode; /* ec20 */
+ /* ignore the 3rd device second AT/mdm iface */
+ }
}
}
- }
- DBG("qmi=%s net=%s mdm=%s gps=%s diag=%s", qmi, net, mdm, gps, diag);
+ DBG("qmi=%s net=%s mdm=%s gps=%s diag=%s", qmi, net, mdm, gps, diag);
- if (qmi == NULL || mdm == NULL || net == NULL)
- return FALSE;
+ if (qmi == NULL || mdm == NULL || net == NULL)
+ return FALSE;
+ } else {
+ qmi = modem->serial->devnode;
+ net = udev_device_get_property_value(modem->serial->dev, "OFONO_NETWORK_INTERFACE");
+ }
ofono_modem_set_string(modem->modem, "Device", qmi);
@@ -2074,6 +2079,9 @@ static void enumerate_devices(struct udev *context)
return;
udev_enumerate_add_match_subsystem(enumerate, "tty");
+ udev_enumerate_add_match_subsystem(enumerate, "wwan");
+ udev_enumerate_add_match_subsystem(enumerate, "smdpkt");
+ udev_enumerate_add_match_subsystem(enumerate, "rpmsg");
udev_enumerate_add_match_subsystem(enumerate, "usb");
udev_enumerate_add_match_subsystem(enumerate, "usbmisc");
udev_enumerate_add_match_subsystem(enumerate, "net");
--
2.31.1

View file

@ -1,3 +0,0 @@
SYMLINK=="modem", SUBSYSTEM=="smdpkt", ENV{OFONO_DRIVER}="gobi"
SYMLINK=="modem", SUBSYSTEM=="rpmsg", ENV{OFONO_DRIVER}="gobi", ENV{OFONO_NETWORK_INTERFACE}="rmnet0"
SUBSYSTEM=="wwan", ATTR{type}=="QMI", ENV{OFONO_DRIVER}="gobi", ENV{OFONO_NETWORK_INTERFACE}="rmnet0"

View file

@ -1,125 +0,0 @@
From 326066dcf5ca27ed8c46f9dfba888255ce84b408 Mon Sep 17 00:00:00 2001
From: Minecrell <minecrell@minecrell.net>
Date: Fri, 19 Feb 2021 11:48:44 +0100
Subject: [PATCH] qmimodem: Update WDA data format for network interfaces !=
qmi_wwan
The network interface for the qmimodem may be provided by another
driver, e.g. bam-dmux for the integrated modem in Qualcomm SoCs or IPA.
Those do not support changing the expected data format, they just support
using the modem in Raw-IP mode. However, it may be necessary to change
the WDA data format of the modem to make that work.
To implement that:
1. Assume the network interface expects Raw-IP if it is not exposed
via USB (and therefore managed by qmi_wwan).
2. Fall back to changing the modem data format with "WDA Set Data Format"
if changing the expected data format fails.
---
drivers/qmimodem/gprs-context.c | 59 ++++++++++++++++++++++++++-------
drivers/qmimodem/qmi.c | 5 ++-
2 files changed, 51 insertions(+), 13 deletions(-)
diff --git a/drivers/qmimodem/gprs-context.c b/drivers/qmimodem/gprs-context.c
index f1fd1f12..b5ab8a83 100644
--- a/drivers/qmimodem/gprs-context.c
+++ b/drivers/qmimodem/gprs-context.c
@@ -390,12 +390,25 @@ static void create_wds_cb(struct qmi_service *service, void *user_data)
pkt_status_notify, gc, NULL);
}
+static void set_data_format_cb(struct qmi_result *result, void *user_data)
+{
+ struct ofono_gprs_context *gc = user_data;
+ struct gprs_context_data *data = ofono_gprs_context_get_data(gc);
+ uint16_t error;
+
+ qmi_result_set_error(result, &error);
+ DBG("result %#x\n", error);
+
+ qmi_service_create_shared(data->dev, QMI_SERVICE_WDS, create_wds_cb, gc,
+ NULL);
+}
+
static void get_data_format_cb(struct qmi_result *result, void *user_data)
{
struct ofono_gprs_context *gc = user_data;
struct gprs_context_data *data = ofono_gprs_context_get_data(gc);
- uint32_t llproto;
- enum qmi_device_expected_data_format expected_llproto;
+ uint32_t llproto, new_llproto = 0;
+ enum qmi_device_expected_data_format expected_llproto, new_expected = 0;
DBG("");
@@ -410,19 +423,41 @@ static void get_data_format_cb(struct qmi_result *result, void *user_data)
if ((llproto == QMI_WDA_DATA_LINK_PROTOCOL_802_3) &&
(expected_llproto ==
QMI_DEVICE_EXPECTED_DATA_FORMAT_RAW_IP)) {
- if (!qmi_device_set_expected_data_format(data->dev,
- QMI_DEVICE_EXPECTED_DATA_FORMAT_802_3))
- DBG("Fail to set expected data to 802.3");
- else
- DBG("expected data set to 802.3");
+ new_llproto = QMI_WDA_DATA_LINK_PROTOCOL_RAW_IP;
+ new_expected = QMI_DEVICE_EXPECTED_DATA_FORMAT_802_3;
} else if ((llproto == QMI_WDA_DATA_LINK_PROTOCOL_RAW_IP) &&
(expected_llproto ==
QMI_DEVICE_EXPECTED_DATA_FORMAT_802_3)) {
- if (!qmi_device_set_expected_data_format(data->dev,
- QMI_DEVICE_EXPECTED_DATA_FORMAT_RAW_IP))
- DBG("Fail to set expected data to raw-ip");
- else
- DBG("expected data set to raw-ip");
+ new_llproto = QMI_WDA_DATA_LINK_PROTOCOL_802_3;
+ new_expected = QMI_DEVICE_EXPECTED_DATA_FORMAT_RAW_IP;
+ }
+
+ /* First, try to change expected data format */
+ if (new_expected) {
+ if (qmi_device_set_expected_data_format(data->dev,
+ QMI_DEVICE_EXPECTED_DATA_FORMAT_RAW_IP)) {
+ DBG("updated expected data format");
+ goto done;
+ }
+
+ DBG("Fail to set expected data format (not qmi_wwan?)");
+ }
+
+ /* Otherwise try to change modem data format */
+ if (new_llproto) {
+ struct qmi_param *param;
+
+ DBG("set WDA data format: %d\n", new_llproto);
+
+ param = qmi_param_new_uint32(QMI_WDA_LL_PROTOCOL, new_llproto);
+ if (!param)
+ goto done;
+
+ if (qmi_service_send(data->wda, QMI_WDA_SET_DATA_FORMAT, param,
+ set_data_format_cb, gc, NULL) > 0)
+ return;
+
+ qmi_param_free(param);
}
done:
diff --git a/drivers/qmimodem/qmi.c b/drivers/qmimodem/qmi.c
index 4cd1530f..d412adb6 100644
--- a/drivers/qmimodem/qmi.c
+++ b/drivers/qmimodem/qmi.c
@@ -1543,7 +1543,10 @@ enum qmi_device_expected_data_format qmi_device_get_expected_data_format(
interface = get_device_interface(device);
if (!interface) {
- DBG("Error while getting interface name");
+ DBG("Error while getting interface name (not qmi_wwan?)");
+
+ /* Assume that all other network drivers use Raw-IP */
+ expected = QMI_DEVICE_EXPECTED_DATA_FORMAT_RAW_IP;
goto done;
}
--
2.30.1