summaryrefslogtreecommitdiffstats
path: root/src/sms.c
diff options
context:
space:
mode:
authorDenis Kenzior <denkenz@gmail.com>2010-06-25 14:21:35 -0500
committerDenis Kenzior <denkenz@gmail.com>2010-06-25 14:25:46 -0500
commit8ff599c691fe88c237b355a481a9fab143f1c95f (patch)
tree6d0de1f2447644098a34fb8d77b075bdfb712bf9 /src/sms.c
parent11cc3ee9224513ede825ade501562bf06fc06534 (diff)
downloadofono-8ff599c691fe88c237b355a481a9fab143f1c95f.tar.bz2
sms: Add support for SMS Bearer settings
Diffstat (limited to 'src/sms.c')
-rw-r--r--src/sms.c134
1 files changed, 132 insertions, 2 deletions
diff --git a/src/sms.c b/src/sms.c
index 00411299..180d14f3 100644
--- a/src/sms.c
+++ b/src/sms.c
@@ -64,6 +64,7 @@ struct ofono_sms {
struct ofono_sim *sim;
GKeyFile *settings;
char *imsi;
+ int bearer;
const struct ofono_sms_driver *driver;
void *driver_data;
struct ofono_atom *atom;
@@ -88,6 +89,55 @@ struct tx_queue_entry {
struct sms_address receiver;
};
+static const char *sms_bearer_to_string(int bearer)
+{
+ switch (bearer) {
+ case 0:
+ return "ps";
+ case 1:
+ return "cs";
+ case 2:
+ return "ps_preferred";
+ case 3:
+ return "cs_preferred";
+ };
+
+ return "unknown";
+}
+
+static int sms_bearer_from_string(const char *str)
+{
+ if (g_str_equal(str, "ps"))
+ return 0;
+ else if (g_str_equal(str, "cs"))
+ return 1;
+ else if (g_str_equal(str, "ps_preferred"))
+ return 2;
+ else if (g_str_equal(str, "cs_preferred"))
+ return 3;
+
+ return -1;
+}
+
+static void set_bearer(struct ofono_sms *sms, int bearer)
+{
+ DBusConnection *conn = ofono_dbus_get_connection();
+ const char *path = __ofono_atom_get_path(sms->atom);
+ const char *value;
+
+ if (sms->bearer == bearer)
+ return;
+
+ sms->bearer = bearer;
+
+ value = sms_bearer_to_string(sms->bearer);
+
+ ofono_dbus_signal_property_changed(conn, path,
+ OFONO_SMS_MANAGER_INTERFACE,
+ "Bearer",
+ DBUS_TYPE_STRING, &value);
+}
+
static void set_sca(struct ofono_sms *sms,
const struct ofono_phone_number *sca)
{
@@ -118,6 +168,7 @@ static DBusMessage *generate_get_properties_reply(struct ofono_sms *sms,
DBusMessageIter iter;
DBusMessageIter dict;
const char *sca;
+ const char *bearer;
reply = dbus_message_new_method_return(msg);
@@ -138,6 +189,9 @@ static DBusMessage *generate_get_properties_reply(struct ofono_sms *sms,
ofono_dbus_dict_append(&dict, "UseDeliveryReports", DBUS_TYPE_BOOLEAN,
&sms->use_delivery_reports);
+ bearer = sms_bearer_to_string(sms->bearer);
+ ofono_dbus_dict_append(&dict, "Bearer", DBUS_TYPE_STRING, &bearer);
+
dbus_message_iter_close_container(&iter, &dict);
return reply;
@@ -185,6 +239,39 @@ static DBusMessage *sms_get_properties(DBusConnection *conn,
return NULL;
}
+static void bearer_set_query_callback(const struct ofono_error *error,
+ int bearer, void *data)
+{
+ struct ofono_sms *sms = data;
+ DBusMessage *reply;
+
+ if (error->type != OFONO_ERROR_TYPE_NO_ERROR) {
+ ofono_error("Set Bearer succeeded, but query failed");
+ reply = __ofono_error_failed(sms->pending);
+ __ofono_dbus_pending_reply(&sms->pending, reply);
+ return;
+ }
+
+ reply = dbus_message_new_method_return(sms->pending);
+ __ofono_dbus_pending_reply(&sms->pending, reply);
+
+ set_bearer(sms, bearer);
+}
+
+static void bearer_set_callback(const struct ofono_error *error, void *data)
+{
+ struct ofono_sms *sms = data;
+
+ if (error->type != OFONO_ERROR_TYPE_NO_ERROR) {
+ DBG("Setting Bearer failed");
+ __ofono_dbus_pending_reply(&sms->pending,
+ __ofono_error_failed(sms->pending));
+ return;
+ }
+
+ sms->driver->bearer_query(sms, bearer_set_query_callback, sms);
+}
+
static void sca_set_query_callback(const struct ofono_error *error,
const struct ofono_phone_number *sca,
void *data)
@@ -269,6 +356,29 @@ static DBusMessage *sms_set_property(DBusConnection *conn, DBusMessage *msg,
return NULL;
}
+ if (!strcmp(property, "Bearer")) {
+ const char *value;
+ int bearer;
+
+ if (dbus_message_iter_get_arg_type(&var) != DBUS_TYPE_STRING)
+ return __ofono_error_invalid_args(msg);
+
+ dbus_message_iter_get_basic(&var, &value);
+
+ bearer = sms_bearer_from_string(value);
+ if (bearer < 0)
+ return __ofono_error_invalid_format(msg);
+
+ if (sms->driver->bearer_set == NULL ||
+ sms->driver->bearer_query == NULL)
+ return __ofono_error_not_implemented(msg);
+
+ sms->pending = dbus_message_ref(msg);
+
+ sms->driver->bearer_set(sms, bearer, bearer_set_callback, sms);
+ return NULL;
+ }
+
if (!strcmp(property, "UseDeliveryReports")) {
const char *path = __ofono_atom_get_path(sms->atom);
dbus_bool_t value;
@@ -980,6 +1090,8 @@ static void sms_remove(struct ofono_atom *atom)
g_key_file_set_boolean(sms->settings, SETTINGS_GROUP,
"UseDeliveryReports",
sms->use_delivery_reports);
+ g_key_file_set_integer(sms->settings, SETTINGS_GROUP,
+ "Bearer", sms->bearer);
storage_close(sms->imsi, SETTINGS_STORE, sms->settings, TRUE);
@@ -1060,6 +1172,8 @@ static void mw_watch(struct ofono_atom *atom,
static void sms_load_settings(struct ofono_sms *sms, const char *imsi)
{
+ GError *error = NULL;
+
sms->settings = storage_open(imsi, SETTINGS_STORE);
if (sms->settings == NULL)
@@ -1069,16 +1183,27 @@ static void sms_load_settings(struct ofono_sms *sms, const char *imsi)
sms->next_msg_id = g_key_file_get_integer(sms->settings, SETTINGS_GROUP,
"NextMessageId", NULL);
+
sms->ref = g_key_file_get_integer(sms->settings, SETTINGS_GROUP,
"NextReference", NULL);
+ if (sms->ref >= 65536)
+ sms->ref = 1;
+
sms->use_delivery_reports =
g_key_file_get_boolean(sms->settings, SETTINGS_GROUP,
"UseDeliveryReports", NULL);
- if (sms->ref >= 65536)
- sms->ref = 1;
+ sms->bearer = g_key_file_get_integer(sms->settings, SETTINGS_GROUP,
+ "Bearer", &error);
+ if (error)
+ sms->bearer = 3; /* Default to CS then PS */
}
+static void bearer_init_callback(const struct ofono_error *error, void *data)
+{
+ if (error->type != OFONO_ERROR_TYPE_NO_ERROR)
+ ofono_error("Error bootstrapping SMS Bearer Preference");
+}
/*
* Indicate oFono that a SMS driver is ready for operation
@@ -1136,8 +1261,13 @@ void ofono_sms_register(struct ofono_sms *sms)
} else {
sms->assembly = sms_assembly_new(NULL);
sms->sr_assembly = status_report_assembly_new(NULL);
+ sms->bearer = 3; /* Default to CS then PS */
}
+ if (sms->driver->bearer_set)
+ sms->driver->bearer_set(sms, sms->bearer,
+ bearer_init_callback, sms);
+
__ofono_atom_register(sms->atom, sms_unregister);
}