Sat Nov 25 00:45:54 2006

Asterisk developer's documentation


chan_misdn.c File Reference

the chan_misdn channel driver for Asterisk More...

#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 <sys/file.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 <chan_misdn_config.h>
#include <isdn_lib.h>
#include <asterisk/strings.h>

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,
  MISDN_FIXUP
}

Functions

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 (char *line, char *word, int pos, int state)
static char * complete_ch_helper (char *line, char *word, int pos, int state, int rpos)
static char * complete_debug_port (char *line, char *word, int pos, int state)
void config_jitterbuffer (struct chan_list *ch)
void debug_numplan (int port, int numplan, char *type)
char * description (void)
 Provides a description of the module.
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)
char * key (void)
 Returns the ASTERISK_GPL_KEY.
int load_module (void)
 Initialize the module.
static int misdn_answer (struct ast_channel *ast)
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 (struct ast_channel *ast, char digit)
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)
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 struct ast_channelmisdn_new (struct chan_list *cl, int state, char *exten, char *callerid, int format, int port, int c)
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_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[])
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_stacks (int fd, int argc, char *argv[])
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 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)
int reload (void)
 Reload stuff.
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 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)
int unload_module (void)
 Cleanup all module structures, sockets, etc.
static int update_config (struct chan_list *ch, int orig)
static int update_ec_config (struct misdn_bchannel *bc)
int usecount (void)
 Provides a usecount.

Variables

allowed_bearers allowed_bearers_array []
chan_listcl_te = NULL
ast_mutex_t cl_te_lock
static struct ast_cli_entry cli_port_block
static struct ast_cli_entry cli_port_down
static struct ast_cli_entry cli_port_unblock
static struct ast_cli_entry cli_port_up
static struct ast_cli_entry cli_reload
static struct ast_cli_entry cli_restart_port
static struct ast_cli_entry cli_send_cd
static struct ast_cli_entry cli_send_digit
static struct ast_cli_entry cli_send_display
static struct ast_cli_entry cli_set_crypt_debug
static struct ast_cli_entry cli_set_debug
static struct ast_cli_entry cli_set_tics
static struct ast_cli_entry cli_show_cl
static struct ast_cli_entry cli_show_cls
static struct ast_cli_entry cli_show_config
static struct ast_cli_entry cli_show_port
static struct ast_cli_entry cli_show_stacks
static struct ast_cli_entry cli_toggle_echocancel
static char * desc = "Channel driver for mISDN Support (Bri/Pri)"
chan_list dummy_cl
static int g_config_initialized = 0
static unsigned long 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 char ** misdn_key_vector = NULL
static int misdn_key_vector_size = 0
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
static int usecnt = 0
static ast_mutex_t usecnt_lock


Detailed Description

the chan_misdn channel driver for Asterisk

Author:
Christian Richter <crich@beronet.com>

Definition in file chan_misdn.c.


Define Documentation

#define AST_BRIDGED_P ast   )     ast_bridged_channel(ast)
 

Definition at line 265 of file chan_misdn.c.

Referenced by misdn_transfer_bc().

#define AST_CID_P ast   )     ast->cid.cid_num
 

Definition at line 264 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 267 of file chan_misdn.c.

#define AST_LOAD_CFG   ast_config_load
 

Definition at line 266 of file chan_misdn.c.

Referenced by misdn_cfg_init().

#define MISDN_ASTERISK_PVT ast   )     1
 

Definition at line 270 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 269 of file chan_misdn.c.

Referenced by cb_events(), do_immediate_setup(), misdn_answer(), misdn_call(), misdn_digit(), 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 130 of file chan_misdn.c.

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

#define ORG_MISDN   2
 

Definition at line 131 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
MISDN_FIXUP  if this chan is holded

Definition at line 104 of file chan_misdn.c.

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


Function Documentation

static char* bearer2str int  cap  )  [static]
 

Definition at line 367 of file chan_misdn.c.

Referenced by print_bc_info(), and print_bearer().

00367                                  {
00368    static char *bearers[]={
00369       "Speech",
00370       "Audio 3.1k",
00371       "Unres Digital",
00372       "Res Digital",
00373       "Video",
00374       "Unknown Bearer"
00375    };
00376    
00377    switch (cap) {
00378    case INFO_CAPABILITY_SPEECH:
00379       return bearers[0];
00380       break;
00381    case INFO_CAPABILITY_AUDIO_3_1K:
00382       return bearers[1];
00383       break;
00384    case INFO_CAPABILITY_DIGITAL_UNRESTRICTED:
00385       return bearers[2];
00386       break;
00387    case INFO_CAPABILITY_DIGITAL_RESTRICTED:
00388       return bearers[3];
00389       break;
00390    case INFO_CAPABILITY_VIDEO:
00391       return bearers[4];
00392       break;
00393    default:
00394       return bearers[5];
00395       break;
00396    }
00397 }

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 3191 of file chan_misdn.c.

References 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_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_WAITING4DIGS, allowed_bearers::name, ast_frame::offset, ORG_MISDN, chan_list::orginator, 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, and ast_channel::transfercapability.

Referenced by load_module().

03192 {
03193    struct chan_list *ch=find_chan_by_bc(cl_te, bc);
03194    
03195    if (event != EVENT_BCHAN_DATA && event != EVENT_TONE_GENERATE) { /*  Debug Only Non-Bchan */
03196       int debuglevel=1;
03197    
03198       if ( event==EVENT_CLEANUP && !user_data)
03199          debuglevel=5;
03200 
03201       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");
03202       if (debuglevel==1) {
03203          misdn_lib_log_ies(bc);
03204          chan_misdn_log(4,bc->port," --> bc_state:%s\n",bc_state2str(bc->bc_state));
03205       }
03206    }
03207    
03208    if (!ch) {
03209       switch(event) {
03210          case EVENT_SETUP:
03211          case EVENT_DISCONNECT:
03212          case EVENT_PORT_ALARM:
03213          case EVENT_RETRIEVE:
03214          case EVENT_NEW_BC:
03215             break;
03216          case EVENT_RELEASE_COMPLETE:
03217             chan_misdn_log(1, bc->port, " --> no Ch, so we've already released.\n");
03218             break;
03219          case EVENT_CLEANUP:
03220          case EVENT_TONE_GENERATE:
03221          case EVENT_BCHAN_DATA:
03222             return -1;
03223 
03224          default:
03225             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);
03226             return -1;
03227       }
03228    }
03229    
03230    if (ch ) {
03231       switch (event) {
03232       case EVENT_TONE_GENERATE:
03233       break;
03234       case EVENT_DISCONNECT:
03235       case EVENT_RELEASE:
03236       case EVENT_RELEASE_COMPLETE:
03237       case EVENT_CLEANUP:
03238       case EVENT_TIMEOUT:
03239          if (!ch->ast)
03240             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));
03241          break;
03242       default:
03243          if ( !ch->ast  || !MISDN_ASTERISK_PVT(ch->ast) || !MISDN_ASTERISK_TECH_PVT(ch->ast)) {
03244             if (event!=EVENT_BCHAN_DATA)
03245                ast_log(LOG_NOTICE, "No Ast or No private Pointer in Event (%d:%s)\n", event, manager_isdn_get_info(event));
03246             return -1;
03247          }
03248       }
03249    }
03250    
03251    
03252    switch (event) {
03253    case EVENT_PORT_ALARM:
03254       {
03255          int boa=0;
03256 
03257          misdn_cfg_get( bc->port, MISDN_CFG_ALARM_BLOCK, &boa, sizeof(int));
03258          if (boa) {
03259             cb_log(1,bc->port," --> blocking\n");
03260             misdn_lib_port_block(bc->port);  
03261          }
03262       }
03263       break;
03264 
03265    case EVENT_BCHAN_ACTIVATED:
03266       break;
03267       
03268    case EVENT_NEW_L3ID:
03269       ch->l3id=bc->l3_id;
03270       ch->addr=bc->addr;
03271       break;
03272 
03273    case EVENT_NEW_BC:
03274       if (!ch) {
03275          ch=find_holded(cl_te,bc);
03276       }
03277       
03278       if (!ch) {
03279          ast_log(LOG_WARNING,"NEW_BC without chan_list?\n");
03280          break;
03281       }
03282 
03283       if (bc)
03284          ch->bc=(struct misdn_bchannel*)user_data;
03285       break;
03286       
03287    case EVENT_DTMF_TONE:
03288    {
03289       /*  sending INFOS as DTMF-Frames :) */
03290       struct ast_frame fr;
03291       memset(&fr, 0 , sizeof(fr));
03292       fr.frametype = AST_FRAME_DTMF;
03293       fr.subclass = bc->dtmf ;
03294       fr.src=NULL;
03295       fr.data = NULL ;
03296       fr.datalen = 0;
03297       fr.samples = 0 ;
03298       fr.mallocd =0 ;
03299       fr.offset= 0 ;
03300       fr.delivery= ast_tv(0,0) ;
03301       
03302       if (!ch->ignore_dtmf) {
03303          chan_misdn_log(2, bc->port, " --> DTMF:%c\n", bc->dtmf);
03304          ast_queue_frame(ch->ast, &fr);
03305       } else {
03306          chan_misdn_log(2, bc->port, " --> Ingoring DTMF:%c due to bridge flags\n", bc->dtmf);
03307       }
03308    }
03309    break;
03310    case EVENT_STATUS:
03311       break;
03312     
03313    case EVENT_INFORMATION:
03314    {
03315       int stop_tone;
03316       misdn_cfg_get( 0, MISDN_GEN_STOP_TONE, &stop_tone, sizeof(int));
03317       if ( stop_tone ) {
03318          stop_indicate(ch);
03319       }
03320       
03321       if (ch->state == MISDN_WAITING4DIGS ) {
03322          /*  Ok, incomplete Setup, waiting till extension exists */
03323 
03324          if (ast_strlen_zero(bc->info_dad) && ! ast_strlen_zero(bc->keypad)) {
03325             chan_misdn_log(1, bc->port, " --> using keypad as info\n");
03326             strcpy(bc->info_dad,bc->keypad);
03327          }
03328 
03329          {
03330             int l = sizeof(bc->dad);
03331             strncat(bc->dad,bc->info_dad, l);
03332             bc->dad[l-1] = 0;
03333          }
03334          
03335          
03336          {
03337             int l = sizeof(ch->ast->exten);
03338             strncpy(ch->ast->exten, bc->dad, l);
03339             ch->ast->exten[l-1] = 0;
03340          }
03341 /*       chan_misdn_log(5, bc->port, "Can Match Extension: dad:%s oad:%s\n",bc->dad,bc->oad);*/
03342          
03343          /* Check for Pickup Request first */
03344          if (!strcmp(ch->ast->exten, ast_pickup_ext())) {
03345             int ret;/** Sending SETUP_ACK**/
03346             ret = misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE );
03347             if (ast_pickup_call(ch->ast)) {
03348                hangup_chan(ch);
03349             } else {
03350                struct ast_channel *chan=ch->ast;
03351                ch->state = MISDN_CALLING_ACKNOWLEDGE;
03352                ast_setstate(chan, AST_STATE_DOWN);
03353                hangup_chan(ch);
03354                ch->ast=NULL;
03355                break;
03356             }
03357          }
03358          
03359          if(!ast_canmatch_extension(ch->ast, ch->context, bc->dad, 1, bc->oad)) {
03360 
03361             chan_misdn_log(-1, bc->port, "Extension can never match, so disconnecting\n");
03362             if (bc->nt)
03363                hanguptone_indicate(ch);
03364             ch->state=MISDN_EXTCANTMATCH;
03365             bc->out_cause=1;
03366 
03367             misdn_lib_send_event(bc, EVENT_DISCONNECT );
03368 
03369             break;
03370          }
03371          if (ast_exists_extension(ch->ast, ch->context, bc->dad, 1, bc->oad)) {
03372             ch->state=MISDN_DIALING;
03373      
03374             stop_indicate(ch);
03375 /*          chan_misdn_log(1, bc->port, " --> * Starting Ast ctx:%s\n", ch->context);*/
03376             if (pbx_start_chan(ch)<0) {
03377                hangup_chan(ch);
03378 
03379                chan_misdn_log(-1, bc->port, "ast_pbx_start returned < 0 in INFO\n");
03380                if (bc->nt) hanguptone_indicate(ch);
03381 
03382                misdn_lib_send_event(bc, EVENT_DISCONNECT );
03383             }
03384          }
03385    
03386       } else {
03387          /*  sending INFOS as DTMF-Frames :) */
03388          struct ast_frame fr;
03389          fr.frametype = AST_FRAME_DTMF;
03390          fr.subclass = bc->info_dad[0] ;
03391          fr.src=NULL;
03392          fr.data = NULL ;
03393          fr.datalen = 0;
03394          fr.samples = 0 ;
03395          fr.mallocd =0 ;
03396          fr.offset= 0 ;
03397          fr.delivery= ast_tv(0,0) ;
03398 
03399          
03400          int digits;
03401          misdn_cfg_get( 0, MISDN_GEN_APPEND_DIGITS2EXTEN, &digits, sizeof(int));
03402          if (ch->state != MISDN_CONNECTED ) {
03403             if (digits) {
03404                int l = sizeof(bc->dad);
03405                strncat(bc->dad,bc->info_dad, l);
03406                bc->dad[l-1] = 0;
03407                l = sizeof(ch->ast->exten);
03408                strncpy(ch->ast->exten, bc->dad, l);
03409                ch->ast->exten[l-1] = 0;
03410 
03411                ast_cdr_update(ch->ast);
03412             }
03413             
03414             ast_queue_frame(ch->ast, &fr);
03415          }
03416       }
03417    }
03418    break;
03419    case EVENT_SETUP:
03420    {
03421       struct chan_list *ch=find_chan_by_bc(cl_te, bc);
03422       if (ch) {
03423          switch (ch->state) {
03424             case MISDN_NOTHING:
03425             ch=NULL;
03426             break;
03427             default:
03428             chan_misdn_log(1, bc->port, " --> Ignoring Call we have already one\n");
03429             return RESPONSE_IGNORE_SETUP_WITHOUT_CLOSE; /*  Ignore MSNs which are not in our List */
03430          }
03431       }
03432    }
03433    
03434 
03435    int msn_valid = misdn_cfg_is_msn_valid(bc->port, bc->dad);
03436    if (!bc->nt && ! msn_valid) {
03437       chan_misdn_log(1, bc->port, " --> Ignoring Call, its not in our MSN List\n");
03438       return RESPONSE_IGNORE_SETUP; /*  Ignore MSNs which are not in our List */
03439    }
03440    
03441    if (bc->cw) {
03442       chan_misdn_log(0, bc->port, " --> Call Waiting on PMP sending RELEASE_COMPLETE\n");
03443       int cause;
03444       misdn_cfg_get( bc->port, MISDN_CFG_REJECT_CAUSE, &cause, sizeof(cause));
03445       bc->out_cause=cause?cause:16;
03446       return RESPONSE_RELEASE_SETUP;
03447    }
03448 
03449    print_bearer(bc);
03450     
03451    {
03452       struct chan_list *ch=init_chan_list(ORG_MISDN);
03453       struct ast_channel *chan;
03454 
03455       if (!ch) { chan_misdn_log(-1, bc->port, "cb_events: malloc for chan_list failed!\n"); return 0;}
03456       
03457       ch->bc = bc;
03458       ch->l3id=bc->l3_id;
03459       ch->addr=bc->addr;
03460       ch->orginator = ORG_MISDN;
03461 
03462       chan=misdn_new(ch, AST_STATE_RESERVED,bc->dad, bc->oad, AST_FORMAT_ALAW, bc->port, bc->channel);
03463       ch->ast = chan;
03464 
03465       read_config(ch, ORG_MISDN);
03466       
03467       export_ch(chan, bc, ch);
03468 
03469       ch->ast->rings=1;
03470       ast_setstate(ch->ast, AST_STATE_RINGING);
03471 
03472       int pres,screen;
03473 
03474       switch (bc->pres) {
03475          case 1:
03476          pres=AST_PRES_RESTRICTED; chan_misdn_log(2,bc->port," --> PRES: Restricted (1)\n");
03477          break;
03478          case 2:
03479          pres=AST_PRES_UNAVAILABLE; chan_misdn_log(2,bc->port," --> PRES: Restricted (2)\n");
03480          break;
03481          default:
03482          pres=AST_PRES_ALLOWED; chan_misdn_log(2,bc->port," --> PRES: Restricted (%d)\n", bc->pres);
03483       }
03484 
03485       switch (bc->screen) {
03486          case 0:
03487          screen=AST_PRES_USER_NUMBER_UNSCREENED;  chan_misdn_log(2,bc->port," --> SCREEN: Unscreened (0)\n");
03488          break;
03489          case 1:
03490          screen=AST_PRES_USER_NUMBER_PASSED_SCREEN; chan_misdn_log(2,bc->port," --> SCREEN: Passed screen (1)\n");
03491          break;
03492          case 2:
03493          screen=AST_PRES_USER_NUMBER_FAILED_SCREEN; chan_misdn_log(2,bc->port," --> SCREEN: failed screen (2)\n");
03494          break;
03495          case 3:
03496          screen=AST_PRES_NETWORK_NUMBER; chan_misdn_log(2,bc->port," --> SCREEN: Network Number (3)\n");
03497          break;
03498          default:
03499          screen=AST_PRES_USER_NUMBER_UNSCREENED; chan_misdn_log(2,bc->port," --> SCREEN: Unscreened (%d)\n",bc->screen);
03500       }
03501 
03502       chan->cid.cid_pres=pres+screen;
03503 
03504       pbx_builtin_setvar_helper(chan, "TRANSFERCAPABILITY", ast_transfercapability2str(bc->capability));
03505       chan->transfercapability=bc->capability;
03506       
03507       switch (bc->capability) {
03508       case INFO_CAPABILITY_DIGITAL_UNRESTRICTED:
03509          pbx_builtin_setvar_helper(chan,"CALLTYPE","DIGITAL");
03510          break;
03511       default:
03512          pbx_builtin_setvar_helper(chan,"CALLTYPE","SPEECH");
03513       }
03514 
03515       /** queue new chan **/
03516       cl_queue_chan(&cl_te, ch) ;
03517 
03518 
03519       if (!strstr(ch->allowed_bearers,"all")) {
03520          int i;
03521          for (i=0; i< sizeof(allowed_bearers_array)/sizeof(struct allowed_bearers); i++) {
03522             if (allowed_bearers_array[i].cap == bc->capability) {
03523                if (  !strstr( ch->allowed_bearers, allowed_bearers_array[i].name)) {
03524                   chan_misdn_log(0,bc->port,"Bearer Not allowed\b");
03525                   bc->out_cause=88;
03526                   
03527                   ch->state=MISDN_EXTCANTMATCH;
03528                   misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE );
03529                   return RESPONSE_OK;
03530                }
03531             }
03532             
03533          }
03534       }
03535       
03536       /* Check for Pickup Request first */
03537       if (!strcmp(chan->exten, ast_pickup_ext())) {
03538          int ret;/** Sending SETUP_ACK**/
03539          ret = misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE );
03540          if (ast_pickup_call(chan)) {
03541             hangup_chan(ch);
03542          } else {
03543             ch->state = MISDN_CALLING_ACKNOWLEDGE;
03544             ast_setstate(chan, AST_STATE_DOWN);
03545             hangup_chan(ch);
03546             ch->ast=NULL;
03547             break;
03548          }
03549       }
03550       
03551       /*
03552         added support for s extension hope it will help those poor cretains
03553         which haven't overlap dial.
03554       */
03555       {
03556          int ai;
03557          misdn_cfg_get( bc->port, MISDN_CFG_ALWAYS_IMMEDIATE, &ai, sizeof(ai));
03558          if ( ai ) {
03559             do_immediate_setup(bc, ch , chan);
03560             break;
03561          }
03562          
03563          
03564          
03565       }
03566 
03567       /* check if we should jump into s when we have no dad */
03568       {
03569          int im;
03570          misdn_cfg_get( bc->port, MISDN_CFG_IMMEDIATE, &im, sizeof(im));
03571          if ( im && ast_strlen_zero(bc->dad) ) {
03572             do_immediate_setup(bc, ch , chan);
03573             break;
03574          }
03575       }
03576 
03577       
03578          chan_misdn_log(5,bc->port,"CONTEXT:%s\n",ch->context);
03579          if(!ast_canmatch_extension(ch->ast, ch->context, bc->dad, 1, bc->oad)) {
03580          
03581          chan_misdn_log(-1, bc->port, "Extension can never match, so disconnecting\n");
03582 
03583          if (bc->nt)
03584             hanguptone_indicate(ch);
03585          ch->state=MISDN_EXTCANTMATCH;
03586          bc->out_cause=1;
03587 
03588          if (bc->nt)
03589             misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE );
03590          else
03591             misdn_lib_send_event(bc, EVENT_RELEASE );
03592             
03593          break;
03594       }
03595       
03596       if (ast_exists_extension(ch->ast, ch->context, bc->dad, 1, bc->oad)) {
03597          ch->state=MISDN_DIALING;
03598          
03599          if (bc->nt || (bc->need_more_infos && misdn_lib_is_ptp(bc->port)) ) {
03600             int ret; 
03601             ret = misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE );
03602          } else {
03603             int ret;
03604             ret= misdn_lib_send_event(bc, EVENT_PROCEEDING );
03605          }
03606    
03607          if (pbx_start_chan(ch)<0) {
03608             hangup_chan(ch);
03609 
03610             chan_misdn_log(-1, bc->port, "ast_pbx_start returned <0 in SETUP\n");
03611             chan=NULL;
03612 
03613             if (bc->nt) {
03614                hanguptone_indicate(ch);
03615                misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE );
03616             } else
03617                misdn_lib_send_event(bc, EVENT_RELEASE);
03618          }
03619       } else {
03620 
03621          if (bc->sending_complete) {
03622             ch->state=MISDN_EXTCANTMATCH;
03623             bc->out_cause=1;
03624 
03625             if (bc->nt)  {
03626                chan_misdn_log(0,bc->port," --> sending_complete so we never match ..\n");
03627                misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE);
03628             } else {
03629                chan_misdn_log(0,bc->port," --> sending_complete so we never match ..\n");
03630                misdn_lib_send_event(bc, EVENT_RELEASE);
03631             }
03632 
03633          } else {
03634             
03635             int ret= misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE );
03636             if (ret == -ENOCHAN) {
03637                ast_log(LOG_WARNING,"Channel was catched, before we could Acknowledge\n");
03638                misdn_lib_send_event(bc,EVENT_RELEASE_COMPLETE);
03639             }
03640             /*  send tone to phone :) */
03641             
03642             /** ADD IGNOREPAT **/
03643             
03644             int stop_tone;
03645             misdn_cfg_get( 0, MISDN_GEN_STOP_TONE, &stop_tone, sizeof(int));
03646             if ( (!ast_strlen_zero(bc->dad)) && stop_tone ) 
03647                stop_indicate(ch);
03648             else {
03649                dialtone_indicate(ch);
03650             }
03651             
03652             ch->state=MISDN_WAITING4DIGS;
03653          }
03654       }
03655       
03656    }
03657    break;
03658    case EVENT_SETUP_ACKNOWLEDGE:
03659    {
03660       ch->state = MISDN_CALLING_ACKNOWLEDGE;
03661       if (!ast_strlen_zero(bc->infos_pending)) {
03662          /* TX Pending Infos */
03663          
03664          {
03665             int l = sizeof(bc->dad);
03666             strncat(bc->dad,bc->infos_pending, l - strlen(bc->dad));
03667             bc->dad[l-1] = 0;
03668          }  
03669          {
03670             int l = sizeof(ch->ast->exten);
03671             strncpy(ch->ast->exten, bc->dad, l);
03672             ch->ast->exten[l-1] = 0;
03673          }
03674          {
03675             int l = sizeof(bc->info_dad);
03676             strncpy(bc->info_dad, bc->infos_pending, l);
03677             bc->info_dad[l-1] = 0;
03678          }
03679          strncpy(bc->infos_pending,"", 1);
03680 
03681          misdn_lib_send_event(bc, EVENT_INFORMATION);
03682       }
03683    }
03684    break;
03685    case EVENT_PROCEEDING:
03686    {
03687       
03688       if ( misdn_cap_is_speech(bc->capability) &&
03689            misdn_inband_avail(bc) ) {
03690          start_bc_tones(ch);
03691       }
03692 
03693       ch->state = MISDN_PROCEEDING;
03694       
03695       ast_queue_control(ch->ast, AST_CONTROL_PROCEEDING);
03696    }
03697    break;
03698    case EVENT_PROGRESS:
03699       if (!bc->nt ) {
03700          if ( misdn_cap_is_speech(bc->capability) &&
03701               misdn_inband_avail(bc)
03702             ) {
03703             start_bc_tones(ch);
03704          }
03705          
03706          ast_queue_control(ch->ast, AST_CONTROL_PROGRESS);
03707          
03708          ch->state=MISDN_PROGRESS;
03709       }
03710       break;
03711       
03712       
03713    case EVENT_ALERTING:
03714    {
03715       ch->state = MISDN_ALERTING;
03716       
03717       ast_queue_control(ch->ast, AST_CONTROL_RINGING);
03718       ast_setstate(ch->ast, AST_STATE_RINGING);
03719       
03720       cb_log(1,bc->port,"Set State Ringing\n");
03721       
03722       if ( misdn_cap_is_speech(bc->capability) && misdn_inband_avail(bc)) {
03723          cb_log(1,bc->port,"Starting Tones, we have inband Data\n");
03724          start_bc_tones(ch);
03725       } else {
03726          cb_log(1,bc->port,"We have no inband Data, the other end must create ringing\n");
03727          if (ch->far_alerting) {
03728             cb_log(1,bc->port,"The other end can not do ringing eh ?.. we must do all ourself..");
03729             start_bc_tones(ch);
03730             /*tone_indicate(ch, TONE_FAR_ALERTING);*/
03731          }
03732       }
03733    }
03734    break;
03735    case EVENT_CONNECT:
03736    {
03737       /*we answer when we've got our very new L3 ID from the NT stack */
03738       misdn_lib_send_event(bc,EVENT_CONNECT_ACKNOWLEDGE);
03739    
03740       struct ast_channel *bridged=AST_BRIDGED_P(ch->ast);
03741       
03742       misdn_lib_echo(bc,0);
03743       stop_indicate(ch);
03744 
03745       if (bridged && !strcasecmp(bridged->tech->type,"mISDN")) {
03746          struct chan_list *bridged_ch=MISDN_ASTERISK_TECH_PVT(bridged);
03747 
03748          chan_misdn_log(1,bc->port," --> copying cpndialplan:%d and cad:%s to the A-Channel\n",bc->cpnnumplan,bc->cad);
03749          if (bridged_ch) {
03750             bridged_ch->bc->cpnnumplan=bc->cpnnumplan;
03751             ast_copy_string(bridged_ch->bc->cad,bc->cad,sizeof(bc->cad));
03752          }
03753       }
03754    }
03755    
03756    /* notice that we don't break here!*/
03757    case EVENT_CONNECT_ACKNOWLEDGE:
03758    {
03759       ch->l3id=bc->l3_id;
03760       ch->addr=bc->addr;
03761       
03762       start_bc_tones(ch);
03763       
03764       
03765       ch->state = MISDN_CONNECTED;
03766       ast_queue_control(ch->ast, AST_CONTROL_ANSWER);
03767    }
03768    break;
03769    case EVENT_DISCONNECT:
03770    /*we might not have an ch->ast ptr here anymore*/
03771    if (ch) {
03772       struct chan_list *holded_ch=find_holded(cl_te, bc);
03773    
03774       chan_misdn_log(3,bc->port," --> org:%d nt:%d, inbandavail:%d state:%d\n", ch->orginator, bc->nt, misdn_inband_avail(bc), ch->state);
03775       if ( ch->orginator==ORG_AST && !bc->nt && misdn_inband_avail(bc) && ch->state != MISDN_CONNECTED) {
03776          /* If there's inband information available (e.g. a
03777             recorded message saying what was wrong with the
03778             dialled number, or perhaps even giving an
03779             alternative number, then play it instead of
03780             immediately releasing the call */
03781          chan_misdn_log(1,bc->port, " --> Inband Info Avail, not sending RELEASE\n");
03782       
03783          ch->state=MISDN_DISCONNECTED;
03784          start_bc_tones(ch);
03785          break;
03786       }
03787       
03788       /*Check for holded channel, to implement transfer*/
03789       if (  holded_ch && 
03790          holded_ch != ch && 
03791          ch->ast && 
03792          ch->state == MISDN_CONNECTED  ) {
03793          cb_log(1,bc->port," --> found holded ch\n");
03794          misdn_transfer_bc(ch, holded_ch) ;
03795       }
03796       
03797       stop_bc_tones(ch);
03798       hangup_chan(ch);
03799    } else {
03800       ch=find_holded_l3(cl_te, bc->l3_id,1);
03801       if (ch) {
03802          hangup_chan(ch);
03803       }
03804    }
03805    bc->out_cause=-1;
03806    if (bc->need_release) misdn_lib_send_event(bc,EVENT_RELEASE);
03807    break;
03808    
03809    case EVENT_RELEASE:
03810       {
03811          bc->out_cause=16;
03812          
03813          hangup_chan(ch);
03814          release_chan(bc);
03815       
03816          if (bc->need_release_complete) 
03817             misdn_lib_send_event(bc,EVENT_RELEASE_COMPLETE);
03818       }
03819       break;
03820    case EVENT_RELEASE_COMPLETE:
03821    {
03822       stop_bc_tones(ch);
03823       hangup_chan(ch);
03824       release_chan(bc);
03825       if(ch)   
03826          ch->state=MISDN_CLEANING;
03827    }
03828    break;
03829    case EVENT_CLEANUP:
03830    {
03831       stop_bc_tones(ch);
03832       
03833       switch(ch->state) {
03834          case MISDN_CALLING:
03835             bc->cause=27; /* Destination out of order */
03836          break;
03837          default:
03838          break;
03839       }
03840       
03841       hangup_chan(ch);
03842       release_chan(bc);
03843    }
03844    break;
03845 
03846    case EVENT_TONE_GENERATE:
03847    {
03848       int tone_len=bc->tone_cnt;
03849       struct ast_channel *ast=ch->ast;
03850       void *tmp;
03851       int res;
03852       int (*generate)(struct ast_channel *chan, void *tmp, int datalen, int samples);
03853 
03854       chan_misdn_log(9,bc->port,"TONE_GEN: len:%d\n");
03855 
03856       if (!ast) break;
03857 
03858       if (!ast->generator) break;
03859    
03860       
03861    
03862       tmp = ast->generatordata;
03863       ast->generatordata = NULL;
03864       generate = ast->generator->generate;
03865 
03866       if (tone_len <0 || tone_len > 512 ) {
03867          ast_log(LOG_NOTICE, "TONE_GEN: len was %d, set to 128\n",tone_len);
03868          tone_len=128;
03869       }
03870 
03871       res = generate(ast, tmp, tone_len, tone_len);
03872       ast->generatordata = tmp;
03873       
03874       if (res) {
03875          ast_log(LOG_WARNING, "Auto-deactivating generator\n");
03876          ast_deactivate_generator(ast);
03877       } else {
03878          bc->tone_cnt=0;
03879       }
03880    }
03881    break;
03882       
03883    case EVENT_BCHAN_DATA:
03884    {
03885       if ( !misdn_cap_is_speech(ch->bc->capability) ) {
03886          struct ast_frame frame;
03887          /*In Data Modes we queue frames*/
03888          frame.frametype  = AST_FRAME_VOICE; /*we have no data frames yet*/
03889          frame.subclass = AST_FORMAT_ALAW;
03890          frame.datalen = bc->bframe_len;
03891          frame.samples = bc->bframe_len ;
03892          frame.mallocd =0 ;
03893          frame.offset= 0 ;
03894          frame.delivery= ast_tv(0,0) ;
03895          frame.src = NULL;
03896          frame.data = bc->bframe ;
03897          
03898          ast_queue_frame(ch->ast,&frame);
03899       } else {
03900          fd_set wrfs;
03901          struct timeval tv;
03902          tv.tv_sec=0;
03903          tv.tv_usec=0;
03904          
03905          
03906          FD_ZERO(&wrfs);
03907          FD_SET(ch->pipe[1],&wrfs);
03908          
03909          int t=select(FD_SETSIZE,NULL,&wrfs,NULL,&tv);
03910 
03911          if (!t) {
03912             chan_misdn_log(9, bc->port, "Select Timed out\n");
03913             break;
03914          }
03915          
03916          if (t<0) {
03917             chan_misdn_log(-1, bc->port, "Select Error (err=%s)\n",strerror(errno));
03918             break;
03919          }
03920          
03921          if (FD_ISSET(ch->pipe[1],&wrfs)) {
03922             chan_misdn_log(9, bc->port, "writing %d bytes 2 asterisk\n",bc->bframe_len);
03923             int ret=write(ch->pipe[1], bc->bframe, bc->bframe_len);
03924             
03925             if (ret<=0) {
03926                chan_misdn_log(-1, bc->port, "Write returned <=0 (err=%s)\n",strerror(errno));
03927             }
03928          } else {
03929             chan_misdn_log(1, bc->port, "Wripe Pipe full!\n");
03930          }
03931       }
03932    }
03933    break;
03934    case EVENT_TIMEOUT:
03935       {
03936       if (ch && bc)
03937          chan_misdn_log(1,bc->port,"--> state: %s\n",misdn_get_ch_state(ch));
03938 
03939       switch (ch->state) {
03940          case MISDN_CALLING:
03941          case MISDN_DIALING:
03942          case MISDN_PROGRESS:
03943          case MISDN_ALERTING:
03944          case MISDN_PROCEEDING:
03945          case MISDN_CALLING_ACKNOWLEDGE:
03946             if (bc->nt) {
03947                bc->progress_indicator=8;
03948                hanguptone_indicate(ch);
03949             }
03950             
03951             bc->out_cause=1;
03952             misdn_lib_send_event(bc,EVENT_DISCONNECT);
03953          break;
03954 
03955          case MISDN_WAITING4DIGS:
03956             if (bc->nt) {
03957                bc->progress_indicator=8;
03958                bc->out_cause=1;
03959                hanguptone_indicate(ch);
03960                misdn_lib_send_event(bc,EVENT_DISCONNECT);
03961             } else {
03962                bc->out_cause=16;
03963                misdn_lib_send_event(bc,EVENT_RELEASE);
03964             }
03965             
03966          break;
03967 
03968 
03969          case MISDN_CLEANING: 
03970             chan_misdn_log(1,bc->port," --> in state cleaning .. so ingoring, the stack should clean it for us\n");
03971          break;
03972 
03973          default:
03974             misdn_lib_send_event(bc,EVENT_RELEASE_COMPLETE);
03975          }
03976       }
03977       break;
03978 
03979     
03980    /***************************/
03981    /** Suplementary Services **/
03982    /***************************/
03983    case EVENT_RETRIEVE:
03984    {
03985       ch=find_holded_l3(cl_te, bc->l3_id,1);
03986       if (!ch) {
03987          ast_log(LOG_WARNING, "Found no Holded channel, cannot Retrieve\n");
03988          misdn_lib_send_event(bc, EVENT_RETRIEVE_REJECT);
03989          break;
03990       }
03991 
03992       /*remember the channel again*/
03993       ch->bc=bc;
03994       ch->state = MISDN_CONNECTED;
03995 
03996       struct ast_channel *hold_ast=AST_BRIDGED_P(ch->ast);
03997       
03998       if (hold_ast) {
03999          ast_moh_stop(hold_ast);
04000       }
04001    
04002       if ( misdn_lib_send_event(bc, EVENT_RETRIEVE_ACKNOWLEDGE) < 0)
04003          misdn_lib_send_event(bc, EVENT_RETRIEVE_REJECT);
04004    }
04005    break;
04006     
04007    case EVENT_HOLD:
04008    {
04009       int hold_allowed;
04010       misdn_cfg_get( bc->port, MISDN_CFG_HOLD_ALLOWED, &hold_allowed, sizeof(int));
04011       
04012       if (!hold_allowed) {
04013 
04014          chan_misdn_log(-1, bc->port, "Hold not allowed this port.\n");
04015          misdn_lib_send_event(bc, EVENT_HOLD_REJECT);
04016          break;
04017       }
04018       
04019       struct ast_channel *bridged=AST_BRIDGED_P(ch->ast);
04020 
04021       if (bridged) {
04022          chan_misdn_log(2,bc->port,"Bridge Partner is of type: %s\n",bridged->tech->type);
04023          ch->state = MISDN_HOLDED;
04024          ch->l3id = bc->l3_id;
04025          
04026          misdn_lib_send_event(bc, EVENT_HOLD_ACKNOWLEDGE);
04027 
04028          ast_moh_start(bridged, NULL);
04029 
04030          /*forget the channel now*/
04031          ch->bc=NULL;
04032          ch->hold_info.port=bc->port;
04033          ch->hold_info.channel=bc->channel;
04034 
04035       } else {
04036          misdn_lib_send_event(bc, EVENT_HOLD_REJECT);
04037          chan_misdn_log(0, bc->port, "We aren't bridged to anybody\n");
04038       }
04039    } 
04040    break;
04041    
04042    case EVENT_FACILITY:
04043       print_facility(bc);
04044       
04045       switch (bc->fac_type) {
04046       case FACILITY_CALLDEFLECT:
04047       {
04048          struct ast_channel *bridged=AST_BRIDGED_P(ch->ast);
04049          struct chan_list *ch;
04050          
04051          if (bridged && MISDN_ASTERISK_TECH_PVT(bridged)) {
04052             ch=MISDN_ASTERISK_TECH_PVT(bridged);
04053             /*ch->state=MISDN_FACILITY_DEFLECTED;*/
04054             if (ch->bc) {
04055                /* todo */
04056             }
04057             
04058          }
04059          
04060       } 
04061       
04062       break;
04063       default:
04064          chan_misdn_log(1, bc->port," --> not yet handled\n");
04065       }
04066       
04067       break;
04068 
04069    case EVENT_RESTART:
04070 
04071       stop_bc_tones(ch);
04072       release_chan(bc);
04073       
04074       break;
04075             
04076    default:
04077       ast_log(LOG_NOTICE, "Got Unknown Event\n");
04078       break;
04079    }
04080    
04081    return RESPONSE_OK;
04082 }

int chan_misdn_jb_empty struct misdn_bchannel *  bc,
char *  buf,
int  len
 

Definition at line 4532 of file chan_misdn.c.

References cl_te, find_chan_by_bc(), chan_list::jb, and misdn_jb_empty().

Referenced by load_module().

04533 {
04534    struct chan_list *ch=find_chan_by_bc(cl_te, bc);
04535    
04536    if (ch && ch->jb) {
04537       return misdn_jb_empty(ch->jb, buf, len);
04538    }
04539    
04540    return -1;
04541 }

void chan_misdn_log int  level,
int  port,
char *  tmpl,
  ...
[static]
 

Definition at line 4717 of file chan_misdn.c.

References ast_console_puts(), ast_log(), ast_strlen_zero(), global_tracefile, LOG_WARNING, max_ports, misdn_debug, and misdn_debug_only.

Referenced by cb_events(), cl_queue_chan(), config_jitterbuffer(), debug_numplan(), dialtone_indicate(), do_immediate_setup(), export_ch(), find_holded(), import_ch(), init_chan_list(), load_module(), misdn_answer(), misdn_bridge(), misdn_call(), misdn_digit(), misdn_facility_exec(), misdn_fixup(), misdn_hangup(), misdn_indication(), misdn_jb_init(), misdn_new(), misdn_read(), misdn_request(), misdn_set_opt_exec(), misdn_transfer_bc(), misdn_write(), print_bearer(), print_facility(), process_ast_dsp(), read_config(), release_chan(), send_cause2ast(), stop_indicate(), and update_config().

04718 {
04719    if (! ((0 <= port) && (port <= max_ports))) {
04720       ast_log(LOG_WARNING, "cb_log called with out-of-range port number! (%d)\n", port);
04721       port=0;
04722       level=-1;
04723    }
04724       
04725    va_list ap;
04726    char buf[1024];
04727    char port_buf[8];
04728    sprintf(port_buf,"P[%2d] ",port);
04729    
04730    va_start(ap, tmpl);
04731    vsnprintf( buf, 1023, tmpl, ap );
04732    va_end(ap);
04733 
04734    if (level == -1)
04735       ast_log(LOG_WARNING, buf);
04736 
04737    else if (misdn_debug_only[port] ? 
04738          (level==1 && misdn_debug[port]) || (level==misdn_debug[port]) 
04739        : level <= misdn_debug[port]) {
04740       
04741       ast_console_puts(port_buf);
04742       ast_console_puts(buf);
04743    }
04744    
04745    if ((level <= misdn_debug[0]) && !ast_strlen_zero(global_tracefile) ) {
04746       time_t tm = time(NULL);
04747       char *tmp=ctime(&tm),*p;
04748       
04749       FILE *fp= fopen(global_tracefile, "a+");
04750       
04751       p=strchr(tmp,'\n');
04752       if (p) *p=':';
04753       
04754       if (!fp) {
04755          ast_console_puts("Error opening Tracefile: [ ");
04756          ast_console_puts(global_tracefile);
04757          ast_console_puts(" ] ");
04758          
04759          ast_console_puts(strerror(errno));
04760          ast_console_puts("\n");
04761          return ;
04762       }
04763       
04764       fputs(tmp,fp);
04765       fputs(" ", fp);
04766       fputs(port_buf,fp);
04767       fputs(" ", fp);
04768       fputs(buf, fp);
04769 
04770       fclose(fp);
04771    }
04772 }

static void cl_dequeue_chan struct chan_list **  list,
struct chan_list chan
[static]
 

Definition at line 2887 of file chan_misdn.c.

References ast_dsp_free(), ast_mutex_lock(), ast_mutex_unlock(), ast_translator_free_path(), cl_te_lock, chan_list::dsp, list, chan_list::next, ast_imager::next, and chan_list::trans.

Referenced by misdn_hangup(), and release_chan().

02888 {
02889    if (chan->dsp) 
02890       ast_dsp_free(chan->dsp);
02891    if (chan->trans)
02892       ast_translator_free_path(chan->trans);
02893 
02894    
02895 
02896    ast_mutex_lock(&cl_te_lock);
02897    if (!*list) {
02898       ast_mutex_unlock(&cl_te_lock);
02899       return;
02900    }
02901   
02902    if (*list == chan) {
02903       *list=(*list)->next;
02904       ast_mutex_unlock(&cl_te_lock);
02905       return ;
02906    }
02907   
02908    {
02909       struct chan_list *help=*list;
02910       for (;help->next; help=help->next) {
02911          if (help->next == chan) {
02912             help->next=help->next->next;
02913             ast_mutex_unlock(&cl_te_lock);
02914             return;
02915          }
02916       }
02917    }
02918    
02919    ast_mutex_unlock(&cl_te_lock);
02920 }

static void cl_queue_chan struct chan_list **  list,
struct chan_list chan
[static]
 

Definition at line 2871 of file chan_misdn.c.

References ast_mutex_lock(), ast_mutex_unlock(), chan_list::bc, chan_misdn_log(), cl_te_lock, list, and chan_list::next.

Referenced by cb_events().

02872 {
02873    chan_misdn_log(4, chan->bc? chan->bc->port : 0, "* Queuing chan %p\n",chan);
02874   
02875    ast_mutex_lock(&cl_te_lock);
02876    if (!*list) {
02877       *list = chan;
02878    } else {
02879       struct chan_list *help=*list;
02880       for (;help->next; help=help->next); 
02881       help->next=chan;
02882    }
02883    chan->next=NULL;
02884    ast_mutex_unlock(&cl_te_lock);
02885 }

static char* complete_ch char *  line,
char *  word,
int  pos,
int  state
[static]
 

Definition at line 1034 of file chan_misdn.c.

References complete_ch_helper().

01035 {
01036    return complete_ch_helper(line, word, pos, state, 3);
01037 }

static char* complete_ch_helper char *  line,
char *  word,
int  pos,
int  state,
int  rpos
[static]
 

Definition at line 1010 of file chan_misdn.c.

References ast_channel_walk_locked(), ast_mutex_unlock(), ast_channel::lock, ast_channel::name, and strdup.

01011 {
01012    struct ast_channel *c;
01013    int which=0;
01014    char *ret;
01015    if (pos != rpos)
01016       return NULL;
01017    c = ast_channel_walk_locked(NULL);
01018    while(c) {
01019       if (!strncasecmp(word, c->name, strlen(word))) {
01020          if (++which > state)
01021             break;
01022       }
01023       ast_mutex_unlock(&c->lock);
01024       c = ast_channel_walk_locked(c);
01025    }
01026    if (c) {
01027       ret = strdup(c->name);
01028       ast_mutex_unlock(&c->lock);
01029    } else
01030       ret = NULL;
01031    return ret;
01032 }

static char* complete_debug_port char *  line,
char *  word,
int  pos,
int  state
[static]
 

Definition at line 1039 of file chan_misdn.c.

References strdup.

01040 {
01041    if (state)
01042       return NULL;
01043 
01044    switch (pos) {
01045    case 4: if (*word == 'p')
01046             return strdup("port");
01047          else if (*word == 'o')
01048             return strdup("only");
01049          break;
01050    case 6: if (*word == 'o')
01051             return strdup("only");
01052          break;
01053    }
01054    return NULL;
01055 }

void config_jitterbuffer struct chan_list ch  ) 
 

Definition at line 1299 of file chan_misdn.c.

References chan_list::bc, chan_misdn_log(), chan_list::jb, chan_list::jb_len, chan_list::jb_upper_threshold, misdn_jb_destroy(), and misdn_jb_init().

Referenced by read_config().

01300 {
01301    struct misdn_bchannel *bc=ch->bc;
01302    int len=ch->jb_len, threshold=ch->jb_upper_threshold;
01303    
01304    chan_misdn_log(5,bc->port, "config_jb: Called\n");
01305    
01306    if ( ! len ) {
01307       chan_misdn_log(1,bc->port, "config_jb: Deactivating Jitterbuffer\n");
01308       bc->nojitter=1;
01309    } else {
01310       
01311       if (len <=100 || len > 8000) {
01312          chan_misdn_log(0,bc->port,"config_jb: Jitterbuffer out of Bounds, setting to 1000\n");
01313          len=1000;
01314       }
01315       
01316       if ( threshold > len ) {
01317          chan_misdn_log(0,bc->port,"config_jb: Jitterbuffer Threshold > Jitterbuffer setting to Jitterbuffer -1\n");
01318       }
01319       
01320       if ( ch->jb) {
01321          cb_log(0,bc->port,"config_jb: We've got a Jitterbuffer Already on this port.\n");
01322          misdn_jb_destroy(ch->jb);
01323          ch->jb=NULL;
01324       }
01325       
01326       ch->jb=misdn_jb_init(len, threshold);
01327 
01328       if (!ch->jb ) 
01329          bc->nojitter=1;
01330    }
01331 }

void debug_numplan int  port,
int  numplan,
char *  type
 

Definition at line 1334 of file chan_misdn.c.

References chan_misdn_log().

Referenced by read_config().

01335 {
01336    switch (numplan) {
01337    case NUMPLAN_INTERNATIONAL:
01338       chan_misdn_log(2, port, " --> %s: International\n",type);
01339       break;
01340    case NUMPLAN_NATIONAL:
01341       chan_misdn_log(2, port, " --> %s: National\n",type);
01342       break;
01343    case NUMPLAN_SUBSCRIBER:
01344       chan_misdn_log(2, port, " --> %s: Subscriber\n",type);
01345       break;
01346    case NUMPLAN_UNKNOWN:
01347       chan_misdn_log(2, port, " --> %s: Unknown\n",type);
01348       break;
01349       /* Maybe we should cut off the prefix if present ? */
01350    default:
01351       chan_misdn_log(0, port, " --> !!!! Wrong dialplan setting, please see the misdn.conf sample file\n ");
01352       break;
01353    }
01354 }

char* description void   ) 
 

Provides a description of the module.

Returns:
a short description of your module

Definition at line 4284 of file chan_misdn.c.

References desc.

04285 {
04286    return desc;
04287 }

static int dialtone_indicate struct chan_list cl  )  [static]
 

AST INDICATIONS END

Definition at line 2383 of file chan_misdn.c.

References chan_list::ast, ast_get_indication_tone(), ast_playtones_start(), chan_list::bc, chan_misdn_log(), tone_zone_sound::data, misdn_cfg_get(), chan_list::norxtone, chan_list::notxtone, chan_list::ts, and ast_channel::zone.

Referenced by do_immediate_setup().

02384 {
02385    const struct tone_zone_sound *ts= NULL;
02386    struct ast_channel *ast=cl->ast;
02387 
02388 
02389    int nd=0;
02390    misdn_cfg_get( cl->bc->port, MISDN_CFG_NODIALTONE, &nd, sizeof(nd));
02391 
02392    if (nd) {
02393       chan_misdn_log(1,cl->bc->port,"Not sending Dialtone, because config wants it\n");
02394       return 0;
02395    }
02396    
02397    chan_misdn_log(3,cl->bc->port," --> Dial\n");
02398    ts=ast_get_indication_tone(ast->zone,"dial");
02399    cl->ts=ts;  
02400    
02401    if (ts) {
02402       cl->notxtone=0;
02403       cl->norxtone=0;
02404       ast_playtones_start(ast,0, ts->data, 0);
02405       chan_misdn_log(4,cl->bc->port,"Starting Playtones\n");
02406       misdn_lib_tone_generator_start(cl->bc);
02407    }
02408 
02409    return 0;
02410 }

static void do_immediate_setup struct misdn_bchannel *  bc,
struct chan_list ch,
struct ast_channel ast
[static]
 

Definition at line 3042 of file chan_misdn.c.

References chan_list::ast, AST_CID_P, AST_FRAME_DTMF, ast_queue_frame(), ast_strlen_zero(), chan_misdn_log(), ast_channel::context, ast_frame::data, ast_frame::datalen, ast_frame::delivery, dialtone_indicate(), ast_channel::exten, ast_frame::frametype, hangup_chan(), hanguptone_indicate(), chan_list::incoming_early_audio, ast_frame::mallocd, MISDN_ASTERISK_PVT, MISDN_ASTERISK_TECH_PVT, MISDN_DIALING, ast_frame::offset, ORG_MISDN, chan_list::orginator, pbx_start_chan(), ast_frame::samples, ast_frame::src, chan_list::state, and ast_frame::subclass.

03043 {
03044    char predial[256]="";
03045    char *p = predial;
03046   
03047    struct ast_frame fr;
03048   
03049    strncpy(predial, ast->exten, sizeof(predial) -1 );
03050   
03051    ch->state=MISDN_DIALING;
03052 
03053    if (bc->nt) {
03054       int ret; 
03055       ret = misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE );
03056    } else {
03057       int ret;
03058       if ( misdn_lib_is_ptp(bc->port)) {
03059          ret = misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE );
03060       } else {
03061          ret = misdn_lib_send_event(bc, EVENT_PROCEEDING );
03062       }
03063    }
03064 
03065    if ( !bc->nt && (ch->orginator==ORG_MISDN) && !ch->incoming_early_audio ) 
03066       chan_misdn_log(1,bc->port, " --> incoming_early_audio off\n");
03067     else  
03068       dialtone_indicate(ch);
03069   
03070    chan_misdn_log(1, bc->port, "* Starting Ast ctx:%s dad:%s oad:%s with 's' extension\n", ast->context, ast->exten, AST_CID_P(ast));
03071   
03072    strncpy(ast->exten,"s", 2);
03073   
03074    if (pbx_start_chan(ch)<0) {
03075       ast=NULL;
03076       hangup_chan(ch);
03077       hanguptone_indicate(ch);
03078 
03079       if (bc->nt)
03080          misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE );
03081       else
03082          misdn_lib_send_event(bc, EVENT_DISCONNECT );
03083    }
03084   
03085   
03086    while (!ast_strlen_zero(p) ) {
03087       fr.frametype = AST_FRAME_DTMF;
03088       fr.subclass = *p ;
03089       fr.src=NULL;
03090       fr.data = NULL ;
03091       fr.datalen = 0;
03092       fr.samples = 0 ;
03093       fr.mallocd =0 ;
03094       fr.offset= 0 ;
03095       fr.delivery= ast_tv(0,0) ;
03096 
03097       if (ch->ast && MISDN_ASTERISK_PVT(ch->ast) && MISDN_ASTERISK_TECH_PVT(ch->ast)) {
03098          ast_queue_frame(ch->ast, &fr);
03099       }
03100       p++;
03101    }
03102 }

void export_ch struct ast_channel chan,
struct misdn_bchannel *  bc,
struct chan_list ch
 

Definition at line 3176 of file chan_misdn.c.

References chan_misdn_log(), and pbx_builtin_setvar_helper().

Referenced by cb_events().

03177 {
03178    char tmp[32];
03179 
03180    chan_misdn_log(1,bc->port,"EXPORT_PID: pid:%d\n",bc->pid);
03181    sprintf(tmp,"%d",bc->pid);
03182    pbx_builtin_setvar_helper(chan,"_MISDN_PID",tmp);
03183 }

static struct chan_list * find_chan_by_bc struct chan_list list,
struct misdn_bchannel *  bc
[static]
 

Definition at line 2815 of file chan_misdn.c.

References chan_list::bc, list, and chan_list::next.

Referenced by cb_events(), chan_misdn_jb_empty(), and release_chan().

02816 {
02817    struct chan_list *help=list;
02818    for (;help; help=help->next) {
02819       if (help->bc == bc) return help;
02820    }
02821   
02822    chan_misdn_log(6, bc->port, "$$$ find_chan: No channel found for oad:%s dad:%s\n",bc->oad,bc->dad);
02823   
02824    return NULL;
02825 }

static struct chan_list * find_chan_by_pid struct chan_list list,
int  pid
[static]
 

Definition at line 2827 of file chan_misdn.c.

References chan_list::bc, list, and chan_list::next.

Referenced by import_ch().

02828 {
02829    struct chan_list *help=list;
02830    for (;help; help=help->next) {
02831       if ( help->bc && (help->bc->pid == pid) ) return help;
02832    }
02833   
02834    chan_misdn_log(6, 0, "$$$ find_chan: No channel found for pid:%d\n",pid);
02835   
02836    return NULL;
02837 }

static struct chan_list* find_holded struct chan_list list,
struct misdn_bchannel *  bc
[static]
 

Definition at line 2839 of file chan_misdn.c.

References chan_misdn_log(), hold_info::channel, chan_list::hold_info, list, MISDN_HOLDED, chan_list::next, hold_info::port, and chan_list::state.

Referenced by cb_events().

02840 {
02841    struct chan_list *help=list;
02842    
02843    chan_misdn_log(6, bc->port, "$$$ find_holded: channel:%d oad:%s dad:%s\n",bc->channel, bc->oad,bc->dad);
02844    for (;help; help=help->next) {
02845       chan_misdn_log(4, bc->port, "$$$ find_holded: --> holded:%d channel:%d\n",help->state==MISDN_HOLDED, help->hold_info.channel);
02846       if (help->hold_info.port == bc->port
02847       ) return help;
02848    }
02849    
02850    chan_misdn_log(6, bc->port, "$$$ find_chan: No channel found for oad:%s dad:%s\n",bc->oad,bc->dad);
02851   
02852    return NULL;
02853 }

static struct chan_list* find_holded_l3 struct chan_list list,
unsigned long  l3_id,
int  w
[static]
 

Definition at line 2856 of file chan_misdn.c.

References chan_list::l3id, list, MISDN_HOLDED, chan_list::next, and chan_list::state.

02858 {
02859    struct chan_list *help=list;
02860 
02861    for (;help; help=help->next) {
02862       if ( (help->state == MISDN_HOLDED) &&
02863           (help->l3id == l3_id)   
02864          ) 
02865          return help;
02866    }
02867 
02868    return NULL;
02869 }

static void free_robin_list void   )  [static]
 

Definition at line 233 of file chan_misdn.c.

References free_robin_list_r(), and robin.

Referenced by reload_config(), and unload_module().

00234 {
00235    free_robin_list_r(robin);
00236    robin = NULL;
00237 }

static void free_robin_list_r struct robin_list r  )  [inline, static]
 

Definition at line 224 of file chan_misdn.c.

References free, robin_list::group, and robin_list::next.

Referenced by free_robin_list().

00225 {
00226         if (r) {
00227                 if (r->next) free_robin_list_r(r->next);
00228                 if (r->group) free(r->group);
00229                 free(r);
00230         }
00231 }

static struct chan_list* get_chan_by_ast struct ast_channel ast  )  [static]
 

Definition at line 329 of file chan_misdn.c.

References chan_list::ast, cl_te, and chan_list::next.

Referenced by misdn_bridge().

00330 {
00331    struct chan_list *tmp;
00332   
00333    for (tmp=cl_te; tmp; tmp = tmp->next) {
00334       if ( tmp->ast == ast ) return tmp;
00335    }
00336   
00337    return NULL;
00338 }

static struct chan_list* get_chan_by_ast_name char *  name  )  [static]
 

Definition at line 340 of file chan_misdn.c.

References chan_list::ast, cl_te, ast_channel::name, and chan_list::next.

Referenced by misdn_send_cd(), misdn_send_digit(), misdn_send_display(), and misdn_toggle_echocancel().

00341 {
00342    struct chan_list *tmp;
00343   
00344    for (tmp=cl_te; tmp; tmp = tmp->next) {
00345       if ( tmp->ast  && strcmp(tmp->ast->name,name) == 0) return tmp;
00346    }
00347   
00348    return NULL;
00349 }

static struct robin_list* get_robin_position char *  group  )  [static]
 

Definition at line 239 of file chan_misdn.c.

References robin_list::group, robin_list::next, and robin.

Referenced by misdn_request().

00240 {
00241    struct robin_list *iter = robin;
00242    for (; iter; iter = iter->next) {
00243       if (!strcasecmp(iter->group, group))
00244          return iter;
00245    }
00246    struct robin_list *new = (struct robin_list *)calloc(1, sizeof(struct robin_list));
00247    new->group = strndup(group, strlen(group));
00248    new->channel = 1;
00249    if (robin) {
00250       new->next = robin;
00251       robin->prev = new;
00252    }
00253    robin = new;
00254    return robin;
00255 }

static void hangup_chan struct chan_list ch  )  [static]
 

Definition at line 2937 of file chan_misdn.c.

References chan_list::ast, ast_hangup(), ast_queue_hangup(), chan_list::bc, chan_list::need_hangup, chan_list::need_queue_hangup, and send_cause2ast().

02938 {
02939    int port=ch?ch->bc?ch->bc->port:0:0;
02940    if (!ch) {
02941       cb_log(1,0,"Cannot hangup chan, no ch\n");
02942       return;
02943    }
02944 
02945    cb_log(1,port,"hangup_chan\n");
02946 
02947    if (ch->need_hangup) 
02948    {
02949       cb_log(1,port,"-> hangup\n");
02950       send_cause2ast(ch->ast,ch->bc,ch);
02951       ch->need_hangup=0;
02952       ch->need_queue_hangup=0;
02953       if (ch->ast)
02954          ast_hangup(ch->ast);
02955       return;
02956    }
02957 
02958    if (!ch->need_queue_hangup) {
02959       cb_log(1,port,"No need to queue hangup\n");
02960    }
02961 
02962    ch->need_queue_hangup=0;
02963    if (ch->ast) {
02964       send_cause2ast(ch->ast,ch->bc,ch);
02965 
02966       if (ch->ast)
02967          ast_queue_hangup(ch->ast);
02968       cb_log(1,port,"-> queue_hangup\n");
02969    } else {
02970       cb_log(1,port,"Cannot hangup chan, no ast\n");
02971    }
02972 }

static int hanguptone_indicate struct chan_list cl  )  [static]
 

Definition at line 2412 of file chan_misdn.c.

References chan_list::bc.

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

02413 {
02414    misdn_lib_send_tone(cl->bc,TONE_HANGUP);
02415    return 0;
02416 }

void import_ch struct ast_channel chan,
struct misdn_bchannel *  bc,
struct chan_list ch
 

Definition at line 3161 of file chan_misdn.c.

References chan_misdn_log(), cl_te, find_chan_by_pid(), chan_list::other_ch, chan_list::other_pid, and pbx_builtin_getvar_helper().

Referenced by misdn_call().

03162 {
03163    char *tmp;
03164    tmp=pbx_builtin_getvar_helper(chan,"MISDN_PID");
03165    if (tmp) {
03166       ch->other_pid=atoi(tmp);
03167       chan_misdn_log(1,bc->port,"IMPORT_PID: importing pid:%s\n",tmp);
03168 
03169       if (ch->other_pid >0) {
03170          ch->other_ch=find_chan_by_pid(cl_te,ch->other_pid);
03171          if (ch->other_ch) ch->other_ch->other_ch=ch;
03172       }
03173    }
03174 }

static struct chan_list* init_chan_list int  orig  )  [static]
 

Definition at line 2449 of file chan_misdn.c.

References chan_misdn_log(), malloc, chan_list::need_busy, chan_list::need_hangup, chan_list::need_queue_hangup, and chan_list::orginator.

Referenced by cb_events(), and misdn_request().

02450 {
02451    struct chan_list *cl=malloc(sizeof(struct chan_list));
02452    
02453    if (!cl) {
02454       chan_misdn_log(-1, 0, "misdn_request: malloc failed!");
02455       return NULL;
02456    }
02457    
02458    memset(cl,0,sizeof(struct chan_list));
02459 
02460    cl->orginator=orig;
02461    cl->need_queue_hangup=1;
02462    cl->need_hangup=1;
02463    cl->need_busy=1;
02464    
02465    return cl;
02466    
02467 }

char* key void   ) 
 

Returns the ASTERISK_GPL_KEY.

This returns the ASTERISK_GPL_KEY, signifiying that you agree to the terms of the GPL stated in the ASTERISK_GPL_KEY. Your module will not load if it does not return the EXACT message:

 char *key(void) {
         return ASTERISK_GPL_KEY;
 }

Returns:
ASTERISK_GPL_KEY

Definition at line 4289 of file chan_misdn.c.

References ASTERISK_GPL_KEY.

04290 {
04291    return ASTERISK_GPL_KEY;
04292 }

int load_module void   ) 
 

Initialize the module.

Initialize the Agents module. This function is being called by Asterisk when loading the module. Among other thing it registers applications, cli commands and reads the cofiguration file.

Returns:
int Always 0.

Definition at line 4096 of file chan_misdn.c.

References ast_channel_register(), ast_cli_register(), ast_log(), ast_mutex_init(), ast_register_application(), calloc, cb_events(), chan_misdn_jb_empty(), chan_misdn_log(), cl_te_lock, cli_port_block, cli_port_down, cli_port_unblock, cli_port_up, cli_reload, cli_restart_port, cli_send_cd, cli_send_digit, cli_send_display, cli_set_crypt_debug, cli_set_debug, cli_set_tics, cli_show_cl, cli_show_cls, cli_show_config, cli_show_port, cli_show_stacks, cli_toggle_echocancel, global_tracefile, LOG_ERROR, malloc, max_ports, misdn_cfg_get(), misdn_cfg_get_ports_string(), misdn_cfg_init(), misdn_cfg_update_ptp(), misdn_debug, misdn_debug_only, misdn_facility_exec(), misdn_set_opt_exec(), misdn_tech, misdn_type, tracing, and unload_module().

04097 {
04098    int i;
04099    
04100    char ports[256]="";
04101    
04102    max_ports=misdn_lib_maxports_get();
04103    
04104    if (max_ports<=0) {
04105       ast_log(LOG_ERROR, "Unable to initialize mISDN\n");
04106       return 0;
04107    }
04108    
04109    
04110    misdn_cfg_init(max_ports);
04111    g_config_initialized=1;
04112    
04113    misdn_debug = (int *)malloc(sizeof(int) * (max_ports+1));
04114    misdn_cfg_get( 0, MISDN_GEN_DEBUG, &misdn_debug[0], sizeof(int));
04115    for (i = 1; i <= max_ports; i++)
04116       misdn_debug[i] = misdn_debug[0];
04117    misdn_debug_only = (int *)calloc(max_ports + 1, sizeof(int));
04118 
04119    
04120    {
04121       char tempbuf[BUFFERSIZE+1];
04122       misdn_cfg_get( 0, MISDN_GEN_TRACEFILE, tempbuf, BUFFERSIZE);
04123       if (strlen(tempbuf))
04124          tracing = 1;
04125    }
04126 
04127    ast_mutex_init(&cl_te_lock);
04128 
04129    misdn_cfg_update_ptp();
04130    misdn_cfg_get_ports_string(ports);
04131       
04132    if (strlen(ports))
04133       chan_misdn_log(0, 0, "Got: %s from get_ports\n",ports);
04134    
04135    {
04136       struct misdn_lib_iface iface = {
04137          .cb_event = cb_events,
04138          .cb_log = chan_misdn_log,
04139          .cb_jb_empty = chan_misdn_jb_empty,
04140       };
04141       if (misdn_lib_init(ports, &iface, NULL))
04142          chan_misdn_log(0, 0, "No te ports initialized\n");
04143    
04144       int ntflags=0;
04145       char ntfile[BUFFERSIZE+1];
04146 
04147       misdn_cfg_get( 0, MISDN_GEN_NTDEBUGFLAGS, &ntflags, sizeof(int));
04148       misdn_cfg_get( 0, MISDN_GEN_NTDEBUGFILE, &ntfile, BUFFERSIZE);
04149 
04150       misdn_lib_nt_debug_init(ntflags,ntfile);
04151 
04152    }
04153 
04154 
04155    {
04156       if (ast_channel_register(&misdn_tech)) {
04157          ast_log(LOG_ERROR, "Unable to register channel class %s\n", misdn_type);
04158          unload_module();
04159          return -1;
04160       }
04161    }
04162   
04163    ast_cli_register(&cli_send_display);
04164    ast_cli_register(&cli_send_cd);
04165    ast_cli_register(&cli_send_digit);
04166    ast_cli_register(&cli_toggle_echocancel);
04167    ast_cli_register(&cli_set_tics);
04168 
04169    ast_cli_register(&cli_show_cls);
04170    ast_cli_register(&cli_show_cl);
04171    ast_cli_register(&cli_show_config);
04172    ast_cli_register(&cli_show_port);
04173    ast_cli_register(&cli_show_stacks);
04174 
04175    ast_cli_register(&cli_port_block);
04176    ast_cli_register(&cli_port_unblock);
04177    ast_cli_register(&cli_restart_port);
04178    ast_cli_register(&cli_port_up);
04179    ast_cli_register(&cli_port_down);
04180    ast_cli_register(&cli_set_debug);
04181    ast_cli_register(&cli_set_crypt_debug);
04182    ast_cli_register(&cli_reload);
04183 
04184   
04185    ast_register_application("misdn_set_opt", misdn_set_opt_exec, "misdn_set_opt",
04186              "misdn_set_opt(:<opt><optarg>:<opt><optarg>..):\n"
04187              "Sets mISDN opts. and optargs\n"
04188              "\n"
04189              "The available options are:\n"
04190              "    d - Send display text on called phone, text is the optparam\n"
04191              "    n - don't detect dtmf tones on called channel\n"
04192              "    h - make digital outgoing call\n" 
04193              "    c - make crypted outgoing call, param is keyindex\n"
04194              "    e - perform echo cancelation on this channel,\n"
04195              "        takes taps as arguments (32,64,128,256)\n"
04196              "    s - send Non Inband DTMF as inband\n"
04197              "   vr - rxgain control\n"
04198              "   vt - txgain control\n"
04199       );
04200 
04201    
04202    ast_register_application("misdn_facility", misdn_facility_exec, "misdn_facility",
04203              "misdn_facility(<FACILITY_TYPE>|<ARG1>|..)\n"
04204              "Sends the Facility Message FACILITY_TYPE with \n"
04205              "the given Arguments to the current ISDN Channel\n"
04206              "Supported Facilities are:\n"
04207              "\n"
04208              "type=calldeflect args=Nr where to deflect\n"
04209       );
04210 
04211 
04212    misdn_cfg_get( 0, MISDN_GEN_TRACEFILE, global_tracefile, BUFFERSIZE);
04213 
04214    chan_misdn_log(0, 0, "-- mISDN Channel Driver Registred -- (BE AWARE THIS DRIVER IS EXPERIMENTAL!)\n");
04215 
04216    return 0;
04217 }

static int misdn_answer struct ast_channel ast  )  [static]
 

Definition at line 1697 of file chan_misdn.c.

References chan_list::ast, ast_log(), ast_queue_hangup(), ast_strlen_zero(), chan_list::bc, chan_misdn_log(), LOG_WARNING, MISDN_ASTERISK_TECH_PVT, MISDN_CONNECTED, pbx_builtin_getvar_helper(), start_bc_tones(), chan_list::state, and stop_indicate().

01698 {
01699    struct chan_list *p;
01700 
01701    
01702    if (!ast || ! (p=MISDN_ASTERISK_TECH_PVT(ast)) ) return -1;
01703    
01704    chan_misdn_log(1, p? (p->bc? p->bc->port : 0) : 0, "* ANSWER:\n");
01705    
01706    if (!p) {
01707       ast_log(LOG_WARNING, " --> Channel not connected ??\n");
01708       ast_queue_hangup(ast);
01709    }
01710 
01711    if (!p->bc) {
01712       chan_misdn_log(1, 0, " --> Got Answer, but theres no bc obj ??\n");
01713 
01714       ast_queue_hangup(ast);
01715    }
01716 
01717    {
01718       const char *tmp_key = pbx_builtin_getvar_helper(p->ast, "CRYPT_KEY");
01719       
01720       if (tmp_key ) {
01721          chan_misdn_log(1, p->bc->port, " --> Connection will be BF crypted\n");
01722          {
01723             int l = sizeof(p->bc->crypt_key);
01724             strncpy(p->bc->crypt_key,tmp_key, l);
01725             p->bc->crypt_key[l-1] = 0;
01726          }
01727       } else {
01728          chan_misdn_log(3, p->bc->port, " --> Connection is without BF encryption\n");
01729       }
01730     
01731    }
01732 
01733    {
01734       const char *nodsp=pbx_builtin_getvar_helper(ast, "MISDN_DIGITAL_TRANS");
01735       if (nodsp) {
01736          chan_misdn_log(1, p->bc->port, " --> Connection is transparent digital\n");
01737          p->bc->nodsp=1;
01738          p->bc->hdlc=0;
01739          p->bc->nojitter=1;
01740       }
01741    }
01742    
01743    p->state = MISDN_CONNECTED;
01744    misdn_lib_echo(p->bc,0);
01745    stop_indicate(p);
01746 
01747    if ( ast_strlen_zero(p->bc->cad) ) {
01748       chan_misdn_log(2,p->bc->port," --> empty cad using dad\n");
01749       ast_copy_string(p->bc->cad,p->bc->dad,sizeof(p->bc->cad));
01750    }
01751 
01752    misdn_lib_send_event( p->bc, EVENT_CONNECT);
01753    start_bc_tones(p);
01754    
01755    return 0;
01756 }

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
 

Definition at line 2272 of file chan_misdn.c.

References AST_BRIDGE_COMPLETE, AST_BRIDGE_DTMF_CHANNEL_0, AST_BRIDGE_DTMF_CHANNEL_1, AST_FRAME_CONTROL, AST_FRAME_DTMF, AST_FRAME_VOICE, ast_log(), ast_read(), ast_waitfor_n(), ast_write(), chan_list::bc, chan_misdn_log(), ast_channel::exten, ast_frame::frametype, get_chan_by_ast(), chan_list::ignore_dtmf, LOG_NOTICE, misdn_cfg_get(), and ast_frame::subclass.

02278 {
02279    struct chan_list *ch1,*ch2;
02280    struct ast_channel *carr[2], *who;
02281    int to=-1;
02282    struct ast_frame *f;
02283   
02284    ch1=get_chan_by_ast(c0);
02285    ch2=get_chan_by_ast(c1);
02286 
02287    carr[0]=c0;
02288    carr[1]=c1;
02289   
02290    if (ch1 && ch2 ) ;
02291    else
02292       return -1;
02293   
02294 
02295    int bridging;
02296    misdn_cfg_get( 0, MISDN_GEN_BRIDGING, &bridging, sizeof(int));
02297    if (bridging) {
02298       int ec;
02299       misdn_cfg_get( ch1->bc->port, MISDN_CFG_ECHOCANCEL, &ec, sizeof(int));
02300       if ( ec ) {
02301          chan_misdn_log(2, ch1->bc->port, "Disabling Echo Cancellor when Bridged\n");
02302          ch1->bc->ec_enable=0;
02303          manager_ec_disable(ch1->bc);
02304       }
02305       misdn_cfg_get( ch2->bc->port, MISDN_CFG_ECHOCANCEL, &ec, sizeof(int));
02306       if ( ec ) {
02307          chan_misdn_log(2, ch2->bc->port, "Disabling Echo Cancellor when Bridged\n");
02308          ch2->bc->ec_enable=0;
02309          manager_ec_disable(ch2->bc); 
02310       }
02311       /* trying to make a mISDN_dsp conference */
02312       chan_misdn_log(1, ch1->bc->port, "I SEND: Making conference with Number:%d\n", ch1->bc->pid +1);
02313 
02314       misdn_lib_bridge(ch1->bc,ch2->bc);
02315    }
02316    
02317    chan_misdn_log(1, ch1->bc->port, "* Making Native Bridge between %s and %s\n", ch1->bc->oad, ch2->bc->oad);
02318 
02319 
02320    if (! (flags&AST_BRIDGE_DTMF_CHANNEL_0) )
02321       ch1->ignore_dtmf=1;
02322    
02323    if (! (flags&AST_BRIDGE_DTMF_CHANNEL_1) )
02324       ch2->ignore_dtmf=1;
02325    
02326    
02327    while(1) {
02328       to=-1;
02329       who = ast_waitfor_n(carr, 2, &to);
02330 
02331       if (!who) {
02332          ast_log(LOG_NOTICE,"misdn_bridge: empty read, breaking out\n");
02333          break;
02334       }
02335       f = ast_read(who);
02336     
02337       if (!f || f->frametype == AST_FRAME_CONTROL) {
02338          /* got hangup .. */
02339 
02340          if (!f) 
02341             chan_misdn_log(1,ch1->bc->port,"Read Null Frame\n");
02342          else
02343             chan_misdn_log(1,ch1->bc->port,"Read Frame Controll class:%d\n",f->subclass);
02344          
02345          *fo=f;
02346          *rc=who;
02347       
02348          break;
02349       }
02350       
02351       if ( f->frametype == AST_FRAME_DTMF ) {
02352          chan_misdn_log(1,0,"Read DTMF %d from %s\n",f->subclass, who->exten);
02353 
02354          *fo=f;
02355          *rc=who;
02356          break;
02357       }
02358       
02359       if (f->frametype == AST_FRAME_VOICE) {
02360          chan_misdn_log(1,0,"Got Voice frame in Bridged state..\n");
02361          continue;
02362       }
02363 
02364       if (who == c0) {
02365          ast_write(c1,f);
02366       }
02367       else {
02368          ast_write(c0,f);
02369       }
02370     
02371    }
02372    
02373    chan_misdn_log(1, ch1->bc->port, "I SEND: Splitting conference with Number:%d\n", ch1->bc->pid +1);
02374    
02375    misdn_lib_split_bridge(ch1->bc,ch2->bc);
02376    
02377    
02378    return AST_BRIDGE_COMPLETE;
02379 }

static int misdn_call struct ast_channel ast,
char *  dest,
int  timeout
[static]
 

we should have l3id after sending setup

Definition at line 1568 of file chan_misdn.c.

References ast_channel::_state, chan_list::ast, AST_CID_P, ast_log(), ast_setstate(), AST_STATE_DIALING, AST_STATE_DOWN, AST_STATE_RESERVED, ast_strlen_zero(), ast_transfercapability2str(), ast_verbose(), chan_list::bc, chan_misdn_log(), ast_channel::context, ast_channel::exten, ast_channel::hangupcause, import_ch(), chan_list::l3id, LOG_WARNING, MISDN_ASTERISK_TECH_PVT, MISDN_CALLING, misdn_set_opt_exec(), ast_channel::name, ORG_AST, pbx_builtin_setvar_helper(), chan_list::state, stop_bc_tones(), ast_channel::transfercapability, and update_config().

01569 {
01570    int port=0;
01571    int r;
01572    struct chan_list *ch=MISDN_ASTERISK_TECH_PVT(ast);
01573    struct misdn_bchannel *newbc;
01574    char *opts=NULL, *ext,*tokb;
01575    char dest_cp[256];
01576    
01577    {
01578       strncpy(dest_cp,dest,sizeof(dest_cp)-1);
01579       dest_cp[sizeof(dest_cp)]=0;
01580       
01581       ext=strtok_r(dest_cp,"/",&tokb);
01582       
01583       if (ext) {
01584          ext=strtok_r(NULL,"/",&tokb);
01585          if (ext) {
01586             opts=strtok_r(NULL,"/",&tokb);
01587          } else {
01588             chan_misdn_log(0,0,"misdn_call: No Extension given!\n");
01589             return -1;
01590          }
01591       }
01592    }
01593 
01594    if (!ast) {
01595       ast_log(LOG_WARNING, " --> ! misdn_call called on ast_channel *ast where ast == NULL\n");
01596       return -1;
01597    }
01598 
01599    if (((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) || !dest  ) {
01600       ast_log(LOG_WARNING, " --> ! misdn_call called on %s, neither down nor reserved (or dest==NULL)\n", ast->name);
01601       ast->hangupcause=41;
01602       ast_setstate(ast, AST_STATE_DOWN);
01603       return -1;
01604    }
01605 
01606    if (!ch) {
01607       ast_log(LOG_WARNING, " --> ! misdn_call called on %s, neither down nor reserved (or dest==NULL)\n", ast->name);
01608       ast->hangupcause=41;
01609       ast_setstate(ast, AST_STATE_DOWN);
01610       return -1;
01611    }
01612    
01613    newbc=ch->bc;
01614    
01615    if (!newbc) {
01616       ast_log(LOG_WARNING, " --> ! misdn_call called on %s, neither down nor reserved (or dest==NULL)\n", ast->name);
01617       ast->hangupcause=41;
01618       ast_setstate(ast, AST_STATE_DOWN);
01619       return -1;
01620    }
01621    
01622    port=newbc->port;
01623    strncpy(newbc->dad,ext,sizeof( newbc->dad));
01624    strncpy(ast->exten,ext,sizeof(ast->exten));
01625    
01626    chan_misdn_log(1, port, "* CALL: %s\n",dest);
01627    
01628    chan_misdn_log(1, port, " --> * dad:%s tech:%s ctx:%s\n",ast->exten,ast->name, ast->context);
01629    
01630    chan_misdn_log(3, port, " --> * adding2newbc ext %s\n",ast->exten);
01631    if (ast->exten) {
01632       int l = sizeof(newbc->dad);
01633       strncpy(newbc->dad,ast->exten, l);
01634       newbc->dad[l-1] = 0;
01635    }
01636    newbc->rad[0]=0;
01637    chan_misdn_log(3, port, " --> * adding2newbc callerid %s\n",AST_CID_P(ast));
01638    if (ast_strlen_zero(newbc->oad) && AST_CID_P(ast) ) {
01639 
01640       if (AST_CID_P(ast)) {
01641          int l = sizeof(newbc->oad);
01642          strncpy(newbc->oad,AST_CID_P(ast), l);
01643          newbc->oad[l-1] = 0;
01644       }
01645    }
01646    
01647    {
01648       struct chan_list *ch=MISDN_ASTERISK_TECH_PVT(ast);
01649       if (!ch) { ast_verbose("No chan_list in misdn_call\n"); return -1;}
01650       
01651       newbc->capability=ast->transfercapability;
01652       pbx_builtin_setvar_helper(ast,"TRANSFERCAPABILITY",ast_transfercapability2str(newbc->capability));
01653       if ( ast->transfercapability == INFO_CAPABILITY_DIGITAL_UNRESTRICTED) {
01654          chan_misdn_log(2, port, " --> * Call with flag Digital\n");
01655       }
01656       
01657 
01658       /* update screening and presentation */ 
01659       update_config(ch,ORG_AST);
01660       
01661       /* fill in some ies from channel vary*/
01662       import_ch(ast, newbc, ch);
01663       
01664       /* Finally The Options Override Everything */
01665       if (opts)
01666          misdn_set_opt_exec(ast,opts);
01667       else
01668          chan_misdn_log(2,port,"NO OPTS GIVEN\n");
01669       
01670       r=misdn_lib_send_event( newbc, EVENT_SETUP );
01671       
01672       /** we should have l3id after sending setup **/
01673       ch->l3id=newbc->l3_id;
01674    }
01675    
01676    if ( r == -ENOCHAN  ) {
01677       chan_misdn_log(0, port, " --> * Theres no Channel at the moment .. !\n");
01678       chan_misdn_log(1, port, " --> * SEND: State Down pid:%d\n",newbc?newbc->pid:-1);
01679       ast->hangupcause=34;
01680       ast_setstate(ast, AST_STATE_DOWN);
01681       return -1;
01682    }
01683    
01684    chan_misdn_log(1, port, " --> * SEND: State Dialing pid:%d\n",newbc?newbc->pid:1);
01685 
01686    ast_setstate(ast, AST_STATE_DIALING);
01687    ast->hangupcause=16;
01688    
01689    if (newbc->nt) stop_bc_tones(ch);
01690 
01691    ch->state=MISDN_CALLING;
01692    
01693    return 0; 
01694 }

static int misdn_digit struct ast_channel ast,
char  digit
[static]
 

Definition at line 1758 of file chan_misdn.c.

References chan_list::ast, ast_log(), chan_list::bc, chan_misdn_log(), ast_channel::exten, LOG_WARNING, MISDN_ASTERISK_TECH_PVT, MISDN_CALLING, MISDN_CALLING_ACKNOWLEDGE, send_digit_to_chan(), and chan_list::state.

01759 {
01760    struct chan_list *p;
01761    
01762    if (!ast || ! (p=MISDN_ASTERISK_TECH_PVT(ast))) return -1;
01763 
01764    struct misdn_bchannel *bc=p->bc;
01765    chan_misdn_log(1, bc?bc->port:0, "* IND : Digit %c\n",digit);
01766    
01767    if (!bc) {
01768       ast_log(LOG_WARNING, " --> !! Got Digit Event withut having bchannel Object\n");
01769       return -1;
01770    }
01771    
01772    switch (p->state ) {
01773       case MISDN_CALLING:
01774       {
01775          
01776          char buf[8];
01777          buf[0]=digit;
01778          buf[1]=0;
01779          
01780          int l = sizeof(bc->infos_pending);
01781          strncat(bc->infos_pending,buf,l);
01782          bc->infos_pending[l-1] = 0;
01783       }
01784       break;
01785       case MISDN_CALLING_ACKNOWLEDGE:
01786       {
01787          bc->info_dad[0]=digit;
01788          bc->info_dad[1]=0;
01789          
01790          {
01791             int l = sizeof(bc->dad);
01792             strncat(bc->dad,bc->info_dad, l - strlen(bc->dad));
01793             bc->dad[l-1] = 0;
01794       }
01795          {
01796             int l = sizeof(p->ast->exten);
01797             strncpy(p->ast->exten, bc->dad, l);
01798             p->ast->exten[l-1] = 0;
01799          }
01800          
01801          misdn_lib_send_event( bc, EVENT_INFORMATION);
01802       }
01803       break;
01804       
01805       default:
01806          if ( bc->send_dtmf ) {
01807             send_digit_to_chan(p,digit);
01808          }
01809       break;
01810    }
01811    
01812    return 0;
01813 }

static int misdn_facility_exec struct ast_channel chan,
void *  data
[static]
 

Definition at line 4299 of file chan_misdn.c.

References ast_log(), ast_strlen_zero(), chan_list::bc, chan_misdn_log(), LOG_WARNING, MISDN_ASTERISK_TECH_PVT, ast_channel::tech, and ast_channel_tech::type.

Referenced by load_module().

04300 {
04301    struct chan_list *ch = MISDN_ASTERISK_TECH_PVT(chan);
04302    char *tok, *tokb;
04303 
04304    chan_misdn_log(0,0,"TYPE: %s\n",chan->tech->type);
04305    
04306    if (strcasecmp(chan->tech->type,"mISDN")) {
04307       ast_log(LOG_WARNING, "misdn_facility makes only sense with chan_misdn channels!\n");
04308       return -1;
04309    }
04310    
04311    if (ast_strlen_zero((char *)data)) {
04312       ast_log(LOG_WARNING, "misdn_facility Requires arguments\n");
04313       return -1;
04314    }
04315    
04316    tok=strtok_r((char*)data,"|", &tokb) ;
04317    
04318    if (!tok) {
04319       ast_log(LOG_WARNING, "misdn_facility Requires arguments\n");
04320       return -1;
04321    }
04322    
04323    if (!strcasecmp(tok,"calldeflect")) {
04324       tok=strtok_r(NULL,"|", &tokb) ;
04325       
04326       if (!tok) {
04327          ast_log(LOG_WARNING, "Facility: Call Defl Requires arguments\n");
04328       }
04329       
04330       misdn_lib_send_facility(ch->bc, FACILITY_CALLDEFLECT, tok);
04331       
04332    } else {
04333       ast_log(LOG_WARNING, "Unknown Facility: %s\n",tok);
04334    }
04335    
04336    return 0;
04337    
04338 }

static int misdn_fixup struct ast_channel oldast,
struct ast_channel ast
[static]
 

Definition at line 1816 of file chan_misdn.c.

References chan_list::ast, chan_list::bc, chan_misdn_log(), chan_list::l3id, MISDN_ASTERISK_TECH_PVT, MISDN_FIXUP, misdn_get_ch_state(), and chan_list::state.

01817 {
01818    struct chan_list *p;
01819    
01820    if (!ast || ! (p=MISDN_ASTERISK_TECH_PVT(ast) )) return -1;
01821    
01822    chan_misdn_log(1, p->bc?p->bc->port:0, "* IND: Got Fixup State:%s L3id:%x\n", misdn_get_ch_state(p), p->l3id);
01823    
01824    p->ast = ast ;
01825    p->state=MISDN_FIXUP;
01826   
01827    return 0;
01828 }

static char* misdn_get_ch_state struct chan_list p  )  [static]
 

Definition at line 688 of file chan_misdn.c.

References chan_list::state, state_array, and state_struct::txt.

Referenced by cb_events(), misdn_fixup(), misdn_hangup(), misdn_write(), print_bc_info(), and release_chan().

00689 {
00690    int i;
00691    static char state[8];
00692    
00693    if( !p) return NULL;
00694   
00695    for (i=0; i< sizeof(state_array)/sizeof(struct state_struct); i++) {
00696       if ( state_array[i].state == p->state) return state_array[i].txt; 
00697    }
00698 
00699    sprintf(state,"%d",p->state) ;
00700 
00701    return state;
00702 }

static int misdn_hangup struct ast_channel ast  )  [static]
 

Definition at line 1966 of file chan_misdn.c.

References ast_channel::_state, chan_list::ast, AST_CID_P, ast_log(), AST_STATE_RESERVED, chan_list::bc, chan_misdn_log(), cl_dequeue_chan(), cl_te, ast_channel::context, ast_channel::exten, free, ast_channel::hangupcause, hanguptone_indicate(), chan_list::l3id, LOG_DEBUG, LOG_WARNING, MISDN_ALERTING, MISDN_ASTERISK_TECH_PVT, MISDN_BUSY, MISDN_CALLING, MISDN_CALLING_ACKNOWLEDGE, MISDN_CLEANING, MISDN_CONNECTED, MISDN_DIALING, MISDN_DISCONNECTED, MISDN_FIXUP, misdn_get_ch_state(), MISDN_HOLD_DISCONNECT, MISDN_HOLDED, MISDN_NOTHING, MISDN_PRECONNECTED, MISDN_PROCEEDING, MISDN_PROGRESS, MISDN_RELEASED, ast_channel::name, chan_list::need_hangup, chan_list::need_queue_hangup, ORG_AST, chan_list::orginator, pbx_builtin_getvar_helper(), chan_list::pipe, start_bc_tones(), chan_list::state, and stop_bc_tones().

01967 {
01968    struct chan_list *p;
01969    struct misdn_bchannel *bc=NULL;
01970    
01971    ast_log(LOG_DEBUG, "misdn_hangup(%s)\n", ast->name);
01972 
01973    if (!ast || ! (p=MISDN_ASTERISK_TECH_PVT(ast) ) ) return -1;
01974    
01975    if (!p) {
01976       chan_misdn_log(3, 0, "misdn_hangup called, without chan_list obj.\n");
01977       return 0 ;
01978    }
01979    
01980    bc=p->bc;
01981 
01982 
01983    
01984    MISDN_ASTERISK_TECH_PVT(ast)=NULL;
01985    p->ast=NULL;
01986 
01987    bc=p->bc;
01988    
01989    if (ast->_state == AST_STATE_RESERVED || 
01990       p->state == MISDN_NOTHING || 
01991       p->state == MISDN_HOLDED || 
01992       p->state == MISDN_FIXUP || 
01993       p->state == MISDN_HOLD_DISCONNECT ) {
01994 
01995       CLEAN_CH:
01996       /* between request and call */
01997       ast_log(LOG_DEBUG, "State Reserved (or nothing) => chanIsAvail\n");
01998       MISDN_ASTERISK_TECH_PVT(ast)=NULL;
01999       
02000       cl_dequeue_chan(&cl_te, p);
02001       
02002       close(p->pipe[0]);
02003       close(p->pipe[1]);
02004       
02005       free(p);
02006       if (bc)
02007          misdn_lib_release(bc);
02008       
02009       return 0;
02010    }
02011 
02012    if (!bc) {
02013       ast_log(LOG_WARNING,"Hangup with private but no bc ? state:%s l3id:%x\n", misdn_get_ch_state(p), p->l3id);
02014       goto CLEAN_CH;
02015    }
02016 
02017 
02018    p->need_hangup=0;
02019    p->need_queue_hangup=0;
02020 
02021 
02022    if (!p->bc->nt) 
02023       stop_bc_tones(p);
02024 
02025    
02026    {
02027       const char *varcause=NULL;
02028       bc->out_cause=ast->hangupcause?ast->hangupcause:16;
02029       
02030       if ( (varcause=pbx_builtin_getvar_helper(ast, "HANGUPCAUSE")) ||
02031            (varcause=pbx_builtin_getvar_helper(ast, "PRI_CAUSE"))) {
02032          int tmpcause=atoi(varcause);
02033          bc->out_cause=tmpcause?tmpcause:16;
02034       }
02035     
02036       chan_misdn_log(1, bc->port, "* IND : HANGUP\tpid:%d ctx:%s dad:%s oad:%s State:%s\n",p->bc?p->bc->pid:-1, ast->context, ast->exten, AST_CID_P(ast), misdn_get_ch_state(p));
02037       chan_misdn_log(2, bc->port, " --> l3id:%x\n",p->l3id);
02038       chan_misdn_log(1, bc->port, " --> cause:%d\n",bc->cause);
02039       chan_misdn_log(1, bc->port, " --> out_cause:%d\n",bc->out_cause);
02040       chan_misdn_log(1, bc->port, " --> state:%s\n", misdn_get_ch_state(p));
02041       
02042       switch (p->state) {
02043       case MISDN_CALLING:
02044          p->state=MISDN_CLEANING;
02045          misdn_lib_send_event( bc, EVENT_RELEASE_COMPLETE);
02046          break;
02047       case MISDN_HOLDED:
02048       case MISDN_DIALING:
02049          start_bc_tones(p);
02050          hanguptone_indicate(p);
02051       
02052          if (bc->need_disconnect)
02053             misdn_lib_send_event( bc, EVENT_DISCONNECT);
02054          break;
02055 
02056       case MISDN_CALLING_ACKNOWLEDGE:
02057          start_bc_tones(p);
02058          hanguptone_indicate(p);
02059       
02060          if (bc->need_disconnect)
02061             misdn_lib_send_event( bc, EVENT_DISCONNECT);
02062          break;
02063       
02064       case MISDN_ALERTING:
02065       case MISDN_PROGRESS:
02066       case MISDN_PROCEEDING:
02067          if (p->orginator != ORG_AST) 
02068             hanguptone_indicate(p);
02069       
02070          /*p->state=MISDN_CLEANING;*/
02071          if (bc->need_disconnect)
02072             misdn_lib_send_event( bc, EVENT_DISCONNECT);
02073          break;
02074       case MISDN_CONNECTED:
02075       case MISDN_PRECONNECTED:
02076          /*  Alerting or Disconect */
02077          if (p->bc->nt) {
02078             start_bc_tones(p);
02079             hanguptone_indicate(p);
02080             p->bc->progress_indicator=8;
02081          }
02082          if (bc->need_disconnect)
02083             misdn_lib_send_event( bc, EVENT_DISCONNECT);
02084 
02085          /*p->state=MISDN_CLEANING;*/
02086          break;
02087       case MISDN_DISCONNECTED:
02088          misdn_lib_send_event( bc, EVENT_RELEASE);
02089          p->state=MISDN_CLEANING; /* MISDN_HUNGUP_FROM_AST; */
02090          break;
02091 
02092       case MISDN_RELEASED:
02093       case MISDN_CLEANING:
02094          p->state=MISDN_CLEANING;
02095          break;
02096 
02097       case MISDN_BUSY:
02098          break;
02099       
02100       case MISDN_HOLD_DISCONNECT:
02101          /* need to send release here */
02102          chan_misdn_log(1, bc->port, " --> cause %d\n",bc->cause);
02103          chan_misdn_log(1, bc->port, " --> out_cause %d\n",bc->out_cause);
02104          
02105          bc->out_cause=-1;
02106          misdn_lib_send_event(bc,EVENT_RELEASE);
02107          p->state=MISDN_CLEANING;
02108          break;
02109       default:
02110          if (bc->nt) {
02111             bc->out_cause=-1;
02112             misdn_lib_send_event(bc, EVENT_RELEASE);
02113             p->state=MISDN_CLEANING; 
02114          } else {
02115             if (bc->need_disconnect)
02116                misdn_lib_send_event(bc, EVENT_DISCONNECT);
02117          }
02118       }
02119 
02120       p->state=MISDN_CLEANING;
02121     
02122    }
02123    
02124 
02125    chan_misdn_log(1, bc->port, "Channel: %s hanguped new state:%s\n",ast->name,misdn_get_ch_state(p));
02126    
02127    return 0;
02128 }

static int misdn_indication struct ast_channel ast,
int  cond
[static]
 

Definition at line 1832 of file chan_misdn.c.

References chan_list::ast, AST_CONTROL_ANSWER, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_FLASH, AST_CONTROL_HOLD, AST_CONTROL_OFFHOOK, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_RING, AST_CONTROL_RINGING, AST_CONTROL_TAKEOFFHOOK, AST_CONTROL_UNHOLD, ast_log(), ast_setstate(), AST_STATE_BUSY, AST_STATE_RINGING, chan_list::bc, chan_misdn_log(), ast_channel::exten, hanguptone_indicate(), chan_list::incoming_early_audio, LOG_NOTICE, LOG_WARNING, MISDN_ALERTING, MISDN_ASTERISK_TECH_PVT, MISDN_CONNECTED, ast_channel::name, ORG_MISDN, chan_list::orginator, chan_list::other_ch, start_bc_tones(), chan_list::state, and stop_indicate().

01833 {
01834    struct chan_list *p;
01835 
01836   
01837    if (!ast || ! (p=MISDN_ASTERISK_TECH_PVT(ast))) {
01838       ast_log(LOG_WARNING, "Returnded -1 in misdn_indication\n");
01839       return -1;
01840    }
01841    
01842    if (!p->bc ) {
01843       chan_misdn_log(1, 0, "* IND : Indication from %s\n",ast->exten);
01844       ast_log(LOG_WARNING, "Private Pointer but no bc ?\n");
01845       return -1;
01846    }
01847    
01848    chan_misdn_log(1, p->bc->port, "* IND : Indication [%d] from %s\n",cond, ast->exten);
01849    
01850    switch (cond) {
01851    case AST_CONTROL_BUSY:
01852       chan_misdn_log(1, p->bc->port, "* IND :\tbusy\n");
01853       chan_misdn_log(1, p->bc->port, " --> * SEND: State Busy pid:%d\n",p->bc?p->bc->pid:-1);
01854       ast_setstate(ast,AST_STATE_BUSY);
01855 
01856       p->bc->out_cause=17;
01857       if (p->state != MISDN_CONNECTED) {
01858          start_bc_tones(p);
01859          misdn_lib_send_event( p->bc, EVENT_DISCONNECT);
01860       } else {
01861          chan_misdn_log(-1, p->bc->port, " --> !! Got Busy in Connected State !?! ast:%s\n", ast->name);
01862       }
01863       return -1;
01864       break;
01865    case AST_CONTROL_RING:
01866       chan_misdn_log(1, p->bc->port, " --> * IND :\tring pid:%d\n",p->bc?p->bc->pid:-1);
01867       return -1;
01868       break;
01869       
01870    case AST_CONTROL_RINGING:
01871       switch (p->state) {
01872          case MISDN_ALERTING:
01873             chan_misdn_log(1, p->bc->port, " --> * IND :\tringing pid:%d but I was Ringing before, so ignoreing it\n",p->bc?p->bc->pid:-1);
01874             break;
01875          case MISDN_CONNECTED:
01876             chan_misdn_log(1, p->bc->port, " --> * IND :\tringing pid:%d but Connected, so just send TONE_ALERTING without state changes \n",p->bc?p->bc->pid:-1);
01877             return -1;
01878             break;
01879          default:
01880             p->state=MISDN_ALERTING;
01881             chan_misdn_log(1, p->bc->port, " --> * IND :\tringing pid:%d\n",p->bc?p->bc->pid:-1);
01882             misdn_lib_send_event( p->bc, EVENT_ALERTING);
01883          
01884             if (p->other_ch && p->other_ch->bc) {
01885                if (misdn_inband_avail(p->other_ch->bc)) {
01886                   chan_misdn_log(1,p->bc->port, " --> other End is mISDN and has inband info available\n");
01887                   break;
01888                }
01889 
01890                if (!p->other_ch->bc->nt) {
01891                   chan_misdn_log(1,p->bc->port, " --> other End is mISDN TE so it has inband info for sure (?)\n");
01892                   break;
01893                }
01894             }
01895 
01896             chan_misdn_log(1, p->bc->port, " --> * SEND: State Ring pid:%d\n",p->bc?p->bc->pid:-1);
01897             ast_setstate(ast,AST_STATE_RINGING);
01898          
01899             if ( !p->bc->nt && (p->orginator==ORG_MISDN) && !p->incoming_early_audio ) 
01900                chan_misdn_log(1,p->bc->port, " --> incoming_early_audio off\n");
01901             else 
01902                return -1;
01903       }
01904       break;
01905    case AST_CONTROL_ANSWER:
01906       chan_misdn_log(1, p->bc->port, " --> * IND :\tanswer pid:%d\n",p->bc?p->bc->pid:-1);
01907       start_bc_tones(p);
01908       break;
01909    case AST_CONTROL_TAKEOFFHOOK:
01910       chan_misdn_log(1, p->bc->port, " --> *\ttakeoffhook pid:%d\n",p->bc?p->bc->pid:-1);
01911       return -1;
01912       break;
01913    case AST_CONTROL_OFFHOOK:
01914       chan_misdn_log(1, p->bc->port, " --> *\toffhook pid:%d\n",p->bc?p->bc->pid:-1);
01915       return -1;
01916       break; 
01917    case AST_CONTROL_FLASH:
01918       chan_misdn_log(1, p->bc->port, " --> *\tflash pid:%d\n",p->bc?p->bc->pid:-1);
01919       break;
01920    case AST_CONTROL_PROGRESS:
01921       chan_misdn_log(1, p->bc->port, " --> * IND :\tprogress pid:%d\n",p->bc?p->bc->pid:-1);
01922       misdn_lib_send_event( p->bc, EVENT_PROGRESS);
01923       break;
01924    case AST_CONTROL_PROCEEDING:
01925       chan_misdn_log(1, p->bc->port, " --> * IND :\tproceeding pid:%d\n",p->bc?p->bc->pid:-1);
01926       misdn_lib_send_event( p->bc, EVENT_PROCEEDING);
01927       break;
01928    case AST_CONTROL_CONGESTION:
01929       chan_misdn_log(1, p->bc->port, " --> * IND :\tcongestion pid:%d\n",p->bc?p->bc->pid:-1);
01930 
01931       p->bc->out_cause=42;
01932       if (p->state != MISDN_CONNECTED) {
01933          start_bc_tones(p);
01934          misdn_lib_send_event( p->bc, EVENT_RELEASE);
01935       } else {
01936          misdn_lib_send_event( p->bc, EVENT_DISCONNECT);
01937       }
01938 
01939       if (p->bc->nt) {
01940          hanguptone_indicate(p);
01941       }
01942       break;
01943    case -1 :
01944       chan_misdn_log(1, p->bc->port, " --> * IND :\t-1! (stop indication) pid:%d\n",p->bc?p->bc->pid:-1);
01945       
01946       stop_indicate(p);
01947 
01948       if (p->state == MISDN_CONNECTED) 
01949          start_bc_tones(p);
01950 
01951       break;
01952 
01953    case AST_CONTROL_HOLD:
01954       chan_misdn_log(1, p->bc->port, " --> *\tHOLD pid:%d\n",p->bc?p->bc->pid:-1);
01955       break;
01956    case AST_CONTROL_UNHOLD:
01957       chan_misdn_log(1, p->bc->port, " --> *\tUNHOLD pid:%d\n",p->bc?p->bc->pid:-1);
01958       break;
01959    default:
01960       ast_log(LOG_NOTICE, " --> * Unknown Indication:%d pid:%d\n",cond,p->bc?p->bc->pid:-1);
01961    }
01962   
01963    return 0;
01964 }

void misdn_jb_destroy struct misdn_jb jb  ) 
 

Definition at line 4585 of file chan_misdn.c.

References ast_mutex_destroy(), free, misdn_jb::mutexjb, and misdn_jb::samples.

Referenced by config_jitterbuffer(), and release_chan().

04586 {
04587    ast_mutex_destroy(&jb->mutexjb);
04588    
04589    free(jb->samples);
04590    free(jb);
04591 }

int misdn_jb_empty struct misdn_jb jb,
char *  data,
int  len
 

Definition at line 4657 of file chan_misdn.c.

References ast_mutex_lock(), ast_mutex_unlock(), misdn_jb::mutexjb, misdn_jb::ok, misdn_jb::rp, misdn_jb::samples, misdn_jb::size, misdn_jb::state_empty, and misdn_jb::wp.

Referenced by chan_misdn_jb_empty().

04658 {
04659     int i, wp, rp, read=0;
04660 
04661     ast_mutex_lock (&jb->mutexjb);
04662 
04663     rp=jb->rp;
04664     wp=jb->wp;
04665 
04666     if(jb->state_empty)
04667     { 
04668    for(i=0; i<len; i++)
04669    {
04670        if(wp==rp)
04671        {
04672       jb->rp=rp;
04673       jb->state_empty=0;
04674 
04675       ast_mutex_unlock (&jb->mutexjb);
04676       
04677       return read;
04678        }
04679        else
04680        {
04681       if(jb->ok[rp]==1)
04682       {
04683           data[i]=jb->samples[rp];
04684           jb->ok[rp]=0;
04685           rp=(rp!=jb->size-1 ? rp+1 : 0);
04686           read+=1;
04687       }
04688        }
04689    }
04690 
04691    if(wp >= rp)
04692       jb->state_buffer=wp-rp;
04693    else
04694       jb->state_buffer= jb->size-rp+wp;
04695    chan_misdn_log(9,0,"misdn_jb_empty: read:%d | Bufferstatus:%d p:%x\n",len,jb->state_buffer,jb);
04696    
04697    jb->rp=rp;
04698     }
04699     else
04700        chan_misdn_log(9,0,"misdn_jb_empty: Wait...requested:%d p:%x\n",len,jb);
04701     
04702     ast_mutex_unlock (&jb->mutexjb);
04703 
04704     return read;
04705 }

int misdn_jb_fill struct misdn_jb jb,
const char *  data,
int  len
 

Definition at line 4595 of file chan_misdn.c.

References ast_mutex_lock(), misdn_jb::mutexjb, misdn_jb::ok, misdn_jb::rp, misdn_jb::samples, misdn_jb::size, misdn_jb::state_full, and misdn_jb::wp.

04596 {
04597     int i, j, rp, wp;
04598 
04599     if (!jb || ! data) return 0;
04600 
04601     ast_mutex_lock (&jb->mutexjb);
04602     
04603     wp=jb->wp;
04604     rp=jb->rp;
04605    
04606     for(i=0; i<len; i++)
04607     {
04608    jb->samples[wp]=data[i];
04609    jb->ok[wp]=1;
04610    wp = (wp!=jb->size-1 ? wp+1 : 0);
04611 
04612    if(wp==jb->rp)
04613        jb->state_full=1;
04614     }
04615     
04616     if(wp>=rp)
04617       jb->state_buffer=wp-rp;
04618     else
04619       jb->state_buffer= jb->size-rp+wp;
04620     chan_misdn_log(9,0,"misdn_jb_fill: written:%d | Bufferstatus:%d p:%x\n",len,jb->state_buffer,jb);
04621     
04622     if(jb->state_full)
04623     {
04624    jb->wp=wp;
04625 
04626    rp=wp;
04627    for(j=0; j<jb->upper_threshold; j++)
04628        rp = (rp!=0 ? rp-1 : jb->size-1);
04629    jb->rp=rp;
04630    jb->state_full=0;
04631    jb->state_empty=1;
04632 
04633    ast_mutex_unlock (&jb->mutexjb);
04634    
04635    return -1;
04636     }
04637 
04638     if(!jb->state_empty)
04639     {
04640    jb->bytes_wrote+=len;
04641    if(jb->bytes_wrote>=jb->upper_threshold)
04642    {
04643        jb->state_empty=1;
04644        jb->bytes_wrote=0;
04645    }
04646     }
04647     jb->wp=wp;
04648 
04649     ast_mutex_unlock (&jb->mutexjb);
04650     
04651     return 0;
04652 }

struct misdn_jb * misdn_jb_init int  size,
int  upper_threshold
 

Definition at line 4551 of file chan_misdn.c.

References ast_mutex_init(), misdn_jb::bytes_wrote, chan_misdn_log(), malloc, misdn_jb::mutexjb, misdn_jb::ok, misdn_jb::rp, misdn_jb::samples, misdn_jb::size, misdn_jb::state_empty, misdn_jb::state_full, misdn_jb::upper_threshold, and misdn_jb::wp.

Referenced by config_jitterbuffer().

04552 {
04553     int i;
04554     struct misdn_jb *jb = (struct misdn_jb*) malloc(sizeof(struct misdn_jb));
04555     jb->size = size;
04556     jb->upper_threshold = upper_threshold;
04557     jb->wp = 0;
04558     jb->rp = 0;
04559     jb->state_full = 0;
04560     jb->state_empty = 0;
04561     jb->bytes_wrote = 0;
04562     jb->samples = (char *)malloc(size*sizeof(char));
04563 
04564     if (!jb->samples) {
04565        chan_misdn_log(-1,0,"No free Mem for jb->samples\n");
04566        return NULL;
04567     }
04568     
04569     jb->ok = (char *)malloc(size*sizeof(char));
04570 
04571     if (!jb->ok) {
04572        chan_misdn_log(-1,0,"No free Mem for jb->ok\n");
04573        return NULL;
04574     }
04575 
04576     for(i=0; i<size; i++)
04577    jb->ok[i]=0;
04578 
04579     ast_mutex_init(&jb->mutexjb);
04580 
04581     return jb;
04582 }

static struct ast_channel * misdn_new struct chan_list cl,
int  state,
char *  exten,
char *  callerid,
int  format,
int  port,
int  c
[static]
 

Definition at line 2690 of file chan_misdn.c.

References ast_callerid_parse(), ast_channel_alloc(), ast_setstate(), AST_STATE_RING, ast_strlen_zero(), chan_misdn_log(), ast_channel::cid, ast_callerid::cid_name, cid_name, ast_callerid::cid_num, cid_num, ast_channel::exten, ast_channel::fds, misdn_cfg_get(), misdn_tech, misdn_tech_wo_bridge, misdn_type, ast_channel::name, ast_channel::nativeformats, chan_list::pipe, prefformat, ast_channel::priority, ast_channel::rawreadformat, ast_channel::rawwriteformat, ast_channel::readformat, ast_channel::rings, strdup, ast_channel::tech, ast_channel::tech_pvt, ast_channel::type, and ast_channel::writeformat.

Referenced by cb_events().

02691 {
02692    struct ast_channel *tmp;
02693    
02694    tmp = ast_channel_alloc(1);
02695    
02696    if (tmp) {
02697       chan_misdn_log(2, 0, " --> * NEW CHANNEL dad:%s oad:%s\n",exten,callerid);
02698       
02699       
02700       if (c<=0) {
02701          c=glob_channel++;
02702          snprintf(tmp->name, sizeof(tmp->name), "%s/%d-u%d",
02703              misdn_type, port, c);
02704       } else {
02705          snprintf(tmp->name, sizeof(tmp->name), "%s/%d-%d",
02706              misdn_type, port, c);
02707       }
02708       
02709       tmp->type = misdn_type;
02710       
02711       tmp->nativeformats = prefformat;
02712 
02713       tmp->readformat = format;
02714       tmp->rawreadformat = format;
02715       tmp->writeformat = format;
02716       tmp->rawwriteformat = format;
02717     
02718       tmp->tech_pvt = chlist;
02719       
02720       int bridging;
02721       misdn_cfg_get( 0, MISDN_GEN_BRIDGING, &bridging, sizeof(int));
02722       if (bridging)
02723          tmp->tech = &misdn_tech;
02724       else
02725          tmp->tech = &misdn_tech_wo_bridge;
02726       
02727       tmp->writeformat = format;
02728       tmp->readformat = format;
02729       tmp->priority=1;
02730       
02731       if (exten) 
02732          ast_copy_string(tmp->exten, exten,  sizeof(tmp->exten));
02733       else
02734          chan_misdn_log(1,0,"misdn_new: no exten given.\n");
02735       
02736       if (callerid) {
02737          char *cid_name, *cid_num;
02738       
02739          ast_callerid_parse(callerid, &cid_name, &cid_num);
02740 
02741          if (!ast_strlen_zero(cid_num))
02742             tmp->cid.cid_num = strdup(cid_num);
02743          if (!ast_strlen_zero(cid_name))
02744             tmp->cid.cid_name = strdup(cid_name);
02745       }
02746 
02747       {
02748          if (pipe(chlist->pipe)<0)
02749             perror("Pipe failed\n");
02750          
02751          tmp->fds[0]=chlist->pipe[0];
02752          
02753       }
02754       
02755       ast_setstate(tmp, state);
02756       if (state == AST_STATE_RING)
02757          tmp->rings = 1;
02758       else
02759          tmp->rings = 0;
02760       
02761       
02762    } else {
02763       chan_misdn_log(-1,0,"Unable to allocate channel structure\n");
02764    }
02765    
02766    return tmp;
02767 }

static int misdn_port_block int  fd,
int  argc,
char *  argv[]
[static]
 

Definition at line 535 of file chan_misdn.c.

References RESULT_SHOWUSAGE.

00536 {
00537    int port;
00538   
00539    if (argc != 4)
00540       return RESULT_SHOWUSAGE;
00541   
00542    port = atoi(argv[3]);
00543 
00544    misdn_lib_port_block(port);
00545 
00546    return 0;
00547 }

static int misdn_port_down int  fd,
int  argc,
char *  argv[]
[static]
 

Definition at line 592 of file chan_misdn.c.

References RESULT_SHOWUSAGE.

00593 {
00594    int port;
00595    
00596    if (argc != 4)
00597       return RESULT_SHOWUSAGE;
00598    
00599    port = atoi(argv[3]);
00600    
00601    misdn_lib_get_port_down(port);
00602   
00603    return 0;
00604 }

static int misdn_port_unblock int  fd,
int  argc,
char *  argv[]
[static]
 

Definition at line 549 of file chan_misdn.c.

References RESULT_SHOWUSAGE.

00550 {
00551    int port;
00552   
00553    if (argc != 4)
00554       return RESULT_SHOWUSAGE;
00555   
00556    port = atoi(argv[3]);
00557 
00558    misdn_lib_port_unblock(port);
00559 
00560    return 0;
00561 }

static int misdn_port_up int  fd,
int  argc,
char *  argv[]
[static]
 

Definition at line 578 of file chan_misdn.c.

References RESULT_SHOWUSAGE.

00579 {
00580    int port;
00581    
00582    if (argc != 4)
00583       return RESULT_SHOWUSAGE;
00584    
00585    port = atoi(argv[3]);
00586    
00587    misdn_lib_get_port_up(port);
00588   
00589    return 0;
00590 }

static struct ast_frame* misdn_read struct ast_channel ast  )  [static]
 

Definition at line 2130 of file chan_misdn.c.

References chan_list::ast, chan_list::ast_dsp, AST_FORMAT_ALAW, AST_FRAME_VOICE, chan_list::ast_rd_buf, chan_list::bc, chan_misdn_log(), ast_frame::data, ast_frame::datalen, ast_frame::delivery, chan_list::faxdetect, chan_list::frame, ast_frame::frametype, ast_frame::mallocd, MISDN_ASTERISK_TECH_PVT, ast_frame::offset, chan_list::pipe, process_ast_dsp(), ast_frame::samples, ast_frame::src, and ast_frame::subclass.

02131 {
02132    struct chan_list *tmp;
02133    int len;
02134    
02135    if (!ast) {
02136       chan_misdn_log(1,0,"misdn_read called without ast\n");
02137       return NULL;
02138    }
02139    if (! (tmp=MISDN_ASTERISK_TECH_PVT(ast)) ) {
02140       chan_misdn_log(1,0,"misdn_read called without ast->pvt\n");
02141       return NULL;
02142    }
02143    if (!tmp->bc) {
02144       chan_misdn_log(1,0,"misdn_read called without bc\n");
02145       return NULL;
02146    }
02147 
02148    len=read(tmp->pipe[0],tmp->ast_rd_buf,sizeof(tmp->ast_rd_buf));
02149    
02150    if (len<=0) {
02151       /* we hangup here, since our pipe is closed */
02152       chan_misdn_log(2,tmp->bc->port,"misdn_read: Pipe closed, hanging up\n");
02153       return NULL;
02154    }
02155 
02156    tmp->frame.frametype  = AST_FRAME_VOICE;
02157    tmp->frame.subclass = AST_FORMAT_ALAW;
02158    tmp->frame.datalen = len;
02159    tmp->frame.samples = len ;
02160    tmp->frame.mallocd =0 ;
02161    tmp->frame.offset= 0 ;
02162    tmp->frame.delivery= ast_tv(0,0) ;
02163    tmp->frame.src = NULL;
02164    tmp->frame.data = tmp->ast_rd_buf ;
02165    
02166    if (tmp->faxdetect || tmp->ast_dsp ) {
02167       return process_ast_dsp(tmp, &tmp->frame);
02168    }
02169    
02170    return &tmp->frame;
02171 }

static int misdn_reload int  fd,
int  argc,
char *  argv[]
[static]
 

Definition at line 722 of file chan_misdn.c.

References ast_cli(), and reload_config().

00723 {
00724    ast_cli(fd, "Reloading mISDN Config\n");
00725    reload_config();
00726    return 0;
00727 }

static struct ast_channel* misdn_request const char *  type,
int  format,
void *  data,
int *  cause
[static]
 

Definition at line 2469 of file chan_misdn.c.

References ast_log(), ast_strlen_zero(), chan_misdn_log(), robin_list::channel, get_robin_position(), group, init_chan_list(), LOG_WARNING, misdn_cfg_get(), misdn_cfg_get_next_port(), misdn_cfg_get_next_port_spin(), misdn_cfg_is_group_method(), misdn_type, ORG_AST, and robin_list::port.

02471 {
02472    struct ast_channel *tmp = NULL;
02473    char group[BUFFERSIZE+1]="";
02474    char buf[128];
02475    char buf2[128], *ext=NULL, *port_str;
02476    char *tokb=NULL, *p=NULL;
02477    int channel=0, port=0;
02478    struct misdn_bchannel *newbc = NULL;
02479    
02480    struct chan_list *cl=init_chan_list(ORG_AST);
02481    
02482    sprintf(buf,"%s/%s",misdn_type,(char*)data);
02483    ast_copy_string(buf2,data, 128);
02484    
02485    port_str=strtok_r(buf2,"/", &tokb);
02486 
02487    ext=strtok_r(NULL,"/", &tokb);
02488 
02489    if (port_str) {
02490       if (port_str[0]=='g' && port_str[1]==':' ) {
02491          /* We make a group call lets checkout which ports are in my group */
02492          port_str += 2;
02493          strncpy(group, port_str, BUFFERSIZE);
02494          group[127] = 0;
02495          chan_misdn_log(2, 0, " --> Group Call group: %s\n",group);
02496       } 
02497       else if ((p = strchr(port_str, ':'))) {
02498          /* we have a preselected channel */
02499          *p = 0;
02500          channel = atoi(++p);
02501          port = atoi(port_str);
02502          chan_misdn_log(2, port, " --> Call on preselected Channel (%d).\n", channel);
02503       }
02504       else {
02505          port = atoi(port_str);
02506       }
02507       
02508       
02509    } else {
02510       ast_log(LOG_WARNING, " --> ! IND : CALL dad:%s WITHOUT PORT/Group, check extension.conf\n",ext);
02511       return NULL;
02512    }
02513 
02514    if (!ast_strlen_zero(group)) {
02515    
02516       char cfg_group[BUFFERSIZE+1];
02517       struct robin_list *rr = NULL;
02518 
02519       if (misdn_cfg_is_group_method(group, METHOD_ROUND_ROBIN)) {
02520          chan_misdn_log(4, port, " --> STARTING ROUND ROBIN...");
02521          rr = get_robin_position(group);
02522       }
02523       
02524       if (rr) {
02525          int robin_channel = rr->channel;
02526          int port_start;
02527          int next_chan = 1;
02528 
02529          do {
02530             port_start = 0;
02531             for (port = misdn_cfg_get_next_port_spin(rr->port); port > 0 && port != port_start;
02532                 port = misdn_cfg_get_next_port_spin(port)) {
02533 
02534                if (!port_start)
02535                   port_start = port;
02536 
02537                if (port >= port_start)
02538                   next_chan = 1;
02539                
02540                if (port <= port_start && next_chan) {
02541                   int maxbchans=misdn_lib_get_maxchans(port);
02542                   if (++robin_channel >= maxbchans) {
02543                      robin_channel = 1;
02544                   }
02545                   next_chan = 0;
02546                }
02547 
02548                misdn_cfg_get(port, MISDN_CFG_GROUPNAME, cfg_group, BUFFERSIZE);
02549                
02550                if (!strcasecmp(cfg_group, group)) {
02551                   int port_up;
02552                   int check;
02553                   misdn_cfg_get(port, MISDN_CFG_PMP_L1_CHECK, &check, sizeof(int));
02554                   port_up = misdn_lib_port_up(port, check);
02555 
02556                   if (check && !port_up) 
02557                      chan_misdn_log(1,port,"L1 is not Up on this Port\n");
02558                   
02559                   if (check && port_up<0) {
02560                      ast_log(LOG_WARNING,"This port (%d) is blocked\n", port);
02561                   }
02562                   
02563                   
02564                   if ( port_up>0 )  {
02565                      newbc = misdn_lib_get_free_bc(port, robin_channel,0);
02566                      if (newbc) {
02567                         chan_misdn_log(4, port, " Success! Found port:%d channel:%d\n", newbc->port, newbc->channel);
02568                         if (port_up)
02569                            chan_misdn_log(4, port, "portup:%d\n",  port_up);
02570                         rr->port = newbc->port;
02571                         rr->channel = newbc->channel;
02572                         break;
02573                      }
02574                   }
02575                }
02576             }
02577          } while (!newbc && robin_channel != rr->channel);
02578          
02579          if (!newbc)
02580             chan_misdn_log(-1, port, " Failed! No free channel in group %d!", group);
02581       }
02582       
02583       else {      
02584          for (port=misdn_cfg_get_next_port(0); port > 0;
02585              port=misdn_cfg_get_next_port(port)) {
02586             
02587             misdn_cfg_get( port, MISDN_CFG_GROUPNAME, cfg_group, BUFFERSIZE);
02588 
02589             chan_misdn_log(3,port, "Group [%s] Port [%d]\n", group, port);
02590             if (!strcasecmp(cfg_group, group)) {
02591                int port_up;
02592                int check;
02593                misdn_cfg_get(port, MISDN_CFG_PMP_L1_CHECK, &check, sizeof(int));
02594                port_up = misdn_lib_port_up(port, check);
02595                
02596                chan_misdn_log(4, port, "portup:%d\n", port_up);
02597                
02598                if ( port_up>0 ) {
02599                   newbc = misdn_lib_get_free_bc(port, 0, 0);
02600                   if (newbc)
02601                      break;
02602                }
02603             }
02604          }
02605       }
02606       
02607    } else {
02608       if (channel)
02609          chan_misdn_log(1, port," --> preselected_channel: %d\n",channel);
02610       newbc = misdn_lib_get_free_bc(port, channel, 0);
02611    }
02612    
02613    if (!newbc) {
02614       chan_misdn_log(-1, 0, "Could not create channel on port:%d with extensions:%s\n",port,ext);
02615       return NULL;
02616    }
02617 
02618    /* create ast_channel and link all the objects together */
02619    cl->bc=newbc;
02620    
02621    tmp = misdn_new(cl, AST_STATE_RESERVED, ext, NULL, format, port, channel);
02622    cl->ast=tmp;
02623    
02624    /* register chan in local list */
02625    cl_queue_chan(&cl_te, cl) ;
02626    
02627    /* fill in the config into the objects */
02628    read_config(cl, ORG_AST);
02629 
02630    /* important */
02631    cl->need_hangup=0;
02632    
02633    return tmp;
02634 }

static int misdn_restart_port int  fd,
int  argc,
char *  argv[]
[static]
 

Definition at line 564 of file chan_misdn.c.

References RESULT_SHOWUSAGE.

00565 {
00566    int port;
00567   
00568    if (argc != 4)
00569       return RESULT_SHOWUSAGE;
00570   
00571    port = atoi(argv[3]);
00572 
00573    misdn_lib_port_restart(port);
00574 
00575    return 0;
00576 }

static int misdn_send_cd int  fd,
int  argc,
char *  argv[]
[static]
 

Definition at line 881 of file chan_misdn.c.

References ast_cli(), chan_list::bc, get_chan_by_ast_name(), and RESULT_SHOWUSAGE.

00882 {
00883    char *channame; 
00884    char *nr; 
00885   
00886    if (argc != 5)
00887       return RESULT_SHOWUSAGE;
00888   
00889    channame = argv[3];
00890    nr = argv[4];
00891    
00892    ast_cli(fd, "Sending Calldeflection (%s) to %s\n",nr, channame);
00893    
00894    {
00895       struct chan_list *tmp=get_chan_by_ast_name(channame);
00896       
00897       if (!tmp) {
00898          ast_cli(fd, "Sending CD with nr %s to %s failed Channel does not exist\n",nr, channame);
00899          return 0; 
00900       } else {
00901          
00902          misdn_lib_send_facility(tmp->bc, FACILITY_CALLDEFLECT, nr);
00903       }
00904    }
00905   
00906    return 0; 
00907 }

static int misdn_send_digit int  fd,
int  argc,
char *  argv[]
[static]
 

Definition at line 909 of file chan_misdn.c.

References chan_list::ast, ast_cli(), ast_dtmf_stream(), get_chan_by_ast_name(), RESULT_SHOWUSAGE, and send_digit_to_chan().

00910 {
00911    char *channame; 
00912    char *msg; 
00913   
00914    if (argc != 5)
00915       return RESULT_SHOWUSAGE;
00916   
00917    channame = argv[3];
00918    msg = argv[4];
00919 
00920    ast_cli(fd, "Sending %s to %s\n",msg, channame);
00921   
00922    {
00923       struct chan_list *tmp=get_chan_by_ast_name(channame);
00924     
00925       if (!tmp) {
00926          ast_cli(fd, "Sending %s to %s failed Channel does not exist\n",msg, channame);
00927          return 0; 
00928       } else {
00929 #if 1
00930          int i;
00931          int msglen = strlen(msg);
00932          for (i=0; i<msglen; i++) {
00933             ast_cli(fd, "Sending: %c\n",msg[i]);
00934             send_digit_to_chan(tmp, msg[i]);
00935             /* res = ast_safe_sleep(tmp->ast, 250); */
00936             usleep(250000);
00937             /* res = ast_waitfor(tmp->ast,100); */
00938          }
00939 #else
00940          int res;
00941          res = ast_dtmf_stream(tmp->ast,NULL,msg,250);
00942 #endif
00943       }
00944    }
00945   
00946    return 0; 
00947 }

static int misdn_send_display int  fd,
int  argc,
char *  argv[]
[static]
 

Definition at line 982 of file chan_misdn.c.

References ast_cli(), chan_list::bc, get_chan_by_ast_name(), RESULT_FAILURE, RESULT_SHOWUSAGE, and RESULT_SUCCESS.

00983 {
00984    char *channame; 
00985    char *msg; 
00986   
00987    if (argc != 5)
00988       return RESULT_SHOWUSAGE;
00989   
00990    channame = argv[3];
00991    msg = argv[4];
00992 
00993    ast_cli(fd, "Sending %s to %s\n",msg, channame);
00994    {
00995       struct chan_list *tmp;
00996       tmp=get_chan_by_ast_name(channame);
00997     
00998       if (tmp && tmp->bc) {
00999          ast_copy_string(tmp->bc->display, msg, sizeof(tmp->bc->display));
01000          misdn_lib_send_event(tmp->bc, EVENT_INFORMATION);
01001       } else {
01002          ast_cli(fd,"No such channel %s\n",channame);
01003          return RESULT_FAILURE;
01004       }
01005    }
01006 
01007    return RESULT_SUCCESS ;
01008 }

int misdn_send_text struct ast_channel chan,
const char *  text
 

Definition at line 2637 of file chan_misdn.c.

References ast_log(), chan_list::bc, LOG_WARNING, and ast_channel::tech_pvt.

02638 {
02639    struct chan_list *tmp=chan->tech_pvt;
02640    
02641    if (tmp && tmp->bc) {
02642       ast_copy_string(tmp->bc->display,text,sizeof(tmp->bc->display));
02643       misdn_lib_send_event(tmp->bc, EVENT_INFORMATION);
02644    } else {
02645       ast_log(LOG_WARNING, "No chan_list but send_text request?\n");
02646       return -1;
02647    }
02648    
02649    return 0;
02650 }

static int misdn_set_crypt_debug int  fd,
int  argc,
char *  argv[]
[static]
 

Definition at line 527 of file chan_misdn.c.

References RESULT_SHOWUSAGE.

00528 {
00529    if (argc != 5) return RESULT_SHOWUSAGE; 
00530 
00531    return 0;
00532 }

static int misdn_set_debug int  fd,
int  argc,
char *  argv[]
[static]
 

Definition at line 470 of file chan_misdn.c.

References ast_cli(), max_ports, misdn_debug, misdn_debug_only, and RESULT_SHOWUSAGE.

00471 {
00472    if (argc != 4 && argc != 5 && argc != 6 && argc != 7)
00473       return RESULT_SHOWUSAGE; 
00474 
00475    int level = atoi(argv[3]);
00476 
00477    switch (argc) {
00478       case 4:  
00479       case 5: {
00480                int only = 0;
00481                if (argc == 5) {
00482                   if (strncasecmp(argv[4], "only", strlen(argv[4])))
00483                      return RESULT_SHOWUSAGE;
00484                   else
00485                      only = 1;
00486                }
00487                int i;
00488                for (i=0; i<=max_ports; i++) {
00489                   misdn_debug[i] = level;
00490                   misdn_debug_only[i] = only;
00491                }
00492                ast_cli(fd, "changing debug level for all ports to %d%s\n",misdn_debug[0], only?" (only)":"");
00493             }
00494             break;
00495       case 6: 
00496       case 7: {
00497                if (strncasecmp(argv[4], "port", strlen(argv[4])))
00498                   return RESULT_SHOWUSAGE;
00499                int port = atoi(argv[5]);
00500                if (port <= 0 || port > max_ports) {
00501                   switch (max_ports) {
00502                      case 0:
00503                         ast_cli(fd, "port number not valid! no ports available so you won't get lucky with any number here...\n");
00504                         break;
00505                      case 1:
00506                         ast_cli(fd, "port number not valid! only port 1 is availble.\n");
00507                         break;
00508                      default:
00509                         ast_cli(fd, "port number not valid! only ports 1 to %d are available.\n", max_ports);
00510                      }
00511                      return 0;
00512                }
00513                if (argc == 7) {
00514                   if (strncasecmp(argv[6], "only", strlen(argv[6])))
00515                      return RESULT_SHOWUSAGE;
00516                   else
00517                      misdn_debug_only[port] = 1;
00518                } else
00519                   misdn_debug_only[port] = 0;
00520                misdn_debug[port] = level;
00521                ast_cli(fd, "changing debug level to %d%s for port %d\n", misdn_debug[port], misdn_debug_only[port]?" (only)":"", port);
00522             }
00523    }
00524    return 0;
00525 }

static int misdn_set_opt_exec struct ast_channel chan,
void *  data
[static]
 

Definition at line 4341 of file chan_misdn.c.

References chan_list::ast_dsp, ast_log(), ast_strlen_zero(), chan_list::bc, chan_misdn_log(), chan_list::faxdetect, chan_list::jb_len, chan_list::jb_upper_threshold, LOG_WARNING, MISDN_ASTERISK_TECH_PVT, misdn_key_vector, misdn_key_vector_size, chan_list::orginator, rxgain, ast_channel::tech, txgain, and ast_channel_tech::type.

Referenced by load_module(), and misdn_call().

04342 {
04343    struct chan_list *ch = MISDN_ASTERISK_TECH_PVT(chan);
04344    char *tok,*tokb;
04345    int  keyidx=0;
04346    int rxgain=0;
04347    int txgain=0;
04348    int change_jitter=0;
04349    
04350    if (strcasecmp(chan->tech->type,"mISDN")) {
04351       ast_log(LOG_WARNING, "misdn_set_opt makes only sense with chan_misdn channels!\n");
04352       return -1;
04353    }
04354    
04355    if (ast_strlen_zero((char *)data)) {
04356       ast_log(LOG_WARNING, "misdn_set_opt Requires arguments\n");
04357       return -1;
04358    }
04359 
04360    for (tok=strtok_r((char*)data, ":",&tokb);
04361         tok;
04362         tok=strtok_r(NULL,":",&tokb) ) {
04363       int neglect=0;
04364       
04365       if (tok[0] == '!' ) {
04366          neglect=1;
04367          tok++;
04368       }
04369       
04370       switch(tok[0]) {
04371          
04372       case 'd' :
04373          ast_copy_string(ch->bc->display,++tok,84);
04374          chan_misdn_log(1, ch->bc->port, "SETOPT: Display:%s\n",ch->bc->display);
04375          break;
04376          
04377       case 'n':
04378          chan_misdn_log(1, ch->bc->port, "SETOPT: No DSP\n");
04379          ch->bc->nodsp=1;
04380          break;
04381 
04382       case 'j':
04383          chan_misdn_log(1, ch->bc->port, "SETOPT: jitter\n");
04384          tok++;
04385          change_jitter=1;
04386          
04387          switch ( tok[0] ) {
04388          case 'b' :
04389             ch->jb_len=atoi(++tok);
04390             chan_misdn_log(1, ch->bc->port, " --> buffer_len:%d\n",ch->jb_len);
04391             break;
04392          case 't' :
04393             ch->jb_upper_threshold=atoi(++tok);
04394             chan_misdn_log(1, ch->bc->port, " --> upper_threshold:%d\n",ch->jb_upper_threshold);
04395             break;
04396 
04397          case 'n':
04398             ch->bc->nojitter=1;
04399             chan_misdn_log(1, ch->bc->port, " --> nojitter\n");
04400             break;
04401             
04402          default:
04403             ch->jb_len=4000;
04404             ch->jb_upper_threshold=0;
04405             chan_misdn_log(1, ch->bc->port, " --> buffer_len:%d (default)\n",ch->jb_len);
04406             chan_misdn_log(1, ch->bc->port, " --> upper_threshold:%d (default)\n",ch->jb_upper_threshold);
04407          }
04408          
04409          break;
04410       
04411       case 'v':
04412          tok++;
04413 
04414          switch ( tok[0] ) {
04415          case 'r' :
04416             rxgain=atoi(++tok);
04417             if (rxgain<-8) rxgain=-8;
04418             if (rxgain>8) rxgain=8;
04419             ch->bc->rxgain=rxgain;
04420             chan_misdn_log(1, ch->bc->port, "SETOPT: Volume:%d\n",rxgain);
04421             break;
04422          case 't':
04423             txgain=atoi(++tok);
04424             if (txgain<-8) txgain=-8;
04425             if (txgain>8) txgain=8;
04426             ch->bc->txgain=txgain;
04427             chan_misdn_log(1, ch->bc->port, "SETOPT: Volume:%d\n",txgain);
04428             break;
04429          }
04430          break;
04431       
04432       case 'c':
04433          keyidx=atoi(++tok);
04434       
04435          if (keyidx > misdn_key_vector_size  || keyidx < 0 ) {
04436             ast_log(LOG_WARNING, "You entered the keyidx: %d but we have only %d keys\n",keyidx, misdn_key_vector_size );
04437             continue; 
04438          }
04439       
04440          {
04441             ast_copy_string(ch->bc->crypt_key,  misdn_key_vector[keyidx], sizeof(ch->bc->crypt_key));
04442          }
04443          
04444          chan_misdn_log(0, ch->bc->port, "SETOPT: crypt with key:%s\n",misdn_key_vector[keyidx]);
04445          break;
04446 
04447       case 'e':
04448          chan_misdn_log(1, ch->bc->port, "SETOPT: EchoCancel\n");
04449          
04450          if (neglect) {
04451             chan_misdn_log(1, ch->bc->port, " --> disabled\n");
04452             ch->bc->ec_enable=0;
04453 
04454          } else {
04455             ch->bc->ec_enable=1;
04456             ch->bc->orig=ch->orginator;
04457             tok++;
04458             if (tok) {
04459                ch->bc->ec_deftaps=atoi(tok);
04460             }
04461          }
04462          
04463          break;
04464       
04465       case 'h':
04466          chan_misdn_log(1, ch->bc->port, "SETOPT: Digital\n");
04467          
04468          if (strlen(tok) > 1 && tok[1]=='1') {
04469             chan_misdn_log(1, ch->bc->port, "SETOPT: HDLC \n");
04470             if (!ch->bc->hdlc) {
04471                ch->bc->hdlc=1;
04472                misdn_lib_setup_bc(ch->bc);
04473             }
04474          }  
04475          ch->bc->capability=INFO_CAPABILITY_DIGITAL_UNRESTRICTED;
04476          break;
04477             
04478       case 's':
04479          chan_misdn_log(1, ch->bc->port, "SETOPT: Send DTMF\n");
04480          ch->bc->send_dtmf=1;
04481          break;
04482          
04483       case 'f':
04484          chan_misdn_log(1, ch->bc->port, "SETOPT: Faxdetect\n");
04485          ch->faxdetect=1;
04486          break;
04487 
04488       case 'a':
04489          chan_misdn_log(1, ch->bc->port, "SETOPT: AST_DSP (for DTMF)\n");
04490          ch->ast_dsp=1;
04491          break;
04492 
04493       case 'p':
04494          chan_misdn_log(1, ch->bc->port, "SETOPT: callerpres: %s\n",&tok[1]);
04495          /* CRICH: callingpres!!! */
04496          if (strstr(tok,"allowed") ) {
04497             ch->bc->pres=0;
04498          } else if (strstr(tok,"not_screened")) {
04499             ch->bc->pres=1;
04500          }
04501          
04502          
04503          break;
04504       
04505       
04506       default:
04507          break;
04508       }
04509    }
04510 
04511    if (change_jitter)
04512       config_jitterbuffer(ch);
04513    
04514    
04515    if (ch->faxdetect || ch->ast_dsp) {
04516       
04517       if (!ch->dsp) ch->dsp = ast_dsp_new();
04518       if (ch->dsp) ast_dsp_set_features(ch->dsp, DSP_FEATURE_DTMF_DETECT| DSP_FEATURE_FAX_DETECT);
04519       if (!ch->trans) ch->trans=ast_translator_build_path(AST_FORMAT_SLINEAR, AST_FORMAT_ALAW);
04520    }
04521 
04522    if (ch->ast_dsp) {
04523       chan_misdn_log(1,ch->bc->port,"SETOPT: with AST_DSP we deactivate mISDN_dsp\n");
04524       ch->bc->nodsp=1;
04525       ch->bc->nojitter=1;
04526    }
04527    
04528    return 0;
04529 }

static int misdn_set_tics int  fd,
int  argc,
char *  argv[]
[static]
 

Definition at line 834 of file chan_misdn.c.

References RESULT_SHOWUSAGE.

00835 {
00836    if (argc != 4)
00837       return RESULT_SHOWUSAGE;
00838   
00839    MAXTICS=atoi(argv[3]);
00840   
00841    return 0;
00842 }

static int misdn_show_cl int  fd,
int  argc,
char *  argv[]
[static]
 

Definition at line 808 of file chan_misdn.c.

References chan_list::ast, chan_list::bc, cl_te, ast_channel::name, chan_list::next, print_bc_info(), and RESULT_SHOWUSAGE.

00809 {
00810    struct chan_list *help=cl_te;
00811 
00812    if (argc != 4)
00813       return RESULT_SHOWUSAGE;
00814   
00815    for (;help; help=help->next) {
00816       struct misdn_bchannel *bc=help->bc;   
00817       struct ast_channel *ast=help->ast;
00818     
00819       if (bc && ast) {
00820          if (!strcasecmp(ast->name,argv[3])) {
00821             print_bc_info(fd, help, bc);
00822             break; 
00823          }
00824       } 
00825    }
00826   
00827   
00828    return 0;
00829 }

static int misdn_show_cls int  fd,
int  argc,
char *  argv[]
[static]
 

Definition at line 776 of file chan_misdn.c.

References chan_list::ast, ast_cli(), chan_list::bc, cl_te, misdn_debug, chan_list::next, and print_bc_info().

00777 {
00778    struct chan_list *help=cl_te;
00779   
00780    ast_cli(fd,"Chan List: %p\n",cl_te); 
00781   
00782    for (;help; help=help->next) {
00783       struct misdn_bchannel *bc=help->bc;   
00784       struct ast_channel *ast=help->ast;
00785       if (misdn_debug[0] > 2) ast_cli(fd, "Bc:%p Ast:%p\n", bc, ast);
00786       if (bc) {
00787          print_bc_info(fd, help, bc);
00788       } else {
00789          if (help->state == MISDN_HOLDED) {
00790             chan_misdn_log(0, 0, "ITS A HOLDED BC:\n");
00791             chan_misdn_log(0,0," --> l3_id: %x\n"
00792                   " --> dad:%s oad:%s\n"
00793             
00794                   ,help->l3id
00795                   ,ast->exten
00796                   ,AST_CID_P(ast)
00797                   );
00798          } else {
00799             ast_cli(fd,"* Channel in unknown STATE !!! Exten:%s, Callerid:%s\n", ast->exten, AST_CID_P(ast));
00800          }
00801       }
00802    }
00803   
00804   
00805    return 0;
00806 }

static int misdn_show_config int  fd,
int  argc,
char *  argv[]
[static]
 

Definition at line 607 of file chan_misdn.c.

References ast_cli(), misdn_cfg_get_config_string(), and RESULT_SHOWUSAGE.

00608 {
00609    char buffer[BUFFERSIZE];
00610    enum misdn_cfg_elements elem;
00611    int linebreak;
00612 
00613    int onlyport = -1;
00614    if (argc >= 4) {
00615       if (!sscanf(argv[3], "%d", &onlyport) || onlyport < 0) {
00616          ast_cli(fd, "Unknown option: %s\n", argv[3]);
00617          return RESULT_SHOWUSAGE;
00618       }
00619    }
00620    
00621    if (argc == 3 || onlyport == 0) {
00622       ast_cli(fd,"Misdn General-Config: \n"); 
00623       ast_cli(fd," -> Version: chan_misdn-" CHAN_MISDN_VERSION "\n");
00624       for (elem = MISDN_GEN_FIRST + 1, linebreak = 1; elem < MISDN_GEN_LAST; elem++, linebreak++) {
00625          misdn_cfg_get_config_string( 0, elem, buffer, BUFFERSIZE);
00626          ast_cli(fd, "%-36s%s", buffer, !(linebreak % 2) ? "\n" : "");
00627       }
00628       ast_cli(fd, "\n");
00629    }
00630 
00631    if (onlyport < 0) {
00632       int port = misdn_cfg_get_next_port(0);
00633       for (; port > 0; port = misdn_cfg_get_next_port(port)) {
00634          ast_cli(fd, "\n[PORT %d]\n", port);
00635          for (elem = MISDN_CFG_FIRST + 1, linebreak = 1; elem < MISDN_CFG_LAST; elem++, linebreak++) {
00636             misdn_cfg_get_config_string( port, elem, buffer, BUFFERSIZE);
00637             ast_cli(fd, "%-36s%s", buffer, !(linebreak % 2) ? "\n" : "");
00638          }  
00639          ast_cli(fd, "\n");
00640       }
00641    }
00642    
00643    if (onlyport > 0) {
00644       if (misdn_cfg_is_port_valid(onlyport)) {
00645          ast_cli(fd, "[PORT %d]\n", onlyport);
00646          for (elem = MISDN_CFG_FIRST + 1, linebreak = 1; elem < MISDN_CFG_LAST; elem++, linebreak++) {
00647             misdn_cfg_get_config_string( onlyport, elem, buffer, BUFFERSIZE);
00648             ast_cli(fd, "%-36s%s", buffer, !(linebreak % 2) ? "\n" : "");
00649          }  
00650          ast_cli(fd, "\n");
00651       } else {
00652          ast_cli(fd, "Port %d is not active!\n", onlyport);
00653       }
00654    }
00655    return 0;
00656 }

static int misdn_show_port int  fd,
int  argc,
char *  argv[]
[static]
 

Definition at line 862 of file chan_misdn.c.

References ast_cli(), misdn_debug, misdn_debug_only, and RESULT_SHOWUSAGE.

00863 {
00864    int port;
00865    
00866    if (argc != 4)
00867       return RESULT_SHOWUSAGE;
00868   
00869    port = atoi(argv[3]);
00870   
00871    ast_cli(fd, "BEGIN STACK_LIST:\n");
00872 
00873    char buf[128];
00874    get_show_stack_details(port,buf);
00875    ast_cli(fd,"  %s  Debug:%d%s\n",buf, misdn_debug[port], misdn_debug_only[port]?"(only)":"");
00876 
00877    
00878    return 0;
00879 }

static int misdn_show_stacks int  fd,
int  argc,
char *  argv[]
[static]
 

Definition at line 844 of file chan_misdn.c.

References ast_cli(), misdn_cfg_get_next_port(), misdn_debug, and misdn_debug_only.

00845 {
00846    int port;
00847 
00848    ast_cli(fd, "BEGIN STACK_LIST:\n");
00849 
00850    for (port=misdn_cfg_get_next_port(0); port > 0;
00851         port=misdn_cfg_get_next_port(port)) {
00852       char buf[128];
00853       get_show_stack_details(port,buf);
00854       ast_cli(fd,"  %s  Debug:%d%s\n", buf, misdn_debug[port], misdn_debug_only[port]?"(only)":"");
00855    }
00856       
00857 
00858    return 0;
00859 
00860 }

static int misdn_toggle_echocancel int  fd,
int  argc,
char *  argv[]
[static]
 

Definition at line 949 of file chan_misdn.c.

References ast_cli(), chan_list::bc, get_chan_by_ast_name(), RESULT_SHOWUSAGE, chan_list::toggle_ec, and update_ec_config().

00950 {
00951    char *channame; 
00952 
00953    if (argc != 4)
00954       return RESULT_SHOWUSAGE;
00955    
00956    channame = argv[3];
00957   
00958    ast_cli(fd, "Toggling EchoCancel on %s\n", channame);
00959   
00960    {
00961       struct chan_list *tmp=get_chan_by_ast_name(channame);
00962     
00963       if (!tmp) {
00964          ast_cli(fd, "Toggling EchoCancel %s failed Channel does not exist\n", channame);
00965          return 0; 
00966       } else {
00967          
00968          tmp->toggle_ec=tmp->toggle_ec?0:1;
00969 
00970          if (tmp->toggle_ec) {
00971             update_ec_config(tmp->bc);
00972             manager_ec_enable(tmp->bc);
00973          } else {
00974             manager_ec_disable(tmp->bc);
00975          }
00976       }
00977    }
00978   
00979    return 0; 
00980 }

static void misdn_transfer_bc struct chan_list tmp_ch,
struct chan_list holded_chan
[static]
 

Definition at line 3028 of file chan_misdn.c.

References chan_list::ast, AST_BRIDGED_P, ast_channel_masquerade(), ast_moh_stop(), chan_misdn_log(), MISDN_CONNECTED, MISDN_HOLD_DISCONNECT, ast_channel::name, and chan_list::state.

03029 {
03030    chan_misdn_log(4,0,"TRANSFERING %s to %s\n",holded_chan->ast->name, tmp_ch->ast->name);
03031    
03032    tmp_ch->state=MISDN_HOLD_DISCONNECT;
03033   
03034    ast_moh_stop(AST_BRIDGED_P(holded_chan->ast));
03035 
03036    holded_chan->state=MISDN_CONNECTED;
03037    //misdn_lib_transfer(holded_chan->bc);
03038    ast_channel_masquerade(holded_chan->ast, AST_BRIDGED_P(tmp_ch->ast));
03039 }

static int misdn_write struct ast_channel ast,
struct ast_frame frame
[static]
 

Definition at line 2174 of file chan_misdn.c.

References chan_list::ast, ast_log(), chan_list::bc, chan_misdn_log(), ast_channel::cid, ast_callerid::cid_num, ast_frame::data, chan_list::dropped_frame_cnt, ast_channel::exten, chan_list::frame, LOG_WARNING, MISDN_ASTERISK_TECH_PVT, misdn_get_ch_state(), MISDN_HOLDED, chan_list::notxtone, prefformat, ast_frame::samples, chan_list::state, and ast_frame::subclass.

02175 {
02176    struct chan_list *ch;
02177    int i  = 0;
02178    
02179    if (!ast || ! (ch=MISDN_ASTERISK_TECH_PVT(ast)) ) return -1;
02180 
02181    if (ch->state == MISDN_HOLDED) {
02182       chan_misdn_log(8, 0, "misdn_write: Returning because holded\n");
02183       return 0;
02184    }
02185    
02186    if (!ch->bc ) {
02187 
02188       ast_log(LOG_WARNING, "private but no bc\n");
02189       return -1;
02190    }
02191    
02192    if (ch->notxtone) {
02193       chan_misdn_log(9, ch->bc->port, "misdn_write: Returning because notxone\n");
02194       return 0;
02195    }
02196 
02197 
02198    if ( !frame->subclass) {
02199       chan_misdn_log(4, ch->bc->port, "misdn_write: * prods us\n");
02200       return 0;
02201    }
02202    
02203    if ( !(frame->subclass & prefformat)) {
02204       
02205       chan_misdn_log(-1, ch->bc->port, "Got Unsupported Frame with Format:%d\n", frame->subclass);
02206       return 0;
02207    }
02208    
02209 
02210    if ( !frame->samples ) {
02211       chan_misdn_log(4, ch->bc->port, "misdn_write: zero write\n");
02212       return 0;
02213    }
02214 
02215    if ( ! ch->bc->addr ) {
02216       chan_misdn_log(8, ch->bc->port, "misdn_write: no addr for bc dropping:%d\n", frame->samples);
02217       return 0;
02218    }
02219    
02220 #if MISDN_DEBUG
02221    {
02222       int i, max=5>frame->samples?frame->samples:5;
02223       
02224       printf("write2mISDN %p %d bytes: ", p, frame->samples);
02225       
02226       for (i=0; i<  max ; i++) printf("%2.2x ",((char*) frame->data)[i]);
02227       printf ("\n");
02228    }
02229 #endif
02230 
02231 
02232    switch (ch->bc->bc_state) {
02233       case BCHAN_ACTIVATED:
02234       case BCHAN_BRIDGED:
02235          break;
02236       default:
02237       if (!ch->dropped_frame_cnt)
02238          chan_misdn_log(5, ch->bc->port, "BC not active (nor bridged) droping: %d frames addr:%x exten:%s cid:%s ch->state:%s bc_state:%d l3id:%x\n",frame->samples,ch->bc->addr, ast->exten, ast->cid.cid_num,misdn_get_ch_state( ch), ch->bc->bc_state, ch->bc->l3_id);
02239       
02240       ch->dropped_frame_cnt++;
02241       if (ch->dropped_frame_cnt > 100) {
02242          ch->dropped_frame_cnt=0;
02243          chan_misdn_log(5, ch->bc->port, "BC not active (nor bridged) droping: %d frames addr:%x  dropped > 100 frames!\n",frame->samples,ch->bc->addr);
02244 
02245       }
02246 
02247       return 0;
02248    }
02249 
02250    chan_misdn_log(9, ch->bc->port, "Sending :%d bytes 2 MISDN\n",frame->samples);
02251    
02252    if ( !ch->bc->nojitter && misdn_cap_is_speech(ch->bc->capability) ) {
02253       /* Buffered Transmit (triggert by read from isdn side)*/
02254       if (misdn_jb_fill(ch->jb,frame->data,frame->samples) < 0) {
02255          if (ch->bc->active)
02256             cb_log(0,ch->bc->port,"Misdn Jitterbuffer Overflow.\n");
02257       }
02258       
02259    } else {
02260       /*transmit without jitterbuffer*/
02261       i=misdn_lib_tx2misdn_frm(ch->bc, frame->data, frame->samples);
02262    }
02263 
02264    
02265    
02266    return 0;
02267 }

static int pbx_start_chan struct chan_list ch  )  [static]
 

Channel Queue End

Definition at line 2925 of file chan_misdn.c.

References chan_list::ast, ast_pbx_start(), and chan_list::need_hangup.

Referenced by cb_events(), and do_immediate_setup().

02926 {
02927    int ret=ast_pbx_start(ch->ast);  
02928 
02929    if (ret>=0) 
02930       ch->need_hangup=0;
02931    else
02932       ch->need_hangup=1;
02933 
02934    return ret;
02935 }

static void print_bc_info int  fd,
struct chan_list help,
struct misdn_bchannel *  bc
[static]
 

Definition at line 729 of file chan_misdn.c.

References chan_list::addr, chan_list::ast, AST_CID_P, ast_cli(), bearer2str(), ast_channel::exten, chan_list::l3id, misdn_debug, misdn_get_ch_state(), ast_channel::name, chan_list::norxtone, chan_list::notxtone, ORG_AST, and chan_list::orginator.

Referenced by misdn_show_cl(), and misdn_show_cls().

00730 {
00731    struct ast_channel *ast=help->ast;
00732    ast_cli(fd,
00733       "* Pid:%d Prt:%d Ch:%d Mode:%s Org:%s dad:%s oad:%s rad:%s ctx:%s state:%s\n",
00734 
00735       bc->pid, bc->port, bc->channel,
00736       bc->nt?"NT":"TE",
00737       help->orginator == ORG_AST?"*":"I",
00738       ast?ast->exten:NULL,
00739       ast?AST_CID_P(ast):NULL,
00740       bc->rad,
00741       ast?ast->context:NULL,
00742       misdn_get_ch_state(help)
00743       );
00744    if (misdn_debug[bc->port] > 0)
00745       ast_cli(fd,
00746          "  --> astname: %s\n"
00747          "  --> ch_l3id: %x\n"
00748          "  --> ch_addr: %x\n"
00749          "  --> bc_addr: %x\n"
00750          "  --> bc_l3id: %x\n"
00751          "  --> display: %s\n"
00752          "  --> activated: %d\n"
00753          "  --> state: %s\n"
00754          "  --> capability: %s\n"
00755          "  --> echo_cancel: %d\n"
00756          "  --> notone : rx %d tx:%d\n"
00757          "  --> bc_hold: %d\n",
00758          help->ast->name,
00759          help->l3id,
00760          help->addr,
00761          bc->addr,
00762          bc?bc->l3_id:-1,
00763          bc->display,
00764          
00765          bc->active,
00766          bc_state2str(bc->bc_state),
00767          bearer2str(bc->capability),
00768          bc->ec_enable,
00769 
00770          help->norxtone,help->notxtone,
00771          bc->holded
00772          );
00773   
00774 }

static void print_bearer struct misdn_bchannel *  bc  )  [static]
 

Definition at line 417 of file chan_misdn.c.

References bearer2str(), and chan_misdn_log().

Referenced by cb_events().

00418 {
00419    
00420    chan_misdn_log(2, bc->port, " --> Bearer: %s\n",bearer2str(bc->capability));
00421    
00422    switch(bc->law) {
00423    case INFO_CODEC_ALAW:
00424       chan_misdn_log(2, bc->port, " --> Codec: Alaw\n");
00425       break;
00426    case INFO_CODEC_ULAW:
00427       chan_misdn_log(2, bc->port, " --> Codec: Ulaw\n");
00428       break;
00429    }
00430 }

static void print_facility struct misdn_bchannel *  bc  )  [static]
 

Definition at line 400 of file chan_misdn.c.

References chan_misdn_log().

00401 {
00402    switch (bc->fac_type) {
00403    case FACILITY_CALLDEFLECT:
00404       chan_misdn_log(2,bc->port," --> calldeflect: %s\n",
00405                 bc->fac.calldeflect_nr);
00406       break;
00407    case FACILITY_CENTREX:
00408       chan_misdn_log(2,bc->port," --> centrex: %s\n",
00409                 bc->fac.cnip);
00410       break;
00411    default:
00412       chan_misdn_log(2,bc->port," --> unknown\n");
00413       
00414    }
00415 }

static struct ast_frame * process_ast_dsp struct chan_list tmp,
struct ast_frame frame
[static]
 

Definition at line 2770 of file chan_misdn.c.

References chan_list::ast, ast_async_goto(), AST_CID_P, chan_list::ast_dsp, ast_dsp_process(), ast_exists_extension(), AST_FRAME_DTMF, AST_FRAME_NULL, ast_log(), ast_strlen_zero(), ast_translate(), ast_verbose(), chan_list::bc, chan_misdn_log(), ast_channel::context, chan_list::dsp, ast_channel::exten, chan_list::faxdetect, chan_list::faxhandled, ast_frame::frametype, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, ast_channel::macrocontext, ast_channel::name, option_verbose, pbx_builtin_setvar_helper(), ast_frame::subclass, chan_list::trans, and VERBOSE_PREFIX_3.

Referenced by misdn_read().

02771 {
02772    struct ast_frame *f,*f2;
02773    if (tmp->trans)
02774       f2=ast_translate(tmp->trans, frame,0);
02775    else {
02776       chan_misdn_log(0, tmp->bc->port, "No T-Path found\n");
02777       return NULL;
02778    }
02779    
02780    f = ast_dsp_process(tmp->ast, tmp->dsp, f2);
02781    if (f && (f->frametype == AST_FRAME_DTMF)) {
02782       ast_log(LOG_DEBUG, "Detected inband DTMF digit: %c\n", f->subclass);
02783       if (f->subclass == 'f' && tmp->faxdetect) {
02784          /* Fax tone -- Handle and return NULL */
02785          struct ast_channel *ast = tmp->ast;
02786          if (!tmp->faxhandled) {
02787             tmp->faxhandled++;
02788             if (strcmp(ast->exten, "fax")) {
02789                if (ast_exists_extension(ast, ast_strlen_zero(ast->macrocontext)? ast->context : ast->macrocontext, "fax", 1, AST_CID_P(ast))) {
02790                   if (option_verbose > 2)
02791                      ast_verbose(VERBOSE_PREFIX_3 "Redirecting %s to fax extension\n", ast->name);
02792                   /* Save the DID/DNIS when we transfer the fax call to a "fax" extension */
02793                   pbx_builtin_setvar_helper(ast,"FAXEXTEN",ast->exten);
02794                   if (ast_async_goto(ast, ast->context, "fax", 1))
02795                      ast_log(LOG_WARNING, "Failed to async goto '%s' into fax of '%s'\n", ast->name, ast->context);
02796                } else
02797                   ast_log(LOG_NOTICE, "Fax detected, but no fax extension ctx:%s exten:%s\n",ast->context, ast->exten);
02798             } else
02799                ast_log(LOG_DEBUG, "Already in a fax extension, not redirecting\n");
02800          } else
02801             ast_log(LOG_DEBUG, "Fax already handled\n");
02802          
02803       }  else if ( tmp->ast_dsp) {
02804          chan_misdn_log(2, tmp->bc->port, " --> * SEND: DTMF (AST_DSP) :%c\n",f->subclass);
02805          return f;
02806       }
02807    }
02808 
02809    frame->frametype = AST_FRAME_NULL;
02810    frame->subclass = 0;
02811    return frame;
02812 }

static int read_config struct chan_list ch,
int  orig
[static]
 

ORIGINATOR MISDN

Definition at line 1377 of file chan_misdn.c.

References chan_list::allowed_bearers, chan_list::ast, ast_log(), ast_print_group(), ast_set_callerid(), ast_strlen_zero(), chan_list::bc, ast_channel::callgroup, chan_misdn_log(), ast_channel::cid, ast_callerid::cid_rdnis, config_jitterbuffer(), ast_channel::context, chan_list::context, debug_numplan(), ast_channel::exten, chan_list::far_alerting, chan_list::incoming_early_audio, chan_list::jb_len, chan_list::jb_upper_threshold, ast_channel::language, LOG_WARNING, misdn_cfg_get(), ast_channel::musicclass, musicclass, ORG_AST, ast_channel::pickupgroup, strdup, and update_ec_config().

Referenced by cb_events().

01377                                                        {
01378 
01379    if (!ch) {
01380       ast_log(LOG_WARNING, "Cannot configure without chanlist\n");
01381       return -1;
01382    }
01383 
01384    struct ast_channel *ast=ch->ast;
01385    struct misdn_bchannel *bc=ch->bc;
01386    if (! ast || ! bc ) {
01387       ast_log(LOG_WARNING, "Cannot configure without ast || bc\n");
01388       return -1;
01389    }
01390    
01391    int port=bc->port;
01392    
01393    chan_misdn_log(5,port,"read_config: Getting Config\n");
01394    
01395    char lang[BUFFERSIZE+1];
01396 
01397    misdn_cfg_get( port, MISDN_CFG_LANGUAGE, lang, BUFFERSIZE);
01398    ast_copy_string(ast->language, lang, sizeof(ast->language));
01399    
01400    char musicclass[BUFFERSIZE+1];
01401    
01402    misdn_cfg_get( port, MISDN_CFG_MUSICCLASS, musicclass, BUFFERSIZE);
01403    ast_copy_string(ast->musicclass, musicclass, sizeof(ast->musicclass));
01404    
01405    misdn_cfg_get( port, MISDN_CFG_TXGAIN, &bc->txgain, sizeof(int));
01406    misdn_cfg_get( port, MISDN_CFG_RXGAIN, &bc->rxgain, sizeof(int));
01407    
01408    misdn_cfg_get( port, MISDN_CFG_INCOMING_EARLY_AUDIO, &ch->incoming_early_audio, sizeof(int));
01409    
01410    misdn_cfg_get( port, MISDN_CFG_SENDDTMF, &bc->send_dtmf, sizeof(int));
01411 
01412    misdn_cfg_get( port, MISDN_CFG_NEED_MORE_INFOS, &bc->need_more_infos, sizeof(int));
01413    
01414    misdn_cfg_get( port, MISDN_CFG_FAR_ALERTING, &ch->far_alerting, sizeof(int));
01415 
01416    misdn_cfg_get( port, MISDN_CFG_ALLOWED_BEARERS, &ch->allowed_bearers, BUFFERSIZE);
01417    
01418    
01419    int hdlc=0;
01420    misdn_cfg_get( port, MISDN_CFG_HDLC, &hdlc, sizeof(int));
01421    
01422    if (hdlc) {
01423       switch (bc->capability) {
01424       case INFO_CAPABILITY_DIGITAL_UNRESTRICTED:
01425       case INFO_CAPABILITY_DIGITAL_RESTRICTED:
01426          chan_misdn_log(1,bc->port," --> CONF HDLC\n");
01427          bc->hdlc=1;
01428          break;
01429       }
01430       
01431    }
01432    /*Initialize new Jitterbuffer*/
01433    {
01434       misdn_cfg_get( port, MISDN_CFG_JITTERBUFFER, &ch->jb_len, sizeof(int));
01435       misdn_cfg_get( port, MISDN_CFG_JITTERBUFFER_UPPER_THRESHOLD, &ch->jb_upper_threshold, sizeof(int));
01436       
01437       config_jitterbuffer(ch);
01438    }
01439    
01440    misdn_cfg_get( bc->port, MISDN_CFG_CONTEXT, ch->context, sizeof(ch->context));
01441    
01442    ast_copy_string (ast->context,ch->context,sizeof(ast->context));  
01443 
01444    update_ec_config(bc);
01445 
01446    {
01447       int eb3;
01448       
01449       misdn_cfg_get( bc->port, MISDN_CFG_EARLY_BCONNECT, &eb3, sizeof(int));
01450       bc->early_bconnect=eb3;
01451    }
01452    
01453    port=bc->port;
01454    
01455    {
01456       char buf[256];
01457       ast_group_t pg,cg;
01458       
01459       misdn_cfg_get(port, MISDN_CFG_PICKUPGROUP, &pg, sizeof(pg));
01460       misdn_cfg_get(port, MISDN_CFG_CALLGROUP, &cg, sizeof(cg));
01461       
01462       chan_misdn_log(5, port, " --> * CallGrp:%s PickupGrp:%s\n",ast_print_group(buf,sizeof(buf),cg),ast_print_group(buf,sizeof(buf),pg));
01463       ast->pickupgroup=pg;
01464       ast->callgroup=cg;
01465    }
01466    
01467    if ( orig  == ORG_AST) {
01468       misdn_cfg_get( port, MISDN_CFG_TE_CHOOSE_CHANNEL, &(bc->te_choose_channel), sizeof(int));
01469       
01470       {
01471          char callerid[BUFFERSIZE+1];
01472          misdn_cfg_get( port, MISDN_CFG_CALLERID, callerid, BUFFERSIZE);
01473          if ( ! ast_strlen_zero(callerid) ) {
01474             chan_misdn_log(1, port, " --> * Setting Cid to %s\n", callerid);
01475             {
01476                int l = sizeof(bc->oad);
01477                strncpy(bc->oad,callerid, l);
01478                bc->oad[l-1] = 0;
01479             }
01480 
01481          }
01482 
01483          
01484          misdn_cfg_get( port, MISDN_CFG_DIALPLAN, &bc->dnumplan, sizeof(int));
01485          misdn_cfg_get( port, MISDN_CFG_LOCALDIALPLAN, &bc->onumplan, sizeof(int));
01486          misdn_cfg_get( port, MISDN_CFG_CPNDIALPLAN, &bc->cpnnumplan, sizeof(int));
01487          debug_numplan(port, bc->dnumplan,"TON");
01488          debug_numplan(port, bc->onumplan,"LTON");
01489          debug_numplan(port, bc->cpnnumplan,"CTON");
01490       }
01491 
01492       
01493       
01494    } else { /** ORIGINATOR MISDN **/
01495    
01496       misdn_cfg_get( port, MISDN_CFG_CPNDIALPLAN, &bc->cpnnumplan, sizeof(int));
01497       debug_numplan(port, bc->cpnnumplan,"CTON");
01498       
01499       char prefix[BUFFERSIZE+1]="";
01500       switch( bc->onumplan ) {
01501       case NUMPLAN_INTERNATIONAL:
01502          misdn_cfg_get( bc->port, MISDN_CFG_INTERNATPREFIX, prefix, BUFFERSIZE);
01503          break;
01504          
01505       case NUMPLAN_NATIONAL:
01506          misdn_cfg_get( bc->port, MISDN_CFG_NATPREFIX, prefix, BUFFERSIZE);
01507          break;
01508       default:
01509          break;
01510       }
01511       
01512       {
01513          int l = strlen(prefix) + strlen(bc->oad);
01514          char tmp[l+1];
01515          strcpy(tmp,prefix);
01516          strcat(tmp,bc->oad);
01517          strcpy(bc->oad,tmp);
01518       }
01519       
01520       if (!ast_strlen_zero(bc->dad)) {
01521          ast_copy_string(bc->orig_dad,bc->dad, sizeof(bc->orig_dad));
01522       }
01523       
01524       if ( ast_strlen_zero(bc->dad) && !ast_strlen_zero(bc->keypad)) {
01525          ast_copy_string(bc->dad,bc->keypad, sizeof(bc->dad));
01526       }
01527 
01528       prefix[0] = 0;
01529       
01530       switch( bc->dnumplan ) {
01531       case NUMPLAN_INTERNATIONAL:
01532          misdn_cfg_get( bc->port, MISDN_CFG_INTERNATPREFIX, prefix, BUFFERSIZE);
01533          break;
01534       case NUMPLAN_NATIONAL:
01535          misdn_cfg_get( bc->port, MISDN_CFG_NATPREFIX, prefix, BUFFERSIZE);
01536          break;
01537       default:
01538          break;
01539       }
01540       
01541       {
01542          int l = strlen(prefix) + strlen(bc->dad);
01543          char tmp[l+1];
01544          strcpy(tmp,prefix);
01545          strcat(tmp,bc->dad);
01546          strcpy(bc->dad,tmp);
01547       }
01548       
01549       if ( strcmp(bc->dad,ast->exten)) {
01550          ast_copy_string(ast->exten, bc->dad, sizeof(ast->exten));
01551       }
01552       
01553       ast_set_callerid(ast, bc->oad, NULL, bc->oad);
01554       
01555       if ( !ast_strlen_zero(bc->rad) ) 
01556          ast->cid.cid_rdnis=strdup(bc->rad);
01557       
01558    } /* ORIG MISDN END */
01559    
01560    return 0;
01561 }

static void release_chan struct misdn_bchannel *  bc  )  [static]
 

Isdn asks us to release channel, pendant to misdn_hangup

Definition at line 2975 of file chan_misdn.c.

References ast_channel::_state, chan_list::ast, AST_CID_P, ast_setstate(), AST_STATE_DOWN, AST_STATE_RESERVED, chan_misdn_log(), cl_dequeue_chan(), cl_te, ast_channel::context, ast_channel::exten, find_chan_by_bc(), free, chan_list::jb, MISDN_ASTERISK_TECH_PVT, MISDN_CLEANING, misdn_get_ch_state(), misdn_jb_destroy(), chan_list::pipe, and chan_list::state.

02975                                                     {
02976    struct ast_channel *ast=NULL;
02977    {
02978       struct chan_list *ch=find_chan_by_bc(cl_te, bc);
02979       if (!ch)  {
02980          chan_misdn_log(1, bc->port, "release_chan: Ch not found!\n");
02981          return;
02982       }
02983       
02984       if (ch->ast) {
02985          ast=ch->ast;
02986       } 
02987       
02988       chan_misdn_log(1, bc->port, "release_chan: bc with l3id: %x\n",bc->l3_id);
02989       
02990       /*releaseing jitterbuffer*/
02991       if (ch->jb ) {
02992          misdn_jb_destroy(ch->jb);
02993          ch->jb=NULL;
02994       } else {
02995          if (!bc->nojitter)
02996             chan_misdn_log(5,bc->port,"Jitterbuffer already destroyed.\n");
02997       }
02998       
02999       if (ch) {
03000          
03001          close(ch->pipe[0]);
03002          close(ch->pipe[1]);
03003 
03004          
03005          if (ast && MISDN_ASTERISK_TECH_PVT(ast)) {
03006             chan_misdn_log(1, bc->port, "* RELEASING CHANNEL pid:%d ctx:%s dad:%s oad:%s state: %s\n",bc?bc->pid:-1, ast->context, ast->exten,AST_CID_P(ast),misdn_get_ch_state(ch));
03007             chan_misdn_log(3, bc->port, " --> * State Down\n");
03008             MISDN_ASTERISK_TECH_PVT(ast)=NULL;
03009             
03010       
03011             if (ast->_state != AST_STATE_RESERVED) {
03012                chan_misdn_log(3, bc->port, " --> Setting AST State to down\n");
03013                ast_setstate(ast, AST_STATE_DOWN);
03014             }
03015          }
03016             
03017          ch->state=MISDN_CLEANING;
03018          cl_dequeue_chan(&cl_te, ch);
03019          
03020          free(ch);
03021       } else {
03022          /* chan is already cleaned, so exiting  */
03023       }
03024    }
03025 }

int reload void   ) 
 

Reload stuff.

This function is where any reload routines take place. Re-read config files, change signalling, whatever is appropriate on a reload.

Returns:
The return value is not used.

Definition at line 4268 of file chan_misdn.c.

References reload_config().

04269 {
04270    reload_config();
04271 
04272    return 0;
04273 }

static void reload_config void   )  [static]
 

Definition at line 706 of file chan_misdn.c.

References free_robin_list(), global_tracefile, max_ports, misdn_cfg_get(), misdn_cfg_reload(), misdn_cfg_update_ptp(), misdn_debug, and misdn_debug_only.

00707 {
00708    int i, cfg_debug;
00709    
00710    free_robin_list();
00711    misdn_cfg_reload();
00712    misdn_cfg_update_ptp();
00713    misdn_cfg_get( 0, MISDN_GEN_TRACEFILE, global_tracefile, BUFFERSIZE);
00714    misdn_cfg_get( 0, MISDN_GEN_DEBUG, &cfg_debug, sizeof(int));
00715 
00716    for (i = 0;  i <= max_ports; i++) {
00717       misdn_debug[i] = cfg_debug;
00718       misdn_debug_only[i] = 0;
00719    }
00720 }

static void send_cause2ast struct ast_channel ast,
struct misdn_bchannel *  bc,
struct chan_list ch
[static]
 

Congestion Cases

Definition at line 3106 of file chan_misdn.c.

References AST_CONTROL_BUSY, ast_queue_control(), chan_misdn_log(), ast_channel::hangupcause, MISDN_BUSY, chan_list::need_busy, and chan_list::state.

Referenced by hangup_chan().

03106                                                                                                     {
03107    if (!ast) {
03108       chan_misdn_log(1,0,"send_cause2ast: No Ast\n");
03109       return;
03110    }
03111    if (!bc) {
03112       chan_misdn_log(1,0,"send_cause2ast: No BC\n");
03113       return;
03114    }
03115    if (!ch) {
03116       chan_misdn_log(1,0,"send_cause2ast: No Ch\n");
03117       return;
03118    }
03119    
03120    ast->hangupcause=bc->cause;
03121    
03122    switch ( bc->cause) {
03123       
03124    case 1: /** Congestion Cases **/
03125    case 2:
03126    case 3:
03127    case 4:
03128    case 22:
03129    case 27:
03130       /*
03131        * Not Queueing the Congestion anymore, since we want to hear
03132        * the inband message
03133        *
03134       chan_misdn_log(1, bc?bc->port:0, " --> * SEND: Queue Congestion pid:%d\n", bc?bc->pid:-1);
03135       ch->state=MISDN_BUSY;
03136       
03137       ast_queue_control(ast, AST_CONTROL_CONGESTION);
03138       */
03139       break;
03140       
03141    case 21:
03142    case 17: /* user busy */
03143    
03144       ch->state=MISDN_BUSY;
03145          
03146       if (!ch->need_busy) {
03147          chan_misdn_log(1,bc?bc->port:0, "Queued busy already\n");
03148          break;
03149       }
03150       
03151       chan_misdn_log(1,  bc?bc->port:0, " --> * SEND: Queue Busy pid:%d\n", bc?bc->pid:-1);
03152       
03153       ast_queue_control(ast, AST_CONTROL_BUSY);
03154       
03155       ch->need_busy=0;
03156       
03157       break;
03158    }
03159 }

static void send_digit_to_chan struct chan_list cl,
char  digit
[static]
 

Definition at line 433 of file chan_misdn.c.

References chan_list::ast, ast_log(), ast_playtones_start(), LOG_DEBUG, and ast_channel::name.

Referenced by misdn_digit(), and misdn_send_digit().

00434 {
00435    static const char* dtmf_tones[] = {
00436       "!941+1336/100,!0/100", /* 0 */
00437       "!697+1209/100,!0/100", /* 1 */
00438       "!697+1336/100,!0/100", /* 2 */
00439       "!697+1477/100,!0/100", /* 3 */
00440       "!770+1209/100,!0/100", /* 4 */
00441       "!770+1336/100,!0/100", /* 5 */
00442       "!770+1477/100,!0/100", /* 6 */
00443       "!852+1209/100,!0/100", /* 7 */
00444       "!852+1336/100,!0/100", /* 8 */
00445       "!852+1477/100,!0/100", /* 9 */
00446       "!697+1633/100,!0/100", /* A */
00447       "!770+1633/100,!0/100", /* B */
00448       "!852+1633/100,!0/100", /* C */
00449       "!941+1633/100,!0/100", /* D */
00450       "!941+1209/100,!0/100", /* * */
00451       "!941+1477/100,!0/100" };  /* # */
00452    struct ast_channel *chan=cl->ast; 
00453   
00454    if (digit >= '0' && digit <='9')
00455       ast_playtones_start(chan,0,dtmf_tones[digit-'0'], 0);
00456    else if (digit >= 'A' && digit <= 'D')
00457       ast_playtones_start(chan,0,dtmf_tones[digit-'A'+10], 0);
00458    else if (digit == '*')
00459       ast_playtones_start(chan,0,dtmf_tones[14], 0);
00460    else if (digit == '#')
00461       ast_playtones_start(chan,0,dtmf_tones[15], 0);
00462    else {
00463       /* not handled */
00464       ast_log(LOG_DEBUG, "Unable to handle DTMF tone '%c' for '%s'\n", digit, chan->name);
00465     
00466     
00467    }
00468 }

static int start_bc_tones struct chan_list cl  )  [static]
 

Definition at line 2430 of file chan_misdn.c.

References chan_list::bc, chan_list::norxtone, and chan_list::notxtone.

Referenced by misdn_answer(), misdn_hangup(), and misdn_indication().

02431 {
02432    misdn_lib_tone_generator_stop(cl->bc);
02433    cl->notxtone=0;
02434    cl->norxtone=0;
02435    return 0;
02436 }

static int stop_bc_tones struct chan_list cl  )  [static]
 

Definition at line 2438 of file chan_misdn.c.

References chan_list::norxtone, and chan_list::notxtone.

Referenced by misdn_call(), and misdn_hangup().

02439 {
02440    if (!cl) return -1;
02441 
02442    cl->notxtone=1;
02443    cl->norxtone=1;
02444    
02445    return 0;
02446 }

static int stop_indicate struct chan_list cl  )  [static]
 

Definition at line 2418 of file chan_misdn.c.

References chan_list::ast, ast_playtones_stop(), chan_list::bc, and chan_misdn_log().

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

02419 {
02420    struct ast_channel *ast=cl->ast;
02421    chan_misdn_log(3,cl->bc->port," --> None\n");
02422    misdn_lib_tone_generator_stop(cl->bc);
02423    ast_playtones_stop(ast);
02424    /*ast_deactivate_generator(ast);*/
02425    
02426    return 0;
02427 }

int unload_module void   ) 
 

Cleanup all module structures, sockets, etc.

This is called at exit. Any registrations and memory allocations need to be unregistered and free'd here. Nothing else will do these for you (until exit).

Returns:
Zero on success, or non-zero on error.

Definition at line 4221 of file chan_misdn.c.

References ast_channel_unregister(), ast_cli_unregister(), ast_log(), ast_unregister_application(), cli_port_block, cli_port_down, cli_port_unblock, cli_port_up, cli_reload, cli_restart_port, cli_send_cd, cli_send_digit, cli_send_display, cli_set_crypt_debug, cli_set_debug, cli_set_tics, cli_show_cl, cli_show_cls, cli_show_config, cli_show_port, cli_show_stacks, cli_toggle_echocancel, free, free_robin_list(), LOG_VERBOSE, misdn_cfg_destroy(), misdn_debug, misdn_debug_only, and misdn_tech.

04222 {
04223    /* First, take us out of the channel loop */
04224    ast_log(LOG_VERBOSE, "-- Unregistering mISDN Channel Driver --\n");
04225    
04226    if (!g_config_initialized) return 0;
04227    
04228    ast_cli_unregister(&cli_send_display);
04229    
04230    ast_cli_unregister(&cli_send_cd);
04231    
04232    ast_cli_unregister(&cli_send_digit);
04233    ast_cli_unregister(&cli_toggle_echocancel);
04234    ast_cli_unregister(&cli_set_tics);
04235   
04236    ast_cli_unregister(&cli_show_cls);
04237    ast_cli_unregister(&cli_show_cl);
04238    ast_cli_unregister(&cli_show_config);
04239    ast_cli_unregister(&cli_show_port);
04240    ast_cli_unregister(&cli_show_stacks);
04241    ast_cli_unregister(&cli_port_block);
04242    ast_cli_unregister(&cli_port_unblock);
04243    ast_cli_unregister(&cli_restart_port);
04244    ast_cli_unregister(&cli_port_up);
04245    ast_cli_unregister(&cli_port_down);
04246    ast_cli_unregister(&cli_set_debug);
04247    ast_cli_unregister(&cli_set_crypt_debug);
04248    ast_cli_unregister(&cli_reload);
04249    /* ast_unregister_application("misdn_crypt"); */
04250    ast_unregister_application("misdn_set_opt");
04251    ast_unregister_application("misdn_facility");
04252   
04253    ast_channel_unregister(&misdn_tech);
04254 
04255 
04256    free_robin_list();
04257    misdn_cfg_destroy();
04258    misdn_lib_destroy();
04259   
04260    if (misdn_debug)
04261       free(misdn_debug);
04262    if (misdn_debug_only)
04263       free(misdn_debug_only);
04264    
04265    return 0;
04266 }

static int update_config struct chan_list ch,
int  orig
[static]
 

Definition at line 1198 of file chan_misdn.c.

References chan_list::ast, ast_log(), 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, chan_list::bc, chan_misdn_log(), ast_channel::cid, ast_callerid::cid_pres, LOG_WARNING, and misdn_cfg_get().

Referenced by misdn_call().

01199 {
01200    if (!ch) {
01201       ast_log(LOG_WARNING, "Cannot configure without chanlist\n");
01202       return -1;
01203    }
01204    
01205    struct ast_channel *ast=ch->ast;
01206    struct misdn_bchannel *bc=ch->bc;
01207    if (! ast || ! bc ) {
01208       ast_log(LOG_WARNING, "Cannot configure without ast || bc\n");
01209       return -1;
01210    }
01211    
01212    int port=bc->port;
01213    
01214    chan_misdn_log(1,port,"update_config: Getting Config\n");
01215 
01216 
01217    int hdlc=0;
01218    misdn_cfg_get( port, MISDN_CFG_HDLC, &hdlc, sizeof(int));
01219    
01220    if (hdlc) {
01221       switch (bc->capability) {
01222       case INFO_CAPABILITY_DIGITAL_UNRESTRICTED:
01223       case INFO_CAPABILITY_DIGITAL_RESTRICTED:
01224          chan_misdn_log(1,bc->port," --> CONF HDLC\n");
01225          bc->hdlc=1;
01226          break;
01227       }
01228       
01229    }
01230    
01231    
01232    int pres, screen;
01233          
01234    misdn_cfg_get( port, MISDN_CFG_PRES, &pres, sizeof(int));
01235    misdn_cfg_get( port, MISDN_CFG_SCREEN, &screen, sizeof(int));
01236    chan_misdn_log(2,port," --> pres: %d screen: %d\n",pres, screen);
01237       
01238    if ( (pres + screen) < 0 ) {
01239 
01240       chan_misdn_log(2,port," --> pres: %x\n", ast->cid.cid_pres);
01241          
01242       switch (ast->cid.cid_pres & 0x60){
01243             
01244       case AST_PRES_RESTRICTED:
01245          bc->pres=1;
01246          chan_misdn_log(2, port, " --> PRES: Restricted (0x1)\n");
01247          break;
01248             
01249             
01250       case AST_PRES_UNAVAILABLE:
01251          bc->pres=2;
01252          chan_misdn_log(2, port, " --> PRES: Unavailable (0x2)\n");
01253          break;
01254             
01255       default:
01256          bc->pres=0;
01257          chan_misdn_log(2, port, " --> PRES: Allowed (0x0)\n");
01258       }
01259          
01260       switch (ast->cid.cid_pres & 0x3){
01261             
01262       case AST_PRES_USER_NUMBER_UNSCREENED:
01263          bc->screen=0;
01264          chan_misdn_log(2, port, " --> SCREEN: Unscreened (0x0)\n");
01265          break;
01266 
01267       case AST_PRES_USER_NUMBER_PASSED_SCREEN:
01268          bc->screen=1;
01269          chan_misdn_log(2, port, " --> SCREEN: Passed Screen (0x1)\n");
01270          break;
01271       case AST_PRES_USER_NUMBER_FAILED_SCREEN:
01272          bc->screen=2;
01273          chan_misdn_log(2, port, " --> SCREEN: Failed Screen (0x2)\n");
01274          break;
01275             
01276       case AST_PRES_NETWORK_NUMBER:
01277          bc->screen=3;
01278          chan_misdn_log(2, port, " --> SCREEN: Network Nr. (0x3)\n");
01279          break;
01280             
01281       default:
01282          bc->screen=0;
01283          chan_misdn_log(2, port, " --> SCREEN: Unscreened (0x0)\n");
01284       }
01285 
01286          
01287    } else {
01288       bc->screen=screen;
01289       bc->pres=pres;
01290    }
01291 
01292    return 0;
01293    
01294 }

static int update_ec_config struct misdn_bchannel *  bc  )  [static]
 

Definition at line 1359 of file chan_misdn.c.

References misdn_cfg_get().

Referenced by misdn_toggle_echocancel(), and read_config().

01360 {
01361    int ec;
01362    int port=bc->port;
01363       
01364    misdn_cfg_get( port, MISDN_CFG_ECHOCANCEL, &ec, sizeof(int));
01365    
01366    if (ec == 1 ) {
01367       bc->ec_enable=1;
01368    } else if ( ec > 1 ) {
01369       bc->ec_enable=1;
01370       bc->ec_deftaps=ec;
01371    }
01372 
01373    return 0;
01374 }

int usecount void   ) 
 

Provides a usecount.

This function will be called by various parts of asterisk. Basically, all it has to do is to return a usecount when called. You will need to maintain your usecount within the module somewhere. The usecount should be how many channels provided by this module are in use.

Returns:
The module's usecount.

Definition at line 4275 of file chan_misdn.c.

References ast_mutex_lock(), ast_mutex_unlock(), usecnt, and usecnt_lock.

04276 {
04277    int res;
04278    ast_mutex_lock(&usecnt_lock);
04279    res = usecnt;
04280    ast_mutex_unlock(&usecnt_lock);
04281    return res;
04282 }


Variable Documentation

struct allowed_bearers allowed_bearers_array[]
 

Definition at line 359 of file chan_misdn.c.

Referenced by cb_events().

struct chan_list* cl_te = NULL
 

Definition at line 297 of file chan_misdn.c.

Referenced by cb_events(), chan_misdn_jb_empty(), get_chan_by_ast(), get_chan_by_ast_name(), import_ch(), misdn_hangup(), misdn_show_cl(), misdn_show_cls(), and release_chan().

ast_mutex_t cl_te_lock
 

Definition at line 298 of file chan_misdn.c.

Referenced by cl_dequeue_chan(), cl_queue_chan(), and load_module().

struct ast_cli_entry cli_port_block [static]
 

Definition at line 1129 of file chan_misdn.c.

Referenced by load_module(), and unload_module().

struct ast_cli_entry cli_port_down [static]
 

Definition at line 1158 of file chan_misdn.c.

Referenced by load_module(), and unload_module().

struct ast_cli_entry cli_port_unblock [static]
 

Definition at line 1136 of file chan_misdn.c.

Referenced by load_module(), and unload_module().

struct ast_cli_entry cli_port_up [static]
 

Definition at line 1151 of file chan_misdn.c.

Referenced by load_module(), and unload_module().

struct ast_cli_entry cli_reload [static]
 

Definition at line 1100 of file chan_misdn.c.

struct ast_cli_entry cli_restart_port [static]
 

Definition at line 1144 of file chan_misdn.c.

Referenced by load_module(), and unload_module().

struct ast_cli_entry cli_send_cd [static]
 

Definition at line 1057 of file chan_misdn.c.

Referenced by load_module(), and unload_module().

struct ast_cli_entry cli_send_digit [static]
 

Definition at line 1065 of file chan_misdn.c.

Referenced by load_module(), and unload_module().

struct ast_cli_entry cli_send_display [static]
 

Definition at line 1083 of file chan_misdn.c.

Referenced by load_module(), and unload_module().

struct ast_cli_entry cli_set_crypt_debug [static]
 

Definition at line 1189 of file chan_misdn.c.

Referenced by load_module(), and unload_module().

struct ast_cli_entry cli_set_debug [static]
 

Definition at line 1181 of file chan_misdn.c.

Referenced by load_module(), and unload_module().

struct ast_cli_entry cli_set_tics [static]
 

Definition at line 1107 of file chan_misdn.c.

Referenced by load_module(), and unload_module().

struct ast_cli_entry cli_show_cl [static]
 

Definition at line 1121 of file chan_misdn.c.

Referenced by load_module(), and unload_module().

struct ast_cli_entry cli_show_cls [static]
 

Definition at line 1114 of file chan_misdn.c.

Referenced by load_module(), and unload_module().

struct ast_cli_entry cli_show_config [static]
 

Definition at line 1093 of file chan_misdn.c.

Referenced by load_module(), and unload_module().

struct ast_cli_entry cli_show_port [static]
 

Definition at line 1174 of file chan_misdn.c.

Referenced by load_module(), and unload_module().

struct ast_cli_entry cli_show_stacks [static]
 

Definition at line 1167 of file chan_misdn.c.

Referenced by load_module(), and unload_module().

struct ast_cli_entry cli_toggle_echocancel [static]
 

Definition at line 1075 of file chan_misdn.c.

Referenced by load_module(), and unload_module().

char* desc = "Channel driver for mISDN Support (Bri/Pri)" [static]
 

Definition at line 276 of file chan_misdn.c.

struct chan_list dummy_cl
 

Definition at line 295 of file chan_misdn.c.

int g_config_initialized = 0 [static]
 

TE STUFF END

Definition at line 4094 of file chan_misdn.c.

unsigned long glob_channel = 0 [static]
 

Definition at line 2688 of file chan_misdn.c.

char global_tracefile[BUFFERSIZE+1]
 

Definition at line 65 of file chan_misdn.c.

Referenced by chan_misdn_log(), load_module(), and reload_config().

ast_mutex_t lock
 

Definition at line 831 of file chan_misdn.c.

Referenced by ast_waitfor_nandfds(), load_config(), load_module(), mkbrd(), rpt_master(), unload_module(), zap_show_channel(), zap_show_channels(), and zt_request().

int max_ports [static]
 

Definition at line 293 of file chan_misdn.c.

Referenced by _build_port_config(), _free_port_cfg(), chan_misdn_log(), load_module(), misdn_cfg_get_next_port(), misdn_cfg_get_ports_string(), misdn_cfg_init(), misdn_cfg_is_group_method(), misdn_cfg_is_port_valid(), misdn_set_debug(), and reload_config().

int MAXTICS = 8
 

Definition at line 832 of file chan_misdn.c.

int* misdn_debug [static]
 

Definition at line 291 of file chan_misdn.c.

Referenced by chan_misdn_log(), load_module(), misdn_set_debug(), misdn_show_cls(), misdn_show_port(), misdn_show_stacks(), print_bc_info(), reload_config(), and unload_module().

int* misdn_debug_only [static]
 

Definition at line 292 of file chan_misdn.c.

Referenced by chan_misdn_log(), load_module(), misdn_set_debug(), misdn_show_port(), misdn_show_stacks(), reload_config(), and unload_module().

char** misdn_key_vector = NULL [static]
 

Definition at line 283 of file chan_misdn.c.

Referenced by misdn_set_opt_exec().

int misdn_key_vector_size = 0 [static]
 

Definition at line 284 of file chan_misdn.c.

Referenced by misdn_set_opt_exec().

struct ast_channel_tech misdn_tech [static]
 

Definition at line 2652 of file chan_misdn.c.

Referenced by load_module(), misdn_new(), and unload_module().

struct ast_channel_tech misdn_tech_wo_bridge [static]
 

Definition at line 2670 of file chan_misdn.c.

Referenced by misdn_new().

const char misdn_type[] = "mISDN" [static]
 

Definition at line 277 of file chan_misdn.c.

Referenced by load_module(), misdn_new(), and misdn_request().

int prefformat = AST_FORMAT_ALAW [static]
 

Definition at line 287 of file chan_misdn.c.

Referenced by misdn_new(), and misdn_write().

struct robin_list* robin = NULL [static]
 

Definition at line 216 of file chan_misdn.c.

Referenced by free_robin_list(), and get_robin_position().

struct state_struct state_array[] [static]
 

Definition at line 663 of file chan_misdn.c.

Referenced by misdn_get_ch_state().

int tracing = 0 [static]
 

Definition at line 279 of file chan_misdn.c.

Referenced by load_module().

int usecnt = 0 [static]
 

Definition at line 281 of file chan_misdn.c.

ast_mutex_t usecnt_lock [static]
 

Definition at line 289 of file chan_misdn.c.

Referenced by __oh323_new(), agent_hangup(), agent_new(), alsa_hangup(), alsa_new(), aopen_decusecnt(), aopen_incusecnt(), ast_iax2_new(), ast_modem_new(), bestdata_decusecnt(), bestdata_incusecnt(), i4l_decusecnt(), i4l_incusecnt(), iax2_predestroy(), local_hangup(), local_new(), mgcp_hangup(), mgcp_new(), modem_hangup(), nbs_new(), oh323_hangup(), oss_hangup(), oss_new(), phone_check_exception(), phone_hangup(), phone_new(), sip_hangup(), sip_new(), skinny_new(), usecount(), vpb_hangup(), vpb_new(), zt_hangup(), and zt_new().


Generated on Sat Nov 25 00:45:54 2006 for Asterisk - the Open Source PBX by  doxygen 1.4.6