#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 "chan_misdn_config.h"
#include "isdn_lib.h"
#include <asterisk/strings.h>
Include dependency graph for chan_misdn.c:

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