EAIF implementation, first stab.
This commit is contained in:
parent
224866fbff
commit
2b2999a31e
|
@ -97,8 +97,9 @@ commonly called a MMS Centre).</p>
|
||||||
|
|
||||||
<p>Mbuni aims to
|
<p>Mbuni aims to
|
||||||
support all the major MMS interfaces, including phone-to-phone (so-called MM1
|
support all the major MMS interfaces, including phone-to-phone (so-called MM1
|
||||||
interface), phone-to-email (MM3), inter-MMSC (MM4) and MMS VAS (MM7). The
|
interface), phone-to-email (MM3), inter-MMSC (MM4) and MMS VAS
|
||||||
initial release fully supports the MM1 and MM3 interfaces, and provides
|
(MM7). The
|
||||||
|
current release fully supports the MM1, MM3 and MM7 interfaces, and provides
|
||||||
rudimentary support for the MM4 interface. This version also supports
|
rudimentary support for the MM4 interface. This version also supports
|
||||||
network-side MMBox storage and transactions as specified in the OMA
|
network-side MMBox storage and transactions as specified in the OMA
|
||||||
MMS v1.2 specification. </p>
|
MMS v1.2 specification. </p>
|
||||||
|
@ -229,8 +230,11 @@ content depending on the capabilities of the receiving terminal
|
||||||
<li> Support for persistent storage of messages for subscribers (MMbox).
|
<li> Support for persistent storage of messages for subscribers (MMbox).
|
||||||
|
|
||||||
<li> Inter-MMSC message exchange (MM4 interface)
|
<li> Inter-MMSC message exchange (MM4 interface)
|
||||||
|
<li> Support for MMS Value Added Service Providers using MM7
|
||||||
<li> Support for integration with subscriber database to enable smart handling of handsets that do not support MMS, handsets not provisioned, etc.
|
protocols (SOAP or EAIF).
|
||||||
|
<li> Support for integration with subscriber database to enable
|
||||||
|
smart handling of handsets that do not support MMS, handsets not
|
||||||
|
provisioned, etc.
|
||||||
|
|
||||||
<li> Support for flexible billing structure through billing/CDR plug-in architecture
|
<li> Support for flexible billing structure through billing/CDR plug-in architecture
|
||||||
|
|
||||||
|
@ -240,9 +244,7 @@ content depending on the capabilities of the receiving terminal
|
||||||
|
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
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
|
The Gateway is designed and tested to conform to Open Mobile Alliance
|
||||||
(OMA), WAP and 3rd Generation Partnership Project (3GPP) MMS standards
|
(OMA), WAP and 3rd Generation Partnership Project (3GPP) MMS standards
|
||||||
including:
|
including:
|
||||||
|
@ -1345,7 +1347,7 @@ mmsc-password
|
||||||
String
|
String
|
||||||
</td>
|
</td>
|
||||||
<td valign=top >
|
<td valign=top >
|
||||||
This should be one of: soap, eaif (<i>note: only soap is supported currently</i>)
|
This should be one of: soap, eaif
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -1428,7 +1430,7 @@ mmsc-password
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
|
||||||
Note that currently only HTTP Basic authentication scheme is supported
|
Note that currently only HTTP Basic Authentication Scheme is supported
|
||||||
by Mbuni (for both incoming and out-going requests).
|
by Mbuni (for both incoming and out-going requests).
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,8 @@
|
||||||
#define XIP_HEADER "X-WAP-Network-Client-IP"
|
#define XIP_HEADER "X-WAP-Network-Client-IP"
|
||||||
#define MM_NAME "Mbuni"
|
#define MM_NAME "Mbuni"
|
||||||
|
|
||||||
|
#define EAIF_VERSION "3.0"
|
||||||
|
|
||||||
typedef struct MmsProxyRelay {
|
typedef struct MmsProxyRelay {
|
||||||
Octstr *host;
|
Octstr *host;
|
||||||
Octstr *name;
|
Octstr *name;
|
||||||
|
|
|
@ -70,7 +70,8 @@ static int sendMsg(MmsEnvelope *e)
|
||||||
MmsMsg *msg = NULL;
|
MmsMsg *msg = NULL;
|
||||||
|
|
||||||
|
|
||||||
if (!e->bill.billed) { /* Attempt to bill. */
|
if (e->msgtype == MMS_MSGTYPE_SEND_REQ &&
|
||||||
|
!e->bill.billed) { /* Attempt to bill if not already billed */
|
||||||
List *l = list_create();
|
List *l = list_create();
|
||||||
double amt;
|
double amt;
|
||||||
|
|
||||||
|
@ -460,107 +461,190 @@ static int _x_octstr_int_compare(int n, Octstr *s)
|
||||||
return octstr_str_compare(s,x);
|
return octstr_str_compare(s,x);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mms_sendtovasp(MmsVasp *vasp, Octstr *from, Octstr *to, Octstr *msgId,
|
static int mm7soap_send(MmsVasp *vasp, Octstr *from, Octstr *to, Octstr *msgId,
|
||||||
MmsMsg *m, Octstr **error)
|
MmsMsg *m, Octstr **error)
|
||||||
{
|
{
|
||||||
int ret = MMS_SEND_ERROR_TRANSIENT;
|
int ret = MMS_SEND_ERROR_TRANSIENT;
|
||||||
int mtype = mms_messagetype(m);
|
int mtype = mms_messagetype(m);
|
||||||
|
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;
|
||||||
|
|
||||||
info(0, "MMS Relay: Send to VASP[%s], msg type [%s], from %s, to %s",
|
info(0, "MMS Relay: Send[soap] to VASP[%s], msg type [%s], from %s, to %s",
|
||||||
vasp ? octstr_get_cstr(vasp->id) : "",
|
vasp ? octstr_get_cstr(vasp->id) : "",
|
||||||
mms_message_type_to_cstr(mtype), octstr_get_cstr(from), octstr_get_cstr(to));
|
mms_message_type_to_cstr(mtype), octstr_get_cstr(from), octstr_get_cstr(to));
|
||||||
|
|
||||||
if (vasp->type == SOAP_VASP) {
|
list_append(xto, to);
|
||||||
int hstatus = HTTP_OK, tstatus;
|
|
||||||
List *xto = list_create();
|
|
||||||
MSoapMsg_t *mreq = NULL, *mresp = NULL;
|
if ((mreq = mm7_mmsmsg_to_soap(m, from, xto, msgId, settings->host_alias)) == NULL) {
|
||||||
List *rh = NULL, *ph = NULL;
|
*error = octstr_format("Failed to convert Msg[%s] 2 SOAP message!",
|
||||||
Octstr *body = NULL, *rbody = NULL, *url = NULL;
|
mms_message_type_to_cstr(mtype));
|
||||||
HTTPCaller *caller = http_caller_create();
|
goto done1;
|
||||||
void *xx;
|
}
|
||||||
Octstr *s;
|
|
||||||
|
if (mm7_soapmsg_to_httpmsg(mreq, &rh, &body) < 0) {
|
||||||
list_append(xto, to);
|
*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)
|
||||||
if ((mreq = mm7_mmsmsg_to_soap(m, from, xto, msgId, settings->host_alias)) == NULL) {
|
octstr_destroy(detail);
|
||||||
*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)
|
} else
|
||||||
http_add_basic_auth(rh, vasp->mmsc_username,
|
ret = MMS_SEND_OK;
|
||||||
vasp->mmsc_password ? vasp->mmsc_password : octstr_imm(""));
|
|
||||||
|
info(0, "Sent to VASP[%s], code=[%d=>%s]", octstr_get_cstr(vasp->id),
|
||||||
http_start_request(caller, HTTP_METHOD_POST, vasp->vasp_url, rh, body, 1, NULL, NULL);
|
tstatus, mms_soap_status_to_cstr(tstatus));
|
||||||
|
done1:
|
||||||
if ((xx = http_receive_result(caller, &hstatus, &url, &ph, &rbody)) == NULL ||
|
|
||||||
hstatus != HTTP_OK) {
|
if (mreq)
|
||||||
*error = octstr_format("Failed to contact VASP[url=%s] => HTTP returned status = %d, id=%s !",
|
mm7_soap_destroy(mreq);
|
||||||
octstr_get_cstr(vasp->vasp_url), hstatus, xx ? "Ok" : "not OK");
|
if (mresp)
|
||||||
goto done1;
|
mm7_soap_destroy(mresp);
|
||||||
}
|
if (rh)
|
||||||
|
http_destroy_headers(rh);
|
||||||
if ((mresp = mm7_parse_soap(ph, rbody)) == NULL) {
|
if (body)
|
||||||
*error = octstr_format("Failed to parse VASP[url=%s, id=%s] response!",
|
octstr_destroy(body);
|
||||||
octstr_get_cstr(vasp->vasp_url),
|
if (ph)
|
||||||
octstr_get_cstr(vasp->id));
|
http_destroy_headers(ph);
|
||||||
goto done1;
|
if (rbody)
|
||||||
}
|
octstr_destroy(rbody);
|
||||||
|
if (url)
|
||||||
/* Now look at response code and use it to tell you what you want. */
|
octstr_destroy(url);
|
||||||
if ((s = mm7_soap_header_value(mresp, octstr_imm("StatusCode"))) != NULL) {
|
http_caller_destroy(caller);
|
||||||
tstatus = atoi(octstr_get_cstr(s));
|
list_destroy(xto, NULL);
|
||||||
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;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int mm7eaif_send(MmsVasp *vasp, Octstr *from, Octstr *to, Octstr *msgid,
|
||||||
|
MmsMsg *m, Octstr **error)
|
||||||
|
{
|
||||||
|
int ret = MMS_SEND_ERROR_TRANSIENT;
|
||||||
|
int mtype = mms_messagetype(m);
|
||||||
|
int hstatus = HTTP_OK;
|
||||||
|
List *rh = http_create_empty_headers(), *ph = NULL;
|
||||||
|
Octstr *body = NULL, *rbody = NULL, *url = NULL;
|
||||||
|
HTTPCaller *caller = http_caller_create();
|
||||||
|
void *xx;
|
||||||
|
char *msgtype;
|
||||||
|
|
||||||
|
|
||||||
|
info(0, "MMS Relay: Send [eaif] 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));
|
||||||
|
|
||||||
|
http_header_add(rh, "X-NOKIA-MMSC-To", octstr_get_cstr(to));
|
||||||
|
http_header_add(rh, "X-NOKIA-MMSC-From", octstr_get_cstr(from));
|
||||||
|
if (msgid)
|
||||||
|
http_header_add(rh, "X-NOKIA-MMSC-Message-Id", octstr_get_cstr(from));
|
||||||
|
http_header_add(rh, "X-NOKIA-MMSC-Version", EAIF_VERSION);
|
||||||
|
|
||||||
|
if (mtype == MMS_MSGTYPE_SEND_REQ)
|
||||||
|
msgtype = "MultiMediaMessage";
|
||||||
|
else if (mtype == MMS_MSGTYPE_DELIVERY_IND)
|
||||||
|
msgtype = "DeliveryReport";
|
||||||
|
else
|
||||||
|
msgtype = "ReadReply";
|
||||||
|
http_header_add(rh, "X-NOKIA-MMSC-Message-Type", msgtype);
|
||||||
|
http_header_add(rh, "Content-Type", "application/vnd.wap.mms-message");
|
||||||
|
|
||||||
|
if (vasp->mmsc_username)
|
||||||
|
http_add_basic_auth(rh, vasp->mmsc_username,
|
||||||
|
vasp->mmsc_password ? vasp->mmsc_password : octstr_imm(""));
|
||||||
|
|
||||||
|
body = mms_tobinary(m);
|
||||||
|
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 ||
|
||||||
|
http_status_class(hstatus) != HTTP_STATUS_SUCCESSFUL) {
|
||||||
|
*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");
|
||||||
|
} else
|
||||||
|
info(0, "Sent to VASP[%s], code=[%d]", octstr_get_cstr(vasp->id), hstatus);
|
||||||
|
|
||||||
|
if (hstatus < 0)
|
||||||
|
ret = MMS_SEND_ERROR_TRANSIENT;
|
||||||
|
else {
|
||||||
|
hstatus = http_status_class(hstatus);
|
||||||
|
if (hstatus == HTTP_STATUS_CLIENT_ERROR)
|
||||||
|
ret = MMS_SEND_ERROR_TRANSIENT;
|
||||||
|
else if (hstatus == HTTP_STATUS_SERVER_ERROR)
|
||||||
|
ret = MMS_SEND_ERROR_FATAL;
|
||||||
|
else
|
||||||
|
ret = MMS_SEND_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mms_sendtovasp(MmsVasp *vasp, Octstr *from, Octstr *to, Octstr *msgid,
|
||||||
|
MmsMsg *m, Octstr **err)
|
||||||
|
{
|
||||||
|
if (vasp->type == SOAP_VASP)
|
||||||
|
return mm7soap_send(vasp, from, to, msgid, m, err);
|
||||||
|
else if (vasp->type == EAIF_VASP)
|
||||||
|
return mm7eaif_send(vasp, from, to, msgid, m, err);
|
||||||
|
else {
|
||||||
|
error(0, "Vasp[%s] of unknown type, can't send!",
|
||||||
|
vasp->id ? octstr_get_cstr(vasp->id) : "");
|
||||||
|
return MMS_SEND_ERROR_FATAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#include "mms_util.h"
|
#include "mms_util.h"
|
||||||
#include "mms_mm7soap.h"
|
#include "mms_mm7soap.h"
|
||||||
|
|
||||||
|
|
||||||
static Cfg *cfg;
|
static Cfg *cfg;
|
||||||
static List *proxyrelays;
|
static List *proxyrelays;
|
||||||
static MmsBoxSettings *settings;
|
static MmsBoxSettings *settings;
|
||||||
|
@ -48,6 +49,7 @@ typedef struct MmsHTTPClientInfo {
|
||||||
MmsVasp *vasp;
|
MmsVasp *vasp;
|
||||||
} MmsHTTPClientInfo;
|
} MmsHTTPClientInfo;
|
||||||
|
|
||||||
|
static void free_clientInfo(MmsHTTPClientInfo *h, int freeh);
|
||||||
static void fetchmms_proxy(MmsHTTPClientInfo *h);
|
static void fetchmms_proxy(MmsHTTPClientInfo *h);
|
||||||
static void sendmms_proxy(MmsHTTPClientInfo *h);
|
static void sendmms_proxy(MmsHTTPClientInfo *h);
|
||||||
|
|
||||||
|
@ -82,7 +84,7 @@ int main(int argc, char *argv[])
|
||||||
octstr_destroy(fname);
|
octstr_destroy(fname);
|
||||||
|
|
||||||
info(0, "----------------------------------------");
|
info(0, "----------------------------------------");
|
||||||
info(0, " MMSC Proxy Relay server version %s starting", MMSC_VERSION);
|
info(0, " " MM_NAME " MMSC Proxy version %s starting", MMSC_VERSION);
|
||||||
|
|
||||||
grp = cfg_get_single_group(cfg, octstr_imm("core"));
|
grp = cfg_get_single_group(cfg, octstr_imm("core"));
|
||||||
log = cfg_get(grp, octstr_imm("log-file"));
|
log = cfg_get(grp, octstr_imm("log-file"));
|
||||||
|
@ -407,20 +409,7 @@ void fetchmms_proxy(MmsHTTPClientInfo *h)
|
||||||
if (token) octstr_destroy(token);
|
if (token) octstr_destroy(token);
|
||||||
if (transid) octstr_destroy(transid);
|
if (transid) octstr_destroy(transid);
|
||||||
|
|
||||||
octstr_destroy(h->ip);
|
free_clientInfo(h,1);
|
||||||
octstr_destroy(h->url);
|
|
||||||
if (h->ua) octstr_destroy(h->ua);
|
|
||||||
if (h->body) octstr_destroy(h->body);
|
|
||||||
|
|
||||||
if (h->base_client_addr)
|
|
||||||
octstr_destroy(h->base_client_addr);
|
|
||||||
octstr_destroy(h->client_addr);
|
|
||||||
|
|
||||||
http_destroy_cgiargs(h->cgivars);
|
|
||||||
http_destroy_headers(h->headers);
|
|
||||||
|
|
||||||
gw_free(h);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Make list of recipients and also sender. */
|
/* Make list of recipients and also sender. */
|
||||||
|
@ -1565,21 +1554,7 @@ static void sendmms_proxy(MmsHTTPClientInfo *h)
|
||||||
if (reply_body)
|
if (reply_body)
|
||||||
octstr_destroy(reply_body);
|
octstr_destroy(reply_body);
|
||||||
|
|
||||||
octstr_destroy(h->ip);
|
free_clientInfo(h,1);
|
||||||
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);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Find sender credentials: only auth-basic supported for now. */
|
/* Find sender credentials: only auth-basic supported for now. */
|
||||||
|
@ -1626,7 +1601,7 @@ static MmsVasp *find_mm7sender(List *headers, List *vasps)
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mm7dispatch(MmsHTTPClientInfo *h)
|
static void mm7soap_dispatch(MmsHTTPClientInfo *h)
|
||||||
{
|
{
|
||||||
/* if no vasp, return 4001 error. */
|
/* if no vasp, return 4001 error. */
|
||||||
MSoapMsg_t *mreq = NULL, *mresp = NULL;
|
MSoapMsg_t *mreq = NULL, *mresp = NULL;
|
||||||
|
@ -1653,14 +1628,7 @@ static void mm7dispatch(MmsHTTPClientInfo *h)
|
||||||
mreq ? msgtype : "Null");
|
mreq ? msgtype : "Null");
|
||||||
|
|
||||||
|
|
||||||
if (!h->vasp) {
|
if (!mreq) {
|
||||||
/* 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);
|
mresp = mm7_make_resp(NULL, 2007, NULL);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
@ -1805,7 +1773,6 @@ static void mm7dispatch(MmsHTTPClientInfo *h)
|
||||||
else
|
else
|
||||||
http_close_client(h->client);
|
http_close_client(h->client);
|
||||||
|
|
||||||
done2:
|
|
||||||
if (e)
|
if (e)
|
||||||
mms_queue_free_env(e);
|
mms_queue_free_env(e);
|
||||||
|
|
||||||
|
@ -1839,23 +1806,132 @@ static void mm7dispatch(MmsHTTPClientInfo *h)
|
||||||
if (to)
|
if (to)
|
||||||
list_destroy(to, (list_item_destructor_t *)octstr_destroy);
|
list_destroy(to, (list_item_destructor_t *)octstr_destroy);
|
||||||
|
|
||||||
octstr_destroy(h->ip);
|
free_clientInfo(h,1);
|
||||||
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 mm7eaif_dispatch(MmsHTTPClientInfo *h)
|
||||||
|
{
|
||||||
|
/* if no vasp, return 4001 error. */
|
||||||
|
MmsMsg *m = NULL;
|
||||||
|
List *mh = NULL;
|
||||||
|
int hstatus = HTTP_NO_CONTENT;
|
||||||
|
List *rh = http_create_empty_headers();
|
||||||
|
Octstr *reply_body = NULL, *value;
|
||||||
|
|
||||||
|
List *to = list_create(), *hto = NULL;
|
||||||
|
Octstr *subject = NULL, *otransid = NULL, *msgid = NULL;
|
||||||
|
Octstr *hfrom = NULL;
|
||||||
|
time_t expiryt = -1, deliveryt = -1;
|
||||||
|
Octstr *qf = NULL;
|
||||||
|
int msize = h->body ? octstr_len(h->body) : 0;
|
||||||
|
int dlr;
|
||||||
|
|
||||||
|
debug("mm7eaif.sendinterface", 0,
|
||||||
|
" --> Enterred eaif send interface, blen=%d <--- ",
|
||||||
|
msize);
|
||||||
|
|
||||||
|
hfrom = http_header_value(h->headers, octstr_imm("X-NOKIA-MMSC-From"));
|
||||||
|
|
||||||
|
if (!h->body || /* A body is required, and must parse */
|
||||||
|
(m = mms_frombinary(h->body, hfrom ? hfrom : octstr_imm("anon@anon"))) == NULL) {
|
||||||
|
http_header_add(rh, "Content-Type", "text/plain");
|
||||||
|
hstatus = HTTP_BAD_REQUEST;
|
||||||
|
reply_body = octstr_format("Unexpected MMS message, no body?");
|
||||||
|
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
mh = mms_message_headers(m);
|
||||||
|
/* Now get sender and receiver data.
|
||||||
|
* for now we ignore adaptation flags.
|
||||||
|
*/
|
||||||
|
collect_senddata(mh, &to, &subject, &otransid, &expiryt, &deliveryt);
|
||||||
|
|
||||||
|
if ((hto = http_header_find_all(h->headers, "X-NOKIA-MMSC-To")) != NULL &&
|
||||||
|
list_len(hto) > 0) { /* To address is in headers. */
|
||||||
|
int i, n;
|
||||||
|
|
||||||
|
if (to)
|
||||||
|
list_destroy(to, (list_item_destructor_t *)octstr_destroy);
|
||||||
|
to = list_create();
|
||||||
|
for (i = 0, n = list_len(hto); i < n; i++) {
|
||||||
|
Octstr *h = NULL, *v = NULL;
|
||||||
|
List *l;
|
||||||
|
int j, m;
|
||||||
|
|
||||||
|
http_header_get(hto,i, &h, &v);
|
||||||
|
l = http_header_split_value(v);
|
||||||
|
|
||||||
|
for (j = 0, m = list_len(l); j < m; j++)
|
||||||
|
list_append(to, list_get(l, j));
|
||||||
|
|
||||||
|
list_destroy(l, NULL);
|
||||||
|
if (h) octstr_destroy(h);
|
||||||
|
if (v) octstr_destroy(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
value = http_header_value(mh, octstr_imm("X-Mms-Delivery-Report"));
|
||||||
|
if (value &&
|
||||||
|
octstr_case_compare(value, octstr_imm("Yes")) == 0)
|
||||||
|
dlr = 1;
|
||||||
|
else
|
||||||
|
dlr = 0;
|
||||||
|
if (value)
|
||||||
|
octstr_destroy(value);
|
||||||
|
|
||||||
|
if (deliveryt < 0)
|
||||||
|
deliveryt = time(NULL);
|
||||||
|
|
||||||
|
if (expiryt < 0)
|
||||||
|
expiryt = time(NULL) + settings->default_msgexpiry;
|
||||||
|
|
||||||
|
/* Save it, make msgid, put message id in header, return. */
|
||||||
|
qf = mms_queue_add(hfrom, to, subject,
|
||||||
|
NULL, NULL, deliveryt, expiryt, m, NULL,
|
||||||
|
NULL, NULL,
|
||||||
|
dlr,
|
||||||
|
octstr_get_cstr(settings->global_queuedir),
|
||||||
|
settings->host_alias);
|
||||||
|
|
||||||
|
if (qf) {
|
||||||
|
msgid = mms_maketransid(octstr_get_cstr(qf),
|
||||||
|
settings->host_alias);
|
||||||
|
|
||||||
|
/* Log to access log */
|
||||||
|
mms_log("Received", hfrom, to, msize, msgid, h->vasp->id, NULL, "MM7", h->ua, NULL);
|
||||||
|
|
||||||
|
octstr_destroy(qf);
|
||||||
|
hstatus = HTTP_NO_CONTENT;
|
||||||
|
} else
|
||||||
|
hstatus = HTTP_INTERNAL_SERVER_ERROR;
|
||||||
|
|
||||||
|
done:
|
||||||
|
http_header_add(rh, "X-NOKIA-MMSC-Version", EAIF_VERSION);
|
||||||
|
if (msgid)
|
||||||
|
http_header_add(rh, "X-NOKIA-MMSC-Message-Id", octstr_get_cstr(msgid));
|
||||||
|
|
||||||
|
http_send_reply(h->client, hstatus, rh, octstr_imm(""));
|
||||||
|
|
||||||
|
if (hto)
|
||||||
|
http_destroy_headers(hto);
|
||||||
|
if (to)
|
||||||
|
list_destroy(to, (list_item_destructor_t *)octstr_destroy);
|
||||||
|
if (hfrom)
|
||||||
|
octstr_destroy(hfrom);
|
||||||
|
if (subject)
|
||||||
|
octstr_destroy(subject);
|
||||||
|
if (otransid)
|
||||||
|
octstr_destroy(otransid);
|
||||||
|
if (msgid)
|
||||||
|
octstr_destroy(msgid);
|
||||||
|
if (mh)
|
||||||
|
http_destroy_headers(mh);
|
||||||
|
|
||||||
|
if (m) mms_destroy(m);
|
||||||
|
}
|
||||||
|
|
||||||
static void mm7proxy(void *unused)
|
static void mm7proxy(void *unused)
|
||||||
{
|
{
|
||||||
MmsHTTPClientInfo h;
|
MmsHTTPClientInfo h;
|
||||||
|
@ -1875,7 +1951,7 @@ static void mm7proxy(void *unused)
|
||||||
debug("mmsproxy", 0,
|
debug("mmsproxy", 0,
|
||||||
" MM7 Request, ip=%s, vasp=%s ",
|
" MM7 Request, ip=%s, vasp=%s ",
|
||||||
h.ip ? octstr_get_cstr(h.ip) : "",
|
h.ip ? octstr_get_cstr(h.ip) : "",
|
||||||
h.vasp && h.vasp->id ? octstr_get_cstr(h.vasp->id) : "(null)");
|
h.vasp && h.vasp->id ? octstr_get_cstr(h.vasp->id) : "(null)");
|
||||||
|
|
||||||
/* Dump headers, url etc. */
|
/* Dump headers, url etc. */
|
||||||
#if 1
|
#if 1
|
||||||
|
@ -1884,21 +1960,42 @@ static void mm7proxy(void *unused)
|
||||||
if (h.ip) octstr_dump(h.ip, 0);
|
if (h.ip) octstr_dump(h.ip, 0);
|
||||||
#endif
|
#endif
|
||||||
*hx = h; /* Copy it all over. */
|
*hx = h; /* Copy it all over. */
|
||||||
gwthread_create((gwthread_func_t *)mm7dispatch, hx);
|
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(hx->client, HTTP_UNAUTHORIZED, hh,
|
||||||
|
octstr_imm(""));
|
||||||
|
http_destroy_headers(hh);
|
||||||
|
free_clientInfo(hx, 1);
|
||||||
|
} else if (h.vasp->type == SOAP_VASP)
|
||||||
|
gwthread_create((gwthread_func_t *)mm7soap_dispatch, hx);
|
||||||
|
else
|
||||||
|
gwthread_create((gwthread_func_t *)mm7eaif_dispatch, hx);
|
||||||
} else {
|
} else {
|
||||||
octstr_destroy(h.ip);
|
free_clientInfo(&h, 0);
|
||||||
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);
|
http_close_client(h.client);
|
||||||
}
|
}
|
||||||
|
|
||||||
debug("proxy", 0, "MM7 Shutting down...");
|
debug("proxy", 0, "MM7 Shutting down...");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void free_clientInfo(MmsHTTPClientInfo *h, int freeh)
|
||||||
|
{
|
||||||
|
if (h->ip)
|
||||||
|
octstr_destroy(h->ip);
|
||||||
|
if (h->url)
|
||||||
|
octstr_destroy(h->url);
|
||||||
|
if (h->ua) octstr_destroy(h->ua);
|
||||||
|
if (h->body) octstr_destroy(h->body);
|
||||||
|
|
||||||
|
if (h->base_client_addr)
|
||||||
|
octstr_destroy(h->base_client_addr);
|
||||||
|
octstr_destroy(h->client_addr);
|
||||||
|
|
||||||
|
http_destroy_cgiargs(h->cgivars);
|
||||||
|
http_destroy_headers(h->headers);
|
||||||
|
|
||||||
|
if (freeh)
|
||||||
|
gw_free(h);
|
||||||
|
}
|
||||||
|
|
|
@ -53,7 +53,7 @@ int main(int argc, char *argv[])
|
||||||
octstr_destroy(fname);
|
octstr_destroy(fname);
|
||||||
|
|
||||||
info(0, "----------------------------------------");
|
info(0, "----------------------------------------");
|
||||||
info(0, " MMSC Relay version %s starting", MMSC_VERSION);
|
info(0, " " MM_NAME " MMSC Relay version %s starting", MMSC_VERSION);
|
||||||
|
|
||||||
grp = cfg_get_single_group(cfg, octstr_imm("core"));
|
grp = cfg_get_single_group(cfg, octstr_imm("core"));
|
||||||
log = cfg_get(grp, octstr_imm("log-file"));
|
log = cfg_get(grp, octstr_imm("log-file"));
|
||||||
|
|
Loading…
Reference in New Issue