Merge branch 'on-waves/mgcp'
This commit is contained in:
commit
637b4f6b7f
|
@ -73,5 +73,6 @@ struct mgcp_msg_ptr {
|
||||||
int mgcp_analyze_header(struct mgcp_config *cfg, struct msgb *msg,
|
int mgcp_analyze_header(struct mgcp_config *cfg, struct msgb *msg,
|
||||||
struct mgcp_msg_ptr *ptr, int size,
|
struct mgcp_msg_ptr *ptr, int size,
|
||||||
const char **transaction_id, struct mgcp_endpoint **endp);
|
const char **transaction_id, struct mgcp_endpoint **endp);
|
||||||
|
int mgcp_send_dummy(struct mgcp_endpoint *endp);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -128,6 +128,15 @@ static int mgcp_rsip_cb(struct mgcp_config *cfg)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int mgcp_change_cb(struct mgcp_config *cfg, int endpoint, int state, int local_rtp)
|
||||||
|
{
|
||||||
|
if (state != MGCP_ENDP_MDCX)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
mgcp_send_dummy(&cfg->endpoints[endpoint]);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int read_call_agent(struct bsc_fd *fd, unsigned int what)
|
static int read_call_agent(struct bsc_fd *fd, unsigned int what)
|
||||||
{
|
{
|
||||||
struct sockaddr_in addr;
|
struct sockaddr_in addr;
|
||||||
|
@ -200,6 +209,7 @@ int main(int argc, char** argv)
|
||||||
|
|
||||||
/* set some callbacks */
|
/* set some callbacks */
|
||||||
cfg->reset_cb = mgcp_rsip_cb;
|
cfg->reset_cb = mgcp_rsip_cb;
|
||||||
|
cfg->change_cb = mgcp_change_cb;
|
||||||
|
|
||||||
/* we need to bind a socket */
|
/* we need to bind a socket */
|
||||||
if (rc == 0) {
|
if (rc == 0) {
|
||||||
|
|
|
@ -73,6 +73,8 @@ enum {
|
||||||
PROTO_RTCP,
|
PROTO_RTCP,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define DUMMY_LOAD 0x23
|
||||||
|
|
||||||
|
|
||||||
static int udp_send(int fd, struct in_addr *addr, int port, char *buf, int len)
|
static int udp_send(int fd, struct in_addr *addr, int port, char *buf, int len)
|
||||||
{
|
{
|
||||||
|
@ -84,6 +86,14 @@ static int udp_send(int fd, struct in_addr *addr, int port, char *buf, int len)
|
||||||
return sendto(fd, buf, len, 0, (struct sockaddr *)&out, sizeof(out));
|
return sendto(fd, buf, len, 0, (struct sockaddr *)&out, sizeof(out));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int mgcp_send_dummy(struct mgcp_endpoint *endp)
|
||||||
|
{
|
||||||
|
static char buf[] = { DUMMY_LOAD };
|
||||||
|
|
||||||
|
return udp_send(endp->local_rtp.fd, &endp->remote,
|
||||||
|
endp->net_rtp, buf, 1);
|
||||||
|
}
|
||||||
|
|
||||||
static void patch_payload(int payload, char *data, int len)
|
static void patch_payload(int payload, char *data, int len)
|
||||||
{
|
{
|
||||||
struct rtp_hdr *rtp_hdr;
|
struct rtp_hdr *rtp_hdr;
|
||||||
|
@ -161,9 +171,17 @@ static int rtp_data_cb(struct bsc_fd *fd, unsigned int what)
|
||||||
LOGP(DMGCP, LOGL_NOTICE, "Found BTS for endpoint: 0x%x on port: %d/%d of %s\n",
|
LOGP(DMGCP, LOGL_NOTICE, "Found BTS for endpoint: 0x%x on port: %d/%d of %s\n",
|
||||||
ENDPOINT_NUMBER(endp), ntohs(endp->bts_rtp), ntohs(endp->bts_rtcp),
|
ENDPOINT_NUMBER(endp), ntohs(endp->bts_rtp), ntohs(endp->bts_rtcp),
|
||||||
inet_ntoa(addr.sin_addr));
|
inet_ntoa(addr.sin_addr));
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* throw away dummy message */
|
||||||
|
if (rc == 1 && buf[0] == DUMMY_LOAD) {
|
||||||
|
LOGP(DMGCP, LOGL_NOTICE, "Filtered dummy on 0x%x\n",
|
||||||
|
ENDPOINT_NUMBER(endp));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* do this before the loop handling */
|
/* do this before the loop handling */
|
||||||
if (dest == DEST_NETWORK)
|
if (dest == DEST_NETWORK)
|
||||||
++endp->in_bts;
|
++endp->in_bts;
|
||||||
|
|
|
@ -389,6 +389,7 @@ static struct msgb *handle_create_con(struct mgcp_config *cfg, struct msgb *msg)
|
||||||
if (cfg->force_realloc) {
|
if (cfg->force_realloc) {
|
||||||
LOGP(DMGCP, LOGL_NOTICE, "Endpoint 0x%x already allocated. Forcing realloc.\n",
|
LOGP(DMGCP, LOGL_NOTICE, "Endpoint 0x%x already allocated. Forcing realloc.\n",
|
||||||
ENDPOINT_NUMBER(endp));
|
ENDPOINT_NUMBER(endp));
|
||||||
|
mgcp_free_endp(endp);
|
||||||
} else {
|
} else {
|
||||||
LOGP(DMGCP, LOGL_ERROR, "Endpoint is already used. 0x%x\n",
|
LOGP(DMGCP, LOGL_ERROR, "Endpoint is already used. 0x%x\n",
|
||||||
ENDPOINT_NUMBER(endp));
|
ENDPOINT_NUMBER(endp));
|
||||||
|
@ -485,6 +486,7 @@ static struct msgb *handle_modify_con(struct mgcp_config *cfg, struct msgb *msg)
|
||||||
const char *trans_id;
|
const char *trans_id;
|
||||||
struct mgcp_endpoint *endp;
|
struct mgcp_endpoint *endp;
|
||||||
int error_code = 500;
|
int error_code = 500;
|
||||||
|
int silent = 0;
|
||||||
|
|
||||||
found = mgcp_analyze_header(cfg, msg, data_ptrs, ARRAY_SIZE(data_ptrs), &trans_id, &endp);
|
found = mgcp_analyze_header(cfg, msg, data_ptrs, ARRAY_SIZE(data_ptrs), &trans_id, &endp);
|
||||||
if (found != 0)
|
if (found != 0)
|
||||||
|
@ -517,6 +519,9 @@ static struct msgb *handle_modify_con(struct mgcp_config *cfg, struct msgb *msg)
|
||||||
goto error3;
|
goto error3;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case 'Z':
|
||||||
|
silent = strcmp("noanswer", (const char *)&msg->l3h[line_start + 3]) == 0;
|
||||||
|
break;
|
||||||
case '\0':
|
case '\0':
|
||||||
/* SDP file begins */
|
/* SDP file begins */
|
||||||
break;
|
break;
|
||||||
|
@ -562,6 +567,8 @@ static struct msgb *handle_modify_con(struct mgcp_config *cfg, struct msgb *msg)
|
||||||
case MGCP_POLICY_REJECT:
|
case MGCP_POLICY_REJECT:
|
||||||
LOGP(DMGCP, LOGL_NOTICE, "MDCX rejected by policy on 0x%x\n",
|
LOGP(DMGCP, LOGL_NOTICE, "MDCX rejected by policy on 0x%x\n",
|
||||||
ENDPOINT_NUMBER(endp));
|
ENDPOINT_NUMBER(endp));
|
||||||
|
if (silent)
|
||||||
|
goto out_silent;
|
||||||
return create_response(500, "MDCX", trans_id);
|
return create_response(500, "MDCX", trans_id);
|
||||||
break;
|
break;
|
||||||
case MGCP_POLICY_DEFER:
|
case MGCP_POLICY_DEFER:
|
||||||
|
@ -579,6 +586,9 @@ static struct msgb *handle_modify_con(struct mgcp_config *cfg, struct msgb *msg)
|
||||||
ENDPOINT_NUMBER(endp), inet_ntoa(endp->remote), ntohs(endp->net_rtp));
|
ENDPOINT_NUMBER(endp), inet_ntoa(endp->remote), ntohs(endp->net_rtp));
|
||||||
if (cfg->change_cb)
|
if (cfg->change_cb)
|
||||||
cfg->change_cb(cfg, ENDPOINT_NUMBER(endp), MGCP_ENDP_MDCX, endp->rtp_port);
|
cfg->change_cb(cfg, ENDPOINT_NUMBER(endp), MGCP_ENDP_MDCX, endp->rtp_port);
|
||||||
|
if (silent)
|
||||||
|
goto out_silent;
|
||||||
|
|
||||||
return create_response_with_sdp(endp, "MDCX", trans_id);
|
return create_response_with_sdp(endp, "MDCX", trans_id);
|
||||||
|
|
||||||
error:
|
error:
|
||||||
|
@ -589,6 +599,10 @@ error:
|
||||||
|
|
||||||
error3:
|
error3:
|
||||||
return create_response(error_code, "MDCX", trans_id);
|
return create_response(error_code, "MDCX", trans_id);
|
||||||
|
|
||||||
|
|
||||||
|
out_silent:
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct msgb *handle_delete_con(struct mgcp_config *cfg, struct msgb *msg)
|
static struct msgb *handle_delete_con(struct mgcp_config *cfg, struct msgb *msg)
|
||||||
|
@ -598,6 +612,7 @@ static struct msgb *handle_delete_con(struct mgcp_config *cfg, struct msgb *msg)
|
||||||
const char *trans_id;
|
const char *trans_id;
|
||||||
struct mgcp_endpoint *endp;
|
struct mgcp_endpoint *endp;
|
||||||
int error_code = 500;
|
int error_code = 500;
|
||||||
|
int silent = 0;
|
||||||
|
|
||||||
found = mgcp_analyze_header(cfg, msg, data_ptrs, ARRAY_SIZE(data_ptrs), &trans_id, &endp);
|
found = mgcp_analyze_header(cfg, msg, data_ptrs, ARRAY_SIZE(data_ptrs), &trans_id, &endp);
|
||||||
if (found != 0)
|
if (found != 0)
|
||||||
|
@ -619,6 +634,9 @@ static struct msgb *handle_delete_con(struct mgcp_config *cfg, struct msgb *msg)
|
||||||
if (verify_ci(endp, (const char *)&msg->l3h[line_start + 3]) != 0)
|
if (verify_ci(endp, (const char *)&msg->l3h[line_start + 3]) != 0)
|
||||||
goto error3;
|
goto error3;
|
||||||
break;
|
break;
|
||||||
|
case 'Z':
|
||||||
|
silent = strcmp("noanswer", (const char *)&msg->l3h[line_start + 3]) == 0;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
LOGP(DMGCP, LOGL_NOTICE, "Unhandled option: '%c'/%d on 0x%x\n",
|
LOGP(DMGCP, LOGL_NOTICE, "Unhandled option: '%c'/%d on 0x%x\n",
|
||||||
|
@ -634,6 +652,8 @@ static struct msgb *handle_delete_con(struct mgcp_config *cfg, struct msgb *msg)
|
||||||
case MGCP_POLICY_REJECT:
|
case MGCP_POLICY_REJECT:
|
||||||
LOGP(DMGCP, LOGL_NOTICE, "DLCX rejected by policy on 0x%x\n",
|
LOGP(DMGCP, LOGL_NOTICE, "DLCX rejected by policy on 0x%x\n",
|
||||||
ENDPOINT_NUMBER(endp));
|
ENDPOINT_NUMBER(endp));
|
||||||
|
if (silent)
|
||||||
|
goto out_silent;
|
||||||
return create_response(500, "DLCX", trans_id);
|
return create_response(500, "DLCX", trans_id);
|
||||||
break;
|
break;
|
||||||
case MGCP_POLICY_DEFER:
|
case MGCP_POLICY_DEFER:
|
||||||
|
@ -647,10 +667,14 @@ static struct msgb *handle_delete_con(struct mgcp_config *cfg, struct msgb *msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* free the connection */
|
/* free the connection */
|
||||||
|
LOGP(DMGCP, LOGL_NOTICE, "Deleted endpoint on: 0x%x Server: %s:%u\n",
|
||||||
|
ENDPOINT_NUMBER(endp), inet_ntoa(endp->remote), ntohs(endp->net_rtp));
|
||||||
mgcp_free_endp(endp);
|
mgcp_free_endp(endp);
|
||||||
if (cfg->change_cb)
|
if (cfg->change_cb)
|
||||||
cfg->change_cb(cfg, ENDPOINT_NUMBER(endp), MGCP_ENDP_DLCX, endp->rtp_port);
|
cfg->change_cb(cfg, ENDPOINT_NUMBER(endp), MGCP_ENDP_DLCX, endp->rtp_port);
|
||||||
|
|
||||||
|
if (silent)
|
||||||
|
goto out_silent;
|
||||||
return create_response(250, "DLCX", trans_id);
|
return create_response(250, "DLCX", trans_id);
|
||||||
|
|
||||||
error:
|
error:
|
||||||
|
@ -661,6 +685,9 @@ error:
|
||||||
|
|
||||||
error3:
|
error3:
|
||||||
return create_response(error_code, "DLCX", trans_id);
|
return create_response(error_code, "DLCX", trans_id);
|
||||||
|
|
||||||
|
out_silent:
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct msgb *handle_rsip(struct mgcp_config *cfg, struct msgb *msg)
|
static struct msgb *handle_rsip(struct mgcp_config *cfg, struct msgb *msg)
|
||||||
|
|
Loading…
Reference in New Issue