mirror of git://git.sysmocom.de/ofono
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:
parent
1b6369d188
commit
99b01eba7f
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue