Add a MessageWaiting interface to track message waiting indications.

The state of the indications is kept in memory and written back to
the SIM after any changes.
This commit is contained in:
Andrzej Zaborowski 2009-08-03 14:50:14 +02:00 committed by Denis Kenzior
parent ba8ef5c3e4
commit 203ed17cec
7 changed files with 822 additions and 10 deletions

View File

@ -13,7 +13,8 @@ ofonod_SOURCES = main.c ofono.h log.c plugin.c \
network.c voicecall.c ussd.h ussd.c sms.c \
call-settings.c call-forwarding.c call-meter.c \
smsutil.h smsutil.c cssn.h cssn.c call-barring.c sim.h sim.c \
phonebook.c history.c simutil.h simutil.c
phonebook.c history.c simutil.h simutil.c \
message-waiting.c message-waiting.h
ofonod_LDADD = $(top_builddir)/plugins/libbuiltin.la \
$(top_builddir)/drivers/libbuiltin.la \

761
src/message-waiting.c Normal file
View File

@ -0,0 +1,761 @@
/*
*
* 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
*
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <string.h>
#include <stdio.h>
#include <dbus/dbus.h>
#include <glib.h>
#include <gdbus.h>
#include <sys/stat.h>
#include <sys/types.h>
#include "ofono.h"
#include "driver.h"
#include "common.h"
#include "util.h"
#include "sim.h"
#include "simutil.h"
#include "smsutil.h"
#include "message-waiting.h"
#define MESSAGE_WAITING_INTERFACE "org.ofono.MessageWaiting"
struct mailbox_state {
gboolean indication;
int message_count;
};
struct message_waiting_data {
struct mailbox_state messages[5];
int efmwis_length;
int efmbdn_length;
int efmbdn_record_id[5];
struct ofono_phone_number mailbox_number[5];
int pending;
struct mailbox_state messages_new[5];
struct ofono_phone_number mailbox_number_new[5];
};
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;
g_free(data);
modem->message_waiting = NULL;
}
static const char *mw_message_waiting_property_name[5] = {
"VoicemailWaiting",
#if 0
"FaxWaiting",
"EmailWaiting",
"OtherWaiting",
"VideomailWaiting",
#endif
};
static const char *mw_message_count_property_name[5] = {
"VoicemailMessageCount",
#if 0
"FaxMessageCount",
"EmailMessageCount",
"OtherMessageCount",
"VideomailMessageCount",
#endif
};
static const char *mw_mailbox_property_name[5] = {
"VoicemailMailboxNumber",
#if 0
"FaxMailboxNumber",
"EmailMailboxNumber",
"OtherMailboxNumber",
"VideomailMailboxNumber",
#endif
};
static DBusMessage *mw_get_properties(DBusConnection *conn,
DBusMessage *msg, void *data)
{
struct ofono_modem *modem = data;
struct message_waiting_data *mw = modem->message_waiting;
DBusMessage *reply;
DBusMessageIter iter;
DBusMessageIter dict;
int i;
dbus_bool_t indication;
unsigned char count;
const char *number;
reply = dbus_message_new_method_return(msg);
if (!reply)
return NULL;
dbus_message_iter_init_append(reply, &iter);
dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
OFONO_PROPERTIES_ARRAY_SIGNATURE, &dict);
for (i = 0; i < 5; i++) {
if (mw_message_waiting_property_name[i]) {
indication = mw->messages[i].indication;
ofono_dbus_dict_append(&dict,
mw_message_waiting_property_name[i],
DBUS_TYPE_BOOLEAN, &indication);
}
if (mw_message_count_property_name[i]) {
count = mw->messages[i].message_count;
ofono_dbus_dict_append(&dict,
mw_message_count_property_name[i],
DBUS_TYPE_BYTE, &count);
}
if (mw_mailbox_property_name[i]) {
number = phone_number_to_string(&mw->mailbox_number[i]);
ofono_dbus_dict_append(&dict,
mw_mailbox_property_name[i],
DBUS_TYPE_STRING, &number);
}
}
dbus_message_iter_close_container(&iter, &dict);
return reply;
}
static gboolean mw_update(gpointer user);
static DBusMessage *mw_set_property(DBusConnection *conn, DBusMessage *msg,
void *data)
{
struct ofono_modem *modem = data;
struct message_waiting_data *mw = modem->message_waiting;
DBusMessageIter iter;
DBusMessageIter var;
const char *name, *value;
int i;
struct ofono_phone_number new_number;
if (mw->efmbdn_length == 0)
return __ofono_error_busy(msg);
if (!dbus_message_iter_init(msg, &iter))
return __ofono_error_invalid_args(msg);
if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
return __ofono_error_invalid_args(msg);
dbus_message_iter_get_basic(&iter, &name);
for (i = 0; i < 5; i++)
if (mw_mailbox_property_name[i] &&
!strcmp(name, mw_mailbox_property_name[i]))
break;
if (i == 5)
return __ofono_error_invalid_args(msg);
dbus_message_iter_next(&iter);
if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT)
return __ofono_error_invalid_args(msg);
dbus_message_iter_recurse(&iter, &var);
if (dbus_message_iter_get_arg_type(&var) != DBUS_TYPE_STRING)
return __ofono_error_invalid_format(msg);
dbus_message_iter_get_basic(&var, &value);
if (!valid_phone_number_format(value))
return __ofono_error_invalid_format(msg);
string_to_phone_number(value, &new_number);
if (strcmp(mw->mailbox_number_new[i].number, new_number.number) ||
mw->mailbox_number_new[i].type != new_number.type) {
memcpy(&mw->mailbox_number_new[i], &new_number,
sizeof(struct ofono_phone_number));
if (!mw->pending)
mw->pending = g_timeout_add(0, mw_update, modem);
}
return dbus_message_new_method_return(msg);
}
static GDBusMethodTable message_waiting_methods[] = {
{ "GetProperties", "", "a{sv}", mw_get_properties },
{ "SetProperty", "sv", "", mw_set_property, },
{ }
};
static GDBusSignalTable message_waiting_signals[] = {
{ "PropertyChanged", "sv" },
{ }
};
static void mw_mwis_read_cb(struct ofono_modem *modem, int ok,
enum ofono_sim_file_structure structure, int total_length,
int record, const unsigned char *data, int record_length,
void *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;
if (!ok ||
structure != OFONO_SIM_FILE_STRUCTURE_FIXED ||
record_length < 5) {
ofono_error("Unable to read waiting messages numbers "
"from SIM");
mw->efmwis_length = -1;
return;
}
/* Handle only current identity (TODO: currently assumes first) */
if (record != 1)
return;
status = data[0];
data++;
for (i = 0; i < 5 && i < record_length - 1; i++) {
info.indication = (status >> i) & 1;
info.message_count = info.indication ? data[0] : 0;
if (mw->messages[i].indication != info.indication ||
mw->messages[i].message_count !=
info.message_count) {
memcpy(&mw->messages[i], &info, sizeof(info));
memcpy(&mw->messages_new[i], &info, sizeof(info));
if (!mw_message_waiting_property_name[i])
continue;
indication = info.indication;
count = info.message_count;
ofono_dbus_signal_property_changed(conn, modem->path,
MESSAGE_WAITING_INTERFACE,
mw_message_waiting_property_name[i],
DBUS_TYPE_BOOLEAN, &indication);
ofono_dbus_signal_property_changed(conn, modem->path,
MESSAGE_WAITING_INTERFACE,
mw_message_count_property_name[i],
DBUS_TYPE_BYTE, &count);
}
}
mw->efmwis_length = record_length;
}
static void mw_mbdn_read_cb(struct ofono_modem *modem, int ok,
enum ofono_sim_file_structure structure, int total_length,
int record, const unsigned char *data, int record_length,
void *userdata)
{
int i;
DBusConnection *conn = ofono_dbus_get_connection();
struct message_waiting_data *mw = modem->message_waiting;
const char *value;
if (!ok ||
structure != OFONO_SIM_FILE_STRUCTURE_FIXED ||
record_length < 14 || total_length < record_length) {
ofono_error("Unable to read mailbox dialling numbers "
"from SIM");
mw->efmbdn_length = -1;
return;
}
for (i = 0; i < 5; i++)
if (record == mw->efmbdn_record_id[i])
break;
if (i == 5)
return;
if (sim_adn_parse(data, record_length, &mw->mailbox_number[i]) ==
FALSE) {
mw->mailbox_number[i].number[0] = '\0';
mw->mailbox_number_new[i].number[0] = '\0';
} else {
memcpy(&mw->mailbox_number_new[i], &mw->mailbox_number[i],
sizeof(struct ofono_phone_number));
}
if (mw_mailbox_property_name[i]) {
value = phone_number_to_string(&mw->mailbox_number[i]);
ofono_dbus_signal_property_changed(conn, modem->path,
MESSAGE_WAITING_INTERFACE,
mw_mailbox_property_name[i],
DBUS_TYPE_STRING, &value);
}
mw->efmbdn_length = record_length;
}
static void mw_mbi_read_cb(struct ofono_modem *modem, int ok,
enum ofono_sim_file_structure structure, int total_length,
int record, const unsigned char *data, int record_length,
void *userdata)
{
int i, err;
struct message_waiting_data *mw = modem->message_waiting;
if (!ok ||
structure != OFONO_SIM_FILE_STRUCTURE_FIXED ||
record_length < 4) {
ofono_error("Unable to read mailbox identifies "
"from SIM");
mw->efmbdn_length = -1;
return;
}
/* Handle only current identity (TODO: currently assumes first) */
if (record != 1)
return;
for (i = 0; i < 5 && i < record_length; i++)
mw->efmbdn_record_id[i] = data[i];
err = ofono_sim_read(modem, SIM_EFMBDN_FILEID, mw_mbdn_read_cb, NULL);
if (err != 0) {
ofono_error("Unable to read EF-MBDN from SIM");
}
}
static void mw_mbdn_write_cb(struct ofono_modem *modem, int ok, void *userdata)
{
if (!ok)
ofono_error("Writing new EF-MBDN failed");
}
/* Loads MWI states and MBDN from SIM */
static gboolean mw_mwis_load(struct ofono_modem *modem)
{
int err;
err = ofono_sim_read(modem, SIM_EFMWIS_FILEID, mw_mwis_read_cb, NULL);
if (err != 0)
return FALSE;
err = ofono_sim_read(modem, SIM_EFMBI_FILEID, mw_mbi_read_cb, NULL);
if (err != 0)
return FALSE;
return TRUE;
}
/* Writes MWI states and/or MBDN back to SIM */
static gboolean mw_update(gpointer user)
{
struct ofono_modem *modem = user;
struct message_waiting_data *mw = modem->message_waiting;
DBusConnection *conn = ofono_dbus_get_connection();
dbus_bool_t indication;
unsigned char count;
const char *number;
int i;
unsigned char *file;
mw->pending = 0;
for (i = 0; i < 5; i++) {
if (mw->messages_new[i].message_count !=
mw->messages[i].message_count) {
mw->messages[i].message_count =
mw->messages_new[i].message_count;
if (!mw_message_count_property_name[i])
continue;
count = mw->messages[i].message_count;
ofono_dbus_signal_property_changed(conn, modem->path,
MESSAGE_WAITING_INTERFACE,
mw_message_count_property_name[i],
DBUS_TYPE_BYTE, &count);
}
if (mw->messages_new[i].indication !=
mw->messages[i].indication) {
mw->messages[i].indication =
mw->messages_new[i].indication;
if (!mw_message_waiting_property_name[i])
continue;
indication = mw->messages[i].indication;
ofono_dbus_signal_property_changed(conn, modem->path,
MESSAGE_WAITING_INTERFACE,
mw_message_waiting_property_name[i],
DBUS_TYPE_BOOLEAN, &indication);
}
}
if (mw->efmwis_length < 1)
goto mbdn;
file = g_malloc0(mw->efmwis_length);
/* Fill in numbers of messages in bytes 1 to X of EF-MWIS */
for (i = 0; i < 5 && i < mw->efmwis_length - 1; i++)
file[i + 1] = mw->messages[i].message_count;
/* Fill in indicator state bits in byte 0 */
for (i = 0; i < 5 && i < mw->efmwis_length - 1; i++)
if (mw->messages[i].indication)
file[0] |= 1 << i;
if (ofono_sim_write(modem, SIM_EFMWIS_FILEID, mw_mbdn_write_cb,
OFONO_SIM_FILE_STRUCTURE_FIXED, 1,
file, mw->efmwis_length, NULL) != 0) {
ofono_error("Queuing a EF-MWI write to SIM failed");
}
g_free(file);
mbdn:
for (i = 0; i < 5; i++)
if (strcmp(mw->mailbox_number_new[i].number,
mw->mailbox_number[i].number) ||
mw->mailbox_number_new[i].type !=
mw->mailbox_number[i].type) {
memcpy(&mw->mailbox_number[i],
&mw->mailbox_number_new[i],
sizeof(struct ofono_phone_number));
if (!mw_mailbox_property_name[i])
continue;
number = phone_number_to_string(
&mw->mailbox_number[i]);
ofono_dbus_signal_property_changed(conn, modem->path,
MESSAGE_WAITING_INTERFACE,
mw_mailbox_property_name[i],
DBUS_TYPE_STRING, &number);
}
if (mw->efmbdn_length < 1)
return FALSE;
return FALSE;
}
void ofono_message_waiting_present_notify(struct ofono_modem *modem,
enum sms_mwi_type type, gboolean present, int profile)
{
struct message_waiting_data *mw = modem->message_waiting;
if (mw == NULL)
return;
/* Handle only current identity (TODO: currently assumes first) */
if (profile != 1)
return;
present = !!present;
if (mw->messages_new[type].indication != present) {
mw->messages_new[type].indication = present;
if (!present)
mw->messages_new[type].message_count = 0;
if (!mw->pending)
mw->pending = g_timeout_add(0, mw_update, modem);
}
}
void ofono_message_waiting_count_notify(struct ofono_modem *modem,
enum sms_mwi_type type, int count, int profile)
{
struct message_waiting_data *mw = modem->message_waiting;
if (mw == NULL)
return;
/* Handle only current identity (TODO: currently assumes first) */
if (profile != 1)
return;
if (mw->messages_new[type].message_count != count ||
mw->messages_new[type].indication != (count > 0)) {
mw->messages_new[type].message_count = count;
mw->messages_new[type].indication = (count > 0);
if (!mw->pending)
mw->pending = g_timeout_add(0, mw_update, modem);
}
}
static void initialize_message_waiting(struct ofono_modem *modem)
{
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);
}
int ofono_message_waiting_register(struct ofono_modem *modem)
{
if (modem == NULL)
return -1;
modem->message_waiting = message_waiting_create();
ofono_sim_ready_notify_register(modem, initialize_message_waiting);
if (ofono_sim_get_ready(modem))
initialize_message_waiting(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;
int profile;
/* Parse type & storage byte */
if (discard)
*discard = (iei[0] & (1 << 7)) ? FALSE : TRUE;
type = iei[0] & 0x1f;
if (type > SMS_MWI_TYPE_OTHER) {
if (type == (SMS_MWI_TYPE_OTHER | 4))
type = SMS_MWI_TYPE_VIDEO;
else
/* 23.040 9.2.3.24.2: "Terminals should be capable of
* receiving any values in octet 1, even including
* those marked as Reserved." Treat Reserved as
* "Other". */
type = SMS_MWI_TYPE_OTHER;
}
profile = ((iei[0] >> 5) & 3) + 1;
ofono_message_waiting_count_notify(modem, iei[1], type, profile);
}
static void handle_enhanced_voicemail_iei(struct ofono_modem *modem,
const guint8 *iei, gboolean *discard, int length)
{
int profile, n;
if (length < 3)
return;
/* ENHANCED_VOICE_MAIL_PDU_TYPE */
if (!(iei[0] & 1)) {
/* 9.2.3.24.13.1 Enhanced Voice Mail Notification */
/* MULTIPLE_SUBSCRIBER_PROFILE */
profile = (iei[0] >> 2) & 3;
/* SM_STORAGE */
if (discard)
*discard = (iei[0] & (1 << 4)) ? FALSE : TRUE;
/* TODO: VM_MAILBOX_ACCESS_ADDRESS */
n = 2 + (iei[1] + 1) / 2;
if (length < n + 11)
return;
/* TODO: VM_MESSAGE_PRIORITY_INDICATION */
/* Other parameters currently not supported */
ofono_message_waiting_count_notify(modem, iei[2 + n],
SMS_MWI_TYPE_VOICE, profile);
} else {
/* 9.2.3.24.13.2 Enhanced Voice Delete Confirmation */
/* MULTIPLE_SUBSCRIBER_PROFILE */
profile = (iei[0] >> 2) & 3;
/* SM_STORAGE */
if (discard)
*discard = (iei[0] & (1 << 4)) ? FALSE : TRUE;
/* TODO: VM_MAILBOX_ACCESS_ADDRESS */
n = 2 + (iei[1] + 1) / 2;
if (length < n + 11)
return;
/* Other parameters currently not supported */
ofono_message_waiting_count_notify(modem, iei[2 + n],
SMS_MWI_TYPE_VOICE, profile);
}
}
void ofono_handle_sms_mwi(struct ofono_modem *modem,
struct sms *sms, gboolean *out_discard)
{
gboolean active, discard;
enum sms_mwi_type type;
int profile = 1, iei_found = 0;
if (out_discard)
*out_discard = FALSE;
/* Check MWI types in the order from highest priority to lowest
* because they must override one another.
*/
if (sms->deliver.udhi) {
guint8 *evm_iei;
struct sms_udh_iter iter;
enum sms_iei iei;
if (!sms_udh_iter_init(sms, &iter))
return;
while ((iei = sms_udh_iter_get_ie_type(&iter)) !=
SMS_IEI_INVALID) {
switch (iei) {
case SMS_IEI_ENHANCED_VOICE_MAIL_INFORMATION:
evm_iei = g_malloc0(
sms_udh_iter_get_ie_length(
&iter));
sms_udh_iter_get_ie_data(&iter, evm_iei);
handle_enhanced_voicemail_iei(modem, evm_iei,
out_discard,
sms_udh_iter_get_ie_length(
&iter));
g_free(evm_iei);
return;
}
sms_udh_iter_next(&iter);
}
}
if (sms->deliver.udhi) {
guint8 special_iei[4];
struct sms_udh_iter iter;
enum sms_iei iei;
if (!sms_udh_iter_init(sms, &iter))
return;
while ((iei = sms_udh_iter_get_ie_type(&iter)) !=
SMS_IEI_INVALID) {
switch (iei) {
case SMS_IEI_SPECIAL_MESSAGE_INDICATION:
if (sms_udh_iter_get_ie_length(&iter) != 2)
break;
sms_udh_iter_get_ie_data(&iter, special_iei);
handle_special_sms_iei(modem, special_iei,
&discard);
if (out_discard)
*out_discard = *out_discard || discard;
iei_found = 1;
}
sms_udh_iter_next(&iter);
}
if (iei_found) {
/* 23.040 9.2.3.24.2 says "In the event of a
* conflict between this setting and the setting
* of the Data Coding Scheme (see 3GPP TS 23.038 [9])
* then the message shall be stored if either the DCS
* indicates this, or Octet 1 above indicates this."
*/
if (sms_mwi_dcs_decode(sms->deliver.dcs, NULL,
NULL, NULL, &discard)) {
if (out_discard)
*out_discard = *out_discard || discard;
}
return;
}
}
if (sms_mwi_dcs_decode(sms->deliver.dcs, &type,
NULL, &active, out_discard)) {
ofono_message_waiting_present_notify(modem,
type, active, profile);
return;
}
if (sms->deliver.pid == SMS_PID_TYPE_RETURN_CALL)
return;
}

30
src/message-waiting.h Normal file
View File

@ -0,0 +1,30 @@
/*
*
* 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
*
*/
void ofono_message_waiting_present_notify(struct ofono_modem *modem,
enum sms_mwi_type type,
gboolean present, int profile);
void ofono_message_waiting_count_notify(struct ofono_modem *modem,
enum sms_mwi_type type, int count,
int profile);
void ofono_handle_sms_mwi(struct ofono_modem *modem,
struct sms *sms, gboolean *out_discard);

View File

@ -79,6 +79,7 @@ struct ofono_modem {
struct sim_manager_data *sim_manager;
struct sms_manager_data *sms_manager;
struct phonebook_data *phonebook;
struct message_waiting_data *message_waiting;
GSList *history_contexts;
};
@ -99,3 +100,6 @@ 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);
int ofono_message_waiting_register(struct ofono_modem *modem);
void ofono_message_waiting_unregister(struct ofono_modem *modem);

