From a195a39a5576cfcfc08333d97f01b688eec93a27 Mon Sep 17 00:00:00 2001 From: MelwareDE Date: Tue, 4 Oct 2011 08:41:28 +0000 Subject: [PATCH] Compaibility with asterisk 10.0 BETA1 --- chan_capi.c | 221 +++++++++++++++++++++++++---------------- chan_capi.h | 20 +++- chan_capi_chat.c | 6 +- chan_capi_fmt.h | 246 ++++++++++++++++++++++++++++++++++++++++++++++ chan_capi_rtp.c | 67 ++++++++----- chan_capi_utils.c | 10 +- create_config.sh | 12 +++ 7 files changed, 461 insertions(+), 121 deletions(-) create mode 100644 chan_capi_fmt.h diff --git a/chan_capi.c b/chan_capi.c index ac8300f..447eb53 100644 --- a/chan_capi.c +++ b/chan_capi.c @@ -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, ¶m, &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; } diff --git a/chan_capi.h b/chan_capi.h index 419acb8..66d1cb5 100644 --- a/chan_capi.h +++ b/chan_capi.h @@ -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 diff --git a/chan_capi_chat.c b/chan_capi_chat.c index c8832f6..5d76486 100644 --- a/chan_capi_chat.c +++ b/chan_capi_chat.c @@ -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); } } } diff --git a/chan_capi_fmt.h b/chan_capi_fmt.h new file mode 100644 index 0000000..b0f802d --- /dev/null +++ b/chan_capi_fmt.h @@ -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 /* } */ diff --git a/chan_capi_rtp.c b/chan_capi_rtp.c index 77efdc9..7470b01 100644 --- a/chan_capi_rtp.c +++ b/chan_capi_rtp.c @@ -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 } diff --git a/chan_capi_utils.c b/chan_capi_utils.c index 1299701..dcd41f1 100644 --- a/chan_capi_utils.c +++ b/chan_capi_utils.c @@ -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; } diff --git a/create_config.sh b/create_config.sh index 16b7a7d..6e6c39d 100755 --- a/create_config.sh +++ b/create_config.sh @@ -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