Simplify CallWaiting plugin interface

The use of a struct with status & cls seemed pointless when only
a single integer can work just as well.

Also the Fax & Data attributes have been squished.  oFono does
not yet support those call types.
This commit is contained in:
Denis Kenzior 2009-05-28 11:21:26 -05:00
parent 1b6369d188
commit 99b01eba7f
3 changed files with 47 additions and 198 deletions

View File

@ -45,11 +45,11 @@ static void ccwa_query_cb(gboolean ok, GAtResult *result, gpointer user_data)
{
struct cb_data *cbd = user_data;
ofono_call_waiting_status_cb_t cb = cbd->cb;
int conditions = 0;
int status;
int cls;
struct ofono_error error;
GAtResultIter iter;
int num = 0;
struct ofono_cw_condition *list = NULL;
int i;
dump_response("ccwa_query_cb", ok, result);
decode_at_error(&error, g_at_result_final_response(result));
@ -59,40 +59,18 @@ static void ccwa_query_cb(gboolean ok, GAtResult *result, gpointer user_data)
g_at_result_iter_init(&iter, result);
while (g_at_result_iter_next(&iter, "+CCWA:"))
num += 1;
/* Specification is really unclear about this
* generate status=0 for all classes just in case
*/
if (num == 0) {
list = g_new(struct ofono_cw_condition, 1);
num = 1;
list->status = 0;
list->cls = GPOINTER_TO_INT(cbd->user);
goto out;
}
list = g_new(struct ofono_cw_condition, num);
g_at_result_iter_init(&iter, result);
num = 0;
while (g_at_result_iter_next(&iter, "+CCWA:")) {
g_at_result_iter_next_number(&iter, &(list[num].status));
g_at_result_iter_next_number(&iter, &(list[num].cls));
g_at_result_iter_next_number(&iter, &status);
g_at_result_iter_next_number(&iter, &cls);
num += 1;
if (status == 1)
conditions |= cls;
}
for (i = 0; i < num; i++)
ofono_debug("ccwa_cb: %d, %d", list[i].status, list[i].cls);
ofono_debug("CW enabled for: %d", conditions);
out:
cb(&error, num, list, cbd->data);
g_free(list);
cb(&error, conditions, cbd->data);
}
static void at_ccwa_query(struct ofono_modem *modem, int cls,
@ -122,7 +100,7 @@ error:
{
DECLARE_FAILURE(error);
cb(&error, 0, NULL, data);
cb(&error, 0, data);
}
}

View File

