- added basic null-plci handling for chat.
- moved more CAPI requests for sendf use.
This commit is contained in:
parent
0c80e2361f
commit
47b9b750f1
48
chan_capi.c
48
chan_capi.c
|
@ -275,9 +275,10 @@ static const char * capi_command_to_string(unsigned short wCmd)
|
|||
/*
|
||||
* wait for B3 up
|
||||
*/
|
||||
void capi_wait_for_b3_up(struct capi_pvt *i)
|
||||
int capi_wait_for_b3_up(struct capi_pvt *i)
|
||||
{
|
||||
struct timespec abstime;
|
||||
int ret = 0;
|
||||
|
||||
cc_mutex_lock(&i->lock);
|
||||
if (!(i->isdnstate & CAPI_ISDN_STATE_B3_UP)) {
|
||||
|
@ -292,9 +293,12 @@ void capi_wait_for_b3_up(struct capi_pvt *i)
|
|||
} else {
|
||||
cc_verbose(4, 1, "%s: cond signal received for b3 up.\n",
|
||||
i->vname);
|
||||
ret = 1;
|
||||
}
|
||||
}
|
||||
cc_mutex_unlock(&i->lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -456,16 +460,6 @@ static void capi_channel_task(struct ast_channel *c, int task)
|
|||
* Echo cancellation is for cards w/ integrated echo cancellation only
|
||||
* (i.e. Eicon active cards support it)
|
||||
*/
|
||||
#define EC_FUNCTION_ENABLE 1
|
||||
#define EC_FUNCTION_DISABLE 2
|
||||
#define EC_FUNCTION_FREEZE 3
|
||||
#define EC_FUNCTION_RESUME 4
|
||||
#define EC_FUNCTION_RESET 5
|
||||
#define EC_OPTION_DISABLE_NEVER 0
|
||||
#define EC_OPTION_DISABLE_G165 (1<<2)
|
||||
#define EC_OPTION_DISABLE_G164_OR_G165 (1<<1 | 1<<2)
|
||||
#define EC_DEFAULT_TAIL 0 /* maximum */
|
||||
|
||||
static void capi_echo_canceller(struct ast_channel *c, int function)
|
||||
{
|
||||
struct capi_pvt *i = CC_CHANNEL_PVT(c);
|
||||
|
@ -801,6 +795,10 @@ static void interface_cleanup(struct capi_pvt *i)
|
|||
i->writerfd = -1;
|
||||
}
|
||||
|
||||
if (capi_remove_nullif(i)) {
|
||||
return;
|
||||
}
|
||||
|
||||
i->isdnstate = 0;
|
||||
i->cause = 0;
|
||||
|
||||
|
@ -946,20 +944,22 @@ static void capi_send_disconnect(unsigned int PLCI, struct capi_pvt *i)
|
|||
* hangup a line (CAPI messages)
|
||||
* (this must be called with i->lock held)
|
||||
*/
|
||||
static void capi_activehangup(struct ast_channel *c, int state)
|
||||
void capi_activehangup(struct capi_pvt *i, int state)
|
||||
{
|
||||
struct capi_pvt *i = CC_CHANNEL_PVT(c);
|
||||
struct ast_channel *c = i->owner;
|
||||
_cmsg CMSG;
|
||||
const char *cause;
|
||||
|
||||
i->cause = c->hangupcause;
|
||||
if ((cause = pbx_builtin_getvar_helper(c, "PRI_CAUSE"))) {
|
||||
i->cause = atoi(cause);
|
||||
}
|
||||
if (c) {
|
||||
i->cause = c->hangupcause;
|
||||
if ((cause = pbx_builtin_getvar_helper(c, "PRI_CAUSE"))) {
|
||||
i->cause = atoi(cause);
|
||||
}
|
||||
|
||||
if ((i->isdnstate & CAPI_ISDN_STATE_ECT)) {
|
||||
cc_verbose(3, 1, VERBOSE_PREFIX_3 "%s: activehangup ECT call\n",
|
||||
i->vname);
|
||||
if ((i->isdnstate & CAPI_ISDN_STATE_ECT)) {
|
||||
cc_verbose(3, 1, VERBOSE_PREFIX_3 "%s: activehangup ECT call\n",
|
||||
i->vname);
|
||||
}
|
||||
}
|
||||
|
||||
cc_verbose(2, 1, VERBOSE_PREFIX_3 "%s: activehangingup (cause=%d) for PLCI=%#x\n",
|
||||
|
@ -1045,7 +1045,7 @@ static int pbx_capi_hangup(struct ast_channel *c)
|
|||
interface_cleanup(i);
|
||||
} else {
|
||||
/* not disconnected yet, we must actively do it */
|
||||
capi_activehangup(c, state);
|
||||
capi_activehangup(i, state);
|
||||
}
|
||||
|
||||
i->owner = NULL;
|
||||
|
@ -3766,7 +3766,7 @@ void capidev_handle_connection_conf(struct capi_pvt **i, unsigned int PLCI,
|
|||
}
|
||||
*i = find_interface_by_msgnum(wMsgNum);
|
||||
ii = *i;
|
||||
if ((ii == NULL) || (!ii->owner)) {
|
||||
if (ii == NULL) {
|
||||
return;
|
||||
}
|
||||
cc_verbose(1, 1, VERBOSE_PREFIX_3 "%s: received CONNECT_CONF PLCI = %#x\n",
|
||||
|
@ -3777,7 +3777,9 @@ void capidev_handle_connection_conf(struct capi_pvt **i, unsigned int PLCI,
|
|||
} else {
|
||||
/* error in connect, so set correct state and signal busy */
|
||||
ii->state = CAPI_STATE_DISCONNECTED;
|
||||
local_queue_frame(ii, &fr);
|
||||
if (ii->owner) {
|
||||
local_queue_frame(ii, &fr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
15
chan_capi.h
15
chan_capi.h
|
@ -175,6 +175,16 @@ typedef struct fax3proto3 B3_PROTO_FAXG3;
|
|||
#define FACILITYSELECTOR_FAX_OVER_IP 0x00fd
|
||||
#define FACILITYSELECTOR_VOICE_OVER_IP 0x00fe
|
||||
|
||||
#define EC_FUNCTION_ENABLE 1
|
||||
#define EC_FUNCTION_DISABLE 2
|
||||
#define EC_FUNCTION_FREEZE 3
|
||||
#define EC_FUNCTION_RESUME 4
|
||||
#define EC_FUNCTION_RESET 5
|
||||
#define EC_OPTION_DISABLE_NEVER 0
|
||||
#define EC_OPTION_DISABLE_G165 (1<<2)
|
||||
#define EC_OPTION_DISABLE_G164_OR_G165 (1<<1 | 1<<2)
|
||||
#define EC_DEFAULT_TAIL 0 /* maximum */
|
||||
|
||||
#define CC_HOLDTYPE_LOCAL 0
|
||||
#define CC_HOLDTYPE_HOLD 1
|
||||
#define CC_HOLDTYPE_NOTIFY 2
|
||||
|
@ -243,7 +253,7 @@ struct cc_capi_gains {
|
|||
|
||||
#define CAPI_CHANNELTYPE_B 0
|
||||
#define CAPI_CHANNELTYPE_D 1
|
||||
#define CAPI_CHANNELTYPE_NONE 2
|
||||
#define CAPI_CHANNELTYPE_NULL 2
|
||||
|
||||
/* the lower word is reserved for capi commands */
|
||||
#define CAPI_WAITEVENT_B3_UP 0x00010000
|
||||
|
@ -570,6 +580,7 @@ extern void queue_cause_control(struct capi_pvt *i, int control);
|
|||
extern void capidev_handle_connection_conf(struct capi_pvt **i, unsigned int PLCI,
|
||||
unsigned short wInfo, unsigned short wMsgNum);
|
||||
extern void capi_wait_for_answered(struct capi_pvt *i);
|
||||
extern void capi_wait_for_b3_up(struct capi_pvt *i);
|
||||
extern int capi_wait_for_b3_up(struct capi_pvt *i);
|
||||
extern void capi_activehangup(struct capi_pvt *i, int state);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -187,16 +187,14 @@ static struct capichat_s *add_chat_member(char *roomname,
|
|||
int pbx_capi_chat(struct ast_channel *c, char *param)
|
||||
{
|
||||
struct capi_pvt *i = NULL;
|
||||
char *roomname, *options;
|
||||
char *roomname, *controller, *options;
|
||||
struct capichat_s *room;
|
||||
struct ast_frame *f;
|
||||
|
||||
if (c->tech == &capi_tech) {
|
||||
i = CC_CHANNEL_PVT(c);
|
||||
} else
|
||||
return -1;
|
||||
int state;
|
||||
unsigned int contr = 1;
|
||||
|
||||
roomname = strsep(¶m, "|");
|
||||
controller = strsep(¶m, "|");
|
||||
options = param;
|
||||
|
||||
if (!roomname) {
|
||||
|
@ -204,15 +202,30 @@ int pbx_capi_chat(struct ast_channel *c, char *param)
|
|||
return -1;
|
||||
}
|
||||
|
||||
cc_verbose(3, 1, VERBOSE_PREFIX_3 "capi chat: %s: roomname=%s options=%s\n",
|
||||
c->name, roomname, options);
|
||||
cc_verbose(3, 1, VERBOSE_PREFIX_3 "capi chat: %s: roomname=%s "
|
||||
"controller=%s options=%s\n",
|
||||
c->name, roomname, controller, options);
|
||||
|
||||
if (controller) {
|
||||
contr = (unsigned int)strtoul(controller, NULL, 0);
|
||||
}
|
||||
|
||||
if (c->tech == &capi_tech) {
|
||||
i = CC_CHANNEL_PVT(c);
|
||||
} else {
|
||||
/* virtual CAPI channel */
|
||||
i = mknullif(contr);
|
||||
if (!i) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (c->_state != AST_STATE_UP)
|
||||
ast_answer(c);
|
||||
|
||||
if (i) {
|
||||
capi_wait_for_answered(i);
|
||||
capi_wait_for_b3_up(i);
|
||||
capi_wait_for_answered(i);
|
||||
if (!(capi_wait_for_b3_up(i))) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
room = add_chat_member(roomname, c, i);
|
||||
|
@ -233,6 +246,15 @@ int pbx_capi_chat(struct ast_channel *c, char *param)
|
|||
|
||||
del_chat_member(room);
|
||||
|
||||
out:
|
||||
if (i->channeltype == CAPI_CHANNELTYPE_NULL) {
|
||||
cc_mutex_lock(&i->lock);
|
||||
state = i->state;
|
||||
i->state = CAPI_STATE_DISCONNECTING;
|
||||
capi_activehangup(i, state);
|
||||
cc_mutex_unlock(&i->lock);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -191,7 +191,6 @@ int capi_alloc_rtp(struct capi_pvt *i)
|
|||
int capi_write_rtp(struct ast_channel *c, struct ast_frame *f)
|
||||
{
|
||||
struct capi_pvt *i = CC_CHANNEL_PVT(c);
|
||||
_cmsg CMSG;
|
||||
struct sockaddr_in us;
|
||||
int len;
|
||||
socklen_t uslen;
|
||||
|
@ -244,14 +243,13 @@ int capi_write_rtp(struct ast_channel *c, struct ast_frame *f)
|
|||
i->vname, i->NCCI, len, f->datalen, ast_getformatname(f->subclass),
|
||||
i->timestamp);
|
||||
|
||||
DATA_B3_REQ_HEADER(&CMSG, capi_ApplID, get_capi_MessageNumber(), 0);
|
||||
DATA_B3_REQ_NCCI(&CMSG) = i->NCCI;
|
||||
DATA_B3_REQ_FLAGS(&CMSG) = 0;
|
||||
DATA_B3_REQ_DATAHANDLE(&CMSG) = i->send_buffer_handle;
|
||||
DATA_B3_REQ_DATALENGTH(&CMSG) = len;
|
||||
DATA_B3_REQ_DATA(&CMSG) = (buf);
|
||||
|
||||
_capi_put_cmsg(&CMSG);
|
||||
capi_sendf (NULL, 0, CAPI_DATA_B3_REQ, i->NCCI, get_capi_MessageNumber(),
|
||||
"dwww",
|
||||
buf,
|
||||
len,
|
||||
i->send_buffer_handle,
|
||||
0
|
||||
);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -315,11 +313,11 @@ void voice_over_ip_profile(struct cc_capi_controller *cp)
|
|||
unsigned short info = 0;
|
||||
unsigned int payload1, payload2;
|
||||
|
||||
FACILITY_REQ_HEADER(&CMSG, capi_ApplID, get_capi_MessageNumber(), 0);
|
||||
FACILITY_REQ_CONTROLLER(&CMSG) = cp->controller;
|
||||
FACILITY_REQ_FACILITYSELECTOR(&CMSG) = FACILITYSELECTOR_VOICE_OVER_IP;
|
||||
FACILITY_REQ_FACILITYREQUESTPARAMETER(&CMSG) = (_cstruct)&fac;
|
||||
_capi_put_cmsg(&CMSG);
|
||||
capi_sendf (NULL, 0, CAPI_FACILITY_REQ, cp->controller, get_capi_MessageNumber(),
|
||||
"ws",
|
||||
FACILITYSELECTOR_VOICE_OVER_IP,
|
||||
&fac
|
||||
);
|
||||
|
||||
tv.tv_sec = 1;
|
||||
tv.tv_usec = 0;
|
||||
|
|
|
@ -27,9 +27,12 @@ AST_MUTEX_DEFINE_STATIC(verbose_lock);
|
|||
AST_MUTEX_DEFINE_STATIC(messagenumber_lock);
|
||||
AST_MUTEX_DEFINE_STATIC(capi_put_lock);
|
||||
AST_MUTEX_DEFINE_STATIC(peerlink_lock);
|
||||
AST_MUTEX_DEFINE_STATIC(nullif_lock);
|
||||
|
||||
static _cword capi_MessageNumber;
|
||||
|
||||
static struct capi_pvt *nulliflist = NULL;
|
||||
|
||||
#define CAPI_MAX_PEERLINKCHANNELS 32
|
||||
static struct peerlink_s {
|
||||
struct ast_channel *channel;
|
||||
|
@ -57,6 +60,86 @@ void cc_verbose(int o_v, int c_d, char *text, ...)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* hangup and remove null-interface
|
||||
*/
|
||||
int capi_remove_nullif(struct capi_pvt *i)
|
||||
{
|
||||
struct capi_pvt *ii;
|
||||
struct capi_pvt *tmp = NULL;
|
||||
|
||||
if (i->channeltype != CAPI_CHANNELTYPE_NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
cc_mutex_lock(&nullif_lock);
|
||||
ii = nulliflist;
|
||||
while (ii) {
|
||||
if (ii == i) {
|
||||
if (!tmp) {
|
||||
nulliflist = ii->next;
|
||||
} else {
|
||||
tmp->next = ii->next;
|
||||
}
|
||||
free(i);
|
||||
break;
|
||||
}
|
||||
tmp = ii;
|
||||
ii = ii->next;
|
||||
}
|
||||
cc_mutex_unlock(&nullif_lock);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* create new null-interface
|
||||
*/
|
||||
struct capi_pvt *mknullif(unsigned int controller)
|
||||
{
|
||||
struct capi_pvt *tmp;
|
||||
|
||||
tmp = malloc(sizeof(struct capi_pvt));
|
||||
if (!tmp) {
|
||||
return NULL;
|
||||
}
|
||||
memset(tmp, 0, sizeof(struct capi_pvt));
|
||||
|
||||
tmp->readerfd = -1;
|
||||
tmp->writerfd = -1;
|
||||
|
||||
cc_mutex_init(&tmp->lock);
|
||||
ast_cond_init(&tmp->event_trigger, NULL);
|
||||
|
||||
snprintf(tmp->name, sizeof(tmp->name) - 1, "CAPI-NULL-PLCI");
|
||||
snprintf(tmp->vname, sizeof(tmp->vname) - 1, "%s", tmp->name);
|
||||
|
||||
tmp->channeltype = CAPI_CHANNELTYPE_NULL;
|
||||
|
||||
tmp->controller = controller;
|
||||
tmp->doEC = 1;
|
||||
tmp->doEC_global = 1;
|
||||
tmp->ecOption = EC_OPTION_DISABLE_NEVER;
|
||||
tmp->ecTail = EC_DEFAULT_TAIL;
|
||||
tmp->isdnmode = CAPI_ISDNMODE_MSN;
|
||||
tmp->ecSelector = FACILITYSELECTOR_ECHO_CANCEL;
|
||||
|
||||
cc_mutex_lock(&nullif_lock);
|
||||
tmp->next = nulliflist; /* prepend */
|
||||
nulliflist = tmp;
|
||||
cc_mutex_unlock(&nullif_lock);
|
||||
|
||||
tmp->outgoing = 1;
|
||||
tmp->state = CAPI_STATE_CONNECTPENDING;
|
||||
tmp->MessageNumber = get_capi_MessageNumber();
|
||||
capi_sendf (NULL, 0, CAPI_CONNECT_REQ, controller, tmp->MessageNumber,
|
||||
"w()()()()(www()()()())()()()((wwbbb)()()())",
|
||||
0, 1,1,0, 3,0,0,0,0);
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* get a new capi message number automically
|
||||
*/
|
||||
|
@ -90,9 +173,16 @@ struct capi_pvt *find_interface_by_plci(unsigned int plci)
|
|||
return NULL;
|
||||
|
||||
for (i = iflist; i; i = i->next) {
|
||||
if (i->PLCI == plci)
|
||||
return i;
|
||||
}
|
||||
|
||||
cc_mutex_lock(&nullif_lock);
|
||||
for (i = nulliflist; i; i = i->next) {
|
||||
if (i->PLCI == plci)
|
||||
break;
|
||||
}
|
||||
cc_mutex_unlock(&nullif_lock);
|
||||
|
||||
return i;
|
||||
}
|
||||
|
@ -108,9 +198,16 @@ struct capi_pvt *find_interface_by_msgnum(unsigned short msgnum)
|
|||
return NULL;
|
||||
|
||||
for (i = iflist; i; i = i->next) {
|
||||
if ((i->PLCI == 0) && (i->MessageNumber == msgnum))
|
||||
if ((i->PLCI == 0) && (i->MessageNumber == msgnum))
|
||||
return i;
|
||||
}
|
||||
|
||||
cc_mutex_lock(&nullif_lock);
|
||||
for (i = nulliflist; i; i = i->next) {
|
||||
if ((i->PLCI == 0) && (i->MessageNumber == msgnum))
|
||||
break;
|
||||
}
|
||||
cc_mutex_unlock(&nullif_lock);
|
||||
|
||||
return i;
|
||||
}
|
||||
|
@ -143,24 +240,30 @@ MESSAGE_EXCHANGE_ERROR capi_wait_conf(struct capi_pvt *i, unsigned short wCmd)
|
|||
}
|
||||
|
||||
/*
|
||||
* log verbose a capi message
|
||||
* log an error in sending capi message
|
||||
*/
|
||||
static void log_capi_message(MESSAGE_EXCHANGE_ERROR err, _cmsg *CMSG)
|
||||
static void log_capi_error_message(MESSAGE_EXCHANGE_ERROR err, _cmsg *CMSG)
|
||||
{
|
||||
unsigned short wCmd;
|
||||
|
||||
if (err) {
|
||||
cc_log(LOG_ERROR, "CAPI error sending %s (NCCI=%#x) (error=%#x %s)\n",
|
||||
capi_cmsg2str(CMSG), (unsigned int)HEADER_CID(CMSG),
|
||||
err, capi_info_string((unsigned int)err));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* log verbose a capi message
|
||||
*/
|
||||
static void log_capi_message(_cmsg *CMSG)
|
||||
{
|
||||
unsigned short wCmd;
|
||||
|
||||
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 {
|
||||
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));
|
||||
}
|
||||
cc_verbose(4, 1, "%s\n", capi_cmsg2str(CMSG));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -177,13 +280,14 @@ MESSAGE_EXCHANGE_ERROR _capi_put_cmsg(_cmsg *CMSG)
|
|||
}
|
||||
|
||||
error = capi_put_cmsg(CMSG);
|
||||
log_capi_message(CMSG);
|
||||
|
||||
if (cc_mutex_unlock(&capi_put_lock)) {
|
||||
cc_log(LOG_WARNING, "Unable to unlock capi put!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
log_capi_message(error, CMSG);
|
||||
log_capi_error_message(error, CMSG);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
@ -202,6 +306,7 @@ MESSAGE_EXCHANGE_ERROR _capi_put_msg(unsigned char *msg)
|
|||
}
|
||||
|
||||
capi_message2cmsg(&CMSG, msg);
|
||||
log_capi_message(&CMSG);
|
||||
|
||||
error = capi20_put_message(capi_ApplID, msg);
|
||||
|
||||
|
@ -210,7 +315,7 @@ MESSAGE_EXCHANGE_ERROR _capi_put_msg(unsigned char *msg)
|
|||
return -1;
|
||||
}
|
||||
|
||||
log_capi_message(error, &CMSG);
|
||||
log_capi_error_message(error, &CMSG);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
@ -744,19 +849,18 @@ void show_capi_info(struct capi_pvt *i, _cword info)
|
|||
/*
|
||||
* send Listen to specified controller
|
||||
*/
|
||||
unsigned ListenOnController(unsigned long CIPmask, unsigned controller)
|
||||
unsigned ListenOnController(unsigned int CIPmask, unsigned controller)
|
||||
{
|
||||
MESSAGE_EXCHANGE_ERROR error;
|
||||
_cmsg CMSG;
|
||||
int waitcount = 50;
|
||||
_cmsg CMSG;
|
||||
|
||||
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);
|
||||
error = capi_sendf (NULL, 0, CAPI_LISTEN_REQ, controller, get_capi_MessageNumber(),
|
||||
"ddd()()",
|
||||
0x0000ffff,
|
||||
CIPmask,
|
||||
0
|
||||
);
|
||||
|
||||
if (error)
|
||||
goto done;
|
||||
|
|
|
@ -30,11 +30,13 @@ extern MESSAGE_EXCHANGE_ERROR capidev_check_wait_get_cmsg(_cmsg *CMSG);
|
|||
extern MESSAGE_EXCHANGE_ERROR _capi_put_cmsg_wait_conf(struct capi_pvt *i, _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 unsigned ListenOnController(unsigned int 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);
|
||||
extern int cc_add_peer_link_id(struct ast_channel *c);
|
||||
extern struct ast_channel *cc_get_peer_link_id(const char *p);
|
||||
extern int capi_remove_nullif(struct capi_pvt *i);
|
||||
extern struct capi_pvt *mknullif(unsigned int controller);
|
||||
|
||||
#define capi_number(data, strip) \
|
||||
capi_number_func(data, strip, alloca(AST_MAX_EXTENSION))
|
||||
|
|
Loading…
Reference in New Issue