diff --git a/channels/chan_misdn.c b/channels/chan_misdn.c index 399ec44942..d47eb3ce0d 100644 --- a/channels/chan_misdn.c +++ b/channels/chan_misdn.c @@ -806,7 +806,7 @@ static int misdn_set_crypt_debug(int fd, int argc, char *argv[]) static int misdn_port_block(int fd, int argc, char *argv[]) { int port; - + if (argc != 4) return RESULT_SHOWUSAGE; @@ -1278,6 +1278,25 @@ static int misdn_send_cd(int fd, int argc, char *argv[]) return 0; } +static int misdn_send_restart(int fd, int argc, char *argv[]) +{ + int port; + int channel; + + if ( (argc < 4) || (argc > 5) ) + return RESULT_SHOWUSAGE; + + port = atoi(argv[3]); + + if (argc==5) { + channel = atoi(argv[4]); + misdn_lib_send_restart(port, channel); + } else + misdn_lib_send_restart(port, -1 ); + + return 0; +} + static int misdn_send_digit(int fd, int argc, char *argv[]) { char *channame; @@ -1498,6 +1517,9 @@ static struct ast_cli_entry chan_misdn_clis[] = { "Usage: misdn port unblock\n" }, { {"misdn","restart","port", NULL}, misdn_restart_port, "Restarts the given port", "Usage: misdn restart port\n" }, + { {"misdn","send","restart", NULL}, misdn_send_restart, + "Sends a restart for every bchannel on the given port", + "Usage: misdn send restart \n"}, { {"misdn","restart","pid", NULL}, misdn_restart_pid, "Restarts the given pid", "Usage: misdn restart pid\n" }, { {"misdn","port","up", NULL}, misdn_port_up, "Tries to establish L1 on the given port", diff --git a/channels/misdn/ie.c b/channels/misdn/ie.c index 32f0b76c2e..4093805b5b 100644 --- a/channels/misdn/ie.c +++ b/channels/misdn/ie.c @@ -1402,3 +1402,21 @@ static void dec_ie_useruser(unsigned char *p, Q931_info_t *qi, int *protocol, ch } #endif +/* IE_DISPLAY */ +static void enc_ie_restart_ind(unsigned char **ntmode, msg_t *msg, unsigned char rind, int nt, struct misdn_bchannel *bc) +{ + unsigned char *p; + Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN); + /* if (MISDN_IE_DEBG) printf(" display='%s' (len=%d)\n", display, strlen((char *)display)); */ + + p = msg_put(msg, 3); + if (nt) + *ntmode = p+1; + else + qi->QI_ELEMENT(restart_ind) = p - (unsigned char *)qi - sizeof(Q931_info_t); + p[0] = IE_RESTART_IND; + p[1] = 1; + p[2] = rind; + +} + diff --git a/channels/misdn/isdn_lib.c b/channels/misdn/isdn_lib.c index 2757c27276..6a6ffb9ee6 100644 --- a/channels/misdn/isdn_lib.c +++ b/channels/misdn/isdn_lib.c @@ -1137,9 +1137,6 @@ int init_bc(struct misdn_stack *stack, struct misdn_bchannel *bc, int midev, in } - - - { stack_info_t *stinf; ret = mISDN_get_stack_info(midev, stack->port, buff, sizeof(buff)); @@ -3205,13 +3202,15 @@ void misdn_send_unlock(struct misdn_bchannel *bc); void misdn_send_lock(struct misdn_bchannel *bc) { //cb_log(0,bc->port,"Locking bc->pid:%d\n", bc->pid); - pthread_mutex_lock(&bc->send_lock->lock); + if (bc->send_lock) + pthread_mutex_lock(&bc->send_lock->lock); } void misdn_send_unlock(struct misdn_bchannel *bc) { //cb_log(0,bc->port,"UnLocking bc->pid:%d\n", bc->pid); - pthread_mutex_unlock(&bc->send_lock->lock); + if (bc->send_lock) + pthread_mutex_unlock(&bc->send_lock->lock); } int misdn_lib_send_event(struct misdn_bchannel *bc, enum event_e event ) @@ -3650,6 +3649,39 @@ int misdn_lib_pid_restart(int pid) return 0; } +/*Sends Restart message for every bchnanel*/ +int misdn_lib_send_restart(int port, int channel) +{ + struct misdn_stack *stack=find_stack_by_port(port); + cb_log(0, port, "Sending Restarts on this port.\n"); + + struct misdn_bchannel dummybc; + memset (&dummybc,0,sizeof(dummybc)); + dummybc.port=stack->port; + dummybc.l3_id=MISDN_ID_GLOBAL; + dummybc.nt=stack->nt; + + /*default is all channels*/ + int max=stack->pri?30:2; + int i=1; + + /*if a channel is specified we restart only this one*/ + if (channel > 0) { + i=channel; + max=channel; + } + + for (;i<=max;i++) { + dummybc.channel=i; + cb_log(0, port, "Restarting channel %d\n",i); + misdn_lib_send_event(&dummybc, EVENT_RESTART); + /*do we need to wait before we get an EVENT_RESTART_ACK ?*/ + } + + return 0; +} + +/*reinitializes the L2/L3*/ int misdn_lib_port_restart(int port) { struct misdn_stack *stack=find_stack_by_port(port); @@ -3768,7 +3800,18 @@ static void manager_event_handler(void *arg) } else { iframe_t *frm = (iframe_t *)msg->data; struct misdn_bchannel *bc = find_bc_by_l3id(stack, frm->dinfo); - if (bc) send_msg(glob_mgr->midev, bc, msg); + if (bc) + send_msg(glob_mgr->midev, bc, msg); + else { + if (frm->dinfo == MISDN_ID_GLOBAL) { + struct misdn_bchannel dummybc; + memset (&dummybc,0,sizeof(dummybc)); + dummybc.port=stack->port; + dummybc.l3_id=MISDN_ID_GLOBAL; + dummybc.nt=stack->nt; + send_msg(glob_mgr->midev, &dummybc, msg); + } + } } } } diff --git a/channels/misdn/isdn_lib.h b/channels/misdn/isdn_lib.h index af4f20feea..ce8900b27d 100644 --- a/channels/misdn/isdn_lib.h +++ b/channels/misdn/isdn_lib.h @@ -416,6 +416,7 @@ void isdn_lib_stop_dtmf (struct misdn_bchannel *bc); int misdn_lib_port_restart(int port); int misdn_lib_pid_restart(int pid); +int misdn_lib_send_restart(int port, int channel); int misdn_lib_get_port_info(int port); diff --git a/channels/misdn/isdn_msg_parser.c b/channels/misdn/isdn_msg_parser.c index 9388e47329..de39741848 100644 --- a/channels/misdn/isdn_msg_parser.c +++ b/channels/misdn/isdn_msg_parser.c @@ -838,6 +838,10 @@ static msg_t *build_restart (struct isdn_msg msgs[], struct misdn_bchannel *bc, #ifdef DEBUG printf("Building RESTART Msg\n"); #endif + enc_ie_channel_id(&restart->CHANNEL_ID, msg, 1,bc->channel, nt,bc); + enc_ie_restart_ind(&restart->RESTART_IND, msg, 0x80, nt, bc); + + cb_log(0,bc->port, "Restarting channel %d\n", bc->channel); return msg; }