diff --git a/channels/chan_misdn.c b/channels/chan_misdn.c index 3e9d1b1c1be6a94405e5f6497e21fd9380aeabb4..eee3510baacb248638ab0d280e4878035ea1c13f 100644 --- a/channels/chan_misdn.c +++ b/channels/chan_misdn.c @@ -299,7 +299,7 @@ ast_mutex_t cl_te_lock; static enum event_response_e cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data); -static void send_cause2ast(struct ast_channel *ast, struct misdn_bchannel*bc); +static void send_cause2ast(struct ast_channel *ast, struct misdn_bchannel*bc, struct chan_list *ch); static void cl_queue_chan(struct chan_list **list, struct chan_list *chan); static void cl_dequeue_chan(struct chan_list **list, struct chan_list *chan); @@ -641,7 +641,9 @@ static struct state_struct state_array[] = { {MISDN_EXTCANTMATCH,"EXTCANTMATCH"}, /* when asterisk couldnt match our ext */ {MISDN_DIALING,"DIALING"}, /* when pbx_start */ {MISDN_PROGRESS,"PROGRESS"}, /* when pbx_start */ + {MISDN_PROCEEDING,"PROCEEDING"}, /* when pbx_start */ {MISDN_CALLING,"CALLING"}, /* when misdn_call is called */ + {MISDN_CALLING_ACKNOWLEDGE,"CALLING_ACKNOWLEDGE"}, /* when misdn_call is called */ {MISDN_ALERTING,"ALERTING"}, /* when Alerting */ {MISDN_BUSY,"BUSY"}, /* when BUSY */ {MISDN_CONNECTED,"CONNECTED"}, /* when connected */ @@ -659,13 +661,17 @@ static struct state_struct state_array[] = { static char *misdn_get_ch_state(struct chan_list *p) { int i; + static char state[8]; + if( !p) return NULL; for (i=0; i< sizeof(state_array)/sizeof(struct state_struct); i++) { if ( state_array[i].state == p->state) return state_array[i].txt; } - - return NULL; + + sprintf(state,"%d",p->state) ; + + return state; } @@ -1829,7 +1835,7 @@ static int misdn_indication(struct ast_channel *ast, int cond, const void *data, chan_misdn_log(1, p->bc->port, "* IND :\tbusy\n"); chan_misdn_log(1, p->bc->port, " --> * SEND: State Busy pid:%d\n",p->bc?p->bc->pid:-1); ast_setstate(ast,AST_STATE_BUSY); - + p->bc->out_cause=17; if (p->state != MISDN_CONNECTED) { misdn_lib_send_event( p->bc, EVENT_DISCONNECT); @@ -1997,7 +2003,7 @@ static int misdn_hangup(struct ast_channel *ast) { const char *varcause=NULL; - bc->cause=ast->hangupcause?ast->hangupcause:16; + bc->out_cause=ast->hangupcause?ast->hangupcause:16; if ( (varcause=pbx_builtin_getvar_helper(ast, "HANGUPCAUSE")) || (varcause=pbx_builtin_getvar_helper(ast, "PRI_CAUSE"))) { @@ -2018,15 +2024,16 @@ static int misdn_hangup(struct ast_channel *ast) break; case MISDN_HOLDED: case MISDN_DIALING: + case MISDN_CALLING_ACKNOWLEDGE: start_bc_tones(p); tone_indicate(p, TONE_HANGUP); - p->state=MISDN_CLEANING; - if (bc->nt) + if (bc->nt) { misdn_lib_send_event( bc, EVENT_DISCONNECT); - else + } else { misdn_lib_send_event( bc, EVENT_RELEASE_COMPLETE); - + p->state=MISDN_CLEANING; + } break; case MISDN_ALERTING: @@ -2035,16 +2042,19 @@ static int misdn_hangup(struct ast_channel *ast) if (p->orginator != ORG_AST) tone_indicate(p, TONE_HANGUP); - p->state=MISDN_CLEANING; + /*p->state=MISDN_CLEANING;*/ misdn_lib_send_event( bc, EVENT_DISCONNECT); break; case MISDN_CONNECTED: /* Alerting or Disconect */ - start_bc_tones(p); - tone_indicate(p, TONE_HANGUP); + if (p->bc->nt) { + start_bc_tones(p); + tone_indicate(p, TONE_HANGUP); + p->bc->progress_indicator=8; + } misdn_lib_send_event( bc, EVENT_DISCONNECT); - - p->state=MISDN_CLEANING; /* MISDN_HUNGUP_FROM_AST; */ + + /*p->state=MISDN_CLEANING;*/ break; case MISDN_DISCONNECTED: misdn_lib_send_event( bc, EVENT_RELEASE); @@ -2053,6 +2063,10 @@ static int misdn_hangup(struct ast_channel *ast) case MISDN_RELEASED: case MISDN_CLEANING: + p->state=MISDN_CLEANING; + break; + + case MISDN_BUSY: break; case MISDN_HOLD_DISCONNECT: @@ -2062,22 +2076,22 @@ static int misdn_hangup(struct ast_channel *ast) bc->out_cause=-1; misdn_lib_send_event(bc,EVENT_RELEASE); + p->state=MISDN_CLEANING; break; default: - /* Alerting or Disconect */ - if (bc->nt) { bc->out_cause=-1; misdn_lib_send_event(bc, EVENT_RELEASE); - } else + p->state=MISDN_CLEANING; + } else { misdn_lib_send_event(bc, EVENT_DISCONNECT); - p->state=MISDN_CLEANING; /* MISDN_HUNGUP_FROM_AST; */ + } } } - chan_misdn_log(1, bc->port, "Channel: %s hanguped\n",ast->name); + chan_misdn_log(1, bc->port, "Channel: %s hanguped new state:%s\n",ast->name,misdn_get_ch_state(p)); return 0; } @@ -2376,6 +2390,7 @@ static int tone_indicate( struct chan_list *cl, enum tone_e tone) chan_misdn_log(3,cl->bc->port,"Ast Ptr Not existing anymore.. we need to generate tones ourselves now (tbd)\n"); misdn_lib_send_tone(cl->bc,tone); + misdn_lib_tone_generator_start(cl->bc); return 0; } @@ -2383,24 +2398,20 @@ static int tone_indicate( struct chan_list *cl, enum tone_e tone) case TONE_DIAL: 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(3,cl->bc->port," --> Ring\n"); ts=ast_get_indication_tone(ast->zone,"ring"); - misdn_lib_tone_generator_start(cl->bc); break; case TONE_FAR_ALERTING: /* VERY UGLY HACK, BECAUSE CHAN_SIP DOES NOT GENERATE TONES */ 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(3,cl->bc->port," --> Busy\n"); ts=ast_get_indication_tone(ast->zone,"busy"); - misdn_lib_tone_generator_start(cl->bc); break; case TONE_FILE: break; @@ -2415,7 +2426,13 @@ static int tone_indicate( struct chan_list *cl, enum tone_e tone) cl->ts=ts; - if (ts) ast_playtones_start(ast,0, ts->data, 0); + if (ts) { + cl->notxtone=0; + cl->norxtone=0; + ast_playtones_start(ast,0, ts->data, 0); + chan_misdn_log(4,cl->bc->port,"Starting Playtones\n"); + misdn_lib_tone_generator_start(cl->bc); + } return 0; } @@ -2531,7 +2548,8 @@ static struct ast_channel *misdn_request(const char *type, int format, void *dat next_chan = 1; if (port <= port_start && next_chan) { - if (++robin_channel >= MAX_BCHANS) { + int maxbchans=misdn_lib_get_maxchans(port); + if (++robin_channel >= maxbchans) { robin_channel = 1; } next_chan = 0; @@ -2914,7 +2932,7 @@ static void release_chan(struct misdn_bchannel *bc) { chan_misdn_log(1, bc->port, "* RELEASING CHANNEL pid:%d ctx:%s dad:%s oad:%s state: %s\n",bc?bc->pid:-1, ast->context, ast->exten,AST_CID_P(ast),misdn_get_ch_state(ch)); chan_misdn_log(3, bc->port, " --> * State Down\n"); /* copy cause */ - send_cause2ast(ast,bc); + send_cause2ast(ast,bc,ch); MISDN_ASTERISK_TECH_PVT(ast)=NULL; @@ -2936,11 +2954,13 @@ static void release_chan(struct misdn_bchannel *bc) { case MISDN_DIALING: case MISDN_CALLING_ACKNOWLEDGE: case MISDN_PROGRESS: + case MISDN_PROCEEDING: chan_misdn_log(2, bc->port, "* --> In State Dialin\n"); chan_misdn_log(2, bc->port, "* --> Queue Hangup\n"); - + ch->state=MISDN_CLEANING; ast_queue_hangup(ast); + break; case MISDN_CALLING: @@ -3059,7 +3079,7 @@ static void do_immediate_setup(struct misdn_bchannel *bc,struct chan_list *ch , -static void send_cause2ast(struct ast_channel *ast, struct misdn_bchannel*bc) { +static void send_cause2ast(struct ast_channel *ast, struct misdn_bchannel*bc, struct chan_list *ch) { ast->hangupcause=bc->cause; @@ -3076,6 +3096,7 @@ static void send_cause2ast(struct ast_channel *ast, struct misdn_bchannel*bc) { * the inband message * chan_misdn_log(1, bc?bc->port:0, " --> * SEND: Queue Congestion pid:%d\n", bc?bc->pid:-1); + ch->state=MISDN_BUSY; ast_queue_control(ast, AST_CONTROL_CONGESTION); */ @@ -3084,7 +3105,8 @@ static void send_cause2ast(struct ast_channel *ast, struct misdn_bchannel*bc) { case 21: case 17: /* user busy */ chan_misdn_log(1, bc?bc->port:0, " --> * SEND: Queue Busy pid:%d\n", bc?bc->pid:-1); - + + ch->state=MISDN_BUSY; ast_queue_control(ast, AST_CONTROL_BUSY); break; @@ -3178,6 +3200,8 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data) if (ch ) { switch (event) { + case EVENT_TONE_GENERATE: + break; case EVENT_DISCONNECT: case EVENT_RELEASE: case EVENT_RELEASE_COMPLETE: @@ -3297,10 +3321,8 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data) ch->state=MISDN_EXTCANTMATCH; bc->out_cause=1; - 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_DISCONNECT ); + break; } if (ast_exists_extension(ch->ast, ch->context, bc->dad, 1, bc->oad)) { @@ -3313,10 +3335,7 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data) chan_misdn_log(-1, bc->port, "ast_pbx_start returned < 0 in INFO\n"); tone_indicate(ch,TONE_BUSY); - 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_DISCONNECT ); } } @@ -3683,8 +3702,7 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data) struct chan_list *holded_ch=find_holded(cl_te, bc); if (ch->ast) - send_cause2ast(ch->ast,bc); - + send_cause2ast(ch->ast,bc,ch); chan_misdn_log(3,bc->port," --> org:%d nt:%d, inbandavail:%d state:%d\n", ch->orginator, bc->nt, misdn_inband_avail(bc), ch->state); if ( ch->orginator==ORG_AST && !bc->nt && misdn_inband_avail(bc) && ch->state != MISDN_CONNECTED) { @@ -3709,19 +3727,9 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data) } stop_bc_tones(ch); - /*bc->out_cause=16;*/ bc->out_cause=-1; - /*if (ch->state == MISDN_CONNECTED) misdn_lib_send_event(bc,EVENT_RELEASE); - else - misdn_lib_send_event(bc,EVENT_RELEASE_COMPLETE); - */ - - misdn_lib_send_event(bc,EVENT_RELEASE); - - if (ch->state == MISDN_CONNECTED) - ch->state=MISDN_RELEASED; } break; @@ -3772,6 +3780,8 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data) chan_misdn_log(9,bc->port,"TONE_GEN: len:%d\n"); + if (!ast) break; + if (!ast->generator) break; @@ -3848,6 +3858,9 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data) break; case EVENT_TIMEOUT: { + if (ch && bc) + chan_misdn_log(1,bc->port,"--> state: %s\n",misdn_get_ch_state(ch)); + switch (ch->state) { case MISDN_WAITING4DIGS: case MISDN_CALLING: diff --git a/channels/misdn/ie.c b/channels/misdn/ie.c index eeeff040bcee51d262926e5108bdf027bd36ac7c..a3eb255f86c92dd5998cba9384ad10f94e2fcd89 100644 --- a/channels/misdn/ie.c +++ b/channels/misdn/ie.c @@ -1093,8 +1093,7 @@ void dec_ie_progress(unsigned char *p, Q931_info_t *qi, int *coding, int *locati *location = p[1] & 0x0f; *progress = p[2] & 0x7f; - //if (MISDN_IE_DEBG) printf(" coding=%d location=%d progress=%d\n", *coding, *location, *progress); - if (1) printf(" coding=%d location=%d progress=%d\n", *coding, *location, *progress); + if (MISDN_IE_DEBG) printf(" coding=%d location=%d progress=%d\n", *coding, *location, *progress); } diff --git a/channels/misdn/isdn_lib.c b/channels/misdn/isdn_lib.c index d88f05c9770d8f1beafc13ac38972bc2c232063b..5a82f71690adc68ebdb607dbe50643005424b30d 100644 --- a/channels/misdn/isdn_lib.c +++ b/channels/misdn/isdn_lib.c @@ -33,6 +33,20 @@ int misdn_lib_is_ptp(int port) return -1; } +int misdn_lib_get_maxchans(int port) +{ + struct misdn_stack *stack=get_misdn_stack(); + for ( ; stack; stack=stack->next) { + if (stack->port == port) { + if (stack->pri) + return 30; + else + return 2; + } + } + return -1; +} + struct misdn_stack* get_stack_by_bc(struct misdn_bchannel *bc) { @@ -374,6 +388,8 @@ static int find_free_chan_in_stack(struct misdn_stack *stack, struct misdn_bchan { int i; + cb_log(1,stack->port,"find_free_chan: req_chan:%d\n",channel); + if (channel < 0 || channel > MAX_BCHANS) { cb_log(4, stack->port, " !! out of bound call to find_free_chan_in_stack! (ch:%d)\n", channel); return 0; @@ -384,7 +400,7 @@ static int find_free_chan_in_stack(struct misdn_stack *stack, struct misdn_bchan for (i = 0; i < stack->b_num; i++) { if (i != 15 && (channel < 0 || i == channel)) { /* skip E1 Dchannel ;) and work with chan preselection */ if (!stack->channels[i]) { - cb_log (4, stack->port, " --> found chan%s: %d\n", channel>=0?" (preselected)":"", i+1); + cb_log (1, stack->port, " --> found chan%s: %d\n", channel>=0?" (preselected)":"", i+1); stack->channels[i] = 1; bc->channel=i+1; cb_event(EVENT_NEW_CHANNEL, bc, NULL); @@ -401,7 +417,7 @@ static int find_free_chan_in_stack(struct misdn_stack *stack, struct misdn_bchan int empty_chan_in_stack(struct misdn_stack *stack, int channel) { - cb_log (4, stack?stack->port:0, " --> empty chan %d\n",channel); + cb_log (1, stack?stack->port:0, "empty_chan_in_stack: %d\n",channel); stack->channels[channel-1] = 0; dump_chan_list(stack); return 0; @@ -613,7 +629,13 @@ void clear_l3(struct misdn_stack *stack) int set_chan_in_stack(struct misdn_stack *stack, int channel) { - stack->channels[channel-1] = 1; + + cb_log(1,stack->port,"set_chan_in_stack: %d\n",channel); + if (channel >=1 ) { + stack->channels[channel-1] = 1; + } else { + cb_log(-1,stack->port,"couldn't set channel %d in\n", channel ); + } return 0; } @@ -802,7 +824,7 @@ static int create_process (int midev, struct misdn_bchannel *bc) { free_chan = find_free_chan_in_stack(stack, bc, bc->channel_preselected?bc->channel:0); if (!free_chan) return -1; /*bc->channel=free_chan;*/ - cb_log(0,stack->port, " --> found channel: %d\n",free_chan); + cb_log(2,stack->port, " --> found channel: %d\n",free_chan); } else { /* other phones could have made a call also on this port (ptmp) */ bc->channel=0xff; @@ -1420,7 +1442,12 @@ int handle_event ( struct misdn_bchannel *bc, enum event_e event, iframe_t *frm) cb_log(-1, stack->port, "Any Channel Requested, but we have no more!!\n"); break; } - } + } + + if (bc->channel >0 && bc->channel<255) { + set_chan_in_stack(stack ,bc->channel); + } + #if 0 int ret=setup_bc(bc); if (ret == -EINVAL){ @@ -2085,6 +2112,7 @@ void misdn_tx_jitter(struct misdn_bchannel *bc, int len) r=mISDN_write( glob_mgr->midev, buf, txfrm->len + mISDN_HEADER_LEN, 8000 ); } else { +#define MISDN_GEN_SILENCE #ifdef MISDN_GEN_SILENCE int cnt=len/TONE_SILENCE_SIZE; int rest=len%TONE_SILENCE_SIZE; @@ -2122,7 +2150,7 @@ int handle_bchan(msg_t *msg) struct misdn_bchannel *bc=find_bc_by_addr(frm->addr); if (!bc) { - cb_log(0,0,"handle_bchan: BC not found for prim:%x with addr:%x dinfo:%x\n", frm->prim, frm->addr, frm->dinfo); + cb_log(1,0,"handle_bchan: BC not found for prim:%x with addr:%x dinfo:%x\n", frm->prim, frm->addr, frm->dinfo); return 0 ; } @@ -2273,7 +2301,8 @@ int handle_bchan(msg_t *msg) free_msg(msg); return 1; - + + case PH_DATA|INDICATION: case DL_DATA|INDICATION: { @@ -3188,6 +3217,16 @@ int handle_err(msg_t *msg) return 1; break; + case DL_DATA|CONFIRM: + cb_log(4,0,"DL_DATA|CONFIRM\n"); + free_msg(msg); + return 1; + + case PH_CONTROL|CONFIRM: + cb_log(4,0,"PH_CONTROL|CONFIRM\n"); + free_msg(msg); + return 1; + case DL_DATA|INDICATION: { int port=(frm->addr&MASTER_ID_MASK) >> 8; @@ -3984,6 +4023,7 @@ struct misdn_bchannel *stack_holder_find(struct misdn_stack *stack, unsigned lon void misdn_lib_send_tone(struct misdn_bchannel *bc, enum tone_e tone) { + switch(tone) { case TONE_DIAL: manager_ph_control(bc, TONE_PATT_ON, TONE_GERMAN_DIALTONE); diff --git a/channels/misdn/isdn_lib.h b/channels/misdn/isdn_lib.h index 318fa9b6715e9c6cdde505f5fe134c041b4681ce..0178633cc51ac5f0e751b3947ee575d016e94ca3 100644 --- a/channels/misdn/isdn_lib.h +++ b/channels/misdn/isdn_lib.h @@ -406,6 +406,7 @@ void misdn_lib_split_bridge( struct misdn_bchannel * bc1, struct misdn_bchannel void misdn_lib_echo(struct misdn_bchannel *bc, int onoff); int misdn_lib_is_ptp(int port); +int misdn_lib_get_maxchans(int port); #define PRI_TRANS_CAP_SPEECH 0x0 #define PRI_TRANS_CAP_DIGITAL 0x08