netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/9] Updates for mmsd
@ 2021-04-10 14:13 Chris Talbot
  2021-04-10 14:17 ` [PATCH 1/9] Fix mmsd to work with T-mobile Chris Talbot
  2021-04-14 18:21 ` Forking on MMSD Chris Talbot
  0 siblings, 2 replies; 19+ messages in thread
From: Chris Talbot @ 2021-04-10 14:13 UTC (permalink / raw)
  To: ofono, netdev, debian-on-mobile-maintainers, librem-5-dev

Hello,

I am submitting a series of patches for mmsd that I have been working
on. The patches have been successfully tested on PostmarketOS, Debian
on Mobile (Mobian), PureOS, and Fedora.

The patches fall into two catagories:
1) core fixes to mmsd to get it to work with several carriers
(including T-Mobile USA, AT&T USA, Telus Canada, and a Swedish
Carrier). 
2) A new plugin to enable mmsd functionality on Modem Manager. 

The Patches have been tested on both the Pinephone and the Librem 5,
and have been confirmed tested accross all major US carriers (as well
as several minor US carriers), Canadian carriers, French carriers, and
Swedish carriers. They been been likely tested on more carriers, but
the author can only confirm the above ones (as he has gotten positive
feedback for them).

-- 
Respectfully,
Chris Talbot


^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH 1/9] Fix mmsd to work with T-mobile
  2021-04-10 14:13 [PATCH 0/9] Updates for mmsd Chris Talbot
@ 2021-04-10 14:17 ` Chris Talbot
  2021-04-10 14:20   ` [PATCH 2/9] Ensure Compatibility with Telus Canada Chris Talbot
  2021-04-14 18:21 ` Forking on MMSD Chris Talbot
  1 sibling, 1 reply; 19+ messages in thread
From: Chris Talbot @ 2021-04-10 14:17 UTC (permalink / raw)
  To: ofono, netdev, debian-on-mobile-maintainers, librem-5-dev

This patch is a squashed version of a series of patches here:

https://git.sr.ht/~anteater/mmsd

It also includes some fixes to a few hacks in the code. Rather than
submit two patches that need to go together, I just squashed it into
one commit.
---
 Makefile.am       |   3 +-
 gweb/gresolv.c    |  73 ++++++++++++++-
 gweb/gweb.c       |   1 +
 plugins/ofono.c   |  11 ++-
 src/mmsutil.c     | 233 ++++++++++++++++++++++++++++++++++++++--------
 src/mmsutil.h     |  17 ++++
 src/service.c     |  58 ++++++++++--
 test/send-message |  24 ++---
 8 files changed, 356 insertions(+), 64 deletions(-)

diff --git a/Makefile.am b/Makefile.am
index ee2c715..99fdb76 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 79abc9b..bb1c32d 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 4c2f95c..f72e137 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 e7324a7..24a147a 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 a9a12eb..5fcf358 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 at 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 e32c761..00ecc39 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 b3ecc1e..c7ef255 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,6 +736,8 @@ 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;
@@ -1632,6 +1634,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 +1796,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 +1817,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 +1871,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 +1884,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 +1895,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 +2071,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 +2224,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 +2395,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 +2433,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 +2464,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 +2481,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;
@@ -2463,6 +2506,7 @@ void mms_service_bearer_notify(struct mms_service
*service, mms_bool_t active,
 	if (active == FALSE)
 		goto interface_down;
 
+
 	DBG("interface %s proxy %s", interface, proxy);
 
 	if (service->web != NULL) {
@@ -2481,6 +2525,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 558fdaa..8477e79 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)
-- 
2.30.2



^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 2/9] Ensure Compatibility with Telus Canada
  2021-04-10 14:17 ` [PATCH 1/9] Fix mmsd to work with T-mobile Chris Talbot
@ 2021-04-10 14:20   ` Chris Talbot
  2021-04-10 14:20     ` [PATCH 3/9] Ensure Compatibility with AT&T Chris Talbot
  0 siblings, 1 reply; 19+ messages in thread
From: Chris Talbot @ 2021-04-10 14:20 UTC (permalink / raw)
  To: ofono, netdev, debian-on-mobile-maintainers, librem-5-dev

Telus Canada makes mmsd decode a header that is not in the standard.
This patch allows this header to be decoded and allows for MMS support
in Telus Canada.
---
 src/mmsutil.c | 16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/src/mmsutil.c b/src/mmsutil.c
index 5fcf358..9430bf1 100644
--- a/src/mmsutil.c
+++ b/src/mmsutil.c
@@ -732,10 +732,9 @@ static header_handler handler_for_type(enum
mms_header header)
 		return extract_text;
 	case MMS_HEADER_INVALID:
 	case __MMS_HEADER_MAX:
+	default:
 		return NULL;
 	}
-
-	return NULL;
 }
 
 struct header_handler_entry {
@@ -781,8 +780,17 @@ static gboolean mms_parse_headers(struct
wsp_header_iter *iter,
 
 		handler = handler_for_type(h);
 		if (handler == NULL) {
-			DBG("no handler for type %u", h);
-			return FALSE;
+			if(h == MMS_HEADER_INVALID) {
+				DBG("no handler for type %u", h);
+				return FALSE;
+			} else if (h == __MMS_HEADER_MAX) {
+				DBG("no handler for type %u", h);
+				return FALSE;
+			} else {
+				/*  Telus has strange headers, so this
handles it */
+				DBG("type isn't a part of the
standard? Skipping %u", h);
+				continue;
+			}
 		}
 
 		DBG("saw header of type %u", h);
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 3/9] Ensure Compatibility with AT&T
  2021-04-10 14:20   ` [PATCH 2/9] Ensure Compatibility with Telus Canada Chris Talbot
@ 2021-04-10 14:20     ` Chris Talbot
  2021-04-10 14:21       ` [PATCH 4/9] Fix issue if there is an empty string in encoded text Chris Talbot
  0 siblings, 1 reply; 19+ messages in thread
From: Chris Talbot @ 2021-04-10 14:20 UTC (permalink / raw)
  To: ofono, netdev, debian-on-mobile-maintainers, librem-5-dev

This patch fixes two issues to ensure compatibility with AT&T:
1) Explicity close connections to the mmsc
2) Allow MMS Proxies that are domain names
---
 gweb/gweb.c   | 3 ++-
 src/service.c | 3 +++
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/gweb/gweb.c b/gweb/gweb.c
index f72e137..995d12f 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 c7ef255..a3b90c5 100644
--- a/src/service.c
+++ b/src/service.c
@@ -2527,6 +2527,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);
-- 
2.30.2



^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 4/9] Fix issue if there is an empty string in encoded text
  2021-04-10 14:20     ` [PATCH 3/9] Ensure Compatibility with AT&T Chris Talbot
@ 2021-04-10 14:21       ` Chris Talbot
  2021-04-10 14:22         ` [PATCH 5/9] Allow for a user configurable maximum attachment size Chris Talbot
  0 siblings, 1 reply; 19+ messages in thread
From: Chris Talbot @ 2021-04-10 14:21 UTC (permalink / raw)
  To: ofono, netdev, debian-on-mobile-maintainers, librem-5-dev

A swedish carrier sends an empty string in the subject line. This
patch allows mmsd to handle it
---
 src/mmsutil.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/src/mmsutil.c b/src/mmsutil.c
index 9430bf1..615198f 100644
--- a/src/mmsutil.c
+++ b/src/mmsutil.c
@@ -297,6 +297,13 @@ static gboolean extract_encoded_text(struct
wsp_header_iter *iter, void *user)
 	p = wsp_header_iter_get_val(iter);
 	l = wsp_header_iter_get_val_len(iter);
 
+	if(l == 0) {
+		DBG("Length is 0! Returning empty string");
+		dec_text = g_strdup("");
+		*out = dec_text;
+		return TRUE;
+	}
+
 	switch (wsp_header_iter_get_val_type(iter)) {
 	case WSP_VALUE_TYPE_TEXT:
 		/* Text-string */
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 5/9] Allow for a user configurable maximum attachment size
  2021-04-10 14:21       ` [PATCH 4/9] Fix issue if there is an empty string in encoded text Chris Talbot
@ 2021-04-10 14:22         ` Chris Talbot
  2021-04-10 14:22           ` [PATCH 6/9] Update README Chris Talbot
  0 siblings, 1 reply; 19+ messages in thread
From: Chris Talbot @ 2021-04-10 14:22 UTC (permalink / raw)
  To: ofono, netdev, debian-on-mobile-maintainers, librem-5-dev

Android and iOS enforce a maximum attachment size for MMS messages.
This patch enforces a maximum attachment size for MMS messages and
makes it user configurable.

The Default maximum size is based off of Android, which has a maximum
MMS size of 1.1 Megabytes
---
 src/service.c | 38 ++++++++++++++++++++++++++++++++++----
 1 file changed, 34 insertions(+), 4 deletions(-)

diff --git a/src/service.c b/src/service.c
index a3b90c5..dede36d 100644
--- a/src/service.c
+++ b/src/service.c
@@ -56,6 +56,7 @@
 
 #define MAX_ATTACHMENTS_NUMBER 25
 #define MAX_ATTEMPTS 3
+#define DEFAULT_MAX_ATTACHMENT_TOTAL_SIZE 1100000
 
 #define SETTINGS_STORE "mms"
 #define SETTINGS_GROUP "Settings"
@@ -100,6 +101,7 @@ struct mms_service {
 	GHashTable *messages;
 	GKeyFile *settings;
 	gboolean use_delivery_reports;
+	int max_attach_total_size;
 };
 
 enum mms_request_type {
@@ -146,7 +148,22 @@ static void mms_load_settings(struct mms_service
*service)
 		g_key_file_set_boolean(service->settings,
SETTINGS_GROUP,
 						"UseDeliveryReports",
 						service-
>use_delivery_reports);
+		error = NULL;
 	}
+
+	service->max_attach_total_size =
+		g_key_file_get_integer(service->settings,
SETTINGS_GROUP,
+						"TotalMaxAttachmentSiz
e", &error);
+
+	if (error) {
+		g_error_free(error);
+		service->max_attach_total_size =
DEFAULT_MAX_ATTACHMENT_TOTAL_SIZE;
+		g_key_file_set_integer(service->settings,
SETTINGS_GROUP,
+						"TotalMaxAttachmentSiz
e",
+						service-
>max_attach_total_size);
+	}
+	mms_debug("Maximum Attachment Total Size (in bytes): %d",
service->max_attach_total_size);
+
 }
 
 static void mms_request_destroy(struct mms_request *request)
@@ -414,10 +431,11 @@ static gboolean
send_message_get_recipients(DBusMessageIter *top_iter,
 }
 
 static gboolean send_message_get_attachments(DBusMessageIter
*top_iter,
-						struct mms_message
*msg)
+						struct mms_message
*msg, struct mms_service *service)
 {
 	DBusMessageIter attachments;
 	unsigned int attach_num = 0;
+	int attach_total_size = 0;
 
 	dbus_message_iter_recurse(top_iter, &attachments);
 
@@ -430,8 +448,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 +486,16 @@ 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);
+		mms_debug("Maximum Attachment Total Size (in bytes):
%d", service->max_attach_total_size);
+
+		if (attach_total_size > service-
>max_attach_total_size) {
+			mms_error("Error: Total Attachment size too
large!");
+			return FALSE;
+		}
+
 		attach->data = ptr;
 
 		attach->content_id = g_strdup(id);
@@ -490,7 +520,7 @@ static gboolean
send_message_get_attachments(DBusMessageIter *top_iter,
 }
 
 static gboolean send_message_get_args(DBusMessage *dbus_msg,
-						struct mms_message
*msg)
+						struct mms_message
*msg, struct mms_service *service)
 {
 	DBusMessageIter top_iter;
 	const char *smil;
@@ -536,7 +566,7 @@ static gboolean send_message_get_args(DBusMessage
*dbus_msg,
 	if (dbus_message_iter_get_arg_type(&top_iter) !=
DBUS_TYPE_ARRAY)
 		return FALSE;
 
-	return send_message_get_attachments(&top_iter, msg);
+	return send_message_get_attachments(&top_iter, msg, service);
 }
 
 static struct mms_request *create_request(enum mms_request_type type,
-- 
2.30.2



^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 6/9] Update README
  2021-04-10 14:22         ` [PATCH 5/9] Allow for a user configurable maximum attachment size Chris Talbot
@ 2021-04-10 14:22           ` Chris Talbot
  2021-04-10 14:23             ` [PATCH 7/9] Fix Draft and Sent Bugs Chris Talbot
  0 siblings, 1 reply; 19+ messages in thread
From: Chris Talbot @ 2021-04-10 14:22 UTC (permalink / raw)
  To: ofono, netdev, debian-on-mobile-maintainers, librem-5-dev

This updates the README for mmsd
---
 README | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 61 insertions(+), 5 deletions(-)

diff --git a/README b/README
index e33be69..cecc99f 100644
--- a/README
+++ b/README
@@ -2,20 +2,76 @@ Multimedia Messaging Service
 ****************************
 
 Copyright (C) 2010-2011  Intel Corporation. All rights reserved.
+Updated 2021 by: Mohammad Sadiq, kent, kop316, 
+                 fuzzy7k, craftyguy, anteater
+Parts adapted from: https://source.puri.sm/Librem5/purple-mm-sms
+                    Copyright (C) 2018 Purism SPC
+                    
+About
+===========================
+mmsd is a lower level daemon that transmits and recieves MMSes. It
works with
+both the ofono stack and the Modem Manager stack.
 
+Please note that mmsd alone will not get MMS working! It is designed
to work 
+with a higher level chat application to facilitate fetching and 
+sending MMS. It interfaces with other applications via the dbus.
 
-Compilation and installation
+Compiling mmsd
 ============================
-
 In order to compile proxy daemon you need following software packages:
 	- GCC compiler
 	- D-Bus library
 	- GLib library
 
+Installing mmsd
+============================
+
 To configure run:
-	./configure --prefix=/usr
+    ./bootstrap-configure --prefix=/usr/
 
 Configure automatically searches for all required components and
packages.
 
-To compile and install run:
-	make && make install
+To compile, run:
+    make
+	
+And to Install:
+    make install
+
+mmsd will be installed in /${prefix}/libexec (if you are following
this guide,
+it is /usr/libexec )
+
+To uninstall, simply remove the "mmsd" binary from /${prefix}/libexec
or run:
+    sudo make uninstall
+
+Note that you must manually configure your favorite service manager to
run 
+the daemon, as this installer does not configure it to autorun.
+
+Testing out mmsd
+===========================
+To configure, run:
+    ./bootstrap-configure --enable-debug --enable-maintainer-mode
+
+Make it:
+    make 
+
+Run daemon in foreground with debugging:
+    ./src/mmsd -n -d 'src/*'
+
+General Configuration
+===========================
+On first run, mmsd will write a settings file at
+"$HOME/.mms/$PLUGIN/mms"
+
+IMPORTANT NOTE: If you change settings in this file, mmsd MUST BE
RESTARTED 
+                for the changes to take effect!
+
+This settings file use sane defaults, but you can change them:
+
+UseDeliveryReports
+        Whether you want delivery reports for MMSes you send
+
+TotalMaxAttachmentSize
+        The maximum size all of your attachments can be before mmsd
rejects it.
+        NOTE: This value is carrier specific! Changing this value to a
higher
+              number may cause your carrier to silently reject MMSes
you send.
+              CHANGE AT YOUR OWN RISK!
\ No newline at end of file
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 7/9] Fix Draft and Sent Bugs
  2021-04-10 14:22           ` [PATCH 6/9] Update README Chris Talbot
@ 2021-04-10 14:23             ` Chris Talbot
  2021-04-10 14:23               ` [PATCH 8/9] Allow Maintainer mode to compile without -WError Chris Talbot
  0 siblings, 1 reply; 19+ messages in thread
From: Chris Talbot @ 2021-04-10 14:23 UTC (permalink / raw)
  To: ofono, netdev, debian-on-mobile-maintainers, librem-5-dev

This patch fixes a few bugs:
- Makes sure "sent" has an accurate time
- Allows "Draft" to Go to "Sent" on the dbus
- Allows the time to be preserved if mmsd is closed and opened
---
 src/mmsutil.h |  2 ++
 src/service.c | 60 +++++++++++++++++++++++++++++++++++++++------------
 2 files changed, 48 insertions(+), 14 deletions(-)

diff --git a/src/mmsutil.h b/src/mmsutil.h
index 00ecc39..ec139f1 100644
--- a/src/mmsutil.h
+++ b/src/mmsutil.h
@@ -120,12 +120,14 @@ struct mms_retrieve_conf {
 	char *priority;
 	char *msgid;
 	time_t date;
+ 	char *datestamp;
 };
 
 struct mms_send_req {
 	enum mms_message_status status;
 	char *to;
 	time_t date;
+ 	char *datestamp;
 	char *content_type;
 	gboolean dr;
 };
diff --git a/src/service.c b/src/service.c
index dede36d..b0c2428 100644
--- a/src/service.c
+++ b/src/service.c
@@ -18,6 +18,7 @@
  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-
1301  USA
  *
  */
+#define _XOPEN_SOURCE 700
 
 #ifdef HAVE_CONFIG_H
 #include <config.h>
@@ -35,6 +36,8 @@
 #include <glib.h>
 #include <glib/gstdio.h>
 #include <gdbus.h>
+#include <time.h>
+#include <stdio.h>
 
 #include <gweb/gweb.h>
 
@@ -129,6 +132,11 @@ static DBusConnection *connection;
 
 static guint32 transaction_id_start = 0;
 
+
+static const char *time_to_str(const time_t *t);
+void debug_print(const char* s, void* data);
+
+
 static void mms_load_settings(struct mms_service *service)
 {
 	GError *error;
@@ -220,6 +228,7 @@ static void emit_msg_status_changed(const char
*path, const char *new_status)
 
 	signal = dbus_message_new_signal(path, MMS_MESSAGE_INTERFACE,
							"PropertyChanged");
+							
 	if (signal == NULL)
 		return;
 
@@ -269,6 +278,7 @@ static DBusMessage *msg_mark_read(DBusConnection
*conn,
 	g_free(state);
 
 	g_key_file_set_boolean(meta, "info", "read", TRUE);
+	mms->rc.status = MMS_MESSAGE_STATUS_READ;
 
 	mms_store_meta_close(service->identity, mms->uuid, meta,
TRUE);
 
@@ -722,6 +732,7 @@ static gboolean result_request_send_conf(struct
mms_request *request)
 
 	g_key_file_set_string(meta, "info", "state", "sent");
 	g_key_file_set_string(meta, "info", "id", msg->sc.msgid);
+	request->msg->sr.status = MMS_MESSAGE_STATUS_SENT;
 
 	mms_message_free(msg);
 
@@ -1047,6 +1058,7 @@ static DBusMessage *send_message(DBusConnection
*conn,
 	struct mms_service *service = data;
 	struct mms_request *request;
 	GKeyFile *meta;
+	const char *datestr;
 
 	msg = g_new0(struct mms_message, 1);
 	if (msg == NULL)
@@ -1059,7 +1071,13 @@ static DBusMessage *send_message(DBusConnection
*conn,
 
 	msg->sr.dr = service->use_delivery_reports;
 
-	if (send_message_get_args(dbus_msg, msg) == FALSE) {
+	time(&msg->sr.date);
+
+	datestr = time_to_str(&msg->sr.date);
+
+	msg->sr.datestamp = g_strdup(datestr);
+
+	if (send_message_get_args(dbus_msg, msg, service) == FALSE) {
 		mms_debug("Invalid arguments");
 
 		release_attachement_data(msg->attachments);
@@ -1099,6 +1117,7 @@ static DBusMessage *send_message(DBusConnection
*conn,
 	if (meta == NULL)
 		goto release_request;
 
+	g_key_file_set_string(meta, "info", "date",  msg-
>sr.datestamp);
 	g_key_file_set_string(meta, "info", "state", "draft");
 
 	if (service->use_delivery_reports) {
@@ -1339,10 +1358,12 @@ static gboolean load_message_from_store(const
char *service_id,
 	char *state = NULL;
 	gboolean read_status;
 	char *data_path = NULL;
+	char *datestr = NULL;
 	gboolean success = FALSE;
 	gboolean tainted = FALSE;
 	void *pdu;
 	size_t len;
+	struct tm tm;
 
 	meta = mms_store_meta_open(service_id, uuid);
 	if (meta == NULL)
@@ -1354,6 +1375,13 @@ static gboolean load_message_from_store(const
char *service_id,
 
 	read_status = g_key_file_get_boolean(meta, "info", "read",
NULL);
 
+	datestr = g_key_file_get_string(meta, "info", "date", NULL);
+	if (datestr != NULL) {
+		strptime(datestr, "%Y-%m-%dT%H:%M:%S%z", &tm);
+	} else {
+		mms_error("src/service.c:load_message_from_store()
There is no date stamp!");
+	}
+    
 	data_path = mms_store_get_path(service_id, uuid);
 	if (data_path == NULL)
 		goto out;
@@ -1372,25 +1400,28 @@ static gboolean load_message_from_store(const
char *service_id,
 
 	msg->uuid = g_strdup(uuid);
 
-	if (strcmp(state, "received") == 0
-			&& msg->type ==
MMS_MESSAGE_TYPE_RETRIEVE_CONF) {
+	if (strcmp(state, "received") == 0 && msg->type ==
MMS_MESSAGE_TYPE_RETRIEVE_CONF) {
+        msg->rc.datestamp = g_strdup(datestr);
+        msg->rc.date = mktime(&tm);
 		if (read_status == TRUE)
 			msg->rc.status = MMS_MESSAGE_STATUS_READ;
 		else
 			msg->rc.status = MMS_MESSAGE_STATUS_RECEIVED;
-	} else if (strcmp(state, "downloaded") == 0
-			&& msg->type ==
MMS_MESSAGE_TYPE_RETRIEVE_CONF) {
+	} else if (strcmp(state, "downloaded") == 0 && msg->type ==
MMS_MESSAGE_TYPE_RETRIEVE_CONF) {
 		msg->rc.status = MMS_MESSAGE_STATUS_DOWNLOADED;
 		if (msg->transaction_id == NULL)
 			msg->transaction_id = "";
-	} else if (strcmp(state, "sent") == 0
-			&& msg->type == MMS_MESSAGE_TYPE_SEND_REQ)
+	} else if (strcmp(state, "sent") == 0 && msg->type ==
MMS_MESSAGE_TYPE_SEND_REQ) {
+        msg->sr.datestamp = g_strdup(datestr);
+        msg->sr.date = mktime(&tm);
 		msg->sr.status = MMS_MESSAGE_STATUS_SENT;
-	else if (strcmp(state, "draft") == 0
-			&& msg->type == MMS_MESSAGE_TYPE_SEND_REQ)
+    }
+	else if (strcmp(state, "draft") == 0 && msg->type ==
MMS_MESSAGE_TYPE_SEND_REQ) {
+        msg->sr.datestamp = g_strdup(datestr);
+        msg->sr.date = mktime(&tm);
 		msg->sr.status = MMS_MESSAGE_STATUS_DRAFT;
-	else if (msg->type != MMS_MESSAGE_TYPE_NOTIFICATION_IND &&
-			msg->type != MMS_MESSAGE_TYPE_DELIVERY_IND)
+    }
+	else if (msg->type != MMS_MESSAGE_TYPE_NOTIFICATION_IND &&
msg->type != MMS_MESSAGE_TYPE_DELIVERY_IND)
 		goto out;
 
 	success = TRUE;
@@ -1879,14 +1910,13 @@ static void
append_rc_msg_properties(DBusMessageIter *dict,
 static void append_sr_msg_properties(DBusMessageIter *dict,
 					struct mms_message *msg)
 {
-	const char *date = time_to_str(&msg->rc.date);
 	const char *status = mms_message_status_get_string(msg-
>sr.status);
 
 	mms_dbus_dict_append_basic(dict, "Status",
 					DBUS_TYPE_STRING, &status);
 
 	mms_dbus_dict_append_basic(dict, "Date",
-					DBUS_TYPE_STRING,  &date);
+					DBUS_TYPE_STRING,  &msg-
>sr.datestamp);
 
 	if (msg->sr.to != NULL)
 		append_msg_recipients(dict, msg);
@@ -2120,6 +2150,9 @@ static gboolean result_request_notify_resp(struct
mms_request *request)
 	if (meta == NULL)
 		return FALSE;
 
+    const char *datestr = time_to_str(&msg->rc.date);
+    msg->rc.datestamp = g_strdup(datestr);
+    g_key_file_set_string(meta, "info", "date",  msg->rc.datestamp);
 	g_key_file_set_string(meta, "info", "state", "received");
 
 	mms_store_meta_close(request->service->identity,
@@ -2536,7 +2569,6 @@ void mms_service_bearer_notify(struct mms_service
*service, mms_bool_t active,
 	if (active == FALSE)
 		goto interface_down;
 
-
 	DBG("interface %s proxy %s", interface, proxy);
 
 	if (service->web != NULL) {
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 8/9] Allow Maintainer mode to compile without -WError
  2021-04-10 14:23             ` [PATCH 7/9] Fix Draft and Sent Bugs Chris Talbot
@ 2021-04-10 14:23               ` Chris Talbot
  2021-04-10 14:24                 ` [PATCH 9/9] Enable support for Modem Manager Chris Talbot
  0 siblings, 1 reply; 19+ messages in thread
From: Chris Talbot @ 2021-04-10 14:23 UTC (permalink / raw)
  To: ofono, netdev, debian-on-mobile-maintainers, librem-5-dev

This patch allows mmsd to compile.

---
 acinclude.m4 | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/acinclude.m4 b/acinclude.m4
index 329c6a9..314dbb1 100644
--- a/acinclude.m4
+++ b/acinclude.m4
@@ -15,7 +15,7 @@ AC_DEFUN([COMPILER_FLAGS], [
 		CFLAGS="-Wall -O2 -D_FORTIFY_SOURCE=2"
 	fi
 	if (test "$USE_MAINTAINER_MODE" = "yes"); then
-		CFLAGS+=" -Werror -Wextra"
+		CFLAGS+=" -Wextra"
 		CFLAGS+=" -Wno-unused-parameter"
 		CFLAGS+=" -Wno-missing-field-initializers"
 		CFLAGS+=" -Wdeclaration-after-statement"
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 9/9] Enable support for Modem Manager
  2021-04-10 14:23               ` [PATCH 8/9] Allow Maintainer mode to compile without -WError Chris Talbot
@ 2021-04-10 14:24                 ` Chris Talbot
  0 siblings, 0 replies; 19+ messages in thread
From: Chris Talbot @ 2021-04-10 14:24 UTC (permalink / raw)
  To: ofono, netdev, debian-on-mobile-maintainers, librem-5-dev

This commit enables mmsd support for Modem Manager. The support has
been well tested across at all major US carriers, as well as Canadia,
Sweden, and French carriers (more have likely beentested, but these
have been confirmed).

The commit automatically searches for SMS WAPs on Modem Manager, and
monitors the modem manager connectivity, giving a full transparent
abtraction for MMS sending and recieving.
---
 Makefile.am               |    8 +-
 README                    |  107 +++-
 configure.ac              |    5 +
 doc/modem-manager-api.txt |  102 ++++
 plugins/modemmanager.c    | 1179 +++++++++++++++++++++++++++++++++++++
 src/service.c             |    3 +-
 src/service.h             |    2 +
 7 files changed, 1400 insertions(+), 6 deletions(-)
 create mode 100644 doc/modem-manager-api.txt
 create mode 100644 plugins/modemmanager.c

diff --git a/Makefile.am b/Makefile.am
index 99fdb76..ecca9d8 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -12,8 +12,8 @@ builtin_sources =
 builtin_cflags =
 builtin_libadd =
 
-builtin_modules += ofono
-builtin_sources += plugins/ofono.c
+builtin_modules += ofono modemmanager
+builtin_sources += plugins/ofono.c plugins/modemmanager.c
 
 libexec_PROGRAMS = src/mmsd
 
@@ -24,7 +24,7 @@ src_mmsd_SOURCES = $(gdbus_sources) $(gweb_sources)
$(builtin_sources) \
 			src/push.h src/push.c src/store.h src/store.c
\
 			src/wsputil.h src/wsputil.c src/mmsutil.h
src/mmsutil.c
 
-src_mmsd_LDADD = $(builtin_libadd) @GLIB_LIBS@ @DBUS_LIBS@ -lresolv -
ldl
+src_mmsd_LDADD = $(builtin_libadd) @GLIB_LIBS@ @DBUS_LIBS@
@MMGLIB_LIBS@ -lresolv -ldl
 
 src_mmsd_LDFLAGS = -Wl,--export-dynamic
 
@@ -41,7 +41,7 @@ src/plugin.$(OBJEXT): src/builtin.h
 src/builtin.h: src/genbuiltin $(builtin_sources)
 	$(AM_V_GEN)$(srcdir)/src/genbuiltin $(builtin_modules) > $@
 
-AM_CFLAGS = @GLIB_CFLAGS@ @DBUS_CFLAGS@ $(builtin_cflags) \
+AM_CFLAGS = @GLIB_CFLAGS@ @DBUS_CFLAGS@ @MMGLIB_CFLAGS@
$(builtin_cflags) \
 					-DMMS_PLUGIN_BUILTIN \
 					-DPLUGINDIR=\""$(plugindir)"\"
\
 					-
DPUSHCONFDIR=\""$(pushconfdir)"\"
diff --git a/README b/README
index cecc99f..ff02121 100644
--- a/README
+++ b/README
@@ -16,12 +16,51 @@ Please note that mmsd alone will not get MMS
working! It is designed to work
 with a higher level chat application to facilitate fetching and 
 sending MMS. It interfaces with other applications via the dbus.
 
+A note about this repository
+===========================
+This repository is a fork of 
+https://git.kernel.org/pub/scm/network/ofono/mmsd.git
+
+and includes updates found here:
+https://git.sr.ht/~anteater/mmsd
+
+Commit f4b8b32477a411180be1823fdc460b4f7e1e3c9c from the master branch
+is synced with the latest updates from upstream.
+
+This fork includes a plugin to support Modem Manager in addition to
ofono, 
+patches to improve the core of mmsd, and packaging for Debian. This
author 
+has only tested this fork with Modem Manager, and primarily maintains 
+the Modem Manager plugin. However, the ofono plugin should work as 
+expected, and the author is happy to work with others to keep the 
+ofono plugin maintained and/or improve the ofono plugin.
+
+Based on a conversation held in Nov/Dec 2019 in the ofono IRC,
upstream 
+mmsd has effectively not been maintained for around 8 years. This
author has 
+attempted to contact the ofono maintainers both through the ofono
mailing 
+list and the ofono IRC to upstream changes found here, but did not get
a 
+response. This author is happy to work with the ofono maintainers to
upstream 
+the changes found in this repository, should they so desire.
+
+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 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 
+from Mobile Data APNs).
+    
+Please read "Configuring the Modem Manager Plugin" for configuration.
+
 Compiling mmsd
 ============================
 In order to compile proxy daemon you need following software packages:
 	- GCC compiler
 	- D-Bus library
 	- GLib library
+	- Modem Manager Library
 
 Installing mmsd
 ============================
@@ -74,4 +113,70 @@ TotalMaxAttachmentSize
         The maximum size all of your attachments can be before mmsd
rejects it.
         NOTE: This value is carrier specific! Changing this value to a
higher
               number may cause your carrier to silently reject MMSes
you send.
-              CHANGE AT YOUR OWN RISK!
\ No newline at end of file
+              CHANGE AT YOUR OWN RISK!
+
+Configuring the Modem Manager Plugin
+===========================
+On first run, mmsd will write a settings file at
+"$HOME/.mms/modemmanager/ModemManagerSettings"
+
+IMPORTANT NOTE: If you change any settings through the file,
+                mmsd MUST BE RESTARTED for the changes to take effect!
+                
+                You can change CarrierMMSC, CarrierMMSProxy, or
MMS_APN via 
+                dbus and they will take effect right away, but any
+	            messages sent to the mmsd queue need to be
processed 
+	            again. The easiest way to do this is to reset
mmsd.
+	            But it can be done with the dbus proxy call
ProcessMessageQueue().
+
+This settings file needs to be changed before mmsd will connect! The
settings
+are as follows:
+
+CarrierMMSC
+        Get this from your carrier.
+	        
+        Carrier MMSC Format: "http://mms.example.com"
+        
+CarrierMMSProxy 
+        Get this from your carrier.
+     	        
+        MMS Proxy Format: "proxy.example.com:80" or "NULL"
+            Both the proxy address AND port are required, or else mmsd
will not work!
+            The proxy is "proxy.example.com" 
+            The proxy port is "80"
+            If you do NOT have a proxy, set this to "NULL"
+            
+MMS_APN
+        Note that at this point, this plugin can only support one
bearer at 
+        a time (this works fine for carriers with a combined
Internet/MMS APN
+        but will not function with carriers that have two APNS
seperating 
+        the two)
+        
+        MMS APN Format: "apn.example.com"
+
+AutoProcessOnConnection
+        Tell mmsd to automatically send and recieve messages when the
modem
+        is connected. This will also allow mmsd to auto send/recieve
if the
+        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:
+https://www.t-mobile.com/support/devices/not-sold-by-t-mobile/byod-t-mobile-data-and-apn-settings
+
+From this:
+
+CarrierMMSC=http://mms.msg.eng.t-mobile.com/mms/wapenc
+MMS_APN=fast.t-mobile.com
+CarrierMMSProxy=NULL
+
+
diff --git a/configure.ac b/configure.ac
index 6b5e1b1..721eb19 100644
--- a/configure.ac
+++ b/configure.ac
@@ -78,4 +78,9 @@ PKG_CHECK_MODULES(DBUS, dbus-1 >= 1.2, dummy=yes,
 AC_SUBST(DBUS_CFLAGS)
 AC_SUBST(DBUS_LIBS)
 
+PKG_CHECK_MODULES(MMGLIB, mm-glib >= 1.10, dummy=yes,
+				AC_MSG_ERROR(mm-glib >= 1.10 is
required))
+AC_SUBST(MMGLIB_CFLAGS)
+AC_SUBST(MMGLIB_LIBS)
+
 AC_OUTPUT(Makefile)
diff --git a/doc/modem-manager-api.txt b/doc/modem-manager-api.txt
new file mode 100644
index 0000000..4a7f67f
--- /dev/null
+++ b/doc/modem-manager-api.txt
@@ -0,0 +1,102 @@
+Message hierarchy
+=================
+
+Service		org.ofono.mms
+Interface	org.ofono.mms.ModemManager
+Object path	/org/ofono/mms
+
+NOTE: This is an independent bus from the rest of mmsd. In order to
talk to 
+      Modem Manager, this plugin must work with dbus 2.0. The rest of
mmsd
+      operates on dbus 1.0. Be sure to connect independently to this
bus!
+
+Methods		                    
+
+    PushNotify()
+    
+		Send mmsd the contents of an SMS WAP for it to process
+		See purple-mm-sms for how this is used
+        
+        Gvariant input Format String    (ay)
+            This is the data contents of the SMS WAP
+
+	ChangeSettings()
+	    IMPORTANT NOTE: Settings changed here will work right
away, but any
+	                    messages sent to the mmsd queue need to be
processed 
+	                    again. The easiest way to do this is to
reset mmsd.
+	                    But it can be done with the dbus proxy
call 
+	                    ProcessMessageQueue()
+	    
+	    This sets and saves the Carrier MMSC, MMS Proxy, and MMS
APN
+	    
+	    Gvariant Input Format String    ((sss))
+	        Argument 1: Carrier MMSC
+	        Argument 2: MMS Proxy
+	        Argument 3: MMS APN
+	        
+	        Carrier MMSC
+	            Get this from your carrier.
+	        
+	            Carrier MMSC Format: "http://mms.example.com"
+	        
+            MMS Proxy 
+                Get this from your carrier.
+         	        
+	            MMS Proxy Format: "proxy.example.com:80" or "NULL"
+	                The proxy is "proxy.example.com" 
+	                The Proxy port is "80"
+                    Both the proxy address AND port is required, or
else mmsd will not work!
+	                If you do NOT have a proxy, set this to "NULL"
+	            
+	        MMS APN
+	            Note that at this point, this plugin can only
support one bearer at 
+	            a time (this works fine for carriers with a
combined Internet/MMS APN
+	            but will not function with carriers that have two
APNS seperating 
+	            the two)
+	        
+	            MMS APN Format: "apn.example.com"
+	        
+	    Example Python Program to call "ChangeSettings":
+	
+            #!/usr/bin/python
+
+            import pydbus
+            from pydbus import SessionBus
+            bus = SessionBus()
+            TestServer = bus.get("org.ofono.mms.ModemManager",
"/org/ofono/mms")
+            TestServer.ChangeSettings(("http://mms.invalid", "NULL",
"apn.invalid"))
+            #TestServer.ChangeSettings(("http://mms.invalid",
"proxy.invalid:80", "apn.invalid"))
+
+    ProcessMessageQueue()
+        This manually activates the Modem Manager Bearer to process
any messages
+        not sent or recieved yet. The primary idea behind is two fold:
+        
+        a) If the Bearer Handler is misconfigured, the OS/higher level
program
+           can change the settings via the dbus and test the bearer
handler 
+           to confirm it works.
+           
+        b) If modem data is disconnected (manually or due to modem
suspend), 
+           the OS/higher level program can also track this and can
command 
+           mmsd to now process any messages it needs to send/recieve
once
+           modem data is active.
+           
+        Since BearerHandlerError() emits a signal for any errors
activating the
+        modem contect, ProcessMessageQueue() does not return any
value.        
+
+Signals		
+    BearerHandlerError()
+        If the bearer handler has an issue activating the context, it
will emit
+        a signal of the error. The errors are shown above. 
+        
+        NOTE: MMSD_MM_MODEM_CONTEXT_ACTIVE will never be emitted as a
signal.
+        
+        Gvariant Output Format String    (h)
+            enum {
+                  MMSD_MM_MODEM_MMSC_MISCONFIGURED, //the MMSC is the
default value
+                  MMSD_MM_MODEM_NO_BEARERS_ACTIVE, //The Modem has no
bearers
+                  MMSD_MM_MODEM_INTERFACE_DISCONNECTED, //mmsd found
the right bearer, but it is disconnected
+                  MMSD_MM_MODEM_INCORRECT_APN_CONNECTED, //no APN is
connected that matches the settings
+                  MMSD_MM_MODEM_FUTURE_CASE_DISCONNECTED, //Reserved
for future case
+                  MMSD_MM_MODEM_CONTEXT_ACTIVE //No error, context
activated properly
+            } mm_context_connection;
+
+Properties	None
diff --git a/plugins/modemmanager.c b/plugins/modemmanager.c
new file mode 100644
index 0000000..383c0f5
--- /dev/null
+++ b/plugins/modemmanager.c
@@ -0,0 +1,1179 @@
+/*
+ *
+ *  Multimedia Messaging Service
+ *
+ *  Copyright (C) 2010-2011  Intel Corporation. All rights reserved.
+ *  Updated 2021: kop316, fuzzy7k, craftyguy, Mohammad Sadiq
+ *
+ *  Adapted from: https://source.puri.sm/Librem5/purple-mm-sms
+ *                Copyright (C) 2018 Purism SPC
+ *
+ *  This program is free software; you can redistribute it and/or
modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-
1301  USA
+ *
+ */
+
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <errno.h>
+#include <gio/gio.h>
+#include <stdlib.h>
+#include <libmm-glib.h>
+#include "mms.h"
+
+// SETTINGS_STORE is synced with services.c
+#define SETTINGS_STORE "ModemManagerSettings"
+// SETTINGS_GROUP is where we store our settings for this plugin
+#define SETTINGS_GROUP "Modem Manager"
+//Identifier of the plugin
+#define IDENTIFIER     "modemmanager"
+//dbus default timeout for Modem
+#define MMSD_MM_MODEM_TIMEOUT       20000
+
+enum {
+	MMSD_MM_STATE_NO_MANAGER,
+	MMSD_MM_STATE_MANAGER_FOUND,
+	MMSD_MM_STATE_NO_MODEM,
+	MMSD_MM_STATE_MODEM_FOUND,
+	MMSD_MM_STATE_NO_MESSAGING_MODEM,
+	MMSD_MM_STATE_MODEM_DISABLED,
+	MMSD_MM_STATE_MODEM_UNLOCK_ERROR,
+	MMSD_MM_STATE_READY
+} e_mmsd_connection;
+
+enum {
+	MMSD_MM_MODEM_MMSC_MISCONFIGURED,	 //the MMSC is the
default value
+	MMSD_MM_MODEM_NO_BEARERS_ACTIVE,	//The Modem has no
bearers
+	MMSD_MM_MODEM_INTERFACE_DISCONNECTED,	//mmsd found the right
bearer, but it is disconnected
+	MMSD_MM_MODEM_INCORRECT_APN_CONNECTED,	//no APN is connected
that matches the settings
+	MMSD_MM_MODEM_FUTURE_CASE_DISCONNECTED, //Reserved for future
case
+	MMSD_MM_MODEM_CONTEXT_ACTIVE		//No error, context
activated properly
+} mm_context_connection;
+
+struct modem_data {
+	struct mms_service *service; //Do not mess with the guts of
this in plugin.c!
+	GKeyFile *modemsettings;
+	//These are pulled from the settings file, and can be set via
the Dbus
+	char			*message_center;		// The
mmsc
+	char			*mms_apn;			// The
MMS APN
+	char			*MMS_proxy;			// I
*think* this is where mms proxy goes?
+	// These are for settings the context (i.e. APN settings and
if the bearer is active)
+	char			*context_interface;		//
Bearer interface here (e.g. "wwan0")
+	char			*context_path;			//
Dbus path of the bearer
+	dbus_bool_t		 context_active;		//
Whether the context is active
+	//The Bus org.ofono.mms.ModemManager
+	GDBusConnection		*master_connection;
+	guint			 owner_id;		 
+	guint			 registration_id; 
+	// This is a way to track the state of the modem if it is
disabled
+	MmGdbusModem		*gdbus_modem;
+	gulong			 modem_state_watch_id;
+	//These are modem manager related settings
+	MMManager		*mm;
+	guint			 mm_watch_id;
+	MMObject		*object; 
+	MMModem			*modem;
+	char			*path;
+	MMSim			*sim;
+	gchar			*imsi;
+	MMModemMessaging	*modem_messaging;
+	MMModemState		 state;
+	GPtrArray	 	*device_arr;
+	gboolean		 modem_available;
+	gboolean		 manager_available;
+	gboolean		 plugin_registered;
+	gboolean		 auto_process_on_connection;
+	gboolean		 autoprocess_sms_wap;
+};
+
+typedef struct {
+	MMObject	*object;
+	MMModem		*modem;
+	MMSim		*sim;
+} MmsdDevice;
+
+/* Introspection data for the service we are exporting */
+static const gchar introspection_xml[] =
+  "<node>"
+  "  <interface name='org.ofono.mms.ModemManager'>"
+  "    <annotation name='org.ofono.mms.ModemManager'
value='OnInterface'/>"
+  "    <annotation name='org.ofono.mms.ModemManager'
value='AlsoOnInterface'/>"
+  "    <method name='PushNotify'>"
+  "      <annotation name='org.ofono.mms.ModemManager'
value='OnMethod'/>"
+  "      <arg type='ay' name='smswap' direction='in'/>"
+  "    </method>"
+  "    <method name='ChangeSettings'>"
+  "      <annotation name='org.ofono.mms.ModemManager'
value='OnMethod'/>"
+  "      <arg type='(sss)' name='greeting' direction='in'/>"
+  "    </method>"
+  "    <method name='ProcessMessageQueue'>"
+  "      <annotation name='org.ofono.mms.ModemManager'
value='OnMethod'/>"
+  "    </method>"
+  "    <signal name='BearerHandlerError'>"
+  "      <annotation name='org.ofono.mms.ModemManager'
value='Onsignal'/>"
+  "      <arg type='h' name='ContextError'/>"
+  "    </signal>"
+  "  </interface>"
+  "</node>";
+
+
+static GDBusNodeInfo *introspection_data = NULL;
+struct modem_data *modem;
+
+static void mmsd_mm_state(int state);
+static void mmsd_plugin_connect(void);
+static void mmsd_plugin_disconnect(void);
+static void free_device(MmsdDevice *device);
+static void bearer_handler(mms_bool_t active, void *user_data);
+static int set_context(void);
+static void cb_mm_manager_new(GDBusConnection *connection,
GAsyncResult *res, gpointer user_data);
+static void mm_appeared_cb(GDBusConnection *connection, const gchar
*name, const gchar *name_owner, gpointer user_data);
+static void mm_vanished_cb(GDBusConnection *connection, const gchar
*name, gpointer user_data);
+static void mm_get_modem_manager(void);
+static int modemmanager_init(void);
+static void modemmanager_exit(void);
+
+static void
+handle_method_call(GDBusConnection		*connection,
+		   const gchar			*sender,
+		   const gchar			*object_path,
+		   const gchar			*interface_name,
+		   const gchar			*method_name,
+		   GVariant			*parameters,
+		   GDBusMethodInvocation	*invocation,
+		   gpointer			 user_data)
+{
+	if(g_strcmp0(method_name, "PushNotify") == 0)
+	{
+		GVariant *smswap;
+		const unsigned char *data;
+		gsize data_len;
+		if(modem->modem_available == TRUE) {
+
+			g_variant_get(parameters, "(@ay)", &smswap);
+			data_len = g_variant_get_size(smswap);
+			data = g_variant_get_fixed_array(smswap,
&data_len, 1);
+			mms_error("ModemManagerPlugin():
%s",__func__);
+
+			mms_service_push_notify(modem->service, data,
data_len);
+			g_dbus_method_invocation_return_value(invocati
on, NULL);
+
+		 } else {
+			g_dbus_method_invocation_return_dbus_error(inv
ocation,
+								  
"org.ofono.mms.ModemManager",
+								  
"Modem is not active!");
+		}
+	} 
+	else if(g_strcmp0(method_name, "ChangeSettings") == 0) {
+
+		const gchar *mmsc, *mmsproxy, *mmsapn;
+		g_variant_get(parameters, "((sss))", &mmsc,
+						     &mmsproxy,
+						     &mmsapn);
+		mms_error("ModemManagerPlugin(): args MMSC:%s MMS
Proxy:%s MMS APN:%s", mmsc, mmsproxy, mmsapn);
+		modem->modemsettings = mms_settings_open(IDENTIFIER,
SETTINGS_STORE);
+
+		if(g_strcmp0(mmsc, "") != 0) {
+			g_free(modem->message_center);
+			modem->message_center = g_strdup(mmsc);
+			g_key_file_set_string(modem->modemsettings,
SETTINGS_GROUP,
+					      "CarrierMMSC", modem-
>message_center);
+		}
+
+		if(g_strcmp0(mmsproxy, "") != 0) {
+			g_free(modem->MMS_proxy);
+			modem->MMS_proxy = g_strdup(mmsproxy);
+			g_key_file_set_string(modem->modemsettings,
SETTINGS_GROUP,
+					      "CarrierMMSProxy",
modem->MMS_proxy);
+			if(g_strcmp0(modem->MMS_proxy, "NULL") == 0) {
+				g_free(modem->MMS_proxy);
+				modem->MMS_proxy = NULL;
+			}
+		}
+		
+		if(g_strcmp0(mmsapn, "") != 0) {
+			g_free(modem->mms_apn);
+			modem->mms_apn = g_strdup(mmsapn);
+			g_key_file_set_string(modem->modemsettings,
SETTINGS_GROUP,
+					      "MMS_APN", modem-
>mms_apn);
+		}
+		mms_settings_close(IDENTIFIER, SETTINGS_STORE,
+				   modem->modemsettings, TRUE); 
+
+		g_dbus_method_invocation_return_value(invocation,
NULL);
+	}
+	else if(g_strcmp0(method_name, "ProcessMessageQueue") == 0) {
+		if(modem->modem_available == TRUE) {
+			/*
+			 * Prevent a race condition from the
connection turning active to usable
+			 * for mmsd
+			 */
+			sleep(1);
+
+			activate_bearer(modem->service);
+			g_dbus_method_invocation_return_value(invocati
on, NULL);
+		} else {
+			g_dbus_method_invocation_return_dbus_error(inv
ocation,
+								  
"org.ofono.mms.ModemManager",
+								  
"Modem is not active!");
+		}
+	}
+} 
+
+static const GDBusInterfaceVTable interface_vtable =
+{
+	handle_method_call
+};
+
+static void
+on_bus_acquired(GDBusConnection *connection,
+		const gchar	*name,
+		gpointer	 user_data)
+{
+
+	modem->master_connection = connection;
+
+	modem->registration_id =
g_dbus_connection_register_object(connection,
+								  
"/org/ofono/mms",
+								  
introspection_data->interfaces[0],
+								  
&interface_vtable,
+								  
NULL,	/* user_data */
+								  
NULL,	/* user_data_free_func */
+								  
NULL);	/* GError** */
+
+	g_assert(modem->registration_id > 0);
+}
+
+static void
+on_name_acquired(GDBusConnection	*connection,
+		 const gchar		*name,
+		 gpointer		 user_data)
+{
+}
+
+static void
+on_name_lost(GDBusConnection	*connection,
+	     const gchar	*name,
+	     gpointer		 user_data)
+{
+}
+
+static void
+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_r
eady,
+				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_r
eady,
+				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);
+
+	g_dbus_proxy_set_default_timeout(G_DBUS_PROXY(modem->modem),
+					 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));
+
+
+	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__);
+}
+
+static void
+free_device(MmsdDevice *device)
+{
+	if(!device)
+		return;
+
+	g_clear_object(&device->sim);
+	g_clear_object(&device->modem);
+	g_clear_object(&device->object);
+	g_free(device);
+}
+
+static gboolean
+device_match_by_object(MmsdDevice	*device,
+		       GDBusObject	*object)
+
+{
+	g_return_val_if_fail(G_IS_DBUS_OBJECT(object), FALSE);
+	g_return_val_if_fail(MM_OBJECT(device->object), FALSE);
+
+	return object == G_DBUS_OBJECT(device->object);
+}
+
+static void
+mmsd_mm_add_object(MMObject *obj)
+{
+	MmsdDevice *device;
+	const gchar *object_path;
+
+	object_path =
g_dbus_object_get_object_path(G_DBUS_OBJECT(obj));
+
+	g_return_if_fail(object_path);
+	//Begin if statement
+	if(g_ptr_array_find_with_equal_func(modem->device_arr,
+					    obj,
+					   
(GEqualFunc)device_match_by_object,
+					    NULL)) {
+	//End if statement
+	mms_error("ModemManagerPlugin(): Device %s already added",
object_path);
+	return;
+	}
+
+	mms_error("ModemManagerPlugin(): Added device at: %s",
object_path);
+
+	// TODO choose default modem if devices->len > 1
+	device = g_new0(MmsdDevice, 1);
+	device->object = g_object_ref(MM_OBJECT(obj));
+	device->modem = mm_object_get_modem(MM_OBJECT(obj));
+	g_ptr_array_add(modem->device_arr, device);
+
+	mmsd_mm_init_modem(obj);
+
+	mmsd_mm_state(MMSD_MM_STATE_MODEM_FOUND);
+}
+
+static void
+mmsd_mm_get_modems(void)
+{
+	GList *list, *l;
+	gboolean has_modem = FALSE;
+
+	g_return_if_fail(MM_IS_MANAGER(modem->mm));
+
+	list =
g_dbus_object_manager_get_objects(G_DBUS_OBJECT_MANAGER(modem->mm));
+
+	for(l = list; l != NULL; l = l->next) {
+		if(!mm_object_peek_modem_messaging(l->data))
+			continue;
+
+		has_modem = TRUE;
+		mmsd_mm_add_object(MM_OBJECT(l->data));
+	}
+
+	if(!has_modem) {
+		mmsd_mm_state(MMSD_MM_STATE_NO_MODEM);
+	} else if(list) {
+		g_list_free_full(list, g_object_unref);
+	}
+}
+
+
+static void
+cb_object_added(GDBusObjectManager 	*manager,
+		GDBusObject		*object,
+		gpointer		 user_data)
+{
+	mms_error("ModemManagerPlugin(): %s", __func__);
+	if(mm_object_peek_modem_messaging(MM_OBJECT(object))) {
+		mms_error("ModemManagerPlugin(): New Object does not
have Messaging feature, ignoring....");
+		mmsd_mm_add_object(MM_OBJECT(object));
+	}
+
+
+}
+
+
+
+static void
+cb_object_removed(GDBusObjectManager	*manager,
+		  GDBusObject		*object,
+		  gpointer		 user_data)
+{
+	guint index;
+
+
+	g_return_if_fail(G_IS_DBUS_OBJECT(object));
+	g_return_if_fail(G_IS_DBUS_OBJECT_MANAGER(manager));
+	//Begin if statement
+	if(g_ptr_array_find_with_equal_func(modem->device_arr,
+					    object,
+					   
(GEqualFunc)device_match_by_object,
+					    &index)) {
+	//End if Statement
+		g_ptr_array_remove_index_fast(modem->device_arr,
index);
+	}
+
+	if(MM_OBJECT(object) == modem->object) {
+		mmsd_mm_state(MMSD_MM_STATE_NO_MODEM);
+	}
+
+	mms_error("ModemManagerPlugin(): Modem removed: %s",
g_dbus_object_get_object_path(object));
+}
+
+
+static void
+cb_name_owner_changed(GDBusObjectManager	*manager,
+		      GDBusObject		*object,
+		      gpointer			 user_data)
+{
+	gchar *name_owner;
+
+	name_owner =
g_dbus_object_manager_client_get_name_owner(G_DBUS_OBJECT_MANAGER_CLIEN
T(manager));
+
+	if(!name_owner) {
+		mmsd_mm_state(MMSD_MM_STATE_NO_MANAGER);
+	}
+
+	mms_error("ModemManagerPlugin(): Name owner changed");
+
+	g_free(name_owner);
+}
+
+static void
+cb_mm_manager_new(GDBusConnection 	*connection,
+		  GAsyncResult		*res,
+		  gpointer		 user_data)
+{
+	gchar		 	*name_owner;
+	g_autoptr(GError)	 error = NULL;
+
+
+	modem->mm = mm_manager_new_finish(res, &error);
+	modem->device_arr =
g_ptr_array_new_with_free_func((GDestroyNotify) free_device);
+
+	if(modem->mm) {
+
+		mmsd_mm_state(MMSD_MM_STATE_MANAGER_FOUND);
+
+		g_signal_connect(modem->mm,
+				 "interface-added",
+				 G_CALLBACK(cb_object_added),
+				 NULL);
+
+		g_signal_connect(modem->mm,
+				 "object-added",
+				 G_CALLBACK(cb_object_added),
+				 NULL);
+
+		g_signal_connect(modem->mm,
+				 "object-removed",
+				 G_CALLBACK(cb_object_removed),
+				 NULL);
+
+		g_signal_connect(modem->mm,
+				 "notify::name-owner",
+				 G_CALLBACK(cb_name_owner_changed),
+				 NULL);
+
+		name_owner =
g_dbus_object_manager_client_get_name_owner(G_DBUS_OBJECT_MANAGER_CLIEN
T(modem->mm));
+		mms_error("ModemManagerPlugin(): ModemManager found:
%s\n", name_owner);
+		g_free(name_owner);
+
+		mmsd_mm_get_modems();
+
+	} else {
+		mms_error("ModemManagerPlugin(): Error connecting to
ModemManager: %s\n", error->message);
+
+		mmsd_mm_state(MMSD_MM_STATE_NO_MANAGER);
+	}
+}
+
+static void
+cb_get_sim_ready(MMModem	*MMmodem,
+		 GAsyncResult	*res,
+		 gpointer	 user_data)
+{
+	modem->sim = mm_modem_get_sim_finish(MMmodem, res, NULL);
+
+	modem->imsi = mm_sim_dup_imsi(modem->sim);
+
+	mms_error("ModemManagerPlugin(): Got SIM Path: %s Identifier:
%s, imsi: %s", mm_sim_get_path(modem->sim),
+			   mm_sim_get_identifier(modem->sim), modem-
>imsi);
+}
+
+static void
+mmsd_mm_get_modem_state(void)
+{
+	g_autoptr(GError) error = NULL;
+
+	if(!modem->modem) {
+		mmsd_mm_state(MMSD_MM_STATE_NO_MODEM);
+		return;
+	}
+
+	if(!modem->modem_messaging) {
+		mmsd_mm_state(MMSD_MM_STATE_NO_MESSAGING_MODEM);
+		return;
+	}
+
+	if(modem->state < MM_MODEM_STATE_ENABLED) {
+			mms_error("ModemManagerPlugin(): Something May
be wrong with the modem, checking....");
+			switch(modem->state) {
+			case MM_MODEM_STATE_FAILED:
+				mms_error("ModemManagerPlugin():
MM_MODEM_STATE_FAILED");
+				mmsd_mm_state(MMSD_MM_STATE_MODEM_DISA
BLED);
+				return;
+			case MM_MODEM_STATE_UNKNOWN:
+				mms_error("ModemManagerPlugin():
MM_MODEM_STATE_UNKNOWN");
+				mmsd_mm_state(MMSD_MM_STATE_MODEM_DISA
BLED);
+				return;
+			case MM_MODEM_STATE_LOCKED:
+				mms_error("ModemManagerPlugin():
MM_MODEM_STATE_FAILED");
+				mmsd_mm_state(MMSD_MM_STATE_MODEM_DISA
BLED);
+				return;
+			case MM_MODEM_STATE_INITIALIZING:
+				mms_error("ModemManagerPlugin():
MM_MODEM_STATE_INITIALIZING");
+				mmsd_mm_state(MMSD_MM_STATE_MODEM_DISA
BLED);
+				return;
+			case MM_MODEM_STATE_DISABLED:
+				mms_error("ModemManagerPlugin():
MM_MODEM_STATE_DISABLED");
+				mms_error("ModemManagerPlugin():
Turning on Modem....");
+				mm_modem_set_power_state_sync(modem-
>modem, MM_MODEM_POWER_STATE_ON, NULL, &error);
+				mmsd_mm_state(MMSD_MM_STATE_MODEM_DISA
BLED);
+				return;
+			case MM_MODEM_STATE_DISABLING:
+				mms_error("ModemManagerPlugin():
MM_MODEM_STATE_DISABLING");
+				mmsd_mm_state(MMSD_MM_STATE_MODEM_DISA
BLED);
+				return;
+			case MM_MODEM_STATE_ENABLING:
+				mms_error("ModemManagerPlugin():
MM_MODEM_STATE_ENABLING");
+				mmsd_mm_state(MMSD_MM_STATE_MODEM_DISA
BLED);
+				return;
+			default:
+				mms_error("ModemManagerPlugin():
MM_MODEM_OTHER_BAD_STATE: %d", modem->state);
+				mmsd_mm_state(MMSD_MM_STATE_MODEM_DISA
BLED);
+				return;
+		}
+	}
+	mms_error("ModemManagerPlugin(): MM_MODEM_GOOD_STATE: %d",
modem->state);
+	mmsd_mm_state(MMSD_MM_STATE_READY);
+
+	/* Automatically process unsent/unrecieved messages when the
modem is connected */
+	if(modem->state == MM_MODEM_STATE_CONNECTED) {
+		if(modem->auto_process_on_connection == TRUE) {
+			mms_error("Auto processing unsent/unrecieved
messages per settings.");
+			/*
+			 * Prevent a race condition from the
connection 
+			 * turning active to usable for mmsd
+			 */
+			sleep(1);
+
+			activate_bearer(modem->service);
+		} else {
+			mms_error("Not auto processing
unsent/unrecieved messages per settings.");
+		}
+	}
+	return;
+}
+
+static void 
+modem_state_changed_cb(MMModem			*cb_modem,
+		       MMModemState		 old,
+		       MMModemState	 	 new,
+		       MMModemStateChangeReason	 reason)
+{
+	mms_error("ModemManagerPlugin(): State Change: Old State: %d
New State: %d, Reason: %d", old, new, reason);
+	modem->state = new;
+	mmsd_mm_get_modem_state();
+}
+
+static void
+mmsd_mm_state(int state)
+{
+	switch(state) {
+		case MMSD_MM_STATE_MODEM_FOUND:
+			if(!modem->modem_available) {
+				if(modem->modem) {
+					mm_modem_get_sim(modem->modem,
+							 NULL,
+							
(GAsyncReadyCallback)cb_get_sim_ready,
+							 NULL);
+								
						
+					modem->gdbus_modem =
MM_GDBUS_MODEM(modem->modem);
+
+					modem->modem_state_watch_id =
g_signal_connect(modem->gdbus_modem, 
+								
		       "state-changed", 
+								
		       G_CALLBACK(modem_state_changed_cb), 
+								
		       NULL);
+				}
+				modem->state =
mm_modem_get_state(modem->modem);
+				mmsd_mm_get_modem_state();
+			}
+			break;
+		case MMSD_MM_STATE_NO_MODEM:
+			if(modem->modem_available) {
+				g_signal_handler_disconnect(modem-
>gdbus_modem,
+							    modem-
>modem_state_watch_id);
+				mmsd_plugin_disconnect();
+				mms_error("ModemManagerPlugin(): Modem
vanished, Disabling plugin");
+			} else {
+				mms_error("ModemManagerPlugin(): Could
not connect to modem");
+			}
+			modem->modem_available = FALSE;
+			mms_error("ModemManagerPlugin():
MMSD_MM_STATE_NO_MODEM");
+			break;
+
+		case MMSD_MM_STATE_NO_MESSAGING_MODEM:
+			g_signal_handler_disconnect(modem-
>gdbus_modem,
+						    modem-
>modem_state_watch_id);
+			mmsd_plugin_disconnect();
+			mms_error("ModemManagerPlugin(): Modem has no
messaging capabilities");
+			mms_error("ModemManagerPlugin():
MMSD_MM_STATE_NO_MESSAGING_MODEM");
+			modem->modem_available = FALSE;
+			break;
+
+		case MMSD_MM_STATE_MODEM_DISABLED:
+			mms_error("ModemManagerPlugin(): Modem
disabled");
+			mms_error("ModemManagerPlugin():
MMSD_MM_STATE_MODEM_DISABLED");
+
+			mms_service_set_bearer_handler(modem->service,
NULL, NULL);
+			modem->modem_available = FALSE;
+			break;
+
+		case MMSD_MM_STATE_MANAGER_FOUND:
+			if(!modem->manager_available) {
+				modem->manager_available = TRUE;
+				modem->owner_id =
g_bus_own_name(G_BUS_TYPE_SESSION,
+								
"org.ofono.mms.ModemManager",
+								
G_BUS_NAME_OWNER_FLAGS_NONE,
+								
on_bus_acquired,
+								
on_name_acquired,
+								
on_name_lost,
+								 NULL,
+								
NULL);
+			}
+			mms_error("ModemManagerPlugin():
MMSD_MM_STATE_MANAGER_FOUND");
+			break;
+
+		case MMSD_MM_STATE_NO_MANAGER:
+			if(modem->manager_available) {
+				mmsd_plugin_disconnect();
+				g_clear_object(&modem->mm);
+				g_dbus_connection_unregister_object(mo
dem->master_connection,
+								   
modem->registration_id);
+				g_bus_unown_name(modem->owner_id);
+				mms_error("ModemManagerPlugin():
ModemManager vanished");
+				modem->modem_available = FALSE;
+			} else {
+				mms_error("ModemManagerPlugin(): Could
not connect to ModemManager");
+			}
+			modem->manager_available = FALSE;
+			mms_error("ModemManagerPlugin():
MMSD_MM_STATE_NO_MANAGER");
+			break;
+
+		case MMSD_MM_STATE_MODEM_UNLOCK_ERROR:
+			mms_error("ModemManagerPlugin(): SIM card
unlock failed");
+			mms_error("ModemManagerPlugin():
MMSD_MM_STATE_MODEM_UNLOCK_ERROR");
+			break;
+
+		case MMSD_MM_STATE_READY:
+			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:
+			g_return_if_reached();
+	}
+}
+
+static void
+mm_appeared_cb(GDBusConnection	*connection,
+	       const gchar 	*name,
+	       const gchar 	*name_owner,
+	       gpointer		 user_data)
+{
+	g_assert(G_IS_DBUS_CONNECTION(connection));
+
+	mm_manager_new(connection,
+		       G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_NONE,
+		       NULL,
+		       (GAsyncReadyCallback) cb_mm_manager_new,
+		       NULL);
+}
+
+static void
+mm_vanished_cb(GDBusConnection	*connection,
+	       const gchar	*name,
+	       gpointer		 user_data)
+{
+	g_assert(G_IS_DBUS_CONNECTION(connection));
+
+	mms_error("ModemManagerPlugin(): Modem Manager vanished");
+	mmsd_mm_state(MMSD_MM_STATE_NO_MANAGER);
+}
+
+static void
+mm_get_modem_manager(void)
+{
+	modem->mm_watch_id = g_bus_watch_name(G_BUS_TYPE_SYSTEM,
+					      MM_DBUS_SERVICE,
+					     
G_BUS_NAME_WATCHER_FLAGS_AUTO_START,
+					     
(GBusNameAppearedCallback) mm_appeared_cb,
+					     
(GBusNameVanishedCallback) mm_vanished_cb,
+					      NULL, 
+					      NULL);
+}
+
+static void bearer_handler(mms_bool_t    active, 
+			   void 	*user_data)
+{
+	struct modem_data *modem = user_data;
+	gint32 response;
+
+	/* Check for any errors within the context */
+	response = set_context();
+	if(response != MMSD_MM_MODEM_CONTEXT_ACTIVE) {
+		mms_error("ModemManagerPlugin(): Set MMSC: %s, Set
Proxy: %s, Set MMS APN: %s", modem->message_center, modem->MMS_proxy,
modem->mms_apn);
+		g_dbus_connection_emit_signal(modem-
>master_connection,
+					      NULL,
+					      "/org/ofono/mms",
+					     
"org.ofono.mms.ModemManager",
+					      "BearerHandlerError",
+					      g_variant_new("(h)",
response),
+					      NULL);
+	}
+	mms_error("ModemManagerPlugin(): At Bearer Handler: path %s
active %d context_active %d", modem->path, active, modem-
>context_active);
+	if(active == TRUE && modem->context_active == TRUE) {
+		mms_error("ModemManagerPlugin(): active and
context_active, bearer_notify");
+		mms_service_bearer_notify(modem->service, TRUE, modem-
>context_interface, modem->MMS_proxy);
+		return;
+	} else if(active == TRUE && modem->context_active == FALSE) {
+		mms_error("ModemManagerPlugin(): Error activating
context!");
+		mms_service_bearer_notify(modem->service, FALSE, NULL,
NULL);
+		return;
+	}
+
+	mms_error("ModemManagerPlugin(): checking for failure");
+	if(active == FALSE && modem->context_active == FALSE) {
+		mms_error("ModemManagerPlugin(): Context not
active!");
+		mms_service_bearer_notify(modem->service, FALSE, NULL,
NULL);
+		return;
+	} else {
+		mms_error("ModemManagerPlugin(): No failures");
+		mms_service_bearer_notify(modem->service, FALSE,
modem->context_interface, modem->MMS_proxy);
+		return;
+	}
+
+}
+ 
+static int set_context(void)
+{
+	guint 			 max_bearers, active_bearers;
+	GList 			*bearer_list, *l;
+	MMBearer 		*modem_bearer;
+	MMBearerProperties 	*modem_bearer_properties;
+	const gchar 		*apn;
+	gboolean 		 interface_disconnected;
+	gboolean 		 bearer_connected;
+
+	mms_error("ModemManagerPlugin(): Setting Context...");
+	if(modem->context_active) {
+		g_free(modem->context_interface);
+		g_free(modem->context_path);
+	}
+	modem->context_active = FALSE;
+	interface_disconnected = FALSE;
+	mms_service_set_mmsc(modem->service, modem->message_center);
+	max_bearers = mm_modem_get_max_active_bearers(modem->modem);
+	mms_error("ModemManagerPlugin(): Max number of bearers: %d",
max_bearers);
+	bearer_list = mm_modem_list_bearers_sync(modem->modem, NULL,
NULL);
+	active_bearers = 0;
+	if(bearer_list != NULL) {
+		for(l = bearer_list; l != NULL; l = l->next) {
+			active_bearers = active_bearers + 1;
+			modem_bearer =(MMBearer *) l->data;
+			modem_bearer_properties =
mm_bearer_get_properties(modem_bearer);
+			apn =
mm_bearer_properties_get_apn(modem_bearer_properties);
+			mms_error("ModemManagerPlugin(): Current
Context APN: %s, mmsd settings MMS APN: %s", apn, modem->mms_apn);
+			bearer_connected =
mm_bearer_get_connected(modem_bearer);
+			if(g_strcmp0(apn, modem->mms_apn) == 0 ) {
+				if(modem->state !=
MM_MODEM_STATE_CONNECTED) {
+					mms_error("ModemManagerPlugin(
): The modem interface is reporting it is disconnected!");
+					mms_error("ModemManagerPlugin(
): Reported State: %d", modem->state);
+					interface_disconnected = TRUE;
+				} else if(!bearer_connected) {
+					mms_error("ModemManagerPlugin(
): The proper context is not connected!");
+					interface_disconnected = TRUE;
+				} else {
+					mms_error("ModemManagerPlugin(
): You are connected to the correct APN! Enabling context...");
+					modem->context_interface =
mm_bearer_dup_interface(modem_bearer);
+					modem->context_path =
mm_bearer_dup_path(modem_bearer);
+					modem->context_active = TRUE;
+				}
+			}
+		}
+		g_list_free(bearer_list);
+		g_list_free(l);
+		if(!modem->context_active) { // I did not find the
right context I wanted.
+			if(active_bearers == max_bearers) {
+				if(interface_disconnected) {
+					return
MMSD_MM_MODEM_INTERFACE_DISCONNECTED;
+				} else {
+					mms_error("ModemManagerPlugin(
): The modem is not connected to the correct APN!");
+					return
MMSD_MM_MODEM_INCORRECT_APN_CONNECTED;
+				}
+			} else if(active_bearers == 0) {
+				mms_error("ModemManagerPlugin(): The
modem bearer is disconnected! Please enable modem data");
+				return
MMSD_MM_MODEM_NO_BEARERS_ACTIVE;
+			} 
+			 else if(active_bearers < max_bearers) {
+				/*
+				 * TODO: Modem manager does not
support this yet, but this is
+				 *	 where to add code when Modem
manager supports multiple
+				 *	 contexts and/or a seperate
MMS context.
+				 *	 The Pinephone and Librem 5
only support 
+				 *	 one active bearer as well
+				 */ 
+				mms_error("ModemManagerPlugin(): This
is a stub for adding a new context/bearer, but Modem Manager does not
support this yet."); 
+				return
MMSD_MM_MODEM_FUTURE_CASE_DISCONNECTED;
+			}
+		}
+	} else {
+		mms_error("ModemManagerPlugin(): There are no modem
bearers! Please enable modem data");
+		return MMSD_MM_MODEM_NO_BEARERS_ACTIVE;
+	}
+	
+	if(g_strcmp0(modem->message_center, "http://mmsc.invalid") ==
0) {
+		mms_error("ModemManagerPlugin(): The MMSC is not
configured! Please configure the MMSC and restart mmsd.");
+		return MMSD_MM_MODEM_MMSC_MISCONFIGURED;
+	} 
+	return MMSD_MM_MODEM_CONTEXT_ACTIVE;
+}
+
+static void mmsd_plugin_connect(void) {
+	if(modem->plugin_registered == FALSE) {
+		mms_error("ModemManagerPlugin(): Registering Modem
Manager MMS Service");
+		mms_service_register(modem->service);
+		modem-> plugin_registered = TRUE;
+	}
+	mms_error("ModemManagerPlugin(): Setting Bearer Handler");
+	mms_service_set_bearer_handler(modem->service, bearer_handler,
modem);
+} 
+
+
+static void mmsd_plugin_disconnect(void)
+{
+	mms_error("ModemManagerPlugin(): Disabling Bearer Handler");
+	mms_service_set_bearer_handler(modem->service, NULL, NULL);
+	g_object_unref(modem->sim);
+	g_free(modem->imsi);
+	g_free(modem->path);
+	g_clear_object(&modem->modem);
+	g_clear_object(&modem->modem_messaging);
+	modem->object = NULL;
+	if(modem->device_arr && modem->device_arr->len) {
+		g_ptr_array_set_size(modem->device_arr, 0);
+		g_ptr_array_unref(modem->device_arr);
+	}
+	modem->modem_available = FALSE;
+}
+ 
+static int modemmanager_init(void)
+{
+	g_autoptr(GError) error = NULL;
+	/* Set up modem Structure to be used here */
+	modem = g_try_new0(struct modem_data, 1);
+
+	if(modem == NULL) {
+		mms_error("ModemManagerPlugin(): Could not allocate
space for modem data!");
+		return -ENOMEM;
+	}
+	modem->service = mms_service_create();
+	mms_service_set_identity(modem->service, IDENTIFIER);
+	
+	// Opening/making config file at
$HOME/.mms/modemmanager/ModemManagerSettings
+	modem->modemsettings = mms_settings_open(IDENTIFIER,
SETTINGS_STORE);
+
+	modem->message_center = g_key_file_get_string(modem-
>modemsettings, 
+						      SETTINGS_GROUP,
+						      "CarrierMMSC",
&error);
+	if(error) {
+		mms_error("ModemManagerPlugin(): No MMSC was
configured!");
+		modem->message_center =
g_strdup("http://mms.invalid");
+		g_key_file_set_string(modem->modemsettings,
SETTINGS_GROUP,
+				      "CarrierMMSC", modem-
>message_center);
+		error = NULL;
+	}
+
+	modem->mms_apn = g_key_file_get_string(modem->modemsettings, 
+					       SETTINGS_GROUP,
+					       "MMS_APN", &error);
+	if(error) {
+		mms_error("ModemManagerPlugin(): No MMS APN was
configured!");
+		modem->mms_apn = g_strdup("apn.invalid");
+		g_key_file_set_string(modem->modemsettings,
SETTINGS_GROUP,
+							  "MMS_APN",
modem->mms_apn);
+		error = NULL;
+	}
+
+	modem->MMS_proxy = g_key_file_get_string(modem->modemsettings,
+						 SETTINGS_GROUP,
+						 "CarrierMMSProxy",
&error);
+	if(error) {
+		mms_error("ModemManagerPlugin(): No Context Proxy was
configured! Setting to NULL.");
+		modem->MMS_proxy = g_strdup("NULL");
+		g_key_file_set_string(modem->modemsettings,
SETTINGS_GROUP,
+				      "CarrierMMSProxy", modem-
>MMS_proxy);
+		error = NULL;
+	}
+	if(g_strcmp0(modem->MMS_proxy, "NULL") == 0) {
+		g_free(modem->MMS_proxy);
+		modem->MMS_proxy = NULL;
+	}
+
+	modem->auto_process_on_connection =
g_key_file_get_boolean(modem->modemsettings, 
+								  
SETTINGS_GROUP,
+								  
"AutoProcessOnConnection", 
+								  
&error);
+	if(error) {
+		mms_error("ModemManagerPlugin(): Auto Process On
Connection was not configured! Setting to TRUE.");
+		modem->auto_process_on_connection = TRUE;
+		g_key_file_set_boolean(modem->modemsettings,
SETTINGS_GROUP,
+				       "AutoProcessOnConnection",
modem->auto_process_on_connection);
+		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);
+	g_assert(introspection_data != NULL);
+
+	modem->modem_available = FALSE;
+	modem->manager_available = FALSE;
+	modem->context_active = FALSE;
+	modem->plugin_registered = FALSE;
+	mm_get_modem_manager();
+
+	return 0;
+}
+
+static void modemmanager_exit(void)
+{
+	if(modem->plugin_registered == TRUE) {
+		mms_service_unregister(modem->service);
+	}
+	if(modem->manager_available) {
+		mmsd_plugin_disconnect();
+		g_clear_object(&modem->mm);
+		g_dbus_connection_unregister_object(modem-
>master_connection,
+						    modem-
>registration_id);
+		g_bus_unown_name(modem->owner_id);
+	}
+	g_free(modem->message_center);
+	g_free(modem->MMS_proxy);
+	g_free(modem->mms_apn);
+	g_free(modem);
+	g_dbus_node_info_unref(introspection_data);
+}
+
+MMS_PLUGIN_DEFINE(modemmanager, modemmanager_init, modemmanager_exit)
diff --git a/src/service.c b/src/service.c
index b0c2428..0f5c13c 100644
--- a/src/service.c
+++ b/src/service.c
@@ -647,7 +647,7 @@ static void process_request_queue(struct
mms_service *service);
 static void emit_message_added(const struct mms_service *service,
 						struct mms_message
*msg);
 
-static void activate_bearer(struct mms_service *service)
+void activate_bearer(struct mms_service *service)
 {
 	DBG("service %p setup %d active %d", service, service-
>bearer_setup, service->bearer_active);
 
@@ -782,6 +782,7 @@ static DBusMessage *get_messages(DBusConnection
*conn,
 	reply = dbus_message_new_method_return(dbus_msg);
 	if (reply == NULL)
 		return NULL;
+	//return reply;
 
 	dbus_message_iter_init_append(reply, &iter);
 
diff --git a/src/service.h b/src/service.h
index 56c0585..586ceca 100644
--- a/src/service.h
+++ b/src/service.h
@@ -52,3 +52,5 @@ int mms_message_register(struct mms_service *service,
 						struct mms_message
*msg);
 int mms_message_unregister(const struct mms_service *service,
 						const char *msg_path);
+
+void activate_bearer(struct mms_service *service);
-- 
2.30.2



^ permalink raw reply related	[flat|nested] 19+ messages in thread

* Forking on MMSD
  2021-04-10 14:13 [PATCH 0/9] Updates for mmsd Chris Talbot
  2021-04-10 14:17 ` [PATCH 1/9] Fix mmsd to work with T-mobile Chris Talbot
@ 2021-04-14 18:21 ` Chris Talbot
  2021-04-14 18:30   ` [Debian-on-mobile-maintainers] " Guido Günther
                     ` (2 more replies)
  1 sibling, 3 replies; 19+ messages in thread
From: Chris Talbot @ 2021-04-14 18:21 UTC (permalink / raw)
  To: ofono, netdev, debian-on-mobile-maintainers, librem-5-dev,
	982250, 985893

Hello All,

In talking to the Debian Developer Mr. Federico Ceratto, since I have
been unable to get a hold of the Ofono Maintainers, the best course of
action for packaging mmsd into Debian is to simply fork the project and
submit my version upstream for packaging in Debian. My repository is
here: https://source.puri.sm/kop316/mmsd/

I am sending this so the relavent parties are aware of this, and to
indicate that I no longer intend on trying to get a hold of upstream
mmsd to try and submit patches.

For the Purism Employees, I am additionally asking for permission to
keep hosting mmsd on https://source.puri.sm/ . I have been extremely
appreciative in using it and I am happy to keep it there, but I want to
be neighboorly and ask if it is okay for me to keep it there. If it is
not, I completely understand and I am fine with moving it to a new
host.

If you have any questions, comments, or concern, please reach out to
me.

-- 
Respectfully,
Chris Talbot


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [Debian-on-mobile-maintainers] Forking on MMSD
  2021-04-14 18:21 ` Forking on MMSD Chris Talbot
@ 2021-04-14 18:30   ` Guido Günther
  2021-04-14 18:46     ` Chris Talbot
  2021-04-14 18:39   ` Marius Gripsgard
  2021-04-14 19:29   ` Pavel Machek
  2 siblings, 1 reply; 19+ messages in thread
From: Guido Günther @ 2021-04-14 18:30 UTC (permalink / raw)
  To: Chris Talbot
  Cc: ofono, netdev, debian-on-mobile-maintainers, librem-5-dev,
	982250, 985893

Hi,
On Wed, Apr 14, 2021 at 02:21:04PM -0400, Chris Talbot wrote:
> Hello All,
> 
> In talking to the Debian Developer Mr. Federico Ceratto, since I have
> been unable to get a hold of the Ofono Maintainers, the best course of
> action for packaging mmsd into Debian is to simply fork the project and
> submit my version upstream for packaging in Debian. My repository is
> here: https://source.puri.sm/kop316/mmsd/
> 
> I am sending this so the relavent parties are aware of this, and to
> indicate that I no longer intend on trying to get a hold of upstream
> mmsd to try and submit patches.
> 
> For the Purism Employees, I am additionally asking for permission to
> keep hosting mmsd on https://source.puri.sm/ . I have been extremely
> appreciative in using it and I am happy to keep it there, but I want to
> be neighboorly and ask if it is okay for me to keep it there. If it is
> not, I completely understand and I am fine with moving it to a new
> host.

Keeping your ofono version on source.puri.sm is certainly welcome!
Cheers,
 -- Guido

> 
> If you have any questions, comments, or concern, please reach out to
> me.
> 
> -- 
> Respectfully,
> Chris Talbot
> 
> 
> _______________________________________________
> Debian-on-mobile-maintainers mailing list
> Debian-on-mobile-maintainers@alioth-lists.debian.net
> https://alioth-lists.debian.net/cgi-bin/mailman/listinfo/debian-on-mobile-maintainers
> 

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: Forking on MMSD
  2021-04-14 18:21 ` Forking on MMSD Chris Talbot
  2021-04-14 18:30   ` [Debian-on-mobile-maintainers] " Guido Günther
@ 2021-04-14 18:39   ` Marius Gripsgard
  2021-04-14 22:09     ` Bug#985893: " Wookey
  2021-04-14 19:29   ` Pavel Machek
  2 siblings, 1 reply; 19+ messages in thread
From: Marius Gripsgard @ 2021-04-14 18:39 UTC (permalink / raw)
  To: Chris Talbot
  Cc: ofono, netdev, debian-on-mobile-maintainers, librem-5-dev,
	982250, 985893

Hi,

I would really like to avoid a fork, it's not worth doing dual work. Did you ping ofono devs at irc?  Also have you sendt upstream patches? If a fork is the way you want to go, you will need to rename it as the existing packages need to follow upstream, we can't just rip an existing packages away from upstream.

Best regards,
Marius

Apr 14, 2021 20:21:18 Chris Talbot <chris@talbothome.com>:

> Hello All,
> 
> In talking to the Debian Developer Mr. Federico Ceratto, since I have
> been unable to get a hold of the Ofono Maintainers, the best course of
> action for packaging mmsd into Debian is to simply fork the project and
> submit my version upstream for packaging in Debian. My repository is
> here: https://source.puri.sm/kop316/mmsd/
> 
> I am sending this so the relavent parties are aware of this, and to
> indicate that I no longer intend on trying to get a hold of upstream
> mmsd to try and submit patches.
> 
> For the Purism Employees, I am additionally asking for permission to
> keep hosting mmsd on https://source.puri.sm/ . I have been extremely
> appreciative in using it and I am happy to keep it there, but I want to
> be neighboorly and ask if it is okay for me to keep it there. If it is
> not, I completely understand and I am fine with moving it to a new
> host.
> 
> If you have any questions, comments, or concern, please reach out to
> me.
> 
> -- 
> Respectfully,
> Chris Talbot
> _______________________________________________
> ofono mailing list -- ofono@ofono.org
> To unsubscribe send an email to ofono-leave@ofono.org

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [Debian-on-mobile-maintainers] Forking on MMSD
  2021-04-14 18:30   ` [Debian-on-mobile-maintainers] " Guido Günther
@ 2021-04-14 18:46     ` Chris Talbot
  2021-04-15  9:10       ` Guido Günther
  0 siblings, 1 reply; 19+ messages in thread
From: Chris Talbot @ 2021-04-14 18:46 UTC (permalink / raw)
  To: Guido Günther
  Cc: ofono, netdev, debian-on-mobile-maintainers, librem-5-dev,
	982250, 985893

Hello,

On Wed, 2021-04-14 at 20:30 +0200, Guido Günther wrote:
> Hi,
> On Wed, Apr 14, 2021 at 02:21:04PM -0400, Chris Talbot wrote:
> > Hello All,
> > 
> > In talking to the Debian Developer Mr. Federico Ceratto, since I
> > have
> > been unable to get a hold of the Ofono Maintainers, the best course
> > of
> > action for packaging mmsd into Debian is to simply fork the project
> > and
> > submit my version upstream for packaging in Debian. My repository
> > is
> > here: https://source.puri.sm/kop316/mmsd/
> > 
> > I am sending this so the relavent parties are aware of this, and to
> > indicate that I no longer intend on trying to get a hold of
> > upstream
> > mmsd to try and submit patches.
> > 
> > For the Purism Employees, I am additionally asking for permission
> > to
> > keep hosting mmsd on https://source.puri.sm/ . I have been
> > extremely
> > appreciative in using it and I am happy to keep it there, but I
> > want to
> > be neighboorly and ask if it is okay for me to keep it there. If it
> > is
> > not, I completely understand and I am fine with moving it to a new
> > host.
> 
> Keeping your ofono version on source.puri.sm is certainly welcome!
> Cheers,
>  -- Guido
> 
> > 
> > If you have any questions, comments, or concern, please reach out
> > to
> > me.
> > 
> > -- 
> > Respectfully,
> > Chris Talbot
> > 
> > 
> > _______________________________________________
> > Debian-on-mobile-maintainers mailing list
> > Debian-on-mobile-maintainers@alioth-lists.debian.net
> > https://alioth-lists.debian.net/cgi-bin/mailman/listinfo/debian-on-mobile-maintainers
> > 
Thank you for allowing me to keep hosting it there.

Since it is now a fork, I added Mr. Ceratto, Mr. Farraris (a-wai), and
Mr. Clayton Craft (craftyguy, a pmOS developer) as maintainers. Is
there a wish for a Purism maintainer to be added as well? 

Respectfully,
Chris Talbot


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: Forking on MMSD
  2021-04-14 18:21 ` Forking on MMSD Chris Talbot
  2021-04-14 18:30   ` [Debian-on-mobile-maintainers] " Guido Günther
  2021-04-14 18:39   ` Marius Gripsgard
@ 2021-04-14 19:29   ` Pavel Machek
  2021-04-14 21:11     ` Bug#985893: " Paul Wise
  2 siblings, 1 reply; 19+ messages in thread
From: Pavel Machek @ 2021-04-14 19:29 UTC (permalink / raw)
  To: Chris Talbot
  Cc: ofono, netdev, debian-on-mobile-maintainers, librem-5-dev,
	982250, 985893

[-- Attachment #1: Type: text/plain, Size: 570 bytes --]

Hi!

> In talking to the Debian Developer Mr. Federico Ceratto, since I have
> been unable to get a hold of the Ofono Maintainers, the best course of
> action for packaging mmsd into Debian is to simply fork the project and
> submit my version upstream for packaging in Debian. My repository is
> here: https://source.puri.sm/kop316/mmsd/

Ofono maintainers are normally pretty responsive, and yes, you seem to
be cc-ing the right list.

I don't think forking ofono is good idea.

Best regards,
								Pavel
-- 
http://www.livejournal.com/~pavelmachek

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 195 bytes --]

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: Bug#985893: Forking on MMSD
  2021-04-14 19:29   ` Pavel Machek
@ 2021-04-14 21:11     ` Paul Wise
  0 siblings, 0 replies; 19+ messages in thread
From: Paul Wise @ 2021-04-14 21:11 UTC (permalink / raw)
  To: Pavel Machek, 985893
  Cc: Chris Talbot, ofono, netdev, debian-on-mobile-maintainers,
	librem-5-dev, 982250

On Wed, Apr 14, 2021 at 7:42 PM Pavel Machek wrote:

> I don't think forking ofono is good idea.

I'd like to point out that this isn't ofono that is being forked, but mmsd.

-- 
bye,
pabs

https://wiki.debian.org/PaulWise

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: Bug#985893: Forking on MMSD
  2021-04-14 18:39   ` Marius Gripsgard
@ 2021-04-14 22:09     ` Wookey
  2021-04-15  0:12       ` Chris Talbot
  0 siblings, 1 reply; 19+ messages in thread
From: Wookey @ 2021-04-14 22:09 UTC (permalink / raw)
  To: Marius Gripsgard, 985893
  Cc: Chris Talbot, ofono, netdev, debian-on-mobile-maintainers,
	librem-5-dev, 982250

[-- Attachment #1: Type: text/plain, Size: 1767 bytes --]

On 2021-04-14 18:39 +0000, Marius Gripsgard wrote:

> I would really like to avoid a fork, it's not worth doing dual
> work. Did you ping ofono devs at irc?  Also have you sent upstream
> patches? If a fork is the way you want to go, you will need to
> rename it as the existing packages need to follow upstream, we can't
> just rip an existing packages away from upstream.

Debian can package mmsd with whatever set of patches it sees fit. If
the end result is ChrisT's version, with Modem Manager support, then I
think that's reasonable. mmsd is not currently packaged in debian so I
don't think a rename is required. Ultimately it's up to maintainers to
choose which upstream is most appropriate. There used to be only one,
but increasingly one gets a choice of varying degrees of active
maintenance. (This can be a huge pain making life quite awkward for
maintainers, and I find Debian is the only org trying to unify a
diverse set of versions where a load of people have scratched their
own itch and then just left it like that.)

Ultimately we want the best functionality for our users, and if the
old upstream has been inactive for years then using this new,
maintained version of mmsd may well be the best course. Efforts should
continue to either give Chris access to the original repo or
officially declare it 'under new management' so that there is a
canonical place for the codebase, but in the meantime it's OK for
debian to have a big patch.

Versioning could be tricky in some situations, but SFACT the ofono
mmsd is just 0.0 so the debian version can be 0.0.something and remain
compatible with a shift back to that repo at some point.

Wookey
-- 
Principal hats:  Linaro, Debian, Wookware, ARM
http://wookware.org/

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: Bug#985893: Forking on MMSD
  2021-04-14 22:09     ` Bug#985893: " Wookey
@ 2021-04-15  0:12       ` Chris Talbot
  0 siblings, 0 replies; 19+ messages in thread
From: Chris Talbot @ 2021-04-15  0:12 UTC (permalink / raw)
  To: Wookey, Marius Gripsgard, 985893
  Cc: ofono, netdev, debian-on-mobile-maintainers, librem-5-dev, 982250

Hello!

On Wed, 2021-04-14 at 23:09 +0100, Wookey wrote:
> On 2021-04-14 18:39 +0000, Marius Gripsgard wrote:
> 
> > I would really like to avoid a fork, it's not worth doing dual
> > work. Did you ping ofono devs at irc?  Also have you sent upstream
> > patches? If a fork is the way you want to go, you will need to
> > rename it as the existing packages need to follow upstream, we
> > can't
> > just rip an existing packages away from upstream.
> 
> Debian can package mmsd with whatever set of patches it sees fit. If
> the end result is ChrisT's version, with Modem Manager support, then
> I
> think that's reasonable. mmsd is not currently packaged in debian so
> I
> don't think a rename is required. Ultimately it's up to maintainers
> to
> choose which upstream is most appropriate. There used to be only one,
> but increasingly one gets a choice of varying degrees of active
> maintenance. (This can be a huge pain making life quite awkward for
> maintainers, and I find Debian is the only org trying to unify a
> diverse set of versions where a load of people have scratched their
> own itch and then just left it like that.)
> 

At this point, fork of mmsd should still work with ofono. I have not
disturbed anything ofono related, and have made several improvements to
the core that should benefit ofono too.

I would in addition welcome someone from ofono to work with me! I would
rather mmsd work with both stacks (as we all benefit from that). The
Mobian and PostmarketOS developers have welcomed me, and I am happy to
work with you all too. I joined the UBports matrix channel and
introduced myself (in addition to asking how you all contact the ofono
folks), you are free to reach out to me.

> Ultimately we want the best functionality for our users, and if the
> old upstream has been inactive for years then using this new,
> maintained version of mmsd may well be the best course. Efforts
> should
> continue to either give Chris access to the original repo or
> officially declare it 'under new management' so that there is a
> canonical place for the codebase, but in the meantime it's OK for
> debian to have a big patch.
> 

I admittedly do not know who to contact for repo access? I asked on the
Kernelnewbies IRC/Mailing list (as I am a bit of a kernel newbie), but
I did not hear anything back.

I am not trying to start a fork because I want to, and if you look at
Ofono's ML history, you can see that I have tried a lot to work with
upstream. I am starting a fork because I feel this is the only way I
can really move forward in getting MMS working. Without MMS,
unfortunately the Pinephone I have is little more than a toy with me,
and I put a lot of work into getting MMS working on the Modem Manager
stack.

> Versioning could be tricky in some situations, but SFACT the ofono
> mmsd is just 0.0 so the debian version can be 0.0.something and
> remain
> compatible with a shift back to that repo at some point.
> 
> Wookey

Thank you!

Respectfully,
Chris Talbot


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [Debian-on-mobile-maintainers] Forking on MMSD
  2021-04-14 18:46     ` Chris Talbot
@ 2021-04-15  9:10       ` Guido Günther
  0 siblings, 0 replies; 19+ messages in thread
From: Guido Günther @ 2021-04-15  9:10 UTC (permalink / raw)
  To: Chris Talbot
  Cc: ofono, netdev, debian-on-mobile-maintainers, librem-5-dev,
	982250, 985893

Hi Chris,
On Wed, Apr 14, 2021 at 02:46:30PM -0400, Chris Talbot wrote:
> Hello,
> 
> On Wed, 2021-04-14 at 20:30 +0200, Guido Günther wrote:
> > Hi,
> > On Wed, Apr 14, 2021 at 02:21:04PM -0400, Chris Talbot wrote:
> > > Hello All,
> > > 
> > > In talking to the Debian Developer Mr. Federico Ceratto, since I
> > > have
> > > been unable to get a hold of the Ofono Maintainers, the best course
> > > of
> > > action for packaging mmsd into Debian is to simply fork the project
> > > and
> > > submit my version upstream for packaging in Debian. My repository
> > > is
> > > here: https://source.puri.sm/kop316/mmsd/
> > > 
> > > I am sending this so the relavent parties are aware of this, and to
> > > indicate that I no longer intend on trying to get a hold of
> > > upstream
> > > mmsd to try and submit patches.
> > > 
> > > For the Purism Employees, I am additionally asking for permission
> > > to
> > > keep hosting mmsd on https://source.puri.sm/ . I have been
> > > extremely
> > > appreciative in using it and I am happy to keep it there, but I
> > > want to
> > > be neighboorly and ask if it is okay for me to keep it there. If it
> > > is
> > > not, I completely understand and I am fine with moving it to a new
> > > host.
> > 
> > Keeping your ofono version on source.puri.sm is certainly welcome!
> > Cheers,
> >  -- Guido
> > 
> > > 
> > > If you have any questions, comments, or concern, please reach out
> > > to
> > > me.
> > > 
> > > -- 
> > > Respectfully,
> > > Chris Talbot
> > > 
> > > 
> > > _______________________________________________
> > > Debian-on-mobile-maintainers mailing list
> > > Debian-on-mobile-maintainers@alioth-lists.debian.net
> > > https://alioth-lists.debian.net/cgi-bin/mailman/listinfo/debian-on-mobile-maintainers
> > > 
> Thank you for allowing me to keep hosting it there.

Great. If you really want to maintain a fork i'd consider renaming to
make that obvious (e.g. mm-mmsd) to avoid confusion within distros.

> Since it is now a fork, I added Mr. Ceratto, Mr. Farraris (a-wai), and
> Mr. Clayton Craft (craftyguy, a pmOS developer) as maintainers. Is
> there a wish for a Purism maintainer to be added as well?
I think sadiq and devrtz were the ones most involved so far but i think
working via MRs is fine since that allows to establish a workflow.

Cheers,
 -- Guido


> Respectfully,
> Chris Talbot
> 

^ permalink raw reply	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2021-04-15  9:11 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-04-10 14:13 [PATCH 0/9] Updates for mmsd Chris Talbot
2021-04-10 14:17 ` [PATCH 1/9] Fix mmsd to work with T-mobile Chris Talbot
2021-04-10 14:20   ` [PATCH 2/9] Ensure Compatibility with Telus Canada Chris Talbot
2021-04-10 14:20     ` [PATCH 3/9] Ensure Compatibility with AT&T Chris Talbot
2021-04-10 14:21       ` [PATCH 4/9] Fix issue if there is an empty string in encoded text Chris Talbot
2021-04-10 14:22         ` [PATCH 5/9] Allow for a user configurable maximum attachment size Chris Talbot
2021-04-10 14:22           ` [PATCH 6/9] Update README Chris Talbot
2021-04-10 14:23             ` [PATCH 7/9] Fix Draft and Sent Bugs Chris Talbot
2021-04-10 14:23               ` [PATCH 8/9] Allow Maintainer mode to compile without -WError Chris Talbot
2021-04-10 14:24                 ` [PATCH 9/9] Enable support for Modem Manager Chris Talbot
2021-04-14 18:21 ` Forking on MMSD Chris Talbot
2021-04-14 18:30   ` [Debian-on-mobile-maintainers] " Guido Günther
2021-04-14 18:46     ` Chris Talbot
2021-04-15  9:10       ` Guido Günther
2021-04-14 18:39   ` Marius Gripsgard
2021-04-14 22:09     ` Bug#985893: " Wookey
2021-04-15  0:12       ` Chris Talbot
2021-04-14 19:29   ` Pavel Machek
2021-04-14 21:11     ` Bug#985893: " Paul Wise

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 NNTP newsgroup(s).