Asterisk.org: Developer Documentation (28 Oct 2009)

Wed Oct 28 15:48:31 2009

## Asterisk developer's documentation

# chan_misdn.c File Reference

the chan_misdn channel driver for Asterisk More...

`#include <stdio.h>`
`#include <pthread.h>`
`#include <string.h>`
`#include <sys/socket.h>`
`#include <sys/time.h>`
`#include <errno.h>`
`#include <unistd.h>`
`#include <stdlib.h>`
`#include <arpa/inet.h>`
`#include <fcntl.h>`
`#include <sys/ioctl.h>`
`#include <signal.h>`
`#include <sys/file.h>`
`#include <semaphore.h>`
`#include <asterisk/channel.h>`
`#include <asterisk/config.h>`
`#include <asterisk/logger.h>`
`#include <asterisk/module.h>`
`#include <asterisk/pbx.h>`
`#include <asterisk/options.h>`
`#include <asterisk/io.h>`
`#include <asterisk/frame.h>`
`#include <asterisk/translate.h>`
`#include <asterisk/cli.h>`
`#include <asterisk/musiconhold.h>`
`#include <asterisk/dsp.h>`
`#include <asterisk/file.h>`
`#include <asterisk/callerid.h>`
`#include <asterisk/indications.h>`
`#include <asterisk/app.h>`
`#include <asterisk/features.h>`
`#include <asterisk/sched.h>`
`#include <chan_misdn_config.h>`
`#include <isdn_lib.h>`
`#include <asterisk/strings.h>`

Include dependency graph for chan_misdn.c:

Go to the source code of this file.

## Data Structures

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

## Defines

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

## Enumerations

enum

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

## Functions

static int | _misdn_tasks_add_variable (int timeout, ast_sched_cb callback, void *data, int variable)
static char * | bearer2str (int cap)
static enum event_response_e | cb_events (enum event_e event, struct misdn_bchannel *bc, void *user_data)
int | chan_misdn_jb_empty (struct misdn_bchannel *bc, char *buf, int len)
static void | chan_misdn_log (int level, int port, char *tmpl,...)
static void | cl_dequeue_chan (struct chan_list **list, struct chan_list *chan)
static void | cl_queue_chan (struct chan_list **list, struct chan_list *chan)
static char * | complete_ch (char *line, char *word, int pos, int state)
static char * | complete_ch_helper (char *line, char *word, int pos, int state, int rpos)
static char * | complete_debug_port (char *line, char *word, int pos, int state)
void | config_jitterbuffer (struct chan_list *ch)
void | debug_numplan (int port, int numplan, char *type)
char * | description (void)
| Provides a description of the module.
static int | dialtone_indicate (struct chan_list *cl)
static void | do_immediate_setup (struct misdn_bchannel *bc, struct chan_list *ch, struct ast_channel *ast)
void | export_ch (struct ast_channel *chan, struct misdn_bchannel *bc, struct chan_list *ch)
static struct chan_list * | find_chan_by_bc (struct chan_list *list, struct misdn_bchannel *bc)
static struct chan_list * | find_chan_by_pid (struct chan_list *list, int pid)
static struct chan_list * | find_holded (struct chan_list *list, struct misdn_bchannel *bc)
static struct chan_list * | find_holded_l3 (struct chan_list *list, unsigned long l3_id, int w)
static void | free_robin_list (void)
static void | free_robin_list_r (struct robin_list *r)
static struct chan_list * | get_chan_by_ast (struct ast_channel *ast)
static struct chan_list * | get_chan_by_ast_name (char *name)
static struct robin_list * | get_robin_position (char *group)
static void | hangup_chan (struct chan_list *ch)
static int | hanguptone_indicate (struct chan_list *cl)
void | import_ch (struct ast_channel *chan, struct misdn_bchannel *bc, struct chan_list *ch)
static struct chan_list * | init_chan_list (int orig)
char * | key (void)
| Returns the ASTERISK_GPL_KEY.
int | load_module (void)
| Initialize the module.
static int | misdn_answer (struct ast_channel *ast)
enum ast_bridge_result | misdn_bridge (struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc, int timeoutms)
static int | misdn_call (struct ast_channel *ast, char *dest, int timeout)
static int | misdn_check_l2l1 (struct ast_channel *chan, void *data)
static int | misdn_digit (struct ast_channel *ast, char digit)
static int | misdn_facility_exec (struct ast_channel *chan, void *data)
static int | misdn_fixup (struct ast_channel *oldast, struct ast_channel *ast)
static char * | misdn_get_ch_state (struct chan_list *p)
static int | misdn_hangup (struct ast_channel *ast)
static int | misdn_indication (struct ast_channel *ast, int cond)
void | misdn_jb_destroy (struct misdn_jb *jb)
int | misdn_jb_empty (struct misdn_jb *jb, char *data, int len)
int | misdn_jb_fill (struct misdn_jb *jb, const char *data, int len)
struct misdn_jb * | misdn_jb_init (int size, int upper_threshold)
static struct ast_channel * | misdn_new (struct chan_list *cl, int state, char *exten, char *callerid, int format, int port, int c)
static int | misdn_overlap_dial_task (void *data)
static int | misdn_port_block (int fd, int argc, char *argv[])
static int | misdn_port_down (int fd, int argc, char *argv[])
static int | misdn_port_unblock (int fd, int argc, char *argv[])
static int | misdn_port_up (int fd, int argc, char *argv[])
static struct ast_frame * | misdn_read (struct ast_channel *ast)
static int | misdn_reload (int fd, int argc, char *argv[])
static struct ast_channel * | misdn_request (const char *type, int format, void *data, int *cause)
static int | misdn_restart_pid (int fd, int argc, char *argv[])
static int | misdn_restart_port (int fd, int argc, char *argv[])
static int | misdn_send_cd (int fd, int argc, char *argv[])
static int | misdn_send_digit (int fd, int argc, char *argv[])
static int | misdn_send_display (int fd, int argc, char *argv[])
static int | misdn_send_restart (int fd, int argc, char *argv[])
int | misdn_send_text (struct ast_channel *chan, const char *text)
static int | misdn_set_crypt_debug (int fd, int argc, char *argv[])
static int | misdn_set_debug (int fd, int argc, char *argv[])
static int | misdn_set_opt_exec (struct ast_channel *chan, void *data)
static int | misdn_set_tics (int fd, int argc, char *argv[])
static int | misdn_show_cl (int fd, int argc, char *argv[])
static int | misdn_show_cls (int fd, int argc, char *argv[])
static int | misdn_show_config (int fd, int argc, char *argv[])
static int | misdn_show_port (int fd, int argc, char *argv[])
static int | misdn_show_stacks (int fd, int argc, char *argv[])
static int | misdn_tasks_add_variable (int timeout, ast_sched_cb callback, void *data)
static void | misdn_tasks_destroy (void)
static void | misdn_tasks_init (void)
static void | misdn_tasks_remove (int task_id)
static void * | misdn_tasks_thread_func (void *data)
static void | misdn_tasks_wakeup (void)
static int | misdn_toggle_echocancel (int fd, int argc, char *argv[])
static void | misdn_transfer_bc (struct chan_list *tmp_ch, struct chan_list *holded_chan)
static int | misdn_write (struct ast_channel *ast, struct ast_frame *frame)
static int | pbx_start_chan (struct chan_list *ch)
static void | print_bc_info (int fd, struct chan_list *help, struct misdn_bchannel *bc)
static void | print_bearer (struct misdn_bchannel *bc)
static void | print_facility (struct misdn_bchannel *bc)
static struct ast_frame * | process_ast_dsp (struct chan_list *tmp, struct ast_frame *frame)
static int | read_config (struct chan_list *ch, int orig)
static void | release_chan (struct misdn_bchannel *bc)
int | reload (void)
| Reload stuff.
static void | reload_config (void)
static void | send_cause2ast (struct ast_channel *ast, struct misdn_bchannel *bc, struct chan_list *ch)
static void | send_digit_to_chan (struct chan_list *cl, char digit)
static void | sighandler (int sig)
static int | start_bc_tones (struct chan_list *cl)
static void | start_pbx (struct chan_list *ch, struct misdn_bchannel *bc, struct ast_channel *chan)
static int | stop_bc_tones (struct chan_list *cl)
static int | stop_indicate (struct chan_list *cl)
int | unload_module (void)
| Cleanup all module structures, sockets, etc.
static int | update_config (struct chan_list *ch, int orig)
static int | update_ec_config (struct misdn_bchannel *bc)
int | usecount (void)
| Provides a usecount.
static void | wait_for_digits (struct chan_list *ch, struct misdn_bchannel *bc, struct ast_channel *chan)

## Variables

struct allowed_bearers | allowed_bearers_array []
struct chan_list * | cl_te = NULL
ast_mutex_t | cl_te_lock
static struct ast_cli_entry | cli_port_block
static struct ast_cli_entry | cli_port_down
static struct ast_cli_entry | cli_port_unblock
static struct ast_cli_entry | cli_port_up
static struct ast_cli_entry | cli_reload
static struct ast_cli_entry | cli_restart_pid
static struct ast_cli_entry | cli_restart_port
static struct ast_cli_entry | cli_send_cd
static struct ast_cli_entry | cli_send_digit
static struct ast_cli_entry | cli_send_display
static struct ast_cli_entry | cli_send_restart
static struct ast_cli_entry | cli_set_crypt_debug
static struct ast_cli_entry | cli_set_debug
static struct ast_cli_entry | cli_set_tics
static struct ast_cli_entry | cli_show_cl
static struct ast_cli_entry | cli_show_cls
static struct ast_cli_entry | cli_show_config
static struct ast_cli_entry | cli_show_port
static struct ast_cli_entry | cli_show_stacks
static struct ast_cli_entry | cli_toggle_echocancel
static char * | desc = "Channel driver for mISDN Support (Bri/Pri)"
struct chan_list | dummy_cl
static int | g_config_initialized = 0
static unsigned long | glob_channel = 0
char | global_tracefile [BUFFERSIZE+1]
ast_mutex_t | lock
static int | max_ports
int | MAXTICS = 8
static int * | misdn_debug
static int * | misdn_debug_only
static struct sched_context * | misdn_tasks = NULL
static pthread_t | misdn_tasks_thread
static struct ast_channel_tech | misdn_tech
static struct ast_channel_tech | misdn_tech_wo_bridge
static const char | misdn_type [] = "mISDN"
static int | prefformat = AST_FORMAT_ALAW
ast_mutex_t | release_lock
static struct robin_list * | robin = NULL
static struct state_struct | state_array []
static int | tracing = 0
static int | usecnt = 0
static ast_mutex_t | usecnt_lock

## Detailed Description

the chan_misdn channel driver for Asterisk

Author:
  Christian Richter <crich@beronet.com>

Definition in file chan_misdn.c.

## Define Documentation

#define AST_BRIDGED_P | ( | ast |  | ) | ast_bridged_channel(ast)

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

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

#define AST_DESTROY_CFG ast_config_destroy

Definition at line 288 of file chan_misdn.c.

Referenced by misdn_cfg_init().

#define AST_LOAD_CFG ast_config_load

Definition at line 287 of file chan_misdn.c.

Referenced by misdn_cfg_init().

#define MISDN_ASTERISK_PVT | ( | ast |  | ) | 1

Definition at line 291 of file chan_misdn.c.

Referenced by cb_events(), and do_immediate_setup().

#define MISDN_ASTERISK_TECH_PVT | ( | ast |  | ) | ast->tech_pvt

Definition at line 290 of file chan_misdn.c.

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

#define ORG_AST 1

Definition at line 135 of file chan_misdn.c.

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

#define ORG_MISDN 2

Definition at line 136 of file chan_misdn.c.

Referenced by cb_events(), and misdn_indication().

## Enumeration Type Documentation

enum misdn_chan_state

Enumerator:

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

Definition at line 109 of file chan_misdn.c.

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

## Function Documentation

static int _misdn_tasks_add_variable | ( | int | timeout,
|  | ast_sched_cb | callback,
|  | void * | data,
|  | int | variable |
| ) |  |  | `[inline, static]`

Definition at line 519 of file chan_misdn.c.

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

Referenced by misdn_tasks_add_variable().

    00520 {
    00521    int task_id;
    00522
    00523    if (!misdn_tasks) {
    00524       misdn_tasks_init();
    00525    }
    00526    task_id = ast_sched_add_variable(misdn_tasks, timeout, callback, data, variable);
    00527    misdn_tasks_wakeup();
    00528
    00529    return task_id;
    00530 }

static char* bearer2str | ( | int | cap | ) | `[static]`

Definition at line 390 of file chan_misdn.c.

Referenced by print_bc_info(), and print_bearer().

    00390                                  {
    00391    static char *bearers[]={
    00392       "Speech",
    00393       "Audio 3.1k",
    00394       "Unres Digital",
    00395       "Res Digital",
    00396       "Video",
    00397       "Unknown Bearer"
    00398    };
    00399
    00400    switch (cap) {
    00401    case INFO_CAPABILITY_SPEECH:
    00402       return bearers[0];
    00403       break;
    00404    case INFO_CAPABILITY_AUDIO_3_1K:
    00405       return bearers[1];
    00406       break;
    00407    case INFO_CAPABILITY_DIGITAL_UNRESTRICTED:
    00408       return bearers[2];
    00409       break;
    00410    case INFO_CAPABILITY_DIGITAL_RESTRICTED:
    00411       return bearers[3];
    00412       break;
    00413    case INFO_CAPABILITY_VIDEO:
    00414       return bearers[4];
    00415       break;
    00416    default:
    00417       return bearers[5];
    00418       break;
    00419    }
    00420 }

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

queue new chan

Sending SETUP_ACK

Suplementary Services

Definition at line 3561 of file chan_misdn.c.

References chan_list::addr, chan_list::allowed_bearers, chan_list::ast, AST_BRIDGED_P, ast_canmatch_extension(), ast_cdr_update(), AST_CONTROL_ANSWER, AST_CONTROL_BUSY, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_RINGING, ast_deactivate_generator(), ast_exists_extension(), AST_FORMAT_ALAW, AST_FRAME_DTMF, AST_FRAME_VOICE, ast_log(), ast_moh_start(), ast_moh_stop(), ast_mutex_lock(), ast_mutex_unlock(), ast_pickup_call(), ast_pickup_ext(), AST_PRES_ALLOWED, AST_PRES_NETWORK_NUMBER, AST_PRES_RESTRICTED, AST_PRES_UNAVAILABLE, AST_PRES_USER_NUMBER_FAILED_SCREEN, AST_PRES_USER_NUMBER_PASSED_SCREEN, AST_PRES_USER_NUMBER_UNSCREENED, ast_queue_control(), ast_queue_frame(), ast_setstate(), AST_STATE_DOWN, AST_STATE_RESERVED, AST_STATE_RINGING, ast_strlen_zero(), ast_transfercapability2str(), chan_list::bc, chan_misdn_log(), hold_info::channel, ast_channel::cid, ast_callerid::cid_pres, cl_queue_chan(), chan_list::context, ast_frame::data, ast_frame::datalen, ast_frame::delivery, do_immediate_setup(), export_ch(), ast_channel::exten, chan_list::far_alerting, find_chan_by_bc(), find_holded(), find_holded_l3(), ast_frame::frametype, ast_generator::generate, ast_channel::generator, ast_channel::generatordata, hangup_chan(), ast_channel::hangupcause, hanguptone_indicate(), chan_list::hold_info, chan_list::ignore_dtmf, init_chan_list(), chan_list::l3id, LOG_ERROR, LOG_NOTICE, LOG_WARNING, ast_frame::mallocd, MISDN_ALERTING, MISDN_ASTERISK_PVT, MISDN_ASTERISK_TECH_PVT, MISDN_CALLING, MISDN_CALLING_ACKNOWLEDGE, misdn_cfg_get(), misdn_cfg_is_msn_valid(), MISDN_CLEANING, MISDN_CONNECTED, MISDN_DIALING, MISDN_DISCONNECTED, MISDN_EXTCANTMATCH, misdn_get_ch_state(), MISDN_HOLDED, MISDN_INCOMING_SETUP, misdn_new(), MISDN_NOTHING, misdn_overlap_dial_task(), MISDN_PROCEEDING, MISDN_PROGRESS, misdn_tasks_add_variable(), misdn_transfer_bc(), MISDN_WAITING4DIGS, allowed_bearers::name, chan_list::need_busy, chan_list::noautorespond_on_setup, chan_list::nttimeout, ast_frame::offset, ORG_AST, ORG_MISDN, chan_list::orginator, chan_list::overlap_dial, chan_list::overlap_dial_task, chan_list::overlap_tv, chan_list::overlap_tv_lock, pbx_builtin_setvar_helper(), chan_list::pipe, hold_info::port, print_bearer(), print_facility(), read_config(), release_chan(), ast_channel::rings, ast_frame::samples, ast_frame::src, start_bc_tones(), start_pbx(), chan_list::state, stop_bc_tones(), stop_indicate(), ast_frame::subclass, t, ast_channel::tech, ast_channel::transfercapability, ast_channel_tech::type, and wait_for_digits().

