dect
/
asterisk
Archived
13
0
Fork 0

added bearer capability reject support. we send release instead of disconnect in case we have no real channel yet. added support for Restarting channels added support for sending complete decoding. changed some log levels.

git-svn-id: http://svn.digium.com/svn/asterisk/trunk@31324 f38db490-d61c-443f-a65b-d21fe96a405b
This commit is contained in:
crichter 2006-06-01 12:51:41 +00:00
parent d42fc385b5
commit f6aed90150
8 changed files with 155 additions and 62 deletions

View File

@ -151,6 +151,8 @@ struct chan_list {
ast_mutex_t lock;
char allowed_bearers[BUFFERSIZE+1];
enum misdn_chan_state state;
int holded;
int orginator;
@ -346,12 +348,28 @@ static struct chan_list * get_chan_by_ast_name(char *name)
}
struct allowed_bearers {
int cap;
int val;
char *name;
};
struct allowed_bearers allowed_bearers_array[]={
{INFO_CAPABILITY_SPEECH,1,"speech"},
{INFO_CAPABILITY_AUDIO_3_1K,2,"3_1khz"},
{INFO_CAPABILITY_DIGITAL_UNRESTRICTED,4,"digital_unrestricted"},
{INFO_CAPABILITY_DIGITAL_RESTRICTED,8,"digital_restriced"},
{INFO_CAPABILITY_VIDEO,16,"video"}
};
static char *bearer2str(int cap) {
static char *bearers[]={
"Speech",
"Audio 3.1k",
"Unres Digital",
"Res Digital",
"Video",
"Unknown Bearer"
};
@ -368,9 +386,12 @@ static char *bearer2str(int cap) {
case INFO_CAPABILITY_DIGITAL_RESTRICTED:
return bearers[3];
break;
default:
case INFO_CAPABILITY_VIDEO:
return bearers[4];
break;
default:
return bearers[5];
break;
}
}
@ -1153,7 +1174,7 @@ static int update_config (struct chan_list *ch, int orig)
int port=bc->port;
chan_misdn_log(1,port,"update_config: Getting Config\n");
chan_misdn_log(5,port,"update_config: Getting Config\n");
int hdlc=0;
@ -1243,7 +1264,7 @@ static void config_jitterbuffer(struct chan_list *ch)
struct misdn_bchannel *bc=ch->bc;
int len=ch->jb_len, threshold=ch->jb_upper_threshold;
chan_misdn_log(1,bc->port, "config_jb: Called\n");
chan_misdn_log(5,bc->port, "config_jb: Called\n");
if ( ! len ) {
chan_misdn_log(1,bc->port, "config_jb: Deactivating Jitterbuffer\n");
@ -1295,6 +1316,10 @@ void debug_numplan(int port, int numplan, char *type)
}
}
static int read_config(struct chan_list *ch, int orig) {
if (!ch) {
@ -1335,6 +1360,9 @@ static int read_config(struct chan_list *ch, int orig) {
misdn_cfg_get( port, MISDN_CFG_NEED_MORE_INFOS, &bc->need_more_infos, sizeof(int));
misdn_cfg_get( port, MISDN_CFG_FAR_ALERTING, &ch->far_alerting, sizeof(int));
misdn_cfg_get( port, MISDN_CFG_ALLOWED_BEARERS, &ch->allowed_bearers, BUFFERSIZE);
int hdlc=0;
misdn_cfg_get( port, MISDN_CFG_HDLC, &hdlc, sizeof(int));
@ -1394,7 +1422,7 @@ static int read_config(struct chan_list *ch, int orig) {
misdn_cfg_get(port, MISDN_CFG_PICKUPGROUP, &pg, sizeof(pg));
misdn_cfg_get(port, MISDN_CFG_CALLGROUP, &cg, sizeof(cg));
chan_misdn_log(2, port, " --> * CallGrp:%s PickupGrp:%s\n",ast_print_group(buf,sizeof(buf),cg),ast_print_group(buf,sizeof(buf),pg));
chan_misdn_log(5, port, " --> * CallGrp:%s PickupGrp:%s\n",ast_print_group(buf,sizeof(buf),cg),ast_print_group(buf,sizeof(buf),pg));
ast->pickupgroup=pg;
ast->callgroup=cg;
}
@ -2228,18 +2256,20 @@ static enum ast_bridge_result misdn_bridge (struct ast_channel *c0,
int bridging;
misdn_cfg_get( 0, MISDN_GEN_BRIDGING, &bridging, sizeof(int));
if (bridging) {
int ecwb;
int ecwb, ec;
misdn_cfg_get( ch1->bc->port, MISDN_CFG_ECHOCANCELWHENBRIDGED, &ecwb, sizeof(int));
if ( !ecwb ) {
misdn_cfg_get( ch1->bc->port, MISDN_CFG_ECHOCANCEL, &ec, sizeof(int));
if ( !ecwb && ec ) {
chan_misdn_log(2, ch1->bc->port, "Disabling Echo Cancellor when Bridged\n");
ch1->bc->ec_enable=0;
/* manager_ec_disable(ch1->bc); */
manager_ec_disable(ch1->bc);
}
misdn_cfg_get( ch2->bc->port, MISDN_CFG_ECHOCANCELWHENBRIDGED, &ecwb, sizeof(int));
if ( !ecwb ) {
misdn_cfg_get( ch2->bc->port, MISDN_CFG_ECHOCANCEL, &ec, sizeof(int));
if ( !ecwb && ec) {
chan_misdn_log(2, ch2->bc->port, "Disabling Echo Cancellor when Bridged\n");
ch2->bc->ec_enable=0;
/* manager_ec_disable(ch2->bc); */
manager_ec_disable(ch2->bc);
}
/* trying to make a mISDN_dsp conference */
@ -2291,7 +2321,7 @@ static int tone_indicate( struct chan_list *cl, enum tone_e tone)
const struct tone_zone_sound *ts= NULL;
struct ast_channel *ast=cl->ast;
chan_misdn_log(2,cl->bc->port,"Tone Indicate:\n");
chan_misdn_log(3,cl->bc->port,"Tone Indicate:\n");
if (!cl->ast) {
return 0;
@ -2299,24 +2329,24 @@ static int tone_indicate( struct chan_list *cl, enum tone_e tone)
switch (tone) {
case TONE_DIAL:
chan_misdn_log(2,cl->bc->port," --> Dial\n");
chan_misdn_log(3,cl->bc->port," --> Dial\n");
ts=ast_get_indication_tone(ast->zone,"dial");
misdn_lib_tone_generator_start(cl->bc);
break;
case TONE_ALERTING:
chan_misdn_log(2,cl->bc->port," --> Ring\n");
chan_misdn_log(3,cl->bc->port," --> Ring\n");
ts=ast_get_indication_tone(ast->zone,"ring");
misdn_lib_tone_generator_stop(cl->bc);
break;
case TONE_FAR_ALERTING:
/* VERY UGLY HACK, BECAUSE CHAN_SIP DOES NOT GENERATE TONES */
chan_misdn_log(2,cl->bc->port," --> Ring\n");
chan_misdn_log(3,cl->bc->port," --> Ring\n");
ts=ast_get_indication_tone(ast->zone,"ring");
misdn_lib_tone_generator_start(cl->bc);
misdn_lib_echo(cl->bc,1);
break;
case TONE_BUSY:
chan_misdn_log(2,cl->bc->port," --> Busy\n");
chan_misdn_log(3,cl->bc->port," --> Busy\n");
ts=ast_get_indication_tone(ast->zone,"busy");
misdn_lib_tone_generator_stop(cl->bc);
break;
@ -2324,7 +2354,7 @@ static int tone_indicate( struct chan_list *cl, enum tone_e tone)
break;
case TONE_NONE:
chan_misdn_log(2,cl->bc->port," --> None\n");
chan_misdn_log(3,cl->bc->port," --> None\n");
misdn_lib_tone_generator_stop(cl->bc);
ast_playtones_stop(ast);
break;
@ -2784,8 +2814,8 @@ static void release_chan(struct misdn_bchannel *bc) {
}
release_unlock;
chan_misdn_log(1, bc->port, "Trying to Release bc with l3id: %x\n",bc->l3_id);
chan_misdn_log(1, bc->port, "release_chan: bc with l3id: %x\n",bc->l3_id);
//releaseing jitterbuffer
if (ch->jb ) {
misdn_jb_destroy(ch->jb);
@ -3325,6 +3355,24 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
/** queue new chan **/
cl_queue_chan(&cl_te, ch) ;
if (!strstr(ch->allowed_bearers,"all")) {
int i;
for (i=0; i< sizeof(allowed_bearers_array)/sizeof(struct allowed_bearers); i++) {
if (allowed_bearers_array[i].cap == bc->capability) {
if ( !strstr( ch->allowed_bearers, allowed_bearers_array[i].name)) {
chan_misdn_log(0,bc->port,"Bearer Not allowed\b");
bc->out_cause=88;
ch->state=MISDN_EXTCANTMATCH;
misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE );
return RESPONSE_OK;
}
}
}
}
/* Check for Pickup Request first */
if (!strcmp(chan->exten, ast_pickup_ext())) {
@ -3380,7 +3428,8 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
if (bc->nt)
misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE );
else
misdn_lib_send_event(bc, EVENT_DISCONNECT );
misdn_lib_send_event(bc, EVENT_RELEASE );
break;
}
@ -3404,26 +3453,34 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
if (bc->nt)
misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE );
else
misdn_lib_send_event(bc, EVENT_DISCONNECT );
misdn_lib_send_event(bc, EVENT_RELEASE);
}
} else {
int ret= misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE );
if (ret == -ENOCHAN) {
ast_log(LOG_WARNING,"Channel was catched, before we could Acknowledge\n");
misdn_lib_send_event(bc,EVENT_RELEASE_COMPLETE);
}
/* send tone to phone :) */
/** ADD IGNOREPAT **/
int stop_tone;
misdn_cfg_get( 0, MISDN_GEN_STOP_TONE, &stop_tone, sizeof(int));
if ( (!ast_strlen_zero(bc->dad)) && stop_tone )
tone_indicate(ch,TONE_NONE);
else
tone_indicate(ch,TONE_DIAL);
ch->state=MISDN_WAITING4DIGS;
if (bc->sending_complete) {
bc->out_cause=1;
misdn_lib_send_event(bc, EVENT_RELEASE);
} else {
int ret= misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE );
if (ret == -ENOCHAN) {
ast_log(LOG_WARNING,"Channel was catched, before we could Acknowledge\n");
misdn_lib_send_event(bc,EVENT_RELEASE_COMPLETE);
}
/* send tone to phone :) */
/** ADD IGNOREPAT **/
int stop_tone;
misdn_cfg_get( 0, MISDN_GEN_STOP_TONE, &stop_tone, sizeof(int));
if ( (!ast_strlen_zero(bc->dad)) && stop_tone )
tone_indicate(ch,TONE_NONE);
else
tone_indicate(ch,TONE_DIAL);
ch->state=MISDN_WAITING4DIGS;
}
}
}
@ -3791,8 +3848,11 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
break;
case EVENT_RESTART:
stop_bc_tones(ch);
release_chan(bc);
break;
default:

View File

@ -23,6 +23,7 @@ enum misdn_cfg_elements {
/* port config items */
MISDN_CFG_FIRST = 0,
MISDN_CFG_GROUPNAME, /* char[] */
MISDN_CFG_ALLOWED_BEARERS, /* char[] */
MISDN_CFG_FAR_ALERTING, /* int (bool) */
MISDN_CFG_RXGAIN, /* int */
MISDN_CFG_TXGAIN, /* int */

View File

@ -162,23 +162,28 @@ void dec_ie_bearer(unsigned char *p, Q931_info_t *qi, int *coding, int *capabili
*stopbits = -1;
*dbits = -1;
*parity = -1;
if (!nt)
{
p = NULL;
if (qi->QI_ELEMENT(llc))
#ifdef LLC_SUPPORT
if (qi->QI_ELEMENT(llc)) {
p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(llc) + 1;
else if (qi->QI_ELEMENT(bearer_capability))
}
#endif
if (qi->QI_ELEMENT(bearer_capability))
p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(bearer_capability) + 1;
}
if (!p)
return;
if (p[0] < 2)
{
printf("%s: ERROR: IE too short (%d).\n", __FUNCTION__, p[0]);
return;
}
*coding = (p[1]&0x60) >> 5;
*capability = p[1] & 0x1f;
octet = 2;

View File

@ -471,6 +471,10 @@ void empty_bc(struct misdn_bchannel *bc)
bc->channel = 0;
bc->in_use = 0;
bc->sending_complete = 0;
bc->restart_channel=0;
bc->conf_id = 0;
bc->need_more_infos = 0;
@ -557,7 +561,7 @@ int clean_up_bc(struct misdn_bchannel *bc)
unsigned char buff[32];
struct misdn_stack * stack;
cb_log(2, 0, "$$$ CLEANUP CALLED\n");
cb_log(3, 0, "$$$ CLEANUP CALLED\n");
if (!bc ) return -1;
stack=get_stack_by_bc(bc);
@ -587,15 +591,18 @@ int clean_up_bc(struct misdn_bchannel *bc)
manager_ec_disable(bc);
}
mISDN_write_frame(stack->midev, buff, bc->layer_id|FLG_MSG_DOWN, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
if (bc->bc_state == BCHAN_SETUP)
mISDN_write_frame(stack->midev, buff, bc->layer_id|FLG_MSG_DOWN, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
else
mISDN_write_frame(stack->midev, buff, bc->addr|FLG_MSG_DOWN, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
cb_log(2, stack->port, "$$$ CLEARING STACK\n");
cb_log(3, stack->port, "$$$ CLEARING STACK\n");
ret=mISDN_clear_stack(stack->midev,bc->b_stid);
if (ret<0) {
cb_log(-1,stack->port,"clear stack failed [%s]\n",strerror(errno));
}
bc->b_stid = 0;
bc_state_change(bc, BCHAN_CLEANED);
@ -612,8 +619,7 @@ void clear_l3(struct misdn_stack *stack)
cb_event(EVENT_CLEANUP, &stack->bc[i], glob_mgr->user_data);
empty_chan_in_stack(stack,i+1);
empty_bc(&stack->bc[i]);
queue_cleanup_bc(&stack->bc[i]);
clean_up_bc(&stack->bc[i]);
}
}
@ -971,19 +977,18 @@ int setup_bc(struct misdn_bchannel *bc)
pid.layermask = ISDN_LAYER((1)) | ISDN_LAYER((2)) | ISDN_LAYER((3)) | ISDN_LAYER((4));
}
ret = mISDN_set_stack(midev, bc->b_stid, &pid);
if (ret){
cb_log(5, stack->port,"$$$ Set Stack Err: %d %s\n",ret,strerror(errno));
cb_log(-1, stack->port,"$$$ Set Stack Err: %d %s\n",ret,strerror(errno));
mISDN_write_frame(midev, buff, bc->layer_id, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
bc_state_change(bc,BCHAN_ERROR);
return(-EINVAL);
}
bc_state_change(bc,BCHAN_SETUP);
@ -1479,7 +1484,7 @@ int handle_cr ( struct misdn_stack *stack, iframe_t *frm)
cb_log(4, stack->port, " --> lib: CLEANING UP l3id: %x\n",frm->dinfo);
empty_chan_in_stack(stack,bc->channel);
empty_bc(bc);
queue_cleanup_bc(bc);
clean_up_bc(bc);
dump_chan_list(stack);
bc->pid = 0;
cb_event(EVENT_CLEANUP, bc, glob_mgr->user_data);
@ -1517,7 +1522,7 @@ void misdn_lib_release(struct misdn_bchannel *bc)
empty_chan_in_stack(stack,bc->channel);
empty_bc(bc);
}
queue_cleanup_bc(bc);
clean_up_bc(bc);
}
@ -2049,7 +2054,7 @@ int handle_bchan(msg_t *msg)
case MGR_SETSTACK| INDICATION:
cb_log(2, stack->port, "BCHAN: MGR_SETSTACK|IND \n");
AGAIN:
bc->addr = mISDN_get_layerid(stack->midev, bc->b_stid, bc->layer);
if (!bc->addr) {
@ -2943,7 +2948,7 @@ int misdn_lib_send_event(struct misdn_bchannel *bc, enum event_e event )
empty_chan_in_stack(stack,bc->channel);
empty_bc(bc);
queue_cleanup_bc(bc);
clean_up_bc(bc);
}
/** we set it up later at RETRIEVE_ACK again.**/
@ -3018,6 +3023,13 @@ int handle_err(msg_t *msg)
case MGR_SETSTACK|INDICATION:
return handle_bchan(msg);
break;
case MGR_SETSTACK|CONFIRM:
case MGR_CLEARSTACK|CONFIRM:
free_msg(msg) ;
return 1;
break;
case DL_DATA|INDICATION:
{
int port=(frm->addr&MASTER_ID_MASK) >> 8;
@ -3101,8 +3113,10 @@ int manager_isdn_handler(iframe_t *frm ,msg_t *msg)
if (handle_l1(msg))
return 0 ;
/* The L2/L3 will be queued */
if (queue_l2l3(msg))
if (handle_frm_nt(msg))
return 0;
if (handle_frm(msg))
return 0;
if (handle_err(msg))
@ -3862,7 +3876,7 @@ void misdn_split_conf(struct misdn_bchannel *bc, int conf_id)
}
void misdn_lib_bridge( struct misdn_bchannel * bc1, struct misdn_bchannel *bc2) {
int conf_id=(bc1->pid<<1) +1;
int conf_id=bc1->pid +1;
cb_log(1, bc1->port, "I Send: BRIDGE from:%d to:%d\n",bc1->port,bc2->port);

View File

@ -182,7 +182,8 @@ struct misdn_bchannel {
int l3_id;
int pid;
int ces;
int restart_channel;
int channel;
int channel_preselected;
@ -208,6 +209,10 @@ struct misdn_bchannel {
/* get setup ack */
int need_more_infos;
/* may there be more infos ?*/
int sending_complete;
/* wether we should use jollys dsp or not */
int nodsp;

View File

@ -197,8 +197,8 @@ void parse_setup (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc,
}
{
int sending_complete;
dec_ie_complete(setup->COMPLETE, (Q931_info_t *)setup, &sending_complete, nt,bc);
dec_ie_complete(setup->COMPLETE, (Q931_info_t *)setup, &bc->sending_complete, nt,bc);
}
{
@ -217,6 +217,8 @@ void parse_setup (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc,
break;
case 0: bc->capability=INFO_CAPABILITY_SPEECH;
break;
case 18: bc->capability=INFO_CAPABILITY_VIDEO;
break;
case 8: bc->capability=INFO_CAPABILITY_DIGITAL_UNRESTRICTED;
bc->user1 = user;
bc->urate = urate;
@ -775,7 +777,7 @@ void parse_restart (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *b
{
int exclusive, channel;
dec_ie_channel_id(restart->CHANNEL_ID, (Q931_info_t *)restart, &exclusive, &channel, nt,bc);
dec_ie_channel_id(restart->CHANNEL_ID, (Q931_info_t *)restart, &exclusive, &bc->restart_channel, nt,bc);
if (channel==0xff) /* any channel */
channel=-1;
cb_log(3, stack->port, "CC_RESTART Request on channel:%d on this port.\n");

View File

@ -84,6 +84,7 @@ struct misdn_cfg_spec {
static const struct misdn_cfg_spec port_spec[] = {
{ "name", MISDN_CFG_GROUPNAME, MISDN_CTYPE_STR, "default", NONE },
{ "allowed_bearers", MISDN_CFG_ALLOWED_BEARERS, MISDN_CTYPE_STR, "all", NONE },
{ "rxgain", MISDN_CFG_RXGAIN, MISDN_CTYPE_INT, "0", NONE },
{ "txgain", MISDN_CFG_TXGAIN, MISDN_CTYPE_INT, "0", NONE },
{ "te_choose_channel", MISDN_CFG_TE_CHOOSE_CHANNEL, MISDN_CTYPE_BOOL, "no", NONE },

View File

@ -128,6 +128,11 @@ senddtmf=yes
far_alerting=no
;
; here you can define which bearers should be allowed
;
allowed_bearers=all
; Prefixes for national and international, those are put before the
; oad if an according dialplan is set by the other end.
;