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