Referenced by load_module().

    03562 {
    03563    struct chan_list *ch=find_chan_by_bc(cl_te, bc);
    03564
    03565    if (event != EVENT_BCHAN_DATA && event != EVENT_TONE_GENERATE) { /*  Debug Only Non-Bchan */
    03566       int debuglevel=1;
    03567       if ( event==EVENT_CLEANUP && !user_data)
    03568          debuglevel=5;
    03569
    03570       chan_misdn_log(debuglevel, bc->port, "I IND :%s oad:%s dad:%s pid:%d state:%s\n", manager_isdn_get_info(event), bc->oad, bc->dad, bc->pid, ch?misdn_get_ch_state(ch):"none");
    03571       if (debuglevel==1) {
    03572          misdn_lib_log_ies(bc);
    03573          chan_misdn_log(4,bc->port," --> bc_state:%s\n",bc_state2str(bc->bc_state));
    03574       }
    03575    }
    03576
    03577    if (!ch) {
    03578       switch(event) {
    03579          case EVENT_SETUP:
    03580          case EVENT_DISCONNECT:
    03581          case EVENT_PORT_ALARM:
    03582          case EVENT_RETRIEVE:
    03583          case EVENT_NEW_BC:
    03584             break;
    03585          case EVENT_RELEASE_COMPLETE:
    03586             chan_misdn_log(1, bc->port, " --> no Ch, so we've already released.\n");
    03587             break;
    03588          case EVENT_CLEANUP:
    03589          case EVENT_TONE_GENERATE:
    03590          case EVENT_BCHAN_DATA:
    03591             return -1;
    03592
    03593          default:
    03594             chan_misdn_log(1,bc->port, "Chan not existing at the moment bc->l3id:%x bc:%p event:%s port:%d channel:%d\n",bc->l3_id, bc, manager_isdn_get_info( event), bc->port,bc->channel);
    03595             return -1;
    03596       }
    03597    }
    03598
    03599    if (ch ) {
    03600       switch (event) {
    03601       case EVENT_TONE_GENERATE:
    03602       break;
    03603       case EVENT_DISCONNECT:
    03604       case EVENT_RELEASE:
    03605       case EVENT_RELEASE_COMPLETE:
    03606       case EVENT_CLEANUP:
    03607       case EVENT_TIMEOUT:
    03608          if (!ch->ast)
    03609             chan_misdn_log(3,bc->port,"ast_hangup already called, so we have no ast ptr anymore in event(%s)\n",manager_isdn_get_info(event));
    03610          break;
    03611       default:
    03612          if ( !ch->ast  || !MISDN_ASTERISK_PVT(ch->ast) || !MISDN_ASTERISK_TECH_PVT(ch->ast)) {
    03613             if (event!=EVENT_BCHAN_DATA)
    03614                ast_log(LOG_NOTICE, "No Ast or No private Pointer in Event (%d:%s)\n", event, manager_isdn_get_info(event));
    03615             return -1;
    03616          }
    03617       }
    03618    }
    03619
    03620
    03621    switch (event) {
    03622    case EVENT_PORT_ALARM:
    03623       {
    03624          int boa=0;
    03625
    03626          misdn_cfg_get( bc->port, MISDN_CFG_ALARM_BLOCK, &boa, sizeof(int));
    03627          if (boa) {
    03628             cb_log(1,bc->port," --> blocking\n");
    03629             misdn_lib_port_block(bc->port);
    03630          }
    03631       }
    03632       break;
    03633
    03634    case EVENT_BCHAN_ACTIVATED:
    03635       break;
    03636
    03637    case EVENT_NEW_L3ID:
    03638       ch->l3id=bc->l3_id;
    03639       ch->addr=bc->addr;
    03640       break;
    03641
    03642    case EVENT_NEW_BC:
    03643       if (!ch) {
    03644          ch=find_holded(cl_te,bc);
    03645       }
    03646
    03647       if (!ch) {
    03648          ast_log(LOG_WARNING,"NEW_BC without chan_list?\n");
    03649          break;
    03650       }
    03651
    03652       if (bc)
    03653          ch->bc=(struct misdn_bchannel*)user_data;
    03654       break;
    03655
    03656    case EVENT_DTMF_TONE:
    03657    {
    03658       /*  sending INFOS as DTMF-Frames :) */
    03659       struct ast_frame fr;
    03660       memset(&fr, 0 , sizeof(fr));
    03661       fr.frametype = AST_FRAME_DTMF;
    03662       fr.subclass = bc->dtmf ;
    03663       fr.src=NULL;
    03664       fr.data = NULL ;
    03665       fr.datalen = 0;
    03666       fr.samples = 0 ;
    03667       fr.mallocd =0 ;
    03668       fr.offset= 0 ;
    03669       fr.delivery= ast_tv(0,0) ;
    03670
    03671       if (!ch->ignore_dtmf) {
    03672          chan_misdn_log(2, bc->port, " --> DTMF:%c\n", bc->dtmf);
    03673          ast_queue_frame(ch->ast, &fr);
    03674       } else {
    03675          chan_misdn_log(2, bc->port, " --> Ingoring DTMF:%c due to bridge flags\n", bc->dtmf);
    03676       }
    03677    }
    03678    break;
    03679    case EVENT_STATUS:
    03680       break;
    03681
    03682    case EVENT_INFORMATION:
    03683    {
    03684       int l;
    03685
    03686       if ( ch->state != MISDN_CONNECTED )
    03687          stop_indicate(ch);
    03688
    03689       if (!ch->ast) break;
    03690
    03691       if (ch->state == MISDN_WAITING4DIGS ) {
    03692          /*  Ok, incomplete Setup, waiting till extension exists */
    03693          if (ast_strlen_zero(bc->info_dad) && ! ast_strlen_zero(bc->keypad)) {
    03694             chan_misdn_log(1, bc->port, " --> using keypad as info\n");
    03695             strcpy(bc->info_dad,bc->keypad);
    03696          }
    03697
    03698          l = sizeof(bc->dad);
    03699          strncat(bc->dad,bc->info_dad, l);
    03700          bc->dad[l-1] = 0;
    03701
    03702          l = sizeof(ch->ast->exten);
    03703          strncpy(ch->ast->exten, bc->dad, l);
    03704          ch->ast->exten[l-1] = 0;
    03705
    03706          /* Check for Pickup Request first */
    03707          if (!strcmp(ch->ast->exten, ast_pickup_ext())) {
    03708             if (ast_pickup_call(ch->ast)) {
    03709                hangup_chan(ch);
    03710             } else {
    03711                struct ast_channel *chan=ch->ast;
    03712                ch->state = MISDN_CALLING_ACKNOWLEDGE;
    03713                ast_setstate(chan, AST_STATE_DOWN);
    03714                hangup_chan(ch);
    03715                ch->ast=NULL;
    03716                break;
    03717             }
    03718          }
    03719
    03720          if(!ast_canmatch_extension(ch->ast, ch->context, bc->dad, 1, bc->oad)) {
    03721             if (ast_exists_extension(ch->ast, ch->context, "i", 1, bc->oad)) {
    03722                ast_log(LOG_WARNING, "Extension can never match, So jumping to 'i' extension. port(%d)\n",bc->port);
    03723                strcpy(ch->ast->exten, "i");
    03724
    03725                ch->state = MISDN_DIALING;
    03726                start_pbx(ch, bc, ch->ast);
    03727                break;
    03728             }
    03729
    03730             ast_log(LOG_WARNING, "Extension can never match, so disconnecting on port(%d)."
    03731                   "maybe you want to add an 'i' extension to catch this case.\n",
    03732                   bc->port);
    03733
    03734             if (bc->nt)
    03735                hanguptone_indicate(ch);
    03736             ch->state=MISDN_EXTCANTMATCH;
    03737             bc->out_cause=1;
    03738
    03739             misdn_lib_send_event(bc, EVENT_DISCONNECT );
    03740             break;
    03741          }
    03742
    03743          if (ch->overlap_dial) {
    03744             ast_mutex_lock(&ch->overlap_tv_lock);
    03745             ch->overlap_tv = ast_tvnow();
    03746             ast_mutex_unlock(&ch->overlap_tv_lock);
    03747             if (ch->overlap_dial_task == -1) {
    03748                ch->overlap_dial_task =
    03749                   misdn_tasks_add_variable(ch->overlap_dial, misdn_overlap_dial_task, ch);
    03750             }
    03751             break;
    03752          }
    03753
    03754          if (ast_exists_extension(ch->ast, ch->context, bc->dad, 1, bc->oad))  {
    03755
    03756             ch->state = MISDN_DIALING;
    03757             start_pbx(ch, bc, ch->ast);
    03758          }
    03759       } else {
    03760          /*  sending INFOS as DTMF-Frames :) */
    03761          struct ast_frame fr;
    03762          fr.frametype = AST_FRAME_DTMF;
    03763          fr.subclass = bc->info_dad[0] ;
    03764          fr.src=NULL;
    03765          fr.data = NULL ;
    03766          fr.datalen = 0;
    03767          fr.samples = 0 ;
    03768          fr.mallocd =0 ;
    03769          fr.offset= 0 ;
    03770          fr.delivery= ast_tv(0,0) ;
    03771
    03772
    03773          int digits;
    03774          misdn_cfg_get( 0, MISDN_GEN_APPEND_DIGITS2EXTEN, &digits, sizeof(int));
    03775          if (ch->state != MISDN_CONNECTED ) {
    03776             if (digits) {
    03777                int l = sizeof(bc->dad);
    03778                strncat(bc->dad,bc->info_dad, l);
    03779                bc->dad[l-1] = 0;
    03780                l = sizeof(ch->ast->exten);
    03781                strncpy(ch->ast->exten, bc->dad, l);
    03782                ch->ast->exten[l-1] = 0;
    03783
    03784                ast_cdr_update(ch->ast);
    03785             }
    03786
    03787             ast_queue_frame(ch->ast, &fr);
    03788          }
    03789       }
    03790    }
    03791    break;
    03792    case EVENT_SETUP:
    03793    {
    03794       struct chan_list *ch=find_chan_by_bc(cl_te, bc);
    03795       if (ch) {
    03796          switch (ch->state) {
    03797             case MISDN_NOTHING:
    03798             ch=NULL;
    03799             break;
    03800             default:
    03801             chan_misdn_log(1, bc->port, " --> Ignoring Call we have already one\n");
    03802             return RESPONSE_IGNORE_SETUP_WITHOUT_CLOSE; /*  Ignore MSNs which are not in our List */
    03803          }
    03804       }
    03805    }
    03806
    03807    {
    03808       int msn_valid = misdn_cfg_is_msn_valid(bc->port, bc->dad);
    03809       if (!bc->nt && ! msn_valid) {
    03810          chan_misdn_log(1, bc->port, " --> Ignoring Call, its not in our MSN List\n");
    03811          return RESPONSE_IGNORE_SETUP; /*  Ignore MSNs which are not in our List */
    03812       }
    03813
    03814       if (bc->cw) {
    03815          chan_misdn_log(0, bc->port, " --> Call Waiting on PMP sending RELEASE_COMPLETE\n");
    03816          int cause;
    03817          misdn_cfg_get( bc->port, MISDN_CFG_REJECT_CAUSE, &cause, sizeof(cause));
    03818          bc->out_cause=cause?cause:16;
    03819          return RESPONSE_RELEASE_SETUP;
    03820       }
    03821
    03822       print_bearer(bc);
    03823
    03824       struct chan_list *ch=init_chan_list(ORG_MISDN);
    03825       struct ast_channel *chan;
    03826
    03827       if (!ch) { chan_misdn_log(-1, bc->port, "cb_events: malloc for chan_list failed!\n"); return 0;}
    03828
    03829       ch->bc = bc;
    03830       ch->l3id=bc->l3_id;
    03831       ch->addr=bc->addr;
    03832       ch->orginator = ORG_MISDN;
    03833
    03834       chan=misdn_new(ch, AST_STATE_RESERVED,bc->dad, bc->oad, AST_FORMAT_ALAW, bc->port, bc->channel);
    03835
    03836       if (!chan) {
    03837          misdn_lib_send_event(bc,EVENT_RELEASE_COMPLETE);
    03838          ast_log(LOG_ERROR, "cb_events: misdn_new failed !\n");
    03839          return 0;
    03840       }
    03841
    03842       ch->ast = chan;
    03843
    03844       read_config(ch, ORG_MISDN);
    03845
    03846       export_ch(chan, bc, ch);
    03847
    03848       ch->ast->rings=1;
    03849       ast_setstate(ch->ast, AST_STATE_RINGING);
    03850
    03851       int pres,screen;
    03852
    03853       switch (bc->pres) {
    03854          case 1:
    03855             pres=AST_PRES_RESTRICTED; chan_misdn_log(2,bc->port," --> PRES: Restricted (1)\n");
    03856             break;
    03857          case 2:
    03858             pres=AST_PRES_UNAVAILABLE; chan_misdn_log(2,bc->port," --> PRES: Restricted (2)\n");
    03859             break;
    03860          default:
    03861             pres=AST_PRES_ALLOWED; chan_misdn_log(2,bc->port," --> PRES: Restricted (%d)\n", bc->pres);
    03862       }
    03863
    03864       switch (bc->screen) {
    03865          case 0:
    03866             screen=AST_PRES_USER_NUMBER_UNSCREENED;  chan_misdn_log(2,bc->port," --> SCREEN: Unscreened (0)\n");
    03867             break;
    03868          case 1:
    03869             screen=AST_PRES_USER_NUMBER_PASSED_SCREEN; chan_misdn_log(2,bc->port," --> SCREEN: Passed screen (1)\n");
    03870             break;
    03871          case 2:
    03872             screen=AST_PRES_USER_NUMBER_FAILED_SCREEN; chan_misdn_log(2,bc->port," --> SCREEN: failed screen (2)\n");
    03873             break;
    03874          case 3:
    03875             screen=AST_PRES_NETWORK_NUMBER; chan_misdn_log(2,bc->port," --> SCREEN: Network Number (3)\n");
    03876             break;
    03877          default:
    03878             screen=AST_PRES_USER_NUMBER_UNSCREENED; chan_misdn_log(2,bc->port," --> SCREEN: Unscreened (%d)\n",bc->screen);
    03879       }
    03880
    03881       chan->cid.cid_pres=pres+screen;
    03882
    03883       pbx_builtin_setvar_helper(chan, "TRANSFERCAPABILITY", ast_transfercapability2str(bc->capability));
    03884       chan->transfercapability=bc->capability;
    03885
    03886       switch (bc->capability) {
    03887          case INFO_CAPABILITY_DIGITAL_UNRESTRICTED:
    03888             pbx_builtin_setvar_helper(chan,"CALLTYPE","DIGITAL");
    03889             break;
    03890          default:
    03891             pbx_builtin_setvar_helper(chan,"CALLTYPE","SPEECH");
    03892       }
    03893
    03894       /** queue new chan **/
    03895       cl_queue_chan(&cl_te, ch) ;
    03896
    03897       if (!strstr(ch->allowed_bearers,"all")) {
    03898          int i;
    03899          for (i=0; i< sizeof(allowed_bearers_array)/sizeof(struct allowed_bearers); i++) {
    03900             if (allowed_bearers_array[i].cap == bc->capability) {
    03901                if (  !strstr( ch->allowed_bearers, allowed_bearers_array[i].name)) {
    03902                   chan_misdn_log(0,bc->port,"Bearer Not allowed\b");
    03903                   bc->out_cause=88;
    03904
    03905                   ch->state=MISDN_EXTCANTMATCH;
    03906                   misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE );
    03907                   return RESPONSE_OK;
    03908                }
    03909             }
    03910
    03911          }
    03912       }
    03913
    03914       /* Check for Pickup Request first */
    03915       if (!strcmp(chan->exten, ast_pickup_ext())) {
    03916          if (!ch->noautorespond_on_setup) {
    03917             int ret;/** Sending SETUP_ACK**/
    03918             ret = misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE );
    03919          } else {
    03920             ch->state = MISDN_INCOMING_SETUP;
    03921          }
    03922          if (ast_pickup_call(chan)) {
    03923             hangup_chan(ch);
    03924          } else {
    03925             ch->state = MISDN_CALLING_ACKNOWLEDGE;
    03926             ast_setstate(chan, AST_STATE_DOWN);
    03927             hangup_chan(ch);
    03928             ch->ast=NULL;
    03929             break;
    03930          }
    03931       }
    03932
    03933       /*
    03934          added support for s extension hope it will help those poor cretains
    03935          which haven't overlap dial.
    03936          */
    03937       int ai;
    03938       misdn_cfg_get( bc->port, MISDN_CFG_ALWAYS_IMMEDIATE, &ai, sizeof(ai));
    03939       if ( ai ) {
    03940          do_immediate_setup(bc, ch , chan);
    03941          break;
    03942       }
    03943
    03944       /* check if we should jump into s when we have no dad */
    03945       int im;
    03946       misdn_cfg_get( bc->port, MISDN_CFG_IMMEDIATE, &im, sizeof(im));
    03947       if ( im && ast_strlen_zero(bc->dad) ) {
    03948          do_immediate_setup(bc, ch , chan);
    03949          break;
    03950       }
    03951
    03952       chan_misdn_log(5,bc->port,"CONTEXT:%s\n",ch->context);
    03953       if(!ast_canmatch_extension(ch->ast, ch->context, bc->dad, 1, bc->oad)) {
    03954          if (ast_exists_extension(ch->ast, ch->context, "i", 1, bc->oad)) {
    03955             ast_log(LOG_WARNING, "Extension can never match, So jumping to 'i' extension. port(%d)\n",bc->port);
    03956             strcpy(ch->ast->exten, "i");
    03957             misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE);
    03958             ch->state=MISDN_DIALING;
    03959             start_pbx(ch, bc, chan);
    03960             break;
    03961          }
    03962
    03963          ast_log(LOG_WARNING, "Extension can never match, so disconnecting on port(%d)."
    03964                "maybe you want to add an 'i' extension to catch this case.\n",
    03965                bc->port);
    03966          if (bc->nt)
    03967             hanguptone_indicate(ch);
    03968
    03969          ch->state=MISDN_EXTCANTMATCH;
    03970          bc->out_cause=1;
    03971
    03972          if (bc->nt)
    03973             misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE );
    03974          else
    03975             misdn_lib_send_event(bc, EVENT_RELEASE );
    03976
    03977          break;
    03978       }
    03979
    03980       /* Whatever happens, when sending_complete is set or we are PTMP TE, we will definitely
    03981        * jump into the dialplan, when the dialed extension does not exist, the 's' extension
    03982        * will be used by Asterisk automatically. */
    03983       if (bc->sending_complete || (!bc->nt && !misdn_lib_is_ptp(bc->port))) {
    03984          if (!ch->noautorespond_on_setup) {
    03985             ch->state=MISDN_DIALING;
    03986             misdn_lib_send_event(bc, EVENT_PROCEEDING );
    03987          } else {
    03988             ch->state = MISDN_INCOMING_SETUP;
    03989          }
    03990          start_pbx(ch, bc, chan);
    03991          break;
    03992       }
    03993
    03994       /*
    03995        * If overlapdial we will definitely send a SETUP_ACKNOWLEDGE and wait for more
    03996        * Infos with a Interdigit Timeout.
    03997        * */
    03998       if (ch->overlap_dial) {
    03999          ast_mutex_lock(&ch->overlap_tv_lock);
    04000          ch->overlap_tv = ast_tvnow();
    04001          ast_mutex_unlock(&ch->overlap_tv_lock);
    04002
    04003          if (ch->overlap_dial_task == -1)
    04004             ch->overlap_dial_task =
    04005                misdn_tasks_add_variable(ch->overlap_dial, misdn_overlap_dial_task, ch);
    04006
    04007          wait_for_digits(ch, bc, chan);
    04008          break;
    04009       }
    04010
    04011       /* If the extension does not exist and we're not TE_PTMP we wait for more digis
    04012        * without interdigit timeout.
    04013        * */
    04014       if (!ast_exists_extension(ch->ast, ch->context, bc->dad, 1, bc->oad))  {
    04015          wait_for_digits(ch, bc, chan);
    04016          break;
    04017       }
    04018
    04019       /*
    04020        * If the extension exists let's just jump into it.
    04021        * */
    04022       if (ast_exists_extension(ch->ast, ch->context, bc->dad, 1, bc->oad)) {
    04023          if (bc->need_more_infos)
    04024             misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE );
    04025          else
    04026             misdn_lib_send_event(bc, EVENT_PROCEEDING);
    04027
    04028          ch->state=MISDN_DIALING;
    04029          start_pbx(ch, bc, chan);
    04030          break;
    04031       }
    04032
    04033    }
    04034    break;
    04035
    04036    case EVENT_SETUP_ACKNOWLEDGE:
    04037    {
    04038       ch->state = MISDN_CALLING_ACKNOWLEDGE;
    04039       if (!ast_strlen_zero(bc->infos_pending)) {
    04040          /* TX Pending Infos */
    04041
    04042          {
    04043             int l = sizeof(bc->dad);
    04044             strncat(bc->dad,bc->infos_pending, l - strlen(bc->dad));
    04045             bc->dad[l-1] = 0;
    04046          }
    04047
    04048          if (!ch->ast) break;
    04049          {
    04050             int l = sizeof(ch->ast->exten);
    04051             strncpy(ch->ast->exten, bc->dad, l);
    04052             ch->ast->exten[l-1] = 0;
    04053          }
    04054          {
    04055             int l = sizeof(bc->info_dad);
    04056             strncpy(bc->info_dad, bc->infos_pending, l);
    04057             bc->info_dad[l-1] = 0;
    04058          }
    04059          strncpy(bc->infos_pending,"", 1);
    04060
    04061          misdn_lib_send_event(bc, EVENT_INFORMATION);
    04062       }
    04063    }
    04064    break;
    04065    case EVENT_PROCEEDING:
    04066    {
    04067       if ( misdn_cap_is_speech(bc->capability) &&
    04068            misdn_inband_avail(bc) ) {
    04069          start_bc_tones(ch);
    04070       }
    04071
    04072       ch->state = MISDN_PROCEEDING;
    04073
    04074       if (!ch->ast) break;
    04075
    04076       ast_queue_control(ch->ast, AST_CONTROL_PROCEEDING);
    04077    }
    04078    break;
    04079    case EVENT_PROGRESS:
    04080
    04081
    04082       if (!bc->nt ) {
    04083          if ( misdn_cap_is_speech(bc->capability) &&
    04084               misdn_inband_avail(bc)
    04085             ) {
    04086             start_bc_tones(ch);
    04087          }
    04088
    04089          ch->state=MISDN_PROGRESS;
    04090
    04091          if (!ch->ast) break;
    04092          ast_queue_control(ch->ast, AST_CONTROL_PROGRESS);
    04093       }
    04094       break;
    04095
    04096
    04097    case EVENT_ALERTING:
    04098    {
    04099       ch->state = MISDN_ALERTING;
    04100
    04101       if (!ch->ast) break;
    04102
    04103       ast_queue_control(ch->ast, AST_CONTROL_RINGING);
    04104       ast_setstate(ch->ast, AST_STATE_RINGING);
    04105
    04106       cb_log(7,bc->port," --> Set State Ringing\n");
    04107
    04108       if ( misdn_cap_is_speech(bc->capability) && misdn_inband_avail(bc)) {
    04109          cb_log(1,bc->port,"Starting Tones, we have inband Data\n");
    04110          start_bc_tones(ch);
    04111       } else {
    04112          cb_log(3,bc->port," --> We have no inband Data, the other end must create ringing\n");
    04113          if (ch->far_alerting) {
    04114             cb_log(1,bc->port," --> The other end can not do ringing eh ?.. we must do all ourself..");
    04115             start_bc_tones(ch);
    04116             /*tone_indicate(ch, TONE_FAR_ALERTING);*/
    04117          }
    04118       }
    04119    }
    04120    break;
    04121    case EVENT_CONNECT:
    04122    {
    04123       /*we answer when we've got our very new L3 ID from the NT stack */
    04124       misdn_lib_send_event(bc,EVENT_CONNECT_ACKNOWLEDGE);
    04125
    04126       if (!ch->ast) break;
    04127
    04128       struct ast_channel *bridged=AST_BRIDGED_P(ch->ast);
    04129       stop_indicate(ch);
    04130
    04131       if (bridged && !strcasecmp(bridged->tech->type,"mISDN")) {
    04132          struct chan_list *bridged_ch=MISDN_ASTERISK_TECH_PVT(bridged);
    04133
    04134          chan_misdn_log(1,bc->port," --> copying cpndialplan:%d and cad:%s to the A-Channel\n",bc->cpnnumplan,bc->cad);
    04135          if (bridged_ch) {
    04136             bridged_ch->bc->cpnnumplan=bc->cpnnumplan;
    04137             ast_copy_string(bridged_ch->bc->cad,bc->cad,sizeof(bc->cad));
    04138          }
    04139       }
    04140    }
    04141
    04142    /* notice that we don't break here!*/
    04143    case EVENT_CONNECT_ACKNOWLEDGE:
    04144    {
    04145       ch->l3id=bc->l3_id;
    04146       ch->addr=bc->addr;
    04147
    04148       start_bc_tones(ch);
    04149
    04150       ch->state = MISDN_CONNECTED;
    04151
    04152       if (!ch->ast) break;
    04153
    04154       ast_queue_control(ch->ast, AST_CONTROL_ANSWER);
    04155    }
    04156    break;
    04157    case EVENT_DISCONNECT:
    04158    /*we might not have an ch->ast ptr here anymore*/
    04159    if (ch) {
    04160       struct chan_list *holded_ch=find_holded(cl_te, bc);
    04161
    04162       chan_misdn_log(3,bc->port," --> org:%d nt:%d, inbandavail:%d state:%d\n", ch->orginator, bc->nt, misdn_inband_avail(bc), ch->state);
    04163       if ( ch->orginator==ORG_AST && !bc->nt && misdn_inband_avail(bc) && ch->state != MISDN_CONNECTED) {
    04164          /* If there's inband information available (e.g. a
    04165             recorded message saying what was wrong with the
    04166             dialled number, or perhaps even giving an
    04167             alternative number, then play it instead of
    04168             immediately releasing the call */
    04169          chan_misdn_log(1,bc->port, " --> Inband Info Avail, not sending RELEASE\n");
    04170
    04171          ch->state=MISDN_DISCONNECTED;
    04172          start_bc_tones(ch);
    04173
    04174          if (ch->ast) {
    04175             ch->ast->hangupcause=bc->cause;
    04176             if (bc->cause == 17)
    04177                ast_queue_control(ch->ast, AST_CONTROL_BUSY);
    04178          }
    04179          ch->need_busy=0;
    04180          break;
    04181       }
    04182
    04183       /*Check for holded channel, to implement transfer*/
    04184       if (  holded_ch &&
    04185          holded_ch != ch &&
    04186          ch->ast &&
    04187          ch->state == MISDN_CONNECTED  ) {
    04188          cb_log(1,bc->port," --> found holded ch\n");
    04189          misdn_transfer_bc(ch, holded_ch) ;
    04190       }
    04191
    04192       bc->need_disconnect=0;
    04193
    04194       stop_bc_tones(ch);
    04195       hangup_chan(ch);
    04196    } else {
    04197       ch=find_holded_l3(cl_te, bc->l3_id,1);
    04198       if (ch) {
    04199          hangup_chan(ch);
    04200       }
    04201    }
    04202    bc->out_cause=-1;
    04203    if (bc->need_release) misdn_lib_send_event(bc,EVENT_RELEASE);
    04204    break;
    04205
    04206    case EVENT_RELEASE:
    04207       {
    04208          bc->need_disconnect=0;
    04209          bc->need_release=0;
    04210
    04211          hangup_chan(ch);
    04212          release_chan(bc);
    04213
    04214          if (bc->need_release_complete)
    04215             misdn_lib_send_event(bc,EVENT_RELEASE_COMPLETE);
    04216       }
    04217       break;
    04218    case EVENT_RELEASE_COMPLETE:
    04219    {
    04220       bc->need_disconnect=0;
    04221       bc->need_release=0;
    04222       bc->need_release_complete=0;
    04223
    04224       stop_bc_tones(ch);
    04225       hangup_chan(ch);
    04226
    04227       if(ch)
    04228          ch->state=MISDN_CLEANING;
    04229
    04230       release_chan(bc);
    04231    }
    04232    break;
    04233    case EVENT_BCHAN_ERROR:
    04234    case EVENT_CLEANUP:
    04235    {
    04236       stop_bc_tones(ch);
    04237
    04238       switch(ch->state) {
    04239          case MISDN_CALLING:
    04240             bc->cause=27; /* Destination out of order */
    04241          break;
    04242          default:
    04243          break;
    04244       }
    04245
    04246       hangup_chan(ch);
    04247       release_chan(bc);
    04248    }
    04249    break;
    04250
    04251    case EVENT_TONE_GENERATE:
    04252    {
    04253       int tone_len=bc->tone_cnt;
    04254       struct ast_channel *ast=ch->ast;
    04255       void *tmp;
    04256       int res;
    04257       int (*generate)(struct ast_channel *chan, void *tmp, int datalen, int samples);
    04258
    04259       chan_misdn_log(9,bc->port,"TONE_GEN: len:%d\n");
    04260
    04261       if (!ast) break;
    04262
    04263       if (!ast->generator) break;
    04264
    04265
    04266
    04267       tmp = ast->generatordata;
    04268       ast->generatordata = NULL;
    04269       generate = ast->generator->generate;
    04270
    04271       if (tone_len <0 || tone_len > 512 ) {
    04272          ast_log(LOG_NOTICE, "TONE_GEN: len was %d, set to 128\n",tone_len);
    04273          tone_len=128;
    04274       }
    04275
    04276       res = generate(ast, tmp, tone_len, tone_len);
    04277       ast->generatordata = tmp;
    04278
    04279       if (res) {
    04280          ast_log(LOG_WARNING, "Auto-deactivating generator\n");
    04281          ast_deactivate_generator(ast);
    04282       } else {
    04283          bc->tone_cnt=0;
    04284       }
    04285    }
    04286    break;
    04287
    04288    case EVENT_BCHAN_DATA:
    04289    {
    04290       if ( !misdn_cap_is_speech(ch->bc->capability) ) {
    04291          struct ast_frame frame;
    04292          /*In Data Modes we queue frames*/
    04293          frame.frametype  = AST_FRAME_VOICE; /*we have no data frames yet*/
    04294          frame.subclass = AST_FORMAT_ALAW;
    04295          frame.datalen = bc->bframe_len;
    04296          frame.samples = bc->bframe_len ;
    04297          frame.mallocd =0 ;
    04298          frame.offset= 0 ;
    04299          frame.delivery= ast_tv(0,0) ;
    04300          frame.src = NULL;
    04301          frame.data = bc->bframe ;
    04302
    04303          if (ch->ast)
    04304             ast_queue_frame(ch->ast,&frame);
    04305       } else {
    04306          fd_set wrfs;
    04307          struct timeval tv;
    04308          tv.tv_sec=0;
    04309          tv.tv_usec=0;
    04310
    04311
    04312          FD_ZERO(&wrfs);
    04313          FD_SET(ch->pipe[1],&wrfs);
    04314
    04315          int t=select(FD_SETSIZE,NULL,&wrfs,NULL,&tv);
    04316
    04317          if (!t) {
    04318             chan_misdn_log(9, bc->port, "Select Timed out\n");
    04319             break;
    04320          }
    04321
    04322          if (t<0) {
    04323             chan_misdn_log(-1, bc->port, "Select Error (err=%s)\n",strerror(errno));
    04324             break;
    04325          }
    04326
    04327          if (FD_ISSET(ch->pipe[1],&wrfs)) {
    04328             chan_misdn_log(9, bc->port, "writing %d bytes 2 asterisk\n",bc->bframe_len);
    04329             int ret=write(ch->pipe[1], bc->bframe, bc->bframe_len);
    04330
    04331             if (ret<=0) {
    04332                chan_misdn_log(-1, bc->port, "Write returned <=0 (err=%s) --> hanging up channel\n",strerror(errno));
    04333
    04334                stop_bc_tones(ch);
    04335                hangup_chan(ch);
    04336                release_chan(bc);
    04337             }
    04338          } else {
    04339             chan_misdn_log(1, bc->port, "Wripe Pipe full!\n");
    04340          }
    04341       }
    04342    }
    04343    break;
    04344    case EVENT_TIMEOUT:
    04345       {
    04346       if (ch && bc)
    04347          chan_misdn_log(1,bc->port,"--> state: %s\n",misdn_get_ch_state(ch));
    04348
    04349       switch (ch->state) {
    04350          case MISDN_DIALING:
    04351          case MISDN_PROGRESS:
    04352             if (bc->nt && !ch->nttimeout) break;
    04353
    04354          case MISDN_CALLING:
    04355          case MISDN_ALERTING:
    04356          case MISDN_PROCEEDING:
    04357          case MISDN_CALLING_ACKNOWLEDGE:
    04358             if (bc->nt) {
    04359                bc->progress_indicator=8;
    04360                hanguptone_indicate(ch);
    04361             }
    04362
    04363             bc->out_cause=1;
    04364             misdn_lib_send_event(bc,EVENT_DISCONNECT);
    04365          break;
    04366
    04367          case MISDN_WAITING4DIGS:
    04368             if (bc->nt) {
    04369                bc->progress_indicator=8;
    04370                bc->out_cause=1;
    04371                hanguptone_indicate(ch);
    04372                misdn_lib_send_event(bc,EVENT_DISCONNECT);
    04373             } else {
    04374                bc->out_cause=16;
    04375                misdn_lib_send_event(bc,EVENT_RELEASE);
    04376             }
    04377
    04378          break;
    04379
    04380
    04381          case MISDN_CLEANING:
    04382             chan_misdn_log(1,bc->port," --> in state cleaning .. so ingoring, the stack should clean it for us\n");
    04383          break;
    04384
    04385          default:
    04386             misdn_lib_send_event(bc,EVENT_RELEASE_COMPLETE);
    04387          }
    04388       }
    04389       break;
    04390
    04391
    04392    /***************************/
    04393    /** Suplementary Services **/
    04394    /***************************/
    04395    case EVENT_RETRIEVE:
    04396    {
    04397       if (!ch) {
    04398          chan_misdn_log(4, bc->port, " --> no CH, searching in holded");
    04399          ch=find_holded_l3(cl_te, bc->l3_id,1);
    04400       }
    04401
    04402       if (!ch) {
    04403          ast_log(LOG_WARNING, "Found no Holded channel, cannot Retrieve\n");
    04404          misdn_lib_send_event(bc, EVENT_RETRIEVE_REJECT);
    04405          break;
    04406       }
    04407
    04408       /*remember the channel again*/
    04409       ch->bc=bc;
    04410       ch->state = MISDN_CONNECTED;
    04411
    04412       ch->hold_info.port=0;
    04413       ch->hold_info.channel=0;
    04414
    04415       struct ast_channel *hold_ast=AST_BRIDGED_P(ch->ast);
    04416
    04417       if (hold_ast) {
    04418          ast_moh_stop(hold_ast);
    04419       }
    04420
    04421       if ( misdn_lib_send_event(bc, EVENT_RETRIEVE_ACKNOWLEDGE) < 0)
    04422          misdn_lib_send_event(bc, EVENT_RETRIEVE_REJECT);
    04423    }
    04424    break;
    04425
    04426    case EVENT_HOLD:
    04427    {
    04428       int hold_allowed;
    04429       misdn_cfg_get( bc->port, MISDN_CFG_HOLD_ALLOWED, &hold_allowed, sizeof(int));
    04430
    04431       if (!hold_allowed) {
    04432
    04433          chan_misdn_log(-1, bc->port, "Hold not allowed this port.\n");
    04434          misdn_lib_send_event(bc, EVENT_HOLD_REJECT);
    04435          break;
    04436       }
    04437
    04438       struct ast_channel *bridged=AST_BRIDGED_P(ch->ast);
    04439
    04440       if (bridged) {
    04441          chan_misdn_log(2,bc->port,"Bridge Partner is of type: %s\n",bridged->tech->type);
    04442          ch->state = MISDN_HOLDED;
    04443          ch->l3id = bc->l3_id;
    04444
    04445          misdn_lib_send_event(bc, EVENT_HOLD_ACKNOWLEDGE);
    04446
    04447          ast_moh_start(bridged, NULL);
    04448
    04449          /*forget the channel now*/
    04450          ch->bc=NULL;
    04451          ch->hold_info.port=bc->port;
    04452          ch->hold_info.channel=bc->channel;
    04453
    04454       } else {
    04455          misdn_lib_send_event(bc, EVENT_HOLD_REJECT);
    04456          chan_misdn_log(0, bc->port, "We aren't bridged to anybody\n");
    04457       }
    04458    }
    04459    break;
    04460
    04461    case EVENT_FACILITY:
    04462       print_facility(bc);
    04463
    04464       switch (bc->fac_type) {
    04465       case FACILITY_CALLDEFLECT:
    04466       {
    04467          struct ast_channel *bridged=AST_BRIDGED_P(ch->ast);
    04468          struct chan_list *ch;
    04469
    04470          if (bridged && MISDN_ASTERISK_TECH_PVT(bridged)) {
    04471             ch=MISDN_ASTERISK_TECH_PVT(bridged);
    04472             /*ch->state=MISDN_FACILITY_DEFLECTED;*/
    04473             if (ch->bc) {
    04474                /* todo */
    04475             }
    04476
    04477          }
    04478
    04479       }
    04480
    04481       break;
    04482       default:
    04483          chan_misdn_log(1, bc->port," --> not yet handled\n");
    04484       }
    04485
    04486       break;
    04487
    04488    case EVENT_RESTART:
    04489
    04490       if (!bc->dummy) {
    04491          stop_bc_tones(ch);
    04492          release_chan(bc);
    04493       }
    04494
    04495       break;
    04496
    04497    default:
    04498       chan_misdn_log(1,0, "Got Unknown Event\n");
    04499       break;
    04500    }
    04501
    04502    return RESPONSE_OK;
    04503 }

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

Definition at line 5068 of file chan_misdn.c.

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

Referenced by load_module().

    05069 {
    05070    struct chan_list *ch=find_chan_by_bc(cl_te, bc);
    05071
    05072    if (ch && ch->jb) {
    05073       return misdn_jb_empty(ch->jb, buf, len);
    05074    }
    05075
    05076    return -1;
    05077 }

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

Definition at line 5253 of file chan_misdn.c.

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

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

    05254 {
    05255    if (! ((0 <= port) && (port <= max_ports))) {
    05256       ast_log(LOG_WARNING, "cb_log called with out-of-range port number! (%d)\n", port);
    05257       port=0;
    05258       level=-1;
    05259    }
    05260
    05261    va_list ap;
    05262    char buf[1024];
    05263    char port_buf[8];
    05264    sprintf(port_buf,"P[%2d] ",port);
    05265
    05266    va_start(ap, tmpl);
    05267    vsnprintf( buf, 1023, tmpl, ap );
    05268    va_end(ap);
    05269
    05270    if (level == -1)
    05271       ast_log(LOG_WARNING, buf);
    05272
    05273    else if (misdn_debug_only[port] ?
    05274          (level==1 && misdn_debug[port]) || (level==misdn_debug[port])
    05275        : level <= misdn_debug[port]) {
    05276
    05277       ast_console_puts(port_buf);
    05278       ast_console_puts(buf);
    05279    }
    05280
    05281    if ((level <= misdn_debug[0]) && !ast_strlen_zero(global_tracefile) ) {
    05282       time_t tm = time(NULL);
    05283       char *tmp=ctime(&tm),*p;
    05284
    05285       FILE *fp= fopen(global_tracefile, "a+");
    05286
    05287       p=strchr(tmp,'\n');
    05288       if (p) *p=':';
    05289
    05290       if (!fp) {
    05291          ast_console_puts("Error opening Tracefile: [ ");
    05292          ast_console_puts(global_tracefile);
    05293          ast_console_puts(" ] ");
    05294
    05295          ast_console_puts(strerror(errno));
    05296          ast_console_puts("\n");
    05297          return ;
    05298       }
    05299
    05300       fputs(tmp,fp);
    05301       fputs(" ", fp);
    05302       fputs(port_buf,fp);
    05303       fputs(" ", fp);
    05304       fputs(buf, fp);
    05305
    05306       fclose(fp);
    05307    }
    05308 }

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

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

    03201 {
    03202    if (chan->dsp)
    03203       ast_dsp_free(chan->dsp);
    03204    if (chan->trans)
    03205       ast_translator_free_path(chan->trans);
    03206
    03207
    03208
    03209    ast_mutex_lock(&cl_te_lock);
    03210    if (!*list) {
    03211       ast_mutex_unlock(&cl_te_lock);
    03212       return;
    03213    }
    03214
    03215    if (*list == chan) {
    03216       *list=(*list)->next;
    03217       ast_mutex_unlock(&cl_te_lock);
    03218       return ;
    03219    }
    03220
    03221    {
    03222       struct chan_list *help=*list;
    03223       for (;help->next; help=help->next) {
    03224          if (help->next == chan) {
    03225             help->next=help->next->next;
    03226             ast_mutex_unlock(&cl_te_lock);
    03227             return;
    03228          }
    03229       }
    03230    }
    03231
    03232    ast_mutex_unlock(&cl_te_lock);
    03233 }

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

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

    03185 {
    03186    chan_misdn_log(4, chan->bc? chan->bc->port : 0, "* Queuing chan %p\n",chan);
    03187
    03188    ast_mutex_lock(&cl_te_lock);
    03189    if (!*list) {
    03190       *list = chan;
    03191    } else {
    03192       struct chan_list *help=*list;
    03193       for (;help->next; help=help->next);
    03194       help->next=chan;
    03195    }
    03196    chan->next=NULL;
    03197    ast_mutex_unlock(&cl_te_lock);
    03198 }

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

Definition at line 1247 of file chan_misdn.c.

References complete_ch_helper().

    01248 {
    01249    return complete_ch_helper(line, word, pos, state, 3);
    01250 }

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

Definition at line 1223 of file chan_misdn.c.

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

    01224 {
    01225    struct ast_channel *c;
    01226    int which=0;
    01227    char *ret;
    01228    if (pos != rpos)
    01229       return NULL;
    01230    c = ast_channel_walk_locked(NULL);
    01231    while(c) {
    01232       if (!strncasecmp(word, c->name, strlen(word))) {
    01233          if (++which > state)
    01234             break;
    01235       }
    01236       ast_mutex_unlock(&c->lock);
    01237       c = ast_channel_walk_locked(c);
    01238    }
    01239    if (c) {
    01240       ret = strdup(c->name);
    01241       ast_mutex_unlock(&c->lock);
    01242    } else
    01243       ret = NULL;
    01244    return ret;
    01245 }

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

Definition at line 1252 of file chan_misdn.c.

References strdup.

    01253 {
    01254    if (state)
    01255       return NULL;
    01256
    01257    switch (pos) {
    01258    case 4: if (*word == 'p')
    01259             return strdup("port");
    01260          else if (*word == 'o')
    01261             return strdup("only");
    01262          break;
    01263    case 6: if (*word == 'o')
    01264             return strdup("only");
    01265          break;
    01266    }
    01267    return NULL;
    01268 }

void config_jitterbuffer | ( | struct chan_list * | ch | ) |

Definition at line 1526 of file chan_misdn.c.

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

Referenced by misdn_set_opt_exec(), and read_config().

    01527 {
    01528    struct misdn_bchannel *bc=ch->bc;
    01529    int len=ch->jb_len, threshold=ch->jb_upper_threshold;
    01530
    01531    chan_misdn_log(5,bc->port, "config_jb: Called\n");
    01532
    01533    if ( ! len ) {
    01534       chan_misdn_log(1,bc->port, "config_jb: Deactivating Jitterbuffer\n");
    01535       bc->nojitter=1;
    01536    } else {
    01537
    01538       if (len <=100 || len > 8000) {
    01539          chan_misdn_log(0,bc->port,"config_jb: Jitterbuffer out of Bounds, setting to 1000\n");
    01540          len=1000;
    01541       }
    01542
    01543       if ( threshold > len ) {
    01544          chan_misdn_log(0,bc->port,"config_jb: Jitterbuffer Threshold > Jitterbuffer setting to Jitterbuffer -1\n");
    01545       }
    01546
    01547       if ( ch->jb) {
    01548          cb_log(0,bc->port,"config_jb: We've got a Jitterbuffer Already on this port.\n");
    01549          misdn_jb_destroy(ch->jb);
    01550          ch->jb=NULL;
    01551       }
    01552
    01553       ch->jb=misdn_jb_init(len, threshold);
    01554
    01555       if (!ch->jb )
    01556          bc->nojitter=1;
    01557    }
    01558 }

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

Definition at line 1561 of file chan_misdn.c.

References chan_misdn_log().

Referenced by read_config().

    01562 {
    01563    switch (numplan) {
    01564    case NUMPLAN_INTERNATIONAL:
    01565       chan_misdn_log(2, port, " --> %s: International\n",type);
    01566       break;
    01567    case NUMPLAN_NATIONAL:
    01568       chan_misdn_log(2, port, " --> %s: National\n",type);
    01569       break;
    01570    case NUMPLAN_SUBSCRIBER:
    01571       chan_misdn_log(2, port, " --> %s: Subscriber\n",type);
    01572       break;
    01573    case NUMPLAN_UNKNOWN:
    01574       chan_misdn_log(2, port, " --> %s: Unknown\n",type);
    01575       break;
    01576       /* Maybe we should cut off the prefix if present ? */
    01577    default:
    01578       chan_misdn_log(0, port, " --> !!!! Wrong dialplan setting, please see the misdn.conf sample file\n ");
    01579       break;
    01580    }
    01581 }

char* description | ( | void |  | ) |

Provides a description of the module.

Returns:
  a short description of your module

Definition at line 4733 of file chan_misdn.c.

References desc.

    04734 {
    04735    return desc;
    04736 }

static int dialtone_indicate | ( | struct chan_list * | cl | ) | `[static]`

AST INDICATIONS END

Definition at line 2665 of file chan_misdn.c.

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

Referenced by wait_for_digits().

    02666 {
    02667    const struct tone_zone_sound *ts= NULL;
    02668    struct ast_channel *ast=cl->ast;
    02669
    02670    if (!ast) {
    02671       chan_misdn_log(0,cl->bc->port,"No Ast in dialtone_indicate\n");
    02672       return -1;
    02673    }
    02674
    02675    int nd=0;
    02676    misdn_cfg_get( cl->bc->port, MISDN_CFG_NODIALTONE, &nd, sizeof(nd));
    02677
    02678    if (nd) {
    02679       chan_misdn_log(1,cl->bc->port,"Not sending Dialtone, because config wants it\n");
    02680       return 0;
    02681    }
    02682
    02683    chan_misdn_log(3,cl->bc->port," --> Dial\n");
    02684    ts=ast_get_indication_tone(ast->zone,"dial");
    02685    cl->ts=ts;
    02686
    02687    if (ts) {
    02688       cl->notxtone=0;
    02689       cl->norxtone=0;
    02690       /* This prods us in misdn_write */
    02691       ast_playtones_start(ast,0, ts->data, 0);
    02692    }
    02693
    02694    return 0;
    02695 }

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

Definition at line 3367 of file chan_misdn.c.

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

Referenced by cb_events().

    03368 {
    03369    char predial[256]="";
    03370    char *p = predial;
    03371
    03372    struct ast_frame fr;
    03373
    03374    strncpy(predial, ast->exten, sizeof(predial) -1 );
    03375
    03376    ch->state=MISDN_DIALING;
    03377
    03378    if (!ch->noautorespond_on_setup) {
    03379       if (bc->nt) {
    03380          int ret;
    03381          ret = misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE );
    03382       } else {
    03383          int ret;
    03384          if ( misdn_lib_is_ptp(bc->port)) {
    03385             ret = misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE );
    03386          } else {
    03387             ret = misdn_lib_send_event(bc, EVENT_PROCEEDING );
    03388          }
    03389       }
    03390    } else {
    03391       ch->state = MISDN_INCOMING_SETUP;
    03392    }
    03393
    03394    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));
    03395
    03396    strncpy(ast->exten,"s", 2);
    03397
    03398    if (pbx_start_chan(ch)<0) {
    03399       ast=NULL;
    03400       hangup_chan(ch);
    03401       hanguptone_indicate(ch);
    03402
    03403       if (bc->nt)
    03404          misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE );
    03405       else
    03406          misdn_lib_send_event(bc, EVENT_DISCONNECT );
    03407    }
    03408
    03409
    03410    while (!ast_strlen_zero(p) ) {
    03411       fr.frametype = AST_FRAME_DTMF;
    03412       fr.subclass = *p ;
    03413       fr.src=NULL;
    03414       fr.data = NULL ;
    03415       fr.datalen = 0;
    03416       fr.samples = 0 ;
    03417       fr.mallocd =0 ;
    03418       fr.offset= 0 ;
    03419       fr.delivery= ast_tv(0,0) ;
    03420
    03421       if (ch->ast && MISDN_ASTERISK_PVT(ch->ast) && MISDN_ASTERISK_TECH_PVT(ch->ast)) {
    03422          ast_queue_frame(ch->ast, &fr);
    03423       }
    03424       p++;
    03425    }
    03426 }

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

Definition at line 3513 of file chan_misdn.c.

References chan_misdn_log(), and pbx_builtin_setvar_helper().

Referenced by cb_events().

    03514 {
    03515    char tmp[32];
    03516
    03517    chan_misdn_log(3,bc->port," --> EXPORT_PID: pid:%d\n",bc->pid);
    03518    sprintf(tmp,"%d",bc->pid);
    03519    pbx_builtin_setvar_helper(chan,"_MISDN_PID",tmp);
    03520
    03521    if (bc->sending_complete) {
    03522       sprintf(tmp,"%d",bc->sending_complete);
    03523       pbx_builtin_setvar_helper(chan,"MISDN_ADDRESS_COMPLETE",tmp);
    03524    }
    03525
    03526    if (bc->urate) {
    03527       sprintf(tmp,"%d",bc->urate);
    03528       pbx_builtin_setvar_helper(chan,"MISDN_URATE",tmp);
    03529    }
    03530
    03531    if (bc->keypad[0])
    03532       pbx_builtin_setvar_helper(chan,"MISDN_KEYPAD",bc->keypad);
    03533 }

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

Definition at line 3126 of file chan_misdn.c.

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

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

    03127 {
    03128    struct chan_list *help=list;
    03129    for (;help; help=help->next) {
    03130       if (help->bc == bc) return help;
    03131    }
    03132
    03133    chan_misdn_log(6, bc->port, "$$$ find_chan: No channel found for oad:%s dad:%s\n",bc->oad,bc->dad);
    03134
    03135    return NULL;
    03136 }

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

Definition at line 3138 of file chan_misdn.c.

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

Referenced by import_ch().

    03139 {
    03140    struct chan_list *help=list;
    03141    for (;help; help=help->next) {
    03142       if ( help->bc && (help->bc->pid == pid) ) return help;
    03143    }
    03144
    03145    chan_misdn_log(6, 0, "$$$ find_chan: No channel found for pid:%d\n",pid);
    03146
    03147    return NULL;
    03148 }

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

Definition at line 3150 of file chan_misdn.c.

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

Referenced by cb_events().

    03151 {
    03152    struct chan_list *help=list;
    03153
    03154    if (bc->pri) return NULL;
    03155
    03156    chan_misdn_log(6, bc->port, "$$$ find_holded: channel:%d oad:%s dad:%s\n",bc->channel, bc->oad,bc->dad);
    03157    for (;help; help=help->next) {
    03158       chan_misdn_log(4, bc->port, "$$$ find_holded: --> holded:%d channel:%d\n",help->state==MISDN_HOLDED, help->hold_info.channel);
    03159       if (help->hold_info.port == bc->port
    03160       ) return help;
    03161    }
    03162
    03163    chan_misdn_log(6, bc->port, "$$$ find_chan: No channel found for oad:%s dad:%s\n",bc->oad,bc->dad);
    03164
    03165    return NULL;
    03166 }

static struct chan_list* find_holded_l3 | ( | struct chan_list * | list,
|  | unsigned long | l3_id,
|  | int | w |
| ) |  |  | `[static, read]`

Definition at line 3169 of file chan_misdn.c.

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

Referenced by cb_events().

    03171 {
    03172    struct chan_list *help=list;
    03173
    03174    for (;help; help=help->next) {
    03175       if ( (help->state == MISDN_HOLDED) &&
    03176           (help->l3id == l3_id)
    03177          )
    03178          return help;
    03179    }
    03180
    03181    return NULL;
    03182 }

static void free_robin_list | ( | void |  | ) | `[static]`

Definition at line 248 of file chan_misdn.c.

References free_robin_list_r().

Referenced by reload_config(), and unload_module().

    00249 {
    00250    free_robin_list_r(robin);
    00251    robin = NULL;
    00252 }

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

Definition at line 239 of file chan_misdn.c.

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

Referenced by free_robin_list().

    00240 {
    00241         if (r) {
    00242                 if (r->next) free_robin_list_r(r->next);
    00243                 if (r->group) free(r->group);
    00244                 free(r);
    00245         }
    00246 }

static struct chan_list* get_chan_by_ast | ( | struct ast_channel * | ast | ) | `[static, read]`

Definition at line 352 of file chan_misdn.c.

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

Referenced by misdn_bridge().

    00353 {
    00354    struct chan_list *tmp;
    00355
    00356    for (tmp=cl_te; tmp; tmp = tmp->next) {
    00357       if ( tmp->ast == ast ) return tmp;
    00358    }
    00359
    00360    return NULL;
    00361 }

static struct chan_list* get_chan_by_ast_name | ( | char * | name | ) | `[static, read]`

Definition at line 363 of file chan_misdn.c.

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

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

    00364 {
    00365    struct chan_list *tmp;
    00366
    00367    for (tmp=cl_te; tmp; tmp = tmp->next) {
    00368       if ( tmp->ast  && strcmp(tmp->ast->name,name) == 0) return tmp;
    00369    }
    00370
    00371    return NULL;
    00372 }

static struct robin_list* get_robin_position | ( | char * | group | ) | `[static, read]`

Definition at line 254 of file chan_misdn.c.

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

Referenced by misdn_request().

    00255 {
    00256    struct robin_list *iter = robin;
    00257    for (; iter; iter = iter->next) {
    00258       if (!strcasecmp(iter->group, group))
    00259          return iter;
    00260    }
    00261    struct robin_list *new = (struct robin_list *)calloc(1, sizeof(struct robin_list));
    00262    new->group = strndup(group, strlen(group));
    00263    new->channel = 1;
    00264    if (robin) {
    00265       new->next = robin;
    00266       robin->prev = new;
    00267    }
    00268    robin = new;
    00269    return robin;
    00270 }

static void hangup_chan | ( | struct chan_list * | ch | ) | `[static]`

Definition at line 3250 of file chan_misdn.c.

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

    03251 {
    03252    int port=ch?ch->bc?ch->bc->port:0:0;
    03253    if (!ch) {
    03254       cb_log(1,0,"Cannot hangup chan, no ch\n");
    03255       return;
    03256    }
    03257
    03258    cb_log(5,port,"hangup_chan called\n");
    03259
    03260    if (ch->need_hangup)
    03261    {
    03262       cb_log(2,port," --> hangup\n");
    03263       send_cause2ast(ch->ast,ch->bc,ch);
    03264       ch->need_hangup=0;
    03265       ch->need_queue_hangup=0;
    03266       if (ch->ast)
    03267          ast_hangup(ch->ast);
    03268       return;
    03269    }
    03270
    03271    if (!ch->need_queue_hangup) {
    03272       cb_log(2,port," --> No need to queue hangup\n");
    03273    }
    03274
    03275    ch->need_queue_hangup=0;
    03276    if (ch->ast) {
    03277       send_cause2ast(ch->ast,ch->bc,ch);
    03278
    03279       if (ch->ast)
    03280          ast_queue_hangup(ch->ast);
    03281       cb_log(2,port," --> queue_hangup\n");
    03282    } else {
    03283       cb_log(1,port,"Cannot hangup chan, no ast\n");
    03284    }
    03285 }

static int hanguptone_indicate | ( | struct chan_list * | cl | ) | `[static]`

Definition at line 2697 of file chan_misdn.c.

References chan_list::bc.

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

    02698 {
    02699    misdn_lib_send_tone(cl->bc,TONE_HANGUP);
    02700    return 0;
    02701 }

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

Definition at line 3485 of file chan_misdn.c.

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

Referenced by misdn_call().

    03486 {
    03487    char *tmp;
    03488    tmp=pbx_builtin_getvar_helper(chan,"MISDN_PID");
    03489    if (tmp) {
    03490       ch->other_pid=atoi(tmp);
    03491       chan_misdn_log(3,bc->port," --> IMPORT_PID: importing pid:%s\n",tmp);
    03492
    03493       if (ch->other_pid >0) {
    03494          ch->other_ch=find_chan_by_pid(cl_te,ch->other_pid);
    03495          if (ch->other_ch) ch->other_ch->other_ch=ch;
    03496       }
    03497    }
    03498
    03499    tmp=pbx_builtin_getvar_helper(chan,"MISDN_ADDRESS_COMPLETE");
    03500    if (tmp && (atoi(tmp) == 1)) {
    03501       bc->sending_complete=1;
    03502    }
    03503
    03504    const char *kp=pbx_builtin_getvar_helper(chan,"MISDN_KEYPAD");
    03505    if (kp) {
    03506       strncpy(bc->keypad,kp,sizeof(bc->keypad));
    03507       bc->keypad[sizeof(bc->keypad)-1]=0;
    03508    }
    03509
    03510
    03511 }

static struct chan_list* init_chan_list | ( | int | orig | ) | `[static, read]`

Definition at line 2742 of file chan_misdn.c.

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

Referenced by cb_events(), and misdn_request().

    02743 {
    02744    struct chan_list *cl=malloc(sizeof(struct chan_list));
    02745
    02746    if (!cl) {
    02747       chan_misdn_log(-1, 0, "misdn_request: malloc failed!");
    02748       return NULL;
    02749    }
    02750
    02751    memset(cl,0,sizeof(struct chan_list));
    02752
    02753    cl->orginator=orig;
    02754    cl->need_queue_hangup=1;
    02755    cl->need_hangup=1;
    02756    cl->need_busy=1;
    02757    cl->overlap_dial_task=-1;
    02758
    02759    return cl;
    02760
    02761 }

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

References ASTERISK_GPL_KEY.

    04739 {
    04740    return ASTERISK_GPL_KEY;
    04741 }

int load_module | ( | void |  | ) |

Initialize the module.

TE STUFF END

Definition at line 4516 of file chan_misdn.c.

References ast_channel_register(), ast_cli_register(), ast_log(), ast_mutex_init(), ast_register_application(), calloc, cb_events(), chan_misdn_jb_empty(), chan_misdn_log(), cl_te_lock, g_config_initialized, global_tracefile, LOG_ERROR, malloc, max_ports, misdn_cfg_get(), misdn_cfg_get_ports_string(), misdn_cfg_init(), misdn_cfg_update_ptp(), misdn_check_l2l1(), misdn_debug, misdn_debug_only, misdn_facility_exec(), misdn_set_opt_exec(), misdn_type, release_lock, tracing, and unload_module().

    04517 {
    04518    int i;
    04519
    04520    char ports[256]="";
    04521
    04522    max_ports=misdn_lib_maxports_get();
    04523
    04524    if (max_ports<=0) {
    04525       ast_log(LOG_ERROR, "Unable to initialize mISDN\n");
    04526       return 0;
    04527    }
    04528
    04529    if (misdn_cfg_init(max_ports)<0) {
    04530       ast_log(LOG_ERROR, "Unable to initialize mISDN Config System\n");
    04531       return 0;
    04532    }
    04533
    04534    g_config_initialized=1;
    04535
    04536    misdn_debug = (int *)malloc(sizeof(int) * (max_ports+1));
    04537    misdn_cfg_get( 0, MISDN_GEN_DEBUG, &misdn_debug[0], sizeof(int));
    04538    for (i = 1; i <= max_ports; i++)
    04539       misdn_debug[i] = misdn_debug[0];
    04540    misdn_debug_only = (int *)calloc(max_ports + 1, sizeof(int));
    04541
    04542
    04543    {
    04544       char tempbuf[BUFFERSIZE+1];
    04545       misdn_cfg_get( 0, MISDN_GEN_TRACEFILE, tempbuf, BUFFERSIZE);
    04546       if (strlen(tempbuf))
    04547          tracing = 1;
    04548    }
    04549
    04550    ast_mutex_init(&cl_te_lock);
    04551    ast_mutex_init(&release_lock);
    04552
    04553    misdn_cfg_update_ptp();
    04554    misdn_cfg_get_ports_string(ports);
    04555
    04556    if (strlen(ports))
    04557       chan_misdn_log(0, 0, "Got: %s from get_ports\n",ports);
    04558
    04559    {
    04560       struct misdn_lib_iface iface = {
    04561          .cb_event = cb_events,
    04562          .cb_log = chan_misdn_log,
    04563          .cb_jb_empty = chan_misdn_jb_empty,
    04564       };
    04565       if (misdn_lib_init(ports, &iface, NULL))
    04566          chan_misdn_log(0, 0, "No te ports initialized\n");
    04567
    04568       int ntflags=0;
    04569       char ntfile[BUFFERSIZE+1];
    04570
    04571       misdn_cfg_get( 0, MISDN_GEN_NTDEBUGFLAGS, &ntflags, sizeof(int));
    04572       misdn_cfg_get( 0, MISDN_GEN_NTDEBUGFILE, &ntfile, BUFFERSIZE);
    04573
    04574       misdn_lib_nt_debug_init(ntflags,ntfile);
    04575
    04576    }
    04577
    04578
    04579    {
    04580       if (ast_channel_register(&misdn_tech)) {
    04581          ast_log(LOG_ERROR, "Unable to register channel class %s\n", misdn_type);
    04582          unload_module();
    04583          return -1;
    04584       }
    04585    }
    04586
    04587    ast_cli_register(&cli_send_display);
    04588    ast_cli_register(&cli_send_cd);
    04589    ast_cli_register(&cli_send_restart);
    04590    ast_cli_register(&cli_send_digit);
    04591    ast_cli_register(&cli_toggle_echocancel);
    04592    ast_cli_register(&cli_set_tics);
    04593
    04594    ast_cli_register(&cli_show_cls);
    04595    ast_cli_register(&cli_show_cl);
    04596    ast_cli_register(&cli_show_config);
    04597    ast_cli_register(&cli_show_port);
    04598    ast_cli_register(&cli_show_stacks);
    04599
    04600    ast_cli_register(&cli_port_block);
    04601    ast_cli_register(&cli_port_unblock);
    04602    ast_cli_register(&cli_restart_port);
    04603    ast_cli_register(&cli_restart_pid);
    04604    ast_cli_register(&cli_port_up);
    04605    ast_cli_register(&cli_port_down);
    04606    ast_cli_register(&cli_set_debug);
    04607    ast_cli_register(&cli_set_crypt_debug);
    04608    ast_cli_register(&cli_reload);
    04609
    04610
    04611    ast_register_application("misdn_set_opt", misdn_set_opt_exec, "misdn_set_opt",
    04612              "misdn_set_opt(:<opt><optarg>:<opt><optarg>..):\n"
    04613              "Sets mISDN opts. and optargs\n"
    04614              "\n"
    04615              "The available options are:\n"
    04616              "    d - Send display text on called phone, text is the optparam\n"
    04617              "    n - don't detect dtmf tones on called channel\n"
    04618              "    h - make digital outgoing call\n"
    04619              "    c - make crypted outgoing call, param is keyindex\n"
    04620              "    e - perform echo cancelation on this channel,\n"
    04621              "        takes taps as arguments (32,64,128,256)\n"
    04622              "    s - send Non Inband DTMF as inband\n"
    04623              "   vr - rxgain control\n"
    04624              "   vt - txgain control\n"
    04625       );
    04626
    04627
    04628    ast_register_application("misdn_facility", misdn_facility_exec, "misdn_facility",
    04629              "misdn_facility(<FACILITY_TYPE>|<ARG1>|..)\n"
    04630              "Sends the Facility Message FACILITY_TYPE with \n"
    04631              "the given Arguments to the current ISDN Channel\n"
    04632              "Supported Facilities are:\n"
    04633              "\n"
    04634              "type=calldeflect args=Nr where to deflect\n"
    04635       );
    04636
    04637
    04638    ast_register_application("misdn_check_l2l1", misdn_check_l2l1, "misdn_check_l2l1",
    04639              "misdn_check_l2l1(<port>||g:<groupname>,timeout)"
    04640              "Checks if the L2 and L1 are up on either the given <port> or\n"
    04641              "on the ports in the group with <groupname>\n"
    04642              "If the L1/L2 are down, check_l2l1 gets up the L1/L2 and waits\n"
    04643              "for <timeout> seconds that this happens. Otherwise, nothing happens\n"
    04644              "\n"
    04645              "This application, ensures the L1/L2 state of the Ports in a group\n"
    04646              "it is intended to make the pmp_l1_check option redundant and to\n"
    04647              "fix a buggy switch config from your provider\n"
    04648              "\n"
    04649              "a sample dialplan would look like:\n\n"
    04650              "exten => _X.,1,misdn_check_l2l1(g:out|2)\n"
    04651              "exten => _X.,n,dial(mISDN/g:out/${EXTEN})\n"
    04652              "\n"
    04653       );
    04654
    04655
    04656    misdn_cfg_get( 0, MISDN_GEN_TRACEFILE, global_tracefile, BUFFERSIZE);
    04657
    04658    chan_misdn_log(0, 0, "-- mISDN Channel Driver Registred -- (BE AWARE THIS DRIVER IS EXPERIMENTAL!)\n");
    04659
    04660    return 0;
    04661 }

static int misdn_answer | ( | struct ast_channel * | ast | ) | `[static]`

Definition at line 1965 of file chan_misdn.c.

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

    01966 {
    01967    struct chan_list *p;
    01968
    01969
    01970    if (!ast || ! (p=MISDN_ASTERISK_TECH_PVT(ast)) ) return -1;
    01971
    01972    chan_misdn_log(1, p? (p->bc? p->bc->port : 0) : 0, "* ANSWER:\n");
    01973
    01974    if (!p) {
    01975       ast_log(LOG_WARNING, " --> Channel not connected ??\n");
    01976       ast_queue_hangup(ast);
    01977    }
    01978
    01979    if (!p->bc) {
    01980       chan_misdn_log(1, 0, " --> Got Answer, but theres no bc obj ??\n");
    01981
    01982       ast_queue_hangup(ast);
    01983    }
    01984
    01985    {
    01986       const char *tmp_key = pbx_builtin_getvar_helper(p->ast, "CRYPT_KEY");
    01987
    01988       if (tmp_key ) {
    01989          chan_misdn_log(1, p->bc->port, " --> Connection will be BF crypted\n");
    01990          {
    01991             int l = sizeof(p->bc->crypt_key);
    01992             strncpy(p->bc->crypt_key,tmp_key, l);
    01993             p->bc->crypt_key[l-1] = 0;
    01994          }
    01995       } else {
    01996          chan_misdn_log(3, p->bc->port, " --> Connection is without BF encryption\n");
    01997       }
    01998
    01999    }
    02000
    02001    {
    02002       const char *nodsp=pbx_builtin_getvar_helper(ast, "MISDN_DIGITAL_TRANS");
    02003       if (nodsp) {
    02004          chan_misdn_log(1, p->bc->port, " --> Connection is transparent digital\n");
    02005          p->bc->nodsp=1;
    02006          p->bc->hdlc=0;
    02007          p->bc->nojitter=1;
    02008       }
    02009    }
    02010
    02011    p->state = MISDN_CONNECTED;
    02012    stop_indicate(p);
    02013
    02014    if ( ast_strlen_zero(p->bc->cad) ) {
    02015       chan_misdn_log(2,p->bc->port," --> empty cad using dad\n");
    02016       ast_copy_string(p->bc->cad,p->bc->dad,sizeof(p->bc->cad));
    02017    }
    02018
    02019    misdn_lib_send_event( p->bc, EVENT_CONNECT);
    02020    start_bc_tones(p);
    02021
    02022    return 0;
    02023 }

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

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

    02562 {
    02563    struct chan_list *ch1,*ch2;
    02564    struct ast_channel *carr[2], *who;
    02565    int to=-1;
    02566    struct ast_frame *f;
    02567
    02568    ch1=get_chan_by_ast(c0);
    02569    ch2=get_chan_by_ast(c1);
    02570
    02571    carr[0]=c0;
    02572    carr[1]=c1;
    02573
    02574    if (ch1 && ch2 ) ;
    02575    else
    02576       return -1;
    02577
    02578    int p1_b, p2_b;
    02579
    02580    misdn_cfg_get(ch1->bc->port, MISDN_CFG_BRIDGING, &p1_b, sizeof(int));
    02581    misdn_cfg_get(ch2->bc->port, MISDN_CFG_BRIDGING, &p2_b, sizeof(int));
    02582
    02583    if ( ! p1_b || ! p2_b) {
    02584       ast_log(LOG_NOTICE, "Falling back to Asterisk bridging\n");
    02585       return AST_BRIDGE_FAILED;
    02586    }
    02587
    02588    int bridging;
    02589    misdn_cfg_get( 0, MISDN_GEN_BRIDGING, &bridging, sizeof(int));
    02590    if (bridging) {
    02591       /* trying to make a mISDN_dsp conference */
    02592       chan_misdn_log(1, ch1->bc->port, "I SEND: Making conference with Number:%d\n", ch1->bc->pid +1);
    02593       misdn_lib_bridge(ch1->bc,ch2->bc);
    02594    }
    02595
    02596    chan_misdn_log(1, ch1->bc->port, "* Making Native Bridge between %s and %s\n", ch1->bc->oad, ch2->bc->oad);
    02597
    02598
    02599    if (! (flags&AST_BRIDGE_DTMF_CHANNEL_0) )
    02600       ch1->ignore_dtmf=1;
    02601
    02602    if (! (flags&AST_BRIDGE_DTMF_CHANNEL_1) )
    02603       ch2->ignore_dtmf=1;
    02604
    02605
    02606    while(1) {
    02607       to=-1;
    02608       who = ast_waitfor_n(carr, 2, &to);
    02609
    02610       if (!who) {
    02611          ast_log(LOG_NOTICE,"misdn_bridge: empty read, breaking out\n");
    02612          break;
    02613       }
    02614       f = ast_read(who);
    02615
    02616       if (!f || f->frametype == AST_FRAME_CONTROL) {
    02617          /* got hangup .. */
    02618
    02619          if (!f)
    02620             chan_misdn_log(4,ch1->bc->port,"Read Null Frame\n");
    02621          else
    02622             chan_misdn_log(4,ch1->bc->port,"Read Frame Controll class:%d\n",f->subclass);
    02623
    02624          *fo=f;
    02625          *rc=who;
    02626
    02627          break;
    02628       }
    02629
    02630       if ( f->frametype == AST_FRAME_DTMF ) {
    02631          chan_misdn_log(1,0,"Read DTMF %d from %s\n",f->subclass, who->exten);
    02632
    02633          *fo=f;
    02634          *rc=who;
    02635          break;
    02636       }
    02637
    02638 #if 0
    02639       if (f->frametype == AST_FRAME_VOICE) {
    02640          chan_misdn_log(1, ch1->bc->port, "I SEND: Splitting conference with Number:%d\n", ch1->bc->pid +1);
    02641
    02642          continue;
    02643       }
    02644 #endif
    02645
    02646       if (who == c0) {
    02647          ast_write(c1,f);
    02648       }
    02649       else {
    02650          ast_write(c0,f);
    02651       }
    02652
    02653    }
    02654
    02655    chan_misdn_log(1, ch1->bc->port, "I SEND: Splitting conference with Number:%d\n", ch1->bc->pid +1);
    02656
    02657    misdn_lib_split_bridge(ch1->bc,ch2->bc);
    02658
    02659
    02660    return AST_BRIDGE_COMPLETE;
    02661 }

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

we should have l3id after sending setup

Definition at line 1821 of file chan_misdn.c.

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

    01822 {
    01823    int port=0;
    01824    int r;
    01825    struct chan_list *ch=MISDN_ASTERISK_TECH_PVT(ast);
    01826    struct misdn_bchannel *newbc;
    01827    char *opts=NULL, *ext;
    01828    char dest_cp[256];
    01829
    01830    {
    01831       strncpy(dest_cp,dest,sizeof(dest_cp)-1);
    01832       dest_cp[sizeof(dest_cp)]=0;
    01833
    01834       ext=dest_cp;
    01835       strsep(&ext,"/");
    01836       if (ext) {
    01837          opts=ext;
    01838          strsep(&opts,"/");
    01839       }  else {
    01840          ast_log(LOG_WARNING, "Malformed dialstring\n");
    01841          return -1;
    01842       }
    01843    }
    01844
    01845    if (!ast) {
    01846       ast_log(LOG_WARNING, " --> ! misdn_call called on ast_channel *ast where ast == NULL\n");
    01847       return -1;
    01848    }
    01849
    01850    if (((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) || !dest  ) {
    01851       ast_log(LOG_WARNING, " --> ! misdn_call called on %s, neither down nor reserved (or dest==NULL)\n", ast->name);
    01852       ast->hangupcause=41;
    01853       ast_setstate(ast, AST_STATE_DOWN);
    01854       return -1;
    01855    }
    01856
    01857    if (!ch) {
    01858       ast_log(LOG_WARNING, " --> ! misdn_call called on %s, neither down nor reserved (or dest==NULL)\n", ast->name);
    01859       ast->hangupcause=41;
    01860       ast_setstate(ast, AST_STATE_DOWN);
    01861       return -1;
    01862    }
    01863
    01864    newbc=ch->bc;
    01865
    01866    if (!newbc) {
    01867       ast_log(LOG_WARNING, " --> ! misdn_call called on %s, neither down nor reserved (or dest==NULL)\n", ast->name);
    01868       ast->hangupcause=41;
    01869       ast_setstate(ast, AST_STATE_DOWN);
    01870       return -1;
    01871    }
    01872
    01873    port=newbc->port;
    01874
    01875
    01876    chan_misdn_log(1, port, "* CALL: %s\n",dest);
    01877
    01878    chan_misdn_log(2, port, " --> * dad:%s tech:%s ctx:%s\n",ast->exten,ast->name, ast->context);
    01879
    01880    chan_misdn_log(3, port, " --> * adding2newbc ext %s\n",ast->exten);
    01881    if (ast->exten) {
    01882       int l = sizeof(newbc->dad);
    01883       strncpy(ast->exten,ext,sizeof(ast->exten));
    01884
    01885       strncpy(newbc->dad,ext,l);
    01886
    01887       newbc->dad[l-1] = 0;
    01888    }
    01889    newbc->rad[0]=0;
    01890    chan_misdn_log(3, port, " --> * adding2newbc callerid %s\n",AST_CID_P(ast));
    01891    if (ast_strlen_zero(newbc->oad) && AST_CID_P(ast) ) {
    01892
    01893       if (AST_CID_P(ast)) {
    01894          int l = sizeof(newbc->oad);
    01895          strncpy(newbc->oad,AST_CID_P(ast), l);
    01896          newbc->oad[l-1] = 0;
    01897       }
    01898    }
    01899
    01900    {
    01901       struct chan_list *ch=MISDN_ASTERISK_TECH_PVT(ast);
    01902       if (!ch) { ast_verbose("No chan_list in misdn_call\n"); return -1;}
    01903
    01904       newbc->capability=ast->transfercapability;
    01905       pbx_builtin_setvar_helper(ast,"TRANSFERCAPABILITY",ast_transfercapability2str(newbc->capability));
    01906       if ( ast->transfercapability == INFO_CAPABILITY_DIGITAL_UNRESTRICTED) {
    01907          chan_misdn_log(2, port, " --> * Call with flag Digital\n");
    01908       }
    01909
    01910
    01911       /* update screening and presentation */
    01912       update_config(ch,ORG_AST);
    01913
    01914       /* fill in some ies from channel vary*/
    01915       import_ch(ast, newbc, ch);
    01916
    01917       /* Finally The Options Override Everything */
    01918       if (opts)
    01919          misdn_set_opt_exec(ast,opts);
    01920       else
    01921          chan_misdn_log(2,port,"NO OPTS GIVEN\n");
    01922
    01923       /*check for bridging*/
    01924       int bridging;
    01925       misdn_cfg_get( 0, MISDN_GEN_BRIDGING, &bridging, sizeof(int));
    01926       if (bridging && ch->other_ch) {
    01927 #ifdef MISDN_1_2
    01928          chan_misdn_log(1, port, "Disabling EC (aka Pipeline) on both Sides\n");
    01929          *ch->bc->pipeline=0;
    01930          *ch->other_ch->bc->pipeline=0;
    01931 #else
    01932          chan_misdn_log(1, port, "Disabling EC on both Sides\n");
    01933          ch->bc->ec_enable=0;
    01934          ch->other_ch->bc->ec_enable=0;
    01935 #endif
    01936       }
    01937
    01938       r=misdn_lib_send_event( newbc, EVENT_SETUP );
    01939
    01940       /** we should have l3id after sending setup **/
    01941       ch->l3id=newbc->l3_id;
    01942    }
    01943
    01944    if ( r == -ENOCHAN  ) {
    01945       chan_misdn_log(0, port, " --> * Theres no Channel at the moment .. !\n");
    01946       chan_misdn_log(1, port, " --> * SEND: State Down pid:%d\n",newbc?newbc->pid:-1);
    01947       ast->hangupcause=34;
    01948       ast_setstate(ast, AST_STATE_DOWN);
    01949       return -1;
    01950    }
    01951
    01952    chan_misdn_log(2, port, " --> * SEND: State Dialing pid:%d\n",newbc?newbc->pid:1);
    01953
    01954    ast_setstate(ast, AST_STATE_DIALING);
    01955    ast->hangupcause=16;
    01956
    01957    if (newbc->nt) stop_bc_tones(ch);
    01958
    01959    ch->state=MISDN_CALLING;
    01960
    01961    return 0;
    01962 }

static int misdn_check_l2l1 | ( | struct ast_channel * | chan,
|  | void * | data |
| ) |  |  | `[static]`

Definition at line 4789 of file chan_misdn.c.

References AST_APP_ARG, AST_DECLARE_APP_ARGS, ast_log(), AST_STANDARD_APP_ARGS, ast_strlen_zero(), chan_misdn_log(), group, LOG_WARNING, misdn_cfg_get(), and misdn_cfg_get_next_port().

Referenced by load_module().

    04790 {
    04791    AST_DECLARE_APP_ARGS(args,
    04792          AST_APP_ARG(grouppar);
    04793          AST_APP_ARG(timeout);
    04794    );
    04795
    04796    if (ast_strlen_zero((char *)data)) {
    04797       ast_log(LOG_WARNING, "misdn_check_l2l1 Requires arguments\n");
    04798       return -1;
    04799    }
    04800
    04801    AST_STANDARD_APP_ARGS(args, data);
    04802
    04803    if (args.argc != 2) {
    04804       ast_log(LOG_WARNING, "Wrong argument count\n");
    04805       return 0;
    04806    }
    04807
    04808    /*ast_log(LOG_NOTICE, "Arguments: group/port '%s' timeout '%s'\n", args.grouppar, args.timeout);*/
    04809    char group[BUFFERSIZE+1];
    04810    char *port_str;
    04811
    04812    int port=0;
    04813    int timeout=atoi(args.timeout);
    04814    int dowait=0;
    04815
    04816    port_str=args.grouppar;
    04817
    04818    int port_up;
    04819    if (port_str[0]=='g' && port_str[1]==':' ) {
    04820       /* We make a group call lets checkout which ports are in my group */
    04821       port_str += 2;
    04822       strncpy(group, port_str, BUFFERSIZE);
    04823       group[BUFFERSIZE-1] = 0;
    04824       chan_misdn_log(2, 0, "Checking Ports in group: %s\n",group);
    04825
    04826       for ( port = misdn_cfg_get_next_port(port);
    04827          port > 0;
    04828          port = misdn_cfg_get_next_port(port)) {
    04829
    04830          chan_misdn_log(2,0,"trying port %d\n",port);
    04831
    04832          char cfg_group[BUFFERSIZE+1];
    04833          misdn_cfg_get(port, MISDN_CFG_GROUPNAME, cfg_group, BUFFERSIZE);
    04834
    04835          if (!strcasecmp(cfg_group, group)) {
    04836             port_up = misdn_lib_port_up(port, 1);
    04837
    04838             if (!port_up) {
    04839                chan_misdn_log(2, 0, " --> port '%d'\n", port);
    04840                misdn_lib_get_port_up(port);
    04841                dowait=1;
    04842             }
    04843          }
    04844       }
    04845
    04846    } else {
    04847       port = atoi(port_str);
    04848       chan_misdn_log(2, 0, "Checking Port: %d\n",port);
    04849       port_up = misdn_lib_port_up(port, 1);
    04850       if (!port_up) {
    04851          misdn_lib_get_port_up(port);
    04852          dowait=1;
    04853       }
    04854
    04855    }
    04856
    04857    if (dowait) {
    04858       chan_misdn_log(2, 0, "Waiting for '%d' seconds\n",timeout);
    04859       sleep(timeout);
    04860    }
    04861
    04862    return 0;
    04863 }

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

Definition at line 2025 of file chan_misdn.c.

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

    02026 {
    02027    struct chan_list *p;
    02028
    02029    if (!ast || ! (p=MISDN_ASTERISK_TECH_PVT(ast))) return -1;
    02030
    02031    struct misdn_bchannel *bc=p->bc;
    02032    chan_misdn_log(1, bc?bc->port:0, "* IND : Digit %c\n",digit);
    02033
    02034    if (!bc) {
    02035       ast_log(LOG_WARNING, " --> !! Got Digit Event withut having bchannel Object\n");
    02036       return -1;
    02037    }
    02038
    02039    switch (p->state ) {
    02040       case MISDN_CALLING:
    02041       {
    02042
    02043          char buf[8];
    02044          buf[0]=digit;
    02045          buf[1]=0;
    02046
    02047          int l = sizeof(bc->infos_pending);
    02048          strncat(bc->infos_pending,buf,l);
    02049          bc->infos_pending[l-1] = 0;
    02050       }
    02051       break;
    02052       case MISDN_CALLING_ACKNOWLEDGE:
    02053       {
    02054          bc->info_dad[0]=digit;
    02055          bc->info_dad[1]=0;
    02056
    02057          {
    02058             int l = sizeof(bc->dad);
    02059             strncat(bc->dad,bc->info_dad, l - strlen(bc->dad));
    02060             bc->dad[l-1] = 0;
    02061       }
    02062          {
    02063             int l = sizeof(p->ast->exten);
    02064             strncpy(p->ast->exten, bc->dad, l);
    02065             p->ast->exten[l-1] = 0;
    02066          }
    02067
    02068          misdn_lib_send_event( bc, EVENT_INFORMATION);
    02069       }
    02070       break;
    02071
    02072       default:
    02073          /* Do not send Digits in CONNECTED State, when
    02074           * the other side is too mISDN. */
    02075          if (p->other_ch )
    02076             return 0;
    02077
    02078          if ( bc->send_dtmf )
    02079             send_digit_to_chan(p,digit);
    02080       break;
    02081    }
    02082
    02083    return 0;
    02084 }

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

Definition at line 4748 of file chan_misdn.c.

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

Referenced by load_module().

    04749 {
    04750    struct chan_list *ch = MISDN_ASTERISK_TECH_PVT(chan);
    04751    char *tok, *tokb;
    04752
    04753    chan_misdn_log(0,0,"TYPE: %s\n",chan->tech->type);
    04754
    04755    if (strcasecmp(chan->tech->type,"mISDN")) {
    04756       ast_log(LOG_WARNING, "misdn_facility makes only sense with chan_misdn channels!\n");
    04757       return -1;
    04758    }
    04759
    04760    if (ast_strlen_zero((char *)data)) {
    04761       ast_log(LOG_WARNING, "misdn_facility Requires arguments\n");
    04762       return -1;
    04763    }
    04764
    04765    tok=strtok_r((char*)data,"|", &tokb) ;
    04766
    04767    if (!tok) {
    04768       ast_log(LOG_WARNING, "misdn_facility Requires arguments\n");
    04769       return -1;
    04770    }
    04771
    04772    if (!strcasecmp(tok,"calldeflect")) {
    04773       tok=strtok_r(NULL,"|", &tokb) ;
    04774
    04775       if (!tok) {
    04776          ast_log(LOG_WARNING, "Facility: Call Defl Requires arguments\n");
    04777       }
    04778
    04779       misdn_lib_send_facility(ch->bc, FACILITY_CALLDEFLECT, tok);
    04780
    04781    } else {
    04782       chan_misdn_log(1, ch->bc->port, "Unknown Facility: %s\n",tok);
    04783    }
    04784
    04785    return 0;
    04786
    04787 }

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

Definition at line 2087 of file chan_misdn.c.

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

    02088 {
    02089    struct chan_list *p;
    02090
    02091    if (!ast || ! (p=MISDN_ASTERISK_TECH_PVT(ast) )) return -1;
    02092
    02093    chan_misdn_log(1, p->bc?p->bc->port:0, "* IND: Got Fixup State:%s L3id:%x\n", misdn_get_ch_state(p), p->l3id);
    02094
    02095    p->ast = ast ;
    02096
    02097    return 0;
    02098 }

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

Definition at line 863 of file chan_misdn.c.

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

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

    00864 {
    00865    int i;
    00866    static char state[8];
    00867
    00868    if( !p) return NULL;
    00869
    00870    for (i=0; i< sizeof(state_array)/sizeof(struct state_struct); i++) {
    00871       if ( state_array[i].state == p->state) return state_array[i].txt;
    00872    }
    00873
    00874    sprintf(state,"%d",p->state) ;
    00875
    00876    return state;
    00877 }

static int misdn_hangup | ( | struct ast_channel * | ast | ) | `[static]`

Definition at line 2232 of file chan_misdn.c.

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

    02233 {
    02234    struct chan_list *p;
    02235    struct misdn_bchannel *bc=NULL;
    02236
    02237    ast_log(LOG_DEBUG, "misdn_hangup(%s)\n", ast->name);
    02238
    02239    if (!ast || ! (p=MISDN_ASTERISK_TECH_PVT(ast) ) ) return -1;
    02240
    02241    if (!p) {
    02242       chan_misdn_log(3, 0, "misdn_hangup called, without chan_list obj.\n");
    02243       return 0 ;
    02244    }
    02245
    02246    bc=p->bc;
    02247
    02248
    02249
    02250    MISDN_ASTERISK_TECH_PVT(ast)=NULL;
    02251    p->ast=NULL;
    02252
    02253    bc=p->bc;
    02254
    02255    if (ast->_state == AST_STATE_RESERVED ||
    02256       p->state == MISDN_NOTHING ||
    02257       p->state == MISDN_HOLDED ||
    02258       p->state == MISDN_HOLD_DISCONNECT ) {
    02259
    02260       CLEAN_CH:
    02261       /* between request and call */
    02262       ast_log(LOG_DEBUG, "State Reserved (or nothing) => chanIsAvail\n");
    02263       MISDN_ASTERISK_TECH_PVT(ast)=NULL;
    02264
    02265       cl_dequeue_chan(&cl_te, p);
    02266
    02267       close(p->pipe[0]);
    02268       close(p->pipe[1]);
    02269
    02270       free(p);
    02271       if (bc)
    02272          misdn_lib_release(bc);
    02273
    02274       return 0;
    02275    }
    02276
    02277    if (!bc) {
    02278       ast_log(LOG_WARNING,"Hangup with private but no bc ? state:%s l3id:%x\n", misdn_get_ch_state(p), p->l3id);
    02279       goto CLEAN_CH;
    02280    }
    02281
    02282
    02283    p->need_hangup=0;
    02284    p->need_queue_hangup=0;
    02285
    02286
    02287    if (!p->bc->nt)
    02288       stop_bc_tones(p);
    02289
    02290
    02291    {
    02292       const char *varcause=NULL;
    02293       bc->out_cause=ast->hangupcause?ast->hangupcause:16;
    02294
    02295       if ( (varcause=pbx_builtin_getvar_helper(ast, "HANGUPCAUSE")) ||
    02296            (varcause=pbx_builtin_getvar_helper(ast, "PRI_CAUSE"))) {
    02297          int tmpcause=atoi(varcause);
    02298          bc->out_cause=tmpcause?tmpcause:16;
    02299       }
    02300
    02301       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));
    02302       chan_misdn_log(3, bc->port, " --> l3id:%x\n",p->l3id);
    02303       chan_misdn_log(3, bc->port, " --> cause:%d\n",bc->cause);
    02304       chan_misdn_log(2, bc->port, " --> out_cause:%d\n",bc->out_cause);
    02305       chan_misdn_log(2, bc->port, " --> state:%s\n", misdn_get_ch_state(p));
    02306
    02307       switch (p->state) {
    02308       case MISDN_CALLING:
    02309       case MISDN_INCOMING_SETUP:
    02310          /* This is the only place in misdn_hangup, where we
    02311           * can call release_chan, else it might create lot's of trouble
    02312           * */
    02313          ast_log(LOG_NOTICE, "release channel, in CALLING/INCOMING_SETUP state.. no other events happened\n");
    02314          release_chan(bc);
    02315
    02316          p->state=MISDN_CLEANING;
    02317          misdn_lib_send_event( bc, EVENT_RELEASE_COMPLETE);
    02318          break;
    02319       case MISDN_HOLDED:
    02320       case MISDN_DIALING:
    02321          start_bc_tones(p);
    02322          hanguptone_indicate(p);
    02323
    02324          if (bc->need_disconnect)
    02325             misdn_lib_send_event( bc, EVENT_DISCONNECT);
    02326          break;
    02327
    02328       case MISDN_CALLING_ACKNOWLEDGE:
    02329          start_bc_tones(p);
    02330          hanguptone_indicate(p);
    02331
    02332          if (bc->need_disconnect)
    02333             misdn_lib_send_event( bc, EVENT_DISCONNECT);
    02334          break;
    02335
    02336       case MISDN_ALERTING:
    02337       case MISDN_PROGRESS:
    02338       case MISDN_PROCEEDING:
    02339          if (p->orginator != ORG_AST)
    02340             hanguptone_indicate(p);
    02341
    02342          /*p->state=MISDN_CLEANING;*/
    02343          if (bc->need_disconnect)
    02344             misdn_lib_send_event( bc, EVENT_DISCONNECT);
    02345          break;
    02346       case MISDN_CONNECTED:
    02347       case MISDN_PRECONNECTED:
    02348          /*  Alerting or Disconect */
    02349          if (p->bc->nt) {
    02350             start_bc_tones(p);
    02351             hanguptone_indicate(p);
    02352             p->bc->progress_indicator=8;
    02353          }
    02354          if (bc->need_disconnect)
    02355             misdn_lib_send_event( bc, EVENT_DISCONNECT);
    02356
    02357          /*p->state=MISDN_CLEANING;*/
    02358          break;
    02359       case MISDN_DISCONNECTED:
    02360          misdn_lib_send_event( bc, EVENT_RELEASE);
    02361          p->state=MISDN_CLEANING; /* MISDN_HUNGUP_FROM_AST; */
    02362          break;
    02363
    02364       case MISDN_RELEASED:
    02365       case MISDN_CLEANING:
    02366          p->state=MISDN_CLEANING;
    02367          break;
    02368
    02369       case MISDN_BUSY:
    02370          break;
    02371
    02372       case MISDN_HOLD_DISCONNECT:
    02373          /* need to send release here */
    02374          chan_misdn_log(1, bc->port, " --> cause %d\n",bc->cause);
    02375          chan_misdn_log(1, bc->port, " --> out_cause %d\n",bc->out_cause);
    02376
    02377          bc->out_cause=-1;
    02378          misdn_lib_send_event(bc,EVENT_RELEASE);
    02379          p->state=MISDN_CLEANING;
    02380          break;
    02381       default:
    02382          if (bc->nt) {
    02383             bc->out_cause=-1;
    02384             misdn_lib_send_event(bc, EVENT_RELEASE);
    02385             p->state=MISDN_CLEANING;
    02386          } else {
    02387             if (bc->need_disconnect)
    02388                misdn_lib_send_event(bc, EVENT_DISCONNECT);
    02389          }
    02390       }
    02391
    02392       p->state=MISDN_CLEANING;
    02393
    02394    }
    02395
    02396
    02397    chan_misdn_log(3, bc->port, " --> Channel: %s hanguped new state:%s\n",ast->name,misdn_get_ch_state(p));
    02398
    02399    return 0;
    02400 }

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

