[asterisk-commits] crichter: branch 1.4 r44559 - in
/branches/1.4/channels: ./ misdn/
asterisk-commits at lists.digium.com
asterisk-commits at lists.digium.com
Fri Oct 6 03:44:35 MST 2006
Author: crichter
Date: Fri Oct 6 05:44:34 2006
New Revision: 44559
URL: http://svn.digium.com/view/asterisk?rev=44559&view=rev
Log:
Merged revisions 44149 via svnmerge from
https://origsvn.digium.com/svn/asterisk/branches/1.2
........
r44149 | crichter | 2006-10-02 15:28:14 +0200 (Mo, 02 Okt 2006) | 1 line
fixed the hold/retrieve/transfer issues, removed a useless bc field, added setting of frame.delivery fields, some minor code cleanups
........
Modified:
branches/1.4/channels/chan_misdn.c
branches/1.4/channels/misdn/isdn_lib.c
branches/1.4/channels/misdn/isdn_lib.h
Modified: branches/1.4/channels/chan_misdn.c
URL: http://svn.digium.com/view/asterisk/branches/1.4/channels/chan_misdn.c?rev=44559&r1=44558&r2=44559&view=diff
==============================================================================
--- branches/1.4/channels/chan_misdn.c (original)
+++ branches/1.4/channels/chan_misdn.c Fri Oct 6 05:44:34 2006
@@ -130,12 +130,18 @@
MISDN_HUNGUP_FROM_AST, /*!< when DISCONNECT/RELEASE/REL_COMP came out of */
/* misdn_hangup */
MISDN_HOLDED, /*!< if this chan is holded */
- MISDN_HOLD_DISCONNECT /*!< if this chan is holded */
+ MISDN_HOLD_DISCONNECT, /*!< if this chan is holded */
+ MISDN_FIXUP/*!< if this chan is holded */
};
#define ORG_AST 1
#define ORG_MISDN 2
+
+struct hold_info {
+ int port;
+ int channel;
+};
struct chan_list {
@@ -180,7 +186,8 @@
int dummy;
struct misdn_bchannel *bc;
- struct misdn_bchannel *holded_bc;
+
+ struct hold_info hold_info;
unsigned int l3id;
int addr;
@@ -345,6 +352,13 @@
static int update_ec_config(struct misdn_bchannel *bc);
+
+
+
+
+/*protos*/
+
+int chan_misdn_jb_empty ( struct misdn_bchannel *bc, char *buf, int len);
/*************** Helpers *****************/
@@ -916,6 +930,7 @@
{MISDN_HUNGUP_FROM_MISDN,"HUNGUP_FROM_MISDN"}, /* when DISCONNECT/RELEASE/REL_COMP cam from misdn */
{MISDN_HOLDED,"HOLDED"}, /* when DISCONNECT/RELEASE/REL_COMP cam from misdn */
{MISDN_HOLD_DISCONNECT,"HOLD_DISCONNECT"}, /* when DISCONNECT/RELEASE/REL_COMP cam from misdn */
+ {MISDN_FIXUP,"FIXUP"}, /**/
{MISDN_HUNGUP_FROM_AST,"HUNGUP_FROM_AST"} /* when DISCONNECT/RELEASE/REL_COMP came out of */
/* misdn_hangup */
};
@@ -989,7 +1004,7 @@
" --> capability: %s\n"
" --> echo_cancel: %d\n"
" --> notone : rx %d tx:%d\n"
- " --> bc_hold: %d holded_bc :%d\n",
+ " --> bc_hold: %d\n",
help->ast->name,
help->l3id,
help->addr,
@@ -1003,7 +1018,7 @@
bc->ec_enable,
help->norxtone,help->notxtone,
- bc->holded, help->holded_bc?1:0
+ bc->holded
);
}
@@ -1020,11 +1035,23 @@
if (misdn_debug[0] > 2) ast_cli(fd, "Bc:%p Ast:%p\n", bc, ast);
if (bc) {
print_bc_info(fd, help, bc);
- } else if ( (bc=help->holded_bc) ) {
- chan_misdn_log(0, 0, "ITS A HOLDED BC:\n");
- print_bc_info(fd, help, bc);
} else {
- ast_cli(fd,"* Channel in unknown STATE !!! Exten:%s, Callerid:%s\n", ast->exten, AST_CID_P(ast));
+ if (help->state == MISDN_HOLDED) {
+ chan_misdn_log(0, 0, "ITS A HOLDED BC:\n");
+ chan_misdn_log(0,0," --> l3_id: %x\n"
+ " --> dad:%s oad:%s\n"
+ " --> hold_port: %d\n"
+ " --> hold_channel: %d\n"
+
+ ,help->l3id
+ ,ast->exten
+ ,AST_CID_P(ast)
+ ,help->hold_info.port
+ ,help->hold_info.channel
+ );
+ } else {
+ ast_cli(fd,"* Channel in unknown STATE !!! Exten:%s, Callerid:%s\n", ast->exten, AST_CID_P(ast));
+ }
}
}
@@ -2078,7 +2105,7 @@
chan_misdn_log(1, p->bc?p->bc->port:0, "* IND: Got Fixup State:%s L3id:%x\n", misdn_get_ch_state(p), p->l3id);
p->ast = ast ;
- p->state=MISDN_CONNECTED;
+ p->state=MISDN_FIXUP;
return 0;
}
@@ -2235,10 +2262,6 @@
bc=p->bc;
- if (!bc) {
- ast_log(LOG_WARNING,"Hangup with private but no bc ?\n");
- return 0;
- }
MISDN_ASTERISK_TECH_PVT(ast)=NULL;
@@ -2246,7 +2269,13 @@
bc=p->bc;
- if (ast->_state == AST_STATE_RESERVED || p->state == MISDN_NOTHING) {
+ if (ast->_state == AST_STATE_RESERVED ||
+ p->state == MISDN_NOTHING ||
+ p->state == MISDN_HOLDED ||
+ p->state == MISDN_FIXUP ||
+ p->state == MISDN_HOLD_DISCONNECT ) {
+
+ CLEAN_CH:
/* between request and call */
ast_log(LOG_DEBUG, "State Reserved (or nothing) => chanIsAvail\n");
MISDN_ASTERISK_TECH_PVT(ast)=NULL;
@@ -2261,6 +2290,12 @@
return 0;
}
+
+ if (!bc) {
+ ast_log(LOG_WARNING,"Hangup with private but no bc ? state:%s l3id:%x\n", misdn_get_ch_state(p), p->l3id);
+ goto CLEAN_CH;
+ }
+
p->need_hangup=0;
p->need_queue_hangup=0;
@@ -2474,6 +2509,7 @@
tmp->frame.samples = len;
tmp->frame.mallocd = 0;
tmp->frame.offset = 0;
+ tmp->frame.delivery= ast_tv(0,0) ;
tmp->frame.src = NULL;
tmp->frame.data = tmp->ast_rd_buf;
@@ -2514,17 +2550,17 @@
int i = 0;
if (!ast || ! (ch=MISDN_ASTERISK_TECH_PVT(ast)) ) return -1;
+
+ if (ch->state == MISDN_HOLDED) {
+ chan_misdn_log(7, 0, "misdn_write: Returning because holded\n");
+ return 0;
+ }
if (!ch->bc ) {
ast_log(LOG_WARNING, "private but no bc\n");
return -1;
}
- if (ch->state == MISDN_HOLDED) {
- chan_misdn_log(7, ch->bc->port, "misdn_write: Returning because holded\n");
- return 0;
- }
-
if (ch->notxtone) {
chan_misdn_log(7, ch->bc->port, "misdn_write: Returning because notxone\n");
return 0;
@@ -2571,7 +2607,7 @@
break;
default:
if (!ch->dropped_frame_cnt)
- chan_misdn_log(5, ch->bc->port, "BC not active (nor bridged) droping: %d frames addr:%x exten:%s cid:%s ch->state:%s bc_state:%d\n",frame->samples,ch->bc->addr, ast->exten, ast->cid.cid_num,misdn_get_ch_state( ch), ch->bc->bc_state);
+ chan_misdn_log(5, ch->bc->port, "BC not active (nor bridged) droping: %d frames addr:%x exten:%s cid:%s ch->state:%s bc_state:%d l3id:%x\n",frame->samples,ch->bc->addr, ast->exten, ast->cid.cid_num,misdn_get_ch_state( ch), ch->bc->bc_state, ch->bc->l3_id);
ch->dropped_frame_cnt++;
if (ch->dropped_frame_cnt > 100) {
@@ -3142,14 +3178,28 @@
chan_misdn_log(6, bc->port, "$$$ find_holded: channel:%d oad:%s dad:%s\n",bc->channel, bc->oad,bc->dad);
for (;help; help=help->next) {
- chan_misdn_log(4, bc->port, "$$$ find_holded: --> holded:%d channel:%d\n",help->bc->holded, help->bc->channel);
- if (help->bc->port == bc->port
- && help->bc->holded ) return help;
- }
-
+ chan_misdn_log(4, bc->port, "$$$ find_holded: --> holded:%d channel:%d\n",help->state==MISDN_HOLDED, help->hold_info.channel);
+ if ( (help->state == MISDN_HOLDED) &&
+ (help->hold_info.port == bc->port) )
+ return help;
+ }
chan_misdn_log(6, bc->port, "$$$ find_chan: No channel found for oad:%s dad:%s\n",bc->oad,bc->dad);
return NULL;
+}
+
+
+static struct chan_list *find_holded_l3(struct chan_list *list, unsigned long l3_id, int w)
+
+{
+ struct chan_list *help=list;
+
+ for (;help; help=help->next) {
+ if ( (help->state == MISDN_HOLDED) &&
+ (help->l3id == l3_id)
+ )
+ return help;
+ }
}
static void cl_queue_chan(struct chan_list **list, struct chan_list *chan)
@@ -3220,16 +3270,17 @@
static void hangup_chan(struct chan_list *ch)
{
+ int port=ch?ch->bc?ch->bc->port:0:0;
if (!ch) {
cb_log(1,0,"Cannot hangup chan, no ch\n");
return;
}
- cb_log(1,ch->bc?ch->bc->port:0,"hangup_chan\n");
+ cb_log(1,port,"hangup_chan\n");
if (ch->need_hangup)
{
- cb_log(1,ch->bc->port,"-> hangup\n");
+ cb_log(1,port,"-> hangup\n");
send_cause2ast(ch->ast,ch->bc,ch);
ch->need_hangup=0;
ch->need_queue_hangup=0;
@@ -3239,7 +3290,7 @@
}
if (!ch->need_queue_hangup) {
- cb_log(1,ch->bc->port,"No need to queue hangup\n");
+ cb_log(1,port,"No need to queue hangup\n");
}
ch->need_queue_hangup=0;
@@ -3248,9 +3299,9 @@
if (ch->ast)
ast_queue_hangup(ch->ast);
- cb_log(1,ch->bc->port,"-> queue_hangup\n");
+ cb_log(1,port,"-> queue_hangup\n");
} else {
- cb_log(1,ch->bc->port,"Cannot hangup chan, no ast\n");
+ cb_log(1,port,"Cannot hangup chan, no ast\n");
}
}
@@ -3260,7 +3311,7 @@
{
struct chan_list *ch=find_chan_by_bc(cl_te, bc);
if (!ch) {
- chan_misdn_log(0, bc->port, "release_chan: Ch not found!\n");
+ chan_misdn_log(1, bc->port, "release_chan: Ch not found!\n");
return;
}
@@ -3331,7 +3382,7 @@
ast_moh_stop(AST_BRIDGED_P(holded_chan->ast));
holded_chan->state=MISDN_CONNECTED;
- misdn_lib_transfer(holded_chan->bc?holded_chan->bc:holded_chan->holded_bc);
+ //misdn_lib_transfer(holded_chan->bc);
ast_channel_masquerade(holded_chan->ast, AST_BRIDGED_P(tmp_ch->ast));
}
@@ -3389,6 +3440,7 @@
fr.samples = 0 ;
fr.mallocd =0 ;
fr.offset= 0 ;
+ fr.delivery= ast_tv(0,0) ;
if (ch->ast && MISDN_ASTERISK_PVT(ch->ast) && MISDN_ASTERISK_TECH_PVT(ch->ast)) {
ast_queue_frame(ch->ast, &fr);
@@ -3630,6 +3682,7 @@
fr.samples = 0 ;
fr.mallocd =0 ;
fr.offset= 0 ;
+ fr.delivery= ast_tv(0,0) ;
if (!ch->ignore_dtmf) {
chan_misdn_log(2, bc->port, " --> DTMF:%c\n", bc->dtmf);
@@ -3732,6 +3785,7 @@
fr.samples = 0 ;
fr.mallocd =0 ;
fr.offset= 0 ;
+ fr.delivery= ast_tv(0,0) ;
int digits;
@@ -3756,9 +3810,15 @@
case EVENT_SETUP:
{
struct chan_list *ch=find_chan_by_bc(cl_te, bc);
- if (ch && ch->state != MISDN_NOTHING ) {
- chan_misdn_log(1, bc->port, " --> Ignoring Call we have already one\n");
- return RESPONSE_IGNORE_SETUP_WITHOUT_CLOSE;
+ if (ch) {
+ switch (ch->state) {
+ case MISDN_NOTHING:
+ ch=NULL;
+ break;
+ default:
+ chan_misdn_log(1, bc->port, " --> Ignoring Call we have already one\n");
+ return RESPONSE_IGNORE_SETUP_WITHOUT_CLOSE; /* Ignore MSNs which are not in our List */
+ }
}
}
@@ -4100,9 +4160,7 @@
}
}
-
/* notice that we don't break here!*/
-
case EVENT_CONNECT_ACKNOWLEDGE:
{
ch->l3id=bc->l3_id;
@@ -4135,18 +4193,22 @@
}
/*Check for holded channel, to implement transfer*/
- if (holded_ch && ch->ast ) {
+ if ( holded_ch &&
+ holded_ch != ch &&
+ ch->ast &&
+ ch->state == MISDN_CONNECTED ) {
cb_log(1,bc->port," --> found holded ch\n");
- if (ch->state == MISDN_CONNECTED ) {
- misdn_transfer_bc(ch, holded_ch) ;
- hangup_chan(ch);
- // release_chan(bc);
- break;
- }
+ misdn_transfer_bc(ch, holded_ch) ;
}
stop_bc_tones(ch);
hangup_chan(ch);
+ } else {
+ /* ch=find_holded_l3(cl_te, bc->l3_id,1);
+ if (ch) {
+ hangup_chan(ch);
+ }
+ */
}
bc->out_cause=-1;
if (bc->need_release) misdn_lib_send_event(bc,EVENT_RELEASE);
@@ -4237,6 +4299,7 @@
frame.samples = bc->bframe_len ;
frame.mallocd =0 ;
frame.offset= 0 ;
+ frame.delivery= ast_tv(0,0) ;
frame.src = NULL;
frame.data = bc->bframe ;
@@ -4327,23 +4390,25 @@
/***************************/
case EVENT_RETRIEVE:
{
- ch=find_holded(cl_te, bc);
+ ch=find_holded_l3(cl_te, bc->l3_id,1);
if (!ch) {
ast_log(LOG_WARNING, "Found no Holded channel, cannot Retrieve\n");
misdn_lib_send_event(bc, EVENT_RETRIEVE_REJECT);
break;
}
+
+ /*remember the channel again*/
+ ch->bc=bc;
+ ch->state = MISDN_CONNECTED;
+
struct ast_channel *hold_ast=AST_BRIDGED_P(ch->ast);
- ch->state = MISDN_CONNECTED;
if (hold_ast) {
ast_moh_stop(hold_ast);
}
-
+
if ( misdn_lib_send_event(bc, EVENT_RETRIEVE_ACKNOWLEDGE) < 0)
misdn_lib_send_event(bc, EVENT_RETRIEVE_REJECT);
-
-
}
break;
@@ -4358,31 +4423,25 @@
misdn_lib_send_event(bc, EVENT_HOLD_REJECT);
break;
}
-
-#if 0
- {
- struct chan_list *holded_ch=find_holded(cl_te, bc);
- if (holded_ch) {
- misdn_lib_send_event(bc, EVENT_HOLD_REJECT);
-
- chan_misdn_log(-1, bc->port, "We can't use RETRIEVE at the moment due to mISDN bug!\n");
- break;
- }
- }
-#endif
+
struct ast_channel *bridged=AST_BRIDGED_P(ch->ast);
-
- if (bridged){
- struct chan_list *bridged_ch=MISDN_ASTERISK_TECH_PVT(bridged);
+
+ if (bridged) {
+ chan_misdn_log(2,bc->port,"Bridge Partner is of type: %s\n",bridged->tech->type);
ch->state = MISDN_HOLDED;
ch->l3id = bc->l3_id;
- bc->holded_bc=bridged_ch->bc;
misdn_lib_send_event(bc, EVENT_HOLD_ACKNOWLEDGE);
/* XXX This should queue an AST_CONTROL_HOLD frame on this channel
* instead of starting moh on the bridged channel directly */
ast_moh_start(bridged, NULL, NULL);
+
+ /*forget the channel now*/
+ ch->bc=NULL;
+ ch->hold_info.port=bc->port;
+ ch->hold_info.channel=bc->channel;
+
} else {
misdn_lib_send_event(bc, EVENT_HOLD_REJECT);
chan_misdn_log(0, bc->port, "We aren't bridged to anybody\n");
Modified: branches/1.4/channels/misdn/isdn_lib.c
URL: http://svn.digium.com/view/asterisk/branches/1.4/channels/misdn/isdn_lib.c?rev=44559&r1=44558&r2=44559&view=diff
==============================================================================
--- branches/1.4/channels/misdn/isdn_lib.c (original)
+++ branches/1.4/channels/misdn/isdn_lib.c Fri Oct 6 05:44:34 2006
@@ -501,7 +501,8 @@
void bc_state_change(struct misdn_bchannel *bc, enum bchannel_state state)
{
- cb_log(5,bc->port,"BC_STATE_CHANGE: from:%s to:%s\n",
+ cb_log(5,bc->port,"BC_STATE_CHANGE: l3id:%x from:%s to:%s\n",
+ bc->l3_id,
bc_state2str(bc->bc_state),
bc_state2str(state) );
@@ -616,8 +617,6 @@
bc->fac_out.Function = Fac_None;
bc->te_choose_channel = 0;
-
- bc->holded_bc=NULL;
}
@@ -1408,21 +1407,33 @@
struct misdn_stack* stack;
int i;
-
for (stack=glob_mgr->stack_list;
stack;
stack=stack->next) {
-
for (i=0; i< stack->b_num; i++) {
-
if ( (stack->bc[i].addr&STACK_ID_MASK)==(addr&STACK_ID_MASK) || stack->bc[i].layer_id== addr ) {
return &stack->bc[i];
}
}
-
- }
-
-
+ }
+
+ return NULL;
+}
+
+struct misdn_bchannel *find_bc_by_confid(unsigned long confid)
+{
+ struct misdn_stack* stack;
+ int i;
+
+ for (stack=glob_mgr->stack_list;
+ stack;
+ stack=stack->next) {
+ for (i=0; i< stack->b_num; i++) {
+ if ( stack->bc[i].conf_id==confid ) {
+ return &stack->bc[i];
+ }
+ }
+ }
return NULL;
}
@@ -1745,16 +1756,17 @@
struct misdn_bchannel *bc=find_bc_by_l3id(stack, hh->dinfo);
struct misdn_bchannel *hold_bc=stack_holder_find(stack,bc->l3_id);
+ cb_log(4, stack->port, "bc_l3id:%x holded_bc_l3id:%x\n",bc->l3_id, hold_bc->l3_id);
if (hold_bc) {
-
cb_log(4, stack->port, "REMOVEING Holder\n");
+
+ /*swap the backup to our new channel back*/
stack_holder_remove(stack, hold_bc);
-
memcpy(bc,hold_bc,sizeof(struct misdn_bchannel));
- cb_event(EVENT_NEW_BC, hold_bc, bc);
-
free(hold_bc);
+
+ bc->holded=0;
}
}
@@ -3178,8 +3190,6 @@
case EVENT_CONNECT:
case EVENT_RETRIEVE_ACKNOWLEDGE:
- bc->holded=0;
-
if (stack->nt) {
if (bc->channel <=0 ) { /* else we have the channel already */
bc->channel = find_free_chan_in_stack(stack, bc, 0);
@@ -3198,9 +3208,6 @@
cb_log(0,bc->port,"send_event: setup_bc failed\n");
}
- cb_log(0,bc->port,"After SETUP BC\n");
-
-
if (misdn_cap_is_speech(bc->capability)) {
if ((event==EVENT_CONNECT)||(event==EVENT_RETRIEVE_ACKNOWLEDGE)) {
if ( *bc->crypt_key ) {
@@ -3228,14 +3235,27 @@
case EVENT_HOLD_ACKNOWLEDGE:
{
struct misdn_bchannel *holded_bc=malloc(sizeof(struct misdn_bchannel));
+ if (!holded_bc) {
+ cb_log(0,bc->port, "Could not allocate holded_bc!!!\n");
+ return -1;
+ }
+
+ /*backup the bc*/
memcpy(holded_bc,bc,sizeof(struct misdn_bchannel));
holded_bc->holded=1;
+ bc_state_change(holded_bc,BCHAN_CLEANED);
+
stack_holder_add(stack,holded_bc);
-
+
+ /*kill the bridge and clean the bchannel*/
if (stack->nt) {
if (bc->bc_state == BCHAN_BRIDGED) {
misdn_split_conf(bc,bc->conf_id);
- misdn_split_conf(bc->holded_bc,bc->holded_bc->conf_id);
+ struct misdn_bchannel *bc2=find_bc_by_confid(bc->conf_id);
+ if (!bc2)
+ cb_log(0,bc->port,"We have no second bc in bridge???\n");
+ else
+ misdn_split_conf(bc2,bc->conf_id);
}
if (bc->channel>0)
@@ -3244,11 +3264,6 @@
clean_up_bc(bc);
}
- /** we set it up later at RETRIEVE_ACK again.**/
- /*holded_bc->upset=0;
- holded_bc->active=0;*/
- bc_state_change(holded_bc,BCHAN_CLEANED);
- cb_event( EVENT_NEW_BC, bc, holded_bc);
}
break;
@@ -4084,6 +4099,27 @@
}
}
+struct misdn_bchannel *stack_holder_find_bychan(struct misdn_stack *stack, int chan)
+{
+ struct misdn_bchannel *help;
+
+ cb_log(4,stack?stack->port:0, "*HOLDER: find_bychan %c\n", chan);
+
+ if (!stack) return NULL;
+
+ for (help=stack->holding;
+ help;
+ help=help->next) {
+ if (help->channel == chan) {
+ cb_log(4,stack->port, "*HOLDER: found_bychan bc\n");
+ return help;
+ }
+ }
+
+ cb_log(4,stack->port, "*HOLDER: find_bychan nothing\n");
+ return NULL;
+
+}
struct misdn_bchannel *stack_holder_find(struct misdn_stack *stack, unsigned long l3id)
{
Modified: branches/1.4/channels/misdn/isdn_lib.h
URL: http://svn.digium.com/view/asterisk/branches/1.4/channels/misdn/isdn_lib.h?rev=44559&r1=44558&r2=44559&view=diff
==============================================================================
--- branches/1.4/channels/misdn/isdn_lib.h (original)
+++ branches/1.4/channels/misdn/isdn_lib.h Fri Oct 6 05:44:34 2006
@@ -294,8 +294,6 @@
int holded;
int stack_holder;
- struct misdn_bchannel *holded_bc;
-
int pres;
int screen;
More information about the asterisk-commits
mailing list