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