aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormarkster <markster@f38db490-d61c-443f-a65b-d21fe96a405b>2004-03-27 17:51:22 +0000
committermarkster <markster@f38db490-d61c-443f-a65b-d21fe96a405b>2004-03-27 17:51:22 +0000
commit301d109812345481ecefd837995bdb74df1157e6 (patch)
tree0d18fc59174818aacee70f0a7df6e2f1fdce2d35
parente8980010c274e1d520f476361a24af3c6ae23479 (diff)
Merge more Sentito contributions (thanks serkan)
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@2575 f38db490-d61c-443f-a65b-d21fe96a405b
-rwxr-xr-xchannels/chan_mgcp.c82
1 files changed, 74 insertions, 8 deletions
diff --git a/channels/chan_mgcp.c b/channels/chan_mgcp.c
index b06f020d6..8cc71b289 100755
--- a/channels/chan_mgcp.c
+++ b/channels/chan_mgcp.c
@@ -182,7 +182,8 @@ static int adsi = 0;
static int usecnt =0;
static ast_mutex_t usecnt_lock = AST_MUTEX_INITIALIZER;
-static int oseq;
+/* SC: transaction id should always be positive */
+static unsigned int oseq;
/* Wait up to 16 seconds for first digit (FXO logic) */
static int firstdigittimeout = 16000;
@@ -235,7 +236,7 @@ struct mgcp_request {
char *line[MGCP_MAX_LINES];
char data[MGCP_MAX_PACKET];
int cmd; /* SC: int version of verb = command */
- int trid; /* SC: int version of identifier = transaction id */
+ unsigned int trid; /* SC: int version of identifier = transaction id */
struct mgcp_request *next; /* SC: next in the queue */
};
@@ -406,7 +407,7 @@ static int transmit_connection_del(struct mgcp_subchannel *sub);
static int transmit_audit_endpoint(struct mgcp_endpoint *p);
static void start_rtp(struct mgcp_subchannel *sub);
static void handle_response(struct mgcp_endpoint *p, struct mgcp_subchannel *sub,
- int result, int ident, struct mgcp_request *resp);
+ int result, unsigned int ident, struct mgcp_request *resp);
static void dump_cmd_queues(struct mgcp_endpoint *p, struct mgcp_subchannel *sub);
static int mgcp_do_reload(void);
static int mgcp_reload(int fd, int argc, char *argv[]);
@@ -484,7 +485,7 @@ static void dump_queue(struct mgcp_gateway *gw, struct mgcp_endpoint *p)
else
gw->msgs = cur->next;
- ast_log(LOG_NOTICE, "Removing message from %s tansaction %d\n",
+ ast_log(LOG_NOTICE, "Removing message from %s tansaction %u\n",
gw->name, cur->seqno);
w = cur;
@@ -534,7 +535,7 @@ static int retrans_pkt(void *data)
if (cur->retrans < MAX_RETRANS) {
cur->retrans++;
if (mgcpdebug) {
- ast_verbose("Retransmitting #%d transaction %d on [%s]\n", cur->retrans, cur->seqno, gw->name);
+ ast_verbose("Retransmitting #%d transaction %u on [%s]\n", cur->retrans, cur->seqno, gw->name);
}
__mgcp_xmit(gw, cur->buf, cur->len);
@@ -547,7 +548,7 @@ static int retrans_pkt(void *data)
else
gw->msgs = cur->next;
- ast_log(LOG_WARNING, "Maximum retries exceeded for transaction %d on [%s]\n", cur->seqno, gw->name);
+ ast_log(LOG_WARNING, "Maximum retries exceeded for transaction %u on [%s]\n", cur->seqno, gw->name);
w = cur;
cur = cur->next;
@@ -1291,6 +1292,28 @@ static char *get_header(struct mgcp_request *req, char *name)
return __get_header(req, name, &start);
}
+/* SC: get comma separated value */
+static char *get_csv(char *c, int *len, char **next)
+{
+ char *s;
+
+ *next = NULL, *len = 0;
+ if (!c) return NULL;
+
+ while(*c && (*c < 33 || *c == ','))
+ c++;
+
+ s = c;
+ while(*c && (*c >= 33 && *c != ','))
+ c++, (*len)++;
+ *next = c;
+
+ if (*len == 0)
+ s = NULL, *next = NULL;
+
+ return s;
+}
+
#if 0
static int rtpready(struct ast_rtp *rtp, struct ast_frame *f, void *data)
{
@@ -2048,6 +2071,26 @@ static int transmit_connection_del(struct mgcp_subchannel *sub)
return send_request(p, sub, &resp, oseq); /* SC */
}
+static int transmit_connection_del_w_params(struct mgcp_endpoint *p, char *callid, char *cxident)
+{
+ struct mgcp_request resp;
+ if (mgcpdebug) {
+ ast_verbose(VERBOSE_PREFIX_3 "Delete connection %s %s@%s on callid: %s\n",
+ cxident ? cxident : "", p->name, p->parent->name, callid ? callid : "");
+ }
+ reqprep(&resp, p, "DLCX");
+ /* SC: check if call id is avail */
+ if (callid && *callid)
+ add_header(&resp, "C", callid);
+ /* SC: check if cxident is avail */
+ if (cxident && *cxident)
+ add_header(&resp, "I", cxident);
+ /* SC: fill in new fields */
+ resp.cmd = MGCP_CMD_DLCX;
+ resp.trid = oseq;
+ return send_request(p, p->sub, &resp, oseq);
+}
+
/* SC: cleanup pendng commands */
static void dump_cmd_queues(struct mgcp_endpoint *p, struct mgcp_subchannel *sub)
{
@@ -2116,7 +2159,7 @@ static struct mgcp_request *find_command(struct mgcp_endpoint *p, struct mgcp_su
/* SC: modified for new transport mechanism */
static void handle_response(struct mgcp_endpoint *p, struct mgcp_subchannel *sub,
- int result, int ident, struct mgcp_request *resp)
+ int result, unsigned int ident, struct mgcp_request *resp)
{
char *c;
struct mgcp_request *req;
@@ -2208,6 +2251,29 @@ static void handle_response(struct mgcp_endpoint *p, struct mgcp_subchannel *sub
}
if (req->cmd == MGCP_CMD_AUEP) {
+ /* SC: check stale connection ids */
+ if ((c = get_header(resp, "I"))) {
+ char *v, *n;
+ int len;
+ while ((v = get_csv(c, &len, &n))) {
+ if (len) {
+ if(strncasecmp(v, p->sub->cxident, len) &&
+ strncasecmp(v, p->sub->next->cxident, len)) {
+ /* connection id not found. delete it */
+ char cxident[80];
+ memcpy(cxident, v, len);
+ cxident[len] = '\0';
+ if (option_verbose > 2) {
+ ast_verbose(VERBOSE_PREFIX_3 "Non existing connection id %s on %s@%s \n",
+ cxident, p->name, gw->name);
+ }
+ transmit_connection_del_w_params(p, NULL, cxident);
+ }
+ }
+ c = n;
+ }
+ }
+
/* Try to determine the hookstate returned from an audit endpoint command */
if ((c = get_header(resp, "ES"))) {
if (strlen(c)) {
@@ -2241,7 +2307,7 @@ static void handle_response(struct mgcp_endpoint *p, struct mgcp_subchannel *sub
}
}
}
- }
+ }
}
if (resp && resp->lines) {