Mon Mar 20 08:20:20 2006

Asterisk developer's documentation


Main Page | Modules | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals | Related Pages

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  chan_list
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 MISDN_ASTERISK_TYPE(ast)   ast->tech->type
#define ORG_AST   1
#define ORG_MISDN   2
#define release_lock   ast_mutex_lock(&release_lock_mutex)
#define release_unlock   ast_mutex_unlock(&release_lock_mutex)

Enumerations

enum  misdn_chan_state {
  MISDN_NOTHING, MISDN_WAITING4DIGS, MISDN_EXTCANTMATCH, MISDN_DIALING,
  MISDN_PROGRESS, MISDN_CALLING, MISDN_CALLING_ACKNOWLEDGE, MISDN_ALERTING,
  MISDN_BUSY, MISDN_CONNECTED, MISDN_BRIDGED, MISDN_CLEANING,
  MISDN_HUNGUP_FROM_MISDN, MISDN_HUNGUP_FROM_AST, MISDN_HOLDED, MISDN_HOLD_DISCONNECT
}

Functions

char * bearer2str (int cap)
enum event_response_e cb_events (enum event_e event, struct misdn_bchannel *bc, void *user_data)
void chan_misdn_log (int level, int port, char *tmpl,...)
void chan_misdn_trace_call (struct ast_channel *chan, int debug, char *tmpl,...)
void cl_dequeue_chan (struct chan_list **list, struct chan_list *chan)
void cl_queue_chan (struct chan_list **list, struct chan_list *chan)
int clearl3_true (void)
char * complete_ch (char *line, char *word, int pos, int state)
char * complete_ch_helper (char *line, char *word, int pos, int state, int rpos)
char * complete_debug_port (char *line, char *word, int pos, int state)
char * description (void)
 Provides a description of the module.
void do_immediate_setup (struct misdn_bchannel *bc, struct chan_list *ch, struct ast_channel *ast)
chan_listfind_chan_by_bc (struct chan_list *list, struct misdn_bchannel *bc)
chan_listfind_chan_by_l3id (struct chan_list *list, unsigned long l3id)
chan_listfind_holded (struct chan_list *list, struct misdn_bchannel *bc)
void free_robin_list (void)
void free_robin_list_r (struct robin_list *r)
chan_listget_chan_by_ast (struct ast_channel *ast)
chan_listget_chan_by_ast_name (char *name)
robin_listget_robin_position (char *group)
chan_listinit_chan_list (void)
char * key (void)
 Returns the ASTERISK_GPL_KEY.
int load_module (void)
 Initialize the module.
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)
int misdn_call (struct ast_channel *ast, char *dest, int timeout)
int misdn_digit (struct ast_channel *ast, char digit)
int misdn_facility_exec (struct ast_channel *chan, void *data)
int misdn_fixup (struct ast_channel *oldast, struct ast_channel *ast)
char * misdn_get_ch_state (struct chan_list *p)
int misdn_hangup (struct ast_channel *ast)
int misdn_indication (struct ast_channel *ast, int cond)
ast_channelmisdn_new (struct chan_list *cl, int state, char *name, char *context, char *exten, char *callerid, int format, int port, int c)
int misdn_port_up (int fd, int argc, char *argv[])
ast_framemisdn_read (struct ast_channel *ast)
int misdn_reload (int fd, int argc, char *argv[])
ast_channelmisdn_request (const char *type, int format, void *data, int *cause)
int misdn_restart_port (int fd, int argc, char *argv[])
int misdn_send_cd (int fd, int argc, char *argv[])
int misdn_send_digit (int fd, int argc, char *argv[])
int misdn_send_display (int fd, int argc, char *argv[])
int misdn_set_crypt_debug (int fd, int argc, char *argv[])
int misdn_set_debug (int fd, int argc, char *argv[])
int misdn_set_opt_exec (struct ast_channel *chan, void *data)
int misdn_set_tics (int fd, int argc, char *argv[])
int misdn_show_cl (int fd, int argc, char *argv[])
int misdn_show_cls (int fd, int argc, char *argv[])
int misdn_show_config (int fd, int argc, char *argv[])
int misdn_show_port (int fd, int argc, char *argv[])
int misdn_show_stacks (int fd, int argc, char *argv[])
int misdn_toggle_echocancel (int fd, int argc, char *argv[])
int misdn_transfer (struct ast_channel *ast, char *dest)
void misdn_transfer_bc (struct chan_list *tmp_ch, struct chan_list *holded_chan)
int misdn_tx2ast_frm (struct chan_list *tmp, char *buf, int len)
int misdn_write (struct ast_channel *ast, struct ast_frame *frame)
void print_bc_info (int fd, struct chan_list *help, struct misdn_bchannel *bc)
void print_bearer (struct misdn_bchannel *bc)
void release_chan (struct misdn_bchannel *bc)
void send_cause2ast (struct ast_channel *ast, struct misdn_bchannel *bc)
void send_digit_to_chan (struct chan_list *cl, char digit)
int start_bc_tones (struct chan_list *cl)
int stop_bc_tones (struct chan_list *cl)
char * tone2str (struct misdn_bchannel *bc)
int unload_module (void)
 Cleanup all module structures, sockets, etc.
int usecount (void)
 Provides a usecount.

Variables

chan_listcl_te = NULL
ast_mutex_t cl_te_lock
ast_cli_entry cli_port_up
ast_cli_entry cli_reload
ast_cli_entry cli_restart_port
ast_cli_entry cli_send_cd
ast_cli_entry cli_send_digit
ast_cli_entry cli_send_display
ast_cli_entry cli_set_crypt_debug
ast_cli_entry cli_set_debug
ast_cli_entry cli_set_tics
ast_cli_entry cli_show_cl
ast_cli_entry cli_show_cls
ast_cli_entry cli_show_config
ast_cli_entry cli_show_port
ast_cli_entry cli_show_stacks
ast_cli_entry cli_toggle_echocancel
char * desc = "Channel driver for mISDN Support (Bri/Pri)"
chan_list dummy_cl
int g_config_initialized = 0
unsigned long glob_channel = 0
ast_mutex_t lock
int max_ports
int MAXTICS = 8
int * misdn_debug
int * misdn_debug_only
char ** misdn_key_vector = NULL
int misdn_key_vector_size = 0
ast_channel_tech misdn_tech
ast_channel_tech misdn_tech_wo_bridge
int prefformat = AST_FORMAT_ALAW
ast_mutex_t release_lock_mutex
robin_listrobin = NULL
state_struct state_array []
int tracing = 0
char * type = "mISDN"
int usecnt = 0
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 181 of file chan_misdn.c.

Referenced by cb_events(), and misdn_transfer_bc().

#define AST_CID_P ast   )     ast->cid.cid_num
 

Definition at line 180 of file chan_misdn.c.

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

#define AST_DESTROY_CFG   ast_config_destroy
 

Definition at line 183 of file chan_misdn.c.

Referenced by misdn_cfg_init().

#define AST_LOAD_CFG   ast_config_load
 

Definition at line 182 of file chan_misdn.c.

Referenced by misdn_cfg_init().

#define MISDN_ASTERISK_PVT ast   )     1
 

Definition at line 186 of file chan_misdn.c.

Referenced by cb_events(), do_immediate_setup(), misdn_answer(), misdn_digit(), misdn_fixup(), misdn_indication(), misdn_transfer(), misdn_tx2ast_frm(), and release_chan().

#define MISDN_ASTERISK_TECH_PVT ast   )     ast->tech_pvt
 

Definition at line 185 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_transfer(), misdn_tx2ast_frm(), misdn_write(), and release_chan().

#define MISDN_ASTERISK_TYPE ast   )     ast->tech->type
 

Definition at line 187 of file chan_misdn.c.

Referenced by misdn_facility_exec(), and misdn_set_opt_exec().

#define ORG_AST   1
 

Definition at line 94 of file chan_misdn.c.

Referenced by print_bc_info().

#define ORG_MISDN   2
 

Definition at line 95 of file chan_misdn.c.

#define release_lock   ast_mutex_lock(&release_lock_mutex)
 

Definition at line 67 of file chan_misdn.c.

#define release_unlock   ast_mutex_unlock(&release_lock_mutex)
 

Definition at line 68 of file chan_misdn.c.


Enumeration Type Documentation

enum misdn_chan_state
 

Enumeration values:
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_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_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 73 of file chan_misdn.c.

00073                       {
00074    MISDN_NOTHING,    /*!< at beginning */
00075    MISDN_WAITING4DIGS, /*!<  when waiting for infos */
00076    MISDN_EXTCANTMATCH, /*!<  when asterisk couldnt match our ext */
00077    MISDN_DIALING, /*!<  when pbx_start */
00078    MISDN_PROGRESS, /*!<  we got a progress */
00079    MISDN_CALLING, /*!<  when misdn_call is called */
00080    MISDN_CALLING_ACKNOWLEDGE, /*!<  when we get SETUP_ACK */
00081    MISDN_ALERTING, /*!<  when Alerting */
00082    MISDN_BUSY, /*!<  when BUSY */
00083    MISDN_CONNECTED, /*!<  when connected */
00084    MISDN_BRIDGED, /*!<  when bridged */
00085    MISDN_CLEANING, /*!< when hangup from * but we were connected before */
00086    MISDN_HUNGUP_FROM_MISDN, /*!< when DISCONNECT/RELEASE/REL_COMP  cam from misdn */
00087    MISDN_HUNGUP_FROM_AST, /*!< when DISCONNECT/RELEASE/REL_COMP came out of */
00088    /* misdn_hangup */
00089    MISDN_HOLDED, /*!< if this chan is holded */
00090    MISDN_HOLD_DISCONNECT /*!< if this chan is holded */
00091   
00092 };


Function Documentation

char* bearer2str int  cap  )  [static]
 

Definition at line 281 of file chan_misdn.c.

Referenced by print_bc_info(), and print_bearer().

00281                                  {
00282    static char *bearers[]={
00283       "Speech",
00284       "Audio 3.1k",
00285       "Unres Digital",
00286       "Res Digital",
00287       "Unknown Bearer"
00288    };
00289    
00290    switch (cap) {
00291    case INFO_CAPABILITY_SPEECH:
00292       return bearers[0];
00293       break;
00294    case INFO_CAPABILITY_AUDIO_3_1K:
00295       return bearers[1];
00296       break;
00297    case INFO_CAPABILITY_DIGITAL_UNRESTRICTED:
00298       return bearers[2];
00299       break;
00300    case INFO_CAPABILITY_DIGITAL_RESTRICTED:
00301       return bearers[3];
00302       break;
00303    default:
00304       return bearers[4];
00305       break;
00306    }
00307 }

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

queue new chan *

from here on we start the PBX, so no configuration should be considered anymore

Sending SETUP_ACK*

Now after we've finished configuring our channel object we'll jump into the dialplan *

Suplementary Services *

Definition at line 2623 of file chan_misdn.c.

References chan_list::addr, chan_list::ast, AST_BRIDGED_P, ast_canmatch_extension(), ast_cdr_update(), AST_CONTROL_ANSWER, AST_CONTROL_PROGRESS, AST_CONTROL_RINGING, ast_exists_extension(), AST_FORMAT_ALAW, ast_hangup(), ast_log(), ast_moh_start(), ast_moh_stop(), ast_pbx_start(), ast_pickup_call(), ast_pickup_ext(), ast_queue_control(), ast_queue_frame(), ast_setstate(), AST_STATE_DOWN, AST_STATE_RING, AST_STATE_RINGING, ast_strlen_zero(), ast_transfercapability2str(), chan_list::bc, chan_misdn_log(), chan_misdn_trace_call(), ast_channel::cid, ast_callerid::cid_pres, cl_queue_chan(), cl_te, ast_frame::data, ast_frame::datalen, do_immediate_setup(), ast_channel::exten, find_chan_by_bc(), find_chan_by_l3id(), find_holded(), ast_frame::frametype, free, init_chan_list(), chan_list::l3id, ast_channel::language, LOG_DEBUG, LOG_WARNING, ast_frame::mallocd, MISDN_ASTERISK_PVT, MISDN_ASTERISK_TECH_PVT, MISDN_CALLING, misdn_cfg_get(), misdn_cfg_is_msn_valid(), MISDN_DIALING, misdn_new(), MISDN_PROGRESS, misdn_transfer_bc(), misdn_tx2ast_frm(), name, ast_frame::offset, chan_list::orginator, pbx_builtin_setvar_helper(), chan_list::pipe, print_bearer(), release_chan(), ast_frame::samples, send_cause2ast(), ast_frame::src, start_bc_tones(), stop_bc_tones(), ast_frame::subclass, ast_channel::transfercapability, and tv.

