Compaibility with asterisk 10.0 BETA1

master
MelwareDE 12 years ago
parent 0f986eebc9
commit a195a39a55
  1. 221
      chan_capi.c
  2. 20
      chan_capi.h
  3. 6
      chan_capi_chat.c
  4. 246
      chan_capi_fmt.h
  5. 67
      chan_capi_rtp.c
  6. 10
      chan_capi_utils.c
  7. 12
      create_config.sh

@ -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;
@ -1655,31 +1655,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 +1771,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 +1885,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
@ -2435,35 +2435,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 +2544,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 +2570,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);
@ -3151,8 +3163,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 +4540,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 +4660,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 +4673,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 +4692,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 +4706,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;
}
@ -7898,7 +7910,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 +7919,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 +7929,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 +7938,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 +8174,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 +8453,11 @@ 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 ();
#else
const void* cap = 0;
#endif
memset(faxdest, 0, sizeof(faxdest));
cc_copy_string(faxcontext, "", sizeof(faxcontext));
@ -8633,10 +8655,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 +8685,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 +8742,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")) {
@ -8847,6 +8873,10 @@ 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
return 0;
}
@ -8865,6 +8895,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,18 +8919,27 @@ 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();
#ifdef CC_AST_HAS_VERSION_10_0
capi_tech.capabilities = ast_format_cap_destroy(capi_tech.capabilities);
#endif
return(res);
}
@ -8898,6 +8949,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,6 +8979,7 @@ 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;
}

@ -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
@ -765,7 +775,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

@ -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);
}
}
}

@ -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 /* } */

@ -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;
@ -363,6 +373,9 @@ struct ast_frame *capi_read_rtp(struct capi_pvt *i, unsigned char *buf, int len)
}
}
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
}

@ -301,9 +301,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 +1458,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;
}

@ -50,6 +50,14 @@ echo "#define CHAN_CAPI_CONFIG_H" >>$CONFIGFILE
echo >>$CONFIGFILE
case "$AVERSIONNUM" in
1000*)
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

Loading…
Cancel
Save