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