summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/call-forwarding.c589
1 files changed, 177 insertions, 412 deletions
diff --git a/src/call-forwarding.c b/src/call-forwarding.c
index b2ce0872..7b940be0 100644
--- a/src/call-forwarding.c
+++ b/src/call-forwarding.c
@@ -51,26 +51,16 @@ struct call_forwarding_data {
GSList *cf_conditions[4];
int flags;
DBusMessage *pending;
+ int query_next;
+ int query_end;
struct cf_ss_request *ss_req;
};
-static void cf_busy_callback(const struct ofono_error *error, int total,
- const struct ofono_cf_condition *list, void *data);
-static void cf_unconditional_callback(const struct ofono_error *error, int total,
- const struct ofono_cf_condition *list, void *data);
-
-static void cf_register_ss_controls(struct ofono_modem *modem);
+static gboolean get_query_next_cf_cond(gpointer user);
+static gboolean set_query_next_cf_cond(gpointer user);
+static gboolean ss_set_query_next_cf_cond(gpointer user);
static void cf_unregister_ss_controls(struct ofono_modem *modem);
-struct set_cf_request {
- struct ofono_modem *modem;
- int type;
- int cls;
- char number[OFONO_MAX_PHONE_NUMBER_LENGTH + 1];
- int number_type;
- int timeout;
-};
-
struct cf_ss_request {
int ss_type;
int cf_type;
@@ -244,9 +234,10 @@ static void set_new_cond_list(struct ofono_modem *modem, int type, GSList *list)
/* New condition lists might have attributes we don't care about
* triggered by e.g. ss control magic strings just skip them
- * here
+ * here. For now we only support Voice, although Fax & all Data
+ * basic services are applicable as well.
*/
- if (lc->cls > BEARER_CLASS_SMS)
+ if (lc->cls > BEARER_CLASS_VOICE)
continue;
timeout = lc->time;
@@ -402,16 +393,55 @@ static DBusMessage *cf_get_properties_reply(DBusMessage *msg,
&dict);
for (i = 0; i < 4; i++)
- property_append_cf_conditions(&dict,
- cf->cf_conditions[i],
- BEARER_CLASS_DEFAULT | BEARER_CLASS_SMS,
- cf_type_lut[i]);
+ property_append_cf_conditions(&dict, cf->cf_conditions[i],
+ BEARER_CLASS_VOICE,
+ cf_type_lut[i]);
dbus_message_iter_close_container(&iter, &dict);
return reply;
}
+static void get_query_cf_callback(const struct ofono_error *error, int total,
+ const struct ofono_cf_condition *list,
+ void *data)
+{
+ struct ofono_modem *modem = data;
+ struct call_forwarding_data *cf = modem->call_forwarding;
+
+ if (error->type == OFONO_ERROR_TYPE_NO_ERROR) {
+ GSList *l;
+ l = cf_cond_list_create(total, list);
+ set_new_cond_list(modem, cf->query_next, l);
+
+ ofono_debug("%s conditions:", cf_type_lut[cf->query_next]);
+ cf_cond_list_print(l);
+
+ if (cf->query_next == CALL_FORWARDING_TYPE_NOT_REACHABLE)
+ cf->flags |= CALL_FORWARDING_FLAG_CACHED;
+ }
+
+ if (cf->query_next == CALL_FORWARDING_TYPE_NOT_REACHABLE) {
+ DBusMessage *reply = cf_get_properties_reply(cf->pending, cf);
+ dbus_gsm_pending_reply(&cf->pending, reply);
+ return;
+ }
+
+ cf->query_next++;
+ g_timeout_add(0, get_query_next_cf_cond, modem);
+}
+
+static gboolean get_query_next_cf_cond(gpointer user)
+{
+ struct ofono_modem *modem = user;
+ struct call_forwarding_data *cf = modem->call_forwarding;
+
+ cf->ops->query(modem, cf->query_next, BEARER_CLASS_DEFAULT,
+ get_query_cf_callback, modem);
+
+ return FALSE;
+}
+
static DBusMessage *cf_get_properties(DBusConnection *conn, DBusMessage *msg,
void *data)
{
@@ -421,8 +451,16 @@ static DBusMessage *cf_get_properties(DBusConnection *conn, DBusMessage *msg,
if (cf->flags & CALL_FORWARDING_FLAG_CACHED)
return cf_get_properties_reply(msg, cf);
- /* We kicked off the query during interface creation, wait for it */
+ if (!cf->ops->query)
+ return dbus_gsm_not_implemented(msg);
+
+ if (cf->pending)
+ return dbus_gsm_busy(msg);
+
cf->pending = dbus_message_ref(msg);
+ cf->query_next = 0;
+
+ get_query_next_cf_cond(modem);
return NULL;
}
@@ -435,9 +473,8 @@ static gboolean cf_condition_enabled_property(struct call_forwarding_data *cf,
int len;
const char *prefix;
- /* We check the 4 bearer classes here, e.g. voice, data, fax, sms */
- for (i = 0; i < 4; i++) {
- prefix = bearer_class_to_string(1 << i);
+ for (i = 1; i <= BEARER_CLASS_VOICE; i = i << 1) {
+ prefix = bearer_class_to_string(i);
len = strlen(prefix);
@@ -450,7 +487,7 @@ static gboolean cf_condition_enabled_property(struct call_forwarding_data *cf,
for (j = 0; j < 4; j++)
if (!strcmp(property+len, cf_type_lut[j])) {
*out_type = j;
- *out_cls = 1 << i;
+ *out_cls = i;
return TRUE;
}
}
@@ -465,8 +502,8 @@ static gboolean cf_condition_timeout_property(const char *property,
int len;
const char *prefix;
- for (i = 0; i < 4; i++) {
- prefix = bearer_class_to_string(1 << i);
+ for (i = 1; i <= BEARER_CLASS_VOICE; i = i << 1) {
+ prefix = bearer_class_to_string(i);
len = strlen(prefix);
@@ -474,7 +511,7 @@ static gboolean cf_condition_timeout_property(const char *property,
continue;
if (!strcmp(property+len, "NoReplyTimeout")) {
- *out_cls = 1 << i;
+ *out_cls = i;
return TRUE;
}
}
@@ -482,162 +519,63 @@ static gboolean cf_condition_timeout_property(const char *property,
return FALSE;
}
-static void cf_condition_manual_set(struct set_cf_request *req)
+static void set_query_cf_callback(const struct ofono_error *error, int total,
+ const struct ofono_cf_condition *list,
+ void *data)
{
- struct ofono_modem *modem = req->modem;
+ struct ofono_modem *modem = data;
struct call_forwarding_data *cf = modem->call_forwarding;
- DBusConnection *conn = dbus_gsm_connection();
- int status = req->number[0] == '\0' ? 0 : 1;
GSList *l;
- struct ofono_cf_condition *c;
- char attr[64];
- char tattr[64];
- const char *number = "";
- dbus_uint16_t timeout;
-
- l = g_slist_find_custom(cf->cf_conditions[req->type],
- GINT_TO_POINTER(req->cls),
- cf_condition_find_with_cls);
-
- ofono_debug("L is: %p, status is: %d", l, status);
-
- if (!l && !status)
- return;
-
- sprintf(attr, "%s%s", bearer_class_to_string(req->cls),
- cf_type_lut[req->type]);
-
- if (req->type == CALL_FORWARDING_TYPE_NO_REPLY)
- sprintf(tattr, "%sTimeout", attr);
-
- if (l && !status) {
- c = l->data;
- timeout = DEFAULT_NO_REPLY_TIMEOUT;
-
- dbus_gsm_signal_property_changed(conn, modem->path,
- CALL_FORWARDING_INTERFACE,
- attr, DBUS_TYPE_STRING, &number);
-
- if (req->type == CALL_FORWARDING_TYPE_NO_REPLY &&
- c->time != DEFAULT_NO_REPLY_TIMEOUT)
- dbus_gsm_signal_property_changed(conn, modem->path,
- CALL_FORWARDING_INTERFACE, tattr,
- DBUS_TYPE_UINT16, &timeout);
-
- ofono_debug("Removing condition");
-
- g_free(c);
- cf->cf_conditions[req->type] =
- g_slist_remove(cf->cf_conditions[req->type], c);
+ DBusMessage *reply;
+ if (error->type != OFONO_ERROR_TYPE_NO_ERROR) {
+ ofono_error("Setting succeeded, but query failed");
+ cf->flags &= ~CALL_FORWARDING_FLAG_CACHED;
+ reply = dbus_gsm_failed(cf->pending);
+ dbus_gsm_pending_reply(&cf->pending, reply);
return;
}
- if (l)
- c = l->data;
- else {
- c = g_try_new0(struct ofono_cf_condition, 1);
-
- if (!c)
- return;
-
- c->status = 1;
- c->cls = req->cls;
- c->phone_number[0] = '\0';
- c->number_type = 129;
- c->time = DEFAULT_NO_REPLY_TIMEOUT;
-
- ofono_debug("Inserting condition");
- cf->cf_conditions[req->type] =
- g_slist_insert_sorted(cf->cf_conditions[req->type],
- c, cf_condition_compare);
- }
-
- if (c->number_type != req->number_type ||
- strcmp(req->number, c->phone_number)) {
- strcpy(c->phone_number, req->number);
- c->number_type = req->number_type;
-
- number = phone_number_to_string(req->number, req->number_type);
-
- dbus_gsm_signal_property_changed(conn, modem->path,
- CALL_FORWARDING_INTERFACE,
- attr, DBUS_TYPE_STRING, &number);
- }
-
- if (req->type == CALL_FORWARDING_TYPE_NO_REPLY &&
- c->time != req->timeout) {
- c->time = req->timeout;
-
- dbus_gsm_signal_property_changed(conn, modem->path,
- CALL_FORWARDING_INTERFACE,
- tattr, DBUS_TYPE_UINT16, &req->timeout);
+ if (cf->query_next == cf->query_end) {
+ reply = dbus_message_new_method_return(cf->pending);
+ dbus_gsm_pending_reply(&cf->pending, reply);
+ } else {
+ cf->query_next++;
+ g_timeout_add(0, set_query_next_cf_cond, modem);
}
-}
-
-static void pending_msg_error(struct call_forwarding_data *cf,
- const struct ofono_error *error)
-{
- DBusMessage *reply;
- DBusConnection *conn = dbus_gsm_connection();
- reply = dbus_gsm_failed(cf->pending);
- g_dbus_send_message(conn, reply);
+ l = cf_cond_list_create(total, list);
+ set_new_cond_list(modem, cf->query_next, l);
- dbus_message_unref(cf->pending);
- cf->pending = NULL;
+ ofono_debug("%s conditions:", cf_type_lut[cf->query_next]);
+ cf_cond_list_print(l);
}
-static void property_set_query_callback(const struct ofono_error *error, int total,
- const struct ofono_cf_condition *list,
- void *data)
+static gboolean set_query_next_cf_cond(gpointer user)
{
- struct set_cf_request *req = data;
- struct ofono_modem *modem = req->modem;
+ struct ofono_modem *modem = user;
struct call_forwarding_data *cf = modem->call_forwarding;
- DBusMessage *reply;
- GSList *new_cf_list;
-
- reply = dbus_message_new_method_return(cf->pending);
- dbus_gsm_pending_reply(&cf->pending, reply);
-
- /* Strange, set succeeded but query failed, fallback to direct method */
- if (error->type != OFONO_ERROR_TYPE_NO_ERROR) {
- ofono_debug("Error occurred during query");
- cf_condition_manual_set(req);
- goto out;
- }
- new_cf_list = cf_cond_list_create(total, list);
+ cf->ops->query(modem, cf->query_next, BEARER_CLASS_DEFAULT,
+ set_query_cf_callback, modem);
- ofono_debug("Query ran successfully");
- cf_cond_list_print(new_cf_list);
-
- set_new_cond_list(modem, req->type, new_cf_list);
-
-out:
- g_free(req);
+ return FALSE;
}
static void set_property_callback(const struct ofono_error *error, void *data)
{
- struct set_cf_request *req = data;
- struct ofono_modem *modem = req->modem;
+ struct ofono_modem *modem = data;
struct call_forwarding_data *cf = modem->call_forwarding;
if (error->type != OFONO_ERROR_TYPE_NO_ERROR) {
ofono_debug("Error occurred during set/erasure");
-
- pending_msg_error(cf, error);
- g_free(req);
-
+ dbus_gsm_pending_reply(&cf->pending,
+ dbus_gsm_failed(cf->pending));
return;
}
/* Successfully set, query the entire set just in case */
- cf->ops->query(modem, req->type,
- BEARER_CLASS_DEFAULT | BEARER_CLASS_SMS,
- property_set_query_callback, req);
+ set_query_next_cf_cond(modem);
}
static DBusMessage *set_property_request(struct ofono_modem *modem,
@@ -647,7 +585,6 @@ static DBusMessage *set_property_request(struct ofono_modem *modem,
int number_type, int timeout)
{
struct call_forwarding_data *cf = modem->call_forwarding;
- struct set_cf_request *req;
if (number[0] != '\0' && cf->ops->registration == NULL)
return dbus_gsm_not_implemented(msg);
@@ -655,27 +592,17 @@ static DBusMessage *set_property_request(struct ofono_modem *modem,
if (number[0] == '\0' && cf->ops->erasure == NULL)
return dbus_gsm_not_implemented(msg);
- req = g_try_new0(struct set_cf_request, 1);
-
- if (!req)
- return dbus_gsm_failed(msg);
-
- req->modem = modem;
- req->type = type;
- req->cls = cls;
- strcpy(req->number, number);
- req->number_type = number_type;
- req->timeout = timeout;
-
cf->pending = dbus_message_ref(msg);
+ cf->query_next = type;
+ cf->query_end = type;
ofono_debug("Farming off request, will be erasure: %d", number[0] == 0);
if (number[0] != '\0')
cf->ops->registration(modem, type, cls, number, number_type,
- timeout, set_property_callback, req);
+ timeout, set_property_callback, modem);
else
- cf->ops->erasure(modem, type, cls, set_property_callback, req);
+ cf->ops->erasure(modem, type, cls, set_property_callback, modem);
return NULL;
}
@@ -767,53 +694,38 @@ static void disable_conditional_callback(const struct ofono_error *error,
{
struct ofono_modem *modem = data;
struct call_forwarding_data *cf = modem->call_forwarding;
- DBusMessage *reply;
if (error->type != OFONO_ERROR_TYPE_NO_ERROR) {
ofono_debug("Error occurred during conditional erasure");
- pending_msg_error(cf, error);
-
+ dbus_gsm_pending_reply(&cf->pending,
+ dbus_gsm_failed(cf->pending));
return;
}
- reply = dbus_message_new_method_return(cf->pending);
- dbus_gsm_pending_reply(&cf->pending, reply);
-
- set_new_cond_list(modem, CALL_FORWARDING_TYPE_NO_REPLY, NULL);
- set_new_cond_list(modem, CALL_FORWARDING_TYPE_NOT_REACHABLE, NULL);
- set_new_cond_list(modem, CALL_FORWARDING_TYPE_BUSY, NULL);
-
- cf->ops->query(modem, CALL_FORWARDING_TYPE_BUSY,
- BEARER_CLASS_DEFAULT | BEARER_CLASS_SMS,
- cf_busy_callback, modem);
+ /* Query the three conditional cf types */
+ cf->query_next = CALL_FORWARDING_TYPE_BUSY;
+ cf->query_end = CALL_FORWARDING_TYPE_NOT_REACHABLE;
+ set_query_next_cf_cond(modem);
}
static void disable_all_callback(const struct ofono_error *error, void *data)
{
struct ofono_modem *modem = data;
struct call_forwarding_data *cf = modem->call_forwarding;
- DBusMessage *reply;
if (error->type != OFONO_ERROR_TYPE_NO_ERROR) {
ofono_debug("Error occurred during erasure of all");
- pending_msg_error(cf, error);
-
+ dbus_gsm_pending_reply(&cf->pending,
+ dbus_gsm_failed(cf->pending));
return;
}
- reply = dbus_message_new_method_return(cf->pending);
- dbus_gsm_pending_reply(&cf->pending, reply);
-
- set_new_cond_list(modem, CALL_FORWARDING_TYPE_UNCONDITIONAL, NULL);
- set_new_cond_list(modem, CALL_FORWARDING_TYPE_NO_REPLY, NULL);
- set_new_cond_list(modem, CALL_FORWARDING_TYPE_NOT_REACHABLE, NULL);
- set_new_cond_list(modem, CALL_FORWARDING_TYPE_BUSY, NULL);
-
- cf->ops->query(modem, CALL_FORWARDING_TYPE_UNCONDITIONAL,
- BEARER_CLASS_DEFAULT | BEARER_CLASS_SMS,
- cf_unconditional_callback, modem);
+ /* Query all cf types */
+ cf->query_next = CALL_FORWARDING_TYPE_UNCONDITIONAL;
+ cf->query_end = CALL_FORWARDING_TYPE_NOT_REACHABLE;
+ set_query_next_cf_cond(modem);
}
static DBusMessage *cf_disable_all(DBusConnection *conn, DBusMessage *msg,
@@ -844,19 +756,18 @@ static DBusMessage *cf_disable_all(DBusConnection *conn, DBusMessage *msg,
cf->pending = dbus_message_ref(msg);
if (type == CALL_FORWARDING_TYPE_ALL)
- cf->ops->erasure(modem, type,
- BEARER_CLASS_DEFAULT | BEARER_CLASS_SMS,
+ cf->ops->erasure(modem, type, BEARER_CLASS_DEFAULT,
disable_all_callback, modem);
else
- cf->ops->erasure(modem, type,
- BEARER_CLASS_DEFAULT | BEARER_CLASS_SMS,
+ cf->ops->erasure(modem, type, BEARER_CLASS_DEFAULT,
disable_conditional_callback, modem);
return NULL;
}
static GDBusMethodTable cf_methods[] = {
- { "GetProperties", "", "a{sv}", cf_get_properties },
+ { "GetProperties", "", "a{sv}", cf_get_properties,
+ G_DBUS_METHOD_FLAG_ASYNC },
{ "SetProperty", "sv", "", cf_set_property,
G_DBUS_METHOD_FLAG_ASYNC },
{ "DisableAll", "s", "", cf_disable_all,
@@ -869,7 +780,7 @@ static GDBusSignalTable cf_signals[] = {
{ }
};
-static void cf_ss_control_reply(struct ofono_modem *modem,
+static DBusMessage *cf_ss_control_reply(struct ofono_modem *modem,
struct cf_ss_request *req)
{
struct call_forwarding_data *cf = modem->call_forwarding;
@@ -877,7 +788,6 @@ static void cf_ss_control_reply(struct ofono_modem *modem,
const char *sig = "(ssa{sv})";
const char *ss_type = ss_control_type_to_string(req->ss_type);
const char *cf_type = cf_type_lut[req->cf_type];
- DBusConnection *conn = dbus_gsm_connection();
DBusMessageIter iter;
DBusMessageIter variant;
DBusMessageIter vstruct;
@@ -940,71 +850,72 @@ static void cf_ss_control_reply(struct ofono_modem *modem,
dbus_message_iter_close_container(&iter, &variant);
- g_dbus_send_message(conn, reply);
+ return reply;
}
-static void cf_ss_control_query_callback(const struct ofono_error *error,
- int total,
+static void ss_set_query_cf_callback(const struct ofono_error *error, int total,
const struct ofono_cf_condition *list,
void *data)
{
struct ofono_modem *modem = data;
struct call_forwarding_data *cf = modem->call_forwarding;
- GSList *new_cf_list;
+ GSList *l;
+ DBusMessage *reply;
- /* Strange, set succeeded but query failed, fallback to direct method */
if (error->type != OFONO_ERROR_TYPE_NO_ERROR) {
- ofono_debug("Error occurred during cf ss query");
-
- pending_msg_error(cf, error);
-
+ ofono_error("Setting succeeded, but query failed");
+ cf->flags &= ~CALL_FORWARDING_FLAG_CACHED;
+ reply = dbus_gsm_failed(cf->pending);
+ dbus_gsm_pending_reply(&cf->pending, reply);
return;
}
- new_cf_list = cf_cond_list_create(total, list);
+ l = cf_cond_list_create(total, list);
+ ofono_debug("%s conditions:", cf_type_lut[cf->query_next]);
+ cf_cond_list_print(l);
- ofono_debug("Query ran successfully");
- cf_cond_list_print(new_cf_list);
+ cf->ss_req->cf_list[cf->query_next] = l;
- cf->ss_req->cf_list[cf->ss_req->cf_type] = new_cf_list;
+ if (cf->query_next == cf->query_end) {
+ reply = cf_ss_control_reply(modem, cf->ss_req);
+ dbus_gsm_pending_reply(&cf->pending, reply);
+ g_free(cf->ss_req);
+ cf->ss_req = NULL;
+ } else {
+ cf->query_next++;
+ g_timeout_add(0, ss_set_query_next_cf_cond, modem);
+ }
- set_new_cond_list(modem, cf->ss_req->cf_type, new_cf_list);
+ set_new_cond_list(modem, cf->query_next, l);
+}
- cf_ss_control_reply(modem, cf->ss_req);
+static gboolean ss_set_query_next_cf_cond(gpointer user)
+{
+ struct ofono_modem *modem = user;
+ struct call_forwarding_data *cf = modem->call_forwarding;
- dbus_message_unref(cf->pending);
- cf->pending = NULL;
+ cf->ops->query(modem, cf->query_next, BEARER_CLASS_DEFAULT,
+ ss_set_query_cf_callback, modem);
- g_free(cf->ss_req);
- cf->ss_req = NULL;
+ return FALSE;
}
static void cf_ss_control_callback(const struct ofono_error *error, void *data)
{
struct ofono_modem *modem = data;
struct call_forwarding_data *cf = modem->call_forwarding;
- int cls;
if (error->type != OFONO_ERROR_TYPE_NO_ERROR) {
ofono_debug("Error occurred during cf ss control set/erasure");
- pending_msg_error(cf, error);
-
+ dbus_gsm_pending_reply(&cf->pending,
+ dbus_gsm_failed(cf->pending));
+ g_free(cf->ss_req);
+ cf->ss_req = NULL;
return;
}
- cls = BEARER_CLASS_DEFAULT | BEARER_CLASS_SMS | cf->ss_req->cls;
-
- /* Successfully set, query the entire set just in case */
- if (cf->ss_req->cf_type == CALL_FORWARDING_TYPE_ALL)
- cf->ops->query(modem, CALL_FORWARDING_TYPE_UNCONDITIONAL,
- cls, cf_unconditional_callback, modem);
- else if (cf->ss_req->cf_type == CALL_FORWARDING_TYPE_ALL_CONDITIONAL)
- cf->ops->query(modem, CALL_FORWARDING_TYPE_BUSY,
- cls, cf_busy_callback, modem);
- else
- cf->ops->query(modem, cf->ss_req->cf_type, cls,
- cf_ss_control_query_callback, modem);
+ ss_set_query_next_cf_cond(modem);
}
static gboolean cf_ss_control(struct ofono_modem *modem, int type, const char *sc,
@@ -1014,7 +925,7 @@ static gboolean cf_ss_control(struct ofono_modem *modem, int type, const char *s
{
struct call_forwarding_data *cf = modem->call_forwarding;
DBusConnection *conn = dbus_gsm_connection();
- int cls = BEARER_CLASS_DEFAULT;
+ int cls = BEARER_CLASS_SS_DEFAULT;
int timeout = DEFAULT_NO_REPLY_TIMEOUT;
int cf_type;
DBusMessage *reply;
@@ -1145,7 +1056,30 @@ static gboolean cf_ss_control(struct ofono_modem *modem, int type, const char *s
cf->ss_req->cls = cls;
cf->pending = dbus_message_ref(msg);
- cls |= BEARER_CLASS_DEFAULT | BEARER_CLASS_SMS;
+
+ switch (cf->ss_req->cf_type) {
+ case CALL_FORWARDING_TYPE_ALL:
+ cf->query_next = CALL_FORWARDING_TYPE_UNCONDITIONAL;
+ cf->query_end = CALL_FORWARDING_TYPE_NOT_REACHABLE;
+ break;
+ case CALL_FORWARDING_TYPE_ALL_CONDITIONAL:
+ cf->query_next = CALL_FORWARDING_TYPE_BUSY;
+ cf->query_end = CALL_FORWARDING_TYPE_NOT_REACHABLE;
+ break;
+ default:
+ cf->query_next = cf->ss_req->cf_type;
+ cf->query_end = cf->ss_req->cf_type;
+ break;
+ }
+
+ /* Some modems don't understand all classes very well, particularly
+ * the older models. So if the bearer class is the default, we
+ * just use the more commonly understood value of 7 since BEARER_SMS
+ * is not applicable to CallForwarding conditions according to 22.004
+ * Annex A
+ */
+ if (cls == BEARER_CLASS_SS_DEFAULT)
+ cls = BEARER_CLASS_DEFAULT;
switch (cf->ss_req->ss_type) {
case SS_CONTROL_TYPE_REGISTRATION:
@@ -1167,17 +1101,7 @@ static gboolean cf_ss_control(struct ofono_modem *modem, int type, const char *s
modem);
break;
case SS_CONTROL_TYPE_QUERY:
- cls |= BEARER_CLASS_DEFAULT | BEARER_CLASS_SMS;
- if (cf_type == CALL_FORWARDING_TYPE_ALL)
- cf->ops->query(modem,
- CALL_FORWARDING_TYPE_UNCONDITIONAL,
- cls, cf_unconditional_callback, modem);
- else if (cf_type == CALL_FORWARDING_TYPE_ALL_CONDITIONAL)
- cf->ops->query(modem, CALL_FORWARDING_TYPE_BUSY,
- cls, cf_busy_callback, modem);
- else
- cf->ops->query(modem, cf_type, cls,
- cf_ss_control_query_callback, modem);
+ ss_set_query_next_cf_cond(modem);
break;
}
@@ -1211,163 +1135,6 @@ static void cf_unregister_ss_controls(struct ofono_modem *modem)
ss_control_unregister(modem, "004", cf_ss_control);
}
-static void cf_not_reachable_callback(const struct ofono_error *error, int total,
- const struct ofono_cf_condition *list, void *data)
-{
- struct ofono_modem *modem = data;
- struct call_forwarding_data *cf = modem->call_forwarding;
- GSList *l = NULL;
-
- if (error->type != OFONO_ERROR_TYPE_NO_ERROR) {
- ofono_debug("Error during not reachable CF query");
- goto out;
- }
-
- l = cf_cond_list_create(total, list);
-
- set_new_cond_list(modem, CALL_FORWARDING_TYPE_NOT_REACHABLE, l);
-
- ofono_debug("Not Reachable conditions:");
- cf_cond_list_print(l);
-
-out:
-
- cf->flags |= CALL_FORWARDING_FLAG_CACHED;
-
- if (cf->pending) {
- if (cf->ss_req) {
- cf->ss_req->cf_list[CALL_FORWARDING_TYPE_NOT_REACHABLE] = l;
- cf_ss_control_reply(modem, cf->ss_req);
- g_free(cf->ss_req);
- cf->ss_req = NULL;
- } else {
- DBusConnection *conn = dbus_gsm_connection();
- DBusMessage *reply =
- cf_get_properties_reply(cf->pending, cf);
-
- g_dbus_send_message(conn, reply);
- }
-
- dbus_message_unref(cf->pending);
- cf->pending = NULL;
- }
-}
-
-static void cf_no_reply_callback(const struct ofono_error *error, int total,
- const struct ofono_cf_condition *list, void *data)
-{
- struct ofono_modem *modem = data;
- struct call_forwarding_data *cf = modem->call_forwarding;
- GSList *l = NULL;
- int cls = BEARER_CLASS_DEFAULT | BEARER_CLASS_SMS;
-
- if (error->type != OFONO_ERROR_TYPE_NO_ERROR) {
- ofono_debug("Error during no reply CF query");
- goto out;
- }
-
- l = cf_cond_list_create(total, list);
-
- set_new_cond_list(modem, CALL_FORWARDING_TYPE_NO_REPLY, l);
-
- ofono_debug("No Reply conditions:");
- cf_cond_list_print(l);
-
-out:
- if (cf->ss_req) {
- cls |= cf->ss_req->cls;
- cf->ss_req->cf_list[CALL_FORWARDING_TYPE_NO_REPLY] = l;
- }
-
- cf->ops->query(modem, CALL_FORWARDING_TYPE_NOT_REACHABLE,
- cls, cf_not_reachable_callback, modem);
-}
-
-static void cf_busy_callback(const struct ofono_error *error, int total,
- const struct ofono_cf_condition *list, void *data)
-{
- struct ofono_modem *modem = data;
- struct call_forwarding_data *cf = modem->call_forwarding;
- GSList *l = NULL;
- int cls = BEARER_CLASS_DEFAULT | BEARER_CLASS_SMS;
-
- if (error->type != OFONO_ERROR_TYPE_NO_ERROR) {
- ofono_debug("Error during busy CF query");
- goto out;
- }
-
- l = cf_cond_list_create(total, list);
-
- set_new_cond_list(modem, CALL_FORWARDING_TYPE_BUSY, l);
-
- ofono_debug("On Busy conditions:");
- cf_cond_list_print(l);
-
-out:
- if (cf->ss_req) {
- cls |= cf->ss_req->cls;
- cf->ss_req->cf_list[CALL_FORWARDING_TYPE_BUSY] = l;
- }
-
- cf->ops->query(modem, CALL_FORWARDING_TYPE_NO_REPLY,
- cls, cf_no_reply_callback, modem);
-}
-
-static void cf_unconditional_callback(const struct ofono_error *error, int total,
- const struct ofono_cf_condition *list,
- void *data)
-{
- struct ofono_modem *modem = data;
- struct call_forwarding_data *cf = modem->call_forwarding;
- GSList *l = NULL;
- int cls = BEARER_CLASS_DEFAULT | BEARER_CLASS_SMS;
-
- if (error->type != OFONO_ERROR_TYPE_NO_ERROR) {
- ofono_debug("Error during unconditional CF query");
- goto out;
- }
-
- l = cf_cond_list_create(total, list);
-
- set_new_cond_list(modem, CALL_FORWARDING_TYPE_UNCONDITIONAL, l);
-
- ofono_debug("Unconditional conditions:");
- cf_cond_list_print(l);
-
-out:
- if (cf->ss_req) {
- cls |= cf->ss_req->cls;
- cf->ss_req->cf_list[CALL_FORWARDING_TYPE_UNCONDITIONAL] = l;
- }
-
- cf->ops->query(modem, CALL_FORWARDING_TYPE_BUSY,
- cls, cf_busy_callback, modem);
-}
-
-static gboolean initiate_settings_request(void *data)
-{
- struct ofono_modem *modem = data;
- struct call_forwarding_data *call_forwarding = modem->call_forwarding;
-
- /* We can't get all settings at the same time according to 22.004:
- * "Interrogation of groups of Supplementary Services is not supported."
- * so we do it piecemeal, unconditional, busy, no reply, not reachable
- */
-
- if (call_forwarding->ops->query)
- call_forwarding->ops->query(modem,
- CALL_FORWARDING_TYPE_UNCONDITIONAL,
- BEARER_CLASS_DEFAULT | BEARER_CLASS_SMS,
- cf_unconditional_callback, modem);
-
- return FALSE;
-}
-
-static void request_settings(struct ofono_modem *modem)
-{
- g_timeout_add(0, initiate_settings_request, modem);
-}
-
int ofono_call_forwarding_register(struct ofono_modem *modem,
struct ofono_call_forwarding_ops *ops)
{
@@ -1405,8 +1172,6 @@ int ofono_call_forwarding_register(struct ofono_modem *modem,
modem_add_interface(modem, CALL_FORWARDING_INTERFACE);
- request_settings(modem);
-
return 0;
}