Something wrong with PushNotification interface?
by Cahill, Ben M
Trying to send DBUS message to ofono's PushNotification interface is apparently crashing the DBUS connection for me. Even when trying to send message from d-feet, d-feet (the app itself) shuts down instantly. Can't find any error message anywhere (not even from DBG statements that I added to ofono's push_notification_register_agent() function ... message apparently doesn't get that far).
Anyone else see the same thing?
I've seen in DBUS spec that DBUS should silently close the connection if spec or protocol gets violated; wondering if this is happening?
I'm no DBUS expert, and have spent a couple days trying to chase this down. :-(
Here's what I do to reproduce the problem (using phonesim):
# ofonod -n -d '*'
$ src/phonesim -p 12345 -gui src/default.xml
# d-feet
Click on "org.ofono" in left window
navigate to /phonesim/org.ofono.Modem/Methods
SetProperty "Powered", True
SetProperty "Online", True
(so far, so good)
Click again on "org.ofono" in left window to refresh object path tree
navigate to /phonesim/Interfaces/org.ofono.PushNotification/Methods
double-click "RegisterAgent"
RegisterAgent "/org.xyz/PushNotificationAgent"
(d-feet GUI disappears, and new command line prompt appears)
(if I were using the daemon I'm developing, it would report "System bus has disconnected" and exit)
Any ideas?
-- Ben --
11 years, 9 months
[RFC PATCH] stk: add support of next action for menu
by Lucas, GuillaumeX
From: Guillaume Lucas <guillaumex.lucas(a)intel.com>
According to the 3GPP 31.124 the support of next action
in SIM toolkit menus is mandatory.
---
doc/stk-api.txt | 5 +++--
src/stk.c | 6 ++++++
src/stkagent.c | 6 ++++--
src/stkagent.h | 1 +
test/test-stk-menu | 6 +++---
5 files changed, 17 insertions(+), 7 deletions(-)
diff --git a/doc/stk-api.txt b/doc/stk-api.txt
index 79daee6..f5bcae4 100644
--- a/doc/stk-api.txt
+++ b/doc/stk-api.txt
@@ -66,13 +66,14 @@ Properties string IdleModeText [readonly]
Contains the identifier of the icon accompanying
the idle mode text.
- array{struct{string, byte}} MainMenu [readonly]
+ array{struct{string, byte, byte}} MainMenu [readonly]
Contains the items that make up the main menu. This
is populated by the SIM when it sends the Setup Menu
Proactive Command. The main menu is always available,
but its contents can be changed at any time. Each
- item contains the item label and icon identifier.
+ item contains the item label, the icon identifier and
+ the next action identifier.
string MainMenuTitle [readonly]
diff --git a/src/stk.c b/src/stk.c
index 7b39f7e..086b540 100644
--- a/src/stk.c
+++ b/src/stk.c
@@ -320,6 +320,7 @@ static struct stk_menu *stk_menu_create(const char *title,
const struct stk_icon_id *icon, GSList *items,
const struct stk_item_text_attribute_list *item_attrs,
const struct stk_item_icon_id_list *item_icon_ids,
+ const struct stk_items_next_action_indicator *next_act,
int default_id, gboolean soft_key, gboolean has_help)
{
unsigned int len = g_slist_length(items);
@@ -374,6 +375,9 @@ static struct stk_menu *stk_menu_create(const char *title,
if (item_icon_ids && item_icon_ids->len)
ret->items[i].icon_id = item_icon_ids->list[i];
+ if (next_act && next_act->len)
+ ret->items[i].next_act = next_act->list[i];
+
if (item->id == default_id)
ret->default_item = i;
}
@@ -393,6 +397,7 @@ static struct stk_menu *stk_menu_create_from_set_up_menu(
cmd->setup_menu.items,
&cmd->setup_menu.item_text_attr_list,
&cmd->setup_menu.item_icon_id_list,
+ &cmd->setup_menu.next_act,
0, soft_key, has_help);
}
@@ -408,6 +413,7 @@ static struct stk_menu *stk_menu_create_from_select_item(
cmd->select_item.items,
&cmd->select_item.item_text_attr_list,
&cmd->select_item.item_icon_id_list,
+ &cmd->select_item.next_act,
cmd->select_item.item_id, soft_key, has_help);
}
diff --git a/src/stkagent.c b/src/stkagent.c
index e1a6f48..5175776 100644
--- a/src/stkagent.c
+++ b/src/stkagent.c
@@ -246,7 +246,7 @@ static void append_menu_items(DBusMessageIter *iter,
DBusMessageIter array, entry;
dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY,
- "(sy)", &array);
+ "(syy)", &array);
while (item && item->text) {
dbus_message_iter_open_container(&array, DBUS_TYPE_STRUCT,
@@ -256,6 +256,8 @@ static void append_menu_items(DBusMessageIter *iter,
&item->text);
dbus_message_iter_append_basic(&entry, DBUS_TYPE_BYTE,
&item->icon_id);
+ dbus_message_iter_append_basic(&entry, DBUS_TYPE_BYTE,
+ &item->next_act);
dbus_message_iter_close_container(&array, &entry);
item++;
@@ -270,7 +272,7 @@ void append_menu_items_variant(DBusMessageIter *iter,
DBusMessageIter variant;
dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT,
- "a(sy)", &variant);
+ "a(syy)", &variant);
append_menu_items(&variant, items);
diff --git a/src/stkagent.h b/src/stkagent.h
index 517bcfe..938b2f8 100644
--- a/src/stkagent.h
+++ b/src/stkagent.h
@@ -33,6 +33,7 @@ struct stk_menu_item {
char *text;
uint8_t icon_id;
uint8_t item_id;
+ uint8_t next_act;
};
struct stk_menu {
diff --git a/test/test-stk-menu b/test/test-stk-menu
index 94d2d6b..32976a5 100755
--- a/test/test-stk-menu
+++ b/test/test-stk-menu
@@ -27,12 +27,12 @@ class StkAgent(dbus.service.Object):
mainloop.quit()
@dbus.service.method("org.ofono.SimToolkitAgent",
- in_signature="sya(sy)n", out_signature="y")
+ in_signature="sya(syy)n", out_signature="y")
def RequestSelection(self, title, icon, items, default):
print "Title: (%s)" % (title)
index = 0;
for item in items:
- print "%d. %s" % (index, item[0])
+ print "%d. %s (%d, %d)" % (index, item[0], item[1], item[2])
index += 1
print "\nDefault: %d" % (default)
@@ -175,7 +175,7 @@ if __name__ == '__main__':
print "Items:"
index = 0
for item in properties["MainMenu"]:
- print "%d. %s" % (index, item[0])
+ print "%d. %s (%d, %d)" % (index, item[0], item[1], item[2])
index += 1
path = "/test/agent"
--
1.7.0.4
---------------------------------------------------------------------
Intel Corporation SAS (French simplified joint stock company)
Registered headquarters: "Les Montalets"- 2, rue de Paris,
92196 Meudon Cedex, France
Registration Number: 302 456 199 R.C.S. NANTERRE
Capital: 4,572,000 Euros
This e-mail and any attachments may contain confidential material for
the sole use of the intended recipient(s). Any review or distribution
by others is strictly prohibited. If you are not the intended
recipient, please contact the sender and delete all copies.
11 years, 9 months
[PATCH 0/5] Call Counters (2nd)
by Andras Domokos
Here a proposal for call counters implementation for keeping track
of the total incoming and outgoing call duration counters. Each
established call instance is contributing to either of the call
duration counters. The 2 counters are updated periodically when
there is an established call and the information is stored in
a file. The bookkeeping of the call duration counters are per IMSI
number.
The implementation makes use of the history framework which had to be
expanded with a function for marking the beginning of a voice call.
There is a D-Bus interface to call counters for reading and clearing
the counters.
Andras Domokos (5):
history: expand history API include file
history: expand history API
voicecall: take into use the new history function
plugins: add call counters
doc: call counters API doc
Makefile.am | 3 +
doc/callcounters-api.txt | 18 ++
include/history.h | 3 +
plugins/callcounters.c | 388 ++++++++++++++++++++++++++++++++++++++++++++++
src/history.c | 24 +++
src/ofono.h | 4 +
src/voicecall.c | 3 +
7 files changed, 443 insertions(+), 0 deletions(-)
create mode 100644 doc/callcounters-api.txt
create mode 100644 plugins/callcounters.c
11 years, 9 months
[PATCH] ifx: adding Infineon modem self test
by Robertino Benis
Hi,
Adding Infineon modem selftest to the plugin. It executes couple of AT
commands, and based on the responses, it continues with ifx modem
enabling or powers the modem down.
Thanks,
-- r.
---
plugins/ifx.c | 98 +++++++++++++++++++++++++++++++++++++++++++++++++++++---
1 files changed, 92 insertions(+), 6 deletions(-)
diff --git a/plugins/ifx.c b/plugins/ifx.c
index 2f4c65b..fcc57c0 100644
--- a/plugins/ifx.c
+++ b/plugins/ifx.c
@@ -80,6 +80,12 @@ static const char *dlc_nodes[NUM_DLC] = { "/dev/ttyGSM1", "/dev/ttyGSM2",
static const char *none_prefix[] = { NULL };
static const char *xdrv_prefix[] = { "+XDRV:", NULL };
+static const char *empty_prefix[] = { "", NULL };
+
+static const char *modem_self_tests[][2] = {
+ { "RTC Test", "at@rtc:rtc_gti_test_verify_32khz()" },
+ { "Version Info Test", "at@vers:device_version_id()" },
+ { NULL, NULL } };
struct ifx_data {
GIOChannel *device;
@@ -99,6 +105,8 @@ struct ifx_data {
int audio_loopback;
struct ofono_sim *sim;
gboolean have_sim;
+ guint self_test_timeout;
+ int self_test_idx;
};
static void ifx_debug(const char *str, void *user_data)
@@ -545,6 +553,82 @@ static gboolean mux_timeout_cb(gpointer user_data)
return FALSE;
}
+static gboolean self_test_timeout_cb(gpointer user_data)
+{
+ struct ofono_modem *modem = user_data;
+ struct ifx_data *data = ofono_modem_get_data(modem);
+
+ ofono_error("Timeout with modem self_test");
+ g_source_remove(data->self_test_timeout);
+ data->self_test_timeout = 0;
+
+ shutdown_device(data);
+ ofono_modem_set_powered(modem, FALSE);
+ return FALSE;
+}
+
+static void ifx_self_test_get_device_resp(GAtResult *result, int test_id)
+{
+ GAtResultIter iter;
+ const char *str;
+
+ ofono_info("Modem Response: %s",
+ modem_self_tests[test_id][0]);
+
+ g_at_result_iter_init(&iter, result);
+
+ while (g_at_result_iter_next(&iter, NULL)) {
+
+ if (g_at_result_iter_next_string(&iter, &str))
+ ofono_info("Modem Response: %s", str);
+ }
+}
+
+static void ifx_self_test_cb(gboolean ok, GAtResult *result,
+ gpointer user_data)
+{
+ struct ofono_modem *modem = user_data;
+ struct ifx_data *data = ofono_modem_get_data(modem);
+
+ if (ok) {
+
+ if (data->self_test_timeout > 0) {
+ g_source_remove(data->self_test_timeout);
+ data->self_test_timeout = 0;
+ }
+
+ ifx_self_test_get_device_resp(result, data->self_test_idx);
+ data->self_test_idx++;
+
+ if (modem_self_tests[data->self_test_idx][1] != NULL) {
+
+ g_at_chat_send(data->dlcs[AUX_DLC],
+ modem_self_tests[data->self_test_idx][1],
+ empty_prefix, ifx_self_test_cb, modem, NULL);
+
+ data->self_test_timeout = g_timeout_add_seconds(10,
+ self_test_timeout_cb, modem);
+ return;
+
+ } else {
+
+ /* Enable MUX Channels */
+ data->frame_size = 1509;
+ g_at_chat_send(data->dlcs[AUX_DLC],
+ "AT+CMUX=0,0,,1509,10,3,30,,", NULL,
+ mux_setup_cb, modem, NULL);
+
+ data->mux_init_timeout = g_timeout_add_seconds(5,
+ mux_timeout_cb, modem);
+ return;
+ }
+ }
+
+ ofono_error("Modem %s: FAIL", modem_self_tests[data->self_test_idx][0]);
+ shutdown_device(data);
+ ofono_modem_set_powered(modem, FALSE);
+}
+
static int ifx_enable(struct ofono_modem *modem)
{
struct ifx_data *data = ofono_modem_get_data(modem);
@@ -598,15 +682,17 @@ static int ifx_enable(struct ofono_modem *modem)
g_at_chat_send(chat, "ATE0 +CMEE=1", NULL,
NULL, NULL, NULL);
- data->frame_size = 1509;
+ /* Execute Modem Self tests */
- g_at_chat_send(chat, "AT+CMUX=0,0,,1509,10,3,30,,", NULL,
- mux_setup_cb, modem, NULL);
+ data->dlcs[AUX_DLC] = chat;
+ data->self_test_idx = 0;
- data->mux_init_timeout = g_timeout_add_seconds(5, mux_timeout_cb,
- modem);
+ g_at_chat_send(data->dlcs[AUX_DLC],
+ modem_self_tests[data->self_test_idx][1],
+ empty_prefix, ifx_self_test_cb, modem, NULL);
- data->dlcs[AUX_DLC] = chat;
+ data->self_test_timeout = g_timeout_add_seconds(10,
+ self_test_timeout_cb, modem);
return -EINPROGRESS;
}
--
1.7.0.4
11 years, 9 months
Fix issues in ofono_sim_get_phase and its usage
by Jeevaka Badrappan
Hi,
Following patch adds the missing OFONO_SIM_PHASE_UNKNOWN check in some
of the functions which uses ofono_sim_get_phase. Also fixed the issue
in ofono_get_sim_phase when the passed sim paramter is NULL.
Jeevaka Badrappan (2):
sim: fix minor issue in ofono_sim_get_phase
simfs: Add unknown sim phase check
src/sim.c | 2 +-
src/simfs.c | 9 ++++++++-
2 files changed, 9 insertions(+), 2 deletions(-)
11 years, 9 months
[PATCH] Specify vendor ID for Huawei modem while creating GPRS context
by Tonny Tzeng
---
plugins/huawei.c | 8 ++++----
1 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/plugins/huawei.c b/plugins/huawei.c
index 25dfaca..32cf70d 100644
--- a/plugins/huawei.c
+++ b/plugins/huawei.c
@@ -454,7 +454,7 @@ static void huawei_disconnect(gpointer user_data)
data->sim_state == HUAWEI_SIM_STATE_INVALID_CS) {
ofono_info("Reopened GPRS context channel");
- data->gc = ofono_gprs_context_create(modem, 0, "atmodem",
+ data->gc = ofono_gprs_context_create(modem, OFONO_VENDOR_HUAWEI,
"atmodem",
data->modem);
if (data->gprs && data->gc)
@@ -631,12 +631,12 @@ static void huawei_post_online(struct ofono_modem
*modem)
if (data->sim_state == HUAWEI_SIM_STATE_VALID ||
data->sim_state == HUAWEI_SIM_STATE_INVALID_CS) {
- data->gprs = ofono_gprs_create(modem, 0, "atmodem", data->pcui);
+ data->gprs = ofono_gprs_create(modem, OFONO_VENDOR_HUAWEI, "atmodem",
data->pcui);
if (data->ndis == TRUE)
- data->gc = ofono_gprs_context_create(modem, 0,
+ data->gc = ofono_gprs_context_create(modem, OFONO_VENDOR_HUAWEI,
"huaweimodem", data->pcui);
else
- data->gc = ofono_gprs_context_create(modem, 0,
+ data->gc = ofono_gprs_context_create(modem, OFONO_VENDOR_HUAWEI,
"atmodem", data->modem);
if (data->gprs && data->gc)
--
1.7.2.2
11 years, 9 months
[PATCH v2] Skip unsolicied CREG/CGREG correctly while checking GPRS attach status
by Tonny Tzeng
This patch is to skip unsolicited CGREG while checking the GPRS attach
status, especially for Huawei modem which sends lac and ci strings in
unquoted format, and casues at_util_parse_reg() return lac value as
status.
---
drivers/atmodem/atutil.c | 12 ++++++++----
gatchat/gatresult.c | 5 +++++
gatchat/gatresult.h | 1 +
3 files changed, 14 insertions(+), 4 deletions(-)
diff --git a/drivers/atmodem/atutil.c b/drivers/atmodem/atutil.c
index b6f0d92..c190aa2 100644
--- a/drivers/atmodem/atutil.c
+++ b/drivers/atmodem/atutil.c
@@ -243,13 +243,11 @@ gboolean at_util_parse_reg(GAtResult *result,
const char *prefix,
if (g_at_result_iter_next_number(&iter, &s) == FALSE)
continue;
- /* Some firmware will report bogus lac/ci when unregistered */
- if (s != 1 && s != 5)
- goto out;
-
switch (vendor) {
case OFONO_VENDOR_HUAWEI:
case OFONO_VENDOR_NOVATEL:
+ if (g_at_result_iter_eol(&iter))
+ continue;
r = g_at_result_iter_next_unquoted_string(&iter, &str);
if (r == TRUE)
@@ -257,6 +255,8 @@ gboolean at_util_parse_reg(GAtResult *result, const
char *prefix,
else
goto out;
+ if (g_at_result_iter_eol(&iter))
+ continue;
r = g_at_result_iter_next_unquoted_string(&iter, &str);
if (r == TRUE)
@@ -266,11 +266,15 @@ gboolean at_util_parse_reg(GAtResult *result,
const char *prefix,
break;
default:
+ if (g_at_result_iter_eol(&iter))
+ continue;
if (g_at_result_iter_next_string(&iter, &str) == TRUE)
l = strtol(str, NULL, 16);
else
goto out;
+ if (g_at_result_iter_eol(&iter))
+ continue;
if (g_at_result_iter_next_string(&iter, &str) == TRUE)
c = strtol(str, NULL, 16);
else
diff --git a/gatchat/gatresult.c b/gatchat/gatresult.c
index 8a6dfae..c919305 100644
--- a/gatchat/gatresult.c
+++ b/gatchat/gatresult.c
@@ -39,6 +39,11 @@ void g_at_result_iter_init(GAtResultIter *iter,
GAtResult *result)
iter->line_pos = 0;
}
+gboolean g_at_result_iter_eol(GAtResultIter *iter)
+{
+ return iter->line_pos >= strlen(iter->l->data);
+}
+
gboolean g_at_result_iter_next(GAtResultIter *iter, const char *prefix)
{
char *line;
diff --git a/gatchat/gatresult.h b/gatchat/gatresult.h
index a74741f..33c0b2c 100644
--- a/gatchat/gatresult.h
+++ b/gatchat/gatresult.h
@@ -46,6 +46,7 @@ struct _GAtResultIter {
typedef struct _GAtResultIter GAtResultIter;
void g_at_result_iter_init(GAtResultIter *iter, GAtResult *result);
+gboolean g_at_result_iter_eol(GAtResultIter *iter);
gboolean g_at_result_iter_next(GAtResultIter *iter, const char
*prefix);
gboolean g_at_result_iter_open_list(GAtResultIter *iter);
--
1.7.2.2
11 years, 9 months
[PATCH 0/3] Persist TX SMS messages
by Kristen Carlson Accardi
This patch series implements a method of persisting pending
outgoing sms messages on disk. Once an sms message has
been submitted to the transmit queue, each pdu in the
message is stored on disk until the driver indicates that
it has been sent.
Each tx_queue_entry is given an id number that represents
it's order in the queue. A subdirectory per entry is
created as id-uuid, in order to preserve order when the
queue is loaded in the event of a crash. Within each
subdirectory, each pdu is saved in order by sequence
number.
When an sms driver is ready for operation, the disk will
be scanned for any saved pending tx sms messages. If there
are any found, they will be loaded from disk and placed
into the queue in order.
Kristen Carlson Accardi (3):
sms: store pending tx pdus on disk
sms: delete sent sms messages from backup
sms: restore pending tx messages from backup
src/ofono.h | 1 +
src/sms.c | 64 ++++++++++++++++++++
src/smsutil.c | 180 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
src/smsutil.h | 13 ++++
4 files changed, 258 insertions(+), 0 deletions(-)
--
1.7.2.3
11 years, 9 months
[PATCH] TODO: Add CDMA Voicecall Support Tasks
by Dara Spieker-Doyle
---
TODO | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 58 insertions(+), 0 deletions(-)
diff --git a/TODO b/TODO
index 8d771d6..cbcdac5 100644
--- a/TODO
+++ b/TODO
@@ -484,3 +484,61 @@ Miscellaneous
Priority: Medium
Complexity: C2
Owner: Sjur Brændeland <sjur.brandeland(a)stericsson.com>
+
+CDMA Voicecall
+==============
+
+- Add support for Mobile Originated and Mobile Terminated Voice Call over
+ a CDMA network. This includes management of call state and providing
+ appropriate values for the LineIdentification in each case.
+
+ Priority: High
+ Complexity: C2
+ Owner: Dara Spieker-Doyle <dara.spieker-doyle(a)nokia.com>
+
+- Add support for Three-Way Calling over a CDMA network. Three-Way Calling
+ provides the subscriber with the capability to add a third party to an
+ established two-party call, so that all three parties may communicate in a
+ three-way call.
+
+ In CDMA mode, the originating subscriber of a current conversation can
+ request for a third party to be added to a conversation by sending a Flash
+ With Information Message (FWIM) with dialed digits to the network. Upon
+ setting up a two-way conversation with the added party, the originating
+ subscriber can request to establish a three-way conversation by sending
+ another Flash With Information Message. Upon receiving the second Flash With
+ Information Message, the MSC reconnects the original party to the
+ conversation thus completing the setup of a three-way conversation.
+
+ CDMA Three-Way Calling is described by Figure B-5 in 3GPP2 C.S0005-E Version
+ 2.0.
+
+ Priority: High
+ Complexity: C2
+ Owner: Dara Spieker-Doyle <dara.spieker-doyle(a)nokia.com>
+
+- Add support for Call Waiting over a CDMA network. Call Waiting (CW) provides
+ notification of an incoming call to an originating subscriber, while the
+ subscriber's call is in the 2-way state. Subsequently, the originating
+ subscriber can either answer or ignore the incoming call. If the originating
+ subscriber answers the second call, it may alternate between the two calls.
+
+ In CDMA mode, the originating subscriber of a current conversation will
+ receive either a Flash With Information Message or an Alert With Information
+ Message from the network if there is an additional mobile terminated voice
+ call incoming. The originating subscriber can change conversation parties by
+ sending a Flash With Information Message to the network and the MSC will
+ toggle the speech path between the two conversations.
+
+ CDMA Call Waiting is described by Figure B-6 in 3GPP2 C.S0005-E Version
+ 2.0.
+
+ Priority: High
+ Complexity: C2
+ Owner: Dara Spieker-Doyle <dara.spieker-doyle(a)nokia.com>
+
+- Support sending DTMF tones over CDMA network.
+
+ Priority: High
+ Complexity: C2
+ Owner: Dara Spieker-Doyle <dara.spieker-doyle(a)nokia.com>
--
1.7.0.4
11 years, 9 months
[PATCH 2/5] cdma-voicecall: Add CDMA MO Call Support
by Dara Spieker-Doyle
---
Makefile.am | 3 +-
src/cdma-voicecall.c | 449 ++++++++++++++++++++++++++++++++++++++++++++++++++
src/common.c | 42 +++++
src/common.h | 14 ++
src/ofono.h | 3 +
5 files changed, 510 insertions(+), 1 deletions(-)
create mode 100644 src/cdma-voicecall.c
diff --git a/Makefile.am b/Makefile.am
index aea3fd3..f111f96 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -319,7 +319,8 @@ src_ofonod_SOURCES = $(gdbus_sources) $(builtin_sources) src/ofono.ver \
src/radio-settings.c src/stkutil.h src/stkutil.c \
src/nettime.c src/stkagent.c src/stkagent.h \
src/simfs.c src/simfs.h src/audio-settings.c \
- src/smsagent.c src/smsagent.h src/ctm.c
+ src/smsagent.c src/smsagent.h src/ctm.c \
+ src/cdma-voicecall.c
src_ofonod_LDADD = $(builtin_libadd) @GLIB_LIBS@ @DBUS_LIBS@ @CAPNG_LIBS@ -ldl
diff --git a/src/cdma-voicecall.c b/src/cdma-voicecall.c
new file mode 100644
index 0000000..8ba3222
--- /dev/null
+++ b/src/cdma-voicecall.c
@@ -0,0 +1,449 @@
+/*
+ *
+ * oFono - Open Source Telephony
+ *
+ * Copyright (C) 2010 Nokia Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h>
+#include <stdio.h>
+#include <time.h>
+#include <errno.h>
+#include <stdint.h>
+
+#include <glib.h>
+#include <gdbus.h>
+
+#include "ofono.h"
+
+#include "common.h"
+
+static GSList *g_drivers;
+
+struct ofono_cdma_voicecall_manager {
+ struct ofono_cdma_phone_number phone_number;
+ int direction;
+ enum cdma_call_status status;
+ time_t start_time;
+ DBusMessage *pending;
+ const struct ofono_cdma_voicecall_manager_driver *driver;
+ void *driver_data;
+ struct ofono_atom *atom;
+};
+
+static void generic_callback(const struct ofono_error *error, void *data);
+
+static const char *disconnect_reason_to_string(enum ofono_disconnect_reason r)
+{
+ switch (r) {
+ case OFONO_DISCONNECT_REASON_LOCAL_HANGUP:
+ return "local";
+ case OFONO_DISCONNECT_REASON_REMOTE_HANGUP:
+ return "remote";
+ default:
+ return "network";
+ }
+}
+
+static const char *cdma_call_status_to_string(enum cdma_call_status status)
+{
+ switch (status) {
+ case CDMA_CALL_STATUS_ACTIVE:
+ return "active";
+ case CDMA_CALL_STATUS_DIALING:
+ return "dialing";
+ case CDMA_CALL_STATUS_ALERTING:
+ return "alerting";
+ case CDMA_CALL_STATUS_INCOMING:
+ return "incoming";
+ default:
+ return "disconnected";
+ }
+}
+
+static const char *time_to_str(const time_t *t)
+{
+ static char buf[128];
+ struct tm tm;
+
+ strftime(buf, 127, "%Y-%m-%dT%H:%M:%S%z", localtime_r(t, &tm));
+ buf[127] = '\0';
+
+ return buf;
+}
+
+static void append_voicecall_properties(struct ofono_cdma_voicecall_manager *v,
+ DBusMessageIter *dict)
+{
+ const char *status;
+ const char *lineid;
+ const char *timestr;
+
+ status = cdma_call_status_to_string(v->status);
+ lineid = cdma_phone_number_to_string(&v->phone_number);
+
+ ofono_dbus_dict_append(dict, "State", DBUS_TYPE_STRING, &status);
+
+ ofono_dbus_dict_append(dict, "LineIdentification",
+ DBUS_TYPE_STRING, &lineid);
+
+ if (v->status == CDMA_CALL_STATUS_ACTIVE ||
+ (v->status == CDMA_CALL_STATUS_DISCONNECTED &&
+ v->start_time != 0)) {
+ timestr = time_to_str(&v->start_time);
+
+ ofono_dbus_dict_append(dict, "StartTime", DBUS_TYPE_STRING,
+ ×tr);
+ }
+}
+
+static DBusMessage *voicecall_manager_get_properties(DBusConnection *conn,
+ DBusMessage *msg, void *data)
+{
+ struct ofono_cdma_voicecall_manager *v = data;
+ DBusMessage *reply;
+ DBusMessageIter iter;
+ DBusMessageIter dict;
+
+ reply = dbus_message_new_method_return(msg);
+
+ if (reply == NULL)
+ return NULL;
+
+ dbus_message_iter_init_append(reply, &iter);
+
+ dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
+ OFONO_PROPERTIES_ARRAY_SIGNATURE,
+ &dict);
+ append_voicecall_properties(v, &dict);
+ dbus_message_iter_close_container(&iter, &dict);
+
+ return reply;
+}
+
+static const char *voicecall_build_path(struct ofono_cdma_voicecall_manager *vc)
+{
+ static char path[256];
+
+ snprintf(path, sizeof(path), "%s/voicecall",
+ __ofono_atom_get_path(vc->atom));
+
+ return path;
+}
+
+static void voicecall_emit_disconnect_reason(
+ struct ofono_cdma_voicecall_manager *vc,
+ enum ofono_disconnect_reason reason)
+{
+ DBusConnection *conn = ofono_dbus_get_connection();
+ const char *path;
+ const char *reason_str;
+
+ reason_str = disconnect_reason_to_string(reason);
+ path = voicecall_build_path(vc);
+
+ g_dbus_emit_signal(conn, path, OFONO_CDMA_VOICECALL_MANAGER_INTERFACE,
+ "DisconnectReason",
+ DBUS_TYPE_STRING, &reason_str,
+ DBUS_TYPE_INVALID);
+}
+
+static void voicecall_set_call_status(struct ofono_cdma_voicecall_manager *vc,
+ enum cdma_call_status status)
+{
+ DBusConnection *conn = ofono_dbus_get_connection();
+ const char *path;
+ const char *status_str;
+ enum cdma_call_status old_status;
+
+ if (vc->status == status)
+ return;
+
+ old_status = vc->status;
+
+ vc->status = status;
+
+ status_str = cdma_call_status_to_string(status);
+ path = voicecall_build_path(vc);
+
+ ofono_dbus_signal_property_changed(conn, path,
+ OFONO_CDMA_VOICECALL_MANAGER_INTERFACE,
+ "State", DBUS_TYPE_STRING,
+ &status_str);
+
+ if (status == CDMA_CALL_STATUS_ACTIVE &&
+ old_status == CDMA_CALL_STATUS_DIALING) {
+ const char *timestr;
+
+ vc->start_time = time(NULL);
+ timestr = time_to_str(&vc->start_time);
+
+ ofono_dbus_signal_property_changed(conn, path,
+ OFONO_CDMA_VOICECALL_MANAGER_INTERFACE,
+ "StartTime", DBUS_TYPE_STRING,
+ ×tr);
+ }
+}
+
+static void voicecall_set_call_lineid(struct ofono_cdma_voicecall_manager *v)
+{
+ DBusConnection *conn = ofono_dbus_get_connection();
+ const char *path;
+ const char *lineid_str;
+
+ path = voicecall_build_path(v);
+
+ /* For MO calls, LineID is the dialed phone number */
+ lineid_str = cdma_phone_number_to_string(&v->phone_number);
+
+ ofono_dbus_signal_property_changed(conn, path,
+ OFONO_CDMA_VOICECALL_MANAGER_INTERFACE,
+ "LineIdentification",
+ DBUS_TYPE_STRING, &lineid_str);
+}
+
+static void manager_dial_callback(const struct ofono_error *error, void *data)
+{
+ struct ofono_cdma_voicecall_manager *vc = data;
+ DBusMessage *reply;
+
+ if (error->type != OFONO_ERROR_TYPE_NO_ERROR) {
+ reply = __ofono_error_failed(vc->pending);
+ } else {
+ const char *path = voicecall_build_path(vc);
+
+ reply = dbus_message_new_method_return(vc->pending);
+
+ dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH, &path,
+ DBUS_TYPE_INVALID);
+ }
+
+ __ofono_dbus_pending_reply(&vc->pending, reply);
+}
+
+static DBusMessage *voicecall_manager_dial(DBusConnection *conn,
+ DBusMessage *msg, void *data)
+{
+ struct ofono_cdma_voicecall_manager *vc = data;
+ const char *number;
+
+ if (vc->pending)
+ return __ofono_error_busy(msg);
+
+ if (vc->status != CDMA_CALL_STATUS_DISCONNECTED)
+ return __ofono_error_failed(msg);
+
+ if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &number,
+ DBUS_TYPE_INVALID) == FALSE)
+ return __ofono_error_invalid_args(msg);
+
+ if (!valid_cdma_phone_number_format(number))
+ return __ofono_error_invalid_format(msg);
+
+ if (vc->driver->dial == NULL)
+ return __ofono_error_not_implemented(msg);
+
+ vc->pending = dbus_message_ref(msg);
+
+ string_to_cdma_phone_number(number, &vc->phone_number);
+ voicecall_set_call_lineid(vc);
+ vc->direction = CALL_DIRECTION_MOBILE_ORIGINATED;
+ voicecall_set_call_status(vc, CDMA_CALL_STATUS_DIALING);
+ vc->driver->dial(vc, &vc->phone_number, manager_dial_callback, vc);
+
+ return NULL;
+}
+
+static DBusMessage *voicecall_manager_hangup(DBusConnection *conn,
+ DBusMessage *msg, void *data)
+{
+ struct ofono_cdma_voicecall_manager *vc = data;
+
+ if (vc->pending)
+ return __ofono_error_busy(msg);
+
+ if (vc->driver->hangup == NULL)
+ return __ofono_error_not_implemented(msg);
+
+ if (vc->status == CDMA_CALL_STATUS_DISCONNECTED)
+ return __ofono_error_failed(msg);
+
+ vc->pending = dbus_message_ref(msg);
+
+ vc->driver->hangup(vc, generic_callback, vc);
+
+ return NULL;
+}
+
+static GDBusMethodTable manager_methods[] = {
+ { "GetProperties", "", "a{sv}",
+ voicecall_manager_get_properties },
+ { "Dial", "ss", "o", voicecall_manager_dial,
+ G_DBUS_METHOD_FLAG_ASYNC },
+ { "Hangup", "", "", voicecall_manager_hangup,
+ G_DBUS_METHOD_FLAG_ASYNC },
+ { }
+};
+
+static GDBusSignalTable manager_signals[] = {
+ { "PropertyChanged", "sv" },
+ { "DisconnectReason", "s" },
+ { }
+};
+
+void ofono_cdma_voicecall_manager_disconnected(
+ struct ofono_cdma_voicecall_manager *vc,
+ enum ofono_disconnect_reason reason,
+ const struct ofono_error *error)
+{
+ DBG("Got disconnection event for reason: %d", reason);
+
+ if (reason != OFONO_DISCONNECT_REASON_UNKNOWN)
+ voicecall_emit_disconnect_reason(vc, reason);
+
+ voicecall_set_call_status(vc, CDMA_CALL_STATUS_DISCONNECTED);
+}
+
+static void generic_callback(const struct ofono_error *error, void *data)
+{
+ struct ofono_cdma_voicecall_manager *vc = data;
+ DBusMessage *reply;
+
+ if (error->type == OFONO_ERROR_TYPE_NO_ERROR)
+ reply = dbus_message_new_method_return(vc->pending);
+ else
+ reply = __ofono_error_failed(vc->pending);
+
+ __ofono_dbus_pending_reply(&vc->pending, reply);
+}
+
+int ofono_cdma_voicecall_manager_driver_register(
+ const struct ofono_cdma_voicecall_manager_driver *d)
+{
+ DBG("driver: %p, name: %s", d, d->name);
+
+ if (d->probe == NULL)
+ return -EINVAL;
+
+ g_drivers = g_slist_prepend(g_drivers, (void *)d);
+
+ return 0;
+}
+
+void ofono_cdma_voicecall_manager_driver_unregister(
+ const struct ofono_cdma_voicecall_manager_driver *d)
+{
+ DBG("driver: %p, name: %s", d, d->name);
+
+ g_drivers = g_slist_remove(g_drivers, (void *)d);
+}
+
+
+static void voicecall_manager_remove(struct ofono_atom *atom)
+{
+ struct ofono_cdma_voicecall_manager *vc = __ofono_atom_get_data(atom);
+
+ DBG("atom: %p", atom);
+
+ if (vc == NULL)
+ return;
+
+ if (vc->driver && vc->driver->remove)
+ vc->driver->remove(vc);
+
+ g_free(vc);
+}
+
+struct ofono_cdma_voicecall_manager *ofono_cdma_voicecall_manager_create(
+ struct ofono_modem *modem,
+ unsigned int vendor,
+ const char *driver,
+ void *data)
+{
+ struct ofono_cdma_voicecall_manager *vc;
+ GSList *l;
+
+ if (driver == NULL)
+ return NULL;
+
+ vc = g_try_new0(struct ofono_cdma_voicecall_manager, 1);
+ if (vc == NULL)
+ return NULL;
+
+ vc->status = CDMA_CALL_STATUS_DISCONNECTED;
+
+ vc->atom = __ofono_modem_add_atom(modem,
+ OFONO_ATOM_TYPE_CDMA_VOICECALL_MANAGER,
+ voicecall_manager_remove, vc);
+
+ for (l = g_drivers; l; l = l->next) {
+ const struct ofono_cdma_voicecall_manager_driver *drv = l->data;
+
+ if (g_strcmp0(drv->name, driver))
+ continue;
+
+ if (drv->probe(vc, vendor, data) < 0)
+ continue;
+
+ vc->driver = drv;
+ break;
+ }
+
+ return vc;
+}
+
+void ofono_cdma_voicecall_manager_register(
+ struct ofono_cdma_voicecall_manager *vc)
+{
+ DBusConnection *conn = ofono_dbus_get_connection();
+ struct ofono_modem *modem = __ofono_atom_get_modem(vc->atom);
+ const char *path = __ofono_atom_get_path(vc->atom);
+
+ if (!g_dbus_register_interface(conn, path,
+ OFONO_CDMA_VOICECALL_MANAGER_INTERFACE,
+ manager_methods, manager_signals, NULL,
+ vc, NULL)) {
+ ofono_error("Could not create %s interface",
+ OFONO_CDMA_VOICECALL_MANAGER_INTERFACE);
+ return;
+ }
+
+ ofono_modem_add_interface(modem,
+ OFONO_CDMA_VOICECALL_MANAGER_INTERFACE);
+}
+
+void ofono_cdma_voicecall_manager_remove(
+ struct ofono_cdma_voicecall_manager *vc)
+{
+ __ofono_atom_free(vc->atom);
+}
+
+void ofono_cdma_voicecall_manager_set_data(
+ struct ofono_cdma_voicecall_manager *vc, void *data)
+{
+ vc->driver_data = data;
+}
+
+void *ofono_cdma_voicecall_manager_get_data(
+ struct ofono_cdma_voicecall_manager *vc)
+{
+ return vc->driver_data;
+}
diff --git a/src/common.c b/src/common.c
index 5154b8d..7aa63ce 100644
--- a/src/common.c
+++ b/src/common.c
@@ -262,6 +262,31 @@ gboolean valid_phone_number_format(const char *number)
return TRUE;
}
+gboolean valid_cdma_phone_number_format(const char *number)
+{
+ int len = strlen(number);
+ int begin = 0;
+ int i;
+
+ if (!len)
+ return FALSE;
+
+ if ((len - begin) > OFONO_MAX_CDMA_PHONE_NUMBER_LENGTH)
+ return FALSE;
+
+ for (i = begin; i < len; i++) {
+ if (number[i] >= '0' && number[i] <= '9')
+ continue;
+
+ if (number[i] == '*' || number[i] == '#')
+ continue;
+
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
const char *telephony_error_to_str(const struct ofono_error *error)
{
struct error_entry *e;
@@ -405,6 +430,23 @@ void string_to_phone_number(const char *str, struct ofono_phone_number *ph)
}
}
+const char *cdma_phone_number_to_string(
+ const struct ofono_cdma_phone_number *ph)
+{
+ static char buffer[OFONO_MAX_CDMA_PHONE_NUMBER_LENGTH + 1];
+
+ strncpy(buffer, ph->number, OFONO_MAX_CDMA_PHONE_NUMBER_LENGTH);
+ buffer[OFONO_MAX_CDMA_PHONE_NUMBER_LENGTH] = '\0';
+
+ return buffer;
+}
+
+void string_to_cdma_phone_number(const char *str,
+ struct ofono_cdma_phone_number *ph)
+{
+ strcpy(ph->number, str);
+}
+
gboolean valid_ussd_string(const char *str, gboolean call_in_progress)
{
int len = strlen(str);
diff --git a/src/common.h b/src/common.h
index 8b5798a..df0adcd 100644
--- a/src/common.h
+++ b/src/common.h
@@ -59,6 +59,14 @@ enum call_status {
CALL_STATUS_DISCONNECTED
};
+enum cdma_call_status {
+ CDMA_CALL_STATUS_ACTIVE = 0,
+ CDMA_CALL_STATUS_DIALING = 1,
+ CDMA_CALL_STATUS_ALERTING = 2,
+ CDMA_CALL_STATUS_INCOMING = 4,
+ CDMA_CALL_STATUS_DISCONNECTED
+};
+
/* 27.007 Section 7.18 */
enum call_direction {
CALL_DIRECTION_MOBILE_ORIGINATED = 0,
@@ -128,6 +136,12 @@ gboolean valid_phone_number_format(const char *number);
const char *phone_number_to_string(const struct ofono_phone_number *ph);
void string_to_phone_number(const char *str, struct ofono_phone_number *ph);
+gboolean valid_cdma_phone_number_format(const char *number);
+const char *cdma_phone_number_to_string(
+ const struct ofono_cdma_phone_number *ph);
+void string_to_cdma_phone_number(const char *str,
+ struct ofono_cdma_phone_number *ph);
+
int mmi_service_code_to_bearer_class(int code);
gboolean valid_ussd_string(const char *str, gboolean call_in_progress);
diff --git a/src/ofono.h b/src/ofono.h
index 792134b..cab70cd 100644
--- a/src/ofono.h
+++ b/src/ofono.h
@@ -126,6 +126,7 @@ enum ofono_atom_type {
OFONO_ATOM_TYPE_STK = 20,
OFONO_ATOM_TYPE_NETTIME = 21,
OFONO_ATOM_TYPE_CTM = 22,
+ OFONO_ATOM_TYPE_CDMA_VOICECALL_MANAGER = 23,
};
enum ofono_atom_watch_condition {
@@ -415,3 +416,5 @@ void __ofono_nettime_probe_drivers(struct ofono_modem *modem);
void __ofono_nettime_info_received(struct ofono_modem *modem,
struct ofono_network_time *info);
+
+#include <ofono/cdma-voicecall.h>
--
1.7.0.4
11 years, 9 months