#include "asterisk.h"
#include <pthread.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <signal.h>
#include <sys/file.h>
#include <semaphore.h>
#include <ctype.h>
#include <time.h>
#include "asterisk/channel.h"
#include "asterisk/config.h"
#include "asterisk/module.h"
#include "asterisk/pbx.h"
#include "asterisk/io.h"
#include "asterisk/frame.h"
#include "asterisk/translate.h"
#include "asterisk/cli.h"
#include "asterisk/musiconhold.h"
#include "asterisk/dsp.h"
#include "asterisk/file.h"
#include "asterisk/callerid.h"
#include "asterisk/indications.h"
#include "asterisk/app.h"
#include "asterisk/features.h"
#include "asterisk/term.h"
#include "asterisk/sched.h"
#include "asterisk/stringfields.h"
#include "asterisk/abstract_jb.h"
#include "asterisk/causes.h"
#include "chan_misdn_config.h"
#include "isdn_lib.h"
#include "asterisk/strings.h"
Go to the source code of this file.
Data Structures | |
struct | allowed_bearers |
struct | chan_list |
Channel call record structure. More... | |
struct | hold_info |
struct | misdn_jb |
struct | robin_list |
struct | state_struct |
Defines | |
#define | chan_list_ref(obj, debug) (ao2_t_ref((obj), +1, (debug)), (obj)) |
#define | chan_list_unref(obj, debug) (ao2_t_ref((obj), -1, (debug)), NULL) |
#define | MISDN_ASTERISK_TECH_PVT(ast) ast->tech_pvt |
#define | ORG_AST 1 |
#define | ORG_MISDN 2 |
#define | TRANSFER_ON_HELD_CALL_HANGUP 1 |
Enumerations | |
enum | misdn_chan_state { MISDN_NOTHING = 0, MISDN_WAITING4DIGS, MISDN_EXTCANTMATCH, MISDN_INCOMING_SETUP, MISDN_DIALING, MISDN_PROGRESS, MISDN_PROCEEDING, MISDN_CALLING, MISDN_CALLING_ACKNOWLEDGE, MISDN_ALERTING, MISDN_BUSY, MISDN_CONNECTED, MISDN_DISCONNECTED, MISDN_CLEANING } |
enum | misdn_hold_state { MISDN_HOLD_IDLE, MISDN_HOLD_ACTIVE, MISDN_HOLD_TRANSFER, MISDN_HOLD_DISCONNECT } |
Functions | |
static void | __reg_module (void) |
static void | __unreg_module (void) |
static int | _misdn_tasks_add_variable (int timeout, ast_sched_cb callback, const void *data, int variable) |
int | add_in_calls (int port) |
int | add_out_calls (int port) |
static enum mISDN_NUMBER_PLAN | ast_to_misdn_plan (unsigned ast_number_plan) |
static int | ast_to_misdn_pres (int presentation) |
static enum mISDN_REDIRECTING_REASON | ast_to_misdn_reason (const enum AST_REDIRECTING_REASON ast) |
static int | ast_to_misdn_screen (int screening) |
static enum mISDN_NUMBER_TYPE | ast_to_misdn_ton (unsigned ast_number_type) |
static const char * | bearer2str (int cap) |
static enum event_response_e | cb_events (enum event_e event, struct misdn_bchannel *bc, void *user_data) |
static void | chan_list_destructor (void *obj) |
static struct chan_list * | chan_list_init (int orig) |
int | chan_misdn_jb_empty (struct misdn_bchannel *bc, char *buf, int len) |
static void | chan_misdn_log (int level, int port, char *tmpl,...) |
static int | cl_dequeue_chan (struct chan_list *chan) |
static void | cl_queue_chan (struct chan_list *chan) |
static char * | complete_ch (struct ast_cli_args *a) |
static char * | complete_debug_port (struct ast_cli_args *a) |
static char * | complete_show_config (struct ast_cli_args *a) |
static void | config_jitterbuffer (struct chan_list *ch) |
void | debug_numtype (int port, int numtype, char *type) |
static int | dialtone_indicate (struct chan_list *cl) |
static void | do_immediate_setup (struct misdn_bchannel *bc, struct chan_list *ch, struct ast_channel *ast) |
static void | export_aoc_vars (int originator, struct ast_channel *ast, struct misdn_bchannel *bc) |
void | export_ch (struct ast_channel *chan, struct misdn_bchannel *bc, struct chan_list *ch) |
Export parameters to the dialplan environment variables. | |
static struct chan_list * | find_chan_by_bc (struct misdn_bchannel *bc) |
static struct chan_list * | find_hold_active_call (struct misdn_bchannel *bc) |
static struct chan_list * | find_hold_call (struct misdn_bchannel *bc) |
static struct chan_list * | find_hold_call_l3 (unsigned long l3_id) |
static void | free_robin_list (void) |
static struct chan_list * | get_chan_by_ast (struct ast_channel *ast) |
static struct chan_list * | get_chan_by_ast_name (const char *name) |
static struct robin_list * | get_robin_position (char *group) |
static char * | handle_cli_misdn_port_block (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_misdn_port_down (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_misdn_port_unblock (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_misdn_port_up (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_misdn_reload (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_misdn_restart_pid (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_misdn_restart_port (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_misdn_send_digit (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_misdn_send_display (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_misdn_send_facility (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_misdn_send_restart (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_misdn_set_crypt_debug (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_misdn_set_debug (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_misdn_set_tics (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_misdn_show_channel (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_misdn_show_channels (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_misdn_show_config (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_misdn_show_port (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_misdn_show_ports_stats (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_misdn_show_stacks (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_misdn_toggle_echocancel (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static void | hangup_chan (struct chan_list *ch, struct misdn_bchannel *bc) |
static void | hanguptone_indicate (struct chan_list *cl) |
void | import_ch (struct ast_channel *chan, struct misdn_bchannel *bc, struct chan_list *ch) |
Import parameters from the dialplan environment variables. | |
static int | load_module (void) |
static void | misdn_add_number_prefix (int port, enum mISDN_NUMBER_TYPE number_type, char *number, size_t size) |
static int | misdn_answer (struct ast_channel *ast) |
static int | misdn_attempt_transfer (struct chan_list *active_ch, struct chan_list *held_ch) |
static enum ast_bridge_result | misdn_bridge (struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc, int timeoutms) |
static int | misdn_call (struct ast_channel *ast, char *dest, int timeout) |
static int | misdn_chan_is_valid (struct chan_list *ch) |
static int | misdn_check_l2l1 (struct ast_channel *chan, const char *data) |
static void | misdn_copy_redirecting_from_ast (struct misdn_bchannel *bc, struct ast_channel *ast) |
static void | misdn_copy_redirecting_to_ast (struct ast_channel *ast, const struct misdn_party_redirecting *redirect, char *tag) |
static int | misdn_digit_begin (struct ast_channel *chan, char digit) |
static int | misdn_digit_end (struct ast_channel *ast, char digit, unsigned int duration) |
static int | misdn_facility_exec (struct ast_channel *chan, const char *data) |
static void | misdn_facility_ie_handler (enum event_e event, struct misdn_bchannel *bc, struct chan_list *ch) |
static int | misdn_fixup (struct ast_channel *oldast, struct ast_channel *ast) |
static const char * | misdn_get_ch_state (struct chan_list *p) |
static void | misdn_get_connected_line (struct ast_channel *ast, struct misdn_bchannel *bc, int originator) |
static int | misdn_hangup (struct ast_channel *ast) |
static int | misdn_indication (struct ast_channel *ast, int cond, const void *data, size_t datalen) |
static int | misdn_is_msn_valid (int port, const struct misdn_party_dialing *dialed) |
void | misdn_jb_destroy (struct misdn_jb *jb) |
frees the data and destroys the given jitterbuffer struct | |
int | misdn_jb_empty (struct misdn_jb *jb, char *data, int len) |
gets len bytes out of the jitterbuffer if available, else only the available data is returned and the return value indicates the number of data. | |
int | misdn_jb_fill (struct misdn_jb *jb, const char *data, int len) |
fills the jitterbuffer with len data returns < 0 if there was an error (buffer overrun). | |
misdn_jb * | misdn_jb_init (int size, int upper_threshold) |
allocates the jb-structure and initialize the elements | |
static int | misdn_l1_task (const void *vdata) |
static struct ast_channel * | misdn_new (struct chan_list *cl, int state, char *exten, char *callerid, int format, const char *linkedid, int port, int c) |
static int | misdn_overlap_dial_task (const void *data) |
static void | misdn_prefix_string (const char *str_prefix, char *str_main, size_t size) |
static void | misdn_queue_connected_line_update (struct ast_channel *ast, const struct misdn_party_id *id, enum AST_CONNECTED_LINE_UPDATE_SOURCE source, char *cid_tag) |
static struct ast_frame * | misdn_read (struct ast_channel *ast) |
static struct ast_channel * | misdn_request (const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause) |
static int | misdn_send_text (struct ast_channel *chan, const char *text) |
static int | misdn_set_opt_exec (struct ast_channel *chan, const char *data) |
static int | misdn_tasks_add (int timeout, ast_sched_cb callback, const void *data) |
static int | misdn_tasks_add_variable (int timeout, ast_sched_cb callback, const void *data) |
static void | misdn_tasks_destroy (void) |
static void | misdn_tasks_init (void) |
static void | misdn_tasks_remove (int task_id) |
static void * | misdn_tasks_thread_func (void *data) |
static void | misdn_tasks_wakeup (void) |
static int | misdn_to_ast_plan (enum mISDN_NUMBER_PLAN number_plan) |
static int | misdn_to_ast_pres (int presentation) |
static enum AST_REDIRECTING_REASON | misdn_to_ast_reason (const enum mISDN_REDIRECTING_REASON q931) |
static int | misdn_to_ast_screen (int screening) |
static int | misdn_to_ast_ton (enum mISDN_NUMBER_TYPE number_type) |
static const char * | misdn_to_str_plan (enum mISDN_NUMBER_PLAN number_plan) |
static const char * | misdn_to_str_pres (int presentation) |
static const char * | misdn_to_str_screen (int screening) |
static const char * | misdn_to_str_ton (enum mISDN_NUMBER_TYPE number_type) |
static void | misdn_update_caller_id (struct ast_channel *ast, const struct misdn_party_id *id, char *cid_tag) |
static void | misdn_update_connected_line (struct ast_channel *ast, struct misdn_bchannel *bc, int originator) |
static void | misdn_update_redirecting (struct ast_channel *ast, struct misdn_bchannel *bc, int originator) |
static void | misdn_update_remote_party (struct ast_channel *ast, const struct misdn_party_id *id, enum AST_CONNECTED_LINE_UPDATE_SOURCE source, char *cid_tag) |
static int | misdn_write (struct ast_channel *ast, struct ast_frame *frame) |
static int | pbx_start_chan (struct chan_list *ch) |
static void | print_bc_info (int fd, struct chan_list *help, struct misdn_bchannel *bc) |
static void | print_bearer (struct misdn_bchannel *bc) |
static void | print_facility (const struct FacParm *fac, const const struct misdn_bchannel *bc) |
static struct ast_frame * | process_ast_dsp (struct chan_list *tmp, struct ast_frame *frame) |
static int | read_config (struct chan_list *ch) |
static void | release_chan (struct chan_list *ch, struct misdn_bchannel *bc) |
static void | release_chan_early (struct chan_list *ch) |
static int | reload (void) |
static void | reload_config (void) |
static 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 ast_module_info | __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Channel driver for mISDN Support (BRI/PRI)" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "ac1f6a56484a8820659555499174e588" , .load = load_module, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_CHANNEL_DRIVER, } |
static struct allowed_bearers | allowed_bearers_array [] |
static struct ast_module_info * | ast_module_info = &__mod_info |
static struct ast_cli_entry | chan_misdn_clis [] |
static struct chan_list * | cl_te = NULL |
Global channel call record list head. | |
static ast_mutex_t | cl_te_lock |
static int | g_config_initialized = 0 |
static int | glob_channel = 0 |
static char | global_tracefile [BUFFERSIZE+1] |
static int | max_ports |
int | MAXTICS = 8 |
static int * | misdn_debug |
static int * | misdn_debug_only |
static int * | misdn_in_calls |
static int * | misdn_out_calls |
static int * | misdn_ports |
static struct sched_context * | misdn_tasks = NULL |
the main schedule context for stuff like l1 watcher, overlap dial, ... | |
static pthread_t | misdn_tasks_thread |
static struct ast_channel_tech | misdn_tech |
static struct ast_channel_tech | misdn_tech_wo_bridge |
static const char | misdn_type [] = "mISDN" |
static int | prefformat = AST_FORMAT_ALAW |
Only alaw and mulaw is allowed for now. | |
static ast_mutex_t | release_lock |
static struct robin_list * | robin = NULL |
static struct state_struct | state_array [] |
static int | tracing = 0 |
Definition in file chan_misdn.c.
#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_display(), handle_cli_misdn_send_facility(), handle_cli_misdn_toggle_echocancel(), misdn_bridge(), misdn_hangup(), 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(), 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 8262 of file chan_misdn.c.
enum misdn_chan_state |
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 void __reg_module | ( | void | ) | [static] |
Definition at line 12704 of file chan_misdn.c.
static void __unreg_module | ( | void | ) | [static] |
Definition at line 12704 of file chan_misdn.c.
static int _misdn_tasks_add_variable | ( | int | timeout, | |
ast_sched_cb | callback, | |||
const void * | data, | |||
int | variable | |||
) | [inline, static] |
Definition at line 3560 of file chan_misdn.c.
References ast_sched_add_variable(), misdn_tasks, misdn_tasks_init(), and misdn_tasks_wakeup().
Referenced by misdn_tasks_add(), and misdn_tasks_add_variable().
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 8804 of file chan_misdn.c.
References ast_log(), LOG_NOTICE, misdn_cfg_get(), MISDN_CFG_MAX_IN, and misdn_in_calls.
Referenced by cb_events().
08805 { 08806 int max_in_calls; 08807 08808 misdn_cfg_get(port, MISDN_CFG_MAX_IN, &max_in_calls, sizeof(max_in_calls)); 08809 misdn_in_calls[port]++; 08810 08811 if (max_in_calls >= 0 && max_in_calls < misdn_in_calls[port]) { 08812 ast_log(LOG_NOTICE, "Marking Incoming Call on port[%d]\n", port); 08813 return misdn_in_calls[port] - max_in_calls; 08814 } 08815 08816 return 0; 08817 }
int add_out_calls | ( | int | port | ) |
Definition at line 8819 of file chan_misdn.c.
References ast_log(), LOG_NOTICE, misdn_cfg_get(), MISDN_CFG_MAX_OUT, and misdn_out_calls.
Referenced by misdn_call().
08820 { 08821 int max_out_calls; 08822 08823 misdn_cfg_get(port, MISDN_CFG_MAX_OUT, &max_out_calls, sizeof(max_out_calls)); 08824 08825 if (max_out_calls >= 0 && max_out_calls <= misdn_out_calls[port]) { 08826 ast_log(LOG_NOTICE, "Rejecting Outgoing Call on port[%d]\n", port); 08827 return (misdn_out_calls[port] + 1) - max_out_calls; 08828 } 08829 08830 misdn_out_calls[port]++; 08831 08832 return 0; 08833 }
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 allowed_bearers_array, ARRAY_LEN, and allowed_bearers::display.
Referenced by cb_events(), misdn_lib_log_ies(), 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] |
Definition at line 9861 of file chan_misdn.c.
References add_in_calls(), misdn_bchannel::addr, chan_list::addr, chan_list::allowed_bearers, allowed_bearers_array, ao2_ref, misdn_bchannel::AOCD_need_export, ARRAY_LEN, chan_list::ast, ast_bridged_channel(), ast_canmatch_extension(), AST_CAUSE_DESTINATION_OUT_OF_ORDER, AST_CAUSE_INCOMPATIBLE_DESTINATION, AST_CAUSE_NORMAL_CLEARING, AST_CAUSE_UNALLOCATED, AST_CAUSE_USER_BUSY, ast_cdr_update(), ast_channel_lock, ast_channel_queue_redirecting_update(), ast_channel_unlock, AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER, AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER, AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER_ALERTING, AST_CONTROL_ANSWER, AST_CONTROL_BUSY, AST_CONTROL_HOLD, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_RINGING, AST_CONTROL_UNHOLD, ast_copy_string(), ast_deactivate_generator(), ast_exists_extension(), AST_FORMAT_ALAW, AST_FRAME_DTMF, AST_FRAME_VOICE, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_pickup_call(), ast_pickup_ext(), ast_poll, AST_PRES_RESTRICTED, AST_PRES_USER_NUMBER_UNSCREENED, ast_queue_control(), ast_queue_frame(), ast_set_callerid(), ast_setstate(), AST_STATE_RESERVED, AST_STATE_RINGING, ast_strdup, ast_strlen_zero(), ast_transfercapability2str(), ast_tv(), ast_tvnow(), chan_list::bc, misdn_bchannel::bc_state, bc_state2str(), bearer2str(), misdn_bchannel::bframe, misdn_bchannel::bframe_len, ast_channel::caller, misdn_bchannel::caller, misdn_bchannel::capability, misdn_bchannel::cause, cause, cb_log, chan_list_init(), chan_list_unref, chan_misdn_log(), hold_info::channel, misdn_bchannel::channel, cl_queue_chan(), misdn_bchannel::connected, chan_list::context, misdn_bchannel::cw, misdn_bchannel::dialed, do_immediate_setup(), misdn_bchannel::dtmf, misdn_bchannel::dummy, errno, EVENT_ALERTING, EVENT_BCHAN_ACTIVATED, EVENT_BCHAN_DATA, EVENT_BCHAN_ERROR, EVENT_CLEANUP, EVENT_CONNECT, EVENT_CONNECT_ACKNOWLEDGE, EVENT_DISCONNECT, EVENT_DTMF_TONE, EVENT_FACILITY, EVENT_HOLD, EVENT_HOLD_ACKNOWLEDGE, EVENT_HOLD_REJECT, EVENT_INFORMATION, EVENT_NEW_BC, EVENT_NEW_CHANNEL, EVENT_NEW_L3ID, EVENT_NOTIFY, EVENT_PORT_ALARM, EVENT_PROCEEDING, EVENT_PROGRESS, EVENT_REGISTER, EVENT_RELEASE, EVENT_RELEASE_COMPLETE, EVENT_RESTART, EVENT_RETRIEVE, EVENT_RETRIEVE_ACKNOWLEDGE, EVENT_RETRIEVE_REJECT, EVENT_SETUP, EVENT_SETUP_ACKNOWLEDGE, EVENT_STATUS, EVENT_TIMEOUT, EVENT_TONE_GENERATE, export_aoc_vars(), export_ch(), ast_channel::exten, misdn_bchannel::fac_in, misdn_bchannel::fac_out, chan_list::far_alerting, find_chan_by_bc(), find_hold_active_call(), find_hold_call(), find_hold_call_l3(), misdn_party_redirecting::from, ast_generator::generate, ast_channel::generator, ast_channel::generatordata, hangup_chan(), ast_channel::hangupcause, hanguptone_indicate(), chan_list::hold, ast_party_caller::id, chan_list::ignore_dtmf, misdn_bchannel::incoming_cid_tag, INFO_CAPABILITY_DIGITAL_UNRESTRICTED, misdn_bchannel::info_dad, INFO_PI_INBAND_AVAILABLE, misdn_bchannel::infos_pending, misdn_bchannel::keypad, misdn_bchannel::l3_id, chan_list::l3id, LOG_ERROR, LOG_NOTICE, LOG_WARNING, manager_isdn_get_info(), misdn_add_number_prefix(), MISDN_ALERTING, MISDN_ASTERISK_TECH_PVT, misdn_attempt_transfer(), MISDN_CALLING, MISDN_CALLING_ACKNOWLEDGE, misdn_cap_is_speech(), MISDN_CFG_ALARM_BLOCK, MISDN_CFG_ALWAYS_IMMEDIATE, MISDN_CFG_APPEND_MSN_TO_CALLERID_TAG, misdn_cfg_get(), MISDN_CFG_HOLD_ALLOWED, MISDN_CFG_IMMEDIATE, MISDN_CFG_REJECT_CAUSE, MISDN_CLEANING, MISDN_CONNECTED, misdn_copy_redirecting_to_ast(), MISDN_DIALING, MISDN_DISCONNECTED, MISDN_EXTCANTMATCH, misdn_facility_ie_handler(), MISDN_GEN_APPEND_DIGITS2EXTEN, misdn_get_ch_state(), MISDN_HOLD_ACTIVE, MISDN_HOLD_DISCONNECT, MISDN_HOLD_IDLE, misdn_inband_avail(), MISDN_INCOMING_SETUP, misdn_is_msn_valid(), misdn_lib_is_ptp(), misdn_lib_log_ies(), misdn_lib_port_block(), misdn_lib_send_event(), misdn_new(), MISDN_NOTHING, mISDN_NOTIFY_CODE_CALL_IS_DIVERTING, mISDN_NOTIFY_CODE_CALL_TRANSFER_ACTIVE, mISDN_NOTIFY_CODE_CALL_TRANSFER_ALERTING, mISDN_NOTIFY_CODE_DIVERSION_ACTIVATED, mISDN_NOTIFY_CODE_INVALID, misdn_overlap_dial_task(), MISDN_PROCEEDING, MISDN_PROGRESS, mISDN_REDIRECTING_REASON_NO_REPLY, mISDN_REDIRECTING_REASON_UNKNOWN, misdn_tasks_add_variable(), misdn_to_ast_plan(), misdn_to_ast_pres(), misdn_to_ast_screen(), misdn_to_ast_ton(), misdn_to_str_plan(), misdn_to_str_pres(), misdn_to_str_screen(), misdn_to_str_ton(), misdn_update_remote_party(), MISDN_WAITING4DIGS, allowed_bearers::name, misdn_party_id::name, chan_list::need_busy, misdn_bchannel::need_disconnect, misdn_bchannel::need_more_infos, misdn_bchannel::need_release, misdn_bchannel::need_release_complete, chan_list::noautorespond_on_setup, misdn_bchannel::notify_description_code, misdn_bchannel::nt, chan_list::nttimeout, ast_party_id::number, misdn_party_dialing::number, misdn_party_id::number, misdn_party_id::number_plan, misdn_party_id::number_type, ORG_AST, ORG_MISDN, chan_list::originator, misdn_bchannel::out_cause, chan_list::overlap_dial, chan_list::overlap_dial_task, chan_list::overlap_tv, chan_list::overlap_tv_lock, pbx_builtin_setvar_helper(), misdn_bchannel::pid, chan_list::pipe, ast_party_number::plan, hold_info::port, misdn_bchannel::port, ast_party_number::presentation, misdn_party_id::presentation, print_bearer(), misdn_bchannel::progress_indicator, read_config(), misdn_party_redirecting::reason, ast_channel::redirecting, misdn_bchannel::redirecting, release_chan(), RESPONSE_IGNORE_SETUP, RESPONSE_IGNORE_SETUP_WITHOUT_CLOSE, RESPONSE_OK, RESPONSE_RELEASE_SETUP, ast_channel::rings, misdn_party_id::screening, misdn_bchannel::sending_complete, start_bc_tones(), start_pbx(), hold_info::state, chan_list::state, stop_bc_tones(), stop_indicate(), ast_party_id::tag, ast_channel::tech, misdn_party_redirecting::to, ast_party_redirecting::to, misdn_party_redirecting::to_changed, misdn_bchannel::tone_cnt, ast_channel::transfercapability, ast_channel_tech::type, update_name(), and wait_for_digits().
Referenced by load_module().
09862 { 09863 #if defined(AST_MISDN_ENHANCEMENTS) 09864 struct misdn_cc_record *cc_record; 09865 #endif /* defined(AST_MISDN_ENHANCEMENTS) */ 09866 struct chan_list *held_ch; 09867 struct chan_list *ch = find_chan_by_bc(bc); 09868 09869 if (event != EVENT_BCHAN_DATA && event != EVENT_TONE_GENERATE) { 09870 int debuglevel = 1; 09871 09872 /* Debug Only Non-Bchan */ 09873 if (event == EVENT_CLEANUP && !user_data) { 09874 debuglevel = 5; 09875 } 09876 09877 chan_misdn_log(debuglevel, bc->port, 09878 "I IND :%s caller:\"%s\" <%s> dialed:%s pid:%d state:%s\n", 09879 manager_isdn_get_info(event), 09880 bc->caller.name, 09881 bc->caller.number, 09882 bc->dialed.number, 09883 bc->pid, 09884 ch ? misdn_get_ch_state(ch) : "none"); 09885 if (debuglevel == 1) { 09886 misdn_lib_log_ies(bc); 09887 chan_misdn_log(4, bc->port, " --> bc_state:%s\n", bc_state2str(bc->bc_state)); 09888 } 09889 } 09890 09891 if (!ch) { 09892 switch(event) { 09893 case EVENT_SETUP: 09894 case EVENT_DISCONNECT: 09895 case EVENT_RELEASE: 09896 case EVENT_RELEASE_COMPLETE: 09897 case EVENT_PORT_ALARM: 09898 case EVENT_RETRIEVE: 09899 case EVENT_NEW_BC: 09900 case EVENT_FACILITY: 09901 case EVENT_REGISTER: 09902 break; 09903 case EVENT_CLEANUP: 09904 case EVENT_TONE_GENERATE: 09905 case EVENT_BCHAN_DATA: 09906 return -1; 09907 default: 09908 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); 09909 return -1; 09910 } 09911 } else { 09912 switch (event) { 09913 case EVENT_TONE_GENERATE: 09914 break; 09915 case EVENT_DISCONNECT: 09916 case EVENT_RELEASE: 09917 case EVENT_RELEASE_COMPLETE: 09918 case EVENT_CLEANUP: 09919 case EVENT_TIMEOUT: 09920 if (!ch->ast) { 09921 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)); 09922 } 09923 break; 09924 default: 09925 if (!ch->ast || !MISDN_ASTERISK_TECH_PVT(ch->ast)) { 09926 if (event != EVENT_BCHAN_DATA) { 09927 ast_log(LOG_NOTICE, "No Ast or No private Pointer in Event (%d:%s)\n", event, manager_isdn_get_info(event)); 09928 } 09929 chan_list_unref(ch, "No Ast or Ast private pointer"); 09930 return -1; 09931 } 09932 break; 09933 } 09934 } 09935 09936 09937 switch (event) { 09938 case EVENT_PORT_ALARM: 09939 { 09940 int boa = 0; 09941 misdn_cfg_get(bc->port, MISDN_CFG_ALARM_BLOCK, &boa, sizeof(boa)); 09942 if (boa) { 09943 cb_log(1, bc->port, " --> blocking\n"); 09944 misdn_lib_port_block(bc->port); 09945 } 09946 } 09947 break; 09948 case EVENT_BCHAN_ACTIVATED: 09949 break; 09950 09951 case EVENT_NEW_CHANNEL: 09952 update_name(ch->ast,bc->port,bc->channel); 09953 break; 09954 09955 case EVENT_NEW_L3ID: 09956 ch->l3id=bc->l3_id; 09957 ch->addr=bc->addr; 09958 break; 09959 09960 case EVENT_NEW_BC: 09961 if (!ch) { 09962 ch = find_hold_call(bc); 09963 } 09964 09965 if (!ch) { 09966 ast_log(LOG_WARNING, "NEW_BC without chan_list?\n"); 09967 break; 09968 } 09969 09970 if (bc) { 09971 ch->bc = (struct misdn_bchannel *) user_data; 09972 } 09973 break; 09974 09975 case EVENT_DTMF_TONE: 09976 { 09977 /* sending INFOS as DTMF-Frames :) */ 09978 struct ast_frame fr; 09979 09980 memset(&fr, 0, sizeof(fr)); 09981 fr.frametype = AST_FRAME_DTMF; 09982 fr.subclass.integer = bc->dtmf ; 09983 fr.src = NULL; 09984 fr.data.ptr = NULL; 09985 fr.datalen = 0; 09986 fr.samples = 0; 09987 fr.mallocd = 0; 09988 fr.offset = 0; 09989 fr.delivery = ast_tv(0,0); 09990 09991 if (!ch->ignore_dtmf) { 09992 chan_misdn_log(2, bc->port, " --> DTMF:%c\n", bc->dtmf); 09993 ast_queue_frame(ch->ast, &fr); 09994 } else { 09995 chan_misdn_log(2, bc->port, " --> Ignoring DTMF:%c due to bridge flags\n", bc->dtmf); 09996 } 09997 break; 09998 } 09999 case EVENT_STATUS: 10000 break; 10001 10002 case EVENT_INFORMATION: 10003 if (ch->state != MISDN_CONNECTED) { 10004 stop_indicate(ch); 10005 } 10006 10007 if (!ch->ast) { 10008 break; 10009 } 10010 10011 if (ch->state == MISDN_WAITING4DIGS) { 10012 /* Ok, incomplete Setup, waiting till extension exists */ 10013 if (ast_strlen_zero(bc->info_dad) && ! ast_strlen_zero(bc->keypad)) { 10014 chan_misdn_log(1, bc->port, " --> using keypad as info\n"); 10015 ast_copy_string(bc->info_dad, bc->keypad, sizeof(bc->info_dad)); 10016 } 10017 10018 strncat(bc->dialed.number, bc->info_dad, sizeof(bc->dialed.number) - strlen(bc->dialed.number) - 1); 10019 ast_copy_string(ch->ast->exten, bc->dialed.number, sizeof(ch->ast->exten)); 10020 10021 /* Check for Pickup Request first */ 10022 if (!strcmp(ch->ast->exten, ast_pickup_ext())) { 10023 if (ast_pickup_call(ch->ast)) { 10024 hangup_chan(ch, bc); 10025 } else { 10026 ch->state = MISDN_CALLING_ACKNOWLEDGE; 10027 hangup_chan(ch, bc); 10028 ch->ast = NULL; 10029 break; 10030 } 10031 } 10032 10033 if (!ast_canmatch_extension(ch->ast, ch->context, bc->dialed.number, 1, bc->caller.number)) { 10034 if (ast_exists_extension(ch->ast, ch->context, "i", 1, bc->caller.number)) { 10035 ast_log(LOG_WARNING, 10036 "Extension '%s@%s' can never match. Jumping to 'i' extension. port:%d\n", 10037 bc->dialed.number, ch->context, bc->port); 10038 strcpy(ch->ast->exten, "i"); 10039 10040 ch->state = MISDN_DIALING; 10041 start_pbx(ch, bc, ch->ast); 10042 break; 10043 } 10044 10045 ast_log(LOG_WARNING, 10046 "Extension '%s@%s' can never match. Disconnecting. port:%d\n" 10047 "\tMaybe you want to add an 'i' extension to catch this case.\n", 10048 bc->dialed.number, ch->context, bc->port); 10049 10050 if (bc->nt) { 10051 hanguptone_indicate(ch); 10052 } 10053 ch->state = MISDN_EXTCANTMATCH; 10054 bc->out_cause = AST_CAUSE_UNALLOCATED; 10055 10056 misdn_lib_send_event(bc, EVENT_DISCONNECT); 10057 break; 10058 } 10059 10060 if (ch->overlap_dial) { 10061 ast_mutex_lock(&ch->overlap_tv_lock); 10062 ch->overlap_tv = ast_tvnow(); 10063 ast_mutex_unlock(&ch->overlap_tv_lock); 10064 if (ch->overlap_dial_task == -1) { 10065 ch->overlap_dial_task = 10066 misdn_tasks_add_variable(ch->overlap_dial, misdn_overlap_dial_task, ch); 10067 } 10068 break; 10069 } 10070 10071 if (ast_exists_extension(ch->ast, ch->context, bc->dialed.number, 1, bc->caller.number)) { 10072 ch->state = MISDN_DIALING; 10073 start_pbx(ch, bc, ch->ast); 10074 } 10075 } else { 10076 /* sending INFOS as DTMF-Frames :) */ 10077 struct ast_frame fr; 10078 int digits; 10079 10080 memset(&fr, 0, sizeof(fr)); 10081 fr.frametype = AST_FRAME_DTMF; 10082 fr.subclass.integer = bc->info_dad[0] ; 10083 fr.src = NULL; 10084 fr.data.ptr = NULL; 10085 fr.datalen = 0; 10086 fr.samples = 0; 10087 fr.mallocd = 0; 10088 fr.offset = 0; 10089 fr.delivery = ast_tv(0,0); 10090 10091 misdn_cfg_get(0, MISDN_GEN_APPEND_DIGITS2EXTEN, &digits, sizeof(digits)); 10092 if (ch->state != MISDN_CONNECTED) { 10093 if (digits) { 10094 strncat(bc->dialed.number, bc->info_dad, sizeof(bc->dialed.number) - strlen(bc->dialed.number) - 1); 10095 ast_copy_string(ch->ast->exten, bc->dialed.number, sizeof(ch->ast->exten)); 10096 ast_cdr_update(ch->ast); 10097 } 10098 10099 ast_queue_frame(ch->ast, &fr); 10100 } 10101 } 10102 break; 10103 case EVENT_SETUP: 10104 { 10105 struct ast_channel *chan; 10106 int exceed; 10107 int ai; 10108 int im; 10109 int append_msn = 0; 10110 10111 if (ch) { 10112 switch (ch->state) { 10113 case MISDN_NOTHING: 10114 chan_list_unref(ch, "Ignore found ch. Is it for an outgoing call?"); 10115 ch = NULL; 10116 break; 10117 default: 10118 chan_list_unref(ch, "Already have a call."); 10119 chan_misdn_log(1, bc->port, " --> Ignoring Call we have already one\n"); 10120 return RESPONSE_IGNORE_SETUP_WITHOUT_CLOSE; /* Ignore MSNs which are not in our List */ 10121 } 10122 } 10123 10124 if (!bc->nt && !misdn_is_msn_valid(bc->port, &bc->dialed)) { 10125 chan_misdn_log(1, bc->port, " --> Ignoring Call, its not in our MSN List\n"); 10126 return RESPONSE_IGNORE_SETUP; /* Ignore MSNs which are not in our List */ 10127 } 10128 10129 if (bc->cw) { 10130 int cause; 10131 chan_misdn_log(0, bc->port, " --> Call Waiting on PMP sending RELEASE_COMPLETE\n"); 10132 misdn_cfg_get(bc->port, MISDN_CFG_REJECT_CAUSE, &cause, sizeof(cause)); 10133 bc->out_cause = cause ? cause : AST_CAUSE_NORMAL_CLEARING; 10134 return RESPONSE_RELEASE_SETUP; 10135 } 10136 10137 print_bearer(bc); 10138 10139 ch = chan_list_init(ORG_MISDN); 10140 if (!ch) { 10141 chan_misdn_log(-1, bc->port, "cb_events: malloc for chan_list failed!\n"); 10142 return 0; 10143 } 10144 10145 ch->bc = bc; 10146 ch->l3id = bc->l3_id; 10147 ch->addr = bc->addr; 10148 10149 chan = misdn_new(ch, AST_STATE_RESERVED, bc->dialed.number, bc->caller.number, AST_FORMAT_ALAW, NULL, bc->port, bc->channel); 10150 if (!chan) { 10151 chan_list_unref(ch, "Failed to create a new channel"); 10152 misdn_lib_send_event(bc,EVENT_RELEASE_COMPLETE); 10153 ast_log(LOG_ERROR, "cb_events: misdn_new failed !\n"); 10154 return 0; 10155 } 10156 10157 if ((exceed = add_in_calls(bc->port))) { 10158 char tmp[16]; 10159 snprintf(tmp, sizeof(tmp), "%d", exceed); 10160 pbx_builtin_setvar_helper(chan, "MAX_OVERFLOW", tmp); 10161 } 10162 10163 read_config(ch); 10164 10165 export_ch(chan, bc, ch); 10166 10167 ch->ast->rings = 1; 10168 ast_setstate(ch->ast, AST_STATE_RINGING); 10169 10170 /* Update asterisk channel caller information */ 10171 chan_misdn_log(2, bc->port, " --> TON: %s(%d)\n", misdn_to_str_ton(bc->caller.number_type), bc->caller.number_type); 10172 chan_misdn_log(2, bc->port, " --> PLAN: %s(%d)\n", misdn_to_str_plan(bc->caller.number_plan), bc->caller.number_plan); 10173 chan->caller.id.number.plan = misdn_to_ast_ton(bc->caller.number_type) 10174 | misdn_to_ast_plan(bc->caller.number_plan); 10175 10176 chan_misdn_log(2, bc->port, " --> PRES: %s(%d)\n", misdn_to_str_pres(bc->caller.presentation), bc->caller.presentation); 10177 chan_misdn_log(2, bc->port, " --> SCREEN: %s(%d)\n", misdn_to_str_screen(bc->caller.screening), bc->caller.screening); 10178 chan->caller.id.number.presentation = misdn_to_ast_pres(bc->caller.presentation) 10179 | misdn_to_ast_screen(bc->caller.screening); 10180 10181 ast_set_callerid(chan, bc->caller.number, NULL, bc->caller.number); 10182 10183 misdn_cfg_get(bc->port, MISDN_CFG_APPEND_MSN_TO_CALLERID_TAG, &append_msn, sizeof(append_msn)); 10184 if (append_msn) { 10185 strncat(bc->incoming_cid_tag, "_", sizeof(bc->incoming_cid_tag) - strlen(bc->incoming_cid_tag) - 1); 10186 strncat(bc->incoming_cid_tag, bc->dialed.number, sizeof(bc->incoming_cid_tag) - strlen(bc->incoming_cid_tag) - 1); 10187 } 10188 10189 ast_channel_lock(chan); 10190 chan->caller.id.tag = ast_strdup(bc->incoming_cid_tag); 10191 ast_channel_unlock(chan); 10192 10193 if (!ast_strlen_zero(bc->redirecting.from.number)) { 10194 /* Add configured prefix to redirecting.from.number */ 10195 misdn_add_number_prefix(bc->port, bc->redirecting.from.number_type, bc->redirecting.from.number, sizeof(bc->redirecting.from.number)); 10196 10197 /* Update asterisk channel redirecting information */ 10198 misdn_copy_redirecting_to_ast(chan, &bc->redirecting, bc->incoming_cid_tag); 10199 } 10200 10201 pbx_builtin_setvar_helper(chan, "TRANSFERCAPABILITY", ast_transfercapability2str(bc->capability)); 10202 chan->transfercapability = bc->capability; 10203 10204 switch (bc->capability) { 10205 case INFO_CAPABILITY_DIGITAL_UNRESTRICTED: 10206 pbx_builtin_setvar_helper(chan, "CALLTYPE", "DIGITAL"); 10207 break; 10208 default: 10209 pbx_builtin_setvar_helper(chan, "CALLTYPE", "SPEECH"); 10210 break; 10211 } 10212 10213 /** queue new chan **/ 10214 cl_queue_chan(ch); 10215 10216 if (!strstr(ch->allowed_bearers, "all")) { 10217 int i; 10218 10219 for (i = 0; i < ARRAY_LEN(allowed_bearers_array); ++i) { 10220 if (allowed_bearers_array[i].cap == bc->capability) { 10221 if (strstr(ch->allowed_bearers, allowed_bearers_array[i].name)) { 10222 /* The bearer capability is allowed */ 10223 if (allowed_bearers_array[i].deprecated) { 10224 chan_misdn_log(0, bc->port, "%s in allowed_bearers list is deprecated\n", 10225 allowed_bearers_array[i].name); 10226 } 10227 break; 10228 } 10229 } 10230 } 10231 if (i == ARRAY_LEN(allowed_bearers_array)) { 10232 /* We did not find the bearer capability */ 10233 chan_misdn_log(0, bc->port, "Bearer capability not allowed: %s(%d)\n", 10234 bearer2str(bc->capability), bc->capability); 10235 bc->out_cause = AST_CAUSE_INCOMPATIBLE_DESTINATION; 10236 10237 ch->state = MISDN_EXTCANTMATCH; 10238 misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE); 10239 chan_list_unref(ch, "BC not allowed, releasing call"); 10240 return RESPONSE_OK; 10241 } 10242 } 10243 10244 if (bc->fac_in.Function != Fac_None) { 10245 misdn_facility_ie_handler(event, bc, ch); 10246 } 10247 10248 /* Check for Pickup Request first */ 10249 if (!strcmp(chan->exten, ast_pickup_ext())) { 10250 if (!ch->noautorespond_on_setup) { 10251 /* Sending SETUP_ACK */ 10252 misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE); 10253 } else { 10254 ch->state = MISDN_INCOMING_SETUP; 10255 } 10256 if (ast_pickup_call(chan)) { 10257 hangup_chan(ch, bc); 10258 } else { 10259 ch->state = MISDN_CALLING_ACKNOWLEDGE; 10260 hangup_chan(ch, bc); 10261 ch->ast = NULL; 10262 break; 10263 } 10264 } 10265 10266 /* 10267 * added support for s extension hope it will help those poor cretains 10268 * which haven't overlap dial. 10269 */ 10270 misdn_cfg_get(bc->port, MISDN_CFG_ALWAYS_IMMEDIATE, &ai, sizeof(ai)); 10271 if (ai) { 10272 do_immediate_setup(bc, ch, chan); 10273 break; 10274 } 10275 10276 /* check if we should jump into s when we have no dialed.number */ 10277 misdn_cfg_get(bc->port, MISDN_CFG_IMMEDIATE, &im, sizeof(im)); 10278 if (im && ast_strlen_zero(bc->dialed.number)) { 10279 do_immediate_setup(bc, ch, chan); 10280 break; 10281 } 10282 10283 chan_misdn_log(5, bc->port, "CONTEXT:%s\n", ch->context); 10284 if (!ast_canmatch_extension(ch->ast, ch->context, bc->dialed.number, 1, bc->caller.number)) { 10285 if (ast_exists_extension(ch->ast, ch->context, "i", 1, bc->caller.number)) { 10286 ast_log(LOG_WARNING, 10287 "Extension '%s@%s' can never match. Jumping to 'i' extension. port:%d\n", 10288 bc->dialed.number, ch->context, bc->port); 10289 strcpy(ch->ast->exten, "i"); 10290 misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE); 10291 ch->state = MISDN_DIALING; 10292 start_pbx(ch, bc, chan); 10293 break; 10294 } 10295 10296 ast_log(LOG_WARNING, 10297 "Extension '%s@%s' can never match. Disconnecting. port:%d\n" 10298 "\tMaybe you want to add an 'i' extension to catch this case.\n", 10299 bc->dialed.number, ch->context, bc->port); 10300 if (bc->nt) { 10301 hanguptone_indicate(ch); 10302 } 10303 10304 ch->state = MISDN_EXTCANTMATCH; 10305 bc->out_cause = AST_CAUSE_UNALLOCATED; 10306 10307 misdn_lib_send_event(bc, bc->nt ? EVENT_RELEASE_COMPLETE : EVENT_RELEASE); 10308 break; 10309 } 10310 10311 /* Whatever happens, when sending_complete is set or we are PTMP TE, we will definitely 10312 * jump into the dialplan, when the dialed extension does not exist, the 's' extension 10313 * will be used by Asterisk automatically. */ 10314 if (bc->sending_complete || (!bc->nt && !misdn_lib_is_ptp(bc->port))) { 10315 if (!ch->noautorespond_on_setup) { 10316 ch->state=MISDN_DIALING; 10317 misdn_lib_send_event(bc, EVENT_PROCEEDING); 10318 } else { 10319 ch->state = MISDN_INCOMING_SETUP; 10320 } 10321 start_pbx(ch, bc, chan); 10322 break; 10323 } 10324 10325 10326 /* 10327 * When we are NT and overlapdial is set and if 10328 * the number is empty, we wait for the ISDN timeout 10329 * instead of our own timer. 10330 */ 10331 if (ch->overlap_dial && bc->nt && !bc->dialed.number[0]) { 10332 wait_for_digits(ch, bc, chan); 10333 break; 10334 } 10335 10336 /* 10337 * If overlapdial we will definitely send a SETUP_ACKNOWLEDGE and wait for more 10338 * Infos with a Interdigit Timeout. 10339 * */ 10340 if (ch->overlap_dial) { 10341 ast_mutex_lock(&ch->overlap_tv_lock); 10342 ch->overlap_tv = ast_tvnow(); 10343 ast_mutex_unlock(&ch->overlap_tv_lock); 10344 10345 wait_for_digits(ch, bc, chan); 10346 if (ch->overlap_dial_task == -1) { 10347 ch->overlap_dial_task = 10348 misdn_tasks_add_variable(ch->overlap_dial, misdn_overlap_dial_task, ch); 10349 } 10350 break; 10351 } 10352 10353 /* If the extension does not exist and we're not TE_PTMP we wait for more digits 10354 * without interdigit timeout. 10355 * */ 10356 if (!ast_exists_extension(ch->ast, ch->context, bc->dialed.number, 1, bc->caller.number)) { 10357 wait_for_digits(ch, bc, chan); 10358 break; 10359 } 10360 10361 /* 10362 * If the extension exists let's just jump into it. 10363 * */ 10364 if (ast_exists_extension(ch->ast, ch->context, bc->dialed.number, 1, bc->caller.number)) { 10365 misdn_lib_send_event(bc, bc->need_more_infos ? EVENT_SETUP_ACKNOWLEDGE : EVENT_PROCEEDING); 10366 ch->state = MISDN_DIALING; 10367 start_pbx(ch, bc, chan); 10368 break; 10369 } 10370 break; 10371 } 10372 #if defined(AST_MISDN_ENHANCEMENTS) 10373 case EVENT_REGISTER: 10374 if (bc->fac_in.Function != Fac_None) { 10375 misdn_facility_ie_handler(event, bc, ch); 10376 } 10377 /* 10378 * Shut down this connection immediately. 10379 * The current design of chan_misdn data structures 10380 * does not allow the proper handling of inbound call records 10381 * without an assigned B channel. Therefore, we cannot 10382 * be the CCBS User-B party in a point-to-point setup. 10383 */ 10384 bc->fac_out.Function = Fac_None; 10385 bc->out_cause = AST_CAUSE_NORMAL_CLEARING; 10386 misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE); 10387 break; 10388 #endif /* defined(AST_MISDN_ENHANCEMENTS) */ 10389 case EVENT_SETUP_ACKNOWLEDGE: 10390 ch->state = MISDN_CALLING_ACKNOWLEDGE; 10391 10392 if (bc->channel) { 10393 update_name(ch->ast,bc->port,bc->channel); 10394 } 10395 10396 if (bc->fac_in.Function != Fac_None) { 10397 misdn_facility_ie_handler(event, bc, ch); 10398 } 10399 10400 if (!ast_strlen_zero(bc->infos_pending)) { 10401 /* TX Pending Infos */ 10402 strncat(bc->dialed.number, bc->infos_pending, sizeof(bc->dialed.number) - strlen(bc->dialed.number) - 1); 10403 10404 if (!ch->ast) { 10405 break; 10406 } 10407 ast_copy_string(ch->ast->exten, bc->dialed.number, sizeof(ch->ast->exten)); 10408 ast_copy_string(bc->info_dad, bc->infos_pending, sizeof(bc->info_dad)); 10409 ast_copy_string(bc->infos_pending, "", sizeof(bc->infos_pending)); 10410 10411 misdn_lib_send_event(bc, EVENT_INFORMATION); 10412 } 10413 break; 10414 case EVENT_PROCEEDING: 10415 if (misdn_cap_is_speech(bc->capability) && 10416 misdn_inband_avail(bc)) { 10417 start_bc_tones(ch); 10418 } 10419 10420 ch->state = MISDN_PROCEEDING; 10421 10422 if (bc->fac_in.Function != Fac_None) { 10423 misdn_facility_ie_handler(event, bc, ch); 10424 } 10425 10426 if (!ch->ast) { 10427 break; 10428 } 10429 10430 ast_queue_control(ch->ast, AST_CONTROL_PROCEEDING); 10431 break; 10432 case EVENT_PROGRESS: 10433 if (bc->channel) { 10434 update_name(ch->ast, bc->port, bc->channel); 10435 } 10436 10437 if (bc->fac_in.Function != Fac_None) { 10438 misdn_facility_ie_handler(event, bc, ch); 10439 } 10440 10441 if (!bc->nt) { 10442 if (misdn_cap_is_speech(bc->capability) && 10443 misdn_inband_avail(bc)) { 10444 start_bc_tones(ch); 10445 } 10446 10447 ch->state = MISDN_PROGRESS; 10448 10449 if (!ch->ast) { 10450 break; 10451 } 10452 ast_queue_control(ch->ast, AST_CONTROL_PROGRESS); 10453 } 10454 break; 10455 case EVENT_ALERTING: 10456 ch->state = MISDN_ALERTING; 10457 10458 if (!ch->ast) { 10459 break; 10460 } 10461 10462 if (bc->fac_in.Function != Fac_None) { 10463 misdn_facility_ie_handler(event, bc, ch); 10464 } 10465 10466 ast_queue_control(ch->ast, AST_CONTROL_RINGING); 10467 ast_setstate(ch->ast, AST_STATE_RINGING); 10468 10469 cb_log(7, bc->port, " --> Set State Ringing\n"); 10470 10471 if (misdn_cap_is_speech(bc->capability) && misdn_inband_avail(bc)) { 10472 cb_log(1, bc->port, "Starting Tones, we have inband Data\n"); 10473 start_bc_tones(ch); 10474 } else { 10475 cb_log(3, bc->port, " --> We have no inband Data, the other end must create ringing\n"); 10476 if (ch->far_alerting) { 10477 cb_log(1, bc->port, " --> The other end can not do ringing eh ?.. we must do all ourself.."); 10478 start_bc_tones(ch); 10479 /*tone_indicate(ch, TONE_FAR_ALERTING);*/ 10480 } 10481 } 10482 break; 10483 case EVENT_CONNECT: 10484 if (bc->fac_in.Function != Fac_None) { 10485 misdn_facility_ie_handler(event, bc, ch); 10486 } 10487 #if defined(AST_MISDN_ENHANCEMENTS) 10488 if (bc->div_leg_3_rx_wanted) { 10489 bc->div_leg_3_rx_wanted = 0; 10490 10491 if (ch->ast) { 10492 ch->ast->redirecting.to.number.presentation = 10493 AST_PRES_RESTRICTED | AST_PRES_USER_NUMBER_UNSCREENED; 10494 ast_channel_queue_redirecting_update(ch->ast, &ch->ast->redirecting, NULL); 10495 } 10496 } 10497 #endif /* defined(AST_MISDN_ENHANCEMENTS) */ 10498 10499 /* we answer when we've got our very new L3 ID from the NT stack */ 10500 misdn_lib_send_event(bc, EVENT_CONNECT_ACKNOWLEDGE); 10501 10502 if (!ch->ast) { 10503 break; 10504 } 10505 10506 stop_indicate(ch); 10507 10508 #if defined(AST_MISDN_ENHANCEMENTS) 10509 if (ch->record_id != -1) { 10510 /* 10511 * We will delete the associated call completion 10512 * record since we now have a completed call. 10513 * We will not wait/depend on the network to tell 10514 * us to delete it. 10515 */ 10516 AST_LIST_LOCK(&misdn_cc_records_db); 10517 cc_record = misdn_cc_find_by_id(ch->record_id); 10518 if (cc_record) { 10519 if (cc_record->ptp && cc_record->mode.ptp.bc) { 10520 /* Close the call-completion signaling link */ 10521 cc_record->mode.ptp.bc->fac_out.Function = Fac_None; 10522 cc_record->mode.ptp.bc->out_cause = AST_CAUSE_NORMAL_CLEARING; 10523 misdn_lib_send_event(cc_record->mode.ptp.bc, EVENT_RELEASE_COMPLETE); 10524 } 10525 misdn_cc_delete(cc_record); 10526 } 10527 AST_LIST_UNLOCK(&misdn_cc_records_db); 10528 ch->record_id = -1; 10529 if (ch->peer) { 10530 misdn_cc_set_peer_var(ch->peer, MISDN_CC_RECORD_ID, ""); 10531 10532 ao2_ref(ch->peer, -1); 10533 ch->peer = NULL; 10534 } 10535 } 10536 #endif /* defined(AST_MISDN_ENHANCEMENTS) */ 10537 10538 if (!ast_strlen_zero(bc->connected.number)) { 10539 /* Add configured prefix to connected.number */ 10540 misdn_add_number_prefix(bc->port, bc->connected.number_type, bc->connected.number, sizeof(bc->connected.number)); 10541 10542 /* Update the connected line information on the other channel */ 10543 misdn_update_remote_party(ch->ast, &bc->connected, AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER, bc->incoming_cid_tag); 10544 } 10545 10546 ch->l3id = bc->l3_id; 10547 ch->addr = bc->addr; 10548 10549 start_bc_tones(ch); 10550 10551 ch->state = MISDN_CONNECTED; 10552 10553 ast_queue_control(ch->ast, AST_CONTROL_ANSWER); 10554 break; 10555 case EVENT_CONNECT_ACKNOWLEDGE: 10556 ch->l3id = bc->l3_id; 10557 ch->addr = bc->addr; 10558 10559 start_bc_tones(ch); 10560 10561 ch->state = MISDN_CONNECTED; 10562 break; 10563 case EVENT_DISCONNECT: 10564 /* we might not have an ch->ast ptr here anymore */ 10565 if (ch) { 10566 if (bc->fac_in.Function != Fac_None) { 10567 misdn_facility_ie_handler(event, bc, ch); 10568 } 10569 10570 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); 10571 if (ch->originator == ORG_AST && !bc->nt && misdn_inband_avail(bc) && ch->state != MISDN_CONNECTED) { 10572 /* If there's inband information available (e.g. a 10573 recorded message saying what was wrong with the 10574 dialled number, or perhaps even giving an 10575 alternative number, then play it instead of 10576 immediately releasing the call */ 10577 chan_misdn_log(1, bc->port, " --> Inband Info Avail, not sending RELEASE\n"); 10578 10579 ch->state = MISDN_DISCONNECTED; 10580 start_bc_tones(ch); 10581 10582 if (ch->ast) { 10583 ch->ast->hangupcause = bc->cause; 10584 if (bc->cause == AST_CAUSE_USER_BUSY) { 10585 ast_queue_control(ch->ast, AST_CONTROL_BUSY); 10586 } 10587 } 10588 ch->need_busy = 0; 10589 break; 10590 } 10591 10592 bc->need_disconnect = 0; 10593 stop_bc_tones(ch); 10594 10595 /* Check for held channel, to implement transfer */ 10596 held_ch = find_hold_call(bc); 10597 if (!held_ch || !ch->ast || misdn_attempt_transfer(ch, held_ch)) { 10598 hangup_chan(ch, bc); 10599 } 10600 } else { 10601 held_ch = find_hold_call_l3(bc->l3_id); 10602 if (held_ch) { 10603 if (bc->fac_in.Function != Fac_None) { 10604 misdn_facility_ie_handler(event, bc, held_ch); 10605 } 10606 10607 if (held_ch->hold.state == MISDN_HOLD_ACTIVE) { 10608 bc->need_disconnect = 0; 10609 10610 #if defined(TRANSFER_ON_HELD_CALL_HANGUP) 10611 /* 10612 * Some phones disconnect the held call and the active call at the 10613 * same time to do the transfer. Unfortunately, either call could 10614 * be disconnected first. 10615 */ 10616 ch = find_hold_active_call(bc); 10617 if (!ch || misdn_attempt_transfer(ch, held_ch)) { 10618 held_ch->hold.state = MISDN_HOLD_DISCONNECT; 10619 hangup_chan(held_ch, bc); 10620 } 10621 #else 10622 hangup_chan(held_ch, bc); 10623 #endif /* defined(TRANSFER_ON_HELD_CALL_HANGUP) */ 10624 } 10625 } 10626 } 10627 if (held_ch) { 10628 chan_list_unref(held_ch, "Done with held call"); 10629 } 10630 bc->out_cause = -1; 10631 if (bc->need_release) { 10632 misdn_lib_send_event(bc, EVENT_RELEASE); 10633 } 10634 break; 10635 case EVENT_RELEASE: 10636 if (!ch) { 10637 ch = find_hold_call_l3(bc->l3_id); 10638 if (!ch) { 10639 chan_misdn_log(1, bc->port, 10640 " --> no Ch, so we've already released. (%s)\n", 10641 manager_isdn_get_info(event)); 10642 return -1; 10643 } 10644 } 10645 if (bc->fac_in.Function != Fac_None) { 10646 misdn_facility_ie_handler(event, bc, ch); 10647 } 10648 10649 bc->need_disconnect = 0; 10650 bc->need_release = 0; 10651 10652 hangup_chan(ch, bc); 10653 release_chan(ch, bc); 10654 break; 10655 case EVENT_RELEASE_COMPLETE: 10656 if (!ch) { 10657 ch = find_hold_call_l3(bc->l3_id); 10658 } 10659 10660 bc->need_disconnect = 0; 10661 bc->need_release = 0; 10662 bc->need_release_complete = 0; 10663 10664 if (ch) { 10665 if (bc->fac_in.Function != Fac_None) { 10666 misdn_facility_ie_handler(event, bc, ch); 10667 } 10668 10669 stop_bc_tones(ch); 10670 hangup_chan(ch, bc); 10671 release_chan(ch, bc); 10672 } else { 10673 #if defined(AST_MISDN_ENHANCEMENTS) 10674 /* 10675 * A call-completion signaling link established with 10676 * REGISTER does not have a struct chan_list record 10677 * associated with it. 10678 */ 10679 AST_LIST_LOCK(&misdn_cc_records_db); 10680 cc_record = misdn_cc_find_by_bc(bc); 10681 if (cc_record) { 10682 /* The call-completion signaling link is closed. */ 10683 misdn_cc_delete(cc_record); 10684 } 10685 AST_LIST_UNLOCK(&misdn_cc_records_db); 10686 #endif /* defined(AST_MISDN_ENHANCEMENTS) */ 10687 10688 chan_misdn_log(1, bc->port, 10689 " --> no Ch, so we've already released. (%s)\n", 10690 manager_isdn_get_info(event)); 10691 } 10692 break; 10693 case EVENT_BCHAN_ERROR: 10694 case EVENT_CLEANUP: 10695 stop_bc_tones(ch); 10696 10697 switch (ch->state) { 10698 case MISDN_CALLING: 10699 bc->cause = AST_CAUSE_DESTINATION_OUT_OF_ORDER; 10700 break; 10701 default: 10702 break; 10703 } 10704 10705 hangup_chan(ch, bc); 10706 release_chan(ch, bc); 10707 break; 10708 case EVENT_TONE_GENERATE: 10709 { 10710 int tone_len = bc->tone_cnt; 10711 struct ast_channel *ast = ch->ast; 10712 void *tmp; 10713 int res; 10714 int (*generate)(struct ast_channel *chan, void *tmp, int datalen, int samples); 10715 10716 chan_misdn_log(9, bc->port, "TONE_GEN: len:%d\n", tone_len); 10717 10718 if (!ast) { 10719 break; 10720 } 10721 10722 if (!ast->generator) { 10723 break; 10724 } 10725 10726 tmp = ast->generatordata; 10727 ast->generatordata = NULL; 10728 generate = ast->generator->generate; 10729 10730 if (tone_len < 0 || tone_len > 512) { 10731 ast_log(LOG_NOTICE, "TONE_GEN: len was %d, set to 128\n", tone_len); 10732 tone_len = 128; 10733 } 10734 10735 res = generate(ast, tmp, tone_len, tone_len); 10736 ast->generatordata = tmp; 10737 10738 if (res) { 10739 ast_log(LOG_WARNING, "Auto-deactivating generator\n"); 10740 ast_deactivate_generator(ast); 10741 } else { 10742 bc->tone_cnt = 0; 10743 } 10744 break; 10745 } 10746 case EVENT_BCHAN_DATA: 10747 if (ch->bc->AOCD_need_export) { 10748 export_aoc_vars(ch->originator, ch->ast, ch->bc); 10749 } 10750 if (!misdn_cap_is_speech(ch->bc->capability)) { 10751 struct ast_frame frame; 10752 10753 /* In Data Modes we queue frames */ 10754 memset(&frame, 0, sizeof(frame)); 10755 frame.frametype = AST_FRAME_VOICE; /* we have no data frames yet */ 10756 frame.subclass.codec = AST_FORMAT_ALAW; 10757 frame.datalen = bc->bframe_len; 10758 frame.samples = bc->bframe_len; 10759 frame.mallocd = 0; 10760 frame.offset = 0; 10761 frame.delivery = ast_tv(0, 0); 10762 frame.src = NULL; 10763 frame.data.ptr = bc->bframe; 10764 10765 if (ch->ast) { 10766 ast_queue_frame(ch->ast, &frame); 10767 } 10768 } else { 10769 struct pollfd pfd = { .fd = ch->pipe[1], .events = POLLOUT }; 10770 int t; 10771 10772 t = ast_poll(&pfd, 1, 0); 10773 10774 if (t < 0) { 10775 chan_misdn_log(-1, bc->port, "poll() error (err=%s)\n", strerror(errno)); 10776 break; 10777 } 10778 if (!t) { 10779 chan_misdn_log(9, bc->port, "poll() timed out\n"); 10780 break; 10781 } 10782 10783 if (pfd.revents & POLLOUT) { 10784 chan_misdn_log(9, bc->port, "writing %d bytes to asterisk\n", bc->bframe_len); 10785 if (write(ch->pipe[1], bc->bframe, bc->bframe_len) <= 0) { 10786 chan_misdn_log(0, bc->port, "Write returned <=0 (err=%s) --> hanging up channel\n", strerror(errno)); 10787 10788 stop_bc_tones(ch); 10789 hangup_chan(ch, bc); 10790 release_chan(ch, bc); 10791 } 10792 } else { 10793 chan_misdn_log(1, bc->port, "Write Pipe full!\n"); 10794 } 10795 } 10796 break; 10797 case EVENT_TIMEOUT: 10798 if (ch && bc) { 10799 chan_misdn_log(1, bc->port, "--> state: %s\n", misdn_get_ch_state(ch)); 10800 } 10801 10802 switch (ch->state) { 10803 case MISDN_DIALING: 10804 case MISDN_PROGRESS: 10805 if (bc->nt && !ch->nttimeout) { 10806 break; 10807 } 10808 /* fall-through */ 10809 case MISDN_CALLING: 10810 case MISDN_ALERTING: 10811 case MISDN_PROCEEDING: 10812 case MISDN_CALLING_ACKNOWLEDGE: 10813 if (bc->nt) { 10814 bc->progress_indicator = INFO_PI_INBAND_AVAILABLE; 10815 hanguptone_indicate(ch); 10816 } 10817 10818 bc->out_cause = AST_CAUSE_UNALLOCATED; 10819 misdn_lib_send_event(bc, EVENT_DISCONNECT); 10820 break; 10821 case MISDN_WAITING4DIGS: 10822 if (bc->nt) { 10823 bc->progress_indicator = INFO_PI_INBAND_AVAILABLE; 10824 bc->out_cause = AST_CAUSE_UNALLOCATED; 10825 hanguptone_indicate(ch); 10826 misdn_lib_send_event(bc, EVENT_DISCONNECT); 10827 } else { 10828 bc->out_cause = AST_CAUSE_NORMAL_CLEARING; 10829 misdn_lib_send_event(bc, EVENT_RELEASE); 10830 } 10831 break; 10832 case MISDN_CLEANING: 10833 chan_misdn_log(1, bc->port, " --> in state cleaning .. so ignoring, the stack should clean it for us\n"); 10834 break; 10835 default: 10836 misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE); 10837 break; 10838 } 10839 break; 10840 10841 /****************************/ 10842 /** Supplementary Services **/ 10843 /****************************/ 10844 case EVENT_RETRIEVE: 10845 if (!ch) { 10846 chan_misdn_log(4, bc->port, " --> no CH, searching for held call\n"); 10847 ch = find_hold_call_l3(bc->l3_id); 10848 if (!ch || ch->hold.state != MISDN_HOLD_ACTIVE) { 10849 ast_log(LOG_WARNING, "No held call found, cannot Retrieve\n"); 10850 misdn_lib_send_event(bc, EVENT_RETRIEVE_REJECT); 10851 break; 10852 } 10853 } 10854 10855 /* remember the channel again */ 10856 ch->bc = bc; 10857 10858 ch->hold.state = MISDN_HOLD_IDLE; 10859 ch->hold.port = 0; 10860 ch->hold.channel = 0; 10861 10862 ast_queue_control(ch->ast, AST_CONTROL_UNHOLD); 10863 10864 if (misdn_lib_send_event(bc, EVENT_RETRIEVE_ACKNOWLEDGE) < 0) { 10865 chan_misdn_log(4, bc->port, " --> RETRIEVE_ACK failed\n"); 10866 misdn_lib_send_event(bc, EVENT_RETRIEVE_REJECT); 10867 } 10868 break; 10869 case EVENT_HOLD: 10870 { 10871 int hold_allowed; 10872 struct ast_channel *bridged; 10873 10874 misdn_cfg_get(bc->port, MISDN_CFG_HOLD_ALLOWED, &hold_allowed, sizeof(hold_allowed)); 10875 if (!hold_allowed) { 10876 chan_misdn_log(-1, bc->port, "Hold not allowed this port.\n"); 10877 misdn_lib_send_event(bc, EVENT_HOLD_REJECT); 10878 break; 10879 } 10880 10881 bridged = ast_bridged_channel(ch->ast); 10882 if (bridged) { 10883 chan_misdn_log(2, bc->port, "Bridge Partner is of type: %s\n", bridged->tech->type); 10884 ch->l3id = bc->l3_id; 10885 10886 /* forget the channel now */ 10887 ch->bc = NULL; 10888 ch->hold.state = MISDN_HOLD_ACTIVE; 10889 ch->hold.port = bc->port; 10890 ch->hold.channel = bc->channel; 10891 10892 ast_queue_control(ch->ast, AST_CONTROL_HOLD); 10893 10894 misdn_lib_send_event(bc, EVENT_HOLD_ACKNOWLEDGE); 10895 } else { 10896 misdn_lib_send_event(bc, EVENT_HOLD_REJECT); 10897 chan_misdn_log(0, bc->port, "We aren't bridged to anybody\n"); 10898 } 10899 break; 10900 } 10901 case EVENT_NOTIFY: 10902 if (bc->redirecting.to_changed) { 10903 /* Add configured prefix to redirecting.to.number */ 10904 misdn_add_number_prefix(bc->port, bc->redirecting.to.number_type, 10905 bc->redirecting.to.number, sizeof(bc->redirecting.to.number)); 10906 } 10907 switch (bc->notify_description_code) { 10908 case mISDN_NOTIFY_CODE_DIVERSION_ACTIVATED: 10909 /* Ignore for now. */ 10910 bc->redirecting.to_changed = 0; 10911 break; 10912 case mISDN_NOTIFY_CODE_CALL_IS_DIVERTING: 10913 if (!bc->redirecting.to_changed) { 10914 break; 10915 } 10916 bc->redirecting.to_changed = 0; 10917 if (!ch || !ch->ast) { 10918 break; 10919 } 10920 switch (ch->state) { 10921 case MISDN_ALERTING: 10922 /* Call is deflecting after we have seen an ALERTING message */ 10923 bc->redirecting.reason = mISDN_REDIRECTING_REASON_NO_REPLY; 10924 break; 10925 default: 10926 /* Call is deflecting for call forwarding unconditional or busy reason. */ 10927 bc->redirecting.reason = mISDN_REDIRECTING_REASON_UNKNOWN; 10928 break; 10929 } 10930 misdn_copy_redirecting_to_ast(ch->ast, &bc->redirecting, bc->incoming_cid_tag); 10931 ast_channel_queue_redirecting_update(ch->ast, &ch->ast->redirecting, NULL); 10932 break; 10933 case mISDN_NOTIFY_CODE_CALL_TRANSFER_ALERTING: 10934 /* 10935 * It would be preferable to update the connected line information 10936 * only when the message callStatus is active. However, the 10937 * optional redirection number may not be present in the active 10938 * message if an alerting message were received earlier. 10939 * 10940 * The consequences if we wind up sending two updates is benign. 10941 * The other end will think that it got transferred twice. 10942 */ 10943 if (!bc->redirecting.to_changed) { 10944 break; 10945 } 10946 bc->redirecting.to_changed = 0; 10947 if (!ch || !ch->ast) { 10948 break; 10949 } 10950 misdn_update_remote_party(ch->ast, &bc->redirecting.to, 10951 AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER_ALERTING, 10952 bc->incoming_cid_tag); 10953 break; 10954 case mISDN_NOTIFY_CODE_CALL_TRANSFER_ACTIVE: 10955 if (!bc->redirecting.to_changed) { 10956 break; 10957 } 10958 bc->redirecting.to_changed = 0; 10959 if (!ch || !ch->ast) { 10960 break; 10961 } 10962 misdn_update_remote_party(ch->ast, &bc->redirecting.to, 10963 AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER, bc->incoming_cid_tag); 10964 break; 10965 default: 10966 bc->redirecting.to_changed = 0; 10967 chan_misdn_log(0, bc->port," --> not yet handled: notify code:0x%02X\n", 10968 bc->notify_description_code); 10969 break; 10970 } 10971 bc->notify_description_code = mISDN_NOTIFY_CODE_INVALID; 10972 break; 10973 case EVENT_FACILITY: 10974 if (bc->fac_in.Function == Fac_None) { 10975 /* This is a FACILITY message so we MUST have a facility ie */ 10976 chan_misdn_log(0, bc->port," --> Missing facility ie or unknown facility ie contents.\n"); 10977 } else { 10978 misdn_facility_ie_handler(event, bc, ch); 10979 } 10980 10981 /* In case it came in on a FACILITY message and we did not handle it. */ 10982 bc->redirecting.to_changed = 0; 10983 bc->notify_description_code = mISDN_NOTIFY_CODE_INVALID; 10984 break; 10985 case EVENT_RESTART: 10986 if (!bc->dummy) { 10987 stop_bc_tones(ch); 10988 release_chan(ch, bc); 10989 } 10990 break; 10991 default: 10992 chan_misdn_log(1, 0, "Got Unknown Event\n"); 10993 break; 10994 } 10995 10996 if (ch) { 10997 chan_list_unref(ch, "cb_event complete OK"); 10998 } 10999 return RESPONSE_OK; 11000 }
static void chan_list_destructor | ( | void * | obj | ) | [static] |
Definition at line 7710 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().
07711 { 07712 struct chan_list *ch = obj; 07713 07714 #if defined(AST_MISDN_ENHANCEMENTS) 07715 if (ch->peer) { 07716 ao2_ref(ch->peer, -1); 07717 ch->peer = NULL; 07718 } 07719 #endif /* AST_MISDN_ENHANCEMENTS */ 07720 07721 if (ch->dsp) { 07722 ast_dsp_free(ch->dsp); 07723 ch->dsp = NULL; 07724 } 07725 07726 /* releasing jitterbuffer */ 07727 if (ch->jb) { 07728 misdn_jb_destroy(ch->jb); 07729 ch->jb = NULL; 07730 } 07731 07732 if (ch->overlap_dial) { 07733 if (ch->overlap_dial_task != -1) { 07734 misdn_tasks_remove(ch->overlap_dial_task); 07735 ch->overlap_dial_task = -1; 07736 } 07737 ast_mutex_destroy(&ch->overlap_tv_lock); 07738 } 07739 07740 if (-1 < ch->pipe[0]) { 07741 close(ch->pipe[0]); 07742 } 07743 if (-1 < ch->pipe[1]) { 07744 close(ch->pipe[1]); 07745 } 07746 }
static struct chan_list* chan_list_init | ( | int | orig | ) | [static] |
Returns a reference to the new chan_list.
Definition at line 7749 of file chan_misdn.c.
References ao2_alloc, chan_list_destructor(), and chan_misdn_log().
Referenced by cb_events().
07750 { 07751 struct chan_list *cl; 07752 07753 cl = ao2_alloc(sizeof(*cl), chan_list_destructor); 07754 if (!cl) { 07755 chan_misdn_log(-1, 0, "misdn_request: malloc failed!"); 07756 return NULL; 07757 } 07758 07759 cl->originator = orig; 07760 cl->need_queue_hangup = 1; 07761 cl->need_hangup = 1; 07762 cl->need_busy = 1; 07763 cl->overlap_dial_task = -1; 07764 #if defined(AST_MISDN_ENHANCEMENTS) 07765 cl->record_id = -1; 07766 #endif /* defined(AST_MISDN_ENHANCEMENTS) */ 07767 cl->pipe[0] = -1; 07768 cl->pipe[1] = -1; 07769 07770 return cl; 07771 }
int chan_misdn_jb_empty | ( | struct misdn_bchannel * | bc, | |
char * | buf, | |||
int | len | |||
) |
Definition at line 12435 of file chan_misdn.c.
References chan_list::bc, chan_list_unref, find_chan_by_bc(), chan_list::jb, and misdn_jb_empty().
Referenced by load_module().
12436 { 12437 struct chan_list *ch; 12438 int res; 12439 12440 ch = find_chan_by_bc(bc); 12441 if (!ch) { 12442 return 0; 12443 } 12444 12445 if (ch->jb) { 12446 res = misdn_jb_empty(ch->jb, buf, len); 12447 } else { 12448 res = 0; 12449 } 12450 chan_list_unref(ch, "Done emptying jb"); 12451 12452 return res; 12453 }
static void chan_misdn_log | ( | int | level, | |
int | port, | |||
char * | tmpl, | |||
... | ||||
) | [static] |
Definition at line 12629 of file chan_misdn.c.
References ast_console_puts(), ast_log(), ast_strlen_zero(), errno, LOG_WARNING, max_ports, misdn_debug, and misdn_debug_only.
Referenced by cb_events(), chan_list_init(), cl_queue_chan(), config_jitterbuffer(), debug_numtype(), dialtone_indicate(), do_immediate_setup(), export_ch(), find_hold_call(), load_module(), misdn_answer(), misdn_attempt_transfer(), misdn_bridge(), misdn_call(), misdn_check_l2l1(), misdn_digit_end(), misdn_facility_exec(), misdn_facility_ie_handler(), misdn_fixup(), misdn_hangup(), misdn_indication(), misdn_jb_empty(), misdn_jb_init(), misdn_l1_task(), misdn_new(), misdn_overlap_dial_task(), misdn_read(), misdn_request(), misdn_set_opt_exec(), misdn_tasks_destroy(), misdn_tasks_init(), misdn_tasks_thread_func(), misdn_write(), print_bearer(), print_facility(), process_ast_dsp(), read_config(), release_chan(), send_cause2ast(), start_pbx(), stop_indicate(), update_config(), and update_name().
12630 { 12631 va_list ap; 12632 char buf[1024]; 12633 char port_buf[8]; 12634 12635 if (!(0 <= port && port <= max_ports)) { 12636 ast_log(LOG_WARNING, "cb_log called with out-of-range port number! (%d)\n", port); 12637 port = 0; 12638 level = -1; 12639 } else if (!(level == -1 12640 || (misdn_debug_only[port] 12641 ? (level == 1 && misdn_debug[port]) || level == misdn_debug[port] 12642 : level <= misdn_debug[port]) 12643 || (level <= misdn_debug[0] && !ast_strlen_zero(global_tracefile)))) { 12644 /* 12645 * We are not going to print anything so lets not 12646 * go to all the work of generating a string. 12647 */ 12648 return; 12649 } 12650 12651 snprintf(port_buf, sizeof(port_buf), "P[%2d] ", port); 12652 va_start(ap, tmpl); 12653 vsnprintf(buf, sizeof(buf), tmpl, ap); 12654 va_end(ap); 12655 12656 if (level == -1) { 12657 ast_log(LOG_WARNING, "%s", buf); 12658 } else if (misdn_debug_only[port] 12659 ? (level == 1 && misdn_debug[port]) || level == misdn_debug[port] 12660 : level <= misdn_debug[port]) { 12661 ast_console_puts(port_buf); 12662 ast_console_puts(buf); 12663 } 12664 12665 if (level <= misdn_debug[0] && !ast_strlen_zero(global_tracefile)) { 12666 char ctimebuf[30]; 12667 time_t tm; 12668 char *tmp; 12669 char *p; 12670 FILE *fp; 12671 12672 fp = fopen(global_tracefile, "a+"); 12673 if (!fp) { 12674 ast_console_puts("Error opening Tracefile: [ "); 12675 ast_console_puts(global_tracefile); 12676 ast_console_puts(" ] "); 12677 12678 ast_console_puts(strerror(errno)); 12679 ast_console_puts("\n"); 12680 return; 12681 } 12682 12683 tm = time(NULL); 12684 tmp = ctime_r(&tm, ctimebuf); 12685 p = strchr(tmp, '\n'); 12686 if (p) { 12687 *p = ':'; 12688 } 12689 fputs(tmp, fp); 12690 fputs(" ", fp); 12691 fputs(port_buf, fp); 12692 fputs(" ", fp); 12693 fputs(buf, fp); 12694 12695 fclose(fp); 12696 } 12697 }
static int cl_dequeue_chan | ( | struct chan_list * | chan | ) | [static] |
Definition at line 8326 of file chan_misdn.c.
References ast_mutex_lock, ast_mutex_unlock, chan_list_unref, cl_te, cl_te_lock, and chan_list::next.
Referenced by release_chan(), and release_chan_early().
08327 { 08328 int found_it; 08329 struct chan_list *help; 08330 08331 ast_mutex_lock(&cl_te_lock); 08332 if (!cl_te) { 08333 /* List is empty. */ 08334 ast_mutex_unlock(&cl_te_lock); 08335 return 0; 08336 } 08337 08338 if (cl_te == chan) { 08339 /* What we want is the head of the list. */ 08340 cl_te = cl_te->next; 08341 ast_mutex_unlock(&cl_te_lock); 08342 chan_list_unref(chan, "Removed chan_list from list head"); 08343 return 1; 08344 } 08345 08346 found_it = 0; 08347 for (help = cl_te; help->next; help = help->next) { 08348 if (help->next == chan) { 08349 /* Found it in the list. */ 08350 help->next = help->next->next; 08351 found_it = 1; 08352 break; 08353 } 08354 } 08355 08356 ast_mutex_unlock(&cl_te_lock); 08357 if (found_it) { 08358 chan_list_unref(chan, "Removed chan_list from list"); 08359 } 08360 return found_it; 08361 }
static void cl_queue_chan | ( | struct chan_list * | chan | ) | [static] |
Definition at line 8305 of file chan_misdn.c.
References ast_mutex_lock, ast_mutex_unlock, chan_list::bc, chan_list_ref, chan_misdn_log(), cl_te, cl_te_lock, chan_list::next, and misdn_bchannel::port.
Referenced by cb_events().
08306 { 08307 chan_misdn_log(4, chan->bc ? chan->bc->port : 0, "* Queuing chan %p\n", chan); 08308 08309 chan_list_ref(chan, "Adding chan_list to list"); 08310 ast_mutex_lock(&cl_te_lock); 08311 chan->next = NULL; 08312 if (!cl_te) { 08313 /* List is empty, make head of list. */ 08314 cl_te = chan; 08315 } else { 08316 struct chan_list *help; 08317 08318 /* Put at end of list. */ 08319 for (help = cl_te; help->next; help = help->next) { 08320 } 08321 help->next = chan; 08322 } 08323 ast_mutex_unlock(&cl_te_lock); 08324 }
static char * complete_ch | ( | struct ast_cli_args * | a | ) | [static] |
Definition at line 5624 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().
05625 { 05626 return ast_complete_channels(a->line, a->word, a->pos, a->n, 3); 05627 }
static char * complete_debug_port | ( | struct ast_cli_args * | a | ) | [static] |
Definition at line 5629 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().
05630 { 05631 if (a->n) { 05632 return NULL; 05633 } 05634 05635 switch (a->pos) { 05636 case 4: 05637 if (a->word[0] == 'p') { 05638 return ast_strdup("port"); 05639 } else if (a->word[0] == 'o') { 05640 return ast_strdup("only"); 05641 } 05642 break; 05643 case 6: 05644 if (a->word[0] == 'o') { 05645 return ast_strdup("only"); 05646 } 05647 break; 05648 } 05649 return NULL; 05650 }
static char * complete_show_config | ( | struct ast_cli_args * | a | ) | [static] |
Definition at line 5652 of file chan_misdn.c.
References ast_strdup, BUFFERSIZE, ast_cli_args::line, MISDN_CFG_FIRST, misdn_cfg_get_name(), misdn_cfg_get_next_port(), MISDN_GEN_FIRST, ast_cli_args::n, ast_cli_args::pos, and ast_cli_args::word.
Referenced by handle_cli_misdn_show_config().
05653 { 05654 char buffer[BUFFERSIZE]; 05655 enum misdn_cfg_elements elem; 05656 int wordlen = strlen(a->word); 05657 int which = 0; 05658 int port = 0; 05659 05660 switch (a->pos) { 05661 case 3: 05662 if ((!strncmp(a->word, "description", wordlen)) && (++which > a->n)) { 05663 return ast_strdup("description"); 05664 } 05665 if ((!strncmp(a->word, "descriptions", wordlen)) && (++which > a->n)) { 05666 return ast_strdup("descriptions"); 05667 } 05668 if ((!strncmp(a->word, "0", wordlen)) && (++which > a->n)) { 05669 return ast_strdup("0"); 05670 } 05671 while ((port = misdn_cfg_get_next_port(port)) != -1) { 05672 snprintf(buffer, sizeof(buffer), "%d", port); 05673 if ((!strncmp(a->word, buffer, wordlen)) && (++which > a->n)) { 05674 return ast_strdup(buffer); 05675 } 05676 } 05677 break; 05678 case 4: 05679 if (strstr(a->line, "description ")) { 05680 for (elem = MISDN_CFG_FIRST + 1; elem < MISDN_GEN_LAST; ++elem) { 05681 if ((elem == MISDN_CFG_LAST) || (elem == MISDN_GEN_FIRST)) { 05682 continue; 05683 } 05684 misdn_cfg_get_name(elem, buffer, sizeof(buffer)); 05685 if (!wordlen || !strncmp(a->word, buffer, wordlen)) { 05686 if (++which > a->n) { 05687 return ast_strdup(buffer); 05688 } 05689 } 05690 } 05691 } else if (strstr(a->line, "descriptions ")) { 05692 if ((!wordlen || !strncmp(a->word, "general", wordlen)) && (++which > a->n)) { 05693 return ast_strdup("general"); 05694 } 05695 if ((!wordlen || !strncmp(a->word, "ports", wordlen)) && (++which > a->n)) { 05696 return ast_strdup("ports"); 05697 } 05698 } 05699 break; 05700 } 05701 return NULL; 05702 }
static void config_jitterbuffer | ( | struct chan_list * | ch | ) | [static] |
Definition at line 5787 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().
05788 { 05789 struct misdn_bchannel *bc = ch->bc; 05790 int len = ch->jb_len; 05791 int threshold = ch->jb_upper_threshold; 05792 05793 chan_misdn_log(5, bc->port, "config_jb: Called\n"); 05794 05795 if (!len) { 05796 chan_misdn_log(1, bc->port, "config_jb: Deactivating Jitterbuffer\n"); 05797 bc->nojitter = 1; 05798 } else { 05799 if (len <= 100 || len > 8000) { 05800 chan_misdn_log(0, bc->port, "config_jb: Jitterbuffer out of Bounds, setting to 1000\n"); 05801 len = 1000; 05802 } 05803 05804 if (threshold > len) { 05805 chan_misdn_log(0, bc->port, "config_jb: Jitterbuffer Threshold > Jitterbuffer setting to Jitterbuffer -1\n"); 05806 } 05807 05808 if (ch->jb) { 05809 cb_log(0, bc->port, "config_jb: We've got a Jitterbuffer Already on this port.\n"); 05810 misdn_jb_destroy(ch->jb); 05811 ch->jb = NULL; 05812 } 05813 05814 ch->jb = misdn_jb_init(len, threshold); 05815 05816 if (!ch->jb) { 05817 bc->nojitter = 1; 05818 } 05819 } 05820 }
void debug_numtype | ( | int | port, | |
int | numtype, | |||
char * | type | |||
) |
Definition at line 5823 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().
05824 { 05825 switch (numtype) { 05826 case NUMTYPE_UNKNOWN: 05827 chan_misdn_log(2, port, " --> %s: Unknown\n", type); 05828 break; 05829 case NUMTYPE_INTERNATIONAL: 05830 chan_misdn_log(2, port, " --> %s: International\n", type); 05831 break; 05832 case NUMTYPE_NATIONAL: 05833 chan_misdn_log(2, port, " --> %s: National\n", type); 05834 break; 05835 case NUMTYPE_NETWORK_SPECIFIC: 05836 chan_misdn_log(2, port, " --> %s: Network Specific\n", type); 05837 break; 05838 case NUMTYPE_SUBSCRIBER: 05839 chan_misdn_log(2, port, " --> %s: Subscriber\n", type); 05840 break; 05841 case NUMTYPE_ABBREVIATED: 05842 chan_misdn_log(2, port, " --> %s: Abbreviated\n", type); 05843 break; 05844 /* Maybe we should cut off the prefix if present ? */ 05845 default: 05846 chan_misdn_log(0, port, " --> !!!! Wrong dialplan setting, please see the misdn.conf sample file\n "); 05847 break; 05848 } 05849 }
static int dialtone_indicate | ( | struct chan_list * | cl | ) | [static] |
AST INDICATIONS END
Definition at line 7625 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().
07626 { 07627 struct ast_channel *ast = cl->ast; 07628 int nd = 0; 07629 07630 if (!ast) { 07631 chan_misdn_log(0, cl->bc->port, "No Ast in dialtone_indicate\n"); 07632 return -1; 07633 } 07634 07635 misdn_cfg_get(cl->bc->port, MISDN_CFG_NODIALTONE, &nd, sizeof(nd)); 07636 07637 if (nd) { 07638 chan_misdn_log(1, cl->bc->port, "Not sending Dialtone, because config wants it\n"); 07639 return 0; 07640 } 07641 07642 chan_misdn_log(3, cl->bc->port, " --> Dial\n"); 07643 07644 cl->ts = ast_get_indication_tone(ast->zone, "dial"); 07645 07646 if (cl->ts) { 07647 cl->notxtone = 0; 07648 cl->norxtone = 0; 07649 /* This prods us in misdn_write */ 07650 ast_playtones_start(ast, 0, cl->ts->data, 0); 07651 } 07652 07653 return 0; 07654 }
static void do_immediate_setup | ( | struct misdn_bchannel * | bc, | |
struct chan_list * | ch, | |||
struct ast_channel * | ast | |||
) | [static] |
Definition at line 8619 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().
08620 { 08621 char *predial; 08622 struct ast_frame fr; 08623 08624 predial = ast_strdupa(ast->exten); 08625 08626 ch->state = MISDN_DIALING; 08627 08628 if (!ch->noautorespond_on_setup) { 08629 if (bc->nt) { 08630 misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE); 08631 } else { 08632 if (misdn_lib_is_ptp(bc->port)) { 08633 misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE); 08634 } else { 08635 misdn_lib_send_event(bc, EVENT_PROCEEDING); 08636 } 08637 } 08638 } else { 08639 ch->state = MISDN_INCOMING_SETUP; 08640 } 08641 08642 chan_misdn_log(1, bc->port, 08643 "* Starting Ast context:%s dialed:%s caller:\"%s\" <%s> with 's' extension\n", 08644 ast->context, 08645 ast->exten, 08646 (ast->caller.id.name.valid && ast->caller.id.name.str) 08647 ? ast->caller.id.name.str : "", 08648 (ast->caller.id.number.valid && ast->caller.id.number.str) 08649 ? ast->caller.id.number.str : ""); 08650 08651 strcpy(ast->exten, "s"); 08652 08653 if (!ast_canmatch_extension(ast, ast->context, ast->exten, 1, bc->caller.number) || pbx_start_chan(ch) < 0) { 08654 ast = NULL; 08655 bc->out_cause = AST_CAUSE_UNALLOCATED; 08656 hangup_chan(ch, bc); 08657 hanguptone_indicate(ch); 08658 08659 misdn_lib_send_event(bc, bc->nt ? EVENT_RELEASE_COMPLETE : EVENT_DISCONNECT); 08660 } 08661 08662 08663 while (!ast_strlen_zero(predial)) { 08664 fr.frametype = AST_FRAME_DTMF; 08665 fr.subclass.integer = *predial; 08666 fr.src = NULL; 08667 fr.data.ptr = NULL; 08668 fr.datalen = 0; 08669 fr.samples = 0; 08670 fr.mallocd = 0; 08671 fr.offset = 0; 08672 fr.delivery = ast_tv(0,0); 08673 08674 if (ch->ast && MISDN_ASTERISK_TECH_PVT(ch->ast)) { 08675 ast_queue_frame(ch->ast, &fr); 08676 } 08677 predial++; 08678 } 08679 }
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 8771 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().
08772 { 08773 char tmp[32]; 08774 08775 /* 08776 * The only use for MISDN_PID is if there is a problem and you 08777 * have to use the "misdn restart pid" CLI command. Otherwise, 08778 * the pid is not used by anyone. The internal use of MISDN_PID 08779 * has been deleted. 08780 */ 08781 chan_misdn_log(3, bc->port, " --> EXPORT_PID: pid:%d\n", bc->pid); 08782 snprintf(tmp, sizeof(tmp), "%d", bc->pid); 08783 pbx_builtin_setvar_helper(chan, "_MISDN_PID", tmp); 08784 08785 if (bc->sending_complete) { 08786 snprintf(tmp, sizeof(tmp), "%d", bc->sending_complete); 08787 pbx_builtin_setvar_helper(chan, "MISDN_ADDRESS_COMPLETE", tmp); 08788 } 08789 08790 if (bc->urate) { 08791 snprintf(tmp, sizeof(tmp), "%d", bc->urate); 08792 pbx_builtin_setvar_helper(chan, "MISDN_URATE", tmp); 08793 } 08794 08795 if (bc->uulen) { 08796 pbx_builtin_setvar_helper(chan, "MISDN_USERUSER", bc->uu); 08797 } 08798 08799 if (!ast_strlen_zero(bc->keypad)) { 08800 pbx_builtin_setvar_helper(chan, "MISDN_KEYPAD", bc->keypad); 08801 } 08802 }
static struct chan_list* find_chan_by_bc | ( | struct misdn_bchannel * | bc | ) | [static] |
Returns a reference to the found chan_list.
Definition at line 8187 of file chan_misdn.c.
References ast_mutex_lock, ast_mutex_unlock, chan_list::bc, chan_list_ref, cl_te, cl_te_lock, and chan_list::next.
Referenced by cb_events(), and chan_misdn_jb_empty().
08188 { 08189 struct chan_list *help; 08190 08191 ast_mutex_lock(&cl_te_lock); 08192 for (help = cl_te; help; help = help->next) { 08193 if (help->bc == bc) { 08194 chan_list_ref(help, "Found chan_list by bc"); 08195 ast_mutex_unlock(&cl_te_lock); 08196 return help; 08197 } 08198 } 08199 ast_mutex_unlock(&cl_te_lock); 08200 08201 chan_misdn_log(6, bc->port, 08202 "$$$ find_chan_by_bc: No channel found for dialed:%s caller:\"%s\" <%s>\n", 08203 bc->dialed.number, 08204 bc->caller.name, 08205 bc->caller.number); 08206 08207 return NULL; 08208 }
static struct chan_list* find_hold_active_call | ( | struct misdn_bchannel * | bc | ) | [static] |
Definition at line 8279 of file chan_misdn.c.
References chan_list::ast, ast_mutex_lock, ast_mutex_unlock, chan_list::bc, chan_list_ref, cl_te, cl_te_lock, chan_list::hold, MISDN_ALERTING, MISDN_CONNECTED, MISDN_HOLD_IDLE, MISDN_PROCEEDING, MISDN_PROGRESS, chan_list::next, misdn_bchannel::port, chan_list::state, and hold_info::state.
Referenced by cb_events().
08280 { 08281 struct chan_list *list; 08282 08283 ast_mutex_lock(&cl_te_lock); 08284 for (list = cl_te; list; list = list->next) { 08285 if (list->hold.state == MISDN_HOLD_IDLE && list->bc && list->bc->port == bc->port 08286 && list->ast) { 08287 switch (list->state) { 08288 case MISDN_PROCEEDING: 08289 case MISDN_PROGRESS: 08290 case MISDN_ALERTING: 08291 case MISDN_CONNECTED: 08292 chan_list_ref(list, "Found chan_list hold active call"); 08293 ast_mutex_unlock(&cl_te_lock); 08294 return list; 08295 default: 08296 break; 08297 } 08298 } 08299 } 08300 ast_mutex_unlock(&cl_te_lock); 08301 return NULL; 08302 }
static struct chan_list* find_hold_call | ( | struct misdn_bchannel * | bc | ) | [static] |
Returns a reference to the found chan_list.
Definition at line 8211 of file chan_misdn.c.
References ast_mutex_lock, ast_mutex_unlock, chan_list::bc, misdn_bchannel::caller, chan_list_ref, chan_misdn_log(), hold_info::channel, misdn_bchannel::channel, cl_te, cl_te_lock, misdn_bchannel::dialed, chan_list::hold, MISDN_HOLD_ACTIVE, misdn_party_id::name, chan_list::next, misdn_party_id::number, misdn_party_dialing::number, hold_info::port, misdn_bchannel::port, misdn_bchannel::pri, and hold_info::state.
Referenced by cb_events().
08212 { 08213 struct chan_list *help; 08214 08215 if (bc->pri) { 08216 return NULL; 08217 } 08218 08219 chan_misdn_log(6, bc->port, "$$$ find_hold_call: channel:%d dialed:%s caller:\"%s\" <%s>\n", 08220 bc->channel, 08221 bc->dialed.number, 08222 bc->caller.name, 08223 bc->caller.number); 08224 ast_mutex_lock(&cl_te_lock); 08225 for (help = cl_te; help; help = help->next) { 08226 chan_misdn_log(4, bc->port, "$$$ find_hold_call: --> hold:%d channel:%d\n", help->hold.state, help->hold.channel); 08227 if (help->hold.state == MISDN_HOLD_ACTIVE && help->hold.port == bc->port) { 08228 chan_list_ref(help, "Found chan_list hold call"); 08229 ast_mutex_unlock(&cl_te_lock); 08230 return help; 08231 } 08232 } 08233 ast_mutex_unlock(&cl_te_lock); 08234 chan_misdn_log(6, bc->port, 08235 "$$$ find_hold_call: No channel found for dialed:%s caller:\"%s\" <%s>\n", 08236 bc->dialed.number, 08237 bc->caller.name, 08238 bc->caller.number); 08239 08240 return NULL; 08241 }
static struct chan_list* find_hold_call_l3 | ( | unsigned long | l3_id | ) | [static] |
Returns a reference to the found chan_list.
Definition at line 8245 of file chan_misdn.c.
References ast_mutex_lock, ast_mutex_unlock, chan_list_ref, cl_te, cl_te_lock, chan_list::hold, chan_list::l3id, MISDN_HOLD_IDLE, chan_list::next, and hold_info::state.
Referenced by cb_events().
08246 { 08247 struct chan_list *help; 08248 08249 ast_mutex_lock(&cl_te_lock); 08250 for (help = cl_te; help; help = help->next) { 08251 if (help->hold.state != MISDN_HOLD_IDLE && help->l3id == l3_id) { 08252 chan_list_ref(help, "Found chan_list hold call l3"); 08253 ast_mutex_unlock(&cl_te_lock); 08254 return help; 08255 } 08256 } 08257 ast_mutex_unlock(&cl_te_lock); 08258 08259 return NULL; 08260 }
static void free_robin_list | ( | void | ) | [static] |
Definition at line 601 of file chan_misdn.c.
References ast_free, robin_list::group, robin_list::next, and robin.
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] |
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, cl_te, cl_te_lock, 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] |
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, cl_te, cl_te_lock, ast_channel::name, and chan_list::next.
Referenced by handle_cli_misdn_send_digit(), handle_cli_misdn_send_display(), handle_cli_misdn_send_facility(), and handle_cli_misdn_toggle_echocancel().
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] |
Definition at line 613 of file chan_misdn.c.
References robin_list::group, robin_list::next, and robin.
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 5479 of file chan_misdn.c.
References ast_cli_args::argc, ast_cli_args::argv, chan_list::ast, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_ch(), ast_cli_args::fd, get_chan_by_ast_name(), send_digit_to_chan(), and ast_cli_entry::usage.
05480 { 05481 const char *channame; 05482 const char *msg; 05483 struct chan_list *tmp; 05484 int i, msglen; 05485 05486 switch (cmd) { 05487 case CLI_INIT: 05488 e->command = "misdn send digit"; 05489 e->usage = 05490 "Usage: misdn send digit <channel> \"<msg>\" \n" 05491 " Send <digit> to <channel> as DTMF Tone\n" 05492 " when channel is a mISDN channel\n"; 05493 return NULL; 05494 case CLI_GENERATE: 05495 return complete_ch(a); 05496 } 05497 05498 if (a->argc != 5) { 05499 return CLI_SHOWUSAGE; 05500 } 05501 05502 channame = a->argv[3]; 05503 msg = a->argv[4]; 05504 msglen = strlen(msg); 05505 05506 ast_cli(a->fd, "Sending %s to %s\n", msg, channame); 05507 05508 tmp = get_chan_by_ast_name(channame); 05509 if (!tmp) { 05510 ast_cli(a->fd, "Sending %s to %s failed Channel does not exist\n", msg, channame); 05511 return CLI_SUCCESS; 05512 } 05513 #if 1 05514 for (i = 0; i < msglen; i++) { 05515 if (!tmp->ast) { 05516 break; 05517 } 05518 ast_cli(a->fd, "Sending: %c\n", msg[i]); 05519 send_digit_to_chan(tmp, msg[i]); 05520 /* res = ast_safe_sleep(tmp->ast, 250); */ 05521 usleep(250000); 05522 /* res = ast_waitfor(tmp->ast,100); */ 05523 } 05524 #else 05525 if (tmp->ast) { 05526 ast_dtmf_stream(tmp->ast, NULL, msg, 250); 05527 } 05528 #endif 05529 chan_list_unref(tmp, "Digit(s) sent"); 05530 05531 return CLI_SUCCESS; 05532 }
static char* handle_cli_misdn_send_display | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 5581 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.
05582 { 05583 const char *channame; 05584 const char *msg; 05585 struct chan_list *tmp; 05586 05587 switch (cmd) { 05588 case CLI_INIT: 05589 e->command = "misdn send display"; 05590 e->usage = 05591 "Usage: misdn send display <channel> \"<msg>\" \n" 05592 " Send <msg> to <channel> as Display Message\n" 05593 " when channel is a mISDN channel\n"; 05594 return NULL; 05595 case CLI_GENERATE: 05596 return complete_ch(a); 05597 } 05598 05599 if (a->argc != 5) { 05600 return CLI_SHOWUSAGE; 05601 } 05602 05603 channame = a->argv[3]; 05604 msg = a->argv[4]; 05605 05606 ast_cli(a->fd, "Sending %s to %s\n", msg, channame); 05607 05608 tmp = get_chan_by_ast_name(channame); 05609 if (tmp && tmp->bc) { 05610 ast_copy_string(tmp->bc->display, msg, sizeof(tmp->bc->display)); 05611 misdn_lib_send_event(tmp->bc, EVENT_INFORMATION); 05612 chan_list_unref(tmp, "Done sending display"); 05613 } else { 05614 if (tmp) { 05615 chan_list_unref(tmp, "Display failed"); 05616 } 05617 ast_cli(a->fd, "No such channel %s\n", channame); 05618 return CLI_SUCCESS; 05619 } 05620 05621 return CLI_SUCCESS; 05622 }
static char* handle_cli_misdn_send_facility | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 5153 of file chan_misdn.c.
References ao2_lock, ao2_unlock, ast_cli_args::argc, ast_cli_args::argv, ARRAY_LEN, ast_copy_string(), ast_verbose, chan_list::bc, chan_list_unref, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_ch(), dummy(), EVENT_FACILITY, EVENT_REGISTER, misdn_bchannel::fac_out, get_chan_by_ast_name(), misdn_lib_port_is_nt(), misdn_lib_send_event(), misdn_make_dummy(), print_facility(), and ast_cli_entry::usage.
05154 { 05155 const char *channame; 05156 const char *nr; 05157 struct chan_list *tmp; 05158 int port; 05159 const char *served_nr; 05160 struct misdn_bchannel dummy, *bc=&dummy; 05161 unsigned max_len; 05162 05163 switch (cmd) { 05164 case CLI_INIT: 05165 e->command = "misdn send facility"; 05166 e->usage = "Usage: misdn send facility <type> <channel|port> \"<args>\" \n" 05167 "\t type is one of:\n" 05168 "\t - calldeflect\n" 05169 #if defined(AST_MISDN_ENHANCEMENTS) 05170 "\t - callrerouting\n" 05171 #endif /* defined(AST_MISDN_ENHANCEMENTS) */ 05172 "\t - CFActivate\n" 05173 "\t - CFDeactivate\n"; 05174 05175 return NULL; 05176 case CLI_GENERATE: 05177 return complete_ch(a); 05178 } 05179 05180 if (a->argc < 5) { 05181 return CLI_SHOWUSAGE; 05182 } 05183 05184 if (strstr(a->argv[3], "calldeflect")) { 05185 if (a->argc < 6) { 05186 ast_verbose("calldeflect requires 1 arg: ToNumber\n\n"); 05187 return 0; 05188 } 05189 channame = a->argv[4]; 05190 nr = a->argv[5]; 05191 05192 ast_verbose("Sending Calldeflection (%s) to %s\n", nr, channame); 05193 tmp = get_chan_by_ast_name(channame); 05194 if (!tmp) { 05195 ast_verbose("Sending CD with nr %s to %s failed: Channel does not exist.\n", nr, channame); 05196 return 0; 05197 } 05198 ao2_lock(tmp); 05199 05200 #if defined(AST_MISDN_ENHANCEMENTS) 05201 max_len = sizeof(tmp->bc->fac_out.u.CallDeflection.Component.Invoke.Deflection.Party.Number) - 1; 05202 if (max_len < strlen(nr)) { 05203 ast_verbose("Sending CD with nr %s to %s failed: Number too long (up to %u digits are allowed).\n", 05204 nr, channame, max_len); 05205 ao2_unlock(tmp); 05206 chan_list_unref(tmp, "Number too long"); 05207 return 0; 05208 } 05209 tmp->bc->fac_out.Function = Fac_CallDeflection; 05210 tmp->bc->fac_out.u.CallDeflection.InvokeID = ++misdn_invoke_id; 05211 tmp->bc->fac_out.u.CallDeflection.ComponentType = FacComponent_Invoke; 05212 tmp->bc->fac_out.u.CallDeflection.Component.Invoke.PresentationAllowedToDivertedToUserPresent = 1; 05213 tmp->bc->fac_out.u.CallDeflection.Component.Invoke.PresentationAllowedToDivertedToUser = 0; 05214 tmp->bc->fac_out.u.CallDeflection.Component.Invoke.Deflection.Party.Type = 0;/* unknown */ 05215 tmp->bc->fac_out.u.CallDeflection.Component.Invoke.Deflection.Party.LengthOfNumber = strlen(nr); 05216 strcpy((char *) tmp->bc->fac_out.u.CallDeflection.Component.Invoke.Deflection.Party.Number, nr); 05217 tmp->bc->fac_out.u.CallDeflection.Component.Invoke.Deflection.Subaddress.Length = 0; 05218 05219 #else /* !defined(AST_MISDN_ENHANCEMENTS) */ 05220 05221 max_len = sizeof(tmp->bc->fac_out.u.CDeflection.DeflectedToNumber) - 1; 05222 if (max_len < strlen(nr)) { 05223 ast_verbose("Sending CD with nr %s to %s failed: Number too long (up to %u digits are allowed).\n", 05224 nr, channame, max_len); 05225 ao2_unlock(tmp); 05226 chan_list_unref(tmp, "Number too long"); 05227 return 0; 05228 } 05229 tmp->bc->fac_out.Function = Fac_CD; 05230 tmp->bc->fac_out.u.CDeflection.PresentationAllowed = 0; 05231 //tmp->bc->fac_out.u.CDeflection.DeflectedToSubaddress[0] = 0; 05232 strcpy((char *) tmp->bc->fac_out.u.CDeflection.DeflectedToNumber, nr); 05233 #endif /* !defined(AST_MISDN_ENHANCEMENTS) */ 05234 05235 /* Send message */ 05236 print_facility(&tmp->bc->fac_out, tmp->bc); 05237 ao2_unlock(tmp); 05238 misdn_lib_send_event(tmp->bc, EVENT_FACILITY); 05239 chan_list_unref(tmp, "Send facility complete"); 05240 #if defined(AST_MISDN_ENHANCEMENTS) 05241 } else if (strstr(a->argv[3], "callrerouteing") || strstr(a->argv[3], "callrerouting")) { 05242 if (a->argc < 6) { 05243 ast_verbose("callrerouting requires 1 arg: ToNumber\n\n"); 05244 return 0; 05245 } 05246 channame = a->argv[4]; 05247 nr = a->argv[5]; 05248 05249 ast_verbose("Sending Callrerouting (%s) to %s\n", nr, channame); 05250 tmp = get_chan_by_ast_name(channame); 05251 if (!tmp) { 05252 ast_verbose("Sending Call Rerouting with nr %s to %s failed: Channel does not exist.\n", nr, channame); 05253 return 0; 05254 } 05255 ao2_lock(tmp); 05256 05257 max_len = sizeof(tmp->bc->fac_out.u.CallRerouteing.Component.Invoke.CalledAddress.Party.Number) - 1; 05258 if (max_len < strlen(nr)) { 05259 ast_verbose("Sending Call Rerouting with nr %s to %s failed: Number too long (up to %u digits are allowed).\n", 05260 nr, channame, max_len); 05261 ao2_unlock(tmp); 05262 chan_list_unref(tmp, "Number too long"); 05263 return 0; 05264 } 05265 tmp->bc->fac_out.Function = Fac_CallRerouteing; 05266 tmp->bc->fac_out.u.CallRerouteing.InvokeID = ++misdn_invoke_id; 05267 tmp->bc->fac_out.u.CallRerouteing.ComponentType = FacComponent_Invoke; 05268 05269 tmp->bc->fac_out.u.CallRerouteing.Component.Invoke.ReroutingReason = 0;/* unknown */ 05270 tmp->bc->fac_out.u.CallRerouteing.Component.Invoke.ReroutingCounter = 1; 05271 05272 tmp->bc->fac_out.u.CallRerouteing.Component.Invoke.CalledAddress.Party.Type = 0;/* unknown */ 05273 tmp->bc->fac_out.u.CallRerouteing.Component.Invoke.CalledAddress.Party.LengthOfNumber = strlen(nr); 05274 strcpy((char *) tmp->bc->fac_out.u.CallRerouteing.Component.Invoke.CalledAddress.Party.Number, nr); 05275 tmp->bc->fac_out.u.CallRerouteing.Component.Invoke.CalledAddress.Subaddress.Length = 0; 05276 05277 tmp->bc->fac_out.u.CallRerouteing.Component.Invoke.CallingPartySubaddress.Length = 0; 05278 05279 /* 0x90 0x90 0xa3 3.1 kHz audio, circuit mode, 64kbit/sec, level1/a-Law */ 05280 tmp->bc->fac_out.u.CallRerouteing.Component.Invoke.Q931ie.Bc.Length = 3; 05281 tmp->bc->fac_out.u.CallRerouteing.Component.Invoke.Q931ie.Bc.Contents[0] = 0x90; 05282 tmp->bc->fac_out.u.CallRerouteing.Component.Invoke.Q931ie.Bc.Contents[1] = 0x90; 05283 tmp->bc->fac_out.u.CallRerouteing.Component.Invoke.Q931ie.Bc.Contents[2] = 0xa3; 05284 tmp->bc->fac_out.u.CallRerouteing.Component.Invoke.Q931ie.Hlc.Length = 0; 05285 tmp->bc->fac_out.u.CallRerouteing.Component.Invoke.Q931ie.Llc.Length = 0; 05286 tmp->bc->fac_out.u.CallRerouteing.Component.Invoke.Q931ie.UserInfo.Length = 0; 05287 05288 tmp->bc->fac_out.u.CallRerouteing.Component.Invoke.LastRerouting.Type = 1;/* presentationRestricted */ 05289 tmp->bc->fac_out.u.CallRerouteing.Component.Invoke.SubscriptionOption = 0;/* no notification to caller */ 05290 05291 /* Send message */ 05292 print_facility(&tmp->bc->fac_out, tmp->bc); 05293 ao2_unlock(tmp); 05294 misdn_lib_send_event(tmp->bc, EVENT_FACILITY); 05295 chan_list_unref(tmp, "Send facility complete"); 05296 #endif /* defined(AST_MISDN_ENHANCEMENTS) */ 05297 } else if (strstr(a->argv[3], "CFActivate")) { 05298 if (a->argc < 7) { 05299 ast_verbose("CFActivate requires 2 args: 1.FromNumber, 2.ToNumber\n\n"); 05300 return 0; 05301 } 05302 port = atoi(a->argv[4]); 05303 served_nr = a->argv[5]; 05304 nr = a->argv[6]; 05305 05306 misdn_make_dummy(bc, port, 0, misdn_lib_port_is_nt(port), 0); 05307 05308 ast_verbose("Sending CFActivate Port:(%d) FromNr. (%s) to Nr. (%s)\n", port, served_nr, nr); 05309 05310 #if defined(AST_MISDN_ENHANCEMENTS) 05311 bc->fac_out.Function = Fac_ActivationDiversion; 05312 bc->fac_out.u.ActivationDiversion.InvokeID = ++misdn_invoke_id; 05313 bc->fac_out.u.ActivationDiversion.ComponentType = FacComponent_Invoke; 05314 bc->fac_out.u.ActivationDiversion.Component.Invoke.BasicService = 0;/* allServices */ 05315 bc->fac_out.u.ActivationDiversion.Component.Invoke.Procedure = 0;/* cfu (Call Forward Unconditional) */ 05316 ast_copy_string((char *) bc->fac_out.u.ActivationDiversion.Component.Invoke.ServedUser.Number, 05317 served_nr, sizeof(bc->fac_out.u.ActivationDiversion.Component.Invoke.ServedUser.Number)); 05318 bc->fac_out.u.ActivationDiversion.Component.Invoke.ServedUser.LengthOfNumber = 05319 strlen((char *) bc->fac_out.u.ActivationDiversion.Component.Invoke.ServedUser.Number); 05320 bc->fac_out.u.ActivationDiversion.Component.Invoke.ServedUser.Type = 0;/* unknown */ 05321 ast_copy_string((char *) bc->fac_out.u.ActivationDiversion.Component.Invoke.ForwardedTo.Party.Number, 05322 nr, sizeof(bc->fac_out.u.ActivationDiversion.Component.Invoke.ForwardedTo.Party.Number)); 05323 bc->fac_out.u.ActivationDiversion.Component.Invoke.ForwardedTo.Party.LengthOfNumber = 05324 strlen((char *) bc->fac_out.u.ActivationDiversion.Component.Invoke.ForwardedTo.Party.Number); 05325 bc->fac_out.u.ActivationDiversion.Component.Invoke.ForwardedTo.Party.Type = 0;/* unknown */ 05326 bc->fac_out.u.ActivationDiversion.Component.Invoke.ForwardedTo.Subaddress.Length = 0; 05327 05328 #else /* !defined(AST_MISDN_ENHANCEMENTS) */ 05329 05330 bc->fac_out.Function = Fac_CFActivate; 05331 bc->fac_out.u.CFActivate.BasicService = 0; /* All Services */ 05332 bc->fac_out.u.CFActivate.Procedure = 0; /* Unconditional */ 05333 ast_copy_string((char *) bc->fac_out.u.CFActivate.ServedUserNumber, served_nr, sizeof(bc->fac_out.u.CFActivate.ServedUserNumber)); 05334 ast_copy_string((char *) bc->fac_out.u.CFActivate.ForwardedToNumber, nr, sizeof(bc->fac_out.u.CFActivate.ForwardedToNumber)); 05335 #endif /* !defined(AST_MISDN_ENHANCEMENTS) */ 05336 05337 /* Send message */ 05338 print_facility(&bc->fac_out, bc); 05339 misdn_lib_send_event(bc, EVENT_FACILITY); 05340 } else if (strstr(a->argv[3], "CFDeactivate")) { 05341 if (a->argc < 6) { 05342 ast_verbose("CFDeactivate requires 1 arg: FromNumber\n\n"); 05343 return 0; 05344 } 05345 port = atoi(a->argv[4]); 05346 served_nr = a->argv[5]; 05347 05348 misdn_make_dummy(bc, port, 0, misdn_lib_port_is_nt(port), 0); 05349 ast_verbose("Sending CFDeactivate Port:(%d) FromNr. (%s)\n", port, served_nr); 05350 05351 #if defined(AST_MISDN_ENHANCEMENTS) 05352 bc->fac_out.Function = Fac_DeactivationDiversion; 05353 bc->fac_out.u.DeactivationDiversion.InvokeID = ++misdn_invoke_id; 05354 bc->fac_out.u.DeactivationDiversion.ComponentType = FacComponent_Invoke; 05355 bc->fac_out.u.DeactivationDiversion.Component.Invoke.BasicService = 0;/* allServices */ 05356 bc->fac_out.u.DeactivationDiversion.Component.Invoke.Procedure = 0;/* cfu (Call Forward Unconditional) */ 05357 ast_copy_string((char *) bc->fac_out.u.DeactivationDiversion.Component.Invoke.ServedUser.Number, 05358 served_nr, sizeof(bc->fac_out.u.DeactivationDiversion.Component.Invoke.ServedUser.Number)); 05359 bc->fac_out.u.DeactivationDiversion.Component.Invoke.ServedUser.LengthOfNumber = 05360 strlen((char *) bc->fac_out.u.DeactivationDiversion.Component.Invoke.ServedUser.Number); 05361 bc->fac_out.u.DeactivationDiversion.Component.Invoke.ServedUser.Type = 0;/* unknown */ 05362 05363 #else /* !defined(AST_MISDN_ENHANCEMENTS) */ 05364 05365 bc->fac_out.Function = Fac_CFDeactivate; 05366 bc->fac_out.u.CFDeactivate.BasicService = 0; /* All Services */ 05367 bc->fac_out.u.CFDeactivate.Procedure = 0; /* Unconditional */ 05368 ast_copy_string((char *) bc->fac_out.u.CFActivate.ServedUserNumber, served_nr, sizeof(bc->fac_out.u.CFActivate.ServedUserNumber)); 05369 #endif /* !defined(AST_MISDN_ENHANCEMENTS) */ 05370 05371 /* Send message */ 05372 print_facility(&bc->fac_out, bc); 05373 misdn_lib_send_event(bc, EVENT_FACILITY); 05374 #if defined(AST_MISDN_ENHANCEMENTS) && defined(CCBS_TEST_MESSAGES) 05375 } else if (strstr(a->argv[3], "test")) { 05376 int msg_number; 05377 05378 if (a->argc < 5) { 05379 ast_verbose("test (<port> [<msg#>]) | (<channel-name> <msg#>)\n\n"); 05380 return 0; 05381 } 05382 port = atoi(a->argv[4]); 05383 05384 channame = a->argv[4]; 05385 tmp = get_chan_by_ast_name(channame); 05386 if (tmp) { 05387 /* We are going to send this FACILITY message out on an existing connection */ 05388 msg_number = atoi(a->argv[5]); 05389 if (msg_number < ARRAY_LEN(Fac_Msgs)) { 05390 ao2_lock(tmp); 05391 tmp->bc->fac_out = Fac_Msgs[msg_number]; 05392 05393 /* Send message */ 05394 print_facility(&tmp->bc->fac_out, tmp->bc); 05395 ao2_unlock(tmp); 05396 misdn_lib_send_event(tmp->bc, EVENT_FACILITY); 05397 } else { 05398 ast_verbose("test <channel-name> <msg#>\n\n"); 05399 } 05400 chan_list_unref(tmp, "Facility test done"); 05401 } else if (a->argc < 6) { 05402 for (msg_number = 0; msg_number < ARRAY_LEN(Fac_Msgs); ++msg_number) { 05403 misdn_make_dummy(bc, port, 0, misdn_lib_port_is_nt(port), 0); 05404 bc->fac_out = Fac_Msgs[msg_number]; 05405 05406 /* Send message */ 05407 print_facility(&bc->fac_out, bc); 05408 misdn_lib_send_event(bc, EVENT_FACILITY); 05409 sleep(1); 05410 } 05411 } else { 05412 msg_number = atoi(a->argv[5]); 05413 if (msg_number < ARRAY_LEN(Fac_Msgs)) { 05414 misdn_make_dummy(bc, port, 0, misdn_lib_port_is_nt(port), 0); 05415 bc->fac_out = Fac_Msgs[msg_number]; 05416 05417 /* Send message */ 05418 print_facility(&bc->fac_out, bc); 05419 misdn_lib_send_event(bc, EVENT_FACILITY); 05420 } else { 05421 ast_verbose("test <port> [<msg#>]\n\n"); 05422 } 05423 } 05424 } else if (strstr(a->argv[3], "register")) { 05425 if (a->argc < 5) { 05426 ast_verbose("register <port>\n\n"); 05427 return 0; 05428 } 05429 port = atoi(a->argv[4]); 05430 05431 bc = misdn_lib_get_register_bc(port); 05432 if (!bc) { 05433 ast_verbose("Could not allocate REGISTER bc struct\n\n"); 05434 return 0; 05435 } 05436 bc->fac_out = Fac_Msgs[45]; 05437 05438 /* Send message */ 05439 print_facility(&bc->fac_out, bc); 05440 misdn_lib_send_event(bc, EVENT_REGISTER); 05441 #endif /* defined(AST_MISDN_ENHANCEMENTS) && defined(CCBS_TEST_MESSAGES) */ 05442 } 05443 05444 return CLI_SUCCESS; 05445 }
static char* handle_cli_misdn_send_restart | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 5447 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.
05448 { 05449 int port; 05450 int channel; 05451 05452 switch (cmd) { 05453 case CLI_INIT: 05454 e->command = "misdn send restart"; 05455 e->usage = 05456 "Usage: misdn send restart [port [channel]]\n" 05457 " Send a restart for every bchannel on the given port.\n"; 05458 return NULL; 05459 case CLI_GENERATE: 05460 return NULL; 05461 } 05462 05463 if (a->argc < 4 || a->argc > 5) { 05464 return CLI_SHOWUSAGE; 05465 } 05466 05467 port = atoi(a->argv[3]); 05468 05469 if (a->argc == 5) { 05470 channel = atoi(a->argv[4]); 05471 misdn_lib_send_restart(port, channel); 05472 } else { 05473 misdn_lib_send_restart(port, -1); 05474 } 05475 05476 return CLI_SUCCESS; 05477 }
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, max_ports, misdn_debug, misdn_debug_only, 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 4309 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.
04310 { 04311 switch (cmd) { 04312 case CLI_INIT: 04313 e->command = "misdn set tics"; 04314 e->usage = 04315 "Usage: misdn set tics <value>\n"; 04316 return NULL; 04317 case CLI_GENERATE: 04318 return NULL; 04319 } 04320 04321 if (a->argc != 4) { 04322 return CLI_SHOWUSAGE; 04323 } 04324 04325 /* XXX Wow, this does... a whole lot of nothing... XXX */ 04326 MAXTICS = atoi(a->argv[3]); 04327 04328 return CLI_SUCCESS; 04329 }
static char* handle_cli_misdn_show_channel | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 4273 of file chan_misdn.c.
References ast_cli_args::argc, ast_cli_args::argv, chan_list::ast, ast_mutex_lock, chan_list::bc, cl_te, cl_te_lock, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, ast_cli_entry::command, complete_ch(), ast_cli_args::fd, ast_channel::name, chan_list::next, print_bc_info(), and ast_cli_entry::usage.
04274 { 04275 struct chan_list *help; 04276 04277 switch (cmd) { 04278 case CLI_INIT: 04279 e->command = "misdn show channel"; 04280 e->usage = 04281 "Usage: misdn show channel <channel>\n" 04282 " Show an internal mISDN channel\n."; 04283 return NULL; 04284 case CLI_GENERATE: 04285 return complete_ch(a); 04286 } 04287 04288 if (a->argc != 4) { 04289 return CLI_SHOWUSAGE; 04290 } 04291 04292 ast_mutex_lock(&cl_te_lock); 04293 for (help = cl_te; help; help = help->next) { 04294 struct misdn_bchannel *bc = help->bc; 04295 struct ast_channel *ast = help->ast; 04296 04297 if (bc && ast) { 04298 if (!strcasecmp(ast->name, a->argv[3])) { 04299 print_bc_info(a->fd, help, bc); 04300 break; 04301 } 04302 } 04303 } 04304 ast_mutex_unlock(&cl_te_lock); 04305 04306 return CLI_SUCCESS; 04307 }
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, cl_te, cl_te_lock, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_channel::exten, ast_cli_args::fd, chan_list::hold, ast_party_caller::id, chan_list::l3id, misdn_debug, misdn_dump_chanlist(), MISDN_HOLD_IDLE, ast_party_id::name, chan_list::next, ast_party_id::number, misdn_bchannel::pid, hold_info::port, print_bc_info(), S_COR, hold_info::state, ast_party_number::str, ast_party_name::str, ast_cli_entry::usage, ast_party_number::valid, and ast_party_name::valid.
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 continue; 04237 } 04238 04239 if (misdn_debug[0] > 2) { 04240 ast_cli(a->fd, "Bc:%p Ast:%p\n", bc, ast); 04241 } 04242 if (bc) { 04243 print_bc_info(a->fd, help, bc); 04244 } else { 04245 if (help->hold.state != MISDN_HOLD_IDLE) { 04246 ast_cli(a->fd, "ITS A HELD CALL BC:\n"); 04247 ast_cli(a->fd, " --> l3_id: %x\n" 04248 " --> dialed:%s\n" 04249 " --> caller:\"%s\" <%s>\n" 04250 " --> hold_port: %d\n" 04251 " --> hold_channel: %d\n", 04252 help->l3id, 04253 ast->exten, 04254 S_COR(ast->caller.id.name.valid, ast->caller.id.name.str, ""), 04255 S_COR(ast->caller.id.number.valid, ast->caller.id.number.str, ""), 04256 help->hold.port, 04257 help->hold.channel 04258 ); 04259 } else { 04260 ast_cli(a->fd, "* Channel in unknown STATE !!! Exten:%s, Callerid:%s\n", 04261 ast->exten, 04262 S_COR(ast->caller.id.number.valid, ast->caller.id.number.str, "")); 04263 } 04264 } 04265 } 04266 ast_mutex_unlock(&cl_te_lock); 04267 04268 misdn_dump_chanlist(); 04269 04270 return CLI_SUCCESS; 04271 }
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_elem(), 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 4391 of file chan_misdn.c.
References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, get_show_stack_details(), misdn_debug, misdn_debug_only, and ast_cli_entry::usage.
04392 { 04393 int port; 04394 char buf[128]; 04395 04396 switch (cmd) { 04397 case CLI_INIT: 04398 e->command = "misdn show port"; 04399 e->usage = 04400 "Usage: misdn show port <port>\n" 04401 " Show detailed information for given port.\n"; 04402 return NULL; 04403 case CLI_GENERATE: 04404 return NULL; 04405 } 04406 04407 if (a->argc != 4) { 04408 return CLI_SHOWUSAGE; 04409 } 04410 04411 port = atoi(a->argv[3]); 04412 04413 ast_cli(a->fd, "BEGIN STACK_LIST:\n"); 04414 get_show_stack_details(port, buf); 04415 ast_cli(a->fd, " %s Debug:%d%s\n", buf, misdn_debug[port], misdn_debug_only[port] ? "(only)" : ""); 04416 04417 return CLI_SUCCESS; 04418 }
static char* handle_cli_misdn_show_ports_stats | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 4362 of file chan_misdn.c.
References ast_cli_args::argc, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, misdn_cfg_get_next_port(), misdn_in_calls, misdn_out_calls, and ast_cli_entry::usage.
04363 { 04364 int port; 04365 04366 switch (cmd) { 04367 case CLI_INIT: 04368 e->command = "misdn show ports stats"; 04369 e->usage = 04370 "Usage: misdn show ports stats\n" 04371 " Show mISDNs channel's call statistics per port.\n"; 04372 return NULL; 04373 case CLI_GENERATE: 04374 return NULL; 04375 } 04376 04377 if (a->argc != 4) { 04378 return CLI_SHOWUSAGE; 04379 } 04380 04381 ast_cli(a->fd, "Port\tin_calls\tout_calls\n"); 04382 for (port = misdn_cfg_get_next_port(0); port > 0; 04383 port = misdn_cfg_get_next_port(port)) { 04384 ast_cli(a->fd, "%d\t%d\t\t%d\n", port, misdn_in_calls[port], misdn_out_calls[port]); 04385 } 04386 ast_cli(a->fd, "\n"); 04387 04388 return CLI_SUCCESS; 04389 }
static char* handle_cli_misdn_show_stacks | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 4331 of file chan_misdn.c.
References ast_cli_args::argc, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, get_show_stack_details(), misdn_cfg_get_next_port(), misdn_debug, misdn_debug_only, and ast_cli_entry::usage.
04332 { 04333 int port; 04334 04335 switch (cmd) { 04336 case CLI_INIT: 04337 e->command = "misdn show stacks"; 04338 e->usage = 04339 "Usage: misdn show stacks\n" 04340 " Show internal mISDN stack_list.\n"; 04341 return NULL; 04342 case CLI_GENERATE: 04343 return NULL; 04344 } 04345 04346 if (a->argc != 3) { 04347 return CLI_SHOWUSAGE; 04348 } 04349 04350 ast_cli(a->fd, "BEGIN STACK_LIST:\n"); 04351 for (port = misdn_cfg_get_next_port(0); port > 0; 04352 port = misdn_cfg_get_next_port(port)) { 04353 char buf[128]; 04354 04355 get_show_stack_details(port, buf); 04356 ast_cli(a->fd, " %s Debug:%d%s\n", buf, misdn_debug[port], misdn_debug_only[port] ? "(only)" : ""); 04357 } 04358 04359 return CLI_SUCCESS; 04360 }
static char* handle_cli_misdn_toggle_echocancel | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 5534 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.
05535 { 05536 const char *channame; 05537 struct chan_list *tmp; 05538 05539 switch (cmd) { 05540 case CLI_INIT: 05541 e->command = "misdn toggle echocancel"; 05542 e->usage = 05543 "Usage: misdn toggle echocancel <channel>\n" 05544 " Toggle EchoCancel on mISDN Channel.\n"; 05545 return NULL; 05546 case CLI_GENERATE: 05547 return complete_ch(a); 05548 } 05549 05550 if (a->argc != 4) { 05551 return CLI_SHOWUSAGE; 05552 } 05553 05554 channame = a->argv[3]; 05555 05556 ast_cli(a->fd, "Toggling EchoCancel on %s\n", channame); 05557 05558 tmp = get_chan_by_ast_name(channame); 05559 if (!tmp) { 05560 ast_cli(a->fd, "Toggling EchoCancel %s failed Channel does not exist\n", channame); 05561 return CLI_SUCCESS; 05562 } 05563 05564 tmp->toggle_ec = tmp->toggle_ec ? 0 : 1; 05565 05566 if (tmp->toggle_ec) { 05567 #ifdef MISDN_1_2 05568 update_pipeline_config(tmp->bc); 05569 #else 05570 update_ec_config(tmp->bc); 05571 #endif 05572 manager_ec_enable(tmp->bc); 05573 } else { 05574 manager_ec_disable(tmp->bc); 05575 } 05576 chan_list_unref(tmp, "Done toggling echo cancel"); 05577 05578 return CLI_SUCCESS; 05579 }
static void hangup_chan | ( | struct chan_list * | ch, | |
struct misdn_bchannel * | bc | |||
) | [static] |
Definition at line 8375 of file chan_misdn.c.
References chan_list::ast, ast_hangup(), ast_queue_hangup_with_cause(), chan_list::bc, misdn_bchannel::cause, cb_log, chan_list::need_hangup, chan_list::need_queue_hangup, misdn_bchannel::port, and send_cause2ast().
Referenced by cb_events(), do_immediate_setup(), local_hangup(), and start_pbx().
08376 { 08377 int port; 08378 08379 if (!ch) { 08380 cb_log(1, 0, "Cannot hangup chan, no ch\n"); 08381 return; 08382 } 08383 08384 port = bc->port; 08385 cb_log(5, port, "hangup_chan called\n"); 08386 08387 if (ch->need_hangup) { 08388 cb_log(2, port, " --> hangup\n"); 08389 ch->need_hangup = 0; 08390 ch->need_queue_hangup = 0; 08391 if (ch->ast && send_cause2ast(ch->ast, bc, ch)) { 08392 ast_hangup(ch->ast); 08393 } 08394 return; 08395 } 08396 08397 if (!ch->need_queue_hangup) { 08398 cb_log(2, port, " --> No need to queue hangup\n"); 08399 return; 08400 } 08401 08402 ch->need_queue_hangup = 0; 08403 if (ch->ast) { 08404 if (send_cause2ast(ch->ast, bc, ch)) { 08405 ast_queue_hangup_with_cause(ch->ast, bc->cause); 08406 cb_log(2, port, " --> queue_hangup\n"); 08407 } 08408 } else { 08409 cb_log(1, port, "Cannot hangup chan, no ast\n"); 08410 } 08411 }
static void hanguptone_indicate | ( | struct chan_list * | cl | ) | [static] |
Definition at line 7656 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().
07657 { 07658 misdn_lib_send_tone(cl->bc, TONE_HANGUP); 07659 }
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 8746 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().
08747 { 08748 const char *tmp; 08749 08750 ast_channel_lock(chan); 08751 tmp = pbx_builtin_getvar_helper(chan, "MISDN_ADDRESS_COMPLETE"); 08752 if (tmp && (atoi(tmp) == 1)) { 08753 bc->sending_complete = 1; 08754 } 08755 08756 tmp = pbx_builtin_getvar_helper(chan, "MISDN_USERUSER"); 08757 if (tmp) { 08758 ast_log(LOG_NOTICE, "MISDN_USERUSER: %s\n", tmp); 08759 ast_copy_string(bc->uu, tmp, sizeof(bc->uu)); 08760 bc->uulen = strlen(bc->uu); 08761 } 08762 08763 tmp = pbx_builtin_getvar_helper(chan, "MISDN_KEYPAD"); 08764 if (tmp) { 08765 ast_copy_string(bc->keypad, tmp, sizeof(bc->keypad)); 08766 } 08767 ast_channel_unlock(chan); 08768 }
static int load_module | ( | void | ) | [static] |
Definition at line 11182 of file chan_misdn.c.
References ast_calloc, ast_channel_register(), ast_cli_register_multiple(), ast_custom_function_register, ast_free, ast_log(), ast_malloc, AST_MODULE_LOAD_DECLINE, ast_mutex_init, ast_register_application, ast_strlen_zero(), BUFFERSIZE, misdn_lib_iface::cb_event, cb_events(), chan_misdn_clis, chan_misdn_jb_empty(), chan_misdn_log(), cl_te_lock, LOG_ERROR, max_ports, misdn_cfg_get(), misdn_cfg_get_next_port(), misdn_cfg_get_ports_string(), misdn_cfg_init(), MISDN_CFG_L1_TIMEOUT, misdn_cfg_update_ptp(), misdn_check_l2l1(), misdn_debug, misdn_debug_only, misdn_facility_exec(), MISDN_GEN_DEBUG, MISDN_GEN_NTDEBUGFILE, MISDN_GEN_NTDEBUGFLAGS, MISDN_GEN_NTKEEPCALLS, MISDN_GEN_TRACEFILE, misdn_in_calls, misdn_l1_task(), misdn_lib_init(), misdn_lib_maxports_get(), misdn_lib_nt_debug_init(), misdn_lib_nt_keepcalls(), misdn_out_calls, misdn_ports, misdn_set_opt_exec(), misdn_tasks_add(), misdn_tech, misdn_type, release_lock, tracing, and unload_module.
11183 { 11184 int i, port; 11185 int ntflags = 0, ntkc = 0; 11186 char ports[256] = ""; 11187 char tempbuf[BUFFERSIZE + 1]; 11188 char ntfile[BUFFERSIZE + 1]; 11189 struct misdn_lib_iface iface = { 11190 .cb_event = cb_events, 11191 .cb_log = chan_misdn_log, 11192 .cb_jb_empty = chan_misdn_jb_empty, 11193 }; 11194 11195 max_ports = misdn_lib_maxports_get(); 11196 11197 if (max_ports <= 0) { 11198 ast_log(LOG_ERROR, "Unable to initialize mISDN\n"); 11199 return AST_MODULE_LOAD_DECLINE; 11200 } 11201 11202 if (misdn_cfg_init(max_ports, 0)) { 11203 ast_log(LOG_ERROR, "Unable to initialize misdn_config.\n"); 11204 return AST_MODULE_LOAD_DECLINE; 11205 } 11206 g_config_initialized = 1; 11207 11208 #if defined(AST_MISDN_ENHANCEMENTS) 11209 misdn_cc_init(); 11210 #endif /* defined(AST_MISDN_ENHANCEMENTS) */ 11211 11212 misdn_debug = ast_malloc(sizeof(int) * (max_ports + 1)); 11213 if (!misdn_debug) { 11214 ast_log(LOG_ERROR, "Out of memory for misdn_debug\n"); 11215 return AST_MODULE_LOAD_DECLINE; 11216 } 11217 misdn_ports = ast_malloc(sizeof(int) * (max_ports + 1)); 11218 if (!misdn_ports) { 11219 ast_free(misdn_debug); 11220 ast_log(LOG_ERROR, "Out of memory for misdn_ports\n"); 11221 return AST_MODULE_LOAD_DECLINE; 11222 } 11223 misdn_cfg_get(0, MISDN_GEN_DEBUG, &misdn_debug[0], sizeof(misdn_debug[0])); 11224 for (i = 1; i <= max_ports; i++) { 11225 misdn_debug[i] = misdn_debug[0]; 11226 misdn_ports[i] = i; 11227 } 11228 *misdn_ports = 0; 11229 misdn_debug_only = ast_calloc(max_ports + 1, sizeof(int)); 11230 if (!misdn_debug_only) { 11231 ast_free(misdn_ports); 11232 ast_free(misdn_debug); 11233 ast_log(LOG_ERROR, "Out of memory for misdn_debug_only\n"); 11234 return AST_MODULE_LOAD_DECLINE; 11235 } 11236 11237 misdn_cfg_get(0, MISDN_GEN_TRACEFILE, tempbuf, sizeof(tempbuf)); 11238 if (!ast_strlen_zero(tempbuf)) { 11239 tracing = 1; 11240 } 11241 11242 misdn_in_calls = ast_malloc(sizeof(int) * (max_ports + 1)); 11243 if (!misdn_in_calls) { 11244 ast_free(misdn_debug_only); 11245 ast_free(misdn_ports); 11246 ast_free(misdn_debug); 11247 ast_log(LOG_ERROR, "Out of memory for misdn_in_calls\n"); 11248 return AST_MODULE_LOAD_DECLINE; 11249 } 11250 misdn_out_calls = ast_malloc(sizeof(int) * (max_ports + 1)); 11251 if (!misdn_out_calls) { 11252 ast_free(misdn_in_calls); 11253 ast_free(misdn_debug_only); 11254 ast_free(misdn_ports); 11255 ast_free(misdn_debug); 11256 ast_log(LOG_ERROR, "Out of memory for misdn_out_calls\n"); 11257 return AST_MODULE_LOAD_DECLINE; 11258 } 11259 11260 for (i = 1; i <= max_ports; i++) { 11261 misdn_in_calls[i] = 0; 11262 misdn_out_calls[i] = 0; 11263 } 11264 11265 ast_mutex_init(&cl_te_lock); 11266 ast_mutex_init(&release_lock); 11267 11268 misdn_cfg_update_ptp(); 11269 misdn_cfg_get_ports_string(ports); 11270 11271 if (!ast_strlen_zero(ports)) { 11272 chan_misdn_log(0, 0, "Got: %s from get_ports\n", ports); 11273 } 11274 if (misdn_lib_init(ports, &iface, NULL)) { 11275 chan_misdn_log(0, 0, "No te ports initialized\n"); 11276 } 11277 11278 misdn_cfg_get(0, MISDN_GEN_NTDEBUGFLAGS, &ntflags, sizeof(ntflags)); 11279 misdn_cfg_get(0, MISDN_GEN_NTDEBUGFILE, &ntfile, sizeof(ntfile)); 11280 misdn_cfg_get(0, MISDN_GEN_NTKEEPCALLS, &ntkc, sizeof(ntkc)); 11281 11282 misdn_lib_nt_keepcalls(ntkc); 11283 misdn_lib_nt_debug_init(ntflags, ntfile); 11284 11285 if (ast_channel_register(&misdn_tech)) { 11286 ast_log(LOG_ERROR, "Unable to register channel class %s\n", misdn_type); 11287 unload_module(); 11288 return AST_MODULE_LOAD_DECLINE; 11289 } 11290 11291 ast_cli_register_multiple(chan_misdn_clis, sizeof(chan_misdn_clis) / sizeof(struct ast_cli_entry)); 11292 11293 ast_register_application("misdn_set_opt", misdn_set_opt_exec, "misdn_set_opt", 11294 "misdn_set_opt(:<opt><optarg>:<opt><optarg>...):\n" 11295 "Sets mISDN opts. and optargs\n" 11296 "\n" 11297 "The available options are:\n" 11298 " a - Have Asterisk detect DTMF tones on called channel\n" 11299 " c - Make crypted outgoing call, optarg is keyindex\n" 11300 " d - Send display text to called phone, text is the optarg\n" 11301 " e - Perform echo cancellation on this channel,\n" 11302 " takes taps as optarg (32,64,128,256)\n" 11303 " e! - Disable echo cancellation on this channel\n" 11304 " f - Enable fax detection\n" 11305 " h - Make digital outgoing call\n" 11306 " h1 - Make HDLC mode digital outgoing call\n" 11307 " i - Ignore detected DTMF tones, don't signal them to Asterisk,\n" 11308 " they will be transported inband.\n" 11309 " jb - Set jitter buffer length, optarg is length\n" 11310 " jt - Set jitter buffer upper threshold, optarg is threshold\n" 11311 " jn - Disable jitter buffer\n" 11312 " n - Disable mISDN DSP on channel.\n" 11313 " Disables: echo cancel, DTMF detection, and volume control.\n" 11314 " p - Caller ID presentation,\n" 11315 " optarg is either 'allowed' or 'restricted'\n" 11316 " s - Send Non-inband DTMF as inband\n" 11317 " vr - Rx gain control, optarg is gain\n" 11318 " vt - Tx gain control, optarg is gain\n" 11319 ); 11320 11321 11322 ast_register_application("misdn_facility", misdn_facility_exec, "misdn_facility", 11323 "misdn_facility(<FACILITY_TYPE>|<ARG1>|..)\n" 11324 "Sends the Facility Message FACILITY_TYPE with \n" 11325 "the given Arguments to the current ISDN Channel\n" 11326 "Supported Facilities are:\n" 11327 "\n" 11328 "type=calldeflect args=Nr where to deflect\n" 11329 #if defined(AST_MISDN_ENHANCEMENTS) 11330 "type=callrerouting args=Nr where to deflect\n" 11331 #endif /* defined(AST_MISDN_ENHANCEMENTS) */ 11332 ); 11333 11334 11335 ast_register_application("misdn_check_l2l1", misdn_check_l2l1, "misdn_check_l2l1", 11336 "misdn_check_l2l1(<port>||g:<groupname>,timeout)\n" 11337 "Checks if the L2 and L1 are up on either the given <port> or\n" 11338 "on the ports in the group with <groupname>\n" 11339 "If the L1/L2 are down, check_l2l1 gets up the L1/L2 and waits\n" 11340 "for <timeout> seconds that this happens. Otherwise, nothing happens\n" 11341 "\n" 11342 "This application, ensures the L1/L2 state of the Ports in a group\n" 11343 "it is intended to make the pmp_l1_check option redundant and to\n" 11344 "fix a buggy switch config from your provider\n" 11345 "\n" 11346 "a sample dialplan would look like:\n\n" 11347 "exten => _X.,1,misdn_check_l2l1(g:out|2)\n" 11348 "exten => _X.,n,dial(mISDN/g:out/${EXTEN})\n" 11349 ); 11350 11351 #if defined(AST_MISDN_ENHANCEMENTS) 11352 ast_register_application(misdn_command_name, misdn_command_exec, misdn_command_name, 11353 "misdn_command(<command>[,<options>])\n" 11354 "The following commands are defined:\n" 11355 "cc-initialize\n" 11356 " Setup mISDN support for call completion\n" 11357 " Must call before doing any Dial() involving call completion.\n" 11358 "ccnr-request,${MISDN_CC_RECORD_ID},<notify-context>,<user-a-extension>,<priority>\n" 11359 " Request Call Completion No Reply activation\n" 11360 "ccbs-request,${MISDN_CC_RECORD_ID},<notify-context>,<user-a-extension>,<priority>\n" 11361 " Request Call Completion Busy Subscriber activation\n" 11362 "cc-b-free,${MISDN_CC_RECORD_ID},<notify-context>,<user-a-extension>,<priority>\n" 11363 " Set the dialplan location to notify when User-B is available but User-A is busy.\n" 11364 " Setting this dialplan location is optional.\n" 11365 "cc-a-busy,${MISDN_CC_RECORD_ID},<yes/no>\n" 11366 " Set the busy status of call completion User-A\n" 11367 "cc-deactivate,${MISDN_CC_RECORD_ID}\n" 11368 " Deactivate the identified call completion request\n" 11369 "\n" 11370 "MISDN_CC_RECORD_ID is set when Dial() returns and call completion is possible\n" 11371 "MISDN_CC_STATUS is set to ACTIVATED or ERROR after the call completion\n" 11372 "activation request.\n" 11373 "MISDN_ERROR_MSG is set to a descriptive message on error.\n" 11374 ); 11375 11376 ast_custom_function_register(&misdn_cc_function); 11377 #endif /* defined(AST_MISDN_ENHANCEMENTS) */ 11378 11379 misdn_cfg_get(0, MISDN_GEN_TRACEFILE, global_tracefile, sizeof(global_tracefile)); 11380 11381 /* start the l1 watchers */ 11382 11383 for (port = misdn_cfg_get_next_port(0); port >= 0; port = misdn_cfg_get_next_port(port)) { 11384 int l1timeout; 11385 misdn_cfg_get(port, MISDN_CFG_L1_TIMEOUT, &l1timeout, sizeof(l1timeout)); 11386 if (l1timeout) { 11387 chan_misdn_log(4, 0, "Adding L1watcher task: port:%d timeout:%ds\n", port, l1timeout); 11388 misdn_tasks_add(l1timeout * 1000, misdn_l1_task, &misdn_ports[port]); 11389 } 11390 } 11391 11392 chan_misdn_log(0, 0, "-- mISDN Channel Driver Registered --\n"); 11393 11394 return 0; 11395 }
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 6754 of file chan_misdn.c.
References chan_list::ast, AST_CAUSE_NETWORK_OUT_OF_ORDER, AST_CAUSE_PROTOCOL_ERROR, ast_channel_lock, ast_channel_unlock, ast_copy_string(), ast_log(), ast_queue_hangup_with_cause(), ast_strlen_zero(), ast_true(), chan_list::bc, chan_misdn_log(), misdn_bchannel::connected, misdn_bchannel::crypt_key, misdn_bchannel::dialed, EVENT_CONNECT, misdn_bchannel::fac_out, misdn_bchannel::hdlc, LOG_WARNING, MISDN_ASTERISK_TECH_PVT, MISDN_CONNECTED, misdn_lib_send_event(), misdn_bchannel::nodsp, misdn_bchannel::nojitter, misdn_party_dialing::number, misdn_party_id::number, misdn_party_dialing::number_plan, misdn_party_id::number_plan, misdn_party_dialing::number_type, misdn_party_id::number_type, misdn_bchannel::outgoing_colp, pbx_builtin_getvar_helper(), misdn_bchannel::port, misdn_bchannel::presentation, misdn_party_id::presentation, print_facility(), misdn_party_id::screening, start_bc_tones(), chan_list::state, and stop_indicate().
06755 { 06756 struct chan_list *p; 06757 const char *tmp; 06758 06759 if (!ast || !(p = MISDN_ASTERISK_TECH_PVT(ast))) { 06760 return -1; 06761 } 06762 06763 chan_misdn_log(1, p ? (p->bc ? p->bc->port : 0) : 0, "* ANSWER:\n"); 06764 06765 if (!p) { 06766 ast_log(LOG_WARNING, " --> Channel not connected ??\n"); 06767 ast_queue_hangup_with_cause(ast, AST_CAUSE_NETWORK_OUT_OF_ORDER); 06768 } 06769 06770 if (!p->bc) { 06771 chan_misdn_log(1, 0, " --> Got Answer, but there is no bc obj ??\n"); 06772 06773 ast_queue_hangup_with_cause(ast, AST_CAUSE_PROTOCOL_ERROR); 06774 } 06775 06776 ast_channel_lock(ast); 06777 tmp = pbx_builtin_getvar_helper(ast, "CRYPT_KEY"); 06778 if (!ast_strlen_zero(tmp)) { 06779 chan_misdn_log(1, p->bc->port, " --> Connection will be BF crypted\n"); 06780 ast_copy_string(p->bc->crypt_key, tmp, sizeof(p->bc->crypt_key)); 06781 } else { 06782 chan_misdn_log(3, p->bc->port, " --> Connection is without BF encryption\n"); 06783 } 06784 06785 tmp = pbx_builtin_getvar_helper(ast, "MISDN_DIGITAL_TRANS"); 06786 if (!ast_strlen_zero(tmp) && ast_true(tmp)) { 06787 chan_misdn_log(1, p->bc->port, " --> Connection is transparent digital\n"); 06788 p->bc->nodsp = 1; 06789 p->bc->hdlc = 0; 06790 p->bc->nojitter = 1; 06791 } 06792 ast_channel_unlock(ast); 06793 06794 p->state = MISDN_CONNECTED; 06795 stop_indicate(p); 06796 06797 if (ast_strlen_zero(p->bc->connected.number)) { 06798 chan_misdn_log(2,p->bc->port," --> empty connected number using dialed number\n"); 06799 ast_copy_string(p->bc->connected.number, p->bc->dialed.number, sizeof(p->bc->connected.number)); 06800 06801 /* 06802 * Use the misdn_set_opt() application to set the presentation 06803 * before we answer or you can use the CONECTEDLINE() function 06804 * to set everything before using the Answer() application. 06805 */ 06806 p->bc->connected.presentation = p->bc->presentation; 06807 p->bc->connected.screening = 0; /* unscreened */ 06808 p->bc->connected.number_type = p->bc->dialed.number_type; 06809 p->bc->connected.number_plan = p->bc->dialed.number_plan; 06810 } 06811 06812 switch (p->bc->outgoing_colp) { 06813 case 1:/* restricted */ 06814 case 2:/* blocked */ 06815 p->bc->connected.presentation = 1;/* restricted */ 06816 break; 06817 default: 06818 break; 06819 } 06820 06821 #if defined(AST_MISDN_ENHANCEMENTS) 06822 if (p->bc->div_leg_3_tx_pending) { 06823 p->bc->div_leg_3_tx_pending = 0; 06824 06825 /* Send DivertingLegInformation3 */ 06826 p->bc->fac_out.Function = Fac_DivertingLegInformation3; 06827 p->bc->fac_out.u.DivertingLegInformation3.InvokeID = ++misdn_invoke_id; 06828 p->bc->fac_out.u.DivertingLegInformation3.PresentationAllowedIndicator = 06829 (p->bc->connected.presentation == 0) ? 1 : 0; 06830 print_facility(&p->bc->fac_out, p->bc); 06831 } 06832 #endif /* defined(AST_MISDN_ENHANCEMENTS) */ 06833 misdn_lib_send_event(p->bc, EVENT_CONNECT); 06834 start_bc_tones(p); 06835 06836 return 0; 06837 }
static int misdn_attempt_transfer | ( | struct chan_list * | active_ch, | |
struct chan_list * | held_ch | |||
) | [static] |
Definition at line 8548 of file chan_misdn.c.
References ao2_ref, chan_list::ast, ast_bridged_channel(), ast_channel_lock, ast_channel_transfer_masquerade(), ast_channel_trylock, ast_channel_unlock, ast_party_connected_line_copy(), ast_party_connected_line_free(), ast_party_connected_line_init(), chan_misdn_log(), CHANNEL_DEADLOCK_AVOIDANCE, ast_channel::connected, chan_list::hold, MISDN_ALERTING, MISDN_CONNECTED, MISDN_HOLD_TRANSFER, MISDN_PROCEEDING, MISDN_PROGRESS, ast_channel::name, hold_info::port, hold_info::state, and chan_list::state.
Referenced by cb_events().
08549 { 08550 int retval; 08551 struct ast_channel *target; 08552 struct ast_channel *transferee; 08553 struct ast_party_connected_line target_colp; 08554 struct ast_party_connected_line transferee_colp; 08555 08556 switch (active_ch->state) { 08557 case MISDN_PROCEEDING: 08558 case MISDN_PROGRESS: 08559 case MISDN_ALERTING: 08560 case MISDN_CONNECTED: 08561 break; 08562 default: 08563 return -1; 08564 } 08565 08566 ast_channel_lock(held_ch->ast); 08567 while (ast_channel_trylock(active_ch->ast)) { 08568 CHANNEL_DEADLOCK_AVOIDANCE(held_ch->ast); 08569 } 08570 08571 transferee = ast_bridged_channel(held_ch->ast); 08572 if (!transferee) { 08573 /* 08574 * Could not transfer. Held channel is not bridged anymore. 08575 * Held party probably got tired of waiting and hung up. 08576 */ 08577 ast_channel_unlock(held_ch->ast); 08578 ast_channel_unlock(active_ch->ast); 08579 return -1; 08580 } 08581 08582 target = active_ch->ast; 08583 chan_misdn_log(1, held_ch->hold.port, "TRANSFERRING %s to %s\n", 08584 held_ch->ast->name, target->name); 08585 08586 ast_party_connected_line_init(&target_colp); 08587 ast_party_connected_line_copy(&target_colp, &target->connected); 08588 ast_party_connected_line_init(&transferee_colp); 08589 ast_party_connected_line_copy(&transferee_colp, &held_ch->ast->connected); 08590 held_ch->hold.state = MISDN_HOLD_TRANSFER; 08591 08592 /* 08593 * Before starting a masquerade, all channel and pvt locks must 08594 * be unlocked. Any recursive channel locks held before 08595 * ast_channel_transfer_masquerade() invalidates deadlock 08596 * avoidance. Since we are unlocking both the pvt and its owner 08597 * channel it is possible for "target" and "transferee" to be 08598 * destroyed by their pbx threads. To prevent this we must give 08599 * "target" and "transferee" a reference before any unlocking 08600 * takes place. 08601 */ 08602 ao2_ref(target, +1); 08603 ao2_ref(transferee, +1); 08604 ast_channel_unlock(held_ch->ast); 08605 ast_channel_unlock(active_ch->ast); 08606 08607 /* Setup transfer masquerade. */ 08608 retval = ast_channel_transfer_masquerade(target, &target_colp, 0, 08609 transferee, &transferee_colp, 1); 08610 08611 ast_party_connected_line_free(&target_colp); 08612 ast_party_connected_line_free(&transferee_colp); 08613 ao2_ref(target, -1); 08614 ao2_ref(transferee, -1); 08615 return retval; 08616 }
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 7512 of file chan_misdn.c.
References AST_BRIDGE_COMPLETE, AST_BRIDGE_DTMF_CHANNEL_0, AST_BRIDGE_DTMF_CHANNEL_1, AST_BRIDGE_FAILED, AST_FRAME_CONTROL, AST_FRAME_DTMF, AST_FRAME_VOICE, ast_log(), ast_read(), ast_verb, ast_waitfor_n(), ast_write(), chan_list::bc, misdn_bchannel::caller, chan_list_unref, chan_misdn_log(), ast_channel::exten, f, get_chan_by_ast(), chan_list::ignore_dtmf, LOG_NOTICE, MISDN_CFG_BRIDGING, misdn_cfg_get(), MISDN_GEN_BRIDGING, misdn_lib_bridge(), misdn_lib_split_bridge(), misdn_party_id::name, ast_channel::name, misdn_party_id::number, misdn_bchannel::pid, and misdn_bchannel::port.
07517 { 07518 struct chan_list *ch1, *ch2; 07519 struct ast_channel *carr[2], *who; 07520 int to = -1; 07521 struct ast_frame *f; 07522 int p1_b, p2_b; 07523 int bridging; 07524 07525 ch1 = get_chan_by_ast(c0); 07526 if (!ch1) { 07527 return -1; 07528 } 07529 ch2 = get_chan_by_ast(c1); 07530 if (!ch2) { 07531 chan_list_unref(ch1, "Failed to find ch2"); 07532 return -1; 07533 } 07534 07535 carr[0] = c0; 07536 carr[1] = c1; 07537 07538 misdn_cfg_get(ch1->bc->port, MISDN_CFG_BRIDGING, &p1_b, sizeof(p1_b)); 07539 misdn_cfg_get(ch2->bc->port, MISDN_CFG_BRIDGING, &p2_b, sizeof(p2_b)); 07540 07541 if (! p1_b || ! p2_b) { 07542 ast_log(LOG_NOTICE, "Falling back to Asterisk bridging\n"); 07543 chan_list_unref(ch1, "Bridge fallback ch1"); 07544 chan_list_unref(ch2, "Bridge fallback ch2"); 07545 return AST_BRIDGE_FAILED; 07546 } 07547 07548 misdn_cfg_get(0, MISDN_GEN_BRIDGING, &bridging, sizeof(bridging)); 07549 if (bridging) { 07550 /* trying to make a mISDN_dsp conference */ 07551 chan_misdn_log(1, ch1->bc->port, "I SEND: Making conference with Number:%d\n", ch1->bc->pid + 1); 07552 misdn_lib_bridge(ch1->bc, ch2->bc); 07553 } 07554 07555 ast_verb(3, "Native bridging %s and %s\n", c0->name, c1->name); 07556 07557 chan_misdn_log(1, ch1->bc->port, "* Making Native Bridge between \"%s\" <%s> and \"%s\" <%s>\n", 07558 ch1->bc->caller.name, 07559 ch1->bc->caller.number, 07560 ch2->bc->caller.name, 07561 ch2->bc->caller.number); 07562 07563 if (!(flags & AST_BRIDGE_DTMF_CHANNEL_0)) { 07564 ch1->ignore_dtmf = 1; 07565 } 07566 07567 if (!(flags & AST_BRIDGE_DTMF_CHANNEL_1)) { 07568 ch2->ignore_dtmf = 1; 07569 } 07570 07571 for (;/*ever*/;) { 07572 to = -1; 07573 who = ast_waitfor_n(carr, 2, &to); 07574 07575 if (!who) { 07576 ast_log(LOG_NOTICE, "misdn_bridge: empty read, breaking out\n"); 07577 break; 07578 } 07579 f = ast_read(who); 07580 07581 if (!f || f->frametype == AST_FRAME_CONTROL) { 07582 /* got hangup .. */ 07583 07584 if (!f) { 07585 chan_misdn_log(4, ch1->bc->port, "Read Null Frame\n"); 07586 } else { 07587 chan_misdn_log(4, ch1->bc->port, "Read Frame Control class:%d\n", f->subclass.integer); 07588 } 07589 07590 *fo = f; 07591 *rc = who; 07592 break; 07593 } 07594 07595 if (f->frametype == AST_FRAME_DTMF) { 07596 chan_misdn_log(1, 0, "Read DTMF %d from %s\n", f->subclass.integer, who->exten); 07597 07598 *fo = f; 07599 *rc = who; 07600 break; 07601 } 07602 07603 #if 0 07604 if (f->frametype == AST_FRAME_VOICE) { 07605 chan_misdn_log(1, ch1->bc->port, "I SEND: Splitting conference with Number:%d\n", ch1->bc->pid +1); 07606 07607 continue; 07608 } 07609 #endif 07610 07611 ast_write((who == c0) ? c1 : c0, f); 07612 } 07613 07614 chan_misdn_log(1, ch1->bc->port, "I SEND: Splitting conference with Number:%d\n", ch1->bc->pid + 1); 07615 07616 misdn_lib_split_bridge(ch1->bc, ch2->bc); 07617 07618 chan_list_unref(ch1, "Bridge complete ch1"); 07619 chan_list_unref(ch2, "Bridge complete ch2"); 07620 return AST_BRIDGE_COMPLETE; 07621 }
static int misdn_call | ( | struct ast_channel * | ast, | |
char * | dest, | |||
int | timeout | |||
) | [static] |
Definition at line 6486 of file chan_misdn.c.
References ast_channel::_state, add_out_calls(), args, AST_APP_ARG, AST_CAUSE_NORMAL_CIRCUIT_CONGESTION, AST_CAUSE_NORMAL_CLEARING, AST_CAUSE_NORMAL_TEMPORARY_FAILURE, ast_copy_string(), AST_DECLARE_APP_ARGS, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), AST_NONSTANDARD_APP_ARGS, ast_setstate(), AST_STATE_DIALING, AST_STATE_DOWN, AST_STATE_RESERVED, ast_strdup, ast_strdupa, ast_strlen_zero(), ast_to_misdn_plan(), ast_to_misdn_ton(), ast_transfercapability2str(), chan_list::bc, ast_channel::caller, misdn_bchannel::caller, misdn_bchannel::capability, chan_misdn_log(), ast_channel::connected, ast_channel::context, misdn_party_redirecting::count, debug_numtype(), misdn_bchannel::dialed, ENOCHAN, EVENT_SETUP, ext, ast_channel::exten, misdn_bchannel::fac_out, misdn_party_redirecting::from, ast_channel::hangupcause, misdn_bchannel::hdlc, ast_party_caller::id, ast_party_connected_line::id, import_ch(), misdn_bchannel::incoming_cid_tag, INFO_CAPABILITY_DIGITAL_UNRESTRICTED, misdn_bchannel::l3_id, chan_list::l3id, LOG_WARNING, MISDN_ASTERISK_TECH_PVT, MISDN_CALLING, MISDN_CFG_APPEND_MSN_TO_CALLERID_TAG, misdn_cfg_get(), MISDN_CFG_LOCALDIALPLAN, misdn_copy_redirecting_from_ast(), misdn_lib_is_ptp(), misdn_lib_send_event(), misdn_set_opt_exec(), ast_party_id::name, misdn_party_id::name, ast_channel::name, misdn_bchannel::nt, ast_party_id::number, misdn_party_id::number, misdn_party_dialing::number, misdn_party_id::number_plan, misdn_party_id::number_type, NUMPLAN_ISDN, NUMTYPE_UNKNOWN, misdn_bchannel::outgoing_colp, pbx_builtin_setvar_helper(), misdn_bchannel::pid, ast_party_number::plan, misdn_bchannel::port, misdn_bchannel::presentation, misdn_party_id::presentation, print_facility(), misdn_party_redirecting::reason, misdn_bchannel::redirecting, misdn_bchannel::sending_complete, misdn_bchannel::set_presentation, chan_list::state, stop_bc_tones(), ast_party_number::str, ast_party_name::str, ast_party_id::tag, ast_channel::transfercapability, update_config(), ast_party_number::valid, and ast_party_name::valid.
06487 { 06488 int port = 0; 06489 int r; 06490 int exceed; 06491 int number_type; 06492 struct chan_list *ch; 06493 struct misdn_bchannel *newbc; 06494 char *dest_cp; 06495 int append_msn = 0; 06496 06497 AST_DECLARE_APP_ARGS(args, 06498 AST_APP_ARG(intf); /* The interface token is discarded. */ 06499 AST_APP_ARG(ext); /* extension token */ 06500 AST_APP_ARG(opts); /* options token */ 06501 ); 06502 06503 if (!ast) { 06504 ast_log(LOG_WARNING, " --> ! misdn_call called on ast_channel *ast where ast == NULL\n"); 06505 return -1; 06506 } 06507 06508 if (((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) || !dest) { 06509 ast_log(LOG_WARNING, " --> ! misdn_call called on %s, neither down nor reserved (or dest==NULL)\n", ast->name); 06510 ast->hangupcause = AST_CAUSE_NORMAL_TEMPORARY_FAILURE; 06511 ast_setstate(ast, AST_STATE_DOWN); 06512 return -1; 06513 } 06514 06515 ch = MISDN_ASTERISK_TECH_PVT(ast); 06516 if (!ch) { 06517 ast_log(LOG_WARNING, " --> ! misdn_call called on %s, chan_list *ch==NULL\n", ast->name); 06518 ast->hangupcause = AST_CAUSE_NORMAL_TEMPORARY_FAILURE; 06519 ast_setstate(ast, AST_STATE_DOWN); 06520 return -1; 06521 } 06522 06523 newbc = ch->bc; 06524 if (!newbc) { 06525 ast_log(LOG_WARNING, " --> ! misdn_call called on %s, newbc==NULL\n", ast->name); 06526 ast->hangupcause = AST_CAUSE_NORMAL_TEMPORARY_FAILURE; 06527 ast_setstate(ast, AST_STATE_DOWN); 06528 return -1; 06529 } 06530 06531 port = newbc->port; 06532 06533 #if defined(AST_MISDN_ENHANCEMENTS) 06534 if ((ch->peer = misdn_cc_caller_get(ast))) { 06535 chan_misdn_log(3, port, " --> Found CC caller data, peer:%s\n", 06536 ch->peer->chan ? "available" : "NULL"); 06537 } 06538 06539 if (ch->record_id != -1) { 06540 struct misdn_cc_record *cc_record; 06541 06542 /* This is a call completion retry call */ 06543 AST_LIST_LOCK(&misdn_cc_records_db); 06544 cc_record = misdn_cc_find_by_id(ch->record_id); 06545 if (!cc_record) { 06546 AST_LIST_UNLOCK(&misdn_cc_records_db); 06547 ast_log(LOG_WARNING, " --> ! misdn_call called on %s, cc_record==NULL\n", ast->name); 06548 ast->hangupcause = AST_CAUSE_NORMAL_TEMPORARY_FAILURE; 06549 ast_setstate(ast, AST_STATE_DOWN); 06550 return -1; 06551 } 06552 06553 /* Setup calling parameters to retry the call. */ 06554 newbc->dialed = cc_record->redial.dialed; 06555 newbc->caller = cc_record->redial.caller; 06556 memset(&newbc->redirecting, 0, sizeof(newbc->redirecting)); 06557 newbc->capability = cc_record->redial.capability; 06558 newbc->hdlc = cc_record->redial.hdlc; 06559 newbc->sending_complete = 1; 06560 06561 if (cc_record->ptp) { 06562 newbc->fac_out.Function = Fac_CCBS_T_Call; 06563 newbc->fac_out.u.CCBS_T_Call.InvokeID = ++misdn_invoke_id; 06564 } else { 06565 newbc->fac_out.Function = Fac_CCBSCall; 06566 newbc->fac_out.u.CCBSCall.InvokeID = ++misdn_invoke_id; 06567 newbc->fac_out.u.CCBSCall.CCBSReference = cc_record->mode.ptmp.reference_id; 06568 } 06569 AST_LIST_UNLOCK(&misdn_cc_records_db); 06570 06571 ast_copy_string(ast->exten, newbc->dialed.number, sizeof(ast->exten)); 06572 06573 chan_misdn_log(1, port, "* Call completion to: %s\n", newbc->dialed.number); 06574 chan_misdn_log(2, port, " --> * tech:%s context:%s\n", ast->name, ast->context); 06575 } else 06576 #endif /* defined(AST_MISDN_ENHANCEMENTS) */ 06577 { 06578 /* 06579 * dest is ---v 06580 * Dial(mISDN/g:group_name[/extension[/options]]) 06581 * Dial(mISDN/port[:preselected_channel][/extension[/options]]) 06582 * 06583 * The dial extension could be empty if you are using MISDN_KEYPAD 06584 * to control ISDN provider features. 06585 */ 06586 dest_cp = ast_strdupa(dest); 06587 AST_NONSTANDARD_APP_ARGS(args, dest_cp, '/'); 06588 if (!args.ext) { 06589 args.ext = ""; 06590 } 06591 06592 chan_misdn_log(1, port, "* CALL: %s\n", dest); 06593 chan_misdn_log(2, port, " --> * dialed:%s tech:%s context:%s\n", args.ext, ast->name, ast->context); 06594 06595 ast_copy_string(ast->exten, args.ext, sizeof(ast->exten)); 06596 ast_copy_string(newbc->dialed.number, args.ext, sizeof(newbc->dialed.number)); 06597 06598 if (ast_strlen_zero(newbc->caller.name) 06599 && ast->connected.id.name.valid 06600 && !ast_strlen_zero(ast->connected.id.name.str)) { 06601 ast_copy_string(newbc->caller.name, ast->connected.id.name.str, sizeof(newbc->caller.name)); 06602 chan_misdn_log(3, port, " --> * set caller:\"%s\" <%s>\n", newbc->caller.name, newbc->caller.number); 06603 } 06604 if (ast_strlen_zero(newbc->caller.number) 06605 && ast->connected.id.number.valid 06606 && !ast_strlen_zero(ast->connected.id.number.str)) { 06607 ast_copy_string(newbc->caller.number, ast->connected.id.number.str, sizeof(newbc->caller.number)); 06608 chan_misdn_log(3, port, " --> * set caller:\"%s\" <%s>\n", newbc->caller.name, newbc->caller.number); 06609 } 06610 06611 misdn_cfg_get(port, MISDN_CFG_APPEND_MSN_TO_CALLERID_TAG, &append_msn, sizeof(append_msn)); 06612 if (append_msn) { 06613 strncat(newbc->incoming_cid_tag, "_", sizeof(newbc->incoming_cid_tag) - strlen(newbc->incoming_cid_tag) - 1); 06614 strncat(newbc->incoming_cid_tag, newbc->caller.number, sizeof(newbc->incoming_cid_tag) - strlen(newbc->incoming_cid_tag) - 1); 06615 } 06616 06617 ast->caller.id.tag = ast_strdup(newbc->incoming_cid_tag); 06618 06619 misdn_cfg_get(port, MISDN_CFG_LOCALDIALPLAN, &number_type, sizeof(number_type)); 06620 if (number_type < 0) { 06621 if (ast->connected.id.number.valid) { 06622 newbc->caller.number_type = ast_to_misdn_ton(ast->connected.id.number.plan); 06623 newbc->caller.number_plan = ast_to_misdn_plan(ast->connected.id.number.plan); 06624 } else { 06625 newbc->caller.number_type = NUMTYPE_UNKNOWN; 06626 newbc->caller.number_plan = NUMPLAN_ISDN; 06627 } 06628 } else { 06629 /* Force us to send in SETUP message */ 06630 newbc->caller.number_type = number_type; 06631 newbc->caller.number_plan = NUMPLAN_ISDN; 06632 } 06633 debug_numtype(port, newbc->caller.number_type, "LTON"); 06634 06635 newbc->capability = ast->transfercapability; 06636 pbx_builtin_setvar_helper(ast, "TRANSFERCAPABILITY", ast_transfercapability2str(newbc->capability)); 06637 if (ast->transfercapability == INFO_CAPABILITY_DIGITAL_UNRESTRICTED) { 06638 chan_misdn_log(2, port, " --> * Call with flag Digital\n"); 06639 } 06640 06641 /* update caller screening and presentation */ 06642 update_config(ch); 06643 06644 /* fill in some ies from channel dialplan variables */ 06645 import_ch(ast, newbc, ch); 06646 06647 /* Finally The Options Override Everything */ 06648 if (!ast_strlen_zero(args.opts)) { 06649 misdn_set_opt_exec(ast, args.opts); 06650 } else { 06651 chan_misdn_log(2, port, "NO OPTS GIVEN\n"); 06652 } 06653 if (newbc->set_presentation) { 06654 newbc->caller.presentation = newbc->presentation; 06655 } 06656 06657 misdn_copy_redirecting_from_ast(newbc, ast); 06658 switch (newbc->outgoing_colp) { 06659 case 1:/* restricted */ 06660 case 2:/* blocked */ 06661 newbc->redirecting.from.presentation = 1;/* restricted */ 06662 break; 06663 default: 06664 break; 06665 } 06666 #if defined(AST_MISDN_ENHANCEMENTS) 06667 if (newbc->redirecting.from.number[0] && misdn_lib_is_ptp(port)) { 06668 if (newbc->redirecting.count < 1) { 06669 newbc->redirecting.count = 1; 06670 } 06671 06672 /* Create DivertingLegInformation2 facility */ 06673 newbc->fac_out.Function = Fac_DivertingLegInformation2; 06674 newbc->fac_out.u.DivertingLegInformation2.InvokeID = ++misdn_invoke_id; 06675 newbc->fac_out.u.DivertingLegInformation2.DivertingPresent = 1; 06676 misdn_PresentedNumberUnscreened_fill( 06677 &newbc->fac_out.u.DivertingLegInformation2.Diverting, 06678 &newbc->redirecting.from); 06679 switch (newbc->outgoing_colp) { 06680 case 2:/* blocked */ 06681 /* Block the number going out */ 06682 newbc->fac_out.u.DivertingLegInformation2.Diverting.Type = 1;/* presentationRestricted */ 06683 06684 /* Don't tell about any previous diversions or why for that matter. */ 06685 newbc->fac_out.u.DivertingLegInformation2.DiversionCounter = 1; 06686 newbc->fac_out.u.DivertingLegInformation2.DiversionReason = 0;/* unknown */ 06687 break; 06688 default: 06689 newbc->fac_out.u.DivertingLegInformation2.DiversionCounter = 06690 newbc->redirecting.count; 06691 newbc->fac_out.u.DivertingLegInformation2.DiversionReason = 06692 misdn_to_diversion_reason(newbc->redirecting.reason); 06693 break; 06694 } 06695 newbc->fac_out.u.DivertingLegInformation2.OriginalCalledPresent = 0; 06696 if (1 < newbc->fac_out.u.DivertingLegInformation2.DiversionCounter) { 06697 newbc->fac_out.u.DivertingLegInformation2.OriginalCalledPresent = 1; 06698 newbc->fac_out.u.DivertingLegInformation2.OriginalCalled.Type = 2;/* numberNotAvailableDueToInterworking */ 06699 } 06700 06701 /* 06702 * Expect a DivertingLegInformation3 to update the COLR of the 06703 * redirecting-to party we are attempting to call now. 06704 */ 06705 newbc->div_leg_3_rx_wanted = 1; 06706 } 06707 #endif /* defined(AST_MISDN_ENHANCEMENTS) */ 06708 } 06709 06710 exceed = add_out_calls(port); 06711 if (exceed != 0) { 06712 char tmp[16]; 06713 06714 snprintf(tmp, sizeof(tmp), "%d", exceed); 06715 pbx_builtin_setvar_helper(ast, "MAX_OVERFLOW", tmp); 06716 ast->hangupcause = AST_CAUSE_NORMAL_TEMPORARY_FAILURE; 06717 ast_setstate(ast, AST_STATE_DOWN); 06718 return -1; 06719 } 06720 06721 #if defined(AST_MISDN_ENHANCEMENTS) 06722 if (newbc->fac_out.Function != Fac_None) { 06723 print_facility(&newbc->fac_out, newbc); 06724 } 06725 #endif /* defined(AST_MISDN_ENHANCEMENTS) */ 06726 r = misdn_lib_send_event(newbc, EVENT_SETUP); 06727 06728 /** we should have l3id after sending setup **/ 06729 ch->l3id = newbc->l3_id; 06730 06731 if (r == -ENOCHAN) { 06732 chan_misdn_log(0, port, " --> * Theres no Channel at the moment .. !\n"); 06733 chan_misdn_log(1, port, " --> * SEND: State Down pid:%d\n", newbc ? newbc->pid : -1); 06734 ast->hangupcause = AST_CAUSE_NORMAL_CIRCUIT_CONGESTION; 06735 ast_setstate(ast, AST_STATE_DOWN); 06736 return -1; 06737 } 06738 06739 chan_misdn_log(2, port, " --> * SEND: State Dialing pid:%d\n", newbc ? newbc->pid : 1); 06740 06741 ast_setstate(ast, AST_STATE_DIALING); 06742 ast->hangupcause = AST_CAUSE_NORMAL_CLEARING; 06743 06744 if (newbc->nt) { 06745 stop_bc_tones(ch); 06746 } 06747 06748 ch->state = MISDN_CALLING; 06749 06750 return 0; 06751 }
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, cl_te, cl_te_lock, 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 12152 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().
12153 { 12154 char *parse; 12155 char group[BUFFERSIZE + 1]; 12156 char *port_str; 12157 int port = 0; 12158 int timeout; 12159 int dowait = 0; 12160 int port_up; 12161 12162 AST_DECLARE_APP_ARGS(args, 12163 AST_APP_ARG(grouppar); 12164 AST_APP_ARG(timeout); 12165 ); 12166 12167 if (ast_strlen_zero((char *) data)) { 12168 ast_log(LOG_WARNING, "misdn_check_l2l1 Requires arguments\n"); 12169 return -1; 12170 } 12171 12172 parse = ast_strdupa(data); 12173 AST_STANDARD_APP_ARGS(args, parse); 12174 12175 if (args.argc != 2) { 12176 ast_log(LOG_WARNING, "Wrong argument count\n"); 12177 return 0; 12178 } 12179 12180 /*ast_log(LOG_NOTICE, "Arguments: group/port '%s' timeout '%s'\n", args.grouppar, args.timeout);*/ 12181 timeout = atoi(args.timeout); 12182 port_str = args.grouppar; 12183 12184 if (port_str[0] == 'g' && port_str[1] == ':') { 12185 /* We make a group call lets checkout which ports are in my group */ 12186 port_str += 2; 12187 ast_copy_string(group, port_str, sizeof(group)); 12188 chan_misdn_log(2, 0, "Checking Ports in group: %s\n", group); 12189 12190 for (port = misdn_cfg_get_next_port(port); 12191 port > 0; 12192 port = misdn_cfg_get_next_port(port)) { 12193 char cfg_group[BUFFERSIZE + 1]; 12194 12195 chan_misdn_log(2, 0, "trying port %d\n", port); 12196 12197 misdn_cfg_get(port, MISDN_CFG_GROUPNAME, cfg_group, sizeof(cfg_group)); 12198 12199 if (!strcasecmp(cfg_group, group)) { 12200 port_up = misdn_lib_port_up(port, 1); 12201 if (!port_up) { 12202 chan_misdn_log(2, 0, " --> port '%d'\n", port); 12203 misdn_lib_get_port_up(port); 12204 dowait = 1; 12205 } 12206 } 12207 } 12208 } else { 12209 port = atoi(port_str); 12210 chan_misdn_log(2, 0, "Checking Port: %d\n", port); 12211 port_up = misdn_lib_port_up(port, 1); 12212 if (!port_up) { 12213 misdn_lib_get_port_up(port); 12214 dowait = 1; 12215 } 12216 } 12217 12218 if (dowait) { 12219 chan_misdn_log(2, 0, "Waiting for '%d' seconds\n", timeout); 12220 ast_safe_sleep(chan, timeout * 1000); 12221 } 12222 12223 return 0; 12224 }
static void misdn_copy_redirecting_from_ast | ( | struct misdn_bchannel * | bc, | |
struct ast_channel * | ast | |||
) | [static] |
Definition at line 6317 of file chan_misdn.c.
References chan_list::ast, ast_copy_string(), ast_to_misdn_plan(), ast_to_misdn_pres(), ast_to_misdn_reason(), ast_to_misdn_screen(), ast_to_misdn_ton(), chan_list::bc, ast_party_redirecting::count, misdn_party_redirecting::count, ast_party_redirecting::from, misdn_party_redirecting::from, ast_party_id::name, misdn_party_id::name, misdn_party_id::number, ast_party_id::number, misdn_party_id::number_plan, misdn_party_id::number_type, NUMPLAN_UNKNOWN, NUMTYPE_UNKNOWN, ast_party_number::plan, ast_party_number::presentation, misdn_party_id::presentation, ast_party_redirecting::reason, misdn_party_redirecting::reason, ast_channel::redirecting, misdn_bchannel::redirecting, S_COR, S_OR, misdn_party_id::screening, ast_party_number::str, ast_party_name::str, ast_party_redirecting::to, misdn_party_redirecting::to, ast_party_number::valid, and ast_party_name::valid.
Referenced by misdn_call(), and misdn_update_redirecting().
06318 { 06319 ast_copy_string(bc->redirecting.from.name, 06320 S_COR(ast->redirecting.from.name.valid, ast->redirecting.from.name.str, ""), 06321 sizeof(bc->redirecting.from.name)); 06322 if (ast->redirecting.from.number.valid) { 06323 ast_copy_string(bc->redirecting.from.number, S_OR(ast->redirecting.from.number.str, ""), 06324 sizeof(bc->redirecting.from.number)); 06325 bc->redirecting.from.presentation = ast_to_misdn_pres(ast->redirecting.from.number.presentation); 06326 bc->redirecting.from.screening = ast_to_misdn_screen(ast->redirecting.from.number.presentation); 06327 bc->redirecting.from.number_type = ast_to_misdn_ton(ast->redirecting.from.number.plan); 06328 bc->redirecting.from.number_plan = ast_to_misdn_plan(ast->redirecting.from.number.plan); 06329 } else { 06330 bc->redirecting.from.number[0] = '\0'; 06331 bc->redirecting.from.presentation = 0;/* Allowed */ 06332 bc->redirecting.from.screening = 0;/* Unscreened */ 06333 bc->redirecting.from.number_type = NUMTYPE_UNKNOWN; 06334 bc->redirecting.from.number_plan = NUMPLAN_UNKNOWN; 06335 } 06336 06337 ast_copy_string(bc->redirecting.to.name, 06338 S_COR(ast->redirecting.to.name.valid, ast->redirecting.to.name.str, ""), 06339 sizeof(bc->redirecting.to.name)); 06340 if (ast->redirecting.to.number.valid) { 06341 ast_copy_string(bc->redirecting.to.number, S_OR(ast->redirecting.to.number.str, ""), 06342 sizeof(bc->redirecting.to.number)); 06343 bc->redirecting.to.presentation = ast_to_misdn_pres(ast->redirecting.to.number.presentation); 06344 bc->redirecting.to.screening = ast_to_misdn_screen(ast->redirecting.to.number.presentation); 06345 bc->redirecting.to.number_type = ast_to_misdn_ton(ast->redirecting.to.number.plan); 06346 bc->redirecting.to.number_plan = ast_to_misdn_plan(ast->redirecting.to.number.plan); 06347 } else { 06348 bc->redirecting.to.number[0] = '\0'; 06349 bc->redirecting.to.presentation = 0;/* Allowed */ 06350 bc->redirecting.to.screening = 0;/* Unscreened */ 06351 bc->redirecting.to.number_type = NUMTYPE_UNKNOWN; 06352 bc->redirecting.to.number_plan = NUMPLAN_UNKNOWN; 06353 } 06354 06355 bc->redirecting.reason = ast_to_misdn_reason(ast->redirecting.reason); 06356 bc->redirecting.count = ast->redirecting.count; 06357 }
static void misdn_copy_redirecting_to_ast | ( | struct ast_channel * | ast, | |
const struct misdn_party_redirecting * | redirect, | |||
char * | tag | |||
) | [static] |
Definition at line 6369 of file chan_misdn.c.
References ast_channel_set_redirecting(), ast_party_redirecting_set_init(), misdn_party_redirecting::count, ast_party_redirecting::count, misdn_party_redirecting::from, ast_party_redirecting::from, misdn_to_ast_plan(), misdn_to_ast_pres(), misdn_to_ast_reason(), misdn_to_ast_screen(), misdn_to_ast_ton(), misdn_party_id::number, ast_party_id::number, misdn_party_id::number_plan, misdn_party_id::number_type, ast_party_number::plan, misdn_party_id::presentation, ast_party_number::presentation, misdn_party_redirecting::reason, ast_party_redirecting::reason, ast_channel::redirecting, misdn_party_id::screening, ast_party_number::str, ast_party_id::tag, misdn_party_redirecting::to, ast_party_redirecting::to, update_redirecting(), and ast_party_number::valid.
Referenced by cb_events(), and misdn_facility_ie_handler().
06370 { 06371 struct ast_party_redirecting redirecting; 06372 struct ast_set_party_redirecting update_redirecting; 06373 06374 ast_party_redirecting_set_init(&redirecting, &ast->redirecting); 06375 memset(&update_redirecting, 0, sizeof(update_redirecting)); 06376 06377 update_redirecting.from.number = 1; 06378 redirecting.from.number.valid = 1; 06379 redirecting.from.number.str = (char *) redirect->from.number; 06380 redirecting.from.number.plan = 06381 misdn_to_ast_ton(redirect->from.number_type) 06382 | misdn_to_ast_plan(redirect->from.number_plan); 06383 redirecting.from.number.presentation = 06384 misdn_to_ast_pres(redirect->from.presentation) 06385 | misdn_to_ast_screen(redirect->from.screening); 06386 redirecting.from.tag = tag; 06387 06388 update_redirecting.to.number = 1; 06389 redirecting.to.number.valid = 1; 06390 redirecting.to.number.str = (char *) redirect->to.number; 06391 redirecting.to.number.plan = 06392 misdn_to_ast_ton(redirect->to.number_type) 06393 | misdn_to_ast_plan(redirect->to.number_plan); 06394 redirecting.to.number.presentation = 06395 misdn_to_ast_pres(redirect->to.presentation) 06396 | misdn_to_ast_screen(redirect->to.screening); 06397 redirecting.to.tag = tag; 06398 06399 redirecting.reason = misdn_to_ast_reason(redirect->reason); 06400 redirecting.count = redirect->count; 06401 06402 ast_channel_set_redirecting(ast, &redirecting, &update_redirecting); 06403 }
static int misdn_digit_begin | ( | struct ast_channel * | chan, | |
char | digit | |||
) | [static] |
Definition at line 6839 of file chan_misdn.c.
06840 { 06841 /* XXX Modify this callback to support Asterisk controlling the length of DTMF */ 06842 return 0; 06843 }
static int misdn_digit_end | ( | struct ast_channel * | ast, | |
char | digit, | |||
unsigned int | duration | |||
) | [static] |
Definition at line 6845 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.
06846 { 06847 struct chan_list *p; 06848 struct misdn_bchannel *bc; 06849 char buf[2] = { digit, 0 }; 06850 06851 if (!ast || !(p = MISDN_ASTERISK_TECH_PVT(ast))) { 06852 return -1; 06853 } 06854 06855 bc = p->bc; 06856 chan_misdn_log(1, bc ? bc->port : 0, "* IND : Digit %c\n", digit); 06857 06858 if (!bc) { 06859 ast_log(LOG_WARNING, " --> !! Got Digit Event without having bchannel Object\n"); 06860 return -1; 06861 } 06862 06863 switch (p->state) { 06864 case MISDN_CALLING: 06865 if (strlen(bc->infos_pending) < sizeof(bc->infos_pending) - 1) { 06866 strncat(bc->infos_pending, buf, sizeof(bc->infos_pending) - strlen(bc->infos_pending) - 1); 06867 } 06868 break; 06869 case MISDN_CALLING_ACKNOWLEDGE: 06870 ast_copy_string(bc->info_dad, buf, sizeof(bc->info_dad)); 06871 if (strlen(bc->dialed.number) < sizeof(bc->dialed.number) - 1) { 06872 strncat(bc->dialed.number, buf, sizeof(bc->dialed.number) - strlen(bc->dialed.number) - 1); 06873 } 06874 ast_copy_string(p->ast->exten, bc->dialed.number, sizeof(p->ast->exten)); 06875 misdn_lib_send_event(bc, EVENT_INFORMATION); 06876 break; 06877 default: 06878 if (bc->send_dtmf) { 06879 send_digit_to_chan(p, digit); 06880 } 06881 break; 06882 } 06883 06884 return 0; 06885 }
static int misdn_facility_exec | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Definition at line 12029 of file chan_misdn.c.
References args, AST_APP_ARG, AST_DECLARE_APP_ARGS, ast_log(), AST_STANDARD_APP_ARGS, ast_strdupa, ast_strlen_zero(), chan_list::bc, chan_misdn_log(), EVENT_FACILITY, misdn_bchannel::fac_out, LOG_WARNING, MISDN_ASTERISK_TECH_PVT, misdn_lib_send_event(), misdn_type, misdn_bchannel::port, print_facility(), ast_channel::tech, and ast_channel_tech::type.
Referenced by load_module().
12030 { 12031 struct chan_list *ch = MISDN_ASTERISK_TECH_PVT(chan); 12032 char *parse; 12033 unsigned max_len; 12034 12035 AST_DECLARE_APP_ARGS(args, 12036 AST_APP_ARG(facility_type); 12037 AST_APP_ARG(arg)[99]; 12038 ); 12039 12040 chan_misdn_log(0, 0, "TYPE: %s\n", chan->tech->type); 12041 12042 if (strcasecmp(chan->tech->type, misdn_type)) { 12043 ast_log(LOG_WARNING, "misdn_facility only makes sense with %s channels!\n", misdn_type); 12044 return -1; 12045 } 12046 12047 if (ast_strlen_zero((char *) data)) { 12048 ast_log(LOG_WARNING, "misdn_facility requires arguments: facility_type[,<args>]\n"); 12049 return -1; 12050 } 12051 12052 parse = ast_strdupa(data); 12053 AST_STANDARD_APP_ARGS(args, parse); 12054 12055 if (ast_strlen_zero(args.facility_type)) { 12056 ast_log(LOG_WARNING, "misdn_facility requires arguments: facility_type[,<args>]\n"); 12057 return -1; 12058 } 12059 12060 if (!strcasecmp(args.facility_type, "calldeflect")) { 12061 if (ast_strlen_zero(args.arg[0])) { 12062 ast_log(LOG_WARNING, "Facility: Call Deflection requires an argument: Number\n"); 12063 } 12064 12065 #if defined(AST_MISDN_ENHANCEMENTS) 12066 max_len = sizeof(ch->bc->fac_out.u.CallDeflection.Component.Invoke.Deflection.Party.Number) - 1; 12067 if (max_len < strlen(args.arg[0])) { 12068 ast_log(LOG_WARNING, 12069 "Facility: Number argument too long (up to %u digits are allowed). Ignoring.\n", 12070 max_len); 12071 return 0; 12072 } 12073 ch->bc->fac_out.Function = Fac_CallDeflection; 12074 ch->bc->fac_out.u.CallDeflection.InvokeID = ++misdn_invoke_id; 12075 ch->bc->fac_out.u.CallDeflection.ComponentType = FacComponent_Invoke; 12076 ch->bc->fac_out.u.CallDeflection.Component.Invoke.PresentationAllowedToDivertedToUserPresent = 1; 12077 ch->bc->fac_out.u.CallDeflection.Component.Invoke.PresentationAllowedToDivertedToUser = 0; 12078 ch->bc->fac_out.u.CallDeflection.Component.Invoke.Deflection.Party.Type = 0;/* unknown */ 12079 ch->bc->fac_out.u.CallDeflection.Component.Invoke.Deflection.Party.LengthOfNumber = strlen(args.arg[0]); 12080 strcpy((char *) ch->bc->fac_out.u.CallDeflection.Component.Invoke.Deflection.Party.Number, args.arg[0]); 12081 ch->bc->fac_out.u.CallDeflection.Component.Invoke.Deflection.Subaddress.Length = 0; 12082 12083 #else /* !defined(AST_MISDN_ENHANCEMENTS) */ 12084 12085 max_len = sizeof(ch->bc->fac_out.u.CDeflection.DeflectedToNumber) - 1; 12086 if (max_len < strlen(args.arg[0])) { 12087 ast_log(LOG_WARNING, 12088 "Facility: Number argument too long (up to %u digits are allowed). Ignoring.\n", 12089 max_len); 12090 return 0; 12091 } 12092 ch->bc->fac_out.Function = Fac_CD; 12093 ch->bc->fac_out.u.CDeflection.PresentationAllowed = 0; 12094 //ch->bc->fac_out.u.CDeflection.DeflectedToSubaddress[0] = 0; 12095 strcpy((char *) ch->bc->fac_out.u.CDeflection.DeflectedToNumber, args.arg[0]); 12096 #endif /* !defined(AST_MISDN_ENHANCEMENTS) */ 12097 12098 /* Send message */ 12099 print_facility(&ch->bc->fac_out, ch->bc); 12100 misdn_lib_send_event(ch->bc, EVENT_FACILITY); 12101 #if defined(AST_MISDN_ENHANCEMENTS) 12102 } else if (!strcasecmp(args.facility_type, "callrerouteing") 12103 || !strcasecmp(args.facility_type, "callrerouting")) { 12104 if (ast_strlen_zero(args.arg[0])) { 12105 ast_log(LOG_WARNING, "Facility: Call rerouting requires an argument: Number\n"); 12106 } 12107 12108 max_len = sizeof(ch->bc->fac_out.u.CallRerouteing.Component.Invoke.CalledAddress.Party.Number) - 1; 12109 if (max_len < strlen(args.arg[0])) { 12110 ast_log(LOG_WARNING, 12111 "Facility: Number argument too long (up to %u digits are allowed). Ignoring.\n", 12112 max_len); 12113 return 0; 12114 } 12115 ch->bc->fac_out.Function = Fac_CallRerouteing; 12116 ch->bc->fac_out.u.CallRerouteing.InvokeID = ++misdn_invoke_id; 12117 ch->bc->fac_out.u.CallRerouteing.ComponentType = FacComponent_Invoke; 12118 12119 ch->bc->fac_out.u.CallRerouteing.Component.Invoke.ReroutingReason = 0;/* unknown */ 12120 ch->bc->fac_out.u.CallRerouteing.Component.Invoke.ReroutingCounter = 1; 12121 12122 ch->bc->fac_out.u.CallRerouteing.Component.Invoke.CalledAddress.Party.Type = 0;/* unknown */ 12123 ch->bc->fac_out.u.CallRerouteing.Component.Invoke.CalledAddress.Party.LengthOfNumber = strlen(args.arg[0]); 12124 strcpy((char *) ch->bc->fac_out.u.CallRerouteing.Component.Invoke.CalledAddress.Party.Number, args.arg[0]); 12125 ch->bc->fac_out.u.CallRerouteing.Component.Invoke.CalledAddress.Subaddress.Length = 0; 12126 12127 ch->bc->fac_out.u.CallRerouteing.Component.Invoke.CallingPartySubaddress.Length = 0; 12128 12129 /* 0x90 0x90 0xa3 3.1 kHz audio, circuit mode, 64kbit/sec, level1/a-Law */ 12130 ch->bc->fac_out.u.CallRerouteing.Component.Invoke.Q931ie.Bc.Length = 3; 12131 ch->bc->fac_out.u.CallRerouteing.Component.Invoke.Q931ie.Bc.Contents[0] = 0x90; 12132 ch->bc->fac_out.u.CallRerouteing.Component.Invoke.Q931ie.Bc.Contents[1] = 0x90; 12133 ch->bc->fac_out.u.CallRerouteing.Component.Invoke.Q931ie.Bc.Contents[2] = 0xa3; 12134 ch->bc->fac_out.u.CallRerouteing.Component.Invoke.Q931ie.Hlc.Length = 0; 12135 ch->bc->fac_out.u.CallRerouteing.Component.Invoke.Q931ie.Llc.Length = 0; 12136 ch->bc->fac_out.u.CallRerouteing.Component.Invoke.Q931ie.UserInfo.Length = 0; 12137 12138 ch->bc->fac_out.u.CallRerouteing.Component.Invoke.LastRerouting.Type = 1;/* presentationRestricted */ 12139 ch->bc->fac_out.u.CallRerouteing.Component.Invoke.SubscriptionOption = 0;/* no notification to caller */ 12140 12141 /* Send message */ 12142 print_facility(&ch->bc->fac_out, ch->bc); 12143 misdn_lib_send_event(ch->bc, EVENT_FACILITY); 12144 #endif /* defined(AST_MISDN_ENHANCEMENTS) */ 12145 } else { 12146 chan_misdn_log(1, ch->bc->port, "Unknown Facility: %s\n", args.facility_type); 12147 } 12148 12149 return 0; 12150 }
static void misdn_facility_ie_handler | ( | enum event_e | event, | |
struct misdn_bchannel * | bc, | |||
struct chan_list * | ch | |||
) | [static] |
Definition at line 9053 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().
09054 { 09055 #if defined(AST_MISDN_ENHANCEMENTS) 09056 const char *diagnostic_msg; 09057 struct misdn_cc_record *cc_record; 09058 char buf[32]; 09059 struct misdn_party_id party_id; 09060 long new_record_id; 09061 #endif /* defined(AST_MISDN_ENHANCEMENTS) */ 09062 09063 print_facility(&bc->fac_in, bc); 09064 switch (bc->fac_in.Function) { 09065 #if defined(AST_MISDN_ENHANCEMENTS) 09066 case Fac_ActivationDiversion: 09067 switch (bc->fac_in.u.ActivationDiversion.ComponentType) { 09068 case FacComponent_Result: 09069 /* Positive ACK to activation */ 09070 /* We don't handle this yet */ 09071 break; 09072 default: 09073 chan_misdn_log(0, bc->port," --> not yet handled: facility type:0x%04X\n", 09074 bc->fac_in.Function); 09075 break; 09076 } 09077 break; 09078 case Fac_DeactivationDiversion: 09079 switch (bc->fac_in.u.DeactivationDiversion.ComponentType) { 09080 case FacComponent_Result: 09081 /* Positive ACK to deactivation */ 09082 /* We don't handle this yet */ 09083 break; 09084 default: 09085 chan_misdn_log(0, bc->port," --> not yet handled: facility type:0x%04X\n", 09086 bc->fac_in.Function); 09087 break; 09088 } 09089 break; 09090 case Fac_ActivationStatusNotificationDiv: 09091 /* Sent to other MSN numbers on the line when a user activates call forwarding. */ 09092 /* Sent in the first call control message of an outgoing call from the served user. */ 09093 /* We do not have anything to do for this message. */ 09094 break; 09095 case Fac_DeactivationStatusNotificationDiv: 09096 /* Sent to other MSN numbers on the line when a user deactivates call forwarding. */ 09097 /* We do not have anything to do for this message. */ 09098 break; 09099 #if 0 /* We don't handle this yet */ 09100 case Fac_InterrogationDiversion: 09101 /* We don't handle this yet */ 09102 break; 09103 case Fac_InterrogateServedUserNumbers: 09104 /* We don't handle this yet */ 09105 break; 09106 #endif /* We don't handle this yet */ 09107 case Fac_DiversionInformation: 09108 /* Sent to the served user when a call is forwarded. */ 09109 /* We do not have anything to do for this message. */ 09110 break; 09111 case Fac_CallDeflection: 09112 if (ch && ch->ast) { 09113 switch (bc->fac_in.u.CallDeflection.ComponentType) { 09114 case FacComponent_Invoke: 09115 ast_copy_string(bc->redirecting.from.number, bc->dialed.number, 09116 sizeof(bc->redirecting.from.number)); 09117 bc->redirecting.from.name[0] = 0; 09118 bc->redirecting.from.number_plan = bc->dialed.number_plan; 09119 bc->redirecting.from.number_type = bc->dialed.number_type; 09120 bc->redirecting.from.screening = 0;/* Unscreened */ 09121 if (bc->fac_in.u.CallDeflection.Component.Invoke.PresentationAllowedToDivertedToUserPresent) { 09122 bc->redirecting.from.presentation = 09123 bc->fac_in.u.CallDeflection.Component.Invoke.PresentationAllowedToDivertedToUser 09124 ? 0 /* Allowed */ : 1 /* Restricted */; 09125 } else { 09126 bc->redirecting.from.presentation = 0;/* Allowed */ 09127 } 09128 09129 /* Add configured prefix to the call deflection number */ 09130 memset(&party_id, 0, sizeof(party_id)); 09131 misdn_PartyNumber_extract(&party_id, 09132 &bc->fac_in.u.CallDeflection.Component.Invoke.Deflection.Party); 09133 misdn_add_number_prefix(bc->port, party_id.number_type, 09134 party_id.number, sizeof(party_id.number)); 09135 //party_id.presentation = 0;/* Allowed */ 09136 //party_id.screening = 0;/* Unscreened */ 09137 bc->redirecting.to = party_id; 09138 09139 ++bc->redirecting.count; 09140 bc->redirecting.reason = mISDN_REDIRECTING_REASON_DEFLECTION; 09141 09142 misdn_copy_redirecting_to_ast(ch->ast, &bc->redirecting, bc->incoming_cid_tag); 09143 ast_string_field_set(ch->ast, call_forward, bc->redirecting.to.number); 09144 09145 /* Send back positive ACK */ 09146 #if 1 09147 /* 09148 * Since there are no return result arguments it must be a 09149 * generic result message. ETSI 300-196 09150 */ 09151 bc->fac_out.Function = Fac_RESULT; 09152 bc->fac_out.u.RESULT.InvokeID = bc->fac_in.u.CallDeflection.InvokeID; 09153 #else 09154 bc->fac_out.Function = Fac_CallDeflection; 09155 bc->fac_out.u.CallDeflection.InvokeID = bc->fac_in.u.CallDeflection.InvokeID; 09156 bc->fac_out.u.CallDeflection.ComponentType = FacComponent_Result; 09157 #endif 09158 print_facility(&bc->fac_out, bc); 09159 misdn_lib_send_event(bc, EVENT_DISCONNECT); 09160 09161 /* This line is BUSY to further attempts by this dialing attempt. */ 09162 ast_queue_control(ch->ast, AST_CONTROL_BUSY); 09163 break; 09164 09165 case FacComponent_Result: 09166 /* Positive ACK to call deflection */ 09167 /* 09168 * Sent in DISCONNECT or FACILITY message depending upon network option. 09169 * It is in the FACILITY message if the call is still offered to the user 09170 * while trying to alert the deflected to party. 09171 */ 09172 /* Ignore the ACK */ 09173 break; 09174 09175 default: 09176 break; 09177 } 09178 } 09179 break; 09180 #if 0 /* We don't handle this yet */ 09181 case Fac_CallRerouteing: 09182 /* Private-Public ISDN interworking message */ 09183 /* We don't handle this yet */ 09184 break; 09185 #endif /* We don't handle this yet */ 09186 case Fac_DivertingLegInformation1: 09187 /* Private-Public ISDN interworking message */ 09188 bc->div_leg_3_rx_wanted = 0; 09189 if (ch && ch->ast) { 09190 bc->redirecting.reason = 09191 diversion_reason_to_misdn(bc->fac_in.u.DivertingLegInformation1.DiversionReason); 09192 if (bc->fac_in.u.DivertingLegInformation1.DivertedToPresent) { 09193 misdn_PresentedNumberUnscreened_extract(&bc->redirecting.to, 09194 &bc->fac_in.u.DivertingLegInformation1.DivertedTo); 09195 09196 /* Add configured prefix to redirecting.to.number */ 09197 misdn_add_number_prefix(bc->port, bc->redirecting.to.number_type, 09198 bc->redirecting.to.number, sizeof(bc->redirecting.to.number)); 09199 } else { 09200 bc->redirecting.to.number[0] = '\0'; 09201 bc->redirecting.to.number_plan = NUMPLAN_ISDN; 09202 bc->redirecting.to.number_type = NUMTYPE_UNKNOWN; 09203 bc->redirecting.to.presentation = 1;/* restricted */ 09204 bc->redirecting.to.screening = 0;/* unscreened */ 09205 } 09206 misdn_copy_redirecting_to_ast(ch->ast, &bc->redirecting, bc->incoming_cid_tag); 09207 bc->div_leg_3_rx_wanted = 1; 09208 } 09209 break; 09210 case Fac_DivertingLegInformation2: 09211 /* Private-Public ISDN interworking message */ 09212 switch (event) { 09213 case EVENT_SETUP: 09214 /* Comes in on a SETUP with redirecting.from information */ 09215 bc->div_leg_3_tx_pending = 1; 09216 if (ch && ch->ast) { 09217 /* 09218 * Setup the redirecting.to informtion so we can identify 09219 * if the user wants to manually supply the COLR for this 09220 * redirected to number if further redirects could happen. 09221 * 09222 * All the user needs to do is set the REDIRECTING(to-pres) 09223 * to the COLR and REDIRECTING(to-num) = ${EXTEN} to be safe 09224 * after determining that the incoming call was redirected by 09225 * checking if there is a REDIRECTING(from-num). 09226 */ 09227 ast_copy_string(bc->redirecting.to.number, bc->dialed.number, 09228 sizeof(bc->redirecting.to.number)); 09229 bc->redirecting.to.number_plan = bc->dialed.number_plan; 09230 bc->redirecting.to.number_type = bc->dialed.number_type; 09231 bc->redirecting.to.presentation = 1;/* restricted */ 09232 bc->redirecting.to.screening = 0;/* unscreened */ 09233 09234 bc->redirecting.reason = 09235 diversion_reason_to_misdn(bc->fac_in.u.DivertingLegInformation2.DiversionReason); 09236 bc->redirecting.count = bc->fac_in.u.DivertingLegInformation2.DiversionCounter; 09237 if (bc->fac_in.u.DivertingLegInformation2.DivertingPresent) { 09238 /* This information is redundant if there was a redirecting ie in the SETUP. */ 09239 misdn_PresentedNumberUnscreened_extract(&bc->redirecting.from, 09240 &bc->fac_in.u.DivertingLegInformation2.Diverting); 09241 09242 /* Add configured prefix to redirecting.from.number */ 09243 misdn_add_number_prefix(bc->port, bc->redirecting.from.number_type, 09244 bc->redirecting.from.number, sizeof(bc->redirecting.from.number)); 09245 } 09246 #if 0 09247 if (bc->fac_in.u.DivertingLegInformation2.OriginalCalledPresent) { 09248 /* We have no place to put the OriginalCalled number */ 09249 } 09250 #endif 09251 misdn_copy_redirecting_to_ast(ch->ast, &bc->redirecting, bc->incoming_cid_tag); 09252 } 09253 break; 09254 default: 09255 chan_misdn_log(0, bc->port," --> Expected in a SETUP message: facility type:0x%04X\n", 09256 bc->fac_in.Function); 09257 break; 09258 } 09259 break; 09260 case Fac_DivertingLegInformation3: 09261 /* Private-Public ISDN interworking message */ 09262 if (bc->div_leg_3_rx_wanted) { 09263 bc->div_leg_3_rx_wanted = 0; 09264 09265 if (ch && ch->ast) { 09266 ch->ast->redirecting.to.number.presentation = 09267 bc->fac_in.u.DivertingLegInformation3.PresentationAllowedIndicator 09268 ? AST_PRES_ALLOWED | AST_PRES_USER_NUMBER_UNSCREENED 09269 : AST_PRES_RESTRICTED | AST_PRES_USER_NUMBER_UNSCREENED; 09270 ast_channel_queue_redirecting_update(ch->ast, &ch->ast->redirecting, NULL); 09271 } 09272 } 09273 break; 09274 09275 #else /* !defined(AST_MISDN_ENHANCEMENTS) */ 09276 09277 case Fac_CD: 09278 if (ch && ch->ast) { 09279 ast_copy_string(bc->redirecting.from.number, bc->dialed.number, 09280 sizeof(bc->redirecting.from.number)); 09281 bc->redirecting.from.name[0] = 0; 09282 bc->redirecting.from.number_plan = bc->dialed.number_plan; 09283 bc->redirecting.from.number_type = bc->dialed.number_type; 09284 bc->redirecting.from.screening = 0;/* Unscreened */ 09285 bc->redirecting.from.presentation = 09286 bc->fac_in.u.CDeflection.PresentationAllowed 09287 ? 0 /* Allowed */ : 1 /* Restricted */; 09288 09289 ast_copy_string(bc->redirecting.to.number, 09290 (char *) bc->fac_in.u.CDeflection.DeflectedToNumber, 09291 sizeof(bc->redirecting.to.number)); 09292 bc->redirecting.to.name[0] = 0; 09293 bc->redirecting.to.number_plan = NUMPLAN_UNKNOWN; 09294 bc->redirecting.to.number_type = NUMTYPE_UNKNOWN; 09295 bc->redirecting.to.presentation = 0;/* Allowed */ 09296 bc->redirecting.to.screening = 0;/* Unscreened */ 09297 09298 ++bc->redirecting.count; 09299 bc->redirecting.reason = mISDN_REDIRECTING_REASON_DEFLECTION; 09300 09301 misdn_copy_redirecting_to_ast(ch->ast, &bc->redirecting, bc->incoming_cid_tag); 09302 ast_string_field_set(ch->ast, call_forward, bc->redirecting.to.number); 09303 09304 misdn_lib_send_event(bc, EVENT_DISCONNECT); 09305 09306 /* This line is BUSY to further attempts by this dialing attempt. */ 09307 ast_queue_control(ch->ast, AST_CONTROL_BUSY); 09308 } 09309 break; 09310 #endif /* !defined(AST_MISDN_ENHANCEMENTS) */ 09311 case Fac_AOCDCurrency: 09312 if (ch && ch->ast) { 09313 bc->AOCDtype = Fac_AOCDCurrency; 09314 memcpy(&bc->AOCD.currency, &bc->fac_in.u.AOCDcur, sizeof(bc->AOCD.currency)); 09315 bc->AOCD_need_export = 1; 09316 export_aoc_vars(ch->originator, ch->ast, bc); 09317 } 09318 break; 09319 case Fac_AOCDChargingUnit: 09320 if (ch && ch->ast) { 09321 bc->AOCDtype = Fac_AOCDChargingUnit; 09322 memcpy(&bc->AOCD.chargingUnit, &bc->fac_in.u.AOCDchu, sizeof(bc->AOCD.chargingUnit)); 09323 bc->AOCD_need_export = 1; 09324 export_aoc_vars(ch->originator, ch->ast, bc); 09325 } 09326 break; 09327 #if defined(AST_MISDN_ENHANCEMENTS) 09328 case Fac_ERROR: 09329 diagnostic_msg = misdn_to_str_error_code(bc->fac_in.u.ERROR.errorValue); 09330 chan_misdn_log(1, bc->port, " --> Facility error code: %s\n", diagnostic_msg); 09331 switch (event) { 09332 case EVENT_DISCONNECT: 09333 case EVENT_RELEASE: 09334 case EVENT_RELEASE_COMPLETE: 09335 /* Possible call failure as a result of Fac_CCBSCall/Fac_CCBS_T_Call */ 09336 if (ch && ch->peer) { 09337 misdn_cc_set_peer_var(ch->peer, MISDN_ERROR_MSG, diagnostic_msg); 09338 } 09339 break; 09340 default: 09341 break; 09342 } 09343 AST_LIST_LOCK(&misdn_cc_records_db); 09344 cc_record = misdn_cc_find_by_invoke(bc->port, bc->fac_in.u.ERROR.invokeId); 09345 if (cc_record) { 09346 cc_record->outstanding_message = 0; 09347 cc_record->error_code = bc->fac_in.u.ERROR.errorValue; 09348 } 09349 AST_LIST_UNLOCK(&misdn_cc_records_db); 09350 break; 09351 case Fac_REJECT: 09352 diagnostic_msg = misdn_to_str_reject_code(bc->fac_in.u.REJECT.Code); 09353 chan_misdn_log(1, bc->port, " --> Facility reject code: %s\n", diagnostic_msg); 09354 switch (event) { 09355 case EVENT_DISCONNECT: 09356 case EVENT_RELEASE: 09357 case EVENT_RELEASE_COMPLETE: 09358 /* Possible call failure as a result of Fac_CCBSCall/Fac_CCBS_T_Call */ 09359 if (ch && ch->peer) { 09360 misdn_cc_set_peer_var(ch->peer, MISDN_ERROR_MSG, diagnostic_msg); 09361 } 09362 break; 09363 default: 09364 break; 09365 } 09366 if (bc->fac_in.u.REJECT.InvokeIDPresent) { 09367 AST_LIST_LOCK(&misdn_cc_records_db); 09368 cc_record = misdn_cc_find_by_invoke(bc->port, bc->fac_in.u.REJECT.InvokeID); 09369 if (cc_record) { 09370 cc_record->outstanding_message = 0; 09371 cc_record->reject_code = bc->fac_in.u.REJECT.Code; 09372 } 09373 AST_LIST_UNLOCK(&misdn_cc_records_db); 09374 } 09375 break; 09376 case Fac_RESULT: 09377 AST_LIST_LOCK(&misdn_cc_records_db); 09378 cc_record = misdn_cc_find_by_invoke(bc->port, bc->fac_in.u.RESULT.InvokeID); 09379 if (cc_record) { 09380 cc_record->outstanding_message = 0; 09381 } 09382 AST_LIST_UNLOCK(&misdn_cc_records_db); 09383 break; 09384 #if 0 /* We don't handle this yet */ 09385 case Fac_EctExecute: 09386 /* We don't handle this yet */ 09387 break; 09388 case Fac_ExplicitEctExecute: 09389 /* We don't handle this yet */ 09390 break; 09391 case Fac_EctLinkIdRequest: 09392 /* We don't handle this yet */ 09393 break; 09394 #endif /* We don't handle this yet */ 09395 case Fac_SubaddressTransfer: 09396 /* We do not have anything to do for this message since we do not handle subaddreses. */ 09397 break; 09398 case Fac_RequestSubaddress: 09399 /* 09400 * We do not have anything to do for this message since we do not handle subaddreses. 09401 * However, we do care about some other ie's that should be present. 09402 */ 09403 if (bc->redirecting.to_changed) { 09404 /* Add configured prefix to redirecting.to.number */ 09405 misdn_add_number_prefix(bc->port, bc->redirecting.to.number_type, 09406 bc->redirecting.to.number, sizeof(bc->redirecting.to.number)); 09407 } 09408 switch (bc->notify_description_code) { 09409 case mISDN_NOTIFY_CODE_INVALID: 09410 /* Notify ie was not present. */ 09411 bc->redirecting.to_changed = 0; 09412 break; 09413 case mISDN_NOTIFY_CODE_CALL_TRANSFER_ALERTING: 09414 /* 09415 * It would be preferable to update the connected line information 09416 * only when the message callStatus is active. However, the 09417 * optional redirection number may not be present in the active 09418 * message if an alerting message were received earlier. 09419 * 09420 * The consequences if we wind up sending two updates is benign. 09421 * The other end will think that it got transferred twice. 09422 */ 09423 if (!bc->redirecting.to_changed) { 09424 break; 09425 } 09426 bc->redirecting.to_changed = 0; 09427 if (!ch || !ch->ast) { 09428 break; 09429 } 09430 misdn_update_remote_party(ch->ast, &bc->redirecting.to, 09431 AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER_ALERTING, 09432 bc->incoming_cid_tag); 09433 break; 09434 case mISDN_NOTIFY_CODE_CALL_TRANSFER_ACTIVE: 09435 if (!bc->redirecting.to_changed) { 09436 break; 09437 } 09438 bc->redirecting.to_changed = 0; 09439 if (!ch || !ch->ast) { 09440 break; 09441 } 09442 misdn_update_remote_party(ch->ast, &bc->redirecting.to, 09443 AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER, bc->incoming_cid_tag); 09444 break; 09445 default: 09446 bc->redirecting.to_changed = 0; 09447 chan_misdn_log(0, bc->port," --> not yet handled: notify code:0x%02X\n", 09448 bc->notify_description_code); 09449 break; 09450 } 09451 bc->notify_description_code = mISDN_NOTIFY_CODE_INVALID; 09452 break; 09453 case Fac_EctInform: 09454 /* Private-Public ISDN interworking message */ 09455 if (ch && ch->ast && bc->fac_in.u.EctInform.RedirectionPresent) { 09456 /* Add configured prefix to the redirection number */ 09457 memset(&party_id, 0, sizeof(party_id)); 09458 misdn_PresentedNumberUnscreened_extract(&party_id, 09459 &bc->fac_in.u.EctInform.Redirection); 09460 misdn_add_number_prefix(bc->port, party_id.number_type, 09461 party_id.number, sizeof(party_id.number)); 09462 09463 /* 09464 * It would be preferable to update the connected line information 09465 * only when the message callStatus is active. However, the 09466 * optional redirection number may not be present in the active 09467 * message if an alerting message were received earlier. 09468 * 09469 * The consequences if we wind up sending two updates is benign. 09470 * The other end will think that it got transferred twice. 09471 */ 09472 misdn_update_remote_party(ch->ast, &party_id, 09473 (bc->fac_in.u.EctInform.Status == 0 /* alerting */) 09474 ? AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER_ALERTING 09475 : AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER, 09476 bc->incoming_cid_tag); 09477 } 09478 break; 09479 #if 0 /* We don't handle this yet */ 09480 case Fac_EctLoopTest: 09481 /* The use of this message is unclear on how it works to detect loops. */ 09482 /* We don't handle this yet */ 09483 break; 09484 #endif /* We don't handle this yet */ 09485 case Fac_CallInfoRetain: 09486 switch (event) { 09487 case EVENT_ALERTING: 09488 case EVENT_DISCONNECT: 09489 /* CCBS/CCNR is available */ 09490 if (ch && ch->peer) { 09491 AST_LIST_LOCK(&misdn_cc_records_db); 09492 if (ch->record_id == -1) { 09493 cc_record = misdn_cc_new(); 09494 } else { 09495 /* 09496 * We are doing a call-completion attempt 09497 * or the switch is sending us extra call-completion 09498 * availability indications (erroneously?). 09499 * 09500 * Assume that the network request retention option 09501 * is not on and that the current call-completion 09502 * request is disabled. 09503 */ 09504 cc_record = misdn_cc_find_by_id(ch->record_id); 09505 if (cc_record) { 09506 if (cc_record->ptp && cc_record->mode.ptp.bc) { 09507 /* 09508 * What? We are getting mixed messages from the 09509 * switch. We are currently setup for 09510 * point-to-point. Now we are switching to 09511 * point-to-multipoint. 09512 * 09513 * Close the call-completion signaling link 09514 */ 09515 cc_record->mode.ptp.bc->fac_out.Function = Fac_None; 09516 cc_record->mode.ptp.bc->out_cause = AST_CAUSE_NORMAL_CLEARING; 09517 misdn_lib_send_event(cc_record->mode.ptp.bc, EVENT_RELEASE_COMPLETE); 09518 } 09519 09520 /* 09521 * Resetup the existing record for a possible new 09522 * call-completion request. 09523 */ 09524 new_record_id = misdn_cc_record_id_new(); 09525 if (new_record_id < 0) { 09526 /* Looks like we must keep the old id anyway. */ 09527 } else { 09528 cc_record->record_id = new_record_id; 09529 ch->record_id = new_record_id; 09530 } 09531 cc_record->ptp = 0; 09532 cc_record->port = bc->port; 09533 memset(&cc_record->mode, 0, sizeof(cc_record->mode)); 09534 cc_record->mode.ptmp.linkage_id = bc->fac_in.u.CallInfoRetain.CallLinkageID; 09535 cc_record->invoke_id = ++misdn_invoke_id; 09536 cc_record->activated = 0; 09537 cc_record->outstanding_message = 0; 09538 cc_record->activation_requested = 0; 09539 cc_record->error_code = FacError_None; 09540 cc_record->reject_code = FacReject_None; 09541 memset(&cc_record->remote_user_free, 0, sizeof(cc_record->remote_user_free)); 09542 memset(&cc_record->b_free, 0, sizeof(cc_record->b_free)); 09543 cc_record->time_created = time(NULL); 09544 09545 cc_record = NULL; 09546 } else { 09547 /* 09548 * Where did the record go? We will have to recapture 09549 * the call setup information. Unfortunately, some 09550 * setup information may have been changed. 09551 */ 09552 ch->record_id = -1; 09553 cc_record = misdn_cc_new(); 09554 } 09555 } 09556 if (cc_record) { 09557 ch->record_id = cc_record->record_id; 09558 cc_record->ptp = 0; 09559 cc_record->port = bc->port; 09560 cc_record->mode.ptmp.linkage_id = bc->fac_in.u.CallInfoRetain.CallLinkageID; 09561 09562 /* Record call information for possible call-completion attempt. */ 09563 cc_record->redial.caller = bc->caller; 09564 cc_record->redial.dialed = bc->dialed; 09565 cc_record->redial.setup_bc_hlc_llc = bc->setup_bc_hlc_llc; 09566 cc_record->redial.capability = bc->capability; 09567 cc_record->redial.hdlc = bc->hdlc; 09568 } 09569 AST_LIST_UNLOCK(&misdn_cc_records_db); 09570 09571 /* Set MISDN_CC_RECORD_ID in original channel */ 09572 if (ch->record_id != -1) { 09573 snprintf(buf, sizeof(buf), "%ld", ch->record_id); 09574 } else { 09575 buf[0] = 0; 09576 } 09577 misdn_cc_set_peer_var(ch->peer, MISDN_CC_RECORD_ID, buf); 09578 } 09579 break; 09580 default: 09581 chan_misdn_log(0, bc->port, 09582 " --> Expected in a DISCONNECT or ALERTING message: facility type:0x%04X\n", 09583 bc->fac_in.Function); 09584 break; 09585 } 09586 break; 09587 case Fac_CCBS_T_Call: 09588 case Fac_CCBSCall: 09589 switch (event) { 09590 case EVENT_SETUP: 09591 /* 09592 * This is a call completion retry call. 09593 * If we had anything to do we would do it here. 09594 */ 09595 break; 09596 default: 09597 chan_misdn_log(0, bc->port, " --> Expected in a SETUP message: facility type:0x%04X\n", 09598 bc->fac_in.Function); 09599 break; 09600 } 09601 break; 09602 case Fac_CCBSDeactivate: 09603 switch (bc->fac_in.u.CCBSDeactivate.ComponentType) { 09604 case FacComponent_Result: 09605 AST_LIST_LOCK(&misdn_cc_records_db); 09606 cc_record = misdn_cc_find_by_invoke(bc->port, bc->fac_in.u.CCBSDeactivate.InvokeID); 09607 if (cc_record) { 09608 cc_record->outstanding_message = 0; 09609 } 09610 AST_LIST_UNLOCK(&misdn_cc_records_db); 09611 break; 09612 09613 default: 09614 chan_misdn_log(0, bc->port, " --> not yet handled: facility type:0x%04X\n", 09615 bc->fac_in.Function); 09616 break; 09617 } 09618 break; 09619 case Fac_CCBSErase: 09620 AST_LIST_LOCK(&misdn_cc_records_db); 09621 cc_record = misdn_cc_find_by_reference(bc->port, bc->fac_in.u.CCBSErase.CCBSReference); 09622 if (cc_record) { 09623 misdn_cc_delete(cc_record); 09624 } 09625 AST_LIST_UNLOCK(&misdn_cc_records_db); 09626 break; 09627 case Fac_CCBSRemoteUserFree: 09628 misdn_cc_handle_remote_user_free(bc->port, &bc->fac_in); 09629 break; 09630 case Fac_CCBSBFree: 09631 misdn_cc_handle_b_free(bc->port, &bc->fac_in); 09632 break; 09633 case Fac_CCBSStatusRequest: 09634 misdn_cc_handle_ccbs_status_request(bc->port, &bc->fac_in); 09635 break; 09636 case Fac_EraseCallLinkageID: 09637 AST_LIST_LOCK(&misdn_cc_records_db); 09638 cc_record = misdn_cc_find_by_linkage(bc->port, 09639 bc->fac_in.u.EraseCallLinkageID.CallLinkageID); 09640 if (cc_record && !cc_record->activation_requested) { 09641 /* 09642 * The T-RETENTION timer expired before we requested 09643 * call completion activation. Call completion is no 09644 * longer available. 09645 */ 09646 misdn_cc_delete(cc_record); 09647 } 09648 AST_LIST_UNLOCK(&misdn_cc_records_db); 09649 break; 09650 case Fac_CCBSStopAlerting: 09651 /* We do not have anything to do for this message. */ 09652 break; 09653 case Fac_CCBSRequest: 09654 case Fac_CCNRRequest: 09655 switch (bc->fac_in.u.CCBSRequest.ComponentType) { 09656 case FacComponent_Result: 09657 AST_LIST_LOCK(&misdn_cc_records_db); 09658 cc_record = misdn_cc_find_by_invoke(bc->port, bc->fac_in.u.CCBSRequest.InvokeID); 09659 if (cc_record && !cc_record->ptp) { 09660 cc_record->outstanding_message = 0; 09661 cc_record->activated = 1; 09662 cc_record->mode.ptmp.recall_mode = bc->fac_in.u.CCBSRequest.Component.Result.RecallMode; 09663 cc_record->mode.ptmp.reference_id = bc->fac_in.u.CCBSRequest.Component.Result.CCBSReference; 09664 } 09665 AST_LIST_UNLOCK(&misdn_cc_records_db); 09666 break; 09667 09668 default: 09669 chan_misdn_log(0, bc->port, " --> not yet handled: facility type:0x%04X\n", 09670 bc->fac_in.Function); 09671 break; 09672 } 09673 break; 09674 #if 0 /* We don't handle this yet */ 09675 case Fac_CCBSInterrogate: 09676 case Fac_CCNRInterrogate: 09677 /* We don't handle this yet */ 09678 break; 09679 case Fac_StatusRequest: 09680 /* We don't handle this yet */ 09681 break; 09682 #endif /* We don't handle this yet */ 09683 #if 0 /* We don't handle this yet */ 09684 case Fac_CCBS_T_Suspend: 09685 case Fac_CCBS_T_Resume: 09686 /* We don't handle this yet */ 09687 break; 09688 #endif /* We don't handle this yet */ 09689 case Fac_CCBS_T_RemoteUserFree: 09690 misdn_cc_handle_T_remote_user_free(bc); 09691 break; 09692 case Fac_CCBS_T_Available: 09693 switch (event) { 09694 case EVENT_ALERTING: 09695 case EVENT_DISCONNECT: 09696 /* CCBS-T/CCNR-T is available */ 09697 if (ch && ch->peer) { 09698 int set_id = 1; 09699 09700 AST_LIST_LOCK(&misdn_cc_records_db); 09701 if (ch->record_id == -1) { 09702 cc_record = misdn_cc_new(); 09703 } else { 09704 /* 09705 * We are doing a call-completion attempt 09706 * or the switch is sending us extra call-completion 09707 * availability indications (erroneously?). 09708 */ 09709 cc_record = misdn_cc_find_by_id(ch->record_id); 09710 if (cc_record) { 09711 if (cc_record->ptp && cc_record->mode.ptp.retention_enabled) { 09712 /* 09713 * Call-completion is still activated. 09714 * The user does not have to request it again. 09715 */ 09716 chan_misdn_log(1, bc->port, " --> Call-completion request retention option is enabled\n"); 09717 09718 set_id = 0; 09719 } else { 09720 if (cc_record->ptp && cc_record->mode.ptp.bc) { 09721 /* 09722 * The network request retention option 09723 * is not on and the current call-completion 09724 * request is to be disabled. 09725 * 09726 * We should get here only if EVENT_DISCONNECT 09727 * 09728 * Close the call-completion signaling link 09729 */ 09730 cc_record->mode.ptp.bc->fac_out.Function = Fac_None; 09731 cc_record->mode.ptp.bc->out_cause = AST_CAUSE_NORMAL_CLEARING; 09732 misdn_lib_send_event(cc_record->mode.ptp.bc, EVENT_RELEASE_COMPLETE); 09733 } 09734 09735 /* 09736 * Resetup the existing record for a possible new 09737 * call-completion request. 09738 */ 09739 new_record_id = misdn_cc_record_id_new(); 09740 if (new_record_id < 0) { 09741 /* Looks like we must keep the old id anyway. */ 09742 } else { 09743 cc_record->record_id = new_record_id; 09744 ch->record_id = new_record_id; 09745 } 09746 cc_record->ptp = 1; 09747 cc_record->port = bc->port; 09748 memset(&cc_record->mode, 0, sizeof(cc_record->mode)); 09749 cc_record->invoke_id = ++misdn_invoke_id; 09750 cc_record->activated = 0; 09751 cc_record->outstanding_message = 0; 09752 cc_record->activation_requested = 0; 09753 cc_record->error_code = FacError_None; 09754 cc_record->reject_code = FacReject_None; 09755 memset(&cc_record->remote_user_free, 0, sizeof(cc_record->remote_user_free)); 09756 memset(&cc_record->b_free, 0, sizeof(cc_record->b_free)); 09757 cc_record->time_created = time(NULL); 09758 } 09759 cc_record = NULL; 09760 } else { 09761 /* 09762 * Where did the record go? We will have to recapture 09763 * the call setup information. Unfortunately, some 09764 * setup information may have been changed. 09765 */ 09766 ch->record_id = -1; 09767 cc_record = misdn_cc_new(); 09768 } 09769 } 09770 if (cc_record) { 09771 ch->record_id = cc_record->record_id; 09772 cc_record->ptp = 1; 09773 cc_record->port = bc->port; 09774 09775 /* Record call information for possible call-completion attempt. */ 09776 cc_record->redial.caller = bc->caller; 09777 cc_record->redial.dialed = bc->dialed; 09778 cc_record->redial.setup_bc_hlc_llc = bc->setup_bc_hlc_llc; 09779 cc_record->redial.capability = bc->capability; 09780 cc_record->redial.hdlc = bc->hdlc; 09781 } 09782 AST_LIST_UNLOCK(&misdn_cc_records_db); 09783 09784 /* Set MISDN_CC_RECORD_ID in original channel */ 09785 if (ch->record_id != -1 && set_id) { 09786 snprintf(buf, sizeof(buf), "%ld", ch->record_id); 09787 } else { 09788 buf[0] = 0; 09789 } 09790 misdn_cc_set_peer_var(ch->peer, MISDN_CC_RECORD_ID, buf); 09791 } 09792 break; 09793 default: 09794 chan_misdn_log(0, bc->port, 09795 " --> Expected in a DISCONNECT or ALERTING message: facility type:0x%04X\n", 09796 bc->fac_in.Function); 09797 break; 09798 } 09799 break; 09800 case Fac_CCBS_T_Request: 09801 case Fac_CCNR_T_Request: 09802 switch (bc->fac_in.u.CCBS_T_Request.ComponentType) { 09803 case FacComponent_Result: 09804 AST_LIST_LOCK(&misdn_cc_records_db); 09805 cc_record = misdn_cc_find_by_invoke(bc->port, bc->fac_in.u.CCBS_T_Request.InvokeID); 09806 if (cc_record && cc_record->ptp) { 09807 cc_record->outstanding_message = 0; 09808 cc_record->activated = 1; 09809 cc_record->mode.ptp.retention_enabled = 09810 cc_record->mode.ptp.requested_retention 09811 ? bc->fac_in.u.CCBS_T_Request.Component.Result.RetentionSupported 09812 ? 1 : 0 09813 : 0; 09814 } 09815 AST_LIST_UNLOCK(&misdn_cc_records_db); 09816 break; 09817 09818 case FacComponent_Invoke: 09819 /* We cannot be User-B in ptp mode. */ 09820 default: 09821 chan_misdn_log(0, bc->port, " --> not yet handled: facility type:0x%04X\n", 09822 bc->fac_in.Function); 09823 break; 09824 } 09825 break; 09826 09827 #endif /* defined(AST_MISDN_ENHANCEMENTS) */ 09828 case Fac_None: 09829 break; 09830 default: 09831 chan_misdn_log(0, bc->port, " --> not yet handled: facility type:0x%04X\n", 09832 bc->fac_in.Function); 09833 break; 09834 } 09835 }
static int misdn_fixup | ( | struct ast_channel * | oldast, | |
struct ast_channel * | ast | |||
) | [static] |
Definition at line 6888 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.
06889 { 06890 struct chan_list *p; 06891 06892 if (!ast || !(p = MISDN_ASTERISK_TECH_PVT(ast))) { 06893 return -1; 06894 } 06895 06896 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); 06897 06898 p->ast = ast; 06899 06900 return 0; 06901 }
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, state_array, 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 6162 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().
06163 { 06164 int number_type; 06165 06166 if (originator == ORG_MISDN) { 06167 /* ORIGINATOR MISDN (incoming call) */ 06168 06169 ast_copy_string(bc->connected.name, 06170 S_COR(ast->connected.id.name.valid, ast->connected.id.name.str, ""), 06171 sizeof(bc->connected.name)); 06172 if (ast->connected.id.number.valid) { 06173 ast_copy_string(bc->connected.number, S_OR(ast->connected.id.number.str, ""), 06174 sizeof(bc->connected.number)); 06175 bc->connected.presentation = ast_to_misdn_pres(ast->connected.id.number.presentation); 06176 bc->connected.screening = ast_to_misdn_screen(ast->connected.id.number.presentation); 06177 bc->connected.number_type = ast_to_misdn_ton(ast->connected.id.number.plan); 06178 bc->connected.number_plan = ast_to_misdn_plan(ast->connected.id.number.plan); 06179 } else { 06180 bc->connected.number[0] = '\0'; 06181 bc->connected.presentation = 0;/* Allowed */ 06182 bc->connected.screening = 0;/* Unscreened */ 06183 bc->connected.number_type = NUMTYPE_UNKNOWN; 06184 bc->connected.number_plan = NUMPLAN_UNKNOWN; 06185 } 06186 06187 misdn_cfg_get(bc->port, MISDN_CFG_CPNDIALPLAN, &number_type, sizeof(number_type)); 06188 if (0 <= number_type) { 06189 /* Force us to send in CONNECT message */ 06190 bc->connected.number_type = number_type; 06191 bc->connected.number_plan = NUMPLAN_ISDN; 06192 } 06193 debug_numtype(bc->port, bc->connected.number_type, "CTON"); 06194 } else { 06195 /* ORIGINATOR Asterisk (outgoing call) */ 06196 06197 ast_copy_string(bc->caller.name, 06198 S_COR(ast->connected.id.name.valid, ast->connected.id.name.str, ""), 06199 sizeof(bc->caller.name)); 06200 if (ast->connected.id.number.valid) { 06201 ast_copy_string(bc->caller.number, S_OR(ast->connected.id.number.str, ""), 06202 sizeof(bc->caller.number)); 06203 bc->caller.presentation = ast_to_misdn_pres(ast->connected.id.number.presentation); 06204 bc->caller.screening = ast_to_misdn_screen(ast->connected.id.number.presentation); 06205 bc->caller.number_type = ast_to_misdn_ton(ast->connected.id.number.plan); 06206 bc->caller.number_plan = ast_to_misdn_plan(ast->connected.id.number.plan); 06207 } else { 06208 bc->caller.number[0] = '\0'; 06209 bc->caller.presentation = 0;/* Allowed */ 06210 bc->caller.screening = 0;/* Unscreened */ 06211 bc->caller.number_type = NUMTYPE_UNKNOWN; 06212 bc->caller.number_plan = NUMPLAN_UNKNOWN; 06213 } 06214 06215 misdn_cfg_get(bc->port, MISDN_CFG_LOCALDIALPLAN, &number_type, sizeof(number_type)); 06216 if (0 <= number_type) { 06217 /* Force us to send in SETUP message */ 06218 bc->caller.number_type = number_type; 06219 bc->caller.number_plan = NUMPLAN_ISDN; 06220 } 06221 debug_numtype(bc->port, bc->caller.number_type, "LTON"); 06222 } 06223 }
static int misdn_hangup | ( | struct ast_channel * | ast | ) | [static] |
Definition at line 7044 of file chan_misdn.c.
References ast_channel::_state, chan_list::ast, AST_CAUSE_NORMAL_CLEARING, ast_copy_string(), ast_debug, ast_log(), ast_mutex_lock, ast_mutex_unlock, AST_STATE_RESERVED, chan_list::bc, ast_channel::caller, misdn_bchannel::cause, chan_list_unref, chan_misdn_log(), ast_channel::context, EVENT_DISCONNECT, EVENT_RELEASE, EVENT_RELEASE_COMPLETE, ast_channel::exten, ast_channel::hangupcause, hanguptone_indicate(), chan_list::hold, ast_party_caller::id, INFO_PI_INBAND_AVAILABLE, chan_list::l3id, LOG_NOTICE, LOG_WARNING, MISDN_ALERTING, MISDN_ASTERISK_TECH_PVT, MISDN_BUSY, MISDN_CALLING, MISDN_CALLING_ACKNOWLEDGE, misdn_chan_is_valid(), MISDN_CLEANING, MISDN_CONNECTED, MISDN_DIALING, MISDN_DISCONNECTED, misdn_get_ch_state(), MISDN_HOLD_DISCONNECT, MISDN_HOLD_IDLE, MISDN_INCOMING_SETUP, misdn_lib_find_held_bc(), misdn_lib_release(), misdn_lib_send_event(), MISDN_NOTHING, MISDN_PROCEEDING, MISDN_PROGRESS, ast_party_id::name, ast_channel::name, chan_list::need_busy, misdn_bchannel::need_disconnect, chan_list::need_hangup, chan_list::need_queue_hangup, misdn_bchannel::need_release, misdn_bchannel::nt, ast_party_id::number, ORG_AST, chan_list::originator, misdn_bchannel::out_cause, pbx_builtin_getvar_helper(), misdn_bchannel::pid, misdn_bchannel::port, hold_info::port, misdn_bchannel::progress_indicator, release_chan(), release_chan_early(), release_lock, start_bc_tones(), chan_list::state, hold_info::state, stop_bc_tones(), ast_party_number::str, ast_party_name::str, misdn_bchannel::uu, misdn_bchannel::uulen, ast_party_number::valid, and ast_party_name::valid.
07045 { 07046 struct chan_list *p; 07047 struct misdn_bchannel *bc; 07048 const char *var; 07049 07050 if (!ast) { 07051 return -1; 07052 } 07053 07054 ast_debug(1, "misdn_hangup(%s)\n", ast->name); 07055 07056 /* Take the ast_channel's tech_pvt reference. */ 07057 ast_mutex_lock(&release_lock); 07058 p = MISDN_ASTERISK_TECH_PVT(ast); 07059 if (!p) { 07060 ast_mutex_unlock(&release_lock); 07061 return -1; 07062 } 07063 MISDN_ASTERISK_TECH_PVT(ast) = NULL; 07064 07065 if (!misdn_chan_is_valid(p)) { 07066 ast_mutex_unlock(&release_lock); 07067 chan_list_unref(p, "Release ast_channel reference. Was not active?"); 07068 return 0; 07069 } 07070 07071 if (p->hold.state == MISDN_HOLD_IDLE) { 07072 bc = p->bc; 07073 } else { 07074 p->hold.state = MISDN_HOLD_DISCONNECT; 07075 bc = misdn_lib_find_held_bc(p->hold.port, p->l3id); 07076 if (!bc) { 07077 chan_misdn_log(4, p->hold.port, 07078 "misdn_hangup: Could not find held bc for (%s)\n", ast->name); 07079 release_chan_early(p); 07080 ast_mutex_unlock(&release_lock); 07081 chan_list_unref(p, "Release ast_channel reference"); 07082 return 0; 07083 } 07084 } 07085 07086 if (ast->_state == AST_STATE_RESERVED || p->state == MISDN_NOTHING) { 07087 /* between request and call */ 07088 ast_debug(1, "State Reserved (or nothing) => chanIsAvail\n"); 07089 release_chan_early(p); 07090 if (bc) { 07091 misdn_lib_release(bc); 07092 } 07093 ast_mutex_unlock(&release_lock); 07094 chan_list_unref(p, "Release ast_channel reference"); 07095 return 0; 07096 } 07097 if (!bc) { 07098 ast_log(LOG_WARNING, "Hangup with private but no bc ? state:%s l3id:%x\n", 07099 misdn_get_ch_state(p), p->l3id); 07100 release_chan_early(p); 07101 ast_mutex_unlock(&release_lock); 07102 chan_list_unref(p, "Release ast_channel reference"); 07103 return 0; 07104 } 07105 07106 p->ast = NULL; 07107 p->need_hangup = 0; 07108 p->need_queue_hangup = 0; 07109 p->need_busy = 0; 07110 07111 if (!bc->nt) { 07112 stop_bc_tones(p); 07113 } 07114 07115 bc->out_cause = ast->hangupcause ? ast->hangupcause : AST_CAUSE_NORMAL_CLEARING; 07116 07117 /* Channel lock is already held when we are called. */ 07118 //ast_channel_lock(ast); 07119 var = pbx_builtin_getvar_helper(ast, "HANGUPCAUSE"); 07120 if (!var) { 07121 var = pbx_builtin_getvar_helper(ast, "PRI_CAUSE"); 07122 } 07123 if (var) { 07124 int tmpcause; 07125 07126 tmpcause = atoi(var); 07127 bc->out_cause = tmpcause ? tmpcause : AST_CAUSE_NORMAL_CLEARING; 07128 } 07129 07130 var = pbx_builtin_getvar_helper(ast, "MISDN_USERUSER"); 07131 if (var) { 07132 ast_log(LOG_NOTICE, "MISDN_USERUSER: %s\n", var); 07133 ast_copy_string(bc->uu, var, sizeof(bc->uu)); 07134 bc->uulen = strlen(bc->uu); 07135 } 07136 //ast_channel_unlock(ast); 07137 07138 chan_misdn_log(1, bc->port, 07139 "* IND : HANGUP\tpid:%d context:%s dialed:%s caller:\"%s\" <%s> State:%s\n", 07140 bc->pid, 07141 ast->context, 07142 ast->exten, 07143 (ast->caller.id.name.valid && ast->caller.id.name.str) 07144 ? ast->caller.id.name.str : "", 07145 (ast->caller.id.number.valid && ast->caller.id.number.str) 07146 ? ast->caller.id.number.str : "", 07147 misdn_get_ch_state(p)); 07148 chan_misdn_log(3, bc->port, " --> l3id:%x\n", p->l3id); 07149 chan_misdn_log(3, bc->port, " --> cause:%d\n", bc->cause); 07150 chan_misdn_log(2, bc->port, " --> out_cause:%d\n", bc->out_cause); 07151 07152 switch (p->state) { 07153 case MISDN_INCOMING_SETUP: 07154 /* 07155 * This is the only place in misdn_hangup, where we 07156 * can call release_chan, else it might create a lot of trouble. 07157 */ 07158 ast_log(LOG_NOTICE, "release channel, in INCOMING_SETUP state.. no other events happened\n"); 07159 release_chan(p, bc); 07160 misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE); 07161 ast_mutex_unlock(&release_lock); 07162 chan_list_unref(p, "Release ast_channel reference"); 07163 return 0; 07164 case MISDN_DIALING: 07165 if (p->hold.state == MISDN_HOLD_IDLE) { 07166 start_bc_tones(p); 07167 hanguptone_indicate(p); 07168 } 07169 07170 if (bc->need_disconnect) { 07171 misdn_lib_send_event(bc, EVENT_DISCONNECT); 07172 } 07173 break; 07174 case MISDN_CALLING_ACKNOWLEDGE: 07175 if (p->hold.state == MISDN_HOLD_IDLE) { 07176 start_bc_tones(p); 07177 hanguptone_indicate(p); 07178 } 07179 07180 if (bc->need_disconnect) { 07181 misdn_lib_send_event(bc, EVENT_DISCONNECT); 07182 } 07183 break; 07184 07185 case MISDN_CALLING: 07186 case MISDN_ALERTING: 07187 case MISDN_PROGRESS: 07188 case MISDN_PROCEEDING: 07189 if (p->originator != ORG_AST && p->hold.state == MISDN_HOLD_IDLE) { 07190 hanguptone_indicate(p); 07191 } 07192 07193 if (bc->need_disconnect) { 07194 misdn_lib_send_event(bc, EVENT_DISCONNECT); 07195 } 07196 break; 07197 case MISDN_CONNECTED: 07198 /* Alerting or Disconnect */ 07199 if (bc->nt && p->hold.state == MISDN_HOLD_IDLE) { 07200 start_bc_tones(p); 07201 hanguptone_indicate(p); 07202 bc->progress_indicator = INFO_PI_INBAND_AVAILABLE; 07203 } 07204 if (bc->need_disconnect) { 07205 misdn_lib_send_event(bc, EVENT_DISCONNECT); 07206 } 07207 break; 07208 case MISDN_DISCONNECTED: 07209 if (bc->need_release) { 07210 misdn_lib_send_event(bc, EVENT_RELEASE); 07211 } 07212 break; 07213 07214 case MISDN_CLEANING: 07215 ast_mutex_unlock(&release_lock); 07216 chan_list_unref(p, "Release ast_channel reference"); 07217 return 0; 07218 07219 case MISDN_BUSY: 07220 break; 07221 default: 07222 if (bc->nt) { 07223 bc->out_cause = -1; 07224 if (bc->need_release) { 07225 misdn_lib_send_event(bc, EVENT_RELEASE); 07226 } 07227 } else { 07228 if (bc->need_disconnect) { 07229 misdn_lib_send_event(bc, EVENT_DISCONNECT); 07230 } 07231 } 07232 break; 07233 } 07234 07235 p->state = MISDN_CLEANING; 07236 chan_misdn_log(3, bc->port, " --> Channel: %s hungup new state:%s\n", ast->name, 07237 misdn_get_ch_state(p)); 07238 07239 ast_mutex_unlock(&release_lock); 07240 chan_list_unref(p, "Release ast_channel reference"); 07241 return 0; 07242 }
static int misdn_indication | ( | struct ast_channel * | ast, | |
int | cond, | |||
const void * | data, | |||
size_t | datalen | |||
) | [static] |
Definition at line 6905 of file chan_misdn.c.
References chan_list::ast, 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, ast_channel::name, 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().
06906 { 06907 struct chan_list *p; 06908 06909 if (!ast || !(p = MISDN_ASTERISK_TECH_PVT(ast))) { 06910 ast_log(LOG_WARNING, "Returned -1 in misdn_indication\n"); 06911 return -1; 06912 } 06913 06914 if (!p->bc) { 06915 if (p->hold.state == MISDN_HOLD_IDLE) { 06916 chan_misdn_log(1, 0, "* IND : Indication [%d] ignored on %s\n", cond, 06917 ast->name); 06918 ast_log(LOG_WARNING, "Private Pointer but no bc ?\n"); 06919 } else { 06920 chan_misdn_log(1, 0, "* IND : Indication [%d] ignored on hold %s\n", 06921 cond, ast->name); 06922 } 06923 return -1; 06924 } 06925 06926 chan_misdn_log(5, p->bc->port, "* IND : Indication [%d] on %s\n\n", cond, ast->name); 06927 06928 switch (cond) { 06929 case AST_CONTROL_BUSY: 06930 chan_misdn_log(1, p->bc->port, "* IND :\tbusy pid:%d\n", p->bc->pid); 06931 ast_setstate(ast, AST_STATE_BUSY); 06932 06933 p->bc->out_cause = AST_CAUSE_USER_BUSY; 06934 if (p->state != MISDN_CONNECTED) { 06935 start_bc_tones(p); 06936 misdn_lib_send_event(p->bc, EVENT_DISCONNECT); 06937 } 06938 return -1; 06939 case AST_CONTROL_RING: 06940 chan_misdn_log(1, p->bc->port, "* IND :\tring pid:%d\n", p->bc->pid); 06941 return -1; 06942 case AST_CONTROL_RINGING: 06943 chan_misdn_log(1, p->bc->port, "* IND :\tringing pid:%d\n", p->bc->pid); 06944 switch (p->state) { 06945 case MISDN_ALERTING: 06946 chan_misdn_log(2, p->bc->port, " --> * IND :\tringing pid:%d but I was Ringing before, so ignoring it\n", p->bc->pid); 06947 break; 06948 case MISDN_CONNECTED: 06949 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); 06950 return -1; 06951 default: 06952 p->state = MISDN_ALERTING; 06953 chan_misdn_log(2, p->bc->port, " --> * IND :\tringing pid:%d\n", p->bc->pid); 06954 misdn_lib_send_event(p->bc, EVENT_ALERTING); 06955 06956 chan_misdn_log(3, p->bc->port, " --> * SEND: State Ring pid:%d\n", p->bc->pid); 06957 ast_setstate(ast, AST_STATE_RING); 06958 06959 if (!p->bc->nt && (p->originator == ORG_MISDN) && !p->incoming_early_audio) { 06960 chan_misdn_log(2, p->bc->port, " --> incoming_early_audio off\n"); 06961 } else { 06962 return -1; 06963 } 06964 } 06965 break; 06966 case AST_CONTROL_ANSWER: 06967 chan_misdn_log(1, p->bc->port, " --> * IND :\tanswer pid:%d\n", p->bc->pid); 06968 start_bc_tones(p); 06969 break; 06970 case AST_CONTROL_TAKEOFFHOOK: 06971 chan_misdn_log(1, p->bc->port, " --> *\ttakeoffhook pid:%d\n", p->bc->pid); 06972 return -1; 06973 case AST_CONTROL_OFFHOOK: 06974 chan_misdn_log(1, p->bc->port, " --> *\toffhook pid:%d\n", p->bc->pid); 06975 return -1; 06976 case AST_CONTROL_FLASH: 06977 chan_misdn_log(1, p->bc->port, " --> *\tflash pid:%d\n", p->bc->pid); 06978 break; 06979 case AST_CONTROL_PROGRESS: 06980 chan_misdn_log(1, p->bc->port, " --> * IND :\tprogress pid:%d\n", p->bc->pid); 06981 misdn_lib_send_event(p->bc, EVENT_PROGRESS); 06982 break; 06983 case AST_CONTROL_PROCEEDING: 06984 chan_misdn_log(1, p->bc->port, " --> * IND :\tproceeding pid:%d\n", p->bc->pid); 06985 misdn_lib_send_event(p->bc, EVENT_PROCEEDING); 06986 break; 06987 case AST_CONTROL_INCOMPLETE: 06988 chan_misdn_log(1, p->bc->port, " --> *\tincomplete pid:%d\n", p->bc->pid); 06989 if (!p->overlap_dial) { 06990 /* Overlapped dialing not enabled - send hangup */ 06991 p->bc->out_cause = AST_CAUSE_INVALID_NUMBER_FORMAT; 06992 start_bc_tones(p); 06993 misdn_lib_send_event(p->bc, EVENT_DISCONNECT); 06994 06995 if (p->bc->nt) { 06996 hanguptone_indicate(p); 06997 } 06998 } 06999 break; 07000 case AST_CONTROL_CONGESTION: 07001 chan_misdn_log(1, p->bc->port, " --> * IND :\tcongestion pid:%d\n", p->bc->pid); 07002 07003 p->bc->out_cause = AST_CAUSE_SWITCH_CONGESTION; 07004 start_bc_tones(p); 07005 misdn_lib_send_event(p->bc, EVENT_DISCONNECT); 07006 07007 if (p->bc->nt) { 07008 hanguptone_indicate(p); 07009 } 07010 break; 07011 case -1 : 07012 chan_misdn_log(1, p->bc->port, " --> * IND :\t-1! (stop indication) pid:%d\n", p->bc->pid); 07013 07014 stop_indicate(p); 07015 07016 if (p->state == MISDN_CONNECTED) { 07017 start_bc_tones(p); 07018 } 07019 break; 07020 case AST_CONTROL_HOLD: 07021 ast_moh_start(ast, data, p->mohinterpret); 07022 chan_misdn_log(1, p->bc->port, " --> *\tHOLD pid:%d\n", p->bc->pid); 07023 break; 07024 case AST_CONTROL_UNHOLD: 07025 ast_moh_stop(ast); 07026 chan_misdn_log(1, p->bc->port, " --> *\tUNHOLD pid:%d\n", p->bc->pid); 07027 break; 07028 case AST_CONTROL_CONNECTED_LINE: 07029 chan_misdn_log(1, p->bc->port, "* IND :\tconnected line update pid:%d\n", p->bc->pid); 07030 misdn_update_connected_line(ast, p->bc, p->originator); 07031 break; 07032 case AST_CONTROL_REDIRECTING: 07033 chan_misdn_log(1, p->bc->port, "* IND :\tredirecting info update pid:%d\n", p->bc->pid); 07034 misdn_update_redirecting(ast, p->bc, p->originator); 07035 break; 07036 default: 07037 chan_misdn_log(1, p->bc->port, " --> * Unknown Indication:%d pid:%d\n", cond, p->bc->pid); 07038 return -1; 07039 } 07040 07041 return 0; 07042 }
static int misdn_is_msn_valid | ( | int | port, | |
const struct misdn_party_dialing * | dialed | |||
) | [static] |
Definition at line 9848 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().
09849 { 09850 char number[sizeof(dialed->number)]; 09851 09852 ast_copy_string(number, dialed->number, sizeof(number)); 09853 misdn_add_number_prefix(port, dialed->number_type, number, sizeof(number)); 09854 return misdn_cfg_is_msn_valid(port, number); 09855 }
void misdn_jb_destroy | ( | struct misdn_jb * | jb | ) |
frees the data and destroys the given jitterbuffer struct
Definition at line 12500 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().
12501 { 12502 ast_mutex_destroy(&jb->mutexjb); 12503 12504 ast_free(jb->ok); 12505 ast_free(jb->samples); 12506 ast_free(jb); 12507 }
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 12577 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().
12578 { 12579 int i; 12580 int wp; 12581 int rp; 12582 int read = 0; 12583 12584 ast_mutex_lock(&jb->mutexjb); 12585 12586 rp = jb->rp; 12587 wp = jb->wp; 12588 12589 if (jb->state_empty) { 12590 for (i = 0; i < len; i++) { 12591 if (wp == rp) { 12592 jb->rp = rp; 12593 jb->state_empty = 0; 12594 12595 ast_mutex_unlock(&jb->mutexjb); 12596 12597 return read; 12598 } else { 12599 if (jb->ok[rp] == 1) { 12600 data[i] = jb->samples[rp]; 12601 jb->ok[rp] = 0; 12602 rp = (rp != jb->size - 1) ? rp + 1 : 0; 12603 read += 1; 12604 } 12605 } 12606 } 12607 12608 if (wp >= rp) { 12609 jb->state_buffer = wp - rp; 12610 } else { 12611 jb->state_buffer = jb->size - rp + wp; 12612 } 12613 chan_misdn_log(9, 0, "misdn_jb_empty: read:%d | Buffer status:%d p:%p\n", len, jb->state_buffer, jb); 12614 12615 jb->rp = rp; 12616 } else { 12617 chan_misdn_log(9, 0, "misdn_jb_empty: Wait...requested:%d p:%p\n", len, jb); 12618 } 12619 12620 ast_mutex_unlock(&jb->mutexjb); 12621 12622 return read; 12623 }
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 12511 of file chan_misdn.c.
References ast_mutex_lock, misdn_jb::mutexjb, misdn_jb::ok, misdn_jb::rp, misdn_jb::samples, misdn_jb::size, misdn_jb::state_full, and misdn_jb::wp.
12512 { 12513 int i; 12514 int j; 12515 int rp; 12516 int wp; 12517 12518 if (!jb || ! data) { 12519 return 0; 12520 } 12521 12522 ast_mutex_lock(&jb->mutexjb); 12523 12524 wp = jb->wp; 12525 rp = jb->rp; 12526 12527 for (i = 0; i < len; i++) { 12528 jb->samples[wp] = data[i]; 12529 jb->ok[wp] = 1; 12530 wp = (wp != jb->size - 1) ? wp + 1 : 0; 12531 12532 if (wp == jb->rp) { 12533 jb->state_full = 1; 12534 } 12535 } 12536 12537 if (wp >= rp) { 12538 jb->state_buffer = wp - rp; 12539 } else { 12540 jb->state_buffer = jb->size - rp + wp; 12541 } 12542 chan_misdn_log(9, 0, "misdn_jb_fill: written:%d | Buffer status:%d p:%p\n", len, jb->state_buffer, jb); 12543 12544 if (jb->state_full) { 12545 jb->wp = wp; 12546 12547 rp = wp; 12548 for (j = 0; j < jb->upper_threshold; j++) { 12549 rp = (rp != 0) ? rp - 1 : jb->size - 1; 12550 } 12551 jb->rp = rp; 12552 jb->state_full = 0; 12553 jb->state_empty = 1; 12554 12555 ast_mutex_unlock(&jb->mutexjb); 12556 12557 return -1; 12558 } 12559 12560 if (!jb->state_empty) { 12561 jb->bytes_wrote += len; 12562 if (jb->bytes_wrote >= jb->upper_threshold) { 12563 jb->state_empty = 1; 12564 jb->bytes_wrote = 0; 12565 } 12566 } 12567 jb->wp = wp; 12568 12569 ast_mutex_unlock(&jb->mutexjb); 12570 12571 return 0; 12572 }
struct misdn_jb * misdn_jb_init | ( | int | size, | |
int | upper_threshold | |||
) |
allocates the jb-structure and initialize the elements
Definition at line 12463 of file chan_misdn.c.
References ast_calloc, ast_free, ast_mutex_init, and chan_misdn_log().
Referenced by config_jitterbuffer().
12464 { 12465 struct misdn_jb *jb; 12466 12467 jb = ast_calloc(1, sizeof(*jb)); 12468 if (!jb) { 12469 chan_misdn_log(-1, 0, "No free Mem for jb\n"); 12470 return NULL; 12471 } 12472 jb->size = size; 12473 jb->upper_threshold = upper_threshold; 12474 //jb->wp = 0; 12475 //jb->rp = 0; 12476 //jb->state_full = 0; 12477 //jb->state_empty = 0; 12478 //jb->bytes_wrote = 0; 12479 jb->samples = ast_calloc(size, sizeof(*jb->samples)); 12480 if (!jb->samples) { 12481 ast_free(jb); 12482 chan_misdn_log(-1, 0, "No free Mem for jb->samples\n"); 12483 return NULL; 12484 } 12485 12486 jb->ok = ast_calloc(size, sizeof(*jb->ok)); 12487 if (!jb->ok) { 12488 ast_free(jb->samples); 12489 ast_free(jb); 12490 chan_misdn_log(-1, 0, "No free Mem for jb->ok\n"); 12491 return NULL; 12492 } 12493 12494 ast_mutex_init(&jb->mutexjb); 12495 12496 return jb; 12497 }
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] |
Definition at line 8112 of file chan_misdn.c.
References ast_party_caller::ani, chan_list::ast, ast_callerid_parse(), ast_channel_alloc, ast_channel_set_fd(), ast_copy_string(), ast_jb_configure(), ast_log(), AST_STATE_RING, ast_strdup, ast_strlen_zero(), ast_channel::caller, chan_list_ref, chan_misdn_log(), cid_name, cid_num, ast_channel::exten, LOG_ERROR, MISDN_ASTERISK_TECH_PVT, misdn_cfg_get(), misdn_cfg_get_next_port(), MISDN_GEN_BRIDGING, misdn_get_global_jbconf(), misdn_lib_port_is_pri(), misdn_tech, misdn_tech_wo_bridge, misdn_type, ast_channel::nativeformats, ast_party_id::number, chan_list::pipe, prefformat, ast_channel::priority, ast_channel::rawreadformat, ast_channel::rawwriteformat, ast_channel::readformat, ast_channel::rings, ast_party_number::str, ast_channel::tech, ast_party_number::valid, and ast_channel::writeformat.
Referenced by cb_events().
08113 { 08114 struct ast_channel *tmp; 08115 char *cid_name = NULL; 08116 char *cid_num = NULL; 08117 int chan_offset = 0; 08118 int tmp_port = misdn_cfg_get_next_port(0); 08119 int bridging; 08120 08121 for (; tmp_port > 0; tmp_port = misdn_cfg_get_next_port(tmp_port)) { 08122 if (tmp_port == port) { 08123 break; 08124 } 08125 chan_offset += misdn_lib_port_is_pri(tmp_port) ? 30 : 2; 08126 } 08127 if (c < 0) { 08128 c = 0; 08129 } 08130 08131 if (callerid) { 08132 ast_callerid_parse(callerid, &cid_name, &cid_num); 08133 } 08134 08135 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++); 08136 if (tmp) { 08137 chan_misdn_log(2, 0, " --> * NEW CHANNEL dialed:%s caller:%s\n", exten, callerid); 08138 08139 tmp->nativeformats = prefformat; 08140 08141 tmp->readformat = format; 08142 tmp->rawreadformat = format; 08143 tmp->writeformat = format; 08144 tmp->rawwriteformat = format; 08145 08146 /* Link the channel and private together */ 08147 chan_list_ref(chlist, "Give a reference to ast_channel"); 08148 MISDN_ASTERISK_TECH_PVT(tmp) = chlist; 08149 chlist->ast = tmp; 08150 08151 misdn_cfg_get(0, MISDN_GEN_BRIDGING, &bridging, sizeof(bridging)); 08152 tmp->tech = bridging ? &misdn_tech : &misdn_tech_wo_bridge; 08153 08154 tmp->writeformat = format; 08155 tmp->readformat = format; 08156 tmp->priority = 1; 08157 08158 if (exten) { 08159 ast_copy_string(tmp->exten, exten, sizeof(tmp->exten)); 08160 } else { 08161 chan_misdn_log(1, 0, "misdn_new: no exten given.\n"); 08162 } 08163 08164 if (!ast_strlen_zero(cid_num)) { 08165 /* Don't use ast_set_callerid() here because it will 08166 * generate a needless NewCallerID event */ 08167 tmp->caller.ani.number.valid = 1; 08168 tmp->caller.ani.number.str = ast_strdup(cid_num); 08169 } 08170 08171 if (pipe(chlist->pipe) < 0) { 08172 ast_log(LOG_ERROR, "Pipe failed\n"); 08173 } 08174 ast_channel_set_fd(tmp, 0, chlist->pipe[0]); 08175 08176 tmp->rings = (state == AST_STATE_RING) ? 1 : 0; 08177 08178 ast_jb_configure(tmp, misdn_get_global_jbconf()); 08179 } else { 08180 chan_misdn_log(-1, 0, "Unable to allocate channel structure\n"); 08181 } 08182 08183 return tmp; 08184 }
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 6078 of file chan_misdn.c.
References ast_channel_queue_connected_line_update(), ast_party_connected_line_init(), connected, id, misdn_to_ast_plan(), misdn_to_ast_pres(), misdn_to_ast_screen(), and misdn_to_ast_ton().
Referenced by misdn_update_remote_party().
06079 { 06080 struct ast_party_connected_line connected; 06081 struct ast_set_party_connected_line update_connected; 06082 06083 ast_party_connected_line_init(&connected); 06084 memset(&update_connected, 0, sizeof(update_connected)); 06085 update_connected.id.number = 1; 06086 connected.id.number.valid = 1; 06087 connected.id.number.str = (char *) id->number; 06088 connected.id.number.plan = misdn_to_ast_ton(id->number_type) 06089 | misdn_to_ast_plan(id->number_plan); 06090 connected.id.number.presentation = misdn_to_ast_pres(id->presentation) 06091 | misdn_to_ast_screen(id->screening); 06092 connected.id.tag = cid_tag; 06093 connected.source = source; 06094 ast_channel_queue_connected_line_update(ast, &connected, &update_connected); 06095 }
static struct ast_frame* misdn_read | ( | struct ast_channel * | ast | ) | [static] |
Definition at line 7320 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.
07321 { 07322 struct chan_list *tmp; 07323 int len, t; 07324 struct pollfd pfd = { .fd = -1, .events = POLLIN }; 07325 07326 if (!ast) { 07327 chan_misdn_log(1, 0, "misdn_read called without ast\n"); 07328 return NULL; 07329 } 07330 if (!(tmp = MISDN_ASTERISK_TECH_PVT(ast))) { 07331 chan_misdn_log(1, 0, "misdn_read called without ast->pvt\n"); 07332 return NULL; 07333 } 07334 07335 if (!tmp->bc && tmp->hold.state == MISDN_HOLD_IDLE) { 07336 chan_misdn_log(1, 0, "misdn_read called without bc\n"); 07337 return NULL; 07338 } 07339 07340 pfd.fd = tmp->pipe[0]; 07341 t = ast_poll(&pfd, 1, 20); 07342 07343 if (t < 0) { 07344 chan_misdn_log(-1, tmp->bc->port, "poll() error (err=%s)\n", strerror(errno)); 07345 return NULL; 07346 } 07347 07348 if (!t) { 07349 chan_misdn_log(3, tmp->bc->port, "poll() timed out\n"); 07350 len = 160; 07351 } else if (pfd.revents & POLLIN) { 07352 len = read(tmp->pipe[0], tmp->ast_rd_buf, sizeof(tmp->ast_rd_buf)); 07353 07354 if (len <= 0) { 07355 /* we hangup here, since our pipe is closed */ 07356 chan_misdn_log(2, tmp->bc->port, "misdn_read: Pipe closed, hanging up\n"); 07357 return NULL; 07358 } 07359 } else { 07360 return NULL; 07361 } 07362 07363 tmp->frame.frametype = AST_FRAME_VOICE; 07364 tmp->frame.subclass.codec = AST_FORMAT_ALAW; 07365 tmp->frame.datalen = len; 07366 tmp->frame.samples = len; 07367 tmp->frame.mallocd = 0; 07368 tmp->frame.offset = 0; 07369 tmp->frame.delivery = ast_tv(0, 0); 07370 tmp->frame.src = NULL; 07371 tmp->frame.data.ptr = tmp->ast_rd_buf; 07372 07373 if (tmp->faxdetect && !tmp->faxhandled) { 07374 if (tmp->faxdetect_timeout) { 07375 if (ast_tvzero(tmp->faxdetect_tv)) { 07376 tmp->faxdetect_tv = ast_tvnow(); 07377 chan_misdn_log(2, tmp->bc->port, "faxdetect: starting detection with timeout: %ds ...\n", tmp->faxdetect_timeout); 07378 return process_ast_dsp(tmp, &tmp->frame); 07379 } else { 07380 struct timeval tv_now = ast_tvnow(); 07381 int diff = ast_tvdiff_ms(tv_now, tmp->faxdetect_tv); 07382 if (diff <= (tmp->faxdetect_timeout * 1000)) { 07383 chan_misdn_log(5, tmp->bc->port, "faxdetect: detecting ...\n"); 07384 return process_ast_dsp(tmp, &tmp->frame); 07385 } else { 07386 chan_misdn_log(2, tmp->bc->port, "faxdetect: stopping detection (time ran out) ...\n"); 07387 tmp->faxdetect = 0; 07388 return &tmp->frame; 07389 } 07390 } 07391 } else { 07392 chan_misdn_log(5, tmp->bc->port, "faxdetect: detecting ... (no timeout)\n"); 07393 return process_ast_dsp(tmp, &tmp->frame); 07394 } 07395 } else { 07396 if (tmp->ast_dsp) { 07397 return process_ast_dsp(tmp, &tmp->frame); 07398 } else { 07399 return &tmp->frame; 07400 } 07401 } 07402 }
static struct ast_channel* misdn_request | ( | const char * | type, | |
format_t | format, | |||
const struct ast_channel * | requestor, | |||
void * | data, | |||
int * | cause | |||
) | [static] |
Definition at line 7773 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_strdupa, ast_strlen_zero(), BUFFERSIZE, chan_misdn_log(), misdn_bchannel::channel, robin_list::channel, misdn_bchannel::dec, ext, get_robin_position(), 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_type, misdn_bchannel::port, and robin_list::port.
07774 { 07775 struct ast_channel *ast; 07776 char group[BUFFERSIZE + 1] = ""; 07777 char dial_str[128]; 07778 char *dest_cp; 07779 char *p = NULL; 07780 int channel = 0; 07781 int port = 0; 07782 struct misdn_bchannel *newbc = NULL; 07783 int dec = 0; 07784 #if defined(AST_MISDN_ENHANCEMENTS) 07785 int cc_retry_call = 0; /* TRUE if this is a call completion retry call */ 07786 long record_id = -1; 07787 struct misdn_cc_record *cc_record; 07788 const char *err_msg; 07789 #endif /* defined(AST_MISDN_ENHANCEMENTS) */ 07790 struct chan_list *cl; 07791 07792 AST_DECLARE_APP_ARGS(args, 07793 AST_APP_ARG(intf); /* interface token */ 07794 AST_APP_ARG(ext); /* extension token */ 07795 AST_APP_ARG(opts); /* options token */ 07796 ); 07797 07798 snprintf(dial_str, sizeof(dial_str), "%s/%s", misdn_type, (char *) data); 07799 07800 /* 07801 * data is ---v 07802 * Dial(mISDN/g:group_name[/extension[/options]]) 07803 * Dial(mISDN/port[:preselected_channel][/extension[/options]]) 07804 * Dial(mISDN/cc/cc-record-id) 07805 * 07806 * The dial extension could be empty if you are using MISDN_KEYPAD 07807 * to control ISDN provider features. 07808 */ 07809 dest_cp = ast_strdupa(data); 07810 AST_NONSTANDARD_APP_ARGS(args, dest_cp, '/'); 07811 if (!args.ext) { 07812 args.ext = ""; 07813 } 07814 07815 if (!ast_strlen_zero(args.intf)) { 07816 if (args.intf[0] == 'g' && args.intf[1] == ':') { 07817 /* We make a group call lets checkout which ports are in my group */ 07818 args.intf += 2; 07819 ast_copy_string(group, args.intf, sizeof(group)); 07820 chan_misdn_log(2, 0, " --> Group Call group: %s\n", group); 07821 #if defined(AST_MISDN_ENHANCEMENTS) 07822 } else if (strcmp(args.intf, "cc") == 0) { 07823 cc_retry_call = 1; 07824 #endif /* defined(AST_MISDN_ENHANCEMENTS) */ 07825 } else if ((p = strchr(args.intf, ':'))) { 07826 /* we have a preselected channel */ 07827 *p++ = 0; 07828 channel = atoi(p); 07829 port = atoi(args.intf); 07830 chan_misdn_log(2, port, " --> Call on preselected Channel (%d).\n", channel); 07831 } else { 07832 port = atoi(args.intf); 07833 } 07834 } else { 07835 ast_log(LOG_WARNING, " --> ! IND : Dial(%s) WITHOUT Port or Group, check extensions.conf\n", dial_str); 07836 return NULL; 07837 } 07838 07839 #if defined(AST_MISDN_ENHANCEMENTS) 07840 if (cc_retry_call) { 07841 if (ast_strlen_zero(args.ext)) { 07842 ast_log(LOG_WARNING, " --> ! IND : Dial(%s) WITHOUT cc-record-id, check extensions.conf\n", dial_str); 07843 return NULL; 07844 } 07845 if (!isdigit(*args.ext)) { 07846 ast_log(LOG_WARNING, " --> ! IND : Dial(%s) cc-record-id must be a number.\n", dial_str); 07847 return NULL; 07848 } 07849 record_id = atol(args.ext); 07850 07851 AST_LIST_LOCK(&misdn_cc_records_db); 07852 cc_record = misdn_cc_find_by_id(record_id); 07853 if (!cc_record) { 07854 AST_LIST_UNLOCK(&misdn_cc_records_db); 07855 err_msg = misdn_cc_record_not_found; 07856 ast_log(LOG_WARNING, " --> ! IND : Dial(%s) %s.\n", dial_str, err_msg); 07857 return NULL; 07858 } 07859 if (!cc_record->activated) { 07860 AST_LIST_UNLOCK(&misdn_cc_records_db); 07861 err_msg = "Call completion has not been activated"; 07862 ast_log(LOG_WARNING, " --> ! IND : Dial(%s) %s.\n", dial_str, err_msg); 07863 return NULL; 07864 } 07865 port = cc_record->port; 07866 AST_LIST_UNLOCK(&misdn_cc_records_db); 07867 } 07868 #endif /* defined(AST_MISDN_ENHANCEMENTS) */ 07869 07870 if (misdn_cfg_is_group_method(group, METHOD_STANDARD_DEC)) { 07871 chan_misdn_log(4, port, " --> STARTING STANDARD DEC...\n"); 07872 dec = 1; 07873 } 07874 07875 if (!ast_strlen_zero(group)) { 07876 char cfg_group[BUFFERSIZE + 1]; 07877 struct robin_list *rr = NULL; 07878 07879 /* Group dial */ 07880 07881 if (misdn_cfg_is_group_method(group, METHOD_ROUND_ROBIN)) { 07882 chan_misdn_log(4, port, " --> STARTING ROUND ROBIN...\n"); 07883 rr = get_robin_position(group); 07884 } 07885 07886 if (rr) { 07887 int port_start; 07888 int bchan_start; 07889 int port_up; 07890 int check; 07891 int maxbchans; 07892 int wraped = 0; 07893 07894 if (!rr->port) { 07895 rr->port = misdn_cfg_get_next_port_spin(0); 07896 } 07897 07898 if (!rr->channel) { 07899 rr->channel = 1; 07900 } 07901 07902 bchan_start = rr->channel; 07903 port_start = rr->port; 07904 do { 07905 misdn_cfg_get(rr->port, MISDN_CFG_GROUPNAME, cfg_group, sizeof(cfg_group)); 07906 if (strcasecmp(cfg_group, group)) { 07907 wraped = 1; 07908 rr->port = misdn_cfg_get_next_port_spin(rr->port); 07909 rr->channel = 1; 07910 continue; 07911 } 07912 07913 misdn_cfg_get(rr->port, MISDN_CFG_PMP_L1_CHECK, &check, sizeof(check)); 07914 port_up = misdn_lib_port_up(rr->port, check); 07915 07916 if (!port_up) { 07917 chan_misdn_log(1, rr->port, "L1 is not Up on this Port\n"); 07918 rr->port = misdn_cfg_get_next_port_spin(rr->port); 07919 rr->channel = 1; 07920 } else if (port_up < 0) { 07921 ast_log(LOG_WARNING, "This port (%d) is blocked\n", rr->port); 07922 rr->port = misdn_cfg_get_next_port_spin(rr->port); 07923 rr->channel = 1; 07924 } else { 07925 chan_misdn_log(4, rr->port, "portup\n"); 07926 maxbchans = misdn_lib_get_maxchans(rr->port); 07927 07928 for (;rr->channel <= maxbchans;rr->channel++) { 07929 /* ive come full circle and can stop now */ 07930 if (wraped && (rr->port == port_start) && (rr->channel == bchan_start)) { 07931 break; 07932 } 07933 07934 chan_misdn_log(4, rr->port, "Checking channel %d\n", rr->channel); 07935 07936 if ((newbc = misdn_lib_get_free_bc(rr->port, rr->channel, 0, 0))) { 07937 chan_misdn_log(4, rr->port, " Success! Found port:%d channel:%d\n", newbc->port, newbc->channel); 07938 rr->channel++; 07939 break; 07940 } 07941 } 07942 if (wraped && (rr->port == port_start) && (rr->channel <= bchan_start)) { 07943 break; 07944 } else if (!newbc || (rr->channel == maxbchans)) { 07945 rr->port = misdn_cfg_get_next_port_spin(rr->port); 07946 rr->channel = 1; 07947 } 07948 07949 } 07950 wraped = 1; 07951 } while (!newbc && (rr->port > 0)); 07952 } else { 07953 for (port = misdn_cfg_get_next_port(0); port > 0; 07954 port = misdn_cfg_get_next_port(port)) { 07955 misdn_cfg_get(port, MISDN_CFG_GROUPNAME, cfg_group, sizeof(cfg_group)); 07956 07957 chan_misdn_log(3, port, "Group [%s] Port [%d]\n", group, port); 07958 if (!strcasecmp(cfg_group, group)) { 07959 int port_up; 07960 int check; 07961 07962 misdn_cfg_get(port, MISDN_CFG_PMP_L1_CHECK, &check, sizeof(check)); 07963 port_up = misdn_lib_port_up(port, check); 07964 07965 chan_misdn_log(4, port, "portup:%d\n", port_up); 07966 07967 if (port_up > 0) { 07968 newbc = misdn_lib_get_free_bc(port, 0, 0, dec); 07969 if (newbc) { 07970 break; 07971 } 07972 } 07973 } 07974 } 07975 } 07976 07977 /* Group dial failed ?*/ 07978 if (!newbc) { 07979 ast_log(LOG_WARNING, 07980 "Could not Dial out on group '%s'.\n" 07981 "\tEither the L2 and L1 on all of these ports where DOWN (see 'show application misdn_check_l2l1')\n" 07982 "\tOr there was no free channel on none of the ports\n\n", 07983 group); 07984 return NULL; 07985 } 07986 } else { 07987 /* 'Normal' Port dial * Port dial */ 07988 if (channel) { 07989 chan_misdn_log(1, port, " --> preselected_channel: %d\n", channel); 07990 } 07991 newbc = misdn_lib_get_free_bc(port, channel, 0, dec); 07992 if (!newbc) { 07993 ast_log(LOG_WARNING, "Could not create channel on port:%d for Dial(%s)\n", port, dial_str); 07994 return NULL; 07995 } 07996 } 07997 07998 /* create ast_channel and link all the objects together */ 07999 cl = chan_list_init(ORG_AST); 08000 if (!cl) { 08001 misdn_lib_release(newbc); 08002 ast_log(LOG_ERROR, "Could not create call record for Dial(%s)\n", dial_str); 08003 return NULL; 08004 } 08005 cl->bc = newbc; 08006 08007 ast = misdn_new(cl, AST_STATE_RESERVED, args.ext, NULL, format, requestor ? requestor->linkedid : NULL, port, channel); 08008 if (!ast) { 08009 chan_list_unref(cl, "Failed to create a new channel"); 08010 misdn_lib_release(newbc); 08011 ast_log(LOG_ERROR, "Could not create Asterisk channel for Dial(%s)\n", dial_str); 08012 return NULL; 08013 } 08014 08015 #if defined(AST_MISDN_ENHANCEMENTS) 08016 cl->record_id = record_id; 08017 #endif /* defined(AST_MISDN_ENHANCEMENTS) */ 08018 08019 /* register chan in local list */ 08020 cl_queue_chan(cl); 08021 08022 /* fill in the config into the objects */ 08023 read_config(cl); 08024 08025 /* important */ 08026 cl->need_hangup = 0; 08027 08028 chan_list_unref(cl, "Successful misdn_request()"); 08029 return ast; 08030 }
static int misdn_send_text | ( | struct ast_channel * | chan, | |
const char * | text | |||
) | [static] |
Definition at line 8033 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().
08034 { 08035 struct chan_list *tmp = MISDN_ASTERISK_TECH_PVT(chan); 08036 08037 if (tmp && tmp->bc) { 08038 ast_copy_string(tmp->bc->display, text, sizeof(tmp->bc->display)); 08039 misdn_lib_send_event(tmp->bc, EVENT_INFORMATION); 08040 } else { 08041 ast_log(LOG_WARNING, "No chan_list but send_text request?\n"); 08042 return -1; 08043 } 08044 08045 return 0; 08046 }
static int misdn_set_opt_exec | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Definition at line 12226 of file chan_misdn.c.
References ast_copy_string(), chan_list::ast_dsp, ast_dsp_new(), ast_dsp_set_features(), ast_log(), ast_strdupa, ast_strlen_zero(), chan_list::bc, misdn_bchannel::capability, chan_misdn_log(), config_jitterbuffer(), misdn_bchannel::crypt_key, misdn_bchannel::display, chan_list::dsp, DSP_FEATURE_DIGIT_DETECT, DSP_FEATURE_FAX_DETECT, misdn_bchannel::ec_deftaps, misdn_bchannel::ec_enable, chan_list::faxdetect, chan_list::faxdetect_timeout, misdn_bchannel::hdlc, chan_list::ignore_dtmf, INFO_CAPABILITY_DIGITAL_UNRESTRICTED, chan_list::jb_len, chan_list::jb_upper_threshold, LOG_WARNING, MISDN_ASTERISK_TECH_PVT, MISDN_CFG_FAXDETECT_TIMEOUT, misdn_cfg_get(), MISDN_GEN_CRYPT_KEYS, misdn_type, misdn_bchannel::nodsp, misdn_bchannel::nojitter, misdn_bchannel::orig, chan_list::originator, misdn_bchannel::port, misdn_bchannel::presentation, misdn_bchannel::rxgain, misdn_bchannel::send_dtmf, misdn_bchannel::set_presentation, strsep(), ast_channel::tech, misdn_bchannel::txgain, and ast_channel_tech::type.
Referenced by load_module(), and misdn_call().
12227 { 12228 struct chan_list *ch = MISDN_ASTERISK_TECH_PVT(chan); 12229 char *tok; 12230 char *tokb; 12231 char *parse; 12232 int keyidx = 0; 12233 int rxgain = 0; 12234 int txgain = 0; 12235 int change_jitter = 0; 12236 12237 if (strcasecmp(chan->tech->type, misdn_type)) { 12238 ast_log(LOG_WARNING, "misdn_set_opt makes sense only with %s channels!\n", misdn_type); 12239 return -1; 12240 } 12241 12242 if (ast_strlen_zero((char *) data)) { 12243 ast_log(LOG_WARNING, "misdn_set_opt Requires arguments\n"); 12244 return -1; 12245 } 12246 12247 parse = ast_strdupa(data); 12248 for (tok = strtok_r(parse, ":", &tokb); 12249 tok; 12250 tok = strtok_r(NULL, ":", &tokb)) { 12251 int neglect = 0; 12252 12253 if (tok[0] == '!') { 12254 neglect = 1; 12255 tok++; 12256 } 12257 12258 switch(tok[0]) { 12259 case 'd' : 12260 ast_copy_string(ch->bc->display, ++tok, sizeof(ch->bc->display)); 12261 chan_misdn_log(1, ch->bc->port, "SETOPT: Display:%s\n", ch->bc->display); 12262 break; 12263 case 'n': 12264 chan_misdn_log(1, ch->bc->port, "SETOPT: No DSP\n"); 12265 ch->bc->nodsp = 1; 12266 break; 12267 case 'j': 12268 chan_misdn_log(1, ch->bc->port, "SETOPT: jitter\n"); 12269 tok++; 12270 change_jitter = 1; 12271 12272 switch (tok[0]) { 12273 case 'b': 12274 ch->jb_len = atoi(++tok); 12275 chan_misdn_log(1, ch->bc->port, " --> buffer_len:%d\n", ch->jb_len); 12276 break; 12277 case 't' : 12278 ch->jb_upper_threshold = atoi(++tok); 12279 chan_misdn_log(1, ch->bc->port, " --> upper_threshold:%d\n", ch->jb_upper_threshold); 12280 break; 12281 case 'n': 12282 ch->bc->nojitter = 1; 12283 chan_misdn_log(1, ch->bc->port, " --> nojitter\n"); 12284 break; 12285 default: 12286 ch->jb_len = 4000; 12287 ch->jb_upper_threshold = 0; 12288 chan_misdn_log(1, ch->bc->port, " --> buffer_len:%d (default)\n", ch->jb_len); 12289 chan_misdn_log(1, ch->bc->port, " --> upper_threshold:%d (default)\n", ch->jb_upper_threshold); 12290 break; 12291 } 12292 break; 12293 case 'v': 12294 tok++; 12295 12296 switch (tok[0]) { 12297 case 'r' : 12298 rxgain = atoi(++tok); 12299 if (rxgain < -8) { 12300 rxgain = -8; 12301 } 12302 if (rxgain > 8) { 12303 rxgain = 8; 12304 } 12305 ch->bc->rxgain = rxgain; 12306 chan_misdn_log(1, ch->bc->port, "SETOPT: Volume:%d\n", rxgain); 12307 break; 12308 case 't': 12309 txgain = atoi(++tok); 12310 if (txgain < -8) { 12311 txgain = -8; 12312 } 12313 if (txgain > 8) { 12314 txgain = 8; 12315 } 12316 ch->bc->txgain = txgain; 12317 chan_misdn_log(1, ch->bc->port, "SETOPT: Volume:%d\n", txgain); 12318 break; 12319 } 12320 break; 12321 case 'c': 12322 keyidx = atoi(++tok); 12323 { 12324 char keys[4096]; 12325 char *key = NULL; 12326 char *tmp = keys; 12327 int i; 12328 12329 misdn_cfg_get(0, MISDN_GEN_CRYPT_KEYS, keys, sizeof(keys)); 12330 12331 for (i = 0; i < keyidx; i++) { 12332 key = strsep(&tmp, ","); 12333 } 12334 12335 if (key) { 12336 ast_copy_string(ch->bc->crypt_key, key, sizeof(ch->bc->crypt_key)); 12337 } 12338 12339 chan_misdn_log(0, ch->bc->port, "SETOPT: crypt with key:%s\n", ch->bc->crypt_key); 12340 break; 12341 } 12342 case 'e': 12343 chan_misdn_log(1, ch->bc->port, "SETOPT: EchoCancel\n"); 12344 12345 if (neglect) { 12346 chan_misdn_log(1, ch->bc->port, " --> disabled\n"); 12347 #ifdef MISDN_1_2 12348 *ch->bc->pipeline = 0; 12349 #else 12350 ch->bc->ec_enable = 0; 12351 #endif 12352 } else { 12353 #ifdef MISDN_1_2 12354 update_pipeline_config(ch->bc); 12355 #else 12356 ch->bc->ec_enable = 1; 12357 ch->bc->orig = ch->originator; 12358 tok++; 12359 if (*tok) { 12360 ch->bc->ec_deftaps = atoi(tok); 12361 } 12362 #endif 12363 } 12364 break; 12365 case 'h': 12366 chan_misdn_log(1, ch->bc->port, "SETOPT: Digital\n"); 12367 12368 if (strlen(tok) > 1 && tok[1] == '1') { 12369 chan_misdn_log(1, ch->bc->port, "SETOPT: HDLC \n"); 12370 if (!ch->bc->hdlc) { 12371 ch->bc->hdlc = 1; 12372 } 12373 } 12374 ch->bc->capability = INFO_CAPABILITY_DIGITAL_UNRESTRICTED; 12375 break; 12376 case 's': 12377 chan_misdn_log(1, ch->bc->port, "SETOPT: Send DTMF\n"); 12378 ch->bc->send_dtmf = 1; 12379 break; 12380 case 'f': 12381 chan_misdn_log(1, ch->bc->port, "SETOPT: Faxdetect\n"); 12382 ch->faxdetect = 1; 12383 misdn_cfg_get(ch->bc->port, MISDN_CFG_FAXDETECT_TIMEOUT, &ch->faxdetect_timeout, sizeof(ch->faxdetect_timeout)); 12384 break; 12385 case 'a': 12386 chan_misdn_log(1, ch->bc->port, "SETOPT: AST_DSP (for DTMF)\n"); 12387 ch->ast_dsp = 1; 12388 break; 12389 case 'p': 12390 chan_misdn_log(1, ch->bc->port, "SETOPT: callerpres: %s\n", &tok[1]); 12391 /* CRICH: callingpres!!! */ 12392 if (strstr(tok, "allowed")) { 12393 ch->bc->presentation = 0; 12394 ch->bc->set_presentation = 1; 12395 } else if (strstr(tok, "restricted")) { 12396 ch->bc->presentation = 1; 12397 ch->bc->set_presentation = 1; 12398 } else if (strstr(tok, "not_screened")) { 12399 chan_misdn_log(0, ch->bc->port, "SETOPT: callerpres: not_screened is deprecated\n"); 12400 ch->bc->presentation = 1; 12401 ch->bc->set_presentation = 1; 12402 } 12403 break; 12404 case 'i' : 12405 chan_misdn_log(1, ch->bc->port, "Ignoring dtmf tones, just use them inband\n"); 12406 ch->ignore_dtmf = 1; 12407 break; 12408 default: 12409 break; 12410 } 12411 } 12412 12413 if (change_jitter) { 12414 config_jitterbuffer(ch); 12415 } 12416 12417 if (ch->faxdetect || ch->ast_dsp) { 12418 if (!ch->dsp) { 12419 ch->dsp = ast_dsp_new(); 12420 } 12421 if (ch->dsp) { 12422 ast_dsp_set_features(ch->dsp, DSP_FEATURE_DIGIT_DETECT | DSP_FEATURE_FAX_DETECT); 12423 } 12424 } 12425 12426 if (ch->ast_dsp) { 12427 chan_misdn_log(1, ch->bc->port, "SETOPT: with AST_DSP we deactivate mISDN_dsp\n"); 12428 ch->bc->nodsp = 1; 12429 } 12430 12431 return 0; 12432 }
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(), misdn_tasks, misdn_tasks_thread, 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, misdn_tasks_thread, 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, and misdn_tasks.
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(), misdn_tasks, 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.
References misdn_tasks_thread.
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 6107 of file chan_misdn.c.
References ast_party_caller::ani, ast_channel_lock, ast_channel_set_caller_event(), ast_channel_unlock, ast_party_caller_set_init(), ast_channel::caller, id, ast_party_caller::id, misdn_to_ast_plan(), misdn_to_ast_pres(), misdn_to_ast_screen(), misdn_to_ast_ton(), ast_party_id::number, ast_party_number::plan, ast_party_number::presentation, ast_party_number::str, ast_party_id::tag, and ast_party_number::valid.
Referenced by misdn_update_remote_party().
06108 { 06109 struct ast_party_caller caller; 06110 struct ast_set_party_caller update_caller; 06111 06112 memset(&update_caller, 0, sizeof(update_caller)); 06113 update_caller.id.number = 1; 06114 update_caller.ani.number = 1; 06115 06116 ast_channel_lock(ast); 06117 ast_party_caller_set_init(&caller, &ast->caller); 06118 06119 caller.id.number.valid = 1; 06120 caller.id.number.str = (char *) id->number; 06121 caller.id.number.plan = misdn_to_ast_ton(id->number_type) 06122 | misdn_to_ast_plan(id->number_plan); 06123 caller.id.number.presentation = misdn_to_ast_pres(id->presentation) 06124 | misdn_to_ast_screen(id->screening); 06125 06126 caller.ani.number = caller.id.number; 06127 06128 caller.id.tag = cid_tag; 06129 caller.ani.tag = cid_tag; 06130 06131 ast_channel_set_caller_event(ast, &caller, &update_caller); 06132 ast_channel_unlock(ast); 06133 }
static void misdn_update_connected_line | ( | struct ast_channel * | ast, | |
struct misdn_bchannel * | bc, | |||
int | originator | |||
) | [static] |
Definition at line 6235 of file chan_misdn.c.
References chan_list::ast, chan_list::bc, misdn_bchannel::caller, misdn_bchannel::connected, EVENT_FACILITY, EVENT_NOTIFY, misdn_bchannel::fac_out, MISDN_ASTERISK_TECH_PVT, MISDN_CONNECTED, misdn_get_connected_line(), misdn_lib_is_ptp(), misdn_lib_port_is_nt(), misdn_lib_send_event(), mISDN_NOTIFY_CODE_CALL_TRANSFER_ACTIVE, misdn_bchannel::notify_description_code, ORG_MISDN, misdn_bchannel::outgoing_colp, misdn_bchannel::port, misdn_party_id::presentation, print_facility(), misdn_bchannel::redirecting, chan_list::state, misdn_party_redirecting::to, and misdn_party_redirecting::to_changed.
Referenced by misdn_indication().
06236 { 06237 struct chan_list *ch; 06238 06239 misdn_get_connected_line(ast, bc, originator); 06240 if (originator == ORG_MISDN) { 06241 bc->redirecting.to = bc->connected; 06242 } else { 06243 bc->redirecting.to = bc->caller; 06244 } 06245 switch (bc->outgoing_colp) { 06246 case 1:/* restricted */ 06247 bc->redirecting.to.presentation = 1;/* restricted */ 06248 break; 06249 case 2:/* blocked */ 06250 /* Don't tell the remote party that the call was transferred. */ 06251 return; 06252 default: 06253 break; 06254 } 06255 06256 ch = MISDN_ASTERISK_TECH_PVT(ast); 06257 if (ch->state == MISDN_CONNECTED 06258 || originator != ORG_MISDN) { 06259 int is_ptmp; 06260 06261 is_ptmp = !misdn_lib_is_ptp(bc->port); 06262 if (is_ptmp) { 06263 /* 06264 * We should not send these messages to the network if we are 06265 * the CPE side since phones do not transfer calls within 06266 * themselves. Well... If you consider handing the handset to 06267 * someone else a transfer then how is the network to know? 06268 */ 06269 if (!misdn_lib_port_is_nt(bc->port)) { 06270 return; 06271 } 06272 if (ch->state != MISDN_CONNECTED) { 06273 /* Send NOTIFY(Nie(transfer-active), RDNie(redirecting.to data)) */ 06274 bc->redirecting.to_changed = 1; 06275 bc->notify_description_code = mISDN_NOTIFY_CODE_CALL_TRANSFER_ACTIVE; 06276 misdn_lib_send_event(bc, EVENT_NOTIFY); 06277 #if defined(AST_MISDN_ENHANCEMENTS) 06278 } else { 06279 /* Send FACILITY(Fie(RequestSubaddress), Nie(transfer-active), RDNie(redirecting.to data)) */ 06280 bc->redirecting.to_changed = 1; 06281 bc->notify_description_code = mISDN_NOTIFY_CODE_CALL_TRANSFER_ACTIVE; 06282 bc->fac_out.Function = Fac_RequestSubaddress; 06283 bc->fac_out.u.RequestSubaddress.InvokeID = ++misdn_invoke_id; 06284 06285 /* Send message */ 06286 print_facility(&bc->fac_out, bc); 06287 misdn_lib_send_event(bc, EVENT_FACILITY); 06288 #endif /* defined(AST_MISDN_ENHANCEMENTS) */ 06289 } 06290 #if defined(AST_MISDN_ENHANCEMENTS) 06291 } else { 06292 /* Send FACILITY(Fie(EctInform(transfer-active, redirecting.to data))) */ 06293 bc->fac_out.Function = Fac_EctInform; 06294 bc->fac_out.u.EctInform.InvokeID = ++misdn_invoke_id; 06295 bc->fac_out.u.EctInform.Status = 1;/* active */ 06296 bc->fac_out.u.EctInform.RedirectionPresent = 1;/* Must be present when status is active */ 06297 misdn_PresentedNumberUnscreened_fill(&bc->fac_out.u.EctInform.Redirection, 06298 &bc->redirecting.to); 06299 06300 /* Send message */ 06301 print_facility(&bc->fac_out, bc); 06302 misdn_lib_send_event(bc, EVENT_FACILITY); 06303 #endif /* defined(AST_MISDN_ENHANCEMENTS) */ 06304 } 06305 } 06306 }
static void misdn_update_redirecting | ( | struct ast_channel * | ast, | |
struct misdn_bchannel * | bc, | |||
int | originator | |||
) | [static] |
Definition at line 6415 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().
06416 { 06417 int is_ptmp; 06418 06419 misdn_copy_redirecting_from_ast(bc, ast); 06420 switch (bc->outgoing_colp) { 06421 case 1:/* restricted */ 06422 bc->redirecting.to.presentation = 1;/* restricted */ 06423 break; 06424 case 2:/* blocked */ 06425 /* Don't tell the remote party that the call was redirected. */ 06426 return; 06427 default: 06428 break; 06429 } 06430 06431 if (originator != ORG_MISDN) { 06432 return; 06433 } 06434 06435 is_ptmp = !misdn_lib_is_ptp(bc->port); 06436 if (is_ptmp) { 06437 /* 06438 * We should not send these messages to the network if we are 06439 * the CPE side since phones do not redirect calls within 06440 * themselves. Well... If you consider someone else picking up 06441 * the handset a redirection then how is the network to know? 06442 */ 06443 if (!misdn_lib_port_is_nt(bc->port)) { 06444 return; 06445 } 06446 /* Send NOTIFY(call-is-diverting, redirecting.to data) */ 06447 bc->redirecting.to_changed = 1; 06448 bc->notify_description_code = mISDN_NOTIFY_CODE_CALL_IS_DIVERTING; 06449 misdn_lib_send_event(bc, EVENT_NOTIFY); 06450 #if defined(AST_MISDN_ENHANCEMENTS) 06451 } else { 06452 int match; /* TRUE if the dialed number matches the redirecting to number */ 06453 06454 match = (strcmp(ast->exten, bc->redirecting.to.number) == 0) ? 1 : 0; 06455 if (!bc->div_leg_3_tx_pending 06456 || !match) { 06457 /* Send DivertingLegInformation1 */ 06458 bc->fac_out.Function = Fac_DivertingLegInformation1; 06459 bc->fac_out.u.DivertingLegInformation1.InvokeID = ++misdn_invoke_id; 06460 bc->fac_out.u.DivertingLegInformation1.DiversionReason = 06461 misdn_to_diversion_reason(bc->redirecting.reason); 06462 bc->fac_out.u.DivertingLegInformation1.SubscriptionOption = 2;/* notificationWithDivertedToNr */ 06463 bc->fac_out.u.DivertingLegInformation1.DivertedToPresent = 1; 06464 misdn_PresentedNumberUnscreened_fill(&bc->fac_out.u.DivertingLegInformation1.DivertedTo, &bc->redirecting.to); 06465 print_facility(&bc->fac_out, bc); 06466 misdn_lib_send_event(bc, EVENT_FACILITY); 06467 } 06468 bc->div_leg_3_tx_pending = 0; 06469 06470 /* Send DivertingLegInformation3 */ 06471 bc->fac_out.Function = Fac_DivertingLegInformation3; 06472 bc->fac_out.u.DivertingLegInformation3.InvokeID = ++misdn_invoke_id; 06473 bc->fac_out.u.DivertingLegInformation3.PresentationAllowedIndicator = 06474 bc->redirecting.to.presentation == 0 ? 1 : 0; 06475 print_facility(&bc->fac_out, bc); 06476 misdn_lib_send_event(bc, EVENT_FACILITY); 06477 #endif /* defined(AST_MISDN_ENHANCEMENTS) */ 06478 } 06479 }
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 6146 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().
06147 { 06148 misdn_update_caller_id(ast, id, cid_tag); 06149 misdn_queue_connected_line_update(ast, id, source, cid_tag); 06150 }
static int misdn_write | ( | struct ast_channel * | ast, | |
struct ast_frame * | frame | |||
) | [static] |
Definition at line 7405 of file chan_misdn.c.
References misdn_bchannel::addr, chan_list::ast, ast_debug, ast_getformatname(), ast_log(), chan_list::bc, misdn_bchannel::bc_state, BCHAN_ACTIVATED, BCHAN_BRIDGED, ast_channel::caller, chan_misdn_log(), ast_frame_subclass::codec, ast_frame::data, chan_list::dropped_frame_cnt, ast_channel::exten, chan_list::frame, chan_list::hold, ast_party_caller::id, misdn_bchannel::l3_id, LOG_WARNING, MISDN_ASTERISK_TECH_PVT, misdn_get_ch_state(), MISDN_HOLD_IDLE, misdn_lib_tone_generator_start(), chan_list::notxtone, ast_party_id::number, misdn_bchannel::port, prefformat, ast_frame::ptr, S_COR, ast_frame::samples, ast_frame::src, hold_info::state, ast_party_number::str, ast_frame::subclass, chan_list::ts, and ast_party_number::valid.
07406 { 07407 struct chan_list *ch; 07408 07409 if (!ast || !(ch = MISDN_ASTERISK_TECH_PVT(ast))) { 07410 return -1; 07411 } 07412 07413 if (ch->hold.state != MISDN_HOLD_IDLE) { 07414 chan_misdn_log(7, 0, "misdn_write: Returning because hold active\n"); 07415 return 0; 07416 } 07417 07418 if (!ch->bc) { 07419 ast_log(LOG_WARNING, "private but no bc\n"); 07420 return -1; 07421 } 07422 07423 if (ch->notxtone) { 07424 chan_misdn_log(7, ch->bc->port, "misdn_write: Returning because notxtone\n"); 07425 return 0; 07426 } 07427 07428 07429 if (!frame->subclass.codec) { 07430 chan_misdn_log(4, ch->bc->port, "misdn_write: * prods us\n"); 07431 return 0; 07432 } 07433 07434 if (!(frame->subclass.codec & prefformat)) { 07435 chan_misdn_log(-1, ch->bc->port, "Got Unsupported Frame with Format:%s\n", ast_getformatname(frame->subclass.codec)); 07436 return 0; 07437 } 07438 07439 07440 if (!frame->samples) { 07441 chan_misdn_log(4, ch->bc->port, "misdn_write: zero write\n"); 07442 07443 if (!strcmp(frame->src,"ast_prod")) { 07444 chan_misdn_log(1, ch->bc->port, "misdn_write: state (%s) prodded.\n", misdn_get_ch_state(ch)); 07445 07446 if (ch->ts) { 07447 chan_misdn_log(4, ch->bc->port, "Starting Playtones\n"); 07448 misdn_lib_tone_generator_start(ch->bc); 07449 } 07450 return 0; 07451 } 07452 07453 return -1; 07454 } 07455 07456 if (!ch->bc->addr) { 07457 chan_misdn_log(8, ch->bc->port, "misdn_write: no addr for bc dropping:%d\n", frame->samples); 07458 return 0; 07459 } 07460 07461 #ifdef MISDN_DEBUG 07462 { 07463 int i; 07464 int max = 5 > frame->samples ? frame->samples : 5; 07465 07466 ast_debug(1, "write2mISDN %p %d bytes: ", p, frame->samples); 07467 07468 for (i = 0; i < max; i++) { 07469 ast_debug(1, "%2.2x ", ((char *) frame->data.ptr)[i]); 07470 } 07471 } 07472 #endif 07473 07474 switch (ch->bc->bc_state) { 07475 case BCHAN_ACTIVATED: 07476 case BCHAN_BRIDGED: 07477 break; 07478 default: 07479 if (!ch->dropped_frame_cnt) { 07480 chan_misdn_log(5, ch->bc->port, 07481 "BC not active (nor bridged) dropping: %d frames addr:%x exten:%s cid:%s ch->state:%s bc_state:%d l3id:%x\n", 07482 frame->samples, ch->bc->addr, ast->exten, 07483 S_COR(ast->caller.id.number.valid, ast->caller.id.number.str, ""), 07484 misdn_get_ch_state(ch), ch->bc->bc_state, ch->bc->l3_id); 07485 } 07486 07487 if (++ch->dropped_frame_cnt > 100) { 07488 ch->dropped_frame_cnt = 0; 07489 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); 07490 } 07491 07492 return 0; 07493 } 07494 07495 chan_misdn_log(9, ch->bc->port, "Sending :%d bytes to MISDN\n", frame->samples); 07496 if (!ch->bc->nojitter && misdn_cap_is_speech(ch->bc->capability)) { 07497 /* Buffered Transmit (triggered by read from isdn side)*/ 07498 if (misdn_jb_fill(ch->jb, frame->data.ptr, frame->samples) < 0) { 07499 if (ch->bc->active) { 07500 cb_log(0, ch->bc->port, "Misdn Jitterbuffer Overflow.\n"); 07501 } 07502 } 07503 07504 } else { 07505 /* transmit without jitterbuffer */ 07506 misdn_lib_tx2misdn_frm(ch->bc, frame->data.ptr, frame->samples); 07507 } 07508 07509 return 0; 07510 }
static int pbx_start_chan | ( | struct chan_list * | ch | ) | [static] |
Channel Queue End
Definition at line 8366 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().
08367 { 08368 int ret = ast_pbx_start(ch->ast); 08369 08370 ch->need_hangup = (ret >= 0) ? 0 : 1; 08371 08372 return ret; 08373 }
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_debug, misdn_get_ch_state(), ast_channel::name, misdn_party_id::name, ast_party_id::name, chan_list::norxtone, chan_list::notxtone, misdn_bchannel::nt, misdn_party_id::number, ast_party_id::number, ORG_AST, chan_list::originator, misdn_bchannel::pid, misdn_bchannel::port, misdn_bchannel::redirecting, ast_party_number::str, ast_party_name::str, misdn_party_redirecting::to, ast_party_number::valid, and ast_party_name::valid.
Referenced by handle_cli_misdn_show_channel(), and handle_cli_misdn_show_channels().
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 help->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 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] |
Definition at line 7245 of file chan_misdn.c.
References chan_list::ast, ast_async_goto(), ast_debug, chan_list::ast_dsp, ast_dsp_process(), ast_exists_extension(), AST_FRAME_DTMF, ast_log(), ast_strlen_zero(), ast_verb, chan_list::bc, BUFFERSIZE, chan_misdn_log(), ast_channel::context, context, chan_list::dsp, misdn_bchannel::ec_enable, ast_channel::exten, f, chan_list::faxdetect, chan_list::faxhandled, isdn_lib_stop_dtmf(), isdn_lib_update_ec(), isdn_lib_update_rxgain(), isdn_lib_update_txgain(), LOG_NOTICE, LOG_WARNING, ast_channel::macrocontext, MISDN_CFG_FAXDETECT_CONTEXT, misdn_cfg_get(), ast_channel::name, pbx_builtin_setvar_helper(), misdn_bchannel::port, misdn_bchannel::rxgain, S_COR, and misdn_bchannel::txgain.
Referenced by misdn_read().
07246 { 07247 struct ast_frame *f; 07248 07249 if (tmp->dsp) { 07250 f = ast_dsp_process(tmp->ast, tmp->dsp, frame); 07251 } else { 07252 chan_misdn_log(0, tmp->bc->port, "No DSP-Path found\n"); 07253 return NULL; 07254 } 07255 07256 if (!f || (f->frametype != AST_FRAME_DTMF)) { 07257 return f; 07258 } 07259 07260 ast_debug(1, "Detected inband DTMF digit: %c\n", f->subclass.integer); 07261 07262 if (tmp->faxdetect && (f->subclass.integer == 'f')) { 07263 /* Fax tone -- Handle and return NULL */ 07264 if (!tmp->faxhandled) { 07265 struct ast_channel *ast = tmp->ast; 07266 tmp->faxhandled++; 07267 chan_misdn_log(0, tmp->bc->port, "Fax detected, preparing %s for fax transfer.\n", ast->name); 07268 tmp->bc->rxgain = 0; 07269 isdn_lib_update_rxgain(tmp->bc); 07270 tmp->bc->txgain = 0; 07271 isdn_lib_update_txgain(tmp->bc); 07272 #ifdef MISDN_1_2 07273 *tmp->bc->pipeline = 0; 07274 #else 07275 tmp->bc->ec_enable = 0; 07276 #endif 07277 isdn_lib_update_ec(tmp->bc); 07278 isdn_lib_stop_dtmf(tmp->bc); 07279 switch (tmp->faxdetect) { 07280 case 1: 07281 if (strcmp(ast->exten, "fax")) { 07282 char *context; 07283 char context_tmp[BUFFERSIZE]; 07284 misdn_cfg_get(tmp->bc->port, MISDN_CFG_FAXDETECT_CONTEXT, &context_tmp, sizeof(context_tmp)); 07285 context = ast_strlen_zero(context_tmp) ? (ast_strlen_zero(ast->macrocontext) ? ast->context : ast->macrocontext) : context_tmp; 07286 if (ast_exists_extension(ast, context, "fax", 1, 07287 S_COR(ast->caller.id.number.valid, ast->caller.id.number.str, NULL))) { 07288 ast_verb(3, "Redirecting %s to fax extension (context:%s)\n", ast->name, context); 07289 /* Save the DID/DNIS when we transfer the fax call to a "fax" extension */ 07290 pbx_builtin_setvar_helper(ast,"FAXEXTEN",ast->exten); 07291 if (ast_async_goto(ast, context, "fax", 1)) { 07292 ast_log(LOG_WARNING, "Failed to async goto '%s' into fax of '%s'\n", ast->name, context); 07293 } 07294 } else { 07295 ast_log(LOG_NOTICE, "Fax detected but no fax extension, context:%s exten:%s\n", context, ast->exten); 07296 } 07297 } else { 07298 ast_debug(1, "Already in a fax extension, not redirecting\n"); 07299 } 07300 break; 07301 case 2: 07302 ast_verb(3, "Not redirecting %s to fax extension, nojump is set.\n", ast->name); 07303 break; 07304 default: 07305 break; 07306 } 07307 } else { 07308 ast_debug(1, "Fax already handled\n"); 07309 } 07310 } 07311 07312 if (tmp->ast_dsp && (f->subclass.integer != 'f')) { 07313 chan_misdn_log(2, tmp->bc->port, " --> * SEND: DTMF (AST_DSP) :%c\n", f->subclass.integer); 07314 } 07315 07316 return f; 07317 }
static int read_config | ( | struct chan_list * | ch | ) | [static] |
Definition at line 5892 of file chan_misdn.c.
References chan_list::allowed_bearers, misdn_bchannel::AOCDtype, chan_list::ast, ast_callerid_parse(), ast_copy_string(), chan_list::ast_dsp, ast_dsp_new(), ast_dsp_set_features(), ast_log(), ast_mutex_init, ast_print_group(), ast_string_field_set, ast_strlen_zero(), chan_list::bc, buf2, BUFFERSIZE, misdn_bchannel::caller, ast_channel::callgroup, misdn_bchannel::capability, chan_misdn_log(), cid_name, cid_num, config_jitterbuffer(), ast_channel::context, chan_list::context, debug_numtype(), misdn_bchannel::dialed, misdn_bchannel::display_connected, misdn_bchannel::display_setup, chan_list::dsp, DSP_FEATURE_DIGIT_DETECT, DSP_FEATURE_FAX_DETECT, misdn_bchannel::early_bconnect, ast_channel::exten, chan_list::far_alerting, chan_list::faxdetect, chan_list::faxdetect_timeout, misdn_bchannel::hdlc, chan_list::ignore_dtmf, misdn_bchannel::incoming_cid_tag, chan_list::incoming_early_audio, INFO_CAPABILITY_DIGITAL_RESTRICTED, INFO_CAPABILITY_DIGITAL_UNRESTRICTED, chan_list::jb_len, chan_list::jb_upper_threshold, misdn_bchannel::keypad, language, LOG_WARNING, misdn_add_number_prefix(), MISDN_CFG_ALLOWED_BEARERS, MISDN_CFG_ASTDTMF, MISDN_CFG_CALLERID, MISDN_CFG_CALLGROUP, MISDN_CFG_CONTEXT, MISDN_CFG_DIALPLAN, MISDN_CFG_DISPLAY_CONNECTED, MISDN_CFG_DISPLAY_SETUP, MISDN_CFG_EARLY_BCONNECT, MISDN_CFG_FAR_ALERTING, MISDN_CFG_FAXDETECT, MISDN_CFG_FAXDETECT_TIMEOUT, misdn_cfg_get(), MISDN_CFG_HDLC, MISDN_CFG_INCOMING_CALLERID_TAG, MISDN_CFG_INCOMING_EARLY_AUDIO, MISDN_CFG_JITTERBUFFER, MISDN_CFG_JITTERBUFFER_UPPER_THRESHOLD, MISDN_CFG_LANGUAGE, MISDN_CFG_MUSICCLASS, MISDN_CFG_NEED_MORE_INFOS, MISDN_CFG_NOAUTORESPOND_ON_SETUP, MISDN_CFG_NTTIMEOUT, MISDN_CFG_OUTGOING_COLP, MISDN_CFG_OVERLAP_DIAL, MISDN_CFG_PICKUPGROUP, MISDN_CFG_RXGAIN, MISDN_CFG_SENDDTMF, MISDN_CFG_TE_CHOOSE_CHANNEL, MISDN_CFG_TXGAIN, chan_list::mohinterpret, misdn_party_id::name, misdn_bchannel::need_more_infos, chan_list::noautorespond_on_setup, chan_list::nttimeout, misdn_party_dialing::number, misdn_party_id::number, misdn_party_dialing::number_plan, misdn_party_id::number_type, misdn_party_dialing::number_type, NUMPLAN_ISDN, ORG_AST, chan_list::originator, misdn_bchannel::outgoing_colp, chan_list::overlap_dial, chan_list::overlap_dial_task, chan_list::overlap_tv_lock, ast_channel::pickupgroup, misdn_bchannel::port, misdn_bchannel::rxgain, misdn_bchannel::send_dtmf, misdn_bchannel::te_choose_channel, misdn_bchannel::txgain, and update_ec_config().
Referenced by cb_events().
05893 { 05894 struct ast_channel *ast; 05895 struct misdn_bchannel *bc; 05896 int port; 05897 int hdlc = 0; 05898 char lang[BUFFERSIZE + 1]; 05899 char faxdetect[BUFFERSIZE + 1]; 05900 char buf[256]; 05901 char buf2[256]; 05902 ast_group_t pg; 05903 ast_group_t cg; 05904 05905 if (!ch) { 05906 ast_log(LOG_WARNING, "Cannot configure without chanlist\n"); 05907 return -1; 05908 } 05909 05910 ast = ch->ast; 05911 bc = ch->bc; 05912 if (! ast || ! bc) { 05913 ast_log(LOG_WARNING, "Cannot configure without ast || bc\n"); 05914 return -1; 05915 } 05916 05917 port = bc->port; 05918 chan_misdn_log(1, port, "read_config: Getting Config\n"); 05919 05920 misdn_cfg_get(port, MISDN_CFG_LANGUAGE, lang, sizeof(lang)); 05921 ast_string_field_set(ast, language, lang); 05922 05923 misdn_cfg_get(port, MISDN_CFG_MUSICCLASS, ch->mohinterpret, sizeof(ch->mohinterpret)); 05924 05925 misdn_cfg_get(port, MISDN_CFG_TXGAIN, &bc->txgain, sizeof(bc->txgain)); 05926 misdn_cfg_get(port, MISDN_CFG_RXGAIN, &bc->rxgain, sizeof(bc->rxgain)); 05927 05928 misdn_cfg_get(port, MISDN_CFG_INCOMING_EARLY_AUDIO, &ch->incoming_early_audio, sizeof(ch->incoming_early_audio)); 05929 05930 misdn_cfg_get(port, MISDN_CFG_SENDDTMF, &bc->send_dtmf, sizeof(bc->send_dtmf)); 05931 05932 misdn_cfg_get(port, MISDN_CFG_ASTDTMF, &ch->ast_dsp, sizeof(int)); 05933 if (ch->ast_dsp) { 05934 ch->ignore_dtmf = 1; 05935 } 05936 05937 misdn_cfg_get(port, MISDN_CFG_NEED_MORE_INFOS, &bc->need_more_infos, sizeof(bc->need_more_infos)); 05938 misdn_cfg_get(port, MISDN_CFG_NTTIMEOUT, &ch->nttimeout, sizeof(ch->nttimeout)); 05939 05940 misdn_cfg_get(port, MISDN_CFG_NOAUTORESPOND_ON_SETUP, &ch->noautorespond_on_setup, sizeof(ch->noautorespond_on_setup)); 05941 05942 misdn_cfg_get(port, MISDN_CFG_FAR_ALERTING, &ch->far_alerting, sizeof(ch->far_alerting)); 05943 05944 misdn_cfg_get(port, MISDN_CFG_ALLOWED_BEARERS, &ch->allowed_bearers, sizeof(ch->allowed_bearers)); 05945 05946 misdn_cfg_get(port, MISDN_CFG_FAXDETECT, faxdetect, sizeof(faxdetect)); 05947 05948 misdn_cfg_get(port, MISDN_CFG_HDLC, &hdlc, sizeof(hdlc)); 05949 if (hdlc) { 05950 switch (bc->capability) { 05951 case INFO_CAPABILITY_DIGITAL_UNRESTRICTED: 05952 case INFO_CAPABILITY_DIGITAL_RESTRICTED: 05953 chan_misdn_log(1, bc->port, " --> CONF HDLC\n"); 05954 bc->hdlc = 1; 05955 break; 05956 } 05957 05958 } 05959 /*Initialize new Jitterbuffer*/ 05960 misdn_cfg_get(port, MISDN_CFG_JITTERBUFFER, &ch->jb_len, sizeof(ch->jb_len)); 05961 misdn_cfg_get(port, MISDN_CFG_JITTERBUFFER_UPPER_THRESHOLD, &ch->jb_upper_threshold, sizeof(ch->jb_upper_threshold)); 05962 05963 config_jitterbuffer(ch); 05964 05965 misdn_cfg_get(bc->port, MISDN_CFG_CONTEXT, ch->context, sizeof(ch->context)); 05966 05967 ast_copy_string(ast->context, ch->context, sizeof(ast->context)); 05968 05969 #ifdef MISDN_1_2 05970 update_pipeline_config(bc); 05971 #else 05972 update_ec_config(bc); 05973 #endif 05974 05975 misdn_cfg_get(bc->port, MISDN_CFG_EARLY_BCONNECT, &bc->early_bconnect, sizeof(bc->early_bconnect)); 05976 05977 misdn_cfg_get(port, MISDN_CFG_DISPLAY_CONNECTED, &bc->display_connected, sizeof(bc->display_connected)); 05978 misdn_cfg_get(port, MISDN_CFG_DISPLAY_SETUP, &bc->display_setup, sizeof(bc->display_setup)); 05979 misdn_cfg_get(port, MISDN_CFG_OUTGOING_COLP, &bc->outgoing_colp, sizeof(bc->outgoing_colp)); 05980 05981 misdn_cfg_get(port, MISDN_CFG_PICKUPGROUP, &pg, sizeof(pg)); 05982 misdn_cfg_get(port, MISDN_CFG_CALLGROUP, &cg, sizeof(cg)); 05983 chan_misdn_log(5, port, " --> * CallGrp:%s PickupGrp:%s\n", ast_print_group(buf, sizeof(buf), cg), ast_print_group(buf2, sizeof(buf2), pg)); 05984 ast->pickupgroup = pg; 05985 ast->callgroup = cg; 05986 05987 if (ch->originator == ORG_AST) { 05988 char callerid[BUFFERSIZE + 1]; 05989 05990 /* ORIGINATOR Asterisk (outgoing call) */ 05991 05992 misdn_cfg_get(port, MISDN_CFG_TE_CHOOSE_CHANNEL, &(bc->te_choose_channel), sizeof(bc->te_choose_channel)); 05993 05994 if (strstr(faxdetect, "outgoing") || strstr(faxdetect, "both")) { 05995 ch->faxdetect = strstr(faxdetect, "nojump") ? 2 : 1; 05996 } 05997 05998 misdn_cfg_get(port, MISDN_CFG_CALLERID, callerid, sizeof(callerid)); 05999 if (!ast_strlen_zero(callerid)) { 06000 char *cid_name = NULL; 06001 char *cid_num = NULL; 06002 06003 ast_callerid_parse(callerid, &cid_name, &cid_num); 06004 if (cid_name) { 06005 ast_copy_string(bc->caller.name, cid_name, sizeof(bc->caller.name)); 06006 } else { 06007 bc->caller.name[0] = '\0'; 06008 } 06009 if (cid_num) { 06010 ast_copy_string(bc->caller.number, cid_num, sizeof(bc->caller.number)); 06011 } else { 06012 bc->caller.number[0] = '\0'; 06013 } 06014 chan_misdn_log(1, port, " --> * Setting caller to \"%s\" <%s>\n", bc->caller.name, bc->caller.number); 06015 } 06016 06017 misdn_cfg_get(port, MISDN_CFG_DIALPLAN, &bc->dialed.number_type, sizeof(bc->dialed.number_type)); 06018 bc->dialed.number_plan = NUMPLAN_ISDN; 06019 debug_numtype(port, bc->dialed.number_type, "TON"); 06020 06021 ch->overlap_dial = 0; 06022 } else { 06023 /* ORIGINATOR MISDN (incoming call) */ 06024 06025 if (strstr(faxdetect, "incoming") || strstr(faxdetect, "both")) { 06026 ch->faxdetect = (strstr(faxdetect, "nojump")) ? 2 : 1; 06027 } 06028 06029 /* Add configured prefix to caller.number */ 06030 misdn_add_number_prefix(bc->port, bc->caller.number_type, bc->caller.number, sizeof(bc->caller.number)); 06031 06032 if (ast_strlen_zero(bc->dialed.number) && !ast_strlen_zero(bc->keypad)) { 06033 ast_copy_string(bc->dialed.number, bc->keypad, sizeof(bc->dialed.number)); 06034 } 06035 06036 /* Add configured prefix to dialed.number */ 06037 misdn_add_number_prefix(bc->port, bc->dialed.number_type, bc->dialed.number, sizeof(bc->dialed.number)); 06038 06039 ast_copy_string(ast->exten, bc->dialed.number, sizeof(ast->exten)); 06040 06041 misdn_cfg_get(bc->port, MISDN_CFG_OVERLAP_DIAL, &ch->overlap_dial, sizeof(ch->overlap_dial)); 06042 ast_mutex_init(&ch->overlap_tv_lock); 06043 } /* ORIG MISDN END */ 06044 06045 misdn_cfg_get(port, MISDN_CFG_INCOMING_CALLERID_TAG, bc->incoming_cid_tag, sizeof(bc->incoming_cid_tag)); 06046 if (!ast_strlen_zero(bc->incoming_cid_tag)) { 06047 chan_misdn_log(1, port, " --> * Setting incoming caller id tag to \"%s\"\n", bc->incoming_cid_tag); 06048 } 06049 ch->overlap_dial_task = -1; 06050 06051 if (ch->faxdetect || ch->ast_dsp) { 06052 misdn_cfg_get(port, MISDN_CFG_FAXDETECT_TIMEOUT, &ch->faxdetect_timeout, sizeof(ch->faxdetect_timeout)); 06053 if (!ch->dsp) { 06054 ch->dsp = ast_dsp_new(); 06055 } 06056 if (ch->dsp) { 06057 ast_dsp_set_features(ch->dsp, DSP_FEATURE_DIGIT_DETECT | (ch->faxdetect ? DSP_FEATURE_FAX_DETECT : 0)); 06058 } 06059 } 06060 06061 /* AOCD initialization */ 06062 bc->AOCDtype = Fac_None; 06063 06064 return 0; 06065 }
static void release_chan | ( | struct chan_list * | ch, | |
struct misdn_bchannel * | bc | |||
) | [static] |
Definition at line 8424 of file chan_misdn.c.
References ast_channel::_state, chan_list::ast, ast_channel_trylock, ast_channel_unlock, ast_mutex_lock, ast_mutex_unlock, ast_setstate(), AST_STATE_DOWN, AST_STATE_RESERVED, chan_list::bc, ast_channel::caller, chan_list_unref, chan_misdn_log(), cl_dequeue_chan(), ast_channel::context, DEADLOCK_AVOIDANCE, ast_channel::exten, ast_party_caller::id, misdn_bchannel::l3_id, MISDN_ASTERISK_TECH_PVT, MISDN_CLEANING, misdn_in_calls, misdn_out_calls, ast_party_id::name, ast_party_id::number, ORG_AST, chan_list::originator, misdn_bchannel::pid, misdn_bchannel::port, release_lock, S_COR, chan_list::state, ast_party_number::str, ast_party_name::str, ast_party_number::valid, and ast_party_name::valid.
Referenced by cb_events(), and misdn_hangup().
08425 { 08426 struct ast_channel *ast; 08427 08428 chan_misdn_log(5, bc->port, "release_chan: bc with pid:%d l3id: %x\n", bc->pid, bc->l3_id); 08429 08430 ast_mutex_lock(&release_lock); 08431 for (;;) { 08432 ast = ch->ast; 08433 if (!ast || !ast_channel_trylock(ast)) { 08434 break; 08435 } 08436 DEADLOCK_AVOIDANCE(&release_lock); 08437 } 08438 if (!cl_dequeue_chan(ch)) { 08439 /* Someone already released it. */ 08440 if (ast) { 08441 ast_channel_unlock(ast); 08442 } 08443 ast_mutex_unlock(&release_lock); 08444 return; 08445 } 08446 ch->state = MISDN_CLEANING; 08447 ch->ast = NULL; 08448 if (ast) { 08449 struct chan_list *ast_ch; 08450 08451 ast_ch = MISDN_ASTERISK_TECH_PVT(ast); 08452 MISDN_ASTERISK_TECH_PVT(ast) = NULL; 08453 chan_misdn_log(1, bc->port, 08454 "* RELEASING CHANNEL pid:%d context:%s dialed:%s caller:\"%s\" <%s>\n", 08455 bc->pid, 08456 ast->context, 08457 ast->exten, 08458 S_COR(ast->caller.id.name.valid, ast->caller.id.name.str, ""), 08459 S_COR(ast->caller.id.number.valid, ast->caller.id.number.str, "")); 08460 08461 if (ast->_state != AST_STATE_RESERVED) { 08462 chan_misdn_log(3, bc->port, " --> Setting AST State to down\n"); 08463 ast_setstate(ast, AST_STATE_DOWN); 08464 } 08465 ast_channel_unlock(ast); 08466 if (ast_ch) { 08467 chan_list_unref(ast_ch, "Release ast_channel reference."); 08468 } 08469 } 08470 08471 if (ch->originator == ORG_AST) { 08472 --misdn_out_calls[bc->port]; 08473 } else { 08474 --misdn_in_calls[bc->port]; 08475 } 08476 08477 ast_mutex_unlock(&release_lock); 08478 }
static void release_chan_early | ( | struct chan_list * | ch | ) | [static] |
Definition at line 8490 of file chan_misdn.c.
References ast_channel::_state, chan_list::ast, ast_channel_trylock, ast_channel_unlock, ast_mutex_lock, ast_mutex_unlock, ast_setstate(), AST_STATE_DOWN, AST_STATE_RESERVED, chan_list_unref, cl_dequeue_chan(), DEADLOCK_AVOIDANCE, chan_list::hold, MISDN_ASTERISK_TECH_PVT, MISDN_CLEANING, MISDN_HOLD_IDLE, misdn_in_calls, misdn_out_calls, ORG_AST, chan_list::originator, hold_info::port, release_lock, hold_info::state, and chan_list::state.
Referenced by misdn_hangup().
08491 { 08492 struct ast_channel *ast; 08493 08494 ast_mutex_lock(&release_lock); 08495 for (;;) { 08496 ast = ch->ast; 08497 if (!ast || !ast_channel_trylock(ast)) { 08498 break; 08499 } 08500 DEADLOCK_AVOIDANCE(&release_lock); 08501 } 08502 if (!cl_dequeue_chan(ch)) { 08503 /* Someone already released it. */ 08504 if (ast) { 08505 ast_channel_unlock(ast); 08506 } 08507 ast_mutex_unlock(&release_lock); 08508 return; 08509 } 08510 ch->state = MISDN_CLEANING; 08511 ch->ast = NULL; 08512 if (ast) { 08513 struct chan_list *ast_ch; 08514 08515 ast_ch = MISDN_ASTERISK_TECH_PVT(ast); 08516 MISDN_ASTERISK_TECH_PVT(ast) = NULL; 08517 08518 if (ast->_state != AST_STATE_RESERVED) { 08519 ast_setstate(ast, AST_STATE_DOWN); 08520 } 08521 ast_channel_unlock(ast); 08522 if (ast_ch) { 08523 chan_list_unref(ast_ch, "Release ast_channel reference."); 08524 } 08525 } 08526 08527 if (ch->hold.state != MISDN_HOLD_IDLE) { 08528 if (ch->originator == ORG_AST) { 08529 --misdn_out_calls[ch->hold.port]; 08530 } else { 08531 --misdn_in_calls[ch->hold.port]; 08532 } 08533 } 08534 08535 ast_mutex_unlock(&release_lock); 08536 }
static int reload | ( | void | ) | [static] |
Definition at line 11399 of file chan_misdn.c.
References reload_config().
11400 { 11401 reload_config(); 11402 11403 return 0; 11404 }
static void reload_config | ( | void | ) | [static] |
Definition at line 4092 of file chan_misdn.c.
References ast_log(), free_robin_list(), LOG_WARNING, max_ports, misdn_cfg_get(), misdn_cfg_reload(), misdn_cfg_update_ptp(), misdn_debug, misdn_debug_only, MISDN_GEN_DEBUG, and MISDN_GEN_TRACEFILE.
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 8685 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().
08686 { 08687 int can_hangup; 08688 08689 if (!ast) { 08690 chan_misdn_log(1, 0, "send_cause2ast: No Ast\n"); 08691 return 0; 08692 } 08693 if (!bc) { 08694 chan_misdn_log(1, 0, "send_cause2ast: No BC\n"); 08695 return 0; 08696 } 08697 if (!ch) { 08698 chan_misdn_log(1, 0, "send_cause2ast: No Ch\n"); 08699 return 0; 08700 } 08701 08702 ast->hangupcause = bc->cause; 08703 08704 can_hangup = -1; 08705 switch (bc->cause) { 08706 case AST_CAUSE_UNALLOCATED: 08707 case AST_CAUSE_NO_ROUTE_TRANSIT_NET: 08708 case AST_CAUSE_NO_ROUTE_DESTINATION: 08709 case 4: /* Send special information tone */ 08710 case AST_CAUSE_NUMBER_CHANGED: 08711 case AST_CAUSE_DESTINATION_OUT_OF_ORDER: 08712 /* Congestion Cases */ 08713 /* 08714 * Not Queueing the Congestion anymore, since we want to hear 08715 * the inband message 08716 * 08717 chan_misdn_log(1, bc ? bc->port : 0, " --> * SEND: Queue Congestion pid:%d\n", bc ? bc->pid : -1); 08718 ch->state = MISDN_BUSY; 08719 08720 ast_queue_control(ast, AST_CONTROL_CONGESTION); 08721 */ 08722 break; 08723 08724 case AST_CAUSE_CALL_REJECTED: 08725 case AST_CAUSE_USER_BUSY: 08726 ch->state = MISDN_BUSY; 08727 08728 if (!ch->need_busy) { 08729 chan_misdn_log(1, bc ? bc->port : 0, "Queued busy already\n"); 08730 break; 08731 } 08732 ch->need_busy = 0; 08733 08734 chan_misdn_log(1, bc ? bc->port : 0, " --> * SEND: Queue Busy pid:%d\n", bc ? bc->pid : -1); 08735 ast_queue_control(ast, AST_CONTROL_BUSY); 08736 08737 /* The BUSY is likely to cause a hangup or the user needs to hear it. */ 08738 can_hangup = 0; 08739 break; 08740 } 08741 return can_hangup; 08742 }
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, ast_playtones_start(), and ast_channel::name.
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] |
static int start_bc_tones | ( | struct chan_list * | cl | ) | [static] |
Definition at line 7682 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().
07683 { 07684 misdn_lib_tone_generator_stop(cl->bc); 07685 cl->notxtone = 0; 07686 cl->norxtone = 0; 07687 return 0; 07688 }
static void start_pbx | ( | struct chan_list * | ch, | |
struct misdn_bchannel * | bc, | |||
struct ast_channel * | chan | |||
) | [static] |
Definition at line 8835 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().
08836 { 08837 if (pbx_start_chan(ch) < 0) { 08838 hangup_chan(ch, bc); 08839 chan_misdn_log(-1, bc->port, "ast_pbx_start returned <0 in SETUP\n"); 08840 if (bc->nt) { 08841 hanguptone_indicate(ch); 08842 misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE); 08843 } else { 08844 misdn_lib_send_event(bc, EVENT_RELEASE); 08845 } 08846 } 08847 }
static int stop_bc_tones | ( | struct chan_list * | cl | ) | [static] |
Definition at line 7690 of file chan_misdn.c.
References chan_list::norxtone, and chan_list::notxtone.
Referenced by cb_events(), misdn_call(), and misdn_hangup().
07691 { 07692 if (!cl) { 07693 return -1; 07694 } 07695 07696 cl->notxtone = 1; 07697 cl->norxtone = 1; 07698 07699 return 0; 07700 }
static int stop_indicate | ( | struct chan_list * | cl | ) | [static] |
Definition at line 7661 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().
07662 { 07663 struct ast_channel *ast = cl->ast; 07664 07665 if (!ast) { 07666 chan_misdn_log(0, cl->bc->port, "No Ast in stop_indicate\n"); 07667 return -1; 07668 } 07669 07670 chan_misdn_log(3, cl->bc->port, " --> None\n"); 07671 misdn_lib_tone_generator_stop(cl->bc); 07672 ast_playtones_stop(ast); 07673 07674 if (cl->ts) { 07675 cl->ts = ast_tone_zone_sound_unref(cl->ts); 07676 } 07677 07678 return 0; 07679 }
static int unload_module | ( | void | ) | [static] |
TE STUFF END
Definition at line 11141 of file chan_misdn.c.
References ast_channel_unregister(), ast_cli_unregister_multiple(), ast_custom_function_unregister(), ast_free, ast_log(), ast_unregister_application(), chan_misdn_clis, free_robin_list(), LOG_VERBOSE, misdn_cfg_destroy(), misdn_debug, misdn_debug_only, misdn_in_calls, misdn_lib_destroy(), misdn_out_calls, misdn_ports, misdn_tasks_destroy(), and misdn_tech.
11142 { 11143 /* First, take us out of the channel loop */ 11144 ast_log(LOG_VERBOSE, "-- Unregistering mISDN Channel Driver --\n"); 11145 11146 misdn_tasks_destroy(); 11147 11148 if (!g_config_initialized) { 11149 return 0; 11150 } 11151 11152 ast_cli_unregister_multiple(chan_misdn_clis, sizeof(chan_misdn_clis) / sizeof(struct ast_cli_entry)); 11153 11154 /* ast_unregister_application("misdn_crypt"); */ 11155 ast_unregister_application("misdn_set_opt"); 11156 ast_unregister_application("misdn_facility"); 11157 ast_unregister_application("misdn_check_l2l1"); 11158 #if defined(AST_MISDN_ENHANCEMENTS) 11159 ast_unregister_application(misdn_command_name); 11160 ast_custom_function_unregister(&misdn_cc_function); 11161 #endif /* defined(AST_MISDN_ENHANCEMENTS) */ 11162 11163 ast_channel_unregister(&misdn_tech); 11164 11165 free_robin_list(); 11166 misdn_cfg_destroy(); 11167 misdn_lib_destroy(); 11168 11169 ast_free(misdn_out_calls); 11170 ast_free(misdn_in_calls); 11171 ast_free(misdn_debug_only); 11172 ast_free(misdn_ports); 11173 ast_free(misdn_debug); 11174 11175 #if defined(AST_MISDN_ENHANCEMENTS) 11176 misdn_cc_destroy(); 11177 #endif /* defined(AST_MISDN_ENHANCEMENTS) */ 11178 11179 return 0; 11180 }
static void update_config | ( | struct chan_list * | ch | ) | [static] |
Updates caller ID information from config.
Definition at line 5731 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().
05732 { 05733 struct ast_channel *ast; 05734 struct misdn_bchannel *bc; 05735 int port; 05736 int hdlc = 0; 05737 int pres; 05738 int screen; 05739 05740 if (!ch) { 05741 ast_log(LOG_WARNING, "Cannot configure without chanlist\n"); 05742 return; 05743 } 05744 05745 ast = ch->ast; 05746 bc = ch->bc; 05747 if (! ast || ! bc) { 05748 ast_log(LOG_WARNING, "Cannot configure without ast || bc\n"); 05749 return; 05750 } 05751 05752 port = bc->port; 05753 05754 chan_misdn_log(7, port, "update_config: Getting Config\n"); 05755 05756 misdn_cfg_get(port, MISDN_CFG_HDLC, &hdlc, sizeof(int)); 05757 if (hdlc) { 05758 switch (bc->capability) { 05759 case INFO_CAPABILITY_DIGITAL_UNRESTRICTED: 05760 case INFO_CAPABILITY_DIGITAL_RESTRICTED: 05761 chan_misdn_log(1, bc->port, " --> CONF HDLC\n"); 05762 bc->hdlc = 1; 05763 break; 05764 } 05765 } 05766 05767 05768 misdn_cfg_get(port, MISDN_CFG_PRES, &pres, sizeof(pres)); 05769 misdn_cfg_get(port, MISDN_CFG_SCREEN, &screen, sizeof(screen)); 05770 chan_misdn_log(2, port, " --> pres: %d screen: %d\n", pres, screen); 05771 05772 if (pres < 0 || screen < 0) { 05773 chan_misdn_log(2, port, " --> pres: %x\n", ast->connected.id.number.presentation); 05774 05775 bc->caller.presentation = ast_to_misdn_pres(ast->connected.id.number.presentation); 05776 chan_misdn_log(2, port, " --> PRES: %s(%d)\n", misdn_to_str_pres(bc->caller.presentation), bc->caller.presentation); 05777 05778 bc->caller.screening = ast_to_misdn_screen(ast->connected.id.number.presentation); 05779 chan_misdn_log(2, port, " --> SCREEN: %s(%d)\n", misdn_to_str_screen(bc->caller.screening), bc->caller.screening); 05780 } else { 05781 bc->caller.screening = screen; 05782 bc->caller.presentation = pres; 05783 } 05784 }
static int update_ec_config | ( | struct misdn_bchannel * | bc | ) | [static] |
Definition at line 5873 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().
05874 { 05875 int ec; 05876 int port = bc->port; 05877 05878 misdn_cfg_get(port, MISDN_CFG_ECHOCANCEL, &ec, sizeof(ec)); 05879 05880 if (ec == 1) { 05881 bc->ec_enable = 1; 05882 } else if (ec > 1) { 05883 bc->ec_enable = 1; 05884 bc->ec_deftaps = ec; 05885 } 05886 05887 return 0; 05888 }
static void update_name | ( | struct ast_channel * | tmp, | |
int | port, | |||
int | c | |||
) | [static] |
Definition at line 8088 of file chan_misdn.c.
References ast_change_name(), chan_misdn_log(), misdn_cfg_get_next_port(), misdn_lib_port_is_pri(), misdn_type, and ast_channel::name.
Referenced by cb_events().
08089 { 08090 int chan_offset = 0; 08091 int tmp_port = misdn_cfg_get_next_port(0); 08092 char newname[255]; 08093 08094 for (; tmp_port > 0; tmp_port = misdn_cfg_get_next_port(tmp_port)) { 08095 if (tmp_port == port) { 08096 break; 08097 } 08098 chan_offset += misdn_lib_port_is_pri(tmp_port) ? 30 : 2; 08099 } 08100 if (c < 0) { 08101 c = 0; 08102 } 08103 08104 snprintf(newname, sizeof(newname), "%s/%d-", misdn_type, chan_offset + c); 08105 if (strncmp(tmp->name, newname, strlen(newname))) { 08106 snprintf(newname, sizeof(newname), "%s/%d-u%d", misdn_type, chan_offset + c, glob_channel++); 08107 ast_change_name(tmp, newname); 08108 chan_misdn_log(3, port, " --> updating channel name to [%s]\n", tmp->name); 08109 } 08110 }
static void wait_for_digits | ( | struct chan_list * | ch, | |
struct misdn_bchannel * | bc, | |||
struct ast_channel * | chan | |||
) | [static] |
Definition at line 8849 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().
08850 { 08851 ch->state = MISDN_WAITING4DIGS; 08852 misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE); 08853 if (bc->nt && !bc->dialed.number[0]) { 08854 dialtone_indicate(ch); 08855 } 08856 }
struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Channel driver for mISDN Support (BRI/PRI)" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "ac1f6a56484a8820659555499174e588" , .load = load_module, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_CHANNEL_DRIVER, } [static] |
Definition at line 12704 of file chan_misdn.c.
struct allowed_bearers allowed_bearers_array[] [static] |
struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 12704 of file chan_misdn.c.
struct ast_cli_entry chan_misdn_clis[] [static] |
Global channel call record list head.
Definition at line 678 of file chan_misdn.c.
Referenced by cl_dequeue_chan(), cl_queue_chan(), find_chan_by_bc(), find_hold_active_call(), find_hold_call(), find_hold_call_l3(), get_chan_by_ast(), get_chan_by_ast_name(), handle_cli_misdn_show_channel(), handle_cli_misdn_show_channels(), and misdn_chan_is_valid().
ast_mutex_t cl_te_lock [static] |
Definition at line 679 of file chan_misdn.c.
Referenced by cl_dequeue_chan(), cl_queue_chan(), find_chan_by_bc(), find_hold_active_call(), find_hold_call(), find_hold_call_l3(), get_chan_by_ast(), get_chan_by_ast_name(), handle_cli_misdn_show_channel(), handle_cli_misdn_show_channels(), load_module(), and misdn_chan_is_valid().
int g_config_initialized = 0 [static] |
Definition at line 101 of file chan_misdn.c.
int glob_channel = 0 [static] |
Definition at line 8086 of file chan_misdn.c.
char global_tracefile[BUFFERSIZE+1] [static] |
The latest modified mISDN v1.1.x based version is available at: http://svn.digium.com/svn/thirdparty/mISDN/trunk http://svn.digium.com/svn/thirdparty/mISDNuser/trunk
Taged versions of the modified mISDN code are available under: http://svn.digium.com/svn/thirdparty/mISDN/tags http://svn.digium.com/svn/thirdparty/mISDNuser/tags
Definition at line 99 of file chan_misdn.c.
int max_ports [static] |
Definition at line 670 of file chan_misdn.c.
Referenced by _build_port_config(), chan_misdn_log(), handle_cli_misdn_set_debug(), load_module(), misdn_cfg_get_next_port(), misdn_cfg_get_ports_string(), misdn_cfg_init(), misdn_cfg_is_group_method(), misdn_cfg_is_port_valid(), misdn_cfg_update_ptp(), and reload_config().
int MAXTICS = 8 |
Definition at line 584 of file chan_misdn.c.
int* misdn_debug [static] |
Definition at line 668 of file chan_misdn.c.
Referenced by chan_misdn_log(), handle_cli_misdn_set_debug(), handle_cli_misdn_show_channels(), handle_cli_misdn_show_port(), handle_cli_misdn_show_stacks(), load_module(), print_bc_info(), reload_config(), and unload_module().
int* misdn_debug_only [static] |
Definition at line 669 of file chan_misdn.c.
Referenced by chan_misdn_log(), handle_cli_misdn_set_debug(), handle_cli_misdn_show_port(), handle_cli_misdn_show_stacks(), load_module(), reload_config(), and unload_module().
int* misdn_in_calls [static] |
Definition at line 672 of file chan_misdn.c.
Referenced by add_in_calls(), handle_cli_misdn_show_ports_stats(), load_module(), release_chan(), release_chan_early(), and unload_module().
int* misdn_out_calls [static] |
Definition at line 673 of file chan_misdn.c.
Referenced by add_out_calls(), handle_cli_misdn_show_ports_stats(), load_module(), release_chan(), release_chan_early(), and unload_module().
int* misdn_ports [static] |
struct sched_context* misdn_tasks = NULL [static] |
the main schedule context for stuff like l1 watcher, overlap dial, ...
Definition at line 642 of file chan_misdn.c.
Referenced by _misdn_tasks_add_variable(), misdn_tasks_destroy(), misdn_tasks_init(), misdn_tasks_remove(), and misdn_tasks_thread_func().
pthread_t misdn_tasks_thread [static] |
Definition at line 643 of file chan_misdn.c.
Referenced by misdn_tasks_destroy(), misdn_tasks_init(), and misdn_tasks_wakeup().
struct ast_channel_tech misdn_tech [static] |
Definition at line 8048 of file chan_misdn.c.
Referenced by load_module(), misdn_new(), and unload_module().
struct ast_channel_tech misdn_tech_wo_bridge [static] |
const char misdn_type[] = "mISDN" [static] |
Definition at line 661 of file chan_misdn.c.
Referenced by load_module(), misdn_facility_exec(), misdn_new(), misdn_request(), misdn_set_opt_exec(), and update_name().
int prefformat = AST_FORMAT_ALAW [static] |
Only alaw and mulaw is allowed for now.
Definition at line 666 of file chan_misdn.c.
Referenced by misdn_new(), and misdn_write().
ast_mutex_t release_lock [static] |
Definition at line 295 of file chan_misdn.c.
Referenced by load_module(), misdn_hangup(), release_chan(), and release_chan_early().
struct robin_list* robin = NULL [static] |
Definition at line 598 of file chan_misdn.c.
Referenced by free_robin_list(), and get_robin_position().
struct state_struct state_array[] [static] |
int tracing = 0 [static] |