From 5999b418e8e171c2d1481b2e90ec42678b0603b9 Mon Sep 17 00:00:00 2001 From: Denis Kenzior Date: Tue, 18 Aug 2009 21:07:44 -0500 Subject: [PATCH] Evolve message waiting low level API --- include/Makefile.am | 2 +- include/message-waiting.h | 41 +++++ src/message-waiting.c | 327 ++++++++++++++++++-------------------- src/ofono.h | 7 +- src/sms.c | 57 +++++-- 5 files changed, 249 insertions(+), 185 deletions(-) create mode 100644 include/message-waiting.h diff --git a/include/Makefile.am b/include/Makefile.am index 133dda3b..207ce7b0 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -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 ussd.h sms.h sim.h + ssn.h ussd.h sms.h sim.h message-waiting.h nodist_include_HEADERS = version.h diff --git a/include/message-waiting.h b/include/message-waiting.h new file mode 100644 index 00000000..e0dd9307 --- /dev/null +++ b/include/message-waiting.h @@ -0,0 +1,41 @@ +/* + * + * 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_MESSAGE_WAITING_H +#define __OFONO_MESSAGE_WAITING_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +struct ofono_message_waiting; + +struct ofono_message_waiting *ofono_message_waiting_create(struct ofono_modem *modem); +void ofono_message_waiting_register(struct ofono_message_waiting *mw); +void ofono_message_waiting_remove(struct ofono_message_waiting *mw); + +#ifdef __cplusplus +} +#endif + +#endif /* __OFONO_MESSAGE_WAITING_H */ diff --git a/src/message-waiting.c b/src/message-waiting.c index b41705a2..ff7df4c9 100644 --- a/src/message-waiting.c +++ b/src/message-waiting.c @@ -34,7 +34,6 @@ #include "ofono.h" -#include "driver.h" #include "common.h" #include "util.h" #include "simutil.h" @@ -47,7 +46,7 @@ struct mailbox_state { unsigned char message_count; }; -struct message_waiting_data { +struct ofono_message_waiting { struct mailbox_state messages[5]; unsigned char efmwis_length; unsigned char efmbdn_length; @@ -56,42 +55,16 @@ struct message_waiting_data { struct ofono_sim *sim; unsigned int sim_watch; unsigned int sim_ready_watch; + struct ofono_atom *atom; }; struct mbdn_set_request { - struct ofono_modem *modem; - struct message_waiting_data *mw; + struct ofono_message_waiting *mw; int mailbox; struct ofono_phone_number number; DBusMessage *msg; }; -static struct message_waiting_data *message_waiting_create() -{ - return g_try_new0(struct message_waiting_data, 1); -} - -static void message_waiting_destroy(gpointer userdata) -{ - struct ofono_modem *modem = userdata; - struct message_waiting_data *data = modem->message_waiting; - - if (data->sim_watch) { - __ofono_modem_remove_atom_watch(modem, data->sim_watch); - data->sim_watch = 0; - } - - if (data->sim_ready_watch) { - ofono_sim_remove_ready_watch(data->sim, data->sim_ready_watch); - data->sim_ready_watch = 0; - data->sim = NULL; - } - - g_free(data); - - modem->message_waiting = NULL; -} - static const char *mw_message_waiting_property_name[5] = { "VoicemailWaiting", #if 0 @@ -125,8 +98,7 @@ static const char *mw_mailbox_property_name[5] = { static DBusMessage *mw_get_properties(DBusConnection *conn, DBusMessage *msg, void *data) { - struct ofono_modem *modem = data; - struct message_waiting_data *mw = modem->message_waiting; + struct ofono_message_waiting *mw = data; DBusMessage *reply; DBusMessageIter iter; DBusMessageIter dict; @@ -199,11 +171,12 @@ static void mbdn_set_cb(int ok, void *data) if (property) { DBusConnection *conn = ofono_dbus_get_connection(); + const char *path = __ofono_atom_get_path(req->mw->atom); const char *number; number = phone_number_to_string(old); - ofono_dbus_signal_property_changed(conn, req->modem->path, + ofono_dbus_signal_property_changed(conn, path, MESSAGE_WAITING_INTERFACE, property, DBUS_TYPE_STRING, &number); @@ -219,13 +192,13 @@ out: g_free(req); } -static DBusMessage *set_mbdn(struct ofono_modem *modem, int mailbox, +static DBusMessage *set_mbdn(struct ofono_message_waiting *mw, int mailbox, const char *number, DBusMessage *msg) { struct mbdn_set_request *req; unsigned char efmbdn[255]; - if (modem->message_waiting->efmbdn_record_id[mailbox] == 0) { + if (mw->efmbdn_record_id[mailbox] == 0) { if (msg) return __ofono_error_failed(msg); @@ -234,8 +207,7 @@ static DBusMessage *set_mbdn(struct ofono_modem *modem, int mailbox, req = g_new0(struct mbdn_set_request, 1); - req->modem = modem; - req->mw = modem->message_waiting; + req->mw = mw; req->mailbox = mailbox; string_to_phone_number(number, &req->number); req->msg = dbus_message_ref(msg); @@ -258,8 +230,7 @@ static DBusMessage *set_mbdn(struct ofono_modem *modem, int mailbox, static DBusMessage *mw_set_property(DBusConnection *conn, DBusMessage *msg, void *data) { - struct ofono_modem *modem = data; - struct message_waiting_data *mw = modem->message_waiting; + struct ofono_message_waiting *mw = data; DBusMessageIter iter; DBusMessageIter var; const char *name, *value; @@ -304,7 +275,7 @@ static DBusMessage *mw_set_property(DBusConnection *conn, DBusMessage *msg, if (g_str_equal(cur_number, value)) return dbus_message_new_method_return(msg); - return set_mbdn(modem, i, value, msg); + return set_mbdn(mw, i, value, msg); } return __ofono_error_invalid_args(msg); @@ -327,13 +298,13 @@ static void mw_mwis_read_cb(int ok, int record, const unsigned char *data, int record_length, void *userdata) { - struct ofono_modem *modem = userdata; + struct ofono_message_waiting *mw = userdata; int i, status; struct mailbox_state info; dbus_bool_t indication; unsigned char count; DBusConnection *conn = ofono_dbus_get_connection(); - struct message_waiting_data *mw = modem->message_waiting; + const char *path = __ofono_atom_get_path(mw->atom); if (!ok || structure != OFONO_SIM_FILE_STRUCTURE_FIXED || @@ -368,12 +339,12 @@ static void mw_mwis_read_cb(int ok, if (!mw_message_waiting_property_name[i]) continue; - ofono_dbus_signal_property_changed(conn, modem->path, + ofono_dbus_signal_property_changed(conn, path, MESSAGE_WAITING_INTERFACE, mw_message_waiting_property_name[i], DBUS_TYPE_BOOLEAN, &indication); - ofono_dbus_signal_property_changed(conn, modem->path, + ofono_dbus_signal_property_changed(conn, path, MESSAGE_WAITING_INTERFACE, mw_message_count_property_name[i], DBUS_TYPE_BYTE, &count); @@ -388,10 +359,9 @@ static void mw_mbdn_read_cb(int ok, int record, const unsigned char *data, int record_length, void *userdata) { - struct ofono_modem *modem = userdata; + struct ofono_message_waiting *mw = userdata; int i; DBusConnection *conn = ofono_dbus_get_connection(); - struct message_waiting_data *mw = modem->message_waiting; const char *value; if (!ok || @@ -415,9 +385,11 @@ static void mw_mbdn_read_cb(int ok, mw->mailbox_number[i].number[0] = '\0'; if (mw_mailbox_property_name[i]) { + const char *path = __ofono_atom_get_path(mw->atom); + value = phone_number_to_string(&mw->mailbox_number[i]); - ofono_dbus_signal_property_changed(conn, modem->path, + ofono_dbus_signal_property_changed(conn, path, MESSAGE_WAITING_INTERFACE, mw_mailbox_property_name[i], DBUS_TYPE_STRING, &value); @@ -431,9 +403,8 @@ static void mw_mbi_read_cb(int ok, int record, const unsigned char *data, int record_length, void *userdata) { - struct ofono_modem *modem = userdata; + struct ofono_message_waiting *mw = userdata; int i, err; - struct message_waiting_data *mw = modem->message_waiting; if (!ok || structure != OFONO_SIM_FILE_STRUCTURE_FIXED || @@ -452,7 +423,7 @@ static void mw_mbi_read_cb(int ok, for (i = 0; i < 5 && i < record_length; i++) mw->efmbdn_record_id[i] = data[i]; - err = ofono_sim_read(mw->sim, SIM_EFMBDN_FILEID, mw_mbdn_read_cb, modem); + err = ofono_sim_read(mw->sim, SIM_EFMBDN_FILEID, mw_mbdn_read_cb, mw); if (err != 0) ofono_error("Unable to read EF-MBDN from SIM"); @@ -464,30 +435,10 @@ static void mw_mwis_write_cb(int ok, void *userdata) ofono_error("Writing new EF-MBDN failed"); } -/* Loads MWI states and MBDN from SIM */ -static gboolean mw_mwis_load(struct ofono_modem *modem) -{ - struct message_waiting_data *mw = modem->message_waiting; - int err; - - err = ofono_sim_read(mw->sim, SIM_EFMWIS_FILEID, mw_mwis_read_cb, modem); - - if (err != 0) - return FALSE; - - err = ofono_sim_read(mw->sim, SIM_EFMBI_FILEID, mw_mbi_read_cb, modem); - - if (err != 0) - return FALSE; - - return TRUE; -} - -static void mw_set_indicator(struct ofono_modem *modem, int profile, +static void mw_set_indicator(struct ofono_message_waiting *mw, int profile, enum sms_mwi_type type, gboolean present, unsigned char messages) { - struct message_waiting_data *mw = modem->message_waiting; DBusConnection *conn = ofono_dbus_get_connection(); unsigned char efmwis[255]; /* Max record size */ int i; @@ -505,22 +456,25 @@ static void mw_set_indicator(struct ofono_modem *modem, int profile, if (mw->messages[type].indication != present) { dbus_bool_t indication; + const char *path = __ofono_atom_get_path(mw->atom); indication = present; mw->messages[type].indication = present; if (!mw_message_waiting_property_name[type]) - ofono_dbus_signal_property_changed(conn, modem->path, + ofono_dbus_signal_property_changed(conn, path, MESSAGE_WAITING_INTERFACE, mw_message_waiting_property_name[type], DBUS_TYPE_BOOLEAN, &indication); } if (mw->messages[type].message_count != messages) { + const char *path = __ofono_atom_get_path(mw->atom); + mw->messages[type].message_count = messages; if (!mw_message_waiting_property_name[type]) - ofono_dbus_signal_property_changed(conn, modem->path, + ofono_dbus_signal_property_changed(conn, path, MESSAGE_WAITING_INTERFACE, mw_message_count_property_name[type], DBUS_TYPE_BYTE, &messages); @@ -543,95 +497,13 @@ static void mw_set_indicator(struct ofono_modem *modem, int profile, if (ofono_sim_write(mw->sim, SIM_EFMWIS_FILEID, mw_mwis_write_cb, OFONO_SIM_FILE_STRUCTURE_FIXED, 1, - efmwis, mw->efmwis_length, modem) != 0) { + efmwis, mw->efmwis_length, mw) != 0) { ofono_error("Queuing a EF-MWI write to SIM failed"); } } -static void initialize_message_waiting(void *user_data) -{ - struct ofono_modem *modem = user_data; - DBusConnection *conn = ofono_dbus_get_connection(); - - if (!mw_mwis_load(modem)) { - ofono_error("Could not register MessageWaiting interface"); - message_waiting_destroy(modem); - - return; - } - - if (!g_dbus_register_interface(conn, modem->path, - MESSAGE_WAITING_INTERFACE, - message_waiting_methods, - message_waiting_signals, - NULL, modem, - message_waiting_destroy)) { - ofono_error("Could not register MessageWaiting interface"); - message_waiting_destroy(modem); - - return; - } - - ofono_debug("MessageWaiting interface for modem: %s created", - modem->path); - - ofono_modem_add_interface(modem, MESSAGE_WAITING_INTERFACE); -} - -static void sim_watch(struct ofono_atom *atom, - enum ofono_atom_watch_condition cond, void *data) -{ - struct ofono_modem *modem = data; - struct message_waiting_data *mw = modem->message_waiting; - - if (cond == OFONO_ATOM_WATCH_CONDITION_UNREGISTERED) { - mw->sim = NULL; - mw->sim_ready_watch = 0; - return; - } - - mw->sim = __ofono_atom_get_data(atom); - mw->sim_ready_watch = ofono_sim_add_ready_watch(mw->sim, - initialize_message_waiting, modem, NULL); - - if (ofono_sim_get_ready(mw->sim)) - initialize_message_waiting(modem); -} - -int ofono_message_waiting_register(struct ofono_modem *modem) -{ - struct message_waiting_data *mw; - struct ofono_atom *sim_atom; - - if (modem == NULL) - return -1; - - mw = message_waiting_create(); - modem->message_waiting = mw; - - mw->sim_watch = __ofono_modem_add_atom_watch(modem, - OFONO_ATOM_TYPE_SIM, - sim_watch, modem, NULL); - - sim_atom = __ofono_modem_find_atom(modem, OFONO_ATOM_TYPE_SIM); - - if (sim_atom && __ofono_atom_get_registered(sim_atom)) - sim_watch(sim_atom, OFONO_ATOM_WATCH_CONDITION_REGISTERED, - modem); - return 0; -} - -void ofono_message_waiting_unregister(struct ofono_modem *modem) -{ - DBusConnection *conn = ofono_dbus_get_connection(); - - g_dbus_unregister_interface(conn, modem->path, - MESSAGE_WAITING_INTERFACE); - ofono_modem_remove_interface(modem, MESSAGE_WAITING_INTERFACE); -} - -static void handle_special_sms_iei(struct ofono_modem *modem, - const guint8 *iei, gboolean *discard) +static void handle_special_sms_iei(struct ofono_message_waiting *mw, + const guint8 *iei, gboolean *discard) { enum sms_mwi_type type; int profile; @@ -656,11 +528,12 @@ static void handle_special_sms_iei(struct ofono_modem *modem, set = iei[1] > 0 ? TRUE : FALSE; profile = ((iei[0] >> 5) & 3) + 1; - mw_set_indicator(modem, profile, type, set, iei[1]); + mw_set_indicator(mw, profile, type, set, iei[1]); } -static void handle_enhanced_voicemail_iei(struct ofono_modem *modem, - const guint8 *iei, gboolean *discard, int length) +static void handle_enhanced_voicemail_iei(struct ofono_message_waiting *mw, + const guint8 *iei, + gboolean *discard, int length) { int profile, n; gboolean set; @@ -691,7 +564,7 @@ static void handle_enhanced_voicemail_iei(struct ofono_modem *modem, /* Other parameters currently not supported */ set = iei[n + 2] > 0 ? TRUE : FALSE; - mw_set_indicator(modem, profile, SMS_MWI_TYPE_VOICE, + mw_set_indicator(mw, profile, SMS_MWI_TYPE_VOICE, set, iei[n + 2]); } else { /* 9.2.3.24.13.2 Enhanced Voice Delete Confirmation */ @@ -712,17 +585,17 @@ static void handle_enhanced_voicemail_iei(struct ofono_modem *modem, /* Other parameters currently not supported */ set = iei[n + 2] > 0 ? TRUE : FALSE; - mw_set_indicator(modem, profile, SMS_MWI_TYPE_VOICE, + mw_set_indicator(mw, profile, SMS_MWI_TYPE_VOICE, set, iei[n + 2]); } if (mailbox_address.address[0] != '\0') - set_mbdn(modem, SMS_MWI_TYPE_VOICE, + set_mbdn(mw, SMS_MWI_TYPE_VOICE, sms_address_to_string(&mailbox_address), NULL); } -void ofono_handle_sms_mwi(struct ofono_modem *modem, - struct sms *sms, gboolean *out_discard) +void __ofono_message_waiting_mwi(struct ofono_message_waiting *mw, + struct sms *sms, gboolean *out_discard) { gboolean active, discard; enum sms_mwi_type type; @@ -749,7 +622,7 @@ void ofono_handle_sms_mwi(struct ofono_modem *modem, case SMS_IEI_ENHANCED_VOICE_MAIL_INFORMATION: sms_udh_iter_get_ie_data(&iter, evm_iei); - handle_enhanced_voicemail_iei(modem, evm_iei, + handle_enhanced_voicemail_iei(mw, evm_iei, out_discard, sms_udh_iter_get_ie_length( &iter)); @@ -778,7 +651,7 @@ void ofono_handle_sms_mwi(struct ofono_modem *modem, break; sms_udh_iter_get_ie_data(&iter, special_iei); - handle_special_sms_iei(modem, special_iei, + handle_special_sms_iei(mw, special_iei, &discard); if (out_discard) *out_discard = *out_discard || discard; @@ -810,7 +683,7 @@ void ofono_handle_sms_mwi(struct ofono_modem *modem, if (sms_mwi_dcs_decode(sms->deliver.dcs, &type, NULL, &active, out_discard)) { - mw_set_indicator(modem, profile, type, active, 0); + mw_set_indicator(mw, profile, type, active, 0); return; } @@ -818,3 +691,119 @@ void ofono_handle_sms_mwi(struct ofono_modem *modem, if (sms->deliver.pid == SMS_PID_TYPE_RETURN_CALL) return; } + +static void message_waiting_sim_ready(void *userdata) +{ + struct ofono_message_waiting *mw = userdata; + + /* Loads MWI states and MBDN from SIM */ + ofono_sim_read(mw->sim, SIM_EFMWIS_FILEID, mw_mwis_read_cb, mw); + ofono_sim_read(mw->sim, SIM_EFMBI_FILEID, mw_mbi_read_cb, mw); +} + +static void message_waiting_unregister(struct ofono_atom *atom) +{ + struct ofono_message_waiting *mw = __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); + + if (mw->sim_watch) { + __ofono_modem_remove_atom_watch(modem, mw->sim_watch); + mw->sim_watch = 0; + } + + if (mw->sim_ready_watch) { + ofono_sim_remove_ready_watch(mw->sim, mw->sim_ready_watch); + mw->sim_ready_watch = 0; + mw->sim = NULL; + } + + g_dbus_unregister_interface(conn, path, + MESSAGE_WAITING_INTERFACE); + ofono_modem_remove_interface(modem, MESSAGE_WAITING_INTERFACE); +} + +static void sim_watch(struct ofono_atom *atom, + enum ofono_atom_watch_condition cond, void *data) +{ + struct ofono_message_waiting *mw = data; + + if (cond == OFONO_ATOM_WATCH_CONDITION_UNREGISTERED) { + mw->sim = NULL; + mw->sim_ready_watch = 0; + return; + } + + mw->sim = __ofono_atom_get_data(atom); + mw->sim_ready_watch = ofono_sim_add_ready_watch(mw->sim, + message_waiting_sim_ready, mw, NULL); + + if (ofono_sim_get_ready(mw->sim)) + message_waiting_sim_ready(mw); +} + +void ofono_message_waiting_register(struct ofono_message_waiting *mw) +{ + DBusConnection *conn = ofono_dbus_get_connection(); + const char *path = __ofono_atom_get_path(mw->atom); + struct ofono_modem *modem = __ofono_atom_get_modem(mw->atom); + struct ofono_atom *sim_atom; + + if (!g_dbus_register_interface(conn, path, + MESSAGE_WAITING_INTERFACE, + message_waiting_methods, + message_waiting_signals, + NULL, mw, NULL)) { + ofono_error("Could not create %s interface", + MESSAGE_WAITING_INTERFACE); + return; + } + + ofono_modem_add_interface(modem, MESSAGE_WAITING_INTERFACE); + + mw->sim_watch = __ofono_modem_add_atom_watch(modem, + OFONO_ATOM_TYPE_SIM, + sim_watch, mw, NULL); + + sim_atom = __ofono_modem_find_atom(modem, OFONO_ATOM_TYPE_SIM); + + if (sim_atom && __ofono_atom_get_registered(sim_atom)) + sim_watch(sim_atom, OFONO_ATOM_WATCH_CONDITION_REGISTERED, mw); + + __ofono_atom_register(mw->atom, message_waiting_unregister); +} + +static void mw_remove(struct ofono_atom *atom) +{ + struct ofono_message_waiting *mw = __ofono_atom_get_data(atom); + struct ofono_modem *modem = __ofono_atom_get_modem(atom); + + DBG("atom: %p", atom); + + if (mw == NULL) + return; + + g_free(mw); +} + +struct ofono_message_waiting *ofono_message_waiting_create(struct ofono_modem *modem) +{ + struct ofono_message_waiting *mw; + + mw = g_try_new0(struct ofono_message_waiting, 1); + + if (mw == NULL) + return NULL; + + mw->atom = __ofono_modem_add_atom(modem, + OFONO_ATOM_TYPE_MESSAGE_WAITING, + mw_remove, mw); + + return mw; +} + +void ofono_message_waiting_remove(struct ofono_message_waiting *mw) +{ + __ofono_atom_free(mw->atom); +} diff --git a/src/ofono.h b/src/ofono.h index cad840f5..54c29f2b 100644 --- a/src/ofono.h +++ b/src/ofono.h @@ -99,6 +99,7 @@ enum ofono_atom_type { OFONO_ATOM_TYPE_VOICECALL = 10, OFONO_ATOM_TYPE_HISTORY = 11, OFONO_ATOM_TYPE_SSN = 12, + OFONO_ATOM_TYPE_MESSAGE_WAITING = 13, }; enum ofono_atom_watch_condition { @@ -196,9 +197,9 @@ void __ofono_history_call_ended(struct ofono_modem *modem, void __ofono_history_call_missed(struct ofono_modem *modem, const struct ofono_call *call, time_t when); +#include + struct sms; -int ofono_message_waiting_register(struct ofono_modem *modem); -void ofono_message_waiting_unregister(struct ofono_modem *modem); -void ofono_handle_sms_mwi(struct ofono_modem *modem, +void __ofono_message_waiting_mwi(struct ofono_message_waiting *mw, struct sms *sms, gboolean *out_discard); diff --git a/src/sms.c b/src/sms.c index 4c55ac2f..1bb9d4cb 100644 --- a/src/sms.c +++ b/src/sms.c @@ -55,6 +55,8 @@ struct ofono_sms { GQueue *txq; time_t last_mms; gint tx_source; + struct ofono_message_waiting *mw; + unsigned int mw_watch; const struct ofono_sms_driver *driver; void *driver_data; struct ofono_atom *atom; @@ -616,13 +618,24 @@ static void handle_deliver(struct ofono_sms *sms, const struct sms *incoming) g_slist_free(l); } +static inline gboolean handle_mwi(struct ofono_sms *sms, struct sms *s) +{ + gboolean discard; + + if (sms->mw == NULL) + return FALSE; + + __ofono_message_waiting_mwi(sms->mw, s, &discard); + + return discard; +} + void ofono_sms_deliver_notify(struct ofono_sms *sms, unsigned char *pdu, int len, int tpdu_len) { struct ofono_modem *modem = __ofono_atom_get_modem(sms->atom); struct sms s; enum sms_class cls; - gboolean discard; if (!sms_decode(pdu, len, FALSE, tpdu_len, &s)) { ofono_error("Unable to decode PDU"); @@ -642,9 +655,7 @@ void ofono_sms_deliver_notify(struct ofono_sms *sms, unsigned char *pdu, /* This is an older style MWI notification, process MWI * headers and handle it like any other message */ if (s.deliver.pid == SMS_PID_TYPE_RETURN_CALL) { - ofono_handle_sms_mwi(modem, &s, &discard); - - if (discard) + if (handle_mwi(sms, &s)) return; goto out; @@ -653,9 +664,7 @@ void ofono_sms_deliver_notify(struct ofono_sms *sms, unsigned char *pdu, /* The DCS indicates this is an MWI notification, process it * and then handle the User-Data as any other message */ if (sms_mwi_dcs_decode(s.deliver.dcs, NULL, NULL, NULL, NULL)) { - ofono_handle_sms_mwi(modem, &s, &discard); - - if (discard) + if (handle_mwi(sms, &s)) return; goto out; @@ -721,9 +730,7 @@ void ofono_sms_deliver_notify(struct ofono_sms *sms, unsigned char *pdu, /* TODO: ignore if not in the very first * segment of a concatenated SM so as not * to repeat the indication. */ - ofono_handle_sms_mwi(modem, &s, &discard); - - if (discard) + if (handle_mwi(sms, &s)) return; goto out; @@ -774,7 +781,11 @@ static void sms_unregister(struct ofono_atom *atom) g_dbus_unregister_interface(conn, path, SMS_MANAGER_INTERFACE); ofono_modem_remove_interface(modem, SMS_MANAGER_INTERFACE); - ofono_message_waiting_unregister(modem); + + if (sms->mw_watch) { + __ofono_modem_remove_atom_watch(modem, sms->mw_watch); + sms->mw_watch = 0; + } } static void sms_remove(struct ofono_atom *atom) @@ -847,11 +858,25 @@ struct ofono_sms *ofono_sms_create(struct ofono_modem *modem, return sms; } +static void mw_watch(struct ofono_atom *atom, + enum ofono_atom_watch_condition cond, void *data) +{ + struct ofono_sms *sms = data; + + if (cond == OFONO_ATOM_WATCH_CONDITION_UNREGISTERED) { + sms->mw = NULL; + return; + } + + sms->mw = __ofono_atom_get_data(atom); +} + void ofono_sms_register(struct ofono_sms *sms) { DBusConnection *conn = ofono_dbus_get_connection(); struct ofono_modem *modem = __ofono_atom_get_modem(sms->atom); const char *path = __ofono_atom_get_path(sms->atom); + struct ofono_atom *mw_atom; if (!g_dbus_register_interface(conn, path, SMS_MANAGER_INTERFACE, @@ -865,7 +890,15 @@ void ofono_sms_register(struct ofono_sms *sms) ofono_modem_add_interface(modem, SMS_MANAGER_INTERFACE); - ofono_message_waiting_register(modem); + sms->mw_watch = __ofono_modem_add_atom_watch(modem, + OFONO_ATOM_TYPE_MESSAGE_WAITING, + mw_watch, sms, NULL); + + mw_atom = __ofono_modem_find_atom(modem, + OFONO_ATOM_TYPE_MESSAGE_WAITING); + + if (mw_atom && __ofono_atom_get_registered(mw_atom)) + mw_watch(mw_atom, OFONO_ATOM_WATCH_CONDITION_REGISTERED, sms); __ofono_atom_register(sms->atom, sms_unregister); }