radio-settings: add frequency band selection props
authorLucas De Marchi <lucas.demarchi@profusion.mobi>
Thu, 2 Dec 2010 01:55:58 +0000 (23:55 -0200)
committerDenis Kenzior <denkenz@gmail.com>
Wed, 8 Dec 2010 17:32:15 +0000 (11:32 -0600)
src/radio-settings.c

index ff6934b..51158ef 100644 (file)
@@ -41,8 +41,12 @@ struct ofono_radio_settings {
        DBusMessage *pending;
        int flags;
        enum ofono_radio_access_mode mode;
-       enum ofono_radio_access_mode pending_mode;
+       enum ofono_radio_band_gsm band_gsm;
+       enum ofono_radio_band_umts band_umts;
        ofono_bool_t fast_dormancy;
+       enum ofono_radio_access_mode pending_mode;
+       enum ofono_radio_band_gsm pending_band_gsm;
+       enum ofono_radio_band_umts pending_band_umts;
        ofono_bool_t fast_dormancy_pending;
        const struct ofono_radio_settings_driver *driver;
        void *driver_data;
@@ -86,6 +90,100 @@ static gboolean radio_access_mode_from_string(const char *str,
        return FALSE;
 }
 
+static const char *radio_band_gsm_to_string(enum ofono_radio_band_gsm band)
+{
+       switch (band) {
+       case OFONO_RADIO_BAND_GSM_ANY:
+               return "any";
+       case OFONO_RADIO_BAND_GSM_850:
+               return "850";
+       case OFONO_RADIO_BAND_GSM_900P:
+               return "900P";
+       case OFONO_RADIO_BAND_GSM_900E:
+               return "900E";
+       case OFONO_RADIO_BAND_GSM_1800:
+               return "1800";
+       case OFONO_RADIO_BAND_GSM_1900:
+               return "1900";
+       }
+
+       return "";
+}
+
+static gboolean radio_band_gsm_from_string(const char *str,
+                                               enum ofono_radio_band_gsm *band)
+
+{
+       if (g_str_equal(str, "any")) {
+               *band = OFONO_RADIO_BAND_GSM_ANY;
+               return TRUE;
+       } else if (g_str_equal(str, "850")) {
+               *band = OFONO_RADIO_BAND_GSM_850;
+               return TRUE;
+       } else if (g_str_equal(str, "900P")) {
+               *band = OFONO_RADIO_BAND_GSM_900P;
+               return TRUE;
+       } else if (g_str_equal(str, "900E")) {
+               *band = OFONO_RADIO_BAND_GSM_900E;
+               return TRUE;
+       } else if (g_str_equal(str, "1800")) {
+               *band = OFONO_RADIO_BAND_GSM_1800;
+               return TRUE;
+       } else if (g_str_equal(str, "1900")) {
+               *band = OFONO_RADIO_BAND_GSM_1900;
+               return TRUE;
+       }
+
+       return FALSE;
+}
+
+static const char *radio_band_umts_to_string(enum ofono_radio_band_umts band)
+{
+       switch (band) {
+       case OFONO_RADIO_BAND_UMTS_ANY:
+               return "any";
+       case OFONO_RADIO_BAND_UMTS_850:
+               return "850";
+       case OFONO_RADIO_BAND_UMTS_900:
+               return "900";
+       case OFONO_RADIO_BAND_UMTS_1700AWS:
+               return "1700AWS";
+       case OFONO_RADIO_BAND_UMTS_1900:
+               return "1900";
+       case OFONO_RADIO_BAND_UMTS_2100:
+               return "2100";
+       }
+
+       return "";
+}
+
+static gboolean radio_band_umts_from_string(const char *str,
+                                               enum ofono_radio_band_umts *band)
+
+{
+       if (g_str_equal(str, "any")) {
+               *band = OFONO_RADIO_BAND_GSM_ANY;
+               return TRUE;
+       } else if (g_str_equal(str, "850")) {
+               *band = OFONO_RADIO_BAND_UMTS_850;
+               return TRUE;
+       } else if (g_str_equal(str, "900")) {
+               *band = OFONO_RADIO_BAND_UMTS_900;
+               return TRUE;
+       } else if (g_str_equal(str, "1700AWS")) {
+               *band = OFONO_RADIO_BAND_UMTS_1700AWS;
+               return TRUE;
+       } else if (g_str_equal(str, "1900")) {
+               *band = OFONO_RADIO_BAND_UMTS_1900;
+               return TRUE;
+       } else if (g_str_equal(str, "2100")) {
+               *band = OFONO_RADIO_BAND_UMTS_2100;
+               return TRUE;
+       }
+
+       return FALSE;
+}
+
 static DBusMessage *radio_get_properties_reply(DBusMessage *msg,
                                                struct ofono_radio_settings *rs)
 {
@@ -108,6 +206,18 @@ static DBusMessage *radio_get_properties_reply(DBusMessage *msg,
        ofono_dbus_dict_append(&dict, "TechnologyPreference",
                                        DBUS_TYPE_STRING, &mode);
 
+       if (rs->driver->query_band) {
+               const char *band = radio_band_gsm_to_string(rs->band_gsm);
+
+               ofono_dbus_dict_append(&dict, "GsmBand",
+                                       DBUS_TYPE_STRING, &band);
+
+               band = radio_band_umts_to_string(rs->band_umts);
+
+               ofono_dbus_dict_append(&dict, "UmtsBand",
+                                       DBUS_TYPE_STRING, &band);
+       }
+
        if (rs->driver->query_fast_dormancy) {
                dbus_bool_t value = rs->fast_dormancy;
                ofono_dbus_dict_append(&dict, "FastDormancy",
@@ -159,6 +269,60 @@ static void radio_fast_dormancy_set_callback(const struct ofono_error *error,
        radio_set_fast_dormancy(rs, rs->fast_dormancy_pending);
 }
 
+static void radio_set_band(struct ofono_radio_settings *rs)
+{
+       DBusConnection *conn = ofono_dbus_get_connection();
+       const char *path;
+       const char *str_band;
+
+       path = __ofono_atom_get_path(rs->atom);
+
+       if (rs->band_gsm != rs->pending_band_gsm) {
+               rs->band_gsm = rs->pending_band_gsm;
+               str_band = radio_band_gsm_to_string(rs->band_gsm);
+
+               ofono_dbus_signal_property_changed(conn, path,
+                                               OFONO_RADIO_SETTINGS_INTERFACE,
+                                               "GsmBand", DBUS_TYPE_STRING,
+                                               &str_band);
+       }
+
+       if (rs->band_umts != rs->pending_band_umts) {
+               rs->band_umts = rs->pending_band_umts;
+               str_band = radio_band_umts_to_string(rs->band_umts);
+
+               ofono_dbus_signal_property_changed(conn, path,
+                                               OFONO_RADIO_SETTINGS_INTERFACE,
+                                               "UmtsBand", DBUS_TYPE_STRING,
+                                               &str_band);
+       }
+
+}
+
+static void radio_band_set_callback(const struct ofono_error *error,
+                                       void *data)
+{
+       struct ofono_radio_settings *rs = data;
+       DBusMessage *reply;
+
+       if (error->type != OFONO_ERROR_TYPE_NO_ERROR) {
+               DBG("Error setting radio frequency band");
+
+               rs->pending_band_gsm = rs->band_gsm;
+               rs->pending_band_umts = rs->band_umts;
+
+               reply = __ofono_error_failed(rs->pending);
+               __ofono_dbus_pending_reply(&rs->pending, reply);
+
+               return;
+       }
+
+       reply = dbus_message_new_method_return(rs->pending);
+       __ofono_dbus_pending_reply(&rs->pending, reply);
+
+       radio_set_band(rs);
+}
+
 static void radio_set_rat_mode(struct ofono_radio_settings *rs,
                                enum ofono_radio_access_mode mode)
 {
@@ -242,6 +406,40 @@ static void radio_query_fast_dormancy(struct ofono_radio_settings *rs)
                                        rs);
 }
 
+static void radio_band_query_callback(const struct ofono_error *error,
+                                       enum ofono_radio_band_gsm band_gsm,
+                                       enum ofono_radio_band_umts band_umts,
+                                       void *data)
+{
+       struct ofono_radio_settings *rs = data;
+       DBusMessage *reply;
+
+       if (error->type != OFONO_ERROR_TYPE_NO_ERROR) {
+               DBG("Error during radio frequency band query");
+
+               reply = __ofono_error_failed(rs->pending);
+               __ofono_dbus_pending_reply(&rs->pending, reply);
+
+               return;
+       }
+
+       rs->pending_band_gsm = band_gsm;
+       rs->pending_band_umts = band_umts;
+
+       radio_set_band(rs);
+       radio_query_fast_dormancy(rs);
+}
+
+static void radio_query_band(struct ofono_radio_settings *rs)
+{
+       if (!rs->driver->query_band) {
+               radio_query_fast_dormancy(rs);
+               return;
+       }
+
+       rs->driver->query_band(rs, radio_band_query_callback, rs);
+}
+
 static void radio_rat_mode_query_callback(const struct ofono_error *error,
                                        enum ofono_radio_access_mode mode,
                                        void *data)
@@ -259,7 +457,7 @@ static void radio_rat_mode_query_callback(const struct ofono_error *error,
        }
 
        radio_set_rat_mode(rs, mode);
-       radio_query_fast_dormancy(rs);
+       radio_query_band(rs);
 }
 
 static DBusMessage *radio_get_properties(DBusConnection *conn,
@@ -330,6 +528,54 @@ static DBusMessage *radio_set_property(DBusConnection *conn, DBusMessage *msg,
                rs->driver->set_rat_mode(rs, mode, radio_mode_set_callback, rs);
 
                return NULL;
+       } else if (g_strcmp0(property, "GsmBand") == 0) {
+               const char *value;
+               enum ofono_radio_band_gsm band;
+
+               if (!rs->driver->set_band)
+                       return __ofono_error_not_implemented(msg);
+
+               if (dbus_message_iter_get_arg_type(&var) != DBUS_TYPE_STRING)
+                       return __ofono_error_invalid_args(msg);
+
+               dbus_message_iter_get_basic(&var, &value);
+               if (radio_band_gsm_from_string(value, &band) == FALSE)
+                       return __ofono_error_invalid_args(msg);
+
+               if (rs->band_gsm == band)
+                       return dbus_message_new_method_return(msg);
+
+               rs->pending = dbus_message_ref(msg);
+               rs->pending_band_gsm = band;
+
+               rs->driver->set_band(rs, band, rs->band_umts,
+                                       radio_band_set_callback, rs);
+
+               return NULL;
+       } else if (g_strcmp0(property, "UmtsBand") == 0) {
+               const char *value;
+               enum ofono_radio_band_umts band;
+
+               if (!rs->driver->set_band)
+                       return __ofono_error_not_implemented(msg);
+
+               if (dbus_message_iter_get_arg_type(&var) != DBUS_TYPE_STRING)
+                       return __ofono_error_invalid_args(msg);
+
+               dbus_message_iter_get_basic(&var, &value);
+               if (radio_band_umts_from_string(value, &band) == FALSE)
+                       return __ofono_error_invalid_args(msg);
+
+               if (rs->band_umts == band)
+                       return dbus_message_new_method_return(msg);
+
+               rs->pending = dbus_message_ref(msg);
+               rs->pending_band_umts = band;
+
+               rs->driver->set_band(rs, rs->band_gsm, band,
+                                       radio_band_set_callback, rs);
+
+               return NULL;
        } else if (g_strcmp0(property, "FastDormancy") == 0) {
                dbus_bool_t value;
                int target;