diff --git a/src/modem.c b/src/modem.c index 2c0d0e60..e58dfad3 100644 --- a/src/modem.c +++ b/src/modem.c @@ -62,7 +62,16 @@ struct ofono_atom { struct ofono_modem *modem; }; +struct ofono_atom_watch { + enum ofono_atom_type type; + int id; + ofono_atom_watch_func notify; + ofono_destroy_func destroy; + void *notify_data; +}; + unsigned int __ofono_modem_alloc_callid(struct ofono_modem *modem) + { struct ofono_modem_data *d = modem->modem_info; unsigned int i; @@ -161,6 +170,82 @@ void __ofono_atom_unregister(struct ofono_atom *atom) atom->unregister(atom); } +int __ofono_modem_add_atom_watch(struct ofono_modem *modem, + enum ofono_atom_type type, + ofono_atom_watch_func notify, + ofono_destroy_func destroy, void *data) +{ + struct ofono_atom_watch *watch; + + if (notify == NULL) + return 0; + + 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; + + modem->atom_watches = g_slist_prepend(modem->atom_watches, watch); + + return watch->id; +} + +gboolean __ofono_modem_remove_atom_watch(struct ofono_modem *modem, 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; +} + struct ofono_atom *__ofono_modem_find_atom(struct ofono_modem *modem, enum ofono_atom_type type) { @@ -546,6 +631,7 @@ static void modem_remove(struct ofono_modem *modem) ofono_debug("Removing modem: %s", modem->path); remove_all_atoms(modem); + remove_all_watches(modem); ofono_cssn_exit(modem); ofono_sim_manager_exit(modem); diff --git a/src/ofono.h b/src/ofono.h index 0c03a2fb..70239cdd 100644 --- a/src/ofono.h +++ b/src/ofono.h @@ -23,6 +23,8 @@ #define OFONO_API_SUBJECT_TO_CHANGE +typedef void (*ofono_destroy_func)(void *data); + int __ofono_manager_init(); void __ofono_manager_cleanup(); @@ -69,6 +71,8 @@ struct ofono_modem { GSList *ss_passwd_list; GSList *atoms; + GSList *atom_watches; + int next_atom_watch_id; struct ofono_modem_data *modem_info; struct network_registration_data *network_registration; @@ -107,6 +111,15 @@ enum ofono_atom_type { OFONO_ATOM_TYPE_HISTORY = 11 }; +enum ofono_atom_watch_condition { + OFONO_ATOM_WATCH_CONDITION_REGISTERED, + OFONO_ATOM_WATCH_CONDITION_UNREGISTERED +}; + +typedef void (*ofono_atom_watch_func)(struct ofono_atom *atom, + enum ofono_atom_watch_condition cond, + void *data); + struct ofono_atom *__ofono_modem_add_atom(struct ofono_modem *modem, enum ofono_atom_type type, void (*destruct)(struct ofono_atom *), @@ -123,6 +136,12 @@ void __ofono_atom_register(struct ofono_atom *atom, void (*unregister)(struct ofono_atom *)); void __ofono_atom_unregister(struct ofono_atom *atom); +int __ofono_modem_add_atom_watch(struct ofono_modem *modem, + enum ofono_atom_type type, + ofono_atom_watch_func notify, + ofono_destroy_func destroy, void *data); +gboolean __ofono_modem_remove_atom_watch(struct ofono_modem *modem, int id); + void __ofono_atom_free(struct ofono_atom *atom); #include