![]() |
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 break; 03882 default: 03883 chan_misdn_log(1, bc->port, " --> Ignoring Call we have already one\n"); 03884 return RESPONSE_IGNORE_SETUP_WITHOUT_CLOSE; /* Ignore MSNs which are not in our List */ 03885 } 03886 } 03887 } 03888 03889 03890 int msn_valid = misdn_cfg_is_msn_valid(bc->port, bc->dad); 03891 if (!bc->nt && ! msn_valid) { 03892 chan_misdn_log(1, bc->port, " --> Ignoring Call, its not in our MSN List\n"); 03893 return RESPONSE_IGNORE_SETUP; /* Ignore MSNs which are not in our List */ 03894 } 03895 03896 03897 if (bc->cw) { 03898 chan_misdn_log(0, bc->port, " --> Call Waiting on PMP sending RELEASE_COMPLETE\n"); 03899 int cause; 03900 misdn_cfg_get( bc->port, MISDN_CFG_REJECT_CAUSE, &cause, sizeof(cause)); 03901 bc->out_cause=cause?cause:16; 03902 return RESPONSE_RELEASE_SETUP; 03903 } 03904 03905 print_bearer(bc); 03906 03907 { 03908 struct chan_list *ch=init_chan_list(ORG_MISDN); 03909 struct ast_channel *chan; 03910 int exceed; 03911 03912 if (!ch) { chan_misdn_log(-1, bc->port, "cb_events: malloc for chan_list failed!\n"); return 0;} 03913 03914 ch->bc = bc; 03915 ch->l3id=bc->l3_id; 03916 ch->addr=bc->addr; 03917 ch->orginator = ORG_MISDN; 03918 03919 chan=misdn_new(ch, AST_STATE_RESERVED,bc->dad, bc->oad, AST_FORMAT_ALAW, bc->port, bc->channel); 03920 ch->ast = chan; 03921 03922 if ((exceed=add_in_calls(bc->port))) { 03923 char tmp[16]; 03924 sprintf(tmp,"%d",exceed); 03925 pbx_builtin_setvar_helper(chan,"MAX_OVERFLOW",tmp); 03926 } 03927 03928 read_config(ch, ORG_MISDN); 03929 03930 export_ch(chan, bc, ch); 03931 03932 ch->ast->rings=1; 03933 ast_setstate(ch->ast, AST_STATE_RINGING); 03934 03935 int pres,screen; 03936 03937 switch (bc->pres) { 03938 case 1: 03939 pres=AST_PRES_RESTRICTED; chan_misdn_log(2,bc->port," --> PRES: Restricted (1)\n"); 03940 break; 03941 case 2: 03942 pres=AST_PRES_UNAVAILABLE; chan_misdn_log(2,bc->port," --> PRES: Restricted (2)\n"); 03943 break; 03944 default: 03945 pres=AST_PRES_ALLOWED; chan_misdn_log(2,bc->port," --> PRES: Restricted (%d)\n", bc->pres); 03946 } 03947 03948 switch (bc->screen) { 03949 case 0: 03950 screen=AST_PRES_USER_NUMBER_UNSCREENED; chan_misdn_log(2,bc->port," --> SCREEN: Unscreened (0)\n"); 03951 break; 03952 case 1: 03953 screen=AST_PRES_USER_NUMBER_PASSED_SCREEN; chan_misdn_log(2,bc->port," --> SCREEN: Passed screen (1)\n"); 03954 break; 03955 case 2: 03956 screen=AST_PRES_USER_NUMBER_FAILED_SCREEN; chan_misdn_log(2,bc->port," --> SCREEN: failed screen (2)\n"); 03957 break; 03958 case 3: 03959 screen=AST_PRES_NETWORK_NUMBER; chan_misdn_log(2,bc->port," --> SCREEN: Network Number (3)\n"); 03960 break; 03961 default: 03962 screen=AST_PRES_USER_NUMBER_UNSCREENED; chan_misdn_log(2,bc->port," --> SCREEN: Unscreened (%d)\n",bc->screen); 03963 } 03964 03965 chan->cid.cid_pres=pres+screen; 03966 03967 pbx_builtin_setvar_helper(chan, "TRANSFERCAPABILITY", ast_transfercapability2str(bc->capability)); 03968 chan->transfercapability=bc->capability; 03969 03970 switch (bc->capability) { 03971 case INFO_CAPABILITY_DIGITAL_UNRESTRICTED: 03972 pbx_builtin_setvar_helper(chan,"CALLTYPE","DIGITAL"); 03973 break; 03974 default: 03975 pbx_builtin_setvar_helper(chan,"CALLTYPE","SPEECH"); 03976 } 03977 03978 /** queue new chan **/ 03979 cl_queue_chan(&cl_te, ch) ; 03980 03981 03982 if (!strstr(ch->allowed_bearers,"all")) { 03983 int i; 03984 for (i=0; i< sizeof(allowed_bearers_array)/sizeof(struct allowed_bearers); i++) { 03985 if (allowed_bearers_array[i].cap == bc->capability) { 03986 if ( !strstr( ch->allowed_bearers, allowed_bearers_array[i].name)) { 03987 chan_misdn_log(0,bc->port,"Bearer Not allowed\b"); 03988 bc->out_cause=88; 03989 03990 ch->state=MISDN_EXTCANTMATCH; 03991 misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE ); 03992 return RESPONSE_OK; 03993 } 03994 } 03995 03996 } 03997 } 03998 03999 /* Check for Pickup Request first */ 04000 if (!strcmp(chan->exten, ast_pickup_ext())) { 04001 int ret;/** Sending SETUP_ACK**/ 04002 ret = misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE ); 04003 if (ast_pickup_call(chan)) { 04004 hangup_chan(ch); 04005 } else { 04006 ch->state = MISDN_CALLING_ACKNOWLEDGE; 04007 ast_setstate(chan, AST_STATE_DOWN); 04008 hangup_chan(ch); 04009 ch->ast=NULL; 04010 break; 04011 } 04012 } 04013 04014 /* 04015 added support for s extension hope it will help those poor cretains 04016 which haven't overlap dial. 04017 */ 04018 { 04019 int ai; 04020 misdn_cfg_get( bc->port, MISDN_CFG_ALWAYS_IMMEDIATE, &ai, sizeof(ai)); 04021 if ( ai ) { 04022 do_immediate_setup(bc, ch , chan); 04023 break; 04024 } 04025 04026 04027 04028 } 04029 04030 /* check if we should jump into s when we have no dad */ 04031 { 04032 int im; 04033 misdn_cfg_get( bc->port, MISDN_CFG_IMMEDIATE, &im, sizeof(im)); 04034 if ( im && ast_strlen_zero(bc->dad) ) { 04035 do_immediate_setup(bc, ch , chan); 04036 break; 04037 } 04038 } 04039 04040 04041 chan_misdn_log(5,bc->port,"CONTEXT:%s\n",ch->context); 04042 if(!ast_canmatch_extension(ch->ast, ch->context, bc->dad, 1, bc->oad)) { 04043 04044 chan_misdn_log(-1, bc->port, "Extension can never match, so disconnecting\n"); 04045 04046 if (bc->nt) 04047 hanguptone_indicate(ch); 04048 ch->state=MISDN_EXTCANTMATCH; 04049 bc->out_cause=1; 04050 04051 if (bc->nt) 04052 misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE ); 04053 else 04054 misdn_lib_send_event(bc, EVENT_RELEASE ); 04055 04056 break; 04057 } 04058 04059 if (!ch->overlap_dial && ast_exists_extension(ch->ast, ch->context, bc->dad, 1, bc->oad)) { 04060 ch->state=MISDN_DIALING; 04061 04062 if (bc->nt || (bc->need_more_infos && misdn_lib_is_ptp(bc->port)) ) { 04063 int ret; 04064 ret = misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE ); 04065 } else { 04066 int ret; 04067 ret= misdn_lib_send_event(bc, EVENT_PROCEEDING ); 04068 } 04069 04070 if (pbx_start_chan(ch)<0) { 04071 hangup_chan(ch); 04072 04073 chan_misdn_log(-1, bc->port, "ast_pbx_start returned <0 in SETUP\n"); 04074 chan=NULL; 04075 04076 if (bc->nt) { 04077 hanguptone_indicate(ch); 04078 misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE ); 04079 } else 04080 misdn_lib_send_event(bc, EVENT_RELEASE); 04081 } 04082 } else { 04083 04084 if (bc->sending_complete) { 04085 ch->state=MISDN_EXTCANTMATCH; 04086 bc->out_cause=1; 04087 04088 if (bc->nt) { 04089 chan_misdn_log(0,bc->port," --> sending_complete so we never match ..\n"); 04090 misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE); 04091 } else { 04092 chan_misdn_log(0,bc->port," --> sending_complete so we never match ..\n"); 04093 misdn_lib_send_event(bc, EVENT_RELEASE); 04094 } 04095 04096 } else { 04097 04098 int ret= misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE ); 04099 if (ret == -ENOCHAN) { 04100 ast_log(LOG_WARNING,"Channel was catched, before we could Acknowledge\n"); 04101 misdn_lib_send_event(bc,EVENT_RELEASE_COMPLETE); 04102 } 04103 /* send tone to phone :) */ 04104 04105 /** ADD IGNOREPAT **/ 04106 04107 int stop_tone, dad_len; 04108 misdn_cfg_get( 0, MISDN_GEN_STOP_TONE, &stop_tone, sizeof(int)); 04109 04110 dad_len = ast_strlen_zero(bc->dad); 04111 04112 if ( !dad_len && stop_tone ) 04113 stop_indicate(ch); 04114 else 04115 dialtone_indicate(ch); 04116 04117 ch->state=MISDN_WAITING4DIGS; 04118 04119 if (ch->overlap_dial && !dad_len) { 04120 ast_mutex_lock(&ch->overlap_tv_lock); 04121 ch->overlap_tv = ast_tvnow(); 04122 ast_mutex_unlock(&ch->overlap_tv_lock); 04123 if (ch->overlap_dial_task == -1) { 04124 ch->overlap_dial_task = 04125 misdn_tasks_add_variable(ch->overlap_dial, misdn_overlap_dial_task, ch); 04126 } 04127 } 04128 } 04129 } 04130 04131 } 04132 break; 04133 case EVENT_SETUP_ACKNOWLEDGE: 04134 { 04135 ch->state = MISDN_CALLING_ACKNOWLEDGE; 04136 04137 if (bc->channel) 04138 update_name(ch->ast,bc->port,bc->channel); 04139 04140 if (!ast_strlen_zero(bc->infos_pending)) { 04141 /* TX Pending Infos */ 04142 04143 { 04144 int l = sizeof(bc->dad); 04145 strncat(bc->dad,bc->infos_pending, l - strlen(bc->dad)); 04146 bc->dad[l-1] = 0; 04147 } 04148 { 04149 int l = sizeof(ch->ast->exten); 04150 strncpy(ch->ast->exten, bc->dad, l); 04151 ch->ast->exten[l-1] = 0; 04152 } 04153 { 04154 int l = sizeof(bc->info_dad); 04155 strncpy(bc->info_dad, bc->infos_pending, l); 04156 bc->info_dad[l-1] = 0; 04157 } 04158 strncpy(bc->infos_pending,"", 1); 04159 04160 misdn_lib_send_event(bc, EVENT_INFORMATION); 04161 } 04162 } 04163 break; 04164 case EVENT_PROCEEDING: 04165 { 04166 04167 if ( misdn_cap_is_speech(bc->capability) && 04168 misdn_inband_avail(bc) ) { 04169 start_bc_tones(ch); 04170 } 04171 04172 ch->state = MISDN_PROCEEDING; 04173 04174 ast_queue_control(ch->ast, AST_CONTROL_PROCEEDING); 04175 } 04176 break; 04177 case EVENT_PROGRESS: 04178 if (!bc->nt ) { 04179 if ( misdn_cap_is_speech(bc->capability) && 04180 misdn_inband_avail(bc) 04181 ) { 04182 start_bc_tones(ch); 04183 } 04184 04185 ast_queue_control(ch->ast, AST_CONTROL_PROGRESS); 04186 04187 ch->state=MISDN_PROGRESS; 04188 } 04189 break; 04190 04191 04192 case EVENT_ALERTING: 04193 { 04194 ch->state = MISDN_ALERTING; 04195 04196 ast_queue_control(ch->ast, AST_CONTROL_RINGING); 04197 ast_setstate(ch->ast, AST_STATE_RINGING); 04198 04199 cb_log(7,bc->port," --> Set State Ringing\n"); 04200 04201 if ( misdn_cap_is_speech(bc->capability) && misdn_inband_avail(bc)) { 04202 cb_log(1,bc->port,"Starting Tones, we have inband Data\n"); 04203 start_bc_tones(ch); 04204 } else { 04205 cb_log(3,bc->port," --> We have no inband Data, the other end must create ringing\n"); 04206 if (ch->far_alerting) { 04207 cb_log(1,bc->port," --> The other end can not do ringing eh ?.. we must do all ourself.."); 04208 start_bc_tones(ch); 04209 /*tone_indicate(ch, TONE_FAR_ALERTING);*/ 04210 } 04211 } 04212 } 04213 break; 04214 case EVENT_CONNECT: 04215 { 04216 /*we answer when we've got our very new L3 ID from the NT stack */ 04217 misdn_lib_send_event(bc,EVENT_CONNECT_ACKNOWLEDGE); 04218 04219 struct ast_channel *bridged=AST_BRIDGED_P(ch->ast); 04220 stop_indicate(ch); 04221 04222 if (bridged && !strcasecmp(bridged->tech->type,"mISDN")) { 04223 struct chan_list *bridged_ch=MISDN_ASTERISK_TECH_PVT(bridged); 04224 04225 chan_misdn_log(1,bc->port," --> copying cpndialplan:%d and cad:%s to the A-Channel\n",bc->cpnnumplan,bc->cad); 04226 if (bridged_ch) { 04227 bridged_ch->bc->cpnnumplan=bc->cpnnumplan; 04228 ast_copy_string(bridged_ch->bc->cad,bc->cad,sizeof(bc->cad)); 04229 } 04230 } 04231 } 04232 04233 /* notice that we don't break here!*/ 04234 case EVENT_CONNECT_ACKNOWLEDGE: 04235 { 04236 ch->l3id=bc->l3_id; 04237 ch->addr=bc->addr; 04238 04239 start_bc_tones(ch); 04240 04241 04242 ch->state = MISDN_CONNECTED; 04243 ast_queue_control(ch->ast, AST_CONTROL_ANSWER); 04244 } 04245 break; 04246 case EVENT_DISCONNECT: 04247 /*we might not have an ch->ast ptr here anymore*/ 04248 if (ch) { 04249 struct chan_list *holded_ch=find_holded(cl_te, bc); 04250 04251 chan_misdn_log(3,bc->port," --> org:%d nt:%d, inbandavail:%d state:%d\n", ch->orginator, bc->nt, misdn_inband_avail(bc), ch->state); 04252 if ( ch->orginator==ORG_AST && !bc->nt && misdn_inband_avail(bc) && ch->state != MISDN_CONNECTED) { 04253 /* If there's inband information available (e.g. a 04254 recorded message saying what was wrong with the 04255 dialled number, or perhaps even giving an 04256 alternative number, then play it instead of 04257 immediately releasing the call */ 04258 chan_misdn_log(1,bc->port, " --> Inband Info Avail, not sending RELEASE\n"); 04259 04260 ch->state=MISDN_DISCONNECTED; 04261 start_bc_tones(ch); 04262 break; 04263 } 04264 04265 /*Check for holded channel, to implement transfer*/ 04266 if ( holded_ch && 04267 holded_ch != ch && 04268 ch->ast && 04269 ch->state == MISDN_CONNECTED ) { 04270 cb_log(1,bc->port," --> found holded ch\n"); 04271 misdn_transfer_bc(ch, holded_ch) ; 04272 } 04273 04274 stop_bc_tones(ch); 04275 hangup_chan(ch); 04276 } else { 04277 /* ch=find_holded_l3(cl_te, bc->l3_id,1); 04278 if (ch) { 04279 hangup_chan(ch); 04280 } 04281 */ 04282 } 04283 bc->out_cause=-1; 04284 if (bc->need_release) misdn_lib_send_event(bc,EVENT_RELEASE); 04285 break; 04286 04287 case EVENT_RELEASE: 04288 { 04289 bc->out_cause=16; 04290 04291 hangup_chan(ch); 04292 release_chan(bc); 04293 04294 if (bc->need_release_complete) 04295 misdn_lib_send_event(bc,EVENT_RELEASE_COMPLETE); 04296 } 04297 break; 04298 case EVENT_RELEASE_COMPLETE: 04299 { 04300 stop_bc_tones(ch); 04301 hangup_chan(ch); 04302 release_chan(bc); 04303 if(ch) 04304 ch->state=MISDN_CLEANING; 04305 } 04306 break; 04307 case EVENT_BCHAN_ERROR: 04308 case EVENT_CLEANUP: 04309 { 04310 stop_bc_tones(ch); 04311 04312 switch(ch->state) { 04313 case MISDN_CALLING: 04314 bc->cause=27; /* Destination out of order */ 04315 break; 04316 default: 04317 break; 04318 } 04319 04320 hangup_chan(ch); 04321 release_chan(bc); 04322 } 04323 break; 04324 04325 case EVENT_TONE_GENERATE: 04326 { 04327 int tone_len=bc->tone_cnt; 04328 struct ast_channel *ast=ch->ast; 04329 void *tmp; 04330 int res; 04331 int (*generate)(struct ast_channel *chan, void *tmp, int datalen, int samples); 04332 04333 chan_misdn_log(9,bc->port,"TONE_GEN: len:%d\n"); 04334 04335 if (!ast) break; 04336 04337 if (!ast->generator) break; 04338 04339 04340 04341 tmp = ast->generatordata; 04342 ast->generatordata = NULL; 04343 generate = ast->generator->generate; 04344 04345 if (tone_len <0 || tone_len > 512 ) { 04346 ast_log(LOG_NOTICE, "TONE_GEN: len was %d, set to 128\n",tone_len); 04347 tone_len=128; 04348 } 04349 04350 res = generate(ast, tmp, tone_len, tone_len); 04351 ast->generatordata = tmp; 04352 04353 if (res) { 04354 ast_log(LOG_WARNING, "Auto-deactivating generator\n"); 04355 ast_deactivate_generator(ast); 04356 } else { 04357 bc->tone_cnt=0; 04358 } 04359 } 04360 break; 04361 04362 case EVENT_BCHAN_DATA: 04363 { 04364 if ( !misdn_cap_is_speech(ch->bc->capability) ) { 04365 struct ast_frame frame; 04366 /*In Data Modes we queue frames*/ 04367 frame.frametype = AST_FRAME_VOICE; /*we have no data frames yet*/ 04368 frame.subclass = AST_FORMAT_ALAW; 04369 frame.datalen = bc->bframe_len; 04370 frame.samples = bc->bframe_len ; 04371 frame.mallocd =0 ; 04372 frame.offset= 0 ; 04373 frame.delivery= ast_tv(0,0) ; 04374 frame.src = NULL; 04375 frame.data = bc->bframe ; 04376 04377 ast_queue_frame(ch->ast,&frame); 04378 } else { 04379 fd_set wrfs; 04380 struct timeval tv; 04381 tv.tv_sec=0; 04382 tv.tv_usec=0; 04383 04384 04385 FD_ZERO(&wrfs); 04386 FD_SET(ch->pipe[1],&wrfs); 04387 04388 int t=select(FD_SETSIZE,NULL,&wrfs,NULL,&tv); 04389 04390 if (!t) { 04391 chan_misdn_log(9, bc->port, "Select Timed out\n"); 04392 break; 04393 } 04394 04395 if (t<0) { 04396 chan_misdn_log(-1, bc->port, "Select Error (err=%s)\n",strerror(errno)); 04397 break; 04398 } 04399 04400 if (FD_ISSET(ch->pipe[1],&wrfs)) { 04401 chan_misdn_log(9, bc->port, "writing %d bytes 2 asterisk\n",bc->bframe_len); 04402 int ret=write(ch->pipe[1], bc->bframe, bc->bframe_len); 04403 04404 if (ret<=0) { 04405 chan_misdn_log(-1, bc->port, "Write returned <=0 (err=%s) --> hanging up channel\n",strerror(errno)); 04406 04407 stop_bc_tones(ch); 04408 hangup_chan(ch); 04409 release_chan(bc); 04410 } 04411 } else { 04412 chan_misdn_log(1, bc->port, "Wripe Pipe full!\n"); 04413 } 04414 } 04415 } 04416 break; 04417 case EVENT_TIMEOUT: 04418 { 04419 if (ch && bc) 04420 chan_misdn_log(1,bc->port,"--> state: %s\n",misdn_get_ch_state(ch)); 04421 04422 switch (ch->state) { 04423 case MISDN_DIALING: 04424 case MISDN_PROGRESS: 04425 if (bc->nt && !ch->nttimeout) break; 04426 04427 case MISDN_CALLING: 04428 case MISDN_ALERTING: 04429 case MISDN_PROCEEDING: 04430 case MISDN_CALLING_ACKNOWLEDGE: 04431 if (bc->nt) { 04432 bc->progress_indicator=8; 04433 hanguptone_indicate(ch); 04434 } 04435 04436 bc->out_cause=1; 04437 misdn_lib_send_event(bc,EVENT_DISCONNECT); 04438 break; 04439 04440 case MISDN_WAITING4DIGS: 04441 if (bc->nt) { 04442 bc->progress_indicator=8; 04443 bc->out_cause=1; 04444 hanguptone_indicate(ch); 04445 misdn_lib_send_event(bc,EVENT_DISCONNECT); 04446 } else { 04447 bc->out_cause=16; 04448 misdn_lib_send_event(bc,EVENT_RELEASE); 04449 } 04450 04451 break; 04452 04453 04454 case MISDN_CLEANING: 04455 chan_misdn_log(1,bc->port," --> in state cleaning .. so ingoring, the stack should clean it for us\n"); 04456 break; 04457 04458 default: 04459 misdn_lib_send_event(bc,EVENT_RELEASE_COMPLETE); 04460 } 04461 } 04462 break; 04463 04464 04465 /***************************/ 04466 /** Suplementary Services **/ 04467 /***************************/ 04468 case EVENT_RETRIEVE: 04469 { 04470 ch=find_holded_l3(cl_te, bc->l3_id,1); 04471 if (!ch) { 04472 ast_log(LOG_WARNING, "Found no Holded channel, cannot Retrieve\n"); 04473 misdn_lib_send_event(bc, EVENT_RETRIEVE_REJECT); 04474 break; 04475 } 04476 04477 /*remember the channel again*/ 04478 ch->bc=bc; 04479 ch->state = MISDN_CONNECTED; 04480 04481 ch->hold_info.port=0; 04482 ch->hold_info.channel=0; 04483 04484 struct ast_channel *hold_ast=AST_BRIDGED_P(ch->ast); 04485 04486 if (hold_ast) { 04487 ast_moh_stop(hold_ast); 04488 } 04489 04490 if ( misdn_lib_send_event(bc, EVENT_RETRIEVE_ACKNOWLEDGE) < 0) 04491 misdn_lib_send_event(bc, EVENT_RETRIEVE_REJECT); 04492 } 04493 break; 04494 04495 case EVENT_HOLD: 04496 { 04497 int hold_allowed; 04498 misdn_cfg_get( bc->port, MISDN_CFG_HOLD_ALLOWED, &hold_allowed, sizeof(int)); 04499 04500 if (!hold_allowed) { 04501 04502 chan_misdn_log(-1, bc->port, "Hold not allowed this port.\n"); 04503 misdn_lib_send_event(bc, EVENT_HOLD_REJECT); 04504 break; 04505 } 04506 04507 struct ast_channel *bridged=AST_BRIDGED_P(ch->ast); 04508 04509 if (bridged) { 04510 chan_misdn_log(2,bc->port,"Bridge Partner is of type: %s\n",bridged->tech->type); 04511 ch->state = MISDN_HOLDED; 04512 ch->l3id = bc->l3_id; 04513 04514 misdn_lib_send_event(bc, EVENT_HOLD_ACKNOWLEDGE); 04515 04516 /* XXX This should queue an AST_CONTROL_HOLD frame on this channel 04517 * instead of starting moh on the bridged channel directly */ 04518 ast_moh_start(bridged, NULL, NULL); 04519 04520 /*forget the channel now*/ 04521 ch->bc=NULL; 04522 ch->hold_info.port=bc->port; 04523 ch->hold_info.channel=bc->channel; 04524 04525 } else { 04526 misdn_lib_send_event(bc, EVENT_HOLD_REJECT); 04527 chan_misdn_log(0, bc->port, "We aren't bridged to anybody\n"); 04528 } 04529 } 04530 break; 04531 04532 case EVENT_FACILITY: 04533 print_facility(&(bc->fac_in), bc); 04534 04535 switch (bc->fac_in.Function) { 04536 case Fac_CD: 04537 { 04538 struct ast_channel *bridged=AST_BRIDGED_P(ch->ast); 04539 struct chan_list *ch_br; 04540 if (bridged && MISDN_ASTERISK_TECH_PVT(bridged)) { 04541 ch_br=MISDN_ASTERISK_TECH_PVT(bridged); 04542 /*ch->state=MISDN_FACILITY_DEFLECTED;*/ 04543 if (ch_br->bc) { 04544 if (ast_exists_extension(bridged, ch->context, (char *)bc->fac_in.u.CDeflection.DeflectedToNumber, 1, bc->oad)) { 04545 ch_br->state=MISDN_DIALING; 04546 if (pbx_start_chan(ch_br) < 0) { 04547 chan_misdn_log(-1, ch_br->bc->port, "ast_pbx_start returned < 0 in misdn_overlap_dial_task\n"); 04548 } 04549 } 04550 } 04551 04552 } 04553 misdn_lib_send_event(bc, EVENT_DISCONNECT); 04554 } 04555 break; 04556 case Fac_AOCDCurrency: 04557 bc->AOCDtype = Fac_AOCDCurrency; 04558 memcpy(&(bc->AOCD.currency), &(bc->fac_in.u.AOCDcur), sizeof(struct FacAOCDCurrency)); 04559 break; 04560 case Fac_AOCDChargingUnit: 04561 bc->AOCDtype = Fac_AOCDChargingUnit; 04562 memcpy(&(bc->AOCD.chargingUnit), &(bc->fac_in.u.AOCDchu), sizeof(struct FacAOCDChargingUnit)); 04563 break; 04564 default: 04565 chan_misdn_log(0, bc->port," --> not yet handled: facility type:%p\n", bc->fac_in.Function); 04566 } 04567 04568 break; 04569 04570 case EVENT_RESTART: 04571 04572 stop_bc_tones(ch); 04573 release_chan(bc); 04574 04575 break; 04576 04577 default: 04578 chan_misdn_log(1,0, "Got Unknown Event\n"); 04579 break; 04580 } 04581 04582 return RESPONSE_OK; 04583 }
|
|
||||||||||||||||
|
Definition at line 5002 of file chan_misdn.c. References cl_te, find_chan_by_bc(), chan_list::jb, and misdn_jb_empty(). 05003 { 05004 struct chan_list *ch=find_chan_by_bc(cl_te, bc); 05005 05006 if (ch && ch->jb) { 05007 return misdn_jb_empty(ch->jb, buf, len); 05008 } 05009 05010 return -1; 05011 }
|
|
||||||||||||||||||||
|
Definition at line 5187 of file chan_misdn.c. References ast_console_puts(), ast_log(), ast_strlen_zero(), 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_holded(), import_ch(), init_chan_list(), misdn_answer(), misdn_bridge(), misdn_call(), misdn_digit_end(), misdn_facility_exec(), misdn_fixup(), misdn_hangup(), misdn_indication(), misdn_jb_init(), misdn_l1_task(), misdn_overlap_dial_task(), misdn_read(), misdn_request(), misdn_set_opt_exec(), misdn_tasks_destroy(), misdn_tasks_init(), misdn_tasks_thread_func(), misdn_transfer_bc(), misdn_write(), print_bearer(), print_facility(), process_ast_dsp(), read_config(), release_chan(), send_cause2ast(), stop_indicate(), and update_config(). 05188 { 05189 if (! ((0 <= port) && (port <= max_ports))) { 05190 ast_log(LOG_WARNING, "cb_log called with out-of-range port number! (%d)\n", port); 05191 port=0; 05192 level=-1; 05193 } 05194 05195 va_list ap; 05196 char buf[1024]; 05197 char port_buf[8]; 05198 sprintf(port_buf,"P[%2d] ",port); 05199 05200 va_start(ap, tmpl); 05201 vsnprintf( buf, 1023, tmpl, ap ); 05202 va_end(ap); 05203 05204 if (level == -1) 05205 ast_log(LOG_WARNING, buf); 05206 05207 else if (misdn_debug_only[port] ? 05208 (level==1 && misdn_debug[port]) || (level==misdn_debug[port]) 05209 : level <= misdn_debug[port]) { 05210 05211 ast_console_puts(port_buf); 05212 ast_console_puts(buf); 05213 } 05214 05215 if ((level <= misdn_debug[0]) && !ast_strlen_zero(global_tracefile) ) { 05216 time_t tm = time(NULL); 05217 char *tmp=ctime(&tm),*p; 05218 05219 FILE *fp= fopen(global_tracefile, "a+"); 05220 05221 p=strchr(tmp,'\n'); 05222 if (p) *p=':'; 05223 05224 if (!fp) { 05225 ast_console_puts("Error opening Tracefile: [ "); 05226 ast_console_puts(global_tracefile); 05227 ast_console_puts(" ] "); 05228 05229 ast_console_puts(strerror(errno)); 05230 ast_console_puts("\n"); 05231 return ; 05232 } 05233 05234 fputs(tmp,fp); 05235 fputs(" ", fp); 05236 fputs(port_buf,fp); 05237 fputs(" ", fp); 05238 fputs(buf, fp); 05239 05240 fclose(fp); 05241 } 05242 }
|
|
||||||||||||
|
Definition at line 3265 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(). 03266 { 03267 if (chan->dsp) 03268 ast_dsp_free(chan->dsp); 03269 if (chan->trans) 03270 ast_translator_free_path(chan->trans); 03271 03272 03273 03274 ast_mutex_lock(&cl_te_lock); 03275 if (!*list) { 03276 ast_mutex_unlock(&cl_te_lock); 03277 return; 03278 } 03279 03280 if (*list == chan) { 03281 *list=(*list)->next; 03282 ast_mutex_unlock(&cl_te_lock); 03283 return ; 03284 } 03285 03286 { 03287 struct chan_list *help=*list; 03288 for (;help->next; help=help->next) { 03289 if (help->next == chan) { 03290 help->next=help->next->next; 03291 ast_mutex_unlock(&cl_te_lock); 03292 return; 03293 } 03294 } 03295 } 03296 03297 ast_mutex_unlock(&cl_te_lock); 03298 }
|
|
||||||||||||
|
Definition at line 3249 of file chan_misdn.c. References ast_mutex_lock(), ast_mutex_unlock(), chan_list::bc, chan_misdn_log(), cl_te_lock, and chan_list::next. Referenced by cb_events(). 03250 { 03251 chan_misdn_log(4, chan->bc? chan->bc->port : 0, "* Queuing chan %p\n",chan); 03252 03253 ast_mutex_lock(&cl_te_lock); 03254 if (!*list) { 03255 *list = chan; 03256 } else { 03257 struct chan_list *help=*list; 03258 for (;help->next; help=help->next); 03259 help->next=chan; 03260 } 03261 chan->next=NULL; 03262 ast_mutex_unlock(&cl_te_lock); 03263 }
|
|
||||||||||||||||||||
|
Definition at line 1329 of file chan_misdn.c. References complete_ch_helper(). 01330 { 01331 return complete_ch_helper(line, word, pos, state, 3); 01332 }
|
|
||||||||||||||||||||||||
|
Definition at line 1305 of file chan_misdn.c. References ast_channel_walk_locked(), ast_mutex_unlock(), ast_channel::lock, and strdup. Referenced by complete_ch(). 01306 { 01307 struct ast_channel *c; 01308 int which=0; 01309 char *ret; 01310 if (pos != rpos) 01311 return NULL; 01312 c = ast_channel_walk_locked(NULL); 01313 while(c) { 01314 if (!strncasecmp(word, c->name, strlen(word))) { 01315 if (++which > state) 01316 break; 01317 } 01318 ast_mutex_unlock(&c->lock); 01319 c = ast_channel_walk_locked(c); 01320 } 01321 if (c) { 01322 ret = strdup(c->name); 01323 ast_mutex_unlock(&c->lock); 01324 } else 01325 ret = NULL; 01326 return ret; 01327 }
|
|
||||||||||||||||||||
|
Definition at line 1334 of file chan_misdn.c. References strdup. 01335 { 01336 if (state) 01337 return NULL; 01338 01339 switch (pos) { 01340 case 4: if (*word == 'p') 01341 return strdup("port"); 01342 else if (*word == 'o') 01343 return strdup("only"); 01344 break; 01345 case 6: if (*word == 'o') 01346 return strdup("only"); 01347 break; 01348 } 01349 return NULL; 01350 }
|
|
||||||||||||||||||||
|
Definition at line 1352 of file chan_misdn.c. References misdn_cfg_get_name(), misdn_cfg_get_next_port(), and strdup. 01353 { 01354 char buffer[BUFFERSIZE]; 01355 enum misdn_cfg_elements elem; 01356 int wordlen = strlen(word); 01357 int which = 0; 01358 int port = 0; 01359 01360 switch (pos) { 01361 case 3: if ((!strncmp(word, "description", wordlen)) && (++which > state)) 01362 return strdup("description"); 01363 if ((!strncmp(word, "descriptions", wordlen)) && (++which > state)) 01364 return strdup("descriptions"); 01365 if ((!strncmp(word, "0", wordlen)) && (++which > state)) 01366 return strdup("0"); 01367 while ((port = misdn_cfg_get_next_port(port)) != -1) { 01368 snprintf(buffer, sizeof(buffer), "%d", port); 01369 if ((!strncmp(word, buffer, wordlen)) && (++which > state)) { 01370 return strdup(buffer); 01371 } 01372 } 01373 break; 01374 case 4: 01375 if (strstr(line, "description ")) { 01376 for (elem = MISDN_CFG_FIRST + 1; elem < MISDN_GEN_LAST; ++elem) { 01377 if ((elem == MISDN_CFG_LAST) || (elem == MISDN_GEN_FIRST)) 01378 continue; 01379 misdn_cfg_get_name(elem, buffer, BUFFERSIZE); 01380 if (!wordlen || !strncmp(word, buffer, wordlen)) { 01381 if (++which > state) 01382 return strdup(buffer); 01383 } 01384 } 01385 } else if (strstr(line, "descriptions ")) { 01386 if ((!wordlen || !strncmp(word, "general", wordlen)) && (++which > state)) 01387 return strdup("general"); 01388 if ((!wordlen || !strncmp(word, "ports", wordlen)) && (++which > state)) 01389 return strdup("ports"); 01390 } 01391 break; 01392 } 01393 return NULL; 01394 }
|
|
|
Definition at line 1544 of file chan_misdn.c. References chan_list::bc, chan_misdn_log(), chan_list::jb, chan_list::jb_len, chan_list::jb_upper_threshold, len, misdn_jb_destroy(), and misdn_jb_init(). Referenced by read_config(). 01545 { 01546 struct misdn_bchannel *bc=ch->bc; 01547 int len=ch->jb_len, threshold=ch->jb_upper_threshold; 01548 01549 chan_misdn_log(5,bc->port, "config_jb: Called\n"); 01550 01551 if ( ! len ) { 01552 chan_misdn_log(1,bc->port, "config_jb: Deactivating Jitterbuffer\n"); 01553 bc->nojitter=1; 01554 } else { 01555 01556 if (len <=100 || len > 8000) { 01557 chan_misdn_log(0,bc->port,"config_jb: Jitterbuffer out of Bounds, setting to 1000\n"); 01558 len=1000; 01559 } 01560 01561 if ( threshold > len ) { 01562 chan_misdn_log(0,bc->port,"config_jb: Jitterbuffer Threshold > Jitterbuffer setting to Jitterbuffer -1\n"); 01563 } 01564 01565 if ( ch->jb) { 01566 cb_log(0,bc->port,"config_jb: We've got a Jitterbuffer Already on this port.\n"); 01567 misdn_jb_destroy(ch->jb); 01568 ch->jb=NULL; 01569 } 01570 01571 ch->jb=misdn_jb_init(len, threshold); 01572 01573 if (!ch->jb ) 01574 bc->nojitter=1; 01575 } 01576 }
|
|
||||||||||||||||
|
Definition at line 1579 of file chan_misdn.c. References chan_misdn_log(). Referenced by read_config(). 01580 { 01581 switch (numplan) { 01582 case NUMPLAN_INTERNATIONAL: 01583 chan_misdn_log(2, port, " --> %s: International\n",type); 01584 break; 01585 case NUMPLAN_NATIONAL: 01586 chan_misdn_log(2, port, " --> %s: National\n",type); 01587 break; 01588 case NUMPLAN_SUBSCRIBER: 01589 chan_misdn_log(2, port, " --> %s: Subscriber\n",type); 01590 break; 01591 case NUMPLAN_UNKNOWN: 01592 chan_misdn_log(2, port, " --> %s: Unknown\n",type); 01593 break; 01594 /* Maybe we should cut off the prefix if present ? */ 01595 default: 01596 chan_misdn_log(0, port, " --> !!!! Wrong dialplan setting, please see the misdn.conf sample file\n "); 01597 break; 01598 } 01599 }
|
|
|
AST INDICATIONS END Definition at line 2777 of file chan_misdn.c. References chan_list::ast, ast_get_indication_tone(), ast_playtones_start(), chan_list::bc, chan_misdn_log(), ind_tone_zone_sound::data, misdn_cfg_get(), chan_list::norxtone, chan_list::notxtone, chan_list::ts, and ast_channel::zone. Referenced by do_immediate_setup(). 02778 { 02779 const struct ind_tone_zone_sound *ts= NULL; 02780 struct ast_channel *ast=cl->ast; 02781 02782 if (!ast) { 02783 chan_misdn_log(0,cl->bc->port,"No Ast in dialtone_indicate\n"); 02784 return -1; 02785 } 02786 02787 int nd=0; 02788 misdn_cfg_get( cl->bc->port, MISDN_CFG_NODIALTONE, &nd, sizeof(nd)); 02789 02790 if (nd) { 02791 chan_misdn_log(1,cl->bc->port,"Not sending Dialtone, because config wants it\n"); 02792 return 0; 02793 } 02794 02795 chan_misdn_log(3,cl->bc->port," --> Dial\n"); 02796 ts=ast_get_indication_tone(ast->zone,"dial"); 02797 cl->ts=ts; 02798 02799 if (ts) { 02800 cl->notxtone=0; 02801 cl->norxtone=0; 02802 ast_playtones_start(ast,0, ts->data, 0); 02803 chan_misdn_log(4,cl->bc->port,"Starting Playtones\n"); 02804 misdn_lib_tone_generator_start(cl->bc); 02805 } 02806 02807 return 0; 02808 }
|
|
||||||||||||||||
|
Definition at line 3434 of file chan_misdn.c. References chan_list::ast, AST_CID_P, AST_FRAME_DTMF, ast_queue_frame(), ast_strlen_zero(), chan_misdn_log(), ast_channel::context, ast_frame::data, ast_frame::datalen, ast_frame::delivery, dialtone_indicate(), ast_channel::exten, ast_frame::frametype, hangup_chan(), hanguptone_indicate(), chan_list::incoming_early_audio, ast_frame::mallocd, MISDN_ASTERISK_PVT, MISDN_ASTERISK_TECH_PVT, MISDN_DIALING, ast_frame::offset, ORG_MISDN, chan_list::orginator, pbx_start_chan(), ast_frame::samples, ast_frame::src, chan_list::state, and ast_frame::subclass. 03435 { 03436 char predial[256]=""; 03437 char *p = predial; 03438 03439 struct ast_frame fr; 03440 03441 strncpy(predial, ast->exten, sizeof(predial) -1 ); 03442 03443 ch->state=MISDN_DIALING; 03444 03445 if (bc->nt) { 03446 int ret; 03447 ret = misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE ); 03448 } else { 03449 int ret; 03450 if ( misdn_lib_is_ptp(bc->port)) { 03451 ret = misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE ); 03452 } else { 03453 ret = misdn_lib_send_event(bc, EVENT_PROCEEDING ); 03454 } 03455 } 03456 03457 if ( !bc->nt && (ch->orginator==ORG_MISDN) && !ch->incoming_early_audio ) 03458 chan_misdn_log(1,bc->port, " --> incoming_early_audio off\n"); 03459 else 03460 dialtone_indicate(ch); 03461 03462 chan_misdn_log(1, bc->port, "* Starting Ast ctx:%s dad:%s oad:%s with 's' extension\n", ast->context, ast->exten, AST_CID_P(ast)); 03463 03464 strncpy(ast->exten,"s", 2); 03465 03466 if (pbx_start_chan(ch)<0) { 03467 ast=NULL; 03468 hangup_chan(ch); 03469 hanguptone_indicate(ch); 03470 03471 if (bc->nt) 03472 misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE ); 03473 else 03474 misdn_lib_send_event(bc, EVENT_DISCONNECT ); 03475 } 03476 03477 03478 while (!ast_strlen_zero(p) ) { 03479 fr.frametype = AST_FRAME_DTMF; 03480 fr.subclass = *p ; 03481 fr.src=NULL; 03482 fr.data = NULL ; 03483 fr.datalen = 0; 03484 fr.samples = 0 ; 03485 fr.mallocd =0 ; 03486 fr.offset= 0 ; 03487 fr.delivery= ast_tv(0,0) ; 03488 03489 if (ch->ast && MISDN_ASTERISK_PVT(ch->ast) && MISDN_ASTERISK_TECH_PVT(ch->ast)) { 03490 ast_queue_frame(ch->ast, &fr); 03491 } 03492 p++; 03493 } 03494 }
|
|
||||||||||||||||
|
Definition at line 3575 of file chan_misdn.c. References chan_misdn_log(), and pbx_builtin_setvar_helper(). Referenced by cb_events(). 03576 { 03577 char tmp[32]; 03578 chan_misdn_log(3,bc->port," --> EXPORT_PID: pid:%d\n",bc->pid); 03579 sprintf(tmp,"%d",bc->pid); 03580 pbx_builtin_setvar_helper(chan,"_MISDN_PID",tmp); 03581 03582 if (bc->sending_complete) { 03583 sprintf(tmp,"%d",bc->sending_complete); 03584 pbx_builtin_setvar_helper(chan,"MISDN_ADDRESS_COMPLETE",tmp); 03585 } 03586 03587 if (bc->urate) { 03588 sprintf(tmp,"%d",bc->urate); 03589 pbx_builtin_setvar_helper(chan,"MISDN_URATE",tmp); 03590 } 03591 }
|
|
||||||||||||
|
Definition at line 3193 of file chan_misdn.c. References chan_list::bc, and chan_list::next. Referenced by cb_events(), chan_misdn_jb_empty(), and release_chan(). 03194 { 03195 struct chan_list *help=list; 03196 for (;help; help=help->next) { 03197 if (help->bc == bc) return help; 03198 } 03199 03200 chan_misdn_log(6, bc->port, "$$$ find_chan: No channel found for oad:%s dad:%s\n",bc->oad,bc->dad); 03201 03202 return NULL; 03203 }
|
|
||||||||||||
|
Definition at line 3205 of file chan_misdn.c. References chan_list::bc, and chan_list::next. Referenced by import_ch(). 03206 { 03207 struct chan_list *help=list; 03208 for (;help; help=help->next) { 03209 if ( help->bc && (help->bc->pid == pid) ) return help; 03210 } 03211 03212 chan_misdn_log(6, 0, "$$$ find_chan: No channel found for pid:%d\n",pid); 03213 03214 return NULL; 03215 }
|
|
||||||||||||
|
Definition at line 3217 of file chan_misdn.c. References chan_misdn_log(), hold_info::channel, chan_list::hold_info, MISDN_HOLDED, chan_list::next, hold_info::port, and chan_list::state. Referenced by cb_events(). 03218 { 03219 struct chan_list *help=list; 03220 03221 chan_misdn_log(6, bc->port, "$$$ find_holded: channel:%d oad:%s dad:%s\n",bc->channel, bc->oad,bc->dad); 03222 for (;help; help=help->next) { 03223 chan_misdn_log(4, bc->port, "$$$ find_holded: --> holded:%d channel:%d\n",help->state==MISDN_HOLDED, help->hold_info.channel); 03224 if ( (help->state == MISDN_HOLDED) && 03225 (help->hold_info.port == bc->port) ) 03226 return help; 03227 } 03228 chan_misdn_log(6, bc->port, "$$$ find_chan: No channel found for oad:%s dad:%s\n",bc->oad,bc->dad); 03229 03230 return NULL; 03231 }
|
|
||||||||||||||||
|
Definition at line 3234 of file chan_misdn.c. References chan_list::l3id, MISDN_HOLDED, chan_list::next, and chan_list::state. 03236 { 03237 struct chan_list *help=list; 03238 03239 for (;help; help=help->next) { 03240 if ( (help->state == MISDN_HOLDED) && 03241 (help->l3id == l3_id) 03242 ) 03243 return help; 03244 } 03245 03246 return NULL; 03247 }
|
|
|
Definition at line 249 of file chan_misdn.c. References free_robin_list_r(), and robin. Referenced by reload_config(), and unload_module(). 00250 { 00251 free_robin_list_r(robin); 00252 robin = NULL; 00253 }
|
|
|
Definition at line 240 of file chan_misdn.c. References free, robin_list::group, and robin_list::next. Referenced by free_robin_list(). 00241 { 00242 if (r) { 00243 if (r->next) free_robin_list_r(r->next); 00244 if (r->group) free(r->group); 00245 free(r); 00246 } 00247 }
|
|
|
Definition at line 368 of file chan_misdn.c. References chan_list::ast, cl_te, and chan_list::next. Referenced by misdn_bridge(). 00369 { 00370 struct chan_list *tmp; 00371 00372 for (tmp=cl_te; tmp; tmp = tmp->next) { 00373 if ( tmp->ast == ast ) return tmp; 00374 } 00375 00376 return NULL; 00377 }
|
|
|
Definition at line 379 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(). 00380 { 00381 struct chan_list *tmp; 00382 00383 for (tmp=cl_te; tmp; tmp = tmp->next) { 00384 if ( tmp->ast && strcmp(tmp->ast->name,name) == 0) return tmp; 00385 } 00386 00387 return NULL; 00388 }
|
|
|
Definition at line 255 of file chan_misdn.c. References robin_list::group, robin_list::next, and robin. Referenced by misdn_request(). 00256 { 00257 struct robin_list *iter = robin; 00258 for (; iter; iter = iter->next) { 00259 if (!strcasecmp(iter->group, group)) 00260 return iter; 00261 } 00262 struct robin_list *new = (struct robin_list *)calloc(1, sizeof(struct robin_list)); 00263 new->group = strndup(group, strlen(group)); 00264 new->channel = 1; 00265 if (robin) { 00266 new->next = robin; 00267 robin->prev = new; 00268 } 00269 robin = new; 00270 return robin; 00271 }
|
|
|
Definition at line 3315 of file chan_misdn.c. References chan_list::ast, ast_hangup(), ast_queue_hangup(), chan_list::bc, chan_list::need_hangup, chan_list::need_queue_hangup, and send_cause2ast(). Referenced by cb_events(), and do_immediate_setup(). 03316 { 03317 int port=ch?ch->bc?ch->bc->port:0:0; 03318 if (!ch) { 03319 cb_log(1,0,"Cannot hangup chan, no ch\n"); 03320 return; 03321 } 03322 03323 cb_log(5,port,"hangup_chan called\n"); 03324 03325 if (ch->need_hangup) 03326 { 03327 cb_log(2,port," --> hangup\n"); 03328 send_cause2ast(ch->ast,ch->bc,ch); 03329 ch->need_hangup=0; 03330 ch->need_queue_hangup=0; 03331 if (ch->ast) 03332 ast_hangup(ch->ast); 03333 return; 03334 } 03335 03336 if (!ch->need_queue_hangup) { 03337 cb_log(2,port," --> No need to queue hangup\n"); 03338 } 03339 03340 ch->need_queue_hangup=0; 03341 if (ch->ast) { 03342 send_cause2ast(ch->ast,ch->bc,ch); 03343 03344 if (ch->ast) 03345 ast_queue_hangup(ch->ast); 03346 cb_log(2,port," --> queue_hangup\n"); 03347 } else { 03348 cb_log(1,port,"Cannot hangup chan, no ast\n"); 03349 } 03350 }
|
|
|
Definition at line 2810 of file chan_misdn.c. References chan_list::bc. Referenced by cb_events(), do_immediate_setup(), misdn_hangup(), misdn_indication(), and misdn_overlap_dial_task(). 02811 { 02812 misdn_lib_send_tone(cl->bc,TONE_HANGUP); 02813 return 0; 02814 }
|
|
||||||||||||||||
|
Definition at line 3556 of file chan_misdn.c. References chan_misdn_log(), cl_te, find_chan_by_pid(), chan_list::other_ch, chan_list::other_pid, and pbx_builtin_getvar_helper(). Referenced by misdn_call(). 03557 { 03558 const char *tmp; 03559 tmp=pbx_builtin_getvar_helper(chan,"MISDN_PID"); 03560 if (tmp) { 03561 ch->other_pid=atoi(tmp); 03562 chan_misdn_log(3,bc->port," --> IMPORT_PID: importing pid:%s\n",tmp); 03563 if (ch->other_pid >0) { 03564 ch->other_ch=find_chan_by_pid(cl_te,ch->other_pid); 03565 if (ch->other_ch) ch->other_ch->other_ch=ch; 03566 } 03567 } 03568 03569 tmp=pbx_builtin_getvar_helper(chan,"MISDN_ADDRESS_COMPLETE"); 03570 if (tmp && (atoi(tmp) == 1)) { 03571 bc->sending_complete=1; 03572 } 03573 }
|
|
|
Definition at line 2853 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::orginator, and chan_list::overlap_dial_task. Referenced by cb_events(), and misdn_request(). 02854 { 02855 struct chan_list *cl=malloc(sizeof(struct chan_list)); 02856 02857 if (!cl) { 02858 chan_misdn_log(-1, 0, "misdn_request: malloc failed!"); 02859 return NULL; 02860 } 02861 02862 memset(cl,0,sizeof(struct chan_list)); 02863 02864 cl->orginator=orig; 02865 cl->need_queue_hangup=1; 02866 cl->need_hangup=1; 02867 cl->need_busy=1; 02868 cl->overlap_dial_task=-1; 02869 02870 return cl; 02871 02872 }
|
|
|
Definition at line 4627 of file chan_misdn.c. References ast_log(), AST_MODULE_LOAD_DECLINE, LOG_ERROR, malloc, max_ports, misdn_cfg_get(), misdn_cfg_init(), misdn_debug, and misdn_ports. 04628 { 04629 int i, port; 04630 04631 char ports[256]=""; 04632 04633 max_ports=misdn_lib_maxports_get(); 04634 04635 if (max_ports<=0) { 04636 ast_log(LOG_ERROR, "Unable to initialize mISDN\n"); 04637 return AST_MODULE_LOAD_DECLINE; 04638 } 04639 04640 if (misdn_cfg_init(max_ports)) { 04641 ast_log(LOG_ERROR, "Unable to initialize misdn_config.\n"); 04642 return AST_MODULE_LOAD_DECLINE; 04643 } 04644 g_config_initialized=1; 04645 04646 misdn_debug = (int *)malloc(sizeof(int) * (max_ports+1)); 04647 misdn_ports = (int *)malloc(sizeof(int) * (max_ports+1)); 04648 misdn_cfg_get( 0, MISDN_GEN_DEBUG, &misdn_debug[0], sizeof(int)); 04649 for (i = 1; i <= max_ports; i++) { 04650 misdn_debug[i] = misdn_debug[0]; 04651 misdn_ports[i] = i; 04652 } 04653 *misdn_ports = 0; 04654 misdn_debug_only = (int *)calloc(max_ports + 1, sizeof(int)); 04655 04656 { 04657 char tempbuf[BUFFERSIZE+1]; 04658 misdn_cfg_get( 0, MISDN_GEN_TRACEFILE, tempbuf, BUFFERSIZE); 04659 if (strlen(tempbuf)) 04660 tracing = 1; 04661 } 04662 04663 misdn_in_calls = (int *)malloc(sizeof(int) * (max_ports+1)); 04664 misdn_out_calls = (int *)malloc(sizeof(int) * (max_ports+1)); 04665 04666 for (i=1; i <= max_ports; i++) { 04667 misdn_in_calls[i]=0; 04668 misdn_out_calls[i]=0; 04669 } 04670 04671 ast_mutex_init(&cl_te_lock); 04672 04673 misdn_cfg_update_ptp(); 04674 misdn_cfg_get_ports_string(ports); 04675 04676 if (strlen(ports)) 04677 chan_misdn_log(0, 0, "Got: %s from get_ports\n",ports); 04678 04679 { 04680 struct misdn_lib_iface iface = { 04681 .cb_event = cb_events, 04682 .cb_log = chan_misdn_log, 04683 .cb_jb_empty = chan_misdn_jb_empty, 04684 }; 04685 04686 if (misdn_lib_init(ports, &iface, NULL)) 04687 chan_misdn_log(0, 0, "No te ports initialized\n"); 04688 04689 int ntflags=0; 04690 char ntfile[BUFFERSIZE+1]; 04691 04692 misdn_cfg_get( 0, MISDN_GEN_NTDEBUGFLAGS, &ntflags, sizeof(int)); 04693 misdn_cfg_get( 0, MISDN_GEN_NTDEBUGFILE, &ntfile, BUFFERSIZE); 04694 04695 misdn_lib_nt_debug_init(ntflags,ntfile); 04696 04697 } 04698 04699 { 04700 if (ast_channel_register(&misdn_tech)) { 04701 ast_log(LOG_ERROR, "Unable to register channel class %s\n", misdn_type); 04702 unload_module(); 04703 return -1; 04704 } 04705 } 04706 04707 ast_cli_register_multiple(chan_misdn_clis, sizeof(chan_misdn_clis) / sizeof(struct ast_cli_entry)); 04708 04709 ast_register_application("misdn_set_opt", misdn_set_opt_exec, "misdn_set_opt", 04710 "misdn_set_opt(:<opt><optarg>:<opt><optarg>..):\n" 04711 "Sets mISDN opts. and optargs\n" 04712 "\n" 04713 "The available options are:\n" 04714 " d - Send display text on called phone, text is the optparam\n" 04715 " n - don't detect dtmf tones on called channel\n" 04716 " h - make digital outgoing call\n" 04717 " c - make crypted outgoing call, param is keyindex\n" 04718 " e - perform echo cancelation on this channel,\n" 04719 " takes taps as arguments (32,64,128,256)\n" 04720 " s - send Non Inband DTMF as inband\n" 04721 " vr - rxgain control\n" 04722 " vt - txgain control\n" 04723 ); 04724 04725 04726 ast_register_application("misdn_facility", misdn_facility_exec, "misdn_facility", 04727 "misdn_facility(<FACILITY_TYPE>|<ARG1>|..)\n" 04728 "Sends the Facility Message FACILITY_TYPE with \n" 04729 "the given Arguments to the current ISDN Channel\n" 04730 "Supported Facilities are:\n" 04731 "\n" 04732 "type=calldeflect args=Nr where to deflect\n" 04733 ); 04734 04735 04736 misdn_cfg_get( 0, MISDN_GEN_TRACEFILE, global_tracefile, BUFFERSIZE); 04737 04738 /* start the l1 watchers */ 04739 04740 for (port = misdn_cfg_get_next_port(0); port >= 0; port = misdn_cfg_get_next_port(port)) { 04741 int l1timeout; 04742 misdn_cfg_get(port, MISDN_CFG_L1_TIMEOUT, &l1timeout, sizeof(l1timeout)); 04743 if (l1timeout) { 04744 chan_misdn_log(4, 0, "Adding L1watcher task: port:%d timeout:%ds\n", port, l1timeout); 04745 misdn_tasks_add(l1timeout * 1000, misdn_l1_task, &misdn_ports[port]); 04746 } 04747 } 04748 04749 chan_misdn_log(0, 0, "-- mISDN Channel Driver Registered --\n"); 04750 04751 return 0; 04752 }
|
|
|
Definition at line 2004 of file chan_misdn.c. References chan_list::ast, ast_log(), ast_queue_hangup(), ast_strlen_zero(), chan_list::bc, chan_misdn_log(), LOG_WARNING, MISDN_ASTERISK_TECH_PVT, MISDN_CONNECTED, pbx_builtin_getvar_helper(), start_bc_tones(), chan_list::state, and stop_indicate(). 02005 { 02006 struct chan_list *p; 02007 02008 02009 if (!ast || ! (p=MISDN_ASTERISK_TECH_PVT(ast)) ) return -1; 02010 02011 chan_misdn_log(1, p? (p->bc? p->bc->port : 0) : 0, "* ANSWER:\n"); 02012 02013 if (!p) { 02014 ast_log(LOG_WARNING, " --> Channel not connected ??\n"); 02015 ast_queue_hangup(ast); 02016 } 02017 02018 if (!p->bc) { 02019 chan_misdn_log(1, 0, " --> Got Answer, but theres no bc obj ??\n"); 02020 02021 ast_queue_hangup(ast); 02022 } 02023 02024 { 02025 const char *tmp_key = pbx_builtin_getvar_helper(p->ast, "CRYPT_KEY"); 02026 02027 if (tmp_key ) { 02028 chan_misdn_log(1, p->bc->port, " --> Connection will be BF crypted\n"); 02029 { 02030 int l = sizeof(p->bc->crypt_key); 02031 strncpy(p->bc->crypt_key,tmp_key, l); 02032 p->bc->crypt_key[l-1] = 0; 02033 } 02034 } else { 02035 chan_misdn_log(3, p->bc->port, " --> Connection is without BF encryption\n"); 02036 } 02037 02038 } 02039 02040 { 02041 const char *nodsp=pbx_builtin_getvar_helper(ast, "MISDN_DIGITAL_TRANS"); 02042 if (nodsp) { 02043 chan_misdn_log(1, p->bc->port, " --> Connection is transparent digital\n"); 02044 p->bc->nodsp=1; 02045 p->bc->hdlc=0; 02046 p->bc->nojitter=1; 02047 } 02048 } 02049 02050 p->state = MISDN_CONNECTED; 02051 stop_indicate(p); 02052 02053 if ( ast_strlen_zero(p->bc->cad) ) { 02054 chan_misdn_log(2,p->bc->port," --> empty cad using dad\n"); 02055 ast_copy_string(p->bc->cad,p->bc->dad,sizeof(p->bc->cad)); 02056 } 02057 02058 misdn_lib_send_event( p->bc, EVENT_CONNECT); 02059 start_bc_tones(p); 02060 02061 return 0; 02062 }
|
|
||||||||||||||||||||||||||||
|
Definition at line 2677 of file chan_misdn.c. References AST_BRIDGE_COMPLETE, AST_BRIDGE_DTMF_CHANNEL_0, AST_BRIDGE_DTMF_CHANNEL_1, AST_FRAME_CONTROL, AST_FRAME_DTMF, AST_FRAME_VOICE, ast_log(), ast_read(), ast_verbose(), ast_waitfor_n(), ast_write(), chan_list::bc, chan_misdn_log(), ast_channel::exten, ast_frame::frametype, get_chan_by_ast(), chan_list::ignore_dtmf, LOG_NOTICE, misdn_cfg_get(), option_verbose, ast_frame::subclass, and VERBOSE_PREFIX_3. 02683 { 02684 struct chan_list *ch1,*ch2; 02685 struct ast_channel *carr[2], *who; 02686 int to=-1; 02687 struct ast_frame *f; 02688 02689 ch1=get_chan_by_ast(c0); 02690 ch2=get_chan_by_ast(c1); 02691 02692 carr[0]=c0; 02693 carr[1]=c1; 02694 02695 if (ch1 && ch2 ) ; 02696 else 02697 return -1; 02698 02699 int bridging; 02700 misdn_cfg_get( 0, MISDN_GEN_BRIDGING, &bridging, sizeof(int)); 02701 if (bridging) { 02702 /* trying to make a mISDN_dsp conference */ 02703 chan_misdn_log(1, ch1->bc->port, "I SEND: Making conference with Number:%d\n", ch1->bc->pid +1); 02704 misdn_lib_bridge(ch1->bc,ch2->bc); 02705 } 02706 02707 if (option_verbose > 2) 02708 ast_verbose(VERBOSE_PREFIX_3 "Native bridging %s and %s\n", c0->name, c1->name); 02709 02710 chan_misdn_log(1, ch1->bc->port, "* Making Native Bridge between %s and %s\n", ch1->bc->oad, ch2->bc->oad); 02711 02712 if (! (flags&AST_BRIDGE_DTMF_CHANNEL_0) ) 02713 ch1->ignore_dtmf=1; 02714 02715 if (! (flags&AST_BRIDGE_DTMF_CHANNEL_1) ) 02716 ch2->ignore_dtmf=1; 02717 02718 while(1) { 02719 to=-1; 02720 who = ast_waitfor_n(carr, 2, &to); 02721 02722 if (!who) { 02723 ast_log(LOG_NOTICE,"misdn_bridge: empty read, breaking out\n"); 02724 break; 02725 } 02726 f = ast_read(who); 02727 02728 if (!f || f->frametype == AST_FRAME_CONTROL) { 02729 /* got hangup .. */ 02730 02731 if (!f) 02732 chan_misdn_log(4,ch1->bc->port,"Read Null Frame\n"); 02733 else 02734 chan_misdn_log(4,ch1->bc->port,"Read Frame Controll class:%d\n",f->subclass); 02735 02736 *fo=f; 02737 *rc=who; 02738 02739 break; 02740 } 02741 02742 if ( f->frametype == AST_FRAME_DTMF ) { 02743 chan_misdn_log(1,0,"Read DTMF %d from %s\n",f->subclass, who->exten); 02744 02745 *fo=f; 02746 *rc=who; 02747 break; 02748 } 02749 02750 #if 0 02751 if (f->frametype == AST_FRAME_VOICE) { 02752 chan_misdn_log(1, ch1->bc->port, "I SEND: Splitting conference with Number:%d\n", ch1->bc->pid +1); 02753 02754 continue; 02755 } 02756 #endif 02757 02758 if (who == c0) { 02759 ast_write(c1,f); 02760 } 02761 else { 02762 ast_write(c0,f); 02763 } 02764 02765 } 02766 02767 chan_misdn_log(1, ch1->bc->port, "I SEND: Splitting conference with Number:%d\n", ch1->bc->pid +1); 02768 02769 misdn_lib_split_bridge(ch1->bc,ch2->bc); 02770 02771 02772 return AST_BRIDGE_COMPLETE; 02773 }
|
|
||||||||||||||||
|
we should have l3id after sending setup Definition at line 1858 of file chan_misdn.c. References ast_channel::_state, add_out_calls(), chan_list::ast, AST_CID_P, ast_log(), ast_setstate(), AST_STATE_DIALING, AST_STATE_DOWN, AST_STATE_RESERVED, ast_strlen_zero(), ast_transfercapability2str(), ast_verbose(), chan_list::bc, chan_misdn_log(), ast_channel::context, ext, ast_channel::exten, ast_channel::hangupcause, import_ch(), chan_list::l3id, LOG_WARNING, MISDN_ASTERISK_TECH_PVT, MISDN_CALLING, misdn_cfg_get(), misdn_set_opt_exec(), ORG_AST, chan_list::other_ch, pbx_builtin_setvar_helper(), chan_list::state, stop_bc_tones(), ast_channel::transfercapability, and update_config(). 01859 { 01860 int port=0; 01861 int r; 01862 struct chan_list *ch=MISDN_ASTERISK_TECH_PVT(ast); 01863 struct misdn_bchannel *newbc; 01864 char *opts=NULL, *ext,*tokb; 01865 char dest_cp[256]; 01866 01867 { 01868 strncpy(dest_cp,dest,sizeof(dest_cp)-1); 01869 dest_cp[sizeof(dest_cp)]=0; 01870 01871 ext=strtok_r(dest_cp,"/",&tokb); 01872 01873 if (ext) { 01874 ext=strtok_r(NULL,"/",&tokb); 01875 if (ext) { 01876 opts=strtok_r(NULL,"/",&tokb); 01877 } else { 01878 chan_misdn_log(0,0,"misdn_call: No Extension given!\n"); 01879 return -1; 01880 } 01881 } 01882 } 01883 01884 if (!ast) { 01885 ast_log(LOG_WARNING, " --> ! misdn_call called on ast_channel *ast where ast == NULL\n"); 01886 return -1; 01887 } 01888 01889 if (((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) || !dest ) { 01890 ast_log(LOG_WARNING, " --> ! misdn_call called on %s, neither down nor reserved (or dest==NULL)\n", ast->name); 01891 ast->hangupcause=41; 01892 ast_setstate(ast, AST_STATE_DOWN); 01893 return -1; 01894 } 01895 01896 if (!ch) { 01897 ast_log(LOG_WARNING, " --> ! misdn_call called on %s, neither down nor reserved (or dest==NULL)\n", ast->name); 01898 ast->hangupcause=41; 01899 ast_setstate(ast, AST_STATE_DOWN); 01900 return -1; 01901 } 01902 01903 newbc=ch->bc; 01904 01905 if (!newbc) { 01906 ast_log(LOG_WARNING, " --> ! misdn_call called on %s, neither down nor reserved (or dest==NULL)\n", ast->name); 01907 ast->hangupcause=41; 01908 ast_setstate(ast, AST_STATE_DOWN); 01909 return -1; 01910 } 01911 01912 port=newbc->port; 01913 strncpy(newbc->dad,ext,sizeof( newbc->dad)); 01914 strncpy(ast->exten,ext,sizeof(ast->exten)); 01915 01916 int exceed; 01917 if ((exceed=add_out_calls(port))) { 01918 char tmp[16]; 01919 sprintf(tmp,"%d",exceed); 01920 pbx_builtin_setvar_helper(ast,"MAX_OVERFLOW",tmp); 01921 return -1; 01922 } 01923 01924 chan_misdn_log(1, port, "* CALL: %s\n",dest); 01925 01926 chan_misdn_log(2, port, " --> * dad:%s tech:%s ctx:%s\n",ast->exten,ast->name, ast->context); 01927 01928 chan_misdn_log(3, port, " --> * adding2newbc ext %s\n",ast->exten); 01929 if (ast->exten) { 01930 int l = sizeof(newbc->dad); 01931 strncpy(newbc->dad,ast->exten, l); 01932 newbc->dad[l-1] = 0; 01933 } 01934 newbc->rad[0]=0; 01935 chan_misdn_log(3, port, " --> * adding2newbc callerid %s\n",AST_CID_P(ast)); 01936 if (ast_strlen_zero(newbc->oad) && AST_CID_P(ast) ) { 01937 01938 if (AST_CID_P(ast)) { 01939 int l = sizeof(newbc->oad); 01940 strncpy(newbc->oad,AST_CID_P(ast), l); 01941 newbc->oad[l-1] = 0; 01942 } 01943 } 01944 01945 { 01946 struct chan_list *ch=MISDN_ASTERISK_TECH_PVT(ast); 01947 if (!ch) { ast_verbose("No chan_list in misdn_call\n"); return -1;} 01948 01949 newbc->capability=ast->transfercapability; 01950 pbx_builtin_setvar_helper(ast,"TRANSFERCAPABILITY",ast_transfercapability2str(newbc->capability)); 01951 if ( ast->transfercapability == INFO_CAPABILITY_DIGITAL_UNRESTRICTED) { 01952 chan_misdn_log(2, port, " --> * Call with flag Digital\n"); 01953 } 01954 01955 01956 /* update screening and presentation */ 01957 update_config(ch,ORG_AST); 01958 01959 /* fill in some ies from channel vary*/ 01960 import_ch(ast, newbc, ch); 01961 01962 /* Finally The Options Override Everything */ 01963 if (opts) 01964 misdn_set_opt_exec(ast,opts); 01965 else 01966 chan_misdn_log(2,port,"NO OPTS GIVEN\n"); 01967 01968 /*check for bridging*/ 01969 int bridging; 01970 misdn_cfg_get( 0, MISDN_GEN_BRIDGING, &bridging, sizeof(int)); 01971 if (bridging && ch->other_ch) { 01972 chan_misdn_log(0, port, "Disabling EC on both Sides\n"); 01973 ch->bc->ec_enable=0; 01974 ch->other_ch->bc->ec_enable=0; 01975 } 01976 01977 r=misdn_lib_send_event( newbc, EVENT_SETUP ); 01978 01979 /** we should have l3id after sending setup **/ 01980 ch->l3id=newbc->l3_id; 01981 } 01982 01983 if ( r == -ENOCHAN ) { 01984 chan_misdn_log(0, port, " --> * Theres no Channel at the moment .. !\n"); 01985 chan_misdn_log(1, port, " --> * SEND: State Down pid:%d\n",newbc?newbc->pid:-1); 01986 ast->hangupcause=34; 01987 ast_setstate(ast, AST_STATE_DOWN); 01988 return -1; 01989 } 01990 01991 chan_misdn_log(2, port, " --> * SEND: State Dialing pid:%d\n",newbc?newbc->pid:1); 01992 01993 ast_setstate(ast, AST_STATE_DIALING); 01994 ast->hangupcause=16; 01995 01996 if (newbc->nt) stop_bc_tones(ch); 01997 01998 ch->state=MISDN_CALLING; 01999 02000 return 0; 02001 }
|
|
||||||||||||
|
Definition at line 2064 of file chan_misdn.c. 02065 { 02066 /* XXX Modify this callback to support Asterisk controlling the length of DTMF */ 02067 return 0; 02068 }
|
|
||||||||||||||||
|
Definition at line 2070 of file chan_misdn.c. References chan_list::ast, ast_log(), chan_list::bc, chan_misdn_log(), ast_channel::exten, LOG_WARNING, MISDN_ASTERISK_TECH_PVT, MISDN_CALLING, MISDN_CALLING_ACKNOWLEDGE, send_digit_to_chan(), and chan_list::state. 02071 { 02072 struct chan_list *p; 02073 02074 if (!ast || ! (p=MISDN_ASTERISK_TECH_PVT(ast))) return -1; 02075 02076 struct misdn_bchannel *bc=p->bc; 02077 chan_misdn_log(1, bc?bc->port:0, "* IND : Digit %c\n",digit); 02078 02079 if (!bc) { 02080 ast_log(LOG_WARNING, " --> !! Got Digit Event withut having bchannel Object\n"); 02081 return -1; 02082 } 02083 02084 switch (p->state ) { 02085 case MISDN_CALLING: 02086 { 02087 02088 char buf[8]; 02089 buf[0]=digit; 02090 buf[1]=0; 02091 02092 int l = sizeof(bc->infos_pending); 02093 strncat(bc->infos_pending,buf,l); 02094 bc->infos_pending[l-1] = 0; 02095 } 02096 break; 02097 case MISDN_CALLING_ACKNOWLEDGE: 02098 { 02099 bc->info_dad[0]=digit; 02100 bc->info_dad[1]=0; 02101 02102 { 02103 int l = sizeof(bc->dad); 02104 strncat(bc->dad,bc->info_dad, l - strlen(bc->dad)); 02105 bc->dad[l-1] = 0; 02106 } 02107 { 02108 int l = sizeof(p->ast->exten); 02109 strncpy(p->ast->exten, bc->dad, l); 02110 p->ast->exten[l-1] = 0; 02111 } 02112 02113 misdn_lib_send_event( bc, EVENT_INFORMATION); 02114 } 02115 break; 02116 02117 default: 02118 if ( bc->send_dtmf ) { 02119 send_digit_to_chan(p,digit); 02120 } 02121 break; 02122 } 02123 02124 return 0; 02125 }
|
|
||||||||||||
|
Definition at line 4765 of file chan_misdn.c. References ast_log(), ast_strlen_zero(), chan_list::bc, chan_misdn_log(), LOG_WARNING, MISDN_ASTERISK_TECH_PVT, ast_channel::tech, and ast_channel_tech::type. 04766 { 04767 struct chan_list *ch = MISDN_ASTERISK_TECH_PVT(chan); 04768 char *tok, *tokb; 04769 04770 chan_misdn_log(0,0,"TYPE: %s\n",chan->tech->type); 04771 04772 if (strcasecmp(chan->tech->type,"mISDN")) { 04773 ast_log(LOG_WARNING, "misdn_facility makes only sense with chan_misdn channels!\n"); 04774 return -1; 04775 } 04776 04777 if (ast_strlen_zero((char *)data)) { 04778 ast_log(LOG_WARNING, "misdn_facility Requires arguments\n"); 04779 return -1; 04780 } 04781 04782 tok=strtok_r((char*)data,"|", &tokb) ; 04783 04784 if (!tok) { 04785 ast_log(LOG_WARNING, "misdn_facility Requires arguments\n"); 04786 return -1; 04787 } 04788 04789 if (!strcasecmp(tok,"calldeflect")) { 04790 tok=strtok_r(NULL,"|", &tokb) ; 04791 04792 if (!tok) { 04793 ast_log(LOG_WARNING, "Facility: Call Defl Requires arguments\n"); 04794 } 04795 04796 if (strlen(tok) >= sizeof(ch->bc->fac_out.u.CDeflection.DeflectedToNumber)) { 04797 ast_log(LOG_WARNING, "Facility: Number argument too long (up to 15 digits are allowed). Ignoring.\n"); 04798 return 0; 04799 } 04800 ch->bc->fac_out.Function = Fac_CD; 04801 strncpy((char *)ch->bc->fac_out.u.CDeflection.DeflectedToNumber, tok, sizeof(ch->bc->fac_out.u.CDeflection.DeflectedToNumber)); 04802 misdn_lib_send_event(ch->bc, EVENT_FACILITY); 04803 } else { 04804 chan_misdn_log(1, ch->bc->port, "Unknown Facility: %s\n",tok); 04805 } 04806 04807 return 0; 04808 04809 }
|
|
||||||||||||
|
Definition at line 2128 of file chan_misdn.c. References chan_list::ast, chan_list::bc, chan_misdn_log(), chan_list::l3id, MISDN_ASTERISK_TECH_PVT, and misdn_get_ch_state(). 02129 { 02130 struct chan_list *p; 02131 02132 if (!ast || ! (p=MISDN_ASTERISK_TECH_PVT(ast) )) return -1; 02133 02134 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); 02135 02136 p->ast = ast ; 02137 02138 return 0; 02139 }
|
|
|
Definition at line 953 of file chan_misdn.c. References chan_list::state, state_struct::state, state_array, and state_struct::txt. Referenced by cb_events(), misdn_fixup(), misdn_hangup(), misdn_write(), print_bc_info(), and release_chan(). 00954 { 00955 int i; 00956 static char state[8]; 00957 00958 if( !p) return NULL; 00959 00960 for (i=0; i< sizeof(state_array)/sizeof(struct state_struct); i++) { 00961 if ( state_array[i].state == p->state) return state_array[i].txt; 00962 } 00963 00964 sprintf(state,"%d",p->state) ; 00965 00966 return state; 00967 }
|
|
|
Definition at line 2277 of file chan_misdn.c. References ast_channel::_state, chan_list::ast, AST_CID_P, ast_log(), AST_STATE_RESERVED, chan_list::bc, chan_misdn_log(), cl_dequeue_chan(), cl_te, ast_channel::context, ast_channel::exten, free, ast_channel::hangupcause, hanguptone_indicate(), chan_list::l3id, LOG_DEBUG, LOG_WARNING, MISDN_ALERTING, MISDN_ASTERISK_TECH_PVT, MISDN_BUSY, MISDN_CALLING, MISDN_CALLING_ACKNOWLEDGE, MISDN_CLEANING, MISDN_CONNECTED, MISDN_DIALING, MISDN_DISCONNECTED, misdn_get_ch_state(), MISDN_HOLD_DISCONNECT, MISDN_HOLDED, MISDN_NOTHING, MISDN_PRECONNECTED, MISDN_PROCEEDING, MISDN_PROGRESS, MISDN_RELEASED, chan_list::need_busy, chan_list::need_hangup, chan_list::need_queue_hangup, option_debug, ORG_AST, chan_list::orginator, pbx_builtin_getvar_helper(), chan_list::pipe, start_bc_tones(), chan_list::state, and stop_bc_tones(). 02278 { 02279 struct chan_list *p; 02280 struct misdn_bchannel *bc=NULL; 02281 02282 if (option_debug) 02283 ast_log(LOG_DEBUG, "misdn_hangup(%s)\n", ast->name); 02284 02285 if (!ast || ! (p=MISDN_ASTERISK_TECH_PVT(ast) ) ) return -1; 02286 02287 if (!p) { 02288 chan_misdn_log(3, 0, "misdn_hangup called, without chan_list obj.\n"); 02289 return 0 ; 02290 } 02291 02292 bc=p->bc; 02293 02294 02295 02296 MISDN_ASTERISK_TECH_PVT(ast)=NULL; 02297 p->ast=NULL; 02298 02299 bc=p->bc; 02300 02301 if (ast->_state == AST_STATE_RESERVED || 02302 p->state == MISDN_NOTHING || 02303 p->state == MISDN_HOLDED || 02304 p->state == MISDN_HOLD_DISCONNECT ) { 02305 02306 CLEAN_CH: 02307 /* between request and call */ 02308 if (option_debug) 02309 ast_log(LOG_DEBUG, "State Reserved (or nothing) => chanIsAvail\n"); 02310 MISDN_ASTERISK_TECH_PVT(ast)=NULL; 02311 02312 cl_dequeue_chan(&cl_te, p); 02313 close(p->pipe[0]); 02314 close(p->pipe[1]); 02315 free(p); 02316 02317 if (bc) 02318 misdn_lib_release(bc); 02319 02320 return 0; 02321 } 02322 02323 if (!bc) { 02324 ast_log(LOG_WARNING,"Hangup with private but no bc ? state:%s l3id:%x\n", misdn_get_ch_state(p), p->l3id); 02325 goto CLEAN_CH; 02326 } 02327 02328 02329 p->need_hangup=0; 02330 p->need_queue_hangup=0; 02331 p->need_busy=0; 02332 02333 02334 if (!p->bc->nt) 02335 stop_bc_tones(p); 02336 02337 02338 { 02339 const char *varcause=NULL; 02340 bc->out_cause=ast->hangupcause?ast->hangupcause:16; 02341 02342 if ( (varcause=pbx_builtin_getvar_helper(ast, "HANGUPCAUSE")) || 02343 (varcause=pbx_builtin_getvar_helper(ast, "PRI_CAUSE"))) { 02344 int tmpcause=atoi(varcause); 02345 bc->out_cause=tmpcause?tmpcause:16; 02346 } 02347 02348 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_P(ast), misdn_get_ch_state(p)); 02349 chan_misdn_log(3, bc->port, " --> l3id:%x\n",p->l3id); 02350 chan_misdn_log(3, bc->port, " --> cause:%d\n",bc->cause); 02351 chan_misdn_log(2, bc->port, " --> out_cause:%d\n",bc->out_cause); 02352 chan_misdn_log(2, bc->port, " --> state:%s\n", misdn_get_ch_state(p)); 02353 02354 switch (p->state) { 02355 case MISDN_CALLING: 02356 p->state=MISDN_CLEANING; 02357 misdn_lib_send_event( bc, EVENT_RELEASE_COMPLETE); 02358 break; 02359 case MISDN_HOLDED: 02360 case MISDN_DIALING: 02361 start_bc_tones(p); 02362 hanguptone_indicate(p); 02363 02364 if (bc->need_disconnect) 02365 misdn_lib_send_event( bc, EVENT_DISCONNECT); 02366 break; 02367 02368 case MISDN_CALLING_ACKNOWLEDGE: 02369 start_bc_tones(p); 02370 hanguptone_indicate(p); 02371 02372 if (bc->need_disconnect) 02373 misdn_lib_send_event( bc, EVENT_DISCONNECT); 02374 break; 02375 02376 case MISDN_ALERTING: 02377 case MISDN_PROGRESS: 02378 case MISDN_PROCEEDING: 02379 if (p->orginator != ORG_AST) 02380 hanguptone_indicate(p); 02381 02382 /*p->state=MISDN_CLEANING;*/ 02383 if (bc->need_disconnect) 02384 misdn_lib_send_event( bc, EVENT_DISCONNECT); 02385 break; 02386 case MISDN_CONNECTED: 02387 case MISDN_PRECONNECTED: 02388 /* Alerting or Disconect */ 02389 if (p->bc->nt) { 02390 start_bc_tones(p); 02391 hanguptone_indicate(p); 02392 p->bc->progress_indicator=8; 02393 } 02394 if (bc->need_disconnect) 02395 misdn_lib_send_event( bc, EVENT_DISCONNECT); 02396 02397 /*p->state=MISDN_CLEANING;*/ 02398 break; 02399 case MISDN_DISCONNECTED: 02400 misdn_lib_send_event( bc, EVENT_RELEASE); 02401 p->state=MISDN_CLEANING; /* MISDN_HUNGUP_FROM_AST; */ 02402 break; 02403 02404 case MISDN_RELEASED: 02405 case MISDN_CLEANING: 02406 p->state=MISDN_CLEANING; 02407 break; 02408 02409 case MISDN_BUSY: 02410 break; 02411 02412 case MISDN_HOLD_DISCONNECT: 02413 /* need to send release here */ 02414 chan_misdn_log(1, bc->port, " --> cause %d\n",bc->cause); 02415 chan_misdn_log(1, bc->port, " --> out_cause %d\n",bc->out_cause); 02416 02417 bc->out_cause=-1; 02418 misdn_lib_send_event(bc,EVENT_RELEASE); 02419 p->state=MISDN_CLEANING; 02420 break; 02421 default: 02422 if (bc->nt) { 02423 bc->out_cause=-1; 02424 misdn_lib_send_event(bc, EVENT_RELEASE); 02425 p->state=MISDN_CLEANING; 02426 } else { 02427 if (bc->need_disconnect) 02428 misdn_lib_send_event(bc, EVENT_DISCONNECT); 02429 } 02430 } 02431 02432 p->state=MISDN_CLEANING; 02433 02434 } 02435 02436 02437 chan_misdn_log(3, bc->port, " --> Channel: %s hanguped new state:%s\n",ast->name,misdn_get_ch_state(p)); 02438 02439 return 0; 02440 }
|
|
||||||||||||||||||||
|
Definition at line 2143 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_setstate(), AST_STATE_BUSY, AST_STATE_RINGING, chan_list::bc, chan_misdn_log(), ast_channel::exten, hanguptone_indicate(), chan_list::incoming_early_audio, LOG_WARNING, MISDN_ALERTING, MISDN_ASTERISK_TECH_PVT, MISDN_CONNECTED, ORG_MISDN, chan_list::orginator, chan_list::other_ch, start_bc_tones(), chan_list::state, and stop_indicate(). 02144 { 02145 struct chan_list *p; 02146 02147 02148 if (!ast || ! (p=MISDN_ASTERISK_TECH_PVT(ast))) { 02149 ast_log(LOG_WARNING, "Returnded -1 in misdn_indication\n"); 02150 return -1; 02151 } 02152 02153 if (!p->bc ) { 02154 chan_misdn_log(1, 0, "* IND : Indication from %s\n",ast->exten); 02155 ast_log(LOG_WARNING, "Private Pointer but no bc ?\n"); 02156 return -1; 02157 } 02158 02159 chan_misdn_log(5, p->bc->port, "* IND : Indication [%d] from %s\n",cond, ast->exten); 02160 02161 switch (cond) { 02162 case AST_CONTROL_BUSY: 02163 chan_misdn_log(1, p->bc->port, "* IND :\tbusy pid:%d\n",p->bc?p->bc->pid:-1); 02164 ast_setstate(ast,AST_STATE_BUSY); 02165 02166 p->bc->out_cause=17; 02167 if (p->state != MISDN_CONNECTED) { 02168 start_bc_tones(p); 02169 misdn_lib_send_event( p->bc, EVENT_DISCONNECT); 02170 } else { 02171 chan_misdn_log(-1, p->bc->port, " --> !! Got Busy in Connected State !?! ast:%s\n", ast->name); 02172 } 02173 return -1; 02174 break; 02175 case AST_CONTROL_RING: 02176 chan_misdn_log(1, p->bc->port, "* IND :\tring pid:%d\n",p->bc?p->bc->pid:-1); 02177 return -1; 02178 break; 02179 02180 case AST_CONTROL_RINGING: 02181 chan_misdn_log(1, p->bc->port, "* IND :\tringing pid:%d\n",p->bc?p->bc->pid:-1); 02182 switch (p->state) { 02183 case MISDN_ALERTING: 02184 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); 02185 break; 02186 case MISDN_CONNECTED: 02187 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); 02188 return -1; 02189 break; 02190 default: 02191 p->state=MISDN_ALERTING; 02192 chan_misdn_log(2, p->bc->port, " --> * IND :\tringing pid:%d\n",p->bc?p->bc->pid:-1); 02193 misdn_lib_send_event( p->bc, EVENT_ALERTING); 02194 02195 if (p->other_ch && p->other_ch->bc) { 02196 if (misdn_inband_avail(p->other_ch->bc)) { 02197 chan_misdn_log(2,p->bc->port, " --> other End is mISDN and has inband info available\n"); 02198 break; 02199 } 02200 02201 if (!p->other_ch->bc->nt) { 02202 chan_misdn_log(2,p->bc->port, " --> other End is mISDN TE so it has inband info for sure (?)\n"); 02203 break; 02204 } 02205 } 02206 02207 chan_misdn_log(3, p->bc->port, " --> * SEND: State Ring pid:%d\n",p->bc?p->bc->pid:-1); 02208 ast_setstate(ast,AST_STATE_RINGING); 02209 02210 if ( !p->bc->nt && (p->orginator==ORG_MISDN) && !p->incoming_early_audio ) 02211 chan_misdn_log(2,p->bc->port, " --> incoming_early_audio off\n"); 02212 else 02213 return -1; 02214 } 02215 break; 02216 case AST_CONTROL_ANSWER: 02217 chan_misdn_log(1, p->bc->port, " --> * IND :\tanswer pid:%d\n",p->bc?p->bc->pid:-1); 02218 start_bc_tones(p); 02219 break; 02220 case AST_CONTROL_TAKEOFFHOOK: 02221 chan_misdn_log(1, p->bc->port, " --> *\ttakeoffhook pid:%d\n",p->bc?p->bc->pid:-1); 02222 return -1; 02223 break; 02224 case AST_CONTROL_OFFHOOK: 02225 chan_misdn_log(1, p->bc->port, " --> *\toffhook pid:%d\n",p->bc?p->bc->pid:-1); 02226 return -1; 02227 break; 02228 case AST_CONTROL_FLASH: 02229 chan_misdn_log(1, p->bc->port, " --> *\tflash pid:%d\n",p->bc?p->bc->pid:-1); 02230 break; 02231 case AST_CONTROL_PROGRESS: 02232 chan_misdn_log(1, p->bc->port, " --> * IND :\tprogress pid:%d\n",p->bc?p->bc->pid:-1); 02233 misdn_lib_send_event( p->bc, EVENT_PROGRESS); 02234 break; 02235 case AST_CONTROL_PROCEEDING: 02236 chan_misdn_log(1, p->bc->port, " --> * IND :\tproceeding pid:%d\n",p->bc?p->bc->pid:-1); 02237 misdn_lib_send_event( p->bc, EVENT_PROCEEDING); 02238 break; 02239 case AST_CONTROL_CONGESTION: 02240 chan_misdn_log(1, p->bc->port, " --> * IND :\tcongestion pid:%d\n",p->bc?p->bc->pid:-1); 02241 02242 p->bc->out_cause=42; 02243 if (p->state != MISDN_CONNECTED) { 02244 start_bc_tones(p); 02245 misdn_lib_send_event( p->bc, EVENT_RELEASE); 02246 } else { 02247 misdn_lib_send_event( p->bc, EVENT_DISCONNECT); 02248 } 02249 02250 if (p->bc->nt) { 02251 hanguptone_indicate(p); 02252 } 02253 break; 02254 case -1 : 02255 chan_misdn_log(1, p->bc->port, " --> * IND :\t-1! (stop indication) pid:%d\n",p->bc?p->bc->pid:-1); 02256 02257 stop_indicate(p); 02258 02259 if (p->state == MISDN_CONNECTED) 02260 start_bc_tones(p); 02261 02262 break; 02263 02264 case AST_CONTROL_HOLD: 02265 chan_misdn_log(1, p->bc->port, " --> *\tHOLD pid:%d\n",p->bc?p->bc->pid:-1); 02266 break; 02267 case AST_CONTROL_UNHOLD: 02268 chan_misdn_log(1, p->bc->port, " --> *\tUNHOLD pid:%d\n",p->bc?p->bc->pid:-1); 02269 break; 02270 default: 02271 chan_misdn_log(1, p->bc->port, " --> * Unknown Indication:%d pid:%d\n",cond,p->bc?p->bc->pid:-1); 02272 } 02273 02274 return 0; 02275 }
|
|
|
Definition at line 5055 of file chan_misdn.c. References ast_mutex_destroy(), free, misdn_jb::mutexjb, and misdn_jb::samples. Referenced by config_jitterbuffer(), and release_chan(). 05056 { 05057 ast_mutex_destroy(&jb->mutexjb); 05058 05059 free(jb->samples); 05060 free(jb); 05061 }
|
|
||||||||||||||||
|
Definition at line 5127 of file chan_misdn.c. References ast_mutex_lock(), ast_mutex_unlock(), misdn_jb::mutexjb, misdn_jb::ok, misdn_jb::rp, misdn_jb::samples, misdn_jb::size, misdn_jb::state_empty, and misdn_jb::wp. Referenced by chan_misdn_jb_empty(). 05128 { 05129 int i, wp, rp, read=0; 05130 05131 ast_mutex_lock (&jb->mutexjb); 05132 05133 rp=jb->rp; 05134 wp=jb->wp; 05135 05136 if(jb->state_empty) 05137 { 05138 for(i=0; i<len; i++) 05139 { 05140 if(wp==rp) 05141 { 05142 jb->rp=rp; 05143 jb->state_empty=0; 05144 05145 ast_mutex_unlock (&jb->mutexjb); 05146 05147 return read; 05148 } 05149 else 05150 { 05151 if(jb->ok[rp]==1) 05152 { 05153 data[i]=jb->samples[rp]; 05154 jb->ok[rp]=0; 05155 rp=(rp!=jb->size-1 ? rp+1 : 0); 05156 read+=1; 05157 } 05158 } 05159 } 05160 05161 if(wp >= rp) 05162 jb->state_buffer=wp-rp; 05163 else 05164 jb->state_buffer= jb->size-rp+wp; 05165 chan_misdn_log(9,0,"misdn_jb_empty: read:%d | Bufferstatus:%d p:%x\n",len,jb->state_buffer,jb); 05166 05167 jb->rp=rp; 05168 } 05169 else 05170 chan_misdn_log(9,0,"misdn_jb_empty: Wait...requested:%d p:%x\n",len,jb); 05171 05172 ast_mutex_unlock (&jb->mutexjb); 05173 05174 return read; 05175 }
|
|
||||||||||||||||
|
Definition at line 5065 of file chan_misdn.c. References ast_mutex_lock(), misdn_jb::mutexjb, misdn_jb::ok, misdn_jb::rp, misdn_jb::samples, misdn_jb::size, misdn_jb::state_full, and misdn_jb::wp. 05066 { 05067 int i, j, rp, wp; 05068 05069 if (!jb || ! data) return 0; 05070 05071 ast_mutex_lock (&jb->mutexjb); 05072 05073 wp=jb->wp; 05074 rp=jb->rp; 05075 05076 for(i=0; i<len; i++) 05077 { 05078 jb->samples[wp]=data[i]; 05079 jb->ok[wp]=1; 05080 wp = (wp!=jb->size-1 ? wp+1 : 0); 05081 05082 if(wp==jb->rp) 05083 jb->state_full=1; 05084 } 05085 05086 if(wp>=rp) 05087 jb->state_buffer=wp-rp; 05088 else 05089 jb->state_buffer= jb->size-rp+wp; 05090 chan_misdn_log(9,0,"misdn_jb_fill: written:%d | Bufferstatus:%d p:%x\n",len,jb->state_buffer,jb); 05091 05092 if(jb->state_full) 05093 { 05094 jb->wp=wp; 05095 05096 rp=wp; 05097 for(j=0; j<jb->upper_threshold; j++) 05098 rp = (rp!=0 ? rp-1 : jb->size-1); 05099 jb->rp=rp; 05100 jb->state_full=0; 05101 jb->state_empty=1; 05102 05103 ast_mutex_unlock (&jb->mutexjb); 05104 05105 return -1; 05106 } 05107 05108 if(!jb->state_empty) 05109 { 05110 jb->bytes_wrote+=len; 05111 if(jb->bytes_wrote>=jb->upper_threshold) 05112 { 05113 jb->state_empty=1; 05114 jb->bytes_wrote=0; 05115 } 05116 } 05117 jb->wp=wp; 05118 05119 ast_mutex_unlock (&jb->mutexjb); 05120 05121 return 0; 05122 }
|
|
||||||||||||
|
Definition at line 5021 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(). 05022 { 05023 int i; 05024 struct misdn_jb *jb = (struct misdn_jb*) malloc(sizeof(struct misdn_jb)); 05025 jb->size = size; 05026 jb->upper_threshold = upper_threshold; 05027 jb->wp = 0; 05028 jb->rp = 0; 05029 jb->state_full = 0; 05030 jb->state_empty = 0; 05031 jb->bytes_wrote = 0; 05032 jb->samples = (char *)malloc(size*sizeof(char)); 05033 05034 if (!jb->samples) { 05035 chan_misdn_log(-1,0,"No free Mem for jb->samples\n"); 05036 return NULL; 05037 } 05038 05039 jb->ok = (char *)malloc(size*sizeof(char)); 05040 05041 if (!jb->ok) { 05042 chan_misdn_log(-1,0,"No free Mem for jb->ok\n"); 05043 return NULL; 05044 } 05045 05046 for(i=0; i<size; i++) 05047 jb->ok[i]=0; 05048 05049 ast_mutex_init(&jb->mutexjb); 05050 05051 return jb; 05052 }
|
|
|
Definition at line 584 of file chan_misdn.c. References chan_misdn_log(). 00585 { 00586 misdn_lib_isdn_l1watcher(*(int *)data); 00587 chan_misdn_log(5, *(int *)data, "L1watcher timeout\n"); 00588 return 1; 00589 }
|
|
||||||||||||||||||||||||||||||||
|
Definition at line 3114 of file chan_misdn.c. References cid_name, cid_num, and misdn_cfg_get_next_port(). Referenced by cb_events(). 03115 { 03116 struct ast_channel *tmp; 03117 char *cid_name = 0, *cid_num = 0; 03118 int chan_offset=0; 03119 int tmp_port = misdn_cfg_get_next_port(0); 03120 03121 for (; tmp_port > 0; tmp_port=misdn_cfg_get_next_port(tmp_port)) { 03122 if (tmp_port == port) break; 03123 chan_offset+=misdn_lib_port_is_pri(tmp_port)?30:2; 03124 } 03125 if (c<0) c=0; 03126 03127 03128 if (callerid) 03129 ast_callerid_parse(callerid, &cid_name, &cid_num); 03130 03131 tmp = ast_channel_alloc(1, state, cid_num, cid_name, "%s/%d-u%d", misdn_type, chan_offset + c, glob_channel++); 03132 03133 if (tmp) { 03134 chan_misdn_log(2, 0, " --> * NEW CHANNEL dad:%s oad:%s\n",exten,callerid); 03135 03136 tmp->nativeformats = prefformat; 03137 03138 tmp->readformat = format; 03139 tmp->rawreadformat = format; 03140 tmp->writeformat = format; 03141 tmp->rawwriteformat = format; 03142 03143 tmp->tech_pvt = chlist; 03144 03145 int bridging; 03146 misdn_cfg_get( 0, MISDN_GEN_BRIDGING, &bridging, sizeof(int)); 03147 if (bridging) 03148 tmp->tech = &misdn_tech; 03149 else 03150 tmp->tech = &misdn_tech_wo_bridge; 03151 03152 tmp->writeformat = format; 03153 tmp->readformat = format; 03154 tmp->priority=1; 03155 03156 if (exten) 03157 ast_copy_string(tmp->exten, exten, sizeof(tmp->exten)); 03158 else 03159 chan_misdn_log(1,0,"misdn_new: no exten given.\n"); 03160 03161 if (callerid) { 03162 char *cid_name, *cid_num; 03163 03164 ast_callerid_parse(callerid, &cid_name, &cid_num); 03165 /* Don't use ast_set_callerid() here because it will 03166 * generate a needless NewCallerID event */ 03167 tmp->cid.cid_num = ast_strdup(cid_num); 03168 tmp->cid.cid_ani = ast_strdup(cid_num); 03169 tmp->cid.cid_name = ast_strdup(cid_name); 03170 } 03171 03172 { 03173 if (pipe(chlist->pipe)<0) 03174 perror("Pipe failed\n"); 03175 03176 tmp->fds[0]=chlist->pipe[0]; 03177 03178 } 03179 03180 if (state == AST_STATE_RING) 03181 tmp->rings = 1; 03182 else 03183 tmp->rings = 0; 03184 03185 03186 } else { 03187 chan_misdn_log(-1,0,"Unable to allocate channel structure\n"); 03188 } 03189 03190 return tmp; 03191 }
|
|
|
Definition at line 591 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, hanguptone_indicate(), MISDN_DIALING, MISDN_WAITING4DIGS, chan_list::overlap_dial, chan_list::overlap_dial_task, chan_list::overlap_tv, chan_list::overlap_tv_lock, pbx_start_chan(), chan_list::state, and stop_indicate(). Referenced by cb_events(). 00592 { 00593 struct timeval tv_end, tv_now; 00594 int diff; 00595 struct chan_list *ch = (struct chan_list *)data; 00596 00597 chan_misdn_log(4, ch->bc->port, "overlap dial task, chan_state: %d\n", ch->state); 00598 00599 if (ch->state != MISDN_WAITING4DIGS) { 00600 ch->overlap_dial_task = -1; 00601 return 0; 00602 } 00603 00604 ast_mutex_lock(&ch->overlap_tv_lock); 00605 tv_end = ch->overlap_tv; 00606 ast_mutex_unlock(&ch->overlap_tv_lock); 00607 00608 tv_end.tv_sec += ch->overlap_dial; 00609 tv_now = ast_tvnow(); 00610 00611 diff = ast_tvdiff_ms(tv_end, tv_now); 00612 00613 if (diff <= 100) { 00614 /* if we are 100ms near the timeout, we are satisfied.. */ 00615 stop_indicate(ch); 00616 if (ast_exists_extension(ch->ast, ch->context, ch->bc->dad, 1, ch->bc->oad)) { 00617 ch->state=MISDN_DIALING; 00618 if (pbx_start_chan(ch) < 0) { 00619 chan_misdn_log(-1, ch->bc->port, "ast_pbx_start returned < 0 in misdn_overlap_dial_task\n"); 00620 goto misdn_overlap_dial_task_disconnect; 00621 } 00622 } else { 00623 misdn_overlap_dial_task_disconnect: 00624 hanguptone_indicate(ch); 00625 if (ch->bc->nt) 00626 misdn_lib_send_event(ch->bc, EVENT_RELEASE_COMPLETE ); 00627 else 00628 misdn_lib_send_event(ch->bc, EVENT_RELEASE); 00629 } 00630 ch->overlap_dial_task = -1; 00631 return 0; 00632 } else 00633 return diff; 00634 }
|
|
||||||||||||||||