Refactor how mwis updates are done

This commit is contained in:
Denis Kenzior 2009-08-04 14:56:03 -05:00
parent c7d29c44a8
commit e117f3112a
1 changed files with 51 additions and 107 deletions

View File

@ -47,19 +47,15 @@ static gboolean mw_update(gpointer user);
struct mailbox_state { struct mailbox_state {
gboolean indication; gboolean indication;
int message_count; unsigned char message_count;
}; };
struct message_waiting_data { struct message_waiting_data {
struct mailbox_state messages[5]; struct mailbox_state messages[5];
int efmwis_length; unsigned char efmwis_length;
int efmbdn_length; unsigned char efmbdn_length;
int efmbdn_record_id[5]; unsigned char efmbdn_record_id[5];
struct ofono_phone_number mailbox_number[5]; struct ofono_phone_number mailbox_number[5];
int pending;
struct mailbox_state messages_new[5];
}; };
struct mbdn_set_request { struct mbdn_set_request {
@ -315,7 +311,7 @@ static void mw_mwis_read_cb(struct ofono_modem *modem, int ok,
ofono_error("Unable to read waiting messages numbers " ofono_error("Unable to read waiting messages numbers "
"from SIM"); "from SIM");
mw->efmwis_length = -1; mw->efmwis_length = 0;
return; return;
} }
@ -335,7 +331,6 @@ static void mw_mwis_read_cb(struct ofono_modem *modem, int ok,
mw->messages[i].message_count != mw->messages[i].message_count !=
info.message_count) { info.message_count) {
memcpy(&mw->messages[i], &info, sizeof(info)); memcpy(&mw->messages[i], &info, sizeof(info));
memcpy(&mw->messages_new[i], &info, sizeof(info));
if (!mw_message_waiting_property_name[i]) if (!mw_message_waiting_property_name[i])
continue; continue;
@ -455,122 +450,67 @@ static gboolean mw_mwis_load(struct ofono_modem *modem)
return TRUE; return TRUE;
} }
/* Writes MWI states and/or MBDN back to SIM */ static void mw_set_indicator(struct ofono_modem *modem, int profile,
static gboolean mw_update(gpointer user) enum sms_mwi_type type,
gboolean present, unsigned char messages)
{ {
struct ofono_modem *modem = user;
struct message_waiting_data *mw = modem->message_waiting; struct message_waiting_data *mw = modem->message_waiting;
DBusConnection *conn = ofono_dbus_get_connection(); DBusConnection *conn = ofono_dbus_get_connection();
dbus_bool_t indication; unsigned char efmwis[255]; /* Max record size */
unsigned char count;
const char *number;
int i; int i;
unsigned char *file;
mw->pending = 0; if (mw == NULL)
return;
for (i = 0; i < 5; i++) { /* Handle only current identity (TODO: currently assumes first) */
if (mw->messages_new[i].message_count != if (profile != 1)
mw->messages[i].message_count) { return;
mw->messages[i].message_count =
mw->messages_new[i].message_count;
if (!mw_message_count_property_name[i]) if (mw->messages[type].indication == present &&
continue; mw->messages[type].message_count == messages)
return;
count = mw->messages[i].message_count; if (mw->messages[type].indication != present) {
dbus_bool_t indication;
ofono_dbus_signal_property_changed(conn, modem->path, indication = present;
mw->messages[type].indication = present;
ofono_dbus_signal_property_changed(conn, modem->path,
MESSAGE_WAITING_INTERFACE, MESSAGE_WAITING_INTERFACE,
mw_message_count_property_name[i], mw_message_waiting_property_name[type],
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); DBUS_TYPE_BOOLEAN, &indication);
}
} }
if (mw->efmwis_length < 1) if (mw->messages[type].message_count != messages) {
return FALSE; mw->messages[type].message_count = messages;
file = g_malloc0(mw->efmwis_length); ofono_dbus_signal_property_changed(conn, modem->path,
MESSAGE_WAITING_INTERFACE,
mw_message_count_property_name[type],
DBUS_TYPE_BYTE, &messages);
}
/* Writes MWI states and/or MBDN back to SIM */
if ((mw->efmwis_length < 5)) {
ofono_error("Unable to update MWIS indicator");
return;
}
/* Fill in numbers of messages in bytes 1 to X of EF-MWIS */ /* Fill in numbers of messages in bytes 1 to X of EF-MWIS */
for (i = 0; i < 5 && i < mw->efmwis_length - 1; i++) for (i = 0; i < 5 && i < mw->efmwis_length - 1; i++)
file[i + 1] = mw->messages[i].message_count; efmwis[i + 1] = mw->messages[i].message_count;
/* Fill in indicator state bits in byte 0 */ /* Fill in indicator state bits in byte 0 */
for (i = 0; i < 5 && i < mw->efmwis_length - 1; i++) for (i = 0; i < 5 && i < mw->efmwis_length - 1; i++)
if (mw->messages[i].indication) if (mw->messages[i].indication)
file[0] |= 1 << i; efmwis[0] |= 1 << i;
if (ofono_sim_write(modem, SIM_EFMWIS_FILEID, mw_mwis_write_cb, if (ofono_sim_write(modem, SIM_EFMWIS_FILEID, mw_mwis_write_cb,
OFONO_SIM_FILE_STRUCTURE_FIXED, 1, OFONO_SIM_FILE_STRUCTURE_FIXED, 1,
file, mw->efmwis_length, NULL) != 0) { efmwis, mw->efmwis_length, NULL) != 0) {
ofono_error("Queuing a EF-MWI write to SIM failed"); ofono_error("Queuing a EF-MWI write to SIM failed");
} }
g_free(file);
return FALSE;
}
static 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;
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);
}
}
static 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) static void initialize_message_waiting(struct ofono_modem *modem)
@ -630,6 +570,7 @@ static void handle_special_sms_iei(struct ofono_modem *modem,
{ {
enum sms_mwi_type type; enum sms_mwi_type type;
int profile; int profile;
gboolean set;
/* Parse type & storage byte */ /* Parse type & storage byte */
if (discard) if (discard)
@ -647,15 +588,17 @@ static void handle_special_sms_iei(struct ofono_modem *modem,
type = SMS_MWI_TYPE_OTHER; type = SMS_MWI_TYPE_OTHER;
} }
set = iei[1] > 0 ? TRUE : FALSE;
profile = ((iei[0] >> 5) & 3) + 1; profile = ((iei[0] >> 5) & 3) + 1;
ofono_message_waiting_count_notify(modem, iei[1], type, profile); mw_set_indicator(modem, profile, type, set, iei[1]);
} }
static void handle_enhanced_voicemail_iei(struct ofono_modem *modem, static void handle_enhanced_voicemail_iei(struct ofono_modem *modem,
const guint8 *iei, gboolean *discard, int length) const guint8 *iei, gboolean *discard, int length)
{ {
int profile, n; int profile, n;
gboolean set;
if (length < 3) if (length < 3)
return; return;
@ -680,8 +623,9 @@ static void handle_enhanced_voicemail_iei(struct ofono_modem *modem,
/* Other parameters currently not supported */ /* Other parameters currently not supported */
ofono_message_waiting_count_notify(modem, iei[2 + n], set = iei[n + 2] > 0 ? TRUE : FALSE;
SMS_MWI_TYPE_VOICE, profile); mw_set_indicator(modem, profile, SMS_MWI_TYPE_VOICE,
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 */
@ -699,8 +643,9 @@ static void handle_enhanced_voicemail_iei(struct ofono_modem *modem,
/* Other parameters currently not supported */ /* Other parameters currently not supported */
ofono_message_waiting_count_notify(modem, iei[2 + n], set = iei[n + 2] > 0 ? TRUE : FALSE;
SMS_MWI_TYPE_VOICE, profile); mw_set_indicator(modem, profile, SMS_MWI_TYPE_VOICE,
set, iei[n + 2]);
} }
} }
@ -788,8 +733,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)) {
ofono_message_waiting_present_notify(modem, mw_set_indicator(modem, profile, type, active, 0);
type, active, profile);
return; return;
} }