02624 {
02625    struct chan_list *ch=find_chan_by_bc(cl_te, bc);
02626    
02627    if (!ch)
02628       ch=find_chan_by_l3id(cl_te, bc->l3_id);
02629    
02630    if (event != EVENT_BCHAN_DATA) { /*  Debug Only Non-Bchan */
02631       chan_misdn_log(1, bc->port, "I IND :%s oad:%s dad:%s port:%d\n", manager_isdn_get_info(event), bc->oad, bc->dad, bc->port);
02632       misdn_lib_log_ies(bc);
02633    }
02634    
02635    if (event != EVENT_SETUP) {
02636       if (!ch) {
02637          if (event != EVENT_CLEANUP )
02638             ast_log(LOG_WARNING, "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);
02639          return -1;
02640       }
02641    }
02642    
02643    if (ch ) {
02644       switch (event) {
02645       case EVENT_RELEASE:
02646       case EVENT_RELEASE_COMPLETE:
02647       case EVENT_CLEANUP:
02648          break;
02649       default:
02650          if ( !ch->ast  || !MISDN_ASTERISK_PVT(ch->ast) || !MISDN_ASTERISK_TECH_PVT(ch->ast)) {
02651             if (event!=EVENT_BCHAN_DATA)
02652                ast_log(LOG_WARNING, "No Ast or No private Pointer in Event (%d:%s)\n", event, manager_isdn_get_info(event));
02653             return -1;
02654          }
02655       }
02656    }
02657    
02658    
02659    switch (event) {
02660    case EVENT_NEW_L3ID:
02661       ch->l3id=bc->l3_id;
02662       break;
02663 
02664    case EVENT_NEW_BC:
02665       if (bc)
02666          ch->bc=bc;
02667       break;
02668       
02669    case EVENT_DTMF_TONE:
02670    {
02671       /*  sending INFOS as DTMF-Frames :) */
02672       struct ast_frame fr;
02673       memset(&fr, 0 , sizeof(fr));
02674       fr.frametype = AST_FRAME_DTMF;
02675       fr.subclass = bc->dtmf ;
02676       fr.src=NULL;
02677       fr.data = NULL ;
02678       fr.datalen = 0;
02679       fr.samples = 0 ;
02680       fr.mallocd =0 ;
02681       fr.offset= 0 ;
02682       
02683       chan_misdn_log(2, bc->port, " --> DTMF:%c\n", bc->dtmf);
02684       
02685       ast_queue_frame(ch->ast, &fr);
02686    }
02687    break;
02688    case EVENT_STATUS:
02689       break;
02690     
02691    case EVENT_INFORMATION:
02692    {
02693       int stop_tone;
02694       misdn_cfg_get( 0, MISDN_GEN_STOP_TONE, &stop_tone, sizeof(int));
02695       if ( stop_tone && bc->tone != TONE_NONE) {
02696          manager_send_tone(bc,TONE_NONE);
02697       }
02698       
02699       if (ch->state == MISDN_WAITING4DIGS ) {
02700          /*  Ok, incomplete Setup, waiting till extension exists */
02701          {
02702             int l = sizeof(bc->dad);
02703             strncat(bc->dad,bc->info_dad, l);
02704             bc->dad[l-1] = 0;
02705          }
02706          
02707          
02708          {
02709             int l = sizeof(ch->ast->exten);
02710             strncpy(ch->ast->exten, bc->dad, l);
02711             ch->ast->exten[l-1] = 0;
02712          }
02713 /*       chan_misdn_log(5, bc->port, "Can Match Extension: dad:%s oad:%s\n",bc->dad,bc->oad);*/
02714          
02715          char bc_context[BUFFERSIZE];
02716          misdn_cfg_get( bc->port, MISDN_CFG_CONTEXT, bc_context, BUFFERSIZE);
02717          if(!ast_canmatch_extension(ch->ast, bc_context, bc->dad, 1, bc->oad)) {
02718             chan_misdn_log(0, bc->port, "Extension can never match, so disconnecting\n");
02719             manager_send_tone(bc,TONE_BUSY);
02720             ch->state=MISDN_EXTCANTMATCH;
02721             bc->out_cause=1;
02722             if (bc->nt)
02723                misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE );
02724             else
02725                misdn_lib_send_event(bc, EVENT_DISCONNECT );
02726             break;
02727          }
02728          if (ast_exists_extension(ch->ast, bc_context, bc->dad, 1, bc->oad)) {
02729             ch->state=MISDN_DIALING;
02730      
02731             manager_send_tone(bc,TONE_NONE);
02732 /*          chan_misdn_log(1, bc->port, " --> * Starting Ast ctx:%s\n", ch->ast->context);*/
02733             if (ast_pbx_start(ch->ast)<0) {
02734                chan_misdn_log(0, bc->port, "ast_pbx_start returned < 0 in INFO\n");
02735                manager_send_tone(bc,TONE_BUSY);
02736                if (bc->nt)
02737                   misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE );
02738                else
02739                   misdn_lib_send_event(bc, EVENT_DISCONNECT );
02740             }
02741          }
02742    
02743       } else {
02744          /*  sending INFOS as DTMF-Frames :) */
02745          struct ast_frame fr;
02746          fr.frametype = AST_FRAME_DTMF;
02747          fr.subclass = bc->info_dad[0] ;
02748          fr.src=NULL;
02749          fr.data = NULL ;
02750          fr.datalen = 0;
02751          fr.samples = 0 ;
02752          fr.mallocd =0 ;
02753          fr.offset= 0 ;
02754 
02755          
02756          int digits;
02757          misdn_cfg_get( 0, MISDN_GEN_APPEND_DIGITS2EXTEN, &digits, sizeof(int));
02758          if (ch->state != MISDN_CONNECTED ) {
02759             if (digits) {
02760                int l = sizeof(bc->dad);
02761                strncat(bc->dad,bc->info_dad, l);
02762                bc->dad[l-1] = 0;
02763                l = sizeof(ch->ast->exten);
02764                strncpy(ch->ast->exten, bc->dad, l);
02765                ch->ast->exten[l-1] = 0;
02766 
02767                ast_cdr_update(ch->ast);
02768             }
02769             
02770             ast_queue_frame(ch->ast, &fr);
02771          }
02772          
02773       }
02774    }
02775    break;
02776    case EVENT_SETUP:
02777    {
02778       struct chan_list *ch=find_chan_by_bc(cl_te, bc);
02779       if (ch && ch->state != MISDN_NOTHING ) {
02780          chan_misdn_log(1, bc->port, " --> Ignoring Call we have already one\n");
02781          return RESPONSE_IGNORE_SETUP_WITHOUT_CLOSE; /*  Ignore MSNs which are not in our List */
02782       }
02783    }
02784    
02785    int msn_valid = misdn_cfg_is_msn_valid(bc->port, bc->dad);
02786    if (!bc->nt && ! msn_valid) {
02787       chan_misdn_log(1, bc->port, " --> Ignoring Call, its not in our MSN List\n");
02788       return RESPONSE_IGNORE_SETUP; /*  Ignore MSNs which are not in our List */
02789    }
02790    
02791    print_bearer(bc);
02792     
02793    {
02794       struct chan_list *ch=init_chan_list();
02795       struct ast_channel *chan;
02796       char name[128];
02797       if (!ch) { chan_misdn_log(0, bc->port, "cb_events: malloc for chan_list failed!\n"); return 0;}
02798       
02799       ch->bc = bc;
02800       ch->l3id=bc->l3_id;
02801       ch->addr=bc->addr;
02802       ch->orginator = ORG_MISDN;
02803 
02804       
02805       {
02806          char prefix[BUFFERSIZE]="";
02807          switch( bc->onumplan ) {
02808          case NUMPLAN_INTERNATIONAL:
02809             misdn_cfg_get( bc->port, MISDN_CFG_INTERNATPREFIX, prefix, BUFFERSIZE);
02810             break;
02811      
02812          case NUMPLAN_NATIONAL:
02813             misdn_cfg_get( bc->port, MISDN_CFG_NATPREFIX, prefix, BUFFERSIZE);
02814             break;
02815      
02816      
02817          case NUMPLAN_SUBSCRIBER:
02818             /* dunno what to do here ? */
02819             break;
02820 
02821          case NUMPLAN_UNKNOWN:
02822             break;
02823          default:
02824             break;
02825          }
02826 
02827          {
02828             int l = strlen(prefix) + strlen(bc->oad);
02829             char tmp[l+1];
02830             strcpy(tmp,prefix);
02831             strcat(tmp,bc->oad);
02832             strcpy(bc->oad,tmp);
02833          }
02834          
02835          if (!ast_strlen_zero(bc->oad))
02836             sprintf(name,"mISDN/%d/%s",bc->port,bc->oad);
02837          else
02838             sprintf(name,"mISDN/%d",bc->port);
02839 
02840 
02841          if (!ast_strlen_zero(bc->dad)) {
02842             strncpy(bc->orig_dad,bc->dad, sizeof(bc->orig_dad));
02843             bc->orig_dad[sizeof(bc->orig_dad)-1] = 0;
02844          }
02845          
02846          if ( ast_strlen_zero(bc->dad) && !ast_strlen_zero(bc->keypad)) {
02847             strncpy(bc->dad,bc->keypad, sizeof(bc->dad));
02848             bc->dad[sizeof(bc->dad)-1] = 0;
02849          }
02850          prefix[0] = 0;
02851          
02852          switch( bc->dnumplan ) {
02853          case NUMPLAN_INTERNATIONAL:
02854             misdn_cfg_get( bc->port, MISDN_CFG_INTERNATPREFIX, prefix, BUFFERSIZE);
02855             break;
02856             
02857          case NUMPLAN_NATIONAL:
02858             misdn_cfg_get( bc->port, MISDN_CFG_NATPREFIX, prefix, BUFFERSIZE);
02859             break;
02860             
02861             
02862          case NUMPLAN_SUBSCRIBER:
02863             /* dunno what to do here ? */
02864             break;
02865             
02866          case NUMPLAN_UNKNOWN:
02867             break;
02868          default:
02869             break;
02870          }
02871       
02872          {
02873             int l = strlen(prefix) + strlen(bc->dad);
02874             char tmp[l+1];
02875             strcpy(tmp,prefix);
02876             strcat(tmp,bc->dad);
02877             strcpy(bc->dad,tmp);
02878          }
02879          
02880          char bc_context[BUFFERSIZE];
02881          misdn_cfg_get( bc->port, MISDN_CFG_CONTEXT, bc_context, BUFFERSIZE);
02882          chan=misdn_new(ch, AST_STATE_RING,name ,bc_context, bc->dad, bc->oad, AST_FORMAT_ALAW, bc->port, bc->channel);
02883          
02884          if (!chan) {
02885             misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE );
02886             return 0;
02887          }
02888          
02889          ch->ast = chan;
02890          pbx_builtin_setvar_helper(ch->ast,"REDIRECTING_NUMBER",bc->rad);
02891          
02892       }
02893 
02894       
02895 
02896       chan_misdn_trace_call(chan,1,"I->*: EVENT_SETUP\n");
02897       
02898       if ( bc->pres ) {
02899          chan->cid.cid_pres=AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED;
02900       }  else {
02901          chan->cid.cid_pres=AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN;
02902       }
02903       
02904       pbx_builtin_setvar_helper(chan, "TRANSFERCAPABILITY", ast_transfercapability2str(bc->capability));
02905       chan->transfercapability=bc->capability;
02906       
02907       switch (bc->capability) {
02908       case INFO_CAPABILITY_DIGITAL_UNRESTRICTED:
02909          pbx_builtin_setvar_helper(chan,"CALLTYPE","DIGITAL");
02910          break;
02911       default:
02912          pbx_builtin_setvar_helper(chan,"CALLTYPE","SPEECH");
02913       }
02914 
02915       /** queue new chan **/
02916       cl_queue_chan(&cl_te, ch) ;
02917 
02918       
02919       /*
02920         added support for s extension hope it will help those poor cretains
02921         which haven't overlap dial.
02922       */
02923       {
02924          
02925          misdn_cfg_get( bc->port, MISDN_CFG_LANGUAGE, chan->language, sizeof(chan->language));        
02926          
02927       }
02928 
02929       {
02930          int eb3;
02931          
02932          misdn_cfg_get( bc->port, MISDN_CFG_EARLY_BCONNECT, &eb3, sizeof(int));
02933          bc->early_bconnect=eb3;
02934          
02935       }
02936 
02937       {
02938          int ec, ectr;
02939          
02940          misdn_cfg_get( bc->port, MISDN_CFG_ECHOCANCEL, &ec, sizeof(int));
02941          
02942          misdn_cfg_get( bc->port, MISDN_CFG_ECHOTRAINING, &ectr, sizeof(int));
02943          if (ec == 1 ) {
02944             bc->ec_enable=1;
02945          } else if ( ec > 1 ) {
02946             bc->ec_enable=1;
02947             bc->ec_deftaps=ec;
02948          }
02949          
02950          if ( ectr>=0 ) {
02951             bc->ec_training=ectr;
02952          }
02953       }
02954       
02955 
02956       if (bc->urate>0) {
02957          char buf[16];
02958          snprintf(buf,16,"%d",bc->urate);
02959          pbx_builtin_setvar_helper(chan,"MISDN_URATE",buf);
02960       }
02961 
02962 
02963 
02964       /**
02965          from here on  we start the PBX, so no configuration should
02966          be considered anymore
02967       **/
02968       
02969       int ai;
02970       misdn_cfg_get( bc->port, MISDN_CFG_ALWAYS_IMMEDIATE, &ai, sizeof(ai));
02971       if ( ai ) {
02972          do_immediate_setup(bc, ch , chan);
02973          break;
02974       }
02975       
02976          
02977       int immediate;
02978       misdn_cfg_get( bc->port, MISDN_CFG_IMMEDIATE, &immediate, sizeof(int));
02979       
02980       if (ast_strlen_zero(bc->orig_dad) && immediate ) {
02981          do_immediate_setup(bc, ch , chan);
02982          break;
02983       }
02984       
02985       /* Check for Pickup Request first */
02986       if (!strcmp(chan->exten, ast_pickup_ext())) {
02987          int ret;/** Sending SETUP_ACK**/
02988          ret = misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE );
02989    
02990          if (ast_pickup_call(chan)) {
02991             ast_hangup(chan);
02992          } else {
02993             ch->state = MISDN_CALLING_ACKNOWLEDGE;
02994      
02995             ch->ast=NULL;
02996      
02997             ast_setstate(chan, AST_STATE_DOWN);
02998             ast_hangup(chan); 
02999      
03000             break;
03001          }
03002       }
03003       
03004       /** Now after we've finished configuring our channel object
03005           we'll jump into the dialplan **/
03006       
03007       char bc_context[BUFFERSIZE];
03008       misdn_cfg_get( bc->port, MISDN_CFG_CONTEXT, bc_context, BUFFERSIZE);
03009       if(!ast_canmatch_extension(ch->ast, bc_context, bc->dad, 1, bc->oad)) {
03010          chan_misdn_log(0, bc->port, "Extension can never match, so disconnecting\n");
03011          manager_send_tone(bc,TONE_BUSY);
03012          ch->state=MISDN_EXTCANTMATCH;
03013          bc->out_cause=1;
03014          if (bc->nt)
03015             misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE );
03016          else
03017             misdn_lib_send_event(bc, EVENT_DISCONNECT );
03018          break;
03019       }
03020       
03021       if (ast_exists_extension(ch->ast, bc_context, bc->dad, 1, bc->oad)) {
03022          ch->state=MISDN_DIALING;
03023    
03024          if (bc->nt) {
03025             int ret; 
03026             ret = misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE );
03027          } else {
03028             int ret;
03029             ret= misdn_lib_send_event(bc, EVENT_PROCEEDING );
03030          }
03031    
03032          if (ast_pbx_start(chan)<0) {
03033             chan_misdn_log(0, bc->port, "ast_pbx_start returned <0 in SETUP\n");
03034             chan=NULL;
03035             manager_send_tone(bc,TONE_BUSY);
03036             if (bc->nt)
03037                misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE );
03038             else
03039                misdn_lib_send_event(bc, EVENT_DISCONNECT );
03040          }
03041       } else {
03042          int ret= misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE );
03043          if (ret == -ENOCHAN) {
03044             ast_log(LOG_WARNING,"Channel was catched, before we could Acknowledge\n");
03045             misdn_lib_send_event(bc,EVENT_RELEASE_COMPLETE);
03046          }
03047          /*  send tone to phone :) */
03048          
03049          int stop_tone;
03050          misdn_cfg_get( 0, MISDN_GEN_STOP_TONE, &stop_tone, sizeof(int));
03051          if ( (!ast_strlen_zero(bc->dad)) && stop_tone ) 
03052             manager_send_tone(bc,TONE_NONE);
03053          else
03054             manager_send_tone(bc,TONE_DIAL);
03055    
03056          ch->state=MISDN_WAITING4DIGS;
03057       }
03058       
03059    }
03060    break;
03061    case EVENT_SETUP_ACKNOWLEDGE:
03062    {
03063       ch->state = MISDN_CALLING_ACKNOWLEDGE;
03064       if (!ast_strlen_zero(bc->infos_pending)) {
03065          /* TX Pending Infos */
03066          
03067          {
03068             int l = sizeof(bc->dad);
03069             strncat(bc->dad,bc->infos_pending, l - strlen(bc->dad));
03070             bc->dad[l-1] = 0;
03071          }  
03072          {
03073             int l = sizeof(ch->ast->exten);
03074             strncpy(ch->ast->exten, bc->dad, l);
03075             ch->ast->exten[l-1] = 0;
03076          }
03077          {
03078             int l = sizeof(bc->info_dad);
03079             strncpy(bc->info_dad, bc->infos_pending, l);
03080             bc->info_dad[l-1] = 0;
03081          }
03082          strncpy(bc->infos_pending,"", 1);
03083 
03084          misdn_lib_send_event(bc, EVENT_INFORMATION);
03085       }
03086    }
03087    break;
03088    case EVENT_PROCEEDING:
03089    {
03090       
03091       if ( misdn_cap_is_speech(bc->capability) &&
03092            misdn_inband_avail(bc) ) {
03093          start_bc_tones(ch);
03094       }
03095    }
03096    break;
03097    case EVENT_PROGRESS:
03098       if (!bc->nt ) {
03099          if ( misdn_cap_is_speech(bc->capability) &&
03100               misdn_inband_avail(bc)
03101             ) {
03102             start_bc_tones(ch);
03103          }
03104          
03105          ast_queue_control(ch->ast, AST_CONTROL_PROGRESS);
03106          
03107          ch->state=MISDN_PROGRESS;
03108       }
03109       break;
03110       
03111       
03112    case EVENT_ALERTING:
03113    {
03114       ch->state = MISDN_ALERTING;
03115       
03116       ast_queue_control(ch->ast, AST_CONTROL_RINGING);
03117       ast_setstate(ch->ast, AST_STATE_RINGING);
03118       
03119       cb_log(1,bc->port,"Set State Ringing\n");
03120       
03121       if ( misdn_cap_is_speech(bc->capability) && misdn_inband_avail(bc)) {
03122           start_bc_tones(ch);
03123        }
03124    }
03125    break;
03126    case EVENT_CONNECT:
03127       misdn_lib_send_event(bc,EVENT_CONNECT_ACKNOWLEDGE);
03128    case EVENT_CONNECT_ACKNOWLEDGE:
03129    {
03130       bc->state=STATE_CONNECTED;
03131       
03132       ch->l3id=bc->l3_id;
03133       ch->addr=bc->addr;
03134       
03135       start_bc_tones(ch);
03136       
03137       chan_misdn_trace_call(ch->ast,1,"I->*: EVENT_CONNECT\n");
03138       
03139       ch->state = MISDN_CONNECTED;
03140       ast_queue_control(ch->ast, AST_CONTROL_ANSWER);
03141    }
03142    break;
03143    case EVENT_DISCONNECT:
03144    {
03145       
03146       struct chan_list *holded_ch=find_holded(cl_te, bc);
03147       
03148       
03149       send_cause2ast(ch->ast,bc);
03150 
03151       if (misdn_inband_avail(bc) && ch->state != MISDN_CONNECTED) {
03152          /* If there's inband information available (e.g. a
03153             recorded message saying what was wrong with the
03154             dialled number, or perhaps even giving an
03155             alternative number, then play it instead of
03156             immediately releasing the call */
03157          start_bc_tones(ch);
03158          break;
03159       }
03160       
03161       /*Check for holded channel, to implement transfer*/
03162       if (holded_ch ) {
03163          if  (ch->state == MISDN_CONNECTED ) {
03164             misdn_transfer_bc(ch, holded_ch) ;
03165             misdn_lib_send_event(bc,EVENT_RELEASE_COMPLETE);
03166             break;
03167          }
03168       }
03169       
03170       stop_bc_tones(ch);
03171       bc->out_cause=16;
03172       misdn_lib_send_event(bc,EVENT_RELEASE);
03173       
03174    }
03175    break;
03176    
03177    case EVENT_RELEASE:
03178       {
03179          
03180          switch ( bc->cause) {
03181             
03182          case -1:
03183             /*
03184               OK, it really sucks, this is a RELEASE from NT-Stack So we take
03185               it and return easylie, It seems that we've send a DISCONNECT
03186               before, so we should RELEASE_COMPLETE after that Disconnect
03187               (looks like ALERTING State at misdn_hangup !!
03188             */
03189             return RESPONSE_OK;
03190             break;
03191          }
03192          
03193          
03194          bc->out_cause=16;
03195          
03196          stop_bc_tones(ch);
03197          release_chan(bc);
03198       }
03199       break;
03200    case EVENT_RELEASE_COMPLETE:
03201    {
03202       stop_bc_tones(ch);
03203       release_chan(bc);
03204    }
03205    break;
03206    
03207    case EVENT_BCHAN_DATA:
03208    {
03209       chan_misdn_trace_call(ch->ast,3,"I->*: EVENT_B_DATA len=%d\n",bc->bframe_len);
03210       
03211       if ( !misdn_cap_is_speech(ch->bc->capability) || bc->nojitter) {
03212          misdn_tx2ast_frm(ch, bc->bframe, bc->bframe_len );
03213       } else {
03214          int len=bc->bframe_len;
03215          int free=misdn_ibuf_freecount(bc->astbuf);
03216          
03217          
03218          if (bc->bframe_len > free) {
03219             ast_log(LOG_DEBUG, "sbuf overflow!\n");
03220             len=misdn_ibuf_freecount(bc->astbuf);
03221 
03222             if (len == 0) {
03223                ast_log(LOG_WARNING, "BCHAN_DATA: write buffer overflow port:%d channel:%d!\n",bc->port,bc->channel);
03224             }
03225          }
03226          
03227          misdn_ibuf_memcpy_w(bc->astbuf, bc->bframe, len);
03228          
03229          {
03230             char blah[1]="\0";
03231 #ifdef FLATTEN_JITTER
03232             {
03233                struct timeval tv;
03234                gettimeofday(&tv,NULL);
03235                
03236                if (tv.tv_usec % 10000 > 0 ) {
03237                   write(ch->pipe[1], blah,sizeof(blah));
03238                   bc->time_usec=tv.tv_usec;
03239                }
03240             }
03241 #else
03242             write(ch->pipe[1], blah,sizeof(blah));
03243 #endif
03244             
03245             
03246          }
03247       }
03248       
03249    }
03250    break;
03251    case EVENT_TIMEOUT:
03252       break; /* Ignore now .. */
03253       {
03254          switch (ch->state) {
03255          case MISDN_CALLING:
03256             chan_misdn_log(0, bc?bc->port:0, "GOT TIMOUT AT CALING pid:%d\n", bc?bc->pid:-1);
03257                break;
03258          case MISDN_DIALING:
03259          case MISDN_PROGRESS:
03260             break;
03261          default:
03262             misdn_lib_send_event(bc,EVENT_RELEASE_COMPLETE);
03263          }
03264       }
03265       break;
03266    case EVENT_CLEANUP:
03267    {
03268       stop_bc_tones(ch);
03269       release_chan(bc);
03270    }
03271    break;
03272     
03273    /***************************/
03274    /** Suplementary Services **/
03275    /***************************/
03276    case EVENT_RETRIEVE:
03277    {
03278       struct ast_channel *hold_ast=AST_BRIDGED_P(ch->ast);
03279       ch->state = MISDN_CONNECTED;
03280       
03281       if (hold_ast) {
03282          ast_moh_stop(hold_ast);
03283       }
03284       
03285       if ( misdn_lib_send_event(bc, EVENT_RETRIEVE_ACKNOWLEDGE) < 0)
03286          misdn_lib_send_event(bc, EVENT_RETRIEVE_REJECT);
03287       
03288       
03289    }
03290    break;
03291     
03292    case EVENT_HOLD:
03293    {
03294       int hold_allowed;
03295       misdn_cfg_get( bc->port, MISDN_CFG_HOLD_ALLOWED, &hold_allowed, sizeof(int));
03296       
03297       if (!hold_allowed) {
03298          chan_misdn_log(0, bc->port, "Hold not allowed on port:%d\n", bc->port);
03299          misdn_lib_send_event(bc, EVENT_HOLD_REJECT);
03300          break;
03301       }
03302 
03303       {
03304          struct chan_list *holded_ch=find_holded(cl_te, bc);
03305          if (holded_ch) {
03306             misdn_lib_send_event(bc, EVENT_HOLD_REJECT);
03307             chan_misdn_log(0, bc->port, "We can't use RETRIEVE at the moment due to mISDN bug!\n");
03308             break;
03309          }
03310       }
03311       
03312       if (AST_BRIDGED_P(ch->ast)){
03313          ch->state = MISDN_HOLDED;
03314          ch->l3id = bc->l3_id;
03315          
03316          ast_moh_start(AST_BRIDGED_P(ch->ast), NULL);
03317          misdn_lib_send_event(bc, EVENT_HOLD_ACKNOWLEDGE);
03318       } else {
03319          misdn_lib_send_event(bc, EVENT_HOLD_REJECT);
03320          chan_misdn_log(0, bc->port, "We aren't bridged to anybody\n");
03321       }
03322    } 
03323    break;
03324    default:
03325       ast_log(LOG_WARNING, "Got Unknown Event\n");
03326       break;
03327    }
03328    
03329    return RESPONSE_OK;
03330 }

void chan_misdn_log int  level,
int  port,
char *  tmpl,
  ...
 

Definition at line 3512 of file chan_misdn.c.

References ast_console_puts(), ast_log(), LOG_WARNING, misdn_cfg_get(), misdn_debug, and misdn_debug_only.

Referenced by cb_events(), cl_queue_chan(), do_immediate_setup(), find_chan_by_bc(), find_chan_by_l3id(), find_holded(), init_chan_list(), load_module(), misdn_answer(), misdn_bridge(), misdn_call(), misdn_digit(), misdn_fixup(), misdn_hangup(), misdn_indication(), misdn_new(), misdn_reload(), misdn_request(), misdn_set_opt_exec(), misdn_show_cls(), misdn_transfer(), misdn_transfer_bc(), misdn_tx2ast_frm(), misdn_write(), print_bearer(), release_chan(), and send_cause2ast().

03513 {
03514    if (! ((0 <= port) && (port <= max_ports))) {
03515       ast_log(LOG_WARNING, "cb_log called with out-of-range port number! (%d)\n", port);
03516       return;
03517    }
03518       
03519    va_list ap;
03520    char buf[1024];
03521   
03522    va_start(ap, tmpl);
03523    vsnprintf( buf, 1023, tmpl, ap );
03524    va_end(ap);
03525    
03526    if (misdn_debug_only[port] ? (level==1 && misdn_debug[port]) || (level==misdn_debug[port]) : level <= misdn_debug[port]) {
03527       ast_console_puts(buf);
03528    }
03529    
03530    if (level <= misdn_debug[0] && tracing) {
03531       time_t tm = time(NULL);
03532       char *tmp=ctime(&tm),*p;
03533       char file[BUFFERSIZE];
03534       misdn_cfg_get( 0, MISDN_GEN_TRACEFILE, file, BUFFERSIZE);
03535       FILE *fp= fopen(file, "a+");
03536 
03537       p=strchr(tmp,'\n');
03538       if (p) *p=':';
03539     
03540       if (!fp) {
03541          ast_console_puts("Error opening Tracefile: ");
03542          ast_console_puts(strerror(errno));
03543          ast_console_puts("\n");
03544          return ;
03545       }
03546       
03547       fputs(tmp,fp);
03548       fputs(" ", fp);
03549       fputs(buf, fp);
03550 
03551       fclose(fp);
03552    }
03553 }

void chan_misdn_trace_call struct ast_channel chan,
int  debug,
char *  tmpl,
  ...
 

Definition at line 3556 of file chan_misdn.c.

References ast_console_puts(), ast_channel::cid, ast_callerid::cid_num, misdn_cfg_get(), misdn_debug, name, and ast_channel::uniqueid.

Referenced by cb_events(), misdn_answer(), misdn_call(), misdn_hangup(), misdn_read(), misdn_write(), and release_chan().

03557 {
03558    va_list ap;
03559    char buf[1024];
03560    char name[1024];
03561 
03562    int trace;
03563    misdn_cfg_get( 0, MISDN_GEN_TRACE_CALLS, &trace, sizeof(int));
03564    if (!trace) return ;
03565    
03566    if (misdn_debug[0] < debug) return ; 
03567    
03568    char tracedir[BUFFERSIZE];
03569    misdn_cfg_get( 0, MISDN_GEN_TRACE_DIR, tracedir, BUFFERSIZE);
03570    sprintf(name,"%s/%s.%s",tracedir, chan->uniqueid, chan->cid.cid_num );
03571    
03572    va_start(ap, tmpl);
03573    
03574    vsprintf( buf, tmpl, ap );
03575    
03576    va_end(ap);
03577    
03578    time_t tm = time(NULL);
03579    char *tmp=ctime(&tm),*p;
03580    FILE *fp= fopen(name, "a");
03581    int fd;
03582    
03583    if (!fp) {
03584       ast_console_puts("Error opening Tracefile");
03585       ast_console_puts(strerror(errno));
03586       ast_console_puts("\n");
03587       return ;
03588    }
03589    
03590    fd=fileno(fp) ;
03591    
03592    flock(fd, LOCK_EX);
03593    
03594    p=strchr(tmp,'\n');
03595    if (p) *p=':';
03596    
03597    
03598    
03599    fputs(tmp,fp);
03600    fputs(" ", fp);
03601    fputs(buf, fp);
03602 
03603    flock(fd, LOCK_UN);
03604    
03605    fclose(fp);
03606    
03607 }

void cl_dequeue_chan struct chan_list **  list,
struct chan_list chan
 

Definition at line 2383 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, chan_list::next, and chan_list::trans.

Referenced by misdn_hangup(), and release_chan().

02384 {
02385    if (chan->dsp) 
02386       ast_dsp_free(chan->dsp);
02387    if (chan->trans)
02388       ast_translator_free_path(chan->trans);
02389    
02390 
02391    ast_mutex_lock(&cl_te_lock);
02392    if (!*list) {
02393       ast_mutex_unlock(&cl_te_lock);
02394       return;
02395    }
02396   
02397    if (*list == chan) {
02398       *list=(*list)->next;
02399       ast_mutex_unlock(&cl_te_lock);
02400       return ;
02401    }
02402   
02403    {
02404       struct chan_list *help=*list;
02405       for (;help->next; help=help->next) {
02406          if (help->next == chan) {
02407             help->next=help->next->next;
02408             ast_mutex_unlock(&cl_te_lock);
02409             return;
02410          }
02411       }
02412    }
02413    
02414    ast_mutex_unlock(&cl_te_lock);
02415 }

void cl_queue_chan struct chan_list **  list,
struct chan_list chan
 

Definition at line 2367 of file chan_misdn.c.

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

Referenced by cb_events(), and misdn_call().

02368 {
02369    chan_misdn_log(4, chan->bc? chan->bc->port : 0, "* Queuing chan %p\n",chan);
02370   
02371    ast_mutex_lock(&cl_te_lock);
02372    if (!*list) {
02373       *list = chan;
02374    } else {
02375       struct chan_list *help=*list;
02376       for (;help->next; help=help->next); 
02377       help->next=chan;
02378    }
02379    chan->next=NULL;
02380    ast_mutex_unlock(&cl_te_lock);
02381 }

int clearl3_true void   ) 
 

TE STUFF END *

Definition at line 3342 of file chan_misdn.c.

References misdn_cfg_get().

Referenced by load_module().

03342                           {
03343    int default_clearl3;
03344    misdn_cfg_get( 0, MISDN_GEN_CLEAR_L3, &default_clearl3, sizeof(int));
03345    return default_clearl3;
03346 }

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

Definition at line 881 of file chan_misdn.c.

References complete_ch_helper().

00882 {
00883    return complete_ch_helper(line, word, pos, state, 3);
00884 }

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

Definition at line 857 of file chan_misdn.c.

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

Referenced by complete_ch(), complete_ch_3(), and complete_ch_4().

00858 {
00859    struct ast_channel *c;
00860    int which=0;
00861    char *ret;
00862    if (pos != rpos)
00863       return NULL;
00864    c = ast_channel_walk_locked(NULL);
00865    while(c) {
00866       if (!strncasecmp(word, c->name, strlen(word))) {
00867          if (++which > state)
00868             break;
00869       }
00870       ast_mutex_unlock(&c->lock);
00871       c = ast_channel_walk_locked(c);
00872    }
00873    if (c) {
00874       ret = strdup(c->name);
00875       ast_mutex_unlock(&c->lock);
00876    } else
00877       ret = NULL;
00878    return ret;
00879 }

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

Definition at line 886 of file chan_misdn.c.

References strdup.

00887 {
00888    if (state)
00889       return NULL;
00890 
00891    switch (pos) {
00892    case 4: if (*word == 'p')
00893             return strdup("port");
00894          else if (*word == 'o')
00895             return strdup("only");
00896          break;
00897    case 6: if (*word == 'o')
00898             return strdup("only");
00899          break;
00900    }
00901    return NULL;
00902 }

char* description void   ) 
 

Provides a description of the module.

Returns:
a short description of your module

Definition at line 3502 of file chan_misdn.c.

03503 {
03504    return desc;
03505 }

void do_immediate_setup struct misdn_bchannel *  bc,
struct chan_list ch,
struct ast_channel ast
 

Definition at line 2534 of file chan_misdn.c.

References chan_list::ast, AST_CID_P, ast_pbx_start(), ast_queue_frame(), ast_strlen_zero(), chan_misdn_log(), ast_channel::context, ast_frame::data, ast_frame::datalen, ast_channel::exten, ast_frame::frametype, ast_frame::mallocd, MISDN_ASTERISK_PVT, MISDN_ASTERISK_TECH_PVT, ast_frame::offset, ast_frame::samples, ast_frame::src, and ast_frame::subclass.

Referenced by cb_events().

02535 {
02536    char predial[256]="";
02537    char *p = predial;
02538   
02539    struct ast_frame fr;
02540   
02541    strncpy(predial, ast->exten, sizeof(predial) -1 );
02542   
02543    ch->state=MISDN_DIALING;
02544    
02545    if (bc->nt) {
02546       int ret; 
02547       ret = misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE );
02548    } else {
02549       int ret;
02550       if ( misdn_lib_is_ptp(bc->port)) {
02551          ret = misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE );
02552       } else {
02553          ret = misdn_lib_send_event(bc, EVENT_PROCEEDING );
02554       }
02555    }
02556 
02557    manager_send_tone(bc,TONE_DIAL);  
02558   
02559    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));
02560   
02561    strncpy(ast->exten,"s", 2);
02562   
02563    if (ast_pbx_start(ast)<0) {
02564       ast=NULL;
02565       manager_send_tone(bc,TONE_BUSY);
02566       if (bc->nt)
02567          misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE );
02568       else
02569          misdn_lib_send_event(bc, EVENT_DISCONNECT );
02570    }
02571   
02572   
02573    while (!ast_strlen_zero(p) ) {
02574       fr.frametype = AST_FRAME_DTMF;
02575       fr.subclass = *p ;
02576       fr.src=NULL;
02577       fr.data = NULL ;
02578       fr.datalen = 0;
02579       fr.samples = 0 ;
02580       fr.mallocd =0 ;
02581       fr.offset= 0 ;
02582 
02583       if (ch->ast && MISDN_ASTERISK_PVT(ch->ast) && MISDN_ASTERISK_TECH_PVT(ch->ast)) {
02584          ast_queue_frame(ch->ast, &fr);
02585       }
02586       p++;
02587    }
02588 }

struct chan_list * find_chan_by_bc struct chan_list list,
struct misdn_bchannel *  bc
 

Definition at line 2338 of file chan_misdn.c.

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

Referenced by cb_events(), and release_chan().

02339 {
02340    struct chan_list *help=list;
02341    for (;help; help=help->next) {
02342       if (help->bc == bc) return help;
02343    }
02344   
02345    chan_misdn_log(4, bc->port, "$$$ find_chan: No channel found for oad:%s dad:%s\n",bc->oad,bc->dad);
02346   
02347    return NULL;
02348 }

struct chan_list* find_chan_by_l3id struct chan_list list,
unsigned long  l3id
 

Channel Queue **

Definition at line 2326 of file chan_misdn.c.

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

Referenced by cb_events(), and release_chan().

02327 {
02328    struct chan_list *help=list;
02329    for (;help; help=help->next) {
02330       if (help->l3id == l3id ) return help;
02331    }
02332   
02333    chan_misdn_log(4, list? (list->bc? list->bc->port : 0) : 0, "$$$ find_chan: No channel found with l3id:%x\n",l3id);
02334   
02335    return NULL;
02336 }

struct chan_list* find_holded struct chan_list list,
struct misdn_bchannel *  bc
 

Definition at line 2351 of file chan_misdn.c.

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

Referenced by cb_events().

02352 {
02353    struct chan_list *help=list;
02354    
02355    chan_misdn_log(4, bc->port, "$$$ find_holded: channel:%d oad:%s dad:%s\n",bc->channel, bc->oad,bc->dad);
02356    for (;help; help=help->next) {
02357       chan_misdn_log(4, bc->port, "$$$ find_holded: --> holded:%d channel:%d\n",help->bc->holded, help->bc->channel);
02358       if (help->bc->port == bc->port
02359           && help->bc->holded ) return help;
02360    }
02361    
02362    chan_misdn_log(4, bc->port, "$$$ find_chan: No channel found for oad:%s dad:%s\n",bc->oad,bc->dad);
02363   
02364    return NULL;
02365 }

void free_robin_list void   )  [static]
 

Definition at line 152 of file chan_misdn.c.

References free_robin_list_r(), and robin.

Referenced by misdn_reload(), and unload_module().

00153 {
00154    free_robin_list_r(robin);
00155    robin = NULL;
00156 }

void free_robin_list_r struct robin_list r  )  [inline, static]
 

Definition at line 143 of file chan_misdn.c.

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

Referenced by free_robin_list().

00144 {
00145    if (r) {
00146       if (r->next) free_robin_list_r(r->next);
00147       if (r->group) free(r->group);
00148       free(r);
00149    }
00150 }

struct chan_list* get_chan_by_ast struct ast_channel ast  )  [static]
 

Definition at line 239 of file chan_misdn.c.

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

Referenced by misdn_bridge().

00240 {
00241    struct chan_list *tmp;
00242   
00243    for (tmp=cl_te; tmp; tmp = tmp->next) {
00244       if ( tmp->ast == ast ) return tmp;
00245    }
00246   
00247    return NULL;
00248 }

struct chan_list* get_chan_by_ast_name char *  name  )  [static]
 

Definition at line 250 of file chan_misdn.c.

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

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

00251 {
00252    struct chan_list *tmp;
00253   
00254    for (tmp=cl_te; tmp; tmp = tmp->next) {
00255       if ( tmp->ast  && strcmp(tmp->ast->name,name) == 0) return tmp;
00256    }
00257   
00258    return NULL;
00259 }

struct robin_list* get_robin_position char *  group  ) 
 

Definition at line 158 of file chan_misdn.c.

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

Referenced by misdn_request().

00159 {
00160    struct robin_list *iter = robin;
00161    for (; iter; iter = iter->next) {
00162       if (!strcasecmp(iter->group, group))
00163          return iter;
00164    }
00165    struct robin_list *new = (struct robin_list *)calloc(1, sizeof(struct robin_list));
00166    new->group = strndup(group, strlen(group));
00167    new->channel = 1;
00168    if (robin) {
00169       new->next = robin;
00170       robin->prev = new;
00171    }
00172    robin = new;
00173    return robin;
00174 }

struct chan_list* init_chan_list void   ) 
 

Definition at line 1902 of file chan_misdn.c.

References chan_misdn_log(), and malloc.

Referenced by cb_events(), and misdn_request().

01903 {
01904    struct chan_list *cl=malloc(sizeof(struct chan_list));
01905    
01906    if (!cl) {
01907       chan_misdn_log(0, 0, "misdn_request: malloc failed!");
01908       return NULL;
01909    }
01910    
01911    memset(cl,0,sizeof(struct chan_list));
01912    
01913    return cl;
01914    
01915 }

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

03508 {
03509    return ASTERISK_GPL_KEY;
03510 }

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

References ast_channel_register(), ast_cli_register(), ast_log(), ast_mutex_init(), ast_register_application(), calloc, chan_misdn_log(), cl_te_lock, clearl3_true(), 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, g_config_initialized, LOG_ERROR, malloc, max_ports, misdn_cfg_get(), misdn_cfg_get_ports_string(), misdn_cfg_init(), misdn_debug, misdn_debug_only, misdn_facility_exec(), misdn_set_opt_exec(), misdn_tech, release_lock_mutex, tracing, type, and unload_module().

03351 {
03352    int i;
03353    
03354    char ports[256]="";
03355    
03356    max_ports=misdn_lib_maxports_get();
03357    
03358    if (max_ports<=0) {
03359       ast_log(LOG_ERROR, "Unable to initialize mISDN\n");
03360       return -1;
03361    }
03362    
03363    
03364    misdn_cfg_init(max_ports);
03365    g_config_initialized=1;
03366    
03367    misdn_debug = (int *)malloc(sizeof(int) * (max_ports+1));
03368    misdn_cfg_get( 0, MISDN_GEN_DEBUG, &misdn_debug[0], sizeof(int));
03369    for (i = 1; i <= max_ports; i++)
03370       misdn_debug[i] = misdn_debug[0];
03371    misdn_debug_only = (int *)calloc(max_ports + 1, sizeof(int));
03372 
03373    
03374    {
03375       char tempbuf[BUFFERSIZE];
03376       misdn_cfg_get( 0, MISDN_GEN_TRACEFILE, tempbuf, BUFFERSIZE);
03377       if (strlen(tempbuf))
03378          tracing = 1;
03379    }
03380 
03381    ast_mutex_init(&cl_te_lock);
03382    ast_mutex_init(&release_lock_mutex);
03383 
03384    misdn_cfg_get_ports_string(ports);
03385    if (strlen(ports))
03386       chan_misdn_log(0, 0, "Got: %s from get_ports\n",ports);
03387    
03388    {
03389       struct misdn_lib_iface iface = {
03390          .cb_event = cb_events,
03391          .cb_log = chan_misdn_log,
03392          .cb_clearl3_true = clearl3_true
03393       };
03394       if (misdn_lib_init(ports, &iface, NULL))
03395          chan_misdn_log(0, 0, "No te ports initialized\n");
03396    }
03397 
03398 
03399    {
03400       if (ast_channel_register(&misdn_tech)) {
03401          ast_log(LOG_ERROR, "Unable to register channel class %s\n", type);
03402          unload_module();
03403          return -1;
03404       }
03405    }
03406   
03407    ast_cli_register(&cli_send_display);
03408    ast_cli_register(&cli_send_cd);
03409    ast_cli_register(&cli_send_digit);
03410    ast_cli_register(&cli_toggle_echocancel);
03411    ast_cli_register(&cli_set_tics);
03412 
03413    ast_cli_register(&cli_show_cls);
03414    ast_cli_register(&cli_show_cl);
03415    ast_cli_register(&cli_show_config);
03416    ast_cli_register(&cli_show_port);
03417    ast_cli_register(&cli_show_stacks);
03418 
03419    ast_cli_register(&cli_restart_port);
03420    ast_cli_register(&cli_port_up);
03421    ast_cli_register(&cli_set_debug);
03422    ast_cli_register(&cli_set_crypt_debug);
03423    ast_cli_register(&cli_reload);
03424 
03425   
03426    ast_register_application("misdn_set_opt", misdn_set_opt_exec, "misdn_set_flags",
03427              "misdn_set_opt(:<opt><optarg>:<opt><optarg>..):\n"
03428              "Sets mISDN opts. and optargs\n"
03429              "\n"
03430       );
03431 
03432    
03433    ast_register_application("misdn_facility", misdn_facility_exec, "misdn_facility",
03434              "misdn_facility(<FACILITY_TYPE>|<ARG1>|..)\n"
03435              "Sends the Facility Message FACILITY_TYPE with \n"
03436              "the given Arguments to the current ISDN Channel\n"
03437              "Supported Facilities are:\n"
03438              "\n"
03439              "type=calldeflect args=Nr where to deflect\n"
03440              "\n"
03441       );
03442   
03443    chan_misdn_log(0, 0, "-- mISDN Channel Driver Registred -- (BE AWARE THIS DRIVER IS EXPERIMENTAL!)\n");
03444 
03445    return 0;
03446 }

