Moved more utilities into own files.
parent
76d0cae461
commit
cd18383e0e
279
chan_capi.c
279
chan_capi.c
|
@ -47,7 +47,6 @@
|
|||
#define CAPI_APPLID_UNUSED 0xffffffff
|
||||
unsigned capi_ApplID = CAPI_APPLID_UNUSED;
|
||||
|
||||
static _cword capi_MessageNumber;
|
||||
static const char tdesc[] = "Common ISDN API Driver (" CC_VERSION ")";
|
||||
static const char channeltype[] = "CAPI";
|
||||
static const struct ast_channel_tech capi_tech;
|
||||
|
@ -134,13 +133,10 @@ static int usecnt;
|
|||
* this lock!
|
||||
*/
|
||||
|
||||
AST_MUTEX_DEFINE_STATIC(messagenumber_lock);
|
||||
#ifndef CC_AST_HAS_VERSION_1_4
|
||||
AST_MUTEX_DEFINE_STATIC(usecnt_lock);
|
||||
#endif
|
||||
AST_MUTEX_DEFINE_STATIC(iflock);
|
||||
AST_MUTEX_DEFINE_STATIC(capi_put_lock);
|
||||
AST_MUTEX_DEFINE_STATIC(verbose_lock);
|
||||
|
||||
static int capi_capability = AST_FORMAT_ALAW;
|
||||
|
||||
|
@ -151,7 +147,6 @@ static struct cc_capi_controller *capi_controllers[CAPI_MAX_CONTROLLERS + 1];
|
|||
static int capi_num_controllers = 0;
|
||||
static unsigned int capi_counter = 0;
|
||||
static unsigned long capi_used_controllers = 0;
|
||||
static char *emptyid = "\0";
|
||||
|
||||
static struct ast_channel *chan_for_task;
|
||||
static int channel_task;
|
||||
|
@ -166,8 +161,6 @@ static char capi_international_prefix[AST_MAX_EXTENSION];
|
|||
|
||||
static char default_language[MAX_LANGUAGE] = "";
|
||||
|
||||
static int capidebug = 0;
|
||||
|
||||
#ifdef CC_AST_HAS_VERSION_1_4
|
||||
/* Global jitterbuffer configuration - by default, jb is disabled */
|
||||
static struct ast_jb_conf default_jbconf =
|
||||
|
@ -188,27 +181,6 @@ static int pbx_capi_indicate(struct ast_channel *c, int condition, const void *d
|
|||
static int pbx_capi_indicate(struct ast_channel *c, int condition);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* helper for <pbx>_verbose with different verbose settings
|
||||
*/
|
||||
void cc_verbose(int o_v, int c_d, char *text, ...)
|
||||
{
|
||||
char line[4096];
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, text);
|
||||
vsnprintf(line, sizeof(line), text, ap);
|
||||
va_end(ap);
|
||||
|
||||
if ((o_v == 0) || (option_verbose > o_v)) {
|
||||
if ((!c_d) || ((c_d) && (capidebug))) {
|
||||
cc_mutex_lock(&verbose_lock);
|
||||
cc_pbx_verbose(line);
|
||||
cc_mutex_unlock(&verbose_lock);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* B protocol settings
|
||||
*/
|
||||
|
@ -299,64 +271,6 @@ static const char * capi_command_to_string(unsigned short wCmd)
|
|||
return "UNDEFINED";
|
||||
}
|
||||
|
||||
/*
|
||||
* get a new capi message number automically
|
||||
*/
|
||||
_cword get_capi_MessageNumber(void)
|
||||
{
|
||||
_cword mn;
|
||||
|
||||
cc_mutex_lock(&messagenumber_lock);
|
||||
|
||||
capi_MessageNumber++;
|
||||
if (capi_MessageNumber == 0) {
|
||||
/* avoid zero */
|
||||
capi_MessageNumber = 1;
|
||||
}
|
||||
|
||||
mn = capi_MessageNumber;
|
||||
|
||||
cc_mutex_unlock(&messagenumber_lock);
|
||||
|
||||
return(mn);
|
||||
}
|
||||
|
||||
/*
|
||||
* write a capi message to capi device
|
||||
*/
|
||||
MESSAGE_EXCHANGE_ERROR _capi_put_cmsg(_cmsg *CMSG)
|
||||
{
|
||||
MESSAGE_EXCHANGE_ERROR error;
|
||||
|
||||
if (cc_mutex_lock(&capi_put_lock)) {
|
||||
cc_log(LOG_WARNING, "Unable to lock capi put!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
error = capi20_put_cmsg(CMSG);
|
||||
|
||||
if (cc_mutex_unlock(&capi_put_lock)) {
|
||||
cc_log(LOG_WARNING, "Unable to unlock capi put!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (error) {
|
||||
cc_log(LOG_ERROR, "CAPI error sending %s (NCCI=%#x) (error=%#x %s)\n",
|
||||
capi_cmsg2str(CMSG), (unsigned int)HEADER_CID(CMSG),
|
||||
error, capi_info_string((unsigned int)error));
|
||||
} else {
|
||||
unsigned short wCmd = HEADER_CMD(CMSG);
|
||||
if ((wCmd == CAPI_P_REQ(DATA_B3)) ||
|
||||
(wCmd == CAPI_P_RESP(DATA_B3))) {
|
||||
cc_verbose(7, 1, "%s\n", capi_cmsg2str(CMSG));
|
||||
} else {
|
||||
cc_verbose(4, 1, "%s\n", capi_cmsg2str(CMSG));
|
||||
}
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
/*
|
||||
* wait for a specific message
|
||||
*/
|
||||
|
@ -465,123 +379,6 @@ static int capi_tell_fax_finish(void *data)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* wait some time for a new capi message
|
||||
*/
|
||||
static MESSAGE_EXCHANGE_ERROR capidev_check_wait_get_cmsg(_cmsg *CMSG)
|
||||
{
|
||||
MESSAGE_EXCHANGE_ERROR Info;
|
||||
struct timeval tv;
|
||||
|
||||
repeat:
|
||||
Info = capi_get_cmsg(CMSG, capi_ApplID);
|
||||
|
||||
#if (CAPI_OS_HINT == 1) || (CAPI_OS_HINT == 2)
|
||||
/*
|
||||
* For BSD allow controller 0:
|
||||
*/
|
||||
if ((HEADER_CID(CMSG) & 0xFF) == 0) {
|
||||
HEADER_CID(CMSG) += capi_num_controllers;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* if queue is empty */
|
||||
if (Info == 0x1104) {
|
||||
/* try waiting a maximum of 0.100 seconds for a message */
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 10000;
|
||||
|
||||
Info = capi20_waitformessage(capi_ApplID, &tv);
|
||||
|
||||
if (Info == 0x0000)
|
||||
goto repeat;
|
||||
}
|
||||
|
||||
if ((Info != 0x0000) && (Info != 0x1104)) {
|
||||
if (capidebug) {
|
||||
cc_log(LOG_DEBUG, "Error waiting for cmsg... INFO = %#x\n", Info);
|
||||
}
|
||||
}
|
||||
|
||||
return Info;
|
||||
}
|
||||
|
||||
/*
|
||||
* send Listen for supplementary to specified controller
|
||||
*/
|
||||
static void ListenOnSupplementary(unsigned controller)
|
||||
{
|
||||
_cmsg CMSG;
|
||||
char fac[8];
|
||||
MESSAGE_EXCHANGE_ERROR error;
|
||||
int waitcount = 50;
|
||||
|
||||
fac[0] = 7; /* len */
|
||||
fac[1] = 0x01; /* listen */
|
||||
fac[2] = 0x00;
|
||||
fac[3] = 4; /* len / sservice specific parameter , cstruct */
|
||||
write_capi_dword(&(fac[4]), 0x0000079f);
|
||||
|
||||
FACILITY_REQ_HEADER(&CMSG, capi_ApplID, get_capi_MessageNumber(), 0);
|
||||
FACILITY_REQ_CONTROLLER(&CMSG) = controller;
|
||||
FACILITY_REQ_FACILITYSELECTOR(&CMSG) = FACILITYSELECTOR_SUPPLEMENTARY;
|
||||
FACILITY_REQ_FACILITYREQUESTPARAMETER(&CMSG) = (_cstruct)&fac;
|
||||
|
||||
error = _capi_put_cmsg(&CMSG);
|
||||
|
||||
while (waitcount) {
|
||||
error = capidev_check_wait_get_cmsg(&CMSG);
|
||||
|
||||
if (IS_FACILITY_CONF(&CMSG)) {
|
||||
break;
|
||||
}
|
||||
usleep(30000);
|
||||
waitcount--;
|
||||
}
|
||||
if (!waitcount) {
|
||||
cc_log(LOG_ERROR,"Unable to supplementary-listen on contr%d (error=0x%x)\n",
|
||||
controller, error);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* send Listen to specified controller
|
||||
*/
|
||||
static unsigned ListenOnController(unsigned long CIPmask, unsigned controller)
|
||||
{
|
||||
MESSAGE_EXCHANGE_ERROR error;
|
||||
_cmsg CMSG;
|
||||
int waitcount = 50;
|
||||
|
||||
LISTEN_REQ_HEADER(&CMSG, capi_ApplID, get_capi_MessageNumber(), controller);
|
||||
|
||||
LISTEN_REQ_INFOMASK(&CMSG) = 0xffff; /* lots of info ;) + early B3 connect */
|
||||
/* 0x00ff if no early B3 should be done */
|
||||
|
||||
LISTEN_REQ_CIPMASK(&CMSG) = CIPmask;
|
||||
error = _capi_put_cmsg(&CMSG);
|
||||
|
||||
if (error)
|
||||
goto done;
|
||||
|
||||
while (waitcount) {
|
||||
error = capidev_check_wait_get_cmsg(&CMSG);
|
||||
|
||||
if (IS_LISTEN_CONF(&CMSG)) {
|
||||
error = LISTEN_CONF_INFO(&CMSG);
|
||||
ListenOnSupplementary(controller);
|
||||
break;
|
||||
}
|
||||
usleep(30000);
|
||||
waitcount--;
|
||||
}
|
||||
if (!waitcount)
|
||||
error = 0x100F;
|
||||
|
||||
done:
|
||||
return error;
|
||||
}
|
||||
|
||||
/*
|
||||
* TCAP -> CIP Translation Table (TransferCapability->CommonIsdnProfile)
|
||||
*/
|
||||
|
@ -1318,82 +1115,6 @@ static int pbx_capi_hangup(struct ast_channel *c)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* convert a number
|
||||
*/
|
||||
static char *capi_number_func(unsigned char *data, unsigned int strip, char *buf)
|
||||
{
|
||||
unsigned int len;
|
||||
|
||||
if (data[0] == 0xff) {
|
||||
len = read_capi_word(&data[1]);
|
||||
data += 2;
|
||||
} else {
|
||||
len = data[0];
|
||||
data += 1;
|
||||
}
|
||||
if (len > (AST_MAX_EXTENSION - 1))
|
||||
len = (AST_MAX_EXTENSION - 1);
|
||||
|
||||
/* convert a capi struct to a \0 terminated string */
|
||||
if ((!len) || (len < strip))
|
||||
return NULL;
|
||||
|
||||
len = len - strip;
|
||||
data += strip;
|
||||
|
||||
memcpy(buf, data, len);
|
||||
buf[len] = '\0';
|
||||
|
||||
return buf;
|
||||
}
|
||||
#define capi_number(data, strip) \
|
||||
capi_number_func(data, strip, alloca(AST_MAX_EXTENSION))
|
||||
|
||||
/*
|
||||
* parse the dialstring
|
||||
*/
|
||||
static void parse_dialstring(char *buffer, char **interface, char **dest, char **param, char **ocid)
|
||||
{
|
||||
int cp = 0;
|
||||
char *buffer_p = buffer;
|
||||
char *oc;
|
||||
|
||||
/* interface is the first part of the string */
|
||||
*interface = buffer;
|
||||
|
||||
*dest = emptyid;
|
||||
*param = emptyid;
|
||||
*ocid = NULL;
|
||||
|
||||
while (*buffer_p) {
|
||||
if (*buffer_p == '/') {
|
||||
*buffer_p = 0;
|
||||
buffer_p++;
|
||||
if (cp == 0) {
|
||||
*dest = buffer_p;
|
||||
cp++;
|
||||
} else if (cp == 1) {
|
||||
*param = buffer_p;
|
||||
cp++;
|
||||
} else {
|
||||
cc_log(LOG_WARNING, "Too many parts in dialstring '%s'\n",
|
||||
buffer);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
buffer_p++;
|
||||
}
|
||||
if ((oc = strchr(*dest, ':')) != NULL) {
|
||||
*ocid = *dest;
|
||||
*oc = '\0';
|
||||
*dest = oc + 1;
|
||||
}
|
||||
cc_verbose(3, 1, VERBOSE_PREFIX_4 "parsed dialstring: '%s' '%s' '%s' '%s'\n",
|
||||
*interface, (*ocid) ? *ocid : "NULL", *dest, *param);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* PBX tells us to make a call
|
||||
*/
|
||||
|
|
|
@ -558,9 +558,6 @@ struct cc_capi_controller {
|
|||
* prototypes
|
||||
*/
|
||||
extern unsigned capi_ApplID;
|
||||
extern MESSAGE_EXCHANGE_ERROR _capi_put_cmsg(_cmsg *CMSG);
|
||||
extern _cword get_capi_MessageNumber(void);
|
||||
extern void cc_verbose(int o_v, int c_d, char *text, ...);
|
||||
extern void cc_start_b3(struct capi_pvt *i);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include <asterisk/options.h>
|
||||
#include "chan_capi20.h"
|
||||
#include "chan_capi.h"
|
||||
#include "chan_capi_utils.h"
|
||||
#include "chan_capi_qsig.h"
|
||||
#include "chan_capi_qsig_asn197no.h"
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include <asterisk/pbx.h>
|
||||
#include "chan_capi20.h"
|
||||
#include "chan_capi.h"
|
||||
#include "chan_capi_utils.h"
|
||||
#include "chan_capi_qsig.h"
|
||||
#include "chan_capi_qsig_asn197ade.h"
|
||||
#include "chan_capi_qsig_asn197no.h"
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include <asterisk/pbx.h>
|
||||
#include "chan_capi20.h"
|
||||
#include "chan_capi.h"
|
||||
#include "chan_capi_utils.h"
|
||||
#include "chan_capi_qsig.h"
|
||||
#include "chan_capi_qsig_asn197ade.h"
|
||||
#include "chan_capi_qsig_asn197no.h"
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include "chan_capi20.h"
|
||||
#include "chan_capi.h"
|
||||
#include "chan_capi_rtp.h"
|
||||
#include "chan_capi_utils.h"
|
||||
|
||||
/* RTP settings / NCPI RTP struct */
|
||||
|
||||
|
|
|
@ -20,6 +20,45 @@
|
|||
#include "chan_capi_supplementary.h"
|
||||
#include "chan_capi_utils.h"
|
||||
|
||||
|
||||
/*
|
||||
* send Listen for supplementary to specified controller
|
||||
*/
|
||||
void ListenOnSupplementary(unsigned controller)
|
||||
{
|
||||
_cmsg CMSG;
|
||||
char fac[8];
|
||||
MESSAGE_EXCHANGE_ERROR error;
|
||||
int waitcount = 50;
|
||||
|
||||
fac[0] = 7; /* len */
|
||||
fac[1] = 0x01; /* listen */
|
||||
fac[2] = 0x00;
|
||||
fac[3] = 4; /* len / sservice specific parameter , cstruct */
|
||||
write_capi_dword(&(fac[4]), 0x0000079f);
|
||||
|
||||
FACILITY_REQ_HEADER(&CMSG, capi_ApplID, get_capi_MessageNumber(), 0);
|
||||
FACILITY_REQ_CONTROLLER(&CMSG) = controller;
|
||||
FACILITY_REQ_FACILITYSELECTOR(&CMSG) = FACILITYSELECTOR_SUPPLEMENTARY;
|
||||
FACILITY_REQ_FACILITYREQUESTPARAMETER(&CMSG) = (_cstruct)&fac;
|
||||
|
||||
error = _capi_put_cmsg(&CMSG);
|
||||
|
||||
while (waitcount) {
|
||||
error = capidev_check_wait_get_cmsg(&CMSG);
|
||||
|
||||
if (IS_FACILITY_CONF(&CMSG)) {
|
||||
break;
|
||||
}
|
||||
usleep(30000);
|
||||
waitcount--;
|
||||
}
|
||||
if (!waitcount) {
|
||||
cc_log(LOG_ERROR,"Unable to supplementary-listen on contr%d (error=0x%x)\n",
|
||||
controller, error);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* CAPI FACILITY_IND supplementary services
|
||||
*/
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
/*
|
||||
* prototypes
|
||||
*/
|
||||
extern void ListenOnSupplementary(unsigned controller);
|
||||
extern void handle_facility_indication_supplementary(_cmsg *CMSG, unsigned int PLCI, unsigned int NCCI, struct capi_pvt *i);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -15,6 +15,136 @@
|
|||
#include "chan_capi20.h"
|
||||
#include "chan_capi.h"
|
||||
#include "chan_capi_utils.h"
|
||||
#include "chan_capi_supplementary.h"
|
||||
|
||||
int capidebug = 0;
|
||||
char *emptyid = "\0";
|
||||
|
||||
AST_MUTEX_DEFINE_STATIC(verbose_lock);
|
||||
AST_MUTEX_DEFINE_STATIC(messagenumber_lock);
|
||||
AST_MUTEX_DEFINE_STATIC(capi_put_lock);
|
||||
|
||||
static _cword capi_MessageNumber;
|
||||
|
||||
/*
|
||||
* helper for <pbx>_verbose with different verbose settings
|
||||
*/
|
||||
void cc_verbose(int o_v, int c_d, char *text, ...)
|
||||
{
|
||||
char line[4096];
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, text);
|
||||
vsnprintf(line, sizeof(line), text, ap);
|
||||
va_end(ap);
|
||||
|
||||
if ((o_v == 0) || (option_verbose > o_v)) {
|
||||
if ((!c_d) || ((c_d) && (capidebug))) {
|
||||
cc_mutex_lock(&verbose_lock);
|
||||
cc_pbx_verbose(line);
|
||||
cc_mutex_unlock(&verbose_lock);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* get a new capi message number automically
|
||||
*/
|
||||
_cword get_capi_MessageNumber(void)
|
||||
{
|
||||
_cword mn;
|
||||
|
||||
cc_mutex_lock(&messagenumber_lock);
|
||||
|
||||
capi_MessageNumber++;
|
||||
if (capi_MessageNumber == 0) {
|
||||
/* avoid zero */
|
||||
capi_MessageNumber = 1;
|
||||
}
|
||||
|
||||
mn = capi_MessageNumber;
|
||||
|
||||
cc_mutex_unlock(&messagenumber_lock);
|
||||
|
||||
return(mn);
|
||||
}
|
||||
|
||||
/*
|
||||
* write a capi message to capi device
|
||||
*/
|
||||
MESSAGE_EXCHANGE_ERROR _capi_put_cmsg(_cmsg *CMSG)
|
||||
{
|
||||
MESSAGE_EXCHANGE_ERROR error;
|
||||
|
||||
if (cc_mutex_lock(&capi_put_lock)) {
|
||||
cc_log(LOG_WARNING, "Unable to lock capi put!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
error = capi20_put_cmsg(CMSG);
|
||||
|
||||
if (cc_mutex_unlock(&capi_put_lock)) {
|
||||
cc_log(LOG_WARNING, "Unable to unlock capi put!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (error) {
|
||||
cc_log(LOG_ERROR, "CAPI error sending %s (NCCI=%#x) (error=%#x %s)\n",
|
||||
capi_cmsg2str(CMSG), (unsigned int)HEADER_CID(CMSG),
|
||||
error, capi_info_string((unsigned int)error));
|
||||
} else {
|
||||
unsigned short wCmd = HEADER_CMD(CMSG);
|
||||
if ((wCmd == CAPI_P_REQ(DATA_B3)) ||
|
||||
(wCmd == CAPI_P_RESP(DATA_B3))) {
|
||||
cc_verbose(7, 1, "%s\n", capi_cmsg2str(CMSG));
|
||||
} else {
|
||||
cc_verbose(4, 1, "%s\n", capi_cmsg2str(CMSG));
|
||||
}
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
/*
|
||||
* wait some time for a new capi message
|
||||
*/
|
||||
MESSAGE_EXCHANGE_ERROR capidev_check_wait_get_cmsg(_cmsg *CMSG)
|
||||
{
|
||||
MESSAGE_EXCHANGE_ERROR Info;
|
||||
struct timeval tv;
|
||||
|
||||
repeat:
|
||||
Info = capi_get_cmsg(CMSG, capi_ApplID);
|
||||
|
||||
#if (CAPI_OS_HINT == 1) || (CAPI_OS_HINT == 2)
|
||||
/*
|
||||
* For BSD allow controller 0:
|
||||
*/
|
||||
if ((HEADER_CID(CMSG) & 0xFF) == 0) {
|
||||
HEADER_CID(CMSG) += capi_num_controllers;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* if queue is empty */
|
||||
if (Info == 0x1104) {
|
||||
/* try waiting a maximum of 0.100 seconds for a message */
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 10000;
|
||||
|
||||
Info = capi20_waitformessage(capi_ApplID, &tv);
|
||||
|
||||
if (Info == 0x0000)
|
||||
goto repeat;
|
||||
}
|
||||
|
||||
if ((Info != 0x0000) && (Info != 0x1104)) {
|
||||
if (capidebug) {
|
||||
cc_log(LOG_DEBUG, "Error waiting for cmsg... INFO = %#x\n", Info);
|
||||
}
|
||||
}
|
||||
|
||||
return Info;
|
||||
}
|
||||
|
||||
/*
|
||||
* decode capi 2.0 info word
|
||||
|
@ -375,3 +505,115 @@ void show_capi_info(struct capi_pvt *i, _cword info)
|
|||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* send Listen to specified controller
|
||||
*/
|
||||
unsigned ListenOnController(unsigned long CIPmask, unsigned controller)
|
||||
{
|
||||
MESSAGE_EXCHANGE_ERROR error;
|
||||
_cmsg CMSG;
|
||||
int waitcount = 50;
|
||||
|
||||
LISTEN_REQ_HEADER(&CMSG, capi_ApplID, get_capi_MessageNumber(), controller);
|
||||
|
||||
LISTEN_REQ_INFOMASK(&CMSG) = 0xffff; /* lots of info ;) + early B3 connect */
|
||||
/* 0x00ff if no early B3 should be done */
|
||||
|
||||
LISTEN_REQ_CIPMASK(&CMSG) = CIPmask;
|
||||
error = _capi_put_cmsg(&CMSG);
|
||||
|
||||
if (error)
|
||||
goto done;
|
||||
|
||||
while (waitcount) {
|
||||
error = capidev_check_wait_get_cmsg(&CMSG);
|
||||
|
||||
if (IS_LISTEN_CONF(&CMSG)) {
|
||||
error = LISTEN_CONF_INFO(&CMSG);
|
||||
ListenOnSupplementary(controller);
|
||||
break;
|
||||
}
|
||||
usleep(30000);
|
||||
waitcount--;
|
||||
}
|
||||
if (!waitcount)
|
||||
error = 0x100F;
|
||||
|
||||
done:
|
||||
return error;
|
||||
}
|
||||
|
||||
/*
|
||||
* convert a number
|
||||
*/
|
||||
char *capi_number_func(unsigned char *data, unsigned int strip, char *buf)
|
||||
{
|
||||
unsigned int len;
|
||||
|
||||
if (data[0] == 0xff) {
|
||||
len = read_capi_word(&data[1]);
|
||||
data += 2;
|
||||
} else {
|
||||
len = data[0];
|
||||
data += 1;
|
||||
}
|
||||
if (len > (AST_MAX_EXTENSION - 1))
|
||||
len = (AST_MAX_EXTENSION - 1);
|
||||
|
||||
/* convert a capi struct to a \0 terminated string */
|
||||
if ((!len) || (len < strip))
|
||||
return NULL;
|
||||
|
||||
len = len - strip;
|
||||
data += strip;
|
||||
|
||||
memcpy(buf, data, len);
|
||||
buf[len] = '\0';
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
/*
|
||||
* parse the dialstring
|
||||
*/
|
||||
void parse_dialstring(char *buffer, char **interface, char **dest, char **param, char **ocid)
|
||||
{
|
||||
int cp = 0;
|
||||
char *buffer_p = buffer;
|
||||
char *oc;
|
||||
|
||||
/* interface is the first part of the string */
|
||||
*interface = buffer;
|
||||
|
||||
*dest = emptyid;
|
||||
*param = emptyid;
|
||||
*ocid = NULL;
|
||||
|
||||
while (*buffer_p) {
|
||||
if (*buffer_p == '/') {
|
||||
*buffer_p = 0;
|
||||
buffer_p++;
|
||||
if (cp == 0) {
|
||||
*dest = buffer_p;
|
||||
cp++;
|
||||
} else if (cp == 1) {
|
||||
*param = buffer_p;
|
||||
cp++;
|
||||
} else {
|
||||
cc_log(LOG_WARNING, "Too many parts in dialstring '%s'\n",
|
||||
buffer);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
buffer_p++;
|
||||
}
|
||||
if ((oc = strchr(*dest, ':')) != NULL) {
|
||||
*ocid = *dest;
|
||||
*oc = '\0';
|
||||
*dest = oc + 1;
|
||||
}
|
||||
cc_verbose(3, 1, VERBOSE_PREFIX_4 "parsed dialstring: '%s' '%s' '%s' '%s'\n",
|
||||
*interface, (*ocid) ? *ocid : "NULL", *dest, *param);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -17,7 +17,20 @@
|
|||
/*
|
||||
* prototypes
|
||||
*/
|
||||
extern int capidebug;
|
||||
extern char *emptyid;
|
||||
|
||||
extern void cc_verbose(int o_v, int c_d, char *text, ...);
|
||||
extern _cword get_capi_MessageNumber(void);
|
||||
extern MESSAGE_EXCHANGE_ERROR _capi_put_cmsg(_cmsg *CMSG);
|
||||
extern MESSAGE_EXCHANGE_ERROR capidev_check_wait_get_cmsg(_cmsg *CMSG);
|
||||
extern char *capi_info_string(unsigned int info);
|
||||
extern void show_capi_info(struct capi_pvt *i, _cword info);
|
||||
extern unsigned ListenOnController(unsigned long CIPmask, unsigned controller);
|
||||
extern void parse_dialstring(char *buffer, char **interface, char **dest, char **param, char **ocid);
|
||||
extern char *capi_number_func(unsigned char *data, unsigned int strip, char *buf);
|
||||
|
||||
#define capi_number(data, strip) \
|
||||
capi_number_func(data, strip, alloca(AST_MAX_EXTENSION))
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue