Commit 7963ca2c authored by Andrea Schaefer's avatar Andrea Schaefer
Browse files

Merge branch 'feat-multipart-sms' into 'master'

Improve SMS plugin functionality

See merge request !4
parents 27086ad5 57f8214b
Pipeline #26134 passed with stage
in 54 seconds
......@@ -18,10 +18,12 @@
#define G_LOG_DOMAIN "mm-sms"
#define _GNU_SOURCE 1
#include <glib.h>
#include <glib/gi18n.h>
#include <string.h>
#include <time.h>
#include <gio/gio.h>
#include <purple.h>
#include <debug.h>
......@@ -59,9 +61,10 @@ typedef struct {
typedef struct {
MMSms *sms;
MMSmsState state;
const gchar *number;
const gchar *message;
const gchar *t_stamp;
time_t t_stamp;
const gchar *path;
} PurSmsProps;
......@@ -69,9 +72,11 @@ static void pur_mm_state (int state);
static void pur_mm_get_modems (void);
static void pur_mm_purple_connect (void);
static void pur_mm_signal_emit (int state);
static void pur_mm_get_sms_list (PurSmsProps *sms_props);
static void pur_mm_delete_sms (const char *path);
static void pur_mm_get_new_sms (char *path);
static void pur_mm_delete_sms (PurSmsProps *sms_props);
static void pur_mm_check_pdu_type (PurSmsProps *sms_props);
static void pur_mm_get_sms_properties (PurSmsProps *sms_props);
static void pur_mm_send_sms_to_purple_serv (PurSmsProps *sms_props);
PurplePlugin *mm_sms_plugin = NULL;
......@@ -171,20 +176,17 @@ cb_mm_sms_cmd (PurpleConversation *conv,
}
static void
static gboolean
cb_dbus_signal_sms_added (MMModemMessaging *device,
gchar *path,
gpointer user_data)
{
PurSmsProps *sms_props;
pur_mm_get_new_sms (g_strdup (path));
sms_props = g_new0 (PurSmsProps, 1);
sms_props->path = g_strdup (path);
purple_debug_info ("mm-sms", "New SMS at '%s'", path);
g_debug ("%s: New SMS at %s", __func__, path);
pur_mm_get_sms_list (sms_props);
purple_debug_info ("mm-sms", "New SMS: %s", path);
g_debug ("New SMS: %s", path);
return TRUE;
}
......@@ -193,22 +195,24 @@ cb_dbus_signal_sms_deleted (MMModemMessaging *device,
gchar *path,
gpointer user_data)
{
g_debug ("Removed SMS `%s'", path);
g_debug ("%s: Removed SMS at '%s'", __func__, path);
}
static void
cb_sms_delete_finish (MMModemMessaging *modem,
GAsyncResult *result,
gpointer user_data)
PurSmsProps *sms_props)
{
GError *error = NULL;
g_autoptr(GError) error = NULL;
pur_mm_data_t *mm_sms = pur_mm_get_data ();
if (mm_modem_messaging_delete_finish (modem, result, &error)) {
g_ptr_array_remove (mm_sms->sms_arr, sms_props);
g_debug ("Message delete finish");
} else {
g_debug ("Couldn't delete SMS - error: %s", error ? error->message : "unknown");
g_error_free (error);
}
}
......@@ -218,15 +222,14 @@ cb_sms_send_finish (MMSms *sms,
GAsyncResult *result,
gpointer user_data)
{
GError *error = NULL;
gboolean fin;
g_autoptr(GError) error = NULL;
gboolean fin;
fin = mm_sms_send_finish (sms, result, &error);
if (!fin) {
pur_mm_signal_emit (SMS_RECEIPT_NONE);
g_debug ("Couldn't send SMS - error: %s", error ? error->message : "unknown");
g_error_free (error);
} else {
pur_mm_signal_emit (SMS_RECEIPT_MM_ACKN);
g_debug ("Successfully sent SMS: %s", mm_sms_get_path (sms));
......@@ -239,14 +242,13 @@ cb_sms_create_finish (MMModemMessaging *modem,
GAsyncResult *result,
gpointer user_data)
{
MMSms *sms;
GError *error = NULL;
MMSms *sms;
g_autoptr(GError) error = NULL;
sms = mm_modem_messaging_create_finish (modem, result, &error);
if (!sms) {
g_debug ("Couldn't create new SMS - error: %s", error ? error->message : "unknown");
g_error_free (error);
} else {
g_debug ("Successfully created new SMS: %s", mm_sms_get_path (sms));
......@@ -261,30 +263,90 @@ cb_sms_create_finish (MMModemMessaging *modem,
static void
cb_sms_list_ready (MMModemMessaging *modem,
GAsyncResult *result,
PurSmsProps *sms_props)
cb_sms_state_change (MMSms *sms,
GParamSpec *pspec,
PurSmsProps *sms_props)
{
pur_mm_get_sms_properties (sms_props);
if (sms_props->state == MM_SMS_STATE_RECEIVED) {
// The message has been completely received,
// hand the SMS message to the libpurple core
pur_mm_get_sms_properties (sms_props);
pur_mm_send_sms_to_purple_serv (sms_props);
}
g_debug ("%s: state %s", __func__,
mm_sms_state_get_string (mm_sms_get_state (sms)));
}
static void
cb_sms_list_new_ready (MMModemMessaging *modem,
GAsyncResult *result,
gchar *path)
{
GList *l, *list;
GError *error = NULL;
GList *l, *list;
g_autoptr(GError) error = NULL;
PurSmsProps *sms_props;
pur_mm_data_t *mm_sms = pur_mm_get_data ();
list = mm_modem_messaging_list_finish (modem, result, &error);
if (!list) {
g_debug ("Couldn't get SMS list - error: %s", error ? error->message : "unknown");
g_error_free (error);
} else {
for (l = list; l; l = g_list_next (l)) {
if (!g_strcmp0 (mm_sms_get_path (MM_SMS (l->data)), sms_props->path)) {
sms_props->sms = MM_SMS (l->data);
if (!g_strcmp0 (mm_sms_get_path (MM_SMS (l->data)), path)) {
sms_props = g_new0 (PurSmsProps, 1);
sms_props->sms = g_object_ref (MM_SMS (l->data));
g_ptr_array_add (mm_sms->sms_arr, sms_props);
pur_mm_get_sms_properties (sms_props);
break;
}
}
pur_mm_check_pdu_type (sms_props);
g_list_free_full (list, g_object_unref);
g_free (sms_props);
g_free (path);
}
g_debug ("%s", __func__);
}
static void
cb_sms_list_all_ready (MMModemMessaging *modem,
GAsyncResult *result,
gpointer user_data)
{
GList *l, *list;
g_autoptr(GError) error = NULL;
PurSmsProps *sms_props;
pur_mm_data_t *mm_sms = pur_mm_get_data ();
list = mm_modem_messaging_list_finish (modem, 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_props = g_new0 (PurSmsProps, 1);
sms_props->sms = g_object_ref (MM_SMS (l->data));
g_ptr_array_add (mm_sms->sms_arr, sms_props);
}
g_ptr_array_foreach (mm_sms->sms_arr,
(GFunc) pur_mm_check_pdu_type,
NULL);
g_list_free_full (list, g_object_unref);
}
g_debug ("%s", __func__);
}
......@@ -335,7 +397,8 @@ static void
pur_mm_get_sim_ready (MMModem *modem)
{
if (!modem) {
g_debug ("Get SIM ready: No Modem");
g_debug ("%s: No Modem", __func__);
pur_mm_state (PUR_MM_STATE_NO_MODEM);
return;
}
......@@ -351,11 +414,10 @@ cb_sim_send_pin_ready (MMSim *sim,
GAsyncResult *res,
gpointer user_data)
{
GError *error = NULL;
g_autoptr(GError) error = NULL;
if (!mm_sim_send_pin_finish (sim, res, &error)) {
g_debug ("Couldn't unlock SIM - error: %s", error ? error->message : "unknown");
g_error_free (error);
pur_mm_state (PUR_MM_STATE_MODEM_UNLOCK_ERROR);
} else {
pur_mm_purple_connect ();
......@@ -402,7 +464,11 @@ pur_mm_send_sms_to_purple_serv (PurSmsProps *sms_props)
sms_props->number,
sms_props->message,
PURPLE_MESSAGE_RECV,
time (NULL));
sms_props->t_stamp);
if (mm_sms->sms_delete_received) {
pur_mm_delete_sms (sms_props);
}
}
}
}
......@@ -410,8 +476,29 @@ pur_mm_send_sms_to_purple_serv (PurSmsProps *sms_props)
static void
pur_mm_get_sms_properties (PurSmsProps *sms_props)
{
MMSms *sms;
const char *mm_time;
struct tm t_8601;
sms = sms_props->sms;
sms_props->state = mm_sms_get_state (sms);
sms_props->path = mm_sms_get_path (sms);
sms_props->number = mm_sms_get_number (sms);
sms_props->message = mm_sms_get_text (sms);
mm_time = mm_sms_get_timestamp (sms);
strptime (mm_time, "%y%m%d%H%M%S%z", &t_8601);
sms_props->t_stamp = mktime (&t_8601);
}
static void
pur_mm_check_pdu_type (PurSmsProps *sms_props)
{
MMSms *sms;
MMSmsState state;
MMSmsPduType pdu_type;
guint message_ref;
guint delivery_state;
......@@ -419,14 +506,8 @@ pur_mm_get_sms_properties (PurSmsProps *sms_props)
pur_mm_data_t *mm_sms = pur_mm_get_data ();
sms = sms_props->sms;
sms_props->path = mm_sms_get_path (sms);
sms_props->number = mm_sms_get_number (sms);
sms_props->message = mm_sms_get_text (sms);
sms_props->t_stamp = mm_sms_get_timestamp (sms);
state = mm_sms_get_state (sms);
message_ref = mm_sms_get_message_reference (sms);
pdu_type = mm_sms_get_pdu_type (sms);
switch (pdu_type) {
......@@ -435,19 +516,27 @@ pur_mm_get_sms_properties (PurSmsProps *sms_props)
// TODO: create hash_table to link message_ref to sms_id
} else {
if (mm_sms->sms_delete_sent) {
pur_mm_delete_sms (sms_props->path);
pur_mm_delete_sms (sms_props);
}
}
break;
case MM_SMS_PDU_TYPE_DELIVER:
// hand the SMS message to the libpurple core
pur_mm_send_sms_to_purple_serv (sms_props);
if (mm_sms->sms_delete_received) {
pur_mm_delete_sms (sms_props->path);
if (state == MM_SMS_STATE_RECEIVED) {
// The message has been completely received,
// hand the SMS message to the libpurple core
pur_mm_get_sms_properties (sms_props);
pur_mm_send_sms_to_purple_serv (sms_props);
}
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_props->sms,
"notify::state",
G_CALLBACK (cb_sms_state_change),
sms_props);
}
break;
case MM_SMS_PDU_TYPE_STATUS_REPORT:
......@@ -466,31 +555,56 @@ pur_mm_get_sms_properties (PurSmsProps *sms_props)
default:
g_debug ("PDU type not handled");
}
g_debug ("%s: pdu type %s", __func__,
mm_sms_pdu_type_get_string (pdu_type));
}
static void
pur_mm_get_sms_list (PurSmsProps *sms_props)
pur_mm_get_new_sms (char *path)
{
pur_mm_data_t *mm_sms = pur_mm_get_data ();
mm_modem_messaging_list (mm_sms->modem_messaging,
NULL,
(GAsyncReadyCallback)cb_sms_list_ready,
sms_props);
(GAsyncReadyCallback)cb_sms_list_new_ready,
path);
g_debug ("%s path %s", __func__, (char*)path);
}
static void
pur_mm_delete_sms (const char *path)
pur_mm_get_all_sms (void)
{
pur_mm_data_t *mm_sms = pur_mm_get_data ();
mm_modem_messaging_delete (mm_sms->modem_messaging,
path,
NULL,
(GAsyncReadyCallback)cb_sms_delete_finish,
NULL);
mm_modem_messaging_list (mm_sms->modem_messaging,
NULL,
(GAsyncReadyCallback)cb_sms_list_all_ready,
NULL);
g_debug ("%s", __func__);
}
static void
pur_mm_delete_sms (PurSmsProps *sms_props)
{
const char *path;
pur_mm_data_t *mm_sms = pur_mm_get_data ();
path = mm_sms_get_path (sms_props->sms);
if (path) {
mm_modem_messaging_delete (mm_sms->modem_messaging,
path,
NULL,
(GAsyncReadyCallback)cb_sms_delete_finish,
sms_props);
}
}
......@@ -559,15 +673,17 @@ pur_mm_init_modem (MMObject *obj)
gdbus_sms = MM_GDBUS_MODEM_MESSAGING(mm_sms->modem_messaging);
g_signal_connect (gdbus_sms, "added",
g_signal_connect (gdbus_sms,
"added",
G_CALLBACK (cb_dbus_signal_sms_added),
NULL);
g_signal_connect (gdbus_sms, "deleted",
g_signal_connect (gdbus_sms,
"deleted",
G_CALLBACK (cb_dbus_signal_sms_deleted),
NULL);
g_debug ("pur_mm_init_modem");
g_debug ("%s", __func__);
}
......@@ -589,7 +705,7 @@ pur_mm_add_object (MMObject *obj)
object_path = g_dbus_object_get_object_path (G_DBUS_OBJECT (obj));
if (g_ptr_array_find_with_equal_func (mm_sms->devices,
if (g_ptr_array_find_with_equal_func (mm_sms->device_arr,
obj,
(GEqualFunc)device_match_by_object,
NULL)) {
......@@ -605,9 +721,10 @@ pur_mm_add_object (MMObject *obj)
device = g_new0 (PurMmDevice, 1);
device->object = MM_OBJECT (obj);
device->modem = mm_object_get_modem (MM_OBJECT(obj));
g_ptr_array_add (mm_sms->devices, device);
g_ptr_array_add (mm_sms->device_arr, device);
pur_mm_init_modem (obj);
pur_mm_get_all_sms ();
pur_mm_state (PUR_MM_STATE_MODEM_FOUND);
}
......@@ -626,7 +743,7 @@ cb_object_added (GDBusObjectManager *manager,
"mm-sms-modem-added",
(int)mm_modem_get_state (modem));
g_debug ("cb_object_added");
g_debug ("%s", __func__);
}
......@@ -639,11 +756,11 @@ cb_object_removed (GDBusObjectManager *manager,
pur_mm_data_t *mm_sms = pur_mm_get_data ();
if (g_ptr_array_find_with_equal_func (mm_sms->devices,
if (g_ptr_array_find_with_equal_func (mm_sms->device_arr,
object,
(GEqualFunc) device_match_by_object,
&index)) {
g_ptr_array_remove_index_fast (mm_sms->devices, index);
g_ptr_array_remove_index_fast (mm_sms->device_arr, index);
}
if (MM_OBJECT(object) == mm_sms->object) {
......@@ -659,7 +776,7 @@ cb_name_owner_changed (GDBusObjectManager *manager,
GDBusObject *object,
gpointer user_data)
{
gchar *name_owner;
gchar *name_owner;
name_owner = g_dbus_object_manager_client_get_name_owner (G_DBUS_OBJECT_MANAGER_CLIENT (manager));
......@@ -699,14 +816,15 @@ cb_mm_manager_new (GDBusConnection *connection,
GAsyncResult *res,
gpointer user_data)
{
gchar *name_owner;
GError *error = NULL;
gchar *name_owner;
g_autoptr(GError) error = NULL;
pur_mm_data_t *mm_sms = pur_mm_get_data ();
mm_sms->mm = mm_manager_new_finish (res, &error);
mm_sms->devices = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
mm_sms->sms_arr = g_ptr_array_new ();
mm_sms->device_arr = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
if (mm_sms->mm) {
g_signal_connect (mm_sms->mm,
......@@ -734,7 +852,6 @@ cb_mm_manager_new (GDBusConnection *connection,
} else {
purple_debug_info ("mm-sms", "Error connecting to ModemManager: %s\n", error->message);
g_debug ("Error connecting to ModemManager: %s", error->message);
g_error_free (error);
pur_mm_state (PUR_MM_STATE_NO_MANAGER);
}
......@@ -744,8 +861,8 @@ cb_mm_manager_new (GDBusConnection *connection,
static gboolean
pur_mm_get_modem_manager (void)
{
GDBusConnection *connection;
GError *error = NULL;
GDBusConnection *connection;
g_autoptr(GError) error = NULL;
connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error);
......@@ -762,7 +879,6 @@ pur_mm_get_modem_manager (void)
} else {
purple_debug_info ("mm-sms", "Error connecting to ModemManager: %s\n", error->message);
g_debug ("Error connecting to ModemManager: %s", error->message);
g_error_free (error);
return FALSE;
}
......@@ -886,8 +1002,13 @@ pur_mm_disconnect (void)
{
pur_mm_data_t *mm_sms = pur_mm_get_data ();
if (mm_sms->devices->len) {
g_ptr_array_set_size (mm_sms->devices, 0);
if (mm_sms->device_arr->len) {
g_ptr_array_set_size (mm_sms->device_arr, 0);
g_ptr_array_unref(mm_sms->device_arr);
}
if (mm_sms->sms_arr->len) {
g_ptr_array_unref(mm_sms->sms_arr);
}
mm_sms->modem_available = FALSE;
......@@ -1105,6 +1226,28 @@ plugin_unload (PurplePlugin *plugin)
return TRUE;
}
static void
plugin_destroy (PurplePlugin *plugin)
{
purple_debug_info ("mm-sms", "shutting down\n");
g_debug ("Shutting down");
}
static gboolean
plugin_can_receive_file (PurpleConnection *gc,
const char *who)
{
return FALSE;
}
static gboolean
plugin_offline_message (const PurpleBuddy *buddy)
{
return TRUE;
}
static GHashTable *
pur_mm_account_text_table (PurpleAccount *account)
......@@ -1278,10 +1421,10 @@ static PurplePluginProtocolInfo prpl_info = {
NULL, /* roomlist_get_list */
NULL, /* roomlist_cancel */
NULL, /* roomlist_expand_category */
NULL, /* can_receive_file */
plugin_can_receive_file, /* can_receive_file */
NULL, /* send_file */
NULL, /* new_xfer */
NULL, /* offline_message */
plugin_offline_message, /* offline_message */
NULL, /* whiteboard_prpl_ops */
NULL, /* send_raw */
NULL, /* roomlist_room_serialize */
......@@ -1318,7 +1461,7 @@ static PurplePluginInfo info = {
"https://source.puri.sm/Librem5/purple-mm-sms",
plugin_load,
plugin_unload,
NULL,
plugin_destroy,
NULL,
&prpl_info,
NULL,
......
......@@ -10,7 +10,8 @@ typedef struct {
MMSim *sim;
MMModemMessaging *modem_messaging;
GPtrArray *devices;
GPtrArray *sms_arr;
GPtrArray *device_arr;
gboolean modem_available;
gboolean manager_available;
......
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