#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 = "f450f61f60e761b3aa089ebed76ca8a5" , .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 5777 of file chan_misdn.c.
static void __unreg_module | ( | void | ) | [static] |
Definition at line 5777 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 3940 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().
03941 { 03942 int max_in_calls; 03943 03944 misdn_cfg_get(port, MISDN_CFG_MAX_IN, &max_in_calls, sizeof(max_in_calls)); 03945 misdn_in_calls[port]++; 03946 03947 if (max_in_calls >= 0 && max_in_calls < misdn_in_calls[port]) { 03948 ast_log(LOG_NOTICE, "Marking Incoming Call on port[%d]\n", port); 03949 return misdn_in_calls[port] - max_in_calls; 03950 } 03951 03952 return 0; 03953 }
int add_out_calls | ( | int | port | ) |
Definition at line 3955 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().
03956 { 03957 int max_out_calls; 03958 03959 misdn_cfg_get(port, MISDN_CFG_MAX_OUT, &max_out_calls, sizeof(max_out_calls)); 03960 03961 if (max_out_calls >= 0 && max_out_calls <= misdn_out_calls[port]) { 03962 ast_log(LOG_NOTICE, "Rejecting Outgoing Call on port[%d]\n", port); 03963 return (misdn_out_calls[port] + 1) - max_out_calls; 03964 } 03965 03966 misdn_out_calls[port]++; 03967 03968 return 0; 03969 }
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 3995 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().
03996 { 03997 int msn_valid; 03998 struct chan_list *ch = find_chan_by_bc(cl_te, bc); 03999 04000 if (event != EVENT_BCHAN_DATA && event != EVENT_TONE_GENERATE) { /* Debug Only Non-Bchan */ 04001 int debuglevel = 1; 04002 if ( event == EVENT_CLEANUP && !user_data) 04003 debuglevel = 5; 04004 04005 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"); 04006 if (debuglevel == 1) { 04007 misdn_lib_log_ies(bc); 04008 chan_misdn_log(4, bc->port, " --> bc_state:%s\n", bc_state2str(bc->bc_state)); 04009 } 04010 } 04011 04012 if (!ch) { 04013 switch(event) { 04014 case EVENT_SETUP: 04015 case EVENT_DISCONNECT: 04016 case EVENT_PORT_ALARM: 04017 case EVENT_RETRIEVE: 04018 case EVENT_NEW_BC: 04019 case EVENT_FACILITY: 04020 break; 04021 case EVENT_RELEASE_COMPLETE: 04022 chan_misdn_log(1, bc->port, " --> no Ch, so we've already released.\n"); 04023 break; 04024 case EVENT_CLEANUP: 04025 case EVENT_TONE_GENERATE: 04026 case EVENT_BCHAN_DATA: 04027 return -1; 04028 default: 04029 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); 04030 return -1; 04031 } 04032 } 04033 04034 if (ch) { 04035 switch (event) { 04036 case EVENT_TONE_GENERATE: 04037 break; 04038 case EVENT_DISCONNECT: 04039 case EVENT_RELEASE: 04040 case EVENT_RELEASE_COMPLETE: 04041 case EVENT_CLEANUP: 04042 case EVENT_TIMEOUT: 04043 if (!ch->ast) 04044 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)); 04045 break; 04046 default: 04047 if (!ch->ast || !MISDN_ASTERISK_PVT(ch->ast) || !MISDN_ASTERISK_TECH_PVT(ch->ast)) { 04048 if (event != EVENT_BCHAN_DATA) 04049 ast_log(LOG_NOTICE, "No Ast or No private Pointer in Event (%d:%s)\n", event, manager_isdn_get_info(event)); 04050 return -1; 04051 } 04052 } 04053 } 04054 04055 04056 switch (event) { 04057 case EVENT_PORT_ALARM: 04058 { 04059 int boa = 0; 04060 misdn_cfg_get(bc->port, MISDN_CFG_ALARM_BLOCK, &boa, sizeof(int)); 04061 if (boa) { 04062 cb_log(1, bc->port, " --> blocking\n"); 04063 misdn_lib_port_block(bc->port); 04064 } 04065 } 04066 break; 04067 case EVENT_BCHAN_ACTIVATED: 04068 break; 04069 04070 case EVENT_NEW_CHANNEL: 04071 update_name(ch->ast,bc->port,bc->channel); 04072 break; 04073 04074 case EVENT_NEW_L3ID: 04075 ch->l3id=bc->l3_id; 04076 ch->addr=bc->addr; 04077 break; 04078 04079 case EVENT_NEW_BC: 04080 if (!ch) { 04081 ch = find_holded(cl_te,bc); 04082 } 04083 04084 if (!ch) { 04085 ast_log(LOG_WARNING, "NEW_BC without chan_list?\n"); 04086 break; 04087 } 04088 04089 if (bc) 04090 ch->bc = (struct misdn_bchannel *)user_data; 04091 break; 04092 04093 case EVENT_DTMF_TONE: 04094 { 04095 /* sending INFOS as DTMF-Frames :) */ 04096 struct ast_frame fr; 04097 04098 memset(&fr, 0, sizeof(fr)); 04099 fr.frametype = AST_FRAME_DTMF; 04100 fr.subclass = bc->dtmf ; 04101 fr.src = NULL; 04102 fr.data = NULL; 04103 fr.datalen = 0; 04104 fr.samples = 0; 04105 fr.mallocd = 0; 04106 fr.offset = 0; 04107 fr.delivery = ast_tv(0,0); 04108 04109 if (!ch->ignore_dtmf) { 04110 chan_misdn_log(2, bc->port, " --> DTMF:%c\n", bc->dtmf); 04111 ast_queue_frame(ch->ast, &fr); 04112 } else { 04113 chan_misdn_log(2, bc->port, " --> Ignoring DTMF:%c due to bridge flags\n", bc->dtmf); 04114 } 04115 } 04116 break; 04117 case EVENT_STATUS: 04118 break; 04119 04120 case EVENT_INFORMATION: 04121 { 04122 if ( ch->state != MISDN_CONNECTED ) 04123 stop_indicate(ch); 04124 04125 if (!ch->ast) 04126 break; 04127 04128 if (ch->state == MISDN_WAITING4DIGS ) { 04129 /* Ok, incomplete Setup, waiting till extension exists */ 04130 if (ast_strlen_zero(bc->info_dad) && ! ast_strlen_zero(bc->keypad)) { 04131 chan_misdn_log(1, bc->port, " --> using keypad as info\n"); 04132 ast_copy_string(bc->info_dad, bc->keypad, sizeof(bc->info_dad)); 04133 } 04134 04135 strncat(bc->dad, bc->info_dad, sizeof(bc->dad) - strlen(bc->dad) - 1); 04136 ast_copy_string(ch->ast->exten, bc->dad, sizeof(ch->ast->exten)); 04137 04138 /* Check for Pickup Request first */ 04139 if (!strcmp(ch->ast->exten, ast_pickup_ext())) { 04140 if (ast_pickup_call(ch->ast)) { 04141 hangup_chan(ch); 04142 } else { 04143 struct ast_channel *chan = ch->ast; 04144 ch->state = MISDN_CALLING_ACKNOWLEDGE; 04145 ast_setstate(chan, AST_STATE_DOWN); 04146 hangup_chan(ch); 04147 ch->ast = NULL; 04148 break; 04149 } 04150 } 04151 04152 if (!ast_canmatch_extension(ch->ast, ch->context, bc->dad, 1, bc->oad)) { 04153 if (ast_exists_extension(ch->ast, ch->context, "i", 1, bc->oad)) { 04154 ast_log(LOG_WARNING, "Extension can never match, So jumping to 'i' extension. port(%d)\n", bc->port); 04155 strcpy(ch->ast->exten, "i"); 04156 04157 ch->state = MISDN_DIALING; 04158 start_pbx(ch, bc, ch->ast); 04159 break; 04160 } 04161 04162 ast_log(LOG_WARNING, "Extension can never match, so disconnecting on port(%d).\n" 04163 "\tMaybe you want to add an 'i' extension to catch this case.\n", 04164 bc->port); 04165 04166 if (bc->nt) 04167 hanguptone_indicate(ch); 04168 ch->state = MISDN_EXTCANTMATCH; 04169 bc->out_cause = AST_CAUSE_UNALLOCATED; 04170 04171 misdn_lib_send_event(bc, EVENT_DISCONNECT); 04172 break; 04173 } 04174 04175 if (ch->overlap_dial) { 04176 ast_mutex_lock(&ch->overlap_tv_lock); 04177 ch->overlap_tv = ast_tvnow(); 04178 ast_mutex_unlock(&ch->overlap_tv_lock); 04179 if (ch->overlap_dial_task == -1) { 04180 ch->overlap_dial_task = 04181 misdn_tasks_add_variable(ch->overlap_dial, misdn_overlap_dial_task, ch); 04182 } 04183 break; 04184 } 04185 04186 if (ast_exists_extension(ch->ast, ch->context, bc->dad, 1, bc->oad)) { 04187 04188 ch->state = MISDN_DIALING; 04189 start_pbx(ch, bc, ch->ast); 04190 } 04191 } else { 04192 /* sending INFOS as DTMF-Frames :) */ 04193 struct ast_frame fr; 04194 int digits; 04195 04196 memset(&fr, 0, sizeof(fr)); 04197 fr.frametype = AST_FRAME_DTMF; 04198 fr.subclass = bc->info_dad[0] ; 04199 fr.src = NULL; 04200 fr.data = NULL; 04201 fr.datalen = 0; 04202 fr.samples = 0; 04203 fr.mallocd = 0; 04204 fr.offset = 0; 04205 fr.delivery = ast_tv(0,0); 04206 04207 misdn_cfg_get(0, MISDN_GEN_APPEND_DIGITS2EXTEN, &digits, sizeof(int)); 04208 if (ch->state != MISDN_CONNECTED ) { 04209 if (digits) { 04210 strncat(bc->dad, bc->info_dad, sizeof(bc->dad) - strlen(bc->dad) - 1); 04211 ast_copy_string(ch->ast->exten, bc->dad, sizeof(ch->ast->exten)); 04212 ast_cdr_update(ch->ast); 04213 } 04214 04215 ast_queue_frame(ch->ast, &fr); 04216 } 04217 } 04218 } 04219 break; 04220 case EVENT_SETUP: 04221 { 04222 struct chan_list *ch = find_chan_by_bc(cl_te, bc); 04223 struct ast_channel *chan; 04224 int exceed; 04225 int pres, screen; 04226 int ai; 04227 int im; 04228 04229 if (ch) { 04230 switch (ch->state) { 04231 case MISDN_NOTHING: 04232 ch = NULL; 04233 break; 04234 default: 04235 chan_misdn_log(1, bc->port, " --> Ignoring Call we have already one\n"); 04236 return RESPONSE_IGNORE_SETUP_WITHOUT_CLOSE; /* Ignore MSNs which are not in our List */ 04237 } 04238 } 04239 04240 msn_valid = misdn_cfg_is_msn_valid(bc->port, bc->dad); 04241 if (!bc->nt && ! msn_valid) { 04242 chan_misdn_log(1, bc->port, " --> Ignoring Call, its not in our MSN List\n"); 04243 return RESPONSE_IGNORE_SETUP; /* Ignore MSNs which are not in our List */ 04244 } 04245 04246 if (bc->cw) { 04247 int cause; 04248 chan_misdn_log(0, bc->port, " --> Call Waiting on PMP sending RELEASE_COMPLETE\n"); 04249 misdn_cfg_get(bc->port, MISDN_CFG_REJECT_CAUSE, &cause, sizeof(cause)); 04250 bc->out_cause = cause ? cause : AST_CAUSE_NORMAL_CLEARING; 04251 return RESPONSE_RELEASE_SETUP; 04252 } 04253 04254 print_bearer(bc); 04255 04256 ch = init_chan_list(ORG_MISDN); 04257 04258 if (!ch) { 04259 chan_misdn_log(-1, bc->port, "cb_events: malloc for chan_list failed!\n"); 04260 return 0; 04261 } 04262 04263 ch->bc = bc; 04264 ch->l3id = bc->l3_id; 04265 ch->addr = bc->addr; 04266 ch->originator = ORG_MISDN; 04267 04268 chan = misdn_new(ch, AST_STATE_RESERVED, bc->dad, bc->oad, AST_FORMAT_ALAW, bc->port, bc->channel); 04269 if (!chan) { 04270 misdn_lib_send_event(bc,EVENT_RELEASE_COMPLETE); 04271 ast_log(LOG_ERROR, "cb_events: misdn_new failed !\n"); 04272 return 0; 04273 } 04274 04275 ch->ast = chan; 04276 04277 if ((exceed = add_in_calls(bc->port))) { 04278 char tmp[16]; 04279 snprintf(tmp, sizeof(tmp), "%d", exceed); 04280 pbx_builtin_setvar_helper(chan, "MAX_OVERFLOW", tmp); 04281 } 04282 04283 read_config(ch, ORG_MISDN); 04284 04285 export_ch(chan, bc, ch); 04286 04287 ch->ast->rings = 1; 04288 ast_setstate(ch->ast, AST_STATE_RINGING); 04289 04290 switch (bc->pres) { 04291 case 1: 04292 pres = AST_PRES_RESTRICTED; 04293 chan_misdn_log(2, bc->port, " --> PRES: Restricted (1)\n"); 04294 break; 04295 case 2: 04296 pres = AST_PRES_UNAVAILABLE; 04297 chan_misdn_log(2, bc->port, " --> PRES: Unavailable (2)\n"); 04298 break; 04299 default: 04300 pres = AST_PRES_ALLOWED; 04301 chan_misdn_log(2, bc->port, " --> PRES: Allowed (%d)\n", bc->pres); 04302 break; 04303 } 04304 04305 switch (bc->screen) { 04306 default: 04307 case 0: 04308 screen = AST_PRES_USER_NUMBER_UNSCREENED; 04309 chan_misdn_log(2, bc->port, " --> SCREEN: Unscreened (%d)\n", bc->screen); 04310 break; 04311 case 1: 04312 screen = AST_PRES_USER_NUMBER_PASSED_SCREEN; 04313 chan_misdn_log(2, bc->port, " --> SCREEN: Passed screen (1)\n"); 04314 break; 04315 case 2: 04316 screen = AST_PRES_USER_NUMBER_FAILED_SCREEN; 04317 chan_misdn_log(2, bc->port, " --> SCREEN: failed screen (2)\n"); 04318 break; 04319 case 3: 04320 screen = AST_PRES_NETWORK_NUMBER; 04321 chan_misdn_log(2, bc->port, " --> SCREEN: Network Number (3)\n"); 04322 break; 04323 } 04324 04325 chan->cid.cid_pres = pres | screen; 04326 04327 pbx_builtin_setvar_helper(chan, "TRANSFERCAPABILITY", ast_transfercapability2str(bc->capability)); 04328 chan->transfercapability = bc->capability; 04329 04330 switch (bc->capability) { 04331 case INFO_CAPABILITY_DIGITAL_UNRESTRICTED: 04332 pbx_builtin_setvar_helper(chan, "CALLTYPE", "DIGITAL"); 04333 break; 04334 default: 04335 pbx_builtin_setvar_helper(chan, "CALLTYPE", "SPEECH"); 04336 } 04337 04338 /** queue new chan **/ 04339 cl_queue_chan(&cl_te, ch); 04340 04341 if (!strstr(ch->allowed_bearers, "all")) { 04342 int i; 04343 04344 for (i = 0; i < ARRAY_LEN(allowed_bearers_array); ++i) { 04345 if (allowed_bearers_array[i].cap == bc->capability) { 04346 if (strstr(ch->allowed_bearers, allowed_bearers_array[i].name)) { 04347 /* The bearer capability is allowed */ 04348 if (allowed_bearers_array[i].deprecated) { 04349 chan_misdn_log(0, bc->port, "%s in allowed_bearers list is deprecated\n", 04350 allowed_bearers_array[i].name); 04351 } 04352 break; 04353 } 04354 } 04355 } /* end for */ 04356 if (i == ARRAY_LEN(allowed_bearers_array)) { 04357 /* We did not find the bearer capability */ 04358 chan_misdn_log(0, bc->port, "Bearer capability not allowed: %s(%d)\n", 04359 bearer2str(bc->capability), bc->capability); 04360 bc->out_cause = AST_CAUSE_INCOMPATIBLE_DESTINATION; 04361 04362 ch->state = MISDN_EXTCANTMATCH; 04363 misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE); 04364 return RESPONSE_OK; 04365 } 04366 } 04367 04368 /* Check for Pickup Request first */ 04369 if (!strcmp(chan->exten, ast_pickup_ext())) { 04370 if (!ch->noautorespond_on_setup) { 04371 int ret;/** Sending SETUP_ACK**/ 04372 ret = misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE ); 04373 } else { 04374 ch->state = MISDN_INCOMING_SETUP; 04375 } 04376 if (ast_pickup_call(chan)) { 04377 hangup_chan(ch); 04378 } else { 04379 ch->state = MISDN_CALLING_ACKNOWLEDGE; 04380 ast_setstate(chan, AST_STATE_DOWN); 04381 hangup_chan(ch); 04382 ch->ast = NULL; 04383 break; 04384 } 04385 } 04386 04387 /* 04388 * added support for s extension hope it will help those poor cretains 04389 * which haven't overlap dial. 04390 */ 04391 misdn_cfg_get(bc->port, MISDN_CFG_ALWAYS_IMMEDIATE, &ai, sizeof(ai)); 04392 if (ai) { 04393 do_immediate_setup(bc, ch, chan); 04394 break; 04395 } 04396 04397 /* check if we should jump into s when we have no dad */ 04398 misdn_cfg_get(bc->port, MISDN_CFG_IMMEDIATE, &im, sizeof(im)); 04399 if (im && ast_strlen_zero(bc->dad)) { 04400 do_immediate_setup(bc, ch, chan); 04401 break; 04402 } 04403 04404 chan_misdn_log(5, bc->port, "CONTEXT:%s\n", ch->context); 04405 if(!ast_canmatch_extension(ch->ast, ch->context, bc->dad, 1, bc->oad)) { 04406 if (ast_exists_extension(ch->ast, ch->context, "i", 1, bc->oad)) { 04407 ast_log(LOG_WARNING, "Extension can never match, So jumping to 'i' extension. port(%d)\n", bc->port); 04408 strcpy(ch->ast->exten, "i"); 04409 misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE); 04410 ch->state = MISDN_DIALING; 04411 start_pbx(ch, bc, chan); 04412 break; 04413 } 04414 04415 ast_log(LOG_WARNING, "Extension can never match, so disconnecting on port(%d).\n" 04416 "\tMaybe you want to add an 'i' extension to catch this case.\n", 04417 bc->port); 04418 if (bc->nt) 04419 hanguptone_indicate(ch); 04420 04421 ch->state = MISDN_EXTCANTMATCH; 04422 bc->out_cause = AST_CAUSE_UNALLOCATED; 04423 04424 if (bc->nt) 04425 misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE ); 04426 else 04427 misdn_lib_send_event(bc, EVENT_RELEASE ); 04428 04429 break; 04430 } 04431 04432 /* Whatever happens, when sending_complete is set or we are PTMP TE, we will definitely 04433 * jump into the dialplan, when the dialed extension does not exist, the 's' extension 04434 * will be used by Asterisk automatically. */ 04435 if (bc->sending_complete || (!bc->nt && !misdn_lib_is_ptp(bc->port))) { 04436 if (!ch->noautorespond_on_setup) { 04437 ch->state=MISDN_DIALING; 04438 misdn_lib_send_event(bc, EVENT_PROCEEDING ); 04439 } else { 04440 ch->state = MISDN_INCOMING_SETUP; 04441 } 04442 start_pbx(ch, bc, chan); 04443 break; 04444 } 04445 04446 04447 /* 04448 * When we are NT and overlapdial is set and if 04449 * the number is empty, we wait for the ISDN timeout 04450 * instead of our own timer. 04451 */ 04452 if (ch->overlap_dial && bc->nt && !bc->dad[0] ) { 04453 wait_for_digits(ch, bc, chan); 04454 break; 04455 } 04456 04457 /* 04458 * If overlapdial we will definitely send a SETUP_ACKNOWLEDGE and wait for more 04459 * Infos with a Interdigit Timeout. 04460 * */ 04461 if (ch->overlap_dial) { 04462 ast_mutex_lock(&ch->overlap_tv_lock); 04463 ch->overlap_tv = ast_tvnow(); 04464 ast_mutex_unlock(&ch->overlap_tv_lock); 04465 04466 wait_for_digits(ch, bc, chan); 04467 if (ch->overlap_dial_task == -1) 04468 ch->overlap_dial_task = 04469 misdn_tasks_add_variable(ch->overlap_dial, misdn_overlap_dial_task, ch); 04470 04471 break; 04472 } 04473 04474 /* If the extension does not exist and we're not TE_PTMP we wait for more digits 04475 * without interdigit timeout. 04476 * */ 04477 if (!ast_exists_extension(ch->ast, ch->context, bc->dad, 1, bc->oad)) { 04478 wait_for_digits(ch, bc, chan); 04479 break; 04480 } 04481 04482 /* 04483 * If the extension exists let's just jump into it. 04484 * */ 04485 if (ast_exists_extension(ch->ast, ch->context, bc->dad, 1, bc->oad)) { 04486 if (bc->need_more_infos) 04487 misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE ); 04488 else 04489 misdn_lib_send_event(bc, EVENT_PROCEEDING); 04490 04491 ch->state = MISDN_DIALING; 04492 start_pbx(ch, bc, chan); 04493 break; 04494 } 04495 } 04496 break; 04497 04498 case EVENT_SETUP_ACKNOWLEDGE: 04499 { 04500 ch->state = MISDN_CALLING_ACKNOWLEDGE; 04501 04502 if (bc->channel) 04503 update_name(ch->ast,bc->port,bc->channel); 04504 04505 if (!ast_strlen_zero(bc->infos_pending)) { 04506 /* TX Pending Infos */ 04507 strncat(bc->dad, bc->infos_pending, sizeof(bc->dad) - strlen(bc->dad) - 1); 04508 04509 if (!ch->ast) 04510 break; 04511 ast_copy_string(ch->ast->exten, bc->dad, sizeof(ch->ast->exten)); 04512 ast_copy_string(bc->info_dad, bc->infos_pending, sizeof(bc->info_dad)); 04513 ast_copy_string(bc->infos_pending, "", sizeof(bc->infos_pending)); 04514 04515 misdn_lib_send_event(bc, EVENT_INFORMATION); 04516 } 04517 } 04518 break; 04519 case EVENT_PROCEEDING: 04520 { 04521 if (bc->channel) 04522 update_name(ch->ast, bc->port, bc->channel); 04523 04524 if (misdn_cap_is_speech(bc->capability) && 04525 misdn_inband_avail(bc) ) { 04526 start_bc_tones(ch); 04527 } 04528 04529 ch->state = MISDN_PROCEEDING; 04530 04531 if (!ch->ast) 04532 break; 04533 04534 ast_queue_control(ch->ast, AST_CONTROL_PROCEEDING); 04535 } 04536 break; 04537 case EVENT_PROGRESS: 04538 if (bc->channel) 04539 update_name(ch->ast, bc->port, bc->channel); 04540 04541 if (!bc->nt ) { 04542 if ( misdn_cap_is_speech(bc->capability) && 04543 misdn_inband_avail(bc) 04544 ) { 04545 start_bc_tones(ch); 04546 } 04547 04548 ch->state = MISDN_PROGRESS; 04549 04550 if (!ch->ast) 04551 break; 04552 ast_queue_control(ch->ast, AST_CONTROL_PROGRESS); 04553 } 04554 break; 04555 04556 04557 case EVENT_ALERTING: 04558 { 04559 if (bc->channel) 04560 update_name(ch->ast, bc->port, bc->channel); 04561 04562 ch->state = MISDN_ALERTING; 04563 04564 if (!ch->ast) 04565 break; 04566 04567 ast_queue_control(ch->ast, AST_CONTROL_RINGING); 04568 ast_setstate(ch->ast, AST_STATE_RINGING); 04569 04570 cb_log(7, bc->port, " --> Set State Ringing\n"); 04571 04572 if (misdn_cap_is_speech(bc->capability) && misdn_inband_avail(bc)) { 04573 cb_log(1, bc->port, "Starting Tones, we have inband Data\n"); 04574 start_bc_tones(ch); 04575 } else { 04576 cb_log(3, bc->port, " --> We have no inband Data, the other end must create ringing\n"); 04577 if (ch->far_alerting) { 04578 cb_log(1, bc->port, " --> The other end can not do ringing eh ?.. we must do all ourself.."); 04579 start_bc_tones(ch); 04580 /*tone_indicate(ch, TONE_FAR_ALERTING);*/ 04581 } 04582 } 04583 } 04584 break; 04585 case EVENT_CONNECT: 04586 { 04587 struct ast_channel *bridged; 04588 04589 /*we answer when we've got our very new L3 ID from the NT stack */ 04590 misdn_lib_send_event(bc, EVENT_CONNECT_ACKNOWLEDGE); 04591 04592 if (!ch->ast) 04593 break; 04594 04595 bridged = ast_bridged_channel(ch->ast); 04596 stop_indicate(ch); 04597 04598 if (bridged && !strcasecmp(bridged->tech->type, "mISDN")) { 04599 struct chan_list *bridged_ch = MISDN_ASTERISK_TECH_PVT(bridged); 04600 04601 chan_misdn_log(1, bc->port, " --> copying cpndialplan:%d and cad:%s to the A-Channel\n", bc->cpnnumplan, bc->cad); 04602 if (bridged_ch) { 04603 bridged_ch->bc->cpnnumplan = bc->cpnnumplan; 04604 ast_copy_string(bridged_ch->bc->cad, bc->cad, sizeof(bridged_ch->bc->cad)); 04605 } 04606 } 04607 } 04608 ch->l3id=bc->l3_id; 04609 ch->addr=bc->addr; 04610 04611 start_bc_tones(ch); 04612 04613 ch->state = MISDN_CONNECTED; 04614 04615 ast_queue_control(ch->ast, AST_CONTROL_ANSWER); 04616 break; 04617 case EVENT_CONNECT_ACKNOWLEDGE: 04618 { 04619 ch->l3id = bc->l3_id; 04620 ch->addr = bc->addr; 04621 04622 start_bc_tones(ch); 04623 04624 ch->state = MISDN_CONNECTED; 04625 } 04626 break; 04627 case EVENT_DISCONNECT: 04628 /*we might not have an ch->ast ptr here anymore*/ 04629 if (ch) { 04630 struct chan_list *holded_ch = find_holded(cl_te, bc); 04631 04632 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); 04633 if (ch->originator == ORG_AST && !bc->nt && misdn_inband_avail(bc) && ch->state != MISDN_CONNECTED) { 04634 /* If there's inband information available (e.g. a 04635 recorded message saying what was wrong with the 04636 dialled number, or perhaps even giving an 04637 alternative number, then play it instead of 04638 immediately releasing the call */ 04639 chan_misdn_log(1, bc->port, " --> Inband Info Avail, not sending RELEASE\n"); 04640 04641 ch->state = MISDN_DISCONNECTED; 04642 start_bc_tones(ch); 04643 04644 if (ch->ast) { 04645 ch->ast->hangupcause = bc->cause; 04646 if (bc->cause == AST_CAUSE_USER_BUSY) 04647 ast_queue_control(ch->ast, AST_CONTROL_BUSY); 04648 } 04649 ch->need_busy = 0; 04650 break; 04651 } 04652 04653 /*Check for holded channel, to implement transfer*/ 04654 if (holded_ch && holded_ch != ch && ch->ast && ch->state == MISDN_CONNECTED) { 04655 cb_log(1, bc->port, " --> found holded ch\n"); 04656 misdn_transfer_bc(ch, holded_ch) ; 04657 } 04658 04659 bc->need_disconnect = 0; 04660 04661 stop_bc_tones(ch); 04662 hangup_chan(ch); 04663 #if 0 04664 } else { 04665 ch = find_holded_l3(cl_te, bc->l3_id,1); 04666 if (ch) { 04667 hangup_chan(ch); 04668 } 04669 #endif 04670 } 04671 bc->out_cause = -1; 04672 if (bc->need_release) 04673 misdn_lib_send_event(bc, EVENT_RELEASE); 04674 break; 04675 04676 case EVENT_RELEASE: 04677 { 04678 bc->need_disconnect = 0; 04679 bc->need_release = 0; 04680 04681 hangup_chan(ch); 04682 release_chan(bc); 04683 } 04684 break; 04685 case EVENT_RELEASE_COMPLETE: 04686 { 04687 bc->need_disconnect = 0; 04688 bc->need_release = 0; 04689 bc->need_release_complete = 0; 04690 04691 stop_bc_tones(ch); 04692 hangup_chan(ch); 04693 04694 if (ch) 04695 ch->state = MISDN_CLEANING; 04696 04697 release_chan(bc); 04698 } 04699 break; 04700 case EVENT_BCHAN_ERROR: 04701 case EVENT_CLEANUP: 04702 { 04703 stop_bc_tones(ch); 04704 04705 switch (ch->state) { 04706 case MISDN_CALLING: 04707 bc->cause = AST_CAUSE_DESTINATION_OUT_OF_ORDER; 04708 break; 04709 default: 04710 break; 04711 } 04712 04713 hangup_chan(ch); 04714 release_chan(bc); 04715 } 04716 break; 04717 04718 case EVENT_TONE_GENERATE: 04719 { 04720 int tone_len = bc->tone_cnt; 04721 struct ast_channel *ast = ch->ast; 04722 void *tmp; 04723 int res; 04724 int (*generate)(struct ast_channel *chan, void *tmp, int datalen, int samples); 04725 04726 chan_misdn_log(9, bc->port, "TONE_GEN: len:%d\n", tone_len); 04727 04728 if (!ast) 04729 break; 04730 04731 if (!ast->generator) 04732 break; 04733 04734 tmp = ast->generatordata; 04735 ast->generatordata = NULL; 04736 generate = ast->generator->generate; 04737 04738 if (tone_len < 0 || tone_len > 512 ) { 04739 ast_log(LOG_NOTICE, "TONE_GEN: len was %d, set to 128\n", tone_len); 04740 tone_len = 128; 04741 } 04742 04743 res = generate(ast, tmp, tone_len, tone_len); 04744 ast->generatordata = tmp; 04745 04746 if (res) { 04747 ast_log(LOG_WARNING, "Auto-deactivating generator\n"); 04748 ast_deactivate_generator(ast); 04749 } else { 04750 bc->tone_cnt = 0; 04751 } 04752 } 04753 break; 04754 04755 case EVENT_BCHAN_DATA: 04756 { 04757 if (!misdn_cap_is_speech(ch->bc->capability)) { 04758 struct ast_frame frame; 04759 /*In Data Modes we queue frames*/ 04760 frame.frametype = AST_FRAME_VOICE; /*we have no data frames yet*/ 04761 frame.subclass = AST_FORMAT_ALAW; 04762 frame.datalen = bc->bframe_len; 04763 frame.samples = bc->bframe_len; 04764 frame.mallocd = 0; 04765 frame.offset = 0; 04766 frame.delivery = ast_tv(0,0); 04767 frame.src = NULL; 04768 frame.data = bc->bframe; 04769 04770 if (ch->ast) 04771 ast_queue_frame(ch->ast, &frame); 04772 } else { 04773 fd_set wrfs; 04774 struct timeval tv = { 0, 0 }; 04775 int t; 04776 04777 FD_ZERO(&wrfs); 04778 FD_SET(ch->pipe[1], &wrfs); 04779 04780 t = select(FD_SETSIZE, NULL, &wrfs, NULL, &tv); 04781 04782 if (!t) { 04783 chan_misdn_log(9, bc->port, "Select Timed out\n"); 04784 break; 04785 } 04786 04787 if (t < 0) { 04788 chan_misdn_log(-1, bc->port, "Select Error (err=%s)\n", strerror(errno)); 04789 break; 04790 } 04791 04792 if (FD_ISSET(ch->pipe[1], &wrfs)) { 04793 chan_misdn_log(9, bc->port, "writing %d bytes to asterisk\n", bc->bframe_len); 04794 if (write(ch->pipe[1], bc->bframe, bc->bframe_len) <= 0) { 04795 chan_misdn_log(0, bc->port, "Write returned <=0 (err=%s) --> hanging up channel\n", strerror(errno)); 04796 04797 stop_bc_tones(ch); 04798 hangup_chan(ch); 04799 release_chan(bc); 04800 } 04801 } else { 04802 chan_misdn_log(1, bc->port, "Write Pipe full!\n"); 04803 } 04804 } 04805 } 04806 break; 04807 case EVENT_TIMEOUT: 04808 { 04809 if (ch && bc) 04810 chan_misdn_log(1, bc->port, "--> state: %s\n", misdn_get_ch_state(ch)); 04811 04812 switch (ch->state) { 04813 case MISDN_DIALING: 04814 case MISDN_PROGRESS: 04815 if (bc->nt && !ch->nttimeout) 04816 break; 04817 04818 case MISDN_CALLING: 04819 case MISDN_ALERTING: 04820 case MISDN_PROCEEDING: 04821 case MISDN_CALLING_ACKNOWLEDGE: 04822 if (bc->nt) { 04823 bc->progress_indicator = INFO_PI_INBAND_AVAILABLE; 04824 hanguptone_indicate(ch); 04825 } 04826 04827 bc->out_cause = AST_CAUSE_UNALLOCATED; 04828 misdn_lib_send_event(bc, EVENT_DISCONNECT); 04829 break; 04830 04831 case MISDN_WAITING4DIGS: 04832 if (bc->nt) { 04833 bc->progress_indicator = INFO_PI_INBAND_AVAILABLE; 04834 bc->out_cause = AST_CAUSE_UNALLOCATED; 04835 hanguptone_indicate(ch); 04836 misdn_lib_send_event(bc, EVENT_DISCONNECT); 04837 } else { 04838 bc->out_cause = AST_CAUSE_NORMAL_CLEARING; 04839 misdn_lib_send_event(bc, EVENT_RELEASE); 04840 } 04841 04842 break; 04843 04844 case MISDN_CLEANING: 04845 chan_misdn_log(1,bc->port," --> in state cleaning .. so ignoring, the stack should clean it for us\n"); 04846 break; 04847 04848 default: 04849 misdn_lib_send_event(bc,EVENT_RELEASE_COMPLETE); 04850 } 04851 } 04852 break; 04853 04854 04855 /****************************/ 04856 /** Supplementary Services **/ 04857 /****************************/ 04858 case EVENT_RETRIEVE: 04859 { 04860 struct ast_channel *hold_ast; 04861 04862 if (!ch) { 04863 chan_misdn_log(4, bc->port, " --> no CH, searching in holded\n"); 04864 ch = find_holded_l3(cl_te, bc->l3_id, 1); 04865 } 04866 04867 if (!ch) { 04868 ast_log(LOG_WARNING, "Found no Holded channel, cannot Retrieve\n"); 04869 misdn_lib_send_event(bc, EVENT_RETRIEVE_REJECT); 04870 break; 04871 } 04872 04873 /*remember the channel again*/ 04874 ch->bc = bc; 04875 ch->state = MISDN_CONNECTED; 04876 04877 ch->hold_info.port = 0; 04878 ch->hold_info.channel = 0; 04879 04880 hold_ast = ast_bridged_channel(ch->ast); 04881 04882 if (hold_ast) { 04883 ast_moh_stop(hold_ast); 04884 } 04885 04886 if (misdn_lib_send_event(bc, EVENT_RETRIEVE_ACKNOWLEDGE) < 0) { 04887 chan_misdn_log(4, bc->port, " --> RETRIEVE_ACK failed\n"); 04888 misdn_lib_send_event(bc, EVENT_RETRIEVE_REJECT); 04889 } 04890 } 04891 break; 04892 04893 case EVENT_HOLD: 04894 { 04895 int hold_allowed; 04896 struct ast_channel *bridged; 04897 04898 misdn_cfg_get(bc->port, MISDN_CFG_HOLD_ALLOWED, &hold_allowed, sizeof(int)); 04899 04900 if (!hold_allowed) { 04901 04902 chan_misdn_log(-1, bc->port, "Hold not allowed this port.\n"); 04903 misdn_lib_send_event(bc, EVENT_HOLD_REJECT); 04904 break; 04905 } 04906 04907 bridged = ast_bridged_channel(ch->ast); 04908 if (bridged) { 04909 chan_misdn_log(2, bc->port, "Bridge Partner is of type: %s\n", bridged->tech->type); 04910 ch->state = MISDN_HOLDED; 04911 ch->l3id = bc->l3_id; 04912 04913 misdn_lib_send_event(bc, EVENT_HOLD_ACKNOWLEDGE); 04914 04915 /* XXX This should queue an AST_CONTROL_HOLD frame on this channel 04916 * instead of starting moh on the bridged channel directly */ 04917 ast_moh_start(bridged, NULL, NULL); 04918 04919 /*forget the channel now*/ 04920 ch->bc = NULL; 04921 ch->hold_info.port = bc->port; 04922 ch->hold_info.channel = bc->channel; 04923 04924 } else { 04925 misdn_lib_send_event(bc, EVENT_HOLD_REJECT); 04926 chan_misdn_log(0, bc->port, "We aren't bridged to anybody\n"); 04927 } 04928 } 04929 break; 04930 04931 case EVENT_FACILITY: 04932 if (!ch) { 04933 /* This may come from a call we don't know nothing about, so we ignore it. */ 04934 chan_misdn_log(-1, bc->port, "Got EVENT_FACILITY but we don't have a ch!\n"); 04935 break; 04936 } 04937 04938 print_facility(&(bc->fac_in), bc); 04939 04940 switch (bc->fac_in.Function) { 04941 case Fac_CD: 04942 { 04943 struct ast_channel *bridged = ast_bridged_channel(ch->ast); 04944 struct chan_list *ch_br; 04945 if (bridged && MISDN_ASTERISK_TECH_PVT(bridged)) { 04946 ch_br = MISDN_ASTERISK_TECH_PVT(bridged); 04947 /*ch->state = MISDN_FACILITY_DEFLECTED;*/ 04948 if (ch_br->bc) { 04949 if (ast_exists_extension(bridged, ch->context, (char *)bc->fac_in.u.CDeflection.DeflectedToNumber, 1, bc->oad)) { 04950 ch_br->state = MISDN_DIALING; 04951 if (pbx_start_chan(ch_br) < 0) { 04952 chan_misdn_log(-1, ch_br->bc->port, "ast_pbx_start returned < 0 in misdn_overlap_dial_task\n"); 04953 } 04954 } 04955 } 04956 } 04957 misdn_lib_send_event(bc, EVENT_DISCONNECT); 04958 } 04959 break; 04960 case Fac_AOCDCurrency: 04961 { 04962 bc->AOCDtype = Fac_AOCDCurrency; 04963 memcpy(&(bc->AOCD.currency), &(bc->fac_in.u.AOCDcur), sizeof(struct FacAOCDCurrency)); 04964 export_aoc_vars(ch->originator, ch->ast, bc); 04965 } 04966 break; 04967 case Fac_AOCDChargingUnit: 04968 { 04969 bc->AOCDtype = Fac_AOCDChargingUnit; 04970 memcpy(&(bc->AOCD.chargingUnit), &(bc->fac_in.u.AOCDchu), sizeof(struct FacAOCDChargingUnit)); 04971 export_aoc_vars(ch->originator, ch->ast, bc); 04972 } 04973 break; 04974 default: 04975 chan_misdn_log(0, bc->port," --> not yet handled: facility type:%d\n", bc->fac_in.Function); 04976 } 04977 04978 break; 04979 04980 case EVENT_RESTART: 04981 04982 if (!bc->dummy) { 04983 stop_bc_tones(ch); 04984 release_chan(bc); 04985 } 04986 break; 04987 04988 default: 04989 chan_misdn_log(1, 0, "Got Unknown Event\n"); 04990 break; 04991 } 04992 04993 return RESPONSE_OK; 04994 }
int chan_misdn_jb_empty | ( | struct misdn_bchannel * | bc, | |
char * | buf, | |||
int | len | |||
) |
Definition at line 5531 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().
05532 { 05533 struct chan_list *ch = find_chan_by_bc(cl_te, bc); 05534 05535 if (ch && ch->jb) { 05536 return misdn_jb_empty(ch->jb, buf, len); 05537 } 05538 05539 return -1; 05540 }
static void chan_misdn_log | ( | int | level, | |
int | port, | |||
char * | tmpl, | |||
... | ||||
) | [static] |
Definition at line 5714 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().
05715 { 05716 va_list ap; 05717 char buf[1024]; 05718 char port_buf[8]; 05719 05720 if (! ((0 <= port) && (port <= max_ports))) { 05721 ast_log(LOG_WARNING, "cb_log called with out-of-range port number! (%d)\n", port); 05722 port = 0; 05723 level = -1; 05724 } 05725 05726 snprintf(port_buf, sizeof(port_buf), "P[%2d] ", port); 05727 05728 va_start(ap, tmpl); 05729 vsnprintf(buf, sizeof(buf), tmpl, ap); 05730 va_end(ap); 05731 05732 if (level == -1) 05733 ast_log(LOG_WARNING, "%s", buf); 05734 05735 else if (misdn_debug_only[port] ? 05736 (level == 1 && misdn_debug[port]) || (level == misdn_debug[port]) 05737 : level <= misdn_debug[port]) { 05738 05739 ast_console_puts(port_buf); 05740 ast_console_puts(buf); 05741 } 05742 05743 if ((level <= misdn_debug[0]) && !ast_strlen_zero(global_tracefile) ) { 05744 time_t tm = time(NULL); 05745 char *tmp = ctime(&tm), *p; 05746 05747 FILE *fp = fopen(global_tracefile, "a+"); 05748 05749 p = strchr(tmp, '\n'); 05750 if (p) 05751 *p = ':'; 05752 05753 if (!fp) { 05754 ast_console_puts("Error opening Tracefile: [ "); 05755 ast_console_puts(global_tracefile); 05756 ast_console_puts(" ] "); 05757 05758 ast_console_puts(strerror(errno)); 05759 ast_console_puts("\n"); 05760 return ; 05761 } 05762 05763 fputs(tmp, fp); 05764 fputs(" ", fp); 05765 fputs(port_buf, fp); 05766 fputs(" ", fp); 05767 fputs(buf, fp); 05768 05769 fclose(fp); 05770 } 05771 }
Definition at line 3594 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().
03595 { 03596 struct chan_list *help; 03597 03598 if (chan->dsp) 03599 ast_dsp_free(chan->dsp); 03600 if (chan->trans) 03601 ast_translator_free_path(chan->trans); 03602 03603 ast_mutex_lock(&cl_te_lock); 03604 if (!*list) { 03605 ast_mutex_unlock(&cl_te_lock); 03606 return; 03607 } 03608 03609 if (*list == chan) { 03610 *list = (*list)->next; 03611 ast_mutex_unlock(&cl_te_lock); 03612 return; 03613 } 03614 03615 for (help = *list; help->next; help = help->next) { 03616 if (help->next == chan) { 03617 help->next = help->next->next; 03618 ast_mutex_unlock(&cl_te_lock); 03619 return; 03620 } 03621 } 03622 03623 ast_mutex_unlock(&cl_te_lock); 03624 }
Definition at line 3578 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().
03579 { 03580 chan_misdn_log(4, chan->bc ? chan->bc->port : 0, "* Queuing chan %p\n", chan); 03581 03582 ast_mutex_lock(&cl_te_lock); 03583 if (!*list) { 03584 *list = chan; 03585 } else { 03586 struct chan_list *help = *list; 03587 for (; help->next; help = help->next); 03588 help->next = chan; 03589 } 03590 chan->next = NULL; 03591 ast_mutex_unlock(&cl_te_lock); 03592 }
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 3081 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().
03082 { 03083 const struct tone_zone_sound *ts = NULL; 03084 struct ast_channel *ast = cl->ast; 03085 int nd = 0; 03086 03087 if (!ast) { 03088 chan_misdn_log(0, cl->bc->port, "No Ast in dialtone_indicate\n"); 03089 return -1; 03090 } 03091 03092 misdn_cfg_get(cl->bc->port, MISDN_CFG_NODIALTONE, &nd, sizeof(nd)); 03093 03094 if (nd) { 03095 chan_misdn_log(1, cl->bc->port, "Not sending Dialtone, because config wants it\n"); 03096 return 0; 03097 } 03098 03099 chan_misdn_log(3, cl->bc->port, " --> Dial\n"); 03100 ts = ast_get_indication_tone(ast->zone, "dial"); 03101 cl->ts = ts; 03102 03103 if (ts) { 03104 cl->notxtone = 0; 03105 cl->norxtone = 0; 03106 /* This prods us in misdn_write */ 03107 ast_playtones_start(ast, 0, ts->data, 0); 03108 } 03109 03110 return 0; 03111 }
static void do_immediate_setup | ( | struct misdn_bchannel * | bc, | |
struct chan_list * | ch, | |||
struct ast_channel * | ast | |||
) | [static] |
Definition at line 3760 of file chan_misdn.c.
References chan_list::ast, 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, ast_frame::offset, pbx_start_chan(), misdn_bchannel::port, ast_frame::samples, ast_frame::src, chan_list::state, and ast_frame::subclass.
Referenced by cb_events().
03761 { 03762 char predial[256]=""; 03763 char *p = predial; 03764 03765 struct ast_frame fr; 03766 03767 strncpy(predial, ast->exten, sizeof(predial) -1 ); 03768 03769 ch->state = MISDN_DIALING; 03770 03771 if (!ch->noautorespond_on_setup) { 03772 if (bc->nt) { 03773 int ret; 03774 ret = misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE ); 03775 } else { 03776 int ret; 03777 if ( misdn_lib_is_ptp(bc->port)) { 03778 ret = misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE ); 03779 } else { 03780 ret = misdn_lib_send_event(bc, EVENT_PROCEEDING ); 03781 } 03782 } 03783 } else { 03784 ch->state = MISDN_INCOMING_SETUP; 03785 } 03786 03787 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); 03788 03789 strcpy(ast->exten, "s"); 03790 03791 if (pbx_start_chan(ch) < 0) { 03792 ast = NULL; 03793 hangup_chan(ch); 03794 hanguptone_indicate(ch); 03795 03796 if (bc->nt) 03797 misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE ); 03798 else 03799 misdn_lib_send_event(bc, EVENT_DISCONNECT ); 03800 } 03801 03802 03803 while (!ast_strlen_zero(p) ) { 03804 fr.frametype = AST_FRAME_DTMF; 03805 fr.subclass = *p; 03806 fr.src = NULL; 03807 fr.data = NULL; 03808 fr.datalen = 0; 03809 fr.samples = 0; 03810 fr.mallocd = 0; 03811 fr.offset = 0; 03812 fr.delivery = ast_tv(0,0); 03813 03814 if (ch->ast && MISDN_ASTERISK_PVT(ch->ast) && MISDN_ASTERISK_TECH_PVT(ch->ast)) { 03815 ast_queue_frame(ch->ast, &fr); 03816 } 03817 p++; 03818 } 03819 }
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 3914 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().
03915 { 03916 char tmp[32]; 03917 chan_misdn_log(3, bc->port, " --> EXPORT_PID: pid:%d\n", bc->pid); 03918 snprintf(tmp, sizeof(tmp), "%d", bc->pid); 03919 pbx_builtin_setvar_helper(chan, "_MISDN_PID", tmp); 03920 03921 if (bc->sending_complete) { 03922 snprintf(tmp, sizeof(tmp), "%d", bc->sending_complete); 03923 pbx_builtin_setvar_helper(chan, "MISDN_ADDRESS_COMPLETE", tmp); 03924 } 03925 03926 if (bc->urate) { 03927 snprintf(tmp, sizeof(tmp), "%d", bc->urate); 03928 pbx_builtin_setvar_helper(chan, "MISDN_URATE", tmp); 03929 } 03930 03931 if (bc->uulen && (bc->uulen < sizeof(bc->uu))) { 03932 bc->uu[bc->uulen] = 0; 03933 pbx_builtin_setvar_helper(chan, "MISDN_USERUSER", bc->uu); 03934 } 03935 03936 if (!ast_strlen_zero(bc->keypad)) 03937 pbx_builtin_setvar_helper(chan, "MISDN_KEYPAD", bc->keypad); 03938 }
static struct chan_list * find_chan_by_bc | ( | struct chan_list * | list, | |
struct misdn_bchannel * | bc | |||
) | [static] |
Definition at line 3521 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().
03522 { 03523 struct chan_list *help = list; 03524 for (; help; help = help->next) { 03525 if (help->bc == bc) return help; 03526 } 03527 03528 chan_misdn_log(6, bc->port, "$$$ find_chan: No channel found for oad:%s dad:%s\n", bc->oad, bc->dad); 03529 03530 return NULL; 03531 }
Definition at line 3533 of file chan_misdn.c.
References chan_list::bc, chan_misdn_log(), chan_list::next, and misdn_bchannel::pid.
Referenced by import_ch().
03534 { 03535 struct chan_list *help = list; 03536 for (; help; help = help->next) { 03537 if ( help->bc && (help->bc->pid == pid) ) return help; 03538 } 03539 03540 chan_misdn_log(6, 0, "$$$ find_chan: No channel found for pid:%d\n", pid); 03541 03542 return NULL; 03543 }
static struct chan_list* find_holded | ( | struct chan_list * | list, | |
struct misdn_bchannel * | bc | |||
) | [static] |
Definition at line 3545 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().
03546 { 03547 struct chan_list *help = list; 03548 03549 if (bc->pri) return NULL; 03550 03551 chan_misdn_log(6, bc->port, "$$$ find_holded: channel:%d oad:%s dad:%s\n", bc->channel, bc->oad, bc->dad); 03552 for (;help; help = help->next) { 03553 chan_misdn_log(4, bc->port, "$$$ find_holded: --> holded:%d channel:%d\n", help->state == MISDN_HOLDED, help->hold_info.channel); 03554 if ((help->state == MISDN_HOLDED) && 03555 (help->hold_info.port == bc->port)) 03556 return help; 03557 } 03558 chan_misdn_log(6, bc->port, "$$$ find_chan: No channel found for oad:%s dad:%s\n", bc->oad, bc->dad); 03559 03560 return NULL; 03561 }
static struct chan_list* find_holded_l3 | ( | struct chan_list * | list, | |
unsigned long | l3_id, | |||
int | w | |||
) | [static] |
Definition at line 3564 of file chan_misdn.c.
References chan_list::l3id, MISDN_HOLDED, chan_list::next, and chan_list::state.
Referenced by cb_events().
03565 { 03566 struct chan_list *help = list; 03567 03568 for (; help; help = help->next) { 03569 if ( (help->state == MISDN_HOLDED) && 03570 (help->l3id == l3_id) 03571 ) 03572 return help; 03573 } 03574 03575 return NULL; 03576 }
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 3641 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().
03642 { 03643 int port = ch ? (ch->bc ? ch->bc->port : 0) : 0; 03644 if (!ch) { 03645 cb_log(1, 0, "Cannot hangup chan, no ch\n"); 03646 return; 03647 } 03648 03649 cb_log(5, port, "hangup_chan called\n"); 03650 03651 if (ch->need_hangup) { 03652 cb_log(2, port, " --> hangup\n"); 03653 send_cause2ast(ch->ast, ch->bc, ch); 03654 ch->need_hangup = 0; 03655 ch->need_queue_hangup = 0; 03656 if (ch->ast) 03657 ast_hangup(ch->ast); 03658 return; 03659 } 03660 03661 if (!ch->need_queue_hangup) { 03662 cb_log(2, port, " --> No need to queue hangup\n"); 03663 } 03664 03665 ch->need_queue_hangup = 0; 03666 if (ch->ast) { 03667 send_cause2ast(ch->ast, ch->bc, ch); 03668 03669 if (ch->ast) 03670 ast_queue_hangup(ch->ast); 03671 cb_log(2, port, " --> queue_hangup\n"); 03672 } else { 03673 cb_log(1, port, "Cannot hangup chan, no ast\n"); 03674 } 03675 }
static int hanguptone_indicate | ( | struct chan_list * | cl | ) | [static] |
Definition at line 3113 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().
03114 { 03115 misdn_lib_send_tone(cl->bc, TONE_HANGUP); 03116 return 0; 03117 }
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 3880 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().
03881 { 03882 const char *tmp; 03883 03884 tmp = pbx_builtin_getvar_helper(chan, "MISDN_PID"); 03885 if (tmp) { 03886 ch->other_pid = atoi(tmp); 03887 chan_misdn_log(3, bc->port, " --> IMPORT_PID: importing pid:%s\n", tmp); 03888 if (ch->other_pid > 0) { 03889 ch->other_ch = find_chan_by_pid(cl_te, ch->other_pid); 03890 if (ch->other_ch) 03891 ch->other_ch->other_ch = ch; 03892 } 03893 } 03894 03895 tmp = pbx_builtin_getvar_helper(chan, "MISDN_ADDRESS_COMPLETE"); 03896 if (tmp && (atoi(tmp) == 1)) { 03897 bc->sending_complete = 1; 03898 } 03899 03900 tmp = pbx_builtin_getvar_helper(chan, "MISDN_USERUSER"); 03901 if (tmp) { 03902 ast_log(LOG_NOTICE, "MISDN_USERUSER: %s\n", tmp); 03903 ast_copy_string(bc->uu, tmp, sizeof(bc->uu)); 03904 bc->uulen = strlen(bc->uu); 03905 } 03906 03907 tmp = pbx_builtin_getvar_helper(chan, "MISDN_KEYPAD"); 03908 if (tmp) { 03909 ast_copy_string(bc->keypad, tmp, sizeof(bc->keypad)); 03910 } 03911 }
static struct chan_list* init_chan_list | ( | int | orig | ) | [static] |
Definition at line 3158 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().
03159 { 03160 struct chan_list *cl; 03161 03162 cl = calloc(1, sizeof(struct chan_list)); 03163 if (!cl) { 03164 chan_misdn_log(-1, 0, "misdn_request: malloc failed!"); 03165 return NULL; 03166 } 03167 03168 cl->originator = orig; 03169 cl->need_queue_hangup = 1; 03170 cl->need_hangup = 1; 03171 cl->need_busy = 1; 03172 cl->overlap_dial_task = -1; 03173 03174 return cl; 03175 }
static int load_module | ( | void | ) | [static] |
Definition at line 5039 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, tracing, and unload_module().
05040 { 05041 int i, port; 05042 int ntflags = 0, ntkc = 0; 05043 char ports[256] = ""; 05044 char tempbuf[BUFFERSIZE + 1]; 05045 char ntfile[BUFFERSIZE + 1]; 05046 struct misdn_lib_iface iface = { 05047 .cb_event = cb_events, 05048 .cb_log = chan_misdn_log, 05049 .cb_jb_empty = chan_misdn_jb_empty, 05050 }; 05051 05052 max_ports = misdn_lib_maxports_get(); 05053 05054 if (max_ports <= 0) { 05055 ast_log(LOG_ERROR, "Unable to initialize mISDN\n"); 05056 return AST_MODULE_LOAD_DECLINE; 05057 } 05058 05059 if (misdn_cfg_init(max_ports)) { 05060 ast_log(LOG_ERROR, "Unable to initialize misdn_config.\n"); 05061 return AST_MODULE_LOAD_DECLINE; 05062 } 05063 g_config_initialized = 1; 05064 05065 misdn_debug = (int *) malloc(sizeof(int) * (max_ports + 1)); 05066 if (!misdn_debug) { 05067 ast_log(LOG_ERROR, "Out of memory for misdn_debug\n"); 05068 return AST_MODULE_LOAD_DECLINE; 05069 } 05070 misdn_ports = (int *) malloc(sizeof(int) * (max_ports + 1)); 05071 if (!misdn_ports) { 05072 ast_log(LOG_ERROR, "Out of memory for misdn_ports\n"); 05073 return AST_MODULE_LOAD_DECLINE; 05074 } 05075 misdn_cfg_get(0, MISDN_GEN_DEBUG, &misdn_debug[0], sizeof(int)); 05076 for (i = 1; i <= max_ports; i++) { 05077 misdn_debug[i] = misdn_debug[0]; 05078 misdn_ports[i] = i; 05079 } 05080 *misdn_ports = 0; 05081 misdn_debug_only = (int *) calloc(max_ports + 1, sizeof(int)); 05082 05083 misdn_cfg_get(0, MISDN_GEN_TRACEFILE, tempbuf, BUFFERSIZE); 05084 if (!ast_strlen_zero(tempbuf)) 05085 tracing = 1; 05086 05087 misdn_in_calls = (int *) malloc(sizeof(int) * (max_ports + 1)); 05088 misdn_out_calls = (int *) malloc(sizeof(int) * (max_ports + 1)); 05089 05090 for (i = 1; i <= max_ports; i++) { 05091 misdn_in_calls[i] = 0; 05092 misdn_out_calls[i] = 0; 05093 } 05094 05095 ast_mutex_init(&cl_te_lock); 05096 ast_mutex_init(&release_lock); 05097 05098 misdn_cfg_update_ptp(); 05099 misdn_cfg_get_ports_string(ports); 05100 05101 if (!ast_strlen_zero(ports)) 05102 chan_misdn_log(0, 0, "Got: %s from get_ports\n", ports); 05103 if (misdn_lib_init(ports, &iface, NULL)) 05104 chan_misdn_log(0, 0, "No te ports initialized\n"); 05105 05106 misdn_cfg_get(0, MISDN_GEN_NTDEBUGFLAGS, &ntflags, sizeof(int)); 05107 misdn_cfg_get(0, MISDN_GEN_NTDEBUGFILE, &ntfile, BUFFERSIZE); 05108 misdn_lib_nt_debug_init(ntflags, ntfile); 05109 05110 misdn_cfg_get( 0, MISDN_GEN_NTKEEPCALLS, &ntkc, sizeof(int)); 05111 misdn_lib_nt_keepcalls(ntkc); 05112 05113 if (ast_channel_register(&misdn_tech)) { 05114 ast_log(LOG_ERROR, "Unable to register channel class %s\n", misdn_type); 05115 unload_module(); 05116 return -1; 05117 } 05118 05119 ast_cli_register_multiple(chan_misdn_clis, sizeof(chan_misdn_clis) / sizeof(struct ast_cli_entry)); 05120 05121 ast_register_application("misdn_set_opt", misdn_set_opt_exec, "misdn_set_opt", 05122 "misdn_set_opt(:<opt><optarg>:<opt><optarg>...):\n" 05123 "Sets mISDN opts. and optargs\n" 05124 "\n" 05125 "The available options are:\n" 05126 " a - Have Asterisk detect DTMF tones on called channel\n" 05127 " c - Make crypted outgoing call, optarg is keyindex\n" 05128 " d - Send display text to called phone, text is the optarg\n" 05129 " e - Perform echo cancelation on this channel,\n" 05130 " takes taps as optarg (32,64,128,256)\n" 05131 " e! - Disable echo cancelation on this channel\n" 05132 " f - Enable fax detection\n" 05133 " h - Make digital outgoing call\n" 05134 " h1 - Make HDLC mode digital outgoing call\n" 05135 " i - Ignore detected DTMF tones, don't signal them to Asterisk,\n" 05136 " they will be transported inband.\n" 05137 " jb - Set jitter buffer length, optarg is length\n" 05138 " jt - Set jitter buffer upper threshold, optarg is threshold\n" 05139 " jn - Disable jitter buffer\n" 05140 " n - Disable mISDN DSP on channel.\n" 05141 " Disables: echo cancel, DTMF detection, and volume control.\n" 05142 " p - Caller ID presentation,\n" 05143 " optarg is either 'allowed' or 'restricted'\n" 05144 " s - Send Non-inband DTMF as inband\n" 05145 " vr - Rx gain control, optarg is gain\n" 05146 " vt - Tx gain control, optarg is gain\n" 05147 ); 05148 05149 05150 ast_register_application("misdn_facility", misdn_facility_exec, "misdn_facility", 05151 "misdn_facility(<FACILITY_TYPE>|<ARG1>|..)\n" 05152 "Sends the Facility Message FACILITY_TYPE with \n" 05153 "the given Arguments to the current ISDN Channel\n" 05154 "Supported Facilities are:\n" 05155 "\n" 05156 "type=calldeflect args=Nr where to deflect\n" 05157 ); 05158 05159 05160 ast_register_application("misdn_check_l2l1", misdn_check_l2l1, "misdn_check_l2l1", 05161 "misdn_check_l2l1(<port>||g:<groupname>,timeout)" 05162 "Checks if the L2 and L1 are up on either the given <port> or\n" 05163 "on the ports in the group with <groupname>\n" 05164 "If the L1/L2 are down, check_l2l1 gets up the L1/L2 and waits\n" 05165 "for <timeout> seconds that this happens. Otherwise, nothing happens\n" 05166 "\n" 05167 "This application, ensures the L1/L2 state of the Ports in a group\n" 05168 "it is intended to make the pmp_l1_check option redundant and to\n" 05169 "fix a buggy switch config from your provider\n" 05170 "\n" 05171 "a sample dialplan would look like:\n\n" 05172 "exten => _X.,1,misdn_check_l2l1(g:out|2)\n" 05173 "exten => _X.,n,dial(mISDN/g:out/${EXTEN})\n" 05174 "\n" 05175 ); 05176 05177 05178 misdn_cfg_get(0, MISDN_GEN_TRACEFILE, global_tracefile, BUFFERSIZE); 05179 05180 /* start the l1 watchers */ 05181 05182 for (port = misdn_cfg_get_next_port(0); port >= 0; port = misdn_cfg_get_next_port(port)) { 05183 int l1timeout; 05184 misdn_cfg_get(port, MISDN_CFG_L1_TIMEOUT, &l1timeout, sizeof(l1timeout)); 05185 if (l1timeout) { 05186 chan_misdn_log(4, 0, "Adding L1watcher task: port:%d timeout:%ds\n", port, l1timeout); 05187 misdn_tasks_add(l1timeout * 1000, misdn_l1_task, &misdn_ports[port]); 05188 } 05189 } 05190 05191 chan_misdn_log(0, 0, "-- mISDN Channel Driver Registered --\n"); 05192 05193 return 0; 05194 }
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 2976 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.
02982 { 02983 struct chan_list *ch1, *ch2; 02984 struct ast_channel *carr[2], *who; 02985 int to = -1; 02986 struct ast_frame *f; 02987 int p1_b, p2_b; 02988 int bridging; 02989 02990 ch1 = get_chan_by_ast(c0); 02991 ch2 = get_chan_by_ast(c1); 02992 02993 carr[0] = c0; 02994 carr[1] = c1; 02995 02996 if (!(ch1 && ch2)) 02997 return -1; 02998 02999 misdn_cfg_get(ch1->bc->port, MISDN_CFG_BRIDGING, &p1_b, sizeof(int)); 03000 misdn_cfg_get(ch2->bc->port, MISDN_CFG_BRIDGING, &p2_b, sizeof(int)); 03001 03002 if (! p1_b || ! p2_b) { 03003 ast_log(LOG_NOTICE, "Falling back to Asterisk bridging\n"); 03004 return AST_BRIDGE_FAILED; 03005 } 03006 03007 misdn_cfg_get(0, MISDN_GEN_BRIDGING, &bridging, sizeof(int)); 03008 if (bridging) { 03009 /* trying to make a mISDN_dsp conference */ 03010 chan_misdn_log(1, ch1->bc->port, "I SEND: Making conference with Number:%d\n", ch1->bc->pid + 1); 03011 misdn_lib_bridge(ch1->bc, ch2->bc); 03012 } 03013 03014 if (option_verbose > 2) 03015 ast_verbose(VERBOSE_PREFIX_3 "Native bridging %s and %s\n", c0->name, c1->name); 03016 03017 chan_misdn_log(1, ch1->bc->port, "* Making Native Bridge between %s and %s\n", ch1->bc->oad, ch2->bc->oad); 03018 03019 if (! (flags & AST_BRIDGE_DTMF_CHANNEL_0) ) 03020 ch1->ignore_dtmf = 1; 03021 03022 if (! (flags & AST_BRIDGE_DTMF_CHANNEL_1) ) 03023 ch2->ignore_dtmf = 1; 03024 03025 for (;/*ever*/;) { 03026 to = -1; 03027 who = ast_waitfor_n(carr, 2, &to); 03028 03029 if (!who) { 03030 ast_log(LOG_NOTICE, "misdn_bridge: empty read, breaking out\n"); 03031 break; 03032 } 03033 f = ast_read(who); 03034 03035 if (!f || f->frametype == AST_FRAME_CONTROL) { 03036 /* got hangup .. */ 03037 03038 if (!f) 03039 chan_misdn_log(4, ch1->bc->port, "Read Null Frame\n"); 03040 else 03041 chan_misdn_log(4, ch1->bc->port, "Read Frame Control class:%d\n", f->subclass); 03042 03043 *fo = f; 03044 *rc = who; 03045 break; 03046 } 03047 03048 if ( f->frametype == AST_FRAME_DTMF ) { 03049 chan_misdn_log(1, 0, "Read DTMF %d from %s\n", f->subclass, who->exten); 03050 03051 *fo = f; 03052 *rc = who; 03053 break; 03054 } 03055 03056 #if 0 03057 if (f->frametype == AST_FRAME_VOICE) { 03058 chan_misdn_log(1, ch1->bc->port, "I SEND: Splitting conference with Number:%d\n", ch1->bc->pid +1); 03059 03060 continue; 03061 } 03062 #endif 03063 03064 if (who == c0) { 03065 ast_write(c1, f); 03066 } 03067 else { 03068 ast_write(c0, f); 03069 } 03070 } 03071 03072 chan_misdn_log(1, ch1->bc->port, "I SEND: Splitting conference with Number:%d\n", ch1->bc->pid + 1); 03073 03074 misdn_lib_split_bridge(ch1->bc, ch2->bc); 03075 03076 return AST_BRIDGE_COMPLETE; 03077 }
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 5252 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().
05253 { 05254 char group[BUFFERSIZE + 1]; 05255 char *port_str; 05256 int port = 0; 05257 int timeout; 05258 int dowait = 0; 05259 int port_up; 05260 05261 AST_DECLARE_APP_ARGS(args, 05262 AST_APP_ARG(grouppar); 05263 AST_APP_ARG(timeout); 05264 ); 05265 05266 if (ast_strlen_zero((char *)data)) { 05267 ast_log(LOG_WARNING, "misdn_check_l2l1 Requires arguments\n"); 05268 return -1; 05269 } 05270 05271 AST_STANDARD_APP_ARGS(args, data); 05272 05273 if (args.argc != 2) { 05274 ast_log(LOG_WARNING, "Wrong argument count\n"); 05275 return 0; 05276 } 05277 05278 /*ast_log(LOG_NOTICE, "Arguments: group/port '%s' timeout '%s'\n", args.grouppar, args.timeout);*/ 05279 timeout = atoi(args.timeout); 05280 port_str = args.grouppar; 05281 05282 if (port_str[0] == 'g' && port_str[1] == ':' ) { 05283 /* We make a group call lets checkout which ports are in my group */ 05284 port_str += 2; 05285 ast_copy_string(group, port_str, sizeof(group)); 05286 chan_misdn_log(2, 0, "Checking Ports in group: %s\n", group); 05287 05288 for ( port = misdn_cfg_get_next_port(port); 05289 port > 0; 05290 port = misdn_cfg_get_next_port(port)) { 05291 char cfg_group[BUFFERSIZE + 1]; 05292 05293 chan_misdn_log(2, 0, "trying port %d\n", port); 05294 05295 misdn_cfg_get(port, MISDN_CFG_GROUPNAME, cfg_group, BUFFERSIZE); 05296 05297 if (!strcasecmp(cfg_group, group)) { 05298 port_up = misdn_lib_port_up(port, 1); 05299 05300 if (!port_up) { 05301 chan_misdn_log(2, 0, " --> port '%d'\n", port); 05302 misdn_lib_get_port_up(port); 05303 dowait = 1; 05304 } 05305 } 05306 } 05307 05308 } else { 05309 port = atoi(port_str); 05310 chan_misdn_log(2, 0, "Checking Port: %d\n",port); 05311 port_up = misdn_lib_port_up(port, 1); 05312 if (!port_up) { 05313 misdn_lib_get_port_up(port); 05314 dowait = 1; 05315 } 05316 } 05317 05318 if (dowait) { 05319 chan_misdn_log(2, 0, "Waiting for '%d' seconds\n", timeout); 05320 sleep(timeout); 05321 } 05322 05323 return 0; 05324 }
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 5207 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().
05208 { 05209 struct chan_list *ch = MISDN_ASTERISK_TECH_PVT(chan); 05210 char *tok, *tokb; 05211 05212 chan_misdn_log(0, 0, "TYPE: %s\n", chan->tech->type); 05213 05214 if (strcasecmp(chan->tech->type, "mISDN")) { 05215 ast_log(LOG_WARNING, "misdn_facility makes only sense with chan_misdn channels!\n"); 05216 return -1; 05217 } 05218 05219 if (ast_strlen_zero((char *)data)) { 05220 ast_log(LOG_WARNING, "misdn_facility Requires arguments\n"); 05221 return -1; 05222 } 05223 05224 tok = strtok_r((char*) data, "|", &tokb) ; 05225 05226 if (!tok) { 05227 ast_log(LOG_WARNING, "misdn_facility Requires arguments\n"); 05228 return -1; 05229 } 05230 05231 if (!strcasecmp(tok, "calldeflect")) { 05232 tok = strtok_r(NULL, "|", &tokb) ; 05233 05234 if (!tok) { 05235 ast_log(LOG_WARNING, "Facility: Call Defl Requires arguments\n"); 05236 } 05237 05238 if (strlen(tok) >= sizeof(ch->bc->fac_out.u.CDeflection.DeflectedToNumber)) { 05239 ast_log(LOG_WARNING, "Facility: Number argument too long (up to 15 digits are allowed). Ignoring.\n"); 05240 return 0; 05241 } 05242 ch->bc->fac_out.Function = Fac_CD; 05243 ast_copy_string((char *)ch->bc->fac_out.u.CDeflection.DeflectedToNumber, tok, sizeof(ch->bc->fac_out.u.CDeflection.DeflectedToNumber)); 05244 misdn_lib_send_event(ch->bc, EVENT_FACILITY); 05245 } else { 05246 chan_misdn_log(1, ch->bc->port, "Unknown Facility: %s\n", tok); 05247 } 05248 05249 return 0; 05250 }
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 2532 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(), start_bc_tones(), chan_list::state, stop_bc_tones(), misdn_bchannel::uu, and misdn_bchannel::uulen.
02533 { 02534 struct chan_list *p; 02535 struct misdn_bchannel *bc = NULL; 02536 const char *varcause = NULL; 02537 02538 ast_log(LOG_DEBUG, "misdn_hangup(%s)\n", ast->name); 02539 02540 if (!ast || ! (p=MISDN_ASTERISK_TECH_PVT(ast) ) ) return -1; 02541 02542 if (!p) { 02543 chan_misdn_log(3, 0, "misdn_hangup called, without chan_list obj.\n"); 02544 return 0 ; 02545 } 02546 02547 bc = p->bc; 02548 02549 if (bc) { 02550 const char *tmp=pbx_builtin_getvar_helper(ast,"MISDN_USERUSER"); 02551 if (tmp) { 02552 ast_log(LOG_NOTICE, "MISDN_USERUSER: %s\n", tmp); 02553 strcpy(bc->uu, tmp); 02554 bc->uulen=strlen(bc->uu); 02555 } 02556 } 02557 02558 MISDN_ASTERISK_TECH_PVT(ast) = NULL; 02559 p->ast = NULL; 02560 02561 if (ast->_state == AST_STATE_RESERVED || 02562 p->state == MISDN_NOTHING || 02563 p->state == MISDN_HOLDED || 02564 p->state == MISDN_HOLD_DISCONNECT ) { 02565 02566 CLEAN_CH: 02567 /* between request and call */ 02568 ast_log(LOG_DEBUG, "State Reserved (or nothing) => chanIsAvail\n"); 02569 MISDN_ASTERISK_TECH_PVT(ast) = NULL; 02570 02571 ast_mutex_lock(&release_lock); 02572 cl_dequeue_chan(&cl_te, p); 02573 close(p->pipe[0]); 02574 close(p->pipe[1]); 02575 free(p); 02576 ast_mutex_unlock(&release_lock); 02577 02578 if (bc) 02579 misdn_lib_release(bc); 02580 02581 return 0; 02582 } 02583 02584 if (!bc) { 02585 ast_log(LOG_WARNING, "Hangup with private but no bc ? state:%s l3id:%x\n", misdn_get_ch_state(p), p->l3id); 02586 goto CLEAN_CH; 02587 } 02588 02589 02590 p->need_hangup = 0; 02591 p->need_queue_hangup = 0; 02592 p->need_busy = 0; 02593 02594 02595 if (!p->bc->nt) 02596 stop_bc_tones(p); 02597 02598 bc->out_cause = ast->hangupcause ? ast->hangupcause : AST_CAUSE_NORMAL_CLEARING; 02599 02600 if ((varcause = pbx_builtin_getvar_helper(ast, "HANGUPCAUSE")) || 02601 (varcause = pbx_builtin_getvar_helper(ast, "PRI_CAUSE"))) { 02602 int tmpcause = atoi(varcause); 02603 bc->out_cause = tmpcause ? tmpcause : AST_CAUSE_NORMAL_CLEARING; 02604 } 02605 02606 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)); 02607 chan_misdn_log(3, bc->port, " --> l3id:%x\n", p->l3id); 02608 chan_misdn_log(3, bc->port, " --> cause:%d\n", bc->cause); 02609 chan_misdn_log(2, bc->port, " --> out_cause:%d\n", bc->out_cause); 02610 chan_misdn_log(2, bc->port, " --> state:%s\n", misdn_get_ch_state(p)); 02611 02612 switch (p->state) { 02613 case MISDN_INCOMING_SETUP: 02614 case MISDN_CALLING: 02615 /* This is the only place in misdn_hangup, where we 02616 * can call release_chan, else it might create lot's of trouble 02617 * */ 02618 ast_log(LOG_NOTICE, "release channel, in CALLING/INCOMING_SETUP state.. no other events happened\n"); 02619 release_chan(bc); 02620 02621 p->state = MISDN_CLEANING; 02622 if (bc->need_release_complete) 02623 misdn_lib_send_event( bc, EVENT_RELEASE_COMPLETE); 02624 break; 02625 case MISDN_HOLDED: 02626 case MISDN_DIALING: 02627 start_bc_tones(p); 02628 hanguptone_indicate(p); 02629 02630 if (bc->need_disconnect) 02631 misdn_lib_send_event( bc, EVENT_DISCONNECT); 02632 break; 02633 case MISDN_CALLING_ACKNOWLEDGE: 02634 start_bc_tones(p); 02635 hanguptone_indicate(p); 02636 02637 if (bc->need_disconnect) 02638 misdn_lib_send_event( bc, EVENT_DISCONNECT); 02639 break; 02640 02641 case MISDN_ALERTING: 02642 case MISDN_PROGRESS: 02643 case MISDN_PROCEEDING: 02644 if (p->originator != ORG_AST) 02645 hanguptone_indicate(p); 02646 02647 /*p->state=MISDN_CLEANING;*/ 02648 if (bc->need_disconnect) 02649 misdn_lib_send_event( bc, EVENT_DISCONNECT); 02650 break; 02651 case MISDN_CONNECTED: 02652 case MISDN_PRECONNECTED: 02653 /* Alerting or Disconnect */ 02654 if (p->bc->nt) { 02655 start_bc_tones(p); 02656 hanguptone_indicate(p); 02657 p->bc->progress_indicator = INFO_PI_INBAND_AVAILABLE; 02658 } 02659 if (bc->need_disconnect) 02660 misdn_lib_send_event( bc, EVENT_DISCONNECT); 02661 02662 /*p->state=MISDN_CLEANING;*/ 02663 break; 02664 case MISDN_DISCONNECTED: 02665 if (bc->need_release) 02666 misdn_lib_send_event( bc, EVENT_RELEASE); 02667 p->state = MISDN_CLEANING; /* MISDN_HUNGUP_FROM_AST; */ 02668 break; 02669 02670 case MISDN_RELEASED: 02671 case MISDN_CLEANING: 02672 p->state = MISDN_CLEANING; 02673 break; 02674 02675 case MISDN_BUSY: 02676 break; 02677 02678 case MISDN_HOLD_DISCONNECT: 02679 /* need to send release here */ 02680 chan_misdn_log(1, bc->port, " --> cause %d\n", bc->cause); 02681 chan_misdn_log(1, bc->port, " --> out_cause %d\n", bc->out_cause); 02682 02683 bc->out_cause = -1; 02684 if (bc->need_release) 02685 misdn_lib_send_event(bc, EVENT_RELEASE); 02686 p->state = MISDN_CLEANING; 02687 break; 02688 default: 02689 if (bc->nt) { 02690 bc->out_cause = -1; 02691 if (bc->need_release) 02692 misdn_lib_send_event(bc, EVENT_RELEASE); 02693 p->state = MISDN_CLEANING; 02694 } else { 02695 if (bc->need_disconnect) 02696 misdn_lib_send_event(bc, EVENT_DISCONNECT); 02697 } 02698 } 02699 02700 p->state = MISDN_CLEANING; 02701 02702 chan_misdn_log(3, bc->port, " --> Channel: %s hanguped new state:%s\n", ast->name, misdn_get_ch_state(p)); 02703 02704 return 0; 02705 }
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(), ast_channel::name, 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 } else { 02436 chan_misdn_log(-1, p->bc->port, " --> !! Got Busy in Connected State !?! ast:%s\n", ast->name); 02437 } 02438 return -1; 02439 case AST_CONTROL_RING: 02440 chan_misdn_log(1, p->bc->port, "* IND :\tring pid:%d\n", p->bc ? p->bc->pid : -1); 02441 return -1; 02442 case AST_CONTROL_RINGING: 02443 chan_misdn_log(1, p->bc->port, "* IND :\tringing pid:%d\n", p->bc ? p->bc->pid : -1); 02444 switch (p->state) { 02445 case MISDN_ALERTING: 02446 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); 02447 break; 02448 case MISDN_CONNECTED: 02449 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); 02450 return -1; 02451 default: 02452 p->state = MISDN_ALERTING; 02453 chan_misdn_log(2, p->bc->port, " --> * IND :\tringing pid:%d\n", p->bc ? p->bc->pid : -1); 02454 misdn_lib_send_event( p->bc, EVENT_ALERTING); 02455 02456 if (p->other_ch && p->other_ch->bc) { 02457 if (misdn_inband_avail(p->other_ch->bc)) { 02458 chan_misdn_log(2, p->bc->port, " --> other End is mISDN and has inband info available\n"); 02459 break; 02460 } 02461 02462 if (!p->other_ch->bc->nt) { 02463 chan_misdn_log(2, p->bc->port, " --> other End is mISDN TE so it has inband info for sure (?)\n"); 02464 break; 02465 } 02466 } 02467 02468 chan_misdn_log(3, p->bc->port, " --> * SEND: State Ring pid:%d\n", p->bc ? p->bc->pid : -1); 02469 ast_setstate(ast, AST_STATE_RING); 02470 02471 if (!p->bc->nt && (p->originator == ORG_MISDN) && !p->incoming_early_audio) 02472 chan_misdn_log(2, p->bc->port, " --> incoming_early_audio off\n"); 02473 else 02474 return -1; 02475 } 02476 break; 02477 case AST_CONTROL_ANSWER: 02478 chan_misdn_log(1, p->bc->port, " --> * IND :\tanswer pid:%d\n", p->bc ? p->bc->pid : -1); 02479 start_bc_tones(p); 02480 break; 02481 case AST_CONTROL_TAKEOFFHOOK: 02482 chan_misdn_log(1, p->bc->port, " --> *\ttakeoffhook pid:%d\n", p->bc ? p->bc->pid : -1); 02483 return -1; 02484 case AST_CONTROL_OFFHOOK: 02485 chan_misdn_log(1, p->bc->port, " --> *\toffhook pid:%d\n", p->bc ? p->bc->pid : -1); 02486 return -1; 02487 case AST_CONTROL_FLASH: 02488 chan_misdn_log(1, p->bc->port, " --> *\tflash pid:%d\n", p->bc ? p->bc->pid : -1); 02489 break; 02490 case AST_CONTROL_PROGRESS: 02491 chan_misdn_log(1, p->bc->port, " --> * IND :\tprogress pid:%d\n", p->bc ? p->bc->pid : -1); 02492 misdn_lib_send_event( p->bc, EVENT_PROGRESS); 02493 break; 02494 case AST_CONTROL_PROCEEDING: 02495 chan_misdn_log(1, p->bc->port, " --> * IND :\tproceeding pid:%d\n", p->bc ? p->bc->pid : -1); 02496 misdn_lib_send_event( p->bc, EVENT_PROCEEDING); 02497 break; 02498 case AST_CONTROL_CONGESTION: 02499 chan_misdn_log(1, p->bc->port, " --> * IND :\tcongestion pid:%d\n", p->bc ? p->bc->pid : -1); 02500 02501 p->bc->out_cause = AST_CAUSE_SWITCH_CONGESTION; 02502 start_bc_tones(p); 02503 misdn_lib_send_event( p->bc, EVENT_DISCONNECT); 02504 02505 if (p->bc->nt) { 02506 hanguptone_indicate(p); 02507 } 02508 break; 02509 case -1 : 02510 chan_misdn_log(1, p->bc->port, " --> * IND :\t-1! (stop indication) pid:%d\n", p->bc ? p->bc->pid : -1); 02511 02512 stop_indicate(p); 02513 02514 if (p->state == MISDN_CONNECTED) 02515 start_bc_tones(p); 02516 break; 02517 case AST_CONTROL_HOLD: 02518 ast_moh_start(ast, data, p->mohinterpret); 02519 chan_misdn_log(1, p->bc->port, " --> *\tHOLD pid:%d\n", p->bc ? p->bc->pid : -1); 02520 break; 02521 case AST_CONTROL_UNHOLD: 02522 ast_moh_stop(ast); 02523 chan_misdn_log(1, p->bc->port, " --> *\tUNHOLD pid:%d\n", p->bc ? p->bc->pid : -1); 02524 break; 02525 default: 02526 chan_misdn_log(1, p->bc->port, " --> * Unknown Indication:%d pid:%d\n", cond, p->bc ? p->bc->pid : -1); 02527 } 02528 02529 return 0; 02530 }
void misdn_jb_destroy | ( | struct misdn_jb * | jb | ) |
frees the data and destroys the given jitterbuffer struct
Definition at line 5591 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().
05592 { 05593 ast_mutex_destroy(&jb->mutexjb); 05594 05595 free(jb->ok); 05596 free(jb->samples); 05597 free(jb); 05598 }
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 5661 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().
05662 { 05663 int i, wp, rp, read = 0; 05664 05665 ast_mutex_lock(&jb->mutexjb); 05666 05667 rp = jb->rp; 05668 wp = jb->wp; 05669 05670 if (jb->state_empty) { 05671 for (i = 0; i < len; i++) { 05672 if (wp == rp) { 05673 jb->rp = rp; 05674 jb->state_empty = 0; 05675 05676 ast_mutex_unlock(&jb->mutexjb); 05677 05678 return read; 05679 } else { 05680 if (jb->ok[rp] == 1) { 05681 data[i] = jb->samples[rp]; 05682 jb->ok[rp] = 0; 05683 rp = (rp != jb->size - 1) ? rp + 1 : 0; 05684 read += 1; 05685 } 05686 } 05687 } 05688 05689 if (wp >= rp) 05690 jb->state_buffer = wp - rp; 05691 else 05692 jb->state_buffer = jb->size - rp + wp; 05693 chan_misdn_log(9, 0, "misdn_jb_empty: read:%d | Buffer status:%d p:%p\n", len, jb->state_buffer, jb); 05694 05695 jb->rp = rp; 05696 } else 05697 chan_misdn_log(9, 0, "misdn_jb_empty: Wait...requested:%d p:%p\n", len, jb); 05698 05699 ast_mutex_unlock(&jb->mutexjb); 05700 05701 return read; 05702 }
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 5602 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.
05603 { 05604 int i, j, rp, wp; 05605 05606 if (!jb || ! data) 05607 return 0; 05608 05609 ast_mutex_lock(&jb->mutexjb); 05610 05611 wp = jb->wp; 05612 rp = jb->rp; 05613 05614 for (i = 0; i < len; i++) { 05615 jb->samples[wp] = data[i]; 05616 jb->ok[wp] = 1; 05617 wp = (wp != jb->size - 1) ? wp + 1 : 0; 05618 05619 if (wp == jb->rp) 05620 jb->state_full = 1; 05621 } 05622 05623 if (wp >= rp) 05624 jb->state_buffer = wp - rp; 05625 else 05626 jb->state_buffer = jb->size - rp + wp; 05627 chan_misdn_log(9, 0, "misdn_jb_fill: written:%d | Buffer status:%d p:%p\n", len, jb->state_buffer, jb); 05628 05629 if (jb->state_full) { 05630 jb->wp = wp; 05631 05632 rp = wp; 05633 for (j = 0; j < jb->upper_threshold; j++) 05634 rp = (rp != 0) ? rp - 1 : jb->size - 1; 05635 jb->rp = rp; 05636 jb->state_full = 0; 05637 jb->state_empty = 1; 05638 05639 ast_mutex_unlock(&jb->mutexjb); 05640 05641 return -1; 05642 } 05643 05644 if (!jb->state_empty) { 05645 jb->bytes_wrote += len; 05646 if (jb->bytes_wrote >= jb->upper_threshold) { 05647 jb->state_empty = 1; 05648 jb->bytes_wrote = 0; 05649 } 05650 } 05651 jb->wp = wp; 05652 05653 ast_mutex_unlock(&jb->mutexjb); 05654 05655 return 0; 05656 }
struct misdn_jb * misdn_jb_init | ( | int | size, | |
int | upper_threshold | |||
) |
allocates the jb-structure and initialize the elements
Definition at line 5550 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().
05551 { 05552 int i; 05553 struct misdn_jb *jb; 05554 05555 jb = malloc(sizeof(struct misdn_jb)); 05556 if (!jb) { 05557 chan_misdn_log(-1, 0, "No free Mem for jb\n"); 05558 return NULL; 05559 } 05560 jb->size = size; 05561 jb->upper_threshold = upper_threshold; 05562 jb->wp = 0; 05563 jb->rp = 0; 05564 jb->state_full = 0; 05565 jb->state_empty = 0; 05566 jb->bytes_wrote = 0; 05567 jb->samples = malloc(size * sizeof(char)); 05568 if (!jb->samples) { 05569 free(jb); 05570 chan_misdn_log(-1, 0, "No free Mem for jb->samples\n"); 05571 return NULL; 05572 } 05573 05574 jb->ok = malloc(size * sizeof(char)); 05575 if (!jb->ok) { 05576 free(jb->samples); 05577 free(jb); 05578 chan_misdn_log(-1, 0, "No free Mem for jb->ok\n"); 05579 return NULL; 05580 } 05581 05582 for (i = 0; i < size; i++) 05583 jb->ok[i] = 0; 05584 05585 ast_mutex_init(&jb->mutexjb); 05586 05587 return jb; 05588 }
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 3450 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().
03451 { 03452 struct ast_channel *tmp; 03453 char *cid_name = 0, *cid_num = 0; 03454 int chan_offset = 0; 03455 int tmp_port = misdn_cfg_get_next_port(0); 03456 int bridging; 03457 03458 for (; tmp_port > 0; tmp_port = misdn_cfg_get_next_port(tmp_port)) { 03459 if (tmp_port == port) 03460 break; 03461 chan_offset += misdn_lib_port_is_pri(tmp_port) ? 30 : 2; 03462 } 03463 if (c < 0) 03464 c = 0; 03465 03466 if (callerid) { 03467 ast_callerid_parse(callerid, &cid_name, &cid_num); 03468 } 03469 03470 tmp = ast_channel_alloc(1, state, cid_num, cid_name, "", exten, "", 0, "%s/%d-u%d", misdn_type, chan_offset + c, glob_channel++); 03471 if (tmp) { 03472 chan_misdn_log(2, 0, " --> * NEW CHANNEL dad:%s oad:%s\n", exten, callerid); 03473 03474 tmp->nativeformats = prefformat; 03475 03476 tmp->readformat = format; 03477 tmp->rawreadformat = format; 03478 tmp->writeformat = format; 03479 tmp->rawwriteformat = format; 03480 03481 tmp->tech_pvt = chlist; 03482 03483 misdn_cfg_get(0, MISDN_GEN_BRIDGING, &bridging, sizeof(int)); 03484 03485 if (bridging) 03486 tmp->tech = &misdn_tech; 03487 else 03488 tmp->tech = &misdn_tech_wo_bridge; 03489 03490 tmp->writeformat = format; 03491 tmp->readformat = format; 03492 tmp->priority=1; 03493 03494 if (exten) 03495 ast_copy_string(tmp->exten, exten, sizeof(tmp->exten)); 03496 else 03497 chan_misdn_log(1, 0, "misdn_new: no exten given.\n"); 03498 03499 if (callerid) 03500 /* Don't use ast_set_callerid() here because it will 03501 * generate a needless NewCallerID event */ 03502 tmp->cid.cid_ani = ast_strdup(cid_num); 03503 03504 if (pipe(chlist->pipe) < 0) 03505 perror("Pipe failed\n"); 03506 tmp->fds[0] = chlist->pipe[0]; 03507 03508 if (state == AST_STATE_RING) 03509 tmp->rings = 1; 03510 else 03511 tmp->rings = 0; 03512 03513 ast_jb_configure(tmp, misdn_get_global_jbconf()); 03514 } else { 03515 chan_misdn_log(-1, 0, "Unable to allocate channel structure\n"); 03516 } 03517 03518 return tmp; 03519 }
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 2779 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.
02780 { 02781 struct chan_list *tmp; 02782 fd_set rrfs; 02783 struct timeval tv; 02784 int len, t; 02785 02786 if (!ast) { 02787 chan_misdn_log(1, 0, "misdn_read called without ast\n"); 02788 return NULL; 02789 } 02790 if (!(tmp = MISDN_ASTERISK_TECH_PVT(ast))) { 02791 chan_misdn_log(1, 0, "misdn_read called without ast->pvt\n"); 02792 return NULL; 02793 } 02794 02795 if (!tmp->bc && !(tmp->state == MISDN_HOLDED)) { 02796 chan_misdn_log(1, 0, "misdn_read called without bc\n"); 02797 return NULL; 02798 } 02799 02800 tv.tv_sec=0; 02801 tv.tv_usec=20000; 02802 02803 FD_ZERO(&rrfs); 02804 FD_SET(tmp->pipe[0],&rrfs); 02805 02806 t=select(FD_SETSIZE,&rrfs,NULL, NULL,&tv); 02807 02808 if (!t) { 02809 chan_misdn_log(3, tmp->bc->port, "read Select Timed out\n"); 02810 len=160; 02811 } 02812 02813 if (t<0) { 02814 chan_misdn_log(-1, tmp->bc->port, "Select Error (err=%s)\n",strerror(errno)); 02815 return NULL; 02816 } 02817 02818 if (FD_ISSET(tmp->pipe[0],&rrfs)) { 02819 len=read(tmp->pipe[0],tmp->ast_rd_buf,sizeof(tmp->ast_rd_buf)); 02820 02821 if (len<=0) { 02822 /* we hangup here, since our pipe is closed */ 02823 chan_misdn_log(2,tmp->bc->port,"misdn_read: Pipe closed, hanging up\n"); 02824 return NULL; 02825 } 02826 02827 } else { 02828 return NULL; 02829 } 02830 02831 tmp->frame.frametype = AST_FRAME_VOICE; 02832 tmp->frame.subclass = AST_FORMAT_ALAW; 02833 tmp->frame.datalen = len; 02834 tmp->frame.samples = len; 02835 tmp->frame.mallocd = 0; 02836 tmp->frame.offset = 0; 02837 tmp->frame.delivery = ast_tv(0,0); 02838 tmp->frame.src = NULL; 02839 tmp->frame.data = tmp->ast_rd_buf; 02840 02841 if (tmp->faxdetect && !tmp->faxhandled) { 02842 if (tmp->faxdetect_timeout) { 02843 if (ast_tvzero(tmp->faxdetect_tv)) { 02844 tmp->faxdetect_tv = ast_tvnow(); 02845 chan_misdn_log(2, tmp->bc->port, "faxdetect: starting detection with timeout: %ds ...\n", tmp->faxdetect_timeout); 02846 return process_ast_dsp(tmp, &tmp->frame); 02847 } else { 02848 struct timeval tv_now = ast_tvnow(); 02849 int diff = ast_tvdiff_ms(tv_now, tmp->faxdetect_tv); 02850 if (diff <= (tmp->faxdetect_timeout * 1000)) { 02851 chan_misdn_log(5, tmp->bc->port, "faxdetect: detecting ...\n"); 02852 return process_ast_dsp(tmp, &tmp->frame); 02853 } else { 02854 chan_misdn_log(2, tmp->bc->port, "faxdetect: stopping detection (time ran out) ...\n"); 02855 tmp->faxdetect = 0; 02856 return &tmp->frame; 02857 } 02858 } 02859 } else { 02860 chan_misdn_log(5, tmp->bc->port, "faxdetect: detecting ... (no timeout)\n"); 02861 return process_ast_dsp(tmp, &tmp->frame); 02862 } 02863 } else { 02864 if (tmp->ast_dsp) 02865 return process_ast_dsp(tmp, &tmp->frame); 02866 else 02867 return &tmp->frame; 02868 } 02869 }
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 3177 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().
03178 { 03179 struct ast_channel *tmp = NULL; 03180 char group[BUFFERSIZE + 1] = ""; 03181 char dial_str[128]; 03182 char *buf2 = ast_strdupa(data); 03183 char *ext; 03184 char *port_str; 03185 char *p = NULL; 03186 int channel = 0; 03187 int port = 0; 03188 struct misdn_bchannel *newbc = NULL; 03189 int dec = 0; 03190 03191 struct chan_list *cl = init_chan_list(ORG_AST); 03192 03193 snprintf(dial_str, sizeof(dial_str), "%s/%s", misdn_type, (char *) data); 03194 03195 /* 03196 * data is ---v 03197 * Dial(mISDN/g:group_name[/extension[/options]]) 03198 * Dial(mISDN/port[:preselected_channel][/extension[/options]]) 03199 * 03200 * The dial extension could be empty if you are using MISDN_KEYPAD 03201 * to control ISDN provider features. 03202 */ 03203 port_str = strsep(&buf2, "/"); 03204 if (!ast_strlen_zero(port_str)) { 03205 if (port_str[0] == 'g' && port_str[1] == ':' ) { 03206 /* We make a group call lets checkout which ports are in my group */ 03207 port_str += 2; 03208 ast_copy_string(group, port_str, sizeof(group)); 03209 chan_misdn_log(2, 0, " --> Group Call group: %s\n", group); 03210 } else if ((p = strchr(port_str, ':'))) { 03211 /* we have a preselected channel */ 03212 *p = 0; 03213 channel = atoi(++p); 03214 port = atoi(port_str); 03215 chan_misdn_log(2, port, " --> Call on preselected Channel (%d).\n", channel); 03216 } else { 03217 port = atoi(port_str); 03218 } 03219 } else { 03220 ast_log(LOG_WARNING, " --> ! IND : Dial(%s) WITHOUT Port or Group, check extensions.conf\n", dial_str); 03221 return NULL; 03222 } 03223 03224 ext = strsep(&buf2, "/"); 03225 if (!ext) { 03226 ext = ""; 03227 } 03228 03229 if (misdn_cfg_is_group_method(group, METHOD_STANDARD_DEC)) { 03230 chan_misdn_log(4, port, " --> STARTING STANDARD DEC...\n"); 03231 dec = 1; 03232 } 03233 03234 if (!ast_strlen_zero(group)) { 03235 char cfg_group[BUFFERSIZE + 1]; 03236 struct robin_list *rr = NULL; 03237 03238 /* Group dial */ 03239 03240 if (misdn_cfg_is_group_method(group, METHOD_ROUND_ROBIN)) { 03241 chan_misdn_log(4, port, " --> STARTING ROUND ROBIN...\n"); 03242 rr = get_robin_position(group); 03243 } 03244 03245 if (rr) { 03246 int port_start = 0; 03247 int port_bak = rr->port; 03248 int chan_bak = rr->channel; 03249 03250 if (!rr->port) 03251 rr->port = misdn_cfg_get_next_port_spin(rr->port); 03252 03253 for (; rr->port > 0; rr->port = misdn_cfg_get_next_port_spin(rr->port)) { 03254 int port_up; 03255 int check; 03256 int max_chan; 03257 int last_chance = 0; 03258 03259 misdn_cfg_get(rr->port, MISDN_CFG_GROUPNAME, cfg_group, BUFFERSIZE); 03260 if (strcasecmp(cfg_group, group)) 03261 continue; 03262 03263 misdn_cfg_get(rr->port, MISDN_CFG_PMP_L1_CHECK, &check, sizeof(int)); 03264 port_up = misdn_lib_port_up(rr->port, check); 03265 03266 if (check && !port_up) 03267 chan_misdn_log(1, rr->port, "L1 is not Up on this Port\n"); 03268 03269 if (check && port_up < 0) 03270 ast_log(LOG_WARNING,"This port (%d) is blocked\n", rr->port); 03271 03272 if ((port_start == rr->port) && (port_up <= 0)) 03273 break; 03274 03275 if (!port_start) 03276 port_start = rr->port; 03277 03278 if (port_up <= 0) 03279 continue; 03280 03281 max_chan = misdn_lib_get_maxchans(rr->port); 03282 03283 for (++rr->channel; !last_chance && rr->channel <= max_chan; ++rr->channel) { 03284 if (rr->port == port_bak && rr->channel == chan_bak) 03285 last_chance = 1; 03286 03287 chan_misdn_log(1, 0, "trying port:%d channel:%d\n", rr->port, rr->channel); 03288 newbc = misdn_lib_get_free_bc(rr->port, rr->channel, 0, 0); 03289 if (newbc) { 03290 chan_misdn_log(4, rr->port, " Success! Found port:%d channel:%d\n", newbc->port, newbc->channel); 03291 if (port_up) 03292 chan_misdn_log(4, rr->port, "portup:%d\n", port_up); 03293 port = rr->port; 03294 break; 03295 } 03296 } 03297 03298 if (newbc || last_chance) 03299 break; 03300 03301 rr->channel = 0; 03302 } 03303 if (!newbc) { 03304 rr->port = port_bak; 03305 rr->channel = chan_bak; 03306 } 03307 } else { 03308 for (port = misdn_cfg_get_next_port(0); port > 0; 03309 port = misdn_cfg_get_next_port(port)) { 03310 03311 misdn_cfg_get(port, MISDN_CFG_GROUPNAME, cfg_group, BUFFERSIZE); 03312 03313 chan_misdn_log(3, port, "Group [%s] Port [%d]\n", group, port); 03314 if (!strcasecmp(cfg_group, group)) { 03315 int port_up; 03316 int check; 03317 misdn_cfg_get(port, MISDN_CFG_PMP_L1_CHECK, &check, sizeof(int)); 03318 port_up = misdn_lib_port_up(port, check); 03319 03320 chan_misdn_log(4, port, "portup:%d\n", port_up); 03321 03322 if (port_up > 0) { 03323 newbc = misdn_lib_get_free_bc(port, 0, 0, dec); 03324 if (newbc) 03325 break; 03326 } 03327 } 03328 } 03329 } 03330 03331 /* Group dial failed ?*/ 03332 if (!newbc) { 03333 ast_log(LOG_WARNING, 03334 "Could not Dial out on group '%s'.\n" 03335 "\tEither the L2 and L1 on all of these ports where DOWN (see 'show application misdn_check_l2l1')\n" 03336 "\tOr there was no free channel on none of the ports\n\n" 03337 , group); 03338 return NULL; 03339 } 03340 } else { 03341 /* 'Normal' Port dial * Port dial */ 03342 if (channel) 03343 chan_misdn_log(1, port, " --> preselected_channel: %d\n", channel); 03344 newbc = misdn_lib_get_free_bc(port, channel, 0, dec); 03345 03346 if (!newbc) { 03347 ast_log(LOG_WARNING, "Could not create channel on port:%d with extensions:%s\n", port, ext); 03348 return NULL; 03349 } 03350 } 03351 03352 03353 /* create ast_channel and link all the objects together */ 03354 cl->bc = newbc; 03355 03356 tmp = misdn_new(cl, AST_STATE_RESERVED, ext, NULL, format, port, channel); 03357 if (!tmp) { 03358 ast_log(LOG_ERROR,"Could not create Asterisk object\n"); 03359 return NULL; 03360 } 03361 03362 cl->ast=tmp; 03363 03364 /* register chan in local list */ 03365 cl_queue_chan(&cl_te, cl) ; 03366 03367 /* fill in the config into the objects */ 03368 read_config(cl, ORG_AST); 03369 03370 /* important */ 03371 cl->need_hangup = 0; 03372 03373 return tmp; 03374 }
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 3377 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.
03378 { 03379 struct chan_list *tmp = chan->tech_pvt; 03380 03381 if (tmp && tmp->bc) { 03382 ast_copy_string(tmp->bc->display, text, sizeof(tmp->bc->display)); 03383 misdn_lib_send_event(tmp->bc, EVENT_INFORMATION); 03384 } else { 03385 ast_log(LOG_WARNING, "No chan_list but send_text request?\n"); 03386 return -1; 03387 } 03388 03389 return 0; 03390 }
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 5326 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().
05327 { 05328 struct chan_list *ch = MISDN_ASTERISK_TECH_PVT(chan); 05329 char *tok, *tokb; 05330 int keyidx = 0; 05331 int rxgain = 0; 05332 int txgain = 0; 05333 int change_jitter = 0; 05334 05335 if (strcasecmp(chan->tech->type, "mISDN")) { 05336 ast_log(LOG_WARNING, "misdn_set_opt makes only sense with chan_misdn channels!\n"); 05337 return -1; 05338 } 05339 05340 if (ast_strlen_zero((char *)data)) { 05341 ast_log(LOG_WARNING, "misdn_set_opt Requires arguments\n"); 05342 return -1; 05343 } 05344 05345 for (tok = strtok_r((char*) data, ":", &tokb); 05346 tok; 05347 tok = strtok_r(NULL, ":", &tokb) ) { 05348 int neglect = 0; 05349 05350 if (tok[0] == '!' ) { 05351 neglect = 1; 05352 tok++; 05353 } 05354 05355 switch(tok[0]) { 05356 05357 case 'd' : 05358 ast_copy_string(ch->bc->display, ++tok, sizeof(ch->bc->display)); 05359 chan_misdn_log(1, ch->bc->port, "SETOPT: Display:%s\n", ch->bc->display); 05360 break; 05361 05362 case 'n': 05363 chan_misdn_log(1, ch->bc->port, "SETOPT: No DSP\n"); 05364 ch->bc->nodsp = 1; 05365 break; 05366 05367 case 'j': 05368 chan_misdn_log(1, ch->bc->port, "SETOPT: jitter\n"); 05369 tok++; 05370 change_jitter = 1; 05371 05372 switch ( tok[0] ) { 05373 case 'b': 05374 ch->jb_len = atoi(++tok); 05375 chan_misdn_log(1, ch->bc->port, " --> buffer_len:%d\n", ch->jb_len); 05376 break; 05377 case 't' : 05378 ch->jb_upper_threshold = atoi(++tok); 05379 chan_misdn_log(1, ch->bc->port, " --> upper_threshold:%d\n", ch->jb_upper_threshold); 05380 break; 05381 case 'n': 05382 ch->bc->nojitter = 1; 05383 chan_misdn_log(1, ch->bc->port, " --> nojitter\n"); 05384 break; 05385 default: 05386 ch->jb_len = 4000; 05387 ch->jb_upper_threshold = 0; 05388 chan_misdn_log(1, ch->bc->port, " --> buffer_len:%d (default)\n", ch->jb_len); 05389 chan_misdn_log(1, ch->bc->port, " --> upper_threshold:%d (default)\n", ch->jb_upper_threshold); 05390 } 05391 break; 05392 case 'v': 05393 tok++; 05394 05395 switch (tok[0]) { 05396 case 'r' : 05397 rxgain = atoi(++tok); 05398 if (rxgain < -8) 05399 rxgain = -8; 05400 if (rxgain > 8) 05401 rxgain = 8; 05402 ch->bc->rxgain = rxgain; 05403 chan_misdn_log(1, ch->bc->port, "SETOPT: Volume:%d\n", rxgain); 05404 break; 05405 case 't': 05406 txgain = atoi(++tok); 05407 if (txgain < -8) 05408 txgain = -8; 05409 if (txgain > 8) 05410 txgain = 8; 05411 ch->bc->txgain = txgain; 05412 chan_misdn_log(1, ch->bc->port, "SETOPT: Volume:%d\n", txgain); 05413 break; 05414 } 05415 break; 05416 05417 case 'c': 05418 keyidx = atoi(++tok); 05419 { 05420 char keys[4096]; 05421 char *key = NULL, *tmp = keys; 05422 int i; 05423 misdn_cfg_get(0, MISDN_GEN_CRYPT_KEYS, keys, sizeof(keys)); 05424 05425 for (i = 0; i < keyidx; i++) { 05426 key = strsep(&tmp, ","); 05427 } 05428 05429 if (key) { 05430 ast_copy_string(ch->bc->crypt_key, key, sizeof(ch->bc->crypt_key)); 05431 } 05432 05433 chan_misdn_log(0, ch->bc->port, "SETOPT: crypt with key:%s\n", ch->bc->crypt_key); 05434 break; 05435 } 05436 case 'e': 05437 chan_misdn_log(1, ch->bc->port, "SETOPT: EchoCancel\n"); 05438 05439 if (neglect) { 05440 chan_misdn_log(1, ch->bc->port, " --> disabled\n"); 05441 #ifdef MISDN_1_2 05442 *ch->bc->pipeline = 0; 05443 #else 05444 ch->bc->ec_enable = 0; 05445 #endif 05446 } else { 05447 #ifdef MISDN_1_2 05448 update_pipeline_config(ch->bc); 05449 #else 05450 ch->bc->ec_enable = 1; 05451 ch->bc->orig = ch->originator; 05452 tok++; 05453 if (*tok) { 05454 ch->bc->ec_deftaps = atoi(tok); 05455 } 05456 #endif 05457 } 05458 05459 break; 05460 case 'h': 05461 chan_misdn_log(1, ch->bc->port, "SETOPT: Digital\n"); 05462 05463 if (strlen(tok) > 1 && tok[1] == '1') { 05464 chan_misdn_log(1, ch->bc->port, "SETOPT: HDLC \n"); 05465 if (!ch->bc->hdlc) { 05466 ch->bc->hdlc = 1; 05467 } 05468 } 05469 ch->bc->capability = INFO_CAPABILITY_DIGITAL_UNRESTRICTED; 05470 break; 05471 05472 case 's': 05473 chan_misdn_log(1, ch->bc->port, "SETOPT: Send DTMF\n"); 05474 ch->bc->send_dtmf = 1; 05475 break; 05476 05477 case 'f': 05478 chan_misdn_log(1, ch->bc->port, "SETOPT: Faxdetect\n"); 05479 ch->faxdetect = 1; 05480 misdn_cfg_get(ch->bc->port, MISDN_CFG_FAXDETECT_TIMEOUT, &ch->faxdetect_timeout, sizeof(ch->faxdetect_timeout)); 05481 break; 05482 05483 case 'a': 05484 chan_misdn_log(1, ch->bc->port, "SETOPT: AST_DSP (for DTMF)\n"); 05485 ch->ast_dsp = 1; 05486 break; 05487 05488 case 'p': 05489 chan_misdn_log(1, ch->bc->port, "SETOPT: callerpres: %s\n", &tok[1]); 05490 /* CRICH: callingpres!!! */ 05491 if (strstr(tok,"allowed")) { 05492 ch->bc->pres = 0; 05493 } else if (strstr(tok, "restricted")) { 05494 ch->bc->pres = 1; 05495 } else if (strstr(tok, "not_screened")) { 05496 chan_misdn_log(0, ch->bc->port, "SETOPT: callerpres: not_screened is deprecated\n"); 05497 ch->bc->pres = 1; 05498 } 05499 break; 05500 case 'i' : 05501 chan_misdn_log(1, ch->bc->port, "Ignoring dtmf tones, just use them inband\n"); 05502 ch->ignore_dtmf=1; 05503 break; 05504 default: 05505 break; 05506 } 05507 } 05508 05509 if (change_jitter) 05510 config_jitterbuffer(ch); 05511 05512 if (ch->faxdetect || ch->ast_dsp) { 05513 if (!ch->dsp) 05514 ch->dsp = ast_dsp_new(); 05515 if (ch->dsp) 05516 ast_dsp_set_features(ch->dsp, DSP_FEATURE_DTMF_DETECT| DSP_FEATURE_FAX_DETECT); 05517 if (!ch->trans) 05518 ch->trans = ast_translator_build_path(AST_FORMAT_SLINEAR, AST_FORMAT_ALAW); 05519 } 05520 05521 if (ch->ast_dsp) { 05522 chan_misdn_log(1, ch->bc->port, "SETOPT: with AST_DSP we deactivate mISDN_dsp\n"); 05523 ch->bc->nodsp = 1; 05524 ch->bc->nojitter = 1; 05525 } 05526 05527 return 0; 05528 }
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], "%d", &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, poll(), 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 3746 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().
03747 { 03748 chan_misdn_log(4, 0, "TRANSFERRING %s to %s\n", holded_chan->ast->name, tmp_ch->ast->name); 03749 03750 tmp_ch->state = MISDN_HOLD_DISCONNECT; 03751 03752 ast_moh_stop(ast_bridged_channel(holded_chan->ast)); 03753 03754 holded_chan->state=MISDN_CONNECTED; 03755 /* misdn_lib_transfer(holded_chan->bc); */ 03756 ast_channel_masquerade(holded_chan->ast, ast_bridged_channel(tmp_ch->ast)); 03757 }
static int misdn_write | ( | struct ast_channel * | ast, | |
struct ast_frame * | frame | |||
) | [static] |
Definition at line 2872 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.
02873 { 02874 struct chan_list *ch; 02875 int i = 0; 02876 02877 if (!ast || ! (ch = MISDN_ASTERISK_TECH_PVT(ast)) ) return -1; 02878 02879 if (ch->state == MISDN_HOLDED) { 02880 chan_misdn_log(7, 0, "misdn_write: Returning because holded\n"); 02881 return 0; 02882 } 02883 02884 if (!ch->bc ) { 02885 ast_log(LOG_WARNING, "private but no bc\n"); 02886 return -1; 02887 } 02888 02889 if (ch->notxtone) { 02890 chan_misdn_log(7, ch->bc->port, "misdn_write: Returning because notxtone\n"); 02891 return 0; 02892 } 02893 02894 02895 if (!frame->subclass) { 02896 chan_misdn_log(4, ch->bc->port, "misdn_write: * prods us\n"); 02897 return 0; 02898 } 02899 02900 if (!(frame->subclass & prefformat)) { 02901 02902 chan_misdn_log(-1, ch->bc->port, "Got Unsupported Frame with Format:%d\n", frame->subclass); 02903 return 0; 02904 } 02905 02906 02907 if (!frame->samples ) { 02908 chan_misdn_log(4, ch->bc->port, "misdn_write: zero write\n"); 02909 02910 if (!strcmp(frame->src,"ast_prod")) { 02911 chan_misdn_log(1, ch->bc->port, "misdn_write: state (%s) prodded.\n", misdn_get_ch_state(ch)); 02912 02913 if (ch->ts) { 02914 chan_misdn_log(4, ch->bc->port, "Starting Playtones\n"); 02915 misdn_lib_tone_generator_start(ch->bc); 02916 } 02917 return 0; 02918 } 02919 02920 return -1; 02921 } 02922 02923 if ( ! ch->bc->addr ) { 02924 chan_misdn_log(8, ch->bc->port, "misdn_write: no addr for bc dropping:%d\n", frame->samples); 02925 return 0; 02926 } 02927 02928 #ifdef MISDN_DEBUG 02929 { 02930 int i, max = 5 > frame->samples ? frame->samples : 5; 02931 02932 printf("write2mISDN %p %d bytes: ", p, frame->samples); 02933 02934 for (i = 0; i < max; i++) 02935 printf("%2.2x ", ((char*) frame->data)[i]); 02936 printf ("\n"); 02937 } 02938 #endif 02939 02940 switch (ch->bc->bc_state) { 02941 case BCHAN_ACTIVATED: 02942 case BCHAN_BRIDGED: 02943 break; 02944 default: 02945 if (!ch->dropped_frame_cnt) 02946 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); 02947 02948 ch->dropped_frame_cnt++; 02949 if (ch->dropped_frame_cnt > 100) { 02950 ch->dropped_frame_cnt = 0; 02951 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); 02952 } 02953 02954 return 0; 02955 } 02956 02957 chan_misdn_log(9, ch->bc->port, "Sending :%d bytes to MISDN\n", frame->samples); 02958 if ( !ch->bc->nojitter && misdn_cap_is_speech(ch->bc->capability) ) { 02959 /* Buffered Transmit (triggered by read from isdn side)*/ 02960 if (misdn_jb_fill(ch->jb, frame->data, frame->samples) < 0) { 02961 if (ch->bc->active) 02962 cb_log(0, ch->bc->port, "Misdn Jitterbuffer Overflow.\n"); 02963 } 02964 02965 } else { 02966 /*transmit without jitterbuffer*/ 02967 i = misdn_lib_tx2misdn_frm(ch->bc, frame->data, frame->samples); 02968 } 02969 02970 return 0; 02971 }
static int pbx_start_chan | ( | struct chan_list * | ch | ) | [static] |
Channel Queue End
Definition at line 3629 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().
03630 { 03631 int ret = ast_pbx_start(ch->ast); 03632 03633 if (ret >= 0) 03634 ch->need_hangup = 0; 03635 else 03636 ch->need_hangup = 1; 03637 03638 return ret; 03639 }
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 2708 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().
02709 { 02710 struct ast_frame *f,*f2; 02711 02712 if (tmp->trans) { 02713 f2 = ast_translate(tmp->trans, frame, 0); 02714 f = ast_dsp_process(tmp->ast, tmp->dsp, f2); 02715 } else { 02716 chan_misdn_log(0, tmp->bc->port, "No T-Path found\n"); 02717 return NULL; 02718 } 02719 02720 if (!f || (f->frametype != AST_FRAME_DTMF)) 02721 return frame; 02722 02723 ast_log(LOG_DEBUG, "Detected inband DTMF digit: %c\n", f->subclass); 02724 02725 if (tmp->faxdetect && (f->subclass == 'f')) { 02726 /* Fax tone -- Handle and return NULL */ 02727 if (!tmp->faxhandled) { 02728 struct ast_channel *ast = tmp->ast; 02729 tmp->faxhandled++; 02730 chan_misdn_log(0, tmp->bc->port, "Fax detected, preparing %s for fax transfer.\n", ast->name); 02731 tmp->bc->rxgain = 0; 02732 isdn_lib_update_rxgain(tmp->bc); 02733 tmp->bc->txgain = 0; 02734 isdn_lib_update_txgain(tmp->bc); 02735 #ifdef MISDN_1_2 02736 *tmp->bc->pipeline = 0; 02737 #else 02738 tmp->bc->ec_enable = 0; 02739 #endif 02740 isdn_lib_update_ec(tmp->bc); 02741 isdn_lib_stop_dtmf(tmp->bc); 02742 switch (tmp->faxdetect) { 02743 case 1: 02744 if (strcmp(ast->exten, "fax")) { 02745 char *context; 02746 char context_tmp[BUFFERSIZE]; 02747 misdn_cfg_get(tmp->bc->port, MISDN_CFG_FAXDETECT_CONTEXT, &context_tmp, sizeof(context_tmp)); 02748 context = ast_strlen_zero(context_tmp) ? (ast_strlen_zero(ast->macrocontext) ? ast->context : ast->macrocontext) : context_tmp; 02749 if (ast_exists_extension(ast, context, "fax", 1, ast->cid.cid_num)) { 02750 if (option_verbose > 2) 02751 ast_verbose(VERBOSE_PREFIX_3 "Redirecting %s to fax extension (context:%s)\n", ast->name, context); 02752 /* Save the DID/DNIS when we transfer the fax call to a "fax" extension */ 02753 pbx_builtin_setvar_helper(ast,"FAXEXTEN",ast->exten); 02754 if (ast_async_goto(ast, context, "fax", 1)) 02755 ast_log(LOG_WARNING, "Failed to async goto '%s' into fax of '%s'\n", ast->name, context); 02756 } else 02757 ast_log(LOG_NOTICE, "Fax detected, but no fax extension ctx:%s exten:%s\n", context, ast->exten); 02758 } else { 02759 ast_log(LOG_DEBUG, "Already in a fax extension, not redirecting\n"); 02760 } 02761 break; 02762 case 2: 02763 ast_verbose(VERBOSE_PREFIX_3 "Not redirecting %s to fax extension, nojump is set.\n", ast->name); 02764 break; 02765 } 02766 } else { 02767 ast_log(LOG_DEBUG, "Fax already handled\n"); 02768 } 02769 } 02770 02771 if (tmp->ast_dsp && (f->subclass != 'f')) { 02772 chan_misdn_log(2, tmp->bc->port, " --> * SEND: DTMF (AST_DSP) :%c\n", f->subclass); 02773 } 02774 02775 return f; 02776 }
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 3678 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, and chan_list::state.
Referenced by cb_events(), and misdn_hangup().
03678 { 03679 struct ast_channel *ast = NULL; 03680 03681 ast_mutex_lock(&release_lock); 03682 { 03683 struct chan_list *ch=find_chan_by_bc(cl_te, bc); 03684 if (!ch) { 03685 chan_misdn_log(1, bc->port, "release_chan: Ch not found!\n"); 03686 ast_mutex_unlock(&release_lock); 03687 return; 03688 } 03689 03690 if (ch->ast) { 03691 ast = ch->ast; 03692 } 03693 03694 chan_misdn_log(5, bc->port, "release_chan: bc with l3id: %x\n", bc->l3_id); 03695 03696 /*releasing jitterbuffer*/ 03697 if (ch->jb ) { 03698 misdn_jb_destroy(ch->jb); 03699 ch->jb = NULL; 03700 } else { 03701 if (!bc->nojitter) 03702 chan_misdn_log(5, bc->port, "Jitterbuffer already destroyed.\n"); 03703 } 03704 03705 if (ch->overlap_dial) { 03706 if (ch->overlap_dial_task != -1) { 03707 misdn_tasks_remove(ch->overlap_dial_task); 03708 ch->overlap_dial_task = -1; 03709 } 03710 ast_mutex_destroy(&ch->overlap_tv_lock); 03711 } 03712 03713 if (ch->originator == ORG_AST) { 03714 misdn_out_calls[bc->port]--; 03715 } else { 03716 misdn_in_calls[bc->port]--; 03717 } 03718 03719 if (ch) { 03720 close(ch->pipe[0]); 03721 close(ch->pipe[1]); 03722 03723 if (ast && MISDN_ASTERISK_TECH_PVT(ast)) { 03724 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)); 03725 chan_misdn_log(3, bc->port, " --> * State Down\n"); 03726 MISDN_ASTERISK_TECH_PVT(ast) = NULL; 03727 03728 if (ast->_state != AST_STATE_RESERVED) { 03729 chan_misdn_log(3, bc->port, " --> Setting AST State to down\n"); 03730 ast_setstate(ast, AST_STATE_DOWN); 03731 } 03732 } 03733 03734 ch->state = MISDN_CLEANING; 03735 cl_dequeue_chan(&cl_te, ch); 03736 03737 free(ch); 03738 } else { 03739 /* chan is already cleaned, so exiting */ 03740 } 03741 } 03742 ast_mutex_unlock(&release_lock); 03743 /*** release end **/ 03744 }
static int reload | ( | void | ) | [static] |
Definition at line 5198 of file chan_misdn.c.
References reload_config().
05199 { 05200 reload_config(); 05201 05202 return 0; 05203 }
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 3823 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().
03823 { 03824 if (!ast) { 03825 chan_misdn_log(1, 0, "send_cause2ast: No Ast\n"); 03826 return; 03827 } 03828 if (!bc) { 03829 chan_misdn_log(1, 0, "send_cause2ast: No BC\n"); 03830 return; 03831 } 03832 if (!ch) { 03833 chan_misdn_log(1, 0, "send_cause2ast: No Ch\n"); 03834 return; 03835 } 03836 03837 ast->hangupcause = bc->cause; 03838 03839 switch (bc->cause) { 03840 03841 case AST_CAUSE_UNALLOCATED: 03842 case AST_CAUSE_NO_ROUTE_TRANSIT_NET: 03843 case AST_CAUSE_NO_ROUTE_DESTINATION: 03844 case 4: /* Send special information tone */ 03845 case AST_CAUSE_NUMBER_CHANGED: 03846 case AST_CAUSE_DESTINATION_OUT_OF_ORDER: 03847 /* Congestion Cases */ 03848 /* 03849 * Not Queueing the Congestion anymore, since we want to hear 03850 * the inband message 03851 * 03852 chan_misdn_log(1, bc ? bc->port : 0, " --> * SEND: Queue Congestion pid:%d\n", bc ? bc->pid : -1); 03853 ch->state = MISDN_BUSY; 03854 03855 ast_queue_control(ast, AST_CONTROL_CONGESTION); 03856 */ 03857 break; 03858 03859 case AST_CAUSE_CALL_REJECTED: 03860 case AST_CAUSE_USER_BUSY: 03861 ch->state = MISDN_BUSY; 03862 03863 if (!ch->need_busy) { 03864 chan_misdn_log(1, bc ? bc->port : 0, "Queued busy already\n"); 03865 break; 03866 } 03867 03868 chan_misdn_log(1, bc ? bc->port : 0, " --> * SEND: Queue Busy pid:%d\n", bc ? bc->pid : -1); 03869 03870 ast_queue_control(ast, AST_CONTROL_BUSY); 03871 03872 ch->need_busy = 0; 03873 03874 break; 03875 } 03876 }
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 3139 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().
03140 { 03141 misdn_lib_tone_generator_stop(cl->bc); 03142 cl->notxtone = 0; 03143 cl->norxtone = 0; 03144 return 0; 03145 }
static void start_pbx | ( | struct chan_list * | ch, | |
struct misdn_bchannel * | bc, | |||
struct ast_channel * | chan | |||
) | [static] |
Definition at line 3971 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().
03971 { 03972 if (pbx_start_chan(ch) < 0) { 03973 hangup_chan(ch); 03974 chan_misdn_log(-1, bc->port, "ast_pbx_start returned <0 in SETUP\n"); 03975 if (bc->nt) { 03976 hanguptone_indicate(ch); 03977 misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE); 03978 } else 03979 misdn_lib_send_event(bc, EVENT_RELEASE); 03980 } 03981 }
static int stop_bc_tones | ( | struct chan_list * | cl | ) | [static] |
Definition at line 3147 of file chan_misdn.c.
References chan_list::norxtone, and chan_list::notxtone.
Referenced by cb_events(), misdn_call(), and misdn_hangup().
03148 { 03149 if (!cl) return -1; 03150 03151 cl->notxtone = 1; 03152 cl->norxtone = 1; 03153 03154 return 0; 03155 }
static int stop_indicate | ( | struct chan_list * | cl | ) | [static] |
Definition at line 3119 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().
03120 { 03121 struct ast_channel *ast = cl->ast; 03122 03123 if (!ast) { 03124 chan_misdn_log(0, cl->bc->port, "No Ast in stop_indicate\n"); 03125 return -1; 03126 } 03127 03128 chan_misdn_log(3, cl->bc->port, " --> None\n"); 03129 misdn_lib_tone_generator_stop(cl->bc); 03130 ast_playtones_stop(ast); 03131 03132 cl->ts = NULL; 03133 /*ast_deactivate_generator(ast);*/ 03134 03135 return 0; 03136 }
static int unload_module | ( | void | ) | [static] |
TE STUFF END
Definition at line 5007 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.
05008 { 05009 /* First, take us out of the channel loop */ 05010 ast_log(LOG_VERBOSE, "-- Unregistering mISDN Channel Driver --\n"); 05011 05012 misdn_tasks_destroy(); 05013 05014 if (!g_config_initialized) 05015 return 0; 05016 05017 ast_cli_unregister_multiple(chan_misdn_clis, sizeof(chan_misdn_clis) / sizeof(struct ast_cli_entry)); 05018 05019 /* ast_unregister_application("misdn_crypt"); */ 05020 ast_unregister_application("misdn_set_opt"); 05021 ast_unregister_application("misdn_facility"); 05022 ast_unregister_application("misdn_check_l2l1"); 05023 05024 ast_channel_unregister(&misdn_tech); 05025 05026 free_robin_list(); 05027 misdn_cfg_destroy(); 05028 misdn_lib_destroy(); 05029 05030 if (misdn_debug) 05031 free(misdn_debug); 05032 if (misdn_debug_only) 05033 free(misdn_debug_only); 05034 free(misdn_ports); 05035 05036 return 0; 05037 }
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 3432 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().
03433 { 03434 int chan_offset = 0; 03435 int tmp_port = misdn_cfg_get_next_port(0); 03436 for (; tmp_port > 0; tmp_port = misdn_cfg_get_next_port(tmp_port)) { 03437 if (tmp_port == port) 03438 break; 03439 chan_offset += misdn_lib_port_is_pri(tmp_port) ? 30 : 2; 03440 } 03441 if (c < 0) 03442 c = 0; 03443 03444 ast_string_field_build(tmp, name, "%s/%d-u%d", 03445 misdn_type, chan_offset + c, glob_channel++); 03446 03447 chan_misdn_log(3, port, " --> updating channel name to [%s]\n", tmp->name); 03448 }
static void wait_for_digits | ( | struct chan_list * | ch, | |
struct misdn_bchannel * | bc, | |||
struct ast_channel * | chan | |||
) | [static] |
Definition at line 3983 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().
03983 { 03984 ch->state=MISDN_WAITING4DIGS; 03985 misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE ); 03986 if (bc->nt && !bc->dad[0]) 03987 dialtone_indicate(ch); 03988 }
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 = "f450f61f60e761b3aa089ebed76ca8a5" , .load = load_module, .unload = unload_module, .reload = reload, } [static] |
Definition at line 5777 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 5777 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 3430 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(), 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 3392 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.
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] |