* Introducing a new way for the l1watcher thread using the ast_sched way. Now l1watcher timeouts can be configured separately for every portgroup.

* added a signal handler to allow waking up the misdn task thread (that may sleep in a poll call) via misdn_tasks_wakeup().
* overlap_dial functionality implemented.
* fixes a bug which leads to a segfault after reordering config elements in the enum or struct



git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@37382 65c4cc65-6c06-0410-ace0-fbb531ad65f3
1.4
Christian Richter 20 years ago
parent ba092c1244
commit 94274cc26b

@ -41,7 +41,10 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include <arpa/inet.h> #include <arpa/inet.h>
#include <fcntl.h> #include <fcntl.h>
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <signal.h>
#include <sys/file.h> #include <sys/file.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include "asterisk/channel.h" #include "asterisk/channel.h"
#include "asterisk/config.h" #include "asterisk/config.h"
@ -63,6 +66,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include "asterisk/app.h" #include "asterisk/app.h"
#include "asterisk/features.h" #include "asterisk/features.h"
#include "asterisk/term.h" #include "asterisk/term.h"
#include "asterisk/sched.h"
#include "asterisk/stringfields.h" #include "asterisk/stringfields.h"
#include "chan_misdn_config.h" #include "chan_misdn_config.h"
@ -101,12 +105,6 @@ of data. */
int misdn_jb_empty(struct misdn_jb *jb, char *data, int len); int misdn_jb_empty(struct misdn_jb *jb, char *data, int len);
/* BEGIN: chan_misdn.h */
enum misdn_chan_state { enum misdn_chan_state {
MISDN_NOTHING, /*!< at beginning */ MISDN_NOTHING, /*!< at beginning */
MISDN_WAITING4DIGS, /*!< when waiting for infos */ MISDN_WAITING4DIGS, /*!< when waiting for infos */
@ -137,8 +135,6 @@ enum misdn_chan_state {
struct chan_list { struct chan_list {
ast_mutex_t lock;
char allowed_bearers[BUFFERSIZE+1]; char allowed_bearers[BUFFERSIZE+1];
enum misdn_chan_state state; enum misdn_chan_state state;
@ -192,6 +188,11 @@ struct chan_list {
const struct tone_zone_sound *ts; const struct tone_zone_sound *ts;
int overlap_dial;
int overlap_dial_task;
ast_mutex_t overlap_tv_lock;
struct timeval overlap_tv;
struct chan_list *peer; struct chan_list *peer;
struct chan_list *next; struct chan_list *next;
struct chan_list *prev; struct chan_list *prev;
@ -252,6 +253,11 @@ static struct robin_list* get_robin_position (char *group)
} }
/* the main schedule context for stuff like l1 watcher, overlap dial, ... */
static struct sched_context *misdn_tasks = NULL;
static pthread_t misdn_tasks_thread;
static int misdn_tasks_semid;
static void chan_misdn_log(int level, int port, char *tmpl, ...); static void chan_misdn_log(int level, int port, char *tmpl, ...);
static struct ast_channel *misdn_new(struct chan_list *cl, int state, char *exten, char *callerid, int format, int port, int c); static struct ast_channel *misdn_new(struct chan_list *cl, int state, char *exten, char *callerid, int format, int port, int c);
@ -436,6 +442,177 @@ static void print_bearer(struct misdn_bchannel *bc)
} }
/*************** Helpers END *************/ /*************** Helpers END *************/
static void sighandler(int sig)
{}
static void* misdn_tasks_thread_func (void *data)
{
int wait;
struct sigaction sa;
struct sembuf semb = {
.sem_num = 0,
.sem_op = 1,
.sem_flg = 0
};
sa.sa_handler = sighandler;
sa.sa_flags = SA_NODEFER;
sigemptyset(&sa.sa_mask);
sigaddset(&sa.sa_mask, SIGUSR1);
sigaction(SIGUSR1, &sa, NULL);
semop(misdn_tasks_semid, &semb, 1);
while (1) {
wait = ast_sched_wait(misdn_tasks);
if (wait < 0)
wait = 8000;
if (poll(NULL, 0, wait) < 0)
chan_misdn_log(4, 0, "Waking up misdn_tasks thread\n");
ast_sched_runq(misdn_tasks);
}
return NULL;
}
static void misdn_tasks_init (void)
{
key_t key;
union {
int val;
struct semid_ds *buf;
unsigned short *array;
struct seminfo *__buf;
} semu;
struct sembuf semb = {
.sem_num = 0,
.sem_op = -1,
.sem_flg = 0
};
chan_misdn_log(4, 0, "Starting misdn_tasks thread\n");
key = ftok("/etc/asterisk/misdn.conf", 'E');
if (key == -1) {
perror("chan_misdn: Failed to create a semaphore key!");
exit(1);
}
misdn_tasks_semid = semget(key, 10, 0666 | IPC_CREAT);
if (misdn_tasks_semid == -1) {
perror("chan_misdn: Failed to get a semaphore!");
exit(1);
}
semu.val = 0;
if (semctl(misdn_tasks_semid, 0, SETVAL, semu) == -1) {
perror("chan_misdn: Failed to initialize semaphore!");
exit(1);
}
misdn_tasks = sched_context_create();
pthread_create(&misdn_tasks_thread, NULL, misdn_tasks_thread_func, NULL);
semop(misdn_tasks_semid, &semb, 1);
semctl(misdn_tasks_semid, 0, IPC_RMID, semu);
}
static void misdn_tasks_destroy (void)
{
if (misdn_tasks) {
chan_misdn_log(4, 0, "Killing misdn_tasks thread\n");
if ( pthread_cancel(misdn_tasks_thread) == 0 ) {
cb_log(4, 0, "Joining misdn_tasks thread\n");
pthread_join(misdn_tasks_thread, NULL);
}
sched_context_destroy(misdn_tasks);
}
}
static inline void misdn_tasks_wakeup (void)
{
pthread_kill(misdn_tasks_thread, SIGUSR1);
}
static inline int _misdn_tasks_add_variable (int timeout, ast_sched_cb callback, void *data, int variable)
{
int task_id;
if (!misdn_tasks) {
misdn_tasks_init();
}
task_id = ast_sched_add_variable(misdn_tasks, timeout, callback, data, variable);
misdn_tasks_wakeup();
return task_id;
}
static int misdn_tasks_add (int timeout, ast_sched_cb callback, void *data)
{
return _misdn_tasks_add_variable(timeout, callback, data, 0);
}
static int misdn_tasks_add_variable (int timeout, ast_sched_cb callback, void *data)
{
return _misdn_tasks_add_variable(timeout, callback, data, 1);
}
static void misdn_tasks_remove (int task_id)
{
ast_sched_del(misdn_tasks, task_id);
}
static int misdn_l1_task (void *data)
{
misdn_lib_isdn_l1watcher((int)data);
chan_misdn_log(5, (int)data, "L1watcher timeout\n");
return 1;
}
static int misdn_overlap_dial_task (void *data)
{
struct timeval tv_end, tv_now;
int diff;
struct chan_list *ch = (struct chan_list *)data;
chan_misdn_log(4, ch->bc->port, "overlap dial task, chan_state: %d\n", ch->state);
if (ch->state != MISDN_WAITING4DIGS) {
ch->overlap_dial_task = -1;
return 0;
}
ast_mutex_lock(&ch->overlap_tv_lock);
tv_end = ch->overlap_tv;
ast_mutex_unlock(&ch->overlap_tv_lock);
tv_end.tv_sec += ch->overlap_dial;
tv_now = ast_tvnow();
diff = ast_tvdiff_ms(tv_end, tv_now);
if (diff <= 100) {
/* if we are 100ms near the timeout, we are satisfied.. */
stop_indicate(ch);
if (ast_exists_extension(ch->ast, ch->context, ch->bc->dad, 1, ch->bc->oad)) {
ch->state=MISDN_DIALING;
if (pbx_start_chan(ch) < 0) {
chan_misdn_log(-1, ch->bc->port, "ast_pbx_start returned < 0 in misdn_overlap_dial_task\n");
goto misdn_overlap_dial_task_disconnect;
}
} else {
misdn_overlap_dial_task_disconnect:
hanguptone_indicate(ch);
if (ch->bc->nt)
misdn_lib_send_event(ch->bc, EVENT_RELEASE_COMPLETE );
else
misdn_lib_send_event(ch->bc, EVENT_RELEASE);
}
ch->overlap_dial_task = -1;
return 0;
} else
return diff;
}
static void send_digit_to_chan(struct chan_list *cl, char digit ) static void send_digit_to_chan(struct chan_list *cl, char digit )
{ {
static const char* dtmf_tones[] = { static const char* dtmf_tones[] = {
@ -632,7 +809,7 @@ static int misdn_show_config (int fd, int argc, char *argv[])
ok = 1; ok = 1;
} }
if ((argc == 4) || ((argc == 5) && !strcmp(argv[4], "ports"))) { if ((argc == 4) || ((argc == 5) && !strcmp(argv[4], "ports"))) {
for (elem = MISDN_CFG_FIRST + 1; elem < MISDN_CFG_LAST; ++elem) { for (elem = MISDN_CFG_FIRST + 1; elem < MISDN_CFG_LAST - 1 /* the ptp hack, remove the -1 when ptp is gone */; ++elem) {
show_config_description(fd, elem); show_config_description(fd, elem);
ast_cli(fd, "\n"); ast_cli(fd, "\n");
} }
@ -872,9 +1049,7 @@ static int misdn_show_stacks (int fd, int argc, char *argv[])
ast_cli(fd," %s Debug:%d%s\n", buf, misdn_debug[port], misdn_debug_only[port]?"(only)":""); ast_cli(fd," %s Debug:%d%s\n", buf, misdn_debug[port], misdn_debug_only[port]?"(only)":"");
} }
return 0; return 0;
} }
@ -1564,8 +1739,7 @@ static int read_config(struct chan_list *ch, int orig) {
debug_numplan(port, bc->cpnnumplan,"CTON"); debug_numplan(port, bc->cpnnumplan,"CTON");
} }
ch->overlap_dial = 0;
} else { /** ORIGINATOR MISDN **/ } else { /** ORIGINATOR MISDN **/
misdn_cfg_get( port, MISDN_CFG_CPNDIALPLAN, &bc->cpnnumplan, sizeof(int)); misdn_cfg_get( port, MISDN_CFG_CPNDIALPLAN, &bc->cpnnumplan, sizeof(int));
@ -1632,6 +1806,9 @@ static int read_config(struct chan_list *ch, int orig) {
free(ast->cid.cid_rdnis); free(ast->cid.cid_rdnis);
ast->cid.cid_rdnis = strdup(bc->rad); ast->cid.cid_rdnis = strdup(bc->rad);
} }
misdn_cfg_get(bc->port, MISDN_CFG_OVERLAP_DIAL, &ch->overlap_dial, sizeof(ch->overlap_dial));
ast_mutex_init(&ch->overlap_tv_lock);
} /* ORIG MISDN END */ } /* ORIG MISDN END */
return 0; return 0;
@ -2297,12 +2474,12 @@ static int misdn_write(struct ast_channel *ast, struct ast_frame *frame)
} }
if (ch->holded ) { if (ch->holded ) {
chan_misdn_log(5, ch->bc->port, "misdn_write: Returning because holded\n"); chan_misdn_log(7, ch->bc->port, "misdn_write: Returning because holded\n");
return 0; return 0;
} }
if (ch->notxtone) { if (ch->notxtone) {
chan_misdn_log(5, ch->bc->port, "misdn_write: Returning because notxone\n"); chan_misdn_log(7, ch->bc->port, "misdn_write: Returning because notxone\n");
return 0; return 0;
} }
@ -2564,6 +2741,7 @@ static struct chan_list *init_chan_list(int orig)
cl->orginator=orig; cl->orginator=orig;
cl->need_queue_hangup=1; cl->need_queue_hangup=1;
cl->need_hangup=1; cl->need_hangup=1;
cl->overlap_dial_task=-1;
return cl; return cl;
@ -3035,6 +3213,13 @@ static void release_chan(struct misdn_bchannel *bc) {
chan_misdn_log(5,bc->port,"Jitterbuffer already destroyed.\n"); chan_misdn_log(5,bc->port,"Jitterbuffer already destroyed.\n");
} }
if (ch->overlap_dial) {
if (ch->overlap_dial_task != -1) {
misdn_tasks_remove(ch->overlap_dial_task);
ch->overlap_dial_task = -1;
}
ast_mutex_destroy(&ch->overlap_tv_lock);
}
if (ch->orginator == ORG_AST) { if (ch->orginator == ORG_AST) {
misdn_out_calls[bc->port]--; misdn_out_calls[bc->port]--;
@ -3416,6 +3601,18 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
break; break;
} }
if (ch->overlap_dial) {
ast_mutex_lock(&ch->overlap_tv_lock);
ch->overlap_tv = ast_tvnow();
ast_mutex_unlock(&ch->overlap_tv_lock);
if (ch->overlap_dial_task == -1) {
ch->overlap_dial_task =
misdn_tasks_add_variable(ch->overlap_dial, misdn_overlap_dial_task, ch);
}
break;
}
if (ast_exists_extension(ch->ast, ch->context, bc->dad, 1, bc->oad)) { if (ast_exists_extension(ch->ast, ch->context, bc->dad, 1, bc->oad)) {
ch->state=MISDN_DIALING; ch->state=MISDN_DIALING;
@ -3468,7 +3665,7 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
struct chan_list *ch=find_chan_by_bc(cl_te, bc); struct chan_list *ch=find_chan_by_bc(cl_te, bc);
if (ch && ch->state != MISDN_NOTHING ) { if (ch && ch->state != MISDN_NOTHING ) {
chan_misdn_log(1, bc->port, " --> Ignoring Call we have already one\n"); 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 */ return RESPONSE_IGNORE_SETUP_WITHOUT_CLOSE;
} }
} }
@ -3608,7 +3805,7 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
break; break;
} }
if (ast_exists_extension(ch->ast, ch->context, bc->dad, 1, bc->oad)) { if (!ch->overlap_dial && ast_exists_extension(ch->ast, ch->context, bc->dad, 1, bc->oad)) {
ch->state=MISDN_DIALING; ch->state=MISDN_DIALING;
if (bc->nt || (bc->need_more_infos && misdn_lib_is_ptp(bc->port)) ) { if (bc->nt || (bc->need_more_infos && misdn_lib_is_ptp(bc->port)) ) {
@ -3646,7 +3843,7 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
} }
} else { } else {
int ret= misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE ); int ret= misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE );
if (ret == -ENOCHAN) { if (ret == -ENOCHAN) {
ast_log(LOG_WARNING,"Channel was catched, before we could Acknowledge\n"); ast_log(LOG_WARNING,"Channel was catched, before we could Acknowledge\n");
@ -3656,18 +3853,30 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
/** ADD IGNOREPAT **/ /** ADD IGNOREPAT **/
int stop_tone; int stop_tone, dad_len;
misdn_cfg_get( 0, MISDN_GEN_STOP_TONE, &stop_tone, sizeof(int)); misdn_cfg_get( 0, MISDN_GEN_STOP_TONE, &stop_tone, sizeof(int));
if ( (!ast_strlen_zero(bc->dad)) && stop_tone )
dad_len = ast_strlen_zero(bc->dad);
if ( !dad_len && stop_tone )
stop_indicate(ch); stop_indicate(ch);
else { else
dialtone_indicate(ch); dialtone_indicate(ch);
}
ch->state=MISDN_WAITING4DIGS; ch->state=MISDN_WAITING4DIGS;
if (ch->overlap_dial && !dad_len) {
ast_mutex_lock(&ch->overlap_tv_lock);
ch->overlap_tv = ast_tvnow();
ast_mutex_unlock(&ch->overlap_tv_lock);
if (ch->overlap_dial_task == -1) {
ch->overlap_dial_task =
misdn_tasks_add_variable(ch->overlap_dial, misdn_overlap_dial_task, ch);
}
}
} }
} }
} }
break; break;
case EVENT_SETUP_ACKNOWLEDGE: case EVENT_SETUP_ACKNOWLEDGE:
@ -4108,6 +4317,8 @@ static int unload_module(void *mod)
{ {
/* First, take us out of the channel loop */ /* First, take us out of the channel loop */
ast_log(LOG_VERBOSE, "-- Unregistering mISDN Channel Driver --\n"); ast_log(LOG_VERBOSE, "-- Unregistering mISDN Channel Driver --\n");
misdn_tasks_destroy();
if (!g_config_initialized) return 0; if (!g_config_initialized) return 0;
@ -4152,10 +4363,10 @@ static int unload_module(void *mod)
static int load_module(void *mod) static int load_module(void *mod)
{ {
int i; int i, port;
char ports[256]=""; char ports[256]="";
max_ports=misdn_lib_maxports_get(); max_ports=misdn_lib_maxports_get();
if (max_ports<=0) { if (max_ports<=0) {
@ -4194,10 +4405,6 @@ static int load_module(void *mod)
misdn_cfg_update_ptp(); misdn_cfg_update_ptp();
misdn_cfg_get_ports_string(ports); misdn_cfg_get_ports_string(ports);
int l1watcher_timeout=0;
misdn_cfg_get( 0, MISDN_GEN_L1_TIMEOUT, &l1watcher_timeout, sizeof(int));
if (strlen(ports)) if (strlen(ports))
chan_misdn_log(0, 0, "Got: %s from get_ports\n",ports); chan_misdn_log(0, 0, "Got: %s from get_ports\n",ports);
@ -4206,7 +4413,6 @@ static int load_module(void *mod)
.cb_event = cb_events, .cb_event = cb_events,
.cb_log = chan_misdn_log, .cb_log = chan_misdn_log,
.cb_jb_empty = chan_misdn_jb_empty, .cb_jb_empty = chan_misdn_jb_empty,
.l1watcher_timeout=l1watcher_timeout,
}; };
if (misdn_lib_init(ports, &iface, NULL)) if (misdn_lib_init(ports, &iface, NULL))
@ -4280,8 +4486,16 @@ static int load_module(void *mod)
misdn_cfg_get( 0, MISDN_GEN_TRACEFILE, global_tracefile, BUFFERSIZE); misdn_cfg_get( 0, MISDN_GEN_TRACEFILE, global_tracefile, BUFFERSIZE);
/* start the l1 watchers */
for (port = misdn_cfg_get_next_port(0); port >= 0; port = misdn_cfg_get_next_port(port)) {
int l1timeout;
misdn_cfg_get(port, MISDN_CFG_L1_TIMEOUT, &l1timeout, sizeof(l1timeout));
if (l1timeout) {
chan_misdn_log(4, 0, "Adding L1watcher task: port:%d timeout:%ds\n", port, l1timeout);
misdn_tasks_add(l1timeout * 1000, misdn_l1_task, (void*)port);
}
}
chan_misdn_log(0, 0, "-- mISDN Channel Driver Registred -- (BE AWARE THIS DRIVER IS EXPERIMENTAL!)\n"); chan_misdn_log(0, 0, "-- mISDN Channel Driver Registred -- (BE AWARE THIS DRIVER IS EXPERIMENTAL!)\n");

@ -59,9 +59,11 @@ enum misdn_cfg_elements {
MISDN_CFG_PICKUPGROUP, /* ast_group_t */ MISDN_CFG_PICKUPGROUP, /* ast_group_t */
MISDN_CFG_MAX_IN, /* int */ MISDN_CFG_MAX_IN, /* int */
MISDN_CFG_MAX_OUT, /* int */ MISDN_CFG_MAX_OUT, /* int */
MISDN_CFG_L1_TIMEOUT, /* int */
MISDN_CFG_OVERLAP_DIAL, /* int (bool)*/
MISDN_CFG_MSNS, /* char[] */ MISDN_CFG_MSNS, /* char[] */
MISDN_CFG_PTP, /* int (bool) */
MISDN_CFG_FAXDETECT, /* char[] */ MISDN_CFG_FAXDETECT, /* char[] */
MISDN_CFG_PTP, /* int (bool) */
MISDN_CFG_LAST, MISDN_CFG_LAST,
/* general config items */ /* general config items */
@ -75,7 +77,6 @@ enum misdn_cfg_elements {
MISDN_GEN_DYNAMIC_CRYPT, /* int (bool) */ MISDN_GEN_DYNAMIC_CRYPT, /* int (bool) */
MISDN_GEN_CRYPT_PREFIX, /* char[] */ MISDN_GEN_CRYPT_PREFIX, /* char[] */
MISDN_GEN_CRYPT_KEYS, /* char[] */ MISDN_GEN_CRYPT_KEYS, /* char[] */
MISDN_GEN_L1_TIMEOUT, /* int */
MISDN_GEN_NTDEBUGFLAGS, /* int */ MISDN_GEN_NTDEBUGFLAGS, /* int */
MISDN_GEN_NTDEBUGFILE, /* char[] */ MISDN_GEN_NTDEBUGFILE, /* char[] */
MISDN_GEN_LAST MISDN_GEN_LAST

@ -108,12 +108,9 @@ struct misdn_lib {
int midev; int midev;
int midev_nt; int midev_nt;
pthread_t l1watcher_thread;
pthread_t event_thread; pthread_t event_thread;
pthread_t event_handler_thread; pthread_t event_handler_thread;
int l1watcher_timeout;
void *user_data; void *user_data;
msg_queue_t upqueue; msg_queue_t upqueue;
@ -163,7 +160,6 @@ static struct misdn_lib *glob_mgr;
unsigned char tone_425_flip[TONE_425_SIZE]; unsigned char tone_425_flip[TONE_425_SIZE];
unsigned char tone_silence_flip[TONE_SILENCE_SIZE]; unsigned char tone_silence_flip[TONE_SILENCE_SIZE];
static void misdn_lib_isdn_l1watcher(void *arg);
static void misdn_lib_isdn_event_catcher(void *arg); static void misdn_lib_isdn_event_catcher(void *arg);
static int handle_event_nt(void *dat, void *arg); static int handle_event_nt(void *dat, void *arg);
@ -2810,30 +2806,20 @@ msg_t *fetch_msg(int midev)
return NULL; return NULL;
} }
static void misdn_lib_isdn_l1watcher(void *arg) void misdn_lib_isdn_l1watcher(int port)
{ {
struct misdn_lib *mgr = arg;
struct misdn_stack *stack; struct misdn_stack *stack;
while (1) { for (stack = glob_mgr->stack_list; stack && (stack->port != port); stack = stack->next)
sleep(mgr->l1watcher_timeout); ;
/* look out for l1 which are down
and try to pull the up.
We might even try to pull the l2 up in the if (stack) {
ptp case. cb_log(4, port, "Checking L1 State\n");
*/ if (!stack->l1link) {
for (stack = mgr->stack_list; cb_log(4, port, "L1 State Down, trying to get it up again\n");
stack; misdn_lib_get_short_status(stack);
stack = stack->next) { misdn_lib_get_l1_up(stack);
cb_log(4,stack->port,"Checking L1 State\n"); misdn_lib_get_l2_up(stack);
if (!stack->l1link) {
cb_log(4,stack->port,"L1 State Down, trying to get it up again\n");
misdn_lib_get_short_status(stack);
misdn_lib_get_l1_up(stack);
misdn_lib_get_l2_up(stack);
}
} }
} }
} }
@ -3703,7 +3689,7 @@ int misdn_lib_init(char *portlist, struct misdn_lib_iface *iface, void *user_dat
if (sem_init(&mgr->new_msg, 1, 0)<0) if (sem_init(&mgr->new_msg, 1, 0)<0)
sem_init(&mgr->new_msg, 0, 0); sem_init(&mgr->new_msg, 0, 0);
for (tok=strtok_r(plist," ,",&tokb ); for (tok=strtok_r(plist," ,",&tokb );
tok; tok;
tok=strtok_r(NULL," ,",&tokb)) { tok=strtok_r(NULL," ,",&tokb)) {
@ -3726,20 +3712,20 @@ int misdn_lib_init(char *portlist, struct misdn_lib_iface *iface, void *user_dat
exit(1); exit(1);
} }
{
int i;
for(i=0;i<stack->b_num; i++) {
int r;
if ((r=init_bc(stack, &stack->bc[i], stack->midev,port,i, "", 1))<0) {
cb_log(-1, port, "Got Err @ init_bc :%d\n",r);
exit(1);
}
}
}
if (stack && first) { if (stack && first) {
mgr->stack_list=stack; mgr->stack_list=stack;
first=0; first=0;
{
int i;
for(i=0;i<stack->b_num; i++) {
int r;
if ((r=init_bc(stack, &stack->bc[i], stack->midev,port,i, "", 1))<0) {
cb_log(-1, port, "Got Err @ init_bc :%d\n",r);
exit(1);
}
}
}
continue; continue;
} }
@ -3747,20 +3733,7 @@ int misdn_lib_init(char *portlist, struct misdn_lib_iface *iface, void *user_dat
struct misdn_stack * help; struct misdn_stack * help;
for ( help=mgr->stack_list; help; help=help->next ) for ( help=mgr->stack_list; help; help=help->next )
if (help->next == NULL) break; if (help->next == NULL) break;
help->next=stack; help->next=stack;
{
int i;
for(i=0;i<stack->b_num; i++) {
int r;
if ((r=init_bc(stack, &stack->bc[i], stack->midev,port,i, "",1 ))<0) {
cb_log(-1, port, "Got Err @ init_bc :%d\n",r);
exit(1);
}
}
}
} }
} }
@ -3777,12 +3750,6 @@ int misdn_lib_init(char *portlist, struct misdn_lib_iface *iface, void *user_dat
cb_log(4, 0, "Event Catcher started\n"); cb_log(4, 0, "Event Catcher started\n");
if (iface->l1watcher_timeout > 0) {
mgr->l1watcher_timeout=iface->l1watcher_timeout;
cb_log(4, 0, "Starting L1 watcher\n");
pthread_create( &mgr->l1watcher_thread, NULL, (void*)misdn_lib_isdn_l1watcher, mgr);
}
global_state= MISDN_INITIALIZED; global_state= MISDN_INITIALIZED;
return (mgr == NULL); return (mgr == NULL);

@ -341,12 +341,9 @@ void (*cb_log) (int level, int port, char *tmpl, ...);
int (*cb_jb_empty)(struct misdn_bchannel *bc, char *buffer, int len); int (*cb_jb_empty)(struct misdn_bchannel *bc, char *buffer, int len);
struct misdn_lib_iface { struct misdn_lib_iface {
enum event_response_e (*cb_event)(enum event_e event, struct misdn_bchannel *bc, void *user_data); enum event_response_e (*cb_event)(enum event_e event, struct misdn_bchannel *bc, void *user_data);
void (*cb_log)(int level, int port, char *tmpl, ...); void (*cb_log)(int level, int port, char *tmpl, ...);
int (*cb_jb_empty)(struct misdn_bchannel *bc, char *buffer, int len); int (*cb_jb_empty)(struct misdn_bchannel *bc, char *buffer, int len);
int l1watcher_timeout;
}; };
/***** USER IFACE **********/ /***** USER IFACE **********/
@ -357,6 +354,8 @@ int misdn_lib_init(char *portlist, struct misdn_lib_iface* iface, void *user_dat
int misdn_lib_send_event(struct misdn_bchannel *bc, enum event_e event ); int misdn_lib_send_event(struct misdn_bchannel *bc, enum event_e event );
void misdn_lib_destroy(void); void misdn_lib_destroy(void);
void misdn_lib_isdn_l1watcher(int port);
void misdn_lib_log_ies(struct misdn_bchannel *bc); void misdn_lib_log_ies(struct misdn_bchannel *bc);
char *manager_isdn_get_info(enum event_e event); char *manager_isdn_get_info(enum event_e event);

@ -262,6 +262,19 @@ static const struct misdn_cfg_spec port_spec[] = {
"\texceeding calls will be rejected" }, "\texceeding calls will be rejected" },
{ "faxdetect", MISDN_CFG_FAXDETECT, MISDN_CTYPE_STR, "no", NONE, { "faxdetect", MISDN_CFG_FAXDETECT, MISDN_CTYPE_STR, "no", NONE,
"Context to jump into if we detect an incoming fax." }, "Context to jump into if we detect an incoming fax." },
{ "l1watcher_timeout", MISDN_CFG_L1_TIMEOUT, MISDN_CTYPE_BOOLINT, "0", 4,
"Watches the layer 1. If the layer 1 is down, it tries to\n"
"\tget it up. The timeout is given in seconds. with 0 as value it\n"
"\tdoes not watch the l1 at all\n"
"\n"
"\tThis option is only read at loading time of chan_misdn, which\n"
"\tmeans you need to unload and load chan_misdn to change the value,\n"
"\tan Asterisk restart should do the trick." },
{ "overlap_dial", MISDN_CFG_OVERLAP_DIAL, MISDN_CTYPE_BOOLINT, "0", 4,
"Enables overlap dial for the given amount of seconds.\n"
"\tPossible values are positive integers or:\n"
"\t yes (= 4 seconds)\n"
"\t no (= 0 seconds = disabled)" },
{ "msns", MISDN_CFG_MSNS, MISDN_CTYPE_MSNLIST, NO_DEFAULT, NONE, { "msns", MISDN_CFG_MSNS, MISDN_CTYPE_MSNLIST, NO_DEFAULT, NONE,
"MSN's for TE ports, listen on those numbers on the above ports, and\n" "MSN's for TE ports, listen on those numbers on the above ports, and\n"
"\tindicate the incoming calls to Asterisk.\n" "\tindicate the incoming calls to Asterisk.\n"
@ -293,18 +306,10 @@ static const struct misdn_cfg_spec gen_spec[] = {
{ "crypt_keys", MISDN_GEN_CRYPT_KEYS, MISDN_CTYPE_STR, NO_DEFAULT, NONE, { "crypt_keys", MISDN_GEN_CRYPT_KEYS, MISDN_CTYPE_STR, NO_DEFAULT, NONE,
"Keys for cryption, you reference them in the dialplan\n" "Keys for cryption, you reference them in the dialplan\n"
"\tLater also in dynamic encr." }, "\tLater also in dynamic encr." },
{ "l1watcher_timeout", MISDN_GEN_L1_TIMEOUT, MISDN_CTYPE_INT, "0", NONE,
"Watches the L1s of every port. If one l1 is down it tries to\n"
"\tget it up. The timeout is given in seconds. with 0 as value it\n"
"\tdoes not watch the l1 at all\n"
"\n"
"\tThis option is only read at loading time of chan_misdn, which\n"
"\tmeans you need to unload and load chan_misdn to change the value,\n"
"\tan Asterisk restart should do the trick." },
{ "ntdebugflags", MISDN_GEN_NTDEBUGFLAGS, MISDN_CTYPE_INT, "0", NONE, { "ntdebugflags", MISDN_GEN_NTDEBUGFLAGS, MISDN_CTYPE_INT, "0", NONE,
"no description yet"}, "No description yet."},
{ "ntdebugfile", MISDN_GEN_NTDEBUGFILE, MISDN_CTYPE_STR, "/var/log/misdn-nt.log", NONE, { "ntdebugfile", MISDN_GEN_NTDEBUGFILE, MISDN_CTYPE_STR, "/var/log/misdn-nt.log", NONE,
"no description yet" } "No description yet." }
}; };
@ -580,10 +585,10 @@ int misdn_cfg_is_msn_valid (int port, char* msn)
} }
misdn_cfg_lock(); misdn_cfg_lock();
if (port_cfg[port][MISDN_CFG_MSNS-1].ml) if (port_cfg[port][map[MISDN_CFG_MSNS]].ml)
iter = port_cfg[port][MISDN_CFG_MSNS-1].ml; iter = port_cfg[port][map[MISDN_CFG_MSNS]].ml;
else else
iter = port_cfg[0][MISDN_CFG_MSNS-1].ml; iter = port_cfg[0][map[MISDN_CFG_MSNS]].ml;
for (; iter; iter = iter->next) for (; iter; iter = iter->next)
if (*(iter->msn) == '*' || ast_extension_match(iter->msn, msn)) { if (*(iter->msn) == '*' || ast_extension_match(iter->msn, msn)) {
re = 1; re = 1;
@ -995,6 +1000,8 @@ void misdn_cfg_init (int this_max_ports)
return; return;
} }
ast_mutex_init(&config_mutex);
misdn_cfg_lock(); misdn_cfg_lock();
if (this_max_ports) { if (this_max_ports) {

Loading…
Cancel
Save