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 \
|
include_HEADERS = log.h plugin.h history.h dbus.h modem.h \
|
||||||
types.h call-barring.h call-forwarding.h \
|
types.h call-barring.h call-forwarding.h \
|
||||||
call-meter.h call-settings.h phonebook.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
|
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 "ofono.h"
|
||||||
|
|
||||||
#include "driver.h"
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "simutil.h"
|
#include "simutil.h"
|
||||||
|
@ -47,7 +46,7 @@ struct mailbox_state {
|
||||||
unsigned char message_count;
|
unsigned char message_count;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct message_waiting_data {
|
struct ofono_message_waiting {
|
||||||
struct mailbox_state messages[5];
|
struct mailbox_state messages[5];
|
||||||
unsigned char efmwis_length;
|
unsigned char efmwis_length;
|
||||||
unsigned char efmbdn_length;
|
unsigned char efmbdn_length;
|
||||||
|
@ -56,42 +55,16 @@ struct message_waiting_data {
|
||||||
struct ofono_sim *sim;
|
struct ofono_sim *sim;
|
||||||
unsigned int sim_watch;
|
unsigned int sim_watch;
|
||||||
unsigned int sim_ready_watch;
|
unsigned int sim_ready_watch;
|
||||||
|
struct ofono_atom *atom;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct mbdn_set_request {
|
struct mbdn_set_request {
|
||||||
struct ofono_modem *modem;
|
struct ofono_message_waiting *mw;
|
||||||
struct message_waiting_data *mw;
|
|
||||||
int mailbox;
|
int mailbox;
|
||||||
struct ofono_phone_number number;
|
struct ofono_phone_number number;
|
||||||
DBusMessage *msg;
|
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] = {
|
static const char *mw_message_waiting_property_name[5] = {
|
||||||
"VoicemailWaiting",
|
"VoicemailWaiting",
|
||||||
#if 0
|
#if 0
|
||||||
|
@ -125,8 +98,7 @@ static const char *mw_mailbox_property_name[5] = {
|
||||||
static DBusMessage *mw_get_properties(DBusConnection *conn,
|
static DBusMessage *mw_get_properties(DBusConnection *conn,
|
||||||
DBusMessage *msg, void *data)
|
DBusMessage *msg, void *data)
|
||||||
{
|
{
|
||||||
struct ofono_modem *modem = data;
|
struct ofono_message_waiting *mw = data;
|
||||||
struct message_waiting_data *mw = modem->message_waiting;
|
|
||||||
DBusMessage *reply;
|
DBusMessage *reply;
|
||||||
DBusMessageIter iter;
|
DBusMessageIter iter;
|
||||||
DBusMessageIter dict;
|
DBusMessageIter dict;
|
||||||
|
@ -199,11 +171,12 @@ static void mbdn_set_cb(int ok, void *data)
|
||||||
|
|
||||||
if (property) {
|
if (property) {
|
||||||
DBusConnection *conn = ofono_dbus_get_connection();
|
DBusConnection *conn = ofono_dbus_get_connection();
|
||||||
|
const char *path = __ofono_atom_get_path(req->mw->atom);
|
||||||
const char *number;
|
const char *number;
|
||||||
|
|
||||||
number = phone_number_to_string(old);
|
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,
|
MESSAGE_WAITING_INTERFACE,
|
||||||
property, DBUS_TYPE_STRING,
|
property, DBUS_TYPE_STRING,
|
||||||
&number);
|
&number);
|
||||||
|
@ -219,13 +192,13 @@ out:
|
||||||
g_free(req);
|
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)
|
const char *number, DBusMessage *msg)
|
||||||
{
|
{
|
||||||
struct mbdn_set_request *req;
|
struct mbdn_set_request *req;
|
||||||
unsigned char efmbdn[255];
|
unsigned char efmbdn[255];
|
||||||
|
|
||||||
if (modem->message_waiting->efmbdn_record_id[mailbox] == 0) {
|
if (mw->efmbdn_record_id[mailbox] == 0) {
|
||||||
if (msg)
|
if (msg)
|
||||||
return __ofono_error_failed(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 = g_new0(struct mbdn_set_request, 1);
|
||||||
|
|
||||||
req->modem = modem;
|
req->mw = mw;
|
||||||
req->mw = modem->message_waiting;
|
|
||||||
req->mailbox = mailbox;
|
req->mailbox = mailbox;
|
||||||
string_to_phone_number(number, &req->number);
|
string_to_phone_number(number, &req->number);
|
||||||
req->msg = dbus_message_ref(msg);
|
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,
|
static DBusMessage *mw_set_property(DBusConnection *conn, DBusMessage *msg,
|
||||||
void *data)
|
void *data)
|
||||||
{
|
{
|
||||||
struct ofono_modem *modem = data;
|
struct ofono_message_waiting *mw = data;
|
||||||
struct message_waiting_data *mw = modem->message_waiting;
|
|
||||||
DBusMessageIter iter;
|
DBusMessageIter iter;
|
||||||
DBusMessageIter var;
|
DBusMessageIter var;
|
||||||
const char *name, *value;
|
const char *name, *value;
|
||||||
|
@ -304,7 +275,7 @@ static DBusMessage *mw_set_property(DBusConnection *conn, DBusMessage *msg,
|
||||||
if (g_str_equal(cur_number, value))
|
if (g_str_equal(cur_number, value))
|
||||||
return dbus_message_new_method_return(msg);
|
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);
|
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,
|
int record, const unsigned char *data, int record_length,
|
||||||
void *userdata)
|
void *userdata)
|
||||||
{
|
{
|
||||||
struct ofono_modem *modem = userdata;
|
struct ofono_message_waiting *mw = userdata;
|
||||||
int i, status;
|
int i, status;
|
||||||
struct mailbox_state info;
|
struct mailbox_state info;
|
||||||
dbus_bool_t indication;
|
dbus_bool_t indication;
|
||||||
unsigned char count;
|
unsigned char count;
|
||||||
DBusConnection *conn = ofono_dbus_get_connection();
|
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 ||
|
if (!ok ||
|
||||||
structure != OFONO_SIM_FILE_STRUCTURE_FIXED ||
|
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])
|
if (!mw_message_waiting_property_name[i])
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
ofono_dbus_signal_property_changed(conn, modem->path,
|
ofono_dbus_signal_property_changed(conn, path,
|
||||||
MESSAGE_WAITING_INTERFACE,
|
MESSAGE_WAITING_INTERFACE,
|
||||||
mw_message_waiting_property_name[i],
|
mw_message_waiting_property_name[i],
|
||||||
DBUS_TYPE_BOOLEAN, &indication);
|
DBUS_TYPE_BOOLEAN, &indication);
|
||||||
|
|
||||||
ofono_dbus_signal_property_changed(conn, modem->path,
|
ofono_dbus_signal_property_changed(conn, path,
|
||||||
MESSAGE_WAITING_INTERFACE,
|
MESSAGE_WAITING_INTERFACE,
|
||||||
mw_message_count_property_name[i],
|
mw_message_count_property_name[i],
|
||||||
DBUS_TYPE_BYTE, &count);
|
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,
|
int record, const unsigned char *data, int record_length,
|
||||||
void *userdata)
|
void *userdata)
|
||||||
{
|
{
|
||||||
struct ofono_modem *modem = userdata;
|
struct ofono_message_waiting *mw = userdata;
|
||||||
int i;
|
int i;
|
||||||
DBusConnection *conn = ofono_dbus_get_connection();
|
DBusConnection *conn = ofono_dbus_get_connection();
|
||||||
struct message_waiting_data *mw = modem->message_waiting;
|
|
||||||
const char *value;
|
const char *value;
|
||||||
|
|
||||||
if (!ok ||
|
if (!ok ||
|
||||||
|
@ -415,9 +385,11 @@ static void mw_mbdn_read_cb(int ok,
|
||||||
mw->mailbox_number[i].number[0] = '\0';
|
mw->mailbox_number[i].number[0] = '\0';
|
||||||
|
|
||||||
if (mw_mailbox_property_name[i]) {
|
if (mw_mailbox_property_name[i]) {
|
||||||
|
const char *path = __ofono_atom_get_path(mw->atom);
|
||||||
|
|
||||||
value = phone_number_to_string(&mw->mailbox_number[i]);
|
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,
|
MESSAGE_WAITING_INTERFACE,
|
||||||
mw_mailbox_property_name[i],
|
mw_mailbox_property_name[i],
|
||||||
DBUS_TYPE_STRING, &value);
|
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,
|
int record, const unsigned char *data, int record_length,
|
||||||
void *userdata)
|
void *userdata)
|
||||||
{
|
{
|
||||||
struct ofono_modem *modem = userdata;
|
struct ofono_message_waiting *mw = userdata;
|
||||||
int i, err;
|
int i, err;
|
||||||
struct message_waiting_data *mw = modem->message_waiting;
|
|
||||||
|
|
||||||
if (!ok ||
|
if (!ok ||
|
||||||
structure != OFONO_SIM_FILE_STRUCTURE_FIXED ||
|
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++)
|
for (i = 0; i < 5 && i < record_length; i++)
|
||||||
mw->efmbdn_record_id[i] = data[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)
|
if (err != 0)
|
||||||
ofono_error("Unable to read EF-MBDN from SIM");
|
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");
|
ofono_error("Writing new EF-MBDN failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Loads MWI states and MBDN from SIM */
|
static void mw_set_indicator(struct ofono_message_waiting *mw, int profile,
|
||||||
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,
|
|
||||||
enum sms_mwi_type type,
|
enum sms_mwi_type type,
|
||||||
gboolean present, unsigned char messages)
|
gboolean present, unsigned char messages)
|
||||||
{
|
{
|
||||||
struct message_waiting_data *mw = modem->message_waiting;
|
|
||||||
DBusConnection *conn = ofono_dbus_get_connection();
|
DBusConnection *conn = ofono_dbus_get_connection();
|
||||||
unsigned char efmwis[255]; /* Max record size */
|
unsigned char efmwis[255]; /* Max record size */
|
||||||
int i;
|
int i;
|
||||||
|
@ -505,22 +456,25 @@ static void mw_set_indicator(struct ofono_modem *modem, int profile,
|
||||||
|
|
||||||
if (mw->messages[type].indication != present) {
|
if (mw->messages[type].indication != present) {
|
||||||
dbus_bool_t indication;
|
dbus_bool_t indication;
|
||||||
|
const char *path = __ofono_atom_get_path(mw->atom);
|
||||||
|
|
||||||
indication = present;
|
indication = present;
|
||||||
mw->messages[type].indication = present;
|
mw->messages[type].indication = present;
|
||||||
|
|
||||||
if (!mw_message_waiting_property_name[type])
|
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,
|
MESSAGE_WAITING_INTERFACE,
|
||||||
mw_message_waiting_property_name[type],
|
mw_message_waiting_property_name[type],
|
||||||
DBUS_TYPE_BOOLEAN, &indication);
|
DBUS_TYPE_BOOLEAN, &indication);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mw->messages[type].message_count != messages) {
|
if (mw->messages[type].message_count != messages) {
|
||||||
|
const char *path = __ofono_atom_get_path(mw->atom);
|
||||||
|
|
||||||
mw->messages[type].message_count = messages;
|
mw->messages[type].message_count = messages;
|
||||||
|
|
||||||
if (!mw_message_waiting_property_name[type])
|
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,
|
MESSAGE_WAITING_INTERFACE,
|
||||||
mw_message_count_property_name[type],
|
mw_message_count_property_name[type],
|
||||||
DBUS_TYPE_BYTE, &messages);
|
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,
|
if (ofono_sim_write(mw->sim, SIM_EFMWIS_FILEID, mw_mwis_write_cb,
|
||||||
OFONO_SIM_FILE_STRUCTURE_FIXED, 1,
|
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");
|
ofono_error("Queuing a EF-MWI write to SIM failed");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void initialize_message_waiting(void *user_data)
|
static void handle_special_sms_iei(struct ofono_message_waiting *mw,
|
||||||
{
|
const guint8 *iei, gboolean *discard)
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
enum sms_mwi_type type;
|
enum sms_mwi_type type;
|
||||||
int profile;
|
int profile;
|
||||||
|
@ -656,11 +528,12 @@ static void handle_special_sms_iei(struct ofono_modem *modem,
|
||||||
set = iei[1] > 0 ? TRUE : FALSE;
|
set = iei[1] > 0 ? TRUE : FALSE;
|
||||||
profile = ((iei[0] >> 5) & 3) + 1;
|
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,
|
static void handle_enhanced_voicemail_iei(struct ofono_message_waiting *mw,
|
||||||
const guint8 *iei, gboolean *discard, int length)
|
const guint8 *iei,
|
||||||
|
gboolean *discard, int length)
|
||||||
{
|
{
|
||||||
int profile, n;
|
int profile, n;
|
||||||
gboolean set;
|
gboolean set;
|
||||||
|
@ -691,7 +564,7 @@ static void handle_enhanced_voicemail_iei(struct ofono_modem *modem,
|
||||||
/* Other parameters currently not supported */
|
/* Other parameters currently not supported */
|
||||||
|
|
||||||
set = iei[n + 2] > 0 ? TRUE : FALSE;
|
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]);
|
set, iei[n + 2]);
|
||||||
} else {
|
} else {
|
||||||
/* 9.2.3.24.13.2 Enhanced Voice Delete Confirmation */
|
/* 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 */
|
/* Other parameters currently not supported */
|
||||||
|
|
||||||
set = iei[n + 2] > 0 ? TRUE : FALSE;
|
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]);
|
set, iei[n + 2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mailbox_address.address[0] != '\0')
|
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);
|
sms_address_to_string(&mailbox_address), NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
struct sms *sms, gboolean *out_discard)
|
||||||
{
|
{
|
||||||
gboolean active, discard;
|
gboolean active, discard;
|
||||||
enum sms_mwi_type type;
|
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:
|
case SMS_IEI_ENHANCED_VOICE_MAIL_INFORMATION:
|
||||||
sms_udh_iter_get_ie_data(&iter, evm_iei);
|
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,
|
out_discard,
|
||||||
sms_udh_iter_get_ie_length(
|
sms_udh_iter_get_ie_length(
|
||||||
&iter));
|
&iter));
|
||||||
|
@ -778,7 +651,7 @@ void ofono_handle_sms_mwi(struct ofono_modem *modem,
|
||||||
break;
|
break;
|
||||||
sms_udh_iter_get_ie_data(&iter, special_iei);
|
sms_udh_iter_get_ie_data(&iter, special_iei);
|
||||||
|
|
||||||
handle_special_sms_iei(modem, special_iei,
|
handle_special_sms_iei(mw, special_iei,
|
||||||
&discard);
|
&discard);
|
||||||
if (out_discard)
|
if (out_discard)
|
||||||
*out_discard = *out_discard || 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,
|
if (sms_mwi_dcs_decode(sms->deliver.dcs, &type,
|
||||||
NULL, &active, out_discard)) {
|
NULL, &active, out_discard)) {
|
||||||
mw_set_indicator(modem, profile, type, active, 0);
|
mw_set_indicator(mw, profile, type, active, 0);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -818,3 +691,119 @@ void ofono_handle_sms_mwi(struct ofono_modem *modem,
|
||||||
if (sms->deliver.pid == SMS_PID_TYPE_RETURN_CALL)
|
if (sms->deliver.pid == SMS_PID_TYPE_RETURN_CALL)
|
||||||
return;
|
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_VOICECALL = 10,
|
||||||
OFONO_ATOM_TYPE_HISTORY = 11,
|
OFONO_ATOM_TYPE_HISTORY = 11,
|
||||||
OFONO_ATOM_TYPE_SSN = 12,
|
OFONO_ATOM_TYPE_SSN = 12,
|
||||||
|
OFONO_ATOM_TYPE_MESSAGE_WAITING = 13,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ofono_atom_watch_condition {
|
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,
|
void __ofono_history_call_missed(struct ofono_modem *modem,
|
||||||
const struct ofono_call *call, time_t when);
|
const struct ofono_call *call, time_t when);
|
||||||
|
|
||||||
|
#include <ofono/message-waiting.h>
|
||||||
|
|
||||||
struct sms;
|
struct sms;
|
||||||
|
|
||||||
int ofono_message_waiting_register(struct ofono_modem *modem);
|
void __ofono_message_waiting_mwi(struct ofono_message_waiting *mw,
|
||||||
void ofono_message_waiting_unregister(struct ofono_modem *modem);
|
|
||||||
void ofono_handle_sms_mwi(struct ofono_modem *modem,
|
|
||||||
struct sms *sms, gboolean *out_discard);
|
struct sms *sms, gboolean *out_discard);
|
||||||
|
|
57
src/sms.c
57
src/sms.c
|
@ -55,6 +55,8 @@ struct ofono_sms {
|
||||||
GQueue *txq;
|
GQueue *txq;
|
||||||
time_t last_mms;
|
time_t last_mms;
|
||||||
gint tx_source;
|
gint tx_source;
|
||||||
|
struct ofono_message_waiting *mw;
|
||||||
|
unsigned int mw_watch;
|
||||||
const struct ofono_sms_driver *driver;
|
const struct ofono_sms_driver *driver;
|
||||||
void *driver_data;
|
void *driver_data;
|
||||||
struct ofono_atom *atom;
|
struct ofono_atom *atom;
|
||||||
|
@ -616,13 +618,24 @@ static void handle_deliver(struct ofono_sms *sms, const struct sms *incoming)
|
||||||
g_slist_free(l);
|
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,
|
void ofono_sms_deliver_notify(struct ofono_sms *sms, unsigned char *pdu,
|
||||||
int len, int tpdu_len)
|
int len, int tpdu_len)
|
||||||
{
|
{
|
||||||
struct ofono_modem *modem = __ofono_atom_get_modem(sms->atom);
|
struct ofono_modem *modem = __ofono_atom_get_modem(sms->atom);
|
||||||
struct sms s;
|
struct sms s;
|
||||||
enum sms_class cls;
|
enum sms_class cls;
|
||||||
gboolean discard;
|
|
||||||
|
|
||||||
if (!sms_decode(pdu, len, FALSE, tpdu_len, &s)) {
|
if (!sms_decode(pdu, len, FALSE, tpdu_len, &s)) {
|
||||||
ofono_error("Unable to decode PDU");
|
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
|
/* This is an older style MWI notification, process MWI
|
||||||
* headers and handle it like any other message */
|
* headers and handle it like any other message */
|
||||||
if (s.deliver.pid == SMS_PID_TYPE_RETURN_CALL) {
|
if (s.deliver.pid == SMS_PID_TYPE_RETURN_CALL) {
|
||||||
ofono_handle_sms_mwi(modem, &s, &discard);
|
if (handle_mwi(sms, &s))
|
||||||
|
|
||||||
if (discard)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
goto out;
|
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
|
/* The DCS indicates this is an MWI notification, process it
|
||||||
* and then handle the User-Data as any other message */
|
* and then handle the User-Data as any other message */
|
||||||
if (sms_mwi_dcs_decode(s.deliver.dcs, NULL, NULL, NULL, NULL)) {
|
if (sms_mwi_dcs_decode(s.deliver.dcs, NULL, NULL, NULL, NULL)) {
|
||||||
ofono_handle_sms_mwi(modem, &s, &discard);
|
if (handle_mwi(sms, &s))
|
||||||
|
|
||||||
if (discard)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
goto out;
|
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
|
/* TODO: ignore if not in the very first
|
||||||
* segment of a concatenated SM so as not
|
* segment of a concatenated SM so as not
|
||||||
* to repeat the indication. */
|
* to repeat the indication. */
|
||||||
ofono_handle_sms_mwi(modem, &s, &discard);
|
if (handle_mwi(sms, &s))
|
||||||
|
|
||||||
if (discard)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -774,7 +781,11 @@ static void sms_unregister(struct ofono_atom *atom)
|
||||||
|
|
||||||
g_dbus_unregister_interface(conn, path, SMS_MANAGER_INTERFACE);
|
g_dbus_unregister_interface(conn, path, SMS_MANAGER_INTERFACE);
|
||||||
ofono_modem_remove_interface(modem, 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)
|
static void sms_remove(struct ofono_atom *atom)
|
||||||
|
@ -847,11 +858,25 @@ struct ofono_sms *ofono_sms_create(struct ofono_modem *modem,
|
||||||
return sms;
|
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)
|
void ofono_sms_register(struct ofono_sms *sms)
|
||||||
{
|
{
|
||||||
DBusConnection *conn = ofono_dbus_get_connection();
|
DBusConnection *conn = ofono_dbus_get_connection();
|
||||||
struct ofono_modem *modem = __ofono_atom_get_modem(sms->atom);
|
struct ofono_modem *modem = __ofono_atom_get_modem(sms->atom);
|
||||||
const char *path = __ofono_atom_get_path(sms->atom);
|
const char *path = __ofono_atom_get_path(sms->atom);
|
||||||
|
struct ofono_atom *mw_atom;
|
||||||
|
|
||||||
if (!g_dbus_register_interface(conn, path,
|
if (!g_dbus_register_interface(conn, path,
|
||||||
SMS_MANAGER_INTERFACE,
|
SMS_MANAGER_INTERFACE,
|
||||||
|
@ -865,7 +890,15 @@ void ofono_sms_register(struct ofono_sms *sms)
|
||||||
|
|
||||||
ofono_modem_add_interface(modem, SMS_MANAGER_INTERFACE);
|
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);
|
__ofono_atom_register(sms->atom, sms_unregister);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue