Evolve the USSD API

This commit is contained in:
Denis Kenzior 2009-08-17 13:45:55 -05:00
parent 5fdc6fd395
commit 229bb3a4ed
5 changed files with 186 additions and 77 deletions

View File

@ -4,7 +4,7 @@ includedir = @includedir@/ofono
include_HEADERS = log.h plugin.h history.h dbus.h modem.h \
types.h call-barring.h call-forwarding.h \
call-meter.h call-settings.h phonebook.h \
ssn.h
ssn.h ussd.h
nodist_include_HEADERS = version.h

63
include/ussd.h Normal file
View File

@ -0,0 +1,63 @@
/*
*
* oFono - Open Source Telephony
*
* 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_USSD_H
#define __OFONO_USSD_H
#ifdef __cplusplus
extern "C" {
#endif
#include <ofono/types.h>
struct ofono_ussd;
typedef void (*ofono_ussd_cb_t)(const struct ofono_error *error, void *data);
struct ofono_ussd_driver {
const char *name;
int (*probe)(struct ofono_ussd *ussd);
int (*remove)(struct ofono_ussd *ussd);
void (*request)(struct ofono_ussd *ussd, const char *str,
ofono_ussd_cb_t, void *data);
void (*cancel)(struct ofono_ussd *ussd,
ofono_ussd_cb_t cb, void *data);
};
void ofono_ussd_notify(struct ofono_ussd *ussd, int status, const char *str);
int ofono_ussd_driver_register(const struct ofono_ussd_driver *d);
void ofono_ussd_driver_unregister(const struct ofono_ussd_driver *d);
struct ofono_ussd *ofono_ussd_create(struct ofono_modem *modem,
const char *driver, void *data);
void ofono_ussd_register(struct ofono_ussd *ussd);
void ofono_ussd_remove(struct ofono_ussd *ussd);
void ofono_ussd_set_data(struct ofono_ussd *ussd, void *data);
void *ofono_ussd_get_data(struct ofono_ussd *ussd);
#ifdef __cplusplus
}
#endif
#endif /* __OFONO_USSD_H */

View File