int misdn_answer struct ast_channel ast  ) 
 

Definition at line 1341 of file chan_misdn.c.

References chan_list::ast, ast_log(), ast_queue_hangup(), chan_list::bc, chan_misdn_log(), chan_misdn_trace_call(), LOG_WARNING, MISDN_ASTERISK_PVT, MISDN_ASTERISK_TECH_PVT, pbx_builtin_getvar_helper(), and start_bc_tones().

01342 {
01343    struct chan_list *p;
01344 
01345    
01346    if (!ast || ! MISDN_ASTERISK_PVT(ast)) return -1;
01347    p = MISDN_ASTERISK_TECH_PVT(ast) ;
01348    
01349    chan_misdn_trace_call(ast,1,"*->I: EVENT_ANSWER\n");
01350    
01351    chan_misdn_log(1, p? (p->bc? p->bc->port : 0) : 0, "* ANSWER:\n");
01352    
01353    if (!p) {
01354       ast_log(LOG_WARNING, " --> Channel not connected ??\n");
01355       ast_queue_hangup(ast);
01356    }
01357 
01358    if (!p->bc) {
01359       chan_misdn_log(1, 0, " --> Got Answer, but theres no bc obj ??\n");
01360 
01361       ast_queue_hangup(ast);
01362    }
01363 
01364    {
01365       char *tmp_key = pbx_builtin_getvar_helper(p->ast, "CRYPT_KEY");
01366       
01367       if (tmp_key ) {
01368          chan_misdn_log(1, p->bc->port, " --> Connection will be BF crypted\n");
01369          {
01370             int l = sizeof(p->bc->crypt_key);
01371             strncpy(p->bc->crypt_key,tmp_key, l);
01372             p->bc->crypt_key[l-1] = 0;
01373          }
01374       } else {
01375          chan_misdn_log(3, p->bc->port, " --> Connection is without BF encryption\n");
01376       }
01377     
01378    }
01379 
01380    {
01381       char *async=pbx_builtin_getvar_helper(ast, "MISDN_DIGITAL_TRANS");
01382       if (async) {
01383          chan_misdn_log(1, p->bc->port, " --> Connection is transparent digital\n");
01384          p->bc->async=1;
01385       }
01386    }
01387    
01388    p->state = MISDN_CONNECTED;
01389    misdn_lib_send_event( p->bc, EVENT_CONNECT);
01390    start_bc_tones(p);
01391    
01392    return 0;
01393 }

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

References ast_bridge_result, ast_log(), ast_read(), ast_waitfor_n(), ast_write(), chan_list::bc, chan_misdn_log(), ast_frame::frametype, get_chan_by_ast(), LOG_DEBUG, and misdn_cfg_get().

01801 {
01802    struct chan_list *ch1,*ch2;
01803    struct ast_channel *carr[2], *who;
01804    int to=-1;
01805    struct ast_frame *f;
01806   
01807    ch1=get_chan_by_ast(c0);
01808    ch2=get_chan_by_ast(c1);
01809 
01810    carr[0]=c0;
01811    carr[1]=c1;
01812   
01813   
01814    if (ch1 && ch2 ) ;
01815    else
01816       return -1;
01817   
01818 
01819    int bridging;
01820    misdn_cfg_get( 0, MISDN_GEN_BRIDGING, &bridging, sizeof(int));
01821    if (bridging) {
01822       int ecwb;
01823       misdn_cfg_get( ch1->bc->port, MISDN_CFG_ECHOCANCELWHENBRIDGED, &ecwb, sizeof(int));
01824       if ( !ecwb ) {
01825          chan_misdn_log(0, ch1->bc->port, "Disabling Echo Cancellor when Bridged\n");
01826          ch1->bc->ec_enable=0;
01827          manager_ec_disable(ch1->bc);
01828       }
01829       misdn_cfg_get( ch2->bc->port, MISDN_CFG_ECHOCANCELWHENBRIDGED, &ecwb, sizeof(int));
01830       if ( !ecwb ) {
01831          chan_misdn_log(0, ch2->bc->port, "Disabling Echo Cancellor when Bridged\n");
01832          ch2->bc->ec_enable=0;
01833          manager_ec_disable(ch2->bc);
01834       }
01835       
01836       /* trying to make a mISDN_dsp conference */
01837       chan_misdn_log(0, ch1->bc->port, "I SEND: Making conference with Number:%d\n", (ch1->bc->pid<<1) +1);
01838 
01839       misdn_lib_bridge(ch1->bc,ch2->bc);
01840    }
01841    
01842    chan_misdn_log(1, ch1->bc->port, "* Makeing Native Bridge between %s and %s\n", ch1->bc->oad, ch2->bc->oad);
01843   
01844    while(1) {
01845       to=-1;
01846       who = ast_waitfor_n(carr, 2, &to);
01847 
01848       if (!who) {
01849          ast_log(LOG_DEBUG,"misdn_bridge: empty read\n");
01850          continue;
01851       }
01852       f = ast_read(who);
01853     
01854       if (!f || f->frametype == AST_FRAME_CONTROL) {
01855          /* got hangup .. */
01856          *fo=f;
01857          *rc=who;
01858       
01859          break;
01860       }
01861     
01862     
01863       if (who == c0) {
01864          ast_write(c1,f);
01865       }
01866       else {
01867          ast_write(c0,f);
01868       }
01869     
01870    }
01871   
01872    if (bridging) {
01873       misdn_lib_split_bridge(ch1->bc,ch2->bc);
01874    }
01875   
01876    return 0;
01877 }

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

we should have l3id after sending setup *

Definition at line 1038 of file chan_misdn.c.

References ast_channel::_state, chan_list::ast, AST_CID_P, 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, ast_setstate(), AST_STATE_DIALING, AST_STATE_DOWN, ast_strlen_zero(), ast_transfercapability2str(), ast_verbose(), chan_list::bc, chan_misdn_log(), chan_misdn_trace_call(), ast_channel::cid, ast_callerid::cid_pres, cl_queue_chan(), cl_te, ast_channel::context, ast_channel::exten, ast_channel::hangupcause, chan_list::l3id, ast_channel::language, LOG_WARNING, MISDN_ASTERISK_TECH_PVT, misdn_cfg_get(), misdn_set_opt_exec(), ast_channel::name, chan_list::orginator, pbx_builtin_setvar_helper(), and ast_channel::transfercapability.

01039 {
01040    int port=0;
01041    int r;
01042    struct chan_list *ch=MISDN_ASTERISK_TECH_PVT(ast);
01043    struct misdn_bchannel *newbc;
01044    char *opts=NULL, *ext=NULL;
01045    char dest_cp[256];
01046    char *tokb;
01047    
01048    {
01049       strncpy(dest_cp,dest,sizeof(dest_cp)-1);
01050       dest_cp[sizeof(dest_cp)]=0;
01051       
01052       ext=strtok_r(dest_cp,"/",&tokb);
01053       
01054       if (ext) {
01055          ext=strtok_r(NULL,"/",&tokb);
01056          if (ext) {
01057             opts=strtok_r(NULL,"/",&tokb);
01058          } else {
01059             chan_misdn_log(-1,0,"misdn_call: No Extension given!\n");
01060             return -1;
01061          }
01062       }
01063       
01064       
01065    }
01066 
01067    if (!ast) {
01068       ast_log(LOG_WARNING, " --> ! misdn_call called on ast_channel *ast where ast == NULL\n");
01069       return -1;
01070    }
01071 
01072    if (((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) || !dest  ) {
01073       ast_log(LOG_WARNING, " --> ! misdn_call called on %s, neither down nor reserved (or dest==NULL)\n", ast->name);
01074       ast->hangupcause=41;
01075       ast_setstate(ast, AST_STATE_DOWN);
01076       return -1;
01077    }
01078 
01079 
01080    if (!ch) {
01081       ast_log(LOG_WARNING, " --> ! misdn_call called on %s, neither down nor reserved (or dest==NULL)\n", ast->name);
01082       ast->hangupcause=41;
01083       ast_setstate(ast, AST_STATE_DOWN);
01084       return -1;
01085    }
01086    
01087    newbc=ch->bc;
01088    
01089    if (!newbc) {
01090       ast_log(LOG_WARNING, " --> ! misdn_call called on %s, neither down nor reserved (or dest==NULL)\n", ast->name);
01091       ast->hangupcause=41;
01092       ast_setstate(ast, AST_STATE_DOWN);
01093       return -1;
01094    }
01095 
01096    port=newbc->port;
01097 
01098    ast_copy_string(newbc->dad, ext, sizeof(newbc->dad));
01099    ast_copy_string(ast->exten, ext, sizeof(ast->exten));
01100    
01101    chan_misdn_log(1, 0, "* CALL: %s\n",dest);
01102    
01103    chan_misdn_log(1, port, " --> * dad:%s tech:%s ctx:%s\n",ast->exten,ast->name, ast->context);
01104    
01105    {
01106       char context[BUFFERSIZE];
01107       
01108       misdn_cfg_get( port, MISDN_CFG_CONTEXT, context, sizeof(ast->context));
01109       {
01110          int l = sizeof(ast->context);
01111          strncpy(ast->context,context, l);
01112          ast->context[l-1] = 0;
01113       }
01114       chan_misdn_log(2, port, " --> * Setting Context to %s\n",context);
01115       misdn_cfg_get( port, MISDN_CFG_LANGUAGE, ast->language, BUFFERSIZE);
01116       
01117       misdn_cfg_get( port, MISDN_CFG_TXGAIN, &newbc->txgain, sizeof(int));
01118       misdn_cfg_get( port, MISDN_CFG_RXGAIN, &newbc->rxgain, sizeof(int));
01119       
01120       misdn_cfg_get( port, MISDN_CFG_TE_CHOOSE_CHANNEL, &(newbc->te_choose_channel), sizeof(int));
01121       
01122 
01123       {
01124          char callerid[BUFFERSIZE];
01125          misdn_cfg_get( port, MISDN_CFG_CALLERID, callerid, BUFFERSIZE);
01126          if ( ! ast_strlen_zero(callerid) ) {
01127             chan_misdn_log(1, port, " --> * Setting Cid to %s\n", callerid);
01128             {
01129                int l = sizeof(newbc->oad);
01130                strncpy(newbc->oad,callerid, l);
01131                newbc->oad[l-1] = 0;
01132             }
01133          }
01134 
01135          
01136          misdn_cfg_get( port, MISDN_CFG_DIALPLAN, &newbc->dnumplan, sizeof(int));
01137          switch (newbc->dnumplan) {
01138          case NUMPLAN_INTERNATIONAL:
01139             chan_misdn_log(2, port, " --> TON: International\n");
01140             break;
01141          case NUMPLAN_NATIONAL:
01142             chan_misdn_log(2, port, " --> TON: National\n");
01143             break;
01144          case NUMPLAN_SUBSCRIBER:
01145             chan_misdn_log(2, port, " --> TON: Subscriber\n");
01146             break;
01147          case NUMPLAN_UNKNOWN:
01148             chan_misdn_log(2, port, " --> TON: Unknown\n");
01149             break;
01150             /* Maybe we should cut off the prefix if present ? */
01151          default:
01152                chan_misdn_log(0, port, " --> !!!! Wrong dialplan setting, please see the misdn.conf sample file\n ");
01153                break;
01154          }
01155 
01156 
01157          misdn_cfg_get( port, MISDN_CFG_LOCALDIALPLAN, &newbc->onumplan, sizeof(int));
01158          switch (newbc->onumplan) {
01159          case NUMPLAN_INTERNATIONAL:
01160             chan_misdn_log(2, port, " --> TON: International\n");
01161             break;
01162          case NUMPLAN_NATIONAL:
01163             chan_misdn_log(2, port, " --> TON: National\n");
01164             break;
01165          case NUMPLAN_SUBSCRIBER:
01166             chan_misdn_log(2, port, " --> TON: Subscriber\n");
01167             break;
01168          case NUMPLAN_UNKNOWN:
01169             chan_misdn_log(2, port, " --> TON: Unknown\n");
01170             break;
01171             /* Maybe we should cut off the prefix if present ? */
01172          default:
01173                chan_misdn_log(0, port, " --> !!!! Wrong dialplan setting, please see the misdn.conf sample file\n ");
01174                break;
01175          }
01176       }
01177 
01178 
01179 
01180       
01181       {
01182          int eb3;
01183          
01184          misdn_cfg_get( port, MISDN_CFG_EARLY_BCONNECT, &eb3, sizeof(int));
01185          newbc->early_bconnect=eb3;
01186          
01187       }
01188       
01189 
01190       
01191       /* Will be overridden by asterisk in head! */
01192       {
01193          int pres;
01194          
01195          misdn_cfg_get( port, MISDN_CFG_PRES, &pres, sizeof(int));
01196          newbc->pres=pres?0:1;
01197          
01198       }
01199       
01200       int def_callingpres;
01201       misdn_cfg_get( port, MISDN_CFG_USE_CALLINGPRES, &def_callingpres, sizeof(int));
01202       if ( def_callingpres) {
01203          
01204          switch (ast->cid.cid_pres & 0x60){
01205             
01206          case AST_PRES_RESTRICTED:
01207             chan_misdn_log(2, port, " --> PRES: Restricted (0x1)\n");
01208             newbc->pres=1;
01209             break;
01210             
01211             
01212          case AST_PRES_UNAVAILABLE:
01213             chan_misdn_log(2, port, " --> PRES: Unavailable (0x2)\n");
01214             newbc->pres=2;
01215             break;
01216             
01217          default:
01218             chan_misdn_log(2, port, " --> PRES: Allowed (0x0)\n");
01219             newbc->pres=0;
01220          }
01221          
01222          switch (ast->cid.cid_pres & 0x3){
01223             
01224          case AST_PRES_USER_NUMBER_UNSCREENED:
01225             chan_misdn_log(2, port, " --> SCREEN: Unscreened (0x0)\n");
01226             newbc->screen=0;
01227             break;
01228 
01229          case AST_PRES_USER_NUMBER_PASSED_SCREEN:
01230             chan_misdn_log(2, port, " --> SCREEN: Passed Screen (0x1)\n");
01231             newbc->screen=1;
01232             break;
01233          case AST_PRES_USER_NUMBER_FAILED_SCREEN:
01234             chan_misdn_log(2, port, " --> SCREEN: Failed Screen (0x2)\n");
01235             newbc->screen=2;
01236             break;
01237             
01238          case AST_PRES_NETWORK_NUMBER:
01239             chan_misdn_log(2, port, " --> SCREEN: Network Nr. (0x3)\n");
01240             newbc->screen=3;
01241             break;
01242             
01243          default:
01244             chan_misdn_log(2, port, " --> SCREEN: Unscreened (0x0)\n");
01245             newbc->screen=0;
01246          }
01247       }
01248 
01249       
01250       {
01251          int ec, ectr;
01252          
01253          misdn_cfg_get( port, MISDN_CFG_ECHOCANCEL, &ec, sizeof(int));
01254          
01255          misdn_cfg_get( port, MISDN_CFG_ECHOTRAINING, &ectr, sizeof(int));
01256          if (ec == 1 ) {
01257             newbc->ec_enable=1;
01258          } else if ( ec > 1 ) {
01259             newbc->ec_enable=1;
01260             newbc->ec_deftaps=ec;
01261          }
01262 
01263 
01264          if (ectr>=0) {
01265             newbc->ec_training=ectr;
01266          }
01267          
01268       }
01269       
01270    } 
01271    
01272    chan_misdn_log(3, port, " --> * adding2newbc ext %s\n",ast->exten);
01273    if (ast->exten) {
01274       int l = sizeof(newbc->dad);
01275       strncpy(newbc->dad,ast->exten, l);
01276       newbc->dad[l-1] = 0;
01277    }
01278    newbc->rad[0]=0;
01279    chan_misdn_log(3, port, " --> * adding2newbc callerid %s\n",AST_CID_P(ast));
01280    if (ast_strlen_zero(newbc->oad) && AST_CID_P(ast) ) {
01281       if (AST_CID_P(ast)) {
01282          int l = sizeof(newbc->oad);
01283          strncpy(newbc->oad,AST_CID_P(ast), l);
01284          newbc->oad[l-1] = 0;
01285       }
01286    }
01287    
01288    {
01289       struct chan_list *ch=MISDN_ASTERISK_TECH_PVT(ast);
01290       if (!ch) { ast_verbose("No chan_list in misdn_call"); return -1;}
01291       ch->bc = newbc;
01292       ch->orginator=ORG_AST;
01293       ch->ast = ast;
01294       
01295       MISDN_ASTERISK_TECH_PVT(ast) = ch ;
01296       
01297       
01298       
01299       newbc->capability=ast->transfercapability;
01300       pbx_builtin_setvar_helper(ast,"TRANSFERCAPABILITY",ast_transfercapability2str(newbc->capability));
01301       if ( ast->transfercapability == INFO_CAPABILITY_DIGITAL_UNRESTRICTED) {
01302          chan_misdn_log(2, port, " --> * Call with flag Digital\n");
01303       }
01304       
01305 
01306       /* Finally The Options Override Everything */
01307       if (opts)
01308          misdn_set_opt_exec(ast,opts);
01309       else
01310          chan_misdn_log(1,0,"NO OPTS GIVEN\n");
01311       
01312       
01313       cl_queue_chan(&cl_te, ch) ;
01314       ch->state=MISDN_CALLING;
01315 
01316       chan_misdn_trace_call(ast,1,"*->I: EVENT_CALL\n" );
01317       
01318       r=misdn_lib_send_event( newbc, EVENT_SETUP );
01319       
01320       /** we should have l3id after sending setup **/
01321       ch->l3id=newbc->l3_id;
01322    }
01323    
01324    if ( r == -ENOCHAN  ) {
01325       chan_misdn_log(0, port, " --> * Theres no Channel at the moment .. !\n");
01326       chan_misdn_log(1, port, " --> * SEND: State Down pid:%d\n",newbc?newbc->pid:-1);
01327       ast->hangupcause=34;
01328       ast_setstate(ast, AST_STATE_DOWN);
01329       return -1;
01330    }
01331    
01332    chan_misdn_log(1, port, " --> * SEND: State Dialing pid:%d\n",newbc?newbc->pid:1);
01333 
01334    ast_setstate(ast, AST_STATE_DIALING);
01335    
01336    ast->hangupcause=16;
01337    return 0; 
01338 }

int misdn_digit struct ast_channel ast,
char  digit
 

Definition at line 1395 of file chan_misdn.c.

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

01396 {
01397    struct chan_list *p;
01398    
01399    if (!ast || ! MISDN_ASTERISK_PVT(ast)) return -1;
01400    p = MISDN_ASTERISK_TECH_PVT(ast) ;
01401    
01402 
01403    struct misdn_bchannel *bc=p->bc;
01404    chan_misdn_log(1, bc?bc->port:0, "* IND : Digit %c\n",digit);
01405    
01406    if (!bc) {
01407       ast_log(LOG_WARNING, " --> !! Got Digit Event withut having bchannel Object\n");
01408       return -1;
01409    }
01410    
01411    switch (p->state ) {
01412       case MISDN_CALLING:
01413       {
01414          
01415          char buf[8];
01416          buf[0]=digit;
01417          buf[1]=0;
01418          
01419          int l = sizeof(bc->infos_pending);
01420          strncat(bc->infos_pending,buf,l);
01421          bc->infos_pending[l-1] = 0;
01422       }
01423       break;
01424       case MISDN_CALLING_ACKNOWLEDGE:
01425       {
01426          bc->info_dad[0]=digit;
01427          bc->info_dad[1]=0;
01428          
01429          {
01430             int l = sizeof(bc->dad);
01431             strncat(bc->dad,bc->info_dad, l - strlen(bc->dad));
01432             bc->dad[l-1] = 0;
01433       }
01434          {
01435             int l = sizeof(p->ast->exten);
01436             strncpy(p->ast->exten, bc->dad, l);
01437             p->ast->exten[l-1] = 0;
01438          }
01439          
01440          misdn_lib_send_event( bc, EVENT_INFORMATION);
01441       }
01442       break;
01443       
01444       default:
01445          if ( bc->send_dtmf ) {
01446             send_digit_to_chan(p,digit);
01447          }
01448       break;
01449    }
01450    
01451    return 0;
01452 }

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

Definition at line 3612 of file chan_misdn.c.

References ast_log(), ast_strlen_zero(), chan_list::bc, LOG_WARNING, MISDN_ASTERISK_TECH_PVT, and MISDN_ASTERISK_TYPE.

Referenced by load_module().

03613 {
03614    struct chan_list *ch = MISDN_ASTERISK_TECH_PVT(chan);
03615    char *tok, *tokb;
03616    
03617 
03618    if (strcasecmp(MISDN_ASTERISK_TYPE(chan),"mISDN")) {
03619       ast_log(LOG_WARNING, "misdn_facility makes only sense with chan_misdn channels!\n");
03620       return -1;
03621    }
03622    
03623    if (ast_strlen_zero((char *)data)) {
03624       ast_log(LOG_WARNING, "misdn_facility Requires arguments\n");
03625       return -1;
03626    }
03627    
03628    tok=strtok_r((char*)data,"|", &tokb) ;
03629    
03630    if (!tok) {
03631       ast_log(LOG_WARNING, "misdn_facility Requires arguments\n");
03632       return -1;
03633    }
03634    
03635    if (!strcasecmp(tok,"calldeflect")) {
03636       tok=strtok_r(NULL,"|", &tokb) ;
03637       
03638       if (!tok) {
03639          ast_log(LOG_WARNING, "Facility: Call Defl Requires arguments\n");
03640       }
03641       
03642       misdn_lib_send_facility(ch->bc, FACILITY_CALLDEFLECT, tok);
03643       
03644    } else {
03645       ast_log(LOG_WARNING, "Unknown Facility: %s\n",tok);
03646    }
03647    
03648    return 0;
03649    
03650 }

int misdn_fixup struct ast_channel oldast,
struct ast_channel ast
 

Definition at line 1455 of file chan_misdn.c.

References chan_list::ast, chan_list::bc, chan_misdn_log(), chan_list::holded, chan_list::l3id, MISDN_ASTERISK_PVT, MISDN_ASTERISK_TECH_PVT, and misdn_get_ch_state().

01456 {
01457    struct chan_list *p;
01458    
01459    if (!ast || ! MISDN_ASTERISK_PVT(ast)) return -1;
01460    p = MISDN_ASTERISK_TECH_PVT(ast) ;
01461    
01462    chan_misdn_log(1, p->bc?p->bc->port:0, "* IND: Got Fixup State:%s Holded:%d L3id:%x\n", misdn_get_ch_state(p), p->holded, p->l3id);
01463    
01464    p->ast = ast ;
01465    p->state=MISDN_CONNECTED;
01466   
01467    return 0;
01468 }

char* misdn_get_ch_state struct chan_list p  ) 
 

