#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/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 |
struct | hold_info |
struct | misdn_jb |
struct | robin_list |
struct | state_struct |
Defines | |
#define | MISDN_ASTERISK_PVT(ast) 1 |
#define | MISDN_ASTERISK_TECH_PVT(ast) ast->tech_pvt |
#define | ORG_AST 1 |
#define | ORG_MISDN 2 |
Enumerations | |
enum | misdn_chan_state { MISDN_NOTHING = 0, MISDN_WAITING4DIGS, MISDN_EXTCANTMATCH, MISDN_INCOMING_SETUP, MISDN_DIALING, MISDN_PROGRESS, MISDN_PROCEEDING, MISDN_CALLING, MISDN_CALLING_ACKNOWLEDGE, MISDN_ALERTING, MISDN_BUSY, MISDN_CONNECTED, MISDN_PRECONNECTED, MISDN_DISCONNECTED, MISDN_RELEASED, MISDN_BRIDGED, MISDN_CLEANING, MISDN_HUNGUP_FROM_MISDN, MISDN_HUNGUP_FROM_AST, MISDN_HOLDED, MISDN_HOLD_DISCONNECT } |
Functions | |
static 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) |
AST_MODULE_INFO (ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT,"Channel driver for mISDN Support (BRI/PRI)",.load=load_module,.unload=unload_module,.reload=reload,) | |
static char * | bearer2str (int cap) |
static enum event_response_e | cb_events (enum event_e event, struct misdn_bchannel *bc, void *user_data) |
int | chan_misdn_jb_empty (struct misdn_bchannel *bc, char *buf, int len) |
static void | chan_misdn_log (int level, int port, char *tmpl,...) |
static void | cl_dequeue_chan (struct chan_list **list, struct chan_list *chan) |
static void | cl_queue_chan (struct chan_list **list, struct chan_list *chan) |
static char * | complete_ch (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) |
static struct chan_list * | find_chan_by_bc (struct chan_list *list, struct misdn_bchannel *bc) |
static struct chan_list * | find_chan_by_pid (struct chan_list *list, int pid) |
static struct chan_list * | find_holded (struct chan_list *list, struct misdn_bchannel *bc) |
static struct chan_list * | find_holded_l3 (struct chan_list *list, unsigned long l3_id, int w) |
static void | free_robin_list (void) |
static void | free_robin_list_r (struct robin_list *r) |
static struct chan_list * | get_chan_by_ast (struct ast_channel *ast) |
static struct chan_list * | get_chan_by_ast_name (char *name) |
static struct robin_list * | get_robin_position (char *group) |
static void | hangup_chan (struct chan_list *ch) |
static int | hanguptone_indicate (struct chan_list *cl) |
void | import_ch (struct ast_channel *chan, struct misdn_bchannel *bc, struct chan_list *ch) |
static struct chan_list * | init_chan_list (int orig) |
static int | load_module (void) |
static int | misdn_answer (struct ast_channel *ast) |
static enum ast_bridge_result | misdn_bridge (struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc, int timeoutms) |
static int | misdn_call (struct ast_channel *ast, char *dest, int timeout) |
static int | misdn_check_l2l1 (struct ast_channel *chan, void *data) |
static int | misdn_digit_begin (struct ast_channel *chan, char digit) |
static int | misdn_digit_end (struct ast_channel *ast, char digit, unsigned int duration) |
static int | misdn_facility_exec (struct ast_channel *chan, void *data) |
static int | misdn_fixup (struct ast_channel *oldast, struct ast_channel *ast) |
static 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) |
int | misdn_jb_empty (struct misdn_jb *jb, char *data, int len) |
int | misdn_jb_fill (struct misdn_jb *jb, const char *data, int len) |
misdn_jb * | misdn_jb_init (int size, int upper_threshold) |
static int | misdn_l1_task (const void *data) |
static struct ast_channel * | misdn_new (struct chan_list *cl, int state, char *exten, char *callerid, int format, int port, int c) |
static int | misdn_overlap_dial_task (const void *data) |
static int | misdn_port_block (int fd, int argc, char *argv[]) |
static int | misdn_port_down (int fd, int argc, char *argv[]) |
static int | misdn_port_unblock (int fd, int argc, char *argv[]) |
static int | misdn_port_up (int fd, int argc, char *argv[]) |
static struct ast_frame * | misdn_read (struct ast_channel *ast) |
static int | misdn_reload (int fd, int argc, char *argv[]) |
static struct ast_channel * | misdn_request (const char *type, int format, void *data, int *cause) |
static int | misdn_restart_pid (int fd, int argc, char *argv[]) |
static int | misdn_restart_port (int fd, int argc, char *argv[]) |
static int | misdn_send_cd (int fd, int argc, char *argv[]) |
static int | misdn_send_digit (int fd, int argc, char *argv[]) |
static int | misdn_send_display (int fd, int argc, char *argv[]) |
static int | misdn_send_restart (int fd, int argc, char *argv[]) |
static int | misdn_send_text (struct ast_channel *chan, const char *text) |
static int | misdn_set_crypt_debug (int fd, int argc, char *argv[]) |
static int | misdn_set_debug (int fd, int argc, char *argv[]) |
static int | misdn_set_opt_exec (struct ast_channel *chan, void *data) |
static int | misdn_set_tics (int fd, int argc, char *argv[]) |
static int | misdn_show_cl (int fd, int argc, char *argv[]) |
static int | misdn_show_cls (int fd, int argc, char *argv[]) |
static int | misdn_show_config (int fd, int argc, char *argv[]) |
static int | misdn_show_port (int fd, int argc, char *argv[]) |
static int | misdn_show_ports_stats (int fd, int argc, char *argv[]) |
static int | misdn_show_stacks (int fd, int argc, char *argv[]) |
static int | misdn_tasks_add (int timeout, ast_sched_cb callback, const void *data) |
static int | misdn_tasks_add_variable (int timeout, ast_sched_cb callback, const void *data) |
static void | misdn_tasks_destroy (void) |
static void | misdn_tasks_init (void) |
static void | misdn_tasks_remove (int task_id) |
static void * | misdn_tasks_thread_func (void *data) |
static void | misdn_tasks_wakeup (void) |
static int | misdn_toggle_echocancel (int fd, int argc, char *argv[]) |
static void | misdn_transfer_bc (struct chan_list *tmp_ch, struct chan_list *holded_chan) |
static int | misdn_write (struct ast_channel *ast, struct ast_frame *frame) |
static int | pbx_start_chan (struct chan_list *ch) |
static void | print_bc_info (int fd, struct chan_list *help, struct misdn_bchannel *bc) |
static void | print_bearer (struct misdn_bchannel *bc) |
static void | print_facility (struct FacParm *fac, struct misdn_bchannel *bc) |
static struct ast_frame * | process_ast_dsp (struct chan_list *tmp, struct ast_frame *frame) |
static int | read_config (struct chan_list *ch, int orig) |
static void | release_chan (struct misdn_bchannel *bc) |
static int | reload (void) |
static void | reload_config (void) |
static void | send_cause2ast (struct ast_channel *ast, struct misdn_bchannel *bc, struct chan_list *ch) |
static void | send_digit_to_chan (struct chan_list *cl, char digit) |
static void | show_config_description (int fd, enum misdn_cfg_elements elem) |
static void | sighandler (int sig) |
static int | start_bc_tones (struct chan_list *cl) |
static void | start_pbx (struct chan_list *ch, struct misdn_bchannel *bc, struct ast_channel *chan) |
static int | stop_bc_tones (struct chan_list *cl) |
static int | stop_indicate (struct chan_list *cl) |
static int | unload_module (void) |
static int | update_config (struct chan_list *ch, int orig) |
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 | |
allowed_bearers | allowed_bearers_array [] |
static struct ast_cli_entry | chan_misdn_clis [] |
chan_list * | cl_te = NULL |
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 |
static pthread_t | misdn_tasks_thread |
static struct ast_channel_tech | misdn_tech |
static struct ast_channel_tech | misdn_tech_wo_bridge |
static const char | misdn_type [] = "mISDN" |
static int | prefformat = AST_FORMAT_ALAW |
ast_mutex_t | release_lock |
static struct robin_list * | robin = NULL |
static struct state_struct | state_array [] |
static int | tracing = 0 |
Definition in file chan_misdn.c.
#define MISDN_ASTERISK_PVT | ( | ast | ) | 1 |
#define MISDN_ASTERISK_TECH_PVT | ( | ast | ) | ast->tech_pvt |
Definition at line 298 of file chan_misdn.c.
Referenced by cb_events(), do_immediate_setup(), misdn_answer(), misdn_call(), misdn_digit_end(), misdn_facility_exec(), misdn_fixup(), misdn_hangup(), misdn_indication(), misdn_read(), misdn_set_opt_exec(), misdn_write(), and release_chan().
#define ORG_AST 1 |
Definition at line 144 of file chan_misdn.c.
Referenced by export_aoc_vars(), misdn_call(), misdn_hangup(), misdn_request(), print_bc_info(), read_config(), and release_chan().
#define ORG_MISDN 2 |
enum misdn_chan_state |
Definition at line 118 of file chan_misdn.c.
00118 { 00119 MISDN_NOTHING=0, /*!< at beginning */ 00120 MISDN_WAITING4DIGS, /*!< when waiting for infos */ 00121 MISDN_EXTCANTMATCH, /*!< when asterisk couldnt match our ext */ 00122 MISDN_INCOMING_SETUP, /*!< for incoming setups*/ 00123 MISDN_DIALING, /*!< when pbx_start */ 00124 MISDN_PROGRESS, /*!< we got a progress */ 00125 MISDN_PROCEEDING, /*!< we got a progress */ 00126 MISDN_CALLING, /*!< when misdn_call is called */ 00127 MISDN_CALLING_ACKNOWLEDGE, /*!< when we get SETUP_ACK */ 00128 MISDN_ALERTING, /*!< when Alerting */ 00129 MISDN_BUSY, /*!< when BUSY */ 00130 MISDN_CONNECTED, /*!< when connected */ 00131 MISDN_PRECONNECTED, /*!< when connected */ 00132 MISDN_DISCONNECTED, /*!< when connected */ 00133 MISDN_RELEASED, /*!< when connected */ 00134 MISDN_BRIDGED, /*!< when bridged */ 00135 MISDN_CLEANING, /*!< when hangup from * but we were connected before */ 00136 MISDN_HUNGUP_FROM_MISDN, /*!< when DISCONNECT/RELEASE/REL_COMP cam from misdn */ 00137 MISDN_HUNGUP_FROM_AST, /*!< when DISCONNECT/RELEASE/REL_COMP came out of */ 00138 /* misdn_hangup */ 00139 MISDN_HOLDED, /*!< if this chan is holded */ 00140 MISDN_HOLD_DISCONNECT, /*!< if this chan is holded */ 00141 00142 };
static int _misdn_tasks_add_variable | ( | int | timeout, | |
ast_sched_cb | callback, | |||
const void * | data, | |||
int | variable | |||
) | [inline, static] |
Definition at line 618 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().
00619 { 00620 int task_id; 00621 00622 if (!misdn_tasks) { 00623 misdn_tasks_init(); 00624 } 00625 task_id = ast_sched_add_variable(misdn_tasks, timeout, callback, data, variable); 00626 misdn_tasks_wakeup(); 00627 00628 return task_id; 00629 }
int add_in_calls | ( | int | port | ) |
Definition at line 3854 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().
03855 { 03856 int max_in_calls; 03857 03858 misdn_cfg_get( port, MISDN_CFG_MAX_IN, &max_in_calls, sizeof(max_in_calls)); 03859 misdn_in_calls[port]++; 03860 03861 if (max_in_calls >=0 && max_in_calls<misdn_in_calls[port]) { 03862 ast_log(LOG_NOTICE,"Marking Incoming Call on port[%d]\n",port); 03863 return misdn_in_calls[port]-max_in_calls; 03864 } 03865 03866 return 0; 03867 }
int add_out_calls | ( | int | port | ) |
Definition at line 3869 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().
03870 { 03871 int max_out_calls; 03872 03873 misdn_cfg_get( port, MISDN_CFG_MAX_OUT, &max_out_calls, sizeof(max_out_calls)); 03874 03875 03876 if (max_out_calls >=0 && max_out_calls<=misdn_out_calls[port]) { 03877 ast_log(LOG_NOTICE,"Rejecting Outgoing Call on port[%d]\n",port); 03878 return (misdn_out_calls[port]+1)-max_out_calls; 03879 } 03880 03881 misdn_out_calls[port]++; 03882 03883 return 0; 03884 }
AST_MODULE_INFO | ( | ASTERISK_GPL_KEY | , | |
AST_MODFLAG_DEFAULT | , | |||
"Channel driver for mISDN Support (BRI/PRI)" | , | |||
. | load = load_module , |
|||
. | unload = unload_module , |
|||
. | reload = reload | |||
) |
static char* bearer2str | ( | int | cap | ) | [static] |
Definition at line 412 of file chan_misdn.c.
References INFO_CAPABILITY_AUDIO_3_1K, INFO_CAPABILITY_DIGITAL_RESTRICTED, INFO_CAPABILITY_DIGITAL_UNRESTRICTED, INFO_CAPABILITY_SPEECH, and INFO_CAPABILITY_VIDEO.
Referenced by misdn_lib_log_ies(), print_bc_info(), and print_bearer().
00412 { 00413 static char *bearers[]={ 00414 "Speech", 00415 "Audio 3.1k", 00416 "Unres Digital", 00417 "Res Digital", 00418 "Video", 00419 "Unknown Bearer" 00420 }; 00421 00422 switch (cap) { 00423 case INFO_CAPABILITY_SPEECH: 00424 return bearers[0]; 00425 break; 00426 case INFO_CAPABILITY_AUDIO_3_1K: 00427 return bearers[1]; 00428 break; 00429 case INFO_CAPABILITY_DIGITAL_UNRESTRICTED: 00430 return bearers[2]; 00431 break; 00432 case INFO_CAPABILITY_DIGITAL_RESTRICTED: 00433 return bearers[3]; 00434 break; 00435 case INFO_CAPABILITY_VIDEO: 00436 return bearers[4]; 00437 break; 00438 default: 00439 return bearers[5]; 00440 break; 00441 } 00442 }
static enum event_response_e cb_events | ( | enum event_e | event, | |
struct misdn_bchannel * | bc, | |||
void * | user_data | |||
) | [static] |
Definition at line 3910 of file chan_misdn.c.
References add_in_calls(), misdn_bchannel::addr, chan_list::addr, chan_list::allowed_bearers, allowed_bearers_array, chan_list::ast, ast_canmatch_extension(), ast_cdr_update(), ast_exists_extension(), AST_FORMAT_ALAW, AST_FRAME_DTMF, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_pickup_call(), ast_pickup_ext(), AST_PRES_ALLOWED, AST_PRES_NETWORK_NUMBER, AST_PRES_RESTRICTED, AST_PRES_UNAVAILABLE, AST_PRES_USER_NUMBER_FAILED_SCREEN, AST_PRES_USER_NUMBER_PASSED_SCREEN, AST_PRES_USER_NUMBER_UNSCREENED, ast_queue_frame(), ast_setstate(), AST_STATE_DOWN, AST_STATE_RESERVED, AST_STATE_RINGING, ast_strlen_zero(), ast_transfercapability2str(), chan_list::bc, misdn_bchannel::bc_state, bc_state2str(), misdn_bchannel::capability, cb_log, chan_misdn_log(), misdn_bchannel::channel, ast_channel::cid, ast_callerid::cid_pres, cl_queue_chan(), cl_te, misdn_bchannel::cw, misdn_bchannel::dad, misdn_bchannel::dtmf, EVENT_BCHAN_ACTIVATED, EVENT_BCHAN_DATA, EVENT_CLEANUP, EVENT_DISCONNECT, EVENT_DTMF_TONE, EVENT_FACILITY, EVENT_INFORMATION, EVENT_NEW_BC, EVENT_NEW_CHANNEL, EVENT_NEW_L3ID, EVENT_PORT_ALARM, EVENT_RELEASE, EVENT_RELEASE_COMPLETE, EVENT_RETRIEVE, EVENT_SETUP, EVENT_SETUP_ACKNOWLEDGE, EVENT_STATUS, EVENT_TIMEOUT, EVENT_TONE_GENERATE, export_ch(), find_chan_by_bc(), find_holded(), hangup_chan(), hanguptone_indicate(), chan_list::ignore_dtmf, INFO_CAPABILITY_DIGITAL_UNRESTRICTED, misdn_bchannel::info_dad, init_chan_list(), misdn_bchannel::keypad, misdn_bchannel::l3_id, chan_list::l3id, LOG_ERROR, LOG_NOTICE, LOG_WARNING, manager_isdn_get_info(), MISDN_ASTERISK_PVT, MISDN_ASTERISK_TECH_PVT, MISDN_CALLING_ACKNOWLEDGE, MISDN_CFG_ALARM_BLOCK, misdn_cfg_get(), misdn_cfg_is_msn_valid(), MISDN_CFG_REJECT_CAUSE, MISDN_CONNECTED, MISDN_DIALING, MISDN_EXTCANTMATCH, MISDN_GEN_APPEND_DIGITS2EXTEN, misdn_get_ch_state(), MISDN_INCOMING_SETUP, misdn_lib_log_ies(), misdn_lib_port_block(), misdn_lib_send_event(), misdn_new(), MISDN_NOTHING, misdn_overlap_dial_task(), misdn_tasks_add_variable(), MISDN_WAITING4DIGS, allowed_bearers::name, chan_list::noautorespond_on_setup, misdn_bchannel::nt, misdn_bchannel::oad, ORG_MISDN, chan_list::originator, misdn_bchannel::out_cause, pbx_builtin_setvar_helper(), misdn_bchannel::pid, misdn_bchannel::port, misdn_bchannel::pres, print_bearer(), read_config(), RESPONSE_IGNORE_SETUP, RESPONSE_IGNORE_SETUP_WITHOUT_CLOSE, RESPONSE_OK, RESPONSE_RELEASE_SETUP, ast_channel::rings, misdn_bchannel::screen, start_pbx(), chan_list::state, stop_indicate(), ast_channel::transfercapability, and update_name().
Referenced by load_module().
03911 { 03912 int msn_valid; 03913 struct chan_list *ch=find_chan_by_bc(cl_te, bc); 03914 03915 if (event != EVENT_BCHAN_DATA && event != EVENT_TONE_GENERATE) { /* Debug Only Non-Bchan */ 03916 int debuglevel=1; 03917 if ( event==EVENT_CLEANUP && !user_data) 03918 debuglevel=5; 03919 03920 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"); 03921 if (debuglevel==1) { 03922 misdn_lib_log_ies(bc); 03923 chan_misdn_log(4,bc->port," --> bc_state:%s\n",bc_state2str(bc->bc_state)); 03924 } 03925 } 03926 03927 if (!ch) { 03928 switch(event) { 03929 case EVENT_SETUP: 03930 case EVENT_DISCONNECT: 03931 case EVENT_PORT_ALARM: 03932 case EVENT_RETRIEVE: 03933 case EVENT_NEW_BC: 03934 case EVENT_FACILITY: 03935 break; 03936 case EVENT_RELEASE_COMPLETE: 03937 chan_misdn_log(1, bc->port, " --> no Ch, so we've already released.\n"); 03938 break; 03939 case EVENT_CLEANUP: 03940 case EVENT_TONE_GENERATE: 03941 case EVENT_BCHAN_DATA: 03942 return -1; 03943 03944 default: 03945 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); 03946 return -1; 03947 } 03948 } 03949 03950 if (ch ) { 03951 switch (event) { 03952 case EVENT_TONE_GENERATE: 03953 break; 03954 case EVENT_DISCONNECT: 03955 case EVENT_RELEASE: 03956 case EVENT_RELEASE_COMPLETE: 03957 case EVENT_CLEANUP: 03958 case EVENT_TIMEOUT: 03959 if (!ch->ast) 03960 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)); 03961 break; 03962 default: 03963 if ( !ch->ast || !MISDN_ASTERISK_PVT(ch->ast) || !MISDN_ASTERISK_TECH_PVT(ch->ast)) { 03964 if (event!=EVENT_BCHAN_DATA) 03965 ast_log(LOG_NOTICE, "No Ast or No private Pointer in Event (%d:%s)\n", event, manager_isdn_get_info(event)); 03966 return -1; 03967 } 03968 } 03969 } 03970 03971 03972 switch (event) { 03973 case EVENT_PORT_ALARM: 03974 { 03975 int boa=0; 03976 misdn_cfg_get( bc->port, MISDN_CFG_ALARM_BLOCK, &boa, sizeof(int)); 03977 if (boa) { 03978 cb_log(1,bc->port," --> blocking\n"); 03979 misdn_lib_port_block(bc->port); 03980 } 03981 } 03982 break; 03983 case EVENT_BCHAN_ACTIVATED: 03984 break; 03985 03986 case EVENT_NEW_CHANNEL: 03987 update_name(ch->ast,bc->port,bc->channel); 03988 break; 03989 03990 case EVENT_NEW_L3ID: 03991 ch->l3id=bc->l3_id; 03992 ch->addr=bc->addr; 03993 break; 03994 03995 case EVENT_NEW_BC: 03996 if (!ch) { 03997 ch=find_holded(cl_te,bc); 03998 } 03999 04000 if (!ch) { 04001 ast_log(LOG_WARNING,"NEW_BC without chan_list?\n"); 04002 break; 04003 } 04004 04005 if (bc) 04006 ch->bc=(struct misdn_bchannel*)user_data; 04007 break; 04008 04009 case EVENT_DTMF_TONE: 04010 { 04011 /* sending INFOS as DTMF-Frames :) */ 04012 struct ast_frame fr; 04013 memset(&fr, 0 , sizeof(fr)); 04014 fr.frametype = AST_FRAME_DTMF; 04015 fr.subclass = bc->dtmf ; 04016 fr.src=NULL; 04017 fr.data = NULL ; 04018 fr.datalen = 0; 04019 fr.samples = 0 ; 04020 fr.mallocd =0 ; 04021 fr.offset= 0 ; 04022 fr.delivery= ast_tv(0,0) ; 04023 04024 if (!ch->ignore_dtmf) { 04025 chan_misdn_log(2, bc->port, " --> DTMF:%c\n", bc->dtmf); 04026 ast_queue_frame(ch->ast, &fr); 04027 } else { 04028 chan_misdn_log(2, bc->port, " --> Ingoring DTMF:%c due to bridge flags\n", bc->dtmf); 04029 } 04030 } 04031 break; 04032 case EVENT_STATUS: 04033 break; 04034 04035 case EVENT_INFORMATION: 04036 { 04037 int l; 04038 04039 if ( ch->state != MISDN_CONNECTED ) 04040 stop_indicate(ch); 04041 04042 if (!ch->ast) break; 04043 04044 if (ch->state == MISDN_WAITING4DIGS ) { 04045 /* Ok, incomplete Setup, waiting till extension exists */ 04046 if (ast_strlen_zero(bc->info_dad) && ! ast_strlen_zero(bc->keypad)) { 04047 chan_misdn_log(1, bc->port, " --> using keypad as info\n"); 04048 strcpy(bc->info_dad,bc->keypad); 04049 } 04050 04051 l = sizeof(bc->dad); 04052 strncat(bc->dad,bc->info_dad, l - strlen(bc->dad) - 1); 04053 04054 l = sizeof(ch->ast->exten); 04055 strncpy(ch->ast->exten, bc->dad, l); 04056 ch->ast->exten[l-1] = 0; 04057 04058 /* Check for Pickup Request first */ 04059 if (!strcmp(ch->ast->exten, ast_pickup_ext())) { 04060 if (ast_pickup_call(ch->ast)) { 04061 hangup_chan(ch); 04062 } else { 04063 struct ast_channel *chan=ch->ast; 04064 ch->state = MISDN_CALLING_ACKNOWLEDGE; 04065 ast_setstate(chan, AST_STATE_DOWN); 04066 hangup_chan(ch); 04067 ch->ast=NULL; 04068 break; 04069 } 04070 } 04071 04072 if(!ast_canmatch_extension(ch->ast, ch->context, bc->dad, 1, bc->oad)) { 04073 if (ast_exists_extension(ch->ast, ch->context, "i", 1, bc->oad)) { 04074 ast_log(LOG_WARNING, "Extension can never match, So jumping to 'i' extension. port(%d)\n",bc->port); 04075 strcpy(ch->ast->exten, "i"); 04076 04077 ch->state = MISDN_DIALING; 04078 start_pbx(ch, bc, ch->ast); 04079 break; 04080 } 04081 04082 ast_log(LOG_WARNING, "Extension can never match, so disconnecting on port(%d)." 04083 "maybe you want to add an 'i' extension to catch this case.\n", 04084 bc->port); 04085 04086 if (bc->nt) 04087 hanguptone_indicate(ch); 04088 ch->state=MISDN_EXTCANTMATCH; 04089 bc->out_cause=1; 04090 04091 misdn_lib_send_event(bc, EVENT_DISCONNECT ); 04092 break; 04093 } 04094 04095 if (ch->overlap_dial) { 04096 ast_mutex_lock(&ch->overlap_tv_lock); 04097 ch->overlap_tv = ast_tvnow(); 04098 ast_mutex_unlock(&ch->overlap_tv_lock); 04099 if (ch->overlap_dial_task == -1) { 04100 ch->overlap_dial_task = 04101 misdn_tasks_add_variable(ch->overlap_dial, misdn_overlap_dial_task, ch); 04102 } 04103 break; 04104 } 04105 04106 if (ast_exists_extension(ch->ast, ch->context, bc->dad, 1, bc->oad)) { 04107 04108 ch->state = MISDN_DIALING; 04109 start_pbx(ch, bc, ch->ast); 04110 } 04111 } else { 04112 /* sending INFOS as DTMF-Frames :) */ 04113 int digits; 04114 struct ast_frame fr; 04115 memset(&fr, 0, sizeof(fr)); 04116 fr.frametype = AST_FRAME_DTMF; 04117 fr.subclass = bc->info_dad[0] ; 04118 fr.src=NULL; 04119 fr.data = NULL ; 04120 fr.datalen = 0; 04121 fr.samples = 0 ; 04122 fr.mallocd =0 ; 04123 fr.offset= 0 ; 04124 fr.delivery= ast_tv(0,0) ; 04125 04126 misdn_cfg_get( 0, MISDN_GEN_APPEND_DIGITS2EXTEN, &digits, sizeof(int)); 04127 if (ch->state != MISDN_CONNECTED ) { 04128 if (digits) { 04129 int l = sizeof(bc->dad); 04130 strncat(bc->dad, bc->info_dad, l - strlen(bc->dad) - 1); 04131 l = sizeof(ch->ast->exten); 04132 strncpy(ch->ast->exten, bc->dad, l); 04133 ch->ast->exten[l-1] = 0; 04134 04135 ast_cdr_update(ch->ast); 04136 } 04137 04138 ast_queue_frame(ch->ast, &fr); 04139 } 04140 } 04141 } 04142 break; 04143 case EVENT_SETUP: 04144 { 04145 struct chan_list *ch=find_chan_by_bc(cl_te, bc); 04146 if (ch) { 04147 switch (ch->state) { 04148 case MISDN_NOTHING: 04149 ch=NULL; 04150 break; 04151 default: 04152 chan_misdn_log(1, bc->port, " --> Ignoring Call we have already one\n"); 04153 return RESPONSE_IGNORE_SETUP_WITHOUT_CLOSE; /* Ignore MSNs which are not in our List */ 04154 } 04155 } 04156 } 04157 04158 msn_valid = misdn_cfg_is_msn_valid(bc->port, bc->dad); 04159 if (!bc->nt && ! msn_valid) { 04160 chan_misdn_log(1, bc->port, " --> Ignoring Call, its not in our MSN List\n"); 04161 return RESPONSE_IGNORE_SETUP; /* Ignore MSNs which are not in our List */ 04162 } 04163 04164 04165 if (bc->cw) { 04166 int cause; 04167 chan_misdn_log(0, bc->port, " --> Call Waiting on PMP sending RELEASE_COMPLETE\n"); 04168 misdn_cfg_get( bc->port, MISDN_CFG_REJECT_CAUSE, &cause, sizeof(cause)); 04169 bc->out_cause=cause?cause:16; 04170 return RESPONSE_RELEASE_SETUP; 04171 } 04172 04173 print_bearer(bc); 04174 04175 { 04176 struct chan_list *ch; 04177 struct ast_channel *chan; 04178 int exceed; 04179 int pres,screen; 04180 int msn_valid = misdn_cfg_is_msn_valid(bc->port, bc->dad); 04181 int ai, im; 04182 if (!bc->nt && ! msn_valid) { 04183 chan_misdn_log(1, bc->port, " --> Ignoring Call, its not in our MSN List\n"); 04184 return RESPONSE_IGNORE_SETUP; /* Ignore MSNs which are not in our List */ 04185 } 04186 04187 if (bc->cw) { 04188 int cause; 04189 chan_misdn_log(0, bc->port, " --> Call Waiting on PMP sending RELEASE_COMPLETE\n"); 04190 misdn_cfg_get( bc->port, MISDN_CFG_REJECT_CAUSE, &cause, sizeof(cause)); 04191 bc->out_cause=cause?cause:16; 04192 return RESPONSE_RELEASE_SETUP; 04193 } 04194 04195 print_bearer(bc); 04196 04197 ch=init_chan_list(ORG_MISDN); 04198 04199 if (!ch) { chan_misdn_log(-1, bc->port, "cb_events: malloc for chan_list failed!\n"); return 0;} 04200 04201 ch->bc = bc; 04202 ch->l3id=bc->l3_id; 04203 ch->addr=bc->addr; 04204 ch->originator = ORG_MISDN; 04205 04206 chan=misdn_new(ch, AST_STATE_RESERVED,bc->dad, bc->oad, AST_FORMAT_ALAW, bc->port, bc->channel); 04207 04208 if (!chan) { 04209 misdn_lib_send_event(bc,EVENT_RELEASE_COMPLETE); 04210 ast_log(LOG_ERROR, "cb_events: misdn_new failed !\n"); 04211 return 0; 04212 } 04213 04214 ch->ast = chan; 04215 04216 if ((exceed=add_in_calls(bc->port))) { 04217 char tmp[16]; 04218 sprintf(tmp,"%d",exceed); 04219 pbx_builtin_setvar_helper(chan,"MAX_OVERFLOW",tmp); 04220 } 04221 04222 read_config(ch, ORG_MISDN); 04223 04224 export_ch(chan, bc, ch); 04225 04226 ch->ast->rings=1; 04227 ast_setstate(ch->ast, AST_STATE_RINGING); 04228 04229 switch (bc->pres) { 04230 case 1: 04231 pres=AST_PRES_RESTRICTED; chan_misdn_log(2,bc->port," --> PRES: Restricted (1)\n"); 04232 break; 04233 case 2: 04234 pres=AST_PRES_UNAVAILABLE; chan_misdn_log(2,bc->port," --> PRES: Restricted (2)\n"); 04235 break; 04236 default: 04237 pres=AST_PRES_ALLOWED; chan_misdn_log(2,bc->port," --> PRES: Restricted (%d)\n", bc->pres); 04238 } 04239 04240 switch (bc->screen) { 04241 case 0: 04242 screen=AST_PRES_USER_NUMBER_UNSCREENED; chan_misdn_log(2,bc->port," --> SCREEN: Unscreened (0)\n"); 04243 break; 04244 case 1: 04245 screen=AST_PRES_USER_NUMBER_PASSED_SCREEN; chan_misdn_log(2,bc->port," --> SCREEN: Passed screen (1)\n"); 04246 break; 04247 case 2: 04248 screen=AST_PRES_USER_NUMBER_FAILED_SCREEN; chan_misdn_log(2,bc->port," --> SCREEN: failed screen (2)\n"); 04249 break; 04250 case 3: 04251 screen=AST_PRES_NETWORK_NUMBER; chan_misdn_log(2,bc->port," --> SCREEN: Network Number (3)\n"); 04252 break; 04253 default: 04254 screen=AST_PRES_USER_NUMBER_UNSCREENED; chan_misdn_log(2,bc->port," --> SCREEN: Unscreened (%d)\n",bc->screen); 04255 } 04256 04257 chan->cid.cid_pres=pres+screen; 04258 04259 pbx_builtin_setvar_helper(chan, "TRANSFERCAPABILITY", ast_transfercapability2str(bc->capability)); 04260 chan->transfercapability=bc->capability; 04261 04262 switch (bc->capability) { 04263 case INFO_CAPABILITY_DIGITAL_UNRESTRICTED: 04264 pbx_builtin_setvar_helper(chan,"CALLTYPE","DIGITAL"); 04265 break; 04266 default: 04267 pbx_builtin_setvar_helper(chan,"CALLTYPE","SPEECH"); 04268 } 04269 04270 /** queue new chan **/ 04271 cl_queue_chan(&cl_te, ch) ; 04272 04273 if (!strstr(ch->allowed_bearers,"all")) { 04274 int i; 04275 for (i=0; i< sizeof(allowed_bearers_array)/sizeof(struct allowed_bearers); i++) { 04276 if (allowed_bearers_array[i].cap == bc->capability) { 04277 if ( !strstr( ch->allowed_bearers, allowed_bearers_array[i].name)) { 04278 chan_misdn_log(0,bc->port,"Bearer Not allowed\b"); 04279 bc->out_cause=88; 04280 04281 ch->state=MISDN_EXTCANTMATCH; 04282 misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE ); 04283 return RESPONSE_OK; 04284 } 04285 } 04286 04287 } 04288 } 04289 04290 /* Check for Pickup Request first */ 04291 if (!strcmp(chan->exten, ast_pickup_ext())) { 04292 if (!ch->noautorespond_on_setup) { 04293 int ret;/** Sending SETUP_ACK**/ 04294 ret = misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE ); 04295 } else { 04296 ch->state = MISDN_INCOMING_SETUP; 04297 } 04298 if (ast_pickup_call(chan)) { 04299 hangup_chan(ch); 04300 } else { 04301 ch->state = MISDN_CALLING_ACKNOWLEDGE; 04302 ast_setstate(chan, AST_STATE_DOWN); 04303 hangup_chan(ch); 04304 ch->ast=NULL; 04305 break; 04306 } 04307 } 04308 04309 /* 04310 added support for s extension hope it will help those poor cretains 04311 which haven't overlap dial. 04312 */ 04313 misdn_cfg_get( bc->port, MISDN_CFG_ALWAYS_IMMEDIATE, &ai, sizeof(ai)); 04314 if ( ai ) { 04315 do_immediate_setup(bc, ch , chan); 04316 break; 04317 } 04318 04319 /* check if we should jump into s when we have no dad */ 04320 misdn_cfg_get( bc->port, MISDN_CFG_IMMEDIATE, &im, sizeof(im)); 04321 if ( im && ast_strlen_zero(bc->dad) ) { 04322 do_immediate_setup(bc, ch , chan); 04323 break; 04324 } 04325 04326 chan_misdn_log(5,bc->port,"CONTEXT:%s\n",ch->context); 04327 if(!ast_canmatch_extension(ch->ast, ch->context, bc->dad, 1, bc->oad)) { 04328 if (ast_exists_extension(ch->ast, ch->context, "i", 1, bc->oad)) { 04329 ast_log(LOG_WARNING, "Extension can never match, So jumping to 'i' extension. port(%d)\n",bc->port); 04330 strcpy(ch->ast->exten, "i"); 04331 misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE); 04332 ch->state=MISDN_DIALING; 04333 start_pbx(ch, bc, chan); 04334 break; 04335 } 04336 04337 ast_log(LOG_WARNING, "Extension can never match, so disconnecting on port(%d)." 04338 "maybe you want to add an 'i' extension to catch this case.\n", 04339 bc->port); 04340 if (bc->nt) 04341 hanguptone_indicate(ch); 04342 04343 ch->state=MISDN_EXTCANTMATCH; 04344 bc->out_cause=1; 04345 04346 if (bc->nt) 04347 misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE ); 04348 else 04349 misdn_lib_send_event(bc, EVENT_RELEASE ); 04350 04351 break; 04352 } 04353 04354 /* Whatever happens, when sending_complete is set or we are PTMP TE, we will definitely 04355 * jump into the dialplan, when the dialed extension does not exist, the 's' extension 04356 * will be used by Asterisk automatically. */ 04357 if (bc->sending_complete || (!bc->nt && !misdn_lib_is_ptp(bc->port))) { 04358 if (!ch->noautorespond_on_setup) { 04359 ch->state=MISDN_DIALING; 04360 misdn_lib_send_event(bc, EVENT_PROCEEDING ); 04361 } else { 04362 ch->state = MISDN_INCOMING_SETUP; 04363 } 04364 start_pbx(ch, bc, chan); 04365 break; 04366 } 04367 04368 04369 /* 04370 * When we are NT and overlapdial is set and if 04371 * the number is empty, we wait for the ISDN timeout 04372 * instead of our own timer. 04373 */ 04374 if (ch->overlap_dial && bc->nt && !bc->dad[0] ) { 04375 wait_for_digits(ch, bc, chan); 04376 break; 04377 } 04378 04379 /* 04380 * If overlapdial we will definitely send a SETUP_ACKNOWLEDGE and wait for more 04381 * Infos with a Interdigit Timeout. 04382 * */ 04383 if (ch->overlap_dial) { 04384 ast_mutex_lock(&ch->overlap_tv_lock); 04385 ch->overlap_tv = ast_tvnow(); 04386 ast_mutex_unlock(&ch->overlap_tv_lock); 04387 04388 wait_for_digits(ch, bc, chan); 04389 if (ch->overlap_dial_task == -1) 04390 ch->overlap_dial_task = 04391 misdn_tasks_add_variable(ch->overlap_dial, misdn_overlap_dial_task, ch); 04392 04393 break; 04394 } 04395 04396 /* If the extension does not exist and we're not TE_PTMP we wait for more digis 04397 * without interdigit timeout. 04398 * */ 04399 if (!ast_exists_extension(ch->ast, ch->context, bc->dad, 1, bc->oad)) { 04400 wait_for_digits(ch, bc, chan); 04401 break; 04402 } 04403 04404 /* 04405 * If the extension exists let's just jump into it. 04406 * */ 04407 if (ast_exists_extension(ch->ast, ch->context, bc->dad, 1, bc->oad)) { 04408 if (bc->need_more_infos) 04409 misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE ); 04410 else 04411 misdn_lib_send_event(bc, EVENT_PROCEEDING); 04412 04413 ch->state=MISDN_DIALING; 04414 start_pbx(ch, bc, chan); 04415 break; 04416 } 04417 } 04418 break; 04419 04420 case EVENT_SETUP_ACKNOWLEDGE: 04421 { 04422 ch->state = MISDN_CALLING_ACKNOWLEDGE; 04423 04424 if (bc->channel) 04425 update_name(ch->ast,bc->port,bc->channel); 04426 04427 if (!ast_strlen_zero(bc->infos_pending)) { 04428 /* TX Pending Infos */ 04429 04430 { 04431 int l = sizeof(bc->dad); 04432 strncat(bc->dad, bc->infos_pending, l - strlen(bc->dad) - 1); 04433 } 04434 04435 if (!ch->ast) break; 04436 { 04437 int l = sizeof(ch->ast->exten); 04438 strncpy(ch->ast->exten, bc->dad, l); 04439 ch->ast->exten[l-1] = 0; 04440 } 04441 { 04442 int l = sizeof(bc->info_dad); 04443 strncpy(bc->info_dad, bc->infos_pending, l); 04444 bc->info_dad[l-1] = 0; 04445 } 04446 strncpy(bc->infos_pending,"", 1); 04447 04448 misdn_lib_send_event(bc, EVENT_INFORMATION); 04449 } 04450 } 04451 break; 04452 case EVENT_PROCEEDING: 04453 { 04454 if (bc->channel) 04455 update_name(ch->ast,bc->port,bc->channel); 04456 04457 if ( misdn_cap_is_speech(bc->capability) && 04458 misdn_inband_avail(bc) ) { 04459 start_bc_tones(ch); 04460 } 04461 04462 ch->state = MISDN_PROCEEDING; 04463 04464 if (!ch->ast) break; 04465 04466 ast_queue_control(ch->ast, AST_CONTROL_PROCEEDING); 04467 } 04468 break; 04469 case EVENT_PROGRESS: 04470 if (bc->channel) 04471 update_name(ch->ast,bc->port,bc->channel); 04472 04473 if (!bc->nt ) { 04474 if ( misdn_cap_is_speech(bc->capability) && 04475 misdn_inband_avail(bc) 04476 ) { 04477 start_bc_tones(ch); 04478 } 04479 04480 ch->state=MISDN_PROGRESS; 04481 04482 if (!ch->ast) break; 04483 ast_queue_control(ch->ast, AST_CONTROL_PROGRESS); 04484 } 04485 break; 04486 04487 04488 case EVENT_ALERTING: 04489 { 04490 if (bc->channel) 04491 update_name(ch->ast,bc->port,bc->channel); 04492 04493 ch->state = MISDN_ALERTING; 04494 04495 if (!ch->ast) break; 04496 04497 ast_queue_control(ch->ast, AST_CONTROL_RINGING); 04498 ast_setstate(ch->ast, AST_STATE_RINGING); 04499 04500 cb_log(7,bc->port," --> Set State Ringing\n"); 04501 04502 if ( misdn_cap_is_speech(bc->capability) && misdn_inband_avail(bc)) { 04503 cb_log(1,bc->port,"Starting Tones, we have inband Data\n"); 04504 start_bc_tones(ch); 04505 } else { 04506 cb_log(3,bc->port," --> We have no inband Data, the other end must create ringing\n"); 04507 if (ch->far_alerting) { 04508 cb_log(1,bc->port," --> The other end can not do ringing eh ?.. we must do all ourself.."); 04509 start_bc_tones(ch); 04510 /*tone_indicate(ch, TONE_FAR_ALERTING);*/ 04511 } 04512 } 04513 } 04514 break; 04515 case EVENT_CONNECT: 04516 { 04517 struct ast_channel *bridged; 04518 /*we answer when we've got our very new L3 ID from the NT stack */ 04519 misdn_lib_send_event(bc,EVENT_CONNECT_ACKNOWLEDGE); 04520 04521 if (!ch->ast) break; 04522 04523 bridged=ast_bridged_channel(ch->ast); 04524 stop_indicate(ch); 04525 04526 if (bridged && !strcasecmp(bridged->tech->type,"mISDN")) { 04527 struct chan_list *bridged_ch=MISDN_ASTERISK_TECH_PVT(bridged); 04528 04529 chan_misdn_log(1,bc->port," --> copying cpndialplan:%d and cad:%s to the A-Channel\n",bc->cpnnumplan,bc->cad); 04530 if (bridged_ch) { 04531 bridged_ch->bc->cpnnumplan=bc->cpnnumplan; 04532 ast_copy_string(bridged_ch->bc->cad,bc->cad,sizeof(bc->cad)); 04533 } 04534 } 04535 } 04536 ch->l3id=bc->l3_id; 04537 ch->addr=bc->addr; 04538 04539 start_bc_tones(ch); 04540 04541 ch->state = MISDN_CONNECTED; 04542 04543 ast_queue_control(ch->ast, AST_CONTROL_ANSWER); 04544 break; 04545 case EVENT_CONNECT_ACKNOWLEDGE: 04546 { 04547 ch->l3id=bc->l3_id; 04548 ch->addr=bc->addr; 04549 04550 start_bc_tones(ch); 04551 04552 ch->state = MISDN_CONNECTED; 04553 } 04554 break; 04555 case EVENT_DISCONNECT: 04556 /*we might not have an ch->ast ptr here anymore*/ 04557 if (ch) { 04558 struct chan_list *holded_ch=find_holded(cl_te, bc); 04559 04560 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); 04561 if ( ch->originator==ORG_AST && !bc->nt && misdn_inband_avail(bc) && ch->state != MISDN_CONNECTED) { 04562 /* If there's inband information available (e.g. a 04563 recorded message saying what was wrong with the 04564 dialled number, or perhaps even giving an 04565 alternative number, then play it instead of 04566 immediately releasing the call */ 04567 chan_misdn_log(1,bc->port, " --> Inband Info Avail, not sending RELEASE\n"); 04568 04569 ch->state=MISDN_DISCONNECTED; 04570 start_bc_tones(ch); 04571 04572 if (ch->ast) { 04573 ch->ast->hangupcause=bc->cause; 04574 if (bc->cause == 17) 04575 ast_queue_control(ch->ast, AST_CONTROL_BUSY); 04576 } 04577 ch->need_busy=0; 04578 break; 04579 } 04580 04581 /*Check for holded channel, to implement transfer*/ 04582 if ( holded_ch && 04583 holded_ch != ch && 04584 ch->ast && 04585 ch->state == MISDN_CONNECTED ) { 04586 cb_log(1,bc->port," --> found holded ch\n"); 04587 misdn_transfer_bc(ch, holded_ch) ; 04588 } 04589 04590 bc->need_disconnect=0; 04591 04592 stop_bc_tones(ch); 04593 hangup_chan(ch); 04594 } else { 04595 /* ch=find_holded_l3(cl_te, bc->l3_id,1); 04596 if (ch) { 04597 hangup_chan(ch); 04598 } 04599 */ 04600 } 04601 bc->out_cause=-1; 04602 if (bc->need_release) misdn_lib_send_event(bc,EVENT_RELEASE); 04603 break; 04604 04605 case EVENT_RELEASE: 04606 { 04607 bc->need_disconnect=0; 04608 bc->need_release=0; 04609 04610 hangup_chan(ch); 04611 release_chan(bc); 04612 } 04613 break; 04614 case EVENT_RELEASE_COMPLETE: 04615 { 04616 bc->need_disconnect=0; 04617 bc->need_release=0; 04618 bc->need_release_complete=0; 04619 04620 stop_bc_tones(ch); 04621 hangup_chan(ch); 04622 04623 if(ch) 04624 ch->state=MISDN_CLEANING; 04625 04626 release_chan(bc); 04627 } 04628 break; 04629 case EVENT_BCHAN_ERROR: 04630 case EVENT_CLEANUP: 04631 { 04632 stop_bc_tones(ch); 04633 04634 switch(ch->state) { 04635 case MISDN_CALLING: 04636 bc->cause=27; /* Destination out of order */ 04637 break; 04638 default: 04639 break; 04640 } 04641 04642 hangup_chan(ch); 04643 release_chan(bc); 04644 } 04645 break; 04646 04647 case EVENT_TONE_GENERATE: 04648 { 04649 int tone_len=bc->tone_cnt; 04650 struct ast_channel *ast=ch->ast; 04651 void *tmp; 04652 int res; 04653 int (*generate)(struct ast_channel *chan, void *tmp, int datalen, int samples); 04654 04655 chan_misdn_log(9,bc->port,"TONE_GEN: len:%d\n"); 04656 04657 if (!ast) break; 04658 04659 if (!ast->generator) break; 04660 04661 04662 04663 tmp = ast->generatordata; 04664 ast->generatordata = NULL; 04665 generate = ast->generator->generate; 04666 04667 if (tone_len <0 || tone_len > 512 ) { 04668 ast_log(LOG_NOTICE, "TONE_GEN: len was %d, set to 128\n",tone_len); 04669 tone_len=128; 04670 } 04671 04672 res = generate(ast, tmp, tone_len, tone_len); 04673 ast->generatordata = tmp; 04674 04675 if (res) { 04676 ast_log(LOG_WARNING, "Auto-deactivating generator\n"); 04677 ast_deactivate_generator(ast); 04678 } else { 04679 bc->tone_cnt=0; 04680 } 04681 } 04682 break; 04683 04684 case EVENT_BCHAN_DATA: 04685 { 04686 if ( !misdn_cap_is_speech(ch->bc->capability) ) { 04687 struct ast_frame frame; 04688 /*In Data Modes we queue frames*/ 04689 frame.frametype = AST_FRAME_VOICE; /*we have no data frames yet*/ 04690 frame.subclass = AST_FORMAT_ALAW; 04691 frame.datalen = bc->bframe_len; 04692 frame.samples = bc->bframe_len ; 04693 frame.mallocd =0 ; 04694 frame.offset= 0 ; 04695 frame.delivery= ast_tv(0,0) ; 04696 frame.src = NULL; 04697 frame.data = bc->bframe ; 04698 04699 if (ch->ast) 04700 ast_queue_frame(ch->ast,&frame); 04701 } else { 04702 int t; 04703 fd_set wrfs; 04704 struct timeval tv; 04705 tv.tv_sec=0; 04706 tv.tv_usec=0; 04707 04708 04709 FD_ZERO(&wrfs); 04710 FD_SET(ch->pipe[1],&wrfs); 04711 04712 t=select(FD_SETSIZE,NULL,&wrfs,NULL,&tv); 04713 04714 if (!t) { 04715 chan_misdn_log(9, bc->port, "Select Timed out\n"); 04716 break; 04717 } 04718 04719 if (t<0) { 04720 chan_misdn_log(-1, bc->port, "Select Error (err=%s)\n",strerror(errno)); 04721 break; 04722 } 04723 04724 if (FD_ISSET(ch->pipe[1],&wrfs)) { 04725 int ret; 04726 chan_misdn_log(9, bc->port, "writing %d bytes 2 asterisk\n",bc->bframe_len); 04727 ret=write(ch->pipe[1], bc->bframe, bc->bframe_len); 04728 04729 if (ret<=0) { 04730 chan_misdn_log(0, bc->port, "Write returned <=0 (err=%s) --> hanging up channel\n",strerror(errno)); 04731 04732 stop_bc_tones(ch); 04733 hangup_chan(ch); 04734 release_chan(bc); 04735 } 04736 } else { 04737 chan_misdn_log(1, bc->port, "Wripe Pipe full!\n"); 04738 } 04739 } 04740 } 04741 break; 04742 case EVENT_TIMEOUT: 04743 { 04744 if (ch && bc) 04745 chan_misdn_log(1,bc->port,"--> state: %s\n",misdn_get_ch_state(ch)); 04746 04747 switch (ch->state) { 04748 case MISDN_DIALING: 04749 case MISDN_PROGRESS: 04750 if (bc->nt && !ch->nttimeout) break; 04751 04752 case MISDN_CALLING: 04753 case MISDN_ALERTING: 04754 case MISDN_PROCEEDING: 04755 case MISDN_CALLING_ACKNOWLEDGE: 04756 if (bc->nt) { 04757 bc->progress_indicator=8; 04758 hanguptone_indicate(ch); 04759 } 04760 04761 bc->out_cause=1; 04762 misdn_lib_send_event(bc,EVENT_DISCONNECT); 04763 break; 04764 04765 case MISDN_WAITING4DIGS: 04766 if (bc->nt) { 04767 bc->progress_indicator=8; 04768 bc->out_cause=1; 04769 hanguptone_indicate(ch); 04770 misdn_lib_send_event(bc,EVENT_DISCONNECT); 04771 } else { 04772 bc->out_cause=16; 04773 misdn_lib_send_event(bc,EVENT_RELEASE); 04774 } 04775 04776 break; 04777 04778 04779 case MISDN_CLEANING: 04780 chan_misdn_log(1,bc->port," --> in state cleaning .. so ingoring, the stack should clean it for us\n"); 04781 break; 04782 04783 default: 04784 misdn_lib_send_event(bc,EVENT_RELEASE_COMPLETE); 04785 } 04786 } 04787 break; 04788 04789 04790 /***************************/ 04791 /** Suplementary Services **/ 04792 /***************************/ 04793 case EVENT_RETRIEVE: 04794 { 04795 struct ast_channel *hold_ast; 04796 if (!ch) { 04797 chan_misdn_log(4, bc->port, " --> no CH, searching in holded\n"); 04798 ch=find_holded_l3(cl_te, bc->l3_id,1); 04799 } 04800 04801 if (!ch) { 04802 ast_log(LOG_WARNING, "Found no Holded channel, cannot Retrieve\n"); 04803 misdn_lib_send_event(bc, EVENT_RETRIEVE_REJECT); 04804 break; 04805 } 04806 04807 /*remember the channel again*/ 04808 ch->bc=bc; 04809 ch->state = MISDN_CONNECTED; 04810 04811 ch->hold_info.port=0; 04812 ch->hold_info.channel=0; 04813 04814 hold_ast=ast_bridged_channel(ch->ast); 04815 04816 if (hold_ast) { 04817 ast_moh_stop(hold_ast); 04818 } 04819 04820 if ( misdn_lib_send_event(bc, EVENT_RETRIEVE_ACKNOWLEDGE) < 0) { 04821 chan_misdn_log(4, bc->port, " --> RETRIEVE_ACK failed\n"); 04822 misdn_lib_send_event(bc, EVENT_RETRIEVE_REJECT); 04823 } 04824 } 04825 break; 04826 04827 case EVENT_HOLD: 04828 { 04829 int hold_allowed; 04830 struct ast_channel *bridged; 04831 misdn_cfg_get( bc->port, MISDN_CFG_HOLD_ALLOWED, &hold_allowed, sizeof(int)); 04832 04833 if (!hold_allowed) { 04834 04835 chan_misdn_log(-1, bc->port, "Hold not allowed this port.\n"); 04836 misdn_lib_send_event(bc, EVENT_HOLD_REJECT); 04837 break; 04838 } 04839 04840 bridged=ast_bridged_channel(ch->ast); 04841 04842 if (bridged) { 04843 chan_misdn_log(2,bc->port,"Bridge Partner is of type: %s\n",bridged->tech->type); 04844 ch->state = MISDN_HOLDED; 04845 ch->l3id = bc->l3_id; 04846 04847 misdn_lib_send_event(bc, EVENT_HOLD_ACKNOWLEDGE); 04848 04849 /* XXX This should queue an AST_CONTROL_HOLD frame on this channel 04850 * instead of starting moh on the bridged channel directly */ 04851 ast_moh_start(bridged, NULL, NULL); 04852 04853 /*forget the channel now*/ 04854 ch->bc=NULL; 04855 ch->hold_info.port=bc->port; 04856 ch->hold_info.channel=bc->channel; 04857 04858 } else { 04859 misdn_lib_send_event(bc, EVENT_HOLD_REJECT); 04860 chan_misdn_log(0, bc->port, "We aren't bridged to anybody\n"); 04861 } 04862 } 04863 break; 04864 04865 case EVENT_FACILITY: 04866 if (!ch) { 04867 /* This may come from a call we don't know nothing about, so we ignore it. */ 04868 chan_misdn_log(-1, bc->port, "Got EVENT_FACILITY but we don't have a ch!\n"); 04869 break; 04870 } 04871 04872 print_facility(&(bc->fac_in), bc); 04873 04874 switch (bc->fac_in.Function) { 04875 case Fac_CD: 04876 { 04877 struct ast_channel *bridged=ast_bridged_channel(ch->ast); 04878 struct chan_list *ch_br; 04879 if (bridged && MISDN_ASTERISK_TECH_PVT(bridged)) { 04880 ch_br=MISDN_ASTERISK_TECH_PVT(bridged); 04881 /*ch->state=MISDN_FACILITY_DEFLECTED;*/ 04882 if (ch_br->bc) { 04883 if (ast_exists_extension(bridged, ch->context, (char *)bc->fac_in.u.CDeflection.DeflectedToNumber, 1, bc->oad)) { 04884 ch_br->state=MISDN_DIALING; 04885 if (pbx_start_chan(ch_br) < 0) { 04886 chan_misdn_log(-1, ch_br->bc->port, "ast_pbx_start returned < 0 in misdn_overlap_dial_task\n"); 04887 } 04888 } 04889 } 04890 04891 } 04892 misdn_lib_send_event(bc, EVENT_DISCONNECT); 04893 } 04894 break; 04895 case Fac_AOCDCurrency: 04896 bc->AOCDtype = Fac_AOCDCurrency; 04897 memcpy(&(bc->AOCD.currency), &(bc->fac_in.u.AOCDcur), sizeof(struct FacAOCDCurrency)); 04898 export_aoc_vars(ch->originator, ch->ast, bc); 04899 break; 04900 case Fac_AOCDChargingUnit: 04901 bc->AOCDtype = Fac_AOCDChargingUnit; 04902 memcpy(&(bc->AOCD.chargingUnit), &(bc->fac_in.u.AOCDchu), sizeof(struct FacAOCDChargingUnit)); 04903 export_aoc_vars(ch->originator, ch->ast, bc); 04904 break; 04905 default: 04906 chan_misdn_log(0, bc->port," --> not yet handled: facility type:%p\n", bc->fac_in.Function); 04907 } 04908 04909 break; 04910 04911 case EVENT_RESTART: 04912 04913 if (!bc->dummy) { 04914 stop_bc_tones(ch); 04915 release_chan(bc); 04916 } 04917 04918 break; 04919 04920 default: 04921 chan_misdn_log(1,0, "Got Unknown Event\n"); 04922 break; 04923 } 04924 04925 return RESPONSE_OK; 04926 }
int chan_misdn_jb_empty | ( | struct misdn_bchannel * | bc, | |
char * | buf, | |||
int | len | |||
) |
Definition at line 5454 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().
05455 { 05456 struct chan_list *ch=find_chan_by_bc(cl_te, bc); 05457 05458 if (ch && ch->jb) { 05459 return misdn_jb_empty(ch->jb, buf, len); 05460 } 05461 05462 return -1; 05463 }
void chan_misdn_log | ( | int | level, | |
int | port, | |||
char * | tmpl, | |||
... | ||||
) | [static] |
Definition at line 5639 of file chan_misdn.c.
References ast_console_puts(), ast_log(), ast_strlen_zero(), errno, global_tracefile, LOG_WARNING, max_ports, misdn_debug, and misdn_debug_only.
Referenced by cb_events(), cl_queue_chan(), config_jitterbuffer(), debug_numplan(), dialtone_indicate(), do_immediate_setup(), export_ch(), find_chan_by_bc(), find_chan_by_pid(), find_holded(), import_ch(), init_chan_list(), load_module(), misdn_answer(), misdn_bridge(), misdn_call(), misdn_check_l2l1(), misdn_digit_end(), misdn_facility_exec(), misdn_fixup(), misdn_hangup(), misdn_indication(), misdn_jb_empty(), misdn_jb_fill(), misdn_jb_init(), misdn_l1_task(), misdn_new(), misdn_overlap_dial_task(), misdn_read(), misdn_request(), misdn_set_opt_exec(), misdn_tasks_destroy(), misdn_tasks_init(), misdn_tasks_thread_func(), misdn_transfer_bc(), misdn_write(), print_bearer(), print_facility(), process_ast_dsp(), read_config(), release_chan(), send_cause2ast(), start_pbx(), stop_indicate(), update_config(), and update_name().
05640 { 05641 va_list ap; 05642 char buf[1024]; 05643 char port_buf[8]; 05644 05645 if (! ((0 <= port) && (port <= max_ports))) { 05646 ast_log(LOG_WARNING, "cb_log called with out-of-range port number! (%d)\n", port); 05647 port=0; 05648 level=-1; 05649 } 05650 05651 sprintf(port_buf,"P[%2d] ",port); 05652 05653 va_start(ap, tmpl); 05654 vsnprintf( buf, 1023, tmpl, ap ); 05655 va_end(ap); 05656 05657 if (level == -1) 05658 ast_log(LOG_WARNING, buf); 05659 05660 else if (misdn_debug_only[port] ? 05661 (level==1 && misdn_debug[port]) || (level==misdn_debug[port]) 05662 : level <= misdn_debug[port]) { 05663 05664 ast_console_puts(port_buf); 05665 ast_console_puts(buf); 05666 } 05667 05668 if ((level <= misdn_debug[0]) && !ast_strlen_zero(global_tracefile) ) { 05669 time_t tm = time(NULL); 05670 char *tmp=ctime(&tm),*p; 05671 05672 FILE *fp= fopen(global_tracefile, "a+"); 05673 05674 p=strchr(tmp,'\n'); 05675 if (p) *p=':'; 05676 05677 if (!fp) { 05678 ast_console_puts("Error opening Tracefile: [ "); 05679 ast_console_puts(global_tracefile); 05680 ast_console_puts(" ] "); 05681 05682 ast_console_puts(strerror(errno)); 05683 ast_console_puts("\n"); 05684 return ; 05685 } 05686 05687 fputs(tmp,fp); 05688 fputs(" ", fp); 05689 fputs(port_buf,fp); 05690 fputs(" ", fp); 05691 fputs(buf, fp); 05692 05693 fclose(fp); 05694 } 05695 }
Definition at line 3499 of file chan_misdn.c.
References ast_dsp_free(), ast_mutex_lock(), ast_mutex_unlock(), ast_translator_free_path(), cl_te_lock, chan_list::dsp, chan_list::next, and chan_list::trans.
Referenced by misdn_hangup(), and release_chan().
03500 { 03501 if (chan->dsp) 03502 ast_dsp_free(chan->dsp); 03503 if (chan->trans) 03504 ast_translator_free_path(chan->trans); 03505 03506 03507 03508 ast_mutex_lock(&cl_te_lock); 03509 if (!*list) { 03510 ast_mutex_unlock(&cl_te_lock); 03511 return; 03512 } 03513 03514 if (*list == chan) { 03515 *list=(*list)->next; 03516 ast_mutex_unlock(&cl_te_lock); 03517 return ; 03518 } 03519 03520 { 03521 struct chan_list *help=*list; 03522 for (;help->next; help=help->next) { 03523 if (help->next == chan) { 03524 help->next=help->next->next; 03525 ast_mutex_unlock(&cl_te_lock); 03526 return; 03527 } 03528 } 03529 } 03530 03531 ast_mutex_unlock(&cl_te_lock); 03532 }
Definition at line 3483 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().
03484 { 03485 chan_misdn_log(4, chan->bc? chan->bc->port : 0, "* Queuing chan %p\n",chan); 03486 03487 ast_mutex_lock(&cl_te_lock); 03488 if (!*list) { 03489 *list = chan; 03490 } else { 03491 struct chan_list *help=*list; 03492 for (;help->next; help=help->next); 03493 help->next=chan; 03494 } 03495 chan->next=NULL; 03496 ast_mutex_unlock(&cl_te_lock); 03497 }
static char* complete_ch | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 1440 of file chan_misdn.c.
References complete_ch_helper().
01441 { 01442 return complete_ch_helper(line, word, pos, state, 3); 01443 }
static char* complete_ch_helper | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state, | |||
int | rpos | |||
) | [static] |
Definition at line 1416 of file chan_misdn.c.
References ast_channel_walk_locked(), ast_mutex_unlock(), ast_channel::lock, and strdup.
Referenced by complete_ch().
01417 { 01418 struct ast_channel *c; 01419 int which=0; 01420 char *ret; 01421 if (pos != rpos) 01422 return NULL; 01423 c = ast_channel_walk_locked(NULL); 01424 while(c) { 01425 if (!strncasecmp(word, c->name, strlen(word))) { 01426 if (++which > state) 01427 break; 01428 } 01429 ast_mutex_unlock(&c->lock); 01430 c = ast_channel_walk_locked(c); 01431 } 01432 if (c) { 01433 ret = strdup(c->name); 01434 ast_mutex_unlock(&c->lock); 01435 } else 01436 ret = NULL; 01437 return ret; 01438 }
static char* complete_debug_port | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 1445 of file chan_misdn.c.
References strdup.
01446 { 01447 if (state) 01448 return NULL; 01449 01450 switch (pos) { 01451 case 4: if (*word == 'p') 01452 return strdup("port"); 01453 else if (*word == 'o') 01454 return strdup("only"); 01455 break; 01456 case 6: if (*word == 'o') 01457 return strdup("only"); 01458 break; 01459 } 01460 return NULL; 01461 }
static char* complete_show_config | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 1463 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.
01464 { 01465 char buffer[BUFFERSIZE]; 01466 enum misdn_cfg_elements elem; 01467 int wordlen = strlen(word); 01468 int which = 0; 01469 int port = 0; 01470 01471 switch (pos) { 01472 case 3: if ((!strncmp(word, "description", wordlen)) && (++which > state)) 01473 return strdup("description"); 01474 if ((!strncmp(word, "descriptions", wordlen)) && (++which > state)) 01475 return strdup("descriptions"); 01476 if ((!strncmp(word, "0", wordlen)) && (++which > state)) 01477 return strdup("0"); 01478 while ((port = misdn_cfg_get_next_port(port)) != -1) { 01479 snprintf(buffer, sizeof(buffer), "%d", port); 01480 if ((!strncmp(word, buffer, wordlen)) && (++which > state)) { 01481 return strdup(buffer); 01482 } 01483 } 01484 break; 01485 case 4: 01486 if (strstr(line, "description ")) { 01487 for (elem = MISDN_CFG_FIRST + 1; elem < MISDN_GEN_LAST; ++elem) { 01488 if ((elem == MISDN_CFG_LAST) || (elem == MISDN_GEN_FIRST)) 01489 continue; 01490 misdn_cfg_get_name(elem, buffer, BUFFERSIZE); 01491 if (!wordlen || !strncmp(word, buffer, wordlen)) { 01492 if (++which > state) 01493 return strdup(buffer); 01494 } 01495 } 01496 } else if (strstr(line, "descriptions ")) { 01497 if ((!wordlen || !strncmp(word, "general", wordlen)) && (++which > state)) 01498 return strdup("general"); 01499 if ((!wordlen || !strncmp(word, "ports", wordlen)) && (++which > state)) 01500 return strdup("ports"); 01501 } 01502 break; 01503 } 01504 return NULL; 01505 }
static void config_jitterbuffer | ( | struct chan_list * | ch | ) | [static] |
Definition at line 1660 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().
01661 { 01662 struct misdn_bchannel *bc=ch->bc; 01663 int len=ch->jb_len, threshold=ch->jb_upper_threshold; 01664 01665 chan_misdn_log(5,bc->port, "config_jb: Called\n"); 01666 01667 if ( ! len ) { 01668 chan_misdn_log(1,bc->port, "config_jb: Deactivating Jitterbuffer\n"); 01669 bc->nojitter=1; 01670 } else { 01671 01672 if (len <=100 || len > 8000) { 01673 chan_misdn_log(0,bc->port,"config_jb: Jitterbuffer out of Bounds, setting to 1000\n"); 01674 len=1000; 01675 } 01676 01677 if ( threshold > len ) { 01678 chan_misdn_log(0,bc->port,"config_jb: Jitterbuffer Threshold > Jitterbuffer setting to Jitterbuffer -1\n"); 01679 } 01680 01681 if ( ch->jb) { 01682 cb_log(0,bc->port,"config_jb: We've got a Jitterbuffer Already on this port.\n"); 01683 misdn_jb_destroy(ch->jb); 01684 ch->jb=NULL; 01685 } 01686 01687 ch->jb=misdn_jb_init(len, threshold); 01688 01689 if (!ch->jb ) 01690 bc->nojitter=1; 01691 } 01692 }
void debug_numplan | ( | int | port, | |
int | numplan, | |||
char * | type | |||
) |
Definition at line 1695 of file chan_misdn.c.
References chan_misdn_log(), NUMPLAN_INTERNATIONAL, NUMPLAN_NATIONAL, NUMPLAN_SUBSCRIBER, and NUMPLAN_UNKNOWN.
Referenced by read_config().
01696 { 01697 switch (numplan) { 01698 case NUMPLAN_INTERNATIONAL: 01699 chan_misdn_log(2, port, " --> %s: International\n",type); 01700 break; 01701 case NUMPLAN_NATIONAL: 01702 chan_misdn_log(2, port, " --> %s: National\n",type); 01703 break; 01704 case NUMPLAN_SUBSCRIBER: 01705 chan_misdn_log(2, port, " --> %s: Subscriber\n",type); 01706 break; 01707 case NUMPLAN_UNKNOWN: 01708 chan_misdn_log(2, port, " --> %s: Unknown\n",type); 01709 break; 01710 /* Maybe we should cut off the prefix if present ? */ 01711 default: 01712 chan_misdn_log(0, port, " --> !!!! Wrong dialplan setting, please see the misdn.conf sample file\n "); 01713 break; 01714 } 01715 }
static int dialtone_indicate | ( | struct chan_list * | cl | ) | [static] |
AST INDICATIONS END
Definition at line 2991 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().
02992 { 02993 const struct tone_zone_sound *ts= NULL; 02994 struct ast_channel *ast=cl->ast; 02995 int nd=0; 02996 02997 if (!ast) { 02998 chan_misdn_log(0,cl->bc->port,"No Ast in dialtone_indicate\n"); 02999 return -1; 03000 } 03001 03002 misdn_cfg_get( cl->bc->port, MISDN_CFG_NODIALTONE, &nd, sizeof(nd)); 03003 03004 if (nd) { 03005 chan_misdn_log(1,cl->bc->port,"Not sending Dialtone, because config wants it\n"); 03006 return 0; 03007 } 03008 03009 chan_misdn_log(3,cl->bc->port," --> Dial\n"); 03010 ts=ast_get_indication_tone(ast->zone,"dial"); 03011 cl->ts=ts; 03012 03013 if (ts) { 03014 cl->notxtone=0; 03015 cl->norxtone=0; 03016 /* This prods us in misdn_write */ 03017 ast_playtones_start(ast,0, ts->data, 0); 03018 } 03019 03020 return 0; 03021 }
static void do_immediate_setup | ( | struct misdn_bchannel * | bc, | |
struct chan_list * | ch, | |||
struct ast_channel * | ast | |||
) | [static] |
Definition at line 3673 of file chan_misdn.c.
References chan_list::ast, AST_FRAME_DTMF, ast_queue_frame(), ast_strlen_zero(), chan_misdn_log(), ast_channel::cid, ast_callerid::cid_num, ast_channel::context, ast_frame::data, ast_frame::datalen, ast_frame::delivery, EVENT_DISCONNECT, EVENT_PROCEEDING, EVENT_RELEASE_COMPLETE, EVENT_SETUP_ACKNOWLEDGE, ast_channel::exten, ast_frame::frametype, hangup_chan(), hanguptone_indicate(), ast_frame::mallocd, MISDN_ASTERISK_PVT, MISDN_ASTERISK_TECH_PVT, MISDN_DIALING, MISDN_INCOMING_SETUP, misdn_lib_is_ptp(), misdn_lib_send_event(), chan_list::noautorespond_on_setup, misdn_bchannel::nt, ast_frame::offset, pbx_start_chan(), misdn_bchannel::port, ast_frame::samples, ast_frame::src, chan_list::state, and ast_frame::subclass.
03674 { 03675 char predial[256]=""; 03676 char *p = predial; 03677 03678 struct ast_frame fr; 03679 03680 strncpy(predial, ast->exten, sizeof(predial) -1 ); 03681 03682 ch->state=MISDN_DIALING; 03683 03684 if (!ch->noautorespond_on_setup) { 03685 if (bc->nt) { 03686 int ret; 03687 ret = misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE ); 03688 } else { 03689 int ret; 03690 if ( misdn_lib_is_ptp(bc->port)) { 03691 ret = misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE ); 03692 } else { 03693 ret = misdn_lib_send_event(bc, EVENT_PROCEEDING ); 03694 } 03695 } 03696 } else { 03697 ch->state = MISDN_INCOMING_SETUP; 03698 } 03699 03700 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); 03701 03702 strncpy(ast->exten,"s", 2); 03703 03704 if (pbx_start_chan(ch)<0) { 03705 ast=NULL; 03706 hangup_chan(ch); 03707 hanguptone_indicate(ch); 03708 03709 if (bc->nt) 03710 misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE ); 03711 else 03712 misdn_lib_send_event(bc, EVENT_DISCONNECT ); 03713 } 03714 03715 03716 while (!ast_strlen_zero(p) ) { 03717 fr.frametype = AST_FRAME_DTMF; 03718 fr.subclass = *p ; 03719 fr.src=NULL; 03720 fr.data = NULL ; 03721 fr.datalen = 0; 03722 fr.samples = 0 ; 03723 fr.mallocd =0 ; 03724 fr.offset= 0 ; 03725 fr.delivery= ast_tv(0,0) ; 03726 03727 if (ch->ast && MISDN_ASTERISK_PVT(ch->ast) && MISDN_ASTERISK_TECH_PVT(ch->ast)) { 03728 ast_queue_frame(ch->ast, &fr); 03729 } 03730 p++; 03731 } 03732 }
static void export_aoc_vars | ( | int | originator, | |
struct ast_channel * | ast, | |||
struct misdn_bchannel * | bc | |||
) | [static] |
Definition at line 498 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().
00499 { 00500 char buf[128]; 00501 00502 if (!ast) 00503 return; 00504 00505 if (originator == ORG_AST) { 00506 ast = ast_bridged_channel(ast); 00507 if (!ast) 00508 return; 00509 } 00510 00511 switch (bc->AOCDtype) { 00512 case Fac_AOCDCurrency: 00513 pbx_builtin_setvar_helper(ast, "AOCD_Type", "currency"); 00514 if (bc->AOCD.currency.chargeNotAvailable) 00515 pbx_builtin_setvar_helper(ast, "AOCD_ChargeAvailable", "no"); 00516 else { 00517 pbx_builtin_setvar_helper(ast, "AOCD_ChargeAvailable", "yes"); 00518 if (bc->AOCD.currency.freeOfCharge) 00519 pbx_builtin_setvar_helper(ast, "AOCD_FreeOfCharge", "yes"); 00520 else { 00521 pbx_builtin_setvar_helper(ast, "AOCD_FreeOfCharge", "no"); 00522 if (snprintf(buf, sizeof(buf), "%d %s", bc->AOCD.currency.currencyAmount * bc->AOCD.currency.multiplier, bc->AOCD.currency.currency) < sizeof(buf)) { 00523 pbx_builtin_setvar_helper(ast, "AOCD_Amount", buf); 00524 if (bc->AOCD.currency.billingId >= 0 && snprintf(buf, sizeof(buf), "%d", bc->AOCD.currency.billingId) < sizeof(buf)) 00525 pbx_builtin_setvar_helper(ast, "AOCD_BillingId", buf); 00526 } 00527 } 00528 } 00529 break; 00530 case Fac_AOCDChargingUnit: 00531 pbx_builtin_setvar_helper(ast, "AOCD_Type", "charging_unit"); 00532 if (bc->AOCD.chargingUnit.chargeNotAvailable) 00533 pbx_builtin_setvar_helper(ast, "AOCD_ChargeAvailable", "no"); 00534 else { 00535 pbx_builtin_setvar_helper(ast, "AOCD_ChargeAvailable", "yes"); 00536 if (bc->AOCD.chargingUnit.freeOfCharge) 00537 pbx_builtin_setvar_helper(ast, "AOCD_FreeOfCharge", "yes"); 00538 else { 00539 pbx_builtin_setvar_helper(ast, "AOCD_FreeOfCharge", "no"); 00540 if (snprintf(buf, sizeof(buf), "%d", bc->AOCD.chargingUnit.recordedUnits) < sizeof(buf)) { 00541 pbx_builtin_setvar_helper(ast, "AOCD_RecordedUnits", buf); 00542 if (bc->AOCD.chargingUnit.billingId >= 0 && snprintf(buf, sizeof(buf), "%d", bc->AOCD.chargingUnit.billingId) < sizeof(buf)) 00543 pbx_builtin_setvar_helper(ast, "AOCD_BillingId", buf); 00544 } 00545 } 00546 } 00547 break; 00548 default: 00549 break; 00550 } 00551 }
void export_ch | ( | struct ast_channel * | chan, | |
struct misdn_bchannel * | bc, | |||
struct chan_list * | ch | |||
) |
Definition at line 3828 of file chan_misdn.c.
References 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().
03829 { 03830 char tmp[32]; 03831 chan_misdn_log(3,bc->port," --> EXPORT_PID: pid:%d\n",bc->pid); 03832 sprintf(tmp,"%d",bc->pid); 03833 pbx_builtin_setvar_helper(chan,"_MISDN_PID",tmp); 03834 03835 if (bc->sending_complete) { 03836 sprintf(tmp,"%d",bc->sending_complete); 03837 pbx_builtin_setvar_helper(chan,"MISDN_ADDRESS_COMPLETE",tmp); 03838 } 03839 03840 if (bc->urate) { 03841 sprintf(tmp,"%d",bc->urate); 03842 pbx_builtin_setvar_helper(chan,"MISDN_URATE",tmp); 03843 } 03844 03845 if (bc->uulen && (bc->uulen < sizeof(bc->uu))) { 03846 bc->uu[bc->uulen]=0; 03847 pbx_builtin_setvar_helper(chan,"MISDN_USERUSER",bc->uu); 03848 } 03849 03850 if (bc->keypad[0]) 03851 pbx_builtin_setvar_helper(chan,"MISDN_KEYPAD",bc->keypad); 03852 }
static struct chan_list * find_chan_by_bc | ( | struct chan_list * | list, | |
struct misdn_bchannel * | bc | |||
) | [static] |
Definition at line 3425 of file chan_misdn.c.
References chan_list::bc, chan_misdn_log(), misdn_bchannel::dad, chan_list::next, misdn_bchannel::oad, and misdn_bchannel::port.
Referenced by cb_events(), chan_misdn_jb_empty(), and release_chan().
03426 { 03427 struct chan_list *help=list; 03428 for (;help; help=help->next) { 03429 if (help->bc == bc) return help; 03430 } 03431 03432 chan_misdn_log(6, bc->port, "$$$ find_chan: No channel found for oad:%s dad:%s\n",bc->oad,bc->dad); 03433 03434 return NULL; 03435 }
Definition at line 3437 of file chan_misdn.c.
References chan_list::bc, chan_misdn_log(), chan_list::next, and misdn_bchannel::pid.
Referenced by import_ch().
03438 { 03439 struct chan_list *help=list; 03440 for (;help; help=help->next) { 03441 if ( help->bc && (help->bc->pid == pid) ) return help; 03442 } 03443 03444 chan_misdn_log(6, 0, "$$$ find_chan: No channel found for pid:%d\n",pid); 03445 03446 return NULL; 03447 }
static struct chan_list* find_holded | ( | struct chan_list * | list, | |
struct misdn_bchannel * | bc | |||
) | [static] |
Definition at line 3449 of file chan_misdn.c.
References chan_list::bc, chan_misdn_log(), hold_info::channel, misdn_bchannel::channel, misdn_bchannel::dad, chan_list::hold_info, MISDN_HOLDED, chan_list::next, misdn_bchannel::oad, hold_info::port, misdn_bchannel::port, misdn_bchannel::pri, and chan_list::state.
Referenced by cb_events().
03450 { 03451 struct chan_list *help=list; 03452 03453 if (bc->pri) return NULL; 03454 03455 chan_misdn_log(6, bc->port, "$$$ find_holded: channel:%d oad:%s dad:%s\n",bc->channel, bc->oad,bc->dad); 03456 for (;help; help=help->next) { 03457 chan_misdn_log(4, bc->port, "$$$ find_holded: --> holded:%d channel:%d\n",help->state==MISDN_HOLDED, help->hold_info.channel); 03458 if ( (help->state == MISDN_HOLDED) && 03459 (help->hold_info.port == bc->port) ) 03460 return help; 03461 } 03462 chan_misdn_log(6, bc->port, "$$$ find_chan: No channel found for oad:%s dad:%s\n",bc->oad,bc->dad); 03463 03464 return NULL; 03465 }
static struct chan_list* find_holded_l3 | ( | struct chan_list * | list, | |
unsigned long | l3_id, | |||
int | w | |||
) | [static] |
Definition at line 3468 of file chan_misdn.c.
References chan_list::l3id, MISDN_HOLDED, chan_list::next, and chan_list::state.
03470 { 03471 struct chan_list *help=list; 03472 03473 for (;help; help=help->next) { 03474 if ( (help->state == MISDN_HOLDED) && 03475 (help->l3id == l3_id) 03476 ) 03477 return help; 03478 } 03479 03480 return NULL; 03481 }
static void free_robin_list | ( | void | ) | [static] |
Definition at line 257 of file chan_misdn.c.
References free_robin_list_r(), and robin.
Referenced by reload_config(), and unload_module().
00258 { 00259 free_robin_list_r(robin); 00260 robin = NULL; 00261 }
static void free_robin_list_r | ( | struct robin_list * | r | ) | [inline, static] |
Definition at line 248 of file chan_misdn.c.
References free, robin_list::group, and robin_list::next.
Referenced by free_robin_list().
00249 { 00250 if (r) { 00251 if (r->next) free_robin_list_r(r->next); 00252 if (r->group) free(r->group); 00253 free(r); 00254 } 00255 }
static struct chan_list* get_chan_by_ast | ( | struct ast_channel * | ast | ) | [static] |
Definition at line 374 of file chan_misdn.c.
References chan_list::ast, cl_te, and chan_list::next.
Referenced by misdn_bridge().
00375 { 00376 struct chan_list *tmp; 00377 00378 for (tmp=cl_te; tmp; tmp = tmp->next) { 00379 if ( tmp->ast == ast ) return tmp; 00380 } 00381 00382 return NULL; 00383 }
static struct chan_list* get_chan_by_ast_name | ( | char * | name | ) | [static] |
Definition at line 385 of file chan_misdn.c.
References chan_list::ast, cl_te, and chan_list::next.
Referenced by misdn_send_cd(), misdn_send_digit(), misdn_send_display(), and misdn_toggle_echocancel().
00386 { 00387 struct chan_list *tmp; 00388 00389 for (tmp=cl_te; tmp; tmp = tmp->next) { 00390 if ( tmp->ast && strcmp(tmp->ast->name,name) == 0) return tmp; 00391 } 00392 00393 return NULL; 00394 }
static struct robin_list* get_robin_position | ( | char * | group | ) | [static] |
Definition at line 263 of file chan_misdn.c.
References calloc, robin_list::group, robin_list::next, robin_list::prev, robin, and strndup.
Referenced by misdn_request().
00264 { 00265 struct robin_list *new; 00266 struct robin_list *iter = robin; 00267 for (; iter; iter = iter->next) { 00268 if (!strcasecmp(iter->group, group)) 00269 return iter; 00270 } 00271 new = (struct robin_list *)calloc(1, sizeof(struct robin_list)); 00272 new->group = strndup(group, strlen(group)); 00273 new->port = 0; 00274 new->channel = 0; 00275 if (robin) { 00276 new->next = robin; 00277 robin->prev = new; 00278 } 00279 robin = new; 00280 return robin; 00281 }
static void hangup_chan | ( | struct chan_list * | ch | ) | [static] |
Definition at line 3549 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().
03550 { 03551 int port=ch?ch->bc?ch->bc->port:0:0; 03552 if (!ch) { 03553 cb_log(1,0,"Cannot hangup chan, no ch\n"); 03554 return; 03555 } 03556 03557 cb_log(5,port,"hangup_chan called\n"); 03558 03559 if (ch->need_hangup) 03560 { 03561 cb_log(2,port," --> hangup\n"); 03562 send_cause2ast(ch->ast,ch->bc,ch); 03563 ch->need_hangup=0; 03564 ch->need_queue_hangup=0; 03565 if (ch->ast) 03566 ast_hangup(ch->ast); 03567 return; 03568 } 03569 03570 if (!ch->need_queue_hangup) { 03571 cb_log(2,port," --> No need to queue hangup\n"); 03572 } 03573 03574 ch->need_queue_hangup=0; 03575 if (ch->ast) { 03576 send_cause2ast(ch->ast,ch->bc,ch); 03577 03578 if (ch->ast) 03579 ast_queue_hangup(ch->ast); 03580 cb_log(2,port," --> queue_hangup\n"); 03581 } else { 03582 cb_log(1,port,"Cannot hangup chan, no ast\n"); 03583 } 03584 }
static int hanguptone_indicate | ( | struct chan_list * | cl | ) | [static] |
Definition at line 3023 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().
03024 { 03025 misdn_lib_send_tone(cl->bc,TONE_HANGUP); 03026 return 0; 03027 }
void import_ch | ( | struct ast_channel * | chan, | |
struct misdn_bchannel * | bc, | |||
struct chan_list * | ch | |||
) |
Definition at line 3794 of file chan_misdn.c.
References 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().
03795 { 03796 const char *tmp; 03797 tmp=pbx_builtin_getvar_helper(chan,"MISDN_PID"); 03798 if (tmp) { 03799 ch->other_pid=atoi(tmp); 03800 chan_misdn_log(3,bc->port," --> IMPORT_PID: importing pid:%s\n",tmp); 03801 if (ch->other_pid >0) { 03802 ch->other_ch=find_chan_by_pid(cl_te,ch->other_pid); 03803 if (ch->other_ch) ch->other_ch->other_ch=ch; 03804 } 03805 } 03806 03807 tmp=pbx_builtin_getvar_helper(chan,"MISDN_ADDRESS_COMPLETE"); 03808 if (tmp && (atoi(tmp) == 1)) { 03809 bc->sending_complete=1; 03810 } 03811 03812 tmp=pbx_builtin_getvar_helper(chan,"MISDN_USERUSER"); 03813 if (tmp) { 03814 ast_log(LOG_NOTICE, "MISDN_USERUSER: %s\n", tmp); 03815 strcpy(bc->uu, tmp); 03816 bc->uulen=strlen(bc->uu); 03817 } 03818 03819 tmp=pbx_builtin_getvar_helper(chan,"MISDN_KEYPAD"); 03820 if (tmp) { 03821 strncpy(bc->keypad,tmp,sizeof(bc->keypad)); 03822 bc->keypad[sizeof(bc->keypad)-1]=0; 03823 } 03824 03825 03826 }
static struct chan_list* init_chan_list | ( | int | orig | ) | [static] |
Definition at line 3068 of file chan_misdn.c.
References chan_misdn_log(), malloc, chan_list::need_busy, chan_list::need_hangup, chan_list::need_queue_hangup, chan_list::originator, and chan_list::overlap_dial_task.
Referenced by cb_events(), and misdn_request().
03069 { 03070 struct chan_list *cl=malloc(sizeof(struct chan_list)); 03071 03072 if (!cl) { 03073 chan_misdn_log(-1, 0, "misdn_request: malloc failed!"); 03074 return NULL; 03075 } 03076 03077 memset(cl,0,sizeof(struct chan_list)); 03078 03079 cl->originator=orig; 03080 cl->need_queue_hangup=1; 03081 cl->need_hangup=1; 03082 cl->need_busy=1; 03083 cl->overlap_dial_task=-1; 03084 03085 return cl; 03086 03087 }
static int load_module | ( | void | ) | [static] |
Definition at line 4971 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(), BUFFERSIZE, calloc, misdn_lib_iface::cb_event, cb_events(), chan_misdn_clis, chan_misdn_jb_empty(), chan_misdn_log(), cl_te_lock, g_config_initialized, global_tracefile, LOG_ERROR, malloc, max_ports, misdn_cfg_get(), misdn_cfg_get_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_ports, misdn_set_opt_exec(), misdn_tasks_add(), misdn_tech, misdn_type, release_lock, tracing, and unload_module().
04972 { 04973 int i, port; 04974 04975 char ports[256]=""; 04976 04977 max_ports=misdn_lib_maxports_get(); 04978 04979 if (max_ports<=0) { 04980 ast_log(LOG_ERROR, "Unable to initialize mISDN\n"); 04981 return AST_MODULE_LOAD_DECLINE; 04982 } 04983 04984 if (misdn_cfg_init(max_ports)) { 04985 ast_log(LOG_ERROR, "Unable to initialize misdn_config.\n"); 04986 return AST_MODULE_LOAD_DECLINE; 04987 } 04988 g_config_initialized=1; 04989 04990 misdn_debug = (int *)malloc(sizeof(int) * (max_ports+1)); 04991 misdn_ports = (int *)malloc(sizeof(int) * (max_ports+1)); 04992 misdn_cfg_get( 0, MISDN_GEN_DEBUG, &misdn_debug[0], sizeof(int)); 04993 for (i = 1; i <= max_ports; i++) { 04994 misdn_debug[i] = misdn_debug[0]; 04995 misdn_ports[i] = i; 04996 } 04997 *misdn_ports = 0; 04998 misdn_debug_only = (int *)calloc(max_ports + 1, sizeof(int)); 04999 05000 { 05001 char tempbuf[BUFFERSIZE+1]; 05002 misdn_cfg_get( 0, MISDN_GEN_TRACEFILE, tempbuf, BUFFERSIZE); 05003 if (strlen(tempbuf)) 05004 tracing = 1; 05005 } 05006 05007 misdn_in_calls = (int *)malloc(sizeof(int) * (max_ports+1)); 05008 misdn_out_calls = (int *)malloc(sizeof(int) * (max_ports+1)); 05009 05010 for (i=1; i <= max_ports; i++) { 05011 misdn_in_calls[i]=0; 05012 misdn_out_calls[i]=0; 05013 } 05014 05015 ast_mutex_init(&cl_te_lock); 05016 ast_mutex_init(&release_lock); 05017 05018 misdn_cfg_update_ptp(); 05019 misdn_cfg_get_ports_string(ports); 05020 05021 if (strlen(ports)) 05022 chan_misdn_log(0, 0, "Got: %s from get_ports\n",ports); 05023 05024 { 05025 int ntflags=0, ntkc=0; 05026 char ntfile[BUFFERSIZE+1]; 05027 struct misdn_lib_iface iface = { 05028 .cb_event = cb_events, 05029 .cb_log = chan_misdn_log, 05030 .cb_jb_empty = chan_misdn_jb_empty, 05031 }; 05032 05033 if (misdn_lib_init(ports, &iface, NULL)) 05034 chan_misdn_log(0, 0, "No te ports initialized\n"); 05035 05036 misdn_cfg_get( 0, MISDN_GEN_NTDEBUGFLAGS, &ntflags, sizeof(int)); 05037 misdn_cfg_get( 0, MISDN_GEN_NTDEBUGFILE, &ntfile, BUFFERSIZE); 05038 misdn_lib_nt_debug_init(ntflags,ntfile); 05039 05040 misdn_cfg_get( 0, MISDN_GEN_NTKEEPCALLS, &ntkc, sizeof(int)); 05041 misdn_lib_nt_keepcalls(ntkc); 05042 } 05043 05044 { 05045 if (ast_channel_register(&misdn_tech)) { 05046 ast_log(LOG_ERROR, "Unable to register channel class %s\n", misdn_type); 05047 unload_module(); 05048 return -1; 05049 } 05050 } 05051 05052 ast_cli_register_multiple(chan_misdn_clis, sizeof(chan_misdn_clis) / sizeof(struct ast_cli_entry)); 05053 05054 ast_register_application("misdn_set_opt", misdn_set_opt_exec, "misdn_set_opt", 05055 "misdn_set_opt(:<opt><optarg>:<opt><optarg>..):\n" 05056 "Sets mISDN opts. and optargs\n" 05057 "\n" 05058 "The available options are:\n" 05059 " d - Send display text on called phone, text is the optparam\n" 05060 " n - don't detect dtmf tones on called channel\n" 05061 " h - make digital outgoing call\n" 05062 " c - make crypted outgoing call, param is keyindex\n" 05063 " e - perform echo cancelation on this channel,\n" 05064 " takes taps as arguments (32,64,128,256)\n" 05065 " s - send Non Inband DTMF as inband\n" 05066 " vr - rxgain control\n" 05067 " vt - txgain control\n" 05068 " i - Ignore detected dtmf tones, don't signal them to asterisk, they will be transported inband.\n" 05069 ); 05070 05071 05072 ast_register_application("misdn_facility", misdn_facility_exec, "misdn_facility", 05073 "misdn_facility(<FACILITY_TYPE>|<ARG1>|..)\n" 05074 "Sends the Facility Message FACILITY_TYPE with \n" 05075 "the given Arguments to the current ISDN Channel\n" 05076 "Supported Facilities are:\n" 05077 "\n" 05078 "type=calldeflect args=Nr where to deflect\n" 05079 ); 05080 05081 05082 ast_register_application("misdn_check_l2l1", misdn_check_l2l1, "misdn_check_l2l1", 05083 "misdn_check_l2l1(<port>||g:<groupname>,timeout)" 05084 "Checks if the L2 and L1 are up on either the given <port> or\n" 05085 "on the ports in the group with <groupname>\n" 05086 "If the L1/L2 are down, check_l2l1 gets up the L1/L2 and waits\n" 05087 "for <timeout> seconds that this happens. Otherwise, nothing happens\n" 05088 "\n" 05089 "This application, ensures the L1/L2 state of the Ports in a group\n" 05090 "it is intended to make the pmp_l1_check option redundant and to\n" 05091 "fix a buggy switch config from your provider\n" 05092 "\n" 05093 "a sample dialplan would look like:\n\n" 05094 "exten => _X.,1,misdn_check_l2l1(g:out|2)\n" 05095 "exten => _X.,n,dial(mISDN/g:out/${EXTEN})\n" 05096 "\n" 05097 ); 05098 05099 05100 misdn_cfg_get( 0, MISDN_GEN_TRACEFILE, global_tracefile, BUFFERSIZE); 05101 05102 /* start the l1 watchers */ 05103 05104 for (port = misdn_cfg_get_next_port(0); port >= 0; port = misdn_cfg_get_next_port(port)) { 05105 int l1timeout; 05106 misdn_cfg_get(port, MISDN_CFG_L1_TIMEOUT, &l1timeout, sizeof(l1timeout)); 05107 if (l1timeout) { 05108 chan_misdn_log(4, 0, "Adding L1watcher task: port:%d timeout:%ds\n", port, l1timeout); 05109 misdn_tasks_add(l1timeout * 1000, misdn_l1_task, &misdn_ports[port]); 05110 } 05111 } 05112 05113 chan_misdn_log(0, 0, "-- mISDN Channel Driver Registered --\n"); 05114 05115 return 0; 05116 }
static int misdn_answer | ( | struct ast_channel * | ast | ) | [static] |
Definition at line 2156 of file chan_misdn.c.
References chan_list::ast, ast_log(), ast_queue_hangup(), ast_strlen_zero(), 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().
02157 { 02158 struct chan_list *p; 02159 02160 02161 if (!ast || ! (p=MISDN_ASTERISK_TECH_PVT(ast)) ) return -1; 02162 02163 chan_misdn_log(1, p? (p->bc? p->bc->port : 0) : 0, "* ANSWER:\n"); 02164 02165 if (!p) { 02166 ast_log(LOG_WARNING, " --> Channel not connected ??\n"); 02167 ast_queue_hangup(ast); 02168 } 02169 02170 if (!p->bc) { 02171 chan_misdn_log(1, 0, " --> Got Answer, but theres no bc obj ??\n"); 02172 02173 ast_queue_hangup(ast); 02174 } 02175 02176 { 02177 const char *tmp_key = pbx_builtin_getvar_helper(p->ast, "CRYPT_KEY"); 02178 02179 if (tmp_key ) { 02180 chan_misdn_log(1, p->bc->port, " --> Connection will be BF crypted\n"); 02181 { 02182 int l = sizeof(p->bc->crypt_key); 02183 strncpy(p->bc->crypt_key,tmp_key, l); 02184 p->bc->crypt_key[l-1] = 0; 02185 } 02186 } else { 02187 chan_misdn_log(3, p->bc->port, " --> Connection is without BF encryption\n"); 02188 } 02189 02190 } 02191 02192 { 02193 const char *nodsp=pbx_builtin_getvar_helper(ast, "MISDN_DIGITAL_TRANS"); 02194 if (nodsp) { 02195 chan_misdn_log(1, p->bc->port, " --> Connection is transparent digital\n"); 02196 p->bc->nodsp=1; 02197 p->bc->hdlc=0; 02198 p->bc->nojitter=1; 02199 } 02200 } 02201 02202 p->state = MISDN_CONNECTED; 02203 stop_indicate(p); 02204 02205 if ( ast_strlen_zero(p->bc->cad) ) { 02206 chan_misdn_log(2,p->bc->port," --> empty cad using dad\n"); 02207 ast_copy_string(p->bc->cad,p->bc->dad,sizeof(p->bc->cad)); 02208 } 02209 02210 misdn_lib_send_event( p->bc, EVENT_CONNECT); 02211 start_bc_tones(p); 02212 02213 return 0; 02214 }
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 2882 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(), misdn_bchannel::oad, option_verbose, misdn_bchannel::pid, misdn_bchannel::port, and VERBOSE_PREFIX_3.
02888 { 02889 struct chan_list *ch1,*ch2; 02890 struct ast_channel *carr[2], *who; 02891 int to=-1; 02892 struct ast_frame *f; 02893 int p1_b, p2_b; 02894 int bridging; 02895 02896 ch1=get_chan_by_ast(c0); 02897 ch2=get_chan_by_ast(c1); 02898 02899 carr[0]=c0; 02900 carr[1]=c1; 02901 02902 if (ch1 && ch2 ) ; 02903 else 02904 return -1; 02905 02906 misdn_cfg_get(ch1->bc->port, MISDN_CFG_BRIDGING, &p1_b, sizeof(int)); 02907 misdn_cfg_get(ch2->bc->port, MISDN_CFG_BRIDGING, &p2_b, sizeof(int)); 02908 02909 if ( ! p1_b || ! p2_b) { 02910 ast_log(LOG_NOTICE, "Falling back to Asterisk bridging\n"); 02911 return AST_BRIDGE_FAILED; 02912 } 02913 02914 misdn_cfg_get( 0, MISDN_GEN_BRIDGING, &bridging, sizeof(int)); 02915 if (bridging) { 02916 /* trying to make a mISDN_dsp conference */ 02917 chan_misdn_log(1, ch1->bc->port, "I SEND: Making conference with Number:%d\n", ch1->bc->pid +1); 02918 misdn_lib_bridge(ch1->bc,ch2->bc); 02919 } 02920 02921 if (option_verbose > 2) 02922 ast_verbose(VERBOSE_PREFIX_3 "Native bridging %s and %s\n", c0->name, c1->name); 02923 02924 chan_misdn_log(1, ch1->bc->port, "* Making Native Bridge between %s and %s\n", ch1->bc->oad, ch2->bc->oad); 02925 02926 if (! (flags&AST_BRIDGE_DTMF_CHANNEL_0) ) 02927 ch1->ignore_dtmf=1; 02928 02929 if (! (flags&AST_BRIDGE_DTMF_CHANNEL_1) ) 02930 ch2->ignore_dtmf=1; 02931 02932 while(1) { 02933 to=-1; 02934 who = ast_waitfor_n(carr, 2, &to); 02935 02936 if (!who) { 02937 ast_log(LOG_NOTICE,"misdn_bridge: empty read, breaking out\n"); 02938 break; 02939 } 02940 f = ast_read(who); 02941 02942 if (!f || f->frametype == AST_FRAME_CONTROL) { 02943 /* got hangup .. */ 02944 02945 if (!f) 02946 chan_misdn_log(4,ch1->bc->port,"Read Null Frame\n"); 02947 else 02948 chan_misdn_log(4,ch1->bc->port,"Read Frame Controll class:%d\n",f->subclass); 02949 02950 *fo=f; 02951 *rc=who; 02952 02953 break; 02954 } 02955 02956 if ( f->frametype == AST_FRAME_DTMF ) { 02957 chan_misdn_log(1,0,"Read DTMF %d from %s\n",f->subclass, who->exten); 02958 02959 *fo=f; 02960 *rc=who; 02961 break; 02962 } 02963 02964 #if 0 02965 if (f->frametype == AST_FRAME_VOICE) { 02966 chan_misdn_log(1, ch1->bc->port, "I SEND: Splitting conference with Number:%d\n", ch1->bc->pid +1); 02967 02968 continue; 02969 } 02970 #endif 02971 02972 if (who == c0) { 02973 ast_write(c1,f); 02974 } 02975 else { 02976 ast_write(c0,f); 02977 } 02978 02979 } 02980 02981 chan_misdn_log(1, ch1->bc->port, "I SEND: Splitting conference with Number:%d\n", ch1->bc->pid +1); 02982 02983 misdn_lib_split_bridge(ch1->bc,ch2->bc); 02984 02985 02986 return AST_BRIDGE_COMPLETE; 02987 }
static int misdn_call | ( | struct ast_channel * | ast, | |
char * | dest, | |||
int | timeout | |||
) | [static] |
Definition at line 2004 of file chan_misdn.c.
References ast_channel::_state, add_out_calls(), chan_list::ast, ast_log(), ast_setstate(), AST_STATE_DIALING, AST_STATE_DOWN, AST_STATE_RESERVED, ast_strdupa, ast_strlen_zero(), ast_transfercapability2str(), ast_verbose(), 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(), 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, chan_list::state, stop_bc_tones(), strsep(), ast_channel::transfercapability, and update_config().
02005 { 02006 int port=0; 02007 int r; 02008 int exceed; 02009 struct chan_list *ch=MISDN_ASTERISK_TECH_PVT(ast); 02010 struct misdn_bchannel *newbc; 02011 char *opts=NULL, *ext; 02012 02013 { 02014 ext = ast_strdupa(dest); 02015 strsep(&ext,"/"); 02016 if (ext) { 02017 opts=ext; 02018 strsep(&opts,"/"); 02019 } else { 02020 ast_log(LOG_WARNING, "Malformed dialstring\n"); 02021 return -1; 02022 } 02023 } 02024 02025 if (!ast) { 02026 ast_log(LOG_WARNING, " --> ! misdn_call called on ast_channel *ast where ast == NULL\n"); 02027 return -1; 02028 } 02029 02030 if (((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) || !dest ) { 02031 ast_log(LOG_WARNING, " --> ! misdn_call called on %s, neither down nor reserved (or dest==NULL)\n", ast->name); 02032 ast->hangupcause=41; 02033 ast_setstate(ast, AST_STATE_DOWN); 02034 return -1; 02035 } 02036 02037 if (!ch) { 02038 ast_log(LOG_WARNING, " --> ! misdn_call called on %s, neither down nor reserved (or dest==NULL)\n", ast->name); 02039 ast->hangupcause=41; 02040 ast_setstate(ast, AST_STATE_DOWN); 02041 return -1; 02042 } 02043 02044 newbc=ch->bc; 02045 02046 if (!newbc) { 02047 ast_log(LOG_WARNING, " --> ! misdn_call called on %s, neither down nor reserved (or dest==NULL)\n", ast->name); 02048 ast->hangupcause=41; 02049 ast_setstate(ast, AST_STATE_DOWN); 02050 return -1; 02051 } 02052 02053 port=newbc->port; 02054 02055 if ((exceed=add_out_calls(port))) { 02056 char tmp[16]; 02057 sprintf(tmp,"%d",exceed); 02058 pbx_builtin_setvar_helper(ast,"MAX_OVERFLOW",tmp); 02059 return -1; 02060 } 02061 02062 chan_misdn_log(1, port, "* CALL: %s\n",dest); 02063 02064 chan_misdn_log(2, port, " --> * dad:%s tech:%s ctx:%s\n",ast->exten,ast->name, ast->context); 02065 02066 chan_misdn_log(3, port, " --> * adding2newbc ext %s\n",ast->exten); 02067 if (ast->exten) { 02068 int l = sizeof(newbc->dad); 02069 strncpy(ast->exten,ext,sizeof(ast->exten)); 02070 02071 strncpy(newbc->dad,ext,l); 02072 02073 newbc->dad[l-1] = 0; 02074 } 02075 02076 if (ast->cid.cid_rdnis) 02077 strcpy(newbc->rad, ast->cid.cid_rdnis); 02078 else 02079 newbc->rad[0]=0; 02080 02081 chan_misdn_log(3, port, " --> * adding2newbc callerid %s\n",ast->cid.cid_num); 02082 if (ast_strlen_zero(newbc->oad) && ast->cid.cid_num ) { 02083 02084 if (ast->cid.cid_num) { 02085 int l = sizeof(newbc->oad); 02086 strncpy(newbc->oad,ast->cid.cid_num, l); 02087 newbc->oad[l-1] = 0; 02088 } 02089 } 02090 02091 { 02092 int bridging; 02093 struct chan_list *ch=MISDN_ASTERISK_TECH_PVT(ast); 02094 if (!ch) { ast_verbose("No chan_list in misdn_call\n"); return -1;} 02095 02096 newbc->capability=ast->transfercapability; 02097 pbx_builtin_setvar_helper(ast,"TRANSFERCAPABILITY",ast_transfercapability2str(newbc->capability)); 02098 if ( ast->transfercapability == INFO_CAPABILITY_DIGITAL_UNRESTRICTED) { 02099 chan_misdn_log(2, port, " --> * Call with flag Digital\n"); 02100 } 02101 02102 02103 /* update screening and presentation */ 02104 update_config(ch,ORG_AST); 02105 02106 /* fill in some ies from channel vary*/ 02107 import_ch(ast, newbc, ch); 02108 02109 /* Finally The Options Override Everything */ 02110 if (opts) 02111 misdn_set_opt_exec(ast,opts); 02112 else 02113 chan_misdn_log(2,port,"NO OPTS GIVEN\n"); 02114 02115 /*check for bridging*/ 02116 misdn_cfg_get( 0, MISDN_GEN_BRIDGING, &bridging, sizeof(int)); 02117 if (bridging && ch->other_ch) { 02118 #ifdef MISDN_1_2 02119 chan_misdn_log(1, port, "Disabling EC (aka Pipeline) on both Sides\n"); 02120 *ch->bc->pipeline=0; 02121 *ch->other_ch->bc->pipeline=0; 02122 #else 02123 chan_misdn_log(1, port, "Disabling EC on both Sides\n"); 02124 ch->bc->ec_enable=0; 02125 ch->other_ch->bc->ec_enable=0; 02126 #endif 02127 } 02128 02129 r=misdn_lib_send_event( newbc, EVENT_SETUP ); 02130 02131 /** we should have l3id after sending setup **/ 02132 ch->l3id=newbc->l3_id; 02133 } 02134 02135 if ( r == -ENOCHAN ) { 02136 chan_misdn_log(0, port, " --> * Theres no Channel at the moment .. !\n"); 02137 chan_misdn_log(1, port, " --> * SEND: State Down pid:%d\n",newbc?newbc->pid:-1); 02138 ast->hangupcause=34; 02139 ast_setstate(ast, AST_STATE_DOWN); 02140 return -1; 02141 } 02142 02143 chan_misdn_log(2, port, " --> * SEND: State Dialing pid:%d\n",newbc?newbc->pid:1); 02144 02145 ast_setstate(ast, AST_STATE_DIALING); 02146 ast->hangupcause=16; 02147 02148 if (newbc->nt) stop_bc_tones(ch); 02149 02150 ch->state=MISDN_CALLING; 02151 02152 return 0; 02153 }
static int misdn_check_l2l1 | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Definition at line 5175 of file chan_misdn.c.
References AST_APP_ARG, 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().
05176 { 05177 char group[BUFFERSIZE+1]; 05178 char *port_str; 05179 int port_up; 05180 int timeout; 05181 int dowait=0; 05182 int port=0; 05183 05184 AST_DECLARE_APP_ARGS(args, 05185 AST_APP_ARG(grouppar); 05186 AST_APP_ARG(timeout); 05187 ); 05188 05189 if (ast_strlen_zero((char *)data)) { 05190 ast_log(LOG_WARNING, "misdn_check_l2l1 Requires arguments\n"); 05191 return -1; 05192 } 05193 05194 AST_STANDARD_APP_ARGS(args, data); 05195 05196 if (args.argc != 2) { 05197 ast_log(LOG_WARNING, "Wrong argument count\n"); 05198 return 0; 05199 } 05200 05201 /*ast_log(LOG_NOTICE, "Arguments: group/port '%s' timeout '%s'\n", args.grouppar, args.timeout);*/ 05202 timeout=atoi(args.timeout); 05203 port_str=args.grouppar; 05204 if (port_str[0]=='g' && port_str[1]==':' ) { 05205 /* We make a group call lets checkout which ports are in my group */ 05206 port_str += 2; 05207 strncpy(group, port_str, BUFFERSIZE); 05208 group[BUFFERSIZE-1] = 0; 05209 chan_misdn_log(2, 0, "Checking Ports in group: %s\n",group); 05210 05211 for ( port = misdn_cfg_get_next_port(port); 05212 port > 0; 05213 port = misdn_cfg_get_next_port(port)) 05214 { 05215 char cfg_group[BUFFERSIZE+1]; 05216 05217 chan_misdn_log(2,0,"trying port %d\n",port); 05218 05219 misdn_cfg_get(port, MISDN_CFG_GROUPNAME, cfg_group, BUFFERSIZE); 05220 05221 if (!strcasecmp(cfg_group, group)) { 05222 port_up = misdn_lib_port_up(port, 1); 05223 05224 if (!port_up) { 05225 chan_misdn_log(2, 0, " --> port '%d'\n", port); 05226 misdn_lib_get_port_up(port); 05227 dowait=1; 05228 } 05229 } 05230 } 05231 05232 } else { 05233 port = atoi(port_str); 05234 chan_misdn_log(2, 0, "Checking Port: %d\n",port); 05235 port_up = misdn_lib_port_up(port, 1); 05236 if (!port_up) { 05237 misdn_lib_get_port_up(port); 05238 dowait=1; 05239 } 05240 05241 } 05242 05243 if (dowait) { 05244 chan_misdn_log(2, 0, "Waiting for '%d' seconds\n",timeout); 05245 sleep(timeout); 05246 } 05247 05248 return 0; 05249 }
static int misdn_digit_begin | ( | struct ast_channel * | chan, | |
char | digit | |||
) | [static] |
Definition at line 2216 of file chan_misdn.c.
02217 { 02218 /* XXX Modify this callback to support Asterisk controlling the length of DTMF */ 02219 return 0; 02220 }
static int misdn_digit_end | ( | struct ast_channel * | ast, | |
char | digit, | |||
unsigned int | duration | |||
) | [static] |
Definition at line 2222 of file chan_misdn.c.
References chan_list::ast, ast_log(), chan_list::bc, chan_misdn_log(), misdn_bchannel::dad, EVENT_INFORMATION, ast_channel::exten, misdn_bchannel::info_dad, misdn_bchannel::infos_pending, LOG_WARNING, MISDN_ASTERISK_TECH_PVT, MISDN_CALLING, MISDN_CALLING_ACKNOWLEDGE, misdn_lib_send_event(), chan_list::other_ch, misdn_bchannel::port, send_digit_to_chan(), misdn_bchannel::send_dtmf, and chan_list::state.
02223 { 02224 struct chan_list *p; 02225 struct misdn_bchannel *bc; 02226 02227 if (!ast || ! (p=MISDN_ASTERISK_TECH_PVT(ast))) return -1; 02228 02229 bc=p->bc; 02230 chan_misdn_log(1, bc?bc->port:0, "* IND : Digit %c\n",digit); 02231 02232 if (!bc) { 02233 ast_log(LOG_WARNING, " --> !! Got Digit Event withut having bchannel Object\n"); 02234 return -1; 02235 } 02236 02237 switch (p->state ) { 02238 case MISDN_CALLING: 02239 { 02240 int l; 02241 char buf[8]; 02242 buf[0]=digit; 02243 buf[1]=0; 02244 02245 l = sizeof(bc->infos_pending); 02246 strncat(bc->infos_pending, buf, l - strlen(bc->infos_pending) - 1); 02247 } 02248 break; 02249 case MISDN_CALLING_ACKNOWLEDGE: 02250 { 02251 bc->info_dad[0]=digit; 02252 bc->info_dad[1]=0; 02253 02254 { 02255 int l = sizeof(bc->dad); 02256 strncat(bc->dad, bc->info_dad, l - strlen(bc->dad) - 1); 02257 } 02258 { 02259 int l = sizeof(p->ast->exten); 02260 strncpy(p->ast->exten, bc->dad, l); 02261 p->ast->exten[l-1] = 0; 02262 } 02263 02264 misdn_lib_send_event( bc, EVENT_INFORMATION); 02265 } 02266 break; 02267 02268 default: 02269 /* Do not send Digits in CONNECTED State, when 02270 * the other side is too mISDN. */ 02271 if (p->other_ch ) 02272 return 0; 02273 02274 if ( bc->send_dtmf ) 02275 send_digit_to_chan(p,digit); 02276 break; 02277 } 02278 02279 return 0; 02280 }
static int misdn_facility_exec | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Definition at line 5129 of file chan_misdn.c.
References 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().
05130 { 05131 struct chan_list *ch = MISDN_ASTERISK_TECH_PVT(chan); 05132 char *tok, *tokb; 05133 05134 chan_misdn_log(0,0,"TYPE: %s\n",chan->tech->type); 05135 05136 if (strcasecmp(chan->tech->type,"mISDN")) { 05137 ast_log(LOG_WARNING, "misdn_facility makes only sense with chan_misdn channels!\n"); 05138 return -1; 05139 } 05140 05141 if (ast_strlen_zero((char *)data)) { 05142 ast_log(LOG_WARNING, "misdn_facility Requires arguments\n"); 05143 return -1; 05144 } 05145 05146 tok=strtok_r((char*)data,"|", &tokb) ; 05147 05148 if (!tok) { 05149 ast_log(LOG_WARNING, "misdn_facility Requires arguments\n"); 05150 return -1; 05151 } 05152 05153 if (!strcasecmp(tok,"calldeflect")) { 05154 tok=strtok_r(NULL,"|", &tokb) ; 05155 05156 if (!tok) { 05157 ast_log(LOG_WARNING, "Facility: Call Defl Requires arguments\n"); 05158 } 05159 05160 if (strlen(tok) >= sizeof(ch->bc->fac_out.u.CDeflection.DeflectedToNumber)) { 05161 ast_log(LOG_WARNING, "Facility: Number argument too long (up to 15 digits are allowed). Ignoring.\n"); 05162 return 0; 05163 } 05164 ch->bc->fac_out.Function = Fac_CD; 05165 strncpy((char *)ch->bc->fac_out.u.CDeflection.DeflectedToNumber, tok, sizeof(ch->bc->fac_out.u.CDeflection.DeflectedToNumber)); 05166 misdn_lib_send_event(ch->bc, EVENT_FACILITY); 05167 } else { 05168 chan_misdn_log(1, ch->bc->port, "Unknown Facility: %s\n",tok); 05169 } 05170 05171 return 0; 05172 05173 }
static int misdn_fixup | ( | struct ast_channel * | oldast, | |
struct ast_channel * | ast | |||
) | [static] |
Definition at line 2283 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.
02284 { 02285 struct chan_list *p; 02286 02287 if (!ast || ! (p=MISDN_ASTERISK_TECH_PVT(ast) )) return -1; 02288 02289 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); 02290 02291 p->ast = ast ; 02292 02293 return 0; 02294 }
static char* misdn_get_ch_state | ( | struct chan_list * | p | ) | [static] |
Definition at line 1025 of file chan_misdn.c.
References chan_list::state, state_array, and state_struct::txt.
Referenced by cb_events(), misdn_fixup(), misdn_hangup(), misdn_write(), print_bc_info(), and release_chan().
01026 { 01027 int i; 01028 static char state[8]; 01029 01030 if( !p) return NULL; 01031 01032 for (i=0; i< sizeof(state_array)/sizeof(struct state_struct); i++) { 01033 if ( state_array[i].state == p->state) return state_array[i].txt; 01034 } 01035 01036 sprintf(state,"%d",p->state) ; 01037 01038 return state; 01039 }
static int misdn_hangup | ( | struct ast_channel * | ast | ) | [static] |
Definition at line 2430 of file chan_misdn.c.
References ast_channel::_state, chan_list::ast, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_STATE_RESERVED, chan_list::bc, misdn_bchannel::cause, chan_misdn_log(), ast_channel::cid, ast_callerid::cid_num, cl_dequeue_chan(), cl_te, ast_channel::context, EVENT_DISCONNECT, EVENT_RELEASE, EVENT_RELEASE_COMPLETE, ast_channel::exten, free, ast_channel::hangupcause, hanguptone_indicate(), chan_list::l3id, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, MISDN_ALERTING, MISDN_ASTERISK_TECH_PVT, MISDN_BUSY, MISDN_CALLING, MISDN_CALLING_ACKNOWLEDGE, MISDN_CLEANING, MISDN_CONNECTED, MISDN_DIALING, MISDN_DISCONNECTED, misdn_get_ch_state(), MISDN_HOLD_DISCONNECT, MISDN_HOLDED, MISDN_INCOMING_SETUP, misdn_lib_release(), misdn_lib_send_event(), MISDN_NOTHING, MISDN_PRECONNECTED, MISDN_PROCEEDING, MISDN_PROGRESS, MISDN_RELEASED, chan_list::need_busy, misdn_bchannel::need_disconnect, chan_list::need_hangup, chan_list::need_queue_hangup, misdn_bchannel::need_release, misdn_bchannel::need_release_complete, misdn_bchannel::nt, ORG_AST, chan_list::originator, misdn_bchannel::out_cause, pbx_builtin_getvar_helper(), misdn_bchannel::pid, chan_list::pipe, misdn_bchannel::port, release_chan(), release_lock, start_bc_tones(), chan_list::state, stop_bc_tones(), misdn_bchannel::uu, and misdn_bchannel::uulen.
02431 { 02432 struct chan_list *p; 02433 struct misdn_bchannel *bc=NULL; 02434 02435 ast_log(LOG_DEBUG, "misdn_hangup(%s)\n", ast->name); 02436 02437 if (!ast || ! (p=MISDN_ASTERISK_TECH_PVT(ast) ) ) return -1; 02438 02439 if (!p) { 02440 chan_misdn_log(3, 0, "misdn_hangup called, without chan_list obj.\n"); 02441 return 0 ; 02442 } 02443 02444 bc=p->bc; 02445 02446 if (bc) { 02447 const char *tmp=pbx_builtin_getvar_helper(ast,"MISDN_USERUSER"); 02448 if (tmp) { 02449 ast_log(LOG_NOTICE, "MISDN_USERUSER: %s\n", tmp); 02450 strcpy(bc->uu, tmp); 02451 bc->uulen=strlen(bc->uu); 02452 } 02453 } 02454 02455 MISDN_ASTERISK_TECH_PVT(ast)=NULL; 02456 p->ast=NULL; 02457 02458 if (ast->_state == AST_STATE_RESERVED || 02459 p->state == MISDN_NOTHING || 02460 p->state == MISDN_HOLDED || 02461 p->state == MISDN_HOLD_DISCONNECT ) { 02462 02463 CLEAN_CH: 02464 /* between request and call */ 02465 ast_log(LOG_DEBUG, "State Reserved (or nothing) => chanIsAvail\n"); 02466 MISDN_ASTERISK_TECH_PVT(ast)=NULL; 02467 02468 ast_mutex_lock(&release_lock); 02469 cl_dequeue_chan(&cl_te, p); 02470 close(p->pipe[0]); 02471 close(p->pipe[1]); 02472 free(p); 02473 ast_mutex_unlock(&release_lock); 02474 02475 if (bc) 02476 misdn_lib_release(bc); 02477 02478 return 0; 02479 } 02480 02481 if (!bc) { 02482 ast_log(LOG_WARNING,"Hangup with private but no bc ? state:%s l3id:%x\n", misdn_get_ch_state(p), p->l3id); 02483 goto CLEAN_CH; 02484 } 02485 02486 02487 p->need_hangup=0; 02488 p->need_queue_hangup=0; 02489 p->need_busy=0; 02490 02491 02492 if (!p->bc->nt) 02493 stop_bc_tones(p); 02494 02495 02496 { 02497 const char *varcause=NULL; 02498 bc->out_cause=ast->hangupcause?ast->hangupcause:16; 02499 02500 if ( (varcause=pbx_builtin_getvar_helper(ast, "HANGUPCAUSE")) || 02501 (varcause=pbx_builtin_getvar_helper(ast, "PRI_CAUSE"))) { 02502 int tmpcause=atoi(varcause); 02503 bc->out_cause=tmpcause?tmpcause:16; 02504 } 02505 02506 chan_misdn_log(1, bc->port, "* IND : HANGUP\tpid:%d ctx:%s dad:%s oad:%s State:%s\n",p->bc?p->bc->pid:-1, ast->context, ast->exten, ast->cid.cid_num, misdn_get_ch_state(p)); 02507 chan_misdn_log(3, bc->port, " --> l3id:%x\n",p->l3id); 02508 chan_misdn_log(3, bc->port, " --> cause:%d\n",bc->cause); 02509 chan_misdn_log(2, bc->port, " --> out_cause:%d\n",bc->out_cause); 02510 chan_misdn_log(2, bc->port, " --> state:%s\n", misdn_get_ch_state(p)); 02511 02512 switch (p->state) { 02513 case MISDN_CALLING: 02514 case MISDN_INCOMING_SETUP: 02515 /* This is the only place in misdn_hangup, where we 02516 * can call release_chan, else it might create lot's of trouble 02517 * */ 02518 ast_log(LOG_NOTICE, "release channel, in CALLING/INCOMING_SETUP state.. no other events happened\n"); 02519 release_chan(bc); 02520 02521 p->state=MISDN_CLEANING; 02522 if (bc->need_release_complete) 02523 misdn_lib_send_event( bc, EVENT_RELEASE_COMPLETE); 02524 break; 02525 case MISDN_HOLDED: 02526 case MISDN_DIALING: 02527 start_bc_tones(p); 02528 hanguptone_indicate(p); 02529 02530 if (bc->need_disconnect) 02531 misdn_lib_send_event( bc, EVENT_DISCONNECT); 02532 break; 02533 02534 case MISDN_CALLING_ACKNOWLEDGE: 02535 start_bc_tones(p); 02536 hanguptone_indicate(p); 02537 02538 if (bc->need_disconnect) 02539 misdn_lib_send_event( bc, EVENT_DISCONNECT); 02540 break; 02541 02542 case MISDN_ALERTING: 02543 case MISDN_PROGRESS: 02544 case MISDN_PROCEEDING: 02545 if (p->originator != ORG_AST) 02546 hanguptone_indicate(p); 02547 02548 /*p->state=MISDN_CLEANING;*/ 02549 if (bc->need_disconnect) 02550 misdn_lib_send_event( bc, EVENT_DISCONNECT); 02551 break; 02552 case MISDN_CONNECTED: 02553 case MISDN_PRECONNECTED: 02554 /* Alerting or Disconect */ 02555 if (p->bc->nt) { 02556 start_bc_tones(p); 02557 hanguptone_indicate(p); 02558 p->bc->progress_indicator=8; 02559 } 02560 if (bc->need_disconnect) 02561 misdn_lib_send_event( bc, EVENT_DISCONNECT); 02562 02563 /*p->state=MISDN_CLEANING;*/ 02564 break; 02565 case MISDN_DISCONNECTED: 02566 if (bc->need_release) 02567 misdn_lib_send_event( bc, EVENT_RELEASE); 02568 p->state=MISDN_CLEANING; /* MISDN_HUNGUP_FROM_AST; */ 02569 break; 02570 02571 case MISDN_RELEASED: 02572 case MISDN_CLEANING: 02573 p->state=MISDN_CLEANING; 02574 break; 02575 02576 case MISDN_BUSY: 02577 break; 02578 02579 case MISDN_HOLD_DISCONNECT: 02580 /* need to send release here */ 02581 chan_misdn_log(1, bc->port, " --> cause %d\n",bc->cause); 02582 chan_misdn_log(1, bc->port, " --> out_cause %d\n",bc->out_cause); 02583 02584 bc->out_cause=-1; 02585 if (bc->need_release) 02586 misdn_lib_send_event(bc,EVENT_RELEASE); 02587 p->state=MISDN_CLEANING; 02588 break; 02589 default: 02590 if (bc->nt) { 02591 bc->out_cause=-1; 02592 if (bc->need_release) 02593 misdn_lib_send_event(bc, EVENT_RELEASE); 02594 p->state=MISDN_CLEANING; 02595 } else { 02596 if (bc->need_disconnect) 02597 misdn_lib_send_event(bc, EVENT_DISCONNECT); 02598 } 02599 } 02600 02601 p->state=MISDN_CLEANING; 02602 02603 } 02604 02605 02606 chan_misdn_log(3, bc->port, " --> Channel: %s hanguped new state:%s\n",ast->name,misdn_get_ch_state(p)); 02607 02608 return 0; 02609 }
static int misdn_indication | ( | struct ast_channel * | ast, | |
int | cond, | |||
const void * | data, | |||
size_t | datalen | |||
) | [static] |
Definition at line 2298 of file chan_misdn.c.
References chan_list::ast, 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_RINGING, chan_list::bc, chan_misdn_log(), EVENT_ALERTING, EVENT_DISCONNECT, EVENT_PROCEEDING, EVENT_PROGRESS, ast_channel::exten, hanguptone_indicate(), chan_list::incoming_early_audio, LOG_WARNING, MISDN_ALERTING, MISDN_ASTERISK_TECH_PVT, MISDN_CONNECTED, misdn_inband_avail(), misdn_lib_send_event(), misdn_bchannel::nt, ORG_MISDN, chan_list::originator, chan_list::other_ch, misdn_bchannel::out_cause, misdn_bchannel::pid, misdn_bchannel::port, start_bc_tones(), chan_list::state, and stop_indicate().
02299 { 02300 struct chan_list *p; 02301 02302 02303 if (!ast || ! (p=MISDN_ASTERISK_TECH_PVT(ast))) { 02304 ast_log(LOG_WARNING, "Returnded -1 in misdn_indication\n"); 02305 return -1; 02306 } 02307 02308 if (!p->bc ) { 02309 chan_misdn_log(1, 0, "* IND : Indication from %s\n",ast->exten); 02310 ast_log(LOG_WARNING, "Private Pointer but no bc ?\n"); 02311 return -1; 02312 } 02313 02314 chan_misdn_log(5, p->bc->port, "* IND : Indication [%d] from %s\n",cond, ast->exten); 02315 02316 switch (cond) { 02317 case AST_CONTROL_BUSY: 02318 chan_misdn_log(1, p->bc->port, "* IND :\tbusy pid:%d\n",p->bc?p->bc->pid:-1); 02319 ast_setstate(ast,AST_STATE_BUSY); 02320 02321 p->bc->out_cause=17; 02322 if (p->state != MISDN_CONNECTED) { 02323 start_bc_tones(p); 02324 misdn_lib_send_event( p->bc, EVENT_DISCONNECT); 02325 } else { 02326 chan_misdn_log(-1, p->bc->port, " --> !! Got Busy in Connected State !?! ast:%s\n", ast->name); 02327 } 02328 return -1; 02329 break; 02330 case AST_CONTROL_RING: 02331 chan_misdn_log(1, p->bc->port, "* IND :\tring pid:%d\n",p->bc?p->bc->pid:-1); 02332 return -1; 02333 break; 02334 02335 case AST_CONTROL_RINGING: 02336 chan_misdn_log(1, p->bc->port, "* IND :\tringing pid:%d\n",p->bc?p->bc->pid:-1); 02337 switch (p->state) { 02338 case MISDN_ALERTING: 02339 chan_misdn_log(2, p->bc->port, " --> * IND :\tringing pid:%d but I was Ringing before, so ignoreing it\n",p->bc?p->bc->pid:-1); 02340 break; 02341 case MISDN_CONNECTED: 02342 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); 02343 return -1; 02344 break; 02345 default: 02346 p->state=MISDN_ALERTING; 02347 chan_misdn_log(2, p->bc->port, " --> * IND :\tringing pid:%d\n",p->bc?p->bc->pid:-1); 02348 misdn_lib_send_event( p->bc, EVENT_ALERTING); 02349 02350 if (p->other_ch && p->other_ch->bc) { 02351 if (misdn_inband_avail(p->other_ch->bc)) { 02352 chan_misdn_log(2,p->bc->port, " --> other End is mISDN and has inband info available\n"); 02353 break; 02354 } 02355 02356 if (!p->other_ch->bc->nt) { 02357 chan_misdn_log(2,p->bc->port, " --> other End is mISDN TE so it has inband info for sure (?)\n"); 02358 break; 02359 } 02360 } 02361 02362 chan_misdn_log(3, p->bc->port, " --> * SEND: State Ring pid:%d\n",p->bc?p->bc->pid:-1); 02363 ast_setstate(ast,AST_STATE_RINGING); 02364 02365 if ( !p->bc->nt && (p->originator==ORG_MISDN) && !p->incoming_early_audio ) 02366 chan_misdn_log(2,p->bc->port, " --> incoming_early_audio off\n"); 02367 else 02368 return -1; 02369 } 02370 break; 02371 case AST_CONTROL_ANSWER: 02372 chan_misdn_log(1, p->bc->port, " --> * IND :\tanswer pid:%d\n",p->bc?p->bc->pid:-1); 02373 start_bc_tones(p); 02374 break; 02375 case AST_CONTROL_TAKEOFFHOOK: 02376 chan_misdn_log(1, p->bc->port, " --> *\ttakeoffhook pid:%d\n",p->bc?p->bc->pid:-1); 02377 return -1; 02378 break; 02379 case AST_CONTROL_OFFHOOK: 02380 chan_misdn_log(1, p->bc->port, " --> *\toffhook pid:%d\n",p->bc?p->bc->pid:-1); 02381 return -1; 02382 break; 02383 case AST_CONTROL_FLASH: 02384 chan_misdn_log(1, p->bc->port, " --> *\tflash pid:%d\n",p->bc?p->bc->pid:-1); 02385 break; 02386 case AST_CONTROL_PROGRESS: 02387 chan_misdn_log(1, p->bc->port, " --> * IND :\tprogress pid:%d\n",p->bc?p->bc->pid:-1); 02388 misdn_lib_send_event( p->bc, EVENT_PROGRESS); 02389 break; 02390 case AST_CONTROL_PROCEEDING: 02391 chan_misdn_log(1, p->bc->port, " --> * IND :\tproceeding pid:%d\n",p->bc?p->bc->pid:-1); 02392 misdn_lib_send_event( p->bc, EVENT_PROCEEDING); 02393 break; 02394 case AST_CONTROL_CONGESTION: 02395 chan_misdn_log(1, p->bc->port, " --> * IND :\tcongestion pid:%d\n",p->bc?p->bc->pid:-1); 02396 02397 p->bc->out_cause=42; 02398 start_bc_tones(p); 02399 misdn_lib_send_event( p->bc, EVENT_DISCONNECT); 02400 02401 if (p->bc->nt) { 02402 hanguptone_indicate(p); 02403 } 02404 break; 02405 case -1 : 02406 chan_misdn_log(1, p->bc->port, " --> * IND :\t-1! (stop indication) pid:%d\n",p->bc?p->bc->pid:-1); 02407 02408 stop_indicate(p); 02409 02410 if (p->state == MISDN_CONNECTED) 02411 start_bc_tones(p); 02412 02413 break; 02414 02415 case AST_CONTROL_HOLD: 02416 ast_moh_start(ast,data,ast->musicclass); 02417 chan_misdn_log(1, p->bc->port, " --> *\tHOLD pid:%d\n",p->bc?p->bc->pid:-1); 02418 break; 02419 case AST_CONTROL_UNHOLD: 02420 ast_moh_stop(ast); 02421 chan_misdn_log(1, p->bc->port, " --> *\tUNHOLD pid:%d\n",p->bc?p->bc->pid:-1); 02422 break; 02423 default: 02424 chan_misdn_log(1, p->bc->port, " --> * Unknown Indication:%d pid:%d\n",cond,p->bc?p->bc->pid:-1); 02425 } 02426 02427 return 0; 02428 }
void misdn_jb_destroy | ( | struct misdn_jb * | jb | ) |
Definition at line 5507 of file chan_misdn.c.
References ast_mutex_destroy(), free, misdn_jb::mutexjb, and misdn_jb::samples.
Referenced by config_jitterbuffer(), and release_chan().
05508 { 05509 ast_mutex_destroy(&jb->mutexjb); 05510 05511 free(jb->samples); 05512 free(jb); 05513 }
int misdn_jb_empty | ( | struct misdn_jb * | jb, | |
char * | data, | |||
int | len | |||
) |
Definition at line 5579 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().
05580 { 05581 int i, wp, rp, read=0; 05582 05583 ast_mutex_lock (&jb->mutexjb); 05584 05585 rp=jb->rp; 05586 wp=jb->wp; 05587 05588 if(jb->state_empty) 05589 { 05590 for(i=0; i<len; i++) 05591 { 05592 if(wp==rp) 05593 { 05594 jb->rp=rp; 05595 jb->state_empty=0; 05596 05597 ast_mutex_unlock (&jb->mutexjb); 05598 05599 return read; 05600 } 05601 else 05602 { 05603 if(jb->ok[rp]==1) 05604 { 05605 data[i]=jb->samples[rp]; 05606 jb->ok[rp]=0; 05607 rp=(rp!=jb->size-1 ? rp+1 : 0); 05608 read+=1; 05609 } 05610 } 05611 } 05612 05613 if(wp >= rp) 05614 jb->state_buffer=wp-rp; 05615 else 05616 jb->state_buffer= jb->size-rp+wp; 05617 chan_misdn_log(9,0,"misdn_jb_empty: read:%d | Bufferstatus:%d p:%x\n",len,jb->state_buffer,jb); 05618 05619 jb->rp=rp; 05620 } 05621 else 05622 chan_misdn_log(9,0,"misdn_jb_empty: Wait...requested:%d p:%x\n",len,jb); 05623 05624 ast_mutex_unlock (&jb->mutexjb); 05625 05626 return read; 05627 }
int misdn_jb_fill | ( | struct misdn_jb * | jb, | |
const char * | data, | |||
int | len | |||
) |
Definition at line 5517 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.
05518 { 05519 int i, j, rp, wp; 05520 05521 if (!jb || ! data) return 0; 05522 05523 ast_mutex_lock (&jb->mutexjb); 05524 05525 wp=jb->wp; 05526 rp=jb->rp; 05527 05528 for(i=0; i<len; i++) 05529 { 05530 jb->samples[wp]=data[i]; 05531 jb->ok[wp]=1; 05532 wp = (wp!=jb->size-1 ? wp+1 : 0); 05533 05534 if(wp==jb->rp) 05535 jb->state_full=1; 05536 } 05537 05538 if(wp>=rp) 05539 jb->state_buffer=wp-rp; 05540 else 05541 jb->state_buffer= jb->size-rp+wp; 05542 chan_misdn_log(9,0,"misdn_jb_fill: written:%d | Bufferstatus:%d p:%x\n",len,jb->state_buffer,jb); 05543 05544 if(jb->state_full) 05545 { 05546 jb->wp=wp; 05547 05548 rp=wp; 05549 for(j=0; j<jb->upper_threshold; j++) 05550 rp = (rp!=0 ? rp-1 : jb->size-1); 05551 jb->rp=rp; 05552 jb->state_full=0; 05553 jb->state_empty=1; 05554 05555 ast_mutex_unlock (&jb->mutexjb); 05556 05557 return -1; 05558 } 05559 05560 if(!jb->state_empty) 05561 { 05562 jb->bytes_wrote+=len; 05563 if(jb->bytes_wrote>=jb->upper_threshold) 05564 { 05565 jb->state_empty=1; 05566 jb->bytes_wrote=0; 05567 } 05568 } 05569 jb->wp=wp; 05570 05571 ast_mutex_unlock (&jb->mutexjb); 05572 05573 return 0; 05574 }
struct misdn_jb * misdn_jb_init | ( | int | size, | |
int | upper_threshold | |||
) |
Definition at line 5473 of file chan_misdn.c.
References ast_mutex_init(), misdn_jb::bytes_wrote, chan_misdn_log(), malloc, misdn_jb::mutexjb, misdn_jb::ok, misdn_jb::rp, misdn_jb::samples, misdn_jb::size, misdn_jb::state_empty, misdn_jb::state_full, misdn_jb::upper_threshold, and misdn_jb::wp.
Referenced by config_jitterbuffer().
05474 { 05475 int i; 05476 struct misdn_jb *jb = (struct misdn_jb*) malloc(sizeof(struct misdn_jb)); 05477 jb->size = size; 05478 jb->upper_threshold = upper_threshold; 05479 jb->wp = 0; 05480 jb->rp = 0; 05481 jb->state_full = 0; 05482 jb->state_empty = 0; 05483 jb->bytes_wrote = 0; 05484 jb->samples = (char *)malloc(size*sizeof(char)); 05485 05486 if (!jb->samples) { 05487 chan_misdn_log(-1,0,"No free Mem for jb->samples\n"); 05488 return NULL; 05489 } 05490 05491 jb->ok = (char *)malloc(size*sizeof(char)); 05492 05493 if (!jb->ok) { 05494 chan_misdn_log(-1,0,"No free Mem for jb->ok\n"); 05495 return NULL; 05496 } 05497 05498 for(i=0; i<size; i++) 05499 jb->ok[i]=0; 05500 05501 ast_mutex_init(&jb->mutexjb); 05502 05503 return jb; 05504 }
static int misdn_l1_task | ( | const void * | data | ) | [static] |
Definition at line 646 of file chan_misdn.c.
References chan_misdn_log(), and misdn_lib_isdn_l1watcher().
Referenced by load_module().
00647 { 00648 misdn_lib_isdn_l1watcher(*(int *)data); 00649 chan_misdn_log(5, *(int *)data, "L1watcher timeout\n"); 00650 return 1; 00651 }
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 3351 of file chan_misdn.c.
References ast_callerid_parse(), ast_channel_alloc(), 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().
03352 { 03353 struct ast_channel *tmp; 03354 char *cid_name = 0, *cid_num = 0; 03355 int chan_offset=0; 03356 int tmp_port = misdn_cfg_get_next_port(0); 03357 03358 for (; tmp_port > 0; tmp_port=misdn_cfg_get_next_port(tmp_port)) { 03359 if (tmp_port == port) break; 03360 chan_offset+=misdn_lib_port_is_pri(tmp_port)?30:2; 03361 } 03362 if (c<0) c=0; 03363 03364 03365 if (callerid) 03366 ast_callerid_parse(callerid, &cid_name, &cid_num); 03367 03368 tmp = ast_channel_alloc(1, state, cid_num, cid_name, "", exten, "", 0, "%s/%d-u%d", misdn_type, chan_offset + c, glob_channel++); 03369 03370 if (tmp) { 03371 int bridging; 03372 chan_misdn_log(2, 0, " --> * NEW CHANNEL dad:%s oad:%s\n",exten,callerid); 03373 03374 tmp->nativeformats = prefformat; 03375 03376 tmp->readformat = format; 03377 tmp->rawreadformat = format; 03378 tmp->writeformat = format; 03379 tmp->rawwriteformat = format; 03380 03381 tmp->tech_pvt = chlist; 03382 03383 misdn_cfg_get( 0, MISDN_GEN_BRIDGING, &bridging, sizeof(int)); 03384 03385 if (bridging) 03386 tmp->tech = &misdn_tech; 03387 else 03388 tmp->tech = &misdn_tech_wo_bridge; 03389 03390 tmp->writeformat = format; 03391 tmp->readformat = format; 03392 tmp->priority=1; 03393 03394 if (exten) 03395 ast_copy_string(tmp->exten, exten, sizeof(tmp->exten)); 03396 else 03397 chan_misdn_log(1,0,"misdn_new: no exten given.\n"); 03398 03399 if (callerid) 03400 /* Don't use ast_set_callerid() here because it will 03401 * generate a needless NewCallerID event */ 03402 tmp->cid.cid_ani = ast_strdup(cid_num); 03403 03404 { 03405 if (pipe(chlist->pipe)<0) 03406 perror("Pipe failed\n"); 03407 03408 tmp->fds[0]=chlist->pipe[0]; 03409 03410 } 03411 03412 if (state == AST_STATE_RING) 03413 tmp->rings = 1; 03414 else 03415 tmp->rings = 0; 03416 03417 ast_jb_configure(tmp, misdn_get_global_jbconf()); 03418 } else { 03419 chan_misdn_log(-1,0,"Unable to allocate channel structure\n"); 03420 } 03421 03422 return tmp; 03423 }
static int misdn_overlap_dial_task | ( | const void * | data | ) | [static] |
Definition at line 653 of file chan_misdn.c.
References chan_list::ast, ast_exists_extension(), ast_mutex_lock(), ast_mutex_unlock(), ast_strlen_zero(), 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().
00654 { 00655 struct timeval tv_end, tv_now; 00656 int diff; 00657 struct chan_list *ch = (struct chan_list *)data; 00658 00659 chan_misdn_log(4, ch->bc->port, "overlap dial task, chan_state: %d\n", ch->state); 00660 00661 if (ch->state != MISDN_WAITING4DIGS) { 00662 ch->overlap_dial_task = -1; 00663 return 0; 00664 } 00665 00666 ast_mutex_lock(&ch->overlap_tv_lock); 00667 tv_end = ch->overlap_tv; 00668 ast_mutex_unlock(&ch->overlap_tv_lock); 00669 00670 tv_end.tv_sec += ch->overlap_dial; 00671 tv_now = ast_tvnow(); 00672 00673 diff = ast_tvdiff_ms(tv_end, tv_now); 00674 00675 if (diff <= 100) { 00676 char *dad=ch->bc->dad, sexten[]="s"; 00677 /* if we are 100ms near the timeout, we are satisfied.. */ 00678 stop_indicate(ch); 00679 00680 if (ast_strlen_zero(ch->bc->dad)) { 00681 dad=sexten; 00682 strcpy(ch->ast->exten, sexten); 00683 } 00684 00685 if (ast_exists_extension(ch->ast, ch->context, dad, 1, ch->bc->oad)) { 00686 ch->state=MISDN_DIALING; 00687 if (pbx_start_chan(ch) < 0) { 00688 chan_misdn_log(-1, ch->bc->port, "ast_pbx_start returned < 0 in misdn_overlap_dial_task\n"); 00689 goto misdn_overlap_dial_task_disconnect; 00690 } 00691 } else { 00692 misdn_overlap_dial_task_disconnect: 00693 hanguptone_indicate(ch); 00694 ch->bc->out_cause=1; 00695 ch->state=MISDN_CLEANING; 00696 misdn_lib_send_event(ch->bc, EVENT_DISCONNECT); 00697 } 00698 ch->overlap_dial_task = -1; 00699 return 0; 00700 } else 00701 return diff; 00702 }
static int misdn_port_block | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 808 of file chan_misdn.c.
References misdn_lib_port_block(), and RESULT_SHOWUSAGE.
00809 { 00810 int port; 00811 00812 if (argc != 4) 00813 return RESULT_SHOWUSAGE; 00814 00815 port = atoi(argv[3]); 00816 00817 misdn_lib_port_block(port); 00818 00819 return 0; 00820 }
static int misdn_port_down | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 879 of file chan_misdn.c.
References misdn_lib_get_port_down(), and RESULT_SHOWUSAGE.
00880 { 00881 int port; 00882 00883 if (argc != 4) 00884 return RESULT_SHOWUSAGE; 00885 00886 port = atoi(argv[3]); 00887 00888 misdn_lib_get_port_down(port); 00889 00890 return 0; 00891 }
static int misdn_port_unblock | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 822 of file chan_misdn.c.
References misdn_lib_port_unblock(), and RESULT_SHOWUSAGE.
00823 { 00824 int port; 00825 00826 if (argc != 4) 00827 return RESULT_SHOWUSAGE; 00828 00829 port = atoi(argv[3]); 00830 00831 misdn_lib_port_unblock(port); 00832 00833 return 0; 00834 }
static int misdn_port_up | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 865 of file chan_misdn.c.
References misdn_lib_get_port_up(), and RESULT_SHOWUSAGE.
00866 { 00867 int port; 00868 00869 if (argc != 4) 00870 return RESULT_SHOWUSAGE; 00871 00872 port = atoi(argv[3]); 00873 00874 misdn_lib_get_port_up(port); 00875 00876 return 0; 00877 }
static struct ast_frame* misdn_read | ( | struct ast_channel * | ast | ) | [static] |
Definition at line 2682 of file chan_misdn.c.
References chan_list::ast_dsp, AST_FORMAT_ALAW, AST_FRAME_VOICE, chan_list::ast_rd_buf, chan_list::bc, chan_misdn_log(), ast_frame::data, ast_frame::datalen, ast_frame::delivery, errno, chan_list::faxdetect, chan_list::faxdetect_timeout, chan_list::faxdetect_tv, chan_list::faxhandled, chan_list::frame, ast_frame::frametype, len, ast_frame::mallocd, MISDN_ASTERISK_TECH_PVT, MISDN_HOLDED, ast_frame::offset, chan_list::pipe, misdn_bchannel::port, process_ast_dsp(), ast_frame::samples, ast_frame::src, chan_list::state, ast_frame::subclass, and t.
02683 { 02684 struct chan_list *tmp; 02685 fd_set rrfs; 02686 struct timeval tv; 02687 int len, t; 02688 02689 if (!ast) { 02690 chan_misdn_log(1,0,"misdn_read called without ast\n"); 02691 return NULL; 02692 } 02693 if (!(tmp=MISDN_ASTERISK_TECH_PVT(ast))) { 02694 chan_misdn_log(1,0,"misdn_read called without ast->pvt\n"); 02695 return NULL; 02696 } 02697 02698 if (!tmp->bc && !(tmp->state==MISDN_HOLDED)) { 02699 chan_misdn_log(1,0,"misdn_read called without bc\n"); 02700 return NULL; 02701 } 02702 02703 tv.tv_sec=0; 02704 tv.tv_usec=20000; 02705 02706 FD_ZERO(&rrfs); 02707 FD_SET(tmp->pipe[0],&rrfs); 02708 02709 t=select(FD_SETSIZE,&rrfs,NULL, NULL,&tv); 02710 02711 if (!t) { 02712 chan_misdn_log(3, tmp->bc->port, "read Select Timed out\n"); 02713 len=160; 02714 } 02715 02716 if (t<0) { 02717 chan_misdn_log(-1, tmp->bc->port, "Select Error (err=%s)\n",strerror(errno)); 02718 return NULL; 02719 } 02720 02721 if (FD_ISSET(tmp->pipe[0],&rrfs)) { 02722 len=read(tmp->pipe[0],tmp->ast_rd_buf,sizeof(tmp->ast_rd_buf)); 02723 02724 if (len<=0) { 02725 /* we hangup here, since our pipe is closed */ 02726 chan_misdn_log(2,tmp->bc->port,"misdn_read: Pipe closed, hanging up\n"); 02727 return NULL; 02728 } 02729 02730 } else { 02731 return NULL; 02732 } 02733 02734 tmp->frame.frametype = AST_FRAME_VOICE; 02735 tmp->frame.subclass = AST_FORMAT_ALAW; 02736 tmp->frame.datalen = len; 02737 tmp->frame.samples = len; 02738 tmp->frame.mallocd = 0; 02739 tmp->frame.offset = 0; 02740 tmp->frame.delivery= ast_tv(0,0) ; 02741 tmp->frame.src = NULL; 02742 tmp->frame.data = tmp->ast_rd_buf; 02743 02744 if (tmp->faxdetect && !tmp->faxhandled) { 02745 if (tmp->faxdetect_timeout) { 02746 if (ast_tvzero(tmp->faxdetect_tv)) { 02747 tmp->faxdetect_tv = ast_tvnow(); 02748 chan_misdn_log(2,tmp->bc->port,"faxdetect: starting detection with timeout: %ds ...\n", tmp->faxdetect_timeout); 02749 return process_ast_dsp(tmp, &tmp->frame); 02750 } else { 02751 struct timeval tv_now = ast_tvnow(); 02752 int diff = ast_tvdiff_ms(tv_now, tmp->faxdetect_tv); 02753 if (diff <= (tmp->faxdetect_timeout * 1000)) { 02754 chan_misdn_log(5,tmp->bc->port,"faxdetect: detecting ...\n"); 02755 return process_ast_dsp(tmp, &tmp->frame); 02756 } else { 02757 chan_misdn_log(2,tmp->bc->port,"faxdetect: stopping detection (time ran out) ...\n"); 02758 tmp->faxdetect = 0; 02759 return &tmp->frame; 02760 } 02761 } 02762 } else { 02763 chan_misdn_log(5,tmp->bc->port,"faxdetect: detecting ... (no timeout)\n"); 02764 return process_ast_dsp(tmp, &tmp->frame); 02765 } 02766 } else { 02767 if (tmp->ast_dsp) 02768 return process_ast_dsp(tmp, &tmp->frame); 02769 else 02770 return &tmp->frame; 02771 } 02772 }
static int misdn_reload | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1064 of file chan_misdn.c.
References ast_cli(), and reload_config().
01065 { 01066 ast_cli(fd, "Reloading mISDN Config\n"); 01067 reload_config(); 01068 return 0; 01069 }
static struct ast_channel* misdn_request | ( | const char * | type, | |
int | format, | |||
void * | data, | |||
int * | cause | |||
) | [static] |
Definition at line 3089 of file chan_misdn.c.
References chan_list::ast, ast_log(), AST_STATE_RESERVED, ast_strlen_zero(), chan_list::bc, BUFFERSIZE, chan_misdn_log(), misdn_bchannel::channel, robin_list::channel, cl_queue_chan(), cl_te, misdn_bchannel::dec, ext, get_robin_position(), group, init_chan_list(), LOG_ERROR, LOG_WARNING, METHOD_ROUND_ROBIN, METHOD_STANDARD_DEC, misdn_cfg_get(), misdn_cfg_get_next_port(), misdn_cfg_get_next_port_spin(), MISDN_CFG_GROUPNAME, misdn_cfg_is_group_method(), MISDN_CFG_PMP_L1_CHECK, misdn_lib_get_free_bc(), misdn_lib_get_maxchans(), misdn_lib_port_up(), misdn_new(), misdn_type, chan_list::need_hangup, ORG_AST, misdn_bchannel::port, robin_list::port, and read_config().
03091 { 03092 struct ast_channel *tmp = NULL; 03093 char group[BUFFERSIZE+1]=""; 03094 char buf[128]; 03095 char buf2[128], *ext=NULL, *port_str; 03096 char *tokb=NULL, *p=NULL; 03097 int channel=0, port=0; 03098 struct misdn_bchannel *newbc = NULL; 03099 int dec=0; 03100 03101 struct chan_list *cl=init_chan_list(ORG_AST); 03102 03103 sprintf(buf,"%s/%s",misdn_type,(char*)data); 03104 ast_copy_string(buf2,data, 128); 03105 03106 port_str=strtok_r(buf2,"/", &tokb); 03107 03108 ext=strtok_r(NULL,"/", &tokb); 03109 03110 if (port_str) { 03111 if (port_str[0]=='g' && port_str[1]==':' ) { 03112 /* We make a group call lets checkout which ports are in my group */ 03113 port_str += 2; 03114 strncpy(group, port_str, BUFFERSIZE); 03115 group[127] = 0; 03116 chan_misdn_log(2, 0, " --> Group Call group: %s\n",group); 03117 } 03118 else if ((p = strchr(port_str, ':'))) { 03119 /* we have a preselected channel */ 03120 *p = 0; 03121 channel = atoi(++p); 03122 port = atoi(port_str); 03123 chan_misdn_log(2, port, " --> Call on preselected Channel (%d).\n", channel); 03124 } 03125 else { 03126 port = atoi(port_str); 03127 } 03128 } else { 03129 ast_log(LOG_WARNING, " --> ! IND : CALL dad:%s WITHOUT PORT/Group, check extension.conf\n",ext); 03130 return NULL; 03131 } 03132 03133 if (misdn_cfg_is_group_method(group, METHOD_STANDARD_DEC)) { 03134 chan_misdn_log(4, port, " --> STARTING STANDARDDEC...\n"); 03135 dec=1; 03136 } 03137 03138 if (!ast_strlen_zero(group)) { 03139 03140 char cfg_group[BUFFERSIZE+1]; 03141 struct robin_list *rr = NULL; 03142 03143 if (misdn_cfg_is_group_method(group, METHOD_ROUND_ROBIN)) { 03144 chan_misdn_log(4, port, " --> STARTING ROUND ROBIN...\n"); 03145 rr = get_robin_position(group); 03146 } 03147 03148 if (rr) { 03149 int port_start = 0; 03150 int port_bak = rr->port; 03151 int chan_bak = rr->channel; 03152 03153 if (!rr->port) 03154 rr->port = misdn_cfg_get_next_port_spin(rr->port); 03155 03156 for (; rr->port > 0; rr->port = misdn_cfg_get_next_port_spin(rr->port)) { 03157 int port_up; 03158 int check; 03159 int max_chan; 03160 int last_chance = 0; 03161 03162 misdn_cfg_get(rr->port, MISDN_CFG_GROUPNAME, cfg_group, BUFFERSIZE); 03163 if (strcasecmp(cfg_group, group)) 03164 continue; 03165 03166 misdn_cfg_get(rr->port, MISDN_CFG_PMP_L1_CHECK, &check, sizeof(int)); 03167 port_up = misdn_lib_port_up(rr->port, check); 03168 03169 if (check && !port_up) 03170 chan_misdn_log(1, rr->port, "L1 is not Up on this Port\n"); 03171 03172 if (check && port_up < 0) 03173 ast_log(LOG_WARNING,"This port (%d) is blocked\n", rr->port); 03174 03175 if ((port_start == rr->port) && (port_up <= 0)) 03176 break; 03177 03178 if (!port_start) 03179 port_start = rr->port; 03180 03181 if (port_up <= 0) 03182 continue; 03183 03184 max_chan = misdn_lib_get_maxchans(rr->port); 03185 03186 for (++rr->channel; !last_chance && rr->channel <= max_chan; ++rr->channel) { 03187 if (rr->port == port_bak && rr->channel == chan_bak) 03188 last_chance = 1; 03189 03190 chan_misdn_log(1, 0, "trying port:%d channel:%d\n", rr->port, rr->channel); 03191 newbc = misdn_lib_get_free_bc(rr->port, rr->channel, 0, 0); 03192 if (newbc) { 03193 chan_misdn_log(4, rr->port, " Success! Found port:%d channel:%d\n", newbc->port, newbc->channel); 03194 if (port_up) 03195 chan_misdn_log(4, rr->port, "portup:%d\n", port_up); 03196 port = rr->port; 03197 break; 03198 } 03199 } 03200 03201 if (newbc || last_chance) 03202 break; 03203 03204 rr->channel = 0; 03205 } 03206 if (!newbc) { 03207 rr->port = port_bak; 03208 rr->channel = chan_bak; 03209 } 03210 } else { 03211 for (port=misdn_cfg_get_next_port(0); port > 0; 03212 port=misdn_cfg_get_next_port(port)) { 03213 03214 misdn_cfg_get( port, MISDN_CFG_GROUPNAME, cfg_group, BUFFERSIZE); 03215 03216 chan_misdn_log(3,port, "Group [%s] Port [%d]\n", group, port); 03217 if (!strcasecmp(cfg_group, group)) { 03218 int port_up; 03219 int check; 03220 misdn_cfg_get(port, MISDN_CFG_PMP_L1_CHECK, &check, sizeof(int)); 03221 port_up = misdn_lib_port_up(port, check); 03222 03223 chan_misdn_log(4, port, "portup:%d\n", port_up); 03224 03225 if ( port_up>0 ) { 03226 newbc = misdn_lib_get_free_bc(port, 0, 0, dec); 03227 if (newbc) 03228 break; 03229 } 03230 } 03231 } 03232 } 03233 03234 /* Group dial failed ?*/ 03235 if (!newbc) { 03236 ast_log(LOG_WARNING, 03237 "Could not Dial out on group '%s'.\n" 03238 "\tEither the L2 and L1 on all of these ports where DOWN (see 'show application misdn_check_l2l1')\n" 03239 "\tOr there was no free channel on none of the ports\n\n" 03240 , group); 03241 return NULL; 03242 } 03243 } else { /* 'Normal' Port dial * Port dial */ 03244 if (channel) 03245 chan_misdn_log(1, port," --> preselected_channel: %d\n",channel); 03246 newbc = misdn_lib_get_free_bc(port, channel, 0, dec); 03247 03248 if (!newbc) { 03249 ast_log(LOG_WARNING, "Could not create channel on port:%d with extensions:%s\n",port,ext); 03250 return NULL; 03251 } 03252 } 03253 03254 03255 /* create ast_channel and link all the objects together */ 03256 cl->bc=newbc; 03257 03258 tmp = misdn_new(cl, AST_STATE_RESERVED, ext, NULL, format, port, channel); 03259 if (!tmp) { 03260 ast_log(LOG_ERROR,"Could not create Asterisk object\n"); 03261 return NULL; 03262 } 03263 03264 cl->ast=tmp; 03265 03266 /* register chan in local list */ 03267 cl_queue_chan(&cl_te, cl) ; 03268 03269 /* fill in the config into the objects */ 03270 read_config(cl, ORG_AST); 03271 03272 /* important */ 03273 cl->need_hangup=0; 03274 03275 return tmp; 03276 }
static int misdn_restart_pid | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 851 of file chan_misdn.c.
References misdn_lib_pid_restart(), and RESULT_SHOWUSAGE.
00852 { 00853 int pid; 00854 00855 if (argc != 4) 00856 return RESULT_SHOWUSAGE; 00857 00858 pid = atoi(argv[3]); 00859 00860 misdn_lib_pid_restart(pid); 00861 00862 return 0; 00863 }
static int misdn_restart_port | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 837 of file chan_misdn.c.
References misdn_lib_port_restart(), and RESULT_SHOWUSAGE.
00838 { 00839 int port; 00840 00841 if (argc != 4) 00842 return RESULT_SHOWUSAGE; 00843 00844 port = atoi(argv[3]); 00845 00846 misdn_lib_port_restart(port); 00847 00848 return 0; 00849 }
static int misdn_send_cd | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1259 of file chan_misdn.c.
References ast_cli(), chan_list::bc, EVENT_FACILITY, misdn_bchannel::fac_out, get_chan_by_ast_name(), misdn_lib_send_event(), and RESULT_SHOWUSAGE.
01260 { 01261 char *channame; 01262 char *nr; 01263 01264 if (argc != 5) 01265 return RESULT_SHOWUSAGE; 01266 01267 channame = argv[3]; 01268 nr = argv[4]; 01269 01270 ast_cli(fd, "Sending Calldeflection (%s) to %s\n",nr, channame); 01271 01272 { 01273 struct chan_list *tmp=get_chan_by_ast_name(channame); 01274 01275 if (!tmp) { 01276 ast_cli(fd, "Sending CD with nr %s to %s failed: Channel does not exist.\n",nr, channame); 01277 return 0; 01278 } else { 01279 if (strlen(nr) >= 15) { 01280 ast_cli(fd, "Sending CD with nr %s to %s failed: Number too long (up to 15 digits are allowed).\n",nr, channame); 01281 return 0; 01282 } 01283 tmp->bc->fac_out.Function = Fac_CD; 01284 strncpy((char *)tmp->bc->fac_out.u.CDeflection.DeflectedToNumber, nr, sizeof(tmp->bc->fac_out.u.CDeflection.DeflectedToNumber)); 01285 misdn_lib_send_event(tmp->bc, EVENT_FACILITY); 01286 } 01287 } 01288 01289 return 0; 01290 }
static int misdn_send_digit | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1311 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().
01312 { 01313 char *channame; 01314 char *msg; 01315 01316 if (argc != 5) 01317 return RESULT_SHOWUSAGE; 01318 01319 channame = argv[3]; 01320 msg = argv[4]; 01321 01322 ast_cli(fd, "Sending %s to %s\n",msg, channame); 01323 01324 { 01325 struct chan_list *tmp=get_chan_by_ast_name(channame); 01326 01327 if (!tmp) { 01328 ast_cli(fd, "Sending %s to %s failed Channel does not exist\n",msg, channame); 01329 return 0; 01330 } else { 01331 #if 1 01332 int i; 01333 int msglen = strlen(msg); 01334 for (i=0; i<msglen; i++) { 01335 ast_cli(fd, "Sending: %c\n",msg[i]); 01336 send_digit_to_chan(tmp, msg[i]); 01337 /* res = ast_safe_sleep(tmp->ast, 250); */ 01338 usleep(250000); 01339 /* res = ast_waitfor(tmp->ast,100); */ 01340 } 01341 #else 01342 int res; 01343 res = ast_dtmf_stream(tmp->ast,NULL,msg,250); 01344 #endif 01345 } 01346 } 01347 01348 return 0; 01349 }
static int misdn_send_display | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1388 of file chan_misdn.c.
References ast_cli(), chan_list::bc, misdn_bchannel::display, EVENT_INFORMATION, get_chan_by_ast_name(), misdn_lib_send_event(), RESULT_FAILURE, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
01389 { 01390 char *channame; 01391 char *msg; 01392 01393 if (argc != 5) 01394 return RESULT_SHOWUSAGE; 01395 01396 channame = argv[3]; 01397 msg = argv[4]; 01398 01399 ast_cli(fd, "Sending %s to %s\n",msg, channame); 01400 { 01401 struct chan_list *tmp; 01402 tmp=get_chan_by_ast_name(channame); 01403 01404 if (tmp && tmp->bc) { 01405 ast_copy_string(tmp->bc->display, msg, sizeof(tmp->bc->display)); 01406 misdn_lib_send_event(tmp->bc, EVENT_INFORMATION); 01407 } else { 01408 ast_cli(fd,"No such channel %s\n",channame); 01409 return RESULT_FAILURE; 01410 } 01411 } 01412 01413 return RESULT_SUCCESS ; 01414 }
static int misdn_send_restart | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1292 of file chan_misdn.c.
References misdn_lib_send_restart(), and RESULT_SHOWUSAGE.
01293 { 01294 int port; 01295 int channel; 01296 01297 if ( (argc < 4) || (argc > 5) ) 01298 return RESULT_SHOWUSAGE; 01299 01300 port = atoi(argv[3]); 01301 01302 if (argc==5) { 01303 channel = atoi(argv[4]); 01304 misdn_lib_send_restart(port, channel); 01305 } else 01306 misdn_lib_send_restart(port, -1 ); 01307 01308 return 0; 01309 }
static int misdn_send_text | ( | struct ast_channel * | chan, | |
const char * | text | |||
) | [static] |
Definition at line 3279 of file chan_misdn.c.
References ast_log(), chan_list::bc, misdn_bchannel::display, EVENT_INFORMATION, LOG_WARNING, misdn_lib_send_event(), and ast_channel::tech_pvt.
03280 { 03281 struct chan_list *tmp=chan->tech_pvt; 03282 03283 if (tmp && tmp->bc) { 03284 ast_copy_string(tmp->bc->display,text,sizeof(tmp->bc->display)); 03285 misdn_lib_send_event(tmp->bc, EVENT_INFORMATION); 03286 } else { 03287 ast_log(LOG_WARNING, "No chan_list but send_text request?\n"); 03288 return -1; 03289 } 03290 03291 return 0; 03292 }
static int misdn_set_crypt_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 801 of file chan_misdn.c.
References RESULT_SHOWUSAGE.
00802 { 00803 if (argc != 5) return RESULT_SHOWUSAGE; 00804 00805 return 0; 00806 }
static int misdn_set_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 741 of file chan_misdn.c.
References ast_cli(), and RESULT_SHOWUSAGE.
00742 { 00743 int level; 00744 00745 if (argc != 4 && argc != 5 && argc != 6 && argc != 7) 00746 return RESULT_SHOWUSAGE; 00747 00748 level = atoi(argv[3]); 00749 00750 switch (argc) { 00751 case 4: 00752 case 5: { 00753 int i; 00754 int only = 0; 00755 if (argc == 5) { 00756 if (strncasecmp(argv[4], "only", strlen(argv[4]))) 00757 return RESULT_SHOWUSAGE; 00758 else 00759 only = 1; 00760 } 00761 for (i=0; i<=max_ports; i++) { 00762 misdn_debug[i] = level; 00763 misdn_debug_only[i] = only; 00764 } 00765 ast_cli(fd, "changing debug level for all ports to %d%s\n",misdn_debug[0], only?" (only)":""); 00766 } 00767 break; 00768 case 6: 00769 case 7: { 00770 int port; 00771 if (strncasecmp(argv[4], "port", strlen(argv[4]))) 00772 return RESULT_SHOWUSAGE; 00773 port = atoi(argv[5]); 00774 if (port <= 0 || port > max_ports) { 00775 switch (max_ports) { 00776 case 0: 00777 ast_cli(fd, "port number not valid! no ports available so you won't get lucky with any number here...\n"); 00778 break; 00779 case 1: 00780 ast_cli(fd, "port number not valid! only port 1 is availble.\n"); 00781 break; 00782 default: 00783 ast_cli(fd, "port number not valid! only ports 1 to %d are available.\n", max_ports); 00784 } 00785 return 0; 00786 } 00787 if (argc == 7) { 00788 if (strncasecmp(argv[6], "only", strlen(argv[6]))) 00789 return RESULT_SHOWUSAGE; 00790 else 00791 misdn_debug_only[port] = 1; 00792 } else 00793 misdn_debug_only[port] = 0; 00794 misdn_debug[port] = level; 00795 ast_cli(fd, "changing debug level to %d%s for port %d\n", misdn_debug[port], misdn_debug_only[port]?" (only)":"", port); 00796 } 00797 } 00798 return 0; 00799 }
static int misdn_set_opt_exec | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Definition at line 5251 of file chan_misdn.c.
References chan_list::ast_dsp, ast_dsp_new(), ast_dsp_set_features(), AST_FORMAT_ALAW, AST_FORMAT_SLINEAR, ast_log(), ast_strlen_zero(), ast_translator_build_path(), chan_list::bc, 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, strsep(), ast_channel::tech, misdn_bchannel::txgain, and ast_channel_tech::type.
Referenced by load_module(), and misdn_call().
05252 { 05253 struct chan_list *ch = MISDN_ASTERISK_TECH_PVT(chan); 05254 char *tok,*tokb; 05255 int keyidx=0; 05256 int rxgain=0; 05257 int txgain=0; 05258 int change_jitter=0; 05259 05260 if (strcasecmp(chan->tech->type,"mISDN")) { 05261 ast_log(LOG_WARNING, "misdn_set_opt makes only sense with chan_misdn channels!\n"); 05262 return -1; 05263 } 05264 05265 if (ast_strlen_zero((char *)data)) { 05266 ast_log(LOG_WARNING, "misdn_set_opt Requires arguments\n"); 05267 return -1; 05268 } 05269 05270 for (tok=strtok_r((char*)data, ":",&tokb); 05271 tok; 05272 tok=strtok_r(NULL,":",&tokb) ) { 05273 char keys[4096]; 05274 char *key, *tmp; 05275 int i; 05276 int neglect=0; 05277 05278 if (tok[0] == '!' ) { 05279 neglect=1; 05280 tok++; 05281 } 05282 05283 switch(tok[0]) { 05284 05285 case 'd' : 05286 ast_copy_string(ch->bc->display,++tok,84); 05287 chan_misdn_log(1, ch->bc->port, "SETOPT: Display:%s\n",ch->bc->display); 05288 break; 05289 05290 case 'n': 05291 chan_misdn_log(1, ch->bc->port, "SETOPT: No DSP\n"); 05292 ch->bc->nodsp=1; 05293 break; 05294 05295 case 'j': 05296 chan_misdn_log(1, ch->bc->port, "SETOPT: jitter\n"); 05297 tok++; 05298 change_jitter=1; 05299 05300 switch ( tok[0] ) { 05301 case 'b' : 05302 ch->jb_len=atoi(++tok); 05303 chan_misdn_log(1, ch->bc->port, " --> buffer_len:%d\n",ch->jb_len); 05304 break; 05305 case 't' : 05306 ch->jb_upper_threshold=atoi(++tok); 05307 chan_misdn_log(1, ch->bc->port, " --> upper_threshold:%d\n",ch->jb_upper_threshold); 05308 break; 05309 05310 case 'n': 05311 ch->bc->nojitter=1; 05312 chan_misdn_log(1, ch->bc->port, " --> nojitter\n"); 05313 break; 05314 05315 default: 05316 ch->jb_len=4000; 05317 ch->jb_upper_threshold=0; 05318 chan_misdn_log(1, ch->bc->port, " --> buffer_len:%d (default)\n",ch->jb_len); 05319 chan_misdn_log(1, ch->bc->port, " --> upper_threshold:%d (default)\n",ch->jb_upper_threshold); 05320 } 05321 05322 break; 05323 05324 case 'v': 05325 tok++; 05326 05327 switch ( tok[0] ) { 05328 case 'r' : 05329 rxgain=atoi(++tok); 05330 if (rxgain<-8) rxgain=-8; 05331 if (rxgain>8) rxgain=8; 05332 ch->bc->rxgain=rxgain; 05333 chan_misdn_log(1, ch->bc->port, "SETOPT: Volume:%d\n",rxgain); 05334 break; 05335 case 't': 05336 txgain=atoi(++tok); 05337 if (txgain<-8) txgain=-8; 05338 if (txgain>8) txgain=8; 05339 ch->bc->txgain=txgain; 05340 chan_misdn_log(1, ch->bc->port, "SETOPT: Volume:%d\n",txgain); 05341 break; 05342 } 05343 break; 05344 05345 case 'c': 05346 keyidx=atoi(++tok); 05347 key=NULL; 05348 misdn_cfg_get( 0, MISDN_GEN_CRYPT_KEYS, keys, sizeof(keys)); 05349 05350 tmp=keys; 05351 05352 for (i=0; i<keyidx; i++) { 05353 key=strsep(&tmp,","); 05354 } 05355 05356 if (key) { 05357 ast_copy_string(ch->bc->crypt_key, key, sizeof(ch->bc->crypt_key)); 05358 } 05359 05360 chan_misdn_log(0, ch->bc->port, "SETOPT: crypt with key:%s\n",ch->bc->crypt_key); 05361 break; 05362 05363 case 'e': 05364 chan_misdn_log(1, ch->bc->port, "SETOPT: EchoCancel\n"); 05365 05366 if (neglect) { 05367 chan_misdn_log(1, ch->bc->port, " --> disabled\n"); 05368 #ifdef MISDN_1_2 05369 *ch->bc->pipeline=0; 05370 #else 05371 ch->bc->ec_enable=0; 05372 #endif 05373 } else { 05374 #ifdef MISDN_1_2 05375 update_pipeline_config(ch->bc); 05376 #else 05377 ch->bc->ec_enable=1; 05378 ch->bc->orig=ch->originator; 05379 tok++; 05380 if (*tok) { 05381 ch->bc->ec_deftaps=atoi(tok); 05382 } 05383 #endif 05384 } 05385 05386 break; 05387 05388 case 'h': 05389 chan_misdn_log(1, ch->bc->port, "SETOPT: Digital\n"); 05390 05391 if (strlen(tok) > 1 && tok[1]=='1') { 05392 chan_misdn_log(1, ch->bc->port, "SETOPT: HDLC \n"); 05393 if (!ch->bc->hdlc) { 05394 ch->bc->hdlc=1; 05395 } 05396 } 05397 ch->bc->capability=INFO_CAPABILITY_DIGITAL_UNRESTRICTED; 05398 break; 05399 05400 case 's': 05401 chan_misdn_log(1, ch->bc->port, "SETOPT: Send DTMF\n"); 05402 ch->bc->send_dtmf=1; 05403 break; 05404 05405 case 'f': 05406 chan_misdn_log(1, ch->bc->port, "SETOPT: Faxdetect\n"); 05407 ch->faxdetect=1; 05408 misdn_cfg_get(ch->bc->port, MISDN_CFG_FAXDETECT_TIMEOUT, &ch->faxdetect_timeout, sizeof(ch->faxdetect_timeout)); 05409 break; 05410 05411 case 'a': 05412 chan_misdn_log(1, ch->bc->port, "SETOPT: AST_DSP (for DTMF)\n"); 05413 ch->ast_dsp=1; 05414 break; 05415 05416 case 'p': 05417 chan_misdn_log(1, ch->bc->port, "SETOPT: callerpres: %s\n",&tok[1]); 05418 /* CRICH: callingpres!!! */ 05419 if (strstr(tok,"allowed") ) { 05420 ch->bc->pres=0; 05421 } else if (strstr(tok,"not_screened")) { 05422 ch->bc->pres=1; 05423 } 05424 break; 05425 case 'i' : 05426 chan_misdn_log(1, ch->bc->port, "Ignoring dtmf tones, just use them inband\n"); 05427 ch->ignore_dtmf=1; 05428 break; 05429 default: 05430 break; 05431 } 05432 } 05433 05434 if (change_jitter) 05435 config_jitterbuffer(ch); 05436 05437 05438 if (ch->faxdetect || ch->ast_dsp) { 05439 if (!ch->dsp) ch->dsp = ast_dsp_new(); 05440 if (ch->dsp) ast_dsp_set_features(ch->dsp, DSP_FEATURE_DTMF_DETECT| DSP_FEATURE_FAX_DETECT); 05441 if (!ch->trans) ch->trans=ast_translator_build_path(AST_FORMAT_SLINEAR, AST_FORMAT_ALAW); 05442 } 05443 05444 if (ch->ast_dsp) { 05445 chan_misdn_log(1,ch->bc->port,"SETOPT: with AST_DSP we deactivate mISDN_dsp\n"); 05446 ch->bc->nodsp=1; 05447 ch->bc->nojitter=1; 05448 } 05449 05450 return 0; 05451 }
static int misdn_set_tics | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1196 of file chan_misdn.c.
References MAXTICS, and RESULT_SHOWUSAGE.
01197 { 01198 if (argc != 4) 01199 return RESULT_SHOWUSAGE; 01200 01201 MAXTICS=atoi(argv[3]); 01202 01203 return 0; 01204 }
static int misdn_show_cl | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1170 of file chan_misdn.c.
References chan_list::ast, chan_list::bc, cl_te, chan_list::next, print_bc_info(), and RESULT_SHOWUSAGE.
01171 { 01172 struct chan_list *help=cl_te; 01173 01174 if (argc != 4) 01175 return RESULT_SHOWUSAGE; 01176 01177 for (;help; help=help->next) { 01178 struct misdn_bchannel *bc=help->bc; 01179 struct ast_channel *ast=help->ast; 01180 01181 if (bc && ast) { 01182 if (!strcasecmp(ast->name,argv[3])) { 01183 print_bc_info(fd, help, bc); 01184 break; 01185 } 01186 } 01187 } 01188 01189 01190 return 0; 01191 }
static int misdn_show_cls | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1126 of file chan_misdn.c.
References chan_list::ast, ast_cli(), chan_list::bc, hold_info::channel, ast_channel::cid, ast_callerid::cid_num, cl_te, ast_channel::exten, chan_list::hold_info, chan_list::l3id, misdn_dump_chanlist(), MISDN_HOLDED, chan_list::next, misdn_bchannel::pid, hold_info::port, print_bc_info(), and chan_list::state.
01127 { 01128 struct chan_list *help=cl_te; 01129 01130 ast_cli(fd,"Chan List: %p\n",cl_te); 01131 01132 for (;help; help=help->next) { 01133 struct misdn_bchannel *bc=help->bc; 01134 struct ast_channel *ast=help->ast; 01135 if (!ast) { 01136 if (!bc) { 01137 ast_cli(fd, "chan_list obj. with l3id:%x has no bc and no ast Leg\n", help->l3id); 01138 continue; 01139 } 01140 ast_cli(fd, "bc with pid:%d has no Ast Leg\n", bc->pid); 01141 continue; 01142 } 01143 if (misdn_debug[0] > 2) ast_cli(fd, "Bc:%p Ast:%p\n", bc, ast); 01144 if (bc) { 01145 print_bc_info(fd, help, bc); 01146 } else { 01147 if (help->state == MISDN_HOLDED) { 01148 ast_cli(fd, "ITS A HOLDED BC:\n"); 01149 ast_cli(fd, " --> l3_id: %x\n" 01150 " --> dad:%s oad:%s\n" 01151 " --> hold_port: %d\n" 01152 " --> hold_channel: %d\n" 01153 01154 ,help->l3id 01155 ,ast->exten 01156 ,ast->cid.cid_num 01157 ,help->hold_info.port 01158 ,help->hold_info.channel 01159 ); 01160 } else { 01161 ast_cli(fd,"* Channel in unknown STATE !!! Exten:%s, Callerid:%s\n", ast->exten, ast->cid.cid_num); 01162 } 01163 } 01164 } 01165 01166 misdn_dump_chanlist(); 01167 return 0; 01168 }
static int misdn_show_config | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 916 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().
00917 { 00918 char buffer[BUFFERSIZE]; 00919 enum misdn_cfg_elements elem; 00920 int linebreak; 00921 int onlyport = -1; 00922 int ok = 0; 00923 00924 if (argc >= 4) { 00925 if (!strcmp(argv[3], "description")) { 00926 if (argc == 5) { 00927 enum misdn_cfg_elements elem = misdn_cfg_get_elem (argv[4]); 00928 if (elem == MISDN_CFG_FIRST) 00929 ast_cli(fd, "Unknown element: %s\n", argv[4]); 00930 else 00931 show_config_description(fd, elem); 00932 return 0; 00933 } 00934 return RESULT_SHOWUSAGE; 00935 } 00936 if (!strcmp(argv[3], "descriptions")) { 00937 if ((argc == 4) || ((argc == 5) && !strcmp(argv[4], "general"))) { 00938 for (elem = MISDN_GEN_FIRST + 1; elem < MISDN_GEN_LAST; ++elem) { 00939 show_config_description(fd, elem); 00940 ast_cli(fd, "\n"); 00941 } 00942 ok = 1; 00943 } 00944 if ((argc == 4) || ((argc == 5) && !strcmp(argv[4], "ports"))) { 00945 for (elem = MISDN_CFG_FIRST + 1; elem < MISDN_CFG_LAST - 1 /* the ptp hack, remove the -1 when ptp is gone */; ++elem) { 00946 show_config_description(fd, elem); 00947 ast_cli(fd, "\n"); 00948 } 00949 ok = 1; 00950 } 00951 return ok ? 0 : RESULT_SHOWUSAGE; 00952 } 00953 if (!sscanf(argv[3], "%d", &onlyport) || onlyport < 0) { 00954 ast_cli(fd, "Unknown option: %s\n", argv[3]); 00955 return RESULT_SHOWUSAGE; 00956 } 00957 } 00958 00959 if (argc == 3 || onlyport == 0) { 00960 ast_cli(fd,"Misdn General-Config: \n"); 00961 for (elem = MISDN_GEN_FIRST + 1, linebreak = 1; elem < MISDN_GEN_LAST; elem++, linebreak++) { 00962 misdn_cfg_get_config_string( 0, elem, buffer, BUFFERSIZE); 00963 ast_cli(fd, "%-36s%s", buffer, !(linebreak % 2) ? "\n" : ""); 00964 } 00965 ast_cli(fd, "\n"); 00966 } 00967 00968 if (onlyport < 0) { 00969 int port = misdn_cfg_get_next_port(0); 00970 for (; port > 0; port = misdn_cfg_get_next_port(port)) { 00971 ast_cli(fd, "\n[PORT %d]\n", port); 00972 for (elem = MISDN_CFG_FIRST + 1, linebreak = 1; elem < MISDN_CFG_LAST; elem++, linebreak++) { 00973 misdn_cfg_get_config_string( port, elem, buffer, BUFFERSIZE); 00974 ast_cli(fd, "%-36s%s", buffer, !(linebreak % 2) ? "\n" : ""); 00975 } 00976 ast_cli(fd, "\n"); 00977 } 00978 } 00979 00980 if (onlyport > 0) { 00981 if (misdn_cfg_is_port_valid(onlyport)) { 00982 ast_cli(fd, "[PORT %d]\n", onlyport); 00983 for (elem = MISDN_CFG_FIRST + 1, linebreak = 1; elem < MISDN_CFG_LAST; elem++, linebreak++) { 00984 misdn_cfg_get_config_string(onlyport, elem, buffer, BUFFERSIZE); 00985 ast_cli(fd, "%-36s%s", buffer, !(linebreak % 2) ? "\n" : ""); 00986 } 00987 ast_cli(fd, "\n"); 00988 } else { 00989 ast_cli(fd, "Port %d is not active!\n", onlyport); 00990 } 00991 } 00992 return 0; 00993 }
static int misdn_show_port | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1240 of file chan_misdn.c.
References ast_cli(), get_show_stack_details(), misdn_debug, misdn_debug_only, and RESULT_SHOWUSAGE.
01241 { 01242 int port; 01243 char buf[128]; 01244 01245 if (argc != 4) 01246 return RESULT_SHOWUSAGE; 01247 01248 port = atoi(argv[3]); 01249 01250 ast_cli(fd, "BEGIN STACK_LIST:\n"); 01251 01252 get_show_stack_details(port,buf); 01253 ast_cli(fd," %s Debug:%d%s\n",buf, misdn_debug[port], misdn_debug_only[port]?"(only)":""); 01254 01255 01256 return 0; 01257 }
static int misdn_show_ports_stats | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1223 of file chan_misdn.c.
References ast_cli(), misdn_cfg_get_next_port(), misdn_in_calls, and misdn_out_calls.
01224 { 01225 int port; 01226 01227 ast_cli(fd, "Port\tin_calls\tout_calls\n"); 01228 01229 for (port=misdn_cfg_get_next_port(0); port > 0; 01230 port=misdn_cfg_get_next_port(port)) { 01231 ast_cli(fd,"%d\t%d\t\t%d\n",port,misdn_in_calls[port],misdn_out_calls[port]); 01232 } 01233 ast_cli(fd,"\n"); 01234 01235 return 0; 01236 01237 }
static int misdn_show_stacks | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1206 of file chan_misdn.c.
References ast_cli(), get_show_stack_details(), misdn_cfg_get_next_port(), misdn_debug, and misdn_debug_only.
01207 { 01208 int port; 01209 01210 ast_cli(fd, "BEGIN STACK_LIST:\n"); 01211 01212 for (port=misdn_cfg_get_next_port(0); port > 0; 01213 port=misdn_cfg_get_next_port(port)) { 01214 char buf[128]; 01215 get_show_stack_details(port,buf); 01216 ast_cli(fd," %s Debug:%d%s\n", buf, misdn_debug[port], misdn_debug_only[port]?"(only)":""); 01217 } 01218 01219 return 0; 01220 }
static int misdn_tasks_add | ( | int | timeout, | |
ast_sched_cb | callback, | |||
const void * | data | |||
) | [static] |
Definition at line 631 of file chan_misdn.c.
References _misdn_tasks_add_variable().
Referenced by load_module().
00632 { 00633 return _misdn_tasks_add_variable(timeout, callback, data, 0); 00634 }
static int misdn_tasks_add_variable | ( | int | timeout, | |
ast_sched_cb | callback, | |||
const void * | data | |||
) | [static] |
Definition at line 636 of file chan_misdn.c.
References _misdn_tasks_add_variable().
Referenced by cb_events().
00637 { 00638 return _misdn_tasks_add_variable(timeout, callback, data, 1); 00639 }
static void misdn_tasks_destroy | ( | void | ) | [static] |
Definition at line 601 of file chan_misdn.c.
References cb_log, chan_misdn_log(), misdn_tasks, and sched_context_destroy().
Referenced by unload_module().
00602 { 00603 if (misdn_tasks) { 00604 chan_misdn_log(4, 0, "Killing misdn_tasks thread\n"); 00605 if ( pthread_cancel(misdn_tasks_thread) == 0 ) { 00606 cb_log(4, 0, "Joining misdn_tasks thread\n"); 00607 pthread_join(misdn_tasks_thread, NULL); 00608 } 00609 sched_context_destroy(misdn_tasks); 00610 } 00611 }
static void misdn_tasks_init | ( | void | ) | [static] |
Definition at line 582 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().
00583 { 00584 sem_t blocker; 00585 int i = 5; 00586 00587 if (sem_init(&blocker, 0, 0)) { 00588 perror("chan_misdn: Failed to initialize semaphore!"); 00589 exit(1); 00590 } 00591 00592 chan_misdn_log(4, 0, "Starting misdn_tasks thread\n"); 00593 00594 misdn_tasks = sched_context_create(); 00595 pthread_create(&misdn_tasks_thread, NULL, misdn_tasks_thread_func, &blocker); 00596 00597 while (sem_wait(&blocker) && --i); 00598 sem_destroy(&blocker); 00599 }
static void misdn_tasks_remove | ( | int | task_id | ) | [static] |
Definition at line 641 of file chan_misdn.c.
References AST_SCHED_DEL, and misdn_tasks.
Referenced by release_chan().
00642 { 00643 AST_SCHED_DEL(misdn_tasks, task_id); 00644 }
static void* misdn_tasks_thread_func | ( | void * | data | ) | [static] |
Definition at line 558 of file chan_misdn.c.
References ast_sched_runq(), ast_sched_wait(), chan_misdn_log(), misdn_tasks, poll(), and sighandler().
Referenced by misdn_tasks_init().
00559 { 00560 int wait; 00561 struct sigaction sa; 00562 00563 sa.sa_handler = sighandler; 00564 sa.sa_flags = SA_NODEFER; 00565 sigemptyset(&sa.sa_mask); 00566 sigaddset(&sa.sa_mask, SIGUSR1); 00567 sigaction(SIGUSR1, &sa, NULL); 00568 00569 sem_post((sem_t *)data); 00570 00571 while (1) { 00572 wait = ast_sched_wait(misdn_tasks); 00573 if (wait < 0) 00574 wait = 8000; 00575 if (poll(NULL, 0, wait) < 0) 00576 chan_misdn_log(4, 0, "Waking up misdn_tasks thread\n"); 00577 ast_sched_runq(misdn_tasks); 00578 } 00579 return NULL; 00580 }
static void misdn_tasks_wakeup | ( | void | ) | [inline, static] |
Definition at line 613 of file chan_misdn.c.
Referenced by _misdn_tasks_add_variable().
00614 { 00615 pthread_kill(misdn_tasks_thread, SIGUSR1); 00616 }
static int misdn_toggle_echocancel | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1351 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().
01352 { 01353 char *channame; 01354 01355 if (argc != 4) 01356 return RESULT_SHOWUSAGE; 01357 01358 channame = argv[3]; 01359 01360 ast_cli(fd, "Toggling EchoCancel on %s\n", channame); 01361 01362 { 01363 struct chan_list *tmp=get_chan_by_ast_name(channame); 01364 01365 if (!tmp) { 01366 ast_cli(fd, "Toggling EchoCancel %s failed Channel does not exist\n", channame); 01367 return 0; 01368 } else { 01369 01370 tmp->toggle_ec=tmp->toggle_ec?0:1; 01371 01372 if (tmp->toggle_ec) { 01373 #ifdef MISDN_1_2 01374 update_pipeline_config(tmp->bc); 01375 #else 01376 update_ec_config(tmp->bc); 01377 #endif 01378 manager_ec_enable(tmp->bc); 01379 } else { 01380 manager_ec_disable(tmp->bc); 01381 } 01382 } 01383 } 01384 01385 return 0; 01386 }
static void misdn_transfer_bc | ( | struct chan_list * | tmp_ch, | |
struct chan_list * | holded_chan | |||
) | [static] |
Definition at line 3659 of file chan_misdn.c.
References chan_list::ast, ast_bridged_channel(), ast_channel_masquerade(), ast_moh_stop(), chan_misdn_log(), MISDN_CONNECTED, MISDN_HOLD_DISCONNECT, and chan_list::state.
03660 { 03661 chan_misdn_log(4,0,"TRANSFERING %s to %s\n",holded_chan->ast->name, tmp_ch->ast->name); 03662 03663 tmp_ch->state=MISDN_HOLD_DISCONNECT; 03664 03665 ast_moh_stop(ast_bridged_channel(holded_chan->ast)); 03666 03667 holded_chan->state=MISDN_CONNECTED; 03668 //misdn_lib_transfer(holded_chan->bc); 03669 ast_channel_masquerade(holded_chan->ast, ast_bridged_channel(tmp_ch->ast)); 03670 }
static int misdn_write | ( | struct ast_channel * | ast, | |
struct ast_frame * | frame | |||
) | [static] |
Definition at line 2775 of file chan_misdn.c.
References misdn_bchannel::addr, chan_list::ast, ast_log(), chan_list::bc, misdn_bchannel::bc_state, BCHAN_ACTIVATED, BCHAN_BRIDGED, chan_misdn_log(), ast_channel::cid, ast_callerid::cid_num, ast_frame::data, chan_list::dropped_frame_cnt, ast_channel::exten, chan_list::frame, misdn_bchannel::l3_id, LOG_WARNING, MISDN_ASTERISK_TECH_PVT, misdn_get_ch_state(), MISDN_HOLDED, misdn_lib_tone_generator_start(), chan_list::notxtone, misdn_bchannel::port, prefformat, ast_frame::samples, ast_frame::src, chan_list::state, ast_frame::subclass, and chan_list::ts.
02776 { 02777 struct chan_list *ch; 02778 int i = 0; 02779 02780 if (!ast || ! (ch=MISDN_ASTERISK_TECH_PVT(ast)) ) return -1; 02781 02782 if (ch->state == MISDN_HOLDED) { 02783 chan_misdn_log(7, 0, "misdn_write: Returning because holded\n"); 02784 return 0; 02785 } 02786 02787 if (!ch->bc ) { 02788 ast_log(LOG_WARNING, "private but no bc\n"); 02789 return -1; 02790 } 02791 02792 if (ch->notxtone) { 02793 chan_misdn_log(7, ch->bc->port, "misdn_write: Returning because notxone\n"); 02794 return 0; 02795 } 02796 02797 02798 if ( !frame->subclass) { 02799 chan_misdn_log(4, ch->bc->port, "misdn_write: * prods us\n"); 02800 return 0; 02801 } 02802 02803 if ( !(frame->subclass & prefformat)) { 02804 02805 chan_misdn_log(-1, ch->bc->port, "Got Unsupported Frame with Format:%d\n", frame->subclass); 02806 return 0; 02807 } 02808 02809 02810 if ( !frame->samples ) { 02811 chan_misdn_log(4, ch->bc->port, "misdn_write: zero write\n"); 02812 02813 if (!strcmp(frame->src,"ast_prod")) { 02814 chan_misdn_log(1, ch->bc->port, "misdn_write: state (%s) prodded.\n", misdn_get_ch_state(ch)); 02815 02816 if (ch->ts) { 02817 chan_misdn_log(4,ch->bc->port,"Starting Playtones\n"); 02818 misdn_lib_tone_generator_start(ch->bc); 02819 } 02820 return 0; 02821 } 02822 02823 return -1; 02824 } 02825 02826 if ( ! ch->bc->addr ) { 02827 chan_misdn_log(8, ch->bc->port, "misdn_write: no addr for bc dropping:%d\n", frame->samples); 02828 return 0; 02829 } 02830 02831 #if MISDN_DEBUG 02832 { 02833 int i, max=5>frame->samples?frame->samples:5; 02834 02835 printf("write2mISDN %p %d bytes: ", p, frame->samples); 02836 02837 for (i=0; i< max ; i++) printf("%2.2x ",((char*) frame->data)[i]); 02838 printf ("\n"); 02839 } 02840 #endif 02841 02842 02843 switch (ch->bc->bc_state) { 02844 case BCHAN_ACTIVATED: 02845 case BCHAN_BRIDGED: 02846 break; 02847 default: 02848 if (!ch->dropped_frame_cnt) 02849 chan_misdn_log(5, ch->bc->port, "BC not active (nor bridged) droping: %d frames addr:%x exten:%s cid:%s ch->state:%s bc_state:%d l3id:%x\n",frame->samples,ch->bc->addr, ast->exten, ast->cid.cid_num,misdn_get_ch_state( ch), ch->bc->bc_state, ch->bc->l3_id); 02850 02851 ch->dropped_frame_cnt++; 02852 if (ch->dropped_frame_cnt > 100) { 02853 ch->dropped_frame_cnt=0; 02854 chan_misdn_log(5, ch->bc->port, "BC not active (nor bridged) droping: %d frames addr:%x dropped > 100 frames!\n",frame->samples,ch->bc->addr); 02855 02856 } 02857 02858 return 0; 02859 } 02860 02861 chan_misdn_log(9, ch->bc->port, "Sending :%d bytes 2 MISDN\n",frame->samples); 02862 if ( !ch->bc->nojitter && misdn_cap_is_speech(ch->bc->capability) ) { 02863 /* Buffered Transmit (triggert by read from isdn side)*/ 02864 if (misdn_jb_fill(ch->jb,frame->data,frame->samples) < 0) { 02865 if (ch->bc->active) 02866 cb_log(0,ch->bc->port,"Misdn Jitterbuffer Overflow.\n"); 02867 } 02868 02869 } else { 02870 /*transmit without jitterbuffer*/ 02871 i=misdn_lib_tx2misdn_frm(ch->bc, frame->data, frame->samples); 02872 } 02873 02874 02875 02876 return 0; 02877 }
int pbx_start_chan | ( | struct chan_list * | ch | ) | [static] |
Channel Queue End
Definition at line 3537 of file chan_misdn.c.
References chan_list::ast, ast_pbx_start(), and chan_list::need_hangup.
Referenced by do_immediate_setup(), misdn_overlap_dial_task(), and start_pbx().
03538 { 03539 int ret=ast_pbx_start(ch->ast); 03540 03541 if (ret>=0) 03542 ch->need_hangup=0; 03543 else 03544 ch->need_hangup=1; 03545 03546 return ret; 03547 }
static void print_bc_info | ( | int | fd, | |
struct chan_list * | help, | |||
struct misdn_bchannel * | bc | |||
) | [static] |
Definition at line 1071 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(), 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().
01072 { 01073 struct ast_channel *ast=help->ast; 01074 ast_cli(fd, 01075 "* Pid:%d Prt:%d Ch:%d Mode:%s Org:%s dad:%s oad:%s rad:%s ctx:%s state:%s\n", 01076 01077 bc->pid, bc->port, bc->channel, 01078 bc->nt?"NT":"TE", 01079 help->originator == ORG_AST?"*":"I", 01080 ast?ast->exten:NULL, 01081 ast?ast->cid.cid_num:NULL, 01082 bc->rad, 01083 ast?ast->context:NULL, 01084 misdn_get_ch_state(help) 01085 ); 01086 if (misdn_debug[bc->port] > 0) 01087 ast_cli(fd, 01088 " --> astname: %s\n" 01089 " --> ch_l3id: %x\n" 01090 " --> ch_addr: %x\n" 01091 " --> bc_addr: %x\n" 01092 " --> bc_l3id: %x\n" 01093 " --> display: %s\n" 01094 " --> activated: %d\n" 01095 " --> state: %s\n" 01096 " --> capability: %s\n" 01097 #ifdef MISDN_1_2 01098 " --> pipeline: %s\n" 01099 #else 01100 " --> echo_cancel: %d\n" 01101 #endif 01102 " --> notone : rx %d tx:%d\n" 01103 " --> bc_hold: %d\n", 01104 help->ast->name, 01105 help->l3id, 01106 help->addr, 01107 bc->addr, 01108 bc?bc->l3_id:-1, 01109 bc->display, 01110 01111 bc->active, 01112 bc_state2str(bc->bc_state), 01113 bearer2str(bc->capability), 01114 #ifdef MISDN_1_2 01115 bc->pipeline, 01116 #else 01117 bc->ec_enable, 01118 #endif 01119 01120 help->norxtone,help->notxtone, 01121 bc->holded 01122 ); 01123 01124 }
static void print_bearer | ( | struct misdn_bchannel * | bc | ) | [static] |
Definition at line 483 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().
00484 { 00485 00486 chan_misdn_log(2, bc->port, " --> Bearer: %s\n",bearer2str(bc->capability)); 00487 00488 switch(bc->law) { 00489 case INFO_CODEC_ALAW: 00490 chan_misdn_log(2, bc->port, " --> Codec: Alaw\n"); 00491 break; 00492 case INFO_CODEC_ULAW: 00493 chan_misdn_log(2, bc->port, " --> Codec: Ulaw\n"); 00494 break; 00495 } 00496 }
static void print_facility | ( | struct FacParm * | fac, | |
struct misdn_bchannel * | bc | |||
) | [static] |
Definition at line 445 of file chan_misdn.c.
References chan_misdn_log(), and misdn_bchannel::port.
00446 { 00447 switch (fac->Function) { 00448 case Fac_CD: 00449 chan_misdn_log(1,bc->port," --> calldeflect to: %s, screened: %s\n", fac->u.CDeflection.DeflectedToNumber, 00450 fac->u.CDeflection.PresentationAllowed ? "yes" : "no"); 00451 break; 00452 case Fac_AOCDCurrency: 00453 if (fac->u.AOCDcur.chargeNotAvailable) 00454 chan_misdn_log(1,bc->port," --> AOCD currency: charge not available\n"); 00455 else if (fac->u.AOCDcur.freeOfCharge) 00456 chan_misdn_log(1,bc->port," --> AOCD currency: free of charge\n"); 00457 else if (fac->u.AOCDchu.billingId >= 0) 00458 chan_misdn_log(1,bc->port," --> AOCD currency: currency:%s amount:%d multiplier:%d typeOfChargingInfo:%d billingId:%d\n", 00459 fac->u.AOCDcur.currency, fac->u.AOCDcur.currencyAmount, fac->u.AOCDcur.multiplier, 00460 (fac->u.AOCDcur.typeOfChargingInfo == 0) ? "subTotal" : "total", fac->u.AOCDcur.billingId); 00461 else 00462 chan_misdn_log(1,bc->port," --> AOCD currency: currency:%s amount:%d multiplier:%d typeOfChargingInfo:%d\n", 00463 fac->u.AOCDcur.currency, fac->u.AOCDcur.currencyAmount, fac->u.AOCDcur.multiplier, 00464 (fac->u.AOCDcur.typeOfChargingInfo == 0) ? "subTotal" : "total"); 00465 break; 00466 case Fac_AOCDChargingUnit: 00467 if (fac->u.AOCDchu.chargeNotAvailable) 00468 chan_misdn_log(1,bc->port," --> AOCD charging unit: charge not available\n"); 00469 else if (fac->u.AOCDchu.freeOfCharge) 00470 chan_misdn_log(1,bc->port," --> AOCD charging unit: free of charge\n"); 00471 else if (fac->u.AOCDchu.billingId >= 0) 00472 chan_misdn_log(1,bc->port," --> AOCD charging unit: recordedUnits:%d typeOfChargingInfo:%s billingId:%d\n", 00473 fac->u.AOCDchu.recordedUnits, (fac->u.AOCDchu.typeOfChargingInfo == 0) ? "subTotal" : "total", fac->u.AOCDchu.billingId); 00474 else 00475 chan_misdn_log(1,bc->port," --> AOCD charging unit: recordedUnits:%d typeOfChargingInfo:%s\n", 00476 fac->u.AOCDchu.recordedUnits, (fac->u.AOCDchu.typeOfChargingInfo == 0) ? "subTotal" : "total"); 00477 break; 00478 default: 00479 chan_misdn_log(1,bc->port," --> unknown\n"); 00480 } 00481 }
static struct ast_frame * process_ast_dsp | ( | struct chan_list * | tmp, | |
struct ast_frame * | frame | |||
) | [static] |
Definition at line 2612 of file chan_misdn.c.
References chan_list::ast, ast_async_goto(), chan_list::ast_dsp, ast_dsp_process(), ast_exists_extension(), AST_FRAME_DTMF, ast_log(), ast_strlen_zero(), ast_translate(), ast_verbose(), chan_list::bc, BUFFERSIZE, chan_misdn_log(), ast_channel::cid, ast_callerid::cid_num, ast_channel::context, context, chan_list::dsp, misdn_bchannel::ec_enable, ast_channel::exten, f, chan_list::faxdetect, chan_list::faxhandled, isdn_lib_stop_dtmf(), isdn_lib_update_ec(), isdn_lib_update_rxgain(), isdn_lib_update_txgain(), LOG_DEBUG, LOG_NOTICE, LOG_WARNING, ast_channel::macrocontext, MISDN_CFG_FAXDETECT_CONTEXT, misdn_cfg_get(), option_verbose, pbx_builtin_setvar_helper(), misdn_bchannel::port, misdn_bchannel::rxgain, chan_list::trans, misdn_bchannel::txgain, and VERBOSE_PREFIX_3.
Referenced by misdn_read().
02613 { 02614 struct ast_frame *f,*f2; 02615 02616 if (tmp->trans) { 02617 f2 = ast_translate(tmp->trans, frame, 0); 02618 f = ast_dsp_process(tmp->ast, tmp->dsp, f2); 02619 } else { 02620 chan_misdn_log(0, tmp->bc->port, "No T-Path found\n"); 02621 return NULL; 02622 } 02623 02624 02625 if (!f || (f->frametype != AST_FRAME_DTMF)) 02626 return frame; 02627 02628 ast_log(LOG_DEBUG, "Detected inband DTMF digit: %c\n", f->subclass); 02629 02630 if (tmp->faxdetect && (f->subclass == 'f')) { 02631 /* Fax tone -- Handle and return NULL */ 02632 if (!tmp->faxhandled) { 02633 struct ast_channel *ast = tmp->ast; 02634 tmp->faxhandled++; 02635 chan_misdn_log(0, tmp->bc->port, "Fax detected, preparing %s for fax transfer.\n", ast->name); 02636 tmp->bc->rxgain = 0; 02637 isdn_lib_update_rxgain(tmp->bc); 02638 tmp->bc->txgain = 0; 02639 isdn_lib_update_txgain(tmp->bc); 02640 #ifdef MISDN_1_2 02641 *tmp->bc->pipeline = 0; 02642 #else 02643 tmp->bc->ec_enable = 0; 02644 #endif 02645 isdn_lib_update_ec(tmp->bc); 02646 isdn_lib_stop_dtmf(tmp->bc); 02647 switch (tmp->faxdetect) { 02648 case 1: 02649 if (strcmp(ast->exten, "fax")) { 02650 char *context; 02651 char context_tmp[BUFFERSIZE]; 02652 misdn_cfg_get(tmp->bc->port, MISDN_CFG_FAXDETECT_CONTEXT, &context_tmp, sizeof(context_tmp)); 02653 context = ast_strlen_zero(context_tmp) ? (ast_strlen_zero(ast->macrocontext) ? ast->context : ast->macrocontext) : context_tmp; 02654 if (ast_exists_extension(ast, context, "fax", 1, ast->cid.cid_num)) { 02655 if (option_verbose > 2) 02656 ast_verbose(VERBOSE_PREFIX_3 "Redirecting %s to fax extension (context:%s)\n", ast->name, context); 02657 /* Save the DID/DNIS when we transfer the fax call to a "fax" extension */ 02658 pbx_builtin_setvar_helper(ast,"FAXEXTEN",ast->exten); 02659 if (ast_async_goto(ast, context, "fax", 1)) 02660 ast_log(LOG_WARNING, "Failed to async goto '%s' into fax of '%s'\n", ast->name, context); 02661 } else 02662 ast_log(LOG_NOTICE, "Fax detected, but no fax extension ctx:%s exten:%s\n", context, ast->exten); 02663 } else 02664 ast_log(LOG_DEBUG, "Already in a fax extension, not redirecting\n"); 02665 break; 02666 case 2: 02667 ast_verbose(VERBOSE_PREFIX_3 "Not redirecting %s to fax extension, nojump is set.\n", ast->name); 02668 break; 02669 } 02670 } else 02671 ast_log(LOG_DEBUG, "Fax already handled\n"); 02672 } 02673 02674 if (tmp->ast_dsp && (f->subclass != 'f')) { 02675 chan_misdn_log(2, tmp->bc->port, " --> * SEND: DTMF (AST_DSP) :%c\n", f->subclass); 02676 } 02677 02678 return f; 02679 }
static int read_config | ( | struct chan_list * | ch, | |
int | orig | |||
) | [static] |
Definition at line 1758 of file chan_misdn.c.
References chan_list::allowed_bearers, misdn_bchannel::AOCDtype, chan_list::ast, chan_list::ast_dsp, ast_dsp_new(), ast_dsp_set_features(), AST_FORMAT_ALAW, AST_FORMAT_SLINEAR, ast_log(), ast_mutex_init(), ast_print_group(), ast_set_callerid(), ast_string_field_set, ast_strlen_zero(), ast_translator_build_path(), chan_list::bc, BUFFERSIZE, ast_channel::callgroup, misdn_bchannel::capability, chan_misdn_log(), ast_channel::cid, ast_callerid::cid_rdnis, config_jitterbuffer(), ast_channel::context, chan_list::context, misdn_bchannel::cpnnumplan, misdn_bchannel::dad, debug_numplan(), misdn_bchannel::dnumplan, chan_list::dsp, DSP_FEATURE_DTMF_DETECT, DSP_FEATURE_FAX_DETECT, misdn_bchannel::early_bconnect, ast_channel::exten, chan_list::far_alerting, chan_list::faxdetect, chan_list::faxdetect_timeout, free, misdn_bchannel::hdlc, chan_list::ignore_dtmf, chan_list::incoming_early_audio, INFO_CAPABILITY_DIGITAL_RESTRICTED, INFO_CAPABILITY_DIGITAL_UNRESTRICTED, chan_list::jb_len, chan_list::jb_upper_threshold, misdn_bchannel::keypad, language, LOG_WARNING, MISDN_CFG_ALLOWED_BEARERS, MISDN_CFG_ASTDTMF, MISDN_CFG_CALLERID, MISDN_CFG_CALLGROUP, MISDN_CFG_CONTEXT, MISDN_CFG_CPNDIALPLAN, MISDN_CFG_DIALPLAN, MISDN_CFG_EARLY_BCONNECT, MISDN_CFG_FAR_ALERTING, MISDN_CFG_FAXDETECT, MISDN_CFG_FAXDETECT_TIMEOUT, misdn_cfg_get(), MISDN_CFG_HDLC, MISDN_CFG_INCOMING_EARLY_AUDIO, MISDN_CFG_INTERNATPREFIX, MISDN_CFG_JITTERBUFFER, MISDN_CFG_JITTERBUFFER_UPPER_THRESHOLD, MISDN_CFG_LANGUAGE, MISDN_CFG_LOCALDIALPLAN, MISDN_CFG_MUSICCLASS, MISDN_CFG_NATPREFIX, MISDN_CFG_NEED_MORE_INFOS, MISDN_CFG_NOAUTORESPOND_ON_SETUP, MISDN_CFG_NTTIMEOUT, MISDN_CFG_OVERLAP_DIAL, MISDN_CFG_PICKUPGROUP, MISDN_CFG_RXGAIN, MISDN_CFG_SENDDTMF, MISDN_CFG_TE_CHOOSE_CHANNEL, MISDN_CFG_TXGAIN, musicclass, misdn_bchannel::need_more_infos, chan_list::noautorespond_on_setup, chan_list::nttimeout, NUMPLAN_INTERNATIONAL, NUMPLAN_NATIONAL, misdn_bchannel::oad, misdn_bchannel::onumplan, ORG_AST, misdn_bchannel::orig_dad, chan_list::overlap_dial, chan_list::overlap_dial_task, chan_list::overlap_tv_lock, ast_channel::pickupgroup, misdn_bchannel::port, prefix, misdn_bchannel::rad, misdn_bchannel::rxgain, misdn_bchannel::send_dtmf, strdup, misdn_bchannel::te_choose_channel, chan_list::trans, misdn_bchannel::txgain, and update_ec_config().
Referenced by cb_events(), and misdn_request().
01759 { 01760 struct ast_channel *ast; 01761 struct misdn_bchannel *bc; 01762 int port; 01763 char lang[BUFFERSIZE+1]; 01764 char localmusicclass[BUFFERSIZE+1]; 01765 char faxdetect[BUFFERSIZE+1]; 01766 int hdlc = 0; 01767 01768 if (!ch) { 01769 ast_log(LOG_WARNING, "Cannot configure without chanlist\n"); 01770 return -1; 01771 } 01772 01773 ast=ch->ast; 01774 bc=ch->bc; 01775 if (! ast || ! bc ) { 01776 ast_log(LOG_WARNING, "Cannot configure without ast || bc\n"); 01777 return -1; 01778 } 01779 01780 port=bc->port; 01781 01782 01783 chan_misdn_log(1,port,"read_config: Getting Config\n"); 01784 01785 misdn_cfg_get( port, MISDN_CFG_LANGUAGE, lang, BUFFERSIZE); 01786 ast_string_field_set(ast, language, lang); 01787 01788 misdn_cfg_get( port, MISDN_CFG_MUSICCLASS, localmusicclass, BUFFERSIZE); 01789 ast_string_field_set(ast, musicclass, localmusicclass); 01790 01791 01792 misdn_cfg_get( port, MISDN_CFG_TXGAIN, &bc->txgain, sizeof(int)); 01793 misdn_cfg_get( port, MISDN_CFG_RXGAIN, &bc->rxgain, sizeof(int)); 01794 01795 misdn_cfg_get( port, MISDN_CFG_INCOMING_EARLY_AUDIO, &ch->incoming_early_audio, sizeof(int)); 01796 01797 misdn_cfg_get( port, MISDN_CFG_SENDDTMF, &bc->send_dtmf, sizeof(int)); 01798 01799 misdn_cfg_get( port, MISDN_CFG_ASTDTMF, &ch->ast_dsp, sizeof(int)); 01800 01801 if (ch->ast_dsp) { 01802 ch->ignore_dtmf=1; 01803 } 01804 01805 misdn_cfg_get( port, MISDN_CFG_NEED_MORE_INFOS, &bc->need_more_infos, sizeof(int)); 01806 misdn_cfg_get( port, MISDN_CFG_NTTIMEOUT, &ch->nttimeout, sizeof(int)); 01807 01808 misdn_cfg_get( port, MISDN_CFG_NOAUTORESPOND_ON_SETUP, &ch->noautorespond_on_setup, sizeof(int)); 01809 01810 misdn_cfg_get( port, MISDN_CFG_FAR_ALERTING, &ch->far_alerting, sizeof(int)); 01811 01812 misdn_cfg_get( port, MISDN_CFG_ALLOWED_BEARERS, &ch->allowed_bearers, BUFFERSIZE); 01813 01814 misdn_cfg_get( port, MISDN_CFG_FAXDETECT, faxdetect, BUFFERSIZE); 01815 01816 misdn_cfg_get( port, MISDN_CFG_HDLC, &hdlc, sizeof(int)); 01817 01818 if (hdlc) { 01819 switch (bc->capability) { 01820 case INFO_CAPABILITY_DIGITAL_UNRESTRICTED: 01821 case INFO_CAPABILITY_DIGITAL_RESTRICTED: 01822 chan_misdn_log(1,bc->port," --> CONF HDLC\n"); 01823 bc->hdlc=1; 01824 break; 01825 } 01826 01827 } 01828 /*Initialize new Jitterbuffer*/ 01829 { 01830 misdn_cfg_get( port, MISDN_CFG_JITTERBUFFER, &ch->jb_len, sizeof(int)); 01831 misdn_cfg_get( port, MISDN_CFG_JITTERBUFFER_UPPER_THRESHOLD, &ch->jb_upper_threshold, sizeof(int)); 01832 01833 config_jitterbuffer(ch); 01834 } 01835 01836 misdn_cfg_get( bc->port, MISDN_CFG_CONTEXT, ch->context, sizeof(ch->context)); 01837 01838 ast_copy_string (ast->context,ch->context,sizeof(ast->context)); 01839 01840 #ifdef MISDN_1_2 01841 update_pipeline_config(bc); 01842 #else 01843 update_ec_config(bc); 01844 #endif 01845 01846 { 01847 int eb3; 01848 01849 misdn_cfg_get( bc->port, MISDN_CFG_EARLY_BCONNECT, &eb3, sizeof(int)); 01850 bc->early_bconnect=eb3; 01851 } 01852 01853 port=bc->port; 01854 01855 { 01856 char buf[256]; 01857 ast_group_t pg,cg; 01858 01859 misdn_cfg_get(port, MISDN_CFG_PICKUPGROUP, &pg, sizeof(pg)); 01860 misdn_cfg_get(port, MISDN_CFG_CALLGROUP, &cg, sizeof(cg)); 01861 01862 chan_misdn_log(5, port, " --> * CallGrp:%s PickupGrp:%s\n",ast_print_group(buf,sizeof(buf),cg),ast_print_group(buf,sizeof(buf),pg)); 01863 ast->pickupgroup=pg; 01864 ast->callgroup=cg; 01865 } 01866 01867 if ( orig == ORG_AST) { 01868 misdn_cfg_get( port, MISDN_CFG_TE_CHOOSE_CHANNEL, &(bc->te_choose_channel), sizeof(int)); 01869 01870 if (strstr(faxdetect, "outgoing") || strstr(faxdetect, "both")) { 01871 if (strstr(faxdetect, "nojump")) 01872 ch->faxdetect=2; 01873 else 01874 ch->faxdetect=1; 01875 } 01876 01877 { 01878 char callerid[BUFFERSIZE+1]; 01879 misdn_cfg_get( port, MISDN_CFG_CALLERID, callerid, BUFFERSIZE); 01880 if ( ! ast_strlen_zero(callerid) ) { 01881 chan_misdn_log(1, port, " --> * Setting Cid to %s\n", callerid); 01882 { 01883 int l = sizeof(bc->oad); 01884 strncpy(bc->oad,callerid, l); 01885 bc->oad[l-1] = 0; 01886 } 01887 01888 } 01889 01890 01891 misdn_cfg_get( port, MISDN_CFG_DIALPLAN, &bc->dnumplan, sizeof(int)); 01892 misdn_cfg_get( port, MISDN_CFG_LOCALDIALPLAN, &bc->onumplan, sizeof(int)); 01893 misdn_cfg_get( port, MISDN_CFG_CPNDIALPLAN, &bc->cpnnumplan, sizeof(int)); 01894 debug_numplan(port, bc->dnumplan,"TON"); 01895 debug_numplan(port, bc->onumplan,"LTON"); 01896 debug_numplan(port, bc->cpnnumplan,"CTON"); 01897 } 01898 01899 ch->overlap_dial = 0; 01900 } else { /** ORIGINATOR MISDN **/ 01901 char prefix[BUFFERSIZE+1]=""; 01902 if (strstr(faxdetect, "incoming") || strstr(faxdetect, "both")) { 01903 if (strstr(faxdetect, "nojump")) 01904 ch->faxdetect=2; 01905 else 01906 ch->faxdetect=1; 01907 } 01908 01909 misdn_cfg_get( port, MISDN_CFG_CPNDIALPLAN, &bc->cpnnumplan, sizeof(int)); 01910 debug_numplan(port, bc->cpnnumplan,"CTON"); 01911 01912 switch( bc->onumplan ) { 01913 case NUMPLAN_INTERNATIONAL: 01914 misdn_cfg_get( bc->port, MISDN_CFG_INTERNATPREFIX, prefix, BUFFERSIZE); 01915 break; 01916 01917 case NUMPLAN_NATIONAL: 01918 misdn_cfg_get( bc->port, MISDN_CFG_NATPREFIX, prefix, BUFFERSIZE); 01919 break; 01920 default: 01921 break; 01922 } 01923 01924 { 01925 int l = strlen(prefix) + strlen(bc->oad); 01926 char *tmp = alloca(l+1); 01927 strcpy(tmp,prefix); 01928 strcat(tmp,bc->oad); 01929 strcpy(bc->oad,tmp); 01930 } 01931 01932 if (!ast_strlen_zero(bc->dad)) { 01933 ast_copy_string(bc->orig_dad,bc->dad, sizeof(bc->orig_dad)); 01934 } 01935 01936 if ( ast_strlen_zero(bc->dad) && !ast_strlen_zero(bc->keypad)) { 01937 ast_copy_string(bc->dad,bc->keypad, sizeof(bc->dad)); 01938 } 01939 01940 prefix[0] = 0; 01941 01942 switch( bc->dnumplan ) { 01943 case NUMPLAN_INTERNATIONAL: 01944 misdn_cfg_get( bc->port, MISDN_CFG_INTERNATPREFIX, prefix, BUFFERSIZE); 01945 break; 01946 case NUMPLAN_NATIONAL: 01947 misdn_cfg_get( bc->port, MISDN_CFG_NATPREFIX, prefix, BUFFERSIZE); 01948 break; 01949 default: 01950 break; 01951 } 01952 01953 { 01954 int l = strlen(prefix) + strlen(bc->dad); 01955 char *tmp = alloca(l+1); 01956 strcpy(tmp,prefix); 01957 strcat(tmp,bc->dad); 01958 strcpy(bc->dad,tmp); 01959 } 01960 01961 if ( strcmp(bc->dad,ast->exten)) { 01962 ast_copy_string(ast->exten, bc->dad, sizeof(ast->exten)); 01963 } 01964 01965 ast_set_callerid(ast, bc->oad, NULL, bc->oad); 01966 01967 if ( !ast_strlen_zero(bc->rad) ) { 01968 if (ast->cid.cid_rdnis) 01969 free(ast->cid.cid_rdnis); 01970 ast->cid.cid_rdnis = strdup(bc->rad); 01971 } 01972 01973 misdn_cfg_get(bc->port, MISDN_CFG_OVERLAP_DIAL, &ch->overlap_dial, sizeof(ch->overlap_dial)); 01974 ast_mutex_init(&ch->overlap_tv_lock); 01975 } /* ORIG MISDN END */ 01976 01977 ch->overlap_dial_task = -1; 01978 01979 if (ch->faxdetect || ch->ast_dsp) { 01980 misdn_cfg_get( port, MISDN_CFG_FAXDETECT_TIMEOUT, &ch->faxdetect_timeout, sizeof(ch->faxdetect_timeout)); 01981 if (!ch->dsp) 01982 ch->dsp = ast_dsp_new(); 01983 if (ch->dsp) { 01984 if (ch->faxdetect) 01985 ast_dsp_set_features(ch->dsp, DSP_FEATURE_DTMF_DETECT | DSP_FEATURE_FAX_DETECT); 01986 else 01987 ast_dsp_set_features(ch->dsp, DSP_FEATURE_DTMF_DETECT ); 01988 } 01989 if (!ch->trans) 01990 ch->trans=ast_translator_build_path(AST_FORMAT_SLINEAR, AST_FORMAT_ALAW); 01991 } 01992 01993 /* AOCD initialization */ 01994 bc->AOCDtype = Fac_None; 01995 01996 return 0; 01997 }
static void release_chan | ( | struct misdn_bchannel * | bc | ) | [static] |
Isdn asks us to release channel, pendant to misdn_hangup
Definition at line 3587 of file chan_misdn.c.
References ast_channel::_state, chan_list::ast, ast_mutex_destroy(), ast_mutex_lock(), ast_mutex_unlock(), ast_setstate(), AST_STATE_DOWN, AST_STATE_RESERVED, chan_list::bc, chan_misdn_log(), ast_channel::cid, ast_callerid::cid_num, cl_dequeue_chan(), cl_te, ast_channel::context, ast_channel::exten, find_chan_by_bc(), free, chan_list::jb, misdn_bchannel::l3_id, MISDN_ASTERISK_TECH_PVT, MISDN_CLEANING, misdn_get_ch_state(), misdn_in_calls, misdn_jb_destroy(), misdn_out_calls, misdn_tasks_remove(), misdn_bchannel::nojitter, ORG_AST, chan_list::originator, chan_list::overlap_dial, chan_list::overlap_dial_task, chan_list::overlap_tv_lock, misdn_bchannel::pid, chan_list::pipe, misdn_bchannel::port, release_lock, and chan_list::state.
Referenced by misdn_hangup().
03587 { 03588 struct ast_channel *ast=NULL; 03589 03590 ast_mutex_lock(&release_lock); 03591 { 03592 struct chan_list *ch=find_chan_by_bc(cl_te, bc); 03593 if (!ch) { 03594 chan_misdn_log(1, bc->port, "release_chan: Ch not found!\n"); 03595 ast_mutex_unlock(&release_lock); 03596 return; 03597 } 03598 03599 if (ch->ast) { 03600 ast=ch->ast; 03601 } 03602 03603 chan_misdn_log(5, bc->port, "release_chan: bc with l3id: %x\n",bc->l3_id); 03604 03605 /*releaseing jitterbuffer*/ 03606 if (ch->jb ) { 03607 misdn_jb_destroy(ch->jb); 03608 ch->jb=NULL; 03609 } else { 03610 if (!bc->nojitter) 03611 chan_misdn_log(5,bc->port,"Jitterbuffer already destroyed.\n"); 03612 } 03613 03614 if (ch->overlap_dial) { 03615 if (ch->overlap_dial_task != -1) { 03616 misdn_tasks_remove(ch->overlap_dial_task); 03617 ch->overlap_dial_task = -1; 03618 } 03619 ast_mutex_destroy(&ch->overlap_tv_lock); 03620 } 03621 03622 if (ch->originator == ORG_AST) { 03623 misdn_out_calls[bc->port]--; 03624 } else { 03625 misdn_in_calls[bc->port]--; 03626 } 03627 03628 if (ch) { 03629 03630 close(ch->pipe[0]); 03631 close(ch->pipe[1]); 03632 03633 03634 if (ast && MISDN_ASTERISK_TECH_PVT(ast)) { 03635 chan_misdn_log(1, bc->port, "* RELEASING CHANNEL pid:%d ctx:%s dad:%s oad:%s state: %s\n",bc?bc->pid:-1, ast->context, ast->exten,ast->cid.cid_num,misdn_get_ch_state(ch)); 03636 chan_misdn_log(3, bc->port, " --> * State Down\n"); 03637 MISDN_ASTERISK_TECH_PVT(ast)=NULL; 03638 03639 03640 if (ast->_state != AST_STATE_RESERVED) { 03641 chan_misdn_log(3, bc->port, " --> Setting AST State to down\n"); 03642 ast_setstate(ast, AST_STATE_DOWN); 03643 } 03644 } 03645 03646 ch->state=MISDN_CLEANING; 03647 cl_dequeue_chan(&cl_te, ch); 03648 03649 free(ch); 03650 } else { 03651 /* chan is already cleaned, so exiting */ 03652 } 03653 } 03654 03655 ast_mutex_unlock(&release_lock); 03656 }
static int reload | ( | void | ) | [static] |
Definition at line 5120 of file chan_misdn.c.
References reload_config().
05121 { 05122 reload_config(); 05123 05124 return 0; 05125 }
static void reload_config | ( | void | ) | [static] |
Definition at line 1043 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.
01044 { 01045 int i, cfg_debug; 01046 01047 if (!g_config_initialized) { 01048 ast_log(LOG_WARNING, "chan_misdn is not initialized properly, still reloading ?\n"); 01049 return ; 01050 } 01051 01052 free_robin_list(); 01053 misdn_cfg_reload(); 01054 misdn_cfg_update_ptp(); 01055 misdn_cfg_get( 0, MISDN_GEN_TRACEFILE, global_tracefile, BUFFERSIZE); 01056 misdn_cfg_get( 0, MISDN_GEN_DEBUG, &cfg_debug, sizeof(int)); 01057 01058 for (i = 0; i <= max_ports; i++) { 01059 misdn_debug[i] = cfg_debug; 01060 misdn_debug_only[i] = 0; 01061 } 01062 }
static void send_cause2ast | ( | struct ast_channel * | ast, | |
struct misdn_bchannel * | bc, | |||
struct chan_list * | ch | |||
) | [static] |
Definition at line 3736 of file chan_misdn.c.
References 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().
03736 { 03737 if (!ast) { 03738 chan_misdn_log(1,0,"send_cause2ast: No Ast\n"); 03739 return; 03740 } 03741 if (!bc) { 03742 chan_misdn_log(1,0,"send_cause2ast: No BC\n"); 03743 return; 03744 } 03745 if (!ch) { 03746 chan_misdn_log(1,0,"send_cause2ast: No Ch\n"); 03747 return; 03748 } 03749 03750 ast->hangupcause=bc->cause; 03751 03752 switch ( bc->cause) { 03753 03754 case 1: /** Congestion Cases **/ 03755 case 2: 03756 case 3: 03757 case 4: 03758 case 22: 03759 case 27: 03760 /* 03761 * Not Queueing the Congestion anymore, since we want to hear 03762 * the inband message 03763 * 03764 chan_misdn_log(1, bc?bc->port:0, " --> * SEND: Queue Congestion pid:%d\n", bc?bc->pid:-1); 03765 ch->state=MISDN_BUSY; 03766 03767 ast_queue_control(ast, AST_CONTROL_CONGESTION); 03768 */ 03769 break; 03770 03771 case 21: 03772 case 17: /* user busy */ 03773 03774 ch->state=MISDN_BUSY; 03775 03776 if (!ch->need_busy) { 03777 chan_misdn_log(1,bc?bc->port:0, "Queued busy already\n"); 03778 break; 03779 } 03780 03781 chan_misdn_log(1, bc?bc->port:0, " --> * SEND: Queue Busy pid:%d\n", bc?bc->pid:-1); 03782 03783 ast_queue_control(ast, AST_CONTROL_BUSY); 03784 03785 ch->need_busy=0; 03786 03787 break; 03788 } 03789 }
static void send_digit_to_chan | ( | struct chan_list * | cl, | |
char | digit | |||
) | [static] |
Definition at line 704 of file chan_misdn.c.
References chan_list::ast, ast_log(), ast_playtones_start(), and LOG_DEBUG.
Referenced by misdn_digit_end(), and misdn_send_digit().
00705 { 00706 static const char* dtmf_tones[] = { 00707 "!941+1336/100,!0/100", /* 0 */ 00708 "!697+1209/100,!0/100", /* 1 */ 00709 "!697+1336/100,!0/100", /* 2 */ 00710 "!697+1477/100,!0/100", /* 3 */ 00711 "!770+1209/100,!0/100", /* 4 */ 00712 "!770+1336/100,!0/100", /* 5 */ 00713 "!770+1477/100,!0/100", /* 6 */ 00714 "!852+1209/100,!0/100", /* 7 */ 00715 "!852+1336/100,!0/100", /* 8 */ 00716 "!852+1477/100,!0/100", /* 9 */ 00717 "!697+1633/100,!0/100", /* A */ 00718 "!770+1633/100,!0/100", /* B */ 00719 "!852+1633/100,!0/100", /* C */ 00720 "!941+1633/100,!0/100", /* D */ 00721 "!941+1209/100,!0/100", /* * */ 00722 "!941+1477/100,!0/100" }; /* # */ 00723 struct ast_channel *chan=cl->ast; 00724 00725 if (digit >= '0' && digit <='9') 00726 ast_playtones_start(chan,0,dtmf_tones[digit-'0'], 0); 00727 else if (digit >= 'A' && digit <= 'D') 00728 ast_playtones_start(chan,0,dtmf_tones[digit-'A'+10], 0); 00729 else if (digit == '*') 00730 ast_playtones_start(chan,0,dtmf_tones[14], 0); 00731 else if (digit == '#') 00732 ast_playtones_start(chan,0,dtmf_tones[15], 0); 00733 else { 00734 /* not handled */ 00735 ast_log(LOG_DEBUG, "Unable to handle DTMF tone '%c' for '%s'\n", digit, chan->name); 00736 00737 00738 } 00739 }
static void show_config_description | ( | int | fd, | |
enum misdn_cfg_elements | elem | |||
) | [inline, static] |
Definition at line 893 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().
00894 { 00895 char section[BUFFERSIZE]; 00896 char name[BUFFERSIZE]; 00897 char desc[BUFFERSIZE]; 00898 char def[BUFFERSIZE]; 00899 char tmp[BUFFERSIZE]; 00900 00901 misdn_cfg_get_name(elem, tmp, sizeof(tmp)); 00902 term_color(name, tmp, COLOR_BRWHITE, 0, sizeof(tmp)); 00903 misdn_cfg_get_desc(elem, desc, sizeof(desc), def, sizeof(def)); 00904 00905 if (elem < MISDN_CFG_LAST) 00906 term_color(section, "PORTS SECTION", COLOR_YELLOW, 0, sizeof(section)); 00907 else 00908 term_color(section, "GENERAL SECTION", COLOR_YELLOW, 0, sizeof(section)); 00909 00910 if (*def) 00911 ast_cli(fd, "[%s] %s (Default: %s)\n\t%s\n", section, name, def, desc); 00912 else 00913 ast_cli(fd, "[%s] %s\n\t%s\n", section, name, desc); 00914 }
static void sighandler | ( | int | sig | ) | [static] |
static int start_bc_tones | ( | struct chan_list * | cl | ) | [static] |
Definition at line 3049 of file chan_misdn.c.
References chan_list::bc, misdn_lib_tone_generator_stop(), chan_list::norxtone, and chan_list::notxtone.
Referenced by misdn_answer(), misdn_hangup(), and misdn_indication().
03050 { 03051 misdn_lib_tone_generator_stop(cl->bc); 03052 cl->notxtone=0; 03053 cl->norxtone=0; 03054 return 0; 03055 }
static void start_pbx | ( | struct chan_list * | ch, | |
struct misdn_bchannel * | bc, | |||
struct ast_channel * | chan | |||
) | [static] |
Definition at line 3886 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().
03886 { 03887 if (pbx_start_chan(ch)<0) { 03888 hangup_chan(ch); 03889 chan_misdn_log(-1, bc->port, "ast_pbx_start returned <0 in SETUP\n"); 03890 if (bc->nt) { 03891 hanguptone_indicate(ch); 03892 misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE ); 03893 } else 03894 misdn_lib_send_event(bc, EVENT_RELEASE); 03895 } 03896 }
static int stop_bc_tones | ( | struct chan_list * | cl | ) | [static] |
Definition at line 3057 of file chan_misdn.c.
References chan_list::norxtone, and chan_list::notxtone.
Referenced by misdn_call(), and misdn_hangup().
03058 { 03059 if (!cl) return -1; 03060 03061 cl->notxtone=1; 03062 cl->norxtone=1; 03063 03064 return 0; 03065 }
static int stop_indicate | ( | struct chan_list * | cl | ) | [static] |
Definition at line 3029 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().
03030 { 03031 struct ast_channel *ast=cl->ast; 03032 03033 if (!ast) { 03034 chan_misdn_log(0,cl->bc->port,"No Ast in stop_indicate\n"); 03035 return -1; 03036 } 03037 03038 chan_misdn_log(3,cl->bc->port," --> None\n"); 03039 misdn_lib_tone_generator_stop(cl->bc); 03040 ast_playtones_stop(ast); 03041 03042 cl->ts=NULL; 03043 /*ast_deactivate_generator(ast);*/ 03044 03045 return 0; 03046 }
static int unload_module | ( | void | ) | [static] |
TE STUFF END
Definition at line 4939 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(), g_config_initialized, LOG_VERBOSE, misdn_cfg_destroy(), misdn_debug, misdn_debug_only, misdn_lib_destroy(), misdn_ports, misdn_tasks_destroy(), and misdn_tech.
04940 { 04941 /* First, take us out of the channel loop */ 04942 ast_log(LOG_VERBOSE, "-- Unregistering mISDN Channel Driver --\n"); 04943 04944 misdn_tasks_destroy(); 04945 04946 if (!g_config_initialized) return 0; 04947 04948 ast_cli_unregister_multiple(chan_misdn_clis, sizeof(chan_misdn_clis) / sizeof(struct ast_cli_entry)); 04949 04950 /* ast_unregister_application("misdn_crypt"); */ 04951 ast_unregister_application("misdn_set_opt"); 04952 ast_unregister_application("misdn_facility"); 04953 ast_unregister_application("misdn_check_l2l1"); 04954 04955 ast_channel_unregister(&misdn_tech); 04956 04957 04958 free_robin_list(); 04959 misdn_cfg_destroy(); 04960 misdn_lib_destroy(); 04961 04962 if (misdn_debug) 04963 free(misdn_debug); 04964 if (misdn_debug_only) 04965 free(misdn_debug_only); 04966 free(misdn_ports); 04967 04968 return 0; 04969 }
static int update_config | ( | struct chan_list * | ch, | |
int | orig | |||
) | [static] |
Definition at line 1558 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().
01559 { 01560 struct ast_channel *ast=ch->ast; 01561 struct misdn_bchannel *bc=ch->bc; 01562 int port; 01563 int pres, screen; 01564 int hdlc=0; 01565 01566 if (!ch) { 01567 ast_log(LOG_WARNING, "Cannot configure without chanlist\n"); 01568 return -1; 01569 } 01570 01571 ast=ch->ast; 01572 bc=ch->bc; 01573 if (! ast || ! bc ) { 01574 ast_log(LOG_WARNING, "Cannot configure without ast || bc\n"); 01575 return -1; 01576 } 01577 01578 port=bc->port; 01579 01580 chan_misdn_log(7,port,"update_config: Getting Config\n"); 01581 01582 misdn_cfg_get( port, MISDN_CFG_HDLC, &hdlc, sizeof(int)); 01583 01584 if (hdlc) { 01585 switch (bc->capability) { 01586 case INFO_CAPABILITY_DIGITAL_UNRESTRICTED: 01587 case INFO_CAPABILITY_DIGITAL_RESTRICTED: 01588 chan_misdn_log(1,bc->port," --> CONF HDLC\n"); 01589 bc->hdlc=1; 01590 break; 01591 } 01592 01593 } 01594 01595 misdn_cfg_get( port, MISDN_CFG_PRES, &pres, sizeof(int)); 01596 misdn_cfg_get( port, MISDN_CFG_SCREEN, &screen, sizeof(int)); 01597 chan_misdn_log(2,port," --> pres: %d screen: %d\n",pres, screen); 01598 01599 if ( (pres + screen) < 0 ) { 01600 01601 chan_misdn_log(2,port," --> pres: %x\n", ast->cid.cid_pres); 01602 01603 switch (ast->cid.cid_pres & 0x60){ 01604 01605 case AST_PRES_RESTRICTED: 01606 bc->pres=1; 01607 chan_misdn_log(2, port, " --> PRES: Restricted (0x1)\n"); 01608 break; 01609 01610 01611 case AST_PRES_UNAVAILABLE: 01612 bc->pres=2; 01613 chan_misdn_log(2, port, " --> PRES: Unavailable (0x2)\n"); 01614 break; 01615 01616 default: 01617 bc->pres=0; 01618 chan_misdn_log(2, port, " --> PRES: Allowed (0x0)\n"); 01619 } 01620 01621 switch (ast->cid.cid_pres & 0x3){ 01622 01623 case AST_PRES_USER_NUMBER_UNSCREENED: 01624 bc->screen=0; 01625 chan_misdn_log(2, port, " --> SCREEN: Unscreened (0x0)\n"); 01626 break; 01627 01628 case AST_PRES_USER_NUMBER_PASSED_SCREEN: 01629 bc->screen=1; 01630 chan_misdn_log(2, port, " --> SCREEN: Passed Screen (0x1)\n"); 01631 break; 01632 case AST_PRES_USER_NUMBER_FAILED_SCREEN: 01633 bc->screen=2; 01634 chan_misdn_log(2, port, " --> SCREEN: Failed Screen (0x2)\n"); 01635 break; 01636 01637 case AST_PRES_NETWORK_NUMBER: 01638 bc->screen=3; 01639 chan_misdn_log(2, port, " --> SCREEN: Network Nr. (0x3)\n"); 01640 break; 01641 01642 default: 01643 bc->screen=0; 01644 chan_misdn_log(2, port, " --> SCREEN: Unscreened (0x0)\n"); 01645 } 01646 01647 01648 } else { 01649 bc->screen=screen; 01650 bc->pres=pres; 01651 } 01652 01653 return 0; 01654 01655 }
static int update_ec_config | ( | struct misdn_bchannel * | bc | ) | [static] |
Definition at line 1739 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().
01740 { 01741 int ec; 01742 int port=bc->port; 01743 01744 misdn_cfg_get( port, MISDN_CFG_ECHOCANCEL, &ec, sizeof(int)); 01745 01746 if (ec == 1 ) { 01747 bc->ec_enable=1; 01748 } else if ( ec > 1 ) { 01749 bc->ec_enable=1; 01750 bc->ec_deftaps=ec; 01751 } 01752 01753 return 0; 01754 }
static void update_name | ( | struct ast_channel * | tmp, | |
int | port, | |||
int | c | |||
) | [static] |
Definition at line 3334 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, and name.
Referenced by cb_events().
03335 { 03336 int chan_offset=0; 03337 int tmp_port = misdn_cfg_get_next_port(0); 03338 for (; tmp_port > 0; tmp_port=misdn_cfg_get_next_port(tmp_port)) { 03339 if (tmp_port == port) break; 03340 chan_offset+=misdn_lib_port_is_pri(tmp_port)?30:2; 03341 } 03342 if (c<0) c=0; 03343 03344 ast_string_field_build(tmp, name, "%s/%d-u%d", 03345 misdn_type, chan_offset+c, glob_channel++); 03346 03347 chan_misdn_log(3,port," --> updating channel name to [%s]\n",tmp->name); 03348 03349 }
static void wait_for_digits | ( | struct chan_list * | ch, | |
struct misdn_bchannel * | bc, | |||
struct ast_channel * | chan | |||
) | [static] |
Definition at line 3898 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.
03898 { 03899 ch->state=MISDN_WAITING4DIGS; 03900 misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE ); 03901 if (bc->nt && !bc->dad[0]) 03902 dialtone_indicate(ch); 03903 }
struct allowed_bearers allowed_bearers_array[] |
struct ast_cli_entry chan_misdn_clis[] [static] |
Definition at line 322 of file chan_misdn.c.
Referenced by cb_events(), chan_misdn_jb_empty(), get_chan_by_ast(), get_chan_by_ast_name(), import_ch(), misdn_hangup(), misdn_request(), misdn_show_cl(), misdn_show_cls(), and release_chan().
Definition at line 323 of file chan_misdn.c.
Referenced by cl_dequeue_chan(), cl_queue_chan(), and load_module().
Definition at line 320 of file chan_misdn.c.
int g_config_initialized = 0 [static] |
int glob_channel = 0 [static] |
Definition at line 3332 of file chan_misdn.c.
char global_tracefile[BUFFERSIZE+1] |
Definition at line 1193 of file chan_misdn.c.
Referenced by load_config(), load_module(), load_rpt_vars(), rpt_master(), smdi_message_wait(), unload_module(), zap_show_channel(), zap_show_channels(), and zt_request().
int max_ports [static] |
Definition at line 314 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 |
int* misdn_debug [static] |
Definition at line 312 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 313 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 316 of file chan_misdn.c.
Referenced by add_in_calls(), load_module(), misdn_show_ports_stats(), and release_chan().
int* misdn_out_calls [static] |
Definition at line 317 of file chan_misdn.c.
Referenced by add_out_calls(), load_module(), misdn_show_ports_stats(), and release_chan().
int* misdn_ports [static] |
struct sched_context* misdn_tasks = NULL [static] |
Definition at line 285 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 286 of file chan_misdn.c.
struct ast_channel_tech misdn_tech [static] |
Definition at line 3294 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 305 of file chan_misdn.c.
Referenced by load_module(), misdn_new(), misdn_request(), and update_name().
int prefformat = AST_FORMAT_ALAW [static] |
Definition at line 116 of file chan_misdn.c.
Referenced by load_module(), misdn_hangup(), and release_chan().
struct robin_list* robin = NULL [static] |
Definition at line 240 of file chan_misdn.c.
Referenced by free_robin_list(), and get_robin_position().
struct state_struct state_array[] [static] |
int tracing = 0 [static] |