Definition at line 2102 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_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_RING, AST_CONTROL_RINGING, AST_CONTROL_TAKEOFFHOOK, AST_CONTROL_UNHOLD, ast_log(), ast_setstate(), AST_STATE_BUSY, AST_STATE_RINGING, chan_list::bc, chan_misdn_log(), ast_channel::exten, hanguptone_indicate(), chan_list::incoming_early_audio, LOG_WARNING, MISDN_ALERTING, MISDN_ASTERISK_TECH_PVT, MISDN_CONNECTED, ast_channel::name, ORG_MISDN, chan_list::orginator, chan_list::other_ch, start_bc_tones(), chan_list::state, and stop_indicate().

    02103 {
    02104    struct chan_list *p;
    02105
    02106
    02107    if (!ast || ! (p=MISDN_ASTERISK_TECH_PVT(ast))) {
    02108       ast_log(LOG_WARNING, "Returnded -1 in misdn_indication\n");
    02109       return -1;
    02110    }
    02111
    02112    if (!p->bc ) {
    02113       chan_misdn_log(1, 0, "* IND : Indication from %s\n",ast->exten);
    02114       ast_log(LOG_WARNING, "Private Pointer but no bc ?\n");
    02115       return -1;
    02116    }
    02117
    02118    chan_misdn_log(5, p->bc->port, "* IND : Indication [%d] from %s\n",cond, ast->exten);
    02119
    02120    switch (cond) {
    02121    case AST_CONTROL_BUSY:
    02122       chan_misdn_log(1, p->bc->port, "* IND :\tbusy pid:%d\n",p->bc?p->bc->pid:-1);
    02123       ast_setstate(ast,AST_STATE_BUSY);
    02124
    02125       p->bc->out_cause=17;
    02126       if (p->state != MISDN_CONNECTED) {
    02127          start_bc_tones(p);
    02128          misdn_lib_send_event( p->bc, EVENT_DISCONNECT);
    02129       } else {
    02130          chan_misdn_log(-1, p->bc->port, " --> !! Got Busy in Connected State !?! ast:%s\n", ast->name);
    02131       }
    02132       return -1;
    02133       break;
    02134    case AST_CONTROL_RING:
    02135       chan_misdn_log(1, p->bc->port, "* IND :\tring pid:%d\n",p->bc?p->bc->pid:-1);
    02136       return -1;
    02137       break;
    02138
    02139    case AST_CONTROL_RINGING:
    02140       chan_misdn_log(1, p->bc->port, "* IND :\tringing pid:%d\n",p->bc?p->bc->pid:-1);
    02141       switch (p->state) {
    02142          case MISDN_ALERTING:
    02143             chan_misdn_log(2, p->bc->port, " --> * IND :\tringing pid:%d but I was Ringing before, so ignoreing it\n",p->bc?p->bc->pid:-1);
    02144             break;
    02145          case MISDN_CONNECTED:
    02146             chan_misdn_log(2, p->bc->port, " --> * IND :\tringing pid:%d but Connected, so just send TONE_ALERTING without state changes \n",p->bc?p->bc->pid:-1);
    02147             return -1;
    02148             break;
    02149          default:
    02150             p->state=MISDN_ALERTING;
    02151             chan_misdn_log(2, p->bc->port, " --> * IND :\tringing pid:%d\n",p->bc?p->bc->pid:-1);
    02152             misdn_lib_send_event( p->bc, EVENT_ALERTING);
    02153
    02154             if (p->other_ch && p->other_ch->bc) {
    02155                if (misdn_inband_avail(p->other_ch->bc)) {
    02156                   chan_misdn_log(2,p->bc->port, " --> other End is mISDN and has inband info available\n");
    02157                   break;
    02158                }
    02159
    02160                if (!p->other_ch->bc->nt) {
    02161                   chan_misdn_log(2,p->bc->port, " --> other End is mISDN TE so it has inband info for sure (?)\n");
    02162                   break;
    02163                }
    02164             }
    02165
    02166             chan_misdn_log(3, p->bc->port, " --> * SEND: State Ring pid:%d\n",p->bc?p->bc->pid:-1);
    02167             ast_setstate(ast,AST_STATE_RINGING);
    02168
    02169             if ( !p->bc->nt && (p->orginator==ORG_MISDN) && !p->incoming_early_audio )
    02170                chan_misdn_log(2,p->bc->port, " --> incoming_early_audio off\n");
    02171             else
    02172                return -1;
    02173       }
    02174       break;
    02175    case AST_CONTROL_ANSWER:
    02176       chan_misdn_log(1, p->bc->port, " --> * IND :\tanswer pid:%d\n",p->bc?p->bc->pid:-1);
    02177       start_bc_tones(p);
    02178       break;
    02179    case AST_CONTROL_TAKEOFFHOOK:
    02180       chan_misdn_log(1, p->bc->port, " --> *\ttakeoffhook pid:%d\n",p->bc?p->bc->pid:-1);
    02181       return -1;
    02182       break;
    02183    case AST_CONTROL_OFFHOOK:
    02184       chan_misdn_log(1, p->bc->port, " --> *\toffhook pid:%d\n",p->bc?p->bc->pid:-1);
    02185       return -1;
    02186       break;
    02187    case AST_CONTROL_FLASH:
    02188       chan_misdn_log(1, p->bc->port, " --> *\tflash pid:%d\n",p->bc?p->bc->pid:-1);
    02189       break;
    02190    case AST_CONTROL_PROGRESS:
    02191       chan_misdn_log(1, p->bc->port, " --> * IND :\tprogress pid:%d\n",p->bc?p->bc->pid:-1);
    02192       misdn_lib_send_event( p->bc, EVENT_PROGRESS);
    02193       break;
    02194    case AST_CONTROL_PROCEEDING:
    02195       chan_misdn_log(1, p->bc->port, " --> * IND :\tproceeding pid:%d\n",p->bc?p->bc->pid:-1);
    02196       misdn_lib_send_event( p->bc, EVENT_PROCEEDING);
    02197       break;
    02198    case AST_CONTROL_CONGESTION:
    02199       chan_misdn_log(1, p->bc->port, " --> * IND :\tcongestion pid:%d\n",p->bc?p->bc->pid:-1);
    02200
    02201       p->bc->out_cause=42;
    02202       start_bc_tones(p);
    02203       misdn_lib_send_event( p->bc, EVENT_DISCONNECT);
    02204
    02205       if (p->bc->nt) {
    02206          hanguptone_indicate(p);
    02207       }
    02208       break;
    02209    case -1 :
    02210       chan_misdn_log(1, p->bc->port, " --> * IND :\t-1! (stop indication) pid:%d\n",p->bc?p->bc->pid:-1);
    02211
    02212       stop_indicate(p);
    02213
    02214       if (p->state == MISDN_CONNECTED)
    02215          start_bc_tones(p);
    02216
    02217       break;
    02218
    02219    case AST_CONTROL_HOLD:
    02220       chan_misdn_log(1, p->bc->port, " --> *\tHOLD pid:%d\n",p->bc?p->bc->pid:-1);
    02221       break;
    02222    case AST_CONTROL_UNHOLD:
    02223       chan_misdn_log(1, p->bc->port, " --> *\tUNHOLD pid:%d\n",p->bc?p->bc->pid:-1);
    02224       break;
    02225    default:
    02226       chan_misdn_log(1, p->bc->port, " --> * Unknown Indication:%d pid:%d\n",cond,p->bc?p->bc->pid:-1);
    02227    }
    02228
    02229    return 0;
    02230 }

void misdn_jb_destroy | ( | struct misdn_jb * | jb | ) |

Definition at line 5121 of file chan_misdn.c.

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

Referenced by config_jitterbuffer(), and release_chan().

    05122 {
    05123    ast_mutex_destroy(&jb->mutexjb);
    05124
    05125    free(jb->samples);
    05126    free(jb);
    05127 }

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

Definition at line 5193 of file chan_misdn.c.

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

Referenced by chan_misdn_jb_empty().

    05194 {
    05195     int i, wp, rp, read=0;
    05196
    05197     ast_mutex_lock (&jb->mutexjb);
    05198
    05199     rp=jb->rp;
    05200     wp=jb->wp;
    05201
    05202     if(jb->state_empty)
    05203     {
    05204    for(i=0; i<len; i++)
    05205    {
    05206        if(wp==rp)
    05207        {
    05208       jb->rp=rp;
    05209       jb->state_empty=0;
    05210
    05211       ast_mutex_unlock (&jb->mutexjb);
    05212
    05213       return read;
    05214        }
    05215        else
    05216        {
    05217       if(jb->ok[rp]==1)
    05218       {
    05219           data[i]=jb->samples[rp];
    05220           jb->ok[rp]=0;
    05221           rp=(rp!=jb->size-1 ? rp+1 : 0);
    05222           read+=1;
    05223       }
    05224        }
    05225    }
    05226
    05227    if(wp >= rp)
    05228       jb->state_buffer=wp-rp;
    05229    else
    05230       jb->state_buffer= jb->size-rp+wp;
    05231    chan_misdn_log(9,0,"misdn_jb_empty: read:%d | Bufferstatus:%d p:%x\n",len,jb->state_buffer,jb);
    05232
    05233    jb->rp=rp;
    05234     }
    05235     else
    05236        chan_misdn_log(9,0,"misdn_jb_empty: Wait...requested:%d p:%x\n",len,jb);
    05237
    05238     ast_mutex_unlock (&jb->mutexjb);
    05239
    05240     return read;
    05241 }

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

Definition at line 5131 of file chan_misdn.c.

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

Referenced by misdn_write().

    05132 {
    05133     int i, j, rp, wp;
    05134
    05135     if (!jb || ! data) return 0;
    05136
    05137     ast_mutex_lock (&jb->mutexjb);
    05138
    05139     wp=jb->wp;
    05140     rp=jb->rp;
    05141
    05142     for(i=0; i<len; i++)
    05143     {
    05144    jb->samples[wp]=data[i];
    05145    jb->ok[wp]=1;
    05146    wp = (wp!=jb->size-1 ? wp+1 : 0);
    05147
    05148    if(wp==jb->rp)
    05149        jb->state_full=1;
    05150     }
    05151
    05152     if(wp>=rp)
    05153       jb->state_buffer=wp-rp;
    05154     else
    05155       jb->state_buffer= jb->size-rp+wp;
    05156     chan_misdn_log(9,0,"misdn_jb_fill: written:%d | Bufferstatus:%d p:%x\n",len,jb->state_buffer,jb);
    05157
    05158     if(jb->state_full)
    05159     {
    05160    jb->wp=wp;
    05161
    05162    rp=wp;
    05163    for(j=0; j<jb->upper_threshold; j++)
    05164        rp = (rp!=0 ? rp-1 : jb->size-1);
    05165    jb->rp=rp;
    05166    jb->state_full=0;
    05167    jb->state_empty=1;
    05168
    05169    ast_mutex_unlock (&jb->mutexjb);
    05170
    05171    return -1;
    05172     }
    05173
    05174     if(!jb->state_empty)
    05175     {
    05176    jb->bytes_wrote+=len;
    05177    if(jb->bytes_wrote>=jb->upper_threshold)
    05178    {
    05179        jb->state_empty=1;
    05180        jb->bytes_wrote=0;
    05181    }
    05182     }
    05183     jb->wp=wp;
    05184
    05185     ast_mutex_unlock (&jb->mutexjb);
    05186
    05187     return 0;
    05188 }

struct misdn_jb * misdn_jb_init | ( | int | size,
|  | int | upper_threshold |
| ) |  |  | `[read]`

Definition at line 5087 of file chan_misdn.c.

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

Referenced by config_jitterbuffer().

    05088 {
    05089     int i;
    05090     struct misdn_jb *jb = (struct misdn_jb*) malloc(sizeof(struct misdn_jb));
    05091     jb->size = size;
    05092     jb->upper_threshold = upper_threshold;
    05093     jb->wp = 0;
    05094     jb->rp = 0;
    05095     jb->state_full = 0;
    05096     jb->state_empty = 0;
    05097     jb->bytes_wrote = 0;
    05098     jb->samples = (char *)malloc(size*sizeof(char));
    05099
    05100     if (!jb->samples) {
    05101        chan_misdn_log(-1,0,"No free Mem for jb->samples\n");
    05102        return NULL;
    05103     }
    05104
    05105     jb->ok = (char *)malloc(size*sizeof(char));
    05106
    05107     if (!jb->ok) {
    05108        chan_misdn_log(-1,0,"No free Mem for jb->ok\n");
    05109        return NULL;
    05110     }
    05111
    05112     for(i=0; i<size; i++)
    05113    jb->ok[i]=0;
    05114
    05115     ast_mutex_init(&jb->mutexjb);
    05116
    05117     return jb;
    05118 }

static struct ast_channel * misdn_new | ( | struct chan_list * | cl,
|  | int | state,
|  | char * | exten,
|  | char * | callerid,
|  | int | format,
|  | int | port,
|  | int | c |
| ) |  |  | `[static, read]`

Definition at line 3000 of file chan_misdn.c.

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

Referenced by cb_events(), and misdn_request().

    03001 {
    03002    struct ast_channel *tmp;
    03003
    03004    tmp = ast_channel_alloc(1);
    03005
    03006    if (tmp) {
    03007       chan_misdn_log(2, 0, " --> * NEW CHANNEL dad:%s oad:%s\n",exten,callerid);
    03008
    03009
    03010       if (c<=0) {
    03011          c=glob_channel++;
    03012          snprintf(tmp->name, sizeof(tmp->name), "%s/%d-u%d",
    03013              misdn_type, port, c);
    03014       } else {
    03015          snprintf(tmp->name, sizeof(tmp->name), "%s/%d-%d",
    03016              misdn_type, port, c);
    03017       }
    03018
    03019       tmp->type = misdn_type;
    03020
    03021       tmp->nativeformats = prefformat;
    03022
    03023       tmp->readformat = format;
    03024       tmp->rawreadformat = format;
    03025       tmp->writeformat = format;
    03026       tmp->rawwriteformat = format;
    03027
    03028       tmp->tech_pvt = chlist;
    03029
    03030       int bridging;
    03031       misdn_cfg_get( 0, MISDN_GEN_BRIDGING, &bridging, sizeof(int));
    03032
    03033       if (bridging)
    03034          tmp->tech = &misdn_tech;
    03035       else
    03036          tmp->tech = &misdn_tech_wo_bridge;
    03037
    03038       tmp->writeformat = format;
    03039       tmp->readformat = format;
    03040       tmp->priority=1;
    03041
    03042       if (exten)
    03043          ast_copy_string(tmp->exten, exten,  sizeof(tmp->exten));
    03044       else
    03045          chan_misdn_log(1,0,"misdn_new: no exten given.\n");
    03046
    03047       if (callerid) {
    03048          char *cid_name, *cid_num;
    03049
    03050          ast_callerid_parse(callerid, &cid_name, &cid_num);
    03051
    03052          if (!ast_strlen_zero(cid_num))
    03053             tmp->cid.cid_num = strdup(cid_num);
    03054          if (!ast_strlen_zero(cid_name))
    03055             tmp->cid.cid_name = strdup(cid_name);
    03056       }
    03057
    03058       {
    03059          if (pipe(chlist->pipe)<0)
    03060             perror("Pipe failed\n");
    03061
    03062          tmp->fds[0]=chlist->pipe[0];
    03063
    03064       }
    03065
    03066       ast_setstate(tmp, state);
    03067       if (state == AST_STATE_RING)
    03068          tmp->rings = 1;
    03069       else
    03070          tmp->rings = 0;
    03071
    03072
    03073    } else {
    03074       chan_misdn_log(-1,0,"Unable to allocate channel structure\n");
    03075    }
    03076
    03077    return tmp;
    03078 }

static int misdn_overlap_dial_task | ( | void * | data | ) | `[static]`

Definition at line 549 of file chan_misdn.c.

References chan_list::ast, ast_exists_extension(), ast_mutex_lock(), ast_mutex_unlock(), chan_list::bc, chan_misdn_log(), chan_list::context, hanguptone_indicate(), MISDN_DIALING, MISDN_WAITING4DIGS, chan_list::overlap_dial, chan_list::overlap_dial_task, chan_list::overlap_tv, chan_list::overlap_tv_lock, pbx_start_chan(), chan_list::state, and stop_indicate().

Referenced by cb_events().

    00550 {
    00551    struct timeval tv_end, tv_now;
    00552    int diff;
    00553    struct chan_list *ch = (struct chan_list *)data;
    00554
    00555    chan_misdn_log(4, ch->bc->port, "overlap dial task, chan_state: %d\n", ch->state);
    00556
    00557    if (ch->state != MISDN_WAITING4DIGS) {
    00558       ch->overlap_dial_task = -1;
    00559       return 0;
    00560    }
    00561
    00562    ast_mutex_lock(&ch->overlap_tv_lock);
    00563    tv_end = ch->overlap_tv;
    00564    ast_mutex_unlock(&ch->overlap_tv_lock);
    00565
    00566    tv_end.tv_sec += ch->overlap_dial;
    00567    tv_now = ast_tvnow();
    00568
    00569    diff = ast_tvdiff_ms(tv_end, tv_now);
    00570
    00571    if (diff <= 100) {
    00572       /* if we are 100ms near the timeout, we are satisfied.. */
    00573       stop_indicate(ch);
    00574       if (ast_exists_extension(ch->ast, ch->context, ch->bc->dad, 1, ch->bc->oad)) {
    00575          ch->state=MISDN_DIALING;
    00576          if (pbx_start_chan(ch) < 0) {
    00577             chan_misdn_log(-1, ch->bc->port, "ast_pbx_start returned < 0 in misdn_overlap_dial_task\n");
    00578             goto misdn_overlap_dial_task_disconnect;
    00579          }
    00580       } else {
    00581 misdn_overlap_dial_task_disconnect:
    00582          hanguptone_indicate(ch);
    00583          if (ch->bc->nt)
    00584             misdn_lib_send_event(ch->bc, EVENT_RELEASE_COMPLETE );
    00585          else
    00586             misdn_lib_send_event(ch->bc, EVENT_RELEASE);
    00587       }
    00588       ch->overlap_dial_task = -1;
    00589       return 0;
    00590    } else
    00591       return diff;
    00592 }

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

Definition at line 696 of file chan_misdn.c.

References RESULT_SHOWUSAGE.

    00697 {
    00698    int port;
    00699
    00700    if (argc != 4)
    00701       return RESULT_SHOWUSAGE;
    00702
    00703    port = atoi(argv[3]);
    00704
    00705    misdn_lib_port_block(port);
    00706
    00707    return 0;
    00708 }

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

Definition at line 767 of file chan_misdn.c.

References RESULT_SHOWUSAGE.

    00768 {
    00769    int port;
    00770
    00771    if (argc != 4)
    00772       return RESULT_SHOWUSAGE;
    00773
    00774    port = atoi(argv[3]);
    00775
    00776    misdn_lib_get_port_down(port);
    00777
    00778    return 0;
    00779 }

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

Definition at line 710 of file chan_misdn.c.

References RESULT_SHOWUSAGE.

    00711 {
    00712    int port;
    00713
    00714    if (argc != 4)
    00715       return RESULT_SHOWUSAGE;
    00716
    00717    port = atoi(argv[3]);
    00718
    00719    misdn_lib_port_unblock(port);
    00720
    00721    return 0;
    00722 }

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

Definition at line 753 of file chan_misdn.c.

References RESULT_SHOWUSAGE.

    00754 {
    00755    int port;
    00756
    00757    if (argc != 4)
    00758       return RESULT_SHOWUSAGE;
    00759
    00760    port = atoi(argv[3]);
    00761
    00762    misdn_lib_get_port_up(port);
    00763
    00764    return 0;
    00765 }

static struct ast_frame* misdn_read | ( | struct ast_channel * | ast | ) | `[static, read]`

Definition at line 2402 of file chan_misdn.c.

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

    02403 {
    02404    struct chan_list *tmp;
    02405    int len;
    02406
    02407    if (!ast) {
    02408       chan_misdn_log(1,0,"misdn_read called without ast\n");
    02409       return NULL;
    02410    }
    02411    if (! (tmp=MISDN_ASTERISK_TECH_PVT(ast)) ) {
    02412       chan_misdn_log(1,0,"misdn_read called without ast->pvt\n");
    02413       return NULL;
    02414    }
    02415
    02416    if (!tmp->bc && !(tmp->state==MISDN_HOLDED)) {
    02417       chan_misdn_log(1,0,"misdn_read called without bc\n");
    02418       return NULL;
    02419    }
    02420
    02421    len=read(tmp->pipe[0],tmp->ast_rd_buf,sizeof(tmp->ast_rd_buf));
    02422
    02423    if (len<=0) {
    02424       /* we hangup here, since our pipe is closed */
    02425       chan_misdn_log(2,tmp->bc->port,"misdn_read: Pipe closed, hanging up\n");
    02426       return NULL;
    02427    }
    02428
    02429    tmp->frame.frametype  = AST_FRAME_VOICE;
    02430    tmp->frame.subclass = AST_FORMAT_ALAW;
    02431    tmp->frame.datalen = len;
    02432    tmp->frame.samples = len ;
    02433    tmp->frame.mallocd =0 ;
    02434    tmp->frame.offset= 0 ;
    02435    tmp->frame.delivery= ast_tv(0,0) ;
    02436    tmp->frame.src = NULL;
    02437    tmp->frame.data = tmp->ast_rd_buf ;
    02438
    02439    if (tmp->faxdetect || tmp->ast_dsp ) {
    02440       return process_ast_dsp(tmp, &tmp->frame);
    02441    }
    02442
    02443    return &tmp->frame;
    02444 }

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

Definition at line 902 of file chan_misdn.c.

References ast_cli(), and reload_config().

    00903 {
    00904    ast_cli(fd, "Reloading mISDN Config\n");
    00905    reload_config();
    00906    return 0;
    00907 }

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

Definition at line 2763 of file chan_misdn.c.

References chan_list::ast, ast_log(), AST_STATE_RESERVED, ast_strlen_zero(), chan_list::bc, chan_misdn_log(), robin_list::channel, cl_queue_chan(), get_robin_position(), group, init_chan_list(), LOG_ERROR, LOG_WARNING, misdn_cfg_get(), misdn_cfg_get_next_port(), misdn_cfg_get_next_port_spin(), misdn_cfg_is_group_method(), misdn_new(), misdn_type, chan_list::need_hangup, ORG_AST, robin_list::port, and read_config().

    02765 {
    02766    struct ast_channel *tmp = NULL;
    02767    char group[BUFFERSIZE+1]="";
    02768    char buf[128];
    02769    char buf2[128], *ext=NULL, *port_str;
    02770    char *tokb=NULL, *p=NULL;
    02771    int channel=0, port=0;
    02772    struct misdn_bchannel *newbc = NULL;
    02773    int dec=0;
    02774
    02775    struct chan_list *cl=init_chan_list(ORG_AST);
    02776
    02777    sprintf(buf,"%s/%s",misdn_type,(char*)data);
    02778    ast_copy_string(buf2,data, 128);
    02779
    02780    port_str=strtok_r(buf2,"/", &tokb);
    02781
    02782    ext=strtok_r(NULL,"/", &tokb);
    02783
    02784    if (port_str) {
    02785       if (port_str[0]=='g' && port_str[1]==':' ) {
    02786          /* We make a group call lets checkout which ports are in my group */
    02787          port_str += 2;
    02788          strncpy(group, port_str, BUFFERSIZE);
    02789          group[127] = 0;
    02790          chan_misdn_log(2, 0, " --> Group Call group: %s\n",group);
    02791       }
    02792       else if ((p = strchr(port_str, ':'))) {
    02793          /* we have a preselected channel */
    02794          *p = 0;
    02795          channel = atoi(++p);
    02796          port = atoi(port_str);
    02797          chan_misdn_log(2, port, " --> Call on preselected Channel (%d).\n", channel);
    02798       }
    02799       else {
    02800          port = atoi(port_str);
    02801       }
    02802    } else {
    02803       ast_log(LOG_WARNING, " --> ! IND : CALL dad:%s WITHOUT PORT/Group, check extension.conf\n",ext);
    02804       return NULL;
    02805    }
    02806
    02807    if (misdn_cfg_is_group_method(group, METHOD_STANDARD_DEC)) {
    02808       chan_misdn_log(4, port, " --> STARTING STANDARDDEC...\n");
    02809       dec=1;
    02810    }
    02811
    02812    if (!ast_strlen_zero(group)) {
    02813
    02814       char cfg_group[BUFFERSIZE+1];
    02815       struct robin_list *rr = NULL;
    02816
    02817       if (misdn_cfg_is_group_method(group, METHOD_ROUND_ROBIN)) {
    02818          chan_misdn_log(4, port, " --> STARTING ROUND ROBIN...\n");
    02819          rr = get_robin_position(group);
    02820       }
    02821
    02822
    02823       if (rr) {
    02824          int robin_channel = rr->channel;
    02825          int port_start;
    02826          int next_chan = 1;
    02827
    02828          do {
    02829             port_start = 0;
    02830             for (port = misdn_cfg_get_next_port_spin(rr->port); port > 0 && port != port_start;
    02831                 port = misdn_cfg_get_next_port_spin(port)) {
    02832
    02833                if (!port_start)
    02834                   port_start = port;
    02835
    02836                if (port >= port_start)
    02837                   next_chan = 1;
    02838
    02839                if (port <= port_start && next_chan) {
    02840                   int maxbchans=misdn_lib_get_maxchans(port);
    02841                   if (++robin_channel >= maxbchans) {
    02842                      robin_channel = 1;
    02843                   }
    02844                   next_chan = 0;
    02845                }
    02846
    02847                misdn_cfg_get(port, MISDN_CFG_GROUPNAME, cfg_group, BUFFERSIZE);
    02848
    02849                if (!strcasecmp(cfg_group, group)) {
    02850                   int port_up;
    02851                   int check;
    02852                   misdn_cfg_get(port, MISDN_CFG_PMP_L1_CHECK, &check, sizeof(int));
    02853                   port_up = misdn_lib_port_up(port, check);
    02854
    02855                   if (check && !port_up)
    02856                      chan_misdn_log(1,port,"L1 is not Up on this Port\n");
    02857
    02858                   if (check && port_up<0) {
    02859                      ast_log(LOG_WARNING,"This port (%d) is blocked\n", port);
    02860                   }
    02861
    02862
    02863                   if ( port_up>0 )  {
    02864                      newbc = misdn_lib_get_free_bc(port, robin_channel,0, 0);
    02865                      if (newbc) {
    02866                         chan_misdn_log(4, port, " Success! Found port:%d channel:%d\n", newbc->port, newbc->channel);
    02867                         if (port_up)
    02868                            chan_misdn_log(4, port, "portup:%d\n",  port_up);
    02869                         rr->port = newbc->port;
    02870                         rr->channel = newbc->channel;
    02871                         break;
    02872                      }
    02873                   }
    02874                }
    02875             }
    02876          } while (!newbc && robin_channel != rr->channel);
    02877
    02878       } else {
    02879          for (port=misdn_cfg_get_next_port(0); port > 0;
    02880              port=misdn_cfg_get_next_port(port)) {
    02881
    02882             misdn_cfg_get( port, MISDN_CFG_GROUPNAME, cfg_group, BUFFERSIZE);
    02883
    02884             chan_misdn_log(3,port, "Group [%s] Port [%d]\n", group, port);
    02885             if (!strcasecmp(cfg_group, group)) {
    02886                int port_up;
    02887                int check;
    02888                misdn_cfg_get(port, MISDN_CFG_PMP_L1_CHECK, &check, sizeof(int));
    02889                port_up = misdn_lib_port_up(port, check);
    02890
    02891                chan_misdn_log(4, port, "portup:%d\n", port_up);
    02892
    02893                if ( port_up>0 ) {
    02894                   newbc = misdn_lib_get_free_bc(port, 0, 0, dec);
    02895                   if (newbc)
    02896                      break;
    02897                }
    02898             }
    02899          }
    02900       }
    02901
    02902       /* Group dial failed ?*/
    02903       if (!newbc) {
    02904          ast_log(LOG_WARNING,
    02905                "Could not Dial out on group '%s'.\n"
    02906                "\tEither the L2 and L1 on all of these ports where DOWN (see 'show application misdn_check_l2l1')\n"
    02907                "\tOr there was no free channel on none of the ports\n\n"
    02908                , group);
    02909          return NULL;
    02910       }
    02911    } else { /* 'Normal' Port dial * Port dial */
    02912       if (channel)
    02913          chan_misdn_log(1, port," --> preselected_channel: %d\n",channel);
    02914       newbc = misdn_lib_get_free_bc(port, channel, 0, dec);
    02915
    02916       if (!newbc) {
    02917          ast_log(LOG_WARNING, "Could not create channel on port:%d with extensions:%s\n",port,ext);
    02918          return NULL;
    02919       }
    02920    }
    02921
    02922
    02923    /* create ast_channel and link all the objects together */
    02924    cl->bc=newbc;
    02925
    02926    tmp = misdn_new(cl, AST_STATE_RESERVED, ext, NULL, format, port, channel);
    02927    if (!tmp) {
    02928       ast_log(LOG_ERROR,"Could not create Asterisk object\n");
    02929       return NULL;
    02930    }
    02931
    02932    cl->ast=tmp;
    02933
    02934    /* register chan in local list */
    02935    cl_queue_chan(&cl_te, cl) ;
    02936
    02937    /* fill in the config into the objects */
    02938    read_config(cl, ORG_AST);
    02939
    02940    /* important */
    02941    cl->need_hangup=0;
    02942
    02943    return tmp;
    02944 }

static int misdn_restart_pid | ( | int | fd,
|  | int | argc,
|  | char * | argv[] |
| ) |  |  | `[static]`

Definition at line 739 of file chan_misdn.c.

References RESULT_SHOWUSAGE.

    00740 {
    00741    int pid;
    00742
    00743    if (argc != 4)
    00744       return RESULT_SHOWUSAGE;
    00745
    00746    pid = atoi(argv[3]);
    00747
    00748    misdn_lib_pid_restart(pid);
    00749
    00750    return 0;
    00751 }

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

Definition at line 725 of file chan_misdn.c.

References RESULT_SHOWUSAGE.

    00726 {
    00727    int port;
    00728
    00729    if (argc != 4)
    00730       return RESULT_SHOWUSAGE;
    00731
    00732    port = atoi(argv[3]);
    00733
    00734    misdn_lib_port_restart(port);
    00735
    00736    return 0;
    00737 }

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

Definition at line 1069 of file chan_misdn.c.

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

    01070 {
    01071    char *channame;
    01072    char *nr;
    01073
    01074    if (argc != 5)
    01075       return RESULT_SHOWUSAGE;
    01076
    01077    channame = argv[3];
    01078    nr = argv[4];
    01079
    01080    ast_cli(fd, "Sending Calldeflection (%s) to %s\n",nr, channame);
    01081
    01082    {
    01083       struct chan_list *tmp=get_chan_by_ast_name(channame);
    01084
    01085       if (!tmp) {
    01086          ast_cli(fd, "Sending CD with nr %s to %s failed Channel does not exist\n",nr, channame);
    01087          return 0;
    01088       } else {
    01089
    01090          misdn_lib_send_facility(tmp->bc, FACILITY_CALLDEFLECT, nr);
    01091       }
    01092    }
    01093
    01094    return 0;
    01095 }

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

Definition at line 1118 of file chan_misdn.c.

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

    01119 {
    01120    char *channame;
    01121    char *msg;
    01122
    01123    if (argc != 5)
    01124       return RESULT_SHOWUSAGE;
    01125
    01126    channame = argv[3];
    01127    msg = argv[4];
    01128
    01129    ast_cli(fd, "Sending %s to %s\n",msg, channame);
    01130
    01131    {
    01132       struct chan_list *tmp=get_chan_by_ast_name(channame);
    01133
    01134       if (!tmp) {
    01135          ast_cli(fd, "Sending %s to %s failed Channel does not exist\n",msg, channame);
    01136          return 0;
    01137       } else {
    01138 #if 1
    01139          int i;
    01140          int msglen = strlen(msg);
    01141          for (i=0; i<msglen; i++) {
    01142             ast_cli(fd, "Sending: %c\n",msg[i]);
    01143             send_digit_to_chan(tmp, msg[i]);
    01144             /* res = ast_safe_sleep(tmp->ast, 250); */
    01145             usleep(250000);
    01146             /* res = ast_waitfor(tmp->ast,100); */
    01147          }
    01148 #else
    01149          int res;
    01150          res = ast_dtmf_stream(tmp->ast,NULL,msg,250);
    01151 #endif
    01152       }
    01153    }
    01154
    01155    return 0;
    01156 }

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

Definition at line 1195 of file chan_misdn.c.

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

    01196 {
    01197    char *channame;
    01198    char *msg;
    01199
    01200    if (argc != 5)
    01201       return RESULT_SHOWUSAGE;
    01202
    01203    channame = argv[3];
    01204    msg = argv[4];
    01205
    01206    ast_cli(fd, "Sending %s to %s\n",msg, channame);
    01207    {
    01208       struct chan_list *tmp;
    01209       tmp=get_chan_by_ast_name(channame);
    01210
    01211       if (tmp && tmp->bc) {
    01212          ast_copy_string(tmp->bc->display, msg, sizeof(tmp->bc->display));
    01213          misdn_lib_send_event(tmp->bc, EVENT_INFORMATION);
    01214       } else {
    01215          ast_cli(fd,"No such channel %s\n",channame);
    01216          return RESULT_FAILURE;
    01217       }
    01218    }
    01219
    01220    return RESULT_SUCCESS ;
    01221 }

static int misdn_send_restart | ( | int | fd,
|  | int | argc,
|  | char * | argv[] |
| ) |  |  | `[static]`

Definition at line 1097 of file chan_misdn.c.

References RESULT_SHOWUSAGE.

    01098 {
    01099    int port;
    01100    int channel;
    01101
    01102    if ( (argc < 4) ||  (argc >  5) )
    01103       return RESULT_SHOWUSAGE;
    01104
    01105    port = atoi(argv[3]);
    01106
    01107    if (argc==5) {
    01108       channel = atoi(argv[4]);
    01109       misdn_lib_send_restart(port, channel);
    01110    } else
    01111       misdn_lib_send_restart(port, -1 );
    01112
    01113    return 0;
    01114 }

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

Definition at line 2947 of file chan_misdn.c.

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

    02948 {
    02949    struct chan_list *tmp=chan->tech_pvt;
    02950
    02951    if (tmp && tmp->bc) {
    02952       ast_copy_string(tmp->bc->display,text,sizeof(tmp->bc->display));
    02953       misdn_lib_send_event(tmp->bc, EVENT_INFORMATION);
    02954    } else {
    02955       ast_log(LOG_WARNING, "No chan_list but send_text request?\n");
    02956       return -1;
    02957    }
    02958
    02959    return 0;
    02960 }

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

Definition at line 688 of file chan_misdn.c.

References RESULT_SHOWUSAGE.

    00689 {
    00690    if (argc != 5) return RESULT_SHOWUSAGE;
    00691
    00692    return 0;
    00693 }

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

Definition at line 631 of file chan_misdn.c.

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

    00632 {
    00633    if (argc != 4 && argc != 5 && argc != 6 && argc != 7)
    00634       return RESULT_SHOWUSAGE;
    00635
    00636    int level = atoi(argv[3]);
    00637
    00638    switch (argc) {
    00639       case 4:
    00640       case 5: {
    00641                int only = 0;
    00642                if (argc == 5) {
    00643                   if (strncasecmp(argv[4], "only", strlen(argv[4])))
    00644                      return RESULT_SHOWUSAGE;
    00645                   else
    00646                      only = 1;
    00647                }
    00648                int i;
    00649                for (i=0; i<=max_ports; i++) {
    00650                   misdn_debug[i] = level;
    00651                   misdn_debug_only[i] = only;
    00652                }
    00653                ast_cli(fd, "changing debug level for all ports to %d%s\n",misdn_debug[0], only?" (only)":"");
    00654             }
    00655             break;
    00656       case 6:
    00657       case 7: {
    00658                if (strncasecmp(argv[4], "port", strlen(argv[4])))
    00659                   return RESULT_SHOWUSAGE;
    00660                int port = atoi(argv[5]);
    00661                if (port <= 0 || port > max_ports) {
    00662                   switch (max_ports) {
    00663                      case 0:
    00664                         ast_cli(fd, "port number not valid! no ports available so you won't get lucky with any number here...\n");
    00665                         break;
    00666                      case 1:
    00667                         ast_cli(fd, "port number not valid! only port 1 is availble.\n");
    00668                         break;
    00669                      default:
    00670                         ast_cli(fd, "port number not valid! only ports 1 to %d are available.\n", max_ports);
    00671                      }
    00672                      return 0;
    00673                }
    00674                if (argc == 7) {
    00675                   if (strncasecmp(argv[6], "only", strlen(argv[6])))
    00676                      return RESULT_SHOWUSAGE;
    00677                   else
    00678                      misdn_debug_only[port] = 1;
    00679                } else
    00680                   misdn_debug_only[port] = 0;
    00681                misdn_debug[port] = level;
    00682                ast_cli(fd, "changing debug level to %d%s for port %d\n", misdn_debug[port], misdn_debug_only[port]?" (only)":"", port);
    00683             }
    00684    }
    00685    return 0;
    00686 }

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

Definition at line 4865 of file chan_misdn.c.

References chan_list::ast_dsp, ast_dsp_new(), ast_dsp_set_features(), AST_FORMAT_ALAW, AST_FORMAT_SLINEAR, ast_log(), ast_strlen_zero(), ast_translator_build_path(), chan_list::bc, chan_misdn_log(), config_jitterbuffer(), chan_list::dsp, DSP_FEATURE_DTMF_DETECT, DSP_FEATURE_FAX_DETECT, chan_list::faxdetect, chan_list::jb_len, chan_list::jb_upper_threshold, key(), keys, LOG_WARNING, MISDN_ASTERISK_TECH_PVT, misdn_cfg_get(), chan_list::orginator, strsep(), ast_channel::tech, chan_list::trans, and ast_channel_tech::type.

Referenced by load_module(), and misdn_call().

    04866 {
    04867    struct chan_list *ch = MISDN_ASTERISK_TECH_PVT(chan);
    04868    char *tok,*tokb;
    04869    int  keyidx=0;
    04870    int rxgain=0;
    04871    int txgain=0;
    04872    int change_jitter=0;
    04873
    04874    if (strcasecmp(chan->tech->type,"mISDN")) {
    04875       ast_log(LOG_WARNING, "misdn_set_opt makes only sense with chan_misdn channels!\n");
    04876       return -1;
    04877    }
    04878
    04879    if (ast_strlen_zero((char *)data)) {
    04880       ast_log(LOG_WARNING, "misdn_set_opt Requires arguments\n");
    04881       return -1;
    04882    }
    04883
    04884    for (tok=strtok_r((char*)data, ":",&tokb);
    04885         tok;
    04886         tok=strtok_r(NULL,":",&tokb) ) {
    04887       int neglect=0;
    04888
    04889       if (tok[0] == '!' ) {
    04890          neglect=1;
    04891          tok++;
    04892       }
    04893
    04894       switch(tok[0]) {
    04895
    04896       case 'd' :
    04897          ast_copy_string(ch->bc->display,++tok,84);
    04898          chan_misdn_log(1, ch->bc->port, "SETOPT: Display:%s\n",ch->bc->display);
    04899          break;
    04900
    04901       case 'n':
    04902          chan_misdn_log(1, ch->bc->port, "SETOPT: No DSP\n");
    04903          ch->bc->nodsp=1;
    04904          break;
    04905
    04906       case 'j':
    04907          chan_misdn_log(1, ch->bc->port, "SETOPT: jitter\n");
    04908          tok++;
    04909          change_jitter=1;
    04910
    04911          switch ( tok[0] ) {
    04912          case 'b' :
    04913             ch->jb_len=atoi(++tok);
    04914             chan_misdn_log(1, ch->bc->port, " --> buffer_len:%d\n",ch->jb_len);
    04915             break;
    04916          case 't' :
    04917             ch->jb_upper_threshold=atoi(++tok);
    04918             chan_misdn_log(1, ch->bc->port, " --> upper_threshold:%d\n",ch->jb_upper_threshold);
    04919             break;
    04920
    04921          case 'n':
    04922             ch->bc->nojitter=1;
    04923             chan_misdn_log(1, ch->bc->port, " --> nojitter\n");
    04924             break;
    04925
    04926          default:
    04927             ch->jb_len=4000;
    04928             ch->jb_upper_threshold=0;
    04929             chan_misdn_log(1, ch->bc->port, " --> buffer_len:%d (default)\n",ch->jb_len);
    04930             chan_misdn_log(1, ch->bc->port, " --> upper_threshold:%d (default)\n",ch->jb_upper_threshold);
    04931          }
    04932
    04933          break;
    04934
    04935       case 'v':
    04936          tok++;
    04937
    04938          switch ( tok[0] ) {
    04939          case 'r' :
    04940             rxgain=atoi(++tok);
    04941             if (rxgain<-8) rxgain=-8;
    04942             if (rxgain>8) rxgain=8;
    04943             ch->bc->rxgain=rxgain;
    04944             chan_misdn_log(1, ch->bc->port, "SETOPT: Volume:%d\n",rxgain);
    04945             break;
    04946          case 't':
    04947             txgain=atoi(++tok);
    04948             if (txgain<-8) txgain=-8;
    04949             if (txgain>8) txgain=8;
    04950             ch->bc->txgain=txgain;
    04951             chan_misdn_log(1, ch->bc->port, "SETOPT: Volume:%d\n",txgain);
    04952             break;
    04953          }
    04954          break;
    04955
    04956       case 'c':
    04957          keyidx=atoi(++tok);
    04958
    04959          char keys[4096];
    04960          char *key=NULL, *tmp;
    04961          int i;
    04962          misdn_cfg_get( 0, MISDN_GEN_CRYPT_KEYS, keys, sizeof(keys));
    04963
    04964          tmp=keys;
    04965
    04966          for (i=0; i<keyidx; i++) {
    04967             key=strsep(&tmp,",");
    04968          }
    04969
    04970          if (key) {
    04971             ast_copy_string(ch->bc->crypt_key, key, sizeof(ch->bc->crypt_key));
    04972          }
    04973
    04974          chan_misdn_log(0, ch->bc->port, "SETOPT: crypt with key:%s\n",ch->bc->crypt_key);
    04975          break;
    04976
    04977       case 'e':
    04978          chan_misdn_log(1, ch->bc->port, "SETOPT: EchoCancel\n");
    04979
    04980          if (neglect) {
    04981             chan_misdn_log(1, ch->bc->port, " --> disabled\n");
    04982 #ifdef MISDN_1_2
    04983             *ch->bc->pipeline=0;
    04984 #else
    04985             ch->bc->ec_enable=0;
    04986 #endif
    04987          } else {
    04988 #ifdef MISDN_1_2
    04989             update_pipeline_config(ch->bc);
    04990 #else
    04991             ch->bc->ec_enable=1;
    04992             ch->bc->orig=ch->orginator;
    04993             tok++;
    04994             if (*tok) {
    04995                ch->bc->ec_deftaps=atoi(tok);
    04996             }
    04997 #endif
    04998          }
    04999
    05000          break;
    05001
    05002       case 'h':
    05003          chan_misdn_log(1, ch->bc->port, "SETOPT: Digital\n");
    05004
    05005          if (strlen(tok) > 1 && tok[1]=='1') {
    05006             chan_misdn_log(1, ch->bc->port, "SETOPT: HDLC \n");
    05007             if (!ch->bc->hdlc) {
    05008                ch->bc->hdlc=1;
    05009             }
    05010          }
    05011          ch->bc->capability=INFO_CAPABILITY_DIGITAL_UNRESTRICTED;
    05012          break;
    05013
    05014       case 's':
    05015          chan_misdn_log(1, ch->bc->port, "SETOPT: Send DTMF\n");
    05016          ch->bc->send_dtmf=1;
    05017          break;
    05018
    05019       case 'f':
    05020          chan_misdn_log(1, ch->bc->port, "SETOPT: Faxdetect\n");
    05021          ch->faxdetect=1;
    05022          break;
    05023
    05024       case 'a':
    05025          chan_misdn_log(1, ch->bc->port, "SETOPT: AST_DSP (for DTMF)\n");
    05026          ch->ast_dsp=1;
    05027          break;
    05028
    05029       case 'p':
    05030          chan_misdn_log(1, ch->bc->port, "SETOPT: callerpres: %s\n",&tok[1]);
    05031          /* CRICH: callingpres!!! */
    05032          if (strstr(tok,"allowed") ) {
    05033             ch->bc->pres=0;
    05034          } else if (strstr(tok,"not_screened")) {
    05035             ch->bc->pres=1;
    05036          }
    05037
    05038
    05039          break;
    05040
    05041
    05042       default:
    05043          break;
    05044       }
    05045    }
    05046
    05047    if (change_jitter)
    05048       config_jitterbuffer(ch);
    05049
    05050
    05051    if (ch->faxdetect || ch->ast_dsp) {
    05052
    05053       if (!ch->dsp) ch->dsp = ast_dsp_new();
    05054       if (ch->dsp) ast_dsp_set_features(ch->dsp, DSP_FEATURE_DTMF_DETECT| DSP_FEATURE_FAX_DETECT);
    05055       if (!ch->trans) ch->trans=ast_translator_build_path(AST_FORMAT_SLINEAR, AST_FORMAT_ALAW);
    05056    }
    05057
    05058    if (ch->ast_dsp) {
    05059       chan_misdn_log(1,ch->bc->port,"SETOPT: with AST_DSP we deactivate mISDN_dsp\n");
    05060       ch->bc->nodsp=1;
    05061       ch->bc->nojitter=1;
    05062    }
    05063
    05064    return 0;
    05065 }

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

Definition at line 1022 of file chan_misdn.c.

References MAXTICS, and RESULT_SHOWUSAGE.

    01023 {
    01024    if (argc != 4)
    01025       return RESULT_SHOWUSAGE;
    01026
    01027    MAXTICS=atoi(argv[3]);
    01028
    01029    return 0;
    01030 }

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

Definition at line 996 of file chan_misdn.c.

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

    00997 {
    00998    struct chan_list *help=cl_te;
    00999
    01000    if (argc != 4)
    01001       return RESULT_SHOWUSAGE;
    01002
    01003    for (;help; help=help->next) {
    01004       struct misdn_bchannel *bc=help->bc;
    01005       struct ast_channel *ast=help->ast;
    01006
    01007       if (bc && ast) {
    01008          if (!strcasecmp(ast->name,argv[3])) {
    01009             print_bc_info(fd, help, bc);
    01010             break;
    01011          }
    01012       }
    01013    }
    01014
    01015
    01016    return 0;
    01017 }

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

Definition at line 964 of file chan_misdn.c.

References chan_list::ast, AST_CID_P, ast_cli(), chan_list::bc, ast_channel::exten, chan_list::l3id, misdn_debug, MISDN_HOLDED, chan_list::next, print_bc_info(), and chan_list::state.

    00965 {
    00966    struct chan_list *help=cl_te;
    00967
    00968    ast_cli(fd,"Chan List: %p\n",cl_te);
    00969
    00970    for (;help; help=help->next) {
    00971       struct misdn_bchannel *bc=help->bc;
    00972       struct ast_channel *ast=help->ast;
    00973       if (misdn_debug[0] > 2) ast_cli(fd, "Bc:%p Ast:%p\n", bc, ast);
    00974       if (bc) {
    00975          print_bc_info(fd, help, bc);
    00976       } else {
    00977          if (help->state == MISDN_HOLDED) {
    00978             ast_cli(fd, "ITS A HOLDED BC:\n");
    00979             ast_cli(fd, " --> l3_id: %x\n"
    00980                   " --> dad:%s oad:%s\n"
    00981
    00982                   ,help->l3id
    00983                   ,ast->exten
    00984                   ,AST_CID_P(ast)
    00985                   );
    00986          } else {
    00987             ast_cli(fd,"* Channel in unknown STATE !!! Exten:%s, Callerid:%s\n", ast->exten, AST_CID_P(ast));
    00988          }
    00989       }
    00990    }
    00991
    00992    misdn_dump_chanlist();
    00993    return 0;
    00994 }

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

