[RFC] HFP support into oFono and BlueZ
by Gustavo F. Padovan
Hi,
These patches implement the new API for the Audio Gateway in BlueZ. It
follows the last version of the HandsfreeGateway and HandsfreeAgent
Intefaces API.
The first two patches is for BlueZ and the other for oFono. You can
test it with using enable-modem and test-voicecall scripts into the
test dir of oFono.
Feel free to test it and send me your comments. We have some bugs yet.
The audio part is not working yet. We are going to work on pulseaudio
this week to get this done soon.
Regards,
--
Gustavo F. Padovan
ProFUSION embedded systems - http://profusion.mobi
9 years, 10 months
oFono v0.22 test report
by Li, Zhigang
Test Objective
--------------------------------------
This is QA regular release testing cycle for oFono released. Our testing focus would be new features exploration and regression testing, to ensure major issues for new features are exposed in timely fashion.
Test Environment
-------------------------------
General Features:
General PC (pre-installed FC12)
- ofono v0.22
- phonesim 1.2
HFP:
Netbook EeePC901
- MeeGo20100424 image
- Sony Ericsson C905, Nokia N95
- ofono v0.22
- Bluez v4.63
GPRS:
- MBM modem
- ofono v0.22
- UNICOM 3G WCDMA network
Modem Emulator:
- test-server tool in ofono
-------------------------------
Test Scope
-------------------------------
The test will do full light functional validation, mainly focus on checking implemented functionality of ofono v0.22 (voice call, message, cell broadcast, phonebook, sim, supplementary service, modem management, voice mail, call volume, call history, message history, GPRS, HFP, USSD) base on phonesim simulator and some hardware devices.
As the dependence of modem, we will do PPP test with gsmdial later.
Test Summary
-------------------------------
During the v0.21 testing, we found the v0.22 release, so switch to v0.22 immediately.
The test result is positive. Most functionalities work well and more stable,
we reported 1 major Bluetooth bug during HFP test, verified 4 bugs, so far, no blocking, critical issues remain.
Executed total 276 test cases during this round of testing, and among them:
Pass: 266
Fail: 10
New Bugs
-------------------------------
Bug 2782 Bluetooth lost connection after unload loopback module in PA.
Open bugs
-------------------------------
2515 nor S5 command not really work in modem emulator
2517 nor Non at command did not handle properly in modem emulator
2519 nor S3 command can not work normally without default value
8898 enh Spend long time on getting fail report of sms
10061 GSM Compliance issue in sim phonebook
9453 enh [Phonesim] To support UCS2 encode in Cell Broadcast Message
9371 nor Modem interface information didn't be updated after modem was removed
868 nor ussd notification display is incorrect with UCS2 character set
872 maj Can not deactivate all contexts
Fixed bugs
-------------------------------
8185 nor Segmentation fault in ste modem which may caused by call history
Verified Bugs
------------------------------
870 can't cancel/response ussd notification
434 Can't input pin code
435 Can't reset the pin code as the same old number
443 can't change the password by gsm string
Details
The every checkpoint would be one or more test case to cover and result is for functionality, besides you may find some functional limitation in comments
------------------------------
Features checkpoints test results comments
Call history Missed call pass
Outgoing call pass
Incoming call pass
Duration pass
Date pass
SMS Send/receive pass
Class0, 1 pass
Set service center address pass
More segments pass
Different character set pass
Voice call Dial pass
Accept pass
Reject pass
Hold pass
Retrieve pass
Release pass
ECT pass
Multiparty call Create pass
Hang up pass
Private chat pass
Hold pass
Sim Phonebook Read pass
Different character set pass
Vcard3.0 pass
SS CF pass
CB pass
CW pass
CLIR/CLIP pass
Setting AOC pass
CF/CB pass
GSM string General strings pass
USSD pass
USSD Send pass
Cancel request pass
Respond pass
Different character set fail #868
Modem Basic function pass
Two modems pass
Abnormal quit fail #9371
Voice mail Get/Set number pass
Message Count pass
Notification pass
CPHS information pass
Networking Basic network information pass
Signal indicator pass
Scan pass
Register pass
SIM file Read IMSI pass
Read/set MSISDN pass
Read Emergency number pass
Read SDN number pass
PIN code pass
PUK pass
Cell broadcast Receive a CB message pass
Receive several CB messages pass
Receive more pages CB message pass
Different language pass
Call volume Set/get volume pass
Mute/unmute pass
Message history Send history pass
Receive history pass
Date pass
HFP Voice call pass
Multiparty call pass
Networking pass
Call volume pass
Audio control pass
GPRS Active context pass
Edit profiles pass
Deactivate context pass
Deactivate all context fail #872
Detach pass
Attach pass
Create context pass
Remove context pass
Modem Emualtor Basic AT command pass
Negative fail #2515,#2517,#2519
-------------------------------
Thanks
Zhigang
11 years, 10 months
[PATCH v3 0/2] Huawei GPRS support
by Kalle Valo
Here's v3 of my Huawei GPRS patches. I followed Marcel's advice and
implemented all Huawei quirks in the huawei plugin. Now the patches
are a lot smaller.
Please comment.
---
Kalle Valo (2):
huawei: add gprs context
huawei: detect SecondaryDevice which is used for events
drivers/atmodem/network-registration.c | 4 +
plugins/huawei.c | 112 +++++++++++++++++++++++++++++++-
plugins/udev.c | 61 +++++++++++++++--
3 files changed, 167 insertions(+), 10 deletions(-)
11 years, 10 months
[SMS D-Bus 00/23] Exports SMS over D-Bus and mis cleanups
by Inaky Perez-Gonzalez
From: Inaky Perez-Gonzalez <inaky.perez-gonzalez(a)intel.com>
Hi All
This patchset is the current state of my tree that changes the D-Bus
interface for SMS:
- adds object based management of SMS messages
- adds a cancelation operation for in-transit / pending messages
- holds messages waiting for acknoledgement (delivery report) -- this
is still not fully integrated with the code that was commited last
days (thus once the delivery arrives the message is not
automatically cleaned up as "confirmed").
- generates truly unique SMS message IDs using hashing of contents
and receiver address
- miscelaeous small cleanups / additions, carryover from a previous
submit that got neither not acked or no resolution was agreed upon
Please review and suggest what else needs to be done / changed.
Thx,
The following changes since commit 1fedd096a0ba2ce8625a9e4d1c2ce25bb8f6dfe4:
Marcel Holtmann (1):
Check sanity the MNC length value from the SIM card
are available in the git repository at:
git://gitorious.org/~inakypg/ofono/ofono-inakypg.git master
Patches follow for reviewing convenience.
Inaky Perez-Gonzalez (23):
documentation: add note about referencing standards
util.h: Add BUILD_BUG_ON() and friends for compile-time assert checking
smutil.h: add missing header file dependencies
write_file: make transaction-safe
doc: explain debugging options to -d, add a pointer in -h to manpage
SMS: introduce message ID API
introduce DECLARE_SMS_ADDR_STR()
export sms_assembly_encode_address
SMS: implement SHA256-based message IDs [incomplete]
sms: add doc about the extensions D-Bus API (not yet implemented)
struct tx_queue_entry: add fields and destructor
SMS: produce a unique, persistent name for in-transit messages
SMS: introduce bare state machine and transitions
SMS: export outgoing messages over D-Bus (skeleton)
SMS: split sms_send_message() into a D-Bus front end and an internal API
SMS: introduce wait-for-ack state and infrastructure
SMS: introduce sms_msg_cancel and its D-Bus wrapper
SMS: rename tx_queue_entry->msg to ->dbus_msg for clarity
SMS: Implement D-Bus SMS-MSG::GetProperties
SMS: send D-Bus SMS-MSG::ProperyChanged signals when message changes status
SMS: make D-Bus SendMessage and Cancel fully synchronous
SMS: set the SRR bit in outgoing PDUs if WFA is requested
sms_text_prepare: document @use_delivery_reports
HACKING | 10 +
Makefile.am | 5 +-
doc/ofonod.8 | 5 +-
doc/sms-api.txt | 94 ++++++++
doc/standards.txt | 8 +
src/main.c | 4 +-
src/sms.c | 512 +++++++++++++++++++++++++++++++++++-----
src/smsutil.c | 202 ++++++++++++++++-
src/smsutil.h | 125 ++++++++++
src/storage.c | 42 +++-
src/util.h | 28 +++
test/test-sms-msg-state-change | 24 ++
unit/test-sms-msg-id.c | 212 +++++++++++++++++
13 files changed, 1199 insertions(+), 72 deletions(-)
create mode 100644 doc/standards.txt
create mode 100755 test/test-sms-msg-state-change
create mode 100644 unit/test-sms-msg-id.c
11 years, 11 months
[PATCH 1/3] hfp: create modem for new devices paired on runtime
by Gustavo F. Padovan
It listens the Paired property to create a modem to the recently paired
devices. It also renames added_watch to adapter_watch, a more proper
name.
---
plugins/hfp.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++----
1 files changed, 57 insertions(+), 5 deletions(-)
diff --git a/plugins/hfp.c b/plugins/hfp.c
index 981b05b..3e41342 100644
--- a/plugins/hfp.c
+++ b/plugins/hfp.c
@@ -66,6 +66,7 @@ static const char *cmer_prefix[] = { "+CMER:", NULL };
static const char *chld_prefix[] = { "+CHLD:", NULL };
static DBusConnection *connection;
+static GHashTable *uuid_hash = NULL;
static void hfp_debug(const char *str, void *user_data)
{
@@ -427,6 +428,7 @@ static int hfp_create_modem(const char *device)
{
struct ofono_modem *modem;
struct hfp_data *data;
+ const char *path;
ofono_info("Using device: %s", device);
@@ -451,6 +453,9 @@ static int hfp_create_modem(const char *device)
ofono_modem_set_data(modem, data);
ofono_modem_register(modem);
+ path = ofono_modem_get_path(modem);
+ g_hash_table_insert(uuid_hash, g_strdup(device), g_strdup(path));
+
return 0;
free:
@@ -465,6 +470,9 @@ static void parse_uuids(DBusMessageIter *i, const char *device)
DBusMessageIter variant, ai;
const char *value;
+ if (g_hash_table_lookup(uuid_hash, device))
+ return;
+
dbus_message_iter_recurse(i, &variant);
dbus_message_iter_recurse(&variant, &ai);
@@ -624,6 +632,33 @@ static gboolean adapter_added(DBusConnection *connection, DBusMessage *message,
return TRUE;
}
+static gboolean uuid_emitted(DBusConnection *connection, DBusMessage *message,
+ void *user_data)
+{
+ const char *device, *property;
+ DBusMessageIter iter;
+
+ dbus_message_iter_init(message, &iter);
+
+ if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
+ return FALSE;
+
+ dbus_message_iter_get_basic(&iter, &property);
+ if (g_str_equal(property, "UUIDs") == FALSE)
+ return TRUE;
+
+ if (!dbus_message_iter_next(&iter))
+ return FALSE;
+
+ if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT)
+ return FALSE;
+
+ device = dbus_message_get_path(message);
+ parse_uuids(&iter, device);
+
+ return TRUE;
+}
+
static void list_adapters_cb(DBusPendingCall *call, gpointer user_data)
{
DBusError err;
@@ -725,6 +760,8 @@ static void hfp_remove(struct ofono_modem *modem)
hfp_unregister_ofono_handsfree(modem);
+ g_hash_table_remove(uuid_hash, data->handsfree_path);
+
g_free(data->handsfree_path);
g_free(data);
@@ -798,7 +835,8 @@ static struct ofono_modem_driver hfp_driver = {
.post_sim = hfp_post_sim,
};
-static guint added_watch;
+static guint adapter_watch;
+static guint uuid_watch;
static int hfp_init(void)
{
@@ -809,12 +847,21 @@ static int hfp_init(void)
connection = ofono_dbus_get_connection();
- added_watch = g_dbus_add_signal_watch(connection, NULL, NULL,
+ adapter_watch = g_dbus_add_signal_watch(connection, NULL, NULL,
BLUEZ_MANAGER_INTERFACE,
"AdapterAdded",
adapter_added, NULL, NULL);
- if (added_watch == 0) {
+ uuid_watch = g_dbus_add_signal_watch(connection, NULL, NULL,
+ BLUEZ_DEVICE_INTERFACE,
+ "PropertyChanged",
+ uuid_emitted, NULL, NULL);
+
+
+ uuid_hash = g_hash_table_new_full(g_str_hash, g_str_equal,
+ g_free, g_free);
+
+ if (adapter_watch == 0 || uuid_watch == 0) {
err = -EIO;
goto remove;
}
@@ -828,7 +875,9 @@ static int hfp_init(void)
return 0;
remove:
- g_dbus_remove_watch(connection, added_watch);
+ g_dbus_remove_watch(connection, adapter_watch);
+ g_dbus_remove_watch(connection, uuid_watch);
+ g_hash_table_destroy(uuid_hash);
dbus_connection_unref(connection);
@@ -837,9 +886,12 @@ remove:
static void hfp_exit(void)
{
- g_dbus_remove_watch(connection, added_watch);
+ g_dbus_remove_watch(connection, adapter_watch);
+ g_dbus_remove_watch(connection, uuid_watch);
ofono_modem_driver_unregister(&hfp_driver);
+
+ g_hash_table_destroy(uuid_hash);
}
OFONO_PLUGIN_DEFINE(hfp, "Hands-Free Profile Plugins", VERSION,
--
1.6.4.4
11 years, 11 months
[PATCH] Introduction of HACKING file in phonesim
by Naresh Mehta
Signed-off-by: Naresh Mehta <nareshtechs(a)gmail.com>
---
HACKING | 102 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 102 insertions(+), 0 deletions(-)
create mode 100644 HACKING
diff --git a/HACKING b/HACKING
new file mode 100644
index 0000000..33eae20
--- /dev/null
+++ b/HACKING
@@ -0,0 +1,102 @@
+Hacking on phonesim
+*******************
+
+phonesim is a soft modem that eliminates the need to have an actual AT
+modem connected to the system for testing and developing Ofono.
+
+Build tools requirements
+========================
+
+When building and testing directly from the repository it is important to
+have at least automake version 1.10 or later installed. All modern
+distributions should default to the latest version, but it seems that
+Debian's default is still an earlier version:
+
+ Check version
+ # dpkg -l '*automake*'
+
+ Install new version
+ # apt-get install automake1.10
+ # update-alternatives --config automake
+
+QT development libraries (libqt4-dev) are also required for building
+phonesim. It is recommended to install the QT 4 development tools package
+(qt4-dev-tools) as an alternative if available with your distribution.
+
+Working with the source code repository
+=======================================
+
+The repository contains two extra scripts that accomplish the bootstrap
+process. One is called "bootstrap" which is the basic scripts that uses the
+autotools scripts to create the needed files for building and installing.
+It makes sure to call the right programs depending on the usage of shared or
+static libraries or translations etc.
+
+The second program is called "bootstrap-configure". This program will make
+sure to properly clean the repository, call the "bootstrap" script and then
+call configure with proper settings for development. It will use the best
+options and pass them over to configure. These options normally include
+the enabling the maintainer mode and the debugging features.
+
+So while in a normal source project the call "./configure ..." is used to
+configure the project with its settings like prefix and extra options. In
+case of bare repositories call "./bootstrap-configure" and it will bootstrap
+the repository and calls configure with all the correct options to make
+development easier.
+
+In case of preparing for a release with "make distcheck", don't use
+bootstrap-configure since it could export development specific settings.
+
+So the normal steps to checkout, build and install such a repository is
+like this:
+
+ Checkout repository
+ # git clone git://git.kernel.org/pub/scm/network/ofono/phonesim.git
+ # cd phonesim
+
+ Configure and build
+ # ./bootstrap-configure
+ # make
+
+ Check installation
+ # make install DESTDIR=$PWD/x
+ # find x
+ # rm -rf x
+
+ Check distribution
+ # make distcheck
+
+ Final installation
+ # sudo make install
+
+ Remove autogenerated files
+ # make maintainer-clean
+
+
+Running from within the source code repository
+==============================================
+
+When using "./configure --enable-maintainer-mode" the automake scripts will
+use the plugins directly from within the repository. This removes the need
+to use "make install" when testing "phonesim". The "bootstrap-configure"
+automatically includes this option.
+
+ Run phonesim in foreground using the following options
+ # ./src/phonesim -p 12345 -gui xml/default.xml
+
+Check your modem.conf file and enable the phonesim configuration before
+executing the above command. Argument -p should be followed by the proper
+port number, in case you have changed the default "12345". Argument -gui
+will launch the gui once the modem is enabled.
+
+To enable the modem, make sure the ofono daemon is running and execute the
+enable-modem script with /phonesim argument (default defined in modem.conf,
+change if changes to that section has been made). The AT chat can then
+be seen in the GUI window. Running the script disable-modem with /phonesim
+argument will turn off the soft modem.
+
+The default.xml can be tweaked further to include additional AT-Commands and
+supposed responses from the soft modem.
+
+For production installations or distribution packaging it is important that
+the "--enable-maintainer-mode" option is NOT used.
--
1.7.0.4
11 years, 11 months
Modem emulator and DUN server side for oFono and BlueZ
by Zhang, Zhenhua
Hi,
I am now working on modem emulator and one usage is for DUN server role. Since Padovan is working on client role, it's good to share my rough thinking for server side implementation. Here are the simple steps I have:
1. Create an oFono emulator atom in oFono. It's the emulator manager that could create DUN, HFP AG or SPP type emulators. It exposes dbus methods like CreateEmulator, DestroyEmulator, GetProperty, etc.
2. DUN agent server in BlueZ watch oFono and call CreateEmulator and pass the file descriptor to oFono. This server could further implement HFP AG and SPP connection.
3. Once an emulator is created, other atom like voicecall, grps, sms register their interested AT command handlers to it. The goal is that we could handle all mandatory AT commands defined in DUN profile spec.
4. Once a DUN emulator received ATD*99#, DUN client performs ppp connection so we forward ppp command to ppp stack. It is done by ppp server side extension. It should be the simple command forwarding.
5. Once the PPP link over DUN is established, DUN client performs ConnMan integration and setup IP address, DNS server, etc.
6. Once the Bluetooth link is disconnected, we destroy the PPP and DUN emulator. If emulator atom itself is destroyed, we destroy the PPP and the Bluetooth connection. If the PPP link is disconnected but Bluetooth link is alive, we destroy the PPP and stay emulator alive.
Comments are welcome. :)
Regards,
Zhenhua
11 years, 11 months
[PATCH 1/9] stk: Utilities for proactive command/envelope handling
by Andrzej Zaborowski
---
include/stk.h | 2 +
src/stk.c | 144 ++++++++++++++++++++++++++++++++++++++++++++++++++-------
2 files changed, 129 insertions(+), 17 deletions(-)
diff --git a/include/stk.h b/include/stk.h
index ad3f6c5..4e5d01e 100644
--- a/include/stk.h
+++ b/include/stk.h
@@ -65,6 +65,8 @@ void *ofono_stk_get_data(struct ofono_stk *stk);
void ofono_stk_proactive_command_notify(struct ofono_stk *stk,
int length, const unsigned char *pdu);
+void ofono_stk_proactive_command_cancel(struct ofono_stk *stk);
+
#ifdef __cplusplus
}
#endif
diff --git a/src/stk.c b/src/stk.c
index b5c6919..e513b06 100644
--- a/src/stk.c
+++ b/src/stk.c
@@ -43,10 +43,61 @@ struct ofono_stk {
const struct ofono_stk_driver *driver;
void *driver_data;
struct ofono_atom *atom;
+ struct stk_command *pending_cmd;
+ void (*cancel_cmd)(struct ofono_stk *stk);
};
+static int stk_respond(struct ofono_stk *stk, struct stk_response *rsp,
+ void (*cb)(const struct ofono_error *error,
+ struct ofono_stk *stk))
+{
+ const guint8 *tlv;
+ unsigned int tlv_len;
+
+ rsp->src = STK_DEVICE_IDENTITY_TYPE_TERMINAL;
+ rsp->dst = STK_DEVICE_IDENTITY_TYPE_UICC;
+ rsp->number = stk->pending_cmd->number;
+ rsp->type = stk->pending_cmd->type;
+ rsp->qualifier = stk->pending_cmd->qualifier;
+
+ if (stk->driver->terminal_response == NULL)
+ return -ENOSYS;
+
+ tlv = stk_pdu_from_response(rsp, &tlv_len);
+ if (!tlv)
+ return -EINVAL;
+
+ stk->driver->terminal_response(stk, tlv_len, tlv,
+ (ofono_stk_generic_cb_t) cb, stk);
+ return 0;
+}
+
+static int stk_send_envelope(struct ofono_stk *stk, struct stk_envelope *e,
+ void (*cb)(const struct ofono_error *error,
+ const unsigned char *data,
+ int length,
+ struct ofono_stk *stk))
+{
+ const guint8 *tlv;
+ unsigned int tlv_len;
+
+ e->dst = STK_DEVICE_IDENTITY_TYPE_UICC;
+
+ if (stk->driver->envelope == NULL)
+ return -ENOSYS;
+
+ tlv = stk_pdu_from_envelope(e, &tlv_len);
+ if (!tlv)
+ return -EINVAL;
+
+ stk->driver->envelope(stk, tlv_len, tlv,
+ (ofono_stk_envelope_cb_t) cb, stk);
+ return 0;
+}
+
static void stk_cbs_download_cb(const struct ofono_error *error,
- const unsigned char *data, int len, void *user)
+ const unsigned char *data, int len,
+ struct ofono_stk *stk)
{
if (error->type != OFONO_ERROR_TYPE_NO_ERROR) {
ofono_error("CellBroadcast download to UICC failed");
@@ -55,36 +106,62 @@ static void stk_cbs_download_cb(const struct ofono_error *error,
return;
}
+ if (len)
+ ofono_error("CellBroadcast download returned %i bytes of data",
+ len);
+
DBG("CellBroadcast download to UICC reported no error");
}
void __ofono_cbs_sim_download(struct ofono_stk *stk, const struct cbs *msg)
{
- const guint8 *tlv;
- unsigned int tlv_len;
+ struct ofono_error error = { .type = OFONO_ERROR_TYPE_FAILURE };
struct stk_envelope e;
+ int err;
- if (stk->driver->envelope == NULL)
- return;
+ memset(&e, 0, sizeof(e));
e.type = STK_ENVELOPE_TYPE_CBS_PP_DOWNLOAD;
e.src = STK_DEVICE_IDENTITY_TYPE_NETWORK;
- e.dst = STK_DEVICE_IDENTITY_TYPE_UICC;
memcpy(&e.cbs_pp_download.page, msg, sizeof(msg));
- tlv = stk_pdu_from_envelope(&e, &tlv_len);
- if (!tlv)
+ err = stk_send_envelope(stk, &e, stk_cbs_download_cb);
+ if (err)
+ stk_cbs_download_cb(&error, NULL, -1, stk);
+}
+
+static void stk_command_cb(const struct ofono_error *error,
+ struct ofono_stk *stk)
+{
+ stk_command_free(stk->pending_cmd);
+ stk->pending_cmd = NULL;
+
+ if (error->type != OFONO_ERROR_TYPE_NO_ERROR) {
+ ofono_error("TERMINAL RESPONSE to a UICC command failed");
+ /* "The ME may retry to deliver the same Cell Broadcast
+ * page." */
return;
+ }
- stk->driver->envelope(stk, tlv_len, tlv, stk_cbs_download_cb, stk);
+ DBG("TERMINAL RESPONSE to a command reported no errors");
+}
+
+void ofono_stk_proactive_command_cancel(struct ofono_stk *stk)
+{
+ if (!stk->pending_cmd)
+ return;
+
+ stk->cancel_cmd(stk);
}
void ofono_stk_proactive_command_notify(struct ofono_stk *stk,
int length, const unsigned char *pdu)
{
- struct stk_command *cmd;
+ struct ofono_error error = { .type = OFONO_ERROR_TYPE_FAILURE };
+ struct stk_response rsp;
char *buf;
- int i;
+ int i, err;
+ gboolean respond = TRUE;
buf = g_try_malloc(length * 2 + 1);
if (!buf)
@@ -93,18 +170,51 @@ void ofono_stk_proactive_command_notify(struct ofono_stk *stk,
for (i = 0; i < length; i ++)
sprintf(buf + i * 2, "%02hhx", pdu[i]);
- cmd = stk_command_new_from_pdu(pdu, length);
- if (!cmd) {
+ stk->pending_cmd = stk_command_new_from_pdu(pdu, length);
+ if (!stk->pending_cmd) {
ofono_error("Can't parse proactive command: %s", buf);
- /* TODO: return TERMINAL RESPONSE with permanent error */
+ /*
+ * Nothing we can do, we'd need at least Command Details
+ * to be able to respond with an error.
+ */
goto done;
}
- /* TODO: execute */
- ofono_info("Proactive command PDU: %s", buf);
+ ofono_debug("Proactive command PDU: %s", buf);
+
+ memset(&rsp, 0, sizeof(rsp));
+
+ switch (stk->pending_cmd->status) {
+ case STK_PARSE_RESULT_OK:
+ switch (stk->pending_cmd->type) {
+ default:
+ rsp.result.type =
+ STK_RESULT_TYPE_COMMAND_NOT_UNDERSTOOD;
+ break;
+ }
+
+ if (respond)
+ break;
+ return;
+
+ case STK_PARSE_RESULT_TYPE_NOT_UNDERSTOOD:
+ default:
+ rsp.result.type = STK_RESULT_TYPE_COMMAND_NOT_UNDERSTOOD;
+ break;
+
+ case STK_PARSE_RESULT_MISSING_VALUE:
+ rsp.result.type = STK_RESULT_TYPE_MINIMUM_NOT_MET;
+ break;
+
+ case STK_PARSE_RESULT_DATA_NOT_UNDERSTOOD:
+ rsp.result.type = STK_RESULT_TYPE_DATA_NOT_UNDERSTOOD;
+ break;
+ }
- stk_command_free(cmd);
+ err = stk_respond(stk, &rsp, stk_command_cb);
+ if (err)
+ stk_command_cb(&error, stk);
done:
g_free(buf);
--
1.7.1.86.g0e460.dirty
11 years, 11 months
[PATCH 1/6] stk: Handle the Get Inkey proactive command.
by Andrzej Zaborowski
The SimApplication agent method signature is:
string/Back/Terminate/Help GetKey(string message, string charset,
bool help_available, bool single_key)
charset is one of:
"yesno" - response needs to be "yes" or "no"
"digit" - one of 0-9, *, #, +
"gsm" - only characters from the GSM SMS charset
"any"
single_key indicates that only characters from the device's
key faces are allowed (e.g. no "+" allowed if device only
has a basic keypad), and that the key should be returned
without being shown on screen or waiting for any kind of
user confirmation.
These patches apply on top of the previous series.
---
src/stk.c | 160 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 159 insertions(+), 1 deletions(-)
diff --git a/src/stk.c b/src/stk.c
index ff47649..a2649b1 100644
--- a/src/stk.c
+++ b/src/stk.c
@@ -31,6 +31,7 @@
#include <glib.h>
#include <gdbus.h>
#include <errno.h>
+#include <sys/time.h>
#include "ofono.h"
@@ -64,6 +65,7 @@ enum stk_agent_state {
STK_AGENT_MAIN_MENU,
STK_AGENT_SELECT_ITEM,
STK_AGENT_DISPLAY_TEXT,
+ STK_AGENT_GET_KEY,
};
struct ofono_stk {
@@ -83,6 +85,7 @@ struct ofono_stk {
struct stk_menu *main_menu;
struct stk_menu *select_item_menu;
+ struct timeval get_inkey_start_ts;
gboolean envelope_q_busy;
GQueue *envelope_q;
@@ -100,6 +103,7 @@ struct envelope_op {
#define OFONO_NAVIGATION_PREFIX OFONO_SERVICE ".Navigation."
#define OFONO_NAVIGATION_GOBACK OFONO_NAVIGATION_PREFIX "Back"
#define OFONO_NAVIGATION_TERMINATED OFONO_NAVIGATION_PREFIX "Terminated"
+#define OFONO_NAVIGATION_GETHELP OFONO_NAVIGATION_PREFIX "Help"
static void envelope_queue_run(struct ofono_stk *stk);
static void display_idle(struct ofono_stk *stk);
@@ -1041,7 +1045,6 @@ out:
display_idle(stk);
}
-
static gboolean handle_command_display_text(const struct stk_command *cmd,
struct stk_response *rsp,
struct ofono_stk *stk)
@@ -1067,6 +1070,157 @@ static gboolean handle_command_display_text(const struct stk_command *cmd,
return cmd->display_text.immediate_response;
}
+static void request_get_key_send(struct ofono_stk *stk, DBusMessage *call)
+{
+ struct stk_command_get_inkey *cmd = &stk->pending_cmd->get_inkey;
+ uint8_t qualifier = stk->pending_cmd->qualifier;
+ dbus_bool_t alphabet = (qualifier & (1 << 0)) != 0;
+ dbus_bool_t ucs2 = (qualifier & (1 << 1)) != 0;
+ dbus_bool_t yesno = (qualifier & (1 << 2)) != 0;
+ dbus_bool_t immediate = (qualifier & (1 << 3)) != 0;
+ dbus_bool_t help = (qualifier & (1 << 7)) != 0;
+ const char *charset =
+ yesno ? "yesno" :
+ (!alphabet ? "digit" :
+ (ucs2 ? "any" : "gsm"));
+
+ dbus_message_set_member(call, "GetKey");
+
+ dbus_message_append_args(call,
+ DBUS_TYPE_STRING, &cmd->text,
+ DBUS_TYPE_STRING, &charset,
+ DBUS_TYPE_BOOLEAN, &help,
+ DBUS_TYPE_BOOLEAN, &immediate,
+ DBUS_TYPE_INVALID);
+}
+
+static void request_get_key_cb(struct ofono_stk *stk, DBusMessage *reply)
+{
+ struct stk_command_get_inkey *cmd = &stk->pending_cmd->get_inkey;
+ uint8_t qualifier = stk->pending_cmd->qualifier;
+ dbus_bool_t yesno = (qualifier & (1 << 2)) != 0;
+ dbus_bool_t help = (qualifier & (1 << 7)) != 0;
+ DBusError err;
+ enum stk_result_type type = STK_RESULT_TYPE_SUCCESS;
+ struct stk_response rsp;
+ struct ofono_error error = { .type = OFONO_ERROR_TYPE_FAILURE };
+ char *key;
+
+ if (!reply) {
+ if (stk->cmd_timeout) {
+ app_agent_request_cancel(stk);
+
+ display_idle(stk);
+ return;
+ }
+
+ type = STK_RESULT_TYPE_NO_RESPONSE;
+
+ goto send;
+ }
+
+ dbus_error_init(&err);
+ if (dbus_set_error_from_message(&err, reply)) {
+ if (g_str_equal(err.name, OFONO_NAVIGATION_TERMINATED))
+ type = STK_RESULT_TYPE_USER_TERMINATED;
+ else if (g_str_equal(err.name, OFONO_NAVIGATION_GOBACK))
+ type = STK_RESULT_TYPE_GO_BACK;
+ else if (g_str_equal(err.name, OFONO_NAVIGATION_GETHELP) &&
+ help)
+ type = STK_RESULT_TYPE_HELP_REQUESTED;
+ else {
+ type = STK_RESULT_TYPE_USER_TERMINATED;
+
+ ofono_error("Unknown reply %s", err.name);
+ }
+
+ dbus_error_free(&err);
+ goto send;
+ }
+
+ if (dbus_message_get_args(reply, NULL,
+ DBUS_TYPE_STRING, &key,
+ DBUS_TYPE_INVALID) == FALSE) {
+ type = STK_RESULT_TYPE_USER_TERMINATED;
+
+ ofono_error("Reply not understood");
+ goto send;
+ }
+
+ if (yesno && strcasecmp(key, "yes") && strcasecmp(key, "no")) {
+ type = STK_RESULT_TYPE_USER_TERMINATED;
+
+ ofono_error("Yes/No reply not understood");
+ goto send;
+ } else if (yesno && strcasecmp(key, "yes"))
+ key = NULL; /* NULL indicates No, non-NULL indicates Yes */
+
+send:
+ memset(&rsp, 0, sizeof(rsp));
+ rsp.result.type = type;
+
+ if (type == STK_RESULT_TYPE_SUCCESS) {
+ rsp.get_inkey.text.text = key;
+ rsp.get_inkey.text.packed = FALSE;
+ rsp.get_inkey.text.yesno = yesno;
+ }
+
+ if (cmd->duration.interval) {
+ struct timeval end_ts;
+ int interval;
+
+ gettimeofday(&end_ts, NULL);
+
+ interval = (end_ts.tv_usec + 1099999 -
+ stk->get_inkey_start_ts.tv_usec) / 100000;
+ interval += (end_ts.tv_sec -
+ stk->get_inkey_start_ts.tv_sec) * 10;
+ interval -= 10;
+
+ switch (cmd->duration.unit) {
+ case STK_DURATION_TYPE_MINUTES:
+ interval = (interval + 59) / 60;
+ case STK_DURATION_TYPE_SECONDS:
+ interval = (interval + 9) / 10;
+ case STK_DURATION_TYPE_SECOND_TENTHS:
+ break;
+ }
+
+ rsp.get_inkey.duration.unit = cmd->duration.unit;
+ rsp.get_inkey.duration.interval = interval;
+ }
+
+ if (stk_respond(stk, &rsp, display_command_cb))
+ display_command_cb(&error, stk);
+}
+
+static gboolean handle_command_get_inkey(const struct stk_command *cmd,
+ struct stk_response *rsp,
+ struct ofono_stk *stk)
+{
+ int timeout = 0;
+
+ if (cmd->get_inkey.duration.interval) {
+ timeout = cmd->get_inkey.duration.interval;
+ switch (cmd->get_inkey.duration.unit) {
+ case STK_DURATION_TYPE_MINUTES:
+ timeout *= 60;
+ case STK_DURATION_TYPE_SECONDS:
+ timeout *= 10;
+ case STK_DURATION_TYPE_SECOND_TENTHS:
+ timeout *= 100;
+ }
+ }
+
+ gettimeofday(&stk->get_inkey_start_ts, NULL);
+
+ stk->custom_timeout = timeout;
+ app_agent_request_start(stk, request_get_key_send, request_get_key_cb,
+ STK_AGENT_GET_KEY);
+
+ return FALSE;
+}
+
void ofono_stk_proactive_command_cancel(struct ofono_stk *stk)
{
if (!stk->pending_cmd)
@@ -1140,6 +1294,10 @@ void ofono_stk_proactive_command_notify(struct ofono_stk *stk,
case STK_COMMAND_TYPE_DISPLAY_TEXT:
respond = handle_command_display_text(stk->pending_cmd,
&rsp, stk);
+ break;
+ case STK_COMMAND_TYPE_GET_INKEY:
+ respond = handle_command_get_inkey(stk->pending_cmd,
+ &rsp, stk);
}
if (respond)
--
1.7.1.86.g0e460.dirty
11 years, 11 months