@ -212,17 +212,6 @@ void ofono_voicecall_disconnected(struct ofono_modem *modem, int id,
int ofono_voicecall_register(struct ofono_modem *modem, struct ofono_voicecall_ops *ops);
void ofono_voicecall_unregister(struct ofono_modem *modem);
struct ofono_ussd_ops {
void (*request)(struct ofono_modem *modem, const char *str,
ofono_generic_cb_t cb, void *data);
void (*cancel)(struct ofono_modem *modem,
ofono_generic_cb_t cb, void *data);
};
void ofono_ussd_notify(struct ofono_modem *modem, int status, const char *str);
int ofono_ussd_register(struct ofono_modem *modem, struct ofono_ussd_ops *ops);
void ofono_ussd_unregister(struct ofono_modem *modem);
struct ofono_sim_ops {
void (*read_file_info)(struct ofono_modem *modem, int fileid,
ofono_sim_file_info_cb_t cb, void *data);

View File

@ -78,7 +78,6 @@ struct ofono_modem {
struct network_registration_data *network_registration;
struct voicecalls_data *voicecalls;
struct ofono_call_forwarding *call_forwarding;
struct ussd_data *ussd;
struct ofono_call_settings *call_settings;
struct ofono_call_barring *call_barring;
struct cssn_data *cssn;
@ -170,6 +169,8 @@ unsigned int __ofono_ssn_mt_watch_add(struct ofono_ssn *ssn, int code2,
ofono_destroy_func destroy);
gboolean __ofono_ssn_mt_watch_remove(struct ofono_ssn *ssn, int id);
#include <ofono/ussd.h>
#include <ofono/history.h>
void __ofono_history_probe_drivers(struct ofono_modem *modem);

View File

@ -26,13 +26,13 @@
#define _GNU_SOURCE
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <glib.h>
#include <gdbus.h>
#include "ofono.h"
#include "driver.h"
#include "common.h"
#include "ussd.h"
@ -40,36 +40,23 @@
#define USSD_FLAG_PENDING 0x1
static GSList *g_drivers = NULL;
enum ussd_state {
USSD_STATE_IDLE = 0,
USSD_STATE_ACTIVE = 1,
USSD_STATE_USER_ACTION = 2
};
struct ussd_data {
struct ofono_ussd_ops *ops;
struct ofono_ussd {
int state;
DBusMessage *pending;
int flags;
const struct ofono_ussd_driver *driver;
void *driver_data;
struct ofono_atom *atom;
};
static struct ussd_data *ussd_create()
{
struct ussd_data *r;
r = g_try_new0(struct ussd_data, 1);
return r;
}
static void ussd_destroy(gpointer data)
{
struct ofono_modem *modem = data;
struct ussd_data *ussd = modem->ussd;
g_free(ussd);
}
struct ss_control_entry {
char *service;
ss_control_cb_t cb;
@ -355,9 +342,8 @@ out:
return ret;
}
void ofono_ussd_notify(struct ofono_modem *modem, int status, const char *str)
void ofono_ussd_notify(struct ofono_ussd *ussd, int status, const char *str)
{
struct ussd_data *ussd = modem->ussd;
DBusConnection *conn = ofono_dbus_get_connection();
const char *ussdstr = "USSD";
const char sig[] = { DBUS_TYPE_STRING, 0 };
@ -416,7 +402,7 @@ out:
static void ussd_callback(const struct ofono_error *error, void *data)
{
struct ussd_data *ussd = data;
struct ofono_ussd *ussd = data;
DBusConnection *conn = ofono_dbus_get_connection();
DBusMessage *reply;
@ -445,8 +431,8 @@ static void ussd_callback(const struct ofono_error *error, void *data)
static DBusMessage *ussd_initiate(DBusConnection *conn, DBusMessage *msg,
void *data)
{
struct ofono_modem *modem = data;
struct ussd_data *ussd = modem->ussd;
struct ofono_ussd *ussd = data;
struct ofono_modem *modem = __ofono_atom_get_modem(ussd->atom);
const char *str;
if (ussd->flags & USSD_FLAG_PENDING)
@ -472,20 +458,20 @@ static DBusMessage *ussd_initiate(DBusConnection *conn, DBusMessage *msg,
ofono_debug("OK, running USSD request");
if (!ussd->ops->request)
if (!ussd->driver->request)
return __ofono_error_not_implemented(msg);
ussd->flags |= USSD_FLAG_PENDING;
ussd->pending = dbus_message_ref(msg);
ussd->ops->request(modem, str, ussd_callback, ussd);
ussd->driver->request(ussd, str, ussd_callback, ussd);
return NULL;
}
static void ussd_cancel_callback(const struct ofono_error *error, void *data)
{
struct ussd_data *ussd = data;
struct ofono_ussd *ussd = data;
DBusMessage *reply;
if (error->type != OFONO_ERROR_TYPE_NO_ERROR)
@ -510,8 +496,7 @@ static void ussd_cancel_callback(const struct ofono_error *error, void *data)
static DBusMessage *ussd_cancel(DBusConnection *conn, DBusMessage *msg,
void *data)
{
struct ofono_modem *modem = data;
struct ussd_data *ussd = modem->ussd;
struct ofono_ussd *ussd = data;
if (ussd->flags & USSD_FLAG_PENDING)
return __ofono_error_busy(msg);
@ -519,13 +504,13 @@ static DBusMessage *ussd_cancel(DBusConnection *conn, DBusMessage *msg,
if (ussd->state == USSD_STATE_IDLE)
return __ofono_error_not_active(msg);
if (!ussd->ops->cancel)
if (!ussd->driver->cancel)
return __ofono_error_not_implemented(msg);
ussd->flags |= USSD_FLAG_PENDING;
ussd->pending = dbus_message_ref(msg);
ussd->ops->cancel(modem, ussd_cancel_callback, ussd);
ussd->driver->cancel(ussd, ussd_cancel_callback, ussd);
return NULL;
}
@ -542,48 +527,119 @@ static GDBusSignalTable ussd_signals[] = {
{ }
};
int ofono_ussd_register(struct ofono_modem *modem, struct ofono_ussd_ops *ops)
int ofono_ussd_driver_register(const struct ofono_ussd_driver *d)
{
DBusConnection *conn = ofono_dbus_get_connection();
DBG("driver: %p, name: %s", d, d->name);
if (modem == NULL)
return -1;
if (d->probe == NULL)
return -EINVAL;
if (ops == NULL)
return -1;
modem->ussd = ussd_create();
if (modem->ussd == NULL)
return -1;
modem->ussd->ops = ops;
if (!g_dbus_register_interface(conn, modem->path,
SUPPLEMENTARY_SERVICES_INTERFACE,
ussd_methods, ussd_signals, NULL,
modem, ussd_destroy)) {
ofono_error("Could not create %s interface",
SUPPLEMENTARY_SERVICES_INTERFACE);
ussd_destroy(modem->ussd);
return -1;
}
ofono_modem_add_interface(modem, SUPPLEMENTARY_SERVICES_INTERFACE);
g_drivers = g_slist_prepend(g_drivers, (void *)d);
return 0;
}
void ofono_ussd_unregister(struct ofono_modem *modem)
void ofono_ussd_driver_unregister(const struct ofono_ussd_driver *d)
{
DBusConnection *conn = ofono_dbus_get_connection();
DBG("driver: %p, name: %s", d, d->name);
if (modem->ussd == NULL)
return;
g_drivers = g_slist_remove(g_drivers, (void *)d);
}
static void ussd_unregister(struct ofono_atom *atom)
{
struct ofono_ussd *ussd = __ofono_atom_get_data(atom);
DBusConnection *conn = ofono_dbus_get_connection();
struct ofono_modem *modem = __ofono_atom_get_modem(atom);
const char *path = __ofono_atom_get_path(atom);
ofono_modem_remove_interface(modem, SUPPLEMENTARY_SERVICES_INTERFACE);
g_dbus_unregister_interface(conn, modem->path,
g_dbus_unregister_interface(conn, path,
SUPPLEMENTARY_SERVICES_INTERFACE);
}
static void ussd_remove(struct ofono_atom *atom)
{
struct ofono_ussd *ussd = __ofono_atom_get_data(atom);
DBG("atom: %p", atom);
if (ussd == NULL)
return;
if (ussd->driver && ussd->driver->remove)
ussd->driver->remove(ussd);
g_free(ussd);
}
struct ofono_ussd *ofono_ussd_create(struct ofono_modem *modem,
const char *driver,
void *data)
{
struct ofono_ussd *ussd;
GSList *l;
if (driver == NULL)
return NULL;
ussd = g_try_new0(struct ofono_ussd, 1);
if (ussd == NULL)
return NULL;
ussd->driver_data = data;
ussd->atom = __ofono_modem_add_atom(modem, OFONO_ATOM_TYPE_USSD,
ussd_remove, ussd);
for (l = g_drivers; l; l = l->next) {
const struct ofono_ussd_driver *drv = l->data;
if (g_strcmp0(drv->name, driver))
continue;
if (drv->probe(ussd) < 0)
continue;
ussd->driver = drv;
break;
}
return ussd;
}
void ofono_ussd_register(struct ofono_ussd *ussd)
{
DBusConnection *conn = ofono_dbus_get_connection();
struct ofono_modem *modem = __ofono_atom_get_modem(ussd->atom);
const char *path = __ofono_atom_get_path(ussd->atom);
if (!g_dbus_register_interface(conn, path,
SUPPLEMENTARY_SERVICES_INTERFACE,
ussd_methods, ussd_signals, NULL,
ussd, NULL)) {
ofono_error("Could not create %s interface",
OFONO_CALL_BARRING_INTERFACE);
return;
}
ofono_modem_add_interface(modem, SUPPLEMENTARY_SERVICES_INTERFACE);
__ofono_atom_register(ussd->atom, ussd_unregister);
}
void ofono_ussd_remove(struct ofono_ussd *ussd)
{
__ofono_atom_free(ussd->atom);
}
void ofono_ussd_set_data(struct ofono_ussd *ussd, void *data)
{
ussd->driver_data = data;
}
void *ofono_ussd_get_data(struct ofono_ussd *ussd)
{
return ussd->driver_data;
}