Definition at line 782 of file chan_misdn.c.

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

    00783 {
    00784    char buffer[BUFFERSIZE];
    00785    enum misdn_cfg_elements elem;
    00786    int linebreak;
    00787
    00788    int onlyport = -1;
    00789    if (argc >= 4) {
    00790       if (!sscanf(argv[3], "%30d", &onlyport) || onlyport < 0) {
    00791          ast_cli(fd, "Unknown option: %s\n", argv[3]);
    00792          return RESULT_SHOWUSAGE;
    00793       }
    00794    }
    00795
    00796    if (argc == 3 || onlyport == 0) {
    00797       ast_cli(fd,"Misdn General-Config: \n");
    00798       ast_cli(fd," -> Version: chan_misdn-" CHAN_MISDN_VERSION "\n");
    00799       for (elem = MISDN_GEN_FIRST + 1, linebreak = 1; elem < MISDN_GEN_LAST; elem++, linebreak++) {
    00800          misdn_cfg_get_config_string( 0, elem, buffer, BUFFERSIZE);
    00801          ast_cli(fd, "%-36s%s", buffer, !(linebreak % 2) ? "\n" : "");
    00802       }
    00803       ast_cli(fd, "\n");
    00804    }
    00805
    00806    if (onlyport < 0) {
    00807       int port = misdn_cfg_get_next_port(0);
    00808       for (; port > 0; port = misdn_cfg_get_next_port(port)) {
    00809          ast_cli(fd, "\n[PORT %d]\n", port);
    00810          for (elem = MISDN_CFG_FIRST + 1, linebreak = 1; elem < MISDN_CFG_LAST; elem++, linebreak++) {
    00811             misdn_cfg_get_config_string( port, elem, buffer, BUFFERSIZE);
    00812             ast_cli(fd, "%-36s%s", buffer, !(linebreak % 2) ? "\n" : "");
    00813          }
    00814          ast_cli(fd, "\n");
    00815       }
    00816    }
    00817
    00818    if (onlyport > 0) {
    00819       if (misdn_cfg_is_port_valid(onlyport)) {
    00820          ast_cli(fd, "[PORT %d]\n", onlyport);
    00821          for (elem = MISDN_CFG_FIRST + 1, linebreak = 1; elem < MISDN_CFG_LAST; elem++, linebreak++) {
    00822             misdn_cfg_get_config_string( onlyport, elem, buffer, BUFFERSIZE);
    00823             ast_cli(fd, "%-36s%s", buffer, !(linebreak % 2) ? "\n" : "");
    00824          }
    00825          ast_cli(fd, "\n");
    00826       } else {
    00827          ast_cli(fd, "Port %d is not active!\n", onlyport);
    00828       }
    00829    }
    00830    return 0;
    00831 }

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

Definition at line 1050 of file chan_misdn.c.

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

    01051 {
    01052    int port;
    01053
    01054    if (argc != 4)
    01055       return RESULT_SHOWUSAGE;
    01056
    01057    port = atoi(argv[3]);
    01058
    01059    ast_cli(fd, "BEGIN STACK_LIST:\n");
    01060
    01061    char buf[128];
    01062    get_show_stack_details(port,buf);
    01063    ast_cli(fd,"  %s  Debug:%d%s\n",buf, misdn_debug[port], misdn_debug_only[port]?"(only)":"");
    01064
    01065
    01066    return 0;
    01067 }

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

Definition at line 1032 of file chan_misdn.c.

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

    01033 {
    01034    int port;
    01035
    01036    ast_cli(fd, "BEGIN STACK_LIST:\n");
    01037
    01038    for (port=misdn_cfg_get_next_port(0); port > 0;
    01039         port=misdn_cfg_get_next_port(port)) {
    01040       char buf[128];
    01041       get_show_stack_details(port,buf);
    01042       ast_cli(fd,"  %s  Debug:%d%s\n", buf, misdn_debug[port], misdn_debug_only[port]?"(only)":"");
    01043    }
    01044
    01045
    01046    return 0;
    01047
    01048 }

static int misdn_tasks_add_variable | ( | int | timeout,
|  | ast_sched_cb | callback,
|  | void * | data |
| ) |  |  | `[static]`

Definition at line 539 of file chan_misdn.c.

References _misdn_tasks_add_variable().

Referenced by cb_events().

    00540 {
    00541    return _misdn_tasks_add_variable(timeout, callback, data, 1);
    00542 }

static void misdn_tasks_destroy | ( | void |  | ) | `[static]`

Definition at line 502 of file chan_misdn.c.

References chan_misdn_log(), misdn_tasks_thread, and sched_context_destroy().

Referenced by unload_module().

    00503 {
    00504    if (misdn_tasks) {
    00505       chan_misdn_log(4, 0, "Killing misdn_tasks thread\n");
    00506       if ( pthread_cancel(misdn_tasks_thread) == 0 ) {
    00507          cb_log(4, 0, "Joining misdn_tasks thread\n");
    00508          pthread_join(misdn_tasks_thread, NULL);
    00509       }
    00510       sched_context_destroy(misdn_tasks);
    00511    }
    00512 }

static void misdn_tasks_init | ( | void |  | ) | `[static]`

Definition at line 483 of file chan_misdn.c.

References chan_misdn_log(), misdn_tasks_thread, misdn_tasks_thread_func(), pthread_create, and sched_context_create().

Referenced by _misdn_tasks_add_variable().

    00484 {
    00485    sem_t blocker;
    00486    int i = 5;
    00487
    00488    if (sem_init(&blocker, 0, 0)) {
    00489       perror("chan_misdn: Failed to initialize semaphore!");
    00490       exit(1);
    00491    }
    00492
    00493    chan_misdn_log(4, 0, "Starting misdn_tasks thread\n");
    00494
    00495    misdn_tasks = sched_context_create();
    00496    pthread_create(&misdn_tasks_thread, NULL, misdn_tasks_thread_func, &blocker);
    00497
    00498    while (sem_wait(&blocker) && --i);
    00499    sem_destroy(&blocker);
    00500 }

static void misdn_tasks_remove | ( | int | task_id | ) | `[static]`

Definition at line 544 of file chan_misdn.c.

References ast_sched_del().

Referenced by release_chan().

    00545 {
    00546    ast_sched_del(misdn_tasks, task_id);
    00547 }

static void* misdn_tasks_thread_func | ( | void * | data | ) | `[static]`

Definition at line 459 of file chan_misdn.c.

References ast_sched_runq(), ast_sched_wait(), chan_misdn_log(), poll(), and sighandler().

Referenced by misdn_tasks_init().

    00460 {
    00461    int wait;
    00462    struct sigaction sa;
    00463
    00464    sa.sa_handler = sighandler;
    00465    sa.sa_flags = SA_NODEFER;
    00466    sigemptyset(&sa.sa_mask);
    00467    sigaddset(&sa.sa_mask, SIGUSR1);
    00468    sigaction(SIGUSR1, &sa, NULL);
    00469
    00470    sem_post((sem_t *)data);
    00471
    00472    while (1) {
    00473       wait = ast_sched_wait(misdn_tasks);
    00474       if (wait < 0)
    00475          wait = 8000;
    00476       if (poll(NULL, 0, wait) < 0)
    00477          chan_misdn_log(4, 0, "Waking up misdn_tasks thread\n");
    00478       ast_sched_runq(misdn_tasks);
    00479    }
    00480    return NULL;
    00481 }

static void misdn_tasks_wakeup | ( | void |  | ) | `[inline, static]`

Definition at line 514 of file chan_misdn.c.

References misdn_tasks_thread.

Referenced by _misdn_tasks_add_variable().

    00515 {
    00516    pthread_kill(misdn_tasks_thread, SIGUSR1);
    00517 }

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

Definition at line 1158 of file chan_misdn.c.

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

    01159 {
    01160    char *channame;
    01161
    01162    if (argc != 4)
    01163       return RESULT_SHOWUSAGE;
    01164
    01165    channame = argv[3];
    01166
    01167    ast_cli(fd, "Toggling EchoCancel on %s\n", channame);
    01168
    01169    {
    01170       struct chan_list *tmp=get_chan_by_ast_name(channame);
    01171
    01172       if (!tmp) {
    01173          ast_cli(fd, "Toggling EchoCancel %s failed Channel does not exist\n", channame);
    01174          return 0;
    01175       } else {
    01176
    01177          tmp->toggle_ec=tmp->toggle_ec?0:1;
    01178
    01179          if (tmp->toggle_ec) {
    01180 #ifdef MISDN_1_2
    01181             update_pipeline_config(tmp->bc);
    01182 #else
    01183             update_ec_config(tmp->bc);
    01184 #endif
    01185             manager_ec_enable(tmp->bc);
    01186          } else {
    01187             manager_ec_disable(tmp->bc);
    01188          }
    01189       }
    01190    }
    01191
    01192    return 0;
    01193 }

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

Definition at line 3353 of file chan_misdn.c.

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

Referenced by cb_events().

    03354 {
    03355    chan_misdn_log(4,0,"TRANSFERING %s to %s\n",holded_chan->ast->name, tmp_ch->ast->name);
    03356
    03357    tmp_ch->state=MISDN_HOLD_DISCONNECT;
    03358
    03359    ast_moh_stop(AST_BRIDGED_P(holded_chan->ast));
    03360
    03361    holded_chan->state=MISDN_CONNECTED;
    03362    //misdn_lib_transfer(holded_chan->bc);
    03363    ast_channel_masquerade(holded_chan->ast, AST_BRIDGED_P(tmp_ch->ast));
    03364 }

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

Definition at line 2447 of file chan_misdn.c.

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

    02448 {
    02449    struct chan_list *ch;
    02450    int i  = 0;
    02451
    02452    if (!ast || ! (ch=MISDN_ASTERISK_TECH_PVT(ast)) ) return -1;
    02453
    02454    if (ch->state == MISDN_HOLDED) {
    02455       chan_misdn_log(8, 0, "misdn_write: Returning because holded\n");
    02456       return 0;
    02457    }
    02458
    02459    if (!ch->bc ) {
    02460
    02461       ast_log(LOG_WARNING, "private but no bc\n");
    02462       return -1;
    02463    }
    02464
    02465    if (ch->notxtone) {
    02466       chan_misdn_log(9, ch->bc->port, "misdn_write: Returning because notxone\n");
    02467       return 0;
    02468    }
    02469
    02470
    02471    if ( !frame->subclass) {
    02472       chan_misdn_log(4, ch->bc->port, "misdn_write: * prods us\n");
    02473       return 0;
    02474    }
    02475
    02476    if ( !(frame->subclass & prefformat)) {
    02477
    02478       chan_misdn_log(-1, ch->bc->port, "Got Unsupported Frame with Format:%d\n", frame->subclass);
    02479       return 0;
    02480    }
    02481
    02482
    02483    if ( !frame->samples ) {
    02484       chan_misdn_log(4, ch->bc->port, "misdn_write: zero write\n");
    02485
    02486       if (!strcmp(frame->src,"ast_prod")) {
    02487          chan_misdn_log(1, ch->bc->port, "misdn_write: state (%s) prodded.\n", misdn_get_ch_state(ch));
    02488
    02489          if (ch->ts) {
    02490             chan_misdn_log(4,ch->bc->port,"Starting Playtones\n");
    02491             misdn_lib_tone_generator_start(ch->bc);
    02492          }
    02493          return 0;
    02494       }
    02495
    02496       return -1;
    02497    }
    02498
    02499    if ( ! ch->bc->addr ) {
    02500       chan_misdn_log(8, ch->bc->port, "misdn_write: no addr for bc dropping:%d\n", frame->samples);
    02501       return 0;
    02502    }
    02503
    02504 #if MISDN_DEBUG
    02505    {
    02506       int i, max=5>frame->samples?frame->samples:5;
    02507
    02508       printf("write2mISDN %p %d bytes: ", p, frame->samples);
    02509
    02510       for (i=0; i<  max ; i++) printf("%2.2x ",((char*) frame->data)[i]);
    02511       printf ("\n");
    02512    }
    02513 #endif
    02514
    02515
    02516    switch (ch->bc->bc_state) {
    02517       case BCHAN_ACTIVATED:
    02518       case BCHAN_BRIDGED:
    02519          break;
    02520       default:
    02521       if (!ch->dropped_frame_cnt)
    02522          chan_misdn_log(5, ch->bc->port, "BC not active (nor bridged) droping: %d frames addr:%x exten:%s cid:%s ch->state:%s bc_state:%d l3id:%x\n",frame->samples,ch->bc->addr, ast->exten, ast->cid.cid_num,misdn_get_ch_state( ch), ch->bc->bc_state, ch->bc->l3_id);
    02523
    02524       ch->dropped_frame_cnt++;
    02525       if (ch->dropped_frame_cnt > 100) {
    02526          ch->dropped_frame_cnt=0;
    02527          chan_misdn_log(5, ch->bc->port, "BC not active (nor bridged) droping: %d frames addr:%x  dropped > 100 frames!\n",frame->samples,ch->bc->addr);
    02528
    02529       }
    02530
    02531       return 0;
    02532    }
    02533
    02534    chan_misdn_log(9, ch->bc->port, "Sending :%d bytes 2 MISDN\n",frame->samples);
    02535
    02536    if ( !ch->bc->nojitter && misdn_cap_is_speech(ch->bc->capability) ) {
    02537       /* Buffered Transmit (triggert by read from isdn side)*/
    02538       if (misdn_jb_fill(ch->jb,frame->data,frame->samples) < 0) {
    02539          if (ch->bc->active)
    02540             cb_log(0,ch->bc->port,"Misdn Jitterbuffer Overflow.\n");
    02541       }
    02542
    02543    } else {
    02544       /*transmit without jitterbuffer*/
    02545       i=misdn_lib_tx2misdn_frm(ch->bc, frame->data, frame->samples);
    02546    }
    02547
    02548
    02549
    02550    return 0;
    02551 }

static int pbx_start_chan | ( | struct chan_list * | ch | ) | `[static]`

Channel Queue End

Definition at line 3238 of file chan_misdn.c.

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

Referenced by do_immediate_setup(), misdn_overlap_dial_task(), and start_pbx().

    03239 {
    03240    int ret=ast_pbx_start(ch->ast);
    03241
    03242    if (ret>=0)
    03243       ch->need_hangup=0;
    03244    else
    03245       ch->need_hangup=1;
    03246
    03247    return ret;
    03248 }

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

Definition at line 909 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::l3id, misdn_debug, misdn_get_ch_state(), ast_channel::name, chan_list::norxtone, chan_list::notxtone, ORG_AST, and chan_list::orginator.

Referenced by misdn_show_cl(), and misdn_show_cls().

    00910 {
    00911    struct ast_channel *ast=help->ast;
    00912    ast_cli(fd,
    00913       "* Pid:%d Prt:%d Ch:%d Mode:%s Org:%s dad:%s oad:%s rad:%s ctx:%s state:%s\n",
    00914
    00915       bc->pid, bc->port, bc->channel,
    00916       bc->nt?"NT":"TE",
    00917       help->orginator == ORG_AST?"*":"I",
    00918       ast?ast->exten:NULL,
    00919       ast?AST_CID_P(ast):NULL,
    00920       bc->rad,
    00921       ast?ast->context:NULL,
    00922       misdn_get_ch_state(help)
    00923       );
    00924    if (misdn_debug[bc->port] > 0)
    00925       ast_cli(fd,
    00926          "  --> astname: %s\n"
    00927          "  --> ch_l3id: %x\n"
    00928          "  --> ch_addr: %x\n"
    00929          "  --> bc_addr: %x\n"
    00930          "  --> bc_l3id: %x\n"
    00931          "  --> display: %s\n"
    00932          "  --> activated: %d\n"
    00933          "  --> state: %s\n"
    00934          "  --> capability: %s\n"
    00935 #ifdef MISDN_1_2
    00936          "  --> pipeline: %s\n"
    00937 #else
    00938          "  --> echo_cancel: %d\n"
    00939 #endif
    00940          "  --> notone : rx %d tx:%d\n"
    00941          "  --> bc_hold: %d\n",
    00942          help->ast->name,
    00943          help->l3id,
    00944          help->addr,
    00945          bc->addr,
    00946          bc?bc->l3_id:-1,
    00947          bc->display,
    00948
    00949          bc->active,
    00950          bc_state2str(bc->bc_state),
    00951          bearer2str(bc->capability),
    00952 #ifdef MISDN_1_2
    00953          bc->pipeline,
    00954 #else
    00955          bc->ec_enable,
    00956 #endif
    00957
    00958          help->norxtone,help->notxtone,
    00959          bc->holded
    00960          );
    00961
    00962 }

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

Definition at line 440 of file chan_misdn.c.

References bearer2str(), and chan_misdn_log().

Referenced by cb_events().

    00441 {
    00442
    00443    chan_misdn_log(2, bc->port, " --> Bearer: %s\n",bearer2str(bc->capability));
    00444
    00445    switch(bc->law) {
    00446    case INFO_CODEC_ALAW:
    00447       chan_misdn_log(2, bc->port, " --> Codec: Alaw\n");
    00448       break;
    00449    case INFO_CODEC_ULAW:
    00450       chan_misdn_log(2, bc->port, " --> Codec: Ulaw\n");
    00451       break;
    00452    }
    00453 }

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

Definition at line 423 of file chan_misdn.c.

References chan_misdn_log().

Referenced by cb_events().

    00424 {
    00425    switch (bc->fac_type) {
    00426    case FACILITY_CALLDEFLECT:
    00427       chan_misdn_log(2,bc->port," --> calldeflect: %s\n",
    00428                 bc->fac.calldeflect_nr);
    00429       break;
    00430    case FACILITY_CENTREX:
    00431       chan_misdn_log(2,bc->port," --> centrex: %s\n",
    00432                 bc->fac.cnip);
    00433       break;
    00434    default:
    00435       chan_misdn_log(2,bc->port," --> unknown\n");
    00436
    00437    }
    00438 }

static struct ast_frame * process_ast_dsp | ( | struct chan_list * | tmp,
|  | struct ast_frame * | frame |
| ) |  |  | `[static, read]`

Definition at line 3081 of file chan_misdn.c.

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

Referenced by misdn_read().

    03082 {
    03083    struct ast_frame *f,*f2;
    03084    if (tmp->trans)
    03085       f2=ast_translate(tmp->trans, frame,0);
    03086    else {
    03087       chan_misdn_log(0, tmp->bc->port, "No T-Path found\n");
    03088       return NULL;
    03089    }
    03090
    03091    f = ast_dsp_process(tmp->ast, tmp->dsp, f2);
    03092    if (f && (f->frametype == AST_FRAME_DTMF)) {
    03093       ast_log(LOG_DEBUG, "Detected inband DTMF digit: %c\n", f->subclass);
    03094       if (f->subclass == 'f' && tmp->faxdetect) {
    03095          /* Fax tone -- Handle and return NULL */
    03096          struct ast_channel *ast = tmp->ast;
    03097          if (!tmp->faxhandled) {
    03098             tmp->faxhandled++;
    03099             if (strcmp(ast->exten, "fax")) {
    03100                if (ast_exists_extension(ast, ast_strlen_zero(ast->macrocontext)? ast->context : ast->macrocontext, "fax", 1, AST_CID_P(ast))) {
    03101                   if (option_verbose > 2)
    03102                      ast_verbose(VERBOSE_PREFIX_3 "Redirecting %s to fax extension\n", ast->name);
    03103                   /* Save the DID/DNIS when we transfer the fax call to a "fax" extension */
    03104                   pbx_builtin_setvar_helper(ast,"FAXEXTEN",ast->exten);
    03105                   if (ast_async_goto(ast, ast->context, "fax", 1))
    03106                      ast_log(LOG_WARNING, "Failed to async goto '%s' into fax of '%s'\n", ast->name, ast->context);
    03107                } else
    03108                   ast_log(LOG_NOTICE, "Fax detected, but no fax extension ctx:%s exten:%s\n",ast->context, ast->exten);
    03109             } else
    03110                ast_log(LOG_DEBUG, "Already in a fax extension, not redirecting\n");
    03111          } else
    03112             ast_log(LOG_DEBUG, "Fax already handled\n");
    03113
    03114       }  else if ( tmp->ast_dsp) {
    03115          chan_misdn_log(2, tmp->bc->port, " --> * SEND: DTMF (AST_DSP) :%c\n",f->subclass);
    03116          return f;
    03117       }
    03118    }
    03119
    03120    frame->frametype = AST_FRAME_NULL;
    03121    frame->subclass = 0;
    03122    return frame;
    03123 }

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

ORIGINATOR MISDN

Definition at line 1620 of file chan_misdn.c.

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

Referenced by cb_events(), and misdn_request().

    01620                                                        {
    01621
    01622    if (!ch) {
    01623       ast_log(LOG_WARNING, "Cannot configure without chanlist\n");
    01624       return -1;
    01625    }
    01626
    01627    struct ast_channel *ast=ch->ast;
    01628    struct misdn_bchannel *bc=ch->bc;
    01629    if (! ast || ! bc ) {
    01630       ast_log(LOG_WARNING, "Cannot configure without ast || bc\n");
    01631       return -1;
    01632    }
    01633
    01634    int port=bc->port;
    01635
    01636    chan_misdn_log(5,port,"read_config: Getting Config\n");
    01637
    01638    char lang[BUFFERSIZE+1];
    01639
    01640    misdn_cfg_get( port, MISDN_CFG_LANGUAGE, lang, BUFFERSIZE);
    01641    ast_copy_string(ast->language, lang, sizeof(ast->language));
    01642
    01643    char musicclass[BUFFERSIZE+1];
    01644
    01645    misdn_cfg_get( port, MISDN_CFG_MUSICCLASS, musicclass, BUFFERSIZE);
    01646    ast_copy_string(ast->musicclass, musicclass, sizeof(ast->musicclass));
    01647
    01648    misdn_cfg_get( port, MISDN_CFG_TXGAIN, &bc->txgain, sizeof(int));
    01649    misdn_cfg_get( port, MISDN_CFG_RXGAIN, &bc->rxgain, sizeof(int));
    01650
    01651    misdn_cfg_get( port, MISDN_CFG_INCOMING_EARLY_AUDIO, &ch->incoming_early_audio, sizeof(int));
    01652
    01653    misdn_cfg_get( port, MISDN_CFG_SENDDTMF, &bc->send_dtmf, sizeof(int));
    01654
    01655    misdn_cfg_get( port, MISDN_CFG_NEED_MORE_INFOS, &bc->need_more_infos, sizeof(int));
    01656    misdn_cfg_get( port, MISDN_CFG_NTTIMEOUT, &ch->nttimeout, sizeof(int));
    01657
    01658    misdn_cfg_get( port, MISDN_CFG_NOAUTORESPOND_ON_SETUP, &ch->noautorespond_on_setup, sizeof(int));
    01659
    01660    misdn_cfg_get( port, MISDN_CFG_FAR_ALERTING, &ch->far_alerting, sizeof(int));
    01661
    01662    misdn_cfg_get( port, MISDN_CFG_ALLOWED_BEARERS, &ch->allowed_bearers, BUFFERSIZE);
    01663
    01664
    01665    int hdlc=0;
    01666    misdn_cfg_get( port, MISDN_CFG_HDLC, &hdlc, sizeof(int));
    01667
    01668    if (hdlc) {
    01669       switch (bc->capability) {
    01670       case INFO_CAPABILITY_DIGITAL_UNRESTRICTED:
    01671       case INFO_CAPABILITY_DIGITAL_RESTRICTED:
    01672          chan_misdn_log(1,bc->port," --> CONF HDLC\n");
    01673          bc->hdlc=1;
    01674          break;
    01675       }
    01676
    01677    }
    01678    /*Initialize new Jitterbuffer*/
    01679    {
    01680       misdn_cfg_get( port, MISDN_CFG_JITTERBUFFER, &ch->jb_len, sizeof(int));
    01681       misdn_cfg_get( port, MISDN_CFG_JITTERBUFFER_UPPER_THRESHOLD, &ch->jb_upper_threshold, sizeof(int));
    01682
    01683       config_jitterbuffer(ch);
    01684    }
    01685
    01686    misdn_cfg_get( bc->port, MISDN_CFG_CONTEXT, ch->context, sizeof(ch->context));
    01687
    01688    ast_copy_string (ast->context,ch->context,sizeof(ast->context));
    01689
    01690 #ifdef MISDN_1_2
    01691    update_pipeline_config(bc);
    01692 #else
    01693    update_ec_config(bc);
    01694 #endif
    01695
    01696    {
    01697       int eb3;
    01698
    01699       misdn_cfg_get( bc->port, MISDN_CFG_EARLY_BCONNECT, &eb3, sizeof(int));
    01700       bc->early_bconnect=eb3;
    01701    }
    01702
    01703    port=bc->port;
    01704
    01705    {
    01706       char buf[256];
    01707       ast_group_t pg,cg;
    01708
    01709       misdn_cfg_get(port, MISDN_CFG_PICKUPGROUP, &pg, sizeof(pg));
    01710       misdn_cfg_get(port, MISDN_CFG_CALLGROUP, &cg, sizeof(cg));
    01711
    01712       chan_misdn_log(5, port, " --> * CallGrp:%s PickupGrp:%s\n",ast_print_group(buf,sizeof(buf),cg),ast_print_group(buf,sizeof(buf),pg));
    01713       ast->pickupgroup=pg;
    01714       ast->callgroup=cg;
    01715    }
    01716
    01717    if ( orig  == ORG_AST) {
    01718       misdn_cfg_get( port, MISDN_CFG_TE_CHOOSE_CHANNEL, &(bc->te_choose_channel), sizeof(int));
    01719
    01720       {
    01721          char callerid[BUFFERSIZE+1];
    01722          misdn_cfg_get( port, MISDN_CFG_CALLERID, callerid, BUFFERSIZE);
    01723          if ( ! ast_strlen_zero(callerid) ) {
    01724             chan_misdn_log(1, port, " --> * Setting Cid to %s\n", callerid);
    01725             {
    01726                int l = sizeof(bc->oad);
    01727                strncpy(bc->oad,callerid, l);
    01728                bc->oad[l-1] = 0;
    01729             }
    01730
    01731          }
    01732
    01733
    01734          misdn_cfg_get( port, MISDN_CFG_DIALPLAN, &bc->dnumplan, sizeof(int));
    01735          misdn_cfg_get( port, MISDN_CFG_LOCALDIALPLAN, &bc->onumplan, sizeof(int));
    01736          misdn_cfg_get( port, MISDN_CFG_CPNDIALPLAN, &bc->cpnnumplan, sizeof(int));
    01737          debug_numplan(port, bc->dnumplan,"TON");
    01738          debug_numplan(port, bc->onumplan,"LTON");
    01739          debug_numplan(port, bc->cpnnumplan,"CTON");
    01740       }
    01741
    01742       ch->overlap_dial = 0;
    01743    } else { /** ORIGINATOR MISDN **/
    01744
    01745       misdn_cfg_get( port, MISDN_CFG_CPNDIALPLAN, &bc->cpnnumplan, sizeof(int));
    01746       debug_numplan(port, bc->cpnnumplan,"CTON");
    01747
    01748       char prefix[BUFFERSIZE+1]="";
    01749       switch( bc->onumplan ) {
    01750       case NUMPLAN_INTERNATIONAL:
    01751          misdn_cfg_get( bc->port, MISDN_CFG_INTERNATPREFIX, prefix, BUFFERSIZE);
    01752          break;
    01753
    01754       case NUMPLAN_NATIONAL:
    01755          misdn_cfg_get( bc->port, MISDN_CFG_NATPREFIX, prefix, BUFFERSIZE);
    01756          break;
    01757       default:
    01758          break;
    01759       }
    01760
    01761       {
    01762          int l = strlen(prefix) + strlen(bc->oad);
    01763          char tmp[l+1];
    01764          strcpy(tmp,prefix);
    01765          strcat(tmp,bc->oad);
    01766          strcpy(bc->oad,tmp);
    01767       }
    01768
    01769       if (!ast_strlen_zero(bc->dad)) {
    01770          ast_copy_string(bc->orig_dad,bc->dad, sizeof(bc->orig_dad));
    01771       }
    01772
    01773       if ( ast_strlen_zero(bc->dad) && !ast_strlen_zero(bc->keypad)) {
    01774          ast_copy_string(bc->dad,bc->keypad, sizeof(bc->dad));
    01775       }
    01776
    01777       prefix[0] = 0;
    01778
    01779       switch( bc->dnumplan ) {
    01780       case NUMPLAN_INTERNATIONAL:
    01781          misdn_cfg_get( bc->port, MISDN_CFG_INTERNATPREFIX, prefix, BUFFERSIZE);
    01782          break;
    01783       case NUMPLAN_NATIONAL:
    01784          misdn_cfg_get( bc->port, MISDN_CFG_NATPREFIX, prefix, BUFFERSIZE);
    01785          break;
    01786       default:
    01787          break;
    01788       }
    01789
    01790       {
    01791          int l = strlen(prefix) + strlen(bc->dad);
    01792          char tmp[l+1];
    01793          strcpy(tmp,prefix);
    01794          strcat(tmp,bc->dad);
    01795          strcpy(bc->dad,tmp);
    01796       }
    01797
    01798       if ( strcmp(bc->dad,ast->exten)) {
    01799          ast_copy_string(ast->exten, bc->dad, sizeof(ast->exten));
    01800       }
    01801
    01802       ast_set_callerid(ast, bc->oad, NULL, bc->oad);
    01803
    01804       if ( !ast_strlen_zero(bc->rad) )
    01805          ast->cid.cid_rdnis=strdup(bc->rad);
    01806
    01807       misdn_cfg_get(bc->port, MISDN_CFG_OVERLAP_DIAL, &ch->overlap_dial, sizeof(ch->overlap_dial));
    01808       ast_mutex_init(&ch->overlap_tv_lock);
    01809    } /* ORIG MISDN END */
    01810
    01811    ch->overlap_dial_task = -1;
    01812
    01813    return 0;
    01814 }

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

