So DUN server could watch GPRS status changes and notify client unsolicited results like +CGREG. --- include/gprs.h | 9 +++++++++ src/gprs.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+), 0 deletions(-)
diff --git a/include/gprs.h b/include/gprs.h index a1cbcd9..c0a0e2f 100644 --- a/include/gprs.h +++ b/include/gprs.h @@ -36,6 +36,8 @@ typedef void (*ofono_gprs_status_cb_t)(const struct ofono_error *error, typedef void (*ofono_gprs_cb_t)(const struct ofono_error *error, void *data); +typedef void (*ofono_gprs_status_notify_cb_t)(const int status, void *data); + struct ofono_gprs_driver { const char *name; int (*probe)(struct ofono_gprs *gprs, unsigned int vendor, @@ -67,6 +69,13 @@ void ofono_gprs_set_cid_range(struct ofono_gprs *gprs, void ofono_gprs_add_context(struct ofono_gprs *gprs, struct ofono_gprs_context *gc); +unsigned int __ofono_gprs_add_status_watch(struct ofono_gprs *gprs, + ofono_gprs_status_notify_cb_t cb, + void *data, ofono_destroy_func destroy); + +gboolean __ofono_gprs_remove_status_watch(struct ofono_gprs *gprs, + unsigned int id); + #ifdef __cplusplus } #endif diff --git a/src/gprs.c b/src/gprs.c index 95f7ab2..b91a099 100644 --- a/src/gprs.c +++ b/src/gprs.c @@ -92,6 +92,7 @@ struct ofono_gprs { const struct ofono_gprs_driver *driver; void *driver_data; struct ofono_atom *atom; + struct ofono_watchlist *status_watches; struct ofono_emulator *dun; unsigned int dun_watch; unsigned int dun_status_watch; @@ -1467,6 +1468,51 @@ static GDBusSignalTable manager_signals[] = { { } }; +unsigned int __ofono_gprs_add_status_watch(struct ofono_gprs *gprs, + ofono_gprs_status_notify_cb_t notify, + void *data, ofono_destroy_func destroy) +{ + struct ofono_watchlist_item *item; + + DBG("%p", gprs); + + if (gprs == NULL) + return 0; + + if (notify == NULL) + return 0; + + item = g_new0(struct ofono_watchlist_item, 1); + + item->notify = notify; + item->destroy = destroy; + item->notify_data = data; + + return __ofono_watchlist_add_item(gprs->status_watches, item); +} + +gboolean __ofono_gprs_remove_status_watch(struct ofono_gprs *gprs, + unsigned int id) +{ + DBG("%p", gprs); + + return __ofono_watchlist_remove_item(gprs->status_watches, id); +} + +static void notify_status_watches(struct ofono_gprs *gprs) +{ + struct ofono_watchlist_item *item; + GSList *l; + ofono_gprs_status_notify_cb_t notify; + + for (l = gprs->status_watches->items; l; l = l->next) { + item = l->data; + notify = item->notify; + + notify(gprs->status, item->notify_data); + } +} + void ofono_gprs_detached_notify(struct ofono_gprs *gprs) { if (gprs->driver_attached == FALSE) @@ -1476,6 +1522,8 @@ void ofono_gprs_detached_notify(struct ofono_gprs *gprs) gprs_attached_update(gprs); + notify_status_watches(gprs); + /* TODO: The network forced a detach, we should wait for some time * and try to re-attach */ @@ -1489,6 +1537,8 @@ void ofono_gprs_status_notify(struct ofono_gprs *gprs, int status) gprs->status = status; gprs_attached_update(gprs); + + notify_status_watches(gprs); } void ofono_gprs_set_cid_range(struct ofono_gprs *gprs, @@ -1972,6 +2022,9 @@ static void gprs_unregister(struct ofono_atom *atom) const char *path = __ofono_atom_get_path(atom); GSList *l; + __ofono_watchlist_free(gprs->status_watches); + gprs->status_watches = NULL; + if (gprs->settings) { storage_close(gprs->imsi, SETTINGS_STORE, gprs->settings, TRUE); @@ -2289,6 +2342,8 @@ void ofono_gprs_register(struct ofono_gprs *gprs) ofono_modem_add_interface(modem, OFONO_DATA_CONNECTION_MANAGER_INTERFACE); + gprs->status_watches = __ofono_watchlist_new(g_free); + sim_atom = __ofono_modem_find_atom(modem, OFONO_ATOM_TYPE_SIM); if (sim_atom) { -- 1.7.0.4 _______________________________________________ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono