mirror of
https://github.com/asterisk/asterisk.git
synced 2025-10-12 15:45:18 +00:00
* 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
This commit is contained in:
@@ -41,7 +41,10 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
|
||||
#include <arpa/inet.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <signal.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/sem.h>
|
||||
|
||||
#include "asterisk/channel.h"
|
||||
#include "asterisk/config.h"
|
||||
@@ -63,6 +66,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
|
||||
#include "asterisk/app.h"
|
||||
#include "asterisk/features.h"
|
||||
#include "asterisk/term.h"
|
||||
#include "asterisk/sched.h"
|
||||
#include "asterisk/stringfields.h"
|
||||
|
||||
#include "chan_misdn_config.h"
|
||||
@@ -101,12 +105,6 @@ of data. */
|
||||
int misdn_jb_empty(struct misdn_jb *jb, char *data, int len);
|
||||
|
||||
|
||||
|
||||
|
||||
/* BEGIN: chan_misdn.h */
|
||||
|
||||
|
||||
|
||||
enum misdn_chan_state {
|
||||
MISDN_NOTHING, /*!< at beginning */
|
||||
MISDN_WAITING4DIGS, /*!< when waiting for infos */
|
||||
@@ -137,8 +135,6 @@ enum misdn_chan_state {
|
||||
|
||||
struct chan_list {
|
||||
|
||||
ast_mutex_t lock;
|
||||
|
||||
char allowed_bearers[BUFFERSIZE+1];
|
||||
|
||||
enum misdn_chan_state state;
|
||||
@@ -192,6 +188,11 @@ struct chan_list {
|
||||
|
||||
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 *next;
|
||||
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 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 *************/
|
||||
|
||||
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 const char* dtmf_tones[] = {
|
||||
@@ -632,7 +809,7 @@ static int misdn_show_config (int fd, int argc, char *argv[])
|
||||
ok = 1;
|
||||
}
|
||||
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);
|
||||
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)":"");
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1564,8 +1739,7 @@ static int read_config(struct chan_list *ch, int orig) {
|
||||
debug_numplan(port, bc->cpnnumplan,"CTON");
|
||||
}
|
||||
|
||||
|
||||
|
||||
ch->overlap_dial = 0;
|
||||
} else { /** ORIGINATOR MISDN **/
|
||||
|
||||
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);
|
||||
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 */
|
||||
|
||||
return 0;
|
||||
@@ -2297,12 +2474,12 @@ static int misdn_write(struct ast_channel *ast, struct ast_frame *frame)
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -2564,6 +2741,7 @@ static struct chan_list *init_chan_list(int orig)
|
||||
cl->orginator=orig;
|
||||
cl->need_queue_hangup=1;
|
||||
cl->need_hangup=1;
|
||||
cl->overlap_dial_task=-1;
|
||||
|
||||
return cl;
|
||||
|
||||
@@ -3035,6 +3213,13 @@ static void release_chan(struct misdn_bchannel *bc) {
|
||||
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) {
|
||||
misdn_out_calls[bc->port]--;
|
||||
@@ -3416,6 +3601,18 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
|
||||
|
||||
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)) {
|
||||
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);
|
||||
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; /* 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;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
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 {
|
||||
|
||||
|
||||
int ret= misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE );
|
||||
if (ret == -ENOCHAN) {
|
||||
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 **/
|
||||
|
||||
int stop_tone;
|
||||
int stop_tone, dad_len;
|
||||
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);
|
||||
else {
|
||||
else
|
||||
dialtone_indicate(ch);
|
||||
}
|
||||
|
||||
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;
|
||||
case EVENT_SETUP_ACKNOWLEDGE:
|
||||
@@ -4108,6 +4317,8 @@ static int unload_module(void *mod)
|
||||
{
|
||||
/* First, take us out of the channel loop */
|
||||
ast_log(LOG_VERBOSE, "-- Unregistering mISDN Channel Driver --\n");
|
||||
|
||||
misdn_tasks_destroy();
|
||||
|
||||
if (!g_config_initialized) return 0;
|
||||
|
||||
@@ -4152,10 +4363,10 @@ static int unload_module(void *mod)
|
||||
|
||||
static int load_module(void *mod)
|
||||
{
|
||||
int i;
|
||||
int i, port;
|
||||
|
||||
char ports[256]="";
|
||||
|
||||
|
||||
max_ports=misdn_lib_maxports_get();
|
||||
|
||||
if (max_ports<=0) {
|
||||
@@ -4194,10 +4405,6 @@ static int load_module(void *mod)
|
||||
misdn_cfg_update_ptp();
|
||||
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))
|
||||
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_log = chan_misdn_log,
|
||||
.cb_jb_empty = chan_misdn_jb_empty,
|
||||
.l1watcher_timeout=l1watcher_timeout,
|
||||
};
|
||||
|
||||
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);
|
||||
|
||||
|
||||
|
||||
/* 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");
|
||||
|
||||
|
@@ -59,9 +59,11 @@ enum misdn_cfg_elements {
|
||||
MISDN_CFG_PICKUPGROUP, /* ast_group_t */
|
||||
MISDN_CFG_MAX_IN, /* int */
|
||||
MISDN_CFG_MAX_OUT, /* int */
|
||||
MISDN_CFG_L1_TIMEOUT, /* int */
|
||||
MISDN_CFG_OVERLAP_DIAL, /* int (bool)*/
|
||||
MISDN_CFG_MSNS, /* char[] */
|
||||
MISDN_CFG_PTP, /* int (bool) */
|
||||
MISDN_CFG_FAXDETECT, /* char[] */
|
||||
MISDN_CFG_PTP, /* int (bool) */
|
||||
MISDN_CFG_LAST,
|
||||
|
||||
/* general config items */
|
||||
@@ -75,7 +77,6 @@ enum misdn_cfg_elements {
|
||||
MISDN_GEN_DYNAMIC_CRYPT, /* int (bool) */
|
||||
MISDN_GEN_CRYPT_PREFIX, /* char[] */
|
||||
MISDN_GEN_CRYPT_KEYS, /* char[] */
|
||||
MISDN_GEN_L1_TIMEOUT, /* int */
|
||||
MISDN_GEN_NTDEBUGFLAGS, /* int */
|
||||
MISDN_GEN_NTDEBUGFILE, /* char[] */
|
||||
MISDN_GEN_LAST
|
||||
|
@@ -108,12 +108,9 @@ struct misdn_lib {
|
||||
int midev;
|
||||
int midev_nt;
|
||||
|
||||
pthread_t l1watcher_thread;
|
||||
pthread_t event_thread;
|
||||
pthread_t event_handler_thread;
|
||||
|
||||
int l1watcher_timeout;
|
||||
|
||||
void *user_data;
|
||||
|
||||
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_silence_flip[TONE_SILENCE_SIZE];
|
||||
|
||||
static void misdn_lib_isdn_l1watcher(void *arg);
|
||||
static void misdn_lib_isdn_event_catcher(void *arg);
|
||||
static int handle_event_nt(void *dat, void *arg);
|
||||
|
||||
@@ -2810,30 +2806,20 @@ msg_t *fetch_msg(int midev)
|
||||
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;
|
||||
|
||||
while (1) {
|
||||
sleep(mgr->l1watcher_timeout);
|
||||
|
||||
/* look out for l1 which are down
|
||||
and try to pull the up.
|
||||
for (stack = glob_mgr->stack_list; stack && (stack->port != port); stack = stack->next)
|
||||
;
|
||||
|
||||
We might even try to pull the l2 up in the
|
||||
ptp case.
|
||||
*/
|
||||
for (stack = mgr->stack_list;
|
||||
stack;
|
||||
stack = stack->next) {
|
||||
cb_log(4,stack->port,"Checking L1 State\n");
|
||||
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);
|
||||
}
|
||||
if (stack) {
|
||||
cb_log(4, port, "Checking L1 State\n");
|
||||
if (!stack->l1link) {
|
||||
cb_log(4, 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)
|
||||
sem_init(&mgr->new_msg, 0, 0);
|
||||
|
||||
|
||||
for (tok=strtok_r(plist," ,",&tokb );
|
||||
tok;
|
||||
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);
|
||||
}
|
||||
|
||||
{
|
||||
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) {
|
||||
mgr->stack_list=stack;
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -3747,20 +3733,7 @@ int misdn_lib_init(char *portlist, struct misdn_lib_iface *iface, void *user_dat
|
||||
struct misdn_stack * help;
|
||||
for ( help=mgr->stack_list; help; help=help->next )
|
||||
if (help->next == NULL) break;
|
||||
|
||||
|
||||
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");
|
||||
|
||||
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;
|
||||
|
||||
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);
|
||||
|
||||
struct misdn_lib_iface {
|
||||
|
||||
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, ...);
|
||||
int (*cb_jb_empty)(struct misdn_bchannel *bc, char *buffer, int len);
|
||||
|
||||
int l1watcher_timeout;
|
||||
};
|
||||
|
||||
/***** 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 );
|
||||
void misdn_lib_destroy(void);
|
||||
|
||||
void misdn_lib_isdn_l1watcher(int port);
|
||||
|
||||
void misdn_lib_log_ies(struct misdn_bchannel *bc);
|
||||
|
||||
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" },
|
||||
{ "faxdetect", MISDN_CFG_FAXDETECT, MISDN_CTYPE_STR, "no", NONE,
|
||||
"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,
|
||||
"MSN's for TE ports, listen on those numbers on the above ports, and\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,
|
||||
"Keys for cryption, you reference them in the dialplan\n"
|
||||
"\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,
|
||||
"no description yet"},
|
||||
"No description yet."},
|
||||
{ "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();
|
||||
if (port_cfg[port][MISDN_CFG_MSNS-1].ml)
|
||||
iter = port_cfg[port][MISDN_CFG_MSNS-1].ml;
|
||||
if (port_cfg[port][map[MISDN_CFG_MSNS]].ml)
|
||||
iter = port_cfg[port][map[MISDN_CFG_MSNS]].ml;
|
||||
else
|
||||
iter = port_cfg[0][MISDN_CFG_MSNS-1].ml;
|
||||
iter = port_cfg[0][map[MISDN_CFG_MSNS]].ml;
|
||||
for (; iter; iter = iter->next)
|
||||
if (*(iter->msn) == '*' || ast_extension_match(iter->msn, msn)) {
|
||||
re = 1;
|
||||
@@ -995,6 +1000,8 @@ void misdn_cfg_init (int this_max_ports)
|
||||
return;
|
||||
}
|
||||
|
||||
ast_mutex_init(&config_mutex);
|
||||
|
||||
misdn_cfg_lock();
|
||||
|
||||
if (this_max_ports) {
|
||||
|
Reference in New Issue
Block a user