ast_mutex_t lock;
+ char allowed_bearers[BUFFERSIZE+1];
+
enum misdn_chan_state state;
int holded;
int orginator;
}
+
+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"
};
case INFO_CAPABILITY_DIGITAL_RESTRICTED:
return bearers[3];
break;
- default:
+ case INFO_CAPABILITY_VIDEO:
return bearers[4];
break;
+ default:
+ return bearers[5];
+ break;
}
}
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;
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");
}
}
+
+
+
+
static int read_config(struct chan_list *ch, int orig) {
if (!ch) {
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));
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;
}
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 */
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;
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;
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;
}
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);
/** 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())) {
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;
}
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;
+ }
}
}
break;
-
case EVENT_RESTART:
+
+ stop_bc_tones(ch);
+ release_chan(bc);
+
break;
default:
bc->channel = 0;
bc->in_use = 0;
+ bc->sending_complete = 0;
+
+ bc->restart_channel=0;
+
bc->conf_id = 0;
bc->need_more_infos = 0;
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);
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);
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]);
}
}
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);
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);
empty_chan_in_stack(stack,bc->channel);
empty_bc(bc);
}
- queue_cleanup_bc(bc);
+ clean_up_bc(bc);
}
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) {
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.**/
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;
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))
}
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);