@ -47,53 +47,19 @@ struct call_waiting_data {
struct ofono_call_waiting_ops *ops;
int flags;
DBusMessage *pending;
GSList *cw_list;
int conditions;
int ss_req_type;
int ss_req_cls;
};
static const char *enabled = "enabled";
static const char *disabled = "disabled";
static void cw_register_ss_controls(struct ofono_modem *modem);
static void cw_unregister_ss_controls(struct ofono_modem *modem);
static gint cw_condition_compare(gconstpointer a, gconstpointer b)
{
const struct ofono_cw_condition *ca = a;
const struct ofono_cw_condition *cb = b;
if (ca->cls < cb->cls)
return -1;
if (ca->cls > cb->cls)
return 1;
return 0;
}
static gint cw_condition_find_with_cls(gconstpointer a, gconstpointer b)
{
const struct ofono_cw_condition *c = a;
int cls = GPOINTER_TO_INT(b);
if (c->cls < cls)
return -1;
if (c->cls > cls)
return 1;
return 0;
}
static struct call_waiting_data *call_waiting_create()
{
struct call_waiting_data *r;
r = g_try_new0(struct call_waiting_data, 1);
if (!r)
return r;
r = g_new0(struct call_waiting_data, 1);
return r;
}
@ -105,132 +71,59 @@ static void call_waiting_destroy(gpointer data)
cw_unregister_ss_controls(modem);
g_slist_foreach(cw->cw_list, (GFunc)g_free, NULL);
g_slist_free(cw->cw_list);
g_free(cw);
}
static void cw_cond_list_print(GSList *list)
{
GSList *l;
struct ofono_cw_condition *cond;
for (l = list; l; l = l->next) {
cond = l->data;
ofono_debug("CW condition status: %d, class: %d",
cond->status, cond->cls);
}
}
static GSList *cw_cond_list_create(int total,
const struct ofono_cw_condition *list)
{
GSList *l = NULL;
int i;
int j;
struct ofono_cw_condition *cond;
/* Specification is not really clear on how the results are reported,
* most modems report it as multiple list items, one for each class
* however, specification does leave room for a single compound value
* to be reported
*/
for (i = 0; i < total; i++) {
for (j = 1; j <= BEARER_CLASS_PAD; j = j << 1) {
if (!(list[i].cls & j))
continue;
if (list[i].status == 0)
continue;
cond = g_new0(struct ofono_cw_condition, 1);
memcpy(cond, &list[i], sizeof(struct ofono_cw_condition));
cond->cls = j;
l = g_slist_insert_sorted(l, cond,
cw_condition_compare);
}
}
return l;
}
static void set_new_cond_list(struct ofono_modem *modem, GSList *new_cw_list)
static void update_conditions(struct ofono_modem *modem, int new_conditions,
int mask)
{
struct call_waiting_data *cw = modem->call_waiting;
DBusConnection *conn = dbus_gsm_connection();
GSList *n;
GSList *o;
struct ofono_cw_condition *nc;
struct ofono_cw_condition *oc;
char buf[64];
int j;
const char *value;
for (n = new_cw_list; n; n = n->next) {
nc = n->data;
if (nc->cls > BEARER_CLASS_FAX)
for (j = 1; j <= BEARER_CLASS_PAD; j = j << 1) {
if ((j & mask) == 0)
continue;
sprintf(buf, "%s", bearer_class_to_string(nc->cls));
if ((cw->conditions & j) == (new_conditions & j))
continue;
o = g_slist_find_custom(cw->cw_list, GINT_TO_POINTER(nc->cls),
cw_condition_find_with_cls);
if (o) {
g_free(o->data);
cw->cw_list = g_slist_remove(cw->cw_list, o->data);
} else {
dbus_gsm_signal_property_changed(conn, modem->path,
CALL_WAITING_INTERFACE,
buf, DBUS_TYPE_STRING,
&enabled);
}
}
for (o = cw->cw_list; o; o = o->next) {
oc = o->data;
sprintf(buf, "%s", bearer_class_to_string(oc->cls));
if (new_conditions & j)
value = "enabled";
else
value = "disabled";
sprintf(buf, "%s", bearer_class_to_string(j));
dbus_gsm_signal_property_changed(conn, modem->path,
CALL_WAITING_INTERFACE,
buf, DBUS_TYPE_STRING,
&disabled);
&value);
}
g_slist_foreach(cw->cw_list, (GFunc)g_free, NULL);
g_slist_free(cw->cw_list);
cw->cw_list = new_cw_list;
cw->conditions = new_conditions;
}
static void property_append_cw_conditions(DBusMessageIter *dict,
GSList *cw_list, int mask)
int conditions, int mask)
{
GSList *l;
int i;
struct ofono_cw_condition *cw;
const char *prop;
const char *value;
for (i = 1, l = cw_list; i <= BEARER_CLASS_PAD; i = i << 1) {
for (i = 1; i <= BEARER_CLASS_PAD; i = i << 1) {
if (!(mask & i))
continue;
prop = bearer_class_to_string(i);
while (l && (cw = l->data) && (cw->cls < i))
l = l->next;
if (conditions & i)
value = "enabled";
else
value = "disabled";
if (!l || cw->cls != i) {
dbus_gsm_dict_append(dict, prop, DBUS_TYPE_STRING,
&disabled);
continue;
}
dbus_gsm_dict_append(dict, prop, DBUS_TYPE_STRING, &enabled);
dbus_gsm_dict_append(dict, prop, DBUS_TYPE_STRING, &value);
}
}
@ -263,7 +156,7 @@ static void generate_ss_query_reply(struct ofono_modem *modem)
dbus_message_iter_open_container(&vstruct, DBUS_TYPE_ARRAY,
PROPERTIES_ARRAY_SIGNATURE, &dict);
property_append_cw_conditions(&dict, cw->cw_list, cw->ss_req_cls);
property_append_cw_conditions(&dict, cw->conditions, cw->ss_req_cls);
dbus_message_iter_close_container(&vstruct, &dict);
@ -274,13 +167,11 @@ static void generate_ss_query_reply(struct ofono_modem *modem)
dbus_gsm_pending_reply(&cw->pending, reply);
}
static void cw_ss_query_callback(const struct ofono_error *error, int num,
struct ofono_cw_condition *cond_list,
static void cw_ss_query_callback(const struct ofono_error *error, int status,
void *data)
{
struct ofono_modem *modem = data;
struct call_waiting_data *cw = modem->call_waiting;
GSList *l;
if (error->type != OFONO_ERROR_TYPE_NO_ERROR) {
ofono_debug("setting CW via SS failed");
@ -292,11 +183,7 @@ static void cw_ss_query_callback(const struct ofono_error *error, int num,
return;
}
l = cw_cond_list_create(num, cond_list);
cw_cond_list_print(l);
set_new_cond_list(modem, l);
update_conditions(modem, status, BEARER_CLASS_VOICE);
cw->flags |= CALL_WAITING_FLAG_CACHED;
generate_ss_query_reply(modem);
@ -427,30 +314,26 @@ static DBusMessage *generate_get_properties_reply(struct ofono_modem *modem,
PROPERTIES_ARRAY_SIGNATURE,
&dict);
property_append_cw_conditions(&dict, cw->cw_list, BEARER_CLASS_DEFAULT);
property_append_cw_conditions(&dict, cw->conditions,
BEARER_CLASS_VOICE);
dbus_message_iter_close_container(&iter, &dict);
return reply;
}
static void cw_query_callback(const struct ofono_error *error, int num,
struct ofono_cw_condition *cond_list, void *data)
static void cw_query_callback(const struct ofono_error *error, int status,
void *data)
{
struct ofono_modem *modem = data;
struct call_waiting_data *cw = modem->call_waiting;
GSList *l = NULL;
if (error->type != OFONO_ERROR_TYPE_NO_ERROR) {
ofono_debug("Error during cw query");
goto out;
}
l = cw_cond_list_create(num, cond_list);
cw_cond_list_print(l);
set_new_cond_list(modem, l);
update_conditions(modem, status, BEARER_CLASS_VOICE);
cw->flags |= CALL_WAITING_FLAG_CACHED;
out:
@ -484,12 +367,11 @@ static DBusMessage *cw_get_properties(DBusConnection *conn, DBusMessage *msg,
return NULL;
}
static void set_query_callback(const struct ofono_error *error, int num,
struct ofono_cw_condition *cond_list, void *data)
static void set_query_callback(const struct ofono_error *error, int status,
void *data)
{
struct ofono_modem *modem = data;
struct call_waiting_data *cw = modem->call_waiting;
GSList *l = NULL;
if (error->type != OFONO_ERROR_TYPE_NO_ERROR) {
ofono_error("CW set succeeded, but query failed!");
@ -503,11 +385,7 @@ static void set_query_callback(const struct ofono_error *error, int num,
dbus_gsm_pending_reply(&cw->pending,
dbus_message_new_method_return(cw->pending));
l = cw_cond_list_create(num, cond_list);
cw_cond_list_print(l);
set_new_cond_list(modem, l);
update_conditions(modem, status, BEARER_CLASS_VOICE);
}
static void set_callback(const struct ofono_error *error, void *data)

View File

@ -90,12 +90,6 @@ struct ofono_cf_condition {
int time;
};
/* 27.007 Section 7.12 Call Waiting */
struct ofono_cw_condition {
int status;
int cls;
};
/* 27.007 Section 7.1 Subscriber Number */
struct ofono_own_number {
struct ofono_phone_number phone_number;
@ -150,8 +144,7 @@ typedef void (*ofono_clir_setting_cb_t)(const struct ofono_error *error,
int override, int network, void *data);
typedef void (*ofono_call_waiting_status_cb_t)(const struct ofono_error *error,
int num, struct ofono_cw_condition *cond,
void *data);
int status, void *data);
typedef void (*ofono_call_meter_query_cb_t)(const struct ofono_error *error,
int value, void *data);