#include "asterisk.h"
#include <stdio.h>
#include <pthread.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <signal.h>
#include <sys/file.h>
#include <semaphore.h>
#include "asterisk/channel.h"
#include "asterisk/config.h"
#include "asterisk/logger.h"
#include "asterisk/module.h"
#include "asterisk/pbx.h"
#include "asterisk/options.h"
#include "asterisk/io.h"
#include "asterisk/frame.h"
#include "asterisk/translate.h"
#include "asterisk/cli.h"
#include "asterisk/musiconhold.h"
#include "asterisk/dsp.h"
#include "asterisk/file.h"
#include "asterisk/callerid.h"
#include "asterisk/indications.h"
#include "asterisk/app.h"
#include "asterisk/features.h"
#include "asterisk/term.h"
#include "asterisk/sched.h"
#include "asterisk/stringfields.h"
#include "asterisk/causes.h"
#include "asterisk/abstract_jb.h"
#include "chan_misdn_config.h"
#include "isdn_lib.h"
#include "asterisk/strings.h"
Go to the source code of this file.
Data Structures | |
struct | allowed_bearers |
struct | chan_list |
Channel call record structure. More... | |
struct | hold_info |
struct | misdn_jb |
struct | robin_list |
struct | state_struct |
Defines | |
#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 void | __reg_module (void) |
static void | __unreg_module (void) |
static int | _misdn_tasks_add_variable (int timeout, ast_sched_cb callback, const void *data, int variable) |
int | add_in_calls (int port) |
int | add_out_calls (int port) |
static const char * | bearer2str (int cap) |
static enum event_response_e | cb_events (enum event_e event, struct misdn_bchannel *bc, void *user_data) |
int | chan_misdn_jb_empty (struct misdn_bchannel *bc, char *buf, int len) |
static void | chan_misdn_log (int level, int port, char *tmpl,...) |
static void | cl_dequeue_chan (struct chan_list **list, struct chan_list *chan) |
static void | cl_queue_chan (struct chan_list **list, struct chan_list *chan) |
static char * | complete_ch (const char *line, const char *word, int pos, int state) |
static char * | complete_ch_helper (const char *line, const char *word, int pos, int state, int rpos) |
static char * | complete_debug_port (const char *line, const char *word, int pos, int state) |
static char * | complete_show_config (const char *line, const char *word, int pos, int state) |
static void | config_jitterbuffer (struct chan_list *ch) |
void | debug_numplan (int port, int numplan, char *type) |
static int | dialtone_indicate (struct chan_list *cl) |
static void | do_immediate_setup (struct misdn_bchannel *bc, struct chan_list *ch, struct ast_channel *ast) |
static void | export_aoc_vars (int originator, struct ast_channel *ast, struct misdn_bchannel *bc) |
void | export_ch (struct ast_channel *chan, struct misdn_bchannel *bc, struct chan_list *ch) |
Export parameters to the dialplan environment variables. | |
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) |
Import parameters from the dialplan environment variables. | |
static struct chan_list * | init_chan_list (int orig) |
static int | load_module (void) |
static int | misdn_answer (struct ast_channel *ast) |
static enum ast_bridge_result | misdn_bridge (struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc, int timeoutms) |
static int | misdn_call (struct ast_channel *ast, char *dest, int timeout) |
static int | misdn_check_l2l1 (struct ast_channel *chan, void *data) |
static int | misdn_digit_begin (struct ast_channel *chan, char digit) |
static int | misdn_digit_end (struct ast_channel *ast, char digit, unsigned int duration) |
static int | misdn_facility_exec (struct ast_channel *chan, void *data) |
static int | misdn_fixup (struct ast_channel *oldast, struct ast_channel *ast) |
static const char * | misdn_get_ch_state (struct chan_list *p) |
static int | misdn_hangup (struct ast_channel *ast) |
static int | misdn_indication (struct ast_channel *ast, int cond, const void *data, size_t datalen) |
void | misdn_jb_destroy (struct misdn_jb *jb) |
frees the data and destroys the given jitterbuffer struct | |
int | misdn_jb_empty (struct misdn_jb *jb, char *data, int len) |
gets len bytes out of the jitterbuffer if available, else only the available data is returned and the return value indicates the number of data. | |
int | misdn_jb_fill (struct misdn_jb *jb, const char *data, int len) |
fills the jitterbuffer with len data returns < 0 if there was an error (buffer overrun). | |
misdn_jb * | misdn_jb_init (int size, int upper_threshold) |
allocates the jb-structure and initialize the elements | |
static int | misdn_l1_task (const void *data) |
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 (const 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[]) |
static int | misdn_send_text (struct ast_channel *chan, const char *text) |
static int | misdn_set_crypt_debug (int fd, int argc, char *argv[]) |
static int | misdn_set_debug (int fd, int argc, char *argv[]) |
static int | misdn_set_opt_exec (struct ast_channel *chan, void *data) |
static int | misdn_set_tics (int fd, int argc, char *argv[]) |
static int | misdn_show_cl (int fd, int argc, char *argv[]) |
static int | misdn_show_cls (int fd, int argc, char *argv[]) |
static int | misdn_show_config (int fd, int argc, char *argv[]) |
static int | misdn_show_port (int fd, int argc, char *argv[]) |
static int | misdn_show_ports_stats (int fd, int argc, char *argv[]) |
static int | misdn_show_stacks (int fd, int argc, char *argv[]) |
static int | misdn_tasks_add (int timeout, ast_sched_cb callback, const void *data) |
static int | misdn_tasks_add_variable (int timeout, ast_sched_cb callback, const void *data) |
static void | misdn_tasks_destroy (void) |
static void | misdn_tasks_init (void) |
static void | misdn_tasks_remove (int task_id) |
static void * | misdn_tasks_thread_func (void *data) |
static void | misdn_tasks_wakeup (void) |
static int | misdn_toggle_echocancel (int fd, int argc, char *argv[]) |
static void | misdn_transfer_bc (struct chan_list *tmp_ch, struct chan_list *holded_chan) |
static int | misdn_write (struct ast_channel *ast, struct ast_frame *frame) |
static int | pbx_start_chan (struct chan_list *ch) |
static void | print_bc_info (int fd, struct chan_list *help, struct misdn_bchannel *bc) |
static void | print_bearer (struct misdn_bchannel *bc) |
static void | print_facility (struct FacParm *fac, struct misdn_bchannel *bc) |
static struct ast_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) |
static int | reload (void) |
static void | reload_config (void) |
static void | send_cause2ast (struct ast_channel *ast, struct misdn_bchannel *bc, struct chan_list *ch) |
static void | send_digit_to_chan (struct chan_list *cl, char digit) |
static void | show_config_description (int fd, enum misdn_cfg_elements elem) |
static void | sighandler (int sig) |
static int | start_bc_tones (struct chan_list *cl) |
static 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) |
static int | unload_module (void) |
static int | update_config (struct chan_list *ch, int orig) |
Updates caller ID information from config. | |
static int | update_ec_config (struct misdn_bchannel *bc) |
static void | update_name (struct ast_channel *tmp, int port, int c) |
static void | wait_for_digits (struct chan_list *ch, struct misdn_bchannel *bc, struct ast_channel *chan) |
Variables | |
static struct ast_module_info | __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT | AST_MODFLAG_BUILDSUM, .description = "Channel driver for mISDN Support (BRI/PRI)" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "6989f2ec67f8497e38c12890500c525b" , .load = load_module, .unload = unload_module, .reload = reload, } |
static struct allowed_bearers | allowed_bearers_array [] |
static const struct ast_module_info * | ast_module_info = &__mod_info |
static struct ast_cli_entry | chan_misdn_clis [] |
chan_list * | cl_te = NULL |
Global channel call record list head. | |
ast_mutex_t | cl_te_lock |
chan_list | dummy_cl |
static int | g_config_initialized = 0 |
static int | glob_channel = 0 |
char | global_tracefile [BUFFERSIZE+1] |
ast_mutex_t | lock |
static int | max_ports |
int | MAXTICS = 8 |
static int * | misdn_debug |
static int * | misdn_debug_only |
static int * | misdn_in_calls |
static int * | misdn_out_calls |
static int * | misdn_ports |
static struct sched_context * | misdn_tasks = NULL |
the main schedule context for stuff like l1 watcher, overlap dial, ... | |
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 |
Only alaw and mulaw is allowed for now. | |
ast_mutex_t | release_lock |
static struct robin_list * | robin = NULL |
static struct state_struct | state_array [] |
static int | tracing = 0 |
Definition in file chan_misdn.c.
#define MISDN_ASTERISK_PVT | ( | ast | ) | 1 |
#define MISDN_ASTERISK_TECH_PVT | ( | ast | ) | ast->tech_pvt |
Definition at line 492 of file chan_misdn.c.
Referenced by cb_events(), do_immediate_setup(), misdn_answer(), misdn_call(), misdn_digit_end(), misdn_facility_exec(), misdn_fixup(), misdn_hangup(), misdn_indication(), misdn_read(), misdn_set_opt_exec(), misdn_write(), and release_chan().
#define ORG_AST 1 |
Definition at line 147 of file chan_misdn.c.
Referenced by cb_events(), export_aoc_vars(), misdn_call(), misdn_hangup(), misdn_request(), print_bc_info(), read_config(), and release_chan().
#define ORG_MISDN 2 |
enum misdn_chan_state |
Definition at line 122 of file chan_misdn.c.
00122 { 00123 MISDN_NOTHING=0, /*!< at beginning */ 00124 MISDN_WAITING4DIGS, /*!< when waiting for infos */ 00125 MISDN_EXTCANTMATCH, /*!< when asterisk couldn't match our ext */ 00126 MISDN_INCOMING_SETUP, /*!< for incoming setups*/ 00127 MISDN_DIALING, /*!< when pbx_start */ 00128 MISDN_PROGRESS, /*!< we got a progress */ 00129 MISDN_PROCEEDING, /*!< we got a progress */ 00130 MISDN_CALLING, /*!< when misdn_call is called */ 00131 MISDN_CALLING_ACKNOWLEDGE, /*!< when we get SETUP_ACK */ 00132 MISDN_ALERTING, /*!< when Alerting */ 00133 MISDN_BUSY, /*!< when BUSY */ 00134 MISDN_CONNECTED, /*!< when connected */ 00135 MISDN_PRECONNECTED, /*!< when connected */ 00136 MISDN_DISCONNECTED, /*!< when connected */ 00137 MISDN_RELEASED, /*!< when connected */ 00138 MISDN_BRIDGED, /*!< when bridged */ 00139 MISDN_CLEANING, /*!< when hangup from * but we were connected before */ 00140 MISDN_HUNGUP_FROM_MISDN, /*!< when DISCONNECT/RELEASE/REL_COMP came from misdn */ 00141 MISDN_HUNGUP_FROM_AST, /*!< when DISCONNECT/RELEASE/REL_COMP came out of misdn_hangup */ 00142 MISDN_HOLDED, /*!< if this chan is holded */ 00143 MISDN_HOLD_DISCONNECT, /*!< if this chan is holded */ 00144 00145 };
static void __reg_module | ( | void | ) | [static] |
Definition at line 5781 of file chan_misdn.c.
static void __unreg_module | ( | void | ) | [static] |
Definition at line 5781 of file chan_misdn.c.
static int _misdn_tasks_add_variable | ( | int | timeout, | |
ast_sched_cb | callback, | |||
const void * | data, | |||
int | variable | |||
) | [inline, static] |
Definition at line 797 of file chan_misdn.c.
References ast_sched_add_variable(), misdn_tasks, misdn_tasks_init(), and misdn_tasks_wakeup().
Referenced by misdn_tasks_add(), and misdn_tasks_add_variable().
00798 { 00799 int task_id; 00800 00801 if (!misdn_tasks) { 00802 misdn_tasks_init(); 00803 } 00804 task_id = ast_sched_add_variable(misdn_tasks, timeout, callback, data, variable); 00805 misdn_tasks_wakeup(); 00806 00807 return task_id; 00808 }
int add_in_calls | ( | int | port | ) |
Definition at line 3939 of file chan_misdn.c.
References ast_log(), LOG_NOTICE, misdn_cfg_get(), MISDN_CFG_MAX_IN, and misdn_in_calls.
Referenced by cb_events().
03940 { 03941 int max_in_calls; 03942 03943 misdn_cfg_get(port, MISDN_CFG_MAX_IN, &max_in_calls, sizeof(max_in_calls)); 03944 misdn_in_calls[port]++; 03945 03946 if (max_in_calls >= 0 && max_in_calls < misdn_in_calls[port]) { 03947 ast_log(LOG_NOTICE, "Marking Incoming Call on port[%d]\n", port); 03948 return misdn_in_calls[port] - max_in_calls; 03949 } 03950 03951 return 0; 03952 }
int add_out_calls | ( | int | port | ) |
Definition at line 3954 of file chan_misdn.c.
References ast_log(), LOG_NOTICE, misdn_cfg_get(), MISDN_CFG_MAX_OUT, and misdn_out_calls.
Referenced by misdn_call().
03955 { 03956 int max_out_calls; 03957 03958 misdn_cfg_get(port, MISDN_CFG_MAX_OUT, &max_out_calls, sizeof(max_out_calls)); 03959 03960 if (max_out_calls >= 0 && max_out_calls <= misdn_out_calls[port]) { 03961 ast_log(LOG_NOTICE, "Rejecting Outgoing Call on port[%d]\n", port); 03962 return (misdn_out_calls[port] + 1) - max_out_calls; 03963 } 03964 03965 misdn_out_calls[port]++; 03966 03967 return 0; 03968 }
static const char* bearer2str | ( | int | cap | ) | [static] |
Definition at line 609 of file chan_misdn.c.
References allowed_bearers_array, ARRAY_LEN, and allowed_bearers::display.
Referenced by cb_events(), misdn_lib_log_ies(), print_bc_info(), and print_bearer().
00610 { 00611 unsigned index; 00612 00613 for (index = 0; index < ARRAY_LEN(allowed_bearers_array); ++index) { 00614 if (allowed_bearers_array[index].cap == cap) { 00615 return allowed_bearers_array[index].display; 00616 } 00617 } /* end for */ 00618 00619 return "Unknown Bearer"; 00620 }
static enum event_response_e cb_events | ( | enum event_e | event, | |
struct misdn_bchannel * | bc, | |||
void * | user_data | |||
) | [static] |
Definition at line 3994 of file chan_misdn.c.
References add_in_calls(), misdn_bchannel::addr, chan_list::addr, chan_list::allowed_bearers, allowed_bearers_array, misdn_bchannel::AOCD, misdn_bchannel::AOCDtype, ARRAY_LEN, chan_list::ast, ast_bridged_channel(), ast_canmatch_extension(), AST_CAUSE_DESTINATION_OUT_OF_ORDER, AST_CAUSE_INCOMPATIBLE_DESTINATION, AST_CAUSE_NORMAL_CLEARING, AST_CAUSE_UNALLOCATED, AST_CAUSE_USER_BUSY, ast_cdr_update(), AST_CONTROL_ANSWER, AST_CONTROL_BUSY, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_RINGING, ast_copy_string(), 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(), ast_tv(), ast_tvnow(), chan_list::bc, misdn_bchannel::bc_state, bc_state2str(), bearer2str(), misdn_bchannel::bframe, misdn_bchannel::bframe_len, misdn_bchannel::cad, misdn_bchannel::capability, misdn_bchannel::cause, cb_log, chan_misdn_log(), hold_info::channel, misdn_bchannel::channel, misdn_bchannel::chargingUnit, ast_channel::cid, ast_callerid::cid_pres, cl_queue_chan(), cl_te, chan_list::context, misdn_bchannel::cpnnumplan, misdn_bchannel::currency, misdn_bchannel::cw, misdn_bchannel::dad, ast_frame::data, ast_frame::datalen, ast_frame::delivery, do_immediate_setup(), misdn_bchannel::dtmf, misdn_bchannel::dummy, errno, EVENT_ALERTING, EVENT_BCHAN_ACTIVATED, EVENT_BCHAN_DATA, EVENT_BCHAN_ERROR, EVENT_CLEANUP, EVENT_CONNECT, EVENT_CONNECT_ACKNOWLEDGE, EVENT_DISCONNECT, EVENT_DTMF_TONE, EVENT_FACILITY, EVENT_HOLD, EVENT_HOLD_ACKNOWLEDGE, EVENT_HOLD_REJECT, EVENT_INFORMATION, EVENT_NEW_BC, EVENT_NEW_CHANNEL, EVENT_NEW_L3ID, EVENT_PORT_ALARM, EVENT_PROCEEDING, EVENT_PROGRESS, EVENT_RELEASE, EVENT_RELEASE_COMPLETE, EVENT_RESTART, EVENT_RETRIEVE, EVENT_RETRIEVE_ACKNOWLEDGE, EVENT_RETRIEVE_REJECT, EVENT_SETUP, EVENT_SETUP_ACKNOWLEDGE, EVENT_STATUS, EVENT_TIMEOUT, EVENT_TONE_GENERATE, export_aoc_vars(), export_ch(), ast_channel::exten, misdn_bchannel::fac_in, 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, INFO_CAPABILITY_DIGITAL_UNRESTRICTED, misdn_bchannel::info_dad, INFO_PI_INBAND_AVAILABLE, misdn_bchannel::infos_pending, init_chan_list(), misdn_bchannel::keypad, misdn_bchannel::l3_id, chan_list::l3id, LOG_ERROR, LOG_NOTICE, LOG_WARNING, ast_frame::mallocd, manager_isdn_get_info(), MISDN_ALERTING, MISDN_ASTERISK_PVT, MISDN_ASTERISK_TECH_PVT, MISDN_CALLING, MISDN_CALLING_ACKNOWLEDGE, misdn_cap_is_speech(), MISDN_CFG_ALARM_BLOCK, MISDN_CFG_ALWAYS_IMMEDIATE, misdn_cfg_get(), MISDN_CFG_HOLD_ALLOWED, MISDN_CFG_IMMEDIATE, misdn_cfg_is_msn_valid(), MISDN_CFG_REJECT_CAUSE, MISDN_CLEANING, MISDN_CONNECTED, MISDN_DIALING, MISDN_DISCONNECTED, MISDN_EXTCANTMATCH, MISDN_GEN_APPEND_DIGITS2EXTEN, misdn_get_ch_state(), MISDN_HOLDED, misdn_inband_avail(), MISDN_INCOMING_SETUP, misdn_lib_is_ptp(), misdn_lib_log_ies(), misdn_lib_port_block(), misdn_lib_send_event(), 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, misdn_bchannel::need_disconnect, misdn_bchannel::need_more_infos, misdn_bchannel::need_release, misdn_bchannel::need_release_complete, chan_list::noautorespond_on_setup, misdn_bchannel::nt, chan_list::nttimeout, misdn_bchannel::oad, ast_frame::offset, ORG_AST, ORG_MISDN, chan_list::originator, misdn_bchannel::out_cause, chan_list::overlap_dial, chan_list::overlap_dial_task, chan_list::overlap_tv, chan_list::overlap_tv_lock, pbx_builtin_setvar_helper(), pbx_start_chan(), misdn_bchannel::pid, chan_list::pipe, hold_info::port, misdn_bchannel::port, misdn_bchannel::pres, print_bearer(), print_facility(), misdn_bchannel::progress_indicator, read_config(), release_chan(), RESPONSE_IGNORE_SETUP, RESPONSE_IGNORE_SETUP_WITHOUT_CLOSE, RESPONSE_OK, RESPONSE_RELEASE_SETUP, ast_channel::rings, ast_frame::samples, misdn_bchannel::screen, misdn_bchannel::sending_complete, ast_frame::src, start_bc_tones(), start_pbx(), chan_list::state, stop_bc_tones(), stop_indicate(), ast_frame::subclass, t, ast_channel::tech, misdn_bchannel::tone_cnt, ast_channel::transfercapability, ast_channel_tech::type, update_name(), and wait_for_digits().
Referenced by load_module().
03995 { 03996 int msn_valid; 03997 struct chan_list *ch = find_chan_by_bc(cl_te, bc); 03998 03999 if (event != EVENT_BCHAN_DATA && event != EVENT_TONE_GENERATE) { /* Debug Only Non-Bchan */ 04000 int debuglevel = 1; 04001 if ( event == EVENT_CLEANUP && !user_data) 04002 debuglevel = 5; 04003 04004 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"); 04005 if (debuglevel == 1) { 04006 misdn_lib_log_ies(bc); 04007 chan_misdn_log(4, bc->port, " --> bc_state:%s\n", bc_state2str(bc->bc_state)); 04008 } 04009 } 04010 04011 if (!ch) { 04012 switch(event) { 04013 case EVENT_SETUP: 04014 case EVENT_DISCONNECT: 04015 case EVENT_PORT_ALARM: 04016 case EVENT_RETRIEVE: 04017 case EVENT_NEW_BC: 04018 case EVENT_FACILITY: 04019 break; 04020 case EVENT_RELEASE_COMPLETE: 04021 chan_misdn_log(1, bc->port, " --> no Ch, so we've already released.\n"); 04022 break; 04023 case EVENT_CLEANUP: 04024 case EVENT_TONE_GENERATE: 04025 case EVENT_BCHAN_DATA: 04026 return -1; 04027 default: 04028 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); 04029 return -1; 04030 } 04031 } 04032 04033 if (ch) { 04034 switch (event) { 04035 case EVENT_TONE_GENERATE: 04036 break; 04037 case EVENT_DISCONNECT: 04038 case EVENT_RELEASE: 04039 case EVENT_RELEASE_COMPLETE: 04040 case EVENT_CLEANUP: 04041 case EVENT_TIMEOUT: 04042 if (!ch->ast) 04043 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)); 04044 break; 04045 default: 04046 if (!ch->ast || !MISDN_ASTERISK_PVT(ch->ast) || !MISDN_ASTERISK_TECH_PVT(ch->ast)) { 04047 if (event != EVENT_BCHAN_DATA) 04048 ast_log(LOG_NOTICE, "No Ast or No private Pointer in Event (%d:%s)\n", event, manager_isdn_get_info(event)); 04049 return -1; 04050 } 04051 } 04052 } 04053 04054 04055 switch (event) { 04056 case EVENT_PORT_ALARM: 04057 { 04058 int boa = 0; 04059 misdn_cfg_get(bc->port, MISDN_CFG_ALARM_BLOCK, &boa, sizeof(int)); 04060 if (boa) { 04061 cb_log(1, bc->port, " --> blocking\n"); 04062 misdn_lib_port_block(bc->port); 04063 } 04064 } 04065 break; 04066 case EVENT_BCHAN_ACTIVATED: 04067 break; 04068 04069 case EVENT_NEW_CHANNEL: 04070 update_name(ch->ast,bc->port,bc->channel); 04071 break; 04072 04073 case EVENT_NEW_L3ID: 04074 ch->l3id=bc->l3_id; 04075 ch->addr=bc->addr; 04076 break; 04077 04078 case EVENT_NEW_BC: 04079 if (!ch) { 04080 ch = find_holded(cl_te,bc); 04081 } 04082 04083 if (!ch) { 04084 ast_log(LOG_WARNING, "NEW_BC without chan_list?\n"); 04085 break; 04086 } 04087 04088 if (bc) 04089 ch->bc = (struct misdn_bchannel *)user_data; 04090 break; 04091 04092 case EVENT_DTMF_TONE: 04093 { 04094 /* sending INFOS as DTMF-Frames :) */ 04095 struct ast_frame fr; 04096 04097 memset(&fr, 0, sizeof(fr)); 04098 fr.frametype = AST_FRAME_DTMF; 04099 fr.subclass = bc->dtmf ; 04100 fr.src = NULL; 04101 fr.data = NULL; 04102 fr.datalen = 0; 04103 fr.samples = 0; 04104 fr.mallocd = 0; 04105 fr.offset = 0; 04106 fr.delivery = ast_tv(0,0); 04107 04108 if (!ch->ignore_dtmf) { 04109 chan_misdn_log(2, bc->port, " --> DTMF:%c\n", bc->dtmf); 04110 ast_queue_frame(ch->ast, &fr); 04111 } else { 04112 chan_misdn_log(2, bc->port, " --> Ignoring DTMF:%c due to bridge flags\n", bc->dtmf); 04113 } 04114 } 04115 break; 04116 case EVENT_STATUS: 04117 break; 04118 04119 case EVENT_INFORMATION: 04120 { 04121 if ( ch->state != MISDN_CONNECTED ) 04122 stop_indicate(ch); 04123 04124 if (!ch->ast) 04125 break; 04126 04127 if (ch->state == MISDN_WAITING4DIGS ) { 04128 /* Ok, incomplete Setup, waiting till extension exists */ 04129 if (ast_strlen_zero(bc->info_dad) && ! ast_strlen_zero(bc->keypad)) { 04130 chan_misdn_log(1, bc->port, " --> using keypad as info\n"); 04131 ast_copy_string(bc->info_dad, bc->keypad, sizeof(bc->info_dad)); 04132 } 04133 04134 strncat(bc->dad, bc->info_dad, sizeof(bc->dad) - strlen(bc->dad) - 1); 04135 ast_copy_string(ch->ast->exten, bc->dad, sizeof(ch->ast->exten)); 04136 04137 /* Check for Pickup Request first */ 04138 if (!strcmp(ch->ast->exten, ast_pickup_ext())) { 04139 if (ast_pickup_call(ch->ast)) { 04140 hangup_chan(ch); 04141 } else { 04142 struct ast_channel *chan = ch->ast; 04143 ch->state = MISDN_CALLING_ACKNOWLEDGE; 04144 ast_setstate(chan, AST_STATE_DOWN); 04145 hangup_chan(ch); 04146 ch->ast = NULL; 04147 break; 04148 } 04149 } 04150 04151 if (!ast_canmatch_extension(ch->ast, ch->context, bc->dad, 1, bc->oad)) { 04152 if (ast_exists_extension(ch->ast, ch->context, "i", 1, bc->oad)) { 04153 ast_log(LOG_WARNING, 04154 "Extension '%s@%s' can never match. Jumping to 'i' extension. port:%d\n", 04155 bc->dad, ch->context, bc->port); 04156 strcpy(ch->ast->exten, "i"); 04157 04158 ch->state = MISDN_DIALING; 04159 start_pbx(ch, bc, ch->ast); 04160 break; 04161 } 04162 04163 ast_log(LOG_WARNING, 04164 "Extension '%s@%s' can never match. Disconnecting. port:%d\n" 04165 "\tMaybe you want to add an 'i' extension to catch this case.\n", 04166 bc->dad, ch->context, bc->port); 04167 04168 if (bc->nt) 04169 hanguptone_indicate(ch); 04170 ch->state = MISDN_EXTCANTMATCH; 04171 bc->out_cause = AST_CAUSE_UNALLOCATED; 04172 04173 misdn_lib_send_event(bc, EVENT_DISCONNECT); 04174 break; 04175 } 04176 04177 if (ch->overlap_dial) { 04178 ast_mutex_lock(&ch->overlap_tv_lock); 04179 ch->overlap_tv = ast_tvnow(); 04180 ast_mutex_unlock(&ch->overlap_tv_lock); 04181 if (ch->overlap_dial_task == -1) { 04182 ch->overlap_dial_task = 04183 misdn_tasks_add_variable(ch->overlap_dial, misdn_overlap_dial_task, ch); 04184 } 04185 break; 04186 } 04187 04188 if (ast_exists_extension(ch->ast, ch->context, bc->dad, 1, bc->oad)) { 04189 04190 ch->state = MISDN_DIALING; 04191 start_pbx(ch, bc, ch->ast); 04192 } 04193 } else { 04194 /* sending INFOS as DTMF-Frames :) */ 04195 struct ast_frame fr; 04196 int digits; 04197 04198 memset(&fr, 0, sizeof(fr)); 04199 fr.frametype = AST_FRAME_DTMF; 04200 fr.subclass = bc->info_dad[0] ; 04201 fr.src = NULL; 04202 fr.data = NULL; 04203 fr.datalen = 0; 04204 fr.samples = 0; 04205 fr.mallocd = 0; 04206 fr.offset = 0; 04207 fr.delivery = ast_tv(0,0); 04208 04209 misdn_cfg_get(0, MISDN_GEN_APPEND_DIGITS2EXTEN, &digits, sizeof(int)); 04210 if (ch->state != MISDN_CONNECTED ) { 04211 if (digits) { 04212 strncat(bc->dad, bc->info_dad, sizeof(bc->dad) - strlen(bc->dad) - 1); 04213 ast_copy_string(ch->ast->exten, bc->dad, sizeof(ch->ast->exten)); 04214 ast_cdr_update(ch->ast); 04215 } 04216 04217 ast_queue_frame(ch->ast, &fr); 04218 } 04219 } 04220 } 04221 break; 04222 case EVENT_SETUP: 04223 { 04224 struct chan_list *ch = find_chan_by_bc(cl_te, bc); 04225 struct ast_channel *chan; 04226 int exceed; 04227 int pres, screen; 04228 int ai; 04229 int im; 04230 04231 if (ch) { 04232 switch (ch->state) { 04233 case MISDN_NOTHING: 04234 ch = NULL; 04235 break; 04236 default: 04237 chan_misdn_log(1, bc->port, " --> Ignoring Call we have already one\n"); 04238 return RESPONSE_IGNORE_SETUP_WITHOUT_CLOSE; /* Ignore MSNs which are not in our List */ 04239 } 04240 } 04241 04242 msn_valid = misdn_cfg_is_msn_valid(bc->port, bc->dad); 04243 if (!bc->nt && ! msn_valid) { 04244 chan_misdn_log(1, bc->port, " --> Ignoring Call, its not in our MSN List\n"); 04245 return RESPONSE_IGNORE_SETUP; /* Ignore MSNs which are not in our List */ 04246 } 04247 04248 if (bc->cw) { 04249 int cause; 04250 chan_misdn_log(0, bc->port, " --> Call Waiting on PMP sending RELEASE_COMPLETE\n"); 04251 misdn_cfg_get(bc->port, MISDN_CFG_REJECT_CAUSE, &cause, sizeof(cause)); 04252 bc->out_cause = cause ? cause : AST_CAUSE_NORMAL_CLEARING; 04253 return RESPONSE_RELEASE_SETUP; 04254 } 04255 04256 print_bearer(bc); 04257 04258 ch = init_chan_list(ORG_MISDN); 04259 04260 if (!ch) { 04261 chan_misdn_log(-1, bc->port, "cb_events: malloc for chan_list failed!\n"); 04262 return 0; 04263 } 04264 04265 ch->bc = bc; 04266 ch->l3id = bc->l3_id; 04267 ch->addr = bc->addr; 04268 ch->originator = ORG_MISDN; 04269 04270 chan = misdn_new(ch, AST_STATE_RESERVED, bc->dad, bc->oad, AST_FORMAT_ALAW, bc->port, bc->channel); 04271 if (!chan) { 04272 misdn_lib_send_event(bc,EVENT_RELEASE_COMPLETE); 04273 ast_log(LOG_ERROR, "cb_events: misdn_new failed !\n"); 04274 return 0; 04275 } 04276 04277 ch->ast = chan; 04278 04279 if ((exceed = add_in_calls(bc->port))) { 04280 char tmp[16]; 04281 snprintf(tmp, sizeof(tmp), "%d", exceed); 04282 pbx_builtin_setvar_helper(chan, "MAX_OVERFLOW", tmp); 04283 } 04284 04285 read_config(ch, ORG_MISDN); 04286 04287 export_ch(chan, bc, ch); 04288 04289 ch->ast->rings = 1; 04290 ast_setstate(ch->ast, AST_STATE_RINGING); 04291 04292 switch (bc->pres) { 04293 case 1: 04294 pres = AST_PRES_RESTRICTED; 04295 chan_misdn_log(2, bc->port, " --> PRES: Restricted (1)\n"); 04296 break; 04297 case 2: 04298 pres = AST_PRES_UNAVAILABLE; 04299 chan_misdn_log(2, bc->port, " --> PRES: Unavailable (2)\n"); 04300 break; 04301 default: 04302 pres = AST_PRES_ALLOWED; 04303 chan_misdn_log(2, bc->port, " --> PRES: Allowed (%d)\n", bc->pres); 04304 break; 04305 } 04306 04307 switch (bc->screen) { 04308 default: 04309 case 0: 04310 screen = AST_PRES_USER_NUMBER_UNSCREENED; 04311 chan_misdn_log(2, bc->port, " --> SCREEN: Unscreened (%d)\n", bc->screen); 04312 break; 04313 case 1: 04314 screen = AST_PRES_USER_NUMBER_PASSED_SCREEN; 04315 chan_misdn_log(2, bc->port, " --> SCREEN: Passed screen (1)\n"); 04316 break; 04317 case 2: 04318 screen = AST_PRES_USER_NUMBER_FAILED_SCREEN; 04319 chan_misdn_log(2, bc->port, " --> SCREEN: failed screen (2)\n"); 04320 break; 04321 case 3: 04322 screen = AST_PRES_NETWORK_NUMBER; 04323 chan_misdn_log(2, bc->port, " --> SCREEN: Network Number (3)\n"); 04324 break; 04325 } 04326 04327 chan->cid.cid_pres = pres | screen; 04328 04329 pbx_builtin_setvar_helper(chan, "TRANSFERCAPABILITY", ast_transfercapability2str(bc->capability)); 04330 chan->transfercapability = bc->capability; 04331 04332 switch (bc->capability) { 04333 case INFO_CAPABILITY_DIGITAL_UNRESTRICTED: 04334 pbx_builtin_setvar_helper(chan, "CALLTYPE", "DIGITAL"); 04335 break; 04336 default: 04337 pbx_builtin_setvar_helper(chan, "CALLTYPE", "SPEECH"); 04338 } 04339 04340 /** queue new chan **/ 04341 cl_queue_chan(&cl_te, ch); 04342 04343 if (!strstr(ch->allowed_bearers, "all")) { 04344 int i; 04345 04346 for (i = 0; i < ARRAY_LEN(allowed_bearers_array); ++i) { 04347 if (allowed_bearers_array[i].cap == bc->capability) { 04348 if (strstr(ch->allowed_bearers, allowed_bearers_array[i].name)) { 04349 /* The bearer capability is allowed */ 04350 if (allowed_bearers_array[i].deprecated) { 04351 chan_misdn_log(0, bc->port, "%s in allowed_bearers list is deprecated\n", 04352 allowed_bearers_array[i].name); 04353 } 04354 break; 04355 } 04356 } 04357 } /* end for */ 04358 if (i == ARRAY_LEN(allowed_bearers_array)) { 04359 /* We did not find the bearer capability */ 04360 chan_misdn_log(0, bc->port, "Bearer capability not allowed: %s(%d)\n", 04361 bearer2str(bc->capability), bc->capability); 04362 bc->out_cause = AST_CAUSE_INCOMPATIBLE_DESTINATION; 04363 04364 ch->state = MISDN_EXTCANTMATCH; 04365 misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE); 04366 return RESPONSE_OK; 04367 } 04368 } 04369 04370 /* Check for Pickup Request first */ 04371 if (!strcmp(chan->exten, ast_pickup_ext())) { 04372 if (!ch->noautorespond_on_setup) { 04373 int ret;/** Sending SETUP_ACK**/ 04374 ret = misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE ); 04375 } else { 04376 ch->state = MISDN_INCOMING_SETUP; 04377 } 04378 if (ast_pickup_call(chan)) { 04379 hangup_chan(ch); 04380 } else { 04381 ch->state = MISDN_CALLING_ACKNOWLEDGE; 04382 ast_setstate(chan, AST_STATE_DOWN); 04383 hangup_chan(ch); 04384 ch->ast = NULL; 04385 break; 04386 } 04387 } 04388 04389 /* 04390 * added support for s extension hope it will help those poor cretains 04391 * which haven't overlap dial. 04392 */ 04393 misdn_cfg_get(bc->port, MISDN_CFG_ALWAYS_IMMEDIATE, &ai, sizeof(ai)); 04394 if (ai) { 04395 do_immediate_setup(bc, ch, chan); 04396 break; 04397 } 04398 04399 /* check if we should jump into s when we have no dad */ 04400 misdn_cfg_get(bc->port, MISDN_CFG_IMMEDIATE, &im, sizeof(im)); 04401 if (im && ast_strlen_zero(bc->dad)) { 04402 do_immediate_setup(bc, ch, chan); 04403 break; 04404 } 04405 04406 chan_misdn_log(5, bc->port, "CONTEXT:%s\n", ch->context); 04407 if(!ast_canmatch_extension(ch->ast, ch->context, bc->dad, 1, bc->oad)) { 04408 if (ast_exists_extension(ch->ast, ch->context, "i", 1, bc->oad)) { 04409 ast_log(LOG_WARNING, 04410 "Extension '%s@%s' can never match. Jumping to 'i' extension. port:%d\n", 04411 bc->dad, ch->context, bc->port); 04412 strcpy(ch->ast->exten, "i"); 04413 misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE); 04414 ch->state = MISDN_DIALING; 04415 start_pbx(ch, bc, chan); 04416 break; 04417 } 04418 04419 ast_log(LOG_WARNING, 04420 "Extension '%s@%s' can never match. Disconnecting. port:%d\n" 04421 "\tMaybe you want to add an 'i' extension to catch this case.\n", 04422 bc->dad, ch->context, bc->port); 04423 if (bc->nt) 04424 hanguptone_indicate(ch); 04425 04426 ch->state = MISDN_EXTCANTMATCH; 04427 bc->out_cause = AST_CAUSE_UNALLOCATED; 04428 04429 if (bc->nt) 04430 misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE ); 04431 else 04432 misdn_lib_send_event(bc, EVENT_RELEASE ); 04433 04434 break; 04435 } 04436 04437 /* Whatever happens, when sending_complete is set or we are PTMP TE, we will definitely 04438 * jump into the dialplan, when the dialed extension does not exist, the 's' extension 04439 * will be used by Asterisk automatically. */ 04440 if (bc->sending_complete || (!bc->nt && !misdn_lib_is_ptp(bc->port))) { 04441 if (!ch->noautorespond_on_setup) { 04442 ch->state=MISDN_DIALING; 04443 misdn_lib_send_event(bc, EVENT_PROCEEDING ); 04444 } else { 04445 ch->state = MISDN_INCOMING_SETUP; 04446 } 04447 start_pbx(ch, bc, chan); 04448 break; 04449 } 04450 04451 04452 /* 04453 * When we are NT and overlapdial is set and if 04454 * the number is empty, we wait for the ISDN timeout 04455 * instead of our own timer. 04456 */ 04457 if (ch->overlap_dial && bc->nt && !bc->dad[0] ) { 04458 wait_for_digits(ch, bc, chan); 04459 break; 04460 } 04461 04462 /* 04463 * If overlapdial we will definitely send a SETUP_ACKNOWLEDGE and wait for more 04464 * Infos with a Interdigit Timeout. 04465 * */ 04466 if (ch->overlap_dial) { 04467 ast_mutex_lock(&ch->overlap_tv_lock); 04468 ch->overlap_tv = ast_tvnow(); 04469 ast_mutex_unlock(&ch->overlap_tv_lock); 04470 04471 wait_for_digits(ch, bc, chan); 04472 if (ch->overlap_dial_task == -1) 04473 ch->overlap_dial_task = 04474 misdn_tasks_add_variable(ch->overlap_dial, misdn_overlap_dial_task, ch); 04475 04476 break; 04477 } 04478 04479 /* If the extension does not exist and we're not TE_PTMP we wait for more digits 04480 * without interdigit timeout. 04481 * */ 04482 if (!ast_exists_extension(ch->ast, ch->context, bc->dad, 1, bc->oad)) { 04483 wait_for_digits(ch, bc, chan); 04484 break; 04485 } 04486 04487 /* 04488 * If the extension exists let's just jump into it. 04489 * */ 04490 if (ast_exists_extension(ch->ast, ch->context, bc->dad, 1, bc->oad)) { 04491 if (bc->need_more_infos) 04492 misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE ); 04493 else 04494 misdn_lib_send_event(bc, EVENT_PROCEEDING); 04495 04496 ch->state = MISDN_DIALING; 04497 start_pbx(ch, bc, chan); 04498 break; 04499 } 04500 } 04501 break; 04502 04503 case EVENT_SETUP_ACKNOWLEDGE: 04504 { 04505 ch->state = MISDN_CALLING_ACKNOWLEDGE; 04506 04507 if (bc->channel) 04508 update_name(ch->ast,bc->port,bc->channel); 04509 04510 if (!ast_strlen_zero(bc->infos_pending)) { 04511 /* TX Pending Infos */ 04512 strncat(bc->dad, bc->infos_pending, sizeof(bc->dad) - strlen(bc->dad) - 1); 04513 04514 if (!ch->ast) 04515 break; 04516 ast_copy_string(ch->ast->exten, bc->dad, sizeof(ch->ast->exten)); 04517 ast_copy_string(bc->info_dad, bc->infos_pending, sizeof(bc->info_dad)); 04518 ast_copy_string(bc->infos_pending, "", sizeof(bc->infos_pending)); 04519 04520 misdn_lib_send_event(bc, EVENT_INFORMATION); 04521 } 04522 } 04523 break; 04524 case EVENT_PROCEEDING: 04525 { 04526 if (bc->channel) 04527 update_name(ch->ast, bc->port, bc->channel); 04528 04529 if (misdn_cap_is_speech(bc->capability) && 04530 misdn_inband_avail(bc) ) { 04531 start_bc_tones(ch); 04532 } 04533 04534 ch->state = MISDN_PROCEEDING; 04535 04536 if (!ch->ast) 04537 break; 04538 04539 ast_queue_control(ch->ast, AST_CONTROL_PROCEEDING); 04540 } 04541 break; 04542 case EVENT_PROGRESS: 04543 if (bc->channel) 04544 update_name(ch->ast, bc->port, bc->channel); 04545 04546 if (!bc->nt ) { 04547 if ( misdn_cap_is_speech(bc->capability) && 04548 misdn_inband_avail(bc) 04549 ) { 04550 start_bc_tones(ch); 04551 } 04552 04553 ch->state = MISDN_PROGRESS; 04554 04555 if (!ch->ast) 04556 break; 04557 ast_queue_control(ch->ast, AST_CONTROL_PROGRESS); 04558 } 04559 break; 04560 04561 04562 case EVENT_ALERTING: 04563 { 04564 if (bc->channel) 04565 update_name(ch->ast, bc->port, bc->channel); 04566 04567 ch->state = MISDN_ALERTING; 04568 04569 if (!ch->ast) 04570 break; 04571 04572 ast_queue_control(ch->ast, AST_CONTROL_RINGING); 04573 ast_setstate(ch->ast, AST_STATE_RINGING); 04574 04575 cb_log(7, bc->port, " --> Set State Ringing\n"); 04576 04577 if (misdn_cap_is_speech(bc->capability) && misdn_inband_avail(bc)) { 04578 cb_log(1, bc->port, "Starting Tones, we have inband Data\n"); 04579 start_bc_tones(ch); 04580 } else { 04581 cb_log(3, bc->port, " --> We have no inband Data, the other end must create ringing\n"); 04582 if (ch->far_alerting) { 04583 cb_log(1, bc->port, " --> The other end can not do ringing eh ?.. we must do all ourself.."); 04584 start_bc_tones(ch); 04585 /*tone_indicate(ch, TONE_FAR_ALERTING);*/ 04586 } 04587 } 04588 } 04589 break; 04590 case EVENT_CONNECT: 04591 { 04592 struct ast_channel *bridged; 04593 04594 /*we answer when we've got our very new L3 ID from the NT stack */ 04595 misdn_lib_send_event(bc, EVENT_CONNECT_ACKNOWLEDGE); 04596 04597 if (!ch->ast) 04598 break; 04599 04600 bridged = ast_bridged_channel(ch->ast); 04601 stop_indicate(ch); 04602 04603 if (bridged && !strcasecmp(bridged->tech->type, "mISDN")) { 04604 struct chan_list *bridged_ch = MISDN_ASTERISK_TECH_PVT(bridged); 04605 04606 chan_misdn_log(1, bc->port, " --> copying cpndialplan:%d and cad:%s to the A-Channel\n", bc->cpnnumplan, bc->cad); 04607 if (bridged_ch) { 04608 bridged_ch->bc->cpnnumplan = bc->cpnnumplan; 04609 ast_copy_string(bridged_ch->bc->cad, bc->cad, sizeof(bridged_ch->bc->cad)); 04610 } 04611 } 04612 } 04613 ch->l3id=bc->l3_id; 04614 ch->addr=bc->addr; 04615 04616 start_bc_tones(ch); 04617 04618 ch->state = MISDN_CONNECTED; 04619 04620 ast_queue_control(ch->ast, AST_CONTROL_ANSWER); 04621 break; 04622 case EVENT_CONNECT_ACKNOWLEDGE: 04623 { 04624 ch->l3id = bc->l3_id; 04625 ch->addr = bc->addr; 04626 04627 start_bc_tones(ch); 04628 04629 ch->state = MISDN_CONNECTED; 04630 } 04631 break; 04632 case EVENT_DISCONNECT: 04633 /*we might not have an ch->ast ptr here anymore*/ 04634 if (ch) { 04635 struct chan_list *holded_ch = find_holded(cl_te, bc); 04636 04637 chan_misdn_log(3, bc->port, " --> org:%d nt:%d, inbandavail:%d state:%d\n", ch->originator, bc->nt, misdn_inband_avail(bc), ch->state); 04638 if (ch->originator == ORG_AST && !bc->nt && misdn_inband_avail(bc) && ch->state != MISDN_CONNECTED) { 04639 /* If there's inband information available (e.g. a 04640 recorded message saying what was wrong with the 04641 dialled number, or perhaps even giving an 04642 alternative number, then play it instead of 04643 immediately releasing the call */ 04644 chan_misdn_log(1, bc->port, " --> Inband Info Avail, not sending RELEASE\n"); 04645 04646 ch->state = MISDN_DISCONNECTED; 04647 start_bc_tones(ch); 04648 04649 if (ch->ast) { 04650 ch->ast->hangupcause = bc->cause; 04651 if (bc->cause == AST_CAUSE_USER_BUSY) 04652 ast_queue_control(ch->ast, AST_CONTROL_BUSY); 04653 } 04654 ch->need_busy = 0; 04655 break; 04656 } 04657 04658 /*Check for holded channel, to implement transfer*/ 04659 if (holded_ch && holded_ch != ch && ch->ast && ch->state == MISDN_CONNECTED) { 04660 cb_log(1, bc->port, " --> found holded ch\n"); 04661 misdn_transfer_bc(ch, holded_ch) ; 04662 } 04663 04664 bc->need_disconnect = 0; 04665 04666 stop_bc_tones(ch); 04667 hangup_chan(ch); 04668 #if 0 04669 } else { 04670 ch = find_holded_l3(cl_te, bc->l3_id,1); 04671 if (ch) { 04672 hangup_chan(ch); 04673 } 04674 #endif 04675 } 04676 bc->out_cause = -1; 04677 if (bc->need_release) 04678 misdn_lib_send_event(bc, EVENT_RELEASE); 04679 break; 04680 04681 case EVENT_RELEASE: 04682 { 04683 bc->need_disconnect = 0; 04684 bc->need_release = 0; 04685 04686 hangup_chan(ch); 04687 release_chan(bc); 04688 } 04689 break; 04690 case EVENT_RELEASE_COMPLETE: 04691 { 04692 bc->need_disconnect = 0; 04693 bc->need_release = 0; 04694 bc->need_release_complete = 0; 04695 04696 stop_bc_tones(ch); 04697 hangup_chan(ch); 04698 04699 if (ch) 04700 ch->state = MISDN_CLEANING; 04701 04702 release_chan(bc); 04703 } 04704 break; 04705 case EVENT_BCHAN_ERROR: 04706 case EVENT_CLEANUP: 04707 { 04708 stop_bc_tones(ch); 04709 04710 switch (ch->state) { 04711 case MISDN_CALLING: 04712 bc->cause = AST_CAUSE_DESTINATION_OUT_OF_ORDER; 04713 break; 04714 default: 04715 break; 04716 } 04717 04718 hangup_chan(ch); 04719 release_chan(bc); 04720 } 04721 break; 04722 04723 case EVENT_TONE_GENERATE: 04724 { 04725 int tone_len = bc->tone_cnt; 04726 struct ast_channel *ast = ch->ast; 04727 void *tmp; 04728 int res; 04729 int (*generate)(struct ast_channel *chan, void *tmp, int datalen, int samples); 04730 04731 chan_misdn_log(9, bc->port, "TONE_GEN: len:%d\n", tone_len); 04732 04733 if (!ast) 04734 break; 04735 04736 if (!ast->generator) 04737 break; 04738 04739 tmp = ast->generatordata; 04740 ast->generatordata = NULL; 04741 generate = ast->generator->generate; 04742 04743 if (tone_len < 0 || tone_len > 512 ) { 04744 ast_log(LOG_NOTICE, "TONE_GEN: len was %d, set to 128\n", tone_len); 04745 tone_len = 128; 04746 } 04747 04748 res = generate(ast, tmp, tone_len, tone_len); 04749 ast->generatordata = tmp; 04750 04751 if (res) { 04752 ast_log(LOG_WARNING, "Auto-deactivating generator\n"); 04753 ast_deactivate_generator(ast); 04754 } else { 04755 bc->tone_cnt = 0; 04756 } 04757 } 04758 break; 04759 04760 case EVENT_BCHAN_DATA: 04761 { 04762 if (!misdn_cap_is_speech(ch->bc->capability)) { 04763 struct ast_frame frame; 04764 /*In Data Modes we queue frames*/ 04765 frame.frametype = AST_FRAME_VOICE; /*we have no data frames yet*/ 04766 frame.subclass = AST_FORMAT_ALAW; 04767 frame.datalen = bc->bframe_len; 04768 frame.samples = bc->bframe_len; 04769 frame.mallocd = 0; 04770 frame.offset = 0; 04771 frame.delivery = ast_tv(0,0); 04772 frame.src = NULL; 04773 frame.data = bc->bframe; 04774 04775 if (ch->ast) 04776 ast_queue_frame(ch->ast, &frame); 04777 } else { 04778 fd_set wrfs; 04779 struct timeval tv = { 0, 0 }; 04780 int t; 04781 04782 FD_ZERO(&wrfs); 04783 FD_SET(ch->pipe[1], &wrfs); 04784 04785 t = select(FD_SETSIZE, NULL, &wrfs, NULL, &tv); 04786 04787 if (!t) { 04788 chan_misdn_log(9, bc->port, "Select Timed out\n"); 04789 break; 04790 } 04791 04792 if (t < 0) { 04793 chan_misdn_log(-1, bc->port, "Select Error (err=%s)\n", strerror(errno)); 04794 break; 04795 } 04796 04797 if (FD_ISSET(ch->pipe[1], &wrfs)) { 04798 chan_misdn_log(9, bc->port, "writing %d bytes to asterisk\n", bc->bframe_len); 04799 if (write(ch->pipe[1], bc->bframe, bc->bframe_len) <= 0) { 04800 chan_misdn_log(0, bc->port, "Write returned <=0 (err=%s) --> hanging up channel\n", strerror(errno)); 04801 04802 stop_bc_tones(ch); 04803 hangup_chan(ch); 04804 release_chan(bc); 04805 } 04806 } else { 04807 chan_misdn_log(1, bc->port, "Write Pipe full!\n"); 04808 } 04809 } 04810 } 04811 break; 04812 case EVENT_TIMEOUT: 04813 { 04814 if (ch && bc) 04815 chan_misdn_log(1, bc->port, "--> state: %s\n", misdn_get_ch_state(ch)); 04816 04817 switch (ch->state) { 04818 case MISDN_DIALING: 04819 case MISDN_PROGRESS: 04820 if (bc->nt && !ch->nttimeout) 04821 break; 04822 04823 case MISDN_CALLING: 04824 case MISDN_ALERTING: 04825 case MISDN_PROCEEDING: 04826 case MISDN_CALLING_ACKNOWLEDGE: 04827 if (bc->nt) { 04828 bc->progress_indicator = INFO_PI_INBAND_AVAILABLE; 04829 hanguptone_indicate(ch); 04830 } 04831 04832 bc->out_cause = AST_CAUSE_UNALLOCATED; 04833 misdn_lib_send_event(bc, EVENT_DISCONNECT); 04834 break; 04835 04836 case MISDN_WAITING4DIGS: 04837 if (bc->nt) { 04838 bc->progress_indicator = INFO_PI_INBAND_AVAILABLE; 04839 bc->out_cause = AST_CAUSE_UNALLOCATED; 04840 hanguptone_indicate(ch); 04841 misdn_lib_send_event(bc, EVENT_DISCONNECT); 04842 } else { 04843 bc->out_cause = AST_CAUSE_NORMAL_CLEARING; 04844 misdn_lib_send_event(bc, EVENT_RELEASE); 04845 } 04846 04847 break; 04848 04849 case MISDN_CLEANING: 04850 chan_misdn_log(1,bc->port," --> in state cleaning .. so ignoring, the stack should clean it for us\n"); 04851 break; 04852 04853 default: 04854 misdn_lib_send_event(bc,EVENT_RELEASE_COMPLETE); 04855 } 04856 } 04857 break; 04858 04859 04860 /****************************/ 04861 /** Supplementary Services **/ 04862 /****************************/ 04863 case EVENT_RETRIEVE: 04864 { 04865 struct ast_channel *hold_ast; 04866 04867 if (!ch) { 04868 chan_misdn_log(4, bc->port, " --> no CH, searching in holded\n"); 04869 ch = find_holded_l3(cl_te, bc->l3_id, 1); 04870 } 04871 04872 if (!ch) { 04873 ast_log(LOG_WARNING, "Found no Holded channel, cannot Retrieve\n"); 04874 misdn_lib_send_event(bc, EVENT_RETRIEVE_REJECT); 04875 break; 04876 } 04877 04878 /*remember the channel again*/ 04879 ch->bc = bc; 04880 ch->state = MISDN_CONNECTED; 04881 04882 ch->hold_info.port = 0; 04883 ch->hold_info.channel = 0; 04884 04885 hold_ast = ast_bridged_channel(ch->ast); 04886 04887 if (hold_ast) { 04888 ast_moh_stop(hold_ast); 04889 } 04890 04891 if (misdn_lib_send_event(bc, EVENT_RETRIEVE_ACKNOWLEDGE) < 0) { 04892 chan_misdn_log(4, bc->port, " --> RETRIEVE_ACK failed\n"); 04893 misdn_lib_send_event(bc, EVENT_RETRIEVE_REJECT); 04894 } 04895 } 04896 break; 04897 04898 case EVENT_HOLD: 04899 { 04900 int hold_allowed; 04901 struct ast_channel *bridged; 04902 04903 misdn_cfg_get(bc->port, MISDN_CFG_HOLD_ALLOWED, &hold_allowed, sizeof(int)); 04904 04905 if (!hold_allowed) { 04906 04907 chan_misdn_log(-1, bc->port, "Hold not allowed this port.\n"); 04908 misdn_lib_send_event(bc, EVENT_HOLD_REJECT); 04909 break; 04910 } 04911 04912 bridged = ast_bridged_channel(ch->ast); 04913 if (bridged) { 04914 chan_misdn_log(2, bc->port, "Bridge Partner is of type: %s\n", bridged->tech->type); 04915 ch->state = MISDN_HOLDED; 04916 ch->l3id = bc->l3_id; 04917 04918 misdn_lib_send_event(bc, EVENT_HOLD_ACKNOWLEDGE); 04919 04920 /* XXX This should queue an AST_CONTROL_HOLD frame on this channel 04921 * instead of starting moh on the bridged channel directly */ 04922 ast_moh_start(bridged, NULL, NULL); 04923 04924 /*forget the channel now*/ 04925 ch->bc = NULL; 04926 ch->hold_info.port = bc->port; 04927 ch->hold_info.channel = bc->channel; 04928 04929 } else { 04930 misdn_lib_send_event(bc, EVENT_HOLD_REJECT); 04931 chan_misdn_log(0, bc->port, "We aren't bridged to anybody\n"); 04932 } 04933 } 04934 break; 04935 04936 case EVENT_FACILITY: 04937 if (!ch) { 04938 /* This may come from a call we don't know nothing about, so we ignore it. */ 04939 chan_misdn_log(-1, bc->port, "Got EVENT_FACILITY but we don't have a ch!\n"); 04940 break; 04941 } 04942 04943 print_facility(&(bc->fac_in), bc); 04944 04945 switch (bc->fac_in.Function) { 04946 case Fac_CD: 04947 { 04948 struct ast_channel *bridged = ast_bridged_channel(ch->ast); 04949 struct chan_list *ch_br; 04950 if (bridged && MISDN_ASTERISK_TECH_PVT(bridged)) { 04951 ch_br = MISDN_ASTERISK_TECH_PVT(bridged); 04952 /*ch->state = MISDN_FACILITY_DEFLECTED;*/ 04953 if (ch_br->bc) { 04954 if (ast_exists_extension(bridged, ch->context, (char *)bc->fac_in.u.CDeflection.DeflectedToNumber, 1, bc->oad)) { 04955 ch_br->state = MISDN_DIALING; 04956 if (pbx_start_chan(ch_br) < 0) { 04957 chan_misdn_log(-1, ch_br->bc->port, "ast_pbx_start returned < 0 in misdn_overlap_dial_task\n"); 04958 } 04959 } 04960 } 04961 } 04962 misdn_lib_send_event(bc, EVENT_DISCONNECT); 04963 } 04964 break; 04965 case Fac_AOCDCurrency: 04966 { 04967 bc->AOCDtype = Fac_AOCDCurrency; 04968 memcpy(&(bc->AOCD.currency), &(bc->fac_in.u.AOCDcur), sizeof(struct FacAOCDCurrency)); 04969 export_aoc_vars(ch->originator, ch->ast, bc); 04970 } 04971 break; 04972 case Fac_AOCDChargingUnit: 04973 { 04974 bc->AOCDtype = Fac_AOCDChargingUnit; 04975 memcpy(&(bc->AOCD.chargingUnit), &(bc->fac_in.u.AOCDchu), sizeof(struct FacAOCDChargingUnit)); 04976 export_aoc_vars(ch->originator, ch->ast, bc); 04977 } 04978 break; 04979 default: 04980 chan_misdn_log(0, bc->port," --> not yet handled: facility type:%d\n", bc->fac_in.Function); 04981 } 04982 04983 break; 04984 04985 case EVENT_RESTART: 04986 04987 if (!bc->dummy) { 04988 stop_bc_tones(ch); 04989 release_chan(bc); 04990 } 04991 break; 04992 04993 default: 04994 chan_misdn_log(1, 0, "Got Unknown Event\n"); 04995 break; 04996 } 04997 04998 return RESPONSE_OK; 04999 }
int chan_misdn_jb_empty | ( | struct misdn_bchannel * | bc, | |
char * | buf, | |||
int | len | |||
) |
Definition at line 5535 of file chan_misdn.c.
References chan_list::bc, cl_te, find_chan_by_bc(), chan_list::jb, and misdn_jb_empty().
Referenced by load_module().
05536 { 05537 struct chan_list *ch = find_chan_by_bc(cl_te, bc); 05538 05539 if (ch && ch->jb) { 05540 return misdn_jb_empty(ch->jb, buf, len); 05541 } 05542 05543 return -1; 05544 }
static void chan_misdn_log | ( | int | level, | |
int | port, | |||
char * | tmpl, | |||
... | ||||
) | [static] |
Definition at line 5718 of file chan_misdn.c.
References ast_console_puts(), ast_log(), ast_strlen_zero(), errno, 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_end(), misdn_facility_exec(), misdn_fixup(), misdn_hangup(), misdn_indication(), misdn_jb_empty(), misdn_jb_fill(), misdn_jb_init(), misdn_l1_task(), 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(), update_config(), and update_name().
05719 { 05720 va_list ap; 05721 char buf[1024]; 05722 char port_buf[8]; 05723 05724 if (! ((0 <= port) && (port <= max_ports))) { 05725 ast_log(LOG_WARNING, "cb_log called with out-of-range port number! (%d)\n", port); 05726 port = 0; 05727 level = -1; 05728 } 05729 05730 snprintf(port_buf, sizeof(port_buf), "P[%2d] ", port); 05731 05732 va_start(ap, tmpl); 05733 vsnprintf(buf, sizeof(buf), tmpl, ap); 05734 va_end(ap); 05735 05736 if (level == -1) 05737 ast_log(LOG_WARNING, "%s", buf); 05738 05739 else if (misdn_debug_only[port] ? 05740 (level == 1 && misdn_debug[port]) || (level == misdn_debug[port]) 05741 : level <= misdn_debug[port]) { 05742 05743 ast_console_puts(port_buf); 05744 ast_console_puts(buf); 05745 } 05746 05747 if ((level <= misdn_debug[0]) && !ast_strlen_zero(global_tracefile) ) { 05748 time_t tm = time(NULL); 05749 char *tmp = ctime(&tm), *p; 05750 05751 FILE *fp = fopen(global_tracefile, "a+"); 05752 05753 p = strchr(tmp, '\n'); 05754 if (p) 05755 *p = ':'; 05756 05757 if (!fp) { 05758 ast_console_puts("Error opening Tracefile: [ "); 05759 ast_console_puts(global_tracefile); 05760 ast_console_puts(" ] "); 05761 05762 ast_console_puts(strerror(errno)); 05763 ast_console_puts("\n"); 05764 return ; 05765 } 05766 05767 fputs(tmp, fp); 05768 fputs(" ", fp); 05769 fputs(port_buf, fp); 05770 fputs(" ", fp); 05771 fputs(buf, fp); 05772 05773 fclose(fp); 05774 } 05775 }
Definition at line 3592 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().
03593 { 03594 struct chan_list *help; 03595 03596 if (chan->dsp) 03597 ast_dsp_free(chan->dsp); 03598 if (chan->trans) 03599 ast_translator_free_path(chan->trans); 03600 03601 ast_mutex_lock(&cl_te_lock); 03602 if (!*list) { 03603 ast_mutex_unlock(&cl_te_lock); 03604 return; 03605 } 03606 03607 if (*list == chan) { 03608 *list = (*list)->next; 03609 ast_mutex_unlock(&cl_te_lock); 03610 return; 03611 } 03612 03613 for (help = *list; help->next; help = help->next) { 03614 if (help->next == chan) { 03615 help->next = help->next->next; 03616 ast_mutex_unlock(&cl_te_lock); 03617 return; 03618 } 03619 } 03620 03621 ast_mutex_unlock(&cl_te_lock); 03622 }
Definition at line 3576 of file chan_misdn.c.
References ast_mutex_lock, ast_mutex_unlock, chan_list::bc, chan_misdn_log(), cl_te_lock, chan_list::next, and misdn_bchannel::port.
Referenced by cb_events(), and misdn_request().
03577 { 03578 chan_misdn_log(4, chan->bc ? chan->bc->port : 0, "* Queuing chan %p\n", chan); 03579 03580 ast_mutex_lock(&cl_te_lock); 03581 if (!*list) { 03582 *list = chan; 03583 } else { 03584 struct chan_list *help = *list; 03585 for (; help->next; help = help->next); 03586 help->next = chan; 03587 } 03588 chan->next = NULL; 03589 ast_mutex_unlock(&cl_te_lock); 03590 }
static char* complete_ch | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 1612 of file chan_misdn.c.
References complete_ch_helper().
01613 { 01614 return complete_ch_helper(line, word, pos, state, 3); 01615 }
static char* complete_ch_helper | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state, | |||
int | rpos | |||
) | [static] |
Definition at line 1588 of file chan_misdn.c.
References ast_channel_walk_locked(), ast_mutex_unlock, ast_channel::lock, ast_channel::name, and strdup.
Referenced by complete_ch().
01589 { 01590 struct ast_channel *c; 01591 int which=0; 01592 char *ret; 01593 if (pos != rpos) 01594 return NULL; 01595 c = ast_channel_walk_locked(NULL); 01596 while(c) { 01597 if (!strncasecmp(word, c->name, strlen(word))) { 01598 if (++which > state) 01599 break; 01600 } 01601 ast_mutex_unlock(&c->lock); 01602 c = ast_channel_walk_locked(c); 01603 } 01604 if (c) { 01605 ret = strdup(c->name); 01606 ast_mutex_unlock(&c->lock); 01607 } else 01608 ret = NULL; 01609 return ret; 01610 }
static char* complete_debug_port | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 1617 of file chan_misdn.c.
References strdup.
01618 { 01619 if (state) 01620 return NULL; 01621 01622 switch (pos) { 01623 case 4: 01624 if (*word == 'p') 01625 return strdup("port"); 01626 else if (*word == 'o') 01627 return strdup("only"); 01628 break; 01629 case 6: 01630 if (*word == 'o') 01631 return strdup("only"); 01632 break; 01633 } 01634 return NULL; 01635 }
static char* complete_show_config | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 1637 of file chan_misdn.c.
References BUFFERSIZE, MISDN_CFG_FIRST, misdn_cfg_get_name(), misdn_cfg_get_next_port(), MISDN_CFG_LAST, MISDN_GEN_FIRST, MISDN_GEN_LAST, and strdup.
01638 { 01639 char buffer[BUFFERSIZE]; 01640 enum misdn_cfg_elements elem; 01641 int wordlen = strlen(word); 01642 int which = 0; 01643 int port = 0; 01644 01645 switch (pos) { 01646 case 3: 01647 if ((!strncmp(word, "description", wordlen)) && (++which > state)) 01648 return strdup("description"); 01649 if ((!strncmp(word, "descriptions", wordlen)) && (++which > state)) 01650 return strdup("descriptions"); 01651 if ((!strncmp(word, "0", wordlen)) && (++which > state)) 01652 return strdup("0"); 01653 while ((port = misdn_cfg_get_next_port(port)) != -1) { 01654 snprintf(buffer, sizeof(buffer), "%d", port); 01655 if ((!strncmp(word, buffer, wordlen)) && (++which > state)) { 01656 return strdup(buffer); 01657 } 01658 } 01659 break; 01660 case 4: 01661 if (strstr(line, "description ")) { 01662 for (elem = MISDN_CFG_FIRST + 1; elem < MISDN_GEN_LAST; ++elem) { 01663 if ((elem == MISDN_CFG_LAST) || (elem == MISDN_GEN_FIRST)) 01664 continue; 01665 misdn_cfg_get_name(elem, buffer, BUFFERSIZE); 01666 if (!wordlen || !strncmp(word, buffer, wordlen)) { 01667 if (++which > state) 01668 return strdup(buffer); 01669 } 01670 } 01671 } else if (strstr(line, "descriptions ")) { 01672 if ((!wordlen || !strncmp(word, "general", wordlen)) && (++which > state)) 01673 return strdup("general"); 01674 if ((!wordlen || !strncmp(word, "ports", wordlen)) && (++which > state)) 01675 return strdup("ports"); 01676 } 01677 break; 01678 } 01679 return NULL; 01680 }
static void config_jitterbuffer | ( | struct chan_list * | ch | ) | [static] |
Definition at line 1820 of file chan_misdn.c.
References chan_list::bc, cb_log, chan_misdn_log(), chan_list::jb, chan_list::jb_len, chan_list::jb_upper_threshold, len(), misdn_jb_destroy(), misdn_jb_init(), misdn_bchannel::nojitter, and misdn_bchannel::port.
Referenced by misdn_set_opt_exec(), and read_config().
01821 { 01822 struct misdn_bchannel *bc = ch->bc; 01823 int len = ch->jb_len, threshold = ch->jb_upper_threshold; 01824 01825 chan_misdn_log(5, bc->port, "config_jb: Called\n"); 01826 01827 if (! len) { 01828 chan_misdn_log(1, bc->port, "config_jb: Deactivating Jitterbuffer\n"); 01829 bc->nojitter=1; 01830 } else { 01831 if (len <= 100 || len > 8000) { 01832 chan_misdn_log(0, bc->port, "config_jb: Jitterbuffer out of Bounds, setting to 1000\n"); 01833 len = 1000; 01834 } 01835 01836 if ( threshold > len ) { 01837 chan_misdn_log(0, bc->port, "config_jb: Jitterbuffer Threshold > Jitterbuffer setting to Jitterbuffer -1\n"); 01838 } 01839 01840 if ( ch->jb) { 01841 cb_log(0, bc->port, "config_jb: We've got a Jitterbuffer Already on this port.\n"); 01842 misdn_jb_destroy(ch->jb); 01843 ch->jb = NULL; 01844 } 01845 01846 ch->jb=misdn_jb_init(len, threshold); 01847 01848 if (!ch->jb ) 01849 bc->nojitter = 1; 01850 } 01851 }
void debug_numplan | ( | int | port, | |
int | numplan, | |||
char * | type | |||
) |
Definition at line 1854 of file chan_misdn.c.
References chan_misdn_log(), NUMPLAN_INTERNATIONAL, NUMPLAN_NATIONAL, NUMPLAN_SUBSCRIBER, and NUMPLAN_UNKNOWN.
Referenced by read_config().
01855 { 01856 switch (numplan) { 01857 case NUMPLAN_INTERNATIONAL: 01858 chan_misdn_log(2, port, " --> %s: International\n", type); 01859 break; 01860 case NUMPLAN_NATIONAL: 01861 chan_misdn_log(2, port, " --> %s: National\n", type); 01862 break; 01863 case NUMPLAN_SUBSCRIBER: 01864 chan_misdn_log(2, port, " --> %s: Subscriber\n", type); 01865 break; 01866 case NUMPLAN_UNKNOWN: 01867 chan_misdn_log(2, port, " --> %s: Unknown\n", type); 01868 break; 01869 /* Maybe we should cut off the prefix if present ? */ 01870 default: 01871 chan_misdn_log(0, port, " --> !!!! Wrong dialplan setting, please see the misdn.conf sample file\n "); 01872 break; 01873 } 01874 }
static int dialtone_indicate | ( | struct chan_list * | cl | ) | [static] |
AST INDICATIONS END
Definition at line 3079 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(), MISDN_CFG_NODIALTONE, chan_list::norxtone, chan_list::notxtone, misdn_bchannel::port, chan_list::ts, and ast_channel::zone.
Referenced by wait_for_digits().
03080 { 03081 const struct tone_zone_sound *ts = NULL; 03082 struct ast_channel *ast = cl->ast; 03083 int nd = 0; 03084 03085 if (!ast) { 03086 chan_misdn_log(0, cl->bc->port, "No Ast in dialtone_indicate\n"); 03087 return -1; 03088 } 03089 03090 misdn_cfg_get(cl->bc->port, MISDN_CFG_NODIALTONE, &nd, sizeof(nd)); 03091 03092 if (nd) { 03093 chan_misdn_log(1, cl->bc->port, "Not sending Dialtone, because config wants it\n"); 03094 return 0; 03095 } 03096 03097 chan_misdn_log(3, cl->bc->port, " --> Dial\n"); 03098 ts = ast_get_indication_tone(ast->zone, "dial"); 03099 cl->ts = ts; 03100 03101 if (ts) { 03102 cl->notxtone = 0; 03103 cl->norxtone = 0; 03104 /* This prods us in misdn_write */ 03105 ast_playtones_start(ast, 0, ts->data, 0); 03106 } 03107 03108 return 0; 03109 }
static void do_immediate_setup | ( | struct misdn_bchannel * | bc, | |
struct chan_list * | ch, | |||
struct ast_channel * | ast | |||
) | [static] |
Definition at line 3758 of file chan_misdn.c.
References chan_list::ast, ast_canmatch_extension(), AST_CAUSE_UNALLOCATED, AST_FRAME_DTMF, ast_queue_frame(), ast_strlen_zero(), ast_tv(), chan_misdn_log(), ast_channel::cid, ast_callerid::cid_num, ast_channel::context, ast_frame::data, ast_frame::datalen, ast_frame::delivery, EVENT_DISCONNECT, EVENT_PROCEEDING, EVENT_RELEASE_COMPLETE, EVENT_SETUP_ACKNOWLEDGE, 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, misdn_lib_is_ptp(), misdn_lib_send_event(), chan_list::noautorespond_on_setup, misdn_bchannel::nt, misdn_bchannel::oad, ast_frame::offset, misdn_bchannel::out_cause, pbx_start_chan(), misdn_bchannel::port, ast_frame::samples, ast_frame::src, chan_list::state, and ast_frame::subclass.
Referenced by cb_events().
03759 { 03760 char predial[256]=""; 03761 char *p = predial; 03762 03763 struct ast_frame fr; 03764 03765 strncpy(predial, ast->exten, sizeof(predial) -1 ); 03766 03767 ch->state = MISDN_DIALING; 03768 03769 if (!ch->noautorespond_on_setup) { 03770 if (bc->nt) { 03771 int ret; 03772 ret = misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE ); 03773 } else { 03774 int ret; 03775 if ( misdn_lib_is_ptp(bc->port)) { 03776 ret = misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE ); 03777 } else { 03778 ret = misdn_lib_send_event(bc, EVENT_PROCEEDING ); 03779 } 03780 } 03781 } else { 03782 ch->state = MISDN_INCOMING_SETUP; 03783 } 03784 03785 chan_misdn_log(1, bc->port, "* Starting Ast ctx:%s dad:%s oad:%s with 's' extension\n", ast->context, ast->exten, ast->cid.cid_num); 03786 03787 strcpy(ast->exten, "s"); 03788 03789 if (!ast_canmatch_extension(ast, ast->context, ast->exten, 1, bc->oad) || pbx_start_chan(ch) < 0) { 03790 ast = NULL; 03791 bc->out_cause = AST_CAUSE_UNALLOCATED; 03792 hangup_chan(ch); 03793 hanguptone_indicate(ch); 03794 03795 if (bc->nt) 03796 misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE ); 03797 else 03798 misdn_lib_send_event(bc, EVENT_DISCONNECT ); 03799 } 03800 03801 03802 while (!ast_strlen_zero(p) ) { 03803 fr.frametype = AST_FRAME_DTMF; 03804 fr.subclass = *p; 03805 fr.src = NULL; 03806 fr.data = NULL; 03807 fr.datalen = 0; 03808 fr.samples = 0; 03809 fr.mallocd = 0; 03810 fr.offset = 0; 03811 fr.delivery = ast_tv(0,0); 03812 03813 if (ch->ast && MISDN_ASTERISK_PVT(ch->ast) && MISDN_ASTERISK_TECH_PVT(ch->ast)) { 03814 ast_queue_frame(ch->ast, &fr); 03815 } 03816 p++; 03817 } 03818 }
static void export_aoc_vars | ( | int | originator, | |
struct ast_channel * | ast, | |||
struct misdn_bchannel * | bc | |||
) | [static] |
Definition at line 677 of file chan_misdn.c.
References misdn_bchannel::AOCD, misdn_bchannel::AOCDtype, ast_bridged_channel(), misdn_bchannel::chargingUnit, misdn_bchannel::currency, ORG_AST, and pbx_builtin_setvar_helper().
Referenced by cb_events().
00678 { 00679 char buf[128]; 00680 00681 if (!ast) 00682 return; 00683 00684 if (originator == ORG_AST) { 00685 ast = ast_bridged_channel(ast); 00686 if (!ast) 00687 return; 00688 } 00689 00690 switch (bc->AOCDtype) { 00691 case Fac_AOCDCurrency: 00692 pbx_builtin_setvar_helper(ast, "AOCD_Type", "currency"); 00693 if (bc->AOCD.currency.chargeNotAvailable) 00694 pbx_builtin_setvar_helper(ast, "AOCD_ChargeAvailable", "no"); 00695 else { 00696 pbx_builtin_setvar_helper(ast, "AOCD_ChargeAvailable", "yes"); 00697 if (bc->AOCD.currency.freeOfCharge) 00698 pbx_builtin_setvar_helper(ast, "AOCD_FreeOfCharge", "yes"); 00699 else { 00700 pbx_builtin_setvar_helper(ast, "AOCD_FreeOfCharge", "no"); 00701 if (snprintf(buf, sizeof(buf), "%d %s", bc->AOCD.currency.currencyAmount * bc->AOCD.currency.multiplier, bc->AOCD.currency.currency) < sizeof(buf)) { 00702 pbx_builtin_setvar_helper(ast, "AOCD_Amount", buf); 00703 if (bc->AOCD.currency.billingId >= 0 && snprintf(buf, sizeof(buf), "%d", bc->AOCD.currency.billingId) < sizeof(buf)) 00704 pbx_builtin_setvar_helper(ast, "AOCD_BillingId", buf); 00705 } 00706 } 00707 } 00708 break; 00709 case Fac_AOCDChargingUnit: 00710 pbx_builtin_setvar_helper(ast, "AOCD_Type", "charging_unit"); 00711 if (bc->AOCD.chargingUnit.chargeNotAvailable) 00712 pbx_builtin_setvar_helper(ast, "AOCD_ChargeAvailable", "no"); 00713 else { 00714 pbx_builtin_setvar_helper(ast, "AOCD_ChargeAvailable", "yes"); 00715 if (bc->AOCD.chargingUnit.freeOfCharge) 00716 pbx_builtin_setvar_helper(ast, "AOCD_FreeOfCharge", "yes"); 00717 else { 00718 pbx_builtin_setvar_helper(ast, "AOCD_FreeOfCharge", "no"); 00719 if (snprintf(buf, sizeof(buf), "%d", bc->AOCD.chargingUnit.recordedUnits) < sizeof(buf)) { 00720 pbx_builtin_setvar_helper(ast, "AOCD_RecordedUnits", buf); 00721 if (bc->AOCD.chargingUnit.billingId >= 0 && snprintf(buf, sizeof(buf), "%d", bc->AOCD.chargingUnit.billingId) < sizeof(buf)) 00722 pbx_builtin_setvar_helper(ast, "AOCD_BillingId", buf); 00723 } 00724 } 00725 } 00726 break; 00727 default: 00728 break; 00729 } 00730 }
void export_ch | ( | struct ast_channel * | chan, | |
struct misdn_bchannel * | bc, | |||
struct chan_list * | ch | |||
) |
Export parameters to the dialplan environment variables.
Definition at line 3913 of file chan_misdn.c.
References ast_strlen_zero(), chan_misdn_log(), misdn_bchannel::keypad, pbx_builtin_setvar_helper(), misdn_bchannel::pid, misdn_bchannel::port, misdn_bchannel::sending_complete, misdn_bchannel::urate, misdn_bchannel::uu, and misdn_bchannel::uulen.
Referenced by cb_events().
03914 { 03915 char tmp[32]; 03916 chan_misdn_log(3, bc->port, " --> EXPORT_PID: pid:%d\n", bc->pid); 03917 snprintf(tmp, sizeof(tmp), "%d", bc->pid); 03918 pbx_builtin_setvar_helper(chan, "_MISDN_PID", tmp); 03919 03920 if (bc->sending_complete) { 03921 snprintf(tmp, sizeof(tmp), "%d", bc->sending_complete); 03922 pbx_builtin_setvar_helper(chan, "MISDN_ADDRESS_COMPLETE", tmp); 03923 } 03924 03925 if (bc->urate) { 03926 snprintf(tmp, sizeof(tmp), "%d", bc->urate); 03927 pbx_builtin_setvar_helper(chan, "MISDN_URATE", tmp); 03928 } 03929 03930 if (bc->uulen && (bc->uulen < sizeof(bc->uu))) { 03931 bc->uu[bc->uulen] = 0; 03932 pbx_builtin_setvar_helper(chan, "MISDN_USERUSER", bc->uu); 03933 } 03934 03935 if (!ast_strlen_zero(bc->keypad)) 03936 pbx_builtin_setvar_helper(chan, "MISDN_KEYPAD", bc->keypad); 03937 }
static struct chan_list * find_chan_by_bc | ( | struct chan_list * | list, | |
struct misdn_bchannel * | bc | |||
) | [static] |
Definition at line 3519 of file chan_misdn.c.
References chan_list::bc, chan_misdn_log(), misdn_bchannel::dad, chan_list::next, misdn_bchannel::oad, and misdn_bchannel::port.
Referenced by cb_events(), chan_misdn_jb_empty(), and release_chan().
03520 { 03521 struct chan_list *help = list; 03522 for (; help; help = help->next) { 03523 if (help->bc == bc) return help; 03524 } 03525 03526 chan_misdn_log(6, bc->port, "$$$ find_chan: No channel found for oad:%s dad:%s\n", bc->oad, bc->dad); 03527 03528 return NULL; 03529 }
Definition at line 3531 of file chan_misdn.c.
References chan_list::bc, chan_misdn_log(), chan_list::next, and misdn_bchannel::pid.
Referenced by import_ch().
03532 { 03533 struct chan_list *help = list; 03534 for (; help; help = help->next) { 03535 if ( help->bc && (help->bc->pid == pid) ) return help; 03536 } 03537 03538 chan_misdn_log(6, 0, "$$$ find_chan: No channel found for pid:%d\n", pid); 03539 03540 return NULL; 03541 }
static struct chan_list* find_holded | ( | struct chan_list * | list, | |
struct misdn_bchannel * | bc | |||
) | [static] |
Definition at line 3543 of file chan_misdn.c.
References chan_list::bc, chan_misdn_log(), hold_info::channel, misdn_bchannel::channel, misdn_bchannel::dad, chan_list::hold_info, MISDN_HOLDED, chan_list::next, misdn_bchannel::oad, hold_info::port, misdn_bchannel::port, misdn_bchannel::pri, and chan_list::state.
Referenced by cb_events().
03544 { 03545 struct chan_list *help = list; 03546 03547 if (bc->pri) return NULL; 03548 03549 chan_misdn_log(6, bc->port, "$$$ find_holded: channel:%d oad:%s dad:%s\n", bc->channel, bc->oad, bc->dad); 03550 for (;help; help = help->next) { 03551 chan_misdn_log(4, bc->port, "$$$ find_holded: --> holded:%d channel:%d\n", help->state == MISDN_HOLDED, help->hold_info.channel); 03552 if ((help->state == MISDN_HOLDED) && 03553 (help->hold_info.port == bc->port)) 03554 return help; 03555 } 03556 chan_misdn_log(6, bc->port, "$$$ find_chan: No channel found for oad:%s dad:%s\n", bc->oad, bc->dad); 03557 03558 return NULL; 03559 }
static struct chan_list* find_holded_l3 | ( | struct chan_list * | list, | |
unsigned long | l3_id, | |||
int | w | |||
) | [static] |
Definition at line 3562 of file chan_misdn.c.
References chan_list::l3id, MISDN_HOLDED, chan_list::next, and chan_list::state.
Referenced by cb_events().
03563 { 03564 struct chan_list *help = list; 03565 03566 for (; help; help = help->next) { 03567 if ( (help->state == MISDN_HOLDED) && 03568 (help->l3id == l3_id) 03569 ) 03570 return help; 03571 } 03572 03573 return NULL; 03574 }
static void free_robin_list | ( | void | ) | [static] |
Definition at line 450 of file chan_misdn.c.
References free_robin_list_r(), and robin.
Referenced by reload_config(), and unload_module().
00451 { 00452 free_robin_list_r(robin); 00453 robin = NULL; 00454 }
static void free_robin_list_r | ( | struct robin_list * | r | ) | [inline, static] |
Definition at line 439 of file chan_misdn.c.
References free, robin_list::group, and robin_list::next.
Referenced by free_robin_list().
00440 { 00441 if (r) { 00442 if (r->next) 00443 free_robin_list_r(r->next); 00444 if (r->group) 00445 free(r->group); 00446 free(r); 00447 } 00448 }
static struct chan_list* get_chan_by_ast | ( | struct ast_channel * | ast | ) | [static] |
Definition at line 566 of file chan_misdn.c.
References chan_list::ast, cl_te, and chan_list::next.
Referenced by misdn_bridge().
00567 { 00568 struct chan_list *tmp; 00569 00570 for (tmp=cl_te; tmp; tmp = tmp->next) { 00571 if ( tmp->ast == ast ) return tmp; 00572 } 00573 00574 return NULL; 00575 }
static struct chan_list* get_chan_by_ast_name | ( | char * | name | ) | [static] |
Definition at line 577 of file chan_misdn.c.
References chan_list::ast, cl_te, ast_channel::name, and chan_list::next.
Referenced by misdn_send_cd(), misdn_send_digit(), misdn_send_display(), and misdn_toggle_echocancel().
00578 { 00579 struct chan_list *tmp; 00580 00581 for (tmp=cl_te; tmp; tmp = tmp->next) { 00582 if ( tmp->ast && strcmp(tmp->ast->name,name) == 0) return tmp; 00583 } 00584 00585 return NULL; 00586 }
static struct robin_list* get_robin_position | ( | char * | group | ) | [static] |
Definition at line 456 of file chan_misdn.c.
References calloc, robin_list::group, robin_list::next, robin_list::prev, robin, and strndup.
Referenced by misdn_request().
00457 { 00458 struct robin_list *new; 00459 struct robin_list *iter = robin; 00460 for (; iter; iter = iter->next) { 00461 if (!strcasecmp(iter->group, group)) 00462 return iter; 00463 } 00464 new = (struct robin_list *) calloc(1, sizeof(struct robin_list)); 00465 new->group = strndup(group, strlen(group)); 00466 new->port = 0; 00467 new->channel = 0; 00468 if (robin) { 00469 new->next = robin; 00470 robin->prev = new; 00471 } 00472 robin = new; 00473 return robin; 00474 }
static void hangup_chan | ( | struct chan_list * | ch | ) | [static] |
Definition at line 3639 of file chan_misdn.c.
References chan_list::ast, ast_hangup(), ast_queue_hangup(), chan_list::bc, cb_log, chan_list::need_hangup, chan_list::need_queue_hangup, misdn_bchannel::port, and send_cause2ast().
Referenced by cb_events(), do_immediate_setup(), and start_pbx().
03640 { 03641 int port = ch ? (ch->bc ? ch->bc->port : 0) : 0; 03642 if (!ch) { 03643 cb_log(1, 0, "Cannot hangup chan, no ch\n"); 03644 return; 03645 } 03646 03647 cb_log(5, port, "hangup_chan called\n"); 03648 03649 if (ch->need_hangup) { 03650 cb_log(2, port, " --> hangup\n"); 03651 send_cause2ast(ch->ast, ch->bc, ch); 03652 ch->need_hangup = 0; 03653 ch->need_queue_hangup = 0; 03654 if (ch->ast) 03655 ast_hangup(ch->ast); 03656 return; 03657 } 03658 03659 if (!ch->need_queue_hangup) { 03660 cb_log(2, port, " --> No need to queue hangup\n"); 03661 } 03662 03663 ch->need_queue_hangup = 0; 03664 if (ch->ast) { 03665 send_cause2ast(ch->ast, ch->bc, ch); 03666 03667 if (ch->ast) 03668 ast_queue_hangup(ch->ast); 03669 cb_log(2, port, " --> queue_hangup\n"); 03670 } else { 03671 cb_log(1, port, "Cannot hangup chan, no ast\n"); 03672 } 03673 }
static int hanguptone_indicate | ( | struct chan_list * | cl | ) | [static] |
Definition at line 3111 of file chan_misdn.c.
References chan_list::bc, misdn_lib_send_tone(), and TONE_HANGUP.
Referenced by cb_events(), do_immediate_setup(), misdn_hangup(), misdn_indication(), misdn_overlap_dial_task(), and start_pbx().
03112 { 03113 misdn_lib_send_tone(cl->bc, TONE_HANGUP); 03114 return 0; 03115 }
void import_ch | ( | struct ast_channel * | chan, | |
struct misdn_bchannel * | bc, | |||
struct chan_list * | ch | |||
) |
Import parameters from the dialplan environment variables.
Definition at line 3879 of file chan_misdn.c.
References ast_copy_string(), ast_log(), chan_misdn_log(), cl_te, find_chan_by_pid(), misdn_bchannel::keypad, LOG_NOTICE, chan_list::other_ch, chan_list::other_pid, pbx_builtin_getvar_helper(), misdn_bchannel::port, misdn_bchannel::sending_complete, misdn_bchannel::uu, and misdn_bchannel::uulen.
Referenced by misdn_call().
03880 { 03881 const char *tmp; 03882 03883 tmp = pbx_builtin_getvar_helper(chan, "MISDN_PID"); 03884 if (tmp) { 03885 ch->other_pid = atoi(tmp); 03886 chan_misdn_log(3, bc->port, " --> IMPORT_PID: importing pid:%s\n", tmp); 03887 if (ch->other_pid > 0) { 03888 ch->other_ch = find_chan_by_pid(cl_te, ch->other_pid); 03889 if (ch->other_ch) 03890 ch->other_ch->other_ch = ch; 03891 } 03892 } 03893 03894 tmp = pbx_builtin_getvar_helper(chan, "MISDN_ADDRESS_COMPLETE"); 03895 if (tmp && (atoi(tmp) == 1)) { 03896 bc->sending_complete = 1; 03897 } 03898 03899 tmp = pbx_builtin_getvar_helper(chan, "MISDN_USERUSER"); 03900 if (tmp) { 03901 ast_log(LOG_NOTICE, "MISDN_USERUSER: %s\n", tmp); 03902 ast_copy_string(bc->uu, tmp, sizeof(bc->uu)); 03903 bc->uulen = strlen(bc->uu); 03904 } 03905 03906 tmp = pbx_builtin_getvar_helper(chan, "MISDN_KEYPAD"); 03907 if (tmp) { 03908 ast_copy_string(bc->keypad, tmp, sizeof(bc->keypad)); 03909 } 03910 }
static struct chan_list* init_chan_list | ( | int | orig | ) | [static] |
Definition at line 3156 of file chan_misdn.c.
References calloc, chan_misdn_log(), chan_list::need_busy, chan_list::need_hangup, chan_list::need_queue_hangup, chan_list::originator, and chan_list::overlap_dial_task.
Referenced by cb_events(), and misdn_request().
03157 { 03158 struct chan_list *cl; 03159 03160 cl = calloc(1, sizeof(struct chan_list)); 03161 if (!cl) { 03162 chan_misdn_log(-1, 0, "misdn_request: malloc failed!"); 03163 return NULL; 03164 } 03165 03166 cl->originator = orig; 03167 cl->need_queue_hangup = 1; 03168 cl->need_hangup = 1; 03169 cl->need_busy = 1; 03170 cl->overlap_dial_task = -1; 03171 03172 return cl; 03173 }
static int load_module | ( | void | ) | [static] |
Definition at line 5044 of file chan_misdn.c.
References ast_channel_register(), ast_cli_register_multiple(), ast_log(), AST_MODULE_LOAD_DECLINE, ast_mutex_init, ast_register_application(), ast_strlen_zero(), BUFFERSIZE, calloc, misdn_lib_iface::cb_event, cb_events(), chan_misdn_clis, chan_misdn_jb_empty(), chan_misdn_log(), cl_te_lock, LOG_ERROR, malloc, max_ports, misdn_cfg_get(), misdn_cfg_get_next_port(), misdn_cfg_get_ports_string(), misdn_cfg_init(), MISDN_CFG_L1_TIMEOUT, misdn_cfg_update_ptp(), misdn_check_l2l1(), misdn_debug, misdn_debug_only, misdn_facility_exec(), MISDN_GEN_DEBUG, MISDN_GEN_NTDEBUGFILE, MISDN_GEN_NTDEBUGFLAGS, MISDN_GEN_NTKEEPCALLS, MISDN_GEN_TRACEFILE, misdn_in_calls, misdn_l1_task(), misdn_lib_init(), misdn_lib_maxports_get(), misdn_lib_nt_debug_init(), misdn_lib_nt_keepcalls(), misdn_out_calls, misdn_set_opt_exec(), misdn_tasks_add(), misdn_tech, misdn_type, release_lock, tracing, and unload_module().
05045 { 05046 int i, port; 05047 int ntflags = 0, ntkc = 0; 05048 char ports[256] = ""; 05049 char tempbuf[BUFFERSIZE + 1]; 05050 char ntfile[BUFFERSIZE + 1]; 05051 struct misdn_lib_iface iface = { 05052 .cb_event = cb_events, 05053 .cb_log = chan_misdn_log, 05054 .cb_jb_empty = chan_misdn_jb_empty, 05055 }; 05056 05057 max_ports = misdn_lib_maxports_get(); 05058 05059 if (max_ports <= 0) { 05060 ast_log(LOG_ERROR, "Unable to initialize mISDN\n"); 05061 return AST_MODULE_LOAD_DECLINE; 05062 } 05063 05064 if (misdn_cfg_init(max_ports)) { 05065 ast_log(LOG_ERROR, "Unable to initialize misdn_config.\n"); 05066 return AST_MODULE_LOAD_DECLINE; 05067 } 05068 g_config_initialized = 1; 05069 05070 misdn_debug = (int *) malloc(sizeof(int) * (max_ports + 1)); 05071 if (!misdn_debug) { 05072 ast_log(LOG_ERROR, "Out of memory for misdn_debug\n"); 05073 return AST_MODULE_LOAD_DECLINE; 05074 } 05075 misdn_ports = (int *) malloc(sizeof(int) * (max_ports + 1)); 05076 if (!misdn_ports) { 05077 ast_log(LOG_ERROR, "Out of memory for misdn_ports\n"); 05078 return AST_MODULE_LOAD_DECLINE; 05079 } 05080 misdn_cfg_get(0, MISDN_GEN_DEBUG, &misdn_debug[0], sizeof(int)); 05081 for (i = 1; i <= max_ports; i++) { 05082 misdn_debug[i] = misdn_debug[0]; 05083 misdn_ports[i] = i; 05084 } 05085 *misdn_ports = 0; 05086 misdn_debug_only = (int *) calloc(max_ports + 1, sizeof(int)); 05087 05088 misdn_cfg_get(0, MISDN_GEN_TRACEFILE, tempbuf, BUFFERSIZE); 05089 if (!ast_strlen_zero(tempbuf)) 05090 tracing = 1; 05091 05092 misdn_in_calls = (int *) malloc(sizeof(int) * (max_ports + 1)); 05093 misdn_out_calls = (int *) malloc(sizeof(int) * (max_ports + 1)); 05094 05095 for (i = 1; i <= max_ports; i++) { 05096 misdn_in_calls[i] = 0; 05097 misdn_out_calls[i] = 0; 05098 } 05099 05100 ast_mutex_init(&cl_te_lock); 05101 ast_mutex_init(&release_lock); 05102 05103 misdn_cfg_update_ptp(); 05104 misdn_cfg_get_ports_string(ports); 05105 05106 if (!ast_strlen_zero(ports)) 05107 chan_misdn_log(0, 0, "Got: %s from get_ports\n", ports); 05108 if (misdn_lib_init(ports, &iface, NULL)) 05109 chan_misdn_log(0, 0, "No te ports initialized\n"); 05110 05111 misdn_cfg_get(0, MISDN_GEN_NTDEBUGFLAGS, &ntflags, sizeof(int)); 05112 misdn_cfg_get(0, MISDN_GEN_NTDEBUGFILE, &ntfile, BUFFERSIZE); 05113 misdn_lib_nt_debug_init(ntflags, ntfile); 05114 05115 misdn_cfg_get( 0, MISDN_GEN_NTKEEPCALLS, &ntkc, sizeof(int)); 05116 misdn_lib_nt_keepcalls(ntkc); 05117 05118 if (ast_channel_register(&misdn_tech)) { 05119 ast_log(LOG_ERROR, "Unable to register channel class %s\n", misdn_type); 05120 unload_module(); 05121 return -1; 05122 } 05123 05124 ast_cli_register_multiple(chan_misdn_clis, sizeof(chan_misdn_clis) / sizeof(struct ast_cli_entry)); 05125 05126 ast_register_application("misdn_set_opt", misdn_set_opt_exec, "misdn_set_opt", 05127 "misdn_set_opt(:<opt><optarg>:<opt><optarg>...):\n" 05128 "Sets mISDN opts. and optargs\n" 05129 "\n" 05130 "The available options are:\n" 05131 " a - Have Asterisk detect DTMF tones on called channel\n" 05132 " c - Make crypted outgoing call, optarg is keyindex\n" 05133 " d - Send display text to called phone, text is the optarg\n" 05134 " e - Perform echo cancelation on this channel,\n" 05135 " takes taps as optarg (32,64,128,256)\n" 05136 " e! - Disable echo cancelation on this channel\n" 05137 " f - Enable fax detection\n" 05138 " h - Make digital outgoing call\n" 05139 " h1 - Make HDLC mode digital outgoing call\n" 05140 " i - Ignore detected DTMF tones, don't signal them to Asterisk,\n" 05141 " they will be transported inband.\n" 05142 " jb - Set jitter buffer length, optarg is length\n" 05143 " jt - Set jitter buffer upper threshold, optarg is threshold\n" 05144 " jn - Disable jitter buffer\n" 05145 " n - Disable mISDN DSP on channel.\n" 05146 " Disables: echo cancel, DTMF detection, and volume control.\n" 05147 " p - Caller ID presentation,\n" 05148 " optarg is either 'allowed' or 'restricted'\n" 05149 " s - Send Non-inband DTMF as inband\n" 05150 " vr - Rx gain control, optarg is gain\n" 05151 " vt - Tx gain control, optarg is gain\n" 05152 ); 05153 05154 05155 ast_register_application("misdn_facility", misdn_facility_exec, "misdn_facility", 05156 "misdn_facility(<FACILITY_TYPE>|<ARG1>|..)\n" 05157 "Sends the Facility Message FACILITY_TYPE with \n" 05158 "the given Arguments to the current ISDN Channel\n" 05159 "Supported Facilities are:\n" 05160 "\n" 05161 "type=calldeflect args=Nr where to deflect\n" 05162 ); 05163 05164 05165 ast_register_application("misdn_check_l2l1", misdn_check_l2l1, "misdn_check_l2l1", 05166 "misdn_check_l2l1(<port>||g:<groupname>,timeout)" 05167 "Checks if the L2 and L1 are up on either the given <port> or\n" 05168 "on the ports in the group with <groupname>\n" 05169 "If the L1/L2 are down, check_l2l1 gets up the L1/L2 and waits\n" 05170 "for <timeout> seconds that this happens. Otherwise, nothing happens\n" 05171 "\n" 05172 "This application, ensures the L1/L2 state of the Ports in a group\n" 05173 "it is intended to make the pmp_l1_check option redundant and to\n" 05174 "fix a buggy switch config from your provider\n" 05175 "\n" 05176 "a sample dialplan would look like:\n\n" 05177 "exten => _X.,1,misdn_check_l2l1(g:out|2)\n" 05178 "exten => _X.,n,dial(mISDN/g:out/${EXTEN})\n" 05179 "\n" 05180 ); 05181 05182 05183 misdn_cfg_get(0, MISDN_GEN_TRACEFILE, global_tracefile, BUFFERSIZE); 05184 05185 /* start the l1 watchers */ 05186 05187 for (port = misdn_cfg_get_next_port(0); port >= 0; port = misdn_cfg_get_next_port(port)) { 05188 int l1timeout; 05189 misdn_cfg_get(port, MISDN_CFG_L1_TIMEOUT, &l1timeout, sizeof(l1timeout)); 05190 if (l1timeout) { 05191 chan_misdn_log(4, 0, "Adding L1watcher task: port:%d timeout:%ds\n", port, l1timeout); 05192 misdn_tasks_add(l1timeout * 1000, misdn_l1_task, &misdn_ports[port]); 05193 } 05194 } 05195 05196 chan_misdn_log(0, 0, "-- mISDN Channel Driver Registered --\n"); 05197 05198 return 0; 05199 }
static int misdn_answer | ( | struct ast_channel * | ast | ) | [static] |
Definition at line 2278 of file chan_misdn.c.
References chan_list::ast, ast_copy_string(), ast_log(), ast_queue_hangup(), ast_strlen_zero(), ast_true(), chan_list::bc, misdn_bchannel::cad, chan_misdn_log(), misdn_bchannel::crypt_key, misdn_bchannel::dad, EVENT_CONNECT, misdn_bchannel::hdlc, LOG_WARNING, MISDN_ASTERISK_TECH_PVT, MISDN_CONNECTED, misdn_lib_send_event(), misdn_bchannel::nodsp, misdn_bchannel::nojitter, pbx_builtin_getvar_helper(), misdn_bchannel::port, start_bc_tones(), chan_list::state, and stop_indicate().
02279 { 02280 struct chan_list *p; 02281 const char *tmp; 02282 02283 if (!ast || !(p = MISDN_ASTERISK_TECH_PVT(ast))) return -1; 02284 02285 chan_misdn_log(1, p ? (p->bc ? p->bc->port : 0) : 0, "* ANSWER:\n"); 02286 02287 if (!p) { 02288 ast_log(LOG_WARNING, " --> Channel not connected ??\n"); 02289 ast_queue_hangup(ast); 02290 } 02291 02292 if (!p->bc) { 02293 chan_misdn_log(1, 0, " --> Got Answer, but there is no bc obj ??\n"); 02294 02295 ast_queue_hangup(ast); 02296 } 02297 02298 tmp = pbx_builtin_getvar_helper(p->ast, "CRYPT_KEY"); 02299 if (!ast_strlen_zero(tmp)) { 02300 chan_misdn_log(1, p->bc->port, " --> Connection will be BF crypted\n"); 02301 ast_copy_string(p->bc->crypt_key, tmp, sizeof(p->bc->crypt_key)); 02302 } else { 02303 chan_misdn_log(3, p->bc->port, " --> Connection is without BF encryption\n"); 02304 } 02305 02306 tmp = pbx_builtin_getvar_helper(ast, "MISDN_DIGITAL_TRANS"); 02307 if (!ast_strlen_zero(tmp) && ast_true(tmp)) { 02308 chan_misdn_log(1, p->bc->port, " --> Connection is transparent digital\n"); 02309 p->bc->nodsp = 1; 02310 p->bc->hdlc = 0; 02311 p->bc->nojitter = 1; 02312 } 02313 02314 p->state = MISDN_CONNECTED; 02315 stop_indicate(p); 02316 02317 if ( ast_strlen_zero(p->bc->cad) ) { 02318 chan_misdn_log(2,p->bc->port," --> empty cad using dad\n"); 02319 ast_copy_string(p->bc->cad, p->bc->dad, sizeof(p->bc->cad)); 02320 } 02321 02322 misdn_lib_send_event( p->bc, EVENT_CONNECT); 02323 start_bc_tones(p); 02324 02325 return 0; 02326 }
static enum ast_bridge_result misdn_bridge | ( | struct ast_channel * | c0, | |
struct ast_channel * | c1, | |||
int | flags, | |||
struct ast_frame ** | fo, | |||
struct ast_channel ** | rc, | |||
int | timeoutms | |||
) | [static] |
Definition at line 2974 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_verbose(), ast_waitfor_n(), ast_write(), chan_list::bc, chan_misdn_log(), ast_channel::exten, f, get_chan_by_ast(), chan_list::ignore_dtmf, LOG_NOTICE, MISDN_CFG_BRIDGING, misdn_cfg_get(), MISDN_GEN_BRIDGING, misdn_lib_bridge(), misdn_lib_split_bridge(), ast_channel::name, misdn_bchannel::oad, option_verbose, misdn_bchannel::pid, misdn_bchannel::port, and VERBOSE_PREFIX_3.
02980 { 02981 struct chan_list *ch1, *ch2; 02982 struct ast_channel *carr[2], *who; 02983 int to = -1; 02984 struct ast_frame *f; 02985 int p1_b, p2_b; 02986 int bridging; 02987 02988 ch1 = get_chan_by_ast(c0); 02989 ch2 = get_chan_by_ast(c1); 02990 02991 carr[0] = c0; 02992 carr[1] = c1; 02993 02994 if (!(ch1 && ch2)) 02995 return -1; 02996 02997 misdn_cfg_get(ch1->bc->port, MISDN_CFG_BRIDGING, &p1_b, sizeof(int)); 02998 misdn_cfg_get(ch2->bc->port, MISDN_CFG_BRIDGING, &p2_b, sizeof(int)); 02999 03000 if (! p1_b || ! p2_b) { 03001 ast_log(LOG_NOTICE, "Falling back to Asterisk bridging\n"); 03002 return AST_BRIDGE_FAILED; 03003 } 03004 03005 misdn_cfg_get(0, MISDN_GEN_BRIDGING, &bridging, sizeof(int)); 03006 if (bridging) { 03007 /* trying to make a mISDN_dsp conference */ 03008 chan_misdn_log(1, ch1->bc->port, "I SEND: Making conference with Number:%d\n", ch1->bc->pid + 1); 03009 misdn_lib_bridge(ch1->bc, ch2->bc); 03010 } 03011 03012 if (option_verbose > 2) 03013 ast_verbose(VERBOSE_PREFIX_3 "Native bridging %s and %s\n", c0->name, c1->name); 03014 03015 chan_misdn_log(1, ch1->bc->port, "* Making Native Bridge between %s and %s\n", ch1->bc->oad, ch2->bc->oad); 03016 03017 if (! (flags & AST_BRIDGE_DTMF_CHANNEL_0) ) 03018 ch1->ignore_dtmf = 1; 03019 03020 if (! (flags & AST_BRIDGE_DTMF_CHANNEL_1) ) 03021 ch2->ignore_dtmf = 1; 03022 03023 for (;/*ever*/;) { 03024 to = -1; 03025 who = ast_waitfor_n(carr, 2, &to); 03026 03027 if (!who) { 03028 ast_log(LOG_NOTICE, "misdn_bridge: empty read, breaking out\n"); 03029 break; 03030 } 03031 f = ast_read(who); 03032 03033 if (!f || f->frametype == AST_FRAME_CONTROL) { 03034 /* got hangup .. */ 03035 03036 if (!f) 03037 chan_misdn_log(4, ch1->bc->port, "Read Null Frame\n"); 03038 else 03039 chan_misdn_log(4, ch1->bc->port, "Read Frame Control class:%d\n", f->subclass); 03040 03041 *fo = f; 03042 *rc = who; 03043 break; 03044 } 03045 03046 if ( f->frametype == AST_FRAME_DTMF ) { 03047 chan_misdn_log(1, 0, "Read DTMF %d from %s\n", f->subclass, who->exten); 03048 03049 *fo = f; 03050 *rc = who; 03051 break; 03052 } 03053 03054 #if 0 03055 if (f->frametype == AST_FRAME_VOICE) { 03056 chan_misdn_log(1, ch1->bc->port, "I SEND: Splitting conference with Number:%d\n", ch1->bc->pid +1); 03057 03058 continue; 03059 } 03060 #endif 03061 03062 if (who == c0) { 03063 ast_write(c1, f); 03064 } 03065 else { 03066 ast_write(c0, f); 03067 } 03068 } 03069 03070 chan_misdn_log(1, ch1->bc->port, "I SEND: Splitting conference with Number:%d\n", ch1->bc->pid + 1); 03071 03072 misdn_lib_split_bridge(ch1->bc, ch2->bc); 03073 03074 return AST_BRIDGE_COMPLETE; 03075 }
static int misdn_call | ( | struct ast_channel * | ast, | |
char * | dest, | |||
int | timeout | |||
) | [static] |
Definition at line 2138 of file chan_misdn.c.
References ast_channel::_state, add_out_calls(), AST_CAUSE_NORMAL_CIRCUIT_CONGESTION, AST_CAUSE_NORMAL_CLEARING, AST_CAUSE_NORMAL_TEMPORARY_FAILURE, ast_copy_string(), ast_log(), ast_setstate(), AST_STATE_DIALING, AST_STATE_DOWN, AST_STATE_RESERVED, ast_strdupa, ast_strlen_zero(), ast_transfercapability2str(), chan_list::bc, misdn_bchannel::capability, chan_misdn_log(), ast_channel::cid, ast_callerid::cid_num, ast_callerid::cid_rdnis, ast_channel::context, misdn_bchannel::dad, misdn_bchannel::ec_enable, ENOCHAN, EVENT_SETUP, ext, ast_channel::exten, ast_channel::hangupcause, import_ch(), INFO_CAPABILITY_DIGITAL_UNRESTRICTED, misdn_bchannel::l3_id, chan_list::l3id, LOG_WARNING, MISDN_ASTERISK_TECH_PVT, MISDN_CALLING, misdn_cfg_get(), MISDN_GEN_BRIDGING, misdn_lib_send_event(), misdn_set_opt_exec(), ast_channel::name, misdn_bchannel::nt, misdn_bchannel::oad, ORG_AST, chan_list::other_ch, pbx_builtin_setvar_helper(), misdn_bchannel::pid, misdn_bchannel::port, misdn_bchannel::rad, S_OR, chan_list::state, stop_bc_tones(), ast_channel::transfercapability, and update_config().
02139 { 02140 int port = 0; 02141 int r; 02142 int exceed; 02143 int bridging; 02144 struct chan_list *ch; 02145 struct misdn_bchannel *newbc; 02146 char *opts, *ext; 02147 char *dest_cp; 02148 02149 if (!ast) { 02150 ast_log(LOG_WARNING, " --> ! misdn_call called on ast_channel *ast where ast == NULL\n"); 02151 return -1; 02152 } 02153 02154 if (((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) || !dest ) { 02155 ast_log(LOG_WARNING, " --> ! misdn_call called on %s, neither down nor reserved (or dest==NULL)\n", ast->name); 02156 ast->hangupcause = AST_CAUSE_NORMAL_TEMPORARY_FAILURE; 02157 ast_setstate(ast, AST_STATE_DOWN); 02158 return -1; 02159 } 02160 02161 ch = MISDN_ASTERISK_TECH_PVT(ast); 02162 if (!ch) { 02163 ast_log(LOG_WARNING, " --> ! misdn_call called on %s, neither down nor reserved (or dest==NULL)\n", ast->name); 02164 ast->hangupcause = AST_CAUSE_NORMAL_TEMPORARY_FAILURE; 02165 ast_setstate(ast, AST_STATE_DOWN); 02166 return -1; 02167 } 02168 02169 newbc = ch->bc; 02170 if (!newbc) { 02171 ast_log(LOG_WARNING, " --> ! misdn_call called on %s, neither down nor reserved (or dest==NULL)\n", ast->name); 02172 ast->hangupcause = AST_CAUSE_NORMAL_TEMPORARY_FAILURE; 02173 ast_setstate(ast, AST_STATE_DOWN); 02174 return -1; 02175 } 02176 02177 /* 02178 * dest is ---v 02179 * Dial(mISDN/g:group_name[/extension[/options]]) 02180 * Dial(mISDN/port[:preselected_channel][/extension[/options]]) 02181 * 02182 * The dial extension could be empty if you are using MISDN_KEYPAD 02183 * to control ISDN provider features. 02184 */ 02185 dest_cp = ast_strdupa(dest); 02186 strsep(&dest_cp, "/");/* Discard port/group token */ 02187 ext = strsep(&dest_cp, "/"); 02188 if (!ext) { 02189 ext = ""; 02190 } 02191 opts = dest_cp; 02192 02193 port = newbc->port; 02194 02195 if ((exceed = add_out_calls(port))) { 02196 char tmp[16]; 02197 snprintf(tmp, sizeof(tmp), "%d", exceed); 02198 pbx_builtin_setvar_helper(ast, "MAX_OVERFLOW", tmp); 02199 return -1; 02200 } 02201 02202 chan_misdn_log(1, port, "* CALL: %s\n", dest); 02203 02204 chan_misdn_log(2, port, " --> * dad:%s tech:%s ctx:%s\n", ast->exten, ast->name, ast->context); 02205 02206 chan_misdn_log(3, port, " --> * adding2newbc ext %s\n", ast->exten); 02207 if (ast->exten) { 02208 ast_copy_string(ast->exten, ext, sizeof(ast->exten)); 02209 ast_copy_string(newbc->dad, ext, sizeof(newbc->dad)); 02210 } 02211 02212 ast_copy_string(newbc->rad, S_OR(ast->cid.cid_rdnis, ""), sizeof(newbc->rad)); 02213 02214 chan_misdn_log(3, port, " --> * adding2newbc callerid %s\n", ast->cid.cid_num); 02215 if (ast_strlen_zero(newbc->oad) && !ast_strlen_zero(ast->cid.cid_num)) { 02216 ast_copy_string(newbc->oad, ast->cid.cid_num, sizeof(newbc->oad)); 02217 } 02218 02219 newbc->capability = ast->transfercapability; 02220 pbx_builtin_setvar_helper(ast, "TRANSFERCAPABILITY", ast_transfercapability2str(newbc->capability)); 02221 if ( ast->transfercapability == INFO_CAPABILITY_DIGITAL_UNRESTRICTED) { 02222 chan_misdn_log(2, port, " --> * Call with flag Digital\n"); 02223 } 02224 02225 /* update screening and presentation */ 02226 update_config(ch, ORG_AST); 02227 02228 /* fill in some ies from channel vary*/ 02229 import_ch(ast, newbc, ch); 02230 02231 /* Finally The Options Override Everything */ 02232 if (opts) 02233 misdn_set_opt_exec(ast, opts); 02234 else 02235 chan_misdn_log(2, port, "NO OPTS GIVEN\n"); 02236 02237 /*check for bridging*/ 02238 misdn_cfg_get(0, MISDN_GEN_BRIDGING, &bridging, sizeof(bridging)); 02239 if (bridging && ch->other_ch) { 02240 #ifdef MISDN_1_2 02241 chan_misdn_log(1, port, "Disabling EC (aka Pipeline) on both Sides\n"); 02242 *ch->bc->pipeline = 0; 02243 *ch->other_ch->bc->pipeline = 0; 02244 #else 02245 chan_misdn_log(1, port, "Disabling EC on both Sides\n"); 02246 ch->bc->ec_enable = 0; 02247 ch->other_ch->bc->ec_enable = 0; 02248 #endif 02249 } 02250 02251 r = misdn_lib_send_event( newbc, EVENT_SETUP ); 02252 02253 /** we should have l3id after sending setup **/ 02254 ch->l3id = newbc->l3_id; 02255 02256 if ( r == -ENOCHAN ) { 02257 chan_misdn_log(0, port, " --> * Theres no Channel at the moment .. !\n"); 02258 chan_misdn_log(1, port, " --> * SEND: State Down pid:%d\n", newbc ? newbc->pid : -1); 02259 ast->hangupcause = AST_CAUSE_NORMAL_CIRCUIT_CONGESTION; 02260 ast_setstate(ast, AST_STATE_DOWN); 02261 return -1; 02262 } 02263 02264 chan_misdn_log(2, port, " --> * SEND: State Dialing pid:%d\n", newbc ? newbc->pid : 1); 02265 02266 ast_setstate(ast, AST_STATE_DIALING); 02267 ast->hangupcause = AST_CAUSE_NORMAL_CLEARING; 02268 02269 if (newbc->nt) 02270 stop_bc_tones(ch); 02271 02272 ch->state = MISDN_CALLING; 02273 02274 return 0; 02275 }
static int misdn_check_l2l1 | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Definition at line 5257 of file chan_misdn.c.
References AST_APP_ARG, ast_copy_string(), AST_DECLARE_APP_ARGS, ast_log(), AST_STANDARD_APP_ARGS, ast_strlen_zero(), BUFFERSIZE, chan_misdn_log(), group, LOG_WARNING, misdn_cfg_get(), misdn_cfg_get_next_port(), MISDN_CFG_GROUPNAME, misdn_lib_get_port_up(), and misdn_lib_port_up().
Referenced by load_module().
05258 { 05259 char group[BUFFERSIZE + 1]; 05260 char *port_str; 05261 int port = 0; 05262 int timeout; 05263 int dowait = 0; 05264 int port_up; 05265 05266 AST_DECLARE_APP_ARGS(args, 05267 AST_APP_ARG(grouppar); 05268 AST_APP_ARG(timeout); 05269 ); 05270 05271 if (ast_strlen_zero((char *)data)) { 05272 ast_log(LOG_WARNING, "misdn_check_l2l1 Requires arguments\n"); 05273 return -1; 05274 } 05275 05276 AST_STANDARD_APP_ARGS(args, data); 05277 05278 if (args.argc != 2) { 05279 ast_log(LOG_WARNING, "Wrong argument count\n"); 05280 return 0; 05281 } 05282 05283 /*ast_log(LOG_NOTICE, "Arguments: group/port '%s' timeout '%s'\n", args.grouppar, args.timeout);*/ 05284 timeout = atoi(args.timeout); 05285 port_str = args.grouppar; 05286 05287 if (port_str[0] == 'g' && port_str[1] == ':' ) { 05288 /* We make a group call lets checkout which ports are in my group */ 05289 port_str += 2; 05290 ast_copy_string(group, port_str, sizeof(group)); 05291 chan_misdn_log(2, 0, "Checking Ports in group: %s\n", group); 05292 05293 for ( port = misdn_cfg_get_next_port(port); 05294 port > 0; 05295 port = misdn_cfg_get_next_port(port)) { 05296 char cfg_group[BUFFERSIZE + 1]; 05297 05298 chan_misdn_log(2, 0, "trying port %d\n", port); 05299 05300 misdn_cfg_get(port, MISDN_CFG_GROUPNAME, cfg_group, BUFFERSIZE); 05301 05302 if (!strcasecmp(cfg_group, group)) { 05303 port_up = misdn_lib_port_up(port, 1); 05304 05305 if (!port_up) { 05306 chan_misdn_log(2, 0, " --> port '%d'\n", port); 05307 misdn_lib_get_port_up(port); 05308 dowait = 1; 05309 } 05310 } 05311 } 05312 05313 } else { 05314 port = atoi(port_str); 05315 chan_misdn_log(2, 0, "Checking Port: %d\n",port); 05316 port_up = misdn_lib_port_up(port, 1); 05317 if (!port_up) { 05318 misdn_lib_get_port_up(port); 05319 dowait = 1; 05320 } 05321 } 05322 05323 if (dowait) { 05324 chan_misdn_log(2, 0, "Waiting for '%d' seconds\n", timeout); 05325 sleep(timeout); 05326 } 05327 05328 return 0; 05329 }
static int misdn_digit_begin | ( | struct ast_channel * | chan, | |
char | digit | |||
) | [static] |
Definition at line 2328 of file chan_misdn.c.
02329 { 02330 /* XXX Modify this callback to support Asterisk controlling the length of DTMF */ 02331 return 0; 02332 }
static int misdn_digit_end | ( | struct ast_channel * | ast, | |
char | digit, | |||
unsigned int | duration | |||
) | [static] |
Definition at line 2334 of file chan_misdn.c.
References chan_list::ast, ast_log(), chan_list::bc, chan_misdn_log(), misdn_bchannel::dad, EVENT_INFORMATION, ast_channel::exten, misdn_bchannel::info_dad, misdn_bchannel::infos_pending, LOG_WARNING, MISDN_ASTERISK_TECH_PVT, MISDN_CALLING, MISDN_CALLING_ACKNOWLEDGE, misdn_lib_send_event(), chan_list::other_ch, misdn_bchannel::port, send_digit_to_chan(), misdn_bchannel::send_dtmf, and chan_list::state.
02335 { 02336 struct chan_list *p; 02337 struct misdn_bchannel *bc; 02338 02339 if (!ast || !(p = MISDN_ASTERISK_TECH_PVT(ast))) return -1; 02340 02341 bc = p->bc; 02342 chan_misdn_log(1, bc ? bc->port : 0, "* IND : Digit %c\n", digit); 02343 02344 if (!bc) { 02345 ast_log(LOG_WARNING, " --> !! Got Digit Event without having bchannel Object\n"); 02346 return -1; 02347 } 02348 02349 switch (p->state ) { 02350 case MISDN_CALLING: 02351 { 02352 int l; 02353 char buf[8]; 02354 buf[0]=digit; 02355 buf[1]=0; 02356 02357 l = sizeof(bc->infos_pending); 02358 strncat(bc->infos_pending, buf, l - strlen(bc->infos_pending) - 1); 02359 } 02360 break; 02361 case MISDN_CALLING_ACKNOWLEDGE: 02362 { 02363 bc->info_dad[0]=digit; 02364 bc->info_dad[1]=0; 02365 02366 { 02367 int l = sizeof(bc->dad); 02368 strncat(bc->dad, bc->info_dad, l - strlen(bc->dad) - 1); 02369 } 02370 { 02371 int l = sizeof(p->ast->exten); 02372 strncpy(p->ast->exten, bc->dad, l); 02373 p->ast->exten[l-1] = 0; 02374 } 02375 02376 misdn_lib_send_event( bc, EVENT_INFORMATION); 02377 } 02378 break; 02379 default: 02380 /* Do not send Digits in CONNECTED State, when 02381 * the other side is too mISDN. */ 02382 if (p->other_ch ) 02383 return 0; 02384 02385 if ( bc->send_dtmf ) 02386 send_digit_to_chan(p,digit); 02387 break; 02388 } 02389 02390 return 0; 02391 }
static int misdn_facility_exec | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Definition at line 5212 of file chan_misdn.c.
References ast_copy_string(), ast_log(), ast_strlen_zero(), chan_list::bc, chan_misdn_log(), EVENT_FACILITY, misdn_bchannel::fac_out, LOG_WARNING, MISDN_ASTERISK_TECH_PVT, misdn_lib_send_event(), misdn_bchannel::port, ast_channel::tech, and ast_channel_tech::type.
Referenced by load_module().
05213 { 05214 struct chan_list *ch = MISDN_ASTERISK_TECH_PVT(chan); 05215 char *tok, *tokb; 05216 05217 chan_misdn_log(0, 0, "TYPE: %s\n", chan->tech->type); 05218 05219 if (strcasecmp(chan->tech->type, "mISDN")) { 05220 ast_log(LOG_WARNING, "misdn_facility makes only sense with chan_misdn channels!\n"); 05221 return -1; 05222 } 05223 05224 if (ast_strlen_zero((char *)data)) { 05225 ast_log(LOG_WARNING, "misdn_facility Requires arguments\n"); 05226 return -1; 05227 } 05228 05229 tok = strtok_r((char*) data, "|", &tokb) ; 05230 05231 if (!tok) { 05232 ast_log(LOG_WARNING, "misdn_facility Requires arguments\n"); 05233 return -1; 05234 } 05235 05236 if (!strcasecmp(tok, "calldeflect")) { 05237 tok = strtok_r(NULL, "|", &tokb) ; 05238 05239 if (!tok) { 05240 ast_log(LOG_WARNING, "Facility: Call Defl Requires arguments\n"); 05241 } 05242 05243 if (strlen(tok) >= sizeof(ch->bc->fac_out.u.CDeflection.DeflectedToNumber)) { 05244 ast_log(LOG_WARNING, "Facility: Number argument too long (up to 15 digits are allowed). Ignoring.\n"); 05245 return 0; 05246 } 05247 ch->bc->fac_out.Function = Fac_CD; 05248 ast_copy_string((char *)ch->bc->fac_out.u.CDeflection.DeflectedToNumber, tok, sizeof(ch->bc->fac_out.u.CDeflection.DeflectedToNumber)); 05249 misdn_lib_send_event(ch->bc, EVENT_FACILITY); 05250 } else { 05251 chan_misdn_log(1, ch->bc->port, "Unknown Facility: %s\n", tok); 05252 } 05253 05254 return 0; 05255 }
static int misdn_fixup | ( | struct ast_channel * | oldast, | |
struct ast_channel * | ast | |||
) | [static] |
Definition at line 2394 of file chan_misdn.c.
References chan_list::ast, chan_list::bc, chan_misdn_log(), chan_list::l3id, MISDN_ASTERISK_TECH_PVT, misdn_get_ch_state(), and misdn_bchannel::port.
02395 { 02396 struct chan_list *p; 02397 02398 if (!ast || ! (p=MISDN_ASTERISK_TECH_PVT(ast) )) return -1; 02399 02400 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); 02401 02402 p->ast = ast; 02403 02404 return 0; 02405 }
static const char* misdn_get_ch_state | ( | struct chan_list * | p | ) | [static] |
Definition at line 1206 of file chan_misdn.c.
References chan_list::state, state_array, and state_struct::txt.
Referenced by cb_events(), misdn_fixup(), misdn_hangup(), misdn_write(), print_bc_info(), and release_chan().
01207 { 01208 int i; 01209 static char state[8]; 01210 01211 if( !p) return NULL; 01212 01213 for (i = 0; i < sizeof(state_array) / sizeof(struct state_struct); i++) { 01214 if (state_array[i].state == p->state) 01215 return state_array[i].txt; 01216 } 01217 01218 snprintf(state, sizeof(state), "%d", p->state) ; 01219 01220 return state; 01221 }
static int misdn_hangup | ( | struct ast_channel * | ast | ) | [static] |
Definition at line 2530 of file chan_misdn.c.
References ast_channel::_state, chan_list::ast, AST_CAUSE_NORMAL_CLEARING, ast_log(), ast_mutex_lock, ast_mutex_unlock, AST_STATE_RESERVED, chan_list::bc, misdn_bchannel::cause, chan_misdn_log(), ast_channel::cid, ast_callerid::cid_num, cl_dequeue_chan(), cl_te, ast_channel::context, EVENT_DISCONNECT, EVENT_RELEASE, EVENT_RELEASE_COMPLETE, ast_channel::exten, free, ast_channel::hangupcause, hanguptone_indicate(), INFO_PI_INBAND_AVAILABLE, 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_lib_release(), misdn_lib_send_event(), MISDN_NOTHING, MISDN_PRECONNECTED, MISDN_PROCEEDING, MISDN_PROGRESS, MISDN_RELEASED, ast_channel::name, chan_list::need_busy, misdn_bchannel::need_disconnect, chan_list::need_hangup, chan_list::need_queue_hangup, misdn_bchannel::need_release, misdn_bchannel::need_release_complete, misdn_bchannel::nt, ORG_AST, chan_list::originator, misdn_bchannel::out_cause, pbx_builtin_getvar_helper(), misdn_bchannel::pid, chan_list::pipe, misdn_bchannel::port, release_chan(), release_lock, start_bc_tones(), chan_list::state, stop_bc_tones(), misdn_bchannel::uu, and misdn_bchannel::uulen.
02531 { 02532 struct chan_list *p; 02533 struct misdn_bchannel *bc = NULL; 02534 const char *varcause = NULL; 02535 02536 ast_log(LOG_DEBUG, "misdn_hangup(%s)\n", ast->name); 02537 02538 if (!ast || ! (p=MISDN_ASTERISK_TECH_PVT(ast) ) ) return -1; 02539 02540 if (!p) { 02541 chan_misdn_log(3, 0, "misdn_hangup called, without chan_list obj.\n"); 02542 return 0 ; 02543 } 02544 02545 bc = p->bc; 02546 02547 if (bc) { 02548 const char *tmp=pbx_builtin_getvar_helper(ast,"MISDN_USERUSER"); 02549 if (tmp) { 02550 ast_log(LOG_NOTICE, "MISDN_USERUSER: %s\n", tmp); 02551 strcpy(bc->uu, tmp); 02552 bc->uulen=strlen(bc->uu); 02553 } 02554 } 02555 02556 MISDN_ASTERISK_TECH_PVT(ast) = NULL; 02557 p->ast = NULL; 02558 02559 if (ast->_state == AST_STATE_RESERVED || 02560 p->state == MISDN_NOTHING || 02561 p->state == MISDN_HOLDED || 02562 p->state == MISDN_HOLD_DISCONNECT ) { 02563 02564 CLEAN_CH: 02565 /* between request and call */ 02566 ast_log(LOG_DEBUG, "State Reserved (or nothing) => chanIsAvail\n"); 02567 MISDN_ASTERISK_TECH_PVT(ast) = NULL; 02568 02569 ast_mutex_lock(&release_lock); 02570 cl_dequeue_chan(&cl_te, p); 02571 close(p->pipe[0]); 02572 close(p->pipe[1]); 02573 free(p); 02574 ast_mutex_unlock(&release_lock); 02575 02576 if (bc) 02577 misdn_lib_release(bc); 02578 02579 return 0; 02580 } 02581 02582 if (!bc) { 02583 ast_log(LOG_WARNING, "Hangup with private but no bc ? state:%s l3id:%x\n", misdn_get_ch_state(p), p->l3id); 02584 goto CLEAN_CH; 02585 } 02586 02587 02588 p->need_hangup = 0; 02589 p->need_queue_hangup = 0; 02590 p->need_busy = 0; 02591 02592 02593 if (!p->bc->nt) 02594 stop_bc_tones(p); 02595 02596 bc->out_cause = ast->hangupcause ? ast->hangupcause : AST_CAUSE_NORMAL_CLEARING; 02597 02598 if ((varcause = pbx_builtin_getvar_helper(ast, "HANGUPCAUSE")) || 02599 (varcause = pbx_builtin_getvar_helper(ast, "PRI_CAUSE"))) { 02600 int tmpcause = atoi(varcause); 02601 bc->out_cause = tmpcause ? tmpcause : AST_CAUSE_NORMAL_CLEARING; 02602 } 02603 02604 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.cid_num, misdn_get_ch_state(p)); 02605 chan_misdn_log(3, bc->port, " --> l3id:%x\n", p->l3id); 02606 chan_misdn_log(3, bc->port, " --> cause:%d\n", bc->cause); 02607 chan_misdn_log(2, bc->port, " --> out_cause:%d\n", bc->out_cause); 02608 chan_misdn_log(2, bc->port, " --> state:%s\n", misdn_get_ch_state(p)); 02609 02610 switch (p->state) { 02611 case MISDN_INCOMING_SETUP: 02612 /* This is the only place in misdn_hangup, where we 02613 * can call release_chan, else it might create lot's of trouble 02614 * */ 02615 ast_log(LOG_NOTICE, "release channel, in INCOMING_SETUP state.. no other events happened\n"); 02616 release_chan(bc); 02617 02618 p->state = MISDN_CLEANING; 02619 if (bc->need_release_complete) 02620 misdn_lib_send_event( bc, EVENT_RELEASE_COMPLETE); 02621 break; 02622 case MISDN_HOLDED: 02623 case MISDN_DIALING: 02624 start_bc_tones(p); 02625 hanguptone_indicate(p); 02626 02627 if (bc->need_disconnect) 02628 misdn_lib_send_event( bc, EVENT_DISCONNECT); 02629 break; 02630 case MISDN_CALLING_ACKNOWLEDGE: 02631 start_bc_tones(p); 02632 hanguptone_indicate(p); 02633 02634 if (bc->need_disconnect) 02635 misdn_lib_send_event( bc, EVENT_DISCONNECT); 02636 break; 02637 02638 case MISDN_CALLING: 02639 case MISDN_ALERTING: 02640 case MISDN_PROGRESS: 02641 case MISDN_PROCEEDING: 02642 if (p->originator != ORG_AST) 02643 hanguptone_indicate(p); 02644 02645 /*p->state=MISDN_CLEANING;*/ 02646 if (bc->need_disconnect) 02647 misdn_lib_send_event( bc, EVENT_DISCONNECT); 02648 break; 02649 case MISDN_CONNECTED: 02650 case MISDN_PRECONNECTED: 02651 /* Alerting or Disconnect */ 02652 if (p->bc->nt) { 02653 start_bc_tones(p); 02654 hanguptone_indicate(p); 02655 p->bc->progress_indicator = INFO_PI_INBAND_AVAILABLE; 02656 } 02657 if (bc->need_disconnect) 02658 misdn_lib_send_event( bc, EVENT_DISCONNECT); 02659 02660 /*p->state=MISDN_CLEANING;*/ 02661 break; 02662 case MISDN_DISCONNECTED: 02663 if (bc->need_release) 02664 misdn_lib_send_event( bc, EVENT_RELEASE); 02665 p->state = MISDN_CLEANING; /* MISDN_HUNGUP_FROM_AST; */ 02666 break; 02667 02668 case MISDN_RELEASED: 02669 case MISDN_CLEANING: 02670 p->state = MISDN_CLEANING; 02671 break; 02672 02673 case MISDN_BUSY: 02674 break; 02675 02676 case MISDN_HOLD_DISCONNECT: 02677 /* need to send release here */ 02678 chan_misdn_log(1, bc->port, " --> cause %d\n", bc->cause); 02679 chan_misdn_log(1, bc->port, " --> out_cause %d\n", bc->out_cause); 02680 02681 bc->out_cause = -1; 02682 if (bc->need_release) 02683 misdn_lib_send_event(bc, EVENT_RELEASE); 02684 p->state = MISDN_CLEANING; 02685 break; 02686 default: 02687 if (bc->nt) { 02688 bc->out_cause = -1; 02689 if (bc->need_release) 02690 misdn_lib_send_event(bc, EVENT_RELEASE); 02691 p->state = MISDN_CLEANING; 02692 } else { 02693 if (bc->need_disconnect) 02694 misdn_lib_send_event(bc, EVENT_DISCONNECT); 02695 } 02696 } 02697 02698 p->state = MISDN_CLEANING; 02699 02700 chan_misdn_log(3, bc->port, " --> Channel: %s hanguped new state:%s\n", ast->name, misdn_get_ch_state(p)); 02701 02702 return 0; 02703 }
static int misdn_indication | ( | struct ast_channel * | ast, | |
int | cond, | |||
const void * | data, | |||
size_t | datalen | |||
) | [static] |
Definition at line 2409 of file chan_misdn.c.
References chan_list::ast, AST_CAUSE_SWITCH_CONGESTION, AST_CAUSE_USER_BUSY, 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_moh_start(), ast_moh_stop(), ast_setstate(), AST_STATE_BUSY, AST_STATE_RING, chan_list::bc, chan_misdn_log(), EVENT_ALERTING, EVENT_DISCONNECT, EVENT_PROCEEDING, EVENT_PROGRESS, ast_channel::exten, hanguptone_indicate(), chan_list::incoming_early_audio, LOG_WARNING, MISDN_ALERTING, MISDN_ASTERISK_TECH_PVT, MISDN_CONNECTED, misdn_inband_avail(), misdn_lib_send_event(), misdn_bchannel::nt, ORG_MISDN, chan_list::originator, chan_list::other_ch, misdn_bchannel::out_cause, misdn_bchannel::pid, misdn_bchannel::port, start_bc_tones(), chan_list::state, and stop_indicate().
02410 { 02411 struct chan_list *p; 02412 02413 if (!ast || ! (p=MISDN_ASTERISK_TECH_PVT(ast))) { 02414 ast_log(LOG_WARNING, "Returned -1 in misdn_indication\n"); 02415 return -1; 02416 } 02417 02418 if (!p->bc ) { 02419 chan_misdn_log(1, 0, "* IND : Indication from %s\n", ast->exten); 02420 ast_log(LOG_WARNING, "Private Pointer but no bc ?\n"); 02421 return -1; 02422 } 02423 02424 chan_misdn_log(5, p->bc->port, "* IND : Indication [%d] from %s\n", cond, ast->exten); 02425 02426 switch (cond) { 02427 case AST_CONTROL_BUSY: 02428 chan_misdn_log(1, p->bc->port, "* IND :\tbusy pid:%d\n", p->bc ? p->bc->pid : -1); 02429 ast_setstate(ast, AST_STATE_BUSY); 02430 02431 p->bc->out_cause = AST_CAUSE_USER_BUSY; 02432 if (p->state != MISDN_CONNECTED) { 02433 start_bc_tones(p); 02434 misdn_lib_send_event( p->bc, EVENT_DISCONNECT); 02435 } 02436 return -1; 02437 case AST_CONTROL_RING: 02438 chan_misdn_log(1, p->bc->port, "* IND :\tring pid:%d\n", p->bc ? p->bc->pid : -1); 02439 return -1; 02440 case AST_CONTROL_RINGING: 02441 chan_misdn_log(1, p->bc->port, "* IND :\tringing pid:%d\n", p->bc ? p->bc->pid : -1); 02442 switch (p->state) { 02443 case MISDN_ALERTING: 02444 chan_misdn_log(2, p->bc->port, " --> * IND :\tringing pid:%d but I was Ringing before, so ignoring it\n", p->bc ? p->bc->pid : -1); 02445 break; 02446 case MISDN_CONNECTED: 02447 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); 02448 return -1; 02449 default: 02450 p->state = MISDN_ALERTING; 02451 chan_misdn_log(2, p->bc->port, " --> * IND :\tringing pid:%d\n", p->bc ? p->bc->pid : -1); 02452 misdn_lib_send_event( p->bc, EVENT_ALERTING); 02453 02454 if (p->other_ch && p->other_ch->bc) { 02455 if (misdn_inband_avail(p->other_ch->bc)) { 02456 chan_misdn_log(2, p->bc->port, " --> other End is mISDN and has inband info available\n"); 02457 break; 02458 } 02459 02460 if (!p->other_ch->bc->nt) { 02461 chan_misdn_log(2, p->bc->port, " --> other End is mISDN TE so it has inband info for sure (?)\n"); 02462 break; 02463 } 02464 } 02465 02466 chan_misdn_log(3, p->bc->port, " --> * SEND: State Ring pid:%d\n", p->bc ? p->bc->pid : -1); 02467 ast_setstate(ast, AST_STATE_RING); 02468 02469 if (!p->bc->nt && (p->originator == ORG_MISDN) && !p->incoming_early_audio) 02470 chan_misdn_log(2, p->bc->port, " --> incoming_early_audio off\n"); 02471 else 02472 return -1; 02473 } 02474 break; 02475 case AST_CONTROL_ANSWER: 02476 chan_misdn_log(1, p->bc->port, " --> * IND :\tanswer pid:%d\n", p->bc ? p->bc->pid : -1); 02477 start_bc_tones(p); 02478 break; 02479 case AST_CONTROL_TAKEOFFHOOK: 02480 chan_misdn_log(1, p->bc->port, " --> *\ttakeoffhook pid:%d\n", p->bc ? p->bc->pid : -1); 02481 return -1; 02482 case AST_CONTROL_OFFHOOK: 02483 chan_misdn_log(1, p->bc->port, " --> *\toffhook pid:%d\n", p->bc ? p->bc->pid : -1); 02484 return -1; 02485 case AST_CONTROL_FLASH: 02486 chan_misdn_log(1, p->bc->port, " --> *\tflash pid:%d\n", p->bc ? p->bc->pid : -1); 02487 break; 02488 case AST_CONTROL_PROGRESS: 02489 chan_misdn_log(1, p->bc->port, " --> * IND :\tprogress pid:%d\n", p->bc ? p->bc->pid : -1); 02490 misdn_lib_send_event( p->bc, EVENT_PROGRESS); 02491 break; 02492 case AST_CONTROL_PROCEEDING: 02493 chan_misdn_log(1, p->bc->port, " --> * IND :\tproceeding pid:%d\n", p->bc ? p->bc->pid : -1); 02494 misdn_lib_send_event( p->bc, EVENT_PROCEEDING); 02495 break; 02496 case AST_CONTROL_CONGESTION: 02497 chan_misdn_log(1, p->bc->port, " --> * IND :\tcongestion pid:%d\n", p->bc ? p->bc->pid : -1); 02498 02499 p->bc->out_cause = AST_CAUSE_SWITCH_CONGESTION; 02500 start_bc_tones(p); 02501 misdn_lib_send_event( p->bc, EVENT_DISCONNECT); 02502 02503 if (p->bc->nt) { 02504 hanguptone_indicate(p); 02505 } 02506 break; 02507 case -1 : 02508 chan_misdn_log(1, p->bc->port, " --> * IND :\t-1! (stop indication) pid:%d\n", p->bc ? p->bc->pid : -1); 02509 02510 stop_indicate(p); 02511 02512 if (p->state == MISDN_CONNECTED) 02513 start_bc_tones(p); 02514 break; 02515 case AST_CONTROL_HOLD: 02516 ast_moh_start(ast, data, p->mohinterpret); 02517 chan_misdn_log(1, p->bc->port, " --> *\tHOLD pid:%d\n", p->bc ? p->bc->pid : -1); 02518 break; 02519 case AST_CONTROL_UNHOLD: 02520 ast_moh_stop(ast); 02521 chan_misdn_log(1, p->bc->port, " --> *\tUNHOLD pid:%d\n", p->bc ? p->bc->pid : -1); 02522 break; 02523 default: 02524 chan_misdn_log(1, p->bc->port, " --> * Unknown Indication:%d pid:%d\n", cond, p->bc ? p->bc->pid : -1); 02525 } 02526 02527 return 0; 02528 }
void misdn_jb_destroy | ( | struct misdn_jb * | jb | ) |
frees the data and destroys the given jitterbuffer struct
Definition at line 5595 of file chan_misdn.c.
References ast_mutex_destroy, free, misdn_jb::mutexjb, misdn_jb::ok, and misdn_jb::samples.
Referenced by config_jitterbuffer(), and release_chan().
05596 { 05597 ast_mutex_destroy(&jb->mutexjb); 05598 05599 free(jb->ok); 05600 free(jb->samples); 05601 free(jb); 05602 }
int misdn_jb_empty | ( | struct misdn_jb * | jb, | |
char * | data, | |||
int | len | |||
) |
gets len bytes out of the jitterbuffer if available, else only the available data is returned and the return value indicates the number of data.
Definition at line 5665 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().
05666 { 05667 int i, wp, rp, read = 0; 05668 05669 ast_mutex_lock(&jb->mutexjb); 05670 05671 rp = jb->rp; 05672 wp = jb->wp; 05673 05674 if (jb->state_empty) { 05675 for (i = 0; i < len; i++) { 05676 if (wp == rp) { 05677 jb->rp = rp; 05678 jb->state_empty = 0; 05679 05680 ast_mutex_unlock(&jb->mutexjb); 05681 05682 return read; 05683 } else { 05684 if (jb->ok[rp] == 1) { 05685 data[i] = jb->samples[rp]; 05686 jb->ok[rp] = 0; 05687 rp = (rp != jb->size - 1) ? rp + 1 : 0; 05688 read += 1; 05689 } 05690 } 05691 } 05692 05693 if (wp >= rp) 05694 jb->state_buffer = wp - rp; 05695 else 05696 jb->state_buffer = jb->size - rp + wp; 05697 chan_misdn_log(9, 0, "misdn_jb_empty: read:%d | Buffer status:%d p:%p\n", len, jb->state_buffer, jb); 05698 05699 jb->rp = rp; 05700 } else 05701 chan_misdn_log(9, 0, "misdn_jb_empty: Wait...requested:%d p:%p\n", len, jb); 05702 05703 ast_mutex_unlock(&jb->mutexjb); 05704 05705 return read; 05706 }
int misdn_jb_fill | ( | struct misdn_jb * | jb, | |
const char * | data, | |||
int | len | |||
) |
fills the jitterbuffer with len data returns < 0 if there was an error (buffer overrun).
Definition at line 5606 of file chan_misdn.c.
References ast_mutex_lock, ast_mutex_unlock, chan_misdn_log(), misdn_jb::mutexjb, misdn_jb::ok, misdn_jb::rp, misdn_jb::samples, misdn_jb::size, misdn_jb::state_buffer, misdn_jb::state_empty, misdn_jb::state_full, misdn_jb::upper_threshold, and misdn_jb::wp.
05607 { 05608 int i, j, rp, wp; 05609 05610 if (!jb || ! data) 05611 return 0; 05612 05613 ast_mutex_lock(&jb->mutexjb); 05614 05615 wp = jb->wp; 05616 rp = jb->rp; 05617 05618 for (i = 0; i < len; i++) { 05619 jb->samples[wp] = data[i]; 05620 jb->ok[wp] = 1; 05621 wp = (wp != jb->size - 1) ? wp + 1 : 0; 05622 05623 if (wp == jb->rp) 05624 jb->state_full = 1; 05625 } 05626 05627 if (wp >= rp) 05628 jb->state_buffer = wp - rp; 05629 else 05630 jb->state_buffer = jb->size - rp + wp; 05631 chan_misdn_log(9, 0, "misdn_jb_fill: written:%d | Buffer status:%d p:%p\n", len, jb->state_buffer, jb); 05632 05633 if (jb->state_full) { 05634 jb->wp = wp; 05635 05636 rp = wp; 05637 for (j = 0; j < jb->upper_threshold; j++) 05638 rp = (rp != 0) ? rp - 1 : jb->size - 1; 05639 jb->rp = rp; 05640 jb->state_full = 0; 05641 jb->state_empty = 1; 05642 05643 ast_mutex_unlock(&jb->mutexjb); 05644 05645 return -1; 05646 } 05647 05648 if (!jb->state_empty) { 05649 jb->bytes_wrote += len; 05650 if (jb->bytes_wrote >= jb->upper_threshold) { 05651 jb->state_empty = 1; 05652 jb->bytes_wrote = 0; 05653 } 05654 } 05655 jb->wp = wp; 05656 05657 ast_mutex_unlock(&jb->mutexjb); 05658 05659 return 0; 05660 }
struct misdn_jb * misdn_jb_init | ( | int | size, | |
int | upper_threshold | |||
) |
allocates the jb-structure and initialize the elements
Definition at line 5554 of file chan_misdn.c.
References ast_mutex_init, misdn_jb::bytes_wrote, chan_misdn_log(), free, 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().
05555 { 05556 int i; 05557 struct misdn_jb *jb; 05558 05559 jb = malloc(sizeof(struct misdn_jb)); 05560 if (!jb) { 05561 chan_misdn_log(-1, 0, "No free Mem for jb\n"); 05562 return NULL; 05563 } 05564 jb->size = size; 05565 jb->upper_threshold = upper_threshold; 05566 jb->wp = 0; 05567 jb->rp = 0; 05568 jb->state_full = 0; 05569 jb->state_empty = 0; 05570 jb->bytes_wrote = 0; 05571 jb->samples = malloc(size * sizeof(char)); 05572 if (!jb->samples) { 05573 free(jb); 05574 chan_misdn_log(-1, 0, "No free Mem for jb->samples\n"); 05575 return NULL; 05576 } 05577 05578 jb->ok = malloc(size * sizeof(char)); 05579 if (!jb->ok) { 05580 free(jb->samples); 05581 free(jb); 05582 chan_misdn_log(-1, 0, "No free Mem for jb->ok\n"); 05583 return NULL; 05584 } 05585 05586 for (i = 0; i < size; i++) 05587 jb->ok[i] = 0; 05588 05589 ast_mutex_init(&jb->mutexjb); 05590 05591 return jb; 05592 }
static int misdn_l1_task | ( | const void * | data | ) | [static] |
Definition at line 825 of file chan_misdn.c.
References chan_misdn_log(), and misdn_lib_isdn_l1watcher().
Referenced by load_module().
00826 { 00827 misdn_lib_isdn_l1watcher(*(int *)data); 00828 chan_misdn_log(5, *(int *)data, "L1watcher timeout\n"); 00829 return 1; 00830 }
static struct ast_channel * misdn_new | ( | struct chan_list * | cl, | |
int | state, | |||
char * | exten, | |||
char * | callerid, | |||
int | format, | |||
int | port, | |||
int | c | |||
) | [static] |
Definition at line 3448 of file chan_misdn.c.
References ast_callerid_parse(), ast_channel_alloc(), ast_copy_string(), ast_jb_configure(), AST_STATE_RING, ast_strdup, chan_misdn_log(), ast_channel::cid, ast_callerid::cid_ani, cid_name, cid_num, ast_channel::exten, ast_channel::fds, misdn_cfg_get(), misdn_cfg_get_next_port(), MISDN_GEN_BRIDGING, misdn_get_global_jbconf(), misdn_lib_port_is_pri(), misdn_tech, misdn_tech_wo_bridge, misdn_type, ast_channel::nativeformats, chan_list::pipe, prefformat, ast_channel::priority, ast_channel::rawreadformat, ast_channel::rawwriteformat, ast_channel::readformat, ast_channel::rings, ast_channel::tech, ast_channel::tech_pvt, and ast_channel::writeformat.
Referenced by cb_events(), and misdn_request().
03449 { 03450 struct ast_channel *tmp; 03451 char *cid_name = 0, *cid_num = 0; 03452 int chan_offset = 0; 03453 int tmp_port = misdn_cfg_get_next_port(0); 03454 int bridging; 03455 03456 for (; tmp_port > 0; tmp_port = misdn_cfg_get_next_port(tmp_port)) { 03457 if (tmp_port == port) 03458 break; 03459 chan_offset += misdn_lib_port_is_pri(tmp_port) ? 30 : 2; 03460 } 03461 if (c < 0) 03462 c = 0; 03463 03464 if (callerid) { 03465 ast_callerid_parse(callerid, &cid_name, &cid_num); 03466 } 03467 03468 tmp = ast_channel_alloc(1, state, cid_num, cid_name, "", exten, "", 0, "%s/%d-u%d", misdn_type, chan_offset + c, glob_channel++); 03469 if (tmp) { 03470 chan_misdn_log(2, 0, " --> * NEW CHANNEL dad:%s oad:%s\n", exten, callerid); 03471 03472 tmp->nativeformats = prefformat; 03473 03474 tmp->readformat = format; 03475 tmp->rawreadformat = format; 03476 tmp->writeformat = format; 03477 tmp->rawwriteformat = format; 03478 03479 tmp->tech_pvt = chlist; 03480 03481 misdn_cfg_get(0, MISDN_GEN_BRIDGING, &bridging, sizeof(int)); 03482 03483 if (bridging) 03484 tmp->tech = &misdn_tech; 03485 else 03486 tmp->tech = &misdn_tech_wo_bridge; 03487 03488 tmp->writeformat = format; 03489 tmp->readformat = format; 03490 tmp->priority=1; 03491 03492 if (exten) 03493 ast_copy_string(tmp->exten, exten, sizeof(tmp->exten)); 03494 else 03495 chan_misdn_log(1, 0, "misdn_new: no exten given.\n"); 03496 03497 if (callerid) 03498 /* Don't use ast_set_callerid() here because it will 03499 * generate a needless NewCallerID event */ 03500 tmp->cid.cid_ani = ast_strdup(cid_num); 03501 03502 if (pipe(chlist->pipe) < 0) 03503 perror("Pipe failed\n"); 03504 tmp->fds[0] = chlist->pipe[0]; 03505 03506 if (state == AST_STATE_RING) 03507 tmp->rings = 1; 03508 else 03509 tmp->rings = 0; 03510 03511 ast_jb_configure(tmp, misdn_get_global_jbconf()); 03512 } else { 03513 chan_misdn_log(-1, 0, "Unable to allocate channel structure\n"); 03514 } 03515 03516 return tmp; 03517 }
static int misdn_overlap_dial_task | ( | const void * | data | ) | [static] |
Definition at line 832 of file chan_misdn.c.
References chan_list::ast, AST_CAUSE_UNALLOCATED, ast_exists_extension(), ast_mutex_lock, ast_mutex_unlock, ast_strlen_zero(), ast_tvdiff_ms(), ast_tvnow(), chan_list::bc, chan_misdn_log(), chan_list::context, misdn_bchannel::dad, EVENT_DISCONNECT, ast_channel::exten, hanguptone_indicate(), MISDN_CLEANING, MISDN_DIALING, misdn_lib_send_event(), MISDN_WAITING4DIGS, misdn_bchannel::oad, misdn_bchannel::out_cause, chan_list::overlap_dial, chan_list::overlap_dial_task, chan_list::overlap_tv, chan_list::overlap_tv_lock, pbx_start_chan(), misdn_bchannel::port, chan_list::state, and stop_indicate().
Referenced by cb_events().
00833 { 00834 struct timeval tv_end, tv_now; 00835 int diff; 00836 struct chan_list *ch = (struct chan_list *)data; 00837 00838 chan_misdn_log(4, ch->bc->port, "overlap dial task, chan_state: %d\n", ch->state); 00839 00840 if (ch->state != MISDN_WAITING4DIGS) { 00841 ch->overlap_dial_task = -1; 00842 return 0; 00843 } 00844 00845 ast_mutex_lock(&ch->overlap_tv_lock); 00846 tv_end = ch->overlap_tv; 00847 ast_mutex_unlock(&ch->overlap_tv_lock); 00848 00849 tv_end.tv_sec += ch->overlap_dial; 00850 tv_now = ast_tvnow(); 00851 00852 diff = ast_tvdiff_ms(tv_end, tv_now); 00853 00854 if (diff <= 100) { 00855 char *dad=ch->bc->dad, sexten[]="s"; 00856 /* if we are 100ms near the timeout, we are satisfied.. */ 00857 stop_indicate(ch); 00858 00859 if (ast_strlen_zero(ch->bc->dad)) { 00860 dad=sexten; 00861 strcpy(ch->ast->exten, sexten); 00862 } 00863 00864 if (ast_exists_extension(ch->ast, ch->context, dad, 1, ch->bc->oad)) { 00865 ch->state=MISDN_DIALING; 00866 if (pbx_start_chan(ch) < 0) { 00867 chan_misdn_log(-1, ch->bc->port, "ast_pbx_start returned < 0 in misdn_overlap_dial_task\n"); 00868 goto misdn_overlap_dial_task_disconnect; 00869 } 00870 } else { 00871 misdn_overlap_dial_task_disconnect: 00872 hanguptone_indicate(ch); 00873 ch->bc->out_cause = AST_CAUSE_UNALLOCATED; 00874 ch->state=MISDN_CLEANING; 00875 misdn_lib_send_event(ch->bc, EVENT_DISCONNECT); 00876 } 00877 ch->overlap_dial_task = -1; 00878 return 0; 00879 } else 00880 return diff; 00881 }
static int misdn_port_block | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 989 of file chan_misdn.c.
References misdn_lib_port_block(), and RESULT_SHOWUSAGE.
00990 { 00991 int port; 00992 00993 if (argc != 4) 00994 return RESULT_SHOWUSAGE; 00995 00996 port = atoi(argv[3]); 00997 00998 misdn_lib_port_block(port); 00999 01000 return 0; 01001 }
static int misdn_port_down | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1060 of file chan_misdn.c.
References misdn_lib_get_port_down(), and RESULT_SHOWUSAGE.
01061 { 01062 int port; 01063 01064 if (argc != 4) 01065 return RESULT_SHOWUSAGE; 01066 01067 port = atoi(argv[3]); 01068 01069 misdn_lib_get_port_down(port); 01070 01071 return 0; 01072 }
static int misdn_port_unblock | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1003 of file chan_misdn.c.
References misdn_lib_port_unblock(), and RESULT_SHOWUSAGE.
01004 { 01005 int port; 01006 01007 if (argc != 4) 01008 return RESULT_SHOWUSAGE; 01009 01010 port = atoi(argv[3]); 01011 01012 misdn_lib_port_unblock(port); 01013 01014 return 0; 01015 }
static int misdn_port_up | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1046 of file chan_misdn.c.
References misdn_lib_get_port_up(), and RESULT_SHOWUSAGE.
01047 { 01048 int port; 01049 01050 if (argc != 4) 01051 return RESULT_SHOWUSAGE; 01052 01053 port = atoi(argv[3]); 01054 01055 misdn_lib_get_port_up(port); 01056 01057 return 0; 01058 }
static struct ast_frame* misdn_read | ( | struct ast_channel * | ast | ) | [static] |
Definition at line 2777 of file chan_misdn.c.
References chan_list::ast_dsp, AST_FORMAT_ALAW, AST_FRAME_VOICE, chan_list::ast_rd_buf, ast_tv(), ast_tvdiff_ms(), ast_tvnow(), ast_tvzero(), chan_list::bc, chan_misdn_log(), ast_frame::data, ast_frame::datalen, ast_frame::delivery, errno, chan_list::faxdetect, chan_list::faxdetect_timeout, chan_list::faxdetect_tv, chan_list::faxhandled, chan_list::frame, ast_frame::frametype, len(), ast_frame::mallocd, MISDN_ASTERISK_TECH_PVT, MISDN_HOLDED, ast_frame::offset, chan_list::pipe, misdn_bchannel::port, process_ast_dsp(), ast_frame::samples, ast_frame::src, chan_list::state, ast_frame::subclass, and t.
02778 { 02779 struct chan_list *tmp; 02780 fd_set rrfs; 02781 struct timeval tv; 02782 int len, t; 02783 02784 if (!ast) { 02785 chan_misdn_log(1, 0, "misdn_read called without ast\n"); 02786 return NULL; 02787 } 02788 if (!(tmp = MISDN_ASTERISK_TECH_PVT(ast))) { 02789 chan_misdn_log(1, 0, "misdn_read called without ast->pvt\n"); 02790 return NULL; 02791 } 02792 02793 if (!tmp->bc && !(tmp->state == MISDN_HOLDED)) { 02794 chan_misdn_log(1, 0, "misdn_read called without bc\n"); 02795 return NULL; 02796 } 02797 02798 tv.tv_sec=0; 02799 tv.tv_usec=20000; 02800 02801 FD_ZERO(&rrfs); 02802 FD_SET(tmp->pipe[0],&rrfs); 02803 02804 t=select(FD_SETSIZE,&rrfs,NULL, NULL,&tv); 02805 02806 if (!t) { 02807 chan_misdn_log(3, tmp->bc->port, "read Select Timed out\n"); 02808 len=160; 02809 } 02810 02811 if (t<0) { 02812 chan_misdn_log(-1, tmp->bc->port, "Select Error (err=%s)\n",strerror(errno)); 02813 return NULL; 02814 } 02815 02816 if (FD_ISSET(tmp->pipe[0],&rrfs)) { 02817 len=read(tmp->pipe[0],tmp->ast_rd_buf,sizeof(tmp->ast_rd_buf)); 02818 02819 if (len<=0) { 02820 /* we hangup here, since our pipe is closed */ 02821 chan_misdn_log(2,tmp->bc->port,"misdn_read: Pipe closed, hanging up\n"); 02822 return NULL; 02823 } 02824 02825 } else { 02826 return NULL; 02827 } 02828 02829 tmp->frame.frametype = AST_FRAME_VOICE; 02830 tmp->frame.subclass = AST_FORMAT_ALAW; 02831 tmp->frame.datalen = len; 02832 tmp->frame.samples = len; 02833 tmp->frame.mallocd = 0; 02834 tmp->frame.offset = 0; 02835 tmp->frame.delivery = ast_tv(0,0); 02836 tmp->frame.src = NULL; 02837 tmp->frame.data = tmp->ast_rd_buf; 02838 02839 if (tmp->faxdetect && !tmp->faxhandled) { 02840 if (tmp->faxdetect_timeout) { 02841 if (ast_tvzero(tmp->faxdetect_tv)) { 02842 tmp->faxdetect_tv = ast_tvnow(); 02843 chan_misdn_log(2, tmp->bc->port, "faxdetect: starting detection with timeout: %ds ...\n", tmp->faxdetect_timeout); 02844 return process_ast_dsp(tmp, &tmp->frame); 02845 } else { 02846 struct timeval tv_now = ast_tvnow(); 02847 int diff = ast_tvdiff_ms(tv_now, tmp->faxdetect_tv); 02848 if (diff <= (tmp->faxdetect_timeout * 1000)) { 02849 chan_misdn_log(5, tmp->bc->port, "faxdetect: detecting ...\n"); 02850 return process_ast_dsp(tmp, &tmp->frame); 02851 } else { 02852 chan_misdn_log(2, tmp->bc->port, "faxdetect: stopping detection (time ran out) ...\n"); 02853 tmp->faxdetect = 0; 02854 return &tmp->frame; 02855 } 02856 } 02857 } else { 02858 chan_misdn_log(5, tmp->bc->port, "faxdetect: detecting ... (no timeout)\n"); 02859 return process_ast_dsp(tmp, &tmp->frame); 02860 } 02861 } else { 02862 if (tmp->ast_dsp) 02863 return process_ast_dsp(tmp, &tmp->frame); 02864 else 02865 return &tmp->frame; 02866 } 02867 }
static int misdn_reload | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1246 of file chan_misdn.c.
References ast_cli(), and reload_config().
01247 { 01248 ast_cli(fd, "Reloading mISDN configuration\n"); 01249 reload_config(); 01250 return 0; 01251 }
static struct ast_channel* misdn_request | ( | const char * | type, | |
int | format, | |||
void * | data, | |||
int * | cause | |||
) | [static] |
Definition at line 3175 of file chan_misdn.c.
References chan_list::ast, ast_copy_string(), ast_log(), AST_STATE_RESERVED, ast_strdupa, ast_strlen_zero(), chan_list::bc, BUFFERSIZE, chan_misdn_log(), misdn_bchannel::channel, robin_list::channel, cl_queue_chan(), cl_te, misdn_bchannel::dec, ext, get_robin_position(), group, init_chan_list(), LOG_ERROR, LOG_WARNING, METHOD_ROUND_ROBIN, METHOD_STANDARD_DEC, misdn_cfg_get(), misdn_cfg_get_next_port(), misdn_cfg_get_next_port_spin(), MISDN_CFG_GROUPNAME, misdn_cfg_is_group_method(), MISDN_CFG_PMP_L1_CHECK, misdn_lib_get_free_bc(), misdn_lib_get_maxchans(), misdn_lib_port_up(), misdn_new(), misdn_type, chan_list::need_hangup, ORG_AST, misdn_bchannel::port, robin_list::port, and read_config().
03176 { 03177 struct ast_channel *tmp = NULL; 03178 char group[BUFFERSIZE + 1] = ""; 03179 char dial_str[128]; 03180 char *buf2 = ast_strdupa(data); 03181 char *ext; 03182 char *port_str; 03183 char *p = NULL; 03184 int channel = 0; 03185 int port = 0; 03186 struct misdn_bchannel *newbc = NULL; 03187 int dec = 0; 03188 03189 struct chan_list *cl = init_chan_list(ORG_AST); 03190 03191 snprintf(dial_str, sizeof(dial_str), "%s/%s", misdn_type, (char *) data); 03192 03193 /* 03194 * data is ---v 03195 * Dial(mISDN/g:group_name[/extension[/options]]) 03196 * Dial(mISDN/port[:preselected_channel][/extension[/options]]) 03197 * 03198 * The dial extension could be empty if you are using MISDN_KEYPAD 03199 * to control ISDN provider features. 03200 */ 03201 port_str = strsep(&buf2, "/"); 03202 if (!ast_strlen_zero(port_str)) { 03203 if (port_str[0] == 'g' && port_str[1] == ':' ) { 03204 /* We make a group call lets checkout which ports are in my group */ 03205 port_str += 2; 03206 ast_copy_string(group, port_str, sizeof(group)); 03207 chan_misdn_log(2, 0, " --> Group Call group: %s\n", group); 03208 } else if ((p = strchr(port_str, ':'))) { 03209 /* we have a preselected channel */ 03210 *p = 0; 03211 channel = atoi(++p); 03212 port = atoi(port_str); 03213 chan_misdn_log(2, port, " --> Call on preselected Channel (%d).\n", channel); 03214 } else { 03215 port = atoi(port_str); 03216 } 03217 } else { 03218 ast_log(LOG_WARNING, " --> ! IND : Dial(%s) WITHOUT Port or Group, check extensions.conf\n", dial_str); 03219 return NULL; 03220 } 03221 03222 ext = strsep(&buf2, "/"); 03223 if (!ext) { 03224 ext = ""; 03225 } 03226 03227 if (misdn_cfg_is_group_method(group, METHOD_STANDARD_DEC)) { 03228 chan_misdn_log(4, port, " --> STARTING STANDARD DEC...\n"); 03229 dec = 1; 03230 } 03231 03232 if (!ast_strlen_zero(group)) { 03233 char cfg_group[BUFFERSIZE + 1]; 03234 struct robin_list *rr = NULL; 03235 03236 /* Group dial */ 03237 03238 if (misdn_cfg_is_group_method(group, METHOD_ROUND_ROBIN)) { 03239 chan_misdn_log(4, port, " --> STARTING ROUND ROBIN...\n"); 03240 rr = get_robin_position(group); 03241 } 03242 03243 if (rr) { 03244 int port_start = 0; 03245 int port_bak = rr->port; 03246 int chan_bak = rr->channel; 03247 03248 if (!rr->port) 03249 rr->port = misdn_cfg_get_next_port_spin(rr->port); 03250 03251 for (; rr->port > 0; rr->port = misdn_cfg_get_next_port_spin(rr->port)) { 03252 int port_up; 03253 int check; 03254 int max_chan; 03255 int last_chance = 0; 03256 03257 misdn_cfg_get(rr->port, MISDN_CFG_GROUPNAME, cfg_group, BUFFERSIZE); 03258 if (strcasecmp(cfg_group, group)) 03259 continue; 03260 03261 misdn_cfg_get(rr->port, MISDN_CFG_PMP_L1_CHECK, &check, sizeof(int)); 03262 port_up = misdn_lib_port_up(rr->port, check); 03263 03264 if (check && !port_up) 03265 chan_misdn_log(1, rr->port, "L1 is not Up on this Port\n"); 03266 03267 if (check && port_up < 0) 03268 ast_log(LOG_WARNING,"This port (%d) is blocked\n", rr->port); 03269 03270 if ((port_start == rr->port) && (port_up <= 0)) 03271 break; 03272 03273 if (!port_start) 03274 port_start = rr->port; 03275 03276 if (port_up <= 0) 03277 continue; 03278 03279 max_chan = misdn_lib_get_maxchans(rr->port); 03280 03281 for (++rr->channel; !last_chance && rr->channel <= max_chan; ++rr->channel) { 03282 if (rr->port == port_bak && rr->channel == chan_bak) 03283 last_chance = 1; 03284 03285 chan_misdn_log(1, 0, "trying port:%d channel:%d\n", rr->port, rr->channel); 03286 newbc = misdn_lib_get_free_bc(rr->port, rr->channel, 0, 0); 03287 if (newbc) { 03288 chan_misdn_log(4, rr->port, " Success! Found port:%d channel:%d\n", newbc->port, newbc->channel); 03289 if (port_up) 03290 chan_misdn_log(4, rr->port, "portup:%d\n", port_up); 03291 port = rr->port; 03292 break; 03293 } 03294 } 03295 03296 if (newbc || last_chance) 03297 break; 03298 03299 rr->channel = 0; 03300 } 03301 if (!newbc) { 03302 rr->port = port_bak; 03303 rr->channel = chan_bak; 03304 } 03305 } else { 03306 for (port = misdn_cfg_get_next_port(0); port > 0; 03307 port = misdn_cfg_get_next_port(port)) { 03308 03309 misdn_cfg_get(port, MISDN_CFG_GROUPNAME, cfg_group, BUFFERSIZE); 03310 03311 chan_misdn_log(3, port, "Group [%s] Port [%d]\n", group, port); 03312 if (!strcasecmp(cfg_group, group)) { 03313 int port_up; 03314 int check; 03315 misdn_cfg_get(port, MISDN_CFG_PMP_L1_CHECK, &check, sizeof(int)); 03316 port_up = misdn_lib_port_up(port, check); 03317 03318 chan_misdn_log(4, port, "portup:%d\n", port_up); 03319 03320 if (port_up > 0) { 03321 newbc = misdn_lib_get_free_bc(port, 0, 0, dec); 03322 if (newbc) 03323 break; 03324 } 03325 } 03326 } 03327 } 03328 03329 /* Group dial failed ?*/ 03330 if (!newbc) { 03331 ast_log(LOG_WARNING, 03332 "Could not Dial out on group '%s'.\n" 03333 "\tEither the L2 and L1 on all of these ports where DOWN (see 'show application misdn_check_l2l1')\n" 03334 "\tOr there was no free channel on none of the ports\n\n" 03335 , group); 03336 return NULL; 03337 } 03338 } else { 03339 /* 'Normal' Port dial * Port dial */ 03340 if (channel) 03341 chan_misdn_log(1, port, " --> preselected_channel: %d\n", channel); 03342 newbc = misdn_lib_get_free_bc(port, channel, 0, dec); 03343 03344 if (!newbc) { 03345 ast_log(LOG_WARNING, "Could not create channel on port:%d with extensions:%s\n", port, ext); 03346 return NULL; 03347 } 03348 } 03349 03350 03351 /* create ast_channel and link all the objects together */ 03352 cl->bc = newbc; 03353 03354 tmp = misdn_new(cl, AST_STATE_RESERVED, ext, NULL, format, port, channel); 03355 if (!tmp) { 03356 ast_log(LOG_ERROR,"Could not create Asterisk object\n"); 03357 return NULL; 03358 } 03359 03360 cl->ast=tmp; 03361 03362 /* register chan in local list */ 03363 cl_queue_chan(&cl_te, cl) ; 03364 03365 /* fill in the config into the objects */ 03366 read_config(cl, ORG_AST); 03367 03368 /* important */ 03369 cl->need_hangup = 0; 03370 03371 return tmp; 03372 }
static int misdn_restart_pid | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1032 of file chan_misdn.c.
References misdn_lib_pid_restart(), and RESULT_SHOWUSAGE.
01033 { 01034 int pid; 01035 01036 if (argc != 4) 01037 return RESULT_SHOWUSAGE; 01038 01039 pid = atoi(argv[3]); 01040 01041 misdn_lib_pid_restart(pid); 01042 01043 return 0; 01044 }
static int misdn_restart_port | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1018 of file chan_misdn.c.
References misdn_lib_port_restart(), and RESULT_SHOWUSAGE.
01019 { 01020 int port; 01021 01022 if (argc != 4) 01023 return RESULT_SHOWUSAGE; 01024 01025 port = atoi(argv[3]); 01026 01027 misdn_lib_port_restart(port); 01028 01029 return 0; 01030 }
static int misdn_send_cd | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1439 of file chan_misdn.c.
References ast_cli(), ast_copy_string(), chan_list::bc, EVENT_FACILITY, misdn_bchannel::fac_out, get_chan_by_ast_name(), misdn_lib_send_event(), and RESULT_SHOWUSAGE.
01440 { 01441 char *channame; 01442 char *nr; 01443 struct chan_list *tmp; 01444 01445 if (argc != 5) 01446 return RESULT_SHOWUSAGE; 01447 01448 01449 { 01450 channame = argv[3]; 01451 nr = argv[4]; 01452 01453 ast_cli(fd, "Sending Calldeflection (%s) to %s\n", nr, channame); 01454 tmp = get_chan_by_ast_name(channame); 01455 if (!tmp) { 01456 ast_cli(fd, "Sending CD with nr %s to %s failed: Channel does not exist.\n",nr, channame); 01457 return 0; 01458 } 01459 01460 if (strlen(nr) >= 15) { 01461 ast_cli(fd, "Sending CD with nr %s to %s failed: Number too long (up to 15 digits are allowed).\n",nr, channame); 01462 return 0; 01463 } 01464 tmp->bc->fac_out.Function = Fac_CD; 01465 ast_copy_string((char *)tmp->bc->fac_out.u.CDeflection.DeflectedToNumber, nr, sizeof(tmp->bc->fac_out.u.CDeflection.DeflectedToNumber)); 01466 misdn_lib_send_event(tmp->bc, EVENT_FACILITY); 01467 } 01468 01469 return 0; 01470 }
static int misdn_send_digit | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1492 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().
01493 { 01494 char *channame; 01495 char *msg; 01496 struct chan_list *tmp; 01497 int i, msglen; 01498 01499 if (argc != 5) 01500 return RESULT_SHOWUSAGE; 01501 01502 channame = argv[3]; 01503 msg = argv[4]; 01504 msglen = strlen(msg); 01505 01506 ast_cli(fd, "Sending %s to %s\n", msg, channame); 01507 01508 tmp = get_chan_by_ast_name(channame); 01509 if (!tmp) { 01510 ast_cli(fd, "Sending %s to %s failed Channel does not exist\n", msg, channame); 01511 return 0; 01512 } 01513 #if 1 01514 for (i = 0; i < msglen; i++) { 01515 ast_cli(fd, "Sending: %c\n", msg[i]); 01516 send_digit_to_chan(tmp, msg[i]); 01517 /* res = ast_safe_sleep(tmp->ast, 250); */ 01518 usleep(250000); 01519 /* res = ast_waitfor(tmp->ast,100); */ 01520 } 01521 #else 01522 ast_dtmf_stream(tmp->ast, NULL, msg, 250); 01523 #endif 01524 01525 return 0; 01526 }
static int misdn_send_display | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1562 of file chan_misdn.c.
References ast_cli(), ast_copy_string(), chan_list::bc, misdn_bchannel::display, EVENT_INFORMATION, get_chan_by_ast_name(), misdn_lib_send_event(), RESULT_FAILURE, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
01563 { 01564 char *channame; 01565 char *msg; 01566 struct chan_list *tmp; 01567 01568 if (argc != 5) 01569 return RESULT_SHOWUSAGE; 01570 01571 channame = argv[3]; 01572 msg = argv[4]; 01573 01574 ast_cli(fd, "Sending %s to %s\n", msg, channame); 01575 tmp = get_chan_by_ast_name(channame); 01576 01577 if (tmp && tmp->bc) { 01578 ast_copy_string(tmp->bc->display, msg, sizeof(tmp->bc->display)); 01579 misdn_lib_send_event(tmp->bc, EVENT_INFORMATION); 01580 } else { 01581 ast_cli(fd, "No such channel %s\n", channame); 01582 return RESULT_FAILURE; 01583 } 01584 01585 return RESULT_SUCCESS; 01586 }
static int misdn_send_restart | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1472 of file chan_misdn.c.
References misdn_lib_send_restart(), and RESULT_SHOWUSAGE.
01473 { 01474 int port; 01475 int channel; 01476 01477 if (argc < 4 || argc > 5) 01478 return RESULT_SHOWUSAGE; 01479 01480 port = atoi(argv[3]); 01481 01482 if (argc == 5) { 01483 channel = atoi(argv[4]); 01484 misdn_lib_send_restart(port, channel); 01485 } else { 01486 misdn_lib_send_restart(port, -1); 01487 } 01488 01489 return 0; 01490 }
static int misdn_send_text | ( | struct ast_channel * | chan, | |
const char * | text | |||
) | [static] |
Definition at line 3375 of file chan_misdn.c.
References ast_copy_string(), ast_log(), chan_list::bc, misdn_bchannel::display, EVENT_INFORMATION, LOG_WARNING, misdn_lib_send_event(), and ast_channel::tech_pvt.
03376 { 03377 struct chan_list *tmp = chan->tech_pvt; 03378 03379 if (tmp && tmp->bc) { 03380 ast_copy_string(tmp->bc->display, text, sizeof(tmp->bc->display)); 03381 misdn_lib_send_event(tmp->bc, EVENT_INFORMATION); 03382 } else { 03383 ast_log(LOG_WARNING, "No chan_list but send_text request?\n"); 03384 return -1; 03385 } 03386 03387 return 0; 03388 }
static int misdn_set_crypt_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 982 of file chan_misdn.c.
References RESULT_SHOWUSAGE.
00983 { 00984 if (argc != 5) return RESULT_SHOWUSAGE; 00985 00986 return 0; 00987 }
static int misdn_set_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 919 of file chan_misdn.c.
References ast_cli(), and RESULT_SHOWUSAGE.
00920 { 00921 int level; 00922 00923 if (argc != 4 && argc != 5 && argc != 6 && argc != 7) 00924 return RESULT_SHOWUSAGE; 00925 00926 level = atoi(argv[3]); 00927 00928 switch (argc) { 00929 case 4: 00930 case 5: 00931 { 00932 int i; 00933 int only = 0; 00934 if (argc == 5) { 00935 if (strncasecmp(argv[4], "only", strlen(argv[4]))) 00936 return RESULT_SHOWUSAGE; 00937 else 00938 only = 1; 00939 } 00940 00941 for (i = 0; i <= max_ports; i++) { 00942 misdn_debug[i] = level; 00943 misdn_debug_only[i] = only; 00944 } 00945 ast_cli(fd, "changing debug level for all ports to %d%s\n",misdn_debug[0], only?" (only)":""); 00946 } 00947 break; 00948 case 6: 00949 case 7: 00950 { 00951 int port; 00952 if (strncasecmp(argv[4], "port", strlen(argv[4]))) 00953 return RESULT_SHOWUSAGE; 00954 port = atoi(argv[5]); 00955 if (port <= 0 || port > max_ports) { 00956 switch (max_ports) { 00957 case 0: 00958 ast_cli(fd, "port number not valid! no ports available so you won't get lucky with any number here...\n"); 00959 break; 00960 case 1: 00961 ast_cli(fd, "port number not valid! only port 1 is available.\n"); 00962 break; 00963 default: 00964 ast_cli(fd, "port number not valid! only ports 1 to %d are available.\n", max_ports); 00965 } 00966 return 0; 00967 } 00968 if (argc == 7) { 00969 if (strncasecmp(argv[6], "only", strlen(argv[6]))) 00970 return RESULT_SHOWUSAGE; 00971 else 00972 misdn_debug_only[port] = 1; 00973 } else 00974 misdn_debug_only[port] = 0; 00975 misdn_debug[port] = level; 00976 ast_cli(fd, "changing debug level to %d%s for port %d\n", misdn_debug[port], misdn_debug_only[port]?" (only)":"", port); 00977 } 00978 } 00979 return 0; 00980 }
static int misdn_set_opt_exec | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Definition at line 5331 of file chan_misdn.c.
References ast_copy_string(), 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, misdn_bchannel::capability, chan_misdn_log(), config_jitterbuffer(), misdn_bchannel::crypt_key, misdn_bchannel::display, DSP_FEATURE_DTMF_DETECT, DSP_FEATURE_FAX_DETECT, misdn_bchannel::ec_deftaps, misdn_bchannel::ec_enable, chan_list::faxdetect, chan_list::faxdetect_timeout, misdn_bchannel::hdlc, chan_list::ignore_dtmf, INFO_CAPABILITY_DIGITAL_UNRESTRICTED, chan_list::jb_len, chan_list::jb_upper_threshold, keys, LOG_WARNING, MISDN_ASTERISK_TECH_PVT, MISDN_CFG_FAXDETECT_TIMEOUT, misdn_cfg_get(), MISDN_GEN_CRYPT_KEYS, misdn_bchannel::nodsp, misdn_bchannel::nojitter, misdn_bchannel::orig, chan_list::originator, misdn_bchannel::port, misdn_bchannel::pres, misdn_bchannel::rxgain, misdn_bchannel::send_dtmf, ast_channel::tech, misdn_bchannel::txgain, and ast_channel_tech::type.
Referenced by load_module(), and misdn_call().
05332 { 05333 struct chan_list *ch = MISDN_ASTERISK_TECH_PVT(chan); 05334 char *tok, *tokb; 05335 int keyidx = 0; 05336 int rxgain = 0; 05337 int txgain = 0; 05338 int change_jitter = 0; 05339 05340 if (strcasecmp(chan->tech->type, "mISDN")) { 05341 ast_log(LOG_WARNING, "misdn_set_opt makes only sense with chan_misdn channels!\n"); 05342 return -1; 05343 } 05344 05345 if (ast_strlen_zero((char *)data)) { 05346 ast_log(LOG_WARNING, "misdn_set_opt Requires arguments\n"); 05347 return -1; 05348 } 05349 05350 for (tok = strtok_r((char*) data, ":", &tokb); 05351 tok; 05352 tok = strtok_r(NULL, ":", &tokb) ) { 05353 int neglect = 0; 05354 05355 if (tok[0] == '!' ) { 05356 neglect = 1; 05357 tok++; 05358 } 05359 05360 switch(tok[0]) { 05361 05362 case 'd' : 05363 ast_copy_string(ch->bc->display, ++tok, sizeof(ch->bc->display)); 05364 chan_misdn_log(1, ch->bc->port, "SETOPT: Display:%s\n", ch->bc->display); 05365 break; 05366 05367 case 'n': 05368 chan_misdn_log(1, ch->bc->port, "SETOPT: No DSP\n"); 05369 ch->bc->nodsp = 1; 05370 break; 05371 05372 case 'j': 05373 chan_misdn_log(1, ch->bc->port, "SETOPT: jitter\n"); 05374 tok++; 05375 change_jitter = 1; 05376 05377 switch ( tok[0] ) { 05378 case 'b': 05379 ch->jb_len = atoi(++tok); 05380 chan_misdn_log(1, ch->bc->port, " --> buffer_len:%d\n", ch->jb_len); 05381 break; 05382 case 't' : 05383 ch->jb_upper_threshold = atoi(++tok); 05384 chan_misdn_log(1, ch->bc->port, " --> upper_threshold:%d\n", ch->jb_upper_threshold); 05385 break; 05386 case 'n': 05387 ch->bc->nojitter = 1; 05388 chan_misdn_log(1, ch->bc->port, " --> nojitter\n"); 05389 break; 05390 default: 05391 ch->jb_len = 4000; 05392 ch->jb_upper_threshold = 0; 05393 chan_misdn_log(1, ch->bc->port, " --> buffer_len:%d (default)\n", ch->jb_len); 05394 chan_misdn_log(1, ch->bc->port, " --> upper_threshold:%d (default)\n", ch->jb_upper_threshold); 05395 } 05396 break; 05397 case 'v': 05398 tok++; 05399 05400 switch (tok[0]) { 05401 case 'r' : 05402 rxgain = atoi(++tok); 05403 if (rxgain < -8) 05404 rxgain = -8; 05405 if (rxgain > 8) 05406 rxgain = 8; 05407 ch->bc->rxgain = rxgain; 05408 chan_misdn_log(1, ch->bc->port, "SETOPT: Volume:%d\n", rxgain); 05409 break; 05410 case 't': 05411 txgain = atoi(++tok); 05412 if (txgain < -8) 05413 txgain = -8; 05414 if (txgain > 8) 05415 txgain = 8; 05416 ch->bc->txgain = txgain; 05417 chan_misdn_log(1, ch->bc->port, "SETOPT: Volume:%d\n", txgain); 05418 break; 05419 } 05420 break; 05421 05422 case 'c': 05423 keyidx = atoi(++tok); 05424 { 05425 char keys[4096]; 05426 char *key = NULL, *tmp = keys; 05427 int i; 05428 misdn_cfg_get(0, MISDN_GEN_CRYPT_KEYS, keys, sizeof(keys)); 05429 05430 for (i = 0; i < keyidx; i++) { 05431 key = strsep(&tmp, ","); 05432 } 05433 05434 if (key) { 05435 ast_copy_string(ch->bc->crypt_key, key, sizeof(ch->bc->crypt_key)); 05436 } 05437 05438 chan_misdn_log(0, ch->bc->port, "SETOPT: crypt with key:%s\n", ch->bc->crypt_key); 05439 break; 05440 } 05441 case 'e': 05442 chan_misdn_log(1, ch->bc->port, "SETOPT: EchoCancel\n"); 05443 05444 if (neglect) { 05445 chan_misdn_log(1, ch->bc->port, " --> disabled\n"); 05446 #ifdef MISDN_1_2 05447 *ch->bc->pipeline = 0; 05448 #else 05449 ch->bc->ec_enable = 0; 05450 #endif 05451 } else { 05452 #ifdef MISDN_1_2 05453 update_pipeline_config(ch->bc); 05454 #else 05455 ch->bc->ec_enable = 1; 05456 ch->bc->orig = ch->originator; 05457 tok++; 05458 if (*tok) { 05459 ch->bc->ec_deftaps = atoi(tok); 05460 } 05461 #endif 05462 } 05463 05464 break; 05465 case 'h': 05466 chan_misdn_log(1, ch->bc->port, "SETOPT: Digital\n"); 05467 05468 if (strlen(tok) > 1 && tok[1] == '1') { 05469 chan_misdn_log(1, ch->bc->port, "SETOPT: HDLC \n"); 05470 if (!ch->bc->hdlc) { 05471 ch->bc->hdlc = 1; 05472 } 05473 } 05474 ch->bc->capability = INFO_CAPABILITY_DIGITAL_UNRESTRICTED; 05475 break; 05476 05477 case 's': 05478 chan_misdn_log(1, ch->bc->port, "SETOPT: Send DTMF\n"); 05479 ch->bc->send_dtmf = 1; 05480 break; 05481 05482 case 'f': 05483 chan_misdn_log(1, ch->bc->port, "SETOPT: Faxdetect\n"); 05484 ch->faxdetect = 1; 05485 misdn_cfg_get(ch->bc->port, MISDN_CFG_FAXDETECT_TIMEOUT, &ch->faxdetect_timeout, sizeof(ch->faxdetect_timeout)); 05486 break; 05487 05488 case 'a': 05489 chan_misdn_log(1, ch->bc->port, "SETOPT: AST_DSP (for DTMF)\n"); 05490 ch->ast_dsp = 1; 05491 break; 05492 05493 case 'p': 05494 chan_misdn_log(1, ch->bc->port, "SETOPT: callerpres: %s\n", &tok[1]); 05495 /* CRICH: callingpres!!! */ 05496 if (strstr(tok,"allowed")) { 05497 ch->bc->pres = 0; 05498 } else if (strstr(tok, "restricted")) { 05499 ch->bc->pres = 1; 05500 } else if (strstr(tok, "not_screened")) { 05501 chan_misdn_log(0, ch->bc->port, "SETOPT: callerpres: not_screened is deprecated\n"); 05502 ch->bc->pres = 1; 05503 } 05504 break; 05505 case 'i' : 05506 chan_misdn_log(1, ch->bc->port, "Ignoring dtmf tones, just use them inband\n"); 05507 ch->ignore_dtmf=1; 05508 break; 05509 default: 05510 break; 05511 } 05512 } 05513 05514 if (change_jitter) 05515 config_jitterbuffer(ch); 05516 05517 if (ch->faxdetect || ch->ast_dsp) { 05518 if (!ch->dsp) 05519 ch->dsp = ast_dsp_new(); 05520 if (ch->dsp) 05521 ast_dsp_set_features(ch->dsp, DSP_FEATURE_DTMF_DETECT| DSP_FEATURE_FAX_DETECT); 05522 if (!ch->trans) 05523 ch->trans = ast_translator_build_path(AST_FORMAT_SLINEAR, AST_FORMAT_ALAW); 05524 } 05525 05526 if (ch->ast_dsp) { 05527 chan_misdn_log(1, ch->bc->port, "SETOPT: with AST_DSP we deactivate mISDN_dsp\n"); 05528 ch->bc->nodsp = 1; 05529 } 05530 05531 return 0; 05532 }
static int misdn_set_tics | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1383 of file chan_misdn.c.
References RESULT_SHOWUSAGE.
01384 { 01385 if (argc != 4) 01386 return RESULT_SHOWUSAGE; 01387 01388 MAXTICS = atoi(argv[3]); 01389 01390 return 0; 01391 }
static int misdn_show_cl | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1356 of file chan_misdn.c.
References chan_list::ast, chan_list::bc, cl_te, ast_channel::name, chan_list::next, print_bc_info(), and RESULT_SHOWUSAGE.
01357 { 01358 struct chan_list *help; 01359 01360 if (argc != 4) 01361 return RESULT_SHOWUSAGE; 01362 01363 help = cl_te; 01364 01365 for (; help; help = help->next) { 01366 struct misdn_bchannel *bc = help->bc; 01367 struct ast_channel *ast = help->ast; 01368 01369 if (bc && ast) { 01370 if (!strcasecmp(ast->name,argv[3])) { 01371 print_bc_info(fd, help, bc); 01372 break; 01373 } 01374 } 01375 } 01376 01377 return 0; 01378 }
static int misdn_show_cls | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1308 of file chan_misdn.c.
References chan_list::ast, ast_cli(), chan_list::bc, hold_info::channel, ast_channel::cid, ast_callerid::cid_num, cl_te, ast_channel::exten, chan_list::hold_info, chan_list::l3id, misdn_dump_chanlist(), MISDN_HOLDED, chan_list::next, misdn_bchannel::pid, hold_info::port, print_bc_info(), and chan_list::state.
01309 { 01310 struct chan_list *help; 01311 01312 help = cl_te; 01313 01314 ast_cli(fd, "Channel List: %p\n", cl_te); 01315 01316 for (; help; help = help->next) { 01317 struct misdn_bchannel *bc = help->bc; 01318 struct ast_channel *ast = help->ast; 01319 if (!ast) { 01320 if (!bc) { 01321 ast_cli(fd, "chan_list obj. with l3id:%x has no bc and no ast Leg\n", help->l3id); 01322 continue; 01323 } 01324 ast_cli(fd, "bc with pid:%d has no Ast Leg\n", bc->pid); 01325 continue; 01326 } 01327 01328 if (misdn_debug[0] > 2) 01329 ast_cli(fd, "Bc:%p Ast:%p\n", bc, ast); 01330 if (bc) { 01331 print_bc_info(fd, help, bc); 01332 } else { 01333 if (help->state == MISDN_HOLDED) { 01334 ast_cli(fd, "ITS A HOLDED BC:\n"); 01335 ast_cli(fd, " --> l3_id: %x\n" 01336 " --> dad:%s oad:%s\n" 01337 " --> hold_port: %d\n" 01338 " --> hold_channel: %d\n", 01339 help->l3id, 01340 ast->exten, 01341 ast->cid.cid_num, 01342 help->hold_info.port, 01343 help->hold_info.channel 01344 ); 01345 } else { 01346 ast_cli(fd, "* Channel in unknown STATE !!! Exten:%s, Callerid:%s\n", ast->exten, ast->cid.cid_num); 01347 } 01348 } 01349 } 01350 01351 misdn_dump_chanlist(); 01352 01353 return 0; 01354 }
static int misdn_show_config | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1097 of file chan_misdn.c.
References ast_cli(), BUFFERSIZE, MISDN_CFG_FIRST, misdn_cfg_get_config_string(), misdn_cfg_get_elem(), misdn_cfg_get_next_port(), misdn_cfg_is_port_valid(), MISDN_CFG_LAST, MISDN_GEN_FIRST, MISDN_GEN_LAST, RESULT_SHOWUSAGE, and show_config_description().
01098 { 01099 char buffer[BUFFERSIZE]; 01100 enum misdn_cfg_elements elem; 01101 int linebreak; 01102 int onlyport = -1; 01103 int ok = 0; 01104 01105 if (argc >= 4) { 01106 if (!strcmp(argv[3], "description")) { 01107 if (argc == 5) { 01108 enum misdn_cfg_elements elem = misdn_cfg_get_elem(argv[4]); 01109 if (elem == MISDN_CFG_FIRST) 01110 ast_cli(fd, "Unknown element: %s\n", argv[4]); 01111 else 01112 show_config_description(fd, elem); 01113 return 0; 01114 } 01115 return RESULT_SHOWUSAGE; 01116 } 01117 if (!strcmp(argv[3], "descriptions")) { 01118 if ((argc == 4) || ((argc == 5) && !strcmp(argv[4], "general"))) { 01119 for (elem = MISDN_GEN_FIRST + 1; elem < MISDN_GEN_LAST; ++elem) { 01120 show_config_description(fd, elem); 01121 ast_cli(fd, "\n"); 01122 } 01123 ok = 1; 01124 } 01125 if ((argc == 4) || ((argc == 5) && !strcmp(argv[4], "ports"))) { 01126 for (elem = MISDN_CFG_FIRST + 1; elem < MISDN_CFG_LAST - 1 /* the ptp hack, remove the -1 when ptp is gone */; ++elem) { 01127 show_config_description(fd, elem); 01128 ast_cli(fd, "\n"); 01129 } 01130 ok = 1; 01131 } 01132 return ok ? 0 : RESULT_SHOWUSAGE; 01133 } 01134 if (!sscanf(argv[3], "%30d", &onlyport) || onlyport < 0) { 01135 ast_cli(fd, "Unknown option: %s\n", argv[3]); 01136 return RESULT_SHOWUSAGE; 01137 } 01138 } 01139 01140 if (argc == 3 || onlyport == 0) { 01141 ast_cli(fd, "Misdn General-Config:\n"); 01142 for (elem = MISDN_GEN_FIRST + 1, linebreak = 1; elem < MISDN_GEN_LAST; elem++, linebreak++) { 01143 misdn_cfg_get_config_string(0, elem, buffer, BUFFERSIZE); 01144 ast_cli(fd, "%-36s%s", buffer, !(linebreak % 2) ? "\n" : ""); 01145 } 01146 ast_cli(fd, "\n"); 01147 } 01148 01149 if (onlyport < 0) { 01150 int port = misdn_cfg_get_next_port(0); 01151 for (; port > 0; port = misdn_cfg_get_next_port(port)) { 01152 ast_cli(fd, "\n[PORT %d]\n", port); 01153 for (elem = MISDN_CFG_FIRST + 1, linebreak = 1; elem < MISDN_CFG_LAST; elem++, linebreak++) { 01154 misdn_cfg_get_config_string(port, elem, buffer, BUFFERSIZE); 01155 ast_cli(fd, "%-36s%s", buffer, !(linebreak % 2) ? "\n" : ""); 01156 } 01157 ast_cli(fd, "\n"); 01158 } 01159 } 01160 01161 if (onlyport > 0) { 01162 if (misdn_cfg_is_port_valid(onlyport)) { 01163 ast_cli(fd, "[PORT %d]\n", onlyport); 01164 for (elem = MISDN_CFG_FIRST + 1, linebreak = 1; elem < MISDN_CFG_LAST; elem++, linebreak++) { 01165 misdn_cfg_get_config_string(onlyport, elem, buffer, BUFFERSIZE); 01166 ast_cli(fd, "%-36s%s", buffer, !(linebreak % 2) ? "\n" : ""); 01167 } 01168 ast_cli(fd, "\n"); 01169 } else { 01170 ast_cli(fd, "Port %d is not active!\n", onlyport); 01171 } 01172 } 01173 01174 return 0; 01175 }
static int misdn_show_port | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1422 of file chan_misdn.c.
References ast_cli(), get_show_stack_details(), misdn_debug, misdn_debug_only, and RESULT_SHOWUSAGE.
01423 { 01424 int port; 01425 char buf[128]; 01426 01427 if (argc != 4) 01428 return RESULT_SHOWUSAGE; 01429 01430 port = atoi(argv[3]); 01431 01432 ast_cli(fd, "BEGIN STACK_LIST:\n"); 01433 get_show_stack_details(port, buf); 01434 ast_cli(fd, " %s Debug:%d%s\n", buf, misdn_debug[port], misdn_debug_only[port] ? "(only)" : ""); 01435 01436 return 0; 01437 }
static int misdn_show_ports_stats | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1408 of file chan_misdn.c.
References ast_cli(), misdn_cfg_get_next_port(), misdn_in_calls, and misdn_out_calls.
01409 { 01410 int port; 01411 01412 ast_cli(fd, "Port\tin_calls\tout_calls\n"); 01413 for (port = misdn_cfg_get_next_port(0); port > 0; 01414 port = misdn_cfg_get_next_port(port)) { 01415 ast_cli(fd, "%d\t%d\t\t%d\n", port, misdn_in_calls[port], misdn_out_calls[port]); 01416 } 01417 ast_cli(fd, "\n"); 01418 01419 return 0; 01420 }
static int misdn_show_stacks | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1393 of file chan_misdn.c.
References ast_cli(), get_show_stack_details(), misdn_cfg_get_next_port(), misdn_debug, and misdn_debug_only.
01394 { 01395 int port; 01396 01397 ast_cli(fd, "BEGIN STACK_LIST:\n"); 01398 for (port = misdn_cfg_get_next_port(0); port > 0; 01399 port = misdn_cfg_get_next_port(port)) { 01400 char buf[128]; 01401 get_show_stack_details(port, buf); 01402 ast_cli(fd, " %s Debug:%d%s\n", buf, misdn_debug[port], misdn_debug_only[port] ? "(only)" : ""); 01403 } 01404 01405 return 0; 01406 }
static int misdn_tasks_add | ( | int | timeout, | |
ast_sched_cb | callback, | |||
const void * | data | |||
) | [static] |
Definition at line 810 of file chan_misdn.c.
References _misdn_tasks_add_variable().
Referenced by load_module().
00811 { 00812 return _misdn_tasks_add_variable(timeout, callback, data, 0); 00813 }
static int misdn_tasks_add_variable | ( | int | timeout, | |
ast_sched_cb | callback, | |||
const void * | data | |||
) | [static] |
Definition at line 815 of file chan_misdn.c.
References _misdn_tasks_add_variable().
Referenced by cb_events().
00816 { 00817 return _misdn_tasks_add_variable(timeout, callback, data, 1); 00818 }
static void misdn_tasks_destroy | ( | void | ) | [static] |
Definition at line 780 of file chan_misdn.c.
References cb_log, chan_misdn_log(), misdn_tasks, and sched_context_destroy().
Referenced by unload_module().
00781 { 00782 if (misdn_tasks) { 00783 chan_misdn_log(4, 0, "Killing misdn_tasks thread\n"); 00784 if ( pthread_cancel(misdn_tasks_thread) == 0 ) { 00785 cb_log(4, 0, "Joining misdn_tasks thread\n"); 00786 pthread_join(misdn_tasks_thread, NULL); 00787 } 00788 sched_context_destroy(misdn_tasks); 00789 } 00790 }
static void misdn_tasks_init | ( | void | ) | [static] |
Definition at line 761 of file chan_misdn.c.
References chan_misdn_log(), misdn_tasks, misdn_tasks_thread_func(), pthread_create, and sched_context_create().
Referenced by _misdn_tasks_add_variable().
00762 { 00763 sem_t blocker; 00764 int i = 5; 00765 00766 if (sem_init(&blocker, 0, 0)) { 00767 perror("chan_misdn: Failed to initialize semaphore!"); 00768 exit(1); 00769 } 00770 00771 chan_misdn_log(4, 0, "Starting misdn_tasks thread\n"); 00772 00773 misdn_tasks = sched_context_create(); 00774 pthread_create(&misdn_tasks_thread, NULL, misdn_tasks_thread_func, &blocker); 00775 00776 while (sem_wait(&blocker) && --i); 00777 sem_destroy(&blocker); 00778 }
static void misdn_tasks_remove | ( | int | task_id | ) | [static] |
Definition at line 820 of file chan_misdn.c.
References AST_SCHED_DEL, and misdn_tasks.
Referenced by release_chan().
00821 { 00822 AST_SCHED_DEL(misdn_tasks, task_id); 00823 }
static void* misdn_tasks_thread_func | ( | void * | data | ) | [static] |
Definition at line 737 of file chan_misdn.c.
References ast_sched_runq(), ast_sched_wait(), chan_misdn_log(), misdn_tasks, and sighandler().
Referenced by misdn_tasks_init().
00738 { 00739 int wait; 00740 struct sigaction sa; 00741 00742 sa.sa_handler = sighandler; 00743 sa.sa_flags = SA_NODEFER; 00744 sigemptyset(&sa.sa_mask); 00745 sigaddset(&sa.sa_mask, SIGUSR1); 00746 sigaction(SIGUSR1, &sa, NULL); 00747 00748 sem_post((sem_t *)data); 00749 00750 while (1) { 00751 wait = ast_sched_wait(misdn_tasks); 00752 if (wait < 0) 00753 wait = 8000; 00754 if (poll(NULL, 0, wait) < 0) 00755 chan_misdn_log(4, 0, "Waking up misdn_tasks thread\n"); 00756 ast_sched_runq(misdn_tasks); 00757 } 00758 return NULL; 00759 }
static void misdn_tasks_wakeup | ( | void | ) | [inline, static] |
Definition at line 792 of file chan_misdn.c.
Referenced by _misdn_tasks_add_variable().
00793 { 00794 pthread_kill(misdn_tasks_thread, SIGUSR1); 00795 }
static int misdn_toggle_echocancel | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1528 of file chan_misdn.c.
References ast_cli(), chan_list::bc, get_chan_by_ast_name(), manager_ec_disable(), manager_ec_enable(), RESULT_SHOWUSAGE, chan_list::toggle_ec, and update_ec_config().
01529 { 01530 char *channame; 01531 struct chan_list *tmp; 01532 01533 if (argc != 4) 01534 return RESULT_SHOWUSAGE; 01535 01536 channame = argv[3]; 01537 01538 ast_cli(fd, "Toggling EchoCancel on %s\n", channame); 01539 01540 tmp = get_chan_by_ast_name(channame); 01541 if (!tmp) { 01542 ast_cli(fd, "Toggling EchoCancel %s failed Channel does not exist\n", channame); 01543 return 0; 01544 } 01545 01546 tmp->toggle_ec = tmp->toggle_ec ? 0 : 1; 01547 01548 if (tmp->toggle_ec) { 01549 #ifdef MISDN_1_2 01550 update_pipeline_config(tmp->bc); 01551 #else 01552 update_ec_config(tmp->bc); 01553 #endif 01554 manager_ec_enable(tmp->bc); 01555 } else { 01556 manager_ec_disable(tmp->bc); 01557 } 01558 01559 return 0; 01560 }
static void misdn_transfer_bc | ( | struct chan_list * | tmp_ch, | |
struct chan_list * | holded_chan | |||
) | [static] |
Definition at line 3744 of file chan_misdn.c.
References chan_list::ast, ast_bridged_channel(), 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().
03745 { 03746 chan_misdn_log(4, 0, "TRANSFERRING %s to %s\n", holded_chan->ast->name, tmp_ch->ast->name); 03747 03748 tmp_ch->state = MISDN_HOLD_DISCONNECT; 03749 03750 ast_moh_stop(ast_bridged_channel(holded_chan->ast)); 03751 03752 holded_chan->state=MISDN_CONNECTED; 03753 /* misdn_lib_transfer(holded_chan->bc); */ 03754 ast_channel_masquerade(holded_chan->ast, ast_bridged_channel(tmp_ch->ast)); 03755 }
static int misdn_write | ( | struct ast_channel * | ast, | |
struct ast_frame * | frame | |||
) | [static] |
Definition at line 2870 of file chan_misdn.c.
References misdn_bchannel::addr, chan_list::ast, ast_log(), chan_list::bc, misdn_bchannel::bc_state, BCHAN_ACTIVATED, BCHAN_BRIDGED, chan_misdn_log(), ast_channel::cid, ast_callerid::cid_num, ast_frame::data, chan_list::dropped_frame_cnt, ast_channel::exten, chan_list::frame, misdn_bchannel::l3_id, LOG_WARNING, MISDN_ASTERISK_TECH_PVT, misdn_get_ch_state(), MISDN_HOLDED, misdn_lib_tone_generator_start(), chan_list::notxtone, misdn_bchannel::port, prefformat, ast_frame::samples, ast_frame::src, chan_list::state, ast_frame::subclass, and chan_list::ts.
02871 { 02872 struct chan_list *ch; 02873 int i = 0; 02874 02875 if (!ast || ! (ch = MISDN_ASTERISK_TECH_PVT(ast)) ) return -1; 02876 02877 if (ch->state == MISDN_HOLDED) { 02878 chan_misdn_log(7, 0, "misdn_write: Returning because holded\n"); 02879 return 0; 02880 } 02881 02882 if (!ch->bc ) { 02883 ast_log(LOG_WARNING, "private but no bc\n"); 02884 return -1; 02885 } 02886 02887 if (ch->notxtone) { 02888 chan_misdn_log(7, ch->bc->port, "misdn_write: Returning because notxtone\n"); 02889 return 0; 02890 } 02891 02892 02893 if (!frame->subclass) { 02894 chan_misdn_log(4, ch->bc->port, "misdn_write: * prods us\n"); 02895 return 0; 02896 } 02897 02898 if (!(frame->subclass & prefformat)) { 02899 02900 chan_misdn_log(-1, ch->bc->port, "Got Unsupported Frame with Format:%d\n", frame->subclass); 02901 return 0; 02902 } 02903 02904 02905 if (!frame->samples ) { 02906 chan_misdn_log(4, ch->bc->port, "misdn_write: zero write\n"); 02907 02908 if (!strcmp(frame->src,"ast_prod")) { 02909 chan_misdn_log(1, ch->bc->port, "misdn_write: state (%s) prodded.\n", misdn_get_ch_state(ch)); 02910 02911 if (ch->ts) { 02912 chan_misdn_log(4, ch->bc->port, "Starting Playtones\n"); 02913 misdn_lib_tone_generator_start(ch->bc); 02914 } 02915 return 0; 02916 } 02917 02918 return -1; 02919 } 02920 02921 if ( ! ch->bc->addr ) { 02922 chan_misdn_log(8, ch->bc->port, "misdn_write: no addr for bc dropping:%d\n", frame->samples); 02923 return 0; 02924 } 02925 02926 #ifdef MISDN_DEBUG 02927 { 02928 int i, max = 5 > frame->samples ? frame->samples : 5; 02929 02930 printf("write2mISDN %p %d bytes: ", p, frame->samples); 02931 02932 for (i = 0; i < max; i++) 02933 printf("%2.2x ", ((char*) frame->data)[i]); 02934 printf ("\n"); 02935 } 02936 #endif 02937 02938 switch (ch->bc->bc_state) { 02939 case BCHAN_ACTIVATED: 02940 case BCHAN_BRIDGED: 02941 break; 02942 default: 02943 if (!ch->dropped_frame_cnt) 02944 chan_misdn_log(5, ch->bc->port, "BC not active (nor bridged) dropping: %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); 02945 02946 ch->dropped_frame_cnt++; 02947 if (ch->dropped_frame_cnt > 100) { 02948 ch->dropped_frame_cnt = 0; 02949 chan_misdn_log(5, ch->bc->port, "BC not active (nor bridged) dropping: %d frames addr:%x dropped > 100 frames!\n", frame->samples, ch->bc->addr); 02950 } 02951 02952 return 0; 02953 } 02954 02955 chan_misdn_log(9, ch->bc->port, "Sending :%d bytes to MISDN\n", frame->samples); 02956 if ( !ch->bc->nojitter && misdn_cap_is_speech(ch->bc->capability) ) { 02957 /* Buffered Transmit (triggered by read from isdn side)*/ 02958 if (misdn_jb_fill(ch->jb, frame->data, frame->samples) < 0) { 02959 if (ch->bc->active) 02960 cb_log(0, ch->bc->port, "Misdn Jitterbuffer Overflow.\n"); 02961 } 02962 02963 } else { 02964 /*transmit without jitterbuffer*/ 02965 i = misdn_lib_tx2misdn_frm(ch->bc, frame->data, frame->samples); 02966 } 02967 02968 return 0; 02969 }
static int pbx_start_chan | ( | struct chan_list * | ch | ) | [static] |
Channel Queue End
Definition at line 3627 of file chan_misdn.c.
References chan_list::ast, ast_pbx_start(), and chan_list::need_hangup.
Referenced by cb_events(), do_immediate_setup(), misdn_overlap_dial_task(), and start_pbx().
03628 { 03629 int ret = ast_pbx_start(ch->ast); 03630 03631 if (ret >= 0) 03632 ch->need_hangup = 0; 03633 else 03634 ch->need_hangup = 1; 03635 03636 return ret; 03637 }
static void print_bc_info | ( | int | fd, | |
struct chan_list * | help, | |||
struct misdn_bchannel * | bc | |||
) | [static] |
Definition at line 1253 of file chan_misdn.c.
References misdn_bchannel::active, misdn_bchannel::addr, chan_list::addr, chan_list::ast, ast_cli(), misdn_bchannel::bc_state, bc_state2str(), bearer2str(), misdn_bchannel::capability, misdn_bchannel::channel, ast_channel::cid, ast_callerid::cid_num, ast_channel::context, misdn_bchannel::display, misdn_bchannel::ec_enable, ast_channel::exten, misdn_bchannel::holded, misdn_bchannel::l3_id, chan_list::l3id, misdn_get_ch_state(), ast_channel::name, chan_list::norxtone, chan_list::notxtone, misdn_bchannel::nt, ORG_AST, chan_list::originator, misdn_bchannel::pid, misdn_bchannel::port, and misdn_bchannel::rad.
Referenced by misdn_show_cl(), and misdn_show_cls().
01254 { 01255 struct ast_channel *ast = help->ast; 01256 ast_cli(fd, 01257 "* Pid:%d Prt:%d Ch:%d Mode:%s Org:%s dad:%s oad:%s rad:%s ctx:%s state:%s\n", 01258 01259 bc->pid, bc->port, bc->channel, 01260 bc->nt ? "NT" : "TE", 01261 help->originator == ORG_AST ? "*" : "I", 01262 ast ? ast->exten : NULL, 01263 ast ? ast->cid.cid_num : NULL, 01264 bc->rad, 01265 ast ? ast->context : NULL, 01266 misdn_get_ch_state(help) 01267 ); 01268 if (misdn_debug[bc->port] > 0) 01269 ast_cli(fd, 01270 " --> astname: %s\n" 01271 " --> ch_l3id: %x\n" 01272 " --> ch_addr: %x\n" 01273 " --> bc_addr: %x\n" 01274 " --> bc_l3id: %x\n" 01275 " --> display: %s\n" 01276 " --> activated: %d\n" 01277 " --> state: %s\n" 01278 " --> capability: %s\n" 01279 #ifdef MISDN_1_2 01280 " --> pipeline: %s\n" 01281 #else 01282 " --> echo_cancel: %d\n" 01283 #endif 01284 " --> notone : rx %d tx:%d\n" 01285 " --> bc_hold: %d\n", 01286 help->ast->name, 01287 help->l3id, 01288 help->addr, 01289 bc->addr, 01290 bc ? bc->l3_id : -1, 01291 bc->display, 01292 01293 bc->active, 01294 bc_state2str(bc->bc_state), 01295 bearer2str(bc->capability), 01296 #ifdef MISDN_1_2 01297 bc->pipeline, 01298 #else 01299 bc->ec_enable, 01300 #endif 01301 01302 help->norxtone, help->notxtone, 01303 bc->holded 01304 ); 01305 01306 }
static void print_bearer | ( | struct misdn_bchannel * | bc | ) | [static] |
Definition at line 662 of file chan_misdn.c.
References bearer2str(), misdn_bchannel::capability, chan_misdn_log(), INFO_CODEC_ALAW, INFO_CODEC_ULAW, misdn_bchannel::law, and misdn_bchannel::port.
Referenced by cb_events().
00663 { 00664 00665 chan_misdn_log(2, bc->port, " --> Bearer: %s\n",bearer2str(bc->capability)); 00666 00667 switch(bc->law) { 00668 case INFO_CODEC_ALAW: 00669 chan_misdn_log(2, bc->port, " --> Codec: Alaw\n"); 00670 break; 00671 case INFO_CODEC_ULAW: 00672 chan_misdn_log(2, bc->port, " --> Codec: Ulaw\n"); 00673 break; 00674 } 00675 }
static void print_facility | ( | struct FacParm * | fac, | |
struct misdn_bchannel * | bc | |||
) | [static] |
Definition at line 623 of file chan_misdn.c.
References chan_misdn_log(), and misdn_bchannel::port.
Referenced by cb_events().
00624 { 00625 switch (fac->Function) { 00626 case Fac_CD: 00627 chan_misdn_log(1,bc->port," --> calldeflect to: %s, presentable: %s\n", fac->u.CDeflection.DeflectedToNumber, 00628 fac->u.CDeflection.PresentationAllowed ? "yes" : "no"); 00629 break; 00630 case Fac_AOCDCurrency: 00631 if (fac->u.AOCDcur.chargeNotAvailable) 00632 chan_misdn_log(1,bc->port," --> AOCD currency: charge not available\n"); 00633 else if (fac->u.AOCDcur.freeOfCharge) 00634 chan_misdn_log(1,bc->port," --> AOCD currency: free of charge\n"); 00635 else if (fac->u.AOCDchu.billingId >= 0) 00636 chan_misdn_log(1,bc->port," --> AOCD currency: currency:%s amount:%d multiplier:%d typeOfChargingInfo:%s billingId:%d\n", 00637 fac->u.AOCDcur.currency, fac->u.AOCDcur.currencyAmount, fac->u.AOCDcur.multiplier, 00638 (fac->u.AOCDcur.typeOfChargingInfo == 0) ? "subTotal" : "total", fac->u.AOCDcur.billingId); 00639 else 00640 chan_misdn_log(1,bc->port," --> AOCD currency: currency:%s amount:%d multiplier:%d typeOfChargingInfo:%s\n", 00641 fac->u.AOCDcur.currency, fac->u.AOCDcur.currencyAmount, fac->u.AOCDcur.multiplier, 00642 (fac->u.AOCDcur.typeOfChargingInfo == 0) ? "subTotal" : "total"); 00643 break; 00644 case Fac_AOCDChargingUnit: 00645 if (fac->u.AOCDchu.chargeNotAvailable) 00646 chan_misdn_log(1,bc->port," --> AOCD charging unit: charge not available\n"); 00647 else if (fac->u.AOCDchu.freeOfCharge) 00648 chan_misdn_log(1,bc->port," --> AOCD charging unit: free of charge\n"); 00649 else if (fac->u.AOCDchu.billingId >= 0) 00650 chan_misdn_log(1,bc->port," --> AOCD charging unit: recordedUnits:%d typeOfChargingInfo:%s billingId:%d\n", 00651 fac->u.AOCDchu.recordedUnits, (fac->u.AOCDchu.typeOfChargingInfo == 0) ? "subTotal" : "total", fac->u.AOCDchu.billingId); 00652 else 00653 chan_misdn_log(1,bc->port," --> AOCD charging unit: recordedUnits:%d typeOfChargingInfo:%s\n", 00654 fac->u.AOCDchu.recordedUnits, (fac->u.AOCDchu.typeOfChargingInfo == 0) ? "subTotal" : "total"); 00655 break; 00656 default: 00657 chan_misdn_log(1,bc->port," --> unknown facility\n"); 00658 break; 00659 } 00660 }
static struct ast_frame * process_ast_dsp | ( | struct chan_list * | tmp, | |
struct ast_frame * | frame | |||
) | [static] |
Definition at line 2706 of file chan_misdn.c.
References chan_list::ast, ast_async_goto(), chan_list::ast_dsp, ast_dsp_process(), ast_exists_extension(), AST_FRAME_DTMF, ast_log(), ast_strlen_zero(), ast_translate(), ast_verbose(), chan_list::bc, BUFFERSIZE, chan_misdn_log(), ast_channel::cid, ast_callerid::cid_num, ast_channel::context, context, chan_list::dsp, misdn_bchannel::ec_enable, ast_channel::exten, f, chan_list::faxdetect, chan_list::faxhandled, isdn_lib_stop_dtmf(), isdn_lib_update_ec(), isdn_lib_update_rxgain(), isdn_lib_update_txgain(), LOG_DEBUG, LOG_NOTICE, LOG_WARNING, ast_channel::macrocontext, MISDN_CFG_FAXDETECT_CONTEXT, misdn_cfg_get(), ast_channel::name, option_verbose, pbx_builtin_setvar_helper(), misdn_bchannel::port, misdn_bchannel::rxgain, chan_list::trans, misdn_bchannel::txgain, and VERBOSE_PREFIX_3.
Referenced by misdn_read().
02707 { 02708 struct ast_frame *f,*f2; 02709 02710 if (tmp->trans) { 02711 f2 = ast_translate(tmp->trans, frame, 0); 02712 f = ast_dsp_process(tmp->ast, tmp->dsp, f2); 02713 } else { 02714 chan_misdn_log(0, tmp->bc->port, "No T-Path found\n"); 02715 return NULL; 02716 } 02717 02718 if (!f || (f->frametype != AST_FRAME_DTMF)) 02719 return frame; 02720 02721 ast_log(LOG_DEBUG, "Detected inband DTMF digit: %c\n", f->subclass); 02722 02723 if (tmp->faxdetect && (f->subclass == 'f')) { 02724 /* Fax tone -- Handle and return NULL */ 02725 if (!tmp->faxhandled) { 02726 struct ast_channel *ast = tmp->ast; 02727 tmp->faxhandled++; 02728 chan_misdn_log(0, tmp->bc->port, "Fax detected, preparing %s for fax transfer.\n", ast->name); 02729 tmp->bc->rxgain = 0; 02730 isdn_lib_update_rxgain(tmp->bc); 02731 tmp->bc->txgain = 0; 02732 isdn_lib_update_txgain(tmp->bc); 02733 #ifdef MISDN_1_2 02734 *tmp->bc->pipeline = 0; 02735 #else 02736 tmp->bc->ec_enable = 0; 02737 #endif 02738 isdn_lib_update_ec(tmp->bc); 02739 isdn_lib_stop_dtmf(tmp->bc); 02740 switch (tmp->faxdetect) { 02741 case 1: 02742 if (strcmp(ast->exten, "fax")) { 02743 char *context; 02744 char context_tmp[BUFFERSIZE]; 02745 misdn_cfg_get(tmp->bc->port, MISDN_CFG_FAXDETECT_CONTEXT, &context_tmp, sizeof(context_tmp)); 02746 context = ast_strlen_zero(context_tmp) ? (ast_strlen_zero(ast->macrocontext) ? ast->context : ast->macrocontext) : context_tmp; 02747 if (ast_exists_extension(ast, context, "fax", 1, ast->cid.cid_num)) { 02748 if (option_verbose > 2) 02749 ast_verbose(VERBOSE_PREFIX_3 "Redirecting %s to fax extension (context:%s)\n", ast->name, context); 02750 /* Save the DID/DNIS when we transfer the fax call to a "fax" extension */ 02751 pbx_builtin_setvar_helper(ast,"FAXEXTEN",ast->exten); 02752 if (ast_async_goto(ast, context, "fax", 1)) 02753 ast_log(LOG_WARNING, "Failed to async goto '%s' into fax of '%s'\n", ast->name, context); 02754 } else 02755 ast_log(LOG_NOTICE, "Fax detected, but no fax extension ctx:%s exten:%s\n", context, ast->exten); 02756 } else { 02757 ast_log(LOG_DEBUG, "Already in a fax extension, not redirecting\n"); 02758 } 02759 break; 02760 case 2: 02761 ast_verbose(VERBOSE_PREFIX_3 "Not redirecting %s to fax extension, nojump is set.\n", ast->name); 02762 break; 02763 } 02764 } else { 02765 ast_log(LOG_DEBUG, "Fax already handled\n"); 02766 } 02767 } 02768 02769 if (tmp->ast_dsp && (f->subclass != 'f')) { 02770 chan_misdn_log(2, tmp->bc->port, " --> * SEND: DTMF (AST_DSP) :%c\n", f->subclass); 02771 } 02772 02773 return f; 02774 }
static int read_config | ( | struct chan_list * | ch, | |
int | orig | |||
) | [static] |
Definition at line 1915 of file chan_misdn.c.
References chan_list::allowed_bearers, misdn_bchannel::AOCDtype, chan_list::ast, ast_copy_string(), chan_list::ast_dsp, ast_dsp_new(), ast_dsp_set_features(), AST_FORMAT_ALAW, AST_FORMAT_SLINEAR, ast_log(), ast_mutex_init, ast_print_group(), ast_set_callerid(), ast_string_field_set, ast_strlen_zero(), ast_translator_build_path(), chan_list::bc, BUFFERSIZE, ast_channel::callgroup, misdn_bchannel::capability, chan_misdn_log(), ast_channel::cid, ast_callerid::cid_rdnis, config_jitterbuffer(), ast_channel::context, chan_list::context, misdn_bchannel::cpnnumplan, misdn_bchannel::dad, debug_numplan(), misdn_bchannel::dnumplan, chan_list::dsp, DSP_FEATURE_DTMF_DETECT, DSP_FEATURE_FAX_DETECT, misdn_bchannel::early_bconnect, ast_channel::exten, chan_list::far_alerting, chan_list::faxdetect, chan_list::faxdetect_timeout, free, misdn_bchannel::hdlc, chan_list::ignore_dtmf, chan_list::incoming_early_audio, INFO_CAPABILITY_DIGITAL_RESTRICTED, INFO_CAPABILITY_DIGITAL_UNRESTRICTED, chan_list::jb_len, chan_list::jb_upper_threshold, misdn_bchannel::keypad, language, LOG_WARNING, MISDN_CFG_ALLOWED_BEARERS, MISDN_CFG_ASTDTMF, MISDN_CFG_CALLERID, MISDN_CFG_CALLGROUP, MISDN_CFG_CONTEXT, MISDN_CFG_CPNDIALPLAN, MISDN_CFG_DIALPLAN, MISDN_CFG_EARLY_BCONNECT, MISDN_CFG_FAR_ALERTING, MISDN_CFG_FAXDETECT, MISDN_CFG_FAXDETECT_TIMEOUT, misdn_cfg_get(), MISDN_CFG_HDLC, MISDN_CFG_INCOMING_EARLY_AUDIO, MISDN_CFG_INTERNATPREFIX, MISDN_CFG_JITTERBUFFER, MISDN_CFG_JITTERBUFFER_UPPER_THRESHOLD, MISDN_CFG_LANGUAGE, MISDN_CFG_LOCALDIALPLAN, MISDN_CFG_MUSICCLASS, MISDN_CFG_NATPREFIX, MISDN_CFG_NEED_MORE_INFOS, MISDN_CFG_NOAUTORESPOND_ON_SETUP, MISDN_CFG_NTTIMEOUT, MISDN_CFG_OVERLAP_DIAL, MISDN_CFG_PICKUPGROUP, MISDN_CFG_RXGAIN, MISDN_CFG_SENDDTMF, MISDN_CFG_TE_CHOOSE_CHANNEL, MISDN_CFG_TXGAIN, chan_list::mohinterpret, misdn_bchannel::need_more_infos, chan_list::noautorespond_on_setup, chan_list::nttimeout, NUMPLAN_INTERNATIONAL, NUMPLAN_NATIONAL, misdn_bchannel::oad, misdn_bchannel::onumplan, ORG_AST, misdn_bchannel::orig_dad, chan_list::overlap_dial, chan_list::overlap_dial_task, chan_list::overlap_tv_lock, ast_channel::pickupgroup, misdn_bchannel::port, prefix, misdn_bchannel::rad, misdn_bchannel::rxgain, misdn_bchannel::send_dtmf, strdup, misdn_bchannel::te_choose_channel, chan_list::trans, misdn_bchannel::txgain, and update_ec_config().
Referenced by cb_events(), and misdn_request().
01916 { 01917 struct ast_channel *ast; 01918 struct misdn_bchannel *bc; 01919 int port; 01920 int hdlc = 0; 01921 char lang[BUFFERSIZE + 1]; 01922 char faxdetect[BUFFERSIZE + 1]; 01923 char buf[256]; 01924 char buf2[256]; 01925 ast_group_t pg; 01926 ast_group_t cg; 01927 01928 if (!ch) { 01929 ast_log(LOG_WARNING, "Cannot configure without chanlist\n"); 01930 return -1; 01931 } 01932 01933 ast = ch->ast; 01934 bc = ch->bc; 01935 if (! ast || ! bc) { 01936 ast_log(LOG_WARNING, "Cannot configure without ast || bc\n"); 01937 return -1; 01938 } 01939 01940 port = bc->port; 01941 chan_misdn_log(1, port, "read_config: Getting Config\n"); 01942 01943 misdn_cfg_get(port, MISDN_CFG_LANGUAGE, lang, BUFFERSIZE); 01944 ast_string_field_set(ast, language, lang); 01945 01946 misdn_cfg_get(port, MISDN_CFG_MUSICCLASS, ch->mohinterpret, sizeof(ch->mohinterpret)); 01947 01948 misdn_cfg_get(port, MISDN_CFG_TXGAIN, &bc->txgain, sizeof(int)); 01949 misdn_cfg_get(port, MISDN_CFG_RXGAIN, &bc->rxgain, sizeof(int)); 01950 01951 misdn_cfg_get(port, MISDN_CFG_INCOMING_EARLY_AUDIO, &ch->incoming_early_audio, sizeof(int)); 01952 01953 misdn_cfg_get(port, MISDN_CFG_SENDDTMF, &bc->send_dtmf, sizeof(int)); 01954 01955 misdn_cfg_get(port, MISDN_CFG_ASTDTMF, &ch->ast_dsp, sizeof(int)); 01956 01957 if (ch->ast_dsp) { 01958 ch->ignore_dtmf = 1; 01959 } 01960 01961 misdn_cfg_get(port, MISDN_CFG_NEED_MORE_INFOS, &bc->need_more_infos, sizeof(int)); 01962 misdn_cfg_get(port, MISDN_CFG_NTTIMEOUT, &ch->nttimeout, sizeof(int)); 01963 01964 misdn_cfg_get(port, MISDN_CFG_NOAUTORESPOND_ON_SETUP, &ch->noautorespond_on_setup, sizeof(int)); 01965 01966 misdn_cfg_get(port, MISDN_CFG_FAR_ALERTING, &ch->far_alerting, sizeof(int)); 01967 01968 misdn_cfg_get(port, MISDN_CFG_ALLOWED_BEARERS, &ch->allowed_bearers, BUFFERSIZE); 01969 01970 misdn_cfg_get(port, MISDN_CFG_FAXDETECT, faxdetect, BUFFERSIZE); 01971 01972 misdn_cfg_get(port, MISDN_CFG_HDLC, &hdlc, sizeof(int)); 01973 01974 if (hdlc) { 01975 switch (bc->capability) { 01976 case INFO_CAPABILITY_DIGITAL_UNRESTRICTED: 01977 case INFO_CAPABILITY_DIGITAL_RESTRICTED: 01978 chan_misdn_log(1, bc->port, " --> CONF HDLC\n"); 01979 bc->hdlc = 1; 01980 break; 01981 } 01982 01983 } 01984 /*Initialize new Jitterbuffer*/ 01985 misdn_cfg_get(port, MISDN_CFG_JITTERBUFFER, &ch->jb_len, sizeof(int)); 01986 misdn_cfg_get(port, MISDN_CFG_JITTERBUFFER_UPPER_THRESHOLD, &ch->jb_upper_threshold, sizeof(int)); 01987 01988 config_jitterbuffer(ch); 01989 01990 misdn_cfg_get(bc->port, MISDN_CFG_CONTEXT, ch->context, sizeof(ch->context)); 01991 01992 ast_copy_string(ast->context, ch->context, sizeof(ast->context)); 01993 01994 #ifdef MISDN_1_2 01995 update_pipeline_config(bc); 01996 #else 01997 update_ec_config(bc); 01998 #endif 01999 02000 { 02001 int eb3; 02002 02003 misdn_cfg_get( bc->port, MISDN_CFG_EARLY_BCONNECT, &eb3, sizeof(int)); 02004 bc->early_bconnect=eb3; 02005 } 02006 02007 misdn_cfg_get(port, MISDN_CFG_PICKUPGROUP, &pg, sizeof(pg)); 02008 misdn_cfg_get(port, MISDN_CFG_CALLGROUP, &cg, sizeof(cg)); 02009 02010 chan_misdn_log(5, port, " --> * CallGrp:%s PickupGrp:%s\n", ast_print_group(buf, sizeof(buf), cg), ast_print_group(buf2, sizeof(buf2), pg)); 02011 ast->pickupgroup = pg; 02012 ast->callgroup = cg; 02013 02014 if (orig == ORG_AST) { 02015 char callerid[BUFFERSIZE + 1]; 02016 02017 /* ORIGINATOR Asterisk (outgoing call) */ 02018 02019 misdn_cfg_get(port, MISDN_CFG_TE_CHOOSE_CHANNEL, &(bc->te_choose_channel), sizeof(int)); 02020 02021 if (strstr(faxdetect, "outgoing") || strstr(faxdetect, "both")) { 02022 if (strstr(faxdetect, "nojump")) 02023 ch->faxdetect = 2; 02024 else 02025 ch->faxdetect = 1; 02026 } 02027 02028 misdn_cfg_get(port, MISDN_CFG_CALLERID, callerid, BUFFERSIZE); 02029 if ( ! ast_strlen_zero(callerid) ) { 02030 chan_misdn_log(1, port, " --> * Setting Cid to %s\n", callerid); 02031 ast_copy_string(bc->oad, callerid, sizeof(bc->oad)); 02032 } 02033 02034 misdn_cfg_get(port, MISDN_CFG_DIALPLAN, &bc->dnumplan, sizeof(int)); 02035 misdn_cfg_get(port, MISDN_CFG_LOCALDIALPLAN, &bc->onumplan, sizeof(int)); 02036 misdn_cfg_get(port, MISDN_CFG_CPNDIALPLAN, &bc->cpnnumplan, sizeof(int)); 02037 debug_numplan(port, bc->dnumplan, "TON"); 02038 debug_numplan(port, bc->onumplan, "LTON"); 02039 debug_numplan(port, bc->cpnnumplan, "CTON"); 02040 02041 ch->overlap_dial = 0; 02042 } else { 02043 /* ORIGINATOR MISDN (incoming call) */ 02044 char prefix[BUFFERSIZE + 1] = ""; 02045 02046 if (strstr(faxdetect, "incoming") || strstr(faxdetect, "both")) { 02047 if (strstr(faxdetect, "nojump")) 02048 ch->faxdetect = 2; 02049 else 02050 ch->faxdetect = 1; 02051 } 02052 02053 misdn_cfg_get(port, MISDN_CFG_CPNDIALPLAN, &bc->cpnnumplan, sizeof(int)); 02054 debug_numplan(port, bc->cpnnumplan, "CTON"); 02055 02056 switch (bc->onumplan) { 02057 case NUMPLAN_INTERNATIONAL: 02058 misdn_cfg_get(bc->port, MISDN_CFG_INTERNATPREFIX, prefix, BUFFERSIZE); 02059 break; 02060 02061 case NUMPLAN_NATIONAL: 02062 misdn_cfg_get(bc->port, MISDN_CFG_NATPREFIX, prefix, BUFFERSIZE); 02063 break; 02064 default: 02065 break; 02066 } 02067 02068 ast_copy_string(buf, bc->oad, sizeof(buf)); 02069 snprintf(bc->oad, sizeof(bc->oad), "%s%s", prefix, buf); 02070 02071 if (!ast_strlen_zero(bc->dad)) { 02072 ast_copy_string(bc->orig_dad, bc->dad, sizeof(bc->orig_dad)); 02073 } 02074 02075 if ( ast_strlen_zero(bc->dad) && !ast_strlen_zero(bc->keypad)) { 02076 ast_copy_string(bc->dad, bc->keypad, sizeof(bc->dad)); 02077 } 02078 02079 prefix[0] = 0; 02080 02081 switch (bc->dnumplan) { 02082 case NUMPLAN_INTERNATIONAL: 02083 misdn_cfg_get(bc->port, MISDN_CFG_INTERNATPREFIX, prefix, BUFFERSIZE); 02084 break; 02085 case NUMPLAN_NATIONAL: 02086 misdn_cfg_get(bc->port, MISDN_CFG_NATPREFIX, prefix, BUFFERSIZE); 02087 break; 02088 default: 02089 break; 02090 } 02091 02092 ast_copy_string(buf, bc->dad, sizeof(buf)); 02093 snprintf(bc->dad, sizeof(bc->dad), "%s%s", prefix, buf); 02094 02095 if (strcmp(bc->dad, ast->exten)) { 02096 ast_copy_string(ast->exten, bc->dad, sizeof(ast->exten)); 02097 } 02098 02099 ast_set_callerid(ast, bc->oad, NULL, bc->oad); 02100 02101 if ( !ast_strlen_zero(bc->rad) ) { 02102 if (ast->cid.cid_rdnis) 02103 free(ast->cid.cid_rdnis); 02104 ast->cid.cid_rdnis = strdup(bc->rad); 02105 } 02106 02107 misdn_cfg_get(bc->port, MISDN_CFG_OVERLAP_DIAL, &ch->overlap_dial, sizeof(ch->overlap_dial)); 02108 ast_mutex_init(&ch->overlap_tv_lock); 02109 } /* ORIG MISDN END */ 02110 02111 ch->overlap_dial_task = -1; 02112 02113 if (ch->faxdetect || ch->ast_dsp) { 02114 misdn_cfg_get(port, MISDN_CFG_FAXDETECT_TIMEOUT, &ch->faxdetect_timeout, sizeof(ch->faxdetect_timeout)); 02115 if (!ch->dsp) 02116 ch->dsp = ast_dsp_new(); 02117 if (ch->dsp) { 02118 if (ch->faxdetect) 02119 ast_dsp_set_features(ch->dsp, DSP_FEATURE_DTMF_DETECT | DSP_FEATURE_FAX_DETECT); 02120 else 02121 ast_dsp_set_features(ch->dsp, DSP_FEATURE_DTMF_DETECT ); 02122 } 02123 if (!ch->trans) 02124 ch->trans = ast_translator_build_path(AST_FORMAT_SLINEAR, AST_FORMAT_ALAW); 02125 } 02126 02127 /* AOCD initialization */ 02128 bc->AOCDtype = Fac_None; 02129 02130 return 0; 02131 }
static void release_chan | ( | struct misdn_bchannel * | bc | ) | [static] |
Isdn asks us to release channel, pendant to misdn_hangup
Definition at line 3676 of file chan_misdn.c.
References ast_channel::_state, chan_list::ast, ast_mutex_destroy, ast_mutex_lock, ast_mutex_unlock, ast_setstate(), AST_STATE_DOWN, AST_STATE_RESERVED, chan_list::bc, chan_misdn_log(), ast_channel::cid, ast_callerid::cid_num, cl_dequeue_chan(), cl_te, ast_channel::context, ast_channel::exten, find_chan_by_bc(), free, chan_list::jb, misdn_bchannel::l3_id, MISDN_ASTERISK_TECH_PVT, MISDN_CLEANING, misdn_get_ch_state(), misdn_in_calls, misdn_jb_destroy(), misdn_out_calls, misdn_tasks_remove(), misdn_bchannel::nojitter, ORG_AST, chan_list::originator, chan_list::overlap_dial, chan_list::overlap_dial_task, chan_list::overlap_tv_lock, misdn_bchannel::pid, chan_list::pipe, misdn_bchannel::port, release_lock, and chan_list::state.
Referenced by cb_events(), and misdn_hangup().
03676 { 03677 struct ast_channel *ast = NULL; 03678 03679 ast_mutex_lock(&release_lock); 03680 { 03681 struct chan_list *ch=find_chan_by_bc(cl_te, bc); 03682 if (!ch) { 03683 chan_misdn_log(1, bc->port, "release_chan: Ch not found!\n"); 03684 ast_mutex_unlock(&release_lock); 03685 return; 03686 } 03687 03688 if (ch->ast) { 03689 ast = ch->ast; 03690 } 03691 03692 chan_misdn_log(5, bc->port, "release_chan: bc with l3id: %x\n", bc->l3_id); 03693 03694 /*releasing jitterbuffer*/ 03695 if (ch->jb ) { 03696 misdn_jb_destroy(ch->jb); 03697 ch->jb = NULL; 03698 } else { 03699 if (!bc->nojitter) 03700 chan_misdn_log(5, bc->port, "Jitterbuffer already destroyed.\n"); 03701 } 03702 03703 if (ch->overlap_dial) { 03704 if (ch->overlap_dial_task != -1) { 03705 misdn_tasks_remove(ch->overlap_dial_task); 03706 ch->overlap_dial_task = -1; 03707 } 03708 ast_mutex_destroy(&ch->overlap_tv_lock); 03709 } 03710 03711 if (ch->originator == ORG_AST) { 03712 misdn_out_calls[bc->port]--; 03713 } else { 03714 misdn_in_calls[bc->port]--; 03715 } 03716 03717 if (ch) { 03718 close(ch->pipe[0]); 03719 close(ch->pipe[1]); 03720 03721 if (ast && MISDN_ASTERISK_TECH_PVT(ast)) { 03722 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.cid_num, misdn_get_ch_state(ch)); 03723 chan_misdn_log(3, bc->port, " --> * State Down\n"); 03724 MISDN_ASTERISK_TECH_PVT(ast) = NULL; 03725 03726 if (ast->_state != AST_STATE_RESERVED) { 03727 chan_misdn_log(3, bc->port, " --> Setting AST State to down\n"); 03728 ast_setstate(ast, AST_STATE_DOWN); 03729 } 03730 } 03731 03732 ch->state = MISDN_CLEANING; 03733 cl_dequeue_chan(&cl_te, ch); 03734 03735 free(ch); 03736 } else { 03737 /* chan is already cleaned, so exiting */ 03738 } 03739 } 03740 ast_mutex_unlock(&release_lock); 03741 /*** release end **/ 03742 }
static int reload | ( | void | ) | [static] |
Definition at line 5203 of file chan_misdn.c.
References reload_config().
05204 { 05205 reload_config(); 05206 05207 return 0; 05208 }
static void reload_config | ( | void | ) | [static] |
Definition at line 1225 of file chan_misdn.c.
References ast_log(), BUFFERSIZE, free_robin_list(), LOG_WARNING, misdn_cfg_get(), misdn_cfg_reload(), misdn_cfg_update_ptp(), MISDN_GEN_DEBUG, and MISDN_GEN_TRACEFILE.
01226 { 01227 int i, cfg_debug; 01228 01229 if (!g_config_initialized) { 01230 ast_log(LOG_WARNING, "chan_misdn is not initialized properly, still reloading ?\n"); 01231 return ; 01232 } 01233 01234 free_robin_list(); 01235 misdn_cfg_reload(); 01236 misdn_cfg_update_ptp(); 01237 misdn_cfg_get(0, MISDN_GEN_TRACEFILE, global_tracefile, BUFFERSIZE); 01238 misdn_cfg_get(0, MISDN_GEN_DEBUG, &cfg_debug, sizeof(int)); 01239 01240 for (i = 0; i <= max_ports; i++) { 01241 misdn_debug[i] = cfg_debug; 01242 misdn_debug_only[i] = 0; 01243 } 01244 }
static void send_cause2ast | ( | struct ast_channel * | ast, | |
struct misdn_bchannel * | bc, | |||
struct chan_list * | ch | |||
) | [static] |
Definition at line 3822 of file chan_misdn.c.
References AST_CAUSE_CALL_REJECTED, AST_CAUSE_DESTINATION_OUT_OF_ORDER, AST_CAUSE_NO_ROUTE_DESTINATION, AST_CAUSE_NO_ROUTE_TRANSIT_NET, AST_CAUSE_NUMBER_CHANGED, AST_CAUSE_UNALLOCATED, AST_CAUSE_USER_BUSY, AST_CONTROL_BUSY, ast_queue_control(), misdn_bchannel::cause, chan_misdn_log(), ast_channel::hangupcause, MISDN_BUSY, chan_list::need_busy, misdn_bchannel::pid, misdn_bchannel::port, and chan_list::state.
Referenced by hangup_chan().
03822 { 03823 if (!ast) { 03824 chan_misdn_log(1, 0, "send_cause2ast: No Ast\n"); 03825 return; 03826 } 03827 if (!bc) { 03828 chan_misdn_log(1, 0, "send_cause2ast: No BC\n"); 03829 return; 03830 } 03831 if (!ch) { 03832 chan_misdn_log(1, 0, "send_cause2ast: No Ch\n"); 03833 return; 03834 } 03835 03836 ast->hangupcause = bc->cause; 03837 03838 switch (bc->cause) { 03839 03840 case AST_CAUSE_UNALLOCATED: 03841 case AST_CAUSE_NO_ROUTE_TRANSIT_NET: 03842 case AST_CAUSE_NO_ROUTE_DESTINATION: 03843 case 4: /* Send special information tone */ 03844 case AST_CAUSE_NUMBER_CHANGED: 03845 case AST_CAUSE_DESTINATION_OUT_OF_ORDER: 03846 /* Congestion Cases */ 03847 /* 03848 * Not Queueing the Congestion anymore, since we want to hear 03849 * the inband message 03850 * 03851 chan_misdn_log(1, bc ? bc->port : 0, " --> * SEND: Queue Congestion pid:%d\n", bc ? bc->pid : -1); 03852 ch->state = MISDN_BUSY; 03853 03854 ast_queue_control(ast, AST_CONTROL_CONGESTION); 03855 */ 03856 break; 03857 03858 case AST_CAUSE_CALL_REJECTED: 03859 case AST_CAUSE_USER_BUSY: 03860 ch->state = MISDN_BUSY; 03861 03862 if (!ch->need_busy) { 03863 chan_misdn_log(1, bc ? bc->port : 0, "Queued busy already\n"); 03864 break; 03865 } 03866 03867 chan_misdn_log(1, bc ? bc->port : 0, " --> * SEND: Queue Busy pid:%d\n", bc ? bc->pid : -1); 03868 03869 ast_queue_control(ast, AST_CONTROL_BUSY); 03870 03871 ch->need_busy = 0; 03872 03873 break; 03874 } 03875 }
static void send_digit_to_chan | ( | struct chan_list * | cl, | |
char | digit | |||
) | [static] |
Definition at line 883 of file chan_misdn.c.
References chan_list::ast, ast_log(), ast_playtones_start(), LOG_DEBUG, and ast_channel::name.
Referenced by misdn_digit_end(), and misdn_send_digit().
00884 { 00885 static const char* dtmf_tones[] = { 00886 "!941+1336/100,!0/100", /* 0 */ 00887 "!697+1209/100,!0/100", /* 1 */ 00888 "!697+1336/100,!0/100", /* 2 */ 00889 "!697+1477/100,!0/100", /* 3 */ 00890 "!770+1209/100,!0/100", /* 4 */ 00891 "!770+1336/100,!0/100", /* 5 */ 00892 "!770+1477/100,!0/100", /* 6 */ 00893 "!852+1209/100,!0/100", /* 7 */ 00894 "!852+1336/100,!0/100", /* 8 */ 00895 "!852+1477/100,!0/100", /* 9 */ 00896 "!697+1633/100,!0/100", /* A */ 00897 "!770+1633/100,!0/100", /* B */ 00898 "!852+1633/100,!0/100", /* C */ 00899 "!941+1633/100,!0/100", /* D */ 00900 "!941+1209/100,!0/100", /* * */ 00901 "!941+1477/100,!0/100" }; /* # */ 00902 struct ast_channel *chan=cl->ast; 00903 00904 if (digit >= '0' && digit <='9') 00905 ast_playtones_start(chan,0,dtmf_tones[digit-'0'], 0); 00906 else if (digit >= 'A' && digit <= 'D') 00907 ast_playtones_start(chan,0,dtmf_tones[digit-'A'+10], 0); 00908 else if (digit == '*') 00909 ast_playtones_start(chan,0,dtmf_tones[14], 0); 00910 else if (digit == '#') 00911 ast_playtones_start(chan,0,dtmf_tones[15], 0); 00912 else { 00913 /* not handled */ 00914 ast_log(LOG_DEBUG, "Unable to handle DTMF tone '%c' for '%s'\n", digit, chan->name); 00915 } 00916 }
static void show_config_description | ( | int | fd, | |
enum misdn_cfg_elements | elem | |||
) | [inline, static] |
Definition at line 1074 of file chan_misdn.c.
References ast_cli(), BUFFERSIZE, COLOR_BRWHITE, COLOR_YELLOW, desc, misdn_cfg_get_desc(), misdn_cfg_get_name(), MISDN_CFG_LAST, name, and term_color().
Referenced by misdn_show_config().
01075 { 01076 char section[BUFFERSIZE]; 01077 char name[BUFFERSIZE]; 01078 char desc[BUFFERSIZE]; 01079 char def[BUFFERSIZE]; 01080 char tmp[BUFFERSIZE]; 01081 01082 misdn_cfg_get_name(elem, tmp, sizeof(tmp)); 01083 term_color(name, tmp, COLOR_BRWHITE, 0, sizeof(tmp)); 01084 misdn_cfg_get_desc(elem, desc, sizeof(desc), def, sizeof(def)); 01085 01086 if (elem < MISDN_CFG_LAST) 01087 term_color(section, "PORTS SECTION", COLOR_YELLOW, 0, sizeof(section)); 01088 else 01089 term_color(section, "GENERAL SECTION", COLOR_YELLOW, 0, sizeof(section)); 01090 01091 if (*def) 01092 ast_cli(fd, "[%s] %s (Default: %s)\n\t%s\n", section, name, def, desc); 01093 else 01094 ast_cli(fd, "[%s] %s\n\t%s\n", section, name, desc); 01095 }
static void sighandler | ( | int | sig | ) | [static] |
static int start_bc_tones | ( | struct chan_list * | cl | ) | [static] |
Definition at line 3137 of file chan_misdn.c.
References chan_list::bc, misdn_lib_tone_generator_stop(), chan_list::norxtone, and chan_list::notxtone.
Referenced by cb_events(), misdn_answer(), misdn_hangup(), and misdn_indication().
03138 { 03139 misdn_lib_tone_generator_stop(cl->bc); 03140 cl->notxtone = 0; 03141 cl->norxtone = 0; 03142 return 0; 03143 }
static void start_pbx | ( | struct chan_list * | ch, | |
struct misdn_bchannel * | bc, | |||
struct ast_channel * | chan | |||
) | [static] |
Definition at line 3970 of file chan_misdn.c.
References chan_misdn_log(), EVENT_RELEASE, EVENT_RELEASE_COMPLETE, hangup_chan(), hanguptone_indicate(), misdn_lib_send_event(), misdn_bchannel::nt, pbx_start_chan(), and misdn_bchannel::port.
Referenced by cb_events().
03970 { 03971 if (pbx_start_chan(ch) < 0) { 03972 hangup_chan(ch); 03973 chan_misdn_log(-1, bc->port, "ast_pbx_start returned <0 in SETUP\n"); 03974 if (bc->nt) { 03975 hanguptone_indicate(ch); 03976 misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE); 03977 } else 03978 misdn_lib_send_event(bc, EVENT_RELEASE); 03979 } 03980 }
static int stop_bc_tones | ( | struct chan_list * | cl | ) | [static] |
Definition at line 3145 of file chan_misdn.c.
References chan_list::norxtone, and chan_list::notxtone.
Referenced by cb_events(), misdn_call(), and misdn_hangup().
03146 { 03147 if (!cl) return -1; 03148 03149 cl->notxtone = 1; 03150 cl->norxtone = 1; 03151 03152 return 0; 03153 }
static int stop_indicate | ( | struct chan_list * | cl | ) | [static] |
Definition at line 3117 of file chan_misdn.c.
References chan_list::ast, ast_playtones_stop(), chan_list::bc, chan_misdn_log(), misdn_lib_tone_generator_stop(), misdn_bchannel::port, and chan_list::ts.
Referenced by cb_events(), misdn_answer(), misdn_indication(), and misdn_overlap_dial_task().
03118 { 03119 struct ast_channel *ast = cl->ast; 03120 03121 if (!ast) { 03122 chan_misdn_log(0, cl->bc->port, "No Ast in stop_indicate\n"); 03123 return -1; 03124 } 03125 03126 chan_misdn_log(3, cl->bc->port, " --> None\n"); 03127 misdn_lib_tone_generator_stop(cl->bc); 03128 ast_playtones_stop(ast); 03129 03130 cl->ts = NULL; 03131 /*ast_deactivate_generator(ast);*/ 03132 03133 return 0; 03134 }
static int unload_module | ( | void | ) | [static] |
TE STUFF END
Definition at line 5012 of file chan_misdn.c.
References ast_channel_unregister(), ast_cli_unregister_multiple(), ast_log(), ast_unregister_application(), chan_misdn_clis, free, free_robin_list(), LOG_VERBOSE, misdn_cfg_destroy(), misdn_debug, misdn_debug_only, misdn_lib_destroy(), misdn_tasks_destroy(), and misdn_tech.
05013 { 05014 /* First, take us out of the channel loop */ 05015 ast_log(LOG_VERBOSE, "-- Unregistering mISDN Channel Driver --\n"); 05016 05017 misdn_tasks_destroy(); 05018 05019 if (!g_config_initialized) 05020 return 0; 05021 05022 ast_cli_unregister_multiple(chan_misdn_clis, sizeof(chan_misdn_clis) / sizeof(struct ast_cli_entry)); 05023 05024 /* ast_unregister_application("misdn_crypt"); */ 05025 ast_unregister_application("misdn_set_opt"); 05026 ast_unregister_application("misdn_facility"); 05027 ast_unregister_application("misdn_check_l2l1"); 05028 05029 ast_channel_unregister(&misdn_tech); 05030 05031 free_robin_list(); 05032 misdn_cfg_destroy(); 05033 misdn_lib_destroy(); 05034 05035 if (misdn_debug) 05036 free(misdn_debug); 05037 if (misdn_debug_only) 05038 free(misdn_debug_only); 05039 free(misdn_ports); 05040 05041 return 0; 05042 }
static int update_config | ( | struct chan_list * | ch, | |
int | orig | |||
) | [static] |
Updates caller ID information from config.
Definition at line 1734 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, misdn_bchannel::capability, chan_misdn_log(), ast_channel::cid, ast_callerid::cid_pres, misdn_bchannel::hdlc, INFO_CAPABILITY_DIGITAL_RESTRICTED, INFO_CAPABILITY_DIGITAL_UNRESTRICTED, LOG_WARNING, misdn_cfg_get(), MISDN_CFG_HDLC, MISDN_CFG_PRES, MISDN_CFG_SCREEN, misdn_bchannel::port, misdn_bchannel::pres, and misdn_bchannel::screen.
Referenced by misdn_call().
01735 { 01736 struct ast_channel *ast; 01737 struct misdn_bchannel *bc; 01738 int port, hdlc = 0; 01739 int pres, screen; 01740 01741 if (!ch) { 01742 ast_log(LOG_WARNING, "Cannot configure without chanlist\n"); 01743 return -1; 01744 } 01745 01746 ast = ch->ast; 01747 bc = ch->bc; 01748 if (! ast || ! bc) { 01749 ast_log(LOG_WARNING, "Cannot configure without ast || bc\n"); 01750 return -1; 01751 } 01752 01753 port = bc->port; 01754 01755 chan_misdn_log(7, port, "update_config: Getting Config\n"); 01756 01757 misdn_cfg_get(port, MISDN_CFG_HDLC, &hdlc, sizeof(int)); 01758 01759 if (hdlc) { 01760 switch (bc->capability) { 01761 case INFO_CAPABILITY_DIGITAL_UNRESTRICTED: 01762 case INFO_CAPABILITY_DIGITAL_RESTRICTED: 01763 chan_misdn_log(1, bc->port, " --> CONF HDLC\n"); 01764 bc->hdlc = 1; 01765 break; 01766 } 01767 } 01768 01769 01770 misdn_cfg_get(port, MISDN_CFG_PRES, &pres, sizeof(pres)); 01771 misdn_cfg_get(port, MISDN_CFG_SCREEN, &screen, sizeof(screen)); 01772 chan_misdn_log(2, port, " --> pres: %d screen: %d\n", pres, screen); 01773 01774 if (pres < 0 || screen < 0) { 01775 chan_misdn_log(2, port, " --> pres: %x\n", ast->cid.cid_pres); 01776 01777 switch (ast->cid.cid_pres & 0x60) { 01778 case AST_PRES_RESTRICTED: 01779 bc->pres = 1; 01780 chan_misdn_log(2, port, " --> PRES: Restricted (1)\n"); 01781 break; 01782 case AST_PRES_UNAVAILABLE: 01783 bc->pres = 2; 01784 chan_misdn_log(2, port, " --> PRES: Unavailable (2)\n"); 01785 break; 01786 default: 01787 bc->pres = 0; 01788 chan_misdn_log(2, port, " --> PRES: Allowed (0)\n"); 01789 break; 01790 } 01791 01792 switch (ast->cid.cid_pres & 0x3) { 01793 default: 01794 case AST_PRES_USER_NUMBER_UNSCREENED: 01795 bc->screen = 0; 01796 chan_misdn_log(2, port, " --> SCREEN: Unscreened (0)\n"); 01797 break; 01798 case AST_PRES_USER_NUMBER_PASSED_SCREEN: 01799 bc->screen = 1; 01800 chan_misdn_log(2, port, " --> SCREEN: Passed Screen (1)\n"); 01801 break; 01802 case AST_PRES_USER_NUMBER_FAILED_SCREEN: 01803 bc->screen = 2; 01804 chan_misdn_log(2, port, " --> SCREEN: Failed Screen (2)\n"); 01805 break; 01806 case AST_PRES_NETWORK_NUMBER: 01807 bc->screen = 3; 01808 chan_misdn_log(2, port, " --> SCREEN: Network Nr. (3)\n"); 01809 break; 01810 } 01811 } else { 01812 bc->screen = screen; 01813 bc->pres = pres; 01814 } 01815 01816 return 0; 01817 }
static int update_ec_config | ( | struct misdn_bchannel * | bc | ) | [static] |
Definition at line 1896 of file chan_misdn.c.
References misdn_bchannel::ec_deftaps, misdn_bchannel::ec_enable, MISDN_CFG_ECHOCANCEL, misdn_cfg_get(), and misdn_bchannel::port.
Referenced by misdn_toggle_echocancel(), and read_config().
01897 { 01898 int ec; 01899 int port = bc->port; 01900 01901 misdn_cfg_get(port, MISDN_CFG_ECHOCANCEL, &ec, sizeof(int)); 01902 01903 if (ec == 1) { 01904 bc->ec_enable = 1; 01905 } else if (ec > 1) { 01906 bc->ec_enable = 1; 01907 bc->ec_deftaps = ec; 01908 } 01909 01910 return 0; 01911 }
static void update_name | ( | struct ast_channel * | tmp, | |
int | port, | |||
int | c | |||
) | [static] |
Definition at line 3430 of file chan_misdn.c.
References ast_string_field_build, chan_misdn_log(), misdn_cfg_get_next_port(), misdn_lib_port_is_pri(), misdn_type, ast_channel::name, and name.
Referenced by cb_events().
03431 { 03432 int chan_offset = 0; 03433 int tmp_port = misdn_cfg_get_next_port(0); 03434 for (; tmp_port > 0; tmp_port = misdn_cfg_get_next_port(tmp_port)) { 03435 if (tmp_port == port) 03436 break; 03437 chan_offset += misdn_lib_port_is_pri(tmp_port) ? 30 : 2; 03438 } 03439 if (c < 0) 03440 c = 0; 03441 03442 ast_string_field_build(tmp, name, "%s/%d-u%d", 03443 misdn_type, chan_offset + c, glob_channel++); 03444 03445 chan_misdn_log(3, port, " --> updating channel name to [%s]\n", tmp->name); 03446 }
static void wait_for_digits | ( | struct chan_list * | ch, | |
struct misdn_bchannel * | bc, | |||
struct ast_channel * | chan | |||
) | [static] |
Definition at line 3982 of file chan_misdn.c.
References misdn_bchannel::dad, dialtone_indicate(), EVENT_SETUP_ACKNOWLEDGE, misdn_lib_send_event(), MISDN_WAITING4DIGS, misdn_bchannel::nt, and chan_list::state.
Referenced by cb_events().
03982 { 03983 ch->state=MISDN_WAITING4DIGS; 03984 misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE ); 03985 if (bc->nt && !bc->dad[0]) 03986 dialtone_indicate(ch); 03987 }
struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT | AST_MODFLAG_BUILDSUM, .description = "Channel driver for mISDN Support (BRI/PRI)" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "6989f2ec67f8497e38c12890500c525b" , .load = load_module, .unload = unload_module, .reload = reload, } [static] |
Definition at line 5781 of file chan_misdn.c.
struct allowed_bearers allowed_bearers_array[] [static] |
const struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 5781 of file chan_misdn.c.
struct ast_cli_entry chan_misdn_clis[] [static] |
Global channel call record list head.
Definition at line 519 of file chan_misdn.c.
Referenced by cb_events(), chan_misdn_jb_empty(), get_chan_by_ast(), get_chan_by_ast_name(), import_ch(), misdn_hangup(), misdn_request(), misdn_show_cl(), misdn_show_cls(), and release_chan().
Definition at line 520 of file chan_misdn.c.
Referenced by cl_dequeue_chan(), cl_queue_chan(), and load_module().
Definition at line 514 of file chan_misdn.c.
int g_config_initialized = 0 [static] |
Definition at line 86 of file chan_misdn.c.
int glob_channel = 0 [static] |
Definition at line 3428 of file chan_misdn.c.
char global_tracefile[BUFFERSIZE+1] |
Definition at line 84 of file chan_misdn.c.
Definition at line 1380 of file chan_misdn.c.
Referenced by dahdi_request(), dahdi_restart(), dahdi_show_channel(), dahdi_show_channels(), handle_show_locks(), load_config(), load_module(), load_rpt_vars(), rpt_master(), smdi_message_wait(), and unload_module().
int max_ports [static] |
Definition at line 508 of file chan_misdn.c.
Referenced by _build_port_config(), 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(), and misdn_cfg_update_ptp().
int MAXTICS = 8 |
Definition at line 1381 of file chan_misdn.c.
int* misdn_debug [static] |
Definition at line 506 of file chan_misdn.c.
Referenced by chan_misdn_log(), load_module(), misdn_show_port(), misdn_show_stacks(), and unload_module().
int* misdn_debug_only [static] |
Definition at line 507 of file chan_misdn.c.
Referenced by chan_misdn_log(), load_module(), misdn_show_port(), misdn_show_stacks(), and unload_module().
int* misdn_in_calls [static] |
Definition at line 510 of file chan_misdn.c.
Referenced by add_in_calls(), load_module(), misdn_show_ports_stats(), and release_chan().
int* misdn_out_calls [static] |
Definition at line 511 of file chan_misdn.c.
Referenced by add_out_calls(), load_module(), misdn_show_ports_stats(), and release_chan().
int* misdn_ports [static] |
Definition at line 481 of file chan_misdn.c.
struct sched_context* misdn_tasks = NULL [static] |
the main schedule context for stuff like l1 watcher, overlap dial, ...
Definition at line 478 of file chan_misdn.c.
Referenced by _misdn_tasks_add_variable(), misdn_tasks_destroy(), misdn_tasks_init(), misdn_tasks_remove(), and misdn_tasks_thread_func().
pthread_t misdn_tasks_thread [static] |
Definition at line 479 of file chan_misdn.c.
struct ast_channel_tech misdn_tech [static] |
Definition at line 3390 of file chan_misdn.c.
Referenced by load_module(), misdn_new(), and unload_module().
struct ast_channel_tech misdn_tech_wo_bridge [static] |
const char misdn_type[] = "mISDN" [static] |
Definition at line 499 of file chan_misdn.c.
Referenced by load_module(), misdn_new(), misdn_request(), and update_name().
int prefformat = AST_FORMAT_ALAW [static] |
Only alaw and mulaw is allowed for now.
Definition at line 504 of file chan_misdn.c.
Referenced by misdn_new(), and misdn_write().
Definition at line 120 of file chan_misdn.c.
Referenced by load_module(), misdn_hangup(), and release_chan().
struct robin_list* robin = NULL [static] |
Definition at line 431 of file chan_misdn.c.
Referenced by free_robin_list(), and get_robin_position().
struct state_struct state_array[] [static] |
int tracing = 0 [static] |