modem/ofono: Patches for the getting the voice call working (#1512)
This patchset is based on the branch on the sysmocom.de git, https://git.sysmocom.de/ofono/log/?h=lynxis/voicecall The original branch was based on old ofono so this patches are manually merged to ofono 1.21 and tested on debian initially.
This commit is contained in:
parent
8cf07bf2cf
commit
975b33952e
12 changed files with 2449 additions and 3 deletions
25
modem/ofono/0001-doc-ofonod.8-escape-minus-sign.patch
Normal file
25
modem/ofono/0001-doc-ofonod.8-escape-minus-sign.patch
Normal file
|
@ -0,0 +1,25 @@
|
|||
From 20653ec096bd0e15c09926f8dfc7771bf2036b9a Mon Sep 17 00:00:00 2001
|
||||
From: Jonny Lamb <jonny@debian.org>
|
||||
Date: Mon, 29 Nov 2010 18:04:01 +0000
|
||||
Subject: [PATCH] doc/ofonod.8: escape minus sign
|
||||
|
||||
I'm a sucker for lintian-cleanliness!
|
||||
|
||||
Signed-off-by: Jonny Lamb <jonny@debian.org>
|
||||
---
|
||||
doc/ofonod.8 | 2 +-
|
||||
1 files changed, 1 insertions(+), 1 deletions(-)
|
||||
|
||||
Index: ofono-1.21/doc/ofonod.8
|
||||
===================================================================
|
||||
--- ofono-1.21.orig/doc/ofonod.8
|
||||
+++ ofono-1.21/doc/ofonod.8
|
||||
@@ -18,7 +18,7 @@ is used to manage \fID-Bus\fP permission
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.B --debug, -d
|
||||
-Enable debug information output. Note multiple arguments to -d can be
|
||||
+Enable debug information output. Note multiple arguments to \-d can be
|
||||
specified, colon, comma or space separated. The arguments are relative
|
||||
source code filenames for which debugging output should be enabled;
|
||||
output shell-style globs are accepted (e.g.: "plugins/*:src/main.c").
|
|
@ -0,0 +1,205 @@
|
|||
From c97a48fd4b94d4e6785dd713abe2a06da5e0d623 Mon Sep 17 00:00:00 2001
|
||||
From: Alexander Couzens <lynxis@fe80.eu>
|
||||
Date: Wed, 12 Jul 2017 21:00:00 +0200
|
||||
Subject: [PATCH 02/17] common: create GList helper ofono_call_compare
|
||||
|
||||
replaces at_util_call_compare (atmodem) and
|
||||
call_compare (rild).
|
||||
---
|
||||
drivers/atmodem/atutil.c | 17 ++---------------
|
||||
drivers/atmodem/atutil.h | 1 -
|
||||
drivers/atmodem/voicecall.c | 2 +-
|
||||
drivers/hfpmodem/voicecall.c | 2 +-
|
||||
drivers/huaweimodem/voicecall.c | 2 +-
|
||||
drivers/ifxmodem/voicecall.c | 2 +-
|
||||
drivers/rilmodem/voicecall.c | 16 +---------------
|
||||
drivers/stemodem/voicecall.c | 2 +-
|
||||
src/common.c | 14 ++++++++++++++
|
||||
src/common.h | 2 ++
|
||||
10 files changed, 24 insertions(+), 36 deletions(-)
|
||||
|
||||
Index: ofono-1.21/drivers/atmodem/atutil.c
|
||||
===================================================================
|
||||
--- ofono-1.21.orig/drivers/atmodem/atutil.c
|
||||
+++ ofono-1.21/drivers/atmodem/atutil.c
|
||||
@@ -32,6 +32,7 @@
|
||||
#define OFONO_API_SUBJECT_TO_CHANGE
|
||||
#include <ofono/log.h>
|
||||
#include <ofono/types.h>
|
||||
+#include "../src/common.h"
|
||||
|
||||
#include "atutil.h"
|
||||
#include "vendor.h"
|
||||
@@ -102,20 +103,6 @@ gint at_util_call_compare_by_id(gconstpo
|
||||
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;
|
||||
@@ -174,7 +161,7 @@ GSList *at_util_parse_clcc(GAtResult *re
|
||||
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;
|
||||
Index: ofono-1.21/drivers/atmodem/atutil.h
|
||||
===================================================================
|
||||
--- ofono-1.21.orig/drivers/atmodem/atutil.h
|
||||
+++ ofono-1.21/drivers/atmodem/atutil.h
|
||||
@@ -54,7 +54,6 @@ void decode_at_error(struct ofono_error
|
||||
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,
|
||||
Index: ofono-1.21/drivers/atmodem/voicecall.c
|
||||
===================================================================
|
||||
--- ofono-1.21.orig/drivers/atmodem/voicecall.c
|
||||
+++ ofono-1.21/drivers/atmodem/voicecall.c
|
||||
@@ -132,7 +132,7 @@ static struct ofono_call *create_call(st
|
||||
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;
|
||||
}
|
||||
Index: ofono-1.21/drivers/hfpmodem/voicecall.c
|
||||
===================================================================
|
||||
--- ofono-1.21.orig/drivers/hfpmodem/voicecall.c
|
||||
+++ ofono-1.21/drivers/hfpmodem/voicecall.c
|
||||
@@ -128,7 +128,7 @@ static struct ofono_call *create_call(st
|
||||
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;
|
||||
|
||||
Index: ofono-1.21/drivers/huaweimodem/voicecall.c
|
||||
===================================================================
|
||||
--- ofono-1.21.orig/drivers/huaweimodem/voicecall.c
|
||||
+++ ofono-1.21/drivers/huaweimodem/voicecall.c
|
||||
@@ -76,7 +76,7 @@ static struct ofono_call *create_call(st
|
||||
|
||||
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;
|
||||
}
|
||||
Index: ofono-1.21/drivers/ifxmodem/voicecall.c
|
||||
===================================================================
|
||||
--- ofono-1.21.orig/drivers/ifxmodem/voicecall.c
|
||||
+++ ofono-1.21/drivers/ifxmodem/voicecall.c
|
||||
@@ -107,7 +107,7 @@ static struct ofono_call *create_call(st
|
||||
|
||||
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;
|
||||
}
|
||||
Index: ofono-1.21/drivers/rilmodem/voicecall.c
|
||||
===================================================================
|
||||
--- ofono-1.21.orig/drivers/rilmodem/voicecall.c
|
||||
+++ ofono-1.21/drivers/rilmodem/voicecall.c
|
||||
@@ -117,20 +117,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;
|
||||
@@ -209,7 +195,7 @@ static void clcc_poll_cb(struct ril_msg
|
||||
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:
|
||||
Index: ofono-1.21/drivers/stemodem/voicecall.c
|
||||
===================================================================
|
||||
--- ofono-1.21.orig/drivers/stemodem/voicecall.c
|
||||
+++ ofono-1.21/drivers/stemodem/voicecall.c
|
||||
@@ -128,7 +128,7 @@ static struct ofono_call *create_call(st
|
||||
|
||||
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;
|
||||
}
|
||||
Index: ofono-1.21/src/common.c
|
||||
===================================================================
|
||||
--- ofono-1.21.orig/src/common.c
|
||||
+++ ofono-1.21/src/common.c
|
||||
@@ -765,3 +765,17 @@ const char *call_status_to_string(enum c
|
||||
|
||||
return "unknown";
|
||||
}
|
||||
+
|
||||
+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;
|
||||
+}
|
||||
Index: ofono-1.21/src/common.h
|
||||
===================================================================
|
||||
--- ofono-1.21.orig/src/common.h
|
||||
+++ ofono-1.21/src/common.h
|
||||
@@ -184,4 +184,5 @@ const char *registration_tech_to_string(
|
||||
const char *packet_bearer_to_string(int bearer);
|
||||
|
||||
gboolean is_valid_apn(const char *apn);
|
||||
+gint ofono_call_compare(gconstpointer a, gconstpointer b);
|
||||
const char *call_status_to_string(enum call_status status);
|
|
@ -0,0 +1,54 @@
|
|||
From 99767e9da1b956afdd08c359785721a293931295 Mon Sep 17 00:00:00 2001
|
||||
From: Alexander Couzens <lynxis@fe80.eu>
|
||||
Date: Tue, 25 Jul 2017 11:34:36 +0200
|
||||
Subject: [PATCH 03/17] voicecall,common: promote call_status_to_string()
|
||||
public
|
||||
|
||||
call_status_to_string() is useful for debug output.
|
||||
Change signature to contain enum call_status
|
||||
Replace default case to get compiler warning when new enums added
|
||||
---
|
||||
src/common.c | 21 +++++++++++++++++++++
|
||||
src/common.h | 1 +
|
||||
src/voicecall.c | 24 ++----------------------
|
||||
3 files changed, 24 insertions(+), 22 deletions(-)
|
||||
|
||||
Index: ofono-1.21/src/common.c
|
||||
===================================================================
|
||||
--- ofono-1.21.orig/src/common.c
|
||||
+++ ofono-1.21/src/common.c
|
||||
@@ -779,3 +779,24 @@ gint ofono_call_compare(gconstpointer a,
|
||||
|
||||
return 0;
|
||||
}
|
||||
+
|
||||
+const char *ofono_call_status_to_string(enum call_status status)
|
||||
+{
|
||||
+ switch (status) {
|
||||
+ case CALL_STATUS_ACTIVE:
|
||||
+ return "active";
|
||||
+ case CALL_STATUS_HELD:
|
||||
+ return "held";
|
||||
+ case CALL_STATUS_DIALING:
|
||||
+ return "dialing";
|
||||
+ case CALL_STATUS_ALERTING:
|
||||
+ return "alerting";
|
||||
+ case CALL_STATUS_INCOMING:
|
||||
+ return "incoming";
|
||||
+ case CALL_STATUS_WAITING:
|
||||
+ return "waiting";
|
||||
+ case CALL_STATUS_DISCONNECTED:
|
||||
+ return "disconnected";
|
||||
+ }
|
||||
+ return "unknown";
|
||||
+}
|
||||
Index: ofono-1.21/src/common.h
|
||||
===================================================================
|
||||
--- ofono-1.21.orig/src/common.h
|
||||
+++ ofono-1.21/src/common.h
|
||||
@@ -185,4 +185,4 @@ const char *packet_bearer_to_string(int
|
||||
|
||||
gboolean is_valid_apn(const char *apn);
|
||||
gint ofono_call_compare(gconstpointer a, gconstpointer b);
|
||||
-const char *call_status_to_string(enum call_status status);
|
||||
+const char *ofono_call_status_to_string(enum call_status status);
|
|
@ -0,0 +1,467 @@
|
|||
From 2ae2366c262a15e4f3269afd9c80ddf06c1b9b46 Mon Sep 17 00:00:00 2001
|
||||
From: Alexander Couzens <lynxis@fe80.eu>
|
||||
Date: Tue, 25 Jul 2017 12:42:29 +0200
|
||||
Subject: [PATCH 06/17] 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 | 13 ++-
|
||||
include/call-list.h | 38 ++++++++
|
||||
src/call-list.c | 114 ++++++++++++++++++++++++
|
||||
unit/test-call-list.c | 237 ++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
4 files changed, 399 insertions(+), 3 deletions(-)
|
||||
create mode 100644 include/call-list.h
|
||||
create mode 100644 src/call-list.c
|
||||
create mode 100644 unit/test-call-list.c
|
||||
|
||||
Index: ofono-1.21/Makefile.am
|
||||
===================================================================
|
||||
--- ofono-1.21.orig/Makefile.am
|
||||
+++ ofono-1.21/Makefile.am
|
||||
@@ -22,7 +22,7 @@ pkginclude_HEADERS = include/log.h inclu
|
||||
include/private-network.h include/cdma-netreg.h \
|
||||
include/cdma-provision.h include/handsfree.h \
|
||||
include/handsfree-audio.h include/siri.h \
|
||||
- include/netmon.h include/lte.h
|
||||
+ include/netmon.h include/lte.h include/call-list.h
|
||||
|
||||
nodist_pkginclude_HEADERS = include/version.h
|
||||
|
||||
@@ -630,7 +630,7 @@ src_ofonod_SOURCES = $(builtin_sources)
|
||||
src/cdma-provision.c src/handsfree.c \
|
||||
src/handsfree-audio.c src/bluetooth.h \
|
||||
src/hfp.h src/siri.c \
|
||||
- src/netmon.c src/lte.c \
|
||||
+ src/netmon.c src/lte.c src/call-list.c \
|
||||
src/netmonagent.c src/netmonagent.h
|
||||
|
||||
src_ofonod_LDADD = gdbus/libgdbus-internal.la $(builtin_libadd) \
|
||||
@@ -807,7 +807,8 @@ unit_tests = unit/test-common unit/test-
|
||||
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
|
||||
@@ -849,6 +850,12 @@ unit_test_sms_root_SOURCES = unit/test-s
|
||||
unit_test_sms_root_LDADD = @GLIB_LIBS@
|
||||
unit_objects += $(unit_test_sms_root_OBJECTS)
|
||||
|
||||
+unit_test_call_list_SOURCES = \
|
||||
+ src/common.c src/util.c src/log.c \
|
||||
+ src/call-list.c unit/test-call-list.c
|
||||
+unit_test_call_list_LDADD = @GLIB_LIBS@ -ldl
|
||||
+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)
|
||||
Index: ofono-1.21/include/call-list.h
|
||||
===================================================================
|
||||
--- /dev/null
|
||||
+++ ofono-1.21/include/call-list.h
|
||||
@@ -0,0 +1,38 @@
|
||||
+/*
|
||||
+ *
|
||||
+ * 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>
|
||||
+
|
||||
+struct ofono_voicecall;
|
||||
+struct ofono_phone_number;
|
||||
+
|
||||
+/*
|
||||
+ * 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);
|
||||
Index: ofono-1.21/src/call-list.c
|
||||
===================================================================
|
||||
--- /dev/null
|
||||
+++ ofono-1.21/src/call-list.c
|
||||
@@ -0,0 +1,114 @@
|
||||
+/*
|
||||
+ *
|
||||
+ * 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 "common.h"
|
||||
+
|
||||
+#include <ofono/types.h>
|
||||
+#include <ofono/log.h>
|
||||
+#include <ofono/voicecall.h>
|
||||
+#include <ofono/call-list.h>
|
||||
+
|
||||
+#include <string.h>
|
||||
+
|
||||
+void ofono_call_list_dial_callback(struct ofono_voicecall *vc,
|
||||
+ GSList **call_list,
|
||||
+ const struct ofono_phone_number *ph,
|
||||
+ int call_id)
|
||||
+{
|
||||
+ GSList *list;
|
||||
+ struct ofono_call *call;
|
||||
+
|
||||
+ /* list_notify could be triggered before this call back is handled */
|
||||
+ list = g_slist_find_custom(*call_list,
|
||||
+ GINT_TO_POINTER(call_id),
|
||||
+ ofono_call_compare_by_id);
|
||||
+
|
||||
+ if (list && list->data) {
|
||||
+ call = list->data;
|
||||
+ DBG("Call id %d already known. In state %s(%d)",
|
||||
+ call_id, ofono_call_status_to_string(call->status),
|
||||
+ call->status);
|
||||
+ 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;
|
||||
+}
|
||||
Index: ofono-1.21/unit/test-call-list.c
|
||||
===================================================================
|
||||
--- /dev/null
|
||||
+++ ofono-1.21/unit/test-call-list.c
|
||||
@@ -0,0 +1,237 @@
|
||||
+/*
|
||||
+ *
|
||||
+ * 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 <ofono/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(¬ified_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, *calls;
|
||||
+
|
||||
+ /* reset test */
|
||||
+ reset_notified();
|
||||
+ call_list = NULL;
|
||||
+
|
||||
+ strcpy(ph.number, "0099301234567890");
|
||||
+ ph.type = 0;
|
||||
+
|
||||
+ /* check if a call gets added to the call_list */
|
||||
+ 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);
|
||||
+
|
||||
+ /* check when notify is faster than dial_callback */
|
||||
+ call_list = NULL;
|
||||
+ 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);
|
||||
+ call = call_list->data;
|
||||
+ g_assert(call_list->next == NULL);
|
||||
+ g_slist_free_full(call_list, g_free);
|
||||
+
|
||||
+ call_list = NULL;
|
||||
+}
|
||||
+
|
||||
+int main(int argc, char **argv)
|
||||
+{
|
||||
+ g_test_init(&argc, &argv, NULL);
|
||||
+
|
||||
+ g_test_add_func("/test-call-list/test_notify", test_notify);
|
||||
+ g_test_add_func("/test-call-list/test_notify_disconnected",
|
||||
+ test_notify_disconnected);
|
||||
+ g_test_add_func("/test-call-list/dial_callback", test_dial_callback);
|
||||
+ return g_test_run();
|
||||
+}
|
|
@ -0,0 +1,313 @@
|
|||
From 4c71f0ca71c74987523c68764df28840ccd3882e Mon Sep 17 00:00:00 2001
|
||||
From: Alexander Couzens <lynxis@fe80.eu>
|
||||
Date: Tue, 25 Jul 2017 15:35:51 +0200
|
||||
Subject: [PATCH 07/17] common,atmodem: rename & move
|
||||
at_util_call_compare_by_status to common.c
|
||||
|
||||
at_util_call_compare_by_status is used by several modem drivers.
|
||||
---
|
||||
drivers/atmodem/atutil.c | 11 -----------
|
||||
drivers/atmodem/atutil.h | 2 +-
|
||||
drivers/atmodem/voicecall.c | 16 ++++++++--------
|
||||
drivers/hfpmodem/voicecall.c | 20 ++++++++++----------
|
||||
drivers/huaweimodem/voicecall.c | 4 ++--
|
||||
drivers/ifxmodem/voicecall.c | 10 +++++-----
|
||||
src/common.c | 11 +++++++++++
|
||||
src/common.h | 1 +
|
||||
8 files changed, 38 insertions(+), 37 deletions(-)
|
||||
|
||||
Index: ofono-1.21/drivers/atmodem/atutil.c
|
||||
===================================================================
|
||||
--- ofono-1.21.orig/drivers/atmodem/atutil.c
|
||||
+++ ofono-1.21/drivers/atmodem/atutil.c
|
||||
@@ -69,17 +69,6 @@ void decode_at_error(struct ofono_error
|
||||
}
|
||||
}
|
||||
|
||||
-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;
|
||||
Index: ofono-1.21/drivers/atmodem/atutil.h
|
||||
===================================================================
|
||||
--- ofono-1.21.orig/drivers/atmodem/atutil.h
|
||||
+++ ofono-1.21/drivers/atmodem/atutil.h
|
||||
@@ -51,7 +51,7 @@ 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 ofono_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);
|
||||
Index: ofono-1.21/drivers/atmodem/voicecall.c
|
||||
===================================================================
|
||||
--- ofono-1.21.orig/drivers/atmodem/voicecall.c
|
||||
+++ ofono-1.21/drivers/atmodem/voicecall.c
|
||||
@@ -660,13 +660,13 @@ static void ring_notify(GAtResult *resul
|
||||
/* 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 */
|
||||
@@ -698,13 +698,13 @@ static void cring_notify(GAtResult *resu
|
||||
*/
|
||||
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);
|
||||
@@ -748,7 +748,7 @@ static void clip_notify(GAtResult *resul
|
||||
|
||||
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;
|
||||
@@ -810,7 +810,7 @@ static void cdip_notify(GAtResult *resul
|
||||
|
||||
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;
|
||||
@@ -859,7 +859,7 @@ static void cnap_notify(GAtResult *resul
|
||||
|
||||
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;
|
||||
@@ -913,7 +913,7 @@ static void ccwa_notify(GAtResult *resul
|
||||
/* 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);
|
||||
Index: ofono-1.21/drivers/hfpmodem/voicecall.c
|
||||
===================================================================
|
||||
--- ofono-1.21.orig/drivers/hfpmodem/voicecall.c
|
||||
+++ ofono-1.21/drivers/hfpmodem/voicecall.c
|
||||
@@ -85,12 +85,12 @@ static GSList *find_dialing(GSList *call
|
||||
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;
|
||||
}
|
||||
@@ -720,7 +720,7 @@ static void ccwa_notify(GAtResult *resul
|
||||
/* 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
|
||||
@@ -729,7 +729,7 @@ static void ccwa_notify(GAtResult *resul
|
||||
*/
|
||||
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;
|
||||
|
||||
|
||||
@@ -772,7 +772,7 @@ static gboolean clip_timeout(gpointer us
|
||||
|
||||
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;
|
||||
@@ -801,12 +801,12 @@ static void ring_notify(GAtResult *resul
|
||||
/* 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
|
||||
@@ -851,7 +851,7 @@ static void clip_notify(GAtResult *resul
|
||||
|
||||
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");
|
||||
@@ -967,7 +967,7 @@ static void ciev_callsetup_notify(struct
|
||||
|
||||
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
|
||||
@@ -1046,7 +1046,7 @@ static void ciev_callsetup_notify(struct
|
||||
{
|
||||
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;
|
||||
Index: ofono-1.21/drivers/huaweimodem/voicecall.c
|
||||
===================================================================
|
||||
--- ofono-1.21.orig/drivers/huaweimodem/voicecall.c
|
||||
+++ ofono-1.21/drivers/huaweimodem/voicecall.c
|
||||
@@ -179,7 +179,7 @@ static void cring_notify(GAtResult *resu
|
||||
/* 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);
|
||||
@@ -218,7 +218,7 @@ static void clip_notify(GAtResult *resul
|
||||
|
||||
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;
|
||||
Index: ofono-1.21/drivers/ifxmodem/voicecall.c
|
||||
===================================================================
|
||||
--- ofono-1.21.orig/drivers/ifxmodem/voicecall.c
|
||||
+++ ofono-1.21/drivers/ifxmodem/voicecall.c
|
||||
@@ -545,12 +545,12 @@ static void cring_notify(GAtResult *resu
|
||||
*/
|
||||
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;
|
||||
@@ -589,7 +589,7 @@ static void clip_notify(GAtResult *resul
|
||||
|
||||
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;
|
||||
@@ -649,7 +649,7 @@ static void cnap_notify(GAtResult *resul
|
||||
*/
|
||||
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;
|
||||
@@ -695,7 +695,7 @@ static void ccwa_notify(GAtResult *resul
|
||||
|
||||
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;
|
||||
Index: ofono-1.21/src/common.c
|
||||
===================================================================
|
||||
--- ofono-1.21.orig/src/common.c
|
||||
+++ ofono-1.21/src/common.c
|
||||
@@ -780,6 +780,17 @@ gint ofono_call_compare(gconstpointer a,
|
||||
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;
|
||||
+}
|
||||
+
|
||||
const char *ofono_call_status_to_string(enum call_status status)
|
||||
{
|
||||
switch (status) {
|
||||
Index: ofono-1.21/src/common.h
|
||||
===================================================================
|
||||
--- ofono-1.21.orig/src/common.h
|
||||
+++ ofono-1.21/src/common.h
|
||||
@@ -185,4 +185,5 @@ const char *packet_bearer_to_string(int
|
||||
|
||||
gboolean is_valid_apn(const char *apn);
|
||||
gint ofono_call_compare(gconstpointer a, gconstpointer b);
|
||||
+gint ofono_call_compare_by_status(gconstpointer a, gconstpointer b);
|
||||
const char *ofono_call_status_to_string(enum call_status status);
|
|
@ -0,0 +1,156 @@
|
|||
From 3bba30fd23705dc8817b2eb0f28c9be03b8f7892 Mon Sep 17 00:00:00 2001
|
||||
From: Alexander Couzens <lynxis@fe80.eu>
|
||||
Date: Tue, 25 Jul 2017 15:39:36 +0200
|
||||
Subject: [PATCH 08/17] common,atmodem: rename & move
|
||||
at_util_call_compare_by_id to common.c
|
||||
|
||||
at_util_call_compare_by_id is used by several modem drivers.
|
||||
---
|
||||
drivers/atmodem/atutil.c | 14 --------------
|
||||
drivers/atmodem/atutil.h | 2 +-
|
||||
drivers/huaweimodem/voicecall.c | 6 +++---
|
||||
drivers/ifxmodem/voicecall.c | 4 ++--
|
||||
drivers/stemodem/voicecall.c | 2 +-
|
||||
src/common.c | 14 ++++++++++++++
|
||||
src/common.h | 1 +
|
||||
7 files changed, 22 insertions(+), 21 deletions(-)
|
||||
|
||||
Index: ofono-1.21/drivers/atmodem/atutil.c
|
||||
===================================================================
|
||||
--- ofono-1.21.orig/drivers/atmodem/atutil.c
|
||||
+++ ofono-1.21/drivers/atmodem/atutil.c
|
||||
@@ -78,20 +78,6 @@ gint at_util_call_compare_by_phone_numbe
|
||||
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;
|
||||
Index: ofono-1.21/drivers/atmodem/atutil.h
|
||||
===================================================================
|
||||
--- ofono-1.21.orig/drivers/atmodem/atutil.h
|
||||
+++ ofono-1.21/drivers/atmodem/atutil.h
|
||||
@@ -53,7 +53,7 @@ typedef void (*at_util_sim_inserted_cb_t
|
||||
void decode_at_error(struct ofono_error *error, const char *final);
|
||||
gint ofono_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 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,
|
||||
Index: ofono-1.21/drivers/huaweimodem/voicecall.c
|
||||
===================================================================
|
||||
--- ofono-1.21.orig/drivers/huaweimodem/voicecall.c
|
||||
+++ ofono-1.21/drivers/huaweimodem/voicecall.c
|
||||
@@ -347,7 +347,7 @@ static void conf_notify(GAtResult *resul
|
||||
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;
|
||||
@@ -384,7 +384,7 @@ static void conn_notify(GAtResult *resul
|
||||
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;
|
||||
@@ -428,7 +428,7 @@ static void cend_notify(GAtResult *resul
|
||||
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;
|
||||
Index: ofono-1.21/drivers/ifxmodem/voicecall.c
|
||||
===================================================================
|
||||
--- ofono-1.21.orig/drivers/ifxmodem/voicecall.c
|
||||
+++ ofono-1.21/drivers/ifxmodem/voicecall.c
|
||||
@@ -135,7 +135,7 @@ static void xcallstat_notify(GAtResult *
|
||||
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 &&
|
||||
@@ -773,7 +773,7 @@ static void xcolp_notify(GAtResult *resu
|
||||
|
||||
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;
|
||||
Index: ofono-1.21/drivers/stemodem/voicecall.c
|
||||
===================================================================
|
||||
--- ofono-1.21.orig/drivers/stemodem/voicecall.c
|
||||
+++ ofono-1.21/drivers/stemodem/voicecall.c
|
||||
@@ -462,7 +462,7 @@ static void ecav_notify(GAtResult *resul
|
||||
* 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;
|
||||
Index: ofono-1.21/src/common.c
|
||||
===================================================================
|
||||
--- ofono-1.21.orig/src/common.c
|
||||
+++ ofono-1.21/src/common.c
|
||||
@@ -791,6 +791,20 @@ gint ofono_call_compare_by_status(gconst
|
||||
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;
|
||||
+}
|
||||
+
|
||||
const char *ofono_call_status_to_string(enum call_status status)
|
||||
{
|
||||
switch (status) {
|
||||
Index: ofono-1.21/src/common.h
|
||||
===================================================================
|
||||
--- ofono-1.21.orig/src/common.h
|
||||
+++ ofono-1.21/src/common.h
|
||||
@@ -186,4 +186,5 @@ const char *packet_bearer_to_string(int
|
||||
gboolean is_valid_apn(const char *apn);
|
||||
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);
|
||||
const char *ofono_call_status_to_string(enum call_status status);
|
123
modem/ofono/0011-qmimodem-sync-the-modem-on-enable.patch
Normal file
123
modem/ofono/0011-qmimodem-sync-the-modem-on-enable.patch
Normal file
|
@ -0,0 +1,123 @@
|
|||
From 32dac2f67735efa1bbfcd7c5563d5cbc980c6770 Mon Sep 17 00:00:00 2001
|
||||
From: Alexander Couzens <lynxis@fe80.eu>
|
||||
Date: Tue, 25 Jul 2017 20:36:00 +0200
|
||||
Subject: [PATCH 11/17] qmimodem: sync the modem on enable
|
||||
|
||||
The qmi sync call release all previous resources.
|
||||
---
|
||||
drivers/qmimodem/qmi.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++
|
||||
drivers/qmimodem/qmi.h | 5 ++++-
|
||||
plugins/gobi.c | 12 +++++++++++-
|
||||
3 files changed, 62 insertions(+), 2 deletions(-)
|
||||
|
||||
Index: ofono-1.21/drivers/qmimodem/qmi.c
|
||||
===================================================================
|
||||
--- ofono-1.21.orig/drivers/qmimodem/qmi.c
|
||||
+++ ofono-1.21/drivers/qmimodem/qmi.c
|
||||
@@ -1323,6 +1323,53 @@ bool qmi_device_shutdown(struct qmi_devi
|
||||
return true;
|
||||
}
|
||||
|
||||
+struct sync_data {
|
||||
+ qmi_sync_func_t func;
|
||||
+ void *user_data;
|
||||
+};
|
||||
+
|
||||
+static void qmi_device_sync_callback(uint16_t message, uint16_t length,
|
||||
+ const void *buffer, void *user_data)
|
||||
+{
|
||||
+ struct sync_data *data = user_data;
|
||||
+
|
||||
+ if(data->func)
|
||||
+ data->func(data->user_data);
|
||||
+
|
||||
+ g_free(data);
|
||||
+}
|
||||
+
|
||||
+/* sync will release all previous clients */
|
||||
+bool qmi_device_sync(struct qmi_device *device,
|
||||
+ qmi_sync_func_t func, void *user_data)
|
||||
+{
|
||||
+ struct qmi_request *req;
|
||||
+ struct qmi_control_hdr *hdr;
|
||||
+ struct sync_data *func_data;
|
||||
+
|
||||
+ if (!device)
|
||||
+ return false;
|
||||
+
|
||||
+ func_data = g_new0(struct sync_data, 1);
|
||||
+ func_data->func = func;
|
||||
+ func_data->user_data = user_data;
|
||||
+
|
||||
+ req = __request_alloc(QMI_SERVICE_CONTROL, 0x00,
|
||||
+ QMI_CTL_SYNC, QMI_CONTROL_HDR_SIZE,
|
||||
+ NULL, 0,
|
||||
+ qmi_device_sync_callback, func_data, (void **) &hdr);
|
||||
+
|
||||
+ if (device->next_control_tid < 1)
|
||||
+ device->next_control_tid = 1;
|
||||
+
|
||||
+ hdr->type = 0x00;
|
||||
+ hdr->transaction = device->next_control_tid++;
|
||||
+
|
||||
+ __request_submit(device, req, hdr->transaction);
|
||||
+
|
||||
+ return true;
|
||||
+}
|
||||
+
|
||||
static bool get_device_file_name(struct qmi_device *device,
|
||||
char *file_name, int size)
|
||||
{
|
||||
Index: ofono-1.21/drivers/qmimodem/qmi.h
|
||||
===================================================================
|
||||
--- ofono-1.21.orig/drivers/qmimodem/qmi.h
|
||||
+++ ofono-1.21/drivers/qmimodem/qmi.h
|
||||
@@ -76,7 +76,7 @@ typedef void (*qmi_destroy_func_t)(void
|
||||
struct qmi_device;
|
||||
|
||||
typedef void (*qmi_debug_func_t)(const char *str, void *user_data);
|
||||
-
|
||||
+typedef void (*qmi_sync_func_t)(void *user_data);
|
||||
typedef void (*qmi_shutdown_func_t)(void *user_data);
|
||||
typedef void (*qmi_discover_func_t)(uint8_t count,
|
||||
const struct qmi_version *list, void *user_data);
|
||||
@@ -96,6 +96,9 @@ bool qmi_device_discover(struct qmi_devi
|
||||
bool qmi_device_shutdown(struct qmi_device *device, qmi_shutdown_func_t func,
|
||||
void *user_data, qmi_destroy_func_t destroy);
|
||||
|
||||
+bool qmi_device_sync(struct qmi_device *device,
|
||||
+ qmi_sync_func_t func, void *user_data);
|
||||
+
|
||||
enum qmi_device_expected_data_format qmi_device_get_expected_data_format(
|
||||
struct qmi_device *device);
|
||||
bool qmi_device_set_expected_data_format(struct qmi_device *device,
|
||||
Index: ofono-1.21/plugins/gobi.c
|
||||
===================================================================
|
||||
--- ofono-1.21.orig/plugins/gobi.c
|
||||
+++ ofono-1.21/plugins/gobi.c
|
||||
@@ -320,6 +320,16 @@ static void discover_cb(uint8_t count, c
|
||||
create_dms_cb, modem, NULL);
|
||||
}
|
||||
|
||||
+static void sync_cb(void *user_data)
|
||||
+{
|
||||
+ struct ofono_modem *modem = user_data;
|
||||
+ struct gobi_data *data = ofono_modem_get_data(modem);
|
||||
+
|
||||
+ DBG("modem in sync");
|
||||
+
|
||||
+ qmi_device_discover(data->device, discover_cb, modem, NULL);
|
||||
+}
|
||||
+
|
||||
static int gobi_enable(struct ofono_modem *modem)
|
||||
{
|
||||
struct gobi_data *data = ofono_modem_get_data(modem);
|
||||
@@ -347,7 +357,7 @@ static int gobi_enable(struct ofono_mode
|
||||
|
||||
qmi_device_set_close_on_unref(data->device, true);
|
||||
|
||||
- qmi_device_discover(data->device, discover_cb, modem, NULL);
|
||||
+ qmi_device_sync(data->device, sync_cb, modem);
|
||||
|
||||
return -EINPROGRESS;
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
From e3d6b09ab785af7e0eab4628592a8bb8239ef7a3 Mon Sep 17 00:00:00 2001
|
||||
From: Alexander Couzens <lynxis@fe80.eu>
|
||||
Date: Wed, 26 Jul 2017 02:11:23 +0200
|
||||
Subject: [PATCH 14/17] network/ofono_netreg_status_notify: debug output lac
|
||||
and ci
|
||||
|
||||
The location are code and cell id is updated at the same time.
|
||||
---
|
||||
src/network.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
Index: ofono-1.21/src/network.c
|
||||
===================================================================
|
||||
--- ofono-1.21.orig/src/network.c
|
||||
+++ ofono-1.21/src/network.c
|
||||
@@ -1351,8 +1351,8 @@ void ofono_netreg_status_notify(struct o
|
||||
if (netreg == NULL)
|
||||
return;
|
||||
|
||||
- DBG("%s status %d tech %d", __ofono_atom_get_path(netreg->atom),
|
||||
- status, tech);
|
||||
+ DBG("%s status %d tech %d lac %d ci %d",
|
||||
+ __ofono_atom_get_path(netreg->atom), status, tech, lac, ci);
|
||||
|
||||
if (netreg->status != status) {
|
||||
struct ofono_modem *modem;
|
|
@ -0,0 +1,25 @@
|
|||
From 8f00ef8b3b9be29ad6f58769234a30c6c5ae0d27 Mon Sep 17 00:00:00 2001
|
||||
From: Alexander Couzens <lynxis@fe80.eu>
|
||||
Date: Wed, 26 Jul 2017 02:12:16 +0200
|
||||
Subject: [PATCH 15/17] network: debug output the network time if updated
|
||||
|
||||
---
|
||||
src/network.c | 5 +++++
|
||||
1 file changed, 5 insertions(+)
|
||||
|
||||
Index: ofono-1.21/src/network.c
|
||||
===================================================================
|
||||
--- ofono-1.21.orig/src/network.c
|
||||
+++ ofono-1.21/src/network.c
|
||||
@@ -1407,6 +1407,11 @@ void ofono_netreg_time_notify(struct ofo
|
||||
if (info == NULL)
|
||||
return;
|
||||
|
||||
+ DBG("net time %d-%02d-%02d %02d:%02d:%02d utcoff %d dst %d",
|
||||
+ info->year, info->mon, info->mday,
|
||||
+ info->hour, info->min, info->sec,
|
||||
+ info->utcoff, info->dst);
|
||||
+
|
||||
__ofono_nettime_info_received(modem, info);
|
||||
}
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
From d43fde3c5e6165b8a977c8917c11e4d1a55eac3f Mon Sep 17 00:00:00 2001
|
||||
From: Alexander Couzens <lynxis@fe80.eu>
|
||||
Date: Tue, 25 Jul 2017 16:43:03 +0200
|
||||
Subject: [PATCH 16/17] voicecall: prefer release_specific() over
|
||||
hang_up_active/hangup_all
|
||||
|
||||
release_specific() has the call_id as parameter in difference to the more unspecific
|
||||
calls hangup_all and hangup_active.
|
||||
---
|
||||
src/voicecall.c | 21 +++++++++++----------
|
||||
1 file changed, 11 insertions(+), 10 deletions(-)
|
||||
|
||||
Index: ofono-1.21/src/voicecall.c
|
||||
===================================================================
|
||||
--- ofono-1.21.orig/src/voicecall.c
|
||||
+++ ofono-1.21/src/voicecall.c
|
||||
@@ -542,10 +542,18 @@ static DBusMessage *voicecall_hangup(DBu
|
||||
if (vc->dial_req && vc->dial_req->call != v)
|
||||
return __ofono_error_busy(msg);
|
||||
|
||||
- switch (call->status) {
|
||||
- case CALL_STATUS_DISCONNECTED:
|
||||
+ if (call->status == CALL_STATUS_DISCONNECTED)
|
||||
return __ofono_error_failed(msg);
|
||||
|
||||
+ if (vc->driver->release_specific) {
|
||||
+ vc->pending = dbus_message_ref(msg);
|
||||
+ vc->driver->release_specific(vc, call->id,
|
||||
+ generic_callback, vc);
|
||||
+
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ switch (call->status) {
|
||||
case CALL_STATUS_INCOMING:
|
||||
if (vc->driver->hangup_all == NULL &&
|
||||
vc->driver->hangup_active == NULL)
|
||||
@@ -615,14 +623,7 @@ static DBusMessage *voicecall_hangup(DBu
|
||||
break;
|
||||
}
|
||||
|
||||
- if (vc->driver->release_specific == NULL)
|
||||
- return __ofono_error_not_implemented(msg);
|
||||
-
|
||||
- vc->pending = dbus_message_ref(msg);
|
||||
- vc->driver->release_specific(vc, call->id,
|
||||
- generic_callback, vc);
|
||||
-
|
||||
- return NULL;
|
||||
+ return __ofono_error_not_implemented(msg);
|
||||
}
|
||||
|
||||
static DBusMessage *voicecall_answer(DBusConnection *conn,
|
976
modem/ofono/0017-RFC-qmimodem-implement-voice-calls.patch
Normal file
976
modem/ofono/0017-RFC-qmimodem-implement-voice-calls.patch
Normal file
|
@ -0,0 +1,976 @@
|
|||
From df3b0c1cd8be029ff2c98c2ba7ba1110385a17f6 Mon Sep 17 00:00:00 2001
|
||||
From: Alexander Couzens <lynxis@fe80.eu>
|
||||
Date: Tue, 25 Jul 2017 15:31:48 +0200
|
||||
Subject: [PATCH 17/17] [RFC] qmimodem: implement voice calls
|
||||
|
||||
The voice_generated.* files is an RFC how files should look like.
|
||||
They aren't yet generated.
|
||||
---
|
||||
Makefile.am | 5 +-
|
||||
drivers/qmimodem/qmi.h | 13 ++
|
||||
drivers/qmimodem/voice.c | 86 ++++++++++
|
||||
drivers/qmimodem/voice.h | 84 ++++++++++
|
||||
drivers/qmimodem/voice_generated.c | 210 +++++++++++++++++++++++
|
||||
drivers/qmimodem/voice_generated.h | 113 +++++++++++++
|
||||
drivers/qmimodem/voicecall.c | 332 ++++++++++++++++++++++++++++++++++++-
|
||||
7 files changed, 840 insertions(+), 3 deletions(-)
|
||||
create mode 100644 drivers/qmimodem/voice.c
|
||||
create mode 100644 drivers/qmimodem/voice.h
|
||||
create mode 100644 drivers/qmimodem/voice_generated.c
|
||||
create mode 100644 drivers/qmimodem/voice_generated.h
|
||||
|
||||
Index: ofono-1.21/Makefile.am
|
||||
===================================================================
|
||||
--- ofono-1.21.orig/Makefile.am
|
||||
+++ ofono-1.21/Makefile.am
|
||||
@@ -216,7 +216,9 @@ qmi_sources = drivers/qmimodem/qmi.h dri
|
||||
drivers/qmimodem/wds.h \
|
||||
drivers/qmimodem/pds.h \
|
||||
drivers/qmimodem/common.h \
|
||||
- drivers/qmimodem/wda.h
|
||||
+ drivers/qmimodem/wda.h \
|
||||
+ drivers/qmimodem/voice.h \
|
||||
+ drivers/qmimodem/voice.c
|
||||
|
||||
builtin_modules += qmimodem
|
||||
builtin_sources += $(qmi_sources) \
|
||||
@@ -225,6 +227,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 \
|
||||
Index: ofono-1.21/drivers/qmimodem/qmi.h
|
||||
===================================================================
|
||||
--- ofono-1.21.orig/drivers/qmimodem/qmi.h
|
||||
+++ ofono-1.21/drivers/qmimodem/qmi.h
|
||||
@@ -19,6 +19,9 @@
|
||||
*
|
||||
*/
|
||||
|
||||
+#ifndef __OFONO_QMI_QMI_H
|
||||
+#define __OFONO_QMI_QMI_H
|
||||
+
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
@@ -175,3 +178,13 @@ uint16_t qmi_service_register(struct qmi
|
||||
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 */
|
||||
Index: ofono-1.21/drivers/qmimodem/voice.c
|
||||
===================================================================
|
||||
--- /dev/null
|
||||
+++ ofono-1.21/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;
|
||||
+}
|
||||
+
|
||||
Index: ofono-1.21/drivers/qmimodem/voice.h
|
||||
===================================================================
|
||||
--- /dev/null
|
||||
+++ ofono-1.21/drivers/qmimodem/voice.h
|
||||
@@ -0,0 +1,84 @@
|
||||
+/*
|
||||
+ *
|
||||
+ * 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.
|
||||
+ *
|
||||
+ */
|
||||
+
|
||||
+enum call_direction;
|
||||
+
|
||||
+enum ussd_dcs {
|
||||
+ USS_DCS_ASCII = 0x1,
|
||||
+ USS_DCS_8BIT,
|
||||
+ USS_DCS_UCS2,
|
||||
+};
|
||||
+
|
||||
+enum ussd_user_required {
|
||||
+ NO_USER_ACTION_REQUIRED = 0x1,
|
||||
+ USER_ACTION_REQUIRED = 0x2,
|
||||
+};
|
||||
+
|
||||
+struct qmi_ussd_data {
|
||||
+ uint8_t dcs;
|
||||
+ uint8_t length;
|
||||
+ uint8_t data[0];
|
||||
+} __attribute__((__packed__));
|
||||
+
|
||||
+enum voice_commands {
|
||||
+ QMI_VOICE_CANCEL_USSD = 0x3c,
|
||||
+ QMI_VOICE_USSD_RELEASE_IND = 0x3d,
|
||||
+ QMI_VOICE_USSD_IND = 0x3e,
|
||||
+ QMI_VOICE_SUPS_IND = 0x42,
|
||||
+ 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,
|
||||
+};
|
||||
+
|
||||
+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);
|
||||
+
|
||||
+#define QMI_VOICE_IND_ALL_STATUS 0x2e
|
||||
+
|
||||
+#define QMI_VOICE_PARAM_USS_DATA 0x01
|
||||
+
|
||||
+#define QMI_VOICE_PARAM_ASYNC_USSD_ERROR 0x10
|
||||
+#define QMI_VOICE_PARAM_ASYNC_USSD_FAILURE_CASE 0x11
|
||||
+#define QMI_VOICE_PARAM_ASYNC_USSD_DATA 0x12
|
||||
+
|
||||
+#define QMI_VOICE_PARAM_USSD_IND_USER_ACTION 0x01
|
||||
+#define QMI_VOICE_PARAM_USSD_IND_DATA 0x10
|
||||
+#define QMI_VOICE_PARAM_USSD_IND_UCS2 0x11
|
||||
+
|
||||
+/* according to GSM TS 23.038 */
|
||||
+#define USSD_DCS_8BIT 0xf4
|
||||
+#define USSD_DCS_UCS2 0x48
|
||||
+#define USSD_DCS_UNSPECIFIC 0x0f
|
||||
Index: ofono-1.21/drivers/qmimodem/voice_generated.c
|
||||
===================================================================
|
||||
--- /dev/null
|
||||
+++ ofono-1.21/drivers/qmimodem/voice_generated.c
|
||||
@@ -0,0 +1,210 @@
|
||||
+
|
||||
+#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)
|
||||
+ {
|
||||
+ int instance_size = sizeof(struct qmi_voice_call_information_instance);
|
||||
+ /* 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;
|
||||
+}
|
||||
Index: ofono-1.21/drivers/qmimodem/voice_generated.h
|
||||
===================================================================
|
||||
--- /dev/null
|
||||
+++ ofono-1.21/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 */
|
||||
Index: ofono-1.21/drivers/qmimodem/voicecall.c
|
||||
===================================================================
|
||||
--- ofono-1.21.orig/drivers/qmimodem/voicecall.c
|
||||
+++ ofono-1.21/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,113 @@
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
+#include <string.h>
|
||||
+
|
||||
#include <ofono/log.h>
|
||||
#include <ofono/modem.h>
|
||||
#include <ofono/voicecall.h>
|
||||
+#include <ofono/call-list.h>
|
||||
|
||||
-#include "qmi.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;
|
||||
+ GSList *n, *o;
|
||||
+ struct ofono_call *nc, *oc;
|
||||
+
|
||||
+
|
||||
+ 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)
|
||||
+ 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 +152,12 @@ static void create_voice_cb(struct qmi_s
|
||||
|
||||
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 +177,6 @@ static int qmi_voicecall_probe(struct of
|
||||
create_voice_cb, vc, NULL);
|
||||
|
||||
return 0;
|
||||
-
|
||||
}
|
||||
|
||||
static void qmi_voicecall_remove(struct ofono_voicecall *vc)
|
||||
@@ -92,13 +191,242 @@ static void qmi_voicecall_remove(struct
|
||||
|
||||
qmi_service_unref(data->voice);
|
||||
|
||||
+ g_slist_free_full(data->call_list, g_free);
|
||||
+
|
||||
g_free(data);
|
||||
}
|
||||
|
||||
+
|
||||
+static struct ofono_call *create_call(struct ofono_voicecall *vc,
|
||||
+ enum call_direction direction,
|
||||
+ enum call_status status,
|
||||
+ const char *num,
|
||||
+ int num_type,
|
||||
+ int clip)
|
||||
+{
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+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;
|
||||
+ struct ofono_call *call;
|
||||
+
|
||||
+ 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;
|
||||
+ struct ofono_voicecall *vc = cbd->user;
|
||||
+ ofono_voicecall_cb_t cb = cbd->cb;
|
||||
+ uint16_t error;
|
||||
+ struct qmi_voice_answer_call_result answer_result;
|
||||
+ struct ofono_call *call;
|
||||
+
|
||||
+ 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;
|
||||
+ struct ofono_voicecall *vc = cbd->user;
|
||||
+ ofono_voicecall_cb_t cb = cbd->cb;
|
||||
+ uint16_t error;
|
||||
+ struct qmi_voice_end_call_result end_result;
|
||||
+ struct ofono_call *call;
|
||||
+
|
||||
+ 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;
|
||||
+ int i;
|
||||
+
|
||||
+ 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 qmi_voice_end_call_arg arg;
|
||||
+ struct ofono_call *call;
|
||||
+ GSList *list = NULL;
|
||||
+ enum call_status active[] = {
|
||||
+ CALL_STATUS_ACTIVE,
|
||||
+ CALL_STATUS_DIALING,
|
||||
+ CALL_STATUS_ALERTING
|
||||
+ };
|
||||
+ int i;
|
||||
+
|
||||
+ DBG("");
|
||||
+ for (i = 0; i < ARRAY_SIZE(active); i++) {
|
||||
+ list = g_slist_find_custom(vd->call_list,
|
||||
+ GINT_TO_POINTER(CALL_STATUS_ACTIVE),
|
||||
+ 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 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,13 +2,13 @@
|
|||
pkgname=ofono
|
||||
_upstreamver=1.21
|
||||
pkgver=1.21_p20180307
|
||||
pkgrel=2
|
||||
pkgrel=3
|
||||
pkgdesc="Infrastructure for building mobile telephony (GSM/UMTS) applications"
|
||||
url="https://01.org/ofono"
|
||||
arch="all"
|
||||
license="GPL2"
|
||||
depends="bluez mobile-broadband-provider-info"
|
||||
makedepends="glib-dev dbus-dev eudev-dev
|
||||
makedepends="autoconf automake libtool glib-dev dbus-dev eudev-dev
|
||||
linux-headers bsd-compat-headers libexecinfo-dev
|
||||
mobile-broadband-provider-info"
|
||||
options="!check"
|
||||
|
@ -18,12 +18,24 @@ source="https://www.kernel.org/pub/linux/network/$pkgname/$pkgname-$_upstreamver
|
|||
0001-nokia-gpio-do-not-create-links-to-gpios-in-dev-cmt.patch::https://git.alpinelinux.org/cgit/aports/plain/testing/ofono/0001-nokia-gpio-do-not-create-links-to-gpios-in-dev-cmt.patch?id=014ae282b4a9152a5b64451f2815f34fcb53507c
|
||||
support-smdpkt.patch
|
||||
udev.rules
|
||||
0001-doc-ofonod.8-escape-minus-sign.patch
|
||||
0002-common-create-GList-helper-ofono_call_compare.patch
|
||||
0003-voicecall-common-promote-call_status_to_string-publi.patch
|
||||
0006-add-call-list-helper-to-manage-voice-call-lists.patch
|
||||
0007-common-atmodem-rename-move-at_util_call_compare_by_s.patch
|
||||
0008-common-atmodem-rename-move-at_util_call_compare_by_i.patch
|
||||
0011-qmimodem-sync-the-modem-on-enable.patch
|
||||
0014-network-ofono_netreg_status_notify-debug-output-lac-.patch
|
||||
0015-network-debug-output-the-network-time-if-updated.patch
|
||||
0016-voicecall-prefer-release_specific-over-hang_up_activ.patch
|
||||
0017-RFC-qmimodem-implement-voice-calls.patch
|
||||
"
|
||||
|
||||
builddir="$srcdir"/$pkgname-$_upstreamver
|
||||
|
||||
build() {
|
||||
cd "$builddir"
|
||||
autoreconf --install
|
||||
./configure \
|
||||
--prefix=/usr \
|
||||
--sysconfdir=/etc \
|
||||
|
@ -45,4 +57,15 @@ sha512sums="bbc7fdb1d05294839eee5f31ec345866315a80feac8ccc2a67e0ca2c1030c55e0fb4
|
|||
fd0d303ca71df6953155aac0624c847f273030ebc5fb12efe2fa2ae7b8d75380e2885ab08d9c65c80cf756ef952569832ffdc25317e86a99552b4caac322b3ed ofono.initd
|
||||
a1f66f3f40c1aa4af5f5b66436414408b46f3c90f2a2c88fa12e09ca6a1732334d2f47687478d652a3a176ee93c1905752635246fd01412834565626c021ca64 0001-nokia-gpio-do-not-create-links-to-gpios-in-dev-cmt.patch
|
||||
b946ac618aa2ab864876f7a81b689a0c3b776ad66657aaac508a52ea803d7031378dab0d7292ee41caba3e35b6e15d7309910c754a5762de7754be813c257b82 support-smdpkt.patch
|
||||
8f2893dfc291fc210ef217c4bc74d79436a0997001dd2773809625d52dd19d092cc75d3f9aa5ed2f3d4a6248d4a4e17013a7655323f7dad951f744c55b572417 udev.rules"
|
||||
8f2893dfc291fc210ef217c4bc74d79436a0997001dd2773809625d52dd19d092cc75d3f9aa5ed2f3d4a6248d4a4e17013a7655323f7dad951f744c55b572417 udev.rules
|
||||
e602504d41a0c28f99db138255eb9f0f020e59c26fcabc99f2bbe9f4e3d3c99b33ffb247a362569c841f55111b7fd8db0b18e98c3497ef04aa9bde467b86475d 0001-doc-ofonod.8-escape-minus-sign.patch
|
||||
1ffa1c7c0a99aabf5e064f7c99db43727942365c8b76b2d3e6278e4995570a067e73755e1111f8bcf3f1574b4d24d427c48fe2dc474ad89099d5d818b597fcb5 0002-common-create-GList-helper-ofono_call_compare.patch
|
||||
4658e7dfdb9167f97c279a55fb2b53d5c33eda87c54cd7fcaaaf489e2b6d2d6b2b487b415ee616827d4388e379a842833860809103010d8b1be75b76505cf8c8 0003-voicecall-common-promote-call_status_to_string-publi.patch
|
||||
0de8030dad134851cacc9564186aef07db94ab72c914c03326a0e8070e764a3fd47cc921a49bbf6c0828692599005e0dd412b808abb9adfd6b7bc49fcd176b93 0006-add-call-list-helper-to-manage-voice-call-lists.patch
|
||||
1ecf593363e25b51cff36d692afd12886877c82b75fce853d137dd0c5fa2910ece4a3a18744b563e898be7df254826c80861f2bb0a113d9c2d9cde686b2297ac 0007-common-atmodem-rename-move-at_util_call_compare_by_s.patch
|
||||
a1b04a014e7643105529b6060577555747c1094c0fc770c99e5fc5b8b97843ba3a23577e33ffa7a77379ef02669ebe96dbf1c25271cf2fd5ab11dabb21aeb588 0008-common-atmodem-rename-move-at_util_call_compare_by_i.patch
|
||||
1664244d301267537423f47d57b67374659c81fc073435507be6845c0a8fec776cc3dd18e3781040e173a92610b6f0cf78a59378414948eb881e8c7cdf9b7322 0011-qmimodem-sync-the-modem-on-enable.patch
|
||||
1e6bce11888ce11080a6dd07c487836104abc52be3e908c96eac412ce17941aadfd19bab386706cb9491e6ecf9666efac7cb85db98ca50dd920928a3c502157a 0014-network-ofono_netreg_status_notify-debug-output-lac-.patch
|
||||
61728285a5247e964d71d2f93d6aa62967ba9be978d41f99928829e3a753124830aede022b86eb5b39b04485afba1a1f2bb7595b0cec5a04899b74297f9297ab 0015-network-debug-output-the-network-time-if-updated.patch
|
||||
6d85d384261af82314d11310150dc37b01bbf89b6cb3c3b5576724a97cdbf96f67a02bf3828560d773a6ff1271202cf290606070f41d52af16bbea320e48f660 0016-voicecall-prefer-release_specific-over-hang_up_activ.patch
|
||||
25279f9570b4312100c87bb7d17c39bdeea04acce19414503a9274befc3ff07383488433d9900540933e8e409eed3b47996196d50c9a40f9d01e921066701b64 0017-RFC-qmimodem-implement-voice-calls.patch"
|
||||
|
|
Loading…
Reference in a new issue