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