[-]
[+]
|
Changed |
_service:tar_git:ofono.changes
|
|
[-]
[+]
|
Changed |
_service:tar_git:ofono.spec
^
|
|
[-]
[+]
|
Changed |
_service
^
|
@@ -2,6 +2,6 @@
<service name="tar_git">
<param name="url">https://git.merproject.org/slava/ofono.git</param>
<param name="branch">master</param>
- <param name="revision">c5286fee</param>
+ <param name="revision">1a25047</param>
</service>
</services>
|
[-]
[+]
|
Changed |
_service:tar_git:ofono-1.18+git7.tar.bz2/ofono/drivers/ril/ril_data.c
^
|
@@ -594,11 +594,11 @@
struct ril_data_priv *priv = req->data->priv;
DBG_(req->data, "canceling %s request %p", req->name, req);
+ if (req->cancel) {
+ req->cancel(req);
+ }
if (priv->pending_req == req) {
/* Request has been submitted already */
- if (req->cancel) {
- req->cancel(req);
- }
priv->pending_req = NULL;
} else if (priv->req_queue == req) {
/* It's the first one in the queue */
@@ -681,14 +681,11 @@
static void ril_data_call_setup_cancel(struct ril_data_request *req)
{
- if (req->pending_id) {
- grilio_queue_cancel_request(req->data->priv->q,
- req->pending_id, FALSE);
- req->pending_id = 0;
- if (req->cb.setup) {
- req->cb.setup(req->data, GRILIO_STATUS_CANCELLED,
- NULL, req->arg);
- }
+ ril_data_request_cancel_io(req);
+ if (req->cb.setup) {
+ ril_data_call_setup_cb_t cb = req->cb.setup;
+ req->cb.setup = NULL;
+ cb(req->data, GRILIO_STATUS_CANCELLED, NULL, req->arg);
}
}
@@ -854,14 +851,11 @@
static void ril_data_call_deact_cancel(struct ril_data_request *req)
{
- if (req->pending_id) {
- grilio_queue_cancel_request(req->data->priv->q,
- req->pending_id, FALSE);
- req->pending_id = 0;
- if (req->cb.setup) {
- req->cb.deact(req->data, GRILIO_STATUS_CANCELLED,
- req->arg);
- }
+ ril_data_request_cancel_io(req);
+ if (req->cb.deact) {
+ ril_data_call_deactivate_cb_t cb = req->cb.deact;
+ req->cb.deact = NULL;
+ cb(req->data, GRILIO_STATUS_CANCELLED, req->arg);
}
}
|
[-]
[+]
|
Changed |
_service:tar_git:ofono-1.18+git7.tar.bz2/ofono/drivers/ril/ril_network.c
^
|
@@ -436,9 +436,30 @@
{
struct ril_sim_settings *settings = self->settings;
struct ril_network_priv *priv = self->priv;
- const enum ofono_radio_access_mode pref_mode = priv->max_pref_mode ?
- MIN(settings->pref_mode, priv->max_pref_mode) :
- settings->pref_mode;
+
+ /*
+ * On dual-SIM phones such as Jolla C only one slot at a time
+ * is allowed to use LTE. Even if the slot which has been using
+ * LTE gets powered off, we still need to explicitely set its
+ * preferred mode to GSM, to make LTE machinery available to
+ * the other slot. This sort of behaviour might not be necessary
+ * on some hardware and can (should) be made configurable when
+ * it becomes necessary.
+ */
+ const enum ofono_radio_access_mode max_pref_mode =
+ (priv->radio->state == RADIO_STATE_ON) ? priv->max_pref_mode :
+ OFONO_RADIO_ACCESS_MODE_GSM;
+
+ /*
+ * OFONO_RADIO_ACCESS_MODE_ANY is zero. If both pref_mode
+ * and max_pref_mode are not ANY, we pick the smallest value.
+ * Otherwise we take any non-zero value if there is one.
+ */
+ const enum ofono_radio_access_mode pref_mode =
+ (settings->pref_mode && max_pref_mode) ?
+ MIN(settings->pref_mode, max_pref_mode) :
+ settings->pref_mode ? settings->pref_mode :
+ max_pref_mode;
return ril_network_mode_to_rat(self, pref_mode);
}
@@ -555,6 +576,31 @@
return pref;
}
+static void ril_network_startup_query_pref_mode_cb(GRilIoChannel *io,
+ int status, const void *data, guint len, void *user_data)
+{
+ if (status == RIL_E_SUCCESS) {
+ struct ril_network *self = RIL_NETWORK(user_data);
+ struct ril_network_priv *priv = self->priv;
+ const enum ofono_radio_access_mode pref_mode = self->pref_mode;
+
+ priv->rat = ril_network_parse_pref_resp(data, len);
+ self->pref_mode = ril_network_rat_to_mode(priv->rat);
+ DBG_(self, "rat mode %d (%s)", priv->rat,
+ ofono_radio_access_mode_to_string(self->pref_mode));
+
+ if (self->pref_mode != pref_mode) {
+ ril_network_emit(self, SIGNAL_PREF_MODE_CHANGED);
+ }
+
+ /*
+ * Unlike ril_network_query_pref_mode_cb, this one always
+ * checks the preferred mode.
+ */
+ ril_network_check_pref_mode(self, FALSE);
+ }
+}
+
static void ril_network_query_pref_mode_cb(GRilIoChannel *io, int status,
const void *data, guint len, void *user_data)
{
@@ -661,8 +707,11 @@
static void ril_network_radio_state_cb(struct ril_radio *radio, void *data)
{
+ struct ril_network *self = RIL_NETWORK(data);
+
+ ril_network_check_pref_mode(self, FALSE);
if (radio->state == RADIO_STATE_ON) {
- ril_network_poll_state(RIL_NETWORK(data));
+ ril_network_poll_state(self);
}
}
@@ -753,7 +802,9 @@
* Query the initial state. Querying network state before the radio
* has been turned on makes RIL unhappy.
*/
- ril_network_query_pref_mode(self);
+ grilio_queue_send_request_full(priv->q, NULL,
+ RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE,
+ ril_network_startup_query_pref_mode_cb, NULL, self);
if (radio->state == RADIO_STATE_ON) {
ril_network_poll_state(self);
}
|
[-]
[+]
|
Changed |
_service:tar_git:ofono-1.18+git7.tar.bz2/ofono/plugins/nettime.c
^
|
@@ -1,8 +1,7 @@
/*
- *
* oFono - Open Source Telephony
*
- * Copyright (C) 2012-2015 Jolla Ltd.
+ * Copyright (C) 2012-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
@@ -12,11 +11,6 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
*/
#ifdef HAVE_CONFIG_H
@@ -35,9 +29,34 @@
#include "ofono.h"
+#define NTD_WAIT_TIMEOUT (500) /* ms */
+
+/*
+ * There are 3 distinct states here:
+ *
+ * 1. !valid
+ *
+ * Initial state, no time/timezone information whatsoever.
+ *
+ * 2. valid && !mccmnc
+ *
+ * Time/timezone information has been received from the network,
+ * but no MCC and MNC yet.
+ *
+ * 3. valid && mccmnc
+ *
+ * Time/timezone information is fully available.
+ *
+ */
struct nt_data {
+ struct ofono_modem *modem;
+ struct ofono_netreg *netreg;
+ unsigned int netreg_watch_id;
+ unsigned int netreg_status_watch_id;
+ guint mccmnc_wait_id;
+
gboolean time_available;
- gboolean time_pending;
+ gboolean valid;
time_t nw_time_utc;
time_t received;
@@ -47,27 +66,11 @@
char *mcc;
char *mnc;
- char* path;
DBusConnection *conn;
};
-static struct nt_data *nettime_new(const char *path)
-{
- struct nt_data *ntd = g_new0(struct nt_data, 1);
-
- ntd->path = g_strdup(path);
- ntd->conn = dbus_connection_ref(ofono_dbus_get_connection());
- return ntd;
-}
-
-static void nettime_free(struct nt_data *ntd)
-{
- dbus_connection_unref(ntd->conn);
- g_free(ntd->path);
- g_free(ntd->mcc);
- g_free(ntd->mnc);
- g_free(ntd);
-}
+#define DBG_(ntd,fmt,args...) \
+ DBG("%s " fmt, ofono_modem_get_path((ntd)->modem), ##args)
static gboolean nettime_encode_time_format(struct tm *tm,
const struct ofono_network_time *time)
@@ -110,7 +113,7 @@
dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
"{sv}",
&iter_array);
- if (ntd->time_pending) {
+ if (ntd->valid && ntd->mcc && ntd->mnc) {
if (ntd->time_available) {
utc_long = (dbus_int64_t) ntd->nw_time_utc;
ofono_dbus_dict_append(&iter_array,
@@ -145,7 +148,7 @@
DBUS_TYPE_STRING,
&ntd->mnc);
} else {
- DBG("fill_time_notification: time not available");
+ DBG_(ntd, "time not available");
}
dbus_message_iter_close_container(&iter, &iter_array);
@@ -177,83 +180,162 @@
{ }
};
-static int nettime_probe(struct ofono_nettime_context *context)
+static void nettime_send_signal(struct nt_data *ntd)
{
- struct nt_data *ntd = nettime_new(ofono_modem_get_path(context->modem));
+ DBusMessage *signal =
+ dbus_message_new_signal(ofono_modem_get_path(ntd->modem),
+ OFONO_NETWORK_TIME_INTERFACE, "NetworkTimeChanged");
- DBG("Network time probe for modem: %p (%s)", context->modem, ntd->path);
- if (g_dbus_register_interface(ntd->conn, ntd->path,
- OFONO_NETWORK_TIME_INTERFACE, nettime_methods,
- nettime_signals, NULL, ntd, NULL)) {
- context->data = ntd;
- ofono_info("Registered interface %s, path %s",
- OFONO_NETWORK_TIME_INTERFACE, ntd->path);
- ofono_modem_add_interface(context->modem,
- OFONO_NETWORK_TIME_INTERFACE);
- return 0;
- } else {
- ofono_error("Could not register interface %s, path %s",
- OFONO_NETWORK_TIME_INTERFACE, ntd->path);
- nettime_free(ntd);
- return 1;
+ DBG_(ntd, "");
+ nettime_fill_time_notification(signal, ntd);
+ g_dbus_send_message(ntd->conn, signal);
+}
+
+static void nettime_set_mcc_mnc(struct nt_data *ntd, const char *mcc,
+ const char *mnc)
+{
+ if (g_strcmp0(ntd->mcc, mcc)) {
+ g_free(ntd->mcc);
+ ntd->mcc = g_strdup(mcc);
+ }
+
+ if (g_strcmp0(ntd->mnc, mnc)) {
+ g_free(ntd->mnc);
+ ntd->mnc = g_strdup(mnc);
+ }
+
+ if (ntd->mcc && ntd->mnc) {
+ DBG_(ntd, "MCC: %s, MNC: %s", ntd->mcc, ntd->mnc);
+
+ if (ntd->mccmnc_wait_id) {
+ /* We have been waiting for MCC and MNC */
+ g_source_remove(ntd->mccmnc_wait_id);
+ ntd->mccmnc_wait_id = 0;
+ nettime_send_signal(ntd);
+ }
}
}
-static void nettime_remove(struct ofono_nettime_context *context)
+static void nettime_netreg_status_watch_cb(int status, int lac, int ci,
+ int tech, const char *mcc, const char *mnc,
+ void *userdata)
{
- struct nt_data *ntd = context->data;
+ nettime_set_mcc_mnc(userdata, mcc, mnc);
+}
- DBG("Network time remove for modem: %p (%s)", context->modem,
- ofono_modem_get_path(context->modem));
- ofono_modem_remove_interface(context->modem,
- OFONO_NETWORK_TIME_INTERFACE);
- if (!g_dbus_unregister_interface(ntd->conn, ntd->path,
- OFONO_NETWORK_TIME_INTERFACE)) {
- ofono_error("Network time: could not unregister interface %s"
- " for %s", OFONO_NETWORK_TIME_INTERFACE, ntd->path);
+static void nettime_netreg_status_watch_done(void *userdata)
+{
+ struct nt_data *ntd = userdata;
+
+ DBG_(ntd, "");
+ ntd->netreg_status_watch_id = 0;
+}
+
+static void nettime_set_netreg(struct nt_data *ntd,
+ struct ofono_netreg *netreg)
+{
+ if (ntd->netreg != netreg) {
+ ntd->valid = FALSE;
+ ntd->netreg = netreg;
+ if (netreg) {
+ nettime_set_mcc_mnc(ntd,
+ ofono_netreg_get_mcc(netreg),
+ ofono_netreg_get_mnc(netreg));
+ ntd->netreg_status_watch_id =
+ __ofono_netreg_add_status_watch(netreg,
|
[-]
[+]
|
Changed |
_service:tar_git:ofono-1.18+git7.tar.bz2/ofono/src/gprs.c
^
|
@@ -135,6 +135,7 @@
struct ofono_gprs *gprs;
};
+static void gprs_attached_update(struct ofono_gprs *gprs);
static void gprs_netreg_update(struct ofono_gprs *gprs);
static void gprs_deactivate_next(struct ofono_gprs *gprs);
static void write_context_settings(struct ofono_gprs *gprs,
@@ -1148,6 +1149,16 @@
ofono_dbus_signal_property_changed(conn, ctx->path,
OFONO_CONNECTION_CONTEXT_INTERFACE,
"Active", DBUS_TYPE_BOOLEAN, &value);
+
+ /*
+ * If "Attached" property was about to be signalled as TRUE but there
+ * were still active contexts, try again to signal "Attached" property
+ * to registered applications after active contexts have been released.
+ */
+ if (ctx->gprs->flags & GPRS_FLAG_ATTACHED_UPDATE) {
+ ctx->gprs->flags &= ~GPRS_FLAG_ATTACHED_UPDATE;
+ gprs_attached_update(ctx->gprs);
+ }
}
static void pri_read_settings_callback(const struct ofono_error *error,
@@ -2358,13 +2369,13 @@
if (ctx == NULL)
return __ofono_error_not_found(msg);
+ /* This context is already being messed with */
+ if (ctx->pending)
+ return __ofono_error_busy(msg);
+
if (ctx->active) {
struct ofono_gprs_context *gc = ctx->context_driver;
- /* This context is already being messed with */
- if (ctx->pending)
- return __ofono_error_busy(msg);
-
gprs->pending = dbus_message_ref(msg);
gc->driver->deactivate_primary(gc, ctx->context.cid,
gprs_deactivate_for_remove, ctx);
|
[-]
[+]
|
Changed |
_service:tar_git:ofono-1.18+git7.tar.bz2/ofono/src/smsutil.c
^
|
@@ -2218,6 +2218,7 @@
const struct sms *sms;
int guess_size = g_slist_length(sms_list);
char *utf8;
+ GByteArray *utf16 = 0;
if (guess_size == 1)
guess_size = 160;
@@ -2289,8 +2290,12 @@
NULL, NULL, 0,
locking_shift,
single_shift);
+ if (converted) {
+ g_string_append(str, converted);
+ g_free(converted);
+ }
} else {
- const gchar *from = (const gchar *) (ud + taken);
+ const guint8 *from = ud + taken;
/*
* According to the spec: A UCS2 character shall not be
* split in the middle; if the length of the User Data
@@ -2300,15 +2305,32 @@
gssize num_ucs2_chars = (udl_in_bytes - taken) >> 1;
num_ucs2_chars = num_ucs2_chars << 1;
- converted = g_convert_with_fallback(from, num_ucs2_chars,
- "UTF-8//TRANSLIT", "UTF-16BE",
- NULL, NULL, NULL, NULL);
+ /*
+ * In theory SMS supports encoding using UCS2 which
+ * is 16-bit, however in the real world messages
+ * are encoded in UTF-16 which can be 4 bytes and
+ * a multiple fragment message can split a 4-byte
+ * character in the middle. So accumulate the
+ * entire message before converting to UTF-8.
+ */
+ if (!utf16)
+ utf16 = g_byte_array_new();
+
+ g_byte_array_append(utf16, from, num_ucs2_chars);
}
+ }
+
+ if (utf16) {
+ char *converted = g_convert_with_fallback((const gchar *)
+ utf16->data, utf16->len,
+ "UTF-8//TRANSLIT", "UTF-16BE",
+ NULL, NULL, NULL, NULL);
if (converted) {
g_string_append(str, converted);
g_free(converted);
}
+ g_byte_array_free(utf16, TRUE);
}
utf8 = g_string_free(str, FALSE);
|