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/ssn.c src/call-barring.c src/sim.c \
src/phonebook.c src/history.c src/message-waiting.c \ src/phonebook.c src/history.c src/message-waiting.c \
src/simutil.h src/simutil.c src/storage.h \ 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) \ src_ofonod_LDADD = $(builtin_libadd) \
@GLIB_LIBS@ @GTHREAD_LIBS@ @DBUS_LIBS@ -ldl @GLIB_LIBS@ @GTHREAD_LIBS@ @DBUS_LIBS@ -ldl

View File

@ -48,22 +48,21 @@ enum ofono_property_type {
}; };
struct ofono_modem { struct ofono_modem {
char *path; char *path;
GSList *atoms; GSList *atoms;
GSList *atom_watches; struct ofono_watchlist *atom_watches;
int next_atom_watch_id; GSList *interface_list;
GSList *interface_list; unsigned int call_ids;
unsigned int call_ids; DBusMessage *pending;
DBusMessage *pending; guint interface_update;
guint interface_update; ofono_bool_t powered;
ofono_bool_t powered; ofono_bool_t powered_pending;
ofono_bool_t powered_pending; ofono_bool_t powered_persistent;
ofono_bool_t powered_persistent; guint timeout;
guint timeout; GHashTable *properties;
GHashTable *properties;
const struct ofono_modem_driver *driver; const struct ofono_modem_driver *driver;
void *driver_data; void *driver_data;
char *driver_type; char *driver_type;
}; };
struct ofono_devinfo { struct ofono_devinfo {
@ -85,11 +84,8 @@ struct ofono_atom {
}; };
struct ofono_atom_watch { struct ofono_atom_watch {
struct ofono_watchlist_item item;
enum ofono_atom_type type; enum ofono_atom_type type;
int id;
ofono_atom_watch_func notify;
ofono_destroy_func destroy;
void *notify_data;
}; };
struct ofono_property { struct ofono_property {
@ -182,16 +178,19 @@ static void call_watches(struct ofono_atom *atom,
enum ofono_atom_watch_condition cond) enum ofono_atom_watch_condition cond)
{ {
struct ofono_modem *modem = atom->modem; struct ofono_modem *modem = atom->modem;
GSList *atom_watches = modem->atom_watches->items;
GSList *l; GSList *l;
struct ofono_atom_watch *watch; 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; watch = l->data;
if (watch->type != atom->type) if (watch->type != atom->type)
continue; 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; 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, enum ofono_atom_type type,
ofono_atom_watch_func notify, ofono_atom_watch_func notify,
void *data, ofono_destroy_func destroy) 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 = g_new0(struct ofono_atom_watch, 1);
watch->type = type; watch->type = type;
watch->id = ++modem->next_atom_watch_id; watch->item.notify = notify;
watch->notify = notify; watch->item.destroy = destroy;
watch->destroy = destroy; watch->item.notify_data = data;
watch->notify_data = data;
modem->atom_watches = g_slist_prepend(modem->atom_watches, watch); return __ofono_watchlist_add_item(modem->atom_watches,
(struct ofono_watchlist_item *)watch);
return watch->id;
} }
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; return __ofono_watchlist_remove_item(modem->atom_watches, id);
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;
} }
struct ofono_atom *__ofono_modem_find_atom(struct ofono_modem *modem, 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->driver_type = g_strdup(type);
modem->properties = g_hash_table_new_full(g_str_hash, g_str_equal, modem->properties = g_hash_table_new_full(g_str_hash, g_str_equal,
g_free, unregister_property); g_free, unregister_property);
modem->atom_watches = __ofono_watchlist_new(g_free);
g_modem_list = g_slist_prepend(g_modem_list, modem); g_modem_list = g_slist_prepend(g_modem_list, modem);
@ -1165,7 +1116,9 @@ static void modem_unregister(struct ofono_modem *modem)
return; return;
remove_all_atoms(modem); 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_foreach(modem->interface_list, (GFunc)g_free, NULL);
g_slist_free(modem->interface_list); 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> #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> #include <ofono/plugin.h>
int __ofono_plugin_init(const char *pattern, const char *exclude); 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); 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, enum ofono_atom_type type,
ofono_atom_watch_func notify, ofono_atom_watch_func notify,
void *data, ofono_destroy_func destroy); 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); void __ofono_atom_free(struct ofono_atom *atom);

110
src/ssn.c
View File

@ -36,23 +36,19 @@
static GSList *g_drivers = NULL; static GSList *g_drivers = NULL;
struct ssn_handler { struct ssn_handler {
unsigned int id; struct ofono_watchlist_item item;
int code; int code;
void *notify;
void *data;
ofono_destroy_func destroy;
}; };
struct ofono_ssn { struct ofono_ssn {
GSList *mo_handler_list; struct ofono_watchlist *mo_handler_list;
GSList *mt_handler_list; struct ofono_watchlist *mt_handler_list;
unsigned int next_id;
const struct ofono_ssn_driver *driver; const struct ofono_ssn_driver *driver;
void *driver_data; void *driver_data;
struct ofono_atom *atom; 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, int code, void *notify, void *data,
ofono_destroy_func destroy) 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 = g_new0(struct ssn_handler, 1);
handler->code = code; handler->code = code;
handler->id = *id; handler->item.notify = notify;
*id = *id + 1; handler->item.notify_data = data;
handler->notify = notify; handler->item.destroy = destroy;
handler->destroy = destroy;
handler->data = data;
*l = g_slist_prepend(*l, handler); return __ofono_watchlist_add_item(watchlist,
(struct ofono_watchlist_item *)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;
} }
unsigned int __ofono_ssn_mo_watch_add(struct ofono_ssn *ssn, int code1, 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); DBG("%p, %d", ssn, code1);
return add_ssn_handler(&ssn->mo_handler_list, &ssn->next_id, return add_ssn_handler(ssn->mo_handler_list, code1, cb, user, destroy);
code1, cb, user, destroy);
} }
gboolean __ofono_ssn_mo_watch_remove(struct ofono_ssn *ssn, int id) 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); 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, 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); DBG("%p, %d", ssn, code2);
return add_ssn_handler(&ssn->mt_handler_list, &ssn->next_id, return add_ssn_handler(ssn->mt_handler_list, code2, cb, user, destroy);
code2, cb, user, destroy);
} }
gboolean __ofono_ssn_mt_watch_remove(struct ofono_ssn *ssn, int id) 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); 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) 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; GSList *l;
ofono_ssn_mo_notify_cb notify; 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; h = l->data;
notify = h->notify; notify = h->item.notify;
if (h->code == code1) 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; GSList *l;
ofono_ssn_mt_notify_cb notify; 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; h = l->data;
notify = h->notify; notify = h->item.notify;
if (h->code == code2) 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); struct ofono_ssn *ssn = __ofono_atom_get_data(atom);
remove_all_handlers(&ssn->mo_handler_list); __ofono_watchlist_free(ssn->mo_handler_list);
remove_all_handlers(&ssn->mt_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) 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) if (ssn == NULL)
return 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->atom = __ofono_modem_add_atom(modem, OFONO_ATOM_TYPE_SSN,
ssn_remove, 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);
}