From e3cb5c02cfe94d0f7957c2a545fa1f621d595912 Mon Sep 17 00:00:00 2001 From: MelwareDE Date: Sun, 11 Sep 2005 08:39:29 +0000 Subject: [PATCH] Added BSD compatibility, thanks to Hans Petter Selasky. --- README | 8 +- capi.conf | 2 + chan_capi.c | 216 +++++++++++++++++++++++++++++++++----------------- chan_capi.h | 44 +++++----- chan_capi20.h | 119 +++++++++++++++++++++++++++ 5 files changed, 290 insertions(+), 99 deletions(-) create mode 100644 chan_capi20.h diff --git a/README b/README index e467a61..681b785 100644 --- a/README +++ b/README @@ -10,7 +10,7 @@ This program is free software and may be modified and distributed under the terms of the GNU Public License. There is _NO_ warranty for this! -Thanks go to the debuggers and bugfixers :) +Thanks go to the debuggers, bugfixers and contributors :) =========================================================================== Lele Forzani Florian Overkamp @@ -19,8 +19,9 @@ Jeff Noxon Petr Michalek Jan Stocker Frank Sautter, levigo group +Hans Petter Selasky -(...and all the others that i forgot..) :-) +(...and all the others that have been forgotten...) :-) This chan_capi version includes: ================================ @@ -57,8 +58,9 @@ This chan_capi version includes: - Updated to support the new frame->delivery field - Compiles with different Asterisk versions (automatic build configuration) - receive faxes over CAPI (see below) -- Fixes for BSD (Jan Stocker) +- Fixes and compatibility for BSD (Jan Stocker and Hans Petter Selasky) - Support 'type of number'. +- ISDN hold. The Dial string =============== diff --git a/capi.conf b/capi.conf index cf4cbeb..6bf9fdd 100644 --- a/capi.conf +++ b/capi.conf @@ -20,6 +20,8 @@ txgain=0.8 isdnmode=msn ;'MSN' (point-to-multipoint) or 'DID' (direct inward dial) ;when using NT-mode, ptp should be set in any case incomingmsn=* ;allow incoming calls to this list of MSNs/DIDs, * == any +;controller=0 ;ISDN4BSD default +;controller=7 ;ISDN4BSD USB default controller=1 ;capi controller number to use group=1 ;dialout group ;prefix=0 ;set a prefix to calling number on incoming calls diff --git a/chan_capi.c b/chan_capi.c index 0278cae..8808f5c 100644 --- a/chan_capi.c +++ b/chan_capi.c @@ -43,12 +43,9 @@ #include #include #include -#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined( __NetBSD__ ) || defined(__APPLE__) -#include -#endif -#include #include #include "xlaw.h" +#include "chan_capi20.h" #include "chan_capi.h" /* #define CC_VERSION "cm-x.y.z" */ @@ -87,7 +84,7 @@ AST_MUTEX_DEFINE_STATIC(verbose_lock); static int capi_capability = AST_FORMAT_ALAW; -static pthread_t monitor_thread = -1; +static pthread_t monitor_thread = (pthread_t)(0-1); static struct ast_capi_pvt *iflist = NULL; static struct ast_capi_controller *capi_controllers[AST_CAPI_MAX_CONTROLLERS + 1]; @@ -171,7 +168,7 @@ static MESSAGE_EXCHANGE_ERROR _capi_put_cmsg(_cmsg *CMSG) if (error) { ast_log(LOG_ERROR, "CAPI error sending %s (NCCI=%#x) (error=%#x)\n", - capi_cmsg2str(CMSG), (unsigned int)CMSG->adr.adrNCCI, error); + capi_cmsg2str(CMSG), (unsigned int)HEADER_CID(CMSG), error); } else { if (CMSG->Command == CAPI_DATA_B3) { cc_ast_verbose(7, 1, "%s\n", capi_cmsg2str(CMSG)); @@ -204,6 +201,16 @@ static MESSAGE_EXCHANGE_ERROR check_wait_get_cmsg(_cmsg *CMSG) if (Info == 0x0000) { Info = capi_get_cmsg(CMSG, ast_capi_ApplID); + + /* There is no reason not to + * allow controller 0 ! + * + * For BSD hide problem from "chan_capi": + */ + if((HEADER_CID(CMSG) & 0xFF) == 0) + { + HEADER_CID(CMSG) += capi_num_controllers; + } } return Info; } @@ -239,12 +246,12 @@ static struct { unsigned short tcap; unsigned short cip; } translate_tcap2cip[] = { - { PRI_TRANS_CAP_SPEECH, CAPI_CIP_SPEECH }, - { PRI_TRANS_CAP_DIGITAL, CAPI_CIP_DIGITAL }, - { PRI_TRANS_CAP_RESTRICTED_DIGITAL, CAPI_CIP_RESTRICTED_DIGITAL }, - { PRI_TRANS_CAP_3K1AUDIO, CAPI_CIP_3K1AUDIO }, - { PRI_TRANS_CAP_DIGITAL_W_TONES, CAPI_CIP_DIGITAL_W_TONES }, - { PRI_TRANS_CAP_VIDEO, CAPI_CIP_VIDEO } + { PRI_TRANS_CAP_SPEECH, CAPI_CIPI_SPEECH }, + { PRI_TRANS_CAP_DIGITAL, CAPI_CIPI_DIGITAL }, + { PRI_TRANS_CAP_RESTRICTED_DIGITAL, CAPI_CIPI_RESTRICTED_DIGITAL }, + { PRI_TRANS_CAP_3K1AUDIO, CAPI_CIPI_3K1AUDIO }, + { PRI_TRANS_CAP_DIGITAL_W_TONES, CAPI_CIPI_DIGITAL_W_TONES }, + { PRI_TRANS_CAP_VIDEO, CAPI_CIPI_VIDEO } }; static int tcap2cip(unsigned short tcap) @@ -265,28 +272,28 @@ static struct { unsigned short cip; unsigned short tcap; } translate_cip2tcap[] = { - { CAPI_CIP_SPEECH, PRI_TRANS_CAP_SPEECH }, - { CAPI_CIP_DIGITAL, PRI_TRANS_CAP_DIGITAL }, - { CAPI_CIP_RESTRICTED_DIGITAL, PRI_TRANS_CAP_RESTRICTED_DIGITAL }, - { CAPI_CIP_3K1AUDIO, PRI_TRANS_CAP_3K1AUDIO }, - { CAPI_CIP_7KAUDIO, PRI_TRANS_CAP_DIGITAL_W_TONES }, - { CAPI_CIP_VIDEO, PRI_TRANS_CAP_VIDEO }, - { CAPI_CIP_PACKET_MODE, PRI_TRANS_CAP_DIGITAL }, - { CAPI_CIP_56KBIT_RATE_ADAPTION, PRI_TRANS_CAP_DIGITAL }, - { CAPI_CIP_DIGITAL_W_TONES, PRI_TRANS_CAP_DIGITAL_W_TONES }, - { CAPI_CIP_TELEPHONY, PRI_TRANS_CAP_SPEECH }, - { CAPI_CIP_FAX_G2_3, PRI_TRANS_CAP_3K1AUDIO }, - { CAPI_CIP_FAX_G4C1, PRI_TRANS_CAP_DIGITAL }, - { CAPI_CIP_FAX_G4C2_3, PRI_TRANS_CAP_DIGITAL }, - { CAPI_CIP_TELETEX_PROCESSABLE, PRI_TRANS_CAP_DIGITAL }, - { CAPI_CIP_TELETEX_BASIC, PRI_TRANS_CAP_DIGITAL }, - { CAPI_CIP_VIDEOTEX, PRI_TRANS_CAP_DIGITAL }, - { CAPI_CIP_TELEX, PRI_TRANS_CAP_DIGITAL }, - { CAPI_CIP_X400, PRI_TRANS_CAP_DIGITAL }, - { CAPI_CIP_X200, PRI_TRANS_CAP_DIGITAL }, - { CAPI_CIP_7K_TELEPHONY, PRI_TRANS_CAP_DIGITAL_W_TONES }, - { CAPI_CIP_VIDEO_TELEPHONY_C1, PRI_TRANS_CAP_DIGITAL_W_TONES }, - { CAPI_CIP_VIDEO_TELEPHONY_C2, PRI_TRANS_CAP_DIGITAL } + { CAPI_CIPI_SPEECH, PRI_TRANS_CAP_SPEECH }, + { CAPI_CIPI_DIGITAL, PRI_TRANS_CAP_DIGITAL }, + { CAPI_CIPI_RESTRICTED_DIGITAL, PRI_TRANS_CAP_RESTRICTED_DIGITAL }, + { CAPI_CIPI_3K1AUDIO, PRI_TRANS_CAP_3K1AUDIO }, + { CAPI_CIPI_7KAUDIO, PRI_TRANS_CAP_DIGITAL_W_TONES }, + { CAPI_CIPI_VIDEO, PRI_TRANS_CAP_VIDEO }, + { CAPI_CIPI_PACKET_MODE, PRI_TRANS_CAP_DIGITAL }, + { CAPI_CIPI_56KBIT_RATE_ADAPTION, PRI_TRANS_CAP_DIGITAL }, + { CAPI_CIPI_DIGITAL_W_TONES, PRI_TRANS_CAP_DIGITAL_W_TONES }, + { CAPI_CIPI_TELEPHONY, PRI_TRANS_CAP_SPEECH }, + { CAPI_CIPI_FAX_G2_3, PRI_TRANS_CAP_3K1AUDIO }, + { CAPI_CIPI_FAX_G4C1, PRI_TRANS_CAP_DIGITAL }, + { CAPI_CIPI_FAX_G4C2_3, PRI_TRANS_CAP_DIGITAL }, + { CAPI_CIPI_TELETEX_PROCESSABLE, PRI_TRANS_CAP_DIGITAL }, + { CAPI_CIPI_TELETEX_BASIC, PRI_TRANS_CAP_DIGITAL }, + { CAPI_CIPI_VIDEOTEX, PRI_TRANS_CAP_DIGITAL }, + { CAPI_CIPI_TELEX, PRI_TRANS_CAP_DIGITAL }, + { CAPI_CIPI_X400, PRI_TRANS_CAP_DIGITAL }, + { CAPI_CIPI_X200, PRI_TRANS_CAP_DIGITAL }, + { CAPI_CIPI_7K_TELEPHONY, PRI_TRANS_CAP_DIGITAL_W_TONES }, + { CAPI_CIPI_VIDEO_TELEPHONY_C1, PRI_TRANS_CAP_DIGITAL_W_TONES }, + { CAPI_CIPI_VIDEO_TELEPHONY_C2, PRI_TRANS_CAP_DIGITAL } }; static unsigned short cip2tcap(int cip) @@ -737,7 +744,8 @@ static char *capi_number_func(unsigned char *data, unsigned int strip, char *buf return buf; } -#define capi_number(data, strip) capi_number_func(data, strip, alloca(AST_MAX_EXTENSION)) +#define capi_number(data, strip) \ + capi_number_func(data, strip, alloca(AST_MAX_EXTENSION)) /* * parse the dialstring @@ -1586,7 +1594,7 @@ static void capi_handle_dtmf_fax(struct ast_channel *ast) static struct ast_capi_pvt *find_interface(_cmsg *CMSG) { struct ast_capi_pvt *i; - unsigned int NCCI = CMSG->adr.adrNCCI; + unsigned int NCCI = HEADER_CID(CMSG); unsigned int PLCI = (NCCI & 0xffff); int MN = CMSG->Messagenumber; @@ -2202,7 +2210,7 @@ static void capi_handle_facility_indication(_cmsg *CMSG, unsigned int PLCI, unsi FACILITY_RESP_HEADER(&CMSG2, ast_capi_ApplID, CMSG->Messagenumber, PLCI); FACILITY_RESP_FACILITYSELECTOR(&CMSG2) = FACILITY_IND_FACILITYSELECTOR(CMSG); - CMSG2.FacilityResponseParameters = FACILITY_IND_FACILITYINDICATIONPARAMETER(CMSG); + FACILITY_RESP_FACILITYRESPONSEPARAMETERS(&CMSG2) = FACILITY_IND_FACILITYINDICATIONPARAMETER(CMSG); _capi_put_cmsg(&CMSG2); return_on_no_interface("FACILITY_IND"); @@ -2991,20 +2999,26 @@ static void capi_handle_facility_confirmation(_cmsg *CMSG, unsigned int PLCI, un /* * show error in confirmation */ -static void show_capi_conf_error(char *msg, struct ast_capi_pvt *i, unsigned int PLCI, _cmsg *CMSG) +static void show_capi_conf_error(char *msg, struct ast_capi_pvt *i, + unsigned int PLCI, u_int16_t wInfo, + u_int16_t wCmd) { const char *name = channeltype; if (i) name = i->name; - if (CMSG->Info == 0x2002) { - cc_ast_verbose(1, 1, VERBOSE_PREFIX_3 "%s: %s_CONF 0x%x (wrong state) PLCI=0x%x Command.Subcommand = %#x.%#x\n", - name, msg, CMSG->Info, PLCI, CMSG->Command, CMSG->Subcommand); + if (wInfo == 0x2002) { + cc_ast_verbose(1, 1, VERBOSE_PREFIX_3 "%s: %s_CONF " + "0x%x (wrong state) PLCI=0x%x " + "Command = 0x%04x\n", + name, msg, wInfo, PLCI, wCmd); } else { - ast_log(LOG_WARNING, "%s: %s conf_error 0x%x PLCI=0x%x Command.Subcommand = %#x.%#x\n", - name, msg, CMSG->Info, PLCI, CMSG->Command, CMSG->Subcommand); + ast_log(LOG_WARNING, "%s: %s conf_error 0x%04x " + "PLCI=0x%x Command = 0x%04x\n", + name, msg, wInfo, PLCI, wCmd); } + return; } /* @@ -3013,6 +3027,7 @@ static void show_capi_conf_error(char *msg, struct ast_capi_pvt *i, unsigned int static void capi_handle_confirmation(_cmsg *CMSG, unsigned int PLCI, unsigned int NCCI) { struct ast_capi_pvt *i; + u_int16_t wInfo = 0; i = find_interface(CMSG); @@ -3025,7 +3040,8 @@ static void capi_handle_confirmation(_cmsg *CMSG, unsigned int PLCI, unsigned in break; cc_ast_verbose(1, 1, VERBOSE_PREFIX_3 "%s: received CONNECT_CONF PLCI = %#x\n", i->name, PLCI); - if (CONNECT_CONF_INFO(CMSG) == 0) { + wInfo = CONNECT_CONF_INFO(CMSG); + if (wInfo == 0) { i->PLCI = PLCI; } else { /* here, something has to be done --> */ @@ -3037,7 +3053,8 @@ static void capi_handle_confirmation(_cmsg *CMSG, unsigned int PLCI, unsigned in } break; case CAPI_CONNECT_B3: - if (CONNECT_B3_CONF_INFO(CMSG) == 0) { + wInfo = CONNECT_B3_CONF_INFO(CMSG); + if (wInfo == 0) { i->NCCI = NCCI; } else { i->earlyB3 = -1; @@ -3047,10 +3064,13 @@ static void capi_handle_confirmation(_cmsg *CMSG, unsigned int PLCI, unsigned in case CAPI_ALERT: if (!i->owner) break; - if ((ALERT_CONF_INFO(CMSG) & 0xff00) == 0) { - if (ALERT_CONF_INFO(CMSG) == 0x0003) { - cc_ast_verbose(3, 1, VERBOSE_PREFIX_3 "%s: Alert already sent by another app.\n", - i->name); + wInfo = ALERT_CONF_INFO(CMSG); + if ((wInfo & 0xff00) == 0) { + if (wInfo == 0x0003) { + cc_ast_verbose(3, 1, VERBOSE_PREFIX_3 + "%s: Alert already sent by " + "another app.\n", + i->name); } if (i->state != CAPI_STATE_DISCONNECTING) { i->state = CAPI_STATE_ALERTING; @@ -3059,12 +3079,15 @@ static void capi_handle_confirmation(_cmsg *CMSG, unsigned int PLCI, unsigned in } } } else { - show_capi_conf_error("ALERT", i, PLCI, CMSG); + show_capi_conf_error("ALERT", i, PLCI, wInfo, + HEADER_CMD(CMSG)); } break; case CAPI_SELECT_B_PROTOCOL: - if (CMSG->Info) { - show_capi_conf_error("SELECT_B_PROTOCOL", i, PLCI, CMSG); + wInfo = SELECT_B_PROTOCOL_CONF_INFO(CMSG); + if (wInfo) { + show_capi_conf_error("SELECT_B_PROTOCOL", i, PLCI, + wInfo, HEADER_CMD(CMSG)); } else { if ((i->owner) && (i->FaxState)) { capi_echo_canceller(i->owner, EC_FUNCTION_DISABLE); @@ -3073,22 +3096,41 @@ static void capi_handle_confirmation(_cmsg *CMSG, unsigned int PLCI, unsigned in } break; case CAPI_DATA_B3: - if (CMSG->Info) { - show_capi_conf_error("DATA_B3", i, PLCI, CMSG); + wInfo = DATA_B3_CONF_INFO(CMSG); + if (wInfo) { + show_capi_conf_error("DATA_B3", i, PLCI, + wInfo, HEADER_CMD(CMSG)); } break; - case CAPI_DISCONNECT: + + case CAPI_DISCONNECT: + wInfo = DISCONNECT_CONF_INFO(CMSG); + goto conf_error; + case CAPI_DISCONNECT_B3: + wInfo = DISCONNECT_B3_CONF_INFO(CMSG); + goto conf_error; + case CAPI_LISTEN: - case CAPI_INFO: - if (CMSG->Info) { - show_capi_conf_error("", i, PLCI, CMSG); + wInfo = LISTEN_CONF_INFO(CMSG); + goto conf_error; + + case CAPI_INFO: + wInfo = INFO_CONF_INFO(CMSG); + + conf_error: + + if (wInfo) { + show_capi_conf_error("", i, PLCI, wInfo, + HEADER_CMD(CMSG)); } break; default: - ast_log(LOG_ERROR,"CAPI: Command.Subcommand = %#x.%#x\n", - CMSG->Command, CMSG->Subcommand); + ast_log(LOG_ERROR,"CAPI: Command = 0x%04x\n", + HEADER_CMD(CMSG)); } + show_capi_info(wInfo); + return; } /* @@ -3096,7 +3138,7 @@ static void capi_handle_confirmation(_cmsg *CMSG, unsigned int PLCI, unsigned in */ static void capi_handle_msg(_cmsg *CMSG) { - unsigned int NCCI = CMSG->adr.adrNCCI; + unsigned int NCCI = HEADER_CID(CMSG); unsigned int PLCI = (NCCI & 0xffff); if ((CMSG->Subcommand != CAPI_IND) && @@ -3118,9 +3160,9 @@ static void capi_handle_msg(_cmsg *CMSG) break; case CAPI_CONF: capi_handle_confirmation(CMSG, PLCI, NCCI); - show_capi_info(CMSG->Info); break; } + return; } /* @@ -3813,11 +3855,32 @@ int mkif(struct ast_capi_conf *conf) strncpy(buffer, conf->controllerstr, sizeof(buffer) - 1); contr = strtok_r(buffer, ",", &buffer_rp); while (contr != NULL) { - contrmap |= (1 << atoi(contr)); - if (capi_controllers[atoi(contr)]) { - capi_controllers[atoi(contr)]->isdnmode = conf->isdnmode; + u_int16_t unit = atoi(contr); + + /* There is no reason not to + * allow controller 0 ! + * + * Hide problem from user: + */ + if (unit == 0) { + /* The ISDN4BSD kernel will modulo + * the controller number by + * "capi_num_controllers", so this + * is equivalent to "0": + */ + unit = capi_num_controllers; + } + + /* always range check user input */ + + if (unit >= AST_CAPI_MAX_CONTROLLERS) + unit = AST_CAPI_MAX_CONTROLLERS - 1; + + contrmap |= (1 << unit); + if (capi_controllers[unit]) { + capi_controllers[unit]->isdnmode = conf->isdnmode; /* ast_log(LOG_NOTICE, "contr %d isdnmode %d\n", - atoi(contr), isdnmode); */ + unit, isdnmode); */ } contr = strtok_r(NULL, ",", &buffer_rp); } @@ -4059,7 +4122,7 @@ static const struct ast_channel_tech capi_tech = { */ static int cc_init_capi(void) { -#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined( __NetBSD__ ) || defined(__APPLE__) +#if (CAPI_OS_HINT == 1) CAPIProfileBuffer_t profile; #else struct ast_capi_profile profile; @@ -4079,8 +4142,10 @@ static int cc_init_capi(void) return -1; } -#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined( __NetBSD__ ) || defined(__APPLE__) +#if (CAPI_OS_HINT == 1) if (capi20_get_profile(0, &profile) != 0) { +#elif (CAPI_OS_HINT == 2) + if (capi20_get_profile(0, &profile, sizeof(profile)) != 0) { #else if (capi20_get_profile(0, (char *)&profile) != 0) { #endif @@ -4088,7 +4153,7 @@ static int cc_init_capi(void) return -1; } -#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined( __NetBSD__ ) || defined(__APPLE__) +#if (CAPI_OS_HINT == 1) capi_num_controllers = profile.wCtlr; #else capi_num_controllers = profile.ncontrollers; @@ -4100,8 +4165,10 @@ static int cc_init_capi(void) for (controller = 1 ;controller <= capi_num_controllers; controller++) { memset(&profile, 0, sizeof(profile)); -#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined( __NetBSD__ ) || defined(__APPLE__) +#if (CAPI_OS_HINT == 1) capi20_get_profile(controller, &profile); +#elif (CAPI_OS_HINT == 2) + capi20_get_profile(controller, &profile, sizeof(profile)); #else capi20_get_profile(controller, (char *)&profile); #endif @@ -4112,7 +4179,7 @@ static int cc_init_capi(void) } memset(cp, 0, sizeof(struct ast_capi_controller)); cp->controller = controller; -#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined( __NetBSD__ ) || defined(__APPLE__) +#if (CAPI_OS_HINT == 1) cp->nbchannels = profile.wNumBChannels; cp->nfreebchannels = profile.wNumBChannels; if (profile.dwGlobalOptions & CAPI_PROFILE_DTMF_SUPPORT) { @@ -4126,7 +4193,7 @@ static int cc_init_capi(void) cp->dtmf = 1; } -#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined( __NetBSD__ ) || defined(__APPLE__) +#if (CAPI_OS_HINT == 1) if (profile.dwGlobalOptions & CAPI_PROFILE_ECHO_CANCELLATION) { #else if (profile.globaloptions2 & 1) { @@ -4136,7 +4203,7 @@ static int cc_init_capi(void) cp->echocancel = 1; } -#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined( __NetBSD__ ) || defined(__APPLE__) +#if (CAPI_OS_HINT == 1) if (profile.dwGlobalOptions & CAPI_PROFILE_SUPPLEMENTARY_SERVICES) { #else if ((profile.globaloptions & 16) >> 4 == 1) { @@ -4437,6 +4504,7 @@ int load_module(void) ast_register_application(commandapp, capicommand_exec, commandsynopsis, commandtdesc); if (ast_pthread_create(&monitor_thread, NULL, do_monitor, NULL) < 0) { + monitor_thread = (pthread_t)(0-1); ast_log(LOG_ERROR, "Unable to start monitor thread!\n"); return -1; } @@ -4460,7 +4528,7 @@ int unload_module() ast_rtp_proto_unregister(&capi_rtp); - if (monitor_thread != -1) { + if (monitor_thread != (pthread_t)(0-1)) { pthread_cancel(monitor_thread); pthread_kill(monitor_thread, SIGURG); pthread_join(monitor_thread, NULL); diff --git a/chan_capi.h b/chan_capi.h index 643eb9b..a031390 100644 --- a/chan_capi.h +++ b/chan_capi.h @@ -383,28 +383,28 @@ struct ast_capi_controller { #define CAPI_ETSI_NPLAN_INTERNAT 0x10 /* Common ISDN Profiles (CIP) */ -#define CAPI_CIP_SPEECH 0x01 -#define CAPI_CIP_DIGITAL 0x02 -#define CAPI_CIP_RESTRICTED_DIGITAL 0x03 -#define CAPI_CIP_3K1AUDIO 0x04 -#define CAPI_CIP_7KAUDIO 0x05 -#define CAPI_CIP_VIDEO 0x06 -#define CAPI_CIP_PACKET_MODE 0x07 -#define CAPI_CIP_56KBIT_RATE_ADAPTION 0x08 -#define CAPI_CIP_DIGITAL_W_TONES 0x09 -#define CAPI_CIP_TELEPHONY 0x10 -#define CAPI_CIP_FAX_G2_3 0x11 -#define CAPI_CIP_FAX_G4C1 0x12 -#define CAPI_CIP_FAX_G4C2_3 0x13 -#define CAPI_CIP_TELETEX_PROCESSABLE 0x14 -#define CAPI_CIP_TELETEX_BASIC 0x15 -#define CAPI_CIP_VIDEOTEX 0x16 -#define CAPI_CIP_TELEX 0x17 -#define CAPI_CIP_X400 0x18 -#define CAPI_CIP_X200 0x19 -#define CAPI_CIP_7K_TELEPHONY 0x1a -#define CAPI_CIP_VIDEO_TELEPHONY_C1 0x1b -#define CAPI_CIP_VIDEO_TELEPHONY_C2 0x1c +#define CAPI_CIPI_SPEECH 0x01 +#define CAPI_CIPI_DIGITAL 0x02 +#define CAPI_CIPI_RESTRICTED_DIGITAL 0x03 +#define CAPI_CIPI_3K1AUDIO 0x04 +#define CAPI_CIPI_7KAUDIO 0x05 +#define CAPI_CIPI_VIDEO 0x06 +#define CAPI_CIPI_PACKET_MODE 0x07 +#define CAPI_CIPI_56KBIT_RATE_ADAPTION 0x08 +#define CAPI_CIPI_DIGITAL_W_TONES 0x09 +#define CAPI_CIPI_TELEPHONY 0x10 +#define CAPI_CIPI_FAX_G2_3 0x11 +#define CAPI_CIPI_FAX_G4C1 0x12 +#define CAPI_CIPI_FAX_G4C2_3 0x13 +#define CAPI_CIPI_TELETEX_PROCESSABLE 0x14 +#define CAPI_CIPI_TELETEX_BASIC 0x15 +#define CAPI_CIPI_VIDEOTEX 0x16 +#define CAPI_CIPI_TELEX 0x17 +#define CAPI_CIPI_X400 0x18 +#define CAPI_CIPI_X200 0x19 +#define CAPI_CIPI_7K_TELEPHONY 0x1a +#define CAPI_CIPI_VIDEO_TELEPHONY_C1 0x1b +#define CAPI_CIPI_VIDEO_TELEPHONY_C2 0x1c /* Transfer capabilities */ #define PRI_TRANS_CAP_SPEECH 0x00 diff --git a/chan_capi20.h b/chan_capi20.h new file mode 100644 index 0000000..a3d5967 --- /dev/null +++ b/chan_capi20.h @@ -0,0 +1,119 @@ +/* + * This header file is common to all CAPI 2.0 + * implementations, and must be included first. + * Else the checks below will fail. + */ + +#include + +#undef CAPI_OS_HINT + +#if (defined(__FreeBSD__) || defined(__OpenBSD__) || \ + defined(__NetBSD__) || defined(__APPLE__)) + +#if (CAPI_STACK_VERSION < 204) +/* + * This looks like CAPI 2.0 for active ISDN cards, + * CAPI4BSD, and not CAPI for passive ISDN cards, + * ISDN4BSD! + */ +#include +#define CAPI_OS_HINT 1 +#else /* (CAPI_STACK_VERSION < 204) */ +#define CAPI_OS_HINT 2 +#endif /* (CAPI_STACK_VERSION < 204) */ + +#else /* BSD */ +#include +#endif /* BSD */ + +#ifndef HEADER_CID +#define HEADER_CID(x) ((x)->adr.adrNCCI) +#endif + +#ifndef HEADER_CMD + +/* + * The following macros have their + * origin in ISDN4BSD 1.5.5+ + */ + +enum +{ + CAPI_PACKED = 0x84 /* non-standard */ +}; + +/* + * Table is sorted by highest usage first: + */ + +#define CAPI_COMMANDS(m,n) \ +/*m(n, enum , value )* \ + *m(n,------------------------------,-------)*/ \ + m(n, DATA_B3 , 0x0086) \ + m(n, CONNECT , 0x0002) \ + m(n, CONNECT_ACTIVE , 0x0003) \ + m(n, CONNECT_B3 , 0x0082) \ + m(n, CONNECT_B3_ACTIVE , 0x0083) \ + m(n, CONNECT_B3_T90_ACTIVE , 0x0088) \ + m(n, DISCONNECT , 0x0004) \ + m(n, DISCONNECT_B3 , 0x0084) \ + m(n, ALERT , 0x0001) \ + m(n, INFO , 0x0008) \ + m(n, SELECT_B_PROTOCOL , 0x0041) \ + m(n, FACILITY , 0x0080) \ + m(n, RESET_B3 , 0x0087) \ + m(n, MANUFACTURER , 0x00FF) \ + m(n, LISTEN , 0x0005) \ + +/* packed version */ +#define CAPI_P_REQ(cmd) ((CAPI_##cmd##_INDEX << 1)^(CAPI_PACKED << 8)^0x7e) +#define CAPI_P_CONF(cmd) ((CAPI_##cmd##_INDEX << 1)^(CAPI_PACKED << 8)^0x81) +#define CAPI_P_IND(cmd) ((CAPI_##cmd##_INDEX << 1)^(CAPI_PACKED << 8)^0x80) +#define CAPI_P_RESP(cmd) ((CAPI_##cmd##_INDEX << 1)^(CAPI_PACKED << 8)^0x7f) + +#define CAPI_P_MIN (((CAPI_COMMAND_INDEX_MAX-1) << 1)^(CAPI_PACKED << 8)^0x7e) /* inclusive */ +#define CAPI_P_MAX ( (CAPI_COMMAND_INDEX_MAX << 1)^(CAPI_PACKED << 8)^0x80) /* exclusive */ + +#define CAPI_MAKE_DEF_2(n,ENUM,value) \ + CAPI_##ENUM##_INDEX, + +enum +{ + CAPI_COMMANDS(CAPI_MAKE_DEF_2,) + CAPI_COMMAND_INDEX_MAX /* exclusive */ +}; + +#define __CAPI_COMMAND_PACK(n, ENUM, value) \ + ((n) == (value)) ? ((CAPI_##ENUM##_INDEX) << 1) : + +/* this macro takes any command and outputs a + * packed CAPI command (which is better suited + * for switching) + * + * define this as a function so that the + * compiler does not expand it, hence + * it is pretty large + */ +#undef CAPI_COMMAND_PACK +static __inline u_int16_t CAPI_COMMAND_PACK(u_int16_t cmd) +{ + return + ((((cmd) >> 8) == CAPI_PACKED) ? (cmd) : + ((((cmd) >> 8) == CAPI_REQ) ? ((CAPI_PACKED << 8)^0x7e) : + (((cmd) >> 8) == CAPI_CONF) ? ((CAPI_PACKED << 8)^0x81) : + (((cmd) >> 8) == CAPI_IND) ? ((CAPI_PACKED << 8)^0x80) : + (((cmd) >> 8) == CAPI_RESP) ? ((CAPI_PACKED << 8)^0x7f) : + 0) ^ + (CAPI_COMMANDS(__CAPI_COMMAND_PACK, (cmd) & 0xFF) 0x7e)); +} + +#define HEADER_CMD(x) \ + CAPI_COMMAND_PACK((((x)->Subcommand) << 8)|(x)->Command) + +#endif /* HEADER_CMD */ + +#ifndef FACILITY_RESP_FACILITYRESPONSEPARAMETERS +#define FACILITY_RESP_FACILITYRESPONSEPARAMETERS(x) \ + ((x)->FacilityResponseParameters) +#endif