![]() |
Home page |
Mailing list |
Docs
Asterisk developer's documentation :: Codename Pineapple
chan_misdn.c File Reference
Definition in file chan_misdn.c.
#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 | AST_BRIDGED_P(ast) ast_bridged_channel(ast) |
| #define | AST_CID_P(ast) ast->cid.cid_num |
| #define | AST_DESTROY_CFG ast_config_destroy |
| #define | AST_LOAD_CFG ast_config_load |
| #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_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) |
| void | export_ch (struct ast_channel *chan, struct misdn_bchannel *bc, struct chan_list *ch) |
| static struct chan_list * | find_chan_by_bc (struct chan_list *list, struct misdn_bchannel *bc) |
| static struct chan_list * | find_chan_by_pid (struct chan_list *list, int pid) |
| static struct chan_list * | find_holded (struct chan_list *list, struct misdn_bchannel *bc) |
| static struct chan_list * | find_holded_l3 (struct chan_list *list, unsigned long l3_id, int w) |
| static void | free_robin_list (void) |
| static void | free_robin_list_r (struct robin_list *r) |
| static struct chan_list * | get_chan_by_ast (struct ast_channel *ast) |
| static struct chan_list * | get_chan_by_ast_name (char *name) |
| static struct robin_list * | get_robin_position (char *group) |
| static void | hangup_chan (struct chan_list *ch) |
| static int | hanguptone_indicate (struct chan_list *cl) |
| void | import_ch (struct ast_channel *chan, struct misdn_bchannel *bc, struct chan_list *ch) |
| static struct chan_list * | init_chan_list (int orig) |
| static int | load_module (void) |
| static int | misdn_answer (struct ast_channel *ast) |
| static enum ast_bridge_result | misdn_bridge (struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc, int timeoutms) |
| static int | misdn_call (struct ast_channel *ast, char *dest, int timeout) |
| static int | misdn_digit_begin (struct ast_channel *chan, char digit) |
| static int | misdn_digit_end (struct ast_channel *ast, char digit, unsigned int duration) |
| static int | misdn_facility_exec (struct ast_channel *chan, void *data) |
| static int | misdn_fixup (struct ast_channel *oldast, struct ast_channel *ast) |
| static char * | misdn_get_ch_state (struct chan_list *p) |
| static int | misdn_hangup (struct ast_channel *ast) |
| static int | misdn_indication (struct ast_channel *ast, int cond, const void *data, size_t datalen) |
| void | misdn_jb_destroy (struct misdn_jb *jb) |
| int | misdn_jb_empty (struct misdn_jb *jb, char *data, int len) |
| int | misdn_jb_fill (struct misdn_jb *jb, const char *data, int len) |
| misdn_jb * | misdn_jb_init (int size, int upper_threshold) |
| static int | misdn_l1_task (void *data) |
| static struct ast_channel * | misdn_new (struct chan_list *cl, int state, char *exten, char *callerid, int format, int port, int c) |
| static int | misdn_overlap_dial_task (void *data) |
| static int | misdn_port_block (int fd, int argc, char *argv[]) |
| static int | misdn_port_down (int fd, int argc, char *argv[]) |
| static int | misdn_port_unblock (int fd, int argc, char *argv[]) |
| static int | misdn_port_up (int fd, int argc, char *argv[]) |
| static struct ast_frame * | misdn_read (struct ast_channel *ast) |
| static int | misdn_reload (int fd, int argc, char *argv[]) |
| static struct ast_channel * | misdn_request (const char *type, int format, void *data, int *cause) |
| static int | misdn_restart_pid (int fd, int argc, char *argv[]) |
| static int | misdn_restart_port (int fd, int argc, char *argv[]) |
| static int | misdn_send_cd (int fd, int argc, char *argv[]) |
| static int | misdn_send_digit (int fd, int argc, char *argv[]) |
| static int | misdn_send_display (int fd, int argc, char *argv[]) |
| static int | misdn_send_text (struct ast_channel *chan, const char *text) |
| static int | misdn_set_crypt_debug (int fd, int argc, char *argv[]) |
| static int | misdn_set_debug (int fd, int argc, char *argv[]) |
| static int | misdn_set_opt_exec (struct ast_channel *chan, void *data) |
| static int | misdn_set_tics (int fd, int argc, char *argv[]) |
| static int | misdn_show_cl (int fd, int argc, char *argv[]) |
| static int | misdn_show_cls (int fd, int argc, char *argv[]) |
| static int | misdn_show_config (int fd, int argc, char *argv[]) |
| static int | misdn_show_port (int fd, int argc, char *argv[]) |
| static int | misdn_show_ports_stats (int fd, int argc, char *argv[]) |
| static int | misdn_show_stacks (int fd, int argc, char *argv[]) |
| static int | misdn_tasks_add (int timeout, ast_sched_cb callback, void *data) |
| static int | misdn_tasks_add_variable (int timeout, ast_sched_cb callback, void *data) |
| static void | misdn_tasks_destroy (void) |
| static void | misdn_tasks_init (void) |
| static void | misdn_tasks_remove (int task_id) |
| static void * | misdn_tasks_thread_func (void *data) |
| static void | misdn_tasks_wakeup (void) |
| static int | misdn_toggle_echocancel (int fd, int argc, char *argv[]) |
| static void | misdn_transfer_bc (struct chan_list *tmp_ch, struct chan_list *holded_chan) |
| static int | misdn_write (struct ast_channel *ast, struct ast_frame *frame) |
| static int | pbx_start_chan (struct chan_list *ch) |
| static void | print_bc_info (int fd, struct chan_list *help, struct misdn_bchannel *bc) |
| static void | print_bearer (struct misdn_bchannel *bc) |
| static void | print_facility (struct FacParm *fac, struct misdn_bchannel *bc) |
| static struct ast_frame * | process_ast_dsp (struct chan_list *tmp, struct ast_frame *frame) |
| static int | read_config (struct chan_list *ch, int orig) |
| static void | release_chan (struct misdn_bchannel *bc) |
| static int | reload (void) |
| static void | reload_config (void) |
| static void | send_cause2ast (struct ast_channel *ast, struct misdn_bchannel *bc, struct chan_list *ch) |
| static void | send_digit_to_chan (struct chan_list *cl, char digit) |
| static void | show_config_description (int fd, enum misdn_cfg_elements elem) |
| static void | sighandler (int sig) |
| static int | start_bc_tones (struct chan_list *cl) |
| static int | stop_bc_tones (struct chan_list *cl) |
| static int | stop_indicate (struct chan_list *cl) |
| static int | unload_module (void) |
| static int | update_config (struct chan_list *ch, int orig) |
| static int | update_ec_config (struct misdn_bchannel *bc) |
| static void | update_name (struct ast_channel *tmp, int port, int c) |
Variables | |
| allowed_bearers | allowed_bearers_array [] |
| static struct ast_cli_entry | chan_misdn_clis [] |
| chan_list * | cl_te = NULL |
| ast_mutex_t | cl_te_lock |
| chan_list | dummy_cl |
| static int | g_config_initialized = 0 |
| static int | glob_channel = 0 |
| char | global_tracefile [BUFFERSIZE+1] |
| ast_mutex_t | lock |
| static int | max_ports |
| int | MAXTICS = 8 |
| static int * | misdn_debug |
| static int * | misdn_debug_only |
| static int * | misdn_in_calls |
| static char ** | misdn_key_vector = NULL |
| static int | misdn_key_vector_size = 0 |
| static int * | misdn_out_calls |
| static int * | misdn_ports |
| static struct sched_context * | misdn_tasks = NULL |
| static pthread_t | misdn_tasks_thread |
| static struct ast_channel_tech | misdn_tech |
| static struct ast_channel_tech | misdn_tech_wo_bridge |
| static const char | misdn_type [] = "mISDN" |
| static int | prefformat = AST_FORMAT_ALAW |
| static struct robin_list * | robin = NULL |
| static struct state_struct | state_array [] |
| static int | tracing = 0 |
|
|
Definition at line 290 of file chan_misdn.c. Referenced by misdn_transfer_bc(). |
|
|
Definition at line 289 of file chan_misdn.c. Referenced by do_immediate_setup(), misdn_call(), misdn_hangup(), print_bc_info(), process_ast_dsp(), and release_chan(). |
|
|
Definition at line 292 of file chan_misdn.c. |
|
|
Definition at line 291 of file chan_misdn.c. Referenced by misdn_cfg_init(). |
|
|
Definition at line 295 of file chan_misdn.c. Referenced by cb_events(), and do_immediate_setup(). |
|
|
Definition at line 294 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(). |
|
|
Definition at line 138 of file chan_misdn.c. Referenced by misdn_call(), misdn_hangup(), misdn_request(), print_bc_info(), read_config(), and release_chan(). |
|
|
Definition at line 139 of file chan_misdn.c. Referenced by cb_events(), do_immediate_setup(), and misdn_indication(). |
|
|
Definition at line 113 of file chan_misdn.c. 00113 { 00114 MISDN_NOTHING=0, /*!< at beginning */ 00115 MISDN_WAITING4DIGS, /*!< when waiting for infos */ 00116 MISDN_EXTCANTMATCH, /*!< when asterisk couldnt match our ext */ 00117 MISDN_DIALING, /*!< when pbx_start */ 00118 MISDN_PROGRESS, /*!< we got a progress */ 00119 MISDN_PROCEEDING, /*!< we got a progress */ 00120 MISDN_CALLING, /*!< when misdn_call is called */ 00121 MISDN_CALLING_ACKNOWLEDGE, /*!< when we get SETUP_ACK */ 00122 MISDN_ALERTING, /*!< when Alerting */ 00123 MISDN_BUSY, /*!< when BUSY */ 00124 MISDN_CONNECTED, /*!< when connected */ 00125 MISDN_PRECONNECTED, /*!< when connected */ 00126 MISDN_DISCONNECTED, /*!< when connected */ 00127 MISDN_RELEASED, /*!< when connected */ 00128 MISDN_BRIDGED, /*!< when bridged */ 00129 MISDN_CLEANING, /*!< when hangup from * but we were connected before */ 00130 MISDN_HUNGUP_FROM_MISDN, /*!< when DISCONNECT/RELEASE/REL_COMP cam from misdn */ 00131 MISDN_HUNGUP_FROM_AST, /*!< when DISCONNECT/RELEASE/REL_COMP came out of */ 00132 /* misdn_hangup */ 00133 MISDN_HOLDED, /*!< if this chan is holded */ 00134 MISDN_HOLD_DISCONNECT, /*!< if this chan is holded */ 00135 00136 };
|
|
||||||||||||||||||||
|
Definition at line 556 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(). 00557 { 00558 int task_id; 00559 00560 if (!misdn_tasks) { 00561 misdn_tasks_init(); 00562 } 00563 task_id = ast_sched_add_variable(misdn_tasks, timeout, callback, data, variable); 00564 misdn_tasks_wakeup(); 00565 00566 return task_id; 00567 }
|
|
|
Definition at line 3593 of file chan_misdn.c. References ast_log(), LOG_NOTICE, misdn_cfg_get(), and misdn_in_calls. Referenced by cb_events(). 03594 { 03595 int max_in_calls; 03596 03597 misdn_cfg_get( port, MISDN_CFG_MAX_IN, &max_in_calls, sizeof(max_in_calls)); 03598 03599 misdn_in_calls[port]++; 03600 03601 if (max_in_calls >=0 && max_in_calls<misdn_in_calls[port]) { 03602 ast_log(LOG_NOTICE,"Marking Incoming Call on port[%d]\n",port); 03603 return misdn_in_calls[port]-max_in_calls; 03604 } 03605 03606 return 0; 03607 }
|
|
|
Definition at line 3609 of file chan_misdn.c. References ast_log(), LOG_NOTICE, misdn_cfg_get(), and misdn_out_calls. Referenced by misdn_call(). 03610 { 03611 int max_out_calls; 03612 03613 misdn_cfg_get( port, MISDN_CFG_MAX_OUT, &max_out_calls, sizeof(max_out_calls)); 03614 03615 03616 if (max_out_calls >=0 && max_out_calls<=misdn_out_calls[port]) { 03617 ast_log(LOG_NOTICE,"Rejecting Outgoing Call on port[%d]\n",port); 03618 return (misdn_out_calls[port]+1)-max_out_calls; 03619 } 03620 03621 misdn_out_calls[port]++; 03622 03623 return 0; 03624 }
|
|
||||||||||||||||||||||||||||
|
|
|
|
Definition at line 406 of file chan_misdn.c. Referenced by print_bc_info(), and print_bearer(). 00406 { 00407 static char *bearers[]={ 00408 "Speech", 00409 "Audio 3.1k", 00410 "Unres Digital", 00411 "Res Digital", 00412 "Video", 00413 "Unknown Bearer" 00414 }; 00415 00416 switch (cap) { 00417 case INFO_CAPABILITY_SPEECH: 00418 return bearers[0]; 00419 break; 00420 case INFO_CAPABILITY_AUDIO_3_1K: 00421 return bearers[1]; 00422 break; 00423 case INFO_CAPABILITY_DIGITAL_UNRESTRICTED: 00424 return bearers[2]; 00425 break; 00426 case INFO_CAPABILITY_DIGITAL_RESTRICTED: 00427 return bearers[3]; 00428 break; 00429 case INFO_CAPABILITY_VIDEO: 00430 return bearers[4]; 00431 break; 00432 default: 00433 return bearers[5]; 00434 break; 00435 } 00436 }
|
|
||||||||||||||||
|
Sending SETUP_ACK queue new chan Sending SETUP_ACK ADD IGNOREPAT Suplementary Services Definition at line 3632 of file chan_misdn.c. References add_in_calls(), 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, chan_misdn_log(), ast_channel::cid, ast_callerid::cid_pres, cl_queue_chan(), cl_te, chan_list::context, ast_frame::data, ast_frame::datalen, ast_frame::delivery, export_ch(), ast_channel::exten, find_chan_by_bc(), find_holded(), ast_frame::frametype, hangup_chan(), hanguptone_indicate(), chan_list::ignore_dtmf, init_chan_list(), chan_list::l3id, LOG_NOTICE, LOG_WARNING, ast_frame::mallocd, MISDN_ASTERISK_PVT, MISDN_ASTERISK_TECH_PVT, MISDN_CALLING_ACKNOWLEDGE, misdn_cfg_get(), misdn_cfg_is_msn_valid(), MISDN_CONNECTED, MISDN_DIALING, MISDN_EXTCANTMATCH, misdn_get_ch_state(), misdn_new(), MISDN_NOTHING, misdn_overlap_dial_task(), misdn_tasks_add_variable(), MISDN_WAITING4DIGS, allowed_bearers::name, ast_frame::offset, ORG_MISDN, chan_list::orginator, chan_list::overlap_dial, chan_list::overlap_dial_task, chan_list::overlap_tv, chan_list::overlap_tv_lock, pbx_builtin_setvar_helper(), pbx_start_chan(), print_bearer(), read_config(), ast_channel::rings, ast_frame::samples, ast_frame::src, chan_list::state, stop_indicate(), ast_frame::subclass, ast_channel::transfercapability, and update_name(). 03633 { 03634 struct chan_list *ch=find_chan_by_bc(cl_te, bc); 03635 03636 if (event != EVENT_BCHAN_DATA && event != EVENT_TONE_GENERATE) { /* Debug Only Non-Bchan */ 03637 int debuglevel=1; 03638 if ( event==EVENT_CLEANUP && !user_data) 03639 debuglevel=5; 03640 03641 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"); 03642 if (debuglevel==1) { 03643 misdn_lib_log_ies(bc); 03644 chan_misdn_log(4,bc->port," --> bc_state:%s\n",bc_state2str(bc->bc_state)); 03645 } 03646 } 03647 03648 if (!ch) { 03649 switch(event) { 03650 case EVENT_SETUP: 03651 case EVENT_DISCONNECT: 03652 case EVENT_PORT_ALARM: 03653 case EVENT_RETRIEVE: 03654 case EVENT_NEW_BC: 03655 case EVENT_FACILITY: 03656 break; 03657 case EVENT_RELEASE_COMPLETE: 03658 chan_misdn_log(1, bc->port, " --> no Ch, so we've already released.\n"); 03659 break; 03660 case EVENT_CLEANUP: 03661 case EVENT_TONE_GENERATE: 03662 case EVENT_BCHAN_DATA: 03663 return -1; 03664 03665 default: 03666 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); 03667 return -1; 03668 } 03669 } 03670 03671 if (ch ) { 03672 switch (event) { 03673 case EVENT_TONE_GENERATE: 03674 break; 03675 case EVENT_DISCONNECT: 03676 case EVENT_RELEASE: 03677 case EVENT_RELEASE_COMPLETE: 03678 case EVENT_CLEANUP: 03679 case EVENT_TIMEOUT: 03680 if (!ch->ast) 03681 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)); 03682 break; 03683 default: 03684 if ( !ch->ast || !MISDN_ASTERISK_PVT(ch->ast) || !MISDN_ASTERISK_TECH_PVT(ch->ast)) { 03685 if (event!=EVENT_BCHAN_DATA) 03686 ast_log(LOG_NOTICE, "No Ast or No private Pointer in Event (%d:%s)\n", event, manager_isdn_get_info(event)); 03687 return -1; 03688 } 03689 } 03690 } 03691 03692 03693 switch (event) { 03694 case EVENT_PORT_ALARM: 03695 { 03696 int boa=0; 03697 misdn_cfg_get( bc->port, MISDN_CFG_ALARM_BLOCK, &boa, sizeof(int)); 03698 if (boa) { 03699 cb_log(1,bc->port," --> blocking\n"); 03700 misdn_lib_port_block(bc->port); 03701 } 03702 } 03703 break; 03704 case EVENT_BCHAN_ACTIVATED: 03705 break; 03706 03707 case EVENT_NEW_CHANNEL: 03708 update_name(ch->ast,bc->port,bc->channel); 03709 break; 03710 03711 case EVENT_NEW_L3ID: 03712 ch->l3id=bc->l3_id; 03713 ch->addr=bc->addr; 03714 break; 03715 03716 case EVENT_NEW_BC: 03717 if (!ch) { 03718 ch=find_holded(cl_te,bc); 03719 } 03720 03721 if (!ch) { 03722 ast_log(LOG_WARNING,"NEW_BC without chan_list?\n"); 03723 break; 03724 } 03725 03726 if (bc) 03727 ch->bc=(struct misdn_bchannel*)user_data; 03728 break; 03729 03730 case EVENT_DTMF_TONE: 03731 { 03732 /* sending INFOS as DTMF-Frames :) */ 03733 struct ast_frame fr; 03734 memset(&fr, 0 , sizeof(fr)); 03735 fr.frametype = AST_FRAME_DTMF; 03736 fr.subclass = bc->dtmf ; 03737 fr.src=NULL; 03738 fr.data = NULL ; 03739 fr.datalen = 0; 03740 fr.samples = 0 ; 03741 fr.mallocd =0 ; 03742 fr.offset= 0 ; 03743 fr.delivery= ast_tv(0,0) ; 03744 03745 if (!ch->ignore_dtmf) { 03746 chan_misdn_log(2, bc->port, " --> DTMF:%c\n", bc->dtmf); 03747 ast_queue_frame(ch->ast, &fr); 03748 } else { 03749 chan_misdn_log(2, bc->port, " --> Ingoring DTMF:%c due to bridge flags\n", bc->dtmf); 03750 } 03751 } 03752 break; 03753 case EVENT_STATUS: 03754 break; 03755 03756 case EVENT_INFORMATION: 03757 { 03758 int stop_tone; 03759 misdn_cfg_get( 0, MISDN_GEN_STOP_TONE, &stop_tone, sizeof(int)); 03760 if ( stop_tone ) { 03761 stop_indicate(ch); 03762 } 03763 03764 if (ch->state == MISDN_WAITING4DIGS ) { 03765 /* Ok, incomplete Setup, waiting till extension exists */ 03766 03767 if (ast_strlen_zero(bc->info_dad) && ! ast_strlen_zero(bc->keypad)) { 03768 chan_misdn_log(1, bc->port, " --> using keypad as info\n"); 03769 strcpy(bc->info_dad,bc->keypad); 03770 } 03771 03772 { 03773 int l = sizeof(bc->dad); 03774 strncat(bc->dad,bc->info_dad, l); 03775 bc->dad[l-1] = 0; 03776 } 03777 03778 03779 { 03780 int l = sizeof(ch->ast->exten); 03781 strncpy(ch->ast->exten, bc->dad, l); 03782 ch->ast->exten[l-1] = 0; 03783 } 03784 /* chan_misdn_log(5, bc->port, "Can Match Extension: dad:%s oad:%s\n",bc->dad,bc->oad);*/ 03785 03786 /* Check for Pickup Request first */ 03787 if (!strcmp(ch->ast->exten, ast_pickup_ext())) { 03788 int ret;/** Sending SETUP_ACK**/ 03789 ret = misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE ); 03790 if (ast_pickup_call(ch->ast)) { 03791 hangup_chan(ch); 03792 } else { 03793 struct ast_channel *chan=ch->ast; 03794 ch->state = MISDN_CALLING_ACKNOWLEDGE; 03795 ast_setstate(chan, AST_STATE_DOWN); 03796 hangup_chan(ch); 03797 ch->ast=NULL; 03798 break; 03799 } 03800 } 03801 03802 if(!ast_canmatch_extension(ch->ast, ch->context, bc->dad, 1, bc->oad)) { 03803 03804 chan_misdn_log(-1, bc->port, "Extension can never match, so disconnecting\n"); 03805 if (bc->nt) 03806 hanguptone_indicate(ch); 03807 ch->state=MISDN_EXTCANTMATCH; 03808 bc->out_cause=1; 03809 03810 misdn_lib_send_event(bc, EVENT_DISCONNECT ); 03811 03812 break; 03813 } 03814 03815 if (ch->overlap_dial) { 03816 ast_mutex_lock(&ch->overlap_tv_lock); 03817 ch->overlap_tv = ast_tvnow(); 03818 ast_mutex_unlock(&ch->overlap_tv_lock); 03819 if (ch->overlap_dial_task == -1) { 03820 ch->overlap_dial_task = 03821 misdn_tasks_add_variable(ch->overlap_dial, misdn_overlap_dial_task, ch); 03822 } 03823 break; 03824 } 03825 03826 if (ast_exists_extension(ch->ast, ch->context, bc->dad, 1, bc->oad)) { 03827 ch->state=MISDN_DIALING; 03828 03829 stop_indicate(ch); 03830 /* chan_misdn_log(1, bc->port, " --> * Starting Ast ctx:%s\n", ch->context);*/ 03831 if (pbx_start_chan(ch)<0) { 03832 hangup_chan(ch); 03833 03834 chan_misdn_log(-1, bc->port, "ast_pbx_start returned < 0 in INFO\n"); 03835 if (bc->nt) hanguptone_indicate(ch); 03836 03837 misdn_lib_send_event(bc, EVENT_DISCONNECT ); 03838 } 03839 } 03840 03841 } else { 03842 /* sending INFOS as DTMF-Frames :) */ 03843 struct ast_frame fr; 03844 fr.frametype = AST_FRAME_DTMF; 03845 fr.subclass = bc->info_dad[0] ; 03846 fr.src=NULL; 03847 fr.data = NULL ; 03848 fr.datalen = 0; 03849 fr.samples = 0 ; 03850 fr.mallocd =0 ; 03851 fr.offset= 0 ; 03852 fr.delivery= ast_tv(0,0) ; 03853 03854 03855 int digits; 03856 misdn_cfg_get( 0, MISDN_GEN_APPEND_DIGITS2EXTEN, &digits, sizeof(int)); 03857 if (ch->state != MISDN_CONNECTED ) { 03858 if (digits) { 03859 int l = sizeof(bc->dad); 03860 strncat(bc->dad,bc->info_dad, l); 03861 bc->dad[l-1] = 0; 03862 l = sizeof(ch->ast->exten); 03863 strncpy(ch->ast->exten, bc->dad, l); 03864 ch->ast->exten[l-1] = 0; 03865 03866 ast_cdr_update(ch->ast); 03867 } 03868 03869 ast_queue_frame(ch->ast, &fr); 03870 } 03871 } 03872 } 03873 break; 03874 case EVENT_SETUP: 03875 { 03876 struct chan_list *ch=find_chan_by_bc(cl_te, bc); 03877 if (ch) { 03878 switch (ch->state) { 03879 case MISDN_NOTHING: 03880 ch=NULL; 03881 |