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_LEGACY_IMEI_QUERY FALSE
|
||||||
#define RILMODEM_DEFAULT_RADIO_POWER_CYCLE TRUE
|
#define RILMODEM_DEFAULT_RADIO_POWER_CYCLE TRUE
|
||||||
#define RILMODEM_DEFAULT_CONFIRM_RADIO_POWER_ON TRUE
|
#define RILMODEM_DEFAULT_CONFIRM_RADIO_POWER_ON TRUE
|
||||||
|
#define RILMODEM_DEFAULT_SLOT_FLAGS SAILFISH_SLOT_NO_FLAGS
|
||||||
|
|
||||||
/* RIL socket transport name and parameters */
|
/* RIL socket transport name and parameters */
|
||||||
#define RIL_TRANSPORT_SOCKET "socket"
|
#define RIL_TRANSPORT_SOCKET "socket"
|
||||||
@@ -130,6 +131,7 @@
|
|||||||
#define RILCONF_LEGACY_IMEI_QUERY "legacyImeiQuery"
|
#define RILCONF_LEGACY_IMEI_QUERY "legacyImeiQuery"
|
||||||
#define RILCONF_RADIO_POWER_CYCLE "radioPowerCycle"
|
#define RILCONF_RADIO_POWER_CYCLE "radioPowerCycle"
|
||||||
#define RILCONF_CONFIRM_RADIO_POWER_ON "confirmRadioPowerOn"
|
#define RILCONF_CONFIRM_RADIO_POWER_ON "confirmRadioPowerOn"
|
||||||
|
#define RILCONF_SINGLE_DATA_CONTEXT "singleDataContext"
|
||||||
|
|
||||||
/* Modem error ids */
|
/* Modem error ids */
|
||||||
#define RIL_ERROR_ID_RILD_RESTART "rild-restart"
|
#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_vendor_hook *vendor_hook;
|
||||||
struct ril_data *data;
|
struct ril_data *data;
|
||||||
gboolean legacy_imei_query;
|
gboolean legacy_imei_query;
|
||||||
|
enum sailfish_slot_flags slot_flags;
|
||||||
guint start_timeout;
|
guint start_timeout;
|
||||||
guint start_timeout_id;
|
guint start_timeout_id;
|
||||||
MceDisplay *display;
|
MceDisplay *display;
|
||||||
@@ -1039,9 +1042,10 @@ static void ril_plugin_slot_connected(ril_slot *slot)
|
|||||||
slot->start_timeout_id = 0;
|
slot->start_timeout_id = 0;
|
||||||
|
|
||||||
/* Register this slot with the sailfish manager plugin */
|
/* 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->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);
|
sailfish_manager_set_cell_info(slot->handle, slot->cell_info);
|
||||||
|
|
||||||
/* Check if this was the last slot we were waiting for */
|
/* 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;
|
RILMODEM_DEFAULT_QUERY_AVAILABLE_BAND_MODE;
|
||||||
slot->timeout = RILMODEM_DEFAULT_TIMEOUT;
|
slot->timeout = RILMODEM_DEFAULT_TIMEOUT;
|
||||||
slot->sim_flags = RILMODEM_DEFAULT_SIM_FLAGS;
|
slot->sim_flags = RILMODEM_DEFAULT_SIM_FLAGS;
|
||||||
|
slot->slot_flags = RILMODEM_DEFAULT_SLOT_FLAGS;
|
||||||
slot->legacy_imei_query = RILMODEM_DEFAULT_LEGACY_IMEI_QUERY;
|
slot->legacy_imei_query = RILMODEM_DEFAULT_LEGACY_IMEI_QUERY;
|
||||||
slot->start_timeout = RILMODEM_DEFAULT_START_TIMEOUT;
|
slot->start_timeout = RILMODEM_DEFAULT_START_TIMEOUT;
|
||||||
slot->data_opt.allow_data = RILMODEM_DEFAULT_DATA_OPT;
|
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;
|
ril_slot *slot;
|
||||||
struct ril_slot_config *config;
|
struct ril_slot_config *config;
|
||||||
|
gboolean bval;
|
||||||
int ival;
|
int ival;
|
||||||
char *sval;
|
char *sval;
|
||||||
char **strv;
|
char **strv;
|
||||||
@@ -1540,6 +1546,14 @@ static ril_slot *ril_plugin_parse_config_group(GKeyFile *file,
|
|||||||
config->confirm_radio_power_on ? "on" : "off");
|
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 */
|
/* uiccWorkaround */
|
||||||
if (ril_config_get_flag(file, group, RILCONF_UICC_WORKAROUND,
|
if (ril_config_get_flag(file, group, RILCONF_UICC_WORKAROUND,
|
||||||
RIL_SIM_CARD_V9_UICC_SUBSCRIPTION_WORKAROUND,
|
RIL_SIM_CARD_V9_UICC_SUBSCRIPTION_WORKAROUND,
|
||||||
|
|||||||
@@ -240,3 +240,12 @@ socket=/dev/socket/rild
|
|||||||
# The default is true for historical reasons
|
# The default is true for historical reasons
|
||||||
#
|
#
|
||||||
#confirmRadioPowerOn=true
|
#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);
|
unsigned int len = sizeof(saddr);
|
||||||
int fd;
|
int fd;
|
||||||
struct ofono_emulator *em;
|
struct ofono_emulator *em;
|
||||||
struct ofono_modem *modem;
|
GList *i;
|
||||||
|
|
||||||
if (cond != G_IO_IN)
|
if (cond != G_IO_IN)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@@ -63,15 +63,16 @@ static gboolean on_socket_connected(GIOChannel *chan, GIOCondition cond,
|
|||||||
if (fd == -1)
|
if (fd == -1)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
/* Pick the first powered modem */
|
DBG("Using all modems for emulator.");
|
||||||
modem = modems->data;
|
|
||||||
DBG("Picked modem %p for emulator", modem);
|
|
||||||
|
|
||||||
em = ofono_emulator_create(modem, GPOINTER_TO_INT(user));
|
em = ofono_emulator_create(GPOINTER_TO_INT(user));
|
||||||
if (em == NULL)
|
|
||||||
close(fd);
|
if (em) {
|
||||||
else
|
for (i = modems; i; i = i->next)
|
||||||
|
ofono_emulator_add_modem(em, i->data);
|
||||||
ofono_emulator_register(em, fd);
|
ofono_emulator_register(em, fd);
|
||||||
|
} else
|
||||||
|
close(fd);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -68,8 +68,9 @@ typedef void (*ofono_emulator_request_cb_t)(struct ofono_emulator *em,
|
|||||||
struct ofono_emulator_request *req,
|
struct ofono_emulator_request *req,
|
||||||
void *data);
|
void *data);
|
||||||
|
|
||||||
struct ofono_emulator *ofono_emulator_create(struct ofono_modem *modem,
|
struct ofono_emulator *ofono_emulator_create(enum ofono_emulator_type type);
|
||||||
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);
|
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)
|
typedef void (*sailfish_slot_manager_impl_cb_t)
|
||||||
(struct sailfish_slot_manager_impl *impl, void *user_data);
|
(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 {
|
typedef struct sailfish_slot {
|
||||||
const char *path;
|
const char *path;
|
||||||
const char *imei;
|
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 *path, enum ofono_radio_access_mode techs,
|
||||||
const char *imei, const char *imeisv,
|
const char *imei, const char *imeisv,
|
||||||
enum sailfish_sim_state sim_state);
|
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_imei_obtained(struct sailfish_slot *s, const char *imei);
|
||||||
void sailfish_manager_imeisv_obtained(struct sailfish_slot *s,
|
void sailfish_manager_imeisv_obtained(struct sailfish_slot *s,
|
||||||
const char *imeisv);
|
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)
|
static void dun_gw_connect_cb(GIOChannel *io, GError *err, gpointer user_data)
|
||||||
{
|
{
|
||||||
struct ofono_emulator *em = user_data;
|
struct ofono_emulator *em = user_data;
|
||||||
struct ofono_modem *modem;
|
GList *i;
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
DBG("");
|
DBG("");
|
||||||
@@ -90,16 +90,17 @@ static void dun_gw_connect_cb(GIOChannel *io, GError *err, gpointer user_data)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Pick the first powered modem */
|
DBG("Using all modems for emulator");
|
||||||
modem = modems->data;
|
|
||||||
DBG("Picked modem %p for emulator", modem);
|
|
||||||
|
|
||||||
em = ofono_emulator_create(modem, OFONO_EMULATOR_TYPE_DUN);
|
em = ofono_emulator_create(OFONO_EMULATOR_TYPE_DUN);
|
||||||
if (em == NULL) {
|
if (em == NULL) {
|
||||||
g_io_channel_shutdown(io, TRUE, NULL);
|
g_io_channel_shutdown(io, TRUE, NULL);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (i = modems; i; i = i->next)
|
||||||
|
ofono_emulator_add_modem(em, i->data);
|
||||||
|
|
||||||
fd = g_io_channel_unix_get_fd(io);
|
fd = g_io_channel_unix_get_fd(io);
|
||||||
g_io_channel_set_close_on_unref(io, FALSE);
|
g_io_channel_set_close_on_unref(io, FALSE);
|
||||||
|
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ static DBusMessage *profile_new_connection(DBusConnection *conn,
|
|||||||
const char *device;
|
const char *device;
|
||||||
int fd;
|
int fd;
|
||||||
struct ofono_emulator *em;
|
struct ofono_emulator *em;
|
||||||
struct ofono_modem *modem;
|
GList *i;
|
||||||
|
|
||||||
DBG("Profile handler NewConnection");
|
DBG("Profile handler NewConnection");
|
||||||
|
|
||||||
@@ -80,7 +80,6 @@ static DBusMessage *profile_new_connection(DBusConnection *conn,
|
|||||||
|
|
||||||
DBG("%s", device);
|
DBG("%s", device);
|
||||||
|
|
||||||
/* Pick the first powered modem */
|
|
||||||
if (modems == NULL) {
|
if (modems == NULL) {
|
||||||
close(fd);
|
close(fd);
|
||||||
return g_dbus_create_error(msg, BLUEZ_ERROR_INTERFACE
|
return g_dbus_create_error(msg, BLUEZ_ERROR_INTERFACE
|
||||||
@@ -88,10 +87,9 @@ static DBusMessage *profile_new_connection(DBusConnection *conn,
|
|||||||
"No GPRS capable modem");
|
"No GPRS capable modem");
|
||||||
}
|
}
|
||||||
|
|
||||||
modem = modems->data;
|
DBG("Using all modems for emulator.");
|
||||||
DBG("Picked modem %p for emulator", modem);
|
|
||||||
|
|
||||||
em = ofono_emulator_create(modem, OFONO_EMULATOR_TYPE_DUN);
|
em = ofono_emulator_create(OFONO_EMULATOR_TYPE_DUN);
|
||||||
if (em == NULL) {
|
if (em == NULL) {
|
||||||
close(fd);
|
close(fd);
|
||||||
return g_dbus_create_error(msg, BLUEZ_ERROR_INTERFACE
|
return g_dbus_create_error(msg, BLUEZ_ERROR_INTERFACE
|
||||||
@@ -99,6 +97,9 @@ static DBusMessage *profile_new_connection(DBusConnection *conn,
|
|||||||
"Not enough resources");
|
"Not enough resources");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (i = modems; i; i = i->next)
|
||||||
|
ofono_emulator_add_modem(em, i->data);
|
||||||
|
|
||||||
ofono_emulator_register(em, fd);
|
ofono_emulator_register(em, fd);
|
||||||
|
|
||||||
return dbus_message_new_method_return(msg);
|
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_modem *modem;
|
||||||
struct ofono_emulator *em;
|
struct ofono_emulator *em;
|
||||||
int fd;
|
int fd;
|
||||||
|
GList *i;
|
||||||
|
|
||||||
DBG("");
|
DBG("");
|
||||||
|
|
||||||
@@ -99,17 +100,18 @@ static void hfp_ag_connect_cb(GIOChannel *io, GError *err, gpointer user_data)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Pick the first voicecall capable modem */
|
if (modems == NULL)
|
||||||
modem = modems->data;
|
|
||||||
if (modem == NULL)
|
|
||||||
return;
|
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)
|
if (em == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
for (i = modems; i; i = i->next)
|
||||||
|
ofono_emulator_add_modem(em, i->data);
|
||||||
|
|
||||||
fd = g_io_channel_unix_get_fd(io);
|
fd = g_io_channel_unix_get_fd(io);
|
||||||
g_io_channel_set_close_on_unref(io, FALSE);
|
g_io_channel_set_close_on_unref(io, FALSE);
|
||||||
|
|
||||||
|
|||||||
@@ -47,19 +47,18 @@ typedef struct GAtResult GAtResult;
|
|||||||
#include "bluez5.h"
|
#include "bluez5.h"
|
||||||
#include "bluetooth.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 HFP_AG_EXT_PROFILE_PATH "/bluetooth/profile/hfp_ag"
|
||||||
#define BT_ADDR_SIZE 18
|
#define BT_ADDR_SIZE 18
|
||||||
|
|
||||||
#define HFP_AG_DRIVER "hfp-ag-driver"
|
#define HFP_AG_DRIVER "hfp-ag-driver"
|
||||||
|
|
||||||
|
static gboolean hfp_ag_enabled;
|
||||||
|
static guint service_watch_id;
|
||||||
static guint modemwatch_id;
|
static guint modemwatch_id;
|
||||||
static GList *modems;
|
static GList *modems;
|
||||||
static GHashTable *sim_hash = NULL;
|
static GHashTable *sim_hash = NULL;
|
||||||
static GHashTable *connection_hash;
|
static GHashTable *connection_hash;
|
||||||
|
static struct ofono_emulator *emulator = NULL;
|
||||||
|
|
||||||
static int hfp_card_probe(struct ofono_handsfree_card *card,
|
static int hfp_card_probe(struct ofono_handsfree_card *card,
|
||||||
unsigned int vendor, void *data)
|
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)
|
static void hfp_card_remove(struct ofono_handsfree_card *card)
|
||||||
{
|
{
|
||||||
DBG("");
|
DBG("");
|
||||||
|
|
||||||
|
emulator = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void codec_negotiation_done_cb(int err, void *data)
|
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;
|
struct sockaddr_rc saddr;
|
||||||
socklen_t optlen;
|
socklen_t optlen;
|
||||||
struct ofono_emulator *em;
|
struct ofono_emulator *em;
|
||||||
struct ofono_modem *modem;
|
|
||||||
char local[BT_ADDR_SIZE], remote[BT_ADDR_SIZE];
|
char local[BT_ADDR_SIZE], remote[BT_ADDR_SIZE];
|
||||||
struct ofono_handsfree_card *card;
|
struct ofono_handsfree_card *card;
|
||||||
|
GList *i;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
DBG("Profile handler NewConnection");
|
DBG("Profile handler NewConnection");
|
||||||
@@ -202,7 +203,6 @@ static DBusMessage *profile_new_connection(DBusConnection *conn,
|
|||||||
goto invalid;
|
goto invalid;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Pick the first voicecall capable modem */
|
|
||||||
if (modems == NULL) {
|
if (modems == NULL) {
|
||||||
close(fd);
|
close(fd);
|
||||||
return g_dbus_create_error(msg, BLUEZ_ERROR_INTERFACE
|
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");
|
"No voice call capable modem");
|
||||||
}
|
}
|
||||||
|
|
||||||
modem = modems->data;
|
DBG("Using all modems for emulator.");
|
||||||
|
|
||||||
DBG("Picked modem %p for emulator", modem);
|
|
||||||
|
|
||||||
memset(&saddr, 0, sizeof(saddr));
|
memset(&saddr, 0, sizeof(saddr));
|
||||||
optlen = sizeof(saddr);
|
optlen = sizeof(saddr);
|
||||||
@@ -240,7 +238,7 @@ static DBusMessage *profile_new_connection(DBusConnection *conn,
|
|||||||
|
|
||||||
bt_ba2str(&saddr.rc_bdaddr, remote);
|
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) {
|
if (em == NULL) {
|
||||||
close(fd);
|
close(fd);
|
||||||
return g_dbus_create_error(msg, BLUEZ_ERROR_INTERFACE
|
return g_dbus_create_error(msg, BLUEZ_ERROR_INTERFACE
|
||||||
@@ -248,6 +246,10 @@ static DBusMessage *profile_new_connection(DBusConnection *conn,
|
|||||||
"Not enough resources");
|
"Not enough resources");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (i = modems; i; i = i->next)
|
||||||
|
ofono_emulator_add_modem(em, i->data);
|
||||||
|
|
||||||
|
emulator = em;
|
||||||
ofono_emulator_register(em, fd);
|
ofono_emulator_register(em, fd);
|
||||||
|
|
||||||
fd_dup = dup(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);
|
modems = g_list_append(modems, modem);
|
||||||
|
|
||||||
|
if (emulator)
|
||||||
|
ofono_emulator_add_modem(emulator, modem);
|
||||||
|
|
||||||
if (modems->next != NULL)
|
if (modems->next != NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -459,29 +464,27 @@ static void call_modemwatch(struct ofono_modem *modem, void *user)
|
|||||||
modem_watch(modem, TRUE, 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;
|
int err;
|
||||||
|
|
||||||
if (DBUS_TYPE_UNIX_FD < 0)
|
|
||||||
return -EBADF;
|
|
||||||
|
|
||||||
/* Registers External Profile handler */
|
/* Registers External Profile handler */
|
||||||
if (!g_dbus_register_interface(conn, HFP_AG_EXT_PROFILE_PATH,
|
if (!g_dbus_register_interface(conn,
|
||||||
BLUEZ_PROFILE_INTERFACE,
|
HFP_AG_EXT_PROFILE_PATH,
|
||||||
profile_methods, NULL,
|
BLUEZ_PROFILE_INTERFACE,
|
||||||
NULL, NULL, NULL)) {
|
profile_methods,
|
||||||
|
NULL, NULL, NULL, NULL)) {
|
||||||
ofono_error("Register Profile interface failed: %s",
|
ofono_error("Register Profile interface failed: %s",
|
||||||
HFP_AG_EXT_PROFILE_PATH);
|
HFP_AG_EXT_PROFILE_PATH);
|
||||||
return -EIO;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = ofono_handsfree_card_driver_register(&hfp_ag_driver);
|
err = ofono_handsfree_card_driver_register(&hfp_ag_driver);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
g_dbus_unregister_interface(conn, HFP_AG_EXT_PROFILE_PATH,
|
g_dbus_unregister_interface(conn, HFP_AG_EXT_PROFILE_PATH,
|
||||||
BLUEZ_PROFILE_INTERFACE);
|
BLUEZ_PROFILE_INTERFACE);
|
||||||
return err;
|
ofono_error("Failed to register driver: %d", err);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
sim_hash = g_hash_table_new(g_direct_hash, g_direct_equal);
|
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);
|
__ofono_modem_foreach(call_modemwatch, NULL);
|
||||||
|
|
||||||
connection_hash = g_hash_table_new_full(g_str_hash, g_str_equal,
|
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();
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -501,19 +559,12 @@ static void hfp_ag_exit(void)
|
|||||||
{
|
{
|
||||||
DBusConnection *conn = ofono_dbus_get_connection();
|
DBusConnection *conn = ofono_dbus_get_connection();
|
||||||
|
|
||||||
__ofono_modemwatch_remove(modemwatch_id);
|
if (service_watch_id) {
|
||||||
g_dbus_unregister_interface(conn, HFP_AG_EXT_PROFILE_PATH,
|
g_dbus_remove_watch(conn, service_watch_id);
|
||||||
BLUEZ_PROFILE_INTERFACE);
|
service_watch_id = 0;
|
||||||
|
}
|
||||||
|
|
||||||
ofono_handsfree_card_driver_unregister(&hfp_ag_driver);
|
hfp_ag_disable(conn);
|
||||||
|
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
OFONO_PLUGIN_DEFINE(hfp_ag_bluez5, "Hands-Free Audio Gateway Profile Plugins",
|
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 *cellinfo;
|
||||||
struct sailfish_cell_info_dbus *cellinfo_dbus;
|
struct sailfish_cell_info_dbus *cellinfo_dbus;
|
||||||
enum sailfish_sim_state sim_state;
|
enum sailfish_sim_state sim_state;
|
||||||
|
enum sailfish_slot_flags flags;
|
||||||
gulong watch_event_id[WATCH_EVENT_COUNT];
|
gulong watch_event_id[WATCH_EVENT_COUNT];
|
||||||
char *imei;
|
char *imei;
|
||||||
char *imeisv;
|
char *imeisv;
|
||||||
@@ -320,6 +321,17 @@ struct sailfish_slot *sailfish_manager_slot_add
|
|||||||
const char *path, enum ofono_radio_access_mode techs,
|
const char *path, enum ofono_radio_access_mode techs,
|
||||||
const char *imei, const char *imeisv,
|
const char *imei, const char *imeisv,
|
||||||
enum sailfish_sim_state sim_state)
|
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
|
/* Only accept these calls when we are starting! We have been
|
||||||
* assuming all along that the number of slots is known right
|
* 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->impl = impl;
|
||||||
s->manager = m;
|
s->manager = m;
|
||||||
s->sim_state = sim_state;
|
s->sim_state = sim_state;
|
||||||
|
s->flags = flags;
|
||||||
s->watch = sailfish_watch_new(path);
|
s->watch = sailfish_watch_new(path);
|
||||||
s->siminfo = sailfish_sim_info_new(path);
|
s->siminfo = sailfish_sim_info_new(path);
|
||||||
s->siminfo_dbus = sailfish_sim_info_dbus_new(s->siminfo);
|
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);
|
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
|
* Reset default data SIM if
|
||||||
* temporarily selected for MMS.
|
* a) another SIM is temporarily selected for MMS; or
|
||||||
|
* b) this slot can't have more than one context active.
|
||||||
*/
|
*/
|
||||||
slot = NULL;
|
slot = NULL;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,7 +51,9 @@ struct hfp_codec_info {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct ofono_emulator {
|
struct ofono_emulator {
|
||||||
struct ofono_atom *atom;
|
GList *atoms;
|
||||||
|
GList *registered_atoms;
|
||||||
|
gboolean emulator_registered;
|
||||||
enum ofono_emulator_type type;
|
enum ofono_emulator_type type;
|
||||||
GAtServer *server;
|
GAtServer *server;
|
||||||
GAtPPP *ppp;
|
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,
|
static struct ofono_call *find_call_with_status(struct ofono_emulator *em,
|
||||||
int status)
|
int status)
|
||||||
{
|
{
|
||||||
struct ofono_modem *modem = __ofono_atom_get_modem(em->atom);
|
struct ofono_modem *modem;
|
||||||
struct ofono_voicecall *vc;
|
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)
|
if (vc == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
@@ -1153,7 +1162,20 @@ static void emulator_unregister(struct ofono_atom *atom)
|
|||||||
struct ofono_emulator *em = __ofono_atom_get_data(atom);
|
struct ofono_emulator *em = __ofono_atom_get_data(atom);
|
||||||
GSList *l;
|
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) {
|
if (em->callsetup_source) {
|
||||||
g_source_remove(em->callsetup_source);
|
g_source_remove(em->callsetup_source);
|
||||||
@@ -1185,12 +1207,27 @@ static void emulator_unregister(struct ofono_atom *atom)
|
|||||||
em->card = NULL;
|
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)
|
void ofono_emulator_register(struct ofono_emulator *em, int fd)
|
||||||
{
|
{
|
||||||
GIOChannel *io;
|
GIOChannel *io;
|
||||||
|
GList *i;
|
||||||
|
|
||||||
DBG("%p, %d", em, fd);
|
DBG("%p, %d", em, fd);
|
||||||
|
|
||||||
|
if (em->emulator_registered) {
|
||||||
|
DBG("emulator already registered");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
return;
|
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);
|
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) {
|
switch (em->type) {
|
||||||
case OFONO_EMULATOR_TYPE_DUN:
|
case OFONO_EMULATOR_TYPE_DUN:
|
||||||
@@ -1254,31 +1292,41 @@ void ofono_emulator_register(struct ofono_emulator *em, int fd)
|
|||||||
default:
|
default:
|
||||||
break;
|
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)
|
static void emulator_remove(struct ofono_atom *atom)
|
||||||
{
|
{
|
||||||
struct ofono_emulator *em = __ofono_atom_get_data(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,
|
struct ofono_emulator *ofono_emulator_create(enum ofono_emulator_type type)
|
||||||
enum ofono_emulator_type type)
|
|
||||||
{
|
{
|
||||||
struct ofono_emulator *em;
|
struct ofono_emulator *em;
|
||||||
enum ofono_atom_type atom_t;
|
|
||||||
|
|
||||||
DBG("modem: %p, type: %d", modem, type);
|
if (type != OFONO_EMULATOR_TYPE_DUN && type != OFONO_EMULATOR_TYPE_HFP) {
|
||||||
|
DBG("unsupported emulator type %d", 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
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
DBG("create emulator of type %d", type);
|
||||||
|
|
||||||
em = g_try_new0(struct ofono_emulator, 1);
|
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->events_mode = 3; /* default mode is forwarding events */
|
||||||
em->cmee_mode = 0; /* CME ERROR disabled by default */
|
em->cmee_mode = 0; /* CME ERROR disabled by default */
|
||||||
|
|
||||||
em->atom = __ofono_modem_add_atom_offline(modem, atom_t,
|
|
||||||
emulator_remove, em);
|
|
||||||
|
|
||||||
return 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)
|
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,
|
void ofono_emulator_send_final(struct ofono_emulator *em,
|
||||||
|
|||||||
@@ -912,6 +912,7 @@ void ofono_handsfree_audio_unref(void)
|
|||||||
if (agent) {
|
if (agent) {
|
||||||
agent_release(agent);
|
agent_release(agent);
|
||||||
agent_free(agent);
|
agent_free(agent);
|
||||||
|
agent = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
__ofono_handsfree_audio_manager_cleanup();
|
__ofono_handsfree_audio_manager_cleanup();
|
||||||
|
|||||||
Reference in New Issue
Block a user