--- src/sms.c | 146 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 143 insertions(+), 3 deletions(-)
diff --git a/src/sms.c b/src/sms.c index e6a2f9c..d86b5ec 100644 --- a/src/sms.c +++ b/src/sms.c @@ -38,6 +38,8 @@ #include "smsutil.h" #include "storage.h" +#include "smsagent.h" + #define uninitialized_var(x) x = x #define MESSAGE_MANAGER_FLAG_CACHED 0x1 @@ -76,6 +78,7 @@ struct ofono_sms { GKeyFile *settings; char *imsi; int bearer; + GSList *agents; const struct ofono_sms_driver *driver; void *driver_data; struct ofono_atom *atom; @@ -631,6 +634,93 @@ static DBusMessage *sms_set_property(DBusConnection *conn, DBusMessage *msg, return __ofono_error_invalid_args(msg); } +static void sms_agent_removed(struct sms_agent *agent, void *data) +{ + struct ofono_sms *sms = data; + + DBG("Agent %p disconnected without unregistering", agent); + + sms->agents = g_slist_remove(sms->agents, agent); + + sms_agent_destroy(agent); +} + +static DBusMessage *sms_register_agent(DBusConnection *conn, + DBusMessage *msg, void *data) +{ + struct ofono_sms *sms = data; + struct sms_agent *agent; + GSList *l; + const char *path; + const char *name; + + if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path, + DBUS_TYPE_INVALID)) + return __ofono_error_invalid_args(msg); + + if (!__ofono_dbus_valid_object_path(path)) + return __ofono_error_invalid_format(msg); + + name = dbus_message_get_sender(msg); + + for (l = sms->agents; l; l = l->next) { + struct sms_agent *old = l->data; + + if (sms_agent_matches(old, path, name)) + return __ofono_error_in_use(msg); + } + + agent = sms_agent_create(path, name, sms_agent_removed, sms); + if (!agent) + return __ofono_error_failed(msg); + + DBG("Registering agent %s at %s (%p)", name, path, agent); + + sms->agents = g_slist_append(sms->agents, agent); + + return dbus_message_new_method_return(msg); +} + +static DBusMessage *sms_unregister_agent(DBusConnection *conn, + DBusMessage *msg, void *data) +{ + struct ofono_sms *sms = data; + GSList *l; + const char *path; + const char *name; + int removed = 0; + + if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path, + DBUS_TYPE_INVALID)) + return __ofono_error_invalid_args(msg); + + if (!__ofono_dbus_valid_object_path(path)) + return __ofono_error_invalid_format(msg); + + name = dbus_message_get_sender(msg); + + DBG("Finding %s at %s", name, path); + + for (l = sms->agents; l; l = l->next) { + struct sms_agent *agent = l->data; + + if (!sms_agent_matches(agent, path, name)) + continue; + + DBG("Unregistering agent %s at %s, (%p)", name, path, agent); + + sms->agents = g_slist_remove(sms->agents, agent); + sms_agent_destroy(agent); + removed = 1; + break; + } + + if (!removed) + return __ofono_error_not_found(msg); + + return dbus_message_new_method_return(msg); +} + /* * Destroy/release the contents of a 'struct tx_queue_entry' * @@ -1025,6 +1115,8 @@ static GDBusMethodTable sms_manager_methods[] = { { "SendMessage", "ss", "o", sms_send_message, G_DBUS_METHOD_FLAG_ASYNC }, { "GetMessages", "", "a(oa{sv})", sms_get_messages }, + { "RegisterAgent", "o", "", sms_register_agent }, + { "UnregisterAgent", "o", "", sms_unregister_agent }, { } }; @@ -1064,6 +1156,21 @@ static gboolean compute_incoming_msgid(GSList *sms_list, return TRUE; } +static void agent_dispatch_cb(struct sms_agent *agent, + enum sms_agent_result result, + void *data) +{ + struct ofono_sms *sms = data; + + if (result == SMS_AGENT_RESULT_OK) + return; + + ofono_error("Dispatching agent %p failed, removing", agent); + + sms->agents = g_slist_remove(sms->agents, agent); + sms_agent_destroy(agent); +} + static void dispatch_app_datagram(struct ofono_sms *sms, const struct ofono_uuid *uuid, int dst, int src, @@ -1076,12 +1183,27 @@ static void dispatch_app_datagram(struct ofono_sms *sms, time_t ts; struct tm remote; struct tm local; + GSList *l; ts = sms_scts_to_time(scts, &remote); localtime_r(&ts, &local); + for (l = sms->agents; l; l = l->next) { + struct sms_agent *agent = l->data; + int ret; + + ret = sms_agent_dispatch_datagram(agent, sender, &remote, &local, + dst, src, buf, len, + agent_dispatch_cb, sms, + NULL); + if (ret < 0) + ofono_error("Unable to dispatch datagram to agent %p: " + "%d (%s)", agent, ret, strerror(-ret)); + } + __ofono_history_datagram_received(modem, uuid, sender, dst, src, &remote, &local, buf, len); + } static void dispatch_text_message(struct ofono_sms *sms, @@ -1103,6 +1225,7 @@ static void dispatch_text_message(struct ofono_sms *sms, struct tm remote; struct tm local; const char *str = buf; + GSList *l; if (!message) return; @@ -1144,9 +1267,23 @@ static void dispatch_text_message(struct ofono_sms *sms, g_dbus_send_message(conn, signal); - if (cls != SMS_CLASS_0) - __ofono_history_sms_received(modem, uuid, str, - &remote, &local, message); + if (cls == SMS_CLASS_0) + return; + + for (l = sms->agents; l; l = l->next) { + struct sms_agent *agent = l->data; + int ret; + + ret = sms_agent_dispatch_text(agent, str, &remote, &local, + message, agent_dispatch_cb, + sms, NULL); + if (ret < 0) + ofono_error("Unable to dispatch text to agent %p", + agent); + } + + __ofono_history_sms_received(modem, uuid, str, &remote, &local, + message); } static void sms_dispatch(struct ofono_sms *sms, GSList *sms_list) @@ -1591,6 +1728,9 @@ static void sms_remove(struct ofono_atom *atom) sms->sr_assembly = NULL; } + g_slist_foreach(sms->agents, (GFunc)sms_agent_destroy, NULL); + g_slist_free(sms->agents); + g_free(sms); } -- 1.7.0.4 _______________________________________________ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono