MM7/SOAP implementation now tested + misc bug fixes
This commit is contained in:
parent
7967dcc45f
commit
7497919605
|
@ -15,7 +15,7 @@ mm4-queue-directory = /tmp/spool/mm4
|
|||
mmbox-root-directory = /tmp/spool/mmbox
|
||||
max-send-threads = 5
|
||||
send-mail-prog = /usr/sbin/sendmail -f '%f' '%t'
|
||||
unified-prefix = "+25637,037,77"
|
||||
unified-prefix = "+25637,037,37"
|
||||
maximum-send-attempts = 50
|
||||
default-message-expiry = 360000
|
||||
queue-run-interval = 0.1
|
||||
|
@ -23,8 +23,8 @@ send-attempt-back-off = 300
|
|||
sendsms-url = http://localhost:13013/cgi-bin/sendsms
|
||||
sendsms-username = tester
|
||||
sendsms-password = foobar
|
||||
#sendsms-global-sender = 198
|
||||
mms-port = 1981
|
||||
mm7-port = 1982
|
||||
#allow-ip = 192.168.129.11
|
||||
email2mms-relay-prefixes = "037;035;25637"
|
||||
ua-profile-cache-directory = /tmp/misc/profiles
|
||||
|
@ -40,6 +40,16 @@ mms-to-email-txt = "This is a multimedia message (HTML suppressed)"
|
|||
mms-to-email-html = "This is a multimedia message powered by <emph>Digital Solutions</emph>"
|
||||
mms-message-too-large-txt = "You have received a multimedia message from %S that is too large for your phone. Go to xxx to view it"
|
||||
|
||||
group = mms-vasp
|
||||
vasp-id = newscorp
|
||||
type = soap
|
||||
short-code = 111
|
||||
vasp-username = newscorp
|
||||
vasp-password = news123
|
||||
vasp-url = http://localhost:23535/
|
||||
mmsc-username = user
|
||||
mmsc-password = secret
|
||||
|
||||
group = mmsproxy
|
||||
name = "A test mms proxy"
|
||||
host = ds.co.ug
|
||||
|
|
|
@ -51,7 +51,9 @@ This document describes the installation and usage of the MMS Gateway.
|
|||
<LI><A HREF="#Section_.1.2.3">Installing Required Components</A></LI>
|
||||
</UL></LI>
|
||||
<LI><A HREF="#Section_.1.3">Chapter 3: Running the Gateway</A><UL>
|
||||
<LI><A HREF="#Section_.1.3.1">Configuration File</A></LI>
|
||||
<LI><A HREF="#Section_.1.3.1">General Configuration File</A></LI>
|
||||
<LI><A HREF="#mm7">MM7 Configuration</A></LI>
|
||||
<LI><A HREF="#mm4">MM4 Configuration File</A></LI>
|
||||
</UL></LI>
|
||||
<LI><A HREF="#Section_.1.4">Chapter 4: Gateway Architecture</A><UL>
|
||||
<LI><A HREF="#Section_.1.4.1">MMS Proxy</A></LI>
|
||||
|
@ -238,8 +240,8 @@ content depending on the capabilities of the receiving terminal
|
|||
|
||||
|
||||
<p>
|
||||
Currently there is no support for VAS via MM7 protocols (SOAP or
|
||||
EIAF), but this is planned and should be available soon.
|
||||
Currently, only the SOAP MM7 requests are supported. Nokia/EAIF is
|
||||
planned and should be available soon.
|
||||
<br>
|
||||
The Gateway is designed and tested to conform to Open Mobile Alliance
|
||||
(OMA), WAP and 3rd Generation Partnership Project (3GPP) MMS standards
|
||||
|
@ -510,7 +512,8 @@ argument on the command line (default is <tt>mmsc.conf</tt>). The
|
|||
configuration file controls most aspects of
|
||||
the operation of the gateway. </p>
|
||||
|
||||
<H4><!--TableOfContentsAnchor:Begin--><A NAME="Section_.1.3.1"></A><!--TableOfContentsAnchor:End-->Configuration File</H4>
|
||||
<H4><!--TableOfContentsAnchor:Begin--><A
|
||||
NAME="Section_.1.3.1"></A><!--TableOfContentsAnchor:End-->General Configuration File</H4>
|
||||
|
||||
<p >The configuration file format is the same as that used
|
||||
by Kannel. The configuration file consists of groups of configuration
|
||||
|
@ -912,6 +915,22 @@ lists all the configuration directives</p>
|
|||
is 8191).
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td valign=top >
|
||||
<tt>mm7-port</tt>
|
||||
|
||||
</td>
|
||||
<td valign=top >
|
||||
Integer
|
||||
</td>
|
||||
<td valign=top >
|
||||
Port on which <tt>mmsproxy</tt> listens for MM7 requests from Value
|
||||
Added Services providers. If this port is not supplied, the MM7
|
||||
sub-system is not started.
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td valign=top >
|
||||
<tt>allow-ip</tt>
|
||||
|
@ -1243,6 +1262,180 @@ lists all the configuration directives</p>
|
|||
</table>
|
||||
<br>
|
||||
|
||||
<a name="mm7"></a>
|
||||
<h4>MM7 Configuration</h4>
|
||||
|
||||
<!--- MM7 stuff -->
|
||||
<p >MMS Value-Added Service Providers (VASPs) are configured using
|
||||
one or more <i>mms-vasp</i> groups:</p>
|
||||
|
||||
<br>
|
||||
<tt>
|
||||
group =
|
||||
mms-vasp<br>
|
||||
|
||||
vasp-id = newcorp<br>
|
||||
|
||||
type =
|
||||
soap<br>
|
||||
|
||||
short-code
|
||||
= 100<br>
|
||||
vasp-username
|
||||
= newscorp<br>
|
||||
vasp-password
|
||||
= news123<br>
|
||||
|
||||
vasp-url
|
||||
= http://example.vasp.com:8080/mm7<br>
|
||||
mmsc-username
|
||||
= mymmsc<br>
|
||||
mmsc-password
|
||||
= mypass<br>
|
||||
|
||||
|
||||
<br>
|
||||
</tt>
|
||||
|
||||
<br>
|
||||
|
||||
<table border=0 cellspacing=2 cellpadding=2 >
|
||||
<tr>
|
||||
<td valign=top >
|
||||
<b>Variable</b>
|
||||
</td>
|
||||
<td valign=top >
|
||||
<b>Type</b>
|
||||
</td>
|
||||
<td valign=top >
|
||||
<b>Description</b>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign=top >
|
||||
<tt>group</tt>
|
||||
|
||||
</td>
|
||||
<td valign=top >
|
||||
String
|
||||
</td>
|
||||
<td valign=top >
|
||||
Mandatory:
|
||||
<tt>mms-vasp</tt>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign=top >
|
||||
<tt>vasp-id</tt>
|
||||
</td>
|
||||
<td valign=top >
|
||||
String
|
||||
</td>
|
||||
<td valign=top >
|
||||
User friendly
|
||||
name
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign=top >
|
||||
<tt>type</tt>
|
||||
</td>
|
||||
<td valign=top >
|
||||
String
|
||||
</td>
|
||||
<td valign=top >
|
||||
This should be one of: soap, eaif (<i>note: only soap is supported currently</i>)
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign=top >
|
||||
<tt>short-code</tt>
|
||||
</td>
|
||||
<td valign=top >
|
||||
Number
|
||||
</td>
|
||||
<td valign=top >
|
||||
Short number for this VASP: Messages received by Mbuni to this
|
||||
number are routed to the VASP via MM7.
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td valign=top >
|
||||
<tt>vasp-url</tt>
|
||||
</td>
|
||||
<td valign=top >
|
||||
String
|
||||
</td>
|
||||
<td valign=top >
|
||||
Outgoing messages to the VASP are sent via this URL (using HTTP POST)
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign=top >
|
||||
<tt>mmsc-username</tt>
|
||||
</td>
|
||||
<td valign=top >
|
||||
String
|
||||
</td>
|
||||
<td valign=top >
|
||||
Outgoing HTTP authentication: The username Mbuni must use when sending data
|
||||
to the VASP
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td valign=top >
|
||||
<tt>mmsc-password</tt>
|
||||
</td>
|
||||
<td valign=top >
|
||||
String
|
||||
</td>
|
||||
<td valign=top >
|
||||
Outgoing HTTP authentication: password Mbuni must use when sending data
|
||||
to the VASP
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td valign=top >
|
||||
<tt>vasp-username</tt>
|
||||
</td>
|
||||
<td valign=top >
|
||||
String
|
||||
</td>
|
||||
<td valign=top >
|
||||
Incoming HTTP authentication: The username used by the VASP to
|
||||
authenticate itself to Mbuni when sending data
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td valign=top >
|
||||
<tt>vasp-password</tt>
|
||||
</td>
|
||||
<td valign=top >
|
||||
String
|
||||
</td>
|
||||
<td valign=top >
|
||||
Incoming HTTP authentication: The password used by the VASP to
|
||||
authenticate itself to Mbuni when sending data
|
||||
to the VASP
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
|
||||
|
||||
Note that currently only HTTP Basic authentication scheme is supported
|
||||
by Mbuni (for both incoming and out-going requests).
|
||||
|
||||
|
||||
<a name="mm4"></a>
|
||||
<h4>MM4 Configuration</h4>
|
||||
|
||||
<!-- Foreign MMSC stuff -->
|
||||
|
||||
<p >Foreign MMS
|
||||
Gateways are configured using one or more <i>mmsproxy</i> groups:</p>
|
||||
|
||||
|
@ -1481,6 +1674,8 @@ re-formatted as MIME, sender and recipient addresses normalised as RFC
|
|||
822 addresses, and the message passed to the mailer.
|
||||
<li> If the message is destined for a foreign gateway, it is coded
|
||||
as MIME and passed to the mailer for delivery via SMTP
|
||||
<li>If the the message is destined for a VASP (identified by short
|
||||
code), then it is sent using MM7 protocols to the relevant VASP.
|
||||
<li> If the message cannot be delivered, the sender is notified.
|
||||
</ol>
|
||||
</ol>
|
||||
|
|
|
@ -696,12 +696,6 @@ diff -Naur gateway-1.4.0/gw/smsbox.c gateway-1.4.0-patched/gw/smsbox.c
|
|||
*status = HTTP_BAD_REQUEST;
|
||||
msg_destroy(msg);
|
||||
if (r == -2) {
|
||||
diff -Naur gateway-1.4.0/gw/smsc/.gdb_history gateway-1.4.0-patched/gw/smsc/.gdb_history
|
||||
--- gateway-1.4.0/gw/smsc/.gdb_history Thu Jan 1 03:00:00 1970
|
||||
+++ gateway-1.4.0-patched/gw/smsc/.gdb_history Thu Feb 10 10:49:06 2005
|
||||
@@ -0,0 +1,2 @@
|
||||
+p 1<<4
|
||||
+q
|
||||
diff -Naur gateway-1.4.0/gw/xml_shared.h gateway-1.4.0-patched/gw/xml_shared.h
|
||||
--- gateway-1.4.0/gw/xml_shared.h Thu Jan 22 17:08:24 2004
|
||||
+++ gateway-1.4.0-patched/gw/xml_shared.h Fri Jan 28 17:23:22 2005
|
||||
|
@ -723,8 +717,8 @@ diff -Naur gateway-1.4.0/gw/xml_shared.h gateway-1.4.0-patched/gw/xml_shared.h
|
|||
/*
|
||||
diff -Naur gateway-1.4.0/gwlib/cfg.def gateway-1.4.0-patched/gwlib/cfg.def
|
||||
--- gateway-1.4.0/gwlib/cfg.def Mon Jun 28 18:18:35 2004
|
||||
+++ gateway-1.4.0-patched/gwlib/cfg.def Mon Mar 21 12:12:16 2005
|
||||
@@ -544,6 +544,61 @@
|
||||
+++ gateway-1.4.0-patched/gwlib/cfg.def Tue Apr 12 11:50:00 2005
|
||||
@@ -544,6 +544,73 @@
|
||||
OCTSTR(unified-prefix)
|
||||
)
|
||||
|
||||
|
@ -749,6 +743,7 @@ diff -Naur gateway-1.4.0/gwlib/cfg.def gateway-1.4.0-patched/gwlib/cfg.def
|
|||
+ OCTSTR(sendsms-password)
|
||||
+ OCTSTR(sendsms-global-sender)
|
||||
+ OCTSTR(mms-port)
|
||||
+ OCTSTR(mm7-port)
|
||||
+ OCTSTR(allow-ip)
|
||||
+ OCTSTR(deny-ip)
|
||||
+ OCTSTR(email2mms-relay-prefixes)
|
||||
|
@ -782,10 +777,118 @@ diff -Naur gateway-1.4.0/gwlib/cfg.def gateway-1.4.0-patched/gwlib/cfg.def
|
|||
+ OCTSTR(allowed-prefix)
|
||||
+ OCTSTR(denied-prefix)
|
||||
+)
|
||||
+
|
||||
+MULTI_GROUP(mms-vasp,
|
||||
+ OCTSTR(vasp-id)
|
||||
+ OCTSTR(type)
|
||||
+ OCTSTR(short-code)
|
||||
+ OCTSTR(vasp-username)
|
||||
+ OCTSTR(vasp-password)
|
||||
+ OCTSTR(vasp-url)
|
||||
+ OCTSTR(mmsc-username)
|
||||
+ OCTSTR(mmsc-password)
|
||||
+)
|
||||
+
|
||||
#undef OCTSTR
|
||||
#undef SINGLE_GROUP
|
||||
#undef MULTI_GROUP
|
||||
diff -Naur gateway-1.4.0/gwlib/mime.c gateway-1.4.0-patched/gwlib/mime.c
|
||||
--- gateway-1.4.0/gwlib/mime.c Wed Aug 11 19:41:29 2004
|
||||
+++ gateway-1.4.0-patched/gwlib/mime.c Thu Apr 14 08:31:05 2005
|
||||
@@ -191,11 +191,11 @@
|
||||
value = http_header_value(headers, octstr_imm("Content-Type"));
|
||||
boundary = http_get_header_parameter(value, octstr_imm("boundary"));
|
||||
if (boundary == NULL) {
|
||||
- boundary = octstr_format("_MIME_boundary-%d-%ld_%c_%c_bd%d",
|
||||
+ boundary = octstr_format("=_MIME_boundary_%d_%ld_%c_%c_bd%d",
|
||||
random(), (long)time(NULL), 'A' + (random()%26),
|
||||
'a'+(random() % 26), random());
|
||||
- octstr_append(value, octstr_imm("; boundary="));
|
||||
- octstr_append(value, boundary);
|
||||
+ octstr_format_append(value, "; boundary=\"%S\"", boundary);
|
||||
+
|
||||
http_header_remove_all(headers, "Content-Type");
|
||||
http_header_add(headers, "Content-Type", octstr_get_cstr(value));
|
||||
http_header_add(headers, "MIME-Version", "1.0");
|
||||
@@ -214,8 +214,8 @@
|
||||
MIMEEntity *e = list_get(m->multiparts, i);
|
||||
Octstr *body;
|
||||
|
||||
- if (i != 0)
|
||||
- octstr_append(mime, octstr_imm("\r\n"));
|
||||
+ if (i != 0)
|
||||
+ octstr_append(mime, octstr_imm("\r\n"));
|
||||
octstr_append(mime, octstr_imm("\r\n--"));
|
||||
octstr_append(mime, boundary);
|
||||
octstr_append(mime, octstr_imm("\r\n"));
|
||||
@@ -331,10 +331,13 @@
|
||||
else
|
||||
octstr_delete(entity, 0, 1);
|
||||
|
||||
- if (octstr_get_char(entity, octstr_len(entity) - 2) == '\r')
|
||||
+ if (octstr_get_char(entity, octstr_len(entity) - 2) == '\r' &&
|
||||
+ octstr_get_char(entity, octstr_len(entity) - 4) == '\r')
|
||||
octstr_delete(entity, octstr_len(entity) - 4, 4);
|
||||
+ else if (octstr_get_char(entity, octstr_len(entity) - 2) == '\r')
|
||||
+ octstr_delete(entity, octstr_len(entity) - 2, 2);
|
||||
else
|
||||
- octstr_delete(entity, octstr_len(entity) - 2, 2);
|
||||
+ octstr_delete(entity, octstr_len(entity) - 1, 1);
|
||||
|
||||
|
||||
debug("mime.parse",0,"MIME multipart: Parsing entity:");
|
||||
@@ -443,6 +446,34 @@
|
||||
return body;
|
||||
}
|
||||
|
||||
+int mime_entity_body_and_headers(MIMEEntity *m, Octstr **body, List **headers)
|
||||
+{
|
||||
+ Octstr *os;
|
||||
+ ParseContext *context;
|
||||
+
|
||||
+ gw_assert(m != NULL && m->headers != NULL);
|
||||
+
|
||||
+ os = mime_entity_to_octstr(m);
|
||||
+ context = parse_context_create(os);
|
||||
+
|
||||
+ *headers = http_create_empty_headers();
|
||||
+
|
||||
+ /* parse the headers up to the body */
|
||||
+ if ((read_mime_headers(context, *headers) != 0) ||*headers == NULL) {
|
||||
+ debug("mime.parse",0,"Failed to read MIME headers in Octstr block:");
|
||||
+ octstr_dump(os, 0);
|
||||
+ parse_context_destroy(context);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ /* the rest is the body */
|
||||
+ *body = parse_get_rest(context);
|
||||
+
|
||||
+ octstr_destroy(os);
|
||||
+
|
||||
+ parse_context_destroy(context);
|
||||
+ return 0;
|
||||
+}
|
||||
|
||||
/********************************************************************
|
||||
* Routines for debugging purposes.
|
||||
diff -Naur gateway-1.4.0/gwlib/mime.h gateway-1.4.0-patched/gwlib/mime.h
|
||||
--- gateway-1.4.0/gwlib/mime.h Mon Jan 26 18:04:57 2004
|
||||
+++ gateway-1.4.0-patched/gwlib/mime.h Wed Apr 13 17:59:48 2005
|
||||
@@ -141,6 +141,13 @@
|
||||
Octstr *mime_entity_body(MIMEEntity *m);
|
||||
|
||||
/*
|
||||
+ * Take a MIME multipart representation and return the headers and body as would
|
||||
+ * result from turning it into a string.
|
||||
+ * this then serves for http header and body...
|
||||
+ */
|
||||
+int mime_entity_body_and_headers(MIMEEntity *m, Octstr **body, List **headers);
|
||||
+
|
||||
+/*
|
||||
* Dump the structure (hicharchical view) of the MIME representation
|
||||
* structure into our DEBUG log level facility.
|
||||
*/
|
||||
diff -Naur gateway-1.4.0/wap/wsp_headers.c gateway-1.4.0-patched/wap/wsp_headers.c
|
||||
--- gateway-1.4.0/wap/wsp_headers.c Sun Aug 8 23:39:56 2004
|
||||
+++ gateway-1.4.0-patched/wap/wsp_headers.c Tue Mar 15 12:26:43 2005
|
||||
|
|
|
@ -6,6 +6,12 @@
|
|||
|
||||
#define content(n) ((n)->xmlChildrenNode ? dfltstr(((n)->xmlChildrenNode)->content) : dfltstr((n)->content))
|
||||
|
||||
struct MSoapMsg_t {
|
||||
List *envelope; /* of http headers. */
|
||||
MIMEEntity *msg; /* XXX - be sure to copy some headers to this from envelope before convert...*/
|
||||
};
|
||||
|
||||
/* We expect ISO formatted time, or interval. */
|
||||
|
||||
static Octstr *parse_time(char *s)
|
||||
{
|
||||
|
@ -15,9 +21,12 @@ static Octstr *parse_time(char *s)
|
|||
|
||||
octstr_strip_blanks(p);
|
||||
|
||||
if (s && s[0] != 'P')
|
||||
return p;
|
||||
else
|
||||
if (s && s[0] != 'P') {
|
||||
struct universaltime tt;
|
||||
if (date_parse_iso(&tt, p) >= 0)
|
||||
t = date_convert_universal(&tt);
|
||||
goto done;
|
||||
} else
|
||||
i++;
|
||||
|
||||
while (i < octstr_len(p)) {
|
||||
|
@ -59,8 +68,9 @@ static Octstr *parse_time(char *s)
|
|||
}
|
||||
}
|
||||
|
||||
done:
|
||||
octstr_destroy(p);
|
||||
return date_create_iso(t);
|
||||
return date_format_http(t);
|
||||
}
|
||||
|
||||
static int parse_header(xmlNodePtr node, List *headers, int *sigparent)
|
||||
|
@ -108,12 +118,21 @@ static int parse_header(xmlNodePtr node, List *headers, int *sigparent)
|
|||
break;
|
||||
case MM7_TAG_SenderIdentification:
|
||||
case MM7_TAG_Recipients:
|
||||
|
||||
skip = 1;
|
||||
break;
|
||||
|
||||
case MM7_TAG_Recipient:
|
||||
*sigparent = MM7_TAG_To; /* make it a To field. */
|
||||
|
||||
break;
|
||||
case MM7_TAG_To:
|
||||
case MM7_TAG_Cc:
|
||||
case MM7_TAG_Bcc:
|
||||
case MM7_TAG_Sender:
|
||||
case MM7_TAG_SenderAddress:
|
||||
skip = 1;
|
||||
|
||||
*sigparent = tag; /* We wait for number and stuff below. */
|
||||
break;
|
||||
case MM7_TAG_Content:
|
||||
|
@ -123,7 +142,7 @@ static int parse_header(xmlNodePtr node, List *headers, int *sigparent)
|
|||
}
|
||||
/* we keep 'cid:' bit. ignore the bit about adaptation. */
|
||||
break;
|
||||
|
||||
case MM7_TAG_ShortCode:
|
||||
case MM7_TAG_Number: /* we will not normalise number here, that's for upper level. */
|
||||
value = octstr_format("%s/TYPE=PLMN", nvalue);
|
||||
|
||||
|
@ -140,10 +159,12 @@ static int parse_header(xmlNodePtr node, List *headers, int *sigparent)
|
|||
octstr_insert(value, octstr_imm("+ "), 0);
|
||||
if (s)
|
||||
xmlFree(s);
|
||||
break;
|
||||
break;
|
||||
|
||||
case MM7_TAG_EarliestDeliveryTime:
|
||||
case MM7_TAG_ExpiryDate:
|
||||
case MM7_TAG_TimeStamp:
|
||||
case MM7_TAG_Date:
|
||||
value = parse_time(nvalue);
|
||||
break;
|
||||
|
||||
|
@ -169,8 +190,12 @@ static int parse_header(xmlNodePtr node, List *headers, int *sigparent)
|
|||
value = octstr_create(nvalue);
|
||||
octstr_strip_blanks(value);
|
||||
|
||||
if (!skip && tag >= 0)
|
||||
if (!skip && tag >= 0 && hname != NULL) {
|
||||
http_header_add(headers, hname, octstr_get_cstr(value));
|
||||
#if 1
|
||||
info(0, "parse.soap, h=%s, v=%s!", hname, octstr_get_cstr(value));
|
||||
#endif
|
||||
}
|
||||
octstr_destroy(value);
|
||||
|
||||
return 0;
|
||||
|
@ -193,7 +218,7 @@ MSoapMsg_t *mm7_parse_soap(List *headers, Octstr *body)
|
|||
MIMEEntity *mime = mime_http_to_entity(headers, body);
|
||||
Octstr *xml = NULL, *cloc;
|
||||
xmlDocPtr doc;
|
||||
MmsMsg *msg = NULL;
|
||||
MIMEEntity *msg = NULL;
|
||||
List *h;
|
||||
int s = -1;
|
||||
MSoapMsg_t *smsg = NULL;
|
||||
|
@ -214,9 +239,12 @@ MSoapMsg_t *mm7_parse_soap(List *headers, Octstr *body)
|
|||
} else
|
||||
xml = mime->body;
|
||||
|
||||
/* Don't free 'xml'! It is part of mime object. */
|
||||
if (!xml)
|
||||
goto done;
|
||||
|
||||
#if 1
|
||||
info(0, "XML sent is: %s!", octstr_get_cstr(xml));
|
||||
#endif
|
||||
doc = xmlParseMemory(octstr_get_cstr(xml), octstr_len(xml));
|
||||
if (!doc || !doc->xmlChildrenNode)
|
||||
goto done;
|
||||
|
@ -239,8 +267,10 @@ MSoapMsg_t *mm7_parse_soap(List *headers, Octstr *body)
|
|||
for (i = 0, n = list_len(mime->multiparts); i<n; i++) {
|
||||
MIMEEntity *x = list_get(mime->multiparts, i);
|
||||
Octstr *y = x ? http_header_value(x->headers, octstr_imm("Content-ID")) : NULL;
|
||||
char *cid = (y && octstr_get_char(y, 0) == '<') ? octstr_get_cstr(y) + 1 : (y ? octstr_get_cstr(y) : "");
|
||||
int cid_len = (y && octstr_get_char(y, 0) == '<') ? octstr_len(y) - 2 : (y ? octstr_len(y) : 0);
|
||||
|
||||
if (y && octstr_str_compare(y, loc) == 0)
|
||||
if (y && strncmp(loc, cid, cid_len) == 0)
|
||||
c = x;
|
||||
|
||||
if (y)
|
||||
|
@ -248,8 +278,9 @@ MSoapMsg_t *mm7_parse_soap(List *headers, Octstr *body)
|
|||
if (c)
|
||||
break;
|
||||
}
|
||||
|
||||
if (c)
|
||||
msg = mms_frommime(c);
|
||||
msg = mime_entity_duplicate(c);
|
||||
|
||||
octstr_destroy(cloc);
|
||||
}
|
||||
|
@ -260,11 +291,29 @@ MSoapMsg_t *mm7_parse_soap(List *headers, Octstr *body)
|
|||
done:
|
||||
if (mime)
|
||||
mime_entity_destroy(mime);
|
||||
if (xml)
|
||||
octstr_destroy(xml);
|
||||
return smsg;
|
||||
}
|
||||
|
||||
static int append_address(Octstr *p, Octstr *addr_spec)
|
||||
{
|
||||
Octstr *v = addr_spec;
|
||||
char *y;
|
||||
int j, ch = octstr_get_char(v, 0);
|
||||
if (ch == '-')
|
||||
y = " displayOnly=\"true\"";
|
||||
else
|
||||
y = "";
|
||||
j = octstr_case_search(v, octstr_imm("/TYPE=PLMN"),0);
|
||||
if (j >= 0) {
|
||||
Octstr *z = octstr_copy(v, 2, j-2); /* skip the initial char that is only for info purposes. */
|
||||
octstr_format_append(p, "<Number%s>%S</Number>\n", y, z);
|
||||
octstr_destroy(z);
|
||||
} else
|
||||
octstr_format_append(p, "<RFC2822Address%s>%s</RFC2822Address>\n",
|
||||
y, octstr_get_cstr(v) + 2); /* as above... */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void output_rcpt(char *hdr, List *hdrs, Octstr *p)
|
||||
{
|
||||
List *l = http_header_find_all(hdrs, hdr);
|
||||
|
@ -273,8 +322,6 @@ static void output_rcpt(char *hdr, List *hdrs, Octstr *p)
|
|||
|
||||
for (i = 0, n = list_len(l), x[0]=0; i < n; i++) {
|
||||
Octstr *h = NULL, *v = NULL;
|
||||
int ch, j;
|
||||
char *y;
|
||||
http_header_get(l, i, &h, &v);
|
||||
|
||||
if (octstr_str_compare(h, x) != 0) {
|
||||
|
@ -284,20 +331,7 @@ static void output_rcpt(char *hdr, List *hdrs, Octstr *p)
|
|||
octstr_format_append(p, "<%S>\n", h);
|
||||
}
|
||||
octstr_destroy(h);
|
||||
|
||||
ch = octstr_get_char(v, 0);
|
||||
if (ch == '-')
|
||||
y = " displayOnly=\"true\"";
|
||||
else
|
||||
y = "";
|
||||
j = octstr_case_search(v, octstr_imm("/TYPE=PLMN"),0);
|
||||
if (j > 0) {
|
||||
Octstr *z = octstr_copy(v, 2, j-2); /* skip the initial char that is only for info purposes. */
|
||||
octstr_format_append(p, "<Number%s>%S</Number>\n", y, z);
|
||||
octstr_destroy(z);
|
||||
} else
|
||||
octstr_format_append(p, "<RFC2822Address%s>%s</RFC2822Address>\n",
|
||||
y, octstr_get_cstr(v) + 2); /* as above... */
|
||||
append_address(p, v);
|
||||
octstr_destroy(v);
|
||||
}
|
||||
if (x[0]) /* close it off. */
|
||||
|
@ -306,13 +340,15 @@ static void output_rcpt(char *hdr, List *hdrs, Octstr *p)
|
|||
http_destroy_headers(l);
|
||||
}
|
||||
|
||||
#define XMLNSMM7 "http://www.3gpp.org/ftp/Specs/archive/23_series/23.140/schema/REL-5-MM7-1-3"
|
||||
#define XMLNSMM7 "http://www.3gpp.org/ftp/Specs/archive/23_series/23.140/schema/REL-5-MM7-1-0"
|
||||
/* Construct by hand. */
|
||||
Octstr *headers_to_soapxml(List *hdrs)
|
||||
{
|
||||
Octstr *s = octstr_create("<?xml version=\"1.0\" ?>\n");
|
||||
Octstr *p, *q, *fault, *mtype;
|
||||
Octstr *p, *q, *r, *fault, *mtype;
|
||||
int i, n;
|
||||
time_t t;
|
||||
int mtag;
|
||||
|
||||
octstr_append_cstr(s,
|
||||
"<env:Envelope xmlns:env=\"http://schemas.xmlsoap.org/soap/envelope/\">\n"
|
||||
|
@ -346,6 +382,7 @@ Octstr *headers_to_soapxml(List *hdrs)
|
|||
|
||||
|
||||
mtype = http_header_value(hdrs, octstr_imm("MessageType"));
|
||||
mtag = mms_string_to_mm7tag(mtype);
|
||||
|
||||
octstr_format_append(s, "<%S xmlns=\"%s\">\n", mtype, XMLNSMM7);
|
||||
|
||||
|
@ -356,8 +393,8 @@ Octstr *headers_to_soapxml(List *hdrs)
|
|||
|
||||
p = http_header_value(hdrs, octstr_imm("VASPID"));
|
||||
q = http_header_value(hdrs, octstr_imm("VASID"));
|
||||
|
||||
if (p || q) {
|
||||
r = http_header_value(hdrs, octstr_imm("SenderAddress"));
|
||||
if (p || q || r) {
|
||||
|
||||
octstr_append_cstr(s, "<SenderIdentification>\n");
|
||||
if (p)
|
||||
|
@ -366,19 +403,33 @@ Octstr *headers_to_soapxml(List *hdrs)
|
|||
if (q)
|
||||
octstr_format_append(s, "<VASID>%S</VASID>\n", q);
|
||||
|
||||
if (r) {
|
||||
Octstr *xx = octstr_create("");
|
||||
append_address(xx, r);
|
||||
octstr_format_append(s, "<SenderAddress>%S</SenderAddress>\n", xx);
|
||||
octstr_destroy(xx);
|
||||
}
|
||||
|
||||
octstr_append_cstr(s, "</SenderIdentification>\n");
|
||||
if (p) octstr_destroy(p);
|
||||
if (q) octstr_destroy(q);
|
||||
if (r) octstr_destroy(r);
|
||||
}
|
||||
|
||||
p = octstr_create("");
|
||||
if (mtag == MM7_TAG_SubmitReq ||
|
||||
mtag == MM7_TAG_DeliverReq) { /* Multiple recipients,... */
|
||||
output_rcpt("To", hdrs, p);
|
||||
output_rcpt("Cc", hdrs, p);
|
||||
output_rcpt("Bcc", hdrs, p);
|
||||
|
||||
output_rcpt("To", hdrs, p);
|
||||
output_rcpt("Cc", hdrs, p);
|
||||
output_rcpt("Bcc", hdrs, p);
|
||||
|
||||
if (octstr_len(p) > 0)
|
||||
octstr_format_append(s, "<Recipients>\n%S</Recipients>\n", p);
|
||||
if (octstr_len(p) > 0)
|
||||
octstr_format_append(s, "<Recipients>\n%S</Recipients>\n", p);
|
||||
} else if ((q = http_header_value(hdrs, octstr_imm("To"))) != NULL) {
|
||||
append_address(p, q);
|
||||
octstr_format_append(s, "<Recipient>\n%S</Recipient>\n", p);
|
||||
octstr_destroy(q);
|
||||
}
|
||||
octstr_destroy(p);
|
||||
|
||||
|
||||
|
@ -408,8 +459,17 @@ Octstr *headers_to_soapxml(List *hdrs)
|
|||
case MM7_TAG_replyChargingSize:
|
||||
case MM7_TAG_replyDeadline:
|
||||
case MM7_TAG_TransactionID:
|
||||
case MM7_TAG_StatusCode:
|
||||
case MM7_TAG_StatusText:
|
||||
case MM7_TAG_StatusCode:
|
||||
case MM7_TAG_StatusText:
|
||||
case MM7_TAG_Details:
|
||||
case MM7_TAG_SenderAddress:
|
||||
skip = 1;
|
||||
break;
|
||||
case MM7_TAG_Sender:
|
||||
p = octstr_create("");
|
||||
append_address(p, v);
|
||||
octstr_format_append(s, "<Sender>%S</Sender>\n", p);
|
||||
octstr_destroy(p);
|
||||
skip = 1;
|
||||
break;
|
||||
case MM7_TAG_Content:
|
||||
|
@ -432,11 +492,19 @@ Octstr *headers_to_soapxml(List *hdrs)
|
|||
octstr_append_cstr(s, "/>\n");
|
||||
skip = 1;
|
||||
break;
|
||||
|
||||
case MM7_TAG_EarliestDeliveryTime:
|
||||
case MM7_TAG_ExpiryDate:
|
||||
case MM7_TAG_TimeStamp:
|
||||
case MM7_TAG_Date:
|
||||
t = date_parse_http(v);
|
||||
octstr_destroy(v);
|
||||
v = date_create_iso(t); /* format as ISO time... */
|
||||
break;
|
||||
case MM7_TAG_Status:
|
||||
p = http_header_value(hdrs, octstr_imm("StatusCode"));
|
||||
q = http_header_value(hdrs, octstr_imm("StatusText"));
|
||||
|
||||
|
||||
octstr_append_cstr(s, "<Status>\n");
|
||||
if (p) {
|
||||
octstr_format_append(s, "<StatusCode>%S</StatusCode>\n", p);
|
||||
|
@ -446,6 +514,12 @@ Octstr *headers_to_soapxml(List *hdrs)
|
|||
octstr_format_append(s, "<StatusText>%S</StatusText>\n", q);
|
||||
octstr_destroy(q);
|
||||
}
|
||||
q = http_header_value(hdrs, octstr_imm("Details"));
|
||||
if (q) {
|
||||
octstr_format_append(s, "<Details>%S</Details>\n", q);
|
||||
octstr_destroy(q);
|
||||
}
|
||||
|
||||
octstr_append_cstr(s, "</Status>\n");
|
||||
skip = 1;
|
||||
break;
|
||||
|
@ -484,11 +558,12 @@ int mm7_soapmsg_to_httpmsg(MSoapMsg_t *m, List **hdrs, Octstr **body)
|
|||
mime = mime_entity_create();
|
||||
|
||||
if (m->msg) {
|
||||
MIMEEntity *c = mms_tomime(m->msg);
|
||||
Octstr *cloc = octstr_format("cid:<c%ld.%d.%c%c.msg>",
|
||||
MIMEEntity *c = mime_entity_duplicate(m->msg);
|
||||
Octstr *cloc = octstr_format("cid:c%ld.%d.%c%c.msg",
|
||||
time(NULL), random(),
|
||||
'A' + random() % 26,
|
||||
'a' + random() % 26);
|
||||
Octstr *cloc_str = octstr_format("<%s>", octstr_get_cstr(cloc) + 4);
|
||||
Octstr *envloc = octstr_format("<s%ld.%d.%c%c.msg>",
|
||||
time(NULL), random(),
|
||||
'A' + random() % 26,
|
||||
|
@ -497,14 +572,14 @@ int mm7_soapmsg_to_httpmsg(MSoapMsg_t *m, List **hdrs, Octstr **body)
|
|||
List *hh = http_header_duplicate(m->envelope);
|
||||
|
||||
/* Replace in envelope. */
|
||||
http_header_remove_all(hh, "Content-ID");
|
||||
http_header_add(hh, "Content-ID", octstr_get_cstr(cloc));
|
||||
http_header_remove_all(hh, "Content");
|
||||
http_header_add(hh, "Content", octstr_get_cstr(cloc));
|
||||
|
||||
/* Replace content location in msg part. */
|
||||
http_header_remove_all(c->headers, "Content-ID");
|
||||
http_header_add(c->headers, "Content-ID", octstr_get_cstr(cloc) + 4);
|
||||
http_header_add(c->headers, "Content-ID", octstr_get_cstr(cloc_str));
|
||||
|
||||
http_header_add(xml->headers, "Content-Type", "text/xml; charset=\"utf-8\"");
|
||||
http_header_add(xml->headers, "Content-Type", "text/xml");
|
||||
http_header_add(xml->headers, "Content-ID", octstr_get_cstr(envloc));
|
||||
xml->body = headers_to_soapxml(hh);
|
||||
|
||||
|
@ -513,23 +588,395 @@ int mm7_soapmsg_to_httpmsg(MSoapMsg_t *m, List **hdrs, Octstr **body)
|
|||
|
||||
http_destroy_headers(hh);
|
||||
|
||||
ctype = octstr_format("multipart/related; start=\"%S\"; type=text/xml",
|
||||
ctype = octstr_format("multipart/related"
|
||||
|
||||
"; start=\"%S\""
|
||||
#if 0
|
||||
"; type=text/xml"
|
||||
#endif
|
||||
,
|
||||
envloc);
|
||||
|
||||
octstr_destroy(envloc);
|
||||
octstr_destroy(cloc);
|
||||
octstr_destroy(cloc_str);
|
||||
} else {
|
||||
ctype = octstr_imm("text/xml; charset=\"utf-8\"");
|
||||
ctype = octstr_imm("text/xml");
|
||||
mime->body = headers_to_soapxml(m->envelope);
|
||||
}
|
||||
|
||||
http_header_add(mime->headers, "Content-Type", octstr_get_cstr(ctype));
|
||||
http_header_add(mime->headers, "SOAPAction", "\"\"");
|
||||
|
||||
*hdrs = mime_entity_headers(mime);
|
||||
*body = mime_entity_body(mime);
|
||||
mime_entity_body_and_headers(mime, body, hdrs);
|
||||
|
||||
mime_entity_destroy(mime);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mm7_msgtype(MSoapMsg_t *m)
|
||||
{
|
||||
Octstr *typ = http_header_value(m->envelope, octstr_imm("MessageType"));
|
||||
int ret;
|
||||
|
||||
if (!typ)
|
||||
return -1;
|
||||
|
||||
ret = mms_string_to_mm7tag(typ);
|
||||
octstr_destroy(typ);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int get_rcptvalues(List *to, List *headers, char *hname)
|
||||
{
|
||||
List *l;
|
||||
int i, n;
|
||||
|
||||
l = http_header_find_all(headers, hname);
|
||||
|
||||
for (i = 0, n = (l) ? list_len(l) : 0; i < n; i++) {
|
||||
Octstr *h, *v;
|
||||
int ch;
|
||||
http_header_get(l, i, &h, &v);
|
||||
|
||||
ch = octstr_get_char(v, 0);
|
||||
if (ch == '+')
|
||||
list_append(to, octstr_copy(v, 2, octstr_len(v)));
|
||||
octstr_destroy(h);
|
||||
octstr_destroy(v);
|
||||
}
|
||||
http_destroy_headers(l);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mm7_get_envelope(MSoapMsg_t *m,
|
||||
Octstr **sender,
|
||||
List **to, Octstr **subject,
|
||||
Octstr **vasid,
|
||||
time_t *expiry_t,
|
||||
time_t *delivery_t)
|
||||
{
|
||||
Octstr *s;
|
||||
|
||||
if (*to == NULL)
|
||||
*to = list_create();
|
||||
|
||||
get_rcptvalues(*to, m->envelope, "To");
|
||||
get_rcptvalues(*to, m->envelope, "Cc");
|
||||
get_rcptvalues(*to, m->envelope, "Bcc");
|
||||
|
||||
|
||||
*subject = http_header_value(m->envelope, octstr_imm("Subject"));
|
||||
*vasid = http_header_value(m->envelope, octstr_imm("VASID"));
|
||||
|
||||
s = http_header_value(m->envelope, octstr_imm("SenderAddress"));
|
||||
if (s && octstr_get_char(s, 0) == '+')
|
||||
octstr_delete(s, 0, 2);
|
||||
else if (s) {
|
||||
octstr_destroy(s);
|
||||
s = NULL;
|
||||
}
|
||||
*sender = s;
|
||||
|
||||
if (expiry_t) {
|
||||
Octstr *s = http_header_value(m->envelope, octstr_imm("ExpiryDate"));
|
||||
|
||||
*expiry_t = -1;
|
||||
if (s) {
|
||||
*expiry_t = date_parse_http(s);
|
||||
octstr_destroy(s);
|
||||
}
|
||||
}
|
||||
|
||||
if (delivery_t) {
|
||||
Octstr *s = http_header_value(m->envelope, octstr_imm("EarliestDeliveryTime"));
|
||||
*delivery_t = -1;
|
||||
if (s) {
|
||||
*delivery_t = date_parse_http(s);
|
||||
octstr_destroy(s);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
MmsMsg *mm7_soap_to_mmsmsg(MSoapMsg_t *m, Octstr *from)
|
||||
{
|
||||
|
||||
int msgtype = mm7_msgtype(m);
|
||||
MmsMsg *msg = NULL;
|
||||
Octstr *s, *f, *p, *q, *r;
|
||||
List *l;
|
||||
time_t t;
|
||||
|
||||
switch(msgtype) {
|
||||
case MM7_TAG_DeliverReq:
|
||||
case MM7_TAG_SubmitReq:
|
||||
case MM7_TAG_ReplaceReq:
|
||||
msg = mms_frommime(m->msg);
|
||||
|
||||
if (!msg)
|
||||
break;
|
||||
|
||||
/* Put in some headers... */
|
||||
if (from)
|
||||
mms_replace_header_value(msg, "From", octstr_get_cstr(from));
|
||||
|
||||
if ((s = http_header_value(m->envelope, octstr_imm("MessageClass"))) != NULL) {
|
||||
if (mms_string_to_message_class(s) >= 0)
|
||||
mms_replace_header_value(msg, "X-Mms-Message-Class", octstr_get_cstr(s));
|
||||
octstr_destroy(s);
|
||||
}
|
||||
|
||||
if ((s = http_header_value(m->envelope, octstr_imm("Priority"))) != NULL) {
|
||||
if (mms_string_to_priority(s) >= 0)
|
||||
mms_replace_header_value(msg, "X-Mms-Priority", octstr_get_cstr(s));
|
||||
octstr_destroy(s);
|
||||
}
|
||||
|
||||
if ((s = http_header_value(m->envelope, octstr_imm("DeliveryReport"))) != NULL) {
|
||||
if (mms_string_to_reports(s) >= 0)
|
||||
mms_replace_header_value(msg, "X-Mms-Delivery-Report", octstr_get_cstr(s));
|
||||
octstr_destroy(s);
|
||||
}
|
||||
|
||||
if ((s = http_header_value(m->envelope, octstr_imm("ReadReply"))) != NULL) {
|
||||
if (mms_string_to_reports(s) >= 0)
|
||||
mms_replace_header_value(msg, "X-Mms-Read-Report", octstr_get_cstr(s));
|
||||
octstr_destroy(s);
|
||||
}
|
||||
|
||||
if ((s = http_header_value(m->envelope, octstr_imm("TimeStamp"))) != NULL) {
|
||||
mms_replace_header_value(msg, "Date", octstr_get_cstr(s));
|
||||
octstr_destroy(s);
|
||||
}
|
||||
|
||||
if ((s = http_header_value(m->envelope, octstr_imm("ExpiryDate"))) != NULL) {
|
||||
mms_replace_header_value(msg, "X-Mms-Expiry", octstr_get_cstr(s));
|
||||
octstr_destroy(s);
|
||||
}
|
||||
|
||||
if ((s = http_header_value(m->envelope, octstr_imm("Subject"))) != NULL) {
|
||||
mms_replace_header_value(msg, "Subject", octstr_get_cstr(s));
|
||||
octstr_destroy(s);
|
||||
}
|
||||
|
||||
/* Put in recipient list. XXX - really?? */
|
||||
l = list_create();
|
||||
get_rcptvalues(l, m->envelope, "To");
|
||||
mms_replace_header_values(msg, "To", l);
|
||||
list_destroy(l, (list_item_destructor_t *)octstr_destroy);
|
||||
|
||||
l = list_create();
|
||||
get_rcptvalues(l, m->envelope, "Cc");
|
||||
mms_replace_header_values(msg, "Cc", l);
|
||||
list_destroy(l, (list_item_destructor_t *)octstr_destroy);
|
||||
|
||||
/* XXX - we ignore reply charging, etc. */
|
||||
break;
|
||||
|
||||
case MM7_TAG_DeliveryReportReq: /* should we bother?? Can these ever be handled here?? */
|
||||
case MM7_TAG_ReadReplyReq:
|
||||
s = http_header_value(m->envelope, octstr_imm("MessageID"));
|
||||
if ((p = http_header_value(m->envelope, octstr_imm("To"))) != NULL &&
|
||||
octstr_get_char(p, 0) == '+')
|
||||
octstr_delete(p, 0, 2);
|
||||
else if (p) {
|
||||
octstr_destroy(p);
|
||||
p = NULL;
|
||||
}
|
||||
|
||||
if ((f = http_header_value(m->envelope, octstr_imm("From"))) != NULL &&
|
||||
octstr_get_char(f, 0) == '+')
|
||||
octstr_delete(f, 0, 2);
|
||||
else if (f) {
|
||||
octstr_destroy(f);
|
||||
f = NULL;
|
||||
}
|
||||
|
||||
if ((q = http_header_value(m->envelope, octstr_imm("Date"))) != NULL)
|
||||
t = date_parse_http(q);
|
||||
else
|
||||
t = time(NULL);
|
||||
r = http_header_value(m->envelope, octstr_imm("MMStatus"));
|
||||
|
||||
if (msgtype == MM7_TAG_DeliveryReportReq &&
|
||||
p && r && mms_string_to_status(r) >= 0)
|
||||
msg = mms_deliveryreport(s ? s : octstr_imm("0000"), p, t, r);
|
||||
else if (msgtype == MM7_TAG_ReadReplyReq &&
|
||||
f && p && r && mms_string_to_read_status(r) >= 0)
|
||||
msg = mms_readreport(s ? s : octstr_imm("0000"),
|
||||
f, p, t, r);
|
||||
if (s)
|
||||
octstr_destroy(s);
|
||||
if (p)
|
||||
octstr_destroy(p);
|
||||
if (r)
|
||||
octstr_destroy(r);
|
||||
if (f)
|
||||
octstr_destroy(f);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return msg;
|
||||
}
|
||||
|
||||
void mm7_soap_destroy(MSoapMsg_t *m)
|
||||
{
|
||||
http_destroy_headers(m->envelope);
|
||||
if (m->msg)
|
||||
mime_entity_destroy(m->msg);
|
||||
gw_free(m);
|
||||
}
|
||||
|
||||
static MSoapMsg_t *mm7_soap_create(int msgtype, Octstr *otransid)
|
||||
{
|
||||
MSoapMsg_t *m = gw_malloc(sizeof *m);
|
||||
|
||||
m->envelope = http_create_empty_headers();
|
||||
m->msg = NULL;
|
||||
|
||||
http_header_add(m->envelope, "MessageType", mms_mm7tag_to_cstr(msgtype));
|
||||
http_header_add(m->envelope, "MM7Version", MM7_DEFAULT_VERSION);
|
||||
http_header_add(m->envelope, "TransactionID",
|
||||
otransid ? octstr_get_cstr(otransid) : "0000");
|
||||
return m;
|
||||
}
|
||||
|
||||
MSoapMsg_t *mm7_mmsmsg_to_soap(MmsMsg *msg, Octstr *from, List *xto,
|
||||
Octstr *transid, Octstr *serverID)
|
||||
{
|
||||
int mtype = mms_messagetype(msg);
|
||||
MSoapMsg_t *m = NULL;
|
||||
Octstr *s;
|
||||
int i, n;
|
||||
Octstr *xfrom;
|
||||
|
||||
xfrom = octstr_format("+ %S", from ? from : octstr_imm("anon@anon"));
|
||||
switch(mtype) {
|
||||
case MMS_MSGTYPE_SEND_REQ:
|
||||
case MMS_MSGTYPE_RETRIEVE_CONF:
|
||||
m = mm7_soap_create(MM7_TAG_DeliverReq, transid);
|
||||
m->msg = mms_tomime(msg);
|
||||
|
||||
for (i = 0, n = xto ? list_len(xto) : 0; i < n; i++) { /* Add recipients. */
|
||||
Octstr *xx = octstr_format("+ %S", list_get(xto, i));
|
||||
http_header_add(m->envelope, "To",
|
||||
octstr_get_cstr(xx));
|
||||
octstr_destroy(xx);
|
||||
}
|
||||
|
||||
if (serverID)
|
||||
http_header_add(m->envelope, "MMSRelayServerID", octstr_get_cstr(serverID));
|
||||
http_header_add(m->envelope, "LinkedID", octstr_get_cstr(transid));
|
||||
http_header_add(m->envelope, "Sender", octstr_get_cstr(xfrom));
|
||||
|
||||
if ((s = mms_get_header_value(msg, octstr_imm("X-Mms-Priority"))) != NULL) {
|
||||
http_header_add(m->envelope, "Priority", octstr_get_cstr(s));
|
||||
octstr_destroy(s);
|
||||
}
|
||||
|
||||
if ((s = mms_get_header_value(msg, octstr_imm("Subject"))) != NULL) {
|
||||
http_header_add(m->envelope, "Subject", octstr_get_cstr(s));
|
||||
octstr_destroy(s);
|
||||
}
|
||||
|
||||
if ((s = mms_get_header_value(msg, octstr_imm("Date"))) != NULL) {
|
||||
http_header_add(m->envelope, "TimeStamp", octstr_get_cstr(s));
|
||||
octstr_destroy(s);
|
||||
}
|
||||
|
||||
/* Should we bother to strip message part of headers??? */
|
||||
http_header_remove_all(m->msg->headers, "Subject");
|
||||
http_header_remove_all(m->msg->headers, "X-Mms-Message-Type");
|
||||
http_header_remove_all(m->msg->headers, "X-Mms-Message-Version");
|
||||
http_header_remove_all(m->msg->headers, "From");
|
||||
http_header_remove_all(m->msg->headers, "To");
|
||||
http_header_remove_all(m->msg->headers, "Cc");
|
||||
http_header_remove_all(m->msg->headers, "Bcc");
|
||||
break;
|
||||
case MMS_MSGTYPE_READ_ORIG_IND:
|
||||
case MMS_MSGTYPE_DELIVERY_IND:
|
||||
m = mm7_soap_create((mtype == MMS_MSGTYPE_READ_ORIG_IND) ?
|
||||
MM7_TAG_ReadReplyReq : MM7_TAG_DeliveryReportReq,
|
||||
transid);
|
||||
|
||||
http_header_add(m->envelope, "Sender", octstr_get_cstr(xfrom));
|
||||
|
||||
if (xto && list_len(xto) > 0) {
|
||||
Octstr *xx = octstr_format("+ %S", list_get(xto, 0));
|
||||
http_header_add(m->envelope, "To",
|
||||
octstr_get_cstr(xx));
|
||||
octstr_destroy(xx);
|
||||
}
|
||||
|
||||
s = mms_get_header_value(msg, octstr_imm("Message-ID"));
|
||||
if (!s)
|
||||
s = octstr_duplicate(transid);
|
||||
http_header_add(m->envelope, "MessageID", octstr_get_cstr(s));
|
||||
octstr_destroy(s);
|
||||
|
||||
if ((s = mms_get_header_value(msg, octstr_imm("Date"))) != NULL) {
|
||||
http_header_add(m->envelope,
|
||||
(mtype == MMS_MSGTYPE_READ_ORIG_IND) ? "TimeStamp" : "Date",
|
||||
octstr_get_cstr(s));
|
||||
octstr_destroy(s);
|
||||
}
|
||||
|
||||
if ((s = mms_get_header_value(msg,
|
||||
(mtype == MMS_MSGTYPE_READ_ORIG_IND) ?
|
||||
octstr_imm("X-Mms-Read-Status") :
|
||||
octstr_imm("X-Mms-Status") )) != NULL) {
|
||||
http_header_add(m->envelope, "MMStatus", octstr_get_cstr(s));
|
||||
octstr_destroy(s);
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
octstr_destroy(xfrom);
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
MSoapMsg_t *mm7_make_resp(MSoapMsg_t *mreq, int status, Octstr *msgid)
|
||||
{
|
||||
int mtype = mreq ? mm7_msgtype(mreq) : -1;
|
||||
Octstr *transid;
|
||||
MSoapMsg_t *mresp;
|
||||
char scode[64];
|
||||
char *statustxt = mms_soap_status_to_cstr(status);
|
||||
|
||||
transid = mreq ? http_header_value(mreq->envelope, octstr_imm("TransactionID")) : NULL;
|
||||
|
||||
if (!MM7_SOAP_STATUS_OK(status) || mtype < 0)
|
||||
mresp = mm7_soap_create(MM7_TAG_RSErrorRsp, transid);
|
||||
else
|
||||
mresp = mm7_soap_create(mtype + 1, transid);
|
||||
|
||||
sprintf(scode, "%d", status);
|
||||
http_header_add(mresp->envelope, "Status", ""); /* So that we get output. */
|
||||
http_header_add(mresp->envelope, "StatusCode", scode);
|
||||
http_header_add(mresp->envelope, "StatusText", statustxt ? statustxt : "Error");
|
||||
|
||||
if (msgid)
|
||||
http_header_add(mresp->envelope, "MessageID", octstr_get_cstr(msgid));
|
||||
|
||||
if (!MM7_SOAP_STATUS_OK(status)) {
|
||||
http_header_add(mresp->envelope, "Fault", ""); /* do we really need these? XXX */
|
||||
http_header_add(mresp->envelope, "faultcode", "env:Server");
|
||||
http_header_add(mresp->envelope, "faultstring", "Server error");
|
||||
}
|
||||
|
||||
octstr_destroy(transid);
|
||||
return mresp;
|
||||
}
|
||||
|
||||
Octstr *mm7_soap_header_value(MSoapMsg_t *m, Octstr *header)
|
||||
{
|
||||
return http_header_value(m->envelope, header);
|
||||
}
|
||||
|
|
|
@ -2,14 +2,44 @@
|
|||
#define __MMS_MM7SOAP_INCLUDED__
|
||||
#include "mms_util.h"
|
||||
|
||||
typedef struct MSoapMsg_t {
|
||||
List *envelope; /* of http headers. */
|
||||
MmsMsg *msg;
|
||||
} MSoapMsg_t;
|
||||
#define MM7_SOAP_OK 1000
|
||||
#define MM7_SOAP_FORMAT_CORRUPT 2007
|
||||
#define MM7_SOAP_STATUS_OK(e) ((e) / 1000 == 1)
|
||||
#define MM7_DEFAULT_VERSION "5.3.0"
|
||||
|
||||
typedef struct MSoapMsg_t MSoapMsg_t;
|
||||
|
||||
/* Parse SOAP message given http headers and body. */
|
||||
extern MSoapMsg_t *mm7_parse_soap(List *headers, Octstr *body);
|
||||
|
||||
/* Convert SOAP message to http headers and body. */
|
||||
extern int mm7_soapmsg_to_httpmsg(MSoapMsg_t *m, List **hdrs, Octstr **body);
|
||||
|
||||
extern MmsMsg *mm7_soapmsg_to_mmsmsg(MSoapMsg_t *m);
|
||||
/* Convert SOAP message to an MMS message. */
|
||||
extern MmsMsg *mm7_soap_to_mmsmsg(MSoapMsg_t *m, Octstr *from);
|
||||
|
||||
/* Return the message type. */
|
||||
extern int mm7_msgtype(MSoapMsg_t *m);
|
||||
|
||||
/* Collect and return envelope data:
|
||||
* - to -- list of recipients to send to
|
||||
* - subject -- subject
|
||||
* - msgid -- message id
|
||||
* - vasid/vaspid -- vasid and vaspid
|
||||
*/
|
||||
extern int mm7_get_envelope(MSoapMsg_t *m, Octstr **sender,
|
||||
List **to, Octstr **subject,
|
||||
Octstr **vasid,
|
||||
time_t *expiry_t,
|
||||
time_t *delivery_t);
|
||||
|
||||
/* Delete the thingie... */
|
||||
extern void mm7_soap_destroy(MSoapMsg_t *m);
|
||||
|
||||
/* Convert a message to a SOAP message. */
|
||||
MSoapMsg_t *mm7_mmsmsg_to_soap(MmsMsg *msg, Octstr *from, List *xto,
|
||||
Octstr *transid, Octstr *serverID);
|
||||
MSoapMsg_t *mm7_make_resp(MSoapMsg_t *mreq, int status, Octstr *msgid);
|
||||
/* Return the header value for some header. */
|
||||
Octstr *mm7_soap_header_value(MSoapMsg_t *m, Octstr *header);
|
||||
#endif
|
||||
|
|
|
@ -911,6 +911,7 @@ static int encode_msgheaders(Octstr *os, List *hdrs)
|
|||
|
||||
version = http_header_value(hdrs,
|
||||
octstr_imm("X-Mms-MMS-Version"));
|
||||
|
||||
transid = http_header_value(hdrs,
|
||||
octstr_imm("X-Mms-Transaction-Id"));
|
||||
msgtype = http_header_value(hdrs,
|
||||
|
@ -980,9 +981,11 @@ static int fixup_msg(MmsMsg *m, Octstr *from)
|
|||
return -1;
|
||||
|
||||
ver = http_header_value(m->headers, octstr_imm("X-Mms-MMS-Version"));
|
||||
if (!ver || octstr_str_compare(ver, "1.1") <= 0)
|
||||
if (!ver || octstr_str_compare(ver, "1.1") <= 0) {
|
||||
m->enc = MS_1_1;
|
||||
else if (octstr_str_compare(ver, "1.2") <= 0)
|
||||
if (!ver)
|
||||
http_header_add(m->headers, "X-Mms-MMS-Version", MMS_DEFAULT_VERSION);
|
||||
} else if (octstr_str_compare(ver, "1.2") <= 0)
|
||||
m->enc = MS_1_2;
|
||||
|
||||
if (m->message_type == MMS_MSGTYPE_SEND_REQ ||
|
||||
|
@ -1226,27 +1229,6 @@ static void unconvert_mime_msg(MIMEEntity *m)
|
|||
|
||||
}
|
||||
|
||||
static MIMEEntity *mime_entity_duplicate(MIMEEntity *m)
|
||||
{
|
||||
MIMEEntity *mx = gw_malloc(sizeof *mx);
|
||||
|
||||
mx->headers = http_header_duplicate(m->headers);
|
||||
if (m->multiparts && list_len(m->multiparts) > 0) {
|
||||
int i, n;
|
||||
mx->multiparts = list_create();
|
||||
for (i = 0, n = list_len(m->multiparts); i < n; i++) {
|
||||
MIMEEntity *x = mime_entity_duplicate(list_get(m->multiparts, i));
|
||||
list_append(mx->multiparts, x);
|
||||
}
|
||||
mx->body = NULL;
|
||||
} else {
|
||||
mx->body = m->body ? octstr_duplicate(m->body) : NULL;
|
||||
mx->multiparts = NULL;
|
||||
}
|
||||
mx->start = NULL;
|
||||
|
||||
return mx;
|
||||
}
|
||||
|
||||
MIMEEntity *mms_tomime(MmsMsg *msg)
|
||||
{
|
||||
|
@ -1269,7 +1251,7 @@ MIMEEntity *mms_tomime(MmsMsg *msg)
|
|||
}
|
||||
}
|
||||
convert_mime_msg(m);
|
||||
|
||||
base64_mimeparts(m);
|
||||
return m;
|
||||
}
|
||||
|
||||
|
@ -1394,6 +1376,40 @@ List *mms_message_headers(MmsMsg *msg)
|
|||
return http_header_duplicate(msg->headers);
|
||||
}
|
||||
|
||||
MmsMsg *mms_readreport(Octstr *msgid, Octstr *from, Octstr *to, time_t date, Octstr *status)
|
||||
{
|
||||
|
||||
MmsMsg *m = gw_malloc(sizeof *m);
|
||||
Octstr *s;
|
||||
|
||||
|
||||
m->ismultipart = 0;
|
||||
m->headers = http_create_empty_headers();
|
||||
|
||||
m->message_type = MMS_MSGTYPE_READ_ORIG_IND;
|
||||
m->body.s = NULL;
|
||||
m->msgId = octstr_duplicate(msgid ? msgid : octstr_imm("none"));
|
||||
|
||||
/* Now append headers. */
|
||||
|
||||
http_header_add(m->headers, "X-Mms-Message-Type", "m-read-orig-ind");
|
||||
http_header_add(m->headers, "X-Mms-MMS-Version", MMS_DEFAULT_VERSION);
|
||||
|
||||
http_header_add(m->headers, "Message-ID", msgid ? octstr_get_cstr(msgid) : "none");
|
||||
http_header_add(m->headers, "To", octstr_get_cstr(to));
|
||||
|
||||
http_header_add(m->headers, "From", octstr_get_cstr(from));
|
||||
|
||||
s = date_format_http(date);
|
||||
http_header_add(m->headers, "Date", octstr_get_cstr(s));
|
||||
|
||||
http_header_add(m->headers, "X-Mms-Status", octstr_get_cstr(status));
|
||||
|
||||
octstr_destroy(s);
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
MmsMsg *mms_deliveryreport(Octstr *msgid, Octstr *to, time_t date, Octstr *status)
|
||||
{
|
||||
|
||||
|
@ -1406,7 +1422,7 @@ MmsMsg *mms_deliveryreport(Octstr *msgid, Octstr *to, time_t date, Octstr *statu
|
|||
|
||||
m->message_type = MMS_MSGTYPE_DELIVERY_IND;
|
||||
m->body.s = NULL;
|
||||
m->msgId = octstr_duplicate(msgid);
|
||||
m->msgId = octstr_duplicate(msgid ? msgid : octstr_imm("none"));
|
||||
|
||||
/* Now append headers. */
|
||||
|
||||
|
@ -1607,6 +1623,16 @@ int mms_replace_header_value(MmsMsg *msg, char *hname, char *value)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int mms_add_missing_headers(MmsMsg *msg, List *headers)
|
||||
{
|
||||
List *h = http_header_duplicate(headers);
|
||||
http_header_combine(h, msg->headers);
|
||||
|
||||
http_destroy_headers(msg->headers);
|
||||
msg->headers = h;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mms_replace_header_values(MmsMsg *msg, char *hname, List *value)
|
||||
{
|
||||
int i;
|
||||
|
@ -1648,11 +1674,24 @@ List *mms_get_header_values(MmsMsg *msg, Octstr *header)
|
|||
|
||||
int mms_convert_readrec2readorig(MmsMsg *msg)
|
||||
{
|
||||
|
||||
Octstr *s;
|
||||
|
||||
if (msg->message_type != MMS_MSGTYPE_READ_REC_IND)
|
||||
return -1;
|
||||
|
||||
mms_replace_header_value(msg, "X-Mms-Message-Type", "m-read-orig-ind");
|
||||
msg->message_type = MMS_MSGTYPE_READ_ORIG_IND;
|
||||
|
||||
if ((s = mms_get_header_value(msg, octstr_imm("Date"))) == NULL) {
|
||||
time_t t = time(NULL);
|
||||
s = date_format_http(t);
|
||||
mms_replace_header_value(msg, "Date", octstr_get_cstr(s));
|
||||
}
|
||||
|
||||
if (s)
|
||||
octstr_destroy(s);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -55,6 +55,8 @@ extern void mms_destroy(MmsMsg *msg);
|
|||
/* Make a delivery report message. */
|
||||
extern MmsMsg *mms_deliveryreport(Octstr *msgid, Octstr *to, time_t date, Octstr *status);
|
||||
|
||||
MmsMsg *mms_readreport(Octstr *msgid, Octstr *from, Octstr *to, time_t date, Octstr *status);
|
||||
|
||||
/* Return message headers. */
|
||||
extern List *mms_message_headers(MmsMsg *msg);
|
||||
|
||||
|
@ -75,6 +77,9 @@ List *mms_get_header_values(MmsMsg *msg, Octstr *header);
|
|||
int mms_replace_header_value(MmsMsg *msg, char *hname, char *value);
|
||||
int mms_replace_header_values(MmsMsg *msg, char *hname, List *values);
|
||||
|
||||
/* Get headers from 'headers' that are not already in message headers and add them. */
|
||||
int mms_add_missing_headers(MmsMsg *msg, List *headers);
|
||||
|
||||
int mms_convert_readrec2readorig(MmsMsg *msg);
|
||||
|
||||
|
||||
|
|
|
@ -44,7 +44,7 @@ static int free_envelope(MmsEnvelope *e, int removefromqueue);
|
|||
* X - Time of expiry of message
|
||||
* N - Number of delivery attempts so far
|
||||
* P - Proxy who sent it to us
|
||||
* V - Proxy through which this message shd be delivered (e.g. delivery report)
|
||||
* p - Proxy through which this message shd be delivered (e.g. delivery report)
|
||||
* S - Message size
|
||||
* s - Message subject.
|
||||
* f - time of last content fetch
|
||||
|
@ -52,6 +52,8 @@ static int free_envelope(MmsEnvelope *e, int removefromqueue);
|
|||
* b - billed amount.
|
||||
* r - whether delivery receipts are required or not.
|
||||
* M - Application specific data (string)
|
||||
* V - VASID -- from VASP
|
||||
* v - vasid -- from VASP
|
||||
*/
|
||||
|
||||
|
||||
|
@ -165,7 +167,7 @@ MmsEnvelope *mms_queue_readenvelope(char *qf, char *mms_queuedir, int shouldbloc
|
|||
case 'M':
|
||||
e->mdata = octstr_create(res);
|
||||
break;
|
||||
case 'V':
|
||||
case 'p':
|
||||
e->viaproxy = octstr_create(res);
|
||||
break;
|
||||
case 'S':
|
||||
|
@ -187,6 +189,12 @@ MmsEnvelope *mms_queue_readenvelope(char *qf, char *mms_queuedir, int shouldbloc
|
|||
case 'r':
|
||||
e->dlr = 1;
|
||||
break;
|
||||
case 'V':
|
||||
e->vaspid = octstr_create(res);
|
||||
break;
|
||||
case 'v':
|
||||
e->vasid = octstr_create(res);
|
||||
break;
|
||||
case '.':
|
||||
okfile = 1;
|
||||
break;
|
||||
|
@ -320,12 +328,19 @@ static int writeenvelope(MmsEnvelope *e, int newenv)
|
|||
|
||||
|
||||
if (e->viaproxy)
|
||||
_putline(fd, "V", octstr_get_cstr(e->viaproxy));
|
||||
_putline(fd, "p", octstr_get_cstr(e->viaproxy));
|
||||
|
||||
if (e->token)
|
||||
_putline(fd, "t", octstr_get_cstr(e->token));
|
||||
|
||||
|
||||
if (e->vaspid)
|
||||
_putline(fd, "V", octstr_get_cstr(e->vaspid));
|
||||
|
||||
if (e->vasid)
|
||||
_putline(fd, "v", octstr_get_cstr(e->vasid));
|
||||
|
||||
|
||||
if (e->dlr)
|
||||
_putline(fd, "r", "Yes");
|
||||
|
||||
|
@ -443,17 +458,18 @@ static int writemmsdata(Octstr *ms, char *df, char *mms_queuedir)
|
|||
}
|
||||
|
||||
|
||||
Octstr *mms_queue_add(Octstr *from, List *to, Octstr *msgid,
|
||||
Octstr *mms_queue_add(Octstr *from, List *to,
|
||||
Octstr *subject,
|
||||
Octstr *fromproxy, Octstr *viaproxy,
|
||||
time_t senddate, time_t expirydate, MmsMsg *m, Octstr *token,
|
||||
Octstr *vaspid, Octstr *vasid,
|
||||
int dlr,
|
||||
char *directory)
|
||||
char *directory, Octstr *mmscname)
|
||||
{
|
||||
char qf[32];
|
||||
int fd, i, n;
|
||||
MmsEnvelope *e;
|
||||
|
||||
Octstr *msgid;
|
||||
Octstr *ms, *res = NULL;
|
||||
|
||||
fd = mkqf(qf, directory);
|
||||
|
@ -466,6 +482,7 @@ Octstr *mms_queue_add(Octstr *from, List *to, Octstr *msgid,
|
|||
res = octstr_create(qf);
|
||||
ms = mms_tobinary(m); /* Convert message to string. */
|
||||
|
||||
msgid = mms_maketransid(octstr_get_cstr(res), mmscname);
|
||||
|
||||
e = gw_malloc(sizeof *e); /* Make envelope, clear it. */
|
||||
memset(e, 0, sizeof *e);
|
||||
|
@ -488,14 +505,17 @@ Octstr *mms_queue_add(Octstr *from, List *to, Octstr *msgid,
|
|||
e->subject = subject;
|
||||
e->to = list_create();
|
||||
e->msize = octstr_len(ms);
|
||||
e->msgId = msgid ? msgid : res;
|
||||
e->msgId = msgid;
|
||||
e->token = token;
|
||||
e->vaspid = vaspid;
|
||||
e->vasid = vasid;
|
||||
|
||||
e->dlr = dlr;
|
||||
e->bill.billed = 0;
|
||||
|
||||
/* Insert message ID into message if it is missing. */
|
||||
if (!msgid && mms_messagetype(m) == MMS_MSGTYPE_SEND_REQ)
|
||||
mms_replace_header_value(m, "Message-ID", octstr_get_cstr(res));
|
||||
mms_replace_header_value(m, "Message-ID", octstr_get_cstr(msgid));
|
||||
|
||||
n = to ? list_len(to) : 0;
|
||||
|
||||
|
@ -540,6 +560,7 @@ Octstr *mms_queue_add(Octstr *from, List *to, Octstr *msgid,
|
|||
list_destroy(e->to, NULL);
|
||||
gw_free(e);
|
||||
octstr_destroy(ms);
|
||||
octstr_destroy(msgid);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
@ -617,6 +638,39 @@ int mms_queue_update(MmsEnvelope *e)
|
|||
return writeenvelope(e, 0);
|
||||
}
|
||||
|
||||
int mms_queue_replacedata(MmsEnvelope *e, MmsMsg *m)
|
||||
{
|
||||
Octstr *tfname;
|
||||
Octstr *ms;
|
||||
int ret = 0;
|
||||
|
||||
if (!e) return -1;
|
||||
|
||||
tfname = octstr_format(".%c%s.%ld.%d", MDF, e->qf.name + 1, time(NULL), random());
|
||||
|
||||
ms = mms_tobinary(m);
|
||||
|
||||
if (writemmsdata(ms, octstr_get_cstr(tfname), e->qf.dir) < 0)
|
||||
ret = -1;
|
||||
else {
|
||||
Octstr *fname = octstr_format("%s/%c%s", e->qf.dir, MDF, e->qf.name + 1);
|
||||
Octstr *tmpf = octstr_format("%s/%S", e->qf.dir, tfname);
|
||||
if (rename(octstr_get_cstr(tmpf), octstr_get_cstr(fname)) < 0) {
|
||||
error(0, "mms_replacedata: Failed to write data file %s: error = %s\n",
|
||||
octstr_get_cstr(tmpf), strerror(errno));
|
||||
ret = -1;
|
||||
unlink(octstr_get_cstr(tmpf)); /* remove it. */
|
||||
}
|
||||
|
||||
octstr_destroy(fname);
|
||||
octstr_destroy(tmpf);
|
||||
}
|
||||
octstr_destroy(ms);
|
||||
|
||||
octstr_destroy(tfname);
|
||||
return ret;
|
||||
}
|
||||
|
||||
MmsMsg *mms_queue_getdata(MmsEnvelope *e)
|
||||
{
|
||||
Octstr *fname;
|
||||
|
|
|
@ -33,6 +33,9 @@ typedef struct MmsEnvelope {
|
|||
Octstr *token; /* User level token, may be null. */
|
||||
Octstr *from; /* from address. */
|
||||
|
||||
Octstr *vaspid; /* VASPID (if any) */
|
||||
Octstr *vasid; /* VASID (if any) */
|
||||
|
||||
List *to; /* List of recipients: MmsEnvelopeTo */
|
||||
|
||||
Octstr *subject; /* Message subject (if any). */
|
||||
|
@ -71,12 +74,13 @@ typedef struct MmsEnvelope {
|
|||
* 'to' is a list of Octstr * *.
|
||||
* Returns a queue file name.
|
||||
*/
|
||||
extern Octstr *mms_queue_add(Octstr *from, List *to, Octstr *msgid,
|
||||
extern Octstr *mms_queue_add(Octstr *from, List *to,
|
||||
Octstr *subject,
|
||||
Octstr *fromproxy, Octstr *viaproxy,
|
||||
time_t senddate, time_t expirydate, MmsMsg *m, Octstr *token,
|
||||
Octstr *vaspid, Octstr *vasid,
|
||||
int dlr,
|
||||
char *directory);
|
||||
char *directory, Octstr *mmscname);
|
||||
|
||||
/*
|
||||
* Update queue status. Returns -1 on error, 0 if queue is updated fine and
|
||||
|
@ -89,6 +93,9 @@ extern int mms_queue_update(MmsEnvelope *e);
|
|||
*/
|
||||
extern MmsMsg *mms_queue_getdata(MmsEnvelope *e);
|
||||
|
||||
/* Replace data for this queue item -- used by mm7 interface. */
|
||||
int mms_queue_replacedata(MmsEnvelope *e, MmsMsg *m);
|
||||
|
||||
/*
|
||||
* Reads queue, returns up to lim queue entries that are ready for processing. send 0 for no limit.
|
||||
*/
|
||||
|
|
|
@ -242,7 +242,7 @@ ASSIGN("Error-permanent-mmbox-full",228)
|
|||
NUMBERED(descriptor_params,
|
||||
ASSIGN("type", 130)
|
||||
)
|
||||
|
||||
/* MM7/SOAP stuff -- *** order of these matters wrt Req/Rsp *** */
|
||||
NAMED(mm7tag,
|
||||
VNSTRING(MM7_5, "Bcc",MM7_TAG_Bcc)
|
||||
VNSTRING(MM7_5, "CancelReq",MM7_TAG_CancelReq)
|
||||
|
@ -296,6 +296,7 @@ VNSTRING(MM7_5, "VASID",MM7_TAG_VASID)
|
|||
VNSTRING(MM7_5, "VASPErrorRsp",MM7_TAG_VASPErrorRsp)
|
||||
VNSTRING(MM7_5, "VASPID",MM7_TAG_VASPID)
|
||||
VNSTRING(MM7_5, "Fault",MM7_TAG_Fault)
|
||||
VNSTRING(MM7_5, "Details",MM7_TAG_Details)
|
||||
VNSTRING(MM7_5, "faultcode",MM7_TAG_faultcode)
|
||||
VNSTRING(MM7_5, "faultstring",MM7_TAG_faultstring)
|
||||
VNSTRING(MM7_5, "MessageType",MM7_TAG_MessageType)
|
||||
|
@ -303,6 +304,30 @@ VNSTRING(MM7_5, "replyChargingSize", MM7_TAG_replyChargingSize)
|
|||
VNSTRING(MM7_5, "replyDeadline", MM7_TAG_replyDeadline)
|
||||
)
|
||||
|
||||
NUMBERED(soap_status,
|
||||
ASSIGN("Success", 1000)
|
||||
ASSIGN("Partial success", 1100)
|
||||
ASSIGN("Client error", 2000)
|
||||
ASSIGN("Operation restricted", 2001)
|
||||
ASSIGN("Address Error", 2002)
|
||||
ASSIGN("Address Not Found", 2003)
|
||||
ASSIGN("Multimedia content refused", 2004)
|
||||
ASSIGN("Message ID Not found", 2005)
|
||||
ASSIGN("LinkedID not found", 2006)
|
||||
ASSIGN("Message format corrupt", 2007)
|
||||
ASSIGN("Server Error", 3000)
|
||||
ASSIGN("Not Possible", 3001)
|
||||
ASSIGN("Message rejected", 3002)
|
||||
ASSIGN("Multiple addresses not supported", 3003)
|
||||
ASSIGN("General service error", 4000)
|
||||
ASSIGN("Improper identification", 4001)
|
||||
ASSIGN("Unsupported version", 4002)
|
||||
ASSIGN("Unsupported operation", 4003)
|
||||
ASSIGN("Validation error", 4004)
|
||||
ASSIGN("Service error", 4005)
|
||||
ASSIGN("Service unavailable", 4006)
|
||||
ASSIGN("Service denied", 4007)
|
||||
)
|
||||
#undef LINEAR
|
||||
#undef STRING
|
||||
#undef VSTRING
|
||||
|
|
|
@ -80,6 +80,7 @@ MmsBoxSettings *mms_load_mmsbox_settings(Cfg *cfg)
|
|||
MmsBoxSettings *m = gw_malloc(sizeof *m);
|
||||
long port = -1;
|
||||
Octstr *user, *pass, *from;
|
||||
int i, n;
|
||||
|
||||
memset(m, 0, sizeof *m);
|
||||
|
||||
|
@ -100,7 +101,7 @@ MmsBoxSettings *mms_load_mmsbox_settings(Cfg *cfg)
|
|||
m->hostname = cfg_getx(grp, octstr_imm("hostname"));
|
||||
|
||||
if (m->hostname == NULL || octstr_len(m->hostname) == 0)
|
||||
m->hostname = octstr_create("localhost");
|
||||
m->hostname = octstr_create("localhost");
|
||||
|
||||
m->name = cfg_getx(grp, octstr_imm("name"));
|
||||
m->host_alias = cfg_getx(grp, octstr_imm("host-alias"));
|
||||
|
@ -157,6 +158,9 @@ MmsBoxSettings *mms_load_mmsbox_settings(Cfg *cfg)
|
|||
|
||||
m->port = (port > 0) ? port : MMS_PORT;
|
||||
|
||||
m->mm7port = -1;
|
||||
cfg_get_integer(&m->mm7port, grp, octstr_imm("mm7-port"));
|
||||
|
||||
m->allow_ip = cfg_getx(grp, octstr_imm("allow-ip"));
|
||||
m->deny_ip = cfg_getx(grp, octstr_imm("deny-ip"));
|
||||
|
||||
|
@ -236,6 +240,40 @@ MmsBoxSettings *mms_load_mmsbox_settings(Cfg *cfg)
|
|||
if (mmbox_root_init(octstr_get_cstr(m->mmbox_rootdir)) != 0)
|
||||
warning(0, "Failed to initialise mmbox root directory, error: %s!",
|
||||
strerror(errno));
|
||||
|
||||
|
||||
/* Now load the VASP list. */
|
||||
l = cfg_get_multi_group(cfg, octstr_imm("mms-vasp"));
|
||||
m->vasp_list = list_create();
|
||||
for (i=0, n=list_len(l); i<n; i++) {
|
||||
CfgGroup *grp = list_get(l, i);
|
||||
MmsVasp *mv = gw_malloc(sizeof *mv);
|
||||
Octstr *s;
|
||||
mv->id = cfg_getx(grp, octstr_imm("vasp-id"));
|
||||
mv->short_code = -1;
|
||||
cfg_get_integer(&mv->short_code, grp, octstr_imm("short-code"));
|
||||
|
||||
mv->vasp_username = cfg_getx(grp, octstr_imm("vasp-username"));
|
||||
mv->vasp_password = cfg_getx(grp, octstr_imm("vasp-password"));
|
||||
|
||||
mv->vasp_url = cfg_getx(grp, octstr_imm("vasp-url"));
|
||||
|
||||
mv->mmsc_username = cfg_getx(grp, octstr_imm("mmsc-username"));
|
||||
mv->mmsc_password = cfg_getx(grp, octstr_imm("mmsc-password"));
|
||||
|
||||
s = cfg_getx(grp, octstr_imm("type"));
|
||||
|
||||
if (octstr_case_compare(s, octstr_imm("soap")) == 0)
|
||||
mv->type = SOAP_VASP;
|
||||
else if (octstr_case_compare(s, octstr_imm("eaif")) == 0)
|
||||
mv->type = EAIF_VASP;
|
||||
else
|
||||
mv->type = NONE_VASP;
|
||||
octstr_destroy(s);
|
||||
|
||||
list_append(m->vasp_list, mv);
|
||||
}
|
||||
list_destroy(l, NULL);
|
||||
return m;
|
||||
}
|
||||
|
||||
|
@ -428,7 +466,8 @@ Octstr *mms_maketransid(char *qf, Octstr *mmscname)
|
|||
extern Octstr *mms_getqf_fromtransid(Octstr *transid)
|
||||
{
|
||||
int i = octstr_search_char(transid, '@', 0);
|
||||
return octstr_copy(transid, 0, i);
|
||||
|
||||
return (i >= 0) ? octstr_copy(transid, 0, i) : octstr_duplicate(transid);
|
||||
}
|
||||
|
||||
Octstr *mms_isodate(time_t t)
|
||||
|
@ -1051,3 +1090,25 @@ int mm_lockfile(int fd, char *fname, int shouldblock)
|
|||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
MIMEEntity *mime_entity_duplicate(MIMEEntity *m)
|
||||
{
|
||||
MIMEEntity *mx = gw_malloc(sizeof *mx);
|
||||
|
||||
mx->headers = http_header_duplicate(m->headers);
|
||||
if (m->multiparts && list_len(m->multiparts) > 0) {
|
||||
int i, n;
|
||||
mx->multiparts = list_create();
|
||||
for (i = 0, n = list_len(m->multiparts); i < n; i++) {
|
||||
MIMEEntity *x = mime_entity_duplicate(list_get(m->multiparts, i));
|
||||
list_append(mx->multiparts, x);
|
||||
}
|
||||
mx->body = NULL;
|
||||
} else {
|
||||
mx->body = m->body ? octstr_duplicate(m->body) : NULL;
|
||||
mx->multiparts = NULL;
|
||||
}
|
||||
mx->start = NULL;
|
||||
|
||||
return mx;
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
/* Useful headers. */
|
||||
#define XMSISDN_HEADER "X-WAP-Network-Client-MSISDN"
|
||||
#define XIP_HEADER "X-WAP-Network-Client-IP"
|
||||
#define MM_NAME "DS_MM"
|
||||
#define MM_NAME "Mbuni"
|
||||
|
||||
typedef struct MmsProxyRelay {
|
||||
Octstr *host;
|
||||
|
@ -42,6 +42,15 @@ typedef struct MmsProxyRelay {
|
|||
Octstr *denied_prefix;
|
||||
} MmsProxyRelay;
|
||||
|
||||
typedef struct MmsVasp {
|
||||
Octstr *id;
|
||||
long short_code;
|
||||
enum {SOAP_VASP, EAIF_VASP, NONE_VASP} type;
|
||||
Octstr *vasp_username, *vasp_password;
|
||||
Octstr *vasp_url;
|
||||
Octstr *mmsc_username, *mmsc_password;
|
||||
} MmsVasp;
|
||||
|
||||
typedef struct MmsBoxSettings {
|
||||
Octstr *system_user;
|
||||
Octstr *name, *hostname, *host_alias;
|
||||
|
@ -59,7 +68,7 @@ typedef struct MmsBoxSettings {
|
|||
double queue_interval;
|
||||
long send_back_off;
|
||||
|
||||
long port;
|
||||
long port, mm7port;
|
||||
|
||||
Octstr *allow_ip;
|
||||
Octstr *deny_ip;
|
||||
|
@ -98,6 +107,8 @@ typedef struct MmsBoxSettings {
|
|||
Octstr *mms_email_html;
|
||||
Octstr *wap_gw_msisdn_header;
|
||||
Octstr *wap_gw_ip_header;
|
||||
|
||||
List *vasp_list; /* of MmsVasp * */
|
||||
} MmsBoxSettings;
|
||||
|
||||
/* Global variables and shared code used by all modules. */
|
||||
|
@ -187,4 +198,6 @@ void mms_log2(char *logmsg, Octstr *from, Octstr *to,
|
|||
*/
|
||||
int mm_lockfile(int fd, char *fname, int shouldblock);
|
||||
|
||||
/* This should be elsewhere, but it isn't, so we do it here... */
|
||||
extern MIMEEntity *mime_entity_duplicate(MIMEEntity *m);
|
||||
#endif
|
||||
|
|
|
@ -159,9 +159,12 @@ int main(int argc, char *argv[])
|
|||
else
|
||||
dlr = 0;
|
||||
|
||||
qf = mms_queue_add(xfrom, lto, msgid, NULL, xproxy, NULL,
|
||||
0, time(NULL) + settings->default_msgexpiry, msg, NULL, dlr,
|
||||
octstr_get_cstr(settings->global_queuedir));
|
||||
qf = mms_queue_add(xfrom, lto, NULL, xproxy, NULL,
|
||||
0, time(NULL) + settings->default_msgexpiry, msg, NULL,
|
||||
NULL, NULL,
|
||||
dlr,
|
||||
octstr_get_cstr(settings->global_queuedir),
|
||||
settings->host_alias);
|
||||
if (qf) {
|
||||
|
||||
info(0, "Email2MMS Queued message to %s from %s (via %s) => %s",
|
||||
|
@ -184,11 +187,14 @@ int main(int argc, char *argv[])
|
|||
xlto = list_create();
|
||||
list_append(xlto, rto);
|
||||
|
||||
qf = mms_queue_add(settings->system_user, xlto, msgid, NULL,
|
||||
qf = mms_queue_add(settings->system_user, xlto, NULL,
|
||||
xproxy, NULL,
|
||||
0, time(NULL) + settings->default_msgexpiry,
|
||||
mresp, NULL, 0,
|
||||
octstr_get_cstr(settings->global_queuedir));
|
||||
mresp, NULL,
|
||||
NULL, NULL,
|
||||
0,
|
||||
octstr_get_cstr(settings->global_queuedir),
|
||||
settings->host_alias);
|
||||
|
||||
list_destroy(xlto, (list_item_destructor_t *)octstr_destroy);
|
||||
mms_destroy(mresp);
|
||||
|
@ -248,14 +254,17 @@ int main(int argc, char *argv[])
|
|||
} else {
|
||||
List *lto = list_create();
|
||||
Octstr *qf;
|
||||
Octstr *msgid = mms_get_header_value(msg, octstr_imm("Message-ID"));
|
||||
|
||||
|
||||
octstr_format_append(xto, "/TYPE=PLMN");
|
||||
list_append(lto, xto);
|
||||
qf = mms_queue_add(xfrom, lto, msgid, NULL,
|
||||
qf = mms_queue_add(xfrom, lto, NULL,
|
||||
xproxy, NULL,
|
||||
0, time(NULL) + settings->default_msgexpiry, msg, NULL, 0,
|
||||
octstr_get_cstr(settings->global_queuedir));
|
||||
0, time(NULL) + settings->default_msgexpiry, msg, NULL,
|
||||
NULL, NULL,
|
||||
0,
|
||||
octstr_get_cstr(settings->global_queuedir),
|
||||
settings->host_alias);
|
||||
list_destroy(lto, NULL);
|
||||
if (qf) {
|
||||
info(0, "Email2MMS Queued DLR from proxy %s to %s from %s => %s",
|
||||
|
@ -265,7 +274,6 @@ int main(int argc, char *argv[])
|
|||
octstr_destroy(qf);
|
||||
}
|
||||
|
||||
octstr_destroy(msgid);
|
||||
list_destroy(lto, NULL);
|
||||
}
|
||||
break;
|
||||
|
@ -283,14 +291,16 @@ int main(int argc, char *argv[])
|
|||
} else {
|
||||
List *lto = list_create();
|
||||
Octstr *qf;
|
||||
Octstr *msgid = mms_get_header_value(msg, octstr_imm("Message-ID"));
|
||||
|
||||
octstr_format_append(xto, "/TYPE=PLMN");
|
||||
list_append(lto, xto);
|
||||
qf = mms_queue_add(xfrom, lto, msgid, NULL,
|
||||
qf = mms_queue_add(xfrom, lto, NULL,
|
||||
xproxy, NULL,
|
||||
0, time(NULL) + settings->default_msgexpiry, msg, NULL,0,
|
||||
octstr_get_cstr(settings->global_queuedir));
|
||||
0, time(NULL) + settings->default_msgexpiry, msg, NULL,
|
||||
NULL, NULL,
|
||||
0,
|
||||
octstr_get_cstr(settings->global_queuedir),
|
||||
settings->host_alias);
|
||||
list_destroy(lto, NULL);
|
||||
if (qf) {
|
||||
info(0, "Email2MMS Queued read report from proxy %s to %s from %s => %s",
|
||||
|
@ -300,7 +310,7 @@ int main(int argc, char *argv[])
|
|||
octstr_destroy(qf);
|
||||
}
|
||||
|
||||
octstr_destroy(msgid);
|
||||
|
||||
list_destroy(lto, NULL);
|
||||
}
|
||||
default:
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include "mms_queue.h"
|
||||
#include "mms_uaprof.h"
|
||||
#include "mms_util.h"
|
||||
#include "mms_mm7soap.h"
|
||||
|
||||
#define NMAX 256
|
||||
static char mobile_qdir[NMAX];
|
||||
|
@ -54,6 +55,10 @@ static int mms_sendtoproxy(Octstr *from, Octstr *to,
|
|||
Octstr *subject, Octstr *proxy,
|
||||
Octstr *msgid, time_t expires, MmsMsg *m, int dlr, Octstr **error);
|
||||
|
||||
static int mms_sendtovasp(MmsVasp *vasp, Octstr *from, Octstr *to, Octstr *msgId,
|
||||
MmsMsg *m, Octstr **error);
|
||||
|
||||
static int _x_octstr_int_compare(int n, Octstr *s);
|
||||
/* Send errors */
|
||||
#define MMS_SEND_OK 0
|
||||
#define MMS_SEND_ERROR_TRANSIENT -1
|
||||
|
@ -146,7 +151,11 @@ static int sendMsg(MmsEnvelope *e)
|
|||
goto done;
|
||||
}
|
||||
|
||||
/* first check if it is an email address */
|
||||
/* - first check if it is an email address.
|
||||
* - Next check if proxy to send through is already set, use it.
|
||||
* - else we have a number of IP, try to deliver...
|
||||
*/
|
||||
|
||||
if (octstr_search_char(to->rcpt, '@', 0) > 0) {
|
||||
res = mms_sendtoemail(e->from, to->rcpt,
|
||||
e->subject,
|
||||
|
@ -156,7 +165,7 @@ static int sendMsg(MmsEnvelope *e)
|
|||
mms_log2("Sent", e->from, to->rcpt,
|
||||
-1, e->msgId, NULL, NULL, "MM3", NULL,NULL);
|
||||
|
||||
} else if (e->viaproxy && octstr_len(e->viaproxy) > 0) /* If proxy to send through is already set, use it. */
|
||||
} else if (e->viaproxy && octstr_len(e->viaproxy) > 0)
|
||||
res = mms_sendtoproxy(e->from,
|
||||
to->rcpt, e->subject, e->viaproxy,
|
||||
e->msgId, e->expiryt, msg, e->dlr, &err);
|
||||
|
@ -167,8 +176,10 @@ static int sendMsg(MmsEnvelope *e)
|
|||
Octstr *phonenum = NULL;
|
||||
Octstr *mmsc;
|
||||
int sent = 0;
|
||||
MmsVasp *vasp;
|
||||
|
||||
if (j > 0 && j - 1 + sizeof "/TYPE=PLMN" == len) /* A proper number. */
|
||||
/* If it is an IP, send to mobile handler, else if number, look for recipient. */
|
||||
if (j > 0 && j - 1 + sizeof "/TYPE=PLMN" == len)
|
||||
phonenum = octstr_copy(to->rcpt, 0, j);
|
||||
else if (k > 0 && k + sizeof "/TYPE=IPv" == len) {
|
||||
res = mms_sendtomobile(e->from,
|
||||
|
@ -184,11 +195,12 @@ static int sendMsg(MmsEnvelope *e)
|
|||
goto done;
|
||||
}
|
||||
|
||||
/* Normalise the number, then match against local prefixes. */
|
||||
/* Normalise the number, then see if we can resolve home MMSC for this recipient. */
|
||||
normalize_number(octstr_get_cstr(settings->unified_prefix), &phonenum);
|
||||
|
||||
if ((mmsc = settings->mms_resolvefuncs->mms_resolve(phonenum,
|
||||
settings->mms_resolver_module_data, settings, proxyrelays))) {
|
||||
settings->mms_resolver_module_data,
|
||||
settings, proxyrelays))) {
|
||||
info(0, "mmsc for \"%s\" resolved to: \"%s\"",
|
||||
octstr_get_cstr(phonenum), octstr_get_cstr(mmsc));
|
||||
|
||||
|
@ -199,8 +211,7 @@ static int sendMsg(MmsEnvelope *e)
|
|||
e->msgId, e->expiryt, msg, e->dlr,
|
||||
&err);
|
||||
sent = 1;
|
||||
} else if (proxyrelays && list_len(proxyrelays) > 0)
|
||||
/* Step through proxies. */
|
||||
} else if (proxyrelays && list_len(proxyrelays) > 0) /* Step through proxies. */
|
||||
for (j = 0, m = list_len(proxyrelays); j<m; j++) {
|
||||
MmsProxyRelay *mp = list_get(proxyrelays, j);
|
||||
|
||||
|
@ -213,7 +224,17 @@ static int sendMsg(MmsEnvelope *e)
|
|||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else /* Search VASP list, see what you can find... */
|
||||
for (j = 0, m = list_len(settings->vasp_list); j < m; j++)
|
||||
if ((vasp = list_get(settings->vasp_list, j)) != NULL &&
|
||||
_x_octstr_int_compare(vasp->short_code, phonenum) == 0) {
|
||||
res = mms_sendtovasp(vasp, e->from, to->rcpt,
|
||||
e->msgId,
|
||||
msg, &err);
|
||||
sent = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!sent) {
|
||||
res = MMS_SEND_ERROR_FATAL;
|
||||
err = octstr_format("MMSC error: Don't know how to deliver to %S !", to->rcpt);
|
||||
|
@ -228,7 +249,7 @@ static int sendMsg(MmsEnvelope *e)
|
|||
else { /* If there was a report request, queue it. */
|
||||
|
||||
if (e->dlr) {
|
||||
|
||||
Octstr *qfs;
|
||||
MmsMsg *m = mms_deliveryreport(e->msgId, to->rcpt, tnow,
|
||||
(e->expiryt != 0 && e->expiryt < tnow) ?
|
||||
octstr_imm("Expired") : octstr_imm("Rejected"));
|
||||
|
@ -239,9 +260,14 @@ static int sendMsg(MmsEnvelope *e)
|
|||
list_append(l, octstr_duplicate(e->from));
|
||||
|
||||
/* Add to queue, switch via proxy to be from proxy. */
|
||||
mms_queue_add(settings->system_user, l, e->msgId, err, NULL, e->fromproxy,
|
||||
tnow, tnow+settings->default_msgexpiry, m, NULL, 0,
|
||||
qdir);
|
||||
qfs = mms_queue_add(settings->system_user, l,
|
||||
err, NULL, e->fromproxy,
|
||||
tnow, tnow+settings->default_msgexpiry, m, NULL,
|
||||
NULL, NULL,
|
||||
0,
|
||||
qdir,
|
||||
settings->host_alias);
|
||||
octstr_destroy(qfs);
|
||||
list_destroy(l, NULL);
|
||||
|
||||
mms_destroy(m);
|
||||
|
@ -432,8 +458,10 @@ int mms_sendtomobile(Octstr *from, Octstr *to,
|
|||
|
||||
x = octstr_create(tokenstr);
|
||||
|
||||
ret = mms_queue_add(from, l, msgid, subject, fromproxy, NULL, 0, expires, m,
|
||||
x, dlr, mobile_qdir);
|
||||
ret = mms_queue_add(from, l, subject, fromproxy, NULL, 0, expires, m,
|
||||
x, NULL, NULL,
|
||||
dlr, mobile_qdir,
|
||||
settings->host_alias);
|
||||
octstr_destroy(x);
|
||||
|
||||
list_destroy(l, NULL);
|
||||
|
@ -470,7 +498,10 @@ static int mms_sendtoproxy(Octstr *from, Octstr *to,
|
|||
List *l = list_create();
|
||||
Octstr *ret;
|
||||
list_append(l, to);
|
||||
ret = mms_queue_add(from, l, msgid, subject, NULL, proxy, 0, expires, msg,NULL, dlr, mm4_qdir);
|
||||
ret = mms_queue_add(from, l, subject, NULL, proxy, 0, expires, msg,NULL,
|
||||
NULL, NULL,
|
||||
dlr, mm4_qdir,
|
||||
settings->host_alias);
|
||||
list_destroy(l, NULL);
|
||||
|
||||
if (ret == NULL) {
|
||||
|
@ -495,3 +526,116 @@ static int mms_sendtoproxy(Octstr *from, Octstr *to,
|
|||
|
||||
return x;
|
||||
}
|
||||
|
||||
static int _x_octstr_int_compare(int n, Octstr *s)
|
||||
{
|
||||
char x[64];
|
||||
|
||||
sprintf(x, "%d", n);
|
||||
return octstr_str_compare(s,x);
|
||||
}
|
||||
|
||||
static int mms_sendtovasp(MmsVasp *vasp, Octstr *from, Octstr *to, Octstr *msgId,
|
||||
MmsMsg *m, Octstr **error)
|
||||
{
|
||||
int ret = MMS_SEND_ERROR_TRANSIENT;
|
||||
int mtype = mms_messagetype(m);
|
||||
|
||||
info(0, "MMS Relay: Send to VASP[%s], msg type [%s], from %s, to %s",
|
||||
vasp ? octstr_get_cstr(vasp->id) : "",
|
||||
mms_message_type_to_cstr(mtype), octstr_get_cstr(from), octstr_get_cstr(to));
|
||||
|
||||
if (vasp->type == SOAP_VASP) {
|
||||
int hstatus = HTTP_OK, tstatus;
|
||||
List *xto = list_create();
|
||||
MSoapMsg_t *mreq = NULL, *mresp = NULL;
|
||||
List *rh = NULL, *ph = NULL;
|
||||
Octstr *body = NULL, *rbody = NULL, *url = NULL;
|
||||
HTTPCaller *caller = http_caller_create();
|
||||
void *xx;
|
||||
Octstr *s;
|
||||
|
||||
list_append(xto, to);
|
||||
|
||||
|
||||
if ((mreq = mm7_mmsmsg_to_soap(m, from, xto, msgId, settings->host_alias)) == NULL) {
|
||||
*error = octstr_format("Failed to convert Msg[%s] 2 SOAP message!",
|
||||
mms_message_type_to_cstr(mtype));
|
||||
goto done1;
|
||||
}
|
||||
|
||||
if (mm7_soapmsg_to_httpmsg(mreq, &rh, &body) < 0) {
|
||||
*error = octstr_format("Failed to convert SOAP message 2 HTTP Msg!");
|
||||
goto done1;
|
||||
}
|
||||
|
||||
if (vasp->mmsc_username)
|
||||
http_add_basic_auth(rh, vasp->mmsc_username,
|
||||
vasp->mmsc_password ? vasp->mmsc_password : octstr_imm(""));
|
||||
|
||||
http_start_request(caller, HTTP_METHOD_POST, vasp->vasp_url, rh, body, 1, NULL, NULL);
|
||||
|
||||
if ((xx = http_receive_result(caller, &hstatus, &url, &ph, &rbody)) == NULL ||
|
||||
hstatus != HTTP_OK) {
|
||||
*error = octstr_format("Failed to contact VASP[url=%s] => HTTP returned status = %d, id=%s !",
|
||||
octstr_get_cstr(vasp->vasp_url), hstatus, xx ? "Ok" : "not OK");
|
||||
goto done1;
|
||||
}
|
||||
|
||||
if ((mresp = mm7_parse_soap(ph, rbody)) == NULL) {
|
||||
*error = octstr_format("Failed to parse VASP[url=%s, id=%s] response!",
|
||||
octstr_get_cstr(vasp->vasp_url),
|
||||
octstr_get_cstr(vasp->id));
|
||||
goto done1;
|
||||
}
|
||||
|
||||
/* Now look at response code and use it to tell you what you want. */
|
||||
if ((s = mm7_soap_header_value(mresp, octstr_imm("StatusCode"))) != NULL) {
|
||||
tstatus = atoi(octstr_get_cstr(s));
|
||||
octstr_destroy(s);
|
||||
} else
|
||||
tstatus = MM7_SOAP_FORMAT_CORRUPT;
|
||||
|
||||
if (!MM7_SOAP_STATUS_OK(tstatus)) {
|
||||
Octstr *detail = mm7_soap_header_value(mresp, octstr_imm("Details"));
|
||||
ret = MMS_SEND_ERROR_FATAL;
|
||||
info(0, "Send to VASP[%s], failed, code=[%d=>%s], detail=%s",
|
||||
vasp ? octstr_get_cstr(vasp->id) : "",
|
||||
tstatus, mms_soap_status_to_cstr(tstatus),
|
||||
detail ? octstr_get_cstr(detail) : "");
|
||||
*error = octstr_format("Failed to deliver to VASP[url=%s, id=%s], status=[%d=>%s]!",
|
||||
octstr_get_cstr(vasp->vasp_url),
|
||||
octstr_get_cstr(vasp->id),
|
||||
tstatus, mms_soap_status_to_cstr(tstatus));
|
||||
|
||||
if (detail)
|
||||
octstr_destroy(detail);
|
||||
|
||||
} else
|
||||
ret = MMS_SEND_OK;
|
||||
|
||||
info(0, "Sent to VASP[%s], code=[%d=>%s]", octstr_get_cstr(vasp->id),
|
||||
tstatus, mms_soap_status_to_cstr(tstatus));
|
||||
done1:
|
||||
|
||||
if (mreq)
|
||||
mm7_soap_destroy(mreq);
|
||||
if (mresp)
|
||||
mm7_soap_destroy(mresp);
|
||||
if (rh)
|
||||
http_destroy_headers(rh);
|
||||
if (body)
|
||||
octstr_destroy(body);
|
||||
if (ph)
|
||||
http_destroy_headers(ph);
|
||||
if (rbody)
|
||||
octstr_destroy(rbody);
|
||||
if (url)
|
||||
octstr_destroy(url);
|
||||
http_caller_destroy(caller);
|
||||
list_destroy(xto, NULL);
|
||||
} /* else if EAIF, etc.. */
|
||||
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -206,7 +206,7 @@ static int receive_push_reply(HTTPCaller *caller)
|
|||
mms_log2("Notify", octstr_imm("system"), to,
|
||||
-1, env ? env->msgId : NULL, NULL, NULL, "MM1", NULL,NULL);
|
||||
|
||||
if (update_env_success(env, xto) != NULL)
|
||||
if ((env = update_env_success(env, xto)) != NULL)
|
||||
goto push_free_env;
|
||||
|
||||
/* Fall through. */
|
||||
|
@ -411,10 +411,13 @@ static int sendNotify(MmsEnvelope *e)
|
|||
list_append(l, from);
|
||||
|
||||
/* Add to queue, switch via proxy to be from proxy. */
|
||||
res = mms_queue_add(settings->system_user, l, msgId, err,
|
||||
res = mms_queue_add(settings->system_user, l, err,
|
||||
NULL, fromproxy,
|
||||
tnow, tnow+settings->default_msgexpiry, m, NULL, 0,
|
||||
octstr_get_cstr(settings->mm1_queuedir));
|
||||
tnow, tnow+settings->default_msgexpiry, m, NULL,
|
||||
NULL, NULL,
|
||||
0,
|
||||
octstr_get_cstr(settings->mm1_queuedir),
|
||||
settings->host_alias);
|
||||
list_destroy(l, NULL);
|
||||
mms_destroy(m);
|
||||
octstr_destroy(res);
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
|
||||
#include "mms_uaprof.h"
|
||||
#include "mms_util.h"
|
||||
#include "mms_mm7soap.h"
|
||||
|
||||
static Cfg *cfg;
|
||||
static List *proxyrelays;
|
||||
|
@ -44,11 +45,13 @@ typedef struct MmsHTTPClientInfo {
|
|||
MmsUaProfile *prof;
|
||||
Octstr *base_client_addr;
|
||||
Octstr *client_addr;
|
||||
MmsVasp *vasp;
|
||||
} MmsHTTPClientInfo;
|
||||
|
||||
static void fetchmms_proxy(MmsHTTPClientInfo *h);
|
||||
static void sendmms_proxy(MmsHTTPClientInfo *h);
|
||||
|
||||
static void mm7proxy(void *unused);
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int cfidx;
|
||||
|
@ -59,6 +62,8 @@ int main(int argc, char *argv[])
|
|||
|
||||
MmsHTTPClientInfo h;
|
||||
|
||||
long mm7_thread = -1;
|
||||
|
||||
mms_lib_init();
|
||||
srandom(time(NULL));
|
||||
|
||||
|
@ -111,14 +116,22 @@ int main(int argc, char *argv[])
|
|||
/* Start cache engine. */
|
||||
mms_start_profile_engine(octstr_get_cstr(settings->ua_profile_cache_dir));
|
||||
|
||||
/* If we have mm7 port, start thread for it. */
|
||||
/* Now open port and start dispatching requests. */
|
||||
|
||||
if (http_open_port(settings->port, 0) < 0) {
|
||||
error(0, "MMS Proxy: Failed to start http server: %d => %s!",
|
||||
errno, strerror(errno));
|
||||
return -1;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (settings->mm7port > 0 &&
|
||||
http_open_port(settings->mm7port, 0) >= 0)
|
||||
mm7_thread = gwthread_create((gwthread_func_t *)mm7proxy, NULL);
|
||||
else
|
||||
warning(0, "MMS Proxy: MM7 interface not open, port=%ld",
|
||||
settings->mm7port);
|
||||
|
||||
while(rstop == 0 && (h.client = http_accept_request(settings->port,
|
||||
&h.ip, &h.url, &h.headers,
|
||||
&h.body, &h.cgivars)) != NULL)
|
||||
|
@ -126,6 +139,8 @@ int main(int argc, char *argv[])
|
|||
MmsHTTPClientInfo *hx = gw_malloc(sizeof *hx);
|
||||
Octstr *profile_url;
|
||||
|
||||
memset(hx, 0, sizeof *hx);
|
||||
|
||||
h.ua = http_header_value(h.headers, octstr_imm("User-Agent"));
|
||||
|
||||
/* Get the profile URL and store it. Has effect of fetching if missing. */
|
||||
|
@ -209,7 +224,11 @@ int main(int argc, char *argv[])
|
|||
http_close_client(h.client);
|
||||
}
|
||||
|
||||
debug("proxy", 0, "Shutdown requested");
|
||||
done:
|
||||
debug("proxy", 0, "MM1 Shutting down...");
|
||||
if (mm7_thread >= 0)
|
||||
gwthread_join(mm7_thread);
|
||||
debug("proxy", 0, "Closed mm7 thread");
|
||||
http_close_all_ports();
|
||||
debug("proxy", 0, "Port closed");
|
||||
sleep(2); /* Give them time to shut down. */
|
||||
|
@ -556,9 +575,6 @@ static void sendmms_proxy(MmsHTTPClientInfo *h)
|
|||
|
||||
mms_remove_headers(m, "X-Mms-Store");
|
||||
|
||||
msgid = mms_maketransid(NULL, settings->host_alias);
|
||||
mms_replace_header_value(m, "Message-ID", octstr_get_cstr(msgid)); /* Put in message id -- for later. */
|
||||
|
||||
|
||||
if (menc >= MS_1_2 &&
|
||||
x != NULL &&
|
||||
|
@ -596,15 +612,19 @@ static void sendmms_proxy(MmsHTTPClientInfo *h)
|
|||
dlr = 0;
|
||||
|
||||
|
||||
qf = mms_queue_add(from, to, msgid, subject,
|
||||
NULL, NULL, deliveryt, expiryt, m, NULL, dlr,
|
||||
octstr_get_cstr(settings->global_queuedir));
|
||||
qf = mms_queue_add(from, to, subject,
|
||||
NULL, NULL, deliveryt, expiryt, m, NULL,
|
||||
NULL, NULL,
|
||||
dlr,
|
||||
octstr_get_cstr(settings->global_queuedir),
|
||||
settings->host_alias);
|
||||
|
||||
if (!qf)
|
||||
mresp = mms_sendconf("Error-transient-failure", "None", octstr_get_cstr(otransid),0,
|
||||
menc);
|
||||
else {
|
||||
|
||||
msgid = mms_maketransid(octstr_get_cstr(qf),
|
||||
settings->host_alias);
|
||||
mresp = mms_sendconf("Ok", octstr_get_cstr(msgid), octstr_get_cstr(otransid),0,
|
||||
menc);
|
||||
|
||||
|
@ -731,7 +751,7 @@ static void sendmms_proxy(MmsHTTPClientInfo *h)
|
|||
Octstr *pmsgid = mms_get_header_value(mfwd, octstr_imm("Message-ID"));
|
||||
Octstr *pdelivery_report = mms_get_header_value(mfwd,
|
||||
octstr_imm("X-Mms-Delivery-Report"));
|
||||
Octstr *msgid = mms_maketransid(NULL, settings->host_alias);
|
||||
Octstr *msgid = NULL;
|
||||
Octstr *s;
|
||||
Octstr *qf2;
|
||||
int n = 0;
|
||||
|
@ -744,7 +764,6 @@ static void sendmms_proxy(MmsHTTPClientInfo *h)
|
|||
|
||||
/* Modify the message before sending on as per spec. */
|
||||
mms_replace_header_value(mfwd, "From", octstr_get_cstr(from));
|
||||
mms_replace_header_value(mfwd, "Message-ID", octstr_get_cstr(msgid)); /* Put in message id -- for later. */
|
||||
|
||||
mms_remove_headers(mfwd, "X-Mms-Read-Report");
|
||||
if (read_report)
|
||||
|
@ -783,10 +802,12 @@ static void sendmms_proxy(MmsHTTPClientInfo *h)
|
|||
else
|
||||
dlr = 0;
|
||||
/* Message to forward is now ready, write it to queue. */
|
||||
qf2 = mms_queue_add(from, to, msgid, subject,
|
||||
NULL, NULL, deliveryt, expiryt, mfwd, NULL,
|
||||
dlr,
|
||||
octstr_get_cstr(settings->global_queuedir));
|
||||
qf2 = mms_queue_add(from, to, subject,
|
||||
NULL, NULL, deliveryt, expiryt, mfwd, NULL,
|
||||
NULL, NULL,
|
||||
dlr,
|
||||
octstr_get_cstr(settings->global_queuedir),
|
||||
settings->host_alias);
|
||||
|
||||
/* Process any requests for writing to mmbox. */
|
||||
x = mms_get_header_value(m, octstr_imm("X-Mms-Store"));
|
||||
|
@ -832,6 +853,7 @@ static void sendmms_proxy(MmsHTTPClientInfo *h)
|
|||
mresp = mms_sendconf("Error-transient-failure",
|
||||
"None", octstr_get_cstr(otransid),1,menc);
|
||||
else {
|
||||
msgid = mms_maketransid(octstr_get_cstr(qf2), settings->host_alias);
|
||||
mresp = mms_sendconf("Ok",
|
||||
octstr_get_cstr(msgid),
|
||||
octstr_get_cstr(otransid),1,menc);
|
||||
|
@ -866,10 +888,13 @@ static void sendmms_proxy(MmsHTTPClientInfo *h)
|
|||
List *l = list_create();
|
||||
list_append(l, pfrom);
|
||||
|
||||
x = mms_queue_add(settings->system_user, l, NULL, NULL, NULL, NULL, 0,
|
||||
x = mms_queue_add(settings->system_user, l, NULL, NULL, NULL, 0,
|
||||
time(NULL) + settings->default_msgexpiry,
|
||||
mrep, NULL,0,
|
||||
octstr_get_cstr(settings->global_queuedir));
|
||||
mrep, NULL,
|
||||
NULL, NULL,
|
||||
0,
|
||||
octstr_get_cstr(settings->global_queuedir),
|
||||
settings->host_alias);
|
||||
octstr_destroy(x);
|
||||
|
||||
list_destroy(l, NULL);
|
||||
|
@ -983,9 +1008,12 @@ static void sendmms_proxy(MmsHTTPClientInfo *h)
|
|||
mrpt = mms_deliveryreport(e->msgId, h->client_addr, time(NULL), status);
|
||||
list_append(l, octstr_duplicate(e->from));
|
||||
|
||||
x = mms_queue_add(settings->system_user, l, NULL, NULL, NULL, NULL, 0,
|
||||
time(NULL) + settings->default_msgexpiry, mrpt, NULL, 0,
|
||||
octstr_get_cstr(settings->global_queuedir));
|
||||
x = mms_queue_add(settings->system_user, l, NULL, NULL, NULL, 0,
|
||||
time(NULL) + settings->default_msgexpiry, mrpt, NULL,
|
||||
NULL, NULL,
|
||||
0,
|
||||
octstr_get_cstr(settings->global_queuedir),
|
||||
settings->host_alias);
|
||||
octstr_destroy(x);
|
||||
|
||||
list_destroy(l, (list_item_destructor_t *)octstr_destroy);
|
||||
|
@ -1030,9 +1058,12 @@ static void sendmms_proxy(MmsHTTPClientInfo *h)
|
|||
|
||||
collect_senddata(mh, &to, NULL, NULL, NULL, NULL);
|
||||
|
||||
x = mms_queue_add(from, to, NULL, NULL, NULL,
|
||||
NULL, time(NULL), time(NULL) + settings->default_msgexpiry,
|
||||
m, NULL, 0, octstr_get_cstr(settings->global_queuedir));
|
||||
x = mms_queue_add(from, to, NULL, NULL, NULL, time(NULL),
|
||||
time(NULL) + settings->default_msgexpiry,
|
||||
m, NULL, 0,
|
||||
NULL, NULL,
|
||||
octstr_get_cstr(settings->global_queuedir),
|
||||
settings->host_alias);
|
||||
|
||||
/* Log to access log */
|
||||
mms_log("ReadReport", h->client_addr, NULL, msize, NULL, NULL, NULL, "MM1", h->ua,NULL);
|
||||
|
@ -1549,3 +1580,324 @@ static void sendmms_proxy(MmsHTTPClientInfo *h)
|
|||
gw_free(h);
|
||||
|
||||
}
|
||||
|
||||
/* Find sender credentials: only auth-basic supported for now. */
|
||||
static MmsVasp *find_mm7sender(List *headers, List *vasps)
|
||||
{
|
||||
Octstr *v = http_header_value(headers, octstr_imm("Authorization"));
|
||||
Octstr *p = NULL, *q = NULL;
|
||||
MmsVasp *m = NULL;
|
||||
int i, n;
|
||||
|
||||
#if 0
|
||||
return list_get(vasps,0); /* XXX for testing... */
|
||||
#endif
|
||||
if (!v ||
|
||||
octstr_search(v, octstr_imm("Basic "), 0) != 0)
|
||||
goto done;
|
||||
p = octstr_copy(v, sizeof "Basic", octstr_len(v));
|
||||
octstr_base64_to_binary(p);
|
||||
|
||||
i = octstr_search_char(p, ':', 0);
|
||||
q = octstr_copy(p, i+1, octstr_len(p));
|
||||
octstr_delete(p, i, octstr_len(p));
|
||||
|
||||
/* p = user, q = pass. */
|
||||
for (i = 0, n = list_len(vasps); i<n; i++) {
|
||||
MmsVasp *x = list_get(vasps, i);
|
||||
|
||||
if (octstr_compare(x->vasp_username, p) == 0 &&
|
||||
octstr_compare(x->vasp_password, q) == 0) {
|
||||
m = x;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* if it can't authenticate, returns NULL. */
|
||||
|
||||
done:
|
||||
if (v)
|
||||
octstr_destroy(v);
|
||||
if (p)
|
||||
octstr_destroy(p);
|
||||
if (q)
|
||||
octstr_destroy(q);
|
||||
return m;
|
||||
}
|
||||
|
||||
static void mm7dispatch(MmsHTTPClientInfo *h)
|
||||
{
|
||||
/* if no vasp, return 4001 error. */
|
||||
MSoapMsg_t *mreq = NULL, *mresp = NULL;
|
||||
int hstatus = HTTP_OK;
|
||||
List *rh = NULL;
|
||||
Octstr *reply_body = NULL;
|
||||
Octstr *sender = NULL;
|
||||
MmsEnvelope *e = NULL;
|
||||
|
||||
List *to = NULL;
|
||||
Octstr *from = NULL, *subject = NULL, *vasid = NULL, *msgid = NULL;
|
||||
time_t expiryt = -1, delivert = -1;
|
||||
MmsMsg *m = NULL;
|
||||
int status = 1000;
|
||||
char *msgtype = "";
|
||||
Octstr *qf = NULL;
|
||||
|
||||
mreq = mm7_parse_soap(h->headers, h->body);
|
||||
if (mreq)
|
||||
msgtype = mms_mm7tag_to_cstr(mm7_msgtype(mreq));
|
||||
debug("mmsprox.mm7sendinterface", 0,
|
||||
" --> Enterred mm7dispatch interface, mreq=%s mtype = %s <-- ",
|
||||
mreq ? "Ok" : "Null",
|
||||
mreq ? msgtype : "Null");
|
||||
|
||||
|
||||
if (!h->vasp) {
|
||||
/* Ask it to authenticate... */
|
||||
List *hh = http_create_empty_headers();
|
||||
http_header_add(hh, "WWW-Authenticate",
|
||||
"Basic realm=\"" MM_NAME "\"");
|
||||
http_send_reply(h->client, 401, hh, octstr_imm(""));
|
||||
goto done2;
|
||||
} else if (!mreq) {
|
||||
mresp = mm7_make_resp(NULL, 2007, NULL);
|
||||
goto done;
|
||||
}
|
||||
|
||||
sender = octstr_format("%d/TYPE=PLMN", h->vasp->short_code);
|
||||
switch (mm7_msgtype(mreq)) {
|
||||
case MM7_TAG_SubmitReq:
|
||||
mm7_get_envelope(mreq, &from, &to, &subject, &vasid, &expiryt, &delivert);
|
||||
m = mm7_soap_to_mmsmsg(mreq, sender);
|
||||
if (m) {
|
||||
Octstr *value;
|
||||
int dlr;
|
||||
|
||||
value = mms_get_header_value(m, octstr_imm("X-Mms-Delivery-Report"));
|
||||
if (value &&
|
||||
octstr_case_compare(value, octstr_imm("Yes")) == 0)
|
||||
dlr = 1;
|
||||
else
|
||||
dlr = 0;
|
||||
|
||||
if (delivert < 0)
|
||||
delivert = time(NULL);
|
||||
|
||||
if (expiryt < 0)
|
||||
expiryt = time(NULL) + settings->default_msgexpiry;
|
||||
|
||||
qf = mms_queue_add(from ? from : sender, to, subject,
|
||||
NULL, NULL,
|
||||
delivert, expiryt, m, NULL,
|
||||
h->vasp->id, vasid, dlr,
|
||||
octstr_get_cstr(settings->global_queuedir),
|
||||
settings->host_alias);
|
||||
msgid = mms_maketransid(octstr_get_cstr(qf), settings->host_alias);
|
||||
mms_log("Received", sender, to, -1, msgid, h->vasp->id, NULL, "MM7", h->ua, NULL);
|
||||
|
||||
octstr_destroy(value);
|
||||
} else
|
||||
status = 4001;
|
||||
mresp = mm7_make_resp(mreq, status, msgid);
|
||||
break;
|
||||
|
||||
case MM7_TAG_ReplaceReq:
|
||||
msgid = mm7_soap_header_value(mreq, octstr_imm("MessageID"));
|
||||
if (msgid && (qf = mms_getqf_fromtransid(msgid)) != NULL &&
|
||||
(e = mms_queue_readenvelope(octstr_get_cstr(qf),
|
||||
octstr_get_cstr(settings->global_queuedir),
|
||||
1)) != NULL) {
|
||||
if (!e->vaspid ||
|
||||
octstr_compare(e->vaspid, h->vasp->id) != 0) {
|
||||
status = 2001;
|
||||
error(0, "MMS Proxy(MM7): ReplaceReq: Found message[id=%s]"
|
||||
" but vaspid id=%s does not match!",
|
||||
octstr_get_cstr(msgid), octstr_get_cstr(h->vasp->id));
|
||||
} else { /* get orig message, change headers of new, replace old. */
|
||||
MmsMsg *old = mms_queue_getdata(e);
|
||||
MmsMsg *new = mm7_soap_to_mmsmsg(mreq, sender);
|
||||
List *hh = mms_message_headers(old);
|
||||
Octstr *s;
|
||||
|
||||
if (new) {
|
||||
mms_add_missing_headers(new, hh);
|
||||
if (mms_queue_replacedata(e, new) < 0) {
|
||||
status = 3000;
|
||||
error(0, "MMS Proxy(MM7): ReplaceReq: Failed to change data, "
|
||||
"id=%s, vasp=%s!",
|
||||
msgid ? octstr_get_cstr(msgid) : "NULL",
|
||||
octstr_get_cstr(h->vasp->id));
|
||||
}
|
||||
} else
|
||||
warning(0, "MMS Proxy(MM7): ReplaceReq: No data sent??, "
|
||||
"id=%s, vasp=%s!",
|
||||
msgid ? octstr_get_cstr(msgid) : "NULL",
|
||||
octstr_get_cstr(h->vasp->id));
|
||||
|
||||
if ((s = mm7_soap_header_value(mreq,
|
||||
octstr_imm("EarliestDeliveryTime"))) != NULL) {
|
||||
e->sendt = date_parse_http(s);
|
||||
octstr_destroy(s);
|
||||
}
|
||||
|
||||
if (mms_queue_update(e) != 1)
|
||||
mms_queue_free_env(e);
|
||||
e = NULL;
|
||||
mms_log("Replace",
|
||||
sender, NULL, -1, msgid, h->vasp->id, NULL, "MM7", h->ua, NULL);
|
||||
|
||||
if (new)
|
||||
mms_destroy(new);
|
||||
if (old)
|
||||
mms_destroy(old);
|
||||
http_destroy_headers(hh);
|
||||
}
|
||||
} else {
|
||||
status = 2005;
|
||||
error(0, "MMS Proxy(MM7): ReplaceReq: Failed to find msg, id=%s, vasp=%s!",
|
||||
msgid ? octstr_get_cstr(msgid) : "NULL",
|
||||
octstr_get_cstr(h->vasp->id));
|
||||
}
|
||||
|
||||
mresp = mm7_make_resp(mreq, status, NULL);
|
||||
break;
|
||||
|
||||
case MM7_TAG_CancelReq:
|
||||
msgid = mm7_soap_header_value(mreq, octstr_imm("MessageID"));
|
||||
if (msgid && (qf = mms_getqf_fromtransid(msgid)) != NULL &&
|
||||
(e = mms_queue_readenvelope(octstr_get_cstr(qf),
|
||||
octstr_get_cstr(settings->global_queuedir),
|
||||
1)) != NULL) {
|
||||
if (!e->vaspid ||
|
||||
octstr_compare(e->vaspid, h->vasp->id) != 0) {
|
||||
status = 2001;
|
||||
error(0, "MMS Proxy(MM7): CancelReq: Found message[id=%s]"
|
||||
" bxut vaspid id=%s does not match!",
|
||||
octstr_get_cstr(msgid), octstr_get_cstr(h->vasp->id));
|
||||
} else { /* Kill it. */
|
||||
int i, n;
|
||||
for (i = 0, n = list_len(e->to); i<n; i++) {
|
||||
MmsEnvelopeTo *xto = list_get(e->to,i);
|
||||
xto->process = 0;
|
||||
}
|
||||
mms_queue_update(e); /* Will clear it. */
|
||||
e = NULL;
|
||||
mms_log("Cancel",
|
||||
sender, NULL, -1, msgid, h->vasp->id, NULL, "MM7", h->ua, NULL);
|
||||
}
|
||||
} else {
|
||||
status = 2005;
|
||||
error(0, "MMS Proxy(MM7): CancelReq: Failed to find msg, id=%s, vasp=%s!",
|
||||
msgid ? octstr_get_cstr(msgid) : "NULL",
|
||||
octstr_get_cstr(h->vasp->id));
|
||||
}
|
||||
mresp = mm7_make_resp(mreq, status, NULL);
|
||||
break;
|
||||
default:
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
done:
|
||||
if (mresp && mm7_soapmsg_to_httpmsg(mresp, &rh, &reply_body) == 0)
|
||||
http_send_reply(h->client, hstatus, rh, reply_body);
|
||||
else
|
||||
http_close_client(h->client);
|
||||
|
||||
done2:
|
||||
if (e)
|
||||
mms_queue_free_env(e);
|
||||
|
||||
if (sender)
|
||||
octstr_destroy(sender);
|
||||
|
||||
if (from)
|
||||
octstr_destroy(from);
|
||||
|
||||
if (subject)
|
||||
octstr_destroy(subject);
|
||||
if (vasid)
|
||||
octstr_destroy(vasid);
|
||||
if (msgid)
|
||||
octstr_destroy(msgid);
|
||||
|
||||
if (qf)
|
||||
octstr_destroy(qf);
|
||||
if (m)
|
||||
mms_destroy(m);
|
||||
if (rh)
|
||||
http_destroy_headers(rh);
|
||||
if (reply_body)
|
||||
octstr_destroy(reply_body);
|
||||
|
||||
if (mresp)
|
||||
mm7_soap_destroy(mresp);
|
||||
if (mreq)
|
||||
mm7_soap_destroy(mreq);
|
||||
|
||||
if (to)
|
||||
list_destroy(to, (list_item_destructor_t *)octstr_destroy);
|
||||
|
||||
octstr_destroy(h->ip);
|
||||
octstr_destroy(h->url);
|
||||
|
||||
if (h->base_client_addr)
|
||||
octstr_destroy(h->base_client_addr);
|
||||
if (h->client_addr)
|
||||
octstr_destroy(h->client_addr);
|
||||
|
||||
if (h->ua) octstr_destroy(h->ua);
|
||||
if (h->body) octstr_destroy(h->body);
|
||||
http_destroy_cgiargs(h->cgivars);
|
||||
http_destroy_headers(h->headers);
|
||||
|
||||
gw_free(h);
|
||||
|
||||
|
||||
}
|
||||
static void mm7proxy(void *unused)
|
||||
{
|
||||
MmsHTTPClientInfo h;
|
||||
while(rstop == 0 &&
|
||||
(h.client = http_accept_request(settings->mm7port,
|
||||
&h.ip, &h.url, &h.headers,
|
||||
&h.body, &h.cgivars)) != NULL)
|
||||
if (is_allowed_ip(settings->deny_ip, settings->allow_ip, h.ip)) {
|
||||
MmsHTTPClientInfo *hx = gw_malloc(sizeof *hx);
|
||||
|
||||
memset(hx, 0, sizeof *hx);
|
||||
|
||||
/* Get the MM7 sender address. */
|
||||
|
||||
h.vasp = find_mm7sender(h.headers, settings->vasp_list);
|
||||
h.ua = http_header_value(h.headers, octstr_imm("User-Agent"));
|
||||
debug("mmsproxy", 0,
|
||||
" MM7 Request, ip=%s, vasp=%s ",
|
||||
h.ip ? octstr_get_cstr(h.ip) : "",
|
||||
h.vasp && h.vasp->id ? octstr_get_cstr(h.vasp->id) : "(null)");
|
||||
|
||||
/* Dump headers, url etc. */
|
||||
#if 1
|
||||
http_header_dump(h.headers);
|
||||
if (h.body) octstr_dump(h.body, 0);
|
||||
if (h.ip) octstr_dump(h.ip, 0);
|
||||
#endif
|
||||
*hx = h; /* Copy it all over. */
|
||||
gwthread_create((gwthread_func_t *)mm7dispatch, hx);
|
||||
|
||||
} else {
|
||||
octstr_destroy(h.ip);
|
||||
octstr_destroy(h.url);
|
||||
|
||||
if (h.body)
|
||||
octstr_destroy(h.body);
|
||||
if (h.headers)
|
||||
http_destroy_headers(h.headers);
|
||||
if (h.cgivars)
|
||||
http_destroy_headers(h.cgivars);
|
||||
|
||||
http_close_client(h.client);
|
||||
}
|
||||
|
||||
debug("proxy", 0, "MM7 Shutting down...");
|
||||
}
|
||||
|
|
|
@ -159,9 +159,12 @@ int main(int argc, char *argv[])
|
|||
if (!m)
|
||||
panic(0, "No Message supplied, or failed to decode binary data!");
|
||||
|
||||
s = mms_queue_add(from, to, NULL, NULL, NULL, NULL, time(NULL),
|
||||
s = mms_queue_add(from, to, NULL, NULL, NULL, time(NULL),
|
||||
time(NULL) + settings->default_msgexpiry, m,
|
||||
NULL, 0, octstr_get_cstr(settings->global_queuedir));
|
||||
NULL, 0,
|
||||
NULL, NULL,
|
||||
octstr_get_cstr(settings->global_queuedir),
|
||||
settings->host_alias);
|
||||
|
||||
if (savetommbox)
|
||||
mmbox = mms_mmbox_addmsg(octstr_get_cstr(settings->mmbox_rootdir),
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
- correct handling of sender-visibility flag when receiving message (and also use correct address for billing. no spoofing).
|
||||
- Sending DLR correctly when sending from/to email.
|
||||
- In content adaptation: Colour depth adjustment
|
||||
- Need to parameterise some values: tmp dir, response messages (say on failed content adaptation)
|
||||
- Tests
|
||||
- Test suite
|
||||
- Correct handling of unrecognised mms headers. spec says pass them un-changed.
|
||||
|
||||
- Queue module needs to be de-coupled slightly from storage, so that mmsproxy can run on a separate box
|
||||
but be able to initiate queue writes/reads over network. Hence pieces can run on separate boxes
|
||||
(with mmsrelay providing network service for queue functions)
|
||||
|
|
Loading…
Reference in New Issue