From 96811a10b7ce79be7525ae7ba06773f7587639ab Mon Sep 17 00:00:00 2001 From: bagyenda <> Date: Mon, 6 Aug 2007 11:57:15 +0000 Subject: [PATCH] misc. fixes: DLR, UAProf on mmsbox side --- mbuni/ChangeLog | 3 + mbuni/doc/userguide.shtml | 72 ++++++++++++++++- mbuni/mmlib/mms_cfg.def | 3 +- mbuni/mmlib/mms_mm7soap.c | 111 ++++++++++++++++++++------- mbuni/mmlib/mms_mm7soap.h | 9 ++- mbuni/mmlib/mms_queue.c | 3 +- mbuni/mmlib/mms_queue.h | 3 +- mbuni/mmlib/mms_strings.def | 2 + mbuni/mmlib/mms_uaprof.c | 2 +- mbuni/mmsbox/bearerbox.c | 140 +++++++++++++++++++++------------ mbuni/mmsbox/dlr.c | 24 ++++-- mbuni/mmsbox/mmsbox.c | 83 ++++++++++++++------ mbuni/mmsbox/mmsbox.h | 4 +- mbuni/mmsc/mmsc_cfg.c | 13 ++++ mbuni/mmsc/mmsc_cfg.h | 1 + mbuni/mmsc/mmsglobalsender.c | 50 +++++++----- mbuni/mmsc/mmsproxy.c | 145 ++++++++++++++--------------------- 17 files changed, 447 insertions(+), 221 deletions(-) diff --git a/mbuni/ChangeLog b/mbuni/ChangeLog index 4916ab5..b9bf584 100644 --- a/mbuni/ChangeLog +++ b/mbuni/ChangeLog @@ -1,3 +1,6 @@ +2007-08-06 P. A. Bagyenda + * Fix for DLR reporting in mmsbox (thanks to Skycore team) + * UACapabilities support for MM7/SOAP v6.x (thanks again to Skycore Team) 2007-08-03 P. A. Bagyenda * added mms-direction CGI param to send-mms interface (see doc for additional info) 2007-07-27 P. A. Bagyenda diff --git a/mbuni/doc/userguide.shtml b/mbuni/doc/userguide.shtml index 690224b..8b179b4 100644 --- a/mbuni/doc/userguide.shtml +++ b/mbuni/doc/userguide.shtml @@ -1828,6 +1828,26 @@ Boolean + + + send-uaprof + + + String + + + Optional. This parameter determines whether the User Agent string is + sent to the VASP (for MM7/SOAP only, as part of + UACapabilities entity). Set to ua to send the + full client User Agent string (i.e. the value of the HTTP request + header User-Agent). Set to url to send the client + Profile URL (i.e. the value of the X-WAP-Profile HTTP + request header). Leave empty not to send any info. Note that this + field is only sent in MO transactions (e.g. message delivery, + delivery reports). + + + @@ -2600,6 +2620,16 @@ faked-sender = 100
+ + + distribution + + + Optional. Should be true or false. This is set as the + MM7/SOAP DistributionIndicator parameter. + + +

@@ -3176,6 +3206,44 @@ A detailed list of configuration parameters for MMS Services is given below. MMS message priority + + + + X-Mbuni-TransactionID + + + This special header is used for transaction tracking. It is included + in the MMS service request and uniquely identifies the service + request transaction. The transaction ID will be included in the delivery or + read report when the DLR URL is called, so that the service side can + match the DLR to the service request transaction. + + + + + + X-Mbuni-UAProf + + + This special header is included in the service request (and DLR URL + request) and contains the client User-Agent Profile string as + received from the MMC side. (Requires MM7/SOAP v6.x support on the + MMC side.) + + + + + + X-Mbuni-Timestamp + + + This special header is included in the service request (and DLR URL + request) and contains the client submission time stamp (HTTP + date format). This header is only included if the User-Agent Profile + string is included. (Requires MM7/SOAP v6.x support on the + MMC side.) + +

