#endif
" --> notone : rx %d tx:%d\n"
" --> bc_hold: %d\n",
- help->ast->name,
+ ast ? ast->name : "",
help->l3id,
help->addr,
bc->addr,
continue;
}
ast_cli(a->fd, "bc with pid:%d has no Ast Leg\n", bc->pid);
- continue;
}
if (misdn_debug[0] > 2) {
return -1;
}
- chan_misdn_log(5, p->bc->port, "* IND : Indication [%d] on %s\n\n", cond, ast->name);
+ chan_misdn_log(5, p->bc->port, "* IND : Indication [%d] on %s\n", cond, ast->name);
switch (cond) {
case AST_CONTROL_BUSY:
tmp = ast_channel_alloc(1, state, cid_num, cid_name, "", exten, "", linkedid, 0, "%s/%s%d-u%d", misdn_type, c ? "" : "tmp", chan_offset + c, glob_channel++);
if (tmp) {
- chan_misdn_log(2, 0, " --> * NEW CHANNEL dialed:%s caller:%s\n", exten, callerid);
+ chan_misdn_log(2, port, " --> * NEW CHANNEL dialed:%s caller:%s\n", exten, callerid);
ast_best_codec(cap, &tmpfmt);
ast_format_cap_add(tmp->nativeformats, &prefformat);
static void hangup_chan(struct chan_list *ch, struct misdn_bchannel *bc)
{
- int port;
+ int port = bc->port;
if (!ch) {
- cb_log(1, 0, "Cannot hangup chan, no ch\n");
+ cb_log(1, port, "Cannot hangup chan, no ch\n");
return;
}
- port = bc->port;
cb_log(5, port, "hangup_chan called\n");
if (ch->need_hangup) {
ch = chan_list_init(ORG_MISDN);
if (!ch) {
chan_misdn_log(-1, bc->port, "cb_events: malloc for chan_list failed!\n");
- return 0;
+ return RESPONSE_RELEASE_SETUP;
}
ch->bc = bc;
}
if (!chan) {
chan_list_unref(ch, "Failed to create a new channel");
- misdn_lib_send_event(bc,EVENT_RELEASE_COMPLETE);
- ast_log(LOG_ERROR, "cb_events: misdn_new failed !\n");
- return 0;
+ ast_log(LOG_ERROR, "cb_events: misdn_new failed!\n");
+ return RESPONSE_RELEASE_SETUP;
}
if ((exceed = add_in_calls(bc->port))) {
break;
}
- /** queue new chan **/
- cl_queue_chan(ch);
-
if (!strstr(ch->allowed_bearers, "all")) {
int i;
/* We did not find the bearer capability */
chan_misdn_log(0, bc->port, "Bearer capability not allowed: %s(%d)\n",
bearer2str(bc->capability), bc->capability);
- bc->out_cause = AST_CAUSE_INCOMPATIBLE_DESTINATION;
ch->state = MISDN_EXTCANTMATCH;
- misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE);
chan_list_unref(ch, "BC not allowed, releasing call");
- return RESPONSE_OK;
+ bc->out_cause = AST_CAUSE_INCOMPATIBLE_DESTINATION;
+ return RESPONSE_RELEASE_SETUP;
}
}
+ /** queue new chan **/
+ cl_queue_chan(ch);
+
if (bc->fac_in.Function != Fac_None) {
misdn_facility_ie_handler(event, bc, ch);
}
char port_buf[8];
if (!(0 <= port && port <= max_ports)) {
- ast_log(LOG_WARNING, "cb_log called with out-of-range port number! (%d)\n", port);
+ ast_log(LOG_WARNING, "chan_misdn_log called with out-of-range port number! (%d)\n", port);
port = 0;
level = -1;
} else if (!(level == -1
void misdn_join_conf(struct misdn_bchannel *bc, int conf_id);
void misdn_split_conf(struct misdn_bchannel *bc, int conf_id);
-int queue_cleanup_bc(struct misdn_bchannel *bc) ;
-
int misdn_lib_get_l2_up(struct misdn_stack *stack);
struct misdn_stack *get_misdn_stack(void);
struct misdn_lib {
/*! \brief mISDN device handle returned by mISDN_open() */
int midev;
- int midev_nt; /* Not used */
pthread_t event_thread;
pthread_t event_handler_thread;
void *user_data;
- msg_queue_t upqueue;
msg_queue_t activatequeue;
sem_t new_msg;
struct misdn_bchannel *find_bc_by_l3id(struct misdn_stack *stack, unsigned long l3id);
-int setup_bc(struct misdn_bchannel *bc);
-
int manager_isdn_handler(iframe_t *frm ,msg_t *msg);
int misdn_lib_port_restart(int port);
} states[] = {
{"BCHAN_CLEANED", BCHAN_CLEANED },
{"BCHAN_EMPTY", BCHAN_EMPTY},
- {"BCHAN_SETUP", BCHAN_SETUP},
- {"BCHAN_SETUPED", BCHAN_SETUPED},
- {"BCHAN_ACTIVE", BCHAN_ACTIVE},
{"BCHAN_ACTIVATED", BCHAN_ACTIVATED},
- {"BCHAN_BRIDGE", BCHAN_BRIDGE},
{"BCHAN_BRIDGED", BCHAN_BRIDGED},
{"BCHAN_RELEASE", BCHAN_RELEASE},
- {"BCHAN_RELEASED", BCHAN_RELEASED},
- {"BCHAN_CLEAN", BCHAN_CLEAN},
- {"BCHAN_CLEAN_REQUEST", BCHAN_CLEAN_REQUEST},
{"BCHAN_ERROR", BCHAN_ERROR}
};
unsigned char buff[32];
struct misdn_stack * stack;
- cb_log(3, bc?bc->port:0, "$$$ CLEANUP CALLED pid:%d\n", bc?bc->pid:-1);
+ cb_log(3, bc->port, "$$$ CLEANUP CALLED pid:%d\n", bc->pid);
- if (!bc ) return -1;
stack=get_stack_by_bc(bc);
if (!stack) return -1;
}
-void misdn_lib_setup_bc(struct misdn_bchannel *bc)
-{
- clean_up_bc(bc);
- setup_bc(bc);
-}
-
-
-int setup_bc(struct misdn_bchannel *bc)
+static int setup_bc(struct misdn_bchannel *bc)
{
unsigned char buff[1025];
int midev;
pthread_mutex_init(&bc->send_lock->lock, NULL);
empty_bc(bc);
- bc_state_change(bc, BCHAN_CLEANED);
bc->port=stack->port;
+ bc_state_change(bc, BCHAN_CLEANED);
bc->nt=stack->nt?1:0;
bc->pri=stack->pri;
stack->pri=0;
msg_queue_init(&stack->downqueue);
- msg_queue_init(&stack->upqueue);
pthread_mutex_init(&stack->st_lock, NULL);
switch(stinf->pid.protocol[0] & ~ISDN_PID_FEATURE_MASK) {
case ISDN_PID_L0_TE_S0:
+ cb_log(8, port, "TE Stack\n");
stack->nt=0;
break;
case ISDN_PID_L0_NT_S0:
cb_log(8, port, "NT Stack\n");
-
stack->nt=1;
break;
case ISDN_PID_L0_TE_E1:
stack->pri=1;
break;
case ISDN_PID_L0_NT_E1:
- cb_log(8, port, "TE S2M Stack\n");
+ cb_log(8, port, "NT S2M Stack\n");
stack->nt=1;
stack->pri=1;
-
break;
default:
cb_log(0, port, "this is a unknown port type 0x%08x\n", stinf->pid.protocol[0]);
int ret;
int nt=stack->nt;
- cb_log(8, port, "Init. Stack.\n");
-
memset(&li, 0, sizeof(li));
{
int l = sizeof(li.name);
return(NULL);
}
- cb_log(8, port, "NT Stacks upper_id %x\n",stack->upper_id);
-
-
/* create nst (nt-mode only) */
if (nt) {
}
- cb_log(8,0,"stack_init: port:%d lowerId:%x upperId:%x\n",stack->port,stack->lower_id, stack->upper_id);
+ cb_log(8, port, "stack_init: lowerId:%x upperId:%x\n", stack->lower_id, stack->upper_id);
return stack;
}
-static int handle_event ( struct misdn_bchannel *bc, enum event_e event, iframe_t *frm)
+static int handle_event_te(struct misdn_bchannel *bc, enum event_e event, iframe_t *frm)
{
struct misdn_stack *stack=get_stack_by_bc(bc);
- if (!stack->nt) {
-
- switch (event) {
-
+ switch (event) {
case EVENT_CONNECT_ACKNOWLEDGE:
setup_bc(bc);
return -1;
}
- setup_bc(bc);
+ if (event != EVENT_SETUP) {
+ setup_bc(bc);
+ }
break;
}
break;
default:
break;
- }
- } else { /** NT MODE **/
-
}
return 0;
}
if (stack->l2upcnt>3) {
cb_log(0 , stack->port, "!!! Could not Get the L2 up after 3 Attempts!!!\n");
} else {
-#if 0
- if (stack->nt)
- misdn_lib_reinit_nt_stack(stack->port);
-#endif
if (stack->l1link) {
misdn_lib_get_l2_up(stack);
stack->l2upcnt++;
case MGR_SETSTACK| INDICATION:
cb_log(3, stack->port, "BCHAN: MGR_SETSTACK|IND pid:%d\n",bc->pid);
break;
-#if 0
- AGAIN:
- bc->addr = mISDN_get_layerid(stack->midev, bc->b_stid, bc->layer);
- if (!bc->addr) {
-
- if (errno == EAGAIN) {
- usleep(1000);
- goto AGAIN;
- }
-
- cb_log(0,stack->port,"$$$ Get Layer (%d) Id Error: %s\n",bc->layer,strerror(errno));
-
- /* we kill the channel later, when we received some
- data. */
- bc->addr= frm->addr;
- } else if ( bc->addr < 0) {
- cb_log(0, stack->port,"$$$ bc->addr <0 Error:%s\n",strerror(errno));
- bc->addr=0;
- }
-
- cb_log(4, stack->port," --> Got Adr %x\n", bc->addr);
-
- free_msg(msg);
-
-
- switch(bc->bc_state) {
- case BCHAN_SETUP:
- bc_state_change(bc,BCHAN_SETUPED);
- break;
-
- case BCHAN_CLEAN_REQUEST:
- default:
- cb_log(0, stack->port," --> STATE WASN'T SETUP (but %s) in SETSTACK|IND pid:%d\n",bc_state2str(bc->bc_state), bc->pid);
- clean_up_bc(bc);
- }
- return 1;
-#endif
case MGR_DELLAYER| INDICATION:
cb_log(3, stack->port, "BCHAN: MGR_DELLAYER|IND pid:%d\n",bc->pid);
}
-static int handle_frm(msg_t *msg)
+static int handle_frm_te(msg_t *msg)
{
struct misdn_bchannel dummybc;
struct misdn_bchannel *bc;
return 0;
}
- cb_log(4, stack ? stack->port : 0, "handle_frm: frm->addr:%x frm->prim:%x\n", frm->addr, frm->prim);
+ cb_log(4, stack->port, "handle_frm_te: frm->addr:%x frm->prim:%x\n", frm->addr, frm->prim);
ret = handle_cr(stack, frm);
if (ret < 0) {
- cb_log(3, stack ? stack->port : 0, "handle_frm: handle_cr <0 prim:%x addr:%x\n", frm->prim, frm->addr);
+ cb_log(3, stack->port, "handle_frm_te: handle_cr <0 prim:%x addr:%x\n", frm->prim, frm->addr);
}
if (ret) {
free_msg(msg);
isdn_msg_parse_event(msgs_g, msg, bc, 0);
/* Preprocess some Events */
- ret = handle_event(bc, event, frm);
+ ret = handle_event_te(bc, event, frm);
if (ret < 0) {
cb_log(0, stack->port, "couldn't handle event\n");
free_msg(msg);
cb_log(0, stack->port, "TOTALLY IGNORING SETUP\n");
break;
case RESPONSE_IGNORE_SETUP:
+ cb_log(0, stack->port, "GOT IGNORE SETUP\n");
/* I think we should send CC_RELEASE_CR, but am not sure*/
bc->out_cause = AST_CAUSE_NORMAL_CLEARING;
/* fall through */
case RESPONSE_RELEASE_SETUP:
- misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE);
- if (bc->channel > 0) {
- empty_chan_in_stack(stack, bc->channel);
+ if (response == RESPONSE_RELEASE_SETUP) {
+ cb_log(0, stack->port, "GOT RELEASE SETUP\n");
}
- empty_bc(bc);
- bc_state_change(bc, BCHAN_CLEANED);
- bc->in_use = 0;
-
- cb_log(0, stack->port, "GOT IGNORE SETUP\n");
+ misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE);
break;
case RESPONSE_OK:
cb_log(4, stack->port, "GOT SETUP OK\n");
break;
default:
+ cb_log(0, stack->port, "GOT UNKNOWN SETUP RESPONSE\n");
break;
}
break;
if (++mypid>5000) mypid=1;
bc->pid=mypid;
-#if 0
- bc->addr=0;
- bc->b_stid=0;
- bc->layer_id=0;
-#endif
-
bc->in_use = 1;
}
case EVENT_PROCEEDING:
case EVENT_SETUP_ACKNOWLEDGE:
case EVENT_CONNECT:
- if (!stack->nt)
+ if (!stack->nt) {
+ if (stack->ptp) {
+ setup_bc(bc);
+ }
break;
+ }
+ /* fall through */
case EVENT_RETRIEVE_ACKNOWLEDGE:
if (stack->nt) {
cb_log(0, bc->port, " --> we have already sent DISCONNECT\n");
RETURN(-1,OUT);
}
+ /* IE cause is mandatory for DISCONNECT, but optional for the answers to DISCONNECT.
+ * We must initialize cause, so it is later correctly indicated to ast_channel
+ * in case the answer does not include one!
+ */
+ bc->cause = bc->out_cause;
bc->need_disconnect=0;
break;
return 0;
}
-#if 0
-static int queue_l2l3(msg_t *msg)
-{
- iframe_t *frm= (iframe_t*)msg->data;
- struct misdn_stack *stack;
- stack=find_stack_by_addr( frm->addr );
-
-
- if (!stack) {
- return 0;
- }
-
- msg_queue_tail(&stack->upqueue, msg);
- sem_post(&glob_mgr->new_msg);
- return 1;
-}
-#endif
-
int manager_isdn_handler(iframe_t *frm ,msg_t *msg)
{
}
#ifdef RECV_FRM_SYSLOG_DEBUG
- syslog(LOG_NOTICE,"mISDN recv: P(%02d): ADDR:%x PRIM:%x DINFO:%x\n",stack->port, frm->addr, frm->prim, frm->dinfo);
+ syslog(LOG_NOTICE,"mISDN recv: ADDR:%x PRIM:%x DINFO:%x\n", frm->addr, frm->prim, frm->dinfo);
#endif
if (handle_timers(msg))
return 0;
}
- if (handle_frm(msg)) {
+ if (handle_frm_te(msg)) {
return 0;
}
return 0;
}
-
-int queue_cleanup_bc(struct misdn_bchannel *bc)
-{
- msg_t *msg=alloc_msg(MAX_MSG_SIZE);
- iframe_t *frm;
- if (!msg) {
- cb_log(0, bc->port, "queue_cleanup_bc: alloc_msg failed!\n");
- return -1;
- }
- frm=(iframe_t*)msg->data;
-
- /* activate bchannel */
- frm->prim = MGR_CLEARSTACK| REQUEST;
-
- frm->addr = bc->l3_id;
-
- frm->dinfo = bc->port;
- frm->len = 0;
-
- msg_queue_tail(&glob_mgr->activatequeue, msg);
- sem_post(&glob_mgr->new_msg);
-
- return 0;
-
-}
-
int misdn_lib_pid_restart(int pid)
{
struct misdn_bchannel *bc=manager_find_bc_by_pid(pid);
iframe_t *frm = (iframe_t*) msg->data ;
switch ( frm->prim) {
-
- case MGR_CLEARSTACK | REQUEST:
- /*a queued bchannel cleanup*/
- {
- struct misdn_stack *stack=find_stack_by_port(frm->dinfo);
- struct misdn_bchannel *bc;
- if (!stack) {
- cb_log(0,0,"no stack found with port [%d]!! so we cannot cleanup the bc\n",frm->dinfo);
- free_msg(msg);
- break;
- }
-
- bc = find_bc_by_l3id(stack, frm->addr);
- if (bc) {
- cb_log(1,bc->port,"CLEARSTACK queued, cleaning up\n");
- clean_up_bc(bc);
- } else {
- cb_log(0,stack->port,"bc could not be cleaned correctly !! addr [%x]\n",frm->addr);
- }
- }
- free_msg(msg);
- break;
case MGR_SETSTACK | REQUEST :
free_msg(msg);
break;
for (stack=glob_mgr->stack_list;
stack;
stack=stack->next ) {
-
- while ( (msg=msg_dequeue(&stack->upqueue)) ) {
- /** Handle L2/3 Signalling after bchans **/
- if (!handle_frm_nt(msg)) {
- /* Maybe it's TE */
- if (!handle_frm(msg)) {
- /* wow none! */
- cb_log(0,stack->port,"Wow we've got a strange issue while dequeueing a Frame\n");
- }
- }
- }
-
/* Here we should check if we really want to
send all the messages we've queued, lets
assume we've queued a Disconnect, but
{
struct misdn_bchannel *help;
- cb_log(4,stack?stack->port:0, "*HOLDER: find %lx\n",l3id);
-
- if (!stack) return NULL;
+ cb_log(4, stack->port, "*HOLDER: find %lx\n",l3id);
for (help=stack->holding;
help;
{
int protocol ;
dec_ie_useruser(setup->USER_USER, (Q931_info_t *)setup, &protocol, bc->uu, &bc->uulen, nt,bc);
- if (bc->uulen) cb_log(1,bc->port,"USERUESRINFO:%s\n",bc->uu);
+ if (bc->uulen) cb_log(1, bc->port, "USERUSERINFO:%s\n", bc->uu);
else
- cb_log(1,bc->port,"NO USERUESRINFO\n");
+ cb_log(1, bc->port, "NO USERUSERINFO\n");
}
dec_ie_progress(setup->PROGRESS, (Q931_info_t *)setup, &bc->progress_coding, &bc->progress_location, &bc->progress_indicator, nt, bc);
if (bc->uulen) {
int protocol=4;
enc_ie_useruser(&setup->USER_USER, msg, protocol, bc->uu, bc->uulen, nt,bc);
- cb_log(1,bc->port,"ENCODING USERUESRINFO:%s\n",bc->uu);
+ cb_log(1, bc->port, "ENCODING USERUSERINFO:%s\n", bc->uu);
}
#if defined(AST_MISDN_ENHANCEMENTS)
if (bc->uulen) {
int protocol=4;
enc_ie_useruser(&disconnect->USER_USER, msg, protocol, bc->uu, bc->uulen, nt,bc);
- cb_log(1,bc->port,"ENCODING USERUESRINFO:%s\n",bc->uu);
+ cb_log(1, bc->port, "ENCODING USERUSERINFO:%s\n", bc->uu);
}
#ifdef DEBUG
if (bc->uulen) {
int protocol=4;
enc_ie_useruser(&release->USER_USER, msg, protocol, bc->uu, bc->uulen, nt,bc);
- cb_log(1,bc->port,"ENCODING USERUESRINFO:%s\n",bc->uu);
+ cb_log(1, bc->port, "ENCODING USERUSERINFO:%s\n", bc->uu);
}
#ifdef DEBUG
if (bc->uulen) {
int protocol=4;
enc_ie_useruser(&release_complete->USER_USER, msg, protocol, bc->uu, bc->uulen, nt,bc);
- cb_log(1,bc->port,"ENCODING USERUESRINFO:%s\n",bc->uu);
+ cb_log(1, bc->port, "ENCODING USERUSERINFO:%s\n", bc->uu);
}
#ifdef DEBUG