forked from sailfishos/ofono
Compare commits
11 Commits
upgrade-3.
...
upgrade-3.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
75b07c5c80 | ||
|
|
4f6f964ca4 | ||
|
|
7af95f6db5 | ||
|
|
99f4667eb7 | ||
|
|
c1c3ecab31 | ||
|
|
83dc99658c | ||
|
|
9a7b538087 | ||
|
|
9f7a1ffe3f | ||
|
|
1f81ec7d9d | ||
|
|
6e833401cc | ||
|
|
d9c68c4fb9 |
@@ -85,6 +85,7 @@
|
||||
#define RILMODEM_DEFAULT_LEGACY_IMEI_QUERY FALSE
|
||||
#define RILMODEM_DEFAULT_RADIO_POWER_CYCLE TRUE
|
||||
#define RILMODEM_DEFAULT_CONFIRM_RADIO_POWER_ON TRUE
|
||||
#define RILMODEM_DEFAULT_SLOT_FLAGS SAILFISH_SLOT_NO_FLAGS
|
||||
|
||||
/* RIL socket transport name and parameters */
|
||||
#define RIL_TRANSPORT_SOCKET "socket"
|
||||
@@ -130,6 +131,7 @@
|
||||
#define RILCONF_LEGACY_IMEI_QUERY "legacyImeiQuery"
|
||||
#define RILCONF_RADIO_POWER_CYCLE "radioPowerCycle"
|
||||
#define RILCONF_CONFIRM_RADIO_POWER_ON "confirmRadioPowerOn"
|
||||
#define RILCONF_SINGLE_DATA_CONTEXT "singleDataContext"
|
||||
|
||||
/* Modem error ids */
|
||||
#define RIL_ERROR_ID_RILD_RESTART "rild-restart"
|
||||
@@ -211,6 +213,7 @@ typedef struct sailfish_slot_impl {
|
||||
struct ril_vendor_hook *vendor_hook;
|
||||
struct ril_data *data;
|
||||
gboolean legacy_imei_query;
|
||||
enum sailfish_slot_flags slot_flags;
|
||||
guint start_timeout;
|
||||
guint start_timeout_id;
|
||||
MceDisplay *display;
|
||||
@@ -1039,9 +1042,10 @@ static void ril_plugin_slot_connected(ril_slot *slot)
|
||||
slot->start_timeout_id = 0;
|
||||
|
||||
/* Register this slot with the sailfish manager plugin */
|
||||
slot->handle = sailfish_manager_slot_add(plugin->handle, slot,
|
||||
slot->handle = sailfish_manager_slot_add2(plugin->handle, slot,
|
||||
slot->path, slot->config.techs, slot->imei,
|
||||
slot->imeisv, ril_plugin_sim_state(slot));
|
||||
slot->imeisv, ril_plugin_sim_state(slot),
|
||||
slot->slot_flags);
|
||||
sailfish_manager_set_cell_info(slot->handle, slot->cell_info);
|
||||
|
||||
/* Check if this was the last slot we were waiting for */
|
||||
@@ -1206,6 +1210,7 @@ static ril_slot *ril_plugin_slot_new_take(char *transport,
|
||||
RILMODEM_DEFAULT_QUERY_AVAILABLE_BAND_MODE;
|
||||
slot->timeout = RILMODEM_DEFAULT_TIMEOUT;
|
||||
slot->sim_flags = RILMODEM_DEFAULT_SIM_FLAGS;
|
||||
slot->slot_flags = RILMODEM_DEFAULT_SLOT_FLAGS;
|
||||
slot->legacy_imei_query = RILMODEM_DEFAULT_LEGACY_IMEI_QUERY;
|
||||
slot->start_timeout = RILMODEM_DEFAULT_START_TIMEOUT;
|
||||
slot->data_opt.allow_data = RILMODEM_DEFAULT_DATA_OPT;
|
||||
@@ -1353,6 +1358,7 @@ static ril_slot *ril_plugin_parse_config_group(GKeyFile *file,
|
||||
{
|
||||
ril_slot *slot;
|
||||
struct ril_slot_config *config;
|
||||
gboolean bval;
|
||||
int ival;
|
||||
char *sval;
|
||||
char **strv;
|
||||
@@ -1540,6 +1546,14 @@ static ril_slot *ril_plugin_parse_config_group(GKeyFile *file,
|
||||
config->confirm_radio_power_on ? "on" : "off");
|
||||
}
|
||||
|
||||
/* singleDataContext */
|
||||
if (ril_config_get_boolean(file, group, RILCONF_SINGLE_DATA_CONTEXT,
|
||||
&bval) && bval) {
|
||||
DBG("%s: " RILCONF_SINGLE_DATA_CONTEXT " %s", group,
|
||||
bval ? "on" : "off");
|
||||
slot->slot_flags |= SAILFISH_SLOT_SINGLE_CONTEXT;
|
||||
}
|
||||
|
||||
/* uiccWorkaround */
|
||||
if (ril_config_get_flag(file, group, RILCONF_UICC_WORKAROUND,
|
||||
RIL_SIM_CARD_V9_UICC_SUBSCRIPTION_WORKAROUND,
|
||||
|
||||
@@ -240,3 +240,12 @@ socket=/dev/socket/rild
|
||||
# The default is true for historical reasons
|
||||
#
|
||||
#confirmRadioPowerOn=true
|
||||
|
||||
# Normally we should be able to have two simultaneously active data
|
||||
# contexts - one for mobile data and one for MMS. Some devices however
|
||||
# require that mobile data is disconnected before we can send or receive
|
||||
# MMS. In other words, activation of the second data context fails.
|
||||
#
|
||||
# The default is false (more than one context is supported)
|
||||
#
|
||||
#singleDataContext=false
|
||||
|
||||
@@ -54,7 +54,7 @@ static gboolean on_socket_connected(GIOChannel *chan, GIOCondition cond,
|
||||
unsigned int len = sizeof(saddr);
|
||||
int fd;
|
||||
struct ofono_emulator *em;
|
||||
struct ofono_modem *modem;
|
||||
GList *i;
|
||||
|
||||
if (cond != G_IO_IN)
|
||||
return FALSE;
|
||||
@@ -63,15 +63,16 @@ static gboolean on_socket_connected(GIOChannel *chan, GIOCondition cond,
|
||||
if (fd == -1)
|
||||
return FALSE;
|
||||
|
||||
/* Pick the first powered modem */
|
||||
modem = modems->data;
|
||||
DBG("Picked modem %p for emulator", modem);
|
||||
DBG("Using all modems for emulator.");
|
||||
|
||||
em = ofono_emulator_create(modem, GPOINTER_TO_INT(user));
|
||||
if (em == NULL)
|
||||
close(fd);
|
||||
else
|
||||
em = ofono_emulator_create(GPOINTER_TO_INT(user));
|
||||
|
||||
if (em) {
|
||||
for (i = modems; i; i = i->next)
|
||||
ofono_emulator_add_modem(em, i->data);
|
||||
ofono_emulator_register(em, fd);
|
||||
} else
|
||||
close(fd);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -68,8 +68,9 @@ typedef void (*ofono_emulator_request_cb_t)(struct ofono_emulator *em,
|
||||
struct ofono_emulator_request *req,
|
||||
void *data);
|
||||
|
||||
struct ofono_emulator *ofono_emulator_create(struct ofono_modem *modem,
|
||||
enum ofono_emulator_type type);
|
||||
struct ofono_emulator *ofono_emulator_create(enum ofono_emulator_type type);
|
||||
void ofono_emulator_add_modem(struct ofono_emulator *em,
|
||||
struct ofono_modem *modem);
|
||||
|
||||
void ofono_emulator_register(struct ofono_emulator *em, int fd);
|
||||
|
||||
|
||||
@@ -35,6 +35,18 @@ struct sailfish_cell_info;
|
||||
typedef void (*sailfish_slot_manager_impl_cb_t)
|
||||
(struct sailfish_slot_manager_impl *impl, void *user_data);
|
||||
|
||||
enum sailfish_slot_flags {
|
||||
SAILFISH_SLOT_NO_FLAGS = 0,
|
||||
/* Normally we should be able to have two simultaneously active
|
||||
* data contexts - one for mobile data and one for MMS. The flag
|
||||
* below says that for whatever reason it's impossible and mobile
|
||||
* data has to be disconnected before we can send or receive MMS.
|
||||
* On such devices it may not be a good idea to automatically
|
||||
* download MMS because that would kill active mobile data
|
||||
* connections. */
|
||||
SAILFISH_SLOT_SINGLE_CONTEXT = 0x01
|
||||
};
|
||||
|
||||
typedef struct sailfish_slot {
|
||||
const char *path;
|
||||
const char *imei;
|
||||
@@ -81,6 +93,12 @@ struct sailfish_slot *sailfish_manager_slot_add
|
||||
const char *path, enum ofono_radio_access_mode techs,
|
||||
const char *imei, const char *imeisv,
|
||||
enum sailfish_sim_state sim_state);
|
||||
struct sailfish_slot *sailfish_manager_slot_add2
|
||||
(struct sailfish_slot_manager *m, struct sailfish_slot_impl *i,
|
||||
const char *path, enum ofono_radio_access_mode techs,
|
||||
const char *imei, const char *imeisv,
|
||||
enum sailfish_sim_state sim_state,
|
||||
enum sailfish_slot_flags flags);
|
||||
void sailfish_manager_imei_obtained(struct sailfish_slot *s, const char *imei);
|
||||
void sailfish_manager_imeisv_obtained(struct sailfish_slot *s,
|
||||
const char *imeisv);
|
||||
|
||||
@@ -79,7 +79,7 @@ static const gchar *dun_record =
|
||||
static void dun_gw_connect_cb(GIOChannel *io, GError *err, gpointer user_data)
|
||||
{
|
||||
struct ofono_emulator *em = user_data;
|
||||
struct ofono_modem *modem;
|
||||
GList *i;
|
||||
int fd;
|
||||
|
||||
DBG("");
|
||||
@@ -90,16 +90,17 @@ static void dun_gw_connect_cb(GIOChannel *io, GError *err, gpointer user_data)
|
||||
return;
|
||||
}
|
||||
|
||||
/* Pick the first powered modem */
|
||||
modem = modems->data;
|
||||
DBG("Picked modem %p for emulator", modem);
|
||||
DBG("Using all modems for emulator");
|
||||
|
||||
em = ofono_emulator_create(modem, OFONO_EMULATOR_TYPE_DUN);
|
||||
em = ofono_emulator_create(OFONO_EMULATOR_TYPE_DUN);
|
||||
if (em == NULL) {
|
||||
g_io_channel_shutdown(io, TRUE, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = modems; i; i = i->next)
|
||||
ofono_emulator_add_modem(em, i->data);
|
||||
|
||||
fd = g_io_channel_unix_get_fd(io);
|
||||
g_io_channel_set_close_on_unref(io, FALSE);
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ static DBusMessage *profile_new_connection(DBusConnection *conn,
|
||||
const char *device;
|
||||
int fd;
|
||||
struct ofono_emulator *em;
|
||||
struct ofono_modem *modem;
|
||||
GList *i;
|
||||
|
||||
DBG("Profile handler NewConnection");
|
||||
|
||||
@@ -80,7 +80,6 @@ static DBusMessage *profile_new_connection(DBusConnection *conn,
|
||||
|
||||
DBG("%s", device);
|
||||
|
||||
/* Pick the first powered modem */
|
||||
if (modems == NULL) {
|
||||
close(fd);
|
||||
return g_dbus_create_error(msg, BLUEZ_ERROR_INTERFACE
|
||||
@@ -88,10 +87,9 @@ static DBusMessage *profile_new_connection(DBusConnection *conn,
|
||||
"No GPRS capable modem");
|
||||
}
|
||||
|
||||
modem = modems->data;
|
||||
DBG("Picked modem %p for emulator", modem);
|
||||
DBG("Using all modems for emulator.");
|
||||
|
||||
em = ofono_emulator_create(modem, OFONO_EMULATOR_TYPE_DUN);
|
||||
em = ofono_emulator_create(OFONO_EMULATOR_TYPE_DUN);
|
||||
if (em == NULL) {
|
||||
close(fd);
|
||||
return g_dbus_create_error(msg, BLUEZ_ERROR_INTERFACE
|
||||
@@ -99,6 +97,9 @@ static DBusMessage *profile_new_connection(DBusConnection *conn,
|
||||
"Not enough resources");
|
||||
}
|
||||
|
||||
for (i = modems; i; i = i->next)
|
||||
ofono_emulator_add_modem(em, i->data);
|
||||
|
||||
ofono_emulator_register(em, fd);
|
||||
|
||||
return dbus_message_new_method_return(msg);
|
||||
|
||||
@@ -91,6 +91,7 @@ static void hfp_ag_connect_cb(GIOChannel *io, GError *err, gpointer user_data)
|
||||
struct ofono_modem *modem;
|
||||
struct ofono_emulator *em;
|
||||
int fd;
|
||||
GList *i;
|
||||
|
||||
DBG("");
|
||||
|
||||
@@ -99,17 +100,18 @@ static void hfp_ag_connect_cb(GIOChannel *io, GError *err, gpointer user_data)
|
||||
return;
|
||||
}
|
||||
|
||||
/* Pick the first voicecall capable modem */
|
||||
modem = modems->data;
|
||||
if (modem == NULL)
|
||||
if (modems == NULL)
|
||||
return;
|
||||
|
||||
DBG("Picked modem %p for emulator", modem);
|
||||
DBG("Using all modems for emulator");
|
||||
|
||||
em = ofono_emulator_create(modem, OFONO_EMULATOR_TYPE_HFP);
|
||||
em = ofono_emulator_create(OFONO_EMULATOR_TYPE_HFP);
|
||||
if (em == NULL)
|
||||
return;
|
||||
|
||||
for (i = modems; i; i = i->next)
|
||||
ofono_emulator_add_modem(em, i->data);
|
||||
|
||||
fd = g_io_channel_unix_get_fd(io);
|
||||
g_io_channel_set_close_on_unref(io, FALSE);
|
||||
|
||||
|
||||
@@ -47,19 +47,18 @@ typedef struct GAtResult GAtResult;
|
||||
#include "bluez5.h"
|
||||
#include "bluetooth.h"
|
||||
|
||||
#ifndef DBUS_TYPE_UNIX_FD
|
||||
#define DBUS_TYPE_UNIX_FD -1
|
||||
#endif
|
||||
|
||||
#define HFP_AG_EXT_PROFILE_PATH "/bluetooth/profile/hfp_ag"
|
||||
#define BT_ADDR_SIZE 18
|
||||
|
||||
#define HFP_AG_DRIVER "hfp-ag-driver"
|
||||
|
||||
static gboolean hfp_ag_enabled;
|
||||
static guint service_watch_id;
|
||||
static guint modemwatch_id;
|
||||
static GList *modems;
|
||||
static GHashTable *sim_hash = NULL;
|
||||
static GHashTable *connection_hash;
|
||||
static struct ofono_emulator *emulator = NULL;
|
||||
|
||||
static int hfp_card_probe(struct ofono_handsfree_card *card,
|
||||
unsigned int vendor, void *data)
|
||||
@@ -72,6 +71,8 @@ static int hfp_card_probe(struct ofono_handsfree_card *card,
|
||||
static void hfp_card_remove(struct ofono_handsfree_card *card)
|
||||
{
|
||||
DBG("");
|
||||
|
||||
emulator = NULL;
|
||||
}
|
||||
|
||||
static void codec_negotiation_done_cb(int err, void *data)
|
||||
@@ -172,9 +173,9 @@ static DBusMessage *profile_new_connection(DBusConnection *conn,
|
||||
struct sockaddr_rc saddr;
|
||||
socklen_t optlen;
|
||||
struct ofono_emulator *em;
|
||||
struct ofono_modem *modem;
|
||||
char local[BT_ADDR_SIZE], remote[BT_ADDR_SIZE];
|
||||
struct ofono_handsfree_card *card;
|
||||
GList *i;
|
||||
int err;
|
||||
|
||||
DBG("Profile handler NewConnection");
|
||||
@@ -202,7 +203,6 @@ static DBusMessage *profile_new_connection(DBusConnection *conn,
|
||||
goto invalid;
|
||||
}
|
||||
|
||||
/* Pick the first voicecall capable modem */
|
||||
if (modems == NULL) {
|
||||
close(fd);
|
||||
return g_dbus_create_error(msg, BLUEZ_ERROR_INTERFACE
|
||||
@@ -210,9 +210,7 @@ static DBusMessage *profile_new_connection(DBusConnection *conn,
|
||||
"No voice call capable modem");
|
||||
}
|
||||
|
||||
modem = modems->data;
|
||||
|
||||
DBG("Picked modem %p for emulator", modem);
|
||||
DBG("Using all modems for emulator.");
|
||||
|
||||
memset(&saddr, 0, sizeof(saddr));
|
||||
optlen = sizeof(saddr);
|
||||
@@ -240,7 +238,7 @@ static DBusMessage *profile_new_connection(DBusConnection *conn,
|
||||
|
||||
bt_ba2str(&saddr.rc_bdaddr, remote);
|
||||
|
||||
em = ofono_emulator_create(modem, OFONO_EMULATOR_TYPE_HFP);
|
||||
em = ofono_emulator_create(OFONO_EMULATOR_TYPE_HFP);
|
||||
if (em == NULL) {
|
||||
close(fd);
|
||||
return g_dbus_create_error(msg, BLUEZ_ERROR_INTERFACE
|
||||
@@ -248,6 +246,10 @@ static DBusMessage *profile_new_connection(DBusConnection *conn,
|
||||
"Not enough resources");
|
||||
}
|
||||
|
||||
for (i = modems; i; i = i->next)
|
||||
ofono_emulator_add_modem(em, i->data);
|
||||
|
||||
emulator = em;
|
||||
ofono_emulator_register(em, fd);
|
||||
|
||||
fd_dup = dup(fd);
|
||||
@@ -367,6 +369,9 @@ static void sim_state_watch(enum ofono_sim_state new_state, void *data)
|
||||
|
||||
modems = g_list_append(modems, modem);
|
||||
|
||||
if (emulator)
|
||||
ofono_emulator_add_modem(emulator, modem);
|
||||
|
||||
if (modems->next != NULL)
|
||||
return;
|
||||
|
||||
@@ -459,29 +464,27 @@ static void call_modemwatch(struct ofono_modem *modem, void *user)
|
||||
modem_watch(modem, TRUE, user);
|
||||
}
|
||||
|
||||
static int hfp_ag_init(void)
|
||||
static void hfp_ag_enable(DBusConnection *conn)
|
||||
{
|
||||
DBusConnection *conn = ofono_dbus_get_connection();
|
||||
int err;
|
||||
|
||||
if (DBUS_TYPE_UNIX_FD < 0)
|
||||
return -EBADF;
|
||||
|
||||
/* Registers External Profile handler */
|
||||
if (!g_dbus_register_interface(conn, HFP_AG_EXT_PROFILE_PATH,
|
||||
BLUEZ_PROFILE_INTERFACE,
|
||||
profile_methods, NULL,
|
||||
NULL, NULL, NULL)) {
|
||||
if (!g_dbus_register_interface(conn,
|
||||
HFP_AG_EXT_PROFILE_PATH,
|
||||
BLUEZ_PROFILE_INTERFACE,
|
||||
profile_methods,
|
||||
NULL, NULL, NULL, NULL)) {
|
||||
ofono_error("Register Profile interface failed: %s",
|
||||
HFP_AG_EXT_PROFILE_PATH);
|
||||
return -EIO;
|
||||
HFP_AG_EXT_PROFILE_PATH);
|
||||
return;
|
||||
}
|
||||
|
||||
err = ofono_handsfree_card_driver_register(&hfp_ag_driver);
|
||||
if (err < 0) {
|
||||
g_dbus_unregister_interface(conn, HFP_AG_EXT_PROFILE_PATH,
|
||||
BLUEZ_PROFILE_INTERFACE);
|
||||
return err;
|
||||
BLUEZ_PROFILE_INTERFACE);
|
||||
ofono_error("Failed to register driver: %d", err);
|
||||
return;
|
||||
}
|
||||
|
||||
sim_hash = g_hash_table_new(g_direct_hash, g_direct_equal);
|
||||
@@ -490,10 +493,65 @@ static int hfp_ag_init(void)
|
||||
__ofono_modem_foreach(call_modemwatch, NULL);
|
||||
|
||||
connection_hash = g_hash_table_new_full(g_str_hash, g_str_equal,
|
||||
g_free, connection_destroy);
|
||||
g_free, connection_destroy);
|
||||
|
||||
ofono_handsfree_audio_ref();
|
||||
|
||||
hfp_ag_enabled = TRUE;
|
||||
}
|
||||
|
||||
static void hfp_ag_disable(DBusConnection *conn)
|
||||
{
|
||||
if (modemwatch_id) {
|
||||
__ofono_modemwatch_remove(modemwatch_id);
|
||||
modemwatch_id = 0;
|
||||
}
|
||||
|
||||
if (connection_hash) {
|
||||
g_hash_table_destroy(connection_hash);
|
||||
connection_hash = NULL;
|
||||
}
|
||||
|
||||
g_list_free(modems);
|
||||
modems = NULL;
|
||||
|
||||
if (sim_hash) {
|
||||
g_hash_table_foreach_remove(sim_hash, sim_watch_remove, NULL);
|
||||
g_hash_table_destroy(sim_hash);
|
||||
sim_hash = NULL;
|
||||
}
|
||||
|
||||
if (hfp_ag_enabled) {
|
||||
g_dbus_unregister_interface(conn, HFP_AG_EXT_PROFILE_PATH,
|
||||
BLUEZ_PROFILE_INTERFACE);
|
||||
ofono_handsfree_card_driver_unregister(&hfp_ag_driver);
|
||||
ofono_handsfree_audio_unref();
|
||||
}
|
||||
|
||||
hfp_ag_enabled = FALSE;
|
||||
}
|
||||
|
||||
static void bluez_connect_cb(DBusConnection *connection, void *user_data)
|
||||
{
|
||||
hfp_ag_enable(connection);
|
||||
}
|
||||
|
||||
static void bluez_disconnect_cb(DBusConnection *connection, void *user_data)
|
||||
{
|
||||
hfp_ag_disable(connection);
|
||||
}
|
||||
|
||||
static int hfp_ag_init(void)
|
||||
{
|
||||
DBusConnection *conn = ofono_dbus_get_connection();
|
||||
|
||||
hfp_ag_enable(conn);
|
||||
|
||||
service_watch_id = g_dbus_add_service_watch(conn, "org.bluez",
|
||||
bluez_connect_cb,
|
||||
bluez_disconnect_cb,
|
||||
NULL, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -501,19 +559,12 @@ static void hfp_ag_exit(void)
|
||||
{
|
||||
DBusConnection *conn = ofono_dbus_get_connection();
|
||||
|
||||
__ofono_modemwatch_remove(modemwatch_id);
|
||||
g_dbus_unregister_interface(conn, HFP_AG_EXT_PROFILE_PATH,
|
||||
BLUEZ_PROFILE_INTERFACE);
|
||||
if (service_watch_id) {
|
||||
g_dbus_remove_watch(conn, service_watch_id);
|
||||
service_watch_id = 0;
|
||||
}
|
||||
|
||||
ofono_handsfree_card_driver_unregister(&hfp_ag_driver);
|
||||
|
||||
g_hash_table_destroy(connection_hash);
|
||||
|
||||
g_list_free(modems);
|
||||
g_hash_table_foreach_remove(sim_hash, sim_watch_remove, NULL);
|
||||
g_hash_table_destroy(sim_hash);
|
||||
|
||||
ofono_handsfree_audio_unref();
|
||||
hfp_ag_disable(conn);
|
||||
}
|
||||
|
||||
OFONO_PLUGIN_DEFINE(hfp_ag_bluez5, "Hands-Free Audio Gateway Profile Plugins",
|
||||
|
||||
@@ -89,6 +89,7 @@ struct sailfish_slot_priv {
|
||||
struct sailfish_cell_info *cellinfo;
|
||||
struct sailfish_cell_info_dbus *cellinfo_dbus;
|
||||
enum sailfish_sim_state sim_state;
|
||||
enum sailfish_slot_flags flags;
|
||||
gulong watch_event_id[WATCH_EVENT_COUNT];
|
||||
char *imei;
|
||||
char *imeisv;
|
||||
@@ -320,6 +321,17 @@ struct sailfish_slot *sailfish_manager_slot_add
|
||||
const char *path, enum ofono_radio_access_mode techs,
|
||||
const char *imei, const char *imeisv,
|
||||
enum sailfish_sim_state sim_state)
|
||||
{
|
||||
return sailfish_manager_slot_add2(m, impl, path, techs, imei, imeisv,
|
||||
sim_state, SAILFISH_SLOT_NO_FLAGS);
|
||||
}
|
||||
|
||||
struct sailfish_slot *sailfish_manager_slot_add2
|
||||
(struct sailfish_slot_manager *m, struct sailfish_slot_impl *impl,
|
||||
const char *path, enum ofono_radio_access_mode techs,
|
||||
const char *imei, const char *imeisv,
|
||||
enum sailfish_sim_state sim_state,
|
||||
enum sailfish_slot_flags flags)
|
||||
{
|
||||
/* Only accept these calls when we are starting! We have been
|
||||
* assuming all along that the number of slots is known right
|
||||
@@ -339,6 +351,7 @@ struct sailfish_slot *sailfish_manager_slot_add
|
||||
s->impl = impl;
|
||||
s->manager = m;
|
||||
s->sim_state = sim_state;
|
||||
s->flags = flags;
|
||||
s->watch = sailfish_watch_new(path);
|
||||
s->siminfo = sailfish_sim_info_new(path);
|
||||
s->siminfo_dbus = sailfish_sim_info_dbus_new(s->siminfo);
|
||||
@@ -649,10 +662,12 @@ static int sailfish_manager_update_modem_paths(struct sailfish_manager_priv *p)
|
||||
mms_slot = sailfish_manager_find_slot_imsi(p, p->mms_imsi);
|
||||
}
|
||||
|
||||
if (mms_slot && mms_slot != slot) {
|
||||
if (mms_slot && (mms_slot != slot ||
|
||||
(slot->flags & SAILFISH_SLOT_SINGLE_CONTEXT))) {
|
||||
/*
|
||||
* Reset default data SIM if another SIM is
|
||||
* temporarily selected for MMS.
|
||||
* Reset default data SIM if
|
||||
* a) another SIM is temporarily selected for MMS; or
|
||||
* b) this slot can't have more than one context active.
|
||||
*/
|
||||
slot = NULL;
|
||||
}
|
||||
|
||||
@@ -51,7 +51,9 @@ struct hfp_codec_info {
|
||||
};
|
||||
|
||||
struct ofono_emulator {
|
||||
struct ofono_atom *atom;
|
||||
GList *atoms;
|
||||
GList *registered_atoms;
|
||||
gboolean emulator_registered;
|
||||
enum ofono_emulator_type type;
|
||||
GAtServer *server;
|
||||
GAtPPP *ppp;
|
||||
@@ -355,10 +357,17 @@ static struct indicator *find_indicator(struct ofono_emulator *em,
|
||||
static struct ofono_call *find_call_with_status(struct ofono_emulator *em,
|
||||
int status)
|
||||
{
|
||||
struct ofono_modem *modem = __ofono_atom_get_modem(em->atom);
|
||||
struct ofono_voicecall *vc;
|
||||
struct ofono_modem *modem;
|
||||
struct ofono_voicecall *vc = NULL;
|
||||
GList *i;
|
||||
|
||||
for (i = em->atoms; i; i = i->next) {
|
||||
modem = __ofono_atom_get_modem(i->data);
|
||||
if ((vc = __ofono_atom_find(OFONO_ATOM_TYPE_VOICECALL, modem)))
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
vc = __ofono_atom_find(OFONO_ATOM_TYPE_VOICECALL, modem);
|
||||
if (vc == NULL)
|
||||
return NULL;
|
||||
|
||||
@@ -1153,7 +1162,20 @@ static void emulator_unregister(struct ofono_atom *atom)
|
||||
struct ofono_emulator *em = __ofono_atom_get_data(atom);
|
||||
GSList *l;
|
||||
|
||||
DBG("%p", em);
|
||||
DBG("%p (atom %p)", em, atom);
|
||||
|
||||
em->registered_atoms = g_list_remove(em->registered_atoms, atom);
|
||||
if (em->registered_atoms)
|
||||
return;
|
||||
|
||||
if (!em->emulator_registered) {
|
||||
DBG("emulator already unregistered");
|
||||
return;
|
||||
}
|
||||
|
||||
em->emulator_registered = FALSE;
|
||||
|
||||
DBG("%p no more atoms registered", em);
|
||||
|
||||
if (em->callsetup_source) {
|
||||
g_source_remove(em->callsetup_source);
|
||||
@@ -1185,12 +1207,27 @@ static void emulator_unregister(struct ofono_atom *atom)
|
||||
em->card = NULL;
|
||||
}
|
||||
|
||||
static void emulator_register_atom(struct ofono_emulator *em, struct ofono_atom *atom)
|
||||
{
|
||||
if (!g_list_find(em->registered_atoms, atom)) {
|
||||
em->registered_atoms = g_list_append(em->registered_atoms, atom);
|
||||
DBG("%p", atom);
|
||||
__ofono_atom_register(atom, emulator_unregister);
|
||||
}
|
||||
}
|
||||
|
||||
void ofono_emulator_register(struct ofono_emulator *em, int fd)
|
||||
{
|
||||
GIOChannel *io;
|
||||
GList *i;
|
||||
|
||||
DBG("%p, %d", em, fd);
|
||||
|
||||
if (em->emulator_registered) {
|
||||
DBG("emulator already registered");
|
||||
return;
|
||||
}
|
||||
|
||||
if (fd < 0)
|
||||
return;
|
||||
|
||||
@@ -1240,7 +1277,8 @@ void ofono_emulator_register(struct ofono_emulator *em, int fd)
|
||||
g_at_server_register(em->server, "+BCS", bcs_cb, em, NULL);
|
||||
}
|
||||
|
||||
__ofono_atom_register(em->atom, emulator_unregister);
|
||||
for (i = em->atoms; i; i = i->next)
|
||||
emulator_register_atom(em, i->data);
|
||||
|
||||
switch (em->type) {
|
||||
case OFONO_EMULATOR_TYPE_DUN:
|
||||
@@ -1254,31 +1292,41 @@ void ofono_emulator_register(struct ofono_emulator *em, int fd)
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
em->emulator_registered = TRUE;
|
||||
}
|
||||
|
||||
static void emulator_free(struct ofono_emulator *em)
|
||||
{
|
||||
g_assert(!em->atoms);
|
||||
|
||||
DBG("free emulator %p", em);
|
||||
if (em->registered_atoms)
|
||||
g_list_free(em->registered_atoms);
|
||||
g_free(em);
|
||||
}
|
||||
|
||||
static void emulator_remove(struct ofono_atom *atom)
|
||||
{
|
||||
struct ofono_emulator *em = __ofono_atom_get_data(atom);
|
||||
|
||||
DBG("atom: %p", atom);
|
||||
DBG("remove atom %p", atom);
|
||||
em->atoms = g_list_remove(em->atoms, atom);
|
||||
|
||||
g_free(em);
|
||||
if (!em->atoms)
|
||||
emulator_free(em);
|
||||
}
|
||||
|
||||
struct ofono_emulator *ofono_emulator_create(struct ofono_modem *modem,
|
||||
enum ofono_emulator_type type)
|
||||
struct ofono_emulator *ofono_emulator_create(enum ofono_emulator_type type)
|
||||
{
|
||||
struct ofono_emulator *em;
|
||||
enum ofono_atom_type atom_t;
|
||||
|
||||
DBG("modem: %p, type: %d", modem, type);
|
||||
|
||||
if (type == OFONO_EMULATOR_TYPE_DUN)
|
||||
atom_t = OFONO_ATOM_TYPE_EMULATOR_DUN;
|
||||
else if (type == OFONO_EMULATOR_TYPE_HFP)
|
||||
atom_t = OFONO_ATOM_TYPE_EMULATOR_HFP;
|
||||
else
|
||||
if (type != OFONO_EMULATOR_TYPE_DUN && type != OFONO_EMULATOR_TYPE_HFP) {
|
||||
DBG("unsupported emulator type %d", type);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
DBG("create emulator of type %d", type);
|
||||
|
||||
em = g_try_new0(struct ofono_emulator, 1);
|
||||
|
||||
@@ -1296,15 +1344,59 @@ struct ofono_emulator *ofono_emulator_create(struct ofono_modem *modem,
|
||||
em->events_mode = 3; /* default mode is forwarding events */
|
||||
em->cmee_mode = 0; /* CME ERROR disabled by default */
|
||||
|
||||
em->atom = __ofono_modem_add_atom_offline(modem, atom_t,
|
||||
emulator_remove, em);
|
||||
|
||||
return em;
|
||||
}
|
||||
|
||||
void ofono_emulator_add_modem(struct ofono_emulator *em,
|
||||
struct ofono_modem *modem)
|
||||
{
|
||||
struct ofono_atom *atom;
|
||||
enum ofono_atom_type atom_t;
|
||||
|
||||
if (em->type == OFONO_EMULATOR_TYPE_DUN)
|
||||
atom_t = OFONO_ATOM_TYPE_EMULATOR_DUN;
|
||||
else
|
||||
atom_t = OFONO_ATOM_TYPE_EMULATOR_HFP;
|
||||
|
||||
if ((atom = __ofono_modem_find_atom(modem, atom_t))) {
|
||||
if (g_list_find(em->atoms, atom)) {
|
||||
DBG("modem %p already added", modem);
|
||||
goto register_atom;
|
||||
}
|
||||
}
|
||||
|
||||
DBG("%p", modem);
|
||||
|
||||
atom = __ofono_modem_add_atom_offline(modem, atom_t,
|
||||
emulator_remove, em);
|
||||
em->atoms = g_list_append(em->atoms, atom);
|
||||
|
||||
register_atom:
|
||||
if (em->emulator_registered)
|
||||
emulator_register_atom(em, atom);
|
||||
}
|
||||
|
||||
void ofono_emulator_remove(struct ofono_emulator *em)
|
||||
{
|
||||
__ofono_atom_free(em->atom);
|
||||
GList *remove_list;
|
||||
GList *i;
|
||||
|
||||
DBG("");
|
||||
|
||||
/* If emulator has atoms we make a copy of the atom list here,
|
||||
* as the list is modified when the atoms are being destroyed.
|
||||
* When last atom is gone struct ofono_emulator is freed as
|
||||
* well (in emulator_remove()). */
|
||||
if (em->atoms) {
|
||||
remove_list = g_list_copy(em->atoms);
|
||||
for (i = remove_list; i; i = i->next) {
|
||||
DBG("free atom %p", i->data);
|
||||
__ofono_atom_free(i->data);
|
||||
}
|
||||
g_list_free(remove_list);
|
||||
} else {
|
||||
emulator_free(em);
|
||||
}
|
||||
}
|
||||
|
||||
void ofono_emulator_send_final(struct ofono_emulator *em,
|
||||
|
||||
@@ -912,6 +912,7 @@ void ofono_handsfree_audio_unref(void)
|
||||
if (agent) {
|
||||
agent_release(agent);
|
||||
agent_free(agent);
|
||||
agent = NULL;
|
||||
}
|
||||
|
||||
__ofono_handsfree_audio_manager_cleanup();
|
||||
|
||||
Reference in New Issue
Block a user