Codename Pineapple

Home page | Mailing list | Docs

Last updated: Sat Feb 3 05:01:10 2007

Asterisk developer's documentation :: Codename Pineapple


chan_misdn.c File Reference


Detailed Description

the chan_misdn channel driver for Asterisk

Author:
Christian Richter <crich@beronet.com>

Definition in file chan_misdn.c.

#include "asterisk.h"
#include <stdio.h>
#include <pthread.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <signal.h>
#include <sys/file.h>
#include <semaphore.h>
#include "asterisk/channel.h"
#include "asterisk/config.h"
#include "asterisk/logger.h"
#include "asterisk/module.h"
#include "asterisk/pbx.h"
#include "asterisk/options.h"
#include "asterisk/io.h"
#include "asterisk/frame.h"
#include "asterisk/translate.h"
#include "asterisk/cli.h"
#include "asterisk/musiconhold.h"
#include "asterisk/dsp.h"
#include "asterisk/file.h"
#include "asterisk/callerid.h"
#include "asterisk/indications.h"
#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"
#include "isdn_lib.h"
#include <asterisk/strings.h>

Include dependency graph for chan_misdn.c:

Go to the source code of this file.

Data Structures

struct  allowed_bearers
struct  chan_list
struct  hold_info
struct  misdn_jb
struct  robin_list
struct  state_struct

Defines

#define AST_BRIDGED_P(ast)   ast_bridged_channel(ast)
#define AST_CID_P(ast)   ast->cid.cid_num
#define AST_DESTROY_CFG   ast_config_destroy
#define AST_LOAD_CFG   ast_config_load
#define MISDN_ASTERISK_PVT(ast)   1
#define MISDN_ASTERISK_TECH_PVT(ast)   ast->tech_pvt
#define ORG_AST   1
#define ORG_MISDN   2

Enumerations

enum  misdn_chan_state {
  MISDN_NOTHING = 0, MISDN_WAITING4DIGS, MISDN_EXTCANTMATCH, MISDN_DIALING,
  MISDN_PROGRESS, MISDN_PROCEEDING, MISDN_CALLING, MISDN_CALLING_ACKNOWLEDGE,
  MISDN_ALERTING, MISDN_BUSY, MISDN_CONNECTED, MISDN_PRECONNECTED,
  MISDN_DISCONNECTED, MISDN_RELEASED, MISDN_BRIDGED, MISDN_CLEANING,
  MISDN_HUNGUP_FROM_MISDN, MISDN_HUNGUP_FROM_AST, MISDN_HOLDED, MISDN_HOLD_DISCONNECT
}

Functions

static int _misdn_tasks_add_variable (int timeout, ast_sched_cb callback, void *data, int variable)
int add_in_calls (int port)
int add_out_calls (int port)
 AST_MODULE_INFO (ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT,"Channel driver for mISDN Support (BRI/PRI)",.load=load_module,.unload=unload_module,.reload=reload,)
static char * bearer2str (int cap)
static enum event_response_e cb_events (enum event_e event, struct misdn_bchannel *bc, void *user_data)
int chan_misdn_jb_empty (struct misdn_bchannel *bc, char *buf, int len)
static void chan_misdn_log (int level, int port, char *tmpl,...)
static void cl_dequeue_chan (struct chan_list **list, struct chan_list *chan)
static void cl_queue_chan (struct chan_list **list, struct chan_list *chan)
static char * complete_ch (const char *line, const char *word, int pos, int state)
static char * complete_ch_helper (const char *line, const char *word, int pos, int state, int rpos)
static char * complete_debug_port (const char *line, const char *word, int pos, int state)
static char * complete_show_config (const char *line, const char *word, int pos, int state)
static void config_jitterbuffer (struct chan_list *ch)
void debug_numplan (int port, int numplan, char *type)
static int dialtone_indicate (struct chan_list *cl)
static void do_immediate_setup (struct misdn_bchannel *bc, struct chan_list *ch, struct ast_channel *ast)
void export_ch (struct ast_channel *chan, struct misdn_bchannel *bc, struct chan_list *ch)
static struct chan_listfind_chan_by_bc (struct chan_list *list, struct misdn_bchannel *bc)
static struct chan_listfind_chan_by_pid (struct chan_list *list, int pid)
static struct chan_listfind_holded (struct chan_list *list, struct misdn_bchannel *bc)
static struct chan_listfind_holded_l3 (struct chan_list *list, unsigned long l3_id, int w)
static void free_robin_list (void)
static void free_robin_list_r (struct robin_list *r)
static struct chan_listget_chan_by_ast (struct ast_channel *ast)
static struct chan_listget_chan_by_ast_name (char *name)
static struct robin_listget_robin_position (char *group)
static void hangup_chan (struct chan_list *ch)
static int hanguptone_indicate (struct chan_list *cl)
void import_ch (struct ast_channel *chan, struct misdn_bchannel *bc, struct chan_list *ch)
static struct chan_listinit_chan_list (int orig)
static int load_module (void)
static int misdn_answer (struct ast_channel *ast)
static enum ast_bridge_result misdn_bridge (struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc, int timeoutms)
static int misdn_call (struct ast_channel *ast, char *dest, int timeout)
static int misdn_digit_begin (struct ast_channel *chan, char digit)
static int misdn_digit_end (struct ast_channel *ast, char digit, unsigned int duration)
static int misdn_facility_exec (struct ast_channel *chan, void *data)
static int misdn_fixup (struct ast_channel *oldast, struct ast_channel *ast)
static char * misdn_get_ch_state (struct chan_list *p)
static int misdn_hangup (struct ast_channel *ast)
static int misdn_indication (struct ast_channel *ast, int cond, const void *data, size_t datalen)
void misdn_jb_destroy (struct misdn_jb *jb)
int misdn_jb_empty (struct misdn_jb *jb, char *data, int len)
int misdn_jb_fill (struct misdn_jb *jb, const char *data, int len)
misdn_jbmisdn_jb_init (int size, int upper_threshold)
static int misdn_l1_task (void *data)
static struct ast_channelmisdn_new (struct chan_list *cl, int state, char *exten, char *callerid, int format, int port, int c)
static int misdn_overlap_dial_task (void *data)
static int misdn_port_block (int fd, int argc, char *argv[])
static int misdn_port_down (int fd, int argc, char *argv[])
static int misdn_port_unblock (int fd, int argc, char *argv[])
static int misdn_port_up (int fd, int argc, char *argv[])
static struct ast_framemisdn_read (struct ast_channel *ast)
static int misdn_reload (int fd, int argc, char *argv[])
static struct ast_channelmisdn_request (const char *type, int format, void *data, int *cause)
static int misdn_restart_pid (int fd, int argc, char *argv[])
static int misdn_restart_port (int fd, int argc, char *argv[])
static int misdn_send_cd (int fd, int argc, char *argv[])
static int misdn_send_digit (int fd, int argc, char *argv[])
static int misdn_send_display (int fd, int argc, char *argv[])
static int misdn_send_text (struct ast_channel *chan, const char *text)
static int misdn_set_crypt_debug (int fd, int argc, char *argv[])
static int misdn_set_debug (int fd, int argc, char *argv[])
static int misdn_set_opt_exec (struct ast_channel *chan, void *data)
static int misdn_set_tics (int fd, int argc, char *argv[])
static int misdn_show_cl (int fd, int argc, char *argv[])
static int misdn_show_cls (int fd, int argc, char *argv[])
static int misdn_show_config (int fd, int argc, char *argv[])
static int misdn_show_port (int fd, int argc, char *argv[])
static int misdn_show_ports_stats (int fd, int argc, char *argv[])
static int misdn_show_stacks (int fd, int argc, char *argv[])
static int misdn_tasks_add (int timeout, ast_sched_cb callback, void *data)
static int misdn_tasks_add_variable (int timeout, ast_sched_cb callback, void *data)
static void misdn_tasks_destroy (void)
static void misdn_tasks_init (void)
static void misdn_tasks_remove (int task_id)
static void * misdn_tasks_thread_func (void *data)
static void misdn_tasks_wakeup (void)
static int misdn_toggle_echocancel (int fd, int argc, char *argv[])
static void misdn_transfer_bc (struct chan_list *tmp_ch, struct chan_list *holded_chan)
static int misdn_write (struct ast_channel *ast, struct ast_frame *frame)
static int pbx_start_chan (struct chan_list *ch)
static void print_bc_info (int fd, struct chan_list *help, struct misdn_bchannel *bc)
static void print_bearer (struct misdn_bchannel *bc)
static void print_facility (struct FacParm *fac, struct misdn_bchannel *bc)
static struct ast_frameprocess_ast_dsp (struct chan_list *tmp, struct ast_frame *frame)
static int read_config (struct chan_list *ch, int orig)
static void release_chan (struct misdn_bchannel *bc)
static int reload (void)
static void reload_config (void)
static void send_cause2ast (struct ast_channel *ast, struct misdn_bchannel *bc, struct chan_list *ch)
static void send_digit_to_chan (struct chan_list *cl, char digit)
static void show_config_description (int fd, enum misdn_cfg_elements elem)
static void sighandler (int sig)
static int start_bc_tones (struct chan_list *cl)
static int stop_bc_tones (struct chan_list *cl)
static int stop_indicate (struct chan_list *cl)
static int unload_module (void)
static int update_config (struct chan_list *ch, int orig)
static int update_ec_config (struct misdn_bchannel *bc)
static void update_name (struct ast_channel *tmp, int port, int c)

Variables

allowed_bearers allowed_bearers_array []
static struct ast_cli_entry chan_misdn_clis []
chan_listcl_te = NULL
ast_mutex_t cl_te_lock
chan_list dummy_cl
static int g_config_initialized = 0
static int glob_channel = 0
char global_tracefile [BUFFERSIZE+1]
ast_mutex_t lock
static int max_ports
int MAXTICS = 8
static int * misdn_debug
static int * misdn_debug_only
static int * misdn_in_calls
static char ** misdn_key_vector = NULL
static int misdn_key_vector_size = 0
static int * misdn_out_calls
static int * misdn_ports
static struct sched_contextmisdn_tasks = NULL
static pthread_t misdn_tasks_thread
static struct ast_channel_tech misdn_tech
static struct ast_channel_tech misdn_tech_wo_bridge
static const char misdn_type [] = "mISDN"
static int prefformat = AST_FORMAT_ALAW
static struct robin_listrobin = NULL
static struct state_struct state_array []
static int tracing = 0


Define Documentation

#define AST_BRIDGED_P ast   )     ast_bridged_channel(ast)
 

Definition at line 290 of file chan_misdn.c.

Referenced by misdn_transfer_bc().

#define AST_CID_P ast   )     ast->cid.cid_num
 

Definition at line 289 of file chan_misdn.c.

Referenced by do_immediate_setup(), misdn_call(), misdn_hangup(), print_bc_info(), process_ast_dsp(), and release_chan().

#define AST_DESTROY_CFG   ast_config_destroy
 

Definition at line 292 of file chan_misdn.c.

#define AST_LOAD_CFG   ast_config_load
 

Definition at line 291 of file chan_misdn.c.

Referenced by misdn_cfg_init().

#define MISDN_ASTERISK_PVT ast   )     1
 

Definition at line 295 of file chan_misdn.c.

Referenced by cb_events(), and do_immediate_setup().

#define MISDN_ASTERISK_TECH_PVT ast   )     ast->tech_pvt
 

Definition at line 294 of file chan_misdn.c.

Referenced by cb_events(), do_immediate_setup(), misdn_answer(), misdn_call(), misdn_digit_end(), misdn_facility_exec(), misdn_fixup(), misdn_hangup(), misdn_indication(), misdn_read(), misdn_set_opt_exec(), misdn_write(), and release_chan().

#define ORG_AST   1
 

Definition at line 138 of file chan_misdn.c.

Referenced by misdn_call(), misdn_hangup(), misdn_request(), print_bc_info(), read_config(), and release_chan().

#define ORG_MISDN   2
 

Definition at line 139 of file chan_misdn.c.

Referenced by cb_events(), do_immediate_setup(), and misdn_indication().


Enumeration Type Documentation

enum misdn_chan_state
 

Enumerator:
MISDN_NOTHING  at beginning
MISDN_WAITING4DIGS  when waiting for infos
MISDN_EXTCANTMATCH  when asterisk couldnt match our ext
MISDN_DIALING  when pbx_start
MISDN_PROGRESS  we got a progress
MISDN_PROCEEDING  we got a progress
MISDN_CALLING  when misdn_call is called
MISDN_CALLING_ACKNOWLEDGE  when we get SETUP_ACK
MISDN_ALERTING  when Alerting
MISDN_BUSY  when BUSY
MISDN_CONNECTED  when connected
MISDN_PRECONNECTED  when connected
MISDN_DISCONNECTED  when connected
MISDN_RELEASED  when connected
MISDN_BRIDGED  when bridged
MISDN_CLEANING  when hangup from * but we were connected before
MISDN_HUNGUP_FROM_MISDN  when DISCONNECT/RELEASE/REL_COMP cam from misdn
MISDN_HUNGUP_FROM_AST  when DISCONNECT/RELEASE/REL_COMP came out of
MISDN_HOLDED  if this chan is holded
MISDN_HOLD_DISCONNECT  if this chan is holded

Definition at line 113 of file chan_misdn.c.

00113                       {
00114    MISDN_NOTHING=0,  /*!< at beginning */
00115    MISDN_WAITING4DIGS, /*!<  when waiting for infos */
00116    MISDN_EXTCANTMATCH, /*!<  when asterisk couldnt match our ext */
00117    MISDN_DIALING, /*!<  when pbx_start */
00118    MISDN_PROGRESS, /*!<  we got a progress */
00119    MISDN_PROCEEDING, /*!<  we got a progress */
00120    MISDN_CALLING, /*!<  when misdn_call is called */
00121    MISDN_CALLING_ACKNOWLEDGE, /*!<  when we get SETUP_ACK */
00122    MISDN_ALERTING, /*!<  when Alerting */
00123    MISDN_BUSY, /*!<  when BUSY */
00124    MISDN_CONNECTED, /*!<  when connected */
00125    MISDN_PRECONNECTED, /*!<  when connected */
00126    MISDN_DISCONNECTED, /*!<  when connected */
00127    MISDN_RELEASED, /*!<  when connected */
00128    MISDN_BRIDGED, /*!<  when bridged */
00129    MISDN_CLEANING, /*!< when hangup from * but we were connected before */
00130    MISDN_HUNGUP_FROM_MISDN, /*!< when DISCONNECT/RELEASE/REL_COMP  cam from misdn */
00131    MISDN_HUNGUP_FROM_AST, /*!< when DISCONNECT/RELEASE/REL_COMP came out of */
00132    /* misdn_hangup */
00133    MISDN_HOLDED, /*!< if this chan is holded */
00134    MISDN_HOLD_DISCONNECT, /*!< if this chan is holded */
00135   
00136 };


Function Documentation

static int _misdn_tasks_add_variable int  timeout,
ast_sched_cb  callback,
void *  data,
int  variable
[inline, static]
 

Definition at line 556 of file chan_misdn.c.

References ast_sched_add_variable(), misdn_tasks, misdn_tasks_init(), and misdn_tasks_wakeup().

Referenced by misdn_tasks_add(), and misdn_tasks_add_variable().

00557 {
00558    int task_id;
00559 
00560    if (!misdn_tasks) {
00561       misdn_tasks_init();
00562    }
00563    task_id = ast_sched_add_variable(misdn_tasks, timeout, callback, data, variable);
00564    misdn_tasks_wakeup();
00565 
00566    return task_id;
00567 }

int add_in_calls int  port  ) 
 

Definition at line 3593 of file chan_misdn.c.

References ast_log(), LOG_NOTICE, misdn_cfg_get(), and misdn_in_calls.

Referenced by cb_events().

03594 {
03595    int max_in_calls;
03596    
03597    misdn_cfg_get( port, MISDN_CFG_MAX_IN, &max_in_calls, sizeof(max_in_calls));
03598 
03599    misdn_in_calls[port]++;
03600 
03601    if (max_in_calls >=0 && max_in_calls<misdn_in_calls[port]) {
03602       ast_log(LOG_NOTICE,"Marking Incoming Call on port[%d]\n",port);
03603       return misdn_in_calls[port]-max_in_calls;
03604    }
03605    
03606    return 0;
03607 }

int add_out_calls int  port  ) 
 

Definition at line 3609 of file chan_misdn.c.

References ast_log(), LOG_NOTICE, misdn_cfg_get(), and misdn_out_calls.

Referenced by misdn_call().

03610 {
03611    int max_out_calls;
03612    
03613    misdn_cfg_get( port, MISDN_CFG_MAX_OUT, &max_out_calls, sizeof(max_out_calls));
03614    
03615 
03616    if (max_out_calls >=0 && max_out_calls<=misdn_out_calls[port]) {
03617       ast_log(LOG_NOTICE,"Rejecting Outgoing Call on port[%d]\n",port);
03618       return (misdn_out_calls[port]+1)-max_out_calls;
03619    }
03620 
03621    misdn_out_calls[port]++;
03622    
03623    return 0;
03624 }

AST_MODULE_INFO ASTERISK_GPL_KEY  ,
AST_MODFLAG_DEFAULT  ,
"Channel driver for mISDN Support (BRI/PRI)"  ,
load = load_module,
unload = unload_module,
reload = reload
 

static char* bearer2str int  cap  )  [static]
 

Definition at line 406 of file chan_misdn.c.

Referenced by print_bc_info(), and print_bearer().

00406                                  {
00407    static char *bearers[]={
00408       "Speech",
00409       "Audio 3.1k",
00410       "Unres Digital",
00411       "Res Digital",
00412       "Video",
00413       "Unknown Bearer"
00414    };
00415    
00416    switch (cap) {
00417    case INFO_CAPABILITY_SPEECH:
00418       return bearers[0];
00419       break;
00420    case INFO_CAPABILITY_AUDIO_3_1K:
00421       return bearers[1];
00422       break;
00423    case INFO_CAPABILITY_DIGITAL_UNRESTRICTED:
00424       return bearers[2];
00425       break;
00426    case INFO_CAPABILITY_DIGITAL_RESTRICTED:
00427       return bearers[3];
00428       break;
00429    case INFO_CAPABILITY_VIDEO:
00430       return bearers[4];
00431       break;
00432    default:
00433       return bearers[5];
00434       break;
00435    }
00436 }

static enum event_response_e cb_events enum event_e  event,
struct misdn_bchannel *  bc,
void *  user_data
[static]
 

Sending SETUP_ACK

queue new chan

Sending SETUP_ACK

ADD IGNOREPAT

Suplementary Services

Definition at line 3632 of file chan_misdn.c.

References add_in_calls(), chan_list::addr, chan_list::allowed_bearers, allowed_bearers_array, chan_list::ast, ast_canmatch_extension(), ast_cdr_update(), ast_exists_extension(), AST_FORMAT_ALAW, AST_FRAME_DTMF, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_pickup_call(), ast_pickup_ext(), AST_PRES_ALLOWED, AST_PRES_NETWORK_NUMBER, AST_PRES_RESTRICTED, AST_PRES_UNAVAILABLE, AST_PRES_USER_NUMBER_FAILED_SCREEN, AST_PRES_USER_NUMBER_PASSED_SCREEN, AST_PRES_USER_NUMBER_UNSCREENED, ast_queue_frame(), ast_setstate(), AST_STATE_DOWN, AST_STATE_RESERVED, AST_STATE_RINGING, ast_strlen_zero(), ast_transfercapability2str(), chan_list::bc, chan_misdn_log(), ast_channel::cid, ast_callerid::cid_pres, cl_queue_chan(), cl_te, chan_list::context, ast_frame::data, ast_frame::datalen, ast_frame::delivery, export_ch(), ast_channel::exten, find_chan_by_bc(), find_holded(), ast_frame::frametype, hangup_chan(), hanguptone_indicate(), chan_list::ignore_dtmf, init_chan_list(), chan_list::l3id, LOG_NOTICE, LOG_WARNING, ast_frame::mallocd, MISDN_ASTERISK_PVT, MISDN_ASTERISK_TECH_PVT, MISDN_CALLING_ACKNOWLEDGE, misdn_cfg_get(), misdn_cfg_is_msn_valid(), MISDN_CONNECTED, MISDN_DIALING, MISDN_EXTCANTMATCH, misdn_get_ch_state(), misdn_new(), MISDN_NOTHING, misdn_overlap_dial_task(), misdn_tasks_add_variable(), MISDN_WAITING4DIGS, allowed_bearers::name, ast_frame::offset, ORG_MISDN, chan_list::orginator, chan_list::overlap_dial, chan_list::overlap_dial_task, chan_list::overlap_tv, chan_list::overlap_tv_lock, pbx_builtin_setvar_helper(), pbx_start_chan(), print_bearer(), read_config(), ast_channel::rings, ast_frame::samples, ast_frame::src, chan_list::state, stop_indicate(), ast_frame::subclass, ast_channel::transfercapability, and update_name().

03633 {
03634    struct chan_list *ch=find_chan_by_bc(cl_te, bc);
03635    
03636    if (event != EVENT_BCHAN_DATA && event != EVENT_TONE_GENERATE) { /*  Debug Only Non-Bchan */
03637       int debuglevel=1;
03638       if ( event==EVENT_CLEANUP && !user_data)
03639          debuglevel=5;
03640 
03641       chan_misdn_log(debuglevel, bc->port, "I IND :%s oad:%s dad:%s pid:%d state:%s\n", manager_isdn_get_info(event), bc->oad, bc->dad, bc->pid, ch?misdn_get_ch_state(ch):"none");
03642       if (debuglevel==1) {
03643          misdn_lib_log_ies(bc);
03644          chan_misdn_log(4,bc->port," --> bc_state:%s\n",bc_state2str(bc->bc_state));
03645       }
03646    }
03647    
03648    if (!ch) {
03649       switch(event) {
03650          case EVENT_SETUP:
03651          case EVENT_DISCONNECT:
03652          case EVENT_PORT_ALARM:
03653          case EVENT_RETRIEVE:
03654          case EVENT_NEW_BC:
03655          case EVENT_FACILITY:
03656             break;
03657          case EVENT_RELEASE_COMPLETE:
03658             chan_misdn_log(1, bc->port, " --> no Ch, so we've already released.\n");
03659             break;
03660          case EVENT_CLEANUP:
03661          case EVENT_TONE_GENERATE:
03662          case EVENT_BCHAN_DATA:
03663             return -1;
03664 
03665          default:
03666             chan_misdn_log(1,bc->port, "Chan not existing at the moment bc->l3id:%x bc:%p event:%s port:%d channel:%d\n",bc->l3_id, bc, manager_isdn_get_info( event), bc->port,bc->channel);
03667             return -1;
03668       }
03669    }
03670    
03671    if (ch ) {
03672       switch (event) {
03673       case EVENT_TONE_GENERATE:
03674       break;
03675       case EVENT_DISCONNECT:
03676       case EVENT_RELEASE:
03677       case EVENT_RELEASE_COMPLETE:
03678       case EVENT_CLEANUP:
03679       case EVENT_TIMEOUT:
03680          if (!ch->ast)
03681             chan_misdn_log(3,bc->port,"ast_hangup already called, so we have no ast ptr anymore in event(%s)\n",manager_isdn_get_info(event));
03682          break;
03683       default:
03684          if ( !ch->ast  || !MISDN_ASTERISK_PVT(ch->ast) || !MISDN_ASTERISK_TECH_PVT(ch->ast)) {
03685             if (event!=EVENT_BCHAN_DATA)
03686                ast_log(LOG_NOTICE, "No Ast or No private Pointer in Event (%d:%s)\n", event, manager_isdn_get_info(event));
03687             return -1;
03688          }
03689       }
03690    }
03691    
03692    
03693    switch (event) {
03694    case EVENT_PORT_ALARM:
03695       {
03696          int boa=0;
03697          misdn_cfg_get( bc->port, MISDN_CFG_ALARM_BLOCK, &boa, sizeof(int));
03698          if (boa) {
03699             cb_log(1,bc->port," --> blocking\n");
03700             misdn_lib_port_block(bc->port); 
03701          }
03702       }
03703    break;
03704    case EVENT_BCHAN_ACTIVATED:
03705       break;
03706       
03707    case EVENT_NEW_CHANNEL:
03708       update_name(ch->ast,bc->port,bc->channel);
03709       break;
03710       
03711    case EVENT_NEW_L3ID:
03712       ch->l3id=bc->l3_id;
03713       ch->addr=bc->addr;
03714       break;
03715 
03716    case EVENT_NEW_BC:
03717       if (!ch) {
03718          ch=find_holded(cl_te,bc);
03719       }
03720       
03721       if (!ch) {
03722          ast_log(LOG_WARNING,"NEW_BC without chan_list?\n");
03723          break;
03724       }
03725 
03726       if (bc)
03727          ch->bc=(struct misdn_bchannel*)user_data;
03728       break;
03729       
03730    case EVENT_DTMF_TONE:
03731    {
03732       /*  sending INFOS as DTMF-Frames :) */
03733       struct ast_frame fr;
03734       memset(&fr, 0 , sizeof(fr));
03735       fr.frametype = AST_FRAME_DTMF;
03736       fr.subclass = bc->dtmf ;
03737       fr.src=NULL;
03738       fr.data = NULL ;
03739       fr.datalen = 0;
03740       fr.samples = 0 ;
03741       fr.mallocd =0 ;
03742       fr.offset= 0 ;
03743       fr.delivery= ast_tv(0,0) ;
03744       
03745       if (!ch->ignore_dtmf) {
03746          chan_misdn_log(2, bc->port, " --> DTMF:%c\n", bc->dtmf);
03747          ast_queue_frame(ch->ast, &fr);
03748       } else {
03749          chan_misdn_log(2, bc->port, " --> Ingoring DTMF:%c due to bridge flags\n", bc->dtmf);
03750       }
03751    }
03752    break;
03753    case EVENT_STATUS:
03754       break;
03755     
03756    case EVENT_INFORMATION:
03757    {
03758       int stop_tone;
03759       misdn_cfg_get( 0, MISDN_GEN_STOP_TONE, &stop_tone, sizeof(int));
03760       if ( stop_tone ) {
03761          stop_indicate(ch);
03762       }
03763       
03764       if (ch->state == MISDN_WAITING4DIGS ) {
03765          /*  Ok, incomplete Setup, waiting till extension exists */
03766 
03767          if (ast_strlen_zero(bc->info_dad) && ! ast_strlen_zero(bc->keypad)) {
03768             chan_misdn_log(1, bc->port, " --> using keypad as info\n");
03769             strcpy(bc->info_dad,bc->keypad);
03770          }
03771 
03772          {
03773             int l = sizeof(bc->dad);
03774             strncat(bc->dad,bc->info_dad, l);
03775             bc->dad[l-1] = 0;
03776          }
03777          
03778          
03779          {
03780             int l = sizeof(ch->ast->exten);
03781             strncpy(ch->ast->exten, bc->dad, l);
03782             ch->ast->exten[l-1] = 0;
03783          }
03784 /*       chan_misdn_log(5, bc->port, "Can Match Extension: dad:%s oad:%s\n",bc->dad,bc->oad);*/
03785          
03786          /* Check for Pickup Request first */
03787          if (!strcmp(ch->ast->exten, ast_pickup_ext())) {
03788             int ret;/** Sending SETUP_ACK**/
03789             ret = misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE );
03790             if (ast_pickup_call(ch->ast)) {
03791                hangup_chan(ch);
03792             } else {
03793                struct ast_channel *chan=ch->ast;
03794                ch->state = MISDN_CALLING_ACKNOWLEDGE;
03795                ast_setstate(chan, AST_STATE_DOWN);
03796                hangup_chan(ch);
03797                ch->ast=NULL;
03798                break;
03799             }
03800          }
03801          
03802          if(!ast_canmatch_extension(ch->ast, ch->context, bc->dad, 1, bc->oad)) {
03803 
03804             chan_misdn_log(-1, bc->port, "Extension can never match, so disconnecting\n");
03805             if (bc->nt)
03806                hanguptone_indicate(ch);
03807             ch->state=MISDN_EXTCANTMATCH;
03808             bc->out_cause=1;
03809 
03810             misdn_lib_send_event(bc, EVENT_DISCONNECT );
03811 
03812             break;
03813          }
03814 
03815          if (ch->overlap_dial) {
03816             ast_mutex_lock(&ch->overlap_tv_lock);
03817             ch->overlap_tv = ast_tvnow();
03818             ast_mutex_unlock(&ch->overlap_tv_lock);
03819             if (ch->overlap_dial_task == -1) {
03820                ch->overlap_dial_task = 
03821                   misdn_tasks_add_variable(ch->overlap_dial, misdn_overlap_dial_task, ch);
03822             }
03823             break;
03824          }
03825 
03826          if (ast_exists_extension(ch->ast, ch->context, bc->dad, 1, bc->oad)) {
03827             ch->state=MISDN_DIALING;
03828      
03829             stop_indicate(ch);
03830 /*          chan_misdn_log(1, bc->port, " --> * Starting Ast ctx:%s\n", ch->context);*/
03831             if (pbx_start_chan(ch)<0) {
03832                hangup_chan(ch);
03833 
03834                chan_misdn_log(-1, bc->port, "ast_pbx_start returned < 0 in INFO\n");
03835                if (bc->nt) hanguptone_indicate(ch);
03836 
03837                misdn_lib_send_event(bc, EVENT_DISCONNECT );
03838             }
03839          }
03840    
03841       } else {
03842          /*  sending INFOS as DTMF-Frames :) */
03843          struct ast_frame fr;
03844          fr.frametype = AST_FRAME_DTMF;
03845          fr.subclass = bc->info_dad[0] ;
03846          fr.src=NULL;
03847          fr.data = NULL ;
03848          fr.datalen = 0;
03849          fr.samples = 0 ;
03850          fr.mallocd =0 ;
03851          fr.offset= 0 ;
03852          fr.delivery= ast_tv(0,0) ;
03853 
03854          
03855          int digits;
03856          misdn_cfg_get( 0, MISDN_GEN_APPEND_DIGITS2EXTEN, &digits, sizeof(int));
03857          if (ch->state != MISDN_CONNECTED ) {
03858             if (digits) {
03859                int l = sizeof(bc->dad);
03860                strncat(bc->dad,bc->info_dad, l);
03861                bc->dad[l-1] = 0;
03862                l = sizeof(ch->ast->exten);
03863                strncpy(ch->ast->exten, bc->dad, l);
03864                ch->ast->exten[l-1] = 0;
03865 
03866                ast_cdr_update(ch->ast);
03867             }
03868             
03869             ast_queue_frame(ch->ast, &fr);
03870          }
03871       }
03872    }
03873    break;
03874    case EVENT_SETUP:
03875    {
03876       struct chan_list *ch=find_chan_by_bc(cl_te, bc);
03877       if (ch) {
03878          switch (ch->state) {
03879             case MISDN_NOTHING:
03880             ch=NULL;
03881