Refactor various watch functions

Use a common core kernel for all the watcher registrations /
notifications.  This is now done in watch.c
This commit is contained in:
Denis Kenzior 2009-09-10 23:01:59 -05:00
parent 27cfc00eba
commit 32fc30fa02
5 changed files with 188 additions and 166 deletions

View File

@ -161,7 +161,7 @@ src_ofonod_SOURCES = $(gdbus_sources) $(builtin_sources) \
src/ssn.c src/call-barring.c src/sim.c \
src/phonebook.c src/history.c src/message-waiting.c \
src/simutil.h src/simutil.c src/storage.h \
src/storage.c src/cbs.c
src/storage.c src/cbs.c src/watch.c
src_ofonod_LDADD = $(builtin_libadd) \
@GLIB_LIBS@ @GTHREAD_LIBS@ @DBUS_LIBS@ -ldl

View File

@ -48,22 +48,21 @@ enum ofono_property_type {
};
struct ofono_modem {
char *path;
GSList *atoms;
GSList *atom_watches;
int next_atom_watch_id;
GSList *interface_list;
unsigned int call_ids;
DBusMessage *pending;
guint interface_update;
ofono_bool_t powered;
ofono_bool_t powered_pending;
ofono_bool_t powered_persistent;
guint timeout;
GHashTable *properties;
char *path;
GSList *atoms;
struct ofono_watchlist *atom_watches;
GSList *interface_list;
unsigned int call_ids;
DBusMessage *pending;
guint interface_update;
ofono_bool_t powered;
ofono_bool_t powered_pending;
ofono_bool_t powered_persistent;
guint timeout;
GHashTable *properties;
const struct ofono_modem_driver *driver;
void *driver_data;
char *driver_type;
void *driver_data;
char *driver_type;
};
struct ofono_devinfo {
@ -85,11 +84,8 @@ struct ofono_atom {
};
struct ofono_atom_watch {
struct ofono_watchlist_item item;
enum ofono_atom_type type;
int id;
ofono_atom_watch_func notify;
ofono_destroy_func destroy;
void *notify_data;
};
struct ofono_property {
@ -182,16 +178,19 @@ static void call_watches(struct ofono_atom *atom,
enum ofono_atom_watch_condition cond)
{
struct ofono_modem *modem = atom->modem;
GSList *atom_watches = modem->atom_watches->items;
GSList *l;
struct ofono_atom_watch *watch;
ofono_atom_watch_func notify;
for (l = modem->atom_watches; l; l = l->next) {
for (l = atom_watches; l; l = l->next) {
watch = l->data;
if (watch->type != atom->type)
continue;
watch->notify(atom, cond, watch->notify_data);
notify = watch->item.notify;
notify(atom, cond, watch->item.notify_data);
}
}
@ -221,7 +220,7 @@ gboolean __ofono_atom_get_registered(struct ofono_atom *atom)
return atom->unregister ? TRUE : FALSE;
}
int __ofono_modem_add_atom_watch(struct ofono_modem *modem,
unsigned int __ofono_modem_add_atom_watch(struct ofono_modem *modem,
enum ofono_atom_type type,
ofono_atom_watch_func notify,
void *data, ofono_destroy_func destroy)
@ -234,67 +233,18 @@ int __ofono_modem_add_atom_watch(struct ofono_modem *modem,
watch = g_new0(struct ofono_atom_watch, 1);
watch->type = type;
watch->id = ++modem->next_atom_watch_id;
watch->notify = notify;
watch->destroy = destroy;
watch->notify_data = data;
watch->item.notify = notify;
watch->item.destroy = destroy;
watch->item.notify_data = data;
modem->atom_watches = g_slist_prepend(modem->atom_watches, watch);
return watch->id;
return __ofono_watchlist_add_item(modem->atom_watches,
(struct ofono_watchlist_item *)watch);
}
gboolean __ofono_modem_remove_atom_watch(struct ofono_modem *modem, int id)
gboolean __ofono_modem_remove_atom_watch(struct ofono_modem *modem,
unsigned int id)
{
struct ofono_atom_watch *watch;
GSList *p;
GSList *c;
p = NULL;
c = modem->atom_watches;
while (c) {
watch = c->data;
if (watch->id != id) {
p = c;
c = c->next;
continue;
}
if (p)
p->next = c->next;
else
modem->atom_watches = c->next;
if (watch->destroy)
watch->destroy(watch->notify_data);
g_free(watch);
g_slist_free_1(c);
return TRUE;
}
return FALSE;
}
static void remove_all_watches(struct ofono_modem *modem)
{
struct ofono_atom_watch *watch;
GSList *l;
for (l = modem->atom_watches; l; l = l->next) {
watch = l->data;
if (watch->destroy)
watch->destroy(watch->notify_data);
g_free(watch);
}
g_slist_free(modem->atom_watches);
modem->atom_watches = NULL;
return __ofono_watchlist_remove_item(modem->atom_watches, id);
}
struct ofono_atom *__ofono_modem_find_atom(struct ofono_modem *modem,
@ -1076,6 +1026,7 @@ struct ofono_modem *ofono_modem_create(const char *type)
modem->driver_type = g_strdup(type);
modem->properties = g_hash_table_new_full(g_str_hash, g_str_equal,
g_free, unregister_property);
modem->atom_watches = __ofono_watchlist_new(g_free);
g_modem_list = g_slist_prepend(g_modem_list, modem);
@ -1165,7 +1116,9 @@ static void modem_unregister(struct ofono_modem *modem)
return;
remove_all_atoms(modem);
remove_all_watches(modem);
__ofono_watchlist_free(modem->atom_watches);
modem->atom_watches = NULL;
g_slist_foreach(modem->interface_list, (GFunc)g_free, NULL);
g_slist_free(modem->interface_list);

View File

@ -57,6 +57,26 @@ gboolean __ofono_dbus_valid_object_path(const char *path);
#include <ofono/types.h>
struct ofono_watchlist_item {
unsigned int id;
void *notify;
void *notify_data;
ofono_destroy_func destroy;
};
struct ofono_watchlist {
int next_id;
GSList *items;
ofono_destroy_func destroy;
};
struct ofono_watchlist *__ofono_watchlist_new(ofono_destroy_func destroy);
unsigned int __ofono_watchlist_add_item(struct ofono_watchlist *watchlist,
struct ofono_watchlist_item *item);
gboolean __ofono_watchlist_remove_item(struct ofono_watchlist *watchlist,
unsigned int id);
void __ofono_watchlist_free(struct ofono_watchlist *watchlist);
#include <ofono/plugin.h>
int __ofono_plugin_init(const char *pattern, const char *exclude);
@ -120,11 +140,12 @@ void __ofono_atom_unregister(struct ofono_atom *atom);
gboolean __ofono_atom_get_registered(struct ofono_atom *atom);
int __ofono_modem_add_atom_watch(struct ofono_modem *modem,
unsigned int __ofono_modem_add_atom_watch(struct ofono_modem *modem,
enum ofono_atom_type type,
ofono_atom_watch_func notify,
void *data, ofono_destroy_func destroy);
gboolean __ofono_modem_remove_atom_watch(struct ofono_modem *modem, int id);
gboolean __ofono_modem_remove_atom_watch(struct ofono_modem *modem,
unsigned int id);
void __ofono_atom_free(struct ofono_atom *atom);

110
src/ssn.c
View File

@ -36,23 +36,19 @@
static GSList *g_drivers = NULL;
struct ssn_handler {
unsigned int id;
struct ofono_watchlist_item item;
int code;
void *notify;
void *data;
ofono_destroy_func destroy;
};
struct ofono_ssn {
GSList *mo_handler_list;
GSList *mt_handler_list;
unsigned int next_id;
struct ofono_watchlist *mo_handler_list;
struct ofono_watchlist *mt_handler_list;
const struct ofono_ssn_driver *driver;
void *driver_data;
struct ofono_atom *atom;
};
static unsigned int add_ssn_handler(GSList **l, unsigned int *id,
static unsigned int add_ssn_handler(struct ofono_watchlist *watchlist,
int code, void *notify, void *data,
ofono_destroy_func destroy)
{
@ -64,68 +60,12 @@ static unsigned int add_ssn_handler(GSList **l, unsigned int *id,
handler = g_new0(struct ssn_handler, 1);
handler->code = code;
handler->id = *id;
*id = *id + 1;
handler->notify = notify;
handler->destroy = destroy;
handler->data = data;
handler->item.notify = notify;
handler->item.notify_data = data;
handler->item.destroy = destroy;
*l = g_slist_prepend(*l, handler);
return handler->id;
}
static gboolean remove_ssn_handler_by_id(GSList **l, unsigned int id)
{
struct ssn_handler *handler;
GSList *p;
GSList *c;
p = NULL;
c = *l;
while (c) {
handler = c->data;
if (handler->id != id) {
p = c;
c = c->next;
continue;
}
if (p)
p->next = c->next;
else
*l = c->next;
if (handler->destroy)
handler->destroy(handler->data);
g_free(handler);
g_slist_free_1(c);
return TRUE;
}
return FALSE;
}
static void remove_all_handlers(GSList **l)
{
struct ssn_handler *handler;
GSList *c;
for (c = *l; c; c = c->next) {
handler = c->data;
if (handler->destroy)
handler->destroy(handler->data);
g_free(handler);
}
g_slist_free(*l);
*l = NULL;
return __ofono_watchlist_add_item(watchlist,
(struct ofono_watchlist_item *)handler);
}
unsigned int __ofono_ssn_mo_watch_add(struct ofono_ssn *ssn, int code1,
@ -137,8 +77,7 @@ unsigned int __ofono_ssn_mo_watch_add(struct ofono_ssn *ssn, int code1,
DBG("%p, %d", ssn, code1);
return add_ssn_handler(&ssn->mo_handler_list, &ssn->next_id,
code1, cb, user, destroy);
return add_ssn_handler(ssn->mo_handler_list, code1, cb, user, destroy);
}
gboolean __ofono_ssn_mo_watch_remove(struct ofono_ssn *ssn, int id)
@ -148,7 +87,7 @@ gboolean __ofono_ssn_mo_watch_remove(struct ofono_ssn *ssn, int id)
DBG("%p, %u", ssn, id);
return remove_ssn_handler_by_id(&ssn->mo_handler_list, id);
return __ofono_watchlist_remove_item(ssn->mo_handler_list, id);
}
unsigned int __ofono_ssn_mt_watch_add(struct ofono_ssn *ssn, int code2,
@ -160,8 +99,7 @@ unsigned int __ofono_ssn_mt_watch_add(struct ofono_ssn *ssn, int code2,
DBG("%p, %d", ssn, code2);
return add_ssn_handler(&ssn->mt_handler_list, &ssn->next_id,
code2, cb, user, destroy);
return add_ssn_handler(ssn->mt_handler_list, code2, cb, user, destroy);
}
gboolean __ofono_ssn_mt_watch_remove(struct ofono_ssn *ssn, int id)
@ -171,7 +109,7 @@ gboolean __ofono_ssn_mt_watch_remove(struct ofono_ssn *ssn, int id)
DBG("%p, %u", ssn, id);
return remove_ssn_handler_by_id(&ssn->mt_handler_list, id);
return __ofono_watchlist_remove_item(ssn->mt_handler_list, id);
}
void ofono_ssn_cssi_notify(struct ofono_ssn *ssn, int code1, int index)
@ -180,12 +118,12 @@ void ofono_ssn_cssi_notify(struct ofono_ssn *ssn, int code1, int index)
GSList *l;
ofono_ssn_mo_notify_cb notify;
for (l = ssn->mo_handler_list; l; l = l->next) {
for (l = ssn->mo_handler_list->items; l; l = l->next) {
h = l->data;
notify = h->notify;
notify = h->item.notify;
if (h->code == code1)
notify(index, h->data);
notify(index, h->item.notify_data);
}
}
@ -196,12 +134,12 @@ void ofono_ssn_cssu_notify(struct ofono_ssn *ssn, int code2, int index,
GSList *l;
ofono_ssn_mt_notify_cb notify;
for (l = ssn->mt_handler_list; l; l = l->next) {
for (l = ssn->mt_handler_list->items; l; l = l->next) {
h = l->data;
notify = h->notify;
notify = h->item.notify;
if (h->code == code2)
notify(index, ph, h->data);
notify(index, ph, h->item.notify_data);
}
}
@ -228,8 +166,11 @@ static void ssn_unregister(struct ofono_atom *atom)
{
struct ofono_ssn *ssn = __ofono_atom_get_data(atom);
remove_all_handlers(&ssn->mo_handler_list);
remove_all_handlers(&ssn->mt_handler_list);
__ofono_watchlist_free(ssn->mo_handler_list);
ssn->mo_handler_list = NULL;
__ofono_watchlist_free(ssn->mt_handler_list);
ssn->mt_handler_list = NULL;
}
static void ssn_remove(struct ofono_atom *atom)
@ -263,6 +204,9 @@ struct ofono_ssn *ofono_ssn_create(struct ofono_modem *modem,
if (ssn == NULL)
return NULL;
ssn->mo_handler_list = __ofono_watchlist_new(g_free);
ssn->mt_handler_list = __ofono_watchlist_new(g_free);
ssn->atom = __ofono_modem_add_atom(modem, OFONO_ATOM_TYPE_SSN,
ssn_remove, ssn);

104
src/watch.c Normal file
View File

@ -0,0 +1,104 @@
/*
*
* 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
*
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <glib.h>
#include "ofono.h"
struct ofono_watchlist *__ofono_watchlist_new(ofono_destroy_func destroy)
{
struct ofono_watchlist *watchlist;
watchlist = g_new0(struct ofono_watchlist, 1);
watchlist->destroy = destroy;
return watchlist;
}
unsigned int __ofono_watchlist_add_item(struct ofono_watchlist *watchlist,
struct ofono_watchlist_item *item)
{
item->id = ++watchlist->next_id;
watchlist->items = g_slist_prepend(watchlist->items, item);
return item->id;
}
gboolean __ofono_watchlist_remove_item(struct ofono_watchlist *watchlist,
unsigned int id)
{
struct ofono_watchlist_item *item;
GSList *p;
GSList *c;
p = NULL;
c = watchlist->items;
while (c) {
item = c->data;
if (item->id != id) {
p = c;
c = c->next;
continue;
}
if (p)
p->next = c->next;
else
watchlist->items = c->next;
if (item->destroy)
item->destroy(item->notify_data);
if (watchlist->destroy)
watchlist->destroy(item);
g_slist_free_1(c);
return TRUE;
}
return FALSE;
}
void __ofono_watchlist_free(struct ofono_watchlist *watchlist)
{
struct ofono_watchlist_item *item;
GSList *l;
for (l = watchlist->items; l; l = l->next) {
item = l->data;
if (item->destroy)
item->destroy(item->notify_data);
if (watchlist->destroy)
watchlist->destroy(item);
}
g_slist_free(watchlist->items);
watchlist->items = NULL;
g_free(watchlist);
}