mgcp: Introduce a mgcp_trunk_config enum for endpoint configs

We want to support real trunks in the MGCP code and we need to
have some better book keeping for those. Move the code around.
This commit is contained in:
Holger Hans Peter Freyther 2011-02-28 00:56:17 +01:00
parent dfdf8d929a
commit 88ad7723b4
9 changed files with 130 additions and 94 deletions

View File

@ -1,8 +1,8 @@
/* A Media Gateway Control Protocol Media Gateway: RFC 3435 */ /* A Media Gateway Control Protocol Media Gateway: RFC 3435 */
/* /*
* (C) 2009-2010 by Holger Hans Peter Freyther <zecke@selfish.org> * (C) 2009-2011 by Holger Hans Peter Freyther <zecke@selfish.org>
* (C) 2009-2010 by On-Waves * (C) 2009-2011 by On-Waves
* All Rights Reserved * All Rights Reserved
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
@ -63,6 +63,7 @@ static inline int rtp_calculate_port(int multiplex, int base)
*/ */
struct mgcp_endpoint; struct mgcp_endpoint;
struct mgcp_config; struct mgcp_config;
struct mgcp_trunk_config;
#define MGCP_ENDP_CRCX 1 #define MGCP_ENDP_CRCX 1
#define MGCP_ENDP_DLCX 2 #define MGCP_ENDP_DLCX 2
@ -78,9 +79,9 @@ struct mgcp_config;
#define MGCP_POLICY_REJECT 5 #define MGCP_POLICY_REJECT 5
#define MGCP_POLICY_DEFER 6 #define MGCP_POLICY_DEFER 6
typedef int (*mgcp_realloc)(struct mgcp_config *cfg, int endpoint); typedef int (*mgcp_realloc)(struct mgcp_trunk_config *cfg, int endpoint);
typedef int (*mgcp_change)(struct mgcp_config *cfg, int endpoint, int state); typedef int (*mgcp_change)(struct mgcp_trunk_config *cfg, int endpoint, int state);
typedef int (*mgcp_policy)(struct mgcp_config *cfg, int endpoint, int state, const char *transactio_id); typedef int (*mgcp_policy)(struct mgcp_trunk_config *cfg, int endpoint, int state, const char *transactio_id);
typedef int (*mgcp_reset)(struct mgcp_config *cfg); typedef int (*mgcp_reset)(struct mgcp_config *cfg);
#define PORT_ALLOC_STATIC 0 #define PORT_ALLOC_STATIC 0
@ -101,18 +102,31 @@ struct mgcp_port_range {
int last_port; int last_port;
}; };
struct mgcp_trunk_config {
struct mgcp_config *cfg;
int trunk_nr;
int trunk_type;
char *audio_name;
int audio_payload;
int audio_loop;
/* spec handling */
int force_realloc;
unsigned int number_endpoints;
struct mgcp_endpoint *endpoints;
};
struct mgcp_config { struct mgcp_config {
int source_port; int source_port;
char *local_ip; char *local_ip;
char *source_addr; char *source_addr;
unsigned int number_endpoints;
char *bts_ip; char *bts_ip;
char *call_agent_addr; char *call_agent_addr;
struct in_addr bts_in; struct in_addr bts_in;
char *audio_name;
int audio_payload;
int audio_loop;
/* transcoder handling */ /* transcoder handling */
char *transcoder_ip; char *transcoder_ip;
@ -126,17 +140,16 @@ struct mgcp_config {
struct mgcp_port_range transcoder_ports; struct mgcp_port_range transcoder_ports;
int endp_dscp; int endp_dscp;
/* spec handling */
int force_realloc;
mgcp_change change_cb; mgcp_change change_cb;
mgcp_policy policy_cb; mgcp_policy policy_cb;
mgcp_reset reset_cb; mgcp_reset reset_cb;
mgcp_realloc realloc_cb; mgcp_realloc realloc_cb;
void *data; void *data;
struct mgcp_endpoint *endpoints;
uint32_t last_call_id; uint32_t last_call_id;
/* trunk handling */
struct mgcp_trunk_config trunk;
}; };
/* config management */ /* config management */

View File

@ -1,8 +1,8 @@
/* MGCP Private Data */ /* MGCP Private Data */
/* /*
* (C) 2009-2010 by Holger Hans Peter Freyther <zecke@selfish.org> * (C) 2009-2011 by Holger Hans Peter Freyther <zecke@selfish.org>
* (C) 2009-2010 by On-Waves * (C) 2009-2011 by On-Waves
* All Rights Reserved * All Rights Reserved
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
@ -35,6 +35,11 @@ enum mgcp_connection_mode {
MGCP_CONN_LOOPBACK = 4, MGCP_CONN_LOOPBACK = 4,
}; };
enum mgcp_trunk_type {
MGCP_TRUNK_VIRTUAL,
MGCP_TRUNK_E1,
};
struct mgcp_rtp_state { struct mgcp_rtp_state {
int initialized; int initialized;
int patch; int patch;
@ -93,6 +98,7 @@ struct mgcp_endpoint {
/* backpointer */ /* backpointer */
struct mgcp_config *cfg; struct mgcp_config *cfg;
struct mgcp_trunk_config *tcfg;
/* port status for bts/net */ /* port status for bts/net */
struct mgcp_rtp_end bts_end; struct mgcp_rtp_end bts_end;
@ -118,7 +124,7 @@ struct mgcp_endpoint {
struct mgcp_rtp_tap taps[MGCP_TAP_COUNT]; struct mgcp_rtp_tap taps[MGCP_TAP_COUNT];
}; };
#define ENDPOINT_NUMBER(endp) abs(endp - endp->cfg->endpoints) #define ENDPOINT_NUMBER(endp) abs(endp - endp->tcfg->endpoints)
struct mgcp_msg_ptr { struct mgcp_msg_ptr {
unsigned int start; unsigned int start;

View File

@ -126,7 +126,7 @@ 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) static int mgcp_change_cb(struct mgcp_trunk_config *cfg, int endpoint, int state)
{ {
if (state != MGCP_ENDP_MDCX) if (state != MGCP_ENDP_MDCX)
return 0; return 0;
@ -172,8 +172,8 @@ static int read_call_agent(struct bsc_fd *fd, unsigned int what)
reset_endpoints = 0; reset_endpoints = 0;
/* is checking in_addr.s_addr == INADDR_LOOPBACK making it more secure? */ /* is checking in_addr.s_addr == INADDR_LOOPBACK making it more secure? */
for (i = 1; i < cfg->number_endpoints; ++i) for (i = 1; i < cfg->trunk.number_endpoints; ++i)
mgcp_free_endp(&cfg->endpoints[i]); mgcp_free_endp(&cfg->trunk.endpoints[i]);
} }
return 0; return 0;

View File

@ -2,8 +2,8 @@
/* The protocol implementation */ /* The protocol implementation */
/* /*
* (C) 2009-2010 by Holger Hans Peter Freyther <zecke@selfish.org> * (C) 2009-2011 by Holger Hans Peter Freyther <zecke@selfish.org>
* (C) 2009-2010 by On-Waves * (C) 2009-2011 by On-Waves
* All Rights Reserved * All Rights Reserved
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
@ -196,9 +196,9 @@ static int send_transcoder(struct mgcp_rtp_end *end, struct mgcp_config *cfg,
static int send_to(struct mgcp_endpoint *endp, int dest, int is_rtp, static int send_to(struct mgcp_endpoint *endp, int dest, int is_rtp,
struct sockaddr_in *addr, char *buf, int rc) struct sockaddr_in *addr, char *buf, int rc)
{ {
struct mgcp_config *cfg = endp->cfg; struct mgcp_trunk_config *tcfg = endp->tcfg;
/* For loop toggle the destination and then dispatch. */ /* For loop toggle the destination and then dispatch. */
if (cfg->audio_loop) if (tcfg->audio_loop)
dest = !dest; dest = !dest;
/* Loop based on the conn_mode, maybe undoing the above */ /* Loop based on the conn_mode, maybe undoing the above */

View File

@ -105,8 +105,8 @@ static uint32_t generate_call_id(struct mgcp_config *cfg)
/* callstack can only be of size number_of_endpoints */ /* callstack can only be of size number_of_endpoints */
/* verify that the call id is free, e.g. in case of overrun */ /* verify that the call id is free, e.g. in case of overrun */
for (i = 1; i < cfg->number_endpoints; ++i) for (i = 1; i < cfg->trunk.number_endpoints; ++i)
if (cfg->endpoints[i].ci == cfg->last_call_id) if (cfg->trunk.endpoints[i].ci == cfg->last_call_id)
return generate_call_id(cfg); return generate_call_id(cfg);
return cfg->last_call_id; return cfg->last_call_id;
@ -187,7 +187,7 @@ static struct msgb *create_response_with_sdp(struct mgcp_endpoint *endp,
"a=rtpmap:%d %s\r\n", "a=rtpmap:%d %s\r\n",
endp->ci, addr, endp->net_end.local_port, endp->ci, addr, endp->net_end.local_port,
endp->bts_end.payload_type, endp->bts_end.payload_type, endp->bts_end.payload_type, endp->bts_end.payload_type,
endp->cfg->audio_name); endp->tcfg->audio_name);
return mgcp_create_response_with_data(200, " OK", msg, trans_id, sdp_record); return mgcp_create_response_with_data(200, " OK", msg, trans_id, sdp_record);
} }
@ -290,12 +290,12 @@ static struct mgcp_endpoint *find_e1_endpoint(struct mgcp_config *cfg,
return NULL; return NULL;
mgcp_endp = mgcp_timeslot_to_endpoint(trunk - 1, endp); mgcp_endp = mgcp_timeslot_to_endpoint(trunk - 1, endp);
if (mgcp_endp < 1 || mgcp_endp >= cfg->number_endpoints) { if (mgcp_endp < 1 || mgcp_endp >= cfg->trunk.number_endpoints) {
LOGP(DMGCP, LOGL_ERROR, "Failed to find endpoint '%s'\n", mgcp); LOGP(DMGCP, LOGL_ERROR, "Failed to find endpoint '%s'\n", mgcp);
return NULL; return NULL;
} }
return &cfg->endpoints[mgcp_endp]; return &cfg->trunk.endpoints[mgcp_endp];
} }
static struct mgcp_endpoint *find_endpoint(struct mgcp_config *cfg, const char *mgcp) static struct mgcp_endpoint *find_endpoint(struct mgcp_config *cfg, const char *mgcp)
@ -307,8 +307,8 @@ static struct mgcp_endpoint *find_endpoint(struct mgcp_config *cfg, const char *
return find_e1_endpoint(cfg, mgcp); return find_e1_endpoint(cfg, mgcp);
} else { } else {
gw = strtoul(mgcp, &endptr, 16); gw = strtoul(mgcp, &endptr, 16);
if (gw > 0 && gw < cfg->number_endpoints && strcmp(endptr, "@mgw") == 0) if (gw > 0 && gw < cfg->trunk.number_endpoints && strcmp(endptr, "@mgw") == 0)
return &cfg->endpoints[gw]; return &cfg->trunk.endpoints[gw];
} }
LOGP(DMGCP, LOGL_ERROR, "Not able to find endpoint: '%s'\n", mgcp); LOGP(DMGCP, LOGL_ERROR, "Not able to find endpoint: '%s'\n", mgcp);
@ -494,6 +494,7 @@ static struct msgb *handle_create_con(struct mgcp_config *cfg, struct msgb *msg)
struct mgcp_msg_ptr data_ptrs[6]; struct mgcp_msg_ptr data_ptrs[6];
int found, i, line_start; int found, i, line_start;
const char *trans_id; const char *trans_id;
struct mgcp_trunk_config *tcfg;
struct mgcp_endpoint *endp; struct mgcp_endpoint *endp;
int error_code = 400; int error_code = 400;
@ -501,13 +502,15 @@ static struct msgb *handle_create_con(struct mgcp_config *cfg, struct msgb *msg)
if (found != 0) if (found != 0)
return create_err_response(510, "CRCX", trans_id); return create_err_response(510, "CRCX", trans_id);
tcfg = endp->tcfg;
if (endp->allocated) { if (endp->allocated) {
if (cfg->force_realloc) { if (tcfg->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); mgcp_free_endp(endp);
if (cfg->realloc_cb) if (cfg->realloc_cb)
cfg->realloc_cb(cfg, ENDPOINT_NUMBER(endp)); cfg->realloc_cb(tcfg, ENDPOINT_NUMBER(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));
@ -519,11 +522,11 @@ static struct msgb *handle_create_con(struct mgcp_config *cfg, struct msgb *msg)
MSG_TOKENIZE_START MSG_TOKENIZE_START
switch (msg->l3h[line_start]) { switch (msg->l3h[line_start]) {
case 'L': case 'L':
endp->local_options = talloc_strdup(cfg->endpoints, endp->local_options = talloc_strdup(tcfg->endpoints,
(const char *)&msg->l3h[line_start + 3]); (const char *)&msg->l3h[line_start + 3]);
break; break;
case 'C': case 'C':
endp->callid = talloc_strdup(cfg->endpoints, endp->callid = talloc_strdup(tcfg->endpoints,
(const char *)&msg->l3h[line_start + 3]); (const char *)&msg->l3h[line_start + 3]);
break; break;
case 'M': case 'M':
@ -559,11 +562,11 @@ static struct msgb *handle_create_con(struct mgcp_config *cfg, struct msgb *msg)
goto error2; goto error2;
endp->allocated = 1; endp->allocated = 1;
endp->bts_end.payload_type = cfg->audio_payload; endp->bts_end.payload_type = tcfg->audio_payload;
/* policy CB */ /* policy CB */
if (cfg->policy_cb) { if (cfg->policy_cb) {
switch (cfg->policy_cb(cfg, ENDPOINT_NUMBER(endp), MGCP_ENDP_CRCX, trans_id)) { switch (cfg->policy_cb(tcfg, ENDPOINT_NUMBER(endp), MGCP_ENDP_CRCX, trans_id)) {
case MGCP_POLICY_REJECT: case MGCP_POLICY_REJECT:
LOGP(DMGCP, LOGL_NOTICE, "CRCX rejected by policy on 0x%x\n", LOGP(DMGCP, LOGL_NOTICE, "CRCX rejected by policy on 0x%x\n",
ENDPOINT_NUMBER(endp)); ENDPOINT_NUMBER(endp));
@ -585,7 +588,7 @@ static struct msgb *handle_create_con(struct mgcp_config *cfg, struct msgb *msg)
ENDPOINT_NUMBER(endp), endp->ci, ENDPOINT_NUMBER(endp), endp->ci,
endp->net_end.local_port, endp->bts_end.local_port); endp->net_end.local_port, endp->bts_end.local_port);
if (cfg->change_cb) if (cfg->change_cb)
cfg->change_cb(cfg, ENDPOINT_NUMBER(endp), MGCP_ENDP_CRCX); cfg->change_cb(tcfg, ENDPOINT_NUMBER(endp), MGCP_ENDP_CRCX);
create_transcoder(endp); create_transcoder(endp);
return create_response_with_sdp(endp, "CRCX", trans_id); return create_response_with_sdp(endp, "CRCX", trans_id);
@ -686,7 +689,7 @@ static struct msgb *handle_modify_con(struct mgcp_config *cfg, struct msgb *msg)
/* policy CB */ /* policy CB */
if (cfg->policy_cb) { if (cfg->policy_cb) {
switch (cfg->policy_cb(cfg, ENDPOINT_NUMBER(endp), MGCP_ENDP_MDCX, trans_id)) { switch (cfg->policy_cb(endp->tcfg, ENDPOINT_NUMBER(endp), MGCP_ENDP_MDCX, trans_id)) {
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));
@ -708,7 +711,7 @@ static struct msgb *handle_modify_con(struct mgcp_config *cfg, struct msgb *msg)
LOGP(DMGCP, LOGL_DEBUG, "Modified endpoint on: 0x%x Server: %s:%u\n", LOGP(DMGCP, LOGL_DEBUG, "Modified endpoint on: 0x%x Server: %s:%u\n",
ENDPOINT_NUMBER(endp), inet_ntoa(endp->net_end.addr), ntohs(endp->net_end.rtp_port)); ENDPOINT_NUMBER(endp), inet_ntoa(endp->net_end.addr), ntohs(endp->net_end.rtp_port));
if (cfg->change_cb) if (cfg->change_cb)
cfg->change_cb(cfg, ENDPOINT_NUMBER(endp), MGCP_ENDP_MDCX); cfg->change_cb(endp->tcfg, ENDPOINT_NUMBER(endp), MGCP_ENDP_MDCX);
if (silent) if (silent)
goto out_silent; goto out_silent;
@ -771,7 +774,7 @@ static struct msgb *handle_delete_con(struct mgcp_config *cfg, struct msgb *msg)
/* policy CB */ /* policy CB */
if (cfg->policy_cb) { if (cfg->policy_cb) {
switch (cfg->policy_cb(cfg, ENDPOINT_NUMBER(endp), MGCP_ENDP_DLCX, trans_id)) { switch (cfg->policy_cb(endp->tcfg, ENDPOINT_NUMBER(endp), MGCP_ENDP_DLCX, trans_id)) {
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));
@ -797,7 +800,7 @@ static struct msgb *handle_delete_con(struct mgcp_config *cfg, struct msgb *msg)
delete_transcoder(endp); delete_transcoder(endp);
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); cfg->change_cb(endp->tcfg, ENDPOINT_NUMBER(endp), MGCP_ENDP_DLCX);
if (silent) if (silent)
goto out_silent; goto out_silent;
@ -858,13 +861,19 @@ struct mgcp_config *mgcp_config_alloc(void)
cfg->source_port = 2427; cfg->source_port = 2427;
cfg->source_addr = talloc_strdup(cfg, "0.0.0.0"); cfg->source_addr = talloc_strdup(cfg, "0.0.0.0");
cfg->audio_name = talloc_strdup(cfg, "AMR/8000");
cfg->audio_payload = 126;
cfg->transcoder_remote_base = 4000; cfg->transcoder_remote_base = 4000;
cfg->bts_ports.base_port = RTP_PORT_DEFAULT; cfg->bts_ports.base_port = RTP_PORT_DEFAULT;
cfg->net_ports.base_port = RTP_PORT_NET_DEFAULT; cfg->net_ports.base_port = RTP_PORT_NET_DEFAULT;
/* default trunk handling */
cfg->trunk.cfg = cfg;
cfg->trunk.trunk_nr = 0;
cfg->trunk.trunk_type = MGCP_TRUNK_VIRTUAL;
cfg->trunk.audio_name = talloc_strdup(cfg, "AMR/8000");
cfg->trunk.audio_payload = 126;
return cfg; return cfg;
} }
@ -891,22 +900,26 @@ static void mgcp_rtp_end_init(struct mgcp_rtp_end *end)
int mgcp_endpoints_allocate(struct mgcp_config *cfg) int mgcp_endpoints_allocate(struct mgcp_config *cfg)
{ {
struct mgcp_trunk_config *tcfg;
int i; int i;
tcfg = &cfg->trunk;
/* Initialize all endpoints */ /* Initialize all endpoints */
cfg->endpoints = _talloc_zero_array(cfg, tcfg->endpoints = _talloc_zero_array(cfg,
sizeof(struct mgcp_endpoint), sizeof(struct mgcp_endpoint),
cfg->number_endpoints, "endpoints"); tcfg->number_endpoints, "endpoints");
if (!cfg->endpoints) if (!tcfg->endpoints)
return -1; return -1;
for (i = 0; i < cfg->number_endpoints; ++i) { for (i = 0; i < tcfg->number_endpoints; ++i) {
cfg->endpoints[i].ci = CI_UNUSED; tcfg->endpoints[i].ci = CI_UNUSED;
cfg->endpoints[i].cfg = cfg; tcfg->endpoints[i].cfg = cfg;
mgcp_rtp_end_init(&cfg->endpoints[i].net_end); tcfg->endpoints[i].tcfg = tcfg;
mgcp_rtp_end_init(&cfg->endpoints[i].bts_end); mgcp_rtp_end_init(&tcfg->endpoints[i].net_end);
mgcp_rtp_end_init(&cfg->endpoints[i].trans_net); mgcp_rtp_end_init(&tcfg->endpoints[i].bts_end);
mgcp_rtp_end_init(&cfg->endpoints[i].trans_bts); mgcp_rtp_end_init(&tcfg->endpoints[i].trans_net);
mgcp_rtp_end_init(&tcfg->endpoints[i].trans_bts);
} }
return 0; return 0;
@ -971,8 +984,8 @@ static void send_msg(struct mgcp_endpoint *endp, int endpoint, int port,
"m=audio %d RTP/AVP %d\r\n" "m=audio %d RTP/AVP %d\r\n"
"a=rtpmap:%d %s\r\n", "a=rtpmap:%d %s\r\n",
msg, endpoint, mode, endp->cfg->source_addr, msg, endpoint, mode, endp->cfg->source_addr,
port, endp->cfg->audio_payload, port, endp->tcfg->audio_payload,
endp->cfg->audio_payload, endp->cfg->audio_name); endp->tcfg->audio_payload, endp->tcfg->audio_name);
if (len < 0) if (len < 0)
return; return;

View File

@ -2,8 +2,8 @@
/* The protocol implementation */ /* The protocol implementation */
/* /*
* (C) 2009-2010 by Holger Hans Peter Freyther <zecke@selfish.org> * (C) 2009-2011 by Holger Hans Peter Freyther <zecke@selfish.org>
* (C) 2009-2010 by On-Waves * (C) 2009-2011 by On-Waves
* All Rights Reserved * All Rights Reserved
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
@ -69,12 +69,14 @@ static int config_write_mgcp(struct vty *vty)
g_cfg->net_ports.range_start, g_cfg->net_ports.range_end, VTY_NEWLINE); g_cfg->net_ports.range_start, g_cfg->net_ports.range_end, VTY_NEWLINE);
vty_out(vty, " rtp ip-dscp %d%s", g_cfg->endp_dscp, VTY_NEWLINE); vty_out(vty, " rtp ip-dscp %d%s", g_cfg->endp_dscp, VTY_NEWLINE);
if (g_cfg->audio_payload != -1) if (g_cfg->trunk.audio_payload != -1)
vty_out(vty, " sdp audio payload number %d%s", g_cfg->audio_payload, VTY_NEWLINE); vty_out(vty, " sdp audio payload number %d%s",
if (g_cfg->audio_name) g_cfg->trunk.audio_payload, VTY_NEWLINE);
vty_out(vty, " sdp audio payload name %s%s", g_cfg->audio_name, VTY_NEWLINE); if (g_cfg->trunk.audio_name)
vty_out(vty, " loop %u%s", !!g_cfg->audio_loop, VTY_NEWLINE); vty_out(vty, " sdp audio payload name %s%s",
vty_out(vty, " number endpoints %u%s", g_cfg->number_endpoints - 1, VTY_NEWLINE); g_cfg->trunk.audio_name, VTY_NEWLINE);
vty_out(vty, " loop %u%s", !!g_cfg->trunk.audio_loop, VTY_NEWLINE);
vty_out(vty, " number endpoints %u%s", g_cfg->trunk.number_endpoints - 1, VTY_NEWLINE);
if (g_cfg->call_agent_addr) if (g_cfg->call_agent_addr)
vty_out(vty, " call agent ip %s%s", g_cfg->call_agent_addr, VTY_NEWLINE); vty_out(vty, " call agent ip %s%s", g_cfg->call_agent_addr, VTY_NEWLINE);
if (g_cfg->transcoder_ip) if (g_cfg->transcoder_ip)
@ -95,9 +97,10 @@ DEFUN(show_mcgp, show_mgcp_cmd, "show mgcp",
{ {
int i; int i;
vty_out(vty, "MGCP is up and running with %u endpoints:%s", g_cfg->number_endpoints - 1, VTY_NEWLINE); vty_out(vty, "MGCP is up and running with %u endpoints:%s",
for (i = 1; i < g_cfg->number_endpoints; ++i) { g_cfg->trunk.number_endpoints - 1, VTY_NEWLINE);
struct mgcp_endpoint *endp = &g_cfg->endpoints[i]; for (i = 1; i < g_cfg->trunk.number_endpoints; ++i) {
struct mgcp_endpoint *endp = &g_cfg->trunk.endpoints[i];
vty_out(vty, " Endpoint 0x%.2x: CI: %d net: %u/%u bts: %u/%u on %s traffic received bts: %u/%u remote: %u/%u transcoder: %u/%u%s", vty_out(vty, " Endpoint 0x%.2x: CI: %d net: %u/%u bts: %u/%u on %s traffic received bts: %u/%u remote: %u/%u transcoder: %u/%u%s",
i, endp->ci, i, endp->ci,
ntohs(endp->net_end.rtp_port), ntohs(endp->net_end.rtcp_port), ntohs(endp->net_end.rtp_port), ntohs(endp->net_end.rtcp_port),
@ -265,7 +268,7 @@ DEFUN(cfg_mgcp_sdp_payload_number,
"Set the audio codec to use") "Set the audio codec to use")
{ {
unsigned int payload = atoi(argv[0]); unsigned int payload = atoi(argv[0]);
g_cfg->audio_payload = payload; g_cfg->trunk.audio_payload = payload;
return CMD_SUCCESS; return CMD_SUCCESS;
} }
@ -274,7 +277,7 @@ DEFUN(cfg_mgcp_sdp_payload_name,
"sdp audio payload name NAME", "sdp audio payload name NAME",
"Set the audio name to use") "Set the audio name to use")
{ {
bsc_replace_string(g_cfg, &g_cfg->audio_name, argv[0]); bsc_replace_string(g_cfg, &g_cfg->trunk.audio_name, argv[0]);
return CMD_SUCCESS; return CMD_SUCCESS;
} }
@ -283,7 +286,7 @@ DEFUN(cfg_mgcp_loop,
"loop (0|1)", "loop (0|1)",
"Loop the audio") "Loop the audio")
{ {
g_cfg->audio_loop = atoi(argv[0]); g_cfg->trunk.audio_loop = atoi(argv[0]);
return CMD_SUCCESS; return CMD_SUCCESS;
} }
@ -293,7 +296,7 @@ DEFUN(cfg_mgcp_number_endp,
"The number of endpoints to allocate. This is not dynamic.") "The number of endpoints to allocate. This is not dynamic.")
{ {
/* + 1 as we start counting at one */ /* + 1 as we start counting at one */
g_cfg->number_endpoints = atoi(argv[0]) + 1; g_cfg->trunk.number_endpoints = atoi(argv[0]) + 1;
return CMD_SUCCESS; return CMD_SUCCESS;
} }
@ -351,14 +354,14 @@ DEFUN(loop_endp,
struct mgcp_endpoint *endp; struct mgcp_endpoint *endp;
int endp_no = strtoul(argv[0], NULL, 16); int endp_no = strtoul(argv[0], NULL, 16);
if (endp_no < 1 || endp_no >= g_cfg->number_endpoints) { if (endp_no < 1 || endp_no >= g_cfg->trunk.number_endpoints) {
vty_out(vty, "Loopback number %s/%d is invalid.%s", vty_out(vty, "Loopback number %s/%d is invalid.%s",
argv[0], endp_no, VTY_NEWLINE); argv[0], endp_no, VTY_NEWLINE);
return CMD_WARNING; return CMD_WARNING;
} }
endp = &g_cfg->endpoints[endp_no]; endp = &g_cfg->trunk.endpoints[endp_no];
int loop = atoi(argv[1]); int loop = atoi(argv[1]);
if (loop) if (loop)
@ -386,13 +389,13 @@ DEFUN(tap_call,
int port = 0; int port = 0;
int endp_no = strtoul(argv[0], NULL, 16); int endp_no = strtoul(argv[0], NULL, 16);
if (endp_no < 1 || endp_no >= g_cfg->number_endpoints) { if (endp_no < 1 || endp_no >= g_cfg->trunk.number_endpoints) {
vty_out(vty, "Endpoint number %s/%d is invalid.%s", vty_out(vty, "Endpoint number %s/%d is invalid.%s",
argv[0], endp_no, VTY_NEWLINE); argv[0], endp_no, VTY_NEWLINE);
return CMD_WARNING; return CMD_WARNING;
} }
endp = &g_cfg->endpoints[endp_no]; endp = &g_cfg->trunk.endpoints[endp_no];
if (strcmp(argv[1], "bts-in") == 0) { if (strcmp(argv[1], "bts-in") == 0) {
port = MGCP_TAP_BTS_IN; port = MGCP_TAP_BTS_IN;
@ -422,13 +425,13 @@ DEFUN(free_endp, free_endp_cmd,
struct mgcp_endpoint *endp; struct mgcp_endpoint *endp;
int endp_no = strtoul(argv[0], NULL, 16); int endp_no = strtoul(argv[0], NULL, 16);
if (endp_no < 1 || endp_no >= g_cfg->number_endpoints) { if (endp_no < 1 || endp_no >= g_cfg->trunk.number_endpoints) {
vty_out(vty, "Endpoint number %s/%d is invalid.%s", vty_out(vty, "Endpoint number %s/%d is invalid.%s",
argv[0], endp_no, VTY_NEWLINE); argv[0], endp_no, VTY_NEWLINE);
return CMD_WARNING; return CMD_WARNING;
} }
endp = &g_cfg->endpoints[endp_no]; endp = &g_cfg->trunk.endpoints[endp_no];
mgcp_free_endp(endp); mgcp_free_endp(endp);
return CMD_SUCCESS; return CMD_SUCCESS;
} }
@ -492,13 +495,14 @@ int mgcp_parse_config(const char *config_file, struct mgcp_config *cfg)
} }
if (mgcp_endpoints_allocate(g_cfg) != 0) { if (mgcp_endpoints_allocate(g_cfg) != 0) {
fprintf(stderr, "Failed to allocate endpoints: %d. Quitting.\n", g_cfg->number_endpoints); fprintf(stderr, "Failed to allocate endpoints: %d. Quitting.\n",
g_cfg->trunk.number_endpoints);
return -1; return -1;
} }
/* early bind */ /* early bind */
for (i = 1; i < g_cfg->number_endpoints; ++i) { for (i = 1; i < g_cfg->trunk.number_endpoints; ++i) {
struct mgcp_endpoint *endp = &g_cfg->endpoints[i]; struct mgcp_endpoint *endp = &g_cfg->trunk.endpoints[i];
int rtp_port; int rtp_port;
if (g_cfg->bts_ports.mode == PORT_ALLOC_STATIC) { if (g_cfg->bts_ports.mode == PORT_ALLOC_STATIC) {

View File

@ -156,7 +156,7 @@ int bsc_mgcp_assign_patch(struct sccp_connections *con, struct msgb *msg)
endp = mgcp_timeslot_to_endpoint(multiplex, timeslot); endp = mgcp_timeslot_to_endpoint(multiplex, timeslot);
if (endp >= con->bsc->nat->mgcp_cfg->number_endpoints) { if (endp >= con->bsc->nat->mgcp_cfg->trunk.number_endpoints) {
LOGP(DNAT, LOGL_ERROR, LOGP(DNAT, LOGL_ERROR,
"MSC attempted to assign bad endpoint 0x%x\n", "MSC attempted to assign bad endpoint 0x%x\n",
endp); endp);
@ -207,9 +207,9 @@ void bsc_mgcp_free_endpoints(struct bsc_nat *nat)
{ {
int i; int i;
for (i = 1; i < nat->mgcp_cfg->number_endpoints; ++i){ for (i = 1; i < nat->mgcp_cfg->trunk.number_endpoints; ++i){
bsc_mgcp_free_endpoint(nat, i); bsc_mgcp_free_endpoint(nat, i);
mgcp_free_endp(&nat->mgcp_cfg->endpoints[i]); mgcp_free_endp(&nat->mgcp_cfg->trunk.endpoints[i]);
} }
} }
@ -294,7 +294,7 @@ struct sccp_connections *bsc_mgcp_find_con(struct bsc_nat *nat, int endpoint)
return NULL; return NULL;
} }
int bsc_mgcp_policy_cb(struct mgcp_config *cfg, int endpoint, int state, const char *transaction_id) int bsc_mgcp_policy_cb(struct mgcp_trunk_config *tcfg, int endpoint, int state, const char *transaction_id)
{ {
struct bsc_nat *nat; struct bsc_nat *nat;
struct bsc_endpoint *bsc_endp; struct bsc_endpoint *bsc_endp;
@ -302,9 +302,9 @@ int bsc_mgcp_policy_cb(struct mgcp_config *cfg, int endpoint, int state, const c
struct mgcp_endpoint *mgcp_endp; struct mgcp_endpoint *mgcp_endp;
struct msgb *bsc_msg; struct msgb *bsc_msg;
nat = cfg->data; nat = tcfg->cfg->data;
bsc_endp = &nat->bsc_endpoints[endpoint]; bsc_endp = &nat->bsc_endpoints[endpoint];
mgcp_endp = &nat->mgcp_cfg->endpoints[endpoint]; mgcp_endp = &nat->mgcp_cfg->trunk.endpoints[endpoint];
if (bsc_endp->transaction_id) { if (bsc_endp->transaction_id) {
LOGP(DMGCP, LOGL_ERROR, "Endpoint 0x%x had pending transaction: '%s'\n", LOGP(DMGCP, LOGL_ERROR, "Endpoint 0x%x had pending transaction: '%s'\n",
@ -434,7 +434,7 @@ void bsc_mgcp_forward(struct bsc_connection *bsc, struct msgb *msg)
return; return;
} }
for (i = 1; i < bsc->nat->mgcp_cfg->number_endpoints; ++i) { for (i = 1; i < bsc->nat->mgcp_cfg->trunk.number_endpoints; ++i) {
if (bsc->nat->bsc_endpoints[i].bsc != bsc) if (bsc->nat->bsc_endpoints[i].bsc != bsc)
continue; continue;
/* no one listening? a bug? */ /* no one listening? a bug? */
@ -443,7 +443,7 @@ void bsc_mgcp_forward(struct bsc_connection *bsc, struct msgb *msg)
if (strcmp(transaction_id, bsc->nat->bsc_endpoints[i].transaction_id) != 0) if (strcmp(transaction_id, bsc->nat->bsc_endpoints[i].transaction_id) != 0)
continue; continue;
endp = &bsc->nat->mgcp_cfg->endpoints[i]; endp = &bsc->nat->mgcp_cfg->trunk.endpoints[i];
bsc_endp = &bsc->nat->bsc_endpoints[i]; bsc_endp = &bsc->nat->bsc_endpoints[i];
break; break;
} }
@ -713,7 +713,7 @@ int bsc_mgcp_nat_init(struct bsc_nat *nat)
/* some more MGCP config handling */ /* some more MGCP config handling */
cfg->data = nat; cfg->data = nat;
cfg->policy_cb = bsc_mgcp_policy_cb; cfg->policy_cb = bsc_mgcp_policy_cb;
cfg->force_realloc = 1; cfg->trunk.force_realloc = 1;
if (cfg->bts_ip) if (cfg->bts_ip)
talloc_free(cfg->bts_ip); talloc_free(cfg->bts_ip);
@ -721,7 +721,7 @@ int bsc_mgcp_nat_init(struct bsc_nat *nat)
nat->bsc_endpoints = talloc_zero_array(nat, nat->bsc_endpoints = talloc_zero_array(nat,
struct bsc_endpoint, struct bsc_endpoint,
cfg->number_endpoints + 1); cfg->trunk.number_endpoints + 1);
if (!nat->bsc_endpoints) { if (!nat->bsc_endpoints) {
LOGP(DMGCP, LOGL_ERROR, "Failed to allocate nat endpoints\n"); LOGP(DMGCP, LOGL_ERROR, "Failed to allocate nat endpoints\n");
close(cfg->gw_fd.bfd.fd); close(cfg->gw_fd.bfd.fd);
@ -749,7 +749,7 @@ void bsc_mgcp_clear_endpoints_for(struct bsc_connection *bsc)
if (bsc->cfg) if (bsc->cfg)
ctr = &bsc->cfg->stats.ctrg->ctr[BCFG_CTR_DROPPED_CALLS]; ctr = &bsc->cfg->stats.ctrg->ctr[BCFG_CTR_DROPPED_CALLS];
for (i = 1; i < bsc->nat->mgcp_cfg->number_endpoints; ++i) { for (i = 1; i < bsc->nat->mgcp_cfg->trunk.number_endpoints; ++i) {
struct bsc_endpoint *bsc_endp = &bsc->nat->bsc_endpoints[i]; struct bsc_endpoint *bsc_endp = &bsc->nat->bsc_endpoints[i];
if (bsc_endp->bsc != bsc) if (bsc_endp->bsc != bsc)
@ -759,6 +759,6 @@ void bsc_mgcp_clear_endpoints_for(struct bsc_connection *bsc)
rate_ctr_inc(ctr); rate_ctr_inc(ctr);
bsc_mgcp_free_endpoint(bsc->nat, i); bsc_mgcp_free_endpoint(bsc->nat, i);
mgcp_free_endp(&bsc->nat->mgcp_cfg->endpoints[i]); mgcp_free_endp(&bsc->nat->mgcp_cfg->trunk.endpoints[i]);
} }
} }

View File

@ -446,7 +446,7 @@ static void test_mgcp_allocations(void)
struct bsc_endpoint, struct bsc_endpoint,
65); 65);
nat->mgcp_cfg = mgcp_config_alloc(); nat->mgcp_cfg = mgcp_config_alloc();
nat->mgcp_cfg->number_endpoints = 64; nat->mgcp_cfg->trunk.number_endpoints = 64;
bsc = bsc_connection_alloc(nat); bsc = bsc_connection_alloc(nat);
bsc->cfg = bsc_config_alloc(nat, "foo"); bsc->cfg = bsc_config_alloc(nat, "foo");
@ -491,7 +491,7 @@ static void test_mgcp_ass_tracking(void)
struct bsc_endpoint, struct bsc_endpoint,
33); 33);
nat->mgcp_cfg = mgcp_config_alloc(); nat->mgcp_cfg = mgcp_config_alloc();
nat->mgcp_cfg->number_endpoints = 64; nat->mgcp_cfg->trunk.number_endpoints = 64;
bsc = bsc_connection_alloc(nat); bsc = bsc_connection_alloc(nat);
bsc->cfg = bsc_config_alloc(nat, "foo"); bsc->cfg = bsc_config_alloc(nat, "foo");

View File

@ -47,7 +47,7 @@ static void test_auep(void)
struct msgb *inp; struct msgb *inp;
struct msgb *msg; struct msgb *msg;
struct mgcp_config *cfg = mgcp_config_alloc(); struct mgcp_config *cfg = mgcp_config_alloc();
cfg->number_endpoints = 64; cfg->trunk.number_endpoints = 64;
mgcp_endpoints_allocate(cfg); mgcp_endpoints_allocate(cfg);
inp = create_auep1(); inp = create_auep1();