Merge branch 'jb33265' into 'master'

Add GetPresentSims to ModemManager interface

Only a simple boolean (presence/absence) is reported. `PresentSimsChanged` signal is emitted when SIM is inserted or removed (if RIL supports it).

See merge request !8
This commit is contained in:
Slava Monich
2015-11-12 08:11:38 +00:00
4 changed files with 461 additions and 276 deletions

View File

@@ -24,7 +24,6 @@
enum ril_modem_power_state { enum ril_modem_power_state {
POWERED_OFF, POWERED_OFF,
POWERING_ON,
POWERED_ON, POWERED_ON,
POWERING_OFF POWERING_OFF
}; };
@@ -36,13 +35,6 @@ enum ril_modem_online_state {
GOING_OFFLINE GOING_OFFLINE
}; };
enum ril_modem_events {
MODEM_EVENT_CONNECTED,
MODEM_EVENT_RADIO_STATE_CHANGED,
MODEM_EVENT_ERROR,
MODEM_EVENT_COUNT
};
struct ril_modem_online_request { struct ril_modem_online_request {
ofono_modem_online_cb_t cb; ofono_modem_online_cb_t cb;
void *data; void *data;
@@ -59,10 +51,7 @@ struct ril_modem {
enum ril_radio_state radio_state; enum ril_radio_state radio_state;
enum ril_modem_power_state power_state; enum ril_modem_power_state power_state;
gulong event_id[MODEM_EVENT_COUNT]; gulong radio_state_event_id;
ril_modem_cb_t error_cb;
void *error_cb_data;
ril_modem_cb_t removed_cb; ril_modem_cb_t removed_cb;
void *removed_cb_data; void *removed_cb_data;
@@ -122,13 +111,6 @@ void ril_modem_delete(struct ril_modem *md)
} }
} }
void ril_modem_set_error_cb(struct ril_modem *md, ril_modem_cb_t cb,
void *data)
{
md->error_cb = cb;
md->error_cb_data = data;
}
void ril_modem_set_removed_cb(struct ril_modem *md, ril_modem_cb_t cb, void ril_modem_set_removed_cb(struct ril_modem *md, ril_modem_cb_t cb,
void *data) void *data)
{ {
@@ -149,18 +131,6 @@ void ril_modem_allow_data(struct ril_modem *md)
} }
} }
static void ril_modem_signal_error(struct ril_modem *md)
{
if (md->modem && md->error_cb) {
ril_modem_cb_t cb = md->error_cb;
void *data = md->error_cb_data;
md->error_cb = NULL;
md->error_cb_data = NULL;
cb(md, data);
}
}
static void ril_modem_online_request_ok(GRilIoChannel* io, static void ril_modem_online_request_ok(GRilIoChannel* io,
struct ril_modem_online_request *req) struct ril_modem_online_request *req)
{ {
@@ -272,21 +242,6 @@ static guint ril_modem_request_power(struct ril_modem *md, gboolean on,
return id; return id;
} }
static void ril_modem_connected(struct ril_modem *md)
{
ofono_debug("RIL version %u", md->io->ril_version);
ril_modem_request_power(md, FALSE, NULL);
if (md->power_state == POWERING_ON) {
md->power_state = POWERED_ON;
ofono_modem_set_powered(md->modem, TRUE);
}
}
static void ril_modem_connected_cb(GRilIoChannel *io, void *user_data)
{
ril_modem_connected((struct ril_modem *)user_data);
}
static void ril_modem_pre_sim(struct ofono_modem *modem) static void ril_modem_pre_sim(struct ofono_modem *modem)
{ {
struct ril_modem *md = ril_modem_from_ofono(modem); struct ril_modem *md = ril_modem_from_ofono(modem);
@@ -346,7 +301,6 @@ static void ril_modem_set_online(struct ofono_modem *modem, ofono_bool_t online,
DBG("%s going %sline", ofono_modem_get_path(modem), DBG("%s going %sline", ofono_modem_get_path(modem),
online ? "on" : "off"); online ? "on" : "off");
GASSERT(md->power_state == POWERED_ON);
if (online) { if (online) {
req = &md->set_online; req = &md->set_online;
GASSERT(!req->id); GASSERT(!req->id);
@@ -373,14 +327,8 @@ static int ril_modem_enable(struct ofono_modem *modem)
struct ril_modem *md = ril_modem_from_ofono(modem); struct ril_modem *md = ril_modem_from_ofono(modem);
DBG("%s", ofono_modem_get_path(modem)); DBG("%s", ofono_modem_get_path(modem));
if (md->io->connected) { md->power_state = POWERED_ON;
md->power_state = POWERED_ON; return 0;
return 0;
} else {
DBG("Waiting for RIL_UNSOL_RIL_CONNECTED");
md->power_state = POWERING_ON;
return -EINPROGRESS;
}
} }
static int ril_modem_disable(struct ofono_modem *modem) static int ril_modem_disable(struct ofono_modem *modem)
@@ -397,17 +345,6 @@ static int ril_modem_disable(struct ofono_modem *modem)
} }
} }
static void ril_modem_error(GRilIoChannel *io, const GError *error,
void *user_data)
{
struct ril_modem *md = user_data;
ofono_error("%s", error->message);
grilio_channel_remove_handler(io, md->event_id[MODEM_EVENT_ERROR]);
md->event_id[MODEM_EVENT_ERROR] = 0;
ril_modem_signal_error(md);
}
static int ril_modem_probe(struct ofono_modem *modem) static int ril_modem_probe(struct ofono_modem *modem)
{ {
DBG("%s", ofono_modem_get_path(modem)); DBG("%s", ofono_modem_get_path(modem));
@@ -417,7 +354,6 @@ static int ril_modem_probe(struct ofono_modem *modem)
static void ril_modem_remove(struct ofono_modem *modem) static void ril_modem_remove(struct ofono_modem *modem)
{ {
struct ril_modem *md = ril_modem_from_ofono(modem); struct ril_modem *md = ril_modem_from_ofono(modem);
int i;
DBG("%s", ofono_modem_get_path(modem)); DBG("%s", ofono_modem_get_path(modem));
GASSERT(md->modem); GASSERT(md->modem);
@@ -440,10 +376,7 @@ static void ril_modem_remove(struct ofono_modem *modem)
ofono_modem_set_data(modem, NULL); ofono_modem_set_data(modem, NULL);
for (i=0; i<G_N_ELEMENTS(md->event_id); i++) { grilio_channel_remove_handler(md->io, md->radio_state_event_id);
grilio_channel_remove_handler(md->io, md->event_id[i]);
}
grilio_channel_unref(md->io); grilio_channel_unref(md->io);
grilio_queue_cancel_all(md->q, FALSE); grilio_queue_cancel_all(md->q, FALSE);
grilio_queue_unref(md->q); grilio_queue_unref(md->q);
@@ -503,23 +436,14 @@ struct ril_modem *ril_modem_create(GRilIoChannel *io, const char *dev,
ofono_modem_set_data(modem, md); ofono_modem_set_data(modem, md);
err = ofono_modem_register(modem); err = ofono_modem_register(modem);
if (!err) { if (!err) {
md->event_id[MODEM_EVENT_ERROR] = md->radio_state_event_id =
grilio_channel_add_error_handler(io,
ril_modem_error, md);
md->event_id[MODEM_EVENT_RADIO_STATE_CHANGED] =
grilio_channel_add_unsol_event_handler(io, grilio_channel_add_unsol_event_handler(io,
ril_modem_radio_state_changed, ril_modem_radio_state_changed,
RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED, RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED,
md); md);
if (io->connected) {
ril_modem_connected(md); GASSERT(io->connected);
} else { ril_modem_request_power(md, FALSE, NULL);
DBG("[%u] waiting for RIL_UNSOL_RIL_CONNECTED",
config->slot);
md->event_id[MODEM_EVENT_CONNECTED] =
grilio_channel_add_connected_handler(
io, ril_modem_connected_cb, md);
}
/* /*
* ofono_modem_reset sets Powered to TRUE without * ofono_modem_reset sets Powered to TRUE without
@@ -527,6 +451,7 @@ struct ril_modem *ril_modem_create(GRilIoChannel *io, const char *dev,
*/ */
ofono_modem_set_powered(md->modem, FALSE); ofono_modem_set_powered(md->modem, FALSE);
ofono_modem_set_powered(md->modem, TRUE); ofono_modem_set_powered(md->modem, TRUE);
md->power_state = POWERED_ON;
return md; return md;
} else { } else {
ofono_error("Error %d registering %s", ofono_error("Error %d registering %s",

View File

@@ -35,7 +35,7 @@
#define RADIO_UID 1001 #define RADIO_UID 1001
#define RIL_SUB_SIZE 4 #define RIL_SUB_SIZE 4
#define RILMODEM_CONF_FILE "/etc/ofono/ril_subscription.conf" #define RILMODEM_CONF_FILE CONFIGDIR "/ril_subscription.conf"
#define RILMODEM_DEFAULT_SOCK "/dev/socket/rild" #define RILMODEM_DEFAULT_SOCK "/dev/socket/rild"
#define RILMODEM_DEFAULT_SOCK2 "/dev/socket/rild2" #define RILMODEM_DEFAULT_SOCK2 "/dev/socket/rild2"
#define RILMODEM_DEFAULT_SUB "SUB1" #define RILMODEM_DEFAULT_SUB "SUB1"
@@ -59,6 +59,14 @@
#define RIL_STORE_DEFAULT_DATA_SIM "DefaultDataSim" #define RIL_STORE_DEFAULT_DATA_SIM "DefaultDataSim"
#define RIL_STORE_SLOTS_SEP "," #define RIL_STORE_SLOTS_SEP ","
enum ril_plugin_io_events {
IO_EVENT_CONNECTED,
IO_EVENT_ERROR,
IO_EVENT_EOF,
IO_EVENT_SIM_STATUS,
IO_EVENT_COUNT
};
struct ril_plugin_priv { struct ril_plugin_priv {
struct ril_plugin pub; struct ril_plugin pub;
struct ril_plugin_dbus *dbus; struct ril_plugin_dbus *dbus;
@@ -72,23 +80,24 @@ struct ril_plugin_priv {
}; };
struct ril_slot { struct ril_slot {
struct ril_slot_info pub;
char *path; char *path;
char *name; char *name;
char *sockpath; char *sockpath;
char *sub; char *sub;
gint timeout; /* RIL timeout, in seconds */ gint timeout; /* RIL timeout, in seconds */
int index;
struct ril_modem_config config; struct ril_modem_config config;
struct ril_plugin_priv *plugin; struct ril_plugin_priv *plugin;
struct ril_sim_dbus *sim_dbus; struct ril_sim_dbus *sim_dbus;
struct ril_modem *modem; struct ril_modem *modem;
struct ril_mce *mce; struct ril_mce *mce;
struct ofono_sim *sim; struct ofono_sim *sim;
GRilIoChannel *io; GRilIoChannel *io;
gulong io_event_id[IO_EVENT_COUNT];
gulong sim_status_req_id;
guint trace_id; guint trace_id;
guint dump_id; guint dump_id;
guint error_id;
guint eof_id;
guint retry_id; guint retry_id;
guint sim_watch_id; guint sim_watch_id;
guint sim_state_watch_id; guint sim_state_watch_id;
@@ -97,7 +106,7 @@ struct ril_slot {
static void ril_debug_trace_notify(struct ofono_debug_desc *desc); static void ril_debug_trace_notify(struct ofono_debug_desc *desc);
static void ril_debug_dump_notify(struct ofono_debug_desc *desc); static void ril_debug_dump_notify(struct ofono_debug_desc *desc);
static void ril_plugin_create_modem(struct ril_slot *slot); static void ril_plugin_retry_init_io(struct ril_slot *slot);
GLOG_MODULE_DEFINE("rilmodem"); GLOG_MODULE_DEFINE("rilmodem");
@@ -129,13 +138,13 @@ static void ril_plugin_foreach_slot(struct ril_plugin_priv *plugin,
g_slist_foreach(plugin->slots, ril_plugin_foreach_slot_proc, fn); g_slist_foreach(plugin->slots, ril_plugin_foreach_slot_proc, fn);
} }
static gboolean ril_plugin_retry(gpointer data) static void ril_plugin_remove_slot_handler(struct ril_slot *slot, int id)
{ {
struct ril_slot *slot = data; GASSERT(id >= 0 && id<IO_EVENT_COUNT);
if (slot->io_event_id[id]) {
slot->retry_id = 0; grilio_channel_remove_handler(slot->io, slot->io_event_id[id]);
ril_plugin_create_modem(slot); slot->io_event_id[id] = 0;
return FALSE; }
} }
static void ril_plugin_shutdown_slot(struct ril_slot *slot, gboolean kill_io) static void ril_plugin_shutdown_slot(struct ril_slot *slot, gboolean kill_io)
@@ -172,16 +181,26 @@ static void ril_plugin_shutdown_slot(struct ril_slot *slot, gboolean kill_io)
slot->mce = NULL; slot->mce = NULL;
} }
if (slot->retry_id) {
g_source_remove(slot->retry_id);
slot->retry_id = 0;
}
if (slot->io) { if (slot->io) {
int i;
grilio_channel_remove_logger(slot->io, slot->trace_id); grilio_channel_remove_logger(slot->io, slot->trace_id);
grilio_channel_remove_logger(slot->io, slot->dump_id); grilio_channel_remove_logger(slot->io, slot->dump_id);
slot->trace_id = 0; slot->trace_id = 0;
slot->dump_id = 0; slot->dump_id = 0;
grilio_channel_remove_handler(slot->io, slot->error_id); grilio_channel_cancel_request(slot->io,
grilio_channel_remove_handler(slot->io, slot->eof_id); slot->sim_status_req_id, FALSE);
slot->error_id = 0; slot->sim_status_req_id = 0;
slot->eof_id = 0;
for (i=0; i<IO_EVENT_COUNT; i++) {
ril_plugin_remove_slot_handler(slot, i);
}
grilio_channel_shutdown(slot->io, FALSE); grilio_channel_shutdown(slot->io, FALSE);
grilio_channel_unref(slot->io); grilio_channel_unref(slot->io);
@@ -190,7 +209,7 @@ static void ril_plugin_shutdown_slot(struct ril_slot *slot, gboolean kill_io)
} }
} }
static void ril_pligin_set_config_string(struct ril_plugin_priv *plugin, static void ril_plugin_set_config_string(struct ril_plugin_priv *plugin,
const char *key, const char *value, gboolean sync) const char *key, const char *value, gboolean sync)
{ {
if (value) { if (value) {
@@ -317,6 +336,55 @@ static void ril_plugin_check_sim_state(struct ril_slot *slot)
} }
} }
static void ril_plugin_request_sim_status_cb(GRilIoChannel *io, int err,
const void *data, guint len, void *user_data)
{
struct ril_slot *slot = user_data;
slot->sim_status_req_id = 0;
if (err != RIL_E_SUCCESS) {
ofono_error("SIM status error %s", ril_error_to_string(err));
} else {
GRilIoParser rilp;
guint32 cardstate;
gboolean present;
grilio_parser_init(&rilp, data, len);
if (grilio_parser_get_uint32(&rilp, &cardstate) &&
(cardstate == RIL_CARDSTATE_PRESENT)) {
DBG("SIM found in slot %u", slot->config.slot);
present = TRUE;
} else {
DBG("No SIM in slot %u", slot->config.slot);
present = FALSE;
}
if (slot->pub.sim_present != present) {
slot->pub.sim_present = present;
ril_plugin_dbus_signal_sim(slot->plugin->dbus,
slot->index, present);
}
}
}
static void ril_plugin_request_sim_status(struct ril_slot *slot)
{
grilio_channel_cancel_request(slot->io, slot->sim_status_req_id, FALSE);
slot->sim_status_req_id = grilio_channel_send_request_full(slot->io,
NULL, RIL_REQUEST_GET_SIM_STATUS,
ril_plugin_request_sim_status_cb, NULL, slot);
}
static void ril_plugin_slot_status_changed(GRilIoChannel *io, guint code,
const void *data, guint len, void *user_data)
{
struct ril_slot *slot = user_data;
DBG("%s", slot->path);
GASSERT(code == RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED);
ril_plugin_request_sim_status(slot);
}
static void ril_plugin_sim_watch_done(void *data) static void ril_plugin_sim_watch_done(void *data)
{ {
struct ril_slot *slot = data; struct ril_slot *slot = data;
@@ -377,22 +445,16 @@ static void ril_plugin_sim_watch(struct ofono_atom *atom,
static void ril_plugin_handle_error(struct ril_slot *slot) static void ril_plugin_handle_error(struct ril_slot *slot)
{ {
ril_plugin_shutdown_slot(slot, TRUE); ril_plugin_shutdown_slot(slot, TRUE);
GASSERT(!slot->retry_id); ril_plugin_retry_init_io(slot);
slot->retry_id = g_timeout_add_seconds(RIL_RETRY_SECS,
ril_plugin_retry, slot);
} }
static void ril_plugin_error(GRilIoChannel *io, const GError *error, void *data) static void ril_plugin_slot_error(GRilIoChannel *io, const GError *error,
void *data)
{ {
ril_plugin_handle_error((struct ril_slot *)data); ril_plugin_handle_error((struct ril_slot *)data);
} }
static void ril_plugin_disconnect(GRilIoChannel *io, void *data) static void ril_plugin_slot_disconnected(GRilIoChannel *io, void *data)
{
ril_plugin_handle_error((struct ril_slot *)data);
}
static void ril_plugin_modem_error(struct ril_modem *modem, void *data)
{ {
ril_plugin_handle_error((struct ril_slot *)data); ril_plugin_handle_error((struct ril_slot *)data);
} }
@@ -484,8 +546,57 @@ static void ril_debug_trace_update_slot(struct ril_slot *slot)
static void ril_plugin_create_modem(struct ril_slot *slot) static void ril_plugin_create_modem(struct ril_slot *slot)
{ {
DBG("%s %s", slot->sockpath, slot->sub); struct ril_modem *modem;
DBG("%s", slot->path);
GASSERT(slot->io && slot->io->connected);
GASSERT(!slot->modem);
modem = ril_modem_create(slot->io, slot->path + 1, &slot->config);
GASSERT(modem); /* Why would it fail? */
if (modem) {
struct ofono_sim *sim = ril_modem_ofono_sim(modem);
slot->modem = modem;
slot->sim_watch_id = __ofono_modem_add_atom_watch(
ril_modem_ofono_modem(modem),
OFONO_ATOM_TYPE_SIM, ril_plugin_sim_watch,
slot, ril_plugin_sim_watch_done);
if (sim) {
ril_plugin_register_sim(slot, sim);
}
ril_modem_set_removed_cb(modem, ril_plugin_modem_removed, slot);
} else {
ril_plugin_shutdown_slot(slot, TRUE);
}
}
static void ril_plugin_slot_connected(struct ril_slot *slot)
{
ofono_debug("%s version %u", slot->name, slot->io->ril_version);
GASSERT(slot->io->connected);
GASSERT(!slot->mce);
slot->mce = ril_mce_new(slot->io);
ril_plugin_request_sim_status(slot);
if (slot->pub.enabled && !slot->modem) {
ril_plugin_create_modem(slot);
}
}
static void ril_plugin_slot_connected_cb(GRilIoChannel *io, void *user_data)
{
struct ril_slot *slot = user_data;
ril_plugin_remove_slot_handler(slot, IO_EVENT_CONNECTED);
ril_plugin_slot_connected(slot);
}
static void ril_plugin_init_io(struct ril_slot *slot)
{
if (!slot->io) { if (!slot->io) {
DBG("%s %s", slot->sockpath, slot->sub);
slot->io = grilio_channel_new_socket(slot->sockpath, slot->sub); slot->io = grilio_channel_new_socket(slot->sockpath, slot->sub);
if (slot->io) { if (slot->io) {
ril_debug_trace_update_slot(slot); ril_debug_trace_update_slot(slot);
@@ -496,47 +607,54 @@ static void ril_plugin_create_modem(struct ril_slot *slot)
} }
grilio_channel_set_timeout(slot->io, slot->timeout); grilio_channel_set_timeout(slot->io, slot->timeout);
slot->error_id = slot->io_event_id[IO_EVENT_ERROR] =
grilio_channel_add_error_handler(slot->io, grilio_channel_add_error_handler(slot->io,
ril_plugin_error, slot); ril_plugin_slot_error, slot);
slot->eof_id = slot->io_event_id[IO_EVENT_EOF] =
grilio_channel_add_disconnected_handler(slot->io, grilio_channel_add_disconnected_handler(slot->io,
ril_plugin_disconnect, slot); ril_plugin_slot_disconnected, slot);
slot->io_event_id[IO_EVENT_SIM_STATUS] =
grilio_channel_add_unsol_event_handler(slot->io,
ril_plugin_slot_status_changed,
RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED,
slot);
if (slot->io->connected) {
ril_plugin_slot_connected(slot);
} else {
slot->io_event_id[IO_EVENT_CONNECTED] =
grilio_channel_add_connected_handler(
slot->io,
ril_plugin_slot_connected_cb,
slot);
}
} }
} }
if (slot->io) { if (!slot->io) {
GASSERT(!slot->modem); ril_plugin_retry_init_io(slot);
slot->modem = ril_modem_create(slot->io, slot->path + 1, }
&slot->config); }
if (slot->modem) {
struct ofono_sim *sim = ril_modem_ofono_sim(slot->modem);
slot->sim_watch_id = __ofono_modem_add_atom_watch( static gboolean ril_plugin_retry_init_io_cb(gpointer data)
ril_modem_ofono_modem(slot->modem), {
OFONO_ATOM_TYPE_SIM, ril_plugin_sim_watch, struct ril_slot *slot = data;
slot, ril_plugin_sim_watch_done);
if (sim) { GASSERT(slot->retry_id);
ril_plugin_register_sim(slot, sim); slot->retry_id = 0;
} ril_plugin_init_io(slot);
ril_modem_set_error_cb(slot->modem, return FALSE;
ril_plugin_modem_error, slot); }
ril_modem_set_removed_cb(slot->modem,
ril_plugin_modem_removed, slot); static void ril_plugin_retry_init_io(struct ril_slot *slot)
if (!slot->mce) { {
GASSERT(!slot->mce); if (slot->retry_id) {
slot->mce = ril_mce_new(slot->io); g_source_remove(slot->retry_id);
}
} else {
ril_plugin_shutdown_slot(slot, TRUE);
}
} }
if (!slot->modem) { DBG("%s %s", slot->sockpath, slot->sub);
GASSERT(!slot->retry_id); slot->retry_id = g_timeout_add_seconds(RIL_RETRY_SECS,
slot->retry_id = g_timeout_add_seconds(RIL_RETRY_SECS, ril_plugin_retry_init_io_cb, slot);
ril_plugin_retry, slot);
}
} }
static GSList *ril_plugin_create_default_config() static GSList *ril_plugin_create_default_config()
@@ -757,17 +875,6 @@ static void ril_plugin_destroy_slot(gpointer data)
ril_plugin_delete_slot((struct ril_slot *)data); ril_plugin_delete_slot((struct ril_slot *)data);
} }
static void ril_plugin_init_slot(gpointer data, gpointer user_data)
{
struct ril_plugin_priv *plugin = user_data;
struct ril_slot *slot = data;
slot->plugin = plugin;
GASSERT(!gutil_strv_contains(plugin->pub.available_slots, slot->path));
plugin->pub.available_slots = gutil_strv_add(plugin->pub.available_slots,
slot->path);
}
/* RIL expects user radio */ /* RIL expects user radio */
static void ril_plugin_switch_user() static void ril_plugin_switch_user()
{ {
@@ -798,52 +905,11 @@ static void ril_plugin_switch_user()
} }
} }
/* Removes unavailable and duplicate slots from the string array,
* reorders them to match the order of available slots */
static char **ril_plugin_clean_slots(struct ril_plugin *plugin, char **slots)
{
guint i;
const guint len1 = gutil_strv_length(plugin->available_slots);
const guint len2 = gutil_strv_length(slots);
const guint len = MIN(len1, len2);
char **clean_slots = g_new0(char*, len + 1);
char **ptr = clean_slots;
*ptr = NULL;
for (i = 0; i < len1; i++) {
const char *slot = plugin->available_slots[i];
if (gutil_strv_contains(slots, slot)) {
GASSERT(!gutil_strv_contains(clean_slots, slot));
*ptr++ = g_strdup(slot);
*ptr = NULL;
}
}
GASSERT(gutil_strv_length(clean_slots) <= len);
return clean_slots;
}
static gboolean ril_plugin_slot_enabled(struct ril_slot *slot)
{
char **enabled = slot->plugin->pub.enabled_slots;
if (enabled) {
while (*enabled) {
if (!strcmp(*enabled, slot->path)) {
return TRUE;
}
enabled++;
}
}
return FALSE;
}
static void ril_plugin_update_enabled_slot(struct ril_slot *slot) static void ril_plugin_update_enabled_slot(struct ril_slot *slot)
{ {
if (ril_plugin_slot_enabled(slot)) { if (slot->pub.enabled) {
DBG("%s enabled", slot->path + 1); DBG("%s enabled", slot->path + 1);
if (!slot->modem) { if (slot->io && slot->io->connected && !slot->modem) {
ril_plugin_create_modem(slot); ril_plugin_create_modem(slot);
} }
} }
@@ -851,7 +917,7 @@ static void ril_plugin_update_enabled_slot(struct ril_slot *slot)
static void ril_plugin_update_disabled_slot(struct ril_slot *slot) static void ril_plugin_update_disabled_slot(struct ril_slot *slot)
{ {
if (!ril_plugin_slot_enabled(slot)) { if (!slot->pub.enabled) {
DBG("%s disabled", slot->path + 1); DBG("%s disabled", slot->path + 1);
ril_plugin_shutdown_slot(slot, FALSE); ril_plugin_shutdown_slot(slot, FALSE);
} }
@@ -865,34 +931,83 @@ static void ril_plugin_update_slots(struct ril_plugin_priv *plugin)
ril_plugin_update_modem_paths(plugin)); ril_plugin_update_modem_paths(plugin));
} }
struct ril_plugin_set_enabled_slots_data {
gchar * const * enabled;
gboolean all_enabled;
gboolean changed;
};
static void ril_plugin_enabled_slots_proc(gpointer data, gpointer user_data)
{
struct ril_slot *slot = data;
if (slot->pub.enabled) {
char ***list = user_data;
*list = gutil_strv_add(*list, slot->path);
}
}
static void ril_plugin_set_enabled_slots_proc(gpointer data, gpointer user_data)
{
struct ril_slot *slot = data;
struct ril_plugin_set_enabled_slots_data *context = user_data;
const gboolean was_enabled = slot->pub.enabled;
slot->pub.enabled = gutil_strv_contains(context->enabled, slot->path);
if ((was_enabled && !slot->pub.enabled) ||
(!was_enabled && slot->pub.enabled)) {
context->changed = TRUE;
}
if (!slot->pub.enabled) {
context->all_enabled = FALSE;
}
}
void ril_plugin_set_enabled_slots(struct ril_plugin *pub, gchar **slots) void ril_plugin_set_enabled_slots(struct ril_plugin *pub, gchar **slots)
{ {
char **new_slots = ril_plugin_clean_slots(pub, slots); struct ril_plugin_priv *plugin = ril_plugin_cast(pub);
struct ril_plugin_set_enabled_slots_data context;
if (!gutil_strv_equal(pub->enabled_slots, new_slots)) { context.enabled = slots;
struct ril_plugin_priv *plugin = ril_plugin_cast(pub); context.changed = FALSE;
context.all_enabled = TRUE;
g_slist_foreach(plugin->slots, ril_plugin_set_enabled_slots_proc,
&context);
if (context.changed) {
char **new_slots = NULL;
g_slist_foreach(plugin->slots, ril_plugin_enabled_slots_proc,
&new_slots);
/* Save the new config value. If it exactly matches the list /* Save the new config value. If it exactly matches the list
* of available modems, delete the setting because that's the * of available modems, delete the setting because that's the
* default behavior. */ * default behavior. */
if (gutil_strv_equal(pub->enabled_slots, new_slots)) { if (context.all_enabled) {
ril_pligin_set_config_string(plugin, ril_plugin_set_config_string(plugin,
RIL_STORE_ENABLED_SLOTS, NULL, TRUE); RIL_STORE_ENABLED_SLOTS, NULL, TRUE);
} else { } else {
char *value = g_strjoinv(RIL_STORE_SLOTS_SEP, new_slots); const char *value;
ril_pligin_set_config_string(plugin, char *tmp;
if (new_slots) {
tmp = g_strjoinv(RIL_STORE_SLOTS_SEP, new_slots);
value = tmp;
} else {
tmp = NULL;
value = "";
}
ril_plugin_set_config_string(plugin,
RIL_STORE_ENABLED_SLOTS, value, TRUE); RIL_STORE_ENABLED_SLOTS, value, TRUE);
g_free(value); g_free(tmp);
} }
g_strfreev(pub->enabled_slots); g_strfreev(new_slots);
pub->enabled_slots = new_slots;
ril_plugin_dbus_signal(plugin->dbus, ril_plugin_dbus_signal(plugin->dbus,
RIL_PLUGIN_SIGNAL_ENABLED_SLOTS); RIL_PLUGIN_SIGNAL_ENABLED_SLOTS);
/* Add and remove modems */ /* Add and remove modems */
ril_plugin_update_slots(plugin); ril_plugin_update_slots(plugin);
} else {
g_strfreev(new_slots);
} }
} }
@@ -905,7 +1020,7 @@ void ril_plugin_set_default_voice_imsi(struct ril_plugin *pub, const char *imsi)
g_free(plugin->default_voice_imsi); g_free(plugin->default_voice_imsi);
pub->default_voice_imsi = pub->default_voice_imsi =
plugin->default_voice_imsi = g_strdup(imsi); plugin->default_voice_imsi = g_strdup(imsi);
ril_pligin_set_config_string(plugin, RIL_STORE_DEFAULT_VOICE_SIM, ril_plugin_set_config_string(plugin, RIL_STORE_DEFAULT_VOICE_SIM,
imsi, TRUE); imsi, TRUE);
ril_plugin_dbus_signal(plugin->dbus, ril_plugin_dbus_signal(plugin->dbus,
RIL_PLUGIN_SIGNAL_VOICE_IMSI | RIL_PLUGIN_SIGNAL_VOICE_IMSI |
@@ -922,7 +1037,7 @@ void ril_plugin_set_default_data_imsi(struct ril_plugin *pub, const char *imsi)
g_free(plugin->default_data_imsi); g_free(plugin->default_data_imsi);
pub->default_data_imsi = pub->default_data_imsi =
plugin->default_data_imsi = g_strdup(imsi); plugin->default_data_imsi = g_strdup(imsi);
ril_pligin_set_config_string(plugin, RIL_STORE_DEFAULT_DATA_SIM, ril_plugin_set_config_string(plugin, RIL_STORE_DEFAULT_DATA_SIM,
imsi, TRUE); imsi, TRUE);
ril_plugin_dbus_signal(plugin->dbus, ril_plugin_dbus_signal(plugin->dbus,
RIL_PLUGIN_SIGNAL_DATA_IMSI | RIL_PLUGIN_SIGNAL_DATA_IMSI |
@@ -930,6 +1045,38 @@ void ril_plugin_set_default_data_imsi(struct ril_plugin *pub, const char *imsi)
} }
} }
static void ril_plugin_init_slots(struct ril_plugin_priv *plugin)
{
int i;
GSList *link;
const struct ril_slot_info **pub =
g_new0(const struct ril_slot_info*,
g_slist_length(plugin->slots) + 1);
plugin->pub.slots = pub;
for (i = 0, link = plugin->slots; link; link = link->next, i++) {
struct ril_slot *slot = link->data;
*pub++ = &slot->pub;
slot->index = i;
slot->plugin = plugin;
slot->pub.path = slot->path;
}
*pub = NULL;
}
static void ril_plugin_enable_disable_slot(gpointer data, gpointer user_data)
{
struct ril_slot *slot = data;
slot->pub.enabled = gutil_strv_contains(user_data, slot->path);
}
static void ril_plugin_enable_slot(struct ril_slot *slot)
{
slot->pub.enabled = TRUE;
}
struct ril_plugin_priv *ril_plugin = NULL; struct ril_plugin_priv *ril_plugin = NULL;
static void ril_debug_trace_notify(struct ofono_debug_desc *desc) static void ril_debug_trace_notify(struct ofono_debug_desc *desc)
@@ -959,7 +1106,7 @@ static int ril_plugin_init(void)
ril_plugin = g_new0(struct ril_plugin_priv, 1); ril_plugin = g_new0(struct ril_plugin_priv, 1);
ril_plugin->slots = ril_plugin_load_config(RILMODEM_CONF_FILE); ril_plugin->slots = ril_plugin_load_config(RILMODEM_CONF_FILE);
g_slist_foreach(ril_plugin->slots, ril_plugin_init_slot, ril_plugin); ril_plugin_init_slots(ril_plugin);
ril_plugin->dbus = ril_plugin_dbus_new(&ril_plugin->pub); ril_plugin->dbus = ril_plugin_dbus_new(&ril_plugin->pub);
/* Load settings */ /* Load settings */
@@ -970,14 +1117,13 @@ static int ril_plugin_init(void)
char **strv = g_strsplit(enabled_slots, RIL_STORE_SLOTS_SEP, 0); char **strv = g_strsplit(enabled_slots, RIL_STORE_SLOTS_SEP, 0);
DBG("Enabled slots: %s", enabled_slots); DBG("Enabled slots: %s", enabled_slots);
ril_plugin->pub.enabled_slots = g_slist_foreach(ril_plugin->slots,
ril_plugin_clean_slots(&ril_plugin->pub, strv); ril_plugin_enable_disable_slot, strv);
g_strfreev(strv); g_strfreev(strv);
g_free(enabled_slots); g_free(enabled_slots);
} else { } else {
/* Let all slots be enabled by default */ /* Let all slots be enabled by default */
ril_plugin->pub.enabled_slots = ril_plugin_foreach_slot(ril_plugin, ril_plugin_enable_slot);
g_strdupv(ril_plugin->pub.available_slots);
} }
ril_plugin->pub.default_voice_imsi = ril_plugin->pub.default_voice_imsi =
@@ -1015,6 +1161,12 @@ static int ril_plugin_init(void)
/* This will create the modems (those that are enabled) */ /* This will create the modems (those that are enabled) */
ril_plugin_update_slots(ril_plugin); ril_plugin_update_slots(ril_plugin);
/*
* Init RIL I/O for disabled slots as well so that we can receive
* SIM insertion/removal notifications
*/
ril_plugin_foreach_slot(ril_plugin, ril_plugin_init_io);
return 0; return 0;
} }
@@ -1046,8 +1198,7 @@ static void ril_plugin_exit(void)
g_slist_free_full(ril_plugin->slots, ril_plugin_destroy_slot); g_slist_free_full(ril_plugin->slots, ril_plugin_destroy_slot);
ril_plugin_dbus_free(ril_plugin->dbus); ril_plugin_dbus_free(ril_plugin->dbus);
g_key_file_free(ril_plugin->storage); g_key_file_free(ril_plugin->storage);
g_strfreev(ril_plugin->pub.available_slots); g_free(ril_plugin->pub.slots);
g_strfreev(ril_plugin->pub.enabled_slots);
g_free(ril_plugin->default_voice_imsi); g_free(ril_plugin->default_voice_imsi);
g_free(ril_plugin->default_data_imsi); g_free(ril_plugin->default_data_imsi);
g_free(ril_plugin->default_voice_path); g_free(ril_plugin->default_voice_path);

View File

@@ -45,13 +45,18 @@
#define RIL_RETRY_SECS (2) #define RIL_RETRY_SECS (2)
#define MAX_SIM_STATUS_RETRIES (15) #define MAX_SIM_STATUS_RETRIES (15)
struct ril_slot_info {
const char *path;
gboolean enabled;
gboolean sim_present;
};
struct ril_plugin { struct ril_plugin {
const char *default_voice_imsi; const char *default_voice_imsi;
const char *default_data_imsi; const char *default_data_imsi;
const char *default_voice_path; const char *default_voice_path;
const char *default_data_path; const char *default_data_path;
char **available_slots; const struct ril_slot_info **slots;
char **enabled_slots;
}; };
struct ril_modem_config { struct ril_modem_config {
@@ -83,6 +88,8 @@ void ril_sim_dbus_free(struct ril_sim_dbus *dbus);
struct ril_plugin_dbus *ril_plugin_dbus_new(struct ril_plugin *plugin); struct ril_plugin_dbus *ril_plugin_dbus_new(struct ril_plugin *plugin);
void ril_plugin_dbus_free(struct ril_plugin_dbus *dbus); void ril_plugin_dbus_free(struct ril_plugin_dbus *dbus);
void ril_plugin_dbus_signal(struct ril_plugin_dbus *dbus, int mask); void ril_plugin_dbus_signal(struct ril_plugin_dbus *dbus, int mask);
void ril_plugin_dbus_signal_sim(struct ril_plugin_dbus *dbus, int index,
gboolean present);
struct ril_modem *ril_modem_create(GRilIoChannel *io, const char *dev, struct ril_modem *ril_modem_create(GRilIoChannel *io, const char *dev,
const struct ril_modem_config *config); const struct ril_modem_config *config);
@@ -94,8 +101,6 @@ struct ofono_sim *ril_modem_ofono_sim(struct ril_modem *modem);
struct ofono_gprs *ril_modem_ofono_gprs(struct ril_modem *modem); struct ofono_gprs *ril_modem_ofono_gprs(struct ril_modem *modem);
struct ofono_netreg *ril_modem_ofono_netreg(struct ril_modem *modem); struct ofono_netreg *ril_modem_ofono_netreg(struct ril_modem *modem);
struct ofono_modem *ril_modem_ofono_modem(struct ril_modem *modem); struct ofono_modem *ril_modem_ofono_modem(struct ril_modem *modem);
void ril_modem_set_error_cb(struct ril_modem *modem, ril_modem_cb_t cb,
void *data);
void ril_modem_set_removed_cb(struct ril_modem *modem, ril_modem_cb_t cb, void ril_modem_set_removed_cb(struct ril_modem *modem, ril_modem_cb_t cb,
void *data); void *data);

View File

@@ -31,25 +31,44 @@ struct ril_plugin_dbus {
#define RIL_DBUS_PATH "/" #define RIL_DBUS_PATH "/"
#define RIL_DBUS_INTERFACE "org.nemomobile.ofono.ModemManager" #define RIL_DBUS_INTERFACE "org.nemomobile.ofono.ModemManager"
#define RIL_DBUS_INTERFACE_VERSION (1) #define RIL_DBUS_INTERFACE_VERSION (2)
#define RIL_DBUS_ENABLED_MODEM_CHANGED_SIGNAL "EnabledModemsChanged" #define RIL_DBUS_ENABLED_MODEMS_CHANGED_SIGNAL "EnabledModemsChanged"
#define RIL_DBUS_PRESENT_SIMS_CHANGED_SIGNAL "PresentSimsChanged"
#define RIL_DBUS_DEFAULT_VOICE_SIM_CHANGED_SIGNAL "DefaultVoiceSimChanged" #define RIL_DBUS_DEFAULT_VOICE_SIM_CHANGED_SIGNAL "DefaultVoiceSimChanged"
#define RIL_DBUS_DEFAULT_DATA_SIM_CHANGED_SIGNAL "DefaultDataSimChanged" #define RIL_DBUS_DEFAULT_DATA_SIM_CHANGED_SIGNAL "DefaultDataSimChanged"
#define RIL_DBUS_DEFAULT_VOICE_MODEM_CHANGED_SIGNAL "DefaultVoiceModemChanged" #define RIL_DBUS_DEFAULT_VOICE_MODEM_CHANGED_SIGNAL "DefaultVoiceModemChanged"
#define RIL_DBUS_DEFAULT_DATA_MODEM_CHANGED_SIGNAL "DefaultDataModemChanged" #define RIL_DBUS_DEFAULT_DATA_MODEM_CHANGED_SIGNAL "DefaultDataModemChanged"
#define RIL_DBUS_IMSI_AUTO "auto" #define RIL_DBUS_IMSI_AUTO "auto"
static void ril_plugin_dbus_append_path_array(DBusMessageIter *it, char **paths) typedef gboolean
(*ril_plugin_dbus_slot_select_fn) (const struct ril_slot_info *);
typedef const char *
(*ril_plugin_dbus_slot_string_fn) (const struct ril_slot_info *);
static gboolean ril_plugin_dbus_enabled(const struct ril_slot_info *slot)
{
return slot->enabled;
}
static gboolean ril_plugin_dbus_present(const struct ril_slot_info *slot)
{
return slot->sim_present;
}
static void ril_plugin_dbus_append_path_array(DBusMessageIter *it,
struct ril_plugin_dbus *dbus, ril_plugin_dbus_slot_select_fn selector)
{ {
DBusMessageIter array; DBusMessageIter array;
const struct ril_slot_info *const *ptr = dbus->plugin->slots;
dbus_message_iter_open_container(it, DBUS_TYPE_ARRAY, dbus_message_iter_open_container(it, DBUS_TYPE_ARRAY,
DBUS_TYPE_OBJECT_PATH_AS_STRING, &array); DBUS_TYPE_OBJECT_PATH_AS_STRING, &array);
if (paths) { while (*ptr) {
while (*paths) { const struct ril_slot_info *slot = *ptr++;
const char *path = *paths++; if (!selector || selector(slot)) {
const char *path = slot->path;
dbus_message_iter_append_basic(&array, dbus_message_iter_append_basic(&array,
DBUS_TYPE_OBJECT_PATH, &path); DBUS_TYPE_OBJECT_PATH, &path);
} }
@@ -58,6 +77,25 @@ static void ril_plugin_dbus_append_path_array(DBusMessageIter *it, char **paths)
dbus_message_iter_close_container(it, &array); dbus_message_iter_close_container(it, &array);
} }
static void ril_plugin_dbus_append_boolean_array(DBusMessageIter *it,
struct ril_plugin_dbus *dbus, ril_plugin_dbus_slot_select_fn value)
{
DBusMessageIter array;
const struct ril_slot_info *const *ptr = dbus->plugin->slots;
dbus_message_iter_open_container(it, DBUS_TYPE_ARRAY,
DBUS_TYPE_BOOLEAN_AS_STRING, &array);
while (*ptr) {
const struct ril_slot_info *slot = *ptr++;
dbus_bool_t b = value(slot);
dbus_message_iter_append_basic(&array, DBUS_TYPE_BOOLEAN, &b);
}
dbus_message_iter_close_container(it, &array);
}
static void ril_plugin_dbus_append_imsi(DBusMessageIter *it, const char *imsi) static void ril_plugin_dbus_append_imsi(DBusMessageIter *it, const char *imsi)
{ {
if (!imsi) imsi = RIL_DBUS_IMSI_AUTO; if (!imsi) imsi = RIL_DBUS_IMSI_AUTO;
@@ -72,21 +110,21 @@ static void ril_plugin_dbus_append_path(DBusMessageIter *it, const char *path)
} }
static void ril_plugin_dbus_message_append_path_array(DBusMessage *msg, static void ril_plugin_dbus_message_append_path_array(DBusMessage *msg,
char **paths) struct ril_plugin_dbus *dbus, ril_plugin_dbus_slot_select_fn fn)
{ {
DBusMessageIter iter; DBusMessageIter iter;
dbus_message_iter_init_append(msg, &iter); dbus_message_iter_init_append(msg, &iter);
ril_plugin_dbus_append_path_array(&iter, paths); ril_plugin_dbus_append_path_array(&iter, dbus, fn);
} }
static void ril_plugin_dbus_signal_path_array(struct ril_plugin_dbus *dbus, static void ril_plugin_dbus_signal_path_array(struct ril_plugin_dbus *dbus,
const char *name, char **paths) const char *name, ril_plugin_dbus_slot_select_fn fn)
{ {
DBusMessage *signal = dbus_message_new_signal(RIL_DBUS_PATH, DBusMessage *signal = dbus_message_new_signal(RIL_DBUS_PATH,
RIL_DBUS_INTERFACE, name); RIL_DBUS_INTERFACE, name);
ril_plugin_dbus_message_append_path_array(signal, paths); ril_plugin_dbus_message_append_path_array(signal, dbus, fn);
g_dbus_send_message(dbus->conn, signal); g_dbus_send_message(dbus->conn, signal);
} }
@@ -121,8 +159,8 @@ void ril_plugin_dbus_signal(struct ril_plugin_dbus *dbus, int mask)
} }
if (mask & RIL_PLUGIN_SIGNAL_ENABLED_SLOTS) { if (mask & RIL_PLUGIN_SIGNAL_ENABLED_SLOTS) {
ril_plugin_dbus_signal_path_array(dbus, ril_plugin_dbus_signal_path_array(dbus,
RIL_DBUS_ENABLED_MODEM_CHANGED_SIGNAL, RIL_DBUS_ENABLED_MODEMS_CHANGED_SIGNAL,
dbus->plugin->enabled_slots); ril_plugin_dbus_enabled);
} }
if (mask & RIL_PLUGIN_SIGNAL_VOICE_PATH) { if (mask & RIL_PLUGIN_SIGNAL_VOICE_PATH) {
ril_plugin_dbus_signal_path(dbus, ril_plugin_dbus_signal_path(dbus,
@@ -137,66 +175,116 @@ void ril_plugin_dbus_signal(struct ril_plugin_dbus *dbus, int mask)
} }
} }
static DBusMessage *ril_plugin_dbus_reply_with_path_array(DBusConnection *conn, void ril_plugin_dbus_signal_sim(struct ril_plugin_dbus *dbus, int index,
DBusMessage *msg, char **paths) gboolean present)
{
dbus_bool_t value = present;
g_dbus_emit_signal(dbus->conn, RIL_DBUS_PATH, RIL_DBUS_INTERFACE,
RIL_DBUS_PRESENT_SIMS_CHANGED_SIGNAL,
DBUS_TYPE_INT32, &index,
DBUS_TYPE_BOOLEAN, &value,
DBUS_TYPE_INVALID);
}
static DBusMessage *ril_plugin_dbus_reply_with_path_array(DBusMessage *msg,
struct ril_plugin_dbus *dbus, ril_plugin_dbus_slot_select_fn fn)
{ {
DBusMessage *reply = dbus_message_new_method_return(msg); DBusMessage *reply = dbus_message_new_method_return(msg);
ril_plugin_dbus_message_append_path_array(reply, paths); ril_plugin_dbus_message_append_path_array(reply, dbus, fn);
return reply; return reply;
} }
static DBusMessage *ril_plugin_dbus_reply(DBusMessage *msg,
struct ril_plugin_dbus *dbus,
void (*append)(DBusMessageIter *, struct ril_plugin_dbus *))
{
DBusMessage *reply = dbus_message_new_method_return(msg);
DBusMessageIter iter;
dbus_message_iter_init_append(reply, &iter);
append(&iter, dbus);
return reply;
}
static void ril_plugin_dbus_append_version(DBusMessageIter *it,
struct ril_plugin_dbus *dbus)
{
dbus_int32_t version = RIL_DBUS_INTERFACE_VERSION;
dbus_message_iter_append_basic(it, DBUS_TYPE_INT32, &version);
}
static void ril_plugin_dbus_append_all(DBusMessageIter *it,
struct ril_plugin_dbus *dbus)
{
ril_plugin_dbus_append_version(it, dbus);
ril_plugin_dbus_append_path_array(it, dbus, NULL);
ril_plugin_dbus_append_path_array(it, dbus, ril_plugin_dbus_enabled);
ril_plugin_dbus_append_imsi(it, dbus->plugin->default_data_imsi);
ril_plugin_dbus_append_imsi(it, dbus->plugin->default_voice_imsi);
ril_plugin_dbus_append_path(it, dbus->plugin->default_data_path);
ril_plugin_dbus_append_path(it, dbus->plugin->default_voice_path);
}
static void ril_plugin_dbus_append_all2(DBusMessageIter *it,
struct ril_plugin_dbus *dbus)
{
ril_plugin_dbus_append_all(it, dbus);
ril_plugin_dbus_append_boolean_array(it, dbus, ril_plugin_dbus_present);
}
static DBusMessage *ril_plugin_dbus_get_all(DBusConnection *conn, static DBusMessage *ril_plugin_dbus_get_all(DBusConnection *conn,
DBusMessage *msg, void *data) DBusMessage *msg, void *data)
{ {
struct ril_plugin_dbus *dbus = data; return ril_plugin_dbus_reply(msg, (struct ril_plugin_dbus *)data,
DBusMessage *reply = dbus_message_new_method_return(msg); ril_plugin_dbus_append_all);
dbus_int32_t version = RIL_DBUS_INTERFACE_VERSION; }
DBusMessageIter iter;
dbus_message_iter_init_append(reply, &iter); static DBusMessage *ril_plugin_dbus_get_all2(DBusConnection *conn,
dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &version); DBusMessage *msg, void *data)
ril_plugin_dbus_append_path_array(&iter, dbus->plugin->available_slots); {
ril_plugin_dbus_append_path_array(&iter, dbus->plugin->enabled_slots); return ril_plugin_dbus_reply(msg, (struct ril_plugin_dbus *)data,
ril_plugin_dbus_append_imsi(&iter, dbus->plugin->default_data_imsi); ril_plugin_dbus_append_all2);
ril_plugin_dbus_append_imsi(&iter, dbus->plugin->default_voice_imsi);
ril_plugin_dbus_append_path(&iter, dbus->plugin->default_data_path);
ril_plugin_dbus_append_path(&iter, dbus->plugin->default_voice_path);
return reply;
} }
static DBusMessage *ril_plugin_dbus_get_interface_version(DBusConnection *conn, static DBusMessage *ril_plugin_dbus_get_interface_version(DBusConnection *conn,
DBusMessage *msg, void *data) DBusMessage *msg, void *data)
{ {
DBusMessage *reply = dbus_message_new_method_return(msg); return ril_plugin_dbus_reply(msg, (struct ril_plugin_dbus *)data,
dbus_int32_t version = RIL_DBUS_INTERFACE_VERSION; ril_plugin_dbus_append_version);
DBusMessageIter iter;
dbus_message_iter_init_append(reply, &iter);
dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &version);
return reply;
} }
static DBusMessage *ril_plugin_dbus_get_available_modems(DBusConnection *conn, static DBusMessage *ril_plugin_dbus_get_available_modems(DBusConnection *conn,
DBusMessage *msg, void *data) DBusMessage *msg, void *data)
{ {
struct ril_plugin_dbus *dbus = data; return ril_plugin_dbus_reply_with_path_array(msg,
(struct ril_plugin_dbus *)data, NULL);
return ril_plugin_dbus_reply_with_path_array(conn, msg,
dbus->plugin->available_slots);
} }
static DBusMessage *ril_plugin_dbus_get_enabled_modems(DBusConnection *conn, static DBusMessage *ril_plugin_dbus_get_enabled_modems(DBusConnection *conn,
DBusMessage *msg, void *data) DBusMessage *msg, void *data)
{ {
struct ril_plugin_dbus *dbus = data; return ril_plugin_dbus_reply_with_path_array(msg,
(struct ril_plugin_dbus *)data, ril_plugin_dbus_enabled);
return ril_plugin_dbus_reply_with_path_array(conn, msg,
dbus->plugin->enabled_slots);
} }
static DBusMessage *ril_plugin_dbus_reply_with_imsi(DBusConnection *conn, static void ril_plugin_dbus_append_present_sims(DBusMessageIter *it,
DBusMessage *msg, const char *imsi) struct ril_plugin_dbus *dbus)
{
ril_plugin_dbus_append_boolean_array(it, dbus, ril_plugin_dbus_present);
}
static DBusMessage *ril_plugin_dbus_get_present_sims(DBusConnection *conn,
DBusMessage *msg, void *data)
{
return ril_plugin_dbus_reply(msg, (struct ril_plugin_dbus *)data,
ril_plugin_dbus_append_present_sims);
}
static DBusMessage *ril_plugin_dbus_reply_with_imsi(DBusMessage *msg,
const char *imsi)
{ {
DBusMessage *reply = dbus_message_new_method_return(msg); DBusMessage *reply = dbus_message_new_method_return(msg);
DBusMessageIter iter; DBusMessageIter iter;
@@ -211,7 +299,7 @@ static DBusMessage *ril_plugin_dbus_get_default_data_sim(DBusConnection *conn,
{ {
struct ril_plugin_dbus *dbus = data; struct ril_plugin_dbus *dbus = data;
return ril_plugin_dbus_reply_with_imsi(conn, msg, return ril_plugin_dbus_reply_with_imsi(msg,
dbus->plugin->default_data_imsi); dbus->plugin->default_data_imsi);
} }
@@ -220,12 +308,12 @@ static DBusMessage *ril_plugin_dbus_get_default_voice_sim(DBusConnection *conn,
{ {
struct ril_plugin_dbus *dbus = data; struct ril_plugin_dbus *dbus = data;
return ril_plugin_dbus_reply_with_imsi(conn, msg, return ril_plugin_dbus_reply_with_imsi(msg,
dbus->plugin->default_voice_imsi); dbus->plugin->default_voice_imsi);
} }
static DBusMessage *ril_plugin_dbus_reply_with_path(DBusConnection *conn, static DBusMessage *ril_plugin_dbus_reply_with_path(DBusMessage *msg,
DBusMessage *msg, const char *path) const char *path)
{ {
DBusMessage *reply = dbus_message_new_method_return(msg); DBusMessage *reply = dbus_message_new_method_return(msg);
DBusMessageIter iter; DBusMessageIter iter;
@@ -240,7 +328,7 @@ static DBusMessage *ril_plugin_dbus_get_default_data_modem(DBusConnection *conn,
{ {
struct ril_plugin_dbus *dbus = data; struct ril_plugin_dbus *dbus = data;
return ril_plugin_dbus_reply_with_path(conn, msg, return ril_plugin_dbus_reply_with_path(msg,
dbus->plugin->default_data_path); dbus->plugin->default_data_path);
} }
@@ -249,7 +337,7 @@ static DBusMessage *ril_plugin_dbus_get_default_voice_modem(DBusConnection *conn
{ {
struct ril_plugin_dbus *dbus = data; struct ril_plugin_dbus *dbus = data;
return ril_plugin_dbus_reply_with_path(conn, msg, return ril_plugin_dbus_reply_with_path(msg,
dbus->plugin->default_voice_path); dbus->plugin->default_voice_path);
} }
@@ -333,6 +421,16 @@ static const GDBusMethodTable ril_plugin_dbus_methods[] = {
{"defaultDataModem", "s" }, {"defaultDataModem", "s" },
{"defaultVoiceModem" , "s"}), {"defaultVoiceModem" , "s"}),
ril_plugin_dbus_get_all) }, ril_plugin_dbus_get_all) },
{ GDBUS_METHOD("GetAll2", NULL,
GDBUS_ARGS({"version", "i" },
{"availableModems", "ao" },
{"enabledModems", "ao" },
{"defaultDataSim", "s" },
{"defaultVoiceSim", "s" },
{"defaultDataModem", "s" },
{"defaultVoiceModem" , "s"},
{"presentSims" , "ab"}),
ril_plugin_dbus_get_all2) },
{ GDBUS_METHOD("GetInterfaceVersion", { GDBUS_METHOD("GetInterfaceVersion",
NULL, GDBUS_ARGS({ "version", "i" }), NULL, GDBUS_ARGS({ "version", "i" }),
ril_plugin_dbus_get_interface_version) }, ril_plugin_dbus_get_interface_version) },
@@ -342,6 +440,9 @@ static const GDBusMethodTable ril_plugin_dbus_methods[] = {
{ GDBUS_METHOD("GetEnabledModems", { GDBUS_METHOD("GetEnabledModems",
NULL, GDBUS_ARGS({ "modems", "ao" }), NULL, GDBUS_ARGS({ "modems", "ao" }),
ril_plugin_dbus_get_enabled_modems) }, ril_plugin_dbus_get_enabled_modems) },
{ GDBUS_METHOD("GetPresentSims",
NULL, GDBUS_ARGS({ "presentSims", "ab" }),
ril_plugin_dbus_get_present_sims) },
{ GDBUS_METHOD("GetDefaultDataSim", { GDBUS_METHOD("GetDefaultDataSim",
NULL, GDBUS_ARGS({ "imsi", "s" }), NULL, GDBUS_ARGS({ "imsi", "s" }),
ril_plugin_dbus_get_default_data_sim) }, ril_plugin_dbus_get_default_data_sim) },
@@ -367,8 +468,11 @@ static const GDBusMethodTable ril_plugin_dbus_methods[] = {
}; };
static const GDBusSignalTable ril_plugin_dbus_signals[] = { static const GDBusSignalTable ril_plugin_dbus_signals[] = {
{ GDBUS_SIGNAL(RIL_DBUS_ENABLED_MODEM_CHANGED_SIGNAL, { GDBUS_SIGNAL(RIL_DBUS_ENABLED_MODEMS_CHANGED_SIGNAL,
GDBUS_ARGS({ "modems", "ao" })) }, GDBUS_ARGS({ "modems", "ao" })) },
{ GDBUS_SIGNAL(RIL_DBUS_PRESENT_SIMS_CHANGED_SIGNAL,
GDBUS_ARGS({"index", "i" },
{"present" , "b"})) },
{ GDBUS_SIGNAL(RIL_DBUS_DEFAULT_DATA_SIM_CHANGED_SIGNAL, { GDBUS_SIGNAL(RIL_DBUS_DEFAULT_DATA_SIM_CHANGED_SIGNAL,
GDBUS_ARGS({ "imsi", "s" })) }, GDBUS_ARGS({ "imsi", "s" })) },
{ GDBUS_SIGNAL(RIL_DBUS_DEFAULT_VOICE_SIM_CHANGED_SIGNAL, { GDBUS_SIGNAL(RIL_DBUS_DEFAULT_VOICE_SIM_CHANGED_SIGNAL,