Definition at line 537 of file chan_misdn.c.

References state_array, and state_struct::txt.

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

00538 {
00539    int i;
00540    if( !p) return NULL;
00541   
00542    for (i=0; i< sizeof(state_array)/sizeof(struct state_struct); i++) {
00543       if ( state_array[i].state == p->state) return state_array[i].txt; 
00544    }
00545   
00546    return NULL;
00547 }

int misdn_hangup struct ast_channel ast  ) 
 

Definition at line 1583 of file chan_misdn.c.

References ast_channel::_state, chan_list::ast, AST_CID_P, ast_log(), chan_list::bc, chan_misdn_log(), chan_misdn_trace_call(), cl_dequeue_chan(), cl_te, ast_channel::context, ast_channel::exten, free, ast_channel::hangupcause, chan_list::l3id, LOG_DEBUG, LOG_WARNING, MISDN_ALERTING, MISDN_ASTERISK_TECH_PVT, MISDN_CALLING, MISDN_CLEANING, MISDN_CONNECTED, MISDN_DIALING, misdn_get_ch_state(), MISDN_HOLD_DISCONNECT, MISDN_HOLDED, ast_channel::name, chan_list::orginator, pbx_builtin_getvar_helper(), start_bc_tones(), and stop_bc_tones().

01584 {
01585    struct chan_list *p;
01586    struct misdn_bchannel *bc=NULL;
01587    
01588    if (!ast || ! (p=MISDN_ASTERISK_TECH_PVT(ast) ) ) return -1;
01589    
01590    release_lock;
01591 
01592    chan_misdn_trace_call(ast,1,"*->I: EVENT_HANGUP cause=%d\n",ast->hangupcause);
01593    
01594    ast_log(LOG_DEBUG, "misdn_hangup(%s)\n", ast->name);
01595    
01596    if (!p) {
01597       chan_misdn_log(3, 0, "misdn_hangup called, without chan_list obj.\n");
01598       release_unlock;
01599       return 0 ;
01600    }
01601    
01602    bc=p->bc;
01603 
01604    if (!bc) {
01605       release_unlock;
01606       ast_log(LOG_WARNING,"Hangup with private but no bc ?\n");
01607       return 0;
01608    }
01609 
01610    
01611    MISDN_ASTERISK_TECH_PVT(ast)=NULL;
01612    p->ast=NULL;
01613 
01614    if (ast->_state == AST_STATE_RESERVED) {
01615       /* between request and call */
01616       MISDN_ASTERISK_TECH_PVT(ast)=NULL;
01617       release_unlock;
01618       
01619       cl_dequeue_chan(&cl_te, p);
01620       free(p);
01621 
01622       misdn_lib_release(bc);
01623       
01624       return 0;
01625    }
01626 
01627    stop_bc_tones(p);
01628    
01629    release_unlock;
01630    
01631    
01632    
01633    
01634    
01635    
01636    {
01637       char *varcause=NULL;
01638       bc->cause=ast->hangupcause?ast->hangupcause:16;
01639       
01640       if ( (varcause=pbx_builtin_getvar_helper(ast, "HANGUPCAUSE")) ||
01641            (varcause=pbx_builtin_getvar_helper(ast, "PRI_CAUSE"))) {
01642          int tmpcause=atoi(varcause);
01643          bc->out_cause=tmpcause?tmpcause:16;
01644       }
01645     
01646       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));
01647       chan_misdn_log(2, bc->port, " --> l3id:%x\n",p->l3id);
01648       chan_misdn_log(1, bc->port, " --> cause:%d\n",bc->cause);
01649       chan_misdn_log(1, bc->port, " --> out_cause:%d\n",bc->out_cause);
01650       
01651       switch (p->state) {
01652       case MISDN_CALLING:
01653          p->state=MISDN_CLEANING;
01654          misdn_lib_send_event( bc, EVENT_RELEASE_COMPLETE);
01655          break;
01656       case MISDN_HOLDED:
01657       case MISDN_DIALING:
01658          start_bc_tones(p);
01659          manager_send_tone(bc, TONE_BUSY);
01660          p->state=MISDN_CLEANING;
01661          
01662          misdn_lib_send_event( bc, EVENT_RELEASE_COMPLETE);
01663       
01664          break;
01665       
01666       case MISDN_ALERTING:
01667          chan_misdn_log(2, bc->port, " --> * State Alerting\n");
01668 
01669          if (p->orginator != ORG_AST) 
01670             manager_send_tone(bc, TONE_BUSY);
01671       
01672          p->state=MISDN_CLEANING;
01673          misdn_lib_send_event( bc, EVENT_DISCONNECT);
01674          break;
01675       case MISDN_CONNECTED:
01676          /*  Alerting or Disconect */
01677          chan_misdn_log(2, bc->port, " --> * State Connected\n");
01678          start_bc_tones(p);
01679          manager_send_tone(bc, TONE_BUSY);
01680          misdn_lib_send_event( bc, EVENT_DISCONNECT);
01681       
01682          p->state=MISDN_CLEANING; /* MISDN_HUNGUP_FROM_AST; */
01683          break;
01684 
01685       case MISDN_CLEANING:
01686          break;
01687       
01688       case MISDN_HOLD_DISCONNECT:
01689          /* need to send release here */
01690          chan_misdn_log(2, bc->port, " --> state HOLD_DISC\n");
01691          chan_misdn_log(1, bc->port, " --> cause %d\n",bc->cause);
01692          chan_misdn_log(1, bc->port, " --> out_cause %d\n",bc->out_cause);
01693          
01694          misdn_lib_send_event(bc,EVENT_RELEASE);
01695          break;
01696       default:
01697          /*  Alerting or Disconect */
01698          if (bc->nt)
01699             misdn_lib_send_event(bc, EVENT_RELEASE);
01700          else
01701             misdn_lib_send_event(bc, EVENT_DISCONNECT);
01702          p->state=MISDN_CLEANING; /* MISDN_HUNGUP_FROM_AST; */
01703       }
01704     
01705    }
01706    
01707    chan_misdn_log(1, bc->port, "Channel: %s hanguped\n",ast->name);
01708    
01709    return 0;
01710 }

int misdn_indication struct ast_channel ast,
int  cond
 

Definition at line 1484 of file chan_misdn.c.

References AST_CONTROL_ANSWER, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_FLASH, AST_CONTROL_HOLD, AST_CONTROL_OFFHOOK, 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, LOG_WARNING, MISDN_ASTERISK_PVT, MISDN_ASTERISK_TECH_PVT, ast_channel::name, and start_bc_tones().

01485 {
01486    struct chan_list *p;
01487 
01488   
01489    if (!ast || ! MISDN_ASTERISK_PVT(ast)) {
01490       ast_log(LOG_WARNING, "Returnded -1 in misdn_indication\n");
01491       return -1;
01492    }
01493    p = MISDN_ASTERISK_TECH_PVT(ast) ;
01494    
01495    if (!p->bc ) {
01496       chan_misdn_log(1, 0, "* IND : Indication from %s\n",ast->exten);
01497       ast_log(LOG_WARNING, "Private Pointer but no bc ?\n");
01498       return -1;
01499    }
01500    
01501    chan_misdn_log(1, p->bc->port, "* IND : Indication from %s\n",ast->exten);
01502    
01503    switch (cond) {
01504    case AST_CONTROL_BUSY:
01505       chan_misdn_log(1, p->bc->port, "* IND :\tbusy\n");
01506       chan_misdn_log(1, p->bc->port, " --> * SEND: State Busy pid:%d\n",p->bc?p->bc->pid:-1);
01507       ast_setstate(ast,AST_STATE_BUSY);
01508       
01509       p->bc->out_cause=17;
01510       if (p->state != MISDN_CONNECTED) {
01511          misdn_lib_send_event( p->bc, EVENT_DISCONNECT);
01512          manager_send_tone(p->bc, TONE_BUSY);
01513       } else {
01514          chan_misdn_log(0, p->bc->port, " --> !! Got Busy in Connected State !?! port:%d ast:%s\n",
01515                    p->bc->port, ast->name);
01516       }
01517       break;
01518    case AST_CONTROL_RING:
01519       chan_misdn_log(1, p->bc->port, " --> * IND :\tring pid:%d\n",p->bc?p->bc->pid:-1);
01520       break;
01521    case AST_CONTROL_RINGING:
01522       if ( p->state == MISDN_ALERTING) {
01523          chan_misdn_log(1, p->bc->port, " --> * IND :\tringing pid:%d but I ws Ringing before, so ignoreing it\n",p->bc?p->bc->pid:-1);
01524          break;
01525       }
01526       p->state=MISDN_ALERTING;
01527       
01528       chan_misdn_log(1, p->bc->port, " --> * IND :\tringing pid:%d\n",p->bc?p->bc->pid:-1);
01529       
01530       misdn_lib_send_event( p->bc, EVENT_ALERTING);
01531       
01532       manager_send_tone(p->bc, TONE_ALERTING);
01533       chan_misdn_log(1, p->bc->port, " --> * SEND: State Ring pid:%d\n",p->bc?p->bc->pid:-1);
01534       ast_setstate(ast,AST_STATE_RINGING);
01535       break;
01536       
01537    case AST_CONTROL_ANSWER:
01538       chan_misdn_log(1, p->bc->port, " --> * IND :\tanswer pid:%d\n",p->bc?p->bc->pid:-1);
01539       break;
01540    case AST_CONTROL_TAKEOFFHOOK:
01541       chan_misdn_log(1, p->bc->port, " --> *\ttakeoffhook pid:%d\n",p->bc?p->bc->pid:-1);
01542       break;
01543    case AST_CONTROL_OFFHOOK:
01544       chan_misdn_log(1, p->bc->port, " --> *\toffhook pid:%d\n",p->bc?p->bc->pid:-1);
01545       break; 
01546    case AST_CONTROL_FLASH:
01547       chan_misdn_log(1, p->bc->port, " --> *\tflash pid:%d\n",p->bc?p->bc->pid:-1);
01548       break;
01549    case AST_CONTROL_PROGRESS:
01550       chan_misdn_log(1, p->bc->port, " --> * IND :\tprogress pid:%d\n",p->bc?p->bc->pid:-1);
01551       break;
01552    case AST_CONTROL_CONGESTION:
01553       chan_misdn_log(1, p->bc->port, " --> * IND :\tcongestion pid:%d\n",p->bc?p->bc->pid:-1);
01554 
01555       p->bc->out_cause=42;
01556       if (p->state != MISDN_CONNECTED) {
01557          start_bc_tones(p);
01558          //misdn_lib_send_event( p->bc, EVENT_RELEASE_COMPLETE);
01559          misdn_lib_send_event( p->bc, EVENT_RELEASE);
01560       } else {
01561          misdn_lib_send_event( p->bc, EVENT_DISCONNECT);
01562       }
01563       if (p->bc->nt) {
01564          manager_send_tone(p->bc, TONE_BUSY);
01565       }
01566       break;
01567    case -1 :
01568       chan_misdn_log(1, p->bc->port, " --> * IND :\t-1! pid:%d\n",p->bc?p->bc->pid:-1);
01569       break;
01570    case AST_CONTROL_HOLD:
01571       chan_misdn_log(1, p->bc->port, " --> *\tHOLD pid:%d\n",p->bc?p->bc->pid:-1);
01572       break;
01573    case AST_CONTROL_UNHOLD:
01574       chan_misdn_log(1, p->bc->port, " --> *\tUNHOLD pid:%d\n",p->bc?p->bc->pid:-1);
01575       break;
01576    default:
01577       ast_log(LOG_WARNING, " --> * Unknown Indication:%d pid:%d\n",cond,p->bc?p->bc->pid:-1);
01578    }
01579   
01580    return 0;
01581 }

struct ast_channel * misdn_new struct chan_list cl,
int  state,
char *  name,
char *  context,
char *  exten,
char *  callerid,
int  format,
int  port,
int  c
 

Definition at line 2111 of file chan_misdn.c.

References ast_callerid_parse(), ast_channel_alloc(), ast_group_t, ast_log(), ast_print_group(), ast_setstate(), chan_list::bc, ast_channel::callgroup, chan_misdn_log(), ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, ast_channel::context, ast_channel::exten, ast_channel::fds, glob_channel, ast_channel::language, LOG_WARNING, misdn_cfg_get(), ast_channel::name, ast_channel::nativeformats, ast_channel::pickupgroup, chan_list::pipe, ast_channel::priority, ast_channel::readformat, ast_channel::rings, strdup, ast_channel::tech, ast_channel::tech_pvt, ast_channel::type, type, and ast_channel::writeformat.

Referenced by cb_events(), and misdn_request().

02112 {
02113    struct ast_channel *tmp;
02114    
02115    tmp = ast_channel_alloc(1);
02116    
02117    if (tmp) {
02118       chan_misdn_log(2, 0, " --> * NEW CHANNEL dad:%s oad:%s ctx:%s\n",exten,callerid, context);
02119       
02120       
02121       if (c<=0) {
02122          c=glob_channel++;
02123          snprintf(tmp->name, sizeof(tmp->name), "%s/%d-u%d",
02124              type, port, c);
02125       } else {
02126          snprintf(tmp->name, sizeof(tmp->name), "%s/%d-%d",
02127              type, port, c);
02128       }
02129       
02130       tmp->type = type;
02131     
02132       tmp->nativeformats = prefformat;
02133       tmp->readformat = format;
02134       tmp->writeformat = format;
02135     
02136       tmp->tech_pvt = chlist;
02137 
02138       int bridging;
02139       misdn_cfg_get( 0, MISDN_GEN_BRIDGING, &bridging, sizeof(int));
02140       if (bridging)
02141          tmp->tech = &misdn_tech;
02142       else
02143          tmp->tech = &misdn_tech_wo_bridge;
02144     
02145     
02146       tmp->writeformat = format;
02147       tmp->readformat = format;
02148       tmp->priority=1;
02149     
02150       
02151       if (context) {
02152          ast_copy_string(tmp->context, context, sizeof(tmp->context));
02153       }  else {
02154          chan_misdn_log(1,0,"misdn_new: no context given.\n");
02155       }
02156       
02157       if (exten) {
02158          ast_copy_string(tmp->exten, exten,  sizeof(tmp->exten));
02159       } else {
02160          chan_misdn_log(1,0,"misdn_new: no exten given.\n");
02161       }
02162       
02163       if (callerid) {
02164          char *cid_name, *cid_num;
02165       
02166          ast_callerid_parse(callerid, &cid_name, &cid_num);
02167          if (cid_name)
02168             tmp->cid.cid_name=strdup(cid_name);
02169          if (cid_num)
02170             tmp->cid.cid_num=strdup(cid_num);
02171       }
02172 
02173       {
02174          if (pipe(chlist->pipe)<0)
02175             perror("Pipe failed\n");
02176          
02177          tmp->fds[0]=chlist->pipe[0];
02178          
02179       }
02180       
02181       if (chlist->bc) {
02182          int port=chlist->bc->port;
02183          misdn_cfg_get( port, MISDN_CFG_LANGUAGE, tmp->language, sizeof(tmp->language));
02184          
02185          {
02186             char buf[256];
02187             ast_group_t pg,cg;
02188             
02189             misdn_cfg_get(port, MISDN_CFG_PICKUPGROUP, &pg, sizeof(pg));
02190             misdn_cfg_get(port, MISDN_CFG_CALLGROUP, &cg, sizeof(cg));
02191             
02192             chan_misdn_log(2, port, " --> * CallGrp:%s PickupGrp:%s\n",ast_print_group(buf,sizeof(buf),cg),ast_print_group(buf,sizeof(buf),pg));
02193             tmp->pickupgroup=pg;
02194             tmp->callgroup=cg;
02195          }
02196          misdn_cfg_get(port, MISDN_CFG_TXGAIN, &chlist->bc->txgain, sizeof(int));
02197          misdn_cfg_get(port, MISDN_CFG_RXGAIN, &chlist->bc->rxgain, sizeof(int));
02198          chan_misdn_log(2, port, " --> rxgain:%d txgain:%d\n",chlist->bc->rxgain,chlist->bc->txgain);
02199          
02200       } else {
02201          chan_misdn_log(3, 0, " --> Not Setting Pickupgroup, we have no bc yet\n");
02202       }
02203       
02204       ast_setstate(tmp, state);
02205       if (state == AST_STATE_RING)
02206          tmp->rings = 1;
02207       else
02208          tmp->rings = 0;
02209    } else {
02210       ast_log(LOG_WARNING, "Unable to allocate channel structure\n");
02211       chan_misdn_log(0,0,"Unable to allocate channel structure\n");
02212    }
02213    
02214    return tmp;
02215 }

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

Definition at line 442 of file chan_misdn.c.

00443 {
00444    int port;
00445    
00446    if (argc != 4)
00447       return RESULT_SHOWUSAGE;
00448    
00449    port = atoi(argv[3]);
00450    
00451    misdn_lib_get_port_up(port);
00452   
00453    return 0;
00454 }

struct ast_frame* misdn_read struct ast_channel ast  ) 
 

Definition at line 1712 of file chan_misdn.c.

References chan_list::ast, chan_list::ast_rd_buf, chan_list::bc, chan_misdn_trace_call(), ast_frame::data, ast_frame::datalen, chan_list::frame, ast_frame::frametype, ast_frame::mallocd, MISDN_ASTERISK_TECH_PVT, ast_frame::offset, chan_list::pipe, ast_frame::samples, ast_frame::src, and ast_frame::subclass.

01713 {
01714    struct chan_list *tmp;
01715    
01716    char blah[255];
01717    int len =0 ;
01718    
01719    if (!ast) return NULL;
01720    if (! (tmp=MISDN_ASTERISK_TECH_PVT(ast)) ) return NULL;
01721    if (!tmp->bc) return NULL;
01722    
01723    
01724    read(tmp->pipe[0],blah,sizeof(blah));
01725    
01726    
01727    len = misdn_ibuf_usedcount(tmp->bc->astbuf);
01728 
01729    /*shrinken len if necessary, we transmit at maximum 4k*/
01730    len = len<=sizeof(tmp->ast_rd_buf)?len:sizeof(tmp->ast_rd_buf);
01731    
01732    misdn_ibuf_memcpy_r(tmp->ast_rd_buf, tmp->bc->astbuf,len);
01733    
01734    tmp->frame.frametype  = AST_FRAME_VOICE;
01735    tmp->frame.subclass = AST_FORMAT_ALAW;
01736    tmp->frame.datalen = len;
01737    tmp->frame.samples = len ;
01738    tmp->frame.mallocd =0 ;
01739    tmp->frame.offset= 0 ;
01740    tmp->frame.src = NULL;
01741    tmp->frame.data = tmp->ast_rd_buf ;
01742 
01743    chan_misdn_trace_call(tmp->ast,3,"*->I: EVENT_READ len=%d\n",len);
01744    return &tmp->frame;
01745 }

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

Definition at line 549 of file chan_misdn.c.

References ast_cli(), chan_misdn_log(), free_robin_list(), misdn_cfg_get(), misdn_cfg_reload(), misdn_debug, misdn_debug_only, and tracing.

00550 {
00551    int i, cfg_debug;
00552    
00553    ast_cli(fd, "Reloading mISDN Config\n");
00554    chan_misdn_log(0, 0, "Dynamic Crypting Activation is not support during reload at the moment\n");
00555    
00556    free_robin_list();
00557 
00558    misdn_cfg_reload();
00559 
00560    {
00561       char tempbuf[BUFFERSIZE];
00562       misdn_cfg_get( 0, MISDN_GEN_TRACEFILE, tempbuf, BUFFERSIZE);
00563       if (strlen(tempbuf))
00564          tracing = 1;
00565    }
00566 
00567    misdn_cfg_get( 0, MISDN_GEN_DEBUG, &cfg_debug, sizeof(int));
00568    for (i = 0;  i <= max_ports; i++) {
00569       misdn_debug[i] = cfg_debug;
00570       misdn_debug_only[i] = 0;
00571    }
00572    
00573    return 0;
00574 }

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

Definition at line 1917 of file chan_misdn.c.

References ast_log(), AST_STATE_RESERVED, ast_strlen_zero(), chan_list::bc, chan_misdn_log(), robin_list::channel, get_robin_position(), 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(), robin_list::port, and type.

01919 {
01920    struct ast_channel *tmp = NULL;
01921    char group[BUFFERSIZE]="";
01922    char buf[128];
01923    char buf2[128], *ext=NULL, *port_str;
01924    char *tokb=NULL, *p=NULL;
01925    int channel=0, port=0;
01926    struct misdn_bchannel *newbc = NULL;
01927    
01928    struct chan_list *cl=init_chan_list();
01929    
01930    sprintf(buf,"%s/%s",type,(char*)data);
01931    strncpy(buf2,data, 128);
01932    buf2[127] = 0;
01933    port_str=strtok_r(buf2,"/", &tokb);
01934 
01935    ext=strtok_r(NULL,"/", &tokb);
01936 
01937    /*
01938      if (!ext) {
01939      ast_log(LOG_WARNING, " --> ! IND : CALL dad:%s WITH WRONG ARGS, check extension.conf\n",ext);
01940      
01941      return NULL;
01942      }
01943    */
01944    
01945    if (port_str) {
01946       if (port_str[0]=='g' && port_str[1]==':' ) {
01947          /* We make a group call lets checkout which ports are in my group */
01948          port_str += 2;
01949          strncpy(group, port_str, BUFFERSIZE);
01950          group[127] = 0;
01951          chan_misdn_log(2, 0, " --> Group Call group: %s\n",group);
01952       } 
01953       else if ((p = strchr(port_str, ':'))) {
01954          // we have a preselected channel
01955          *p = 0;
01956          channel = atoi(++p);
01957          port = atoi(port_str);
01958          chan_misdn_log(2, port, " --> Call on preselected Channel (%d) on Port %d\n", channel, port);
01959       }
01960       else {
01961          port = atoi(port_str);
01962       }
01963       
01964       
01965    } else {
01966       ast_log(LOG_WARNING, " --> ! IND : CALL dad:%s WITHOUT PORT/Group, check extension.conf\n",ext);
01967       return NULL;
01968    }
01969 
01970    if (!ast_strlen_zero(group)) {
01971    
01972       char cfg_group[BUFFERSIZE];
01973       struct robin_list *rr = NULL;
01974 
01975       if (misdn_cfg_is_group_method(group, METHOD_ROUND_ROBIN)) {
01976          chan_misdn_log(4, port, " --> STARTING ROUND ROBIN...");
01977          rr = get_robin_position(group);
01978       }
01979       
01980       if (rr) {
01981          int robin_channel = rr->channel;
01982          int port_start;
01983          int next_chan = 1;
01984 
01985          do {
01986             port_start = 0;
01987             for (port = misdn_cfg_get_next_port_spin(rr->port); port > 0 && port != port_start;
01988                 port = misdn_cfg_get_next_port_spin(port)) {
01989 
01990                if (!port_start)
01991                   port_start = port;
01992 
01993                if (port >= port_start)
01994                   next_chan = 1;
01995                
01996                if (port < port_start && next_chan) {
01997                   if (++robin_channel >= MAX_BCHANS) {
01998                      robin_channel = 1;
01999                   }
02000                   next_chan = 0;
02001                }
02002 
02003                misdn_cfg_get(port, MISDN_CFG_GROUPNAME, cfg_group, BUFFERSIZE);
02004                
02005                if (!strcasecmp(cfg_group, group)) {
02006                   int l1, port_up;
02007                
02008                   misdn_cfg_get( 0, MISDN_GEN_L1_INFO_OK, &l1, sizeof(l1));
02009                   port_up = misdn_lib_port_up(port);
02010                   
02011                   if ((l1 && port_up) || !l1)   {
02012                      newbc = misdn_lib_get_free_bc(port, robin_channel);
02013                      if (newbc) {
02014                         chan_misdn_log(4, port, " Success! Found port:%d channel:%d\n", newbc->port, newbc->channel);
02015                         if (port_up)
02016                            chan_misdn_log(4, port, "def_l1:%d, portup:%d\n", l1, port_up);
02017                         rr->port = newbc->port;
02018                         rr->channel = newbc->channel;
02019                         break;
02020                      }
02021                   }
02022                }
02023             }
02024          } while (!newbc && robin_channel != rr->channel);
02025          
02026          if (!newbc)
02027             chan_misdn_log(4, port, " Failed! No free channel in group %d!", group);
02028       }
02029       
02030       else {      
02031          for (port=misdn_cfg_get_next_port(0); port > 0;
02032              port=misdn_cfg_get_next_port(port)) {
02033             
02034             misdn_cfg_get( port, MISDN_CFG_GROUPNAME, cfg_group, BUFFERSIZE);
02035             
02036             if (!strcasecmp(cfg_group, group)) {
02037                int l1, port_up;
02038                
02039                misdn_cfg_get( 0, MISDN_GEN_L1_INFO_OK, &l1, sizeof(l1));
02040                port_up = misdn_lib_port_up(port);
02041 
02042                chan_misdn_log(4, port, "def_l1:%d, portup:%d\n", l1, port_up);
02043                
02044                if ((l1 && port_up) || !l1)   {
02045                   newbc = misdn_lib_get_free_bc(port, 0);
02046                   if (newbc)
02047                      break;
02048                }
02049             }
02050          }
02051       }
02052       
02053    } else {
02054       if (channel)
02055          chan_misdn_log(1, port," --> preselected_channel: %d\n",channel);
02056       newbc = misdn_lib_get_free_bc(port, channel);
02057    }
02058    
02059    if (!newbc) {
02060       chan_misdn_log(1, 0, " --> ! No free channel chan ext:%s even after Group Call\n",ext);
02061       chan_misdn_log(1, 0, " --> SEND: State Down\n");
02062       return NULL;
02063    }
02064    
02065    cl->bc=newbc;
02066    
02067    tmp = misdn_new(cl, AST_STATE_RESERVED, buf, "default", ext, ext, format, port, channel);
02068    
02069    return tmp;
02070 }

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

Definition at line 428 of file chan_misdn.c.

00429 {
00430    int port;
00431   
00432    if (argc != 4)
00433       return RESULT_SHOWUSAGE;
00434   
00435    port = atoi(argv[3]);
00436 
00437    misdn_lib_port_restart(port);
00438 
00439    return 0;
00440 }

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

Definition at line 721 of file chan_misdn.c.

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

00722 {
00723    char *channame; 
00724    char *nr; 
00725   
00726    if (argc != 5)
00727       return RESULT_SHOWUSAGE;
00728   
00729    channame = argv[3];
00730    nr = argv[4];
00731    
00732    ast_cli(fd, "Sending Calldeflection (%s) to %s\n",nr, channame);
00733    
00734    {
00735       struct chan_list *tmp=get_chan_by_ast_name(channame);
00736       
00737       if (!tmp) {
00738          ast_cli(fd, "Sending CD with nr %s to %s failed Channel does not exist\n",nr, channame);
00739          return 0; 
00740       } else {
00741          
00742          misdn_lib_send_facility(tmp->bc, FACILITY_CALLDEFLECT, nr);
00743       }
00744    }
00745   
00746    return 0; 
00747 }

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

Definition at line 751 of file chan_misdn.c.

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

00752 {
00753    char *channame; 
00754    char *msg; 
00755   
00756    if (argc != 5)
00757       return RESULT_SHOWUSAGE;
00758   
00759    channame = argv[3];
00760    msg = argv[4];
00761 
00762    ast_cli(fd, "Sending %s to %s\n",msg, channame);
00763   
00764    {
00765       struct chan_list *tmp=get_chan_by_ast_name(channame);
00766     
00767       if (!tmp) {
00768          ast_cli(fd, "Sending %s to %s failed Channel does not exist\n",msg, channame);
00769          return 0; 
00770       } else {
00771 #if 1
00772          int i;
00773          int msglen = strlen(msg);
00774          for (i=0; i<msglen; i++) {
00775             ast_cli(fd, "Sending: %c\n",msg[i]);
00776             send_digit_to_chan(tmp, msg[i]);
00777             /* res = ast_safe_sleep(tmp->ast, 250); */
00778             usleep(250000);
00779             /* res = ast_waitfor(tmp->ast,100); */
00780          }
00781 #else
00782          int res;
00783          res = ast_dtmf_stream(tmp->ast,NULL,msg,250);
00784 #endif
00785       }
00786    }
00787   
00788    return 0; 
00789 }

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

Definition at line 824 of file chan_misdn.c.

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

00825 {
00826    char *channame; 
00827    char *msg; 
00828   
00829    if (argc != 5)
00830       return RESULT_SHOWUSAGE;
00831   
00832    channame = argv[3];
00833    msg = argv[4];
00834 
00835    ast_cli(fd, "Sending %s to %s\n",msg, channame);
00836    {
00837       struct chan_list *tmp;
00838       tmp=get_chan_by_ast_name(channame);
00839     
00840       if (tmp && tmp->bc) {
00841          int l = sizeof(tmp->bc->display);
00842          strncpy(tmp->bc->display, msg, l);
00843          tmp->bc->display[l-1] = 0;
00844          misdn_lib_send_event(tmp->bc, EVENT_INFORMATION);
00845       } else {
00846          ast_cli(fd,"No such channel %s\n",channame);
00847          return RESULT_FAILURE;
00848       }
00849    }
00850 
00851    return RESULT_SUCCESS ;
00852 }

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

Definition at line 420 of file chan_misdn.c.

00421 {
00422    if (argc != 5 )return RESULT_SHOWUSAGE; 
00423 
00424    return 0;
00425 }

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

Definition at line 362 of file chan_misdn.c.

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

00363 {
00364    if (argc != 4 && argc != 5 && argc != 6 && argc != 7)
00365       return RESULT_SHOWUSAGE; 
00366 
00367    int level = atoi(argv[3]);
00368 
00369    switch (argc) {
00370       case 4:  
00371       case 5: {
00372                int only = 0;
00373                if (argc == 5) {
00374                   if (strncasecmp(argv[4], "only", strlen(argv[4])))
00375                      return RESULT_SHOWUSAGE;
00376                   else
00377                      only = 1;
00378                }
00379                int i;
00380                for (i=0; i<=max_ports; i++) {
00381                   misdn_debug[i] = level;
00382                   misdn_debug_only[i] = only;
00383                }
00384                ast_cli(fd, "changing debug level for all ports to %d%s\n",misdn_debug[0], only?" (only)":"");
00385             }
00386             break;
00387       case 6: 
00388       case 7: {
00389                if (strncasecmp(argv[4], "port", strlen(argv[4])))
00390                   return RESULT_SHOWUSAGE;
00391                int port = atoi(argv[5]);
00392                if (port <= 0 || port > max_ports) {
00393                   switch (max_ports) {
00394                      case 0:
00395                         ast_cli(fd, "port number not valid! no ports available so you won't get lucky with any number here...\n");
00396                         break;
00397                      case 1:
00398                         ast_cli(fd, "port number not valid! only port 1 is availble.\n");
00399                         break;
00400                      default:
00401                         ast_cli(fd, "port number not valid! only ports 1 to %d are available.\n", max_ports);
00402                      }
00403                      return 0;
00404                }
00405                if (argc == 7) {
00406                   if (strncasecmp(argv[6], "only", strlen(argv[6])))
00407                      return RESULT_SHOWUSAGE;
00408                   else
00409                      misdn_debug_only[port] = 1;
00410                } else
00411                   misdn_debug_only[port] = 0;
00412                misdn_debug[port] = level;
00413                ast_cli(fd, "changing debug level to %d%s for port %d\n", misdn_debug[port], misdn_debug_only[port]?" (only)":"", port);
00414             }
00415    }
00416    return 0;
00417 }

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

Definition at line 3653 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(), chan_list::dsp, DSP_FEATURE_DTMF_DETECT, DSP_FEATURE_FAX_DETECT, chan_list::faxdetect, LOG_WARNING, MISDN_ASTERISK_TECH_PVT, MISDN_ASTERISK_TYPE, misdn_key_vector, misdn_key_vector_size, chan_list::orginator, and chan_list::trans.

Referenced by load_module(), and misdn_call().

03654 {
03655    struct chan_list *ch = MISDN_ASTERISK_TECH_PVT(chan);
03656    char *tok,*tokb;
03657    int  keyidx=0;
03658    int rxgain=0;
03659    int txgain=0;
03660 
03661    if (strcasecmp(MISDN_ASTERISK_TYPE(chan),"mISDN")) {
03662       ast_log(LOG_WARNING, "misdn_set_opt makes only sense with chan_misdn channels!\n");
03663       return -1;
03664    }
03665    
03666    if (ast_strlen_zero((char *)data)) {
03667       ast_log(LOG_WARNING, "misdn_set_opt Requires arguments\n");
03668       return -1;
03669    }
03670 
03671    for (tok=strtok_r((char*)data, ":",&tokb);
03672         tok;
03673         tok=strtok_r(NULL,":",&tokb) ) {
03674       int neglect=0;
03675       
03676       if (tok[0] == '!' ) {
03677          neglect=1;
03678          tok++;
03679       }
03680       
03681       switch(tok[0]) {
03682          
03683       case 'd' :
03684          strncpy(ch->bc->display,++tok,84);
03685          chan_misdn_log(1, ch->bc->port, "SETOPT: Display:%s\n",ch->bc->display);
03686          break;
03687          
03688       case 'n':
03689          chan_misdn_log(1, ch->bc->port, "SETOPT: No DSP\n");
03690          ch->bc->nodsp=1;
03691          break;
03692 
03693       case 'j':
03694          chan_misdn_log(1, ch->bc->port, "SETOPT: No jitter\n");
03695          ch->bc->nojitter=1;
03696          break;
03697       
03698       case 'v':
03699          tok++;
03700 
03701          switch ( tok[0] ) {
03702          case 'r' :
03703             rxgain=atoi(++tok);
03704             if (rxgain<-8) rxgain=-8;
03705             if (rxgain>8) rxgain=8;
03706             ch->bc->rxgain=rxgain;
03707             chan_misdn_log(1, ch->bc->port, "SETOPT: Volume:%d\n",rxgain);
03708             break;
03709          case 't':
03710             txgain=atoi(++tok);
03711             if (txgain<-8) txgain=-8;
03712             if (txgain>8) txgain=8;
03713             ch->bc->txgain=txgain;
03714             chan_misdn_log(1, ch->bc->port, "SETOPT: Volume:%d\n",txgain);
03715             break;
03716          }
03717          break;
03718       
03719       case 'c':
03720          keyidx=atoi(++tok);
03721       
03722          if (keyidx > misdn_key_vector_size  || keyidx < 0 ) {
03723             ast_log(LOG_WARNING, "You entered the keyidx: %d but we have only %d keys\n",keyidx, misdn_key_vector_size );
03724             continue; 
03725          }
03726       
03727          {
03728             int l = sizeof(ch->bc->crypt_key);
03729             strncpy(ch->bc->crypt_key, misdn_key_vector[keyidx], l);
03730             ch->bc->crypt_key[l-1] = 0;
03731          }
03732          chan_misdn_log(0, ch->bc->port, "SETOPT: crypt with key:%s\n",misdn_key_vector[keyidx]);
03733          break;
03734 
03735       case 'e':
03736          chan_misdn_log(1, ch->bc->port, "SETOPT: EchoCancel\n");
03737          
03738          if (neglect) {
03739             ch->bc->ec_enable=0;
03740          } else {
03741             ch->bc->ec_enable=1;
03742             ch->bc->orig=ch->orginator;
03743             tok++;
03744             if (tok) {
03745                ch->bc->ec_deftaps=atoi(tok);
03746             }
03747          }
03748          
03749          break;
03750       
03751       case 'h':
03752          chan_misdn_log(1, ch->bc->port, "SETOPT: Digital\n");
03753          if (strlen(tok) > 1 && tok[1]=='1') {
03754             chan_misdn_log(1, ch->bc->port, "SETOPT: Digital TRANS_DIGITAL\n");
03755             ch->bc->async=1;
03756             ch->bc->capability=INFO_CAPABILITY_DIGITAL_UNRESTRICTED;
03757             /*ch->bc->state=STATE_CONNECTED;
03758               misdn_lib_setup_bc(ch->bc);*/
03759          } else {
03760             ch->bc->async=0;
03761             ch->bc->capability=INFO_CAPABILITY_DIGITAL_UNRESTRICTED;
03762             /*ch->bc->state=STATE_CONNECTED;
03763               misdn_lib_setup_bc(ch->bc);*/
03764          }
03765          break;
03766             
03767       case 's':
03768          chan_misdn_log(1, ch->bc->port, "SETOPT: Send DTMF\n");
03769          ch->bc->send_dtmf=1;
03770          break;
03771          
03772       case 'f':
03773          chan_misdn_log(1, ch->bc->port, "SETOPT: Faxdetect\n");
03774          ch->faxdetect=1;
03775          break;
03776 
03777       case 'a':
03778          chan_misdn_log(1, ch->bc->port, "SETOPT: AST_DSP (for DTMF)\n");
03779          ch->ast_dsp=1;
03780          break;
03781 
03782       case 'p':
03783          chan_misdn_log(1, ch->bc->port, "SETOPT: callerpres: %s\n",&tok[1]);
03784          /* CRICH: callingpres!!! */
03785          if (strstr(tok,"allowed") ) {
03786             ch->bc->pres=0;
03787          } else if (strstr(tok,"not_screened")) {
03788             ch->bc->pres=1;
03789          }
03790          
03791          
03792          break;
03793       
03794       
03795       default:
03796          break;
03797       }
03798    }
03799    
03800    if (ch->faxdetect || ch->ast_dsp) {
03801       
03802       if (!ch->dsp) ch->dsp = ast_dsp_new();
03803       if (ch->dsp) ast_dsp_set_features(ch->dsp, DSP_FEATURE_DTMF_DETECT| DSP_FEATURE_FAX_DETECT);
03804       if (!ch->trans) ch->trans=ast_translator_build_path(AST_FORMAT_SLINEAR, AST_FORMAT_ALAW);
03805    }
03806 
03807    if (ch->ast_dsp) {
03808       chan_misdn_log(1,ch->bc->port,"SETOPT: with AST_DSP we deactivate mISDN_dsp\n");
03809       ch->bc->nodsp=1;
03810       ch->bc->nojitter=1;
03811    }
03812    
03813    return 0;
03814 }

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

Definition at line 673 of file chan_misdn.c.

References MAXTICS.

00674 {
00675    if (argc != 4)
00676       return RESULT_SHOWUSAGE;
00677   
00678    MAXTICS=atoi(argv[3]);
00679   
00680    return 0;
00681 }

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

Definition at line 647 of file chan_misdn.c.

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

00648 {
00649    struct chan_list *help=cl_te;
00650 
00651    if (argc != 4)
00652       return RESULT_SHOWUSAGE;
00653   
00654    for (;help; help=help->next) {
00655       struct misdn_bchannel *bc=help->bc;   
00656       struct ast_channel *ast=help->ast;
00657     
00658       if (bc && ast) {
00659          if (!strcasecmp(ast->name,argv[3])) {
00660             print_bc_info(fd, help, bc);
00661             break; 
00662          }
00663       } 
00664    }
00665   
00666   
00667    return 0;
00668 }

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

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

00622 {
00623    struct chan_list *help=cl_te;
00624   
00625    ast_cli(fd,"Chan List: %p\n",cl_te); 
00626   
00627    for (;help; help=help->next) {
00628       struct misdn_bchannel *bc=help->bc;   
00629       struct ast_channel *ast=help->ast;
00630       if (misdn_debug[0] > 2) ast_cli(fd, "Bc:%p Ast:%p\n", bc, ast);
00631       if (bc) {
00632          print_bc_info(fd, help, bc);
00633       } else if ( (bc=help->holded_bc) ) {
00634          chan_misdn_log(0, 0, "ITS A HOLDED BC:\n");
00635          print_bc_info(fd, help,  bc);
00636       } else {
00637          ast_cli(fd,"* Channel in unknown STATE !!! Exten:%s, Callerid:%s\n", ast->exten, AST_CID_P(ast));
00638       }
00639    }
00640   
00641   
00642    return 0;
00643 }

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

Definition at line 457 of file chan_misdn.c.

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

00458 {
00459    char buffer[BUFFERSIZE];
00460    enum misdn_cfg_elements elem;
00461    int linebreak;
00462 
00463    int onlyport = -1;
00464    if (argc >= 4) {
00465       if (!sscanf(argv[3], "%d", &onlyport) || onlyport < 0) {
00466          ast_cli(fd, "Unknown option: %s\n", argv[3]);
00467          return RESULT_SHOWUSAGE;
00468       }
00469    }
00470    
00471    if (argc == 3 || onlyport == 0) {
00472       ast_cli(fd,"Misdn General-Config: \n"); 
00473       ast_cli(fd," ->  VERSION: " CHAN_MISDN_VERSION "\n");
00474       
00475       for (elem = MISDN_GEN_FIRST + 1, linebreak = 1; elem < MISDN_GEN_LAST; elem++, linebreak++) {
00476          misdn_cfg_get_config_string( 0, elem, buffer, BUFFERSIZE);
00477          ast_cli(fd, "%-36s%s", buffer, !(linebreak % 2) ? "\n" : "");
00478       }
00479    }
00480 
00481    if (onlyport < 0) {
00482       int port = misdn_cfg_get_next_port(0);
00483       for (; port > 0; port = misdn_cfg_get_next_port(port)) {
00484          ast_cli(fd, "\n[PORT %d]\n", port);
00485          for (elem = MISDN_CFG_FIRST + 1, linebreak = 1; elem < MISDN_CFG_LAST; elem++, linebreak++) {
00486             misdn_cfg_get_config_string( port, elem, buffer, BUFFERSIZE);
00487             ast_cli(fd, "%-36s%s", buffer, !(linebreak % 2) ? "\n" : "");
00488          }  
00489          ast_cli(fd, "\n");
00490       }
00491    }
00492    
00493    if (onlyport > 0) {
00494       if (misdn_cfg_is_port_valid(onlyport)) {
00495          ast_cli(fd, "[PORT %d]\n", onlyport);
00496          for (elem = MISDN_CFG_FIRST + 1, linebreak = 1; elem < MISDN_CFG_LAST; elem++, linebreak++) {
00497             misdn_cfg_get_config_string( onlyport, elem, buffer, BUFFERSIZE);
00498             ast_cli(fd, "%-36s%s", buffer, !(linebreak % 2) ? "\n" : "");
00499          }  
00500          ast_cli(fd, "\n");
00501       } else {
00502          ast_cli(fd, "Port %d is not active!\n", onlyport);
00503       }
00504    }
00505    return 0;
00506 }

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

Definition at line 702 of file chan_misdn.c.

References ast_cli(), misdn_debug, and misdn_debug_only.

00703 {
00704    int port;
00705    
00706    if (argc != 4)
00707       return RESULT_SHOWUSAGE;
00708   
00709    port = atoi(argv[3]);
00710   
00711    ast_cli(fd, "BEGIN STACK_LIST:\n");
00712 
00713    char buf[128];
00714    get_show_stack_details(port,buf);
00715    ast_cli(fd,"  %s  Debug:%d%s\n",buf, misdn_debug[port], misdn_debug_only[port]?"(only)":"");
00716 
00717    
00718    return 0;
00719 }

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

Definition at line 685 of file chan_misdn.c.

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

00686 {
00687    int port;
00688    
00689    ast_cli(fd, "BEGIN STACK_LIST:\n");
00690    for (port=misdn_cfg_get_next_port(0); port > 0;
00691         port=misdn_cfg_get_next_port(port)) {
00692       char buf[128];
00693       get_show_stack_details(port,buf);
00694       ast_cli(fd,"  %s  Debug:%d%s\n", buf, misdn_debug[port], misdn_debug_only[port]?"(only)":"");
00695    }
00696       
00697 
00698    return 0;
00699 
00700 }

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

Definition at line 791 of file chan_misdn.c.

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

00792 {
00793    char *channame; 
00794 
00795    if (argc != 4)
00796       return RESULT_SHOWUSAGE;
00797    
00798    channame = argv[3];
00799   
00800    ast_cli(fd, "Toggling EchoCancel on %s\n", channame);
00801   
00802    {
00803       struct chan_list *tmp=get_chan_by_ast_name(channame);
00804     
00805       if (!tmp) {
00806          ast_cli(fd, "Toggling EchoCancel %s failed Channel does not exist\n", channame);
00807          return 0; 
00808       } else {
00809          tmp->bc->ec_enable=tmp->bc->ec_enable?0:1;
00810 
00811          if (tmp->bc->ec_enable) {
00812             manager_ec_enable(tmp->bc);
00813          } else {
00814             manager_ec_disable(tmp->bc);
00815          }
00816       }
00817    }
00818   
00819    return 0; 
00820 }

int misdn_transfer struct ast_channel ast,
char *  dest
 

Definition at line 1471 of file chan_misdn.c.

References chan_list::bc, chan_misdn_log(), MISDN_ASTERISK_PVT, and MISDN_ASTERISK_TECH_PVT.

01472 {
01473    struct chan_list *p;
01474    
01475    if (!ast || ! MISDN_ASTERISK_PVT(ast)) return -1;
01476    p = MISDN_ASTERISK_TECH_PVT(ast) ;
01477 
01478    chan_misdn_log(1, p->bc?p->bc->port:0, "* IND : Got Transfer %s\n",dest);
01479    return 0;
01480 }

void misdn_transfer_bc struct chan_list tmp_ch,
struct chan_list holded_chan
 

Definition at line 2518 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, chan_list::holded_bc, and ast_channel::name.

Referenced by cb_events().

02519 {
02520    chan_misdn_log(4,0,"TRANSFERING %s to %s\n",holded_chan->ast->name, tmp_ch->ast->name);
02521    
02522    tmp_ch->state=MISDN_HOLD_DISCONNECT;
02523   
02524    ast_moh_stop(AST_BRIDGED_P(holded_chan->ast));
02525 
02526    holded_chan->state=MISDN_CONNECTED;
02527    holded_chan->holded=0;
02528    misdn_lib_transfer(holded_chan->bc?holded_chan->bc:holded_chan->holded_bc);
02529    
02530    ast_channel_masquerade(holded_chan->ast, AST_BRIDGED_P(tmp_ch->ast));
02531 }

int misdn_tx2ast_frm struct chan_list tmp,
char *  buf,
int  len
 

Definition at line 2219 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_log(), ast_queue_frame(), ast_strlen_zero(), ast_translate(), ast_verbose(), chan_list::bc, chan_misdn_log(), ast_channel::context, ast_frame::data, ast_frame::datalen, chan_list::dsp, ast_channel::exten, chan_list::faxdetect, chan_list::faxhandled, ast_frame::frametype, chan_list::holded, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, ast_channel::macrocontext, ast_frame::mallocd, MISDN_ASTERISK_PVT, MISDN_ASTERISK_TECH_PVT, MISDN_CLEANING, MISDN_EXTCANTMATCH, MISDN_WAITING4DIGS, ast_channel::name, chan_list::norxtone, ast_frame::offset, option_verbose, pbx_builtin_setvar_helper(), ast_frame::samples, ast_frame::src, ast_frame::subclass, chan_list::trans, and VERBOSE_PREFIX_3.

Referenced by cb_events().

02220 {
02221    struct ast_frame frame;
02222    
02223    /* If in hold state we drop frame .. */
02224    if (tmp->holded ) return 0;
02225 
02226    switch(tmp->state) {
02227    case MISDN_CLEANING:
02228    case MISDN_EXTCANTMATCH:
02229    case MISDN_WAITING4DIGS:
02230       return 0;
02231    default:
02232       break;
02233    }
02234    
02235    if (tmp->norxtone) {
02236       chan_misdn_log(3, tmp->bc->port, "misdn_tx2ast_frm: Returning because norxtone\n");
02237       return 0;
02238    }
02239    
02240    frame.frametype  = AST_FRAME_VOICE;
02241    frame.subclass = AST_FORMAT_ALAW;
02242    frame.datalen = len;
02243    frame.samples = len ;
02244    frame.mallocd =0 ;
02245    frame.offset= 0 ;
02246    frame.src = NULL;
02247    frame.data = buf ;
02248    
02249    if (tmp->faxdetect || tmp->ast_dsp ) {
02250       struct ast_frame *f,*f2;
02251       if (tmp->trans)
02252          f2=ast_translate(tmp->trans, &frame,0);
02253       else {
02254          chan_misdn_log(0, tmp->bc->port, "No T-Path found\n");
02255          return 0;
02256       }
02257       
02258       f = ast_dsp_process(tmp->ast, tmp->dsp, f2);
02259       if (f && (f->frametype == AST_FRAME_DTMF)) {
02260          ast_log(LOG_DEBUG, "Detected inband DTMF digit: %c", f->subclass);
02261          if (f->subclass == 'f' && tmp->faxdetect) {
02262             /* Fax tone -- Handle and return NULL */
02263             struct ast_channel *ast = tmp->ast;
02264             if (!tmp->faxhandled) {
02265                tmp->faxhandled++;
02266                if (strcmp(ast->exten, "fax")) {
02267                   if (ast_exists_extension(ast, ast_strlen_zero(ast->macrocontext)? ast->context : ast->macrocontext, "fax", 1, AST_CID_P(ast))) {
02268                      if (option_verbose > 2)
02269                         ast_verbose(VERBOSE_PREFIX_3 "Redirecting %s to fax extension\n", ast->name);
02270                      /* Save the DID/DNIS when we transfer the fax call to a "fax" extension */
02271                      pbx_builtin_setvar_helper(ast,"FAXEXTEN",ast->exten);
02272                      if (ast_async_goto(ast, ast->context, "fax", 1))
02273                         ast_log(LOG_WARNING, "Failed to async goto '%s' into fax of '%s'\n", ast->name, ast->context);
02274                   } else
02275                      ast_log(LOG_NOTICE, "Fax detected, but no fax extension ctx:%s exten:%s\n",ast->context, ast->exten);
02276                } else
02277                   ast_log(LOG_DEBUG, "Already in a fax extension, not redirecting\n");
02278             } else
02279                ast_log(LOG_DEBUG, "Fax already handled\n");
02280             frame.frametype = AST_FRAME_NULL;
02281             frame.subclass = 0;
02282             f = &frame;
02283          }  else if ( tmp->ast_dsp) {
02284             struct ast_frame fr;
02285             memset(&fr, 0 , sizeof(fr));
02286             fr.frametype = AST_FRAME_DTMF;
02287             fr.subclass = f->subclass ;
02288             fr.src=NULL;
02289             fr.data = NULL ;
02290             fr.datalen = 0;
02291             fr.samples = 0 ;
02292             fr.mallocd =0 ;
02293             fr.offset= 0 ;
02294             
02295             chan_misdn_log(2, tmp->bc->port, " --> * SEND: DTMF (AST_DSP) :%c\n",f->subclass);
02296             ast_queue_frame(tmp->ast, &fr);
02297             
02298             frame.frametype = AST_FRAME_NULL;
02299             frame.subclass = 0;
02300             f = &frame;
02301          }
02302       }
02303    }
02304    
02305    if (tmp && tmp->ast && MISDN_ASTERISK_PVT (tmp->ast) && MISDN_ASTERISK_TECH_PVT(tmp->ast) ) {
02306 #if MISDN_DEBUG
02307       int i, max=5>len?len:5;
02308     
02309       printf("write2* %p %d bytes: ",tmp, len);
02310     
02311       for (i=0; i<  max ; i++) printf("%2.2x ",((char*) frame.data)[i]);
02312       printf ("\n");
02313 #endif
02314       chan_misdn_log(9, tmp->bc->port, "Queueing %d bytes 2 Asterisk\n",len);
02315       ast_queue_frame(tmp->ast,&frame);
02316       
02317    }  else {
02318       ast_log (LOG_WARNING, "No ast || ast->pvt || ch\n");
02319    }
02320    
02321    return 0;
02322 }

int misdn_write struct ast_channel ast,
struct ast_frame frame
 

Definition at line 1747 of file chan_misdn.c.

References ast_log(), chan_list::bc, chan_misdn_log(), chan_misdn_trace_call(), ast_frame::data, chan_list::holded, LOG_WARNING, MISDN_ASTERISK_TECH_PVT, chan_list::notxtone, ast_frame::samples, and ast_frame::subclass.

