Added linkage id handling for CCBS/CCNR.

This commit is contained in:
MelwareDE 2007-04-17 21:04:42 +00:00
parent cd18383e0e
commit a9c2413461
7 changed files with 146 additions and 2 deletions

10
README
View File

@ -202,6 +202,11 @@ ECT:
exten => s,1,capicommand(hold)
exten => s,2,Dial(CAPI/contr1/1234,,M(capi3pty))
Peer link creation:
Create a reference for chan-capi to know who is the calling channel on Dial().
This is needed if you want to use CCBS/CCNR afterwards.
Example:
exten => s,1,capicommand(peerlink)
Using CLIR
==========
@ -362,7 +367,10 @@ CALLINGSUBADDRESS
CALLEDSUBADDRESS
If set on dial(), the called subaddress will be set to the content.
CCLINKAGEID
If a Call-Linkage-Id is received for CCBS/CCNR, this variable contains this Id.
CONNECTEDNUMBER
Can be set before answering and if set, the content is used for
IE 'Connected Number' on answering.

View File

@ -1210,6 +1210,8 @@ static int pbx_capi_call(struct ast_channel *c, char *idest, int timeout)
dsa = calledsubaddress;
}
i->peer = cc_get_peer_link_id(pbx_builtin_getvar_helper(c, "CAPIPEERLINKID"));
i->MessageNumber = get_capi_MessageNumber();
CONNECT_REQ_HEADER(&CMSG, capi_ApplID, i->MessageNumber, i->controller);
CONNECT_REQ_CONTROLLER(&CMSG) = i->controller;
@ -4050,6 +4052,24 @@ static int pbx_capi_call_deflect(struct ast_channel *c, char *param)
return(res);
}
/*
* store the peer for future actions
*/
static int pbx_capi_peer_link(struct ast_channel *c, char *param)
{
char buffer[32];
int id;
id = cc_add_peer_link_id(c);
if (id >= 0) {
snprintf(buffer, sizeof(buffer) - 1, "%d", id);
pbx_builtin_setvar_helper(c, "_CAPIPEERLINKID", buffer);
}
return 0;
}
/*
* retrieve a hold on call
*/
@ -4621,6 +4641,7 @@ static struct capicommands_s {
int (*cmd)(struct ast_channel *, char *);
int capionly;
} capicommands[] = {
{ "peerlink", pbx_capi_peer_link, 0 },
{ "progress", pbx_capi_signal_progress, 1 },
{ "deflect", pbx_capi_call_deflect, 1 },
{ "receivefax", pbx_capi_receive_fax, 1 },
@ -4634,7 +4655,7 @@ static struct capicommands_s {
{ "ect", pbx_capi_ect, 1 },
{ "3pty_begin", pbx_capi_3pty_begin, 1 },
{ "qsig_ssct", pbx_capi_qsig_ssct, 1 },
{ "qsig_ct", pbx_capi_qsig_ct, 1 },
{ "qsig_ct", pbx_capi_qsig_ct, 1 },
{ "qsig_callmark",pbx_capi_qsig_callmark, 1 },
{ "qsig_getplci", pbx_capi_qsig_getplci, 1 },
{ NULL, NULL, 0 }

View File

@ -291,6 +291,9 @@ struct capi_pvt {
/*! Channel we belong to, possibly NULL */
struct ast_channel *owner;
/*! Channel who called us, possibly NULL */
struct ast_channel *peer;
/* capi message number */
_cword MessageNumber;
unsigned int NCCI;

View File

@ -20,6 +20,53 @@
#include "chan_capi_supplementary.h"
#include "chan_capi_utils.h"
#define CCBSNR_MAX_LIST_ENTRIES 32
static struct ccbsnr_s ccbsnr_list[CCBSNR_MAX_LIST_ENTRIES];
/*
* a new CCBS/CCNR id was received
*/
static void new_ccbsnr_id(ccbsnrtype_t type, unsigned int plci,
_cword id, struct capi_pvt *i)
{
int a;
char buffer[CAPI_MAX_STRING];
for (a = 0; a < CCBSNR_MAX_LIST_ENTRIES; a++) {
if (ccbsnr_list[a].type == CCBSNR_TYPE_NULL) {
ccbsnr_list[a].type = type;
ccbsnr_list[a].id = id;
ccbsnr_list[a].plci = plci;
ccbsnr_list[a].state = CCBSNR_AVAILABLE;
if (i->peer) {
snprintf(buffer, CAPI_MAX_STRING-1, "%d", (id | ((plci & 0xff) << 16)));
pbx_builtin_setvar_helper(i->peer, "CCLINKAGEID", buffer);
}
break;
}
}
if (a == CCBSNR_MAX_LIST_ENTRIES) {
cc_log(LOG_ERROR, "No free entry for new CCBS/CCNR ID\n");
}
}
/*
* a CCBS/CCNR id was removed
*/
static void del_ccbsnr_id(unsigned int plci, _cword id)
{
int a;
for (a = 0; a < CCBSNR_MAX_LIST_ENTRIES; a++) {
if (((ccbsnr_list[a].plci & 0xff) == (plci & 0xff)) &&
(ccbsnr_list[a].id == id)) {
ccbsnr_list[a].type = CCBSNR_TYPE_NULL;
ccbsnr_list[a].state = 0;
break;
}
}
}
/*
* send Listen for supplementary to specified controller
@ -81,6 +128,7 @@ void handle_facility_indication_supplementary(
case 0x800d: /* CCBS erase call linkage ID */
cc_verbose(1, 1, VERBOSE_PREFIX_3 "contr%d: PLCI=%#x CCBS/CCNR erase id=0x%04x\n",
PLCI & 0xff, PLCI, infoword);
del_ccbsnr_id(PLCI, infoword);
break;
}
@ -134,10 +182,12 @@ void handle_facility_indication_supplementary(
case 0x8013: /* CCBS info retain */
cc_verbose(1, 1, VERBOSE_PREFIX_3 "%s: PLCI=%#x CCBS unique id=0x%04x\n",
i->vname, PLCI, infoword);
new_ccbsnr_id(CCBSNR_TYPE_CCBS, PLCI, infoword, i);
break;
case 0x8015: /* CCNR info retain */
cc_verbose(1, 1, VERBOSE_PREFIX_3 "%s: PLCI=%#x CCNR unique id=0x%04x\n",
i->vname, PLCI, infoword);
new_ccbsnr_id(CCBSNR_TYPE_CCNR, PLCI, infoword, i);
break;
case 0x800d: /* CCBS erase call linkage ID */
/* handled above */

View File

@ -20,4 +20,22 @@
extern void ListenOnSupplementary(unsigned controller);
extern void handle_facility_indication_supplementary(_cmsg *CMSG, unsigned int PLCI, unsigned int NCCI, struct capi_pvt *i);
typedef enum {
CCBSNR_TYPE_NULL = 0,
CCBSNR_TYPE_CCBS,
CCBSNR_TYPE_CCNR
} ccbsnrtype_t;
#define CCBSNR_AVAILABLE 1
struct ccbsnr_s {
ccbsnrtype_t type;
_cword id;
unsigned int plci;
unsigned int state;
char context[AST_MAX_CONTEXT];
char exten[AST_MAX_EXTENSION];
int priority;
};
#endif

View File

@ -12,6 +12,7 @@
*/
#include <stdio.h>
#include <stdlib.h>
#include "chan_capi20.h"
#include "chan_capi.h"
#include "chan_capi_utils.h"
@ -26,6 +27,9 @@ AST_MUTEX_DEFINE_STATIC(capi_put_lock);
static _cword capi_MessageNumber;
#define CAPI_MAX_PEERLINKCHANNELS 32
static struct ast_channel *peerlinkchannel[CAPI_MAX_PEERLINKCHANNELS];
/*
* helper for <pbx>_verbose with different verbose settings
*/
@ -617,3 +621,41 @@ void parse_dialstring(char *buffer, char **interface, char **dest, char **param,
return;
}
/*
* Add a new peer link id
*/
int cc_add_peer_link_id(struct ast_channel *c)
{
int a;
for (a = 0; a < CAPI_MAX_PEERLINKCHANNELS; a++) {
if (peerlinkchannel[a] == NULL) {
peerlinkchannel[a] = c;
break;
}
}
if (a == CAPI_MAX_PEERLINKCHANNELS) {
return -1;
}
return a;
}
/*
* Get and remove peer link id
*/
struct ast_channel *cc_get_peer_link_id(const char *p)
{
int id = -1;
struct ast_channel *chan = NULL;
if (p) {
id = (int)strtoul(p, NULL, 0);
}
if ((id >= 0) && (id < CAPI_MAX_PEERLINKCHANNELS)) {
chan = peerlinkchannel[id];
peerlinkchannel[id] = NULL;
}
return chan;
}

View File

@ -29,6 +29,8 @@ 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);
extern int cc_add_peer_link_id(struct ast_channel *c);
extern struct ast_channel *cc_get_peer_link_id(const char *p);
#define capi_number(data, strip) \
capi_number_func(data, strip, alloca(AST_MAX_EXTENSION))