mirror of git://git.sysmocom.de/ofono
Evolve the call-forwarding driver
This commit is contained in:
parent
2f37befd27
commit
872a24690d
|
@ -2,7 +2,7 @@
|
||||||
includedir = @includedir@/ofono
|
includedir = @includedir@/ofono
|
||||||
|
|
||||||
include_HEADERS = log.h plugin.h history.h dbus.h modem.h \
|
include_HEADERS = log.h plugin.h history.h dbus.h modem.h \
|
||||||
types.h call-barring.h
|
types.h call-barring.h call-forwarding.h
|
||||||
|
|
||||||
nodist_include_HEADERS = version.h
|
nodist_include_HEADERS = version.h
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,88 @@
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* oFono - Open Telephony stack for Linux
|
||||||
|
*
|
||||||
|
* Copyright (C) 2008-2009 Intel Corporation. All rights reserved.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __OFONO_CALL_FORWARDING_H
|
||||||
|
#define __OFONO_CALL_FORWARDING_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <ofono/types.h>
|
||||||
|
|
||||||
|
struct ofono_call_forwarding;
|
||||||
|
|
||||||
|
/* 27.007 Section 7.11 Call Forwarding */
|
||||||
|
struct ofono_call_forwarding_condition {
|
||||||
|
int status;
|
||||||
|
int cls;
|
||||||
|
struct ofono_phone_number phone_number;
|
||||||
|
int time;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef void (*ofono_call_forwarding_set_cb_t)(const struct ofono_error *error,
|
||||||
|
void *data);
|
||||||
|
typedef void (*ofono_call_forwarding_query_cb_t)(const struct ofono_error *error,
|
||||||
|
int total,
|
||||||
|
const struct ofono_call_forwarding_condition *list,
|
||||||
|
void *data);
|
||||||
|
|
||||||
|
struct ofono_call_forwarding_driver {
|
||||||
|
const char *name;
|
||||||
|
int (*probe)(struct ofono_call_forwarding *cf);
|
||||||
|
int (*remove)(struct ofono_call_forwarding *cf);
|
||||||
|
void (*activation)(struct ofono_call_forwarding *cf,
|
||||||
|
int type, int cls,
|
||||||
|
ofono_call_forwarding_set_cb_t cb, void *data);
|
||||||
|
void (*registration)(struct ofono_call_forwarding *cf,
|
||||||
|
int type, int cls,
|
||||||
|
const struct ofono_phone_number *number,
|
||||||
|
int time,
|
||||||
|
ofono_call_forwarding_set_cb_t cb, void *data);
|
||||||
|
void (*deactivation)(struct ofono_call_forwarding *cf,
|
||||||
|
int type, int cls,
|
||||||
|
ofono_call_forwarding_set_cb_t cb, void *data);
|
||||||
|
void (*erasure)(struct ofono_call_forwarding *cf, int type, int cls,
|
||||||
|
ofono_call_forwarding_set_cb_t cb, void *data);
|
||||||
|
void (*query)(struct ofono_call_forwarding *cf, int type, int cls,
|
||||||
|
ofono_call_forwarding_query_cb_t cb,
|
||||||
|
void *data);
|
||||||
|
};
|
||||||
|
|
||||||
|
int ofono_call_forwarding_driver_register(const struct ofono_call_forwarding_driver *d);
|
||||||
|
void ofono_call_forwarding_driver_unregister(const struct ofono_call_forwarding_driver *d);
|
||||||
|
|
||||||
|
struct ofono_call_forwarding *ofono_call_forwarding_create(struct ofono_modem *modem,
|
||||||
|
const char *driver,
|
||||||
|
void *data);
|
||||||
|
|
||||||
|
void ofono_call_forwarding_register(struct ofono_call_forwarding *cf);
|
||||||
|
void ofono_call_forwarding_remove(struct ofono_call_forwarding *cf);
|
||||||
|
|
||||||
|
void ofono_call_forwarding_set_data(struct ofono_call_forwarding *cf,
|
||||||
|
void *data);
|
||||||
|
void *ofono_call_forwarding_get_data(struct ofono_call_forwarding *cf);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __OFONO_CALL_FORWARDING_H */
|
|
@ -26,13 +26,13 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
#include <gdbus.h>
|
#include <gdbus.h>
|
||||||
|
|
||||||
#include "ofono.h"
|
#include "ofono.h"
|
||||||
|
|
||||||
#include "driver.h"
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "ussd.h"
|
#include "ussd.h"
|
||||||
|
|
||||||
|
@ -43,20 +43,25 @@
|
||||||
/* According to 27.007 Spec */
|
/* According to 27.007 Spec */
|
||||||
#define DEFAULT_NO_REPLY_TIMEOUT 20
|
#define DEFAULT_NO_REPLY_TIMEOUT 20
|
||||||
|
|
||||||
struct call_forwarding_data {
|
static GSList *g_drivers = NULL;
|
||||||
struct ofono_call_forwarding_ops *ops;
|
|
||||||
|
struct ofono_call_forwarding {
|
||||||
GSList *cf_conditions[4];
|
GSList *cf_conditions[4];
|
||||||
int flags;
|
int flags;
|
||||||
DBusMessage *pending;
|
DBusMessage *pending;
|
||||||
int query_next;
|
int query_next;
|
||||||
int query_end;
|
int query_end;
|
||||||
struct cf_ss_request *ss_req;
|
struct cf_ss_request *ss_req;
|
||||||
|
const struct ofono_call_forwarding_driver *driver;
|
||||||
|
void *driver_data;
|
||||||
|
struct ofono_modem *modem;
|
||||||
|
struct ofono_atom *atom;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void get_query_next_cf_cond(struct ofono_modem *modem);
|
static void get_query_next_cf_cond(struct ofono_call_forwarding *cf);
|
||||||
static void set_query_next_cf_cond(struct ofono_modem *modem);
|
static void set_query_next_cf_cond(struct ofono_call_forwarding *cf);
|
||||||
static void ss_set_query_next_cf_cond(struct ofono_modem *modem);
|
static void ss_set_query_next_cf_cond(struct ofono_call_forwarding *cf);
|
||||||
static void cf_unregister_ss_controls(struct ofono_modem *modem);
|
static void cf_unregister_ss_controls(struct ofono_call_forwarding *cf);
|
||||||
|
|
||||||
struct cf_ss_request {
|
struct cf_ss_request {
|
||||||
int ss_type;
|
int ss_type;
|
||||||
|
@ -67,8 +72,8 @@ struct cf_ss_request {
|
||||||
|
|
||||||
static gint cf_condition_compare(gconstpointer a, gconstpointer b)
|
static gint cf_condition_compare(gconstpointer a, gconstpointer b)
|
||||||
{
|
{
|
||||||
const struct ofono_cf_condition *ca = a;
|
const struct ofono_call_forwarding_condition *ca = a;
|
||||||
const struct ofono_cf_condition *cb = b;
|
const struct ofono_call_forwarding_condition *cb = b;
|
||||||
|
|
||||||
if (ca->cls < cb->cls)
|
if (ca->cls < cb->cls)
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -81,7 +86,7 @@ static gint cf_condition_compare(gconstpointer a, gconstpointer b)
|
||||||
|
|
||||||
static gint cf_condition_find_with_cls(gconstpointer a, gconstpointer b)
|
static gint cf_condition_find_with_cls(gconstpointer a, gconstpointer b)
|
||||||
{
|
{
|
||||||
const struct ofono_cf_condition *c = a;
|
const struct ofono_call_forwarding_condition *c = a;
|
||||||
int cls = GPOINTER_TO_INT(b);
|
int cls = GPOINTER_TO_INT(b);
|
||||||
|
|
||||||
if (c->cls < cls)
|
if (c->cls < cls)
|
||||||
|
@ -96,7 +101,7 @@ static gint cf_condition_find_with_cls(gconstpointer a, gconstpointer b)
|
||||||
static int cf_find_timeout(GSList *cf_list, int cls)
|
static int cf_find_timeout(GSList *cf_list, int cls)
|
||||||
{
|
{
|
||||||
GSList *l;
|
GSList *l;
|
||||||
struct ofono_cf_condition *c;
|
struct ofono_call_forwarding_condition *c;
|
||||||
|
|
||||||
l = g_slist_find_custom(cf_list, GINT_TO_POINTER(cls),
|
l = g_slist_find_custom(cf_list, GINT_TO_POINTER(cls),
|
||||||
cf_condition_find_with_cls);
|
cf_condition_find_with_cls);
|
||||||
|
@ -112,7 +117,7 @@ static int cf_find_timeout(GSList *cf_list, int cls)
|
||||||
static void cf_cond_list_print(GSList *list)
|
static void cf_cond_list_print(GSList *list)
|
||||||
{
|
{
|
||||||
GSList *l;
|
GSList *l;
|
||||||
struct ofono_cf_condition *cond;
|
struct ofono_call_forwarding_condition *cond;
|
||||||
|
|
||||||
for (l = list; l; l = l->next) {
|
for (l = list; l; l = l->next) {
|
||||||
cond = l->data;
|
cond = l->data;
|
||||||
|
@ -125,12 +130,12 @@ static void cf_cond_list_print(GSList *list)
|
||||||
}
|
}
|
||||||
|
|
||||||
static GSList *cf_cond_list_create(int total,
|
static GSList *cf_cond_list_create(int total,
|
||||||
const struct ofono_cf_condition *list)
|
const struct ofono_call_forwarding_condition *list)
|
||||||
{
|
{
|
||||||
GSList *l = NULL;
|
GSList *l = NULL;
|
||||||
int i;
|
int i;
|
||||||
int j;
|
int j;
|
||||||
struct ofono_cf_condition *cond;
|
struct ofono_call_forwarding_condition *cond;
|
||||||
|
|
||||||
/* Specification is not really clear how the results are reported,
|
/* Specification is not really clear how the results are reported,
|
||||||
* so assume both multiple list items & compound values of class
|
* so assume both multiple list items & compound values of class
|
||||||
|
@ -144,11 +149,12 @@ static GSList *cf_cond_list_create(int total,
|
||||||
if (list[i].status == 0)
|
if (list[i].status == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
cond = g_try_new0(struct ofono_cf_condition, 1);
|
cond = g_try_new0(struct ofono_call_forwarding_condition, 1);
|
||||||
if (!cond)
|
if (!cond)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
memcpy(cond, &list[i], sizeof(struct ofono_cf_condition));
|
memcpy(cond, &list[i],
|
||||||
|
sizeof(struct ofono_call_forwarding_condition));
|
||||||
cond->cls = j;
|
cond->cls = j;
|
||||||
|
|
||||||
l = g_slist_insert_sorted(l, cond,
|
l = g_slist_insert_sorted(l, cond,
|
||||||
|
@ -169,7 +175,7 @@ static inline void cf_list_clear(GSList *cf_list)
|
||||||
g_slist_free(cf_list);
|
g_slist_free(cf_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void cf_clear_all(struct call_forwarding_data *cf)
|
static inline void cf_clear_all(struct ofono_call_forwarding *cf)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
@ -179,30 +185,6 @@ static inline void cf_clear_all(struct call_forwarding_data *cf)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct call_forwarding_data *call_forwarding_create()
|
|
||||||
{
|
|
||||||
struct call_forwarding_data *r;
|
|
||||||
|
|
||||||
r = g_try_new0(struct call_forwarding_data, 1);
|
|
||||||
|
|
||||||
if (!r)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void call_forwarding_destroy(gpointer data)
|
|
||||||
{
|
|
||||||
struct ofono_modem *modem = data;
|
|
||||||
struct call_forwarding_data *cf = modem->call_forwarding;
|
|
||||||
|
|
||||||
cf_clear_all(cf);
|
|
||||||
|
|
||||||
cf_unregister_ss_controls(modem);
|
|
||||||
|
|
||||||
g_free(cf);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const char *cf_type_lut[] = {
|
static const char *cf_type_lut[] = {
|
||||||
"Unconditional",
|
"Unconditional",
|
||||||
"Busy",
|
"Busy",
|
||||||
|
@ -212,15 +194,16 @@ static const char *cf_type_lut[] = {
|
||||||
"AllConditional"
|
"AllConditional"
|
||||||
};
|
};
|
||||||
|
|
||||||
static void set_new_cond_list(struct ofono_modem *modem, int type, GSList *list)
|
static void set_new_cond_list(struct ofono_call_forwarding *cf,
|
||||||
|
int type, GSList *list)
|
||||||
{
|
{
|
||||||
struct call_forwarding_data *cf = modem->call_forwarding;
|
|
||||||
GSList *old = cf->cf_conditions[type];
|
GSList *old = cf->cf_conditions[type];
|
||||||
DBusConnection *conn = ofono_dbus_get_connection();
|
DBusConnection *conn = ofono_dbus_get_connection();
|
||||||
|
const char *path = ofono_modem_get_path(cf->modem);
|
||||||
GSList *l;
|
GSList *l;
|
||||||
GSList *o;
|
GSList *o;
|
||||||
struct ofono_cf_condition *lc;
|
struct ofono_call_forwarding_condition *lc;
|
||||||
struct ofono_cf_condition *oc;
|
struct ofono_call_forwarding_condition *oc;
|
||||||
const char *number;
|
const char *number;
|
||||||
dbus_uint16_t timeout;
|
dbus_uint16_t timeout;
|
||||||
char attr[64];
|
char attr[64];
|
||||||
|
@ -255,16 +238,14 @@ static void set_new_cond_list(struct ofono_modem *modem, int type, GSList *list)
|
||||||
if (oc->phone_number.type != lc->phone_number.type ||
|
if (oc->phone_number.type != lc->phone_number.type ||
|
||||||
strcmp(oc->phone_number.number,
|
strcmp(oc->phone_number.number,
|
||||||
lc->phone_number.number))
|
lc->phone_number.number))
|
||||||
ofono_dbus_signal_property_changed(conn,
|
ofono_dbus_signal_property_changed(conn, path,
|
||||||
modem->path,
|
|
||||||
CALL_FORWARDING_INTERFACE,
|
CALL_FORWARDING_INTERFACE,
|
||||||
attr, DBUS_TYPE_STRING,
|
attr, DBUS_TYPE_STRING,
|
||||||
&number);
|
&number);
|
||||||
|
|
||||||
if (type == CALL_FORWARDING_TYPE_NO_REPLY &&
|
if (type == CALL_FORWARDING_TYPE_NO_REPLY &&
|
||||||
oc->time != lc->time)
|
oc->time != lc->time)
|
||||||
ofono_dbus_signal_property_changed(conn,
|
ofono_dbus_signal_property_changed(conn, path,
|
||||||
modem->path,
|
|
||||||
CALL_FORWARDING_INTERFACE,
|
CALL_FORWARDING_INTERFACE,
|
||||||
tattr, DBUS_TYPE_UINT16,
|
tattr, DBUS_TYPE_UINT16,
|
||||||
&timeout);
|
&timeout);
|
||||||
|
@ -275,15 +256,14 @@ static void set_new_cond_list(struct ofono_modem *modem, int type, GSList *list)
|
||||||
} else {
|
} else {
|
||||||
number = phone_number_to_string(&lc->phone_number);
|
number = phone_number_to_string(&lc->phone_number);
|
||||||
|
|
||||||
ofono_dbus_signal_property_changed(conn, modem->path,
|
ofono_dbus_signal_property_changed(conn, path,
|
||||||
CALL_FORWARDING_INTERFACE,
|
CALL_FORWARDING_INTERFACE,
|
||||||
attr, DBUS_TYPE_STRING,
|
attr, DBUS_TYPE_STRING,
|
||||||
&number);
|
&number);
|
||||||
|
|
||||||
if (type == CALL_FORWARDING_TYPE_NO_REPLY &&
|
if (type == CALL_FORWARDING_TYPE_NO_REPLY &&
|
||||||
lc->time != DEFAULT_NO_REPLY_TIMEOUT)
|
lc->time != DEFAULT_NO_REPLY_TIMEOUT)
|
||||||
ofono_dbus_signal_property_changed(conn,
|
ofono_dbus_signal_property_changed(conn, path,
|
||||||
modem->path,
|
|
||||||
CALL_FORWARDING_INTERFACE,
|
CALL_FORWARDING_INTERFACE,
|
||||||
tattr, DBUS_TYPE_UINT16,
|
tattr, DBUS_TYPE_UINT16,
|
||||||
&timeout);
|
&timeout);
|
||||||
|
@ -302,13 +282,13 @@ static void set_new_cond_list(struct ofono_modem *modem, int type, GSList *list)
|
||||||
if (type == CALL_FORWARDING_TYPE_NO_REPLY)
|
if (type == CALL_FORWARDING_TYPE_NO_REPLY)
|
||||||
sprintf(tattr, "%sTimeout", attr);
|
sprintf(tattr, "%sTimeout", attr);
|
||||||
|
|
||||||
ofono_dbus_signal_property_changed(conn, modem->path,
|
ofono_dbus_signal_property_changed(conn, path,
|
||||||
CALL_FORWARDING_INTERFACE, attr,
|
CALL_FORWARDING_INTERFACE, attr,
|
||||||
DBUS_TYPE_STRING, &number);
|
DBUS_TYPE_STRING, &number);
|
||||||
|
|
||||||
if (type == CALL_FORWARDING_TYPE_NO_REPLY &&
|
if (type == CALL_FORWARDING_TYPE_NO_REPLY &&
|
||||||
oc->time != DEFAULT_NO_REPLY_TIMEOUT)
|
oc->time != DEFAULT_NO_REPLY_TIMEOUT)
|
||||||
ofono_dbus_signal_property_changed(conn, modem->path,
|
ofono_dbus_signal_property_changed(conn, path,
|
||||||
CALL_FORWARDING_INTERFACE,
|
CALL_FORWARDING_INTERFACE,
|
||||||
tattr, DBUS_TYPE_UINT16,
|
tattr, DBUS_TYPE_UINT16,
|
||||||
&timeout);
|
&timeout);
|
||||||
|
@ -345,7 +325,7 @@ static void property_append_cf_conditions(DBusMessageIter *dict,
|
||||||
{
|
{
|
||||||
GSList *l;
|
GSList *l;
|
||||||
int i;
|
int i;
|
||||||
struct ofono_cf_condition *cf;
|
struct ofono_call_forwarding_condition *cf;
|
||||||
const char *number;
|
const char *number;
|
||||||
|
|
||||||
for (i = 1, l = cf_list; i <= BEARER_CLASS_PAD; i = i << 1) {
|
for (i = 1, l = cf_list; i <= BEARER_CLASS_PAD; i = i << 1) {
|
||||||
|
@ -369,7 +349,7 @@ static void property_append_cf_conditions(DBusMessageIter *dict,
|
||||||
}
|
}
|
||||||
|
|
||||||
static DBusMessage *cf_get_properties_reply(DBusMessage *msg,
|
static DBusMessage *cf_get_properties_reply(DBusMessage *msg,
|
||||||
struct call_forwarding_data *cf)
|
struct ofono_call_forwarding *cf)
|
||||||
{
|
{
|
||||||
DBusMessage *reply;
|
DBusMessage *reply;
|
||||||
DBusMessageIter iter;
|
DBusMessageIter iter;
|
||||||
|
@ -398,16 +378,15 @@ static DBusMessage *cf_get_properties_reply(DBusMessage *msg,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void get_query_cf_callback(const struct ofono_error *error, int total,
|
static void get_query_cf_callback(const struct ofono_error *error, int total,
|
||||||
const struct ofono_cf_condition *list,
|
const struct ofono_call_forwarding_condition *list,
|
||||||
void *data)
|
void *data)
|
||||||
{
|
{
|
||||||
struct ofono_modem *modem = data;
|
struct ofono_call_forwarding *cf = data;
|
||||||
struct call_forwarding_data *cf = modem->call_forwarding;
|
|
||||||
|
|
||||||
if (error->type == OFONO_ERROR_TYPE_NO_ERROR) {
|
if (error->type == OFONO_ERROR_TYPE_NO_ERROR) {
|
||||||
GSList *l;
|
GSList *l;
|
||||||
l = cf_cond_list_create(total, list);
|
l = cf_cond_list_create(total, list);
|
||||||
set_new_cond_list(modem, cf->query_next, l);
|
set_new_cond_list(cf, cf->query_next, l);
|
||||||
|
|
||||||
ofono_debug("%s conditions:", cf_type_lut[cf->query_next]);
|
ofono_debug("%s conditions:", cf_type_lut[cf->query_next]);
|
||||||
cf_cond_list_print(l);
|
cf_cond_list_print(l);
|
||||||
|
@ -423,27 +402,24 @@ static void get_query_cf_callback(const struct ofono_error *error, int total,
|
||||||
}
|
}
|
||||||
|
|
||||||
cf->query_next++;
|
cf->query_next++;
|
||||||
get_query_next_cf_cond(modem);
|
get_query_next_cf_cond(cf);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void get_query_next_cf_cond(struct ofono_modem *modem)
|
static void get_query_next_cf_cond(struct ofono_call_forwarding *cf)
|
||||||
{
|
{
|
||||||
struct call_forwarding_data *cf = modem->call_forwarding;
|
cf->driver->query(cf, cf->query_next, BEARER_CLASS_DEFAULT,
|
||||||
|
get_query_cf_callback, cf);
|
||||||
cf->ops->query(modem, cf->query_next, BEARER_CLASS_DEFAULT,
|
|
||||||
get_query_cf_callback, modem);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static DBusMessage *cf_get_properties(DBusConnection *conn, DBusMessage *msg,
|
static DBusMessage *cf_get_properties(DBusConnection *conn, DBusMessage *msg,
|
||||||
void *data)
|
void *data)
|
||||||
{
|
{
|
||||||
struct ofono_modem *modem = data;
|
struct ofono_call_forwarding *cf = data;
|
||||||
struct call_forwarding_data *cf = modem->call_forwarding;
|
|
||||||
|
|
||||||
if (cf->flags & CALL_FORWARDING_FLAG_CACHED)
|
if (cf->flags & CALL_FORWARDING_FLAG_CACHED)
|
||||||
return cf_get_properties_reply(msg, cf);
|
return cf_get_properties_reply(msg, cf);
|
||||||
|
|
||||||
if (!cf->ops->query)
|
if (!cf->driver->query)
|
||||||
return __ofono_error_not_implemented(msg);
|
return __ofono_error_not_implemented(msg);
|
||||||
|
|
||||||
if (cf->pending)
|
if (cf->pending)
|
||||||
|
@ -452,12 +428,12 @@ static DBusMessage *cf_get_properties(DBusConnection *conn, DBusMessage *msg,
|
||||||
cf->pending = dbus_message_ref(msg);
|
cf->pending = dbus_message_ref(msg);
|
||||||
cf->query_next = 0;
|
cf->query_next = 0;
|
||||||
|
|
||||||
get_query_next_cf_cond(modem);
|
get_query_next_cf_cond(cf);
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean cf_condition_enabled_property(struct call_forwarding_data *cf,
|
static gboolean cf_condition_enabled_property(struct ofono_call_forwarding *cf,
|
||||||
const char *property, int *out_type, int *out_cls)
|
const char *property, int *out_type, int *out_cls)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
@ -512,11 +488,10 @@ static gboolean cf_condition_timeout_property(const char *property,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void set_query_cf_callback(const struct ofono_error *error, int total,
|
static void set_query_cf_callback(const struct ofono_error *error, int total,
|
||||||
const struct ofono_cf_condition *list,
|
const struct ofono_call_forwarding_condition *list,
|
||||||
void *data)
|
void *data)
|
||||||
{
|
{
|
||||||
struct ofono_modem *modem = data;
|
struct ofono_call_forwarding *cf = data;
|
||||||
struct call_forwarding_data *cf = modem->call_forwarding;
|
|
||||||
GSList *l;
|
GSList *l;
|
||||||
DBusMessage *reply;
|
DBusMessage *reply;
|
||||||
|
|
||||||
|
@ -534,29 +509,26 @@ static void set_query_cf_callback(const struct ofono_error *error, int total,
|
||||||
}
|
}
|
||||||
|
|
||||||
l = cf_cond_list_create(total, list);
|
l = cf_cond_list_create(total, list);
|
||||||
set_new_cond_list(modem, cf->query_next, l);
|
set_new_cond_list(cf, cf->query_next, l);
|
||||||
|
|
||||||
ofono_debug("%s conditions:", cf_type_lut[cf->query_next]);
|
ofono_debug("%s conditions:", cf_type_lut[cf->query_next]);
|
||||||
cf_cond_list_print(l);
|
cf_cond_list_print(l);
|
||||||
|
|
||||||
if (cf->query_next != cf->query_end) {
|
if (cf->query_next != cf->query_end) {
|
||||||
cf->query_next++;
|
cf->query_next++;
|
||||||
set_query_next_cf_cond(modem);
|
set_query_next_cf_cond(cf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void set_query_next_cf_cond(struct ofono_modem *modem)
|
static void set_query_next_cf_cond(struct ofono_call_forwarding *cf)
|
||||||
{
|
{
|
||||||
struct call_forwarding_data *cf = modem->call_forwarding;
|
cf->driver->query(cf, cf->query_next, BEARER_CLASS_DEFAULT,
|
||||||
|
set_query_cf_callback, cf);
|
||||||
cf->ops->query(modem, cf->query_next, BEARER_CLASS_DEFAULT,
|
|
||||||
set_query_cf_callback, modem);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void set_property_callback(const struct ofono_error *error, void *data)
|
static void set_property_callback(const struct ofono_error *error, void *data)
|
||||||
{
|
{
|
||||||
struct ofono_modem *modem = data;
|
struct ofono_call_forwarding *cf = data;
|
||||||
struct call_forwarding_data *cf = modem->call_forwarding;
|
|
||||||
|
|
||||||
if (error->type != OFONO_ERROR_TYPE_NO_ERROR) {
|
if (error->type != OFONO_ERROR_TYPE_NO_ERROR) {
|
||||||
ofono_debug("Error occurred during set/erasure");
|
ofono_debug("Error occurred during set/erasure");
|
||||||
|
@ -566,21 +538,19 @@ static void set_property_callback(const struct ofono_error *error, void *data)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Successfully set, query the entire set just in case */
|
/* Successfully set, query the entire set just in case */
|
||||||
set_query_next_cf_cond(modem);
|
set_query_next_cf_cond(cf);
|
||||||
}
|
}
|
||||||
|
|
||||||
static DBusMessage *set_property_request(struct ofono_modem *modem,
|
static DBusMessage *set_property_request(struct ofono_call_forwarding *cf,
|
||||||
DBusMessage *msg,
|
DBusMessage *msg,
|
||||||
int type, int cls,
|
int type, int cls,
|
||||||
struct ofono_phone_number *ph,
|
struct ofono_phone_number *ph,
|
||||||
int timeout)
|
int timeout)
|
||||||
{
|
{
|
||||||
struct call_forwarding_data *cf = modem->call_forwarding;
|
if (ph->number[0] != '\0' && cf->driver->registration == NULL)
|
||||||
|
|
||||||
if (ph->number[0] != '\0' && cf->ops->registration == NULL)
|
|
||||||
return __ofono_error_not_implemented(msg);
|
return __ofono_error_not_implemented(msg);
|
||||||
|
|
||||||
if (ph->number[0] == '\0' && cf->ops->erasure == NULL)
|
if (ph->number[0] == '\0' && cf->driver->erasure == NULL)
|
||||||
return __ofono_error_not_implemented(msg);
|
return __ofono_error_not_implemented(msg);
|
||||||
|
|
||||||
cf->pending = dbus_message_ref(msg);
|
cf->pending = dbus_message_ref(msg);
|
||||||
|
@ -591,10 +561,10 @@ static DBusMessage *set_property_request(struct ofono_modem *modem,
|
||||||
ph->number[0] == '\0');
|
ph->number[0] == '\0');
|
||||||
|
|
||||||
if (ph->number[0] != '\0')
|
if (ph->number[0] != '\0')
|
||||||
cf->ops->registration(modem, type, cls, ph, timeout,
|
cf->driver->registration(cf, type, cls, ph, timeout,
|
||||||
set_property_callback, modem);
|
set_property_callback, cf);
|
||||||
else
|
else
|
||||||
cf->ops->erasure(modem, type, cls, set_property_callback, modem);
|
cf->driver->erasure(cf, type, cls, set_property_callback, cf);
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -602,8 +572,7 @@ static DBusMessage *set_property_request(struct ofono_modem *modem,
|
||||||
static DBusMessage *cf_set_property(DBusConnection *conn, DBusMessage *msg,
|
static DBusMessage *cf_set_property(DBusConnection *conn, DBusMessage *msg,
|
||||||
void *data)
|
void *data)
|
||||||
{
|
{
|
||||||
struct ofono_modem *modem = data;
|
struct ofono_call_forwarding *cf = data;
|
||||||
struct call_forwarding_data *cf = modem->call_forwarding;
|
|
||||||
DBusMessageIter iter;
|
DBusMessageIter iter;
|
||||||
DBusMessageIter var;
|
DBusMessageIter var;
|
||||||
const char *property;
|
const char *property;
|
||||||
|
@ -630,7 +599,7 @@ static DBusMessage *cf_set_property(DBusConnection *conn, DBusMessage *msg,
|
||||||
if (cf_condition_timeout_property(property, &cls)) {
|
if (cf_condition_timeout_property(property, &cls)) {
|
||||||
dbus_uint16_t timeout;
|
dbus_uint16_t timeout;
|
||||||
GSList *l;
|
GSList *l;
|
||||||
struct ofono_cf_condition *c;
|
struct ofono_call_forwarding_condition *c;
|
||||||
|
|
||||||
type = CALL_FORWARDING_TYPE_NO_REPLY;
|
type = CALL_FORWARDING_TYPE_NO_REPLY;
|
||||||
|
|
||||||
|
@ -651,7 +620,7 @@ static DBusMessage *cf_set_property(DBusConnection *conn, DBusMessage *msg,
|
||||||
|
|
||||||
c = l->data;
|
c = l->data;
|
||||||
|
|
||||||
return set_property_request(modem, msg, type, cls,
|
return set_property_request(cf, msg, type, cls,
|
||||||
&c->phone_number, timeout);
|
&c->phone_number, timeout);
|
||||||
} else if (cf_condition_enabled_property(cf, property, &type, &cls)) {
|
} else if (cf_condition_enabled_property(cf, property, &type, &cls)) {
|
||||||
struct ofono_phone_number ph;
|
struct ofono_phone_number ph;
|
||||||
|
@ -674,7 +643,7 @@ static DBusMessage *cf_set_property(DBusConnection *conn, DBusMessage *msg,
|
||||||
|
|
||||||
timeout = cf_find_timeout(cf->cf_conditions[type], cls);
|
timeout = cf_find_timeout(cf->cf_conditions[type], cls);
|
||||||
|
|
||||||
return set_property_request(modem, msg, type, cls, &ph,
|
return set_property_request(cf, msg, type, cls, &ph,
|
||||||
timeout);
|
timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -684,8 +653,7 @@ static DBusMessage *cf_set_property(DBusConnection *conn, DBusMessage *msg,
|
||||||
static void disable_conditional_callback(const struct ofono_error *error,
|
static void disable_conditional_callback(const struct ofono_error *error,
|
||||||
void *data)
|
void *data)
|
||||||
{
|
{
|
||||||
struct ofono_modem *modem = data;
|
struct ofono_call_forwarding *cf = data;
|
||||||
struct call_forwarding_data *cf = modem->call_forwarding;
|
|
||||||
|
|
||||||
if (error->type != OFONO_ERROR_TYPE_NO_ERROR) {
|
if (error->type != OFONO_ERROR_TYPE_NO_ERROR) {
|
||||||
ofono_debug("Error occurred during conditional erasure");
|
ofono_debug("Error occurred during conditional erasure");
|
||||||
|
@ -698,13 +666,12 @@ static void disable_conditional_callback(const struct ofono_error *error,
|
||||||
/* Query the three conditional cf types */
|
/* Query the three conditional cf types */
|
||||||
cf->query_next = CALL_FORWARDING_TYPE_BUSY;
|
cf->query_next = CALL_FORWARDING_TYPE_BUSY;
|
||||||
cf->query_end = CALL_FORWARDING_TYPE_NOT_REACHABLE;
|
cf->query_end = CALL_FORWARDING_TYPE_NOT_REACHABLE;
|
||||||
set_query_next_cf_cond(modem);
|
set_query_next_cf_cond(cf);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void disable_all_callback(const struct ofono_error *error, void *data)
|
static void disable_all_callback(const struct ofono_error *error, void *data)
|
||||||
{
|
{
|
||||||
struct ofono_modem *modem = data;
|
struct ofono_call_forwarding *cf = data;
|
||||||
struct call_forwarding_data *cf = modem->call_forwarding;
|
|
||||||
|
|
||||||
if (error->type != OFONO_ERROR_TYPE_NO_ERROR) {
|
if (error->type != OFONO_ERROR_TYPE_NO_ERROR) {
|
||||||
ofono_debug("Error occurred during erasure of all");
|
ofono_debug("Error occurred during erasure of all");
|
||||||
|
@ -717,21 +684,20 @@ static void disable_all_callback(const struct ofono_error *error, void *data)
|
||||||
/* Query all cf types */
|
/* Query all cf types */
|
||||||
cf->query_next = CALL_FORWARDING_TYPE_UNCONDITIONAL;
|
cf->query_next = CALL_FORWARDING_TYPE_UNCONDITIONAL;
|
||||||
cf->query_end = CALL_FORWARDING_TYPE_NOT_REACHABLE;
|
cf->query_end = CALL_FORWARDING_TYPE_NOT_REACHABLE;
|
||||||
set_query_next_cf_cond(modem);
|
set_query_next_cf_cond(cf);
|
||||||
}
|
}
|
||||||
|
|
||||||
static DBusMessage *cf_disable_all(DBusConnection *conn, DBusMessage *msg,
|
static DBusMessage *cf_disable_all(DBusConnection *conn, DBusMessage *msg,
|
||||||
void *data)
|
void *data)
|
||||||
{
|
{
|
||||||
struct ofono_modem *modem = data;
|
struct ofono_call_forwarding *cf = data;
|
||||||
struct call_forwarding_data *cf = modem->call_forwarding;
|
|
||||||
const char *strtype;
|
const char *strtype;
|
||||||
int type;
|
int type;
|
||||||
|
|
||||||
if (cf->pending)
|
if (cf->pending)
|
||||||
return __ofono_error_busy(msg);
|
return __ofono_error_busy(msg);
|
||||||
|
|
||||||
if (!cf->ops->erasure)
|
if (!cf->driver->erasure)
|
||||||
return __ofono_error_not_implemented(msg);
|
return __ofono_error_not_implemented(msg);
|
||||||
|
|
||||||
if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &strtype,
|
if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &strtype,
|
||||||
|
@ -748,11 +714,11 @@ static DBusMessage *cf_disable_all(DBusConnection *conn, DBusMessage *msg,
|
||||||
cf->pending = dbus_message_ref(msg);
|
cf->pending = dbus_message_ref(msg);
|
||||||
|
|
||||||
if (type == CALL_FORWARDING_TYPE_ALL)
|
if (type == CALL_FORWARDING_TYPE_ALL)
|
||||||
cf->ops->erasure(modem, type, BEARER_CLASS_DEFAULT,
|
cf->driver->erasure(cf, type, BEARER_CLASS_DEFAULT,
|
||||||
disable_all_callback, modem);
|
disable_all_callback, cf);
|
||||||
else
|
else
|
||||||
cf->ops->erasure(modem, type, BEARER_CLASS_DEFAULT,
|
cf->driver->erasure(cf, type, BEARER_CLASS_DEFAULT,
|
||||||
disable_conditional_callback, modem);
|
disable_conditional_callback, cf);
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -772,10 +738,9 @@ static GDBusSignalTable cf_signals[] = {
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
|
|
||||||
static DBusMessage *cf_ss_control_reply(struct ofono_modem *modem,
|
static DBusMessage *cf_ss_control_reply(struct ofono_call_forwarding *cf,
|
||||||
struct cf_ss_request *req)
|
struct cf_ss_request *req)
|
||||||
{
|
{
|
||||||
struct call_forwarding_data *cf = modem->call_forwarding;
|
|
||||||
const char *context = "CallForwarding";
|
const char *context = "CallForwarding";
|
||||||
const char *sig = "(ssa{sv})";
|
const char *sig = "(ssa{sv})";
|
||||||
const char *ss_type = ss_control_type_to_string(req->ss_type);
|
const char *ss_type = ss_control_type_to_string(req->ss_type);
|
||||||
|
@ -846,11 +811,10 @@ static DBusMessage *cf_ss_control_reply(struct ofono_modem *modem,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ss_set_query_cf_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,
|
const struct ofono_call_forwarding_condition *list,
|
||||||
void *data)
|
void *data)
|
||||||
{
|
{
|
||||||
struct ofono_modem *modem = data;
|
struct ofono_call_forwarding *cf = data;
|
||||||
struct call_forwarding_data *cf = modem->call_forwarding;
|
|
||||||
GSList *l;
|
GSList *l;
|
||||||
DBusMessage *reply;
|
DBusMessage *reply;
|
||||||
|
|
||||||
|
@ -869,32 +833,29 @@ static void ss_set_query_cf_callback(const struct ofono_error *error, int total,
|
||||||
cf->ss_req->cf_list[cf->query_next] = l;
|
cf->ss_req->cf_list[cf->query_next] = l;
|
||||||
|
|
||||||
if (cf->query_next == cf->query_end) {
|
if (cf->query_next == cf->query_end) {
|
||||||
reply = cf_ss_control_reply(modem, cf->ss_req);
|
reply = cf_ss_control_reply(cf, cf->ss_req);
|
||||||
__ofono_dbus_pending_reply(&cf->pending, reply);
|
__ofono_dbus_pending_reply(&cf->pending, reply);
|
||||||
g_free(cf->ss_req);
|
g_free(cf->ss_req);
|
||||||
cf->ss_req = NULL;
|
cf->ss_req = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
set_new_cond_list(modem, cf->query_next, l);
|
set_new_cond_list(cf, cf->query_next, l);
|
||||||
|
|
||||||
if (cf->query_next != cf->query_end) {
|
if (cf->query_next != cf->query_end) {
|
||||||
cf->query_next++;
|
cf->query_next++;
|
||||||
ss_set_query_next_cf_cond(modem);
|
ss_set_query_next_cf_cond(cf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ss_set_query_next_cf_cond(struct ofono_modem *modem)
|
static void ss_set_query_next_cf_cond(struct ofono_call_forwarding *cf)
|
||||||
{
|
{
|
||||||
struct call_forwarding_data *cf = modem->call_forwarding;
|
cf->driver->query(cf, cf->query_next, BEARER_CLASS_DEFAULT,
|
||||||
|
ss_set_query_cf_callback, cf);
|
||||||
cf->ops->query(modem, cf->query_next, BEARER_CLASS_DEFAULT,
|
|
||||||
ss_set_query_cf_callback, modem);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cf_ss_control_callback(const struct ofono_error *error, void *data)
|
static void cf_ss_control_callback(const struct ofono_error *error, void *data)
|
||||||
{
|
{
|
||||||
struct ofono_modem *modem = data;
|
struct ofono_call_forwarding *cf = data;
|
||||||
struct call_forwarding_data *cf = modem->call_forwarding;
|
|
||||||
|
|
||||||
if (error->type != OFONO_ERROR_TYPE_NO_ERROR) {
|
if (error->type != OFONO_ERROR_TYPE_NO_ERROR) {
|
||||||
ofono_debug("Error occurred during cf ss control set/erasure");
|
ofono_debug("Error occurred during cf ss control set/erasure");
|
||||||
|
@ -906,7 +867,7 @@ static void cf_ss_control_callback(const struct ofono_error *error, void *data)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ss_set_query_next_cf_cond(modem);
|
ss_set_query_next_cf_cond(cf);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean cf_ss_control(struct ofono_modem *modem,
|
static gboolean cf_ss_control(struct ofono_modem *modem,
|
||||||
|
@ -915,7 +876,7 @@ static gboolean cf_ss_control(struct ofono_modem *modem,
|
||||||
const char *sic, const char *dn,
|
const char *sic, const char *dn,
|
||||||
DBusMessage *msg)
|
DBusMessage *msg)
|
||||||
{
|
{
|
||||||
struct call_forwarding_data *cf = modem->call_forwarding;
|
struct ofono_call_forwarding *cf = modem->call_forwarding;
|
||||||
DBusConnection *conn = ofono_dbus_get_connection();
|
DBusConnection *conn = ofono_dbus_get_connection();
|
||||||
int cls = BEARER_CLASS_SS_DEFAULT;
|
int cls = BEARER_CLASS_SS_DEFAULT;
|
||||||
int timeout = DEFAULT_NO_REPLY_TIMEOUT;
|
int timeout = DEFAULT_NO_REPLY_TIMEOUT;
|
||||||
|
@ -1010,19 +971,19 @@ static gboolean cf_ss_control(struct ofono_modem *modem,
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case SS_CONTROL_TYPE_REGISTRATION:
|
case SS_CONTROL_TYPE_REGISTRATION:
|
||||||
operation = cf->ops->registration;
|
operation = cf->driver->registration;
|
||||||
break;
|
break;
|
||||||
case SS_CONTROL_TYPE_ACTIVATION:
|
case SS_CONTROL_TYPE_ACTIVATION:
|
||||||
operation = cf->ops->activation;
|
operation = cf->driver->activation;
|
||||||
break;
|
break;
|
||||||
case SS_CONTROL_TYPE_DEACTIVATION:
|
case SS_CONTROL_TYPE_DEACTIVATION:
|
||||||
operation = cf->ops->deactivation;
|
operation = cf->driver->deactivation;
|
||||||
break;
|
break;
|
||||||
case SS_CONTROL_TYPE_ERASURE:
|
case SS_CONTROL_TYPE_ERASURE:
|
||||||
operation = cf->ops->erasure;
|
operation = cf->driver->erasure;
|
||||||
break;
|
break;
|
||||||
case SS_CONTROL_TYPE_QUERY:
|
case SS_CONTROL_TYPE_QUERY:
|
||||||
operation = cf->ops->query;
|
operation = cf->driver->query;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1075,23 +1036,23 @@ static gboolean cf_ss_control(struct ofono_modem *modem,
|
||||||
switch (cf->ss_req->ss_type) {
|
switch (cf->ss_req->ss_type) {
|
||||||
case SS_CONTROL_TYPE_REGISTRATION:
|
case SS_CONTROL_TYPE_REGISTRATION:
|
||||||
string_to_phone_number(sia, &ph);
|
string_to_phone_number(sia, &ph);
|
||||||
cf->ops->registration(modem, cf_type, cls, &ph, timeout,
|
cf->driver->registration(cf, cf_type, cls, &ph, timeout,
|
||||||
cf_ss_control_callback, modem);
|
cf_ss_control_callback, cf);
|
||||||
break;
|
break;
|
||||||
case SS_CONTROL_TYPE_ACTIVATION:
|
case SS_CONTROL_TYPE_ACTIVATION:
|
||||||
cf->ops->activation(modem, cf_type, cls, cf_ss_control_callback,
|
cf->driver->activation(cf, cf_type, cls, cf_ss_control_callback,
|
||||||
modem);
|
cf);
|
||||||
break;
|
break;
|
||||||
case SS_CONTROL_TYPE_DEACTIVATION:
|
case SS_CONTROL_TYPE_DEACTIVATION:
|
||||||
cf->ops->deactivation(modem, cf_type, cls,
|
cf->driver->deactivation(cf, cf_type, cls,
|
||||||
cf_ss_control_callback, modem);
|
cf_ss_control_callback, cf);
|
||||||
break;
|
break;
|
||||||
case SS_CONTROL_TYPE_ERASURE:
|
case SS_CONTROL_TYPE_ERASURE:
|
||||||
cf->ops->erasure(modem, cf_type, cls, cf_ss_control_callback,
|
cf->driver->erasure(cf, cf_type, cls, cf_ss_control_callback,
|
||||||
modem);
|
cf);
|
||||||
break;
|
break;
|
||||||
case SS_CONTROL_TYPE_QUERY:
|
case SS_CONTROL_TYPE_QUERY:
|
||||||
ss_set_query_next_cf_cond(modem);
|
ss_set_query_next_cf_cond(cf);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1103,79 +1064,148 @@ error:
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cf_register_ss_controls(struct ofono_modem *modem)
|
static void cf_register_ss_controls(struct ofono_call_forwarding *cf)
|
||||||
{
|
{
|
||||||
ss_control_register(modem, "21", cf_ss_control);
|
ss_control_register(cf->modem, "21", cf_ss_control);
|
||||||
ss_control_register(modem, "67", cf_ss_control);
|
ss_control_register(cf->modem, "67", cf_ss_control);
|
||||||
ss_control_register(modem, "61", cf_ss_control);
|
ss_control_register(cf->modem, "61", cf_ss_control);
|
||||||
ss_control_register(modem, "62", cf_ss_control);
|
ss_control_register(cf->modem, "62", cf_ss_control);
|
||||||
|
|
||||||
ss_control_register(modem, "002", cf_ss_control);
|
ss_control_register(cf->modem, "002", cf_ss_control);
|
||||||
ss_control_register(modem, "004", cf_ss_control);
|
ss_control_register(cf->modem, "004", cf_ss_control);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cf_unregister_ss_controls(struct ofono_modem *modem)
|
static void cf_unregister_ss_controls(struct ofono_call_forwarding *cf)
|
||||||
{
|
{
|
||||||
ss_control_unregister(modem, "21", cf_ss_control);
|
ss_control_unregister(cf->modem, "21", cf_ss_control);
|
||||||
ss_control_unregister(modem, "67", cf_ss_control);
|
ss_control_unregister(cf->modem, "67", cf_ss_control);
|
||||||
ss_control_unregister(modem, "61", cf_ss_control);
|
ss_control_unregister(cf->modem, "61", cf_ss_control);
|
||||||
ss_control_unregister(modem, "62", cf_ss_control);
|
ss_control_unregister(cf->modem, "62", cf_ss_control);
|
||||||
|
|
||||||
ss_control_unregister(modem, "002", cf_ss_control);
|
ss_control_unregister(cf->modem, "002", cf_ss_control);
|
||||||
ss_control_unregister(modem, "004", cf_ss_control);
|
ss_control_unregister(cf->modem, "004", cf_ss_control);
|
||||||
}
|
}
|
||||||
|
|
||||||
int ofono_call_forwarding_register(struct ofono_modem *modem,
|
int ofono_call_forwarding_driver_register(const struct ofono_call_forwarding_driver *d)
|
||||||
struct ofono_call_forwarding_ops *ops)
|
|
||||||
{
|
{
|
||||||
DBusConnection *conn = ofono_dbus_get_connection();
|
DBG("driver: %p, name: %s", d, d->name);
|
||||||
|
|
||||||
if (modem == NULL)
|
if (d->probe == NULL)
|
||||||
return -1;
|
return -EINVAL;
|
||||||
|
|
||||||
if (ops == NULL)
|
g_drivers = g_slist_prepend(g_drivers, (void *)d);
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (ops->query == NULL)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
modem->call_forwarding = call_forwarding_create();
|
|
||||||
|
|
||||||
if (modem->call_forwarding == NULL)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
modem->call_forwarding->ops = ops;
|
|
||||||
|
|
||||||
if (!g_dbus_register_interface(conn, modem->path,
|
|
||||||
CALL_FORWARDING_INTERFACE,
|
|
||||||
cf_methods, cf_signals, NULL,
|
|
||||||
modem, call_forwarding_destroy)) {
|
|
||||||
ofono_error("Could not register CallForwarding %s", modem->path);
|
|
||||||
call_forwarding_destroy(modem);
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
ofono_debug("Registered call forwarding interface");
|
|
||||||
|
|
||||||
cf_register_ss_controls(modem);
|
|
||||||
|
|
||||||
ofono_modem_add_interface(modem, CALL_FORWARDING_INTERFACE);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ofono_call_forwarding_unregister(struct ofono_modem *modem)
|
void ofono_call_forwarding_driver_unregister(const struct ofono_call_forwarding_driver *d)
|
||||||
{
|
{
|
||||||
struct call_forwarding_data *cf = modem->call_forwarding;
|
DBG("driver: %p, name: %s", d, d->name);
|
||||||
|
|
||||||
|
g_drivers = g_slist_remove(g_drivers, (void *)d);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void call_forwarding_unregister(struct ofono_atom *atom)
|
||||||
|
{
|
||||||
|
struct ofono_call_forwarding *cf = __ofono_atom_get_data(atom);
|
||||||
|
const char *path = ofono_modem_get_path(cf->modem);
|
||||||
DBusConnection *conn = ofono_dbus_get_connection();
|
DBusConnection *conn = ofono_dbus_get_connection();
|
||||||
|
|
||||||
if (!cf)
|
ofono_modem_remove_interface(cf->modem, CALL_FORWARDING_INTERFACE);
|
||||||
|
g_dbus_unregister_interface(conn, path, CALL_FORWARDING_INTERFACE);
|
||||||
|
|
||||||
|
cf_unregister_ss_controls(cf);
|
||||||
|
|
||||||
|
cf->modem->call_forwarding = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void call_forwarding_remove(struct ofono_atom *atom)
|
||||||
|
{
|
||||||
|
struct ofono_call_forwarding *cf = __ofono_atom_get_data(atom);
|
||||||
|
|
||||||
|
DBG("atom: %p", atom);
|
||||||
|
|
||||||
|
if (cf == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ofono_modem_remove_interface(modem, CALL_FORWARDING_INTERFACE);
|
if (cf->driver && cf->driver->remove)
|
||||||
g_dbus_unregister_interface(conn, modem->path,
|
cf->driver->remove(cf);
|
||||||
|
|
||||||
|
cf_clear_all(cf);
|
||||||
|
|
||||||
|
g_free(cf);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ofono_call_forwarding *ofono_call_forwarding_create(struct ofono_modem *modem,
|
||||||
|
const char *driver,
|
||||||
|
void *data)
|
||||||
|
{
|
||||||
|
struct ofono_call_forwarding *cf;
|
||||||
|
GSList *l;
|
||||||
|
|
||||||
|
if (driver == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
cf = g_try_new0(struct ofono_call_forwarding, 1);
|
||||||
|
|
||||||
|
if (cf == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
cf->modem = modem;
|
||||||
|
cf->driver_data = data;
|
||||||
|
cf->atom = __ofono_modem_add_atom(modem,
|
||||||
|
OFONO_ATOM_TYPE_CALL_FORWARDING,
|
||||||
|
call_forwarding_remove, cf);
|
||||||
|
for (l = g_drivers; l; l = l->next) {
|
||||||
|
const struct ofono_call_forwarding_driver *drv = l->data;
|
||||||
|
|
||||||
|
if (g_strcmp0(drv->name, driver))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (drv->probe(cf) < 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
cf->driver = drv;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return cf;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ofono_call_forwarding_register(struct ofono_call_forwarding *cf)
|
||||||
|
{
|
||||||
|
DBusConnection *conn = ofono_dbus_get_connection();
|
||||||
|
const char *path = ofono_modem_get_path(cf->modem);
|
||||||
|
|
||||||
|
if (!g_dbus_register_interface(conn, path,
|
||||||
|
CALL_FORWARDING_INTERFACE,
|
||||||
|
cf_methods, cf_signals, NULL, cf,
|
||||||
|
NULL)) {
|
||||||
|
ofono_error("Could not create %s interface",
|
||||||
CALL_FORWARDING_INTERFACE);
|
CALL_FORWARDING_INTERFACE);
|
||||||
|
|
||||||
modem->call_forwarding = NULL;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
cf->modem->call_forwarding = cf;
|
||||||
|
|
||||||
|
ofono_modem_add_interface(cf->modem, CALL_FORWARDING_INTERFACE);
|
||||||
|
cf_register_ss_controls(cf);
|
||||||
|
|
||||||
|
__ofono_atom_register(cf->atom, call_forwarding_unregister);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ofono_call_forwarding_remove(struct ofono_call_forwarding *cf)
|
||||||
|
{
|
||||||
|
__ofono_modem_remove_atom(cf->modem, cf->atom);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ofono_call_forwarding_set_data(struct ofono_call_forwarding *cf, void *data)
|
||||||
|
{
|
||||||
|
cf->driver_data = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *ofono_call_forwarding_get_data(struct ofono_call_forwarding *cf)
|
||||||
|
{
|
||||||
|
return cf->driver_data;
|
||||||
}
|
}
|
||||||
|
|
31
src/driver.h
31
src/driver.h
|
@ -69,14 +69,6 @@ struct ofono_network_operator {
|
||||||
int tech;
|
int tech;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* 27.007 Section 7.11 Call Forwarding */
|
|
||||||
struct ofono_cf_condition {
|
|
||||||
int status;
|
|
||||||
int cls;
|
|
||||||
struct ofono_phone_number phone_number;
|
|
||||||
int time;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* 51.011 Section 9.3 */
|
/* 51.011 Section 9.3 */
|
||||||
enum ofono_sim_file_structure {
|
enum ofono_sim_file_structure {
|
||||||
OFONO_SIM_FILE_STRUCTURE_TRANSPARENT = 0,
|
OFONO_SIM_FILE_STRUCTURE_TRANSPARENT = 0,
|
||||||
|
@ -115,11 +107,6 @@ typedef void (*ofono_registration_status_cb_t)(const struct ofono_error *error,
|
||||||
typedef void (*ofono_signal_strength_cb_t)(const struct ofono_error *error,
|
typedef void (*ofono_signal_strength_cb_t)(const struct ofono_error *error,
|
||||||
int strength, void *data);
|
int strength, void *data);
|
||||||
|
|
||||||
typedef void (*ofono_call_forwarding_query_cb_t)(const struct ofono_error *error,
|
|
||||||
int total,
|
|
||||||
const struct ofono_cf_condition *list,
|
|
||||||
void *data);
|
|
||||||
|
|
||||||
typedef void (*ofono_modem_attribute_query_cb_t)(const struct ofono_error *error,
|
typedef void (*ofono_modem_attribute_query_cb_t)(const struct ofono_error *error,
|
||||||
const char *attribute, void *data);
|
const char *attribute, void *data);
|
||||||
|
|
||||||
|
@ -259,24 +246,6 @@ void ofono_cssi_notify(struct ofono_modem *modem, int code, int index);
|
||||||
void ofono_cssu_notify(struct ofono_modem *modem, int code, int index,
|
void ofono_cssu_notify(struct ofono_modem *modem, int code, int index,
|
||||||
const struct ofono_phone_number *number);
|
const struct ofono_phone_number *number);
|
||||||
|
|
||||||
struct ofono_call_forwarding_ops {
|
|
||||||
void (*activation)(struct ofono_modem *modem, int type, int cls,
|
|
||||||
ofono_generic_cb_t cb, void *data);
|
|
||||||
void (*registration)(struct ofono_modem *modem, int type, int cls,
|
|
||||||
const struct ofono_phone_number *number,
|
|
||||||
int time, ofono_generic_cb_t cb, void *data);
|
|
||||||
void (*deactivation)(struct ofono_modem *modem, int type, int cls,
|
|
||||||
ofono_generic_cb_t cb, void *data);
|
|
||||||
void (*erasure)(struct ofono_modem *modem, int type, int cls,
|
|
||||||
ofono_generic_cb_t cb, void *data);
|
|
||||||
void (*query)(struct ofono_modem *modem, int type, int cls,
|
|
||||||
ofono_call_forwarding_query_cb_t cb, void *data);
|
|
||||||
};
|
|
||||||
|
|
||||||
int ofono_call_forwarding_register(struct ofono_modem *modem,
|
|
||||||
struct ofono_call_forwarding_ops *ops);
|
|
||||||
void ofono_call_forwarding_unregister(struct ofono_modem *modem);
|
|
||||||
|
|
||||||
struct ofono_ussd_ops {
|
struct ofono_ussd_ops {
|
||||||
void (*request)(struct ofono_modem *modem, const char *str,
|
void (*request)(struct ofono_modem *modem, const char *str,
|
||||||
ofono_generic_cb_t cb, void *data);
|
ofono_generic_cb_t cb, void *data);
|
||||||
|
|
|
@ -73,7 +73,7 @@ struct ofono_modem {
|
||||||
struct ofono_modem_data *modem_info;
|
struct ofono_modem_data *modem_info;
|
||||||
struct network_registration_data *network_registration;
|
struct network_registration_data *network_registration;
|
||||||
struct voicecalls_data *voicecalls;
|
struct voicecalls_data *voicecalls;
|
||||||
struct call_forwarding_data *call_forwarding;
|
struct ofono_call_forwarding *call_forwarding;
|
||||||
struct ussd_data *ussd;
|
struct ussd_data *ussd;
|
||||||
struct call_settings_data *call_settings;
|
struct call_settings_data *call_settings;
|
||||||
struct call_waiting_data *call_waiting;
|
struct call_waiting_data *call_waiting;
|
||||||
|
@ -128,6 +128,7 @@ void __ofono_modem_remove_atom(struct ofono_modem *modem,
|
||||||
struct ofono_atom *atom);
|
struct ofono_atom *atom);
|
||||||
|
|
||||||
#include <ofono/call-barring.h>
|
#include <ofono/call-barring.h>
|
||||||
|
#include <ofono/call-forwarding.h>
|
||||||
|
|
||||||
#include <ofono/history.h>
|
#include <ofono/history.h>
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue