RF control, atoms and "Powered" property
by Pekka Pessi
Hello all,
I continue the Powered saga with Nokia N900 phone as an example use
case. N900 is a Linux phone running Maemo 5, it has a Nokia modem with
ISI interface.
When N900 is powered on, it boots the Linux. First thing in user space
are the system services, things like system dbus, hal, ohm. Also, the
daemons controlling the modem, sscd and csd are started immediately
after the system dbus gets started. (csd provides roughly the same
functionality as ofono does, sscd powers on the modem and controls its
RF state.)
Next step is to start the X server and launch the X session. The first
UI component started after the boot is system-ui. If phone is in
offline or "flight" mode, system-ui asks whether user wants to get
online. If so, it changes the system mode to "normal". Next thing is
pin-query UI. The PIN query checks if there is SIM card which requires
a PIN or PUK code. After giving the PIN/PUK code to the modem, it also
checks if additional codes like device unlocking code is needed and
prompts for them.
Next thing is localization wizard, known as startup-wizard. If it
detects that a new SIM card is inserted into the device it will prompt
the user about the user interface language and the regional settings
with defaults based on the information read from the SIM card.
The normal X session is then started with home screen. The session
includes the Telepathy framework used to handle calls and messaging. A
Telepathy component called Mission Control loads the UI and logging
components and the protocol-specific connection managers. Only after
they are ready to handle an incoming call, the modem is given
permission to register to the cellular network.
N900 modem has three runlevels or states used to control modem,
POWER_OFF, RF_INACTIVE and NORMAL. Power off means real power off, it
is only used when whole device is powered off. The rf inactive is also
pretty self-explanatory. The normal state activates the 3G/UMTS radios
and the software controlling it. The first thing the radio resource
control (RRC) does is registering the modem to the network. If the SIM
is ready, it registers using IMSI. If not, it registers using IMEI. In
latter case, the network only provides "limited services". Only
service available in this limited service mode is emergency call.
There are two conditions when N900 modem enters the normal mode (turn
on the modem radios and register to the network):
1) SIM is ready (there is a SIM card inserted in the device, a PIN
code is entered), device is not in flight mode and call UI is ready to
accept an incoming call
2) an emergency call is made
On N900, emergency calls can be initiated by three UI components:
normal call UI, PIN query UI, and screen lock UI. You can make an
emergency call if you enter a valid emergency number like 112 or 911
as pin code or lock code. This is not a N900 feature, but a type
approval requirement for cellular phones. These UI components need to
access the list of valid emergency numbers and a way to initiate an
emergency call regardless of the RF state of the modem. It makes no
sense to enable cellular radio just in order to check if a screen lock
code entered by user is an emergency call number. When the UI
component requests an emergency call, the csd call component makes
things required to place the call: enables RF (and registers to
network), detaches GPRS and then lets the modem dial the emergency
call.
So, based on N900 experience, the current "Powered" property does not
serve any purpose in RF control. The only interesting use case for RF
control is in post-sim state. If the modem is on, but there is no SIM
card or it requires a PIN code, modem should not enable RF. However,
the atoms required to initiate emergency call should be there.
The emergency call can and probably should override the normal power
control. In other words, if RF is disabled for any reason, it gets
enabled for emergency calls but only during the call. Many other
settings beside RF on/off gets overridden during the call. If
registration is disabled, it gets enabled. If manual registration is
configured, and that network rejects the registration attempt, modem
registers to an another network.
--
Pekka.Pessi mail at nokia.com
10 years, 9 months
Unreliable next_msg_id (was Re: [PATCH 2/2] Added SQLite history plugin)
by Nicola Mfb
Hi!
At first look it seems that ofono stores permanently the next_msg_id
only when the "sms_remove" functions is called, and that's does not
happen when ofono quits in a not clean way.
During our tests, users reported bad behaivour of the sqlite history
plugins and error messages about sqlite constraints violation, after a
rude power off of the device (battery drained, forced shutdown with
long press power button, and so on).
That's becouse ofono on the next start reads an "old" next_msg_id from
the permanent storage, so when sending/receiving a new message the
history plugin fails to insert a new row as one with the same msg_id
was already inserted in the prev session.
Any suggestion to fix that?
Finally, we'd like to use some "panic" function in ofono, that should
power down all modems and warn clients when critical conditions
happen.
Is that possible?
Regards
Niko
10 years, 9 months
Access to SIM card when Modem is not "Powered"
by Pekka Pessi
Hi all,
I think the Modem "Powered" property is meant to control the radios
(something like at+cfun=0 vs. at+cfun=1..). Now core automatically
removes all the atoms in case modem has "Powered" false. However, the
SIM card should be accessible while the radios are off (cfun=0) so
that PIN code could be entered. If the +CFUN=1 is given before PIN
code is entered, the modem registers to network in limited service
(emergency call only) mode. Perhaps it would be better to let the
modem driver itself decide which atoms are active when it is not fully
powered?
--
Pekka.Pessi mail at nokia.com
10 years, 9 months
[PATCH 8/8] Implement STATUS polling in atmodem driver.
by Andrzej Zaborowski
---
Makefile.am | 2 +
drivers/atmodem/sim-poll.c | 319 ++++++++++++++++++++++++++++++++++++++++++++
drivers/atmodem/sim-poll.h | 22 +++
plugins/atgen.c | 8 +-
plugins/phonesim.c | 5 +-
5 files changed, 350 insertions(+), 5 deletions(-)
create mode 100644 drivers/atmodem/sim-poll.c
create mode 100644 drivers/atmodem/sim-poll.h
diff --git a/Makefile.am b/Makefile.am
index a506dba..1279b0a 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -125,6 +125,8 @@ builtin_sources += $(gatchat_sources) \
drivers/atmodem/network-registration.c \
drivers/atmodem/sim.c \
drivers/atmodem/stk.c \
+ drivers/atmodem/sim-poll.c \
+ drivers/atmodem/sim-poll.h \
drivers/atmodem/ussd.c \
drivers/atmodem/voicecall.c \
drivers/atmodem/call-barring.c \
diff --git a/drivers/atmodem/sim-poll.c b/drivers/atmodem/sim-poll.c
new file mode 100644
index 0000000..0fca4e7
--- /dev/null
+++ b/drivers/atmodem/sim-poll.c
@@ -0,0 +1,319 @@
+/*
+ *
+ * oFono - Open Source Telephony
+ *
+ * Copyright (C) 2008-2010 Intel 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
+
+#define _GNU_SOURCE
+#include <stdio.h>
+
+#include <glib.h>
+
+#include <ofono/log.h>
+#include <ofono/modem.h>
+#include <ofono/sim.h>
+#include <ofono/stk.h>
+
+#include "gatchat.h"
+#include "gatresult.h"
+#include "ofono.h"
+
+#include "atmodem.h"
+#include "sim-poll.h"
+
+struct sim_poll_data {
+ GAtChat *chat;
+ struct ofono_modem *modem;
+ struct ofono_sim *sim;
+ struct ofono_stk *stk;
+ unsigned int sim_watch;
+ unsigned int stk_watch;
+ unsigned int sim_state_watch;
+ gboolean inserted;
+ int idle_poll_interval;
+ gint status_timeout;
+ gint poll_timeout;
+ guint status_cmd;
+};
+
+static const char *csim_prefix[] = { "+CSIM:", NULL };
+
+static gboolean sim_status_poll(gpointer user_data);
+static void sim_fetch_command(struct sim_poll_data *spd, int length);
+
+static void at_csim_fetch_cb(gboolean ok, GAtResult *result,
+ gpointer user_data)
+{
+ struct sim_poll_data *spd = user_data;
+ GAtResultIter iter;
+ const guint8 *response;
+ gint rlen, len;
+
+ if (!ok)
+ return;
+
+ g_at_result_iter_init(&iter, result);
+
+ if (!g_at_result_iter_next(&iter, "+CSIM:"))
+ return;
+
+ if (!g_at_result_iter_next_number(&iter, &rlen))
+ return;
+
+ if (!g_at_result_iter_next_hexstring(&iter, &response, &len))
+ return;
+
+ if (rlen != len * 2 || len < 2)
+ return;
+
+ /* Check that SW1 indicates success */
+ if (response[len - 2] != 0x90 && response[len - 2] != 0x91)
+ return;
+
+ if (response[len - 2] == 0x90 && response[len - 1] != 0)
+ return;
+
+ DBG("csim_fetch_cb: %i", len);
+
+ ofono_stk_proactive_command_notify(spd->stk, len - 2, response);
+
+ /* Can this happen? */
+ if (response[len - 2] == 0x91)
+ sim_fetch_command(spd, response[len - 1]);
+}
+
+static void sim_fetch_command(struct sim_poll_data *spd, int length)
+{
+ char buf[64];
+
+ snprintf(buf, sizeof(buf), "AT+CSIM=10,A0120000%02hhX", length);
+
+ g_at_chat_send(spd->chat, buf, csim_prefix,
+ at_csim_fetch_cb, spd, NULL);
+}
+
+static void sim_status_poll_schedule(struct sim_poll_data *spd)
+{
+ /* TODO: Decide on the interval based on whether any call is active */
+ /* TODO: On idle, possibly only schedule if proactive commands enabled
+ * as indicated by EFphase + EFsst (51.011: 11.6.1) */
+ int interval = spd->idle_poll_interval;
+
+ /* When a SIM is inserted, the SIM might have requested a different
+ * interval. */
+ if (spd->inserted)
+ interval = ofono_modem_get_integer(spd->modem,
+ "status-poll-interval");
+
+ spd->poll_timeout = g_timeout_add_seconds(interval,
+ sim_status_poll, spd);
+}
+
+static gboolean sim_status_timeout(gpointer user_data)
+{
+ struct sim_poll_data *spd = user_data;
+
+ spd->status_timeout = 0;
+
+ g_at_chat_cancel(spd->chat, spd->status_cmd);
+ spd->status_cmd = 0;
+
+ if (spd->inserted == TRUE) {
+ spd->inserted = FALSE;
+ ofono_sim_inserted_notify(spd->sim, FALSE);
+ }
+
+ sim_status_poll_schedule(spd);
+
+ return FALSE;
+}
+
+static void at_csim_status_cb(gboolean ok, GAtResult *result,
+ gpointer user_data)
+{
+ struct sim_poll_data *spd = user_data;
+ GAtResultIter iter;
+ const guint8 *response;
+ gint rlen, len;
+
+ spd->status_cmd = 0;
+
+ if (!spd->status_timeout)
+ /* The STATUS already timed out */
+ return;
+
+ /* Card responded on time */
+
+ g_source_remove(spd->status_timeout);
+ spd->status_timeout = 0;
+
+ if (spd->inserted != TRUE) {
+ spd->inserted = TRUE;
+ ofono_sim_inserted_notify(spd->sim, TRUE);
+ }
+
+ sim_status_poll_schedule(spd);
+
+ /* Check if we have a proactive command */
+
+ if (!ok)
+ return;
+
+ g_at_result_iter_init(&iter, result);
+
+ if (!g_at_result_iter_next(&iter, "+CSIM:"))
+ return;
+
+ if (!g_at_result_iter_next_number(&iter, &rlen))
+ return;
+
+ if (!g_at_result_iter_next_hexstring(&iter, &response, &len))
+ return;
+
+ if (rlen != len * 2 || len < 2)
+ return;
+
+ if (response[len - 2] != 0x91)
+ return;
+
+ /* We have a proactive command pending, FETCH it */
+ sim_fetch_command(spd, response[len - 1]);
+}
+
+static gboolean sim_status_poll(gpointer user_data)
+{
+ struct sim_poll_data *spd = user_data;
+
+ spd->poll_timeout = 0;
+
+ /* The SIM must respond in a given time frame which is of at
+ * least 5 seconds in TS 11.11. */
+ spd->status_timeout = g_timeout_add_seconds(5,
+ sim_status_timeout, spd);
+
+ /* Send STATUS */
+ spd->status_cmd = g_at_chat_send(spd->chat, "AT+CSIM=8,A0F200C0",
+ csim_prefix, at_csim_status_cb, spd, NULL);
+ if (spd->status_cmd == 0)
+ at_csim_status_cb(FALSE, NULL, spd);
+
+ return FALSE;
+}
+
+static void sim_state_watch(void *user, enum ofono_sim_state new_state)
+{
+ struct sim_poll_data *spd = user;
+
+ spd->inserted = new_state != OFONO_SIM_STATE_NOT_PRESENT;
+
+ if (!spd->inserted)
+ ofono_modem_set_integer(spd->modem,
+ "status-poll-interval", 30);
+}
+
+static void sim_watch(struct ofono_atom *atom,
+ enum ofono_atom_watch_condition cond, void *data)
+{
+ struct sim_poll_data *spd = data;
+
+ if (cond == OFONO_ATOM_WATCH_CONDITION_REGISTERED) {
+ spd->sim = __ofono_atom_get_data(atom);
+
+ spd->sim_state_watch = ofono_sim_add_state_watch(spd->sim,
+ sim_state_watch, spd, NULL);
+ sim_state_watch(spd, ofono_sim_get_state(spd->sim));
+
+ sim_status_poll(spd);
+
+ return;
+ }
+
+ if (cond != OFONO_ATOM_WATCH_CONDITION_UNREGISTERED)
+ return;
+
+ spd->inserted = FALSE;
+
+ spd->sim_state_watch = 0;
+
+ if (spd->sim_watch) {
+ __ofono_modem_remove_atom_watch(spd->modem, spd->sim_watch);
+ spd->sim_watch = 0;
+ }
+
+ if (spd->stk_watch) {
+ __ofono_modem_remove_atom_watch(spd->modem, spd->stk_watch);
+ spd->stk_watch = 0;
+ }
+
+ if (spd->status_timeout) {
+ g_source_remove(spd->status_timeout);
+ spd->status_timeout = 0;
+ }
+
+ if (spd->poll_timeout) {
+ g_source_remove(spd->poll_timeout);
+ spd->poll_timeout = 0;
+ }
+
+ g_free(spd);
+}
+
+static void stk_watch(struct ofono_atom *atom,
+ enum ofono_atom_watch_condition cond, void *data)
+{
+ struct sim_poll_data *spd = data;
+
+ if (cond == OFONO_ATOM_WATCH_CONDITION_REGISTERED)
+ spd->stk = __ofono_atom_get_data(atom);
+ else if (cond == OFONO_ATOM_WATCH_CONDITION_UNREGISTERED)
+ spd->stk = NULL;
+}
+
+void ofono_atmodem_poll_enable(struct ofono_modem *modem, GAtChat *chat)
+{
+ struct ofono_atom *sim_atom;
+ struct ofono_atom *stk_atom;
+ struct sim_poll_data *spd;
+
+ sim_atom = __ofono_modem_find_atom(modem, OFONO_ATOM_TYPE_SIM);
+ stk_atom = __ofono_modem_find_atom(modem, OFONO_ATOM_TYPE_STK);
+
+ if (!sim_atom)
+ return;
+
+ spd = g_new0(struct sim_poll_data, 1);
+ spd->chat = chat;
+ spd->modem = modem;
+ spd->idle_poll_interval = 30;
+
+ spd->stk_watch = __ofono_modem_add_atom_watch(spd->modem,
+ OFONO_ATOM_TYPE_STK, stk_watch, spd, NULL);
+ if (stk_atom && __ofono_atom_get_registered(stk_atom))
+ stk_watch(stk_atom,
+ OFONO_ATOM_WATCH_CONDITION_REGISTERED, spd);
+
+ spd->sim_watch = __ofono_modem_add_atom_watch(spd->modem,
+ OFONO_ATOM_TYPE_SIM, sim_watch, spd, NULL);
+ if (__ofono_atom_get_registered(sim_atom))
+ sim_watch(sim_atom,
+ OFONO_ATOM_WATCH_CONDITION_REGISTERED, spd);
+}
diff --git a/drivers/atmodem/sim-poll.h b/drivers/atmodem/sim-poll.h
new file mode 100644
index 0000000..595c2f5
--- /dev/null
+++ b/drivers/atmodem/sim-poll.h
@@ -0,0 +1,22 @@
+/*
+ *
+ * oFono - Open Source Telephony
+ *
+ * Copyright (C) 2008-2010 Intel 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
+ *
+ */
+
+void ofono_atmodem_poll_enable(struct ofono_modem *modem, GAtChat *chat);
diff --git a/plugins/atgen.c b/plugins/atgen.c
index 262d32f..4a0e315 100644
--- a/plugins/atgen.c
+++ b/plugins/atgen.c
@@ -49,6 +49,8 @@
#include <ofono/ussd.h>
#include <ofono/voicecall.h>
+#include <drivers/atmodem/sim-poll.h>
+
static const char *tty_opts[] = {
"Baud",
"Read",
@@ -157,17 +159,15 @@ static int atgen_disable(struct ofono_modem *modem)
static void atgen_pre_sim(struct ofono_modem *modem)
{
GAtChat *chat = ofono_modem_get_data(modem);
- struct ofono_sim *sim;
DBG("%p", modem);
ofono_devinfo_create(modem, 0, "atmodem", chat);
- sim = ofono_sim_create(modem, 0, "atmodem", chat);
+ ofono_sim_create(modem, 0, "atmodem", chat);
ofono_voicecall_create(modem, 0, "atmodem", chat);
ofono_stk_create(modem, 0, "atmodem", chat);
- if (sim)
- ofono_sim_inserted_notify(sim, TRUE);
+ ofono_atmodem_poll_enable(modem, chat);
}
static void atgen_post_sim(struct ofono_modem *modem)
diff --git a/plugins/phonesim.c b/plugins/phonesim.c
index 9153e1b..5685820 100644
--- a/plugins/phonesim.c
+++ b/plugins/phonesim.c
@@ -59,6 +59,7 @@
#include <ofono/gprs-context.h>
#include <drivers/atmodem/vendor.h>
+#include <drivers/atmodem/sim-poll.h>
struct phonesim_data {
GAtMux *mux;
@@ -292,7 +293,9 @@ static void phonesim_pre_sim(struct ofono_modem *modem)
ofono_stk_create(modem, 0, "atmodem", data->chat);
- if (sim)
+ if (!data->calypso)
+ ofono_atmodem_poll_enable(modem, data->chat);
+ else if (sim)
ofono_sim_inserted_notify(sim, TRUE);
}
--
1.6.1
10 years, 9 months
[PATCH 5/8] Remove post-sim atoms after SIM is extracted.
by Andrzej Zaborowski
---
src/modem.c | 40 ++++++++++++++++++++++++++++++++++++++++
1 files changed, 40 insertions(+), 0 deletions(-)
diff --git a/src/modem.c b/src/modem.c
index 7cdd9c4..45c2bc4 100644
--- a/src/modem.c
+++ b/src/modem.c
@@ -53,6 +53,7 @@ enum ofono_property_type {
struct ofono_modem {
char *path;
GSList *atoms;
+ GSList *pre_sim_atoms;
struct ofono_watchlist *atom_watches;
GSList *interface_list;
unsigned int call_ids;
@@ -301,6 +302,7 @@ void __ofono_atom_free(struct ofono_atom *atom)
struct ofono_modem *modem = atom->modem;
modem->atoms = g_slist_remove(modem->atoms, atom);
+ modem->pre_sim_atoms = g_slist_remove(modem->pre_sim_atoms, atom);
__ofono_atom_unregister(atom);
@@ -330,7 +332,35 @@ static void remove_all_atoms(struct ofono_modem *modem)
}
g_slist_free(modem->atoms);
+ g_slist_free(modem->pre_sim_atoms);
modem->atoms = NULL;
+ modem->pre_sim_atoms = NULL;
+}
+
+static void remove_post_sim_atoms(struct ofono_modem *modem)
+{
+ GSList *l;
+ struct ofono_atom *atom;
+
+ if (modem == NULL)
+ return;
+
+ for (l = modem->atoms; l; l = l->next) {
+ atom = l->data;
+
+ if (g_slist_find(modem->pre_sim_atoms, atom))
+ continue;
+
+ __ofono_atom_unregister(atom);
+
+ if (atom->destruct)
+ atom->destruct(atom);
+
+ g_free(atom);
+ }
+
+ g_slist_free(modem->atoms);
+ modem->atoms = g_slist_copy(modem->pre_sim_atoms);
}
static DBusMessage *modem_get_properties(DBusConnection *conn,
@@ -1122,9 +1152,19 @@ static void modem_sim_ready(void *user, enum ofono_sim_state new_state)
{
struct ofono_modem *modem = user;
+ if (new_state == OFONO_SIM_STATE_NOT_PRESENT) {
+ if (modem->pre_sim_atoms)
+ remove_post_sim_atoms(modem);
+
+ return;
+ }
+
if (new_state != OFONO_SIM_STATE_READY)
return;
+ if (modem->pre_sim_atoms == NULL)
+ modem->pre_sim_atoms = g_slist_copy(modem->atoms);
+
if (modem->driver->post_sim)
modem->driver->post_sim(modem);
--
1.6.1
10 years, 9 months
[PATCH 6/8] Add SIM "Present" property.
by Andrzej Zaborowski
---
src/sim.c | 117 ++++++++++++++++++++++++++++++++++++++++---------------------
1 files changed, 77 insertions(+), 40 deletions(-)
diff --git a/src/sim.c b/src/sim.c
index 41ddd13..6bd846f 100644
--- a/src/sim.c
+++ b/src/sim.c
@@ -271,6 +271,7 @@ static DBusMessage *sim_get_properties(DBusConnection *conn,
char **service_numbers;
char **locked_pins;
const char *pin_name;
+ dbus_bool_t present = sim->state != OFONO_SIM_STATE_NOT_PRESENT;
reply = dbus_message_new_method_return(msg);
if (!reply)
@@ -282,6 +283,11 @@ static DBusMessage *sim_get_properties(DBusConnection *conn,
OFONO_PROPERTIES_ARRAY_SIGNATURE,
&dict);
+ ofono_dbus_dict_append(&dict, "Present", DBUS_TYPE_BOOLEAN, &present);
+
+ if (!present)
+ goto done;
+
if (sim->imsi)
ofono_dbus_dict_append(&dict, "SubscriberIdentity",
DBUS_TYPE_STRING, &sim->imsi);
@@ -335,6 +341,7 @@ static DBusMessage *sim_get_properties(DBusConnection *conn,
DBUS_TYPE_STRING,
(void *) &pin_name);
+done:
dbus_message_iter_close_container(&iter, &dict);
return reply;
@@ -1010,6 +1017,8 @@ static void sim_imsi_cb(const struct ofono_error *error, const char *imsi,
void *data)
{
struct ofono_sim *sim = data;
+ DBusConnection *conn = ofono_dbus_get_connection();
+ const char *path = __ofono_atom_get_path(sim->atom);
if (error->type != OFONO_ERROR_TYPE_NO_ERROR) {
ofono_error("Unable to read IMSI, emergency calls only");
@@ -1018,6 +1027,11 @@ static void sim_imsi_cb(const struct ofono_error *error, const char *imsi,
sim->imsi = g_strdup(imsi);
+ ofono_dbus_signal_property_changed(conn, path,
+ OFONO_SIM_MANAGER_INTERFACE,
+ "SubscriberIdentity",
+ DBUS_TYPE_STRING, &sim->imsi);
+
/* Read CPHS-support bits, this is still part of the SIM
* initialisation but no order is specified for it. */
ofono_sim_read(sim, SIM_EF_CPHS_INFORMATION_FILEID,
@@ -1778,6 +1792,62 @@ const unsigned char *ofono_sim_get_cphs_service_table(struct ofono_sim *sim)
return sim->cphs_service_table;
}
+static void sim_inserted_update(struct ofono_sim *sim)
+{
+ dbus_bool_t present = sim->state != OFONO_SIM_STATE_NOT_PRESENT;
+ DBusConnection *conn = ofono_dbus_get_connection();
+ const char *path = __ofono_atom_get_path(sim->atom);
+
+ ofono_dbus_signal_property_changed(conn, path,
+ OFONO_SIM_MANAGER_INTERFACE, "Present",
+ DBUS_TYPE_BOOLEAN, &present);
+}
+
+static void sim_free_state(struct ofono_sim *sim)
+{
+ if (sim->simop_source) {
+ g_source_remove(sim->simop_source);
+ sim->simop_source = 0;
+ }
+
+ if (sim->simop_q) {
+ /* Note: users of ofono_sim_read/write must not assume that
+ * the callback happens for operations still in progress. */
+ g_queue_foreach(sim->simop_q, (GFunc)sim_file_op_free, NULL);
+ g_queue_free(sim->simop_q);
+ sim->simop_q = NULL;
+ }
+
+ if (sim->imsi) {
+ g_free(sim->imsi);
+ sim->imsi = NULL;
+ }
+
+ if (sim->own_numbers) {
+ g_slist_foreach(sim->own_numbers, (GFunc)g_free, NULL);
+ g_slist_free(sim->own_numbers);
+ sim->own_numbers = NULL;
+ }
+
+ if (sim->service_numbers) {
+ g_slist_foreach(sim->service_numbers,
+ (GFunc)service_number_free, NULL);
+ g_slist_free(sim->service_numbers);
+ sim->service_numbers = NULL;
+ }
+
+ if (sim->efli) {
+ g_free(sim->efli);
+ sim->efli = NULL;
+ sim->efli_length = 0;
+ }
+
+ if (sim->language_prefs) {
+ g_strfreev(sim->language_prefs);
+ sim->language_prefs = NULL;
+ }
+}
+
void ofono_sim_inserted_notify(struct ofono_sim *sim, ofono_bool_t inserted)
{
ofono_sim_state_event_notify_cb_t notify;
@@ -1793,6 +1863,8 @@ void ofono_sim_inserted_notify(struct ofono_sim *sim, ofono_bool_t inserted)
if (!__ofono_atom_get_registered(sim->atom))
return;
+ sim_inserted_update(sim);
+
for (l = sim->state_watches->items; l; l = l->next) {
struct ofono_watchlist_item *item = l->data;
notify = item->notify;
@@ -1800,8 +1872,11 @@ void ofono_sim_inserted_notify(struct ofono_sim *sim, ofono_bool_t inserted)
notify(item->notify_data, sim->state);
}
- if (!inserted)
+ if (!inserted) {
+ sim_free_state(sim);
+
return;
+ }
/* Perform SIM initialization according to 3GPP 31.102 Section 5.1.1.2
* The assumption here is that if sim manager is being initialized,
@@ -1927,45 +2002,7 @@ static void sim_remove(struct ofono_atom *atom)
if (sim->driver && sim->driver->remove)
sim->driver->remove(sim);
- if (sim->imsi) {
- g_free(sim->imsi);
- sim->imsi = NULL;
- }
-
- if (sim->own_numbers) {
- g_slist_foreach(sim->own_numbers, (GFunc)g_free, NULL);
- g_slist_free(sim->own_numbers);
- sim->own_numbers = NULL;
- }
-
- if (sim->service_numbers) {
- g_slist_foreach(sim->service_numbers,
- (GFunc)service_number_free, NULL);
- g_slist_free(sim->service_numbers);
- sim->service_numbers = NULL;
- }
-
- if (sim->efli) {
- g_free(sim->efli);
- sim->efli = NULL;
- sim->efli_length = 0;
- }
-
- if (sim->language_prefs) {
- g_strfreev(sim->language_prefs);
- sim->language_prefs = NULL;
- }
-
- if (sim->simop_source) {
- g_source_remove(sim->simop_source);
- sim->simop_source = 0;
- }
-
- if (sim->simop_q) {
- g_queue_foreach(sim->simop_q, (GFunc)sim_file_op_free, NULL);
- g_queue_free(sim->simop_q);
- sim->simop_q = NULL;
- }
+ sim_free_state(sim);
g_free(sim);
}
--
1.6.1
10 years, 9 months
[PATCH 4/8] Retrieve/forget emergency numbers on SIM insert/remove.
by Andrzej Zaborowski
---
src/voicecall.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++++------
1 files changed, 58 insertions(+), 7 deletions(-)
diff --git a/src/voicecall.c b/src/voicecall.c
index 8bf6379..b6e0226 100644
--- a/src/voicecall.c
+++ b/src/voicecall.c
@@ -54,6 +54,7 @@ struct ofono_voicecall {
gint emit_calls_source;
gint emit_multi_source;
unsigned int sim_watch;
+ unsigned int sim_state_watch;
const struct ofono_voicecall_driver *driver;
void *driver_data;
struct ofono_atom *atom;
@@ -1784,6 +1785,10 @@ static void voicecall_unregister(struct ofono_atom *atom)
static void voicecall_remove(struct ofono_atom *atom)
{
struct ofono_voicecall *vc = __ofono_atom_get_data(atom);
+ struct ofono_modem *modem = __ofono_atom_get_modem(vc->atom);
+ struct ofono_atom *sim_atom =
+ __ofono_modem_find_atom(modem, OFONO_ATOM_TYPE_SIM);
+ struct ofono_sim *sim = NULL;
DBG("atom: %p", atom);
@@ -1805,6 +1810,14 @@ static void voicecall_remove(struct ofono_atom *atom)
vc->new_en_list = NULL;
}
+ if (sim_atom && __ofono_atom_get_registered(sim_atom))
+ sim = __ofono_atom_get_data(sim_atom);
+
+ if (sim && vc->sim_state_watch) {
+ ofono_sim_remove_state_watch(sim, vc->sim_state_watch);
+ vc->sim_state_watch = 0;
+ }
+
g_free(vc);
}
@@ -1843,6 +1856,46 @@ struct ofono_voicecall *ofono_voicecall_create(struct ofono_modem *modem,
return vc;
}
+static void sim_state_watch(void *user, enum ofono_sim_state new_state)
+{
+ struct ofono_voicecall *vc = user;
+
+ if (new_state == OFONO_SIM_STATE_INSERTED) {
+ struct ofono_modem *modem =
+ __ofono_atom_get_modem(vc->atom);
+ struct ofono_atom *sim_atom =
+ __ofono_modem_find_atom(modem, OFONO_ATOM_TYPE_SIM);
+ struct ofono_sim *sim =
+ __ofono_atom_get_data(sim_atom);
+
+ /* Try both formats, only one or none will work */
+ ofono_sim_read(sim, SIM_EFECC_FILEID,
+ OFONO_SIM_FILE_STRUCTURE_TRANSPARENT,
+ ecc_g2_read_cb, vc);
+ ofono_sim_read(sim, SIM_EFECC_FILEID,
+ OFONO_SIM_FILE_STRUCTURE_FIXED,
+ ecc_g3_read_cb, vc);
+
+ return;
+ }
+
+ if (new_state != OFONO_SIM_STATE_NOT_PRESENT)
+ return;
+
+ if (vc->call_list) {
+ /* TODO: Must release all non-emergency calls */
+ }
+
+ if (vc->new_en_list) {
+ g_slist_foreach(vc->new_en_list, (GFunc) g_free, NULL);
+ g_slist_free(vc->new_en_list);
+ vc->new_en_list = NULL;
+ }
+
+ add_to_en_list(&vc->new_en_list, default_en_list_no_sim);
+ set_new_ecc(vc);
+}
+
static void sim_watch(struct ofono_atom *atom,
enum ofono_atom_watch_condition cond, void *data)
{
@@ -1850,16 +1903,14 @@ static void sim_watch(struct ofono_atom *atom,
struct ofono_sim *sim = __ofono_atom_get_data(atom);
if (cond == OFONO_ATOM_WATCH_CONDITION_UNREGISTERED) {
+ vc->sim_state_watch = 0;
return;
}
- /* Try both formats, only one or none will work */
- ofono_sim_read(sim, SIM_EFECC_FILEID,
- OFONO_SIM_FILE_STRUCTURE_TRANSPARENT,
- ecc_g2_read_cb, vc);
- ofono_sim_read(sim, SIM_EFECC_FILEID,
- OFONO_SIM_FILE_STRUCTURE_FIXED,
- ecc_g3_read_cb, vc);
+ vc->sim_state_watch = ofono_sim_add_state_watch(sim,
+ sim_state_watch, vc, NULL);
+
+ sim_state_watch(vc, ofono_sim_get_state(sim));
}
void ofono_voicecall_register(struct ofono_voicecall *vc)
--
1.6.1
10 years, 9 months
[PATCH 3/8] Add an atom for STK, move envelope command to stk driver.
by Andrzej Zaborowski
---
Makefile.am | 4 +-
drivers/atmodem/sim.c | 77 -------------------
include/sim.h | 3 -
include/stk.h | 71 +++++++++++++++++
src/cbs.c | 10 ++-
src/modem.c | 1 +
src/ofono.h | 4 +-
src/sim.c | 37 ---------
src/stk.c | 201 +++++++++++++++++++++++++++++++++++++++++++++++++
9 files changed, 287 insertions(+), 121 deletions(-)
create mode 100644 include/stk.h
create mode 100644 src/stk.c
diff --git a/Makefile.am b/Makefile.am
index ee10095..7a18c41 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -12,7 +12,7 @@ include_HEADERS = include/log.h include/plugin.h include/history.h \
include/netreg.h include/voicecall.h include/devinfo.h \
include/cbs.h include/call-volume.h \
include/gprs.h include/gprs-context.h \
- include/radio-settings.h
+ include/radio-settings.h include/stk.h
nodist_include_HEADERS = include/version.h
@@ -231,7 +231,7 @@ src_ofonod_SOURCES = $(gdbus_sources) $(builtin_sources) \
src/network.c src/voicecall.c src/ussd.c src/sms.c \
src/call-settings.c src/call-forwarding.c \
src/call-meter.c src/smsutil.h src/smsutil.c \
- src/ssn.c src/call-barring.c src/sim.c \
+ src/ssn.c src/call-barring.c src/sim.c src/stk.c \
src/phonebook.c src/history.c src/message-waiting.c \
src/simutil.h src/simutil.c src/storage.h \
src/storage.c src/cbs.c src/watch.c src/call-volume.c \
diff --git a/drivers/atmodem/sim.c b/drivers/atmodem/sim.c
index 89ddcc6..13e7459 100644
--- a/drivers/atmodem/sim.c
+++ b/drivers/atmodem/sim.c
@@ -709,82 +709,6 @@ error:
CALLBACK_WITH_FAILURE(cb, -1, data);
}
-static void at_csim_envelope_cb(gboolean ok, GAtResult *result,
- gpointer user_data)
-{
- struct cb_data *cbd = user_data;
- GAtResultIter iter;
- ofono_sim_read_cb_t cb = cbd->cb;
- struct ofono_error error;
- const guint8 *response;
- gint rlen, len;
-
- decode_at_error(&error, g_at_result_final_response(result));
-
- if (!ok)
- goto error;
-
- g_at_result_iter_init(&iter, result);
-
- if (!g_at_result_iter_next(&iter, "+CSIM:"))
- goto error;
-
- if (!g_at_result_iter_next_number(&iter, &rlen))
- goto error;
-
- if (!g_at_result_iter_next_hexstring(&iter, &response, &len))
- goto error;
-
- if (rlen != len * 2 || len < 2 ||
- response[len - 2] != 0x90 || response[len - 1] != 0)
- goto error;
-
- DBG("csim_envelope_cb: %i", len);
-
- cb(&error, response, len - 2, cbd->data);
- return;
-
-error:
- CALLBACK_WITH_FAILURE(cb, NULL, 0, cbd->data);
-}
-
-static void at_sim_envelope(struct ofono_sim *sim, int length,
- const guint8 *command,
- ofono_sim_read_cb_t cb, void *data)
-{
- struct sim_data *sd = ofono_sim_get_data(sim);
- struct cb_data *cbd = cb_data_new(cb, data);
- char *buf = g_try_new(char, 64 + length * 2);
- int len, ret;
-
- if (!cbd || !buf)
- goto error;
-
- len = sprintf(buf, "AT+CSIM=%i,A0C20000%02hhX",
- 10 + length * 2, length);
-
- for (; length; length--)
- len += sprintf(buf + len, "%02hhX", *command++);
-
- ret = g_at_chat_send(sd->chat, buf, crsm_prefix,
- at_csim_envelope_cb, cbd, g_free);
-
- g_free(buf);
- buf = NULL;
-
- if (ret > 0)
- return;
-
-error:
- if (buf)
- g_free(buf);
-
- if (cbd)
- g_free(cbd);
-
- CALLBACK_WITH_FAILURE(cb, NULL, 0, data);
-}
-
static gboolean at_sim_register(gpointer user)
{
struct ofono_sim *sim = user;
@@ -840,7 +764,6 @@ static struct ofono_sim_driver driver = {
.lock = at_pin_enable,
.change_passwd = at_change_passwd,
.query_locked = at_pin_query_enabled,
- .envelope = at_sim_envelope,
};
void at_sim_init()
diff --git a/include/sim.h b/include/sim.h
index 2218564..36a99b9 100644
--- a/include/sim.h
+++ b/include/sim.h
@@ -156,9 +156,6 @@ struct ofono_sim_driver {
void (*query_locked)(struct ofono_sim *sim,
enum ofono_sim_password_type type,
ofono_sim_locked_cb_t cb, void *data);
- void (*envelope)(struct ofono_sim *sim, int length,
- const guint8 *command,
- ofono_sim_read_cb_t cb, void *data);
};
int ofono_sim_driver_register(const struct ofono_sim_driver *d);
diff --git a/include/stk.h b/include/stk.h
new file mode 100644
index 0000000..dfae261
--- /dev/null
+++ b/include/stk.h
@@ -0,0 +1,71 @@
+/*
+ *
+ * oFono - Open Source Telephony
+ *
+ * Copyright (C) 2008-2010 Intel 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
+ *
+ */
+
+#ifndef __OFONO_STK_H
+#define __OFONO_STK_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <ofono/types.h>
+
+struct ofono_stk;
+
+typedef void (*ofono_stk_envelope_cb_t)(const struct ofono_error *error,
+ const unsigned char *rdata, int length, void *data);
+
+typedef void (*ofono_stk_generic_cb_t)(const struct ofono_error *error,
+ void *data);
+
+struct ofono_stk_driver {
+ const char *name;
+ int (*probe)(struct ofono_stk *stk, unsigned int vendor, void *data);
+ void (*remove)(struct ofono_stk *stk);
+ void (*envelope)(struct ofono_stk *stk, int length,
+ const guint8 *command, ofono_stk_envelope_cb_t cb,
+ void *data);
+ void (*terminal_response)(struct ofono_stk *stk, int length,
+ const unsigned char *value, ofono_stk_generic_cb_t cb,
+ void *data);
+};
+
+int ofono_stk_driver_register(const struct ofono_stk_driver *d);
+void ofono_stk_driver_unregister(const struct ofono_stk_driver *d);
+
+struct ofono_stk *ofono_stk_create(struct ofono_modem *modem,
+ unsigned int vendor,
+ const char *driver, void *data);
+
+void ofono_stk_register(struct ofono_stk *stk);
+void ofono_stk_remove(struct ofono_stk *stk);
+
+void ofono_stk_set_data(struct ofono_stk *stk, void *data);
+void *ofono_stk_get_data(struct ofono_stk *stk);
+
+void ofono_stk_proactive_command_notify(struct ofono_stk *stk,
+ int length, const guint8 *pdu);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __OFONO_STK_H */
diff --git a/src/cbs.c b/src/cbs.c
index 2fa33c1..ff343e3 100644
--- a/src/cbs.c
+++ b/src/cbs.c
@@ -57,6 +57,7 @@ struct ofono_cbs {
GSList *topics;
GSList *new_topics;
struct ofono_sim *sim;
+ struct ofono_stk *stk;
struct ofono_netreg *netreg;
unsigned int netreg_watch;
unsigned int location_watch;
@@ -195,7 +196,7 @@ void ofono_cbs_notify(struct ofono_cbs *cbs, const unsigned char *pdu,
}
if (cbs_topic_in_range(c.message_identifier, cbs->efcbmid_contents)) {
- __ofono_cbs_sim_download(cbs->sim, pdu, pdu_len);
+ __ofono_cbs_sim_download(cbs->stk, pdu, pdu_len);
return;
}
@@ -590,6 +591,7 @@ static void cbs_unregister(struct ofono_atom *atom)
}
cbs->sim = NULL;
+ cbs->stk = NULL;
if (cbs->reset_source) {
g_source_remove(cbs->reset_source);
@@ -1027,6 +1029,7 @@ void ofono_cbs_register(struct ofono_cbs *cbs)
struct ofono_modem *modem = __ofono_atom_get_modem(cbs->atom);
const char *path = __ofono_atom_get_path(cbs->atom);
struct ofono_atom *sim_atom;
+ struct ofono_atom *stk_atom;
struct ofono_atom *netreg_atom;
if (!g_dbus_register_interface(conn, path,
@@ -1050,6 +1053,11 @@ void ofono_cbs_register(struct ofono_cbs *cbs)
cbs_got_imsi(cbs);
}
+ stk_atom = __ofono_modem_find_atom(modem, OFONO_ATOM_TYPE_SIM);
+
+ if (stk_atom)
+ cbs->stk = __ofono_atom_get_data(stk_atom);
+
cbs->netreg_watch = __ofono_modem_add_atom_watch(modem,
OFONO_ATOM_TYPE_NETREG,
netreg_watch, cbs, NULL);
diff --git a/src/modem.c b/src/modem.c
index df74be3..7cdd9c4 100644
--- a/src/modem.c
+++ b/src/modem.c
@@ -31,6 +31,7 @@
#include <gdbus.h>
#include "ofono.h"
+#include "sim.h"
#include "common.h"
diff --git a/src/ofono.h b/src/ofono.h
index ff67728..7b13cce 100644
--- a/src/ofono.h
+++ b/src/ofono.h
@@ -114,6 +114,7 @@ enum ofono_atom_type {
OFONO_ATOM_TYPE_GPRS = 16,
OFONO_ATOM_TYPE_GPRS_CONTEXT = 17,
OFONO_ATOM_TYPE_RADIO_SETTINGS = 18,
+ OFONO_ATOM_TYPE_STK = 19,
};
enum ofono_atom_watch_condition {
@@ -172,8 +173,9 @@ void __ofono_atom_free(struct ofono_atom *atom);
#include <ofono/radio-settings.h>
#include <ofono/sim.h>
+#include <ofono/stk.h>
-void __ofono_cbs_sim_download(struct ofono_sim *sim,
+void __ofono_cbs_sim_download(struct ofono_stk *stk,
const guint8 *pdu, int pdu_len);
#include <ofono/ssn.h>
diff --git a/src/sim.c b/src/sim.c
index 5559be4..41ddd13 100644
--- a/src/sim.c
+++ b/src/sim.c
@@ -42,7 +42,6 @@
#include "smsutil.h"
#include "simutil.h"
#include "storage.h"
-#include "stkutil.h"
#define SIM_CACHE_MODE 0600
#define SIM_CACHE_PATH STORAGEDIR "/%s-%i/%04x"
@@ -1883,42 +1882,6 @@ static void sim_set_ready(struct ofono_sim *sim)
}
}
-static void sim_cb_download_cb(const struct ofono_error *error,
- const unsigned char *data, int len, void *user)
-{
- if (error->type != OFONO_ERROR_TYPE_NO_ERROR) {
- ofono_error("CellBroadcast download to UICC failed");
- return;
- }
-
- DBG("CellBroadcast download to UICC reported no error");
-}
-
-void __ofono_cbs_sim_download(struct ofono_sim *sim,
- const guint8 *pdu, int pdu_len)
-{
- guint8 tlv[pdu_len + 8];
-
- if (sim->state != OFONO_SIM_STATE_READY)
- return;
-
- if (sim->driver->envelope == NULL)
- return;
-
- tlv[0] = STK_ENVELOPE_TYPE_CBS_PP_DOWNLOAD;
- tlv[1] = 6 + pdu_len;
- tlv[2] = 0x80 | STK_DATA_OBJECT_TYPE_DEVICE_IDENTITIES;
- tlv[3] = 0x02; /* Device Identities length */
- tlv[4] = STK_DEVICE_IDENTITY_TYPE_NETWORK;
- tlv[5] = STK_DEVICE_IDENTITY_TYPE_UICC;
- tlv[6] = 0x80 | STK_DATA_OBJECT_TYPE_CBS_PAGE;
- tlv[7] = pdu_len;
-
- memcpy(tlv + 8, pdu, pdu_len);
-
- sim->driver->envelope(sim, pdu_len + 8, tlv, sim_cb_download_cb, sim);
-}
-
int ofono_sim_driver_register(const struct ofono_sim_driver *d)
{
DBG("driver: %p, name: %s", d, d->name);
diff --git a/src/stk.c b/src/stk.c
new file mode 100644
index 0000000..5f76a86
--- /dev/null
+++ b/src/stk.c
@@ -0,0 +1,201 @@
+/*
+ *
+ * oFono - Open Source Telephony
+ *
+ * Copyright (C) 2008-2010 Intel 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
+
+#define _GNU_SOURCE
+#include <string.h>
+#include <stdio.h>
+
+#include <glib.h>
+#include <gdbus.h>
+#include <errno.h>
+
+#include "ofono.h"
+
+#include "smsutil.h"
+#include "stkutil.h"
+
+static GSList *g_drivers = NULL;
+
+struct ofono_stk {
+ const struct ofono_stk_driver *driver;
+ void *driver_data;
+ struct ofono_atom *atom;
+};
+
+static void stk_cb_download_cb(const struct ofono_error *error,
+ const unsigned char *data, int len, void *user)
+{
+ if (error->type != OFONO_ERROR_TYPE_NO_ERROR) {
+ ofono_error("CellBroadcast download to UICC failed");
+ return;
+ }
+
+ DBG("CellBroadcast download to UICC reported no error");
+}
+
+void __ofono_cbs_sim_download(struct ofono_stk *stk,
+ const guint8 *pdu, int pdu_len)
+{
+ guint8 tlv[pdu_len + 8];
+
+ if (stk == NULL)
+ return;
+
+ if (stk->driver->envelope == NULL)
+ return;
+
+ tlv[0] = STK_ENVELOPE_TYPE_CBS_PP_DOWNLOAD;
+ tlv[1] = 6 + pdu_len;
+ tlv[2] = 0x80 | STK_DATA_OBJECT_TYPE_DEVICE_IDENTITIES;
+ tlv[3] = 0x02; /* Device Identities length */
+ tlv[4] = STK_DEVICE_IDENTITY_TYPE_NETWORK;
+ tlv[5] = STK_DEVICE_IDENTITY_TYPE_UICC;
+ tlv[6] = 0x80 | STK_DATA_OBJECT_TYPE_CBS_PAGE;
+ tlv[7] = pdu_len;
+
+ memcpy(tlv + 8, pdu, pdu_len);
+
+ stk->driver->envelope(stk, pdu_len + 8, tlv, stk_cb_download_cb, stk);
+}
+
+void ofono_stk_proactive_command_notify(struct ofono_stk *stk,
+ int length, const guint8 *pdu)
+{
+ struct stk_command *cmd;
+ char *buf;
+ int i;
+
+ buf = g_try_new(char, length * 2 + 1);
+ for (i = 0; i < length; i ++)
+ sprintf(buf + i * 2, "%02hhx", pdu[i]);
+ DBG("Proactive command PDU: %s", buf);
+
+ cmd = stk_command_new_from_pdu(pdu, length);
+ if (!cmd) {
+ ofono_error("Can't parse proactive command: %s", buf);
+ g_free(buf);
+
+ /* TODO: return TERMINAL RESPONSE with permanent error */
+ return;
+ }
+
+ /* TODO: execute */
+
+ g_free(buf);
+ stk_command_free(cmd);
+}
+
+int ofono_stk_driver_register(const struct ofono_stk_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_stk_driver_unregister(const struct ofono_stk_driver *d)
+{
+ DBG("driver: %p, name: %s", d, d->name);
+
+ g_drivers = g_slist_remove(g_drivers, (void *)d);
+}
+
+static void stk_unregister(struct ofono_atom *atom)
+{
+}
+
+static void stk_remove(struct ofono_atom *atom)
+{
+ struct ofono_stk *stk = __ofono_atom_get_data(atom);
+
+ DBG("atom: %p", atom);
+
+ if (stk == NULL)
+ return;
+
+ if (stk->driver && stk->driver->remove)
+ stk->driver->remove(stk);
+
+ g_free(stk);
+}
+
+struct ofono_stk *ofono_stk_create(struct ofono_modem *modem,
+ unsigned int vendor,
+ const char *driver,
+ void *data)
+{
+ struct ofono_stk *stk;
+ GSList *l;
+
+ if (driver == NULL)
+ return NULL;
+
+ stk = g_try_new0(struct ofono_stk, 1);
+
+ if (stk == NULL)
+ return NULL;
+
+ stk->atom = __ofono_modem_add_atom(modem, OFONO_ATOM_TYPE_STK,
+ stk_remove, stk);
+
+ for (l = g_drivers; l; l = l->next) {
+ const struct ofono_stk_driver *drv = l->data;
+
+ if (g_strcmp0(drv->name, driver))
+ continue;
+
+ if (drv->probe(stk, vendor, data) < 0)
+ continue;
+
+ stk->driver = drv;
+ break;
+ }
+
+ return stk;
+}
+
+void ofono_stk_register(struct ofono_stk *stk)
+{
+ __ofono_atom_register(stk->atom, stk_unregister);
+}
+
+void ofono_stk_remove(struct ofono_stk *stk)
+{
+ __ofono_atom_free(stk->atom);
+}
+
+void ofono_stk_set_data(struct ofono_stk *stk, void *data)
+{
+ stk->driver_data = data;
+}
+
+void *ofono_stk_get_data(struct ofono_stk *stk)
+{
+ return stk->driver_data;
+}
--
1.6.1
10 years, 9 months
[PATCH 2/8] Functions to notify core of SIM insertion/removal.
by Andrzej Zaborowski
Make every plugin generate a sim inserted event on start. For devices
with removable card, the event should be emitted after the
plugin detects such event.
---
include/sim.h | 3 +-
plugins/atgen.c | 6 +++-
plugins/calypso.c | 6 +++-
plugins/em770.c | 6 +++-
plugins/g1.c | 6 +++-
plugins/hso.c | 6 +++-
plugins/huawei.c | 6 +++-
plugins/mbm.c | 6 +++-
plugins/palmpre.c | 6 +++-
plugins/phonesim.c | 6 +++-
plugins/ste.c | 6 +++-
src/sim.c | 78 ++++++++++++++++++++++++++++++++++++---------------
12 files changed, 107 insertions(+), 34 deletions(-)
diff --git a/include/sim.h b/include/sim.h
index 23b1905..2218564 100644
--- a/include/sim.h
+++ b/include/sim.h
@@ -187,7 +187,8 @@ unsigned int ofono_sim_add_state_watch(struct ofono_sim *sim,
void ofono_sim_remove_state_watch(struct ofono_sim *sim, unsigned int id);
enum ofono_sim_state ofono_sim_get_state(struct ofono_sim *sim);
-void ofono_sim_set_ready(struct ofono_sim *sim);
+
+void ofono_sim_inserted_notify(struct ofono_sim *sim, ofono_bool_t inserted);
/* This will queue an operation to read all available records with id from the
* SIM. Callback cb will be called every time a record has been read, or once
diff --git a/plugins/atgen.c b/plugins/atgen.c
index 7e760bc..ed963c2 100644
--- a/plugins/atgen.c
+++ b/plugins/atgen.c
@@ -156,12 +156,16 @@ static int atgen_disable(struct ofono_modem *modem)
static void atgen_pre_sim(struct ofono_modem *modem)
{
GAtChat *chat = ofono_modem_get_data(modem);
+ struct ofono_sim *sim;
DBG("%p", modem);
ofono_devinfo_create(modem, 0, "atmodem", chat);
- ofono_sim_create(modem, 0, "atmodem", chat);
+ sim = ofono_sim_create(modem, 0, "atmodem", chat);
ofono_voicecall_create(modem, 0, "atmodem", chat);
+
+ if (sim)
+ ofono_sim_inserted_notify(sim, TRUE);
}
static void atgen_post_sim(struct ofono_modem *modem)
diff --git a/plugins/calypso.c b/plugins/calypso.c
index 5b28176..9d6280c 100644
--- a/plugins/calypso.c
+++ b/plugins/calypso.c
@@ -431,12 +431,16 @@ static int calypso_disable(struct ofono_modem *modem)
static void calypso_pre_sim(struct ofono_modem *modem)
{
struct calypso_data *data = ofono_modem_get_data(modem);
+ struct ofono_sim *sim;
DBG("");
ofono_devinfo_create(modem, 0, "atmodem", data->dlcs[AUX_DLC]);
- ofono_sim_create(modem, 0, "atmodem", data->dlcs[AUX_DLC]);
+ sim = ofono_sim_create(modem, 0, "atmodem", data->dlcs[AUX_DLC]);
ofono_voicecall_create(modem, 0, "calypsomodem", data->dlcs[VOICE_DLC]);
+
+ if (sim)
+ ofono_sim_inserted_notify(sim, TRUE);
}
static void calypso_post_sim(struct ofono_modem *modem)
diff --git a/plugins/em770.c b/plugins/em770.c
index a5d87f7..138c67a 100644
--- a/plugins/em770.c
+++ b/plugins/em770.c
@@ -172,12 +172,16 @@ static int em770_disable(struct ofono_modem *modem)
static void em770_pre_sim(struct ofono_modem *modem)
{
struct em770_data *data = ofono_modem_get_data(modem);
+ struct ofono_sim *sim;
DBG("%p", modem);
ofono_devinfo_create(modem, 0, "atmodem", data->chat);
- ofono_sim_create(modem, 0, "atmodem", data->chat);
+ sim = ofono_sim_create(modem, 0, "atmodem", data->chat);
ofono_voicecall_create(modem, 0, "atmodem", data->chat);
+
+ if (sim)
+ ofono_sim_inserted_notify(sim, TRUE);
}
static void em770_post_sim(struct ofono_modem *modem)
diff --git a/plugins/g1.c b/plugins/g1.c
index 81edfab..fa96eb1 100644
--- a/plugins/g1.c
+++ b/plugins/g1.c
@@ -156,12 +156,16 @@ static int g1_disable(struct ofono_modem *modem)
static void g1_pre_sim(struct ofono_modem *modem)
{
GAtChat *chat = ofono_modem_get_data(modem);
+ struct ofono_sim *sim;
DBG("");
ofono_devinfo_create(modem, 0, "atmodem", chat);
- ofono_sim_create(modem, 0, "atmodem", chat);
+ sim = ofono_sim_create(modem, 0, "atmodem", chat);
ofono_voicecall_create(modem, 0, "atmodem", chat);
+
+ if (sim)
+ ofono_sim_inserted_notify(sim, TRUE);
}
static void g1_post_sim(struct ofono_modem *modem)
diff --git a/plugins/hso.c b/plugins/hso.c
index e682064..27b69dc 100644
--- a/plugins/hso.c
+++ b/plugins/hso.c
@@ -198,11 +198,15 @@ static int hso_disable(struct ofono_modem *modem)
static void hso_pre_sim(struct ofono_modem *modem)
{
struct hso_data *data = ofono_modem_get_data(modem);
+ struct ofono_sim *sim;
DBG("%p", modem);
ofono_devinfo_create(modem, 0, "atmodem", data->control);
- ofono_sim_create(modem, 0, "atmodem", data->control);
+ sim = ofono_sim_create(modem, 0, "atmodem", data->control);
+
+ if (sim)
+ ofono_sim_inserted_notify(sim, TRUE);
}
static void hso_post_sim(struct ofono_modem *modem)
diff --git a/plugins/huawei.c b/plugins/huawei.c
index 41ad636..90fdcf0 100644
--- a/plugins/huawei.c
+++ b/plugins/huawei.c
@@ -163,12 +163,16 @@ static int huawei_disable(struct ofono_modem *modem)
static void huawei_pre_sim(struct ofono_modem *modem)
{
struct huawei_data *data = ofono_modem_get_data(modem);
+ struct ofono_sim *sim;
DBG("%p", modem);
ofono_devinfo_create(modem, 0, "atmodem", data->chat);
- ofono_sim_create(modem, 0, "atmodem", data->chat);
+ sim = ofono_sim_create(modem, 0, "atmodem", data->chat);
ofono_voicecall_create(modem, 0, "atmodem", data->chat);
+
+ if (sim)
+ ofono_sim_inserted_notify(sim, TRUE);
}
static void huawei_post_sim(struct ofono_modem *modem)
diff --git a/plugins/mbm.c b/plugins/mbm.c
index 439d3b9..79d180b 100644
--- a/plugins/mbm.c
+++ b/plugins/mbm.c
@@ -285,12 +285,16 @@ static int mbm_disable(struct ofono_modem *modem)
static void mbm_pre_sim(struct ofono_modem *modem)
{
struct mbm_data *data = ofono_modem_get_data(modem);
+ struct ofono_sim *sim;
DBG("%p", modem);
ofono_devinfo_create(modem, 0, "atmodem", data->modem_port);
- ofono_sim_create(modem, 0, "atmodem", data->modem_port);
+ sim = ofono_sim_create(modem, 0, "atmodem", data->modem_port);
ofono_voicecall_create(modem, 0, "atmodem", data->modem_port);
+
+ if (sim)
+ ofono_sim_inserted_notify(sim, TRUE);
}
static void mbm_post_sim(struct ofono_modem *modem)
diff --git a/plugins/palmpre.c b/plugins/palmpre.c
index 049b9bd..7d2aeb4 100644
--- a/plugins/palmpre.c
+++ b/plugins/palmpre.c
@@ -170,13 +170,17 @@ static int palmpre_disable(struct ofono_modem *modem)
static void palmpre_pre_sim(struct ofono_modem *modem)
{
struct palmpre_data *data = ofono_modem_get_data(modem);
+ struct ofono_sim *sim;
DBG("%p", modem);
ofono_devinfo_create(modem, 0, "atmodem", data->chat);
- ofono_sim_create(modem, OFONO_VENDOR_QUALCOMM_MSM, "atmodem",
+ sim = ofono_sim_create(modem, OFONO_VENDOR_QUALCOMM_MSM, "atmodem",
data->chat);
ofono_voicecall_create(modem, 0, "atmodem", data->chat);
+
+ if (sim)
+ ofono_sim_inserted_notify(sim, TRUE);
}
static void palmpre_post_sim(struct ofono_modem *modem)
diff --git a/plugins/phonesim.c b/plugins/phonesim.c
index ca12cf2..4c3b3ce 100644
--- a/plugins/phonesim.c
+++ b/plugins/phonesim.c
@@ -277,16 +277,20 @@ static int phonesim_disable(struct ofono_modem *modem)
static void phonesim_pre_sim(struct ofono_modem *modem)
{
struct phonesim_data *data = ofono_modem_get_data(modem);
+ struct ofono_sim *sim;
DBG("%p", modem);
ofono_devinfo_create(modem, 0, "atmodem", data->chat);
- ofono_sim_create(modem, 0, "atmodem", data->chat);
+ sim = ofono_sim_create(modem, 0, "atmodem", data->chat);
if (data->calypso)
ofono_voicecall_create(modem, 0, "calypsomodem", data->chat);
else
ofono_voicecall_create(modem, 0, "atmodem", data->chat);
+
+ if (sim)
+ ofono_sim_inserted_notify(sim, TRUE);
}
static void phonesim_post_sim(struct ofono_modem *modem)
diff --git a/plugins/ste.c b/plugins/ste.c
index 66065c1..7e2df96 100644
--- a/plugins/ste.c
+++ b/plugins/ste.c
@@ -208,12 +208,16 @@ static int ste_disable(struct ofono_modem *modem)
static void ste_pre_sim(struct ofono_modem *modem)
{
struct ste_data *data = ofono_modem_get_data(modem);
+ struct ofono_sim *sim;
DBG("%p", modem);
ofono_devinfo_create(modem, 0, "atmodem", data->chat);
- ofono_sim_create(modem, 0, "atmodem", data->chat);
+ sim = ofono_sim_create(modem, 0, "atmodem", data->chat);
ofono_voicecall_create(modem, 0, "stemodem", data->chat);
+
+ if (sim)
+ ofono_sim_inserted_notify(sim, TRUE);
}
static void ste_post_sim(struct ofono_modem *modem)
diff --git a/src/sim.c b/src/sim.c
index 58de191..5559be4 100644
--- a/src/sim.c
+++ b/src/sim.c
@@ -55,6 +55,7 @@ static gboolean sim_op_next(gpointer user_data);
static gboolean sim_op_retrieve_next(gpointer user);
static void sim_own_numbers_update(struct ofono_sim *sim);
static void sim_pin_check(struct ofono_sim *sim);
+static void sim_set_ready(struct ofono_sim *sim);
struct sim_file_op {
int id;
@@ -1003,7 +1004,7 @@ static void sim_cphs_information_read_cb(int ok, int length, int record,
memcpy(sim->cphs_service_table, data + 1, 2);
ready:
- ofono_sim_set_ready(sim);
+ sim_set_ready(sim);
}
static void sim_imsi_cb(const struct ofono_error *error, const char *imsi,
@@ -1778,6 +1779,53 @@ const unsigned char *ofono_sim_get_cphs_service_table(struct ofono_sim *sim)
return sim->cphs_service_table;
}
+void ofono_sim_inserted_notify(struct ofono_sim *sim, ofono_bool_t inserted)
+{
+ ofono_sim_state_event_notify_cb_t notify;
+ GSList *l;
+
+ if (inserted && sim->state == OFONO_SIM_STATE_NOT_PRESENT)
+ sim->state = OFONO_SIM_STATE_INSERTED;
+ else if (!inserted && sim->state != OFONO_SIM_STATE_NOT_PRESENT)
+ sim->state = OFONO_SIM_STATE_NOT_PRESENT;
+ else
+ return;
+
+ if (!__ofono_atom_get_registered(sim->atom))
+ return;
+
+ for (l = sim->state_watches->items; l; l = l->next) {
+ struct ofono_watchlist_item *item = l->data;
+ notify = item->notify;
+
+ notify(item->notify_data, sim->state);
+ }
+
+ if (!inserted)
+ return;
+
+ /* Perform SIM initialization according to 3GPP 31.102 Section 5.1.1.2
+ * The assumption here is that if sim manager is being initialized,
+ * then sim commands are implemented, and the sim manager is then
+ * responsible for checking the PIN, reading the IMSI and signaling
+ * SIM ready condition.
+ *
+ * The procedure according to 31.102 is roughly:
+ * Read EFecc
+ * Read EFli and EFpl
+ * SIM Pin check
+ * Request SIM phase (only in 51.011)
+ * Read EFust
+ * Read EFest
+ * Read IMSI
+ *
+ * At this point we signal the SIM ready condition and allow
+ * arbitrary files to be written or read, assuming their presence
+ * in the EFust
+ */
+ sim_determine_phase(sim);
+}
+
unsigned int ofono_sim_add_state_watch(struct ofono_sim *sim,
ofono_sim_state_event_notify_cb_t notify,
void *data, ofono_destroy_func destroy)
@@ -1814,7 +1862,7 @@ enum ofono_sim_state ofono_sim_get_state(struct ofono_sim *sim)
return sim->state;
}
-void ofono_sim_set_ready(struct ofono_sim *sim)
+static void sim_set_ready(struct ofono_sim *sim)
{
GSList *l;
ofono_sim_state_event_notify_cb_t notify;
@@ -2000,6 +2048,7 @@ void ofono_sim_register(struct ofono_sim *sim)
DBusConnection *conn = ofono_dbus_get_connection();
struct ofono_modem *modem = __ofono_atom_get_modem(sim->atom);
const char *path = __ofono_atom_get_path(sim->atom);
+ ofono_bool_t inserted;
if (!g_dbus_register_interface(conn, path,
OFONO_SIM_MANAGER_INTERFACE,
@@ -2013,32 +2062,15 @@ void ofono_sim_register(struct ofono_sim *sim)
ofono_modem_add_interface(modem, OFONO_SIM_MANAGER_INTERFACE);
sim->state_watches = __ofono_watchlist_new(g_free);
- sim->state = OFONO_SIM_STATE_INSERTED;
__ofono_atom_register(sim->atom, sim_unregister);
ofono_sim_add_state_watch(sim, sim_ready, sim, NULL);
- /* Perform SIM initialization according to 3GPP 31.102 Section 5.1.1.2
- * The assumption here is that if sim manager is being initialized,
- * then sim commands are implemented, and the sim manager is then
- * responsible for checking the PIN, reading the IMSI and signaling
- * SIM ready condition.
- *
- * The procedure according to 31.102 is roughly:
- * Read EFecc
- * Read EFli and EFpl
- * SIM Pin check
- * Request SIM phase (only in 51.011)
- * Read EFust
- * Read EFest
- * Read IMSI
- *
- * At this point we signal the SIM ready condition and allow
- * arbitrary files to be written or read, assuming their presence
- * in the EFust
- */
- sim_determine_phase(sim);
+ inserted = sim->state != OFONO_SIM_STATE_NOT_PRESENT;
+ sim->state = OFONO_SIM_STATE_NOT_PRESENT;
+
+ ofono_sim_inserted_notify(sim, inserted);
}
void ofono_sim_remove(struct ofono_sim *sim)
--
1.6.1
10 years, 9 months
[PATCH 1/8] Extend sim-ready watch with card insert/eject events.
by Andrzej Zaborowski
---
include/sim.h | 17 ++++++++++++-----
src/cbs.c | 2 +-
src/modem.c | 11 ++++++-----
src/sim.c | 49 +++++++++++++++++++++++++------------------------
4 files changed, 44 insertions(+), 35 deletions(-)
diff --git a/include/sim.h b/include/sim.h
index 6ff29f7..23b1905 100644
--- a/include/sim.h
+++ b/include/sim.h
@@ -71,6 +71,12 @@ enum ofono_sim_cphs_phase {
OFONO_SIM_CPHS_PHASE_2G,
};
+enum ofono_sim_state {
+ OFONO_SIM_STATE_NOT_PRESENT,
+ OFONO_SIM_STATE_INSERTED,
+ OFONO_SIM_STATE_READY,
+};
+
typedef void (*ofono_sim_file_info_cb_t)(const struct ofono_error *error,
int filelength,
enum ofono_sim_file_structure structure,
@@ -88,7 +94,8 @@ typedef void (*ofono_sim_write_cb_t)(const struct ofono_error *error,
typedef void (*ofono_sim_imsi_cb_t)(const struct ofono_error *error,
const char *imsi, void *data);
-typedef void (*ofono_sim_ready_notify_cb_t)(void *data);
+typedef void (*ofono_sim_state_event_notify_cb_t)(void *data,
+ enum ofono_sim_state new_state);
typedef void (*ofono_sim_file_read_cb_t)(int ok, int total_length, int record,
const unsigned char *data,
@@ -173,13 +180,13 @@ enum ofono_sim_phase ofono_sim_get_phase(struct ofono_sim *sim);
enum ofono_sim_cphs_phase ofono_sim_get_cphs_phase(struct ofono_sim *sim);
const unsigned char *ofono_sim_get_cphs_service_table(struct ofono_sim *sim);
-unsigned int ofono_sim_add_ready_watch(struct ofono_sim *sim,
- ofono_sim_ready_notify_cb_t cb,
+unsigned int ofono_sim_add_state_watch(struct ofono_sim *sim,
+ ofono_sim_state_event_notify_cb_t cb,
void *data, ofono_destroy_func destroy);
-void ofono_sim_remove_ready_watch(struct ofono_sim *sim, unsigned int id);
+void ofono_sim_remove_state_watch(struct ofono_sim *sim, unsigned int id);
-int ofono_sim_get_ready(struct ofono_sim *sim);
+enum ofono_sim_state ofono_sim_get_state(struct ofono_sim *sim);
void ofono_sim_set_ready(struct ofono_sim *sim);
/* This will queue an operation to read all available records with id from the
diff --git a/src/cbs.c b/src/cbs.c
index d04404e..2fa33c1 100644
--- a/src/cbs.c
+++ b/src/cbs.c
@@ -1046,7 +1046,7 @@ void ofono_cbs_register(struct ofono_cbs *cbs)
if (sim_atom) {
cbs->sim = __ofono_atom_get_data(sim_atom);
- if (ofono_sim_get_ready(cbs->sim) == TRUE)
+ if (ofono_sim_get_state(cbs->sim) == OFONO_SIM_STATE_READY)
cbs_got_imsi(cbs);
}
diff --git a/src/modem.c b/src/modem.c
index b935328..df74be3 100644
--- a/src/modem.c
+++ b/src/modem.c
@@ -1117,10 +1117,13 @@ static void emit_modems()
g_free(modems);
}
-static void modem_sim_ready(void *user)
+static void modem_sim_ready(void *user, enum ofono_sim_state new_state)
{
struct ofono_modem *modem = user;
+ if (new_state != OFONO_SIM_STATE_READY)
+ return;
+
if (modem->driver->post_sim)
modem->driver->post_sim(modem);
@@ -1138,12 +1141,10 @@ static void sim_watch(struct ofono_atom *atom,
}
modem->sim = __ofono_atom_get_data(atom);
- modem->sim_ready_watch = ofono_sim_add_ready_watch(modem->sim,
+ modem->sim_ready_watch = ofono_sim_add_state_watch(modem->sim,
modem_sim_ready,
modem, NULL);
-
- if (ofono_sim_get_ready(modem->sim))
- modem_sim_ready(modem);
+ modem_sim_ready(modem, ofono_sim_get_state(modem->sim));
}
int ofono_modem_register(struct ofono_modem *modem)
diff --git a/src/sim.c b/src/sim.c
index f64c7d4..58de191 100644
--- a/src/sim.c
+++ b/src/sim.c
@@ -77,7 +77,7 @@ struct ofono_sim {
GSList *new_numbers;
GSList *service_numbers;
gboolean sdn_ready;
- gboolean ready;
+ enum ofono_sim_state state;
enum ofono_sim_password_type pin_type;
gboolean locked_pins[OFONO_SIM_PASSWORD_INVALID];
char **language_prefs;
@@ -89,7 +89,7 @@ struct ofono_sim {
unsigned char efli_length;
enum ofono_sim_cphs_phase cphs_phase;
unsigned char cphs_service_table[2];
- struct ofono_watchlist *ready_watches;
+ struct ofono_watchlist *state_watches;
const struct ofono_sim_driver *driver;
void *driver_data;
struct ofono_atom *atom;
@@ -968,10 +968,13 @@ static void sim_own_numbers_update(struct ofono_sim *sim)
sim_msisdn_read_cb, sim);
}
-static void sim_ready(void *user)
+static void sim_ready(void *user, enum ofono_sim_state new_state)
{
struct ofono_sim *sim = user;
+ if (new_state != OFONO_SIM_STATE_READY)
+ return;
+
sim_own_numbers_update(sim);
ofono_sim_read(sim, SIM_EFAD_FILEID,
@@ -1775,8 +1778,8 @@ const unsigned char *ofono_sim_get_cphs_service_table(struct ofono_sim *sim)
return sim->cphs_service_table;
}
-unsigned int ofono_sim_add_ready_watch(struct ofono_sim *sim,
- ofono_sim_ready_notify_cb_t notify,
+unsigned int ofono_sim_add_state_watch(struct ofono_sim *sim,
+ ofono_sim_state_event_notify_cb_t notify,
void *data, ofono_destroy_func destroy)
{
struct ofono_watchlist_item *item;
@@ -1795,43 +1798,40 @@ unsigned int ofono_sim_add_ready_watch(struct ofono_sim *sim,
item->destroy = destroy;
item->notify_data = data;
- return __ofono_watchlist_add_item(sim->ready_watches, item);
+ return __ofono_watchlist_add_item(sim->state_watches, item);
}
-void ofono_sim_remove_ready_watch(struct ofono_sim *sim, unsigned int id)
+void ofono_sim_remove_state_watch(struct ofono_sim *sim, unsigned int id)
{
- __ofono_watchlist_remove_item(sim->ready_watches, id);
+ __ofono_watchlist_remove_item(sim->state_watches, id);
}
-int ofono_sim_get_ready(struct ofono_sim *sim)
+enum ofono_sim_state ofono_sim_get_state(struct ofono_sim *sim)
{
if (sim == NULL)
- return 0;
+ return OFONO_SIM_STATE_NOT_PRESENT;
- if (sim->ready == TRUE)
- return 1;
-
- return 0;
+ return sim->state;
}
void ofono_sim_set_ready(struct ofono_sim *sim)
{
GSList *l;
- ofono_sim_ready_notify_cb_t notify;
+ ofono_sim_state_event_notify_cb_t notify;
if (sim == NULL)
return;
- if (sim->ready == TRUE)
+ if (sim->state != OFONO_SIM_STATE_INSERTED)
return;
- sim->ready = TRUE;
+ sim->state = OFONO_SIM_STATE_READY;
- for (l = sim->ready_watches->items; l; l = l->next) {
+ for (l = sim->state_watches->items; l; l = l->next) {
struct ofono_watchlist_item *item = l->data;
notify = item->notify;
- notify(item->notify_data);
+ notify(item->notify_data, sim->state);
}
}
@@ -1851,7 +1851,7 @@ void __ofono_cbs_sim_download(struct ofono_sim *sim,
{
guint8 tlv[pdu_len + 8];
- if (sim->ready != TRUE)
+ if (sim->state != OFONO_SIM_STATE_READY)
return;
if (sim->driver->envelope == NULL)
@@ -1897,8 +1897,8 @@ static void sim_unregister(struct ofono_atom *atom)
const char *path = __ofono_atom_get_path(atom);
struct ofono_sim *sim = __ofono_atom_get_data(atom);
- __ofono_watchlist_free(sim->ready_watches);
- sim->ready_watches = NULL;
+ __ofono_watchlist_free(sim->state_watches);
+ sim->state_watches = NULL;
g_dbus_unregister_interface(conn, path, OFONO_SIM_MANAGER_INTERFACE);
ofono_modem_remove_interface(modem, OFONO_SIM_MANAGER_INTERFACE);
@@ -2012,11 +2012,12 @@ void ofono_sim_register(struct ofono_sim *sim)
}
ofono_modem_add_interface(modem, OFONO_SIM_MANAGER_INTERFACE);
- sim->ready_watches = __ofono_watchlist_new(g_free);
+ sim->state_watches = __ofono_watchlist_new(g_free);
+ sim->state = OFONO_SIM_STATE_INSERTED;
__ofono_atom_register(sim->atom, sim_unregister);
- ofono_sim_add_ready_watch(sim, sim_ready, sim, NULL);
+ ofono_sim_add_state_watch(sim, sim_ready, sim, NULL);
/* Perform SIM initialization according to 3GPP 31.102 Section 5.1.1.2
* The assumption here is that if sim manager is being initialized,
--
1.6.1
10 years, 9 months