[Asterisk-cvs] asterisk/channels chan_mgcp.c,1.50,1.51
markster at lists.digium.com
markster at lists.digium.com
Fri May 21 01:52:25 CDT 2004
Update of /usr/cvsroot/asterisk/channels
In directory mongoose.digium.com:/tmp/cvs-serv10186/channels
Modified Files:
chan_mgcp.c
Log Message:
First pass at handling responses properly for retransmissions
Index: chan_mgcp.c
===================================================================
RCS file: /usr/cvsroot/asterisk/channels/chan_mgcp.c,v
retrieving revision 1.50
retrieving revision 1.51
diff -u -d -r1.50 -r1.51
--- chan_mgcp.c 20 May 2004 16:30:10 -0000 1.50
+++ chan_mgcp.c 21 May 2004 06:05:20 -0000 1.51
@@ -280,6 +280,16 @@
unsigned char buf[0];
};
+#define RESPONSE_TIMEOUT 30 /* in seconds */
+
+struct mgcp_response {
+ time_t whensent;
+ int len;
+ int seqno;
+ struct mgcp_response *next;
+ unsigned char buf[0];
+};
+
#define MAX_SUBS 2
#define SUB_REAL 0
@@ -405,6 +415,7 @@
ast_mutex_t msgs_lock; /* SC: queue lock */
int retransid; /* SC: retrans timer id */
int delme; /* SC: needed for reload */
+ struct mgcp_response *responses;
struct mgcp_gateway *next;
} *gateways;
@@ -478,6 +489,19 @@
return res;
}
+static int resend_response(struct mgcp_subchannel *sub, struct mgcp_response *resp)
+{
+ struct mgcp_endpoint *p = sub->parent;
+ int res;
+ if (mgcpdebug) {
+ ast_verbose("Retransmitting:\n%s\n to %s:%d\n", resp->buf, inet_ntoa(p->parent->addr.sin_addr), ntohs(p->parent->addr.sin_port));
+ }
+ res = __mgcp_xmit(p->parent, resp->buf, resp->len);
+ if (res > 0)
+ res = 0;
+ return res;
+}
+
static int send_response(struct mgcp_subchannel *sub, struct mgcp_request *req)
{
struct mgcp_endpoint *p = sub->parent;
@@ -1774,7 +1798,20 @@
{
struct mgcp_request resp;
struct mgcp_endpoint *p = sub->parent;
+ struct mgcp_response *mgr;
respprep(&resp, p, msg, req, msgrest);
+ mgr = malloc(sizeof(struct mgcp_response) + resp.len + 1);
+ if (mgr) {
+ /* Store MGCP response in case we have to retransmit */
+ memset(mgr, 0, sizeof(struct mgcp_response));
+ sscanf(req->identifier, "%d", &mgr->seqno);
+ time(&mgr->whensent);
+ mgr->len = resp.len;
+ memcpy(mgr->buf, resp.data, resp.len);
+ mgr->buf[resp.len] = '\0';
+ mgr->next = p->parent->responses;
+ p->parent->responses = mgr->next;
+ }
return send_response(sub, &resp);
}
@@ -3036,6 +3073,38 @@
return 0;
}
+static int find_and_retrans(struct mgcp_subchannel *sub, struct mgcp_request *req)
+{
+ int seqno=0;
+ time_t now;
+ struct mgcp_response *prev = NULL, *cur, *next, *answer=NULL;
+ time(&now);
+ if (sscanf(req->identifier, "%d", &seqno) != 1)
+ seqno = 0;
+ cur = sub->parent->parent->responses;
+ while(cur) {
+ next = cur->next;
+ if (now - cur->whensent > RESPONSE_TIMEOUT) {
+ /* Delete this entry */
+ if (prev)
+ prev->next = next;
+ else
+ sub->parent->parent->responses = next;
+ free(cur);
+ } else {
+ if (seqno == cur->seqno)
+ answer = cur;
+ prev = cur;
+ }
+ cur = next;
+ }
+ if (answer) {
+ resend_response(sub, answer);
+ return 1;
+ }
+ return 0;
+}
+
static int mgcpsock_read(int *id, int fd, short events, void *ignore)
{
struct mgcp_request req;
@@ -3079,7 +3148,7 @@
ast_mutex_lock(&gw->msgs_lock);
for (prev = NULL, cur = gw->msgs; cur; prev = cur, cur = cur->next) {
if (cur->seqno == ident) {
- ast_log(LOG_DEBUG, "Got response back on tansaction %d\n", ident);
+ ast_log(LOG_DEBUG, "Got response back on transaction %d\n", ident);
if (prev)
prev->next = cur->next;
else
@@ -3115,8 +3184,10 @@
/* Process request, with iflock held */
sub = find_subchannel(req.endpoint, 0, &sin);
if (sub) {
- /* pass the request off to the currently mastering subchannel */
- handle_request(sub, &req, &sin);
+ /* look first to find a matching response in the queue */
+ if (!find_and_retrans(sub, &req))
+ /* pass the request off to the currently mastering subchannel */
+ handle_request(sub, &req, &sin);
}
}
return 1;
More information about the svn-commits
mailing list