Isdn asks us to release channel, pendant to misdn_hangup

Definition at line 3288 of file chan_misdn.c.

References ast_channel::_state, chan_list::ast, AST_CID_P, ast_mutex_destroy(), ast_mutex_lock(), ast_mutex_unlock(), ast_setstate(), AST_STATE_DOWN, AST_STATE_RESERVED, chan_misdn_log(), cl_dequeue_chan(), ast_channel::context, ast_channel::exten, find_chan_by_bc(), free, chan_list::jb, MISDN_ASTERISK_TECH_PVT, MISDN_CLEANING, misdn_get_ch_state(), misdn_jb_destroy(), misdn_tasks_remove(), chan_list::overlap_dial, chan_list::overlap_dial_task, chan_list::overlap_tv_lock, chan_list::pipe, release_lock, and chan_list::state.

Referenced by cb_events(), and misdn_hangup().

    03288                                                     {
    03289    struct ast_channel *ast=NULL;
    03290
    03291    ast_mutex_lock(&release_lock);
    03292    {
    03293       struct chan_list *ch=find_chan_by_bc(cl_te, bc);
    03294       if (!ch)  {
    03295          chan_misdn_log(1, bc->port, "release_chan: Ch not found!\n");
    03296          ast_mutex_unlock(&release_lock);
    03297          return;
    03298       }
    03299
    03300       if (ch->ast) {
    03301          ast=ch->ast;
    03302       }
    03303
    03304       chan_misdn_log(5, bc->port, "release_chan: bc with l3id: %x\n",bc->l3_id);
    03305
    03306       /*releaseing jitterbuffer*/
    03307       if (ch->jb ) {
    03308          misdn_jb_destroy(ch->jb);
    03309          ch->jb=NULL;
    03310       } else {
    03311          if (!bc->nojitter)
    03312             chan_misdn_log(5,bc->port,"Jitterbuffer already destroyed.\n");
    03313       }
    03314
    03315       if (ch->overlap_dial) {
    03316          if (ch->overlap_dial_task != -1) {
    03317             misdn_tasks_remove(ch->overlap_dial_task);
    03318             ch->overlap_dial_task = -1;
    03319          }
    03320          ast_mutex_destroy(&ch->overlap_tv_lock);
    03321       }
    03322       if (ch) {
    03323
    03324          close(ch->pipe[0]);
    03325          close(ch->pipe[1]);
    03326
    03327
    03328          if (ast && MISDN_ASTERISK_TECH_PVT(ast)) {
    03329             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));
    03330             chan_misdn_log(3, bc->port, " --> * State Down\n");
    03331             MISDN_ASTERISK_TECH_PVT(ast)=NULL;
    03332
    03333
    03334             if (ast->_state != AST_STATE_RESERVED) {
    03335                chan_misdn_log(3, bc->port, " --> Setting AST State to down\n");
    03336                ast_setstate(ast, AST_STATE_DOWN);
    03337             }
    03338          }
    03339
    03340          ch->state=MISDN_CLEANING;
    03341          cl_dequeue_chan(&cl_te, ch);
    03342
    03343          free(ch);
    03344       } else {
    03345          /* chan is already cleaned, so exiting  */
    03346       }
    03347    }
    03348
    03349    ast_mutex_unlock(&release_lock);
    03350 }

int reload | ( | void |  | ) |

Reload stuff.

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

Returns:
  The return value is not used.

Definition at line 4717 of file chan_misdn.c.

References reload_config().

    04718 {
    04719    reload_config();
    04720
    04721    return 0;
    04722 }

static void reload_config | ( | void |  | ) | `[static]`

Definition at line 881 of file chan_misdn.c.

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

    00882 {
    00883    int i, cfg_debug;
    00884
    00885    if (!g_config_initialized) {
    00886       ast_log(LOG_WARNING, "chan_misdn is not initialized properly, still reloading ?\n");
    00887       return ;
    00888    }
    00889
    00890    free_robin_list();
    00891    misdn_cfg_reload();
    00892    misdn_cfg_update_ptp();
    00893    misdn_cfg_get( 0, MISDN_GEN_TRACEFILE, global_tracefile, BUFFERSIZE);
    00894    misdn_cfg_get( 0, MISDN_GEN_DEBUG, &cfg_debug, sizeof(int));
    00895
    00896    for (i = 0;  i <= max_ports; i++) {
    00897       misdn_debug[i] = cfg_debug;
    00898       misdn_debug_only[i] = 0;
    00899    }
    00900 }

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

Congestion Cases

Definition at line 3430 of file chan_misdn.c.

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

Referenced by hangup_chan().

    03430                                                                                                     {
    03431    if (!ast) {
    03432       chan_misdn_log(1,0,"send_cause2ast: No Ast\n");
    03433       return;
    03434    }
    03435    if (!bc) {
    03436       chan_misdn_log(1,0,"send_cause2ast: No BC\n");
    03437       return;
    03438    }
    03439    if (!ch) {
    03440       chan_misdn_log(1,0,"send_cause2ast: No Ch\n");
    03441       return;
    03442    }
    03443
    03444    ast->hangupcause=bc->cause;
    03445
    03446    switch ( bc->cause) {
    03447
    03448    case 1: /** Congestion Cases **/
    03449    case 2:
    03450    case 3:
    03451    case 4:
    03452    case 22:
    03453    case 27:
    03454       /*
    03455        * Not Queueing the Congestion anymore, since we want to hear
    03456        * the inband message
    03457        *
    03458       chan_misdn_log(1, bc?bc->port:0, " --> * SEND: Queue Congestion pid:%d\n", bc?bc->pid:-1);
    03459       ch->state=MISDN_BUSY;
    03460
    03461       ast_queue_control(ast, AST_CONTROL_CONGESTION);
    03462       */
    03463       break;
    03464
    03465    case 21:
    03466    case 17: /* user busy */
    03467
    03468       ch->state=MISDN_BUSY;
    03469
    03470       if (!ch->need_busy) {
    03471          chan_misdn_log(1,bc?bc->port:0, "Queued busy already\n");
    03472          break;
    03473       }
    03474
    03475       chan_misdn_log(1,  bc?bc->port:0, " --> * SEND: Queue Busy pid:%d\n", bc?bc->pid:-1);
    03476
    03477       ast_queue_control(ast, AST_CONTROL_BUSY);
    03478
    03479       ch->need_busy=0;
    03480
    03481       break;
    03482    }
    03483 }

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

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

    00595 {
    00596    static const char* dtmf_tones[] = {
    00597       "!941+1336/100,!0/100", /* 0 */
    00598       "!697+1209/100,!0/100", /* 1 */
    00599       "!697+1336/100,!0/100", /* 2 */
    00600       "!697+1477/100,!0/100", /* 3 */
    00601       "!770+1209/100,!0/100", /* 4 */
    00602       "!770+1336/100,!0/100", /* 5 */
    00603       "!770+1477/100,!0/100", /* 6 */
    00604       "!852+1209/100,!0/100", /* 7 */
    00605       "!852+1336/100,!0/100", /* 8 */
    00606       "!852+1477/100,!0/100", /* 9 */
    00607       "!697+1633/100,!0/100", /* A */
    00608       "!770+1633/100,!0/100", /* B */
    00609       "!852+1633/100,!0/100", /* C */
    00610       "!941+1633/100,!0/100", /* D */
    00611       "!941+1209/100,!0/100", /* * */
    00612       "!941+1477/100,!0/100" };  /* # */
    00613    struct ast_channel *chan=cl->ast;
    00614
    00615    if (digit >= '0' && digit <='9')
    00616       ast_playtones_start(chan,0,dtmf_tones[digit-'0'], 0);
    00617    else if (digit >= 'A' && digit <= 'D')
    00618       ast_playtones_start(chan,0,dtmf_tones[digit-'A'+10], 0);
    00619    else if (digit == '*')
    00620       ast_playtones_start(chan,0,dtmf_tones[14], 0);
    00621    else if (digit == '#')
    00622       ast_playtones_start(chan,0,dtmf_tones[15], 0);
    00623    else {
    00624       /* not handled */
    00625       ast_log(LOG_DEBUG, "Unable to handle DTMF tone '%c' for '%s'\n", digit, chan->name);
    00626
    00627
    00628    }
    00629 }

static void sighandler | ( | int | sig | ) | `[static]`

Definition at line 456 of file chan_misdn.c.

Referenced by misdn_tasks_thread_func().

    00457 {}

static int start_bc_tones | ( | struct chan_list * | cl | ) | `[static]`

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

    02724 {
    02725    misdn_lib_tone_generator_stop(cl->bc);
    02726    cl->notxtone=0;
    02727    cl->norxtone=0;
    02728    return 0;
    02729 }

static void start_pbx | ( | struct chan_list * | ch,
|  | struct misdn_bchannel * | bc,
|  | struct ast_channel * | chan |
| ) |  |  | `[static]`

Definition at line 3536 of file chan_misdn.c.

References chan_misdn_log(), hangup_chan(), hanguptone_indicate(), and pbx_start_chan().

Referenced by cb_events().

    03536                                                                                                  {
    03537    if (pbx_start_chan(ch)<0) {
    03538       hangup_chan(ch);
    03539       chan_misdn_log(-1, bc->port, "ast_pbx_start returned <0 in SETUP\n");
    03540       if (bc->nt) {
    03541          hanguptone_indicate(ch);
    03542          misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE );
    03543       } else
    03544          misdn_lib_send_event(bc, EVENT_RELEASE);
    03545    }
    03546 }

static int stop_bc_tones | ( | struct chan_list * | cl | ) | `[static]`

Definition at line 2731 of file chan_misdn.c.

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

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

    02732 {
    02733    if (!cl) return -1;
    02734
    02735    cl->notxtone=1;
    02736    cl->norxtone=1;
    02737
    02738    return 0;
    02739 }

static int stop_indicate | ( | struct chan_list * | cl | ) | `[static]`

Definition at line 2703 of file chan_misdn.c.

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

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

    02704 {
    02705    struct ast_channel *ast=cl->ast;
    02706
    02707    if (!ast) {
    02708       chan_misdn_log(0,cl->bc->port,"No Ast in stop_indicate\n");
    02709       return -1;
    02710    }
    02711
    02712    chan_misdn_log(3,cl->bc->port," --> None\n");
    02713    misdn_lib_tone_generator_stop(cl->bc);
    02714    ast_playtones_stop(ast);
    02715
    02716    cl->ts=NULL;
    02717    /*ast_deactivate_generator(ast);*/
    02718
    02719    return 0;
    02720 }

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

References ast_channel_unregister(), ast_cli_unregister(), ast_log(), ast_unregister_application(), free, free_robin_list(), g_config_initialized, LOG_VERBOSE, misdn_cfg_destroy(), misdn_debug, misdn_debug_only, and misdn_tasks_destroy().

    04666 {
    04667    /* First, take us out of the channel loop */
    04668    ast_log(LOG_VERBOSE, "-- Unregistering mISDN Channel Driver --\n");
    04669
    04670    misdn_tasks_destroy();
    04671
    04672    if (!g_config_initialized) return 0;
    04673
    04674    ast_cli_unregister(&cli_send_display);
    04675
    04676    ast_cli_unregister(&cli_send_cd);
    04677    ast_cli_unregister(&cli_send_restart);
    04678
    04679    ast_cli_unregister(&cli_send_digit);
    04680    ast_cli_unregister(&cli_toggle_echocancel);
    04681    ast_cli_unregister(&cli_set_tics);
    04682
    04683    ast_cli_unregister(&cli_show_cls);
    04684    ast_cli_unregister(&cli_show_cl);
    04685    ast_cli_unregister(&cli_show_config);
    04686    ast_cli_unregister(&cli_show_port);
    04687    ast_cli_unregister(&cli_show_stacks);
    04688    ast_cli_unregister(&cli_port_block);
    04689    ast_cli_unregister(&cli_port_unblock);
    04690    ast_cli_unregister(&cli_restart_port);
    04691    ast_cli_unregister(&cli_restart_pid);
    04692    ast_cli_unregister(&cli_port_up);
    04693    ast_cli_unregister(&cli_port_down);
    04694    ast_cli_unregister(&cli_set_debug);
    04695    ast_cli_unregister(&cli_set_crypt_debug);
    04696    ast_cli_unregister(&cli_reload);
    04697    /* ast_unregister_application("misdn_crypt"); */
    04698    ast_unregister_application("misdn_set_opt");
    04699    ast_unregister_application("misdn_facility");
    04700    ast_unregister_application("misdn_check_l2l1");
    04701
    04702    ast_channel_unregister(&misdn_tech);
    04703
    04704
    04705    free_robin_list();
    04706    misdn_cfg_destroy();
    04707    misdn_lib_destroy();
    04708
    04709    if (misdn_debug)
    04710       free(misdn_debug);
    04711    if (misdn_debug_only)
    04712       free(misdn_debug_only);
    04713
    04714    return 0;
    04715 }

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

Definition at line 1426 of file chan_misdn.c.

References chan_list::ast, ast_log(), AST_PRES_NETWORK_NUMBER, AST_PRES_RESTRICTED, AST_PRES_UNAVAILABLE, AST_PRES_USER_NUMBER_FAILED_SCREEN, AST_PRES_USER_NUMBER_PASSED_SCREEN, AST_PRES_USER_NUMBER_UNSCREENED, chan_list::bc, chan_misdn_log(), ast_channel::cid, ast_callerid::cid_pres, LOG_WARNING, and misdn_cfg_get().

Referenced by misdn_call().

    01427 {
    01428    if (!ch) {
    01429       ast_log(LOG_WARNING, "Cannot configure without chanlist\n");
    01430       return -1;
    01431    }
    01432
    01433    struct ast_channel *ast=ch->ast;
    01434    struct misdn_bchannel *bc=ch->bc;
    01435    if (! ast || ! bc ) {
    01436       ast_log(LOG_WARNING, "Cannot configure without ast || bc\n");
    01437       return -1;
    01438    }
    01439
    01440    int port=bc->port;
    01441
    01442    chan_misdn_log(7,port,"update_config: Getting Config\n");
    01443
    01444    int hdlc=0;
    01445    misdn_cfg_get( port, MISDN_CFG_HDLC, &hdlc, sizeof(int));
    01446
    01447    if (hdlc) {
    01448       switch (bc->capability) {
    01449       case INFO_CAPABILITY_DIGITAL_UNRESTRICTED:
    01450       case INFO_CAPABILITY_DIGITAL_RESTRICTED:
    01451          chan_misdn_log(1,bc->port," --> CONF HDLC\n");
    01452          bc->hdlc=1;
    01453          break;
    01454       }
    01455
    01456    }
    01457
    01458
    01459    int pres, screen;
    01460
    01461    misdn_cfg_get( port, MISDN_CFG_PRES, &pres, sizeof(int));
    01462    misdn_cfg_get( port, MISDN_CFG_SCREEN, &screen, sizeof(int));
    01463    chan_misdn_log(2,port," --> pres: %d screen: %d\n",pres, screen);
    01464
    01465    if ( (pres + screen) < 0 ) {
    01466
    01467       chan_misdn_log(2,port," --> pres: %x\n", ast->cid.cid_pres);
    01468
    01469       switch (ast->cid.cid_pres & 0x60){
    01470
    01471       case AST_PRES_RESTRICTED:
    01472          bc->pres=1;
    01473          chan_misdn_log(2, port, " --> PRES: Restricted (0x1)\n");
    01474          break;
    01475
    01476
    01477       case AST_PRES_UNAVAILABLE:
    01478          bc->pres=2;
    01479          chan_misdn_log(2, port, " --> PRES: Unavailable (0x2)\n");
    01480          break;
    01481
    01482       default:
    01483          bc->pres=0;
    01484          chan_misdn_log(2, port, " --> PRES: Allowed (0x0)\n");
    01485       }
    01486
    01487       switch (ast->cid.cid_pres & 0x3){
    01488
    01489       case AST_PRES_USER_NUMBER_UNSCREENED:
    01490          bc->screen=0;
    01491          chan_misdn_log(2, port, " --> SCREEN: Unscreened (0x0)\n");
    01492          break;
    01493
    01494       case AST_PRES_USER_NUMBER_PASSED_SCREEN:
    01495          bc->screen=1;
    01496          chan_misdn_log(2, port, " --> SCREEN: Passed Screen (0x1)\n");
    01497          break;
    01498       case AST_PRES_USER_NUMBER_FAILED_SCREEN:
    01499          bc->screen=2;
    01500          chan_misdn_log(2, port, " --> SCREEN: Failed Screen (0x2)\n");
    01501          break;
    01502
    01503       case AST_PRES_NETWORK_NUMBER:
    01504          bc->screen=3;
    01505          chan_misdn_log(2, port, " --> SCREEN: Network Nr. (0x3)\n");
    01506          break;
    01507
    01508       default:
    01509          bc->screen=0;
    01510          chan_misdn_log(2, port, " --> SCREEN: Unscreened (0x0)\n");
    01511       }
    01512
    01513
    01514    } else {
    01515       bc->screen=screen;
    01516       bc->pres=pres;
    01517    }
    01518
    01519    return 0;
    01520
    01521 }

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

Definition at line 1602 of file chan_misdn.c.

References misdn_cfg_get().

Referenced by misdn_toggle_echocancel(), and read_config().

    01603 {
    01604    int ec;
    01605    int port=bc->port;
    01606
    01607    misdn_cfg_get( port, MISDN_CFG_ECHOCANCEL, &ec, sizeof(int));
    01608
    01609    if (ec == 1 ) {
    01610       bc->ec_enable=1;
    01611    } else if ( ec > 1 ) {
    01612       bc->ec_enable=1;
    01613       bc->ec_deftaps=ec;
    01614    }
    01615
    01616    return 0;
    01617 }

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

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

    04725 {
    04726    int res;
    04727    ast_mutex_lock(&usecnt_lock);
    04728    res = usecnt;
    04729    ast_mutex_unlock(&usecnt_lock);
    04730    return res;
    04731 }

static void wait_for_digits | ( | struct chan_list * | ch,
|  | struct misdn_bchannel * | bc,
|  | struct ast_channel * | chan |
| ) |  |  | `[static]`

Definition at line 3548 of file chan_misdn.c.

References dialtone_indicate(), MISDN_WAITING4DIGS, and chan_list::state.

Referenced by cb_events().

    03548                                                                                                        {
    03549    ch->state=MISDN_WAITING4DIGS;
    03550    misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE );
    03551    if (bc->nt && !bc->dad[0])
    03552       dialtone_indicate(ch);
    03553 }

## Variable Documentation

struct allowed_bearers allowed_bearers_array[]

Definition at line 382 of file chan_misdn.c.

struct chan_list* cl_te = NULL

Definition at line 315 of file chan_misdn.c.

ast_mutex_t cl_te_lock

Definition at line 316 of file chan_misdn.c.

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

struct ast_cli_entry cli_port_block`[static]`

Definition at line 1350 of file chan_misdn.c.

struct ast_cli_entry cli_port_down`[static]`

Definition at line 1386 of file chan_misdn.c.

struct ast_cli_entry cli_port_unblock`[static]`

Definition at line 1357 of file chan_misdn.c.

struct ast_cli_entry cli_port_up`[static]`

Definition at line 1379 of file chan_misdn.c.

struct ast_cli_entry cli_reload`[static]`

Definition at line 1321 of file chan_misdn.c.

struct ast_cli_entry cli_restart_pid`[static]`

Definition at line 1372 of file chan_misdn.c.

struct ast_cli_entry cli_restart_port`[static]`

Definition at line 1365 of file chan_misdn.c.

struct ast_cli_entry cli_send_cd`[static]`

Definition at line 1270 of file chan_misdn.c.

struct ast_cli_entry cli_send_digit`[static]`

Definition at line 1286 of file chan_misdn.c.

struct ast_cli_entry cli_send_display`[static]`

Definition at line 1304 of file chan_misdn.c.

struct ast_cli_entry cli_send_restart`[static]`

Definition at line 1278 of file chan_misdn.c.

struct ast_cli_entry cli_set_crypt_debug`[static]`

Definition at line 1417 of file chan_misdn.c.

struct ast_cli_entry cli_set_debug`[static]`

Definition at line 1409 of file chan_misdn.c.

struct ast_cli_entry cli_set_tics`[static]`

Definition at line 1328 of file chan_misdn.c.

struct ast_cli_entry cli_show_cl`[static]`

Definition at line 1342 of file chan_misdn.c.

struct ast_cli_entry cli_show_cls`[static]`

Definition at line 1335 of file chan_misdn.c.

struct ast_cli_entry cli_show_config`[static]`

Definition at line 1314 of file chan_misdn.c.

struct ast_cli_entry cli_show_port`[static]`

Definition at line 1402 of file chan_misdn.c.

struct ast_cli_entry cli_show_stacks`[static]`

Definition at line 1395 of file chan_misdn.c.

struct ast_cli_entry cli_toggle_echocancel`[static]`

Definition at line 1296 of file chan_misdn.c.

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

Definition at line 297 of file chan_misdn.c.

struct chan_list dummy_cl

Definition at line 313 of file chan_misdn.c.

int g_config_initialized = 0`[static]`

Definition at line 70 of file chan_misdn.c.

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

unsigned long glob_channel = 0`[static]`

Definition at line 2998 of file chan_misdn.c.

char global_tracefile[BUFFERSIZE+1]

Definition at line 68 of file chan_misdn.c.

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

ast_mutex_t lock

Definition at line 1019 of file chan_misdn.c.

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

int max_ports`[static]`

Definition at line 311 of file chan_misdn.c.

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

int MAXTICS = 8

Definition at line 1020 of file chan_misdn.c.

Referenced by misdn_set_tics().

int* misdn_debug`[static]`

Definition at line 309 of file chan_misdn.c.

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

int* misdn_debug_only`[static]`

Definition at line 310 of file chan_misdn.c.

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

struct sched_context* misdn_tasks = NULL`[static]`

Definition at line 274 of file chan_misdn.c.

pthread_t misdn_tasks_thread`[static]`

Definition at line 275 of file chan_misdn.c.

Referenced by misdn_tasks_destroy(), misdn_tasks_init(), and misdn_tasks_wakeup().

struct ast_channel_tech misdn_tech`[static]`

Definition at line 2962 of file chan_misdn.c.

struct ast_channel_tech misdn_tech_wo_bridge`[static]`

Definition at line 2980 of file chan_misdn.c.

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

Definition at line 298 of file chan_misdn.c.

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

int prefformat = AST_FORMAT_ALAW`[static]`

Definition at line 305 of file chan_misdn.c.

Referenced by misdn_new(), misdn_write(), vpb_new(), and vpb_request().

ast_mutex_t release_lock

Definition at line 106 of file chan_misdn.c.

Referenced by load_module(), and release_chan().

struct robin_list* robin = NULL`[static]`

Definition at line 231 of file chan_misdn.c.

struct state_struct state_array[]`[static]`

Definition at line 838 of file chan_misdn.c.

int tracing = 0`[static]`

Definition at line 300 of file chan_misdn.c.

Referenced by load_module().

int usecnt = 0`[static]`

Definition at line 302 of file chan_misdn.c.

ast_mutex_t usecnt_lock`[static]`

Definition at line 307 of file chan_misdn.c.

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