01748 {
01749    struct chan_list *p;
01750    int i  = 0;
01751    
01752    if (!ast || ! (p=MISDN_ASTERISK_TECH_PVT(ast)) ) return -1;
01753    
01754    if (!p->bc ) {
01755       ast_log(LOG_WARNING, "private but no bc\n");
01756       return -1;
01757    }
01758    
01759    if (p->bc->tone != TONE_NONE)
01760       manager_send_tone(p->bc,TONE_NONE);
01761    
01762    
01763    if (p->holded ) {
01764       chan_misdn_log(5, p->bc->port, "misdn_write: Returning because holded\n");
01765       return 0;
01766    }
01767    
01768    if (p->notxtone) {
01769       chan_misdn_log(5, p->bc->port, "misdn_write: Returning because notxone\n");
01770       return 0;
01771    }
01772    
01773    if ( !(frame->subclass & prefformat)) {
01774       chan_misdn_log(0, p->bc->port, "Got Unsupported Frame with Format:%d\n", frame->subclass);
01775    }
01776    
01777    
01778 #if MISDN_DEBUG
01779    {
01780       int i, max=5>frame->samples?frame->samples:5;
01781       
01782       printf("write2mISDN %p %d bytes: ", p, frame->samples);
01783       
01784       for (i=0; i<  max ; i++) printf("%2.2x ",((char*) frame->data)[i]);
01785       printf ("\n");
01786    }
01787 #endif
01788    chan_misdn_trace_call(ast,3,"*->I: EVENT_WRITE len=%d\n",frame->samples);
01789    i= manager_tx2misdn_frm(p->bc, frame->data, frame->samples);
01790    
01791    return 0;
01792 }

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

Definition at line 576 of file chan_misdn.c.

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

Referenced by misdn_show_cl(), and misdn_show_cls().

00577 {
00578    struct ast_channel *ast=help->ast;
00579    ast_cli(fd,
00580       "* Pid:%d Prt:%d Ch:%d Mode:%s Org:%s dad:%s oad:%s ctx:%s state:%s\n",
00581       bc->pid, bc->port, bc->channel,
00582       bc->nt?"NT":"TE",
00583       help->orginator == ORG_AST?"*":"I",
00584       ast?ast->exten:NULL,
00585       ast?AST_CID_P(ast):NULL,
00586       ast?ast->context:NULL,
00587       misdn_get_ch_state(help)
00588       );
00589    if (misdn_debug[bc->port] > 0)
00590       ast_cli(fd,
00591          "  --> astname: %s\n"
00592          "  --> ch_l3id: %x\n"
00593          "  --> ch_addr: %x\n"
00594          "  --> bc_addr: %x\n"
00595          "  --> bc_l3id: %x\n"
00596          "  --> tone: %s\n"
00597          "  --> display: %s\n"
00598          "  --> activated: %d\n"
00599          "  --> capability: %s\n"
00600          "  --> echo_cancel: %d\n"
00601          "  --> notone : rx %d tx:%d\n"
00602          "  --> bc_hold: %d holded_bc :%d\n",
00603          help->ast->name,
00604          help->l3id,
00605          help->addr,
00606          bc->addr,
00607          bc?bc->l3_id:-1,
00608          tone2str(bc),
00609          bc->display,
00610          
00611          bc->active,
00612          bearer2str(bc->capability),
00613          bc->ec_enable,
00614          help->norxtone,help->notxtone,
00615          bc->holded, help->holded_bc?1:0
00616          );
00617   
00618 }

void print_bearer struct misdn_bchannel *  bc  )  [static]
 

Definition at line 309 of file chan_misdn.c.

References bearer2str(), and chan_misdn_log().

Referenced by cb_events().

00310 {
00311    
00312    chan_misdn_log(2, bc->port, " --> Bearer: %s\n",bearer2str(bc->capability));
00313    
00314    switch(bc->law) {
00315    case INFO_CODEC_ALAW:
00316       chan_misdn_log(2, bc->port, " --> Codec: Alaw\n");
00317       break;
00318    case INFO_CODEC_ULAW:
00319       chan_misdn_log(2, bc->port, " --> Codec: Ulaw\n");
00320       break;
00321    }
00322 }

void release_chan struct misdn_bchannel *  bc  )  [static]
 

Isdn asks us to release channel, pendant to misdn_hangup *

Definition at line 2422 of file chan_misdn.c.

References ast_channel::_state, chan_list::ast, AST_CID_P, ast_hangup(), ast_queue_hangup(), ast_setstate(), AST_STATE_DOWN, chan_misdn_log(), chan_misdn_trace_call(), cl_dequeue_chan(), cl_te, ast_channel::context, ast_channel::exten, find_chan_by_bc(), find_chan_by_l3id(), free, MISDN_ASTERISK_PVT, MISDN_ASTERISK_TECH_PVT, MISDN_CALLING, MISDN_CALLING_ACKNOWLEDGE, MISDN_CLEANING, MISDN_DIALING, MISDN_EXTCANTMATCH, misdn_get_ch_state(), MISDN_HOLD_DISCONNECT, MISDN_PROGRESS, MISDN_WAITING4DIGS, chan_list::pipe, and send_cause2ast().

Referenced by cb_events().

02422                                                     {
02423    struct ast_channel *ast=NULL;
02424    
02425    {
02426       struct chan_list *ch=find_chan_by_bc(cl_te, bc);
02427       if (!ch) ch=find_chan_by_l3id (cl_te, bc->l3_id);
02428       
02429       release_lock;
02430       if (ch->ast) {
02431          ast=ch->ast;
02432       } 
02433       release_unlock;
02434       
02435       chan_misdn_log(1, bc->port, "Trying to Release bc with l3id: %x\n",bc->l3_id);
02436       if (ch) {
02437          if (ast)
02438             chan_misdn_trace_call(ast,1,"I->*: EVENT_RELEASE\n");
02439          
02440          close(ch->pipe[0]);
02441          close(ch->pipe[1]);
02442          
02443          if (ast && MISDN_ASTERISK_PVT(ast)) {
02444             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));
02445             chan_misdn_log(3, bc->port, " --> * State Down\n");
02446             /* copy cause */
02447             send_cause2ast(ast,bc);
02448             
02449             MISDN_ASTERISK_TECH_PVT(ast)=NULL;
02450             
02451       
02452             if (ast->_state != AST_STATE_RESERVED) {
02453                chan_misdn_log(3, bc->port, " --> Setting AST State to down\n");
02454                ast_setstate(ast, AST_STATE_DOWN);
02455             }
02456             
02457             switch(ch->state) {
02458             case MISDN_EXTCANTMATCH:
02459             case MISDN_WAITING4DIGS:
02460             {
02461                chan_misdn_log(3,  bc->port, " --> * State Wait4dig | ExtCantMatch\n");
02462                ast_hangup(ast);
02463             }
02464             break;
02465             
02466             case MISDN_DIALING:
02467             case MISDN_CALLING_ACKNOWLEDGE:
02468             case MISDN_PROGRESS:
02469                chan_misdn_log(2,  bc->port, "* --> In State Dialin\n");
02470                chan_misdn_log(2,  bc->port, "* --> Queue Hangup\n");
02471                
02472 
02473                ast_queue_hangup(ast);
02474                break;
02475             case MISDN_CALLING:
02476                
02477                chan_misdn_log(2,  bc->port, "* --> In State Callin\n");
02478                
02479                if (!bc->nt) {
02480                   chan_misdn_log(2,  bc->port, "* --> Queue Hangup\n");
02481                   ast_queue_hangup(ast);
02482                } else {
02483                   chan_misdn_log(2,  bc->port, "* --> Hangup\n");
02484                   ast_queue_hangup(ast);
02485                   //ast_hangup(ast);
02486                }
02487                break;
02488                
02489             case MISDN_CLEANING:
02490                /* this state comes out of ast so we mustnt call a ast function ! */
02491                chan_misdn_log(2,  bc->port, "* --> In StateCleaning\n");
02492                break;
02493             case MISDN_HOLD_DISCONNECT:
02494                chan_misdn_log(2,  bc->port, "* --> In HOLD_DISC\n");
02495                break;
02496             default:
02497                chan_misdn_log(2,  bc->port, "* --> In State Default\n");
02498                chan_misdn_log(2,  bc->port, "* --> Queue Hangup\n");
02499    
02500                
02501                if (ast && MISDN_ASTERISK_PVT(ast)) {
02502                   ast_queue_hangup(ast);
02503                } else {
02504                   chan_misdn_log (0,  bc->port, "!! Not really queued!\n");
02505                }
02506             }
02507          }
02508          cl_dequeue_chan(&cl_te, ch);
02509          
02510          free(ch);
02511       } else {
02512          /* chan is already cleaned, so exiting  */
02513       }
02514    }
02515 }

void send_cause2ast struct ast_channel ast,
struct misdn_bchannel *  bc
 

Congestion Cases *

Definition at line 2592 of file chan_misdn.c.

References AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, ast_queue_control(), chan_misdn_log(), and ast_channel::hangupcause.

Referenced by cb_events(), and release_chan().

02592                                                                        {
02593    
02594    ast->hangupcause=bc->cause;
02595    
02596    switch ( bc->cause) {
02597       
02598    case 1: /** Congestion Cases **/
02599    case 2:
02600    case 3:
02601    case 4:
02602    case 22:
02603    case 27:
02604       chan_misdn_log(1, bc?bc->port:0, " --> * SEND: Queue Congestion pid:%d\n", bc?bc->pid:-1);
02605       
02606       ast_queue_control(ast, AST_CONTROL_CONGESTION);
02607       break;
02608       
02609    case 21:
02610    case 17: /* user busy */
02611       chan_misdn_log(1,  bc?bc->port:0, " --> * SEND: Queue Busy pid:%d\n", bc?bc->pid:-1);
02612       
02613       ast_queue_control(ast, AST_CONTROL_BUSY);
02614       
02615       break;
02616    }
02617 }

void send_digit_to_chan struct chan_list cl,
char  digit
 

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

00326 {
00327    static const char* dtmf_tones[] = {
00328       "!941+1336/100,!0/100", /* 0 */
00329       "!697+1209/100,!0/100", /* 1 */
00330       "!697+1336/100,!0/100", /* 2 */
00331       "!697+1477/100,!0/100", /* 3 */
00332       "!770+1209/100,!0/100", /* 4 */
00333       "!770+1336/100,!0/100", /* 5 */
00334       "!770+1477/100,!0/100", /* 6 */
00335       "!852+1209/100,!0/100", /* 7 */
00336       "!852+1336/100,!0/100", /* 8 */
00337       "!852+1477/100,!0/100", /* 9 */
00338       "!697+1633/100,!0/100", /* A */
00339       "!770+1633/100,!0/100", /* B */
00340       "!852+1633/100,!0/100", /* C */
00341       "!941+1633/100,!0/100", /* D */
00342       "!941+1209/100,!0/100", /* * */
00343       "!941+1477/100,!0/100" };  /* # */
00344    struct ast_channel *chan=cl->ast; 
00345   
00346    if (digit >= '0' && digit <='9')
00347       ast_playtones_start(chan,0,dtmf_tones[digit-'0'], 0);
00348    else if (digit >= 'A' && digit <= 'D')
00349       ast_playtones_start(chan,0,dtmf_tones[digit-'A'+10], 0);
00350    else if (digit == '*')
00351       ast_playtones_start(chan,0,dtmf_tones[14], 0);
00352    else if (digit == '#')
00353       ast_playtones_start(chan,0,dtmf_tones[15], 0);
00354    else {
00355       /* not handled */
00356       ast_log(LOG_DEBUG, "Unable to handle DTMF tone '%c' for '%s'\n", digit, chan->name);
00357     
00358     
00359    }
00360 }

int start_bc_tones struct chan_list cl  )  [static]
 

AST INDICATIONS END *

Definition at line 1881 of file chan_misdn.c.

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

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

01882 {
01883    manager_bchannel_activate(cl->bc);
01884    manager_send_tone(cl->bc ,TONE_NONE);
01885    cl->notxtone=0;
01886    cl->norxtone=0;
01887    return 0;
01888 }

int stop_bc_tones struct chan_list cl  )  [static]
 

Definition at line 1890 of file chan_misdn.c.

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

Referenced by cb_events(), and misdn_hangup().

01891 {
01892    if (cl->bc) {
01893       manager_bchannel_deactivate(cl->bc);
01894    }
01895    cl->notxtone=1;
01896    cl->norxtone=1;
01897    
01898    return 0;
01899 }

char* tone2str struct misdn_bchannel *  bc  )  [static]
 

Definition at line 261 of file chan_misdn.c.

References name.

Referenced by print_bc_info().

00262 {
00263    static struct {
00264       char name[16];
00265       enum tone_e tone;
00266    } *tone, tone_buf[] = {
00267       {"NOTONE",TONE_NONE},
00268       {"DIAL",TONE_DIAL},
00269       {"BUSY",TONE_BUSY},
00270       {"ALERT",TONE_ALERTING},
00271       {"",TONE_NONE}
00272    };
00273   
00274   
00275    for (tone=&tone_buf[0]; tone->name[0]; tone++) {
00276       if (tone->tone == bc->tone) return tone->name;
00277    }
00278    return NULL;
00279 }

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

References ast_channel_unregister(), ast_cli_unregister(), ast_log(), ast_unregister_application(), 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.

03451 {
03452    /* First, take us out of the channel loop */
03453    ast_log(LOG_VERBOSE, "-- Unregistering mISDN Channel Driver --\n");
03454    
03455    if (!g_config_initialized) return 0;
03456    
03457    ast_cli_unregister(&cli_send_display);
03458    
03459    ast_cli_unregister(&cli_send_cd);
03460    
03461    ast_cli_unregister(&cli_send_digit);
03462    ast_cli_unregister(&cli_toggle_echocancel);
03463    ast_cli_unregister(&cli_set_tics);
03464   
03465    ast_cli_unregister(&cli_show_cls);
03466    ast_cli_unregister(&cli_show_cl);
03467    ast_cli_unregister(&cli_show_config);
03468    ast_cli_unregister(&cli_show_port);
03469    ast_cli_unregister(&cli_show_stacks);
03470    ast_cli_unregister(&cli_restart_port);
03471    ast_cli_unregister(&cli_port_up);
03472    ast_cli_unregister(&cli_set_debug);
03473    ast_cli_unregister(&cli_set_crypt_debug);
03474    ast_cli_unregister(&cli_reload);
03475    /* ast_unregister_application("misdn_crypt"); */
03476    ast_unregister_application("misdn_set_opt");
03477    ast_unregister_application("misdn_facility");
03478   
03479    ast_channel_unregister(&misdn_tech);
03480 
03481    free_robin_list();
03482    misdn_cfg_destroy();
03483    misdn_lib_destroy();
03484   
03485    if (misdn_debug)
03486       free(misdn_debug);
03487    if (misdn_debug_only)
03488       free(misdn_debug_only);
03489    
03490    return 0;
03491 }

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

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

03494 {
03495    int res;
03496    ast_mutex_lock(&usecnt_lock);
03497    res = usecnt;
03498    ast_mutex_unlock(&usecnt_lock);
03499    return res;
03500 }


Variable Documentation

struct chan_list* cl_te = NULL
 

Definition at line 216 of file chan_misdn.c.

Referenced by cb_events(), misdn_call(), misdn_hangup(), misdn_show_cls(), and release_chan().

ast_mutex_t cl_te_lock
 

Definition at line 217 of file chan_misdn.c.

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

struct ast_cli_entry cli_port_up [static]
 

Definition at line 993 of file chan_misdn.c.

Referenced by load_module(), and unload_module().

struct ast_cli_entry cli_reload [static]
 

Definition at line 953 of file chan_misdn.c.

Referenced by load_module(), and unload_module().

struct ast_cli_entry cli_restart_port [static]
 

Definition at line 985 of file chan_misdn.c.

Referenced by load_module(), and unload_module().

struct ast_cli_entry cli_send_cd [static]
 

Definition at line 904 of file chan_misdn.c.

Referenced by load_module(), and unload_module().

struct ast_cli_entry cli_send_digit [static]
 

Definition at line 913 of file chan_misdn.c.

Referenced by load_module(), and unload_module().

struct ast_cli_entry cli_send_display [static]
 

Definition at line 934 of file chan_misdn.c.

Referenced by load_module(), and unload_module().

struct ast_cli_entry cli_set_crypt_debug [static]
 

Definition at line 1025 of file chan_misdn.c.

Referenced by load_module(), and unload_module().

struct ast_cli_entry cli_set_debug [static]
 

Definition at line 1017 of file chan_misdn.c.

Referenced by load_module(), and unload_module().

struct ast_cli_entry cli_set_tics [static]
 

Definition at line 960 of file chan_misdn.c.

Referenced by load_module(), and unload_module().

struct ast_cli_entry cli_show_cl [static]
 

Definition at line 975 of file chan_misdn.c.

Referenced by load_module(), and unload_module().

struct ast_cli_entry cli_show_cls [static]
 

Definition at line 968 of file chan_misdn.c.

Referenced by load_module(), and unload_module().

struct ast_cli_entry cli_show_config [static]
 

Definition at line 945 of file chan_misdn.c.

Referenced by load_module(), and unload_module().

struct ast_cli_entry cli_show_port [static]
 

Definition at line 1008 of file chan_misdn.c.

Referenced by load_module(), and unload_module().

struct ast_cli_entry cli_show_stacks [static]
 

Definition at line 1001 of file chan_misdn.c.

Referenced by load_module(), and unload_module().

struct ast_cli_entry cli_toggle_echocancel [static]
 

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

struct chan_list dummy_cl
 

Definition at line 214 of file chan_misdn.c.

int g_config_initialized = 0
 

Definition at line 3348 of file chan_misdn.c.

Referenced by load_module().

unsigned long glob_channel = 0
 

Definition at line 2109 of file chan_misdn.c.

Referenced by misdn_new().

ast_mutex_t lock
 

Definition at line 670 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
 

Definition at line 212 of file chan_misdn.c.

Referenced by build_port_config(), free_port_cfg(), load_module(), misdn_cfg_init(), and misdn_set_debug().

int MAXTICS = 8
 

Definition at line 671 of file chan_misdn.c.

Referenced by misdn_set_tics().

int* misdn_debug
 

Definition at line 210 of file chan_misdn.c.

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

int* misdn_debug_only
 

Definition at line 211 of file chan_misdn.c.

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

char** misdn_key_vector = NULL
 

Definition at line 202 of file chan_misdn.c.

Referenced by misdn_set_opt_exec().

int misdn_key_vector_size = 0
 

Definition at line 203 of file chan_misdn.c.

Referenced by misdn_set_opt_exec().

struct ast_channel_tech misdn_tech
 

Definition at line 2073 of file chan_misdn.c.

Referenced by load_module(), and unload_module().

struct ast_channel_tech misdn_tech_wo_bridge
 

Definition at line 2091 of file chan_misdn.c.

int prefformat = AST_FORMAT_ALAW [static]
 

Definition at line 206 of file chan_misdn.c.

ast_mutex_t release_lock_mutex
 

Definition at line 65 of file chan_misdn.c.

Referenced by load_module().

struct robin_list* robin = NULL [static]
 

Definition at line 141 of file chan_misdn.c.

Referenced by free_robin_list(), and get_robin_position().

struct state_struct state_array[]
 

Definition at line 515 of file chan_misdn.c.

Referenced by misdn_get_ch_state().

int tracing = 0
 

Definition at line 198 of file chan_misdn.c.

Referenced by load_module(), and misdn_reload().

char* type = "mISDN" [static]
 

Definition at line 196 of file chan_misdn.c.

int usecnt = 0 [static]
 

Definition at line 200 of file chan_misdn.c.

ast_mutex_t usecnt_lock [static]
 

Definition at line 208 of file chan_misdn.c.

Referenced by usecount().


Generated on Mon Mar 20 08:20:20 2006 for Asterisk - the Open Source PBX by  doxygen 1.3.9.1