@@ -3590,7 +3658,9 @@ maximum, and the queue entry ID is printed to standard output. queue. If the sender requested a read or delivery report (by specifying the requisite URL), the relevant URL is - stored to the DLR URL store for future use. + stored to the DLR URL store for future use. On success, the + interface returns the message submission transaction ID (which is + also reported with an DLR).
  • MMSC handler module: Receives messages coming from MMSCs, and saves them to the incoming queue. Also watches the outgoing message queue for new messages, which it dispatches to the relevant diff --git a/mbuni/mmlib/mms_cfg.def b/mbuni/mmlib/mms_cfg.def index 1c9065b..3d3be0a 100644 --- a/mbuni/mmlib/mms_cfg.def +++ b/mbuni/mmlib/mms_cfg.def @@ -107,7 +107,8 @@ MULTI_GROUP(mms-vasp, OCTSTR(vasp-password) OCTSTR(vasp-url) OCTSTR(mms-to-email-handler) - OCTSTR(mms-to-local-copy-handler) + OCTSTR(mms-to-local-copy-handler) + OCTSTR(send-uaprof) ) MULTI_GROUP(send-mms-user, diff --git a/mbuni/mmlib/mms_mm7soap.c b/mbuni/mmlib/mms_mm7soap.c index ce780a3..7270db2 100644 --- a/mbuni/mmlib/mms_mm7soap.c +++ b/mbuni/mmlib/mms_mm7soap.c @@ -3,7 +3,7 @@ * * MM7/SOAP message encoder/decoder and helper functions * - * Copyright (C) 2003 - 2005, Digital Solutions Ltd. - http://www.dsmagic.com + * Copyright (C) 2003 - 2007, Digital Solutions Ltd. - http://www.dsmagic.com * * Paul Bagyenda * @@ -26,7 +26,7 @@ struct MSoapMsg_t { /* We expect ISO formatted time, or interval. */ -static Octstr *parse_time(char *s) +static time_t parse_time(char *s) { time_t t = time(NULL); Octstr *p = octstr_create(s); @@ -83,7 +83,7 @@ static Octstr *parse_time(char *s) done: octstr_destroy(p); - return date_format_http(t); + return t; } static int parse_header(xmlNodePtr node, List *headers, int *sigparent) @@ -137,7 +137,6 @@ static int parse_header(xmlNodePtr node, List *headers, int *sigparent) case MM7_TAG_Recipient: *sigparent = MM7_TAG_To; /* make it a To field. */ - break; case MM7_TAG_To: case MM7_TAG_Cc: @@ -159,11 +158,15 @@ static int parse_header(xmlNodePtr node, List *headers, int *sigparent) } break; case MM7_TAG_Content: - if ((s = xmlGetProp(node, (unsigned char *)"href")) != NULL) { - value = octstr_create((char *)s); + if ((s = xmlGetProp(node, (unsigned char *)"href")) != NULL) { + value = octstr_create((char *)s); + xmlFree(s); + } + + if ((s = xmlGetProp(node, (unsigned char *)"allowAdaptations")) != NULL) { + http_header_add(headers, "allowAdaptations", (char *)s); xmlFree(s); } - /* 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. */ @@ -188,7 +191,7 @@ static int parse_header(xmlNodePtr node, List *headers, int *sigparent) case MM7_TAG_ExpiryDate: case MM7_TAG_TimeStamp: case MM7_TAG_Date: - value = parse_time(nvalue); + value = date_format_http(parse_time(nvalue)); break; case MM7_TAG_ReplyCharging: @@ -199,12 +202,25 @@ static int parse_header(xmlNodePtr node, List *headers, int *sigparent) xmlFree(s); } if ((s = xmlGetProp(node, (unsigned char *)"replyDeadline")) != NULL) { - Octstr *t = parse_time((char *)s); + Octstr *t = date_format_http(parse_time((char *)s)); http_header_add(headers, "replyDeadline", octstr_get_cstr(t)); xmlFree(s); octstr_destroy(t); } break; + case MM7_TAG_UACapabilities: + if ((s = xmlGetProp(node, (unsigned char *)"UAProf")) != NULL) { + value = octstr_create((void *)s); + xmlFree(s); + } else + value = octstr_create("none"); + + if ((s = xmlGetProp(node, (unsigned char *)"TimeStamp")) != NULL) { + time_t lt = parse_time((char *)s); + octstr_format_append(value, ",%ld", lt); + xmlFree(s); + } + break; default: break; } @@ -487,9 +503,9 @@ static Octstr *headers_to_soapxml(List *hdrs, MM7Version_t *ver) } octstr_append_cstr(s, "\n"); - if (p) octstr_destroy(p); - if (q) octstr_destroy(q); - if (r) octstr_destroy(r); + octstr_destroy(p); + octstr_destroy(q); + octstr_destroy(r); } p = octstr_create(""); @@ -513,7 +529,7 @@ static Octstr *headers_to_soapxml(List *hdrs, MM7Version_t *ver) for (i = 0, n = gwlist_len(hdrs); i < n; i++) { Octstr *h = NULL, *v = NULL; - char *zz; + char *zz, *s1, *s2; int tag; int skip = 0; @@ -610,7 +626,19 @@ static Octstr *headers_to_soapxml(List *hdrs, MM7Version_t *ver) octstr_append_cstr(s, "\n"); skip = 1; break; - + case MM7_TAG_UACapabilities: + s1 = octstr_get_cstr(v); + if ((s2 = strrchr(s1, ',')) != NULL) { + t = strtoul(s2 + 1, NULL, 10); + octstr_delete(v, s2-s1, octstr_len(v)); + } else + t = time(NULL); + p = date_create_iso(t); + octstr_format_append(s, "\n", + h, p, v); + octstr_destroy(p); + skip = 1; + break; default: break; } @@ -618,14 +646,12 @@ static Octstr *headers_to_soapxml(List *hdrs, MM7Version_t *ver) if (!skip && h && v) octstr_format_append(s, "%S\n", h, v, h); - if (h) octstr_destroy(h); - if (v) octstr_destroy(v); + octstr_destroy(h); + octstr_destroy(v); } octstr_format_append(s, "\n", mtype); - octstr_destroy(mtype); - - if (fault) { - + octstr_destroy(mtype); + if (fault) { octstr_append_cstr(s, "\n"); octstr_append_cstr(s, "\n"); octstr_destroy(fault); @@ -757,7 +783,9 @@ int mm7_get_envelope(MSoapMsg_t *m, List **to, Octstr **subject, Octstr **vasid, time_t *expiry_t, - time_t *delivery_t) + time_t *delivery_t, + Octstr **uaprof, + time_t *uaprof_tstamp) { Octstr *s; @@ -801,6 +829,20 @@ int mm7_get_envelope(MSoapMsg_t *m, octstr_destroy(s); } } + if (uaprof) { + Octstr *s = http_header_value(m->envelope, octstr_imm("UACapabilities")); + if (uaprof_tstamp) *uaprof_tstamp = -1; + if (s) { + char *s1 = octstr_get_cstr(s); + char *s2 = strrchr(s1, ','); + + if (s2) { + *uaprof_tstamp = strtoul(s2+1, NULL, 10); + octstr_delete(s, s2-s1, octstr_len(s)); + } + *uaprof = s; + } + } return 0; } @@ -850,7 +892,7 @@ MmsMsg *mm7_soap_to_mmsmsg(MSoapMsg_t *m, Octstr *from) if ((s = http_header_value(m->envelope, octstr_imm("ReadReply"))) != NULL) { long x = mms_string_to_boolean_flag(s); if (x >= 0) - mms_replace_header_value(msg, "X-Mms-Read-Report", + mms_replace_header_value(msg, "X-Mms-Read-Reply", (char *)mms_reports_to_cstr(x)); octstr_destroy(s); } @@ -963,12 +1005,16 @@ static MSoapMsg_t *mm7_soap_create(int msgtype, Octstr *otransid) MSoapMsg_t *mm7_mmsmsg_to_soap(MmsMsg *msg, Octstr *from, List *xto, Octstr *transid, Octstr *srvcode, Octstr *linkedid, int isclientside, - char *vaspid, char *vasid) + char *vaspid, char *vasid, + Octstr *uaprof, + time_t uaprof_tstamp, + Octstr *distrib_indicator) { int i, n, mtype = mms_messagetype(msg); MSoapMsg_t *m = NULL; List *headers; Octstr *xfrom = (from != NULL) ? octstr_format("+ %S", from) : NULL, *s; + Octstr *xuaprof_val = (uaprof) ? octstr_format("%S,%ld", uaprof, uaprof_tstamp) : NULL; switch(mtype) { case MMS_MSGTYPE_SEND_REQ: @@ -1024,7 +1070,7 @@ MSoapMsg_t *mm7_mmsmsg_to_soap(MmsMsg *msg, Octstr *from, List *xto, octstr_destroy(s); } - if ((s = mms_get_header_value(msg, octstr_imm("X-Mms-Read-Report"))) != NULL) { + if ((s = mms_get_header_value(msg, octstr_imm("X-Mms-Read-Reply"))) != NULL) { char *val = (octstr_case_compare(s, octstr_imm("Yes")) == 0) ? "true" : "false"; http_header_add(m->envelope, "ReadReply", val); @@ -1037,7 +1083,13 @@ MSoapMsg_t *mm7_mmsmsg_to_soap(MmsMsg *msg, Octstr *from, List *xto, http_header_add(m->envelope, "allowAdaptations", val); octstr_destroy(s); } - + + if (distrib_indicator) + http_header_add(m->envelope, "DistributionIndicator", + octstr_str_case_compare(distrib_indicator, "true") == 0 ? "true" : "false"); + } else { /* not clientside. */ + if (xuaprof_val) /* only on DeliverReq. */ + http_header_add(m->envelope, "UACapabilities", octstr_get_cstr(xuaprof_val)); } if ((s = mms_get_header_value(msg, octstr_imm("X-Mms-Priority"))) != NULL) { @@ -1100,14 +1152,19 @@ MSoapMsg_t *mm7_mmsmsg_to_soap(MmsMsg *msg, Octstr *from, List *xto, http_header_add(m->envelope, "MMStatus", octstr_get_cstr(s)); octstr_destroy(s); } + + if (mtype == MMS_MSGTYPE_DELIVERY_IND && + xuaprof_val) /* and for DeliveryReport. */ + http_header_add(m->envelope, "UACapabilities", octstr_get_cstr(xuaprof_val)); break; default: break; } - if (xfrom) - octstr_destroy(xfrom); + octstr_destroy(xfrom); + octstr_destroy(xuaprof_val); + return m; } diff --git a/mbuni/mmlib/mms_mm7soap.h b/mbuni/mmlib/mms_mm7soap.h index dda8ad7..92b7ec1 100644 --- a/mbuni/mmlib/mms_mm7soap.h +++ b/mbuni/mmlib/mms_mm7soap.h @@ -57,7 +57,9 @@ extern int mm7_get_envelope(MSoapMsg_t *m, Octstr **sender, List **to, Octstr **subject, Octstr **vasid, time_t *expiry_t, - time_t *delivery_t); + time_t *delivery_t, + Octstr **uaprof, + time_t *uaprof_tstamp); /* Delete the thingie... */ extern void mm7_soap_destroy(MSoapMsg_t *m); @@ -67,7 +69,10 @@ MSoapMsg_t *mm7_mmsmsg_to_soap(MmsMsg *msg, Octstr *from, List *xto, Octstr *transid, Octstr *srvcode, Octstr *linkedid, int isclientside, - char *vaspid, char *vasid); + char *vaspid, char *vasid, + Octstr *uaprof, + time_t uaprof_tstamp, + Octstr *distrib_indicator); MSoapMsg_t *mm7_make_resp(MSoapMsg_t *mreq, int status, Octstr *msgid, int isclientside); /* Return the header value for some header. */ Octstr *mm7_soap_header_value(MSoapMsg_t *m, Octstr *header); diff --git a/mbuni/mmlib/mms_queue.c b/mbuni/mmlib/mms_queue.c index 1b81feb..acd93aa 100644 --- a/mbuni/mmlib/mms_queue.c +++ b/mbuni/mmlib/mms_queue.c @@ -779,6 +779,7 @@ static int free_envelope(MmsEnvelope *e, int removefromqueue) { int i, n; + if (e == NULL) return 0; octstr_destroy(e->msgId); for (i = 0, n = gwlist_len(e->to); i < n; i++) { @@ -819,7 +820,7 @@ static int free_envelope(MmsEnvelope *e, int removefromqueue) int mms_queue_free_env(MmsEnvelope *e) { - + return free_envelope(e, 0); } int mms_queue_update(MmsEnvelope *e) diff --git a/mbuni/mmlib/mms_queue.h b/mbuni/mmlib/mms_queue.h index 8ed14ea..f4bff62 100644 --- a/mbuni/mmlib/mms_queue.h +++ b/mbuni/mmlib/mms_queue.h @@ -88,7 +88,8 @@ int mms_init_queuedir(Octstr *qdir); 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, + time_t senddate, time_t expirydate, MmsMsg *m, + Octstr *token, Octstr *vaspid, Octstr *vasid, Octstr *url1, Octstr *url2, List *hdrs, diff --git a/mbuni/mmlib/mms_strings.def b/mbuni/mmlib/mms_strings.def index 2a89130..dd92dc7 100644 --- a/mbuni/mmlib/mms_strings.def +++ b/mbuni/mmlib/mms_strings.def @@ -308,6 +308,8 @@ VNSTRING(MM7_5, "replyChargingSize", MM7_TAG_replyChargingSize) VNSTRING(MM7_5, "replyDeadline", MM7_TAG_replyDeadline) VNSTRING(MM7_5, "DeliveryReport", MM7_TAG_DeliveryReport) VNSTRING(MM7_5, "allowAdaptations", MM7_TAG_allowAdaptations) +VNSTRING(MM7_5, "DistributionIndicator",MM7_TAG_distributionIndicator) +VNSTRING(MM7_5, "UACapabilities",MM7_TAG_UACapabilities) ) NUMBERED(soap_status, diff --git a/mbuni/mmlib/mms_uaprof.c b/mbuni/mmlib/mms_uaprof.c index 3a6b4e5..34fa5f1 100644 --- a/mbuni/mmlib/mms_uaprof.c +++ b/mbuni/mmlib/mms_uaprof.c @@ -3,7 +3,7 @@ * * User-Agent profiles handling, content adaptation. * - * Copyright (C) 2003 - 2005, Digital Solutions Ltd. - http://www.dsmagic.com + * Copyright (C) 2003 - 2007, Digital Solutions Ltd. - http://www.dsmagic.com * * Paul Bagyenda * diff --git a/mbuni/mmsbox/bearerbox.c b/mbuni/mmsbox/bearerbox.c index 069e226..05973a3 100644 --- a/mbuni/mmsbox/bearerbox.c +++ b/mbuni/mmsbox/bearerbox.c @@ -68,26 +68,31 @@ static int auth_check(Octstr *user, Octstr *pass, List *headers) else res = 0; done: - if (v) - octstr_destroy(v); - if (p) - octstr_destroy(p); - if (q) - octstr_destroy(q); + octstr_destroy(v); + octstr_destroy(p); + octstr_destroy(q); return res; } static int send_report(Octstr *from, char *report_type, Octstr *dlr_url, Octstr *status, - Octstr *msgid, Octstr *mmc_id, Octstr *mmc_gid) + Octstr *msgid, Octstr *mmc_id, Octstr *mmc_gid, + Octstr *orig_transid, Octstr *uaprof, + time_t uaprof_tstamp) { - Octstr *url = dlr_url ? octstr_duplicate(dlr_url) : mms_dlr_url_get(msgid, report_type, mmc_gid); + Octstr *url = NULL; List *rh, *rph = NULL; Octstr *rb = NULL; + Octstr *xtransid = NULL; - if (!url) { - info(0, "Sending delivery-report Failed: `url' is NULL, `group_id'=[%s], `msgid'=[%s]", + if (dlr_url) + url = octstr_duplicate(dlr_url); + else + mms_dlr_url_get(msgid, report_type, mmc_gid, &url, &xtransid); + + if (!url || octstr_len(url) == 0) { + info(0, "Sending delivery-report skipped: `url' is empty, `group_id'=[%s], `msgid'=[%s]", octstr_get_cstr(mmc_gid), octstr_get_cstr(msgid)); return 0; } @@ -96,16 +101,26 @@ static int send_report(Octstr *from, char *report_type, http_header_add(rh, "X-Mbuni-Report-Type", report_type); http_header_add(rh, "X-Mbuni-MM-Status", octstr_get_cstr(status)); - http_header_add(rh, "X-Mbuni-Message-ID", octstr_get_cstr(msgid)); http_header_add(rh, "X-Mbuni-MMSC-ID", octstr_get_cstr(mmc_id)); http_header_add(rh, "X-Mbuni-MMSC-GID", octstr_get_cstr(mmc_gid)); http_header_add(rh, "X-Mbuni-From", octstr_get_cstr(from)); - + if (xtransid || orig_transid) + http_header_add(rh, "X-Mbuni-TransactionID", + octstr_get_cstr(xtransid ? xtransid : orig_transid)); + if (msgid) + http_header_add(rh, "X-Mbuni-Message-ID", octstr_get_cstr(msgid)); + if (uaprof) { + Octstr *sx = date_format_http(uaprof_tstamp); + http_header_add(rh, "X-Mbuni-UAProf", octstr_get_cstr(uaprof)); + http_header_add(rh, "X-Mbuni-Timestamp", octstr_get_cstr(sx)); + octstr_destroy(sx); + } mms_url_fetch_content(HTTP_METHOD_GET, url, rh, octstr_imm(""), &rph, &rb); - + octstr_destroy(rb); octstr_destroy(url); + octstr_destroy(xtransid); http_destroy_headers(rph); http_destroy_headers(rh); @@ -130,8 +145,8 @@ static void mm7soap_receive(MmsHTTPClientInfo *h) Octstr *reply_body = NULL, *value, *desc; List *to = NULL; - Octstr *from = NULL, *subject = NULL, *vasid = NULL, *msgid = NULL; - time_t expiryt = -1, delivert = -1; + Octstr *from = NULL, *subject = NULL, *vasid = NULL, *msgid = NULL, *uaprof = NULL; + time_t expiryt = -1, delivert = -1, uaprof_tstamp = -1; MmsMsg *m = NULL; int status = 1000; unsigned char *msgtype = (unsigned char *)""; @@ -152,7 +167,7 @@ static void mm7soap_receive(MmsHTTPClientInfo *h) goto done; } - mm7_get_envelope(mreq, &from, &to, &subject, &vasid, &expiryt, &delivert); + mm7_get_envelope(mreq, &from, &to, &subject, &vasid, &expiryt, &delivert, &uaprof, &uaprof_tstamp); if (!from) from = octstr_imm("anon@anon"); @@ -164,27 +179,34 @@ static void mm7soap_receive(MmsHTTPClientInfo *h) Octstr *value = NULL; /* Store linked id so we use it in response. */ Octstr *linkedid = mm7_soap_header_value(mreq, octstr_imm("LinkedID")); + List *qh = http_create_empty_headers(); 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; - + + 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) + DEFAULT_EXPIRE; + if (uaprof) { + Octstr *sx = date_format_http(uaprof_tstamp); + http_header_add(qh, "X-Mbuni-UAProf", octstr_get_cstr(uaprof)); + http_header_add(qh, "X-Mbuni-Timestamp", octstr_get_cstr(sx)); + octstr_destroy(sx); + } qf = mms_queue_add(from, to, subject, h->m->id, NULL, delivert, expiryt, m, linkedid, NULL, NULL, NULL, NULL, - NULL, + qh, dlr, octstr_get_cstr(incoming_qdir), octstr_imm(MM_NAME)); @@ -193,12 +215,15 @@ static void mm7soap_receive(MmsHTTPClientInfo *h) octstr_destroy(linkedid); octstr_destroy(value); + http_destroy_headers(qh); } else { - error(0, "Failed to convert received MM7/SOAP DeliverReq message from mmc=%s to MMS Message!", + error(0, + "Failed to convert received MM7/SOAP DeliverReq message from mmc=%s to MMS Message!", octstr_get_cstr(h->m->id)); status = 4000; } mresp = mm7_make_resp(mreq, status, NULL,1); + break; case MM7_TAG_DeliveryReportReq: @@ -210,7 +235,7 @@ static void mm7soap_receive(MmsHTTPClientInfo *h) octstr_get_cstr(from), octstr_get_cstr(value), octstr_get_cstr(desc), octstr_get_cstr(h->m->id)); send_report(from, "delivery-report", NULL, - value, msgid, h->m->id, h->m->group_id); + value, msgid, h->m->id, h->m->group_id, NULL, uaprof, uaprof_tstamp); octstr_destroy(desc); octstr_destroy(value); @@ -225,7 +250,7 @@ static void mm7soap_receive(MmsHTTPClientInfo *h) send_report(from, "read-report", NULL, value, msgid, - h->m->id, h->m->group_id); + h->m->id, h->m->group_id, NULL, uaprof, uaprof_tstamp); octstr_destroy(value); mms_log("ReadReport", @@ -255,6 +280,7 @@ static void mm7soap_receive(MmsHTTPClientInfo *h) octstr_destroy(vasid); octstr_destroy(msgid); octstr_destroy(qf); + octstr_destroy(uaprof); mms_destroy(m); http_destroy_headers(rh); octstr_destroy(reply_body); @@ -383,7 +409,7 @@ static void mm7eaif_receive(MmsHTTPClientInfo *h) case MMS_MSGTYPE_DELIVERY_IND: value = http_header_value(mh, octstr_imm("X-Mms-Status")); value2 = http_header_value(mh, octstr_imm("Message-ID")); - send_report(hfrom, "delivery-report", NULL, value, value2, h->m->id, h->m->group_id); + send_report(hfrom, "delivery-report", NULL, value, value2, h->m->id, h->m->group_id, NULL, NULL, -1); octstr_destroy(value); octstr_destroy(value2); @@ -392,7 +418,7 @@ static void mm7eaif_receive(MmsHTTPClientInfo *h) case MMS_MSGTYPE_READ_ORIG_IND: value = http_header_value(mh, octstr_imm("X-Mms-Read-Status")); value2 = http_header_value(mh, octstr_imm("Message-ID")); - send_report(hfrom, "read-report", NULL, value, value2, h->m->id, h->m->group_id); + send_report(hfrom, "read-report", NULL, value, value2, h->m->id, h->m->group_id, NULL, NULL, -1); octstr_destroy(value); @@ -521,7 +547,7 @@ static Octstr *mm7soap_send(MmscGrp *mmc, Octstr *from, Octstr *to, MSoapMsg_t *mreq = NULL, *mresp = NULL; List *rh = NULL, *ph = NULL; Octstr *body = NULL, *rbody = NULL, *url = NULL; - Octstr *s; + Octstr *s, *distrib = NULL; info(0, "MMSBox: Send[soap] to MMSC[%s], msg type [%s], from %s, to %s", mmc->id ? octstr_get_cstr(mmc->id) : "", @@ -529,11 +555,14 @@ static Octstr *mm7soap_send(MmscGrp *mmc, Octstr *from, Octstr *to, octstr_get_cstr(from), octstr_get_cstr(to)); gwlist_append(xto, to); - + + if (hdrs) + distrib = http_header_value(hdrs, octstr_imm("X-Mbuni-DistributionIndicator")); if ((mreq = mm7_mmsmsg_to_soap(m, from, xto, transid, service_code, linkedid, - 1, octstr_get_cstr(mmc->id), vasid)) == NULL) { + 1, octstr_get_cstr(mmc->id), vasid, NULL, 0,/* UA N/A on this side. */ + distrib)) == NULL) { *error = octstr_format("Failed to convert Msg[%S] 2 SOAP message!", mms_message_type_to_string(mtype)); goto done1; @@ -606,7 +635,7 @@ done1: http_destroy_headers(ph); octstr_destroy(rbody); octstr_destroy(url); - + octstr_destroy(distrib); gwlist_destroy(xto, NULL); return ret; @@ -696,10 +725,11 @@ static Octstr *mm7eaif_send(MmscGrp *mmc, Octstr *from, Octstr *to, if (ret) mms_log2("Sent", from, to, -1, ret, NULL, mmc->id, "MMSBox", NULL, NULL); +#if 0 info(0, "Sent to MMC[%s], code=[%d], resp=[%s] msgid [%s]", octstr_get_cstr(mmc->id), hstatus, resp ? octstr_get_cstr(resp) : "(none)", ret ? octstr_get_cstr(ret) : "(none)"); - +#endif http_destroy_headers(rh); octstr_destroy(body); @@ -712,9 +742,12 @@ static Octstr *mm7eaif_send(MmscGrp *mmc, Octstr *from, Octstr *to, static int mms_sendtommsc(MmscGrp *mmc, Octstr *from, Octstr *to, Octstr *transid, + Octstr *orig_transid, Octstr *linkedid, char *vasid, Octstr *service_code, MmsMsg *m, Octstr *dlr_url, Octstr *rr_url, - List *hdrs, Octstr **err) + List *hdrs, + Octstr **new_msgid, + Octstr **err) { Octstr *id = NULL, *groupid = NULL; int ret = 0, retry = 0; @@ -735,20 +768,16 @@ static int mms_sendtommsc(MmscGrp *mmc, Octstr *from, Octstr *to, Octstr *transi } mutex_unlock(mmc->mutex); /* release lock */ if (id) { - if (dlr_url) { /* remember the url's for reporting purposes. */ - mms_dlr_url_put(id, "delivery-report", groupid, dlr_url); - send_report(from, "delivery-report", dlr_url, - octstr_imm("Sent"), id, mmc->id, groupid); - } - + if (dlr_url) /* remember the url's for reporting purposes. */ + mms_dlr_url_put(id, "delivery-report", groupid, dlr_url, orig_transid); if (rr_url) - mms_dlr_url_put(id, "read-report", groupid, rr_url); - - octstr_destroy(id); + mms_dlr_url_put(id, "read-report", groupid, rr_url, orig_transid); ret = MMS_SEND_OK; } else ret = retry ? MMS_SEND_ERROR_TRANSIENT : MMS_SEND_ERROR_FATAL; + *new_msgid = id; + octstr_destroy(groupid); if (id && throughput > 0) gwthread_sleep(1.0/throughput); @@ -760,7 +789,7 @@ static int sendMsg(MmsEnvelope *e) { MmsMsg *msg = NULL; int i, n; - + Octstr *otransid = e->hdrs ? http_header_value(e->hdrs, octstr_imm("X-Mbuni-TransactionID")) : NULL; msg = mms_queue_getdata(e); for (i = 0, n = gwlist_len(e->to); iprocess) continue; @@ -798,32 +828,39 @@ static int sendMsg(MmsEnvelope *e) res = mms_sendtommsc(mmc, e->from, to->rcpt, e->msgId, + otransid, e->token, /* token = linkedid */ e->vasid ? octstr_get_cstr(e->vasid) : NULL, e->vaspid, msg, e->url1, e->url2, e->hdrs, + &new_msgid, &err); done: - if (res == MMS_SEND_OK) + if (res == MMS_SEND_OK) { to->process = 0; - else if (res == MMS_SEND_ERROR_FATAL && mmc) + send_report(to->rcpt, "delivery-report", e->url1, + octstr_imm("Sent"), new_msgid, mmc->id, mmc->group_id, otransid, NULL, -1); + + } else if (res == MMS_SEND_ERROR_FATAL && mmc) send_report(to->rcpt, "delivery-report", e->url1, (e->expiryt != 0 && e->expiryt < tnow) ? octstr_imm("Expired") : octstr_imm("Rejected"), - e->msgId, mmc->id, mmc->group_id); + e->msgId, mmc->id, mmc->group_id, otransid, NULL, -1); if (res == MMS_SEND_ERROR_FATAL) to->process = 0; /* No more attempts. */ - info(0, "%s MMSBox Outgoing Queue MMS Send: From %s, to %s, msgsize=%ld: err=%s", + info(0, "%s MMSBox Outgoing Queue MMS Send: From %s, to %s, msgsize=%ld: msgid=[%s], err=%s", SEND_ERROR_STR(res), octstr_get_cstr(e->from), octstr_get_cstr(to->rcpt), e->msize, + new_msgid ? octstr_get_cstr(new_msgid) : NULL, err ? octstr_get_cstr(err) : "(none)"); - + octstr_destroy(new_msgid); + e->lasttry = tnow; if (mms_queue_update(e) == 1) { e = NULL; @@ -833,6 +870,7 @@ static int sendMsg(MmsEnvelope *e) } mms_destroy(msg); + octstr_destroy(otransid); if (e) { /* Update the queue if it is still valid (e.g. recipients not handled) * XXX can this happen here??... diff --git a/mbuni/mmsbox/dlr.c b/mbuni/mmsbox/dlr.c index 3649190..c206790 100644 --- a/mbuni/mmsbox/dlr.c +++ b/mbuni/mmsbox/dlr.c @@ -81,33 +81,41 @@ static int dlr_entry_fname(char *msgid, char *rtype, Octstr *mmc_gid, Octstr **e return fd; } -void mms_dlr_url_put(Octstr *msgid, char *rtype, Octstr *mmc_gid, Octstr *dlr_url) +void mms_dlr_url_put(Octstr *msgid, char *rtype, Octstr *mmc_gid, Octstr *dlr_url, Octstr *transid) { int fd = dlr_entry_fname(octstr_get_cstr(msgid), rtype, mmc_gid, NULL); if (fd >= 0) { - octstr_write_data(dlr_url, fd, 0); + Octstr *x = octstr_format("%S %S", transid ? transid : octstr_imm("x"), dlr_url); /* better have no spaces in transid! */ + octstr_write_data(x, fd, 0); close(fd); + octstr_destroy(x); } } -Octstr *mms_dlr_url_get(Octstr *msgid, char *rtype, Octstr *mmc_gid) +int mms_dlr_url_get(Octstr *msgid, char *rtype, Octstr *mmc_gid, Octstr **dlr_url, Octstr **transid) { int fd = dlr_entry_fname(octstr_get_cstr(msgid), rtype, mmc_gid, NULL); FILE *f; if (fd >= 0 && (f = fdopen(fd, "r+")) != NULL) { Octstr *s = octstr_read_pipe(f); - + int i, ret; + fclose(f); if (s && octstr_len(s) == 0) { - octstr_destroy(s); - return NULL; + ret = -1; + } else if ((i = octstr_search_char(s, ' ', 0)) >= 0) { + *transid = octstr_copy(s, 0, i); + *dlr_url = octstr_copy(s, i+1, octstr_len(s)); + ret = 0; } else - return s; + ret = -1; + octstr_destroy(s); + return ret; } else if (fd >= 0) close(fd); - return NULL; + return -1; } void mms_dlr_url_remove(Octstr *msgid, char *rtype, Octstr *mmc_gid) diff --git a/mbuni/mmsbox/mmsbox.c b/mbuni/mmsbox/mmsbox.c index 40e6672..07cba5a 100644 --- a/mbuni/mmsbox/mmsbox.c +++ b/mbuni/mmsbox/mmsbox.c @@ -293,6 +293,7 @@ done: enum _xurltype {FILE_TYPE, URL_TYPE}; static Octstr *url_path_prefix(Octstr *url, int type); +/* this function constructs and sends the message -- a bit too many params XXX! */ static int make_and_queue_msg(Octstr *data, Octstr *ctype, List *reply_headers, Octstr *msg_url, Octstr *base_url, int type, MmsEnvelope *e, @@ -308,13 +309,15 @@ static int fetch_serviceurl(MmsEnvelope *e, Octstr **err) { List *rh, *rph = NULL; - Octstr *body = NULL, *rb = NULL; + Octstr *body = NULL, *rb = NULL, *transid; Octstr *ctype = NULL, *params = NULL; + Octstr *s; int i, n, method, typ = FILE_TYPE; FILE *fp = NULL; int res = -1; + transid = mms_maketransid(e->xqfname, octstr_imm(MM_NAME)); switch (ms->type) { case TRANS_TYPE_GET_URL: case TRANS_TYPE_POST_URL: @@ -331,11 +334,25 @@ static int fetch_serviceurl(MmsEnvelope *e, if (e->subject) http_header_add(rh, "X-Mbuni-Subject", octstr_get_cstr(e->subject)); + + /* Put in a transaction ID. */ + http_header_add(rh, "X-Mbuni-TransactionID", octstr_get_cstr(transid)); + for (i = 0, n = gwlist_len(e->to); i < n; i++) { MmsEnvelopeTo *r = gwlist_get(e->to, i); if (r && r->rcpt) http_header_add(rh, "X-Mbuni-To", octstr_get_cstr(r->rcpt)); } + + if ((s = http_header_value(e->hdrs, octstr_imm("X-Mbuni-UAProf"))) != NULL) { /* add UAProf info, if any. */ + Octstr *sx = http_header_value(e->hdrs,octstr_imm("X-Mbuni-Timestamp")); + http_header_add(rh, "X-Mbuni-UAProf", octstr_get_cstr(s)); + if (sx) + http_header_add(rh, "X-Mbuni-Timestamp", octstr_get_cstr(sx)); + octstr_destroy(sx); + octstr_destroy(s); + } + if (ms->type == TRANS_TYPE_POST_URL) { /* Put in the parameters. */ MIMEEntity *x = mime_entity_create(); @@ -358,14 +375,16 @@ static int fetch_serviceurl(MmsEnvelope *e, method = HTTP_METHOD_GET; typ = URL_TYPE; - if (mmsbox_url_fetch_content(method, ms->url, rh, body, &rph, &rb) == HTTP_OK) + if (mmsbox_url_fetch_content(method, ms->url, rh, body, &rph, &rb) == HTTP_OK) { get_content_type(rph, &ctype, ¶ms); - else + /* add transaction id back.*/ + http_header_remove_all(rph, "X-Mbuni-TransactionID"); + http_header_add(rph, "X-Mbuni-TransactionID", octstr_get_cstr(transid)); + } else *err = octstr_format("MMSBox: Failed to fetch content for Service %S, url %S!", ms->name, ms->url); http_destroy_headers(rh); - if (body) - octstr_destroy(body); + octstr_destroy(body); break; case TRANS_TYPE_FILE: if ((fp = fopen(octstr_get_cstr(ms->url), "r")) != NULL) { @@ -438,7 +457,8 @@ done: octstr_destroy(rb); http_destroy_headers(rph); octstr_destroy(params); - + octstr_destroy(transid); + return res; } @@ -451,7 +471,8 @@ static int mmsbox_service_dispatch(MmsEnvelope *e) Octstr *err = NULL, *keyword = NULL; MmsService *ms; - gw_assert(e->msgtype == MMS_MSGTYPE_SEND_REQ || e->msgtype == MMS_MSGTYPE_RETRIEVE_CONF); + gw_assert(e->msgtype == MMS_MSGTYPE_SEND_REQ || + e->msgtype == MMS_MSGTYPE_RETRIEVE_CONF); if ((msg = mms_queue_getdata(e)) == NULL) { err = octstr_format("Failed to read message for queue entry %s!", @@ -800,11 +821,12 @@ static int make_and_queue_msg(Octstr *data, Octstr *ctype, List *reply_headers, { Octstr *from = NULL, *xfrom = NULL, *subject = NULL, *turl = get_toplevel_url(base_url); Octstr *dlr_url = NULL, *rr_url = NULL, *mmc = NULL, *xservice_code = NULL, *hsvc_code = NULL; - Octstr *allow_adaptations = NULL, *mclass = NULL, *prio = NULL; + Octstr *allow_adaptations = NULL, *mclass = NULL, *prio = NULL, *distro = NULL; MmsMsg *m = NULL; MIMEEntity *me = mime_entity_create(); - List *hdrs = NULL, *xheaders = NULL; - + List *xheaders = NULL; + List *hdrs = http_create_empty_headers(); + Octstr *otransid = NULL; time_t expiryt = time(NULL) + DEFAULT_EXPIRE; Octstr *x; @@ -856,6 +878,11 @@ static int make_and_queue_msg(Octstr *data, Octstr *ctype, List *reply_headers, hsvc_code = http_header_value(reply_headers, octstr_imm("X-Mbuni-ServiceCode")); } + if (reply_headers) { + /* always capture transid and distro */ + otransid = http_header_value(reply_headers, octstr_imm("X-Mbuni-TransactionID")); + distro = http_header_value(reply_headers, octstr_imm("X-Mbuni-DistributionIndicator")); + } if (gwlist_len(xto) == 0 && e && e->from) gwlist_append(xto, octstr_duplicate(e->from)); @@ -988,7 +1015,6 @@ static int make_and_queue_msg(Octstr *data, Octstr *ctype, List *reply_headers, me = xm; } } - /* Add some nice headers. */ xheaders = mime_entity_headers(me); @@ -1003,7 +1029,7 @@ static int make_and_queue_msg(Octstr *data, Octstr *ctype, List *reply_headers, if (dlr_url) http_header_add(xheaders, "X-Mms-Delivery-Report", "Yes"); if (rr_url) - http_header_add(xheaders, "X-Mms-Read-Report", "Yes"); + http_header_add(xheaders, "X-Mms-Read-Reply", "Yes"); if (allow_adaptations) http_header_add(xheaders, "X-Mms-Allow-Adaptations", (octstr_str_compare(allow_adaptations, "true") == 0) ? "true" : "false"); @@ -1032,11 +1058,15 @@ static int make_and_queue_msg(Octstr *data, Octstr *ctype, List *reply_headers, goto done; } + if (otransid) /* always add transid */ + http_header_add(hdrs, "X-Mbuni-TransactionID", octstr_get_cstr(otransid)); + + if (distro) /* always add distrib */ + http_header_add(hdrs, "X-Mbuni-DistributionIndicator", octstr_get_cstr(distro)); + if (passthro_headers && reply_headers) { /* if user wants passthro headers, get them and add them. */ int n = gwlist_len(reply_headers); - int i; - - hdrs = http_create_empty_headers(); + int i; for (i = 0; i < n; i++) { Octstr *h = NULL, *v = NULL; int j; @@ -1072,8 +1102,10 @@ static int make_and_queue_msg(Octstr *data, Octstr *ctype, List *reply_headers, (dlr_url != NULL), octstr_get_cstr(qdir), octstr_imm(MM_NAME)); - info(0, "MMSBox: Queued message from service [%s]: %s", - octstr_get_cstr(svc_name), octstr_get_cstr(x)); + info(0, "MMSBox: Queued message from service [%s], [transid [%s]: %s", + octstr_get_cstr(svc_name), + otransid ? octstr_get_cstr(otransid) : "", + octstr_get_cstr(x)); *err = x; res = 0; done: @@ -1086,6 +1118,7 @@ done: octstr_destroy(from); octstr_destroy(xfrom); octstr_destroy(subject); + octstr_destroy(otransid); if (me) mime_entity_destroy(me); @@ -1258,20 +1291,27 @@ static void sendmms_func(void *unused) /* Requests to make_and_queue below can block, but for now we don't care. */ if (ctype && data && !rb) { /* only send if no error. */ + int send_as_incoming = (send_type && + octstr_str_case_compare(send_type, "mo") == 0); + Octstr *transid = NULL; + if (!send_as_incoming) { /* for outgoing, track TransactionID for DLR. */ + transid = mms_maketransid(NULL, octstr_imm(MM_NAME)); + http_header_add(rh, "X-Mbuni-TransactionID", octstr_get_cstr(transid)); + } res = make_and_queue_msg(data, ctype, rh, data_url ? data_url : base_url, base_url, URL_TYPE, NULL, vasid ? vasid : octstr_imm("sendmms-user"), u->faked_sender, service_code, 1, NULL, - (send_type && - octstr_str_case_compare(send_type, "mo") == 0) ? - incoming_qdir : outgoing_qdir, + send_as_incoming ? incoming_qdir : outgoing_qdir, &err); if (res < 0) rb = octstr_format("Error in message conversion: %S", err); else - rb = octstr_format("Accepted: %S", err ? err : octstr_imm("1")); + rb = octstr_format("Accepted: %S", /* repeat transid. */ + send_as_incoming ? err : transid); + octstr_destroy(transid); } else if (!rb) rb = octstr_imm("Failed to send message"); http_send_reply(client, (res == 0) ? HTTP_OK : HTTP_BAD_REQUEST, hh, @@ -1281,7 +1321,6 @@ static void sendmms_func(void *unused) (res == 0) ? "Queued" : "Not Queued", rb ? octstr_get_cstr(rb) : ""); - http_destroy_headers(rh); octstr_destroy(ctype); octstr_destroy(rb); diff --git a/mbuni/mmsbox/mmsbox.h b/mbuni/mmsbox/mmsbox.h index e7c7196..340f9e5 100644 --- a/mbuni/mmsbox/mmsbox.h +++ b/mbuni/mmsbox/mmsbox.h @@ -15,8 +15,8 @@ #include "mmsbox_cfg.h" extern int rstop; -void mms_dlr_url_put(Octstr *msgid, char *rtype, Octstr *mmc_gid, Octstr *dlr_url); -Octstr *mms_dlr_url_get(Octstr *msgid, char *rtype, Octstr *mmc_gid); +void mms_dlr_url_put(Octstr *msgid, char *rtype, Octstr *mmc_gid, Octstr *dlr_url, Octstr *transid); +int mms_dlr_url_get(Octstr *msgid, char *rtype, Octstr *mmc_gid, Octstr **dlr_url, Octstr **transid); void mms_dlr_url_remove(Octstr *msgid, char *rtype, Octstr *mmc_gid); void mmsc_receive_func(MmscGrp *m); void mmsbox_outgoing_queue_runner(int *rstop); diff --git a/mbuni/mmsc/mmsc_cfg.c b/mbuni/mmsc/mmsc_cfg.c index 7da9895..afd0add 100644 --- a/mbuni/mmsc/mmsc_cfg.c +++ b/mbuni/mmsc/mmsc_cfg.c @@ -345,6 +345,19 @@ MmscSettings *mms_load_mmsc_settings(mCfg *cfg, List **proxyrelays) warning(0, "mms-to-mobile copy handler VASP specified more than once! Only last config taken."); m->mms2mobile = mv; } + + if ((s = _mms_cfg_getx(grp, octstr_imm("send-uaprof"))) != NULL){ + if (octstr_str_case_compare(s, "url") == 0) + mv->send_uaprof = UAProf_URL; + else if (octstr_str_case_compare(s, "ua") == 0) + mv->send_uaprof = UAProf_UA; + else { + warning(0, "unknown send-uaprof value '%s'. Must be \"ua\" or \"url\"!", + octstr_get_cstr(s)); + mv->send_uaprof = UAProf_None; + } + octstr_destroy(s); + } gwlist_append(m->vasp_list, mv); } gwlist_destroy(l, NULL); diff --git a/mbuni/mmsc/mmsc_cfg.h b/mbuni/mmsc/mmsc_cfg.h index 3a53b70..7fad2b5 100644 --- a/mbuni/mmsc/mmsc_cfg.h +++ b/mbuni/mmsc/mmsc_cfg.h @@ -31,6 +31,7 @@ typedef struct MmsVasp { enum {SOAP_VASP, EAIF_VASP, NONE_VASP} type; Octstr *vasp_username, *vasp_password; Octstr *vasp_url; + enum {UAProf_None, UAProf_URL, UAProf_UA} send_uaprof; MM7Version_t ver; } MmsVasp; diff --git a/mbuni/mmsc/mmsglobalsender.c b/mbuni/mmsc/mmsglobalsender.c index b3be21d..624103e 100644 --- a/mbuni/mmsc/mmsglobalsender.c +++ b/mbuni/mmsc/mmsglobalsender.c @@ -49,6 +49,7 @@ static int mms_sendtoproxy(Octstr *from, Octstr *to, int dlr, Octstr **error); static int mms_sendtovasp(MmsVasp *vasp, Octstr *from, Octstr *to, Octstr *msgId, + List *qh, MmsMsg *m, Octstr **error); static int _x_octstr_int_compare(int n, Octstr *s); @@ -156,6 +157,7 @@ static int sendMsg(MmsEnvelope *e) res = mms_sendtovasp(settings->mms2email, e->from, to->rcpt, e->msgId, + e->hdrs, msg, &err); else res = mms_sendtoemail(pfrom, to->rcpt, @@ -191,6 +193,7 @@ static int sendMsg(MmsEnvelope *e) int res = mms_sendtovasp(settings->mms2mobile, e->from, to->rcpt, e->msgId, + e->hdrs, msg, &err); info(0, "%s Global Queue MMS Send: Local Msg copy to VASP (%s) - " "From %s, to %s, msgsize=%ld: err=%s", @@ -220,6 +223,7 @@ static int sendMsg(MmsEnvelope *e) _x_octstr_int_compare(vasp->short_code, phonenum) == 0) { res = mms_sendtovasp(vasp, e->from, to->rcpt, e->msgId, + e->hdrs, msg, &err); sent = 1; break; @@ -242,6 +246,7 @@ static int sendMsg(MmsEnvelope *e) int res = mms_sendtovasp(settings->mms2mobile, e->from, to->rcpt, e->msgId, + e->hdrs, msg, &err); info(0, "%s Global Queue MMS Send: Local Msg copy to VASP (%s) - " "From %s, to %s, msgsize=%ld: err=%s", @@ -310,7 +315,7 @@ static int sendMsg(MmsEnvelope *e) gwlist_append(l, octstr_duplicate(e->from)); /* Add to queue, switch via proxy to be from proxy. */ - qfs = mms_queue_add(settings->system_user, l, + qfs = mms_queue_add(to->rcpt, l, err, NULL, e->fromproxy, tnow, tnow+settings->default_msgexpiry, m, NULL, NULL, NULL, @@ -528,7 +533,8 @@ static int _x_octstr_int_compare(int n, Octstr *s) } static int mm7soap_send(MmsVasp *vasp, Octstr *from, Octstr *to, Octstr *msgId, - MmsMsg *m, Octstr **error) + List *qh, + MmsMsg *m, Octstr **error) { int ret = MMS_SEND_ERROR_TRANSIENT; int mtype = mms_messagetype(m); @@ -537,8 +543,8 @@ static int mm7soap_send(MmsVasp *vasp, Octstr *from, Octstr *to, Octstr *msgId, MSoapMsg_t *mreq = NULL, *mresp = NULL; List *rh = NULL, *ph = NULL; Octstr *body = NULL, *rbody = NULL; - - Octstr *s; + Octstr *uaprof = NULL, *s; + time_t tstamp; info(0, "MMS Relay: Send[soap] to VASP[%s], msg_type=[%s], from=[%s], to=[%s]", vasp ? octstr_get_cstr(vasp->id) : "", @@ -546,10 +552,20 @@ static int mm7soap_send(MmsVasp *vasp, Octstr *from, Octstr *to, Octstr *msgId, gwlist_append(xto, to); + if (vasp->send_uaprof == UAProf_URL) + uaprof = http_header_value(qh, octstr_imm("X-Mbuni-Profile-Url")); + else if (vasp->send_uaprof == UAProf_UA) + uaprof = http_header_value(qh, octstr_imm("X-Mbuni-User-Agent")); + + if ((s = http_header_value(qh, octstr_imm("X-Mbuni-Timestamp"))) != NULL) { + tstamp = strtoul(octstr_get_cstr(s), NULL, 10); + octstr_destroy(s); + } else + tstamp = 0; if ((mreq = mm7_mmsmsg_to_soap(m, from, xto, msgId, settings->host_alias, msgId, - 0, NULL, NULL)) == NULL) { + 0, NULL, NULL, uaprof, tstamp, NULL)) == NULL) { *error = octstr_format("Failed to convert Msg[%s] 2 SOAP message!", mms_message_type_to_cstr(mtype)); goto done1; @@ -604,19 +620,16 @@ static int mm7soap_send(MmsVasp *vasp, Octstr *from, Octstr *to, Octstr *msgId, 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); + mm7_soap_destroy(mreq); + mm7_soap_destroy(mresp); + http_destroy_headers(rh); + + octstr_destroy(body); + http_destroy_headers(ph); + + octstr_destroy(rbody); + octstr_destroy(uaprof); gwlist_destroy(xto, NULL); return ret; @@ -695,13 +708,14 @@ static int mm7eaif_send(MmsVasp *vasp, Octstr *from, Octstr *to, Octstr *msgid, } static int mms_sendtovasp(MmsVasp *vasp, Octstr *from, Octstr *to, Octstr *msgid, + List *qh, MmsMsg *m, Octstr **err) { if (m == NULL) { *err = octstr_format("GlobalSend: Failed to send to %S, Message format is corrupt!", to); return MMS_SEND_ERROR_FATAL; } else if (vasp->type == SOAP_VASP) - return mm7soap_send(vasp, from, to, msgid, m, err); + return mm7soap_send(vasp, from, to, msgid, qh, m, err); else if (vasp->type == EAIF_VASP) return mm7eaif_send(vasp, from, to, msgid, m, err); else { diff --git a/mbuni/mmsc/mmsproxy.c b/mbuni/mmsc/mmsproxy.c index 9ad2e36..facd73a 100644 --- a/mbuni/mmsc/mmsproxy.c +++ b/mbuni/mmsc/mmsproxy.c @@ -386,9 +386,7 @@ void fetchmms_proxy(MmsHTTPClientInfo *h) /* Send to access log with success. */ mms_log2("Fetched", e ? e->from : NULL, h->client_addr, e ? e->msize : 0, e ? e->msgId : NULL, NULL, NULL, "MM1", - h->ua, (loc == MMS_LOC_MMBOX) ? qf : NULL); - - + h->ua, (loc == MMS_LOC_MMBOX) ? qf : NULL); goto free_stuff; /* Skip to end. */ failed: @@ -415,7 +413,6 @@ void fetchmms_proxy(MmsHTTPClientInfo *h) } free_stuff: - if (notify_cmd) /* Inform provisioning server */ notify_prov_server(octstr_get_cstr(settings->prov_notify), h->base_client_addr ? octstr_get_cstr(h->base_client_addr) : "unknown", @@ -423,15 +420,15 @@ void fetchmms_proxy(MmsHTTPClientInfo *h) http_destroy_headers(rh); - if (e) mms_queue_free_env(e); + mms_queue_free_env(e); - if (s) octstr_destroy(s); - if (m) mms_destroy(m); - if (mr) mms_destroy(mr); + octstr_destroy(s); + mms_destroy(m); + mms_destroy(mr); - if (qf) octstr_destroy(qf); - if (token) octstr_destroy(token); - if (transid) octstr_destroy(transid); + octstr_destroy(qf); + octstr_destroy(token); + octstr_destroy(transid); free_clientInfo(h,1); } @@ -446,9 +443,11 @@ static void sendmms_proxy(MmsHTTPClientInfo *h) int ctype_set = 0; int mtype = 0, menc; int hstatus = HTTP_OK; - char *notify_cmd = NULL; + char *notify_cmd = NULL, tbuf[64]; int msize = h->body ? octstr_len(h->body) : 0; + List *qh = http_create_empty_headers(); + debug("proxy.sendinterface", 0, " --> Enterred sendmms interface, blen=%d <--- ", msize); @@ -458,7 +457,7 @@ static void sendmms_proxy(MmsHTTPClientInfo *h) if (!h->body) { /* A body is required. */ http_header_add(rh, "Content-Type", "text/plain"); - hstatus = HTTP_FORBIDDEN; + hstatus = HTTP_BAD_REQUEST; reply_body = octstr_format("Unexpected MMS message[%s], no body?", mms_message_type_to_cstr(mtype)); @@ -476,9 +475,17 @@ static void sendmms_proxy(MmsHTTPClientInfo *h) goto done; } + /* Record user agent and profile url. */ + if (h->ua) + http_header_add(qh, "X-Mbuni-User-Agent", octstr_get_cstr(h->ua)); + if (h->profile_url) + http_header_add(qh, "X-Mbuni-Profile-Url", octstr_get_cstr(h->profile_url)); + sprintf(tbuf, "%ld", time(NULL)); + http_header_add(qh, "X-Mbuni-Timestamp", tbuf); /* record time of message. */ + debug("proxy.sendinterface", 0, " Client sent us: "); -#if 1 +#if 0 mms_msgdump(m,1); /* octstr_dump(h->body, 0); */ #endif @@ -495,13 +502,11 @@ static void sendmms_proxy(MmsHTTPClientInfo *h) List *to = gwlist_create(); Octstr *subject = NULL; time_t expiryt, deliveryt; - Octstr *otransid = NULL, *value = NULL, *msgid = NULL; int dlr; char *mmbox_store_status = NULL; Octstr *mmbox_loc = NULL; Octstr *sdf = NULL; - mms_collect_envdata_from_msgheaders(mh, &to, &subject, &otransid, &expiryt, &deliveryt, settings->default_msgexpiry); @@ -551,14 +556,12 @@ static void sendmms_proxy(MmsHTTPClientInfo *h) octstr_case_compare(value, octstr_imm("Yes")) == 0) dlr = 1; else - dlr = 0; - - + dlr = 0; qf = mms_queue_add(from, to, subject, NULL, NULL, deliveryt, expiryt, m, NULL, NULL, NULL, NULL, NULL, - NULL, + qh, dlr, octstr_get_cstr(settings->global_queuedir), settings->host_alias); @@ -585,28 +588,16 @@ static void sendmms_proxy(MmsHTTPClientInfo *h) mms_replace_header_value(mresp, "X-Mms-Content-Location", octstr_get_cstr(mmbox_loc)); - } - - if (otransid) - octstr_destroy(otransid); - if (value) - octstr_destroy(value); + } + octstr_destroy(otransid); + octstr_destroy(value); + octstr_destroy(msgid); + octstr_destroy(mmbox_loc); + octstr_destroy(sdf); + octstr_destroy(from); + octstr_destroy(subject); + http_destroy_headers(mh); - if (msgid) - octstr_destroy(msgid); - - if (mmbox_loc) - octstr_destroy(mmbox_loc); - - if (sdf) - octstr_destroy(sdf); - - if (from) - octstr_destroy(from); - if (subject) - octstr_destroy(subject); - if (mh) - http_destroy_headers(mh); gwlist_destroy(to, (gwlist_item_destructor_t *)octstr_destroy); notify_cmd = "sent"; @@ -689,8 +680,6 @@ static void sendmms_proxy(MmsHTTPClientInfo *h) } { /* Found it, etc. */ - - Octstr *pfrom = mms_get_header_value(mfwd, octstr_imm("From")); Octstr *pdate = mms_get_header_value(mfwd, octstr_imm("Date")); Octstr *pmsgid = mms_get_header_value(mfwd, octstr_imm("Message-ID")); @@ -752,7 +741,7 @@ static void sendmms_proxy(MmsHTTPClientInfo *h) NULL, NULL, deliveryt, expiryt, mfwd, NULL, NULL, NULL, NULL, NULL, - NULL, + qh, dlr, octstr_get_cstr(settings->global_queuedir), settings->host_alias); @@ -969,7 +958,7 @@ static void sendmms_proxy(MmsHTTPClientInfo *h) time(NULL) + settings->default_msgexpiry, mrpt, NULL, NULL, NULL, NULL, NULL, - NULL, + qh, 0, octstr_get_cstr(settings->global_queuedir), settings->host_alias); @@ -1025,7 +1014,7 @@ static void sendmms_proxy(MmsHTTPClientInfo *h) m, NULL, NULL, NULL, NULL, NULL, - NULL, + qh, 0, octstr_get_cstr(settings->global_queuedir), settings->host_alias); @@ -1142,13 +1131,10 @@ static void sendmms_proxy(MmsHTTPClientInfo *h) store_done: - if (xstate) - octstr_destroy(xstate); + octstr_destroy(xstate); if (xflags) - gwlist_destroy(xflags, (gwlist_item_destructor_t *)octstr_destroy); - - if (mstore) - mms_destroy(mstore); + gwlist_destroy(xflags, (gwlist_item_destructor_t *)octstr_destroy); + mms_destroy(mstore); if (e) { /* Update the message queue and go. */ e->lastaccess = time(NULL); @@ -1157,23 +1143,13 @@ static void sendmms_proxy(MmsHTTPClientInfo *h) e = NULL; } - if (qf) - octstr_destroy(qf); - if (token) - octstr_destroy(token); - if (mh) - http_destroy_headers(mh); - if (otransid) - octstr_destroy(otransid); - if (url) - octstr_destroy(url); - - - if (mmbox_loc) - octstr_destroy(mmbox_loc); - - if (sdf) - octstr_destroy(sdf); + octstr_destroy(qf); + octstr_destroy(token); + http_destroy_headers(mh); + octstr_destroy(otransid); + octstr_destroy(url); + octstr_destroy(mmbox_loc); + octstr_destroy(sdf); reply_body = mms_tobinary(mresp); notify_cmd = "stored"; @@ -1514,20 +1490,19 @@ static void sendmms_proxy(MmsHTTPClientInfo *h) done: #if 1 - if (mresp) - mms_msgdump(mresp, 0); -#endif - if (mresp) - mms_destroy(mresp); + mms_msgdump(mresp, 0); +#endif + + + mms_destroy(mresp); if (!ctype_set) http_header_add(rh, "Content-Type", "application/vnd.wap.mms-message"); http_send_reply(h->client, hstatus, rh, reply_body); http_destroy_headers(rh); - if (reply_body) - octstr_destroy(reply_body); - + octstr_destroy(reply_body); + http_destroy_headers(qh); free_clientInfo(h,1); } @@ -1611,7 +1586,7 @@ static void mm7soap_dispatch(MmsHTTPClientInfo *h) 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); + mm7_get_envelope(mreq, &from, &to, &subject, &vasid, &expiryt, &delivert, NULL, NULL); m = mm7_soap_to_mmsmsg(mreq, from ? from : sender); if (m) { Octstr *value = NULL; @@ -1629,7 +1604,7 @@ static void mm7soap_dispatch(MmsHTTPClientInfo *h) if (expiryt < 0) expiryt = time(NULL) + settings->default_msgexpiry; - + mms_remove_headers(m, "Message-ID"); /* cannot be found here. */ qf = mms_queue_add(from ? from : sender, to, subject, NULL, NULL, delivert, expiryt, m, NULL, @@ -1642,8 +1617,7 @@ static void mm7soap_dispatch(MmsHTTPClientInfo *h) msgid = mms_maketransid(octstr_get_cstr(qf), settings->host_alias); mms_log("Received", from ? from : sender, to, -1, msgid, h->vasp->id, NULL, "MM7", h->ua, NULL); - if (value) - octstr_destroy(value); + octstr_destroy(value); } else { error(0, "Failed to convert received MM7/SOAP SubmitReq message from vasp=%s to MMS Message!", octstr_get_cstr(h->vasp->id)); @@ -1696,11 +1670,9 @@ static void mm7soap_dispatch(MmsHTTPClientInfo *h) 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); + + mms_destroy(new); + mms_destroy(old); http_destroy_headers(hh); } } else { @@ -1829,6 +1801,7 @@ static void mm7eaif_dispatch(MmsHTTPClientInfo *h) goto done; } + mms_remove_headers(m, "Message-ID"); mh = mms_message_headers(m); /* Now get sender and receiver data. * for now we ignore adaptation flags.