#include "asterisk.h"
#include <pthread.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <signal.h>
#include <sys/file.h>
#include <semaphore.h>
#include <ctype.h>
#include <time.h>
#include "asterisk/channel.h"
#include "asterisk/config.h"
#include "asterisk/module.h"
#include "asterisk/pbx.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 "asterisk/abstract_jb.h"
#include "asterisk/causes.h"
#include "chan_misdn_config.h"
#include "isdn_lib.h"
#include "asterisk/strings.h"
Go to the source code of this file.
Data Structures | |
struct | allowed_bearers |
struct | chan_list |
Channel call record structure. More... | |
struct | hold_info |
struct | misdn_jb |
struct | robin_list |
struct | state_struct |
Defines | |
#define | chan_list_ref(obj, debug) (ao2_t_ref((obj), +1, (debug)), (obj)) |
#define | chan_list_unref(obj, debug) (ao2_t_ref((obj), -1, (debug)), NULL) |
#define | MISDN_ASTERISK_TECH_PVT(ast) ast->tech_pvt |
#define | ORG_AST 1 |
#define | ORG_MISDN 2 |
#define | TRANSFER_ON_HELD_CALL_HANGUP 1 |
Enumerations | |
enum | misdn_chan_state { MISDN_NOTHING = 0, MISDN_WAITING4DIGS, MISDN_EXTCANTMATCH, MISDN_INCOMING_SETUP, MISDN_DIALING, MISDN_PROGRESS, MISDN_PROCEEDING, MISDN_CALLING, MISDN_CALLING_ACKNOWLEDGE, MISDN_ALERTING, MISDN_BUSY, MISDN_CONNECTED, MISDN_DISCONNECTED, MISDN_CLEANING } |
enum | misdn_hold_state { MISDN_HOLD_IDLE, MISDN_HOLD_ACTIVE, MISDN_HOLD_TRANSFER, MISDN_HOLD_DISCONNECT } |
Functions | |
static void | __reg_module (void) |
static void | __unreg_module (void) |
static int | _misdn_tasks_add_variable (int timeout, ast_sched_cb callback, const void *data, int variable) |
int | add_in_calls (int port) |
int | add_out_calls (int port) |
static enum mISDN_NUMBER_PLAN | ast_to_misdn_plan (unsigned ast_number_plan) |
static int | ast_to_misdn_pres (int presentation) |
static enum mISDN_REDIRECTING_REASON | ast_to_misdn_reason (const enum AST_REDIRECTING_REASON ast) |
static int | ast_to_misdn_screen (int screening) |
static enum mISDN_NUMBER_TYPE | ast_to_misdn_ton (unsigned ast_number_type) |
static const char * | bearer2str (int cap) |
static enum event_response_e | cb_events (enum event_e event, struct misdn_bchannel *bc, void *user_data) |
static void | chan_list_destructor (void *obj) |
static struct chan_list * | chan_list_init (int orig) |
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 int | cl_dequeue_chan (struct chan_list *chan) |
static void | cl_queue_chan (struct chan_list *chan) |
static char * | complete_ch (struct ast_cli_args *a) |
static char * | complete_debug_port (struct ast_cli_args *a) |
static char * | complete_show_config (struct ast_cli_args *a) |
static void | config_jitterbuffer (struct chan_list *ch) |
void | debug_numtype (int port, int numtype, char *type) |
static int | dialtone_indicate (struct chan_list *cl) |
static void | do_immediate_setup (struct misdn_bchannel *bc, struct chan_list *ch, struct ast_channel *ast) |
static void | export_aoc_vars (int originator, struct ast_channel *ast, struct misdn_bchannel *bc) |
void | export_ch (struct ast_channel *chan, struct misdn_bchannel *bc, struct chan_list *ch) |
Export parameters to the dialplan environment variables. | |
static struct chan_list * | find_chan_by_bc (struct misdn_bchannel *bc) |
static struct chan_list * | find_hold_active_call (struct misdn_bchannel *bc) |
static struct chan_list * | find_hold_call (struct misdn_bchannel *bc) |
static struct chan_list * | find_hold_call_l3 (unsigned long l3_id) |
static void | free_robin_list (void) |
static struct chan_list * | get_chan_by_ast (struct ast_channel *ast) |
static struct chan_list * | get_chan_by_ast_name (const char *name) |
static struct robin_list * | get_robin_position (char *group) |
static char * | handle_cli_misdn_port_block (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_misdn_port_down (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_misdn_port_unblock (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_misdn_port_up (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_misdn_reload (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_misdn_restart_pid (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_misdn_restart_port (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_misdn_send_digit (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_misdn_send_display (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_misdn_send_facility (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_misdn_send_restart (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_misdn_set_crypt_debug (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_misdn_set_debug (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_misdn_set_tics (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_misdn_show_channel (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_misdn_show_channels (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_misdn_show_config (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_misdn_show_port (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_misdn_show_ports_stats (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_misdn_show_stacks (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_misdn_toggle_echocancel (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static void | hangup_chan (struct chan_list *ch, struct misdn_bchannel *bc) |
static void | hanguptone_indicate (struct chan_list *cl) |
void | import_ch (struct ast_channel *chan, struct misdn_bchannel *bc, struct chan_list *ch) |
Import parameters from the dialplan environment variables. | |
static int | load_module (void) |
static void | misdn_add_number_prefix (int port, enum mISDN_NUMBER_TYPE number_type, char *number, size_t size) |
static int | misdn_answer (struct ast_channel *ast) |
static int | misdn_attempt_transfer (struct chan_list *active_ch, struct chan_list *held_ch) |
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_chan_is_valid (struct chan_list *ch) |
static int | misdn_check_l2l1 (struct ast_channel *chan, const char *data) |
static void | misdn_copy_redirecting_from_ast (struct misdn_bchannel *bc, struct ast_channel *ast) |
static void | misdn_copy_redirecting_to_ast (struct ast_channel *ast, const struct misdn_party_redirecting *redirect, char *tag) |
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, const char *data) |
static void | misdn_facility_ie_handler (enum event_e event, struct misdn_bchannel *bc, struct chan_list *ch) |
static int | misdn_fixup (struct ast_channel *oldast, struct ast_channel *ast) |
static const char * | misdn_get_ch_state (struct chan_list *p) |
static void | misdn_get_connected_line (struct ast_channel *ast, struct misdn_bchannel *bc, int originator) |
static int | misdn_hangup (struct ast_channel *ast) |
static int | misdn_indication (struct ast_channel *ast, int cond, const void *data, size_t datalen) |
static int | misdn_is_msn_valid (int port, const struct misdn_party_dialing *dialed) |
void | misdn_jb_destroy (struct misdn_jb *jb) |
frees the data and destroys the given jitterbuffer struct | |
int | misdn_jb_empty (struct misdn_jb *jb, char *data, int len) |
gets len bytes out of the jitterbuffer if available, else only the available data is returned and the return value indicates the number of data. | |
int | misdn_jb_fill (struct misdn_jb *jb, const char *data, int len) |
fills the jitterbuffer with len data returns < 0 if there was an error (buffer overrun). | |
misdn_jb * | misdn_jb_init (int size, int upper_threshold) |
allocates the jb-structure and initialize the elements | |
static int | misdn_l1_task (const void *vdata) |
static struct ast_channel * | misdn_new (struct chan_list *cl, int state, char *exten, char *callerid, int format, const char *linkedid, int port, int c) |
static int | misdn_overlap_dial_task (const void *data) |
static void | misdn_prefix_string (const char *str_prefix, char *str_main, size_t size) |
static void | misdn_queue_connected_line_update (struct ast_channel *ast, const struct misdn_party_id *id, enum AST_CONNECTED_LINE_UPDATE_SOURCE source, char *cid_tag) |
static struct ast_frame * | misdn_read (struct ast_channel *ast) |
static struct ast_channel * | misdn_request (const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause) |
static int | misdn_send_text (struct ast_channel *chan, const char *text) |
static int | misdn_set_opt_exec (struct ast_channel *chan, const char *data) |
static int | misdn_tasks_add (int timeout, ast_sched_cb callback, const void *data) |
static int | misdn_tasks_add_variable (int timeout, ast_sched_cb callback, const 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_to_ast_plan (enum mISDN_NUMBER_PLAN number_plan) |
static int | misdn_to_ast_pres (int presentation) |
static enum AST_REDIRECTING_REASON | misdn_to_ast_reason (const enum mISDN_REDIRECTING_REASON q931) |
static int | misdn_to_ast_screen (int screening) |
static int | misdn_to_ast_ton (enum mISDN_NUMBER_TYPE number_type) |
static const char * | misdn_to_str_plan (enum mISDN_NUMBER_PLAN number_plan) |
static const char * | misdn_to_str_pres (int presentation) |
static const char * | misdn_to_str_screen (int screening) |
static const char * | misdn_to_str_ton (enum mISDN_NUMBER_TYPE number_type) |
static void | misdn_update_caller_id (struct ast_channel *ast, const struct misdn_party_id *id, char *cid_tag) |
static void | misdn_update_connected_line (struct ast_channel *ast, struct misdn_bchannel *bc, int originator) |
static void | misdn_update_redirecting (struct ast_channel *ast, struct misdn_bchannel *bc, int originator) |
static void | misdn_update_remote_party (struct ast_channel *ast, const struct misdn_party_id *id, enum AST_CONNECTED_LINE_UPDATE_SOURCE source, char *cid_tag) |
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 (const struct FacParm *fac, const const 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) |
static void | release_chan (struct chan_list *ch, struct misdn_bchannel *bc) |
static void | release_chan_early (struct chan_list *ch) |
static int | reload (void) |
static void | reload_config (void) |
static void | send_cause2ast (struct ast_channel *ast, struct misdn_bchannel *bc, struct chan_list *ch) |
static void | send_digit_to_chan (struct chan_list *cl, char digit) |
static void | show_config_description (int fd, enum misdn_cfg_elements elem) |
static void | sighandler (int sig) |
static int | start_bc_tones (struct chan_list *cl) |
static void | start_pbx (struct chan_list *ch, struct misdn_bchannel *bc, struct ast_channel *chan) |
static int | stop_bc_tones (struct chan_list *cl) |
static int | stop_indicate (struct chan_list *cl) |
static int | unload_module (void) |
static void | update_config (struct chan_list *ch) |
Updates caller ID information from config. | |
static int | update_ec_config (struct misdn_bchannel *bc) |
static void | update_name (struct ast_channel *tmp, int port, int c) |
static void | wait_for_digits (struct chan_list *ch, struct misdn_bchannel *bc, struct ast_channel *chan) |
Variables | |
static struct ast_module_info | __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Channel driver for mISDN Support (BRI/PRI)" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "8586c2a7d357cb591cc3a6607a8f62d1" , .load = load_module, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_CHANNEL_DRIVER, } |
static struct allowed_bearers | allowed_bearers_array [] |
static struct ast_module_info * | ast_module_info = &__mod_info |
static struct ast_cli_entry | chan_misdn_clis [] |
static struct chan_list * | cl_te = NULL |
Global channel call record list head. | |
static ast_mutex_t | cl_te_lock |
static int | g_config_initialized = 0 |
static int | glob_channel = 0 |
static char | global_tracefile [BUFFERSIZE+1] |
static int | max_ports |
int | MAXTICS = 8 |
static int * | misdn_debug |
static int * | misdn_debug_only |
static int * | misdn_in_calls |
static int * | misdn_out_calls |
static int * | misdn_ports |
static struct sched_context * | misdn_tasks = NULL |
the main schedule context for stuff like l1 watcher, overlap dial, ... | |
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 |
Only alaw and mulaw is allowed for now. | |
static ast_mutex_t | release_lock |
static struct robin_list * | robin = NULL |
static struct state_struct | state_array [] |
static int | tracing = 0 |
Definition in file chan_misdn.c.
Definition at line 341 of file chan_misdn.c.
Referenced by cl_queue_chan(), find_chan_by_bc(), find_hold_active_call(), find_hold_call(), find_hold_call_l3(), get_chan_by_ast(), get_chan_by_ast_name(), and misdn_new().
Definition at line 342 of file chan_misdn.c.
Referenced by cb_events(), chan_misdn_jb_empty(), cl_dequeue_chan(), handle_cli_misdn_send_display(), handle_cli_misdn_send_facility(), handle_cli_misdn_toggle_echocancel(), misdn_bridge(), misdn_hangup(), misdn_request(), release_chan(), and release_chan_early().
#define MISDN_ASTERISK_TECH_PVT | ( | ast | ) | ast->tech_pvt |
Definition at line 653 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_new(), misdn_read(), misdn_send_text(), misdn_set_opt_exec(), misdn_update_connected_line(), misdn_write(), release_chan(), and release_chan_early().
#define ORG_AST 1 |
Asterisk created the channel (outgoing call)
Definition at line 313 of file chan_misdn.c.
Referenced by cb_events(), export_aoc_vars(), misdn_hangup(), misdn_request(), print_bc_info(), read_config(), release_chan(), and release_chan_early().
#define ORG_MISDN 2 |
mISDN created the channel (incoming call)
Definition at line 315 of file chan_misdn.c.
Referenced by cb_events(), misdn_get_connected_line(), misdn_indication(), misdn_update_connected_line(), and misdn_update_redirecting().
#define TRANSFER_ON_HELD_CALL_HANGUP 1 |
Definition at line 8239 of file chan_misdn.c.
enum misdn_chan_state |
Definition at line 295 of file chan_misdn.c.
00295 { 00296 MISDN_NOTHING = 0, /*!< at beginning */ 00297 MISDN_WAITING4DIGS, /*!< when waiting for info */ 00298 MISDN_EXTCANTMATCH, /*!< when asterisk couldn't match our ext */ 00299 MISDN_INCOMING_SETUP, /*!< for incoming setup */ 00300 MISDN_DIALING, /*!< when pbx_start */ 00301 MISDN_PROGRESS, /*!< we have progress */ 00302 MISDN_PROCEEDING, /*!< we have progress */ 00303 MISDN_CALLING, /*!< when misdn_call is called */ 00304 MISDN_CALLING_ACKNOWLEDGE, /*!< when we get SETUP_ACK */ 00305 MISDN_ALERTING, /*!< when Alerting */ 00306 MISDN_BUSY, /*!< when BUSY */ 00307 MISDN_CONNECTED, /*!< when connected */ 00308 MISDN_DISCONNECTED, /*!< when connected */ 00309 MISDN_CLEANING, /*!< when hangup from * but we were connected before */ 00310 };
enum misdn_hold_state |
MISDN_HOLD_IDLE | HOLD not active |
MISDN_HOLD_ACTIVE | Call is held |
MISDN_HOLD_TRANSFER | Held call is being transferred |
MISDN_HOLD_DISCONNECT | Held call is being disconnected |
Definition at line 317 of file chan_misdn.c.
00317 { 00318 MISDN_HOLD_IDLE, /*!< HOLD not active */ 00319 MISDN_HOLD_ACTIVE, /*!< Call is held */ 00320 MISDN_HOLD_TRANSFER, /*!< Held call is being transferred */ 00321 MISDN_HOLD_DISCONNECT, /*!< Held call is being disconnected */ 00322 };
static void __reg_module | ( | void | ) | [static] |
Definition at line 12679 of file chan_misdn.c.
static void __unreg_module | ( | void | ) | [static] |
Definition at line 12679 of file chan_misdn.c.
static int _misdn_tasks_add_variable | ( | int | timeout, | |
ast_sched_cb | callback, | |||
const void * | data, | |||
int | variable | |||
) | [inline, static] |
Definition at line 3558 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().
03559 { 03560 int task_id; 03561 03562 if (!misdn_tasks) { 03563 misdn_tasks_init(); 03564 } 03565 task_id = ast_sched_add_variable(misdn_tasks, timeout, callback, data, variable); 03566 misdn_tasks_wakeup(); 03567 03568 return task_id; 03569 }
int add_in_calls | ( | int | port | ) |
Definition at line 8774 of file chan_misdn.c.
References ast_log(), LOG_NOTICE, misdn_cfg_get(), MISDN_CFG_MAX_IN, and misdn_in_calls.
Referenced by cb_events().
08775 { 08776 int max_in_calls; 08777 08778 misdn_cfg_get(port, MISDN_CFG_MAX_IN, &max_in_calls, sizeof(max_in_calls)); 08779 misdn_in_calls[port]++; 08780 08781 if (max_in_calls >= 0 && max_in_calls < misdn_in_calls[port]) { 08782 ast_log(LOG_NOTICE, "Marking Incoming Call on port[%d]\n", port); 08783 return misdn_in_calls[port] - max_in_calls; 08784 } 08785 08786 return 0; 08787 }
int add_out_calls | ( | int | port | ) |
Definition at line 8789 of file chan_misdn.c.
References ast_log(), LOG_NOTICE, misdn_cfg_get(), MISDN_CFG_MAX_OUT, and misdn_out_calls.
Referenced by misdn_call().
08790 { 08791 int max_out_calls; 08792 08793 misdn_cfg_get(port, MISDN_CFG_MAX_OUT, &max_out_calls, sizeof(max_out_calls)); 08794 08795 if (max_out_calls >= 0 && max_out_calls <= misdn_out_calls[port]) { 08796 ast_log(LOG_NOTICE, "Rejecting Outgoing Call on port[%d]\n", port); 08797 return (misdn_out_calls[port] + 1) - max_out_calls; 08798 } 08799 08800 misdn_out_calls[port]++; 08801 08802 return 0; 08803 }
static enum mISDN_NUMBER_PLAN ast_to_misdn_plan | ( | unsigned | ast_number_plan | ) | [static] |
Definition at line 2012 of file chan_misdn.c.
References NUMPLAN_DATA, NUMPLAN_ISDN, NUMPLAN_NATIONAL, NUMPLAN_PRIVATE, NUMPLAN_TELEX, and NUMPLAN_UNKNOWN.
Referenced by misdn_call(), misdn_copy_redirecting_from_ast(), and misdn_get_connected_line().
02013 { 02014 enum mISDN_NUMBER_PLAN number_plan; 02015 02016 switch (ast_number_plan & 0x0F) { 02017 default: 02018 case NUMPLAN_UNKNOWN: 02019 number_plan = NUMPLAN_UNKNOWN; 02020 break; 02021 02022 case NUMPLAN_ISDN: 02023 number_plan = NUMPLAN_ISDN; 02024 break; 02025 02026 case NUMPLAN_DATA: 02027 number_plan = NUMPLAN_DATA; 02028 break; 02029 02030 case NUMPLAN_TELEX: 02031 number_plan = NUMPLAN_TELEX; 02032 break; 02033 02034 case NUMPLAN_NATIONAL: 02035 number_plan = NUMPLAN_NATIONAL; 02036 break; 02037 02038 case NUMPLAN_PRIVATE: 02039 number_plan = NUMPLAN_PRIVATE; 02040 break; 02041 } 02042 02043 return number_plan; 02044 }
static int ast_to_misdn_pres | ( | int | presentation | ) | [static] |
Definition at line 2115 of file chan_misdn.c.
References AST_PRES_ALLOWED, AST_PRES_RESTRICTED, AST_PRES_RESTRICTION, and AST_PRES_UNAVAILABLE.
Referenced by misdn_copy_redirecting_from_ast(), misdn_get_connected_line(), and update_config().
02116 { 02117 switch (presentation & AST_PRES_RESTRICTION) { 02118 default: 02119 case AST_PRES_ALLOWED: 02120 presentation = 0; 02121 break; 02122 02123 case AST_PRES_RESTRICTED: 02124 presentation = 1; 02125 break; 02126 02127 case AST_PRES_UNAVAILABLE: 02128 presentation = 2; 02129 break; 02130 } 02131 02132 return presentation; 02133 }
static enum mISDN_REDIRECTING_REASON ast_to_misdn_reason | ( | const enum AST_REDIRECTING_REASON | ast | ) | [static] |
Definition at line 2244 of file chan_misdn.c.
References ARRAY_LEN, AST_REDIRECTING_REASON_AWAY, AST_REDIRECTING_REASON_CALL_FWD_DTE, AST_REDIRECTING_REASON_DEFLECTION, AST_REDIRECTING_REASON_DO_NOT_DISTURB, AST_REDIRECTING_REASON_FOLLOW_ME, AST_REDIRECTING_REASON_NO_ANSWER, AST_REDIRECTING_REASON_OUT_OF_ORDER, AST_REDIRECTING_REASON_TIME_OF_DAY, AST_REDIRECTING_REASON_UNAVAILABLE, AST_REDIRECTING_REASON_UNCONDITIONAL, AST_REDIRECTING_REASON_UNKNOWN, AST_REDIRECTING_REASON_USER_BUSY, mISDN_REDIRECTING_REASON_CALL_FWD, mISDN_REDIRECTING_REASON_CALL_FWD_BUSY, mISDN_REDIRECTING_REASON_CALL_FWD_DTE, mISDN_REDIRECTING_REASON_DEFLECTION, mISDN_REDIRECTING_REASON_NO_REPLY, mISDN_REDIRECTING_REASON_OUT_OF_ORDER, and mISDN_REDIRECTING_REASON_UNKNOWN.
Referenced by misdn_copy_redirecting_from_ast().
02245 { 02246 unsigned index; 02247 02248 static const struct misdn_reasons { 02249 enum AST_REDIRECTING_REASON ast; 02250 enum mISDN_REDIRECTING_REASON q931; 02251 } misdn_reason_table[] = { 02252 /* *INDENT-OFF* */ 02253 { AST_REDIRECTING_REASON_UNKNOWN, mISDN_REDIRECTING_REASON_UNKNOWN }, 02254 { AST_REDIRECTING_REASON_USER_BUSY, mISDN_REDIRECTING_REASON_CALL_FWD_BUSY }, 02255 { AST_REDIRECTING_REASON_NO_ANSWER, mISDN_REDIRECTING_REASON_NO_REPLY }, 02256 { AST_REDIRECTING_REASON_UNAVAILABLE, mISDN_REDIRECTING_REASON_NO_REPLY }, 02257 { AST_REDIRECTING_REASON_UNCONDITIONAL, mISDN_REDIRECTING_REASON_CALL_FWD }, 02258 { AST_REDIRECTING_REASON_TIME_OF_DAY, mISDN_REDIRECTING_REASON_UNKNOWN }, 02259 { AST_REDIRECTING_REASON_DO_NOT_DISTURB, mISDN_REDIRECTING_REASON_UNKNOWN }, 02260 { AST_REDIRECTING_REASON_DEFLECTION, mISDN_REDIRECTING_REASON_DEFLECTION }, 02261 { AST_REDIRECTING_REASON_FOLLOW_ME, mISDN_REDIRECTING_REASON_UNKNOWN }, 02262 { AST_REDIRECTING_REASON_OUT_OF_ORDER, mISDN_REDIRECTING_REASON_OUT_OF_ORDER }, 02263 { AST_REDIRECTING_REASON_AWAY, mISDN_REDIRECTING_REASON_UNKNOWN }, 02264 { AST_REDIRECTING_REASON_CALL_FWD_DTE, mISDN_REDIRECTING_REASON_CALL_FWD_DTE } 02265 /* *INDENT-ON* */ 02266 }; 02267 02268 for (index = 0; index < ARRAY_LEN(misdn_reason_table); ++index) { 02269 if (misdn_reason_table[index].ast == ast) { 02270 return misdn_reason_table[index].q931; 02271 } 02272 } 02273 return mISDN_REDIRECTING_REASON_UNKNOWN; 02274 }
static int ast_to_misdn_screen | ( | int | screening | ) | [static] |
Definition at line 2212 of file chan_misdn.c.
References AST_PRES_NETWORK_NUMBER, AST_PRES_NUMBER_TYPE, AST_PRES_USER_NUMBER_FAILED_SCREEN, AST_PRES_USER_NUMBER_PASSED_SCREEN, and AST_PRES_USER_NUMBER_UNSCREENED.
Referenced by misdn_copy_redirecting_from_ast(), misdn_get_connected_line(), and update_config().
02213 { 02214 switch (screening & AST_PRES_NUMBER_TYPE) { 02215 default: 02216 case AST_PRES_USER_NUMBER_UNSCREENED: 02217 screening = 0; 02218 break; 02219 02220 case AST_PRES_USER_NUMBER_PASSED_SCREEN: 02221 screening = 1; 02222 break; 02223 02224 case AST_PRES_USER_NUMBER_FAILED_SCREEN: 02225 screening = 2; 02226 break; 02227 02228 case AST_PRES_NETWORK_NUMBER: 02229 screening = 3; 02230 break; 02231 } 02232 02233 return screening; 02234 }
static enum mISDN_NUMBER_TYPE ast_to_misdn_ton | ( | unsigned | ast_number_type | ) | [static] |
Definition at line 1886 of file chan_misdn.c.
References NUMTYPE_ABBREVIATED, NUMTYPE_INTERNATIONAL, NUMTYPE_NATIONAL, NUMTYPE_NETWORK_SPECIFIC, NUMTYPE_SUBSCRIBER, and NUMTYPE_UNKNOWN.
Referenced by misdn_call(), misdn_copy_redirecting_from_ast(), and misdn_get_connected_line().
01887 { 01888 enum mISDN_NUMBER_TYPE number_type; 01889 01890 switch ((ast_number_type >> 4) & 0x07) { 01891 default: 01892 case NUMTYPE_UNKNOWN: 01893 number_type = NUMTYPE_UNKNOWN; 01894 break; 01895 01896 case NUMTYPE_INTERNATIONAL: 01897 number_type = NUMTYPE_INTERNATIONAL; 01898 break; 01899 01900 case NUMTYPE_NATIONAL: 01901 number_type = NUMTYPE_NATIONAL; 01902 break; 01903 01904 case NUMTYPE_NETWORK_SPECIFIC: 01905 number_type = NUMTYPE_NETWORK_SPECIFIC; 01906 break; 01907 01908 case NUMTYPE_SUBSCRIBER: 01909 number_type = NUMTYPE_SUBSCRIBER; 01910 break; 01911 01912 case NUMTYPE_ABBREVIATED: 01913 number_type = NUMTYPE_ABBREVIATED; 01914 break; 01915 } 01916 01917 return number_type; 01918 }
static const char* bearer2str | ( | int | cap | ) | [static] |
Definition at line 2343 of file chan_misdn.c.
References allowed_bearers_array, ARRAY_LEN, and allowed_bearers::display.
Referenced by cb_events(), misdn_lib_log_ies(), print_bc_info(), and print_bearer().
02344 { 02345 unsigned index; 02346 02347 for (index = 0; index < ARRAY_LEN(allowed_bearers_array); ++index) { 02348 if (allowed_bearers_array[index].cap == cap) { 02349 return allowed_bearers_array[index].display; 02350 } 02351 } 02352 02353 return "Unknown Bearer"; 02354 }
static enum event_response_e cb_events | ( | enum event_e | event, | |
struct misdn_bchannel * | bc, | |||
void * | user_data | |||
) | [static] |
Definition at line 9831 of file chan_misdn.c.
References add_in_calls(), misdn_bchannel::addr, chan_list::addr, chan_list::allowed_bearers, allowed_bearers_array, ao2_ref, misdn_bchannel::AOCD_need_export, ARRAY_LEN, chan_list::ast, ast_bridged_channel(), ast_canmatch_extension(), AST_CAUSE_DESTINATION_OUT_OF_ORDER, AST_CAUSE_INCOMPATIBLE_DESTINATION, AST_CAUSE_NORMAL_CLEARING, AST_CAUSE_UNALLOCATED, AST_CAUSE_USER_BUSY, ast_cdr_update(), ast_channel_lock, ast_channel_queue_redirecting_update(), ast_channel_unlock, AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER, AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER, AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER_ALERTING, AST_CONTROL_ANSWER, AST_CONTROL_BUSY, AST_CONTROL_HOLD, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_RINGING, AST_CONTROL_UNHOLD, ast_copy_string(), ast_deactivate_generator(), ast_exists_extension(), AST_FORMAT_ALAW, AST_FRAME_DTMF, AST_FRAME_VOICE, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_pickup_call(), ast_pickup_ext(), ast_poll, AST_PRES_RESTRICTED, AST_PRES_USER_NUMBER_UNSCREENED, ast_queue_control(), ast_queue_frame(), ast_set_callerid(), ast_setstate(), AST_STATE_RESERVED, AST_STATE_RINGING, ast_strdup, ast_strlen_zero(), ast_transfercapability2str(), ast_tv(), ast_tvnow(), chan_list::bc, misdn_bchannel::bc_state, bc_state2str(), bearer2str(), misdn_bchannel::bframe, misdn_bchannel::bframe_len, ast_channel::caller, misdn_bchannel::caller, misdn_bchannel::capability, misdn_bchannel::cause, cause, cb_log, chan_list_init(), chan_list_unref, chan_misdn_log(), hold_info::channel, misdn_bchannel::channel, cl_queue_chan(), misdn_bchannel::connected, chan_list::context, misdn_bchannel::cw, misdn_bchannel::dialed, do_immediate_setup(), misdn_bchannel::dtmf, misdn_bchannel::dummy, errno, EVENT_ALERTING, EVENT_BCHAN_ACTIVATED, EVENT_BCHAN_DATA, EVENT_BCHAN_ERROR, EVENT_CLEANUP, EVENT_CONNECT, EVENT_CONNECT_ACKNOWLEDGE, EVENT_DISCONNECT, EVENT_DTMF_TONE, EVENT_FACILITY, EVENT_HOLD, EVENT_HOLD_ACKNOWLEDGE, EVENT_HOLD_REJECT, EVENT_INFORMATION, EVENT_NEW_BC, EVENT_NEW_CHANNEL, EVENT_NEW_L3ID, EVENT_NOTIFY, EVENT_PORT_ALARM, EVENT_PROCEEDING, EVENT_PROGRESS, EVENT_REGISTER, EVENT_RELEASE, EVENT_RELEASE_COMPLETE, EVENT_RESTART, EVENT_RETRIEVE, EVENT_RETRIEVE_ACKNOWLEDGE, EVENT_RETRIEVE_REJECT, EVENT_SETUP, EVENT_SETUP_ACKNOWLEDGE, EVENT_STATUS, EVENT_TIMEOUT, EVENT_TONE_GENERATE, export_aoc_vars(), export_ch(), ast_channel::exten, misdn_bchannel::fac_in, misdn_bchannel::fac_out, chan_list::far_alerting, find_chan_by_bc(), find_hold_active_call(), find_hold_call(), find_hold_call_l3(), misdn_party_redirecting::from, ast_generator::generate, ast_channel::generator, ast_channel::generatordata, hangup_chan(), ast_channel::hangupcause, hanguptone_indicate(), chan_list::hold, ast_party_caller::id, chan_list::ignore_dtmf, misdn_bchannel::incoming_cid_tag, INFO_CAPABILITY_DIGITAL_UNRESTRICTED, misdn_bchannel::info_dad, INFO_PI_INBAND_AVAILABLE, misdn_bchannel::infos_pending, misdn_bchannel::keypad, misdn_bchannel::l3_id, chan_list::l3id, LOG_ERROR, LOG_NOTICE, LOG_WARNING, manager_isdn_get_info(), misdn_add_number_prefix(), MISDN_ALERTING, MISDN_ASTERISK_TECH_PVT, misdn_attempt_transfer(), MISDN_CALLING, MISDN_CALLING_ACKNOWLEDGE, misdn_cap_is_speech(), MISDN_CFG_ALARM_BLOCK, MISDN_CFG_ALWAYS_IMMEDIATE, MISDN_CFG_APPEND_MSN_TO_CALLERID_TAG, misdn_cfg_get(), MISDN_CFG_HOLD_ALLOWED, MISDN_CFG_IMMEDIATE, MISDN_CFG_REJECT_CAUSE, MISDN_CLEANING, MISDN_CONNECTED, misdn_copy_redirecting_to_ast(), MISDN_DIALING, MISDN_DISCONNECTED, MISDN_EXTCANTMATCH, misdn_facility_ie_handler(), MISDN_GEN_APPEND_DIGITS2EXTEN, misdn_get_ch_state(), MISDN_HOLD_ACTIVE, MISDN_HOLD_DISCONNECT, MISDN_HOLD_IDLE, misdn_inband_avail(), MISDN_INCOMING_SETUP, misdn_is_msn_valid(), misdn_lib_is_ptp(), misdn_lib_log_ies(), misdn_lib_port_block(), misdn_lib_send_event(), misdn_new(), MISDN_NOTHING, mISDN_NOTIFY_CODE_CALL_IS_DIVERTING, mISDN_NOTIFY_CODE_CALL_TRANSFER_ACTIVE, mISDN_NOTIFY_CODE_CALL_TRANSFER_ALERTING, mISDN_NOTIFY_CODE_DIVERSION_ACTIVATED, mISDN_NOTIFY_CODE_INVALID, misdn_overlap_dial_task(), MISDN_PROCEEDING, MISDN_PROGRESS, mISDN_REDIRECTING_REASON_NO_REPLY, mISDN_REDIRECTING_REASON_UNKNOWN, misdn_tasks_add_variable(), misdn_to_ast_plan(), misdn_to_ast_pres(), misdn_to_ast_screen(), misdn_to_ast_ton(), misdn_to_str_plan(), misdn_to_str_pres(), misdn_to_str_screen(), misdn_to_str_ton(), misdn_update_remote_party(), MISDN_WAITING4DIGS, allowed_bearers::name, misdn_party_id::name, chan_list::need_busy, misdn_bchannel::need_disconnect, misdn_bchannel::need_more_infos, misdn_bchannel::need_release, misdn_bchannel::need_release_complete, chan_list::noautorespond_on_setup, misdn_bchannel::notify_description_code, misdn_bchannel::nt, chan_list::nttimeout, ast_party_id::number, misdn_party_dialing::number, misdn_party_id::number, misdn_party_id::number_plan, misdn_party_id::number_type, ORG_AST, ORG_MISDN, chan_list::originator, misdn_bchannel::out_cause, chan_list::overlap_dial, chan_list::overlap_dial_task, chan_list::overlap_tv, chan_list::overlap_tv_lock, pbx_builtin_setvar_helper(), misdn_bchannel::pid, chan_list::pipe, ast_party_number::plan, hold_info::port, misdn_bchannel::port, ast_party_number::presentation, misdn_party_id::presentation, print_bearer(), misdn_bchannel::progress_indicator, read_config(), misdn_party_redirecting::reason, ast_channel::redirecting, misdn_bchannel::redirecting, release_chan(), RESPONSE_IGNORE_SETUP, RESPONSE_IGNORE_SETUP_WITHOUT_CLOSE, RESPONSE_OK, RESPONSE_RELEASE_SETUP, ast_channel::rings, misdn_party_id::screening, misdn_bchannel::sending_complete, start_bc_tones(), start_pbx(), hold_info::state, chan_list::state, stop_bc_tones(), stop_indicate(), ast_party_id::tag, ast_channel::tech, misdn_party_redirecting::to, ast_party_redirecting::to, misdn_party_redirecting::to_changed, misdn_bchannel::tone_cnt, ast_channel::transfercapability, ast_channel_tech::type, update_name(), and wait_for_digits().
Referenced by load_module().
09832 { 09833 #if defined(AST_MISDN_ENHANCEMENTS) 09834 struct misdn_cc_record *cc_record; 09835 #endif /* defined(AST_MISDN_ENHANCEMENTS) */ 09836 struct chan_list *held_ch; 09837 struct chan_list *ch = find_chan_by_bc(bc); 09838 09839 if (event != EVENT_BCHAN_DATA && event != EVENT_TONE_GENERATE) { 09840 int debuglevel = 1; 09841 09842 /* Debug Only Non-Bchan */ 09843 if (event == EVENT_CLEANUP && !user_data) { 09844 debuglevel = 5; 09845 } 09846 09847 chan_misdn_log(debuglevel, bc->port, 09848 "I IND :%s caller:\"%s\" <%s> dialed:%s pid:%d state:%s\n", 09849 manager_isdn_get_info(event), 09850 bc->caller.name, 09851 bc->caller.number, 09852 bc->dialed.number, 09853 bc->pid, 09854 ch ? misdn_get_ch_state(ch) : "none"); 09855 if (debuglevel == 1) { 09856 misdn_lib_log_ies(bc); 09857 chan_misdn_log(4, bc->port, " --> bc_state:%s\n", bc_state2str(bc->bc_state)); 09858 } 09859 } 09860 09861 if (!ch) { 09862 switch(event) { 09863 case EVENT_SETUP: 09864 case EVENT_DISCONNECT: 09865 case EVENT_RELEASE: 09866 case EVENT_RELEASE_COMPLETE: 09867 case EVENT_PORT_ALARM: 09868 case EVENT_RETRIEVE: 09869 case EVENT_NEW_BC: 09870 case EVENT_FACILITY: 09871 case EVENT_REGISTER: 09872 break; 09873 case EVENT_CLEANUP: 09874 case EVENT_TONE_GENERATE: 09875 case EVENT_BCHAN_DATA: 09876 return -1; 09877 default: 09878 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); 09879 return -1; 09880 } 09881 } else { 09882 switch (event) { 09883 case EVENT_TONE_GENERATE: 09884 break; 09885 case EVENT_DISCONNECT: 09886 case EVENT_RELEASE: 09887 case EVENT_RELEASE_COMPLETE: 09888 case EVENT_CLEANUP: 09889 case EVENT_TIMEOUT: 09890 if (!ch->ast) { 09891 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)); 09892 } 09893 break; 09894 default: 09895 if (!ch->ast || !MISDN_ASTERISK_TECH_PVT(ch->ast)) { 09896 if (event != EVENT_BCHAN_DATA) { 09897 ast_log(LOG_NOTICE, "No Ast or No private Pointer in Event (%d:%s)\n", event, manager_isdn_get_info(event)); 09898 } 09899 chan_list_unref(ch, "No Ast or Ast private pointer"); 09900 return -1; 09901 } 09902 break; 09903 } 09904 } 09905 09906 09907 switch (event) { 09908 case EVENT_PORT_ALARM: 09909 { 09910 int boa = 0; 09911 misdn_cfg_get(bc->port, MISDN_CFG_ALARM_BLOCK, &boa, sizeof(boa)); 09912 if (boa) { 09913 cb_log(1, bc->port, " --> blocking\n"); 09914 misdn_lib_port_block(bc->port); 09915 } 09916 } 09917 break; 09918 case EVENT_BCHAN_ACTIVATED: 09919 break; 09920 09921 case EVENT_NEW_CHANNEL: 09922 update_name(ch->ast,bc->port,bc->channel); 09923 break; 09924 09925 case EVENT_NEW_L3ID: 09926 ch->l3id=bc->l3_id; 09927 ch->addr=bc->addr; 09928 break; 09929 09930 case EVENT_NEW_BC: 09931 if (!ch) { 09932 ch = find_hold_call(bc); 09933 } 09934 09935 if (!ch) { 09936 ast_log(LOG_WARNING, "NEW_BC without chan_list?\n"); 09937 break; 09938 } 09939 09940 if (bc) { 09941 ch->bc = (struct misdn_bchannel *) user_data; 09942 } 09943 break; 09944 09945 case EVENT_DTMF_TONE: 09946 { 09947 /* sending INFOS as DTMF-Frames :) */ 09948 struct ast_frame fr; 09949 09950 memset(&fr, 0, sizeof(fr)); 09951 fr.frametype = AST_FRAME_DTMF; 09952 fr.subclass.integer = bc->dtmf ; 09953 fr.src = NULL; 09954 fr.data.ptr = NULL; 09955 fr.datalen = 0; 09956 fr.samples = 0; 09957 fr.mallocd = 0; 09958 fr.offset = 0; 09959 fr.delivery = ast_tv(0,0); 09960 09961 if (!ch->ignore_dtmf) { 09962 chan_misdn_log(2, bc->port, " --> DTMF:%c\n", bc->dtmf); 09963 ast_queue_frame(ch->ast, &fr); 09964 } else { 09965 chan_misdn_log(2, bc->port, " --> Ignoring DTMF:%c due to bridge flags\n", bc->dtmf); 09966 } 09967 break; 09968 } 09969 case EVENT_STATUS: 09970 break; 09971 09972 case EVENT_INFORMATION: 09973 if (ch->state != MISDN_CONNECTED) { 09974 stop_indicate(ch); 09975 } 09976 09977 if (!ch->ast) { 09978 break; 09979 } 09980 09981 if (ch->state == MISDN_WAITING4DIGS) { 09982 /* Ok, incomplete Setup, waiting till extension exists */ 09983 if (ast_strlen_zero(bc->info_dad) && ! ast_strlen_zero(bc->keypad)) { 09984 chan_misdn_log(1, bc->port, " --> using keypad as info\n"); 09985 ast_copy_string(bc->info_dad, bc->keypad, sizeof(bc->info_dad)); 09986 } 09987 09988 strncat(bc->dialed.number, bc->info_dad, sizeof(bc->dialed.number) - strlen(bc->dialed.number) - 1); 09989 ast_copy_string(ch->ast->exten, bc->dialed.number, sizeof(ch->ast->exten)); 09990 09991 /* Check for Pickup Request first */ 09992 if (!strcmp(ch->ast->exten, ast_pickup_ext())) { 09993 if (ast_pickup_call(ch->ast)) { 09994 hangup_chan(ch, bc); 09995 } else { 09996 ch->state = MISDN_CALLING_ACKNOWLEDGE; 09997 hangup_chan(ch, bc); 09998 ch->ast = NULL; 09999 break; 10000 } 10001 } 10002 10003 if (!ast_canmatch_extension(ch->ast, ch->context, bc->dialed.number, 1, bc->caller.number)) { 10004 if (ast_exists_extension(ch->ast, ch->context, "i", 1, bc->caller.number)) { 10005 ast_log(LOG_WARNING, 10006 "Extension '%s@%s' can never match. Jumping to 'i' extension. port:%d\n", 10007 bc->dialed.number, ch->context, bc->port); 10008 strcpy(ch->ast->exten, "i"); 10009 10010 ch->state = MISDN_DIALING; 10011 start_pbx(ch, bc, ch->ast); 10012 break; 10013 } 10014 10015 ast_log(LOG_WARNING, 10016 "Extension '%s@%s' can never match. Disconnecting. port:%d\n" 10017 "\tMaybe you want to add an 'i' extension to catch this case.\n", 10018 bc->dialed.number, ch->context, bc->port); 10019 10020 if (bc->nt) { 10021 hanguptone_indicate(ch); 10022 } 10023 ch->state = MISDN_EXTCANTMATCH; 10024 bc->out_cause = AST_CAUSE_UNALLOCATED; 10025 10026 misdn_lib_send_event(bc, EVENT_DISCONNECT); 10027 break; 10028 } 10029 10030 if (ch->overlap_dial) { 10031 ast_mutex_lock(&ch->overlap_tv_lock); 10032 ch->overlap_tv = ast_tvnow(); 10033 ast_mutex_unlock(&ch->overlap_tv_lock); 10034 if (ch->overlap_dial_task == -1) { 10035 ch->overlap_dial_task = 10036 misdn_tasks_add_variable(ch->overlap_dial, misdn_overlap_dial_task, ch); 10037 } 10038 break; 10039 } 10040 10041 if (ast_exists_extension(ch->ast, ch->context, bc->dialed.number, 1, bc->caller.number)) { 10042 ch->state = MISDN_DIALING; 10043 start_pbx(ch, bc, ch->ast); 10044 } 10045 } else { 10046 /* sending INFOS as DTMF-Frames :) */ 10047 struct ast_frame fr; 10048 int digits; 10049 10050 memset(&fr, 0, sizeof(fr)); 10051 fr.frametype = AST_FRAME_DTMF; 10052 fr.subclass.integer = bc->info_dad[0] ; 10053 fr.src = NULL; 10054 fr.data.ptr = NULL; 10055 fr.datalen = 0; 10056 fr.samples = 0; 10057 fr.mallocd = 0; 10058 fr.offset = 0; 10059 fr.delivery = ast_tv(0,0); 10060 10061 misdn_cfg_get(0, MISDN_GEN_APPEND_DIGITS2EXTEN, &digits, sizeof(digits)); 10062 if (ch->state != MISDN_CONNECTED) { 10063 if (digits) { 10064 strncat(bc->dialed.number, bc->info_dad, sizeof(bc->dialed.number) - strlen(bc->dialed.number) - 1); 10065 ast_copy_string(ch->ast->exten, bc->dialed.number, sizeof(ch->ast->exten)); 10066 ast_cdr_update(ch->ast); 10067 } 10068 10069 ast_queue_frame(ch->ast, &fr); 10070 } 10071 } 10072 break; 10073 case EVENT_SETUP: 10074 { 10075 struct ast_channel *chan; 10076 int exceed; 10077 int ai; 10078 int im; 10079 int append_msn = 0; 10080 10081 if (ch) { 10082 switch (ch->state) { 10083 case MISDN_NOTHING: 10084 chan_list_unref(ch, "Ignore found ch. Is it for an outgoing call?"); 10085 ch = NULL; 10086 break; 10087 default: 10088 chan_list_unref(ch, "Already have a call."); 10089 chan_misdn_log(1, bc->port, " --> Ignoring Call we have already one\n"); 10090 return RESPONSE_IGNORE_SETUP_WITHOUT_CLOSE; /* Ignore MSNs which are not in our List */ 10091 } 10092 } 10093 10094 if (!bc->nt && !misdn_is_msn_valid(bc->port, &bc->dialed)) { 10095 chan_misdn_log(1, bc->port, " --> Ignoring Call, its not in our MSN List\n"); 10096 return RESPONSE_IGNORE_SETUP; /* Ignore MSNs which are not in our List */ 10097 } 10098 10099 if (bc->cw) { 10100 int cause; 10101 chan_misdn_log(0, bc->port, " --> Call Waiting on PMP sending RELEASE_COMPLETE\n"); 10102 misdn_cfg_get(bc->port, MISDN_CFG_REJECT_CAUSE, &cause, sizeof(cause)); 10103 bc->out_cause = cause ? cause : AST_CAUSE_NORMAL_CLEARING; 10104 return RESPONSE_RELEASE_SETUP; 10105 } 10106 10107 print_bearer(bc); 10108 10109 ch = chan_list_init(ORG_MISDN); 10110 if (!ch) { 10111 chan_misdn_log(-1, bc->port, "cb_events: malloc for chan_list failed!\n"); 10112 return 0; 10113 } 10114 10115 ch->bc = bc; 10116 ch->l3id = bc->l3_id; 10117 ch->addr = bc->addr; 10118 10119 chan = misdn_new(ch, AST_STATE_RESERVED, bc->dialed.number, bc->caller.number, AST_FORMAT_ALAW, NULL, bc->port, bc->channel); 10120 if (!chan) { 10121 chan_list_unref(ch, "Failed to create a new channel"); 10122 misdn_lib_send_event(bc,EVENT_RELEASE_COMPLETE); 10123 ast_log(LOG_ERROR, "cb_events: misdn_new failed !\n"); 10124 return 0; 10125 } 10126 10127 if ((exceed = add_in_calls(bc->port))) { 10128 char tmp[16]; 10129 snprintf(tmp, sizeof(tmp), "%d", exceed); 10130 pbx_builtin_setvar_helper(chan, "MAX_OVERFLOW", tmp); 10131 } 10132 10133 read_config(ch); 10134 10135 export_ch(chan, bc, ch); 10136 10137 ch->ast->rings = 1; 10138 ast_setstate(ch->ast, AST_STATE_RINGING); 10139 10140 /* Update asterisk channel caller information */ 10141 chan_misdn_log(2, bc->port, " --> TON: %s(%d)\n", misdn_to_str_ton(bc->caller.number_type), bc->caller.number_type); 10142 chan_misdn_log(2, bc->port, " --> PLAN: %s(%d)\n", misdn_to_str_plan(bc->caller.number_plan), bc->caller.number_plan); 10143 chan->caller.id.number.plan = misdn_to_ast_ton(bc->caller.number_type) 10144 | misdn_to_ast_plan(bc->caller.number_plan); 10145 10146 chan_misdn_log(2, bc->port, " --> PRES: %s(%d)\n", misdn_to_str_pres(bc->caller.presentation), bc->caller.presentation); 10147 chan_misdn_log(2, bc->port, " --> SCREEN: %s(%d)\n", misdn_to_str_screen(bc->caller.screening), bc->caller.screening); 10148 chan->caller.id.number.presentation = misdn_to_ast_pres(bc->caller.presentation) 10149 | misdn_to_ast_screen(bc->caller.screening); 10150 10151 ast_set_callerid(chan, bc->caller.number, NULL, bc->caller.number); 10152 10153 misdn_cfg_get(bc->port, MISDN_CFG_APPEND_MSN_TO_CALLERID_TAG, &append_msn, sizeof(append_msn)); 10154 if (append_msn) { 10155 strncat(bc->incoming_cid_tag, "_", sizeof(bc->incoming_cid_tag) - strlen(bc->incoming_cid_tag) - 1); 10156 strncat(bc->incoming_cid_tag, bc->dialed.number, sizeof(bc->incoming_cid_tag) - strlen(bc->incoming_cid_tag) - 1); 10157 } 10158 10159 ast_channel_lock(chan); 10160 chan->caller.id.tag = ast_strdup(bc->incoming_cid_tag); 10161 ast_channel_unlock(chan); 10162 10163 if (!ast_strlen_zero(bc->redirecting.from.number)) { 10164 /* Add configured prefix to redirecting.from.number */ 10165 misdn_add_number_prefix(bc->port, bc->redirecting.from.number_type, bc->redirecting.from.number, sizeof(bc->redirecting.from.number)); 10166 10167 /* Update asterisk channel redirecting information */ 10168 misdn_copy_redirecting_to_ast(chan, &bc->redirecting, bc->incoming_cid_tag); 10169 } 10170 10171 pbx_builtin_setvar_helper(chan, "TRANSFERCAPABILITY", ast_transfercapability2str(bc->capability)); 10172 chan->transfercapability = bc->capability; 10173 10174 switch (bc->capability) { 10175 case INFO_CAPABILITY_DIGITAL_UNRESTRICTED: 10176 pbx_builtin_setvar_helper(chan, "CALLTYPE", "DIGITAL"); 10177 break; 10178 default: 10179 pbx_builtin_setvar_helper(chan, "CALLTYPE", "SPEECH"); 10180 break; 10181 } 10182 10183 /** queue new chan **/ 10184 cl_queue_chan(ch); 10185 10186 if (!strstr(ch->allowed_bearers, "all")) { 10187 int i; 10188 10189 for (i = 0; i < ARRAY_LEN(allowed_bearers_array); ++i) { 10190 if (allowed_bearers_array[i].cap == bc->capability) { 10191 if (strstr(ch->allowed_bearers, allowed_bearers_array[i].name)) { 10192 /* The bearer capability is allowed */ 10193 if (allowed_bearers_array[i].deprecated) { 10194 chan_misdn_log(0, bc->port, "%s in allowed_bearers list is deprecated\n", 10195 allowed_bearers_array[i].name); 10196 } 10197 break; 10198 } 10199 } 10200 } 10201 if (i == ARRAY_LEN(allowed_bearers_array)) { 10202 /* We did not find the bearer capability */ 10203 chan_misdn_log(0, bc->port, "Bearer capability not allowed: %s(%d)\n", 10204 bearer2str(bc->capability), bc->capability); 10205 bc->out_cause = AST_CAUSE_INCOMPATIBLE_DESTINATION; 10206 10207 ch->state = MISDN_EXTCANTMATCH; 10208 misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE); 10209 chan_list_unref(ch, "BC not allowed, releasing call"); 10210 return RESPONSE_OK; 10211 } 10212 } 10213 10214 if (bc->fac_in.Function != Fac_None) { 10215 misdn_facility_ie_handler(event, bc, ch); 10216 } 10217 10218 /* Check for Pickup Request first */ 10219 if (!strcmp(chan->exten, ast_pickup_ext())) { 10220 if (!ch->noautorespond_on_setup) { 10221 /* Sending SETUP_ACK */ 10222 misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE); 10223 } else { 10224 ch->state = MISDN_INCOMING_SETUP; 10225 } 10226 if (ast_pickup_call(chan)) { 10227 hangup_chan(ch, bc); 10228 } else { 10229 ch->state = MISDN_CALLING_ACKNOWLEDGE; 10230 hangup_chan(ch, bc); 10231 ch->ast = NULL; 10232 break; 10233 } 10234 } 10235 10236 /* 10237 * added support for s extension hope it will help those poor cretains 10238 * which haven't overlap dial. 10239 */ 10240 misdn_cfg_get(bc->port, MISDN_CFG_ALWAYS_IMMEDIATE, &ai, sizeof(ai)); 10241 if (ai) { 10242 do_immediate_setup(bc, ch, chan); 10243 break; 10244 } 10245 10246 /* check if we should jump into s when we have no dialed.number */ 10247 misdn_cfg_get(bc->port, MISDN_CFG_IMMEDIATE, &im, sizeof(im)); 10248 if (im && ast_strlen_zero(bc->dialed.number)) { 10249 do_immediate_setup(bc, ch, chan); 10250 break; 10251 } 10252 10253 chan_misdn_log(5, bc->port, "CONTEXT:%s\n", ch->context); 10254 if (!ast_canmatch_extension(ch->ast, ch->context, bc->dialed.number, 1, bc->caller.number)) { 10255 if (ast_exists_extension(ch->ast, ch->context, "i", 1, bc->caller.number)) { 10256 ast_log(LOG_WARNING, 10257 "Extension '%s@%s' can never match. Jumping to 'i' extension. port:%d\n", 10258 bc->dialed.number, ch->context, bc->port); 10259 strcpy(ch->ast->exten, "i"); 10260 misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE); 10261 ch->state = MISDN_DIALING; 10262 start_pbx(ch, bc, chan); 10263 break; 10264 } 10265 10266 ast_log(LOG_WARNING, 10267 "Extension '%s@%s' can never match. Disconnecting. port:%d\n" 10268 "\tMaybe you want to add an 'i' extension to catch this case.\n", 10269 bc->dialed.number, ch->context, bc->port); 10270 if (bc->nt) { 10271 hanguptone_indicate(ch); 10272 } 10273 10274 ch->state = MISDN_EXTCANTMATCH; 10275 bc->out_cause = AST_CAUSE_UNALLOCATED; 10276 10277 misdn_lib_send_event(bc, bc->nt ? EVENT_RELEASE_COMPLETE : EVENT_RELEASE); 10278 break; 10279 } 10280 10281 /* Whatever happens, when sending_complete is set or we are PTMP TE, we will definitely 10282 * jump into the dialplan, when the dialed extension does not exist, the 's' extension 10283 * will be used by Asterisk automatically. */ 10284 if (bc->sending_complete || (!bc->nt && !misdn_lib_is_ptp(bc->port))) { 10285 if (!ch->noautorespond_on_setup) { 10286 ch->state=MISDN_DIALING; 10287 misdn_lib_send_event(bc, EVENT_PROCEEDING); 10288 } else { 10289 ch->state = MISDN_INCOMING_SETUP; 10290 } 10291 start_pbx(ch, bc, chan); 10292 break; 10293 } 10294 10295 10296 /* 10297 * When we are NT and overlapdial is set and if 10298 * the number is empty, we wait for the ISDN timeout 10299 * instead of our own timer. 10300 */ 10301 if (ch->overlap_dial && bc->nt && !bc->dialed.number[0]) { 10302 wait_for_digits(ch, bc, chan); 10303 break; 10304 } 10305 10306 /* 10307 * If overlapdial we will definitely send a SETUP_ACKNOWLEDGE and wait for more 10308 * Infos with a Interdigit Timeout. 10309 * */ 10310 if (ch->overlap_dial) { 10311 ast_mutex_lock(&ch->overlap_tv_lock); 10312 ch->overlap_tv = ast_tvnow(); 10313 ast_mutex_unlock(&ch->overlap_tv_lock); 10314 10315 wait_for_digits(ch, bc, chan); 10316 if (ch->overlap_dial_task == -1) { 10317 ch->overlap_dial_task = 10318 misdn_tasks_add_variable(ch->overlap_dial, misdn_overlap_dial_task, ch); 10319 } 10320 break; 10321 } 10322 10323 /* If the extension does not exist and we're not TE_PTMP we wait for more digits 10324 * without interdigit timeout. 10325 * */ 10326 if (!ast_exists_extension(ch->ast, ch->context, bc->dialed.number, 1, bc->caller.number)) { 10327 wait_for_digits(ch, bc, chan); 10328 break; 10329 } 10330 10331 /* 10332 * If the extension exists let's just jump into it. 10333 * */ 10334 if (ast_exists_extension(ch->ast, ch->context, bc->dialed.number, 1, bc->caller.number)) { 10335 misdn_lib_send_event(bc, bc->need_more_infos ? EVENT_SETUP_ACKNOWLEDGE : EVENT_PROCEEDING); 10336 ch->state = MISDN_DIALING; 10337 start_pbx(ch, bc, chan); 10338 break; 10339 } 10340 break; 10341 } 10342 #if defined(AST_MISDN_ENHANCEMENTS) 10343 case EVENT_REGISTER: 10344 if (bc->fac_in.Function != Fac_None) { 10345 misdn_facility_ie_handler(event, bc, ch); 10346 } 10347 /* 10348 * Shut down this connection immediately. 10349 * The current design of chan_misdn data structures 10350 * does not allow the proper handling of inbound call records 10351 * without an assigned B channel. Therefore, we cannot 10352 * be the CCBS User-B party in a point-to-point setup. 10353 */ 10354 bc->fac_out.Function = Fac_None; 10355 bc->out_cause = AST_CAUSE_NORMAL_CLEARING; 10356 misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE); 10357 break; 10358 #endif /* defined(AST_MISDN_ENHANCEMENTS) */ 10359 case EVENT_SETUP_ACKNOWLEDGE: 10360 ch->state = MISDN_CALLING_ACKNOWLEDGE; 10361 10362 if (bc->channel) { 10363 update_name(ch->ast,bc->port,bc->channel); 10364 } 10365 10366 if (bc->fac_in.Function != Fac_None) { 10367 misdn_facility_ie_handler(event, bc, ch); 10368 } 10369 10370 if (!ast_strlen_zero(bc->infos_pending)) { 10371 /* TX Pending Infos */ 10372 strncat(bc->dialed.number, bc->infos_pending, sizeof(bc->dialed.number) - strlen(bc->dialed.number) - 1); 10373 10374 if (!ch->ast) { 10375 break; 10376 } 10377 ast_copy_string(ch->ast->exten, bc->dialed.number, sizeof(ch->ast->exten)); 10378 ast_copy_string(bc->info_dad, bc->infos_pending, sizeof(bc->info_dad)); 10379 ast_copy_string(bc->infos_pending, "", sizeof(bc->infos_pending)); 10380 10381 misdn_lib_send_event(bc, EVENT_INFORMATION); 10382 } 10383 break; 10384 case EVENT_PROCEEDING: 10385 if (misdn_cap_is_speech(bc->capability) && 10386 misdn_inband_avail(bc)) { 10387 start_bc_tones(ch); 10388 } 10389 10390 ch->state = MISDN_PROCEEDING; 10391 10392 if (bc->fac_in.Function != Fac_None) { 10393 misdn_facility_ie_handler(event, bc, ch); 10394 } 10395 10396 if (!ch->ast) { 10397 break; 10398 } 10399 10400 ast_queue_control(ch->ast, AST_CONTROL_PROCEEDING); 10401 break; 10402 case EVENT_PROGRESS: 10403 if (bc->channel) { 10404 update_name(ch->ast, bc->port, bc->channel); 10405 } 10406 10407 if (bc->fac_in.Function != Fac_None) { 10408 misdn_facility_ie_handler(event, bc, ch); 10409 } 10410 10411 if (!bc->nt) { 10412 if (misdn_cap_is_speech(bc->capability) && 10413 misdn_inband_avail(bc)) { 10414 start_bc_tones(ch); 10415 } 10416 10417 ch->state = MISDN_PROGRESS; 10418 10419 if (!ch->ast) { 10420 break; 10421 } 10422 ast_queue_control(ch->ast, AST_CONTROL_PROGRESS); 10423 } 10424 break; 10425 case EVENT_ALERTING: 10426 ch->state = MISDN_ALERTING; 10427 10428 if (!ch->ast) { 10429 break; 10430 } 10431 10432 if (bc->fac_in.Function != Fac_None) { 10433 misdn_facility_ie_handler(event, bc, ch); 10434 } 10435 10436 ast_queue_control(ch->ast, AST_CONTROL_RINGING); 10437 ast_setstate(ch->ast, AST_STATE_RINGING); 10438 10439 cb_log(7, bc->port, " --> Set State Ringing\n"); 10440 10441 if (misdn_cap_is_speech(bc->capability) && misdn_inband_avail(bc)) { 10442 cb_log(1, bc->port, "Starting Tones, we have inband Data\n"); 10443 start_bc_tones(ch); 10444 } else { 10445 cb_log(3, bc->port, " --> We have no inband Data, the other end must create ringing\n"); 10446 if (ch->far_alerting) { 10447 cb_log(1, bc->port, " --> The other end can not do ringing eh ?.. we must do all ourself.."); 10448 start_bc_tones(ch); 10449 /*tone_indicate(ch, TONE_FAR_ALERTING);*/ 10450 } 10451 } 10452 break; 10453 case EVENT_CONNECT: 10454 if (bc->fac_in.Function != Fac_None) { 10455 misdn_facility_ie_handler(event, bc, ch); 10456 } 10457 #if defined(AST_MISDN_ENHANCEMENTS) 10458 if (bc->div_leg_3_rx_wanted) { 10459 bc->div_leg_3_rx_wanted = 0; 10460 10461 if (ch->ast) { 10462 ch->ast->redirecting.to.number.presentation = 10463 AST_PRES_RESTRICTED | AST_PRES_USER_NUMBER_UNSCREENED; 10464 ast_channel_queue_redirecting_update(ch->ast, &ch->ast->redirecting, NULL); 10465 } 10466 } 10467 #endif /* defined(AST_MISDN_ENHANCEMENTS) */ 10468 10469 /* we answer when we've got our very new L3 ID from the NT stack */ 10470 misdn_lib_send_event(bc, EVENT_CONNECT_ACKNOWLEDGE); 10471 10472 if (!ch->ast) { 10473 break; 10474 } 10475 10476 stop_indicate(ch); 10477 10478 #if defined(AST_MISDN_ENHANCEMENTS) 10479 if (ch->record_id != -1) { 10480 /* 10481 * We will delete the associated call completion 10482 * record since we now have a completed call. 10483 * We will not wait/depend on the network to tell 10484 * us to delete it. 10485 */ 10486 AST_LIST_LOCK(&misdn_cc_records_db); 10487 cc_record = misdn_cc_find_by_id(ch->record_id); 10488 if (cc_record) { 10489 if (cc_record->ptp && cc_record->mode.ptp.bc) { 10490 /* Close the call-completion signaling link */ 10491 cc_record->mode.ptp.bc->fac_out.Function = Fac_None; 10492 cc_record->mode.ptp.bc->out_cause = AST_CAUSE_NORMAL_CLEARING; 10493 misdn_lib_send_event(cc_record->mode.ptp.bc, EVENT_RELEASE_COMPLETE); 10494 } 10495 misdn_cc_delete(cc_record); 10496 } 10497 AST_LIST_UNLOCK(&misdn_cc_records_db); 10498 ch->record_id = -1; 10499 if (ch->peer) { 10500 misdn_cc_set_peer_var(ch->peer, MISDN_CC_RECORD_ID, ""); 10501 10502 ao2_ref(ch->peer, -1); 10503 ch->peer = NULL; 10504 } 10505 } 10506 #endif /* defined(AST_MISDN_ENHANCEMENTS) */ 10507 10508 if (!ast_strlen_zero(bc->connected.number)) { 10509 /* Add configured prefix to connected.number */ 10510 misdn_add_number_prefix(bc->port, bc->connected.number_type, bc->connected.number, sizeof(bc->connected.number)); 10511 10512 /* Update the connected line information on the other channel */ 10513 misdn_update_remote_party(ch->ast, &bc->connected, AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER, bc->incoming_cid_tag); 10514 } 10515 10516 ch->l3id = bc->l3_id; 10517 ch->addr = bc->addr; 10518 10519 start_bc_tones(ch); 10520 10521 ch->state = MISDN_CONNECTED; 10522 10523 ast_queue_control(ch->ast, AST_CONTROL_ANSWER); 10524 break; 10525 case EVENT_CONNECT_ACKNOWLEDGE: 10526 ch->l3id = bc->l3_id; 10527 ch->addr = bc->addr; 10528 10529 start_bc_tones(ch); 10530 10531 ch->state = MISDN_CONNECTED; 10532 break; 10533 case EVENT_DISCONNECT: 10534 /* we might not have an ch->ast ptr here anymore */ 10535 if (ch) { 10536 if (bc->fac_in.Function != Fac_None) { 10537 misdn_facility_ie_handler(event, bc, ch); 10538 } 10539 10540 chan_misdn_log(3, bc->port, " --> org:%d nt:%d, inbandavail:%d state:%d\n", ch->originator, bc->nt, misdn_inband_avail(bc), ch->state); 10541 if (ch->originator == ORG_AST && !bc->nt && misdn_inband_avail(bc) && ch->state != MISDN_CONNECTED) { 10542 /* If there's inband information available (e.g. a 10543 recorded message saying what was wrong with the 10544 dialled number, or perhaps even giving an 10545 alternative number, then play it instead of 10546 immediately releasing the call */ 10547 chan_misdn_log(1, bc->port, " --> Inband Info Avail, not sending RELEASE\n"); 10548 10549 ch->state = MISDN_DISCONNECTED; 10550 start_bc_tones(ch); 10551 10552 if (ch->ast) { 10553 ch->ast->hangupcause = bc->cause; 10554 if (bc->cause == AST_CAUSE_USER_BUSY) { 10555 ast_queue_control(ch->ast, AST_CONTROL_BUSY); 10556 } 10557 } 10558 ch->need_busy = 0; 10559 break; 10560 } 10561 10562 bc->need_disconnect = 0; 10563 stop_bc_tones(ch); 10564 10565 /* Check for held channel, to implement transfer */ 10566 held_ch = find_hold_call(bc); 10567 if (!held_ch || !ch->ast || misdn_attempt_transfer(ch, held_ch)) { 10568 hangup_chan(ch, bc); 10569 } 10570 } else { 10571 held_ch = find_hold_call_l3(bc->l3_id); 10572 if (held_ch) { 10573 if (bc->fac_in.Function != Fac_None) { 10574 misdn_facility_ie_handler(event, bc, held_ch); 10575 } 10576 10577 if (held_ch->hold.state == MISDN_HOLD_ACTIVE) { 10578 bc->need_disconnect = 0; 10579 10580 #if defined(TRANSFER_ON_HELD_CALL_HANGUP) 10581 /* 10582 * Some phones disconnect the held call and the active call at the 10583 * same time to do the transfer. Unfortunately, either call could 10584 * be disconnected first. 10585 */ 10586 ch = find_hold_active_call(bc); 10587 if (!ch || misdn_attempt_transfer(ch, held_ch)) { 10588 held_ch->hold.state = MISDN_HOLD_DISCONNECT; 10589 hangup_chan(held_ch, bc); 10590 } 10591 #else 10592 hangup_chan(held_ch, bc); 10593 #endif /* defined(TRANSFER_ON_HELD_CALL_HANGUP) */ 10594 } 10595 } 10596 } 10597 if (held_ch) { 10598 chan_list_unref(held_ch, "Done with held call"); 10599 } 10600 bc->out_cause = -1; 10601 if (bc->need_release) { 10602 misdn_lib_send_event(bc, EVENT_RELEASE); 10603 } 10604 break; 10605 case EVENT_RELEASE: 10606 if (!ch) { 10607 ch = find_hold_call_l3(bc->l3_id); 10608 if (!ch) { 10609 chan_misdn_log(1, bc->port, 10610 " --> no Ch, so we've already released. (%s)\n", 10611 manager_isdn_get_info(event)); 10612 return -1; 10613 } 10614 } 10615 if (bc->fac_in.Function != Fac_None) { 10616 misdn_facility_ie_handler(event, bc, ch); 10617 } 10618 10619 bc->need_disconnect = 0; 10620 bc->need_release = 0; 10621 10622 hangup_chan(ch, bc); 10623 release_chan(ch, bc); 10624 break; 10625 case EVENT_RELEASE_COMPLETE: 10626 if (!ch) { 10627 ch = find_hold_call_l3(bc->l3_id); 10628 } 10629 10630 bc->need_disconnect = 0; 10631 bc->need_release = 0; 10632 bc->need_release_complete = 0; 10633 10634 if (ch) { 10635 if (bc->fac_in.Function != Fac_None) { 10636 misdn_facility_ie_handler(event, bc, ch); 10637 } 10638 10639 stop_bc_tones(ch); 10640 hangup_chan(ch, bc); 10641 release_chan(ch, bc); 10642 } else { 10643 #if defined(AST_MISDN_ENHANCEMENTS) 10644 /* 10645 * A call-completion signaling link established with 10646 * REGISTER does not have a struct chan_list record 10647 * associated with it. 10648 */ 10649 AST_LIST_LOCK(&misdn_cc_records_db); 10650 cc_record = misdn_cc_find_by_bc(bc); 10651 if (cc_record) { 10652 /* The call-completion signaling link is closed. */ 10653 misdn_cc_delete(cc_record); 10654 } 10655 AST_LIST_UNLOCK(&misdn_cc_records_db); 10656 #endif /* defined(AST_MISDN_ENHANCEMENTS) */ 10657 10658 chan_misdn_log(1, bc->port, 10659 " --> no Ch, so we've already released. (%s)\n", 10660 manager_isdn_get_info(event)); 10661 } 10662 break; 10663 case EVENT_BCHAN_ERROR: 10664 case EVENT_CLEANUP: 10665 stop_bc_tones(ch); 10666 10667 switch (ch->state) { 10668 case MISDN_CALLING: 10669 bc->cause = AST_CAUSE_DESTINATION_OUT_OF_ORDER; 10670 break; 10671 default: 10672 break; 10673 } 10674 10675 hangup_chan(ch, bc); 10676 release_chan(ch, bc); 10677 break; 10678 case EVENT_TONE_GENERATE: 10679 { 10680 int tone_len = bc->tone_cnt; 10681 struct ast_channel *ast = ch->ast; 10682 void *tmp; 10683 int res; 10684 int (*generate)(struct ast_channel *chan, void *tmp, int datalen, int samples); 10685 10686 chan_misdn_log(9, bc->port, "TONE_GEN: len:%d\n", tone_len); 10687 10688 if (!ast) { 10689 break; 10690 } 10691 10692 if (!ast->generator) { 10693 break; 10694 } 10695 10696 tmp = ast->generatordata; 10697 ast->generatordata = NULL; 10698 generate = ast->generator->generate; 10699 10700 if (tone_len < 0 || tone_len > 512) { 10701 ast_log(LOG_NOTICE, "TONE_GEN: len was %d, set to 128\n", tone_len); 10702 tone_len = 128; 10703 } 10704 10705 res = generate(ast, tmp, tone_len, tone_len); 10706 ast->generatordata = tmp; 10707 10708 if (res) { 10709 ast_log(LOG_WARNING, "Auto-deactivating generator\n"); 10710 ast_deactivate_generator(ast); 10711 } else { 10712 bc->tone_cnt = 0; 10713 } 10714 break; 10715 } 10716 case EVENT_BCHAN_DATA: 10717 if (ch->bc->AOCD_need_export) { 10718 export_aoc_vars(ch->originator, ch->ast, ch->bc); 10719 } 10720 if (!misdn_cap_is_speech(ch->bc->capability)) { 10721 struct ast_frame frame; 10722 10723 /* In Data Modes we queue frames */ 10724 memset(&frame, 0, sizeof(frame)); 10725 frame.frametype = AST_FRAME_VOICE; /* we have no data frames yet */ 10726 frame.subclass.codec = AST_FORMAT_ALAW; 10727 frame.datalen = bc->bframe_len; 10728 frame.samples = bc->bframe_len; 10729 frame.mallocd = 0; 10730 frame.offset = 0; 10731 frame.delivery = ast_tv(0, 0); 10732 frame.src = NULL; 10733 frame.data.ptr = bc->bframe; 10734 10735 if (ch->ast) { 10736 ast_queue_frame(ch->ast, &frame); 10737 } 10738 } else { 10739 struct pollfd pfd = { .fd = ch->pipe[1], .events = POLLOUT }; 10740 int t; 10741 10742 t = ast_poll(&pfd, 1, 0); 10743 10744 if (t < 0) { 10745 chan_misdn_log(-1, bc->port, "poll() error (err=%s)\n", strerror(errno)); 10746 break; 10747 } 10748 if (!t) { 10749 chan_misdn_log(9, bc->port, "poll() timed out\n"); 10750 break; 10751 } 10752 10753 if (pfd.revents & POLLOUT) { 10754 chan_misdn_log(9, bc->port, "writing %d bytes to asterisk\n", bc->bframe_len); 10755 if (write(ch->pipe[1], bc->bframe, bc->bframe_len) <= 0) { 10756 chan_misdn_log(0, bc->port, "Write returned <=0 (err=%s) --> hanging up channel\n", strerror(errno)); 10757 10758 stop_bc_tones(ch); 10759 hangup_chan(ch, bc); 10760 release_chan(ch, bc); 10761 } 10762 } else { 10763 chan_misdn_log(1, bc->port, "Write Pipe full!\n"); 10764 } 10765 } 10766 break; 10767 case EVENT_TIMEOUT: 10768 if (ch && bc) { 10769 chan_misdn_log(1, bc->port, "--> state: %s\n", misdn_get_ch_state(ch)); 10770 } 10771 10772 switch (ch->state) { 10773 case MISDN_DIALING: 10774 case MISDN_PROGRESS: 10775 if (bc->nt && !ch->nttimeout) { 10776 break; 10777 } 10778 /* fall-through */ 10779 case MISDN_CALLING: 10780 case MISDN_ALERTING: 10781 case MISDN_PROCEEDING: 10782 case MISDN_CALLING_ACKNOWLEDGE: 10783 if (bc->nt) { 10784 bc->progress_indicator = INFO_PI_INBAND_AVAILABLE; 10785 hanguptone_indicate(ch); 10786 } 10787 10788 bc->out_cause = AST_CAUSE_UNALLOCATED; 10789 misdn_lib_send_event(bc, EVENT_DISCONNECT); 10790 break; 10791 case MISDN_WAITING4DIGS: 10792 if (bc->nt) { 10793 bc->progress_indicator = INFO_PI_INBAND_AVAILABLE; 10794 bc->out_cause = AST_CAUSE_UNALLOCATED; 10795 hanguptone_indicate(ch); 10796 misdn_lib_send_event(bc, EVENT_DISCONNECT); 10797 } else { 10798 bc->out_cause = AST_CAUSE_NORMAL_CLEARING; 10799 misdn_lib_send_event(bc, EVENT_RELEASE); 10800 } 10801 break; 10802 case MISDN_CLEANING: 10803 chan_misdn_log(1, bc->port, " --> in state cleaning .. so ignoring, the stack should clean it for us\n"); 10804 break; 10805 default: 10806 misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE); 10807 break; 10808 } 10809 break; 10810 10811 /****************************/ 10812 /** Supplementary Services **/ 10813 /****************************/ 10814 case EVENT_RETRIEVE: 10815 if (!ch) { 10816 chan_misdn_log(4, bc->port, " --> no CH, searching for held call\n"); 10817 ch = find_hold_call_l3(bc->l3_id); 10818 if (!ch || ch->hold.state != MISDN_HOLD_ACTIVE) { 10819 ast_log(LOG_WARNING, "No held call found, cannot Retrieve\n"); 10820 misdn_lib_send_event(bc, EVENT_RETRIEVE_REJECT); 10821 break; 10822 } 10823 } 10824 10825 /* remember the channel again */ 10826 ch->bc = bc; 10827 10828 ch->hold.state = MISDN_HOLD_IDLE; 10829 ch->hold.port = 0; 10830 ch->hold.channel = 0; 10831 10832 ast_queue_control(ch->ast, AST_CONTROL_UNHOLD); 10833 10834 if (misdn_lib_send_event(bc, EVENT_RETRIEVE_ACKNOWLEDGE) < 0) { 10835 chan_misdn_log(4, bc->port, " --> RETRIEVE_ACK failed\n"); 10836 misdn_lib_send_event(bc, EVENT_RETRIEVE_REJECT); 10837 } 10838 break; 10839 case EVENT_HOLD: 10840 { 10841 int hold_allowed; 10842 struct ast_channel *bridged; 10843 10844 misdn_cfg_get(bc->port, MISDN_CFG_HOLD_ALLOWED, &hold_allowed, sizeof(hold_allowed)); 10845 if (!hold_allowed) { 10846 chan_misdn_log(-1, bc->port, "Hold not allowed this port.\n"); 10847 misdn_lib_send_event(bc, EVENT_HOLD_REJECT); 10848 break; 10849 } 10850 10851 bridged = ast_bridged_channel(ch->ast); 10852 if (bridged) { 10853 chan_misdn_log(2, bc->port, "Bridge Partner is of type: %s\n", bridged->tech->type); 10854 ch->l3id = bc->l3_id; 10855 10856 /* forget the channel now */ 10857 ch->bc = NULL; 10858 ch->hold.state = MISDN_HOLD_ACTIVE; 10859 ch->hold.port = bc->port; 10860 ch->hold.channel = bc->channel; 10861 10862 ast_queue_control(ch->ast, AST_CONTROL_HOLD); 10863 10864 misdn_lib_send_event(bc, EVENT_HOLD_ACKNOWLEDGE); 10865 } else { 10866 misdn_lib_send_event(bc, EVENT_HOLD_REJECT); 10867 chan_misdn_log(0, bc->port, "We aren't bridged to anybody\n"); 10868 } 10869 break; 10870 } 10871 case EVENT_NOTIFY: 10872 if (bc->redirecting.to_changed) { 10873 /* Add configured prefix to redirecting.to.number */ 10874 misdn_add_number_prefix(bc->port, bc->redirecting.to.number_type, 10875 bc->redirecting.to.number, sizeof(bc->redirecting.to.number)); 10876 } 10877 switch (bc->notify_description_code) { 10878 case mISDN_NOTIFY_CODE_DIVERSION_ACTIVATED: 10879 /* Ignore for now. */ 10880 bc->redirecting.to_changed = 0; 10881 break; 10882 case mISDN_NOTIFY_CODE_CALL_IS_DIVERTING: 10883 if (!bc->redirecting.to_changed) { 10884 break; 10885 } 10886 bc->redirecting.to_changed = 0; 10887 if (!ch || !ch->ast) { 10888 break; 10889 } 10890 switch (ch->state) { 10891 case MISDN_ALERTING: 10892 /* Call is deflecting after we have seen an ALERTING message */ 10893 bc->redirecting.reason = mISDN_REDIRECTING_REASON_NO_REPLY; 10894 break; 10895 default: 10896 /* Call is deflecting for call forwarding unconditional or busy reason. */ 10897 bc->redirecting.reason = mISDN_REDIRECTING_REASON_UNKNOWN; 10898 break; 10899 } 10900 misdn_copy_redirecting_to_ast(ch->ast, &bc->redirecting, bc->incoming_cid_tag); 10901 ast_channel_queue_redirecting_update(ch->ast, &ch->ast->redirecting, NULL); 10902 break; 10903 case mISDN_NOTIFY_CODE_CALL_TRANSFER_ALERTING: 10904 /* 10905 * It would be preferable to update the connected line information 10906 * only when the message callStatus is active. However, the 10907 * optional redirection number may not be present in the active 10908 * message if an alerting message were received earlier. 10909 * 10910 * The consequences if we wind up sending two updates is benign. 10911 * The other end will think that it got transferred twice. 10912 */ 10913 if (!bc->redirecting.to_changed) { 10914 break; 10915 } 10916 bc->redirecting.to_changed = 0; 10917 if (!ch || !ch->ast) { 10918 break; 10919 } 10920 misdn_update_remote_party(ch->ast, &bc->redirecting.to, 10921 AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER_ALERTING, 10922 bc->incoming_cid_tag); 10923 break; 10924 case mISDN_NOTIFY_CODE_CALL_TRANSFER_ACTIVE: 10925 if (!bc->redirecting.to_changed) { 10926 break; 10927 } 10928 bc->redirecting.to_changed = 0; 10929 if (!ch || !ch->ast) { 10930 break; 10931 } 10932 misdn_update_remote_party(ch->ast, &bc->redirecting.to, 10933 AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER, bc->incoming_cid_tag); 10934 break; 10935 default: 10936 bc->redirecting.to_changed = 0; 10937 chan_misdn_log(0, bc->port," --> not yet handled: notify code:0x%02X\n", 10938 bc->notify_description_code); 10939 break; 10940 } 10941 bc->notify_description_code = mISDN_NOTIFY_CODE_INVALID; 10942 break; 10943 case EVENT_FACILITY: 10944 if (bc->fac_in.Function == Fac_None) { 10945 /* This is a FACILITY message so we MUST have a facility ie */ 10946 chan_misdn_log(0, bc->port," --> Missing facility ie or unknown facility ie contents.\n"); 10947 } else { 10948 misdn_facility_ie_handler(event, bc, ch); 10949 } 10950 10951 /* In case it came in on a FACILITY message and we did not handle it. */ 10952 bc->redirecting.to_changed = 0; 10953 bc->notify_description_code = mISDN_NOTIFY_CODE_INVALID; 10954 break; 10955 case EVENT_RESTART: 10956 if (!bc->dummy) { 10957 stop_bc_tones(ch); 10958 release_chan(ch, bc); 10959 } 10960 break; 10961 default: 10962 chan_misdn_log(1, 0, "Got Unknown Event\n"); 10963 break; 10964 } 10965 10966 if (ch) { 10967 chan_list_unref(ch, "cb_event complete OK"); 10968 } 10969 return RESPONSE_OK; 10970 }
static void chan_list_destructor | ( | void * | obj | ) | [static] |
Definition at line 7696 of file chan_misdn.c.
References ao2_ref, ast_dsp_free(), ast_mutex_destroy, chan_list::dsp, chan_list::jb, misdn_jb_destroy(), misdn_tasks_remove(), chan_list::overlap_dial, chan_list::overlap_dial_task, chan_list::overlap_tv_lock, and chan_list::pipe.
Referenced by chan_list_init().
07697 { 07698 struct chan_list *ch = obj; 07699 07700 #if defined(AST_MISDN_ENHANCEMENTS) 07701 if (ch->peer) { 07702 ao2_ref(ch->peer, -1); 07703 ch->peer = NULL; 07704 } 07705 #endif /* AST_MISDN_ENHANCEMENTS */ 07706 07707 if (ch->dsp) { 07708 ast_dsp_free(ch->dsp); 07709 ch->dsp = NULL; 07710 } 07711 07712 /* releasing jitterbuffer */ 07713 if (ch->jb) { 07714 misdn_jb_destroy(ch->jb); 07715 ch->jb = NULL; 07716 } 07717 07718 if (ch->overlap_dial) { 07719 if (ch->overlap_dial_task != -1) { 07720 misdn_tasks_remove(ch->overlap_dial_task); 07721 ch->overlap_dial_task = -1; 07722 } 07723 ast_mutex_destroy(&ch->overlap_tv_lock); 07724 } 07725 07726 if (-1 < ch->pipe[0]) { 07727 close(ch->pipe[0]); 07728 } 07729 if (-1 < ch->pipe[1]) { 07730 close(ch->pipe[1]); 07731 } 07732 }
static struct chan_list* chan_list_init | ( | int | orig | ) | [static] |
Returns a reference to the new chan_list.
Definition at line 7735 of file chan_misdn.c.
References ao2_alloc, chan_list_destructor(), and chan_misdn_log().
Referenced by cb_events(), and misdn_request().
07736 { 07737 struct chan_list *cl; 07738 07739 cl = ao2_alloc(sizeof(*cl), chan_list_destructor); 07740 if (!cl) { 07741 chan_misdn_log(-1, 0, "misdn_request: malloc failed!"); 07742 return NULL; 07743 } 07744 07745 cl->originator = orig; 07746 cl->need_queue_hangup = 1; 07747 cl->need_hangup = 1; 07748 cl->need_busy = 1; 07749 cl->overlap_dial_task = -1; 07750 #if defined(AST_MISDN_ENHANCEMENTS) 07751 cl->record_id = -1; 07752 #endif /* defined(AST_MISDN_ENHANCEMENTS) */ 07753 cl->pipe[0] = -1; 07754 cl->pipe[1] = -1; 07755 07756 return cl; 07757 }
int chan_misdn_jb_empty | ( | struct misdn_bchannel * | bc, | |
char * | buf, | |||
int | len | |||
) |
Definition at line 12405 of file chan_misdn.c.
References chan_list::bc, chan_list_unref, find_chan_by_bc(), chan_list::jb, and misdn_jb_empty().
Referenced by load_module().
12406 { 12407 struct chan_list *ch; 12408 int res; 12409 12410 ch = find_chan_by_bc(bc); 12411 if (!ch) { 12412 return 0; 12413 } 12414 12415 if (ch->jb) { 12416 res = misdn_jb_empty(ch->jb, buf, len); 12417 } else { 12418 res = 0; 12419 } 12420 chan_list_unref(ch, "Done emptying jb"); 12421 12422 return res; 12423 }
static void chan_misdn_log | ( | int | level, | |
int | port, | |||
char * | tmpl, | |||
... | ||||
) | [static] |
Definition at line 12604 of file chan_misdn.c.
References ast_console_puts(), ast_log(), ast_strlen_zero(), errno, LOG_WARNING, max_ports, misdn_debug, and misdn_debug_only.
Referenced by cb_events(), chan_list_init(), cl_queue_chan(), config_jitterbuffer(), debug_numtype(), dialtone_indicate(), do_immediate_setup(), export_ch(), find_hold_call(), load_module(), misdn_answer(), misdn_attempt_transfer(), misdn_bridge(), misdn_call(), misdn_check_l2l1(), misdn_digit_end(), misdn_facility_exec(), misdn_facility_ie_handler(), misdn_fixup(), misdn_hangup(), misdn_indication(), misdn_jb_empty(), misdn_jb_init(), misdn_l1_task(), misdn_new(), misdn_overlap_dial_task(), misdn_read(), misdn_request(), misdn_set_opt_exec(), misdn_tasks_destroy(), misdn_tasks_init(), misdn_tasks_thread_func(), misdn_write(), print_bearer(), print_facility(), process_ast_dsp(), read_config(), release_chan(), send_cause2ast(), start_pbx(), stop_indicate(), update_config(), and update_name().
12605 { 12606 va_list ap; 12607 char buf[1024]; 12608 char port_buf[8]; 12609 12610 if (!(0 <= port && port <= max_ports)) { 12611 ast_log(LOG_WARNING, "cb_log called with out-of-range port number! (%d)\n", port); 12612 port = 0; 12613 level = -1; 12614 } else if (!(level == -1 12615 || (misdn_debug_only[port] 12616 ? (level == 1 && misdn_debug[port]) || level == misdn_debug[port] 12617 : level <= misdn_debug[port]) 12618 || (level <= misdn_debug[0] && !ast_strlen_zero(global_tracefile)))) { 12619 /* 12620 * We are not going to print anything so lets not 12621 * go to all the work of generating a string. 12622 */ 12623 return; 12624 } 12625 12626 snprintf(port_buf, sizeof(port_buf), "P[%2d] ", port); 12627 va_start(ap, tmpl); 12628 vsnprintf(buf, sizeof(buf), tmpl, ap); 12629 va_end(ap); 12630 12631 if (level == -1) { 12632 ast_log(LOG_WARNING, "%s", buf); 12633 } else if (misdn_debug_only[port] 12634 ? (level == 1 && misdn_debug[port]) || level == misdn_debug[port] 12635 : level <= misdn_debug[port]) { 12636 ast_console_puts(port_buf); 12637 ast_console_puts(buf); 12638 } 12639 12640 if (level <= misdn_debug[0] && !ast_strlen_zero(global_tracefile)) { 12641 char ctimebuf[30]; 12642 time_t tm; 12643 char *tmp; 12644 char *p; 12645 FILE *fp; 12646 12647 fp = fopen(global_tracefile, "a+"); 12648 if (!fp) { 12649 ast_console_puts("Error opening Tracefile: [ "); 12650 ast_console_puts(global_tracefile); 12651 ast_console_puts(" ] "); 12652 12653 ast_console_puts(strerror(errno)); 12654 ast_console_puts("\n"); 12655 return; 12656 } 12657 12658 tm = time(NULL); 12659 tmp = ctime_r(&tm, ctimebuf); 12660 p = strchr(tmp, '\n'); 12661 if (p) { 12662 *p = ':'; 12663 } 12664 fputs(tmp, fp); 12665 fputs(" ", fp); 12666 fputs(port_buf, fp); 12667 fputs(" ", fp); 12668 fputs(buf, fp); 12669 12670 fclose(fp); 12671 } 12672 }
static int cl_dequeue_chan | ( | struct chan_list * | chan | ) | [static] |
Definition at line 8303 of file chan_misdn.c.
References ast_mutex_lock, ast_mutex_unlock, chan_list_unref, cl_te, cl_te_lock, and chan_list::next.
Referenced by release_chan(), and release_chan_early().
08304 { 08305 int found_it; 08306 struct chan_list *help; 08307 08308 ast_mutex_lock(&cl_te_lock); 08309 if (!cl_te) { 08310 /* List is empty. */ 08311 ast_mutex_unlock(&cl_te_lock); 08312 return 0; 08313 } 08314 08315 if (cl_te == chan) { 08316 /* What we want is the head of the list. */ 08317 cl_te = cl_te->next; 08318 ast_mutex_unlock(&cl_te_lock); 08319 chan_list_unref(chan, "Removed chan_list from list head"); 08320 return 1; 08321 } 08322 08323 found_it = 0; 08324 for (help = cl_te; help->next; help = help->next) { 08325 if (help->next == chan) { 08326 /* Found it in the list. */ 08327 help->next = help->next->next; 08328 found_it = 1; 08329 break; 08330 } 08331 } 08332 08333 ast_mutex_unlock(&cl_te_lock); 08334 if (found_it) { 08335 chan_list_unref(chan, "Removed chan_list from list"); 08336 } 08337 return found_it; 08338 }
static void cl_queue_chan | ( | struct chan_list * | chan | ) | [static] |
Definition at line 8282 of file chan_misdn.c.
References ast_mutex_lock, ast_mutex_unlock, chan_list::bc, chan_list_ref, chan_misdn_log(), cl_te, cl_te_lock, chan_list::next, and misdn_bchannel::port.
Referenced by cb_events(), and misdn_request().
08283 { 08284 chan_misdn_log(4, chan->bc ? chan->bc->port : 0, "* Queuing chan %p\n", chan); 08285 08286 chan_list_ref(chan, "Adding chan_list to list"); 08287 ast_mutex_lock(&cl_te_lock); 08288 chan->next = NULL; 08289 if (!cl_te) { 08290 /* List is empty, make head of list. */ 08291 cl_te = chan; 08292 } else { 08293 struct chan_list *help; 08294 08295 /* Put at end of list. */ 08296 for (help = cl_te; help->next; help = help->next) { 08297 } 08298 help->next = chan; 08299 } 08300 ast_mutex_unlock(&cl_te_lock); 08301 }
static char * complete_ch | ( | struct ast_cli_args * | a | ) | [static] |
Definition at line 5622 of file chan_misdn.c.
References ast_complete_channels(), ast_cli_args::line, ast_cli_args::n, ast_cli_args::pos, and ast_cli_args::word.
Referenced by handle_cli_misdn_send_digit(), handle_cli_misdn_send_display(), handle_cli_misdn_send_facility(), handle_cli_misdn_show_channel(), and handle_cli_misdn_toggle_echocancel().
05623 { 05624 return ast_complete_channels(a->line, a->word, a->pos, a->n, 3); 05625 }
static char * complete_debug_port | ( | struct ast_cli_args * | a | ) | [static] |
Definition at line 5627 of file chan_misdn.c.
References ast_strdup, ast_cli_args::n, ast_cli_args::pos, and ast_cli_args::word.
Referenced by handle_cli_misdn_set_debug().
05628 { 05629 if (a->n) { 05630 return NULL; 05631 } 05632 05633 switch (a->pos) { 05634 case 4: 05635 if (a->word[0] == 'p') { 05636 return ast_strdup("port"); 05637 } else if (a->word[0] == 'o') { 05638 return ast_strdup("only"); 05639 } 05640 break; 05641 case 6: 05642 if (a->word[0] == 'o') { 05643 return ast_strdup("only"); 05644 } 05645 break; 05646 } 05647 return NULL; 05648 }
static char * complete_show_config | ( | struct ast_cli_args * | a | ) | [static] |
Definition at line 5650 of file chan_misdn.c.
References ast_strdup, BUFFERSIZE, ast_cli_args::line, MISDN_CFG_FIRST, misdn_cfg_get_name(), misdn_cfg_get_next_port(), MISDN_GEN_FIRST, ast_cli_args::n, ast_cli_args::pos, and ast_cli_args::word.
Referenced by handle_cli_misdn_show_config().
05651 { 05652 char buffer[BUFFERSIZE]; 05653 enum misdn_cfg_elements elem; 05654 int wordlen = strlen(a->word); 05655 int which = 0; 05656 int port = 0; 05657 05658 switch (a->pos) { 05659 case 3: 05660 if ((!strncmp(a->word, "description", wordlen)) && (++which > a->n)) { 05661 return ast_strdup("description"); 05662 } 05663 if ((!strncmp(a->word, "descriptions", wordlen)) && (++which > a->n)) { 05664 return ast_strdup("descriptions"); 05665 } 05666 if ((!strncmp(a->word, "0", wordlen)) && (++which > a->n)) { 05667 return ast_strdup("0"); 05668 } 05669 while ((port = misdn_cfg_get_next_port(port)) != -1) { 05670 snprintf(buffer, sizeof(buffer), "%d", port); 05671 if ((!strncmp(a->word, buffer, wordlen)) && (++which > a->n)) { 05672 return ast_strdup(buffer); 05673 } 05674 } 05675 break; 05676 case 4: 05677 if (strstr(a->line, "description ")) { 05678 for (elem = MISDN_CFG_FIRST + 1; elem < MISDN_GEN_LAST; ++elem) { 05679 if ((elem == MISDN_CFG_LAST) || (elem == MISDN_GEN_FIRST)) { 05680 continue; 05681 } 05682 misdn_cfg_get_name(elem, buffer, sizeof(buffer)); 05683 if (!wordlen || !strncmp(a->word, buffer, wordlen)) { 05684 if (++which > a->n) { 05685 return ast_strdup(buffer); 05686 } 05687 } 05688 } 05689 } else if (strstr(a->line, "descriptions ")) { 05690 if ((!wordlen || !strncmp(a->word, "general", wordlen)) && (++which > a->n)) { 05691 return ast_strdup("general"); 05692 } 05693 if ((!wordlen || !strncmp(a->word, "ports", wordlen)) && (++which > a->n)) { 05694 return ast_strdup("ports"); 05695 } 05696 } 05697 break; 05698 } 05699 return NULL; 05700 }
static void config_jitterbuffer | ( | struct chan_list * | ch | ) | [static] |
Definition at line 5785 of file chan_misdn.c.
References chan_list::bc, cb_log, chan_misdn_log(), chan_list::jb, chan_list::jb_len, chan_list::jb_upper_threshold, len(), misdn_jb_destroy(), misdn_jb_init(), misdn_bchannel::nojitter, and misdn_bchannel::port.
Referenced by misdn_set_opt_exec(), and read_config().
05786 { 05787 struct misdn_bchannel *bc = ch->bc; 05788 int len = ch->jb_len; 05789 int threshold = ch->jb_upper_threshold; 05790 05791 chan_misdn_log(5, bc->port, "config_jb: Called\n"); 05792 05793 if (!len) { 05794 chan_misdn_log(1, bc->port, "config_jb: Deactivating Jitterbuffer\n"); 05795 bc->nojitter = 1; 05796 } else { 05797 if (len <= 100 || len > 8000) { 05798 chan_misdn_log(0, bc->port, "config_jb: Jitterbuffer out of Bounds, setting to 1000\n"); 05799 len = 1000; 05800 } 05801 05802 if (threshold > len) { 05803 chan_misdn_log(0, bc->port, "config_jb: Jitterbuffer Threshold > Jitterbuffer setting to Jitterbuffer -1\n"); 05804 } 05805 05806 if (ch->jb) { 05807 cb_log(0, bc->port, "config_jb: We've got a Jitterbuffer Already on this port.\n"); 05808 misdn_jb_destroy(ch->jb); 05809 ch->jb = NULL; 05810 } 05811 05812 ch->jb = misdn_jb_init(len, threshold); 05813 05814 if (!ch->jb) { 05815 bc->nojitter = 1; 05816 } 05817 } 05818 }
void debug_numtype | ( | int | port, | |
int | numtype, | |||
char * | type | |||
) |
Definition at line 5821 of file chan_misdn.c.
References chan_misdn_log(), NUMTYPE_ABBREVIATED, NUMTYPE_INTERNATIONAL, NUMTYPE_NATIONAL, NUMTYPE_NETWORK_SPECIFIC, NUMTYPE_SUBSCRIBER, and NUMTYPE_UNKNOWN.
Referenced by misdn_call(), misdn_get_connected_line(), and read_config().
05822 { 05823 switch (numtype) { 05824 case NUMTYPE_UNKNOWN: 05825 chan_misdn_log(2, port, " --> %s: Unknown\n", type); 05826 break; 05827 case NUMTYPE_INTERNATIONAL: 05828 chan_misdn_log(2, port, " --> %s: International\n", type); 05829 break; 05830 case NUMTYPE_NATIONAL: 05831 chan_misdn_log(2, port, " --> %s: National\n", type); 05832 break; 05833 case NUMTYPE_NETWORK_SPECIFIC: 05834 chan_misdn_log(2, port, " --> %s: Network Specific\n", type); 05835 break; 05836 case NUMTYPE_SUBSCRIBER: 05837 chan_misdn_log(2, port, " --> %s: Subscriber\n", type); 05838 break; 05839 case NUMTYPE_ABBREVIATED: 05840 chan_misdn_log(2, port, " --> %s: Abbreviated\n", type); 05841 break; 05842 /* Maybe we should cut off the prefix if present ? */ 05843 default: 05844 chan_misdn_log(0, port, " --> !!!! Wrong dialplan setting, please see the misdn.conf sample file\n "); 05845 break; 05846 } 05847 }
static int dialtone_indicate | ( | struct chan_list * | cl | ) | [static] |
AST INDICATIONS END
Definition at line 7611 of file chan_misdn.c.
References chan_list::ast, ast_get_indication_tone(), ast_playtones_start(), chan_list::bc, chan_misdn_log(), ast_tone_zone_sound::data, misdn_cfg_get(), MISDN_CFG_NODIALTONE, chan_list::norxtone, chan_list::notxtone, misdn_bchannel::port, chan_list::ts, and ast_channel::zone.
Referenced by wait_for_digits().
07612 { 07613 struct ast_channel *ast = cl->ast; 07614 int nd = 0; 07615 07616 if (!ast) { 07617 chan_misdn_log(0, cl->bc->port, "No Ast in dialtone_indicate\n"); 07618 return -1; 07619 } 07620 07621 misdn_cfg_get(cl->bc->port, MISDN_CFG_NODIALTONE, &nd, sizeof(nd)); 07622 07623 if (nd) { 07624 chan_misdn_log(1, cl->bc->port, "Not sending Dialtone, because config wants it\n"); 07625 return 0; 07626 } 07627 07628 chan_misdn_log(3, cl->bc->port, " --> Dial\n"); 07629 07630 cl->ts = ast_get_indication_tone(ast->zone, "dial"); 07631 07632 if (cl->ts) { 07633 cl->notxtone = 0; 07634 cl->norxtone = 0; 07635 /* This prods us in misdn_write */ 07636 ast_playtones_start(ast, 0, cl->ts->data, 0); 07637 } 07638 07639 return 0; 07640 }
static void do_immediate_setup | ( | struct misdn_bchannel * | bc, | |
struct chan_list * | ch, | |||
struct ast_channel * | ast | |||
) | [static] |
Definition at line 8595 of file chan_misdn.c.
References chan_list::ast, ast_canmatch_extension(), AST_CAUSE_UNALLOCATED, AST_FRAME_DTMF, ast_queue_frame(), ast_strdupa, ast_strlen_zero(), ast_tv(), misdn_bchannel::caller, ast_channel::caller, chan_misdn_log(), ast_channel::context, ast_frame::data, ast_frame::datalen, ast_frame::delivery, EVENT_DISCONNECT, EVENT_PROCEEDING, EVENT_RELEASE_COMPLETE, EVENT_SETUP_ACKNOWLEDGE, ast_channel::exten, ast_frame::frametype, hangup_chan(), hanguptone_indicate(), ast_party_caller::id, ast_frame_subclass::integer, ast_frame::mallocd, MISDN_ASTERISK_TECH_PVT, MISDN_DIALING, MISDN_INCOMING_SETUP, misdn_lib_is_ptp(), misdn_lib_send_event(), ast_party_id::name, chan_list::noautorespond_on_setup, misdn_bchannel::nt, misdn_party_id::number, ast_party_id::number, ast_frame::offset, misdn_bchannel::out_cause, pbx_start_chan(), misdn_bchannel::port, ast_frame::ptr, ast_frame::samples, ast_frame::src, chan_list::state, ast_party_number::str, ast_party_name::str, ast_frame::subclass, ast_party_number::valid, and ast_party_name::valid.
Referenced by cb_events().
08596 { 08597 char *predial; 08598 struct ast_frame fr; 08599 08600 predial = ast_strdupa(ast->exten); 08601 08602 ch->state = MISDN_DIALING; 08603 08604 if (!ch->noautorespond_on_setup) { 08605 if (bc->nt) { 08606 misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE); 08607 } else { 08608 if (misdn_lib_is_ptp(bc->port)) { 08609 misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE); 08610 } else { 08611 misdn_lib_send_event(bc, EVENT_PROCEEDING); 08612 } 08613 } 08614 } else { 08615 ch->state = MISDN_INCOMING_SETUP; 08616 } 08617 08618 chan_misdn_log(1, bc->port, 08619 "* Starting Ast context:%s dialed:%s caller:\"%s\" <%s> with 's' extension\n", 08620 ast->context, 08621 ast->exten, 08622 (ast->caller.id.name.valid && ast->caller.id.name.str) 08623 ? ast->caller.id.name.str : "", 08624 (ast->caller.id.number.valid && ast->caller.id.number.str) 08625 ? ast->caller.id.number.str : ""); 08626 08627 strcpy(ast->exten, "s"); 08628 08629 if (!ast_canmatch_extension(ast, ast->context, ast->exten, 1, bc->caller.number) || pbx_start_chan(ch) < 0) { 08630 ast = NULL; 08631 bc->out_cause = AST_CAUSE_UNALLOCATED; 08632 hangup_chan(ch, bc); 08633 hanguptone_indicate(ch); 08634 08635 misdn_lib_send_event(bc, bc->nt ? EVENT_RELEASE_COMPLETE : EVENT_DISCONNECT); 08636 } 08637 08638 08639 while (!ast_strlen_zero(predial)) { 08640 fr.frametype = AST_FRAME_DTMF; 08641 fr.subclass.integer = *predial; 08642 fr.src = NULL; 08643 fr.data.ptr = NULL; 08644 fr.datalen = 0; 08645 fr.samples = 0; 08646 fr.mallocd = 0; 08647 fr.offset = 0; 08648 fr.delivery = ast_tv(0,0); 08649 08650 if (ch->ast && MISDN_ASTERISK_TECH_PVT(ch->ast)) { 08651 ast_queue_frame(ch->ast, &fr); 08652 } 08653 predial++; 08654 } 08655 }
static void export_aoc_vars | ( | int | originator, | |
struct ast_channel * | ast, | |||
struct misdn_bchannel * | bc | |||
) | [static] |
Definition at line 3428 of file chan_misdn.c.
References misdn_bchannel::AOCD, misdn_bchannel::AOCD_need_export, misdn_bchannel::AOCDtype, ast_bridged_channel(), misdn_bchannel::chargingUnit, misdn_bchannel::currency, ORG_AST, and pbx_builtin_setvar_helper().
Referenced by cb_events(), and misdn_facility_ie_handler().
03429 { 03430 char buf[128]; 03431 03432 if (!bc->AOCD_need_export || !ast) { 03433 return; 03434 } 03435 03436 if (originator == ORG_AST) { 03437 ast = ast_bridged_channel(ast); 03438 if (!ast) { 03439 return; 03440 } 03441 } 03442 03443 switch (bc->AOCDtype) { 03444 case Fac_AOCDCurrency: 03445 pbx_builtin_setvar_helper(ast, "AOCD_Type", "currency"); 03446 if (bc->AOCD.currency.chargeNotAvailable) { 03447 pbx_builtin_setvar_helper(ast, "AOCD_ChargeAvailable", "no"); 03448 } else { 03449 pbx_builtin_setvar_helper(ast, "AOCD_ChargeAvailable", "yes"); 03450 if (bc->AOCD.currency.freeOfCharge) { 03451 pbx_builtin_setvar_helper(ast, "AOCD_FreeOfCharge", "yes"); 03452 } else { 03453 pbx_builtin_setvar_helper(ast, "AOCD_FreeOfCharge", "no"); 03454 if (snprintf(buf, sizeof(buf), "%d %s", bc->AOCD.currency.currencyAmount * bc->AOCD.currency.multiplier, bc->AOCD.currency.currency) < sizeof(buf)) { 03455 pbx_builtin_setvar_helper(ast, "AOCD_Amount", buf); 03456 if (bc->AOCD.currency.billingId >= 0 && snprintf(buf, sizeof(buf), "%d", bc->AOCD.currency.billingId) < sizeof(buf)) { 03457 pbx_builtin_setvar_helper(ast, "AOCD_BillingId", buf); 03458 } 03459 } 03460 } 03461 } 03462 break; 03463 case Fac_AOCDChargingUnit: 03464 pbx_builtin_setvar_helper(ast, "AOCD_Type", "charging_unit"); 03465 if (bc->AOCD.chargingUnit.chargeNotAvailable) { 03466 pbx_builtin_setvar_helper(ast, "AOCD_ChargeAvailable", "no"); 03467 } else { 03468 pbx_builtin_setvar_helper(ast, "AOCD_ChargeAvailable", "yes"); 03469 if (bc->AOCD.chargingUnit.freeOfCharge) { 03470 pbx_builtin_setvar_helper(ast, "AOCD_FreeOfCharge", "yes"); 03471 } else { 03472 pbx_builtin_setvar_helper(ast, "AOCD_FreeOfCharge", "no"); 03473 if (snprintf(buf, sizeof(buf), "%d", bc->AOCD.chargingUnit.recordedUnits) < sizeof(buf)) { 03474 pbx_builtin_setvar_helper(ast, "AOCD_RecordedUnits", buf); 03475 if (bc->AOCD.chargingUnit.billingId >= 0 && snprintf(buf, sizeof(buf), "%d", bc->AOCD.chargingUnit.billingId) < sizeof(buf)) { 03476 pbx_builtin_setvar_helper(ast, "AOCD_BillingId", buf); 03477 } 03478 } 03479 } 03480 } 03481 break; 03482 default: 03483 break; 03484 } 03485 03486 bc->AOCD_need_export = 0; 03487 }
void export_ch | ( | struct ast_channel * | chan, | |
struct misdn_bchannel * | bc, | |||
struct chan_list * | ch | |||
) |
Export parameters to the dialplan environment variables.
Definition at line 8741 of file chan_misdn.c.
References ast_strlen_zero(), chan_misdn_log(), misdn_bchannel::keypad, pbx_builtin_setvar_helper(), misdn_bchannel::pid, misdn_bchannel::port, misdn_bchannel::sending_complete, misdn_bchannel::urate, misdn_bchannel::uu, and misdn_bchannel::uulen.
Referenced by cb_events().
08742 { 08743 char tmp[32]; 08744 08745 /* 08746 * The only use for MISDN_PID is if there is a problem and you 08747 * have to use the "misdn restart pid" CLI command. Otherwise, 08748 * the pid is not used by anyone. The internal use of MISDN_PID 08749 * has been deleted. 08750 */ 08751 chan_misdn_log(3, bc->port, " --> EXPORT_PID: pid:%d\n", bc->pid); 08752 snprintf(tmp, sizeof(tmp), "%d", bc->pid); 08753 pbx_builtin_setvar_helper(chan, "_MISDN_PID", tmp); 08754 08755 if (bc->sending_complete) { 08756 snprintf(tmp, sizeof(tmp), "%d", bc->sending_complete); 08757 pbx_builtin_setvar_helper(chan, "MISDN_ADDRESS_COMPLETE", tmp); 08758 } 08759 08760 if (bc->urate) { 08761 snprintf(tmp, sizeof(tmp), "%d", bc->urate); 08762 pbx_builtin_setvar_helper(chan, "MISDN_URATE", tmp); 08763 } 08764 08765 if (bc->uulen) { 08766 pbx_builtin_setvar_helper(chan, "MISDN_USERUSER", bc->uu); 08767 } 08768 08769 if (!ast_strlen_zero(bc->keypad)) { 08770 pbx_builtin_setvar_helper(chan, "MISDN_KEYPAD", bc->keypad); 08771 } 08772 }
static struct chan_list* find_chan_by_bc | ( | struct misdn_bchannel * | bc | ) | [static] |
Returns a reference to the found chan_list.
Definition at line 8164 of file chan_misdn.c.
References ast_mutex_lock, ast_mutex_unlock, chan_list::bc, chan_list_ref, cl_te, cl_te_lock, and chan_list::next.
Referenced by cb_events(), and chan_misdn_jb_empty().
08165 { 08166 struct chan_list *help; 08167 08168 ast_mutex_lock(&cl_te_lock); 08169 for (help = cl_te; help; help = help->next) { 08170 if (help->bc == bc) { 08171 chan_list_ref(help, "Found chan_list by bc"); 08172 ast_mutex_unlock(&cl_te_lock); 08173 return help; 08174 } 08175 } 08176 ast_mutex_unlock(&cl_te_lock); 08177 08178 chan_misdn_log(6, bc->port, 08179 "$$$ find_chan_by_bc: No channel found for dialed:%s caller:\"%s\" <%s>\n", 08180 bc->dialed.number, 08181 bc->caller.name, 08182 bc->caller.number); 08183 08184 return NULL; 08185 }
static struct chan_list* find_hold_active_call | ( | struct misdn_bchannel * | bc | ) | [static] |
Definition at line 8256 of file chan_misdn.c.
References chan_list::ast, ast_mutex_lock, ast_mutex_unlock, chan_list::bc, chan_list_ref, cl_te, cl_te_lock, chan_list::hold, MISDN_ALERTING, MISDN_CONNECTED, MISDN_HOLD_IDLE, MISDN_PROCEEDING, MISDN_PROGRESS, chan_list::next, misdn_bchannel::port, chan_list::state, and hold_info::state.
Referenced by cb_events().
08257 { 08258 struct chan_list *list; 08259 08260 ast_mutex_lock(&cl_te_lock); 08261 for (list = cl_te; list; list = list->next) { 08262 if (list->hold.state == MISDN_HOLD_IDLE && list->bc && list->bc->port == bc->port 08263 && list->ast) { 08264 switch (list->state) { 08265 case MISDN_PROCEEDING: 08266 case MISDN_PROGRESS: 08267 case MISDN_ALERTING: 08268 case MISDN_CONNECTED: 08269 chan_list_ref(list, "Found chan_list hold active call"); 08270 ast_mutex_unlock(&cl_te_lock); 08271 return list; 08272 default: 08273 break; 08274 } 08275 } 08276 } 08277 ast_mutex_unlock(&cl_te_lock); 08278 return NULL; 08279 }
static struct chan_list* find_hold_call | ( | struct misdn_bchannel * | bc | ) | [static] |
Returns a reference to the found chan_list.
Definition at line 8188 of file chan_misdn.c.
References ast_mutex_lock, ast_mutex_unlock, chan_list::bc, misdn_bchannel::caller, chan_list_ref, chan_misdn_log(), hold_info::channel, misdn_bchannel::channel, cl_te, cl_te_lock, misdn_bchannel::dialed, chan_list::hold, MISDN_HOLD_ACTIVE, misdn_party_id::name, chan_list::next, misdn_party_id::number, misdn_party_dialing::number, hold_info::port, misdn_bchannel::port, misdn_bchannel::pri, and hold_info::state.
Referenced by cb_events().
08189 { 08190 struct chan_list *help; 08191 08192 if (bc->pri) { 08193 return NULL; 08194 } 08195 08196 chan_misdn_log(6, bc->port, "$$$ find_hold_call: channel:%d dialed:%s caller:\"%s\" <%s>\n", 08197 bc->channel, 08198 bc->dialed.number, 08199 bc->caller.name, 08200 bc->caller.number); 08201 ast_mutex_lock(&cl_te_lock); 08202 for (help = cl_te; help; help = help->next) { 08203 chan_misdn_log(4, bc->port, "$$$ find_hold_call: --> hold:%d channel:%d\n", help->hold.state, help->hold.channel); 08204 if (help->hold.state == MISDN_HOLD_ACTIVE && help->hold.port == bc->port) { 08205 chan_list_ref(help, "Found chan_list hold call"); 08206 ast_mutex_unlock(&cl_te_lock); 08207 return help; 08208 } 08209 } 08210 ast_mutex_unlock(&cl_te_lock); 08211 chan_misdn_log(6, bc->port, 08212 "$$$ find_hold_call: No channel found for dialed:%s caller:\"%s\" <%s>\n", 08213 bc->dialed.number, 08214 bc->caller.name, 08215 bc->caller.number); 08216 08217 return NULL; 08218 }
static struct chan_list* find_hold_call_l3 | ( | unsigned long | l3_id | ) | [static] |
Returns a reference to the found chan_list.
Definition at line 8222 of file chan_misdn.c.
References ast_mutex_lock, ast_mutex_unlock, chan_list_ref, cl_te, cl_te_lock, chan_list::hold, chan_list::l3id, MISDN_HOLD_IDLE, chan_list::next, and hold_info::state.
Referenced by cb_events().
08223 { 08224 struct chan_list *help; 08225 08226 ast_mutex_lock(&cl_te_lock); 08227 for (help = cl_te; help; help = help->next) { 08228 if (help->hold.state != MISDN_HOLD_IDLE && help->l3id == l3_id) { 08229 chan_list_ref(help, "Found chan_list hold call l3"); 08230 ast_mutex_unlock(&cl_te_lock); 08231 return help; 08232 } 08233 } 08234 ast_mutex_unlock(&cl_te_lock); 08235 08236 return NULL; 08237 }
static void free_robin_list | ( | void | ) | [static] |
Definition at line 599 of file chan_misdn.c.
References ast_free, robin_list::group, robin_list::next, and robin.
Referenced by reload_config(), and unload_module().
00600 { 00601 struct robin_list *r; 00602 struct robin_list *next; 00603 00604 for (r = robin, robin = NULL; r; r = next) { 00605 next = r->next; 00606 ast_free(r->group); 00607 ast_free(r); 00608 } 00609 }
static struct chan_list* get_chan_by_ast | ( | struct ast_channel * | ast | ) | [static] |
Returns a reference to the found chan_list.
Definition at line 738 of file chan_misdn.c.
References chan_list::ast, ast_mutex_lock, ast_mutex_unlock, chan_list_ref, cl_te, cl_te_lock, and chan_list::next.
Referenced by misdn_bridge().
00739 { 00740 struct chan_list *tmp; 00741 00742 ast_mutex_lock(&cl_te_lock); 00743 for (tmp = cl_te; tmp; tmp = tmp->next) { 00744 if (tmp->ast == ast) { 00745 chan_list_ref(tmp, "Found chan_list by ast"); 00746 ast_mutex_unlock(&cl_te_lock); 00747 return tmp; 00748 } 00749 } 00750 ast_mutex_unlock(&cl_te_lock); 00751 00752 return NULL; 00753 }
static struct chan_list* get_chan_by_ast_name | ( | const char * | name | ) | [static] |
Returns a reference to the found chan_list.
Definition at line 756 of file chan_misdn.c.
References chan_list::ast, ast_mutex_lock, ast_mutex_unlock, chan_list_ref, cl_te, cl_te_lock, ast_channel::name, and chan_list::next.
Referenced by handle_cli_misdn_send_digit(), handle_cli_misdn_send_display(), handle_cli_misdn_send_facility(), and handle_cli_misdn_toggle_echocancel().
00757 { 00758 struct chan_list *tmp; 00759 00760 ast_mutex_lock(&cl_te_lock); 00761 for (tmp = cl_te; tmp; tmp = tmp->next) { 00762 if (tmp->ast && strcmp(tmp->ast->name, name) == 0) { 00763 chan_list_ref(tmp, "Found chan_list by ast name"); 00764 ast_mutex_unlock(&cl_te_lock); 00765 return tmp; 00766 } 00767 } 00768 ast_mutex_unlock(&cl_te_lock); 00769 00770 return NULL; 00771 }
static struct robin_list* get_robin_position | ( | char * | group | ) | [static] |
Definition at line 611 of file chan_misdn.c.
References robin_list::group, robin_list::next, and robin.
Referenced by misdn_request().
00612 { 00613 struct robin_list *new; 00614 struct robin_list *iter = robin; 00615 for (; iter; iter = iter->next) { 00616 if (!strcasecmp(iter->group, group)) { 00617 return iter; 00618 } 00619 } 00620 new = ast_calloc(1, sizeof(*new)); 00621 if (!new) { 00622 return NULL; 00623 } 00624 new->group = ast_strdup(group); 00625 if (!new->group) { 00626 ast_free(new); 00627 return NULL; 00628 } 00629 new->channel = 1; 00630 if (robin) { 00631 new->next = robin; 00632 robin->prev = new; 00633 } 00634 robin = new; 00635 return robin; 00636 }
static char* handle_cli_misdn_port_block | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 3797 of file chan_misdn.c.
References ast_cli_args::argc, ast_cli_args::argv, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, misdn_lib_port_block(), and ast_cli_entry::usage.
03798 { 03799 switch (cmd) { 03800 case CLI_INIT: 03801 e->command = "misdn port block"; 03802 e->usage = 03803 "Usage: misdn port block <port>\n" 03804 " Block the specified port by <port>.\n"; 03805 return NULL; 03806 case CLI_GENERATE: 03807 return NULL; 03808 } 03809 03810 if (a->argc != 4) { 03811 return CLI_SHOWUSAGE; 03812 } 03813 03814 misdn_lib_port_block(atoi(a->argv[3])); 03815 03816 return CLI_SUCCESS; 03817 }
static char* handle_cli_misdn_port_down | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 3907 of file chan_misdn.c.
References ast_cli_args::argc, ast_cli_args::argv, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, misdn_lib_get_port_down(), and ast_cli_entry::usage.
03908 { 03909 switch (cmd) { 03910 case CLI_INIT: 03911 e->command = "misdn port down"; 03912 e->usage = 03913 "Usage: misdn port down <port>\n" 03914 " Try to deactivate the L1 on the given port.\n"; 03915 return NULL; 03916 case CLI_GENERATE: 03917 return NULL; 03918 } 03919 03920 if (a->argc != 4) { 03921 return CLI_SHOWUSAGE; 03922 } 03923 03924 misdn_lib_get_port_down(atoi(a->argv[3])); 03925 03926 return CLI_SUCCESS; 03927 }
static char* handle_cli_misdn_port_unblock | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 3819 of file chan_misdn.c.
References ast_cli_args::argc, ast_cli_args::argv, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, misdn_lib_port_unblock(), and ast_cli_entry::usage.
03820 { 03821 switch (cmd) { 03822 case CLI_INIT: 03823 e->command = "misdn port unblock"; 03824 e->usage = 03825 "Usage: misdn port unblock <port>\n" 03826 " Unblock the port specified by <port>.\n"; 03827 return NULL; 03828 case CLI_GENERATE: 03829 return NULL; 03830 } 03831 03832 if (a->argc != 4) { 03833 return CLI_SHOWUSAGE; 03834 } 03835 03836 misdn_lib_port_unblock(atoi(a->argv[3])); 03837 03838 return CLI_SUCCESS; 03839 }
static char* handle_cli_misdn_port_up | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 3885 of file chan_misdn.c.
References ast_cli_args::argc, ast_cli_args::argv, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, misdn_lib_get_port_up(), and ast_cli_entry::usage.
03886 { 03887 switch (cmd) { 03888 case CLI_INIT: 03889 e->command = "misdn port up"; 03890 e->usage = 03891 "Usage: misdn port up <port>\n" 03892 " Try to establish L1 on the given port.\n"; 03893 return NULL; 03894 case CLI_GENERATE: 03895 return NULL; 03896 } 03897 03898 if (a->argc != 4) { 03899 return CLI_SHOWUSAGE; 03900 } 03901 03902 misdn_lib_get_port_up(atoi(a->argv[3])); 03903 03904 return CLI_SUCCESS; 03905 }
static char* handle_cli_misdn_reload | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 4111 of file chan_misdn.c.
References ast_cli_args::argc, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, reload_config(), and ast_cli_entry::usage.
04112 { 04113 switch (cmd) { 04114 case CLI_INIT: 04115 e->command = "misdn reload"; 04116 e->usage = 04117 "Usage: misdn reload\n" 04118 " Reload internal mISDN config, read from the config\n" 04119 " file.\n"; 04120 return NULL; 04121 case CLI_GENERATE: 04122 return NULL; 04123 } 04124 04125 if (a->argc != 2) { 04126 return CLI_SHOWUSAGE; 04127 } 04128 04129 ast_cli(a->fd, "Reloading mISDN configuration\n"); 04130 reload_config(); 04131 return CLI_SUCCESS; 04132 }
static char* handle_cli_misdn_restart_pid | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 3863 of file chan_misdn.c.
References ast_cli_args::argc, ast_cli_args::argv, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, misdn_lib_pid_restart(), and ast_cli_entry::usage.
03864 { 03865 switch (cmd) { 03866 case CLI_INIT: 03867 e->command = "misdn restart pid"; 03868 e->usage = 03869 "Usage: misdn restart pid <pid>\n" 03870 " Restart the given pid\n"; 03871 return NULL; 03872 case CLI_GENERATE: 03873 return NULL; 03874 } 03875 03876 if (a->argc != 4) { 03877 return CLI_SHOWUSAGE; 03878 } 03879 03880 misdn_lib_pid_restart(atoi(a->argv[3])); 03881 03882 return CLI_SUCCESS; 03883 }
static char* handle_cli_misdn_restart_port | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 3841 of file chan_misdn.c.
References ast_cli_args::argc, ast_cli_args::argv, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, misdn_lib_port_restart(), and ast_cli_entry::usage.
03842 { 03843 switch (cmd) { 03844 case CLI_INIT: 03845 e->command = "misdn restart port"; 03846 e->usage = 03847 "Usage: misdn restart port <port>\n" 03848 " Restart the given port.\n"; 03849 return NULL; 03850 case CLI_GENERATE: 03851 return NULL; 03852 } 03853 03854 if (a->argc != 4) { 03855 return CLI_SHOWUSAGE; 03856 } 03857 03858 misdn_lib_port_restart(atoi(a->argv[3])); 03859 03860 return CLI_SUCCESS; 03861 }
static char* handle_cli_misdn_send_digit | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 5477 of file chan_misdn.c.
References ast_cli_args::argc, ast_cli_args::argv, chan_list::ast, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_ch(), ast_cli_args::fd, get_chan_by_ast_name(), send_digit_to_chan(), and ast_cli_entry::usage.
05478 { 05479 const char *channame; 05480 const char *msg; 05481 struct chan_list *tmp; 05482 int i, msglen; 05483 05484 switch (cmd) { 05485 case CLI_INIT: 05486 e->command = "misdn send digit"; 05487 e->usage = 05488 "Usage: misdn send digit <channel> \"<msg>\" \n" 05489 " Send <digit> to <channel> as DTMF Tone\n" 05490 " when channel is a mISDN channel\n"; 05491 return NULL; 05492 case CLI_GENERATE: 05493 return complete_ch(a); 05494 } 05495 05496 if (a->argc != 5) { 05497 return CLI_SHOWUSAGE; 05498 } 05499 05500 channame = a->argv[3]; 05501 msg = a->argv[4]; 05502 msglen = strlen(msg); 05503 05504 ast_cli(a->fd, "Sending %s to %s\n", msg, channame); 05505 05506 tmp = get_chan_by_ast_name(channame); 05507 if (!tmp) { 05508 ast_cli(a->fd, "Sending %s to %s failed Channel does not exist\n", msg, channame); 05509 return CLI_SUCCESS; 05510 } 05511 #if 1 05512 for (i = 0; i < msglen; i++) { 05513 if (!tmp->ast) { 05514 break; 05515 } 05516 ast_cli(a->fd, "Sending: %c\n", msg[i]); 05517 send_digit_to_chan(tmp, msg[i]); 05518 /* res = ast_safe_sleep(tmp->ast, 250); */ 05519 usleep(250000); 05520 /* res = ast_waitfor(tmp->ast,100); */ 05521 } 05522 #else 05523 if (tmp->ast) { 05524 ast_dtmf_stream(tmp->ast, NULL, msg, 250); 05525 } 05526 #endif 05527 chan_list_unref(tmp, "Digit(s) sent"); 05528 05529 return CLI_SUCCESS; 05530 }
static char* handle_cli_misdn_send_display | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 5579 of file chan_misdn.c.
References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_copy_string(), chan_list::bc, chan_list_unref, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_ch(), misdn_bchannel::display, EVENT_INFORMATION, ast_cli_args::fd, get_chan_by_ast_name(), misdn_lib_send_event(), and ast_cli_entry::usage.
05580 { 05581 const char *channame; 05582 const char *msg; 05583 struct chan_list *tmp; 05584 05585 switch (cmd) { 05586 case CLI_INIT: 05587 e->command = "misdn send display"; 05588 e->usage = 05589 "Usage: misdn send display <channel> \"<msg>\" \n" 05590 " Send <msg> to <channel> as Display Message\n" 05591 " when channel is a mISDN channel\n"; 05592 return NULL; 05593 case CLI_GENERATE: 05594 return complete_ch(a); 05595 } 05596 05597 if (a->argc != 5) { 05598 return CLI_SHOWUSAGE; 05599 } 05600 05601 channame = a->argv[3]; 05602 msg = a->argv[4]; 05603 05604 ast_cli(a->fd, "Sending %s to %s\n", msg, channame); 05605 05606 tmp = get_chan_by_ast_name(channame); 05607 if (tmp && tmp->bc) { 05608 ast_copy_string(tmp->bc->display, msg, sizeof(tmp->bc->display)); 05609 misdn_lib_send_event(tmp->bc, EVENT_INFORMATION); 05610 chan_list_unref(tmp, "Done sending display"); 05611 } else { 05612 if (tmp) { 05613 chan_list_unref(tmp, "Display failed"); 05614 } 05615 ast_cli(a->fd, "No such channel %s\n", channame); 05616 return CLI_SUCCESS; 05617 } 05618 05619 return CLI_SUCCESS; 05620 }
static char* handle_cli_misdn_send_facility | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 5151 of file chan_misdn.c.
References ao2_lock, ao2_unlock, ast_cli_args::argc, ast_cli_args::argv, ARRAY_LEN, ast_copy_string(), ast_verbose, chan_list::bc, chan_list_unref, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_ch(), dummy(), EVENT_FACILITY, EVENT_REGISTER, misdn_bchannel::fac_out, get_chan_by_ast_name(), misdn_lib_port_is_nt(), misdn_lib_send_event(), misdn_make_dummy(), print_facility(), and ast_cli_entry::usage.
05152 { 05153 const char *channame; 05154 const char *nr; 05155 struct chan_list *tmp; 05156 int port; 05157 const char *served_nr; 05158 struct misdn_bchannel dummy, *bc=&dummy; 05159 unsigned max_len; 05160 05161 switch (cmd) { 05162 case CLI_INIT: 05163 e->command = "misdn send facility"; 05164 e->usage = "Usage: misdn send facility <type> <channel|port> \"<args>\" \n" 05165 "\t type is one of:\n" 05166 "\t - calldeflect\n" 05167 #if defined(AST_MISDN_ENHANCEMENTS) 05168 "\t - callrerouting\n" 05169 #endif /* defined(AST_MISDN_ENHANCEMENTS) */ 05170 "\t - CFActivate\n" 05171 "\t - CFDeactivate\n"; 05172 05173 return NULL; 05174 case CLI_GENERATE: 05175 return complete_ch(a); 05176 } 05177 05178 if (a->argc < 5) { 05179 return CLI_SHOWUSAGE; 05180 } 05181 05182 if (strstr(a->argv[3], "calldeflect")) { 05183 if (a->argc < 6) { 05184 ast_verbose("calldeflect requires 1 arg: ToNumber\n\n"); 05185 return 0; 05186 } 05187 channame = a->argv[4]; 05188 nr = a->argv[5]; 05189 05190 ast_verbose("Sending Calldeflection (%s) to %s\n", nr, channame); 05191 tmp = get_chan_by_ast_name(channame); 05192 if (!tmp) { 05193 ast_verbose("Sending CD with nr %s to %s failed: Channel does not exist.\n", nr, channame); 05194 return 0; 05195 } 05196 ao2_lock(tmp); 05197 05198 #if defined(AST_MISDN_ENHANCEMENTS) 05199 max_len = sizeof(tmp->bc->fac_out.u.CallDeflection.Component.Invoke.Deflection.Party.Number) - 1; 05200 if (max_len < strlen(nr)) { 05201 ast_verbose("Sending CD with nr %s to %s failed: Number too long (up to %u digits are allowed).\n", 05202 nr, channame, max_len); 05203 ao2_unlock(tmp); 05204 chan_list_unref(tmp, "Number too long"); 05205 return 0; 05206 } 05207 tmp->bc->fac_out.Function = Fac_CallDeflection; 05208 tmp->bc->fac_out.u.CallDeflection.InvokeID = ++misdn_invoke_id; 05209 tmp->bc->fac_out.u.CallDeflection.ComponentType = FacComponent_Invoke; 05210 tmp->bc->fac_out.u.CallDeflection.Component.Invoke.PresentationAllowedToDivertedToUserPresent = 1; 05211 tmp->bc->fac_out.u.CallDeflection.Component.Invoke.PresentationAllowedToDivertedToUser = 0; 05212 tmp->bc->fac_out.u.CallDeflection.Component.Invoke.Deflection.Party.Type = 0;/* unknown */ 05213 tmp->bc->fac_out.u.CallDeflection.Component.Invoke.Deflection.Party.LengthOfNumber = strlen(nr); 05214 strcpy((char *) tmp->bc->fac_out.u.CallDeflection.Component.Invoke.Deflection.Party.Number, nr); 05215 tmp->bc->fac_out.u.CallDeflection.Component.Invoke.Deflection.Subaddress.Length = 0; 05216 05217 #else /* !defined(AST_MISDN_ENHANCEMENTS) */ 05218 05219 max_len = sizeof(tmp->bc->fac_out.u.CDeflection.DeflectedToNumber) - 1; 05220 if (max_len < strlen(nr)) { 05221 ast_verbose("Sending CD with nr %s to %s failed: Number too long (up to %u digits are allowed).\n", 05222 nr, channame, max_len); 05223 ao2_unlock(tmp); 05224 chan_list_unref(tmp, "Number too long"); 05225 return 0; 05226 } 05227 tmp->bc->fac_out.Function = Fac_CD; 05228 tmp->bc->fac_out.u.CDeflection.PresentationAllowed = 0; 05229 //tmp->bc->fac_out.u.CDeflection.DeflectedToSubaddress[0] = 0; 05230 strcpy((char *) tmp->bc->fac_out.u.CDeflection.DeflectedToNumber, nr); 05231 #endif /* !defined(AST_MISDN_ENHANCEMENTS) */ 05232 05233 /* Send message */ 05234 print_facility(&tmp->bc->fac_out, tmp->bc); 05235 ao2_unlock(tmp); 05236 misdn_lib_send_event(tmp->bc, EVENT_FACILITY); 05237 chan_list_unref(tmp, "Send facility complete"); 05238 #if defined(AST_MISDN_ENHANCEMENTS) 05239 } else if (strstr(a->argv[3], "callrerouteing") || strstr(a->argv[3], "callrerouting")) { 05240 if (a->argc < 6) { 05241 ast_verbose("callrerouting requires 1 arg: ToNumber\n\n"); 05242 return 0; 05243 } 05244 channame = a->argv[4]; 05245 nr = a->argv[5]; 05246 05247 ast_verbose("Sending Callrerouting (%s) to %s\n", nr, channame); 05248 tmp = get_chan_by_ast_name(channame); 05249 if (!tmp) { 05250 ast_verbose("Sending Call Rerouting with nr %s to %s failed: Channel does not exist.\n", nr, channame); 05251 return 0; 05252 } 05253 ao2_lock(tmp); 05254 05255 max_len = sizeof(tmp->bc->fac_out.u.CallRerouteing.Component.Invoke.CalledAddress.Party.Number) - 1; 05256 if (max_len < strlen(nr)) { 05257 ast_verbose("Sending Call Rerouting with nr %s to %s failed: Number too long (up to %u digits are allowed).\n", 05258 nr, channame, max_len); 05259 ao2_unlock(tmp); 05260 chan_list_unref(tmp, "Number too long"); 05261 return 0; 05262 } 05263 tmp->bc->fac_out.Function = Fac_CallRerouteing; 05264 tmp->bc->fac_out.u.CallRerouteing.InvokeID = ++misdn_invoke_id; 05265 tmp->bc->fac_out.u.CallRerouteing.ComponentType = FacComponent_Invoke; 05266 05267 tmp->bc->fac_out.u.CallRerouteing.Component.Invoke.ReroutingReason = 0;/* unknown */ 05268 tmp->bc->fac_out.u.CallRerouteing.Component.Invoke.ReroutingCounter = 1; 05269 05270 tmp->bc->fac_out.u.CallRerouteing.Component.Invoke.CalledAddress.Party.Type = 0;/* unknown */ 05271 tmp->bc->fac_out.u.CallRerouteing.Component.Invoke.CalledAddress.Party.LengthOfNumber = strlen(nr); 05272 strcpy((char *) tmp->bc->fac_out.u.CallRerouteing.Component.Invoke.CalledAddress.Party.Number, nr); 05273 tmp->bc->fac_out.u.CallRerouteing.Component.Invoke.CalledAddress.Subaddress.Length = 0; 05274 05275 tmp->bc->fac_out.u.CallRerouteing.Component.Invoke.CallingPartySubaddress.Length = 0; 05276 05277 /* 0x90 0x90 0xa3 3.1 kHz audio, circuit mode, 64kbit/sec, level1/a-Law */ 05278 tmp->bc->fac_out.u.CallRerouteing.Component.Invoke.Q931ie.Bc.Length = 3; 05279 tmp->bc->fac_out.u.CallRerouteing.Component.Invoke.Q931ie.Bc.Contents[0] = 0x90; 05280 tmp->bc->fac_out.u.CallRerouteing.Component.Invoke.Q931ie.Bc.Contents[1] = 0x90; 05281 tmp->bc->fac_out.u.CallRerouteing.Component.Invoke.Q931ie.Bc.Contents[2] = 0xa3; 05282 tmp->bc->fac_out.u.CallRerouteing.Component.Invoke.Q931ie.Hlc.Length = 0; 05283 tmp->bc->fac_out.u.CallRerouteing.Component.Invoke.Q931ie.Llc.Length = 0; 05284 tmp->bc->fac_out.u.CallRerouteing.Component.Invoke.Q931ie.UserInfo.Length = 0; 05285 05286 tmp->bc->fac_out.u.CallRerouteing.Component.Invoke.LastRerouting.Type = 1;/* presentationRestricted */ 05287 tmp->bc->fac_out.u.CallRerouteing.Component.Invoke.SubscriptionOption = 0;/* no notification to caller */ 05288 05289 /* Send message */ 05290 print_facility(&tmp->bc->fac_out, tmp->bc); 05291 ao2_unlock(tmp); 05292 misdn_lib_send_event(tmp->bc, EVENT_FACILITY); 05293 chan_list_unref(tmp, "Send facility complete"); 05294 #endif /* defined(AST_MISDN_ENHANCEMENTS) */ 05295 } else if (strstr(a->argv[3], "CFActivate")) { 05296 if (a->argc < 7) { 05297 ast_verbose("CFActivate requires 2 args: 1.FromNumber, 2.ToNumber\n\n"); 05298 return 0; 05299 } 05300 port = atoi(a->argv[4]); 05301 served_nr = a->argv[5]; 05302 nr = a->argv[6]; 05303 05304 misdn_make_dummy(bc, port, 0, misdn_lib_port_is_nt(port), 0); 05305 05306 ast_verbose("Sending CFActivate Port:(%d) FromNr. (%s) to Nr. (%s)\n", port, served_nr, nr); 05307 05308 #if defined(AST_MISDN_ENHANCEMENTS) 05309 bc->fac_out.Function = Fac_ActivationDiversion; 05310 bc->fac_out.u.ActivationDiversion.InvokeID = ++misdn_invoke_id; 05311 bc->fac_out.u.ActivationDiversion.ComponentType = FacComponent_Invoke; 05312 bc->fac_out.u.ActivationDiversion.Component.Invoke.BasicService = 0;/* allServices */ 05313 bc->fac_out.u.ActivationDiversion.Component.Invoke.Procedure = 0;/* cfu (Call Forward Unconditional) */ 05314 ast_copy_string((char *) bc->fac_out.u.ActivationDiversion.Component.Invoke.ServedUser.Number, 05315 served_nr, sizeof(bc->fac_out.u.ActivationDiversion.Component.Invoke.ServedUser.Number)); 05316 bc->fac_out.u.ActivationDiversion.Component.Invoke.ServedUser.LengthOfNumber = 05317 strlen((char *) bc->fac_out.u.ActivationDiversion.Component.Invoke.ServedUser.Number); 05318 bc->fac_out.u.ActivationDiversion.Component.Invoke.ServedUser.Type = 0;/* unknown */ 05319 ast_copy_string((char *) bc->fac_out.u.ActivationDiversion.Component.Invoke.ForwardedTo.Party.Number, 05320 nr, sizeof(bc->fac_out.u.ActivationDiversion.Component.Invoke.ForwardedTo.Party.Number)); 05321 bc->fac_out.u.ActivationDiversion.Component.Invoke.ForwardedTo.Party.LengthOfNumber = 05322 strlen((char *) bc->fac_out.u.ActivationDiversion.Component.Invoke.ForwardedTo.Party.Number); 05323 bc->fac_out.u.ActivationDiversion.Component.Invoke.ForwardedTo.Party.Type = 0;/* unknown */ 05324 bc->fac_out.u.ActivationDiversion.Component.Invoke.ForwardedTo.Subaddress.Length = 0; 05325 05326 #else /* !defined(AST_MISDN_ENHANCEMENTS) */ 05327 05328 bc->fac_out.Function = Fac_CFActivate; 05329 bc->fac_out.u.CFActivate.BasicService = 0; /* All Services */ 05330 bc->fac_out.u.CFActivate.Procedure = 0; /* Unconditional */ 05331 ast_copy_string((char *) bc->fac_out.u.CFActivate.ServedUserNumber, served_nr, sizeof(bc->fac_out.u.CFActivate.ServedUserNumber)); 05332 ast_copy_string((char *) bc->fac_out.u.CFActivate.ForwardedToNumber, nr, sizeof(bc->fac_out.u.CFActivate.ForwardedToNumber)); 05333 #endif /* !defined(AST_MISDN_ENHANCEMENTS) */ 05334 05335 /* Send message */ 05336 print_facility(&bc->fac_out, bc); 05337 misdn_lib_send_event(bc, EVENT_FACILITY); 05338 } else if (strstr(a->argv[3], "CFDeactivate")) { 05339 if (a->argc < 6) { 05340 ast_verbose("CFDeactivate requires 1 arg: FromNumber\n\n"); 05341 return 0; 05342 } 05343 port = atoi(a->argv[4]); 05344 served_nr = a->argv[5]; 05345 05346 misdn_make_dummy(bc, port, 0, misdn_lib_port_is_nt(port), 0); 05347 ast_verbose("Sending CFDeactivate Port:(%d) FromNr. (%s)\n", port, served_nr); 05348 05349 #if defined(AST_MISDN_ENHANCEMENTS) 05350 bc->fac_out.Function = Fac_DeactivationDiversion; 05351 bc->fac_out.u.DeactivationDiversion.InvokeID = ++misdn_invoke_id; 05352 bc->fac_out.u.DeactivationDiversion.ComponentType = FacComponent_Invoke; 05353 bc->fac_out.u.DeactivationDiversion.Component.Invoke.BasicService = 0;/* allServices */ 05354 bc->fac_out.u.DeactivationDiversion.Component.Invoke.Procedure = 0;/* cfu (Call Forward Unconditional) */ 05355 ast_copy_string((char *) bc->fac_out.u.DeactivationDiversion.Component.Invoke.ServedUser.Number, 05356 served_nr, sizeof(bc->fac_out.u.DeactivationDiversion.Component.Invoke.ServedUser.Number)); 05357 bc->fac_out.u.DeactivationDiversion.Component.Invoke.ServedUser.LengthOfNumber = 05358 strlen((char *) bc->fac_out.u.DeactivationDiversion.Component.Invoke.ServedUser.Number); 05359 bc->fac_out.u.DeactivationDiversion.Component.Invoke.ServedUser.Type = 0;/* unknown */ 05360 05361 #else /* !defined(AST_MISDN_ENHANCEMENTS) */ 05362 05363 bc->fac_out.Function = Fac_CFDeactivate; 05364 bc->fac_out.u.CFDeactivate.BasicService = 0; /* All Services */ 05365 bc->fac_out.u.CFDeactivate.Procedure = 0; /* Unconditional */ 05366 ast_copy_string((char *) bc->fac_out.u.CFActivate.ServedUserNumber, served_nr, sizeof(bc->fac_out.u.CFActivate.ServedUserNumber)); 05367 #endif /* !defined(AST_MISDN_ENHANCEMENTS) */ 05368 05369 /* Send message */ 05370 print_facility(&bc->fac_out, bc); 05371 misdn_lib_send_event(bc, EVENT_FACILITY); 05372 #if defined(AST_MISDN_ENHANCEMENTS) && defined(CCBS_TEST_MESSAGES) 05373 } else if (strstr(a->argv[3], "test")) { 05374 int msg_number; 05375 05376 if (a->argc < 5) { 05377 ast_verbose("test (<port> [<msg#>]) | (<channel-name> <msg#>)\n\n"); 05378 return 0; 05379 } 05380 port = atoi(a->argv[4]); 05381 05382 channame = a->argv[4]; 05383 tmp = get_chan_by_ast_name(channame); 05384 if (tmp) { 05385 /* We are going to send this FACILITY message out on an existing connection */ 05386 msg_number = atoi(a->argv[5]); 05387 if (msg_number < ARRAY_LEN(Fac_Msgs)) { 05388 ao2_lock(tmp); 05389 tmp->bc->fac_out = Fac_Msgs[msg_number]; 05390 05391 /* Send message */ 05392 print_facility(&tmp->bc->fac_out, tmp->bc); 05393 ao2_unlock(tmp); 05394 misdn_lib_send_event(tmp->bc, EVENT_FACILITY); 05395 } else { 05396 ast_verbose("test <channel-name> <msg#>\n\n"); 05397 } 05398 chan_list_unref(tmp, "Facility test done"); 05399 } else if (a->argc < 6) { 05400 for (msg_number = 0; msg_number < ARRAY_LEN(Fac_Msgs); ++msg_number) { 05401 misdn_make_dummy(bc, port, 0, misdn_lib_port_is_nt(port), 0); 05402 bc->fac_out = Fac_Msgs[msg_number]; 05403 05404 /* Send message */ 05405 print_facility(&bc->fac_out, bc); 05406 misdn_lib_send_event(bc, EVENT_FACILITY); 05407 sleep(1); 05408 } 05409 } else { 05410 msg_number = atoi(a->argv[5]); 05411 if (msg_number < ARRAY_LEN(Fac_Msgs)) { 05412 misdn_make_dummy(bc, port, 0, misdn_lib_port_is_nt(port), 0); 05413 bc->fac_out = Fac_Msgs[msg_number]; 05414 05415 /* Send message */ 05416 print_facility(&bc->fac_out, bc); 05417 misdn_lib_send_event(bc, EVENT_FACILITY); 05418 } else { 05419 ast_verbose("test <port> [<msg#>]\n\n"); 05420 } 05421 } 05422 } else if (strstr(a->argv[3], "register")) { 05423 if (a->argc < 5) { 05424 ast_verbose("register <port>\n\n"); 05425 return 0; 05426 } 05427 port = atoi(a->argv[4]); 05428 05429 bc = misdn_lib_get_register_bc(port); 05430 if (!bc) { 05431 ast_verbose("Could not allocate REGISTER bc struct\n\n"); 05432 return 0; 05433 } 05434 bc->fac_out = Fac_Msgs[45]; 05435 05436 /* Send message */ 05437 print_facility(&bc->fac_out, bc); 05438 misdn_lib_send_event(bc, EVENT_REGISTER); 05439 #endif /* defined(AST_MISDN_ENHANCEMENTS) && defined(CCBS_TEST_MESSAGES) */ 05440 } 05441 05442 return CLI_SUCCESS; 05443 }
static char* handle_cli_misdn_send_restart | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 5445 of file chan_misdn.c.
References ast_cli_args::argc, ast_cli_args::argv, misdn_bchannel::channel, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, misdn_lib_send_restart(), and ast_cli_entry::usage.
05446 { 05447 int port; 05448 int channel; 05449 05450 switch (cmd) { 05451 case CLI_INIT: 05452 e->command = "misdn send restart"; 05453 e->usage = 05454 "Usage: misdn send restart [port [channel]]\n" 05455 " Send a restart for every bchannel on the given port.\n"; 05456 return NULL; 05457 case CLI_GENERATE: 05458 return NULL; 05459 } 05460 05461 if (a->argc < 4 || a->argc > 5) { 05462 return CLI_SHOWUSAGE; 05463 } 05464 05465 port = atoi(a->argv[3]); 05466 05467 if (a->argc == 5) { 05468 channel = atoi(a->argv[4]); 05469 misdn_lib_send_restart(port, channel); 05470 } else { 05471 misdn_lib_send_restart(port, -1); 05472 } 05473 05474 return CLI_SUCCESS; 05475 }
static char* handle_cli_misdn_set_crypt_debug | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 3774 of file chan_misdn.c.
References ast_cli_args::argc, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, and ast_cli_entry::usage.
03775 { 03776 switch (cmd) { 03777 case CLI_INIT: 03778 e->command = "misdn set crypt debug"; 03779 e->usage = 03780 "Usage: misdn set crypt debug <level>\n" 03781 " Set the crypt debug level of the mISDN channel. Level\n" 03782 " must be 1 or 2.\n"; 03783 return NULL; 03784 case CLI_GENERATE: 03785 return NULL; 03786 } 03787 03788 if (a->argc != 5) { 03789 return CLI_SHOWUSAGE; 03790 } 03791 03792 /* XXX Is this supposed to not do anything? XXX */ 03793 03794 return CLI_SUCCESS; 03795 }
static char* handle_cli_misdn_set_debug | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 3687 of file chan_misdn.c.
References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_debug_port(), ast_cli_args::fd, max_ports, misdn_debug, misdn_debug_only, and ast_cli_entry::usage.
03688 { 03689 int level; 03690 03691 switch (cmd) { 03692 case CLI_INIT: 03693 e->command = "misdn set debug [on|off]"; 03694 e->usage = 03695 "Usage: misdn set debug {on|off|<level>} [only] | [port <port> [only]]\n" 03696 " Set the debug level of the mISDN channel.\n"; 03697 return NULL; 03698 case CLI_GENERATE: 03699 return complete_debug_port(a); 03700 } 03701 03702 if (a->argc < 4 || a->argc > 7) { 03703 return CLI_SHOWUSAGE; 03704 } 03705 03706 if (!strcasecmp(a->argv[3], "on")) { 03707 level = 1; 03708 } else if (!strcasecmp(a->argv[3], "off")) { 03709 level = 0; 03710 } else if (isdigit(a->argv[3][0])) { 03711 level = atoi(a->argv[3]); 03712 } else { 03713 return CLI_SHOWUSAGE; 03714 } 03715 03716 switch (a->argc) { 03717 case 4: 03718 case 5: 03719 { 03720 int i; 03721 int only = 0; 03722 if (a->argc == 5) { 03723 if (strncasecmp(a->argv[4], "only", strlen(a->argv[4]))) { 03724 return CLI_SHOWUSAGE; 03725 } else { 03726 only = 1; 03727 } 03728 } 03729 03730 for (i = 0; i <= max_ports; i++) { 03731 misdn_debug[i] = level; 03732 misdn_debug_only[i] = only; 03733 } 03734 ast_cli(a->fd, "changing debug level for all ports to %d%s\n", misdn_debug[0], only ? " (only)" : ""); 03735 } 03736 break; 03737 case 6: 03738 case 7: 03739 { 03740 int port; 03741 if (strncasecmp(a->argv[4], "port", strlen(a->argv[4]))) 03742 return CLI_SHOWUSAGE; 03743 port = atoi(a->argv[5]); 03744 if (port <= 0 || port > max_ports) { 03745 switch (max_ports) { 03746 case 0: 03747 ast_cli(a->fd, "port number not valid! no ports available so you won't get lucky with any number here...\n"); 03748 break; 03749 case 1: 03750 ast_cli(a->fd, "port number not valid! only port 1 is available.\n"); 03751 break; 03752 default: 03753 ast_cli(a->fd, "port number not valid! only ports 1 to %d are available.\n", max_ports); 03754 } 03755 return 0; 03756 } 03757 if (a->argc == 7) { 03758 if (strncasecmp(a->argv[6], "only", strlen(a->argv[6]))) { 03759 return CLI_SHOWUSAGE; 03760 } else { 03761 misdn_debug_only[port] = 1; 03762 } 03763 } else { 03764 misdn_debug_only[port] = 0; 03765 } 03766 misdn_debug[port] = level; 03767 ast_cli(a->fd, "changing debug level to %d%s for port %d\n", misdn_debug[port], misdn_debug_only[port] ? " (only)" : "", port); 03768 } 03769 } 03770 03771 return CLI_SUCCESS; 03772 }
static char* handle_cli_misdn_set_tics | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 4307 of file chan_misdn.c.
References ast_cli_args::argc, ast_cli_args::argv, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, and ast_cli_entry::usage.
04308 { 04309 switch (cmd) { 04310 case CLI_INIT: 04311 e->command = "misdn set tics"; 04312 e->usage = 04313 "Usage: misdn set tics <value>\n"; 04314 return NULL; 04315 case CLI_GENERATE: 04316 return NULL; 04317 } 04318 04319 if (a->argc != 4) { 04320 return CLI_SHOWUSAGE; 04321 } 04322 04323 /* XXX Wow, this does... a whole lot of nothing... XXX */ 04324 MAXTICS = atoi(a->argv[3]); 04325 04326 return CLI_SUCCESS; 04327 }
static char* handle_cli_misdn_show_channel | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 4271 of file chan_misdn.c.
References ast_cli_args::argc, ast_cli_args::argv, chan_list::ast, ast_mutex_lock, chan_list::bc, cl_te, cl_te_lock, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, ast_cli_entry::command, complete_ch(), ast_cli_args::fd, ast_channel::name, chan_list::next, print_bc_info(), and ast_cli_entry::usage.
04272 { 04273 struct chan_list *help; 04274 04275 switch (cmd) { 04276 case CLI_INIT: 04277 e->command = "misdn show channel"; 04278 e->usage = 04279 "Usage: misdn show channel <channel>\n" 04280 " Show an internal mISDN channel\n."; 04281 return NULL; 04282 case CLI_GENERATE: 04283 return complete_ch(a); 04284 } 04285 04286 if (a->argc != 4) { 04287 return CLI_SHOWUSAGE; 04288 } 04289 04290 ast_mutex_lock(&cl_te_lock); 04291 for (help = cl_te; help; help = help->next) { 04292 struct misdn_bchannel *bc = help->bc; 04293 struct ast_channel *ast = help->ast; 04294 04295 if (bc && ast) { 04296 if (!strcasecmp(ast->name, a->argv[3])) { 04297 print_bc_info(a->fd, help, bc); 04298 break; 04299 } 04300 } 04301 } 04302 ast_mutex_unlock(&cl_te_lock); 04303 04304 return CLI_SUCCESS; 04305 }
static char* handle_cli_misdn_show_channels | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 4197 of file chan_misdn.c.
References ast_cli_args::argc, chan_list::ast, ast_cli(), ast_mutex_lock, ast_mutex_unlock, chan_list::bc, ast_channel::caller, hold_info::channel, cl_te, cl_te_lock, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_channel::exten, ast_cli_args::fd, chan_list::hold, ast_party_caller::id, chan_list::l3id, misdn_debug, misdn_dump_chanlist(), MISDN_HOLD_IDLE, ast_party_id::name, chan_list::next, ast_party_id::number, misdn_bchannel::pid, hold_info::port, print_bc_info(), S_COR, hold_info::state, ast_party_number::str, ast_party_name::str, ast_cli_entry::usage, ast_party_number::valid, and ast_party_name::valid.
04198 { 04199 struct chan_list *help; 04200 04201 switch (cmd) { 04202 case CLI_INIT: 04203 e->command = "misdn show channels"; 04204 e->usage = 04205 "Usage: misdn show channels\n" 04206 " Show the internal mISDN channel list\n"; 04207 return NULL; 04208 case CLI_GENERATE: 04209 return NULL; 04210 } 04211 04212 if (a->argc != 3) { 04213 return CLI_SHOWUSAGE; 04214 } 04215 04216 ast_cli(a->fd, "Channel List: %p\n", cl_te); 04217 04218 /* 04219 * Walking the list and dumping the channel information could 04220 * take awhile. With the list locked for the duration, the 04221 * channel driver cannot process signaling messages. However, 04222 * since this is a CLI command it should not be run very often. 04223 */ 04224 ast_mutex_lock(&cl_te_lock); 04225 for (help = cl_te; help; help = help->next) { 04226 struct misdn_bchannel *bc = help->bc; 04227 struct ast_channel *ast = help->ast; 04228 if (!ast) { 04229 if (!bc) { 04230 ast_cli(a->fd, "chan_list obj. with l3id:%x has no bc and no ast Leg\n", help->l3id); 04231 continue; 04232 } 04233 ast_cli(a->fd, "bc with pid:%d has no Ast Leg\n", bc->pid); 04234 continue; 04235 } 04236 04237 if (misdn_debug[0] > 2) { 04238 ast_cli(a->fd, "Bc:%p Ast:%p\n", bc, ast); 04239 } 04240 if (bc) { 04241 print_bc_info(a->fd, help, bc); 04242 } else { 04243 if (help->hold.state != MISDN_HOLD_IDLE) { 04244 ast_cli(a->fd, "ITS A HELD CALL BC:\n"); 04245 ast_cli(a->fd, " --> l3_id: %x\n" 04246 " --> dialed:%s\n" 04247 " --> caller:\"%s\" <%s>\n" 04248 " --> hold_port: %d\n" 04249 " --> hold_channel: %d\n", 04250 help->l3id, 04251 ast->exten, 04252 S_COR(ast->caller.id.name.valid, ast->caller.id.name.str, ""), 04253 S_COR(ast->caller.id.number.valid, ast->caller.id.number.str, ""), 04254 help->hold.port, 04255 help->hold.channel 04256 ); 04257 } else { 04258 ast_cli(a->fd, "* Channel in unknown STATE !!! Exten:%s, Callerid:%s\n", 04259 ast->exten, 04260 S_COR(ast->caller.id.number.valid, ast->caller.id.number.str, "")); 04261 } 04262 } 04263 } 04264 ast_mutex_unlock(&cl_te_lock); 04265 04266 misdn_dump_chanlist(); 04267 04268 return CLI_SUCCESS; 04269 }
static char* handle_cli_misdn_show_config | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 3954 of file chan_misdn.c.
References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), BUFFERSIZE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_show_config(), ast_cli_args::fd, MISDN_CFG_FIRST, misdn_cfg_get_elem(), MISDN_CFG_LAST, MISDN_GEN_FIRST, MISDN_GEN_LAST, show_config_description(), and ast_cli_entry::usage.
03955 { 03956 char buffer[BUFFERSIZE]; 03957 enum misdn_cfg_elements elem; 03958 int linebreak; 03959 int onlyport = -1; 03960 int ok = 0; 03961 03962 switch (cmd) { 03963 case CLI_INIT: 03964 e->command = "misdn show config"; 03965 e->usage = 03966 "Usage: misdn show config [<port> | description <config element> | descriptions [general|ports]]\n" 03967 " Use 0 for <port> to only print the general config.\n"; 03968 return NULL; 03969 case CLI_GENERATE: 03970 return complete_show_config(a); 03971 } 03972 03973 if (a->argc >= 4) { 03974 if (!strcmp(a->argv[3], "description")) { 03975 if (a->argc == 5) { 03976 enum misdn_cfg_elements elem = misdn_cfg_get_elem(a->argv[4]); 03977 if (elem == MISDN_CFG_FIRST) { 03978 ast_cli(a->fd, "Unknown element: %s\n", a->argv[4]); 03979 } else { 03980 show_config_description(a->fd, elem); 03981 } 03982 return CLI_SUCCESS; 03983 } 03984 return CLI_SHOWUSAGE; 03985 } else if (!strcmp(a->argv[3], "descriptions")) { 03986 if ((a->argc == 4) || ((a->argc == 5) && !strcmp(a->argv[4], "general"))) { 03987 for (elem = MISDN_GEN_FIRST + 1; elem < MISDN_GEN_LAST; ++elem) { 03988 show_config_description(a->fd, elem); 03989 ast_cli(a->fd, "\n"); 03990 } 03991 ok = 1; 03992 } 03993 if ((a->argc == 4) || ((a->argc == 5) && !strcmp(a->argv[4], "ports"))) { 03994 for (elem = MISDN_CFG_FIRST + 1; elem < MISDN_CFG_LAST - 1 /* the ptp hack, remove the -1 when ptp is gone */; ++elem) { 03995 show_config_description(a->fd, elem); 03996 ast_cli(a->fd, "\n"); 03997 } 03998 ok = 1; 03999 } 04000 return ok ? CLI_SUCCESS : CLI_SHOWUSAGE; 04001 } else if (!sscanf(a->argv[3], "%5d", &onlyport) || onlyport < 0) { 04002 ast_cli(a->fd, "Unknown option: %s\n", a->argv[3]); 04003 return CLI_SHOWUSAGE; 04004 } 04005 } 04006 04007 if (a->argc == 3 || onlyport == 0) { 04008 ast_cli(a->fd, "mISDN General-Config:\n"); 04009 for (elem = MISDN_GEN_FIRST + 1, linebreak = 1; elem < MISDN_GEN_LAST; elem++, linebreak++) { 04010 misdn_cfg_get_config_string(0, elem, buffer, sizeof(buffer)); 04011 ast_cli(a->fd, "%-36s%s", buffer, !(linebreak % 2) ? "\n" : ""); 04012 } 04013 ast_cli(a->fd, "\n"); 04014 } 04015 04016 if (onlyport < 0) { 04017 int port = misdn_cfg_get_next_port(0); 04018 04019 for (; port > 0; port = misdn_cfg_get_next_port(port)) { 04020 ast_cli(a->fd, "\n[PORT %d]\n", port); 04021 for (elem = MISDN_CFG_FIRST + 1, linebreak = 1; elem < MISDN_CFG_LAST; elem++, linebreak++) { 04022 misdn_cfg_get_config_string(port, elem, buffer, sizeof(buffer)); 04023 ast_cli(a->fd, "%-36s%s", buffer, !(linebreak % 2) ? "\n" : ""); 04024 } 04025 ast_cli(a->fd, "\n"); 04026 } 04027 } 04028 04029 if (onlyport > 0) { 04030 if (misdn_cfg_is_port_valid(onlyport)) { 04031 ast_cli(a->fd, "[PORT %d]\n", onlyport); 04032 for (elem = MISDN_CFG_FIRST + 1, linebreak = 1; elem < MISDN_CFG_LAST; elem++, linebreak++) { 04033 misdn_cfg_get_config_string(onlyport, elem, buffer, sizeof(buffer)); 04034 ast_cli(a->fd, "%-36s%s", buffer, !(linebreak % 2) ? "\n" : ""); 04035 } 04036 ast_cli(a->fd, "\n"); 04037 } else { 04038 ast_cli(a->fd, "Port %d is not active!\n", onlyport); 04039 } 04040 } 04041 04042 return CLI_SUCCESS; 04043 }
static char* handle_cli_misdn_show_port | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 4389 of file chan_misdn.c.
References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, get_show_stack_details(), misdn_debug, misdn_debug_only, and ast_cli_entry::usage.
04390 { 04391 int port; 04392 char buf[128]; 04393 04394 switch (cmd) { 04395 case CLI_INIT: 04396 e->command = "misdn show port"; 04397 e->usage = 04398 "Usage: misdn show port <port>\n" 04399 " Show detailed information for given port.\n"; 04400 return NULL; 04401 case CLI_GENERATE: 04402 return NULL; 04403 } 04404 04405 if (a->argc != 4) { 04406 return CLI_SHOWUSAGE; 04407 } 04408 04409 port = atoi(a->argv[3]); 04410 04411 ast_cli(a->fd, "BEGIN STACK_LIST:\n"); 04412 get_show_stack_details(port, buf); 04413 ast_cli(a->fd, " %s Debug:%d%s\n", buf, misdn_debug[port], misdn_debug_only[port] ? "(only)" : ""); 04414 04415 return CLI_SUCCESS; 04416 }
static char* handle_cli_misdn_show_ports_stats | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 4360 of file chan_misdn.c.
References ast_cli_args::argc, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, misdn_cfg_get_next_port(), misdn_in_calls, misdn_out_calls, and ast_cli_entry::usage.
04361 { 04362 int port; 04363 04364 switch (cmd) { 04365 case CLI_INIT: 04366 e->command = "misdn show ports stats"; 04367 e->usage = 04368 "Usage: misdn show ports stats\n" 04369 " Show mISDNs channel's call statistics per port.\n"; 04370 return NULL; 04371 case CLI_GENERATE: 04372 return NULL; 04373 } 04374 04375 if (a->argc != 4) { 04376 return CLI_SHOWUSAGE; 04377 } 04378 04379 ast_cli(a->fd, "Port\tin_calls\tout_calls\n"); 04380 for (port = misdn_cfg_get_next_port(0); port > 0; 04381 port = misdn_cfg_get_next_port(port)) { 04382 ast_cli(a->fd, "%d\t%d\t\t%d\n", port, misdn_in_calls[port], misdn_out_calls[port]); 04383 } 04384 ast_cli(a->fd, "\n"); 04385 04386 return CLI_SUCCESS; 04387 }
static char* handle_cli_misdn_show_stacks | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 4329 of file chan_misdn.c.
References ast_cli_args::argc, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, get_show_stack_details(), misdn_cfg_get_next_port(), misdn_debug, misdn_debug_only, and ast_cli_entry::usage.
04330 { 04331 int port; 04332 04333 switch (cmd) { 04334 case CLI_INIT: 04335 e->command = "misdn show stacks"; 04336 e->usage = 04337 "Usage: misdn show stacks\n" 04338 " Show internal mISDN stack_list.\n"; 04339 return NULL; 04340 case CLI_GENERATE: 04341 return NULL; 04342 } 04343 04344 if (a->argc != 3) { 04345 return CLI_SHOWUSAGE; 04346 } 04347 04348 ast_cli(a->fd, "BEGIN STACK_LIST:\n"); 04349 for (port = misdn_cfg_get_next_port(0); port > 0; 04350 port = misdn_cfg_get_next_port(port)) { 04351 char buf[128]; 04352 04353 get_show_stack_details(port, buf); 04354 ast_cli(a->fd, " %s Debug:%d%s\n", buf, misdn_debug[port], misdn_debug_only[port] ? "(only)" : ""); 04355 } 04356 04357 return CLI_SUCCESS; 04358 }
static char* handle_cli_misdn_toggle_echocancel | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 5532 of file chan_misdn.c.
References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), chan_list::bc, chan_list_unref, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_ch(), ast_cli_args::fd, get_chan_by_ast_name(), manager_ec_disable(), manager_ec_enable(), chan_list::toggle_ec, update_ec_config(), and ast_cli_entry::usage.
05533 { 05534 const char *channame; 05535 struct chan_list *tmp; 05536 05537 switch (cmd) { 05538 case CLI_INIT: 05539 e->command = "misdn toggle echocancel"; 05540 e->usage = 05541 "Usage: misdn toggle echocancel <channel>\n" 05542 " Toggle EchoCancel on mISDN Channel.\n"; 05543 return NULL; 05544 case CLI_GENERATE: 05545 return complete_ch(a); 05546 } 05547 05548 if (a->argc != 4) { 05549 return CLI_SHOWUSAGE; 05550 } 05551 05552 channame = a->argv[3]; 05553 05554 ast_cli(a->fd, "Toggling EchoCancel on %s\n", channame); 05555 05556 tmp = get_chan_by_ast_name(channame); 05557 if (!tmp) { 05558 ast_cli(a->fd, "Toggling EchoCancel %s failed Channel does not exist\n", channame); 05559 return CLI_SUCCESS; 05560 } 05561 05562 tmp->toggle_ec = tmp->toggle_ec ? 0 : 1; 05563 05564 if (tmp->toggle_ec) { 05565 #ifdef MISDN_1_2 05566 update_pipeline_config(tmp->bc); 05567 #else 05568 update_ec_config(tmp->bc); 05569 #endif 05570 manager_ec_enable(tmp->bc); 05571 } else { 05572 manager_ec_disable(tmp->bc); 05573 } 05574 chan_list_unref(tmp, "Done toggling echo cancel"); 05575 05576 return CLI_SUCCESS; 05577 }
static void hangup_chan | ( | struct chan_list * | ch, | |
struct misdn_bchannel * | bc | |||
) | [static] |
Definition at line 8352 of file chan_misdn.c.
References chan_list::ast, ast_hangup(), ast_queue_hangup_with_cause(), chan_list::bc, misdn_bchannel::cause, cb_log, chan_list::need_hangup, chan_list::need_queue_hangup, misdn_bchannel::port, and send_cause2ast().
Referenced by cb_events(), do_immediate_setup(), and start_pbx().
08353 { 08354 int port; 08355 08356 if (!ch) { 08357 cb_log(1, 0, "Cannot hangup chan, no ch\n"); 08358 return; 08359 } 08360 08361 port = bc->port; 08362 cb_log(5, port, "hangup_chan called\n"); 08363 08364 if (ch->need_hangup) { 08365 cb_log(2, port, " --> hangup\n"); 08366 ch->need_hangup = 0; 08367 ch->need_queue_hangup = 0; 08368 if (ch->ast) { 08369 send_cause2ast(ch->ast, bc, ch); 08370 ast_hangup(ch->ast); 08371 } 08372 return; 08373 } 08374 08375 if (!ch->need_queue_hangup) { 08376 cb_log(2, port, " --> No need to queue hangup\n"); 08377 } 08378 08379 ch->need_queue_hangup = 0; 08380 if (ch->ast) { 08381 send_cause2ast(ch->ast, bc, ch); 08382 ast_queue_hangup_with_cause(ch->ast, bc->cause); 08383 cb_log(2, port, " --> queue_hangup\n"); 08384 } else { 08385 cb_log(1, port, "Cannot hangup chan, no ast\n"); 08386 } 08387 }
static void hanguptone_indicate | ( | struct chan_list * | cl | ) | [static] |
Definition at line 7642 of file chan_misdn.c.
References chan_list::bc, misdn_lib_send_tone(), and TONE_HANGUP.
Referenced by cb_events(), do_immediate_setup(), misdn_hangup(), misdn_indication(), misdn_overlap_dial_task(), and start_pbx().
07643 { 07644 misdn_lib_send_tone(cl->bc, TONE_HANGUP); 07645 }
void import_ch | ( | struct ast_channel * | chan, | |
struct misdn_bchannel * | bc, | |||
struct chan_list * | ch | |||
) |
Import parameters from the dialplan environment variables.
Definition at line 8716 of file chan_misdn.c.
References ast_channel_lock, ast_channel_unlock, ast_copy_string(), ast_log(), misdn_bchannel::keypad, LOG_NOTICE, pbx_builtin_getvar_helper(), misdn_bchannel::sending_complete, misdn_bchannel::uu, and misdn_bchannel::uulen.
Referenced by misdn_call().
08717 { 08718 const char *tmp; 08719 08720 ast_channel_lock(chan); 08721 tmp = pbx_builtin_getvar_helper(chan, "MISDN_ADDRESS_COMPLETE"); 08722 if (tmp && (atoi(tmp) == 1)) { 08723 bc->sending_complete = 1; 08724 } 08725 08726 tmp = pbx_builtin_getvar_helper(chan, "MISDN_USERUSER"); 08727 if (tmp) { 08728 ast_log(LOG_NOTICE, "MISDN_USERUSER: %s\n", tmp); 08729 ast_copy_string(bc->uu, tmp, sizeof(bc->uu)); 08730 bc->uulen = strlen(bc->uu); 08731 } 08732 08733 tmp = pbx_builtin_getvar_helper(chan, "MISDN_KEYPAD"); 08734 if (tmp) { 08735 ast_copy_string(bc->keypad, tmp, sizeof(bc->keypad)); 08736 } 08737 ast_channel_unlock(chan); 08738 }
static int load_module | ( | void | ) | [static] |
Definition at line 11152 of file chan_misdn.c.
References ast_calloc, ast_channel_register(), ast_cli_register_multiple(), ast_custom_function_register, ast_free, ast_log(), ast_malloc, AST_MODULE_LOAD_DECLINE, ast_mutex_init, ast_register_application, ast_strlen_zero(), BUFFERSIZE, misdn_lib_iface::cb_event, cb_events(), chan_misdn_clis, chan_misdn_jb_empty(), chan_misdn_log(), cl_te_lock, LOG_ERROR, max_ports, misdn_cfg_get(), misdn_cfg_get_next_port(), misdn_cfg_get_ports_string(), misdn_cfg_init(), MISDN_CFG_L1_TIMEOUT, misdn_cfg_update_ptp(), misdn_check_l2l1(), misdn_debug, misdn_debug_only, misdn_facility_exec(), MISDN_GEN_DEBUG, MISDN_GEN_NTDEBUGFILE, MISDN_GEN_NTDEBUGFLAGS, MISDN_GEN_NTKEEPCALLS, MISDN_GEN_TRACEFILE, misdn_in_calls, misdn_l1_task(), misdn_lib_init(), misdn_lib_maxports_get(), misdn_lib_nt_debug_init(), misdn_lib_nt_keepcalls(), misdn_out_calls, misdn_ports, misdn_set_opt_exec(), misdn_tasks_add(), misdn_tech, misdn_type, release_lock, tracing, and unload_module.
11153 { 11154 int i, port; 11155 int ntflags = 0, ntkc = 0; 11156 char ports[256] = ""; 11157 char tempbuf[BUFFERSIZE + 1]; 11158 char ntfile[BUFFERSIZE + 1]; 11159 struct misdn_lib_iface iface = { 11160 .cb_event = cb_events, 11161 .cb_log = chan_misdn_log, 11162 .cb_jb_empty = chan_misdn_jb_empty, 11163 }; 11164 11165 max_ports = misdn_lib_maxports_get(); 11166 11167 if (max_ports <= 0) { 11168 ast_log(LOG_ERROR, "Unable to initialize mISDN\n"); 11169 return AST_MODULE_LOAD_DECLINE; 11170 } 11171 11172 if (misdn_cfg_init(max_ports, 0)) { 11173 ast_log(LOG_ERROR, "Unable to initialize misdn_config.\n"); 11174 return AST_MODULE_LOAD_DECLINE; 11175 } 11176 g_config_initialized = 1; 11177 11178 #if defined(AST_MISDN_ENHANCEMENTS) 11179 misdn_cc_init(); 11180 #endif /* defined(AST_MISDN_ENHANCEMENTS) */ 11181 11182 misdn_debug = ast_malloc(sizeof(int) * (max_ports + 1)); 11183 if (!misdn_debug) { 11184 ast_log(LOG_ERROR, "Out of memory for misdn_debug\n"); 11185 return AST_MODULE_LOAD_DECLINE; 11186 } 11187 misdn_ports = ast_malloc(sizeof(int) * (max_ports + 1)); 11188 if (!misdn_ports) { 11189 ast_free(misdn_debug); 11190 ast_log(LOG_ERROR, "Out of memory for misdn_ports\n"); 11191 return AST_MODULE_LOAD_DECLINE; 11192 } 11193 misdn_cfg_get(0, MISDN_GEN_DEBUG, &misdn_debug[0], sizeof(misdn_debug[0])); 11194 for (i = 1; i <= max_ports; i++) { 11195 misdn_debug[i] = misdn_debug[0]; 11196 misdn_ports[i] = i; 11197 } 11198 *misdn_ports = 0; 11199 misdn_debug_only = ast_calloc(max_ports + 1, sizeof(int)); 11200 if (!misdn_debug_only) { 11201 ast_free(misdn_ports); 11202 ast_free(misdn_debug); 11203 ast_log(LOG_ERROR, "Out of memory for misdn_debug_only\n"); 11204 return AST_MODULE_LOAD_DECLINE; 11205 } 11206 11207 misdn_cfg_get(0, MISDN_GEN_TRACEFILE, tempbuf, sizeof(tempbuf)); 11208 if (!ast_strlen_zero(tempbuf)) { 11209 tracing = 1; 11210 } 11211 11212 misdn_in_calls = ast_malloc(sizeof(int) * (max_ports + 1)); 11213 if (!misdn_in_calls) { 11214 ast_free(misdn_debug_only); 11215 ast_free(misdn_ports); 11216 ast_free(misdn_debug); 11217 ast_log(LOG_ERROR, "Out of memory for misdn_in_calls\n"); 11218 return AST_MODULE_LOAD_DECLINE; 11219 } 11220 misdn_out_calls = ast_malloc(sizeof(int) * (max_ports + 1)); 11221 if (!misdn_out_calls) { 11222 ast_free(misdn_in_calls); 11223 ast_free(misdn_debug_only); 11224 ast_free(misdn_ports); 11225 ast_free(misdn_debug); 11226 ast_log(LOG_ERROR, "Out of memory for misdn_out_calls\n"); 11227 return AST_MODULE_LOAD_DECLINE; 11228 } 11229 11230 for (i = 1; i <= max_ports; i++) { 11231 misdn_in_calls[i] = 0; 11232 misdn_out_calls[i] = 0; 11233 } 11234 11235 ast_mutex_init(&cl_te_lock); 11236 ast_mutex_init(&release_lock); 11237 11238 misdn_cfg_update_ptp(); 11239 misdn_cfg_get_ports_string(ports); 11240 11241 if (!ast_strlen_zero(ports)) { 11242 chan_misdn_log(0, 0, "Got: %s from get_ports\n", ports); 11243 } 11244 if (misdn_lib_init(ports, &iface, NULL)) { 11245 chan_misdn_log(0, 0, "No te ports initialized\n"); 11246 } 11247 11248 misdn_cfg_get(0, MISDN_GEN_NTDEBUGFLAGS, &ntflags, sizeof(ntflags)); 11249 misdn_cfg_get(0, MISDN_GEN_NTDEBUGFILE, &ntfile, sizeof(ntfile)); 11250 misdn_cfg_get(0, MISDN_GEN_NTKEEPCALLS, &ntkc, sizeof(ntkc)); 11251 11252 misdn_lib_nt_keepcalls(ntkc); 11253 misdn_lib_nt_debug_init(ntflags, ntfile); 11254 11255 if (ast_channel_register(&misdn_tech)) { 11256 ast_log(LOG_ERROR, "Unable to register channel class %s\n", misdn_type); 11257 unload_module(); 11258 return AST_MODULE_LOAD_DECLINE; 11259 } 11260 11261 ast_cli_register_multiple(chan_misdn_clis, sizeof(chan_misdn_clis) / sizeof(struct ast_cli_entry)); 11262 11263 ast_register_application("misdn_set_opt", misdn_set_opt_exec, "misdn_set_opt", 11264 "misdn_set_opt(:<opt><optarg>:<opt><optarg>...):\n" 11265 "Sets mISDN opts. and optargs\n" 11266 "\n" 11267 "The available options are:\n" 11268 " a - Have Asterisk detect DTMF tones on called channel\n" 11269 " c - Make crypted outgoing call, optarg is keyindex\n" 11270 " d - Send display text to called phone, text is the optarg\n" 11271 " e - Perform echo cancellation on this channel,\n" 11272 " takes taps as optarg (32,64,128,256)\n" 11273 " e! - Disable echo cancellation on this channel\n" 11274 " f - Enable fax detection\n" 11275 " h - Make digital outgoing call\n" 11276 " h1 - Make HDLC mode digital outgoing call\n" 11277 " i - Ignore detected DTMF tones, don't signal them to Asterisk,\n" 11278 " they will be transported inband.\n" 11279 " jb - Set jitter buffer length, optarg is length\n" 11280 " jt - Set jitter buffer upper threshold, optarg is threshold\n" 11281 " jn - Disable jitter buffer\n" 11282 " n - Disable mISDN DSP on channel.\n" 11283 " Disables: echo cancel, DTMF detection, and volume control.\n" 11284 " p - Caller ID presentation,\n" 11285 " optarg is either 'allowed' or 'restricted'\n" 11286 " s - Send Non-inband DTMF as inband\n" 11287 " vr - Rx gain control, optarg is gain\n" 11288 " vt - Tx gain control, optarg is gain\n" 11289 ); 11290 11291 11292 ast_register_application("misdn_facility", misdn_facility_exec, "misdn_facility", 11293 "misdn_facility(<FACILITY_TYPE>|<ARG1>|..)\n" 11294 "Sends the Facility Message FACILITY_TYPE with \n" 11295 "the given Arguments to the current ISDN Channel\n" 11296 "Supported Facilities are:\n" 11297 "\n" 11298 "type=calldeflect args=Nr where to deflect\n" 11299 #if defined(AST_MISDN_ENHANCEMENTS) 11300 "type=callrerouting args=Nr where to deflect\n" 11301 #endif /* defined(AST_MISDN_ENHANCEMENTS) */ 11302 ); 11303 11304 11305 ast_register_application("misdn_check_l2l1", misdn_check_l2l1, "misdn_check_l2l1", 11306 "misdn_check_l2l1(<port>||g:<groupname>,timeout)\n" 11307 "Checks if the L2 and L1 are up on either the given <port> or\n" 11308 "on the ports in the group with <groupname>\n" 11309 "If the L1/L2 are down, check_l2l1 gets up the L1/L2 and waits\n" 11310 "for <timeout> seconds that this happens. Otherwise, nothing happens\n" 11311 "\n" 11312 "This application, ensures the L1/L2 state of the Ports in a group\n" 11313 "it is intended to make the pmp_l1_check option redundant and to\n" 11314 "fix a buggy switch config from your provider\n" 11315 "\n" 11316 "a sample dialplan would look like:\n\n" 11317 "exten => _X.,1,misdn_check_l2l1(g:out|2)\n" 11318 "exten => _X.,n,dial(mISDN/g:out/${EXTEN})\n" 11319 ); 11320 11321 #if defined(AST_MISDN_ENHANCEMENTS) 11322 ast_register_application(misdn_command_name, misdn_command_exec, misdn_command_name, 11323 "misdn_command(<command>[,<options>])\n" 11324 "The following commands are defined:\n" 11325 "cc-initialize\n" 11326 " Setup mISDN support for call completion\n" 11327 " Must call before doing any Dial() involving call completion.\n" 11328 "ccnr-request,${MISDN_CC_RECORD_ID},<notify-context>,<user-a-extension>,<priority>\n" 11329 " Request Call Completion No Reply activation\n" 11330 "ccbs-request,${MISDN_CC_RECORD_ID},<notify-context>,<user-a-extension>,<priority>\n" 11331 " Request Call Completion Busy Subscriber activation\n" 11332 "cc-b-free,${MISDN_CC_RECORD_ID},<notify-context>,<user-a-extension>,<priority>\n" 11333 " Set the dialplan location to notify when User-B is available but User-A is busy.\n" 11334 " Setting this dialplan location is optional.\n" 11335 "cc-a-busy,${MISDN_CC_RECORD_ID},<yes/no>\n" 11336 " Set the busy status of call completion User-A\n" 11337 "cc-deactivate,${MISDN_CC_RECORD_ID}\n" 11338 " Deactivate the identified call completion request\n" 11339 "\n" 11340 "MISDN_CC_RECORD_ID is set when Dial() returns and call completion is possible\n" 11341 "MISDN_CC_STATUS is set to ACTIVATED or ERROR after the call completion\n" 11342 "activation request.\n" 11343 "MISDN_ERROR_MSG is set to a descriptive message on error.\n" 11344 ); 11345 11346 ast_custom_function_register(&misdn_cc_function); 11347 #endif /* defined(AST_MISDN_ENHANCEMENTS) */ 11348 11349 misdn_cfg_get(0, MISDN_GEN_TRACEFILE, global_tracefile, sizeof(global_tracefile)); 11350 11351 /* start the l1 watchers */ 11352 11353 for (port = misdn_cfg_get_next_port(0); port >= 0; port = misdn_cfg_get_next_port(port)) { 11354 int l1timeout; 11355 misdn_cfg_get(port, MISDN_CFG_L1_TIMEOUT, &l1timeout, sizeof(l1timeout)); 11356 if (l1timeout) { 11357 chan_misdn_log(4, 0, "Adding L1watcher task: port:%d timeout:%ds\n", port, l1timeout); 11358 misdn_tasks_add(l1timeout * 1000, misdn_l1_task, &misdn_ports[port]); 11359 } 11360 } 11361 11362 chan_misdn_log(0, 0, "-- mISDN Channel Driver Registered --\n"); 11363 11364 return 0; 11365 }
static void misdn_add_number_prefix | ( | int | port, | |
enum mISDN_NUMBER_TYPE | number_type, | |||
char * | number, | |||
size_t | size | |||
) | [static] |
Definition at line 3394 of file chan_misdn.c.
References misdn_cfg_get(), MISDN_CFG_TON_PREFIX_ABBREVIATED, MISDN_CFG_TON_PREFIX_INTERNATIONAL, MISDN_CFG_TON_PREFIX_NATIONAL, MISDN_CFG_TON_PREFIX_NETWORK_SPECIFIC, MISDN_CFG_TON_PREFIX_SUBSCRIBER, MISDN_CFG_TON_PREFIX_UNKNOWN, MISDN_MAX_NUMBER_LEN, misdn_prefix_string(), NUMTYPE_ABBREVIATED, NUMTYPE_INTERNATIONAL, NUMTYPE_NATIONAL, NUMTYPE_NETWORK_SPECIFIC, NUMTYPE_SUBSCRIBER, and NUMTYPE_UNKNOWN.
Referenced by cb_events(), misdn_facility_ie_handler(), misdn_is_msn_valid(), and read_config().
03395 { 03396 enum misdn_cfg_elements type_prefix; 03397 char num_prefix[MISDN_MAX_NUMBER_LEN]; 03398 03399 /* Get prefix string. */ 03400 switch (number_type) { 03401 case NUMTYPE_UNKNOWN: 03402 type_prefix = MISDN_CFG_TON_PREFIX_UNKNOWN; 03403 break; 03404 case NUMTYPE_INTERNATIONAL: 03405 type_prefix = MISDN_CFG_TON_PREFIX_INTERNATIONAL; 03406 break; 03407 case NUMTYPE_NATIONAL: 03408 type_prefix = MISDN_CFG_TON_PREFIX_NATIONAL; 03409 break; 03410 case NUMTYPE_NETWORK_SPECIFIC: 03411 type_prefix = MISDN_CFG_TON_PREFIX_NETWORK_SPECIFIC; 03412 break; 03413 case NUMTYPE_SUBSCRIBER: 03414 type_prefix = MISDN_CFG_TON_PREFIX_SUBSCRIBER; 03415 break; 03416 case NUMTYPE_ABBREVIATED: 03417 type_prefix = MISDN_CFG_TON_PREFIX_ABBREVIATED; 03418 break; 03419 default: 03420 /* Type-of-number does not have a prefix that can be added. */ 03421 return; 03422 } 03423 misdn_cfg_get(port, type_prefix, num_prefix, sizeof(num_prefix)); 03424 03425 misdn_prefix_string(num_prefix, number, size); 03426 }
static int misdn_answer | ( | struct ast_channel * | ast | ) | [static] |
Definition at line 6752 of file chan_misdn.c.
References chan_list::ast, AST_CAUSE_NETWORK_OUT_OF_ORDER, AST_CAUSE_PROTOCOL_ERROR, ast_channel_lock, ast_channel_unlock, ast_copy_string(), ast_log(), ast_queue_hangup_with_cause(), ast_strlen_zero(), ast_true(), chan_list::bc, chan_misdn_log(), misdn_bchannel::connected, misdn_bchannel::crypt_key, misdn_bchannel::dialed, EVENT_CONNECT, misdn_bchannel::fac_out, misdn_bchannel::hdlc, LOG_WARNING, MISDN_ASTERISK_TECH_PVT, MISDN_CONNECTED, misdn_lib_send_event(), misdn_bchannel::nodsp, misdn_bchannel::nojitter, misdn_party_dialing::number, misdn_party_id::number, misdn_party_dialing::number_plan, misdn_party_id::number_plan, misdn_party_dialing::number_type, misdn_party_id::number_type, misdn_bchannel::outgoing_colp, pbx_builtin_getvar_helper(), misdn_bchannel::port, misdn_bchannel::presentation, misdn_party_id::presentation, print_facility(), misdn_party_id::screening, start_bc_tones(), chan_list::state, and stop_indicate().
06753 { 06754 struct chan_list *p; 06755 const char *tmp; 06756 06757 if (!ast || !(p = MISDN_ASTERISK_TECH_PVT(ast))) { 06758 return -1; 06759 } 06760 06761 chan_misdn_log(1, p ? (p->bc ? p->bc->port : 0) : 0, "* ANSWER:\n"); 06762 06763 if (!p) { 06764 ast_log(LOG_WARNING, " --> Channel not connected ??\n"); 06765 ast_queue_hangup_with_cause(ast, AST_CAUSE_NETWORK_OUT_OF_ORDER); 06766 } 06767 06768 if (!p->bc) { 06769 chan_misdn_log(1, 0, " --> Got Answer, but there is no bc obj ??\n"); 06770 06771 ast_queue_hangup_with_cause(ast, AST_CAUSE_PROTOCOL_ERROR); 06772 } 06773 06774 ast_channel_lock(ast); 06775 tmp = pbx_builtin_getvar_helper(ast, "CRYPT_KEY"); 06776 if (!ast_strlen_zero(tmp)) { 06777 chan_misdn_log(1, p->bc->port, " --> Connection will be BF crypted\n"); 06778 ast_copy_string(p->bc->crypt_key, tmp, sizeof(p->bc->crypt_key)); 06779 } else { 06780 chan_misdn_log(3, p->bc->port, " --> Connection is without BF encryption\n"); 06781 } 06782 06783 tmp = pbx_builtin_getvar_helper(ast, "MISDN_DIGITAL_TRANS"); 06784 if (!ast_strlen_zero(tmp) && ast_true(tmp)) { 06785 chan_misdn_log(1, p->bc->port, " --> Connection is transparent digital\n"); 06786 p->bc->nodsp = 1; 06787 p->bc->hdlc = 0; 06788 p->bc->nojitter = 1; 06789 } 06790 ast_channel_unlock(ast); 06791 06792 p->state = MISDN_CONNECTED; 06793 stop_indicate(p); 06794 06795 if (ast_strlen_zero(p->bc->connected.number)) { 06796 chan_misdn_log(2,p->bc->port," --> empty connected number using dialed number\n"); 06797 ast_copy_string(p->bc->connected.number, p->bc->dialed.number, sizeof(p->bc->connected.number)); 06798 06799 /* 06800 * Use the misdn_set_opt() application to set the presentation 06801 * before we answer or you can use the CONECTEDLINE() function 06802 * to set everything before using the Answer() application. 06803 */ 06804 p->bc->connected.presentation = p->bc->presentation; 06805 p->bc->connected.screening = 0; /* unscreened */ 06806 p->bc->connected.number_type = p->bc->dialed.number_type; 06807 p->bc->connected.number_plan = p->bc->dialed.number_plan; 06808 } 06809 06810 switch (p->bc->outgoing_colp) { 06811 case 1:/* restricted */ 06812 case 2:/* blocked */ 06813 p->bc->connected.presentation = 1;/* restricted */ 06814 break; 06815 default: 06816 break; 06817 } 06818 06819 #if defined(AST_MISDN_ENHANCEMENTS) 06820 if (p->bc->div_leg_3_tx_pending) { 06821 p->bc->div_leg_3_tx_pending = 0; 06822 06823 /* Send DivertingLegInformation3 */ 06824 p->bc->fac_out.Function = Fac_DivertingLegInformation3; 06825 p->bc->fac_out.u.DivertingLegInformation3.InvokeID = ++misdn_invoke_id; 06826 p->bc->fac_out.u.DivertingLegInformation3.PresentationAllowedIndicator = 06827 (p->bc->connected.presentation == 0) ? 1 : 0; 06828 print_facility(&p->bc->fac_out, p->bc); 06829 } 06830 #endif /* defined(AST_MISDN_ENHANCEMENTS) */ 06831 misdn_lib_send_event(p->bc, EVENT_CONNECT); 06832 start_bc_tones(p); 06833 06834 return 0; 06835 }
static int misdn_attempt_transfer | ( | struct chan_list * | active_ch, | |
struct chan_list * | held_ch | |||
) | [static] |
Definition at line 8524 of file chan_misdn.c.
References ao2_ref, chan_list::ast, ast_bridged_channel(), ast_channel_lock, ast_channel_transfer_masquerade(), ast_channel_trylock, ast_channel_unlock, ast_party_connected_line_copy(), ast_party_connected_line_free(), ast_party_connected_line_init(), chan_misdn_log(), CHANNEL_DEADLOCK_AVOIDANCE, ast_channel::connected, chan_list::hold, MISDN_ALERTING, MISDN_CONNECTED, MISDN_HOLD_TRANSFER, MISDN_PROCEEDING, MISDN_PROGRESS, ast_channel::name, hold_info::port, hold_info::state, and chan_list::state.
Referenced by cb_events().
08525 { 08526 int retval; 08527 struct ast_channel *target; 08528 struct ast_channel *transferee; 08529 struct ast_party_connected_line target_colp; 08530 struct ast_party_connected_line transferee_colp; 08531 08532 switch (active_ch->state) { 08533 case MISDN_PROCEEDING: 08534 case MISDN_PROGRESS: 08535 case MISDN_ALERTING: 08536 case MISDN_CONNECTED: 08537 break; 08538 default: 08539 return -1; 08540 } 08541 08542 ast_channel_lock(held_ch->ast); 08543 while (ast_channel_trylock(active_ch->ast)) { 08544 CHANNEL_DEADLOCK_AVOIDANCE(held_ch->ast); 08545 } 08546 08547 transferee = ast_bridged_channel(held_ch->ast); 08548 if (!transferee) { 08549 /* 08550 * Could not transfer. Held channel is not bridged anymore. 08551 * Held party probably got tired of waiting and hung up. 08552 */ 08553 ast_channel_unlock(held_ch->ast); 08554 ast_channel_unlock(active_ch->ast); 08555 return -1; 08556 } 08557 08558 target = active_ch->ast; 08559 chan_misdn_log(1, held_ch->hold.port, "TRANSFERRING %s to %s\n", 08560 held_ch->ast->name, target->name); 08561 08562 ast_party_connected_line_init(&target_colp); 08563 ast_party_connected_line_copy(&target_colp, &target->connected); 08564 ast_party_connected_line_init(&transferee_colp); 08565 ast_party_connected_line_copy(&transferee_colp, &held_ch->ast->connected); 08566 held_ch->hold.state = MISDN_HOLD_TRANSFER; 08567 08568 /* 08569 * Before starting a masquerade, all channel and pvt locks must 08570 * be unlocked. Any recursive channel locks held before 08571 * ast_channel_transfer_masquerade() invalidates deadlock 08572 * avoidance. Since we are unlocking both the pvt and its owner 08573 * channel it is possible for "target" and "transferee" to be 08574 * destroyed by their pbx threads. To prevent this we must give 08575 * "target" and "transferee" a reference before any unlocking 08576 * takes place. 08577 */ 08578 ao2_ref(target, +1); 08579 ao2_ref(transferee, +1); 08580 ast_channel_unlock(held_ch->ast); 08581 ast_channel_unlock(active_ch->ast); 08582 08583 /* Setup transfer masquerade. */ 08584 retval = ast_channel_transfer_masquerade(target, &target_colp, 0, 08585 transferee, &transferee_colp, 1); 08586 08587 ast_party_connected_line_free(&target_colp); 08588 ast_party_connected_line_free(&transferee_colp); 08589 ao2_ref(target, -1); 08590 ao2_ref(transferee, -1); 08591 return retval; 08592 }
static enum ast_bridge_result misdn_bridge | ( | struct ast_channel * | c0, | |
struct ast_channel * | c1, | |||
int | flags, | |||
struct ast_frame ** | fo, | |||
struct ast_channel ** | rc, | |||
int | timeoutms | |||
) | [static] |
Definition at line 7498 of file chan_misdn.c.
References AST_BRIDGE_COMPLETE, AST_BRIDGE_DTMF_CHANNEL_0, AST_BRIDGE_DTMF_CHANNEL_1, AST_BRIDGE_FAILED, AST_FRAME_CONTROL, AST_FRAME_DTMF, AST_FRAME_VOICE, ast_log(), ast_read(), ast_verb, ast_waitfor_n(), ast_write(), chan_list::bc, misdn_bchannel::caller, chan_list_unref, chan_misdn_log(), ast_channel::exten, f, get_chan_by_ast(), chan_list::ignore_dtmf, LOG_NOTICE, MISDN_CFG_BRIDGING, misdn_cfg_get(), MISDN_GEN_BRIDGING, misdn_lib_bridge(), misdn_lib_split_bridge(), misdn_party_id::name, ast_channel::name, misdn_party_id::number, misdn_bchannel::pid, and misdn_bchannel::port.
07503 { 07504 struct chan_list *ch1, *ch2; 07505 struct ast_channel *carr[2], *who; 07506 int to = -1; 07507 struct ast_frame *f; 07508 int p1_b, p2_b; 07509 int bridging; 07510 07511 ch1 = get_chan_by_ast(c0); 07512 if (!ch1) { 07513 return -1; 07514 } 07515 ch2 = get_chan_by_ast(c1); 07516 if (!ch2) { 07517 chan_list_unref(ch1, "Failed to find ch2"); 07518 return -1; 07519 } 07520 07521 carr[0] = c0; 07522 carr[1] = c1; 07523 07524 misdn_cfg_get(ch1->bc->port, MISDN_CFG_BRIDGING, &p1_b, sizeof(p1_b)); 07525 misdn_cfg_get(ch2->bc->port, MISDN_CFG_BRIDGING, &p2_b, sizeof(p2_b)); 07526 07527 if (! p1_b || ! p2_b) { 07528 ast_log(LOG_NOTICE, "Falling back to Asterisk bridging\n"); 07529 chan_list_unref(ch1, "Bridge fallback ch1"); 07530 chan_list_unref(ch2, "Bridge fallback ch2"); 07531 return AST_BRIDGE_FAILED; 07532 } 07533 07534 misdn_cfg_get(0, MISDN_GEN_BRIDGING, &bridging, sizeof(bridging)); 07535 if (bridging) { 07536 /* trying to make a mISDN_dsp conference */ 07537 chan_misdn_log(1, ch1->bc->port, "I SEND: Making conference with Number:%d\n", ch1->bc->pid + 1); 07538 misdn_lib_bridge(ch1->bc, ch2->bc); 07539 } 07540 07541 ast_verb(3, "Native bridging %s and %s\n", c0->name, c1->name); 07542 07543 chan_misdn_log(1, ch1->bc->port, "* Making Native Bridge between \"%s\" <%s> and \"%s\" <%s>\n", 07544 ch1->bc->caller.name, 07545 ch1->bc->caller.number, 07546 ch2->bc->caller.name, 07547 ch2->bc->caller.number); 07548 07549 if (!(flags & AST_BRIDGE_DTMF_CHANNEL_0)) { 07550 ch1->ignore_dtmf = 1; 07551 } 07552 07553 if (!(flags & AST_BRIDGE_DTMF_CHANNEL_1)) { 07554 ch2->ignore_dtmf = 1; 07555 } 07556 07557 for (;/*ever*/;) { 07558 to = -1; 07559 who = ast_waitfor_n(carr, 2, &to); 07560 07561 if (!who) { 07562 ast_log(LOG_NOTICE, "misdn_bridge: empty read, breaking out\n"); 07563 break; 07564 } 07565 f = ast_read(who); 07566 07567 if (!f || f->frametype == AST_FRAME_CONTROL) { 07568 /* got hangup .. */ 07569 07570 if (!f) { 07571 chan_misdn_log(4, ch1->bc->port, "Read Null Frame\n"); 07572 } else { 07573 chan_misdn_log(4, ch1->bc->port, "Read Frame Control class:%d\n", f->subclass.integer); 07574 } 07575 07576 *fo = f; 07577 *rc = who; 07578 break; 07579 } 07580 07581 if (f->frametype == AST_FRAME_DTMF) { 07582 chan_misdn_log(1, 0, "Read DTMF %d from %s\n", f->subclass.integer, who->exten); 07583 07584 *fo = f; 07585 *rc = who; 07586 break; 07587 } 07588 07589 #if 0 07590 if (f->frametype == AST_FRAME_VOICE) { 07591 chan_misdn_log(1, ch1->bc->port, "I SEND: Splitting conference with Number:%d\n", ch1->bc->pid +1); 07592 07593 continue; 07594 } 07595 #endif 07596 07597 ast_write((who == c0) ? c1 : c0, f); 07598 } 07599 07600 chan_misdn_log(1, ch1->bc->port, "I SEND: Splitting conference with Number:%d\n", ch1->bc->pid + 1); 07601 07602 misdn_lib_split_bridge(ch1->bc, ch2->bc); 07603 07604 chan_list_unref(ch1, "Bridge complete ch1"); 07605 chan_list_unref(ch2, "Bridge complete ch2"); 07606 return AST_BRIDGE_COMPLETE; 07607 }
static int misdn_call | ( | struct ast_channel * | ast, | |
char * | dest, | |||
int | timeout | |||
) | [static] |
Definition at line 6484 of file chan_misdn.c.
References ast_channel::_state, add_out_calls(), args, AST_APP_ARG, AST_CAUSE_NORMAL_CIRCUIT_CONGESTION, AST_CAUSE_NORMAL_CLEARING, AST_CAUSE_NORMAL_TEMPORARY_FAILURE, ast_copy_string(), AST_DECLARE_APP_ARGS, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), AST_NONSTANDARD_APP_ARGS, ast_setstate(), AST_STATE_DIALING, AST_STATE_DOWN, AST_STATE_RESERVED, ast_strdup, ast_strdupa, ast_strlen_zero(), ast_to_misdn_plan(), ast_to_misdn_ton(), ast_transfercapability2str(), chan_list::bc, ast_channel::caller, misdn_bchannel::caller, misdn_bchannel::capability, chan_misdn_log(), ast_channel::connected, ast_channel::context, misdn_party_redirecting::count, debug_numtype(), misdn_bchannel::dialed, ENOCHAN, EVENT_SETUP, ext, ast_channel::exten, misdn_bchannel::fac_out, misdn_party_redirecting::from, ast_channel::hangupcause, misdn_bchannel::hdlc, ast_party_caller::id, ast_party_connected_line::id, import_ch(), misdn_bchannel::incoming_cid_tag, INFO_CAPABILITY_DIGITAL_UNRESTRICTED, misdn_bchannel::l3_id, chan_list::l3id, LOG_WARNING, MISDN_ASTERISK_TECH_PVT, MISDN_CALLING, MISDN_CFG_APPEND_MSN_TO_CALLERID_TAG, misdn_cfg_get(), MISDN_CFG_LOCALDIALPLAN, misdn_copy_redirecting_from_ast(), misdn_lib_is_ptp(), misdn_lib_send_event(), misdn_set_opt_exec(), ast_party_id::name, misdn_party_id::name, ast_channel::name, misdn_bchannel::nt, ast_party_id::number, misdn_party_id::number, misdn_party_dialing::number, misdn_party_id::number_plan, misdn_party_id::number_type, NUMPLAN_ISDN, NUMTYPE_UNKNOWN, misdn_bchannel::outgoing_colp, pbx_builtin_setvar_helper(), misdn_bchannel::pid, ast_party_number::plan, misdn_bchannel::port, misdn_bchannel::presentation, misdn_party_id::presentation, print_facility(), misdn_party_redirecting::reason, misdn_bchannel::redirecting, misdn_bchannel::sending_complete, misdn_bchannel::set_presentation, chan_list::state, stop_bc_tones(), ast_party_number::str, ast_party_name::str, ast_party_id::tag, ast_channel::transfercapability, update_config(), ast_party_number::valid, and ast_party_name::valid.
06485 { 06486 int port = 0; 06487 int r; 06488 int exceed; 06489 int number_type; 06490 struct chan_list *ch; 06491 struct misdn_bchannel *newbc; 06492 char *dest_cp; 06493 int append_msn = 0; 06494 06495 AST_DECLARE_APP_ARGS(args, 06496 AST_APP_ARG(intf); /* The interface token is discarded. */ 06497 AST_APP_ARG(ext); /* extension token */ 06498 AST_APP_ARG(opts); /* options token */ 06499 ); 06500 06501 if (!ast) { 06502 ast_log(LOG_WARNING, " --> ! misdn_call called on ast_channel *ast where ast == NULL\n"); 06503 return -1; 06504 } 06505 06506 if (((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) || !dest) { 06507 ast_log(LOG_WARNING, " --> ! misdn_call called on %s, neither down nor reserved (or dest==NULL)\n", ast->name); 06508 ast->hangupcause = AST_CAUSE_NORMAL_TEMPORARY_FAILURE; 06509 ast_setstate(ast, AST_STATE_DOWN); 06510 return -1; 06511 } 06512 06513 ch = MISDN_ASTERISK_TECH_PVT(ast); 06514 if (!ch) { 06515 ast_log(LOG_WARNING, " --> ! misdn_call called on %s, chan_list *ch==NULL\n", ast->name); 06516 ast->hangupcause = AST_CAUSE_NORMAL_TEMPORARY_FAILURE; 06517 ast_setstate(ast, AST_STATE_DOWN); 06518 return -1; 06519 } 06520 06521 newbc = ch->bc; 06522 if (!newbc) { 06523 ast_log(LOG_WARNING, " --> ! misdn_call called on %s, newbc==NULL\n", ast->name); 06524 ast->hangupcause = AST_CAUSE_NORMAL_TEMPORARY_FAILURE; 06525 ast_setstate(ast, AST_STATE_DOWN); 06526 return -1; 06527 } 06528 06529 port = newbc->port; 06530 06531 #if defined(AST_MISDN_ENHANCEMENTS) 06532 if ((ch->peer = misdn_cc_caller_get(ast))) { 06533 chan_misdn_log(3, port, " --> Found CC caller data, peer:%s\n", 06534 ch->peer->chan ? "available" : "NULL"); 06535 } 06536 06537 if (ch->record_id != -1) { 06538 struct misdn_cc_record *cc_record; 06539 06540 /* This is a call completion retry call */ 06541 AST_LIST_LOCK(&misdn_cc_records_db); 06542 cc_record = misdn_cc_find_by_id(ch->record_id); 06543 if (!cc_record) { 06544 AST_LIST_UNLOCK(&misdn_cc_records_db); 06545 ast_log(LOG_WARNING, " --> ! misdn_call called on %s, cc_record==NULL\n", ast->name); 06546 ast->hangupcause = AST_CAUSE_NORMAL_TEMPORARY_FAILURE; 06547 ast_setstate(ast, AST_STATE_DOWN); 06548 return -1; 06549 } 06550 06551 /* Setup calling parameters to retry the call. */ 06552 newbc->dialed = cc_record->redial.dialed; 06553 newbc->caller = cc_record->redial.caller; 06554 memset(&newbc->redirecting, 0, sizeof(newbc->redirecting)); 06555 newbc->capability = cc_record->redial.capability; 06556 newbc->hdlc = cc_record->redial.hdlc; 06557 newbc->sending_complete = 1; 06558 06559 if (cc_record->ptp) { 06560 newbc->fac_out.Function = Fac_CCBS_T_Call; 06561 newbc->fac_out.u.CCBS_T_Call.InvokeID = ++misdn_invoke_id; 06562 } else { 06563 newbc->fac_out.Function = Fac_CCBSCall; 06564 newbc->fac_out.u.CCBSCall.InvokeID = ++misdn_invoke_id; 06565 newbc->fac_out.u.CCBSCall.CCBSReference = cc_record->mode.ptmp.reference_id; 06566 } 06567 AST_LIST_UNLOCK(&misdn_cc_records_db); 06568 06569 ast_copy_string(ast->exten, newbc->dialed.number, sizeof(ast->exten)); 06570 06571 chan_misdn_log(1, port, "* Call completion to: %s\n", newbc->dialed.number); 06572 chan_misdn_log(2, port, " --> * tech:%s context:%s\n", ast->name, ast->context); 06573 } else 06574 #endif /* defined(AST_MISDN_ENHANCEMENTS) */ 06575 { 06576 /* 06577 * dest is ---v 06578 * Dial(mISDN/g:group_name[/extension[/options]]) 06579 * Dial(mISDN/port[:preselected_channel][/extension[/options]]) 06580 * 06581 * The dial extension could be empty if you are using MISDN_KEYPAD 06582 * to control ISDN provider features. 06583 */ 06584 dest_cp = ast_strdupa(dest); 06585 AST_NONSTANDARD_APP_ARGS(args, dest_cp, '/'); 06586 if (!args.ext) { 06587 args.ext = ""; 06588 } 06589 06590 chan_misdn_log(1, port, "* CALL: %s\n", dest); 06591 chan_misdn_log(2, port, " --> * dialed:%s tech:%s context:%s\n", args.ext, ast->name, ast->context); 06592 06593 ast_copy_string(ast->exten, args.ext, sizeof(ast->exten)); 06594 ast_copy_string(newbc->dialed.number, args.ext, sizeof(newbc->dialed.number)); 06595 06596 if (ast_strlen_zero(newbc->caller.name) 06597 && ast->connected.id.name.valid 06598 && !ast_strlen_zero(ast->connected.id.name.str)) { 06599 ast_copy_string(newbc->caller.name, ast->connected.id.name.str, sizeof(newbc->caller.name)); 06600 chan_misdn_log(3, port, " --> * set caller:\"%s\" <%s>\n", newbc->caller.name, newbc->caller.number); 06601 } 06602 if (ast_strlen_zero(newbc->caller.number) 06603 && ast->connected.id.number.valid 06604 && !ast_strlen_zero(ast->connected.id.number.str)) { 06605 ast_copy_string(newbc->caller.number, ast->connected.id.number.str, sizeof(newbc->caller.number)); 06606 chan_misdn_log(3, port, " --> * set caller:\"%s\" <%s>\n", newbc->caller.name, newbc->caller.number); 06607 } 06608 06609 misdn_cfg_get(port, MISDN_CFG_APPEND_MSN_TO_CALLERID_TAG, &append_msn, sizeof(append_msn)); 06610 if (append_msn) { 06611 strncat(newbc->incoming_cid_tag, "_", sizeof(newbc->incoming_cid_tag) - strlen(newbc->incoming_cid_tag) - 1); 06612 strncat(newbc->incoming_cid_tag, newbc->caller.number, sizeof(newbc->incoming_cid_tag) - strlen(newbc->incoming_cid_tag) - 1); 06613 } 06614 06615 ast->caller.id.tag = ast_strdup(newbc->incoming_cid_tag); 06616 06617 misdn_cfg_get(port, MISDN_CFG_LOCALDIALPLAN, &number_type, sizeof(number_type)); 06618 if (number_type < 0) { 06619 if (ast->connected.id.number.valid) { 06620 newbc->caller.number_type = ast_to_misdn_ton(ast->connected.id.number.plan); 06621 newbc->caller.number_plan = ast_to_misdn_plan(ast->connected.id.number.plan); 06622 } else { 06623 newbc->caller.number_type = NUMTYPE_UNKNOWN; 06624 newbc->caller.number_plan = NUMPLAN_ISDN; 06625 } 06626 } else { 06627 /* Force us to send in SETUP message */ 06628 newbc->caller.number_type = number_type; 06629 newbc->caller.number_plan = NUMPLAN_ISDN; 06630 } 06631 debug_numtype(port, newbc->caller.number_type, "LTON"); 06632 06633 newbc->capability = ast->transfercapability; 06634 pbx_builtin_setvar_helper(ast, "TRANSFERCAPABILITY", ast_transfercapability2str(newbc->capability)); 06635 if (ast->transfercapability == INFO_CAPABILITY_DIGITAL_UNRESTRICTED) { 06636 chan_misdn_log(2, port, " --> * Call with flag Digital\n"); 06637 } 06638 06639 /* update caller screening and presentation */ 06640 update_config(ch); 06641 06642 /* fill in some ies from channel dialplan variables */ 06643 import_ch(ast, newbc, ch); 06644 06645 /* Finally The Options Override Everything */ 06646 if (!ast_strlen_zero(args.opts)) { 06647 misdn_set_opt_exec(ast, args.opts); 06648 } else { 06649 chan_misdn_log(2, port, "NO OPTS GIVEN\n"); 06650 } 06651 if (newbc->set_presentation) { 06652 newbc->caller.presentation = newbc->presentation; 06653 } 06654 06655 misdn_copy_redirecting_from_ast(newbc, ast); 06656 switch (newbc->outgoing_colp) { 06657 case 1:/* restricted */ 06658 case 2:/* blocked */ 06659 newbc->redirecting.from.presentation = 1;/* restricted */ 06660 break; 06661 default: 06662 break; 06663 } 06664 #if defined(AST_MISDN_ENHANCEMENTS) 06665 if (newbc->redirecting.from.number[0] && misdn_lib_is_ptp(port)) { 06666 if (newbc->redirecting.count < 1) { 06667 newbc->redirecting.count = 1; 06668 } 06669 06670 /* Create DivertingLegInformation2 facility */ 06671 newbc->fac_out.Function = Fac_DivertingLegInformation2; 06672 newbc->fac_out.u.DivertingLegInformation2.InvokeID = ++misdn_invoke_id; 06673 newbc->fac_out.u.DivertingLegInformation2.DivertingPresent = 1; 06674 misdn_PresentedNumberUnscreened_fill( 06675 &newbc->fac_out.u.DivertingLegInformation2.Diverting, 06676 &newbc->redirecting.from); 06677 switch (newbc->outgoing_colp) { 06678 case 2:/* blocked */ 06679 /* Block the number going out */ 06680 newbc->fac_out.u.DivertingLegInformation2.Diverting.Type = 1;/* presentationRestricted */ 06681 06682 /* Don't tell about any previous diversions or why for that matter. */ 06683 newbc->fac_out.u.DivertingLegInformation2.DiversionCounter = 1; 06684 newbc->fac_out.u.DivertingLegInformation2.DiversionReason = 0;/* unknown */ 06685 break; 06686 default: 06687 newbc->fac_out.u.DivertingLegInformation2.DiversionCounter = 06688 newbc->redirecting.count; 06689 newbc->fac_out.u.DivertingLegInformation2.DiversionReason = 06690 misdn_to_diversion_reason(newbc->redirecting.reason); 06691 break; 06692 } 06693 newbc->fac_out.u.DivertingLegInformation2.OriginalCalledPresent = 0; 06694 if (1 < newbc->fac_out.u.DivertingLegInformation2.DiversionCounter) { 06695 newbc->fac_out.u.DivertingLegInformation2.OriginalCalledPresent = 1; 06696 newbc->fac_out.u.DivertingLegInformation2.OriginalCalled.Type = 2;/* numberNotAvailableDueToInterworking */ 06697 } 06698 06699 /* 06700 * Expect a DivertingLegInformation3 to update the COLR of the 06701 * redirecting-to party we are attempting to call now. 06702 */ 06703 newbc->div_leg_3_rx_wanted = 1; 06704 } 06705 #endif /* defined(AST_MISDN_ENHANCEMENTS) */ 06706 } 06707 06708 exceed = add_out_calls(port); 06709 if (exceed != 0) { 06710 char tmp[16]; 06711 06712 snprintf(tmp, sizeof(tmp), "%d", exceed); 06713 pbx_builtin_setvar_helper(ast, "MAX_OVERFLOW", tmp); 06714 ast->hangupcause = AST_CAUSE_NORMAL_TEMPORARY_FAILURE; 06715 ast_setstate(ast, AST_STATE_DOWN); 06716 return -1; 06717 } 06718 06719 #if defined(AST_MISDN_ENHANCEMENTS) 06720 if (newbc->fac_out.Function != Fac_None) { 06721 print_facility(&newbc->fac_out, newbc); 06722 } 06723 #endif /* defined(AST_MISDN_ENHANCEMENTS) */ 06724 r = misdn_lib_send_event(newbc, EVENT_SETUP); 06725 06726 /** we should have l3id after sending setup **/ 06727 ch->l3id = newbc->l3_id; 06728 06729 if (r == -ENOCHAN) { 06730 chan_misdn_log(0, port, " --> * Theres no Channel at the moment .. !\n"); 06731 chan_misdn_log(1, port, " --> * SEND: State Down pid:%d\n", newbc ? newbc->pid : -1); 06732 ast->hangupcause = AST_CAUSE_NORMAL_CIRCUIT_CONGESTION; 06733 ast_setstate(ast, AST_STATE_DOWN); 06734 return -1; 06735 } 06736 06737 chan_misdn_log(2, port, " --> * SEND: State Dialing pid:%d\n", newbc ? newbc->pid : 1); 06738 06739 ast_setstate(ast, AST_STATE_DIALING); 06740 ast->hangupcause = AST_CAUSE_NORMAL_CLEARING; 06741 06742 if (newbc->nt) { 06743 stop_bc_tones(ch); 06744 } 06745 06746 ch->state = MISDN_CALLING; 06747 06748 return 0; 06749 }
static int misdn_chan_is_valid | ( | struct chan_list * | ch | ) | [static] |
Definition at line 721 of file chan_misdn.c.
References ast_mutex_lock, ast_mutex_unlock, cl_te, cl_te_lock, and chan_list::next.
Referenced by misdn_hangup().
00722 { 00723 struct chan_list *list; 00724 00725 ast_mutex_lock(&cl_te_lock); 00726 for (list = cl_te; list; list = list->next) { 00727 if (list == ch) { 00728 ast_mutex_unlock(&cl_te_lock); 00729 return 1; 00730 } 00731 } 00732 ast_mutex_unlock(&cl_te_lock); 00733 00734 return 0; 00735 }
static int misdn_check_l2l1 | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Definition at line 12122 of file chan_misdn.c.
References args, AST_APP_ARG, ast_copy_string(), AST_DECLARE_APP_ARGS, ast_log(), ast_safe_sleep(), AST_STANDARD_APP_ARGS, ast_strdupa, ast_strlen_zero(), BUFFERSIZE, chan_misdn_log(), LOG_WARNING, misdn_cfg_get(), misdn_cfg_get_next_port(), MISDN_CFG_GROUPNAME, misdn_lib_get_port_up(), and misdn_lib_port_up().
Referenced by load_module().
12123 { 12124 char *parse; 12125 char group[BUFFERSIZE + 1]; 12126 char *port_str; 12127 int port = 0; 12128 int timeout; 12129 int dowait = 0; 12130 int port_up; 12131 12132 AST_DECLARE_APP_ARGS(args, 12133 AST_APP_ARG(grouppar); 12134 AST_APP_ARG(timeout); 12135 ); 12136 12137 if (ast_strlen_zero((char *) data)) { 12138 ast_log(LOG_WARNING, "misdn_check_l2l1 Requires arguments\n"); 12139 return -1; 12140 } 12141 12142 parse = ast_strdupa(data); 12143 AST_STANDARD_APP_ARGS(args, parse); 12144 12145 if (args.argc != 2) { 12146 ast_log(LOG_WARNING, "Wrong argument count\n"); 12147 return 0; 12148 } 12149 12150 /*ast_log(LOG_NOTICE, "Arguments: group/port '%s' timeout '%s'\n", args.grouppar, args.timeout);*/ 12151 timeout = atoi(args.timeout); 12152 port_str = args.grouppar; 12153 12154 if (port_str[0] == 'g' && port_str[1] == ':') { 12155 /* We make a group call lets checkout which ports are in my group */ 12156 port_str += 2; 12157 ast_copy_string(group, port_str, sizeof(group)); 12158 chan_misdn_log(2, 0, "Checking Ports in group: %s\n", group); 12159 12160 for (port = misdn_cfg_get_next_port(port); 12161 port > 0; 12162 port = misdn_cfg_get_next_port(port)) { 12163 char cfg_group[BUFFERSIZE + 1]; 12164 12165 chan_misdn_log(2, 0, "trying port %d\n", port); 12166 12167 misdn_cfg_get(port, MISDN_CFG_GROUPNAME, cfg_group, sizeof(cfg_group)); 12168 12169 if (!strcasecmp(cfg_group, group)) { 12170 port_up = misdn_lib_port_up(port, 1); 12171 if (!port_up) { 12172 chan_misdn_log(2, 0, " --> port '%d'\n", port); 12173 misdn_lib_get_port_up(port); 12174 dowait = 1; 12175 } 12176 } 12177 } 12178 } else { 12179 port = atoi(port_str); 12180 chan_misdn_log(2, 0, "Checking Port: %d\n", port); 12181 port_up = misdn_lib_port_up(port, 1); 12182 if (!port_up) { 12183 misdn_lib_get_port_up(port); 12184 dowait = 1; 12185 } 12186 } 12187 12188 if (dowait) { 12189 chan_misdn_log(2, 0, "Waiting for '%d' seconds\n", timeout); 12190 ast_safe_sleep(chan, timeout * 1000); 12191 } 12192 12193 return 0; 12194 }
static void misdn_copy_redirecting_from_ast | ( | struct misdn_bchannel * | bc, | |
struct ast_channel * | ast | |||
) | [static] |
Definition at line 6315 of file chan_misdn.c.
References chan_list::ast, ast_copy_string(), ast_to_misdn_plan(), ast_to_misdn_pres(), ast_to_misdn_reason(), ast_to_misdn_screen(), ast_to_misdn_ton(), chan_list::bc, ast_party_redirecting::count, misdn_party_redirecting::count, ast_party_redirecting::from, misdn_party_redirecting::from, ast_party_id::name, misdn_party_id::name, misdn_party_id::number, ast_party_id::number, misdn_party_id::number_plan, misdn_party_id::number_type, NUMPLAN_UNKNOWN, NUMTYPE_UNKNOWN, ast_party_number::plan, ast_party_number::presentation, misdn_party_id::presentation, ast_party_redirecting::reason, misdn_party_redirecting::reason, ast_channel::redirecting, misdn_bchannel::redirecting, S_COR, S_OR, misdn_party_id::screening, ast_party_number::str, ast_party_name::str, ast_party_redirecting::to, misdn_party_redirecting::to, ast_party_number::valid, and ast_party_name::valid.
Referenced by misdn_call(), and misdn_update_redirecting().
06316 { 06317 ast_copy_string(bc->redirecting.from.name, 06318 S_COR(ast->redirecting.from.name.valid, ast->redirecting.from.name.str, ""), 06319 sizeof(bc->redirecting.from.name)); 06320 if (ast->redirecting.from.number.valid) { 06321 ast_copy_string(bc->redirecting.from.number, S_OR(ast->redirecting.from.number.str, ""), 06322 sizeof(bc->redirecting.from.number)); 06323 bc->redirecting.from.presentation = ast_to_misdn_pres(ast->redirecting.from.number.presentation); 06324 bc->redirecting.from.screening = ast_to_misdn_screen(ast->redirecting.from.number.presentation); 06325 bc->redirecting.from.number_type = ast_to_misdn_ton(ast->redirecting.from.number.plan); 06326 bc->redirecting.from.number_plan = ast_to_misdn_plan(ast->redirecting.from.number.plan); 06327 } else { 06328 bc->redirecting.from.number[0] = '\0'; 06329 bc->redirecting.from.presentation = 0;/* Allowed */ 06330 bc->redirecting.from.screening = 0;/* Unscreened */ 06331 bc->redirecting.from.number_type = NUMTYPE_UNKNOWN; 06332 bc->redirecting.from.number_plan = NUMPLAN_UNKNOWN; 06333 } 06334 06335 ast_copy_string(bc->redirecting.to.name, 06336 S_COR(ast->redirecting.to.name.valid, ast->redirecting.to.name.str, ""), 06337 sizeof(bc->redirecting.to.name)); 06338 if (ast->redirecting.to.number.valid) { 06339 ast_copy_string(bc->redirecting.to.number, S_OR(ast->redirecting.to.number.str, ""), 06340 sizeof(bc->redirecting.to.number)); 06341 bc->redirecting.to.presentation = ast_to_misdn_pres(ast->redirecting.to.number.presentation); 06342 bc->redirecting.to.screening = ast_to_misdn_screen(ast->redirecting.to.number.presentation); 06343 bc->redirecting.to.number_type = ast_to_misdn_ton(ast->redirecting.to.number.plan); 06344 bc->redirecting.to.number_plan = ast_to_misdn_plan(ast->redirecting.to.number.plan); 06345 } else { 06346 bc->redirecting.to.number[0] = '\0'; 06347 bc->redirecting.to.presentation = 0;/* Allowed */ 06348 bc->redirecting.to.screening = 0;/* Unscreened */ 06349 bc->redirecting.to.number_type = NUMTYPE_UNKNOWN; 06350 bc->redirecting.to.number_plan = NUMPLAN_UNKNOWN; 06351 } 06352 06353 bc->redirecting.reason = ast_to_misdn_reason(ast->redirecting.reason); 06354 bc->redirecting.count = ast->redirecting.count; 06355 }
static void misdn_copy_redirecting_to_ast | ( | struct ast_channel * | ast, | |
const struct misdn_party_redirecting * | redirect, | |||
char * | tag | |||
) | [static] |
Definition at line 6367 of file chan_misdn.c.
References ast_channel_set_redirecting(), ast_party_redirecting_set_init(), misdn_party_redirecting::count, ast_party_redirecting::count, misdn_party_redirecting::from, ast_party_redirecting::from, misdn_to_ast_plan(), misdn_to_ast_pres(), misdn_to_ast_reason(), misdn_to_ast_screen(), misdn_to_ast_ton(), misdn_party_id::number, ast_party_id::number, misdn_party_id::number_plan, misdn_party_id::number_type, ast_party_number::plan, misdn_party_id::presentation, ast_party_number::presentation, misdn_party_redirecting::reason, ast_party_redirecting::reason, ast_channel::redirecting, misdn_party_id::screening, ast_party_number::str, ast_party_id::tag, misdn_party_redirecting::to, ast_party_redirecting::to, update_redirecting(), and ast_party_number::valid.
Referenced by cb_events(), and misdn_facility_ie_handler().
06368 { 06369 struct ast_party_redirecting redirecting; 06370 struct ast_set_party_redirecting update_redirecting; 06371 06372 ast_party_redirecting_set_init(&redirecting, &ast->redirecting); 06373 memset(&update_redirecting, 0, sizeof(update_redirecting)); 06374 06375 update_redirecting.from.number = 1; 06376 redirecting.from.number.valid = 1; 06377 redirecting.from.number.str = (char *) redirect->from.number; 06378 redirecting.from.number.plan = 06379 misdn_to_ast_ton(redirect->from.number_type) 06380 | misdn_to_ast_plan(redirect->from.number_plan); 06381 redirecting.from.number.presentation = 06382 misdn_to_ast_pres(redirect->from.presentation) 06383 | misdn_to_ast_screen(redirect->from.screening); 06384 redirecting.from.tag = tag; 06385 06386 update_redirecting.to.number = 1; 06387 redirecting.to.number.valid = 1; 06388 redirecting.to.number.str = (char *) redirect->to.number; 06389 redirecting.to.number.plan = 06390 misdn_to_ast_ton(redirect->to.number_type) 06391 | misdn_to_ast_plan(redirect->to.number_plan); 06392 redirecting.to.number.presentation = 06393 misdn_to_ast_pres(redirect->to.presentation) 06394 | misdn_to_ast_screen(redirect->to.screening); 06395 redirecting.to.tag = tag; 06396 06397 redirecting.reason = misdn_to_ast_reason(redirect->reason); 06398 redirecting.count = redirect->count; 06399 06400 ast_channel_set_redirecting(ast, &redirecting, &update_redirecting); 06401 }
static int misdn_digit_begin | ( | struct ast_channel * | chan, | |
char | digit | |||
) | [static] |
Definition at line 6837 of file chan_misdn.c.
06838 { 06839 /* XXX Modify this callback to support Asterisk controlling the length of DTMF */ 06840 return 0; 06841 }
static int misdn_digit_end | ( | struct ast_channel * | ast, | |
char | digit, | |||
unsigned int | duration | |||
) | [static] |
Definition at line 6843 of file chan_misdn.c.
References chan_list::ast, ast_copy_string(), ast_log(), chan_list::bc, chan_misdn_log(), misdn_bchannel::dialed, EVENT_INFORMATION, ast_channel::exten, misdn_bchannel::info_dad, misdn_bchannel::infos_pending, LOG_WARNING, MISDN_ASTERISK_TECH_PVT, MISDN_CALLING, MISDN_CALLING_ACKNOWLEDGE, misdn_lib_send_event(), misdn_party_dialing::number, misdn_bchannel::port, send_digit_to_chan(), misdn_bchannel::send_dtmf, and chan_list::state.
06844 { 06845 struct chan_list *p; 06846 struct misdn_bchannel *bc; 06847 char buf[2] = { digit, 0 }; 06848 06849 if (!ast || !(p = MISDN_ASTERISK_TECH_PVT(ast))) { 06850 return -1; 06851 } 06852 06853 bc = p->bc; 06854 chan_misdn_log(1, bc ? bc->port : 0, "* IND : Digit %c\n", digit); 06855 06856 if (!bc) { 06857 ast_log(LOG_WARNING, " --> !! Got Digit Event without having bchannel Object\n"); 06858 return -1; 06859 } 06860 06861 switch (p->state) { 06862 case MISDN_CALLING: 06863 if (strlen(bc->infos_pending) < sizeof(bc->infos_pending) - 1) { 06864 strncat(bc->infos_pending, buf, sizeof(bc->infos_pending) - strlen(bc->infos_pending) - 1); 06865 } 06866 break; 06867 case MISDN_CALLING_ACKNOWLEDGE: 06868 ast_copy_string(bc->info_dad, buf, sizeof(bc->info_dad)); 06869 if (strlen(bc->dialed.number) < sizeof(bc->dialed.number) - 1) { 06870 strncat(bc->dialed.number, buf, sizeof(bc->dialed.number) - strlen(bc->dialed.number) - 1); 06871 } 06872 ast_copy_string(p->ast->exten, bc->dialed.number, sizeof(p->ast->exten)); 06873 misdn_lib_send_event(bc, EVENT_INFORMATION); 06874 break; 06875 default: 06876 if (bc->send_dtmf) { 06877 send_digit_to_chan(p, digit); 06878 } 06879 break; 06880 } 06881 06882 return 0; 06883 }
static int misdn_facility_exec | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Definition at line 11999 of file chan_misdn.c.
References args, AST_APP_ARG, AST_DECLARE_APP_ARGS, ast_log(), AST_STANDARD_APP_ARGS, ast_strdupa, ast_strlen_zero(), chan_list::bc, chan_misdn_log(), EVENT_FACILITY, misdn_bchannel::fac_out, LOG_WARNING, MISDN_ASTERISK_TECH_PVT, misdn_lib_send_event(), misdn_type, misdn_bchannel::port, print_facility(), ast_channel::tech, and ast_channel_tech::type.
Referenced by load_module().
12000 { 12001 struct chan_list *ch = MISDN_ASTERISK_TECH_PVT(chan); 12002 char *parse; 12003 unsigned max_len; 12004 12005 AST_DECLARE_APP_ARGS(args, 12006 AST_APP_ARG(facility_type); 12007 AST_APP_ARG(arg)[99]; 12008 ); 12009 12010 chan_misdn_log(0, 0, "TYPE: %s\n", chan->tech->type); 12011 12012 if (strcasecmp(chan->tech->type, misdn_type)) { 12013 ast_log(LOG_WARNING, "misdn_facility only makes sense with %s channels!\n", misdn_type); 12014 return -1; 12015 } 12016 12017 if (ast_strlen_zero((char *) data)) { 12018 ast_log(LOG_WARNING, "misdn_facility requires arguments: facility_type[,<args>]\n"); 12019 return -1; 12020 } 12021 12022 parse = ast_strdupa(data); 12023 AST_STANDARD_APP_ARGS(args, parse); 12024 12025 if (ast_strlen_zero(args.facility_type)) { 12026 ast_log(LOG_WARNING, "misdn_facility requires arguments: facility_type[,<args>]\n"); 12027 return -1; 12028 } 12029 12030 if (!strcasecmp(args.facility_type, "calldeflect")) { 12031 if (ast_strlen_zero(args.arg[0])) { 12032 ast_log(LOG_WARNING, "Facility: Call Deflection requires an argument: Number\n"); 12033 } 12034 12035 #if defined(AST_MISDN_ENHANCEMENTS) 12036 max_len = sizeof(ch->bc->fac_out.u.CallDeflection.Component.Invoke.Deflection.Party.Number) - 1; 12037 if (max_len < strlen(args.arg[0])) { 12038 ast_log(LOG_WARNING, 12039 "Facility: Number argument too long (up to %u digits are allowed). Ignoring.\n", 12040 max_len); 12041 return 0; 12042 } 12043 ch->bc->fac_out.Function = Fac_CallDeflection; 12044 ch->bc->fac_out.u.CallDeflection.InvokeID = ++misdn_invoke_id; 12045 ch->bc->fac_out.u.CallDeflection.ComponentType = FacComponent_Invoke; 12046 ch->bc->fac_out.u.CallDeflection.Component.Invoke.PresentationAllowedToDivertedToUserPresent = 1; 12047 ch->bc->fac_out.u.CallDeflection.Component.Invoke.PresentationAllowedToDivertedToUser = 0; 12048 ch->bc->fac_out.u.CallDeflection.Component.Invoke.Deflection.Party.Type = 0;/* unknown */ 12049 ch->bc->fac_out.u.CallDeflection.Component.Invoke.Deflection.Party.LengthOfNumber = strlen(args.arg[0]); 12050 strcpy((char *) ch->bc->fac_out.u.CallDeflection.Component.Invoke.Deflection.Party.Number, args.arg[0]); 12051 ch->bc->fac_out.u.CallDeflection.Component.Invoke.Deflection.Subaddress.Length = 0; 12052 12053 #else /* !defined(AST_MISDN_ENHANCEMENTS) */ 12054 12055 max_len = sizeof(ch->bc->fac_out.u.CDeflection.DeflectedToNumber) - 1; 12056 if (max_len < strlen(args.arg[0])) { 12057 ast_log(LOG_WARNING, 12058 "Facility: Number argument too long (up to %u digits are allowed). Ignoring.\n", 12059 max_len); 12060 return 0; 12061 } 12062 ch->bc->fac_out.Function = Fac_CD; 12063 ch->bc->fac_out.u.CDeflection.PresentationAllowed = 0; 12064 //ch->bc->fac_out.u.CDeflection.DeflectedToSubaddress[0] = 0; 12065 strcpy((char *) ch->bc->fac_out.u.CDeflection.DeflectedToNumber, args.arg[0]); 12066 #endif /* !defined(AST_MISDN_ENHANCEMENTS) */ 12067 12068 /* Send message */ 12069 print_facility(&ch->bc->fac_out, ch->bc); 12070 misdn_lib_send_event(ch->bc, EVENT_FACILITY); 12071 #if defined(AST_MISDN_ENHANCEMENTS) 12072 } else if (!strcasecmp(args.facility_type, "callrerouteing") 12073 || !strcasecmp(args.facility_type, "callrerouting")) { 12074 if (ast_strlen_zero(args.arg[0])) { 12075 ast_log(LOG_WARNING, "Facility: Call rerouting requires an argument: Number\n"); 12076 } 12077 12078 max_len = sizeof(ch->bc->fac_out.u.CallRerouteing.Component.Invoke.CalledAddress.Party.Number) - 1; 12079 if (max_len < strlen(args.arg[0])) { 12080 ast_log(LOG_WARNING, 12081 "Facility: Number argument too long (up to %u digits are allowed). Ignoring.\n", 12082 max_len); 12083 return 0; 12084 } 12085 ch->bc->fac_out.Function = Fac_CallRerouteing; 12086 ch->bc->fac_out.u.CallRerouteing.InvokeID = ++misdn_invoke_id; 12087 ch->bc->fac_out.u.CallRerouteing.ComponentType = FacComponent_Invoke; 12088 12089 ch->bc->fac_out.u.CallRerouteing.Component.Invoke.ReroutingReason = 0;/* unknown */ 12090 ch->bc->fac_out.u.CallRerouteing.Component.Invoke.ReroutingCounter = 1; 12091 12092 ch->bc->fac_out.u.CallRerouteing.Component.Invoke.CalledAddress.Party.Type = 0;/* unknown */ 12093 ch->bc->fac_out.u.CallRerouteing.Component.Invoke.CalledAddress.Party.LengthOfNumber = strlen(args.arg[0]); 12094 strcpy((char *) ch->bc->fac_out.u.CallRerouteing.Component.Invoke.CalledAddress.Party.Number, args.arg[0]); 12095 ch->bc->fac_out.u.CallRerouteing.Component.Invoke.CalledAddress.Subaddress.Length = 0; 12096 12097 ch->bc->fac_out.u.CallRerouteing.Component.Invoke.CallingPartySubaddress.Length = 0; 12098 12099 /* 0x90 0x90 0xa3 3.1 kHz audio, circuit mode, 64kbit/sec, level1/a-Law */ 12100 ch->bc->fac_out.u.CallRerouteing.Component.Invoke.Q931ie.Bc.Length = 3; 12101 ch->bc->fac_out.u.CallRerouteing.Component.Invoke.Q931ie.Bc.Contents[0] = 0x90; 12102 ch->bc->fac_out.u.CallRerouteing.Component.Invoke.Q931ie.Bc.Contents[1] = 0x90; 12103 ch->bc->fac_out.u.CallRerouteing.Component.Invoke.Q931ie.Bc.Contents[2] = 0xa3; 12104 ch->bc->fac_out.u.CallRerouteing.Component.Invoke.Q931ie.Hlc.Length = 0; 12105 ch->bc->fac_out.u.CallRerouteing.Component.Invoke.Q931ie.Llc.Length = 0; 12106 ch->bc->fac_out.u.CallRerouteing.Component.Invoke.Q931ie.UserInfo.Length = 0; 12107 12108 ch->bc->fac_out.u.CallRerouteing.Component.Invoke.LastRerouting.Type = 1;/* presentationRestricted */ 12109 ch->bc->fac_out.u.CallRerouteing.Component.Invoke.SubscriptionOption = 0;/* no notification to caller */ 12110 12111 /* Send message */ 12112 print_facility(&ch->bc->fac_out, ch->bc); 12113 misdn_lib_send_event(ch->bc, EVENT_FACILITY); 12114 #endif /* defined(AST_MISDN_ENHANCEMENTS) */ 12115 } else { 12116 chan_misdn_log(1, ch->bc->port, "Unknown Facility: %s\n", args.facility_type); 12117 } 12118 12119 return 0; 12120 }
static void misdn_facility_ie_handler | ( | enum event_e | event, | |
struct misdn_bchannel * | bc, | |||
struct chan_list * | ch | |||
) | [static] |
Definition at line 9023 of file chan_misdn.c.
References misdn_bchannel::AOCD, misdn_bchannel::AOCD_need_export, misdn_bchannel::AOCDtype, chan_list::ast, AST_CAUSE_NORMAL_CLEARING, ast_channel_queue_redirecting_update(), AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER, AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER_ALERTING, AST_CONTROL_BUSY, ast_copy_string(), AST_LIST_LOCK, AST_LIST_UNLOCK, AST_PRES_ALLOWED, AST_PRES_RESTRICTED, AST_PRES_USER_NUMBER_UNSCREENED, ast_queue_control(), ast_string_field_set, misdn_bchannel::caller, misdn_bchannel::capability, chan_misdn_log(), misdn_bchannel::chargingUnit, misdn_party_redirecting::count, misdn_bchannel::currency, misdn_bchannel::dialed, EVENT_ALERTING, EVENT_DISCONNECT, EVENT_RELEASE, EVENT_RELEASE_COMPLETE, EVENT_SETUP, export_aoc_vars(), misdn_bchannel::fac_in, misdn_bchannel::fac_out, misdn_party_redirecting::from, misdn_bchannel::hdlc, misdn_bchannel::incoming_cid_tag, misdn_add_number_prefix(), misdn_copy_redirecting_to_ast(), misdn_lib_send_event(), mISDN_NOTIFY_CODE_CALL_TRANSFER_ACTIVE, mISDN_NOTIFY_CODE_CALL_TRANSFER_ALERTING, mISDN_NOTIFY_CODE_INVALID, mISDN_REDIRECTING_REASON_DEFLECTION, misdn_update_remote_party(), misdn_party_id::name, misdn_bchannel::notify_description_code, ast_party_id::number, misdn_party_dialing::number, misdn_party_id::number, misdn_party_dialing::number_plan, misdn_party_id::number_plan, misdn_party_dialing::number_type, misdn_party_id::number_type, NUMPLAN_ISDN, NUMPLAN_UNKNOWN, NUMTYPE_UNKNOWN, chan_list::originator, misdn_bchannel::port, ast_party_number::presentation, misdn_party_id::presentation, print_facility(), misdn_party_redirecting::reason, ast_channel::redirecting, misdn_bchannel::redirecting, misdn_party_id::screening, ast_party_redirecting::to, misdn_party_redirecting::to, and misdn_party_redirecting::to_changed.
Referenced by cb_events().
09024 { 09025 #if defined(AST_MISDN_ENHANCEMENTS) 09026 const char *diagnostic_msg; 09027 struct misdn_cc_record *cc_record; 09028 char buf[32]; 09029 struct misdn_party_id party_id; 09030 long new_record_id; 09031 #endif /* defined(AST_MISDN_ENHANCEMENTS) */ 09032 09033 print_facility(&bc->fac_in, bc); 09034 switch (bc->fac_in.Function) { 09035 #if defined(AST_MISDN_ENHANCEMENTS) 09036 case Fac_ActivationDiversion: 09037 switch (bc->fac_in.u.ActivationDiversion.ComponentType) { 09038 case FacComponent_Result: 09039 /* Positive ACK to activation */ 09040 /* We don't handle this yet */ 09041 break; 09042 default: 09043 chan_misdn_log(0, bc->port," --> not yet handled: facility type:0x%04X\n", 09044 bc->fac_in.Function); 09045 break; 09046 } 09047 break; 09048 case Fac_DeactivationDiversion: 09049 switch (bc->fac_in.u.DeactivationDiversion.ComponentType) { 09050 case FacComponent_Result: 09051 /* Positive ACK to deactivation */ 09052 /* We don't handle this yet */ 09053 break; 09054 default: 09055 chan_misdn_log(0, bc->port," --> not yet handled: facility type:0x%04X\n", 09056 bc->fac_in.Function); 09057 break; 09058 } 09059 break; 09060 case Fac_ActivationStatusNotificationDiv: 09061 /* Sent to other MSN numbers on the line when a user activates call forwarding. */ 09062 /* Sent in the first call control message of an outgoing call from the served user. */ 09063 /* We do not have anything to do for this message. */ 09064 break; 09065 case Fac_DeactivationStatusNotificationDiv: 09066 /* Sent to other MSN numbers on the line when a user deactivates call forwarding. */ 09067 /* We do not have anything to do for this message. */ 09068 break; 09069 #if 0 /* We don't handle this yet */ 09070 case Fac_InterrogationDiversion: 09071 /* We don't handle this yet */ 09072 break; 09073 case Fac_InterrogateServedUserNumbers: 09074 /* We don't handle this yet */ 09075 break; 09076 #endif /* We don't handle this yet */ 09077 case Fac_DiversionInformation: 09078 /* Sent to the served user when a call is forwarded. */ 09079 /* We do not have anything to do for this message. */ 09080 break; 09081 case Fac_CallDeflection: 09082 if (ch && ch->ast) { 09083 switch (bc->fac_in.u.CallDeflection.ComponentType) { 09084 case FacComponent_Invoke: 09085 ast_copy_string(bc->redirecting.from.number, bc->dialed.number, 09086 sizeof(bc->redirecting.from.number)); 09087 bc->redirecting.from.name[0] = 0; 09088 bc->redirecting.from.number_plan = bc->dialed.number_plan; 09089 bc->redirecting.from.number_type = bc->dialed.number_type; 09090 bc->redirecting.from.screening = 0;/* Unscreened */ 09091 if (bc->fac_in.u.CallDeflection.Component.Invoke.PresentationAllowedToDivertedToUserPresent) { 09092 bc->redirecting.from.presentation = 09093 bc->fac_in.u.CallDeflection.Component.Invoke.PresentationAllowedToDivertedToUser 09094 ? 0 /* Allowed */ : 1 /* Restricted */; 09095 } else { 09096 bc->redirecting.from.presentation = 0;/* Allowed */ 09097 } 09098 09099 /* Add configured prefix to the call deflection number */ 09100 memset(&party_id, 0, sizeof(party_id)); 09101 misdn_PartyNumber_extract(&party_id, 09102 &bc->fac_in.u.CallDeflection.Component.Invoke.Deflection.Party); 09103 misdn_add_number_prefix(bc->port, party_id.number_type, 09104 party_id.number, sizeof(party_id.number)); 09105 //party_id.presentation = 0;/* Allowed */ 09106 //party_id.screening = 0;/* Unscreened */ 09107 bc->redirecting.to = party_id; 09108 09109 ++bc->redirecting.count; 09110 bc->redirecting.reason = mISDN_REDIRECTING_REASON_DEFLECTION; 09111 09112 misdn_copy_redirecting_to_ast(ch->ast, &bc->redirecting, bc->incoming_cid_tag); 09113 ast_string_field_set(ch->ast, call_forward, bc->redirecting.to.number); 09114 09115 /* Send back positive ACK */ 09116 #if 1 09117 /* 09118 * Since there are no return result arguments it must be a 09119 * generic result message. ETSI 300-196 09120 */ 09121 bc->fac_out.Function = Fac_RESULT; 09122 bc->fac_out.u.RESULT.InvokeID = bc->fac_in.u.CallDeflection.InvokeID; 09123 #else 09124 bc->fac_out.Function = Fac_CallDeflection; 09125 bc->fac_out.u.CallDeflection.InvokeID = bc->fac_in.u.CallDeflection.InvokeID; 09126 bc->fac_out.u.CallDeflection.ComponentType = FacComponent_Result; 09127 #endif 09128 print_facility(&bc->fac_out, bc); 09129 misdn_lib_send_event(bc, EVENT_DISCONNECT); 09130 09131 /* This line is BUSY to further attempts by this dialing attempt. */ 09132 ast_queue_control(ch->ast, AST_CONTROL_BUSY); 09133 break; 09134 09135 case FacComponent_Result: 09136 /* Positive ACK to call deflection */ 09137 /* 09138 * Sent in DISCONNECT or FACILITY message depending upon network option. 09139 * It is in the FACILITY message if the call is still offered to the user 09140 * while trying to alert the deflected to party. 09141 */ 09142 /* Ignore the ACK */ 09143 break; 09144 09145 default: 09146 break; 09147 } 09148 } 09149 break; 09150 #if 0 /* We don't handle this yet */ 09151 case Fac_CallRerouteing: 09152 /* Private-Public ISDN interworking message */ 09153 /* We don't handle this yet */ 09154 break; 09155 #endif /* We don't handle this yet */ 09156 case Fac_DivertingLegInformation1: 09157 /* Private-Public ISDN interworking message */ 09158 bc->div_leg_3_rx_wanted = 0; 09159 if (ch && ch->ast) { 09160 bc->redirecting.reason = 09161 diversion_reason_to_misdn(bc->fac_in.u.DivertingLegInformation1.DiversionReason); 09162 if (bc->fac_in.u.DivertingLegInformation1.DivertedToPresent) { 09163 misdn_PresentedNumberUnscreened_extract(&bc->redirecting.to, 09164 &bc->fac_in.u.DivertingLegInformation1.DivertedTo); 09165 09166 /* Add configured prefix to redirecting.to.number */ 09167 misdn_add_number_prefix(bc->port, bc->redirecting.to.number_type, 09168 bc->redirecting.to.number, sizeof(bc->redirecting.to.number)); 09169 } else { 09170 bc->redirecting.to.number[0] = '\0'; 09171 bc->redirecting.to.number_plan = NUMPLAN_ISDN; 09172 bc->redirecting.to.number_type = NUMTYPE_UNKNOWN; 09173 bc->redirecting.to.presentation = 1;/* restricted */ 09174 bc->redirecting.to.screening = 0;/* unscreened */ 09175 } 09176 misdn_copy_redirecting_to_ast(ch->ast, &bc->redirecting, bc->incoming_cid_tag); 09177 bc->div_leg_3_rx_wanted = 1; 09178 } 09179 break; 09180 case Fac_DivertingLegInformation2: 09181 /* Private-Public ISDN interworking message */ 09182 switch (event) { 09183 case EVENT_SETUP: 09184 /* Comes in on a SETUP with redirecting.from information */ 09185 bc->div_leg_3_tx_pending = 1; 09186 if (ch && ch->ast) { 09187 /* 09188 * Setup the redirecting.to informtion so we can identify 09189 * if the user wants to manually supply the COLR for this 09190 * redirected to number if further redirects could happen. 09191 * 09192 * All the user needs to do is set the REDIRECTING(to-pres) 09193 * to the COLR and REDIRECTING(to-num) = ${EXTEN} to be safe 09194 * after determining that the incoming call was redirected by 09195 * checking if there is a REDIRECTING(from-num). 09196 */ 09197 ast_copy_string(bc->redirecting.to.number, bc->dialed.number, 09198 sizeof(bc->redirecting.to.number)); 09199 bc->redirecting.to.number_plan = bc->dialed.number_plan; 09200 bc->redirecting.to.number_type = bc->dialed.number_type; 09201 bc->redirecting.to.presentation = 1;/* restricted */ 09202 bc->redirecting.to.screening = 0;/* unscreened */ 09203 09204 bc->redirecting.reason = 09205 diversion_reason_to_misdn(bc->fac_in.u.DivertingLegInformation2.DiversionReason); 09206 bc->redirecting.count = bc->fac_in.u.DivertingLegInformation2.DiversionCounter; 09207 if (bc->fac_in.u.DivertingLegInformation2.DivertingPresent) { 09208 /* This information is redundant if there was a redirecting ie in the SETUP. */ 09209 misdn_PresentedNumberUnscreened_extract(&bc->redirecting.from, 09210 &bc->fac_in.u.DivertingLegInformation2.Diverting); 09211 09212 /* Add configured prefix to redirecting.from.number */ 09213 misdn_add_number_prefix(bc->port, bc->redirecting.from.number_type, 09214 bc->redirecting.from.number, sizeof(bc->redirecting.from.number)); 09215 } 09216 #if 0 09217 if (bc->fac_in.u.DivertingLegInformation2.OriginalCalledPresent) { 09218 /* We have no place to put the OriginalCalled number */ 09219 } 09220 #endif 09221 misdn_copy_redirecting_to_ast(ch->ast, &bc->redirecting, bc->incoming_cid_tag); 09222 } 09223 break; 09224 default: 09225 chan_misdn_log(0, bc->port," --> Expected in a SETUP message: facility type:0x%04X\n", 09226 bc->fac_in.Function); 09227 break; 09228 } 09229 break; 09230 case Fac_DivertingLegInformation3: 09231 /* Private-Public ISDN interworking message */ 09232 if (bc->div_leg_3_rx_wanted) { 09233 bc->div_leg_3_rx_wanted = 0; 09234 09235 if (ch && ch->ast) { 09236 ch->ast->redirecting.to.number.presentation = 09237 bc->fac_in.u.DivertingLegInformation3.PresentationAllowedIndicator 09238 ? AST_PRES_ALLOWED | AST_PRES_USER_NUMBER_UNSCREENED 09239 : AST_PRES_RESTRICTED | AST_PRES_USER_NUMBER_UNSCREENED; 09240 ast_channel_queue_redirecting_update(ch->ast, &ch->ast->redirecting, NULL); 09241 } 09242 } 09243 break; 09244 09245 #else /* !defined(AST_MISDN_ENHANCEMENTS) */ 09246 09247 case Fac_CD: 09248 if (ch && ch->ast) { 09249 ast_copy_string(bc->redirecting.from.number, bc->dialed.number, 09250 sizeof(bc->redirecting.from.number)); 09251 bc->redirecting.from.name[0] = 0; 09252 bc->redirecting.from.number_plan = bc->dialed.number_plan; 09253 bc->redirecting.from.number_type = bc->dialed.number_type; 09254 bc->redirecting.from.screening = 0;/* Unscreened */ 09255 bc->redirecting.from.presentation = 09256 bc->fac_in.u.CDeflection.PresentationAllowed 09257 ? 0 /* Allowed */ : 1 /* Restricted */; 09258 09259 ast_copy_string(bc->redirecting.to.number, 09260 (char *) bc->fac_in.u.CDeflection.DeflectedToNumber, 09261 sizeof(bc->redirecting.to.number)); 09262 bc->redirecting.to.name[0] = 0; 09263 bc->redirecting.to.number_plan = NUMPLAN_UNKNOWN; 09264 bc->redirecting.to.number_type = NUMTYPE_UNKNOWN; 09265 bc->redirecting.to.presentation = 0;/* Allowed */ 09266 bc->redirecting.to.screening = 0;/* Unscreened */ 09267 09268 ++bc->redirecting.count; 09269 bc->redirecting.reason = mISDN_REDIRECTING_REASON_DEFLECTION; 09270 09271 misdn_copy_redirecting_to_ast(ch->ast, &bc->redirecting, bc->incoming_cid_tag); 09272 ast_string_field_set(ch->ast, call_forward, bc->redirecting.to.number); 09273 09274 misdn_lib_send_event(bc, EVENT_DISCONNECT); 09275 09276 /* This line is BUSY to further attempts by this dialing attempt. */ 09277 ast_queue_control(ch->ast, AST_CONTROL_BUSY); 09278 } 09279 break; 09280 #endif /* !defined(AST_MISDN_ENHANCEMENTS) */ 09281 case Fac_AOCDCurrency: 09282 if (ch && ch->ast) { 09283 bc->AOCDtype = Fac_AOCDCurrency; 09284 memcpy(&bc->AOCD.currency, &bc->fac_in.u.AOCDcur, sizeof(bc->AOCD.currency)); 09285 bc->AOCD_need_export = 1; 09286 export_aoc_vars(ch->originator, ch->ast, bc); 09287 } 09288 break; 09289 case Fac_AOCDChargingUnit: 09290 if (ch && ch->ast) { 09291 bc->AOCDtype = Fac_AOCDChargingUnit; 09292 memcpy(&bc->AOCD.chargingUnit, &bc->fac_in.u.AOCDchu, sizeof(bc->AOCD.chargingUnit)); 09293 bc->AOCD_need_export = 1; 09294 export_aoc_vars(ch->originator, ch->ast, bc); 09295 } 09296 break; 09297 #if defined(AST_MISDN_ENHANCEMENTS) 09298 case Fac_ERROR: 09299 diagnostic_msg = misdn_to_str_error_code(bc->fac_in.u.ERROR.errorValue); 09300 chan_misdn_log(1, bc->port, " --> Facility error code: %s\n", diagnostic_msg); 09301 switch (event) { 09302 case EVENT_DISCONNECT: 09303 case EVENT_RELEASE: 09304 case EVENT_RELEASE_COMPLETE: 09305 /* Possible call failure as a result of Fac_CCBSCall/Fac_CCBS_T_Call */ 09306 if (ch && ch->peer) { 09307 misdn_cc_set_peer_var(ch->peer, MISDN_ERROR_MSG, diagnostic_msg); 09308 } 09309 break; 09310 default: 09311 break; 09312 } 09313 AST_LIST_LOCK(&misdn_cc_records_db); 09314 cc_record = misdn_cc_find_by_invoke(bc->port, bc->fac_in.u.ERROR.invokeId); 09315 if (cc_record) { 09316 cc_record->outstanding_message = 0; 09317 cc_record->error_code = bc->fac_in.u.ERROR.errorValue; 09318 } 09319 AST_LIST_UNLOCK(&misdn_cc_records_db); 09320 break; 09321 case Fac_REJECT: 09322 diagnostic_msg = misdn_to_str_reject_code(bc->fac_in.u.REJECT.Code); 09323 chan_misdn_log(1, bc->port, " --> Facility reject code: %s\n", diagnostic_msg); 09324 switch (event) { 09325 case EVENT_DISCONNECT: 09326 case EVENT_RELEASE: 09327 case EVENT_RELEASE_COMPLETE: 09328 /* Possible call failure as a result of Fac_CCBSCall/Fac_CCBS_T_Call */ 09329 if (ch && ch->peer) { 09330 misdn_cc_set_peer_var(ch->peer, MISDN_ERROR_MSG, diagnostic_msg); 09331 } 09332 break; 09333 default: 09334 break; 09335 } 09336 if (bc->fac_in.u.REJECT.InvokeIDPresent) { 09337 AST_LIST_LOCK(&misdn_cc_records_db); 09338 cc_record = misdn_cc_find_by_invoke(bc->port, bc->fac_in.u.REJECT.InvokeID); 09339 if (cc_record) { 09340 cc_record->outstanding_message = 0; 09341 cc_record->reject_code = bc->fac_in.u.REJECT.Code; 09342 } 09343 AST_LIST_UNLOCK(&misdn_cc_records_db); 09344 } 09345 break; 09346 case Fac_RESULT: 09347 AST_LIST_LOCK(&misdn_cc_records_db); 09348 cc_record = misdn_cc_find_by_invoke(bc->port, bc->fac_in.u.RESULT.InvokeID); 09349 if (cc_record) { 09350 cc_record->outstanding_message = 0; 09351 } 09352 AST_LIST_UNLOCK(&misdn_cc_records_db); 09353 break; 09354 #if 0 /* We don't handle this yet */ 09355 case Fac_EctExecute: 09356 /* We don't handle this yet */ 09357 break; 09358 case Fac_ExplicitEctExecute: 09359 /* We don't handle this yet */ 09360 break; 09361 case Fac_EctLinkIdRequest: 09362 /* We don't handle this yet */ 09363 break; 09364 #endif /* We don't handle this yet */ 09365 case Fac_SubaddressTransfer: 09366 /* We do not have anything to do for this message since we do not handle subaddreses. */ 09367 break; 09368 case Fac_RequestSubaddress: 09369 /* 09370 * We do not have anything to do for this message since we do not handle subaddreses. 09371 * However, we do care about some other ie's that should be present. 09372 */ 09373 if (bc->redirecting.to_changed) { 09374 /* Add configured prefix to redirecting.to.number */ 09375 misdn_add_number_prefix(bc->port, bc->redirecting.to.number_type, 09376 bc->redirecting.to.number, sizeof(bc->redirecting.to.number)); 09377 } 09378 switch (bc->notify_description_code) { 09379 case mISDN_NOTIFY_CODE_INVALID: 09380 /* Notify ie was not present. */ 09381 bc->redirecting.to_changed = 0; 09382 break; 09383 case mISDN_NOTIFY_CODE_CALL_TRANSFER_ALERTING: 09384 /* 09385 * It would be preferable to update the connected line information 09386 * only when the message callStatus is active. However, the 09387 * optional redirection number may not be present in the active 09388 * message if an alerting message were received earlier. 09389 * 09390 * The consequences if we wind up sending two updates is benign. 09391 * The other end will think that it got transferred twice. 09392 */ 09393 if (!bc->redirecting.to_changed) { 09394 break; 09395 } 09396 bc->redirecting.to_changed = 0; 09397 if (!ch || !ch->ast) { 09398 break; 09399 } 09400 misdn_update_remote_party(ch->ast, &bc->redirecting.to, 09401 AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER_ALERTING, 09402 bc->incoming_cid_tag); 09403 break; 09404 case mISDN_NOTIFY_CODE_CALL_TRANSFER_ACTIVE: 09405 if (!bc->redirecting.to_changed) { 09406 break; 09407 } 09408 bc->redirecting.to_changed = 0; 09409 if (!ch || !ch->ast) { 09410 break; 09411 } 09412 misdn_update_remote_party(ch->ast, &bc->redirecting.to, 09413 AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER, bc->incoming_cid_tag); 09414 break; 09415 default: 09416 bc->redirecting.to_changed = 0; 09417 chan_misdn_log(0, bc->port," --> not yet handled: notify code:0x%02X\n", 09418 bc->notify_description_code); 09419 break; 09420 } 09421 bc->notify_description_code = mISDN_NOTIFY_CODE_INVALID; 09422 break; 09423 case Fac_EctInform: 09424 /* Private-Public ISDN interworking message */ 09425 if (ch && ch->ast && bc->fac_in.u.EctInform.RedirectionPresent) { 09426 /* Add configured prefix to the redirection number */ 09427 memset(&party_id, 0, sizeof(party_id)); 09428 misdn_PresentedNumberUnscreened_extract(&party_id, 09429 &bc->fac_in.u.EctInform.Redirection); 09430 misdn_add_number_prefix(bc->port, party_id.number_type, 09431 party_id.number, sizeof(party_id.number)); 09432 09433 /* 09434 * It would be preferable to update the connected line information 09435 * only when the message callStatus is active. However, the 09436 * optional redirection number may not be present in the active 09437 * message if an alerting message were received earlier. 09438 * 09439 * The consequences if we wind up sending two updates is benign. 09440 * The other end will think that it got transferred twice. 09441 */ 09442 misdn_update_remote_party(ch->ast, &party_id, 09443 (bc->fac_in.u.EctInform.Status == 0 /* alerting */) 09444 ? AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER_ALERTING 09445 : AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER, 09446 bc->incoming_cid_tag); 09447 } 09448 break; 09449 #if 0 /* We don't handle this yet */ 09450 case Fac_EctLoopTest: 09451 /* The use of this message is unclear on how it works to detect loops. */ 09452 /* We don't handle this yet */ 09453 break; 09454 #endif /* We don't handle this yet */ 09455 case Fac_CallInfoRetain: 09456 switch (event) { 09457 case EVENT_ALERTING: 09458 case EVENT_DISCONNECT: 09459 /* CCBS/CCNR is available */ 09460 if (ch && ch->peer) { 09461 AST_LIST_LOCK(&misdn_cc_records_db); 09462 if (ch->record_id == -1) { 09463 cc_record = misdn_cc_new(); 09464 } else { 09465 /* 09466 * We are doing a call-completion attempt 09467 * or the switch is sending us extra call-completion 09468 * availability indications (erroneously?). 09469 * 09470 * Assume that the network request retention option 09471 * is not on and that the current call-completion 09472 * request is disabled. 09473 */ 09474 cc_record = misdn_cc_find_by_id(ch->record_id); 09475 if (cc_record) { 09476 if (cc_record->ptp && cc_record->mode.ptp.bc) { 09477 /* 09478 * What? We are getting mixed messages from the 09479 * switch. We are currently setup for 09480 * point-to-point. Now we are switching to 09481 * point-to-multipoint. 09482 * 09483 * Close the call-completion signaling link 09484 */ 09485 cc_record->mode.ptp.bc->fac_out.Function = Fac_None; 09486 cc_record->mode.ptp.bc->out_cause = AST_CAUSE_NORMAL_CLEARING; 09487 misdn_lib_send_event(cc_record->mode.ptp.bc, EVENT_RELEASE_COMPLETE); 09488 } 09489 09490 /* 09491 * Resetup the existing record for a possible new 09492 * call-completion request. 09493 */ 09494 new_record_id = misdn_cc_record_id_new(); 09495 if (new_record_id < 0) { 09496 /* Looks like we must keep the old id anyway. */ 09497 } else { 09498 cc_record->record_id = new_record_id; 09499 ch->record_id = new_record_id; 09500 } 09501 cc_record->ptp = 0; 09502 cc_record->port = bc->port; 09503 memset(&cc_record->mode, 0, sizeof(cc_record->mode)); 09504 cc_record->mode.ptmp.linkage_id = bc->fac_in.u.CallInfoRetain.CallLinkageID; 09505 cc_record->invoke_id = ++misdn_invoke_id; 09506 cc_record->activated = 0; 09507 cc_record->outstanding_message = 0; 09508 cc_record->activation_requested = 0; 09509 cc_record->error_code = FacError_None; 09510 cc_record->reject_code = FacReject_None; 09511 memset(&cc_record->remote_user_free, 0, sizeof(cc_record->remote_user_free)); 09512 memset(&cc_record->b_free, 0, sizeof(cc_record->b_free)); 09513 cc_record->time_created = time(NULL); 09514 09515 cc_record = NULL; 09516 } else { 09517 /* 09518 * Where did the record go? We will have to recapture 09519 * the call setup information. Unfortunately, some 09520 * setup information may have been changed. 09521 */ 09522 ch->record_id = -1; 09523 cc_record = misdn_cc_new(); 09524 } 09525 } 09526 if (cc_record) { 09527 ch->record_id = cc_record->record_id; 09528 cc_record->ptp = 0; 09529 cc_record->port = bc->port; 09530 cc_record->mode.ptmp.linkage_id = bc->fac_in.u.CallInfoRetain.CallLinkageID; 09531 09532 /* Record call information for possible call-completion attempt. */ 09533 cc_record->redial.caller = bc->caller; 09534 cc_record->redial.dialed = bc->dialed; 09535 cc_record->redial.setup_bc_hlc_llc = bc->setup_bc_hlc_llc; 09536 cc_record->redial.capability = bc->capability; 09537 cc_record->redial.hdlc = bc->hdlc; 09538 } 09539 AST_LIST_UNLOCK(&misdn_cc_records_db); 09540 09541 /* Set MISDN_CC_RECORD_ID in original channel */ 09542 if (ch->record_id != -1) { 09543 snprintf(buf, sizeof(buf), "%ld", ch->record_id); 09544 } else { 09545 buf[0] = 0; 09546 } 09547 misdn_cc_set_peer_var(ch->peer, MISDN_CC_RECORD_ID, buf); 09548 } 09549 break; 09550 default: 09551 chan_misdn_log(0, bc->port, 09552 " --> Expected in a DISCONNECT or ALERTING message: facility type:0x%04X\n", 09553 bc->fac_in.Function); 09554 break; 09555 } 09556 break; 09557 case Fac_CCBS_T_Call: 09558 case Fac_CCBSCall: 09559 switch (event) { 09560 case EVENT_SETUP: 09561 /* 09562 * This is a call completion retry call. 09563 * If we had anything to do we would do it here. 09564 */ 09565 break; 09566 default: 09567 chan_misdn_log(0, bc->port, " --> Expected in a SETUP message: facility type:0x%04X\n", 09568 bc->fac_in.Function); 09569 break; 09570 } 09571 break; 09572 case Fac_CCBSDeactivate: 09573 switch (bc->fac_in.u.CCBSDeactivate.ComponentType) { 09574 case FacComponent_Result: 09575 AST_LIST_LOCK(&misdn_cc_records_db); 09576 cc_record = misdn_cc_find_by_invoke(bc->port, bc->fac_in.u.CCBSDeactivate.InvokeID); 09577 if (cc_record) { 09578 cc_record->outstanding_message = 0; 09579 } 09580 AST_LIST_UNLOCK(&misdn_cc_records_db); 09581 break; 09582 09583 default: 09584 chan_misdn_log(0, bc->port, " --> not yet handled: facility type:0x%04X\n", 09585 bc->fac_in.Function); 09586 break; 09587 } 09588 break; 09589 case Fac_CCBSErase: 09590 AST_LIST_LOCK(&misdn_cc_records_db); 09591 cc_record = misdn_cc_find_by_reference(bc->port, bc->fac_in.u.CCBSErase.CCBSReference); 09592 if (cc_record) { 09593 misdn_cc_delete(cc_record); 09594 } 09595 AST_LIST_UNLOCK(&misdn_cc_records_db); 09596 break; 09597 case Fac_CCBSRemoteUserFree: 09598 misdn_cc_handle_remote_user_free(bc->port, &bc->fac_in); 09599 break; 09600 case Fac_CCBSBFree: 09601 misdn_cc_handle_b_free(bc->port, &bc->fac_in); 09602 break; 09603 case Fac_CCBSStatusRequest: 09604 misdn_cc_handle_ccbs_status_request(bc->port, &bc->fac_in); 09605 break; 09606 case Fac_EraseCallLinkageID: 09607 AST_LIST_LOCK(&misdn_cc_records_db); 09608 cc_record = misdn_cc_find_by_linkage(bc->port, 09609 bc->fac_in.u.EraseCallLinkageID.CallLinkageID); 09610 if (cc_record && !cc_record->activation_requested) { 09611 /* 09612 * The T-RETENTION timer expired before we requested 09613 * call completion activation. Call completion is no 09614 * longer available. 09615 */ 09616 misdn_cc_delete(cc_record); 09617 } 09618 AST_LIST_UNLOCK(&misdn_cc_records_db); 09619 break; 09620 case Fac_CCBSStopAlerting: 09621 /* We do not have anything to do for this message. */ 09622 break; 09623 case Fac_CCBSRequest: 09624 case Fac_CCNRRequest: 09625 switch (bc->fac_in.u.CCBSRequest.ComponentType) { 09626 case FacComponent_Result: 09627 AST_LIST_LOCK(&misdn_cc_records_db); 09628 cc_record = misdn_cc_find_by_invoke(bc->port, bc->fac_in.u.CCBSRequest.InvokeID); 09629 if (cc_record && !cc_record->ptp) { 09630 cc_record->outstanding_message = 0; 09631 cc_record->activated = 1; 09632 cc_record->mode.ptmp.recall_mode = bc->fac_in.u.CCBSRequest.Component.Result.RecallMode; 09633 cc_record->mode.ptmp.reference_id = bc->fac_in.u.CCBSRequest.Component.Result.CCBSReference; 09634 } 09635 AST_LIST_UNLOCK(&misdn_cc_records_db); 09636 break; 09637 09638 default: 09639 chan_misdn_log(0, bc->port, " --> not yet handled: facility type:0x%04X\n", 09640 bc->fac_in.Function); 09641 break; 09642 } 09643 break; 09644 #if 0 /* We don't handle this yet */ 09645 case Fac_CCBSInterrogate: 09646 case Fac_CCNRInterrogate: 09647 /* We don't handle this yet */ 09648 break; 09649 case Fac_StatusRequest: 09650 /* We don't handle this yet */ 09651 break; 09652 #endif /* We don't handle this yet */ 09653 #if 0 /* We don't handle this yet */ 09654 case Fac_CCBS_T_Suspend: 09655 case Fac_CCBS_T_Resume: 09656 /* We don't handle this yet */ 09657 break; 09658 #endif /* We don't handle this yet */ 09659 case Fac_CCBS_T_RemoteUserFree: 09660 misdn_cc_handle_T_remote_user_free(bc); 09661 break; 09662 case Fac_CCBS_T_Available: 09663 switch (event) { 09664 case EVENT_ALERTING: 09665 case EVENT_DISCONNECT: 09666 /* CCBS-T/CCNR-T is available */ 09667 if (ch && ch->peer) { 09668 int set_id = 1; 09669 09670 AST_LIST_LOCK(&misdn_cc_records_db); 09671 if (ch->record_id == -1) { 09672 cc_record = misdn_cc_new(); 09673 } else { 09674 /* 09675 * We are doing a call-completion attempt 09676 * or the switch is sending us extra call-completion 09677 * availability indications (erroneously?). 09678 */ 09679 cc_record = misdn_cc_find_by_id(ch->record_id); 09680 if (cc_record) { 09681 if (cc_record->ptp && cc_record->mode.ptp.retention_enabled) { 09682 /* 09683 * Call-completion is still activated. 09684 * The user does not have to request it again. 09685 */ 09686 chan_misdn_log(1, bc->port, " --> Call-completion request retention option is enabled\n"); 09687 09688 set_id = 0; 09689 } else { 09690 if (cc_record->ptp && cc_record->mode.ptp.bc) { 09691 /* 09692 * The network request retention option 09693 * is not on and the current call-completion 09694 * request is to be disabled. 09695 * 09696 * We should get here only if EVENT_DISCONNECT 09697 * 09698 * Close the call-completion signaling link 09699 */ 09700 cc_record->mode.ptp.bc->fac_out.Function = Fac_None; 09701 cc_record->mode.ptp.bc->out_cause = AST_CAUSE_NORMAL_CLEARING; 09702 misdn_lib_send_event(cc_record->mode.ptp.bc, EVENT_RELEASE_COMPLETE); 09703 } 09704 09705 /* 09706 * Resetup the existing record for a possible new 09707 * call-completion request. 09708 */ 09709 new_record_id = misdn_cc_record_id_new(); 09710 if (new_record_id < 0) { 09711 /* Looks like we must keep the old id anyway. */ 09712 } else { 09713 cc_record->record_id = new_record_id; 09714 ch->record_id = new_record_id; 09715 } 09716 cc_record->ptp = 1; 09717 cc_record->port = bc->port; 09718 memset(&cc_record->mode, 0, sizeof(cc_record->mode)); 09719 cc_record->invoke_id = ++misdn_invoke_id; 09720 cc_record->activated = 0; 09721 cc_record->outstanding_message = 0; 09722 cc_record->activation_requested = 0; 09723 cc_record->error_code = FacError_None; 09724 cc_record->reject_code = FacReject_None; 09725 memset(&cc_record->remote_user_free, 0, sizeof(cc_record->remote_user_free)); 09726 memset(&cc_record->b_free, 0, sizeof(cc_record->b_free)); 09727 cc_record->time_created = time(NULL); 09728 } 09729 cc_record = NULL; 09730 } else { 09731 /* 09732 * Where did the record go? We will have to recapture 09733 * the call setup information. Unfortunately, some 09734 * setup information may have been changed. 09735 */ 09736 ch->record_id = -1; 09737 cc_record = misdn_cc_new(); 09738 } 09739 } 09740 if (cc_record) { 09741 ch->record_id = cc_record->record_id; 09742 cc_record->ptp = 1; 09743 cc_record->port = bc->port; 09744 09745 /* Record call information for possible call-completion attempt. */ 09746 cc_record->redial.caller = bc->caller; 09747 cc_record->redial.dialed = bc->dialed; 09748 cc_record->redial.setup_bc_hlc_llc = bc->setup_bc_hlc_llc; 09749 cc_record->redial.capability = bc->capability; 09750 cc_record->redial.hdlc = bc->hdlc; 09751 } 09752 AST_LIST_UNLOCK(&misdn_cc_records_db); 09753 09754 /* Set MISDN_CC_RECORD_ID in original channel */ 09755 if (ch->record_id != -1 && set_id) { 09756 snprintf(buf, sizeof(buf), "%ld", ch->record_id); 09757 } else { 09758 buf[0] = 0; 09759 } 09760 misdn_cc_set_peer_var(ch->peer, MISDN_CC_RECORD_ID, buf); 09761 } 09762 break; 09763 default: 09764 chan_misdn_log(0, bc->port, 09765 " --> Expected in a DISCONNECT or ALERTING message: facility type:0x%04X\n", 09766 bc->fac_in.Function); 09767 break; 09768 } 09769 break; 09770 case Fac_CCBS_T_Request: 09771 case Fac_CCNR_T_Request: 09772 switch (bc->fac_in.u.CCBS_T_Request.ComponentType) { 09773 case FacComponent_Result: 09774 AST_LIST_LOCK(&misdn_cc_records_db); 09775 cc_record = misdn_cc_find_by_invoke(bc->port, bc->fac_in.u.CCBS_T_Request.InvokeID); 09776 if (cc_record && cc_record->ptp) { 09777 cc_record->outstanding_message = 0; 09778 cc_record->activated = 1; 09779 cc_record->mode.ptp.retention_enabled = 09780 cc_record->mode.ptp.requested_retention 09781 ? bc->fac_in.u.CCBS_T_Request.Component.Result.RetentionSupported 09782 ? 1 : 0 09783 : 0; 09784 } 09785 AST_LIST_UNLOCK(&misdn_cc_records_db); 09786 break; 09787 09788 case FacComponent_Invoke: 09789 /* We cannot be User-B in ptp mode. */ 09790 default: 09791 chan_misdn_log(0, bc->port, " --> not yet handled: facility type:0x%04X\n", 09792 bc->fac_in.Function); 09793 break; 09794 } 09795 break; 09796 09797 #endif /* defined(AST_MISDN_ENHANCEMENTS) */ 09798 case Fac_None: 09799 break; 09800 default: 09801 chan_misdn_log(0, bc->port, " --> not yet handled: facility type:0x%04X\n", 09802 bc->fac_in.Function); 09803 break; 09804 } 09805 }
static int misdn_fixup | ( | struct ast_channel * | oldast, | |
struct ast_channel * | ast | |||
) | [static] |
Definition at line 6886 of file chan_misdn.c.
References chan_list::ast, chan_list::bc, chan_misdn_log(), chan_list::l3id, MISDN_ASTERISK_TECH_PVT, misdn_get_ch_state(), and misdn_bchannel::port.
06887 { 06888 struct chan_list *p; 06889 06890 if (!ast || !(p = MISDN_ASTERISK_TECH_PVT(ast))) { 06891 return -1; 06892 } 06893 06894 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); 06895 06896 p->ast = ast; 06897 06898 return 0; 06899 }
static const char* misdn_get_ch_state | ( | struct chan_list * | p | ) | [static] |
Definition at line 4069 of file chan_misdn.c.
References ARRAY_LEN, chan_list::state, state_array, and state_struct::txt.
Referenced by cb_events(), misdn_fixup(), misdn_hangup(), misdn_write(), and print_bc_info().
04070 { 04071 int i; 04072 static char state[8]; 04073 04074 if (!p) { 04075 return NULL; 04076 } 04077 04078 for (i = 0; i < ARRAY_LEN(state_array); i++) { 04079 if (state_array[i].state == p->state) { 04080 return state_array[i].txt; 04081 } 04082 } 04083 04084 snprintf(state, sizeof(state), "%d", p->state) ; 04085 04086 return state; 04087 }
static void misdn_get_connected_line | ( | struct ast_channel * | ast, | |
struct misdn_bchannel * | bc, | |||
int | originator | |||
) | [static] |
Definition at line 6160 of file chan_misdn.c.
References ast_copy_string(), ast_to_misdn_plan(), ast_to_misdn_pres(), ast_to_misdn_screen(), ast_to_misdn_ton(), misdn_bchannel::caller, ast_channel::connected, misdn_bchannel::connected, debug_numtype(), ast_party_connected_line::id, MISDN_CFG_CPNDIALPLAN, misdn_cfg_get(), MISDN_CFG_LOCALDIALPLAN, ast_party_id::name, misdn_party_id::name, misdn_party_id::number, ast_party_id::number, misdn_party_id::number_plan, misdn_party_id::number_type, NUMPLAN_ISDN, NUMPLAN_UNKNOWN, NUMTYPE_UNKNOWN, ORG_MISDN, ast_party_number::plan, misdn_bchannel::port, ast_party_number::presentation, misdn_party_id::presentation, S_COR, S_OR, misdn_party_id::screening, ast_party_number::str, ast_party_name::str, ast_party_number::valid, and ast_party_name::valid.
Referenced by misdn_update_connected_line().
06161 { 06162 int number_type; 06163 06164 if (originator == ORG_MISDN) { 06165 /* ORIGINATOR MISDN (incoming call) */ 06166 06167 ast_copy_string(bc->connected.name, 06168 S_COR(ast->connected.id.name.valid, ast->connected.id.name.str, ""), 06169 sizeof(bc->connected.name)); 06170 if (ast->connected.id.number.valid) { 06171 ast_copy_string(bc->connected.number, S_OR(ast->connected.id.number.str, ""), 06172 sizeof(bc->connected.number)); 06173 bc->connected.presentation = ast_to_misdn_pres(ast->connected.id.number.presentation); 06174 bc->connected.screening = ast_to_misdn_screen(ast->connected.id.number.presentation); 06175 bc->connected.number_type = ast_to_misdn_ton(ast->connected.id.number.plan); 06176 bc->connected.number_plan = ast_to_misdn_plan(ast->connected.id.number.plan); 06177 } else { 06178 bc->connected.number[0] = '\0'; 06179 bc->connected.presentation = 0;/* Allowed */ 06180 bc->connected.screening = 0;/* Unscreened */ 06181 bc->connected.number_type = NUMTYPE_UNKNOWN; 06182 bc->connected.number_plan = NUMPLAN_UNKNOWN; 06183 } 06184 06185 misdn_cfg_get(bc->port, MISDN_CFG_CPNDIALPLAN, &number_type, sizeof(number_type)); 06186 if (0 <= number_type) { 06187 /* Force us to send in CONNECT message */ 06188 bc->connected.number_type = number_type; 06189 bc->connected.number_plan = NUMPLAN_ISDN; 06190 } 06191 debug_numtype(bc->port, bc->connected.number_type, "CTON"); 06192 } else { 06193 /* ORIGINATOR Asterisk (outgoing call) */ 06194 06195 ast_copy_string(bc->caller.name, 06196 S_COR(ast->connected.id.name.valid, ast->connected.id.name.str, ""), 06197 sizeof(bc->caller.name)); 06198 if (ast->connected.id.number.valid) { 06199 ast_copy_string(bc->caller.number, S_OR(ast->connected.id.number.str, ""), 06200 sizeof(bc->caller.number)); 06201 bc->caller.presentation = ast_to_misdn_pres(ast->connected.id.number.presentation); 06202 bc->caller.screening = ast_to_misdn_screen(ast->connected.id.number.presentation); 06203 bc->caller.number_type = ast_to_misdn_ton(ast->connected.id.number.plan); 06204 bc->caller.number_plan = ast_to_misdn_plan(ast->connected.id.number.plan); 06205 } else { 06206 bc->caller.number[0] = '\0'; 06207 bc->caller.presentation = 0;/* Allowed */ 06208 bc->caller.screening = 0;/* Unscreened */ 06209 bc->caller.number_type = NUMTYPE_UNKNOWN; 06210 bc->caller.number_plan = NUMPLAN_UNKNOWN; 06211 } 06212 06213 misdn_cfg_get(bc->port, MISDN_CFG_LOCALDIALPLAN, &number_type, sizeof(number_type)); 06214 if (0 <= number_type) { 06215 /* Force us to send in SETUP message */ 06216 bc->caller.number_type = number_type; 06217 bc->caller.number_plan = NUMPLAN_ISDN; 06218 } 06219 debug_numtype(bc->port, bc->caller.number_type, "LTON"); 06220 } 06221 }
static int misdn_hangup | ( | struct ast_channel * | ast | ) | [static] |
Definition at line 7029 of file chan_misdn.c.
References ast_channel::_state, chan_list::ast, AST_CAUSE_NORMAL_CLEARING, ast_copy_string(), ast_debug, ast_log(), ast_mutex_lock, ast_mutex_unlock, AST_STATE_RESERVED, chan_list::bc, ast_channel::caller, misdn_bchannel::cause, chan_list_unref, chan_misdn_log(), ast_channel::context, EVENT_DISCONNECT, EVENT_RELEASE, EVENT_RELEASE_COMPLETE, ast_channel::exten, ast_channel::hangupcause, hanguptone_indicate(), chan_list::hold, ast_party_caller::id, INFO_PI_INBAND_AVAILABLE, chan_list::l3id, LOG_NOTICE, LOG_WARNING, MISDN_ALERTING, MISDN_ASTERISK_TECH_PVT, MISDN_BUSY, MISDN_CALLING, MISDN_CALLING_ACKNOWLEDGE, misdn_chan_is_valid(), MISDN_CLEANING, MISDN_CONNECTED, MISDN_DIALING, MISDN_DISCONNECTED, misdn_get_ch_state(), MISDN_HOLD_DISCONNECT, MISDN_HOLD_IDLE, MISDN_INCOMING_SETUP, misdn_lib_find_held_bc(), misdn_lib_release(), misdn_lib_send_event(), MISDN_NOTHING, MISDN_PROCEEDING, MISDN_PROGRESS, ast_party_id::name, ast_channel::name, chan_list::need_busy, misdn_bchannel::need_disconnect, chan_list::need_hangup, chan_list::need_queue_hangup, misdn_bchannel::need_release, misdn_bchannel::nt, ast_party_id::number, ORG_AST, chan_list::originator, misdn_bchannel::out_cause, pbx_builtin_getvar_helper(), misdn_bchannel::pid, misdn_bchannel::port, hold_info::port, misdn_bchannel::progress_indicator, release_chan(), release_chan_early(), release_lock, start_bc_tones(), chan_list::state, hold_info::state, stop_bc_tones(), ast_party_number::str, ast_party_name::str, misdn_bchannel::uu, misdn_bchannel::uulen, ast_party_number::valid, and ast_party_name::valid.
07030 { 07031 struct chan_list *p; 07032 struct misdn_bchannel *bc; 07033 const char *var; 07034 07035 if (!ast) { 07036 return -1; 07037 } 07038 07039 ast_debug(1, "misdn_hangup(%s)\n", ast->name); 07040 07041 /* Take the ast_channel's tech_pvt reference. */ 07042 ast_mutex_lock(&release_lock); 07043 p = MISDN_ASTERISK_TECH_PVT(ast); 07044 if (!p) { 07045 ast_mutex_unlock(&release_lock); 07046 return -1; 07047 } 07048 MISDN_ASTERISK_TECH_PVT(ast) = NULL; 07049 07050 if (!misdn_chan_is_valid(p)) { 07051 ast_mutex_unlock(&release_lock); 07052 chan_list_unref(p, "Release ast_channel reference. Was not active?"); 07053 return 0; 07054 } 07055 07056 if (p->hold.state == MISDN_HOLD_IDLE) { 07057 bc = p->bc; 07058 } else { 07059 p->hold.state = MISDN_HOLD_DISCONNECT; 07060 bc = misdn_lib_find_held_bc(p->hold.port, p->l3id); 07061 if (!bc) { 07062 chan_misdn_log(4, p->hold.port, 07063 "misdn_hangup: Could not find held bc for (%s)\n", ast->name); 07064 release_chan_early(p); 07065 ast_mutex_unlock(&release_lock); 07066 chan_list_unref(p, "Release ast_channel reference"); 07067 return 0; 07068 } 07069 } 07070 07071 if (ast->_state == AST_STATE_RESERVED || p->state == MISDN_NOTHING) { 07072 /* between request and call */ 07073 ast_debug(1, "State Reserved (or nothing) => chanIsAvail\n"); 07074 release_chan_early(p); 07075 if (bc) { 07076 misdn_lib_release(bc); 07077 } 07078 ast_mutex_unlock(&release_lock); 07079 chan_list_unref(p, "Release ast_channel reference"); 07080 return 0; 07081 } 07082 if (!bc) { 07083 ast_log(LOG_WARNING, "Hangup with private but no bc ? state:%s l3id:%x\n", 07084 misdn_get_ch_state(p), p->l3id); 07085 release_chan_early(p); 07086 ast_mutex_unlock(&release_lock); 07087 chan_list_unref(p, "Release ast_channel reference"); 07088 return 0; 07089 } 07090 07091 p->ast = NULL; 07092 p->need_hangup = 0; 07093 p->need_queue_hangup = 0; 07094 p->need_busy = 0; 07095 07096 if (!bc->nt) { 07097 stop_bc_tones(p); 07098 } 07099 07100 bc->out_cause = ast->hangupcause ? ast->hangupcause : AST_CAUSE_NORMAL_CLEARING; 07101 07102 /* Channel lock is already held when we are called. */ 07103 //ast_channel_lock(ast); 07104 var = pbx_builtin_getvar_helper(ast, "HANGUPCAUSE"); 07105 if (!var) { 07106 var = pbx_builtin_getvar_helper(ast, "PRI_CAUSE"); 07107 } 07108 if (var) { 07109 int tmpcause; 07110 07111 tmpcause = atoi(var); 07112 bc->out_cause = tmpcause ? tmpcause : AST_CAUSE_NORMAL_CLEARING; 07113 } 07114 07115 var = pbx_builtin_getvar_helper(ast, "MISDN_USERUSER"); 07116 if (var) { 07117 ast_log(LOG_NOTICE, "MISDN_USERUSER: %s\n", var); 07118 ast_copy_string(bc->uu, var, sizeof(bc->uu)); 07119 bc->uulen = strlen(bc->uu); 07120 } 07121 //ast_channel_unlock(ast); 07122 07123 chan_misdn_log(1, bc->port, 07124 "* IND : HANGUP\tpid:%d context:%s dialed:%s caller:\"%s\" <%s> State:%s\n", 07125 bc->pid, 07126 ast->context, 07127 ast->exten, 07128 (ast->caller.id.name.valid && ast->caller.id.name.str) 07129 ? ast->caller.id.name.str : "", 07130 (ast->caller.id.number.valid && ast->caller.id.number.str) 07131 ? ast->caller.id.number.str : "", 07132 misdn_get_ch_state(p)); 07133 chan_misdn_log(3, bc->port, " --> l3id:%x\n", p->l3id); 07134 chan_misdn_log(3, bc->port, " --> cause:%d\n", bc->cause); 07135 chan_misdn_log(2, bc->port, " --> out_cause:%d\n", bc->out_cause); 07136 07137 switch (p->state) { 07138 case MISDN_INCOMING_SETUP: 07139 /* 07140 * This is the only place in misdn_hangup, where we 07141 * can call release_chan, else it might create a lot of trouble. 07142 */ 07143 ast_log(LOG_NOTICE, "release channel, in INCOMING_SETUP state.. no other events happened\n"); 07144 release_chan(p, bc); 07145 misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE); 07146 ast_mutex_unlock(&release_lock); 07147 chan_list_unref(p, "Release ast_channel reference"); 07148 return 0; 07149 case MISDN_DIALING: 07150 if (p->hold.state == MISDN_HOLD_IDLE) { 07151 start_bc_tones(p); 07152 hanguptone_indicate(p); 07153 } 07154 07155 if (bc->need_disconnect) { 07156 misdn_lib_send_event(bc, EVENT_DISCONNECT); 07157 } 07158 break; 07159 case MISDN_CALLING_ACKNOWLEDGE: 07160 if (p->hold.state == MISDN_HOLD_IDLE) { 07161 start_bc_tones(p); 07162 hanguptone_indicate(p); 07163 } 07164 07165 if (bc->need_disconnect) { 07166 misdn_lib_send_event(bc, EVENT_DISCONNECT); 07167 } 07168 break; 07169 07170 case MISDN_CALLING: 07171 case MISDN_ALERTING: 07172 case MISDN_PROGRESS: 07173 case MISDN_PROCEEDING: 07174 if (p->originator != ORG_AST && p->hold.state == MISDN_HOLD_IDLE) { 07175 hanguptone_indicate(p); 07176 } 07177 07178 if (bc->need_disconnect) { 07179 misdn_lib_send_event(bc, EVENT_DISCONNECT); 07180 } 07181 break; 07182 case MISDN_CONNECTED: 07183 /* Alerting or Disconnect */ 07184 if (bc->nt && p->hold.state == MISDN_HOLD_IDLE) { 07185 start_bc_tones(p); 07186 hanguptone_indicate(p); 07187 bc->progress_indicator = INFO_PI_INBAND_AVAILABLE; 07188 } 07189 if (bc->need_disconnect) { 07190 misdn_lib_send_event(bc, EVENT_DISCONNECT); 07191 } 07192 break; 07193 case MISDN_DISCONNECTED: 07194 if (bc->need_release) { 07195 misdn_lib_send_event(bc, EVENT_RELEASE); 07196 } 07197 break; 07198 07199 case MISDN_CLEANING: 07200 ast_mutex_unlock(&release_lock); 07201 chan_list_unref(p, "Release ast_channel reference"); 07202 return 0; 07203 07204 case MISDN_BUSY: 07205 break; 07206 default: 07207 if (bc->nt) { 07208 bc->out_cause = -1; 07209 if (bc->need_release) { 07210 misdn_lib_send_event(bc, EVENT_RELEASE); 07211 } 07212 } else { 07213 if (bc->need_disconnect) { 07214 misdn_lib_send_event(bc, EVENT_DISCONNECT); 07215 } 07216 } 07217 break; 07218 } 07219 07220 p->state = MISDN_CLEANING; 07221 chan_misdn_log(3, bc->port, " --> Channel: %s hungup new state:%s\n", ast->name, 07222 misdn_get_ch_state(p)); 07223 07224 ast_mutex_unlock(&release_lock); 07225 chan_list_unref(p, "Release ast_channel reference"); 07226 return 0; 07227 }
static int misdn_indication | ( | struct ast_channel * | ast, | |
int | cond, | |||
const void * | data, | |||
size_t | datalen | |||
) | [static] |
Definition at line 6903 of file chan_misdn.c.
References chan_list::ast, AST_CAUSE_SWITCH_CONGESTION, AST_CAUSE_USER_BUSY, AST_CONTROL_ANSWER, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_CONNECTED_LINE, AST_CONTROL_FLASH, AST_CONTROL_HOLD, AST_CONTROL_OFFHOOK, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_REDIRECTING, AST_CONTROL_RING, AST_CONTROL_RINGING, AST_CONTROL_TAKEOFFHOOK, AST_CONTROL_UNHOLD, ast_log(), ast_moh_start(), ast_moh_stop(), ast_setstate(), AST_STATE_BUSY, AST_STATE_RING, chan_list::bc, chan_misdn_log(), EVENT_ALERTING, EVENT_DISCONNECT, EVENT_PROCEEDING, EVENT_PROGRESS, hanguptone_indicate(), chan_list::hold, chan_list::incoming_early_audio, LOG_WARNING, MISDN_ALERTING, MISDN_ASTERISK_TECH_PVT, MISDN_CONNECTED, MISDN_HOLD_IDLE, misdn_lib_send_event(), misdn_update_connected_line(), misdn_update_redirecting(), chan_list::mohinterpret, ast_channel::name, misdn_bchannel::nt, ORG_MISDN, chan_list::originator, misdn_bchannel::out_cause, misdn_bchannel::pid, misdn_bchannel::port, start_bc_tones(), chan_list::state, hold_info::state, and stop_indicate().
06904 { 06905 struct chan_list *p; 06906 06907 if (!ast || !(p = MISDN_ASTERISK_TECH_PVT(ast))) { 06908 ast_log(LOG_WARNING, "Returned -1 in misdn_indication\n"); 06909 return -1; 06910 } 06911 06912 if (!p->bc) { 06913 if (p->hold.state == MISDN_HOLD_IDLE) { 06914 chan_misdn_log(1, 0, "* IND : Indication [%d] ignored on %s\n", cond, 06915 ast->name); 06916 ast_log(LOG_WARNING, "Private Pointer but no bc ?\n"); 06917 } else { 06918 chan_misdn_log(1, 0, "* IND : Indication [%d] ignored on hold %s\n", 06919 cond, ast->name); 06920 } 06921 return -1; 06922 } 06923 06924 chan_misdn_log(5, p->bc->port, "* IND : Indication [%d] on %s\n\n", cond, ast->name); 06925 06926 switch (cond) { 06927 case AST_CONTROL_BUSY: 06928 chan_misdn_log(1, p->bc->port, "* IND :\tbusy pid:%d\n", p->bc->pid); 06929 ast_setstate(ast, AST_STATE_BUSY); 06930 06931 p->bc->out_cause = AST_CAUSE_USER_BUSY; 06932 if (p->state != MISDN_CONNECTED) { 06933 start_bc_tones(p); 06934 misdn_lib_send_event(p->bc, EVENT_DISCONNECT); 06935 } 06936 return -1; 06937 case AST_CONTROL_RING: 06938 chan_misdn_log(1, p->bc->port, "* IND :\tring pid:%d\n", p->bc->pid); 06939 return -1; 06940 case AST_CONTROL_RINGING: 06941 chan_misdn_log(1, p->bc->port, "* IND :\tringing pid:%d\n", p->bc->pid); 06942 switch (p->state) { 06943 case MISDN_ALERTING: 06944 chan_misdn_log(2, p->bc->port, " --> * IND :\tringing pid:%d but I was Ringing before, so ignoring it\n", p->bc->pid); 06945 break; 06946 case MISDN_CONNECTED: 06947 chan_misdn_log(2, p->bc->port, " --> * IND :\tringing pid:%d but Connected, so just send TONE_ALERTING without state changes \n", p->bc->pid); 06948 return -1; 06949 default: 06950 p->state = MISDN_ALERTING; 06951 chan_misdn_log(2, p->bc->port, " --> * IND :\tringing pid:%d\n", p->bc->pid); 06952 misdn_lib_send_event(p->bc, EVENT_ALERTING); 06953 06954 chan_misdn_log(3, p->bc->port, " --> * SEND: State Ring pid:%d\n", p->bc->pid); 06955 ast_setstate(ast, AST_STATE_RING); 06956 06957 if (!p->bc->nt && (p->originator == ORG_MISDN) && !p->incoming_early_audio) { 06958 chan_misdn_log(2, p->bc->port, " --> incoming_early_audio off\n"); 06959 } else { 06960 return -1; 06961 } 06962 } 06963 break; 06964 case AST_CONTROL_ANSWER: 06965 chan_misdn_log(1, p->bc->port, " --> * IND :\tanswer pid:%d\n", p->bc->pid); 06966 start_bc_tones(p); 06967 break; 06968 case AST_CONTROL_TAKEOFFHOOK: 06969 chan_misdn_log(1, p->bc->port, " --> *\ttakeoffhook pid:%d\n", p->bc->pid); 06970 return -1; 06971 case AST_CONTROL_OFFHOOK: 06972 chan_misdn_log(1, p->bc->port, " --> *\toffhook pid:%d\n", p->bc->pid); 06973 return -1; 06974 case AST_CONTROL_FLASH: 06975 chan_misdn_log(1, p->bc->port, " --> *\tflash pid:%d\n", p->bc->pid); 06976 break; 06977 case AST_CONTROL_PROGRESS: 06978 chan_misdn_log(1, p->bc->port, " --> * IND :\tprogress pid:%d\n", p->bc->pid); 06979 misdn_lib_send_event(p->bc, EVENT_PROGRESS); 06980 break; 06981 case AST_CONTROL_PROCEEDING: 06982 chan_misdn_log(1, p->bc->port, " --> * IND :\tproceeding pid:%d\n", p->bc->pid); 06983 misdn_lib_send_event(p->bc, EVENT_PROCEEDING); 06984 break; 06985 case AST_CONTROL_CONGESTION: 06986 chan_misdn_log(1, p->bc->port, " --> * IND :\tcongestion pid:%d\n", p->bc->pid); 06987 06988 p->bc->out_cause = AST_CAUSE_SWITCH_CONGESTION; 06989 start_bc_tones(p); 06990 misdn_lib_send_event(p->bc, EVENT_DISCONNECT); 06991 06992 if (p->bc->nt) { 06993 hanguptone_indicate(p); 06994 } 06995 break; 06996 case -1 : 06997 chan_misdn_log(1, p->bc->port, " --> * IND :\t-1! (stop indication) pid:%d\n", p->bc->pid); 06998 06999 stop_indicate(p); 07000 07001 if (p->state == MISDN_CONNECTED) { 07002 start_bc_tones(p); 07003 } 07004 break; 07005 case AST_CONTROL_HOLD: 07006 ast_moh_start(ast, data, p->mohinterpret); 07007 chan_misdn_log(1, p->bc->port, " --> *\tHOLD pid:%d\n", p->bc->pid); 07008 break; 07009 case AST_CONTROL_UNHOLD: 07010 ast_moh_stop(ast); 07011 chan_misdn_log(1, p->bc->port, " --> *\tUNHOLD pid:%d\n", p->bc->pid); 07012 break; 07013 case AST_CONTROL_CONNECTED_LINE: 07014 chan_misdn_log(1, p->bc->port, "* IND :\tconnected line update pid:%d\n", p->bc->pid); 07015 misdn_update_connected_line(ast, p->bc, p->originator); 07016 break; 07017 case AST_CONTROL_REDIRECTING: 07018 chan_misdn_log(1, p->bc->port, "* IND :\tredirecting info update pid:%d\n", p->bc->pid); 07019 misdn_update_redirecting(ast, p->bc, p->originator); 07020 break; 07021 default: 07022 chan_misdn_log(1, p->bc->port, " --> * Unknown Indication:%d pid:%d\n", cond, p->bc->pid); 07023 return -1; 07024 } 07025 07026 return 0; 07027 }
static int misdn_is_msn_valid | ( | int | port, | |
const struct misdn_party_dialing * | dialed | |||
) | [static] |
Definition at line 9818 of file chan_misdn.c.
References ast_copy_string(), misdn_add_number_prefix(), misdn_cfg_is_msn_valid(), misdn_party_dialing::number, and misdn_party_dialing::number_type.
Referenced by cb_events().
09819 { 09820 char number[sizeof(dialed->number)]; 09821 09822 ast_copy_string(number, dialed->number, sizeof(number)); 09823 misdn_add_number_prefix(port, dialed->number_type, number, sizeof(number)); 09824 return misdn_cfg_is_msn_valid(port, number); 09825 }
void misdn_jb_destroy | ( | struct misdn_jb * | jb | ) |
frees the data and destroys the given jitterbuffer struct
Definition at line 12475 of file chan_misdn.c.
References ast_free, ast_mutex_destroy, misdn_jb::mutexjb, misdn_jb::ok, and misdn_jb::samples.
Referenced by chan_list_destructor(), and config_jitterbuffer().
12476 { 12477 ast_mutex_destroy(&jb->mutexjb); 12478 12479 ast_free(jb->ok); 12480 ast_free(jb->samples); 12481 ast_free(jb); 12482 }
int misdn_jb_empty | ( | struct misdn_jb * | jb, | |
char * | data, | |||
int | len | |||
) |
gets len bytes out of the jitterbuffer if available, else only the available data is returned and the return value indicates the number of data.
Definition at line 12552 of file chan_misdn.c.
References ast_mutex_lock, ast_mutex_unlock, chan_misdn_log(), misdn_jb::mutexjb, misdn_jb::ok, misdn_jb::rp, misdn_jb::samples, misdn_jb::size, misdn_jb::state_buffer, misdn_jb::state_empty, and misdn_jb::wp.
Referenced by chan_misdn_jb_empty().
12553 { 12554 int i; 12555 int wp; 12556 int rp; 12557 int read = 0; 12558 12559 ast_mutex_lock(&jb->mutexjb); 12560 12561 rp = jb->rp; 12562 wp = jb->wp; 12563 12564 if (jb->state_empty) { 12565 for (i = 0; i < len; i++) { 12566 if (wp == rp) { 12567 jb->rp = rp; 12568 jb->state_empty = 0; 12569 12570 ast_mutex_unlock(&jb->mutexjb); 12571 12572 return read; 12573 } else { 12574 if (jb->ok[rp] == 1) { 12575 data[i] = jb->samples[rp]; 12576 jb->ok[rp] = 0; 12577 rp = (rp != jb->size - 1) ? rp + 1 : 0; 12578 read += 1; 12579 } 12580 } 12581 } 12582 12583 if (wp >= rp) { 12584 jb->state_buffer = wp - rp; 12585 } else { 12586 jb->state_buffer = jb->size - rp + wp; 12587 } 12588 chan_misdn_log(9, 0, "misdn_jb_empty: read:%d | Buffer status:%d p:%p\n", len, jb->state_buffer, jb); 12589 12590 jb->rp = rp; 12591 } else { 12592 chan_misdn_log(9, 0, "misdn_jb_empty: Wait...requested:%d p:%p\n", len, jb); 12593 } 12594 12595 ast_mutex_unlock(&jb->mutexjb); 12596 12597 return read; 12598 }
int misdn_jb_fill | ( | struct misdn_jb * | jb, | |
const char * | data, | |||
int | len | |||
) |
fills the jitterbuffer with len data returns < 0 if there was an error (buffer overrun).
Definition at line 12486 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.
12487 { 12488 int i; 12489 int j; 12490 int rp; 12491 int wp; 12492 12493 if (!jb || ! data) { 12494 return 0; 12495 } 12496 12497 ast_mutex_lock(&jb->mutexjb); 12498 12499 wp = jb->wp; 12500 rp = jb->rp; 12501 12502 for (i = 0; i < len; i++) { 12503 jb->samples[wp] = data[i]; 12504 jb->ok[wp] = 1; 12505 wp = (wp != jb->size - 1) ? wp + 1 : 0; 12506 12507 if (wp == jb->rp) { 12508 jb->state_full = 1; 12509 } 12510 } 12511 12512 if (wp >= rp) { 12513 jb->state_buffer = wp - rp; 12514 } else { 12515 jb->state_buffer = jb->size - rp + wp; 12516 } 12517 chan_misdn_log(9, 0, "misdn_jb_fill: written:%d | Buffer status:%d p:%p\n", len, jb->state_buffer, jb); 12518 12519 if (jb->state_full) { 12520 jb->wp = wp; 12521 12522 rp = wp; 12523 for (j = 0; j < jb->upper_threshold; j++) { 12524 rp = (rp != 0) ? rp - 1 : jb->size - 1; 12525 } 12526 jb->rp = rp; 12527 jb->state_full = 0; 12528 jb->state_empty = 1; 12529 12530 ast_mutex_unlock(&jb->mutexjb); 12531 12532 return -1; 12533 } 12534 12535 if (!jb->state_empty) { 12536 jb->bytes_wrote += len; 12537 if (jb->bytes_wrote >= jb->upper_threshold) { 12538 jb->state_empty = 1; 12539 jb->bytes_wrote = 0; 12540 } 12541 } 12542 jb->wp = wp; 12543 12544 ast_mutex_unlock(&jb->mutexjb); 12545 12546 return 0; 12547 }
struct misdn_jb * misdn_jb_init | ( | int | size, | |
int | upper_threshold | |||
) |
allocates the jb-structure and initialize the elements
Definition at line 12433 of file chan_misdn.c.
References ast_free, ast_malloc, ast_mutex_init, and chan_misdn_log().
Referenced by config_jitterbuffer().
12434 { 12435 int i; 12436 struct misdn_jb *jb; 12437 12438 jb = ast_malloc(sizeof(*jb)); 12439 if (!jb) { 12440 chan_misdn_log(-1, 0, "No free Mem for jb\n"); 12441 return NULL; 12442 } 12443 jb->size = size; 12444 jb->upper_threshold = upper_threshold; 12445 jb->wp = 0; 12446 jb->rp = 0; 12447 jb->state_full = 0; 12448 jb->state_empty = 0; 12449 jb->bytes_wrote = 0; 12450 jb->samples = ast_malloc(size * sizeof(char)); 12451 if (!jb->samples) { 12452 ast_free(jb); 12453 chan_misdn_log(-1, 0, "No free Mem for jb->samples\n"); 12454 return NULL; 12455 } 12456 12457 jb->ok = ast_malloc(size * sizeof(char)); 12458 if (!jb->ok) { 12459 ast_free(jb->samples); 12460 ast_free(jb); 12461 chan_misdn_log(-1, 0, "No free Mem for jb->ok\n"); 12462 return NULL; 12463 } 12464 12465 for (i = 0; i < size; i++) { 12466 jb->ok[i] = 0; 12467 } 12468 12469 ast_mutex_init(&jb->mutexjb); 12470 12471 return jb; 12472 }
static int misdn_l1_task | ( | const void * | vdata | ) | [static] |
Definition at line 3586 of file chan_misdn.c.
References chan_misdn_log(), and misdn_lib_isdn_l1watcher().
Referenced by load_module().
03587 { 03588 const int *data = vdata; 03589 03590 misdn_lib_isdn_l1watcher(*data); 03591 chan_misdn_log(5, *data, "L1watcher timeout\n"); 03592 return 1; 03593 }
static struct ast_channel * misdn_new | ( | struct chan_list * | cl, | |
int | state, | |||
char * | exten, | |||
char * | callerid, | |||
int | format, | |||
const char * | linkedid, | |||
int | port, | |||
int | c | |||
) | [static] |
Definition at line 8089 of file chan_misdn.c.
References ast_party_caller::ani, chan_list::ast, ast_callerid_parse(), ast_channel_alloc, ast_channel_set_fd(), ast_copy_string(), ast_jb_configure(), ast_log(), AST_STATE_RING, ast_strdup, ast_strlen_zero(), ast_channel::caller, chan_list_ref, chan_misdn_log(), cid_name, cid_num, ast_channel::exten, LOG_ERROR, MISDN_ASTERISK_TECH_PVT, misdn_cfg_get(), misdn_cfg_get_next_port(), MISDN_GEN_BRIDGING, misdn_get_global_jbconf(), misdn_lib_port_is_pri(), misdn_tech, misdn_tech_wo_bridge, misdn_type, ast_channel::nativeformats, ast_party_id::number, chan_list::pipe, prefformat, ast_channel::priority, ast_channel::rawreadformat, ast_channel::rawwriteformat, ast_channel::readformat, ast_channel::rings, ast_party_number::str, ast_channel::tech, ast_party_number::valid, and ast_channel::writeformat.
Referenced by cb_events(), and misdn_request().
08090 { 08091 struct ast_channel *tmp; 08092 char *cid_name = NULL; 08093 char *cid_num = NULL; 08094 int chan_offset = 0; 08095 int tmp_port = misdn_cfg_get_next_port(0); 08096 int bridging; 08097 08098 for (; tmp_port > 0; tmp_port = misdn_cfg_get_next_port(tmp_port)) { 08099 if (tmp_port == port) { 08100 break; 08101 } 08102 chan_offset += misdn_lib_port_is_pri(tmp_port) ? 30 : 2; 08103 } 08104 if (c < 0) { 08105 c = 0; 08106 } 08107 08108 if (callerid) { 08109 ast_callerid_parse(callerid, &cid_name, &cid_num); 08110 } 08111 08112 tmp = ast_channel_alloc(1, state, cid_num, cid_name, "", exten, "", linkedid, 0, "%s/%s%d-u%d", misdn_type, c ? "" : "tmp", chan_offset + c, glob_channel++); 08113 if (tmp) { 08114 chan_misdn_log(2, 0, " --> * NEW CHANNEL dialed:%s caller:%s\n", exten, callerid); 08115 08116 tmp->nativeformats = prefformat; 08117 08118 tmp->readformat = format; 08119 tmp->rawreadformat = format; 08120 tmp->writeformat = format; 08121 tmp->rawwriteformat = format; 08122 08123 /* Link the channel and private together */ 08124 chan_list_ref(chlist, "Give a reference to ast_channel"); 08125 MISDN_ASTERISK_TECH_PVT(tmp) = chlist; 08126 chlist->ast = tmp; 08127 08128 misdn_cfg_get(0, MISDN_GEN_BRIDGING, &bridging, sizeof(bridging)); 08129 tmp->tech = bridging ? &misdn_tech : &misdn_tech_wo_bridge; 08130 08131 tmp->writeformat = format; 08132 tmp->readformat = format; 08133 tmp->priority = 1; 08134 08135 if (exten) { 08136 ast_copy_string(tmp->exten, exten, sizeof(tmp->exten)); 08137 } else { 08138 chan_misdn_log(1, 0, "misdn_new: no exten given.\n"); 08139 } 08140 08141 if (!ast_strlen_zero(cid_num)) { 08142 /* Don't use ast_set_callerid() here because it will 08143 * generate a needless NewCallerID event */ 08144 tmp->caller.ani.number.valid = 1; 08145 tmp->caller.ani.number.str = ast_strdup(cid_num); 08146 } 08147 08148 if (pipe(chlist->pipe) < 0) { 08149 ast_log(LOG_ERROR, "Pipe failed\n"); 08150 } 08151 ast_channel_set_fd(tmp, 0, chlist->pipe[0]); 08152 08153 tmp->rings = (state == AST_STATE_RING) ? 1 : 0; 08154 08155 ast_jb_configure(tmp, misdn_get_global_jbconf()); 08156 } else { 08157 chan_misdn_log(-1, 0, "Unable to allocate channel structure\n"); 08158 } 08159 08160 return tmp; 08161 }
static int misdn_overlap_dial_task | ( | const void * | data | ) | [static] |
Definition at line 3595 of file chan_misdn.c.
References chan_list::ast, AST_CAUSE_UNALLOCATED, ast_exists_extension(), ast_mutex_lock, ast_mutex_unlock, ast_strlen_zero(), ast_tvdiff_ms(), ast_tvnow(), chan_list::bc, misdn_bchannel::caller, chan_misdn_log(), chan_list::context, misdn_bchannel::dialed, EVENT_DISCONNECT, ast_channel::exten, hanguptone_indicate(), MISDN_CLEANING, MISDN_DIALING, misdn_lib_send_event(), MISDN_WAITING4DIGS, misdn_party_id::number, misdn_party_dialing::number, misdn_bchannel::out_cause, chan_list::overlap_dial, chan_list::overlap_dial_task, chan_list::overlap_tv, chan_list::overlap_tv_lock, pbx_start_chan(), misdn_bchannel::port, chan_list::state, and stop_indicate().
Referenced by cb_events().
03596 { 03597 struct timeval tv_end, tv_now; 03598 int diff; 03599 struct chan_list *ch = (struct chan_list *) data; 03600 char *dad; 03601 03602 chan_misdn_log(4, ch->bc->port, "overlap dial task, chan_state: %d\n", ch->state); 03603 03604 if (ch->state != MISDN_WAITING4DIGS) { 03605 ch->overlap_dial_task = -1; 03606 return 0; 03607 } 03608 03609 ast_mutex_lock(&ch->overlap_tv_lock); 03610 tv_end = ch->overlap_tv; 03611 ast_mutex_unlock(&ch->overlap_tv_lock); 03612 03613 tv_end.tv_sec += ch->overlap_dial; 03614 tv_now = ast_tvnow(); 03615 03616 diff = ast_tvdiff_ms(tv_end, tv_now); 03617 if (100 < diff) { 03618 return diff; 03619 } 03620 03621 /* if we are 100ms near the timeout, we are satisfied.. */ 03622 stop_indicate(ch); 03623 03624 if (ast_strlen_zero(ch->bc->dialed.number)) { 03625 dad = "s"; 03626 strcpy(ch->ast->exten, dad); 03627 } else { 03628 dad = ch->bc->dialed.number; 03629 } 03630 03631 if (ast_exists_extension(ch->ast, ch->context, dad, 1, ch->bc->caller.number)) { 03632 ch->state = MISDN_DIALING; 03633 if (pbx_start_chan(ch) < 0) { 03634 chan_misdn_log(-1, ch->bc->port, "ast_pbx_start returned < 0 in misdn_overlap_dial_task\n"); 03635 goto misdn_overlap_dial_task_disconnect; 03636 } 03637 } else { 03638 misdn_overlap_dial_task_disconnect: 03639 hanguptone_indicate(ch); 03640 ch->bc->out_cause = AST_CAUSE_UNALLOCATED; 03641 ch->state = MISDN_CLEANING; 03642 misdn_lib_send_event(ch->bc, EVENT_DISCONNECT); 03643 } 03644 ch->overlap_dial_task = -1; 03645 return 0; 03646 }
static void misdn_prefix_string | ( | const char * | str_prefix, | |
char * | str_main, | |||
size_t | size | |||
) | [static] |
Definition at line 3351 of file chan_misdn.c.
Referenced by misdn_add_number_prefix().
03352 { 03353 size_t len_over; 03354 size_t len_total; 03355 size_t len_main; 03356 size_t len_prefix; 03357 03358 len_prefix = strlen(str_prefix); 03359 if (!len_prefix) { 03360 /* There is no prefix to prepend. */ 03361 return; 03362 } 03363 len_main = strlen(str_main); 03364 len_total = len_prefix + len_main; 03365 if (size <= len_total) { 03366 /* We need to truncate since the buffer is too small. */ 03367 len_over = len_total + 1 - size; 03368 if (len_over <= len_main) { 03369 len_main -= len_over; 03370 } else { 03371 len_over -= len_main; 03372 len_main = 0; 03373 len_prefix -= len_over; 03374 } 03375 } 03376 if (len_main) { 03377 memmove(str_main + len_prefix, str_main, len_main); 03378 } 03379 memcpy(str_main, str_prefix, len_prefix); 03380 str_main[len_prefix + len_main] = '\0'; 03381 }
static void misdn_queue_connected_line_update | ( | struct ast_channel * | ast, | |
const struct misdn_party_id * | id, | |||
enum AST_CONNECTED_LINE_UPDATE_SOURCE | source, | |||
char * | cid_tag | |||
) | [static] |
Definition at line 6076 of file chan_misdn.c.
References ast_channel_queue_connected_line_update(), ast_party_connected_line_init(), connected, id, misdn_to_ast_plan(), misdn_to_ast_pres(), misdn_to_ast_screen(), and misdn_to_ast_ton().
Referenced by misdn_update_remote_party().
06077 { 06078 struct ast_party_connected_line connected; 06079 struct ast_set_party_connected_line update_connected; 06080 06081 ast_party_connected_line_init(&connected); 06082 memset(&update_connected, 0, sizeof(update_connected)); 06083 update_connected.id.number = 1; 06084 connected.id.number.valid = 1; 06085 connected.id.number.str = (char *) id->number; 06086 connected.id.number.plan = misdn_to_ast_ton(id->number_type) 06087 | misdn_to_ast_plan(id->number_plan); 06088 connected.id.number.presentation = misdn_to_ast_pres(id->presentation) 06089 | misdn_to_ast_screen(id->screening); 06090 connected.id.tag = cid_tag; 06091 connected.source = source; 06092 ast_channel_queue_connected_line_update(ast, &connected, &update_connected); 06093 }
static struct ast_frame* misdn_read | ( | struct ast_channel * | ast | ) | [static] |
Definition at line 7305 of file chan_misdn.c.
References chan_list::ast_dsp, AST_FORMAT_ALAW, AST_FRAME_VOICE, ast_poll, chan_list::ast_rd_buf, ast_tv(), ast_tvdiff_ms(), ast_tvnow(), ast_tvzero(), chan_list::bc, chan_misdn_log(), ast_frame_subclass::codec, ast_frame::data, ast_frame::datalen, ast_frame::delivery, errno, chan_list::faxdetect, chan_list::faxdetect_timeout, chan_list::faxdetect_tv, chan_list::faxhandled, chan_list::frame, ast_frame::frametype, chan_list::hold, len(), ast_frame::mallocd, MISDN_ASTERISK_TECH_PVT, MISDN_HOLD_IDLE, ast_frame::offset, chan_list::pipe, misdn_bchannel::port, process_ast_dsp(), ast_frame::ptr, ast_frame::samples, ast_frame::src, hold_info::state, and ast_frame::subclass.
07306 { 07307 struct chan_list *tmp; 07308 int len, t; 07309 struct pollfd pfd = { .fd = -1, .events = POLLIN }; 07310 07311 if (!ast) { 07312 chan_misdn_log(1, 0, "misdn_read called without ast\n"); 07313 return NULL; 07314 } 07315 if (!(tmp = MISDN_ASTERISK_TECH_PVT(ast))) { 07316 chan_misdn_log(1, 0, "misdn_read called without ast->pvt\n"); 07317 return NULL; 07318 } 07319 07320 if (!tmp->bc && tmp->hold.state == MISDN_HOLD_IDLE) { 07321 chan_misdn_log(1, 0, "misdn_read called without bc\n"); 07322 return NULL; 07323 } 07324 07325 pfd.fd = tmp->pipe[0]; 07326 t = ast_poll(&pfd, 1, 20); 07327 07328 if (t < 0) { 07329 chan_misdn_log(-1, tmp->bc->port, "poll() error (err=%s)\n", strerror(errno)); 07330 return NULL; 07331 } 07332 07333 if (!t) { 07334 chan_misdn_log(3, tmp->bc->port, "poll() timed out\n"); 07335 len = 160; 07336 } else if (pfd.revents & POLLIN) { 07337 len = read(tmp->pipe[0], tmp->ast_rd_buf, sizeof(tmp->ast_rd_buf)); 07338 07339 if (len <= 0) { 07340 /* we hangup here, since our pipe is closed */ 07341 chan_misdn_log(2, tmp->bc->port, "misdn_read: Pipe closed, hanging up\n"); 07342 return NULL; 07343 } 07344 } else { 07345 return NULL; 07346 } 07347 07348 tmp->frame.frametype = AST_FRAME_VOICE; 07349 tmp->frame.subclass.codec = AST_FORMAT_ALAW; 07350 tmp->frame.datalen = len; 07351 tmp->frame.samples = len; 07352 tmp->frame.mallocd = 0; 07353 tmp->frame.offset = 0; 07354 tmp->frame.delivery = ast_tv(0, 0); 07355 tmp->frame.src = NULL; 07356 tmp->frame.data.ptr = tmp->ast_rd_buf; 07357 07358 if (tmp->faxdetect && !tmp->faxhandled) { 07359 if (tmp->faxdetect_timeout) { 07360 if (ast_tvzero(tmp->faxdetect_tv)) { 07361 tmp->faxdetect_tv = ast_tvnow(); 07362 chan_misdn_log(2, tmp->bc->port, "faxdetect: starting detection with timeout: %ds ...\n", tmp->faxdetect_timeout); 07363 return process_ast_dsp(tmp, &tmp->frame); 07364 } else { 07365 struct timeval tv_now = ast_tvnow(); 07366 int diff = ast_tvdiff_ms(tv_now, tmp->faxdetect_tv); 07367 if (diff <= (tmp->faxdetect_timeout * 1000)) { 07368 chan_misdn_log(5, tmp->bc->port, "faxdetect: detecting ...\n"); 07369 return process_ast_dsp(tmp, &tmp->frame); 07370 } else { 07371 chan_misdn_log(2, tmp->bc->port, "faxdetect: stopping detection (time ran out) ...\n"); 07372 tmp->faxdetect = 0; 07373 return &tmp->frame; 07374 } 07375 } 07376 } else { 07377 chan_misdn_log(5, tmp->bc->port, "faxdetect: detecting ... (no timeout)\n"); 07378 return process_ast_dsp(tmp, &tmp->frame); 07379 } 07380 } else { 07381 if (tmp->ast_dsp) { 07382 return process_ast_dsp(tmp, &tmp->frame); 07383 } else { 07384 return &tmp->frame; 07385 } 07386 } 07387 }
static struct ast_channel* misdn_request | ( | const char * | type, | |
format_t | format, | |||
const struct ast_channel * | requestor, | |||
void * | data, | |||
int * | cause | |||
) | [static] |
Definition at line 7759 of file chan_misdn.c.
References args, AST_APP_ARG, ast_copy_string(), AST_DECLARE_APP_ARGS, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), AST_NONSTANDARD_APP_ARGS, AST_STATE_RESERVED, ast_strdupa, ast_strlen_zero(), chan_list::bc, BUFFERSIZE, chan_list_init(), chan_list_unref, chan_misdn_log(), misdn_bchannel::channel, robin_list::channel, cl_queue_chan(), misdn_bchannel::dec, ext, get_robin_position(), ast_channel::linkedid, LOG_ERROR, LOG_WARNING, METHOD_ROUND_ROBIN, METHOD_STANDARD_DEC, misdn_cfg_get(), misdn_cfg_get_next_port(), misdn_cfg_get_next_port_spin(), MISDN_CFG_GROUPNAME, misdn_cfg_is_group_method(), MISDN_CFG_PMP_L1_CHECK, misdn_lib_get_free_bc(), misdn_lib_get_maxchans(), misdn_lib_port_up(), misdn_new(), misdn_type, chan_list::need_hangup, ORG_AST, misdn_bchannel::port, robin_list::port, and read_config().
07760 { 07761 struct ast_channel *ast; 07762 char group[BUFFERSIZE + 1] = ""; 07763 char dial_str[128]; 07764 char *dest_cp; 07765 char *p = NULL; 07766 int channel = 0; 07767 int port = 0; 07768 struct misdn_bchannel *newbc = NULL; 07769 int dec = 0; 07770 #if defined(AST_MISDN_ENHANCEMENTS) 07771 int cc_retry_call = 0; /* TRUE if this is a call completion retry call */ 07772 long record_id = -1; 07773 struct misdn_cc_record *cc_record; 07774 const char *err_msg; 07775 #endif /* defined(AST_MISDN_ENHANCEMENTS) */ 07776 struct chan_list *cl; 07777 07778 AST_DECLARE_APP_ARGS(args, 07779 AST_APP_ARG(intf); /* interface token */ 07780 AST_APP_ARG(ext); /* extension token */ 07781 AST_APP_ARG(opts); /* options token */ 07782 ); 07783 07784 snprintf(dial_str, sizeof(dial_str), "%s/%s", misdn_type, (char *) data); 07785 07786 /* 07787 * data is ---v 07788 * Dial(mISDN/g:group_name[/extension[/options]]) 07789 * Dial(mISDN/port[:preselected_channel][/extension[/options]]) 07790 * Dial(mISDN/cc/cc-record-id) 07791 * 07792 * The dial extension could be empty if you are using MISDN_KEYPAD 07793 * to control ISDN provider features. 07794 */ 07795 dest_cp = ast_strdupa(data); 07796 AST_NONSTANDARD_APP_ARGS(args, dest_cp, '/'); 07797 if (!args.ext) { 07798 args.ext = ""; 07799 } 07800 07801 if (!ast_strlen_zero(args.intf)) { 07802 if (args.intf[0] == 'g' && args.intf[1] == ':') { 07803 /* We make a group call lets checkout which ports are in my group */ 07804 args.intf += 2; 07805 ast_copy_string(group, args.intf, sizeof(group)); 07806 chan_misdn_log(2, 0, " --> Group Call group: %s\n", group); 07807 #if defined(AST_MISDN_ENHANCEMENTS) 07808 } else if (strcmp(args.intf, "cc") == 0) { 07809 cc_retry_call = 1; 07810 #endif /* defined(AST_MISDN_ENHANCEMENTS) */ 07811 } else if ((p = strchr(args.intf, ':'))) { 07812 /* we have a preselected channel */ 07813 *p++ = 0; 07814 channel = atoi(p); 07815 port = atoi(args.intf); 07816 chan_misdn_log(2, port, " --> Call on preselected Channel (%d).\n", channel); 07817 } else { 07818 port = atoi(args.intf); 07819 } 07820 } else { 07821 ast_log(LOG_WARNING, " --> ! IND : Dial(%s) WITHOUT Port or Group, check extensions.conf\n", dial_str); 07822 return NULL; 07823 } 07824 07825 #if defined(AST_MISDN_ENHANCEMENTS) 07826 if (cc_retry_call) { 07827 if (ast_strlen_zero(args.ext)) { 07828 ast_log(LOG_WARNING, " --> ! IND : Dial(%s) WITHOUT cc-record-id, check extensions.conf\n", dial_str); 07829 return NULL; 07830 } 07831 if (!isdigit(*args.ext)) { 07832 ast_log(LOG_WARNING, " --> ! IND : Dial(%s) cc-record-id must be a number.\n", dial_str); 07833 return NULL; 07834 } 07835 record_id = atol(args.ext); 07836 07837 AST_LIST_LOCK(&misdn_cc_records_db); 07838 cc_record = misdn_cc_find_by_id(record_id); 07839 if (!cc_record) { 07840 AST_LIST_UNLOCK(&misdn_cc_records_db); 07841 err_msg = misdn_cc_record_not_found; 07842 ast_log(LOG_WARNING, " --> ! IND : Dial(%s) %s.\n", dial_str, err_msg); 07843 return NULL; 07844 } 07845 if (!cc_record->activated) { 07846 AST_LIST_UNLOCK(&misdn_cc_records_db); 07847 err_msg = "Call completion has not been activated"; 07848 ast_log(LOG_WARNING, " --> ! IND : Dial(%s) %s.\n", dial_str, err_msg); 07849 return NULL; 07850 } 07851 port = cc_record->port; 07852 AST_LIST_UNLOCK(&misdn_cc_records_db); 07853 } 07854 #endif /* defined(AST_MISDN_ENHANCEMENTS) */ 07855 07856 if (misdn_cfg_is_group_method(group, METHOD_STANDARD_DEC)) { 07857 chan_misdn_log(4, port, " --> STARTING STANDARD DEC...\n"); 07858 dec = 1; 07859 } 07860 07861 if (!ast_strlen_zero(group)) { 07862 char cfg_group[BUFFERSIZE + 1]; 07863 struct robin_list *rr = NULL; 07864 07865 /* Group dial */ 07866 07867 if (misdn_cfg_is_group_method(group, METHOD_ROUND_ROBIN)) { 07868 chan_misdn_log(4, port, " --> STARTING ROUND ROBIN...\n"); 07869 rr = get_robin_position(group); 07870 } 07871 07872 if (rr) { 07873 int robin_channel = rr->channel; 07874 int port_start; 07875 int next_chan = 1; 07876 07877 do { 07878 port_start = 0; 07879 for (port = misdn_cfg_get_next_port_spin(rr->port); port > 0 && port != port_start; 07880 port = misdn_cfg_get_next_port_spin(port)) { 07881 07882 if (!port_start) { 07883 port_start = port; 07884 } 07885 07886 if (port >= port_start) { 07887 next_chan = 1; 07888 } 07889 07890 if (port <= port_start && next_chan) { 07891 int maxbchans = misdn_lib_get_maxchans(port); 07892 07893 if (++robin_channel >= maxbchans) { 07894 robin_channel = 1; 07895 } 07896 next_chan = 0; 07897 } 07898 07899 misdn_cfg_get(port, MISDN_CFG_GROUPNAME, cfg_group, sizeof(cfg_group)); 07900 07901 if (!strcasecmp(cfg_group, group)) { 07902 int port_up; 07903 int check; 07904 07905 misdn_cfg_get(port, MISDN_CFG_PMP_L1_CHECK, &check, sizeof(check)); 07906 port_up = misdn_lib_port_up(port, check); 07907 07908 if (check && !port_up) { 07909 chan_misdn_log(1, port, "L1 is not Up on this Port\n"); 07910 } 07911 07912 if (check && port_up < 0) { 07913 ast_log(LOG_WARNING, "This port (%d) is blocked\n", port); 07914 } 07915 07916 if (port_up > 0) { 07917 newbc = misdn_lib_get_free_bc(port, robin_channel, 0, 0); 07918 if (newbc) { 07919 chan_misdn_log(4, port, " Success! Found port:%d channel:%d\n", newbc->port, newbc->channel); 07920 if (port_up) { 07921 chan_misdn_log(4, port, "portup:%d\n", port_up); 07922 } 07923 rr->port = newbc->port; 07924 rr->channel = newbc->channel; 07925 break; 07926 } 07927 } 07928 } 07929 } 07930 } while (!newbc && robin_channel != rr->channel); 07931 } else { 07932 for (port = misdn_cfg_get_next_port(0); port > 0; 07933 port = misdn_cfg_get_next_port(port)) { 07934 misdn_cfg_get(port, MISDN_CFG_GROUPNAME, cfg_group, sizeof(cfg_group)); 07935 07936 chan_misdn_log(3, port, "Group [%s] Port [%d]\n", group, port); 07937 if (!strcasecmp(cfg_group, group)) { 07938 int port_up; 07939 int check; 07940 07941 misdn_cfg_get(port, MISDN_CFG_PMP_L1_CHECK, &check, sizeof(check)); 07942 port_up = misdn_lib_port_up(port, check); 07943 07944 chan_misdn_log(4, port, "portup:%d\n", port_up); 07945 07946 if (port_up > 0) { 07947 newbc = misdn_lib_get_free_bc(port, 0, 0, dec); 07948 if (newbc) { 07949 break; 07950 } 07951 } 07952 } 07953 } 07954 } 07955 07956 /* Group dial failed ?*/ 07957 if (!newbc) { 07958 ast_log(LOG_WARNING, 07959 "Could not Dial out on group '%s'.\n" 07960 "\tEither the L2 and L1 on all of these ports where DOWN (see 'show application misdn_check_l2l1')\n" 07961 "\tOr there was no free channel on none of the ports\n\n", 07962 group); 07963 return NULL; 07964 } 07965 } else { 07966 /* 'Normal' Port dial * Port dial */ 07967 if (channel) { 07968 chan_misdn_log(1, port, " --> preselected_channel: %d\n", channel); 07969 } 07970 newbc = misdn_lib_get_free_bc(port, channel, 0, dec); 07971 if (!newbc) { 07972 ast_log(LOG_WARNING, "Could not create channel on port:%d for Dial(%s)\n", port, dial_str); 07973 return NULL; 07974 } 07975 } 07976 07977 /* create ast_channel and link all the objects together */ 07978 cl = chan_list_init(ORG_AST); 07979 if (!cl) { 07980 ast_log(LOG_ERROR, "Could not create call record for Dial(%s)\n", dial_str); 07981 return NULL; 07982 } 07983 cl->bc = newbc; 07984 07985 ast = misdn_new(cl, AST_STATE_RESERVED, args.ext, NULL, format, requestor ? requestor->linkedid : NULL, port, channel); 07986 if (!ast) { 07987 chan_list_unref(cl, "Failed to create a new channel"); 07988 ast_log(LOG_ERROR, "Could not create Asterisk channel for Dial(%s)\n", dial_str); 07989 return NULL; 07990 } 07991 07992 #if defined(AST_MISDN_ENHANCEMENTS) 07993 cl->record_id = record_id; 07994 #endif /* defined(AST_MISDN_ENHANCEMENTS) */ 07995 07996 /* register chan in local list */ 07997 cl_queue_chan(cl); 07998 07999 /* fill in the config into the objects */ 08000 read_config(cl); 08001 08002 /* important */ 08003 cl->need_hangup = 0; 08004 08005 chan_list_unref(cl, "Successful misdn_request()"); 08006 return ast; 08007 }
static int misdn_send_text | ( | struct ast_channel * | chan, | |
const char * | text | |||
) | [static] |
Definition at line 8010 of file chan_misdn.c.
References ast_copy_string(), ast_log(), chan_list::bc, misdn_bchannel::display, EVENT_INFORMATION, LOG_WARNING, MISDN_ASTERISK_TECH_PVT, and misdn_lib_send_event().
08011 { 08012 struct chan_list *tmp = MISDN_ASTERISK_TECH_PVT(chan); 08013 08014 if (tmp && tmp->bc) { 08015 ast_copy_string(tmp->bc->display, text, sizeof(tmp->bc->display)); 08016 misdn_lib_send_event(tmp->bc, EVENT_INFORMATION); 08017 } else { 08018 ast_log(LOG_WARNING, "No chan_list but send_text request?\n"); 08019 return -1; 08020 } 08021 08022 return 0; 08023 }
static int misdn_set_opt_exec | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Definition at line 12196 of file chan_misdn.c.
References ast_copy_string(), chan_list::ast_dsp, ast_dsp_new(), ast_dsp_set_features(), ast_log(), ast_strdupa, ast_strlen_zero(), chan_list::bc, misdn_bchannel::capability, chan_misdn_log(), config_jitterbuffer(), misdn_bchannel::crypt_key, misdn_bchannel::display, chan_list::dsp, DSP_FEATURE_DIGIT_DETECT, DSP_FEATURE_FAX_DETECT, misdn_bchannel::ec_deftaps, misdn_bchannel::ec_enable, chan_list::faxdetect, chan_list::faxdetect_timeout, misdn_bchannel::hdlc, chan_list::ignore_dtmf, INFO_CAPABILITY_DIGITAL_UNRESTRICTED, chan_list::jb_len, chan_list::jb_upper_threshold, LOG_WARNING, MISDN_ASTERISK_TECH_PVT, MISDN_CFG_FAXDETECT_TIMEOUT, misdn_cfg_get(), MISDN_GEN_CRYPT_KEYS, misdn_type, misdn_bchannel::nodsp, misdn_bchannel::nojitter, misdn_bchannel::orig, chan_list::originator, misdn_bchannel::port, misdn_bchannel::presentation, misdn_bchannel::rxgain, misdn_bchannel::send_dtmf, misdn_bchannel::set_presentation, strsep(), ast_channel::tech, misdn_bchannel::txgain, and ast_channel_tech::type.
Referenced by load_module(), and misdn_call().
12197 { 12198 struct chan_list *ch = MISDN_ASTERISK_TECH_PVT(chan); 12199 char *tok; 12200 char *tokb; 12201 char *parse; 12202 int keyidx = 0; 12203 int rxgain = 0; 12204 int txgain = 0; 12205 int change_jitter = 0; 12206 12207 if (strcasecmp(chan->tech->type, misdn_type)) { 12208 ast_log(LOG_WARNING, "misdn_set_opt makes sense only with %s channels!\n", misdn_type); 12209 return -1; 12210 } 12211 12212 if (ast_strlen_zero((char *) data)) { 12213 ast_log(LOG_WARNING, "misdn_set_opt Requires arguments\n"); 12214 return -1; 12215 } 12216 12217 parse = ast_strdupa(data); 12218 for (tok = strtok_r(parse, ":", &tokb); 12219 tok; 12220 tok = strtok_r(NULL, ":", &tokb)) { 12221 int neglect = 0; 12222 12223 if (tok[0] == '!') { 12224 neglect = 1; 12225 tok++; 12226 } 12227 12228 switch(tok[0]) { 12229 case 'd' : 12230 ast_copy_string(ch->bc->display, ++tok, sizeof(ch->bc->display)); 12231 chan_misdn_log(1, ch->bc->port, "SETOPT: Display:%s\n", ch->bc->display); 12232 break; 12233 case 'n': 12234 chan_misdn_log(1, ch->bc->port, "SETOPT: No DSP\n"); 12235 ch->bc->nodsp = 1; 12236 break; 12237 case 'j': 12238 chan_misdn_log(1, ch->bc->port, "SETOPT: jitter\n"); 12239 tok++; 12240 change_jitter = 1; 12241 12242 switch (tok[0]) { 12243 case 'b': 12244 ch->jb_len = atoi(++tok); 12245 chan_misdn_log(1, ch->bc->port, " --> buffer_len:%d\n", ch->jb_len); 12246 break; 12247 case 't' : 12248 ch->jb_upper_threshold = atoi(++tok); 12249 chan_misdn_log(1, ch->bc->port, " --> upper_threshold:%d\n", ch->jb_upper_threshold); 12250 break; 12251 case 'n': 12252 ch->bc->nojitter = 1; 12253 chan_misdn_log(1, ch->bc->port, " --> nojitter\n"); 12254 break; 12255 default: 12256 ch->jb_len = 4000; 12257 ch->jb_upper_threshold = 0; 12258 chan_misdn_log(1, ch->bc->port, " --> buffer_len:%d (default)\n", ch->jb_len); 12259 chan_misdn_log(1, ch->bc->port, " --> upper_threshold:%d (default)\n", ch->jb_upper_threshold); 12260 break; 12261 } 12262 break; 12263 case 'v': 12264 tok++; 12265 12266 switch (tok[0]) { 12267 case 'r' : 12268 rxgain = atoi(++tok); 12269 if (rxgain < -8) { 12270 rxgain = -8; 12271 } 12272 if (rxgain > 8) { 12273 rxgain = 8; 12274 } 12275 ch->bc->rxgain = rxgain; 12276 chan_misdn_log(1, ch->bc->port, "SETOPT: Volume:%d\n", rxgain); 12277 break; 12278 case 't': 12279 txgain = atoi(++tok); 12280 if (txgain < -8) { 12281 txgain = -8; 12282 } 12283 if (txgain > 8) { 12284 txgain = 8; 12285 } 12286 ch->bc->txgain = txgain; 12287 chan_misdn_log(1, ch->bc->port, "SETOPT: Volume:%d\n", txgain); 12288 break; 12289 } 12290 break; 12291 case 'c': 12292 keyidx = atoi(++tok); 12293 { 12294 char keys[4096]; 12295 char *key = NULL; 12296 char *tmp = keys; 12297 int i; 12298 12299 misdn_cfg_get(0, MISDN_GEN_CRYPT_KEYS, keys, sizeof(keys)); 12300 12301 for (i = 0; i < keyidx; i++) { 12302 key = strsep(&tmp, ","); 12303 } 12304 12305 if (key) { 12306 ast_copy_string(ch->bc->crypt_key, key, sizeof(ch->bc->crypt_key)); 12307 } 12308 12309 chan_misdn_log(0, ch->bc->port, "SETOPT: crypt with key:%s\n", ch->bc->crypt_key); 12310 break; 12311 } 12312 case 'e': 12313 chan_misdn_log(1, ch->bc->port, "SETOPT: EchoCancel\n"); 12314 12315 if (neglect) { 12316 chan_misdn_log(1, ch->bc->port, " --> disabled\n"); 12317 #ifdef MISDN_1_2 12318 *ch->bc->pipeline = 0; 12319 #else 12320 ch->bc->ec_enable = 0; 12321 #endif 12322 } else { 12323 #ifdef MISDN_1_2 12324 update_pipeline_config(ch->bc); 12325 #else 12326 ch->bc->ec_enable = 1; 12327 ch->bc->orig = ch->originator; 12328 tok++; 12329 if (*tok) { 12330 ch->bc->ec_deftaps = atoi(tok); 12331 } 12332 #endif 12333 } 12334 break; 12335 case 'h': 12336 chan_misdn_log(1, ch->bc->port, "SETOPT: Digital\n"); 12337 12338 if (strlen(tok) > 1 && tok[1] == '1') { 12339 chan_misdn_log(1, ch->bc->port, "SETOPT: HDLC \n"); 12340 if (!ch->bc->hdlc) { 12341 ch->bc->hdlc = 1; 12342 } 12343 } 12344 ch->bc->capability = INFO_CAPABILITY_DIGITAL_UNRESTRICTED; 12345 break; 12346 case 's': 12347 chan_misdn_log(1, ch->bc->port, "SETOPT: Send DTMF\n"); 12348 ch->bc->send_dtmf = 1; 12349 break; 12350 case 'f': 12351 chan_misdn_log(1, ch->bc->port, "SETOPT: Faxdetect\n"); 12352 ch->faxdetect = 1; 12353 misdn_cfg_get(ch->bc->port, MISDN_CFG_FAXDETECT_TIMEOUT, &ch->faxdetect_timeout, sizeof(ch->faxdetect_timeout)); 12354 break; 12355 case 'a': 12356 chan_misdn_log(1, ch->bc->port, "SETOPT: AST_DSP (for DTMF)\n"); 12357 ch->ast_dsp = 1; 12358 break; 12359 case 'p': 12360 chan_misdn_log(1, ch->bc->port, "SETOPT: callerpres: %s\n", &tok[1]); 12361 /* CRICH: callingpres!!! */ 12362 if (strstr(tok, "allowed")) { 12363 ch->bc->presentation = 0; 12364 ch->bc->set_presentation = 1; 12365 } else if (strstr(tok, "restricted")) { 12366 ch->bc->presentation = 1; 12367 ch->bc->set_presentation = 1; 12368 } else if (strstr(tok, "not_screened")) { 12369 chan_misdn_log(0, ch->bc->port, "SETOPT: callerpres: not_screened is deprecated\n"); 12370 ch->bc->presentation = 1; 12371 ch->bc->set_presentation = 1; 12372 } 12373 break; 12374 case 'i' : 12375 chan_misdn_log(1, ch->bc->port, "Ignoring dtmf tones, just use them inband\n"); 12376 ch->ignore_dtmf = 1; 12377 break; 12378 default: 12379 break; 12380 } 12381 } 12382 12383 if (change_jitter) { 12384 config_jitterbuffer(ch); 12385 } 12386 12387 if (ch->faxdetect || ch->ast_dsp) { 12388 if (!ch->dsp) { 12389 ch->dsp = ast_dsp_new(); 12390 } 12391 if (ch->dsp) { 12392 ast_dsp_set_features(ch->dsp, DSP_FEATURE_DIGIT_DETECT | DSP_FEATURE_FAX_DETECT); 12393 } 12394 } 12395 12396 if (ch->ast_dsp) { 12397 chan_misdn_log(1, ch->bc->port, "SETOPT: with AST_DSP we deactivate mISDN_dsp\n"); 12398 ch->bc->nodsp = 1; 12399 } 12400 12401 return 0; 12402 }
static int misdn_tasks_add | ( | int | timeout, | |
ast_sched_cb | callback, | |||
const void * | data | |||
) | [static] |
Definition at line 3571 of file chan_misdn.c.
References _misdn_tasks_add_variable().
Referenced by load_module().
03572 { 03573 return _misdn_tasks_add_variable(timeout, callback, data, 0); 03574 }
static int misdn_tasks_add_variable | ( | int | timeout, | |
ast_sched_cb | callback, | |||
const void * | data | |||
) | [static] |
Definition at line 3576 of file chan_misdn.c.
References _misdn_tasks_add_variable().
Referenced by cb_events().
03577 { 03578 return _misdn_tasks_add_variable(timeout, callback, data, 1); 03579 }
static void misdn_tasks_destroy | ( | void | ) | [static] |
Definition at line 3541 of file chan_misdn.c.
References cb_log, chan_misdn_log(), misdn_tasks, misdn_tasks_thread, and sched_context_destroy().
Referenced by unload_module().
03542 { 03543 if (misdn_tasks) { 03544 chan_misdn_log(4, 0, "Killing misdn_tasks thread\n"); 03545 if (pthread_cancel(misdn_tasks_thread) == 0) { 03546 cb_log(4, 0, "Joining misdn_tasks thread\n"); 03547 pthread_join(misdn_tasks_thread, NULL); 03548 } 03549 sched_context_destroy(misdn_tasks); 03550 } 03551 }
static void misdn_tasks_init | ( | void | ) | [static] |
Definition at line 3521 of file chan_misdn.c.
References chan_misdn_log(), misdn_tasks, misdn_tasks_thread, misdn_tasks_thread_func(), pthread_create, and sched_context_create().
Referenced by _misdn_tasks_add_variable().
03522 { 03523 sem_t blocker; 03524 int i = 5; 03525 03526 if (sem_init(&blocker, 0, 0)) { 03527 perror("chan_misdn: Failed to initialize semaphore!"); 03528 exit(1); 03529 } 03530 03531 chan_misdn_log(4, 0, "Starting misdn_tasks thread\n"); 03532 03533 misdn_tasks = sched_context_create(); 03534 pthread_create(&misdn_tasks_thread, NULL, misdn_tasks_thread_func, &blocker); 03535 03536 while (sem_wait(&blocker) && --i) { 03537 } 03538 sem_destroy(&blocker); 03539 }
static void misdn_tasks_remove | ( | int | task_id | ) | [static] |
Definition at line 3581 of file chan_misdn.c.
References AST_SCHED_DEL, and misdn_tasks.
Referenced by chan_list_destructor().
03582 { 03583 AST_SCHED_DEL(misdn_tasks, task_id); 03584 }
static void* misdn_tasks_thread_func | ( | void * | data | ) | [static] |
Definition at line 3495 of file chan_misdn.c.
References ast_sched_runq(), ast_sched_wait(), chan_misdn_log(), misdn_tasks, and sighandler().
Referenced by misdn_tasks_init().
03496 { 03497 int wait; 03498 struct sigaction sa; 03499 03500 sa.sa_handler = sighandler; 03501 sa.sa_flags = SA_NODEFER; 03502 sigemptyset(&sa.sa_mask); 03503 sigaddset(&sa.sa_mask, SIGUSR1); 03504 sigaction(SIGUSR1, &sa, NULL); 03505 03506 sem_post((sem_t *)data); 03507 03508 while (1) { 03509 wait = ast_sched_wait(misdn_tasks); 03510 if (wait < 0) { 03511 wait = 8000; 03512 } 03513 if (poll(NULL, 0, wait) < 0) { 03514 chan_misdn_log(4, 0, "Waking up misdn_tasks thread\n"); 03515 } 03516 ast_sched_runq(misdn_tasks); 03517 } 03518 return NULL; 03519 }
static void misdn_tasks_wakeup | ( | void | ) | [inline, static] |
Definition at line 3553 of file chan_misdn.c.
References misdn_tasks_thread.
Referenced by _misdn_tasks_add_variable().
03554 { 03555 pthread_kill(misdn_tasks_thread, SIGUSR1); 03556 }
static int misdn_to_ast_plan | ( | enum mISDN_NUMBER_PLAN | number_plan | ) | [static] |
Definition at line 1970 of file chan_misdn.c.
References NUMPLAN_DATA, NUMPLAN_ISDN, NUMPLAN_NATIONAL, NUMPLAN_PRIVATE, NUMPLAN_TELEX, and NUMPLAN_UNKNOWN.
Referenced by cb_events(), misdn_copy_redirecting_to_ast(), misdn_queue_connected_line_update(), and misdn_update_caller_id().
01971 { 01972 int ast_number_plan; 01973 01974 switch (number_plan) { 01975 default: 01976 case NUMPLAN_UNKNOWN: 01977 ast_number_plan = NUMPLAN_UNKNOWN; 01978 break; 01979 01980 case NUMPLAN_ISDN: 01981 ast_number_plan = NUMPLAN_ISDN; 01982 break; 01983 01984 case NUMPLAN_DATA: 01985 ast_number_plan = NUMPLAN_DATA; 01986 break; 01987 01988 case NUMPLAN_TELEX: 01989 ast_number_plan = NUMPLAN_TELEX; 01990 break; 01991 01992 case NUMPLAN_NATIONAL: 01993 ast_number_plan = NUMPLAN_NATIONAL; 01994 break; 01995 01996 case NUMPLAN_PRIVATE: 01997 ast_number_plan = NUMPLAN_PRIVATE; 01998 break; 01999 } 02000 02001 return ast_number_plan; 02002 }
static int misdn_to_ast_pres | ( | int | presentation | ) | [static] |
Definition at line 2087 of file chan_misdn.c.
References AST_PRES_ALLOWED, AST_PRES_RESTRICTED, and AST_PRES_UNAVAILABLE.
Referenced by cb_events(), misdn_copy_redirecting_to_ast(), misdn_queue_connected_line_update(), and misdn_update_caller_id().
02088 { 02089 switch (presentation) { 02090 default: 02091 case 0: 02092 presentation = AST_PRES_ALLOWED; 02093 break; 02094 02095 case 1: 02096 presentation = AST_PRES_RESTRICTED; 02097 break; 02098 02099 case 2: 02100 presentation = AST_PRES_UNAVAILABLE; 02101 break; 02102 } 02103 02104 return presentation; 02105 }
static enum AST_REDIRECTING_REASON misdn_to_ast_reason | ( | const enum mISDN_REDIRECTING_REASON | q931 | ) | [static] |
Definition at line 2284 of file chan_misdn.c.
References AST_REDIRECTING_REASON_CALL_FWD_DTE, AST_REDIRECTING_REASON_DEFLECTION, AST_REDIRECTING_REASON_NO_ANSWER, AST_REDIRECTING_REASON_OUT_OF_ORDER, AST_REDIRECTING_REASON_UNCONDITIONAL, AST_REDIRECTING_REASON_UNKNOWN, AST_REDIRECTING_REASON_USER_BUSY, mISDN_REDIRECTING_REASON_CALL_FWD, mISDN_REDIRECTING_REASON_CALL_FWD_BUSY, mISDN_REDIRECTING_REASON_CALL_FWD_DTE, mISDN_REDIRECTING_REASON_DEFLECTION, mISDN_REDIRECTING_REASON_NO_REPLY, mISDN_REDIRECTING_REASON_OUT_OF_ORDER, and mISDN_REDIRECTING_REASON_UNKNOWN.
Referenced by misdn_copy_redirecting_to_ast().
02285 { 02286 enum AST_REDIRECTING_REASON ast; 02287 02288 switch (q931) { 02289 default: 02290 case mISDN_REDIRECTING_REASON_UNKNOWN: 02291 ast = AST_REDIRECTING_REASON_UNKNOWN; 02292 break; 02293 02294 case mISDN_REDIRECTING_REASON_CALL_FWD_BUSY: 02295 ast = AST_REDIRECTING_REASON_USER_BUSY; 02296 break; 02297 02298 case mISDN_REDIRECTING_REASON_NO_REPLY: 02299 ast = AST_REDIRECTING_REASON_NO_ANSWER; 02300 break; 02301 02302 case mISDN_REDIRECTING_REASON_DEFLECTION: 02303 ast = AST_REDIRECTING_REASON_DEFLECTION; 02304 break; 02305 02306 case mISDN_REDIRECTING_REASON_OUT_OF_ORDER: 02307 ast = AST_REDIRECTING_REASON_OUT_OF_ORDER; 02308 break; 02309 02310 case mISDN_REDIRECTING_REASON_CALL_FWD_DTE: 02311 ast = AST_REDIRECTING_REASON_CALL_FWD_DTE; 02312 break; 02313 02314 case mISDN_REDIRECTING_REASON_CALL_FWD: 02315 ast = AST_REDIRECTING_REASON_UNCONDITIONAL; 02316 break; 02317 } 02318 02319 return ast; 02320 }
static int misdn_to_ast_screen | ( | int | screening | ) | [static] |
Definition at line 2180 of file chan_misdn.c.
References AST_PRES_NETWORK_NUMBER, AST_PRES_USER_NUMBER_FAILED_SCREEN, AST_PRES_USER_NUMBER_PASSED_SCREEN, and AST_PRES_USER_NUMBER_UNSCREENED.
Referenced by cb_events(), misdn_copy_redirecting_to_ast(), misdn_queue_connected_line_update(), and misdn_update_caller_id().
02181 { 02182 switch (screening) { 02183 default: 02184 case 0: 02185 screening = AST_PRES_USER_NUMBER_UNSCREENED; 02186 break; 02187 02188 case 1: 02189 screening = AST_PRES_USER_NUMBER_PASSED_SCREEN; 02190 break; 02191 02192 case 2: 02193 screening = AST_PRES_USER_NUMBER_FAILED_SCREEN; 02194 break; 02195 02196 case 3: 02197 screening = AST_PRES_NETWORK_NUMBER; 02198 break; 02199 } 02200 02201 return screening; 02202 }
static int misdn_to_ast_ton | ( | enum mISDN_NUMBER_TYPE | number_type | ) | [static] |
Definition at line 1844 of file chan_misdn.c.
References NUMTYPE_ABBREVIATED, NUMTYPE_INTERNATIONAL, NUMTYPE_NATIONAL, NUMTYPE_NETWORK_SPECIFIC, NUMTYPE_SUBSCRIBER, and NUMTYPE_UNKNOWN.
Referenced by cb_events(), misdn_copy_redirecting_to_ast(), misdn_queue_connected_line_update(), and misdn_update_caller_id().
01845 { 01846 int ast_number_type; 01847 01848 switch (number_type) { 01849 default: 01850 case NUMTYPE_UNKNOWN: 01851 ast_number_type = NUMTYPE_UNKNOWN << 4; 01852 break; 01853 01854 case NUMTYPE_INTERNATIONAL: 01855 ast_number_type = NUMTYPE_INTERNATIONAL << 4; 01856 break; 01857 01858 case NUMTYPE_NATIONAL: 01859 ast_number_type = NUMTYPE_NATIONAL << 4; 01860 break; 01861 01862 case NUMTYPE_NETWORK_SPECIFIC: 01863 ast_number_type = NUMTYPE_NETWORK_SPECIFIC << 4; 01864 break; 01865 01866 case NUMTYPE_SUBSCRIBER: 01867 ast_number_type = NUMTYPE_SUBSCRIBER << 4; 01868 break; 01869 01870 case NUMTYPE_ABBREVIATED: 01871 ast_number_type = NUMTYPE_ABBREVIATED << 4; 01872 break; 01873 } 01874 01875 return ast_number_type; 01876 }
static const char* misdn_to_str_plan | ( | enum mISDN_NUMBER_PLAN | number_plan | ) | [static] |
Definition at line 1928 of file chan_misdn.c.
References NUMPLAN_DATA, NUMPLAN_ISDN, NUMPLAN_NATIONAL, NUMPLAN_PRIVATE, NUMPLAN_TELEX, NUMPLAN_UNKNOWN, and str.
Referenced by cb_events().
01929 { 01930 const char *str; 01931 01932 switch (number_plan) { 01933 default: 01934 case NUMPLAN_UNKNOWN: 01935 str = "Unknown"; 01936 break; 01937 01938 case NUMPLAN_ISDN: 01939 str = "ISDN"; 01940 break; 01941 01942 case NUMPLAN_DATA: 01943 str = "Data"; 01944 break; 01945 01946 case NUMPLAN_TELEX: 01947 str = "Telex"; 01948 break; 01949 01950 case NUMPLAN_NATIONAL: 01951 str = "National"; 01952 break; 01953 01954 case NUMPLAN_PRIVATE: 01955 str = "Private"; 01956 break; 01957 } 01958 01959 return str; 01960 }
static const char* misdn_to_str_pres | ( | int | presentation | ) | [static] |
Definition at line 2054 of file chan_misdn.c.
References str.
Referenced by cb_events(), and update_config().
02055 { 02056 const char *str; 02057 02058 switch (presentation) { 02059 case 0: 02060 str = "Allowed"; 02061 break; 02062 02063 case 1: 02064 str = "Restricted"; 02065 break; 02066 02067 case 2: 02068 str = "Unavailable"; 02069 break; 02070 02071 default: 02072 str = "Unknown"; 02073 break; 02074 } 02075 02076 return str; 02077 }
static const char* misdn_to_str_screen | ( | int | screening | ) | [static] |
Definition at line 2143 of file chan_misdn.c.
References str.
Referenced by cb_events(), and update_config().
02144 { 02145 const char *str; 02146 02147 switch (screening) { 02148 case 0: 02149 str = "Unscreened"; 02150 break; 02151 02152 case 1: 02153 str = "Passed Screen"; 02154 break; 02155 02156 case 2: 02157 str = "Failed Screen"; 02158 break; 02159 02160 case 3: 02161 str = "Network Number"; 02162 break; 02163 02164 default: 02165 str = "Unknown"; 02166 break; 02167 } 02168 02169 return str; 02170 }
static const char* misdn_to_str_ton | ( | enum mISDN_NUMBER_TYPE | number_type | ) | [static] |
Definition at line 1802 of file chan_misdn.c.
References NUMTYPE_ABBREVIATED, NUMTYPE_INTERNATIONAL, NUMTYPE_NATIONAL, NUMTYPE_NETWORK_SPECIFIC, NUMTYPE_SUBSCRIBER, NUMTYPE_UNKNOWN, and str.
Referenced by cb_events().
01803 { 01804 const char *str; 01805 01806 switch (number_type) { 01807 default: 01808 case NUMTYPE_UNKNOWN: 01809 str = "Unknown"; 01810 break; 01811 01812 case NUMTYPE_INTERNATIONAL: 01813 str = "International"; 01814 break; 01815 01816 case NUMTYPE_NATIONAL: 01817 str = "National"; 01818 break; 01819 01820 case NUMTYPE_NETWORK_SPECIFIC: 01821 str = "Network Specific"; 01822 break; 01823 01824 case NUMTYPE_SUBSCRIBER: 01825 str = "Subscriber"; 01826 break; 01827 01828 case NUMTYPE_ABBREVIATED: 01829 str = "Abbreviated"; 01830 break; 01831 } 01832 01833 return str; 01834 }
static void misdn_update_caller_id | ( | struct ast_channel * | ast, | |
const struct misdn_party_id * | id, | |||
char * | cid_tag | |||
) | [static] |
Definition at line 6105 of file chan_misdn.c.
References ast_party_caller::ani, ast_channel_lock, ast_channel_set_caller_event(), ast_channel_unlock, ast_party_caller_set_init(), ast_channel::caller, id, ast_party_caller::id, misdn_to_ast_plan(), misdn_to_ast_pres(), misdn_to_ast_screen(), misdn_to_ast_ton(), ast_party_id::number, ast_party_number::plan, ast_party_number::presentation, ast_party_number::str, ast_party_id::tag, and ast_party_number::valid.
Referenced by misdn_update_remote_party().
06106 { 06107 struct ast_party_caller caller; 06108 struct ast_set_party_caller update_caller; 06109 06110 memset(&update_caller, 0, sizeof(update_caller)); 06111 update_caller.id.number = 1; 06112 update_caller.ani.number = 1; 06113 06114 ast_channel_lock(ast); 06115 ast_party_caller_set_init(&caller, &ast->caller); 06116 06117 caller.id.number.valid = 1; 06118 caller.id.number.str = (char *) id->number; 06119 caller.id.number.plan = misdn_to_ast_ton(id->number_type) 06120 | misdn_to_ast_plan(id->number_plan); 06121 caller.id.number.presentation = misdn_to_ast_pres(id->presentation) 06122 | misdn_to_ast_screen(id->screening); 06123 06124 caller.ani.number = caller.id.number; 06125 06126 caller.id.tag = cid_tag; 06127 caller.ani.tag = cid_tag; 06128 06129 ast_channel_set_caller_event(ast, &caller, &update_caller); 06130 ast_channel_unlock(ast); 06131 }
static void misdn_update_connected_line | ( | struct ast_channel * | ast, | |
struct misdn_bchannel * | bc, | |||
int | originator | |||
) | [static] |
Definition at line 6233 of file chan_misdn.c.
References chan_list::ast, chan_list::bc, misdn_bchannel::caller, misdn_bchannel::connected, EVENT_FACILITY, EVENT_NOTIFY, misdn_bchannel::fac_out, MISDN_ASTERISK_TECH_PVT, MISDN_CONNECTED, misdn_get_connected_line(), misdn_lib_is_ptp(), misdn_lib_port_is_nt(), misdn_lib_send_event(), mISDN_NOTIFY_CODE_CALL_TRANSFER_ACTIVE, misdn_bchannel::notify_description_code, ORG_MISDN, misdn_bchannel::outgoing_colp, misdn_bchannel::port, misdn_party_id::presentation, print_facility(), misdn_bchannel::redirecting, chan_list::state, misdn_party_redirecting::to, and misdn_party_redirecting::to_changed.
Referenced by misdn_indication().
06234 { 06235 struct chan_list *ch; 06236 06237 misdn_get_connected_line(ast, bc, originator); 06238 if (originator == ORG_MISDN) { 06239 bc->redirecting.to = bc->connected; 06240 } else { 06241 bc->redirecting.to = bc->caller; 06242 } 06243 switch (bc->outgoing_colp) { 06244 case 1:/* restricted */ 06245 bc->redirecting.to.presentation = 1;/* restricted */ 06246 break; 06247 case 2:/* blocked */ 06248 /* Don't tell the remote party that the call was transferred. */ 06249 return; 06250 default: 06251 break; 06252 } 06253 06254 ch = MISDN_ASTERISK_TECH_PVT(ast); 06255 if (ch->state == MISDN_CONNECTED 06256 || originator != ORG_MISDN) { 06257 int is_ptmp; 06258 06259 is_ptmp = !misdn_lib_is_ptp(bc->port); 06260 if (is_ptmp) { 06261 /* 06262 * We should not send these messages to the network if we are 06263 * the CPE side since phones do not transfer calls within 06264 * themselves. Well... If you consider handing the handset to 06265 * someone else a transfer then how is the network to know? 06266 */ 06267 if (!misdn_lib_port_is_nt(bc->port)) { 06268 return; 06269 } 06270 if (ch->state != MISDN_CONNECTED) { 06271 /* Send NOTIFY(Nie(transfer-active), RDNie(redirecting.to data)) */ 06272 bc->redirecting.to_changed = 1; 06273 bc->notify_description_code = mISDN_NOTIFY_CODE_CALL_TRANSFER_ACTIVE; 06274 misdn_lib_send_event(bc, EVENT_NOTIFY); 06275 #if defined(AST_MISDN_ENHANCEMENTS) 06276 } else { 06277 /* Send FACILITY(Fie(RequestSubaddress), Nie(transfer-active), RDNie(redirecting.to data)) */ 06278 bc->redirecting.to_changed = 1; 06279 bc->notify_description_code = mISDN_NOTIFY_CODE_CALL_TRANSFER_ACTIVE; 06280 bc->fac_out.Function = Fac_RequestSubaddress; 06281 bc->fac_out.u.RequestSubaddress.InvokeID = ++misdn_invoke_id; 06282 06283 /* Send message */ 06284 print_facility(&bc->fac_out, bc); 06285 misdn_lib_send_event(bc, EVENT_FACILITY); 06286 #endif /* defined(AST_MISDN_ENHANCEMENTS) */ 06287 } 06288 #if defined(AST_MISDN_ENHANCEMENTS) 06289 } else { 06290 /* Send FACILITY(Fie(EctInform(transfer-active, redirecting.to data))) */ 06291 bc->fac_out.Function = Fac_EctInform; 06292 bc->fac_out.u.EctInform.InvokeID = ++misdn_invoke_id; 06293 bc->fac_out.u.EctInform.Status = 1;/* active */ 06294 bc->fac_out.u.EctInform.RedirectionPresent = 1;/* Must be present when status is active */ 06295 misdn_PresentedNumberUnscreened_fill(&bc->fac_out.u.EctInform.Redirection, 06296 &bc->redirecting.to); 06297 06298 /* Send message */ 06299 print_facility(&bc->fac_out, bc); 06300 misdn_lib_send_event(bc, EVENT_FACILITY); 06301 #endif /* defined(AST_MISDN_ENHANCEMENTS) */ 06302 } 06303 } 06304 }
static void misdn_update_redirecting | ( | struct ast_channel * | ast, | |
struct misdn_bchannel * | bc, | |||
int | originator | |||
) | [static] |
Definition at line 6413 of file chan_misdn.c.
References EVENT_FACILITY, EVENT_NOTIFY, ast_channel::exten, misdn_bchannel::fac_out, match(), misdn_copy_redirecting_from_ast(), misdn_lib_is_ptp(), misdn_lib_port_is_nt(), misdn_lib_send_event(), mISDN_NOTIFY_CODE_CALL_IS_DIVERTING, misdn_bchannel::notify_description_code, misdn_party_id::number, ORG_MISDN, misdn_bchannel::outgoing_colp, misdn_bchannel::port, misdn_party_id::presentation, print_facility(), misdn_party_redirecting::reason, misdn_bchannel::redirecting, misdn_party_redirecting::to, and misdn_party_redirecting::to_changed.
Referenced by misdn_indication().
06414 { 06415 int is_ptmp; 06416 06417 misdn_copy_redirecting_from_ast(bc, ast); 06418 switch (bc->outgoing_colp) { 06419 case 1:/* restricted */ 06420 bc->redirecting.to.presentation = 1;/* restricted */ 06421 break; 06422 case 2:/* blocked */ 06423 /* Don't tell the remote party that the call was redirected. */ 06424 return; 06425 default: 06426 break; 06427 } 06428 06429 if (originator != ORG_MISDN) { 06430 return; 06431 } 06432 06433 is_ptmp = !misdn_lib_is_ptp(bc->port); 06434 if (is_ptmp) { 06435 /* 06436 * We should not send these messages to the network if we are 06437 * the CPE side since phones do not redirect calls within 06438 * themselves. Well... If you consider someone else picking up 06439 * the handset a redirection then how is the network to know? 06440 */ 06441 if (!misdn_lib_port_is_nt(bc->port)) { 06442 return; 06443 } 06444 /* Send NOTIFY(call-is-diverting, redirecting.to data) */ 06445 bc->redirecting.to_changed = 1; 06446 bc->notify_description_code = mISDN_NOTIFY_CODE_CALL_IS_DIVERTING; 06447 misdn_lib_send_event(bc, EVENT_NOTIFY); 06448 #if defined(AST_MISDN_ENHANCEMENTS) 06449 } else { 06450 int match; /* TRUE if the dialed number matches the redirecting to number */ 06451 06452 match = (strcmp(ast->exten, bc->redirecting.to.number) == 0) ? 1 : 0; 06453 if (!bc->div_leg_3_tx_pending 06454 || !match) { 06455 /* Send DivertingLegInformation1 */ 06456 bc->fac_out.Function = Fac_DivertingLegInformation1; 06457 bc->fac_out.u.DivertingLegInformation1.InvokeID = ++misdn_invoke_id; 06458 bc->fac_out.u.DivertingLegInformation1.DiversionReason = 06459 misdn_to_diversion_reason(bc->redirecting.reason); 06460 bc->fac_out.u.DivertingLegInformation1.SubscriptionOption = 2;/* notificationWithDivertedToNr */ 06461 bc->fac_out.u.DivertingLegInformation1.DivertedToPresent = 1; 06462 misdn_PresentedNumberUnscreened_fill(&bc->fac_out.u.DivertingLegInformation1.DivertedTo, &bc->redirecting.to); 06463 print_facility(&bc->fac_out, bc); 06464 misdn_lib_send_event(bc, EVENT_FACILITY); 06465 } 06466 bc->div_leg_3_tx_pending = 0; 06467 06468 /* Send DivertingLegInformation3 */ 06469 bc->fac_out.Function = Fac_DivertingLegInformation3; 06470 bc->fac_out.u.DivertingLegInformation3.InvokeID = ++misdn_invoke_id; 06471 bc->fac_out.u.DivertingLegInformation3.PresentationAllowedIndicator = 06472 bc->redirecting.to.presentation == 0 ? 1 : 0; 06473 print_facility(&bc->fac_out, bc); 06474 misdn_lib_send_event(bc, EVENT_FACILITY); 06475 #endif /* defined(AST_MISDN_ENHANCEMENTS) */ 06476 } 06477 }
static void misdn_update_remote_party | ( | struct ast_channel * | ast, | |
const struct misdn_party_id * | id, | |||
enum AST_CONNECTED_LINE_UPDATE_SOURCE | source, | |||
char * | cid_tag | |||
) | [static] |
Definition at line 6144 of file chan_misdn.c.
References misdn_queue_connected_line_update(), and misdn_update_caller_id().
Referenced by cb_events(), and misdn_facility_ie_handler().
06145 { 06146 misdn_update_caller_id(ast, id, cid_tag); 06147 misdn_queue_connected_line_update(ast, id, source, cid_tag); 06148 }
static int misdn_write | ( | struct ast_channel * | ast, | |
struct ast_frame * | frame | |||
) | [static] |
Definition at line 7390 of file chan_misdn.c.
References misdn_bchannel::addr, chan_list::ast, ast_debug, ast_getformatname(), ast_log(), chan_list::bc, misdn_bchannel::bc_state, BCHAN_ACTIVATED, BCHAN_BRIDGED, ast_channel::caller, chan_misdn_log(), ast_frame_subclass::codec, ast_frame::data, chan_list::dropped_frame_cnt, ast_channel::exten, chan_list::frame, chan_list::hold, ast_party_caller::id, misdn_bchannel::l3_id, LOG_WARNING, MISDN_ASTERISK_TECH_PVT, misdn_get_ch_state(), MISDN_HOLD_IDLE, misdn_lib_tone_generator_start(), chan_list::notxtone, ast_party_id::number, misdn_bchannel::port, prefformat, ast_frame::ptr, S_COR, ast_frame::samples, ast_frame::src, hold_info::state, ast_party_number::str, ast_frame::subclass, chan_list::ts, and ast_party_number::valid.
07391 { 07392 struct chan_list *ch; 07393 int i = 0; 07394 07395 if (!ast || !(ch = MISDN_ASTERISK_TECH_PVT(ast))) { 07396 return -1; 07397 } 07398 07399 if (ch->hold.state != MISDN_HOLD_IDLE) { 07400 chan_misdn_log(7, 0, "misdn_write: Returning because hold active\n"); 07401 return 0; 07402 } 07403 07404 if (!ch->bc) { 07405 ast_log(LOG_WARNING, "private but no bc\n"); 07406 return -1; 07407 } 07408 07409 if (ch->notxtone) { 07410 chan_misdn_log(7, ch->bc->port, "misdn_write: Returning because notxtone\n"); 07411 return 0; 07412 } 07413 07414 07415 if (!frame->subclass.codec) { 07416 chan_misdn_log(4, ch->bc->port, "misdn_write: * prods us\n"); 07417 return 0; 07418 } 07419 07420 if (!(frame->subclass.codec & prefformat)) { 07421 chan_misdn_log(-1, ch->bc->port, "Got Unsupported Frame with Format:%s\n", ast_getformatname(frame->subclass.codec)); 07422 return 0; 07423 } 07424 07425 07426 if (!frame->samples) { 07427 chan_misdn_log(4, ch->bc->port, "misdn_write: zero write\n"); 07428 07429 if (!strcmp(frame->src,"ast_prod")) { 07430 chan_misdn_log(1, ch->bc->port, "misdn_write: state (%s) prodded.\n", misdn_get_ch_state(ch)); 07431 07432 if (ch->ts) { 07433 chan_misdn_log(4, ch->bc->port, "Starting Playtones\n"); 07434 misdn_lib_tone_generator_start(ch->bc); 07435 } 07436 return 0; 07437 } 07438 07439 return -1; 07440 } 07441 07442 if (!ch->bc->addr) { 07443 chan_misdn_log(8, ch->bc->port, "misdn_write: no addr for bc dropping:%d\n", frame->samples); 07444 return 0; 07445 } 07446 07447 #ifdef MISDN_DEBUG 07448 { 07449 int i; 07450 int max = 5 > frame->samples ? frame->samples : 5; 07451 07452 ast_debug(1, "write2mISDN %p %d bytes: ", p, frame->samples); 07453 07454 for (i = 0; i < max; i++) { 07455 ast_debug(1, "%2.2x ", ((char *) frame->data.ptr)[i]); 07456 } 07457 } 07458 #endif 07459 07460 switch (ch->bc->bc_state) { 07461 case BCHAN_ACTIVATED: 07462 case BCHAN_BRIDGED: 07463 break; 07464 default: 07465 if (!ch->dropped_frame_cnt) { 07466 chan_misdn_log(5, ch->bc->port, 07467 "BC not active (nor bridged) dropping: %d frames addr:%x exten:%s cid:%s ch->state:%s bc_state:%d l3id:%x\n", 07468 frame->samples, ch->bc->addr, ast->exten, 07469 S_COR(ast->caller.id.number.valid, ast->caller.id.number.str, ""), 07470 misdn_get_ch_state(ch), ch->bc->bc_state, ch->bc->l3_id); 07471 } 07472 07473 if (++ch->dropped_frame_cnt > 100) { 07474 ch->dropped_frame_cnt = 0; 07475 chan_misdn_log(5, ch->bc->port, "BC not active (nor bridged) dropping: %d frames addr:%x dropped > 100 frames!\n", frame->samples, ch->bc->addr); 07476 } 07477 07478 return 0; 07479 } 07480 07481 chan_misdn_log(9, ch->bc->port, "Sending :%d bytes to MISDN\n", frame->samples); 07482 if (!ch->bc->nojitter && misdn_cap_is_speech(ch->bc->capability)) { 07483 /* Buffered Transmit (triggered by read from isdn side)*/ 07484 if (misdn_jb_fill(ch->jb, frame->data.ptr, frame->samples) < 0) { 07485 if (ch->bc->active) { 07486 cb_log(0, ch->bc->port, "Misdn Jitterbuffer Overflow.\n"); 07487 } 07488 } 07489 07490 } else { 07491 /* transmit without jitterbuffer */ 07492 i = misdn_lib_tx2misdn_frm(ch->bc, frame->data.ptr, frame->samples); 07493 } 07494 07495 return 0; 07496 }
static int pbx_start_chan | ( | struct chan_list * | ch | ) | [static] |
Channel Queue End
Definition at line 8343 of file chan_misdn.c.
References chan_list::ast, ast_pbx_start(), and chan_list::need_hangup.
Referenced by do_immediate_setup(), misdn_overlap_dial_task(), and start_pbx().
08344 { 08345 int ret = ast_pbx_start(ch->ast); 08346 08347 ch->need_hangup = (ret >= 0) ? 0 : 1; 08348 08349 return ret; 08350 }
static void print_bc_info | ( | int | fd, | |
struct chan_list * | help, | |||
struct misdn_bchannel * | bc | |||
) | [static] |
Definition at line 4134 of file chan_misdn.c.
References misdn_bchannel::active, misdn_bchannel::addr, chan_list::addr, chan_list::ast, ast_cli(), misdn_bchannel::bc_state, bc_state2str(), bearer2str(), ast_channel::caller, misdn_bchannel::capability, misdn_bchannel::channel, ast_channel::context, misdn_bchannel::display, misdn_bchannel::ec_enable, ast_channel::exten, misdn_party_redirecting::from, misdn_bchannel::holded, ast_party_caller::id, misdn_bchannel::l3_id, chan_list::l3id, misdn_debug, misdn_get_ch_state(), ast_channel::name, misdn_party_id::name, ast_party_id::name, chan_list::norxtone, chan_list::notxtone, misdn_bchannel::nt, misdn_party_id::number, ast_party_id::number, ORG_AST, chan_list::originator, misdn_bchannel::pid, misdn_bchannel::port, misdn_bchannel::redirecting, ast_party_number::str, ast_party_name::str, misdn_party_redirecting::to, ast_party_number::valid, and ast_party_name::valid.
Referenced by handle_cli_misdn_show_channel(), and handle_cli_misdn_show_channels().
04135 { 04136 struct ast_channel *ast = help->ast; 04137 04138 ast_cli(fd, 04139 "* Pid:%d Port:%d Ch:%d Mode:%s Orig:%s dialed:%s\n" 04140 " --> caller:\"%s\" <%s>\n" 04141 " --> redirecting-from:\"%s\" <%s>\n" 04142 " --> redirecting-to:\"%s\" <%s>\n" 04143 " --> context:%s state:%s\n", 04144 bc->pid, 04145 bc->port, 04146 bc->channel, 04147 bc->nt ? "NT" : "TE", 04148 help->originator == ORG_AST ? "*" : "I", 04149 ast ? ast->exten : "", 04150 (ast && ast->caller.id.name.valid && ast->caller.id.name.str) 04151 ? ast->caller.id.name.str : "", 04152 (ast && ast->caller.id.number.valid && ast->caller.id.number.str) 04153 ? ast->caller.id.number.str : "", 04154 bc->redirecting.from.name, 04155 bc->redirecting.from.number, 04156 bc->redirecting.to.name, 04157 bc->redirecting.to.number, 04158 ast ? ast->context : "", 04159 misdn_get_ch_state(help)); 04160 if (misdn_debug[bc->port] > 0) { 04161 ast_cli(fd, 04162 " --> astname: %s\n" 04163 " --> ch_l3id: %x\n" 04164 " --> ch_addr: %x\n" 04165 " --> bc_addr: %x\n" 04166 " --> bc_l3id: %x\n" 04167 " --> display: %s\n" 04168 " --> activated: %d\n" 04169 " --> state: %s\n" 04170 " --> capability: %s\n" 04171 #ifdef MISDN_1_2 04172 " --> pipeline: %s\n" 04173 #else 04174 " --> echo_cancel: %d\n" 04175 #endif 04176 " --> notone : rx %d tx:%d\n" 04177 " --> bc_hold: %d\n", 04178 help->ast->name, 04179 help->l3id, 04180 help->addr, 04181 bc->addr, 04182 bc->l3_id, 04183 bc->display, 04184 bc->active, 04185 bc_state2str(bc->bc_state), 04186 bearer2str(bc->capability), 04187 #ifdef MISDN_1_2 04188 bc->pipeline, 04189 #else 04190 bc->ec_enable, 04191 #endif 04192 help->norxtone, help->notxtone, 04193 bc->holded); 04194 } 04195 }
static void print_bearer | ( | struct misdn_bchannel * | bc | ) | [static] |
Definition at line 3325 of file chan_misdn.c.
References bearer2str(), misdn_bchannel::capability, chan_misdn_log(), INFO_CODEC_ALAW, INFO_CODEC_ULAW, misdn_bchannel::law, and misdn_bchannel::port.
Referenced by cb_events().
03326 { 03327 chan_misdn_log(2, bc->port, " --> Bearer: %s\n", bearer2str(bc->capability)); 03328 03329 switch(bc->law) { 03330 case INFO_CODEC_ALAW: 03331 chan_misdn_log(2, bc->port, " --> Codec: Alaw\n"); 03332 break; 03333 case INFO_CODEC_ULAW: 03334 chan_misdn_log(2, bc->port, " --> Codec: Ulaw\n"); 03335 break; 03336 } 03337 }
static void print_facility | ( | const struct FacParm * | fac, | |
const const struct misdn_bchannel * | bc | |||
) | [static] |
Definition at line 2732 of file chan_misdn.c.
References chan_misdn_log(), and misdn_bchannel::port.
Referenced by handle_cli_misdn_send_facility(), misdn_answer(), misdn_call(), misdn_facility_exec(), misdn_facility_ie_handler(), misdn_update_connected_line(), and misdn_update_redirecting().
02733 { 02734 #if defined(AST_MISDN_ENHANCEMENTS) 02735 unsigned Index; 02736 #endif /* defined(AST_MISDN_ENHANCEMENTS) */ 02737 02738 switch (fac->Function) { 02739 #if defined(AST_MISDN_ENHANCEMENTS) 02740 case Fac_ActivationDiversion: 02741 chan_misdn_log(1, bc->port, " --> ActivationDiversion: InvokeID:%d\n", 02742 fac->u.ActivationDiversion.InvokeID); 02743 switch (fac->u.ActivationDiversion.ComponentType) { 02744 case FacComponent_Invoke: 02745 chan_misdn_log(1, bc->port, " --> Invoke: Procedure:%d BasicService:%d\n", 02746 fac->u.ActivationDiversion.Component.Invoke.Procedure, 02747 fac->u.ActivationDiversion.Component.Invoke.BasicService); 02748 chan_misdn_log(1, bc->port, " --> ForwardedTo:\n"); 02749 print_facility_Address(3, &fac->u.ActivationDiversion.Component.Invoke.ForwardedTo, bc); 02750 chan_misdn_log(1, bc->port, " --> ServedUserNr:\n"); 02751 print_facility_ServedUserNr(3, &fac->u.ActivationDiversion.Component.Invoke.ServedUser, bc); 02752 break; 02753 case FacComponent_Result: 02754 chan_misdn_log(1, bc->port, " --> Result\n"); 02755 break; 02756 default: 02757 break; 02758 } 02759 break; 02760 case Fac_DeactivationDiversion: 02761 chan_misdn_log(1, bc->port, " --> DeactivationDiversion: InvokeID:%d\n", 02762 fac->u.DeactivationDiversion.InvokeID); 02763 switch (fac->u.DeactivationDiversion.ComponentType) { 02764 case FacComponent_Invoke: 02765 chan_misdn_log(1, bc->port, " --> Invoke: Procedure:%d BasicService:%d\n", 02766 fac->u.DeactivationDiversion.Component.Invoke.Procedure, 02767 fac->u.DeactivationDiversion.Component.Invoke.BasicService); 02768 chan_misdn_log(1, bc->port, " --> ServedUserNr:\n"); 02769 print_facility_ServedUserNr(3, &fac->u.DeactivationDiversion.Component.Invoke.ServedUser, bc); 02770 break; 02771 case FacComponent_Result: 02772 chan_misdn_log(1, bc->port, " --> Result\n"); 02773 break; 02774 default: 02775 break; 02776 } 02777 break; 02778 case Fac_ActivationStatusNotificationDiv: 02779 chan_misdn_log(1, bc->port, " --> ActivationStatusNotificationDiv: InvokeID:%d Procedure:%d BasicService:%d\n", 02780 fac->u.ActivationStatusNotificationDiv.InvokeID, 02781 fac->u.ActivationStatusNotificationDiv.Procedure, 02782 fac->u.ActivationStatusNotificationDiv.BasicService); 02783 chan_misdn_log(1, bc->port, " --> ForwardedTo:\n"); 02784 print_facility_Address(2, &fac->u.ActivationStatusNotificationDiv.ForwardedTo, bc); 02785 chan_misdn_log(1, bc->port, " --> ServedUserNr:\n"); 02786 print_facility_ServedUserNr(2, &fac->u.ActivationStatusNotificationDiv.ServedUser, bc); 02787 break; 02788 case Fac_DeactivationStatusNotificationDiv: 02789 chan_misdn_log(1, bc->port, " --> DeactivationStatusNotificationDiv: InvokeID:%d Procedure:%d BasicService:%d\n", 02790 fac->u.DeactivationStatusNotificationDiv.InvokeID, 02791 fac->u.DeactivationStatusNotificationDiv.Procedure, 02792 fac->u.DeactivationStatusNotificationDiv.BasicService); 02793 chan_misdn_log(1, bc->port, " --> ServedUserNr:\n"); 02794 print_facility_ServedUserNr(2, &fac->u.DeactivationStatusNotificationDiv.ServedUser, bc); 02795 break; 02796 case Fac_InterrogationDiversion: 02797 chan_misdn_log(1, bc->port, " --> InterrogationDiversion: InvokeID:%d\n", 02798 fac->u.InterrogationDiversion.InvokeID); 02799 switch (fac->u.InterrogationDiversion.ComponentType) { 02800 case FacComponent_Invoke: 02801 chan_misdn_log(1, bc->port, " --> Invoke: Procedure:%d BasicService:%d\n", 02802 fac->u.InterrogationDiversion.Component.Invoke.Procedure, 02803 fac->u.InterrogationDiversion.Component.Invoke.BasicService); 02804 chan_misdn_log(1, bc->port, " --> ServedUserNr:\n"); 02805 print_facility_ServedUserNr(3, &fac->u.InterrogationDiversion.Component.Invoke.ServedUser, bc); 02806 break; 02807 case FacComponent_Result: 02808 chan_misdn_log(1, bc->port, " --> Result:\n"); 02809 if (fac->u.InterrogationDiversion.Component.Result.NumRecords) { 02810 for (Index = 0; Index < fac->u.InterrogationDiversion.Component.Result.NumRecords; ++Index) { 02811 chan_misdn_log(1, bc->port, " --> IntResult[%d]:\n", Index); 02812 print_facility_IntResult(3, &fac->u.InterrogationDiversion.Component.Result.List[Index], bc); 02813 } 02814 } 02815 break; 02816 default: 02817 break; 02818 } 02819 break; 02820 case Fac_DiversionInformation: 02821 chan_misdn_log(1, bc->port, " --> DiversionInformation: InvokeID:%d Reason:%d BasicService:%d\n", 02822 fac->u.DiversionInformation.InvokeID, 02823 fac->u.DiversionInformation.DiversionReason, 02824 fac->u.DiversionInformation.BasicService); 02825 if (fac->u.DiversionInformation.ServedUserSubaddress.Length) { 02826 chan_misdn_log(1, bc->port, " --> ServedUserSubaddress:\n"); 02827 print_facility_Subaddress(2, &fac->u.DiversionInformation.ServedUserSubaddress, bc); 02828 } 02829 if (fac->u.DiversionInformation.CallingAddressPresent) { 02830 chan_misdn_log(1, bc->port, " --> CallingAddress:\n"); 02831 print_facility_PresentedAddressScreened(2, &fac->u.DiversionInformation.CallingAddress, bc); 02832 } 02833 if (fac->u.DiversionInformation.OriginalCalledPresent) { 02834 chan_misdn_log(1, bc->port, " --> OriginalCalledNr:\n"); 02835 print_facility_PresentedNumberUnscreened(2, &fac->u.DiversionInformation.OriginalCalled, bc); 02836 } 02837 if (fac->u.DiversionInformation.LastDivertingPresent) { 02838 chan_misdn_log(1, bc->port, " --> LastDivertingNr:\n"); 02839 print_facility_PresentedNumberUnscreened(2, &fac->u.DiversionInformation.LastDiverting, bc); 02840 } 02841 if (fac->u.DiversionInformation.LastDivertingReasonPresent) { 02842 chan_misdn_log(1, bc->port, " --> LastDivertingReason:%d\n", fac->u.DiversionInformation.LastDivertingReason); 02843 } 02844 if (fac->u.DiversionInformation.UserInfo.Length) { 02845 chan_misdn_log(1, bc->port, " --> UserInfo Length:%d\n", fac->u.DiversionInformation.UserInfo.Length); 02846 } 02847 break; 02848 case Fac_CallDeflection: 02849 chan_misdn_log(1, bc->port, " --> CallDeflection: InvokeID:%d\n", 02850 fac->u.CallDeflection.InvokeID); 02851 switch (fac->u.CallDeflection.ComponentType) { 02852 case FacComponent_Invoke: 02853 chan_misdn_log(1, bc->port, " --> Invoke:\n"); 02854 if (fac->u.CallDeflection.Component.Invoke.PresentationAllowedToDivertedToUserPresent) { 02855 chan_misdn_log(1, bc->port, " --> PresentationAllowed:%d\n", 02856 fac->u.CallDeflection.Component.Invoke.PresentationAllowedToDivertedToUser); 02857 } 02858 chan_misdn_log(1, bc->port, " --> DeflectionAddress:\n"); 02859 print_facility_Address(3, &fac->u.CallDeflection.Component.Invoke.Deflection, bc); 02860 break; 02861 case FacComponent_Result: 02862 chan_misdn_log(1, bc->port, " --> Result\n"); 02863 break; 02864 default: 02865 break; 02866 } 02867 break; 02868 case Fac_CallRerouteing: 02869 chan_misdn_log(1, bc->port, " --> CallRerouteing: InvokeID:%d\n", 02870 fac->u.CallRerouteing.InvokeID); 02871 switch (fac->u.CallRerouteing.ComponentType) { 02872 case FacComponent_Invoke: 02873 chan_misdn_log(1, bc->port, " --> Invoke: Reason:%d Counter:%d\n", 02874 fac->u.CallRerouteing.Component.Invoke.ReroutingReason, 02875 fac->u.CallRerouteing.Component.Invoke.ReroutingCounter); 02876 chan_misdn_log(1, bc->port, " --> CalledAddress:\n"); 02877 print_facility_Address(3, &fac->u.CallRerouteing.Component.Invoke.CalledAddress, bc); 02878 print_facility_Q931_Bc_Hlc_Llc_Uu(2, &fac->u.CallRerouteing.Component.Invoke.Q931ie, bc); 02879 chan_misdn_log(1, bc->port, " --> LastReroutingNr:\n"); 02880 print_facility_PresentedNumberUnscreened(3, &fac->u.CallRerouteing.Component.Invoke.LastRerouting, bc); 02881 chan_misdn_log(1, bc->port, " --> SubscriptionOption:%d\n", 02882 fac->u.CallRerouteing.Component.Invoke.SubscriptionOption); 02883 if (fac->u.CallRerouteing.Component.Invoke.CallingPartySubaddress.Length) { 02884 chan_misdn_log(1, bc->port, " --> CallingParty:\n"); 02885 print_facility_Subaddress(3, &fac->u.CallRerouteing.Component.Invoke.CallingPartySubaddress, bc); 02886 } 02887 break; 02888 case FacComponent_Result: 02889 chan_misdn_log(1, bc->port, " --> Result\n"); 02890 break; 02891 default: 02892 break; 02893 } 02894 break; 02895 case Fac_InterrogateServedUserNumbers: 02896 chan_misdn_log(1, bc->port, " --> InterrogateServedUserNumbers: InvokeID:%d\n", 02897 fac->u.InterrogateServedUserNumbers.InvokeID); 02898 switch (fac->u.InterrogateServedUserNumbers.ComponentType) { 02899 case FacComponent_Invoke: 02900 chan_misdn_log(1, bc->port, " --> Invoke\n"); 02901 break; 02902 case FacComponent_Result: 02903 chan_misdn_log(1, bc->port, " --> Result:\n"); 02904 if (fac->u.InterrogateServedUserNumbers.Component.Result.NumRecords) { 02905 for (Index = 0; Index < fac->u.InterrogateServedUserNumbers.Component.Result.NumRecords; ++Index) { 02906 chan_misdn_log(1, bc->port, " --> ServedUserNr[%d]:\n", Index); 02907 print_facility_PartyNumber(3, &fac->u.InterrogateServedUserNumbers.Component.Result.List[Index], bc); 02908 } 02909 } 02910 break; 02911 default: 02912 break; 02913 } 02914 break; 02915 case Fac_DivertingLegInformation1: 02916 chan_misdn_log(1, bc->port, " --> DivertingLegInformation1: InvokeID:%d Reason:%d SubscriptionOption:%d\n", 02917 fac->u.DivertingLegInformation1.InvokeID, 02918 fac->u.DivertingLegInformation1.DiversionReason, 02919 fac->u.DivertingLegInformation1.SubscriptionOption); 02920 if (fac->u.DivertingLegInformation1.DivertedToPresent) { 02921 chan_misdn_log(1, bc->port, " --> DivertedToNr:\n"); 02922 print_facility_PresentedNumberUnscreened(2, &fac->u.DivertingLegInformation1.DivertedTo, bc); 02923 } 02924 break; 02925 case Fac_DivertingLegInformation2: 02926 chan_misdn_log(1, bc->port, " --> DivertingLegInformation2: InvokeID:%d Reason:%d Count:%d\n", 02927 fac->u.DivertingLegInformation2.InvokeID, 02928 fac->u.DivertingLegInformation2.DiversionReason, 02929 fac->u.DivertingLegInformation2.DiversionCounter); 02930 if (fac->u.DivertingLegInformation2.DivertingPresent) { 02931 chan_misdn_log(1, bc->port, " --> DivertingNr:\n"); 02932 print_facility_PresentedNumberUnscreened(2, &fac->u.DivertingLegInformation2.Diverting, bc); 02933 } 02934 if (fac->u.DivertingLegInformation2.OriginalCalledPresent) { 02935 chan_misdn_log(1, bc->port, " --> OriginalCalledNr:\n"); 02936 print_facility_PresentedNumberUnscreened(2, &fac->u.DivertingLegInformation2.OriginalCalled, bc); 02937 } 02938 break; 02939 case Fac_DivertingLegInformation3: 02940 chan_misdn_log(1, bc->port, " --> DivertingLegInformation3: InvokeID:%d PresentationAllowed:%d\n", 02941 fac->u.DivertingLegInformation3.InvokeID, 02942 fac->u.DivertingLegInformation3.PresentationAllowedIndicator); 02943 break; 02944 02945 #else /* !defined(AST_MISDN_ENHANCEMENTS) */ 02946 02947 case Fac_CD: 02948 chan_misdn_log(1, bc->port, " --> calldeflect to: %s, presentable: %s\n", fac->u.CDeflection.DeflectedToNumber, 02949 fac->u.CDeflection.PresentationAllowed ? "yes" : "no"); 02950 break; 02951 #endif /* !defined(AST_MISDN_ENHANCEMENTS) */ 02952 case Fac_AOCDCurrency: 02953 if (fac->u.AOCDcur.chargeNotAvailable) { 02954 chan_misdn_log(1, bc->port, " --> AOCD currency: charge not available\n"); 02955 } else if (fac->u.AOCDcur.freeOfCharge) { 02956 chan_misdn_log(1, bc->port, " --> AOCD currency: free of charge\n"); 02957 } else if (fac->u.AOCDchu.billingId >= 0) { 02958 chan_misdn_log(1, bc->port, " --> AOCD currency: currency:%s amount:%d multiplier:%d typeOfChargingInfo:%s billingId:%d\n", 02959 fac->u.AOCDcur.currency, fac->u.AOCDcur.currencyAmount, fac->u.AOCDcur.multiplier, 02960 (fac->u.AOCDcur.typeOfChargingInfo == 0) ? "subTotal" : "total", fac->u.AOCDcur.billingId); 02961 } else { 02962 chan_misdn_log(1, bc->port, " --> AOCD currency: currency:%s amount:%d multiplier:%d typeOfChargingInfo:%s\n", 02963 fac->u.AOCDcur.currency, fac->u.AOCDcur.currencyAmount, fac->u.AOCDcur.multiplier, 02964 (fac->u.AOCDcur.typeOfChargingInfo == 0) ? "subTotal" : "total"); 02965 } 02966 break; 02967 case Fac_AOCDChargingUnit: 02968 if (fac->u.AOCDchu.chargeNotAvailable) { 02969 chan_misdn_log(1, bc->port, " --> AOCD charging unit: charge not available\n"); 02970 } else if (fac->u.AOCDchu.freeOfCharge) { 02971 chan_misdn_log(1, bc->port, " --> AOCD charging unit: free of charge\n"); 02972 } else if (fac->u.AOCDchu.billingId >= 0) { 02973 chan_misdn_log(1, bc->port, " --> AOCD charging unit: recordedUnits:%d typeOfChargingInfo:%s billingId:%d\n", 02974 fac->u.AOCDchu.recordedUnits, (fac->u.AOCDchu.typeOfChargingInfo == 0) ? "subTotal" : "total", fac->u.AOCDchu.billingId); 02975 } else { 02976 chan_misdn_log(1, bc->port, " --> AOCD charging unit: recordedUnits:%d typeOfChargingInfo:%s\n", 02977 fac->u.AOCDchu.recordedUnits, (fac->u.AOCDchu.typeOfChargingInfo == 0) ? "subTotal" : "total"); 02978 } 02979 break; 02980 #if defined(AST_MISDN_ENHANCEMENTS) 02981 case Fac_ERROR: 02982 chan_misdn_log(1, bc->port, " --> ERROR: InvokeID:%d, Code:0x%02x\n", 02983 fac->u.ERROR.invokeId, fac->u.ERROR.errorValue); 02984 break; 02985 case Fac_RESULT: 02986 chan_misdn_log(1, bc->port, " --> RESULT: InvokeID:%d\n", 02987 fac->u.RESULT.InvokeID); 02988 break; 02989 case Fac_REJECT: 02990 if (fac->u.REJECT.InvokeIDPresent) { 02991 chan_misdn_log(1, bc->port, " --> REJECT: InvokeID:%d, Code:0x%02x\n", 02992 fac->u.REJECT.InvokeID, fac->u.REJECT.Code); 02993 } else { 02994 chan_misdn_log(1, bc->port, " --> REJECT: Code:0x%02x\n", 02995 fac->u.REJECT.Code); 02996 } 02997 break; 02998 case Fac_EctExecute: 02999 chan_misdn_log(1, bc->port, " --> EctExecute: InvokeID:%d\n", 03000 fac->u.EctExecute.InvokeID); 03001 break; 03002 case Fac_ExplicitEctExecute: 03003 chan_misdn_log(1, bc->port, " --> ExplicitEctExecute: InvokeID:%d LinkID:%d\n", 03004 fac->u.ExplicitEctExecute.InvokeID, 03005 fac->u.ExplicitEctExecute.LinkID); 03006 break; 03007 case Fac_RequestSubaddress: 03008 chan_misdn_log(1, bc->port, " --> RequestSubaddress: InvokeID:%d\n", 03009 fac->u.RequestSubaddress.InvokeID); 03010 break; 03011 case Fac_SubaddressTransfer: 03012 chan_misdn_log(1, bc->port, " --> SubaddressTransfer: InvokeID:%d\n", 03013 fac->u.SubaddressTransfer.InvokeID); 03014 print_facility_Subaddress(1, &fac->u.SubaddressTransfer.Subaddress, bc); 03015 break; 03016 case Fac_EctLinkIdRequest: 03017 chan_misdn_log(1, bc->port, " --> EctLinkIdRequest: InvokeID:%d\n", 03018 fac->u.EctLinkIdRequest.InvokeID); 03019 switch (fac->u.EctLinkIdRequest.ComponentType) { 03020 case FacComponent_Invoke: 03021 chan_misdn_log(1, bc->port, " --> Invoke\n"); 03022 break; 03023 case FacComponent_Result: 03024 chan_misdn_log(1, bc->port, " --> Result: LinkID:%d\n", 03025 fac->u.EctLinkIdRequest.Component.Result.LinkID); 03026 break; 03027 default: 03028 break; 03029 } 03030 break; 03031 case Fac_EctInform: 03032 chan_misdn_log(1, bc->port, " --> EctInform: InvokeID:%d Status:%d\n", 03033 fac->u.EctInform.InvokeID, 03034 fac->u.EctInform.Status); 03035 if (fac->u.EctInform.RedirectionPresent) { 03036 chan_misdn_log(1, bc->port, " --> Redirection Number\n"); 03037 print_facility_PresentedNumberUnscreened(2, &fac->u.EctInform.Redirection, bc); 03038 } 03039 break; 03040 case Fac_EctLoopTest: 03041 chan_misdn_log(1, bc->port, " --> EctLoopTest: InvokeID:%d\n", 03042 fac->u.EctLoopTest.InvokeID); 03043 switch (fac->u.EctLoopTest.ComponentType) { 03044 case FacComponent_Invoke: 03045 chan_misdn_log(1, bc->port, " --> Invoke: CallTransferID:%d\n", 03046 fac->u.EctLoopTest.Component.Invoke.CallTransferID); 03047 break; 03048 case FacComponent_Result: 03049 chan_misdn_log(1, bc->port, " --> Result: LoopResult:%d\n", 03050 fac->u.EctLoopTest.Component.Result.LoopResult); 03051 break; 03052 default: 03053 break; 03054 } 03055 break; 03056 case Fac_StatusRequest: 03057 chan_misdn_log(1, bc->port, " --> StatusRequest: InvokeID:%d\n", 03058 fac->u.StatusRequest.InvokeID); 03059 switch (fac->u.StatusRequest.ComponentType) { 03060 case FacComponent_Invoke: 03061 chan_misdn_log(1, bc->port, " --> Invoke: Compatibility:%d\n", 03062 fac->u.StatusRequest.Component.Invoke.CompatibilityMode); 03063 break; 03064 case FacComponent_Result: 03065 chan_misdn_log(1, bc->port, " --> Result: Status:%d\n", 03066 fac->u.StatusRequest.Component.Result.Status); 03067 break; 03068 default: 03069 break; 03070 } 03071 break; 03072 case Fac_CallInfoRetain: 03073 chan_misdn_log(1, bc->port, " --> CallInfoRetain: InvokeID:%d, LinkageID:%d\n", 03074 fac->u.CallInfoRetain.InvokeID, fac->u.CallInfoRetain.CallLinkageID); 03075 break; 03076 case Fac_CCBSDeactivate: 03077 chan_misdn_log(1, bc->port, " --> CCBSDeactivate: InvokeID:%d\n", 03078 fac->u.CCBSDeactivate.InvokeID); 03079 switch (fac->u.CCBSDeactivate.ComponentType) { 03080 case FacComponent_Invoke: 03081 chan_misdn_log(1, bc->port, " --> Invoke: CCBSReference:%d\n", 03082 fac->u.CCBSDeactivate.Component.Invoke.CCBSReference); 03083 break; 03084 case FacComponent_Result: 03085 chan_misdn_log(1, bc->port, " --> Result\n"); 03086 break; 03087 default: 03088 break; 03089 } 03090 break; 03091 case Fac_CCBSErase: 03092 chan_misdn_log(1, bc->port, " --> CCBSErase: InvokeID:%d, CCBSReference:%d RecallMode:%d, Reason:%d\n", 03093 fac->u.CCBSErase.InvokeID, fac->u.CCBSErase.CCBSReference, 03094 fac->u.CCBSErase.RecallMode, fac->u.CCBSErase.Reason); 03095 chan_misdn_log(1, bc->port, " --> AddressOfB\n"); 03096 print_facility_Address(2, &fac->u.CCBSErase.AddressOfB, bc); 03097 print_facility_Q931_Bc_Hlc_Llc(1, &fac->u.CCBSErase.Q931ie, bc); 03098 break; 03099 case Fac_CCBSRemoteUserFree: 03100 chan_misdn_log(1, bc->port, " --> CCBSRemoteUserFree: InvokeID:%d, CCBSReference:%d RecallMode:%d\n", 03101 fac->u.CCBSRemoteUserFree.InvokeID, fac->u.CCBSRemoteUserFree.CCBSReference, 03102 fac->u.CCBSRemoteUserFree.RecallMode); 03103 chan_misdn_log(1, bc->port, " --> AddressOfB\n"); 03104 print_facility_Address(2, &fac->u.CCBSRemoteUserFree.AddressOfB, bc); 03105 print_facility_Q931_Bc_Hlc_Llc(1, &fac->u.CCBSRemoteUserFree.Q931ie, bc); 03106 break; 03107 case Fac_CCBSCall: 03108 chan_misdn_log(1, bc->port, " --> CCBSCall: InvokeID:%d, CCBSReference:%d\n", 03109 fac->u.CCBSCall.InvokeID, fac->u.CCBSCall.CCBSReference); 03110 break; 03111 case Fac_CCBSStatusRequest: 03112 chan_misdn_log(1, bc->port, " --> CCBSStatusRequest: InvokeID:%d\n", 03113 fac->u.CCBSStatusRequest.InvokeID); 03114 switch (fac->u.CCBSStatusRequest.ComponentType) { 03115 case FacComponent_Invoke: 03116 chan_misdn_log(1, bc->port, " --> Invoke: CCBSReference:%d RecallMode:%d\n", 03117 fac->u.CCBSStatusRequest.Component.Invoke.CCBSReference, 03118 fac->u.CCBSStatusRequest.Component.Invoke.RecallMode); 03119 print_facility_Q931_Bc_Hlc_Llc(2, &fac->u.CCBSStatusRequest.Component.Invoke.Q931ie, bc); 03120 break; 03121 case FacComponent_Result: 03122 chan_misdn_log(1, bc->port, " --> Result: Free:%d\n", 03123 fac->u.CCBSStatusRequest.Component.Result.Free); 03124 break; 03125 default: 03126 break; 03127 } 03128 break; 03129 case Fac_CCBSBFree: 03130 chan_misdn_log(1, bc->port, " --> CCBSBFree: InvokeID:%d, CCBSReference:%d RecallMode:%d\n", 03131 fac->u.CCBSBFree.InvokeID, fac->u.CCBSBFree.CCBSReference, 03132 fac->u.CCBSBFree.RecallMode); 03133 chan_misdn_log(1, bc->port, " --> AddressOfB\n"); 03134 print_facility_Address(2, &fac->u.CCBSBFree.AddressOfB, bc); 03135 print_facility_Q931_Bc_Hlc_Llc(1, &fac->u.CCBSBFree.Q931ie, bc); 03136 break; 03137 case Fac_EraseCallLinkageID: 03138 chan_misdn_log(1, bc->port, " --> EraseCallLinkageID: InvokeID:%d, LinkageID:%d\n", 03139 fac->u.EraseCallLinkageID.InvokeID, fac->u.EraseCallLinkageID.CallLinkageID); 03140 break; 03141 case Fac_CCBSStopAlerting: 03142 chan_misdn_log(1, bc->port, " --> CCBSStopAlerting: InvokeID:%d, CCBSReference:%d\n", 03143 fac->u.CCBSStopAlerting.InvokeID, fac->u.CCBSStopAlerting.CCBSReference); 03144 break; 03145 case Fac_CCBSRequest: 03146 chan_misdn_log(1, bc->port, " --> CCBSRequest: InvokeID:%d\n", 03147 fac->u.CCBSRequest.InvokeID); 03148 switch (fac->u.CCBSRequest.ComponentType) { 03149 case FacComponent_Invoke: 03150 chan_misdn_log(1, bc->port, " --> Invoke: LinkageID:%d\n", 03151 fac->u.CCBSRequest.Component.Invoke.CallLinkageID); 03152 break; 03153 case FacComponent_Result: 03154 chan_misdn_log(1, bc->port, " --> Result: CCBSReference:%d RecallMode:%d\n", 03155 fac->u.CCBSRequest.Component.Result.CCBSReference, 03156 fac->u.CCBSRequest.Component.Result.RecallMode); 03157 break; 03158 default: 03159 break; 03160 } 03161 break; 03162 case Fac_CCBSInterrogate: 03163 chan_misdn_log(1, bc->port, " --> CCBSInterrogate: InvokeID:%d\n", 03164 fac->u.CCBSInterrogate.InvokeID); 03165 switch (fac->u.CCBSInterrogate.ComponentType) { 03166 case FacComponent_Invoke: 03167 chan_misdn_log(1, bc->port, " --> Invoke\n"); 03168 if (fac->u.CCBSInterrogate.Component.Invoke.CCBSReferencePresent) { 03169 chan_misdn_log(1, bc->port, " --> CCBSReference:%d\n", 03170 fac->u.CCBSInterrogate.Component.Invoke.CCBSReference); 03171 } 03172 if (fac->u.CCBSInterrogate.Component.Invoke.AParty.LengthOfNumber) { 03173 chan_misdn_log(1, bc->port, " --> AParty\n"); 03174 print_facility_PartyNumber(3, &fac->u.CCBSInterrogate.Component.Invoke.AParty, bc); 03175 } 03176 break; 03177 case FacComponent_Result: 03178 chan_misdn_log(1, bc->port, " --> Result: RecallMode:%d\n", 03179 fac->u.CCBSInterrogate.Component.Result.RecallMode); 03180 if (fac->u.CCBSInterrogate.Component.Result.NumRecords) { 03181 for (Index = 0; Index < fac->u.CCBSInterrogate.Component.Result.NumRecords; ++Index) { 03182 chan_misdn_log(1, bc->port, " --> CallDetails[%d]:\n", Index); 03183 print_facility_CallInformation(3, &fac->u.CCBSInterrogate.Component.Result.CallDetails[Index], bc); 03184 } 03185 } 03186 break; 03187 default: 03188 break; 03189 } 03190 break; 03191 case Fac_CCNRRequest: 03192 chan_misdn_log(1, bc->port, " --> CCNRRequest: InvokeID:%d\n", 03193 fac->u.CCNRRequest.InvokeID); 03194 switch (fac->u.CCNRRequest.ComponentType) { 03195 case FacComponent_Invoke: 03196 chan_misdn_log(1, bc->port, " --> Invoke: LinkageID:%d\n", 03197 fac->u.CCNRRequest.Component.Invoke.CallLinkageID); 03198 break; 03199 case FacComponent_Result: 03200 chan_misdn_log(1, bc->port, " --> Result: CCBSReference:%d RecallMode:%d\n", 03201 fac->u.CCNRRequest.Component.Result.CCBSReference, 03202 fac->u.CCNRRequest.Component.Result.RecallMode); 03203 break; 03204 default: 03205 break; 03206 } 03207 break; 03208 case Fac_CCNRInterrogate: 03209 chan_misdn_log(1, bc->port, " --> CCNRInterrogate: InvokeID:%d\n", 03210 fac->u.CCNRInterrogate.InvokeID); 03211 switch (fac->u.CCNRInterrogate.ComponentType) { 03212 case FacComponent_Invoke: 03213 chan_misdn_log(1, bc->port, " --> Invoke\n"); 03214 if (fac->u.CCNRInterrogate.Component.Invoke.CCBSReferencePresent) { 03215 chan_misdn_log(1, bc->port, " --> CCBSReference:%d\n", 03216 fac->u.CCNRInterrogate.Component.Invoke.CCBSReference); 03217 } 03218 if (fac->u.CCNRInterrogate.Component.Invoke.AParty.LengthOfNumber) { 03219 chan_misdn_log(1, bc->port, " --> AParty\n"); 03220 print_facility_PartyNumber(3, &fac->u.CCNRInterrogate.Component.Invoke.AParty, bc); 03221 } 03222 break; 03223 case FacComponent_Result: 03224 chan_misdn_log(1, bc->port, " --> Result: RecallMode:%d\n", 03225 fac->u.CCNRInterrogate.Component.Result.RecallMode); 03226 if (fac->u.CCNRInterrogate.Component.Result.NumRecords) { 03227 for (Index = 0; Index < fac->u.CCNRInterrogate.Component.Result.NumRecords; ++Index) { 03228 chan_misdn_log(1, bc->port, " --> CallDetails[%d]:\n", Index); 03229 print_facility_CallInformation(3, &fac->u.CCNRInterrogate.Component.Result.CallDetails[Index], bc); 03230 } 03231 } 03232 break; 03233 default: 03234 break; 03235 } 03236 break; 03237 case Fac_CCBS_T_Call: 03238 chan_misdn_log(1, bc->port, " --> CCBS_T_Call: InvokeID:%d\n", 03239 fac->u.CCBS_T_Call.InvokeID); 03240 break; 03241 case Fac_CCBS_T_Suspend: 03242 chan_misdn_log(1, bc->port, " --> CCBS_T_Suspend: InvokeID:%d\n", 03243 fac->u.CCBS_T_Suspend.InvokeID); 03244 break; 03245 case Fac_CCBS_T_Resume: 03246 chan_misdn_log(1, bc->port, " --> CCBS_T_Resume: InvokeID:%d\n", 03247 fac->u.CCBS_T_Resume.InvokeID); 03248 break; 03249 case Fac_CCBS_T_RemoteUserFree: 03250 chan_misdn_log(1, bc->port, " --> CCBS_T_RemoteUserFree: InvokeID:%d\n", 03251 fac->u.CCBS_T_RemoteUserFree.InvokeID); 03252 break; 03253 case Fac_CCBS_T_Available: 03254 chan_misdn_log(1, bc->port, " --> CCBS_T_Available: InvokeID:%d\n", 03255 fac->u.CCBS_T_Available.InvokeID); 03256 break; 03257 case Fac_CCBS_T_Request: 03258 chan_misdn_log(1, bc->port, " --> CCBS_T_Request: InvokeID:%d\n", 03259 fac->u.CCBS_T_Request.InvokeID); 03260 switch (fac->u.CCBS_T_Request.ComponentType) { 03261 case FacComponent_Invoke: 03262 chan_misdn_log(1, bc->port, " --> Invoke\n"); 03263 chan_misdn_log(1, bc->port, " --> DestinationAddress:\n"); 03264 print_facility_Address(3, &fac->u.CCBS_T_Request.Component.Invoke.Destination, bc); 03265 print_facility_Q931_Bc_Hlc_Llc(2, &fac->u.CCBS_T_Request.Component.Invoke.Q931ie, bc); 03266 if (fac->u.CCBS_T_Request.Component.Invoke.RetentionSupported) { 03267 chan_misdn_log(1, bc->port, " --> RetentionSupported:1\n"); 03268 } 03269 if (fac->u.CCBS_T_Request.Component.Invoke.PresentationAllowedIndicatorPresent) { 03270 chan_misdn_log(1, bc->port, " --> PresentationAllowed:%d\n", 03271 fac->u.CCBS_T_Request.Component.Invoke.PresentationAllowedIndicator); 03272 } 03273 if (fac->u.CCBS_T_Request.Component.Invoke.Originating.Party.LengthOfNumber) { 03274 chan_misdn_log(1, bc->port, " --> OriginatingAddress:\n"); 03275 print_facility_Address(3, &fac->u.CCBS_T_Request.Component.Invoke.Originating, bc); 03276 } 03277 break; 03278 case FacComponent_Result: 03279 chan_misdn_log(1, bc->port, " --> Result: RetentionSupported:%d\n", 03280 fac->u.CCBS_T_Request.Component.Result.RetentionSupported); 03281 break; 03282 default: 03283 break; 03284 } 03285 break; 03286 case Fac_CCNR_T_Request: 03287 chan_misdn_log(1, bc->port, " --> CCNR_T_Request: InvokeID:%d\n", 03288 fac->u.CCNR_T_Request.InvokeID); 03289 switch (fac->u.CCNR_T_Request.ComponentType) { 03290 case FacComponent_Invoke: 03291 chan_misdn_log(1, bc->port, " --> Invoke\n"); 03292 chan_misdn_log(1, bc->port, " --> DestinationAddress:\n"); 03293 print_facility_Address(3, &fac->u.CCNR_T_Request.Component.Invoke.Destination, bc); 03294 print_facility_Q931_Bc_Hlc_Llc(2, &fac->u.CCNR_T_Request.Component.Invoke.Q931ie, bc); 03295 if (fac->u.CCNR_T_Request.Component.Invoke.RetentionSupported) { 03296 chan_misdn_log(1, bc->port, " --> RetentionSupported:1\n"); 03297 } 03298 if (fac->u.CCNR_T_Request.Component.Invoke.PresentationAllowedIndicatorPresent) { 03299 chan_misdn_log(1, bc->port, " --> PresentationAllowed:%d\n", 03300 fac->u.CCNR_T_Request.Component.Invoke.PresentationAllowedIndicator); 03301 } 03302 if (fac->u.CCNR_T_Request.Component.Invoke.Originating.Party.LengthOfNumber) { 03303 chan_misdn_log(1, bc->port, " --> OriginatingAddress:\n"); 03304 print_facility_Address(3, &fac->u.CCNR_T_Request.Component.Invoke.Originating, bc); 03305 } 03306 break; 03307 case FacComponent_Result: 03308 chan_misdn_log(1, bc->port, " --> Result: RetentionSupported:%d\n", 03309 fac->u.CCNR_T_Request.Component.Result.RetentionSupported); 03310 break; 03311 default: 03312 break; 03313 } 03314 break; 03315 #endif /* defined(AST_MISDN_ENHANCEMENTS) */ 03316 case Fac_None: 03317 /* No facility so print nothing */ 03318 break; 03319 default: 03320 chan_misdn_log(1, bc->port, " --> unknown facility\n"); 03321 break; 03322 } 03323 }
static struct ast_frame * process_ast_dsp | ( | struct chan_list * | tmp, | |
struct ast_frame * | frame | |||
) | [static] |
Definition at line 7230 of file chan_misdn.c.
References chan_list::ast, ast_async_goto(), ast_debug, chan_list::ast_dsp, ast_dsp_process(), ast_exists_extension(), AST_FRAME_DTMF, ast_log(), ast_strlen_zero(), ast_verb, chan_list::bc, BUFFERSIZE, chan_misdn_log(), ast_channel::context, context, chan_list::dsp, misdn_bchannel::ec_enable, ast_channel::exten, f, chan_list::faxdetect, chan_list::faxhandled, isdn_lib_stop_dtmf(), isdn_lib_update_ec(), isdn_lib_update_rxgain(), isdn_lib_update_txgain(), LOG_NOTICE, LOG_WARNING, ast_channel::macrocontext, MISDN_CFG_FAXDETECT_CONTEXT, misdn_cfg_get(), ast_channel::name, pbx_builtin_setvar_helper(), misdn_bchannel::port, misdn_bchannel::rxgain, S_COR, and misdn_bchannel::txgain.
Referenced by misdn_read().
07231 { 07232 struct ast_frame *f; 07233 07234 if (tmp->dsp) { 07235 f = ast_dsp_process(tmp->ast, tmp->dsp, frame); 07236 } else { 07237 chan_misdn_log(0, tmp->bc->port, "No DSP-Path found\n"); 07238 return NULL; 07239 } 07240 07241 if (!f || (f->frametype != AST_FRAME_DTMF)) { 07242 return f; 07243 } 07244 07245 ast_debug(1, "Detected inband DTMF digit: %c\n", f->subclass.integer); 07246 07247 if (tmp->faxdetect && (f->subclass.integer == 'f')) { 07248 /* Fax tone -- Handle and return NULL */ 07249 if (!tmp->faxhandled) { 07250 struct ast_channel *ast = tmp->ast; 07251 tmp->faxhandled++; 07252 chan_misdn_log(0, tmp->bc->port, "Fax detected, preparing %s for fax transfer.\n", ast->name); 07253 tmp->bc->rxgain = 0; 07254 isdn_lib_update_rxgain(tmp->bc); 07255 tmp->bc->txgain = 0; 07256 isdn_lib_update_txgain(tmp->bc); 07257 #ifdef MISDN_1_2 07258 *tmp->bc->pipeline = 0; 07259 #else 07260 tmp->bc->ec_enable = 0; 07261 #endif 07262 isdn_lib_update_ec(tmp->bc); 07263 isdn_lib_stop_dtmf(tmp->bc); 07264 switch (tmp->faxdetect) { 07265 case 1: 07266 if (strcmp(ast->exten, "fax")) { 07267 char *context; 07268 char context_tmp[BUFFERSIZE]; 07269 misdn_cfg_get(tmp->bc->port, MISDN_CFG_FAXDETECT_CONTEXT, &context_tmp, sizeof(context_tmp)); 07270 context = ast_strlen_zero(context_tmp) ? (ast_strlen_zero(ast->macrocontext) ? ast->context : ast->macrocontext) : context_tmp; 07271 if (ast_exists_extension(ast, context, "fax", 1, 07272 S_COR(ast->caller.id.number.valid, ast->caller.id.number.str, NULL))) { 07273 ast_verb(3, "Redirecting %s to fax extension (context:%s)\n", ast->name, context); 07274 /* Save the DID/DNIS when we transfer the fax call to a "fax" extension */ 07275 pbx_builtin_setvar_helper(ast,"FAXEXTEN",ast->exten); 07276 if (ast_async_goto(ast, context, "fax", 1)) { 07277 ast_log(LOG_WARNING, "Failed to async goto '%s' into fax of '%s'\n", ast->name, context); 07278 } 07279 } else { 07280 ast_log(LOG_NOTICE, "Fax detected but no fax extension, context:%s exten:%s\n", context, ast->exten); 07281 } 07282 } else { 07283 ast_debug(1, "Already in a fax extension, not redirecting\n"); 07284 } 07285 break; 07286 case 2: 07287 ast_verb(3, "Not redirecting %s to fax extension, nojump is set.\n", ast->name); 07288 break; 07289 default: 07290 break; 07291 } 07292 } else { 07293 ast_debug(1, "Fax already handled\n"); 07294 } 07295 } 07296 07297 if (tmp->ast_dsp && (f->subclass.integer != 'f')) { 07298 chan_misdn_log(2, tmp->bc->port, " --> * SEND: DTMF (AST_DSP) :%c\n", f->subclass.integer); 07299 } 07300 07301 return f; 07302 }
static int read_config | ( | struct chan_list * | ch | ) | [static] |
Definition at line 5890 of file chan_misdn.c.
References chan_list::allowed_bearers, misdn_bchannel::AOCDtype, chan_list::ast, ast_callerid_parse(), ast_copy_string(), chan_list::ast_dsp, ast_dsp_new(), ast_dsp_set_features(), ast_log(), ast_mutex_init, ast_print_group(), ast_string_field_set, ast_strlen_zero(), chan_list::bc, buf2, BUFFERSIZE, misdn_bchannel::caller, ast_channel::callgroup, misdn_bchannel::capability, chan_misdn_log(), cid_name, cid_num, config_jitterbuffer(), ast_channel::context, chan_list::context, debug_numtype(), misdn_bchannel::dialed, misdn_bchannel::display_connected, misdn_bchannel::display_setup, chan_list::dsp, DSP_FEATURE_DIGIT_DETECT, DSP_FEATURE_FAX_DETECT, misdn_bchannel::early_bconnect, ast_channel::exten, chan_list::far_alerting, chan_list::faxdetect, chan_list::faxdetect_timeout, misdn_bchannel::hdlc, chan_list::ignore_dtmf, misdn_bchannel::incoming_cid_tag, chan_list::incoming_early_audio, INFO_CAPABILITY_DIGITAL_RESTRICTED, INFO_CAPABILITY_DIGITAL_UNRESTRICTED, chan_list::jb_len, chan_list::jb_upper_threshold, misdn_bchannel::keypad, language, LOG_WARNING, misdn_add_number_prefix(), MISDN_CFG_ALLOWED_BEARERS, MISDN_CFG_ASTDTMF, MISDN_CFG_CALLERID, MISDN_CFG_CALLGROUP, MISDN_CFG_CONTEXT, MISDN_CFG_DIALPLAN, MISDN_CFG_DISPLAY_CONNECTED, MISDN_CFG_DISPLAY_SETUP, MISDN_CFG_EARLY_BCONNECT, MISDN_CFG_FAR_ALERTING, MISDN_CFG_FAXDETECT, MISDN_CFG_FAXDETECT_TIMEOUT, misdn_cfg_get(), MISDN_CFG_HDLC, MISDN_CFG_INCOMING_CALLERID_TAG, MISDN_CFG_INCOMING_EARLY_AUDIO, MISDN_CFG_JITTERBUFFER, MISDN_CFG_JITTERBUFFER_UPPER_THRESHOLD, MISDN_CFG_LANGUAGE, MISDN_CFG_MUSICCLASS, MISDN_CFG_NEED_MORE_INFOS, MISDN_CFG_NOAUTORESPOND_ON_SETUP, MISDN_CFG_NTTIMEOUT, MISDN_CFG_OUTGOING_COLP, MISDN_CFG_OVERLAP_DIAL, MISDN_CFG_PICKUPGROUP, MISDN_CFG_RXGAIN, MISDN_CFG_SENDDTMF, MISDN_CFG_TE_CHOOSE_CHANNEL, MISDN_CFG_TXGAIN, chan_list::mohinterpret, misdn_party_id::name, misdn_bchannel::need_more_infos, chan_list::noautorespond_on_setup, chan_list::nttimeout, misdn_party_dialing::number, misdn_party_id::number, misdn_party_dialing::number_plan, misdn_party_id::number_type, misdn_party_dialing::number_type, NUMPLAN_ISDN, ORG_AST, chan_list::originator, misdn_bchannel::outgoing_colp, chan_list::overlap_dial, chan_list::overlap_dial_task, chan_list::overlap_tv_lock, ast_channel::pickupgroup, misdn_bchannel::port, misdn_bchannel::rxgain, misdn_bchannel::send_dtmf, misdn_bchannel::te_choose_channel, misdn_bchannel::txgain, and update_ec_config().
Referenced by cb_events(), and misdn_request().
05891 { 05892 struct ast_channel *ast; 05893 struct misdn_bchannel *bc; 05894 int port; 05895 int hdlc = 0; 05896 char lang[BUFFERSIZE + 1]; 05897 char faxdetect[BUFFERSIZE + 1]; 05898 char buf[256]; 05899 char buf2[256]; 05900 ast_group_t pg; 05901 ast_group_t cg; 05902 05903 if (!ch) { 05904 ast_log(LOG_WARNING, "Cannot configure without chanlist\n"); 05905 return -1; 05906 } 05907 05908 ast = ch->ast; 05909 bc = ch->bc; 05910 if (! ast || ! bc) { 05911 ast_log(LOG_WARNING, "Cannot configure without ast || bc\n"); 05912 return -1; 05913 } 05914 05915 port = bc->port; 05916 chan_misdn_log(1, port, "read_config: Getting Config\n"); 05917 05918 misdn_cfg_get(port, MISDN_CFG_LANGUAGE, lang, sizeof(lang)); 05919 ast_string_field_set(ast, language, lang); 05920 05921 misdn_cfg_get(port, MISDN_CFG_MUSICCLASS, ch->mohinterpret, sizeof(ch->mohinterpret)); 05922 05923 misdn_cfg_get(port, MISDN_CFG_TXGAIN, &bc->txgain, sizeof(bc->txgain)); 05924 misdn_cfg_get(port, MISDN_CFG_RXGAIN, &bc->rxgain, sizeof(bc->rxgain)); 05925 05926 misdn_cfg_get(port, MISDN_CFG_INCOMING_EARLY_AUDIO, &ch->incoming_early_audio, sizeof(ch->incoming_early_audio)); 05927 05928 misdn_cfg_get(port, MISDN_CFG_SENDDTMF, &bc->send_dtmf, sizeof(bc->send_dtmf)); 05929 05930 misdn_cfg_get(port, MISDN_CFG_ASTDTMF, &ch->ast_dsp, sizeof(int)); 05931 if (ch->ast_dsp) { 05932 ch->ignore_dtmf = 1; 05933 } 05934 05935 misdn_cfg_get(port, MISDN_CFG_NEED_MORE_INFOS, &bc->need_more_infos, sizeof(bc->need_more_infos)); 05936 misdn_cfg_get(port, MISDN_CFG_NTTIMEOUT, &ch->nttimeout, sizeof(ch->nttimeout)); 05937 05938 misdn_cfg_get(port, MISDN_CFG_NOAUTORESPOND_ON_SETUP, &ch->noautorespond_on_setup, sizeof(ch->noautorespond_on_setup)); 05939 05940 misdn_cfg_get(port, MISDN_CFG_FAR_ALERTING, &ch->far_alerting, sizeof(ch->far_alerting)); 05941 05942 misdn_cfg_get(port, MISDN_CFG_ALLOWED_BEARERS, &ch->allowed_bearers, sizeof(ch->allowed_bearers)); 05943 05944 misdn_cfg_get(port, MISDN_CFG_FAXDETECT, faxdetect, sizeof(faxdetect)); 05945 05946 misdn_cfg_get(port, MISDN_CFG_HDLC, &hdlc, sizeof(hdlc)); 05947 if (hdlc) { 05948 switch (bc->capability) { 05949 case INFO_CAPABILITY_DIGITAL_UNRESTRICTED: 05950 case INFO_CAPABILITY_DIGITAL_RESTRICTED: 05951 chan_misdn_log(1, bc->port, " --> CONF HDLC\n"); 05952 bc->hdlc = 1; 05953 break; 05954 } 05955 05956 } 05957 /*Initialize new Jitterbuffer*/ 05958 misdn_cfg_get(port, MISDN_CFG_JITTERBUFFER, &ch->jb_len, sizeof(ch->jb_len)); 05959 misdn_cfg_get(port, MISDN_CFG_JITTERBUFFER_UPPER_THRESHOLD, &ch->jb_upper_threshold, sizeof(ch->jb_upper_threshold)); 05960 05961 config_jitterbuffer(ch); 05962 05963 misdn_cfg_get(bc->port, MISDN_CFG_CONTEXT, ch->context, sizeof(ch->context)); 05964 05965 ast_copy_string(ast->context, ch->context, sizeof(ast->context)); 05966 05967 #ifdef MISDN_1_2 05968 update_pipeline_config(bc); 05969 #else 05970 update_ec_config(bc); 05971 #endif 05972 05973 misdn_cfg_get(bc->port, MISDN_CFG_EARLY_BCONNECT, &bc->early_bconnect, sizeof(bc->early_bconnect)); 05974 05975 misdn_cfg_get(port, MISDN_CFG_DISPLAY_CONNECTED, &bc->display_connected, sizeof(bc->display_connected)); 05976 misdn_cfg_get(port, MISDN_CFG_DISPLAY_SETUP, &bc->display_setup, sizeof(bc->display_setup)); 05977 misdn_cfg_get(port, MISDN_CFG_OUTGOING_COLP, &bc->outgoing_colp, sizeof(bc->outgoing_colp)); 05978 05979 misdn_cfg_get(port, MISDN_CFG_PICKUPGROUP, &pg, sizeof(pg)); 05980 misdn_cfg_get(port, MISDN_CFG_CALLGROUP, &cg, sizeof(cg)); 05981 chan_misdn_log(5, port, " --> * CallGrp:%s PickupGrp:%s\n", ast_print_group(buf, sizeof(buf), cg), ast_print_group(buf2, sizeof(buf2), pg)); 05982 ast->pickupgroup = pg; 05983 ast->callgroup = cg; 05984 05985 if (ch->originator == ORG_AST) { 05986 char callerid[BUFFERSIZE + 1]; 05987 05988 /* ORIGINATOR Asterisk (outgoing call) */ 05989 05990 misdn_cfg_get(port, MISDN_CFG_TE_CHOOSE_CHANNEL, &(bc->te_choose_channel), sizeof(bc->te_choose_channel)); 05991 05992 if (strstr(faxdetect, "outgoing") || strstr(faxdetect, "both")) { 05993 ch->faxdetect = strstr(faxdetect, "nojump") ? 2 : 1; 05994 } 05995 05996 misdn_cfg_get(port, MISDN_CFG_CALLERID, callerid, sizeof(callerid)); 05997 if (!ast_strlen_zero(callerid)) { 05998 char *cid_name = NULL; 05999 char *cid_num = NULL; 06000 06001 ast_callerid_parse(callerid, &cid_name, &cid_num); 06002 if (cid_name) { 06003 ast_copy_string(bc->caller.name, cid_name, sizeof(bc->caller.name)); 06004 } else { 06005 bc->caller.name[0] = '\0'; 06006 } 06007 if (cid_num) { 06008 ast_copy_string(bc->caller.number, cid_num, sizeof(bc->caller.number)); 06009 } else { 06010 bc->caller.number[0] = '\0'; 06011 } 06012 chan_misdn_log(1, port, " --> * Setting caller to \"%s\" <%s>\n", bc->caller.name, bc->caller.number); 06013 } 06014 06015 misdn_cfg_get(port, MISDN_CFG_DIALPLAN, &bc->dialed.number_type, sizeof(bc->dialed.number_type)); 06016 bc->dialed.number_plan = NUMPLAN_ISDN; 06017 debug_numtype(port, bc->dialed.number_type, "TON"); 06018 06019 ch->overlap_dial = 0; 06020 } else { 06021 /* ORIGINATOR MISDN (incoming call) */ 06022 06023 if (strstr(faxdetect, "incoming") || strstr(faxdetect, "both")) { 06024 ch->faxdetect = (strstr(faxdetect, "nojump")) ? 2 : 1; 06025 } 06026 06027 /* Add configured prefix to caller.number */ 06028 misdn_add_number_prefix(bc->port, bc->caller.number_type, bc->caller.number, sizeof(bc->caller.number)); 06029 06030 if (ast_strlen_zero(bc->dialed.number) && !ast_strlen_zero(bc->keypad)) { 06031 ast_copy_string(bc->dialed.number, bc->keypad, sizeof(bc->dialed.number)); 06032 } 06033 06034 /* Add configured prefix to dialed.number */ 06035 misdn_add_number_prefix(bc->port, bc->dialed.number_type, bc->dialed.number, sizeof(bc->dialed.number)); 06036 06037 ast_copy_string(ast->exten, bc->dialed.number, sizeof(ast->exten)); 06038 06039 misdn_cfg_get(bc->port, MISDN_CFG_OVERLAP_DIAL, &ch->overlap_dial, sizeof(ch->overlap_dial)); 06040 ast_mutex_init(&ch->overlap_tv_lock); 06041 } /* ORIG MISDN END */ 06042 06043 misdn_cfg_get(port, MISDN_CFG_INCOMING_CALLERID_TAG, bc->incoming_cid_tag, sizeof(bc->incoming_cid_tag)); 06044 if (!ast_strlen_zero(bc->incoming_cid_tag)) { 06045 chan_misdn_log(1, port, " --> * Setting incoming caller id tag to \"%s\"\n", bc->incoming_cid_tag); 06046 } 06047 ch->overlap_dial_task = -1; 06048 06049 if (ch->faxdetect || ch->ast_dsp) { 06050 misdn_cfg_get(port, MISDN_CFG_FAXDETECT_TIMEOUT, &ch->faxdetect_timeout, sizeof(ch->faxdetect_timeout)); 06051 if (!ch->dsp) { 06052 ch->dsp = ast_dsp_new(); 06053 } 06054 if (ch->dsp) { 06055 ast_dsp_set_features(ch->dsp, DSP_FEATURE_DIGIT_DETECT | (ch->faxdetect ? DSP_FEATURE_FAX_DETECT : 0)); 06056 } 06057 } 06058 06059 /* AOCD initialization */ 06060 bc->AOCDtype = Fac_None; 06061 06062 return 0; 06063 }
static void release_chan | ( | struct chan_list * | ch, | |
struct misdn_bchannel * | bc | |||
) | [static] |
Definition at line 8400 of file chan_misdn.c.
References ast_channel::_state, chan_list::ast, ast_channel_trylock, ast_channel_unlock, ast_mutex_lock, ast_mutex_unlock, ast_setstate(), AST_STATE_DOWN, AST_STATE_RESERVED, chan_list::bc, ast_channel::caller, chan_list_unref, chan_misdn_log(), cl_dequeue_chan(), ast_channel::context, DEADLOCK_AVOIDANCE, ast_channel::exten, ast_party_caller::id, misdn_bchannel::l3_id, MISDN_ASTERISK_TECH_PVT, MISDN_CLEANING, misdn_in_calls, misdn_out_calls, ast_party_id::name, ast_party_id::number, ORG_AST, chan_list::originator, misdn_bchannel::pid, misdn_bchannel::port, release_lock, S_COR, chan_list::state, ast_party_number::str, ast_party_name::str, ast_party_number::valid, and ast_party_name::valid.
Referenced by cb_events(), and misdn_hangup().
08401 { 08402 struct ast_channel *ast; 08403 08404 chan_misdn_log(5, bc->port, "release_chan: bc with pid:%d l3id: %x\n", bc->pid, bc->l3_id); 08405 08406 ast_mutex_lock(&release_lock); 08407 for (;;) { 08408 ast = ch->ast; 08409 if (!ast || !ast_channel_trylock(ast)) { 08410 break; 08411 } 08412 DEADLOCK_AVOIDANCE(&release_lock); 08413 } 08414 if (!cl_dequeue_chan(ch)) { 08415 /* Someone already released it. */ 08416 if (ast) { 08417 ast_channel_unlock(ast); 08418 } 08419 ast_mutex_unlock(&release_lock); 08420 return; 08421 } 08422 ch->state = MISDN_CLEANING; 08423 ch->ast = NULL; 08424 if (ast) { 08425 struct chan_list *ast_ch; 08426 08427 ast_ch = MISDN_ASTERISK_TECH_PVT(ast); 08428 MISDN_ASTERISK_TECH_PVT(ast) = NULL; 08429 chan_misdn_log(1, bc->port, 08430 "* RELEASING CHANNEL pid:%d context:%s dialed:%s caller:\"%s\" <%s>\n", 08431 bc->pid, 08432 ast->context, 08433 ast->exten, 08434 S_COR(ast->caller.id.name.valid, ast->caller.id.name.str, ""), 08435 S_COR(ast->caller.id.number.valid, ast->caller.id.number.str, "")); 08436 08437 if (ast->_state != AST_STATE_RESERVED) { 08438 chan_misdn_log(3, bc->port, " --> Setting AST State to down\n"); 08439 ast_setstate(ast, AST_STATE_DOWN); 08440 } 08441 ast_channel_unlock(ast); 08442 if (ast_ch) { 08443 chan_list_unref(ast_ch, "Release ast_channel reference."); 08444 } 08445 } 08446 08447 if (ch->originator == ORG_AST) { 08448 --misdn_out_calls[bc->port]; 08449 } else { 08450 --misdn_in_calls[bc->port]; 08451 } 08452 08453 ast_mutex_unlock(&release_lock); 08454 }
static void release_chan_early | ( | struct chan_list * | ch | ) | [static] |
Definition at line 8466 of file chan_misdn.c.
References ast_channel::_state, chan_list::ast, ast_channel_trylock, ast_channel_unlock, ast_mutex_lock, ast_mutex_unlock, ast_setstate(), AST_STATE_DOWN, AST_STATE_RESERVED, chan_list_unref, cl_dequeue_chan(), DEADLOCK_AVOIDANCE, chan_list::hold, MISDN_ASTERISK_TECH_PVT, MISDN_CLEANING, MISDN_HOLD_IDLE, misdn_in_calls, misdn_out_calls, ORG_AST, chan_list::originator, hold_info::port, release_lock, hold_info::state, and chan_list::state.
Referenced by misdn_hangup().
08467 { 08468 struct ast_channel *ast; 08469 08470 ast_mutex_lock(&release_lock); 08471 for (;;) { 08472 ast = ch->ast; 08473 if (!ast || !ast_channel_trylock(ast)) { 08474 break; 08475 } 08476 DEADLOCK_AVOIDANCE(&release_lock); 08477 } 08478 if (!cl_dequeue_chan(ch)) { 08479 /* Someone already released it. */ 08480 if (ast) { 08481 ast_channel_unlock(ast); 08482 } 08483 ast_mutex_unlock(&release_lock); 08484 return; 08485 } 08486 ch->state = MISDN_CLEANING; 08487 ch->ast = NULL; 08488 if (ast) { 08489 struct chan_list *ast_ch; 08490 08491 ast_ch = MISDN_ASTERISK_TECH_PVT(ast); 08492 MISDN_ASTERISK_TECH_PVT(ast) = NULL; 08493 08494 if (ast->_state != AST_STATE_RESERVED) { 08495 ast_setstate(ast, AST_STATE_DOWN); 08496 } 08497 ast_channel_unlock(ast); 08498 if (ast_ch) { 08499 chan_list_unref(ast_ch, "Release ast_channel reference."); 08500 } 08501 } 08502 08503 if (ch->hold.state != MISDN_HOLD_IDLE) { 08504 if (ch->originator == ORG_AST) { 08505 --misdn_out_calls[ch->hold.port]; 08506 } else { 08507 --misdn_in_calls[ch->hold.port]; 08508 } 08509 } 08510 08511 ast_mutex_unlock(&release_lock); 08512 }
static int reload | ( | void | ) | [static] |
Definition at line 11369 of file chan_misdn.c.
References reload_config().
11370 { 11371 reload_config(); 11372 11373 return 0; 11374 }
static void reload_config | ( | void | ) | [static] |
Definition at line 4090 of file chan_misdn.c.
References ast_log(), free_robin_list(), LOG_WARNING, max_ports, misdn_cfg_get(), misdn_cfg_reload(), misdn_cfg_update_ptp(), misdn_debug, misdn_debug_only, MISDN_GEN_DEBUG, and MISDN_GEN_TRACEFILE.
04091 { 04092 int i, cfg_debug; 04093 04094 if (!g_config_initialized) { 04095 ast_log(LOG_WARNING, "chan_misdn is not initialized properly, still reloading ?\n"); 04096 return ; 04097 } 04098 04099 free_robin_list(); 04100 misdn_cfg_reload(); 04101 misdn_cfg_update_ptp(); 04102 misdn_cfg_get(0, MISDN_GEN_TRACEFILE, global_tracefile, sizeof(global_tracefile)); 04103 misdn_cfg_get(0, MISDN_GEN_DEBUG, &cfg_debug, sizeof(cfg_debug)); 04104 04105 for (i = 0; i <= max_ports; i++) { 04106 misdn_debug[i] = cfg_debug; 04107 misdn_debug_only[i] = 0; 04108 } 04109 }
static void send_cause2ast | ( | struct ast_channel * | ast, | |
struct misdn_bchannel * | bc, | |||
struct chan_list * | ch | |||
) | [static] |
Definition at line 8659 of file chan_misdn.c.
References AST_CAUSE_CALL_REJECTED, AST_CAUSE_DESTINATION_OUT_OF_ORDER, AST_CAUSE_NO_ROUTE_DESTINATION, AST_CAUSE_NO_ROUTE_TRANSIT_NET, AST_CAUSE_NUMBER_CHANGED, AST_CAUSE_UNALLOCATED, AST_CAUSE_USER_BUSY, AST_CONTROL_BUSY, ast_queue_control(), misdn_bchannel::cause, chan_misdn_log(), ast_channel::hangupcause, MISDN_BUSY, chan_list::need_busy, misdn_bchannel::pid, misdn_bchannel::port, and chan_list::state.
Referenced by hangup_chan().
08659 { 08660 if (!ast) { 08661 chan_misdn_log(1, 0, "send_cause2ast: No Ast\n"); 08662 return; 08663 } 08664 if (!bc) { 08665 chan_misdn_log(1, 0, "send_cause2ast: No BC\n"); 08666 return; 08667 } 08668 if (!ch) { 08669 chan_misdn_log(1, 0, "send_cause2ast: No Ch\n"); 08670 return; 08671 } 08672 08673 ast->hangupcause = bc->cause; 08674 08675 switch (bc->cause) { 08676 08677 case AST_CAUSE_UNALLOCATED: 08678 case AST_CAUSE_NO_ROUTE_TRANSIT_NET: 08679 case AST_CAUSE_NO_ROUTE_DESTINATION: 08680 case 4: /* Send special information tone */ 08681 case AST_CAUSE_NUMBER_CHANGED: 08682 case AST_CAUSE_DESTINATION_OUT_OF_ORDER: 08683 /* Congestion Cases */ 08684 /* 08685 * Not Queueing the Congestion anymore, since we want to hear 08686 * the inband message 08687 * 08688 chan_misdn_log(1, bc ? bc->port : 0, " --> * SEND: Queue Congestion pid:%d\n", bc ? bc->pid : -1); 08689 ch->state = MISDN_BUSY; 08690 08691 ast_queue_control(ast, AST_CONTROL_CONGESTION); 08692 */ 08693 break; 08694 08695 case AST_CAUSE_CALL_REJECTED: 08696 case AST_CAUSE_USER_BUSY: 08697 ch->state = MISDN_BUSY; 08698 08699 if (!ch->need_busy) { 08700 chan_misdn_log(1, bc ? bc->port : 0, "Queued busy already\n"); 08701 break; 08702 } 08703 08704 chan_misdn_log(1, bc ? bc->port : 0, " --> * SEND: Queue Busy pid:%d\n", bc ? bc->pid : -1); 08705 08706 ast_queue_control(ast, AST_CONTROL_BUSY); 08707 08708 ch->need_busy = 0; 08709 08710 break; 08711 } 08712 }
static void send_digit_to_chan | ( | struct chan_list * | cl, | |
char | digit | |||
) | [static] |
Definition at line 3648 of file chan_misdn.c.
References chan_list::ast, ast_debug, ast_playtones_start(), and ast_channel::name.
Referenced by handle_cli_misdn_send_digit(), and misdn_digit_end().
03649 { 03650 static const char * const dtmf_tones[] = { 03651 /* *INDENT-OFF* */ 03652 "!941+1336/100,!0/100", /* 0 */ 03653 "!697+1209/100,!0/100", /* 1 */ 03654 "!697+1336/100,!0/100", /* 2 */ 03655 "!697+1477/100,!0/100", /* 3 */ 03656 "!770+1209/100,!0/100", /* 4 */ 03657 "!770+1336/100,!0/100", /* 5 */ 03658 "!770+1477/100,!0/100", /* 6 */ 03659 "!852+1209/100,!0/100", /* 7 */ 03660 "!852+1336/100,!0/100", /* 8 */ 03661 "!852+1477/100,!0/100", /* 9 */ 03662 "!697+1633/100,!0/100", /* A */ 03663 "!770+1633/100,!0/100", /* B */ 03664 "!852+1633/100,!0/100", /* C */ 03665 "!941+1633/100,!0/100", /* D */ 03666 "!941+1209/100,!0/100", /* * */ 03667 "!941+1477/100,!0/100", /* # */ 03668 /* *INDENT-ON* */ 03669 }; 03670 struct ast_channel *chan = cl->ast; 03671 03672 if (digit >= '0' && digit <='9') { 03673 ast_playtones_start(chan, 0, dtmf_tones[digit - '0'], 0); 03674 } else if (digit >= 'A' && digit <= 'D') { 03675 ast_playtones_start(chan, 0, dtmf_tones[digit - 'A' + 10], 0); 03676 } else if (digit == '*') { 03677 ast_playtones_start(chan, 0, dtmf_tones[14], 0); 03678 } else if (digit == '#') { 03679 ast_playtones_start(chan, 0, dtmf_tones[15], 0); 03680 } else { 03681 /* not handled */ 03682 ast_debug(1, "Unable to handle DTMF tone '%c' for '%s'\n", digit, chan->name); 03683 } 03684 }
static void show_config_description | ( | int | fd, | |
enum misdn_cfg_elements | elem | |||
) | [inline, static] |
Definition at line 3929 of file chan_misdn.c.
References ast_cli(), BUFFERSIZE, COLOR_BRWHITE, COLOR_YELLOW, desc, misdn_cfg_get_desc(), misdn_cfg_get_name(), MISDN_CFG_LAST, name, and term_color().
Referenced by handle_cli_misdn_show_config().
03930 { 03931 char section[BUFFERSIZE]; 03932 char name[BUFFERSIZE]; 03933 char desc[BUFFERSIZE]; 03934 char def[BUFFERSIZE]; 03935 char tmp[BUFFERSIZE]; 03936 03937 misdn_cfg_get_name(elem, tmp, sizeof(tmp)); 03938 term_color(name, tmp, COLOR_BRWHITE, 0, sizeof(tmp)); 03939 misdn_cfg_get_desc(elem, desc, sizeof(desc), def, sizeof(def)); 03940 03941 if (elem < MISDN_CFG_LAST) { 03942 term_color(section, "PORTS SECTION", COLOR_YELLOW, 0, sizeof(section)); 03943 } else { 03944 term_color(section, "GENERAL SECTION", COLOR_YELLOW, 0, sizeof(section)); 03945 } 03946 03947 if (*def) { 03948 ast_cli(fd, "[%s] %s (Default: %s)\n\t%s\n", section, name, def, desc); 03949 } else { 03950 ast_cli(fd, "[%s] %s\n\t%s\n", section, name, desc); 03951 } 03952 }
static void sighandler | ( | int | sig | ) | [static] |
static int start_bc_tones | ( | struct chan_list * | cl | ) | [static] |
Definition at line 7668 of file chan_misdn.c.
References chan_list::bc, misdn_lib_tone_generator_stop(), chan_list::norxtone, and chan_list::notxtone.
Referenced by cb_events(), misdn_answer(), misdn_hangup(), and misdn_indication().
07669 { 07670 misdn_lib_tone_generator_stop(cl->bc); 07671 cl->notxtone = 0; 07672 cl->norxtone = 0; 07673 return 0; 07674 }
static void start_pbx | ( | struct chan_list * | ch, | |
struct misdn_bchannel * | bc, | |||
struct ast_channel * | chan | |||
) | [static] |
Definition at line 8805 of file chan_misdn.c.
References chan_misdn_log(), EVENT_RELEASE, EVENT_RELEASE_COMPLETE, hangup_chan(), hanguptone_indicate(), misdn_lib_send_event(), misdn_bchannel::nt, pbx_start_chan(), and misdn_bchannel::port.
Referenced by cb_events().
08806 { 08807 if (pbx_start_chan(ch) < 0) { 08808 hangup_chan(ch, bc); 08809 chan_misdn_log(-1, bc->port, "ast_pbx_start returned <0 in SETUP\n"); 08810 if (bc->nt) { 08811 hanguptone_indicate(ch); 08812 misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE); 08813 } else { 08814 misdn_lib_send_event(bc, EVENT_RELEASE); 08815 } 08816 } 08817 }
static int stop_bc_tones | ( | struct chan_list * | cl | ) | [static] |
Definition at line 7676 of file chan_misdn.c.
References chan_list::norxtone, and chan_list::notxtone.
Referenced by cb_events(), misdn_call(), and misdn_hangup().
07677 { 07678 if (!cl) { 07679 return -1; 07680 } 07681 07682 cl->notxtone = 1; 07683 cl->norxtone = 1; 07684 07685 return 0; 07686 }
static int stop_indicate | ( | struct chan_list * | cl | ) | [static] |
Definition at line 7647 of file chan_misdn.c.
References chan_list::ast, ast_playtones_stop(), ast_tone_zone_sound_unref(), chan_list::bc, chan_misdn_log(), misdn_lib_tone_generator_stop(), misdn_bchannel::port, and chan_list::ts.
Referenced by cb_events(), misdn_answer(), misdn_indication(), and misdn_overlap_dial_task().
07648 { 07649 struct ast_channel *ast = cl->ast; 07650 07651 if (!ast) { 07652 chan_misdn_log(0, cl->bc->port, "No Ast in stop_indicate\n"); 07653 return -1; 07654 } 07655 07656 chan_misdn_log(3, cl->bc->port, " --> None\n"); 07657 misdn_lib_tone_generator_stop(cl->bc); 07658 ast_playtones_stop(ast); 07659 07660 if (cl->ts) { 07661 cl->ts = ast_tone_zone_sound_unref(cl->ts); 07662 } 07663 07664 return 0; 07665 }
static int unload_module | ( | void | ) | [static] |
TE STUFF END
Definition at line 11111 of file chan_misdn.c.
References ast_channel_unregister(), ast_cli_unregister_multiple(), ast_custom_function_unregister(), ast_free, ast_log(), ast_unregister_application(), chan_misdn_clis, free_robin_list(), LOG_VERBOSE, misdn_cfg_destroy(), misdn_debug, misdn_debug_only, misdn_in_calls, misdn_lib_destroy(), misdn_out_calls, misdn_ports, misdn_tasks_destroy(), and misdn_tech.
11112 { 11113 /* First, take us out of the channel loop */ 11114 ast_log(LOG_VERBOSE, "-- Unregistering mISDN Channel Driver --\n"); 11115 11116 misdn_tasks_destroy(); 11117 11118 if (!g_config_initialized) { 11119 return 0; 11120 } 11121 11122 ast_cli_unregister_multiple(chan_misdn_clis, sizeof(chan_misdn_clis) / sizeof(struct ast_cli_entry)); 11123 11124 /* ast_unregister_application("misdn_crypt"); */ 11125 ast_unregister_application("misdn_set_opt"); 11126 ast_unregister_application("misdn_facility"); 11127 ast_unregister_application("misdn_check_l2l1"); 11128 #if defined(AST_MISDN_ENHANCEMENTS) 11129 ast_unregister_application(misdn_command_name); 11130 ast_custom_function_unregister(&misdn_cc_function); 11131 #endif /* defined(AST_MISDN_ENHANCEMENTS) */ 11132 11133 ast_channel_unregister(&misdn_tech); 11134 11135 free_robin_list(); 11136 misdn_cfg_destroy(); 11137 misdn_lib_destroy(); 11138 11139 ast_free(misdn_out_calls); 11140 ast_free(misdn_in_calls); 11141 ast_free(misdn_debug_only); 11142 ast_free(misdn_ports); 11143 ast_free(misdn_debug); 11144 11145 #if defined(AST_MISDN_ENHANCEMENTS) 11146 misdn_cc_destroy(); 11147 #endif /* defined(AST_MISDN_ENHANCEMENTS) */ 11148 11149 return 0; 11150 }
static void update_config | ( | struct chan_list * | ch | ) | [static] |
Updates caller ID information from config.
Definition at line 5729 of file chan_misdn.c.
References chan_list::ast, ast_log(), ast_to_misdn_pres(), ast_to_misdn_screen(), chan_list::bc, misdn_bchannel::caller, misdn_bchannel::capability, chan_misdn_log(), ast_channel::connected, misdn_bchannel::hdlc, ast_party_connected_line::id, INFO_CAPABILITY_DIGITAL_RESTRICTED, INFO_CAPABILITY_DIGITAL_UNRESTRICTED, LOG_WARNING, misdn_cfg_get(), MISDN_CFG_HDLC, MISDN_CFG_PRES, MISDN_CFG_SCREEN, misdn_to_str_pres(), misdn_to_str_screen(), ast_party_id::number, misdn_bchannel::port, misdn_party_id::presentation, ast_party_number::presentation, and misdn_party_id::screening.
Referenced by misdn_call().
05730 { 05731 struct ast_channel *ast; 05732 struct misdn_bchannel *bc; 05733 int port; 05734 int hdlc = 0; 05735 int pres; 05736 int screen; 05737 05738 if (!ch) { 05739 ast_log(LOG_WARNING, "Cannot configure without chanlist\n"); 05740 return; 05741 } 05742 05743 ast = ch->ast; 05744 bc = ch->bc; 05745 if (! ast || ! bc) { 05746 ast_log(LOG_WARNING, "Cannot configure without ast || bc\n"); 05747 return; 05748 } 05749 05750 port = bc->port; 05751 05752 chan_misdn_log(7, port, "update_config: Getting Config\n"); 05753 05754 misdn_cfg_get(port, MISDN_CFG_HDLC, &hdlc, sizeof(int)); 05755 if (hdlc) { 05756 switch (bc->capability) { 05757 case INFO_CAPABILITY_DIGITAL_UNRESTRICTED: 05758 case INFO_CAPABILITY_DIGITAL_RESTRICTED: 05759 chan_misdn_log(1, bc->port, " --> CONF HDLC\n"); 05760 bc->hdlc = 1; 05761 break; 05762 } 05763 } 05764 05765 05766 misdn_cfg_get(port, MISDN_CFG_PRES, &pres, sizeof(pres)); 05767 misdn_cfg_get(port, MISDN_CFG_SCREEN, &screen, sizeof(screen)); 05768 chan_misdn_log(2, port, " --> pres: %d screen: %d\n", pres, screen); 05769 05770 if (pres < 0 || screen < 0) { 05771 chan_misdn_log(2, port, " --> pres: %x\n", ast->connected.id.number.presentation); 05772 05773 bc->caller.presentation = ast_to_misdn_pres(ast->connected.id.number.presentation); 05774 chan_misdn_log(2, port, " --> PRES: %s(%d)\n", misdn_to_str_pres(bc->caller.presentation), bc->caller.presentation); 05775 05776 bc->caller.screening = ast_to_misdn_screen(ast->connected.id.number.presentation); 05777 chan_misdn_log(2, port, " --> SCREEN: %s(%d)\n", misdn_to_str_screen(bc->caller.screening), bc->caller.screening); 05778 } else { 05779 bc->caller.screening = screen; 05780 bc->caller.presentation = pres; 05781 } 05782 }
static int update_ec_config | ( | struct misdn_bchannel * | bc | ) | [static] |
Definition at line 5871 of file chan_misdn.c.
References misdn_bchannel::ec_deftaps, misdn_bchannel::ec_enable, MISDN_CFG_ECHOCANCEL, misdn_cfg_get(), and misdn_bchannel::port.
Referenced by handle_cli_misdn_toggle_echocancel(), and read_config().
05872 { 05873 int ec; 05874 int port = bc->port; 05875 05876 misdn_cfg_get(port, MISDN_CFG_ECHOCANCEL, &ec, sizeof(ec)); 05877 05878 if (ec == 1) { 05879 bc->ec_enable = 1; 05880 } else if (ec > 1) { 05881 bc->ec_enable = 1; 05882 bc->ec_deftaps = ec; 05883 } 05884 05885 return 0; 05886 }
static void update_name | ( | struct ast_channel * | tmp, | |
int | port, | |||
int | c | |||
) | [static] |
Definition at line 8065 of file chan_misdn.c.
References ast_change_name(), chan_misdn_log(), misdn_cfg_get_next_port(), misdn_lib_port_is_pri(), misdn_type, and ast_channel::name.
Referenced by cb_events().
08066 { 08067 int chan_offset = 0; 08068 int tmp_port = misdn_cfg_get_next_port(0); 08069 char newname[255]; 08070 08071 for (; tmp_port > 0; tmp_port = misdn_cfg_get_next_port(tmp_port)) { 08072 if (tmp_port == port) { 08073 break; 08074 } 08075 chan_offset += misdn_lib_port_is_pri(tmp_port) ? 30 : 2; 08076 } 08077 if (c < 0) { 08078 c = 0; 08079 } 08080 08081 snprintf(newname, sizeof(newname), "%s/%d-", misdn_type, chan_offset + c); 08082 if (strncmp(tmp->name, newname, strlen(newname))) { 08083 snprintf(newname, sizeof(newname), "%s/%d-u%d", misdn_type, chan_offset + c, glob_channel++); 08084 ast_change_name(tmp, newname); 08085 chan_misdn_log(3, port, " --> updating channel name to [%s]\n", tmp->name); 08086 } 08087 }
static void wait_for_digits | ( | struct chan_list * | ch, | |
struct misdn_bchannel * | bc, | |||
struct ast_channel * | chan | |||
) | [static] |
Definition at line 8819 of file chan_misdn.c.
References misdn_bchannel::dialed, dialtone_indicate(), EVENT_SETUP_ACKNOWLEDGE, misdn_lib_send_event(), MISDN_WAITING4DIGS, misdn_bchannel::nt, misdn_party_dialing::number, and chan_list::state.
Referenced by cb_events().
08820 { 08821 ch->state = MISDN_WAITING4DIGS; 08822 misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE); 08823 if (bc->nt && !bc->dialed.number[0]) { 08824 dialtone_indicate(ch); 08825 } 08826 }
struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Channel driver for mISDN Support (BRI/PRI)" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "8586c2a7d357cb591cc3a6607a8f62d1" , .load = load_module, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_CHANNEL_DRIVER, } [static] |
Definition at line 12679 of file chan_misdn.c.
struct allowed_bearers allowed_bearers_array[] [static] |
struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 12679 of file chan_misdn.c.
struct ast_cli_entry chan_misdn_clis[] [static] |
Global channel call record list head.
Definition at line 676 of file chan_misdn.c.
Referenced by cl_dequeue_chan(), cl_queue_chan(), find_chan_by_bc(), find_hold_active_call(), find_hold_call(), find_hold_call_l3(), get_chan_by_ast(), get_chan_by_ast_name(), handle_cli_misdn_show_channel(), handle_cli_misdn_show_channels(), and misdn_chan_is_valid().
ast_mutex_t cl_te_lock [static] |
Definition at line 677 of file chan_misdn.c.
Referenced by cl_dequeue_chan(), cl_queue_chan(), find_chan_by_bc(), find_hold_active_call(), find_hold_call(), find_hold_call_l3(), get_chan_by_ast(), get_chan_by_ast_name(), handle_cli_misdn_show_channel(), handle_cli_misdn_show_channels(), load_module(), and misdn_chan_is_valid().
int g_config_initialized = 0 [static] |
Definition at line 99 of file chan_misdn.c.
int glob_channel = 0 [static] |
Definition at line 8063 of file chan_misdn.c.
char global_tracefile[BUFFERSIZE+1] [static] |
The latest modified mISDN v1.1.x based version is available at: http://svn.digium.com/svn/thirdparty/mISDN/trunk http://svn.digium.com/svn/thirdparty/mISDNuser/trunk
Taged versions of the modified mISDN code are available under: http://svn.digium.com/svn/thirdparty/mISDN/tags http://svn.digium.com/svn/thirdparty/mISDNuser/tags
Definition at line 97 of file chan_misdn.c.
int max_ports [static] |
Definition at line 668 of file chan_misdn.c.
Referenced by _build_port_config(), chan_misdn_log(), handle_cli_misdn_set_debug(), load_module(), misdn_cfg_get_next_port(), misdn_cfg_get_ports_string(), misdn_cfg_init(), misdn_cfg_is_group_method(), misdn_cfg_is_port_valid(), misdn_cfg_update_ptp(), and reload_config().
int MAXTICS = 8 |
Definition at line 582 of file chan_misdn.c.
int* misdn_debug [static] |
Definition at line 666 of file chan_misdn.c.
Referenced by chan_misdn_log(), handle_cli_misdn_set_debug(), handle_cli_misdn_show_channels(), handle_cli_misdn_show_port(), handle_cli_misdn_show_stacks(), load_module(), print_bc_info(), reload_config(), and unload_module().
int* misdn_debug_only [static] |
Definition at line 667 of file chan_misdn.c.
Referenced by chan_misdn_log(), handle_cli_misdn_set_debug(), handle_cli_misdn_show_port(), handle_cli_misdn_show_stacks(), load_module(), reload_config(), and unload_module().
int* misdn_in_calls [static] |
Definition at line 670 of file chan_misdn.c.
Referenced by add_in_calls(), handle_cli_misdn_show_ports_stats(), load_module(), release_chan(), release_chan_early(), and unload_module().
int* misdn_out_calls [static] |
Definition at line 671 of file chan_misdn.c.
Referenced by add_out_calls(), handle_cli_misdn_show_ports_stats(), load_module(), release_chan(), release_chan_early(), and unload_module().
int* misdn_ports [static] |
struct sched_context* misdn_tasks = NULL [static] |
the main schedule context for stuff like l1 watcher, overlap dial, ...
Definition at line 640 of file chan_misdn.c.
Referenced by _misdn_tasks_add_variable(), misdn_tasks_destroy(), misdn_tasks_init(), misdn_tasks_remove(), and misdn_tasks_thread_func().
pthread_t misdn_tasks_thread [static] |
Definition at line 641 of file chan_misdn.c.
Referenced by misdn_tasks_destroy(), misdn_tasks_init(), and misdn_tasks_wakeup().
struct ast_channel_tech misdn_tech [static] |
Definition at line 8025 of file chan_misdn.c.
Referenced by load_module(), misdn_new(), and unload_module().
struct ast_channel_tech misdn_tech_wo_bridge [static] |
const char misdn_type[] = "mISDN" [static] |
Definition at line 659 of file chan_misdn.c.
Referenced by load_module(), misdn_facility_exec(), misdn_new(), misdn_request(), misdn_set_opt_exec(), and update_name().
int prefformat = AST_FORMAT_ALAW [static] |
Only alaw and mulaw is allowed for now.
Definition at line 664 of file chan_misdn.c.
Referenced by misdn_new(), and misdn_write().
ast_mutex_t release_lock [static] |
Definition at line 293 of file chan_misdn.c.
Referenced by load_module(), misdn_hangup(), release_chan(), and release_chan_early().
struct robin_list* robin = NULL [static] |
Definition at line 596 of file chan_misdn.c.
Referenced by free_robin_list(), and get_robin_position().
struct state_struct state_array[] [static] |
int tracing = 0 [static] |