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