diff options
author | matteo <matteo@f38db490-d61c-443f-a65b-d21fe96a405b> | 2003-03-15 06:00:16 +0000 |
---|---|---|
committer | matteo <matteo@f38db490-d61c-443f-a65b-d21fe96a405b> | 2003-03-15 06:00:16 +0000 |
commit | 30610b61ae18888f54ae12b9cef4a95917e969e6 (patch) | |
tree | 5852502480f57f1aa5563287316be8a59e437af3 /channels | |
parent | 24c1f82b133befef1fd6008db6126baff33cd158 (diff) |
Sat Mar 15 07:00:01 CET 2003
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@645 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'channels')
-rwxr-xr-x | channels/chan_mgcp.c | 97 |
1 files changed, 83 insertions, 14 deletions
diff --git a/channels/chan_mgcp.c b/channels/chan_mgcp.c index 49d823b00..d2bb1304a 100755 --- a/channels/chan_mgcp.c +++ b/channels/chan_mgcp.c @@ -109,6 +109,14 @@ static struct mgcp_pkt { struct mgcp_pkt *next; } *packets = NULL; +/* MGCP message for queuing up */ +struct mgcp_message { + unsigned int seqno; + int len; + struct mgcp_message *next; + unsigned char buf[0]; +}; + #define TYPE_TRUNK 1 #define TYPE_LINE 2 @@ -141,6 +149,8 @@ struct mgcp_endpoint { struct ast_channel *owner; struct ast_rtp *rtp; struct sockaddr_in tmpdest; + struct mgcp_message *msgs; /* Message queue */ + int messagepending; struct mgcp_endpoint *next; struct mgcp_gateway *parent; }; @@ -194,12 +204,52 @@ static int send_response(struct mgcp_endpoint *p, struct mgcp_request *req) return res; } -static int send_request(struct mgcp_endpoint *p, struct mgcp_request *req) +static void dump_queue(struct mgcp_endpoint *p) +{ + struct mgcp_message *cur; + while(p->msgs) { + cur = p->msgs; + p->msgs = p->msgs->next; + free(cur); + } + p->messagepending = 0; + p->msgs = NULL; +} + +static int mgcp_postrequest(struct mgcp_endpoint *p, unsigned char *data, int len, unsigned int seqno) +{ + struct mgcp_message *msg = malloc(sizeof(struct mgcp_message) + len); + struct mgcp_message *cur; + if (!msg) + return -1; + msg->seqno = seqno; + msg->next = NULL; + msg ->len = len; + memcpy(msg->buf, data, msg->len); + cur = p->msgs; + if (cur) { + while(cur->next) + cur = cur->next; + cur->next = msg; + } else + p->msgs = msg; + if (!p->messagepending) { + p->messagepending = 1; + p->lastout = seqno; + __mgcp_xmit(p, msg->buf, msg->len); + /* XXX Should schedule retransmission XXX */ + } else + ast_log(LOG_DEBUG, "Deferring transmission of transaction %d\n", seqno); + return 0; +} + +static int send_request(struct mgcp_endpoint *p, struct mgcp_request *req, unsigned int seqno) { int res; if (mgcpdebug) - ast_verbose("XXX Need to handle Retransmitting XXX:\n%s to %s:%d\n", req->data, inet_ntoa(p->parent->addr.sin_addr), ntohs(p->parent->addr.sin_port)); - res = __mgcp_xmit(p, req->data, req->len); + ast_verbose("Posting Request:\n%s to %s:%d\n", req->data, inet_ntoa(p->parent->addr.sin_addr), ntohs(p->parent->addr.sin_port)); + + res = mgcp_postrequest(p, req->data, req->len, seqno); return res; } @@ -861,8 +911,7 @@ static int process_sdp(struct mgcp_endpoint *p, struct mgcp_request *req) sin.sin_family = AF_INET; memcpy(&sin.sin_addr, hp->h_addr, sizeof(sin.sin_addr)); sin.sin_port = htons(portno); - if (p->rtp) - ast_rtp_set_peer(p->rtp, &sin); + ast_rtp_set_peer(p->rtp, &sin); #if 0 printf("Peer RTP is at port %s:%d\n", inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); #endif @@ -1127,8 +1176,7 @@ static int transmit_modify_with_sdp(struct mgcp_endpoint *p, struct ast_rtp *rtp add_header(&resp, "I", p->cxident); add_header(&resp, "S", ""); add_sdp(&resp, p, rtp); - p->lastout = oseq; - return send_request(p, &resp); + return send_request(p, &resp, oseq); } static int transmit_connect_with_sdp(struct mgcp_endpoint *p, struct ast_rtp *rtp) @@ -1151,8 +1199,7 @@ static int transmit_connect_with_sdp(struct mgcp_endpoint *p, struct ast_rtp *rt add_header(&resp, "X", p->txident); add_header(&resp, "S", ""); add_sdp(&resp, p, rtp); - p->lastout = oseq; - return send_request(p, &resp); + return send_request(p, &resp, oseq); } static int transmit_notify_request(struct mgcp_endpoint *p, char *tone, int offhook) @@ -1166,7 +1213,7 @@ static int transmit_notify_request(struct mgcp_endpoint *p, char *tone, int offh else add_header(&resp, "R", "hd(N)"); add_header(&resp, "S", tone); - return send_request(p, &resp); + return send_request(p, &resp, oseq); } static int transmit_notify_request_with_callerid(struct mgcp_endpoint *p, char *tone, int offhook, char *callerid) @@ -1206,7 +1253,7 @@ static int transmit_notify_request_with_callerid(struct mgcp_endpoint *p, char * else add_header(&resp, "R", "hd(N)"); add_header(&resp, "S", tone2); - return send_request(p, &resp); + return send_request(p, &resp, oseq); } static int transmit_connection_del(struct mgcp_endpoint *p) { @@ -1214,11 +1261,28 @@ static int transmit_connection_del(struct mgcp_endpoint *p) reqprep(&resp, p, "DLCX"); add_header(&resp, "C", p->callid); add_header(&resp, "I", p->cxident); - return send_request(p, &resp); + return send_request(p, &resp, oseq); } static void handle_response(struct mgcp_endpoint *p, int result, int ident) { + struct mgcp_message *cur; + if (p->msgs && (p->msgs->seqno == ident)) { + ast_log(LOG_DEBUG, "Got response back on tansaction %d\n", ident); + cur = p->msgs; + p->msgs = p->msgs->next; + free(cur); + if (p->msgs) { + /* Send next pending message if appropriate */ + p->messagepending = 1; + p->lastout = p->msgs->seqno; + __mgcp_xmit(p, p->msgs->buf, p->msgs->len); + /* XXX Should schedule retransmission XXX */ + } else + p->messagepending = 0; + } else { + ast_log(LOG_NOTICE, "Got response back on transaction %d we aren't sending? (current = %d)\n", ident, p->msgs ? p->msgs->seqno : -1); + } if ((result >= 400) && (result <= 499)) { ast_log(LOG_NOTICE, "Terminating on result %d from %s@%s\n", result, p->name, p->parent->name); if (p->owner) @@ -1299,6 +1363,7 @@ static int handle_request(struct mgcp_endpoint *p, struct mgcp_request *req, str ast_verbose("Handling request '%s' on %s@%s\n", req->verb, p->name, p->parent->name); /* Clear out potential response */ if (!strcasecmp(req->verb, "RSIP")) { + dump_queue(p); if (option_verbose > 2) ast_verbose(VERBOSE_PREFIX_3 "Resetting interface %s@%s\n", p->name, p->parent->name); if (p->owner) @@ -1413,8 +1478,12 @@ static int mgcpsock_read(int *id, int fd, short events, void *ignore) } } } - if (req.lines) - process_sdp(p, &req); + if (req.lines) { + if (!p->rtp) + start_rtp(p); + if (p->rtp) + process_sdp(p, &req); + } } } else { if (!req.endpoint || !strlen(req.endpoint) || |