pluggable mmsc types
This commit is contained in:
parent
970badf660
commit
e76995ab27
|
@ -1,3 +1,5 @@
|
|||
2007-09-18 P. A. Bagyenda <bagyenda@dsmagic.com>
|
||||
* Support for custom MM7 MMC types using a loadable module.
|
||||
2007-09-17 P. A. Bagyenda <bagyenda@dsmagic.com>
|
||||
* Added pluggable MMSBOX routing using loadable module or shell script (see mmsbox_resolve.h)
|
||||
2007-09-14 P. A. Bagyenda <bagyenda@dsmagic.com>
|
||||
|
|
|
@ -2100,8 +2100,10 @@ Supported configuration parameters are:
|
|||
</td>
|
||||
<td valign=top >
|
||||
Mandatory:
|
||||
Protocol spoken by this MMSC, one of <tt>soap</tt> (for 3GPP MM7
|
||||
SOAP) or <tt>eaif</tt> for Nokia EAIF protocol.
|
||||
Protocol spoken by this MMSC, one of <tt>soap</tt> for 3GPP MM7
|
||||
SOAP, <tt>eaif</tt> for Nokia EAIF protocol or <tt>custom</tt> for
|
||||
a custom implementation handled by a loadable module (see
|
||||
<tt>mmsc-library</tt> below)
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
|
@ -2315,6 +2317,36 @@ string
|
|||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td valign=top >
|
||||
<tt>mmsc-library</tt>
|
||||
</td>
|
||||
<td valign=top >
|
||||
String
|
||||
</td>
|
||||
<td valign=top >
|
||||
If MMC type is <tt>custom</tt>, this parameter provides the dynamic
|
||||
shared object (DSO) library to be loaded to provide connectivity to
|
||||
the MMC. (See <tt>mmsbox_mmsc.h</tt> for details on required
|
||||
exported symbols.)
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td valign=top >
|
||||
<tt>custom-settings</tt>
|
||||
</td>
|
||||
<td valign=top >
|
||||
String
|
||||
</td>
|
||||
<td valign=top >
|
||||
If MMC type is <tt>custom</tt>, this parameter provides settings to
|
||||
be provided to the dynamic
|
||||
shared object (DSO) library loaded to provide connectivity to
|
||||
the MMC. (See <tt>mmsbox_mmsc.h</tt> for details on how this is used.)
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
|
||||
|
||||
|
|
|
@ -795,17 +795,16 @@ static void pgdeliver(List *item_list)
|
|||
while ((d = gwlist_consume(item_list)) != NULL) {
|
||||
MmsEnvelope *e = pgq_queue_readenvelope(d->qf, d->dir, 0);
|
||||
int res;
|
||||
time_t tnow = time(NULL);
|
||||
|
||||
if (e && e->sendt <= tnow) {
|
||||
if (e) { /* no need to check time -- it was checked in queue runner, so we know it's time to send.*/
|
||||
debug("pgqueue_run", 0, "Queued entry %s/%s to thread %ld",
|
||||
d->dir, d->qf, gwthread_self());
|
||||
res = d->deliver(e);
|
||||
|
||||
if (res != 1)
|
||||
pgq_free_envelope(e, 0);
|
||||
} else if (e)
|
||||
pgq_free_envelope(e, 0);
|
||||
}
|
||||
|
||||
gw_free(d);
|
||||
}
|
||||
/* we're done, exit. */
|
||||
|
|
|
@ -140,6 +140,8 @@ MULTI_GROUP(mmsc,
|
|||
OCTSTR(mm7-mt-filter-params)
|
||||
OCTSTR(reroute)
|
||||
OCTSTR(reroute-mmsc-id)
|
||||
OCTSTR(mmsc-library)
|
||||
OCTSTR(custom-settings)
|
||||
)
|
||||
|
||||
MULTI_GROUP(mms-service,
|
||||
|
|
|
@ -1033,6 +1033,12 @@ static int fixup_msg(MmsMsg *m, Octstr *from)
|
|||
} else
|
||||
octstr_destroy(s);
|
||||
|
||||
/* check for transaction ID. */
|
||||
if ((s = http_header_value(m->headers, octstr_imm("X-Mms-Transaction-ID"))) == NULL) {
|
||||
if (m->message_type != MMS_MSGTYPE_RETRIEVE_CONF)
|
||||
http_header_add(m->headers, "X-Mms-Transaction-ID", "00001");
|
||||
octstr_destroy(s);
|
||||
}
|
||||
#if 0 /* This will be done elsewhere. */
|
||||
/* Check for msgid, put in if missing. */
|
||||
if ((s = http_header_value(m->headers, octstr_imm("Message-ID"))) == NULL)
|
||||
|
|
|
@ -4,4 +4,4 @@ bin_PROGRAMS = mmsbox
|
|||
mmsbox_SOURCES = mmsbox.c mmsbox_cfg.c dlr.c bearerbox.c mmsbox_resolve.c mmsbox_resolve_shell.c
|
||||
mmsbox_LDADD = $(libmms)
|
||||
|
||||
EXTRA_DIST = mmsbox_cfg.h mmsbox.h mmsbox_mt_filter.h mmsbox_resolve.h
|
||||
EXTRA_DIST = mmsbox_cfg.h mmsbox.h mmsbox_mt_filter.h mmsbox_resolve.h mmsbox_mmsc.h
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* MMSC handler functions: Receive and send MMS messages to MMSCs
|
||||
*
|
||||
* Copyright (C) 2003 - 2005, Digital Solutions Ltd. - http://www.dsmagic.com
|
||||
* Copyright (C) 2003 - 2007, Digital Solutions Ltd. - http://www.dsmagic.com
|
||||
*
|
||||
* Paul Bagyenda <bagyenda@dsmagic.com>
|
||||
*
|
||||
|
@ -74,7 +74,7 @@ done:
|
|||
return res;
|
||||
}
|
||||
|
||||
static int send_report(Octstr *from, char *report_type,
|
||||
int mmsbox_send_report(Octstr *from, char *report_type,
|
||||
Octstr *dlr_url, Octstr *status,
|
||||
Octstr *msgid, Octstr *mmc_id, Octstr *mmc_gid,
|
||||
Octstr *orig_transid, Octstr *uaprof,
|
||||
|
@ -257,7 +257,7 @@ static void mm7soap_receive(MmsHTTPClientInfo *h)
|
|||
info(0, "Sending delivery-report [FROM:%s] [VALUE:%s] [DESC:%s] [MSGID:%s]",
|
||||
octstr_get_cstr(from), octstr_get_cstr(value), octstr_get_cstr(desc),
|
||||
octstr_get_cstr(h->m->id));
|
||||
send_report(from, "delivery-report", NULL,
|
||||
mmsbox_send_report(from, "delivery-report", NULL,
|
||||
value, msgid, h->m->id, h->m->group_id, NULL, uaprof, uaprof_tstamp);
|
||||
|
||||
mms_log("DeliveryReport",
|
||||
|
@ -293,7 +293,7 @@ static void mm7soap_receive(MmsHTTPClientInfo *h)
|
|||
Octstr *value = mm7_soap_header_value(mreq, octstr_imm("MMStatus"));
|
||||
msgid = mm7_soap_header_value(mreq, octstr_imm("MessageID"));
|
||||
|
||||
send_report(from,
|
||||
mmsbox_send_report(from,
|
||||
"read-report", NULL, value, msgid,
|
||||
h->m->id, h->m->group_id, NULL, uaprof, uaprof_tstamp);
|
||||
|
||||
|
@ -475,7 +475,7 @@ static void mm7eaif_receive(MmsHTTPClientInfo *h)
|
|||
} else {
|
||||
Octstr *value = http_header_value(mh, octstr_imm("X-Mms-Status"));
|
||||
Octstr *value2 = http_header_value(mh, octstr_imm("Message-ID"));
|
||||
send_report(hfrom, "delivery-report", NULL, value, value2, h->m->id, h->m->group_id, NULL, NULL, -1);
|
||||
mmsbox_send_report(hfrom, "delivery-report", NULL, value, value2, h->m->id, h->m->group_id, NULL, NULL, -1);
|
||||
|
||||
octstr_destroy(value);
|
||||
octstr_destroy(value2);
|
||||
|
@ -503,7 +503,7 @@ static void mm7eaif_receive(MmsHTTPClientInfo *h)
|
|||
} else {
|
||||
Octstr *value = http_header_value(mh, octstr_imm("X-Mms-Read-Status"));
|
||||
Octstr *value2 = http_header_value(mh, octstr_imm("Message-ID"));
|
||||
send_report(hfrom, "read-report", NULL, value, value2, h->m->id,
|
||||
mmsbox_send_report(hfrom, "read-report", NULL, value, value2, h->m->id,
|
||||
h->m->group_id, NULL, NULL, -1);
|
||||
|
||||
|
||||
|
@ -556,7 +556,7 @@ void mmsc_receive_func(MmscGrp *m)
|
|||
m->incoming.port);
|
||||
|
||||
/* Dump headers, url etc. */
|
||||
#if 1
|
||||
#if 0
|
||||
http_header_dump(h.headers);
|
||||
if (h.body) octstr_dump(h.body, 0);
|
||||
if (h.ip) octstr_dump(h.ip, 0);
|
||||
|
@ -848,6 +848,10 @@ static int mms_sendtommsc(MmscGrp *mmc, Octstr *from, Octstr *to, Octstr *transi
|
|||
id = mm7soap_send(mmc, from, to, transid, linkedid, vasid, service_code, hdrs, m, err, &retry);
|
||||
else if (mmc->type == EAIF_MMSC)
|
||||
id = mm7eaif_send(mmc, from, to, transid, vasid, hdrs, m, err, &retry);
|
||||
else if (mmc->type == CUSTOM_MMSC && mmc->custom_started)
|
||||
id = mmc->fns->send_msg(mmc->data,
|
||||
from, to, transid, linkedid, vasid,
|
||||
service_code, m, hdrs, err, &retry);
|
||||
else
|
||||
error(0, "MMC[%s] of unknown type, can't send!",
|
||||
mmc->id ? octstr_get_cstr(mmc->id) : "");
|
||||
|
@ -931,11 +935,11 @@ static int sendMsg(MmsEnvelope *e)
|
|||
done:
|
||||
if (res == MMS_SEND_OK) {
|
||||
to->process = 0;
|
||||
send_report(to->rcpt, "delivery-report", e->url1,
|
||||
mmsbox_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",
|
||||
mmsbox_send_report(to->rcpt, "delivery-report",
|
||||
e->url1,
|
||||
(e->expiryt != 0 && e->expiryt < tnow) ?
|
||||
octstr_imm("Expired") : octstr_imm("Rejected"),
|
||||
|
|
|
@ -29,15 +29,18 @@ static void quit_now(int notused)
|
|||
MmscGrp *mmc;
|
||||
rstop = 1;
|
||||
|
||||
/* Close all MMSC http ports, kill all MMSC threads, kill sendmms port... */
|
||||
|
||||
/* Close all MMSC http ports, kill all MMSC threads, kill sendmms port... */
|
||||
if (sendmms_port.port > 0)
|
||||
http_close_port(sendmms_port.port);
|
||||
|
||||
for (i = 0, n = gwlist_len(mmscs); i < n; i++)
|
||||
if ((mmc = gwlist_get(mmscs, i)) != NULL &&
|
||||
mmc->incoming.port > 0)
|
||||
http_close_port(mmc->incoming.port);
|
||||
if ((mmc = gwlist_get(mmscs, i)) != NULL) {
|
||||
if (mmc->type == CUSTOM_MMSC && mmc->fns && mmc->custom_started) {
|
||||
mmc->fns->stop_conn(mmc->data);
|
||||
mmc->custom_started = 0;
|
||||
} else if (mmc->incoming.port > 0)
|
||||
http_close_port(mmc->incoming.port);
|
||||
}
|
||||
}
|
||||
|
||||
/* manage the SIGHUP signal */
|
||||
|
|
|
@ -18,6 +18,11 @@ extern int rstop;
|
|||
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);
|
||||
int mmsbox_send_report(Octstr *from, char *report_type,
|
||||
Octstr *dlr_url, Octstr *status,
|
||||
Octstr *msgid, Octstr *mmc_id, Octstr *mmc_gid,
|
||||
Octstr *orig_transid, Octstr *uaprof,
|
||||
time_t uaprof_tstamp);
|
||||
void mmsc_receive_func(MmscGrp *m);
|
||||
void mmsbox_outgoing_queue_runner(int *rstop);
|
||||
|
||||
|
|
|
@ -215,7 +215,13 @@ int mms_load_mmsbox_settings(mCfg *cfg, gwthread_func_t *mmsc_handler_func)
|
|||
m->type = EAIF_MMSC;
|
||||
else if (octstr_case_compare(type, octstr_imm("soap")) == 0)
|
||||
m->type = SOAP_MMSC;
|
||||
else
|
||||
else if (octstr_case_compare(type, octstr_imm("custom")) == 0) {
|
||||
m->type = CUSTOM_MMSC;
|
||||
m->settings = _mms_cfg_getx(x, octstr_imm("custom-settings"));
|
||||
/* also load the libary. */
|
||||
if ((m->fns = _mms_load_module(x, "mmsc-library", "mmsc_funcs", NULL)) == NULL)
|
||||
panic(0, "failed to load MMSC libary functions from module!");
|
||||
} else
|
||||
warning(0, "MMSBox: Unknown MMSC type [%s]!",
|
||||
octstr_get_cstr(type));
|
||||
if ((xver = _mms_cfg_getx(x, octstr_imm("mm7-version"))) != NULL &&
|
||||
|
@ -244,22 +250,6 @@ int mms_load_mmsbox_settings(mCfg *cfg, gwthread_func_t *mmsc_handler_func)
|
|||
octstr_destroy(xver);
|
||||
octstr_destroy(type);
|
||||
|
||||
if (m->incoming.port > 0 &&
|
||||
http_open_port(m->incoming.port, ssl) < 0) {
|
||||
warning(0, "MMSBox: Failed to start HTTP server on receive port for "
|
||||
" MMSC %s, port %ld: %s!",
|
||||
octstr_get_cstr(m->id), m->incoming.port,
|
||||
strerror(errno));
|
||||
m->incoming.port = 0; /* so we don't listen on it. */
|
||||
}
|
||||
|
||||
if (mmsc_handler_func && m->incoming.port > 0) { /* Only start threads if func passed and ... */
|
||||
if ((m->threadid = gwthread_create(mmsc_handler_func, m)) < 0)
|
||||
error(0, "MMSBox: Failed to start MMSC handler thread for MMSC[%s]: %s!",
|
||||
octstr_get_cstr(m->id), strerror(errno));
|
||||
} else
|
||||
m->threadid = -1;
|
||||
|
||||
/* Init for filter. */
|
||||
if ((s = mms_cfg_get(x, octstr_imm("mm7-mt-filter-params"))) != NULL) {
|
||||
if (mt_filter)
|
||||
|
@ -281,6 +271,32 @@ int mms_load_mmsbox_settings(mCfg *cfg, gwthread_func_t *mmsc_handler_func)
|
|||
warning(0, "MMSBox: reroute-mmsc-id parameter set but reroute=false!");
|
||||
|
||||
m->mutex = mutex_create();
|
||||
|
||||
/* finally start the thingie. */
|
||||
if (m->type == CUSTOM_MMSC) {
|
||||
if (m->fns->start_conn(m, qfs, &m->data) != 0) {
|
||||
warning(0, "MMSBox: Failed to start custom MMSC [%s]", octstr_get_cstr(m->id));
|
||||
m->custom_started = 0;
|
||||
} else
|
||||
m->custom_started = 1;
|
||||
} else {
|
||||
if (m->incoming.port > 0 &&
|
||||
http_open_port(m->incoming.port, ssl) < 0) {
|
||||
warning(0, "MMSBox: Failed to start HTTP server on receive port for "
|
||||
" MMSC %s, port %ld: %s!",
|
||||
octstr_get_cstr(m->id), m->incoming.port,
|
||||
strerror(errno));
|
||||
m->incoming.port = 0; /* so we don't listen on it. */
|
||||
}
|
||||
|
||||
if (mmsc_handler_func && m->incoming.port > 0) { /* Only start threads if func passed and ... */
|
||||
if ((m->threadid = gwthread_create(mmsc_handler_func, m)) < 0)
|
||||
error(0, "MMSBox: Failed to start MMSC handler thread for MMSC[%s]: %s!",
|
||||
octstr_get_cstr(m->id), strerror(errno));
|
||||
} else
|
||||
m->threadid = -1;
|
||||
}
|
||||
|
||||
gwlist_append(mmscs, m);
|
||||
}
|
||||
gwlist_destroy(l, NULL);
|
||||
|
@ -468,9 +484,6 @@ MmscGrp *get_handler_mmc(Octstr *id, Octstr *to)
|
|||
Octstr *get_mmsbox_queue_dir(Octstr *from, List *to, MmscGrp *m,
|
||||
Octstr **mmc_id) {
|
||||
|
||||
*mmc_id = octstr_imm("local");
|
||||
return outgoing_qdir;
|
||||
|
||||
if (m->reroute) {
|
||||
*mmc_id = octstr_duplicate(m->reroute_mmsc_id);
|
||||
return outgoing_qdir;
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* MMSBOX CFG: MMC configuration and misc. 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 <bagyenda@dsmagic.com>
|
||||
*
|
||||
|
@ -17,6 +17,8 @@
|
|||
#include "mms_queue.h"
|
||||
#include "mmsbox_resolve.h"
|
||||
|
||||
#include "mmsbox_mmsc.h"
|
||||
|
||||
typedef struct MmscGrp {
|
||||
Octstr *id; /* MMSC id (for logging). */
|
||||
Octstr *group_id; /* GROUP MMSC id (used for qf). */
|
||||
|
@ -28,7 +30,7 @@ typedef struct MmscGrp {
|
|||
long port;
|
||||
} incoming; /* user, pass, port (and whether SSL) that MMSC uses to connect to us. */
|
||||
Octstr *allowed_prefix, *denied_prefix;
|
||||
enum {UNKNOWN_MMSC, SOAP_MMSC, EAIF_MMSC} type; /* type of connection. */
|
||||
enum {UNKNOWN_MMSC = -1, CUSTOM_MMSC, SOAP_MMSC, EAIF_MMSC} type; /* type of connection. */
|
||||
long throughput; /* Max send rate. */
|
||||
long threadid; /* handler thread. */
|
||||
|
||||
|
@ -37,6 +39,11 @@ typedef struct MmscGrp {
|
|||
MM7Version_t ver; /* supported MM7/SOAP version. */
|
||||
int use_mt_filter; /* whether to use MT filter on this connection. */
|
||||
Mutex *mutex;
|
||||
|
||||
MmsBoxMmscFuncs *fns; /* pointer to functions for handling this mmsc connection type */
|
||||
Octstr *settings; /* settings for the above module. */
|
||||
void *data; /* data for above module. */
|
||||
int custom_started; /* set to 1 if custom mmc started. */
|
||||
} MmscGrp;
|
||||
|
||||
typedef struct MmsServiceUrlParam {
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Mbuni - Open Source MMS Gateway
|
||||
*
|
||||
* MMSBOX Custom MMSC types: MMC function definitions
|
||||
*
|
||||
* Copyright (C) 2003 - 2007, Digital Solutions Ltd. - http://www.dsmagic.com
|
||||
*
|
||||
* Paul Bagyenda <bagyenda@dsmagic.com>
|
||||
*
|
||||
* This program is free software, distributed under the terms of
|
||||
* the GNU General Public License, with a few exceptions granted (see LICENSE)
|
||||
*/
|
||||
#ifndef __MMSBOX_MMSC_CFG_INCLUDED__
|
||||
#define __MMSBOX_MMSC_CFG_INCLUDED__
|
||||
#include "mms_util.h"
|
||||
#include "mms_queue.h"
|
||||
struct MmscGrp; /* so we compile. */
|
||||
typedef struct MmsBoxMmscFuncs {
|
||||
/* start_conn: called once with the module settings, ID of the connection
|
||||
* and a pointer where to store module specific info.
|
||||
* should return 0 on success, -1 on error.
|
||||
*/
|
||||
int (*start_conn)(struct MmscGrp *mmc, MmsQueueHandlerFuncs *qfs, void **data);
|
||||
|
||||
/* stop_conn: Called to stop the MMC connection. */
|
||||
int (*stop_conn)(void *data);
|
||||
|
||||
/* send_msg: called to send a message. Should msg ID if any. On error,
|
||||
* retry can be set to 1 for sending to be retried later.
|
||||
* Should set err to the error message (if any).
|
||||
*/
|
||||
Octstr *(*send_msg)(void *data, Octstr *from, Octstr *to,
|
||||
Octstr *transid,
|
||||
Octstr *linkedid, char *vasid, Octstr *service_code,
|
||||
MmsMsg *m, List *hdrs, Octstr **err, int *retry);
|
||||
|
||||
} MmsBoxMmscFuncs;
|
||||
|
||||
extern MmsBoxMmscFuncs mmsc_funcs; /* lib should expose this structure. */
|
||||
#endif
|
Loading…
Reference in New Issue