*
* \par See also
* \arg \ref Config_mgcp
+ * \arg \ref res_pktccops
*
* \ingroup channel_drivers
*/
+/*** MODULEINFO
+ <use type="module">res_pktccops</use>
+ <support_level>extended</support_level>
+ ***/
+
#include "asterisk.h"
ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include "asterisk/app.h"
#include "asterisk/musiconhold.h"
#include "asterisk/utils.h"
-#include "asterisk/netsock.h"
+#include "asterisk/netsock2.h"
#include "asterisk/causes.h"
#include "asterisk/dsp.h"
#include "asterisk/devicestate.h"
#define INADDR_NONE (in_addr_t)(-1)
#endif
-/*! Global jitterbuffer configuration - by default, jb is disabled */
+/*! Global jitterbuffer configuration - by default, jb is disabled
+ * \note Values shown here match the defaults shown in mgcp.conf.sample */
static struct ast_jb_conf default_jbconf =
{
.flags = 0,
- .max_size = -1,
- .resync_threshold = -1,
- .impl = ""
+ .max_size = 200,
+ .resync_threshold = 1000,
+ .impl = "fixed",
+ .target_extra = 40,
};
static struct ast_jb_conf global_jbconf;
static int restart_monitor(void);
-static format_t capability = AST_FORMAT_ULAW;
+static struct ast_format_cap *global_capability;
static int nonCodecCapability = AST_RTP_DTMF;
static char ourhost[MAXHOSTNAMELEN];
static int mgcpdebug = 0;
-static struct sched_context *sched;
+static struct ast_sched_context *sched;
static struct io_context *io;
/*! The private structures of the mgcp channels are linked for
* selecting outgoing channels
int iseq; /*!< Not used? */
int lastout; /*!< tracking this on the subchannels. Is it needed here? */
int needdestroy; /*!< Not used? */
- format_t capability;
+ struct ast_format_cap *cap;
int nonCodecCapability;
int onhooktime;
int msgstate; /*!< voicemail message state */
static int transmit_modify_request(struct mgcp_subchannel *sub);
static int transmit_connect(struct mgcp_subchannel *sub);
static int transmit_notify_request_with_callerid(struct mgcp_subchannel *sub, char *tone, char *callernum, char *callername);
-static int transmit_modify_with_sdp(struct mgcp_subchannel *sub, struct ast_rtp_instance *rtp, format_t codecs);
+static int transmit_modify_with_sdp(struct mgcp_subchannel *sub, struct ast_rtp_instance *rtp, const struct ast_format_cap *codecs);
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 char *mgcp_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a);
static int reload_config(int reload);
-static struct ast_channel *mgcp_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause);
-static int mgcp_call(struct ast_channel *ast, char *dest, int timeout);
+static struct ast_channel *mgcp_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, const char *dest, int *cause);
+static int mgcp_call(struct ast_channel *ast, const char *dest, int timeout);
static int mgcp_hangup(struct ast_channel *ast);
static int mgcp_answer(struct ast_channel *ast);
static struct ast_frame *mgcp_read(struct ast_channel *ast);
static int mgcp_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
static int mgcp_senddigit_begin(struct ast_channel *ast, char digit);
static int mgcp_senddigit_end(struct ast_channel *ast, char digit, unsigned int duration);
-static int mgcp_devicestate(void *data);
+static int mgcp_devicestate(const char *data);
static void add_header_offhook(struct mgcp_subchannel *sub, struct mgcp_request *resp, char *tone);
static int transmit_connect_with_sdp(struct mgcp_subchannel *sub, struct ast_rtp_instance *rtp);
static struct mgcp_gateway *build_gateway(char *cat, struct ast_variable *v);
static struct ast_variable *add_var(const char *buf, struct ast_variable *list);
static struct ast_variable *copy_vars(struct ast_variable *src);
-static const struct ast_channel_tech mgcp_tech = {
+static struct ast_channel_tech mgcp_tech = {
.type = "MGCP",
.description = tdesc,
- .capabilities = AST_FORMAT_ULAW | AST_FORMAT_ALAW,
.properties = AST_CHAN_TP_WANTSJITTER | AST_CHAN_TP_CREATESJITTER,
.requester = mgcp_request,
.devicestate = mgcp_devicestate,
return res;
}
-static int mgcp_call(struct ast_channel *ast, char *dest, int timeout)
+static int mgcp_call(struct ast_channel *ast, const char *dest, int timeout)
{
int res;
struct mgcp_endpoint *p;
struct varshead *headp;
struct ast_var_t *current;
- ast_debug(3, "MGCP mgcp_call(%s)\n", ast->name);
- sub = ast->tech_pvt;
+ ast_debug(3, "MGCP mgcp_call(%s)\n", ast_channel_name(ast));
+ sub = ast_channel_tech_pvt(ast);
p = sub->parent;
headp = &ast->varshead;
AST_LIST_TRAVERSE(headp,current,entries) {
break;
}
- if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) {
- ast_log(LOG_WARNING, "mgcp_call called on %s, neither down nor reserved\n", ast->name);
+ if ((ast_channel_state(ast) != AST_STATE_DOWN) && (ast_channel_state(ast) != AST_STATE_RESERVED)) {
+ ast_log(LOG_WARNING, "mgcp_call called on %s, neither down nor reserved\n", ast_channel_name(ast));
ast_mutex_unlock(&sub->lock);
return -1;
}
transmit_modify_request(sub->next);
}
- transmit_notify_request_with_callerid(sub, tone, ast->connected.id.number, ast->connected.id.name);
+ transmit_notify_request_with_callerid(sub, tone,
+ S_COR(ast->connected.id.number.valid, ast->connected.id.number.str, ""),
+ S_COR(ast->connected.id.name.valid, ast->connected.id.name.str, ""));
ast_setstate(ast, AST_STATE_RINGING);
if (sub->next->owner && !ast_strlen_zero(sub->next->cxident) && !ast_strlen_zero(sub->next->callid)) {
static int mgcp_hangup(struct ast_channel *ast)
{
- struct mgcp_subchannel *sub = ast->tech_pvt;
+ struct mgcp_subchannel *sub = ast_channel_tech_pvt(ast);
struct mgcp_endpoint *p = sub->parent;
+ struct ast_channel *bridged;
- ast_debug(1, "mgcp_hangup(%s)\n", ast->name);
- if (!ast->tech_pvt) {
+ ast_debug(1, "mgcp_hangup(%s)\n", ast_channel_name(ast));
+ if (!ast_channel_tech_pvt(ast)) {
ast_debug(1, "Asked to hangup channel not connected\n");
return 0;
}
return 0;
}
ast_mutex_lock(&sub->lock);
- ast_debug(3, "MGCP mgcp_hangup(%s) on %s@%s\n", ast->name, p->name, p->parent->name);
+ ast_debug(3, "MGCP mgcp_hangup(%s) on %s@%s\n", ast_channel_name(ast), p->name, p->parent->name);
if ((p->dtmfmode & MGCP_DTMF_INBAND) && p->dsp) {
/* check whether other channel is active. */
if (p->hookstate == MGCP_OFFHOOK) {
if (sub->next->owner && ast_bridged_channel(sub->next->owner)) {
/* ncs fix! */
- transmit_notify_request_with_callerid(p->sub, (p->ncs ? "L/wt1" : "L/wt"), ast_bridged_channel(sub->next->owner)->cid.cid_num, ast_bridged_channel(sub->next->owner)->cid.cid_name);
+ bridged = ast_bridged_channel(sub->next->owner);
+ transmit_notify_request_with_callerid(p->sub, (p->ncs ? "L/wt1" : "L/wt"),
+ S_COR(bridged->caller.id.number.valid, bridged->caller.id.number.str, ""),
+ S_COR(bridged->caller.id.name.valid, bridged->caller.id.name.str, ""));
}
} else {
/* set our other connection as the primary and swith over to it */
p->sub->cxmode = MGCP_CX_RECVONLY;
transmit_modify_request(p->sub);
if (sub->next->owner && ast_bridged_channel(sub->next->owner)) {
- transmit_notify_request_with_callerid(p->sub, "L/rg", ast_bridged_channel(sub->next->owner)->cid.cid_num, ast_bridged_channel(sub->next->owner)->cid.cid_name);
+ bridged = ast_bridged_channel(sub->next->owner);
+ transmit_notify_request_with_callerid(p->sub, "L/rg",
+ S_COR(bridged->caller.id.number.valid, bridged->caller.id.number.str, ""),
+ S_COR(bridged->caller.id.name.valid, bridged->caller.id.name.str, ""));
}
}
transmit_notify_request(sub, "");
}
- ast->tech_pvt = NULL;
+ ast_channel_tech_pvt_set(ast, NULL);
sub->alreadygone = 0;
sub->outgoing = 0;
sub->cxmode = MGCP_CX_INACTIVE;
if ((p->hookstate == MGCP_ONHOOK) && (!sub->next->rtp)) {
p->hidecallerid = 0;
if (p->hascallwaiting && !p->callwaiting) {
- ast_verb(3, "Enabling call waiting on %s\n", ast->name);
+ ast_verb(3, "Enabling call waiting on %s\n", ast_channel_name(ast));
p->callwaiting = -1;
}
if (has_voicemail(p)) {
ast_debug(3, "MGCP mgcp_hangup(%s) on %s@%s set vmwi(+)\n",
- ast->name, p->name, p->parent->name);
+ ast_channel_name(ast), p->name, p->parent->name);
transmit_notify_request(sub, "L/vmwi(+)");
} else {
ast_debug(3, "MGCP mgcp_hangup(%s) on %s@%s set vmwi(-)\n",
- ast->name, p->name, p->parent->name);
+ ast_channel_name(ast), p->name, p->parent->name);
transmit_notify_request(sub, "L/vmwi(-)");
}
}
static int mgcp_answer(struct ast_channel *ast)
{
int res = 0;
- struct mgcp_subchannel *sub = ast->tech_pvt;
+ struct mgcp_subchannel *sub = ast_channel_tech_pvt(ast);
struct mgcp_endpoint *p = sub->parent;
ast_mutex_lock(&sub->lock);
transmit_modify_request(sub);
}
ast_verb(3, "MGCP mgcp_answer(%s) on %s@%s-%d\n",
- ast->name, p->name, p->parent->name, sub->id);
- if (ast->_state != AST_STATE_UP) {
+ ast_channel_name(ast), p->name, p->parent->name, sub->id);
+ if (ast_channel_state(ast) != AST_STATE_UP) {
ast_setstate(ast, AST_STATE_UP);
- ast_debug(1, "mgcp_answer(%s)\n", ast->name);
+ ast_debug(1, "mgcp_answer(%s)\n", ast_channel_name(ast));
transmit_notify_request(sub, "");
transmit_modify_request(sub);
}
if (sub->owner) {
/* We already hold the channel lock */
if (f->frametype == AST_FRAME_VOICE) {
- if (f->subclass.codec != sub->owner->nativeformats) {
- ast_debug(1, "Oooh, format changed to %s\n", ast_getformatname(f->subclass.codec));
- sub->owner->nativeformats = f->subclass.codec;
- ast_set_read_format(sub->owner, sub->owner->readformat);
- ast_set_write_format(sub->owner, sub->owner->writeformat);
+ if (!ast_format_cap_iscompatible(ast_channel_nativeformats(sub->owner), &f->subclass.format)) {
+ ast_debug(1, "Oooh, format changed to %s\n", ast_getformatname(&f->subclass.format));
+ ast_format_cap_set(ast_channel_nativeformats(sub->owner), &f->subclass.format);
+ ast_set_read_format(sub->owner, ast_channel_readformat(sub->owner));
+ ast_set_write_format(sub->owner, ast_channel_writeformat(sub->owner));
}
/* Courtesy fearnor aka alex@pilosoft.com */
if ((sub->parent->dtmfmode & MGCP_DTMF_INBAND) && (sub->parent->dsp)) {
static struct ast_frame *mgcp_read(struct ast_channel *ast)
{
struct ast_frame *f;
- struct mgcp_subchannel *sub = ast->tech_pvt;
+ struct mgcp_subchannel *sub = ast_channel_tech_pvt(ast);
ast_mutex_lock(&sub->lock);
f = mgcp_rtp_read(sub);
ast_mutex_unlock(&sub->lock);
static int mgcp_write(struct ast_channel *ast, struct ast_frame *frame)
{
- struct mgcp_subchannel *sub = ast->tech_pvt;
+ struct mgcp_subchannel *sub = ast_channel_tech_pvt(ast);
int res = 0;
char buf[256];
return 0;
}
} else {
- if (!(frame->subclass.codec & ast->nativeformats)) {
+ if (!(ast_format_cap_iscompatible(ast_channel_nativeformats(ast), &frame->subclass.format))) {
ast_log(LOG_WARNING, "Asked to transmit frame type %s, while native formats is %s (read/write = %s/%s)\n",
- ast_getformatname(frame->subclass.codec),
- ast_getformatname_multiple(buf, sizeof(buf), ast->nativeformats),
- ast_getformatname(ast->readformat),
- ast_getformatname(ast->writeformat));
+ ast_getformatname(&frame->subclass.format),
+ ast_getformatname_multiple(buf, sizeof(buf), ast_channel_nativeformats(ast)),
+ ast_getformatname(ast_channel_readformat(ast)),
+ ast_getformatname(ast_channel_writeformat(ast)));
/* return -1; */
}
}
static int mgcp_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
{
- struct mgcp_subchannel *sub = newchan->tech_pvt;
+ struct mgcp_subchannel *sub = ast_channel_tech_pvt(newchan);
ast_mutex_lock(&sub->lock);
- ast_log(LOG_NOTICE, "mgcp_fixup(%s, %s)\n", oldchan->name, newchan->name);
+ ast_log(LOG_NOTICE, "mgcp_fixup(%s, %s)\n", ast_channel_name(oldchan), ast_channel_name(newchan));
if (sub->owner != oldchan) {
ast_mutex_unlock(&sub->lock);
ast_log(LOG_WARNING, "old channel wasn't %p but was %p\n", oldchan, sub->owner);
static int mgcp_senddigit_begin(struct ast_channel *ast, char digit)
{
- struct mgcp_subchannel *sub = ast->tech_pvt;
+ struct mgcp_subchannel *sub = ast_channel_tech_pvt(ast);
struct mgcp_endpoint *p = sub->parent;
int res = 0;
static int mgcp_senddigit_end(struct ast_channel *ast, char digit, unsigned int duration)
{
- struct mgcp_subchannel *sub = ast->tech_pvt;
+ struct mgcp_subchannel *sub = ast_channel_tech_pvt(ast);
struct mgcp_endpoint *p = sub->parent;
int res = 0;
char tmp[4];
*
* \return device status result (from devicestate.h) AST_DEVICE_INVALID (not available) or AST_DEVICE_UNKNOWN (available but unknown state)
*/
-static int mgcp_devicestate(void *data)
+static int mgcp_devicestate(const char *data)
{
struct mgcp_gateway *g;
struct mgcp_endpoint *e = NULL;
static int mgcp_indicate(struct ast_channel *ast, int ind, const void *data, size_t datalen)
{
- struct mgcp_subchannel *sub = ast->tech_pvt;
+ struct mgcp_subchannel *sub = ast_channel_tech_pvt(ast);
int res = 0;
ast_debug(3, "MGCP asked to indicate %d '%s' condition on channel %s\n",
- ind, control2str(ind), ast->name);
+ ind, control2str(ind), ast_channel_name(ast));
ast_mutex_lock(&sub->lock);
switch(ind) {
case AST_CONTROL_RINGING:
case AST_CONTROL_BUSY:
transmit_notify_request(sub, "L/bz");
break;
+ case AST_CONTROL_INCOMPLETE:
+ /* We do not currently support resetting of the Interdigit Timer, so treat
+ * Incomplete control frames as a congestion response
+ */
case AST_CONTROL_CONGESTION:
transmit_notify_request(sub, sub->parent->ncs ? "L/cg" : "G/cg");
break;
ast_moh_stop(ast);
break;
case AST_CONTROL_SRCUPDATE:
- ast_rtp_instance_new_source(sub->rtp);
+ ast_rtp_instance_update_source(sub->rtp);
+ break;
+ case AST_CONTROL_SRCCHANGE:
+ ast_rtp_instance_change_source(sub->rtp);
break;
case AST_CONTROL_PROGRESS:
case AST_CONTROL_PROCEEDING:
struct ast_channel *tmp;
struct ast_variable *v = NULL;
struct mgcp_endpoint *i = sub->parent;
- int fmt;
+ struct ast_format tmpfmt;
tmp = ast_channel_alloc(1, state, i->cid_num, i->cid_name, linkedid, i->accountcode, i->exten, i->context, i->amaflags, "MGCP/%s@%s-%d", i->name, i->parent->name, sub->id);
if (tmp) {
- tmp->tech = &mgcp_tech;
- tmp->nativeformats = i->capability;
- if (!tmp->nativeformats) {
- tmp->nativeformats = capability;
+ ast_channel_tech_set(tmp, &mgcp_tech);
+ ast_format_cap_copy(ast_channel_nativeformats(tmp), i->cap);
+ if (ast_format_cap_is_empty(ast_channel_nativeformats(tmp))) {
+ ast_format_cap_copy(ast_channel_nativeformats(tmp), global_capability);
}
- fmt = ast_best_codec(tmp->nativeformats);
if (sub->rtp) {
ast_channel_set_fd(tmp, 0, ast_rtp_instance_fd(sub->rtp, 0));
}
i->dsp = NULL;
}
if (state == AST_STATE_RING)
- tmp->rings = 1;
- tmp->writeformat = fmt;
- tmp->rawwriteformat = fmt;
- tmp->readformat = fmt;
- tmp->rawreadformat = fmt;
- tmp->tech_pvt = sub;
+ ast_channel_rings_set(tmp, 1);
+
+ ast_best_codec(ast_channel_nativeformats(tmp), &tmpfmt);
+ ast_format_copy(ast_channel_writeformat(tmp), &tmpfmt);
+ ast_format_copy(ast_channel_rawwriteformat(tmp), &tmpfmt);
+ ast_format_copy(ast_channel_readformat(tmp), &tmpfmt);
+ ast_format_copy(ast_channel_rawreadformat(tmp), &tmpfmt);
+ ast_channel_tech_pvt_set(tmp, sub);
if (!ast_strlen_zero(i->language))
- ast_string_field_set(tmp, language, i->language);
+ ast_channel_language_set(tmp, i->language);
if (!ast_strlen_zero(i->accountcode))
- ast_string_field_set(tmp, accountcode, i->accountcode);
+ ast_channel_accountcode_set(tmp, i->accountcode);
if (i->amaflags)
- tmp->amaflags = i->amaflags;
+ ast_channel_amaflags_set(tmp, i->amaflags);
sub->owner = tmp;
ast_module_ref(ast_module_info->self);
tmp->callgroup = i->callgroup;
tmp->pickupgroup = i->pickupgroup;
- ast_string_field_set(tmp, call_forward, i->call_forward);
- ast_copy_string(tmp->context, i->context, sizeof(tmp->context));
- ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten));
+ ast_channel_call_forward_set(tmp, i->call_forward);
+ ast_channel_context_set(tmp, i->context);
+ ast_channel_exten_set(tmp, i->exten);
/* Don't use ast_set_callerid() here because it will
* generate a needless NewCallerID event */
- tmp->cid.cid_ani = ast_strdup(i->cid_num);
+ if (!ast_strlen_zero(i->cid_num)) {
+ tmp->caller.ani.number.valid = 1;
+ tmp->caller.ani.number.str = ast_strdup(i->cid_num);
+ }
if (!i->adsi) {
- tmp->adsicpe = AST_ADSI_UNAVAILABLE;
+ ast_channel_adsicpe_set(tmp, AST_ADSI_UNAVAILABLE);
}
- tmp->priority = 1;
+ ast_channel_priority_set(tmp, 1);
/* Set channel variables for this call from configuration */
for (v = i->chanvars ; v ; v = v->next) {
}
if (state != AST_STATE_DOWN) {
if (ast_pbx_start(tmp)) {
- ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
+ ast_log(LOG_WARNING, "Unable to start PBX on %s\n", ast_channel_name(tmp));
ast_hangup(tmp);
tmp = NULL;
}
}
ast_verb(3, "MGCP mgcp_new(%s) created in state: %s\n",
- tmp->name, ast_state2str(state));
+ ast_channel_name(tmp), ast_state2str(state));
} else {
ast_log(LOG_WARNING, "Unable to allocate channel structure\n");
}
{
struct mgcp_gateway *g = NULL;
struct ast_variable *mgcpgwconfig = NULL;
- struct ast_variable *mgcpepconfig = NULL;
struct ast_variable *gwv, *epname = NULL;
struct mgcp_endpoint *e;
- char *c = NULL, *line;
char lines[256];
- char tmp[4096];
int i, j;
ast_debug(1, "*** find Realtime MGCPGW\n");
return NULL;
}
+ /*!
+ * \note This is a fairly odd way of instantiating lines. Instead of each
+ * line created by virtue of being in the database (and loaded via
+ * ast_load_realtime_multientry), this code forces a specific order with a
+ * "lines" entry in the "mgcpgw" record. This has benefits, because as with
+ * chan_dahdi, values are inherited across definitions. The downside is
+ * that it's not as clear what the values will be simply by looking at a
+ * single row in the database, and it's probable that the sanest configuration
+ * should have the first column in the "mgcpep" table be "clearvars", with a
+ * static value of "all", if any variables are set at all. It may be worth
+ * making this assumption explicit in the code in the future, and then just
+ * using ast_load_realtime_multientry for the "mgcpep" records.
+ */
lines[0] = '\0';
for (gwv = mgcpgwconfig; gwv; gwv = gwv->next) {
if (!strcasecmp(gwv->name, "lines")) {
break;
}
}
+ /* Position gwv at the end of the list */
for (gwv = gwv && gwv->next ? gwv : mgcpgwconfig; gwv->next; gwv = gwv->next);
+
if (!ast_strlen_zero(lines)) {
- for (c = lines, line = tmp; *c; c++) {
- *line = *c;
- if (*c == ',') {
- *(line) = 0;
- mgcpepconfig = ast_load_realtime("mgcpep", "name", at, "line", tmp, NULL);
- gwv->next = mgcpepconfig;
-
- while (gwv->next) {
- if (!strcasecmp(gwv->next->name, "line")) {
- epname = gwv->next;
- gwv->next = gwv->next->next;
- } else {
- gwv = gwv->next;
- }
- }
- /* moving the line var to the end */
- if (epname) {
- gwv->next = epname;
- epname->next = NULL;
- gwv = gwv->next;
- }
- mgcpepconfig = NULL;
- line = tmp;
- } else {
- line++;
+ AST_DECLARE_APP_ARGS(args,
+ AST_APP_ARG(line)[100];
+ );
+ AST_STANDARD_APP_ARGS(args, lines);
+ for (i = 0; i < args.argc; i++) {
+ gwv->next = ast_load_realtime("mgcpep", "name", at, "line", args.line[i], NULL);
+
+ /* Remove "line" AND position gwv at the end of the list. */
+ for (epname = NULL; gwv->next; gwv = gwv->next) {
+ if (!strcasecmp(gwv->next->name, "line")) {
+ /* Remove it from the list */
+ epname = gwv->next;
+ gwv->next = gwv->next->next;
+ }
+ }
+ /* Since "line" instantiates the configuration, we have to move it to the end. */
+ if (epname) {
+ gwv->next = epname;
+ epname->next = NULL;
+ gwv = gwv->next;
}
}
}
if ((g->addr.sin_addr.s_addr != sin->sin_addr.s_addr) ||
(g->addr.sin_port != sin->sin_port)) {
memcpy(&g->addr, sin, sizeof(g->addr));
- if (ast_ouraddrfor(&g->addr.sin_addr, &g->ourip))
- memcpy(&g->ourip, &__ourip, sizeof(g->ourip));
+ {
+ struct ast_sockaddr tmp1, tmp2;
+ struct sockaddr_in tmp3 = {0,};
+
+ tmp3.sin_addr = g->ourip;
+ ast_sockaddr_from_sin(&tmp1, &g->addr);
+ ast_sockaddr_from_sin(&tmp2, &tmp3);
+ if (ast_ouraddrfor(&tmp1, &tmp2)) {
+ memcpy(&g->ourip, &__ourip, sizeof(g->ourip));
+ }
+ ast_sockaddr_to_sin(&tmp2, &tmp3);
+ g->ourip = tmp3.sin_addr;
+ }
ast_verb(3, "Registered MGCP gateway '%s' at %s port %d\n", g->name, ast_inet_ntoa(g->addr.sin_addr), ntohs(g->addr.sin_port));
}
/* not dynamic, check if the name matches */
char host[258];
int len;
int portno;
- format_t peercapability;
+ struct ast_format_cap *peercap;
int peerNonCodecCapability;
struct sockaddr_in sin;
+ struct ast_sockaddr sin_tmp;
char *codecs;
struct ast_hostent ahp; struct hostent *hp;
int codec, codec_count=0;
sin.sin_family = AF_INET;
memcpy(&sin.sin_addr, hp->h_addr, sizeof(sin.sin_addr));
sin.sin_port = htons(portno);
- ast_rtp_instance_set_remote_address(sub->rtp, &sin);
+ ast_sockaddr_from_sin(&sin_tmp, &sin);
+ ast_rtp_instance_set_remote_address(sub->rtp, &sin_tmp);
ast_debug(3, "Peer RTP is at port %s:%d\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
/* Scan through the RTP payload types specified in a "m=" line: */
ast_rtp_codecs_payloads_clear(ast_rtp_instance_get_codecs(sub->rtp), sub->rtp);
}
/* Now gather all of the codecs that were asked for: */
- ast_rtp_codecs_payload_formats(ast_rtp_instance_get_codecs(sub->rtp), &peercapability, &peerNonCodecCapability);
- p->capability = capability & peercapability;
+ if (!(peercap = ast_format_cap_alloc_nolock())) {
+ return -1;
+ }
+ ast_rtp_codecs_payload_formats(ast_rtp_instance_get_codecs(sub->rtp), peercap, &peerNonCodecCapability);
+ ast_format_cap_joint_copy(global_capability, peercap, p->cap);
ast_debug(1, "Capabilities: us - %s, them - %s, combined - %s\n",
- ast_getformatname_multiple(tmp1, sizeof(tmp1), capability),
- ast_getformatname_multiple(tmp2, sizeof(tmp2), peercapability),
- ast_getformatname_multiple(tmp3, sizeof(tmp3), p->capability));
+ ast_getformatname_multiple(tmp1, sizeof(tmp1), global_capability),
+ ast_getformatname_multiple(tmp2, sizeof(tmp2), peercap),
+ ast_getformatname_multiple(tmp3, sizeof(tmp3), p->cap));
+ peercap = ast_format_cap_destroy(peercap);
+
ast_debug(1, "Non-codec capabilities: us - %d, them - %d, combined - %d\n",
nonCodecCapability, peerNonCodecCapability, p->nonCodecCapability);
- if (!p->capability) {
+ if (ast_format_cap_is_empty(p->cap)) {
ast_log(LOG_WARNING, "No compatible codecs!\n");
return -1;
}
int codec;
char costr[80];
struct sockaddr_in sin;
+ struct ast_sockaddr sin_tmp;
char v[256];
char s[256];
char o[256];
char t[256];
char m[256] = "";
char a[1024] = "";
- format_t x;
+ int x;
+ struct ast_format tmpfmt;
struct sockaddr_in dest = { 0, };
+ struct ast_sockaddr dest_tmp;
struct mgcp_endpoint *p = sub->parent;
/* XXX We break with the "recommendation" and send our IP, in order that our
peer doesn't have to ast_gethostbyname() us XXX */
ast_log(LOG_WARNING, "No way to add SDP without an RTP structure\n");
return -1;
}
- ast_rtp_instance_get_local_address(sub->rtp, &sin);
+ ast_rtp_instance_get_local_address(sub->rtp, &sin_tmp);
+ ast_sockaddr_to_sin(&sin_tmp, &sin);
if (rtp) {
- ast_rtp_instance_get_remote_address(sub->rtp, &dest);
+ ast_rtp_instance_get_remote_address(sub->rtp, &dest_tmp);
+ ast_sockaddr_to_sin(&dest_tmp, &dest);
} else {
if (sub->tmpdest.sin_addr.s_addr) {
dest.sin_addr = sub->tmpdest.sin_addr;
snprintf(c, sizeof(c), "c=IN IP4 %s\r\n", ast_inet_ntoa(dest.sin_addr));
ast_copy_string(t, "t=0 0\r\n", sizeof(t));
snprintf(m, sizeof(m), "m=audio %d RTP/AVP", ntohs(dest.sin_port));
- for (x = 1LL; x <= AST_FORMAT_AUDIO_MASK; x <<= 1) {
- if (!(x & AST_FORMAT_AUDIO_MASK)) {
+
+ ast_format_cap_iter_start(p->cap);
+ while (!(ast_format_cap_iter_next(p->cap, &tmpfmt))) {
+ if (AST_FORMAT_GET_TYPE(tmpfmt.id) != AST_FORMAT_TYPE_AUDIO) {
/* Audio is now discontiguous */
continue;
}
- if (p->capability & x) {
- ast_debug(1, "Answering with capability %s\n", ast_getformatname(x));
- codec = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(sub->rtp), 1, x);
+ if (ast_format_cap_iscompatible(p->cap, &tmpfmt)) {
+ ast_debug(1, "Answering with capability %s\n", ast_getformatname(&tmpfmt));
+ codec = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(sub->rtp), 1, &tmpfmt, 0);
if (codec > -1) {
snprintf(costr, sizeof(costr), " %d", codec);
strncat(m, costr, sizeof(m) - strlen(m) - 1);
- snprintf(costr, sizeof(costr), "a=rtpmap:%d %s/8000\r\n", codec, ast_rtp_lookup_mime_subtype2(1, x, 0));
+ snprintf(costr, sizeof(costr), "a=rtpmap:%d %s/8000\r\n", codec, ast_rtp_lookup_mime_subtype2(1, &tmpfmt, 0, 0));
strncat(a, costr, sizeof(a) - strlen(a) - 1);
}
}
}
+ ast_format_cap_iter_end(p->cap);
+
for (x = 1LL; x <= AST_RTP_MAX; x <<= 1) {
if (p->nonCodecCapability & x) {
ast_debug(1, "Answering with non-codec capability %d\n", (int) x);
- codec = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(sub->rtp), 0, x);
+ codec = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(sub->rtp), 0, NULL, x);
if (codec > -1) {
snprintf(costr, sizeof(costr), " %d", codec);
strncat(m, costr, sizeof(m) - strlen(m) - 1);
- snprintf(costr, sizeof(costr), "a=rtpmap:%d %s/8000\r\n", codec, ast_rtp_lookup_mime_subtype2(0, x, 0));
+ snprintf(costr, sizeof(costr), "a=rtpmap:%d %s/8000\r\n", codec, ast_rtp_lookup_mime_subtype2(0, NULL, x, 0));
strncat(a, costr, sizeof(a) - strlen(a) - 1);
if (x == AST_RTP_DTMF) {
/* Indicate we support DTMF... Not sure about 16,
return 0;
}
-static int transmit_modify_with_sdp(struct mgcp_subchannel *sub, struct ast_rtp_instance *rtp, format_t codecs)
+static int transmit_modify_with_sdp(struct mgcp_subchannel *sub, struct ast_rtp_instance *rtp, const struct ast_format_cap *codecs)
{
struct mgcp_request resp;
char local[256];
char tmp[80];
struct mgcp_endpoint *p = sub->parent;
- format_t x;
+ struct ast_format tmpfmt;
+ struct ast_sockaddr sub_tmpdest_tmp;
if (ast_strlen_zero(sub->cxident) && rtp) {
/* We don't have a CXident yet, store the destination and
wait a bit */
- ast_rtp_instance_get_remote_address(rtp, &sub->tmpdest);
+ ast_rtp_instance_get_remote_address(rtp, &sub_tmpdest_tmp);
+ ast_sockaddr_to_sin(&sub_tmpdest_tmp, &sub->tmpdest);
return 0;
}
ast_copy_string(local, "e:on, s:off, p:20", sizeof(local));
- for (x = 1; x <= AST_FORMAT_AUDIO_MASK; x <<= 1) {
- if (!(x & AST_FORMAT_AUDIO_MASK)) {
- /* No longer contiguous */
+ ast_format_cap_iter_start(p->cap);
+ while (!(ast_format_cap_iter_next(p->cap, &tmpfmt))) {
+ if (AST_FORMAT_GET_TYPE(tmpfmt.id) != AST_FORMAT_TYPE_AUDIO) {
+ /* Audio is now discontiguous */
continue;
}
- if (p->capability & x) {
- snprintf(tmp, sizeof(tmp), ", a:%s", ast_rtp_lookup_mime_subtype2(1, x, 0));
+ if (ast_format_cap_iscompatible(p->cap, &tmpfmt)) {
+ snprintf(tmp, sizeof(tmp), ", a:%s", ast_rtp_lookup_mime_subtype2(1, &tmpfmt, 0, 0));
strncat(local, tmp, sizeof(local) - strlen(local) - 1);
}
}
+ ast_format_cap_iter_end(p->cap);
if (sub->gate) {
if (sub->gate->state == GATE_ALLOCATED || sub->gate->state == GATE_OPEN) {
struct mgcp_request resp;
char local[256];
char tmp[80];
- int x;
+ struct ast_format tmpfmt;
struct mgcp_endpoint *p = sub->parent;
ast_debug(3, "Creating connection for %s@%s-%d in cxmode: %s callid: %s\n",
ast_copy_string(local, "e:on, s:off, p:20", sizeof(local));
- for (x = 1; x <= AST_FORMAT_AUDIO_MASK; x <<= 1) {
- if (!(x & AST_FORMAT_AUDIO_MASK)) {
- /* No longer contiguous */
+ ast_format_cap_iter_start(p->cap);
+ while (!(ast_format_cap_iter_next(p->cap, &tmpfmt))) {
+ if (AST_FORMAT_GET_TYPE(tmpfmt.id) != AST_FORMAT_TYPE_AUDIO) {
+ /* Audio is now discontiguous */
continue;
}
- if (p->capability & x) {
- snprintf(tmp, sizeof(tmp), ", a:%s", ast_rtp_lookup_mime_subtype2(1, x, 0));
+ if (ast_format_cap_iscompatible(p->cap, &tmpfmt)) {
+ snprintf(tmp, sizeof(tmp), ", a:%s", ast_rtp_lookup_mime_subtype2(1, &tmpfmt, 0, 0));
strncat(local, tmp, sizeof(local) - strlen(local) - 1);
}
}
+ ast_format_cap_iter_end(p->cap);
if (sub->gate) {
if(sub->gate->state == GATE_ALLOCATED) {
struct mgcp_request resp;
char local[256];
char tmp[80];
- format_t x;
+ struct ast_format tmpfmt;
struct mgcp_endpoint *p = sub->parent;
ast_copy_string(local, "p:20, s:off, e:on", sizeof(local));
- for (x = 1LL; x <= AST_FORMAT_AUDIO_MASK; x <<= 1) {
- if (p->capability & x) {
- snprintf(tmp, sizeof(tmp), ", a:%s", ast_rtp_lookup_mime_subtype2(1, x, 0));
+ ast_format_cap_iter_start(p->cap);
+ while (!(ast_format_cap_iter_next(p->cap, &tmpfmt))) {
+ if (ast_format_cap_iscompatible(p->cap, &tmpfmt)) {
+ snprintf(tmp, sizeof(tmp), ", a:%s", ast_rtp_lookup_mime_subtype2(1, &tmpfmt, 0, 0));
strncat(local, tmp, sizeof(local) - strlen(local) - 1);
}
}
+ ast_format_cap_iter_end(p->cap);
ast_debug(3, "Creating connection for %s@%s-%d in cxmode: %s callid: %s\n",
p->name, p->parent->name, sub->id, mgcp_cxmodes[sub->cxmode], sub->callid);
{
struct mgcp_request resp;
struct mgcp_endpoint *p = sub->parent;
- format_t x;
+ struct ast_format tmpfmt;
int fc = 1;
char local[256];
char tmp[80];
p->name, p->parent->name, sub->id, mgcp_cxmodes[sub->cxmode], sub->callid);
ast_copy_string(local, "", sizeof(local));
- for (x = 1; x <= AST_FORMAT_AUDIO_MASK; x <<= 1) {
- if (p->capability & x) {
- if (p->ncs && !fc) {
- p->capability = x; /* sb5120e bug */
- break;
- } else {
- fc = 0;
- snprintf(tmp, sizeof(tmp), ", a:%s", ast_rtp_lookup_mime_subtype2(1, x, 0));
- }
- strncat(local, tmp, sizeof(local) - strlen(local) - 1);
+ ast_format_cap_iter_start(p->cap);
+ while (!(ast_format_cap_iter_next(p->cap, &tmpfmt))) {
+ if (p->ncs && !fc) {
+ ast_format_cap_set(p->cap, &tmpfmt); /* sb5120e bug */
+ break;
+ } else {
+ fc = 0;
+ snprintf(tmp, sizeof(tmp), ", a:%s", ast_rtp_lookup_mime_subtype2(1, &tmpfmt, 0, 0));
}
+ strncat(local, tmp, sizeof(local) - strlen(local) - 1);
}
+ ast_format_cap_iter_end(p->cap);
if (!sub->sdpsent) {
if (sub->gate) {
snprintf(tmp, sizeof(tmp), ", dq-gi:%x", sub->gate->gateid);
strncat(local, tmp, sizeof(local) - strlen(local) - 1);
} else {
- /* we still dont have gateid wait */
+ /* we still don't have gateid wait */
return 0;
}
}
}
if (p && p->sub && p->sub->owner &&
- p->sub->owner->_state >= AST_STATE_RINGING &&
+ ast_channel_state(p->sub->owner) >= AST_STATE_RINGING &&
(p->dtmfmode & (MGCP_DTMF_INBAND | MGCP_DTMF_HYBRID))) {
add_header(resp, "R", "L/hu(N),L/hf(N)");
if (result == 200 && (req->cmd == MGCP_CMD_CRCX || req->cmd == MGCP_CMD_MDCX)) {
if (sub) {
transmit_response(sub, "000", resp, "OK");
- if (sub->owner && sub->owner->_state == AST_STATE_RINGING) {
+ if (sub->owner && ast_channel_state(sub->owner) == AST_STATE_RINGING) {
ast_queue_control(sub->owner, AST_CONTROL_RINGING);
}
}
static void start_rtp(struct mgcp_subchannel *sub)
{
+ struct ast_sockaddr bindaddr_tmp;
+
ast_mutex_lock(&sub->lock);
/* check again to be on the safe side */
if (sub->rtp) {
sub->rtp = NULL;
}
/* Allocate the RTP now */
- sub->rtp = ast_rtp_instance_new("asterisk", sched, &bindaddr, NULL);
+ ast_sockaddr_from_sin(&bindaddr_tmp, &bindaddr);
+ sub->rtp = ast_rtp_instance_new("asterisk", sched, &bindaddr_tmp, NULL);
if (sub->rtp && sub->owner)
ast_channel_set_fd(sub->owner, 0, ast_rtp_instance_fd(sub->rtp, 0));
if (sub->rtp) {
static void *mgcp_ss(void *data)
{
struct ast_channel *chan = data;
- struct mgcp_subchannel *sub = chan->tech_pvt;
+ struct mgcp_subchannel *sub = ast_channel_tech_pvt(chan);
struct mgcp_endpoint *p = sub->parent;
/* char exten[AST_MAX_EXTENSION] = ""; */
int len = 0;
timeout = 0;
len = strlen(p->dtmf_buf);
- if (!ast_ignore_pattern(chan->context, p->dtmf_buf)) {
+ if (!ast_ignore_pattern(ast_channel_context(chan), p->dtmf_buf)) {
/*res = tone_zone_play_tone(p->subs[index].zfd, -1);*/
ast_indicate(chan, -1);
} else {
/*tone_zone_play_tone(p->subs[index].zfd, DAHDI_TONE_DIALTONE);*/
transmit_notify_request(sub, "L/dl");
}
- if (ast_exists_extension(chan, chan->context, p->dtmf_buf, 1, p->cid_num)) {
- if (!res || !ast_matchmore_extension(chan, chan->context, p->dtmf_buf, 1, p->cid_num)) {
+ if (ast_exists_extension(chan, ast_channel_context(chan), p->dtmf_buf, 1, p->cid_num)) {
+ if (!res || !ast_matchmore_extension(chan, ast_channel_context(chan), p->dtmf_buf, 1, p->cid_num)) {
if (getforward) {
/* Record this as the forwarding extension */
ast_copy_string(p->call_forward, p->dtmf_buf, sizeof(p->call_forward));
ast_verb(3, "Setting call forward to '%s' on channel %s\n",
- p->call_forward, chan->name);
+ p->call_forward, ast_channel_name(chan));
/*res = tone_zone_play_tone(p->subs[index].zfd, DAHDI_TONE_DIALRECALL);*/
transmit_notify_request(sub, "L/sl");
if (res)
} else {
/*res = tone_zone_play_tone(p->subs[index].zfd, -1);*/
ast_indicate(chan, -1);
- ast_copy_string(chan->exten, p->dtmf_buf, sizeof(chan->exten));
- chan->cid.cid_dnid = ast_strdup(p->dtmf_buf);
+ ast_channel_exten_set(chan, p->dtmf_buf);
+ chan->dialed.number.str = ast_strdup(p->dtmf_buf);
memset(p->dtmf_buf, 0, sizeof(p->dtmf_buf));
ast_set_callerid(chan,
p->hidecallerid ? "" : p->cid_num,
p->hidecallerid ? "" : p->cid_name,
- chan->cid.cid_ani ? NULL : p->cid_num);
+ chan->caller.ani.number.valid ? NULL : p->cid_num);
ast_setstate(chan, AST_STATE_RING);
/*dahdi_enable_ec(p);*/
if (p->dtmfmode & MGCP_DTMF_HYBRID) {
memset(p->dtmf_buf, 0, sizeof(p->dtmf_buf));
return NULL;
} else if (p->hascallwaiting && p->callwaiting && !strcmp(p->dtmf_buf, "*70")) {
- ast_verb(3, "Disabling call waiting on %s\n", chan->name);
+ ast_verb(3, "Disabling call waiting on %s\n", ast_channel_name(chan));
/* Disable call waiting if enabled */
p->callwaiting = 0;
/*res = tone_zone_play_tone(p->subs[index].zfd, DAHDI_TONE_DIALRECALL);*/
ast_hangup(chan);
return NULL;
} else if (!p->hidecallerid && !strcmp(p->dtmf_buf, "*67")) {
- ast_verb(3, "Disabling Caller*ID on %s\n", chan->name);
+ ast_verb(3, "Disabling Caller*ID on %s\n", ast_channel_name(chan));
/* Disable Caller*ID if enabled */
p->hidecallerid = 1;
ast_set_callerid(chan, "", "", NULL);
} else if (p->callreturn && !strcmp(p->dtmf_buf, "*69")) {
res = 0;
if (!ast_strlen_zero(p->lastcallerid)) {
- res = ast_say_digit_str(chan, p->lastcallerid, "", chan->language);
+ res = ast_say_digit_str(chan, p->lastcallerid, "", ast_channel_language(chan));
}
if (!res)
/*res = tone_zone_play_tone(p->subs[index].zfd, DAHDI_TONE_DIALRECALL);*/
break;
} else if (!strcmp(p->dtmf_buf, "*78")) {
/* Do not disturb */
- ast_verb(3, "Enabled DND on channel %s\n", chan->name);
+ ast_verb(3, "Enabled DND on channel %s\n", ast_channel_name(chan));
/*res = tone_zone_play_tone(p->subs[index].zfd, DAHDI_TONE_DIALRECALL);*/
transmit_notify_request(sub, "L/sl");
p->dnd = 1;
len = 0;
} else if (!strcmp(p->dtmf_buf, "*79")) {
/* Do not disturb */
- ast_verb(3, "Disabled DND on channel %s\n", chan->name);
+ ast_verb(3, "Disabled DND on channel %s\n", ast_channel_name(chan));
/*res = tone_zone_play_tone(p->subs[index].zfd, DAHDI_TONE_DIALRECALL);*/
transmit_notify_request(sub, "L/sl");
p->dnd = 0;
memset(p->dtmf_buf, 0, sizeof(p->dtmf_buf));
len = 0;
} else if (p->cancallforward && !strcmp(p->dtmf_buf, "*73")) {
- ast_verb(3, "Cancelling call forwarding on channel %s\n", chan->name);
+ ast_verb(3, "Cancelling call forwarding on channel %s\n", ast_channel_name(chan));
/*res = tone_zone_play_tone(p->subs[index].zfd, DAHDI_TONE_DIALRECALL);*/
transmit_notify_request(sub, "L/sl");
memset(p->call_forward, 0, sizeof(p->call_forward));
getforward = 0;
memset(p->dtmf_buf, 0, sizeof(p->dtmf_buf));
len = 0;
- } else if (!strcmp(p->dtmf_buf, ast_parking_ext()) &&
+ } else if (ast_parking_ext_valid(p->dtmf_buf, chan, ast_channel_context(chan)) &&
sub->next->owner && ast_bridged_channel(sub->next->owner)) {
/* This is a three way call, the main call being a real channel,
and we're parking the first call. */
- ast_masq_park_call(ast_bridged_channel(sub->next->owner), chan, 0, NULL);
- ast_verb(3, "Parking call to '%s'\n", chan->name);
+ ast_masq_park_call_exten(ast_bridged_channel(sub->next->owner), chan,
+ p->dtmf_buf, ast_channel_context(chan), 0, NULL);
+ ast_verb(3, "Parking call to '%s'\n", ast_channel_name(chan));
break;
} else if (!ast_strlen_zero(p->lastcallerid) && !strcmp(p->dtmf_buf, "*60")) {
ast_verb(3, "Blacklisting number %s\n", p->lastcallerid);
len = 0;
}
} else if (p->hidecallerid && !strcmp(p->dtmf_buf, "*82")) {
- ast_verb(3, "Enabling Caller*ID on %s\n", chan->name);
+ ast_verb(3, "Enabling Caller*ID on %s\n", ast_channel_name(chan));
/* Enable Caller*ID if enabled */
p->hidecallerid = 0;
ast_set_callerid(chan, p->cid_num, p->cid_name, NULL);
len = 0;
memset(p->dtmf_buf, 0, sizeof(p->dtmf_buf));
timeout = firstdigittimeout;
- } else if (!ast_canmatch_extension(chan, chan->context, p->dtmf_buf, 1, chan->cid.cid_num) &&
- ((p->dtmf_buf[0] != '*') || (strlen(p->dtmf_buf) > 2))) {
- ast_debug(1, "Can't match %s from '%s' in context %s\n", p->dtmf_buf, chan->cid.cid_num ? chan->cid.cid_num : "<Unknown Caller>", chan->context);
+ } else if (!ast_canmatch_extension(chan, ast_channel_context(chan), p->dtmf_buf, 1,
+ S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))
+ && ((p->dtmf_buf[0] != '*') || (strlen(p->dtmf_buf) > 2))) {
+ ast_debug(1, "Can't match %s from '%s' in context %s\n", p->dtmf_buf,
+ S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, "<Unknown Caller>"),
+ ast_channel_context(chan));
break;
}
if (!timeout)
timeout = gendigittimeout;
- if (len && !ast_ignore_pattern(chan->context, p->dtmf_buf))
+ if (len && !ast_ignore_pattern(ast_channel_context(chan), p->dtmf_buf))
/*tone_zone_play_tone(p->subs[index].zfd, -1);*/
ast_indicate(chan, -1);
}
stop if now if appropriate */
if (ast_bridged_channel(p->sub->next->owner))
ast_queue_control(p->sub->next->owner, AST_CONTROL_UNHOLD);
- if (p->sub->owner->_state == AST_STATE_RINGING) {
+ if (ast_channel_state(p->sub->owner) == AST_STATE_RINGING) {
ast_indicate(ast_bridged_channel(p->sub->next->owner), AST_CONTROL_RINGING);
}
if (ast_channel_masquerade(p->sub->next->owner, ast_bridged_channel(p->sub->owner))) {
ast_log(LOG_WARNING, "Unable to masquerade %s as %s\n",
- ast_bridged_channel(p->sub->owner)->name, p->sub->next->owner->name);
+ ast_channel_name(ast_bridged_channel(p->sub->owner)), ast_channel_name(p->sub->next->owner));
return -1;
}
/* Orphan the channel */
unalloc_sub(p->sub->next);
} else if (ast_bridged_channel(p->sub->next->owner)) {
- if (p->sub->owner->_state == AST_STATE_RINGING) {
+ if (ast_channel_state(p->sub->owner) == AST_STATE_RINGING) {
ast_indicate(ast_bridged_channel(p->sub->next->owner), AST_CONTROL_RINGING);
}
ast_queue_control(p->sub->next->owner, AST_CONTROL_UNHOLD);
if (ast_channel_masquerade(p->sub->owner, ast_bridged_channel(p->sub->next->owner))) {
ast_log(LOG_WARNING, "Unable to masquerade %s as %s\n",
- ast_bridged_channel(p->sub->next->owner)->name, p->sub->owner->name);
+ ast_channel_name(ast_bridged_channel(p->sub->next->owner)), ast_channel_name(p->sub->owner));
return -1;
}
/*swap_subs(p, SUB_THREEWAY, SUB_REAL);*/
return 1;
} else {
ast_debug(1, "Neither %s nor %s are in a bridge, nothing to transfer\n",
- p->sub->owner->name, p->sub->next->owner->name);
+ ast_channel_name(p->sub->owner), ast_channel_name(p->sub->next->owner));
p->sub->next->owner->_softhangup |= AST_SOFTHANGUP_DEV;
if (p->sub->next->owner) {
p->sub->next->alreadygone = 1;
mgcp_queue_hangup(sub);
}
transmit_response(sub, "200", req, "OK");
- /* We dont send NTFY or AUEP to wildcard ep */
+ /* We don't send NTFY or AUEP to wildcard ep */
if (strcmp(p->name, p->parent->wcardep) != 0) {
transmit_notify_request(sub, "");
/* Audit endpoint.
return -1;
}
/* do not let * conference two down channels */
- if (sub->owner && sub->owner->_state == AST_STATE_DOWN && !sub->next->owner)
+ if (sub->owner && ast_channel_state(sub->owner) == AST_STATE_DOWN && !sub->next->owner)
return -1;
if (p->callwaiting || p->transfer || p->threewaycalling) {
(((ev[0] >= '0') && (ev[0] <= '9')) ||
((ev[0] >= 'A') && (ev[0] <= 'D')) ||
(ev[0] == '*') || (ev[0] == '#'))) {
- if (sub && sub->owner && (sub->owner->_state >= AST_STATE_UP)) {
+ if (sub && sub->owner && (ast_channel_state(sub->owner) >= AST_STATE_UP)) {
f.frametype = AST_FRAME_DTMF;
f.subclass.integer = ev[0];
f.src = "mgcp";
if (sscanf(req->identifier, "%30d", &seqno) != 1) {
seqno = 0;
}
- for (cur = sub->parent->parent->responses, next = cur->next; cur; cur = next, next = cur->next) {
+ for (cur = sub->parent->parent->responses, next = cur ? cur->next : NULL; cur; cur = next, next = cur ? cur->next : NULL) {
if (now - cur->whensent > RESPONSE_TIMEOUT) {
/* Delete this entry */
if (prev)
{
int res;
int reloading;
- struct mgcp_gateway *g, *gprev, *gnext;
+ struct mgcp_gateway *g, *gprev;
/*struct mgcp_gateway *g;*/
/*struct mgcp_endpoint *e;*/
/*time_t thispass = 0, lastpass = 0;*/
g = gateways;
gprev = NULL;
while(g) {
- gnext = g->next;
if(g->realtime) {
if(mgcp_prune_realtime_gateway(g)) {
if(gprev) {
- gprev->next = gnext;
- gprev = g;
+ gprev->next = g->next;
} else {
gateways = g->next;
}
} else {
gprev = g;
}
- g = gnext;
+ g = g->next;
}
ast_mutex_unlock(&gatelock);
lastrun = time(NULL);
return 0;
}
-static struct ast_channel *mgcp_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause)
+static struct ast_channel *mgcp_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, const char *dest, int *cause)
{
- format_t oldformat;
struct mgcp_subchannel *sub;
struct ast_channel *tmpc = NULL;
char tmp[256];
- char *dest = data;
- oldformat = format;
- format &= capability;
- if (!format) {
- ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format '%s'\n", ast_getformatname_multiple(tmp, sizeof(tmp), format));
+ if (!(ast_format_cap_has_joint(cap, global_capability))) {
+ ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format '%s'\n", ast_getformatname_multiple(tmp, sizeof(tmp), cap));
/*return NULL;*/
}
ast_copy_string(tmp, dest, sizeof(tmp));
ast_mutex_unlock(&sub->lock);
return NULL;
}
- tmpc = mgcp_new(sub->owner ? sub->next : sub, AST_STATE_DOWN, requestor ? requestor->linkedid : NULL);
+ tmpc = mgcp_new(sub->owner ? sub->next : sub, AST_STATE_DOWN, requestor ? ast_channel_linkedid(requestor) : NULL);
ast_mutex_unlock(&sub->lock);
if (!tmpc)
ast_log(LOG_WARNING, "Unable to make channel for '%s'\n", tmp);
/* Non-dynamic. Make sure we become that way if we're not */
AST_SCHED_DEL(sched, gw->expire);
gw->dynamic = 0;
- if (ast_get_ip(&gw->addr, v->value)) {
- if (!gw_reload) {
- ast_mutex_destroy(&gw->msgs_lock);
- ast_free(gw);
+ {
+ struct ast_sockaddr tmp;
+
+ ast_sockaddr_from_sin(&tmp, &gw->addr);
+ if (ast_get_ip(&tmp, v->value)) {
+ if (!gw_reload) {
+ ast_mutex_destroy(&gw->msgs_lock);
+ ast_free(gw);
+ }
+ return NULL;
}
- return NULL;
+ ast_sockaddr_to_sin(&tmp, &gw->addr);
}
}
} else if (!strcasecmp(v->name, "defaultip")) {
- if (ast_get_ip(&gw->defaddr, v->value)) {
+ struct ast_sockaddr tmp;
+
+ ast_sockaddr_from_sin(&tmp, &gw->defaddr);
+ if (ast_get_ip(&tmp, v->value)) {
if (!gw_reload) {
ast_mutex_destroy(&gw->msgs_lock);
ast_free(gw);
}
return NULL;
}
+ ast_sockaddr_to_sin(&tmp, &gw->defaddr);
} else if (!strcasecmp(v->name, "permit") ||
!strcasecmp(v->name, "deny")) {
gw->ha = ast_append_ha(v->name, v->value, gw->ha, NULL);
ast_mutex_init(&e->lock);
ast_mutex_init(&e->rqnt_queue_lock);
ast_mutex_init(&e->cmd_queue_lock);
+ e->cap = ast_format_cap_alloc_nolock();
ast_copy_string(e->name, v->value, sizeof(e->name));
e->needaudit = 1;
}
snprintf(e->rqnt_ident, sizeof(e->rqnt_ident), "%08lx", ast_random());
e->msgstate = -1;
e->amaflags = amaflags;
- e->capability = capability;
+ ast_format_cap_copy(e->cap, global_capability);
e->parent = gw;
e->ncs = ncs;
e->dtmfmode = dtmfmode;
ast_mutex_init(&e->lock);
ast_mutex_init(&e->rqnt_queue_lock);
ast_mutex_init(&e->cmd_queue_lock);
+ e->cap = ast_format_cap_alloc_nolock();
ast_copy_string(e->name, v->value, sizeof(e->name));
e->needaudit = 1;
}
e->parent = gw;
}
e->amaflags = amaflags;
- e->capability = capability;
+ ast_format_cap_copy(e->cap, global_capability);
e->dtmfmode = dtmfmode;
e->ncs = ncs;
e->pktcgatealloc = pktcgatealloc;
if (gw->addr.sin_addr.s_addr && !ntohs(gw->addr.sin_port)) {
gw->addr.sin_port = htons(DEFAULT_MGCP_GW_PORT);
}
- if (gw->addr.sin_addr.s_addr && ast_ouraddrfor(&gw->addr.sin_addr, &gw->ourip)) {
- memcpy(&gw->ourip, &__ourip, sizeof(gw->ourip));
+ {
+ struct ast_sockaddr tmp1, tmp2;
+ struct sockaddr_in tmp3 = {0,};
+
+ tmp3.sin_addr = gw->ourip;
+ ast_sockaddr_from_sin(&tmp1, &gw->addr);
+ ast_sockaddr_from_sin(&tmp2, &tmp3);
+ if (gw->addr.sin_addr.s_addr && ast_ouraddrfor(&tmp1, &tmp2)) {
+ memcpy(&gw->ourip, &__ourip, sizeof(gw->ourip));
+ } else {
+ ast_sockaddr_to_sin(&tmp2, &tmp3);
+ gw->ourip = tmp3.sin_addr;
+ }
}
}
{
struct mgcp_subchannel *sub = NULL;
- if (!(sub = chan->tech_pvt) || !(sub->rtp))
+ if (!(sub = ast_channel_tech_pvt(chan)) || !(sub->rtp))
return AST_RTP_GLUE_RESULT_FORBID;
*instance = sub->rtp ? ao2_ref(sub->rtp, +1), sub->rtp : NULL;
return AST_RTP_GLUE_RESULT_LOCAL;
}
-static int mgcp_set_rtp_peer(struct ast_channel *chan, struct ast_rtp_instance *rtp, struct ast_rtp_instance *vrtp, struct ast_rtp_instance *trtp, format_t codecs, int nat_active)
+static int mgcp_set_rtp_peer(struct ast_channel *chan, struct ast_rtp_instance *rtp, struct ast_rtp_instance *vrtp, struct ast_rtp_instance *trtp, const struct ast_format_cap *cap, int nat_active)
{
/* XXX Is there such thing as video support with MGCP? XXX */
struct mgcp_subchannel *sub;
- sub = chan->tech_pvt;
+ sub = ast_channel_tech_pvt(chan);
if (sub && !sub->alreadygone) {
- transmit_modify_with_sdp(sub, rtp, codecs);
+ transmit_modify_with_sdp(sub, rtp, cap);
return 0;
}
return -1;
}
-static format_t mgcp_get_codec(struct ast_channel *chan)
+static void mgcp_get_codec(struct ast_channel *chan, struct ast_format_cap *result)
{
- struct mgcp_subchannel *sub = chan->tech_pvt;
+ struct mgcp_subchannel *sub = ast_channel_tech_pvt(chan);
struct mgcp_endpoint *p = sub->parent;
- return p->capability;
+ ast_format_cap_copy(result, p->cap);
}
static struct ast_rtp_glue mgcp_rtp_glue = {
static int acf_channel_read(struct ast_channel *chan, const char *funcname, char *args, char *buf, size_t buflen)
{
- struct mgcp_subchannel *sub = chan->tech_pvt;
+ struct mgcp_subchannel *sub = ast_channel_tech_pvt(chan);
int res = 0;
/* Sanity check */
- if (!chan || chan->tech != &mgcp_tech) {
+ if (!chan || ast_channel_tech(chan) != &mgcp_tech) {
ast_log(LOG_ERROR, "This function requires a valid MGCP channel\n");
return -1;
}
ast_mutex_destroy(&e->lock);
ast_mutex_destroy(&e->rqnt_queue_lock);
ast_mutex_destroy(&e->cmd_queue_lock);
+ e->cap = ast_format_cap_destroy(e->cap);
ast_free(e);
}
char *cat;
struct ast_hostent ahp;
struct hostent *hp;
- int format;
+ struct ast_format format;
struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
if (gethostname(ourhost, sizeof(ourhost)-1)) {
memcpy(&bindaddr.sin_addr, hp->h_addr, sizeof(bindaddr.sin_addr));
}
} else if (!strcasecmp(v->name, "allow")) {
- format = ast_getformatbyname(v->value);
- if (format < 1) {
+ ast_getformatbyname(v->value, &format);
+ if (!format.id) {
ast_log(LOG_WARNING, "Cannot allow unknown format '%s'\n", v->value);
} else {
- capability |= format;
+ ast_format_cap_add(global_capability, &format);
}
} else if (!strcasecmp(v->name, "disallow")) {
- format = ast_getformatbyname(v->value);
- if (format < 1) {
- ast_log(LOG_WARNING, "Cannot disallow unknown format '%s'\n", v->value);
+ ast_getformatbyname(v->value, &format);
+ if (!format.id) {
+ ast_log(LOG_WARNING, "Cannot allow unknown format '%s'\n", v->value);
} else {
- capability &= ~format;
+ ast_format_cap_remove(global_capability, &format);
}
} else if (!strcasecmp(v->name, "tos")) {
if (ast_str2tos(v->value, &qos.tos)) {
memcpy(&__ourip, hp->h_addr, sizeof(__ourip));
}
if (!ntohs(bindaddr.sin_port))
- bindaddr.sin_port = ntohs(DEFAULT_MGCP_CA_PORT);
+ bindaddr.sin_port = htons(DEFAULT_MGCP_CA_PORT);
bindaddr.sin_family = AF_INET;
ast_mutex_lock(&netlock);
if (mgcpsock > -1)
} else {
ast_verb(2, "MGCP Listening on %s:%d\n",
ast_inet_ntoa(bindaddr.sin_addr), ntohs(bindaddr.sin_port));
- ast_netsock_set_qos(mgcpsock, qos.tos, qos.cos, "MGCP");
+ ast_set_qos(mgcpsock, qos.tos, qos.cos, "MGCP");
}
}
ast_mutex_unlock(&netlock);
/*! \brief load_module: PBX load module - initialization ---*/
static int load_module(void)
{
- if (!(sched = sched_context_create())) {
+ struct ast_format tmpfmt;
+
+ if (!(global_capability = ast_format_cap_alloc())) {
+ return AST_MODULE_LOAD_FAILURE;
+ }
+ if (!(mgcp_tech.capabilities = ast_format_cap_alloc())) {
+ return AST_MODULE_LOAD_FAILURE;
+ }
+ ast_format_cap_add(global_capability, ast_format_set(&tmpfmt, AST_FORMAT_ULAW, 0));
+ ast_format_cap_add(mgcp_tech.capabilities, ast_format_set(&tmpfmt, AST_FORMAT_ULAW, 0));
+ ast_format_cap_add(mgcp_tech.capabilities, ast_format_set(&tmpfmt, AST_FORMAT_ALAW, 0));
+ if (!(sched = ast_sched_context_create())) {
ast_log(LOG_WARNING, "Unable to create schedule context\n");
return AST_MODULE_LOAD_FAILURE;
}
if (!(io = io_context_create())) {
ast_log(LOG_WARNING, "Unable to create I/O context\n");
- sched_context_destroy(sched);
+ ast_sched_context_destroy(sched);
return AST_MODULE_LOAD_FAILURE;
}
if (ast_channel_register(&mgcp_tech)) {
ast_log(LOG_ERROR, "Unable to register channel class 'MGCP'\n");
io_context_destroy(io);
- sched_context_destroy(sched);
+ ast_sched_context_destroy(sched);
return AST_MODULE_LOAD_FAILURE;
}
close(mgcpsock);
ast_rtp_glue_unregister(&mgcp_rtp_glue);
ast_cli_unregister_multiple(cli_mgcp, sizeof(cli_mgcp) / sizeof(struct ast_cli_entry));
- sched_context_destroy(sched);
+ ast_sched_context_destroy(sched);
+
+ global_capability = ast_format_cap_destroy(global_capability);
+ mgcp_tech.capabilities = ast_format_cap_destroy(mgcp_tech.capabilities);
return 0;
}
-AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Media Gateway Control Protocol (MGCP)",
+AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "Media Gateway Control Protocol (MGCP)",
.load = load_module,
.unload = unload_module,
.reload = reload,
+ .load_pri = AST_MODPRI_CHANNEL_DRIVER,
+ .nonoptreq = "res_pktccops",
);