mirror of git://git.sysmocom.de/ofono
sms: Implement text and datagram watch
Allow setting a watch for incoming text and datagram messages on the sms atom.
This commit is contained in:
parent
297b14ca8b
commit
5a85a57cc3
25
src/ofono.h
25
src/ofono.h
|
@ -229,12 +229,37 @@ enum ofono_sms_submit_flag {
|
|||
};
|
||||
|
||||
typedef void (*ofono_sms_txq_submit_cb_t)(gboolean ok, void *data);
|
||||
typedef void (*ofono_sms_text_notify_cb_t)(const char *from,
|
||||
const struct tm *remote,
|
||||
const struct tm *local,
|
||||
const char *text,
|
||||
void *data);
|
||||
typedef void (*ofono_sms_datagram_notify_cb_t)(const char *from,
|
||||
const struct tm *remote,
|
||||
const struct tm *local,
|
||||
int dst, int src,
|
||||
const unsigned char *buffer,
|
||||
unsigned int len,
|
||||
void *data);
|
||||
|
||||
int __ofono_sms_txq_submit(struct ofono_sms *sms, GSList *list,
|
||||
unsigned int flags, struct ofono_uuid *uuid,
|
||||
ofono_sms_txq_submit_cb_t cb,
|
||||
void *data, ofono_destroy_func destroy);
|
||||
|
||||
unsigned int __ofono_sms_text_watch_add(struct ofono_sms *sms,
|
||||
ofono_sms_text_notify_cb_t cb,
|
||||
void *data, ofono_destroy_func destroy);
|
||||
gboolean __ofono_sms_text_watch_remove(struct ofono_sms *sms,
|
||||
unsigned int id);
|
||||
|
||||
unsigned int __ofono_sms_datagram_watch_add(struct ofono_sms *sms,
|
||||
ofono_sms_datagram_notify_cb_t cb,
|
||||
int dst, int src, void *data,
|
||||
ofono_destroy_func destroy);
|
||||
gboolean __ofono_sms_datagram_watch_remove(struct ofono_sms *sms,
|
||||
unsigned int id);
|
||||
|
||||
#include <ofono/sim.h>
|
||||
#include <ofono/stk.h>
|
||||
|
||||
|
|
163
src/sms.c
163
src/sms.c
|
@ -62,6 +62,12 @@ struct message {
|
|||
enum message_state state;
|
||||
};
|
||||
|
||||
struct sms_handler {
|
||||
struct ofono_watchlist_item item;
|
||||
int dst;
|
||||
int src;
|
||||
};
|
||||
|
||||
struct ofono_sms {
|
||||
int flags;
|
||||
DBusMessage *pending;
|
||||
|
@ -82,6 +88,8 @@ struct ofono_sms {
|
|||
ofono_bool_t use_delivery_reports;
|
||||
struct status_report_assembly *sr_assembly;
|
||||
GHashTable *messages;
|
||||
struct ofono_watchlist *text_handlers;
|
||||
struct ofono_watchlist *datagram_handlers;
|
||||
};
|
||||
|
||||
struct pending_pdu {
|
||||
|
@ -108,6 +116,11 @@ static gboolean uuid_equal(gconstpointer v1, gconstpointer v2)
|
|||
return memcmp(v1, v2, OFONO_SHA1_UUID_LEN) == 0;
|
||||
}
|
||||
|
||||
static gboolean port_equal(int received, int expected)
|
||||
{
|
||||
return expected == -1 || received == expected;
|
||||
}
|
||||
|
||||
static guint uuid_hash(gconstpointer v)
|
||||
{
|
||||
const struct ofono_uuid *uuid = v;
|
||||
|
@ -170,6 +183,77 @@ static void append_message_properties(struct message *m, DBusMessageIter *dict)
|
|||
ofono_dbus_dict_append(dict, "State", DBUS_TYPE_STRING, &state);
|
||||
}
|
||||
|
||||
static unsigned int add_sms_handler(struct ofono_watchlist *watchlist,
|
||||
int dst, int src, void *notify,
|
||||
void *data, ofono_destroy_func destroy)
|
||||
{
|
||||
struct sms_handler *handler;
|
||||
|
||||
if (!notify)
|
||||
return 0;
|
||||
|
||||
handler = g_try_new0(struct sms_handler, 1);
|
||||
if (!handler)
|
||||
return 0;
|
||||
|
||||
handler->dst = dst;
|
||||
handler->src = src;
|
||||
handler->item.notify = notify;
|
||||
handler->item.notify_data = data;
|
||||
handler->item.destroy = destroy;
|
||||
|
||||
return __ofono_watchlist_add_item(watchlist,
|
||||
(struct ofono_watchlist_item *)handler);
|
||||
}
|
||||
|
||||
unsigned int __ofono_sms_text_watch_add(struct ofono_sms *sms,
|
||||
ofono_sms_text_notify_cb_t cb,
|
||||
void *data, ofono_destroy_func destroy)
|
||||
{
|
||||
if (!sms)
|
||||
return 0;
|
||||
|
||||
DBG("%p", sms);
|
||||
|
||||
return add_sms_handler(sms->text_handlers, -1, -1, cb, data, destroy);
|
||||
}
|
||||
|
||||
gboolean __ofono_sms_text_watch_remove(struct ofono_sms *sms,
|
||||
unsigned int id)
|
||||
{
|
||||
if (!sms)
|
||||
return FALSE;
|
||||
|
||||
DBG("%p", sms);
|
||||
|
||||
return __ofono_watchlist_remove_item(sms->text_handlers, id);
|
||||
}
|
||||
|
||||
unsigned int __ofono_sms_datagram_watch_add(struct ofono_sms *sms,
|
||||
ofono_sms_datagram_notify_cb_t cb,
|
||||
int dst, int src, void *data,
|
||||
ofono_destroy_func destroy)
|
||||
{
|
||||
if (!sms)
|
||||
return 0;
|
||||
|
||||
DBG("%p: dst %d, src %d", sms, dst, src);
|
||||
|
||||
return add_sms_handler(sms->datagram_handlers, dst, src, cb, data,
|
||||
destroy);
|
||||
}
|
||||
|
||||
gboolean __ofono_sms_datagram_watch_remove(struct ofono_sms *sms,
|
||||
unsigned int id)
|
||||
{
|
||||
if (!sms)
|
||||
return FALSE;
|
||||
|
||||
DBG("%p", sms);
|
||||
|
||||
return __ofono_watchlist_remove_item(sms->datagram_handlers, id);
|
||||
}
|
||||
|
||||
static DBusMessage *message_get_properties(DBusConnection *conn,
|
||||
DBusMessage *msg, void *data)
|
||||
{
|
||||
|
@ -1064,12 +1148,35 @@ static gboolean compute_incoming_msgid(GSList *sms_list,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static void dispatch_app_datagram(struct ofono_sms *sms, int dst, int src,
|
||||
unsigned char *buf, long len)
|
||||
static void dispatch_app_datagram(struct ofono_sms *sms,
|
||||
const struct ofono_uuid *uuid,
|
||||
int dst, int src,
|
||||
unsigned char *buf, unsigned len,
|
||||
const struct sms_address *addr,
|
||||
const struct sms_scts *scts)
|
||||
{
|
||||
DBG("Got app datagram for dst port: %d, src port: %d",
|
||||
dst, src);
|
||||
DBG("Contents-Len: %ld", len);
|
||||
const char *sender = sms_address_to_string(addr);
|
||||
time_t ts;
|
||||
struct tm remote;
|
||||
struct tm local;
|
||||
|
||||
ofono_sms_datagram_notify_cb_t notify;
|
||||
struct sms_handler *h;
|
||||
GSList *l;
|
||||
|
||||
ts = sms_scts_to_time(scts, &remote);
|
||||
localtime_r(&ts, &local);
|
||||
|
||||
for (l = sms->datagram_handlers->items; l; l = l->next) {
|
||||
h = l->data;
|
||||
notify = h->item.notify;
|
||||
|
||||
if (!port_equal(dst, h->dst) || !port_equal(src, h->src))
|
||||
continue;
|
||||
|
||||
notify(sender, &remote, &local, dst, src, buf, len,
|
||||
h->item.notify_data);
|
||||
}
|
||||
}
|
||||
|
||||
static void dispatch_text_message(struct ofono_sms *sms,
|
||||
|
@ -1091,6 +1198,9 @@ static void dispatch_text_message(struct ofono_sms *sms,
|
|||
struct tm remote;
|
||||
struct tm local;
|
||||
const char *str = buf;
|
||||
ofono_sms_text_notify_cb_t notify;
|
||||
struct sms_handler *h;
|
||||
GSList *l;
|
||||
|
||||
if (!message)
|
||||
return;
|
||||
|
@ -1132,15 +1242,25 @@ 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->text_handlers->items; l; l = l->next) {
|
||||
h = l->data;
|
||||
notify = h->item.notify;
|
||||
|
||||
notify(str, &remote, &local, message, h->item.notify_data);
|
||||
}
|
||||
|
||||
__ofono_history_sms_received(modem, uuid, str, &remote, &local,
|
||||
message);
|
||||
}
|
||||
|
||||
static void sms_dispatch(struct ofono_sms *sms, GSList *sms_list)
|
||||
{
|
||||
GSList *l;
|
||||
const struct sms *s;
|
||||
struct ofono_uuid uuid;
|
||||
enum sms_charset uninitialized_var(old_charset);
|
||||
enum sms_class cls;
|
||||
int srcport = -1;
|
||||
|
@ -1214,6 +1334,11 @@ static void sms_dispatch(struct ofono_sms *sms, GSList *sms_list)
|
|||
}
|
||||
}
|
||||
|
||||
if (!compute_incoming_msgid(sms_list, &uuid))
|
||||
return;
|
||||
|
||||
s = sms_list->data;
|
||||
|
||||
/* Handle datagram */
|
||||
if (old_charset == SMS_CHARSET_8BIT) {
|
||||
unsigned char *buf;
|
||||
|
@ -1230,23 +1355,18 @@ static void sms_dispatch(struct ofono_sms *sms, GSList *sms_list)
|
|||
if (!buf)
|
||||
return;
|
||||
|
||||
dispatch_app_datagram(sms, dstport, srcport, buf, len);
|
||||
dispatch_app_datagram(sms, &uuid, dstport, srcport, buf, len,
|
||||
&s->deliver.oaddr, &s->deliver.scts);
|
||||
|
||||
g_free(buf);
|
||||
} else {
|
||||
struct ofono_uuid uuid;
|
||||
char *message = sms_decode_text(sms_list);
|
||||
|
||||
if (!message)
|
||||
return;
|
||||
|
||||
if (compute_incoming_msgid(sms_list, &uuid)) {
|
||||
s = sms_list->data;
|
||||
|
||||
dispatch_text_message(sms, &uuid, message, cls,
|
||||
&s->deliver.oaddr,
|
||||
&s->deliver.scts);
|
||||
}
|
||||
dispatch_text_message(sms, &uuid, message, cls,
|
||||
&s->deliver.oaddr, &s->deliver.scts);
|
||||
|
||||
g_free(message);
|
||||
}
|
||||
|
@ -1527,6 +1647,12 @@ static void sms_unregister(struct ofono_atom *atom)
|
|||
g_hash_table_destroy(sms->messages);
|
||||
sms->messages = NULL;
|
||||
}
|
||||
|
||||
__ofono_watchlist_free(sms->text_handlers);
|
||||
sms->text_handlers = NULL;
|
||||
|
||||
__ofono_watchlist_free(sms->datagram_handlers);
|
||||
sms->datagram_handlers = NULL;
|
||||
}
|
||||
|
||||
static void sms_remove(struct ofono_atom *atom)
|
||||
|
@ -1741,6 +1867,9 @@ void ofono_sms_register(struct ofono_sms *sms)
|
|||
sms->driver->bearer_set(sms, sms->bearer,
|
||||
bearer_init_callback, sms);
|
||||
|
||||
sms->text_handlers = __ofono_watchlist_new(g_free);
|
||||
sms->datagram_handlers = __ofono_watchlist_new(g_free);
|
||||
|
||||
__ofono_atom_register(sms->atom, sms_unregister);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue