Commit 6015490d authored by Slava Monich's avatar Slava Monich

[ril] Indicate SIM card presence in appropriate radio state. Contributes to JB#33805

This also reduces the number of GET_SIM_STATUS requests. Only one object
per RIL instance makes these requests, the results are shared by all
other objects involved.

In addition to that, radio power on request is retried if radio power
unexpectedly switches off which does happen on multi-sim hardware.
parent a135d0ea
......@@ -136,8 +136,10 @@ builtin_sources += drivers/ril/ril_call_barring.c \
drivers/ril/ril_phonebook.c \
drivers/ril/ril_plugin.c \
drivers/ril/ril_plugin_dbus.c \
drivers/ril/ril_radio.c \
drivers/ril/ril_radio_settings.c \
drivers/ril/ril_sim.c \
drivers/ril/ril_sim_card.c \
drivers/ril/ril_sim_dbus.c \
drivers/ril/ril_sms.c \
drivers/ril/ril_stk.c \
......
This diff is collapsed.
/*
* oFono - Open Source Telephony - RIL-based devices
*
* Copyright (C) 2015 Jolla Ltd.
* Copyright (C) 2015-2016 Jolla Ltd.
*
* 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
......@@ -14,8 +14,9 @@
*/
#include "ril_plugin.h"
#include "ril_sim_card.h"
#include "ril_radio.h"
#include "ril_mce.h"
#include "ril_constants.h"
#include "ril_util.h"
#include "ril_log.h"
......@@ -63,7 +64,6 @@ enum ril_plugin_io_events {
IO_EVENT_CONNECTED,
IO_EVENT_ERROR,
IO_EVENT_EOF,
IO_EVENT_SIM_STATUS,
IO_EVENT_COUNT
};
......@@ -88,16 +88,19 @@ struct ril_slot {
char *sub;
gint timeout; /* RIL timeout, in seconds */
int index;
struct ril_modem_config config;
struct ril_slot_config config;
struct ril_plugin_priv *plugin;
struct ril_sim_dbus *sim_dbus;
struct ril_modem *modem;
struct ril_mce *mce;
struct ofono_sim *sim;
struct ril_radio *radio;
struct ril_sim_card *sim_card;
GRilIoChannel *io;
gulong io_event_id[IO_EVENT_COUNT];
gulong sim_status_req_id;
gulong imei_req_id;
gulong sim_card_state_event_id;
gulong radio_state_event_id;
guint trace_id;
guint dump_id;
guint retry_id;
......@@ -160,7 +163,7 @@ static void ril_plugin_shutdown_slot(struct ril_slot *slot, gboolean kill_io)
}
if (slot->modem) {
struct ofono_modem *m = ril_modem_ofono_modem(slot->modem);
struct ofono_modem *m = slot->modem->ofono;
if (m && slot->sim_watch_id) {
__ofono_modem_remove_atom_watch(m, slot->sim_watch_id);
......@@ -198,10 +201,7 @@ static void ril_plugin_shutdown_slot(struct ril_slot *slot, gboolean kill_io)
grilio_channel_cancel_request(slot->io,
slot->imei_req_id, FALSE);
grilio_channel_cancel_request(slot->io,
slot->sim_status_req_id, FALSE);
slot->imei_req_id = 0;
slot->sim_status_req_id = 0;
for (i=0; i<IO_EVENT_COUNT; i++) {
ril_plugin_remove_slot_handler(slot, i);
......@@ -210,6 +210,17 @@ static void ril_plugin_shutdown_slot(struct ril_slot *slot, gboolean kill_io)
grilio_channel_shutdown(slot->io, FALSE);
grilio_channel_unref(slot->io);
slot->io = NULL;
ril_radio_remove_handler(slot->radio,
slot->radio_state_event_id);
ril_radio_unref(slot->radio);
slot->radio = NULL;
ril_sim_card_remove_handler(slot->sim_card,
slot->sim_card_state_event_id);
ril_sim_card_unref(slot->sim_card);
slot->sim_card_state_event_id = 0;
slot->sim_card = NULL;
}
}
}
......@@ -342,55 +353,27 @@ 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)
static void ril_plugin_sim_state_changed(struct ril_sim_card *card, void *data)
{
struct ril_slot *slot = user_data;
struct ril_slot *slot = data;
gboolean present;
slot->sim_status_req_id = 0;
if (err != RIL_E_SUCCESS) {
ofono_error("SIM status error %s", ril_error_to_string(err));
if (card && card->status &&
card->status->card_state == RIL_CARDSTATE_PRESENT) {
DBG("SIM found in slot %u", slot->config.slot);
present = TRUE;
} 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;
}
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,
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)
{
struct ril_slot *slot = data;
......@@ -563,14 +546,14 @@ static void ril_plugin_create_modem(struct ril_slot *slot)
GASSERT(slot->io && slot->io->connected);
GASSERT(!slot->modem);
modem = ril_modem_create(slot->io, slot->path + 1, &slot->config);
modem = ril_modem_create(slot->io, slot->radio, slot->sim_card,
slot->path + 1, &slot->config);
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),
slot->sim_watch_id = __ofono_modem_add_atom_watch(modem->ofono,
OFONO_ATOM_TYPE_SIM, ril_plugin_sim_watch,
slot, ril_plugin_sim_watch_done);
if (sim) {
......@@ -617,9 +600,31 @@ static void ril_plugin_imei_cb(GRilIoChannel *io, int status,
}
}
static void ril_plugin_power_check(struct ril_slot *slot)
{
/*
* It seems to be necessary to kick (with RIL_REQUEST_RADIO_POWER)
* the modems with power on after one of the modems has been powered
* off. Otherwise bad things may happens (like the modem never
* registering on the network).
*/
ril_radio_confirm_power_on(slot->radio);
}
static void ril_plugin_radio_state_changed(struct ril_radio *radio, void *data)
{
struct ril_slot *slot = data;
if (radio->state == RADIO_STATE_OFF) {
DBG("power off for slot %u", slot->config.slot);
ril_plugin_foreach_slot(slot->plugin, ril_plugin_power_check);
}
}
static void ril_plugin_slot_connected(struct ril_slot *slot)
{
ofono_debug("%s version %u", slot->name, slot->io->ril_version);
ofono_debug("%s version %u", (slot->name && slot->name[0]) ?
slot->name : "RIL", slot->io->ril_version);
GASSERT(slot->io->connected);
GASSERT(!slot->io_event_id[IO_EVENT_CONNECTED]);
......@@ -631,7 +636,18 @@ static void ril_plugin_slot_connected(struct ril_slot *slot)
slot->imei_req_id = grilio_channel_send_request_full(slot->io, NULL,
RIL_REQUEST_GET_IMEI, ril_plugin_imei_cb, NULL, slot);
ril_plugin_request_sim_status(slot);
GASSERT(!slot->radio);
GASSERT(!slot->radio_state_event_id);
slot->radio = ril_radio_new(slot->io);
slot->radio_state_event_id =
ril_radio_add_state_changed_handler(slot->radio,
ril_plugin_radio_state_changed, slot);
GASSERT(!slot->sim_card);
slot->sim_card = ril_sim_card_new(slot->io, slot->config.slot);
slot->sim_card_state_event_id = ril_sim_card_add_state_changed_handler(
slot->sim_card, ril_plugin_sim_state_changed, slot);
if (ril_plugin_can_create_modem(slot) && !slot->modem) {
ril_plugin_create_modem(slot);
}
......@@ -665,11 +681,6 @@ static void ril_plugin_init_io(struct ril_slot *slot)
slot->io_event_id[IO_EVENT_EOF] =
grilio_channel_add_disconnected_handler(slot->io,
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);
......
/*
* oFono - Open Source Telephony - RIL-based devices
*
* Copyright (C) 2015 Jolla Ltd.
* Copyright (C) 2015-2016 Jolla Ltd.
*
* 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
......@@ -42,8 +42,6 @@
#include <grilio_parser.h>
#define RILMODEM_DRIVER "ril"
#define RIL_RETRY_SECS (2)
#define MAX_SIM_STATUS_RETRIES (15)
struct ril_slot_info {
const char *path;
......@@ -60,20 +58,26 @@ struct ril_plugin {
const struct ril_slot_info **slots;
};
struct ril_modem_config {
struct ril_slot_config {
guint slot;
gboolean enable_4g;
const char *default_name;
};
struct ril_modem {
GRilIoChannel *io;
struct ofono_modem *ofono;
struct ril_radio *radio;
struct ril_sim_card *sim_card;
struct ril_slot_config config;
};
#define RIL_PLUGIN_SIGNAL_VOICE_IMSI (0x01)
#define RIL_PLUGIN_SIGNAL_DATA_IMSI (0x02)
#define RIL_PLUGIN_SIGNAL_VOICE_PATH (0x04)
#define RIL_PLUGIN_SIGNAL_DATA_PATH (0x10)
#define RIL_PLUGIN_SIGNAL_ENABLED_SLOTS (0x20)
struct ril_modem;
struct ril_plugin_dbus;
typedef void (*ril_modem_cb_t)(struct ril_modem *modem, void *data);
void ril_plugin_set_enabled_slots(struct ril_plugin *plugin, char **slots);
......@@ -94,22 +98,21 @@ 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,
const struct ril_modem_config *config);
struct ril_modem *ril_modem_create(GRilIoChannel *io, struct ril_radio *radio,
struct ril_sim_card *sc, const char *dev,
const struct ril_slot_config *config);
void ril_modem_delete(struct ril_modem *modem);
void ril_modem_allow_data(struct ril_modem *modem);
GRilIoChannel *ril_modem_io(struct ril_modem *modem);
const struct ril_modem_config *ril_modem_config(struct ril_modem *modem);
struct ofono_sim *ril_modem_ofono_sim(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_modem *ril_modem_ofono_modem(struct ril_modem *modem);
void ril_modem_set_removed_cb(struct ril_modem *modem, ril_modem_cb_t cb,
void *data);
#define ril_modem_slot(md) (ril_modem_config(modem)->slot)
#define ril_modem_4g_enabled(md) (ril_modem_config(modem)->enable_4g)
#define ril_modem_get_path(md) ofono_modem_get_path(ril_modem_ofono_modem(md))
#define ril_modem_get_path(modem) ofono_modem_get_path((modem)->ofono)
#define ril_modem_4g_enabled(modem) ((modem)->config.enable_4g)
#define ril_modem_slot(modem) ((modem)->config.slot)
#define ril_modem_io(modem) ((modem)->io)
void ril_sim_read_file_linear(struct ofono_sim *sim, int fileid,
int record, int length, const unsigned char *path,
......@@ -126,8 +129,7 @@ void ril_sim_read_file_info(struct ofono_sim *sim, int fileid,
int ril_sim_app_type(struct ofono_sim *sim);
int ril_gprs_ril_data_tech(struct ofono_gprs *gprs);
int ril_netreg_check_if_really_roaming(struct ofono_netreg *netreg,
gint status);
int ril_netreg_check_if_really_roaming(struct ofono_netreg *netreg, gint status);
extern const struct ofono_call_barring_driver ril_call_barring_driver;
extern const struct ofono_call_forwarding_driver ril_call_forwarding_driver;
......
This diff is collapsed.
/*
* oFono - Open Source Telephony - RIL-based devices
*
* Copyright (C) 2015-2016 Jolla Ltd.
*
* 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.
*/
#ifndef RIL_RADIO_H
#define RIL_RADIO_H
#include "ril_types.h"
struct ril_radio {
GObject object;
struct ril_radio_priv *priv;
enum ril_radio_state state;
};
typedef void (*ril_radio_cb_t)(struct ril_radio *radio, void *arg);
struct ril_radio *ril_radio_new(GRilIoChannel *io);
struct ril_radio *ril_radio_ref(struct ril_radio *radio);
void ril_radio_unref(struct ril_radio *radio);
void ril_radio_power_on(struct ril_radio *radio, gpointer tag);
void ril_radio_power_off(struct ril_radio *radio, gpointer tag);
void ril_radio_confirm_power_on(struct ril_radio *radio);
void ril_radio_power_cycle(struct ril_radio *radio);
gulong ril_radio_add_state_changed_handler(struct ril_radio *radio,
ril_radio_cb_t cb, void *arg);
void ril_radio_remove_handler(struct ril_radio *radio, gulong id);
#endif /* RIL_RADIO */
/*
* Local Variables:
* mode: C
* c-basic-offset: 8
* indent-tabs-mode: t
* End:
*/
This diff is collapsed.
This diff is collapsed.
/*
* oFono - Open Source Telephony - RIL-based devices
*
* Copyright (C) 2015-2016 Jolla Ltd.
*
* 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.
*/
#ifndef RIL_SIM_CARD_H
#define RIL_SIM_CARD_H
#include "ril_types.h"
struct ril_sim_card_app {
enum ril_app_type app_type;
enum ril_app_state app_state;
enum ril_perso_substate perso_substate;
char *aid;
char *label;
guint pin_replaced;
enum ril_pin_state pin1_state;
enum ril_pin_state pin2_state;
};
struct ril_sim_card_status {
enum ril_card_state card_state;
enum ril_pin_state pin_state;
int gsm_umts_index;
int cdma_index;
int ims_index;
int num_apps;
struct ril_sim_card_app *apps;
};
struct ril_sim_card {
GObject object;
struct ril_sim_card_priv *priv;
struct ril_sim_card_status *status;
const struct ril_sim_card_app *app;
guint slot;
};
typedef void (*ril_sim_card_cb_t)(struct ril_sim_card *sc, void *arg);
struct ril_sim_card *ril_sim_card_new(GRilIoChannel *io, guint slot);
struct ril_sim_card *ril_sim_card_ref(struct ril_sim_card *sc);
void ril_sim_card_unref(struct ril_sim_card *sc);
gulong ril_sim_card_add_status_received_handler(struct ril_sim_card *sc,
ril_sim_card_cb_t cb, void *arg);
gulong ril_sim_card_add_status_changed_handler(struct ril_sim_card *sc,
ril_sim_card_cb_t cb, void *arg);
gulong ril_sim_card_add_state_changed_handler(struct ril_sim_card *sc,
ril_sim_card_cb_t cb, void *arg);
gulong ril_sim_card_add_app_changed_handler(struct ril_sim_card *sc,
ril_sim_card_cb_t cb, void *arg);
void ril_sim_card_remove_handler(struct ril_sim_card *sc, gulong id);
/* Inline wrappers */
G_INLINE_FUNC enum ril_app_type
ril_sim_card_app_type(struct ril_sim_card *sc)
{ return (sc && sc->app) ? sc->app->app_type : RIL_APPTYPE_UNKNOWN; }
#endif /* RIL_SIM_CARD_H */
/*
* Local Variables:
* mode: C
* c-basic-offset: 8
* indent-tabs-mode: t
* End:
*/
/*
* oFono - Open Source Telephony - RIL-based devices
*
* Copyright (C) 2015 Jolla Ltd.
* Copyright (C) 2015-2016 Jolla Ltd.
*
* 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
......@@ -16,7 +16,6 @@
#include "ril_plugin.h"
#include "ril_log.h"
#include <ofono/log.h>
#include <ofono/dbus.h>
#include <gdbus.h>
......@@ -174,7 +173,7 @@ struct ril_sim_dbus *ril_sim_dbus_new(struct ril_modem *md)
if (imsi) {
GError *error = NULL;
const struct ril_modem_config *config= ril_modem_config(md);
const struct ril_slot_config *config = &md->config;
struct ril_sim_dbus *dbus = g_new0(struct ril_sim_dbus, 1);
DBG("%s", ril_modem_get_path(md));
......@@ -204,7 +203,7 @@ struct ril_sim_dbus *ril_sim_dbus_new(struct ril_modem *md)
if (g_dbus_register_interface(dbus->conn, dbus->path,
RIL_SIM_DBUS_INTERFACE, ril_sim_dbus_methods,
ril_sim_dbus_signals, NULL, dbus, NULL)) {
ofono_modem_add_interface(ril_modem_ofono_modem(md),
ofono_modem_add_interface(md->ofono,
RIL_SIM_DBUS_INTERFACE);
return dbus;
} else {
......@@ -222,7 +221,7 @@ void ril_sim_dbus_free(struct ril_sim_dbus *dbus)
DBG("%s", dbus->path);
g_dbus_unregister_interface(dbus->conn, dbus->path,
RIL_SIM_DBUS_INTERFACE);
ofono_modem_remove_interface(ril_modem_ofono_modem(dbus->md),
ofono_modem_remove_interface(dbus->md->ofono,
RIL_SIM_DBUS_INTERFACE);
dbus_connection_unref(dbus->conn);
g_key_file_free(dbus->storage);
......
/*
* oFono - Open Source Telephony - RIL-based devices
*
* Copyright (C) 2015 Jolla Ltd.
* Copyright (C) 2015-2016 Jolla Ltd.
*
* 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
......@@ -30,6 +30,15 @@
#include <string.h>
#include <unistd.h>
#include "ril_constants.h"
#define RIL_RETRY_SECS (2)
struct ril_modem;
struct ril_radio;
struct ril_sim_card;
struct ril_plugin_dbus;
#endif /* RIL_TYPES_H */
/*
......
......@@ -20,7 +20,7 @@ BuildRequires: pkgconfig(bluez) >= 4.85
BuildRequires: pkgconfig(mobile-broadband-provider-info)
BuildRequires: pkgconfig(libwspcodec) >= 2.0
BuildRequires: pkgconfig(libglibutil)
BuildRequires: pkgconfig(libgrilio)
BuildRequires: pkgconfig(libgrilio) >= 1.0.3
BuildRequires: libtool
BuildRequires: automake
BuildRequires: autoconf
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment