From 2df07d549db99e8aeb829308311f420bd7ee2f85 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Tue, 11 Dec 2012 18:30:19 +0100 Subject: mgw: Implement the specific RSIP handling The RSIP has morphed from a global reset, to a per trunk reset and now it is possible to reset specific ranges on a trunk. This will be used by the ISUP filter code in the STP. For legacy range == -1 will be used. This will reset all endpoints on the trunk. Use OSMO_MAX on endpoint and number of endpoints in case number_endpoints is 0. This code will now free everything from the endpoint to endpoint + range including endpoint+range. --- include/mgcp/mgcp.h | 2 +- src/mgcp/mgcp_protocol.c | 18 +++++++++++++++++- src/mgcp_ss7.c | 40 ++++++++++++++++++++++++++++++---------- 3 files changed, 48 insertions(+), 12 deletions(-) diff --git a/include/mgcp/mgcp.h b/include/mgcp/mgcp.h index ad88bfd..6ac3896 100644 --- a/include/mgcp/mgcp.h +++ b/include/mgcp/mgcp.h @@ -82,7 +82,7 @@ struct mgcp_trunk_config; typedef int (*mgcp_realloc)(struct mgcp_trunk_config *cfg, int endpoint); typedef int (*mgcp_change)(struct mgcp_trunk_config *cfg, int endpoint, int state); typedef int (*mgcp_policy)(struct mgcp_trunk_config *cfg, int endpoint, int state, const char *transactio_id); -typedef int (*mgcp_reset)(struct mgcp_trunk_config *cfg); +typedef int (*mgcp_reset)(struct mgcp_trunk_config *cfg, int endpoint, int range); typedef int (*mgcp_rqnt)(struct mgcp_endpoint *endp, char tone); #define PORT_ALLOC_STATIC 0 diff --git a/src/mgcp/mgcp_protocol.c b/src/mgcp/mgcp_protocol.c index be6ec00..f847caf 100644 --- a/src/mgcp/mgcp_protocol.c +++ b/src/mgcp/mgcp_protocol.c @@ -860,13 +860,29 @@ out_silent: static struct msgb *handle_rsip(struct mgcp_parse_data *p) { + int range = -1; + const char *line; + if (p->found != 0) { LOGP(DMGCP, LOGL_ERROR, "Failed to find the endpoint.\n"); return NULL; } + for_each_line(line, p->save) { + if (strlen(line) < 4) + continue; + + switch (line[0]) { + case 'R': + range = atoi(line + 3); + break; + } + } + + if (p->cfg->reset_cb) - p->cfg->reset_cb(p->endp->tcfg); + p->cfg->reset_cb(p->endp->tcfg, + ENDPOINT_NUMBER(p->endp), range); return NULL; } diff --git a/src/mgcp_ss7.c b/src/mgcp_ss7.c index 46cd185..fd64732 100644 --- a/src/mgcp_ss7.c +++ b/src/mgcp_ss7.c @@ -60,7 +60,7 @@ static int exit_on_failure = 0; extern struct mgcp_config *g_cfg; -static void mgcp_ss7_reset(struct mgcp_trunk_config *tcfg); +static void mgcp_ss7_reset(struct mgcp_trunk_config *tcfg, int endpoint, int range); static void mgcp_ss7_endp_free(struct mgcp_endpoint *endp); @@ -766,9 +766,25 @@ static void mgcp_ss7_endp_free(struct mgcp_endpoint *endp) mgcp_ss7_exec(endp, MGCP_SS7_DELETE, 0); } -static int reset_cb(struct mgcp_trunk_config *trunk) +static int reset_cb(struct mgcp_trunk_config *trunk, int _endpoint, int _range) { - mgcp_ss7_reset(trunk); + int endpoint, range; + + if (_range < -1) { + LOGP(DMGCP, LOGL_ERROR, "Range is invalid: %d\n", _range); + return -1; + } + + if (_range == -1) { + endpoint = 1; + range = OSMO_MAX(endpoint, trunk->number_endpoints - 1); + } else { + endpoint = _endpoint; + range = OSMO_MIN(_endpoint + _range, trunk->number_endpoints - 1); + } + + + mgcp_ss7_reset(trunk, endpoint, range); return 0; } @@ -880,24 +896,28 @@ static struct mgcp_ss7 *mgcp_ss7_init(struct mgcp_config *cfg) return conf; } -static void free_trunk(struct mgcp_trunk_config *trunk) +/* range must be < number_endpoints, it includes the endpoint */ +static void free_trunk(struct mgcp_trunk_config *trunk, + const int start, const int range) { int i; - for (i = 1; i < trunk->number_endpoints; ++i) { + for (i = start; i <= range; ++i) { struct mgcp_endpoint *endp = &trunk->endpoints[i]; mgcp_ss7_endp_free(endp); mgcp_free_endp(endp); } } -static void mgcp_ss7_reset(struct mgcp_trunk_config *tcfg) +static void mgcp_ss7_reset(struct mgcp_trunk_config *tcfg, int start, int range) { - LOGP(DMGCP, LOGL_INFO, "Resetting endpoint on trunk type %s %s/%d\n", - tcfg->trunk_type == MGCP_TRUNK_VIRTUAL ? "virtual" : "e1", - tcfg->virtual_domain, tcfg->trunk_nr); + LOGP(DMGCP, LOGL_INFO, + "Resetting endpoints(%d to %d) on trunk type %s %s/%d\n", + start, range, + tcfg->trunk_type == MGCP_TRUNK_VIRTUAL ? "virtual" : "e1", + tcfg->virtual_domain, tcfg->trunk_nr); /* free UniPorte and MGCP data */ - free_trunk(tcfg); + free_trunk(tcfg, start, range); } static void print_help() -- cgit v1.2.3