dect
/
asterisk
Archived
13
0
Fork 0

Asterisk media architecture conversion - no more format bitfields

This patch is the foundation of an entire new way of looking at media in Asterisk.
The code present in this patch is everything required to complete phase1 of my
Media Architecture proposal.  For more information about this project visit the link below.
https://wiki.asterisk.org/wiki/display/AST/Media+Architecture+Proposal

The primary function of this patch is to convert all the usages of format
bitfields in Asterisk to use the new format and format_cap APIs.  Functionally
no change in behavior should be present in this patch.  Thanks to twilson
and russell for all the time they spent reviewing these changes.

Review: https://reviewboard.asterisk.org/r/1083/



git-svn-id: http://svn.digium.com/svn/asterisk/trunk@306010 f38db490-d61c-443f-a65b-d21fe96a405b
This commit is contained in:
dvossel 2011-02-03 16:22:10 +00:00
parent 8170aae0a0
commit 4aca3187a3
168 changed files with 8120 additions and 3764 deletions

View File

@ -71,7 +71,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#define DEVICE_FRAME_FORMAT AST_FORMAT_SLINEAR
#define CHANNEL_FRAME_SIZE 320
static format_t prefformat = DEVICE_FRAME_FORMAT;
static struct ast_format prefformat;
static int discovery_interval = 60; /* The device discovery interval, default 60 seconds. */
static pthread_t discovery_thread = AST_PTHREADT_NULL; /* The discovery thread */
@ -196,7 +196,7 @@ static char *mblsendsms_desc =
static struct ast_channel *mbl_new(int state, struct mbl_pvt *pvt, char *cid_num,
const struct ast_channel *requestor);
static struct ast_channel *mbl_request(const char *type, format_t format,
static struct ast_channel *mbl_request(const char *type, struct ast_format_cap *cap,
const struct ast_channel *requestor, void *data, int *cause);
static int mbl_call(struct ast_channel *ast, char *dest, int timeout);
static int mbl_hangup(struct ast_channel *ast);
@ -450,10 +450,9 @@ static struct msg_queue_entry *msg_queue_head(struct mbl_pvt *pvt);
* channel stuff
*/
static const struct ast_channel_tech mbl_tech = {
static struct ast_channel_tech mbl_tech = {
.type = "Mobile",
.description = "Bluetooth Mobile Device Channel Driver",
.capabilities = AST_FORMAT_SLINEAR,
.requester = mbl_request,
.call = mbl_call,
.hangup = mbl_hangup,
@ -844,11 +843,11 @@ static struct ast_channel *mbl_new(int state, struct mbl_pvt *pvt, char *cid_num
}
chn->tech = &mbl_tech;
chn->nativeformats = prefformat;
chn->rawreadformat = prefformat;
chn->rawwriteformat = prefformat;
chn->writeformat = prefformat;
chn->readformat = prefformat;
ast_format_cap_add(chn->nativeformats, &prefformat);
ast_format_copy(&chn->rawreadformat, &prefformat);
ast_format_copy(&chn->rawwriteformat, &prefformat);
ast_format_copy(&chn->writeformat, &prefformat);
ast_format_copy(&chn->readformat, &prefformat);
chn->tech_pvt = pvt;
if (state == AST_STATE_RING)
@ -867,7 +866,7 @@ e_return:
return NULL;
}
static struct ast_channel *mbl_request(const char *type, format_t format,
static struct ast_channel *mbl_request(const char *type, struct ast_format_cap *cap,
const struct ast_channel *requestor, void *data, int *cause)
{
@ -875,7 +874,6 @@ static struct ast_channel *mbl_request(const char *type, format_t format,
struct mbl_pvt *pvt;
char *dest_dev = NULL;
char *dest_num = NULL;
format_t oldformat;
int group = -1;
if (!data) {
@ -884,10 +882,9 @@ static struct ast_channel *mbl_request(const char *type, format_t format,
return NULL;
}
oldformat = format;
format &= (AST_FORMAT_SLINEAR);
if (!format) {
ast_log(LOG_WARNING, "Asked to get a channel of unsupported format '%s'\n", ast_getformatname(oldformat));
if (!(ast_format_cap_iscompatible(cap, &prefformat))) {
char tmp[256];
ast_log(LOG_WARNING, "Asked to get a channel of unsupported format '%s'\n", ast_getformatname_multiple(tmp, sizeof(tmp), cap));
*cause = AST_CAUSE_FACILITY_NOT_IMPLEMENTED;
return NULL;
}
@ -1099,7 +1096,7 @@ static struct ast_frame *mbl_read(struct ast_channel *ast)
memset(&pvt->fr, 0x00, sizeof(struct ast_frame));
pvt->fr.frametype = AST_FRAME_VOICE;
pvt->fr.subclass.codec = DEVICE_FRAME_FORMAT;
ast_format_set(&pvt->fr.subclass.format, DEVICE_FRAME_FORMAT, 0);
pvt->fr.src = "Mobile";
pvt->fr.offset = AST_FRIENDLY_OFFSET;
pvt->fr.mallocd = 0;
@ -4534,6 +4531,7 @@ static int unload_module(void)
if (sdp_session)
sdp_close(sdp_session);
mbl_tech.capabilities = ast_format_cap_destroy(mbl_tech.capabilities);
return 0;
}
@ -4542,6 +4540,11 @@ static int load_module(void)
int dev_id, s;
if (!(mbl_tech.capabilities = ast_format_cap_alloc())) {
return AST_MODULE_LOAD_DECLINE;
}
ast_format_set(&prefformat, DEVICE_FRAME_FORMAT, 0);
ast_format_cap_add(mbl_tech.capabilities, &prefformat);
/* Check if we have Bluetooth, no point loading otherwise... */
dev_id = hci_get_route(NULL);
s = hci_open_dev(dev_id);

View File

@ -66,7 +66,7 @@ static struct ast_jb_conf default_jbconf =
static struct ast_jb_conf global_jbconf;
/* Channel Definition */
static struct ast_channel *ooh323_request(const char *type, format_t format,
static struct ast_channel *ooh323_request(const char *type, struct ast_format_cap *cap,
const struct ast_channel *requestor, void *data, int *cause);
static int ooh323_digit_begin(struct ast_channel *ast, char digit);
static int ooh323_digit_end(struct ast_channel *ast, char digit, unsigned int duration);
@ -82,7 +82,7 @@ static int ooh323_fixup(struct ast_channel *oldchan, struct ast_channel *newchan
static enum ast_rtp_glue_result ooh323_get_rtp_peer(struct ast_channel *chan, struct ast_rtp_instance **rtp);
static enum ast_rtp_glue_result ooh323_get_vrtp_peer(struct ast_channel *chan, struct ast_rtp_instance **rtp);
static int ooh323_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);
struct ast_rtp_instance *vrtp, struct ast_rtp_instance *trtp, const struct ast_format_cap *codecs, int nat_active);
static struct ast_udptl *ooh323_get_udptl_peer(struct ast_channel *chan);
static int ooh323_set_udptl_peer(struct ast_channel *chan, struct ast_udptl *udptl);
@ -92,10 +92,9 @@ static void print_codec_to_cli(int fd, struct ast_codec_pref *pref);
struct ooh323_peer *find_friend(const char *name, int port);
static const struct ast_channel_tech ooh323_tech = {
static struct ast_channel_tech ooh323_tech = {
.type = type,
.description = tdesc,
.capabilities = -1,
.properties = AST_CHAN_TP_WANTSJITTER | AST_CHAN_TP_CREATESJITTER,
.requester = ooh323_request,
.send_digit_begin = ooh323_digit_begin,
@ -172,9 +171,9 @@ static struct ooh323_pvt {
char callee_url[AST_MAX_EXTENSION];
int port;
format_t readformat; /* negotiated read format */
format_t writeformat; /* negotiated write format */
format_t capability;
struct ast_format readformat; /* negotiated read format */
struct ast_format writeformat; /* negotiated write format */
struct ast_format_cap *cap;
struct ast_codec_pref prefs;
int dtmfmode;
int dtmfcodec;
@ -204,7 +203,7 @@ struct ooh323_user{
unsigned inUse;
char accountcode[20];
int amaflags;
format_t capability;
struct ast_format_cap *cap;
struct ast_codec_pref prefs;
int dtmfmode;
int dtmfcodec;
@ -225,7 +224,7 @@ struct ooh323_peer{
char name[256];
unsigned outgoinglimit;
unsigned outUse;
format_t capability;
struct ast_format_cap *cap;
struct ast_codec_pref prefs;
char accountcode[20];
int amaflags;
@ -286,7 +285,7 @@ static int gPort = 1720;
static char gIP[20];
static char gCallerID[AST_MAX_EXTENSION] = "";
static struct ooAliases *gAliasList;
static format_t gCapability = AST_FORMAT_ULAW;
static struct ast_format_cap *gCap;
static struct ast_codec_pref gPrefs;
static int gDTMFMode = H323_DTMF_RFC2833;
static int gDTMFCodec = 101;
@ -337,14 +336,14 @@ static pthread_t monitor_thread = AST_PTHREADT_NULL;
static struct ast_channel *ooh323_new(struct ooh323_pvt *i, int state,
const char *host, int capability, const char *linkedid)
const char *host, struct ast_format_cap *cap, const char *linkedid)
{
struct ast_channel *ch = NULL;
int fmt = 0;
struct ast_format tmpfmt;
if (gH323Debug)
ast_verbose("--- ooh323_new - %s, %d\n", host, capability);
ast_verbose("--- ooh323_new - %s\n", host);
ast_format_clear(&tmpfmt);
/* Don't hold a h323 pvt lock while we allocate a channel */
ast_mutex_unlock(&i->lock);
ch = ast_channel_alloc(1, state, i->callerid_num, i->callerid_name,
@ -360,12 +359,14 @@ static struct ast_channel *ooh323_new(struct ooh323_pvt *i, int state,
ast_channel_lock(ch);
ch->tech = &ooh323_tech;
if (capability)
fmt = ast_best_codec(capability);
if (!fmt)
fmt = ast_codec_pref_index(&i->prefs, 0);
if (cap)
ast_best_codec(cap, &tmpfmt);
if (!tmpfmt.id)
ast_codec_pref_index(&i->prefs, 0, &tmpfmt);
ch->nativeformats = ch->rawwriteformat = ch->rawreadformat = fmt;
ast_format_cap_add(ch->nativeformats, &tmpfmt);
ast_format_copy(&ch->rawwriteformat, &tmpfmt);
ast_format_copy(&ch->rawreadformat, &tmpfmt);
ast_channel_set_fd(ch, 0, ast_rtp_instance_fd(i->rtp, 0));
ast_channel_set_fd(ch, 1, ast_rtp_instance_fd(i->rtp, 1));
@ -377,8 +378,8 @@ static struct ast_channel *ooh323_new(struct ooh323_pvt *i, int state,
ch->rings = 1;
ch->adsicpe = AST_ADSI_UNAVAILABLE;
ast_set_write_format(ch, fmt);
ast_set_read_format(ch, fmt);
ast_set_write_format(ch, &tmpfmt);
ast_set_read_format(ch, &tmpfmt);
ch->tech_pvt = i;
i->owner = ch;
ast_module_ref(myself);
@ -472,6 +473,11 @@ static struct ooh323_pvt *ooh323_alloc(int callref, char *callToken)
ast_log(LOG_ERROR, "Couldn't allocate private ooh323 structure\n");
return NULL;
}
if (!(pvt->cap = ast_format_cap_alloc_nolock())) {
ast_free(pvt);
ast_log(LOG_ERROR, "Couldn't allocate private ooh323 structure\n");
return NULL;
}
ast_mutex_init(&pvt->lock);
ast_mutex_lock(&pvt->lock);
@ -529,7 +535,7 @@ static struct ooh323_pvt *ooh323_alloc(int callref, char *callToken)
ast_copy_string(pvt->accountcode, gAccountcode, sizeof(pvt->accountcode));
pvt->amaflags = gAMAFLAGS;
pvt->capability = gCapability;
ast_format_cap_copy(pvt->cap, gCap);
memcpy(&pvt->prefs, &gPrefs, sizeof(pvt->prefs));
ast_mutex_unlock(&pvt->lock);
@ -549,7 +555,7 @@ static struct ooh323_pvt *ooh323_alloc(int callref, char *callToken)
/*
Possible data values - peername, exten/peername, exten@ip
*/
static struct ast_channel *ooh323_request(const char *type, format_t format,
static struct ast_channel *ooh323_request(const char *type, struct ast_format_cap *cap,
const struct ast_channel *requestor, void *data, int *cause)
{
@ -560,17 +566,14 @@ static struct ast_channel *ooh323_request(const char *type, format_t format,
char *ext = NULL;
char tmp[256];
char formats[FORMAT_STRING_SIZE];
int oldformat;
int port = 0;
if (gH323Debug)
ast_verbose("--- ooh323_request - data %s format %s\n", (char*)data,
ast_getformatname_multiple(formats,FORMAT_STRING_SIZE,format));
ast_getformatname_multiple(formats,FORMAT_STRING_SIZE,cap));
oldformat = format;
format &= AST_FORMAT_AUDIO_MASK;
if (!format) {
ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format '%lld'\n", (long long) format);
if (!(ast_format_cap_has_type(cap, AST_FORMAT_TYPE_AUDIO))) {
ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format '%s'\n", ast_getformatname_multiple(formats,FORMAT_STRING_SIZE,cap));
return NULL;
}
@ -633,7 +636,7 @@ static struct ast_channel *ooh323_request(const char *type, format_t format,
if (ext)
ast_copy_string(p->exten, ext, sizeof(p->exten));
p->capability = peer->capability;
ast_format_cap_copy(p->cap, peer->cap);
memcpy(&p->prefs, &peer->prefs, sizeof(struct ast_codec_pref));
p->dtmfmode |= peer->dtmfmode;
p->dtmfcodec = peer->dtmfcodec;
@ -667,7 +670,7 @@ static struct ast_channel *ooh323_request(const char *type, format_t format,
p->dtmfcodec = gDTMFCodec;
p->t38support = gT38Support;
p->rtptimeout = gRTPTimeout;
p->capability = gCapability;
ast_format_cap_copy(p->cap, gCap);
p->rtdrinterval = gRTDRInterval;
p->rtdrcount = gRTDRCount;
p->faststart = gFastStart;
@ -686,7 +689,7 @@ static struct ast_channel *ooh323_request(const char *type, format_t format,
}
chan = ooh323_new(p, AST_STATE_DOWN, p->username, format,
chan = ooh323_new(p, AST_STATE_DOWN, p->username, cap,
requestor ? requestor->linkedid : NULL);
ast_mutex_unlock(&p->lock);
@ -1140,16 +1143,16 @@ static int ooh323_write(struct ast_channel *ast, struct ast_frame *f)
}
if (!(f->subclass.codec & ast->nativeformats)) {
if (ast->nativeformats != 0) {
if (!(ast_format_cap_iscompatible(ast->nativeformats, &f->subclass.format))) {
if (!(ast_format_cap_is_empty(ast->nativeformats))) {
ast_log(LOG_WARNING,
"Asked to transmit frame type %s, while native formats is %s (read/write = %s/%s)\n",
ast_getformatname(f->subclass.codec),
ast_getformatname(&f->subclass.format),
ast_getformatname_multiple(buf, sizeof(buf), ast->nativeformats),
ast_getformatname(ast->readformat),
ast_getformatname(ast->writeformat));
ast_getformatname(&ast->readformat),
ast_getformatname(&ast->writeformat));
ast_set_write_format(ast, f->subclass.codec);
ast_set_write_format(ast, &f->subclass.format);
} else {
/* ast_set_write_format(ast, f->subclass);
ast->nativeformats = f->subclass; */
@ -1409,14 +1412,14 @@ static int ooh323_fixup(struct ast_channel *oldchan, struct ast_channel *newchan
}
void ooh323_set_write_format(ooCallData *call, int fmt, int txframes)
void ooh323_set_write_format(ooCallData *call, struct ast_format *fmt, int txframes)
{
struct ooh323_pvt *p = NULL;
char formats[FORMAT_STRING_SIZE];
if (gH323Debug)
ast_verbose("--- ooh323_update_writeformat %s/%d\n",
ast_getformatname_multiple(formats,FORMAT_STRING_SIZE, fmt), txframes);
ast_getformatname(fmt), txframes);
p = find_call(call);
if (!p) {
@ -1426,7 +1429,7 @@ void ooh323_set_write_format(ooCallData *call, int fmt, int txframes)
ast_mutex_lock(&p->lock);
p->writeformat = fmt;
ast_format_copy(&p->writeformat, fmt);
if (p->owner) {
while (p->owner && ast_channel_trylock(p->owner)) {
@ -1440,8 +1443,8 @@ void ooh323_set_write_format(ooCallData *call, int fmt, int txframes)
}
if (gH323Debug)
ast_verbose("Writeformat before update %s/%s\n",
ast_getformatname_multiple(formats,FORMAT_STRING_SIZE, p->owner->writeformat),
ast_getformatname_multiple(formats,FORMAT_STRING_SIZE, p->owner->nativeformats));
ast_getformatname(&p->owner->writeformat),
ast_getformatname_multiple(formats, sizeof(formats), p->owner->nativeformats));
if (txframes)
ast_codec_pref_setsize(&p->prefs, fmt, txframes);
ast_rtp_codecs_packetization_set(ast_rtp_instance_get_codecs(p->rtp), p->rtp, &p->prefs);
@ -1454,9 +1457,9 @@ void ooh323_set_write_format(ooCallData *call, int fmt, int txframes)
p->rtp, p->dtmfcodec, "audio", "cisco-telephone-event", 0);
}
p->owner->nativeformats = fmt;
ast_set_write_format(p->owner, p->owner->writeformat);
ast_set_read_format(p->owner, p->owner->readformat);
ast_format_cap_set(p->owner->nativeformats, fmt);
ast_set_write_format(p->owner, &p->owner->writeformat);
ast_set_read_format(p->owner, &p->owner->readformat);
ast_channel_unlock(p->owner);
} else
ast_log(LOG_ERROR, "No owner found\n");
@ -1468,14 +1471,13 @@ void ooh323_set_write_format(ooCallData *call, int fmt, int txframes)
ast_verbose("+++ ooh323_update_writeformat\n");
}
void ooh323_set_read_format(ooCallData *call, int fmt)
void ooh323_set_read_format(ooCallData *call, struct ast_format *fmt)
{
struct ooh323_pvt *p = NULL;
char formats[FORMAT_STRING_SIZE];
if (gH323Debug)
ast_verbose("--- ooh323_update_readformat %s\n",
ast_getformatname_multiple(formats,FORMAT_STRING_SIZE, fmt));
ast_getformatname(fmt));
p = find_call(call);
if (!p) {
@ -1485,8 +1487,7 @@ void ooh323_set_read_format(ooCallData *call, int fmt)
ast_mutex_lock(&p->lock);
p->readformat = fmt;
ast_format_copy(&p->readformat, fmt);
if (p->owner) {
while (p->owner && ast_channel_trylock(p->owner)) {
@ -1501,9 +1502,9 @@ void ooh323_set_read_format(ooCallData *call, int fmt)
if (gH323Debug)
ast_verbose("Readformat before update %s\n",
ast_getformatname_multiple(formats,FORMAT_STRING_SIZE, p->owner->readformat));
p->owner->nativeformats = fmt;
ast_set_read_format(p->owner, p->owner->readformat);
ast_getformatname(&p->owner->readformat));
ast_format_cap_set(p->owner->nativeformats, fmt);
ast_set_read_format(p->owner, &p->owner->readformat);
ast_channel_unlock(p->owner);
} else
ast_log(LOG_ERROR, "No owner found\n");
@ -1760,7 +1761,7 @@ int ooh323_onReceivedSetup(ooCallData *call, Q931Message *pmsg)
ast_copy_string(p->context, user->context, sizeof(p->context));
ast_copy_string(p->accountcode, user->accountcode, sizeof(p->accountcode));
p->amaflags = user->amaflags;
p->capability = user->capability;
ast_format_cap_copy(p->cap, user->cap);
memcpy(&p->prefs, &user->prefs, sizeof(struct ast_codec_pref));
p->dtmfmode |= user->dtmfmode;
p->dtmfcodec = user->dtmfcodec;
@ -1804,7 +1805,7 @@ int ooh323_onReceivedSetup(ooCallData *call, Q931Message *pmsg)
}
}
ooh323c_set_capability_for_call(call, &p->prefs, p->capability, p->dtmfmode, p->dtmfcodec,
ooh323c_set_capability_for_call(call, &p->prefs, p->cap, p->dtmfmode, p->dtmfcodec,
p->t38support);
configure_local_rtp(p, call);
@ -1971,7 +1972,7 @@ int onNewCallCreated(ooCallData *call)
p->username?p->username:"NULL", call->callToken, prefsBuf);
}
ooh323c_set_capability_for_call(call, &p->prefs, p->capability,
ooh323c_set_capability_for_call(call, &p->prefs, p->cap,
p->dtmfmode, p->dtmfcodec, p->t38support);
configure_local_rtp(p, call);
@ -2157,6 +2158,7 @@ void ooh323_delete_peer(struct ooh323_peer *peer)
if(peer->url) free(peer->url);
if(peer->e164) free(peer->e164);
peer->cap = ast_format_cap_destroy(peer->cap);
free(peer);
}
@ -2176,10 +2178,14 @@ static struct ooh323_user *build_user(const char *name, struct ast_variable *v)
user = ast_calloc(1,sizeof(struct ooh323_user));
if (user) {
if (!(user->cap = ast_format_cap_alloc_nolock())) {
ast_free(user);
return NULL;
}
memset(user, 0, sizeof(struct ooh323_user));
ast_mutex_init(&user->lock);
ast_copy_string(user->name, name, sizeof(user->name));
user->capability = gCapability;
ast_format_cap_copy(user->cap, gCap);
memcpy(&user->prefs, &gPrefs, sizeof(user->prefs));
user->rtptimeout = gRTPTimeout;
user->dtmfmode = gDTMFMode;
@ -2223,14 +2229,14 @@ static struct ooh323_user *build_user(const char *name, struct ast_variable *v)
} else user->rtpmask = NULL;
} else if (!strcasecmp(v->name, "disallow")) {
ast_parse_allow_disallow(&user->prefs,
&user->capability, v->value, 0);
user->cap, v->value, 0);
} else if (!strcasecmp(v->name, "allow")) {
const char* tcodecs = v->value;
if (!strcasecmp(v->value, "all")) {
tcodecs = "ulaw,alaw,g729,g723,gsm";
}
ast_parse_allow_disallow(&user->prefs,
&user->capability, tcodecs, 1);
user->cap, tcodecs, 1);
} else if (!strcasecmp(v->name, "amaflags")) {
user->amaflags = ast_cdr_amaflags2int(v->value);
} else if (!strcasecmp(v->name, "ip")) {
@ -2285,10 +2291,14 @@ static struct ooh323_peer *build_peer(const char *name, struct ast_variable *v,
peer = ast_calloc(1, sizeof(*peer));
if (peer) {
if (!(peer->cap = ast_format_cap_alloc_nolock())) {
ast_free(peer);
return NULL;
}
memset(peer, 0, sizeof(struct ooh323_peer));
ast_mutex_init(&peer->lock);
ast_copy_string(peer->name, name, sizeof(peer->name));
peer->capability = gCapability;
ast_format_cap_copy(peer->cap, gCap);
memcpy(&peer->prefs, &gPrefs, sizeof(peer->prefs));
peer->rtptimeout = gRTPTimeout;
ast_copy_string(peer->accountcode, gAccountcode, sizeof(peer->accountcode));
@ -2362,14 +2372,14 @@ static struct ooh323_peer *build_peer(const char *name, struct ast_variable *v,
sizeof(peer->rtpmaskstr));
} else peer->rtpmask = NULL;
} else if (!strcasecmp(v->name, "disallow")) {
ast_parse_allow_disallow(&peer->prefs, &peer->capability,
ast_parse_allow_disallow(&peer->prefs, peer->cap,
v->value, 0);
} else if (!strcasecmp(v->name, "allow")) {
const char* tcodecs = v->value;
if (!strcasecmp(v->value, "all")) {
tcodecs = "ulaw,alaw,g729,g723,gsm";
}
ast_parse_allow_disallow(&peer->prefs, &peer->capability,
ast_parse_allow_disallow(&peer->prefs, peer->cap,
tcodecs, 1);
} else if (!strcasecmp(v->name, "amaflags")) {
peer->amaflags = ast_cdr_amaflags2int(v->value);
@ -2475,6 +2485,7 @@ int reload_config(int reload)
struct ooh323_peer *peer = NULL;
char *cat;
const char *utype;
struct ast_format tmpfmt;
if (gH323Debug)
ast_verbose("--- reload_config\n");
@ -2509,7 +2520,7 @@ int reload_config(int reload)
gPort = 1720;
gIP[0] = '\0';
strcpy(gCallerID, DEFAULT_H323ID);
gCapability = AST_FORMAT_ALAW;
ast_format_cap_set(gCap, ast_format_set(&tmpfmt, AST_FORMAT_ALAW, 0));
memset(&gPrefs, 0, sizeof(struct ast_codec_pref));
gDTMFMode = H323_DTMF_RFC2833;
gDTMFCodec = 101;
@ -2678,13 +2689,13 @@ int reload_config(int reload)
} else if (!strcasecmp(v->name, "accountcode")) {
ast_copy_string(gAccountcode, v->value, sizeof(gAccountcode));
} else if (!strcasecmp(v->name, "disallow")) {
ast_parse_allow_disallow(&gPrefs, &gCapability, v->value, 0);
ast_parse_allow_disallow(&gPrefs, gCap, v->value, 0);
} else if (!strcasecmp(v->name, "allow")) {
const char* tcodecs = v->value;
if (!strcasecmp(v->value, "all")) {
tcodecs = "ulaw,alaw,g729,g723,gsm";
}
ast_parse_allow_disallow(&gPrefs, &gCapability, tcodecs, 1);
ast_parse_allow_disallow(&gPrefs, gCap, tcodecs, 1);
} else if (!strcasecmp(v->name, "dtmfmode")) {
if (!strcasecmp(v->value, "inband"))
gDTMFMode = H323_DTMF_INBAND;
@ -2893,7 +2904,7 @@ static char *handle_cli_ooh323_show_peers(struct ast_cli_entry *e, int cmd, stru
ast_cli(a->fd, FORMAT, peer->name,
peer->accountcode,
ip_port,
ast_getformatname_multiple(formats,FORMAT_STRING_SIZE,peer->capability));
ast_getformatname_multiple(formats,FORMAT_STRING_SIZE,peer->cap));
prev = peer;
peer = peer->next;
ast_mutex_unlock(&prev->lock);
@ -2907,15 +2918,15 @@ static char *handle_cli_ooh323_show_peers(struct ast_cli_entry *e, int cmd, stru
/*! \brief Print codec list from preference to CLI/manager */
static void print_codec_to_cli(int fd, struct ast_codec_pref *pref)
{
int x, codec;
int x;
struct ast_format tmpfmt;
for (x = 0; x < 32; x++) {
codec = ast_codec_pref_index(pref, x);
if (!codec)
ast_codec_pref_index(pref, x, &tmpfmt);
if (!tmpfmt.id)
break;
ast_cli(fd, "%s", ast_getformatname(codec));
ast_cli(fd, "%s", ast_getformatname(&tmpfmt));
ast_cli(fd, ":%d", pref->framing[x]);
if (x < 31 && ast_codec_pref_index(pref, x + 1))
if (x < 31 && ast_codec_pref_index(pref, x + 1, &tmpfmt))
ast_cli(fd, ",");
}
if (!x)
@ -3038,7 +3049,7 @@ static char *handle_cli_ooh323_show_users(struct ast_cli_entry *e, int cmd, stru
ast_mutex_lock(&user->lock);
ast_cli(a->fd, FORMAT1, user->name,
user->accountcode, user->context,
ast_getformatname_multiple(formats, FORMAT_STRING_SIZE, user->capability));
ast_getformatname_multiple(formats, FORMAT_STRING_SIZE, user->cap));
prev = user;
user = user->next;
ast_mutex_unlock(&prev->lock);
@ -3137,7 +3148,7 @@ static char *handle_cli_ooh323_show_config(struct ast_cli_entry *e, int cmd, str
ast_cli(a->fd, "%-20s%s\n", "Context:", gContext);
ast_cli(a->fd, "%-20s%s\n", "Capability:",
ast_getformatname_multiple(value,FORMAT_STRING_SIZE,gCapability));
ast_getformatname_multiple(value,FORMAT_STRING_SIZE,gCap));
ast_cli(a->fd, "%-20s", "DTMF Mode: ");
if (gDTMFMode & H323_DTMF_CISCO) {
@ -3207,6 +3218,7 @@ static int load_module(void)
int res;
struct ooAliases * pNewAlias = NULL;
struct ooh323_peer *peer = NULL;
struct ast_format tmpfmt;
OOH225MsgCallbacks h225Callbacks = {0, 0, 0, 0};
OOH323CALLBACKS h323Callbacks = {
@ -3221,6 +3233,14 @@ static int load_module(void)
.onReceivedDTMF = ooh323_onReceivedDigit,
.onModeChanged = onModeChanged
};
if (!(gCap = ast_format_cap_alloc())) {
return 1;
}
if (!(ooh323_tech.capabilities = ast_format_cap_alloc())) {
return 1;
}
ast_format_cap_add(gCap, ast_format_set(&tmpfmt, AST_FORMAT_ULAW, 0));
ast_format_cap_add_all(ooh323_tech.capabilities);
myself = ast_module_info->self;
@ -3334,7 +3354,7 @@ static int load_module(void)
ooH323EpSetH323Callbacks(h323Callbacks);
/* Add endpoint capabilities */
if (ooh323c_set_capability(&gPrefs, gCapability, gDTMFMode, gDTMFCodec) < 0) {
if (ooh323c_set_capability(&gPrefs, gCap, gDTMFMode, gDTMFCodec) < 0) {
ast_log(LOG_ERROR, "Capabilities failure for OOH323. OOH323 Disabled.\n");
return 1;
}
@ -3558,7 +3578,7 @@ int ooh323_destroy(struct ooh323_pvt *p)
ast_mutex_unlock(&cur->lock);
ast_mutex_destroy(&cur->lock);
cur->cap = ast_format_cap_destroy(cur->cap);
ast_free(cur);
}
@ -3623,6 +3643,7 @@ int delete_users()
free(prev->rtpmask);
}
}
prev->cap = ast_format_cap_destroy(prev->cap);
free(prev);
if (cur == userl.users) {
break;
@ -3751,6 +3772,8 @@ static int unload_module(void)
ast_verbose("+++ ooh323 unload_module \n");
}
gCap = ast_format_cap_destroy(gCap);
ooh323_tech.capabilities = ast_format_cap_destroy(ooh323_tech.capabilities);
return 0;
}
@ -3802,22 +3825,23 @@ int ooh323_update_capPrefsOrderForCall
(ooCallData *call, struct ast_codec_pref *prefs)
{
int i = 0;
int codec = ast_codec_pref_index(prefs, i);
struct ast_format tmpfmt;
ast_codec_pref_index(prefs, i, &tmpfmt);
ooResetCapPrefs(call);
while (codec) {
ooAppendCapToCapPrefs(call, ooh323_convertAsteriskCapToH323Cap(codec));
codec = ast_codec_pref_index(prefs, ++i);
while (tmpfmt.id) {
ooAppendCapToCapPrefs(call, ooh323_convertAsteriskCapToH323Cap(&tmpfmt));
ast_codec_pref_index(prefs, ++i, &tmpfmt);
}
return 0;
}
int ooh323_convertAsteriskCapToH323Cap(format_t cap)
int ooh323_convertAsteriskCapToH323Cap(struct ast_format *format)
{
char formats[FORMAT_STRING_SIZE];
switch (cap) {
switch (format->id) {
case AST_FORMAT_ULAW:
return OO_G711ULAW64K;
case AST_FORMAT_ALAW:
@ -3845,14 +3869,13 @@ int ooh323_convertAsteriskCapToH323Cap(format_t cap)
case AST_FORMAT_H263:
return OO_H263VIDEO;
default:
ast_log(LOG_NOTICE, "Don't know how to deal with mode %s\n",
ast_getformatname_multiple(formats,FORMAT_STRING_SIZE,cap));
ast_log(LOG_NOTICE, "Don't know how to deal with mode %s\n", ast_getformatname(format));
return -1;
}
}
static int ooh323_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)
struct ast_rtp_instance *vrtp, struct ast_rtp_instance *trtp, const struct ast_format_cap *cap, int nat_active)
{
/* XXX Deal with Video */
struct ooh323_pvt *p;
@ -3868,7 +3891,7 @@ static int ooh323_set_rtp_peer(struct ast_channel *chan, struct ast_rtp_instance
return 0;
}
mode = ooh323_convertAsteriskCapToH323Cap(chan->writeformat);
mode = ooh323_convertAsteriskCapToH323Cap(&chan->writeformat);
p = (struct ooh323_pvt *) chan->tech_pvt;
if (!p) {
ast_log(LOG_ERROR, "No Private Structure, this is bad\n");
@ -3890,7 +3913,9 @@ int configure_local_rtp(struct ooh323_pvt *p, ooCallData *call)
struct ast_sockaddr tmp;
ooMediaInfo mediaInfo;
int x;
format_t format = 0;
struct ast_format tmpfmt;
ast_format_clear(&tmpfmt);
if (gH323Debug)
ast_verbose("--- configure_local_rtp\n");
@ -3929,9 +3954,9 @@ int configure_local_rtp(struct ooh323_pvt *p, ooCallData *call)
ast_copy_string(mediaInfo.lMediaIP, ast_inet_ntoa(us.sin_addr), sizeof(mediaInfo.lMediaIP));
mediaInfo.lMediaPort = ntohs(us.sin_port);
mediaInfo.lMediaCntrlPort = mediaInfo.lMediaPort +1;
for (x = 0; 0 != (format = ast_codec_pref_index(&p->prefs, x)); x++) {
for (x = 0; ast_codec_pref_index(&p->prefs, x, &tmpfmt); x++) {
strcpy(mediaInfo.dir, "transmit");
mediaInfo.cap = ooh323_convertAsteriskCapToH323Cap(format);
mediaInfo.cap = ooh323_convertAsteriskCapToH323Cap(&tmpfmt);
ooAddMediaInfo(call, mediaInfo);
strcpy(mediaInfo.dir, "receive");
ooAddMediaInfo(call, mediaInfo);
@ -3995,7 +4020,7 @@ void setup_rtp_connection(ooCallData *call, const char *remoteIp,
ast_sockaddr_from_sin(&tmp, &them);
ast_rtp_instance_set_remote_address(p->rtp, &tmp);
if (p->writeformat & AST_FORMAT_G726_AAL2)
if (p->writeformat.id == AST_FORMAT_G726_AAL2)
ast_rtp_codecs_payloads_set_rtpmap_type(ast_rtp_instance_get_codecs(p->rtp), p->rtp, 2,
"audio", "G726-32", AST_RTP_OPT_G726_NONSTANDARD);
@ -4237,16 +4262,16 @@ struct ast_frame *ooh323_rtp_read(struct ast_channel *ast, struct ooh323_pvt *p)
if (p->owner) {
/* We already hold the channel lock */
if (f->frametype == AST_FRAME_VOICE && !p->faxmode) {
if (f->subclass.codec != p->owner->nativeformats) {
ast_debug(1, "Oooh, voice format changed to %s\n", ast_getformatname(f->subclass.codec));
p->owner->nativeformats = f->subclass.codec;
ast_set_read_format(p->owner, p->owner->readformat);
ast_set_write_format(p->owner, p->owner->writeformat);
if (!(ast_format_cap_iscompatible(p->owner->nativeformats, &f->subclass.format))) {
ast_debug(1, "Oooh, voice format changed to %s\n", ast_getformatname(&f->subclass.format));
ast_format_cap_set(p->owner->nativeformats, &f->subclass.format);
ast_set_read_format(p->owner, &p->owner->readformat);
ast_set_write_format(p->owner, &p->owner->writeformat);
}
if ((p->dtmfmode & H323_DTMF_INBAND) && p->vad &&
(f->subclass.codec == AST_FORMAT_SLINEAR || f->subclass.codec == AST_FORMAT_ALAW ||
f->subclass.codec == AST_FORMAT_ULAW)) {
(f->subclass.format.id == AST_FORMAT_SLINEAR || f->subclass.format.id == AST_FORMAT_ALAW ||
f->subclass.format.id == AST_FORMAT_ULAW)) {
f = ast_dsp_process(p->owner, p->vad, f);
if (f && (f->frametype == AST_FRAME_DTMF))
ast_debug(1, "* Detected inband DTMF '%c'\n", f->subclass.integer);

View File

@ -61,7 +61,8 @@
#include "asterisk/manager.h"
#include "asterisk/dsp.h"
#include "asterisk/stringfields.h"
#include "asterisk/frame_defs.h"
#include "asterisk/format.h"
#include "asterisk/format_cap.h"
#include "asterisk/udptl.h"
#include "ootypes.h"
@ -99,13 +100,13 @@ void close_rtp_connection(ooCallData *call);
struct ast_frame *ooh323_rtp_read
(struct ast_channel *ast, struct ooh323_pvt *p);
void ooh323_set_write_format(ooCallData *call, int fmt, int txframes);
void ooh323_set_read_format(ooCallData *call, int fmt);
void ooh323_set_write_format(ooCallData *call, struct ast_format *fmt, int txframes);
void ooh323_set_read_format(ooCallData *call, struct ast_format *fmt);
int ooh323_update_capPrefsOrderForCall
(ooCallData *call, struct ast_codec_pref *prefs);
int ooh323_convertAsteriskCapToH323Cap(format_t cap);
int ooh323_convertAsteriskCapToH323Cap(struct ast_format *format);
int ooh323_convert_hangupcause_asteriskToH323(int cause);
int ooh323_convert_hangupcause_h323ToAsterisk(int cause);

View File

@ -224,7 +224,7 @@ static struct ast_frame *mp3_read(struct ast_filestream *s, int *whennext)
p->offset += p->buflen;
delay = p->buflen/2;
s->fr.frametype = AST_FRAME_VOICE;
s->fr.subclass.codec = AST_FORMAT_SLINEAR;
ast_format_set(&s->fr.subclass.format, AST_FORMAT_SLINEAR, 0);
AST_FRAME_SET_BUFFER(&s->fr, s->buf, AST_FRIENDLY_OFFSET, p->buflen);
s->fr.mallocd = 0;
s->fr.samples = delay;
@ -293,10 +293,9 @@ static char *mp3_getcomment(struct ast_filestream *s)
return NULL;
}
static const struct ast_format mp3_f = {
static struct ast_format_def mp3_f = {
.name = "mp3",
.exts = "mp3",
.format = AST_FORMAT_SLINEAR,
.open = mp3_open,
.write = mp3_write,
.rewrite = mp3_rewrite,
@ -313,13 +312,14 @@ static const struct ast_format mp3_f = {
static int load_module(void)
{
ast_format_set(&mp3_f.format, AST_FORMAT_SLINEAR, 0);
InitMP3Constants();
return ast_format_register(&mp3_f);
return ast_format_def_register(&mp3_f);
}
static int unload_module(void)
{
return ast_format_unregister(name);
return ast_format_def_unregister(name);
}
AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "MP3 format [Any rate but 8000hz mono is optimal]");

View File

@ -226,15 +226,16 @@ int ooh323c_stop_stack_thread(void)
}
int ooh323c_set_capability
(struct ast_codec_pref *prefs, int capability, int dtmf, int dtmfcodec)
(struct ast_codec_pref *prefs, struct ast_format_cap *cap, int dtmf, int dtmfcodec)
{
int ret = 0, x, format=0;
int ret = 0, x;
struct ast_format tmpfmt;
if(gH323Debug)
ast_verbose("\tAdding capabilities to H323 endpoint\n");
for(x=0; 0 != (format=ast_codec_pref_index(prefs, x)); x++)
for(x=0; ast_codec_pref_index(prefs, x, &tmpfmt); x++)
{
if(format & AST_FORMAT_ULAW)
if(tmpfmt.id == AST_FORMAT_ULAW)
{
if(gH323Debug)
ast_verbose("\tAdding g711 ulaw capability to H323 endpoint\n");
@ -244,7 +245,7 @@ int ooh323c_set_capability
&ooh323c_stop_receive_channel,
&ooh323c_stop_transmit_channel);
}
if(format & AST_FORMAT_ALAW)
if(tmpfmt.id == AST_FORMAT_ALAW)
{
if(gH323Debug)
ast_verbose("\tAdding g711 alaw capability to H323 endpoint\n");
@ -255,7 +256,7 @@ int ooh323c_set_capability
&ooh323c_stop_transmit_channel);
}
if(format & AST_FORMAT_G729A)
if(tmpfmt.id == AST_FORMAT_G729A)
{
if(gH323Debug)
ast_verbose("\tAdding g729A capability to H323 endpoint\n");
@ -281,7 +282,7 @@ int ooh323c_set_capability
&ooh323c_stop_transmit_channel);
}
if(format & AST_FORMAT_G723_1)
if(tmpfmt.id == AST_FORMAT_G723_1)
{
if(gH323Debug)
ast_verbose("\tAdding g7231 capability to H323 endpoint\n");
@ -293,7 +294,7 @@ int ooh323c_set_capability
}
if(format & AST_FORMAT_G726)
if(tmpfmt.id == AST_FORMAT_G726)
{
if(gH323Debug)
ast_verbose("\tAdding g726 capability to H323 endpoint\n");
@ -305,7 +306,7 @@ int ooh323c_set_capability
}
if(format & AST_FORMAT_G726_AAL2)
if(tmpfmt.id == AST_FORMAT_G726_AAL2)
{
if(gH323Debug)
ast_verbose("\tAdding g726aal2 capability to H323 endpoint\n");
@ -317,7 +318,7 @@ int ooh323c_set_capability
}
if(format & AST_FORMAT_H263)
if(tmpfmt.id == AST_FORMAT_H263)
{
if(gH323Debug)
ast_verbose("\tAdding h263 capability to H323 endpoint\n");
@ -329,7 +330,7 @@ int ooh323c_set_capability
}
if(format & AST_FORMAT_GSM)
if(tmpfmt.id == AST_FORMAT_GSM)
{
if(gH323Debug)
ast_verbose("\tAdding gsm capability to H323 endpoint\n");
@ -342,7 +343,7 @@ int ooh323c_set_capability
}
#ifdef AST_FORMAT_AMRNB
if(format & AST_FORMAT_AMRNB)
if(tmpfmt.id == AST_FORMAT_AMRNB)
{
if(gH323Debug)
ast_verbose("\tAdding amr nb capability to H323 endpoint\n");
@ -356,7 +357,7 @@ int ooh323c_set_capability
#endif
#ifdef AST_FORMAT_SPEEX
if(format & AST_FORMAT_SPEEX)
if(tmpfmt.id == AST_FORMAT_SPEEX)
{
if(gH323Debug)
ast_verbose("\tAdding speex capability to H323 endpoint\n");
@ -384,11 +385,11 @@ int ooh323c_set_capability
}
int ooh323c_set_capability_for_call
(ooCallData *call, struct ast_codec_pref *prefs, int capability, int dtmf, int dtmfcodec,
(ooCallData *call, struct ast_codec_pref *prefs, struct ast_format_cap *cap, int dtmf, int dtmfcodec,
int t38support)
{
int ret = 0, x, txframes;
int format=0;
struct ast_format tmpfmt;
if(gH323Debug)
ast_verbose("\tAdding capabilities to call(%s, %s)\n", call->callType,
call->callToken);
@ -409,9 +410,9 @@ int ooh323c_set_capability_for_call
&ooh323c_stop_transmit_datachannel,
0);
for(x=0; 0 !=(format=ast_codec_pref_index(prefs, x)); x++)
for(x=0; ast_codec_pref_index(prefs, x, &tmpfmt); x++)
{
if(format & AST_FORMAT_ULAW)
if(tmpfmt.id == AST_FORMAT_ULAW)
{
if(gH323Debug)
ast_verbose("\tAdding g711 ulaw capability to call(%s, %s)\n",
@ -424,7 +425,7 @@ int ooh323c_set_capability_for_call
&ooh323c_stop_receive_channel,
&ooh323c_stop_transmit_channel);
}
if(format & AST_FORMAT_ALAW)
if(tmpfmt.id == AST_FORMAT_ALAW)
{
if(gH323Debug)
ast_verbose("\tAdding g711 alaw capability to call(%s, %s)\n",
@ -438,7 +439,7 @@ int ooh323c_set_capability_for_call
&ooh323c_stop_transmit_channel);
}
if(format & AST_FORMAT_G726)
if(tmpfmt.id == AST_FORMAT_G726)
{
if(gH323Debug)
ast_verbose("\tAdding g726 capability to call (%s, %s)\n",
@ -452,7 +453,7 @@ int ooh323c_set_capability_for_call
}
if(format & AST_FORMAT_G726_AAL2)
if(tmpfmt.id == AST_FORMAT_G726_AAL2)
{
if(gH323Debug)
ast_verbose("\tAdding g726aal2 capability to call (%s, %s)\n",
@ -466,7 +467,7 @@ int ooh323c_set_capability_for_call
}
if(format & AST_FORMAT_G729A)
if(tmpfmt.id == AST_FORMAT_G729A)
{
txframes = (prefs->framing[x])/10;
@ -497,7 +498,7 @@ int ooh323c_set_capability_for_call
}
if(format & AST_FORMAT_G723_1)
if(tmpfmt.id == AST_FORMAT_G723_1)
{
if(gH323Debug)
ast_verbose("\tAdding g7231 capability to call (%s, %s)\n",
@ -510,7 +511,7 @@ int ooh323c_set_capability_for_call
}
if(format & AST_FORMAT_H263)
if(tmpfmt.id == AST_FORMAT_H263)
{
if(gH323Debug)
ast_verbose("\tAdding h263 capability to call (%s, %s)\n",
@ -523,7 +524,7 @@ int ooh323c_set_capability_for_call
}
if(format & AST_FORMAT_GSM)
if(tmpfmt.id == AST_FORMAT_GSM)
{
if(gH323Debug)
ast_verbose("\tAdding gsm capability to call(%s, %s)\n",
@ -536,7 +537,7 @@ int ooh323c_set_capability_for_call
}
#ifdef AST_FORMAT_AMRNB
if(format & AST_FORMAT_AMRNB)
if(tmpfmt.id == AST_FORMAT_AMRNB)
{
if(gH323Debug)
ast_verbose("\tAdding AMR capability to call(%s, %s)\n",
@ -549,7 +550,7 @@ int ooh323c_set_capability_for_call
}
#endif
#ifdef AST_FORMAT_SPEEX
if(format & AST_FORMAT_SPEEX)
if(tmpfmt.id == AST_FORMAT_SPEEX)
{
if(gH323Debug)
ast_verbose("\tAdding Speex capability to call(%s, %s)\n",
@ -594,9 +595,9 @@ int ooh323c_set_aliases(ooAliases * aliases)
int ooh323c_start_receive_channel(ooCallData *call, ooLogicalChannel *pChannel)
{
format_t fmt=-1;
fmt = convertH323CapToAsteriskCap(pChannel->chanCap->cap);
if(fmt>0) {
struct ast_format tmpfmt;
convertH323CapToAsteriskCap(pChannel->chanCap->cap, &tmpfmt);
if(tmpfmt.id) {
/* ooh323_set_read_format(call, fmt); */
}else{
ast_log(LOG_ERROR, "Invalid capability type for receive channel %s\n",
@ -608,19 +609,19 @@ int ooh323c_start_receive_channel(ooCallData *call, ooLogicalChannel *pChannel)
int ooh323c_start_transmit_channel(ooCallData *call, ooLogicalChannel *pChannel)
{
format_t fmt;
fmt = convertH323CapToAsteriskCap(pChannel->chanCap->cap);
if(fmt>0) {
switch (fmt) {
struct ast_format tmpfmt;
convertH323CapToAsteriskCap(pChannel->chanCap->cap, &tmpfmt);
if(tmpfmt.id) {
switch (tmpfmt.id) {
case AST_FORMAT_ALAW:
case AST_FORMAT_ULAW:
ooh323_set_write_format(call, fmt, ((OOCapParams *)(pChannel->chanCap->params))->txframes);
ooh323_set_write_format(call, &tmpfmt, ((OOCapParams *)(pChannel->chanCap->params))->txframes);
break;
case AST_FORMAT_G729A:
ooh323_set_write_format(call, fmt, ((OOCapParams *)(pChannel->chanCap->params))->txframes*10);
ooh323_set_write_format(call, &tmpfmt, ((OOCapParams *)(pChannel->chanCap->params))->txframes*10);
break;
default:
ooh323_set_write_format(call, fmt, 0);
ooh323_set_write_format(call, &tmpfmt, 0);
}
}else{
ast_log(LOG_ERROR, "Invalid capability type for receive channel %s\n",
@ -665,47 +666,47 @@ int ooh323c_stop_transmit_datachannel(ooCallData *call, ooLogicalChannel *pChann
return 1;
}
format_t convertH323CapToAsteriskCap(int cap)
struct ast_format *convertH323CapToAsteriskCap(int cap, struct ast_format *result)
{
ast_format_clear(result);
switch(cap)
{
case OO_G711ULAW64K:
return AST_FORMAT_ULAW;
return ast_format_set(result, AST_FORMAT_ULAW, 0);
case OO_G711ALAW64K:
return AST_FORMAT_ALAW;
return ast_format_set(result, AST_FORMAT_ALAW, 0);
case OO_GSMFULLRATE:
return AST_FORMAT_GSM;
return ast_format_set(result, AST_FORMAT_GSM, 0);
#ifdef AST_FORMAT_AMRNB
case OO_AMRNB:
return AST_FORMAT_AMRNB;
return ast_format_set(result, AST_FORMAT_AMRNB, 0);
#endif
#ifdef AST_FORMAT_SPEEX
case OO_SPEEX:
return AST_FORMAT_SPEEX;
return ast_format_set(result, AST_FORMAT_SPEEX, 0);
#endif
case OO_G729:
return AST_FORMAT_G729A;
return ast_format_set(result, AST_FORMAT_G729A, 0);
case OO_G729A:
return AST_FORMAT_G729A;
return ast_format_set(result, AST_FORMAT_G729A, 0);
case OO_G729B:
return AST_FORMAT_G729A;
return ast_format_set(result, AST_FORMAT_G729A, 0);
case OO_G7231:
return AST_FORMAT_G723_1;
return ast_format_set(result, AST_FORMAT_G723_1, 0);
case OO_G726:
return AST_FORMAT_G726;
return ast_format_set(result, AST_FORMAT_G726, 0);
case OO_G726AAL2:
return AST_FORMAT_G726_AAL2;
return ast_format_set(result, AST_FORMAT_G726_AAL2, 0);
case OO_H263VIDEO:
return AST_FORMAT_H263;
return ast_format_set(result, AST_FORMAT_H263, 0);
default:
ast_debug(1, "Cap %d is not supported by driver yet\n", cap);
return -1;
return NULL;
}
return -1;
return NULL;
}

View File

@ -22,7 +22,7 @@
#include "ooCalls.h"
#include "ooCapability.h"
#include "ooStackCmds.h"
#include "asterisk/frame_defs.h"
#include "asterisk/format.h"
#define H323_DTMF_RFC2833 (1 << 0)
#define H323_DTMF_Q931 (1 << 1)
#define H323_DTMF_H245ALPHANUMERIC (1 << 2)
@ -37,9 +37,9 @@ int ooh323c_stop_stack_thread(void);
int ooh323c_start_call_thread(ooCallData *call);
int ooh323c_stop_call_thread(ooCallData *call);
int ooh323c_set_capability
(struct ast_codec_pref *prefs, int capability, int dtmf, int dtmfcodec);
format_t convertH323CapToAsteriskCap(int cap);
(struct ast_codec_pref *prefs, struct ast_format_cap *cap, int dtmf, int dtmfcodec);
struct ast_format *convertH323CapToAsteriskCap(int cap, struct ast_format *format);
int ooh323c_set_capability_for_call
(ooCallData *call, struct ast_codec_pref *prefs, int capability, int dtmf, int dtmfcodec,
(ooCallData *call, struct ast_codec_pref *prefs, struct ast_format_cap *cap, int dtmf, int dtmfcodec,
int t38support);
#endif

View File

@ -191,7 +191,7 @@ static int send_tone_burst(struct ast_channel *chan, float freq, int duration, i
if (f->frametype == AST_FRAME_VOICE) {
wf.frametype = AST_FRAME_VOICE;
wf.subclass.codec = AST_FORMAT_ULAW;
ast_format_set(&wf.subclass.format, AST_FORMAT_ULAW, 0);
wf.offset = AST_FRIENDLY_OFFSET;
wf.mallocd = 0;
wf.data.ptr = tone_block.buf;
@ -578,12 +578,12 @@ static int alarmreceiver_exec(struct ast_channel *chan, const char *data)
/* Set write and read formats to ULAW */
ast_verb(4, "AlarmReceiver: Setting read and write formats to ULAW\n");
if (ast_set_write_format(chan,AST_FORMAT_ULAW)) {
if (ast_set_write_format_by_id(chan,AST_FORMAT_ULAW)) {
ast_log(LOG_WARNING, "AlarmReceiver: Unable to set write format to Mu-law on %s\n",chan->name);
return -1;
}
if (ast_set_read_format(chan,AST_FORMAT_ULAW)) {
if (ast_set_read_format_by_id(chan,AST_FORMAT_ULAW)) {
ast_log(LOG_WARNING, "AlarmReceiver: Unable to set read format to Mu-law on %s\n",chan->name);
return -1;
}

View File

@ -148,7 +148,8 @@ static void isAnsweringMachine(struct ast_channel *chan, const char *data)
int res = 0;
struct ast_frame *f = NULL;
struct ast_dsp *silenceDetector = NULL;
int dspsilence = 0, readFormat, framelength = 0;
int dspsilence = 0, framelength = 0;
struct ast_format readFormat;
int inInitialSilence = 1;
int inGreeting = 0;
int voiceDuration = 0;
@ -188,10 +189,11 @@ static void isAnsweringMachine(struct ast_channel *chan, const char *data)
AST_APP_ARG(argMaximumWordLength);
);
ast_format_clear(&readFormat);
ast_verb(3, "AMD: %s %s %s (Fmt: %s)\n", chan->name,
S_COR(chan->caller.ani.number.valid, chan->caller.ani.number.str, "(N/A)"),
S_COR(chan->redirecting.from.number.valid, chan->redirecting.from.number.str, "(N/A)"),
ast_getformatname(chan->readformat));
ast_getformatname(&chan->readformat));
/* Lets parse the arguments. */
if (!ast_strlen_zero(parse)) {
@ -240,8 +242,8 @@ static void isAnsweringMachine(struct ast_channel *chan, const char *data)
minimumWordLength, betweenWordsSilence, maximumNumberOfWords, silenceThreshold, maximumWordLength);
/* Set read format to signed linear so we get signed linear frames in */
readFormat = chan->readformat;
if (ast_set_read_format(chan, AST_FORMAT_SLINEAR) < 0 ) {
ast_format_copy(&readFormat, &chan->readformat);
if (ast_set_read_format_by_id(chan, AST_FORMAT_SLINEAR) < 0 ) {
ast_log(LOG_WARNING, "AMD: Channel [%s]. Unable to set to linear mode, giving up\n", chan->name );
pbx_builtin_setvar_helper(chan , "AMDSTATUS", "");
pbx_builtin_setvar_helper(chan , "AMDCAUSE", "");
@ -399,7 +401,7 @@ static void isAnsweringMachine(struct ast_channel *chan, const char *data)
pbx_builtin_setvar_helper(chan , "AMDCAUSE" , amdCause);
/* Restore channel read format */
if (readFormat && ast_set_read_format(chan, readFormat))
if (readFormat.id && ast_set_read_format(chan, &readFormat))
ast_log(LOG_WARNING, "AMD: Unable to restore read format on '%s'\n", chan->name);
/* Free the DSP used to detect silence */

View File

@ -427,6 +427,9 @@ static int spy_generate(struct ast_channel *chan, void *data, int len, int sampl
{
struct chanspy_translation_helper *csth = data;
struct ast_frame *f, *cur;
struct ast_format format_slin;
ast_format_set(&format_slin, AST_FORMAT_SLINEAR, 0);
ast_audiohook_lock(&csth->spy_audiohook);
if (csth->spy_audiohook.status != AST_AUDIOHOOK_STATUS_RUNNING) {
@ -437,9 +440,9 @@ static int spy_generate(struct ast_channel *chan, void *data, int len, int sampl
if (ast_test_flag(&csth->spy_audiohook, OPTION_READONLY)) {
/* Option 'o' was set, so don't mix channel audio */
f = ast_audiohook_read_frame(&csth->spy_audiohook, samples, AST_AUDIOHOOK_DIRECTION_READ, AST_FORMAT_SLINEAR);
f = ast_audiohook_read_frame(&csth->spy_audiohook, samples, AST_AUDIOHOOK_DIRECTION_READ, &format_slin);
} else {
f = ast_audiohook_read_frame(&csth->spy_audiohook, samples, AST_AUDIOHOOK_DIRECTION_BOTH, AST_FORMAT_SLINEAR);
f = ast_audiohook_read_frame(&csth->spy_audiohook, samples, AST_AUDIOHOOK_DIRECTION_BOTH, &format_slin);
}
ast_audiohook_unlock(&csth->spy_audiohook);
@ -1006,7 +1009,7 @@ static int chanspy_exec(struct ast_channel *chan, const char *data)
.volume = '#',
.exit = '\0',
};
int oldwf = 0;
struct ast_format oldwf;
int volfactor = 0;
int res;
char *mailbox = NULL;
@ -1019,6 +1022,7 @@ static int chanspy_exec(struct ast_channel *chan, const char *data)
char *parse = ast_strdupa(data);
AST_STANDARD_APP_ARGS(args, parse);
ast_format_clear(&oldwf);
if (args.spec && !strcmp(args.spec, "all"))
args.spec = NULL;
@ -1082,8 +1086,8 @@ static int chanspy_exec(struct ast_channel *chan, const char *data)
ast_clear_flag(&flags, AST_FLAGS_ALL);
}
oldwf = chan->writeformat;
if (ast_set_write_format(chan, AST_FORMAT_SLINEAR) < 0) {
ast_format_copy(&oldwf, &chan->writeformat);
if (ast_set_write_format_by_id(chan, AST_FORMAT_SLINEAR) < 0) {
ast_log(LOG_ERROR, "Could Not Set Write Format.\n");
return -1;
}
@ -1103,7 +1107,7 @@ static int chanspy_exec(struct ast_channel *chan, const char *data)
if (fd)
close(fd);
if (oldwf && ast_set_write_format(chan, oldwf) < 0)
if (oldwf.id && ast_set_write_format(chan, &oldwf) < 0)
ast_log(LOG_ERROR, "Could Not Set Write Format.\n");
if (ast_test_flag(&flags, OPTION_EXITONHANGUP)) {
@ -1125,7 +1129,7 @@ static int extenspy_exec(struct ast_channel *chan, const char *data)
.volume = '#',
.exit = '\0',
};
int oldwf = 0;
struct ast_format oldwf;
int volfactor = 0;
int res;
char *mailbox = NULL;
@ -1137,12 +1141,13 @@ static int extenspy_exec(struct ast_channel *chan, const char *data)
char *parse = ast_strdupa(data);
AST_STANDARD_APP_ARGS(args, parse);
ast_format_clear(&oldwf);
if (!ast_strlen_zero(args.context) && (ptr = strchr(args.context, '@'))) {
exten = args.context;
*ptr++ = '\0';
args.context = ptr;
}
if (ast_strlen_zero(args.context))
args.context = ast_strdupa(chan->context);
@ -1206,7 +1211,7 @@ static int extenspy_exec(struct ast_channel *chan, const char *data)
}
oldwf = chan->writeformat;
if (ast_set_write_format(chan, AST_FORMAT_SLINEAR) < 0) {
if (ast_set_write_format_by_id(chan, AST_FORMAT_SLINEAR) < 0) {
ast_log(LOG_ERROR, "Could Not Set Write Format.\n");
return -1;
}
@ -1227,7 +1232,7 @@ static int extenspy_exec(struct ast_channel *chan, const char *data)
if (fd)
close(fd);
if (oldwf && ast_set_write_format(chan, oldwf) < 0)
if (oldwf.id && ast_set_write_format(chan, &oldwf) < 0)
ast_log(LOG_ERROR, "Could Not Set Write Format.\n");
return res;
@ -1242,12 +1247,12 @@ static int dahdiscan_exec(struct ast_channel *chan, const char *data)
.volume = '\0',
.exit = '*',
};
int oldwf = 0;
struct ast_format oldwf;
int res;
char *mygroup = NULL;
ast_clear_flag(&flags, AST_FLAGS_ALL);
ast_format_clear(&oldwf);
if (!ast_strlen_zero(data)) {
mygroup = ast_strdupa(data);
}
@ -1255,15 +1260,15 @@ static int dahdiscan_exec(struct ast_channel *chan, const char *data)
ast_set_flag(&flags, OPTION_DTMF_CYCLE);
ast_set_flag(&flags, OPTION_DAHDI_SCAN);
oldwf = chan->writeformat;
if (ast_set_write_format(chan, AST_FORMAT_SLINEAR) < 0) {
ast_format_copy(&oldwf, &chan->writeformat);
if (ast_set_write_format_by_id(chan, AST_FORMAT_SLINEAR) < 0) {
ast_log(LOG_ERROR, "Could Not Set Write Format.\n");
return -1;
}
res = common_exec(chan, &flags, 0, 0, &user_options, mygroup, NULL, spec, NULL, NULL, NULL, NULL);
if (oldwf && ast_set_write_format(chan, oldwf) < 0)
if (oldwf.id && ast_set_write_format(chan, &oldwf) < 0)
ast_log(LOG_ERROR, "Could Not Set Write Format.\n");
return res;

View File

@ -568,11 +568,18 @@ static int play_sound_file(struct conference_bridge *conference_bridge, const ch
if (!(conference_bridge->playback_chan)) {
int cause;
if (!(conference_bridge->playback_chan = ast_request("Bridge", AST_FORMAT_SLINEAR, NULL, "", &cause))) {
ast_mutex_unlock(&conference_bridge->playback_lock);
struct ast_format_cap *cap = ast_format_cap_alloc_nolock();
struct ast_format tmpfmt;
if (!cap) {
return -1;
}
ast_format_cap_add(cap, ast_format_set(&tmpfmt, AST_FORMAT_SLINEAR, 0));
if (!(conference_bridge->playback_chan = ast_request("Bridge", cap, NULL, "", &cause))) {
ast_mutex_unlock(&conference_bridge->playback_lock);
cap = ast_format_cap_destroy(cap);
return -1;
}
cap = ast_format_cap_destroy(cap);
conference_bridge->playback_chan->bridge = conference_bridge->bridge;

View File

@ -113,13 +113,13 @@ static int conf_run(struct ast_channel *chan, int confno, int confflags)
char *buf = __buf + AST_FRIENDLY_OFFSET;
/* Set it into U-law mode (write) */
if (ast_set_write_format(chan, AST_FORMAT_ULAW) < 0) {
if (ast_set_write_format_by_id(chan, AST_FORMAT_ULAW) < 0) {
ast_log(LOG_WARNING, "Unable to set '%s' to write ulaw mode\n", chan->name);
goto outrun;
}
/* Set it into U-law mode (read) */
if (ast_set_read_format(chan, AST_FORMAT_ULAW) < 0) {
if (ast_set_read_format_by_id(chan, AST_FORMAT_ULAW) < 0) {
ast_log(LOG_WARNING, "Unable to set '%s' to read ulaw mode\n", chan->name);
goto outrun;
}
@ -214,11 +214,11 @@ dahdiretry:
break;
} else if (fd != chan->fds[0]) {
if (f->frametype == AST_FRAME_VOICE) {
if (f->subclass.codec == AST_FORMAT_ULAW) {
if (f->subclass.format.id == AST_FORMAT_ULAW) {
/* Carefully write */
careful_write(fd, f->data.ptr, f->datalen);
} else
ast_log(LOG_WARNING, "Huh? Got a non-ulaw (%s) frame in the conference\n", ast_getformatname(f->subclass.codec));
ast_log(LOG_WARNING, "Huh? Got a non-ulaw (%s) frame in the conference\n", ast_getformatname(&f->subclass.format));
}
}
ast_frfree(f);
@ -227,7 +227,7 @@ dahdiretry:
if (res > 0) {
memset(&fr, 0, sizeof(fr));
fr.frametype = AST_FRAME_VOICE;
fr.subclass.codec = AST_FORMAT_ULAW;
ast_format_set(&fr.subclass.format, AST_FORMAT_ULAW, 0);
fr.datalen = res;
fr.samples = res;
fr.data.ptr = buf;

View File

@ -97,7 +97,6 @@ static int dictate_exec(struct ast_channel *chan, const char *data)
int ffactor = 320 * 80,
res = 0,
done = 0,
oldr = 0,
lastop = 0,
samples = 0,
speed = 1,
@ -105,6 +104,8 @@ static int dictate_exec(struct ast_channel *chan, const char *data)
len = 0,
maxlen = 0,
mode = 0;
struct ast_format oldr;
ast_format_clear(&oldr);
snprintf(dftbase, sizeof(dftbase), "%s/dictate", ast_config_AST_SPOOL_DIR);
if (!ast_strlen_zero(data)) {
@ -121,8 +122,8 @@ static int dictate_exec(struct ast_channel *chan, const char *data)
if (args.argc > 1 && args.filename) {
filename = args.filename;
}
oldr = chan->readformat;
if ((res = ast_set_read_format(chan, AST_FORMAT_SLINEAR)) < 0) {
ast_format_copy(&oldr, &chan->readformat);
if ((res = ast_set_read_format_by_id(chan, AST_FORMAT_SLINEAR)) < 0) {
ast_log(LOG_WARNING, "Unable to set to linear mode.\n");
return -1;
}
@ -330,8 +331,8 @@ static int dictate_exec(struct ast_channel *chan, const char *data)
ast_frfree(f);
}
}
if (oldr) {
ast_set_read_format(chan, oldr);
if (oldr.id) {
ast_set_read_format(chan, &oldr);
}
return 0;
}

View File

@ -126,10 +126,10 @@ static int serialize_showchan(struct ast_channel *c, char *buf, size_t size)
c->_state,
c->rings,
ast_getformatname_multiple(formatbuf, sizeof(formatbuf), c->nativeformats),
ast_getformatname_multiple(formatbuf, sizeof(formatbuf), c->writeformat),
ast_getformatname_multiple(formatbuf, sizeof(formatbuf), c->readformat),
ast_getformatname_multiple(formatbuf, sizeof(formatbuf), c->rawwriteformat),
ast_getformatname_multiple(formatbuf, sizeof(formatbuf), c->rawreadformat),
ast_getformatname(&c->writeformat),
ast_getformatname(&c->readformat),
ast_getformatname(&c->rawwriteformat),
ast_getformatname(&c->rawreadformat),
c->fds[0], c->fin & ~DEBUGCHAN_FLAG, (c->fin & DEBUGCHAN_FLAG) ? " (DEBUGGED)" : "",
c->fout & ~DEBUGCHAN_FLAG, (c->fout & DEBUGCHAN_FLAG) ? " (DEBUGGED)" : "", (long)c->whentohangup.tv_sec,
hour,

View File

@ -51,11 +51,11 @@ static const char app[] = "Echo";
static int echo_exec(struct ast_channel *chan, const char *data)
{
int res = -1;
format_t format;
struct ast_format format;
format = ast_best_codec(chan->nativeformats);
ast_set_write_format(chan, format);
ast_set_read_format(chan, format);
ast_best_codec(chan->nativeformats, &format);
ast_set_write_format(chan, &format);
ast_set_read_format(chan, &format);
while (ast_waitfor(chan, -1) > -1) {
struct ast_frame *f = ast_read(chan);

View File

@ -329,9 +329,9 @@ static int fax_generator_generate(struct ast_channel *chan, void *data, int len,
struct ast_frame outf = {
.frametype = AST_FRAME_VOICE,
.subclass.codec = AST_FORMAT_SLINEAR,
.src = __FUNCTION__,
};
ast_format_set(&outf.subclass.format, AST_FORMAT_SLINEAR, 0);
if (samples > MAX_SAMPLES) {
ast_log(LOG_WARNING, "Only generating %d samples, where %d requested\n", MAX_SAMPLES, samples);
@ -362,8 +362,8 @@ static struct ast_generator generator = {
static int transmit_audio(fax_session *s)
{
int res = -1;
int original_read_fmt = AST_FORMAT_SLINEAR;
int original_write_fmt = AST_FORMAT_SLINEAR;
struct ast_format original_read_fmt;
struct ast_format original_write_fmt;
fax_state_t fax;
t30_state_t *t30state;
struct ast_frame *inf = NULL;
@ -383,6 +383,9 @@ static int transmit_audio(fax_session *s)
*/
};
ast_format_clear(&original_read_fmt);
ast_format_clear(&original_write_fmt);
/* if in called party mode, try to use T.38 */
if (s->caller_mode == FALSE) {
/* check if we are already in T.38 mode (unlikely), or if we can request
@ -455,18 +458,18 @@ static int transmit_audio(fax_session *s)
t30state = &fax.t30_state;
#endif
original_read_fmt = s->chan->readformat;
if (original_read_fmt != AST_FORMAT_SLINEAR) {
res = ast_set_read_format(s->chan, AST_FORMAT_SLINEAR);
ast_format_copy(&original_read_fmt, &s->chan->readformat);
if (original_read_fmt.id != AST_FORMAT_SLINEAR) {
res = ast_set_read_format_by_id(s->chan, AST_FORMAT_SLINEAR);
if (res < 0) {
ast_log(LOG_WARNING, "Unable to set to linear read mode, giving up\n");
goto done;
}
}
original_write_fmt = s->chan->writeformat;
if (original_write_fmt != AST_FORMAT_SLINEAR) {
res = ast_set_write_format(s->chan, AST_FORMAT_SLINEAR);
ast_format_copy(&original_write_fmt, &s->chan->writeformat);
if (original_write_fmt.id != AST_FORMAT_SLINEAR) {
res = ast_set_write_format_by_id(s->chan, AST_FORMAT_SLINEAR);
if (res < 0) {
ast_log(LOG_WARNING, "Unable to set to linear write mode, giving up\n");
goto done;
@ -523,12 +526,12 @@ static int transmit_audio(fax_session *s)
break;
}
ast_debug(10, "frame %d/%llu, len=%d\n", inf->frametype, (unsigned long long) inf->subclass.codec, inf->datalen);
ast_debug(10, "frame %d/%u, len=%d\n", inf->frametype, (unsigned int) inf->subclass.format.id, inf->datalen);
/* Check the frame type. Format also must be checked because there is a chance
that a frame in old format was already queued before we set channel format
to slinear so it will still be received by ast_read */
if (inf->frametype == AST_FRAME_VOICE && inf->subclass.codec == AST_FORMAT_SLINEAR) {
if (inf->frametype == AST_FRAME_VOICE && inf->subclass.format.id == AST_FORMAT_SLINEAR) {
if (fax_rx(&fax, inf->data.ptr, inf->samples) < 0) {
/* I know fax_rx never returns errors. The check here is for good style only */
ast_log(LOG_WARNING, "fax_rx returned error\n");
@ -582,13 +585,13 @@ static int transmit_audio(fax_session *s)
fax_release(&fax);
done:
if (original_write_fmt != AST_FORMAT_SLINEAR) {
if (ast_set_write_format(s->chan, original_write_fmt) < 0)
if (original_write_fmt.id != AST_FORMAT_SLINEAR) {
if (ast_set_write_format(s->chan, &original_write_fmt) < 0)
ast_log(LOG_WARNING, "Unable to restore write format on '%s'\n", s->chan->name);
}
if (original_read_fmt != AST_FORMAT_SLINEAR) {
if (ast_set_read_format(s->chan, original_read_fmt) < 0)
if (original_read_fmt.id != AST_FORMAT_SLINEAR) {
if (ast_set_read_format(s->chan, &original_read_fmt) < 0)
ast_log(LOG_WARNING, "Unable to restore read format on '%s'\n", s->chan->name);
}

View File

@ -165,7 +165,7 @@ static int send_waveform_to_channel(struct ast_channel *chan, char *waveform, in
int fds[2];
int pid = -1;
int needed = 0;
int owriteformat;
struct ast_format owriteformat;
struct ast_frame *f;
struct myframe {
struct ast_frame f;
@ -175,6 +175,7 @@ static int send_waveform_to_channel(struct ast_channel *chan, char *waveform, in
.f = { 0, },
};
ast_format_clear(&owriteformat);
if (pipe(fds)) {
ast_log(LOG_WARNING, "Unable to create pipe\n");
return -1;
@ -186,8 +187,8 @@ static int send_waveform_to_channel(struct ast_channel *chan, char *waveform, in
ast_stopstream(chan);
ast_indicate(chan, -1);
owriteformat = chan->writeformat;
res = ast_set_write_format(chan, AST_FORMAT_SLINEAR);
ast_format_copy(&owriteformat, &chan->writeformat);
res = ast_set_write_format_by_id(chan, AST_FORMAT_SLINEAR);
if (res < 0) {
ast_log(LOG_WARNING, "Unable to set write format to signed linear\n");
return -1;
@ -229,7 +230,7 @@ static int send_waveform_to_channel(struct ast_channel *chan, char *waveform, in
res = read(fds[0], myf.frdata, needed);
if (res > 0) {
myf.f.frametype = AST_FRAME_VOICE;
myf.f.subclass.codec = AST_FORMAT_SLINEAR;
ast_format_set(&myf.f.subclass.format, AST_FORMAT_SLINEAR, 0);
myf.f.datalen = res;
myf.f.samples = res / 2;
myf.f.offset = AST_FRIENDLY_OFFSET;
@ -261,8 +262,8 @@ static int send_waveform_to_channel(struct ast_channel *chan, char *waveform, in
if (pid > -1)
kill(pid, SIGKILL);
#endif
if (!res && owriteformat)
ast_set_write_format(chan, owriteformat);
if (!res && owriteformat.id)
ast_set_write_format(chan, &owriteformat);
return res;
}

View File

@ -848,7 +848,7 @@ static void findmeexec(struct fm_args *tpargs)
return;
}
outbound = ast_request("Local", ast_best_codec(caller->nativeformats), caller, dialarg, &dg);
outbound = ast_request("Local", caller->nativeformats, caller, dialarg, &dg);
if (outbound) {
ast_set_callerid(outbound,
S_COR(caller->caller.id.number.valid, caller->caller.id.number.str, NULL),

View File

@ -111,12 +111,13 @@ static int ices_exec(struct ast_channel *chan, const char *data)
int ms = -1;
int pid = -1;
int flags;
int oreadformat;
struct ast_format oreadformat;
struct timeval last;
struct ast_frame *f;
char filename[256]="";
char *c;
ast_format_clear(&oreadformat);
if (ast_strlen_zero(data)) {
ast_log(LOG_WARNING, "ICES requires an argument (configfile.xml)\n");
return -1;
@ -143,8 +144,8 @@ static int ices_exec(struct ast_channel *chan, const char *data)
return -1;
}
oreadformat = chan->readformat;
res = ast_set_read_format(chan, AST_FORMAT_SLINEAR);
ast_format_copy(&oreadformat, &chan->readformat);
res = ast_set_read_format_by_id(chan, AST_FORMAT_SLINEAR);
if (res < 0) {
close(fds[0]);
close(fds[1]);
@ -195,8 +196,8 @@ static int ices_exec(struct ast_channel *chan, const char *data)
if (pid > -1)
kill(pid, SIGKILL);
if (!res && oreadformat)
ast_set_read_format(chan, oreadformat);
if (!res && oreadformat.id)
ast_set_read_format(chan, &oreadformat);
return res;
}

View File

@ -604,12 +604,12 @@ static void handle_jack_audio(struct ast_channel *chan, struct jack_data *jack_d
short buf[160];
struct ast_frame f = {
.frametype = AST_FRAME_VOICE,
.subclass.codec = AST_FORMAT_SLINEAR,
.src = "JACK",
.data.ptr = buf,
.datalen = sizeof(buf),
.samples = ARRAY_LEN(buf),
};
ast_format_set(&f.subclass.format, AST_FORMAT_SLINEAR, 0);
for (;;) {
size_t res, read_len;
@ -754,12 +754,12 @@ static int jack_exec(struct ast_channel *chan, const char *data)
return -1;
}
if (ast_set_read_format(chan, AST_FORMAT_SLINEAR)) {
if (ast_set_read_format_by_id(chan, AST_FORMAT_SLINEAR)) {
destroy_jack_data(jack_data);
return -1;
}
if (ast_set_write_format(chan, AST_FORMAT_SLINEAR)) {
if (ast_set_write_format_by_id(chan, AST_FORMAT_SLINEAR)) {
destroy_jack_data(jack_data);
return -1;
}
@ -823,9 +823,9 @@ static int jack_hook_callback(struct ast_audiohook *audiohook, struct ast_channe
if (frame->frametype != AST_FRAME_VOICE)
return 0;
if (frame->subclass.codec != AST_FORMAT_SLINEAR) {
if (frame->subclass.format.id != AST_FORMAT_SLINEAR) {
ast_log(LOG_WARNING, "Expected frame in SLINEAR for the audiohook, but got format %s\n",
ast_getformatname(frame->subclass.codec));
ast_getformatname(&frame->subclass.format));
return 0;
}

View File

@ -1189,6 +1189,8 @@ static struct ast_conference *build_conf(const char *confno, const char *pin,
struct ast_conference *cnf;
struct dahdi_confinfo dahdic = { 0, };
int confno_int = 0;
struct ast_format_cap *cap_slin = ast_format_cap_alloc_nolock();
struct ast_format tmp_fmt;
AST_LIST_LOCK(&confs);
@ -1197,9 +1199,10 @@ static struct ast_conference *build_conf(const char *confno, const char *pin,
break;
}
if (cnf || (!make && !dynamic))
if (cnf || (!make && !dynamic) || !cap_slin)
goto cnfout;
ast_format_cap_add(cap_slin, ast_format_set(&tmp_fmt, AST_FORMAT_SLINEAR, 0));
/* Make a new one */
if (!(cnf = ast_calloc(1, sizeof(*cnf))) ||
!(cnf->usercontainer = ao2_container_alloc(1, NULL, user_no_cmp))) {
@ -1245,10 +1248,10 @@ static struct ast_conference *build_conf(const char *confno, const char *pin,
cnf->dahdiconf = dahdic.confno;
/* Setup a new channel for playback of audio files */
cnf->chan = ast_request("DAHDI", AST_FORMAT_SLINEAR, chan, "pseudo", NULL);
cnf->chan = ast_request("DAHDI", cap_slin, chan, "pseudo", NULL);
if (cnf->chan) {
ast_set_read_format(cnf->chan, AST_FORMAT_SLINEAR);
ast_set_write_format(cnf->chan, AST_FORMAT_SLINEAR);
ast_set_read_format_by_id(cnf->chan, AST_FORMAT_SLINEAR);
ast_set_write_format_by_id(cnf->chan, AST_FORMAT_SLINEAR);
dahdic.chan = 0;
dahdic.confno = cnf->dahdiconf;
dahdic.confmode = DAHDI_CONF_CONFANN | DAHDI_CONF_CONFANNMON;
@ -1284,6 +1287,7 @@ static struct ast_conference *build_conf(const char *confno, const char *pin,
conf_map[confno_int] = 1;
cnfout:
cap_slin = ast_format_cap_destroy(cap_slin);
if (cnf)
ast_atomic_fetchadd_int(&cnf->refcount, refcount);
@ -2260,9 +2264,16 @@ static int conf_run(struct ast_channel *chan, struct ast_conference *conf, struc
int setusercount = 0;
int confsilence = 0, totalsilence = 0;
char *mailbox, *context;
struct ast_format_cap *cap_slin = ast_format_cap_alloc_nolock();
struct ast_format tmpfmt;
if (!cap_slin) {
goto conf_run_cleanup;
}
ast_format_cap_add(cap_slin, ast_format_set(&tmpfmt, AST_FORMAT_SLINEAR, 0));
if (!(user = ao2_alloc(sizeof(*user), NULL))) {
return ret;
goto conf_run_cleanup;
}
/* Possible timeout waiting for marked user */
@ -2372,9 +2383,9 @@ static int conf_run(struct ast_channel *chan, struct ast_conference *conf, struc
ast_mutex_lock(&conf->recordthreadlock);
if ((conf->recordthread == AST_PTHREADT_NULL) && ast_test_flag64(confflags, CONFFLAG_RECORDCONF) &&
((conf->lchan = ast_request("DAHDI", AST_FORMAT_SLINEAR, chan, "pseudo", NULL)))) {
ast_set_read_format(conf->lchan, AST_FORMAT_SLINEAR);
ast_set_write_format(conf->lchan, AST_FORMAT_SLINEAR);
((conf->lchan = ast_request("DAHDI", cap_slin, chan, "pseudo", NULL)))) {
ast_set_read_format_by_id(conf->lchan, AST_FORMAT_SLINEAR);
ast_set_write_format_by_id(conf->lchan, AST_FORMAT_SLINEAR);
dahdic.chan = 0;
dahdic.confno = conf->dahdiconf;
dahdic.confmode = DAHDI_CONF_CONFANN | DAHDI_CONF_CONFANNMON;
@ -2601,12 +2612,12 @@ static int conf_run(struct ast_channel *chan, struct ast_conference *conf, struc
ast_indicate(chan, -1);
}
if (ast_set_write_format(chan, AST_FORMAT_SLINEAR) < 0) {
if (ast_set_write_format_by_id(chan, AST_FORMAT_SLINEAR) < 0) {
ast_log(LOG_WARNING, "Unable to set '%s' to write linear mode\n", chan->name);
goto outrun;
}
if (ast_set_read_format(chan, AST_FORMAT_SLINEAR) < 0) {
if (ast_set_read_format_by_id(chan, AST_FORMAT_SLINEAR) < 0) {
ast_log(LOG_WARNING, "Unable to set '%s' to read linear mode\n", chan->name);
goto outrun;
}
@ -3167,7 +3178,7 @@ static int conf_run(struct ast_channel *chan, struct ast_conference *conf, struc
dtmfstr[1] = '\0';
}
if ((f->frametype == AST_FRAME_VOICE) && (f->subclass.codec == AST_FORMAT_SLINEAR)) {
if ((f->frametype == AST_FRAME_VOICE) && (f->subclass.format.id == AST_FORMAT_SLINEAR)) {
if (user->talk.actual) {
ast_frame_adjust_volume(f, user->talk.actual);
}
@ -3339,9 +3350,9 @@ static int conf_run(struct ast_channel *chan, struct ast_conference *conf, struc
}
ast_mutex_lock(&conf->recordthreadlock);
if ((conf->recordthread == AST_PTHREADT_NULL) && ast_test_flag64(confflags, CONFFLAG_RECORDCONF) && ((conf->lchan = ast_request("DAHDI", AST_FORMAT_SLINEAR, chan, "pseudo", NULL)))) {
ast_set_read_format(conf->lchan, AST_FORMAT_SLINEAR);
ast_set_write_format(conf->lchan, AST_FORMAT_SLINEAR);
if ((conf->recordthread == AST_PTHREADT_NULL) && ast_test_flag64(confflags, CONFFLAG_RECORDCONF) && ((conf->lchan = ast_request("DAHDI", cap_slin, chan, "pseudo", NULL)))) {
ast_set_read_format_by_id(conf->lchan, AST_FORMAT_SLINEAR);
ast_set_write_format_by_id(conf->lchan, AST_FORMAT_SLINEAR);
dahdic.chan = 0;
dahdic.confno = conf->dahdiconf;
dahdic.confmode = DAHDI_CONF_CONFANN | DAHDI_CONF_CONFANNMON;
@ -3627,7 +3638,7 @@ static int conf_run(struct ast_channel *chan, struct ast_conference *conf, struc
if (res > 0) {
memset(&fr, 0, sizeof(fr));
fr.frametype = AST_FRAME_VOICE;
fr.subclass.codec = AST_FORMAT_SLINEAR;
ast_format_set(&fr.subclass.format, AST_FORMAT_SLINEAR, 0);
fr.datalen = res;
fr.samples = res / 2;
fr.data.ptr = buf;
@ -3639,7 +3650,7 @@ static int conf_run(struct ast_channel *chan, struct ast_conference *conf, struc
)) {
int idx;
for (idx = 0; idx < AST_FRAME_BITS; idx++) {
if (chan->rawwriteformat & (1 << idx)) {
if (ast_format_to_old_bitfield(&chan->rawwriteformat) & (1 << idx)) {
break;
}
}
@ -3654,7 +3665,11 @@ static int conf_run(struct ast_channel *chan, struct ast_conference *conf, struc
mohtempstopped = 1;
}
if (!conf->transpath[idx]) {
conf->transpath[idx] = ast_translator_build_path((1 << idx), AST_FORMAT_SLINEAR);
struct ast_format src;
struct ast_format dst;
ast_format_set(&src, AST_FORMAT_SLINEAR, 0);
ast_format_from_old_bitfield(&dst, (1 << idx));
conf->transpath[idx] = ast_translator_build_path(&dst, &src);
}
if (conf->transpath[idx]) {
conf->transframe[idx] = ast_translate(conf->transpath[idx], conf->origframe, 0);
@ -3821,6 +3836,10 @@ bailoutandtrynormal:
ao2_ref(user, -1);
AST_LIST_UNLOCK(&confs);
conf_run_cleanup:
cap_slin = ast_format_cap_destroy(cap_slin);
return ret;
}

View File

@ -78,10 +78,10 @@ static int milliwatt_generate(struct ast_channel *chan, void *data, int len, int
int i, *indexp = (int *) data;
struct ast_frame wf = {
.frametype = AST_FRAME_VOICE,
.subclass.codec = AST_FORMAT_ULAW,
.offset = AST_FRIENDLY_OFFSET,
.src = __FUNCTION__,
};
ast_format_set(&wf.subclass.format, AST_FORMAT_ULAW, 0);
wf.data.ptr = buf + AST_FRIENDLY_OFFSET;
/* Instead of len, use samples, because channel.c generator_force
@ -120,8 +120,8 @@ static struct ast_generator milliwattgen = {
static int old_milliwatt_exec(struct ast_channel *chan)
{
ast_set_write_format(chan, AST_FORMAT_ULAW);
ast_set_read_format(chan, AST_FORMAT_ULAW);
ast_set_write_format_by_id(chan, AST_FORMAT_ULAW);
ast_set_read_format_by_id(chan, AST_FORMAT_ULAW);
if (chan->_state != AST_STATE_UP) {
ast_answer(chan);

View File

@ -281,7 +281,9 @@ static void *mixmonitor_thread(void *obj)
unsigned int oflags;
char *ext;
int errflag = 0;
struct ast_format format_slin;
ast_format_set(&format_slin, AST_FORMAT_SLINEAR, 0);
ast_verb(2, "Begin MixMonitor Recording %s\n", mixmonitor->name);
fs = &mixmonitor->mixmonitor_ds->fs;
@ -291,7 +293,7 @@ static void *mixmonitor_thread(void *obj)
while (mixmonitor->audiohook.status == AST_AUDIOHOOK_STATUS_RUNNING && !mixmonitor->mixmonitor_ds->fs_quit) {
struct ast_frame *fr = NULL;
if (!(fr = ast_audiohook_read_frame(&mixmonitor->audiohook, SAMPLES_PER_FRAME, AST_AUDIOHOOK_DIRECTION_BOTH, AST_FORMAT_SLINEAR))) {
if (!(fr = ast_audiohook_read_frame(&mixmonitor->audiohook, SAMPLES_PER_FRAME, AST_AUDIOHOOK_DIRECTION_BOTH, &format_slin))) {
ast_audiohook_trigger_wait(&mixmonitor->audiohook);
if (mixmonitor->audiohook.status != AST_AUDIOHOOK_STATUS_RUNNING) {

View File

@ -137,7 +137,7 @@ static int mp3_exec(struct ast_channel *chan, const char *data)
int fds[2];
int ms = -1;
int pid = -1;
int owriteformat;
struct ast_format owriteformat;
int timeout = 2000;
struct timeval next;
struct ast_frame *f;
@ -149,6 +149,7 @@ static int mp3_exec(struct ast_channel *chan, const char *data)
.f = { 0, },
};
ast_format_clear(&owriteformat);
if (ast_strlen_zero(data)) {
ast_log(LOG_WARNING, "MP3 Playback requires an argument (filename)\n");
return -1;
@ -161,8 +162,8 @@ static int mp3_exec(struct ast_channel *chan, const char *data)
ast_stopstream(chan);
owriteformat = chan->writeformat;
res = ast_set_write_format(chan, AST_FORMAT_SLINEAR);
ast_format_copy(&owriteformat, &chan->writeformat);
res = ast_set_write_format_by_id(chan, AST_FORMAT_SLINEAR);
if (res < 0) {
ast_log(LOG_WARNING, "Unable to set write format to signed linear\n");
return -1;
@ -185,7 +186,7 @@ static int mp3_exec(struct ast_channel *chan, const char *data)
res = timed_read(fds[0], myf.frdata, sizeof(myf.frdata), timeout);
if (res > 0) {
myf.f.frametype = AST_FRAME_VOICE;
myf.f.subclass.codec = AST_FORMAT_SLINEAR;
ast_format_set(&myf.f.subclass.format, AST_FORMAT_SLINEAR, 0);
myf.f.datalen = res;
myf.f.samples = res / 2;
myf.f.mallocd = 0;
@ -234,8 +235,8 @@ static int mp3_exec(struct ast_channel *chan, const char *data)
if (pid > -1)
kill(pid, SIGKILL);
if (!res && owriteformat)
ast_set_write_format(chan, owriteformat);
if (!res && owriteformat.id)
ast_set_write_format(chan, &owriteformat);
return res;
}

View File

@ -111,7 +111,7 @@ static int NBScat_exec(struct ast_channel *chan, const char *data)
int fds[2];
int ms = -1;
int pid = -1;
int owriteformat;
struct ast_format owriteformat;
struct timeval next;
struct ast_frame *f;
struct myframe {
@ -119,7 +119,8 @@ static int NBScat_exec(struct ast_channel *chan, const char *data)
char offset[AST_FRIENDLY_OFFSET];
short frdata[160];
} myf;
ast_format_clear(&owriteformat);
if (socketpair(AF_LOCAL, SOCK_STREAM, 0, fds)) {
ast_log(LOG_WARNING, "Unable to create socketpair\n");
return -1;
@ -127,8 +128,8 @@ static int NBScat_exec(struct ast_channel *chan, const char *data)
ast_stopstream(chan);
owriteformat = chan->writeformat;
res = ast_set_write_format(chan, AST_FORMAT_SLINEAR);
ast_format_copy(&owriteformat, &chan->writeformat);
res = ast_set_write_format_by_id(chan, AST_FORMAT_SLINEAR);
if (res < 0) {
ast_log(LOG_WARNING, "Unable to set write format to signed linear\n");
return -1;
@ -148,7 +149,7 @@ static int NBScat_exec(struct ast_channel *chan, const char *data)
res = timed_read(fds[0], myf.frdata, sizeof(myf.frdata));
if (res > 0) {
myf.f.frametype = AST_FRAME_VOICE;
myf.f.subclass.codec = AST_FORMAT_SLINEAR;
ast_format_set(&myf.f.subclass.format, AST_FORMAT_SLINEAR, 0);
myf.f.datalen = res;
myf.f.samples = res / 2;
myf.f.mallocd = 0;
@ -197,8 +198,8 @@ static int NBScat_exec(struct ast_channel *chan, const char *data)
if (pid > -1)
kill(pid, SIGKILL);
if (!res && owriteformat)
ast_set_write_format(chan, owriteformat);
if (!res && owriteformat.id)
ast_set_write_format(chan, &owriteformat);
return res;
}

View File

@ -105,8 +105,14 @@ static int originate_exec(struct ast_channel *chan, const char *data)
int outgoing_status = 0;
static const unsigned int timeout = 30;
static const char default_exten[] = "s";
struct ast_format tmpfmt;
struct ast_format_cap *cap_slin = ast_format_cap_alloc_nolock();
ast_autoservice_start(chan);
if (!cap_slin) {
goto return_cleanup;
}
ast_format_cap_add(cap_slin, ast_format_set(&tmpfmt, AST_FORMAT_SLINEAR, 0));
if (ast_strlen_zero(data)) {
ast_log(LOG_ERROR, "Originate() requires arguments\n");
@ -148,14 +154,14 @@ static int originate_exec(struct ast_channel *chan, const char *data)
ast_debug(1, "Originating call to '%s/%s' and connecting them to extension %s,%s,%d\n",
chantech, chandata, args.arg1, exten, priority);
outgoing_res = ast_pbx_outgoing_exten(chantech, AST_FORMAT_SLINEAR, chandata,
outgoing_res = ast_pbx_outgoing_exten(chantech, cap_slin, chandata,
timeout * 1000, args.arg1, exten, priority, &outgoing_status, 0, NULL,
NULL, NULL, NULL, NULL);
} else if (!strcasecmp(args.type, "app")) {
ast_debug(1, "Originating call to '%s/%s' and connecting them to %s(%s)\n",
chantech, chandata, args.arg1, S_OR(args.arg2, ""));
outgoing_res = ast_pbx_outgoing_app(chantech, AST_FORMAT_SLINEAR, chandata,
outgoing_res = ast_pbx_outgoing_app(chantech, cap_slin, chandata,
timeout * 1000, args.arg1, args.arg2, &outgoing_status, 0, NULL,
NULL, NULL, NULL, NULL);
} else {
@ -194,7 +200,7 @@ return_cleanup:
break;
}
}
cap_slin = ast_format_cap_destroy(cap_slin);
ast_autoservice_stop(chan);
return res;

View File

@ -96,6 +96,9 @@ static int parkandannounce_exec(struct ast_channel *chan, const char *data)
struct ast_channel *dchan;
struct outgoing_helper oh = { 0, };
int outstate;
struct ast_format tmpfmt;
struct ast_format_cap *cap_slin = ast_format_cap_alloc_nolock();
AST_DECLARE_APP_ARGS(args,
AST_APP_ARG(template);
AST_APP_ARG(timeout);
@ -104,9 +107,15 @@ static int parkandannounce_exec(struct ast_channel *chan, const char *data)
);
if (ast_strlen_zero(data)) {
ast_log(LOG_WARNING, "ParkAndAnnounce requires arguments: (announce:template|timeout|dial|[return_context])\n");
return -1;
res = -1;
goto parkcleanup;
}
if (!cap_slin) {
res = -1;
goto parkcleanup;
}
ast_format_cap_add(cap_slin, ast_format_set(&tmpfmt, AST_FORMAT_SLINEAR, 0));
s = ast_strdupa(data);
AST_STANDARD_APP_ARGS(args, s);
@ -115,7 +124,8 @@ static int parkandannounce_exec(struct ast_channel *chan, const char *data)
if (ast_strlen_zero(args.dial)) {
ast_log(LOG_WARNING, "PARK: A dial resource must be specified i.e: Console/dsp or DAHDI/g1/5551212\n");
return -1;
res = -1;
goto parkcleanup;
}
dialtech = strsep(&args.dial, "/");
@ -138,8 +148,9 @@ static int parkandannounce_exec(struct ast_channel *chan, const char *data)
before we are done announcing and the channel is messed with, Kablooeee. So we use Masq to prevent this. */
res = ast_masq_park_call(chan, NULL, timeout, &lot);
if (res == -1)
return res;
if (res == -1) {
goto parkcleanup;
}
ast_verb(3, "Call Parking Called, lot: %d, timeout: %d, context: %s\n", lot, timeout, args.return_context);
@ -148,7 +159,7 @@ static int parkandannounce_exec(struct ast_channel *chan, const char *data)
snprintf(buf, sizeof(buf), "%d", lot);
oh.parent_channel = chan;
oh.vars = ast_variable_new("_PARKEDAT", buf, "");
dchan = __ast_request_and_dial(dialtech, AST_FORMAT_SLINEAR, chan, args.dial, 30000,
dchan = __ast_request_and_dial(dialtech, cap_slin, chan, args.dial, 30000,
&outstate,
S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL),
S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL),
@ -160,11 +171,13 @@ static int parkandannounce_exec(struct ast_channel *chan, const char *data)
ast_verb(4, "Channel %s was never answered.\n", dchan->name);
ast_log(LOG_WARNING, "PARK: Channel %s was never answered for the announce.\n", dchan->name);
ast_hangup(dchan);
return -1;
res = -1;
goto parkcleanup;
}
} else {
ast_log(LOG_WARNING, "PARK: Unable to allocate announce channel.\n");
return -1;
res = -1;
goto parkcleanup;
}
ast_stopstream(dchan);
@ -197,7 +210,10 @@ static int parkandannounce_exec(struct ast_channel *chan, const char *data)
ast_stopstream(dchan);
ast_hangup(dchan);
parkcleanup:
cap_slin = ast_format_cap_destroy(cap_slin);
return res;
}

View File

@ -154,7 +154,7 @@ static int record_exec(struct ast_channel *chan, const char *data)
int maxduration = 0; /* max duration of recording in milliseconds */
int gottimeout = 0; /* did we timeout for maxduration exceeded? */
int terminator = '#';
int rfmt = 0;
struct ast_format rfmt;
int ioflags;
int waitres;
struct ast_silence_generator *silgen = NULL;
@ -165,7 +165,8 @@ static int record_exec(struct ast_channel *chan, const char *data)
AST_APP_ARG(maxduration);
AST_APP_ARG(options);
);
ast_format_clear(&rfmt);
/* The next few lines of code parse out the filename and header from the input string */
if (ast_strlen_zero(data)) { /* no data implies no filename or anything is present */
ast_log(LOG_WARNING, "Record requires an argument (filename)\n");
@ -286,8 +287,8 @@ static int record_exec(struct ast_channel *chan, const char *data)
/* The end of beep code. Now the recording starts */
if (silence > 0) {
rfmt = chan->readformat;
res = ast_set_read_format(chan, AST_FORMAT_SLINEAR);
ast_format_copy(&rfmt, &chan->readformat);
res = ast_set_read_format_by_id(chan, AST_FORMAT_SLINEAR);
if (res < 0) {
ast_log(LOG_WARNING, "Unable to set to linear mode, giving up\n");
pbx_builtin_setvar_helper(chan, "RECORD_STATUS", "ERROR");
@ -408,8 +409,8 @@ static int record_exec(struct ast_channel *chan, const char *data)
ast_channel_stop_silence_generator(chan, silgen);
out:
if ((silence > 0) && rfmt) {
res = ast_set_read_format(chan, rfmt);
if ((silence > 0) && rfmt.id) {
res = ast_set_read_format(chan, &rfmt);
if (res)
ast_log(LOG_WARNING, "Unable to restore read format on '%s'\n", chan->name);
if (sildet)

View File

@ -882,6 +882,7 @@ static int setrem(struct rpt *myrpt);
static int setrtx_check(struct rpt *myrpt);
static int channel_revert(struct rpt *myrpt);
static int channel_steer(struct rpt *myrpt, char *data);
static struct ast_format_cap *get_slin_cap(struct ast_format_cap *cap);
AST_MUTEX_DEFINE_STATIC(nodeloglock);
@ -951,7 +952,6 @@ int i;
return(NULL);
}
static void rpt_mutex_spew(void)
{
struct by_lightning lock_ring_copy[32];
@ -1070,6 +1070,18 @@ pthread_t id;
#endif /* APP_RPT_LOCK_DEBUG */
static struct ast_format_cap *get_slin_cap(struct ast_format_cap *cap)
{
struct ast_format tmp;
cap = ast_format_cap_alloc_nolock();
if (!cap) {
return NULL;
}
ast_format_cap_add(cap, ast_format_set(&tmp, AST_FORMAT_SLINEAR, 0));
return cap;
}
/*
* Return 1 if rig is multimode capable
*/
@ -3961,7 +3973,7 @@ char mhz[MAXREMSTR];
char decimals[MAXREMSTR];
char mystr[200];
struct dahdi_params par;
struct ast_format_cap *cap = NULL;
/* get a pointer to myrpt */
myrpt = mytele->rpt;
@ -4004,7 +4016,8 @@ struct dahdi_params par;
/* allocate a pseudo-channel thru asterisk */
mychannel = ast_request("DAHDI", AST_FORMAT_SLINEAR, NULL, "pseudo", NULL);
mychannel = ast_request("DAHDI", get_slin_cap(cap), NULL, "pseudo", NULL);
cap = ast_format_cap_destroy(cap);
if (!mychannel)
{
fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n");
@ -5288,10 +5301,12 @@ struct rpt *myrpt = (struct rpt *)this;
int res;
int stopped,congstarted,dialtimer,lastcidx,aborted;
struct ast_channel *mychannel,*genchannel;
struct ast_format_cap *cap = NULL;
myrpt->mydtmf = 0;
/* allocate a pseudo-channel thru asterisk */
mychannel = ast_request("DAHDI", AST_FORMAT_SLINEAR, NULL, "pseudo", NULL);
mychannel = ast_request("DAHDI", get_slin_cap(cap), NULL, "pseudo", NULL);
cap = ast_format_cap_destroy(cap);
if (!mychannel)
{
fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n");
@ -5317,7 +5332,8 @@ struct ast_channel *mychannel,*genchannel;
pthread_exit(NULL);
}
/* allocate a pseudo-channel thru asterisk */
genchannel = ast_request("DAHDI", AST_FORMAT_SLINEAR, NULL, "pseudo", NULL);
genchannel = ast_request("DAHDI", get_slin_cap(cap), NULL, "pseudo", NULL);
cap = ast_format_cap_destroy(cap);
if (!genchannel)
{
fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n");
@ -5689,6 +5705,7 @@ static int connect_link(struct rpt *myrpt, char* node, int mode, int perma)
int reconnects = 0;
int i,n;
struct dahdi_confinfo ci; /* conference info */
struct ast_format_cap *cap = NULL;
val = node_lookup(myrpt,node);
if (!val){
@ -5792,10 +5809,11 @@ static int connect_link(struct rpt *myrpt, char* node, int mode, int perma)
return -1;
}
*tele++ = 0;
l->chan = ast_request(deststr, AST_FORMAT_SLINEAR, NULL, tele, NULL);
l->chan = ast_request(deststr, get_slin_cap(cap), NULL, tele, NULL);
cap = ast_format_cap_destroy(cap);
if (l->chan){
ast_set_read_format(l->chan, AST_FORMAT_SLINEAR);
ast_set_write_format(l->chan, AST_FORMAT_SLINEAR);
ast_set_read_format_by_id(l->chan, AST_FORMAT_SLINEAR);
ast_set_write_format_by_id(l->chan, AST_FORMAT_SLINEAR);
#ifdef AST_CDR_FLAG_POST_DISABLED
if (l->chan->cdr)
ast_set_flag(l->chan->cdr,AST_CDR_FLAG_POST_DISABLED);
@ -5827,15 +5845,16 @@ static int connect_link(struct rpt *myrpt, char* node, int mode, int perma)
return -1;
}
/* allocate a pseudo-channel thru asterisk */
l->pchan = ast_request("DAHDI", AST_FORMAT_SLINEAR, NULL, "pseudo", NULL);
l->pchan = ast_request("DAHDI", get_slin_cap(cap), NULL, "pseudo", NULL);
cap = ast_format_cap_destroy(cap);
if (!l->pchan){
ast_log(LOG_WARNING,"rpt connect: Sorry unable to obtain pseudo channel\n");
ast_hangup(l->chan);
ast_free(l);
return -1;
}
ast_set_read_format(l->pchan, AST_FORMAT_SLINEAR);
ast_set_write_format(l->pchan, AST_FORMAT_SLINEAR);
ast_set_read_format_by_id(l->pchan, AST_FORMAT_SLINEAR);
ast_set_write_format_by_id(l->pchan, AST_FORMAT_SLINEAR);
#ifdef AST_CDR_FLAG_POST_DISABLED
if (l->pchan->cdr)
ast_set_flag(l->pchan->cdr,AST_CDR_FLAG_POST_DISABLED);
@ -10341,6 +10360,7 @@ static int attempt_reconnect(struct rpt *myrpt, struct rpt_link *l)
char *val, *s, *s1, *s2, *tele;
char tmp[300], deststr[300] = "";
char sx[320],*sy;
struct ast_format_cap *cap = NULL;
val = node_lookup(myrpt,l->name);
@ -10376,10 +10396,11 @@ static int attempt_reconnect(struct rpt *myrpt, struct rpt_link *l)
l->connecttime = 0;
l->thisconnected = 0;
l->newkey = 0;
l->chan = ast_request(deststr, AST_FORMAT_SLINEAR, NULL, tele, NULL);
l->chan = ast_request(deststr, get_slin_cap(cap), NULL, tele, NULL);
cap = ast_format_cap_destroy(cap);
if (l->chan){
ast_set_read_format(l->chan, AST_FORMAT_SLINEAR);
ast_set_write_format(l->chan, AST_FORMAT_SLINEAR);
ast_set_read_format_by_id(l->chan, AST_FORMAT_SLINEAR);
ast_set_write_format_by_id(l->chan, AST_FORMAT_SLINEAR);
#ifndef NEW_ASTERISK
l->chan->whentohangup = 0;
#endif
@ -10743,6 +10764,7 @@ time_t t;
struct rpt_link *l,*m;
struct rpt_tele *telem;
char tmpstr[300],lstr[MAXLINKLIST];
struct ast_format_cap *cap = NULL;
if (myrpt->p.archivedir) mkdir(myrpt->p.archivedir,0600);
@ -10795,7 +10817,8 @@ char tmpstr[300],lstr[MAXLINKLIST];
pthread_exit(NULL);
}
*tele++ = 0;
myrpt->rxchannel = ast_request(tmpstr, AST_FORMAT_SLINEAR, NULL, tele, NULL);
myrpt->rxchannel = ast_request(tmpstr, get_slin_cap(cap), NULL, tele, NULL);
cap = ast_format_cap_destroy(cap);
myrpt->dahdirxchannel = NULL;
if (!strcasecmp(tmpstr,"DAHDI"))
myrpt->dahdirxchannel = myrpt->rxchannel;
@ -10809,8 +10832,8 @@ char tmpstr[300],lstr[MAXLINKLIST];
myrpt->rpt_thread = AST_PTHREADT_STOP;
pthread_exit(NULL);
}
ast_set_read_format(myrpt->rxchannel,AST_FORMAT_SLINEAR);
ast_set_write_format(myrpt->rxchannel,AST_FORMAT_SLINEAR);
ast_set_read_format_by_id(myrpt->rxchannel,AST_FORMAT_SLINEAR);
ast_set_write_format_by_id(myrpt->rxchannel,AST_FORMAT_SLINEAR);
#ifdef AST_CDR_FLAG_POST_DISABLED
if (myrpt->rxchannel->cdr)
ast_set_flag(myrpt->rxchannel->cdr,AST_CDR_FLAG_POST_DISABLED);
@ -10853,7 +10876,8 @@ char tmpstr[300],lstr[MAXLINKLIST];
pthread_exit(NULL);
}
*tele++ = 0;
myrpt->txchannel = ast_request(tmpstr, AST_FORMAT_SLINEAR, NULL, tele, NULL);
myrpt->txchannel = ast_request(tmpstr, get_slin_cap(cap), NULL, tele, NULL);
cap = ast_format_cap_destroy(cap);
if (!strcasecmp(tmpstr,"DAHDI"))
myrpt->dahditxchannel = myrpt->txchannel;
if (myrpt->txchannel)
@ -10867,8 +10891,8 @@ char tmpstr[300],lstr[MAXLINKLIST];
myrpt->rpt_thread = AST_PTHREADT_STOP;
pthread_exit(NULL);
}
ast_set_read_format(myrpt->txchannel,AST_FORMAT_SLINEAR);
ast_set_write_format(myrpt->txchannel,AST_FORMAT_SLINEAR);
ast_set_read_format_by_id(myrpt->txchannel,AST_FORMAT_SLINEAR);
ast_set_write_format_by_id(myrpt->txchannel,AST_FORMAT_SLINEAR);
#ifdef AST_CDR_FLAG_POST_DISABLED
if (myrpt->txchannel->cdr)
ast_set_flag(myrpt->txchannel->cdr,AST_CDR_FLAG_POST_DISABLED);
@ -10909,7 +10933,8 @@ char tmpstr[300],lstr[MAXLINKLIST];
ast_indicate(myrpt->txchannel,AST_CONTROL_RADIO_KEY);
ast_indicate(myrpt->txchannel,AST_CONTROL_RADIO_UNKEY);
/* allocate a pseudo-channel thru asterisk */
myrpt->pchannel = ast_request("DAHDI", AST_FORMAT_SLINEAR, NULL, "pseudo", NULL);
myrpt->pchannel = ast_request("DAHDI", get_slin_cap(cap), NULL, "pseudo", NULL);
cap = ast_format_cap_destroy(cap);
if (!myrpt->pchannel)
{
fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n");
@ -10928,7 +10953,8 @@ char tmpstr[300],lstr[MAXLINKLIST];
if (!myrpt->dahditxchannel)
{
/* allocate a pseudo-channel thru asterisk */
myrpt->dahditxchannel = ast_request("DAHDI", AST_FORMAT_SLINEAR, NULL, "pseudo", NULL);
myrpt->dahditxchannel = ast_request("DAHDI", get_slin_cap(cap), NULL, "pseudo", NULL);
cap = ast_format_cap_destroy(cap);
if (!myrpt->dahditxchannel)
{
fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n");
@ -10939,15 +10965,16 @@ char tmpstr[300],lstr[MAXLINKLIST];
myrpt->rpt_thread = AST_PTHREADT_STOP;
pthread_exit(NULL);
}
ast_set_read_format(myrpt->dahditxchannel,AST_FORMAT_SLINEAR);
ast_set_write_format(myrpt->dahditxchannel,AST_FORMAT_SLINEAR);
ast_set_read_format_by_id(myrpt->dahditxchannel,AST_FORMAT_SLINEAR);
ast_set_write_format_by_id(myrpt->dahditxchannel,AST_FORMAT_SLINEAR);
#ifdef AST_CDR_FLAG_POST_DISABLED
if (myrpt->dahditxchannel->cdr)
ast_set_flag(myrpt->dahditxchannel->cdr,AST_CDR_FLAG_POST_DISABLED);
#endif
}
/* allocate a pseudo-channel thru asterisk */
myrpt->monchannel = ast_request("DAHDI", AST_FORMAT_SLINEAR, NULL, "pseudo", NULL);
myrpt->monchannel = ast_request("DAHDI", get_slin_cap(cap), NULL, "pseudo", NULL);
cap = ast_format_cap_destroy(cap);
if (!myrpt->monchannel)
{
fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n");
@ -10958,8 +10985,8 @@ char tmpstr[300],lstr[MAXLINKLIST];
myrpt->rpt_thread = AST_PTHREADT_STOP;
pthread_exit(NULL);
}
ast_set_read_format(myrpt->monchannel,AST_FORMAT_SLINEAR);
ast_set_write_format(myrpt->monchannel,AST_FORMAT_SLINEAR);
ast_set_read_format_by_id(myrpt->monchannel,AST_FORMAT_SLINEAR);
ast_set_write_format_by_id(myrpt->monchannel,AST_FORMAT_SLINEAR);
#ifdef AST_CDR_FLAG_POST_DISABLED
if (myrpt->monchannel->cdr)
ast_set_flag(myrpt->monchannel->cdr,AST_CDR_FLAG_POST_DISABLED);
@ -11042,7 +11069,8 @@ char tmpstr[300],lstr[MAXLINKLIST];
pthread_exit(NULL);
}
/* allocate a pseudo-channel thru asterisk */
myrpt->parrotchannel = ast_request("DAHDI", AST_FORMAT_SLINEAR, NULL, "pseudo", NULL);
myrpt->parrotchannel = ast_request("DAHDI", get_slin_cap(cap), NULL, "pseudo", NULL);
cap = ast_format_cap_destroy(cap);
if (!myrpt->parrotchannel)
{
fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n");
@ -11053,14 +11081,15 @@ char tmpstr[300],lstr[MAXLINKLIST];
myrpt->rpt_thread = AST_PTHREADT_STOP;
pthread_exit(NULL);
}
ast_set_read_format(myrpt->parrotchannel,AST_FORMAT_SLINEAR);
ast_set_write_format(myrpt->parrotchannel,AST_FORMAT_SLINEAR);
ast_set_read_format_by_id(myrpt->parrotchannel,AST_FORMAT_SLINEAR);
ast_set_write_format_by_id(myrpt->parrotchannel,AST_FORMAT_SLINEAR);
#ifdef AST_CDR_FLAG_POST_DISABLED
if (myrpt->parrotchannel->cdr)
ast_set_flag(myrpt->parrotchannel->cdr,AST_CDR_FLAG_POST_DISABLED);
#endif
/* allocate a pseudo-channel thru asterisk */
myrpt->voxchannel = ast_request("DAHDI", AST_FORMAT_SLINEAR, NULL, "pseudo", NULL);
myrpt->voxchannel = ast_request("DAHDI", get_slin_cap(cap), NULL, "pseudo", NULL);
cap = ast_format_cap_destroy(cap);
if (!myrpt->voxchannel)
{
fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n");
@ -11071,14 +11100,15 @@ char tmpstr[300],lstr[MAXLINKLIST];
myrpt->rpt_thread = AST_PTHREADT_STOP;
pthread_exit(NULL);
}
ast_set_read_format(myrpt->voxchannel,AST_FORMAT_SLINEAR);
ast_set_write_format(myrpt->voxchannel,AST_FORMAT_SLINEAR);
ast_set_read_format_by_id(myrpt->voxchannel,AST_FORMAT_SLINEAR);
ast_set_write_format_by_id(myrpt->voxchannel,AST_FORMAT_SLINEAR);
#ifdef AST_CDR_FLAG_POST_DISABLED
if (myrpt->voxchannel->cdr)
ast_set_flag(myrpt->voxchannel->cdr,AST_CDR_FLAG_POST_DISABLED);
#endif
/* allocate a pseudo-channel thru asterisk */
myrpt->txpchannel = ast_request("DAHDI", AST_FORMAT_SLINEAR, NULL, "pseudo", NULL);
myrpt->txpchannel = ast_request("DAHDI", get_slin_cap(cap), NULL, "pseudo", NULL);
cap = ast_format_cap_destroy(cap);
if (!myrpt->txpchannel)
{
fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n");
@ -13146,6 +13176,7 @@ static int rpt_exec(struct ast_channel *chan, const char *data)
struct dahdi_radio_param z;
struct rpt_tele *telem;
int numlinks;
struct ast_format_cap *cap = NULL;
nullfd = open("/dev/null",O_RDWR);
if (ast_strlen_zero(data)) {
@ -13631,17 +13662,18 @@ static int rpt_exec(struct ast_channel *chan, const char *data)
l->lastf2 = NULL;
l->dtmfed = 0;
voxinit_link(l,1);
ast_set_read_format(l->chan,AST_FORMAT_SLINEAR);
ast_set_write_format(l->chan,AST_FORMAT_SLINEAR);
ast_set_read_format_by_id(l->chan,AST_FORMAT_SLINEAR);
ast_set_write_format_by_id(l->chan,AST_FORMAT_SLINEAR);
/* allocate a pseudo-channel thru asterisk */
l->pchan = ast_request("DAHDI", AST_FORMAT_SLINEAR, NULL, "pseudo", NULL);
l->pchan = ast_request("DAHDI", get_slin_cap(cap), NULL, "pseudo", NULL);
cap = ast_format_cap_destroy(cap);
if (!l->pchan)
{
fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n");
pthread_exit(NULL);
}
ast_set_read_format(l->pchan,AST_FORMAT_SLINEAR);
ast_set_write_format(l->pchan,AST_FORMAT_SLINEAR);
ast_set_read_format_by_id(l->pchan,AST_FORMAT_SLINEAR);
ast_set_write_format_by_id(l->pchan,AST_FORMAT_SLINEAR);
#ifdef AST_CDR_FLAG_POST_DISABLED
if (l->pchan->cdr)
ast_set_flag(l->pchan->cdr,AST_CDR_FLAG_POST_DISABLED);
@ -13778,14 +13810,15 @@ static int rpt_exec(struct ast_channel *chan, const char *data)
pthread_exit(NULL);
}
*tele++ = 0;
myrpt->rxchannel = ast_request(myrpt->rxchanname, AST_FORMAT_SLINEAR, NULL, tele, NULL);
myrpt->rxchannel = ast_request(myrpt->rxchanname, get_slin_cap(cap), NULL, tele, NULL);
cap = ast_format_cap_destroy(cap);
myrpt->dahdirxchannel = NULL;
if (!strcasecmp(myrpt->rxchanname,"DAHDI"))
myrpt->dahdirxchannel = myrpt->rxchannel;
if (myrpt->rxchannel)
{
ast_set_read_format(myrpt->rxchannel,AST_FORMAT_SLINEAR);
ast_set_write_format(myrpt->rxchannel,AST_FORMAT_SLINEAR);
ast_set_read_format_by_id(myrpt->rxchannel,AST_FORMAT_SLINEAR);
ast_set_write_format_by_id(myrpt->rxchannel,AST_FORMAT_SLINEAR);
#ifdef AST_CDR_FLAG_POST_DISABLED
if (myrpt->rxchannel->cdr)
ast_set_flag(myrpt->rxchannel->cdr,AST_CDR_FLAG_POST_DISABLED);
@ -13821,13 +13854,14 @@ static int rpt_exec(struct ast_channel *chan, const char *data)
pthread_exit(NULL);
}
*tele++ = 0;
myrpt->txchannel = ast_request(myrpt->txchanname, AST_FORMAT_SLINEAR, NULL, tele, NULL);
myrpt->txchannel = ast_request(myrpt->txchanname, get_slin_cap(cap), NULL, tele, NULL);
cap = ast_format_cap_destroy(cap);
if (!strncasecmp(myrpt->txchanname,"DAHDI",3))
myrpt->dahditxchannel = myrpt->txchannel;
if (myrpt->txchannel)
{
ast_set_read_format(myrpt->txchannel,AST_FORMAT_SLINEAR);
ast_set_write_format(myrpt->txchannel,AST_FORMAT_SLINEAR);
ast_set_read_format_by_id(myrpt->txchannel,AST_FORMAT_SLINEAR);
ast_set_write_format_by_id(myrpt->txchannel,AST_FORMAT_SLINEAR);
#ifdef AST_CDR_FLAG_POST_DISABLED
if (myrpt->txchannel->cdr)
ast_set_flag(myrpt->txchannel->cdr,AST_CDR_FLAG_POST_DISABLED);
@ -13860,7 +13894,8 @@ static int rpt_exec(struct ast_channel *chan, const char *data)
myrpt->dahditxchannel = myrpt->rxchannel;
}
/* allocate a pseudo-channel thru asterisk */
myrpt->pchannel = ast_request("DAHDI", AST_FORMAT_SLINEAR, NULL, "pseudo", NULL);
myrpt->pchannel = ast_request("DAHDI", get_slin_cap(cap), NULL, "pseudo", NULL);
cap = ast_format_cap_destroy(cap);
if (!myrpt->pchannel)
{
fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n");
@ -13870,8 +13905,8 @@ static int rpt_exec(struct ast_channel *chan, const char *data)
ast_hangup(myrpt->rxchannel);
pthread_exit(NULL);
}
ast_set_read_format(myrpt->pchannel,AST_FORMAT_SLINEAR);
ast_set_write_format(myrpt->pchannel,AST_FORMAT_SLINEAR);
ast_set_read_format_by_id(myrpt->pchannel,AST_FORMAT_SLINEAR);
ast_set_write_format_by_id(myrpt->pchannel,AST_FORMAT_SLINEAR);
#ifdef AST_CDR_FLAG_POST_DISABLED
if (myrpt->pchannel->cdr)
ast_set_flag(myrpt->pchannel->cdr,AST_CDR_FLAG_POST_DISABLED);
@ -13987,8 +14022,8 @@ static int rpt_exec(struct ast_channel *chan, const char *data)
myrpt->tele.prev = &myrpt->tele;
myrpt->newkey = 0;
rpt_mutex_unlock(&myrpt->lock);
ast_set_write_format(chan, AST_FORMAT_SLINEAR);
ast_set_read_format(chan, AST_FORMAT_SLINEAR);
ast_set_write_format_by_id(chan, AST_FORMAT_SLINEAR);
ast_set_read_format_by_id(chan, AST_FORMAT_SLINEAR);
rem_rx = 0;
remkeyed = 0;
/* if we are on 2w loop and are a remote, turn EC on */

View File

@ -1603,7 +1603,7 @@ static int sms_generate(struct ast_channel *chan, void *data, int len, int sampl
buf = alloca(len);
f.frametype = AST_FRAME_VOICE;
f.subclass.codec = __OUT_FMT;
ast_format_set(&f.subclass.format, __OUT_FMT, 0);
f.datalen = samples * sizeof(*buf);
f.offset = AST_FRIENDLY_OFFSET;
f.mallocd = 0;
@ -2001,9 +2001,9 @@ static int sms_exec(struct ast_channel *chan, const char *data)
sms_messagetx(&h);
}
res = ast_set_write_format(chan, __OUT_FMT);
res = ast_set_write_format_by_id(chan, __OUT_FMT);
if (res >= 0) {
res = ast_set_read_format(chan, AST_FORMAT_SLINEAR);
res = ast_set_read_format_by_id(chan, AST_FORMAT_SLINEAR);
}
if (res < 0) {
ast_log(LOG_ERROR, "Unable to set to linear mode, giving up\n");

View File

@ -642,7 +642,7 @@ static int speech_background(struct ast_channel *chan, const char *data)
int res = 0, done = 0, started = 0, quieted = 0, max_dtmf_len = 0;
struct ast_speech *speech = find_speech(chan);
struct ast_frame *f = NULL;
int oldreadformat = AST_FORMAT_SLINEAR;
struct ast_format oldreadformat;
char dtmf[AST_MAX_EXTENSION] = "";
struct timeval start = { 0, 0 }, current;
struct ast_datastore *datastore = NULL;
@ -658,6 +658,7 @@ static int speech_background(struct ast_channel *chan, const char *data)
parse = ast_strdupa(data);
AST_STANDARD_APP_ARGS(args, parse);
ast_format_clear(&oldreadformat);
if (speech == NULL)
return -1;
@ -673,10 +674,10 @@ static int speech_background(struct ast_channel *chan, const char *data)
}
/* Record old read format */
oldreadformat = chan->readformat;
ast_format_copy(&oldreadformat, &chan->readformat);
/* Change read format to be signed linear */
if (ast_set_read_format(chan, speech->format))
if (ast_set_read_format(chan, &speech->format))
return -1;
if (!ast_strlen_zero(args.soundfile)) {
@ -881,7 +882,7 @@ static int speech_background(struct ast_channel *chan, const char *data)
ast_channel_datastore_remove(chan, datastore);
} else {
/* Channel is okay so restore read format */
ast_set_read_format(chan, oldreadformat);
ast_set_read_format(chan, &oldreadformat);
}
return 0;

View File

@ -87,7 +87,7 @@ static int background_detect_exec(struct ast_channel *chan, const char *data)
int analysistime = -1;
int continue_analysis = 1;
int x;
int origrformat = 0;
struct ast_format origrformat;
struct ast_dsp *dsp = NULL;
AST_DECLARE_APP_ARGS(args,
AST_APP_ARG(filename);
@ -96,7 +96,8 @@ static int background_detect_exec(struct ast_channel *chan, const char *data)
AST_APP_ARG(max);
AST_APP_ARG(analysistime);
);
ast_format_clear(&origrformat);
if (ast_strlen_zero(data)) {
ast_log(LOG_WARNING, "BackgroundDetect requires an argument (filename)\n");
return -1;
@ -126,8 +127,8 @@ static int background_detect_exec(struct ast_channel *chan, const char *data)
}
}
origrformat = chan->readformat;
if ((ast_set_read_format(chan, AST_FORMAT_SLINEAR))) {
ast_format_copy(&origrformat, &chan->readformat);
if ((ast_set_read_format_by_id(chan, AST_FORMAT_SLINEAR))) {
ast_log(LOG_WARNING, "Unable to set read format to linear!\n");
res = -1;
break;
@ -182,7 +183,7 @@ static int background_detect_exec(struct ast_channel *chan, const char *data)
ast_frfree(fr);
break;
}
} else if ((fr->frametype == AST_FRAME_VOICE) && (fr->subclass.codec == AST_FORMAT_SLINEAR) && continue_analysis) {
} else if ((fr->frametype == AST_FRAME_VOICE) && (fr->subclass.format.id == AST_FORMAT_SLINEAR) && continue_analysis) {
int totalsilence;
int ms;
res = ast_dsp_silence(dsp, fr, &totalsilence);
@ -228,9 +229,9 @@ static int background_detect_exec(struct ast_channel *chan, const char *data)
} while (0);
if (res > -1) {
if (origrformat && ast_set_read_format(chan, origrformat)) {
if (origrformat.id && ast_set_read_format(chan, &origrformat)) {
ast_log(LOG_WARNING, "Failed to restore read format for %s to %s\n",
chan->name, ast_getformatname(origrformat));
chan->name, ast_getformatname(&origrformat));
}
}
if (dsp) {

View File

@ -87,9 +87,10 @@ static int measurenoise(struct ast_channel *chan, int ms, char *who)
short *foo;
struct timeval start;
struct ast_frame *f;
int rformat;
rformat = chan->readformat;
if (ast_set_read_format(chan, AST_FORMAT_SLINEAR)) {
struct ast_format rformat;
ast_format_copy(&rformat, &chan->readformat);
if (ast_set_read_format_by_id(chan, AST_FORMAT_SLINEAR)) {
ast_log(LOG_NOTICE, "Unable to set to linear mode!\n");
return -1;
}
@ -106,7 +107,7 @@ static int measurenoise(struct ast_channel *chan, int ms, char *who)
res = -1;
break;
}
if ((f->frametype == AST_FRAME_VOICE) && (f->subclass.codec == AST_FORMAT_SLINEAR)) {
if ((f->frametype == AST_FRAME_VOICE) && (f->subclass.format.id == AST_FORMAT_SLINEAR)) {
foo = (short *)f->data.ptr;
for (x=0;x<f->samples;x++) {
noise += abs(foo[x]);
@ -116,8 +117,8 @@ static int measurenoise(struct ast_channel *chan, int ms, char *who)
ast_frfree(f);
}
if (rformat) {
if (ast_set_read_format(chan, rformat)) {
if (rformat.id) {
if (ast_set_read_format(chan, &rformat)) {
ast_log(LOG_NOTICE, "Unable to restore original format!\n");
return -1;
}

View File

@ -12347,11 +12347,11 @@ AST_TEST_DEFINE(test_voicemail_vmsayname)
}
/* normally this is done in the channel driver */
test_channel1->nativeformats = AST_FORMAT_GSM;
test_channel1->writeformat = AST_FORMAT_GSM;
test_channel1->rawwriteformat = AST_FORMAT_GSM;
test_channel1->readformat = AST_FORMAT_GSM;
test_channel1->rawreadformat = AST_FORMAT_GSM;
ast_format_set(&test_channel1->writeformat, AST_FORMAT_GSM, 0);
ast_format_cap_add(test_channel1->nativeformats, &test_channel1->writeformat);
ast_format_set(&test_channel1->rawwriteformat, AST_FORMAT_GSM, 0);
ast_format_set(&test_channel1->readformat, AST_FORMAT_GSM, 0);
ast_format_set(&test_channel1->rawreadformat, AST_FORMAT_GSM, 0);
test_channel1->tech = &fake_tech;
ast_test_status_update(test, "Test playing of extension when greeting is not available...\n");

View File

@ -125,7 +125,7 @@ static char *app_noise = "WaitForNoise";
static int do_waiting(struct ast_channel *chan, int timereqd, time_t waitstart, int timeout, int wait_for_silence) {
struct ast_frame *f = NULL;
int dsptime = 0;
int rfmt = 0;
struct ast_format rfmt;
int res = 0;
struct ast_dsp *sildet; /* silence detector dsp */
time_t now;
@ -134,8 +134,8 @@ static int do_waiting(struct ast_channel *chan, int timereqd, time_t waitstart,
int (*ast_dsp_func)(struct ast_dsp*, struct ast_frame*, int*) =
wait_for_silence ? ast_dsp_silence : ast_dsp_noise;
rfmt = chan->readformat; /* Set to linear mode */
if ((res = ast_set_read_format(chan, AST_FORMAT_SLINEAR)) < 0) {
ast_format_copy(&rfmt, &chan->readformat); /* Set to linear mode */
if ((res = ast_set_read_format_by_id(chan, AST_FORMAT_SLINEAR)) < 0) {
ast_log(LOG_WARNING, "Unable to set channel to linear mode, giving up\n");
return -1;
}
@ -195,8 +195,8 @@ static int do_waiting(struct ast_channel *chan, int timereqd, time_t waitstart,
}
if (rfmt && ast_set_read_format(chan, rfmt)) {
ast_log(LOG_WARNING, "Unable to restore format %s to channel '%s'\n", ast_getformatname(rfmt), chan->name);
if (rfmt.id && ast_set_read_format(chan, &rfmt)) {
ast_log(LOG_WARNING, "Unable to restore format %s to channel '%s'\n", ast_getformatname(&rfmt), chan->name);
}
ast_dsp_free(sildet);
return res;

View File

@ -306,7 +306,9 @@ static int multiplexed_bridge_join(struct ast_bridge *bridge, struct ast_bridge_
return 0;
}
if (((c0->writeformat == c1->readformat) && (c0->readformat == c1->writeformat) && (c0->nativeformats == c1->nativeformats))) {
if ((ast_format_cmp(&c0->writeformat, &c1->readformat) == AST_FORMAT_CMP_EQUAL) &&
(ast_format_cmp(&c0->readformat, &c1->writeformat) == AST_FORMAT_CMP_EQUAL) &&
(ast_format_cap_identical(c0->nativeformats, c1->nativeformats))) {
return 0;
}
@ -373,7 +375,6 @@ static struct ast_bridge_technology multiplexed_bridge = {
.name = "multiplexed_bridge",
.capabilities = AST_BRIDGE_CAPABILITY_1TO1MIX,
.preference = AST_BRIDGE_PREFERENCE_HIGH,
.formats = AST_FORMAT_AUDIO_MASK | AST_FORMAT_VIDEO_MASK | AST_FORMAT_TEXT_MASK,
.create = multiplexed_bridge_create,
.destroy = multiplexed_bridge_destroy,
.join = multiplexed_bridge_join,
@ -388,6 +389,7 @@ static int unload_module(void)
int res = ast_bridge_technology_unregister(&multiplexed_bridge);
ao2_ref(multiplexed_threads, -1);
multiplexed_bridge.format_capabilities = ast_format_cap_destroy(multiplexed_bridge.format_capabilities);
return res;
}
@ -397,7 +399,12 @@ static int load_module(void)
if (!(multiplexed_threads = ao2_container_alloc(MULTIPLEXED_BUCKETS, NULL, NULL))) {
return AST_MODULE_LOAD_DECLINE;
}
if (!(multiplexed_bridge.format_capabilities = ast_format_cap_alloc())) {
return AST_MODULE_LOAD_DECLINE;
}
ast_format_cap_add_all_by_type(multiplexed_bridge.format_capabilities, AST_FORMAT_TYPE_AUDIO);
ast_format_cap_add_all_by_type(multiplexed_bridge.format_capabilities, AST_FORMAT_TYPE_VIDEO);
ast_format_cap_add_all_by_type(multiplexed_bridge.format_capabilities, AST_FORMAT_TYPE_TEXT);
return ast_bridge_technology_register(&multiplexed_bridge);
}

View File

@ -51,7 +51,9 @@ static int simple_bridge_join(struct ast_bridge *bridge, struct ast_bridge_chann
}
/* See if we need to make these compatible */
if (((c0->writeformat == c1->readformat) && (c0->readformat == c1->writeformat) && (c0->nativeformats == c1->nativeformats))) {
if ((ast_format_cmp(&c0->writeformat, &c1->readformat) == AST_FORMAT_CMP_EQUAL) &&
(ast_format_cmp(&c0->readformat, &c1->writeformat) == AST_FORMAT_CMP_EQUAL) &&
(ast_format_cap_identical(c0->nativeformats, c1->nativeformats))) {
return 0;
}
@ -85,18 +87,25 @@ static struct ast_bridge_technology simple_bridge = {
.name = "simple_bridge",
.capabilities = AST_BRIDGE_CAPABILITY_1TO1MIX | AST_BRIDGE_CAPABILITY_THREAD,
.preference = AST_BRIDGE_PREFERENCE_MEDIUM,
.formats = AST_FORMAT_AUDIO_MASK | AST_FORMAT_VIDEO_MASK | AST_FORMAT_TEXT_MASK,
.join = simple_bridge_join,
.write = simple_bridge_write,
};
static int unload_module(void)
{
ast_format_cap_destroy(simple_bridge.format_capabilities);
return ast_bridge_technology_unregister(&simple_bridge);
}
static int load_module(void)
{
if (!(simple_bridge.format_capabilities = ast_format_cap_alloc())) {
return AST_MODULE_LOAD_DECLINE;
}
ast_format_cap_add_all_by_type(simple_bridge.format_capabilities, AST_FORMAT_TYPE_AUDIO);
ast_format_cap_add_all_by_type(simple_bridge.format_capabilities, AST_FORMAT_TYPE_VIDEO);
ast_format_cap_add_all_by_type(simple_bridge.format_capabilities, AST_FORMAT_TYPE_TEXT);
return ast_bridge_technology_register(&simple_bridge);
}

View File

@ -126,9 +126,9 @@ static int softmix_bridge_join(struct ast_bridge *bridge, struct ast_bridge_chan
/* Setup frame parameters */
sc->frame.frametype = AST_FRAME_VOICE;
#ifdef SOFTMIX_16_SUPPORT
sc->frame.subclass.codec = AST_FORMAT_SLINEAR16;
ast_format_set(&sc->frame.subclass.format, AST_FORMAT_SLINEAR16, 0);
#else
sc->frame.subclass.codec = AST_FORMAT_SLINEAR;
ast_format_set(&sc->frame.subclass.format, AST_FORMAT_SLINEAR, 0);
#endif
sc->frame.data.ptr = sc->final_buf;
sc->frame.datalen = SOFTMIX_DATALEN;
@ -171,9 +171,9 @@ static enum ast_bridge_write_result softmix_bridge_write(struct ast_bridge *brid
/* If a frame was provided add it to the smoother */
#ifdef SOFTMIX_16_SUPPORT
if (frame->frametype == AST_FRAME_VOICE && frame->subclass.codec == AST_FORMAT_SLINEAR16) {
if (frame->frametype == AST_FRAME_VOICE && frame->subclass.format.id == AST_FORMAT_SLINEAR16) {
#else
if (frame->frametype == AST_FRAME_VOICE && frame->subclass.codec == AST_FORMAT_SLINEAR) {
if (frame->frametype == AST_FRAME_VOICE && frame->subclass.format.id == AST_FORMAT_SLINEAR) {
#endif
ast_slinfactory_feed(&sc->factory, frame);
}
@ -282,11 +282,6 @@ static struct ast_bridge_technology softmix_bridge = {
.name = "softmix",
.capabilities = AST_BRIDGE_CAPABILITY_MULTIMIX | AST_BRIDGE_CAPABILITY_THREAD | AST_BRIDGE_CAPABILITY_MULTITHREADED,
.preference = AST_BRIDGE_PREFERENCE_LOW,
#ifdef SOFTMIX_16_SUPPORT
.formats = AST_FORMAT_SLINEAR16,
#else
.formats = AST_FORMAT_SLINEAR,
#endif
.create = softmix_bridge_create,
.destroy = softmix_bridge_destroy,
.join = softmix_bridge_join,
@ -298,11 +293,21 @@ static struct ast_bridge_technology softmix_bridge = {
static int unload_module(void)
{
ast_format_cap_destroy(softmix_bridge.format_capabilities);
return ast_bridge_technology_unregister(&softmix_bridge);
}
static int load_module(void)
{
struct ast_format tmp;
if (!(softmix_bridge.format_capabilities = ast_format_cap_alloc())) {
return AST_MODULE_LOAD_DECLINE;
}
#ifdef SOFTMIX_16_SUPPORT
ast_format_cap_add(softmix_bridge.format_capabilities, ast_format_set(&tmp, AST_FORMAT_SLINEAR16, 0));
#else
ast_format_cap_add(softmix_bridge.format_capabilities, ast_format_set(&tmp, AST_FORMAT_SLINEAR, 0));
#endif
return ast_bridge_technology_register(&softmix_bridge);
}

View File

@ -297,19 +297,19 @@ static AST_LIST_HEAD_STATIC(agents, agent_pvt); /*!< Holds the list of agents (l
#define CHECK_FORMATS(ast, p) do { \
if (p->chan) {\
if (ast->nativeformats != p->chan->nativeformats) { \
if (!(ast_format_cap_identical(ast->nativeformats, p->chan->nativeformats))) { \
char tmp1[256], tmp2[256]; \
ast_debug(1, "Native formats changing from '%s' to '%s'\n", ast_getformatname_multiple(tmp1, sizeof(tmp1), ast->nativeformats), ast_getformatname_multiple(tmp2, sizeof(tmp2), p->chan->nativeformats)); \
/* Native formats changed, reset things */ \
ast->nativeformats = p->chan->nativeformats; \
ast_debug(1, "Resetting read to '%s' and write to '%s'\n", ast_getformatname_multiple(tmp1, sizeof(tmp1), ast->readformat), ast_getformatname_multiple(tmp2, sizeof(tmp2), ast->writeformat));\
ast_set_read_format(ast, ast->readformat); \
ast_set_write_format(ast, ast->writeformat); \
ast_format_cap_copy(ast->nativeformats, p->chan->nativeformats); \
ast_debug(1, "Resetting read to '%s' and write to '%s'\n", ast_getformatname(&ast->readformat), ast_getformatname(&ast->writeformat));\
ast_set_read_format(ast, &ast->readformat); \
ast_set_write_format(ast, &ast->writeformat); \
} \
if (p->chan->readformat != ast->rawreadformat && !p->chan->generator) \
ast_set_read_format(p->chan, ast->rawreadformat); \
if (p->chan->writeformat != ast->rawwriteformat && !p->chan->generator) \
ast_set_write_format(p->chan, ast->rawwriteformat); \
if ((ast_format_cmp(&p->chan->readformat, &ast->rawreadformat) != AST_FORMAT_CMP_EQUAL) && !p->chan->generator) \
ast_set_read_format(p->chan, &ast->rawreadformat); \
if ((ast_format_cmp(&p->chan->writeformat, &ast->rawwriteformat) != AST_FORMAT_CMP_EQUAL) && !p->chan->generator) \
ast_set_write_format(p->chan, &ast->rawwriteformat); \
} \
} while(0)
@ -329,7 +329,7 @@ static AST_LIST_HEAD_STATIC(agents, agent_pvt); /*!< Holds the list of agents (l
} while(0)
/*--- Forward declarations */
static struct ast_channel *agent_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause);
static struct ast_channel *agent_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, void *data, int *cause);
static int agent_devicestate(void *data);
static int agent_digit_begin(struct ast_channel *ast, char digit);
static int agent_digit_end(struct ast_channel *ast, char digit, unsigned int duration);
@ -349,10 +349,9 @@ static int agent_set_base_channel(struct ast_channel *chan, struct ast_channel *
static int agent_logoff(const char *agent, int soft);
/*! \brief Channel interface description for PBX integration */
static const struct ast_channel_tech agent_tech = {
static struct ast_channel_tech agent_tech = {
.type = "Agent",
.description = tdesc,
.capabilities = -1,
.requester = agent_request,
.devicestate = agent_devicestate,
.send_digit_begin = agent_digit_begin,
@ -695,7 +694,7 @@ static int agent_write(struct ast_channel *ast, struct ast_frame *f)
else {
if ((f->frametype != AST_FRAME_VOICE) ||
(f->frametype != AST_FRAME_VIDEO) ||
(f->subclass.codec == p->chan->writeformat)) {
(ast_format_cmp(&f->subclass.format, &p->chan->writeformat) != AST_FORMAT_CMP_NOT_EQUAL)) {
res = ast_write(p->chan, f);
} else {
ast_debug(1, "Dropping one incompatible %s frame on '%s' to '%s'\n",
@ -799,10 +798,11 @@ static int agent_call(struct ast_channel *ast, char *dest, int timeout)
ast_debug(3, "Waited for stream, result '%d'\n", res);
}
if (!res) {
res = ast_set_read_format(p->chan, ast_best_codec(p->chan->nativeformats));
struct ast_format tmpfmt;
res = ast_set_read_format_from_cap(p->chan, p->chan->nativeformats);
ast_debug(3, "Set read format, result '%d'\n", res);
if (res)
ast_log(LOG_WARNING, "Unable to set read format to %s\n", ast_getformatname(ast_best_codec(p->chan->nativeformats)));
ast_log(LOG_WARNING, "Unable to set read format to %s\n", ast_getformatname(&tmpfmt));
} else {
/* Agent hung-up */
p->chan = NULL;
@ -810,10 +810,11 @@ static int agent_call(struct ast_channel *ast, char *dest, int timeout)
}
if (!res) {
res = ast_set_write_format(p->chan, ast_best_codec(p->chan->nativeformats));
struct ast_format tmpfmt;
res = ast_set_write_format_from_cap(p->chan, p->chan->nativeformats);
ast_debug(3, "Set write format, result '%d'\n", res);
if (res)
ast_log(LOG_WARNING, "Unable to set write format to %s\n", ast_getformatname(ast_best_codec(p->chan->nativeformats)));
ast_log(LOG_WARNING, "Unable to set write format to %s\n", ast_getformatname(&tmpfmt));
}
if(!res) {
/* Call is immediately up, or might need ack */
@ -1047,21 +1048,21 @@ static struct ast_channel *agent_new(struct agent_pvt *p, int state, const char
tmp->tech = &agent_tech;
if (p->chan) {
tmp->nativeformats = p->chan->nativeformats;
tmp->writeformat = p->chan->writeformat;
tmp->rawwriteformat = p->chan->writeformat;
tmp->readformat = p->chan->readformat;
tmp->rawreadformat = p->chan->readformat;
ast_format_cap_copy(tmp->nativeformats, p->chan->nativeformats);
ast_format_copy(&tmp->writeformat, &p->chan->writeformat);
ast_format_copy(&tmp->rawwriteformat, &p->chan->writeformat);
ast_format_copy(&tmp->readformat, &p->chan->readformat);
ast_format_copy(&tmp->rawreadformat, &p->chan->readformat);
ast_string_field_set(tmp, language, p->chan->language);
ast_copy_string(tmp->context, p->chan->context, sizeof(tmp->context));
ast_copy_string(tmp->exten, p->chan->exten, sizeof(tmp->exten));
/* XXX Is this really all we copy form the originating channel?? */
} else {
tmp->nativeformats = AST_FORMAT_SLINEAR;
tmp->writeformat = AST_FORMAT_SLINEAR;
tmp->rawwriteformat = AST_FORMAT_SLINEAR;
tmp->readformat = AST_FORMAT_SLINEAR;
tmp->rawreadformat = AST_FORMAT_SLINEAR;
ast_format_set(&tmp->writeformat, AST_FORMAT_SLINEAR, 0);
ast_format_set(&tmp->rawwriteformat, AST_FORMAT_SLINEAR, 0);
ast_format_set(&tmp->readformat, AST_FORMAT_SLINEAR, 0);
ast_format_set(&tmp->rawreadformat, AST_FORMAT_SLINEAR, 0);
ast_format_cap_add(tmp->nativeformats, &tmp->writeformat);
}
/* Safe, agentlock already held */
tmp->tech_pvt = p;
@ -1374,7 +1375,7 @@ static int check_beep(struct agent_pvt *newlyavailable, int needlock)
}
/*! \brief Part of the Asterisk PBX interface */
static struct ast_channel *agent_request(const char *type, format_t format, const struct ast_channel* requestor, void *data, int *cause)
static struct ast_channel *agent_request(const char *type, struct ast_format_cap *cap, const struct ast_channel* requestor, void *data, int *cause)
{
struct agent_pvt *p;
struct ast_channel *chan = NULL;
@ -1997,14 +1998,18 @@ static int login_exec(struct ast_channel *chan, const char *data)
AST_LIST_LOCK(&agents);
ast_mutex_lock(&p->lock);
if (!res) {
res = ast_set_read_format(chan, ast_best_codec(chan->nativeformats));
if (res)
ast_log(LOG_WARNING, "Unable to set read format to %s\n", ast_getformatname(ast_best_codec(chan->nativeformats)));
struct ast_format tmpfmt;
res = ast_set_read_format_from_cap(chan, chan->nativeformats);
if (res) {
ast_log(LOG_WARNING, "Unable to set read format to %s\n", ast_getformatname(&tmpfmt));
}
}
if (!res) {
res = ast_set_write_format(chan, ast_best_codec(chan->nativeformats));
if (res)
ast_log(LOG_WARNING, "Unable to set write format to %s\n", ast_getformatname(ast_best_codec(chan->nativeformats)));
struct ast_format tmpfmt;
res = ast_set_write_format_from_cap(chan, chan->nativeformats);
if (res) {
ast_log(LOG_WARNING, "Unable to set write format to %s\n", ast_getformatname(&tmpfmt));
}
}
/* Check once more just in case */
if (p->chan)
@ -2024,7 +2029,7 @@ static int login_exec(struct ast_channel *chan, const char *data)
snprintf(chan->cdr->channel, sizeof(chan->cdr->channel), "Agent/%s", p->agent);
ast_queue_log("NONE", chan->uniqueid, agent, "AGENTLOGIN", "%s", chan->name);
ast_verb(2, "Agent '%s' logged in (format %s/%s)\n", p->agent,
ast_getformatname(chan->readformat), ast_getformatname(chan->writeformat));
ast_getformatname(&chan->readformat), ast_getformatname(&chan->writeformat));
/* Login this channel and wait for it to go away */
p->chan = chan;
if (p->ackcall) {
@ -2418,6 +2423,11 @@ static const struct ast_data_entry agents_data_providers[] = {
*/
static int load_module(void)
{
if (!(agent_tech.capabilities = ast_format_cap_alloc())) {
ast_log(LOG_ERROR, "ast_format_cap_alloc_nolock fail.\n");
return AST_MODULE_LOAD_FAILURE;
}
ast_format_cap_add_all(agent_tech.capabilities);
/* Make sure we can register our agent channel type */
if (ast_channel_register(&agent_tech)) {
ast_log(LOG_ERROR, "Unable to register channel class 'Agent'\n");
@ -2477,6 +2487,8 @@ static int unload_module(void)
ast_free(p);
}
AST_LIST_UNLOCK(&agents);
agent_tech.capabilities = ast_format_cap_destroy(agent_tech.capabilities);
return 0;
}

View File

@ -133,7 +133,7 @@ static int autoanswer = 1;
static int mute = 0;
static int noaudiocapture = 0;
static struct ast_channel *alsa_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause);
static struct ast_channel *alsa_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, void *data, int *cause);
static int alsa_digit(struct ast_channel *c, char digit, unsigned int duration);
static int alsa_text(struct ast_channel *c, const char *text);
static int alsa_hangup(struct ast_channel *c);
@ -144,10 +144,9 @@ static int alsa_write(struct ast_channel *chan, struct ast_frame *f);
static int alsa_indicate(struct ast_channel *chan, int cond, const void *data, size_t datalen);
static int alsa_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
static const struct ast_channel_tech alsa_tech = {
static struct ast_channel_tech alsa_tech = {
.type = "Console",
.description = tdesc,
.capabilities = AST_FORMAT_SLINEAR,
.requester = alsa_request,
.send_digit_end = alsa_digit,
.send_text = alsa_text,
@ -502,7 +501,7 @@ static struct ast_frame *alsa_read(struct ast_channel *chan)
}
f.frametype = AST_FRAME_VOICE;
f.subclass.codec = AST_FORMAT_SLINEAR;
ast_format_set(&f.subclass.format, AST_FORMAT_SLINEAR, 0);
f.samples = FRAME_SIZE;
f.datalen = FRAME_SIZE * 2;
f.data.ptr = buf;
@ -572,9 +571,10 @@ static struct ast_channel *alsa_new(struct chan_alsa_pvt *p, int state, const ch
tmp->tech = &alsa_tech;
ast_channel_set_fd(tmp, 0, readdev);
tmp->nativeformats = AST_FORMAT_SLINEAR;
tmp->readformat = AST_FORMAT_SLINEAR;
tmp->writeformat = AST_FORMAT_SLINEAR;
ast_format_set(&tmp->readformat, AST_FORMAT_SLINEAR, 0);
ast_format_set(&tmp->writeformat, AST_FORMAT_SLINEAR, 0);
ast_format_cap_add(tmp->nativeformats, &tmp->writeformat);
tmp->tech_pvt = p;
if (!ast_strlen_zero(p->context))
ast_copy_string(tmp->context, p->context, sizeof(tmp->context));
@ -596,14 +596,16 @@ static struct ast_channel *alsa_new(struct chan_alsa_pvt *p, int state, const ch
return tmp;
}
static struct ast_channel *alsa_request(const char *type, format_t fmt, const struct ast_channel *requestor, void *data, int *cause)
static struct ast_channel *alsa_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, void *data, int *cause)
{
format_t oldformat = fmt;
struct ast_format tmpfmt;
char buf[256];
struct ast_channel *tmp = NULL;
if (!(fmt &= AST_FORMAT_SLINEAR)) {
ast_log(LOG_NOTICE, "Asked to get a channel of format '%s'\n", ast_getformatname_multiple(buf, sizeof(buf), oldformat));
ast_format_set(&tmpfmt, AST_FORMAT_SLINEAR, 0);
if (!(ast_format_cap_iscompatible(cap, &tmpfmt))) {
ast_log(LOG_NOTICE, "Asked to get a channel of format '%s'\n", ast_getformatname_multiple(buf, sizeof(buf), cap));
return NULL;
}
@ -929,6 +931,12 @@ static int load_module(void)
struct ast_config *cfg;
struct ast_variable *v;
struct ast_flags config_flags = { 0 };
struct ast_format tmpfmt;
if (!(alsa_tech.capabilities = ast_format_cap_alloc())) {
return AST_MODULE_LOAD_DECLINE;
}
ast_format_cap_add(alsa_tech.capabilities, ast_format_set(&tmpfmt, AST_FORMAT_SLINEAR, 0));
/* Copy the default jb config over global_jbconf */
memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf));
@ -1006,6 +1014,7 @@ static int unload_module(void)
if (alsa.owner)
return -1;
alsa_tech.capabilities = ast_format_cap_destroy(alsa_tech.capabilities);
return 0;
}

View File

@ -46,17 +46,16 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include "asterisk/app.h"
#include "asterisk/bridging.h"
static struct ast_channel *bridge_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause);
static struct ast_channel *bridge_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, void *data, int *cause);
static int bridge_call(struct ast_channel *ast, char *dest, int timeout);
static int bridge_hangup(struct ast_channel *ast);
static struct ast_frame *bridge_read(struct ast_channel *ast);
static int bridge_write(struct ast_channel *ast, struct ast_frame *f);
static struct ast_channel *bridge_bridgedchannel(struct ast_channel *chan, struct ast_channel *bridge);
static const struct ast_channel_tech bridge_tech = {
static struct ast_channel_tech bridge_tech = {
.type = "Bridge",
.description = "Bridge Interaction Channel",
.capabilities = -1,
.requester = bridge_request,
.call = bridge_call,
.hangup = bridge_hangup,
@ -189,9 +188,10 @@ static int bridge_hangup(struct ast_channel *ast)
}
/*! \brief Called when we want to place a call somewhere, but not actually call it... yet */
static struct ast_channel *bridge_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause)
static struct ast_channel *bridge_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, void *data, int *cause)
{
struct bridge_pvt *p = NULL;
struct ast_format slin;
/* Try to allocate memory for our very minimal pvt structure */
if (!(p = ast_calloc(1, sizeof(*p)))) {
@ -215,11 +215,19 @@ static struct ast_channel *bridge_request(const char *type, format_t format, con
/* Setup parameters on both new channels */
p->input->tech = p->output->tech = &bridge_tech;
p->input->tech_pvt = p->output->tech_pvt = p;
p->input->nativeformats = p->output->nativeformats = AST_FORMAT_SLINEAR;
p->input->readformat = p->output->readformat = AST_FORMAT_SLINEAR;
p->input->rawreadformat = p->output->rawreadformat = AST_FORMAT_SLINEAR;
p->input->writeformat = p->output->writeformat = AST_FORMAT_SLINEAR;
p->input->rawwriteformat = p->output->rawwriteformat = AST_FORMAT_SLINEAR;
ast_format_set(&slin, AST_FORMAT_SLINEAR, 0);
ast_format_cap_add(p->input->nativeformats, &slin);
ast_format_cap_add(p->output->nativeformats, &slin);
ast_format_copy(&p->input->readformat, &slin);
ast_format_copy(&p->output->readformat, &slin);
ast_format_copy(&p->input->rawreadformat, &slin);
ast_format_copy(&p->output->rawreadformat, &slin);
ast_format_copy(&p->input->writeformat, &slin);
ast_format_copy(&p->output->writeformat, &slin);
ast_format_copy(&p->input->rawwriteformat, &slin);
ast_format_copy(&p->output->rawwriteformat, &slin);
return p->input;
}
@ -227,6 +235,11 @@ static struct ast_channel *bridge_request(const char *type, format_t format, con
/*! \brief Load module into PBX, register channel */
static int load_module(void)
{
if (!(bridge_tech.capabilities = ast_format_cap_alloc())) {
return AST_MODULE_LOAD_FAILURE;
}
ast_format_cap_add_all(bridge_tech.capabilities);
/* Make sure we can register our channel type */
if (ast_channel_register(&bridge_tech)) {
ast_log(LOG_ERROR, "Unable to register channel class 'Bridge'\n");
@ -239,6 +252,7 @@ static int load_module(void)
static int unload_module(void)
{
ast_channel_unregister(&bridge_tech);
bridge_tech.capabilities = ast_format_cap_destroy(bridge_tech.capabilities);
return 0;
}

View File

@ -183,7 +183,7 @@ static struct ast_jb_conf default_jbconf = {
static struct ast_jb_conf global_jbconf;
/*! Channel Technology Callbacks @{ */
static struct ast_channel *console_request(const char *type, format_t format,
static struct ast_channel *console_request(const char *type, struct ast_format_cap *cap,
const struct ast_channel *requestor, void *data, int *cause);
static int console_digit_begin(struct ast_channel *c, char digit);
static int console_digit_end(struct ast_channel *c, char digit, unsigned int duration);
@ -198,15 +198,9 @@ static int console_indicate(struct ast_channel *chan, int cond,
static int console_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
/*! @} */
/*!
* \brief Formats natively supported by this module.
*/
#define SUPPORTED_FORMATS ( AST_FORMAT_SLINEAR16 )
static const struct ast_channel_tech console_tech = {
static struct ast_channel_tech console_tech = {
.type = "Console",
.description = "Console Channel Driver",
.capabilities = SUPPORTED_FORMATS,
.requester = console_request,
.send_digit_begin = console_digit_begin,
.send_digit_end = console_digit_end,
@ -265,12 +259,12 @@ static void *stream_monitor(void *data)
PaError res;
struct ast_frame f = {
.frametype = AST_FRAME_VOICE,
.subclass.codec = AST_FORMAT_SLINEAR16,
.src = "console_stream_monitor",
.data.ptr = buf,
.datalen = sizeof(buf),
.samples = sizeof(buf) / sizeof(int16_t),
};
ast_format_set(&f.subclass.format, AST_FORMAT_SLINEAR16, 0);
for (;;) {
pthread_testcancel();
@ -424,9 +418,9 @@ static struct ast_channel *console_new(struct console_pvt *pvt, const char *ext,
}
chan->tech = &console_tech;
chan->nativeformats = AST_FORMAT_SLINEAR16;
chan->readformat = AST_FORMAT_SLINEAR16;
chan->writeformat = AST_FORMAT_SLINEAR16;
ast_format_set(&chan->readformat, AST_FORMAT_SLINEAR16, 0);
ast_format_set(&chan->writeformat, AST_FORMAT_SLINEAR16, 0);
ast_format_cap_add(chan->nativeformats, &chan->readformat);
chan->tech_pvt = ref_pvt(pvt);
pvt->owner = chan;
@ -448,9 +442,8 @@ static struct ast_channel *console_new(struct console_pvt *pvt, const char *ext,
return chan;
}
static struct ast_channel *console_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause)
static struct ast_channel *console_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, void *data, int *cause)
{
format_t oldformat = format;
struct ast_channel *chan = NULL;
struct console_pvt *pvt;
char buf[512];
@ -460,9 +453,8 @@ static struct ast_channel *console_request(const char *type, format_t format, co
return NULL;
}
format &= SUPPORTED_FORMATS;
if (!format) {
ast_log(LOG_NOTICE, "Channel requested with unsupported format(s): '%s'\n", ast_getformatname_multiple(buf, sizeof(buf), oldformat));
if (!(ast_format_cap_has_joint(cap, console_tech.capabilities))) {
ast_log(LOG_NOTICE, "Channel requested with unsupported format(s): '%s'\n", ast_getformatname_multiple(buf, sizeof(buf), cap));
goto return_unref;
}
@ -1457,6 +1449,7 @@ static void stop_streams(void)
static int unload_module(void)
{
console_tech.capabilities = ast_format_cap_destroy(console_tech.capabilities);
ast_channel_unregister(&console_tech);
ast_cli_unregister_multiple(cli_console, ARRAY_LEN(cli_console));
@ -1474,8 +1467,14 @@ static int unload_module(void)
static int load_module(void)
{
struct ast_format tmpfmt;
PaError res;
if (!(console_tech.capabilities = ast_format_cap_alloc())) {
return AST_MODULE_LOAD_DECLINE;
}
ast_format_cap_add(console_tech.capabilities, ast_format_set(&tmpfmt, AST_FORMAT_SLINEAR16, 0));
init_pvt(&globals, NULL);
if (!(pvts = ao2_container_alloc(NUM_PVT_BUCKETS, pvt_hash_cb, pvt_cmp_cb)))

View File

@ -1471,7 +1471,7 @@ static struct dahdi_chan_conf dahdi_chan_conf_default(void)
}
static struct ast_channel *dahdi_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause);
static struct ast_channel *dahdi_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, void *data, int *cause);
static int dahdi_digit_begin(struct ast_channel *ast, char digit);
static int dahdi_digit_end(struct ast_channel *ast, char digit, unsigned int duration);
static int dahdi_sendtext(struct ast_channel *c, const char *text);
@ -1490,10 +1490,9 @@ static int dahdi_func_write(struct ast_channel *chan, const char *function, char
static int dahdi_devicestate(void *data);
static int dahdi_cc_callback(struct ast_channel *inbound, const char *dest, ast_cc_callback_fn callback);
static const struct ast_channel_tech dahdi_tech = {
static struct ast_channel_tech dahdi_tech = {
.type = "DAHDI",
.description = tdesc,
.capabilities = AST_FORMAT_SLINEAR | AST_FORMAT_ULAW | AST_FORMAT_ALAW,
.requester = dahdi_request,
.send_digit_begin = dahdi_digit_begin,
.send_digit_end = dahdi_digit_end,
@ -1679,6 +1678,7 @@ static int my_get_callerid(void *pvt, char *namebuf, char *numbuf, enum analog_e
int res;
unsigned char buf[256];
int flags;
struct ast_format tmpfmt;
poller.fd = p->subs[SUB_REAL].dfd;
poller.events = POLLPRI | POLLIN;
@ -1714,9 +1714,9 @@ static int my_get_callerid(void *pvt, char *namebuf, char *numbuf, enum analog_e
}
if (p->cid_signalling == CID_SIG_V23_JP) {
res = callerid_feed_jp(p->cs, buf, res, AST_LAW(p));
res = callerid_feed_jp(p->cs, buf, res, ast_format_set(&tmpfmt, AST_LAW(p), 0));
} else {
res = callerid_feed(p->cs, buf, res, AST_LAW(p));
res = callerid_feed(p->cs, buf, res, ast_format_set(&tmpfmt, AST_LAW(p), 0));
}
if (res < 0) {
/*
@ -1885,6 +1885,7 @@ static int restore_conference(struct dahdi_pvt *p);
static int my_callwait(void *pvt)
{
struct dahdi_pvt *p = pvt;
struct ast_format tmpfmt;
p->callwaitingrepeat = CALLWAITING_REPEAT_SAMPLES;
if (p->cidspill) {
ast_log(LOG_WARNING, "Spill already exists?!?\n");
@ -1901,11 +1902,11 @@ static int my_callwait(void *pvt)
/* Silence */
memset(p->cidspill, 0x7f, 2400 + 600 + READ_SIZE * 4);
if (!p->callwaitrings && p->callwaitingcallerid) {
ast_gen_cas(p->cidspill, 1, 2400 + 680, AST_LAW(p));
ast_gen_cas(p->cidspill, 1, 2400 + 680, ast_format_set(&tmpfmt, AST_LAW(p), 0));
p->callwaitcas = 1;
p->cidlen = 2400 + 680 + READ_SIZE * 4;
} else {
ast_gen_cas(p->cidspill, 1, 2400, AST_LAW(p));
ast_gen_cas(p->cidspill, 1, 2400, ast_format_set(&tmpfmt, AST_LAW(p), 0));
p->callwaitcas = 0;
p->cidlen = 2400 + READ_SIZE * 4;
}
@ -1918,6 +1919,7 @@ static int my_callwait(void *pvt)
static int my_send_callerid(void *pvt, int cwcid, struct ast_party_caller *caller)
{
struct dahdi_pvt *p = pvt;
struct ast_format tmpfmt;
ast_debug(2, "Starting cid spill\n");
@ -1931,7 +1933,7 @@ static int my_send_callerid(void *pvt, int cwcid, struct ast_party_caller *calle
p->cidlen = ast_callerid_generate(p->cidspill,
caller->id.name.str,
caller->id.number.str,
AST_LAW(p));
ast_format_set(&tmpfmt, AST_LAW(p), 0));
} else {
ast_verb(3, "CPE supports Call Waiting Caller*ID. Sending '%s/%s'\n",
caller->id.name.str, caller->id.number.str);
@ -1940,7 +1942,7 @@ static int my_send_callerid(void *pvt, int cwcid, struct ast_party_caller *calle
p->cidlen = ast_callerid_callwaiting_generate(p->cidspill,
caller->id.name.str,
caller->id.number.str,
AST_LAW(p));
ast_format_set(&tmpfmt, AST_LAW(p), 0));
p->cidlen += READ_SIZE * 4;
}
p->cidpos = 0;
@ -5106,12 +5108,14 @@ static int restore_conference(struct dahdi_pvt *p)
static int send_cwcidspill(struct dahdi_pvt *p)
{
struct ast_format tmpfmt;
p->callwaitcas = 0;
p->cidcwexpire = 0;
p->cid_suppress_expire = 0;
if (!(p->cidspill = ast_malloc(MAX_CALLERID_SIZE)))
return -1;
p->cidlen = ast_callerid_callwaiting_generate(p->cidspill, p->callwait_name, p->callwait_num, AST_LAW(p));
p->cidlen = ast_callerid_callwaiting_generate(p->cidspill, p->callwait_name, p->callwait_num, ast_format_set(&tmpfmt, AST_LAW(p), 0));
/* Make sure we account for the end */
p->cidlen += READ_SIZE * 4;
p->cidpos = 0;
@ -5186,6 +5190,7 @@ static int send_callerid(struct dahdi_pvt *p)
static int dahdi_callwait(struct ast_channel *ast)
{
struct dahdi_pvt *p = ast->tech_pvt;
struct ast_format tmpfmt;
p->callwaitingrepeat = CALLWAITING_REPEAT_SAMPLES;
if (p->cidspill) {
ast_log(LOG_WARNING, "Spill already exists?!?\n");
@ -5202,11 +5207,11 @@ static int dahdi_callwait(struct ast_channel *ast)
/* Silence */
memset(p->cidspill, 0x7f, 2400 + 600 + READ_SIZE * 4);
if (!p->callwaitrings && p->callwaitingcallerid) {
ast_gen_cas(p->cidspill, 1, 2400 + 680, AST_LAW(p));
ast_gen_cas(p->cidspill, 1, 2400 + 680, ast_format_set(&tmpfmt, AST_LAW(p), 0));
p->callwaitcas = 1;
p->cidlen = 2400 + 680 + READ_SIZE * 4;
} else {
ast_gen_cas(p->cidspill, 1, 2400, AST_LAW(p));
ast_gen_cas(p->cidspill, 1, 2400, ast_format_set(&tmpfmt, AST_LAW(p), 0));
p->callwaitcas = 0;
p->cidlen = 2400 + READ_SIZE * 4;
}
@ -8823,15 +8828,15 @@ static struct ast_frame *dahdi_read(struct ast_channel *ast)
return &p->subs[idx].f;
}
if (ast->rawreadformat == AST_FORMAT_SLINEAR) {
if (ast->rawreadformat.id == AST_FORMAT_SLINEAR) {
if (!p->subs[idx].linear) {
p->subs[idx].linear = 1;
res = dahdi_setlinear(p->subs[idx].dfd, p->subs[idx].linear);
if (res)
ast_log(LOG_WARNING, "Unable to set channel %d (index %d) to linear mode.\n", p->channel, idx);
}
} else if ((ast->rawreadformat == AST_FORMAT_ULAW) ||
(ast->rawreadformat == AST_FORMAT_ALAW)) {
} else if ((ast->rawreadformat.id == AST_FORMAT_ULAW) ||
(ast->rawreadformat.id == AST_FORMAT_ALAW)) {
if (p->subs[idx].linear) {
p->subs[idx].linear = 0;
res = dahdi_setlinear(p->subs[idx].dfd, p->subs[idx].linear);
@ -8839,7 +8844,7 @@ static struct ast_frame *dahdi_read(struct ast_channel *ast)
ast_log(LOG_WARNING, "Unable to set channel %d (index %d) to companded mode.\n", p->channel, idx);
}
} else {
ast_log(LOG_WARNING, "Don't know how to read frames in format %s\n", ast_getformatname(ast->rawreadformat));
ast_log(LOG_WARNING, "Don't know how to read frames in format %s\n", ast_getformatname(&ast->rawreadformat));
ast_mutex_unlock(&p->lock);
return NULL;
}
@ -8931,7 +8936,7 @@ static struct ast_frame *dahdi_read(struct ast_channel *ast)
}
p->subs[idx].f.frametype = AST_FRAME_VOICE;
p->subs[idx].f.subclass.codec = ast->rawreadformat;
ast_format_copy(&p->subs[idx].f.subclass.format, &ast->rawreadformat);
p->subs[idx].f.samples = READ_SIZE;
p->subs[idx].f.mallocd = 0;
p->subs[idx].f.offset = AST_FRIENDLY_OFFSET;
@ -9101,10 +9106,10 @@ static int dahdi_write(struct ast_channel *ast, struct ast_frame *frame)
ast_log(LOG_WARNING, "Don't know what to do with frame type '%d'\n", frame->frametype);
return 0;
}
if ((frame->subclass.codec != AST_FORMAT_SLINEAR) &&
(frame->subclass.codec != AST_FORMAT_ULAW) &&
(frame->subclass.codec != AST_FORMAT_ALAW)) {
ast_log(LOG_WARNING, "Cannot handle frames in %s format\n", ast_getformatname(frame->subclass.codec));
if ((frame->subclass.format.id != AST_FORMAT_SLINEAR) &&
(frame->subclass.format.id != AST_FORMAT_ULAW) &&
(frame->subclass.format.id != AST_FORMAT_ALAW)) {
ast_log(LOG_WARNING, "Cannot handle frames in %s format\n", ast_getformatname(&frame->subclass.format));
return -1;
}
if (p->dialing) {
@ -9124,7 +9129,7 @@ static int dahdi_write(struct ast_channel *ast, struct ast_frame *frame)
if (!frame->data.ptr || !frame->datalen)
return 0;
if (frame->subclass.codec == AST_FORMAT_SLINEAR) {
if (frame->subclass.format.id == AST_FORMAT_SLINEAR) {
if (!p->subs[idx].linear) {
p->subs[idx].linear = 1;
res = dahdi_setlinear(p->subs[idx].dfd, p->subs[idx].linear);
@ -9316,7 +9321,7 @@ static struct ast_str *create_channel_name(struct dahdi_pvt *i)
static struct ast_channel *dahdi_new(struct dahdi_pvt *i, int state, int startpbx, int idx, int law, const char *linkedid)
{
struct ast_channel *tmp;
format_t deflaw;
struct ast_format deflaw;
int x;
int features;
struct ast_str *chan_name;
@ -9327,6 +9332,7 @@ static struct ast_channel *dahdi_new(struct dahdi_pvt *i, int state, int startpb
return NULL;
}
ast_format_clear(&deflaw);
#if defined(HAVE_PRI)
/*
* The dnid has been stuffed with the called-number[:subaddress]
@ -9354,9 +9360,9 @@ static struct ast_channel *dahdi_new(struct dahdi_pvt *i, int state, int startpb
if (law) {
i->law = law;
if (law == DAHDI_LAW_ALAW) {
deflaw = AST_FORMAT_ALAW;
ast_format_set(&deflaw, AST_FORMAT_ALAW, 0);
} else {
deflaw = AST_FORMAT_ULAW;
ast_format_set(&deflaw, AST_FORMAT_ULAW, 0);
}
} else {
switch (i->sig) {
@ -9370,18 +9376,18 @@ static struct ast_channel *dahdi_new(struct dahdi_pvt *i, int state, int startpb
break;
}
if (i->law_default == DAHDI_LAW_ALAW) {
deflaw = AST_FORMAT_ALAW;
ast_format_set(&deflaw, AST_FORMAT_ALAW, 0);
} else {
deflaw = AST_FORMAT_ULAW;
ast_format_set(&deflaw, AST_FORMAT_ULAW, 0);
}
}
ast_channel_set_fd(tmp, 0, i->subs[idx].dfd);
tmp->nativeformats = deflaw;
ast_format_cap_add(tmp->nativeformats, &deflaw);
/* Start out assuming ulaw since it's smaller :) */
tmp->rawreadformat = deflaw;
tmp->readformat = deflaw;
tmp->rawwriteformat = deflaw;
tmp->writeformat = deflaw;
ast_format_copy(&tmp->rawreadformat, &deflaw);
ast_format_copy(&tmp->readformat, &deflaw);
ast_format_copy(&tmp->rawwriteformat, &deflaw);
ast_format_copy(&tmp->writeformat, &deflaw);
i->subs[idx].linear = 0;
dahdi_setlinear(i->subs[idx].dfd, i->subs[idx].linear);
features = 0;
@ -9619,6 +9625,7 @@ static void *analog_ss_thread(void *data)
int len = 0;
int res;
int idx;
struct ast_format tmpfmt;
ast_mutex_lock(&ss_thread_lock);
ss_thread_count++;
@ -10279,9 +10286,9 @@ static void *analog_ss_thread(void *data)
samples += res;
if (p->cid_signalling == CID_SIG_V23_JP) {
res = callerid_feed_jp(cs, buf, res, AST_LAW(p));
res = callerid_feed_jp(cs, buf, res, ast_format_set(&tmpfmt, AST_LAW(p), 0));
} else {
res = callerid_feed(cs, buf, res, AST_LAW(p));
res = callerid_feed(cs, buf, res, ast_format_set(&tmpfmt, AST_LAW(p), 0));
}
if (res < 0) {
/*
@ -10550,7 +10557,7 @@ static void *analog_ss_thread(void *data)
}
}
samples += res;
res = callerid_feed(cs, buf, res, AST_LAW(p));
res = callerid_feed(cs, buf, res, ast_format_set(&tmpfmt, AST_LAW(p), 0));
if (res < 0) {
/*
* The previous diagnostic message output likely
@ -10718,7 +10725,7 @@ struct mwi_thread_data {
size_t len;
};
static int calc_energy(const unsigned char *buf, int len, format_t law)
static int calc_energy(const unsigned char *buf, int len, enum ast_format_id law)
{
int x;
int sum = 0;
@ -10743,6 +10750,7 @@ static void *mwi_thread(void *data)
int i, res;
unsigned int spill_done = 0;
int spill_result = -1;
struct ast_format tmpfmt;
if (!(cs = callerid_new(mtd->pvt->cid_signalling))) {
mtd->pvt->mwimonitoractive = 0;
@ -10750,7 +10758,7 @@ static void *mwi_thread(void *data)
return NULL;
}
callerid_feed(cs, mtd->buf, mtd->len, AST_LAW(mtd->pvt));
callerid_feed(cs, mtd->buf, mtd->len, ast_format_set(&tmpfmt, AST_LAW(mtd->pvt), 0));
bump_gains(mtd->pvt);
@ -10832,7 +10840,7 @@ static void *mwi_thread(void *data)
}
samples += res;
if (!spill_done) {
if ((spill_result = callerid_feed(cs, mtd->buf, res, AST_LAW(mtd->pvt))) < 0) {
if ((spill_result = callerid_feed(cs, mtd->buf, res, ast_format_set(&tmpfmt, AST_LAW(mtd->pvt), 0))) < 0) {
/*
* The previous diagnostic message output likely
* explains why it failed.
@ -10891,6 +10899,7 @@ quit_no_clean:
static int mwi_send_init(struct dahdi_pvt * pvt)
{
int x, res;
struct ast_format tmpfmt;
#ifdef HAVE_DAHDI_LINEREVERSE_VMWI
/* Determine how this spill is to be sent */
@ -10933,7 +10942,7 @@ static int mwi_send_init(struct dahdi_pvt * pvt)
if (pvt->mwisend_fsk) {
#endif
pvt->cidlen = ast_callerid_vmwi_generate(pvt->cidspill, has_voicemail(pvt), CID_MWI_TYPE_MDMF_FULL,
AST_LAW(pvt), pvt->cid_name, pvt->cid_num, 0);
ast_format_set(&tmpfmt, AST_LAW(pvt), 0), pvt->cid_name, pvt->cid_num, 0);
pvt->cidpos = 0;
#ifdef HAVE_DAHDI_LINEREVERSE_VMWI
}
@ -13295,7 +13304,7 @@ static struct dahdi_pvt *determine_starting_point(const char *data, struct dahdi
return p;
}
static struct ast_channel *dahdi_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause)
static struct ast_channel *dahdi_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, void *data, int *cause)
{
int callwait = 0;
struct dahdi_pvt *p;
@ -16285,6 +16294,8 @@ static int __unload_module(void)
}
#endif /* defined(HAVE_SS7) */
ast_cond_destroy(&ss_thread_complete);
dahdi_tech.capabilities = ast_format_cap_destroy(dahdi_tech.capabilities);
return 0;
}
@ -18034,10 +18045,18 @@ static const struct ast_data_entry dahdi_data_providers[] = {
static int load_module(void)
{
int res;
struct ast_format tmpfmt;
#if defined(HAVE_PRI) || defined(HAVE_SS7)
int y;
#endif /* defined(HAVE_PRI) || defined(HAVE_SS7) */
if (!(dahdi_tech.capabilities = ast_format_cap_alloc())) {
return AST_MODULE_LOAD_FAILURE;
}
ast_format_cap_add(dahdi_tech.capabilities, ast_format_set(&tmpfmt, AST_FORMAT_SLINEAR, 0));
ast_format_cap_add(dahdi_tech.capabilities, ast_format_set(&tmpfmt, AST_FORMAT_ULAW, 0));
ast_format_cap_add(dahdi_tech.capabilities, ast_format_set(&tmpfmt, AST_FORMAT_ALAW, 0));
#ifdef HAVE_PRI
memset(pris, 0, sizeof(pris));
for (y = 0; y < NUM_SPANS; y++) {
@ -18146,7 +18165,10 @@ static int dahdi_sendtext(struct ast_channel *c, const char *text)
return -1;
mybuf = buf;
if (p->mate) {
int codec = AST_LAW(p);
struct ast_format tmp;
/* PUT_CLI_MARKMS is a macro and requires a format ptr called codec to be present */
struct ast_format *codec = &tmp;
ast_format_set(codec, AST_LAW(p), 0);
for (x = 0; x < HEADER_MS; x++) { /* 50 ms of Mark */
PUT_CLID_MARKMS;
}

View File

@ -111,7 +111,6 @@ struct gtalk_pvt {
iksrule *ringrule; /*!< Rule for matching RING request */
int initiator; /*!< If we're the initiator */
int alreadygone;
int capability;
struct ast_codec_pref prefs;
struct gtalk_candidate *theircandidates;
struct gtalk_candidate *ourcandidates;
@ -121,8 +120,9 @@ struct gtalk_pvt {
struct ast_channel *owner; /*!< Master Channel */
struct ast_rtp_instance *rtp; /*!< RTP audio session */
struct ast_rtp_instance *vrtp; /*!< RTP video session */
format_t jointcapability; /*!< Supported capability at both ends (codecs ) */
format_t peercapability;
struct ast_format_cap *cap;
struct ast_format_cap *jointcap; /*!< Supported capability at both ends (codecs ) */
struct ast_format_cap *peercap;
struct gtalk_pvt *next; /* Next entity */
};
@ -152,7 +152,7 @@ struct gtalk {
char context[AST_MAX_CONTEXT];
char parkinglot[AST_MAX_CONTEXT]; /*!< Parkinglot */
char accountcode[AST_MAX_ACCOUNT_CODE]; /*!< Account code */
format_t capability;
struct ast_format_cap *cap;
ast_group_t callgroup; /*!< Call group */
ast_group_t pickupgroup; /*!< Pickup group */
int callingpres; /*!< Calling presentation */
@ -169,12 +169,12 @@ static const char desc[] = "Gtalk Channel";
static const char DEFAULT_CONTEXT[] = "default";
static const int DEFAULT_ALLOWGUEST = 1;
static format_t global_capability = AST_FORMAT_ULAW | AST_FORMAT_ALAW | AST_FORMAT_GSM | AST_FORMAT_H263;
static struct ast_format_cap *global_capability;
AST_MUTEX_DEFINE_STATIC(gtalklock); /*!< Protect the interface list (of gtalk_pvt's) */
/* Forward declarations */
static struct ast_channel *gtalk_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause);
static struct ast_channel *gtalk_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, void *data, int *cause);
/*static int gtalk_digit(struct ast_channel *ast, char digit, unsigned int duration);*/
static int gtalk_sendtext(struct ast_channel *ast, const char *text);
static int gtalk_digit_begin(struct ast_channel *ast, char digit);
@ -200,10 +200,9 @@ static int gtalk_parser(void *data, ikspak *pak);
static int gtalk_create_candidates(struct gtalk *client, struct gtalk_pvt *p, char *sid, char *from, char *to);
/*! \brief PBX interface structure for channel registration */
static const struct ast_channel_tech gtalk_tech = {
static struct ast_channel_tech gtalk_tech = {
.type = "Gtalk",
.description = "Gtalk Channel Driver",
.capabilities = AST_FORMAT_AUDIO_MASK,
.requester = gtalk_request,
.send_text = gtalk_sendtext,
.send_digit_begin = gtalk_digit_begin,
@ -247,6 +246,7 @@ static struct gtalk_container gtalk_list;
static void gtalk_member_destroy(struct gtalk *obj)
{
obj->cap = ast_format_cap_destroy(obj->cap);
ast_free(obj);
}
@ -282,7 +282,7 @@ static struct gtalk *find_gtalk(char *name, char *connection)
}
static int add_codec_to_answer(const struct gtalk_pvt *p, int codec, iks *dcodecs)
static int add_codec_to_answer(const struct gtalk_pvt *p, struct ast_format *codec, iks *dcodecs)
{
int res = 0;
char *format = ast_getformatname(codec);
@ -392,17 +392,17 @@ static int gtalk_invite(struct gtalk_pvt *p, char *to, char *from, char *sid, in
struct gtalk *client = p->parent;
iks *iq, *gtalk, *dcodecs, *payload_telephone, *transport;
int x;
int pref_codec = 0;
int alreadysent = 0;
struct ast_format_cap *alreadysent;
int codecs_num = 0;
char *lowerto = NULL;
struct ast_format tmpfmt;
iq = iks_new("iq");
gtalk = iks_new("session");
dcodecs = iks_new("description");
transport = iks_new("transport");
payload_telephone = iks_new("payload-type");
if (!(iq && gtalk && dcodecs && transport && payload_telephone)){
if (!(iq && gtalk && dcodecs && transport && payload_telephone)) {
iks_delete(iq);
iks_delete(gtalk);
iks_delete(dcodecs);
@ -415,16 +415,23 @@ static int gtalk_invite(struct gtalk_pvt *p, char *to, char *from, char *sid, in
iks_insert_attrib(dcodecs, "xmlns", GOOGLE_AUDIO_NS);
iks_insert_attrib(dcodecs, "xml:lang", "en");
for (x = 0; x < 64; x++) {
if (!(pref_codec = ast_codec_pref_index(&client->prefs, x)))
break;
if (!(client->capability & pref_codec))
continue;
if (alreadysent & pref_codec)
continue;
codecs_num = add_codec_to_answer(p, pref_codec, dcodecs);
alreadysent |= pref_codec;
if (!(alreadysent = ast_format_cap_alloc_nolock())) {
return 0;
}
for (x = 0; x < AST_CODEC_PREF_SIZE; x++) {
if (!(ast_codec_pref_index(&client->prefs, x, &tmpfmt))) {
break;
}
if (!(ast_format_cap_iscompatible(client->cap, &tmpfmt))) {
continue;
}
if (ast_format_cap_iscompatible(alreadysent, &tmpfmt)) {
continue;
}
codecs_num = add_codec_to_answer(p, &tmpfmt, dcodecs);
ast_format_cap_add(alreadysent, &tmpfmt);
}
alreadysent = ast_format_cap_destroy(alreadysent);
if (codecs_num) {
/* only propose DTMF within an audio session */
@ -544,13 +551,15 @@ static enum ast_rtp_glue_result gtalk_get_rtp_peer(struct ast_channel *chan, str
return res;
}
static format_t gtalk_get_codec(struct ast_channel *chan)
static void gtalk_get_codec(struct ast_channel *chan, struct ast_format_cap *result)
{
struct gtalk_pvt *p = chan->tech_pvt;
return p->peercapability;
ast_mutex_lock(&p->lock);
ast_format_cap_copy(result, p->peercap);
ast_mutex_unlock(&p->lock);
}
static int gtalk_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 gtalk_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)
{
struct gtalk_pvt *p;
@ -658,15 +667,15 @@ static int gtalk_is_answered(struct gtalk *client, ikspak *pak)
}
/* Now gather all of the codecs that we are asked for */
ast_rtp_codecs_payload_formats(ast_rtp_instance_get_codecs(tmp->rtp), &tmp->peercapability, &peernoncodeccapability);
ast_rtp_codecs_payload_formats(ast_rtp_instance_get_codecs(tmp->rtp), tmp->peercap, &peernoncodeccapability);
/* at this point, we received an awser from the remote Gtalk client,
/* at this point, we received an answer from the remote Gtalk client,
which allows us to compare capabilities */
tmp->jointcapability = tmp->capability & tmp->peercapability;
if (!tmp->jointcapability) {
ast_log(LOG_WARNING, "Capabilities don't match : us - %s, peer - %s, combined - %s \n", ast_getformatname_multiple(s1, BUFSIZ, tmp->capability),
ast_getformatname_multiple(s2, BUFSIZ, tmp->peercapability),
ast_getformatname_multiple(s3, BUFSIZ, tmp->jointcapability));
ast_format_cap_joint_copy(tmp->cap, tmp->peercap, tmp->jointcap);
if (ast_format_cap_is_empty(tmp->jointcap)) {
ast_log(LOG_WARNING, "Capabilities don't match : us - %s, peer - %s, combined - %s \n", ast_getformatname_multiple(s1, BUFSIZ, tmp->cap),
ast_getformatname_multiple(s2, BUFSIZ, tmp->peercap),
ast_getformatname_multiple(s3, BUFSIZ, tmp->jointcap));
/* close session if capabilities don't match */
ast_queue_hangup(tmp->owner);
@ -1018,6 +1027,16 @@ static struct gtalk_pvt *gtalk_alloc(struct gtalk *client, const char *us, const
if (!(tmp = ast_calloc(1, sizeof(*tmp)))) {
return NULL;
}
tmp->cap = ast_format_cap_alloc_nolock();
tmp->jointcap = ast_format_cap_alloc_nolock();
tmp->peercap = ast_format_cap_alloc_nolock();
if (!tmp->jointcap || !tmp->peercap || !tmp->cap) {
tmp->cap = ast_format_cap_destroy(tmp->cap);
tmp->jointcap = ast_format_cap_destroy(tmp->jointcap);
tmp->peercap = ast_format_cap_destroy(tmp->peercap);
ast_free(tmp);
return NULL;
}
memcpy(&tmp->prefs, &client->prefs, sizeof(struct ast_codec_pref));
@ -1046,10 +1065,10 @@ static struct gtalk_pvt *gtalk_alloc(struct gtalk *client, const char *us, const
ast_rtp_codecs_payloads_clear(ast_rtp_instance_get_codecs(tmp->rtp), tmp->rtp);
/* add user configured codec capabilites */
if (client->capability) {
tmp->capability = client->capability;
} else if (global_capability) {
tmp->capability = global_capability;
if (!(ast_format_cap_is_empty(client->cap))) {
ast_format_cap_copy(tmp->cap, client->cap);
} else if (!(ast_format_cap_is_empty(global_capability))) {
ast_format_cap_copy(tmp->cap, global_capability);
}
tmp->parent = client;
@ -1081,9 +1100,9 @@ static struct gtalk_pvt *gtalk_alloc(struct gtalk *client, const char *us, const
static struct ast_channel *gtalk_new(struct gtalk *client, struct gtalk_pvt *i, int state, const char *title, const char *linkedid)
{
struct ast_channel *tmp;
int fmt;
int what;
const char *n2;
struct ast_format_cap *what; /* used as SHALLOW COPY DO NOT DESTROY */
struct ast_format tmpfmt;
if (title)
n2 = title;
@ -1098,20 +1117,29 @@ static struct ast_channel *gtalk_new(struct gtalk *client, struct gtalk_pvt *i,
/* Select our native format based on codec preference until we receive
something from another device to the contrary. */
if (i->jointcapability)
what = i->jointcapability;
else if (i->capability)
what = i->capability;
else
if (!(ast_format_cap_is_empty(i->jointcap))) {
what = i->jointcap;
} else if (i->cap) {
what = i->cap;
} else {
what = global_capability;
}
/* Set Frame packetization */
if (i->rtp) {
ast_rtp_codecs_packetization_set(ast_rtp_instance_get_codecs(i->rtp), i->rtp, &i->prefs);
}
tmp->nativeformats = ast_codec_choose(&i->prefs, what, 1) | (i->jointcapability & AST_FORMAT_VIDEO_MASK);
fmt = ast_best_codec(tmp->nativeformats);
ast_codec_choose(&i->prefs, what, 1, &tmpfmt);
ast_format_cap_add(tmp->nativeformats, &tmpfmt);
ast_format_cap_iter_start(i->jointcap);
while (!(ast_format_cap_iter_next(i->jointcap, &tmpfmt))) {
if (AST_FORMAT_GET_TYPE(tmpfmt.id) == AST_FORMAT_TYPE_VIDEO) {
ast_format_cap_add(tmp->nativeformats, &tmpfmt);
}
}
ast_format_cap_iter_end(i->jointcap);
if (i->rtp) {
ast_channel_set_fd(tmp, 0, ast_rtp_instance_fd(i->rtp, 0));
@ -1124,10 +1152,12 @@ static struct ast_channel *gtalk_new(struct gtalk *client, struct gtalk_pvt *i,
if (state == AST_STATE_RING)
tmp->rings = 1;
tmp->adsicpe = AST_ADSI_UNAVAILABLE;
tmp->writeformat = fmt;
tmp->rawwriteformat = fmt;
tmp->readformat = fmt;
tmp->rawreadformat = fmt;
ast_best_codec(tmp->nativeformats, &tmpfmt);
ast_format_copy(&tmp->writeformat, &tmpfmt);
ast_format_copy(&tmp->rawwriteformat, &tmpfmt);
ast_format_copy(&tmp->readformat, &tmpfmt);
ast_format_copy(&tmp->rawreadformat, &tmpfmt);
tmp->tech_pvt = i;
tmp->callgroup = client->callgroup;
@ -1240,6 +1270,9 @@ static void gtalk_free_pvt(struct gtalk *client, struct gtalk_pvt *p)
if (p->vrtp)
ast_rtp_instance_destroy(p->vrtp);
gtalk_free_candidates(p->theircandidates);
p->cap = ast_format_cap_destroy(p->cap);
p->jointcap = ast_format_cap_destroy(p->jointcap);
p->peercap = ast_format_cap_destroy(p->peercap);
ast_free(p);
}
@ -1341,15 +1374,15 @@ static int gtalk_newcall(struct gtalk *client, ikspak *pak)
}
/* Now gather all of the codecs that we are asked for */
ast_rtp_codecs_payload_formats(ast_rtp_instance_get_codecs(p->rtp), &p->peercapability, &peernoncodeccapability);
p->jointcapability = p->capability & p->peercapability;
ast_rtp_codecs_payload_formats(ast_rtp_instance_get_codecs(p->rtp), p->peercap, &peernoncodeccapability);
ast_format_cap_joint_copy(p->cap, p->peercap, p->jointcap);
ast_mutex_unlock(&p->lock);
ast_setstate(chan, AST_STATE_RING);
if (!p->jointcapability) {
ast_log(LOG_WARNING, "Capabilities don't match : us - %s, peer - %s, combined - %s \n", ast_getformatname_multiple(s1, BUFSIZ, p->capability),
ast_getformatname_multiple(s2, BUFSIZ, p->peercapability),
ast_getformatname_multiple(s3, BUFSIZ, p->jointcapability));
if (ast_format_cap_is_empty(p->jointcap)) {
ast_log(LOG_WARNING, "Capabilities don't match : us - %s, peer - %s, combined - %s \n", ast_getformatname_multiple(s1, BUFSIZ, p->cap),
ast_getformatname_multiple(s2, BUFSIZ, p->peercap),
ast_getformatname_multiple(s3, BUFSIZ, p->jointcap));
/* close session if capabilities don't match */
gtalk_action(client, p, "reject");
p->alreadygone = 1;
@ -1572,12 +1605,12 @@ static struct ast_frame *gtalk_rtp_read(struct ast_channel *ast, struct gtalk_pv
if (p->owner) {
/* We already hold the channel lock */
if (f->frametype == AST_FRAME_VOICE) {
if (f->subclass.codec != (p->owner->nativeformats & AST_FORMAT_AUDIO_MASK)) {
ast_debug(1, "Oooh, format changed to %s\n", ast_getformatname(f->subclass.codec));
p->owner->nativeformats =
(p->owner->nativeformats & AST_FORMAT_VIDEO_MASK) | f->subclass.codec;
ast_set_read_format(p->owner, p->owner->readformat);
ast_set_write_format(p->owner, p->owner->writeformat);
if (!ast_format_cap_iscompatible(p->owner->nativeformats, &f->subclass.format)) {
ast_debug(1, "Oooh, format changed to %s\n", ast_getformatname(&f->subclass.format));
ast_format_cap_remove_bytype(p->owner->nativeformats, AST_FORMAT_TYPE_AUDIO);
ast_format_cap_add(p->owner->nativeformats, &f->subclass.format);
ast_set_read_format(p->owner, &p->owner->readformat);
ast_set_write_format(p->owner, &p->owner->writeformat);
}
/* if ((ast_test_flag(p, SIP_DTMF) == SIP_DTMF_INBAND) && p->vad) {
f = ast_dsp_process(p->owner, p->vad, f);
@ -1609,13 +1642,13 @@ static int gtalk_write(struct ast_channel *ast, struct ast_frame *frame)
switch (frame->frametype) {
case AST_FRAME_VOICE:
if (!(frame->subclass.codec & ast->nativeformats)) {
if (!(ast_format_cap_iscompatible(ast->nativeformats, &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(&frame->subclass.format),
ast_getformatname_multiple(buf, sizeof(buf), ast->nativeformats),
ast_getformatname(ast->readformat),
ast_getformatname(ast->writeformat));
ast_getformatname(&ast->readformat),
ast_getformatname(&ast->writeformat));
return 0;
}
if (p) {
@ -1845,7 +1878,7 @@ static int gtalk_hangup(struct ast_channel *ast)
}
/*!\brief Part of PBX interface */
static struct ast_channel *gtalk_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause)
static struct ast_channel *gtalk_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, void *data, int *cause)
{
struct gtalk_pvt *p = NULL;
struct gtalk *client = NULL;
@ -1937,8 +1970,8 @@ static char *gtalk_show_channels(struct ast_cli_entry *e, int cmd, struct ast_cl
chan->name,
jid,
resource,
ast_getformatname(chan->readformat),
ast_getformatname(chan->writeformat)
ast_getformatname(&chan->readformat),
ast_getformatname(&chan->writeformat)
);
else
ast_log(LOG_WARNING, "No available channel\n");
@ -2067,9 +2100,9 @@ static int gtalk_create_member(char *label, struct ast_variable *var, int allowg
if (!strcasecmp(var->name, "username"))
ast_copy_string(member->user, var->value, sizeof(member->user));
else if (!strcasecmp(var->name, "disallow"))
ast_parse_allow_disallow(&member->prefs, &member->capability, var->value, 0);
ast_parse_allow_disallow(&member->prefs, member->cap, var->value, 0);
else if (!strcasecmp(var->name, "allow"))
ast_parse_allow_disallow(&member->prefs, &member->capability, var->value, 1);
ast_parse_allow_disallow(&member->prefs, member->cap, var->value, 1);
else if (!strcasecmp(var->name, "context"))
ast_copy_string(member->context, var->value, sizeof(member->context));
else if (!strcasecmp(var->name, "parkinglot"))
@ -2122,6 +2155,7 @@ static int gtalk_load_config(void)
memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf));
/* set defaults */
memset(&prefs, 0, sizeof(prefs));
memset(&stunaddr, 0, sizeof(stunaddr));
global_stunaddr = 0;
global_allowguest = DEFAULT_ALLOWGUEST;
@ -2138,9 +2172,9 @@ static int gtalk_load_config(void)
if (!strcasecmp(var->name, "allowguest")) {
global_allowguest = (ast_true(ast_variable_retrieve(cfg, "general", "allowguest"))) ? 1 : 0;
} else if (!strcasecmp(var->name, "disallow")) {
ast_parse_allow_disallow(&prefs, &global_capability, var->value, 0);
ast_parse_allow_disallow(&prefs, global_capability, var->value, 0);
} else if (!strcasecmp(var->name, "allow")) {
ast_parse_allow_disallow(&prefs, &global_capability, var->value, 1);
ast_parse_allow_disallow(&prefs, global_capability, var->value, 1);
} else if (!strcasecmp(var->name, "context")) {
ast_copy_string(global_context, var->value, sizeof(global_context));
} else if (!strcasecmp(var->name, "externip")) {
@ -2167,6 +2201,7 @@ static int gtalk_load_config(void)
member = ast_calloc(1, sizeof(*member));
ASTOBJ_INIT(member);
ASTOBJ_WRLOCK(member);
member->cap = ast_format_cap_alloc_nolock();
if (!strcasecmp(cat, "guest")) {
ast_copy_string(member->name, "guest", sizeof(member->name));
ast_copy_string(member->user, "guest", sizeof(member->user));
@ -2176,10 +2211,10 @@ static int gtalk_load_config(void)
member->prefs = prefs;
while (var) {
if (!strcasecmp(var->name, "disallow")) {
ast_parse_allow_disallow(&member->prefs, &member->capability,
ast_parse_allow_disallow(&member->prefs, member->cap,
var->value, 0);
} else if (!strcasecmp(var->name, "allow")) {
ast_parse_allow_disallow(&member->prefs, &member->capability,
ast_parse_allow_disallow(&member->prefs, member->cap,
var->value, 1);
} else if (!strcasecmp(var->name, "context")) {
ast_copy_string(member->context, var->value,
@ -2229,8 +2264,22 @@ static int load_module(void)
{
struct ast_sockaddr bindaddr_tmp;
struct ast_sockaddr ourip_tmp;
char *jabber_loaded = ast_module_helper("", "res_jabber.so", 0, 0, 0, 0);
struct ast_format tmpfmt;
if (!(gtalk_tech.capabilities = ast_format_cap_alloc())) {
return AST_MODULE_LOAD_DECLINE;
}
if (!(global_capability = ast_format_cap_alloc())) {
return AST_MODULE_LOAD_DECLINE;
}
ast_format_cap_add_all_by_type(gtalk_tech.capabilities, AST_FORMAT_TYPE_AUDIO);
ast_format_cap_add(global_capability, ast_format_set(&tmpfmt, AST_FORMAT_ULAW, 0));
ast_format_cap_add(global_capability, ast_format_set(&tmpfmt, AST_FORMAT_GSM, 0));
ast_format_cap_add(global_capability, ast_format_set(&tmpfmt, AST_FORMAT_ALAW, 0));
ast_format_cap_add(global_capability, ast_format_set(&tmpfmt, AST_FORMAT_H263, 0));
free(jabber_loaded);
if (!jabber_loaded) {
/* If embedded, check for a different module name */
@ -2313,6 +2362,8 @@ static int unload_module(void)
}
ASTOBJ_CONTAINER_DESTROYALL(&gtalk_list, gtalk_member_destroy);
ASTOBJ_CONTAINER_DESTROY(&gtalk_list);
global_capability = ast_format_cap_destroy(global_capability);
gtalk_tech.capabilities = ast_format_cap_destroy(gtalk_tech.capabilities);
return 0;
}

View File

@ -85,6 +85,8 @@ extern "C" {
#include "asterisk/stringfields.h"
#include "asterisk/abstract_jb.h"
#include "asterisk/astobj.h"
#include "asterisk/format.h"
#include "asterisk/format_cap.h"
#ifdef __cplusplus
}
@ -129,7 +131,13 @@ static const char config[] = "h323.conf";
static char default_context[AST_MAX_CONTEXT] = "default";
static struct sockaddr_in bindaddr;
#define GLOBAL_CAPABILITY (AST_FORMAT_G723_1 | AST_FORMAT_GSM | AST_FORMAT_ULAW | AST_FORMAT_ALAW | AST_FORMAT_G729A | AST_FORMAT_G726_AAL2 | AST_FORMAT_H261)
#define GLOBAL_CAPABILITY (ast_format_id_to_old_bitfield(AST_FORMAT_G723_1) | \
ast_format_id_to_old_bitfield(AST_FORMAT_GSM) | \
ast_format_id_to_old_bitfield(AST_FORMAT_ULAW) | \
ast_format_id_to_old_bitfield(AST_FORMAT_ALAW) | \
ast_format_id_to_old_bitfield(AST_FORMAT_G729A) | \
ast_format_id_to_old_bitfield(AST_FORMAT_G726_AAL2) | \
ast_format_id_to_old_bitfield(AST_FORMAT_H261)) \
/** H.323 configuration values */
static int h323_signalling_port = 1720;
@ -173,9 +181,9 @@ static struct oh323_pvt {
int newcontrol; /*!< Pending control to send */
int newdigit; /*!< Pending DTMF digit to send */
int newduration; /*!< Pending DTMF digit duration to send */
format_t pref_codec; /*!< Preferred codec */
format_t peercapability; /*!< Capabilities learned from peer */
format_t jointcapability; /*!< Common capabilities for local and remote side */
h323_format pref_codec; /*!< Preferred codec */
h323_format peercapability; /*!< Capabilities learned from peer */
h323_format jointcapability; /*!< Common capabilities for local and remote side */
struct ast_codec_pref peer_prefs; /*!< Preferenced list of codecs which remote side supports */
int dtmf_pt[2]; /*!< Payload code used for RFC2833/CISCO messages */
int curDTMF; /*!< DTMF tone being generated to Asterisk side */
@ -231,7 +239,7 @@ static void delete_users(void);
static void delete_aliases(void);
static void prune_peers(void);
static struct ast_channel *oh323_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause);
static struct ast_channel *oh323_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, void *data, int *cause);
static int oh323_digit_begin(struct ast_channel *c, char digit);
static int oh323_digit_end(struct ast_channel *c, char digit, unsigned int duration);
static int oh323_call(struct ast_channel *c, char *dest, int timeout);
@ -242,10 +250,9 @@ static int oh323_write(struct ast_channel *c, struct ast_frame *frame);
static int oh323_indicate(struct ast_channel *c, int condition, const void *data, size_t datalen);
static int oh323_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
static const struct ast_channel_tech oh323_tech = {
static struct ast_channel_tech oh323_tech = {
.type = "H323",
.description = tdesc,
.capabilities = AST_FORMAT_AUDIO_MASK,
.properties = AST_CHAN_TP_WANTSJITTER | AST_CHAN_TP_CREATESJITTER,
.requester = oh323_request,
.send_digit_begin = oh323_digit_begin,
@ -331,12 +338,13 @@ static int oh323_simulate_dtmf_end(const void *data)
/*! \brief Channel and private structures should be already locked */
static void __oh323_update_info(struct ast_channel *c, struct oh323_pvt *pvt)
{
if (c->nativeformats != pvt->nativeformats) {
h323_format chan_nativeformats_bits = ast_format_cap_to_old_bitfield(c->nativeformats);
if (chan_nativeformats_bits != pvt->nativeformats) {
if (h323debug)
ast_debug(1, "Preparing %s for new native format\n", c->name);
c->nativeformats = pvt->nativeformats;
ast_set_read_format(c, c->readformat);
ast_set_write_format(c, c->writeformat);
ast_format_cap_from_old_bitfield(c->nativeformats, pvt->nativeformats);
ast_set_read_format(c, &c->readformat);
ast_set_write_format(c, &c->writeformat);
}
if (pvt->needhangup) {
if (h323debug)
@ -764,18 +772,20 @@ static struct ast_frame *oh323_rtp_read(struct oh323_pvt *pvt)
if (pvt->owner) {
/* We already hold the channel lock */
if (f->frametype == AST_FRAME_VOICE) {
if (f->subclass.codec != pvt->owner->nativeformats) {
if (!ast_format_cap_iscompatible(pvt->owner->nativeformats, &f->subclass.format)) {
/* Try to avoid deadlock */
if (ast_channel_trylock(pvt->owner)) {
ast_log(LOG_NOTICE, "Format changed but channel is locked. Ignoring frame...\n");
return &ast_null_frame;
}
if (h323debug)
ast_debug(1, "Oooh, format changed to '%s'\n", ast_getformatname(f->subclass.codec));
pvt->owner->nativeformats = f->subclass.codec;
pvt->nativeformats = f->subclass.codec;
ast_set_read_format(pvt->owner, pvt->owner->readformat);
ast_set_write_format(pvt->owner, pvt->owner->writeformat);
ast_debug(1, "Oooh, format changed to '%s'\n", ast_getformatname(&f->subclass.format));
ast_format_cap_set(pvt->owner->nativeformats, &f->subclass.format);
pvt->nativeformats = ast_format_to_old_bitfield(&f->subclass.format);
ast_set_read_format(pvt->owner, &pvt->owner->readformat);
ast_set_write_format(pvt->owner, &pvt->owner->writeformat);
ast_channel_unlock(pvt->owner);
}
/* Do in-band DTMF detection */
@ -788,7 +798,7 @@ static struct ast_frame *oh323_rtp_read(struct oh323_pvt *pvt)
else
ast_log(LOG_NOTICE, "Unable to process inband DTMF while channel is locked\n");
} else if (pvt->nativeformats && !pvt->noInbandDtmf) {
ast_log(LOG_NOTICE, "Inband DTMF is not supported on codec %s. Use RFC2833\n", ast_getformatname(f->subclass.codec));
ast_log(LOG_NOTICE, "Inband DTMF is not supported on codec %s. Use RFC2833\n", ast_getformatname(&f->subclass.format));
pvt->noInbandDtmf = 1;
}
if (f &&(f->frametype == AST_FRAME_DTMF)) {
@ -838,10 +848,10 @@ static int oh323_write(struct ast_channel *c, struct ast_frame *frame)
return 0;
}
} else {
if (!(frame->subclass.codec & c->nativeformats)) {
if (!(ast_format_cap_iscompatible(c->nativeformats, &frame->subclass.format))) {
char tmp[256];
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(tmp, sizeof(tmp), c->nativeformats), ast_getformatname(c->readformat), ast_getformatname(c->writeformat));
ast_getformatname(&frame->subclass.format), ast_getformatname_multiple(tmp, sizeof(tmp), c->nativeformats), ast_getformatname(&c->readformat), ast_getformatname(&c->writeformat));
return 0;
}
}
@ -1011,7 +1021,8 @@ static struct ast_channel *__oh323_new(struct oh323_pvt *pvt, int state, const c
{
struct ast_channel *ch;
char *cid_num, *cid_name;
int fmt;
h323_format fmt;
struct ast_format tmpfmt;
if (!ast_strlen_zero(pvt->options.cid_num))
cid_num = pvt->options.cid_num;
@ -1033,13 +1044,18 @@ static struct ast_channel *__oh323_new(struct oh323_pvt *pvt, int state, const c
ch->tech = &oh323_tech;
if (!(fmt = pvt->jointcapability) && !(fmt = pvt->options.capability))
fmt = global_options.capability;
ch->nativeformats = ast_codec_choose(&pvt->options.prefs, fmt, 1)/* | (pvt->jointcapability & AST_FORMAT_VIDEO_MASK)*/;
pvt->nativeformats = ch->nativeformats;
fmt = ast_best_codec(ch->nativeformats);
ch->writeformat = fmt;
ch->rawwriteformat = fmt;
ch->readformat = fmt;
ch->rawreadformat = fmt;
ast_format_cap_from_old_bitfield(ch->nativeformats, fmt);
ast_codec_choose(&pvt->options.prefs, ch->nativeformats, 1, &tmpfmt)/* | (pvt->jointcapability & AST_FORMAT_VIDEO_MASK)*/;
ast_format_cap_set(ch->nativeformats, &tmpfmt);
pvt->nativeformats = ast_format_cap_to_old_bitfield(ch->nativeformats);
ast_best_codec(ch->nativeformats, &tmpfmt);
ast_format_copy(&ch->writeformat, &tmpfmt);
ast_format_copy(&ch->rawwriteformat, &tmpfmt);
ast_format_copy(&ch->readformat, &tmpfmt);
ast_format_copy(&ch->rawreadformat, &tmpfmt);
if (!pvt->rtp)
__oh323_rtp_create(pvt);
#if 0
@ -1264,17 +1280,33 @@ static struct oh323_alias *realtime_alias(const char *alias)
return a;
}
static int h323_parse_allow_disallow(struct ast_codec_pref *pref, h323_format *formats, const char *list, int allowing)
{
int res;
struct ast_format_cap *cap = ast_format_cap_alloc_nolock();
if (!cap) {
return 1;
}
ast_format_cap_from_old_bitfield(cap, *formats);
res = ast_parse_allow_disallow(pref, cap, list, allowing);
*formats = ast_format_cap_to_old_bitfield(cap);
cap = ast_format_cap_destroy(cap);
return res;
}
static int update_common_options(struct ast_variable *v, struct call_options *options)
{
int tmp = 0;
char *val, *opt;
if (!strcasecmp(v->name, "allow")) {
ast_parse_allow_disallow(&options->prefs, &options->capability, v->value, 1);
h323_parse_allow_disallow(&options->prefs, &options->capability, v->value, 1);
} else if (!strcasecmp(v->name, "autoframing")) {
options->autoframing = ast_true(v->value);
} else if (!strcasecmp(v->name, "disallow")) {
ast_parse_allow_disallow(&options->prefs, &options->capability, v->value, 0);
h323_parse_allow_disallow(&options->prefs, &options->capability, v->value, 0);
} else if (!strcasecmp(v->name, "dtmfmode")) {
val = ast_strdupa(v->value);
if ((opt = strchr(val, ':')) != (char *)NULL) {
@ -1745,9 +1777,8 @@ static int create_addr(struct oh323_pvt *pvt, char *opeer)
return 0;
}
}
static struct ast_channel *oh323_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause)
static struct ast_channel *oh323_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, void *data, int *cause)
{
format_t oldformat;
struct oh323_pvt *pvt;
struct ast_channel *tmpc = NULL;
char *dest = (char *)data;
@ -1756,17 +1787,15 @@ static struct ast_channel *oh323_request(const char *type, format_t format, cons
char tmp[256], tmp1[256];
if (h323debug)
ast_debug(1, "type=%s, format=%s, data=%s.\n", type, ast_getformatname_multiple(tmp, sizeof(tmp), format), (char *)data);
ast_debug(1, "type=%s, format=%s, data=%s.\n", type, ast_getformatname_multiple(tmp, sizeof(tmp), cap), (char *)data);
pvt = oh323_alloc(0);
if (!pvt) {
ast_log(LOG_WARNING, "Unable to build pvt data for '%s'\n", (char *)data);
return NULL;
}
oldformat = format;
format &= AST_FORMAT_AUDIO_MASK;
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_type(cap, AST_FORMAT_TYPE_AUDIO))) {
ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format '%s'\n", ast_getformatname_multiple(tmp, sizeof(tmp), cap));
oh323_destroy(pvt);
if (cause)
*cause = AST_CAUSE_INCOMPATIBLE_DESTINATION;
@ -2020,11 +2049,11 @@ static void setup_rtp_connection(unsigned call_reference, const char *remoteIp,
nativeformats_changed = 0;
if (pt != 128 && pvt->rtp) { /* Payload type is invalid, so try to use previously decided */
struct ast_rtp_payload_type rtptype = ast_rtp_codecs_payload_lookup(ast_rtp_instance_get_codecs(pvt->rtp), pt);
if (h323debug)
ast_debug(1, "Native format is set to %llu from %d by RTP payload type %d\n", (unsigned long long) rtptype.code, pvt->nativeformats, pt);
if (pvt->nativeformats != rtptype.code) {
pvt->nativeformats = rtptype.code;
nativeformats_changed = 1;
if (rtptype.asterisk_format) {
if (pvt->nativeformats != ast_format_to_old_bitfield(&rtptype.format)) {
pvt->nativeformats = ast_format_to_old_bitfield(&rtptype.format);
nativeformats_changed = 1;
}
}
} else if (h323debug)
ast_log(LOG_NOTICE, "Payload type is unknown, formats isn't changed\n");
@ -2032,15 +2061,18 @@ static void setup_rtp_connection(unsigned call_reference, const char *remoteIp,
/* Don't try to lock the channel if nothing changed */
if (nativeformats_changed || pvt->options.progress_audio || (rtp_change != NEED_NONE)) {
if (pvt->owner && !ast_channel_trylock(pvt->owner)) {
struct ast_format_cap *pvt_native = ast_format_cap_alloc_nolock();
ast_format_cap_from_old_bitfield(pvt_native, pvt->nativeformats);
/* Re-build translation path only if native format(s) has been changed */
if (pvt->owner->nativeformats != pvt->nativeformats) {
if (!(ast_format_cap_identical(pvt->owner->nativeformats, pvt_native))) {
if (h323debug) {
char tmp[256], tmp2[256];
ast_debug(1, "Native format changed to '%s' from '%s', read format is %s, write format is %s\n", ast_getformatname_multiple(tmp, sizeof(tmp), pvt->nativeformats), ast_getformatname_multiple(tmp2, sizeof(tmp2), pvt->owner->nativeformats), ast_getformatname(pvt->owner->readformat), ast_getformatname(pvt->owner->writeformat));
ast_debug(1, "Native format changed to '%s' from '%s', read format is %s, write format is %s\n", ast_getformatname_multiple(tmp, sizeof(tmp), pvt_native), ast_getformatname_multiple(tmp2, sizeof(tmp2), pvt->owner->nativeformats), ast_getformatname(&pvt->owner->readformat), ast_getformatname(&pvt->owner->writeformat));
}
pvt->owner->nativeformats = pvt->nativeformats;
ast_set_read_format(pvt->owner, pvt->owner->readformat);
ast_set_write_format(pvt->owner, pvt->owner->writeformat);
ast_format_cap_copy(pvt->owner->nativeformats, pvt_native);
ast_set_read_format(pvt->owner, &pvt->owner->readformat);
ast_set_write_format(pvt->owner, &pvt->owner->writeformat);
}
if (pvt->options.progress_audio)
ast_queue_control(pvt->owner, AST_CONTROL_PROGRESS);
@ -2055,6 +2087,7 @@ static void setup_rtp_connection(unsigned call_reference, const char *remoteIp,
break;
}
ast_channel_unlock(pvt->owner);
pvt_native = ast_format_cap_destroy(pvt_native);
}
else {
if (pvt->options.progress_audio)
@ -2491,7 +2524,7 @@ static void set_peer_capabilities(unsigned call_reference, const char *token, in
for (i = 0; i < 32; ++i) {
if (!prefs->order[i])
break;
ast_debug(1, "prefs[%d]=%s:%d\n", i, (prefs->order[i] ? ast_getformatname(1 << (prefs->order[i]-1)) : "<none>"), prefs->framing[i]);
ast_debug(1, "prefs[%d]=%s:%d\n", i, (prefs->order[i] ? ast_getformatname(&prefs->formats[i]) : "<none>"), prefs->framing[i]);
}
}
if (pvt->rtp) {
@ -2531,7 +2564,7 @@ static void set_local_capabilities(unsigned call_reference, const char *token)
for (i = 0; i < 32; i++) {
if (!prefs.order[i])
break;
ast_debug(1, "local prefs[%d]=%s:%d\n", i, (prefs.order[i] ? ast_getformatname(1 << (prefs.order[i]-1)) : "<none>"), prefs.framing[i]);
ast_debug(1, "local prefs[%d]=%s:%d\n", i, (prefs.order[i] ? ast_getformatname(&prefs.formats[i]) : "<none>"), prefs.framing[i]);
}
ast_debug(1, "Capabilities for connection %s is set\n", token);
}
@ -3191,9 +3224,9 @@ static enum ast_rtp_glue_result oh323_get_rtp_peer(struct ast_channel *chan, str
return res;
}
static char *convertcap(format_t cap)
static char *convertcap(struct ast_format *format)
{
switch (cap) {
switch (format->id) {
case AST_FORMAT_G723_1:
return "G.723";
case AST_FORMAT_GSM:
@ -3213,12 +3246,12 @@ static char *convertcap(format_t cap)
case AST_FORMAT_ILBC:
return "ILBC";
default:
ast_log(LOG_NOTICE, "Don't know how to deal with mode %" PRId64 "\n", cap);
ast_log(LOG_NOTICE, "Don't know how to deal with mode %s\n", ast_getformatname(format));
return NULL;
}
}
static int oh323_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 oh323_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 *codecs, int nat_active)
{
/* XXX Deal with Video */
struct oh323_pvt *pvt;
@ -3230,7 +3263,7 @@ static int oh323_set_rtp_peer(struct ast_channel *chan, struct ast_rtp_instance
return 0;
}
mode = convertcap(chan->writeformat);
mode = convertcap(&chan->writeformat);
pvt = (struct oh323_pvt *) chan->tech_pvt;
if (!pvt) {
ast_log(LOG_ERROR, "No Private Structure, this is bad\n");
@ -3260,6 +3293,11 @@ static enum ast_module_load_result load_module(void)
{
int res;
if (!(oh323_tech.capabilities = ast_format_cap_alloc())) {
return AST_MODULE_LOAD_FAILURE;
}
ast_format_cap_add_all_by_type(oh323_tech.capabilities, AST_FORMAT_TYPE_AUDIO);
h323debug = 0;
sched = ast_sched_context_create();
if (!sched) {
@ -3430,6 +3468,7 @@ static int unload_module(void)
ASTOBJ_CONTAINER_DESTROYALL(&aliasl, oh323_destroy_alias);
ASTOBJ_CONTAINER_DESTROY(&aliasl);
oh323_tech.capabilities = ast_format_cap_destroy(oh323_tech.capabilities);
return 0;
}

View File

@ -317,22 +317,22 @@ static int (*iax2_regfunk)(const char *username, int onoff) = NULL;
#define IAX_CAPABILITY_FULLBANDWIDTH 0xFFFF
/* T1, maybe ISDN */
#define IAX_CAPABILITY_MEDBANDWIDTH (IAX_CAPABILITY_FULLBANDWIDTH & \
~AST_FORMAT_SLINEAR & \
~AST_FORMAT_SLINEAR16 & \
~AST_FORMAT_SIREN7 & \
~AST_FORMAT_SIREN14 & \
~AST_FORMAT_G719 & \
~AST_FORMAT_ULAW & \
~AST_FORMAT_ALAW & \
~AST_FORMAT_G722)
~ast_format_id_to_old_bitfield(AST_FORMAT_SLINEAR) & \
~ast_format_id_to_old_bitfield(AST_FORMAT_SLINEAR16) & \
~ast_format_id_to_old_bitfield(AST_FORMAT_SIREN7) & \
~ast_format_id_to_old_bitfield(AST_FORMAT_SIREN14) & \
~ast_format_id_to_old_bitfield(AST_FORMAT_G719) & \
~ast_format_id_to_old_bitfield(AST_FORMAT_ULAW) & \
~ast_format_id_to_old_bitfield(AST_FORMAT_ALAW) & \
~ast_format_id_to_old_bitfield(AST_FORMAT_G722))
/* A modem */
#define IAX_CAPABILITY_LOWBANDWIDTH (IAX_CAPABILITY_MEDBANDWIDTH & \
~AST_FORMAT_G726 & \
~AST_FORMAT_G726_AAL2 & \
~AST_FORMAT_ADPCM)
~ast_format_id_to_old_bitfield(AST_FORMAT_G726) & \
~ast_format_id_to_old_bitfield(AST_FORMAT_G726_AAL2) & \
~ast_format_id_to_old_bitfield(AST_FORMAT_ADPCM))
#define IAX_CAPABILITY_LOWFREE (IAX_CAPABILITY_LOWBANDWIDTH & \
~AST_FORMAT_G723_1)
~ast_format_id_to_old_bitfield(AST_FORMAT_G723_1))
#define DEFAULT_MAXMS 2000 /* Must be faster than 2 seconds by default */
@ -361,7 +361,7 @@ static struct ast_sched_context *sched;
#define DONT_RESCHEDULE -2
static format_t iax2_capability = IAX_CAPABILITY_FULLBANDWIDTH;
static iax2_format iax2_capability = IAX_CAPABILITY_FULLBANDWIDTH;
static int iaxdebug = 0;
@ -470,7 +470,7 @@ struct iax2_user {
int amaflags;
int adsi;
uint64_t flags;
format_t capability;
iax2_format capability;
int maxauthreq; /*!< Maximum allowed outstanding AUTHREQs */
int curauthreq; /*!< Current number of outstanding AUTHREQs */
struct ast_codec_pref prefs;
@ -517,7 +517,7 @@ struct iax2_peer {
int expire; /*!< Schedule entry for expiry */
int expiry; /*!< How soon to expire */
format_t capability; /*!< Capability */
iax2_format capability; /*!< Capability */
/* Qualification */
int callno; /*!< Call number of POKE request */
@ -648,15 +648,15 @@ struct chan_iax2_pvt {
/*! Socket to send/receive on for this call */
int sockfd;
/*! Last received voice format */
format_t voiceformat;
iax2_format voiceformat;
/*! Last received video format */
format_t videoformat;
iax2_format videoformat;
/*! Last sent voice format */
format_t svoiceformat;
iax2_format svoiceformat;
/*! Last sent video format */
format_t svideoformat;
iax2_format svideoformat;
/*! What we are capable of sending */
format_t capability;
iax2_format capability;
/*! Last received timestamp */
unsigned int last;
/*! Last sent timestamp - never send the same timestamp twice in a single call */
@ -690,11 +690,11 @@ struct chan_iax2_pvt {
/*! Negotiated format, this is only used to remember what format was
chosen for an unauthenticated call so that the channel can get
created later using the right format */
format_t chosenformat;
iax2_format chosenformat;
/*! Peer selected format */
format_t peerformat;
iax2_format peerformat;
/*! Peer capability */
format_t peercapability;
iax2_format peercapability;
/*! timeval that we base our transmission on */
struct timeval offset;
/*! timeval that we base our delivery on */
@ -1191,7 +1191,7 @@ static int send_command_final(struct chan_iax2_pvt *, char, int, unsigned int, c
static int send_command_immediate(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
static int send_command_locked(unsigned short callno, char, int, unsigned int, const unsigned char *, int, int);
static int send_command_transfer(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int);
static struct ast_channel *iax2_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause);
static struct ast_channel *iax2_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, void *data, int *cause);
static struct ast_frame *iax2_read(struct ast_channel *c);
static struct iax2_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly);
static struct iax2_user *build_user(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly);
@ -1211,10 +1211,9 @@ static int replace_callno(const void *obj);
static void sched_delay_remove(struct sockaddr_in *sin, struct callno_entry *callno_entry);
static void network_change_event_cb(const struct ast_event *, void *);
static const struct ast_channel_tech iax2_tech = {
static struct ast_channel_tech iax2_tech = {
.type = "IAX2",
.description = tdesc,
.capabilities = IAX_CAPABILITY_FULLBANDWIDTH,
.properties = AST_CHAN_TP_WANTSJITTER,
.requester = iax2_request,
.devicestate = iax2_devicestate,
@ -1604,7 +1603,7 @@ static int send_lagrq(const void *data)
return 0;
}
static unsigned char compress_subclass(format_t subclass)
static unsigned char compress_subclass(iax2_format subclass)
{
int x;
int power=-1;
@ -1624,7 +1623,7 @@ static unsigned char compress_subclass(format_t subclass)
return power | IAX_FLAG_SC_LOG;
}
static format_t uncompress_subclass(unsigned char csub)
static iax2_format uncompress_subclass(unsigned char csub)
{
/* If the SC_LOG flag is set, return 2^csub otherwise csub */
if (csub & IAX_FLAG_SC_LOG) {
@ -1638,6 +1637,90 @@ static format_t uncompress_subclass(unsigned char csub)
return csub;
}
static iax2_format iax2_codec_choose(struct ast_codec_pref *pref, iax2_format formats, int find_best)
{
struct ast_format_cap *cap;
struct ast_format tmpfmt;
iax2_format format = 0;
if ((cap = ast_format_cap_alloc_nolock())) {
ast_format_clear(&tmpfmt);
ast_format_cap_from_old_bitfield(cap, formats);
ast_codec_choose(pref, cap, find_best, &tmpfmt);
format = ast_format_to_old_bitfield(&tmpfmt);
cap = ast_format_cap_destroy(cap);
}
return format;
}
static iax2_format iax2_best_codec(iax2_format formats)
{
struct ast_format_cap *cap = ast_format_cap_alloc_nolock();
struct ast_format tmpfmt;
if (!cap) {
return 0;
}
ast_format_clear(&tmpfmt);
ast_format_cap_from_old_bitfield(cap, formats);
ast_best_codec(cap, &tmpfmt);
cap = ast_format_cap_destroy(cap);
return ast_format_to_old_bitfield(&tmpfmt);
}
char *iax2_getformatname(iax2_format format)
{
struct ast_format tmpfmt;
if (!(ast_format_from_old_bitfield(&tmpfmt, format))) {
return "Unknown";
}
return ast_getformatname(&tmpfmt);
}
static char *iax2_getformatname_multiple(char *codec_buf, size_t len, iax2_format format)
{
struct ast_format_cap *cap = ast_format_cap_alloc_nolock();
if (!cap) {
return "(Nothing)";
}
ast_format_cap_from_old_bitfield(cap, format);
ast_getformatname_multiple(codec_buf, len, cap);
cap = ast_format_cap_destroy(cap);
return codec_buf;
}
static int iax2_parse_allow_disallow(struct ast_codec_pref *pref, iax2_format *formats, const char *list, int allowing)
{
int res;
struct ast_format_cap *cap = ast_format_cap_alloc_nolock();
if (!cap) {
return 1;
}
ast_format_cap_from_old_bitfield(cap, *formats);
res = ast_parse_allow_disallow(pref, cap, list, allowing);
*formats = ast_format_cap_to_old_bitfield(cap);
cap = ast_format_cap_destroy(cap);
return res;
}
static int iax2_data_add_codecs(struct ast_data *root, const char *node_name, iax2_format formats)
{
int res;
struct ast_format_cap *cap = ast_format_cap_alloc_nolock();
if (!cap) {
return -1;
}
ast_format_cap_from_old_bitfield(cap, formats);
res = ast_data_add_codecs(root, node_name, cap);
cap = ast_format_cap_destroy(cap);
return res;
}
/*!
* \note The only member of the peer passed here guaranteed to be set is the name field
*/
@ -3727,7 +3810,7 @@ static char *handle_cli_iax2_show_peer(struct ast_cli_entry *e, int cmd, struct
struct iax2_peer *peer;
char codec_buf[512];
struct ast_str *encmethods = ast_str_alloca(256);
int x = 0, codec = 0, load_realtime = 0;
int x = 0, load_realtime = 0;
switch (cmd) {
case CLI_INIT:
@ -3772,16 +3855,16 @@ static char *handle_cli_iax2_show_peer(struct ast_cli_entry *e, int cmd, struct
ast_cli(a->fd, " Defaddr->IP : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port));
ast_cli(a->fd, " Username : %s\n", peer->username);
ast_cli(a->fd, " Codecs : ");
ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability);
iax2_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability);
ast_cli(a->fd, "%s\n", codec_buf);
ast_cli(a->fd, " Codec Order : (");
for(x = 0; x < 32 ; x++) {
codec = ast_codec_pref_index(&peer->prefs,x);
if(!codec)
for(x = 0; x < AST_CODEC_PREF_SIZE; x++) {
struct ast_format tmpfmt;
if(!(ast_codec_pref_index(&peer->prefs, x, &tmpfmt)))
break;
ast_cli(a->fd, "%s", ast_getformatname(codec));
if(x < 31 && ast_codec_pref_index(&peer->prefs,x+1))
ast_cli(a->fd, "%s", ast_getformatname(&tmpfmt));
if(x < 31 && ast_codec_pref_index(&peer->prefs, x+1, &tmpfmt))
ast_cli(a->fd, "|");
}
@ -4067,7 +4150,9 @@ static void __get_from_jb(const void *p)
ms = ast_tvdiff_ms(now, pvt->rxcore);
if(ms >= (next = jb_next(pvt->jb))) {
ret = jb_get(pvt->jb,&frame,ms,ast_codec_interp_len(pvt->voiceformat));
struct ast_format voicefmt;
ast_format_from_old_bitfield(&voicefmt, pvt->voiceformat);
ret = jb_get(pvt->jb, &frame, ms, ast_codec_interp_len(&voicefmt));
switch(ret) {
case JB_OK:
fr = frame.data;
@ -4081,8 +4166,8 @@ static void __get_from_jb(const void *p)
/* create an interpolation frame */
af.frametype = AST_FRAME_VOICE;
af.subclass.codec = pvt->voiceformat;
af.samples = frame.ms * (ast_format_rate(pvt->voiceformat) / 1000);
ast_format_copy(&af.subclass.format, &voicefmt);
af.samples = frame.ms * (ast_format_rate(&voicefmt) / 1000);
af.src = "IAX2 JB interpolation";
af.delivery = ast_tvadd(pvt->rxcore, ast_samp2tv(next, 1000));
af.offset = AST_FRIENDLY_OFFSET;
@ -4154,7 +4239,7 @@ static int schedule_delivery(struct iax_frame *fr, int updatehistory, int fromtr
if(fr->af.frametype == AST_FRAME_VOICE) {
type = JB_TYPE_VOICE;
len = ast_codec_get_samples(&fr->af) / (ast_format_rate(fr->af.subclass.codec) / 1000);
len = ast_codec_get_samples(&fr->af) / (ast_format_rate(&fr->af.subclass.format) / 1000);
} else if(fr->af.frametype == AST_FRAME_CNG) {
type = JB_TYPE_SILENCE;
}
@ -4511,7 +4596,7 @@ static void realtime_update_peer(const char *peername, struct ast_sockaddr *sock
}
struct create_addr_info {
format_t capability;
iax2_format capability;
uint64_t flags;
int maxtime;
int encmethods;
@ -4557,8 +4642,14 @@ static int create_addr(const char *peername, struct ast_channel *c, struct socka
/* use global iax prefs for unknown peer/user */
/* But move the calling channel's native codec to the top of the preference list */
memcpy(&ourprefs, &prefs, sizeof(ourprefs));
if (c)
ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1);
if (c) {
struct ast_format tmpfmt;
ast_format_cap_iter_start(c->nativeformats);
while (!(ast_format_cap_iter_next(c->nativeformats, &tmpfmt))) {
ast_codec_pref_prepend(&ourprefs, &tmpfmt, 1);
}
ast_format_cap_iter_end(c->nativeformats);
}
ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1);
return 0;
}
@ -4585,8 +4676,13 @@ static int create_addr(const char *peername, struct ast_channel *c, struct socka
memcpy(&ourprefs, &peer->prefs, sizeof(ourprefs));
/* Move the calling channel's native codec to the top of the preference list */
if (c) {
ast_debug(1, "prepending %llx to prefs\n", (unsigned long long) c->nativeformats);
ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1);
struct ast_format tmpfmt;
ast_format_cap_iter_start(c->nativeformats);
while (!(ast_format_cap_iter_next(c->nativeformats, &tmpfmt))) {
ast_debug(1, "prepending %s to prefs\n", ast_getformatname(&tmpfmt));
ast_codec_pref_prepend(&ourprefs, &tmpfmt, 1);
}
ast_format_cap_iter_end(c->nativeformats);
}
ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1);
ast_copy_string(cai->context, peer->context, sizeof(cai->context));
@ -4995,6 +5091,7 @@ static int iax2_call(struct ast_channel *c, char *dest, int timeout)
unsigned char osp_block_index;
unsigned int osp_block_length;
unsigned char osp_buffer[256];
iax2_format iax2_tmpfmt;
if ((c->_state != AST_STATE_DOWN) && (c->_state != AST_STATE_RESERVED)) {
ast_log(LOG_WARNING, "Channel is already in use (%s)?\n", c->name);
@ -5121,8 +5218,10 @@ static int iax2_call(struct ast_channel *c, char *dest, int timeout)
if (pds.password)
ast_string_field_set(iaxs[callno], secret, pds.password);
iax_ie_append_int(&ied, IAX_IE_FORMAT, (int) c->nativeformats);
iax_ie_append_versioned_uint64(&ied, IAX_IE_FORMAT2, 0, c->nativeformats);
iax2_tmpfmt = ast_format_cap_to_old_bitfield(c->nativeformats);
iax_ie_append_int(&ied, IAX_IE_FORMAT, (int) iax2_tmpfmt);
iax_ie_append_versioned_uint64(&ied, IAX_IE_FORMAT2, 0, iax2_tmpfmt);
iax_ie_append_int(&ied, IAX_IE_CAPABILITY, (int) iaxs[callno]->capability);
iax_ie_append_versioned_uint64(&ied, IAX_IE_CAPABILITY2, 0, iaxs[callno]->capability);
iax_ie_append_short(&ied, IAX_IE_ADSICPE, c->adsicpe);
@ -5471,7 +5570,7 @@ static enum ast_bridge_result iax2_bridge(struct ast_channel *c0, struct ast_cha
}
return AST_BRIDGE_FAILED_NOWARN;
}
if (c0->nativeformats != c1->nativeformats) {
if (!(ast_format_cap_identical(c0->nativeformats, c1->nativeformats))) {
char buf0[256];
char buf1[256];
ast_getformatname_multiple(buf0, sizeof(buf0), c0->nativeformats);
@ -5676,11 +5775,12 @@ static int iax2_getpeertrunk(struct sockaddr_in sin)
}
/*! \brief Create new call, interface with the PBX core */
static struct ast_channel *ast_iax2_new(int callno, int state, format_t capability, const char *linkedid)
static struct ast_channel *ast_iax2_new(int callno, int state, iax2_format capability, const char *linkedid)
{
struct ast_channel *tmp;
struct chan_iax2_pvt *i;
struct ast_variable *v = NULL;
struct ast_format tmpfmt;
if (!(i = iaxs[callno])) {
ast_log(LOG_WARNING, "No IAX2 pvt found for callno '%d' !\n", callno);
@ -5705,9 +5805,14 @@ static struct ast_channel *ast_iax2_new(int callno, int state, format_t capabili
return NULL;
tmp->tech = &iax2_tech;
/* We can support any format by default, until we get restricted */
tmp->nativeformats = capability;
tmp->readformat = tmp->rawreadformat = ast_best_codec(capability);
tmp->writeformat = tmp->rawwriteformat = ast_best_codec(capability);
ast_format_cap_from_old_bitfield(tmp->nativeformats, capability);
ast_best_codec(tmp->nativeformats, &tmpfmt);
ast_format_copy(&tmp->readformat, &tmpfmt);
ast_format_copy(&tmp->rawreadformat, &tmpfmt);
ast_format_copy(&tmp->writeformat, &tmpfmt);
ast_format_copy(&tmp->rawwriteformat, &tmpfmt);
tmp->tech_pvt = CALLNO_TO_PTR(i->callno);
if (!ast_strlen_zero(i->parkinglot))
@ -5848,7 +5953,7 @@ static unsigned int calc_timestamp(struct chan_iax2_pvt *p, unsigned int ts, str
int voice = 0;
int genuine = 0;
int adjust;
int rate = ast_format_rate(f->subclass.codec) / 1000;
int rate = ast_format_rate(&f->subclass.format) / 1000;
struct timeval *delivery = NULL;
@ -6221,9 +6326,9 @@ static int decode_frame(ast_aes_decrypt_key *dcx, struct ast_iax2_full_hdr *fh,
memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
f->frametype = fh->type;
if (f->frametype == AST_FRAME_VIDEO) {
f->subclass.codec = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
ast_format_from_old_bitfield(&f->subclass.format, (uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1)));
} else if (f->frametype == AST_FRAME_VOICE) {
f->subclass.codec = uncompress_subclass(fh->csub);
ast_format_from_old_bitfield(&f->subclass.format, uncompress_subclass(fh->csub));
} else {
f->subclass.integer = uncompress_subclass(fh->csub);
}
@ -6366,7 +6471,7 @@ static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned in
/* High two bytes are the same on timestamp, or sending on a trunk */ &&
(f->frametype == AST_FRAME_VOICE)
/* is a voice frame */ &&
(f->subclass.codec == pvt->svoiceformat)
(f->subclass.format.id == ast_format_id_from_old_bitfield(pvt->svoiceformat))
/* is the same type */ ) {
/* Force immediate rather than delayed transmission */
now = 1;
@ -6380,7 +6485,7 @@ static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned in
* Otherwise send a mini video frame
*/
if (((fts & 0xFFFF8000L) == (pvt->lastvsent & 0xFFFF8000L)) &&
((f->subclass.codec & ~0x1LL) == pvt->svideoformat)
((f->subclass.format.id) == ast_format_id_from_old_bitfield(pvt->svideoformat))
) {
now = 1;
sendmini = 1;
@ -6435,9 +6540,11 @@ static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned in
fh->type = fr->af.frametype & 0xFF;
if (fr->af.frametype == AST_FRAME_VIDEO) {
fh->csub = compress_subclass(fr->af.subclass.codec & ~0x1LL) | ((fr->af.subclass.codec & 0x1LL) << 6);
iax2_format tmpfmt = ast_format_to_old_bitfield(&fr->af.subclass.format);
tmpfmt |= ast_format_get_video_mark(&fr->af.subclass.format) ? 0x1LL : 0;
fh->csub = compress_subclass(tmpfmt | ((tmpfmt & 0x1LL) << 6));
} else if (fr->af.frametype == AST_FRAME_VOICE) {
fh->csub = compress_subclass(fr->af.subclass.codec);
fh->csub = compress_subclass(ast_format_to_old_bitfield(&fr->af.subclass.format));
} else {
fh->csub = compress_subclass(fr->af.subclass.integer);
}
@ -6460,9 +6567,9 @@ static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned in
if ((f->frametype == AST_FRAME_IAX) && (f->subclass.integer == IAX_COMMAND_ACK))
fr->retries = -1;
else if (f->frametype == AST_FRAME_VOICE)
pvt->svoiceformat = f->subclass.codec;
pvt->svoiceformat = ast_format_to_old_bitfield(&f->subclass.format);
else if (f->frametype == AST_FRAME_VIDEO)
pvt->svideoformat = f->subclass.codec & ~0x1LL;
pvt->svideoformat = ast_format_to_old_bitfield(&f->subclass.format);
if (ast_test_flag64(pvt, IAX_ENCRYPTED)) {
if (ast_test_flag64(pvt, IAX_KEYPOPULATED)) {
if (fr->transfer)
@ -6493,7 +6600,7 @@ static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned in
vh = (struct ast_iax2_video_hdr *)(fr->af.data.ptr - sizeof(struct ast_iax2_video_hdr));
vh->zeros = 0;
vh->callno = htons(0x8000 | fr->callno);
vh->ts = htons((fr->ts & 0x7FFF) | (fr->af.subclass.codec & 0x1LL ? 0x8000 : 0));
vh->ts = htons((fr->ts & 0x7FFF) | (ast_format_get_video_mark(&fr->af.subclass.format) ? 0x8000 : 0));
fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_video_hdr);
fr->data = vh;
fr->retries = -1;
@ -7167,7 +7274,7 @@ static char *handle_cli_iax2_show_channels(struct ast_cli_entry *e, int cmd, str
lag,
jitter,
localdelay,
ast_getformatname(iaxs[x]->voiceformat),
iax2_getformatname(iaxs[x]->voiceformat),
(iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
first_message,
(iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
@ -9659,7 +9766,7 @@ static int socket_process_meta(int packet_len, struct ast_iax2_meta_hdr *meta, s
ast_log(LOG_WARNING, "Received trunked frame before first full voice frame\n");
iax2_vnak(fr->callno);
} else {
f.subclass.codec = iaxs[fr->callno]->voiceformat;
ast_format_from_old_bitfield(&f.subclass.format, iaxs[fr->callno]->voiceformat);
f.datalen = len;
if (f.datalen >= 0) {
if (f.datalen)
@ -9806,7 +9913,7 @@ static int socket_process(struct iax2_thread *thread)
struct iax2_peer *peer;
struct iax_ies ies;
struct iax_ie_data ied0, ied1;
format_t format;
iax2_format format;
int fd;
int exists;
int minivid = 0;
@ -9877,9 +9984,12 @@ static int socket_process(struct iax2_thread *thread)
/* Retrieve the type and subclass */
f.frametype = fh->type;
if (f.frametype == AST_FRAME_VIDEO) {
f.subclass.codec = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
ast_format_from_old_bitfield(&f.subclass.format, (uncompress_subclass(fh->csub & ~0x40)));
if ((fh->csub >> 6) & 0x1) {
ast_format_set_video_mark(&f.subclass.format);
}
} else if (f.frametype == AST_FRAME_VOICE) {
f.subclass.codec = uncompress_subclass(fh->csub);
ast_format_from_old_bitfield(&f.subclass.format, uncompress_subclass(fh->csub));
} else {
f.subclass.integer = uncompress_subclass(fh->csub);
}
@ -10250,21 +10360,24 @@ static int socket_process(struct iax2_thread *thread)
}
if (f.frametype == AST_FRAME_VOICE) {
if (f.subclass.codec != iaxs[fr->callno]->voiceformat) {
iaxs[fr->callno]->voiceformat = f.subclass.codec;
ast_debug(1, "Ooh, voice format changed to '%s'\n", ast_getformatname(f.subclass.codec));
if (ast_format_to_old_bitfield(&f.subclass.format) != iaxs[fr->callno]->voiceformat) {
iaxs[fr->callno]->voiceformat = ast_format_to_old_bitfield(&f.subclass.format);
ast_debug(1, "Ooh, voice format changed to '%s'\n", ast_getformatname(&f.subclass.format));
if (iaxs[fr->callno]->owner) {
iax2_lock_owner(fr->callno);
if (iaxs[fr->callno]) {
if (iaxs[fr->callno]->owner) {
format_t orignative;
orignative = iaxs[fr->callno]->owner->nativeformats;
iaxs[fr->callno]->owner->nativeformats = f.subclass.codec;
if (iaxs[fr->callno]->owner->readformat)
ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat);
iaxs[fr->callno]->owner->nativeformats = orignative;
ast_channel_unlock(iaxs[fr->callno]->owner);
struct ast_format_cap *orignative = ast_format_cap_dup(iaxs[fr->callno]->owner->nativeformats);
struct ast_format_cap *native = iaxs[fr->callno]->owner->nativeformats;
if (orignative) {
ast_format_cap_set(native, &f.subclass.format);
if (iaxs[fr->callno]->owner->readformat.id) {
ast_set_read_format(iaxs[fr->callno]->owner, &iaxs[fr->callno]->owner->readformat);
}
ast_format_cap_copy(native, orignative);
ast_channel_unlock(iaxs[fr->callno]->owner);
orignative = ast_format_cap_destroy(orignative);
}
}
} else {
ast_debug(1, "Neat, somebody took away the channel at a magical time but i found it!\n");
@ -10281,9 +10394,9 @@ static int socket_process(struct iax2_thread *thread)
}
}
if (f.frametype == AST_FRAME_VIDEO) {
if (f.subclass.codec != iaxs[fr->callno]->videoformat) {
ast_debug(1, "Ooh, video format changed to %s\n", ast_getformatname(f.subclass.codec & ~0x1LL));
iaxs[fr->callno]->videoformat = f.subclass.codec & ~0x1LL;
if (f.subclass.format.id != ast_format_id_from_old_bitfield(iaxs[fr->callno]->videoformat)) {
ast_debug(1, "Ooh, video format changed to %s\n", ast_getformatname(&f.subclass.format));
iaxs[fr->callno]->videoformat = ast_format_to_old_bitfield(&f.subclass.format);
}
}
if (f.frametype == AST_FRAME_CONTROL && iaxs[fr->callno]->owner) {
@ -10471,11 +10584,12 @@ static int socket_process(struct iax2_thread *thread)
strcpy(caller_pref_buf, "disabled");
strcpy(host_pref_buf, "disabled");
} else {
struct ast_format tmpfmt;
using_prefs = "mine";
/* If the information elements are in here... use them */
if (ies.codec_prefs)
ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0, &tmpfmt)) {
/* If we are codec_first_choice we let the caller have the 1st shot at picking the codec.*/
if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
pref = iaxs[fr->callno]->rprefs;
@ -10486,7 +10600,7 @@ static int socket_process(struct iax2_thread *thread)
} else
pref = iaxs[fr->callno]->prefs;
format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
format = iax2_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
}
@ -10506,14 +10620,14 @@ static int socket_process(struct iax2_thread *thread)
if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested '%s' incompatible with our capability '%s'.\n",
ast_inet_ntoa(sin.sin_addr),
ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat),
ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability));
iax2_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat),
iax2_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability));
} else {
ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n",
ast_inet_ntoa(sin.sin_addr),
ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat),
ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability),
ast_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability));
iax2_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat),
iax2_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability),
iax2_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability));
}
}
} else {
@ -10525,12 +10639,13 @@ static int socket_process(struct iax2_thread *thread)
if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
using_prefs = ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
memset(&pref, 0, sizeof(pref));
format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
format = iax2_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
strcpy(caller_pref_buf,"disabled");
strcpy(host_pref_buf,"disabled");
} else {
struct ast_format tmpfmt;
using_prefs = "mine";
if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0, &tmpfmt)) {
/* Do the opposite of what we tried above. */
if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
pref = iaxs[fr->callno]->prefs;
@ -10538,9 +10653,9 @@ static int socket_process(struct iax2_thread *thread)
pref = iaxs[fr->callno]->rprefs;
using_prefs = "caller";
}
format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
format = iax2_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
} else /* if no codec_prefs IE do it the old way */
format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
format = iax2_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
}
}
@ -10549,7 +10664,7 @@ static int socket_process(struct iax2_thread *thread)
memset(&ied0, 0, sizeof(ied0));
iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
ast_log(LOG_ERROR, "No best format in '%s'???\n", ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability));
ast_log(LOG_ERROR, "No best format in '%s'???\n", iax2_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability));
send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
if (!iaxs[fr->callno]) {
break;
@ -10557,9 +10672,9 @@ static int socket_process(struct iax2_thread *thread)
if (authdebug) {
ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n",
ast_inet_ntoa(sin.sin_addr),
ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat),
ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability),
ast_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability));
iax2_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat),
iax2_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability),
iax2_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability));
}
ast_set_flag64(iaxs[fr->callno], IAX_ALREADYGONE);
break;
@ -10582,11 +10697,11 @@ static int socket_process(struct iax2_thread *thread)
"%spriority = %s\n",
ast_inet_ntoa(sin.sin_addr),
VERBOSE_PREFIX_4,
ast_getformatname(iaxs[fr->callno]->peerformat),
iax2_getformatname(iaxs[fr->callno]->peerformat),
VERBOSE_PREFIX_4,
caller_pref_buf,
VERBOSE_PREFIX_4,
ast_getformatname(format),
iax2_getformatname(format),
VERBOSE_PREFIX_4,
host_pref_buf,
VERBOSE_PREFIX_4,
@ -10730,11 +10845,11 @@ static int socket_process(struct iax2_thread *thread)
iaxs[fr->callno]->peerformat = ies.format;
} else {
if (iaxs[fr->callno]->owner)
iaxs[fr->callno]->peerformat = iaxs[fr->callno]->owner->nativeformats;
iaxs[fr->callno]->peerformat = ast_format_cap_to_old_bitfield(iaxs[fr->callno]->owner->nativeformats);
else
iaxs[fr->callno]->peerformat = iaxs[fr->callno]->capability;
}
ast_verb(3, "Call accepted by %s (format %s)\n", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), ast_getformatname(iaxs[fr->callno]->peerformat));
ast_verb(3, "Call accepted by %s (format %s)\n", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), iax2_getformatname(iaxs[fr->callno]->peerformat));
if (!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) {
memset(&ied0, 0, sizeof(ied0));
iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
@ -10747,22 +10862,23 @@ static int socket_process(struct iax2_thread *thread)
char tmp1[256], tmp2[256];
ast_log(LOG_NOTICE, "Rejected call to %s, format %s incompatible with our capability %s.\n",
ast_inet_ntoa(sin.sin_addr),
ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability));
iax2_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
iax2_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability));
}
} else {
ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
iax2_lock_owner(fr->callno);
if (iaxs[fr->callno] && iaxs[fr->callno]->owner) {
char tmp[256];
/* Switch us to use a compatible format */
iaxs[fr->callno]->owner->nativeformats = iaxs[fr->callno]->peerformat;
ast_verb(3, "Format for call is %s\n", ast_getformatname(iaxs[fr->callno]->owner->nativeformats));
ast_format_cap_from_old_bitfield(iaxs[fr->callno]->owner->nativeformats, iaxs[fr->callno]->peerformat);
ast_verb(3, "Format for call is %s\n", ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->owner->nativeformats));
/* Setup read/write formats properly. */
if (iaxs[fr->callno]->owner->writeformat)
ast_set_write_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->writeformat);
if (iaxs[fr->callno]->owner->readformat)
ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat);
if (iaxs[fr->callno]->owner->writeformat.id)
ast_set_write_format(iaxs[fr->callno]->owner, &iaxs[fr->callno]->owner->writeformat);
if (iaxs[fr->callno]->owner->readformat.id)
ast_set_read_format(iaxs[fr->callno]->owner, &iaxs[fr->callno]->owner->readformat);
ast_channel_unlock(iaxs[fr->callno]->owner);
}
}
@ -10921,10 +11037,11 @@ static int socket_process(struct iax2_thread *thread)
strcpy(caller_pref_buf, "disabled");
strcpy(host_pref_buf, "disabled");
} else {
struct ast_format tmpfmt;
using_prefs = "mine";
if (ies.codec_prefs)
ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0, &tmpfmt)) {
if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
pref = iaxs[fr->callno]->rprefs;
using_prefs = "caller";
@ -10933,7 +11050,7 @@ static int socket_process(struct iax2_thread *thread)
}
} else /* if no codec_prefs IE do it the old way */
pref = iaxs[fr->callno]->prefs;
format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
format = iax2_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
}
@ -10941,22 +11058,22 @@ static int socket_process(struct iax2_thread *thread)
char tmp1[256], tmp2[256], tmp3[256];
if(!ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
ast_debug(1, "We don't do requested format %s, falling back to peer capability '%s'\n",
ast_getformatname(iaxs[fr->callno]->peerformat),
ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peercapability));
iax2_getformatname(iaxs[fr->callno]->peerformat),
iax2_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peercapability));
format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
}
if (!format) {
if (authdebug) {
if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested '%s' incompatible with our capability '%s'.\n", ast_inet_ntoa(sin.sin_addr),
ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability));
iax2_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
iax2_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability));
} else {
ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n",
ast_inet_ntoa(sin.sin_addr),
ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability),
ast_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability));
iax2_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
iax2_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability),
iax2_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability));
}
}
memset(&ied0, 0, sizeof(ied0));
@ -10976,12 +11093,13 @@ static int socket_process(struct iax2_thread *thread)
using_prefs = ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
memset(&pref, 0, sizeof(pref));
format = ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP) ?
iaxs[fr->callno]->peerformat : ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
iaxs[fr->callno]->peerformat : iax2_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
strcpy(caller_pref_buf,"disabled");
strcpy(host_pref_buf,"disabled");
} else {
struct ast_format tmpfmt;
using_prefs = "mine";
if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0, &tmpfmt)) {
/* Do the opposite of what we tried above. */
if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
pref = iaxs[fr->callno]->prefs;
@ -10989,27 +11107,27 @@ static int socket_process(struct iax2_thread *thread)
pref = iaxs[fr->callno]->rprefs;
using_prefs = "caller";
}
format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
format = iax2_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
} else /* if no codec_prefs IE do it the old way */
format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
format = iax2_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
}
}
if (!format) {
char tmp1[256], tmp2[256], tmp3[256];
ast_log(LOG_ERROR, "No best format in %s???\n",
ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability));
iax2_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability));
if (authdebug) {
if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested '%s' incompatible with our capability '%s'.\n",
ast_inet_ntoa(sin.sin_addr),
ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability));
iax2_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
iax2_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability));
} else {
ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n",
ast_inet_ntoa(sin.sin_addr),
ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability),
ast_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability));
iax2_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
iax2_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability),
iax2_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability));
}
}
memset(&ied0, 0, sizeof(ied0));
@ -11038,11 +11156,11 @@ static int socket_process(struct iax2_thread *thread)
"%spriority = %s\n",
ast_inet_ntoa(sin.sin_addr),
VERBOSE_PREFIX_4,
ast_getformatname(iaxs[fr->callno]->peerformat),
iax2_getformatname(iaxs[fr->callno]->peerformat),
VERBOSE_PREFIX_4,
caller_pref_buf,
VERBOSE_PREFIX_4,
ast_getformatname(format),
iax2_getformatname(format),
VERBOSE_PREFIX_4,
host_pref_buf,
VERBOSE_PREFIX_4,
@ -11117,7 +11235,7 @@ immediatedial:
ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
ast_verb(3, "Accepting DIAL from %s, formats = %s\n",
ast_inet_ntoa(sin.sin_addr),
ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat));
iax2_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat));
ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
send_command(iaxs[fr->callno], AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, 0, NULL, 0, -1);
if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->peerformat, NULL)))
@ -11396,9 +11514,12 @@ immediatedial:
send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
} else if (minivid) {
f.frametype = AST_FRAME_VIDEO;
if (iaxs[fr->callno]->videoformat > 0)
f.subclass.codec = iaxs[fr->callno]->videoformat | (ntohs(vh->ts) & 0x8000LL ? 1 : 0);
else {
if (iaxs[fr->callno]->videoformat > 0) {
if (ntohs(vh->ts) & 0x8000LL) {
ast_format_set_video_mark(&f.subclass.format);
}
ast_format_from_old_bitfield(&f.subclass.format, iaxs[fr->callno]->videoformat);
} else {
ast_log(LOG_WARNING, "Received mini frame before first full video frame\n");
iax2_vnak(fr->callno);
ast_variables_destroy(ies.vars);
@ -11420,7 +11541,7 @@ immediatedial:
/* A mini frame */
f.frametype = AST_FRAME_VOICE;
if (iaxs[fr->callno]->voiceformat > 0)
f.subclass.codec = iaxs[fr->callno]->voiceformat;
ast_format_from_old_bitfield(&f.subclass.format, iaxs[fr->callno]->voiceformat);
else {
ast_debug(1, "Received mini frame before first full voice frame\n");
iax2_vnak(fr->callno);
@ -11492,7 +11613,7 @@ immediatedial:
if (f.datalen && (f.frametype == AST_FRAME_VOICE)) {
f.samples = ast_codec_get_samples(&f);
/* We need to byteswap incoming slinear samples from network byte order */
if (f.subclass.codec == AST_FORMAT_SLINEAR)
if (f.subclass.format.id == AST_FORMAT_SLINEAR)
ast_frame_byteswap_be(&f);
} else
f.samples = 0;
@ -11982,11 +12103,10 @@ static void free_context(struct iax2_context *con)
}
}
static struct ast_channel *iax2_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause)
static struct ast_channel *iax2_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, void *data, int *cause)
{
int callno;
int res;
format_t fmt, native;
struct sockaddr_in sin;
struct ast_channel *c;
struct parsed_dial_string pds;
@ -12001,12 +12121,11 @@ static struct ast_channel *iax2_request(const char *type, format_t format, const
ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data);
return NULL;
}
memset(&cai, 0, sizeof(cai));
cai.capability = iax2_capability;
ast_copy_flags64(&cai, &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
/* Populate our address from the given */
if (create_addr(pds.peer, NULL, &sin, &cai)) {
*cause = AST_CAUSE_UNREGISTERED;
@ -12039,23 +12158,28 @@ static struct ast_channel *iax2_request(const char *type, format_t format, const
ast_mutex_unlock(&iaxsl[callno]);
if (c) {
struct ast_format_cap *joint;
/* Choose a format we can live with */
if (c->nativeformats & format)
c->nativeformats &= format;
else {
native = c->nativeformats;
fmt = format;
res = ast_translator_best_choice(&fmt, &native);
if ((joint = ast_format_cap_joint(c->nativeformats, cap))) {
ast_format_cap_copy(c->nativeformats, joint);
joint = ast_format_cap_destroy(joint);
} else {
struct ast_format best_fmt_cap;
struct ast_format best_fmt_native;
res = ast_translator_best_choice(cap, c->nativeformats, &best_fmt_cap, &best_fmt_native);
if (res < 0) {
char tmp[256];
char tmp2[256];
ast_log(LOG_WARNING, "Unable to create translator path for %s to %s on %s\n",
ast_getformatname(c->nativeformats), ast_getformatname(fmt), c->name);
ast_getformatname_multiple(tmp, sizeof(tmp), c->nativeformats), ast_getformatname_multiple(tmp2, sizeof(tmp2), cap), c->name);
ast_hangup(c);
return NULL;
}
c->nativeformats = native;
ast_format_cap_set(c->nativeformats, &best_fmt_native);
}
c->readformat = ast_best_codec(c->nativeformats);
c->writeformat = c->readformat;
ast_best_codec(c->nativeformats, &c->readformat);
ast_format_copy(&c->writeformat, &c->readformat);
}
return c;
@ -12429,9 +12553,9 @@ static struct iax2_peer *build_peer(const char *name, struct ast_variable *v, st
} else if (!strcasecmp(v->name, "username")) {
ast_string_field_set(peer, username, v->value);
} else if (!strcasecmp(v->name, "allow")) {
ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1);
iax2_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1);
} else if (!strcasecmp(v->name, "disallow")) {
ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0);
iax2_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0);
} else if (!strcasecmp(v->name, "callerid")) {
if (!ast_strlen_zero(v->value)) {
char name2[80];
@ -12641,9 +12765,9 @@ static struct iax2_user *build_user(const char *name, struct ast_variable *v, st
}
}
} else if (!strcasecmp(v->name, "allow")) {
ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1);
iax2_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1);
} else if (!strcasecmp(v->name, "disallow")) {
ast_parse_allow_disallow(&user->prefs, &user->capability,v->value, 0);
iax2_parse_allow_disallow(&user->prefs, &user->capability,v->value, 0);
} else if (!strcasecmp(v->name, "trunk")) {
ast_set2_flag64(user, ast_true(v->value), IAX_TRUNK);
if (ast_test_flag64(user, IAX_TRUNK) && !timer) {
@ -12903,7 +13027,7 @@ static void set_config_destroy(void)
static int set_config(const char *config_file, int reload)
{
struct ast_config *cfg, *ucfg;
format_t capability = iax2_capability;
iax2_format capability = iax2_capability;
struct ast_variable *v;
char *cat;
const char *utype;
@ -13164,9 +13288,9 @@ static int set_config(const char *config_file, int reload)
} else
ast_log(LOG_WARNING, "bandwidth must be either low, medium, or high\n");
} else if (!strcasecmp(v->name, "allow")) {
ast_parse_allow_disallow(&prefs, &capability, v->value, 1);
iax2_parse_allow_disallow(&prefs, &capability, v->value, 1);
} else if (!strcasecmp(v->name, "disallow")) {
ast_parse_allow_disallow(&prefs, &capability, v->value, 0);
iax2_parse_allow_disallow(&prefs, &capability, v->value, 0);
} else if (!strcasecmp(v->name, "register")) {
iax2_register(v->value, v->lineno);
} else if (!strcasecmp(v->name, "iaxcompat")) {
@ -13802,19 +13926,18 @@ static int function_iaxpeer(struct ast_channel *chan, const char *cmd, char *dat
} else if (!strcasecmp(colname, "callerid_num")) {
ast_copy_string(buf, peer->cid_num, len);
} else if (!strcasecmp(colname, "codecs")) {
ast_getformatname_multiple(buf, len -1, peer->capability);
iax2_getformatname_multiple(buf, len -1, peer->capability);
} else if (!strncasecmp(colname, "codec[", 6)) {
char *codecnum, *ptr;
int codec = 0;
struct ast_format tmpfmt;
codecnum = strchr(colname, '[');
*codecnum = '\0';
codecnum++;
if ((ptr = strchr(codecnum, ']'))) {
*ptr = '\0';
}
if((codec = ast_codec_pref_index(&peer->prefs, atoi(codecnum)))) {
ast_copy_string(buf, ast_getformatname(codec), len);
if((ast_codec_pref_index(&peer->prefs, atoi(codecnum), &tmpfmt))) {
ast_copy_string(buf, ast_getformatname(&tmpfmt), len);
} else {
buf[0] = '\0';
}
@ -14273,6 +14396,8 @@ static int __unload_module(void)
if (con)
ast_context_destroy(con, "IAX2");
ast_unload_realtime("iaxpeers");
iax2_tech.capabilities = ast_format_cap_destroy(iax2_tech.capabilities);
return 0;
}
@ -14436,7 +14561,7 @@ static int peers_data_provider_get(const struct ast_data_search *search,
ast_data_add_structure(iax2_peer, data_peer, peer);
ast_data_add_codecs(data_peer, "codecs", peer->capability);
iax2_data_add_codecs(data_peer, "codecs", peer->capability);
peer_status(peer, status, sizeof(status));
ast_data_add_str(data_peer, "status", status);
@ -14500,7 +14625,7 @@ static int users_data_provider_get(const struct ast_data_search *search,
ast_data_add_structure(iax2_user, data_user, user);
ast_data_add_codecs(data_user, "codecs", user->capability);
iax2_data_add_codecs(data_user, "codecs", user->capability);
if (!ast_strlen_zero(user->secret)) {
ast_copy_string(auth, user->secret, sizeof(auth));
@ -14576,6 +14701,11 @@ static int load_module(void)
int x = 0;
struct iax2_registry *reg = NULL;
if (!(iax2_tech.capabilities = ast_format_cap_alloc())) {
return AST_MODULE_LOAD_FAILURE;
}
ast_format_cap_add_all(iax2_tech.capabilities);
if (load_objects()) {
return AST_MODULE_LOAD_FAILURE;
}

View File

@ -104,7 +104,6 @@ struct jingle_pvt {
iksrule *ringrule; /*!< Rule for matching RING request */
int initiator; /*!< If we're the initiator */
int alreadygone;
format_t capability;
struct ast_codec_pref prefs;
struct jingle_candidate *theircandidates;
struct jingle_candidate *ourcandidates;
@ -116,8 +115,9 @@ struct jingle_pvt {
struct ast_rtp_instance *rtp; /*!< RTP audio session */
char video_content_name[100]; /*!< name attribute of content tag */
struct ast_rtp_instance *vrtp; /*!< RTP video session */
format_t jointcapability; /*!< Supported capability at both ends (codecs ) */
format_t peercapability;
struct ast_format_cap *cap;
struct ast_format_cap *jointcap; /*!< Supported capability at both ends (codecs ) */
struct ast_format_cap *peercap;
struct jingle_pvt *next; /* Next entity */
};
@ -147,7 +147,7 @@ struct jingle {
char user[100];
char context[100];
char accountcode[AST_MAX_ACCOUNT_CODE]; /*!< Account code */
format_t capability;
struct ast_format_cap *cap;
ast_group_t callgroup; /*!< Call group */
ast_group_t pickupgroup; /*!< Pickup group */
int callingpres; /*!< Calling presentation */
@ -164,12 +164,12 @@ struct jingle_container {
static const char desc[] = "Jingle Channel";
static const char channel_type[] = "Jingle";
static format_t global_capability = AST_FORMAT_ULAW | AST_FORMAT_ALAW | AST_FORMAT_GSM | AST_FORMAT_H263;
static struct ast_format_cap *global_capability;
AST_MUTEX_DEFINE_STATIC(jinglelock); /*!< Protect the interface list (of jingle_pvt's) */
/* Forward declarations */
static struct ast_channel *jingle_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause);
static struct ast_channel *jingle_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, void *data, int *cause);
static int jingle_sendtext(struct ast_channel *ast, const char *text);
static int jingle_digit_begin(struct ast_channel *ast, char digit);
static int jingle_digit_end(struct ast_channel *ast, char digit, unsigned int duration);
@ -187,10 +187,9 @@ static char *jingle_show_channels(struct ast_cli_entry *e, int cmd, struct ast_c
static char *jingle_do_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a);
/*! \brief PBX interface structure for channel registration */
static const struct ast_channel_tech jingle_tech = {
static struct ast_channel_tech jingle_tech = {
.type = "Jingle",
.description = "Jingle Channel Driver",
.capabilities = AST_FORMAT_AUDIO_MASK,
.requester = jingle_request,
.send_text = jingle_sendtext,
.send_digit_begin = jingle_digit_begin,
@ -226,6 +225,7 @@ static struct jingle_container jingle_list;
static void jingle_member_destroy(struct jingle *obj)
{
obj->cap = ast_format_cap_destroy(obj->cap);
ast_free(obj);
}
@ -255,7 +255,7 @@ static struct jingle *find_jingle(char *name, char *connection)
}
static void add_codec_to_answer(const struct jingle_pvt *p, int codec, iks *dcodecs)
static void add_codec_to_answer(const struct jingle_pvt *p, struct ast_format *codec, iks *dcodecs)
{
char *format = ast_getformatname(codec);
@ -301,10 +301,10 @@ static int jingle_accept_call(struct jingle *client, struct jingle_pvt *p)
struct aji_client *c = client->connection;
iks *iq, *jingle, *dcodecs, *payload_red, *payload_audio, *payload_cn;
int x;
format_t pref_codec = 0;
int alreadysent = 0;
struct ast_format pref_codec;
struct ast_format_cap *alreadysent = ast_format_cap_alloc_nolock();
if (p->initiator)
if (p->initiator || !alreadysent)
return 1;
iq = iks_new("iq");
@ -313,15 +313,15 @@ static int jingle_accept_call(struct jingle *client, struct jingle_pvt *p)
if (iq && jingle && dcodecs) {
iks_insert_attrib(dcodecs, "xmlns", JINGLE_AUDIO_RTP_NS);
for (x = 0; x < 64; x++) {
if (!(pref_codec = ast_codec_pref_index(&client->prefs, x)))
for (x = 0; x < AST_CODEC_PREF_SIZE; x++) {
if (!(ast_codec_pref_index(&client->prefs, x, &pref_codec)))
break;
if (!(client->capability & pref_codec))
if (!(ast_format_cap_iscompatible(client->cap, &pref_codec)))
continue;
if (alreadysent & pref_codec)
if ((ast_format_cap_iscompatible(alreadysent, &pref_codec)))
continue;
add_codec_to_answer(p, pref_codec, dcodecs);
alreadysent |= pref_codec;
add_codec_to_answer(p, &pref_codec, dcodecs);
ast_format_cap_add(alreadysent, &pref_codec);
}
payload_red = iks_new("payload-type");
iks_insert_attrib(payload_red, "id", "117");
@ -358,6 +358,7 @@ static int jingle_accept_call(struct jingle *client, struct jingle_pvt *p)
iks_delete(jingle);
iks_delete(iq);
}
alreadysent = ast_format_cap_destroy(alreadysent);
return 1;
}
@ -405,13 +406,15 @@ static enum ast_rtp_glue_result jingle_get_rtp_peer(struct ast_channel *chan, st
return res;
}
static format_t jingle_get_codec(struct ast_channel *chan)
static void jingle_get_codec(struct ast_channel *chan, struct ast_format_cap *result)
{
struct jingle_pvt *p = chan->tech_pvt;
return p->peercapability;
ast_mutex_lock(&p->lock);
ast_format_cap_copy(result, p->peercap);
ast_mutex_unlock(&p->lock);
}
static int jingle_set_rtp_peer(struct ast_channel *chan, struct ast_rtp_instance *rtp, struct ast_rtp_instance *vrtp, struct ast_rtp_instance *tpeer, format_t codecs, int nat_active)
static int jingle_set_rtp_peer(struct ast_channel *chan, struct ast_rtp_instance *rtp, struct ast_rtp_instance *vrtp, struct ast_rtp_instance *tpeer, const struct ast_format_cap *cap, int nat_active)
{
struct jingle_pvt *p;
@ -772,6 +775,16 @@ static struct jingle_pvt *jingle_alloc(struct jingle *client, const char *from,
return NULL;
}
tmp->cap = ast_format_cap_alloc_nolock();
tmp->jointcap = ast_format_cap_alloc_nolock();
tmp->peercap = ast_format_cap_alloc_nolock();
if (!tmp->cap || !tmp->jointcap || !tmp->peercap) {
tmp->cap = ast_format_cap_destroy(tmp->cap);
tmp->jointcap = ast_format_cap_destroy(tmp->jointcap);
tmp->peercap = ast_format_cap_destroy(tmp->peercap);
ast_free(tmp);
return NULL;
}
memcpy(&tmp->prefs, &client->prefs, sizeof(tmp->prefs));
if (sid) {
@ -803,8 +816,8 @@ static struct jingle_pvt *jingle_alloc(struct jingle *client, const char *from,
static struct ast_channel *jingle_new(struct jingle *client, struct jingle_pvt *i, int state, const char *title, const char *linkedid)
{
struct ast_channel *tmp;
int fmt;
int what;
struct ast_format_cap *what; /* SHALLOW COPY DO NOT DESTROY */
struct ast_format tmpfmt;
const char *str;
if (title)
@ -820,10 +833,10 @@ static struct ast_channel *jingle_new(struct jingle *client, struct jingle_pvt *
/* Select our native format based on codec preference until we receive
something from another device to the contrary. */
if (i->jointcapability)
what = i->jointcapability;
else if (i->capability)
what = i->capability;
if (!ast_format_cap_is_empty(i->jointcap))
what = i->jointcap;
else if (!(ast_format_cap_is_empty(i->cap)))
what = i->cap;
else
what = global_capability;
@ -831,8 +844,16 @@ static struct ast_channel *jingle_new(struct jingle *client, struct jingle_pvt *
if (i->rtp)
ast_rtp_codecs_packetization_set(ast_rtp_instance_get_codecs(i->rtp), i->rtp, &i->prefs);
tmp->nativeformats = ast_codec_choose(&i->prefs, what, 1) | (i->jointcapability & AST_FORMAT_VIDEO_MASK);
fmt = ast_best_codec(tmp->nativeformats);
ast_codec_choose(&i->prefs, what, 1, &tmpfmt);
ast_format_cap_add(tmp->nativeformats, &tmpfmt);
ast_format_cap_iter_start(i->jointcap);
while (!(ast_format_cap_iter_next(i->jointcap, &tmpfmt))) {
if (AST_FORMAT_GET_TYPE(tmpfmt.id) == AST_FORMAT_TYPE_VIDEO) {
ast_format_cap_add(tmp->nativeformats, &tmpfmt);
}
}
ast_format_cap_iter_end(i->jointcap);
if (i->rtp) {
ast_channel_set_fd(tmp, 0, ast_rtp_instance_fd(i->rtp, 0));
@ -845,10 +866,13 @@ static struct ast_channel *jingle_new(struct jingle *client, struct jingle_pvt *
if (state == AST_STATE_RING)
tmp->rings = 1;
tmp->adsicpe = AST_ADSI_UNAVAILABLE;
tmp->writeformat = fmt;
tmp->rawwriteformat = fmt;
tmp->readformat = fmt;
tmp->rawreadformat = fmt;
ast_best_codec(tmp->nativeformats, &tmpfmt);
ast_format_copy(&tmp->writeformat, &tmpfmt);
ast_format_copy(&tmp->rawwriteformat, &tmpfmt);
ast_format_copy(&tmp->readformat, &tmpfmt);
ast_format_copy(&tmp->rawreadformat, &tmpfmt);
tmp->tech_pvt = i;
tmp->callgroup = client->callgroup;
@ -955,6 +979,10 @@ static void jingle_free_pvt(struct jingle *client, struct jingle_pvt *p)
if (p->vrtp)
ast_rtp_instance_destroy(p->vrtp);
jingle_free_candidates(p->theircandidates);
p->cap = ast_format_cap_destroy(p->cap);
p->jointcap = ast_format_cap_destroy(p->jointcap);
p->peercap = ast_format_cap_destroy(p->peercap);
ast_free(p);
}
@ -1185,12 +1213,12 @@ static struct ast_frame *jingle_rtp_read(struct ast_channel *ast, struct jingle_
if (p->owner) {
/* We already hold the channel lock */
if (f->frametype == AST_FRAME_VOICE) {
if (f->subclass.codec != (p->owner->nativeformats & AST_FORMAT_AUDIO_MASK)) {
ast_debug(1, "Oooh, format changed to %s\n", ast_getformatname(f->subclass.codec));
p->owner->nativeformats =
(p->owner->nativeformats & AST_FORMAT_VIDEO_MASK) | f->subclass.codec;
ast_set_read_format(p->owner, p->owner->readformat);
ast_set_write_format(p->owner, p->owner->writeformat);
if (!(ast_format_cap_iscompatible(p->owner->nativeformats, &f->subclass.format))) {
ast_debug(1, "Oooh, format changed to %s\n", ast_getformatname(&f->subclass.format));
ast_format_cap_remove_bytype(p->owner->nativeformats, AST_FORMAT_TYPE_AUDIO);
ast_format_cap_add(p->owner->nativeformats, &f->subclass.format);
ast_set_read_format(p->owner, &p->owner->readformat);
ast_set_write_format(p->owner, &p->owner->writeformat);
}
/* if ((ast_test_flag(p, SIP_DTMF) == SIP_DTMF_INBAND) && p->vad) {
f = ast_dsp_process(p->owner, p->vad, f);
@ -1222,13 +1250,13 @@ static int jingle_write(struct ast_channel *ast, struct ast_frame *frame)
switch (frame->frametype) {
case AST_FRAME_VOICE:
if (!(frame->subclass.codec & ast->nativeformats)) {
if (!(ast_format_cap_iscompatible(ast->nativeformats, &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(&frame->subclass.format),
ast_getformatname_multiple(buf, sizeof(buf), ast->nativeformats),
ast_getformatname(ast->readformat),
ast_getformatname(ast->writeformat));
ast_getformatname(&ast->readformat),
ast_getformatname(&ast->writeformat));
return 0;
}
if (p) {
@ -1464,7 +1492,7 @@ static int jingle_call(struct ast_channel *ast, char *dest, int timeout)
}
ast_setstate(ast, AST_STATE_RING);
p->jointcapability = p->capability;
ast_format_cap_copy(p->jointcap, p->cap);
if (!p->ringrule) {
ast_copy_string(p->ring, p->parent->connection->mid, sizeof(p->ring));
p->ringrule = iks_filter_add_rule(p->parent->connection->f, jingle_ringing_ack, p,
@ -1498,7 +1526,7 @@ static int jingle_hangup(struct ast_channel *ast)
}
/*! \brief Part of PBX interface */
static struct ast_channel *jingle_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause)
static struct ast_channel *jingle_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, void *data, int *cause)
{
struct jingle_pvt *p = NULL;
struct jingle *client = NULL;
@ -1588,8 +1616,8 @@ static char *jingle_show_channels(struct ast_cli_entry *e, int cmd, struct ast_c
chan->name,
jid,
resource,
ast_getformatname(chan->readformat),
ast_getformatname(chan->writeformat)
ast_getformatname(&chan->readformat),
ast_getformatname(&chan->writeformat)
);
else
ast_log(LOG_WARNING, "No available channel\n");
@ -1717,9 +1745,9 @@ static int jingle_create_member(char *label, struct ast_variable *var, int allow
if (!strcasecmp(var->name, "username"))
ast_copy_string(member->user, var->value, sizeof(member->user));
else if (!strcasecmp(var->name, "disallow"))
ast_parse_allow_disallow(&member->prefs, &member->capability, var->value, 0);
ast_parse_allow_disallow(&member->prefs, member->cap, var->value, 0);
else if (!strcasecmp(var->name, "allow"))
ast_parse_allow_disallow(&member->prefs, &member->capability, var->value, 1);
ast_parse_allow_disallow(&member->prefs, member->cap, var->value, 1);
else if (!strcasecmp(var->name, "context"))
ast_copy_string(member->context, var->value, sizeof(member->context));
#if 0
@ -1787,9 +1815,9 @@ static int jingle_load_config(void)
allowguest =
(ast_true(ast_variable_retrieve(cfg, "general", "allowguest"))) ? 1 : 0;
else if (!strcasecmp(var->name, "disallow"))
ast_parse_allow_disallow(&prefs, &global_capability, var->value, 0);
ast_parse_allow_disallow(&prefs, global_capability, var->value, 0);
else if (!strcasecmp(var->name, "allow"))
ast_parse_allow_disallow(&prefs, &global_capability, var->value, 1);
ast_parse_allow_disallow(&prefs, global_capability, var->value, 1);
else if (!strcasecmp(var->name, "context"))
ast_copy_string(context, var->value, sizeof(context));
else if (!strcasecmp(var->name, "externip"))
@ -1818,6 +1846,7 @@ static int jingle_load_config(void)
member = ast_calloc(1, sizeof(*member));
ASTOBJ_INIT(member);
ASTOBJ_WRLOCK(member);
member->cap = ast_format_cap_alloc_nolock();
if (!strcasecmp(cat, "guest")) {
ast_copy_string(member->name, "guest", sizeof(member->name));
ast_copy_string(member->user, "guest", sizeof(member->user));
@ -1826,10 +1855,10 @@ static int jingle_load_config(void)
member->prefs = prefs;
while (var) {
if (!strcasecmp(var->name, "disallow"))
ast_parse_allow_disallow(&member->prefs, &member->capability,
ast_parse_allow_disallow(&member->prefs, member->cap,
var->value, 0);
else if (!strcasecmp(var->name, "allow"))
ast_parse_allow_disallow(&member->prefs, &member->capability,
ast_parse_allow_disallow(&member->prefs, member->cap,
var->value, 1);
else if (!strcasecmp(var->name, "context"))
ast_copy_string(member->context, var->value,
@ -1884,8 +1913,23 @@ static int load_module(void)
{
struct ast_sockaddr ourip_tmp;
struct ast_sockaddr bindaddr_tmp;
struct ast_format tmpfmt;
char *jabber_loaded = ast_module_helper("", "res_jabber.so", 0, 0, 0, 0);
if (!(jingle_tech.capabilities = ast_format_cap_alloc())) {
return AST_MODULE_LOAD_DECLINE;
}
ast_format_cap_add_all_by_type(jingle_tech.capabilities, AST_FORMAT_TYPE_AUDIO);
if (!(global_capability = ast_format_cap_alloc())) {
return AST_MODULE_LOAD_DECLINE;
}
ast_format_cap_add(global_capability, ast_format_set(&tmpfmt, AST_FORMAT_ULAW, 0));
ast_format_cap_add(global_capability, ast_format_set(&tmpfmt, AST_FORMAT_GSM, 0));
ast_format_cap_add(global_capability, ast_format_set(&tmpfmt, AST_FORMAT_ALAW, 0));
ast_format_cap_add(global_capability, ast_format_set(&tmpfmt, AST_FORMAT_H263, 0));
free(jabber_loaded);
if (!jabber_loaded) {
/* Dependency module has a different name, if embedded */
@ -1965,6 +2009,8 @@ static int unload_module(void)
}
ASTOBJ_CONTAINER_DESTROYALL(&jingle_list, jingle_member_destroy);
ASTOBJ_CONTAINER_DESTROY(&jingle_list);
global_capability = ast_format_cap_destroy(global_capability);
return 0;
}

View File

@ -88,7 +88,7 @@ static struct ast_jb_conf g_jb_conf = {
.target_extra = -1,
};
static struct ast_channel *local_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause);
static struct ast_channel *local_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, void *data, int *cause);
static int local_digit_begin(struct ast_channel *ast, char digit);
static int local_digit_end(struct ast_channel *ast, char digit, unsigned int duration);
static int local_call(struct ast_channel *ast, char *dest, int timeout);
@ -106,10 +106,9 @@ static int local_queryoption(struct ast_channel *ast, int option, void *data, in
static int local_setoption(struct ast_channel *chan, int option, void *data, int datalen);
/* PBX interface structure for channel registration */
static const struct ast_channel_tech local_tech = {
static struct ast_channel_tech local_tech = {
.type = "Local",
.description = tdesc,
.capabilities = -1,
.requester = local_request,
.send_digit_begin = local_digit_begin,
.send_digit_end = local_digit_end,
@ -138,15 +137,15 @@ static const struct ast_channel_tech local_tech = {
*/
struct local_pvt {
unsigned int flags; /*!< Private flags */
char context[AST_MAX_CONTEXT]; /*!< Context to call */
char exten[AST_MAX_EXTENSION]; /*!< Extension to call */
format_t reqformat; /*!< Requested format */
struct ast_jb_conf jb_conf; /*!< jitterbuffer configuration for this local channel */
struct ast_channel *owner; /*!< Master Channel - Bridging happens here */
struct ast_channel *chan; /*!< Outbound channel - PBX is run here */
struct ast_module_user *u_owner; /*!< reference to keep the module loaded while in use */
struct ast_module_user *u_chan; /*!< reference to keep the module loaded while in use */
unsigned int flags; /*!< Private flags */
char context[AST_MAX_CONTEXT]; /*!< Context to call */
char exten[AST_MAX_EXTENSION]; /*!< Extension to call */
struct ast_format_cap *reqcap; /*!< Requested format capabilities */
struct ast_jb_conf jb_conf; /*!< jitterbuffer configuration for this local channel */
struct ast_channel *owner; /*!< Master Channel - Bridging happens here */
struct ast_channel *chan; /*!< Outbound channel - PBX is run here */
struct ast_module_user *u_owner;/*!< reference to keep the module loaded while in use */
struct ast_module_user *u_chan; /*!< reference to keep the module loaded while in use */
};
#define LOCAL_ALREADY_MASQED (1 << 0) /*!< Already masqueraded */
@ -954,13 +953,23 @@ static int local_hangup(struct ast_channel *ast)
return 0;
}
static void local_destroy(void *obj)
{
struct local_pvt *pvt = obj;
pvt->reqcap = ast_format_cap_destroy(pvt->reqcap);
}
/*! \brief Create a call structure */
static struct local_pvt *local_alloc(const char *data, format_t format)
static struct local_pvt *local_alloc(const char *data, struct ast_format_cap *cap)
{
struct local_pvt *tmp = NULL;
char *c = NULL, *opts = NULL;
if (!(tmp = ao2_alloc(sizeof(*tmp), NULL))) {
if (!(tmp = ao2_alloc(sizeof(*tmp), local_destroy))) {
return NULL;
}
if (!(tmp->reqcap = ast_format_cap_dup(cap))) {
ao2_ref(tmp, -1);
return NULL;
}
@ -995,9 +1004,6 @@ static struct local_pvt *local_alloc(const char *data, format_t format)
*c++ = '\0';
ast_copy_string(tmp->context, c ? c : "default", sizeof(tmp->context));
tmp->reqformat = format;
#if 0
/* We can't do this check here, because we don't know the CallerID yet, and
* the CallerID could potentially affect what step is actually taken (or
@ -1019,7 +1025,8 @@ static struct local_pvt *local_alloc(const char *data, format_t format)
static struct ast_channel *local_new(struct local_pvt *p, int state, const char *linkedid)
{
struct ast_channel *tmp = NULL, *tmp2 = NULL;
int randnum = ast_random() & 0xffff, fmt = 0;
int randnum = ast_random() & 0xffff;
struct ast_format fmt;
const char *t;
int ama;
@ -1045,19 +1052,19 @@ static struct ast_channel *local_new(struct local_pvt *p, int state, const char
tmp2->tech = tmp->tech = &local_tech;
tmp->nativeformats = p->reqformat;
tmp2->nativeformats = p->reqformat;
ast_format_cap_copy(tmp->nativeformats, p->reqcap);
ast_format_cap_copy(tmp2->nativeformats, p->reqcap);
/* Determine our read/write format and set it on each channel */
fmt = ast_best_codec(p->reqformat);
tmp->writeformat = fmt;
tmp2->writeformat = fmt;
tmp->rawwriteformat = fmt;
tmp2->rawwriteformat = fmt;
tmp->readformat = fmt;
tmp2->readformat = fmt;
tmp->rawreadformat = fmt;
tmp2->rawreadformat = fmt;
ast_best_codec(p->reqcap, &fmt);
ast_format_copy(&tmp->writeformat, &fmt);
ast_format_copy(&tmp2->writeformat, &fmt);
ast_format_copy(&tmp->rawwriteformat, &fmt);
ast_format_copy(&tmp2->rawwriteformat, &fmt);
ast_format_copy(&tmp->readformat, &fmt);
ast_format_copy(&tmp2->readformat, &fmt);
ast_format_copy(&tmp->rawreadformat, &fmt);
ast_format_copy(&tmp2->rawreadformat, &fmt);
tmp->tech_pvt = p;
tmp2->tech_pvt = p;
@ -1079,13 +1086,13 @@ static struct ast_channel *local_new(struct local_pvt *p, int state, const char
}
/*! \brief Part of PBX interface */
static struct ast_channel *local_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause)
static struct ast_channel *local_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, void *data, int *cause)
{
struct local_pvt *p = NULL;
struct ast_channel *chan = NULL;
/* Allocate a new private structure and then Asterisk channel */
if ((p = local_alloc(data, format))) {
if ((p = local_alloc(data, cap))) {
if (!(chan = local_new(p, AST_STATE_DOWN, requestor ? requestor->linkedid : NULL))) {
ao2_unlink(locals, p);
}
@ -1197,7 +1204,13 @@ static int locals_cmp_cb(void *obj, void *arg, int flags)
/*! \brief Load module into PBX, register channel */
static int load_module(void)
{
if (!(local_tech.capabilities = ast_format_cap_alloc())) {
return AST_MODULE_LOAD_FAILURE;
}
ast_format_cap_add_all(local_tech.capabilities);
if (!(locals = ao2_container_alloc(BUCKET_SIZE, NULL, locals_cmp_cb))) {
ast_format_cap_destroy(local_tech.capabilities);
return AST_MODULE_LOAD_FAILURE;
}
@ -1205,6 +1218,7 @@ static int load_module(void)
if (ast_channel_register(&local_tech)) {
ast_log(LOG_ERROR, "Unable to register channel class 'Local'\n");
ao2_ref(locals, -1);
ast_format_cap_destroy(local_tech.capabilities);
return AST_MODULE_LOAD_FAILURE;
}
ast_cli_register_multiple(cli_local, sizeof(cli_local) / sizeof(struct ast_cli_entry));
@ -1234,6 +1248,7 @@ static int unload_module(void)
ao2_iterator_destroy(&it);
ao2_ref(locals, -1);
ast_format_cap_destroy(local_tech.capabilities);
return 0;
}

View File

@ -222,7 +222,7 @@ static pthread_t monitor_thread = AST_PTHREADT_NULL;
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];
@ -361,7 +361,7 @@ struct mgcp_endpoint {
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 */
@ -429,7 +429,7 @@ static int transmit_notify_request(struct mgcp_subchannel *sub, char *tone);
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);
@ -439,7 +439,7 @@ static void dump_cmd_queues(struct mgcp_endpoint *p, 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 struct ast_channel *mgcp_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, void *data, int *cause);
static int mgcp_call(struct ast_channel *ast, char *dest, int timeout);
static int mgcp_hangup(struct ast_channel *ast);
static int mgcp_answer(struct ast_channel *ast);
@ -458,10 +458,9 @@ static int acf_channel_read(struct ast_channel *chan, const char *funcname, char
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,
@ -1208,11 +1207,11 @@ static struct ast_frame *mgcp_rtp_read(struct mgcp_subchannel *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(sub->owner->nativeformats, &f->subclass.format)) {
ast_debug(1, "Oooh, format changed to %s\n", ast_getformatname(&f->subclass.format));
ast_format_cap_set(sub->owner->nativeformats, &f->subclass.format);
ast_set_read_format(sub->owner, &sub->owner->readformat);
ast_set_write_format(sub->owner, &sub->owner->writeformat);
}
/* Courtesy fearnor aka alex@pilosoft.com */
if ((sub->parent->dtmfmode & MGCP_DTMF_INBAND) && (sub->parent->dsp)) {
@ -1251,12 +1250,12 @@ static int mgcp_write(struct ast_channel *ast, struct ast_frame *frame)
return 0;
}
} else {
if (!(frame->subclass.codec & ast->nativeformats)) {
if (!(ast_format_cap_iscompatible(ast->nativeformats, &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(&frame->subclass.format),
ast_getformatname_multiple(buf, sizeof(buf), ast->nativeformats),
ast_getformatname(ast->readformat),
ast_getformatname(ast->writeformat));
ast_getformatname(&ast->readformat),
ast_getformatname(&ast->writeformat));
/* return -1; */
}
}
@ -1489,16 +1488,15 @@ static struct ast_channel *mgcp_new(struct mgcp_subchannel *sub, int state, cons
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_format_cap_copy(tmp->nativeformats, i->cap);
if (ast_format_cap_is_empty(tmp->nativeformats)) {
ast_format_cap_copy(tmp->nativeformats, global_capability);
}
fmt = ast_best_codec(tmp->nativeformats);
if (sub->rtp) {
ast_channel_set_fd(tmp, 0, ast_rtp_instance_fd(sub->rtp, 0));
}
@ -1512,10 +1510,12 @@ static struct ast_channel *mgcp_new(struct mgcp_subchannel *sub, int state, cons
}
if (state == AST_STATE_RING)
tmp->rings = 1;
tmp->writeformat = fmt;
tmp->rawwriteformat = fmt;
tmp->readformat = fmt;
tmp->rawreadformat = fmt;
ast_best_codec(tmp->nativeformats, &tmpfmt);
ast_format_copy(&tmp->writeformat, &tmpfmt);
ast_format_copy(&tmp->rawwriteformat, &tmpfmt);
ast_format_copy(&tmp->readformat, &tmpfmt);
ast_format_copy(&tmp->rawreadformat, &tmpfmt);
tmp->tech_pvt = sub;
if (!ast_strlen_zero(i->language))
ast_string_field_set(tmp, language, i->language);
@ -1954,7 +1954,7 @@ static int process_sdp(struct mgcp_subchannel *sub, struct mgcp_request *req)
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;
@ -2020,15 +2020,20 @@ static int process_sdp(struct mgcp_subchannel *sub, struct mgcp_request *req)
}
/* 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;
}
@ -2181,7 +2186,8 @@ static int add_sdp(struct mgcp_request *resp, struct mgcp_subchannel *sub, struc
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;
@ -2215,30 +2221,34 @@ static int add_sdp(struct mgcp_request *resp, struct mgcp_subchannel *sub, struc
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,
@ -2262,13 +2272,13 @@ static int add_sdp(struct mgcp_request *resp, struct mgcp_subchannel *sub, struc
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) {
@ -2279,16 +2289,18 @@ static int transmit_modify_with_sdp(struct mgcp_subchannel *sub, struct ast_rtp_
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) {
@ -2324,7 +2336,7 @@ static int transmit_connect_with_sdp(struct mgcp_subchannel *sub, struct ast_rtp
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",
@ -2332,16 +2344,18 @@ static int transmit_connect_with_sdp(struct mgcp_subchannel *sub, struct ast_rtp
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) {
@ -2419,17 +2433,19 @@ static int transmit_connect(struct mgcp_subchannel *sub)
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);
@ -2522,7 +2538,7 @@ static int transmit_modify_request(struct mgcp_subchannel *sub)
{
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];
@ -2536,18 +2552,18 @@ static int transmit_modify_request(struct mgcp_subchannel *sub)
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) {
@ -3899,18 +3915,15 @@ static int restart_monitor(void)
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, void *data, 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));
@ -4138,6 +4151,7 @@ static struct mgcp_gateway *build_gateway(char *cat, struct ast_variable *v)
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;
}
@ -4167,7 +4181,7 @@ static struct mgcp_gateway *build_gateway(char *cat, struct ast_variable *v)
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;
@ -4249,6 +4263,7 @@ static struct mgcp_gateway *build_gateway(char *cat, struct ast_variable *v)
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;
}
@ -4270,7 +4285,7 @@ static struct mgcp_gateway *build_gateway(char *cat, struct ast_variable *v)
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;
@ -4410,23 +4425,23 @@ static enum ast_rtp_glue_result mgcp_get_rtp_peer(struct ast_channel *chan, stru
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;
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_endpoint *p = sub->parent;
return p->capability;
ast_format_cap_copy(result, p->cap);
}
static struct ast_rtp_glue mgcp_rtp_glue = {
@ -4511,6 +4526,7 @@ static void destroy_endpoint(struct mgcp_endpoint *e)
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);
}
@ -4608,7 +4624,7 @@ static int reload_config(int reload)
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)) {
@ -4648,18 +4664,18 @@ static int reload_config(int reload)
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)) {
@ -4776,6 +4792,17 @@ static int reload_config(int reload)
/*! \brief load_module: PBX load module - initialization ---*/
static int load_module(void)
{
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;
@ -4907,6 +4934,9 @@ static int unload_module(void)
ast_cli_unregister_multiple(cli_mgcp, sizeof(cli_mgcp) / sizeof(struct ast_cli_entry));
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;
}

View File

@ -90,6 +90,8 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include "asterisk/stringfields.h"
#include "asterisk/abstract_jb.h"
#include "asterisk/causes.h"
#include "asterisk/format.h"
#include "asterisk/format_cap.h"
#include "chan_misdn_config.h"
#include "isdn_lib.h"
@ -645,7 +647,7 @@ static int *misdn_ports;
static void chan_misdn_log(int level, int port, char *tmpl, ...)
__attribute__((format(printf, 3, 4)));
static struct ast_channel *misdn_new(struct chan_list *cl, int state, char *exten, char *callerid, int format, const char *linkedid, int port, int c);
static struct ast_channel *misdn_new(struct chan_list *cl, int state, char *exten, char *callerid, struct ast_format_cap *cap, const char *linkedid, int port, int c);
static void send_digit_to_chan(struct chan_list *cl, char digit);
static int pbx_start_chan(struct chan_list *ch);
@ -661,7 +663,7 @@ static const char misdn_type[] = "mISDN";
static int tracing = 0;
/*! \brief Only alaw and mulaw is allowed for now */
static int prefformat = AST_FORMAT_ALAW ; /* AST_FORMAT_SLINEAR ; AST_FORMAT_ULAW | */
static struct ast_format prefformat; /* AST_FORMAT_SLINEAR ; AST_FORMAT_ULAW | */
static int *misdn_debug;
static int *misdn_debug_only;
@ -7346,7 +7348,7 @@ static struct ast_frame *misdn_read(struct ast_channel *ast)
}
tmp->frame.frametype = AST_FRAME_VOICE;
tmp->frame.subclass.codec = AST_FORMAT_ALAW;
ast_format_set(&tmp->frame.subclass.format, AST_FORMAT_ALAW, 0);
tmp->frame.datalen = len;
tmp->frame.samples = len;
tmp->frame.mallocd = 0;
@ -7412,13 +7414,13 @@ static int misdn_write(struct ast_channel *ast, struct ast_frame *frame)
}
if (!frame->subclass.codec) {
if (!frame->subclass.format.id) {
chan_misdn_log(4, ch->bc->port, "misdn_write: * prods us\n");
return 0;
}
if (!(frame->subclass.codec & prefformat)) {
chan_misdn_log(-1, ch->bc->port, "Got Unsupported Frame with Format:%s\n", ast_getformatname(frame->subclass.codec));
if (ast_format_cmp(&frame->subclass.format, &prefformat) == AST_FORMAT_CMP_NOT_EQUAL) {
chan_misdn_log(-1, ch->bc->port, "Got Unsupported Frame with Format:%s\n", ast_getformatname(&frame->subclass.format));
return 0;
}
@ -7756,7 +7758,7 @@ static struct chan_list *chan_list_init(int orig)
return cl;
}
static struct ast_channel *misdn_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause)
static struct ast_channel *misdn_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, void *data, int *cause)
{
struct ast_channel *ast;
char group[BUFFERSIZE + 1] = "";
@ -7982,7 +7984,7 @@ static struct ast_channel *misdn_request(const char *type, format_t format, cons
}
cl->bc = newbc;
ast = misdn_new(cl, AST_STATE_RESERVED, args.ext, NULL, format, requestor ? requestor->linkedid : NULL, port, channel);
ast = misdn_new(cl, AST_STATE_RESERVED, args.ext, NULL, cap, requestor ? requestor->linkedid : NULL, port, channel);
if (!ast) {
chan_list_unref(cl, "Failed to create a new channel");
ast_log(LOG_ERROR, "Could not create Asterisk channel for Dial(%s)\n", dial_str);
@ -8025,7 +8027,6 @@ static int misdn_send_text(struct ast_channel *chan, const char *text)
static struct ast_channel_tech misdn_tech = {
.type = misdn_type,
.description = "Channel driver for mISDN Support (Bri/Pri)",
.capabilities = AST_FORMAT_ALAW ,
.requester = misdn_request,
.send_digit_begin = misdn_digit_begin,
.send_digit_end = misdn_digit_end,
@ -8044,7 +8045,6 @@ static struct ast_channel_tech misdn_tech = {
static struct ast_channel_tech misdn_tech_wo_bridge = {
.type = misdn_type,
.description = "Channel driver for mISDN Support (Bri/Pri)",
.capabilities = AST_FORMAT_ALAW ,
.requester = misdn_request,
.send_digit_begin = misdn_digit_begin,
.send_digit_end = misdn_digit_end,
@ -8086,7 +8086,7 @@ static void update_name(struct ast_channel *tmp, int port, int c)
}
}
static struct ast_channel *misdn_new(struct chan_list *chlist, int state, char *exten, char *callerid, int format, const char *linkedid, int port, int c)
static struct ast_channel *misdn_new(struct chan_list *chlist, int state, char *exten, char *callerid, struct ast_format_cap *cap, const char *linkedid, int port, int c)
{
struct ast_channel *tmp;
char *cid_name = NULL;
@ -8094,6 +8094,7 @@ static struct ast_channel *misdn_new(struct chan_list *chlist, int state, char
int chan_offset = 0;
int tmp_port = misdn_cfg_get_next_port(0);
int bridging;
struct ast_format tmpfmt;
for (; tmp_port > 0; tmp_port = misdn_cfg_get_next_port(tmp_port)) {
if (tmp_port == port) {
@ -8113,12 +8114,12 @@ static struct ast_channel *misdn_new(struct chan_list *chlist, int state, char
if (tmp) {
chan_misdn_log(2, 0, " --> * NEW CHANNEL dialed:%s caller:%s\n", exten, callerid);
tmp->nativeformats = prefformat;
tmp->readformat = format;
tmp->rawreadformat = format;
tmp->writeformat = format;
tmp->rawwriteformat = format;
ast_best_codec(cap, &tmpfmt);
ast_format_cap_add(tmp->nativeformats, &prefformat);
ast_format_copy(&tmp->writeformat, &tmpfmt);
ast_format_copy(&tmp->rawwriteformat, &tmpfmt);
ast_format_copy(&tmp->readformat, &tmpfmt);
ast_format_copy(&tmp->rawreadformat, &tmpfmt);
/* Link the channel and private together */
chan_list_ref(chlist, "Give a reference to ast_channel");
@ -8128,8 +8129,6 @@ static struct ast_channel *misdn_new(struct chan_list *chlist, int state, char
misdn_cfg_get(0, MISDN_GEN_BRIDGING, &bridging, sizeof(bridging));
tmp->tech = bridging ? &misdn_tech : &misdn_tech_wo_bridge;
tmp->writeformat = format;
tmp->readformat = format;
tmp->priority = 1;
if (exten) {
@ -10116,7 +10115,16 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
ch->l3id = bc->l3_id;
ch->addr = bc->addr;
chan = misdn_new(ch, AST_STATE_RESERVED, bc->dialed.number, bc->caller.number, AST_FORMAT_ALAW, NULL, bc->port, bc->channel);
{
struct ast_format_cap *cap = ast_format_cap_alloc_nolock();
struct ast_format tmpfmt;
if (!(cap)) {
return RESPONSE_ERR;
}
ast_format_cap_add(cap, ast_format_set(&tmpfmt, AST_FORMAT_ALAW, 0));
chan = misdn_new(ch, AST_STATE_RESERVED, bc->dialed.number, bc->caller.number, cap, NULL, bc->port, bc->channel);
cap = ast_format_cap_destroy(cap);
}
if (!chan) {
chan_list_unref(ch, "Failed to create a new channel");
misdn_lib_send_event(bc,EVENT_RELEASE_COMPLETE);
@ -10723,7 +10731,7 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
/* In Data Modes we queue frames */
memset(&frame, 0, sizeof(frame));
frame.frametype = AST_FRAME_VOICE; /* we have no data frames yet */
frame.subclass.codec = AST_FORMAT_ALAW;
ast_format_set(&frame.subclass.format, AST_FORMAT_ALAW, 0);
frame.datalen = bc->bframe_len;
frame.samples = bc->bframe_len;
frame.mallocd = 0;
@ -11145,6 +11153,8 @@ static int unload_module(void)
#if defined(AST_MISDN_ENHANCEMENTS)
misdn_cc_destroy();
#endif /* defined(AST_MISDN_ENHANCEMENTS) */
misdn_tech.capabilities = ast_format_cap_destroy(misdn_tech.capabilities);
misdn_tech_wo_bridge.capabilities = ast_format_cap_destroy(misdn_tech_wo_bridge.capabilities);
return 0;
}
@ -11162,6 +11172,17 @@ static int load_module(void)
.cb_jb_empty = chan_misdn_jb_empty,
};
if (!(misdn_tech.capabilities = ast_format_cap_alloc())) {
return AST_MODULE_LOAD_DECLINE;
}
if (!(misdn_tech_wo_bridge.capabilities = ast_format_cap_alloc())) {
return AST_MODULE_LOAD_DECLINE;
}
ast_format_set(&prefformat, AST_FORMAT_ALAW, 0);
ast_format_cap_add(misdn_tech.capabilities, &prefformat);
ast_format_cap_add(misdn_tech_wo_bridge.capabilities, &prefformat);
max_ports = misdn_lib_maxports_get();
if (max_ports <= 0) {

View File

@ -52,17 +52,16 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
static const char tdesc[] = "Multicast RTP Paging Channel Driver";
/* Forward declarations */
static struct ast_channel *multicast_rtp_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause);
static struct ast_channel *multicast_rtp_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, void *data, int *cause);
static int multicast_rtp_call(struct ast_channel *ast, char *dest, int timeout);
static int multicast_rtp_hangup(struct ast_channel *ast);
static struct ast_frame *multicast_rtp_read(struct ast_channel *ast);
static int multicast_rtp_write(struct ast_channel *ast, struct ast_frame *f);
/* Channel driver declaration */
static const struct ast_channel_tech multicast_rtp_tech = {
static struct ast_channel_tech multicast_rtp_tech = {
.type = "MulticastRTP",
.description = tdesc,
.capabilities = -1,
.requester = multicast_rtp_request,
.call = multicast_rtp_call,
.hangup = multicast_rtp_hangup,
@ -107,14 +106,15 @@ static int multicast_rtp_hangup(struct ast_channel *ast)
}
/*! \brief Function called when we should prepare to call the destination */
static struct ast_channel *multicast_rtp_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause)
static struct ast_channel *multicast_rtp_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, void *data, int *cause)
{
char *tmp = ast_strdupa(data), *multicast_type = tmp, *destination, *control;
struct ast_rtp_instance *instance;
struct ast_sockaddr control_address;
struct ast_sockaddr destination_address;
struct ast_channel *chan;
format_t fmt = ast_best_codec(format);
struct ast_format fmt;
ast_best_codec(cap, &fmt);
ast_sockaddr_setnull(&control_address);
@ -153,11 +153,13 @@ static struct ast_channel *multicast_rtp_request(const char *type, format_t form
ast_rtp_instance_set_remote_address(instance, &destination_address);
chan->tech = &multicast_rtp_tech;
chan->nativeformats = fmt;
chan->writeformat = fmt;
chan->readformat = fmt;
chan->rawwriteformat = fmt;
chan->rawreadformat = fmt;
ast_format_cap_add(chan->nativeformats, &fmt);
ast_format_copy(&chan->writeformat, &fmt);
ast_format_copy(&chan->rawwriteformat, &fmt);
ast_format_copy(&chan->readformat, &fmt);
ast_format_copy(&chan->rawreadformat, &fmt);
chan->tech_pvt = instance;
return chan;
@ -170,6 +172,10 @@ failure:
/*! \brief Function called when our module is loaded */
static int load_module(void)
{
if (!(multicast_rtp_tech.capabilities = ast_format_cap_alloc())) {
return AST_MODULE_LOAD_DECLINE;
}
ast_format_cap_add_all(multicast_rtp_tech.capabilities);
if (ast_channel_register(&multicast_rtp_tech)) {
ast_log(LOG_ERROR, "Unable to register channel class 'MulticastRTP'\n");
return AST_MODULE_LOAD_DECLINE;
@ -182,6 +188,7 @@ static int load_module(void)
static int unload_module(void)
{
ast_channel_unregister(&multicast_rtp_tech);
multicast_rtp_tech.capabilities = ast_format_cap_destroy(multicast_rtp_tech.capabilities);
return 0;
}

View File

@ -50,7 +50,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
static const char tdesc[] = "Network Broadcast Sound Driver";
/* Only linear is allowed */
static format_t prefformat = AST_FORMAT_SLINEAR;
static struct ast_format prefformat;
static char context[AST_MAX_EXTENSION] = "default";
static const char type[] = "NBS";
@ -66,16 +66,15 @@ struct nbs_pvt {
struct ast_module_user *u; /*! for holding a reference to this module */
};
static struct ast_channel *nbs_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause);
static struct ast_channel *nbs_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, void *data, int *cause);
static int nbs_call(struct ast_channel *ast, char *dest, int timeout);
static int nbs_hangup(struct ast_channel *ast);
static struct ast_frame *nbs_xread(struct ast_channel *ast);
static int nbs_xwrite(struct ast_channel *ast, struct ast_frame *frame);
static const struct ast_channel_tech nbs_tech = {
static struct ast_channel_tech nbs_tech = {
.type = type,
.description = tdesc,
.capabilities = AST_FORMAT_SLINEAR,
.requester = nbs_request,
.call = nbs_call,
.hangup = nbs_hangup,
@ -205,9 +204,8 @@ static int nbs_xwrite(struct ast_channel *ast, struct ast_frame *frame)
ast_log(LOG_WARNING, "Don't know what to do with frame type '%d'\n", frame->frametype);
return 0;
}
if (!(frame->subclass.codec &
(AST_FORMAT_SLINEAR))) {
ast_log(LOG_WARNING, "Cannot handle frames in %s format\n", ast_getformatname(frame->subclass.codec));
if (frame->subclass.format.id != (AST_FORMAT_SLINEAR)) {
ast_log(LOG_WARNING, "Cannot handle frames in %s format\n", ast_getformatname(&frame->subclass.format));
return 0;
}
if (ast->_state != AST_STATE_UP) {
@ -226,11 +224,12 @@ static struct ast_channel *nbs_new(struct nbs_pvt *i, int state, const char *lin
if (tmp) {
tmp->tech = &nbs_tech;
ast_channel_set_fd(tmp, 0, nbs_fd(i->nbs));
tmp->nativeformats = prefformat;
tmp->rawreadformat = prefformat;
tmp->rawwriteformat = prefformat;
tmp->writeformat = prefformat;
tmp->readformat = prefformat;
ast_format_cap_add(tmp->nativeformats, &prefformat);
ast_format_copy(&tmp->rawreadformat, &prefformat);
ast_format_copy(&tmp->rawwriteformat, &prefformat);
ast_format_copy(&tmp->writeformat, &prefformat);
ast_format_copy(&tmp->readformat, &prefformat);
if (state == AST_STATE_RING)
tmp->rings = 1;
tmp->tech_pvt = i;
@ -251,16 +250,14 @@ static struct ast_channel *nbs_new(struct nbs_pvt *i, int state, const char *lin
}
static struct ast_channel *nbs_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause)
static struct ast_channel *nbs_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, void *data, int *cause)
{
format_t oldformat;
struct nbs_pvt *p;
struct ast_channel *tmp = NULL;
oldformat = format;
format &= (AST_FORMAT_SLINEAR);
if (!format) {
ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format '%s'\n", ast_getformatname(oldformat));
if (!(ast_format_cap_iscompatible(cap, &prefformat))) {
char tmp[256];
ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format '%s'\n", ast_getformatname_multiple(tmp, sizeof(tmp), cap));
return NULL;
}
p = nbs_alloc(data);
@ -276,11 +273,17 @@ static int unload_module(void)
{
/* First, take us out of the channel loop */
ast_channel_unregister(&nbs_tech);
nbs_tech.capabilities = ast_format_cap_destroy(nbs_tech.capabilities);
return 0;
}
static int load_module(void)
{
ast_format_set(&prefformat, AST_FORMAT_SLINEAR, 0);
if (!(nbs_tech.capabilities == ast_format_cap_alloc())) {
return -1;
}
ast_format_cap_add(nbs_tech.capabilities, &prefformat);
/* Make sure we can register our channel type */
if (ast_channel_register(&nbs_tech)) {
ast_log(LOG_ERROR, "Unable to register channel class %s\n", type);

View File

@ -326,7 +326,7 @@ static struct chan_oss_pvt oss_default = {
static int setformat(struct chan_oss_pvt *o, int mode);
static struct ast_channel *oss_request(const char *type, format_t format, const struct ast_channel *requestor,
static struct ast_channel *oss_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor,
void *data, int *cause);
static int oss_digit_begin(struct ast_channel *c, char digit);
static int oss_digit_end(struct ast_channel *c, char digit, unsigned int duration);
@ -344,7 +344,6 @@ static char tdesc[] = "OSS Console Channel Driver";
static struct ast_channel_tech oss_tech = {
.type = "Console",
.description = tdesc,
.capabilities = AST_FORMAT_SLINEAR, /* overwritten later */
.requester = oss_request,
.send_digit_begin = oss_digit_begin,
.send_digit_end = oss_digit_end,
@ -719,7 +718,7 @@ static struct ast_frame *oss_read(struct ast_channel *c)
return f;
/* ok we can build and deliver the frame to the caller */
f->frametype = AST_FRAME_VOICE;
f->subclass.codec = AST_FORMAT_SLINEAR;
ast_format_set(&f->subclass.format, AST_FORMAT_SLINEAR, 0);
f->samples = FRAME_SIZE;
f->datalen = FRAME_SIZE * 2;
f->data.ptr = o->oss_read_buf + AST_FRIENDLY_OFFSET;
@ -794,13 +793,15 @@ static struct ast_channel *oss_new(struct chan_oss_pvt *o, char *ext, char *ctx,
if (o->sounddev < 0)
setformat(o, O_RDWR);
ast_channel_set_fd(c, 0, o->sounddev); /* -1 if device closed, override later */
c->nativeformats = AST_FORMAT_SLINEAR;
/* if the console makes the call, add video to the offer */
if (state == AST_STATE_RINGING)
c->nativeformats |= console_video_formats;
c->readformat = AST_FORMAT_SLINEAR;
c->writeformat = AST_FORMAT_SLINEAR;
ast_format_set(&c->readformat, AST_FORMAT_SLINEAR, 0);
ast_format_set(&c->writeformat, AST_FORMAT_SLINEAR, 0);
ast_format_cap_add(c->nativeformats, &c->readformat);
/* if the console makes the call, add video to the offer */
/* if (state == AST_STATE_RINGING) TODO XXX CONSOLE VIDEO IS DISABLED UNTIL IT GETS A MAINTAINER
c->nativeformats |= console_video_formats; */
c->tech_pvt = o;
if (!ast_strlen_zero(o->language))
@ -830,7 +831,7 @@ static struct ast_channel *oss_new(struct chan_oss_pvt *o, char *ext, char *ctx,
return c;
}
static struct ast_channel *oss_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause)
static struct ast_channel *oss_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, void *data, int *cause)
{
struct ast_channel *c;
struct chan_oss_pvt *o;
@ -840,6 +841,7 @@ static struct ast_channel *oss_request(const char *type, format_t format, const
);
char *parse = ast_strdupa(data);
char buf[256];
struct ast_format tmpfmt;
AST_NONSTANDARD_APP_ARGS(args, parse, '/');
o = find_desc(args.name);
@ -850,8 +852,8 @@ static struct ast_channel *oss_request(const char *type, format_t format, const
/* XXX we could default to 'dsp' perhaps ? */
return NULL;
}
if ((format & AST_FORMAT_SLINEAR) == 0) {
ast_log(LOG_NOTICE, "Format %s unsupported\n", ast_getformatname_multiple(buf, sizeof(buf), format));
if (!(ast_format_cap_iscompatible(cap, ast_format_set(&tmpfmt, AST_FORMAT_SLINEAR, 0)))) {
ast_log(LOG_NOTICE, "Format %s unsupported\n", ast_getformatname_multiple(buf, sizeof(buf), cap));
return NULL;
}
if (o->owner) {
@ -1437,6 +1439,7 @@ static int load_module(void)
struct ast_config *cfg = NULL;
char *ctg = NULL;
struct ast_flags config_flags = { 0 };
struct ast_format tmpfmt;
/* Copy the default jb config over global_jbconf */
memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf));
@ -1463,7 +1466,13 @@ static int load_module(void)
return AST_MODULE_LOAD_FAILURE;
}
oss_tech.capabilities |= console_video_formats;
if (!(oss_tech.capabilities = ast_format_cap_alloc())) {
return AST_MODULE_LOAD_FAILURE;
}
ast_format_cap_add(oss_tech.capabilities, ast_format_set(&tmpfmt, AST_FORMAT_SLINEAR, 0));
/* TODO XXX CONSOLE VIDEO IS DISABLE UNTIL IT HAS A MAINTAINER
* add console_video_formats to oss_tech.capabilities once this occurs. */
if (ast_channel_register(&oss_tech)) {
ast_log(LOG_ERROR, "Unable to register channel type 'OSS'\n");
@ -1495,6 +1504,7 @@ static int unload_module(void)
ast_free(o);
o = next;
}
oss_tech.capabilities = ast_format_cap_destroy(oss_tech.capabilities);
return 0;
}

View File

@ -94,7 +94,7 @@ static int echocancel = AEC_OFF;
static int silencesupression = 0;
static format_t prefformat = AST_FORMAT_G729A | AST_FORMAT_G723_1 | AST_FORMAT_SLINEAR | AST_FORMAT_ULAW;
static struct ast_format_cap *prefcap;
/* Protect the interface list (of phone_pvt's) */
AST_MUTEX_DEFINE_STATIC(iflock);
@ -125,8 +125,8 @@ static struct phone_pvt {
int fd; /* Raw file descriptor for this device */
struct ast_channel *owner; /* Channel we belong to, possibly NULL */
int mode; /* Is this in the */
format_t lastformat; /* Last output format */
format_t lastinput; /* Last input format */
struct ast_format lastformat; /* Last output format */
struct ast_format lastinput; /* Last input format */
int ministate; /* Miniature state, for dialtone mode */
char dev[256]; /* Device name */
struct phone_pvt *next; /* Next channel in list */
@ -150,7 +150,7 @@ static struct phone_pvt {
static char cid_num[AST_MAX_EXTENSION];
static char cid_name[AST_MAX_EXTENSION];
static struct ast_channel *phone_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause);
static struct ast_channel *phone_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, void *data, int *cause);
static int phone_digit_begin(struct ast_channel *ast, char digit);
static int phone_digit_end(struct ast_channel *ast, char digit, unsigned int duration);
static int phone_call(struct ast_channel *ast, char *dest, int timeout);
@ -163,10 +163,9 @@ static int phone_send_text(struct ast_channel *ast, const char *text);
static int phone_fixup(struct ast_channel *old, struct ast_channel *new);
static int phone_indicate(struct ast_channel *chan, int condition, const void *data, size_t datalen);
static const struct ast_channel_tech phone_tech = {
static struct ast_channel_tech phone_tech = {
.type = "Phone",
.description = tdesc,
.capabilities = AST_FORMAT_G723_1 | AST_FORMAT_SLINEAR | AST_FORMAT_ULAW | AST_FORMAT_G729A,
.requester = phone_request,
.send_digit_begin = phone_digit_begin,
.send_digit_end = phone_digit_end,
@ -210,9 +209,9 @@ static int phone_indicate(struct ast_channel *chan, int condition, const void *d
ioctl(p->fd, IXJCTL_PSTN_SET_STATE, PSTN_ON_HOOK);
usleep(320000);
ioctl(p->fd, IXJCTL_PSTN_SET_STATE, PSTN_OFF_HOOK);
p->lastformat = -1;
res = 0;
break;
ast_format_clear(&p->lastformat);
res = 0;
break;
case AST_CONTROL_HOLD:
ast_moh_start(chan, data, NULL);
break;
@ -272,7 +271,7 @@ static int phone_digit_end(struct ast_channel *ast, char digit, unsigned int dur
ioctl(p->fd, IXJCTL_PSTN_SET_STATE, PSTN_ON_HOOK);
usleep(320000);
ioctl(p->fd, IXJCTL_PSTN_SET_STATE, PSTN_OFF_HOOK);
p->lastformat = -1;
ast_format_clear(&p->lastformat);
return 0;
default:
ast_log(LOG_WARNING, "Unknown digit '%c'\n", digit);
@ -280,7 +279,7 @@ static int phone_digit_end(struct ast_channel *ast, char digit, unsigned int dur
}
ast_debug(1, "Dialed %d\n", outdigit);
ioctl(p->fd, PHONE_PLAY_TONE, outdigit);
p->lastformat = -1;
ast_format_clear(&p->lastformat);
return 0;
}
@ -373,8 +372,8 @@ static int phone_hangup(struct ast_channel *ast)
ioctl(p->fd, PHONE_BUSY);
p->cpt = 1;
}
p->lastformat = -1;
p->lastinput = -1;
ast_format_clear(&p->lastformat);
ast_format_clear(&p->lastinput);
p->ministate = 0;
p->obuflen = 0;
p->dialtone = 0;
@ -394,38 +393,38 @@ static int phone_setup(struct ast_channel *ast)
p = ast->tech_pvt;
ioctl(p->fd, PHONE_CPT_STOP);
/* Nothing to answering really, just start recording */
if (ast->rawreadformat == AST_FORMAT_G729A) {
if (ast->rawreadformat.id == AST_FORMAT_G729A) {
/* Prefer g729 */
ioctl(p->fd, PHONE_REC_STOP);
if (p->lastinput != AST_FORMAT_G729A) {
p->lastinput = AST_FORMAT_G729A;
if (p->lastinput.id != AST_FORMAT_G729A) {
ast_format_set(&p->lastinput, AST_FORMAT_G729A, 0);
if (ioctl(p->fd, PHONE_REC_CODEC, G729)) {
ast_log(LOG_WARNING, "Failed to set codec to g729\n");
return -1;
}
}
} else if (ast->rawreadformat == AST_FORMAT_G723_1) {
} else if (ast->rawreadformat.id == AST_FORMAT_G723_1) {
ioctl(p->fd, PHONE_REC_STOP);
if (p->lastinput != AST_FORMAT_G723_1) {
p->lastinput = AST_FORMAT_G723_1;
if (p->lastinput.id != AST_FORMAT_G723_1) {
ast_format_set(&p->lastinput, AST_FORMAT_G723_1, 0);
if (ioctl(p->fd, PHONE_REC_CODEC, G723_63)) {
ast_log(LOG_WARNING, "Failed to set codec to g723.1\n");
return -1;
}
}
} else if (ast->rawreadformat == AST_FORMAT_SLINEAR) {
} else if (ast->rawreadformat.id == AST_FORMAT_SLINEAR) {
ioctl(p->fd, PHONE_REC_STOP);
if (p->lastinput != AST_FORMAT_SLINEAR) {
p->lastinput = AST_FORMAT_SLINEAR;
if (p->lastinput.id != AST_FORMAT_SLINEAR) {
ast_format_set(&p->lastinput, AST_FORMAT_SLINEAR, 0);
if (ioctl(p->fd, PHONE_REC_CODEC, LINEAR16)) {
ast_log(LOG_WARNING, "Failed to set codec to signed linear 16\n");
return -1;
}
}
} else if (ast->rawreadformat == AST_FORMAT_ULAW) {
} else if (ast->rawreadformat.id == AST_FORMAT_ULAW) {
ioctl(p->fd, PHONE_REC_STOP);
if (p->lastinput != AST_FORMAT_ULAW) {
p->lastinput = AST_FORMAT_ULAW;
if (p->lastinput.id != AST_FORMAT_ULAW) {
ast_format_set(&p->lastinput, AST_FORMAT_ULAW, 0);
if (ioctl(p->fd, PHONE_REC_CODEC, ULAW)) {
ast_log(LOG_WARNING, "Failed to set codec to uLaw\n");
return -1;
@ -433,16 +432,16 @@ static int phone_setup(struct ast_channel *ast)
}
} else if (p->mode == MODE_FXS) {
ioctl(p->fd, PHONE_REC_STOP);
if (p->lastinput != ast->rawreadformat) {
p->lastinput = ast->rawreadformat;
if (ioctl(p->fd, PHONE_REC_CODEC, ast->rawreadformat)) {
if (ast_format_cmp(&p->lastinput, &ast->rawreadformat) == AST_FORMAT_CMP_NOT_EQUAL) {
ast_format_copy(&p->lastinput, &ast->rawreadformat);
if (ioctl(p->fd, PHONE_REC_CODEC, &ast->rawreadformat)) {
ast_log(LOG_WARNING, "Failed to set codec to %s\n",
ast_getformatname(ast->rawreadformat));
ast_getformatname(&ast->rawreadformat));
return -1;
}
}
} else {
ast_log(LOG_WARNING, "Can't do format %s\n", ast_getformatname(ast->rawreadformat));
ast_log(LOG_WARNING, "Can't do format %s\n", ast_getformatname(&ast->rawreadformat));
return -1;
}
if (ioctl(p->fd, PHONE_REC_START)) {
@ -593,14 +592,13 @@ static struct ast_frame *phone_read(struct ast_channel *ast)
}
p->fr.samples = 240;
p->fr.datalen = res;
p->fr.frametype = p->lastinput <= AST_FORMAT_AUDIO_MASK ?
AST_FRAME_VOICE :
p->lastinput <= AST_FORMAT_PNG ? AST_FRAME_IMAGE
: AST_FRAME_VIDEO;
p->fr.subclass.codec = p->lastinput;
p->fr.frametype = AST_FORMAT_GET_TYPE(p->lastinput.id) == AST_FORMAT_TYPE_AUDIO ?
AST_FRAME_VOICE : AST_FORMAT_GET_TYPE(p->lastinput.id) == AST_FORMAT_TYPE_IMAGE ?
AST_FRAME_IMAGE : AST_FRAME_VIDEO;
ast_format_copy(&p->fr.subclass.format, &p->lastinput);
p->fr.offset = AST_FRIENDLY_OFFSET;
/* Byteswap from little-endian to native-endian */
if (p->fr.subclass.codec == AST_FORMAT_SLINEAR)
if (p->fr.subclass.format.id == AST_FORMAT_SLINEAR)
ast_frame_byteswap_le(&p->fr);
return &p->fr;
}
@ -662,10 +660,12 @@ static int phone_write(struct ast_channel *ast, struct ast_frame *frame)
ast_log(LOG_WARNING, "Don't know what to do with frame type '%d'\n", frame->frametype);
return 0;
}
if (!(frame->subclass.codec &
(AST_FORMAT_G723_1 | AST_FORMAT_SLINEAR | AST_FORMAT_ULAW | AST_FORMAT_G729A)) &&
if (!(frame->subclass.format.id == AST_FORMAT_G723_1 ||
frame->subclass.format.id == AST_FORMAT_SLINEAR ||
frame->subclass.format.id == AST_FORMAT_ULAW ||
frame->subclass.format.id == AST_FORMAT_G729A) &&
p->mode != MODE_FXS) {
ast_log(LOG_WARNING, "Cannot handle frames in %s format\n", ast_getformatname(frame->subclass.codec));
ast_log(LOG_WARNING, "Cannot handle frames in %s format\n", ast_getformatname(&frame->subclass.format));
return -1;
}
#if 0
@ -680,8 +680,8 @@ static int phone_write(struct ast_channel *ast, struct ast_frame *frame)
return 0;
}
#endif
if (frame->subclass.codec == AST_FORMAT_G729A) {
if (p->lastformat != AST_FORMAT_G729A) {
if (frame->subclass.format.id == AST_FORMAT_G729A) {
if (p->lastformat.id != AST_FORMAT_G729A) {
ioctl(p->fd, PHONE_PLAY_STOP);
ioctl(p->fd, PHONE_REC_STOP);
if (ioctl(p->fd, PHONE_PLAY_CODEC, G729)) {
@ -692,8 +692,8 @@ static int phone_write(struct ast_channel *ast, struct ast_frame *frame)
ast_log(LOG_WARNING, "Unable to set G729 mode\n");
return -1;
}
p->lastformat = AST_FORMAT_G729A;
p->lastinput = AST_FORMAT_G729A;
ast_format_set(&p->lastformat, AST_FORMAT_G729A, 0);
ast_format_set(&p->lastinput, AST_FORMAT_G729A, 0);
/* Reset output buffer */
p->obuflen = 0;
codecset = 1;
@ -703,8 +703,8 @@ static int phone_write(struct ast_channel *ast, struct ast_frame *frame)
return -1;
}
maxfr = 80;
} else if (frame->subclass.codec == AST_FORMAT_G723_1) {
if (p->lastformat != AST_FORMAT_G723_1) {
} else if (frame->subclass.format.id == AST_FORMAT_G723_1) {
if (p->lastformat.id != AST_FORMAT_G723_1) {
ioctl(p->fd, PHONE_PLAY_STOP);
ioctl(p->fd, PHONE_REC_STOP);
if (ioctl(p->fd, PHONE_PLAY_CODEC, G723_63)) {
@ -715,8 +715,8 @@ static int phone_write(struct ast_channel *ast, struct ast_frame *frame)
ast_log(LOG_WARNING, "Unable to set G723.1 mode\n");
return -1;
}
p->lastformat = AST_FORMAT_G723_1;
p->lastinput = AST_FORMAT_G723_1;
ast_format_set(&p->lastformat, AST_FORMAT_G723_1, 0);
ast_format_set(&p->lastinput, AST_FORMAT_G723_1, 0);
/* Reset output buffer */
p->obuflen = 0;
codecset = 1;
@ -726,8 +726,8 @@ static int phone_write(struct ast_channel *ast, struct ast_frame *frame)
return -1;
}
maxfr = 24;
} else if (frame->subclass.codec == AST_FORMAT_SLINEAR) {
if (p->lastformat != AST_FORMAT_SLINEAR) {
} else if (frame->subclass.format.id == AST_FORMAT_SLINEAR) {
if (p->lastformat.id != AST_FORMAT_SLINEAR) {
ioctl(p->fd, PHONE_PLAY_STOP);
ioctl(p->fd, PHONE_REC_STOP);
if (ioctl(p->fd, PHONE_PLAY_CODEC, LINEAR16)) {
@ -738,15 +738,15 @@ static int phone_write(struct ast_channel *ast, struct ast_frame *frame)
ast_log(LOG_WARNING, "Unable to set 16-bit linear mode\n");
return -1;
}
p->lastformat = AST_FORMAT_SLINEAR;
p->lastinput = AST_FORMAT_SLINEAR;
ast_format_set(&p->lastformat, AST_FORMAT_SLINEAR, 0);
ast_format_set(&p->lastinput, AST_FORMAT_SLINEAR, 0);
codecset = 1;
/* Reset output buffer */
p->obuflen = 0;
}
maxfr = 480;
} else if (frame->subclass.codec == AST_FORMAT_ULAW) {
if (p->lastformat != AST_FORMAT_ULAW) {
} else if (frame->subclass.format.id == AST_FORMAT_ULAW) {
if (p->lastformat.id != AST_FORMAT_ULAW) {
ioctl(p->fd, PHONE_PLAY_STOP);
ioctl(p->fd, PHONE_REC_STOP);
if (ioctl(p->fd, PHONE_PLAY_CODEC, ULAW)) {
@ -757,29 +757,29 @@ static int phone_write(struct ast_channel *ast, struct ast_frame *frame)
ast_log(LOG_WARNING, "Unable to set uLaw mode\n");
return -1;
}
p->lastformat = AST_FORMAT_ULAW;
p->lastinput = AST_FORMAT_ULAW;
ast_format_set(&p->lastformat, AST_FORMAT_ULAW, 0);
ast_format_set(&p->lastinput, AST_FORMAT_ULAW, 0);
codecset = 1;
/* Reset output buffer */
p->obuflen = 0;
}
maxfr = 240;
} else {
if (p->lastformat != frame->subclass.codec) {
if (ast_format_cmp(&p->lastformat, &frame->subclass.format) != AST_FORMAT_CMP_EQUAL) {
ioctl(p->fd, PHONE_PLAY_STOP);
ioctl(p->fd, PHONE_REC_STOP);
if (ioctl(p->fd, PHONE_PLAY_CODEC, (int) frame->subclass.codec)) {
if (ioctl(p->fd, PHONE_PLAY_CODEC, (int) frame->subclass.format.id)) {
ast_log(LOG_WARNING, "Unable to set %s mode\n",
ast_getformatname(frame->subclass.codec));
ast_getformatname(&frame->subclass.format));
return -1;
}
if (ioctl(p->fd, PHONE_REC_CODEC, (int) frame->subclass.codec)) {
if (ioctl(p->fd, PHONE_REC_CODEC, (int) frame->subclass.format.id)) {
ast_log(LOG_WARNING, "Unable to set %s mode\n",
ast_getformatname(frame->subclass.codec));
ast_getformatname(&frame->subclass.format));
return -1;
}
p->lastformat = frame->subclass.codec;
p->lastinput = frame->subclass.codec;
ast_format_copy(&p->lastformat, &frame->subclass.format);
ast_format_copy(&p->lastinput, &frame->subclass.format);
codecset = 1;
/* Reset output buffer */
p->obuflen = 0;
@ -850,6 +850,7 @@ static struct ast_channel *phone_new(struct phone_pvt *i, int state, char *cntx,
{
struct ast_channel *tmp;
struct phone_codec_data queried_codec;
struct ast_format tmpfmt;
tmp = ast_channel_alloc(1, state, i->cid_num, i->cid_name, "", i->ext, i->context, linkedid, 0, "Phone/%s", i->dev + 5);
if (tmp) {
tmp->tech = cur_tech;
@ -857,22 +858,18 @@ static struct ast_channel *phone_new(struct phone_pvt *i, int state, char *cntx,
/* XXX Switching formats silently causes kernel panics XXX */
if (i->mode == MODE_FXS &&
ioctl(i->fd, PHONE_QUERY_CODEC, &queried_codec) == 0) {
if (queried_codec.type == LINEAR16)
tmp->nativeformats =
tmp->rawreadformat =
tmp->rawwriteformat =
AST_FORMAT_SLINEAR;
else {
tmp->nativeformats =
tmp->rawreadformat =
tmp->rawwriteformat =
prefformat & ~AST_FORMAT_SLINEAR;
if (queried_codec.type == LINEAR16) {
ast_format_cap_add(tmp->nativeformats, ast_format_set(&tmpfmt, AST_FORMAT_SLINEAR, 0));
ast_format_copy(&tmp->rawreadformat, &tmpfmt);
ast_format_copy(&tmp->rawwriteformat, &tmpfmt);
} else {
ast_format_cap_remove(prefcap, ast_format_set(&tmpfmt, AST_FORMAT_SLINEAR, 0));
}
}
else {
tmp->nativeformats = prefformat;
tmp->rawreadformat = prefformat;
tmp->rawwriteformat = prefformat;
} else {
ast_format_cap_copy(tmp->nativeformats, prefcap);
ast_best_codec(tmp->nativeformats, &tmpfmt);
ast_format_copy(&tmp->rawreadformat, &tmpfmt);
ast_format_copy(&tmp->rawwriteformat, &tmpfmt);
}
/* no need to call ast_setstate: the channel_alloc already did its job */
if (state == AST_STATE_RING)
@ -981,7 +978,7 @@ static void phone_check_exception(struct phone_pvt *i)
ioctl(i->fd, PHONE_PLAY_STOP);
ioctl(i->fd, PHONE_PLAY_CODEC, ULAW);
ioctl(i->fd, PHONE_PLAY_START);
i->lastformat = -1;
ast_format_clear(&i->lastformat);
} else if (i->mode == MODE_SIGMA) {
ast_module_ref(ast_module_info->self);
/* Reset the extension */
@ -1002,7 +999,7 @@ static void phone_check_exception(struct phone_pvt *i)
ioctl(i->fd, PHONE_PLAY_STOP);
ioctl(i->fd, PHONE_REC_STOP);
i->dialtone = 0;
i->lastformat = -1;
ast_format_clear(&i->lastformat);
}
}
if (phonee.bits.pstn_ring) {
@ -1214,8 +1211,8 @@ static struct phone_pvt *mkif(const char *iface, int mode, int txgain, int rxgai
flags = fcntl(tmp->fd, F_GETFL);
fcntl(tmp->fd, F_SETFL, flags | O_NONBLOCK);
tmp->owner = NULL;
tmp->lastformat = -1;
tmp->lastinput = -1;
ast_format_clear(&tmp->lastformat);
ast_format_clear(&tmp->lastinput);
tmp->ministate = 0;
memset(tmp->ext, 0, sizeof(tmp->ext));
ast_copy_string(tmp->language, language, sizeof(tmp->language));
@ -1235,9 +1232,8 @@ static struct phone_pvt *mkif(const char *iface, int mode, int txgain, int rxgai
return tmp;
}
static struct ast_channel *phone_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause)
static struct ast_channel *phone_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, void *data, int *cause)
{
format_t oldformat;
struct phone_pvt *p;
struct ast_channel *tmp = NULL;
char *name = data;
@ -1249,9 +1245,8 @@ static struct ast_channel *phone_request(const char *type, format_t format, cons
}
p = iflist;
while(p) {
if (p->mode == MODE_FXS ||
format & (AST_FORMAT_G729A | AST_FORMAT_G723_1 | AST_FORMAT_SLINEAR | AST_FORMAT_ULAW)) {
size_t length = strlen(p->dev + 5);
if (p->mode == MODE_FXS || (ast_format_cap_has_joint(cap, phone_tech.capabilities))) {
size_t length = strlen(p->dev + 5);
if (strncmp(name, p->dev + 5, length) == 0 &&
!isalnum(name[length])) {
if (!p->owner) {
@ -1266,11 +1261,9 @@ static struct ast_channel *phone_request(const char *type, format_t format, cons
ast_mutex_unlock(&iflock);
restart_monitor();
if (tmp == NULL) {
oldformat = format;
format &= (AST_FORMAT_G729A | AST_FORMAT_G723_1 | AST_FORMAT_SLINEAR | AST_FORMAT_ULAW);
if (!format) {
if (!(ast_format_cap_has_joint(cap, phone_tech.capabilities))) {
char buf[256];
ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format '%s'\n", ast_getformatname_multiple(buf, sizeof(buf), oldformat));
ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format '%s'\n", ast_getformatname_multiple(buf, sizeof(buf), cap));
return NULL;
}
}
@ -1352,7 +1345,10 @@ static int __unload_module(void)
ast_log(LOG_WARNING, "Unable to lock the monitor\n");
return -1;
}
phone_tech.capabilities = ast_format_cap_destroy(phone_tech.capabilities);
phone_tech_fxs.capabilities = ast_format_cap_destroy(phone_tech_fxs.capabilities);
prefcap = ast_format_cap_destroy(prefcap);
return 0;
}
@ -1369,6 +1365,23 @@ static int load_module(void)
int mode = MODE_IMMEDIATE;
int txgain = DEFAULT_GAIN, rxgain = DEFAULT_GAIN; /* default gain 1.0 */
struct ast_flags config_flags = { 0 };
struct ast_format tmpfmt;
if (!(phone_tech.capabilities = ast_format_cap_alloc())) {
return AST_MODULE_LOAD_DECLINE;
}
ast_format_cap_add(phone_tech.capabilities, ast_format_set(&tmpfmt, AST_FORMAT_G723_1, 0));
ast_format_cap_add(phone_tech.capabilities, ast_format_set(&tmpfmt, AST_FORMAT_SLINEAR, 0));
ast_format_cap_add(phone_tech.capabilities, ast_format_set(&tmpfmt, AST_FORMAT_ULAW, 0));
ast_format_cap_add(phone_tech.capabilities, ast_format_set(&tmpfmt, AST_FORMAT_G729A, 0));
if (!(prefcap = ast_format_cap_alloc())) {
return AST_MODULE_LOAD_DECLINE;
}
ast_format_cap_copy(prefcap, phone_tech.capabilities);
if (!(phone_tech_fxs.capabilities = ast_format_cap_alloc())) {
return AST_MODULE_LOAD_DECLINE;
}
if ((cfg = ast_config_load(config, config_flags)) == CONFIG_STATUS_FILEINVALID) {
ast_log(LOG_ERROR, "Config file %s is in an invalid format. Aborting.\n", config);
@ -1416,7 +1429,7 @@ static int load_module(void)
mode = MODE_IMMEDIATE;
else if (!strncasecmp(v->value, "fxs", 3)) {
mode = MODE_FXS;
prefformat = 0x01ff0000; /* All non-voice */
ast_format_cap_remove_bytype(prefcap, AST_FORMAT_TYPE_AUDIO); /* All non-voice */
}
else if (!strncasecmp(v->value, "fx", 2))
mode = MODE_FXO;
@ -1425,16 +1438,20 @@ static int load_module(void)
} else if (!strcasecmp(v->name, "context")) {
ast_copy_string(context, v->value, sizeof(context));
} else if (!strcasecmp(v->name, "format")) {
struct ast_format tmpfmt;
if (!strcasecmp(v->value, "g729")) {
prefformat = AST_FORMAT_G729A;
} else if (!strcasecmp(v->value, "g723.1")) {
prefformat = AST_FORMAT_G723_1;
ast_format_cap_set(prefcap, ast_format_set(&tmpfmt, AST_FORMAT_G729A, 0));
} else if (!strcasecmp(v->value, "g723.1")) {
ast_format_cap_set(prefcap, ast_format_set(&tmpfmt, AST_FORMAT_G723_1, 0));
} else if (!strcasecmp(v->value, "slinear")) {
if (mode == MODE_FXS)
prefformat |= AST_FORMAT_SLINEAR;
else prefformat = AST_FORMAT_SLINEAR;
ast_format_set(&tmpfmt, AST_FORMAT_SLINEAR, 0);
if (mode == MODE_FXS) {
ast_format_cap_add(prefcap, &tmpfmt);
} else {
ast_format_cap_set(prefcap, &tmpfmt);
}
} else if (!strcasecmp(v->value, "ulaw")) {
prefformat = AST_FORMAT_ULAW;
ast_format_cap_set(prefcap, ast_format_set(&tmpfmt, AST_FORMAT_ULAW, 0));
} else
ast_log(LOG_WARNING, "Unknown format '%s'\n", v->value);
} else if (!strcasecmp(v->name, "echocancel")) {
@ -1458,7 +1475,7 @@ static int load_module(void)
ast_mutex_unlock(&iflock);
if (mode == MODE_FXS) {
phone_tech_fxs.capabilities = prefformat;
ast_format_cap_copy(phone_tech_fxs.capabilities, prefcap);
cur_tech = &phone_tech_fxs;
} else
cur_tech = (struct ast_channel_tech *) &phone_tech;

File diff suppressed because it is too large Load Diff

View File

@ -148,7 +148,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
static const char tdesc[] = "Skinny Client Control Protocol (Skinny)";
static const char config[] = "skinny.conf";
static format_t default_capability = AST_FORMAT_ULAW | AST_FORMAT_ALAW;
static struct ast_format_cap *default_cap;
static struct ast_codec_pref default_prefs;
enum skinny_codecs {
@ -296,7 +296,7 @@ struct onhook_message {
#define CAPABILITIES_RES_MESSAGE 0x0010
struct station_capabilities {
uint32_t codec;
uint32_t codec; /* skinny codec, not ast codec */
uint32_t frames;
union {
char res[8];
@ -1244,9 +1244,9 @@ struct skinny_subchannel {
int instance; \
int group; \
int needdestroy; \
format_t confcapability; \
struct ast_format_cap *confcap; \
struct ast_codec_pref confprefs; \
format_t capability; \
struct ast_format_cap *cap; \
struct ast_codec_pref prefs; \
int nonCodecCapability; \
int onhooktime; \
@ -1282,8 +1282,6 @@ static struct skinny_line_options{
.instance = 0,
.directmedia = 0,
.nat = 0,
.confcapability = AST_FORMAT_ULAW | AST_FORMAT_ALAW,
.capability = 0,
.getforward = 0,
.needdestroy = 0,
.prune = 0,
@ -1324,9 +1322,9 @@ struct skinny_addon {
int registered; \
int lastlineinstance; \
int lastcallreference; \
format_t confcapability; \
struct ast_format_cap *confcap; \
struct ast_codec_pref confprefs; \
format_t capability; \
struct ast_format_cap *cap; \
int earlyrtp; \
int transfer; \
int callwaiting; \
@ -1358,8 +1356,6 @@ static struct skinny_device_options {
.callwaiting = 1,
.mwiblink = 0,
.dnd = 0,
.confcapability = AST_FORMAT_ULAW | AST_FORMAT_ALAW,
.capability = 0,
.prune = 0,
};
static struct skinny_device_options *default_device = &default_device_struct;
@ -1386,7 +1382,7 @@ struct skinnysession {
AST_LIST_ENTRY(skinnysession) list;
};
static struct ast_channel *skinny_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause);
static struct ast_channel *skinny_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, void *data, int *cause);
static AST_LIST_HEAD_STATIC(sessions, skinnysession);
static int skinny_devicestate(void *data);
@ -1402,10 +1398,9 @@ static int skinny_senddigit_end(struct ast_channel *ast, char digit, unsigned in
static void mwi_event_cb(const struct ast_event *event, void *userdata);
static int skinny_reload(void);
static const struct ast_channel_tech skinny_tech = {
static struct ast_channel_tech skinny_tech = {
.type = "Skinny",
.description = tdesc,
.capabilities = AST_FORMAT_AUDIO_MASK,
.properties = AST_CHAN_TP_WANTSJITTER | AST_CHAN_TP_CREATESJITTER,
.requester = skinny_request,
.devicestate = skinny_devicestate,
@ -1424,6 +1419,55 @@ static const struct ast_channel_tech skinny_tech = {
static int skinny_extensionstate_cb(char *context, char* exten, int state, void *data);
static int skinny_transfer(struct skinny_subchannel *sub);
static struct skinny_line *skinny_line_alloc(void)
{
struct skinny_line *l;
if (!(l = ast_calloc(1, sizeof(*l)))) {
return NULL;
}
l->cap = ast_format_cap_alloc_nolock();
l->confcap = ast_format_cap_alloc_nolock();
if (!l->cap || !l->confcap) {
l->cap = ast_format_cap_destroy(l->cap);
l->confcap = ast_format_cap_destroy(l->confcap);
ast_free(l);
return NULL;
}
return l;
}
static struct skinny_line *skinny_line_destroy(struct skinny_line *l)
{
l->cap = ast_format_cap_destroy(l->cap);
l->confcap = ast_format_cap_destroy(l->confcap);
ast_free(l);
return NULL;
}
static struct skinny_device *skinny_device_alloc(void)
{
struct skinny_device *d;
if (!(d = ast_calloc(1, sizeof(*d)))) {
return NULL;
}
d->cap = ast_format_cap_alloc_nolock();
d->confcap = ast_format_cap_alloc_nolock();
if (!d->cap || !d->confcap) {
d->cap = ast_format_cap_destroy(d->cap);
d->confcap = ast_format_cap_destroy(d->confcap);
ast_free(d);
return NULL;
}
return d;
}
static struct skinny_device *skinny_device_destroy(struct skinny_device *d)
{
d->cap = ast_format_cap_destroy(d->cap);
d->confcap = ast_format_cap_destroy(d->confcap);
ast_free(d);
return NULL;
}
static void *get_button_template(struct skinnysession *s, struct button_definition_template *btn)
{
struct skinny_device *d = s->device;
@ -1729,31 +1773,32 @@ static struct skinny_speeddial *find_speeddial_by_instance(struct skinny_device
return sd;
}
static format_t codec_skinny2ast(enum skinny_codecs skinnycodec)
static struct ast_format *codec_skinny2ast(enum skinny_codecs skinnycodec, struct ast_format *result)
{
switch (skinnycodec) {
case SKINNY_CODEC_ALAW:
return AST_FORMAT_ALAW;
return ast_format_set(result, AST_FORMAT_ALAW, 0);
case SKINNY_CODEC_ULAW:
return AST_FORMAT_ULAW;
return ast_format_set(result, AST_FORMAT_ULAW, 0);
case SKINNY_CODEC_G723_1:
return AST_FORMAT_G723_1;
return ast_format_set(result, AST_FORMAT_G723_1, 0);
case SKINNY_CODEC_G729A:
return AST_FORMAT_G729A;
return ast_format_set(result, AST_FORMAT_G729A, 0);
case SKINNY_CODEC_G726_32:
return AST_FORMAT_G726_AAL2; /* XXX Is this right? */
return ast_format_set(result, AST_FORMAT_G726_AAL2, 0); /* XXX Is this right? */
case SKINNY_CODEC_H261:
return AST_FORMAT_H261;
return ast_format_set(result, AST_FORMAT_H261, 0);
case SKINNY_CODEC_H263:
return AST_FORMAT_H263;
return ast_format_set(result, AST_FORMAT_H263 ,0);
default:
return 0;
ast_format_clear(result);
return result;
}
}
static int codec_ast2skinny(format_t astcodec)
static int codec_ast2skinny(struct ast_format *astcodec)
{
switch (astcodec) {
switch (astcodec->id) {
case AST_FORMAT_ALAW:
return SKINNY_CODEC_ALAW;
case AST_FORMAT_ULAW:
@ -1924,7 +1969,7 @@ static int skinny_register(struct skinny_req *req, struct skinnysession *s)
ast_verb(1, "Line %s already connected to %s. Not connecting to %s.\n", l->name, l->device->name, d->name);
} else {
l->device = d;
l->capability = l->confcapability & d->capability;
ast_format_cap_joint_copy(l->confcap, d->cap, l->cap);
l->prefs = l->confprefs;
if (!l->prefs.order[0]) {
l->prefs = d->confprefs;
@ -1971,8 +2016,8 @@ static int skinny_unregister(struct skinny_req *req, struct skinnysession *s)
AST_LIST_TRAVERSE(&d->lines, l, list) {
if (l->device == d) {
l->device = NULL;
l->capability = 0;
ast_parse_allow_disallow(&l->prefs, &l->capability, "all", 0);
ast_format_cap_remove_all(l->cap);
ast_parse_allow_disallow(&l->prefs, l->cap, "all", 0);
l->instance = 0;
manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: Skinny\r\nPeer: Skinny/%s@%s\r\nPeerStatus: Unregistered\r\n", l->name, d->name);
unregister_exten(l);
@ -2234,16 +2279,17 @@ static void transmit_connect(struct skinny_device *d, struct skinny_subchannel *
struct skinny_req *req;
struct skinny_line *l = sub->parent;
struct ast_format_list fmt;
struct ast_format tmpfmt;
if (!(req = req_alloc(sizeof(struct open_receive_channel_message), OPEN_RECEIVE_CHANNEL_MESSAGE)))
return;
fmt = ast_codec_pref_getsize(&l->prefs, ast_best_codec(l->capability));
ast_best_codec(l->cap, &tmpfmt);
fmt = ast_codec_pref_getsize(&l->prefs, &tmpfmt);
req->data.openreceivechannel.conferenceId = htolel(sub->callid);
req->data.openreceivechannel.partyId = htolel(sub->callid);
req->data.openreceivechannel.packets = htolel(fmt.cur_ms);
req->data.openreceivechannel.capability = htolel(codec_ast2skinny(fmt.bits));
req->data.openreceivechannel.capability = htolel(codec_ast2skinny(ast_format_set(&tmpfmt, fmt.id, 0)));
req->data.openreceivechannel.echo = htolel(0);
req->data.openreceivechannel.bitrate = htolel(0);
transmit_response(d, req);
@ -2448,6 +2494,7 @@ static void transmit_stopmediatransmission(struct skinny_device *d, struct skinn
static void transmit_startmediatransmission(struct skinny_device *d, struct skinny_subchannel *sub, struct sockaddr_in dest, struct ast_format_list fmt)
{
struct skinny_req *req;
struct ast_format tmpfmt;
if (!(req = req_alloc(sizeof(struct start_media_transmission_message), START_MEDIA_TRANSMISSION_MESSAGE)))
return;
@ -2457,7 +2504,7 @@ static void transmit_startmediatransmission(struct skinny_device *d, struct skin
req->data.startmedia.remoteIp = dest.sin_addr.s_addr;
req->data.startmedia.remotePort = htolel(ntohs(dest.sin_port));
req->data.startmedia.packetSize = htolel(fmt.cur_ms);
req->data.startmedia.payloadType = htolel(codec_ast2skinny(fmt.bits));
req->data.startmedia.payloadType = htolel(codec_ast2skinny(ast_format_set(&tmpfmt, fmt.id, 0)));
req->data.startmedia.qualifier.precedence = htolel(127);
req->data.startmedia.qualifier.vad = htolel(0);
req->data.startmedia.qualifier.packets = htolel(0);
@ -2901,7 +2948,7 @@ static enum ast_rtp_glue_result skinny_get_rtp_peer(struct ast_channel *c, struc
}
static int skinny_set_rtp_peer(struct ast_channel *c, struct ast_rtp_instance *rtp, struct ast_rtp_instance *vrtp, struct ast_rtp_instance *trtp, format_t codecs, int nat_active)
static int skinny_set_rtp_peer(struct ast_channel *c, struct ast_rtp_instance *rtp, struct ast_rtp_instance *vrtp, struct ast_rtp_instance *trtp, const struct ast_format_cap *codecs, int nat_active)
{
struct skinny_subchannel *sub;
struct skinny_line *l;
@ -2925,6 +2972,7 @@ static int skinny_set_rtp_peer(struct ast_channel *c, struct ast_rtp_instance *r
d = l->device;
if (rtp){
struct ast_format tmpfmt;
ast_rtp_instance_get_remote_address(rtp, &them_tmp);
ast_sockaddr_to_sin(&them_tmp, &them);
@ -2934,10 +2982,11 @@ static int skinny_set_rtp_peer(struct ast_channel *c, struct ast_rtp_instance *r
if (skinnydebug)
ast_verb(1, "Peerip = %s:%d\n", ast_inet_ntoa(them.sin_addr), ntohs(them.sin_port));
fmt = ast_codec_pref_getsize(&l->prefs, ast_best_codec(l->capability));
ast_best_codec(l->cap, &tmpfmt);
fmt = ast_codec_pref_getsize(&l->prefs, &tmpfmt);
if (skinnydebug)
ast_verb(1, "Setting payloadType to '%s' (%d ms)\n", ast_getformatname(fmt.bits), fmt.cur_ms);
ast_verb(1, "Setting payloadType to '%s' (%d ms)\n", ast_getformatname(ast_format_set(&tmpfmt, fmt.id, 0)), fmt.cur_ms);
if (!(l->directmedia) || (l->nat)){
ast_rtp_instance_get_local_address(rtp, &us_tmp);
@ -3195,15 +3244,16 @@ static char *device2str(int type)
/*! \brief Print codec list from preference to CLI/manager */
static void print_codec_to_cli(int fd, struct ast_codec_pref *pref)
{
int x, codec;
int x;
struct ast_format tmpfmt;
for(x = 0; x < 32 ; x++) {
codec = ast_codec_pref_index(pref, x);
if (!codec)
ast_codec_pref_index(pref, x, &tmpfmt);
if (!tmpfmt.id)
break;
ast_cli(fd, "%s", ast_getformatname(codec));
ast_cli(fd, "%s", ast_getformatname(&tmpfmt));
ast_cli(fd, ":%d", pref->framing[x]);
if (x < 31 && ast_codec_pref_index(pref, x + 1))
if (x < 31 && ast_codec_pref_index(pref, x + 1, &tmpfmt))
ast_cli(fd, ",");
}
if (!x)
@ -3358,10 +3408,10 @@ static char *_skinny_show_device(int type, int fd, struct mansession *s, const s
ast_cli(fd, "Port: %d\n", (d->session ? ntohs(d->session->sin.sin_port) : 0));
ast_cli(fd, "Device Type: %s\n", device2str(d->type));
ast_cli(fd, "Conf Codecs:");
ast_getformatname_multiple(codec_buf, sizeof(codec_buf) - 1, d->confcapability);
ast_getformatname_multiple(codec_buf, sizeof(codec_buf) - 1, d->confcap);
ast_cli(fd, "%s\n", codec_buf);
ast_cli(fd, "Neg Codecs: ");
ast_getformatname_multiple(codec_buf, sizeof(codec_buf) - 1, d->capability);
ast_getformatname_multiple(codec_buf, sizeof(codec_buf) - 1, d->cap);
ast_cli(fd, "%s\n", codec_buf);
ast_cli(fd, "Registered: %s\n", (d->registered ? "Yes" : "No"));
ast_cli(fd, "Lines: %d\n", numlines);
@ -3392,10 +3442,10 @@ static char *_skinny_show_device(int type, int fd, struct mansession *s, const s
astman_append(s, "Port: %d\r\n", (d->session ? ntohs(d->session->sin.sin_port) : 0));
astman_append(s, "DeviceType: %s\r\n", device2str(d->type));
astman_append(s, "Codecs: ");
ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, d->confcapability);
ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, d->confcap);
astman_append(s, "%s\r\n", codec_buf);
astman_append(s, "CodecOrder: ");
ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, d->capability);
ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, d->cap);
astman_append(s, "%s\r\n", codec_buf);
astman_append(s, "Devicestatus: %s\r\n", (d->registered?"registered":"unregistered"));
astman_append(s, "NumberOfLines: %d\r\n", numlines);
@ -3587,7 +3637,7 @@ static char *_skinny_show_line(int type, int fd, struct mansession *s, const str
struct skinny_device *d;
struct skinny_line *l;
struct ast_codec_pref *pref;
int x = 0, codec = 0;
int x = 0;
char codec_buf[512];
char group_buf[256];
char cbuf[256];
@ -3648,10 +3698,10 @@ static char *_skinny_show_line(int type, int fd, struct mansession *s, const str
ast_cli(fd, "Group: %d\n", l->group);
ast_cli(fd, "Parkinglot: %s\n", S_OR(l->parkinglot, "<not set>"));
ast_cli(fd, "Conf Codecs: ");
ast_getformatname_multiple(codec_buf, sizeof(codec_buf) - 1, l->confcapability);
ast_getformatname_multiple(codec_buf, sizeof(codec_buf) - 1, l->confcap);
ast_cli(fd, "%s\n", codec_buf);
ast_cli(fd, "Neg Codecs: ");
ast_getformatname_multiple(codec_buf, sizeof(codec_buf) - 1, l->capability);
ast_getformatname_multiple(codec_buf, sizeof(codec_buf) - 1, l->cap);
ast_cli(fd, "%s\n", codec_buf);
ast_cli(fd, "Codec Order: (");
print_codec_to_cli(fd, &l->prefs);
@ -3693,16 +3743,17 @@ static char *_skinny_show_line(int type, int fd, struct mansession *s, const str
astman_append(s, "immediate: %s\r\n", (l->immediate ? "Yes" : "No"));
astman_append(s, "Group: %d\r\n", l->group);
astman_append(s, "Parkinglot: %s\r\n", S_OR(l->parkinglot, "<not set>"));
ast_getformatname_multiple(codec_buf, sizeof(codec_buf) - 1, l->confcapability);
ast_getformatname_multiple(codec_buf, sizeof(codec_buf) - 1, l->confcap);
astman_append(s, "Codecs: %s\r\n", codec_buf);
astman_append(s, "CodecOrder: ");
pref = &l->prefs;
for(x = 0; x < 32 ; x++) {
codec = ast_codec_pref_index(pref, x);
if (!codec)
struct ast_format tmpfmt;
ast_codec_pref_index(pref, x, &tmpfmt);
if (!tmpfmt.id)
break;
astman_append(s, "%s", ast_getformatname(codec));
if (x < 31 && ast_codec_pref_index(pref, x+1))
astman_append(s, "%s", ast_getformatname(&tmpfmt));
if (x < 31 && ast_codec_pref_index(pref, x+1, &tmpfmt))
astman_append(s, ",");
}
astman_append(s, "\r\n");
@ -4221,11 +4272,11 @@ static struct ast_frame *skinny_rtp_read(struct skinny_subchannel *sub)
if (ast) {
/* We already hold the channel lock */
if (f->frametype == AST_FRAME_VOICE) {
if (f->subclass.codec != ast->nativeformats) {
ast_debug(1, "Oooh, format changed to %s\n", ast_getformatname(f->subclass.codec));
ast->nativeformats = f->subclass.codec;
ast_set_read_format(ast, ast->readformat);
ast_set_write_format(ast, ast->writeformat);
if (!(ast_format_cap_iscompatible(ast->nativeformats, &f->subclass.format))) {
ast_debug(1, "Oooh, format changed to %s\n", ast_getformatname(&f->subclass.format));
ast_format_cap_set(ast->nativeformats, &f->subclass.format);
ast_set_read_format(ast, &ast->readformat);
ast_set_write_format(ast, &ast->writeformat);
}
}
}
@ -4254,13 +4305,13 @@ static int skinny_write(struct ast_channel *ast, struct ast_frame *frame)
return 0;
}
} else {
if (!(frame->subclass.codec & ast->nativeformats)) {
if (!(ast_format_cap_iscompatible(ast->nativeformats, &frame->subclass.format))) {
char buf[256];
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(&frame->subclass.format),
ast_getformatname_multiple(buf, sizeof(buf), ast->nativeformats),
ast_getformatname(ast->readformat),
ast_getformatname(ast->writeformat));
ast_getformatname(&ast->readformat),
ast_getformatname(&ast->writeformat));
return -1;
}
}
@ -4586,7 +4637,7 @@ static struct ast_channel *skinny_new(struct skinny_line *l, int state, const ch
struct skinny_subchannel *sub;
struct skinny_device *d = l->device;
struct ast_variable *v = NULL;
int fmt;
struct ast_format tmpfmt;
if (!l->device) {
ast_log(LOG_WARNING, "Device for line %s is not registered.\n", l->name);
@ -4622,16 +4673,17 @@ static struct ast_channel *skinny_new(struct skinny_line *l, int state, const ch
}
tmp->tech = &skinny_tech;
tmp->tech_pvt = sub;
tmp->nativeformats = l->capability;
if (!tmp->nativeformats)
ast_format_cap_copy(tmp->nativeformats, l->cap);
if (ast_format_cap_is_empty(tmp->nativeformats)) {
// Should throw an error
tmp->nativeformats = default_capability;
fmt = ast_best_codec(tmp->nativeformats);
ast_format_cap_copy(tmp->nativeformats, default_cap);
}
ast_best_codec(tmp->nativeformats, &tmpfmt);
if (skinnydebug) {
char buf[256];
ast_verb(1, "skinny_new: tmp->nativeformats=%s fmt=%s\n",
ast_getformatname_multiple(buf, sizeof(buf), tmp->nativeformats),
ast_getformatname(fmt));
ast_getformatname(&tmpfmt));
}
if (sub->rtp) {
ast_channel_set_fd(tmp, 0, ast_rtp_instance_fd(sub->rtp, 0));
@ -4639,10 +4691,11 @@ static struct ast_channel *skinny_new(struct skinny_line *l, int state, const ch
if (state == AST_STATE_RING) {
tmp->rings = 1;
}
tmp->writeformat = fmt;
tmp->rawwriteformat = fmt;
tmp->readformat = fmt;
tmp->rawreadformat = fmt;
ast_format_copy(&tmp->writeformat, &tmpfmt);
ast_format_copy(&tmp->rawwriteformat, &tmpfmt);
ast_format_copy(&tmp->readformat, &tmpfmt);
ast_format_copy(&tmp->rawreadformat, &tmpfmt);
if (!ast_strlen_zero(l->language))
ast_string_field_set(tmp, language, l->language);
if (!ast_strlen_zero(l->accountcode))
@ -5469,10 +5522,14 @@ static int handle_capabilities_res_message(struct skinny_req *req, struct skinny
struct skinny_device *d = s->device;
struct skinny_line *l;
uint32_t count = 0;
format_t codecs = 0;
struct ast_format_cap *codecs = ast_format_cap_alloc();
int i;
char buf[256];
if (!codecs) {
return 0;
}
count = letohl(req->data.caps.count);
if (count > SKINNY_MAX_CAPABILITIES) {
count = SKINNY_MAX_CAPABILITIES;
@ -5480,23 +5537,24 @@ static int handle_capabilities_res_message(struct skinny_req *req, struct skinny
}
for (i = 0; i < count; i++) {
format_t acodec = 0;
struct ast_format acodec;
int scodec = 0;
scodec = letohl(req->data.caps.caps[i].codec);
acodec = codec_skinny2ast(scodec);
codec_skinny2ast(scodec, &acodec);
if (skinnydebug)
ast_verb(1, "Adding codec capability '%" PRId64 " (%d)'\n", acodec, scodec);
codecs |= acodec;
ast_verb(1, "Adding codec capability %s (%d)'\n", ast_getformatname(&acodec), scodec);
ast_format_cap_add(codecs, &acodec);
}
d->capability = d->confcapability & codecs;
ast_verb(0, "Device capability set to '%s'\n", ast_getformatname_multiple(buf, sizeof(buf), d->capability));
ast_format_cap_joint_copy(d->confcap, codecs, d->cap);
ast_verb(0, "Device capability set to '%s'\n", ast_getformatname_multiple(buf, sizeof(buf), d->cap));
AST_LIST_TRAVERSE(&d->lines, l, list) {
ast_mutex_lock(&l->lock);
l->capability = l->confcapability & d->capability;
ast_format_cap_joint_copy(l->confcap, d->cap, l->cap);
ast_mutex_unlock(&l->lock);
}
codecs = ast_format_cap_destroy(codecs);
return 1;
}
@ -5658,6 +5716,7 @@ static int handle_open_receive_channel_ack_message(struct skinny_req *req, struc
struct sockaddr_in us = { 0, };
struct ast_sockaddr sin_tmp;
struct ast_sockaddr us_tmp;
struct ast_format tmpfmt;
uint32_t addr;
int port;
int status;
@ -5698,11 +5757,11 @@ static int handle_open_receive_channel_ack_message(struct skinny_req *req, struc
ast_verb(1, "device ipaddr = %s:%d\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
ast_verb(1, "asterisk ipaddr = %s:%d\n", ast_inet_ntoa(us.sin_addr), ntohs(us.sin_port));
}
fmt = ast_codec_pref_getsize(&l->prefs, ast_best_codec(l->capability));
ast_best_codec(l->cap, &tmpfmt);
fmt = ast_codec_pref_getsize(&l->prefs, &tmpfmt);
if (skinnydebug)
ast_verb(1, "Setting payloadType to '%s' (%d ms)\n", ast_getformatname(fmt.bits), fmt.cur_ms);
ast_verb(1, "Setting payloadType to '%s' (%d ms)\n", ast_getformatname(ast_format_set(&tmpfmt, fmt.id, 0)), fmt.cur_ms);
transmit_startmediatransmission(d, sub, us, fmt);
@ -6546,19 +6605,15 @@ static int skinny_devicestate(void *data)
return get_devicestate(l);
}
static struct ast_channel *skinny_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause)
static struct ast_channel *skinny_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, void *data, int *cause)
{
format_t oldformat;
struct skinny_line *l;
struct ast_channel *tmpc = NULL;
char tmp[256];
char *dest = data;
oldformat = format;
if (!(format &= AST_FORMAT_AUDIO_MASK)) {
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_type(cap, AST_FORMAT_TYPE_AUDIO))) {
ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format '%s'\n", ast_getformatname_multiple(tmp, sizeof(tmp), cap));
return NULL;
}
@ -6670,10 +6725,10 @@ static struct ast_channel *skinny_request(const char *type, format_t format, con
}
continue;
} else if (!strcasecmp(v->name, "allow")) {
ast_parse_allow_disallow(&default_prefs, &default_capability, v->value, 1);
ast_parse_allow_disallow(&default_prefs, default_cap, v->value, 1);
continue;
} else if (!strcasecmp(v->name, "disallow")) {
ast_parse_allow_disallow(&default_prefs, &default_capability, v->value, 0);
ast_parse_allow_disallow(&default_prefs, default_cap, v->value, 0);
continue;
}
}
@ -6860,20 +6915,20 @@ static struct ast_channel *skinny_request(const char *type, format_t format, con
}
} else if (!strcasecmp(v->name, "allow")) {
if (type & (TYPE_DEF_DEVICE | TYPE_DEVICE)) {
ast_parse_allow_disallow(&CDEV_OPTS->confprefs, &CDEV_OPTS->confcapability, v->value, 1);
ast_parse_allow_disallow(&CDEV_OPTS->confprefs, CDEV_OPTS->confcap, v->value, 1);
continue;
}
if (type & (TYPE_DEF_LINE | TYPE_LINE)) {
ast_parse_allow_disallow(&CLINE_OPTS->confprefs, &CLINE_OPTS->confcapability, v->value, 1);
ast_parse_allow_disallow(&CLINE_OPTS->confprefs, CLINE_OPTS->confcap, v->value, 1);
continue;
}
} else if (!strcasecmp(v->name, "disallow")) {
if (type & (TYPE_DEF_DEVICE | TYPE_DEVICE)) {
ast_parse_allow_disallow(&CDEV_OPTS->confprefs, &CDEV_OPTS->confcapability, v->value, 0);
ast_parse_allow_disallow(&CDEV_OPTS->confprefs, CDEV_OPTS->confcap, v->value, 0);
continue;
}
if (type & (TYPE_DEF_LINE | TYPE_LINE)) {
ast_parse_allow_disallow(&CLINE_OPTS->confprefs, &CLINE_OPTS->confcapability, v->value, 0);
ast_parse_allow_disallow(&CLINE_OPTS->confprefs, CLINE_OPTS->confcap, v->value, 0);
continue;
}
} else if (!strcasecmp(v->name, "version")) {
@ -6982,7 +7037,7 @@ static struct ast_channel *skinny_request(const char *type, format_t format, con
}
}
if (!(l=ast_calloc(1, sizeof(*l)))) {
if (!(l = skinny_line_alloc())) {
ast_verb(1, "Unable to allocate memory for line %s.\n", lname);
AST_LIST_UNLOCK(&lines);
return NULL;
@ -7040,7 +7095,7 @@ static struct ast_channel *skinny_request(const char *type, format_t format, con
}
}
if (!(d = ast_calloc(1, sizeof(*d)))) {
if (!(d = skinny_device_alloc())) {
ast_verb(1, "Unable to allocate memory for device %s.\n", dname);
AST_LIST_UNLOCK(&devices);
return NULL;
@ -7162,7 +7217,7 @@ static struct ast_channel *skinny_request(const char *type, format_t format, con
bindaddr.sin_family = AF_INET;
/* load the lines sections */
default_line->confcapability = default_capability;
ast_format_cap_copy(default_line->confcap, default_cap);
default_line->confprefs = default_prefs;
config_parse_variables(TYPE_DEF_LINE, default_line, ast_variable_browse(cfg, "lines"));
cat = ast_category_browse(cfg, "lines");
@ -7172,7 +7227,7 @@ static struct ast_channel *skinny_request(const char *type, format_t format, con
}
/* load the devices sections */
default_device->confcapability = default_capability;
ast_format_cap_copy(default_device->confcap, default_cap);
default_device->confprefs = default_prefs;
config_parse_variables(TYPE_DEF_DEVICE, default_device, ast_variable_browse(cfg, "devices"));
cat = ast_category_browse(cfg, "devices");
@ -7243,7 +7298,7 @@ static void delete_devices(void)
/* Delete all lines for this device */
while ((l = AST_LIST_REMOVE_HEAD(&d->lines, list))) {
AST_LIST_REMOVE(&lines, l, all);
free(l);
l = skinny_line_destroy(l);
}
/* Delete all speeddials for this device */
while ((sd = AST_LIST_REMOVE_HEAD(&d->speeddials, list))) {
@ -7252,8 +7307,8 @@ static void delete_devices(void)
/* Delete all addons for this device */
while ((a = AST_LIST_REMOVE_HEAD(&d->addons, list))) {
free(a);
}
free(d);
}
d = skinny_device_destroy(d);
}
AST_LIST_UNLOCK(&lines);
AST_LIST_UNLOCK(&devices);
@ -7310,7 +7365,7 @@ int skinny_reload(void)
free(a);
}
AST_LIST_REMOVE_CURRENT(list);
free(d);
d = skinny_device_destroy(d);
}
AST_LIST_TRAVERSE_SAFE_END;
AST_LIST_UNLOCK(&devices);
@ -7319,7 +7374,7 @@ int skinny_reload(void)
AST_LIST_TRAVERSE_SAFE_BEGIN(&lines, l, all) {
if (l->prune) {
AST_LIST_REMOVE_CURRENT(all);
free(l);
l = skinny_line_destroy(l);
}
}
AST_LIST_TRAVERSE_SAFE_END;
@ -7344,6 +7399,33 @@ int skinny_reload(void)
static int load_module(void)
{
int res = 0;
struct ast_format tmpfmt;
if (!(default_cap = ast_format_cap_alloc())) {
return AST_MODULE_LOAD_DECLINE;
}
if (!(skinny_tech.capabilities = ast_format_cap_alloc())) {
return AST_MODULE_LOAD_DECLINE;
}
if (!(default_line->confcap = ast_format_cap_alloc())) {
return AST_MODULE_LOAD_DECLINE;
}
if (!(default_line->cap = ast_format_cap_alloc())) {
return AST_MODULE_LOAD_DECLINE;
}
if (!(default_device->confcap = ast_format_cap_alloc())) {
return AST_MODULE_LOAD_DECLINE;
}
if (!(default_device->cap = ast_format_cap_alloc())) {
return AST_MODULE_LOAD_DECLINE;
}
ast_format_cap_add_all_by_type(skinny_tech.capabilities, AST_FORMAT_TYPE_AUDIO);
ast_format_cap_add(default_cap, ast_format_set(&tmpfmt, AST_FORMAT_ULAW, 0));
ast_format_cap_add(default_cap, ast_format_set(&tmpfmt, AST_FORMAT_ALAW, 0));
ast_format_cap_add(default_line->confcap, ast_format_set(&tmpfmt, AST_FORMAT_ULAW, 0));
ast_format_cap_add(default_line->confcap, ast_format_set(&tmpfmt, AST_FORMAT_ALAW, 0));
ast_format_cap_add(default_device->confcap, ast_format_set(&tmpfmt, AST_FORMAT_ULAW, 0));
ast_format_cap_add(default_device->confcap, ast_format_set(&tmpfmt, AST_FORMAT_ALAW, 0));
for (; res < ARRAY_LEN(soft_key_template_default); res++) {
soft_key_template_default[res].softKeyEvent = htolel(soft_key_template_default[res].softKeyEvent);
@ -7456,7 +7538,13 @@ static int unload_module(void)
con = ast_context_find(used_context);
if (con)
ast_context_destroy(con, "Skinny");
default_cap = ast_format_cap_destroy(default_cap);
skinny_tech.capabilities = ast_format_cap_destroy(skinny_tech.capabilities);
default_line->confcap = ast_format_cap_destroy(default_line->confcap);
default_line->cap = ast_format_cap_destroy(default_line->cap);
default_device->confcap = ast_format_cap_destroy(default_device->confcap);
default_device->cap = ast_format_cap_destroy(default_device->cap);
return 0;
}

View File

@ -71,7 +71,6 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include "asterisk/indications.h"
/*! Beware, G729 and G723 are not supported by asterisk, except with the proper licence */
#define CAPABILITY AST_FORMAT_ALAW | AST_FORMAT_ULAW /* | AST_FORMAT_G729A | AST_FORMAT_G723_1 */
#define DEFAULTCONTEXT "default"
#define DEFAULTCALLERID "Unknown"
@ -102,6 +101,8 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#define SUB_THREEWAY 1
#define MAX_SUBS 2
struct ast_format_cap *global_cap;
enum autoprovision {
AUTOPROVISIONING_NO = 0,
AUTOPROVISIONING_YES,
@ -409,7 +410,7 @@ struct unistim_line {
/*! AMA flags (for billing) */
int amaflags;
/*! Codec supported */
format_t capability;
struct ast_format_cap *cap;
/*! Parkinglot */
char parkinglot[AST_MAX_CONTEXT];
struct unistim_line *next;
@ -679,7 +680,7 @@ static int reload(void);
static int unload_module(void);
static int reload_config(void);
static void show_main_page(struct unistimsession *pte);
static struct ast_channel *unistim_request(const char *type, format_t format, const struct ast_channel *requestor,
static struct ast_channel *unistim_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor,
void *data, int *cause);
static int unistim_call(struct ast_channel *ast, char *dest, int timeout);
static int unistim_hangup(struct ast_channel *ast);
@ -698,10 +699,9 @@ static int write_entry_history(struct unistimsession *pte, FILE * f, char c,
char *line1);
static void change_callerid(struct unistimsession *pte, int type, char *callerid);
static const struct ast_channel_tech unistim_tech = {
static struct ast_channel_tech unistim_tech = {
.type = channel_type,
.description = tdesc,
.capabilities = CAPABILITY,
.properties = AST_CHAN_TP_WANTSJITTER | AST_CHAN_TP_CREATESJITTER,
.requester = unistim_request,
.call = unistim_call,
@ -1483,6 +1483,38 @@ static int unistim_register(struct unistimsession *s)
return 1;
}
static void unistim_line_copy(struct unistim_line *dst, struct unistim_line *src)
{
struct ast_format_cap *tmp = src->cap;
memcpy(dst, src, sizeof(*dst)); /* this over writes the cap ptr, so we have to reset it */
src->cap = tmp;
ast_format_cap_copy(src->cap, dst->cap);
}
static struct unistim_line *unistim_line_destroy(struct unistim_line *l)
{
if (!l) {
return NULL;
}
l->cap = ast_format_cap_destroy(l->cap);
ast_free(l);
return NULL;
}
static struct unistim_line *unistim_line_alloc(void)
{
struct unistim_line *l;
if (!(l = ast_calloc(1, sizeof(*l)))) {
return NULL;
}
if (!(l->cap = ast_format_cap_alloc_nolock())) {
ast_free(l);
return NULL;
}
return l;
}
static int alloc_sub(struct unistim_line *l, int x)
{
struct unistim_subchannel *sub;
@ -1554,16 +1586,16 @@ static void rcv_mac_addr(struct unistimsession *pte, const unsigned char *buf)
}
memcpy(newd, d, sizeof(*newd));
if (!(newl = ast_malloc(sizeof(*newl)))) {
if (!(newl = unistim_line_alloc())) {
ast_free(newd);
ast_mutex_unlock(&devicelock);
return;
}
memcpy(newl, d->lines, sizeof(*newl));
unistim_line_copy(d->lines, newl);
if (!alloc_sub(newl, SUB_REAL)) {
ast_free(newd);
ast_free(newl);
unistim_line_destroy(newl);
ast_mutex_unlock(&devicelock);
return;
}
@ -2038,7 +2070,7 @@ static void start_rtp(struct unistim_subchannel *sub)
struct sockaddr_in us = { 0, };
struct sockaddr_in public = { 0, };
struct sockaddr_in sin = { 0, };
format_t codec;
int codec;
struct sockaddr_in sout = { 0, };
struct ast_sockaddr us_tmp;
struct ast_sockaddr sin_tmp;
@ -2093,19 +2125,19 @@ static void start_rtp(struct unistim_subchannel *sub)
sin.sin_port = htons(sub->parent->parent->rtp_port);
ast_sockaddr_from_sin(&sin_tmp, &sin);
ast_rtp_instance_set_remote_address(sub->rtp, &sin_tmp);
if (!(sub->owner->nativeformats & sub->owner->readformat)) {
format_t fmt;
if (!(ast_format_cap_iscompatible(sub->owner->nativeformats, &sub->owner->readformat))) {
struct ast_format tmpfmt;
char tmp[256];
fmt = ast_best_codec(sub->owner->nativeformats);
ast_best_codec(sub->owner->nativeformats, &tmpfmt);
ast_log(LOG_WARNING,
"Our read/writeformat has been changed to something incompatible: %s, using %s best codec from %s\n",
ast_getformatname(sub->owner->readformat),
ast_getformatname(fmt),
ast_getformatname(&sub->owner->readformat),
ast_getformatname(&tmpfmt),
ast_getformatname_multiple(tmp, sizeof(tmp), sub->owner->nativeformats));
sub->owner->readformat = fmt;
sub->owner->writeformat = fmt;
ast_format_copy(&sub->owner->readformat, &tmpfmt);
ast_format_copy(&sub->owner->writeformat, &tmpfmt);
}
codec = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(sub->rtp), 1, sub->owner->readformat);
codec = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(sub->rtp), 1, &sub->owner->readformat, 0);
/* Setting up RTP of the phone */
if (public_ip.sin_family == 0) /* NAT IP override ? */
memcpy(&public, &us, sizeof(public)); /* No defined, using IP from recvmsg */
@ -2114,14 +2146,14 @@ static void start_rtp(struct unistim_subchannel *sub)
if (unistimdebug) {
ast_verb(0, "RTP started : Our IP/port is : %s:%hd with codec %s\n",
ast_inet_ntoa(us.sin_addr),
htons(us.sin_port), ast_getformatname(sub->owner->readformat));
htons(us.sin_port), ast_getformatname(&sub->owner->readformat));
ast_verb(0, "Starting phone RTP stack. Our public IP is %s\n",
ast_inet_ntoa(public.sin_addr));
}
if ((sub->owner->readformat == AST_FORMAT_ULAW) ||
(sub->owner->readformat == AST_FORMAT_ALAW)) {
if ((sub->owner->readformat.id == AST_FORMAT_ULAW) ||
(sub->owner->readformat.id == AST_FORMAT_ALAW)) {
if (unistimdebug)
ast_verb(0, "Sending packet_send_rtp_packet_size for codec %s\n", ast_getformatname(codec));
ast_verb(0, "Sending packet_send_rtp_packet_size for codec %d\n", codec);
memcpy(buffsend + SIZE_HEADER, packet_send_rtp_packet_size,
sizeof(packet_send_rtp_packet_size));
buffsend[10] = (int) codec & 0xffffffffLL;
@ -2214,17 +2246,17 @@ static void start_rtp(struct unistim_subchannel *sub)
/* Codec */
buffsend[40] = codec;
buffsend[41] = codec;
if (sub->owner->readformat == AST_FORMAT_ULAW)
if (sub->owner->readformat.id == AST_FORMAT_ULAW)
buffsend[42] = 1; /* 1 = 20ms (160 bytes), 2 = 40ms (320 bytes) */
else if (sub->owner->readformat == AST_FORMAT_ALAW)
else if (sub->owner->readformat.id == AST_FORMAT_ALAW)
buffsend[42] = 1; /* 1 = 20ms (160 bytes), 2 = 40ms (320 bytes) */
else if (sub->owner->readformat == AST_FORMAT_G723_1)
else if (sub->owner->readformat.id == AST_FORMAT_G723_1)
buffsend[42] = 2; /* 1 = 30ms (24 bytes), 2 = 60 ms (48 bytes) */
else if (sub->owner->readformat == AST_FORMAT_G729A)
else if (sub->owner->readformat.id == AST_FORMAT_G729A)
buffsend[42] = 2; /* 1 = 10ms (10 bytes), 2 = 20ms (20 bytes) */
else
ast_log(LOG_WARNING, "Unsupported codec %s!\n",
ast_getformatname(sub->owner->readformat));
ast_getformatname(&sub->owner->readformat));
/* Source port for transmit RTP and Destination port for receiving RTP */
buffsend[45] = (htons(sin.sin_port) & 0xff00) >> 8;
buffsend[46] = (htons(sin.sin_port) & 0x00ff);
@ -4005,15 +4037,16 @@ static struct ast_frame *unistim_rtp_read(const struct ast_channel *ast,
if (sub->owner) {
/* We already hold the channel lock */
if (f->frametype == AST_FRAME_VOICE) {
if (f->subclass.codec != sub->owner->nativeformats) {
if (!(ast_format_cap_iscompatible(sub->owner->nativeformats, &f->subclass.format))) {
char tmp[256];
ast_debug(1,
"Oooh, format changed from %s to %s\n",
ast_getformatname(sub->owner->nativeformats),
ast_getformatname(f->subclass.codec));
ast_getformatname_multiple(tmp, sizeof(tmp), sub->owner->nativeformats),
ast_getformatname(&f->subclass.format));
sub->owner->nativeformats = f->subclass.codec;
ast_set_read_format(sub->owner, sub->owner->readformat);
ast_set_write_format(sub->owner, sub->owner->writeformat);
ast_format_cap_set(sub->owner->nativeformats, &f->subclass.format);
ast_set_read_format(sub->owner, &sub->owner->readformat);
ast_set_write_format(sub->owner, &sub->owner->writeformat);
}
}
}
@ -4047,14 +4080,14 @@ static int unistim_write(struct ast_channel *ast, struct ast_frame *frame)
return 0;
}
} else {
if (!(frame->subclass.codec & ast->nativeformats)) {
if (!(ast_format_cap_iscompatible(ast->nativeformats, &frame->subclass.format))) {
char tmp[256];
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(&frame->subclass.format),
ast_getformatname_multiple(tmp, sizeof(tmp), ast->nativeformats),
ast_getformatname(ast->readformat),
ast_getformatname(ast->writeformat));
ast_getformatname(&ast->readformat),
ast_getformatname(&ast->writeformat));
return -1;
}
}
@ -4499,7 +4532,7 @@ static struct ast_channel *unistim_new(struct unistim_subchannel *sub, int state
{
struct ast_channel *tmp;
struct unistim_line *l;
int fmt;
struct ast_format tmpfmt;
if (!sub) {
ast_log(LOG_WARNING, "subchannel null in unistim_new\n");
@ -4519,17 +4552,17 @@ static struct ast_channel *unistim_new(struct unistim_subchannel *sub, int state
return NULL;
}
tmp->nativeformats = l->capability;
if (!tmp->nativeformats)
tmp->nativeformats = CAPABILITY;
fmt = ast_best_codec(tmp->nativeformats);
ast_format_cap_copy(tmp->nativeformats, l->cap);
if (ast_format_cap_is_empty(tmp->nativeformats))
ast_format_cap_copy(tmp->nativeformats, global_cap);
ast_best_codec(tmp->nativeformats, &tmpfmt);
if (unistimdebug) {
char tmp1[256], tmp2[256], tmp3[256];
ast_verb(0, "Best codec = %s from nativeformats %s (line cap=%s global=%s)\n",
ast_getformatname(fmt),
ast_getformatname(&tmpfmt),
ast_getformatname_multiple(tmp1, sizeof(tmp1), tmp->nativeformats),
ast_getformatname_multiple(tmp2, sizeof(tmp2), l->capability),
ast_getformatname_multiple(tmp3, sizeof(tmp3), CAPABILITY));
ast_getformatname_multiple(tmp2, sizeof(tmp2), l->cap),
ast_getformatname_multiple(tmp3, sizeof(tmp3), global_cap));
}
if ((sub->rtp) && (sub->subtype == 0)) {
if (unistimdebug)
@ -4545,10 +4578,10 @@ static struct ast_channel *unistim_new(struct unistim_subchannel *sub, int state
if (state == AST_STATE_RING)
tmp->rings = 1;
tmp->adsicpe = AST_ADSI_UNAVAILABLE;
tmp->writeformat = fmt;
tmp->rawwriteformat = fmt;
tmp->readformat = fmt;
tmp->rawreadformat = fmt;
ast_format_copy(&tmp->writeformat, &tmpfmt);
ast_format_copy(&tmp->rawwriteformat, &tmpfmt);
ast_format_copy(&tmp->readformat, &tmpfmt);
ast_format_copy(&tmp->rawreadformat, &tmpfmt);
tmp->tech_pvt = sub;
tmp->tech = &unistim_tech;
if (!ast_strlen_zero(l->language))
@ -4699,26 +4732,19 @@ static int restart_monitor(void)
/*--- unistim_request: PBX interface function ---*/
/* UNISTIM calls initiated by the PBX arrive here */
static struct ast_channel *unistim_request(const char *type, format_t format, const struct ast_channel *requestor, void *data,
static struct ast_channel *unistim_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, void *data,
int *cause)
{
format_t oldformat;
struct unistim_subchannel *sub;
struct ast_channel *tmpc = NULL;
char tmp[256];
char tmp2[256];
char *dest = data;
oldformat = format;
format &= CAPABILITY;
ast_log(LOG_NOTICE,
"Asked to get a channel of format %s while capability is %s result : %s\n",
ast_getformatname(oldformat),
ast_getformatname_multiple(tmp, sizeof(tmp), CAPABILITY),
ast_getformatname(format));
if (!format) {
if (!(ast_format_cap_has_joint(cap, global_cap))) {
ast_log(LOG_NOTICE,
"Asked to get a channel of unsupported format %s while capability is %s\n",
ast_getformatname(oldformat), ast_getformatname_multiple(tmp, sizeof(tmp), CAPABILITY));
ast_getformatname_multiple(tmp2, sizeof(tmp2), cap), ast_getformatname_multiple(tmp, sizeof(tmp), global_cap));
return NULL;
}
@ -4743,7 +4769,7 @@ static struct ast_channel *unistim_request(const char *type, format_t format, co
*cause = AST_CAUSE_BUSY;
return NULL;
}
sub->parent->capability = format;
ast_format_cap_copy(sub->parent->cap, cap);
tmpc = unistim_new(sub, AST_STATE_DOWN, requestor ? requestor->linkedid : NULL);
if (!tmpc)
ast_log(LOG_WARNING, "Unable to make channel for '%s'\n", tmp);
@ -4786,10 +4812,11 @@ static char *unistim_info(struct ast_cli_entry *e, int cmd, struct ast_cli_args
device);
line = device->lines;
while (line) {
char tmp2[256];
ast_cli(a->fd,
"->name=%s fullname=%s exten=%s callid=%s cap=%" PRId64 " device=%p line=%p\n",
"->name=%s fullname=%s exten=%s callid=%s cap=%s device=%p line=%p\n",
line->name, line->fullname, line->exten, line->cid_num,
line->capability, line->parent, line);
ast_getformatname_multiple(tmp2, sizeof(tmp2), line->cap), line->parent, line);
for (i = 0; i < MAX_SUBS; i++) {
sub = line->subs[i];
if (!sub)
@ -5080,6 +5107,7 @@ static void finish_bookmark(void)
}
}
static struct unistim_device *build_device(const char *cat, const struct ast_variable *v)
{
struct unistim_device *d;
@ -5115,7 +5143,7 @@ static struct unistim_device *build_device(const char *cat, const struct ast_var
if (!(d = ast_calloc(1, sizeof(*d))))
return NULL;
if (!(l = ast_calloc(1, sizeof(*l)))) {
if (!(l = unistim_line_alloc())) {
ast_free(d);
return NULL;
}
@ -5232,7 +5260,7 @@ static struct unistim_device *build_device(const char *cat, const struct ast_var
"You must use bookmark AFTER line=>. Only one line is supported in this version\n");
if (create) {
ast_free(d);
ast_free(l);
unistim_line_destroy(l);
}
return NULL;
}
@ -5277,13 +5305,13 @@ static struct unistim_device *build_device(const char *cat, const struct ast_var
ast_verb(3, "Setting mailbox '%s' on %s@%s\n", l->mailbox, d->name, l->name);
}
l->capability = CAPABILITY;
ast_format_cap_copy(l->cap, global_cap);
l->parent = d;
if (create) {
if (!alloc_sub(l, SUB_REAL)) {
ast_mutex_destroy(&l->lock);
ast_free(l);
unistim_line_destroy(l);
ast_free(d);
return NULL;
}
@ -5311,7 +5339,7 @@ static struct unistim_device *build_device(const char *cat, const struct ast_var
if (!d->lines) {
ast_log(LOG_ERROR, "An Unistim device must have at least one line!\n");
ast_mutex_destroy(&l->lock);
ast_free(l);
unistim_line_destroy(l);
if (d->tz) {
d->tz = ast_tone_zone_unref(d->tz);
}
@ -5331,7 +5359,7 @@ static struct unistim_device *build_device(const char *cat, const struct ast_var
if (strcmp(d->name, "template")) {
ast_log(LOG_ERROR, "You must specify the mac address with device=\n");
ast_mutex_destroy(&l->lock);
ast_free(l);
unistim_line_destroy(l);
if (d->tz) {
d->tz = ast_tone_zone_unref(d->tz);
}
@ -5635,7 +5663,17 @@ static struct ast_rtp_glue unistim_rtp_glue = {
int load_module(void)
{
int res;
struct ast_format tmpfmt;
if (!(global_cap = ast_format_cap_alloc())) {
goto buff_failed;
}
if (!(unistim_tech.capabilities = ast_format_cap_alloc())) {
goto buff_failed;
}
ast_format_cap_add(global_cap, ast_format_set(&tmpfmt, AST_FORMAT_ULAW, 0));
ast_format_cap_add(global_cap, ast_format_set(&tmpfmt, AST_FORMAT_ALAW, 0));
ast_format_cap_copy(unistim_tech.capabilities, global_cap);
if (!(buff = ast_malloc(SIZE_PAGE)))
goto buff_failed;
@ -5679,6 +5717,8 @@ sched_failed:
io_failed:
ast_free(buff);
buff = NULL;
global_cap = ast_format_cap_destroy(global_cap);
unistim_tech.capabilities = ast_format_cap_destroy(unistim_tech.capabilities);
buff_failed:
return AST_MODULE_LOAD_FAILURE;
}
@ -5709,6 +5749,9 @@ static int unload_module(void)
if (unistimsock > -1)
close(unistimsock);
global_cap = ast_format_cap_destroy(global_cap);
unistim_tech.capabilities = ast_format_cap_destroy(unistim_tech.capabilities);
return 0;
}

View File

@ -661,7 +661,7 @@ static char *usbradio_active; /* the active device */
static int setformat(struct chan_usbradio_pvt *o, int mode);
static struct ast_channel *usbradio_request(const char *type, format_t format,
static struct ast_channel *usbradio_request(const char *type, struct ast_format_cap *cap,
const struct ast_channel *requestor,
void *data, int *cause);
static int usbradio_digit_begin(struct ast_channel *c, char digit);
@ -682,10 +682,11 @@ static int RxTestIt(struct chan_usbradio_pvt *o);
static char tdesc[] = "USB (CM108) Radio Channel Driver";
static const struct ast_channel_tech usbradio_tech = {
static struct ast_format slin;
static struct ast_channel_tech usbradio_tech = {
.type = "Radio",
.description = tdesc,
.capabilities = AST_FORMAT_SLINEAR,
.requester = usbradio_request,
.send_digit_begin = usbradio_digit_begin,
.send_digit_end = usbradio_digit_end,
@ -2060,7 +2061,7 @@ static struct ast_frame *usbradio_read(struct ast_channel *c)
return f;
/* ok we can build and deliver the frame to the caller */
f->frametype = AST_FRAME_VOICE;
f->subclass.codec = AST_FORMAT_SLINEAR;
ast_format_set(&f->subclass.format, AST_FORMAT_SLINEAR, 0);
f->samples = FRAME_SIZE;
f->datalen = FRAME_SIZE * 2;
f->data.ptr = o->usbradio_read_buf_8k + AST_FRIENDLY_OFFSET;
@ -2177,9 +2178,9 @@ static struct ast_channel *usbradio_new(struct chan_usbradio_pvt *o, char *ext,
if (o->sounddev < 0)
setformat(o, O_RDWR);
c->fds[0] = o->sounddev; /* -1 if device closed, override later */
c->nativeformats = AST_FORMAT_SLINEAR;
c->readformat = AST_FORMAT_SLINEAR;
c->writeformat = AST_FORMAT_SLINEAR;
ast_format_cap_add(c->nativeformats, &slin);
ast_format_set(&c->readformat, AST_FORMAT_SLINEAR, 0);
ast_format_set(&c->writeformat, AST_FORMAT_SLINEAR, 0);
c->tech_pvt = o;
if (!ast_strlen_zero(o->language))
@ -2211,7 +2212,7 @@ static struct ast_channel *usbradio_new(struct chan_usbradio_pvt *o, char *ext,
}
/*
*/
static struct ast_channel *usbradio_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause)
static struct ast_channel *usbradio_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, void *data, int *cause)
{
struct ast_channel *c;
struct chan_usbradio_pvt *o = find_desc(data);
@ -2227,8 +2228,7 @@ static struct ast_channel *usbradio_request(const char *type, format_t format, c
/* XXX we could default to 'dsp' perhaps ? */
return NULL;
}
if ((format & AST_FORMAT_SLINEAR) == 0) {
ast_log(LOG_NOTICE, "Format 0x%" PRIx64 " unsupported\n", format);
if (!(ast_format_cap_iscompatible(cap, &slin))) {
return NULL;
}
if (o->owner) {
@ -3932,6 +3932,11 @@ static int load_module(void)
struct ast_flags zeroflag = {0};
#endif
if (!(usbradio_tech.capabilities = ast_format_cap_alloc())) {
return AST_MODULE_LOAD_DECLINE;
}
ast_format_cap_add(usbradio_tech.capabilities, ast_format_set(&slin, AST_FORMAT_SLINEAR, 0));
if (hid_device_mklist()) {
ast_log(LOG_NOTICE, "Unable to make hid list\n");
return AST_MODULE_LOAD_DECLINE;
@ -4016,6 +4021,8 @@ static int unload_module(void)
/* XXX what about the thread ? */
/* XXX what about the memory allocated ? */
}
usbradio_tech.capabilities = ast_format_cap_destroy(usbradio_tech.capabilities);
return 0;
}

View File

@ -101,8 +101,6 @@ static char language[MAX_LANGUAGE] = "";
static int gruntdetect_timeout = 3600000; /* Grunt detect timeout is 1hr. */
static const int prefformat = AST_FORMAT_SLINEAR;
/* Protect the interface list (of vpb_pvt's) */
AST_MUTEX_DEFINE_STATIC(iflock);
@ -331,7 +329,7 @@ static struct vpb_pvt {
static struct ast_channel *vpb_new(struct vpb_pvt *i, enum ast_channel_state state, const char *context, const char *linkedid);
static void *do_chanreads(void *pvt);
static struct ast_channel *vpb_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause);
static struct ast_channel *vpb_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, void *data, int *cause);
static int vpb_digit_begin(struct ast_channel *ast, char digit);
static int vpb_digit_end(struct ast_channel *ast, char digit, unsigned int duration);
static int vpb_call(struct ast_channel *ast, char *dest, int timeout);
@ -346,7 +344,7 @@ static int vpb_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
static struct ast_channel_tech vpb_tech = {
type: "vpb",
description: tdesc,
capabilities: AST_FORMAT_SLINEAR,
capabilities: NULL,
properties: 0,
requester: vpb_request,
devicestate: NULL,
@ -380,7 +378,7 @@ static struct ast_channel_tech vpb_tech = {
static struct ast_channel_tech vpb_tech_indicate = {
type: "vpb",
description: tdesc,
capabilities: AST_FORMAT_SLINEAR,
capabilities: NULL,
properties: 0,
requester: vpb_request,
devicestate: NULL,
@ -755,10 +753,11 @@ static void get_callerid_ast(struct vpb_pvt *p)
#endif
vpb_record_buf_start(p->handle, VPB_MULAW);
while ((rc == 0) && (sam_count < 8000 * 3)) {
struct ast_format tmpfmt;
vrc = vpb_record_buf_sync(p->handle, (char*)buf, sizeof(buf));
if (vrc != VPB_OK)
ast_log(LOG_ERROR, "%s: Caller ID couldn't read audio buffer!\n", p->dev);
rc = callerid_feed(cs, (unsigned char *)buf, sizeof(buf), AST_FORMAT_ULAW);
rc = callerid_feed(cs, (unsigned char *)buf, sizeof(buf), ast_format_set(&tmpfmt, AST_FORMAT_ULAW, 0));
#ifdef ANALYSE_CID
vpb_wave_write(ws, (char *)buf, sizeof(buf));
#endif
@ -2096,9 +2095,9 @@ static struct ast_frame *vpb_read(struct ast_channel *ast)
return &f;
}
static inline AudioCompress ast2vpbformat(format_t ast_format)
static inline AudioCompress ast2vpbformat(struct ast_format *format)
{
switch (ast_format) {
switch (format->id) {
case AST_FORMAT_ALAW:
return VPB_ALAW;
case AST_FORMAT_SLINEAR:
@ -2112,9 +2111,9 @@ static inline AudioCompress ast2vpbformat(format_t ast_format)
}
}
static inline const char * ast2vpbformatname(format_t ast_format)
static inline const char * ast2vpbformatname(struct ast_format *format)
{
switch(ast_format) {
switch(format->id) {
case AST_FORMAT_ALAW:
return "AST_FORMAT_ALAW:VPB_ALAW";
case AST_FORMAT_SLINEAR:
@ -2128,9 +2127,9 @@ static inline const char * ast2vpbformatname(format_t ast_format)
}
}
static inline int astformatbits(format_t ast_format)
static inline int astformatbits(struct ast_format *format)
{
switch (ast_format) {
switch (format->id) {
case AST_FORMAT_SLINEAR:
return 16;
case AST_FORMAT_ADPCM:
@ -2174,7 +2173,7 @@ static int vpb_write(struct ast_channel *ast, struct ast_frame *frame)
/* ast_mutex_unlock(&p->lock); */
return 0;
} else if (ast->_state != AST_STATE_UP) {
ast_verb(4, "%s: vpb_write: Attempt to Write frame type[%d]subclass[%s] on not up chan(state[%d])\n", ast->name, frame->frametype, ast_getformatname(frame->subclass.codec), ast->_state);
ast_verb(4, "%s: vpb_write: Attempt to Write frame type[%d]subclass[%s] on not up chan(state[%d])\n", ast->name, frame->frametype, ast_getformatname(&frame->subclass.format), ast->_state);
p->lastoutput = -1;
/* ast_mutex_unlock(&p->lock); */
return 0;
@ -2182,9 +2181,9 @@ static int vpb_write(struct ast_channel *ast, struct ast_frame *frame)
/* ast_debug(1, "%s: vpb_write: Checked frame type..\n", p->dev); */
fmt = ast2vpbformat(frame->subclass.codec);
fmt = ast2vpbformat(&frame->subclass.format);
if (fmt < 0) {
ast_log(LOG_WARNING, "%s: vpb_write: Cannot handle frames of %s format!\n", ast->name, ast_getformatname(frame->subclass.codec));
ast_log(LOG_WARNING, "%s: vpb_write: Cannot handle frames of %s format!\n", ast->name, ast_getformatname(&frame->subclass.format));
return -1;
}
@ -2208,7 +2207,7 @@ static int vpb_write(struct ast_channel *ast, struct ast_frame *frame)
/* Check if we have set up the play_buf */
if (p->lastoutput == -1) {
vpb_play_buf_start(p->handle, fmt);
ast_verb(2, "%s: vpb_write: Starting play mode (codec=%d)[%s]\n", p->dev, fmt, ast2vpbformatname(frame->subclass.codec));
ast_verb(2, "%s: vpb_write: Starting play mode (codec=%d)[%s]\n", p->dev, fmt, ast2vpbformatname(&frame->subclass.format));
p->lastoutput = fmt;
ast_mutex_unlock(&p->play_lock);
return 0;
@ -2258,7 +2257,7 @@ static void *do_chanreads(void *pvt)
struct ast_frame *fr = &p->fr;
char *readbuf = ((char *)p->buf) + AST_FRIENDLY_OFFSET;
int bridgerec = 0;
format_t afmt;
struct ast_format tmpfmt;
int readlen, res, trycnt=0;
AudioCompress fmt;
int ignore_dtmf;
@ -2353,26 +2352,23 @@ static void *do_chanreads(void *pvt)
}
ast_mutex_unlock(&p->play_dtmf_lock);
/* afmt = (p->owner) ? p->owner->rawreadformat : AST_FORMAT_SLINEAR; */
if (p->owner) {
afmt = p->owner->rawreadformat;
/* ast_debug(1,"%s: Record using owner format [%s]\n", p->dev, ast2vpbformatname(afmt)); */
ast_format_copy(&tmpfmt, &p->owner->rawreadformat);
} else {
afmt = AST_FORMAT_SLINEAR;
/* ast_debug(1,"%s: Record using default format [%s]\n", p->dev, ast2vpbformatname(afmt)); */
ast_format_set(&tmpfmt, AST_FORMAT_SLINEAR, 0);
}
fmt = ast2vpbformat(afmt);
fmt = ast2vpbformat(&tmpfmt);
if (fmt < 0) {
ast_log(LOG_WARNING, "%s: Record failure (unsupported format %s)\n", p->dev, ast_getformatname(afmt));
ast_log(LOG_WARNING, "%s: Record failure (unsupported format %s)\n", p->dev, ast_getformatname(&tmpfmt));
return NULL;
}
readlen = VPB_SAMPLES * astformatbits(afmt) / 8;
readlen = VPB_SAMPLES * astformatbits(&tmpfmt) / 8;
if (p->lastinput == -1) {
vpb_record_buf_start(p->handle, fmt);
/* vpb_reset_record_fifo_alarm(p->handle); */
p->lastinput = fmt;
ast_verb(2, "%s: Starting record mode (codec=%d)[%s]\n", p->dev, fmt, ast2vpbformatname(afmt));
ast_verb(2, "%s: Starting record mode (codec=%d)[%s]\n", p->dev, fmt, ast2vpbformatname(&tmpfmt));
continue;
} else if (p->lastinput != fmt) {
vpb_record_buf_finish(p->handle);
@ -2391,7 +2387,7 @@ static void *do_chanreads(void *pvt)
a_gain_vector(p->rxswgain - MAX_VPB_GAIN, (short *)readbuf, readlen / sizeof(short));
ast_verb(6, "%s: chanreads: applied gain\n", p->dev);
fr->subclass.codec = afmt;
ast_format_copy(&fr->subclass.format, &tmpfmt);
fr->data.ptr = readbuf;
fr->datalen = readlen;
fr->frametype = AST_FRAME_VOICE;
@ -2471,6 +2467,7 @@ static struct ast_channel *vpb_new(struct vpb_pvt *me, enum ast_channel_state st
struct ast_channel *tmp;
char cid_num[256];
char cid_name[256];
struct ast_format tmpfmt;
if (me->owner) {
ast_log(LOG_WARNING, "Called vpb_new on owned channel (%s) ?!\n", me->dev);
@ -2493,9 +2490,9 @@ static struct ast_channel *vpb_new(struct vpb_pvt *me, enum ast_channel_state st
* they are all converted to/from linear in the vpb code. Best for us to use
* linear since we can then adjust volume in this modules.
*/
tmp->nativeformats = prefformat;
tmp->rawreadformat = AST_FORMAT_SLINEAR;
tmp->rawwriteformat = AST_FORMAT_SLINEAR;
ast_format_cap_add(tmp->nativeformats, ast_format_set(&tmpfmt, AST_FORMAT_SLINEAR, 0));
ast_format_copy(&tmp->rawreadformat, &tmpfmt);
ast_format_copy(&tmp->rawwriteformat, &tmpfmt);
if (state == AST_STATE_RING) {
tmp->rings = 1;
cid_name[0] = '\0';
@ -2541,19 +2538,20 @@ static struct ast_channel *vpb_new(struct vpb_pvt *me, enum ast_channel_state st
return tmp;
}
static struct ast_channel *vpb_request(const char *type, format_t format, const struct ast_channel *requestor, void *vdata, int *cause)
static struct ast_channel *vpb_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, void *vdata, int *cause)
{
format_t oldformat;
struct vpb_pvt *p;
struct ast_channel *tmp = NULL;
char *sepstr, *data = (char *)vdata, *name;
const char *s;
int group = -1;
struct ast_format slin;
oldformat = format;
format &= prefformat;
if (!format) {
ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format '%s'\n", ast_getformatname(oldformat));
ast_format_set(&slin, AST_FORMAT_SLINEAR, 0);
if (!(ast_format_cap_iscompatible(cap, &slin))) {
char tmp[256];
ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format '%s'\n", ast_getformatname_multiple(tmp, sizeof(tmp), cap));
return NULL;
}
@ -2675,6 +2673,8 @@ static int unload_module(void)
ast_free(bridges);
}
ast_format_cap_destroy(vpb_tech.capabilities);
ast_format_cap_destroy(vpb_tech_indicate.capabilities);
return 0;
}
@ -2698,8 +2698,17 @@ static enum ast_module_load_result load_module()
int bal2 = -1;
int bal3 = -1;
char * callerid = NULL;
struct ast_format tmpfmt;
int num_cards = 0;
if (!(vpb_tech.capabilities = ast_format_cap_alloc())) {
return AST_MODULE_LOAD_DECLINE;
}
if (!(vpb_tech_indicate.capabilities = ast_format_cap_alloc())) {
return AST_MODULE_LOAD_DECLINE;
}
ast_format_cap_add(vpb_tech.capabilities, ast_format_set(&tmpfmt, AST_FORMAT_SLINEAR, 0));
ast_format_cap_add(vpb_tech_indicate.capabilities, ast_format_set(&tmpfmt, AST_FORMAT_SLINEAR, 0));
try {
num_cards = vpb_get_num_cards();
} catch (std::exception e) {

View File

@ -1770,20 +1770,21 @@ PBoolean MyH323Connection::OnReceivedCapabilitySet(const H323Capabilities & remo
if ((subType == codecs[x].h245_cap) && (!codecs[x].formatName || (!strcmp(codecs[x].formatName, (const char *)remoteCapabilities[i].GetFormatName())))) {
int ast_codec = codecs[x].asterisk_codec;
int ms = 0;
if (!(peer_capabilities & ast_codec)) {
struct ast_format tmpfmt;
if (!(peer_capabilities & ast_format_id_to_old_bitfield((enum ast_format_id) ast_codec))) {
struct ast_format_list format;
ast_codec_pref_append(&prefs, ast_codec);
format = ast_codec_pref_getsize(&prefs, ast_codec);
ast_codec_pref_append(&prefs, ast_format_set(&tmpfmt, (enum ast_format_id) ast_codec, 0));
format = ast_codec_pref_getsize(&prefs, &tmpfmt);
if ((ast_codec == AST_FORMAT_ALAW) || (ast_codec == AST_FORMAT_ULAW)) {
ms = remoteCapabilities[i].GetTxFramesInPacket();
} else
ms = remoteCapabilities[i].GetTxFramesInPacket() * format.inc_ms;
ast_codec_pref_setsize(&prefs, ast_codec, ms);
ast_codec_pref_setsize(&prefs, &tmpfmt, ms);
}
if (h323debug) {
cout << "Found peer capability " << remoteCapabilities[i] << ", Asterisk code is " << ast_codec << ", frame size (in ms) is " << ms << endl;
}
peer_capabilities |= ast_codec;
peer_capabilities |= ast_format_id_to_old_bitfield((enum ast_format_id) ast_codec);
}
}
break;
@ -1846,12 +1847,7 @@ PBoolean MyH323Connection::OnReceivedCapabilitySet(const H323Capabilities & remo
break;
}
}
if (h323debug) {
char caps_str[1024], caps2_str[1024];
ast_codec_pref_string(&prefs, caps2_str, sizeof(caps2_str));
cout << "Peer capabilities = " << ast_getformatname_multiple(caps_str, sizeof(caps_str), peer_capabilities)
<< ", ordered list is " << caps2_str << endl;
}
#if 0
redir_capabilities &= peer_capabilities;
#endif
@ -1897,38 +1893,37 @@ void MyH323Connection::SetCapabilities(int caps, int dtmf_mode, void *_prefs, in
int alreadysent = 0;
int codec;
int x, y;
char caps_str[1024];
struct ast_codec_pref *prefs = (struct ast_codec_pref *)_prefs;
struct ast_format_list format;
int frames_per_packet;
struct ast_format tmpfmt;
H323Capability *cap;
localCapabilities.RemoveAll();
if (h323debug) {
cout << "Setting capabilities to " << ast_getformatname_multiple(caps_str, sizeof(caps_str), caps) << endl;
ast_codec_pref_string(prefs, caps_str, sizeof(caps_str));
cout << "Capabilities in preference order is " << caps_str << endl;
}
/* Add audio codecs in preference order first, then
audio codecs without preference as allowed by mask */
for (y = 0, x = -1; x < 32 + 32; ++x) {
ast_format_clear(&tmpfmt);
if (x < 0)
codec = pref_codec;
else if (y || (!(codec = ast_codec_pref_index(prefs, x)))) {
else if (y || (!(ast_codec_pref_index(prefs, x, &tmpfmt)))) {
if (!y)
y = 1;
else
y <<= 1;
codec = y;
}
if (!(caps & codec) || (alreadysent & codec) || !(codec & AST_FORMAT_AUDIO_MASK))
if (tmpfmt.id) {
codec = ast_format_to_old_bitfield(&tmpfmt);
}
if (!(caps & codec) || (alreadysent & codec) || (AST_FORMAT_GET_TYPE(ast_format_id_from_old_bitfield(codec)) != AST_FORMAT_TYPE_AUDIO))
continue;
alreadysent |= codec;
/* format.cur_ms will be set to default if packetization is not explicitly set */
format = ast_codec_pref_getsize(prefs, codec);
format = ast_codec_pref_getsize(prefs, ast_format_from_old_bitfield(&tmpfmt, codec));
frames_per_packet = (format.inc_ms ? format.cur_ms / format.inc_ms : format.cur_ms);
switch(codec) {
switch(ast_format_id_from_old_bitfield(codec)) {
#if 0
case AST_FORMAT_SPEEX:
/* Not real sure if Asterisk acutally supports all

View File

@ -30,7 +30,7 @@
#define CHAN_H323_H
#include <arpa/inet.h>
#include "asterisk/frame_defs.h"
#include "asterisk/format.h"
/*
* Enable support for sending/reception of tunnelled Q.SIG messages and
@ -47,6 +47,8 @@
#define H323_HOLD_Q931ONLY (1 << 1)
#define H323_HOLD_H450 (1 << 2)
typedef int64_t h323_format;
/** call_option struct holds various bits
* of information for each call */
typedef struct call_options {
@ -65,7 +67,7 @@ typedef struct call_options {
int progress_audio;
int dtmfcodec[2];
int dtmfmode;
format_t capability;
h323_format capability;
int bridge;
int nat;
int tunnelOptions;

View File

@ -218,9 +218,9 @@ static void dump_versioned_codec(char *output, int maxlen, void *value, int len)
{
char *version = (char *) value;
if (version[0] == 0) {
if (len == (int) (sizeof(format_t) + sizeof(char))) {
format_t codec = ntohll(get_unaligned_uint64(value + 1));
ast_copy_string(output, ast_getformatname(codec), maxlen);
if (len == (int) (sizeof(iax2_format) + sizeof(char))) {
iax2_format codec = ntohll(get_unaligned_uint64(value + 1));
ast_copy_string(output, iax2_getformatname(codec), maxlen);
} else {
ast_copy_string(output, "Invalid length!", maxlen);
}
@ -804,11 +804,11 @@ int iax_parse_ies(struct iax_ies *ies, unsigned char *data, int datalen)
{
int version = data[2];
if (version == 0) {
if (len != (int)sizeof(char) + sizeof(format_t)) {
snprintf(tmp, (int)sizeof(tmp), "Expecting capability to be %d bytes long but was %d\n", (int) (sizeof(format_t) + sizeof(char)), len);
if (len != (int)sizeof(char) + sizeof(iax2_format)) {
snprintf(tmp, (int)sizeof(tmp), "Expecting capability to be %d bytes long but was %d\n", (int) (sizeof(iax2_format) + sizeof(char)), len);
errorf(tmp);
} else {
ies->capability = (format_t) ntohll(get_unaligned_uint64(data + 3));
ies->capability = (iax2_format) ntohll(get_unaligned_uint64(data + 3));
}
} /* else unknown version */
}
@ -825,11 +825,11 @@ int iax_parse_ies(struct iax_ies *ies, unsigned char *data, int datalen)
{
int version = data[2];
if (version == 0) {
if (len != (int)sizeof(char) + sizeof(format_t)) {
snprintf(tmp, (int)sizeof(tmp), "Expecting format to be %d bytes long but was %d\n", (int) (sizeof(format_t) + sizeof(char)), len);
if (len != (int)sizeof(char) + sizeof(iax2_format)) {
snprintf(tmp, (int)sizeof(tmp), "Expecting format to be %d bytes long but was %d\n", (int) (sizeof(iax2_format) + sizeof(char)), len);
errorf(tmp);
} else {
ies->format = (format_t) ntohll(get_unaligned_uint64(data + 3));
ies->format = (iax2_format) ntohll(get_unaligned_uint64(data + 3));
}
} /* else unknown version */
}
@ -1138,7 +1138,7 @@ int iax_parse_ies(struct iax_ies *ies, unsigned char *data, int datalen)
void iax_frame_wrap(struct iax_frame *fr, struct ast_frame *f)
{
fr->af.frametype = f->frametype;
fr->af.subclass.codec = f->subclass.codec;
ast_format_copy(&fr->af.subclass.format, &f->subclass.format);
fr->af.mallocd = 0; /* Our frame is static relative to the container */
fr->af.datalen = f->datalen;
fr->af.samples = f->samples;
@ -1157,7 +1157,7 @@ void iax_frame_wrap(struct iax_frame *fr, struct ast_frame *f)
}
#if __BYTE_ORDER == __LITTLE_ENDIAN
/* We need to byte-swap slinear samples from network byte order */
if ((fr->af.frametype == AST_FRAME_VOICE) && (fr->af.subclass.codec == AST_FORMAT_SLINEAR)) {
if ((fr->af.frametype == AST_FRAME_VOICE) && (fr->af.subclass.format.id == AST_FORMAT_SLINEAR)) {
/* 2 bytes / sample for SLINEAR */
ast_swapcopy_samples(fr->af.data.ptr, f->data.ptr, copy_len / 2);
} else

View File

@ -20,7 +20,7 @@
#include "asterisk/linkedlists.h"
#include "asterisk/crypto.h"
#include "asterisk/frame_defs.h"
#include "iax2.h"
struct iax_ies {
char *called_number;
@ -33,8 +33,8 @@ struct iax_ies {
char *called_context;
char *username;
char *password;
format_t capability;
format_t format;
iax2_format capability;
iax2_format format;
char *codec_prefs;
char *language;
int version;

View File

@ -59,7 +59,7 @@ struct iax_template {
unsigned short serverport;
unsigned int altserver;
unsigned int flags;
unsigned int format;
iax2_format format;
unsigned int tos;
AST_LIST_ENTRY(iax_template) list;
};
@ -340,8 +340,9 @@ static int iax_template_parse(struct iax_template *cur, struct ast_config *cfg,
} else
ast_log(LOG_WARNING, "Ignoring invalid %s '%s' for '%s' at line %d\n", v->name, v->value, s, v->lineno);
} else if (!strcasecmp(v->name, "codec")) {
if ((x = ast_getformatbyname(v->value)) > 0) {
cur->format = x;
struct ast_format tmpfmt;
if ((ast_getformatbyname(v->value, &tmpfmt)) > 0) {
cur->format = ast_format_to_old_bitfield(&tmpfmt);
} else
ast_log(LOG_WARNING, "Ignoring invalid codec '%s' for '%s' at line %d\n", v->value, s, v->lineno);
} else if (!strcasecmp(v->name, "tos")) {
@ -468,7 +469,7 @@ static char *iax_show_provisioning(struct ast_cli_entry *e, int cmd, struct ast_
ast_cli(a->fd, "Server Port: %d\n", cur->serverport);
ast_cli(a->fd, "Alternate: %s\n", alternate);
ast_cli(a->fd, "Flags: %s\n", iax_provflags2str(flags, sizeof(flags), cur->flags));
ast_cli(a->fd, "Format: %s\n", ast_getformatname(cur->format));
ast_cli(a->fd, "Format: %s\n", iax2_getformatname(cur->format));
ast_cli(a->fd, "TOS: 0x%x\n", cur->tos);
found++;
}

View File

@ -214,6 +214,12 @@ enum iax_frame_subclass {
#define IAX_DPSTATUS_IGNOREPAT (1 << 14)
#define IAX_DPSTATUS_MATCHMORE (1 << 15)
/*! iax2 format bit field for handling codecs the old way */
typedef int64_t iax2_format;
/*!\brief iax2 wrapper function for ast_getformatname */
char *iax2_getformatname(iax2_format format);
/*! Full frames are always delivered reliably */
struct ast_iax2_full_hdr {
unsigned short scallno; /*!< Source call number -- high bit must be 1 */

View File

@ -28,7 +28,7 @@ extern struct ast_sockaddr bindaddr; /*!< UDP: The address we bind to */
extern struct ast_sched_context *sched; /*!< The scheduling context */
/*! \brief Definition of this channel for PBX channel registration */
extern const struct ast_channel_tech sip_tech;
extern struct ast_channel_tech sip_tech;
/*! \brief This version of the sip channel tech has no send_digit_begin
* callback so that the core knows that the channel does not want

View File

@ -216,7 +216,6 @@
#define DEFAULT_SDPSESSION "Asterisk PBX" /*!< Default SDP session name, (s=) header unless re-defined in sip.conf */
#define DEFAULT_SDPOWNER "root" /*!< Default SDP username field in (o=) header unless re-defined in sip.conf */
#define DEFAULT_ENGINE "asterisk" /*!< Default RTP engine to use for sessions */
#define DEFAULT_CAPABILITY (AST_FORMAT_ULAW | AST_FORMAT_TESTLAW | AST_FORMAT_ALAW | AST_FORMAT_GSM | AST_FORMAT_H263);
#endif
/*@}*/
@ -695,7 +694,7 @@ struct sip_settings {
char default_context[AST_MAX_CONTEXT];
char default_subscribecontext[AST_MAX_CONTEXT];
struct ast_ha *contact_ha; /*! \brief Global list of addresses dynamic peers are not allowed to use */
format_t capability; /*!< Supported codecs */
struct ast_format_cap *caps; /*!< Supported codecs */
int tcp_enabled;
int default_max_forwards; /*!< Default max forwards (SIP Anti-loop) */
};
@ -995,13 +994,13 @@ struct sip_pvt {
unsigned int sipoptions; /*!< Supported SIP options on the other end */
unsigned int reqsipoptions; /*!< Required SIP options on the other end */
struct ast_codec_pref prefs; /*!< codec prefs */
format_t capability; /*!< Special capability (codec) */
format_t jointcapability; /*!< Supported capability at both ends (codecs) */
format_t peercapability; /*!< Supported peer capability */
format_t prefcodec; /*!< Preferred codec (outbound only) */
struct ast_format_cap *caps; /*!< Special capability (codec) */
struct ast_format_cap *jointcaps; /*!< Supported capability at both ends (codecs) */
struct ast_format_cap *peercaps; /*!< Supported peer capability */
struct ast_format_cap *redircaps; /*!< Redirect codecs */
struct ast_format_cap *prefcaps; /*!< Preferred codec (outbound only) */
int noncodeccapability; /*!< DTMF RFC2833 telephony-event */
int jointnoncodeccapability; /*!< Joint Non codec capability */
format_t redircodecs; /*!< Redirect codecs */
int maxcallbitrate; /*!< Maximum Call Bitrate for Video Calls */
int t38_maxdatagram; /*!< T.38 FaxMaxDatagram override */
int request_queue_sched_id; /*!< Scheduler ID of any scheduled action to process queued requests */
@ -1217,7 +1216,7 @@ struct sip_peer {
int maxcallbitrate; /*!< Maximum Bitrate for a video call */
int expire; /*!< When to expire this peer registration */
format_t capability; /*!< Codec capability */
struct ast_format_cap *caps; /*!< Codec capability */
int rtptimeout; /*!< RTP timeout */
int rtpholdtimeout; /*!< RTP Hold Timeout */
int rtpkeepalive; /*!< Send RTP packets for keepalive */

View File

@ -76,8 +76,6 @@ static int ulawtoalaw_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
static struct ast_translator alawtoulaw = {
.name = "alawtoulaw",
.srcfmt = AST_FORMAT_ALAW,
.dstfmt = AST_FORMAT_ULAW,
.framein = alawtoulaw_framein,
.sample = alaw_sample,
.buffer_samples = BUFFER_SAMPLES,
@ -86,8 +84,6 @@ static struct ast_translator alawtoulaw = {
static struct ast_translator ulawtoalaw = {
.name = "ulawtoalaw",
.srcfmt = AST_FORMAT_ULAW,
.dstfmt = AST_FORMAT_ALAW,
.framein = ulawtoalaw_framein,
.sample = ulaw_sample,
.buffer_samples = BUFFER_SAMPLES,
@ -111,6 +107,12 @@ static int load_module(void)
int res;
int x;
ast_format_set(&alawtoulaw.src_format, AST_FORMAT_ALAW, 0);
ast_format_set(&alawtoulaw.dst_format, AST_FORMAT_ULAW, 0);
ast_format_set(&ulawtoalaw.src_format, AST_FORMAT_ULAW, 0);
ast_format_set(&ulawtoalaw.dst_format, AST_FORMAT_ALAW, 0);
for (x=0;x<256;x++) {
mu2a[x] = AST_LIN2A(AST_MULAW(x));
a2mu[x] = AST_LIN2MU(AST_ALAW(x));

View File

@ -286,8 +286,6 @@ static struct ast_frame *lintoadpcm_frameout(struct ast_trans_pvt *pvt)
static struct ast_translator adpcmtolin = {
.name = "adpcmtolin",
.srcfmt = AST_FORMAT_ADPCM,
.dstfmt = AST_FORMAT_SLINEAR,
.framein = adpcmtolin_framein,
.sample = adpcm_sample,
.desc_size = sizeof(struct adpcm_decoder_pvt),
@ -297,8 +295,6 @@ static struct ast_translator adpcmtolin = {
static struct ast_translator lintoadpcm = {
.name = "lintoadpcm",
.srcfmt = AST_FORMAT_SLINEAR,
.dstfmt = AST_FORMAT_ADPCM,
.framein = lintoadpcm_framein,
.frameout = lintoadpcm_frameout,
.sample = slin8_sample,
@ -327,6 +323,12 @@ static int load_module(void)
{
int res;
ast_format_set(&adpcmtolin.src_format, AST_FORMAT_ADPCM, 0);
ast_format_set(&adpcmtolin.dst_format, AST_FORMAT_SLINEAR, 0);
ast_format_set(&lintoadpcm.src_format, AST_FORMAT_SLINEAR, 0);
ast_format_set(&lintoadpcm.dst_format, AST_FORMAT_ADPCM, 0);
res = ast_register_translator(&adpcmtolin);
if (!res)
res = ast_register_translator(&lintoadpcm);

View File

@ -73,8 +73,6 @@ static int lintoalaw_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
static struct ast_translator alawtolin = {
.name = "alawtolin",
.srcfmt = AST_FORMAT_ALAW,
.dstfmt = AST_FORMAT_SLINEAR,
.framein = alawtolin_framein,
.sample = alaw_sample,
.buffer_samples = BUFFER_SAMPLES,
@ -83,8 +81,6 @@ static struct ast_translator alawtolin = {
static struct ast_translator lintoalaw = {
"lintoalaw",
.srcfmt = AST_FORMAT_SLINEAR,
.dstfmt = AST_FORMAT_ALAW,
.framein = lintoalaw_framein,
.sample = slin8_sample,
.buffer_samples = BUFFER_SAMPLES,
@ -112,6 +108,12 @@ static int load_module(void)
{
int res;
ast_format_set(&lintoalaw.src_format, AST_FORMAT_SLINEAR, 0);
ast_format_set(&lintoalaw.dst_format, AST_FORMAT_ALAW, 0);
ast_format_set(&alawtolin.src_format, AST_FORMAT_ALAW, 0);
ast_format_set(&alawtolin.dst_format, AST_FORMAT_SLINEAR, 0);
res = ast_register_translator(&alawtolin);
if (!res)
res = ast_register_translator(&lintoalaw);

View File

@ -179,7 +179,7 @@ static int dahdi_encoder_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
{
struct codec_dahdi_pvt *dahdip = pvt->pvt;
if (!f->subclass.codec) {
if (!f->subclass.format.id) {
/* We're just faking a return for calculation purposes. */
dahdip->fake = 2;
pvt->samples = f->samples;
@ -227,7 +227,7 @@ static struct ast_frame *dahdi_encoder_frameout(struct ast_trans_pvt *pvt)
if (2 == dahdip->fake) {
dahdip->fake = 1;
pvt->f.frametype = AST_FRAME_VOICE;
pvt->f.subclass.codec = 0;
ast_format_clear(&pvt->f.subclass.format);
pvt->f.samples = dahdip->required_samples;
pvt->f.data.ptr = NULL;
pvt->f.offset = 0;
@ -255,7 +255,7 @@ static struct ast_frame *dahdi_encoder_frameout(struct ast_trans_pvt *pvt)
pvt->f.datalen = res;
pvt->f.samples = dahdip->required_samples;
pvt->f.frametype = AST_FRAME_VOICE;
pvt->f.subclass.codec = 1 << (pvt->t->dstfmt);
ast_format_copy(&pvt->f.subclass.format, &pvt->t->dst_format);
pvt->f.mallocd = 0;
pvt->f.offset = AST_FRIENDLY_OFFSET;
pvt->f.src = pvt->t->name;
@ -274,7 +274,7 @@ static int dahdi_decoder_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
{
struct codec_dahdi_pvt *dahdip = pvt->pvt;
if (!f->subclass.codec) {
if (!f->subclass.format.id) {
/* We're just faking a return for calculation purposes. */
dahdip->fake = 2;
pvt->samples = f->samples;
@ -300,7 +300,7 @@ static struct ast_frame *dahdi_decoder_frameout(struct ast_trans_pvt *pvt)
if (2 == dahdip->fake) {
dahdip->fake = 1;
pvt->f.frametype = AST_FRAME_VOICE;
pvt->f.subclass.codec = 0;
ast_format_clear(&pvt->f.subclass.format);
pvt->f.samples = dahdip->required_samples;
pvt->f.data.ptr = NULL;
pvt->f.offset = 0;
@ -338,7 +338,7 @@ static struct ast_frame *dahdi_decoder_frameout(struct ast_trans_pvt *pvt)
}
pvt->datalen = 0;
pvt->f.frametype = AST_FRAME_VOICE;
pvt->f.subclass.codec = 1 << (pvt->t->dstfmt);
ast_format_copy(&pvt->f.subclass.format, &pvt->t->dst_format);
pvt->f.mallocd = 0;
pvt->f.offset = AST_FRIENDLY_OFFSET;
pvt->f.src = pvt->t->name;
@ -371,7 +371,7 @@ static void dahdi_destroy(struct ast_trans_pvt *pvt)
close(dahdip->fd);
}
static int dahdi_translate(struct ast_trans_pvt *pvt, int dest, int source)
static int dahdi_translate(struct ast_trans_pvt *pvt, struct ast_format *dst_format, struct ast_format *src_format)
{
/* Request translation through zap if possible */
int fd;
@ -385,10 +385,10 @@ static int dahdi_translate(struct ast_trans_pvt *pvt, int dest, int source)
return -1;
}
dahdip->fmts.srcfmt = (1 << source);
dahdip->fmts.dstfmt = (1 << dest);
dahdip->fmts.srcfmt = ast_format_to_old_bitfield(src_format);
dahdip->fmts.dstfmt = ast_format_to_old_bitfield(dst_format);
ast_debug(1, "Opening transcoder channel from %d to %d.\n", source, dest);
ast_debug(1, "Opening transcoder channel from %s to %s.\n", ast_getformatname(src_format), ast_getformatname(dst_format));
retry:
if (ioctl(fd, DAHDI_TC_ALLOCATE, &dahdip->fmts)) {
@ -401,14 +401,14 @@ retry:
* support for ULAW instead of signed linear and then
* we'll just convert from ulaw to signed linear in
* software. */
if (AST_FORMAT_SLINEAR == dahdip->fmts.srcfmt) {
if (AST_FORMAT_SLINEAR == ast_format_id_from_old_bitfield(dahdip->fmts.srcfmt)) {
ast_debug(1, "Using soft_slin support on source\n");
dahdip->softslin = 1;
dahdip->fmts.srcfmt = AST_FORMAT_ULAW;
} else if (AST_FORMAT_SLINEAR == dahdip->fmts.dstfmt) {
dahdip->fmts.srcfmt = ast_format_id_to_old_bitfield(AST_FORMAT_ULAW);
} else if (AST_FORMAT_SLINEAR == ast_format_id_from_old_bitfield(dahdip->fmts.dstfmt)) {
ast_debug(1, "Using soft_slin support on destination\n");
dahdip->softslin = 1;
dahdip->fmts.dstfmt = AST_FORMAT_ULAW;
dahdip->fmts.dstfmt = ast_format_id_to_old_bitfield(AST_FORMAT_ULAW);
}
tried_once = 1;
goto retry;
@ -427,9 +427,9 @@ retry:
dahdip->fd = fd;
dahdip->required_samples = ((dahdip->fmts.dstfmt|dahdip->fmts.srcfmt)&AST_FORMAT_G723_1) ? G723_SAMPLES : G729_SAMPLES;
dahdip->required_samples = ((dahdip->fmts.dstfmt|dahdip->fmts.srcfmt) & (ast_format_id_to_old_bitfield(AST_FORMAT_G723_1))) ? G723_SAMPLES : G729_SAMPLES;
switch (dahdip->fmts.dstfmt) {
switch (ast_format_id_from_old_bitfield(dahdip->fmts.dstfmt)) {
case AST_FORMAT_G729A:
ast_atomic_fetchadd_int(&channels.encoders, +1);
break;
@ -446,7 +446,9 @@ retry:
static int dahdi_new(struct ast_trans_pvt *pvt)
{
return dahdi_translate(pvt, pvt->t->dstfmt, pvt->t->srcfmt);
return dahdi_translate(pvt,
&pvt->t->dst_format,
&pvt->t->src_format);
}
static struct ast_frame *fakesrc_sample(void)
@ -463,7 +465,9 @@ static struct ast_frame *fakesrc_sample(void)
static int is_encoder(struct translator *zt)
{
if (zt->t.srcfmt&(AST_FORMAT_ULAW|AST_FORMAT_ALAW|AST_FORMAT_SLINEAR)) {
if ((zt->t.src_format.id == AST_FORMAT_ULAW) ||
(zt->t.src_format.id == AST_FORMAT_ALAW) ||
(zt->t.src_format.id == AST_FORMAT_SLINEAR)) {
return 1;
} else {
return 0;
@ -474,15 +478,20 @@ static int register_translator(int dst, int src)
{
struct translator *zt;
int res;
struct ast_format dst_format;
struct ast_format src_format;
ast_format_from_old_bitfield(&dst_format, (1 << dst));
ast_format_from_old_bitfield(&src_format, (1 << src));
if (!(zt = ast_calloc(1, sizeof(*zt)))) {
return -1;
}
snprintf((char *) (zt->t.name), sizeof(zt->t.name), "zap%sto%s",
ast_getformatname((1 << src)), ast_getformatname((1 << dst)));
zt->t.srcfmt = (1 << src);
zt->t.dstfmt = (1 << dst);
ast_getformatname(&src_format), ast_getformatname(&dst_format));
ast_format_copy(&zt->t.src_format, &src_format);
ast_format_copy(&zt->t.dst_format, &dst_format);
zt->t.buf_size = BUFFER_SIZE;
if (is_encoder(zt)) {
zt->t.framein = dahdi_encoder_framein;
@ -518,10 +527,10 @@ static void drop_translator(int dst, int src)
AST_LIST_LOCK(&translators);
AST_LIST_TRAVERSE_SAFE_BEGIN(&translators, cur, entry) {
if (cur->t.srcfmt != src)
if (cur->t.src_format.id != ast_format_id_from_old_bitfield((1 << src)))
continue;
if (cur->t.dstfmt != dst)
if (cur->t.dst_format.id != ast_format_id_from_old_bitfield((1 << dst)))
continue;
AST_LIST_REMOVE_CURRENT(entry);

View File

@ -134,8 +134,6 @@ static int lintog722_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
static struct ast_translator g722tolin = {
.name = "g722tolin",
.srcfmt = AST_FORMAT_G722,
.dstfmt = AST_FORMAT_SLINEAR,
.newpvt = g722tolin_new, /* same for both directions */
.framein = g722tolin_framein,
.sample = g722_sample,
@ -146,8 +144,6 @@ static struct ast_translator g722tolin = {
static struct ast_translator lintog722 = {
.name = "lintog722",
.srcfmt = AST_FORMAT_SLINEAR,
.dstfmt = AST_FORMAT_G722,
.newpvt = lintog722_new, /* same for both directions */
.framein = lintog722_framein,
.sample = slin8_sample,
@ -158,8 +154,6 @@ static struct ast_translator lintog722 = {
static struct ast_translator g722tolin16 = {
.name = "g722tolin16",
.srcfmt = AST_FORMAT_G722,
.dstfmt = AST_FORMAT_SLINEAR16,
.newpvt = g722tolin16_new, /* same for both directions */
.framein = g722tolin_framein,
.sample = g722_sample,
@ -170,8 +164,6 @@ static struct ast_translator g722tolin16 = {
static struct ast_translator lin16tog722 = {
.name = "lin16tog722",
.srcfmt = AST_FORMAT_SLINEAR16,
.dstfmt = AST_FORMAT_G722,
.newpvt = lin16tog722_new, /* same for both directions */
.framein = lintog722_framein,
.sample = slin16_sample,
@ -201,6 +193,18 @@ static int load_module(void)
{
int res = 0;
ast_format_set(&g722tolin.src_format, AST_FORMAT_G722, 0);
ast_format_set(&g722tolin.dst_format, AST_FORMAT_SLINEAR, 0);
ast_format_set(&lintog722.src_format, AST_FORMAT_SLINEAR, 0);
ast_format_set(&lintog722.dst_format, AST_FORMAT_G722, 0);
ast_format_set(&g722tolin16.src_format, AST_FORMAT_G722, 0);
ast_format_set(&g722tolin16.dst_format, AST_FORMAT_SLINEAR16, 0);
ast_format_set(&lin16tog722.src_format, AST_FORMAT_SLINEAR16, 0);
ast_format_set(&lin16tog722.dst_format, AST_FORMAT_G722, 0);
res |= ast_register_translator(&g722tolin);
res |= ast_register_translator(&lintog722);
res |= ast_register_translator(&g722tolin16);

View File

@ -771,8 +771,6 @@ static int lintog726_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
static struct ast_translator g726tolin = {
.name = "g726tolin",
.srcfmt = AST_FORMAT_G726,
.dstfmt = AST_FORMAT_SLINEAR,
.newpvt = lintog726_new, /* same for both directions */
.framein = g726tolin_framein,
.sample = g726_sample,
@ -783,8 +781,6 @@ static struct ast_translator g726tolin = {
static struct ast_translator lintog726 = {
.name = "lintog726",
.srcfmt = AST_FORMAT_SLINEAR,
.dstfmt = AST_FORMAT_G726,
.newpvt = lintog726_new, /* same for both directions */
.framein = lintog726_framein,
.sample = slin8_sample,
@ -795,8 +791,6 @@ static struct ast_translator lintog726 = {
static struct ast_translator g726aal2tolin = {
.name = "g726aal2tolin",
.srcfmt = AST_FORMAT_G726_AAL2,
.dstfmt = AST_FORMAT_SLINEAR,
.newpvt = lintog726_new, /* same for both directions */
.framein = g726aal2tolin_framein,
.sample = g726_sample,
@ -807,8 +801,6 @@ static struct ast_translator g726aal2tolin = {
static struct ast_translator lintog726aal2 = {
.name = "lintog726aal2",
.srcfmt = AST_FORMAT_SLINEAR,
.dstfmt = AST_FORMAT_G726_AAL2,
.newpvt = lintog726_new, /* same for both directions */
.framein = lintog726aal2_framein,
.sample = slin8_sample,
@ -839,6 +831,18 @@ static int load_module(void)
{
int res = 0;
ast_format_set(&g726tolin.src_format, AST_FORMAT_G726, 0);
ast_format_set(&g726tolin.dst_format, AST_FORMAT_SLINEAR, 0);
ast_format_set(&lintog726.src_format, AST_FORMAT_SLINEAR, 0);
ast_format_set(&lintog726.dst_format, AST_FORMAT_G726, 0);
ast_format_set(&g726aal2tolin.src_format, AST_FORMAT_G726_AAL2, 0);
ast_format_set(&g726aal2tolin.dst_format, AST_FORMAT_SLINEAR, 0);
ast_format_set(&lintog726aal2.src_format, AST_FORMAT_SLINEAR, 0);
ast_format_set(&lintog726aal2.dst_format, AST_FORMAT_G726_AAL2, 0);
res |= ast_register_translator(&g726tolin);
res |= ast_register_translator(&lintog726);

View File

@ -168,8 +168,6 @@ static void gsm_destroy_stuff(struct ast_trans_pvt *pvt)
static struct ast_translator gsmtolin = {
.name = "gsmtolin",
.srcfmt = AST_FORMAT_GSM,
.dstfmt = AST_FORMAT_SLINEAR,
.newpvt = gsm_new,
.framein = gsmtolin_framein,
.destroy = gsm_destroy_stuff,
@ -181,8 +179,6 @@ static struct ast_translator gsmtolin = {
static struct ast_translator lintogsm = {
.name = "lintogsm",
.srcfmt = AST_FORMAT_SLINEAR,
.dstfmt = AST_FORMAT_GSM,
.newpvt = gsm_new,
.framein = lintogsm_framein,
.frameout = lintogsm_frameout,
@ -213,6 +209,12 @@ static int load_module(void)
{
int res;
ast_format_set(&gsmtolin.src_format, AST_FORMAT_GSM, 0);
ast_format_set(&gsmtolin.dst_format, AST_FORMAT_SLINEAR, 0);
ast_format_set(&lintogsm.src_format, AST_FORMAT_SLINEAR, 0);
ast_format_set(&lintogsm.dst_format, AST_FORMAT_GSM, 0);
res = ast_register_translator(&gsmtolin);
if (!res)
res=ast_register_translator(&lintogsm);

View File

@ -166,8 +166,6 @@ static struct ast_frame *lintoilbc_frameout(struct ast_trans_pvt *pvt)
static struct ast_translator ilbctolin = {
.name = "ilbctolin",
.srcfmt = AST_FORMAT_ILBC,
.dstfmt = AST_FORMAT_SLINEAR,
.newpvt = ilbctolin_new,
.framein = ilbctolin_framein,
.sample = ilbc_sample,
@ -178,8 +176,6 @@ static struct ast_translator ilbctolin = {
static struct ast_translator lintoilbc = {
.name = "lintoilbc",
.srcfmt = AST_FORMAT_SLINEAR,
.dstfmt = AST_FORMAT_ILBC,
.newpvt = lintoilbc_new,
.framein = lintoilbc_framein,
.frameout = lintoilbc_frameout,
@ -202,6 +198,13 @@ static int load_module(void)
{
int res;
ast_format_set(&ilibctolin.src_format, AST_FORMAT_ILBC, 0);
ast_format_set(&ilibctolin.dst_format, AST_FORMAT_SLINEAR, 0);
ast_format_set(&lintoilbc.src_format, AST_FORMAT_SLINEAR, 0);
ast_format_set(&lintoilbc.dst_format, AST_FORMAT_ILBC, 0);
res = ast_register_translator(&ilbctolin);
if (!res)
res=ast_register_translator(&lintoilbc);

View File

@ -193,8 +193,6 @@ static void lpc10_destroy(struct ast_trans_pvt *arg)
static struct ast_translator lpc10tolin = {
.name = "lpc10tolin",
.srcfmt = AST_FORMAT_LPC10,
.dstfmt = AST_FORMAT_SLINEAR,
.newpvt = lpc10_dec_new,
.framein = lpc10tolin_framein,
.destroy = lpc10_destroy,
@ -206,8 +204,6 @@ static struct ast_translator lpc10tolin = {
static struct ast_translator lintolpc10 = {
.name = "lintolpc10",
.srcfmt = AST_FORMAT_SLINEAR,
.dstfmt = AST_FORMAT_LPC10,
.newpvt = lpc10_enc_new,
.framein = lintolpc10_framein,
.frameout = lintolpc10_frameout,
@ -238,6 +234,12 @@ static int load_module(void)
{
int res;
ast_format_set(&lpc10tolin.src_format, AST_FORMAT_LPC10, 0);
ast_format_set(&lpc10tolin.dst_format, AST_FORMAT_SLINEAR, 0);
ast_format_set(&lintolpc10.src_format, AST_FORMAT_SLINEAR, 0);
ast_format_set(&lintolpc10.dst_format, AST_FORMAT_LPC10, 0);
res = ast_register_translator(&lpc10tolin);
if (!res)
res = ast_register_translator(&lintolpc10);

View File

@ -170,8 +170,6 @@ static int slin8_to_slin16_framein(struct ast_trans_pvt *pvt, struct ast_frame *
static struct ast_translator slin16_to_slin8 = {
.name = "slin16_to_slin8",
.srcfmt = AST_FORMAT_SLINEAR16,
.dstfmt = AST_FORMAT_SLINEAR,
.newpvt = slin16_to_slin8_new,
.destroy = slin16_to_slin8_destroy,
.framein = slin16_to_slin8_framein,
@ -183,8 +181,6 @@ static struct ast_translator slin16_to_slin8 = {
static struct ast_translator slin8_to_slin16 = {
.name = "slin8_to_slin16",
.srcfmt = AST_FORMAT_SLINEAR,
.dstfmt = AST_FORMAT_SLINEAR16,
.newpvt = slin8_to_slin16_new,
.destroy = slin8_to_slin16_destroy,
.framein = slin8_to_slin16_framein,
@ -208,6 +204,12 @@ static int load_module(void)
{
int res = 0;
ast_format_set(&slin16_to_slin8.src_format, AST_FORMAT_SLINEAR16, 0);
ast_format_set(&slin16_to_slin8.dst_format, AST_FORMAT_SLINEAR, 0);
ast_format_set(&slin8_to_slin16.src_format, AST_FORMAT_SLINEAR, 0);
ast_format_set(&slin8_to_slin16.dst_format, AST_FORMAT_SLINEAR16, 0);
res |= ast_register_translator(&slin16_to_slin8);
res |= ast_register_translator(&slin8_to_slin16);

View File

@ -330,8 +330,6 @@ static void lintospeex_destroy(struct ast_trans_pvt *arg)
static struct ast_translator speextolin = {
.name = "speextolin",
.srcfmt = AST_FORMAT_SPEEX,
.dstfmt = AST_FORMAT_SLINEAR,
.newpvt = speextolin_new,
.framein = speextolin_framein,
.destroy = speextolin_destroy,
@ -344,8 +342,6 @@ static struct ast_translator speextolin = {
static struct ast_translator lintospeex = {
.name = "lintospeex",
.srcfmt = AST_FORMAT_SLINEAR,
.dstfmt = AST_FORMAT_SPEEX,
.newpvt = lintospeex_new,
.framein = lintospeex_framein,
.frameout = lintospeex_frameout,
@ -358,8 +354,6 @@ static struct ast_translator lintospeex = {
static struct ast_translator speexwbtolin16 = {
.name = "speexwbtolin16",
.srcfmt = AST_FORMAT_SPEEX16,
.dstfmt = AST_FORMAT_SLINEAR16,
.newpvt = speexwbtolin16_new,
.framein = speextolin_framein,
.destroy = speextolin_destroy,
@ -372,8 +366,6 @@ static struct ast_translator speexwbtolin16 = {
static struct ast_translator lin16tospeexwb = {
.name = "lin16tospeexwb",
.srcfmt = AST_FORMAT_SLINEAR16,
.dstfmt = AST_FORMAT_SPEEX16,
.newpvt = lin16tospeexwb_new,
.framein = lintospeex_framein,
.frameout = lintospeex_frameout,
@ -505,6 +497,19 @@ static int load_module(void)
if (parse_config(0))
return AST_MODULE_LOAD_DECLINE;
ast_format_set(&speextolin.src_format, AST_FORMAT_SPEEX, 0);
ast_format_set(&speextolin.dst_format, AST_FORMAT_SLINEAR, 0);
ast_format_set(&lintospeex.src_format, AST_FORMAT_SLINEAR, 0);
ast_format_set(&lintospeex.dst_format, AST_FORMAT_SPEEX, 0);
ast_format_set(&speexwbtolin16.src_format, AST_FORMAT_SPEEX16, 0);
ast_format_set(&speexwbtolin16.dst_format, AST_FORMAT_SLINEAR16, 0);
ast_format_set(&lin16tospeexwb.src_format, AST_FORMAT_SLINEAR16, 0);
ast_format_set(&lin16tospeexwb.dst_format, AST_FORMAT_SPEEX16, 0);
res |= ast_register_translator(&speextolin);
res |= ast_register_translator(&lintospeex);
res |= ast_register_translator(&speexwbtolin16);

View File

@ -78,8 +78,6 @@ static int lintoulaw_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
static struct ast_translator ulawtolin = {
.name = "ulawtolin",
.srcfmt = AST_FORMAT_ULAW,
.dstfmt = AST_FORMAT_SLINEAR,
.framein = ulawtolin_framein,
.sample = ulaw_sample,
.buffer_samples = BUFFER_SAMPLES,
@ -88,8 +86,6 @@ static struct ast_translator ulawtolin = {
static struct ast_translator testlawtolin = {
.name = "testlawtolin",
.srcfmt = AST_FORMAT_TESTLAW,
.dstfmt = AST_FORMAT_SLINEAR,
.framein = ulawtolin_framein,
.sample = ulaw_sample,
.buffer_samples = BUFFER_SAMPLES,
@ -102,8 +98,6 @@ static struct ast_translator testlawtolin = {
static struct ast_translator lintoulaw = {
.name = "lintoulaw",
.srcfmt = AST_FORMAT_SLINEAR,
.dstfmt = AST_FORMAT_ULAW,
.framein = lintoulaw_framein,
.sample = slin8_sample,
.buf_size = BUFFER_SAMPLES,
@ -112,8 +106,6 @@ static struct ast_translator lintoulaw = {
static struct ast_translator lintotestlaw = {
.name = "lintotestlaw",
.srcfmt = AST_FORMAT_SLINEAR,
.dstfmt = AST_FORMAT_TESTLAW,
.framein = lintoulaw_framein,
.sample = slin8_sample,
.buf_size = BUFFER_SAMPLES,
@ -141,6 +133,18 @@ static int load_module(void)
{
int res;
ast_format_set(&lintoulaw.src_format, AST_FORMAT_SLINEAR, 0);
ast_format_set(&lintoulaw.dst_format, AST_FORMAT_ULAW, 0);
ast_format_set(&lintotestlaw.src_format, AST_FORMAT_SLINEAR, 0);
ast_format_set(&lintotestlaw.dst_format, AST_FORMAT_TESTLAW, 0);
ast_format_set(&ulawtolin.src_format, AST_FORMAT_ULAW, 0);
ast_format_set(&ulawtolin.dst_format, AST_FORMAT_SLINEAR, 0);
ast_format_set(&testlawtolin.src_format, AST_FORMAT_TESTLAW, 0);
ast_format_set(&testlawtolin.dst_format, AST_FORMAT_SLINEAR, 0);
res = ast_register_translator(&ulawtolin);
if (!res) {
res = ast_register_translator(&lintoulaw);

View File

@ -19,7 +19,6 @@ static struct ast_frame *adpcm_sample(void)
{
static struct ast_frame f = {
.frametype = AST_FRAME_VOICE,
.subclass.codec = AST_FORMAT_ADPCM,
.datalen = sizeof(ex_adpcm),
.samples = ARRAY_LEN(ex_adpcm) * 2,
.mallocd = 0,
@ -27,6 +26,7 @@ static struct ast_frame *adpcm_sample(void)
.src = __PRETTY_FUNCTION__,
.data.ptr = ex_adpcm,
};
ast_format_set(&f.subclass.format, AST_FORMAT_ADPCM, 0);
return &f;
}

View File

@ -24,7 +24,6 @@ static struct ast_frame *alaw_sample(void)
{
static struct ast_frame f = {
.frametype = AST_FRAME_VOICE,
.subclass.codec = AST_FORMAT_ALAW,
.datalen = sizeof(ex_alaw),
.samples = ARRAY_LEN(ex_alaw),
.mallocd = 0,
@ -32,6 +31,6 @@ static struct ast_frame *alaw_sample(void)
.src = __PRETTY_FUNCTION__,
.data.ptr = ex_alaw,
};
ast_format_set(&f.subclass.format, AST_FORMAT_ALAW, 0);
return &f;
}

View File

@ -34,7 +34,6 @@ static struct ast_frame *g722_sample(void)
{
static struct ast_frame f = {
.frametype = AST_FRAME_VOICE,
.subclass.codec = AST_FORMAT_G722,
.datalen = sizeof(ex_g722),
.samples = ARRAY_LEN(ex_g722),
.mallocd = 0,
@ -43,5 +42,7 @@ static struct ast_frame *g722_sample(void)
.data.ptr = ex_g722,
};
ast_format_set(&f.subclass.format, AST_FORMAT_G722, 0);
return &f;
}

View File

@ -19,7 +19,6 @@ static struct ast_frame *g726_sample(void)
{
static struct ast_frame f = {
.frametype = AST_FRAME_VOICE,
.subclass.codec = AST_FORMAT_G726,
.datalen = sizeof(ex_g726),
.samples = ARRAY_LEN(ex_g726) * 2, /* 2 samples per byte */
.mallocd = 0,
@ -28,5 +27,7 @@ static struct ast_frame *g726_sample(void)
.data.ptr = ex_g726,
};
ast_format_set(&f.subclass.format, AST_FORMAT_G726, 0);
return &f;
}

View File

@ -18,7 +18,6 @@ static struct ast_frame *gsm_sample(void)
{
static struct ast_frame f = {
.frametype = AST_FRAME_VOICE,
.subclass.codec = AST_FORMAT_GSM,
.datalen = sizeof(ex_gsm),
/* All frames are 20 ms long */
.samples = GSM_SAMPLES,
@ -28,5 +27,6 @@ static struct ast_frame *gsm_sample(void)
.data.ptr = ex_gsm,
};
ast_format_set(&f.subclass.format, AST_FORMAT_GSM, 0);
return &f;
}

View File

@ -15,7 +15,6 @@ static struct ast_frame *lpc10_sample(void)
{
static struct ast_frame f = {
.frametype = AST_FRAME_VOICE,
.subclass.codec = AST_FORMAT_LPC10,
.datalen = sizeof(ex_lpc10),
/* All frames are 22 ms long (maybe a little more -- why did he choose
LPC10_SAMPLES_PER_FRAME sample frames anyway?? */
@ -26,5 +25,7 @@ static struct ast_frame *lpc10_sample(void)
.data.ptr = ex_lpc10,
};
ast_format_set(&f.subclass.format, AST_FORMAT_LPC10, 0);
return &f;
}

View File

@ -18,7 +18,6 @@ static struct ast_frame *speex_sample(void)
{
static struct ast_frame f = {
.frametype = AST_FRAME_VOICE,
.subclass.codec = AST_FORMAT_SPEEX,
.datalen = sizeof(ex_speex),
/* All frames are 20 ms long */
.samples = SPEEX_SAMPLES,
@ -28,6 +27,8 @@ static struct ast_frame *speex_sample(void)
.data.ptr = ex_speex,
};
ast_format_set(&f.subclass.format, AST_FORMAT_SPEEX, 0);
return &f;
}
@ -49,7 +50,6 @@ static struct ast_frame *speex16_sample(void)
{
static struct ast_frame f = {
.frametype = AST_FRAME_VOICE,
.subclass.codec = AST_FORMAT_SPEEX16,
.datalen = sizeof(ex_speex16),
/* All frames are 20 ms long */
.samples = SPEEX_SAMPLES,
@ -58,6 +58,7 @@ static struct ast_frame *speex16_sample(void)
.src = __PRETTY_FUNCTION__,
.data.ptr = ex_speex16,
};
ast_format_set(&f.subclass.format, AST_FORMAT_SPEEX16, 0);
return &f;
}

View File

@ -24,7 +24,6 @@ static struct ast_frame *ulaw_sample(void)
{
static struct ast_frame f = {
.frametype = AST_FRAME_VOICE,
.subclass.codec = AST_FORMAT_ULAW,
.datalen = sizeof(ex_ulaw),
.samples = ARRAY_LEN(ex_ulaw),
.mallocd = 0,
@ -33,5 +32,6 @@ static struct ast_frame *ulaw_sample(void)
.data.ptr = ex_ulaw,
};
ast_format_set(&f.subclass.format, AST_FORMAT_ULAW, 0);
return &f;
}

View File

@ -41,7 +41,7 @@ static struct ast_frame *g719read(struct ast_filestream *s, int *whennext)
/* Send a frame from the file to the appropriate channel */
s->fr.frametype = AST_FRAME_VOICE;
s->fr.subclass.codec = AST_FORMAT_G719;
ast_format_set(&s->fr.subclass.format, AST_FORMAT_G719, 0);
s->fr.mallocd = 0;
AST_FRAME_SET_BUFFER(&s->fr, s->buf, AST_FRIENDLY_OFFSET, BUF_SIZE);
if ((res = fread(s->fr.data.ptr, 1, s->fr.datalen, s->f)) != s->fr.datalen) {
@ -61,8 +61,8 @@ static int g719write(struct ast_filestream *fs, struct ast_frame *f)
ast_log(LOG_WARNING, "Asked to write non-voice frame!\n");
return -1;
}
if (f->subclass.codec != AST_FORMAT_G719) {
ast_log(LOG_WARNING, "Asked to write non-G.719 frame (%s)!\n", ast_getformatname(f->subclass.codec));
if (f->subclass.format.id != AST_FORMAT_G719) {
ast_log(LOG_WARNING, "Asked to write non-G.719 frame (%s)!\n", ast_getformatname(&f->subclass.format));
return -1;
}
if ((res = fwrite(f->data.ptr, 1, f->datalen, fs->f)) != f->datalen) {
@ -110,10 +110,9 @@ static off_t g719tell(struct ast_filestream *fs)
return BYTES_TO_SAMPLES(ftello(fs->f));
}
static const struct ast_format g719_f = {
static struct ast_format_def g719_f = {
.name = "g719",
.exts = "g719",
.format = AST_FORMAT_G719,
.write = g719write,
.seek = g719seek,
.trunc = g719trunc,
@ -124,15 +123,15 @@ static const struct ast_format g719_f = {
static int load_module(void)
{
if (ast_format_register(&g719_f))
ast_format_set(&g719_f.format, AST_FORMAT_G719, 0);
if (ast_format_def_register(&g719_f))
return AST_MODULE_LOAD_DECLINE;
return AST_MODULE_LOAD_SUCCESS;
}
static int unload_module(void)
{
return ast_format_unregister(g719_f.name);
return ast_format_def_unregister(g719_f.name);
}
AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "ITU G.719",

View File

@ -61,7 +61,7 @@ static struct ast_frame *g723_read(struct ast_filestream *s, int *whennext)
}
/* Read the data into the buffer */
s->fr.frametype = AST_FRAME_VOICE;
s->fr.subclass.codec = AST_FORMAT_G723_1;
ast_format_set(&s->fr.subclass.format, AST_FORMAT_G723_1, 0);
s->fr.mallocd = 0;
AST_FRAME_SET_BUFFER(&s->fr, s->buf, AST_FRIENDLY_OFFSET, size);
if ((res = fread(s->fr.data.ptr, 1, s->fr.datalen, s->f)) != size) {
@ -82,7 +82,7 @@ static int g723_write(struct ast_filestream *s, struct ast_frame *f)
ast_log(LOG_WARNING, "Asked to write non-voice frame!\n");
return -1;
}
if (f->subclass.codec != AST_FORMAT_G723_1) {
if (f->subclass.format.id != AST_FORMAT_G723_1) {
ast_log(LOG_WARNING, "Asked to write non-g723 frame!\n");
return -1;
}
@ -125,10 +125,9 @@ static off_t g723_tell(struct ast_filestream *fs)
return -1;
}
static const struct ast_format g723_1_f = {
static struct ast_format_def g723_1_f = {
.name = "g723sf",
.exts = "g723|g723sf",
.format = AST_FORMAT_G723_1,
.write = g723_write,
.seek = g723_seek,
.trunc = g723_trunc,
@ -139,14 +138,16 @@ static const struct ast_format g723_1_f = {
static int load_module(void)
{
if (ast_format_register(&g723_1_f))
ast_format_set(&g723_1_f.format, AST_FORMAT_G723_1, 0);
if (ast_format_def_register(&g723_1_f))
return AST_MODULE_LOAD_FAILURE;
return AST_MODULE_LOAD_SUCCESS;
}
static int unload_module(void)
{
return ast_format_unregister(g723_1_f.name);
return ast_format_def_unregister(g723_1_f.name);
}
AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "G.723.1 Simple Timestamp File Format",

View File

@ -119,7 +119,7 @@ static struct ast_frame *g726_read(struct ast_filestream *s, int *whennext)
/* Send a frame from the file to the appropriate channel */
s->fr.frametype = AST_FRAME_VOICE;
s->fr.subclass.codec = AST_FORMAT_G726;
ast_format_set(&s->fr.subclass.format, AST_FORMAT_G726, 0);
s->fr.mallocd = 0;
AST_FRAME_SET_BUFFER(&s->fr, s->buf, AST_FRIENDLY_OFFSET, frame_size[fs->rate]);
s->fr.samples = 8 * FRAME_TIME;
@ -141,9 +141,9 @@ static int g726_write(struct ast_filestream *s, struct ast_frame *f)
ast_log(LOG_WARNING, "Asked to write non-voice frame!\n");
return -1;
}
if (f->subclass.codec != AST_FORMAT_G726) {
if (f->subclass.format.id != AST_FORMAT_G726) {
ast_log(LOG_WARNING, "Asked to write non-G726 frame (%s)!\n",
ast_getformatname(f->subclass.codec));
ast_getformatname(&f->subclass.format));
return -1;
}
if (f->datalen % frame_size[fs->rate]) {
@ -174,11 +174,10 @@ static off_t g726_tell(struct ast_filestream *fs)
return -1;
}
static const struct ast_format f[] = {
static struct ast_format_def f[] = {
{
.name = "g726-40",
.exts = "g726-40",
.format = AST_FORMAT_G726,
.open = g726_40_open,
.rewrite = g726_40_rewrite,
.write = g726_write,
@ -192,7 +191,6 @@ static const struct ast_format f[] = {
{
.name = "g726-32",
.exts = "g726-32",
.format = AST_FORMAT_G726,
.open = g726_32_open,
.rewrite = g726_32_rewrite,
.write = g726_write,
@ -206,7 +204,6 @@ static const struct ast_format f[] = {
{
.name = "g726-24",
.exts = "g726-24",
.format = AST_FORMAT_G726,
.open = g726_24_open,
.rewrite = g726_24_rewrite,
.write = g726_write,
@ -220,7 +217,6 @@ static const struct ast_format f[] = {
{
.name = "g726-16",
.exts = "g726-16",
.format = AST_FORMAT_G726,
.open = g726_16_open,
.rewrite = g726_16_rewrite,
.write = g726_write,
@ -231,15 +227,16 @@ static const struct ast_format f[] = {
.buf_size = BUF_SIZE + AST_FRIENDLY_OFFSET,
.desc_size = sizeof(struct g726_desc),
},
{ .format = 0 } /* terminator */
{ .desc_size = 0 } /* terminator */
};
static int load_module(void)
{
int i;
for (i = 0; f[i].format ; i++) {
if (ast_format_register(&f[i])) { /* errors are fatal */
for (i = 0; f[i].desc_size ; i++) {
ast_format_set(&f[i].format, AST_FORMAT_G726, 0);
if (ast_format_def_register(&f[i])) { /* errors are fatal */
ast_log(LOG_WARNING, "Failed to register format %s.\n", f[i].name);
return AST_MODULE_LOAD_FAILURE;
}
@ -251,8 +248,8 @@ static int unload_module(void)
{
int i;
for (i = 0; f[i].format ; i++) {
if (ast_format_unregister(f[i].name))
for (i = 0; f[i].desc_size ; i++) {
if (ast_format_def_unregister(f[i].name))
ast_log(LOG_WARNING, "Failed to unregister format %s.\n", f[i].name);
}
return(0);

View File

@ -46,7 +46,7 @@ static struct ast_frame *g729_read(struct ast_filestream *s, int *whennext)
int res;
/* Send a frame from the file to the appropriate channel */
s->fr.frametype = AST_FRAME_VOICE;
s->fr.subclass.codec = AST_FORMAT_G729A;
ast_format_set(&s->fr.subclass.format, AST_FORMAT_G729A, 0);
s->fr.mallocd = 0;
s->fr.samples = G729A_SAMPLES;
AST_FRAME_SET_BUFFER(&s->fr, s->buf, AST_FRIENDLY_OFFSET, BUF_SIZE);
@ -66,8 +66,8 @@ static int g729_write(struct ast_filestream *fs, struct ast_frame *f)
ast_log(LOG_WARNING, "Asked to write non-voice frame!\n");
return -1;
}
if (f->subclass.codec != AST_FORMAT_G729A) {
ast_log(LOG_WARNING, "Asked to write non-G729 frame (%s)!\n", ast_getformatname(f->subclass.codec));
if (f->subclass.format.id != AST_FORMAT_G729A) {
ast_log(LOG_WARNING, "Asked to write non-G729 frame (%s)!\n", ast_getformatname(&f->subclass.format));
return -1;
}
if (f->datalen % 10) {
@ -121,10 +121,9 @@ static off_t g729_tell(struct ast_filestream *fs)
return (offset/BUF_SIZE)*G729A_SAMPLES;
}
static const struct ast_format g729_f = {
static struct ast_format_def g729_f = {
.name = "g729",
.exts = "g729",
.format = AST_FORMAT_G729A,
.write = g729_write,
.seek = g729_seek,
.trunc = g729_trunc,
@ -135,14 +134,15 @@ static const struct ast_format g729_f = {
static int load_module(void)
{
if (ast_format_register(&g729_f))
ast_format_set(&g729_f.format, AST_FORMAT_G729A, 0);
if (ast_format_def_register(&g729_f))
return AST_MODULE_LOAD_FAILURE;
return AST_MODULE_LOAD_SUCCESS;
}
static int unload_module(void)
{
return ast_format_unregister(g729_f.name);
return ast_format_def_unregister(g729_f.name);
}
AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "Raw G.729 data",

View File

@ -53,7 +53,7 @@ static struct ast_frame *gsm_read(struct ast_filestream *s, int *whennext)
int res;
s->fr.frametype = AST_FRAME_VOICE;
s->fr.subclass.codec = AST_FORMAT_GSM;
ast_format_set(&s->fr.subclass.format, AST_FORMAT_GSM, 0);
AST_FRAME_SET_BUFFER(&(s->fr), s->buf, AST_FRIENDLY_OFFSET, GSM_FRAME_SIZE)
s->fr.mallocd = 0;
if ((res = fread(s->fr.data.ptr, 1, GSM_FRAME_SIZE, s->f)) != GSM_FRAME_SIZE) {
@ -74,8 +74,8 @@ static int gsm_write(struct ast_filestream *fs, struct ast_frame *f)
ast_log(LOG_WARNING, "Asked to write non-voice frame!\n");
return -1;
}
if (f->subclass.codec != AST_FORMAT_GSM) {
ast_log(LOG_WARNING, "Asked to write non-GSM frame (%s)!\n", ast_getformatname(f->subclass.codec));
if (f->subclass.format.id != AST_FORMAT_GSM) {
ast_log(LOG_WARNING, "Asked to write non-GSM frame (%s)!\n", ast_getformatname(&f->subclass.format));
return -1;
}
if (!(f->datalen % 65)) {
@ -145,10 +145,9 @@ static off_t gsm_tell(struct ast_filestream *fs)
return (offset/GSM_FRAME_SIZE)*GSM_SAMPLES;
}
static const struct ast_format gsm_f = {
static struct ast_format_def gsm_f = {
.name = "gsm",
.exts = "gsm",
.format = AST_FORMAT_GSM,
.write = gsm_write,
.seek = gsm_seek,
.trunc = gsm_trunc,
@ -159,14 +158,15 @@ static const struct ast_format gsm_f = {
static int load_module(void)
{
if (ast_format_register(&gsm_f))
ast_format_set(&gsm_f.format, AST_FORMAT_GSM, 0);
if (ast_format_def_register(&gsm_f))
return AST_MODULE_LOAD_FAILURE;
return AST_MODULE_LOAD_SUCCESS;
}
static int unload_module(void)
{
return ast_format_unregister(gsm_f.name);
return ast_format_def_unregister(gsm_f.name);
}
AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "Raw GSM data",

View File

@ -64,7 +64,7 @@ static int h263_open(struct ast_filestream *s)
static struct ast_frame *h263_read(struct ast_filestream *s, int *whennext)
{
int res;
format_t mark;
uint32_t mark;
unsigned short len;
unsigned int ts;
struct h263_desc *fs = (struct h263_desc *)s->_private;
@ -80,7 +80,7 @@ static struct ast_frame *h263_read(struct ast_filestream *s, int *whennext)
return NULL;
}
s->fr.frametype = AST_FRAME_VIDEO;
s->fr.subclass.codec = AST_FORMAT_H263;
ast_format_set(&s->fr.subclass.format, AST_FORMAT_H263, 0);
s->fr.mallocd = 0;
AST_FRAME_SET_BUFFER(&s->fr, s->buf, AST_FRIENDLY_OFFSET, len);
if ((res = fread(s->fr.data.ptr, 1, s->fr.datalen, s->f)) != s->fr.datalen) {
@ -90,7 +90,9 @@ static struct ast_frame *h263_read(struct ast_filestream *s, int *whennext)
}
s->fr.samples = fs->lastts; /* XXX what ? */
s->fr.datalen = len;
s->fr.subclass.codec |= mark;
if (mark) {
ast_format_set_video_mark(&s->fr.subclass.format);
}
s->fr.delivery.tv_sec = 0;
s->fr.delivery.tv_usec = 0;
if ((res = fread(&ts, 1, sizeof(ts), s->f)) == sizeof(ts)) {
@ -106,18 +108,14 @@ static int h263_write(struct ast_filestream *fs, struct ast_frame *f)
int res;
unsigned int ts;
unsigned short len;
format_t subclass;
format_t mark=0;
uint32_t mark = 0;
if (f->frametype != AST_FRAME_VIDEO) {
ast_log(LOG_WARNING, "Asked to write non-video frame!\n");
return -1;
}
subclass = f->subclass.codec;
if (subclass & 0x1)
mark=0x8000;
subclass &= ~0x1;
if (subclass != AST_FORMAT_H263) {
ast_log(LOG_WARNING, "Asked to write non-h263 frame (%s)!\n", ast_getformatname(f->subclass.codec));
mark = ast_format_get_video_mark(&f->subclass.format) ? 0x8000 : 0;
if (f->subclass.format.id != AST_FORMAT_H263) {
ast_log(LOG_WARNING, "Asked to write non-h263 frame (%s)!\n", ast_getformatname(&f->subclass.format));
return -1;
}
ts = htonl(f->samples);
@ -157,10 +155,9 @@ static off_t h263_tell(struct ast_filestream *fs)
return offset; /* XXX totally bogus, needs fixing */
}
static const struct ast_format h263_f = {
static struct ast_format_def h263_f = {
.name = "h263",
.exts = "h263",
.format = AST_FORMAT_H263,
.open = h263_open,
.write = h263_write,
.seek = h263_seek,
@ -173,14 +170,15 @@ static const struct ast_format h263_f = {
static int load_module(void)
{
if (ast_format_register(&h263_f))
ast_format_set(&h263_f.format, AST_FORMAT_H263, 0);
if (ast_format_def_register(&h263_f))
return AST_MODULE_LOAD_FAILURE;
return AST_MODULE_LOAD_SUCCESS;
}
static int unload_module(void)
{
return ast_format_unregister(h263_f.name);
return ast_format_def_unregister(h263_f.name);
}
AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "Raw H.263 data",

View File

@ -56,7 +56,7 @@ static int h264_open(struct ast_filestream *s)
static struct ast_frame *h264_read(struct ast_filestream *s, int *whennext)
{
int res;
int mark=0;
int mark = 0;
unsigned short len;
unsigned int ts;
struct h264_desc *fs = (struct h264_desc *)s->_private;
@ -72,7 +72,7 @@ static struct ast_frame *h264_read(struct ast_filestream *s, int *whennext)
len = BUF_SIZE; /* XXX truncate */
}
s->fr.frametype = AST_FRAME_VIDEO;
s->fr.subclass.codec = AST_FORMAT_H264;
ast_format_set(&s->fr.subclass.format, AST_FORMAT_H264, 0);
s->fr.mallocd = 0;
AST_FRAME_SET_BUFFER(&s->fr, s->buf, AST_FRIENDLY_OFFSET, len);
if ((res = fread(s->fr.data.ptr, 1, s->fr.datalen, s->f)) != s->fr.datalen) {
@ -82,7 +82,9 @@ static struct ast_frame *h264_read(struct ast_filestream *s, int *whennext)
}
s->fr.samples = fs->lastts;
s->fr.datalen = len;
s->fr.subclass.codec |= mark;
if (mark) {
ast_format_set_video_mark(&s->fr.subclass.format);
}
s->fr.delivery.tv_sec = 0;
s->fr.delivery.tv_usec = 0;
if ((res = fread(&ts, 1, sizeof(ts), s->f)) == sizeof(ts)) {
@ -104,9 +106,9 @@ static int h264_write(struct ast_filestream *s, struct ast_frame *f)
ast_log(LOG_WARNING, "Asked to write non-video frame!\n");
return -1;
}
mark = (f->subclass.codec & 0x1) ? 0x8000 : 0;
if ((f->subclass.codec & ~0x1) != AST_FORMAT_H264) {
ast_log(LOG_WARNING, "Asked to write non-h264 frame (%s)!\n", ast_getformatname(f->subclass.codec));
mark = ast_format_get_video_mark(&f->subclass.format) ? 0x8000 : 0;
if (f->subclass.format.id != AST_FORMAT_H264) {
ast_log(LOG_WARNING, "Asked to write non-h264 frame (%s)!\n", ast_getformatname(&f->subclass.format));
return -1;
}
ts = htonl(f->samples);
@ -146,10 +148,9 @@ static off_t h264_tell(struct ast_filestream *fs)
return offset; /* XXX totally bogus, needs fixing */
}
static const struct ast_format h264_f = {
static struct ast_format_def h264_f = {
.name = "h264",
.exts = "h264",
.format = AST_FORMAT_H264,
.open = h264_open,
.write = h264_write,
.seek = h264_seek,
@ -162,14 +163,15 @@ static const struct ast_format h264_f = {
static int load_module(void)
{
if (ast_format_register(&h264_f))
ast_format_set(&h264_f.format, AST_FORMAT_H264, 0);
if (ast_format_def_register(&h264_f))
return AST_MODULE_LOAD_FAILURE;
return AST_MODULE_LOAD_SUCCESS;
}
static int unload_module(void)
{
return ast_format_unregister(h264_f.name);
return ast_format_def_unregister(h264_f.name);
}
AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "Raw H.264 data",

View File

@ -45,7 +45,7 @@ static struct ast_frame *ilbc_read(struct ast_filestream *s, int *whennext)
int res;
/* Send a frame from the file to the appropriate channel */
s->fr.frametype = AST_FRAME_VOICE;
s->fr.subclass.codec = AST_FORMAT_ILBC;
ast_format_set(&s->fr.subclass.format, AST_FORMAT_ILBC, 0);
s->fr.mallocd = 0;
AST_FRAME_SET_BUFFER(&s->fr, s->buf, AST_FRIENDLY_OFFSET, ILBC_BUF_SIZE);
if ((res = fread(s->fr.data.ptr, 1, s->fr.datalen, s->f)) != s->fr.datalen) {
@ -64,8 +64,8 @@ static int ilbc_write(struct ast_filestream *fs, struct ast_frame *f)
ast_log(LOG_WARNING, "Asked to write non-voice frame!\n");
return -1;
}
if (f->subclass.codec != AST_FORMAT_ILBC) {
ast_log(LOG_WARNING, "Asked to write non-iLBC frame (%s)!\n", ast_getformatname(f->subclass.codec));
if (f->subclass.format.id != AST_FORMAT_ILBC) {
ast_log(LOG_WARNING, "Asked to write non-iLBC frame (%s)!\n", ast_getformatname(&f->subclass.format));
return -1;
}
if (f->datalen % 50) {
@ -119,10 +119,9 @@ static off_t ilbc_tell(struct ast_filestream *fs)
return (offset/ILBC_BUF_SIZE)*ILBC_SAMPLES;
}
static const struct ast_format ilbc_f = {
static struct ast_format_def ilbc_f = {
.name = "iLBC",
.exts = "ilbc",
.format = AST_FORMAT_ILBC,
.write = ilbc_write,
.seek = ilbc_seek,
.trunc = ilbc_trunc,
@ -133,14 +132,15 @@ static const struct ast_format ilbc_f = {
static int load_module(void)
{
if (ast_format_register(&ilbc_f))
ast_format_set(&ilbc_f.format, AST_FORMAT_ILBC, 0);
if (ast_format_def_register(&ilbc_f))
return AST_MODULE_LOAD_FAILURE;
return AST_MODULE_LOAD_SUCCESS;
}
static int unload_module(void)
{
return ast_format_unregister(ilbc_f.name);
return ast_format_def_unregister(ilbc_f.name);
}
AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "Raw iLBC data",

View File

@ -48,7 +48,7 @@ static struct ast_frame *jpeg_read_image(int fd, int len)
}
memset(&fr, 0, sizeof(fr));
fr.frametype = AST_FRAME_IMAGE;
fr.subclass.codec = AST_FORMAT_JPEG;
ast_format_set(&fr.subclass.format, AST_FORMAT_JPEG, 0);
fr.data.ptr = buf;
fr.src = "JPEG Read";
fr.datalen = len;
@ -74,7 +74,7 @@ static int jpeg_write_image(int fd, struct ast_frame *fr)
ast_log(LOG_WARNING, "Not an image\n");
return -1;
}
if (fr->subclass.codec != AST_FORMAT_JPEG) {
if (fr->subclass.format.id != AST_FORMAT_JPEG) {
ast_log(LOG_WARNING, "Not a jpeg image\n");
return -1;
}
@ -92,7 +92,6 @@ static struct ast_imager jpeg_format = {
.name = "jpg",
.desc = "JPEG (Joint Picture Experts Group)",
.exts = "jpg|jpeg",
.format = AST_FORMAT_JPEG,
.read_image = jpeg_read_image,
.identify = jpeg_identify,
.write_image = jpeg_write_image,
@ -100,6 +99,7 @@ static struct ast_imager jpeg_format = {
static int load_module(void)
{
ast_format_set(&jpeg_format.format, AST_FORMAT_JPEG, 0);
if (ast_image_register(&jpeg_format))
return AST_MODULE_LOAD_FAILURE;
return AST_MODULE_LOAD_SUCCESS;

View File

@ -291,9 +291,9 @@ static int ogg_vorbis_write(struct ast_filestream *fs, struct ast_frame *f)
ast_log(LOG_WARNING, "Asked to write non-voice frame!\n");
return -1;
}
if (f->subclass.codec != AST_FORMAT_SLINEAR) {
if (f->subclass.format.id != AST_FORMAT_SLINEAR) {
ast_log(LOG_WARNING, "Asked to write non-SLINEAR frame (%s)!\n",
ast_getformatname(f->subclass.codec));
ast_getformatname(&f->subclass.format));
return -1;
}
if (!f->datalen)
@ -438,7 +438,7 @@ static struct ast_frame *ogg_vorbis_read(struct ast_filestream *fs,
short *buf; /* SLIN data buffer */
fs->fr.frametype = AST_FRAME_VOICE;
fs->fr.subclass.codec = AST_FORMAT_SLINEAR;
ast_format_set(&fs->fr.subclass.format, AST_FORMAT_SLINEAR, 0);
fs->fr.mallocd = 0;
AST_FRAME_SET_BUFFER(&fs->fr, fs->buf, AST_FRIENDLY_OFFSET, BUF_SIZE);
buf = (short *)(fs->fr.data.ptr); /* SLIN data buffer */
@ -528,10 +528,9 @@ static off_t ogg_vorbis_tell(struct ast_filestream *s)
return -1;
}
static const struct ast_format vorbis_f = {
static struct ast_format_def vorbis_f = {
.name = "ogg_vorbis",
.exts = "ogg",
.format = AST_FORMAT_SLINEAR,
.open = ogg_vorbis_open,
.rewrite = ogg_vorbis_rewrite,
.write = ogg_vorbis_write,
@ -546,14 +545,15 @@ static const struct ast_format vorbis_f = {
static int load_module(void)
{
if (ast_format_register(&vorbis_f))
ast_format_set(&vorbis_f.format, AST_FORMAT_SLINEAR, 0);
if (ast_format_def_register(&vorbis_f))
return AST_MODULE_LOAD_FAILURE;
return AST_MODULE_LOAD_SUCCESS;
}
static int unload_module(void)
{
return ast_format_unregister(vorbis_f.name);
return ast_format_def_unregister(vorbis_f.name);
}
AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "OGG/Vorbis audio",

View File

@ -80,7 +80,7 @@ static struct ast_frame *pcm_read(struct ast_filestream *s, int *whennext)
/* Send a frame from the file to the appropriate channel */
s->fr.frametype = AST_FRAME_VOICE;
s->fr.subclass.codec = s->fmt->format;
ast_format_copy(&s->fr.subclass.format, &s->fmt->format);
s->fr.mallocd = 0;
AST_FRAME_SET_BUFFER(&s->fr, s->buf, AST_FRIENDLY_OFFSET, BUF_SIZE);
if ((res = fread(s->fr.data.ptr, 1, s->fr.datalen, s->f)) < 1) {
@ -89,7 +89,7 @@ static struct ast_frame *pcm_read(struct ast_filestream *s, int *whennext)
return NULL;
}
s->fr.datalen = res;
if (s->fmt->format == AST_FORMAT_G722)
if (s->fmt->format.id == AST_FORMAT_G722)
*whennext = s->fr.samples = res * 2;
else
*whennext = s->fr.samples = res;
@ -126,7 +126,7 @@ static int pcm_seek(struct ast_filestream *fs, off_t sample_offset, int whence)
}
if (whence == SEEK_FORCECUR && offset > max) { /* extend the file */
size_t left = offset - max;
const char *src = (fs->fmt->format == AST_FORMAT_ALAW) ? alaw_silence : ulaw_silence;
const char *src = (fs->fmt->format.id == AST_FORMAT_ALAW) ? alaw_silence : ulaw_silence;
while (left) {
size_t written = fwrite(src, 1, (left > BUF_SIZE) ? BUF_SIZE : left, fs->f);
@ -163,8 +163,8 @@ static int pcm_write(struct ast_filestream *fs, struct ast_frame *f)
ast_log(LOG_WARNING, "Asked to write non-voice frame!\n");
return -1;
}
if (f->subclass.codec != fs->fmt->format) {
ast_log(LOG_WARNING, "Asked to write incompatible format frame (%s)!\n", ast_getformatname(f->subclass.codec));
if (ast_format_cmp(&f->subclass.format, &fs->fmt->format) == AST_FORMAT_CMP_NOT_EQUAL) {
ast_log(LOG_WARNING, "Asked to write incompatible format frame (%s)!\n", ast_getformatname(&f->subclass.format));
return -1;
}
@ -373,7 +373,7 @@ static int au_seek(struct ast_filestream *fs, off_t sample_offset, int whence)
off_t min, max, cur;
long offset = 0, bytes;
if (fs->fmt->format == AST_FORMAT_G722)
if (fs->fmt->format.id == AST_FORMAT_G722)
bytes = sample_offset / 2;
else
bytes = sample_offset;
@ -413,10 +413,9 @@ static off_t au_tell(struct ast_filestream *fs)
return offset - AU_HEADER_SIZE;
}
static const struct ast_format alaw_f = {
static struct ast_format_def alaw_f = {
.name = "alaw",
.exts = "alaw|al|alw",
.format = AST_FORMAT_ALAW,
.write = pcm_write,
.seek = pcm_seek,
.trunc = pcm_trunc,
@ -430,10 +429,9 @@ static const struct ast_format alaw_f = {
#endif
};
static const struct ast_format pcm_f = {
static struct ast_format_def pcm_f = {
.name = "pcm",
.exts = "pcm|ulaw|ul|mu|ulw",
.format = AST_FORMAT_ULAW,
.write = pcm_write,
.seek = pcm_seek,
.trunc = pcm_trunc,
@ -442,10 +440,9 @@ static const struct ast_format pcm_f = {
.buf_size = BUF_SIZE + AST_FRIENDLY_OFFSET,
};
static const struct ast_format g722_f = {
static struct ast_format_def g722_f = {
.name = "g722",
.exts = "g722",
.format = AST_FORMAT_G722,
.write = pcm_write,
.seek = pcm_seek,
.trunc = pcm_trunc,
@ -454,10 +451,9 @@ static const struct ast_format g722_f = {
.buf_size = (BUF_SIZE * 2) + AST_FRIENDLY_OFFSET,
};
static const struct ast_format au_f = {
static struct ast_format_def au_f = {
.name = "au",
.exts = "au",
.format = AST_FORMAT_ULAW,
.open = au_open,
.rewrite = au_rewrite,
.write = pcm_write,
@ -478,20 +474,24 @@ static int load_module(void)
for (i = 0; i < ARRAY_LEN(alaw_silence); i++)
alaw_silence[i] = AST_LIN2A(0);
if ( ast_format_register(&pcm_f)
|| ast_format_register(&alaw_f)
|| ast_format_register(&au_f)
|| ast_format_register(&g722_f) )
ast_format_set(&pcm_f.format, AST_FORMAT_ULAW, 0);
ast_format_set(&alaw_f.format, AST_FORMAT_ALAW, 0);
ast_format_set(&au_f.format, AST_FORMAT_ULAW, 0);
ast_format_set(&g722_f.format, AST_FORMAT_G722, 0);
if ( ast_format_def_register(&pcm_f)
|| ast_format_def_register(&alaw_f)
|| ast_format_def_register(&au_f)
|| ast_format_def_register(&g722_f) )
return AST_MODULE_LOAD_FAILURE;
return AST_MODULE_LOAD_SUCCESS;
}
static int unload_module(void)
{
return ast_format_unregister(pcm_f.name)
|| ast_format_unregister(alaw_f.name)
|| ast_format_unregister(au_f.name)
|| ast_format_unregister(g722_f.name);
return ast_format_def_unregister(pcm_f.name)
|| ast_format_def_unregister(alaw_f.name)
|| ast_format_def_unregister(au_f.name)
|| ast_format_def_unregister(g722_f.name);
}
AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "Raw/Sun uLaw/ALaw 8KHz (PCM,PCMA,AU), G.722 16Khz",

View File

@ -41,7 +41,7 @@ static struct ast_frame *siren14read(struct ast_filestream *s, int *whennext)
/* Send a frame from the file to the appropriate channel */
s->fr.frametype = AST_FRAME_VOICE;
s->fr.subclass.codec = AST_FORMAT_SIREN14;
ast_format_set(&s->fr.subclass.format, AST_FORMAT_SIREN14, 0);
s->fr.mallocd = 0;
AST_FRAME_SET_BUFFER(&s->fr, s->buf, AST_FRIENDLY_OFFSET, BUF_SIZE);
if ((res = fread(s->fr.data.ptr, 1, s->fr.datalen, s->f)) != s->fr.datalen) {
@ -61,8 +61,8 @@ static int siren14write(struct ast_filestream *fs, struct ast_frame *f)
ast_log(LOG_WARNING, "Asked to write non-voice frame!\n");
return -1;
}
if (f->subclass.codec != AST_FORMAT_SIREN14) {
ast_log(LOG_WARNING, "Asked to write non-Siren14 frame (%s)!\n", ast_getformatname(f->subclass.codec));
if (f->subclass.format.id != AST_FORMAT_SIREN14) {
ast_log(LOG_WARNING, "Asked to write non-Siren14 frame (%s)!\n", ast_getformatname(&f->subclass.format));
return -1;
}
if ((res = fwrite(f->data.ptr, 1, f->datalen, fs->f)) != f->datalen) {
@ -110,10 +110,9 @@ static off_t siren14tell(struct ast_filestream *fs)
return BYTES_TO_SAMPLES(ftello(fs->f));
}
static const struct ast_format siren14_f = {
static struct ast_format_def siren14_f = {
.name = "siren14",
.exts = "siren14",
.format = AST_FORMAT_SIREN14,
.write = siren14write,
.seek = siren14seek,
.trunc = siren14trunc,
@ -124,7 +123,8 @@ static const struct ast_format siren14_f = {
static int load_module(void)
{
if (ast_format_register(&siren14_f))
ast_format_set(&siren14_f.format, AST_FORMAT_SIREN14, 0);
if (ast_format_def_register(&siren14_f))
return AST_MODULE_LOAD_DECLINE;
return AST_MODULE_LOAD_SUCCESS;
@ -132,7 +132,7 @@ static int load_module(void)
static int unload_module(void)
{
return ast_format_unregister(siren14_f.name);
return ast_format_def_unregister(siren14_f.name);
}
AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "ITU G.722.1 Annex C (Siren14, licensed from Polycom)",

View File

@ -41,7 +41,7 @@ static struct ast_frame *siren7read(struct ast_filestream *s, int *whennext)
/* Send a frame from the file to the appropriate channel */
s->fr.frametype = AST_FRAME_VOICE;
s->fr.subclass.codec = AST_FORMAT_SIREN7;
ast_format_set(&s->fr.subclass.format, AST_FORMAT_SIREN7, 0);
s->fr.mallocd = 0;
AST_FRAME_SET_BUFFER(&s->fr, s->buf, AST_FRIENDLY_OFFSET, BUF_SIZE);
if ((res = fread(s->fr.data.ptr, 1, s->fr.datalen, s->f)) != s->fr.datalen) {
@ -61,8 +61,8 @@ static int siren7write(struct ast_filestream *fs, struct ast_frame *f)
ast_log(LOG_WARNING, "Asked to write non-voice frame!\n");
return -1;
}
if (f->subclass.codec != AST_FORMAT_SIREN7) {
ast_log(LOG_WARNING, "Asked to write non-Siren7 frame (%s)!\n", ast_getformatname(f->subclass.codec));
if (f->subclass.format.id != AST_FORMAT_SIREN7) {
ast_log(LOG_WARNING, "Asked to write non-Siren7 frame (%s)!\n", ast_getformatname(&f->subclass.format));
return -1;
}
if ((res = fwrite(f->data.ptr, 1, f->datalen, fs->f)) != f->datalen) {
@ -110,10 +110,9 @@ static off_t siren7tell(struct ast_filestream *fs)
return BYTES_TO_SAMPLES(ftello(fs->f));
}
static const struct ast_format siren7_f = {
static struct ast_format_def siren7_f = {
.name = "siren7",
.exts = "siren7",
.format = AST_FORMAT_SIREN7,
.write = siren7write,
.seek = siren7seek,
.trunc = siren7trunc,
@ -124,7 +123,8 @@ static const struct ast_format siren7_f = {
static int load_module(void)
{
if (ast_format_register(&siren7_f))
ast_format_set(&siren7_f.format, AST_FORMAT_SIREN7, 0);
if (ast_format_def_register(&siren7_f))
return AST_MODULE_LOAD_DECLINE;
return AST_MODULE_LOAD_SUCCESS;
@ -132,7 +132,7 @@ static int load_module(void)
static int unload_module(void)
{
return ast_format_unregister(siren7_f.name);
return ast_format_def_unregister(siren7_f.name);
}
AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "ITU G.722.1 (Siren7, licensed from Polycom)",

View File

@ -39,7 +39,7 @@ static struct ast_frame *slinear_read(struct ast_filestream *s, int *whennext)
/* Send a frame from the file to the appropriate channel */
s->fr.frametype = AST_FRAME_VOICE;
s->fr.subclass.codec = AST_FORMAT_SLINEAR;
ast_format_set(&s->fr.subclass.format, AST_FORMAT_SLINEAR, 0);
s->fr.mallocd = 0;
AST_FRAME_SET_BUFFER(&s->fr, s->buf, AST_FRIENDLY_OFFSET, BUF_SIZE);
if ((res = fread(s->fr.data.ptr, 1, s->fr.datalen, s->f)) < 1) {
@ -59,8 +59,8 @@ static int slinear_write(struct ast_filestream *fs, struct ast_frame *f)
ast_log(LOG_WARNING, "Asked to write non-voice frame!\n");
return -1;
}
if (f->subclass.codec != AST_FORMAT_SLINEAR) {
ast_log(LOG_WARNING, "Asked to write non-slinear frame (%s)!\n", ast_getformatname(f->subclass.codec));
if (f->subclass.format.id != AST_FORMAT_SLINEAR) {
ast_log(LOG_WARNING, "Asked to write non-slinear frame (%s)!\n", ast_getformatname(&f->subclass.format));
return -1;
}
if ((res = fwrite(f->data.ptr, 1, f->datalen, fs->f)) != f->datalen) {
@ -103,10 +103,9 @@ static off_t slinear_tell(struct ast_filestream *fs)
return ftello(fs->f) / 2;
}
static const struct ast_format slin_f = {
static struct ast_format_def slin_f = {
.name = "sln",
.exts = "sln|raw",
.format = AST_FORMAT_SLINEAR,
.write = slinear_write,
.seek = slinear_seek,
.trunc = slinear_trunc,
@ -117,14 +116,15 @@ static const struct ast_format slin_f = {
static int load_module(void)
{
if (ast_format_register(&slin_f))
ast_format_set(&slin_f.format, AST_FORMAT_SLINEAR, 0);
if (ast_format_def_register(&slin_f))
return AST_MODULE_LOAD_FAILURE;
return AST_MODULE_LOAD_SUCCESS;
}
static int unload_module(void)
{
return ast_format_unregister(slin_f.name);
return ast_format_def_unregister(slin_f.name);
}
AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "Raw Signed Linear Audio support (SLN)",

Some files were not shown because too many files have changed in this diff Show More