- added variable REDIRECTREASON
- use stack memory for capi_number() - use struct for capicommand() commands - capicommand(RETRIEVE) can now be called from other channels - start PBX on SETUP only.
This commit is contained in:
parent
7ee382db9e
commit
398aa1b09f
4
README
4
README
|
@ -276,4 +276,8 @@ REDIRECTINGNUMBER
|
||||||
On incoming call, if the call was redirected to you by someone, the
|
On incoming call, if the call was redirected to you by someone, the
|
||||||
number of the redirecting party is saved in this variable.
|
number of the redirecting party is saved in this variable.
|
||||||
|
|
||||||
|
REDIRECTREASON
|
||||||
|
If the incoming call was redirected to you, this variable is set
|
||||||
|
with the reason value.
|
||||||
|
|
||||||
|
|
||||||
|
|
227
chan_capi.c
227
chan_capi.c
|
@ -686,20 +686,33 @@ static int capi_hangup(struct ast_channel *c)
|
||||||
/*
|
/*
|
||||||
* convert a number
|
* convert a number
|
||||||
*/
|
*/
|
||||||
static char *capi_number(char *data, int strip)
|
static char *capi_number_func(unsigned char *data, unsigned int strip, char *buf)
|
||||||
{
|
{
|
||||||
unsigned len = *data;
|
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)
|
||||||
|
len = AST_MAX_EXTENSION;
|
||||||
|
|
||||||
/* XXX fix me */
|
|
||||||
/* convert a capi struct to a \0 terminated string */
|
/* convert a capi struct to a \0 terminated string */
|
||||||
if ((!len) || (len < (unsigned int) strip))
|
if ((!len) || (len < strip))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
len = len - strip;
|
len = len - strip;
|
||||||
data = (char *)(data + 1 + strip);
|
data += strip;
|
||||||
|
|
||||||
return strndup((char *)data, len);
|
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
|
* parse the dialstring
|
||||||
|
@ -750,6 +763,11 @@ static int capi_call(struct ast_channel *c, char *idest, int timeout)
|
||||||
char bchaninfo[3];
|
char bchaninfo[3];
|
||||||
int CLIR;
|
int CLIR;
|
||||||
int callernplan = 0;
|
int callernplan = 0;
|
||||||
|
char *ton, *p;
|
||||||
|
char *osa = NULL;
|
||||||
|
char *dsa = NULL;
|
||||||
|
char callingsubaddress[AST_MAX_EXTENSION];
|
||||||
|
char calledsubaddress[AST_MAX_EXTENSION];
|
||||||
|
|
||||||
_cmsg CMSG;
|
_cmsg CMSG;
|
||||||
MESSAGE_EXCHANGE_ERROR error;
|
MESSAGE_EXCHANGE_ERROR error;
|
||||||
|
@ -797,15 +815,31 @@ static int capi_call(struct ast_channel *c, char *idest, int timeout)
|
||||||
#else
|
#else
|
||||||
CLIR = c->callingpres;
|
CLIR = c->callingpres;
|
||||||
#endif
|
#endif
|
||||||
cc_ast_verbose(1, 1, VERBOSE_PREFIX_2 "%s: Call %s %s%s (pres=0x%02x)\n",
|
if ((ton = pbx_builtin_getvar_helper(c, "CALLERTON"))) {
|
||||||
|
callernplan = atoi(ton) & 0x7f;
|
||||||
|
}
|
||||||
|
cc_ast_verbose(1, 1, VERBOSE_PREFIX_2 "%s: Call %s %s%s (pres=0x%02x, ton=0x%02x)\n",
|
||||||
i->name, c->name, i->doB3 ? "with B3 ":" ",
|
i->name, c->name, i->doB3 ? "with B3 ":" ",
|
||||||
i->doOverlap ? "overlap":"", CLIR);
|
i->doOverlap ? "overlap":"", CLIR, callernplan);
|
||||||
|
|
||||||
/* set FD for Asterisk*/
|
/* set FD for Asterisk*/
|
||||||
c->fds[0] = i->fd;
|
c->fds[0] = i->fd;
|
||||||
|
|
||||||
i->outgoing = 1;
|
i->outgoing = 1;
|
||||||
|
|
||||||
|
if ((p = pbx_builtin_getvar_helper(c, "CALLINGSUBADDRESS"))) {
|
||||||
|
callingsubaddress[0] = strlen(p) + 1;
|
||||||
|
callingsubaddress[1] = 0x80;
|
||||||
|
strncpy(&callingsubaddress[2], p, sizeof(callingsubaddress) - 3);
|
||||||
|
osa = callingsubaddress;
|
||||||
|
}
|
||||||
|
if ((p = pbx_builtin_getvar_helper(c, "CALLEDSUBADDRESS"))) {
|
||||||
|
calledsubaddress[0] = strlen(p) + 1;
|
||||||
|
calledsubaddress[1] = 0x80;
|
||||||
|
strncpy(&calledsubaddress[2], p, sizeof(calledsubaddress) - 3);
|
||||||
|
dsa = calledsubaddress;
|
||||||
|
}
|
||||||
|
|
||||||
i->MessageNumber = get_ast_capi_MessageNumber();
|
i->MessageNumber = get_ast_capi_MessageNumber();
|
||||||
CONNECT_REQ_HEADER(&CMSG, ast_capi_ApplID, i->MessageNumber, i->controller);
|
CONNECT_REQ_HEADER(&CMSG, ast_capi_ApplID, i->MessageNumber, i->controller);
|
||||||
CONNECT_REQ_CONTROLLER(&CMSG) = i->controller;
|
CONNECT_REQ_CONTROLLER(&CMSG) = i->controller;
|
||||||
|
@ -823,7 +857,7 @@ static int capi_call(struct ast_channel *c, char *idest, int timeout)
|
||||||
called[1] = 0x80;
|
called[1] = 0x80;
|
||||||
strncpy(&called[2], dest, sizeof(called) - 3);
|
strncpy(&called[2], dest, sizeof(called) - 3);
|
||||||
CONNECT_REQ_CALLEDPARTYNUMBER(&CMSG) = called;
|
CONNECT_REQ_CALLEDPARTYNUMBER(&CMSG) = called;
|
||||||
CONNECT_REQ_CALLEDPARTYSUBADDRESS(&CMSG) = NULL;
|
CONNECT_REQ_CALLEDPARTYSUBADDRESS(&CMSG) = dsa;
|
||||||
|
|
||||||
#ifdef CC_AST_CHANNEL_HAS_CID
|
#ifdef CC_AST_CHANNEL_HAS_CID
|
||||||
if (c->cid.cid_num)
|
if (c->cid.cid_num)
|
||||||
|
@ -841,7 +875,7 @@ static int capi_call(struct ast_channel *c, char *idest, int timeout)
|
||||||
strncpy(&calling[3], callerid, sizeof(calling) - 4);
|
strncpy(&calling[3], callerid, sizeof(calling) - 4);
|
||||||
|
|
||||||
CONNECT_REQ_CALLINGPARTYNUMBER(&CMSG) = calling;
|
CONNECT_REQ_CALLINGPARTYNUMBER(&CMSG) = calling;
|
||||||
CONNECT_REQ_CALLINGPARTYSUBADDRESS(&CMSG) = NULL;
|
CONNECT_REQ_CALLINGPARTYSUBADDRESS(&CMSG) = osa;
|
||||||
|
|
||||||
CONNECT_REQ_B1PROTOCOL(&CMSG) = 1;
|
CONNECT_REQ_B1PROTOCOL(&CMSG) = 1;
|
||||||
CONNECT_REQ_B2PROTOCOL(&CMSG) = 1;
|
CONNECT_REQ_B2PROTOCOL(&CMSG) = 1;
|
||||||
|
@ -1227,19 +1261,6 @@ static struct ast_channel *capi_new(struct ast_capi_pvt *i, int state)
|
||||||
|
|
||||||
ast_setstate(tmp, state);
|
ast_setstate(tmp, state);
|
||||||
|
|
||||||
if (state == AST_STATE_RING) {
|
|
||||||
if (ast_pbx_start(tmp)) {
|
|
||||||
ast_log(LOG_ERROR, "%s: Unable to start pbx on channel!\n",
|
|
||||||
i->name);
|
|
||||||
ast_hangup(tmp);
|
|
||||||
ast_channel_free(tmp);
|
|
||||||
i->owner = NULL;
|
|
||||||
tmp = NULL;
|
|
||||||
} else {
|
|
||||||
cc_ast_verbose(2, 0, VERBOSE_PREFIX_2 "%s: started pbx on channel (callgroup=%d)!\n",
|
|
||||||
i->name, tmp->callgroup);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1887,6 +1908,25 @@ static void handle_info_disconnect(_cmsg *CMSG, unsigned int PLCI, unsigned int
|
||||||
i->name);
|
i->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* incoming call SETUP
|
||||||
|
*/
|
||||||
|
static void handle_setup_element(_cmsg *CMSG, unsigned int PLCI, struct ast_capi_pvt *i)
|
||||||
|
{
|
||||||
|
if (!i->owner) {
|
||||||
|
ast_log(LOG_ERROR, "No channel for interface!\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i->isdnmode == AST_CAPI_ISDNMODE_DID) {
|
||||||
|
if (!strlen(i->dnid) && (i->immediate)) {
|
||||||
|
start_pbx_on_match(i, PLCI, CMSG->Messagenumber);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
start_pbx_on_match(i, PLCI, CMSG->Messagenumber);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* CAPI INFO_IND
|
* CAPI INFO_IND
|
||||||
*/
|
*/
|
||||||
|
@ -1894,7 +1934,8 @@ static void capi_handle_info_indication(_cmsg *CMSG, unsigned int PLCI, unsigned
|
||||||
{
|
{
|
||||||
_cmsg CMSG2;
|
_cmsg CMSG2;
|
||||||
struct ast_frame fr;
|
struct ast_frame fr;
|
||||||
char *p;
|
char *p = NULL;
|
||||||
|
int val = 0;
|
||||||
|
|
||||||
memset(&CMSG2, 0, sizeof(_cmsg));
|
memset(&CMSG2, 0, sizeof(_cmsg));
|
||||||
INFO_RESP_HEADER(&CMSG2, ast_capi_ApplID, CMSG->Messagenumber, PLCI);
|
INFO_RESP_HEADER(&CMSG2, ast_capi_ApplID, CMSG->Messagenumber, PLCI);
|
||||||
|
@ -1942,8 +1983,8 @@ static void capi_handle_info_indication(_cmsg *CMSG, unsigned int PLCI, unsigned
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cc_ast_verbose(3, 1, VERBOSE_PREFIX_3 "%s: info element NOTIFICATION INDICATOR '%s'\n",
|
cc_ast_verbose(3, 1, VERBOSE_PREFIX_3 "%s: info element NOTIFICATION INDICATOR '%s' (0x%02x)\n",
|
||||||
i->name, desc);
|
i->name, desc, INFO_IND_INFOELEMENT(CMSG)[1]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 0x0028: /* DSP */
|
case 0x0028: /* DSP */
|
||||||
|
@ -1970,10 +2011,16 @@ static void capi_handle_info_indication(_cmsg *CMSG, unsigned int PLCI, unsigned
|
||||||
break;
|
break;
|
||||||
case 0x0074: /* Redirecting Number */
|
case 0x0074: /* Redirecting Number */
|
||||||
p = capi_number(INFO_IND_INFOELEMENT(CMSG), 3);
|
p = capi_number(INFO_IND_INFOELEMENT(CMSG), 3);
|
||||||
|
if (INFO_IND_INFOELEMENT(CMSG)[0] > 2) {
|
||||||
|
val = INFO_IND_INFOELEMENT(CMSG)[3] & 0x0f;
|
||||||
|
}
|
||||||
cc_ast_verbose(3, 1, VERBOSE_PREFIX_3 "%s: info element REDIRECTING NUMBER '%s' Reason=0x%02x\n",
|
cc_ast_verbose(3, 1, VERBOSE_PREFIX_3 "%s: info element REDIRECTING NUMBER '%s' Reason=0x%02x\n",
|
||||||
i->name, p, (INFO_IND_INFOELEMENT(CMSG)[0] > 2) ? (INFO_IND_INFOELEMENT(CMSG)[3] & 0x0f) : 0xff);
|
i->name, p, val);
|
||||||
if (i->owner) {
|
if (i->owner) {
|
||||||
|
char reasonbuf[16];
|
||||||
|
snprintf(reasonbuf, sizeof(reasonbuf) - 1, "%d", val);
|
||||||
pbx_builtin_setvar_helper(i->owner, "REDIRECTINGNUMBER", p);
|
pbx_builtin_setvar_helper(i->owner, "REDIRECTINGNUMBER", p);
|
||||||
|
pbx_builtin_setvar_helper(i->owner, "REDIRECTREASON", reasonbuf);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0x4000: /* CHARGE in UNITS */
|
case 0x4000: /* CHARGE in UNITS */
|
||||||
|
@ -2013,10 +2060,13 @@ static void capi_handle_info_indication(_cmsg *CMSG, unsigned int PLCI, unsigned
|
||||||
* related to the call setup; then, we could always abort if we
|
* related to the call setup; then, we could always abort if we
|
||||||
* get a PROGRESS with a hangupcause set (safer?)
|
* get a PROGRESS with a hangupcause set (safer?)
|
||||||
*/
|
*/
|
||||||
if (i->owner && i->owner->hangupcause == AST_CAUSE_USER_BUSY) {
|
if (i->doB3 == AST_CAPI_B3_DONT) {
|
||||||
|
if ((i->owner) &&
|
||||||
|
(i->owner->hangupcause == AST_CAUSE_USER_BUSY)) {
|
||||||
pipe_cause_control(i, 1);
|
pipe_cause_control(i, 1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
fr.frametype = AST_FRAME_CONTROL;
|
fr.frametype = AST_FRAME_CONTROL;
|
||||||
fr.subclass = AST_CONTROL_PROGRESS;
|
fr.subclass = AST_CONTROL_PROGRESS;
|
||||||
pipe_frame(i, &fr);
|
pipe_frame(i, &fr);
|
||||||
|
@ -2024,6 +2074,7 @@ static void capi_handle_info_indication(_cmsg *CMSG, unsigned int PLCI, unsigned
|
||||||
case 0x8005: /* SETUP */
|
case 0x8005: /* SETUP */
|
||||||
cc_ast_verbose(3, 1, VERBOSE_PREFIX_3 "%s: info element SETUP\n",
|
cc_ast_verbose(3, 1, VERBOSE_PREFIX_3 "%s: info element SETUP\n",
|
||||||
i->name);
|
i->name);
|
||||||
|
handle_setup_element(CMSG, PLCI, i);
|
||||||
break;
|
break;
|
||||||
case 0x8007: /* CONNECT */
|
case 0x8007: /* CONNECT */
|
||||||
cc_ast_verbose(3, 1, VERBOSE_PREFIX_3 "%s: info element CONNECT\n",
|
cc_ast_verbose(3, 1, VERBOSE_PREFIX_3 "%s: info element CONNECT\n",
|
||||||
|
@ -2728,14 +2779,10 @@ static void capi_handle_connect_indication(_cmsg *CMSG, unsigned int PLCI, unsig
|
||||||
i->MessageNumber = CMSG->Messagenumber;
|
i->MessageNumber = CMSG->Messagenumber;
|
||||||
i->cid_ton = callernplan;
|
i->cid_ton = callernplan;
|
||||||
|
|
||||||
if (i->isdnmode == AST_CAPI_ISDNMODE_DID) {
|
|
||||||
capi_new(i, AST_STATE_DOWN);
|
capi_new(i, AST_STATE_DOWN);
|
||||||
|
if (i->isdnmode == AST_CAPI_ISDNMODE_DID) {
|
||||||
i->state = CAPI_STATE_DID;
|
i->state = CAPI_STATE_DID;
|
||||||
if (!strlen(i->dnid) && (i->immediate) && (i->owner)) {
|
|
||||||
start_pbx_on_match(i, PLCI, CMSG->Messagenumber);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
capi_new(i, AST_STATE_RING);
|
|
||||||
i->state = CAPI_STATE_INCALL;
|
i->state = CAPI_STATE_INCALL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2760,12 +2807,16 @@ static void capi_handle_connect_indication(_cmsg *CMSG, unsigned int PLCI, unsig
|
||||||
i->name, i->cid, i->dnid);
|
i->name, i->cid, i->dnid);
|
||||||
sprintf(buffer, "%d", callednplan);
|
sprintf(buffer, "%d", callednplan);
|
||||||
pbx_builtin_setvar_helper(i->owner, "CALLEDTON", buffer);
|
pbx_builtin_setvar_helper(i->owner, "CALLEDTON", buffer);
|
||||||
#warning TODO set some variables on incoming call
|
/*
|
||||||
/* TODO
|
pbx_builtin_setvar_helper(i->owner, "CALLINGSUBADDRESS",
|
||||||
pbx_builtin_setvar_helper(i->owner, "USERUSERINFO", buffer);
|
CONNECT_IND_CALLINGPARTYSUBADDRESS(CMSG));
|
||||||
pbx_builtin_setvar_helper(i->owner, "CALLINGSUBADDR", buffer);
|
pbx_builtin_setvar_helper(i->owner, "CALLEDSUBADDRESS",
|
||||||
pbx_builtin_setvar_helper(i->owner, "CALLEDSUBADDR", buffer);
|
CONNECT_IND_CALLEDPARTYSUBADDRESS(CMSG));
|
||||||
pbx_builtin_setvar_helper(i->owner, "PRIREDIRECTREASON", buffer);
|
pbx_builtin_setvar_helper(i->owner, "USERUSERINFO",
|
||||||
|
CONNECT_IND_USERUSERDATA(CMSG));
|
||||||
|
*/
|
||||||
|
/* TODO : set some more variables on incoming call */
|
||||||
|
/*
|
||||||
pbx_builtin_setvar_helper(i->owner, "ANI2", buffer);
|
pbx_builtin_setvar_helper(i->owner, "ANI2", buffer);
|
||||||
pbx_builtin_setvar_helper(i->owner, "SECONDCALLERID", buffer);
|
pbx_builtin_setvar_helper(i->owner, "SECONDCALLERID", buffer);
|
||||||
*/
|
*/
|
||||||
|
@ -3011,10 +3062,15 @@ static void capi_handle_msg(_cmsg *CMSG)
|
||||||
*/
|
*/
|
||||||
static int capi_retrieve(struct ast_channel *c, char *param)
|
static int capi_retrieve(struct ast_channel *c, char *param)
|
||||||
{
|
{
|
||||||
struct ast_capi_pvt *i = CC_AST_CHANNEL_PVT(c);
|
struct ast_capi_pvt *i = NULL;
|
||||||
_cmsg CMSG;
|
_cmsg CMSG;
|
||||||
char fac[4];
|
char fac[4];
|
||||||
unsigned int plci = i->onholdPLCI;
|
unsigned int plci = 0;
|
||||||
|
|
||||||
|
if (!(strcmp(c->type, "CAPI"))) {
|
||||||
|
i = CC_AST_CHANNEL_PVT(c);
|
||||||
|
plci = i->onholdPLCI;
|
||||||
|
}
|
||||||
|
|
||||||
if (param) {
|
if (param) {
|
||||||
plci = (unsigned int)strtoul(param, NULL, 0);
|
plci = (unsigned int)strtoul(param, NULL, 0);
|
||||||
|
@ -3029,6 +3085,12 @@ static int capi_retrieve(struct ast_channel *c, char *param)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!i) {
|
||||||
|
ast_log(LOG_WARNING, "%s is not valid or not on capi hold to retrieve!\n",
|
||||||
|
c->name);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if ((i->state != CAPI_STATE_ONHOLD) &&
|
if ((i->state != CAPI_STATE_ONHOLD) &&
|
||||||
(i->isdnstate & CAPI_ISDN_STATE_HOLD)) {
|
(i->isdnstate & CAPI_ISDN_STATE_HOLD)) {
|
||||||
int waitcount = 200;
|
int waitcount = 200;
|
||||||
|
@ -3175,7 +3237,8 @@ static int capi_hold(struct ast_channel *c, char *param)
|
||||||
char buffer[16];
|
char buffer[16];
|
||||||
char fac[4];
|
char fac[4];
|
||||||
|
|
||||||
#warning TODO: support holdtype notify
|
/* TODO: support holdtype notify */
|
||||||
|
|
||||||
if (i->isdnstate & CAPI_ISDN_STATE_HOLD) {
|
if (i->isdnstate & CAPI_ISDN_STATE_HOLD) {
|
||||||
ast_log(LOG_NOTICE,"%s: %s already on hold.\n",
|
ast_log(LOG_NOTICE,"%s: %s already on hold.\n",
|
||||||
i->name, c->name);
|
i->name, c->name);
|
||||||
|
@ -3185,12 +3248,12 @@ static int capi_hold(struct ast_channel *c, char *param)
|
||||||
if (i->state != CAPI_STATE_BCONNECTED) {
|
if (i->state != CAPI_STATE_BCONNECTED) {
|
||||||
ast_log(LOG_NOTICE,"%s: Cannot put on hold %s while not connected.\n",
|
ast_log(LOG_NOTICE,"%s: Cannot put on hold %s while not connected.\n",
|
||||||
i->name, c->name);
|
i->name, c->name);
|
||||||
return -1;
|
return 0;
|
||||||
}
|
}
|
||||||
if (!(capi_controllers[i->controller]->holdretrieve)) {
|
if (!(capi_controllers[i->controller]->holdretrieve)) {
|
||||||
ast_log(LOG_NOTICE,"%s: HOLD for %s not supported by controller.\n",
|
ast_log(LOG_NOTICE,"%s: HOLD for %s not supported by controller.\n",
|
||||||
i->name, c->name);
|
i->name, c->name);
|
||||||
return -1;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
fac[0] = 3; /* len */
|
fac[0] = 3; /* len */
|
||||||
|
@ -3302,6 +3365,7 @@ static int capi_holdtype(struct ast_channel *c, char *param)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
/*
|
/*
|
||||||
* set early-B3 for incoming connections
|
* set early-B3 for incoming connections
|
||||||
* (only for NT mode)
|
* (only for NT mode)
|
||||||
|
@ -3347,6 +3411,27 @@ static int capi_set_earlyb3(struct ast_channel *c, char *param)
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* struct of capi commands
|
||||||
|
*/
|
||||||
|
static struct capicommands_s {
|
||||||
|
char *cmdname;
|
||||||
|
int (*cmd)(struct ast_channel *, char *);
|
||||||
|
int capionly;
|
||||||
|
} capicommands[] = {
|
||||||
|
/* { "earlyb3", capi_set_earlyb3, 1 }, */
|
||||||
|
{ "deflect", capi_call_deflect, 1 },
|
||||||
|
{ "receivefax", capi_receive_fax, 1 },
|
||||||
|
{ "echosquelch", capi_echosquelch, 1 },
|
||||||
|
{ "malicious", capi_malicious, 1 },
|
||||||
|
{ "hold", capi_hold, 1 },
|
||||||
|
{ "holdtype", capi_holdtype, 1 },
|
||||||
|
{ "retrieve", capi_retrieve, 0 },
|
||||||
|
{ "ect", capi_ect, 1 },
|
||||||
|
{ NULL, NULL, 0 }
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* capi command interface
|
* capi command interface
|
||||||
|
@ -3358,15 +3443,15 @@ static int capicommand_exec(struct ast_channel *chan, void *data)
|
||||||
char *s;
|
char *s;
|
||||||
char *stringp;
|
char *stringp;
|
||||||
char *command, *params;
|
char *command, *params;
|
||||||
|
struct capicommands_s *capicmd = &capicommands[0];
|
||||||
|
|
||||||
if (!data) {
|
if (!data) {
|
||||||
ast_log(LOG_WARNING, "capiCommand requires arguments\n");
|
ast_log(LOG_WARNING, "capiCommand requires arguments\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (strcmp(chan->type, "CAPI")) {
|
|
||||||
ast_log(LOG_WARNING, "capiCommand works on CAPI channels only, check your extensions.conf!\n");
|
LOCAL_USER_ADD(u);
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
s = ast_strdupa(data);
|
s = ast_strdupa(data);
|
||||||
stringp = s;
|
stringp = s;
|
||||||
command = strsep(&stringp, "|");
|
command = strsep(&stringp, "|");
|
||||||
|
@ -3374,31 +3459,26 @@ static int capicommand_exec(struct ast_channel *chan, void *data)
|
||||||
cc_ast_verbose(2, 1, VERBOSE_PREFIX_3 "capiCommand: '%s' '%s'\n",
|
cc_ast_verbose(2, 1, VERBOSE_PREFIX_3 "capiCommand: '%s' '%s'\n",
|
||||||
command, params);
|
command, params);
|
||||||
|
|
||||||
LOCAL_USER_ADD(u);
|
while(capicmd->cmd) {
|
||||||
if (!strcasecmp(command, "earlyb3")) {
|
if (!strcasecmp(capicmd->cmdname, command))
|
||||||
res = capi_set_earlyb3(chan, params);
|
break;
|
||||||
} else if (!strcasecmp(command, "deflect")) {
|
capicmd++;
|
||||||
res = capi_call_deflect(chan, params);
|
}
|
||||||
} else if (!strcasecmp(command, "receivefax")) {
|
if (!capicmd->cmd) {
|
||||||
res = capi_receive_fax(chan, params);
|
LOCAL_USER_REMOVE(u);
|
||||||
} else if (!strcasecmp(command, "echosquelch")) {
|
|
||||||
res = capi_echosquelch(chan, params);
|
|
||||||
} else if (!strcasecmp(command, "malicious")) {
|
|
||||||
res = capi_malicious(chan, params);
|
|
||||||
} else if (!strcasecmp(command, "hold")) {
|
|
||||||
res = capi_hold(chan, params);
|
|
||||||
} else if (!strcasecmp(command, "holdtype")) {
|
|
||||||
res = capi_holdtype(chan, params);
|
|
||||||
} else if (!strcasecmp(command, "retrieve")) {
|
|
||||||
res = capi_retrieve(chan, params);
|
|
||||||
} else if (!strcasecmp(command, "ect")) {
|
|
||||||
res = capi_ect(chan, params);
|
|
||||||
} else {
|
|
||||||
res = -1;
|
|
||||||
ast_log(LOG_WARNING, "Unknown command '%s' for capiCommand\n",
|
ast_log(LOG_WARNING, "Unknown command '%s' for capiCommand\n",
|
||||||
command);
|
command);
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((capicmd->capionly) && (strcmp(chan->type, "CAPI"))) {
|
||||||
|
LOCAL_USER_REMOVE(u);
|
||||||
|
ast_log(LOG_WARNING, "capiCommand works on CAPI channels only, check your extensions.conf!\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
res = (capicmd->cmd)(chan, params);
|
||||||
|
|
||||||
LOCAL_USER_REMOVE(u);
|
LOCAL_USER_REMOVE(u);
|
||||||
return(res);
|
return(res);
|
||||||
}
|
}
|
||||||
|
@ -3420,9 +3500,9 @@ static int capi_indicate(struct ast_channel *c, int condition)
|
||||||
case AST_CONTROL_RINGING:
|
case AST_CONTROL_RINGING:
|
||||||
cc_ast_verbose(3, 1, VERBOSE_PREFIX_2 "%s: Requested RINGING-Indication for %s\n",
|
cc_ast_verbose(3, 1, VERBOSE_PREFIX_2 "%s: Requested RINGING-Indication for %s\n",
|
||||||
i->name, c->name);
|
i->name, c->name);
|
||||||
#warning TODO somehow enable unhold on ringing, but when wanted only
|
/* TODO somehow enable unhold on ringing, but when wanted only */
|
||||||
/* if (i->isdnstate & CAPI_ISDN_STATE_HOLD) */
|
if (i->isdnstate & CAPI_ISDN_STATE_HOLD)
|
||||||
/* capi_retrieve(c, NULL); */
|
capi_retrieve(c, NULL);
|
||||||
ret = capi_alert(c);
|
ret = capi_alert(c);
|
||||||
break;
|
break;
|
||||||
case AST_CONTROL_BUSY:
|
case AST_CONTROL_BUSY:
|
||||||
|
@ -3456,11 +3536,12 @@ static int capi_indicate(struct ast_channel *c, int condition)
|
||||||
case AST_CONTROL_PROGRESS:
|
case AST_CONTROL_PROGRESS:
|
||||||
cc_ast_verbose(3, 1, VERBOSE_PREFIX_2 "%s: Requested PROGRESS-Indication for %s\n",
|
cc_ast_verbose(3, 1, VERBOSE_PREFIX_2 "%s: Requested PROGRESS-Indication for %s\n",
|
||||||
i->name, c->name);
|
i->name, c->name);
|
||||||
#warning TODO: in NT-mode we should send progress for early b3 to phone
|
/* TODO: in NT-mode we should send progress for early b3 to phone */
|
||||||
break;
|
break;
|
||||||
case AST_CONTROL_PROCEEDING:
|
case AST_CONTROL_PROCEEDING:
|
||||||
cc_ast_verbose(3, 1, VERBOSE_PREFIX_2 "%s: Requested PROCEEDING-Indication for %s\n",
|
cc_ast_verbose(3, 1, VERBOSE_PREFIX_2 "%s: Requested PROCEEDING-Indication for %s\n",
|
||||||
i->name, c->name);
|
i->name, c->name);
|
||||||
|
/* TODO: in NT-mode we should send progress for early b3 to phone */
|
||||||
break;
|
break;
|
||||||
#ifdef CC_AST_CONTROL_HOLD
|
#ifdef CC_AST_CONTROL_HOLD
|
||||||
case AST_CONTROL_HOLD:
|
case AST_CONTROL_HOLD:
|
||||||
|
|
Loading…
Reference in New Issue