From: ofono@market.talbothome.com
To: ofono@ofono.org
Subject: Two Patches for MMSD
Date: Thu, 18 Feb 2021 19:01:13 +0000 [thread overview]
Message-ID: <20210218190113.2937.66552@ml01.vlan13.01.org> (raw)
[-- Attachment #1: Type: text/plain, Size: 33953 bytes --]
Hello,
It was suggested to me to directly add patches here for MMSD. So I have two such patches, and I am working to clean up my code base so it is easier to get all of the patches. The following patches enable MMSD to work with both T-Mobile USA and AT&T USA.
My git repository is here: https://source.puri.sm/kop316/mmsd
----------------START AT&T PATCH------------------------
diff --git a/gweb/gweb.c b/gweb/gweb.c
index f72e1375de98858b5f6f7dbabc4af5618380abc3..2fa2a45e5867e8367a25efd64f01d9b5210aa04f 100644
--- a/gweb/gweb.c
+++ b/gweb/gweb.c
@@ -1309,7 +1309,8 @@ static guint do_request(GWeb *web, const char *url,
session->address = g_strdup(session->host);
memset(&hints, 0, sizeof(struct addrinfo));
- hints.ai_flags = AI_NUMERICHOST;
+ /* Comment out next line to have AT&T MMS proxy work */
+ //hints.ai_flags = AI_NUMERICHOST;
hints.ai_family = session->web->family;
if (session->addr != NULL) {
diff --git a/patch.diff b/patch.diff
new file mode 100644
index 0000000000000000000000000000000000000000..f4f4e341a2f45f7b07bf2b80b9b577ff0b562633
--- /dev/null
+++ b/patch.diff
@@ -0,0 +1,29 @@
+diff --git a/gweb/gweb.c b/gweb/gweb.c
+index f72e1375de98858b5f6f7dbabc4af5618380abc3..2fa2a45e5867e8367a25efd64f01d9b5210aa04f 100644
+--- a/gweb/gweb.c
++++ b/gweb/gweb.c
+@@ -1309,7 +1309,8 @@ static guint do_request(GWeb *web, const char *url,
+ session->address = g_strdup(session->host);
+
+ memset(&hints, 0, sizeof(struct addrinfo));
+- hints.ai_flags = AI_NUMERICHOST;
++ /* Comment out next line to have AT&T MMS proxy work */
++ //hints.ai_flags = AI_NUMERICHOST;
+ hints.ai_family = session->web->family;
+
+ if (session->addr != NULL) {
+diff --git a/src/service.c b/src/service.c
+index e5bde351556a08b9fbc0db9488fd929413bc07d8..daedca59ab65eac071724b513bbd39c885adb79d 100644
+--- a/src/service.c
++++ b/src/service.c
+@@ -2531,6 +2531,9 @@ void mms_service_bearer_notify(struct mms_service *service, mms_bool_t active,
+
+ g_web_set_debug(service->web, (GWebDebugFunc)debug_print, NULL);
+
++ /* Explicitly close connections to work with AT&T */
++ g_web_set_close_connection(service->web,TRUE);
++
+ /* Sometimes no proxy is reported as string instead of NULL */
+ if (g_strcmp0(proxy, "") != 0)
+ g_web_set_proxy(service->web, proxy);
+
diff --git a/src/service.c b/src/service.c
index e5bde351556a08b9fbc0db9488fd929413bc07d8..f0966a83258d0186dff955fe2b4b79c439f229eb 100644
--- a/src/service.c
+++ b/src/service.c
@@ -56,6 +56,7 @@
#define MAX_ATTACHMENTS_NUMBER 25
#define MAX_ATTEMPTS 3
+#define MAX_ATTACHMENT_TOTAL_SIZE 1000000
#define SETTINGS_STORE "mms"
#define SETTINGS_GROUP "Settings"
@@ -418,6 +419,7 @@ static gboolean send_message_get_attachments(DBusMessageIter *top_iter,
{
DBusMessageIter attachments;
unsigned int attach_num = 0;
+ unsigned int attach_total_size = 0;
dbus_message_iter_recurse(top_iter, &attachments);
@@ -430,8 +432,10 @@ static gboolean send_message_get_attachments(DBusMessageIter *top_iter,
struct mms_attachment *attach;
void *ptr;
- if (++attach_num > MAX_ATTACHMENTS_NUMBER)
+ if (++attach_num > MAX_ATTACHMENTS_NUMBER) {
+ mms_error("Error: Too many attachments!");
return FALSE;
+ }
dbus_message_iter_recurse(&attachments, &entry);
@@ -466,6 +470,14 @@ static gboolean send_message_get_attachments(DBusMessageIter *top_iter,
return FALSE;
}
+ attach_total_size = attach_total_size + attach->length;
+ mms_debug("Total attachment size: %d", attach_total_size);
+
+ if (attach_total_size > MAX_ATTACHMENT_TOTAL_SIZE) {
+ mms_error("Error: Total Attachment size too large!");
+ return FALSE;
+ }
+
attach->data = ptr;
attach->content_id = g_strdup(id);
@@ -2531,6 +2543,9 @@ void mms_service_bearer_notify(struct mms_service *service, mms_bool_t active,
g_web_set_debug(service->web, (GWebDebugFunc)debug_print, NULL);
+ /* Explicitly close connections to work with AT&T */
+ g_web_set_close_connection(service->web,TRUE);
+
/* Sometimes no proxy is reported as string instead of NULL */
if (g_strcmp0(proxy, "") != 0)
g_web_set_proxy(service->web, proxy);
----------END AT&T PATCH------------------------
---------------START TMOBILE PATCH----------------------
diff --git a/Makefile.am b/Makefile.am
index ee2c715bb935c1e26d81d5db831913883a887a7b..99fdb766ee1204ac840d7c6fe76513ac1ce75a9b 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -88,7 +88,8 @@ unit_test_wsputil_SOURCES = unit/test-wsputil.c src/wsputil.c src/wsputil.h
unit_test_wsputil_LDADD = @GLIB_LIBS@
unit_test_mmsutil_SOURCES = unit/test-mmsutil.c src/mmsutil.c src/mmsutil.h \
- src/wsputil.c src/wsputil.h
+ src/wsputil.c src/wsputil.h \
+ src/log.c src/log.h
unit_test_mmsutil_LDADD = @GLIB_LIBS@
TESTS = unit/test-wsputil unit/test-mmsutil
diff --git a/gweb/gresolv.c b/gweb/gresolv.c
index 79abc9b709585c2cc76bb9494c46c135b96d8c30..bb1c32de136831f15db8a10f3c5b482517732c71 100644
--- a/gweb/gresolv.c
+++ b/gweb/gresolv.c
@@ -35,6 +35,7 @@
#include <arpa/inet.h>
#include <arpa/nameser.h>
#include <net/if.h>
+#include <ifaddrs.h>
#include "gresolv.h"
@@ -764,13 +765,15 @@ static int connect_udp_channel(struct resolv_nameserver *nameserver)
return -EINVAL;
sk = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
+ const int so_reuseaddr = 1;
+ setsockopt(sk, SOL_SOCKET, SO_REUSEADDR, &so_reuseaddr, sizeof so_reuseaddr);
if (sk < 0) {
freeaddrinfo(rp);
return -EIO;
}
/*
- * If nameserver points to localhost ip, their is no need to
+ * If nameserver points to localhost ip, there is no need to
* bind the socket on any interface.
*/
if (nameserver->resolv->index > 0 &&
@@ -780,12 +783,63 @@ static int connect_udp_channel(struct resolv_nameserver *nameserver)
memset(interface, 0, IF_NAMESIZE);
if (if_indextoname(nameserver->resolv->index,
interface) != NULL) {
- if (setsockopt(sk, SOL_SOCKET, SO_BINDTODEVICE,
- interface, IF_NAMESIZE) < 0) {
+ /* set up bind address */
+ struct sockaddr_storage bind_addr;
+ int addr_size = 0;
+ memset(&bind_addr, 0, sizeof(bind_addr));
+ bind_addr.ss_family = rp->ai_family;
+
+ struct ifaddrs *ifa, *ifa_tmp;
+ if (getifaddrs(&ifa) == -1) {
+ perror("getifaddrs failed");
+ return -errno;
+ }
+ ifa_tmp = ifa;
+ while (ifa_tmp) {
+ if (!strcmp(ifa_tmp->ifa_name, interface) &&
+ ifa_tmp->ifa_addr) {
+ if (ifa_tmp->ifa_addr->sa_family != rp->ai_family) {
+ printf("fam %d != expected %d\n", ifa_tmp->ifa_addr->sa_family, rp->ai_family);
+ ifa_tmp = ifa_tmp->ifa_next;
+ continue;
+ }
+ if (ifa_tmp->ifa_addr->sa_family == AF_INET) {
+ struct sockaddr_in *bind_addr4 = (struct sockaddr_in *)&bind_addr;
+ bind_addr4->sin_addr.s_addr = ((struct sockaddr_in *)ifa_tmp->ifa_addr)->sin_addr.s_addr;
+ bind_addr4->sin_port = 53;
+ printf("addr = %s\n", inet_ntoa(bind_addr4->sin_addr));
+ addr_size = sizeof(*bind_addr4);
+ } else if (ifa_tmp->ifa_addr->sa_family == AF_INET6) {
+ struct sockaddr_in6 *bind_addr6 = (struct sockaddr_in6 *)&bind_addr;
+ bind_addr6->sin6_addr = ((struct sockaddr_in6 *)ifa_tmp->ifa_addr)->sin6_addr;
+ bind_addr6->sin6_port = 53;
+ char buf[64];
+ inet_ntop(AF_INET6, bind_addr6->sin6_addr.s6_addr, buf, 64);
+ printf("addr = %s\n", buf);
+ addr_size = sizeof(*bind_addr6);
+ } else {
+ printf("unknown fam\n");
+ }
+ break;
+ }
+ ifa_tmp = ifa_tmp->ifa_next;
+ }
+
+/* if (bind_addr. && bind_addr.sin_addr.s_addr == 0) {
+ printf("interface not found\n");
+ }
+
+ if (bind_addr.sin6_addr.s_addr == 0) {
+ printf("interface6 not found\n");
+ }*/
+
+ if (bind(sk, (struct sockaddr *)&bind_addr, addr_size) < 0) {
+ perror("bind failed");
close(sk);
freeaddrinfo(rp);
return -EIO;
}
+ freeifaddrs(ifa);
}
}
@@ -896,6 +950,7 @@ void g_resolv_set_debug(GResolv *resolv, GResolvDebugFunc func,
gboolean g_resolv_add_nameserver(GResolv *resolv, const char *address,
uint16_t port, unsigned long flags)
{
+ printf ("adding nameserver %s\n", address);
struct resolv_nameserver *nameserver;
if (resolv == NULL)
@@ -911,6 +966,7 @@ gboolean g_resolv_add_nameserver(GResolv *resolv, const char *address,
nameserver->resolv = resolv;
if (connect_udp_channel(nameserver) < 0) {
+ printf ("connect_udp_channel failed!\n");
free_nameserver(nameserver);
return FALSE;
}
@@ -977,6 +1033,9 @@ guint g_resolv_lookup_hostname(GResolv *resolv, const char *hostname,
if (resolv->nameserver_list == NULL) {
int i;
+ printf("g_resolv_lookup_hostname: nameserver_list NULL\n");
+
+ printf("g_resolv_lookup_hostname: nscount=%d\n", resolv->res.nscount);
for (i = 0; i < resolv->res.nscount; i++) {
char buf[100];
@@ -989,15 +1048,19 @@ guint g_resolv_lookup_hostname(GResolv *resolv, const char *hostname,
sa_addr = &resolv->res._u._ext.nsaddrs[i]->sin6_addr;
}
- if (family != AF_INET && family != AF_INET6)
+ if (family != AF_INET && family != AF_INET6) {
+ printf("g_resolv_lookup_hostname: skipping b/c family=%d\n", family);
continue;
+ }
if (inet_ntop(family, sa_addr, buf, sizeof(buf)))
g_resolv_add_nameserver(resolv, buf, 53, 0);
}
- if (resolv->nameserver_list == NULL)
+ if (resolv->nameserver_list == NULL) {
+ printf("g_resolv_lookup_hostname: nameserver_list *still* NULL\n");
g_resolv_add_nameserver(resolv, "127.0.0.1", 53, 0);
+ }
}
lookup = g_try_new0(struct resolv_lookup, 1);
diff --git a/gweb/gweb.c b/gweb/gweb.c
index 4c2f95c1a1a2d25d1cfe4bd7c94f6403311a6124..f72e1375de98858b5f6f7dbabc4af5618380abc3 100644
--- a/gweb/gweb.c
+++ b/gweb/gweb.c
@@ -1008,6 +1008,7 @@ static inline int bind_socket(int sk, int index, int family)
if (if_indextoname(index, interface) == NULL)
return -1;
+ printf("binding %s\n", interface);
err = setsockopt(sk, SOL_SOCKET, SO_BINDTODEVICE,
interface, IF_NAMESIZE);
if (err < 0)
diff --git a/plugins/ofono.c b/plugins/ofono.c
index e7324a7bedce08be62713e12c5e27a8fcf7399df..24a147a77a3b0180f8d8572c2cb8b83ad2fe3c2f 100644
--- a/plugins/ofono.c
+++ b/plugins/ofono.c
@@ -396,11 +396,14 @@ static void check_context_active(struct modem_data *modem,
g_free(modem->context_proxy);
modem->context_proxy = NULL;
+ DBG("context_active = false");
mms_service_bearer_notify(modem->service, FALSE, NULL, NULL);
- } else if (modem->context_proxy != NULL)
+ } else if (modem->context_proxy != NULL) {
+ DBG("nonnull proxy");
mms_service_bearer_notify(modem->service, TRUE,
modem->context_interface,
modem->context_proxy);
+ }
}
static void check_context_settings(struct modem_data *modem,
@@ -452,6 +455,7 @@ static void check_context_settings(struct modem_data *modem,
if (modem->context_active == FALSE)
return;
+ DBG("about to bearer_notify");
mms_service_bearer_notify(modem->service, TRUE,
modem->context_interface,
modem->context_proxy);
@@ -692,6 +696,7 @@ static void set_context_reply(DBusPendingCall *call, void *user_data)
dbus_error_init(&err);
if (dbus_set_error_from_message(&err, reply) == TRUE) {
+ DBG("set_ctx reply failure (%s: %s), about to bearer_notify", err.name, err.message);
dbus_error_free(&err);
mms_service_bearer_notify(modem->service, FALSE, NULL, NULL);
}
@@ -739,15 +744,17 @@ static void bearer_handler(mms_bool_t active, void *user_data)
{
struct modem_data *modem = user_data;
- DBG("path %s active %d", modem->path, active);
+ DBG("path %s active %d context_active %d", modem->path, active, modem->context_active);
if (active == TRUE && modem->context_active == TRUE) {
+ DBG("active and context_active, bearer_notify");
mms_service_bearer_notify(modem->service, TRUE,
modem->context_interface,
modem->context_proxy);
return;
}
+ DBG("checking for failure");
if (active == FALSE && modem->context_active == FALSE) {
mms_service_bearer_notify(modem->service, FALSE, NULL, NULL);
return;
diff --git a/src/mmsutil.c b/src/mmsutil.c
index a9a12eb2d4efe16a3889d7dafc9a36463d626874..5fcf358c8464b2a8703589e0dcc82dc92629db87 100644
--- a/src/mmsutil.c
+++ b/src/mmsutil.c
@@ -32,6 +32,7 @@
#include "wsputil.h"
#include "mmsutil.h"
+#include "mms.h"
#define MAX_ENC_VALUE_BYTES 6
@@ -75,7 +76,11 @@ enum mms_header {
MMS_HEADER_SUBJECT = 0x16,
MMS_HEADER_TO = 0x17,
MMS_HEADER_TRANSACTION_ID = 0x18,
- __MMS_HEADER_MAX = 0x19,
+ MMS_HEADER_RETRIEVE_STATUS = 0x19,
+ MMS_HEADER_RETRIEVE_TEXT = 0x20,
+ MMS_HEADER_READ_STATUS = 0x21,
+ MMS_HEADER_LAST_HANDLED = 0x21,
+ __MMS_HEADER_MAX = 0x22,
MMS_HEADER_INVALID = 0x80,
};
@@ -159,13 +164,18 @@ static gboolean extract_short(struct wsp_header_iter *iter, void *user)
static const char *decode_text(struct wsp_header_iter *iter)
{
const unsigned char *p;
- unsigned int l;
+ unsigned int l=32;
- if (wsp_header_iter_get_val_type(iter) != WSP_VALUE_TYPE_TEXT)
+ if (wsp_header_iter_get_val_type(iter) != WSP_VALUE_TYPE_TEXT) {
+ p = wsp_header_iter_get_val(iter);
+ DBG("could not decode text of (dummy) length %u: %*s", l-1, l-1, p+1);
return NULL;
+ }
p = wsp_header_iter_get_val(iter);
l = wsp_header_iter_get_val_len(iter);
+ DBG("claimed len: %u", l);
+ DBG("val: %*s", l - 1, p);
return wsp_decode_text(p, l, NULL);
}
@@ -184,31 +194,14 @@ static gboolean extract_text(struct wsp_header_iter *iter, void *user)
return TRUE;
}
-static gboolean extract_text_array_element(struct wsp_header_iter *iter,
- void *user)
-{
- char **out = user;
- const char *element;
- char *tmp;
-
- element = decode_text(iter);
- if (element == NULL)
- return FALSE;
-
- if (*out == NULL) {
- *out = g_strdup(element);
- return TRUE;
- }
-
- tmp = g_strjoin(",", *out, element, NULL);
- if (tmp == NULL)
- return FALSE;
-
- g_free(*out);
-
- *out = tmp;
-
- return TRUE;
+static char* remove_address_type_suffix(const char* addr, size_t len) {
+ return g_strdup(addr);
+/* #define MMS_ADDR_SUFFIX_PUBLIC_LAND_MOBILE_NUMBER "/TYPE=PLMN"
+ if(g_str_has_suffix(addr, MMS_ADDR_SUFFIX_PUBLIC_LAND_MOBILE_NUMBER)) {
+ return g_strndup(addr, len - strlen(MMS_ADDR_SUFFIX_PUBLIC_LAND_MOBILE_NUMBER));
+ } else {
+ return g_strdup(addr);
+ }*/
}
static char *decode_encoded_string_with_mib_enum(const unsigned char *p,
@@ -242,6 +235,57 @@ static char *decode_encoded_string_with_mib_enum(const unsigned char *p,
&bytes_read, &bytes_written, NULL);
}
+static gboolean extract_text_array_element(struct wsp_header_iter *iter,
+ void *user)
+{
+ char **out = user;
+ const char *element = NULL;
+ char *tmp;
+ DBG("");
+
+ const unsigned char *p;
+ unsigned int l;
+
+ p = wsp_header_iter_get_val(iter);
+ l = wsp_header_iter_get_val_len(iter);
+
+ switch (wsp_header_iter_get_val_type(iter)) {
+ case WSP_VALUE_TYPE_TEXT:
+ /* Text-string */
+ element = wsp_decode_text(p, l, NULL);
+ break;
+ case WSP_VALUE_TYPE_LONG:
+ /* (Value-len) Char-set Text-string */
+ element = decode_encoded_string_with_mib_enum(p, l);
+ break;
+ case WSP_VALUE_TYPE_SHORT:
+ element = NULL;
+ break;
+ }
+
+ if (element == NULL) {
+ DBG("failed, type=%d", wsp_header_iter_get_val_type(iter));
+ return FALSE;
+ }
+
+ if (*out == NULL) {
+ *out = g_strdup(element);
+ return TRUE;
+ }
+
+ tmp = g_strjoin(",", *out, element, NULL);
+ if (tmp == NULL) {
+ DBG("join failed");
+ return FALSE;
+ }
+
+ g_free(*out);
+
+ *out = tmp;
+
+ return TRUE;
+}
+
static gboolean extract_encoded_text(struct wsp_header_iter *iter, void *user)
{
char **out = user;
@@ -361,26 +405,62 @@ static gboolean extract_from(struct wsp_header_iter *iter, void *user)
const unsigned char *p;
unsigned int l;
const char *text;
+ unsigned char char_set = 0;
- if (wsp_header_iter_get_val_type(iter) != WSP_VALUE_TYPE_LONG)
+ if (wsp_header_iter_get_val_type(iter) != WSP_VALUE_TYPE_LONG) {
+ DBG("val_type not LONG");
return FALSE;
+ }
p = wsp_header_iter_get_val(iter);
l = wsp_header_iter_get_val_len(iter);
- if (p[0] != 128 && p[0] != 129)
+ /* From-value = Value-length (Address-present-token=128 Encoded-string-value | Insert-address-token=129) */
+ /* Encoded-string-value = Text-string | Value-length Char-set Text-string */
+ /* Value-length = Short-length | (Length-quote Length) */
+ /* Short-length = val 0-30 */
+ /* Length-quote = val 31 */
+ /* Length = Uintvar-integer */
+
+ if (p[0] != 128 && p[0] != 129) {
+ DBG("not 128 or 129");
return FALSE;
+ }
if (p[0] == 129) {
*out = NULL;
return TRUE;
}
+ p += 1; l -= 1; /* token has been handled */
+
+ unsigned int val_len = l;
+ unsigned int str_len;
+ if (p[0] < 31) { /*short-length */
+ val_len = p[0];
+ char_set = p[1];
+ p += 2;
+ val_len -= 1; /* count encoding against val_len */
+ } else if (p[0] == 31) /* length quote then long length */ {
+ unsigned int consumed = 0;
+ gboolean ok = wsp_decode_uintvar(p, l, &val_len, &consumed);
+ if (!ok)
+ return FALSE;
+ char_set = p[1];
+ p += consumed;
+ val_len -= 1; /* count encoding against val_len */
+ }
+ str_len = val_len - 1; /* NUL@the end is not counted by strlen() */
+
+ DBG("trying to decode text of length %u: %*s", str_len, str_len, p);
+ text = wsp_decode_text(p, val_len, NULL);
+ DBG("text=\"%s\"", text);
- text = wsp_decode_text(p + 1, l - 1, NULL);
- if (text == NULL)
+ if (text == NULL) {
+ DBG("could not decode text of length %u: %*s", str_len, str_len, p);
return FALSE;
+ }
- *out = g_strdup(text);
+ *out = remove_address_type_suffix(text, str_len);
return TRUE;
}
@@ -473,6 +553,50 @@ static gboolean extract_priority(struct wsp_header_iter *iter, void *user)
return TRUE;
}
+static gboolean extract_read_status(struct wsp_header_iter *iter, void *user)
+{
+ enum mms_message_read_status *out = user;
+ const unsigned char *p;
+
+ if (wsp_header_iter_get_val_type(iter) != WSP_VALUE_TYPE_SHORT)
+ return FALSE;
+
+ p = wsp_header_iter_get_val(iter);
+
+ if (p[0] == MMS_MESSAGE_READ_STATUS_READ ||
+ p[0] == MMS_MESSAGE_READ_STATUS_DELETED_UNREAD) {
+ *out = p[0];
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static gboolean extract_retr_status(struct wsp_header_iter *iter, void *user)
+{
+ enum mms_message_retr_status *out = user;
+ const unsigned char *p;
+
+ if (wsp_header_iter_get_val_type(iter) != WSP_VALUE_TYPE_SHORT)
+ return FALSE;
+
+ p = wsp_header_iter_get_val(iter);
+
+ switch (p[0]) {
+ case MMS_MESSAGE_RETR_STATUS_OK:
+ case MMS_MESSAGE_RETR_STATUS_ERR_TRANS_FAILURE:
+ case MMS_MESSAGE_RETR_STATUS_ERR_TRANS_MESSAGE_NOT_FOUND:
+ case MMS_MESSAGE_RETR_STATUS_ERR_PERM_FAILURE:
+ case MMS_MESSAGE_RETR_STATUS_ERR_PERM_SERVICE_DENIED:
+ case MMS_MESSAGE_RETR_STATUS_ERR_PERM_MESSAGE_NOT_FOUND:
+ case MMS_MESSAGE_RETR_STATUS_ERR_PERM_CONTENT_UNSUPPORTED:
+ *out = p[0];
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
static gboolean extract_rsp_status(struct wsp_header_iter *iter, void *user)
{
unsigned char *out = user;
@@ -559,7 +683,7 @@ static header_handler handler_for_type(enum mms_header header)
case MMS_HEADER_CONTENT_LOCATION:
return extract_text;
case MMS_HEADER_CONTENT_TYPE:
- return extract_text;
+ return extract_text; /* extract_encoded_text? */
case MMS_HEADER_DATE:
return extract_date;
case MMS_HEADER_DELIVERY_REPORT:
@@ -590,6 +714,12 @@ static header_handler handler_for_type(enum mms_header header)
return extract_rsp_status;
case MMS_HEADER_RESPONSE_TEXT:
return extract_encoded_text;
+ case MMS_HEADER_RETRIEVE_STATUS:
+ return extract_retr_status;
+ case MMS_HEADER_RETRIEVE_TEXT:
+ return extract_encoded_text;
+ case MMS_HEADER_READ_STATUS:
+ return extract_read_status;
case MMS_HEADER_SENDER_VISIBILITY:
return extract_sender_visibility;
case MMS_HEADER_STATUS:
@@ -650,8 +780,12 @@ static gboolean mms_parse_headers(struct wsp_header_iter *iter,
h = p[0] & 0x7f;
handler = handler_for_type(h);
- if (handler == NULL)
+ if (handler == NULL) {
+ DBG("no handler for type %u", h);
return FALSE;
+ }
+
+ DBG("saw header of type %u", h);
/* Unsupported header, skip */
if (entries[h].data == NULL)
@@ -662,9 +796,15 @@ static gboolean mms_parse_headers(struct wsp_header_iter *iter,
!(entries[h].flags & HEADER_FLAG_ALLOW_MULTI))
continue;
+ DBG("running handler for type %u", h);
+
/* Parse the header */
- if (handler(iter, entries[h].data) == FALSE)
+ if (handler(iter, entries[h].data) == FALSE) {
+ DBG("handler %p for type %u returned false", handler, h);
return FALSE;
+ }
+
+ DBG("handler for type %u was success", h);
entries[h].pos = i;
entries[h].flags |= HEADER_FLAG_MARKED;
@@ -672,8 +812,10 @@ static gboolean mms_parse_headers(struct wsp_header_iter *iter,
for (i = 0; i < __MMS_HEADER_MAX + 1; i++) {
if ((entries[i].flags & HEADER_FLAG_MANDATORY) &&
- !(entries[i].flags & HEADER_FLAG_MARKED))
+ !(entries[i].flags & HEADER_FLAG_MARKED)) {
+ DBG("header %u was mandatory but not marked", i);
return FALSE;
+ }
}
/*
@@ -704,8 +846,10 @@ static gboolean mms_parse_headers(struct wsp_header_iter *iter,
va_end(args);
- if (entries[i].pos != expected_pos)
+ if (entries[i].pos != expected_pos) {
+ DBG("header %u was in position %u but expected in position %u", i, entries[i].pos, expected_pos);
return FALSE;
+ }
}
return TRUE;
@@ -770,6 +914,7 @@ static gboolean extract_content_id(struct wsp_header_iter *iter, void *user)
return FALSE;
*out = g_strdup(text);
+ DBG("extracted content-id %s\n", *out);
return TRUE;
}
@@ -991,11 +1136,17 @@ gboolean mms_message_decode(const unsigned char *pdu,
flags |= WSP_HEADER_ITER_FLAG_DETECT_MMS_MULTIPART;
wsp_header_iter_init(&iter, pdu, len, flags);
+ DBG("about to check well known");
+
CHECK_WELL_KNOWN_HDR(MMS_HEADER_MESSAGE_TYPE);
+ DBG("about to extract short");
+
if (extract_short(&iter, &octet) == FALSE)
return FALSE;
+ DBG("octet %u", octet);
+
if (octet < MMS_MESSAGE_TYPE_SEND_REQ ||
octet > MMS_MESSAGE_TYPE_DELIVERY_IND)
return FALSE;
@@ -1422,6 +1573,12 @@ static header_encoder encoder_for_type(enum mms_header header)
return NULL;
case MMS_HEADER_RESPONSE_TEXT:
return NULL;
+ case MMS_HEADER_RETRIEVE_STATUS:
+ return NULL;
+ case MMS_HEADER_RETRIEVE_TEXT:
+ return NULL;
+ case MMS_HEADER_READ_STATUS:
+ return NULL;
case MMS_HEADER_SENDER_VISIBILITY:
return NULL;
case MMS_HEADER_STATUS:
diff --git a/src/mmsutil.h b/src/mmsutil.h
index e32c76142d39e9393b974ed1ab6bcf74416a7797..00ecc3944771c2af761213b4442edd432bc2e40d 100644
--- a/src/mmsutil.h
+++ b/src/mmsutil.h
@@ -50,6 +50,23 @@ enum mms_message_rsp_status {
MMS_MESSAGE_RSP_STATUS_ERR_PERM_LACK_OF_PREPAID = 235,
};
+enum mms_message_retr_status {
+ MMS_MESSAGE_RETR_STATUS_OK = 128,
+ MMS_MESSAGE_RETR_STATUS_ERR_TRANS_MIN = 192,
+ MMS_MESSAGE_RETR_STATUS_ERR_TRANS_FAILURE = 192,
+ MMS_MESSAGE_RETR_STATUS_ERR_TRANS_MESSAGE_NOT_FOUND = 194,
+ MMS_MESSAGE_RETR_STATUS_ERR_PERM_MIN = 224,
+ MMS_MESSAGE_RETR_STATUS_ERR_PERM_FAILURE = 224,
+ MMS_MESSAGE_RETR_STATUS_ERR_PERM_SERVICE_DENIED = 225,
+ MMS_MESSAGE_RETR_STATUS_ERR_PERM_MESSAGE_NOT_FOUND = 226,
+ MMS_MESSAGE_RETR_STATUS_ERR_PERM_CONTENT_UNSUPPORTED = 227,
+};
+
+enum mms_message_read_status {
+ MMS_MESSAGE_READ_STATUS_READ = 128,
+ MMS_MESSAGE_READ_STATUS_DELETED_UNREAD = 129,
+};
+
enum mms_message_notify_status {
MMS_MESSAGE_NOTIFY_STATUS_RETRIEVED = 129,
MMS_MESSAGE_NOTIFY_STATUS_REJECTED = 130,
diff --git a/src/service.c b/src/service.c
index b3ecc1e4202c6ebefb0ee92bf7aa0da3f624155c..e5bde351556a08b9fbc0db9488fd929413bc07d8 100644
--- a/src/service.c
+++ b/src/service.c
@@ -609,7 +609,7 @@ static void emit_message_added(const struct mms_service *service,
static void activate_bearer(struct mms_service *service)
{
- DBG("service %p", service);
+ DBG("service %p setup %d active %d", service, service->bearer_setup, service->bearer_active);
if (service->bearer_setup == TRUE)
return;
@@ -622,7 +622,7 @@ static void activate_bearer(struct mms_service *service)
if (service->bearer_handler == NULL)
return;
- DBG("service %p", service);
+ DBG("service %p waiting for %d seconds", service, BEARER_SETUP_TIMEOUT);
service->bearer_setup = TRUE;
@@ -736,9 +736,12 @@ static DBusMessage *get_messages(DBusConnection *conn,
GHashTableIter table_iter;
gpointer key, value;
+ DBG("");
+
reply = dbus_message_new_method_return(dbus_msg);
if (reply == NULL)
return NULL;
+ //return reply;
dbus_message_iter_init_append(reply, &iter);
@@ -1632,6 +1635,7 @@ static void append_attachment_properties(struct mms_attachment *part,
dbus_message_iter_open_container(part_array, DBUS_TYPE_STRUCT,
NULL, &entry);
+ DBG("content-id: %s\n", part->content_id);
dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING,
&part->content_id);
dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING,
@@ -1793,7 +1797,7 @@ static void append_msg_recipients(DBusMessageIter *dict,
for (i = 0; tokens[i] != NULL; i++) {
rcpt = mms_address_to_string(tokens[i]);
-
+ DBG("rcpt=%s", rcpt);
dbus_message_iter_append_basic(&array, DBUS_TYPE_STRING, &rcpt);
}
@@ -1814,25 +1818,31 @@ static void append_rc_msg_properties(DBusMessageIter *dict,
const char *from_prefix;
char *from;
+ DBG("status=%s", status);
mms_dbus_dict_append_basic(dict, "Status",
DBUS_TYPE_STRING, &status);
+ DBG("date=%s", date);
mms_dbus_dict_append_basic(dict, "Date",
DBUS_TYPE_STRING, &date);
+ DBG("subject=%s", msg->rc.subject);
if (msg->rc.subject != NULL)
mms_dbus_dict_append_basic(dict, "Subject",
DBUS_TYPE_STRING, &msg->rc.subject);
+ DBG("from=%s", msg->rc.from);
from = g_strdup(msg->rc.from);
if (from != NULL) {
from_prefix = mms_address_to_string(from);
+ DBG("from_pfx=%s", from_prefix);
mms_dbus_dict_append_basic(dict, "Sender",
DBUS_TYPE_STRING, &from_prefix);
g_free(from);
}
+ DBG("to=%s", msg->rc.to);
if (msg->rc.to != NULL)
append_msg_recipients(dict, msg);
}
@@ -1862,6 +1872,8 @@ static void append_message(const char *path, const struct mms_service *service,
mms_dbus_dict_open(iter, &dict);
+ DBG("type=%d", msg->type);
+
switch (msg->type) {
case MMS_MESSAGE_TYPE_SEND_REQ:
append_sr_msg_properties(&dict, msg);
@@ -1873,7 +1885,7 @@ static void append_message(const char *path, const struct mms_service *service,
case MMS_MESSAGE_TYPE_NOTIFYRESP_IND:
break;
case MMS_MESSAGE_TYPE_RETRIEVE_CONF:
- append_rc_msg_properties(&dict, msg);
+ append_rc_msg_properties(&dict, msg); /* causes dbus disconnect! */
break;
case MMS_MESSAGE_TYPE_ACKNOWLEDGE_IND:
break;
@@ -1884,6 +1896,7 @@ static void append_message(const char *path, const struct mms_service *service,
if (msg->attachments != NULL) {
char *pdu_path = mms_store_get_path(service->identity,
msg->uuid);
+ DBG("appending pdu path %s", pdu_path);
append_msg_attachments(&dict, pdu_path, msg);
g_free(pdu_path);
}
@@ -2059,8 +2072,10 @@ static gboolean result_request_notify_resp(struct mms_request *request)
return FALSE;
}
- if (request->msg == NULL)
+ if (request->msg == NULL) {
+ mms_error("POST m.notify.resp.ind provided no message to register");
return FALSE;
+ }
msg = mms_request_steal_message(request);
@@ -2210,6 +2225,9 @@ static gboolean web_get_cb(GWebResult *result, gpointer user_data)
complete:
close(request->fd);
+ DBG("request->result_cb=%p vs. retrieve_conf=%p/send_conf=%p/notify_resp=%p",
+ request->result_cb, result_request_retrieve_conf, result_request_send_conf, result_request_notify_resp);
+
if (request->result_cb == NULL || request->result_cb(request) == TRUE)
mms_request_destroy(request);
else {
@@ -2378,25 +2396,37 @@ void mms_service_push_notify(struct mms_service *service,
return;
}
+ DBG("about to push notify");
+
if (mms_push_notify(data, len, &nread) == FALSE)
goto out;
+ DBG("did push notify; about to store");
+
uuid = mms_store(service->identity, data + nread, len - nread);
if (uuid == NULL)
goto out;
+ DBG("did store; about to decode");
+
if (mms_message_decode(data + nread, len - nread, msg) == FALSE)
goto error;
+ DBG("did decode message");
+
if (msg->type == MMS_MESSAGE_TYPE_DELIVERY_IND) {
msg->uuid = g_strdup(uuid);
dump_delivery_ind(msg);
+ DBG("about to store_meta_open");
+
meta = mms_store_meta_open(service->identity, uuid);
if (meta == NULL)
goto error;
+ DBG("did store_meta_open");
+
g_key_file_set_string(meta, "info", "state", "notification");
mms_store_meta_close(service->identity, uuid, meta, TRUE);
@@ -2404,17 +2434,25 @@ void mms_service_push_notify(struct mms_service *service,
return;
}
+ DBG("is type NI?");
+
if (msg->type != MMS_MESSAGE_TYPE_NOTIFICATION_IND)
goto error;
+ DBG("type is NI");
+
msg->uuid = g_strdup(uuid);
dump_notification_ind(msg);
+ DBG("about to store_meta_open 2");
+
meta = mms_store_meta_open(service->identity, uuid);
if (meta == NULL)
goto error;
+ DBG("did store_meta_open 2");
+
g_key_file_set_boolean(meta, "info", "read", FALSE);
g_key_file_set_string(meta, "info", "state", "notification");
@@ -2427,6 +2465,8 @@ void mms_service_push_notify(struct mms_service *service,
if (request == NULL)
goto out;
+ DBG("did create_request");
+
g_queue_push_tail(service->request_queue, request);
activate_bearer(service);
@@ -2442,12 +2482,16 @@ out:
mms_error("Failed to handle incoming notification");
}
+void debug_print(const char* s, void* data) {
+ printf("%s\n", s);
+}
+
void mms_service_bearer_notify(struct mms_service *service, mms_bool_t active,
const char *interface, const char *proxy)
{
int ifindex;
- DBG("service %p active %d", service, active);
+ DBG("service=%p active=%d iface=%s proxy=%s", service, active, interface, proxy);
if (service == NULL)
return;
@@ -2460,8 +2504,12 @@ void mms_service_bearer_notify(struct mms_service *service, mms_bool_t active,
service->bearer_setup = FALSE;
service->bearer_active = active;
- if (active == FALSE)
- goto interface_down;
+ if (active == FALSE) {
+ DBG("ignoring inactive");
+ service->bearer_active = TRUE;
+ interface = g_strdup("wwan0");
+ //goto interface_down;
+ }
DBG("interface %s proxy %s", interface, proxy);
@@ -2481,6 +2529,8 @@ void mms_service_bearer_notify(struct mms_service *service, mms_bool_t active,
if (service->web == NULL)
return;
+ g_web_set_debug(service->web, (GWebDebugFunc)debug_print, NULL);
+
/* Sometimes no proxy is reported as string instead of NULL */
if (g_strcmp0(proxy, "") != 0)
g_web_set_proxy(service->web, proxy);
diff --git a/test/send-message b/test/send-message
index 558fdaa3fb563e826cd07d14aeaf067ef71c446f..8477e79ec452a93b23e6c48cc8c71a505321c76f 100755
--- a/test/send-message
+++ b/test/send-message
@@ -5,23 +5,23 @@ import dbus
import csv
if (len(sys.argv) < 4):
- print "Usage: %s"\
+ print("Usage: {}"\
" <recipient>,..."\
" <smil-file-path>"\
" <<content-id>,<content-type>,<file-path>>,..."\
- % (sys.argv[0])
- print "Sample(Related): %s"\
+ .format(sys.argv[0]))
+ print("Sample(Related): {}"\
" \"+33611111111,+33622222222\""\
" \"smil.txt\""\
" \"cid-1,text/plain,text.txt\""\
" \"cid-2,image/jpeg,image.jpg\""\
- % (sys.argv[0])
- print "Sample(Mixed): %s"\
+ .format(sys.argv[0]))
+ print("Sample(Mixed): {}"\
" \"+33611111111,+33622222222\""\
" \"\""\
" \"cid-1,text/plain,text.txt\""\
" \"cid-2,image/jpeg,image.jpg\""\
- % (sys.argv[0])
+ .format(sys.argv[0]))
sys.exit(1)
bus = dbus.SessionBus()
@@ -38,23 +38,23 @@ service = dbus.Interface(bus.get_object('org.ofono.mms', path),
recipients = dbus.Array([],signature=dbus.Signature('s'))
reader = csv.reader([sys.argv[1]])
for r in reader:
- print "Recipient list: %s" % r
+ print("Recipient list: {}".format(r))
for i in r:
recipients.append(dbus.String(i))
if sys.argv[2] == "":
- print "Send MMS as Mixed"
+ print("Send MMS as Mixed")
smil = ""
else:
- print "Send MMS as Related"
- print "Smil path: %s" % (sys.argv[2])
+ print("Send MMS as Related")
+ print("Smil path: {}".format(sys.argv[2]))
file = open(sys.argv[2],"r")
smil = dbus.String(file.read())
attachments = dbus.Array([],signature=dbus.Signature('(sss)'))
for a in sys.argv[3:]:
- print "Attachment: (%s)" % a
+ print("Attachment: ({})".format(a))
reader = csv.reader([a])
for r in reader:
attachments.append(dbus.Struct((dbus.String(r[0]),
@@ -64,4 +64,4 @@ for a in sys.argv[3:]:
path = service.SendMessage(recipients, smil, attachments)
-print path
+print(path)
-------------END TMOBILE PATCH-----------------------------
reply other threads:[~2021-02-18 19:01 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20210218190113.2937.66552@ml01.vlan13.01.org \
--to=ofono@market.talbothome.com \
--cc=ofono@ofono.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).