merged from trunk

This commit is contained in:
MelwareDE 2012-10-24 11:50:54 +00:00
parent 2384c8d7cc
commit 1cbac5a811
12 changed files with 634 additions and 153 deletions

View File

@ -3,6 +3,7 @@ CHANGES
HEAD
------------------
- Asterisk 1.8 changes
- added dialplan variables ISDNPI1 and ISDNPI2
- Support for 'divastreaming' available (Diva 4PRI PCI, Diva 2PRI PCI,
Diva 4PRI HS PCIe, Diva 2PRI HS PCIe, Diva 1PRI HS PCIe,

View File

@ -111,6 +111,7 @@ endif
CFLAGS=-pipe -fPIC -Wall -Wmissing-prototypes -Wmissing-declarations $(DEBUG) $(INCLUDE) -D_REENTRANT -D_GNU_SOURCE
CFLAGS+=$(OPTIMIZE)
CFLAGS+=-Wno-unused-but-set-variable
CFLAGS+=-O2
CFLAGS+=$(shell if $(CC) -march=$(PROC) -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-march=$(PROC)"; fi)
CFLAGS+=$(shell if uname -m | grep -q "ppc\|arm\|s390"; then echo "-fsigned-char"; fi)

View File

@ -198,7 +198,7 @@ static char capi_subscriber_prefix[AST_MAX_EXTENSION];
static char default_language[MAX_LANGUAGE] = "";
cc_format_t capi_capability = AST_FORMAT_ALAW;
cc_format_t capi_capability = CC_FORMAT_ALAW;
static int null_plci_dtmf_support = 1;
@ -216,7 +216,7 @@ static char global_mohinterpret[MAX_MUSICCLASS] = "default";
#endif
/* local prototypes */
#define CC_B_INTERFACE_NOT_FREE(__x__) (((__x__)->used) || \
#define CC_B_INTERFACE_NOT_FREE(__x__) (((__x__)->used) || ((__x__)->reserved) || \
((__x__)->channeltype != CAPI_CHANNELTYPE_B) || \
(capi_controllers[(__x__)->controller]->nfreebchannels < capi_controllers[(__x__)->controller]->nfreebchannelsHardThr))
@ -1212,6 +1212,7 @@ static void interface_cleanup(struct capi_pvt *i)
i->peer = NULL;
i->owner = NULL;
i->used = NULL;
i->reserved = 0;
if (i->channeltype == CAPI_CHANNELTYPE_NULL) {
capi_interface_task(i, CAPI_INTERFACE_TASK_NULLIFREMOVE);
@ -1655,31 +1656,31 @@ static int pbx_capi_call(struct ast_channel *c, char *idest, int timeout)
cip = tcap2cip(i->transfercapability);
}
#if defined(AST_FORMAT_G722) || defined(AST_FORMAT_SIREN7) || defined(AST_FORMAT_SIREN14) || defined(AST_FORMAT_SLINEAR16)
#if defined(CC_FORMAT_G722) || defined(CC_FORMAT_SIREN7) || defined(CC_FORMAT_SIREN14) || defined(CC_FORMAT_SLINEAR16)
if (capi_tcap_is_digital(i->transfercapability) == 0 && i->bproto == CC_BPROTO_VOCODER) {
static unsigned char llc_s_template[] = { 0x04, 0x00, 0xc0, 0x90, 0xa5 };
static unsigned char hlc_s_template[] = { 0x02, 0x91, 0x81 };
switch(i->codec) {
#if defined(AST_FORMAT_G722)
case AST_FORMAT_G722:
#if defined(CC_FORMAT_G722)
case CC_FORMAT_G722:
llc_s = llc_s_template;
hlc_s = hlc_s_template;
break;
#endif
#if defined(AST_FORMAT_SIREN7)
case AST_FORMAT_SIREN7:
#if defined(CC_FORMAT_SIREN7)
case CC_FORMAT_SIREN7:
llc_s = llc_s_template;
hlc_s = hlc_s_template;
break;
#endif
#if defined(AST_FORMAT_SIREN14)
case AST_FORMAT_SIREN14:
#if defined(CC_FORMAT_SIREN14)
case CC_FORMAT_SIREN14:
llc_s = llc_s_template;
hlc_s = hlc_s_template;
break;
#endif
#if defined(AST_FORMAT_SLINEAR16)
case AST_FORMAT_SLINEAR16:
#if defined(CC_FORMAT_SLINEAR16)
case CC_FORMAT_SLINEAR16:
llc_s = llc_s_template;
hlc_s = hlc_s_template;
break;
@ -1771,55 +1772,55 @@ _cstruct diva_get_b1_conf (struct capi_pvt *i) {
if (i->bproto == CC_BPROTO_VOCODER) {
switch(i->codec) {
case AST_FORMAT_ALAW:
case CC_FORMAT_ALAW:
b1conf = (_cstruct)"\x06\x08\x04\x03\x00\xa0\x00";
break;
case AST_FORMAT_ULAW:
case CC_FORMAT_ULAW:
b1conf = (_cstruct)"\x06\x00\x04\x03\x00\xa0\x00";
break;
case AST_FORMAT_GSM:
case CC_FORMAT_GSM:
b1conf = (_cstruct)"\x06\x03\x04\x0f\x00\xa0\x00";
break;
case AST_FORMAT_G723_1:
case CC_FORMAT_G723_1:
b1conf = (_cstruct)"\x06\x04\x04\x01\x00\xa0\x00";
break;
case AST_FORMAT_G726:
case CC_FORMAT_G726:
b1conf = (_cstruct)"\x06\x02\x04\x0f\x00\xa0\x00";
break;
case AST_FORMAT_ILBC: /* 30 mSec 240 samples */
case CC_FORMAT_ILBC: /* 30 mSec 240 samples */
b1conf = (_cstruct)"\x06\x1b\x04\x03\x00\xf0\x00";
break;
case AST_FORMAT_G729A:
case CC_FORMAT_G729A:
b1conf = (_cstruct)"\x06\x12\x04\x0f\x00\xa0\x00";
break;
#ifdef AST_FORMAT_G722
case AST_FORMAT_G722:
#ifdef CC_FORMAT_G722
case CC_FORMAT_G722:
b1conf = (_cstruct)"\x06\x09\x04\x03\x00\xa0\x00";
break;
#endif
#ifdef AST_FORMAT_SIREN7
case AST_FORMAT_SIREN7:
#ifdef CC_FORMAT_SIREN7
case CC_FORMAT_SIREN7:
b1conf = (_cstruct)"\x06\x24\x04\x0f\x02\xa0\x00"; /* 32 kBit/s */
break;
#endif
#ifdef AST_FORMAT_SIREN14
case AST_FORMAT_SIREN14:
#ifdef CC_FORMAT_SIREN14
case CC_FORMAT_SIREN14:
b1conf = (_cstruct)"\x06\x24\x04\x0f\x07\xa0\x00"; /* 48 kBit/s */
break;
#endif
#if defined(AST_FORMAT_SLINEAR)
case AST_FORMAT_SLINEAR:
#if defined(CC_FORMAT_SLINEAR)
case CC_FORMAT_SLINEAR:
b1conf = (_cstruct)"\x06\x01\x04\x0f\x01\xa0\x00";
break;
#endif
#if defined(AST_FORMAT_SLINEAR16)
case AST_FORMAT_SLINEAR16:
#if defined(CC_FORMAT_SLINEAR16)
case CC_FORMAT_SLINEAR16:
b1conf = (_cstruct)"\x06\x01\x04\x0f\x05\xa0\x00";
break;
#endif
default:
cc_log(LOG_ERROR, "%s: format %s(%d) invalid.\n",
i->vname, ast_getformatname(i->codec), i->codec);
i->vname, cc_getformatname(i->codec), i->codec);
break;
}
}
@ -1885,27 +1886,27 @@ static int capi_send_answer(struct ast_channel *c, _cstruct b3conf)
capi_facility_add_datetime(facilityarray);
}
#if defined(AST_FORMAT_G722) || defined(AST_FORMAT_SIREN7) || defined(AST_FORMAT_SIREN14) || defined(AST_FORMAT_SLINEAR16)
#if defined(CC_FORMAT_G722) || defined(CC_FORMAT_SIREN7) || defined(CC_FORMAT_SIREN14) || defined(CC_FORMAT_SLINEAR16)
if (i->bproto == CC_BPROTO_VOCODER) {
static unsigned char llc_s_template[] = { 0x03, 0x91, 0x90, 0xa5 };
switch(i->codec) {
#if defined(AST_FORMAT_G722)
case AST_FORMAT_G722:
#if defined(CC_FORMAT_G722)
case CC_FORMAT_G722:
llc_s = llc_s_template;
break;
#endif
#if defined(AST_FORMAT_SIREN7)
case AST_FORMAT_SIREN7:
#if defined(CC_FORMAT_SIREN7)
case CC_FORMAT_SIREN7:
llc_s = llc_s_template;
break;
#endif
#if defined(AST_FORMAT_SIREN14)
case AST_FORMAT_SIREN14:
#if defined(CC_FORMAT_SIREN14)
case CC_FORMAT_SIREN14:
llc_s = llc_s_template;
break;
#endif
#if defined(AST_FORMAT_SLINEAR16)
case AST_FORMAT_SLINEAR16:
#if defined(CC_FORMAT_SLINEAR16)
case CC_FORMAT_SLINEAR16:
llc_s = llc_s_template;
break;
#endif
@ -2365,6 +2366,9 @@ static struct ast_channel *capi_new(struct capi_pvt *i, int state, const char *l
#else
tmp = ast_channel_alloc(0);
#endif
cc_mutex_lock(&iflock);
i->reserved = 0;
if (tmp == NULL) {
cc_log(LOG_ERROR, "Unable to allocate channel!\n");
@ -2388,7 +2392,12 @@ static struct ast_channel *capi_new(struct capi_pvt *i, int state, const char *l
ast_channel_release(tmp);
return NULL;
}
#ifdef CC_AST_HAS_VERSION_1_6
ast_channel_set_fd(tmp, 0, i->readerfd);
#else
tmp->fds[0] = i->readerfd;
#endif
if (i->smoother != NULL) {
ast_smoother_reset(i->smoother, CAPI_MAX_B3_BLOCK_SIZE);
@ -2435,35 +2444,41 @@ static struct ast_channel *capi_new(struct capi_pvt *i, int state, const char *l
tmp->callgroup = i->callgroup;
tmp->pickupgroup = i->pickupgroup;
tmp->nativeformats = capi_capability;
#if 0
i->bproto = CC_BPROTO_TRANSPARENT;
tmp->nativeformats = capi_capability;
if ((i->rtpcodec = (capi_controllers[i->controller]->rtpcodec & i->capability))) {
#if 0 /* VOCODER */
if (capi_alloc_rtp(i)) {
/* error on rtp alloc */
i->rtpcodec = 0;
} else {
/* start with rtp */
tmp->nativeformats = i->rtpcodec;
i->bproto = CC_BPROTO_RTP;
}
#else
tmp->nativeformats = i->rtpcodec;
i->bproto = CC_BPROTO_VOCODER;
#endif
}
fmt = ast_best_codec(tmp->nativeformats);
i->codec = fmt;
tmp->readformat = fmt;
tmp->writeformat = fmt;
tmp->tech = &capi_tech;
tmp->rawreadformat = fmt;
tmp->rawwriteformat = fmt;
#else
if ((i->rtpcodec = (capi_controllers[i->controller]->rtpcodec & i->capability))) {
i->bproto = CC_BPROTO_VOCODER;
cc_add_formats(tmp->nativeformats, i->rtpcodec);
} else {
i->bproto = CC_BPROTO_TRANSPARENT;
cc_add_formats(tmp->nativeformats, capi_capability);
}
fmt = cc_set_best_codec(tmp);
i->codec = fmt;
#endif
tmp->tech = &capi_tech;
cc_verbose(3, 1, VERBOSE_PREFIX_2 "%s: setting format %s - %s%s\n",
i->vname, ast_getformatname(fmt),
i->vname, cc_getformatname(fmt),
ast_getformatname_multiple(alloca(80), 80,
tmp->nativeformats),
(i->bproto == CC_BPROTO_VOCODER) ? "VOCODER" : ((i->rtp) ? " (RTP)" : ""));
@ -2538,19 +2553,23 @@ static struct ast_channel *capi_new(struct capi_pvt *i, int state, const char *l
/*
* PBX wants us to dial ...
*/
#ifdef CC_AST_HAS_REQUEST_REQUESTOR
#ifdef CC_AST_HAS_REQUEST_FORMAT_T
#ifdef CC_AST_HAS_REQUEST_REQUESTOR /* { */
#ifdef CC_AST_HAS_REQUEST_FORMAT_T /* { */
static struct ast_channel *
pbx_capi_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause)
/* TODO: new field requestor to link to called channel */
#else
#elif !defined(CC_AST_HAS_VERSION_10_0) /* } { */
static struct ast_channel *
pbx_capi_request(const char *type, int format, const struct ast_channel *requestor, void *data, int *cause)
#endif
#else
#else /* } { */
static struct ast_channel *
pbx_capi_request(const char *type, struct ast_format_cap *format, const struct ast_channel *requestor, void *data, int *cause)
#endif /* } */
#else /* } { */
static struct ast_channel *
pbx_capi_request(const char *type, int format, void *data, int *cause)
#endif
#endif /* } */
{
struct capi_pvt *i, *bestChannel;
struct ast_channel *tmp = NULL;
@ -2560,7 +2579,9 @@ pbx_capi_request(const char *type, int format, void *data, int *cause)
unsigned int controller = 0;
unsigned int ccbsnrhandle = 0;
cc_verbose(1, 1, VERBOSE_PREFIX_4 "data = %s format=%d\n", (char *)data, format);
cc_verbose(1, 1, VERBOSE_PREFIX_4 "data = %s format=%s\n",
(char *)data,
ast_getformatname_multiple(alloca(80), 80, format));
cc_copy_string(buffer, (char *)data, sizeof(buffer));
capi_parse_dialstring(buffer, &interface, &dest, &param, &ocid);
@ -2643,6 +2664,8 @@ pbx_capi_request(const char *type, int format, void *data, int *cause)
found_best_channel:
/* when we come here, we found a free controller match */
cc_copy_string(i->dnid, dest, sizeof(i->dnid));
i->reserved = 1;
cc_mutex_unlock(&iflock);
tmp = capi_new(i, AST_STATE_RESERVED,
#ifdef CC_AST_HAS_REQUEST_REQUESTOR
requestor ? requestor->linkedid : NULL
@ -3151,8 +3174,8 @@ static void clear_channel_fax_loop(struct ast_channel *c, struct capi_pvt *i)
ast_indicate(chan, -1);
waitfd = i->readerfd;
ast_set_read_format(chan, capi_capability);
ast_set_write_format(chan, capi_capability);
cc_set_read_format(chan, capi_capability);
cc_set_write_format(chan, capi_capability);
while (capi_tell_fax_finish(i)) {
ready_fd = 0;
@ -4528,21 +4551,21 @@ static void capidev_handle_facility_indication(_cmsg *CMSG, unsigned int PLCI, u
static int pbx_capi_get_samples(struct capi_pvt *i, int length)
{
switch (i->codec) {
case AST_FORMAT_SLINEAR:
#if defined(AST_FORMAT_SLINEAR16)
case AST_FORMAT_SLINEAR16:
case CC_FORMAT_SLINEAR:
#if defined(CC_FORMAT_SLINEAR16)
case CC_FORMAT_SLINEAR16:
#endif
return (length/2);
#if defined(AST_FORMAT_G722)
case AST_FORMAT_G722:
#if defined(CC_FORMAT_G722)
case CC_FORMAT_G722:
return (length*2);
#endif
#if defined(AST_FORMAT_SIREN7)
case AST_FORMAT_SIREN7:
#if defined(CC_FORMAT_SIREN7)
case CC_FORMAT_SIREN7:
return (length * (320 / 80));
#endif
#if defined(AST_FORMAT_SIREN14)
case AST_FORMAT_SIREN14:
#if defined(CC_FORMAT_SIREN14)
case CC_FORMAT_SIREN14:
return ((typeof(length)) length * ((float) 640 / 120));
#endif
}
@ -4648,7 +4671,7 @@ static void capidev_handle_data_b3_indication(
if ((i->doES == 1) && (!capi_tcap_is_digital(i->transfercapability))) {
for (j = 0; j < b3len; j++) {
*(b3buf + j) = capi_reversebits[*(b3buf + j)];
if (capi_capability == AST_FORMAT_ULAW) {
if (capi_capability == CC_FORMAT_ULAW) {
rxavg += abs(capiULAW2INT[ capi_reversebits[*(b3buf + j)]]);
} else {
rxavg += abs(capiALAW2INT[ capi_reversebits[*(b3buf + j)]]);
@ -4661,7 +4684,7 @@ static void capidev_handle_data_b3_indication(
txavg = txavg / j;
if ( (txavg / ECHO_TXRX_RATIO) > rxavg) {
if (capi_capability == AST_FORMAT_ULAW) {
if (capi_capability == CC_FORMAT_ULAW) {
memset(b3buf, 255, b3len);
} else {
memset(b3buf, 85, b3len);
@ -4680,9 +4703,9 @@ static void capidev_handle_data_b3_indication(
}
}
}
FRAME_SUBCLASS_CODEC(fr.subclass) = capi_capability;
SET_FRAME_SUBCLASS_CODEC(fr.subclass, capi_capability);
} else {
FRAME_SUBCLASS_CODEC(fr.subclass) = i->codec;
SET_FRAME_SUBCLASS_CODEC(fr.subclass, i->codec);
}
fr.frametype = AST_FRAME_VOICE;
@ -4694,7 +4717,7 @@ static void capidev_handle_data_b3_indication(
fr.delivery = ast_tv(0,0);
fr.src = NULL;
cc_verbose(8, 1, VERBOSE_PREFIX_3 "%s: DATA_B3_IND (len=%d) fr.datalen=%d fr.subclass=%ld\n",
i->vname, b3len, fr.datalen, FRAME_SUBCLASS_CODEC(fr.subclass));
i->vname, b3len, fr.datalen, GET_FRAME_SUBCLASS_CODEC(fr.subclass));
local_queue_frame(i, &fr);
return;
}
@ -4895,7 +4918,16 @@ static void capidev_handle_diva_signaling_manufacturer_infications(struct capi_p
if (length != 0) {
capidev_read_name_from_diva_manufacturer_infications (data, &data[length], buffer, sizeof(buffer), &octet3a, i->vname, "Calling Party");
#ifdef CC_AST_HAS_VERSION_1_8
ast_set_callerid(i->owner, NULL, buffer, NULL);
/* ast_set_callerid updates CDR, but __ast_pbx_run updates CDR too.
__ast_pbx_run does not uses the channel lock and this results in destruction
of CDR list
Do notcall this function until problem resolved
ast_set_callerid(i->owner, NULL, buffer, NULL);
Use code from ast_set_callerid but do not update CDR
*/
i->owner->caller.id.name.valid = 1;
ast_free(i->owner->caller.id.name.str);
i->owner->caller.id.name.str = ast_strdup(buffer);
#else
ast_free (i->owner->cid.cid_name);
i->owner->cid.cid_name = ast_strdup(buffer); /* Save name to callerid */
@ -5330,7 +5362,7 @@ static void capidev_handle_connect_indication(
/* well...somebody is calling us. let's set up a channel */
cc_mutex_lock(&iflock);
for (i = capi_iflist; i; i = i->next) {
if (i->used) {
if (i->used || i->reserved) {
/* is already used */
continue;
}
@ -5387,6 +5419,8 @@ static void capidev_handle_connect_indication(
i->MessageNumber = HEADER_MSGNUM(CMSG);
i->cid_ton = callernplan;
i->reserved = 1;
cc_mutex_unlock(&iflock);
capi_new(i, AST_STATE_DOWN, NULL);
if (i->isdnmode == CAPI_ISDNMODE_DID) {
i->state = CAPI_STATE_DID;
@ -5418,7 +5452,17 @@ static void capidev_handle_connect_indication(
}
i->owner->caller.id.number.presentation = callpres;
ast_set_callerid(i->owner, effective_cid, NULL, effective_cid);
/* Don't use ast_set_callerid() here because it will
generate a needless NewCallerID event
ast_set_callerid(i->owner, effective_cid, NULL, effective_cid);
*/
i->owner->caller.id.number.valid = 1;
ast_free(i->owner->caller.id.number.str);
i->owner->caller.id.number.str = ast_strdup(effective_cid);
i->owner->caller.ani.number.valid = 1;
ast_free(i->owner->caller.ani.number.str);
i->owner->caller.ani.number.str = ast_strdup(effective_cid);
}
#else
i->owner->cid.cid_pres = callpres;
@ -5698,10 +5742,11 @@ static struct ast_channel* capidev_acquire_locks_from_thread_context(struct capi
cc_mutex_lock(&i->lock);
owner = i->owner;
if (likely(owner != 0)) {
struct ast_channel *ref_owner = owner;
ast_channel_ref (owner);
cc_mutex_unlock(&i->lock);
ast_channel_lock(owner);
ast_channel_unref (owner);
cc_mutex_lock(&i->lock);
if (unlikely(i->owner == 0)) {
cc_mutex_unlock (&i->lock);
@ -5709,6 +5754,7 @@ static struct ast_channel* capidev_acquire_locks_from_thread_context(struct capi
cc_mutex_lock (&i->lock);
owner = 0;
}
ast_channel_unref (ref_owner);
}
#else
for (;;) {
@ -6444,10 +6490,10 @@ static int pbx_capi_noisesuppressor(struct ast_channel *c, char *param)
}
if (ast_true(param)) {
i->divaDataStubAudioFlags |= 0x0080;
i->divaDataStubAudioFlags |= 0x0080 /* Use to activate in Tx direction 0x0040 */;
capi_diva_audio_features(i, 0);
} else if (ast_false(param)) {
i->divaDataStubAudioFlags &= ~0x0080;
i->divaDataStubAudioFlags &= ~0x0080 /* Use to activate in Tx direction ~0x0040 */;
capi_diva_audio_features(i, 0);
} else {
cc_log(LOG_WARNING, "Parameter for noise suppressor invalid.\n");
@ -7898,7 +7944,7 @@ void capi_gains(struct cc_capi_gains *g, float rxgain, float txgain)
if (rxgain != 1.0) {
for (i = 0; i < 256; i++) {
if (capi_capability == AST_FORMAT_ULAW) {
if (capi_capability == CC_FORMAT_ULAW) {
x = (int)(((float)capiULAW2INT[i]) * rxgain);
} else {
x = (int)(((float)capiALAW2INT[i]) * rxgain);
@ -7907,7 +7953,7 @@ void capi_gains(struct cc_capi_gains *g, float rxgain, float txgain)
x = 32767;
if (x < -32767)
x = -32767;
if (capi_capability == AST_FORMAT_ULAW) {
if (capi_capability == CC_FORMAT_ULAW) {
g->rxgains[i] = capi_int2ulaw(x);
} else {
g->rxgains[i] = capi_int2alaw(x);
@ -7917,7 +7963,7 @@ void capi_gains(struct cc_capi_gains *g, float rxgain, float txgain)
if (txgain != 1.0) {
for (i = 0; i < 256; i++) {
if (capi_capability == AST_FORMAT_ULAW) {
if (capi_capability == CC_FORMAT_ULAW) {
x = (int)(((float)capiULAW2INT[i]) * txgain);
} else {
x = (int)(((float)capiALAW2INT[i]) * txgain);
@ -7926,7 +7972,7 @@ void capi_gains(struct cc_capi_gains *g, float rxgain, float txgain)
x = 32767;
if (x < -32767)
x = -32767;
if (capi_capability == AST_FORMAT_ULAW) {
if (capi_capability == CC_FORMAT_ULAW) {
g->txgains[i] = capi_int2ulaw(x);
} else {
g->txgains[i] = capi_int2alaw(x);
@ -8162,10 +8208,15 @@ static void supported_sservices(struct cc_capi_controller *cp)
return;
}
const struct ast_channel_tech capi_tech = {
#ifndef CC_AST_HAS_VERSION_10_0
const
#endif
struct ast_channel_tech capi_tech = {
.type = channeltype,
.description = tdesc,
#ifndef CC_AST_HAS_VERSION_10_0
.capabilities = AST_FORMAT_ALAW,
#endif
.requester = pbx_capi_request,
#ifdef CC_AST_HAS_VERSION_1_4
.send_digit_begin = pbx_capi_send_digit_begin,
@ -8436,6 +8487,9 @@ static int conf_interface(struct cc_capi_conf *conf, struct ast_variable *v)
int faxpriority = 1;
char faxdest[AST_MAX_EXTENSION+1];
char *p, *q;
#ifdef CC_AST_HAS_VERSION_10_0
struct ast_format_cap *cap = ast_format_cap_alloc ();
#endif
memset(faxdest, 0, sizeof(faxdest));
cc_copy_string(faxcontext, "", sizeof(faxcontext));
@ -8633,10 +8687,10 @@ static int conf_interface(struct cc_capi_conf *conf, struct ast_variable *v)
v->value);
} else
if (!strcasecmp(v->name, "allow")) {
ast_parse_allow_disallow(&conf->prefs, &conf->capability, v->value, 1);
cc_parse_allow_disallow(&conf->prefs, &conf->capability, v->value, 1, cap);
} else
if (!strcasecmp(v->name, "disallow")) {
ast_parse_allow_disallow(&conf->prefs, &conf->capability, v->value, 0);
cc_parse_allow_disallow(&conf->prefs, &conf->capability, v->value, 0, cap);
}
cc_pbx_qsig_conf_interface_value(conf, v);
}
@ -8663,6 +8717,10 @@ static int conf_interface(struct cc_capi_conf *conf, struct ast_variable *v)
if (faxpriority < 1) faxpriority = 1;
conf->faxpriority = faxpriority;
#ifdef CC_AST_HAS_VERSION_10_0
ast_format_cap_destroy(cap);
#endif
return 0;
}
@ -8716,7 +8774,7 @@ static int capi_eval_config(struct ast_config *cfg)
}
} else if (!strcasecmp(v->name, "ulaw")) {
if (ast_true(v->value)) {
capi_capability = AST_FORMAT_ULAW;
capi_capability = CC_FORMAT_ULAW;
}
#ifdef DIVA_STREAMING
} else if (!strcasecmp(v->name, "nodivastreaming")) {
@ -8771,14 +8829,6 @@ static int capi_eval_config(struct ast_config *cfg)
return 0;
}
#ifdef CC_AST_HAS_VERSION_1_4
static int reload(void)
{
cc_log(LOG_WARNING, "config reload is not supported yet.\n");
return 0;
}
#endif
/*
* unload the module
*/
@ -8804,6 +8854,7 @@ int unload_module(void)
pthread_cancel(capi_device_thread);
pthread_kill(capi_device_thread, SIGURG);
pthread_join(capi_device_thread, NULL);
capi_device_thread = (pthread_t)(0-1);
}
cc_mutex_lock(&iflock);
@ -8820,6 +8871,7 @@ int unload_module(void)
diva_status_cleanup_interface(controller);
#endif
ast_free(capi_controllers[controller]);
capi_controllers[controller] = 0;
}
}
@ -8827,8 +8879,10 @@ int unload_module(void)
while (i) {
if ((i->owner) || (i->used))
cc_log(LOG_WARNING, "On unload, interface still has owner or is used.\n");
if (i->smoother)
if (i->smoother) {
ast_smoother_free(i->smoother);
i->smoother = 0;
}
pbx_capi_qsig_unload_module(i);
@ -8838,6 +8892,7 @@ int unload_module(void)
i = i->next;
ast_free(itmp);
}
capi_iflist = NULL;
cc_mutex_unlock(&iflock);
@ -8847,6 +8902,13 @@ int unload_module(void)
diva_verbose_unload();
#ifdef CC_AST_HAS_VERSION_10_0
capi_tech.capabilities = ast_format_cap_destroy(capi_tech.capabilities);
#endif
capi_num_controllers = 0;
capi_counter = 0;
return 0;
}
@ -8865,6 +8927,18 @@ int load_module(void)
struct ast_flags config_flags = { 0 };
#endif
#ifdef CC_AST_HAS_VERSION_10_0
if (!(capi_tech.capabilities = ast_format_cap_alloc())) {
return AST_MODULE_LOAD_DECLINE;
} else {
struct ast_format fmt;
ast_format_clear(&fmt);
ast_format_set(&fmt, AST_FORMAT_ALAW, 0);
ast_format_cap_add(capi_tech.capabilities, &fmt);
}
#endif
diva_verbose_load();
#ifdef CC_AST_HAS_VERSION_1_6
@ -8877,19 +8951,28 @@ int load_module(void)
if (!cfg) {
cc_log(LOG_ERROR, "Unable to load config %s, chan_capi disabled\n", config);
diva_verbose_unload();
#ifdef CC_AST_HAS_VERSION_10_0
capi_tech.capabilities = ast_format_cap_destroy(capi_tech.capabilities);
#endif
return 0;
}
if (cc_mutex_lock(&iflock)) {
cc_log(LOG_ERROR, "Unable to lock interface list???\n");
diva_verbose_unload();
#ifdef CC_AST_HAS_VERSION_10_0
capi_tech.capabilities = ast_format_cap_destroy(capi_tech.capabilities);
#endif
return -1;
}
if ((res = cc_init_capi()) != 0) {
cc_mutex_unlock(&iflock);
diva_verbose_unload();
return(res);
#ifdef CC_AST_HAS_VERSION_10_0
capi_tech.capabilities = ast_format_cap_destroy(capi_tech.capabilities);
#endif
return 0;
}
res = capi_eval_config(cfg);
@ -8898,6 +8981,9 @@ int load_module(void)
if (res != 0) {
cc_mutex_unlock(&iflock);
diva_verbose_unload();
#ifdef CC_AST_HAS_VERSION_10_0
capi_tech.capabilities = ast_format_cap_destroy(capi_tech.capabilities);
#endif
return(res);
}
@ -8925,12 +9011,27 @@ int load_module(void)
if (ast_pthread_create(&capi_device_thread, NULL, capidev_loop, NULL) < 0) {
capi_device_thread = (pthread_t)(0-1);
cc_log(LOG_ERROR, "Unable to start CAPI device thread!\n");
unload_module();
return -1;
}
return 0;
}
#ifdef CC_AST_HAS_VERSION_1_4
static int reload(void)
{
int ret;
cc_verbose(1, 0, VERBOSE_PREFIX_1 "config reload\n");
unload_module();
ret = load_module();
return ret;
}
#endif
#ifdef CC_AST_HAS_VERSION_1_4
AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, tdesc,
.load = load_module,

View File

@ -45,6 +45,7 @@
#endif
#include "asterisk/musiconhold.h"
#include "dlist.h"
#include "chan_capi_fmt.h"
#ifndef _PBX_CAPI_H
#define _PBX_CAPI_H
@ -146,10 +147,19 @@ static inline unsigned int read_capi_dword(const void *m)
#ifdef CC_AST_HAS_UNION_SUBCLASS_IN_FRAME
#define FRAME_SUBCLASS_INTEGER(x) x.integer
#define FRAME_SUBCLASS_CODEC(x) x.codec
#ifndef CC_AST_HAS_VERSION_10_0
#define SET_FRAME_SUBCLASS_CODEC(__a__,__b__) do {(__a__).codec = (__b__); }while(0)
#define GET_FRAME_SUBCLASS_CODEC(__a__) (__a__).codec
#else
#define SET_FRAME_SUBCLASS_CODEC(__a__,__b__) do{ ast_format_from_old_bitfield(&(__a__).format, __b__); } while(0)
#define GET_FRAME_SUBCLASS_CODEC(__a__) ast_format_to_old_bitfield(&(__a__).format)
#endif
#else
#define FRAME_SUBCLASS_INTEGER(x) x
#define FRAME_SUBCLASS_CODEC(x) x
#define SET_FRAME_SUBCLASS_CODEC(__a__, __b__) do { (__a__) = (__b__); }while(0)
#define GET_FRAME_SUBCLASS_CODEC(__a__) __a__
#endif
#ifndef CC_AST_HAS_CHANNEL_RELEASE
@ -383,6 +393,8 @@ struct capi_pvt {
struct ast_channel *owner;
/*! Channel who called us, possibly NULL */
struct ast_channel *peer;
/*! Set if structure is reserved */
volatile int reserved;
/* capi message number */
_cword MessageNumber;
@ -765,7 +777,11 @@ struct cc_capi_controller {
/*
* prototypes
*/
extern const struct ast_channel_tech capi_tech;
extern
#ifndef CC_AST_HAS_VERSION_10_0
const
#endif
struct ast_channel_tech capi_tech;
#ifdef CC_AST_HAS_FORMAT_T
extern format_t capi_capability;
#else

View File

@ -503,8 +503,8 @@ static void chat_handle_events(struct ast_channel *c, struct capi_pvt *i,
if (i->channeltype == CAPI_CHANNELTYPE_NULL) {
int fmt = (i->line_plci != 0 && i->line_plci->bproto == CC_BPROTO_VOCODER) ? i->line_plci->codec : capi_capability;
nfds = 1;
ast_set_read_format(chan, fmt);
ast_set_write_format(chan, fmt);
cc_set_read_format(chan, fmt);
cc_set_write_format(chan, fmt);
}
if ((flags & CHAT_FLAG_MOH) && ((room->active < 2) || (voice_message != NULL))) {
@ -1063,7 +1063,7 @@ int pbx_capi_chat_associate_resource_plci(struct ast_channel *c, char *param)
if (strcmp (currentcodec, "all") == 0) {
all = 1; /* All supported by selected controller codecs */
} else {
codecs |= ast_getformatbyname (currentcodec);
codecs |= cc_getformatbyname (currentcodec);
}
}
}

246
chan_capi_fmt.h Normal file
View File

@ -0,0 +1,246 @@
/*
*
Copyright (c) Dialogic(R), 2010
*
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
*
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
*
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#ifdef CC_AST_HAS_VERSION_10_0 /* { */
#define CC_FORMAT_ALAW (1ULL << 3)
#define CC_FORMAT_G722 (1ULL << 12)
#define CC_FORMAT_G723_1 (1ULL << 0)
#define CC_FORMAT_G726 (1ULL << 11)
#define CC_FORMAT_G729A (1ULL << 8)
#define CC_FORMAT_GSM (1ULL << 1)
#define CC_FORMAT_ILBC (1ULL << 10)
#define CC_FORMAT_SIREN14 (1ULL << 14)
#define CC_FORMAT_SIREN7 (1ULL << 13)
#define CC_FORMAT_SLINEAR (1ULL << 6)
#define CC_FORMAT_SLINEAR16 (1ULL << 15)
#define CC_FORMAT_ULAW (1ULL << 2)
static inline enum ast_format_id ccCodec2AstCodec(int ccCodec)
{
#if 0
unsigned int ret;
switch (ccCodec) {
case CC_FORMAT_ALAW:
ret = AST_FORMAT_ALAW;
break;
case CC_FORMAT_G722:
ret = AST_FORMAT_G722;
break;
case CC_FORMAT_G723_1:
ret = AST_FORMAT_G723_1;
break;
case CC_FORMAT_G726:
ret = AST_FORMAT_G726;
break;
case CC_FORMAT_G729A:
ret = AST_FORMAT_G729A;
break;
case CC_FORMAT_GSM:
ret = AST_FORMAT_GSM;
break;
case CC_FORMAT_ILBC:
ret = AST_FORMAT_ILBC;
break;
case CC_FORMAT_SIREN14:
ret = AST_FORMAT_SIREN14;
break;
case CC_FORMAT_SIREN7:
ret = AST_FORMAT_SIREN7;
break;
case CC_FORMAT_SLINEAR:
ret = AST_FORMAT_SLINEAR;
break;
case CC_FORMAT_SLINEAR16:
ret = AST_FORMAT_SLINEAR16;
break;
case CC_FORMAT_ULAW:
ret = AST_FORMAT_ULAW;
break;
default:
ret = 0;
break;
}
return ret;
#else
return (ast_format_id_from_old_bitfield(ccCodec));
#endif
}
static inline const char* cc_getformatname(int ccCodec)
{
enum ast_format_id id = ccCodec2AstCodec (ccCodec);
struct ast_format fmt;
ast_format_clear(&fmt);
ast_format_set(&fmt, id, 0);
return ast_getformatname(&fmt);
}
static inline void cc_add_formats(struct ast_format_cap *fmts, unsigned int divaFormats)
{
int i;
for (i = 0; i < 32; i++) {
unsigned int ccCodec = (1U << i);
if ((divaFormats & ccCodec) != 0) {
enum ast_format_id id = ccCodec2AstCodec (ccCodec);
struct ast_format fmt;
ast_format_clear(&fmt);
ast_format_set(&fmt, id, 0);
ast_format_cap_add(fmts, &fmt);
}
}
}
static inline int cc_set_best_codec(struct ast_channel *a)
{
struct ast_format bestCodec;
ast_format_clear(&bestCodec);
if (ast_best_codec(a->nativeformats, &bestCodec) == NULL) {
/*
Fallback to aLaw
*/
ast_format_set(&bestCodec, CC_FORMAT_ALAW, 0);
}
ast_format_copy(&a->rawreadformat, &bestCodec);
ast_format_copy(&a->readformat, &bestCodec);
ast_format_copy(&a->rawwriteformat, &bestCodec);
ast_format_copy(&a->writeformat, &bestCodec);
return (int)ast_format_to_old_bitfield(&bestCodec);
}
static inline void cc_set_read_format(struct ast_channel* a, int ccCodec)
{
struct ast_format ccFmt;
ast_format_clear(&ccFmt);
ast_format_set(&ccFmt, ccCodec, 0);
ast_set_read_format(a, &ccFmt);
}
static inline void cc_set_write_format(struct ast_channel* a, int ccCodec)
{
struct ast_format ccFmt;
ast_format_clear(&ccFmt);
ast_format_set(&ccFmt, ccCodec, 0);
ast_set_write_format(a, &ccFmt);
}
#define cc_parse_allow_disallow(__prefs__, __capability__, __value__, __allowing__, __cap__) do{\
ast_parse_allow_disallow(__prefs__, __cap__, __value__, __allowing__); \
*(__capability__) = (int)ast_format_cap_to_old_bitfield(__cap__); }while(0)
#define cc_get_formats_as_bits(__a__) (int)ast_format_cap_to_old_bitfield(__a__)
static inline int cc_get_best_codec_as_bits(int src)
{
struct ast_format_cap *dst = ast_format_cap_alloc_nolock();
int ret = 0;
if (dst != 0) {
struct ast_format bestCodec;
ast_format_cap_from_old_bitfield(dst, src);
ast_format_clear(&bestCodec);
if (ast_best_codec(dst, &bestCodec) != NULL) {
ret = (int)ast_format_to_old_bitfield(&bestCodec);
}
ast_format_cap_destroy(dst);
}
return (ret);
}
#define cc_set_read_format(__a__, __b__) ast_set_read_format_by_id(__a__, ccCodec2AstCodec (__b__))
#define cc_set_write_format(__a__, __b__) ast_set_write_format_by_id(__a__, ccCodec2AstCodec (__b__))
static inline int cc_getformatbyname(const char* value)
{
struct ast_format fmt;
int ret = 0;
if (ast_getformatbyname(value, &fmt) != NULL) {
ret = (int)ast_format_to_old_bitfield(&fmt);
}
return (ret);
}
#else /* } { */
#define CC_FORMAT_ALAW AST_FORMAT_ALAW
#ifdef AST_FORMAT_G722
#define CC_FORMAT_G722 AST_FORMAT_G722
#endif
#define CC_FORMAT_G723_1 AST_FORMAT_G723_1
#define CC_FORMAT_G726 AST_FORMAT_G726
#define CC_FORMAT_G729A AST_FORMAT_G729A
#define CC_FORMAT_GSM AST_FORMAT_GSM
#define CC_FORMAT_ILBC AST_FORMAT_ILBC
#ifdef AST_FORMAT_SIREN14
#define CC_FORMAT_SIREN14 AST_FORMAT_SIREN14
#endif
#ifdef AST_FORMAT_SIREN7
#define CC_FORMAT_SIREN7 AST_FORMAT_SIREN7
#endif
#ifdef AST_FORMAT_SLINEAR
#define CC_FORMAT_SLINEAR AST_FORMAT_SLINEAR
#endif
#ifdef AST_FORMAT_SLINEAR16
#define CC_FORMAT_SLINEAR16 AST_FORMAT_SLINEAR16
#endif
#define CC_FORMAT_ULAW AST_FORMAT_ULAW
#define cc_getformatname(__x__) ast_getformatname((__x__))
#define cc_add_formats(__x__,__y__) do {(__x__)=(__y__);}while(0)
static inline int cc_set_best_codec(struct ast_channel *a)
{
int fmt = ast_best_codec(a->nativeformats);
a->readformat = fmt;
a->writeformat = fmt;
a->rawreadformat = fmt;
a->rawwriteformat = fmt;
return fmt;
}
#define cc_set_read_format(__a__, __b__) ast_set_read_format(__a__, __b__)
#define cc_set_write_format(__a__, __b__) ast_set_write_format(__a__, __b__)
#define cc_parse_allow_disallow(__a__, __b__, __c__, __d__, __e__) ast_parse_allow_disallow(__a__, __b__, __c__, __d__)
#define cc_get_formats_as_bits(__a__) (__a__)
#define cc_get_best_codec_as_bits(__a__) ast_best_codec(__a__)
#define cc_getformatbyname(__a__) ast_getformatbyname(__a__)
#endif /* } */

View File

@ -76,7 +76,16 @@ void cc_qsig_op_ecma_isdn_namepres(struct cc_qsig_invokedata *invoke, struct cap
switch (invoke->type) {
case 0: /* Calling Name */
#ifdef CC_AST_HAS_VERSION_1_8
ast_set_callerid(i->owner, NULL, callername, NULL);
/* ast_set_callerid updates CDR, but __ast_pbx_run updates CDR too.
__ast_pbx_run does not uses the channel lock and this results in destruction
of CDR list
Do notcall this function until problem resolved
ast_set_callerid(i->owner, NULL, callername, NULL);
Use code from ast_set_callerid but do not update CDR
*/
i->owner->caller.id.name.valid = 1;
ast_free(i->owner->caller.id.name.str);
i->owner->caller.id.name.str = ast_strdup(callername);
#else
i->owner->cid.cid_name = ast_strdup(callername); /* Save name to callerid */
#endif

View File

@ -122,27 +122,27 @@ _cstruct capi_rtp_ncpi(struct capi_pvt *i)
if ((i) && (i->owner) &&
(i->bproto == CC_BPROTO_RTP)) {
switch(i->codec) {
case AST_FORMAT_ALAW:
case CC_FORMAT_ALAW:
ncpi = NCPI_voice_over_ip_alaw;
break;
case AST_FORMAT_ULAW:
case CC_FORMAT_ULAW:
ncpi = NCPI_voice_over_ip_ulaw;
break;
case AST_FORMAT_GSM:
case CC_FORMAT_GSM:
ncpi = NCPI_voice_over_ip_gsm;
break;
case AST_FORMAT_G723_1:
case CC_FORMAT_G723_1:
ncpi = NCPI_voice_over_ip_g723;
break;
case AST_FORMAT_G726:
case CC_FORMAT_G726:
ncpi = NCPI_voice_over_ip_g726;
break;
case AST_FORMAT_G729A:
case CC_FORMAT_G729A:
ncpi = NCPI_voice_over_ip_g729;
break;
default:
cc_log(LOG_ERROR, "%s: format %s(%d) invalid.\n",
i->vname, ast_getformatname(i->codec), i->codec);
i->vname, cc_getformatname(i->codec), i->codec);
break;
}
}
@ -155,6 +155,7 @@ _cstruct capi_rtp_ncpi(struct capi_pvt *i)
*/
int capi_alloc_rtp(struct capi_pvt *i)
{
#ifndef CC_AST_HAS_VERSION_10_0 /* Use vocoder without RTP framing */
#ifdef CC_AST_HAS_AST_SOCKADDR
struct ast_sockaddr addr;
struct ast_sockaddr us;
@ -210,6 +211,11 @@ int capi_alloc_rtp(struct capi_pvt *i)
#endif
i->timestamp = 0;
return 0;
#else
i->rtp = 0;
cc_log(LOG_ERROR, "%s: use vocoder\n", i->vname);
return 1;
#endif
}
/*
@ -217,6 +223,7 @@ int capi_alloc_rtp(struct capi_pvt *i)
*/
int capi_write_rtp(struct capi_pvt *i, struct ast_frame *f)
{
#ifndef CC_AST_HAS_VERSION_10_0 /* Use vocoder */
#ifdef CC_AST_HAS_AST_SOCKADDR
struct ast_sockaddr us;
#else
@ -283,7 +290,7 @@ int capi_write_rtp(struct capi_pvt *i, struct ast_frame *f)
i->send_buffer_handle++;
cc_verbose(6, 1, VERBOSE_PREFIX_4 "%s: RTP write for NCCI=%#x len=%d(%d) %s ts=%x\n",
i->vname, i->NCCI, len, f->datalen, ast_getformatname(FRAME_SUBCLASS_CODEC(f->subclass)),
i->vname, i->NCCI, len, f->datalen, cc_getformatname(GET_FRAME_SUBCLASS_CODEC(f->subclass)),
i->timestamp);
capi_sendf(NULL, 0, CAPI_DATA_B3_REQ, i->NCCI, get_capi_MessageNumber(),
@ -295,6 +302,8 @@ int capi_write_rtp(struct capi_pvt *i, struct ast_frame *f)
);
}
#endif
return 0;
}
@ -303,6 +312,7 @@ int capi_write_rtp(struct capi_pvt *i, struct ast_frame *f)
*/
struct ast_frame *capi_read_rtp(struct capi_pvt *i, unsigned char *buf, int len)
{
#ifndef CC_AST_HAS_VERSION_10_0 /* Use vocoder */
struct ast_frame *f;
#ifdef CC_AST_HAS_AST_SOCKADDR
struct ast_sockaddr us;
@ -352,17 +362,20 @@ struct ast_frame *capi_read_rtp(struct capi_pvt *i, unsigned char *buf, int len)
return NULL;
}
cc_verbose(6, 1, VERBOSE_PREFIX_4 "%s: DATA_B3_IND RTP NCCI=%#x len=%d %s (read/write=%d/%d)\n",
i->vname, i->NCCI, len, ast_getformatname(FRAME_SUBCLASS_CODEC(f->subclass)),
i->vname, i->NCCI, len, cc_getformatname(GET_FRAME_SUBCLASS_CODEC(f->subclass)),
i->owner->readformat, i->owner->writeformat);
if (i->owner->nativeformats != FRAME_SUBCLASS_CODEC(f->subclass)) {
if (i->owner->nativeformats != GET_FRAME_SUBCLASS_CODEC(f->subclass)) {
cc_verbose(3, 1, VERBOSE_PREFIX_3 "%s: DATA_B3_IND RTP nativeformats=%d, but subclass=%ld\n",
i->vname, i->owner->nativeformats, FRAME_SUBCLASS_CODEC(f->subclass));
i->owner->nativeformats = FRAME_SUBCLASS_CODEC(f->subclass);
i->vname, i->owner->nativeformats, GET_FRAME_SUBCLASS_CODEC(f->subclass));
i->owner->nativeformats = GET_FRAME_SUBCLASS_CODEC(f->subclass);
ast_set_read_format(i->owner, i->owner->readformat);
ast_set_write_format(i->owner, i->owner->writeformat);
}
}
return f;
#else
return NULL;
#endif
}
/*
@ -435,59 +448,59 @@ void voice_over_ip_profile(struct cc_capi_controller *cp)
cc_verbose(3, 0, VERBOSE_PREFIX_4 "RTP codec: ");
if (payload1 & 0x00000100) {
cp->rtpcodec |= AST_FORMAT_ALAW;
cp->rtpcodec |= CC_FORMAT_ALAW;
cc_verbose(3, 0, "G.711-alaw ");
}
if (payload1 & 0x00000001) {
cp->rtpcodec |= AST_FORMAT_ULAW;
cp->rtpcodec |= CC_FORMAT_ULAW;
cc_verbose(3, 0, "G.711-ulaw ");
}
if (payload1 & 0x00000008) {
cp->rtpcodec |= AST_FORMAT_GSM;
cp->rtpcodec |= CC_FORMAT_GSM;
cc_verbose(3, 0, "GSM ");
}
if (payload1 & 0x00000010) {
cp->rtpcodec |= AST_FORMAT_G723_1;
cp->rtpcodec |= CC_FORMAT_G723_1;
cc_verbose(3, 0, "G.723.1 ");
}
if (payload1 & 0x00000004) {
cp->rtpcodec |= AST_FORMAT_G726;
cp->rtpcodec |= CC_FORMAT_G726;
cc_verbose(3, 0, "G.726 ");
}
if (payload1 & 0x00040000) {
cp->rtpcodec |= AST_FORMAT_G729A;
cp->rtpcodec |= CC_FORMAT_G729A;
cc_verbose(3, 0, "G.729 ");
}
if (payload1 & (1U << 27)) {
cp->rtpcodec |= AST_FORMAT_ILBC;
cp->rtpcodec |= CC_FORMAT_ILBC;
cc_verbose(3, 0, "iLBC ");
}
#ifdef AST_FORMAT_G722
#ifdef CC_FORMAT_G722
if (payload1 & (1U << 9)) {
cp->rtpcodec |= AST_FORMAT_G722;
cp->rtpcodec |= CC_FORMAT_G722;
cc_verbose(3, 0, "G.722 ");
}
#endif
#if defined(AST_FORMAT_SIREN7) && defined(AST_FORMAT_SIREN14)
#if defined(CC_FORMAT_SIREN7) && defined(CC_FORMAT_SIREN14)
if (payload1 & (1U << 24)) {
#ifdef AST_FORMAT_SIREN7
cp->rtpcodec |= AST_FORMAT_SIREN7;
#ifdef CC_FORMAT_SIREN7
cp->rtpcodec |= CC_FORMAT_SIREN7;
cc_verbose(3, 0, "siren7 ");
#endif
#ifdef AST_FORMAT_SIREN14
cp->rtpcodec |= AST_FORMAT_SIREN14;
#ifdef CC_FORMAT_SIREN14
cp->rtpcodec |= CC_FORMAT_SIREN14;
cc_verbose(3, 0, "siren14 ");
#endif
}
#endif
#if defined(AST_FORMAT_SLINEAR) || defined(AST_FORMAT_SLINEAR16)
#if defined(CC_FORMAT_SLINEAR) || defined(CC_FORMAT_SLINEAR16)
if (payload1 & (1U << 1)) {
#if defined(AST_FORMAT_SLINEAR)
cp->rtpcodec |= AST_FORMAT_SLINEAR;
#if defined(CC_FORMAT_SLINEAR)
cp->rtpcodec |= CC_FORMAT_SLINEAR;
cc_verbose(3, 0, "slin ");
#endif
#if defined(AST_FORMAT_SLINEAR16)
cp->rtpcodec |= AST_FORMAT_SLINEAR16;
#if defined(CC_FORMAT_SLINEAR16)
cp->rtpcodec |= CC_FORMAT_SLINEAR16;
cc_verbose(3, 0, "slin16 ");
#endif
}

View File

@ -135,8 +135,10 @@ void capi_remove_nullif(struct capi_pvt *i)
}
cc_verbose(3, 1, VERBOSE_PREFIX_4 "%s: removed null-interface from controller %d.\n",
i->vname, i->controller);
if (i->smoother)
if (i->smoother) {
ast_smoother_free(i->smoother);
i->smoother = 0;
}
cc_mutex_destroy(&i->lock);
ast_cond_destroy(&i->event_trigger);
controller_nullplcis[i->controller - 1]--;
@ -301,9 +303,9 @@ struct capi_pvt *capi_mkresourceif(
} else {
controller = data_plci_ifc->controller;
codecs = (all != 0) ? pbx_capi_get_controller_codecs (controller) : codecs;
fmt = pbx_capi_get_controller_codecs (controller) & codecs & c->nativeformats;
fmt = pbx_capi_get_controller_codecs (controller) & codecs & cc_get_formats_as_bits(c->nativeformats);
if (fmt != 0)
fmt = ast_best_codec(fmt);
fmt = cc_get_best_codec_as_bits(fmt);
}
data_ifc = ast_malloc(sizeof(struct capi_pvt));
@ -1458,10 +1460,10 @@ int capi_write_frame(struct capi_pvt *i, struct ast_frame *f)
return 0;
}
if (i->isdnstate & CAPI_ISDN_STATE_RTP) {
if (unlikely((!(FRAME_SUBCLASS_CODEC(f->subclass) & i->codec)) &&
(FRAME_SUBCLASS_CODEC(f->subclass) != capi_capability))) {
if (unlikely((!(GET_FRAME_SUBCLASS_CODEC(f->subclass) & i->codec)) &&
(GET_FRAME_SUBCLASS_CODEC(f->subclass) != capi_capability))) {
cc_log(LOG_ERROR, "don't know how to write subclass %s(%d)\n",
ast_getformatname(FRAME_SUBCLASS_CODEC(f->subclass)),
cc_getformatname(GET_FRAME_SUBCLASS_CODEC(f->subclass)),
FRAME_SUBCLASS_INTEGER(f->subclass));
return 0;
}

View File

@ -50,6 +50,14 @@ echo "#define CHAN_CAPI_CONFIG_H" >>$CONFIGFILE
echo >>$CONFIGFILE
case "$AVERSIONNUM" in
100*)
echo "#define CC_AST_HAS_VERSION_1_6" >>$CONFIGFILE
echo "#define CC_AST_HAS_VERSION_1_8" >>$CONFIGFILE
echo "#define CC_AST_HAS_VERSION_10_0" >>$CONFIGFILE
echo "#define CC_AST_HAS_EVENT_MWI" >>$CONFIGFILE
echo " * found Asterisk version 10"
VER=10_0
;;
108*)
echo "#define CC_AST_HAS_VERSION_1_6" >>$CONFIGFILE
echo "#define CC_AST_HAS_VERSION_1_8" >>$CONFIGFILE
@ -271,6 +279,10 @@ case $VER in
echo "Using Asterisk 1.8 API"
check_version_onesix
;;
10_0)
echo "Using Asterisk 10.0 API"
check_version_onesix
;;
*)
echo >&2 "Asterisk version invalid."
exit 1

View File

@ -372,7 +372,7 @@ static char* diva_status_read_file(unsigned int controller, const char* fileName
static int diva_status_get_controller_state(int controller, diva_status_ifc_state_t *state)
{
char *data, *p;
int i, pri;
int i, pri, bri;
const char* v;
memset (state, 0x00, sizeof(*state));
@ -380,6 +380,8 @@ static int diva_status_get_controller_state(int controller, diva_status_ifc_stat
state->hwState = DivaStatusHwStateUnknown;
state->ifcL1State = DivaStatusIfcL2DoNotApply;
state->ifcL2State = DivaStatusIfcL2DoNotApply;
state->ifcL1VisualState = DivaStatusIfcL2DoNotApply;
state->ifcL2VisualState = DivaStatusIfcL2DoNotApply;
if (diva_status_active() != 0)
return -1;
@ -387,7 +389,7 @@ static int diva_status_get_controller_state(int controller, diva_status_ifc_stat
if ((data = diva_status_read_file(controller, DIVA_CONFIG_FILE)) == 0)
return -1;
for (i = 0, pri = 0, p = data, v = strsep(&p, ",");
for (i = 0, pri = 0, bri = 0, p = data, v = strsep(&p, ",");
v != 0 && i < DivaStateIfcConfig_Max;
v = strsep(&p, ","), i++) {
if (v[0] == '\'' && v[strlen(v)-1] != '\'') {
@ -402,10 +404,12 @@ static int diva_status_get_controller_state(int controller, diva_status_ifc_stat
switch ((diva_state_ifc_config_parameters_t)i) {
case DivaStateIfcConfig_TYPE:
pri += (strcmp ("PRI", v) == 0);
bri += (strcmp ("BRI", v) == 0);
break;
case DivaStateIfcConfig_PRI:
pri += (strcmp ("'YES'", v) == 0);
bri += (strcmp ("'NO'", v) == 0);
break;
default:
@ -415,6 +419,9 @@ static int diva_status_get_controller_state(int controller, diva_status_ifc_stat
ast_free(data);
state->ifcType = (pri == 2) ? DivaStatusIfcPri : DivaStatusIfcNotPri;
if (bri == 2) {
state->ifcType = DivaStatusIfcBri;
}
if ((data = diva_status_read_file(controller, DIVA_STATUS_FILE)) == 0)
return (-1);
@ -431,14 +438,16 @@ static int diva_status_get_controller_state(int controller, diva_status_ifc_stat
switch ((diva_state_ifcstate_parameters_t)i) {
case DivaStateIfcState_LAYER1_STATE:
state->ifcL1VisualState = (strcmp ("'Activated'", v) == 0) ? DivaStatusIfcL1OK : DivaStatusIfcL1Error;
if (state->ifcType == DivaStatusIfcPri) {
state->ifcL1State = (strcmp ("'Activated'", v) == 0) ? DivaStatusIfcL1OK : DivaStatusIfcL1Error;
state->ifcL1State = state->ifcL1VisualState;
}
break;
case DivaStateIfcState_LAYER2_STATE:
state->ifcL2VisualState = (strcmp ("'Layer2 UP'", v) == 0) ? DivaStatusIfcL2OK : DivaStatusIfcL2Error;
if (state->ifcType == DivaStatusIfcPri) {
state->ifcL2State = (strcmp ("'Layer2 UP'", v) == 0) ? DivaStatusIfcL2OK : DivaStatusIfcL2Error;
state->ifcL2State = state->ifcL2VisualState;
}
break;
@ -611,6 +620,77 @@ const char* diva_status_hw_state_name(diva_status_hardware_state_t hwState)
}
}
static const char* pbxcli_get_visual_ifc_state(const diva_status_ifc_state_t* state)
{
diva_status_interface_state_t ifcState;
switch (state->ifcType) {
case DivaStatusIfcBri: /* Functional state is always unknown, probably L1/L2 activated on demand, \todo read L2 config */
if (state->hwState == DivaStateHwStateActive &&
state->ifcL1VisualState == DivaStatusIfcL1OK &&
state->ifcL2VisualState == DivaStatusIfcL2OK) {
ifcState = DivaStatusInterfaceStateOK;
} else {
ifcState = diva_status_get_interface_state_from_idi_state (state);
}
break;
case DivaStatusIfcAnalog: /* \todo implementation */
ifcState = diva_status_get_interface_state_from_idi_state (state);
break;
case DivaStatusIfcPri: /* Functional state == visual state */
default:
ifcState = diva_status_get_interface_state_from_idi_state (state);
break;
}
return (diva_status_interface_state_name(ifcState));
}
static const char* pbxcli_get_visual_ifc_l1_state(const diva_status_ifc_state_t* state)
{
const char* ret = "-";
if (state->hwState == DivaStatusHardwareStateOK) {
switch (state->ifcType) {
case DivaStatusIfcPri: /* Functional state == visual state */
ret = (state->ifcL1State == DivaStatusIfcL1OK) ? "On" : "Off";
break;
case DivaStatusIfcBri:
ret = (state->ifcL1VisualState == DivaStatusIfcL1OK) ? "On" : "Off"; /* Functional state != visual state */
break;
case DivaStatusIfcAnalog: /* \todo implementation */
break;
default:
break;
}
}
return (ret);
}
static const char* pbxcli_get_visual_ifc_l2_state(const diva_status_ifc_state_t* state)
{
const char* ret = "-";
if (state->hwState == DivaStatusHardwareStateOK) {
switch (state->ifcType) {
case DivaStatusIfcPri: /* Functional state == visual state */
ret = (state->ifcL2State == DivaStatusIfcL2OK) ? "On" : "Off";
break;
case DivaStatusIfcBri:
ret = (state->ifcL2VisualState == DivaStatusIfcL2OK) ? "On" : "Off"; /* Functional state != visual state */
break;
case DivaStatusIfcAnalog: /* \todo implementation */
break;
default:
break;
}
}
return (ret);
}
#ifdef CC_AST_HAS_VERSION_1_6
char *pbxcli_capi_ifc_status(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
@ -650,11 +730,9 @@ int pbxcli_capi_ifc_status(int fd, int argc, char *argv[])
diva_status_ifc_state_t* state = &controllerState->state[controllerState->currentState];
ast_cli(fd, "ISDN%-3d%-2s %-9s%-4s%-4s%-4s%-7s%-3s %12d %11d %11d %11d %11d\n",
controllerState->capiController, "",
diva_status_interface_state_name(diva_status_get_interface_state_from_idi_state (state)),
((state->ifcType == DivaStatusIfcPri) && (state->hwState == DivaStatusHardwareStateOK)) ?
(state->ifcL1State == DivaStatusIfcL1OK ? "On" : "Off") : "-",
((state->ifcType == DivaStatusIfcPri) && (state->hwState == DivaStatusHardwareStateOK)) ?
(state->ifcL2State == DivaStatusIfcL2OK ? "On" : "Off") : "-",
pbxcli_get_visual_ifc_state(state),
pbxcli_get_visual_ifc_l1_state(state),
pbxcli_get_visual_ifc_l2_state(state),
((state->ifcType == DivaStatusIfcPri) && (state->hwState == DivaStatusHardwareStateOK)) ?
(state->ifcAlarms.Red != 0 ? "On" : "Off") : "-",
((state->ifcType == DivaStatusIfcPri) && (state->hwState == DivaStatusHardwareStateOK)) ?

View File

@ -69,6 +69,8 @@ typedef struct _diva_status_ifc_state {
diva_status_ifc_alarms_t ifcAlarms;
diva_status_ifc_l1_state_t ifcL1State;
diva_status_ifc_l2_state_t ifcL2State;
diva_status_ifc_l1_state_t ifcL1VisualState;
diva_status_ifc_l2_state_t ifcL2VisualState;
diva_status_ifc_statistics_t ifcRxDStatistics;
diva_status_ifc_statistics_t ifcTxDStatistics;
unsigned int serialNumber;