View File

@ -24,6 +24,9 @@ enum sim_fileid {
SIM_EFSPN_FILEID = 0x6f46,
SIM_EFPNN_FILEID = 0x6fc5,
SIM_EFOPL_FILEID = 0x6fc6,
SIM_EFMBDN_FILEID = 0x6fc7,
SIM_EFMBI_FILEID = 0x6fc9,
SIM_EFMWIS_FILEID = 0x6fca,
SIM_EFSPDI_FILEID = 0x6fcd,
};

View File

@ -36,6 +36,7 @@
#include "util.h"
#include "sim.h"
#include "smsutil.h"
#include "message-waiting.h"
#define uninitialized_var(x) x = x
@ -655,11 +656,6 @@ static void handle_deliver(struct ofono_modem *modem,
g_slist_free(l);
}
static void handle_mwi(struct ofono_modem *modem, struct sms *mwi)
{
ofono_error("MWI information not yet handled");
}
void ofono_sms_deliver_notify(struct ofono_modem *modem, unsigned char *pdu,
int len, int tpdu_len)
{
@ -685,14 +681,18 @@ void ofono_sms_deliver_notify(struct ofono_modem *modem, unsigned char *pdu,
/* This is an older style MWI notification, process MWI
* headers and handle it like any other message */
if (sms.deliver.pid == SMS_PID_TYPE_RETURN_CALL) {
handle_mwi(modem, &sms);
ofono_handle_sms_mwi(modem, &sms, &discard);
if (discard)
return;
goto out;
}
/* 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(sms.deliver.dcs, NULL, NULL, NULL, &discard)) {
handle_mwi(modem, &sms);
if (sms_mwi_dcs_decode(sms.deliver.dcs, NULL, NULL, NULL, NULL)) {
ofono_handle_sms_mwi(modem, &sms, &discard);
if (discard)
return;
@ -757,7 +757,14 @@ void ofono_sms_deliver_notify(struct ofono_modem *modem, unsigned char *pdu,
switch (iei) {
case SMS_IEI_SPECIAL_MESSAGE_INDICATION:
case SMS_IEI_ENHANCED_VOICE_MAIL_INFORMATION:
handle_mwi(modem, &sms);
/* 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, &sms, &discard);
if (discard)
return;
goto out;
case SMS_IEI_WCMP:
ofono_error("No support for WCMP, ignoring");
@ -789,6 +796,9 @@ int ofono_sms_manager_register(struct ofono_modem *modem,
if (ops == NULL)
return -1;
if (ofono_message_waiting_register(modem))
return -1;
modem->sms_manager = sms_manager_create();
if (!modem->sms_manager)
@ -824,4 +834,6 @@ void ofono_sms_manager_unregister(struct ofono_modem *modem)
SMS_MANAGER_INTERFACE);
ofono_modem_remove_interface(modem, SMS_MANAGER_INTERFACE);
ofono_message_waiting_unregister(modem);
}

View File

@ -158,6 +158,7 @@ enum sms_mwi_type {
SMS_MWI_TYPE_FAX = 1,
SMS_MWI_TYPE_EMAIL = 2,
SMS_MWI_TYPE_OTHER = 3,
SMS_MWI_TYPE_VIDEO = 4,
};
enum sms_pid_type {