Commit b4b506dc authored by Chris Talbot's avatar Chris Talbot

This commit adds support to automatically check and process SMS WAPs.

This can be useful if you do not have a chat application that manages
MMS or if a higher level chat application does not process SMS WAPs
to send to mmsd.
parent 0646eda8
......@@ -45,15 +45,8 @@ Modem Manager specific notes
===========================
Upon start up, mmsd looks for and tracks the state of the modem
that has Modem Messaging (i.e. SMS) capabilities. Since mmsd is a lower
level program, mmsd assumes that other parts of the OS stack/the
higher level chat application track/manage mobile connectivity and SMS.
This design decision was made as to not conflict with the OS stack and the
chat application.
This decision has two primary consequences to be aware of:
- mmsd does NOT manage mobile connectivity, and does not track the state of
mobile connectivity.
- mmsd also NOT watch the Modem Manager SMS dbus interface for new SMS.
level program, mmsd assumes that other parts of the OS stack manage mobile
connectivity.
Please note that due to limitations of Modem Manager, mmsd does not support
having multiple APNs at the same time (for carriers that seperate MMS APN
......@@ -167,6 +160,14 @@ AutoProcessOnConnection
modem is disconnected and reconnects, suspends and unsuspends, etc.
AutoProcessOnConnection Options: "true" or "false"
AutoProcessSMSWAP
Tell mmsd to automatically check and process SMS WAPs. This can be
useful if you do not have a chat application that manages MMS or if
a higher level chat application does not process SMS WAPs to send to
mmsd.
AutoProcessSMSWAP Options: "true" or "false"
An example of what you are looking for is here:
......
......@@ -95,6 +95,7 @@ struct modem_data {
gboolean manager_available;
gboolean plugin_registered;
gboolean auto_process_on_connection;
gboolean autoprocess_sms_wap;
};
typedef struct {
......@@ -274,9 +275,189 @@ on_name_lost (GDBusConnection *connection,
}
static void
mmsd_mm_init_modem (MMObject *obj)
cb_sms_delete_finish (MMModemMessaging *modemmessaging,
GAsyncResult *result,
MMSms *sms)
{
g_autoptr(GError) error = NULL;
if (mm_modem_messaging_delete_finish (modemmessaging, result, &error)) {
g_debug ("Message delete finish");
} else {
g_debug ("Couldn't delete SMS - error: %s", error ? error->message : "unknown");
}
}
static void
mmsd_process_sms (MMSms *sms)
{
const gchar *message;
const guint8 *data;
const char *path;
gsize data_len;
data_len = 0;
message = mm_sms_get_text (sms);
data = mm_sms_get_data(sms, &data_len);
if (message) {
mms_error ("ModemManagerPlugin(): This is a regular SMS.");
mms_error ("ModemManagerPlugin(): Message: %s", message);
} else if (data) {
mms_error ("ModemManagerPlugin(): Received SMS WAP!");
if (modem->modem_available == TRUE) {
mms_service_push_notify(modem->service, data, data_len);
path = mm_sms_get_path (sms);
if (path) {
mm_modem_messaging_delete (modem->modem_messaging,
path,
NULL,
(GAsyncReadyCallback)cb_sms_delete_finish,
sms);
} else {
mms_error ("ModemManagerPlugin(): mmsd cannot process MMS at this time!");
}
}
} else {
mms_error("ModemManagerPlugin(): Not sure what kind of SMS this is!");
}
}
static void
cb_sms_state_change (MMSms *sms,
GParamSpec *pspec,
gpointer *user_data)
{
MMSmsState state;
state = mm_sms_get_state (sms);
mms_error ("ModemManagerPlugin(): %s: state %s", __func__,
mm_sms_state_get_string (mm_sms_get_state (sms)));
if (state == MM_SMS_STATE_RECEIVED) {
mmsd_process_sms (sms);
}
}
static void
mmsd_check_pdu_type (MMSms *sms)
{
MMSmsState state;
MMSmsPduType pdu_type;
pdu_type = mm_sms_get_pdu_type (sms);
state = mm_sms_get_state (sms);
switch (pdu_type) {
case MM_SMS_PDU_TYPE_CDMA_DELIVER:
case MM_SMS_PDU_TYPE_DELIVER:
if (state == MM_SMS_STATE_RECEIVED) {
mmsd_process_sms (sms);
}
if (state == MM_SMS_STATE_RECEIVING) {
// The first chunk of a multipart SMS has been
// received -> wait for MM_SMS_STATE_RECEIVED
g_signal_connect (sms,
"notify::state",
G_CALLBACK (cb_sms_state_change),
NULL);
}
break;
case MM_SMS_PDU_TYPE_STATUS_REPORT:
case MM_SMS_PDU_TYPE_SUBMIT:
mms_error ("ModemManagerPlugin(): This is not an SMS being recieved, do not care");
break;
case MM_SMS_PDU_TYPE_UNKNOWN:
mms_error ("ModemManagerPlugin(): Unknown PDU type");
break;
default:
mms_error ("ModemManagerPlugin(): PDU type not handled");
}
}
static void
cb_sms_list_new_ready (MMModemMessaging *modemmessaging,
GAsyncResult *result,
gchar *path)
{
GList *l, *list;
g_autoptr(GError) error = NULL;
MMSms *sms;
list = mm_modem_messaging_list_finish (modemmessaging, result, &error);
if (!list) {
mms_error ("ModemManagerPlugin(): Couldn't get SMS list - error: %s",
error ? error->message : "unknown");
} else {
for (l = list; l; l = g_list_next (l)) {
//We are searching for the SMS from the list that is new
if (!g_strcmp0 (mm_sms_get_path (MM_SMS (l->data)), path)) {
sms = g_object_ref (MM_SMS (l->data));
mmsd_check_pdu_type (sms);
break;
}
}
g_list_free_full (list, g_object_unref);
g_free (path);
}
}
static gboolean
cb_dbus_signal_sms_added (MMModemMessaging *device,
gchar *const_path,
gpointer user_data)
{
gchar *path;
path = g_strdup (const_path);
mm_modem_messaging_list (modem->modem_messaging,
NULL,
(GAsyncReadyCallback)cb_sms_list_new_ready,
path);
return TRUE;
}
static void
cb_sms_list_all_ready (MMModemMessaging *modemmessaging,
GAsyncResult *result,
gpointer user_data)
{
GList *l, *list;
g_autoptr(GError) error = NULL;
MMSms *sms;
list = mm_modem_messaging_list_finish (modemmessaging, result, &error);
if (!list) {
g_debug ("Couldn't get SMS list - error: %s", error ? error->message : "unknown");
} else {
for (l = list; l; l = g_list_next (l)) {
sms = g_object_ref (MM_SMS (l->data));
mmsd_check_pdu_type (sms);
}
}
}
static void
mmsd_get_all_sms (void)
{
g_return_if_fail (MM_IS_MODEM_MESSAGING (modem->modem_messaging));
mm_modem_messaging_list (modem->modem_messaging,
NULL,
(GAsyncReadyCallback)cb_sms_list_all_ready,
NULL);
}
static void
mmsd_mm_init_modem (MMObject *obj)
{
MmGdbusModemMessaging *gdbus_sms;
modem->object = obj;
modem->modem = mm_object_get_modem (MM_OBJECT(obj));
modem->path = mm_modem_dup_path (modem->modem);
......@@ -285,7 +466,19 @@ mmsd_mm_init_modem (MMObject *obj)
MMSD_MM_MODEM_TIMEOUT);
modem->modem_messaging = mm_object_get_modem_messaging (MM_OBJECT(obj));
g_return_if_fail (MM_IS_MODEM_MESSAGING (modem->modem_messaging));
g_return_if_fail (MM_IS_MODEM_MESSAGING (modem->modem_messaging));
gdbus_sms = MM_GDBUS_MODEM_MESSAGING(modem->modem_messaging);
if (modem->autoprocess_sms_wap) {
mms_error("ModemManagerPlugin(): Autoprocessing SMS WAPs");
g_signal_connect (gdbus_sms,
"added",
G_CALLBACK (cb_dbus_signal_sms_added),
NULL);
} else {
mms_error("ModemManagerPlugin(): Not autoprocessing SMS WAPs");
}
mms_error("ModemManagerPlugin(): %s", __func__);
}
......@@ -685,6 +878,13 @@ mmsd_mm_state (int state)
mms_error("ModemManagerPlugin(): MMSD_MM_STATE_READY");
modem->modem_available = TRUE;
mmsd_plugin_connect();
if (modem->autoprocess_sms_wap) {
mms_error("ModemManagerPlugin(): Checking for new SMS WAPs");
mmsd_get_all_sms ();
} else {
mms_error("ModemManagerPlugin(): Not checking SMS WAPs");
}
break;
default:
......@@ -956,6 +1156,18 @@ static int modemmanager_init(void)
error = NULL;
}
modem->autoprocess_sms_wap = g_key_file_get_boolean(modem->modemsettings,
SETTINGS_GROUP,
"AutoProcessSMSWAP",
&error);
if (error) {
mms_error("ModemManagerPlugin(): Auto Process SMS WAP was not configured! Setting to FALSE.");
modem->autoprocess_sms_wap = FALSE;
g_key_file_set_boolean(modem->modemsettings, SETTINGS_GROUP,
"AutoProcessSMSWAP", modem->autoprocess_sms_wap);
error = NULL;
}
mms_settings_close(IDENTIFIER, SETTINGS_STORE,
modem->modemsettings, TRUE);
introspection_data = g_dbus_node_info_new_for_xml (introspection_xml, NULL);
......@@ -990,4 +1202,4 @@ static void modemmanager_exit(void)
}
MMS_PLUGIN_DEFINE(modemmanager, modemmanager_init, modemmanager_exit)
\ No newline at end of file
MMS_PLUGIN_DEFINE(modemmanager, modemmanager_init, modemmanager_exit)
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment