Sat Sep 16 07:28:14 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  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, MISDN_WAITING4DIGS, MISDN_EXTCANTMATCH, MISDN_DIALING,
  MISDN_PROGRESS, MISDN_PROCEEDING, MISDN_CALLING, MISDN_CALLING_ACKNOWLEDGE,
  MISDN_ALERTING, MISDN_BUSY, MISDN_CONNECTED, MISDN_PRECONNECTED,
  MISDN_DISCONNECTED, MISDN_RELEASED, MISDN_BRIDGED, MISDN_CLEANING,
  MISDN_HUNGUP_FROM_MISDN, MISDN_HUNGUP_FROM_AST, MISDN_HOLDED, MISDN_HOLD_DISCONNECT
}

Functions

static 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 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)
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)
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.
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 258 of file chan_misdn.c.

Referenced by misdn_transfer_bc().

#define AST_CID_P ( ast   )     ast->cid.cid_num

Definition at line 257 of file chan_misdn.c.

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

#define AST_DESTROY_CFG   ast_config_destroy

Definition at line 260 of file chan_misdn.c.

Referenced by misdn_cfg_init().

#define AST_LOAD_CFG   ast_config_load

Definition at line 259 of file chan_misdn.c.

Referenced by misdn_cfg_init().

#define MISDN_ASTERISK_PVT ( ast   )     1

Definition at line 263 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 262 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 129 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 130 of file chan_misdn.c.

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


Enumeration Type Documentation

enum misdn_chan_state

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

Definition at line 104 of file chan_misdn.c.

00104                       {
00105    MISDN_NOTHING,    /*!< 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   
00127 };


Function Documentation

static char* bearer2str ( int  cap  )  [static]

Definition at line 360 of file chan_misdn.c.

Referenced by print_bc_info(), and print_bearer().

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

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

Definition at line 3145 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, dialtone_indicate(), do_immediate_setup(), 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().

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

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

Definition at line 4463 of file chan_misdn.c.

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

Referenced by load_module().

04464 {
04465    struct chan_list *ch=find_chan_by_bc(cl_te, bc);
04466    
04467    if (ch && ch->jb) {
04468       return misdn_jb_empty(ch->jb, buf, len);
04469    }
04470    
04471    return -1;
04472 }

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

Definition at line 4648 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_chan_by_bc(), find_chan_by_pid(), 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_empty(), misdn_jb_fill(), misdn_jb_init(), misdn_new(), misdn_read(), misdn_request(), misdn_set_opt_exec(), misdn_show_cls(), misdn_transfer_bc(), misdn_write(), print_bearer(), print_facility(), process_ast_dsp(), read_config(), release_chan(), send_cause2ast(), stop_indicate(), and update_config().

04649 {
04650    if (! ((0 <= port) && (port <= max_ports))) {
04651       ast_log(LOG_WARNING, "cb_log called with out-of-range port number! (%d)\n", port);
04652       port=0;
04653       level=-1;
04654    }
04655       
04656    va_list ap;
04657    char buf[1024];
04658    char port_buf[8];
04659    sprintf(port_buf,"P[%2d] ",port);
04660    
04661    va_start(ap, tmpl);
04662    vsnprintf( buf, 1023, tmpl, ap );
04663    va_end(ap);
04664 
04665    if (level == -1)
04666       ast_log(LOG_WARNING, buf);
04667 
04668    else if (misdn_debug_only[port] ? 
04669          (level==1 && misdn_debug[port]) || (level==misdn_debug[port]) 
04670        : level <= misdn_debug[port]) {
04671       
04672       ast_console_puts(port_buf);
04673       ast_console_puts(buf);
04674    }
04675    
04676    if ((level <= misdn_debug[0]) && !ast_strlen_zero(global_tracefile) ) {
04677       time_t tm = time(NULL);
04678       char *tmp=ctime(&tm),*p;
04679       
04680       FILE *fp= fopen(global_tracefile, "a+");
04681       
04682       p=strchr(tmp,'\n');
04683       if (p) *p=':';
04684       
04685       if (!fp) {
04686          ast_console_puts("Error opening Tracefile: [ ");
04687          ast_console_puts(global_tracefile);
04688          ast_console_puts(" ] ");
04689          
04690          ast_console_puts(strerror(errno));
04691          ast_console_puts("\n");
04692          return ;
04693       }
04694       
04695       fputs(tmp,fp);
04696       fputs(" ", fp);
04697       fputs(port_buf,fp);
04698       fputs(" ", fp);
04699       fputs(buf, fp);
04700 
04701       fclose(fp);
04702    }
04703 }

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

Definition at line 2843 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().

02844 {
02845    if (chan->dsp) 
02846       ast_dsp_free(chan->dsp);
02847    if (chan->trans)
02848       ast_translator_free_path(chan->trans);
02849 
02850    
02851 
02852    ast_mutex_lock(&cl_te_lock);
02853    if (!*list) {
02854       ast_mutex_unlock(&cl_te_lock);
02855       return;
02856    }
02857   
02858    if (*list == chan) {
02859       *list=(*list)->next;
02860       ast_mutex_unlock(&cl_te_lock);
02861       return ;
02862    }
02863   
02864    {
02865       struct chan_list *help=*list;
02866       for (;help->next; help=help->next) {
02867          if (help->next == chan) {
02868             help->next=help->next->next;
02869             ast_mutex_unlock(&cl_te_lock);
02870             return;
02871          }
02872       }
02873    }
02874    
02875    ast_mutex_unlock(&cl_te_lock);
02876 }

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

Definition at line 2827 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(), and misdn_request().

02828 {
02829    chan_misdn_log(4, chan->bc? chan->bc->port : 0, "* Queuing chan %p\n",chan);
02830   
02831    ast_mutex_lock(&cl_te_lock);
02832    if (!*list) {
02833       *list = chan;
02834    } else {
02835       struct chan_list *help=*list;
02836       for (;help->next; help=help->next); 
02837       help->next=chan;
02838    }
02839    chan->next=NULL;
02840    ast_mutex_unlock(&cl_te_lock);
02841 }

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

Definition at line 1018 of file chan_misdn.c.

References complete_ch_helper().

01019 {
01020    return complete_ch_helper(line, word, pos, state, 3);
01021 }

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

Definition at line 994 of file chan_misdn.c.

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

00995 {
00996    struct ast_channel *c;
00997    int which=0;
00998    char *ret;
00999    if (pos != rpos)
01000       return NULL;
01001    c = ast_channel_walk_locked(NULL);
01002    while(c) {
01003       if (!strncasecmp(word, c->name, strlen(word))) {
01004          if (++which > state)
01005             break;
01006       }
01007       ast_mutex_unlock(&c->lock);
01008       c = ast_channel_walk_locked(c);
01009    }
01010    if (c) {
01011       ret = strdup(c->name);
01012       ast_mutex_unlock(&c->lock);
01013    } else
01014       ret = NULL;
01015    return ret;
01016 }

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

Definition at line 1023 of file chan_misdn.c.

References strdup.

01024 {
01025    if (state)
01026       return NULL;
01027 
01028    switch (pos) {
01029    case 4: if (*word == 'p')
01030             return strdup("port");
01031          else if (*word == 'o')
01032             return strdup("only");
01033          break;
01034    case 6: if (*word == 'o')
01035             return strdup("only");
01036          break;
01037    }
01038    return NULL;
01039 }

void config_jitterbuffer ( struct chan_list ch  ) 

Definition at line 1283 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 misdn_set_opt_exec(), and read_config().

01284 {
01285    struct misdn_bchannel *bc=ch->bc;
01286    int len=ch->jb_len, threshold=ch->jb_upper_threshold;
01287    
01288    chan_misdn_log(5,bc->port, "config_jb: Called\n");
01289    
01290    if ( ! len ) {
01291       chan_misdn_log(1,bc->port, "config_jb: Deactivating Jitterbuffer\n");
01292       bc->nojitter=1;
01293    } else {
01294       
01295       if (len <=100 || len > 8000) {
01296          chan_misdn_log(0,bc->port,"config_jb: Jitterbuffer out of Bounds, setting to 1000\n");
01297          len=1000;
01298       }
01299       
01300       if ( threshold > len ) {
01301          chan_misdn_log(0,bc->port,"config_jb: Jitterbuffer Threshold > Jitterbuffer setting to Jitterbuffer -1\n");
01302       }
01303       
01304       if ( ch->jb) {
01305          cb_log(0,bc->port,"config_jb: We've got a Jitterbuffer Already on this port.\n");
01306          misdn_jb_destroy(ch->jb);
01307          ch->jb=NULL;
01308       }
01309       
01310       ch->jb=misdn_jb_init(len, threshold);
01311 
01312       if (!ch->jb ) 
01313          bc->nojitter=1;
01314    }
01315 }

void debug_numplan ( int  port,
int  numplan,
char *  type 
)

Definition at line 1318 of file chan_misdn.c.

References chan_misdn_log().

Referenced by read_config().

01319 {
01320    switch (numplan) {
01321    case NUMPLAN_INTERNATIONAL:
01322       chan_misdn_log(2, port, " --> %s: International\n",type);
01323       break;
01324    case NUMPLAN_NATIONAL:
01325       chan_misdn_log(2, port, " --> %s: National\n",type);
01326       break;
01327    case NUMPLAN_SUBSCRIBER:
01328       chan_misdn_log(2, port, " --> %s: Subscriber\n",type);
01329       break;
01330    case NUMPLAN_UNKNOWN:
01331       chan_misdn_log(2, port, " --> %s: Unknown\n",type);
01332       break;
01333       /* Maybe we should cut off the prefix if present ? */
01334    default:
01335       chan_misdn_log(0, port, " --> !!!! Wrong dialplan setting, please see the misdn.conf sample file\n ");
01336       break;
01337    }
01338 }

char* description ( void   ) 

Provides a description of the module.

Returns:
a short description of your module

Definition at line 4218 of file chan_misdn.c.

References desc.

04219 {
04220    return desc;
04221 }

static int dialtone_indicate ( struct chan_list cl  )  [static]

AST INDICATIONS END

Definition at line 2355 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 cb_events(), and do_immediate_setup().

02356 {
02357    const struct tone_zone_sound *ts= NULL;
02358    struct ast_channel *ast=cl->ast;
02359 
02360 
02361    int nd=0;
02362    misdn_cfg_get( cl->bc->port, MISDN_CFG_NODIALTONE, &nd, sizeof(nd));
02363 
02364    if (nd) {
02365       chan_misdn_log(1,cl->bc->port,"Not sending Dialtone, because config wants it\n");
02366       return 0;
02367    }
02368    
02369    chan_misdn_log(3,cl->bc->port," --> Dial\n");
02370    ts=ast_get_indication_tone(ast->zone,"dial");
02371    cl->ts=ts;  
02372    
02373    if (ts) {
02374       cl->notxtone=0;
02375       cl->norxtone=0;
02376       ast_playtones_start(ast,0, ts->data, 0);
02377       chan_misdn_log(4,cl->bc->port,"Starting Playtones\n");
02378       misdn_lib_tone_generator_start(cl->bc);
02379    }
02380 
02381    return 0;
02382 }

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

Definition at line 2997 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, 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.

Referenced by cb_events().

02998 {
02999    char predial[256]="";
03000    char *p = predial;
03001   
03002    struct ast_frame fr;
03003   
03004    strncpy(predial, ast->exten, sizeof(predial) -1 );
03005   
03006    ch->state=MISDN_DIALING;
03007 
03008    if (bc->nt) {
03009       int ret; 
03010       ret = misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE );
03011    } else {
03012       int ret;
03013       if ( misdn_lib_is_ptp(bc->port)) {
03014          ret = misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE );
03015       } else {
03016          ret = misdn_lib_send_event(bc, EVENT_PROCEEDING );
03017       }
03018    }
03019 
03020    if ( !bc->nt && (ch->orginator==ORG_MISDN) && !ch->incoming_early_audio ) 
03021       chan_misdn_log(1,bc->port, " --> incoming_early_audio off\n");
03022     else  
03023       dialtone_indicate(ch);
03024   
03025    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));
03026   
03027    strncpy(ast->exten,"s", 2);
03028   
03029    if (pbx_start_chan(ch)<0) {
03030       ast=NULL;
03031       hangup_chan(ch);
03032       hanguptone_indicate(ch);
03033 
03034       if (bc->nt)
03035          misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE );
03036       else
03037          misdn_lib_send_event(bc, EVENT_DISCONNECT );
03038    }
03039   
03040   
03041    while (!ast_strlen_zero(p) ) {
03042       fr.frametype = AST_FRAME_DTMF;
03043       fr.subclass = *p ;
03044       fr.src=NULL;
03045       fr.data = NULL ;
03046       fr.datalen = 0;
03047       fr.samples = 0 ;
03048       fr.mallocd =0 ;
03049       fr.offset= 0 ;
03050 
03051       if (ch->ast && MISDN_ASTERISK_PVT(ch->ast) && MISDN_ASTERISK_TECH_PVT(ch->ast)) {
03052          ast_queue_frame(ch->ast, &fr);
03053       }
03054       p++;
03055    }
03056 }

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

Definition at line 3130 of file chan_misdn.c.

References chan_misdn_log(), and pbx_builtin_setvar_helper().

Referenced by cb_events().

03131 {
03132    char tmp[32];
03133 
03134    chan_misdn_log(1,bc->port,"EXPORT_PID: pid:%d\n",bc->pid);
03135    sprintf(tmp,"%d",bc->pid);
03136    pbx_builtin_setvar_helper(chan,"_MISDN_PID",tmp);
03137 }

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

Definition at line 2787 of file chan_misdn.c.

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

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

02788 {
02789    struct chan_list *help=list;
02790    for (;help; help=help->next) {
02791       if (help->bc == bc) return help;
02792    }
02793   
02794    chan_misdn_log(6, bc->port, "$$$ find_chan: No channel found for oad:%s dad:%s\n",bc->oad,bc->dad);
02795   
02796    return NULL;
02797 }

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

Definition at line 2799 of file chan_misdn.c.

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

Referenced by import_ch().

02800 {
02801    struct chan_list *help=list;
02802    for (;help; help=help->next) {
02803       if (help->bc->pid == pid) return help;
02804    }
02805   
02806    chan_misdn_log(6, 0, "$$$ find_chan: No channel found for pid:%d\n",pid);
02807   
02808    return NULL;
02809 }

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

Definition at line 2811 of file chan_misdn.c.

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

Referenced by cb_events().

02812 {
02813    struct chan_list *help=list;
02814    
02815    chan_misdn_log(6, bc->port, "$$$ find_holded: channel:%d oad:%s dad:%s\n",bc->channel, bc->oad,bc->dad);
02816    for (;help; help=help->next) {
02817       chan_misdn_log(4, bc->port, "$$$ find_holded: --> holded:%d channel:%d\n",help->bc->holded, help->bc->channel);
02818       if (help->bc->port == bc->port
02819           && help->bc->holded ) 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 void free_robin_list ( void   )  [static]

Definition at line 226 of file chan_misdn.c.

References free_robin_list_r(), and robin.

Referenced by reload_config(), and unload_module().

00227 {
00228    free_robin_list_r(robin);
00229    robin = NULL;
00230 }

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

Definition at line 217 of file chan_misdn.c.

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

Referenced by free_robin_list().

00218 {
00219         if (r) {
00220                 if (r->next) free_robin_list_r(r->next);
00221                 if (r->group) free(r->group);
00222                 free(r);
00223         }
00224 }

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

Definition at line 322 of file chan_misdn.c.

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

Referenced by misdn_bridge().

00323 {
00324    struct chan_list *tmp;
00325   
00326    for (tmp=cl_te; tmp; tmp = tmp->next) {
00327       if ( tmp->ast == ast ) return tmp;
00328    }
00329   
00330    return NULL;
00331 }

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

Definition at line 333 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().

00334 {
00335    struct chan_list *tmp;
00336   
00337    for (tmp=cl_te; tmp; tmp = tmp->next) {
00338       if ( tmp->ast  && strcmp(tmp->ast->name,name) == 0) return tmp;
00339    }
00340   
00341    return NULL;
00342 }

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

Definition at line 232 of file chan_misdn.c.

References calloc, robin_list::group, robin_list::next, robin_list::prev, robin, and strndup.

Referenced by misdn_request().

00233 {
00234    struct robin_list *iter = robin;
00235    for (; iter; iter = iter->next) {
00236       if (!strcasecmp(iter->group, group))
00237          return iter;
00238    }
00239    struct robin_list *new = (struct robin_list *)calloc(1, sizeof(struct robin_list));
00240    new->group = strndup(group, strlen(group));
00241    new->channel = 1;
00242    if (robin) {
00243       new->next = robin;
00244       robin->prev = new;
00245    }
00246    robin = new;
00247    return robin;
00248 }

static void hangup_chan ( struct chan_list ch  )  [static]

Definition at line 2893 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().

02894 {
02895    if (!ch) {
02896       cb_log(1,0,"Cannot hangup chan, no ch\n");
02897       return;
02898    }
02899 
02900    cb_log(1,ch->bc?ch->bc->port:0,"hangup_chan\n");
02901 
02902    if (ch->need_hangup) 
02903    {
02904       cb_log(1,ch->bc->port,"-> hangup\n");
02905       send_cause2ast(ch->ast,ch->bc,ch);
02906       ch->need_hangup=0;
02907       ch->need_queue_hangup=0;
02908       if (ch->ast)
02909          ast_hangup(ch->ast);
02910       return;
02911    }
02912 
02913    if (!ch->need_queue_hangup) {
02914       cb_log(1,ch->bc->port,"No need to queue hangup\n");
02915    }
02916 
02917    ch->need_queue_hangup=0;
02918    if (ch->ast) {
02919       send_cause2ast(ch->ast,ch->bc,ch);
02920 
02921       if (ch->ast)
02922          ast_queue_hangup(ch->ast);
02923       cb_log(1,ch->bc->port,"-> queue_hangup\n");
02924    } else {
02925       cb_log(1,ch->bc->port,"Cannot hangup chan, no ast\n");
02926    }
02927 }

static int hanguptone_indicate ( struct chan_list cl  )  [static]

Definition at line 2384 of file chan_misdn.c.

References chan_list::bc.

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

02385 {
02386    misdn_lib_send_tone(cl->bc,TONE_HANGUP);
02387    return 0;
02388 }

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

Definition at line 3115 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().

03116 {
03117    char *tmp;
03118    tmp=pbx_builtin_getvar_helper(chan,"MISDN_PID");
03119    if (tmp) {
03120       ch->other_pid=atoi(tmp);
03121       chan_misdn_log(1,bc->port,"IMPORT_PID: importing pid:%s\n",tmp);
03122 
03123       if (ch->other_pid >0) {
03124          ch->other_ch=find_chan_by_pid(cl_te,ch->other_pid);
03125          if (ch->other_ch) ch->other_ch->other_ch=ch;
03126       }
03127    }
03128 }

static struct chan_list* init_chan_list ( int  orig  )  [static]

Definition at line 2421 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().

02422 {
02423    struct chan_list *cl=malloc(sizeof(struct chan_list));
02424    
02425    if (!cl) {
02426       chan_misdn_log(-1, 0, "misdn_request: malloc failed!");
02427       return NULL;
02428    }
02429    
02430    memset(cl,0,sizeof(struct chan_list));
02431 
02432    cl->orginator=orig;
02433    cl->need_queue_hangup=1;
02434    cl->need_hangup=1;
02435    cl->need_busy=1;
02436    
02437    return cl;
02438    
02439 }

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

References ASTERISK_GPL_KEY.

04224 {
04225    return ASTERISK_GPL_KEY;
04226 }

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 4030 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().

04031 {
04032    int i;
04033    
04034    char ports[256]="";
04035    
04036    max_ports=misdn_lib_maxports_get();
04037    
04038    if (max_ports<=0) {
04039       ast_log(LOG_ERROR, "Unable to initialize mISDN\n");
04040       return 0;
04041    }
04042    
04043    
04044    misdn_cfg_init(max_ports);
04045    g_config_initialized=1;
04046    
04047    misdn_debug = (int *)malloc(sizeof(int) * (max_ports+1));
04048    misdn_cfg_get( 0, MISDN_GEN_DEBUG, &misdn_debug[0], sizeof(int));
04049    for (i = 1; i <= max_ports; i++)
04050       misdn_debug[i] = misdn_debug[0];
04051    misdn_debug_only = (int *)calloc(max_ports + 1, sizeof(int));
04052 
04053    
04054    {
04055       char tempbuf[BUFFERSIZE+1];
04056       misdn_cfg_get( 0, MISDN_GEN_TRACEFILE, tempbuf, BUFFERSIZE);
04057       if (strlen(tempbuf))
04058          tracing = 1;
04059    }
04060 
04061    ast_mutex_init(&cl_te_lock);
04062 
04063    misdn_cfg_update_ptp();
04064    misdn_cfg_get_ports_string(ports);
04065       
04066    if (strlen(ports))
04067       chan_misdn_log(0, 0, "Got: %s from get_ports\n",ports);
04068    
04069    {
04070       struct misdn_lib_iface iface = {
04071          .cb_event = cb_events,
04072          .cb_log = chan_misdn_log,
04073          .cb_jb_empty = chan_misdn_jb_empty,
04074       };
04075       if (misdn_lib_init(ports, &iface, NULL))
04076          chan_misdn_log(0, 0, "No te ports initialized\n");
04077    
04078       int ntflags=0;
04079       char ntfile[BUFFERSIZE+1];
04080 
04081       misdn_cfg_get( 0, MISDN_GEN_NTDEBUGFLAGS, &ntflags, sizeof(int));
04082       misdn_cfg_get( 0, MISDN_GEN_NTDEBUGFILE, &ntfile, BUFFERSIZE);
04083 
04084       misdn_lib_nt_debug_init(ntflags,ntfile);
04085 
04086    }
04087 
04088 
04089    {
04090       if (ast_channel_register(&misdn_tech)) {
04091          ast_log(LOG_ERROR, "Unable to register channel class %s\n", misdn_type);
04092          unload_module();
04093          return -1;
04094       }
04095    }
04096   
04097    ast_cli_register(&cli_send_display);
04098    ast_cli_register(&cli_send_cd);
04099    ast_cli_register(&cli_send_digit);
04100    ast_cli_register(&cli_toggle_echocancel);
04101    ast_cli_register(&cli_set_tics);
04102 
04103    ast_cli_register(&cli_show_cls);
04104    ast_cli_register(&cli_show_cl);
04105    ast_cli_register(&cli_show_config);
04106    ast_cli_register(&cli_show_port);
04107    ast_cli_register(&cli_show_stacks);
04108 
04109    ast_cli_register(&cli_port_block);
04110    ast_cli_register(&cli_port_unblock);
04111    ast_cli_register(&cli_restart_port);
04112    ast_cli_register(&cli_port_up);
04113    ast_cli_register(&cli_port_down);
04114    ast_cli_register(&cli_set_debug);
04115    ast_cli_register(&cli_set_crypt_debug);
04116    ast_cli_register(&cli_reload);
04117 
04118   
04119    ast_register_application("misdn_set_opt", misdn_set_opt_exec, "misdn_set_opt",
04120              "misdn_set_opt(:<opt><optarg>:<opt><optarg>..):\n"
04121              "Sets mISDN opts. and optargs\n"
04122              "\n"
04123              "The available options are:\n"
04124              "    d - Send display text on called phone, text is the optparam\n"
04125              "    n - don't detect dtmf tones on called channel\n"
04126              "    h - make digital outgoing call\n" 
04127              "    c - make crypted outgoing call, param is keyindex\n"
04128              "    e - perform echo cancelation on this channel,\n"
04129              "        takes taps as arguments (32,64,128,256)\n"
04130              "    s - send Non Inband DTMF as inband\n"
04131              "   vr - rxgain control\n"
04132              "   vt - txgain control\n"
04133       );
04134 
04135    
04136    ast_register_application("misdn_facility", misdn_facility_exec, "misdn_facility",
04137              "misdn_facility(<FACILITY_TYPE>|<ARG1>|..)\n"
04138              "Sends the Facility Message FACILITY_TYPE with \n"
04139              "the given Arguments to the current ISDN Channel\n"
04140              "Supported Facilities are:\n"
04141              "\n"
04142              "type=calldeflect args=Nr where to deflect\n"
04143       );
04144 
04145 
04146    misdn_cfg_get( 0, MISDN_GEN_TRACEFILE, global_tracefile, BUFFERSIZE);
04147 
04148    chan_misdn_log(0, 0, "-- mISDN Channel Driver Registred -- (BE AWARE THIS DRIVER IS EXPERIMENTAL!)\n");
04149 
04150    return 0;
04151 }

static int misdn_answer ( struct ast_channel ast  )  [static]

Definition at line 1681 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().

01682 {
01683    struct chan_list *p;
01684 
01685    
01686    if (!ast || ! (p=MISDN_ASTERISK_TECH_PVT(ast)) ) return -1;
01687    
01688    chan_misdn_log(1, p? (p->bc? p->bc->port : 0) : 0, "* ANSWER:\n");
01689    
01690    if (!p) {
01691       ast_log(LOG_WARNING, " --> Channel not connected ??\n");
01692       ast_queue_hangup(ast);
01693    }
01694 
01695    if (!p->bc) {
01696       chan_misdn_log(1, 0, " --> Got Answer, but theres no bc obj ??\n");
01697 
01698       ast_queue_hangup(ast);
01699    }
01700 
01701    {
01702       const char *tmp_key = pbx_builtin_getvar_helper(p->ast, "CRYPT_KEY");
01703       
01704       if (tmp_key ) {
01705          chan_misdn_log(1, p->bc->port, " --> Connection will be BF crypted\n");
01706          {
01707             int l = sizeof(p->bc->crypt_key);
01708             strncpy(p->bc->crypt_key,tmp_key, l);
01709             p->bc->crypt_key[l-1] = 0;
01710          }
01711       } else {
01712          chan_misdn_log(3, p->bc->port, " --> Connection is without BF encryption\n");
01713       }
01714     
01715    }
01716 
01717    {
01718       const char *nodsp=pbx_builtin_getvar_helper(ast, "MISDN_DIGITAL_TRANS");
01719       if (nodsp) {
01720          chan_misdn_log(1, p->bc->port, " --> Connection is transparent digital\n");
01721          p->bc->nodsp=1;
01722          p->bc->hdlc=0;
01723          p->bc->nojitter=1;
01724       }
01725    }
01726    
01727    p->state = MISDN_CONNECTED;
01728    misdn_lib_echo(p->bc,0);
01729    stop_indicate(p);
01730 
01731    if ( ast_strlen_zero(p->bc->cad) ) {
01732       chan_misdn_log(2,p->bc->port," --> empty cad using dad\n");
01733       ast_copy_string(p->bc->cad,p->bc->dad,sizeof(p->bc->cad));
01734    }
01735 
01736    misdn_lib_send_event( p->bc, EVENT_CONNECT);
01737    start_bc_tones(p);
01738    
01739    return 0;
01740 }

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 2246 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_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.

02252 {
02253    struct chan_list *ch1,*ch2;
02254    struct ast_channel *carr[2], *who;
02255    int to=-1;
02256    struct ast_frame *f;
02257   
02258    ch1=get_chan_by_ast(c0);
02259    ch2=get_chan_by_ast(c1);
02260 
02261    carr[0]=c0;
02262    carr[1]=c1;
02263   
02264   
02265    if (ch1 && ch2 ) ;
02266    else
02267       return -1;
02268   
02269 
02270    int bridging;
02271    misdn_cfg_get( 0, MISDN_GEN_BRIDGING, &bridging, sizeof(int));
02272    if (bridging) {
02273       int ec;
02274       misdn_cfg_get( ch1->bc->port, MISDN_CFG_ECHOCANCEL, &ec, sizeof(int));
02275       if ( ec ) {
02276          chan_misdn_log(2, ch1->bc->port, "Disabling Echo Cancellor when Bridged\n");
02277          ch1->bc->ec_enable=0;
02278          manager_ec_disable(ch1->bc);
02279       }
02280       misdn_cfg_get( ch2->bc->port, MISDN_CFG_ECHOCANCEL, &ec, sizeof(int));
02281       if ( ec ) {
02282          chan_misdn_log(2, ch2->bc->port, "Disabling Echo Cancellor when Bridged\n");
02283          ch2->bc->ec_enable=0;
02284          manager_ec_disable(ch2->bc); 
02285       }
02286       
02287       /* trying to make a mISDN_dsp conference */
02288       chan_misdn_log(1, ch1->bc->port, "I SEND: Making conference with Number:%d\n", ch1->bc->pid +1);
02289       
02290       misdn_lib_bridge(ch1->bc,ch2->bc);
02291    }
02292    
02293    chan_misdn_log(1, ch1->bc->port, "* Making Native Bridge between %s and %s\n", ch1->bc->oad, ch2->bc->oad);
02294 
02295 
02296    if (! (flags&AST_BRIDGE_DTMF_CHANNEL_0) )
02297       ch1->ignore_dtmf=1;
02298    
02299    if (! (flags&AST_BRIDGE_DTMF_CHANNEL_1) )
02300       ch2->ignore_dtmf=1;
02301    
02302    
02303    while(1) {
02304       to=-1;
02305       who = ast_waitfor_n(carr, 2, &to);
02306 
02307       if (!who) {
02308          ast_log(LOG_NOTICE,"misdn_bridge: empty read, breaking out\n");
02309          break;
02310       }
02311       f = ast_read(who);
02312     
02313       if (!f || f->frametype == AST_FRAME_CONTROL) {
02314          /* got hangup .. */
02315 
02316          if (!f) 
02317             chan_misdn_log(1,ch1->bc->port,"Read Null Frame\n");
02318          else
02319             chan_misdn_log(1,ch1->bc->port,"Read Frame Controll class:%d\n",f->subclass);
02320          
02321          *fo=f;
02322          *rc=who;
02323       
02324          break;
02325       }
02326       
02327       if ( f->frametype == AST_FRAME_DTMF ) {
02328          chan_misdn_log(1,0,"Read DTMF %d from %s\n",f->subclass, who->exten);
02329 
02330          *fo=f;
02331          *rc=who;
02332          break;
02333       }
02334       
02335       
02336       if (who == c0) {
02337          ast_write(c1,f);
02338       }
02339       else {
02340          ast_write(c0,f);
02341       }
02342     
02343    }
02344    
02345    chan_misdn_log(1, ch1->bc->port, "I SEND: Splitting conference with Number:%d\n", ch1->bc->pid +1);
02346    
02347    misdn_lib_split_bridge(ch1->bc,ch2->bc);
02348    
02349    
02350    return AST_BRIDGE_COMPLETE;
02351 }

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

Definition at line 1552 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().

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

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

Definition at line 1742 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.

01743 {
01744    struct chan_list *p;
01745    
01746    if (!ast || ! (p=MISDN_ASTERISK_TECH_PVT(ast))) return -1;
01747 
01748    struct misdn_bchannel *bc=p->bc;
01749    chan_misdn_log(1, bc?bc->port:0, "* IND : Digit %c\n",digit);
01750    
01751    if (!bc) {
01752       ast_log(LOG_WARNING, " --> !! Got Digit Event withut having bchannel Object\n");
01753       return -1;
01754    }
01755    
01756    switch (p->state ) {
01757       case MISDN_CALLING:
01758       {
01759          
01760          char buf[8];
01761          buf[0]=digit;
01762          buf[1]=0;
01763          
01764          int l = sizeof(bc->infos_pending);
01765          strncat(bc->infos_pending,buf,l);
01766          bc->infos_pending[l-1] = 0;
01767       }
01768       break;
01769       case MISDN_CALLING_ACKNOWLEDGE:
01770       {
01771          bc->info_dad[0]=digit;
01772          bc->info_dad[1]=0;
01773          
01774          {
01775             int l = sizeof(bc->dad);
01776             strncat(bc->dad,bc->info_dad, l - strlen(bc->dad));
01777             bc->dad[l-1] = 0;
01778       }
01779          {
01780             int l = sizeof(p->ast->exten);
01781             strncpy(p->ast->exten, bc->dad, l);
01782             p->ast->exten[l-1] = 0;
01783          }
01784          
01785          misdn_lib_send_event( bc, EVENT_INFORMATION);
01786       }
01787       break;
01788       
01789       default:
01790          if ( bc->send_dtmf ) {
01791             send_digit_to_chan(p,digit);
01792          }
01793       break;
01794    }
01795    
01796    return 0;
01797 }

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

Definition at line 4233 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().

04234 {
04235    struct chan_list *ch = MISDN_ASTERISK_TECH_PVT(chan);
04236    char *tok, *tokb;
04237 
04238    chan_misdn_log(0,0,"TYPE: %s\n",chan->tech->type);
04239    
04240    if (strcasecmp(chan->tech->type,"mISDN")) {
04241       ast_log(LOG_WARNING, "misdn_facility makes only sense with chan_misdn channels!\n");
04242       return -1;
04243    }
04244    
04245    if (ast_strlen_zero((char *)data)) {
04246       ast_log(LOG_WARNING, "misdn_facility Requires arguments\n");
04247       return -1;
04248    }
04249    
04250    tok=strtok_r((char*)data,"|", &tokb) ;
04251    
04252    if (!tok) {
04253       ast_log(LOG_WARNING, "misdn_facility Requires arguments\n");
04254       return -1;
04255    }
04256    
04257    if (!strcasecmp(tok,"calldeflect")) {
04258       tok=strtok_r(NULL,"|", &tokb) ;
04259       
04260       if (!tok) {
04261          ast_log(LOG_WARNING, "Facility: Call Defl Requires arguments\n");
04262       }
04263       
04264       misdn_lib_send_facility(ch->bc, FACILITY_CALLDEFLECT, tok);
04265       
04266    } else {
04267       ast_log(LOG_WARNING, "Unknown Facility: %s\n",tok);
04268    }
04269    
04270    return 0;
04271    
04272 }

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

Definition at line 1800 of file chan_misdn.c.

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

01801 {
01802    struct chan_list *p;
01803    
01804    if (!ast || ! (p=MISDN_ASTERISK_TECH_PVT(ast) )) return -1;
01805    
01806    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);
01807    
01808    p->ast = ast ;
01809    p->state=MISDN_CONNECTED;
01810   
01811    return 0;
01812 }

static char* misdn_get_ch_state ( struct chan_list p  )  [static]

Definition at line 680 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().

00681 {
00682    int i;
00683    static char state[8];
00684    
00685    if( !p) return NULL;
00686   
00687    for (i=0; i< sizeof(state_array)/sizeof(struct state_struct); i++) {
00688       if ( state_array[i].state == p->state) return state_array[i].txt; 
00689    }
00690 
00691    sprintf(state,"%d",p->state) ;
00692 
00693    return state;
00694 }

static int misdn_hangup ( struct ast_channel ast  )  [static]

Definition at line 1950 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_get_ch_state(), MISDN_HOLD_DISCONNECT, MISDN_HOLDED, 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().

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

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

Definition at line 1816 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().

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

void misdn_jb_destroy ( struct misdn_jb jb  ) 

Definition at line 4516 of file chan_misdn.c.

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

Referenced by config_jitterbuffer(), and release_chan().

04517 {
04518    ast_mutex_destroy(&jb->mutexjb);
04519    
04520    free(jb->samples);
04521    free(jb);
04522 }

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

Definition at line 4588 of file chan_misdn.c.

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

Referenced by chan_misdn_jb_empty().

04589 {
04590     int i, wp, rp, read=0;
04591 
04592     ast_mutex_lock (&jb->mutexjb);
04593 
04594     rp=jb->rp;
04595     wp=jb->wp;
04596 
04597     if(jb->state_empty)
04598     { 
04599    for(i=0; i<len; i++)
04600    {
04601        if(wp==rp)
04602        {
04603       jb->rp=rp;
04604       jb->state_empty=0;
04605 
04606       ast_mutex_unlock (&jb->mutexjb);
04607       
04608       return read;
04609        }
04610        else
04611        {
04612       if(jb->ok[rp]==1)
04613       {
04614           data[i]=jb->samples[rp];
04615           jb->ok[rp]=0;
04616           rp=(rp!=jb->size-1 ? rp+1 : 0);
04617           read+=1;
04618       }
04619        }
04620    }
04621 
04622    if(wp >= rp)
04623       jb->state_buffer=wp-rp;
04624    else
04625       jb->state_buffer= jb->size-rp+wp;
04626    chan_misdn_log(9,0,"misdn_jb_empty: read:%d | Bufferstatus:%d p:%x\n",len,jb->state_buffer,jb);
04627    
04628    jb->rp=rp;
04629     }
04630     else
04631        chan_misdn_log(9,0,"misdn_jb_empty: Wait...requested:%d p:%x\n",len,jb);
04632     
04633     ast_mutex_unlock (&jb->mutexjb);
04634 
04635     return read;
04636 }

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

Definition at line 4526 of file chan_misdn.c.

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

04527 {
04528     int i, j, rp, wp;
04529 
04530     if (!jb || ! data) return 0;
04531 
04532     ast_mutex_lock (&jb->mutexjb);
04533     
04534     wp=jb->wp;
04535     rp=jb->rp;
04536    
04537     for(i=0; i<len; i++)
04538     {
04539    jb->samples[wp]=data[i];
04540    jb->ok[wp]=1;
04541    wp = (wp!=jb->size-1 ? wp+1 : 0);
04542 
04543    if(wp==jb->rp)
04544        jb->state_full=1;
04545     }
04546     
04547     if(wp>=rp)
04548       jb->state_buffer=wp-rp;
04549     else
04550       jb->state_buffer= jb->size-rp+wp;
04551     chan_misdn_log(9,0,"misdn_jb_fill: written:%d | Bufferstatus:%d p:%x\n",len,jb->state_buffer,jb);
04552     
04553     if(jb->state_full)
04554     {
04555    jb->wp=wp;
04556 
04557    rp=wp;
04558    for(j=0; j<jb->upper_threshold; j++)
04559        rp = (rp!=0 ? rp-1 : jb->size-1);
04560    jb->rp=rp;
04561    jb->state_full=0;
04562    jb->state_empty=1;
04563 
04564    ast_mutex_unlock (&jb->mutexjb);
04565    
04566    return -1;
04567     }
04568 
04569     if(!jb->state_empty)
04570     {
04571    jb->bytes_wrote+=len;
04572    if(jb->bytes_wrote>=jb->upper_threshold)
04573    {
04574        jb->state_empty=1;
04575        jb->bytes_wrote=0;
04576    }
04577     }
04578     jb->wp=wp;
04579 
04580     ast_mutex_unlock (&jb->mutexjb);
04581     
04582     return 0;
04583 }

struct misdn_jb * misdn_jb_init ( int  size,
int  upper_threshold 
)

Definition at line 4482 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().

04483 {
04484     int i;
04485     struct misdn_jb *jb = (struct misdn_jb*) malloc(sizeof(struct misdn_jb));
04486     jb->size = size;
04487     jb->upper_threshold = upper_threshold;
04488     jb->wp = 0;
04489     jb->rp = 0;
04490     jb->state_full = 0;
04491     jb->state_empty = 0;
04492     jb->bytes_wrote = 0;
04493     jb->samples = (char *)malloc(size*sizeof(char));
04494 
04495     if (!jb->samples) {
04496        chan_misdn_log(-1,0,"No free Mem for jb->samples\n");
04497        return NULL;
04498     }
04499     
04500     jb->ok = (char *)malloc(size*sizeof(char));
04501 
04502     if (!jb->ok) {
04503        chan_misdn_log(-1,0,"No free Mem for jb->ok\n");
04504        return NULL;
04505     }
04506 
04507     for(i=0; i<size; i++)
04508    jb->ok[i]=0;
04509 
04510     ast_mutex_init(&jb->mutexjb);
04511 
04512     return jb;
04513 }

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 2662 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(), and misdn_request().

02663 {
02664    struct ast_channel *tmp;
02665    
02666    tmp = ast_channel_alloc(1);
02667    
02668    if (tmp) {
02669       chan_misdn_log(2, 0, " --> * NEW CHANNEL dad:%s oad:%s\n",exten,callerid);
02670       
02671       
02672       if (c<=0) {
02673          c=glob_channel++;
02674          snprintf(tmp->name, sizeof(tmp->name), "%s/%d-u%d",
02675              misdn_type, port, c);
02676       } else {
02677          snprintf(tmp->name, sizeof(tmp->name), "%s/%d-%d",
02678              misdn_type, port, c);
02679       }
02680       
02681       tmp->type = misdn_type;
02682       
02683       tmp->nativeformats = prefformat;
02684 
02685       tmp->readformat = format;
02686       tmp->rawreadformat = format;
02687       tmp->writeformat = format;
02688       tmp->rawwriteformat = format;
02689     
02690       tmp->tech_pvt = chlist;
02691       
02692       int bridging;
02693       misdn_cfg_get( 0, MISDN_GEN_BRIDGING, &bridging, sizeof(int));
02694       if (bridging)
02695          tmp->tech = &misdn_tech;
02696       else
02697          tmp->tech = &misdn_tech_wo_bridge;
02698       
02699       tmp->writeformat = format;
02700       tmp->readformat = format;
02701       tmp->priority=1;
02702       
02703       if (exten) 
02704          ast_copy_string(tmp->exten, exten,  sizeof(tmp->exten));
02705       else
02706          chan_misdn_log(1,0,"misdn_new: no exten given.\n");
02707       
02708       if (callerid) {
02709          char *cid_name, *cid_num;
02710       
02711          ast_callerid_parse(callerid, &cid_name, &cid_num);
02712 
02713          if (!ast_strlen_zero(cid_num))
02714             tmp->cid.cid_num = strdup(cid_num);
02715          if (!ast_strlen_zero(cid_name))
02716             tmp->cid.cid_name = strdup(cid_name);
02717       }
02718 
02719       {
02720          if (pipe(chlist->pipe)<0)
02721             perror("Pipe failed\n");
02722          
02723          tmp->fds[0]=chlist->pipe[0];
02724          
02725       }
02726       
02727       ast_setstate(tmp, state);
02728       if (state == AST_STATE_RING)
02729          tmp->rings = 1;
02730       else
02731          tmp->rings = 0;
02732       
02733       
02734    } else {
02735       chan_misdn_log(-1,0,"Unable to allocate channel structure\n");
02736    }
02737    
02738    return tmp;
02739 }

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

Definition at line 528 of file chan_misdn.c.

References RESULT_SHOWUSAGE.

00529 {
00530    int port;
00531   
00532    if (argc != 4)
00533       return RESULT_SHOWUSAGE;
00534   
00535    port = atoi(argv[3]);
00536 
00537    misdn_lib_port_block(port);
00538 
00539    return 0;
00540 }

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

Definition at line 585 of file chan_misdn.c.

References RESULT_SHOWUSAGE.

00586 {
00587    int port;
00588    
00589    if (argc != 4)
00590       return RESULT_SHOWUSAGE;
00591    
00592    port = atoi(argv[3]);
00593    
00594    misdn_lib_get_port_down(port);
00595   
00596    return 0;
00597 }

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

Definition at line 542 of file chan_misdn.c.

References RESULT_SHOWUSAGE.

00543 {
00544    int port;
00545   
00546    if (argc != 4)
00547       return RESULT_SHOWUSAGE;
00548   
00549    port = atoi(argv[3]);
00550 
00551    misdn_lib_port_unblock(port);
00552 
00553    return 0;
00554 }

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

Definition at line 571 of file chan_misdn.c.

References RESULT_SHOWUSAGE.

00572 {
00573    int port;
00574    
00575    if (argc != 4)
00576       return RESULT_SHOWUSAGE;
00577    
00578    port = atoi(argv[3]);
00579    
00580    misdn_lib_get_port_up(port);
00581   
00582    return 0;
00583 }

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

Definition at line 2106 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, 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.

02107 {
02108    struct chan_list *tmp;
02109    int len;
02110    
02111    if (!ast) {
02112       chan_misdn_log(1,0,"misdn_read called without ast\n");
02113       return NULL;
02114    }
02115    if (! (tmp=MISDN_ASTERISK_TECH_PVT(ast)) ) {
02116       chan_misdn_log(1,0,"misdn_read called without ast->pvt\n");
02117       return NULL;
02118    }
02119    if (!tmp->bc) {
02120       chan_misdn_log(1,0,"misdn_read called without bc\n");
02121       return NULL;
02122    }
02123 
02124    len=read(tmp->pipe[0],tmp->ast_rd_buf,sizeof(tmp->ast_rd_buf));
02125    
02126    if (len<=0) {
02127       /* we hangup here, since our pipe is closed */
02128       chan_misdn_log(2,tmp->bc->port,"misdn_read: Pipe closed, hanging up\n");
02129       return NULL;
02130    }
02131 
02132    tmp->frame.frametype  = AST_FRAME_VOICE;
02133    tmp->frame.subclass = AST_FORMAT_ALAW;
02134    tmp->frame.datalen = len;
02135    tmp->frame.samples = len ;
02136    tmp->frame.mallocd =0 ;
02137    tmp->frame.offset= 0 ;
02138    tmp->frame.src = NULL;
02139    tmp->frame.data = tmp->ast_rd_buf ;
02140    
02141    if (tmp->faxdetect || tmp->ast_dsp ) {
02142       return process_ast_dsp(tmp, &tmp->frame);
02143    }
02144    
02145    return &tmp->frame;
02146 }

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

Definition at line 714 of file chan_misdn.c.

References ast_cli(), and reload_config().

00715 {
00716    ast_cli(fd, "Reloading mISDN Config\n");
00717    reload_config();
00718    return 0;
00719 }

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

Definition at line 2441 of file chan_misdn.c.

References chan_list::ast, ast_log(), AST_STATE_RESERVED, ast_strlen_zero(), chan_list::bc, chan_misdn_log(), robin_list::channel, cl_queue_chan(), cl_te, 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_new(), misdn_type, chan_list::need_hangup, ORG_AST, robin_list::port, and read_config().

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

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

Definition at line 557 of file chan_misdn.c.

References RESULT_SHOWUSAGE.

00558 {
00559    int port;
00560   
00561    if (argc != 4)
00562       return RESULT_SHOWUSAGE;
00563   
00564    port = atoi(argv[3]);
00565 
00566    misdn_lib_port_restart(port);
00567 
00568    return 0;
00569 }

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

Definition at line 865 of file chan_misdn.c.

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

00866 {
00867    char *channame; 
00868    char *nr; 
00869   
00870    if (argc != 5)
00871       return RESULT_SHOWUSAGE;
00872   
00873    channame = argv[3];
00874    nr = argv[4];
00875    
00876    ast_cli(fd, "Sending Calldeflection (%s) to %s\n",nr, channame);
00877    
00878    {
00879       struct chan_list *tmp=get_chan_by_ast_name(channame);
00880       
00881       if (!tmp) {
00882          ast_cli(fd, "Sending CD with nr %s to %s failed Channel does not exist\n",nr, channame);
00883          return 0; 
00884       } else {
00885          
00886          misdn_lib_send_facility(tmp->bc, FACILITY_CALLDEFLECT, nr);
00887       }
00888    }
00889   
00890    return 0; 
00891 }

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

Definition at line 893 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().

00894 {
00895    char *channame; 
00896    char *msg; 
00897   
00898    if (argc != 5)
00899       return RESULT_SHOWUSAGE;
00900   
00901    channame = argv[3];
00902    msg = argv[4];
00903 
00904    ast_cli(fd, "Sending %s to %s\n",msg, channame);
00905   
00906    {
00907       struct chan_list *tmp=get_chan_by_ast_name(channame);
00908     
00909       if (!tmp) {
00910          ast_cli(fd, "Sending %s to %s failed Channel does not exist\n",msg, channame);
00911          return 0; 
00912       } else {
00913 #if 1
00914          int i;
00915          int msglen = strlen(msg);
00916          for (i=0; i<msglen; i++) {
00917             ast_cli(fd, "Sending: %c\n",msg[i]);
00918             send_digit_to_chan(tmp, msg[i]);
00919             /* res = ast_safe_sleep(tmp->ast, 250); */
00920             usleep(250000);
00921             /* res = ast_waitfor(tmp->ast,100); */
00922          }
00923 #else
00924          int res;
00925          res = ast_dtmf_stream(tmp->ast,NULL,msg,250);
00926 #endif
00927       }
00928    }
00929   
00930    return 0; 
00931 }

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

Definition at line 966 of file chan_misdn.c.

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

00967 {
00968    char *channame; 
00969    char *msg; 
00970   
00971    if (argc != 5)
00972       return RESULT_SHOWUSAGE;
00973   
00974    channame = argv[3];
00975    msg = argv[4];
00976 
00977    ast_cli(fd, "Sending %s to %s\n",msg, channame);
00978    {
00979       struct chan_list *tmp;
00980       tmp=get_chan_by_ast_name(channame);
00981     
00982       if (tmp && tmp->bc) {
00983          ast_copy_string(tmp->bc->display, msg, sizeof(tmp->bc->display));
00984          misdn_lib_send_event(tmp->bc, EVENT_INFORMATION);
00985       } else {
00986          ast_cli(fd,"No such channel %s\n",channame);
00987          return RESULT_FAILURE;
00988       }
00989    }
00990 
00991    return RESULT_SUCCESS ;
00992 }

int misdn_send_text ( struct ast_channel chan,
const char *  text 
)

Definition at line 2609 of file chan_misdn.c.

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

02610 {
02611    struct chan_list *tmp=chan->tech_pvt;
02612    
02613    if (tmp && tmp->bc) {
02614       ast_copy_string(tmp->bc->display,text,sizeof(tmp->bc->display));
02615       misdn_lib_send_event(tmp->bc, EVENT_INFORMATION);
02616    } else {
02617       ast_log(LOG_WARNING, "No chan_list but send_text request?\n");
02618       return -1;
02619    }
02620    
02621    return 0;
02622 }

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

Definition at line 520 of file chan_misdn.c.

References RESULT_SHOWUSAGE.

00521 {
00522    if (argc != 5) return RESULT_SHOWUSAGE; 
00523 
00524    return 0;
00525 }

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

Definition at line 463 of file chan_misdn.c.

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

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

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

Definition at line 4275 of file chan_misdn.c.

References chan_list::ast_dsp, ast_dsp_new(), ast_dsp_set_features(), AST_FORMAT_ALAW, AST_FORMAT_SLINEAR, ast_log(), ast_strlen_zero(), ast_translator_build_path(), chan_list::bc, chan_misdn_log(), config_jitterbuffer(), DSP_FEATURE_DTMF_DETECT, DSP_FEATURE_FAX_DETECT, 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().

04276 {
04277    struct chan_list *ch = MISDN_ASTERISK_TECH_PVT(chan);
04278    char *tok,*tokb;
04279    int  keyidx=0;
04280    int rxgain=0;
04281    int txgain=0;
04282    int change_jitter=0;
04283    
04284    if (strcasecmp(chan->tech->type,"mISDN")) {
04285       ast_log(LOG_WARNING, "misdn_set_opt makes only sense with chan_misdn channels!\n");
04286       return -1;
04287    }
04288    
04289    if (ast_strlen_zero((char *)data)) {
04290       ast_log(LOG_WARNING, "misdn_set_opt Requires arguments\n");
04291       return -1;
04292    }
04293 
04294    for (tok=strtok_r((char*)data, ":",&tokb);
04295         tok;
04296         tok=strtok_r(NULL,":",&tokb) ) {
04297       int neglect=0;
04298       
04299       if (tok[0] == '!' ) {
04300          neglect=1;
04301          tok++;
04302       }
04303       
04304       switch(tok[0]) {
04305          
04306       case 'd' :
04307          ast_copy_string(ch->bc->display,++tok,84);
04308          chan_misdn_log(1, ch->bc->port, "SETOPT: Display:%s\n",ch->bc->display);
04309          break;
04310          
04311       case 'n':
04312          chan_misdn_log(1, ch->bc->port, "SETOPT: No DSP\n");
04313          ch->bc->nodsp=1;
04314          break;
04315 
04316       case 'j':
04317          chan_misdn_log(1, ch->bc->port, "SETOPT: jitter\n");
04318          tok++;
04319          change_jitter=1;
04320          
04321          switch ( tok[0] ) {
04322          case 'b' :
04323             ch->jb_len=atoi(++tok);
04324             chan_misdn_log(1, ch->bc->port, " --> buffer_len:%d\n",ch->jb_len);
04325             break;
04326          case 't' :
04327             ch->jb_upper_threshold=atoi(++tok);
04328             chan_misdn_log(1, ch->bc->port, " --> upper_threshold:%d\n",ch->jb_upper_threshold);
04329             break;
04330 
04331          case 'n':
04332             ch->bc->nojitter=1;
04333             chan_misdn_log(1, ch->bc->port, " --> nojitter\n");
04334             break;
04335             
04336          default:
04337             ch->jb_len=4000;
04338             ch->jb_upper_threshold=0;
04339             chan_misdn_log(1, ch->bc->port, " --> buffer_len:%d (default)\n",ch->jb_len);
04340             chan_misdn_log(1, ch->bc->port, " --> upper_threshold:%d (default)\n",ch->jb_upper_threshold);
04341          }
04342          
04343          break;
04344       
04345       case 'v':
04346          tok++;
04347 
04348          switch ( tok[0] ) {
04349          case 'r' :
04350             rxgain=atoi(++tok);
04351             if (rxgain<-8) rxgain=-8;
04352             if (rxgain>8) rxgain=8;
04353             ch->bc->rxgain=rxgain;
04354             chan_misdn_log(1, ch->bc->port, "SETOPT: Volume:%d\n",rxgain);
04355             break;
04356          case 't':
04357             txgain=atoi(++tok);
04358             if (txgain<-8) txgain=-8;
04359             if (txgain>8) txgain=8;
04360             ch->bc->txgain=txgain;
04361             chan_misdn_log(1, ch->bc->port, "SETOPT: Volume:%d\n",txgain);
04362             break;
04363          }
04364          break;
04365       
04366       case 'c':
04367          keyidx=atoi(++tok);
04368       
04369          if (keyidx > misdn_key_vector_size  || keyidx < 0 ) {
04370             ast_log(LOG_WARNING, "You entered the keyidx: %d but we have only %d keys\n",keyidx, misdn_key_vector_size );
04371             continue; 
04372          }
04373       
04374          {
04375             ast_copy_string(ch->bc->crypt_key,  misdn_key_vector[keyidx], sizeof(ch->bc->crypt_key));
04376          }
04377          
04378          chan_misdn_log(0, ch->bc->port, "SETOPT: crypt with key:%s\n",misdn_key_vector[keyidx]);
04379          break;
04380 
04381       case 'e':
04382          chan_misdn_log(1, ch->bc->port, "SETOPT: EchoCancel\n");
04383          
04384          if (neglect) {
04385             chan_misdn_log(1, ch->bc->port, " --> disabled\n");
04386             ch->bc->ec_enable=0;
04387 
04388          } else {
04389             ch->bc->ec_enable=1;
04390             ch->bc->orig=ch->orginator;
04391             tok++;
04392             if (tok) {
04393                ch->bc->ec_deftaps=atoi(tok);
04394             }
04395          }
04396          
04397          break;
04398       
04399       case 'h':
04400          chan_misdn_log(1, ch->bc->port, "SETOPT: Digital\n");
04401          
04402          if (strlen(tok) > 1 && tok[1]=='1') {
04403             chan_misdn_log(1, ch->bc->port, "SETOPT: HDLC \n");
04404             ch->bc->hdlc=1;
04405          }  
04406          ch->bc->capability=INFO_CAPABILITY_DIGITAL_UNRESTRICTED;
04407          break;
04408             
04409       case 's':
04410          chan_misdn_log(1, ch->bc->port, "SETOPT: Send DTMF\n");
04411          ch->bc->send_dtmf=1;
04412          break;
04413          
04414       case 'f':
04415          chan_misdn_log(1, ch->bc->port, "SETOPT: Faxdetect\n");
04416          ch->faxdetect=1;
04417          break;
04418 
04419       case 'a':
04420          chan_misdn_log(1, ch->bc->port, "SETOPT: AST_DSP (for DTMF)\n");
04421          ch->ast_dsp=1;
04422          break;
04423 
04424       case 'p':
04425          chan_misdn_log(1, ch->bc->port, "SETOPT: callerpres: %s\n",&tok[1]);
04426          /* CRICH: callingpres!!! */
04427          if (strstr(tok,"allowed") ) {
04428             ch->bc->pres=0;
04429          } else if (strstr(tok,"not_screened")) {
04430             ch->bc->pres=1;
04431          }
04432          
04433          
04434          break;
04435       
04436       
04437       default:
04438          break;
04439       }
04440    }
04441 
04442    if (change_jitter)
04443       config_jitterbuffer(ch);
04444    
04445    
04446    if (ch->faxdetect || ch->ast_dsp) {
04447       
04448       if (!ch->dsp) ch->dsp = ast_dsp_new();
04449       if (ch->dsp) ast_dsp_set_features(ch->dsp, DSP_FEATURE_DTMF_DETECT| DSP_FEATURE_FAX_DETECT);
04450       if (!ch->trans) ch->trans=ast_translator_build_path(AST_FORMAT_SLINEAR, AST_FORMAT_ALAW);
04451    }
04452 
04453    if (ch->ast_dsp) {
04454       chan_misdn_log(1,ch->bc->port,"SETOPT: with AST_DSP we deactivate mISDN_dsp\n");
04455       ch->bc->nodsp=1;
04456       ch->bc->nojitter=1;
04457    }
04458    
04459    return 0;
04460 }

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

Definition at line 818 of file chan_misdn.c.

References MAXTICS, and RESULT_SHOWUSAGE.

00819 {
00820    if (argc != 4)
00821       return RESULT_SHOWUSAGE;
00822   
00823    MAXTICS=atoi(argv[3]);
00824   
00825    return 0;
00826 }

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

Definition at line 792 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.

00793 {
00794    struct chan_list *help=cl_te;
00795 
00796    if (argc != 4)
00797       return RESULT_SHOWUSAGE;
00798   
00799    for (;help; help=help->next) {
00800       struct misdn_bchannel *bc=help->bc;   
00801       struct ast_channel *ast=help->ast;
00802     
00803       if (bc && ast) {
00804          if (!strcasecmp(ast->name,argv[3])) {
00805             print_bc_info(fd, help, bc);
00806             break; 
00807          }
00808       } 
00809    }
00810   
00811   
00812    return 0;
00813 }

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

Definition at line 768 of file chan_misdn.c.

References chan_list::ast, AST_CID_P, ast_cli(), chan_list::bc, chan_misdn_log(), cl_te, ast_channel::exten, chan_list::holded_bc, misdn_debug, chan_list::next, and print_bc_info().

00769 {
00770    struct chan_list *help=cl_te;
00771   
00772    ast_cli(fd,"Chan List: %p\n",cl_te); 
00773   
00774    for (;help; help=help->next) {
00775       struct misdn_bchannel *bc=help->bc;   
00776       struct ast_channel *ast=help->ast;
00777       if (misdn_debug[0] > 2) ast_cli(fd, "Bc:%p Ast:%p\n", bc, ast);
00778       if (bc) {
00779          print_bc_info(fd, help, bc);
00780       } else if ( (bc=help->holded_bc) ) {
00781          chan_misdn_log(0, 0, "ITS A HOLDED BC:\n");
00782          print_bc_info(fd, help,  bc);
00783       } else {
00784          ast_cli(fd,"* Channel in unknown STATE !!! Exten:%s, Callerid:%s\n", ast->exten, AST_CID_P(ast));
00785       }
00786    }
00787   
00788   
00789    return 0;
00790 }

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

Definition at line 600 of file chan_misdn.c.

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

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

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

Definition at line 846 of file chan_misdn.c.

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

00847 {
00848    int port;
00849    
00850    if (argc != 4)
00851       return RESULT_SHOWUSAGE;
00852   
00853    port = atoi(argv[3]);
00854   
00855    ast_cli(fd, "BEGIN STACK_LIST:\n");
00856 
00857    char buf[128];
00858    get_show_stack_details(port,buf);
00859    ast_cli(fd,"  %s  Debug:%d%s\n",buf, misdn_debug[port], misdn_debug_only[port]?"(only)":"");
00860 
00861    
00862    return 0;
00863 }

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

Definition at line 828 of file chan_misdn.c.

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

00829 {
00830    int port;
00831 
00832    ast_cli(fd, "BEGIN STACK_LIST:\n");
00833 
00834    for (port=misdn_cfg_get_next_port(0); port > 0;
00835         port=misdn_cfg_get_next_port(port)) {
00836       char buf[128];
00837       get_show_stack_details(port,buf);
00838       ast_cli(fd,"  %s  Debug:%d%s\n", buf, misdn_debug[port], misdn_debug_only[port]?"(only)":"");
00839    }
00840       
00841 
00842    return 0;
00843 
00844 }

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

Definition at line 933 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().

00934 {
00935    char *channame; 
00936 
00937    if (argc != 4)
00938       return RESULT_SHOWUSAGE;
00939    
00940    channame = argv[3];
00941   
00942    ast_cli(fd, "Toggling EchoCancel on %s\n", channame);
00943   
00944    {
00945       struct chan_list *tmp=get_chan_by_ast_name(channame);
00946     
00947       if (!tmp) {
00948          ast_cli(fd, "Toggling EchoCancel %s failed Channel does not exist\n", channame);
00949          return 0; 
00950       } else {
00951          
00952          tmp->toggle_ec=tmp->toggle_ec?0:1;
00953 
00954          if (tmp->toggle_ec) {
00955             update_ec_config(tmp->bc);
00956             manager_ec_enable(tmp->bc);
00957          } else {
00958             manager_ec_disable(tmp->bc);
00959          }
00960       }
00961    }
00962   
00963    return 0; 
00964 }

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

Definition at line 2983 of file chan_misdn.c.

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

02984 {
02985    chan_misdn_log(4,0,"TRANSFERING %s to %s\n",holded_chan->ast->name, tmp_ch->ast->name);
02986    
02987    tmp_ch->state=MISDN_HOLD_DISCONNECT;
02988   
02989    ast_moh_stop(AST_BRIDGED_P(holded_chan->ast));
02990 
02991    holded_chan->state=MISDN_CONNECTED;
02992    misdn_lib_transfer(holded_chan->bc?holded_chan->bc:holded_chan->holded_bc);
02993    ast_channel_masquerade(holded_chan->ast, AST_BRIDGED_P(tmp_ch->ast));
02994 }

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

Definition at line 2149 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.

02150 {
02151    struct chan_list *ch;
02152    int i  = 0;
02153    
02154    if (!ast || ! (ch=MISDN_ASTERISK_TECH_PVT(ast)) ) return -1;
02155    
02156    if (!ch->bc ) {
02157       ast_log(LOG_WARNING, "private but no bc\n");
02158       return -1;
02159    }
02160    
02161    if (ch->state == MISDN_HOLDED) {
02162       chan_misdn_log(8, ch->bc->port, "misdn_write: Returning because holded\n");
02163       return 0;
02164    }
02165    
02166    if (ch->notxtone) {
02167       chan_misdn_log(9, ch->bc->port, "misdn_write: Returning because notxone\n");
02168       return 0;
02169    }
02170 
02171 
02172    if ( !frame->subclass) {
02173       chan_misdn_log(4, ch->bc->port, "misdn_write: * prods us\n");
02174       return 0;
02175    }
02176    
02177    if ( !(frame->subclass & prefformat)) {
02178       
02179       chan_misdn_log(-1, ch->bc->port, "Got Unsupported Frame with Format:%d\n", frame->subclass);
02180       return 0;
02181    }
02182    
02183 
02184    if ( !frame->samples ) {
02185       chan_misdn_log(4, ch->bc->port, "misdn_write: zero write\n");
02186       return 0;
02187    }
02188 
02189    if ( ! ch->bc->addr ) {
02190       chan_misdn_log(8, ch->bc->port, "misdn_write: no addr for bc dropping:%d\n", frame->samples);
02191       return 0;
02192    }
02193    
02194 #if MISDN_DEBUG
02195    {
02196       int i, max=5>frame->samples?frame->samples:5;
02197       
02198       printf("write2mISDN %p %d bytes: ", p, frame->samples);
02199       
02200       for (i=0; i<  max ; i++) printf("%2.2x ",((char*) frame->data)[i]);
02201       printf ("\n");
02202    }
02203 #endif
02204 
02205 
02206    switch (ch->bc->bc_state) {
02207       case BCHAN_ACTIVATED:
02208       case BCHAN_BRIDGED:
02209          break;
02210       default:
02211       if (!ch->dropped_frame_cnt)
02212          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\n",frame->samples,ch->bc->addr, ast->exten, ast->cid.cid_num,misdn_get_ch_state( ch), ch->bc->bc_state);
02213       
02214       ch->dropped_frame_cnt++;
02215       if (ch->dropped_frame_cnt > 100) {
02216          ch->dropped_frame_cnt=0;
02217          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);
02218 
02219       }
02220 
02221       return 0;
02222    }
02223 
02224    chan_misdn_log(9, ch->bc->port, "Sending :%d bytes 2 MISDN\n",frame->samples);
02225    
02226    if ( !ch->bc->nojitter && misdn_cap_is_speech(ch->bc->capability) ) {
02227       /* Buffered Transmit (triggert by read from isdn side)*/
02228       if (misdn_jb_fill(ch->jb,frame->data,frame->samples) < 0) {
02229          if (ch->bc->active)
02230             cb_log(0,ch->bc->port,"Misdn Jitterbuffer Overflow.\n");
02231       }
02232       
02233    } else {
02234       /*transmit without jitterbuffer*/
02235       i=misdn_lib_tx2misdn_frm(ch->bc, frame->data, frame->samples);
02236    }
02237 
02238    
02239    
02240    return 0;
02241 }

int pbx_start_chan ( struct chan_list ch  ) 

Channel Queue End

Definition at line 2881 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().

02882 {
02883    int ret=ast_pbx_start(ch->ast);  
02884 
02885    if (ret>=0) 
02886       ch->need_hangup=0;
02887    else
02888       ch->need_hangup=1;
02889 
02890    return ret;
02891 }

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

Definition at line 721 of file chan_misdn.c.

References chan_list::addr, chan_list::ast, AST_CID_P, ast_cli(), bearer2str(), ast_channel::exten, chan_list::holded_bc, 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().

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

static void print_bearer ( struct misdn_bchannel *  bc  )  [static]

Definition at line 410 of file chan_misdn.c.

References bearer2str(), and chan_misdn_log().

Referenced by cb_events().

00411 {
00412    
00413    chan_misdn_log(2, bc->port, " --> Bearer: %s\n",bearer2str(bc->capability));
00414    
00415    switch(bc->law) {
00416    case INFO_CODEC_ALAW:
00417       chan_misdn_log(2, bc->port, " --> Codec: Alaw\n");
00418       break;
00419    case INFO_CODEC_ULAW:
00420       chan_misdn_log(2, bc->port, " --> Codec: Ulaw\n");
00421       break;
00422    }
00423 }

static void print_facility ( struct misdn_bchannel *  bc  )  [static]

Definition at line 393 of file chan_misdn.c.

References chan_misdn_log().

00394 {
00395    switch (bc->fac_type) {
00396    case FACILITY_CALLDEFLECT:
00397       chan_misdn_log(2,bc->port," --> calldeflect: %s\n",
00398                 bc->fac.calldeflect_nr);
00399       break;
00400    case FACILITY_CENTREX:
00401       chan_misdn_log(2,bc->port," --> centrex: %s\n",
00402                 bc->fac.cnip);
00403       break;
00404    default:
00405       chan_misdn_log(2,bc->port," --> unknown\n");
00406       
00407    }
00408 }

struct ast_frame * process_ast_dsp ( struct chan_list tmp,
struct ast_frame frame 
)

Definition at line 2742 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().

02743 {
02744    struct ast_frame *f,*f2;
02745    if (tmp->trans)
02746       f2=ast_translate(tmp->trans, frame,0);
02747    else {
02748       chan_misdn_log(0, tmp->bc->port, "No T-Path found\n");
02749       return NULL;
02750    }
02751    
02752    f = ast_dsp_process(tmp->ast, tmp->dsp, f2);
02753    if (f && (f->frametype == AST_FRAME_DTMF)) {
02754       ast_log(LOG_DEBUG, "Detected inband DTMF digit: %c", f->subclass);
02755       if (f->subclass == 'f' && tmp->faxdetect) {
02756          /* Fax tone -- Handle and return NULL */
02757          struct ast_channel *ast = tmp->ast;
02758          if (!tmp->faxhandled) {
02759             tmp->faxhandled++;
02760             if (strcmp(ast->exten, "fax")) {
02761                if (ast_exists_extension(ast, ast_strlen_zero(ast->macrocontext)? ast->context : ast->macrocontext, "fax", 1, AST_CID_P(ast))) {
02762                   if (option_verbose > 2)
02763                      ast_verbose(VERBOSE_PREFIX_3 "Redirecting %s to fax extension\n", ast->name);
02764                   /* Save the DID/DNIS when we transfer the fax call to a "fax" extension */
02765                   pbx_builtin_setvar_helper(ast,"FAXEXTEN",ast->exten);
02766                   if (ast_async_goto(ast, ast->context, "fax", 1))
02767                      ast_log(LOG_WARNING, "Failed to async goto '%s' into fax of '%s'\n", ast->name, ast->context);
02768                } else
02769                   ast_log(LOG_NOTICE, "Fax detected, but no fax extension ctx:%s exten:%s\n",ast->context, ast->exten);
02770             } else
02771                ast_log(LOG_DEBUG, "Already in a fax extension, not redirecting\n");
02772          } else
02773             ast_log(LOG_DEBUG, "Fax already handled\n");
02774          
02775       }  else if ( tmp->ast_dsp) {
02776          chan_misdn_log(2, tmp->bc->port, " --> * SEND: DTMF (AST_DSP) :%c\n",f->subclass);
02777          return f;
02778       }
02779    }
02780 
02781    frame->frametype = AST_FRAME_NULL;
02782    frame->subclass = 0;
02783    return frame;
02784 }

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

Definition at line 1361 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(), and misdn_request().

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

static void release_chan ( struct misdn_bchannel *  bc  )  [static]

Isdn asks us to release channel, pendant to misdn_hangup

Definition at line 2930 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.

02930                                                     {
02931    struct ast_channel *ast=NULL;
02932    {
02933       struct chan_list *ch=find_chan_by_bc(cl_te, bc);
02934       if (!ch)  {
02935          chan_misdn_log(0, bc->port, "release_chan: Ch not found!\n");
02936          return;
02937       }
02938       
02939       if (ch->ast) {
02940          ast=ch->ast;
02941       } 
02942       
02943       chan_misdn_log(1, bc->port, "release_chan: bc with l3id: %x\n",bc->l3_id);
02944       
02945       /*releaseing jitterbuffer*/
02946       if (ch->jb ) {
02947          misdn_jb_destroy(ch->jb);
02948          ch->jb=NULL;
02949       } else {
02950          if (!bc->nojitter)
02951             chan_misdn_log(5,bc->port,"Jitterbuffer already destroyed.\n");
02952       }
02953       
02954       if (ch) {
02955          
02956          close(ch->pipe[0]);
02957          close(ch->pipe[1]);
02958 
02959          
02960          if (ast && MISDN_ASTERISK_TECH_PVT(ast)) {
02961             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));
02962             chan_misdn_log(3, bc->port, " --> * State Down\n");
02963             MISDN_ASTERISK_TECH_PVT(ast)=NULL;
02964             
02965       
02966             if (ast->_state != AST_STATE_RESERVED) {
02967                chan_misdn_log(3, bc->port, " --> Setting AST State to down\n");
02968                ast_setstate(ast, AST_STATE_DOWN);
02969             }
02970          }
02971             
02972          ch->state=MISDN_CLEANING;
02973          cl_dequeue_chan(&cl_te, ch);
02974          
02975          free(ch);
02976       } else {
02977          /* chan is already cleaned, so exiting  */
02978       }
02979    }
02980 }

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

References reload_config().

04203 {
04204    reload_config();
04205 
04206    return 0;
04207 }

void reload_config ( void   ) 

Definition at line 698 of file chan_misdn.c.

References ahp, ast_alias_list::aliases, aliasl, ast_category_browse(), ast_config_destroy(), ast_config_load(), ast_gethostbyname(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_true(), ast_variable_browse(), ast_variable_retrieve(), ast_verbose(), build_alias(), build_peer(), build_user(), cfg, format, free_robin_list(), global_tracefile, hp, IPTOS_MINCOST, ast_variable::lineno, ast_user_list::lock, ast_peer_list::lock, ast_alias_list::lock, LOG_ERROR, LOG_NOTICE, LOG_WARNING, max_ports, misdn_cfg_get(), misdn_cfg_reload(), misdn_cfg_update_ptp(), misdn_debug, misdn_debug_only, ast_variable::name, ast_variable::next, peerl, ast_peer_list::peers, update_common_options(), user, userl, ast_user_list::users, ast_variable::value, and VERBOSE_PREFIX_2.

00699 {
00700    int i, cfg_debug;
00701    
00702    free_robin_list();
00703    misdn_cfg_reload();
00704    misdn_cfg_update_ptp();
00705    misdn_cfg_get( 0, MISDN_GEN_TRACEFILE, global_tracefile, BUFFERSIZE);
00706    misdn_cfg_get( 0, MISDN_GEN_DEBUG, &cfg_debug, sizeof(int));
00707 
00708    for (i = 0;  i <= max_ports; i++) {
00709       misdn_debug[i] = cfg_debug;
00710       misdn_debug_only[i] = 0;
00711    }
00712 }

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

Definition at line 3060 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().

03060                                                                                                     {
03061    if (!ast) {
03062       chan_misdn_log(1,0,"send_cause2ast: No Ast\n");
03063       return;
03064    }
03065    if (!bc) {
03066       chan_misdn_log(1,0,"send_cause2ast: No BC\n");
03067       return;
03068    }
03069    if (!ch) {
03070       chan_misdn_log(1,0,"send_cause2ast: No Ch\n");
03071       return;
03072    }
03073    
03074    ast->hangupcause=bc->cause;
03075    
03076    switch ( bc->cause) {
03077       
03078    case 1: /** Congestion Cases **/
03079    case 2:
03080    case 3:
03081    case 4:
03082    case 22:
03083    case 27:
03084       /*
03085        * Not Queueing the Congestion anymore, since we want to hear
03086        * the inband message
03087        *
03088       chan_misdn_log(1, bc?bc->port:0, " --> * SEND: Queue Congestion pid:%d\n", bc?bc->pid:-1);
03089       ch->state=MISDN_BUSY;
03090       
03091       ast_queue_control(ast, AST_CONTROL_CONGESTION);
03092       */
03093       break;
03094       
03095    case 21:
03096    case 17: /* user busy */
03097    
03098       ch->state=MISDN_BUSY;
03099          
03100       if (!ch->need_busy) {
03101          chan_misdn_log(1,bc?bc->port:0, "Queued busy already\n");
03102          break;
03103       }
03104       
03105       chan_misdn_log(1,  bc?bc->port:0, " --> * SEND: Queue Busy pid:%d\n", bc?bc->pid:-1);
03106       
03107       ast_queue_control(ast, AST_CONTROL_BUSY);
03108       
03109       ch->need_busy=0;
03110       
03111       break;
03112    }
03113 }

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

Definition at line 426 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().

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

static int start_bc_tones ( struct chan_list cl  )  [static]

Definition at line 2402 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().

02403 {
02404    misdn_lib_tone_generator_stop(cl->bc);
02405    cl->notxtone=0;
02406    cl->norxtone=0;
02407    return 0;
02408 }

static int stop_bc_tones ( struct chan_list cl  )  [static]

Definition at line 2410 of file chan_misdn.c.

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

Referenced by misdn_call(), and misdn_hangup().

02411 {
02412    if (!cl) return -1;
02413 
02414    cl->notxtone=1;
02415    cl->norxtone=1;
02416    
02417    return 0;
02418 }

static int stop_indicate ( struct chan_list cl  )  [static]

Definition at line 2390 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().

02391 {
02392    struct ast_channel *ast=cl->ast;
02393    chan_misdn_log(3,cl->bc->port," --> None\n");
02394    misdn_lib_tone_generator_stop(cl->bc);
02395    ast_playtones_stop(ast);
02396    /*ast_deactivate_generator(ast);*/
02397    
02398    return 0;
02399 }

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 4155 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.

04156 {
04157    /* First, take us out of the channel loop */
04158    ast_log(LOG_VERBOSE, "-- Unregistering mISDN Channel Driver --\n");
04159    
04160    if (!g_config_initialized) return 0;
04161    
04162    ast_cli_unregister(&cli_send_display);
04163    
04164    ast_cli_unregister(&cli_send_cd);
04165    
04166    ast_cli_unregister(&cli_send_digit);
04167    ast_cli_unregister(&cli_toggle_echocancel);
04168    ast_cli_unregister(&cli_set_tics);
04169   
04170    ast_cli_unregister(&cli_show_cls);
04171    ast_cli_unregister(&cli_show_cl);
04172    ast_cli_unregister(&cli_show_config);
04173    ast_cli_unregister(&cli_show_port);
04174    ast_cli_unregister(&cli_show_stacks);
04175    ast_cli_unregister(&cli_port_block);
04176    ast_cli_unregister(&cli_port_unblock);
04177    ast_cli_unregister(&cli_restart_port);
04178    ast_cli_unregister(&cli_port_up);
04179    ast_cli_unregister(&cli_port_down);
04180    ast_cli_unregister(&cli_set_debug);
04181    ast_cli_unregister(&cli_set_crypt_debug);
04182    ast_cli_unregister(&cli_reload);
04183    /* ast_unregister_application("misdn_crypt"); */
04184    ast_unregister_application("misdn_set_opt");
04185    ast_unregister_application("misdn_facility");
04186   
04187    ast_channel_unregister(&misdn_tech);
04188 
04189 
04190    free_robin_list();
04191    misdn_cfg_destroy();
04192    misdn_lib_destroy();
04193   
04194    if (misdn_debug)
04195       free(misdn_debug);
04196    if (misdn_debug_only)
04197       free(misdn_debug_only);
04198    
04199    return 0;
04200 }

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

Definition at line 1182 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().

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

static int update_ec_config ( struct misdn_bchannel *  bc  )  [static]

Definition at line 1343 of file chan_misdn.c.

References misdn_cfg_get().

Referenced by misdn_toggle_echocancel(), and read_config().

01344 {
01345    int ec;
01346    int port=bc->port;
01347       
01348    misdn_cfg_get( port, MISDN_CFG_ECHOCANCEL, &ec, sizeof(int));
01349    
01350    if (ec == 1 ) {
01351       bc->ec_enable=1;
01352    } else if ( ec > 1 ) {
01353       bc->ec_enable=1;
01354       bc->ec_deftaps=ec;
01355    }
01356 
01357    return 0;
01358 }

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

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

04210 {
04211    int res;
04212    ast_mutex_lock(&usecnt_lock);
04213    res = usecnt;
04214    ast_mutex_unlock(&usecnt_lock);
04215    return res;
04216 }


Variable Documentation

struct allowed_bearers allowed_bearers_array[]

Definition at line 352 of file chan_misdn.c.

Referenced by cb_events().

struct chan_list* cl_te = NULL

Definition at line 290 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_request(), misdn_show_cl(), misdn_show_cls(), and release_chan().

ast_mutex_t cl_te_lock

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

Referenced by load_module(), and unload_module().

struct ast_cli_entry cli_port_down [static]

Definition at line 1142 of file chan_misdn.c.

Referenced by load_module(), and unload_module().

struct ast_cli_entry cli_port_unblock [static]

Definition at line 1120 of file chan_misdn.c.

Referenced by load_module(), and unload_module().

struct ast_cli_entry cli_port_up [static]

Definition at line 1135 of file chan_misdn.c.

Referenced by load_module(), and unload_module().

struct ast_cli_entry cli_reload [static]

Definition at line 1084 of file chan_misdn.c.

struct ast_cli_entry cli_restart_port [static]

Definition at line 1128 of file chan_misdn.c.

Referenced by load_module(), and unload_module().

struct ast_cli_entry cli_send_cd [static]

Definition at line 1041 of file chan_misdn.c.

Referenced by load_module(), and unload_module().

struct ast_cli_entry cli_send_digit [static]

Definition at line 1049 of file chan_misdn.c.

Referenced by load_module(), and unload_module().

struct ast_cli_entry cli_send_display [static]

Definition at line 1067 of file chan_misdn.c.

Referenced by load_module(), and unload_module().

struct ast_cli_entry cli_set_crypt_debug [static]

Definition at line 1173 of file chan_misdn.c.

Referenced by load_module(), and unload_module().

struct ast_cli_entry cli_set_debug [static]

Definition at line 1165 of file chan_misdn.c.

Referenced by load_module(), and unload_module().

struct ast_cli_entry cli_set_tics [static]

Definition at line 1091 of file chan_misdn.c.

Referenced by load_module(), and unload_module().

struct ast_cli_entry cli_show_cl [static]

Definition at line 1105 of file chan_misdn.c.

Referenced by load_module(), and unload_module().

struct ast_cli_entry cli_show_cls [static]

Definition at line 1098 of file chan_misdn.c.

Referenced by load_module(), and unload_module().

struct ast_cli_entry cli_show_config [static]

Definition at line 1077 of file chan_misdn.c.

Referenced by load_module(), and unload_module().

struct ast_cli_entry cli_show_port [static]

Definition at line 1158 of file chan_misdn.c.

Referenced by load_module(), and unload_module().

struct ast_cli_entry cli_show_stacks [static]

Definition at line 1151 of file chan_misdn.c.

Referenced by load_module(), and unload_module().

struct ast_cli_entry cli_toggle_echocancel [static]

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

struct chan_list dummy_cl

Definition at line 288 of file chan_misdn.c.

int g_config_initialized = 0 [static]

TE STUFF END

Definition at line 4028 of file chan_misdn.c.

unsigned long glob_channel = 0 [static]

Definition at line 2660 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 815 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 286 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 816 of file chan_misdn.c.

Referenced by misdn_set_tics().

int* misdn_debug [static]

Definition at line 284 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 285 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 276 of file chan_misdn.c.

Referenced by misdn_set_opt_exec().

int misdn_key_vector_size = 0 [static]

Definition at line 277 of file chan_misdn.c.

Referenced by misdn_set_opt_exec().

struct ast_channel_tech misdn_tech [static]

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

Referenced by misdn_new().

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

Definition at line 270 of file chan_misdn.c.

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

int prefformat = AST_FORMAT_ALAW [static]

Definition at line 280 of file chan_misdn.c.

Referenced by misdn_new(), and misdn_write().

struct robin_list* robin = NULL [static]

Definition at line 209 of file chan_misdn.c.

Referenced by free_robin_list(), and get_robin_position().

struct state_struct state_array[] [static]

Definition at line 656 of file chan_misdn.c.

Referenced by misdn_get_ch_state().

int tracing = 0 [static]

Definition at line 272 of file chan_misdn.c.

Referenced by load_module().

int usecnt = 0 [static]

Definition at line 274 of file chan_misdn.c.

ast_mutex_t usecnt_lock [static]

Definition at line 282 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(), features_new(), 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 Sep 16 07:28:14 2006 for Asterisk - the Open Source PBX by  doxygen 1.4.7