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