mirror of git://git.sysmocom.de/ofono
Evolve message waiting low level API
This commit is contained in:
parent
a45007f91d
commit
5999b418e8
|
@ -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
|
||||
|
||||
|
|
|
@ -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 */
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
57
src/sms.c
57
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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue