Evolve message waiting low level API

This commit is contained in:
Denis Kenzior 2009-08-18 21:07:44 -05:00
parent a45007f91d
commit 5999b418e8
5 changed files with 249 additions and 185 deletions

View File

@ -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

41
include/message-waiting.h Normal file
View File

@ -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 <ofono/types.h>
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 */

View File

@ -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);
}

View File

@ -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 <ofono/message-waiting.h>
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);

View File

@ -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);
}