Asterisk - The Open Source Telephony Project  18.5.0
Data Structures | Macros | Enumerations | Functions | Variables
chan_misdn.c File Reference

the chan_misdn channel driver for Asterisk More...

#include "asterisk.h"
#include <pthread.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <signal.h>
#include <sys/file.h>
#include <semaphore.h>
#include <ctype.h>
#include <time.h>
#include "asterisk/channel.h"
#include "asterisk/config.h"
#include "asterisk/module.h"
#include "asterisk/pbx.h"
#include "asterisk/io.h"
#include "asterisk/frame.h"
#include "asterisk/translate.h"
#include "asterisk/cli.h"
#include "asterisk/musiconhold.h"
#include "asterisk/dsp.h"
#include "asterisk/file.h"
#include "asterisk/callerid.h"
#include "asterisk/indications.h"
#include "asterisk/app.h"
#include "asterisk/features.h"
#include "asterisk/term.h"
#include "asterisk/sched.h"
#include "asterisk/stringfields.h"
#include "asterisk/abstract_jb.h"
#include "asterisk/causes.h"
#include "asterisk/format.h"
#include "asterisk/format_cap.h"
#include "asterisk/features_config.h"
#include "asterisk/bridge.h"
#include "asterisk/pickup.h"
#include "asterisk/format_cache.h"
#include "chan_misdn_config.h"
#include "isdn_lib.h"
#include "asterisk/strings.h"
Include dependency graph for chan_misdn.c:

Go to the source code of this file.

Data Structures

struct  allowed_bearers
 
struct  chan_list
 Channel call record structure. More...
 
struct  hold_info
 
struct  misdn_jb
 
struct  robin_list
 
struct  state_struct
 

Macros

#define chan_list_ref(obj, debug)   ao2_t_ref((obj), +1, (debug))
 
#define chan_list_unref(obj, debug)   ao2_t_ref((obj), -1, (debug))
 
#define MISDN_ASTERISK_TECH_PVT(ast)   ast_channel_tech_pvt(ast)
 
#define MISDN_ASTERISK_TECH_PVT_SET(ast, value)   ast_channel_tech_pvt_set(ast, value)
 
#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)
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
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_listchan_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. More...
 
static struct chan_listfind_chan_by_bc (struct misdn_bchannel *bc)
 
static struct chan_listfind_hold_active_call (struct misdn_bchannel *bc)
 
static struct chan_listfind_hold_call (struct misdn_bchannel *bc)
 
static struct chan_listfind_hold_call_l3 (unsigned long l3_id)
 
static void free_robin_list (void)
 
static struct chan_listget_chan_by_ast_name (const char *name)
 
static struct robin_listget_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. More...
 
static int load_module (void)
 Load the module. More...
 
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 int misdn_call (struct ast_channel *ast, const 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 More...
 
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. More...
 
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). More...
 
struct misdn_jbmisdn_jb_init (int size, int upper_threshold)
 allocates the jb-structure and initialize the elements More...
 
static int misdn_l1_task (const void *vdata)
 
static struct ast_channelmisdn_new (struct chan_list *cl, int state, char *exten, char *callerid, struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, 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_framemisdn_read (struct ast_channel *ast)
 
static struct ast_channelmisdn_request (const char *type, struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *data, int *cause)
 
static int misdn_send_text (struct ast_channel *chan, const char *text)
 
static int misdn_set_opt_exec (struct ast_channel *chan, const char *data)
 
static int misdn_tasks_add (int timeout, ast_sched_cb callback, const void *data)
 
static int misdn_tasks_add_variable (int timeout, ast_sched_cb callback, const void *data)
 
static void misdn_tasks_destroy (void)
 
static void misdn_tasks_init (void)
 
static void misdn_tasks_remove (int task_id)
 
static void * misdn_tasks_thread_func (void *data)
 
static void misdn_tasks_wakeup (void)
 
static int misdn_to_ast_plan (enum mISDN_NUMBER_PLAN number_plan)
 
static int misdn_to_ast_pres (int presentation)
 
static enum AST_REDIRECTING_REASON misdn_to_ast_reason (const enum mISDN_REDIRECTING_REASON q931)
 
static int misdn_to_ast_screen (int screening)
 
static int misdn_to_ast_ton (enum mISDN_NUMBER_TYPE number_type)
 
static const char * misdn_to_str_plan (enum mISDN_NUMBER_PLAN number_plan)
 
static const char * misdn_to_str_pres (int presentation)
 
static const char * misdn_to_str_screen (int screening)
 
static const char * misdn_to_str_ton (enum mISDN_NUMBER_TYPE number_type)
 
static void misdn_update_caller_id (struct ast_channel *ast, const struct misdn_party_id *id, char *cid_tag)
 
static void misdn_update_connected_line (struct ast_channel *ast, struct misdn_bchannel *bc, int originator)
 
static void misdn_update_redirecting (struct ast_channel *ast, struct misdn_bchannel *bc, int originator)
 
static void misdn_update_remote_party (struct ast_channel *ast, const struct misdn_party_id *id, enum AST_CONNECTED_LINE_UPDATE_SOURCE source, char *cid_tag)
 
static int misdn_write (struct ast_channel *ast, struct ast_frame *frame)
 
static int pbx_start_chan (struct chan_list *ch)
 
static void print_bc_info (int fd, struct chan_list *help, struct misdn_bchannel *bc)
 
static void print_bearer (struct misdn_bchannel *bc)
 
static void print_facility (const struct FacParm *fac, const struct misdn_bchannel *bc)
 
static struct ast_frameprocess_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. More...
 
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 = "30ef0c93b36035ec78c9cfd712d36d9b" , .support_level = AST_MODULE_SUPPORT_DEPRECATED, .load = load_module, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_CHANNEL_DRIVER, }
 
static const struct allowed_bearers allowed_bearers_array []
 
static const struct ast_module_infoast_module_info = &__mod_info
 
static struct ast_cli_entry chan_misdn_clis []
 
static struct chan_listcl_te =NULL
 Global channel call record list head. More...
 
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 ast_sched_contextmisdn_tasks = NULL
 the main schedule context for stuff like l1 watcher, overlap dial, ... More...
 
static pthread_t misdn_tasks_thread
 
static struct ast_channel_tech misdn_tech
 
static const char misdn_type [] = "mISDN"
 
static ast_mutex_t release_lock
 
static struct robin_listrobin = NULL
 
static const struct state_struct state_array []
 
static int tracing = 0
 

Detailed Description

the chan_misdn channel driver for Asterisk

Author
Christian Richter crich.nosp@m.@ber.nosp@m.onet..nosp@m.com

MISDN http://www.misdn.org/

Definition in file chan_misdn.c.

Macro Definition Documentation

◆ chan_list_ref

#define chan_list_ref (   obj,
  debug 
)    ao2_t_ref((obj), +1, (debug))

◆ chan_list_unref

#define chan_list_unref (   obj,
  debug 
)    ao2_t_ref((obj), -1, (debug))

◆ MISDN_ASTERISK_TECH_PVT

#define MISDN_ASTERISK_TECH_PVT (   ast)    ast_channel_tech_pvt(ast)

◆ MISDN_ASTERISK_TECH_PVT_SET

#define MISDN_ASTERISK_TECH_PVT_SET (   ast,
  value 
)    ast_channel_tech_pvt_set(ast, value)

Definition at line 684 of file chan_misdn.c.

Referenced by misdn_hangup(), misdn_new(), release_chan(), and release_chan_early().

◆ ORG_AST

#define ORG_AST   1

Asterisk created the channel (outgoing call)

Definition at line 343 of file chan_misdn.c.

Referenced by cb_events(), export_aoc_vars(), misdn_hangup(), misdn_request(), print_bc_info(), read_config(), release_chan(), and release_chan_early().

◆ ORG_MISDN

#define ORG_MISDN   2

mISDN created the channel (incoming call)

Definition at line 345 of file chan_misdn.c.

Referenced by cb_events(), misdn_get_connected_line(), misdn_indication(), misdn_update_connected_line(), and misdn_update_redirecting().

◆ TRANSFER_ON_HELD_CALL_HANGUP

#define TRANSFER_ON_HELD_CALL_HANGUP   1

Definition at line 8334 of file chan_misdn.c.

Enumeration Type Documentation

◆ misdn_chan_state

Enumerator
MISDN_NOTHING 

at beginning

MISDN_WAITING4DIGS 

when waiting for info

MISDN_EXTCANTMATCH 

when asterisk couldn't match our ext

MISDN_INCOMING_SETUP 

for incoming setup

MISDN_DIALING 

when pbx_start

MISDN_PROGRESS 

we have progress

MISDN_PROCEEDING 

we have progress

MISDN_CALLING 

when misdn_call is called

MISDN_CALLING_ACKNOWLEDGE 

when we get SETUP_ACK

MISDN_ALERTING 

when Alerting

MISDN_BUSY 

when BUSY

MISDN_CONNECTED 

when connected

MISDN_DISCONNECTED 

when connected

MISDN_CLEANING 

when hangup from * but we were connected before

Definition at line 325 of file chan_misdn.c.

325  {
326  MISDN_NOTHING = 0, /*!< at beginning */
327  MISDN_WAITING4DIGS, /*!< when waiting for info */
328  MISDN_EXTCANTMATCH, /*!< when asterisk couldn't match our ext */
329  MISDN_INCOMING_SETUP, /*!< for incoming setup */
330  MISDN_DIALING, /*!< when pbx_start */
331  MISDN_PROGRESS, /*!< we have progress */
332  MISDN_PROCEEDING, /*!< we have progress */
333  MISDN_CALLING, /*!< when misdn_call is called */
334  MISDN_CALLING_ACKNOWLEDGE, /*!< when we get SETUP_ACK */
335  MISDN_ALERTING, /*!< when Alerting */
336  MISDN_BUSY, /*!< when BUSY */
337  MISDN_CONNECTED, /*!< when connected */
338  MISDN_DISCONNECTED, /*!< when connected */
339  MISDN_CLEANING, /*!< when hangup from * but we were connected before */
340 };

◆ misdn_hold_state

Enumerator
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 347 of file chan_misdn.c.

347  {
348  MISDN_HOLD_IDLE, /*!< HOLD not active */
349  MISDN_HOLD_ACTIVE, /*!< Call is held */
350  MISDN_HOLD_TRANSFER, /*!< Held call is being transferred */
351  MISDN_HOLD_DISCONNECT, /*!< Held call is being disconnected */
352 };

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 12838 of file chan_misdn.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 12838 of file chan_misdn.c.

◆ _misdn_tasks_add_variable()

static int _misdn_tasks_add_variable ( int  timeout,
ast_sched_cb  callback,
const void *  data,
int  variable 
)
inlinestatic

Definition at line 3591 of file chan_misdn.c.

References ast_sched_add_variable(), misdn_tasks_init(), and misdn_tasks_wakeup().

Referenced by misdn_tasks_add(), and misdn_tasks_add_variable().

3592 {
3593  int task_id;
3594 
3595  if (!misdn_tasks) {
3596  misdn_tasks_init();
3597  }
3598  task_id = ast_sched_add_variable(misdn_tasks, timeout, callback, data, variable);
3600 
3601  return task_id;
3602 }
static int timeout
Definition: cdr_mysql.c:86
int ast_sched_add_variable(struct ast_sched_context *con, int when, ast_sched_cb callback, const void *data, int variable) attribute_warn_unused_result
Adds a scheduled event with rescheduling support.
Definition: sched.c:524
static void misdn_tasks_init(void)
Definition: chan_misdn.c:3554
static struct ast_sched_context * misdn_tasks
the main schedule context for stuff like l1 watcher, overlap dial, ...
Definition: chan_misdn.c:670
static void misdn_tasks_wakeup(void)
Definition: chan_misdn.c:3586

◆ add_in_calls()

int add_in_calls ( int  port)

Definition at line 8844 of file chan_misdn.c.

References ast_log, LOG_NOTICE, misdn_cfg_get(), and MISDN_CFG_MAX_IN.

Referenced by cb_events().

8845 {
8846  int max_in_calls;
8847 
8848  misdn_cfg_get(port, MISDN_CFG_MAX_IN, &max_in_calls, sizeof(max_in_calls));
8849  misdn_in_calls[port]++;
8850 
8851  if (max_in_calls >= 0 && max_in_calls < misdn_in_calls[port]) {
8852  ast_log(LOG_NOTICE, "Marking Incoming Call on port[%d]\n", port);
8853  return misdn_in_calls[port] - max_in_calls;
8854  }
8855 
8856  return 0;
8857 }
#define ast_log
Definition: astobj2.c:42
void misdn_cfg_get(int port, enum misdn_cfg_elements elem, void *buf, int bufsize)
Definition: misdn_config.c:569
#define LOG_NOTICE
Definition: logger.h:263
static int * misdn_in_calls
Definition: chan_misdn.c:698

◆ add_out_calls()

int add_out_calls ( int  port)

Definition at line 8859 of file chan_misdn.c.

References ast_log, LOG_NOTICE, misdn_cfg_get(), and MISDN_CFG_MAX_OUT.

Referenced by misdn_call().

8860 {
8861  int max_out_calls;
8862 
8863  misdn_cfg_get(port, MISDN_CFG_MAX_OUT, &max_out_calls, sizeof(max_out_calls));
8864 
8865  if (max_out_calls >= 0 && max_out_calls <= misdn_out_calls[port]) {
8866  ast_log(LOG_NOTICE, "Rejecting Outgoing Call on port[%d]\n", port);
8867  return (misdn_out_calls[port] + 1) - max_out_calls;
8868  }
8869 
8870  misdn_out_calls[port]++;
8871 
8872  return 0;
8873 }
#define ast_log
Definition: astobj2.c:42
void misdn_cfg_get(int port, enum misdn_cfg_elements elem, void *buf, int bufsize)
Definition: misdn_config.c:569
#define LOG_NOTICE
Definition: logger.h:263
static int * misdn_out_calls
Definition: chan_misdn.c:699

◆ AST_MODULE_SELF_SYM()

struct ast_module* AST_MODULE_SELF_SYM ( void  )

Definition at line 12838 of file chan_misdn.c.

◆ ast_to_misdn_plan()

static enum mISDN_NUMBER_PLAN ast_to_misdn_plan ( unsigned  ast_number_plan)
static

Definition at line 2042 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().

2043 {
2044  enum mISDN_NUMBER_PLAN number_plan;
2045 
2046  switch (ast_number_plan & 0x0F) {
2047  default:
2048  case NUMPLAN_UNKNOWN:
2049  number_plan = NUMPLAN_UNKNOWN;
2050  break;
2051 
2052  case NUMPLAN_ISDN:
2053  number_plan = NUMPLAN_ISDN;
2054  break;
2055 
2056  case NUMPLAN_DATA:
2057  number_plan = NUMPLAN_DATA;
2058  break;
2059 
2060  case NUMPLAN_TELEX:
2061  number_plan = NUMPLAN_TELEX;
2062  break;
2063 
2064  case NUMPLAN_NATIONAL:
2065  number_plan = NUMPLAN_NATIONAL;
2066  break;
2067 
2068  case NUMPLAN_PRIVATE:
2069  number_plan = NUMPLAN_PRIVATE;
2070  break;
2071  }
2072 
2073  return number_plan;
2074 }
mISDN_NUMBER_PLAN
Definition: isdn_lib.h:92

◆ ast_to_misdn_pres()

static int ast_to_misdn_pres ( int  presentation)
static

Definition at line 2145 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().

2146 {
2147  switch (presentation & AST_PRES_RESTRICTION) {
2148  default:
2149  case AST_PRES_ALLOWED:
2150  presentation = 0;
2151  break;
2152 
2153  case AST_PRES_RESTRICTED:
2154  presentation = 1;
2155  break;
2156 
2157  case AST_PRES_UNAVAILABLE:
2158  presentation = 2;
2159  break;
2160  }
2161 
2162  return presentation;
2163 }
#define AST_PRES_RESTRICTED
Definition: callerid.h:325
#define AST_PRES_RESTRICTION
Definition: callerid.h:323
#define AST_PRES_ALLOWED
Definition: callerid.h:324
#define AST_PRES_UNAVAILABLE
Definition: callerid.h:326

◆ ast_to_misdn_reason()

static enum mISDN_REDIRECTING_REASON ast_to_misdn_reason ( const enum AST_REDIRECTING_REASON  ast)
static

Definition at line 2274 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().

2275 {
2276  unsigned index;
2277 
2278  static const struct misdn_reasons {
2279  enum AST_REDIRECTING_REASON ast;
2280  enum mISDN_REDIRECTING_REASON q931;
2281  } misdn_reason_table[] = {
2282  /* *INDENT-OFF* */
2286  { AST_REDIRECTING_REASON_UNAVAILABLE, mISDN_REDIRECTING_REASON_NO_REPLY },
2288  { AST_REDIRECTING_REASON_TIME_OF_DAY, mISDN_REDIRECTING_REASON_UNKNOWN },
2289  { AST_REDIRECTING_REASON_DO_NOT_DISTURB, mISDN_REDIRECTING_REASON_UNKNOWN },
2291  { AST_REDIRECTING_REASON_FOLLOW_ME, mISDN_REDIRECTING_REASON_UNKNOWN },
2293  { AST_REDIRECTING_REASON_AWAY, mISDN_REDIRECTING_REASON_UNKNOWN },
2295  /* *INDENT-ON* */
2296  };
2297 
2298  for (index = 0; index < ARRAY_LEN(misdn_reason_table); ++index) {
2299  if (misdn_reason_table[index].ast == ast) {
2300  return misdn_reason_table[index].q931;
2301  }
2302  }
2304 }
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
mISDN_REDIRECTING_REASON
Q.931 encoded redirecting reason.
Definition: isdn_lib.h:197
AST_REDIRECTING_REASON
redirecting reason codes.
Definition: callerid.h:390

◆ ast_to_misdn_screen()

static int ast_to_misdn_screen ( int  screening)
static

Definition at line 2242 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().

2243 {
2244  switch (screening & AST_PRES_NUMBER_TYPE) {
2245  default:
2247  screening = 0;
2248  break;
2249 
2251  screening = 1;
2252  break;
2253 
2255  screening = 2;
2256  break;
2257 
2259  screening = 3;
2260  break;
2261  }
2262 
2263  return screening;
2264 }
#define AST_PRES_USER_NUMBER_FAILED_SCREEN
Definition: callerid.h:320
#define AST_PRES_NETWORK_NUMBER
Definition: callerid.h:321
#define AST_PRES_USER_NUMBER_UNSCREENED
Definition: callerid.h:318
#define AST_PRES_NUMBER_TYPE
Definition: callerid.h:317
#define AST_PRES_USER_NUMBER_PASSED_SCREEN
Definition: callerid.h:319

◆ ast_to_misdn_ton()

static enum mISDN_NUMBER_TYPE ast_to_misdn_ton ( unsigned  ast_number_type)
static

Definition at line 1916 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().

1917 {
1918  enum mISDN_NUMBER_TYPE number_type;
1919 
1920  switch ((ast_number_type >> 4) & 0x07) {
1921  default:
1922  case NUMTYPE_UNKNOWN:
1923  number_type = NUMTYPE_UNKNOWN;
1924  break;
1925 
1926  case NUMTYPE_INTERNATIONAL:
1927  number_type = NUMTYPE_INTERNATIONAL;
1928  break;
1929 
1930  case NUMTYPE_NATIONAL:
1931  number_type = NUMTYPE_NATIONAL;
1932  break;
1933 
1935  number_type = NUMTYPE_NETWORK_SPECIFIC;
1936  break;
1937 
1938  case NUMTYPE_SUBSCRIBER:
1939  number_type = NUMTYPE_SUBSCRIBER;
1940  break;
1941 
1942  case NUMTYPE_ABBREVIATED:
1943  number_type = NUMTYPE_ABBREVIATED;
1944  break;
1945  }
1946 
1947  return number_type;
1948 }
mISDN_NUMBER_TYPE
Definition: isdn_lib.h:101

◆ bearer2str()

static const char* bearer2str ( int  cap)
static

Definition at line 2373 of file chan_misdn.c.

References ARRAY_LEN, ast_copy_string(), chan_misdn_log(), allowed_bearers::display, misdn_party_id::number, misdn_party_id::number_plan, misdn_party_id::number_type, NUMPLAN_ISDN, NUMTYPE_UNKNOWN, misdn_bchannel::port, and misdn_party_id::presentation.

Referenced by cb_events(), print_bc_info(), and print_bearer().

2374 {
2375  unsigned index;
2376 
2377  for (index = 0; index < ARRAY_LEN(allowed_bearers_array); ++index) {
2378  if (allowed_bearers_array[index].cap == cap) {
2379  return allowed_bearers_array[index].display;
2380  }
2381  }
2382 
2383  return "Unknown Bearer";
2384 }
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
static const struct allowed_bearers allowed_bearers_array[]
Definition: chan_misdn.c:2362

◆ cb_events()

static enum event_response_e cb_events ( enum event_e  event,
struct misdn_bchannel bc,
void *  user_data 
)
static

queue new chan

Supplementary Services

Definition at line 9917 of file chan_misdn.c.

References add_in_calls(), misdn_bchannel::addr, chan_list::addr, chan_list::allowed_bearers, ao2_cleanup, ao2_ref, misdn_bchannel::AOCD_need_export, args, ARRAY_LEN, chan_list::ast, AST_APP_ARG, 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_channel_bridge_peer(), ast_channel_caller(), ast_channel_cleanup, ast_channel_exten(), ast_channel_exten_set(), ast_channel_generator(), ast_channel_generatordata(), ast_channel_generatordata_set(), ast_channel_hangupcause_set(), ast_channel_lock, ast_channel_queue_redirecting_update(), ast_channel_redirecting(), ast_channel_rings_set(), ast_channel_transfercapability_set(), 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_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_RINGING, ast_copy_string(), ast_deactivate_generator(), AST_DECLARE_APP_ARGS, ast_exists_extension(), ast_format_alaw, ast_format_cap_alloc, ast_format_cap_append, AST_FORMAT_CAP_FLAG_DEFAULT, AST_FRAME_DTMF, AST_FRAME_VOICE, ast_get_chan_features_pickup_config(), AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log, ast_mutex_lock, ast_mutex_unlock, ast_named_caller_presentation(), ast_party_id_reset(), ast_party_redirecting_copy(), ast_party_redirecting_free(), ast_party_redirecting_init(), ast_pickup_call(), ast_poll, AST_PRES_RESTRICTED, AST_PRES_USER_NUMBER_UNSCREENED, ast_queue_control(), ast_queue_frame(), ast_queue_hold(), ast_queue_unhold(), ast_set_callerid(), ast_setstate(), AST_STANDARD_APP_ARGS, AST_STATE_RESERVED, AST_STATE_RINGING, ast_strdup, ast_strdupa, ast_strlen_zero, ast_transfercapability2str(), ast_tv(), ast_tvnow(), bc, chan_list::bc, misdn_bchannel::bc_state, bc_state2str(), bearer2str(), misdn_bchannel::bframe, misdn_bchannel::bframe_len, buf, misdn_bchannel::caller, misdn_bchannel::capability, misdn_bchannel::cause, cb_log, chan_list_init(), chan_list_unref, chan_misdn_log(), hold_info::channel, misdn_bchannel::channel, cl_queue_chan(), misdn_bchannel::connected, chan_list::context, misdn_bchannel::cw, ast_frame::data, ast_frame::datalen, ast_frame::delivery, misdn_bchannel::dialed, do_immediate_setup(), misdn_bchannel::dtmf, misdn_bchannel::dummy, errno, EVENT_ALERTING, EVENT_BCHAN_ACTIVATED, EVENT_BCHAN_DATA, EVENT_BCHAN_ERROR, EVENT_CLEANUP, EVENT_CONNECT, EVENT_CONNECT_ACKNOWLEDGE, EVENT_DISCONNECT, EVENT_DTMF_TONE, EVENT_FACILITY, EVENT_HOLD, EVENT_HOLD_ACKNOWLEDGE, EVENT_HOLD_REJECT, EVENT_INFORMATION, EVENT_NEW_BC, EVENT_NEW_CHANNEL, EVENT_NEW_L3ID, EVENT_NOTIFY, EVENT_PORT_ALARM, EVENT_PROCEEDING, EVENT_PROGRESS, EVENT_REGISTER, EVENT_RELEASE, EVENT_RELEASE_COMPLETE, EVENT_RESTART, EVENT_RETRIEVE, EVENT_RETRIEVE_ACKNOWLEDGE, EVENT_RETRIEVE_REJECT, EVENT_SETUP, EVENT_SETUP_ACKNOWLEDGE, EVENT_STATUS, EVENT_TIMEOUT, EVENT_TONE_GENERATE, export_aoc_vars(), export_ch(), misdn_bchannel::fac_in, misdn_bchannel::fac_out, chan_list::far_alerting, find_chan_by_bc(), find_hold_active_call(), find_hold_call(), find_hold_call_l3(), ast_frame_subclass::format, ast_frame::frametype, misdn_party_redirecting::from, ast_generator::generate, hangup_chan(), hanguptone_indicate(), chan_list::hold, ast_party_caller::id, chan_list::ignore_dtmf, misdn_bchannel::incoming_cid_tag, INFO_CAPABILITY_DIGITAL_UNRESTRICTED, misdn_bchannel::info_dad, INFO_PI_INBAND_AVAILABLE, misdn_bchannel::infos_pending, ast_frame_subclass::integer, misdn_bchannel::keypad, misdn_bchannel::l3_id, chan_list::l3id, LOG_ERROR, LOG_NOTICE, LOG_WARNING, ast_frame::mallocd, manager_isdn_get_info(), misdn_add_number_prefix(), MISDN_ALERTING, MISDN_ASTERISK_TECH_PVT, misdn_attempt_transfer(), MISDN_CALLING, MISDN_CALLING_ACKNOWLEDGE, misdn_cap_is_speech(), MISDN_CFG_ALARM_BLOCK, MISDN_CFG_ALWAYS_IMMEDIATE, MISDN_CFG_APPEND_MSN_TO_CALLERID_TAG, misdn_cfg_get(), MISDN_CFG_HOLD_ALLOWED, MISDN_CFG_IMMEDIATE, MISDN_CFG_REJECT_CAUSE, MISDN_CLEANING, MISDN_CONNECTED, misdn_copy_redirecting_to_ast(), MISDN_DIALING, MISDN_DISCONNECTED, MISDN_EXTCANTMATCH, misdn_facility_ie_handler(), MISDN_GEN_APPEND_DIGITS2EXTEN, misdn_get_ch_state(), MISDN_HOLD_ACTIVE, MISDN_HOLD_DISCONNECT, MISDN_HOLD_IDLE, misdn_inband_avail(), MISDN_INCOMING_SETUP, misdn_is_msn_valid(), misdn_lib_is_ptp(), misdn_lib_log_ies(), misdn_lib_port_block(), misdn_lib_send_event(), misdn_new(), MISDN_NOTHING, mISDN_NOTIFY_CODE_CALL_IS_DIVERTING, mISDN_NOTIFY_CODE_CALL_TRANSFER_ACTIVE, mISDN_NOTIFY_CODE_CALL_TRANSFER_ALERTING, mISDN_NOTIFY_CODE_DIVERSION_ACTIVATED, mISDN_NOTIFY_CODE_INVALID, misdn_overlap_dial_task(), MISDN_PROCEEDING, MISDN_PROGRESS, mISDN_REDIRECTING_REASON_NO_REPLY, mISDN_REDIRECTING_REASON_UNKNOWN, misdn_tasks_add_variable(), misdn_to_ast_plan(), misdn_to_ast_pres(), misdn_to_ast_screen(), misdn_to_ast_ton(), misdn_to_str_plan(), misdn_to_str_pres(), misdn_to_str_screen(), misdn_to_str_ton(), misdn_update_remote_party(), MISDN_WAITING4DIGS, ast_custom_function::name, misdn_party_id::name, allowed_bearers::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, NULL, misdn_party_dialing::number, misdn_party_id::number, ast_party_id::number, misdn_party_id::number_plan, misdn_party_id::number_type, ast_frame::offset, ORG_AST, ORG_MISDN, chan_list::originator, misdn_bchannel::out_cause, chan_list::overlap_dial, chan_list::overlap_dial_task, chan_list::overlap_tv, chan_list::overlap_tv_lock, parse(), pbx_builtin_setvar_helper(), misdn_bchannel::pid, chan_list::pipe, ast_party_number::plan, hold_info::port, misdn_bchannel::port, misdn_party_id::presentation, ast_party_number::presentation, print_bearer(), ast_party_redirecting::priv_from, ast_party_redirecting::priv_orig, ast_party_redirecting::priv_to, misdn_bchannel::progress_indicator, ast_frame::ptr, RAII_VAR, read_config(), misdn_party_redirecting::reason, misdn_bchannel::redirecting, release_chan(), RESPONSE_ERR, RESPONSE_IGNORE_SETUP, RESPONSE_IGNORE_SETUP_WITHOUT_CLOSE, RESPONSE_OK, RESPONSE_RELEASE_SETUP, misdn_jb::samples, ast_frame::samples, misdn_party_id::screening, misdn_bchannel::sending_complete, misdn_jb::size, ast_frame::src, start_bc_tones(), start_pbx(), hold_info::state, chan_list::state, stop_bc_tones(), stop_indicate(), ast_frame::subclass, ast_party_id::tag, tmp(), misdn_party_redirecting::to, ast_party_redirecting::to, misdn_party_redirecting::to_changed, misdn_bchannel::tone_cnt, update_name(), and wait_for_digits().

Referenced by load_module().

9918 {
9919 #if defined(AST_MISDN_ENHANCEMENTS)
9920  struct misdn_cc_record *cc_record;
9921 #endif /* defined(AST_MISDN_ENHANCEMENTS) */
9922  struct chan_list *held_ch;
9923  struct chan_list *ch = find_chan_by_bc(bc);
9924 
9926  int debuglevel = 1;
9927 
9928  /* Debug Only Non-Bchan */
9929  if (event == EVENT_CLEANUP && !user_data) {
9930  debuglevel = 5;
9931  }
9932 
9933  chan_misdn_log(debuglevel, bc->port,
9934  "I IND :%s caller:\"%s\" <%s> dialed:%s pid:%d state:%s\n",
9936  bc->caller.name,
9937  bc->caller.number,
9938  bc->dialed.number,
9939  bc->pid,
9940  ch ? misdn_get_ch_state(ch) : "none");
9941  if (debuglevel == 1) {
9942  misdn_lib_log_ies(bc);
9943  chan_misdn_log(4, bc->port, " --> bc_state:%s\n", bc_state2str(bc->bc_state));
9944  }
9945  }
9946 
9947  if (!ch) {
9948  switch(event) {
9949  case EVENT_SETUP:
9950  case EVENT_DISCONNECT:
9951  case EVENT_RELEASE:
9953  case EVENT_PORT_ALARM:
9954  case EVENT_RETRIEVE:
9955  case EVENT_NEW_BC:
9956  case EVENT_FACILITY:
9957  case EVENT_REGISTER:
9958  break;
9959  case EVENT_CLEANUP:
9960  case EVENT_TONE_GENERATE:
9961  case EVENT_BCHAN_DATA:
9962  return -1;
9963  default:
9964  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);
9965  return -1;
9966  }
9967  } else {
9968  switch (event) {
9969  case EVENT_TONE_GENERATE:
9970  break;
9971  case EVENT_DISCONNECT:
9972  case EVENT_RELEASE:
9974  case EVENT_CLEANUP:
9975  case EVENT_TIMEOUT:
9976  if (!ch->ast) {
9977  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));
9978  }
9979  break;
9980  default:
9981  if (!ch->ast || !MISDN_ASTERISK_TECH_PVT(ch->ast)) {
9982  if (event != EVENT_BCHAN_DATA) {
9983  ast_log(LOG_NOTICE, "No Ast or No private Pointer in Event (%d:%s)\n", event, manager_isdn_get_info(event));
9984  }
9985  chan_list_unref(ch, "No Ast or Ast private pointer");
9986  return -1;
9987  }
9988  break;
9989  }
9990  }
9991 
9992 
9993  switch (event) {
9994  case EVENT_PORT_ALARM:
9995  {
9996  int boa = 0;
9997  misdn_cfg_get(bc->port, MISDN_CFG_ALARM_BLOCK, &boa, sizeof(boa));
9998  if (boa) {
9999  cb_log(1, bc->port, " --> blocking\n");
10001  }
10002  }
10003  break;
10004  case EVENT_BCHAN_ACTIVATED:
10005  break;
10006 
10007  case EVENT_NEW_CHANNEL:
10008  update_name(ch->ast,bc->port,bc->channel);
10009  break;
10010 
10011  case EVENT_NEW_L3ID:
10012  ch->l3id=bc->l3_id;
10013  ch->addr=bc->addr;
10014  break;
10015 
10016  case EVENT_NEW_BC:
10017  if (!ch) {
10018  ch = find_hold_call(bc);
10019  }
10020 
10021  if (!ch) {
10022  ast_log(LOG_WARNING, "NEW_BC without chan_list?\n");
10023  break;
10024  }
10025 
10026  if (bc) {
10027  ch->bc = (struct misdn_bchannel *) user_data;
10028  }
10029  break;
10030 
10031  case EVENT_DTMF_TONE:
10032  {
10033  /* sending INFOS as DTMF-Frames :) */
10034  struct ast_frame fr;
10035 
10036  memset(&fr, 0, sizeof(fr));
10037  fr.frametype = AST_FRAME_DTMF;
10038  fr.subclass.integer = bc->dtmf ;
10039  fr.src = NULL;
10040  fr.data.ptr = NULL;
10041  fr.datalen = 0;
10042  fr.samples = 0;
10043  fr.mallocd = 0;
10044  fr.offset = 0;
10045  fr.delivery = ast_tv(0,0);
10046 
10047  if (!ch->ignore_dtmf) {
10048  chan_misdn_log(2, bc->port, " --> DTMF:%c\n", bc->dtmf);
10049  ast_queue_frame(ch->ast, &fr);
10050  } else {
10051  chan_misdn_log(2, bc->port, " --> Ignoring DTMF:%c due to bridge flags\n", bc->dtmf);
10052  }
10053  break;
10054  }
10055  case EVENT_STATUS:
10056  break;
10057 
10058  case EVENT_INFORMATION:
10059  if (ch->state != MISDN_CONNECTED) {
10060  stop_indicate(ch);
10061  }
10062 
10063  if (!ch->ast) {
10064  break;
10065  }
10066 
10067  if (ch->state == MISDN_WAITING4DIGS) {
10068  RAII_VAR(struct ast_features_pickup_config *, pickup_cfg, NULL, ao2_cleanup);
10069  const char *pickupexten;
10070 
10071  /* Ok, incomplete Setup, waiting till extension exists */
10072  if (ast_strlen_zero(bc->info_dad) && ! ast_strlen_zero(bc->keypad)) {
10073  chan_misdn_log(1, bc->port, " --> using keypad as info\n");
10074  ast_copy_string(bc->info_dad, bc->keypad, sizeof(bc->info_dad));
10075  }
10076 
10077  strncat(bc->dialed.number, bc->info_dad, sizeof(bc->dialed.number) - strlen(bc->dialed.number) - 1);
10079 
10080  ast_channel_lock(ch->ast);
10081  pickup_cfg = ast_get_chan_features_pickup_config(ch->ast);
10082  if (!pickup_cfg) {
10083  ast_log(LOG_ERROR, "Unable to retrieve pickup configuration options. Unable to detect call pickup extension\n");
10084  pickupexten = "";
10085  } else {
10086  pickupexten = ast_strdupa(pickup_cfg->pickupexten);
10087  }
10088  ast_channel_unlock(ch->ast);
10089 
10090  /* Check for Pickup Request first */
10091  if (!strcmp(ast_channel_exten(ch->ast), pickupexten)) {
10092  if (ast_pickup_call(ch->ast)) {
10093  hangup_chan(ch, bc);
10094  } else {
10096  hangup_chan(ch, bc);
10097  ch->ast = NULL;
10098  break;
10099  }
10100  }
10101 
10102  if (!ast_canmatch_extension(ch->ast, ch->context, bc->dialed.number, 1, bc->caller.number)) {
10103  if (ast_exists_extension(ch->ast, ch->context, "i", 1, bc->caller.number)) {
10105  "Extension '%s@%s' can never match. Jumping to 'i' extension. port:%d\n",
10106  bc->dialed.number, ch->context, bc->port);
10107  pbx_builtin_setvar_helper(ch->ast, "INVALID_EXTEN", bc->dialed.number);
10108  ast_channel_exten_set(ch->ast, "i");
10109  ch->state = MISDN_DIALING;
10110  start_pbx(ch, bc, ch->ast);
10111  break;
10112  }
10113 
10115  "Extension '%s@%s' can never match. Disconnecting. port:%d\n"
10116  "\tMaybe you want to add an 'i' extension to catch this case.\n",
10117  bc->dialed.number, ch->context, bc->port);
10118 
10119  if (bc->nt) {
10120  hanguptone_indicate(ch);
10121  }
10122  ch->state = MISDN_EXTCANTMATCH;
10124 
10126  break;
10127  }
10128 
10129  if (ch->overlap_dial) {
10131  ch->overlap_tv = ast_tvnow();
10133  if (ch->overlap_dial_task == -1) {
10134  ch->overlap_dial_task =
10136  }
10137  break;
10138  }
10139 
10140  if (ast_exists_extension(ch->ast, ch->context, bc->dialed.number, 1, bc->caller.number)) {
10141  ch->state = MISDN_DIALING;
10142  start_pbx(ch, bc, ch->ast);
10143  }
10144  } else {
10145  /* sending INFOS as DTMF-Frames :) */
10146  struct ast_frame fr;
10147  int digits;
10148 
10149  memset(&fr, 0, sizeof(fr));
10150  fr.frametype = AST_FRAME_DTMF;
10151  fr.subclass.integer = bc->info_dad[0] ;
10152  fr.src = NULL;
10153  fr.data.ptr = NULL;
10154  fr.datalen = 0;
10155  fr.samples = 0;
10156  fr.mallocd = 0;
10157  fr.offset = 0;
10158  fr.delivery = ast_tv(0,0);
10159 
10160  misdn_cfg_get(0, MISDN_GEN_APPEND_DIGITS2EXTEN, &digits, sizeof(digits));
10161  if (ch->state != MISDN_CONNECTED) {
10162  if (digits) {
10163  strncat(bc->dialed.number, bc->info_dad, sizeof(bc->dialed.number) - strlen(bc->dialed.number) - 1);
10165  }
10166 
10167  ast_queue_frame(ch->ast, &fr);
10168  }
10169  }
10170  break;
10171  case EVENT_SETUP:
10172  {
10173  struct ast_channel *chan;
10174  int exceed;
10175  int ai;
10176  int im;
10177  int append_msn = 0;
10178  RAII_VAR(struct ast_features_pickup_config *, pickup_cfg, NULL, ao2_cleanup);
10179  const char *pickupexten;
10180 
10181  if (ch) {
10182  switch (ch->state) {
10183  case MISDN_NOTHING:
10184  chan_list_unref(ch, "Ignore found ch. Is it for an outgoing call?");
10185  ch = NULL;
10186  break;
10187  default:
10188  chan_list_unref(ch, "Already have a call.");
10189  chan_misdn_log(1, bc->port, " --> Ignoring Call we have already one\n");
10190  return RESPONSE_IGNORE_SETUP_WITHOUT_CLOSE; /* Ignore MSNs which are not in our List */
10191  }
10192  }
10193 
10194  if (!bc->nt && !misdn_is_msn_valid(bc->port, &bc->dialed)) {
10195  chan_misdn_log(1, bc->port, " --> Ignoring Call, its not in our MSN List\n");
10196  return RESPONSE_IGNORE_SETUP; /* Ignore MSNs which are not in our List */
10197  }
10198 
10199  if (bc->cw) {
10200  int cause;
10201  chan_misdn_log(0, bc->port, " --> Call Waiting on PMP sending RELEASE_COMPLETE\n");
10202  misdn_cfg_get(bc->port, MISDN_CFG_REJECT_CAUSE, &cause, sizeof(cause));
10203  bc->out_cause = cause ? cause : AST_CAUSE_NORMAL_CLEARING;
10204  return RESPONSE_RELEASE_SETUP;
10205  }
10206 
10207  print_bearer(bc);
10208 
10209  ch = chan_list_init(ORG_MISDN);
10210  if (!ch) {
10211  chan_misdn_log(-1, bc->port, "cb_events: malloc for chan_list failed!\n");
10212  return RESPONSE_RELEASE_SETUP;
10213  }
10214 
10215  ch->bc = bc;
10216  ch->l3id = bc->l3_id;
10217  ch->addr = bc->addr;
10218 
10219  {
10221  if (!(cap)) {
10222  return RESPONSE_ERR;
10223  }
10225  chan = misdn_new(ch, AST_STATE_RESERVED, bc->dialed.number, bc->caller.number, cap, NULL, NULL, bc->port, bc->channel);
10226  ao2_ref(cap, -1);
10227  }
10228  if (!chan) {
10229  chan_list_unref(ch, "Failed to create a new channel");
10230  ast_log(LOG_ERROR, "cb_events: misdn_new failed!\n");
10231  return RESPONSE_RELEASE_SETUP;
10232  }
10233 
10234  ast_channel_lock(chan);
10235  pickup_cfg = ast_get_chan_features_pickup_config(chan);
10236  if (!pickup_cfg) {
10237  ast_log(LOG_ERROR, "Unable to retrieve pickup configuration options. Unable to detect call pickup extension\n");
10238  pickupexten = "";
10239  } else {
10240  pickupexten = ast_strdupa(pickup_cfg->pickupexten);
10241  }
10242  ast_channel_unlock(chan);
10243 
10244  if ((exceed = add_in_calls(bc->port))) {
10245  char tmp[16];
10246  snprintf(tmp, sizeof(tmp), "%d", exceed);
10247  pbx_builtin_setvar_helper(chan, "MAX_OVERFLOW", tmp);
10248  }
10249 
10250  read_config(ch);
10251 
10252  export_ch(chan, bc, ch);
10253 
10254  ast_channel_lock(ch->ast);
10255  ast_channel_rings_set(ch->ast, 1);
10257  ast_channel_unlock(ch->ast);
10258 
10259  /* Update asterisk channel caller information */
10260  chan_misdn_log(2, bc->port, " --> TON: %s(%d)\n", misdn_to_str_ton(bc->caller.number_type), bc->caller.number_type);
10261  chan_misdn_log(2, bc->port, " --> PLAN: %s(%d)\n", misdn_to_str_plan(bc->caller.number_plan), bc->caller.number_plan);
10264 
10265  chan_misdn_log(2, bc->port, " --> PRES: %s(%d)\n", misdn_to_str_pres(bc->caller.presentation), bc->caller.presentation);
10266  chan_misdn_log(2, bc->port, " --> SCREEN: %s(%d)\n", misdn_to_str_screen(bc->caller.screening), bc->caller.screening);
10269 
10270  ast_set_callerid(chan, bc->caller.number, NULL, bc->caller.number);
10271 
10272  misdn_cfg_get(bc->port, MISDN_CFG_APPEND_MSN_TO_CALLERID_TAG, &append_msn, sizeof(append_msn));
10273  if (append_msn) {
10274  strncat(bc->incoming_cid_tag, "_", sizeof(bc->incoming_cid_tag) - strlen(bc->incoming_cid_tag) - 1);
10275  strncat(bc->incoming_cid_tag, bc->dialed.number, sizeof(bc->incoming_cid_tag) - strlen(bc->incoming_cid_tag) - 1);
10276  }
10277 
10278  ast_channel_lock(chan);
10280  ast_channel_unlock(chan);
10281 
10282  if (!ast_strlen_zero(bc->redirecting.from.number)) {
10283  /* Add configured prefix to redirecting.from.number */
10285 
10286  /* Update asterisk channel redirecting information */
10288  }
10289 
10290  pbx_builtin_setvar_helper(chan, "TRANSFERCAPABILITY", ast_transfercapability2str(bc->capability));
10292 
10293  switch (bc->capability) {
10295  pbx_builtin_setvar_helper(chan, "CALLTYPE", "DIGITAL");
10296  break;
10297  default:
10298  pbx_builtin_setvar_helper(chan, "CALLTYPE", "SPEECH");
10299  break;
10300  }
10301 
10302  if (!strstr(ch->allowed_bearers, "all")) {
10303  int i;
10304 
10305  for (i = 0; i < ARRAY_LEN(allowed_bearers_array); ++i) {
10306  if (allowed_bearers_array[i].cap == bc->capability) {
10307  if (strstr(ch->allowed_bearers, allowed_bearers_array[i].name)) {
10308  /* The bearer capability is allowed */
10309  if (allowed_bearers_array[i].deprecated) {
10310  chan_misdn_log(0, bc->port, "%s in allowed_bearers list is deprecated\n",
10312  }
10313  break;
10314  }
10315  }
10316  }
10317  if (i == ARRAY_LEN(allowed_bearers_array)) {
10318  /* We did not find the bearer capability */
10319  chan_misdn_log(0, bc->port, "Bearer capability not allowed: %s(%d)\n",
10320  bearer2str(bc->capability), bc->capability);
10321 
10322  ch->state = MISDN_EXTCANTMATCH;
10323  chan_list_unref(ch, "BC not allowed, releasing call");
10325  return RESPONSE_RELEASE_SETUP;
10326  }
10327  }
10328 
10329  /** queue new chan **/
10330  cl_queue_chan(ch);
10331 
10332  if (bc->fac_in.Function != Fac_None) {
10334  }
10335 
10336  /* Check for Pickup Request first */
10337  if (!strcmp(ast_channel_exten(chan), pickupexten)) {
10338  if (!ch->noautorespond_on_setup) {
10339  /* Sending SETUP_ACK */
10341  } else {
10343  }
10344  if (ast_pickup_call(chan)) {
10345  hangup_chan(ch, bc);
10346  } else {
10348  hangup_chan(ch, bc);
10349  ch->ast = NULL;
10350  break;
10351  }
10352  }
10353 
10354  /*
10355  * added support for s extension hope it will help those poor cretains
10356  * which haven't overlap dial.
10357  */
10358  misdn_cfg_get(bc->port, MISDN_CFG_ALWAYS_IMMEDIATE, &ai, sizeof(ai));
10359  if (ai) {
10360  do_immediate_setup(bc, ch, chan);
10361  break;
10362  }
10363 
10364  /* check if we should jump into s when we have no dialed.number */
10365  misdn_cfg_get(bc->port, MISDN_CFG_IMMEDIATE, &im, sizeof(im));
10366  if (im && ast_strlen_zero(bc->dialed.number)) {
10367  do_immediate_setup(bc, ch, chan);
10368  break;
10369  }
10370 
10371  chan_misdn_log(5, bc->port, "CONTEXT:%s\n", ch->context);
10372  if (!ast_canmatch_extension(ch->ast, ch->context, bc->dialed.number, 1, bc->caller.number)) {
10373  if (ast_exists_extension(ch->ast, ch->context, "i", 1, bc->caller.number)) {
10375  "Extension '%s@%s' can never match. Jumping to 'i' extension. port:%d\n",
10376  bc->dialed.number, ch->context, bc->port);
10377  pbx_builtin_setvar_helper(ch->ast, "INVALID_EXTEN", bc->dialed.number);
10378  ast_channel_exten_set(ch->ast, "i");
10380  ch->state = MISDN_DIALING;
10381  start_pbx(ch, bc, chan);
10382  break;
10383  }
10384 
10386  "Extension '%s@%s' can never match. Disconnecting. port:%d\n"
10387  "\tMaybe you want to add an 'i' extension to catch this case.\n",
10388  bc->dialed.number, ch->context, bc->port);
10389  if (bc->nt) {
10390  hanguptone_indicate(ch);
10391  }
10392 
10393  ch->state = MISDN_EXTCANTMATCH;
10395 
10397  break;
10398  }
10399 
10400  /* Whatever happens, when sending_complete is set or we are PTMP TE, we will definitely
10401  * jump into the dialplan, when the dialed extension does not exist, the 's' extension
10402  * will be used by Asterisk automatically. */
10403  if (bc->sending_complete || (!bc->nt && !misdn_lib_is_ptp(bc->port))) {
10404  if (!ch->noautorespond_on_setup) {
10405  ch->state=MISDN_DIALING;
10407  } else {
10409  }
10410  start_pbx(ch, bc, chan);
10411  break;
10412  }
10413 
10414 
10415  /*
10416  * When we are NT and overlapdial is set and if
10417  * the number is empty, we wait for the ISDN timeout
10418  * instead of our own timer.
10419  */
10420  if (ch->overlap_dial && bc->nt && !bc->dialed.number[0]) {
10421  wait_for_digits(ch, bc, chan);
10422  break;
10423  }
10424 
10425  /*
10426  * If overlapdial we will definitely send a SETUP_ACKNOWLEDGE and wait for more
10427  * Infos with a Interdigit Timeout.
10428  * */
10429  if (ch->overlap_dial) {
10431  ch->overlap_tv = ast_tvnow();
10433 
10434  wait_for_digits(ch, bc, chan);
10435  if (ch->overlap_dial_task == -1) {
10436  ch->overlap_dial_task =
10438  }
10439  break;
10440  }
10441 
10442  /* If the extension does not exist and we're not TE_PTMP we wait for more digits
10443  * without interdigit timeout.
10444  * */
10445  if (!ast_exists_extension(ch->ast, ch->context, bc->dialed.number, 1, bc->caller.number)) {
10446  wait_for_digits(ch, bc, chan);
10447  break;
10448  }
10449 
10450  /*
10451  * If the extension exists let's just jump into it.
10452  * */
10453  if (ast_exists_extension(ch->ast, ch->context, bc->dialed.number, 1, bc->caller.number)) {
10455  ch->state = MISDN_DIALING;
10456  start_pbx(ch, bc, chan);
10457  break;
10458  }
10459  break;
10460  }
10461 #if defined(AST_MISDN_ENHANCEMENTS)
10462  case EVENT_REGISTER:
10463  if (bc->fac_in.Function != Fac_None) {
10465  }
10466  /*
10467  * Shut down this connection immediately.
10468  * The current design of chan_misdn data structures
10469  * does not allow the proper handling of inbound call records
10470  * without an assigned B channel. Therefore, we cannot
10471  * be the CCBS User-B party in a point-to-point setup.
10472  */
10473  bc->fac_out.Function = Fac_None;
10476  break;
10477 #endif /* defined(AST_MISDN_ENHANCEMENTS) */
10480 
10481  if (bc->channel) {
10482  update_name(ch->ast,bc->port,bc->channel);
10483  }
10484 
10485  if (bc->fac_in.Function != Fac_None) {
10487  }
10488 
10489  if (!ast_strlen_zero(bc->infos_pending)) {
10490  /* TX Pending Infos */
10491  strncat(bc->dialed.number, bc->infos_pending, sizeof(bc->dialed.number) - strlen(bc->dialed.number) - 1);
10492 
10493  if (!ch->ast) {
10494  break;
10495  }
10497  ast_copy_string(bc->info_dad, bc->infos_pending, sizeof(bc->info_dad));
10498  ast_copy_string(bc->infos_pending, "", sizeof(bc->infos_pending));
10499 
10501  }
10502  break;
10503  case EVENT_PROCEEDING:
10504  if (misdn_cap_is_speech(bc->capability) &&
10505  misdn_inband_avail(bc)) {
10506  start_bc_tones(ch);
10507  }
10508 
10509  ch->state = MISDN_PROCEEDING;
10510 
10511  if (bc->fac_in.Function != Fac_None) {
10513  }
10514 
10515  if (!ch->ast) {
10516  break;
10517  }
10518 
10520  break;
10521  case EVENT_PROGRESS:
10522  if (bc->channel) {
10523  update_name(ch->ast, bc->port, bc->channel);
10524  }
10525 
10526  if (bc->fac_in.Function != Fac_None) {
10528  }
10529 
10530  if (!bc->nt) {
10531  if (misdn_cap_is_speech(bc->capability) &&
10532  misdn_inband_avail(bc)) {
10533  start_bc_tones(ch);
10534  }
10535 
10536  ch->state = MISDN_PROGRESS;
10537 
10538  if (!ch->ast) {
10539  break;
10540  }
10542  }
10543  break;
10544  case EVENT_ALERTING:
10545  ch->state = MISDN_ALERTING;
10546 
10547  if (!ch->ast) {
10548  break;
10549  }
10550 
10551  if (bc->fac_in.Function != Fac_None) {
10553  }
10554 
10556  ast_channel_lock(ch->ast);
10558  ast_channel_unlock(ch->ast);
10559 
10560  cb_log(7, bc->port, " --> Set State Ringing\n");
10561 
10563  cb_log(1, bc->port, "Starting Tones, we have inband Data\n");
10564  start_bc_tones(ch);
10565  } else {
10566  cb_log(3, bc->port, " --> We have no inband Data, the other end must create ringing\n");
10567  if (ch->far_alerting) {
10568  cb_log(1, bc->port, " --> The other end can not do ringing eh ?.. we must do all ourself..");
10569  start_bc_tones(ch);
10570  /*tone_indicate(ch, TONE_FAR_ALERTING);*/
10571  }
10572  }
10573  break;
10574  case EVENT_CONNECT:
10575  if (bc->fac_in.Function != Fac_None) {
10577  }
10578 #if defined(AST_MISDN_ENHANCEMENTS)
10579  if (bc->div_leg_3_rx_wanted) {
10580  bc->div_leg_3_rx_wanted = 0;
10581 
10582  if (ch->ast) {
10583  struct ast_party_redirecting redirecting;
10584 
10587  ast_party_redirecting_init(&redirecting);
10589 
10590  /*
10591  * Reset any earlier private redirecting id representations and
10592  * make sure that it is invalidated at the remote end.
10593  */
10594  ast_party_id_reset(&redirecting.priv_orig);
10595  ast_party_id_reset(&redirecting.priv_from);
10596  ast_party_id_reset(&redirecting.priv_to);
10597 
10598  ast_channel_queue_redirecting_update(ch->ast, &redirecting, NULL);
10599  ast_party_redirecting_free(&redirecting);
10600  }
10601  }
10602 #endif /* defined(AST_MISDN_ENHANCEMENTS) */
10603 
10604  /* we answer when we've got our very new L3 ID from the NT stack */
10606 
10607  if (!ch->ast) {
10608  break;
10609  }
10610 
10611  stop_indicate(ch);
10612 
10613 #if defined(AST_MISDN_ENHANCEMENTS)
10614  if (ch->record_id != -1) {
10615  /*
10616  * We will delete the associated call completion
10617  * record since we now have a completed call.
10618  * We will not wait/depend on the network to tell
10619  * us to delete it.
10620  */
10621  AST_LIST_LOCK(&misdn_cc_records_db);
10622  cc_record = misdn_cc_find_by_id(ch->record_id);
10623  if (cc_record) {
10624  if (cc_record->ptp && cc_record->mode.ptp.bc) {
10625  /* Close the call-completion signaling link */
10626  cc_record->mode.ptp.bc->fac_out.Function = Fac_None;
10627  cc_record->mode.ptp.bc->out_cause = AST_CAUSE_NORMAL_CLEARING;
10628  misdn_lib_send_event(cc_record->mode.ptp.bc, EVENT_RELEASE_COMPLETE);
10629  }
10630  misdn_cc_delete(cc_record);
10631  }
10632  AST_LIST_UNLOCK(&misdn_cc_records_db);
10633  ch->record_id = -1;
10634  if (ch->peer) {
10635  misdn_cc_set_peer_var(ch->peer, MISDN_CC_RECORD_ID, "");
10636 
10637  ao2_ref(ch->peer, -1);
10638  ch->peer = NULL;
10639  }
10640  }
10641 #endif /* defined(AST_MISDN_ENHANCEMENTS) */
10642 
10643  if (!ast_strlen_zero(bc->connected.number)) {
10644  /* Add configured prefix to connected.number */
10646 
10647  /* Update the connected line information on the other channel */
10649  }
10650 
10651  ch->l3id = bc->l3_id;
10652  ch->addr = bc->addr;
10653 
10654  start_bc_tones(ch);
10655 
10656  ch->state = MISDN_CONNECTED;
10657 
10659  break;
10661  ch->l3id = bc->l3_id;
10662  ch->addr = bc->addr;
10663 
10664  start_bc_tones(ch);
10665 
10666  ch->state = MISDN_CONNECTED;
10667  break;
10668  case EVENT_DISCONNECT:
10669  /* we might not have an ch->ast ptr here anymore */
10670  if (ch) {
10671  if (bc->fac_in.Function != Fac_None) {
10673  }
10674 
10675  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);
10676  if (ch->originator == ORG_AST && !bc->nt && misdn_inband_avail(bc) && ch->state != MISDN_CONNECTED) {
10677  /* If there's inband information available (e.g. a
10678  recorded message saying what was wrong with the
10679  dialled number, or perhaps even giving an
10680  alternative number, then play it instead of
10681  immediately releasing the call */
10682  chan_misdn_log(1, bc->port, " --> Inband Info Avail, not sending RELEASE\n");
10683 
10684  ch->state = MISDN_DISCONNECTED;
10685  start_bc_tones(ch);
10686 
10687  if (ch->ast) {
10689  if (bc->cause == AST_CAUSE_USER_BUSY) {
10691  }
10692  }
10693  ch->need_busy = 0;
10694  break;
10695  }
10696 
10697  bc->need_disconnect = 0;
10698  stop_bc_tones(ch);
10699 
10700  /* Check for held channel, to implement transfer */
10701  held_ch = find_hold_call(bc);
10702  if (!held_ch || !ch->ast || misdn_attempt_transfer(ch, held_ch)) {
10703  hangup_chan(ch, bc);
10704  }
10705  } else {
10706  held_ch = find_hold_call_l3(bc->l3_id);
10707  if (held_ch) {
10708  if (bc->fac_in.Function != Fac_None) {
10709  misdn_facility_ie_handler(event, bc, held_ch);
10710  }
10711 
10712  if (held_ch->hold.state == MISDN_HOLD_ACTIVE) {
10713  bc->need_disconnect = 0;
10714 
10715 #if defined(TRANSFER_ON_HELD_CALL_HANGUP)
10716  /*
10717  * Some phones disconnect the held call and the active call at the
10718  * same time to do the transfer. Unfortunately, either call could
10719  * be disconnected first.
10720  */
10721  ch = find_hold_active_call(bc);
10722  if (!ch || misdn_attempt_transfer(ch, held_ch)) {
10723  held_ch->hold.state = MISDN_HOLD_DISCONNECT;
10724  hangup_chan(held_ch, bc);
10725  }
10726 #else
10727  hangup_chan(held_ch, bc);
10728 #endif /* defined(TRANSFER_ON_HELD_CALL_HANGUP) */
10729  }
10730  }
10731  }
10732  if (held_ch) {
10733  chan_list_unref(held_ch, "Done with held call");
10734  }
10735  bc->out_cause = -1;
10736  if (bc->need_release) {
10738  }
10739  break;
10740  case EVENT_RELEASE:
10741  if (!ch) {
10742  ch = find_hold_call_l3(bc->l3_id);
10743  if (!ch) {
10744  chan_misdn_log(1, bc->port,
10745  " --> no Ch, so we've already released. (%s)\n",
10747  return -1;
10748  }
10749  }
10750  if (bc->fac_in.Function != Fac_None) {
10752  }
10753 
10754  bc->need_disconnect = 0;
10755  bc->need_release = 0;
10756 
10757  hangup_chan(ch, bc);
10758  release_chan(ch, bc);
10759  break;
10761  if (!ch) {
10762  ch = find_hold_call_l3(bc->l3_id);
10763  }
10764 
10765  bc->need_disconnect = 0;
10766  bc->need_release = 0;
10767  bc->need_release_complete = 0;
10768 
10769  if (ch) {
10770  if (bc->fac_in.Function != Fac_None) {
10772  }
10773 
10774  stop_bc_tones(ch);
10775  hangup_chan(ch, bc);
10776  release_chan(ch, bc);
10777  } else {
10778 #if defined(AST_MISDN_ENHANCEMENTS)
10779  /*
10780  * A call-completion signaling link established with
10781  * REGISTER does not have a struct chan_list record
10782  * associated with it.
10783  */
10784  AST_LIST_LOCK(&misdn_cc_records_db);
10785  cc_record = misdn_cc_find_by_bc(bc);
10786  if (cc_record) {
10787  /* The call-completion signaling link is closed. */
10788  misdn_cc_delete(cc_record);
10789  }
10790  AST_LIST_UNLOCK(&misdn_cc_records_db);
10791 #endif /* defined(AST_MISDN_ENHANCEMENTS) */
10792 
10793  chan_misdn_log(1, bc->port,
10794  " --> no Ch, so we've already released. (%s)\n",
10796  }
10797  break;
10798  case EVENT_BCHAN_ERROR:
10799  case EVENT_CLEANUP:
10800  stop_bc_tones(ch);
10801 
10802  switch (ch->state) {
10803  case MISDN_CALLING:
10805  break;
10806  default:
10807  break;
10808  }
10809 
10810  hangup_chan(ch, bc);
10811  release_chan(ch, bc);
10812  break;
10813  case EVENT_TONE_GENERATE:
10814  {
10815  int tone_len = bc->tone_cnt;
10816  struct ast_channel *ast = ch->ast;
10817  void *tmp;
10818  int res;
10819  int (*generate)(struct ast_channel *chan, void *tmp, int datalen, int samples);
10820 
10821  chan_misdn_log(9, bc->port, "TONE_GEN: len:%d\n", tone_len);
10822 
10823  if (!ast) {
10824  break;
10825  }
10826 
10827  if (!ast_channel_generator(ast)) {
10828  break;
10829  }
10830 
10831  tmp = ast_channel_generatordata(ast);
10833  generate = ast_channel_generator(ast)->generate;
10834 
10835  if (tone_len < 0 || tone_len > 512) {
10836  ast_log(LOG_NOTICE, "TONE_GEN: len was %d, set to 128\n", tone_len);
10837  tone_len = 128;
10838  }
10839 
10840  res = generate(ast, tmp, tone_len, tone_len);
10842 
10843  if (res) {
10844  ast_log(LOG_WARNING, "Auto-deactivating generator\n");
10846  } else {
10847  bc->tone_cnt = 0;
10848  }
10849  break;
10850  }
10851  case EVENT_BCHAN_DATA:
10852  if (ch->bc->AOCD_need_export) {
10853  export_aoc_vars(ch->originator, ch->ast, ch->bc);
10854  }
10855  if (!misdn_cap_is_speech(ch->bc->capability)) {
10856  struct ast_frame frame;
10857 
10858  /* In Data Modes we queue frames */
10859  memset(&frame, 0, sizeof(frame));
10860  frame.frametype = AST_FRAME_VOICE; /* we have no data frames yet */
10861  frame.subclass.format = ast_format_alaw;
10862  frame.datalen = bc->bframe_len;
10863  frame.samples = bc->bframe_len;
10864  frame.mallocd = 0;
10865  frame.offset = 0;
10866  frame.delivery = ast_tv(0, 0);
10867  frame.src = NULL;
10868  frame.data.ptr = bc->bframe;
10869 
10870  if (ch->ast) {
10871  ast_queue_frame(ch->ast, &frame);
10872  }
10873  } else {
10874  struct pollfd pfd = { .fd = ch->pipe[1], .events = POLLOUT };
10875  int t;
10876 
10877  t = ast_poll(&pfd, 1, 0);
10878 
10879  if (t < 0) {
10880  chan_misdn_log(-1, bc->port, "poll() error (err=%s)\n", strerror(errno));
10881  break;
10882  }
10883  if (!t) {
10884  chan_misdn_log(9, bc->port, "poll() timed out\n");
10885  break;
10886  }
10887 
10888  if (pfd.revents & POLLOUT) {
10889  chan_misdn_log(9, bc->port, "writing %d bytes to asterisk\n", bc->bframe_len);
10890  if (write(ch->pipe[1], bc->bframe, bc->bframe_len) <= 0) {
10891  chan_misdn_log(0, bc->port, "Write returned <=0 (err=%s) --> hanging up channel\n", strerror(errno));
10892 
10893  stop_bc_tones(ch);
10894  hangup_chan(ch, bc);
10895  release_chan(ch, bc);
10896  }
10897  } else {
10898  chan_misdn_log(1, bc->port, "Write Pipe full!\n");
10899  }
10900  }
10901  break;
10902  case EVENT_TIMEOUT:
10903  if (ch && bc) {
10904  chan_misdn_log(1, bc->port, "--> state: %s\n", misdn_get_ch_state(ch));
10905  }
10906 
10907  switch (ch->state) {
10908  case MISDN_DIALING:
10909  case MISDN_PROGRESS:
10910  if (bc->nt && !ch->nttimeout) {
10911  break;
10912  }
10913  /* fall-through */
10914  case MISDN_CALLING:
10915  case MISDN_ALERTING:
10916  case MISDN_PROCEEDING:
10918  if (bc->nt) {
10920  hanguptone_indicate(ch);
10921  }
10922 
10925  break;
10926  case MISDN_WAITING4DIGS:
10927  if (bc->nt) {
10930  hanguptone_indicate(ch);
10932  } else {
10935  }
10936  break;
10937  case MISDN_CLEANING:
10938  chan_misdn_log(1, bc->port, " --> in state cleaning .. so ignoring, the stack should clean it for us\n");
10939  break;
10940  default:
10942  break;
10943  }
10944  break;
10945 
10946  /****************************/
10947  /** Supplementary Services **/
10948  /****************************/
10949  case EVENT_RETRIEVE:
10950  if (!ch) {
10951  chan_misdn_log(4, bc->port, " --> no CH, searching for held call\n");
10952  ch = find_hold_call_l3(bc->l3_id);
10953  if (!ch || ch->hold.state != MISDN_HOLD_ACTIVE) {
10954  ast_log(LOG_WARNING, "No held call found, cannot Retrieve\n");
10956  break;
10957  }
10958  }
10959 
10960  /* remember the channel again */
10961  ch->bc = bc;
10962 
10963  ch->hold.state = MISDN_HOLD_IDLE;
10964  ch->hold.port = 0;
10965  ch->hold.channel = 0;
10966 
10967  ast_queue_unhold(ch->ast);
10968 
10970  chan_misdn_log(4, bc->port, " --> RETRIEVE_ACK failed\n");
10972  }
10973  break;
10974  case EVENT_HOLD:
10975  {
10976  int hold_allowed;
10977  RAII_VAR(struct ast_channel *, bridged, NULL, ast_channel_cleanup);
10978 
10979  misdn_cfg_get(bc->port, MISDN_CFG_HOLD_ALLOWED, &hold_allowed, sizeof(hold_allowed));
10980  if (!hold_allowed) {
10981  chan_misdn_log(-1, bc->port, "Hold not allowed this port.\n");
10983  break;
10984  }
10985 
10986  bridged = ast_channel_bridge_peer(ch->ast);
10987  if (bridged) {
10988  chan_misdn_log(2, bc->port, "Bridge Partner is of type: %s\n", ast_channel_tech(bridged)->type);
10989  ch->l3id = bc->l3_id;
10990 
10991  /* forget the channel now */
10992  ch->bc = NULL;
10994  ch->hold.port = bc->port;
10995  ch->hold.channel = bc->channel;
10996 
10997  ast_queue_hold(ch->ast, NULL);
10998 
11000  } else {
11002  chan_misdn_log(0, bc->port, "We aren't bridged to anybody\n");
11003  }
11004  break;
11005  }
11006  case EVENT_NOTIFY:
11007  if (bc->redirecting.to_changed) {
11008  /* Add configured prefix to redirecting.to.number */
11010  bc->redirecting.to.number, sizeof(bc->redirecting.to.number));
11011  }
11012  switch (bc->notify_description_code) {
11014  /* Ignore for now. */
11015  bc->redirecting.to_changed = 0;
11016  break;
11018  {
11019  struct ast_party_redirecting redirecting;
11020 
11021  if (!bc->redirecting.to_changed) {
11022  break;
11023  }
11024  bc->redirecting.to_changed = 0;
11025  if (!ch || !ch->ast) {
11026  break;
11027  }
11028  switch (ch->state) {
11029  case MISDN_ALERTING:
11030  /* Call is deflecting after we have seen an ALERTING message */
11032  break;
11033  default:
11034  /* Call is deflecting for call forwarding unconditional or busy reason. */
11036  break;
11037  }
11039  ast_party_redirecting_init(&redirecting);
11041 
11042  /*
11043  * Reset any earlier private redirecting id representations and
11044  * make sure that it is invalidated at the remote end.
11045  */
11046  ast_party_id_reset(&redirecting.priv_orig);
11047  ast_party_id_reset(&redirecting.priv_from);
11048  ast_party_id_reset(&redirecting.priv_to);
11049 
11050  ast_channel_queue_redirecting_update(ch->ast, &redirecting, NULL);
11051  ast_party_redirecting_free(&redirecting);
11052  break;
11053  }
11055  /*
11056  * It would be preferable to update the connected line information
11057  * only when the message callStatus is active. However, the
11058  * optional redirection number may not be present in the active
11059  * message if an alerting message were received earlier.
11060  *
11061  * The consequences if we wind up sending two updates is benign.
11062  * The other end will think that it got transferred twice.
11063  */
11064  if (!bc->redirecting.to_changed) {
11065  break;
11066  }
11067  bc->redirecting.to_changed = 0;
11068  if (!ch || !ch->ast) {
11069  break;
11070  }
11073  bc->incoming_cid_tag);
11074  break;
11076  if (!bc->redirecting.to_changed) {
11077  break;
11078  }
11079  bc->redirecting.to_changed = 0;
11080  if (!ch || !ch->ast) {
11081  break;
11082  }
11085  break;
11086  default:
11087  bc->redirecting.to_changed = 0;
11088  chan_misdn_log(0, bc->port," --> not yet handled: notify code:0x%02X\n",
11090  break;
11091  }
11093  break;
11094  case EVENT_FACILITY:
11095  if (bc->fac_in.Function == Fac_None) {
11096  /* This is a FACILITY message so we MUST have a facility ie */
11097  chan_misdn_log(0, bc->port," --> Missing facility ie or unknown facility ie contents.\n");
11098  } else {
11100  }
11101 
11102  /* In case it came in on a FACILITY message and we did not handle it. */
11103  bc->redirecting.to_changed = 0;
11105  break;
11106  case EVENT_RESTART:
11107  if (!bc->dummy) {
11108  stop_bc_tones(ch);
11109  release_chan(ch, bc);
11110  }
11111  break;
11112  default:
11113  chan_misdn_log(1, 0, "Got Unknown Event\n");
11114  break;
11115  }
11116 
11117  if (ch) {
11118  chan_list_unref(ch, "cb_event complete OK");
11119  }
11120  return RESPONSE_OK;
11121 }
struct ast_party_caller * ast_channel_caller(struct ast_channel *chan)
int need_busy
TRUE if we could send an AST_CONTROL_BUSY if needed.
Definition: chan_misdn.c:402
static void chan_misdn_log(int level, int port, char *tmpl,...)
Definition: chan_misdn.c:12768
static const char type[]
Definition: chan_ooh323.c:109
char keypad[MISDN_MAX_KEYPAD_LEN]
Q.931 Keypad Facility IE contents.
Definition: isdn_lib.h:647
void ast_set_callerid(struct ast_channel *chan, const char *cid_num, const char *cid_name, const char *cid_ani)
Set caller ID number, name and ANI and generate AMI event.
Definition: channel.c:7434
#define ast_channel_lock(chan)
Definition: channel.h:2945
Main Channel structure associated with a channel.
static int stop_indicate(struct chan_list *cl)
Definition: chan_misdn.c:7743
static struct chan_list * find_hold_call(struct misdn_bchannel *bc)
Definition: chan_misdn.c:8283
struct FacParm fac_out
Outbound FACILITY message function type and contents.
Definition: isdn_lib.h:512
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
static void hanguptone_indicate(struct chan_list *cl)
Definition: chan_misdn.c:7738
static void wait_for_digits(struct chan_list *ch, struct misdn_bchannel *bc, struct ast_channel *chan)
Definition: chan_misdn.c:8889
#define AST_CAUSE_INCOMPATIBLE_DESTINATION
Definition: causes.h:134
static const char * misdn_to_str_ton(enum mISDN_NUMBER_TYPE number_type)
Definition: chan_misdn.c:1832
char number[MISDN_MAX_NUMBER_LEN]
Phone number (Address)
Definition: isdn_lib.h:298
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
struct ast_features_pickup_config * ast_get_chan_features_pickup_config(struct ast_channel *chan)
Get the pickup configuration options for a channel.
int ast_queue_control(struct ast_channel *chan, enum ast_control_frame_type control)
Queue a control frame without payload.
Definition: channel.c:1231
void * ast_channel_generatordata(const struct ast_channel *chan)
static int read_config(struct chan_list *ch)
Definition: chan_misdn.c:5922
static int misdn_to_ast_plan(enum mISDN_NUMBER_PLAN number_plan)
Definition: chan_misdn.c:2000
int presentation
Q.931 presentation-indicator and screening-indicator encoded fields.
Definition: channel.h:296
void ast_party_id_reset(struct ast_party_id *id)
Destroy and initialize the given party id structure.
Definition: channel.c:1896
int addr
From associated B channel: B Channel mISDN driver layer ID from mISDN_get_layerid() ...
Definition: chan_misdn.c:547
static struct ast_channel * misdn_new(struct chan_list *cl, int state, char *exten, char *callerid, struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, int port, int c)
Definition: chan_misdn.c:8174
int tone_cnt
Number of tone samples to generate.
Definition: isdn_lib.h:544
int ignore_dtmf
TRUE if DTMF digits are to be passed inband only.
Definition: chan_misdn.c:438
#define bc
#define AST_CAUSE_UNALLOCATED
Definition: causes.h:97
void ast_channel_hangupcause_set(struct ast_channel *chan, int value)
static int misdn_attempt_transfer(struct chan_list *active_ch, struct chan_list *held_ch)
Definition: chan_misdn.c:8619
int dummy
TRUE if this is a dummy BC record.
Definition: isdn_lib.h:361
int pipe[2]
Pipe file descriptor handles array. Read from pipe[0], write to pipe[1].
Definition: chan_misdn.c:444
int ast_queue_unhold(struct ast_channel *chan)
Queue an unhold frame.
Definition: channel.c:1216
static int misdn_to_ast_pres(int presentation)
Definition: chan_misdn.c:2117
static void cl_queue_chan(struct chan_list *chan)
Definition: chan_misdn.c:8377
int bframe_len
B channel speech sample data buffer size.
Definition: isdn_lib.h:435
#define LOG_WARNING
Definition: logger.h:274
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
char * manager_isdn_get_info(enum event_e event)
Definition: isdn_lib.c:4324
char incoming_cid_tag[MISDN_MAX_NAME_LEN]
Incoming Caller ID string tag for special purpose.
Definition: isdn_lib.h:348
static const struct allowed_bearers allowed_bearers_array[]
Definition: chan_misdn.c:2362
int cw
TRUE if call waiting.
Definition: isdn_lib.h:426
static int tmp()
Definition: bt_open.c:389
static void release_chan(struct chan_list *ch, struct misdn_bchannel *bc)
Definition: chan_misdn.c:8495
struct hold_info hold
HELD channel call information.
Definition: chan_misdn.c:535
B channel control structure.
Definition: isdn_lib.h:324
int presentation
Number presentation restriction code 0=Allowed, 1=Restricted, 2=Unavailable.
Definition: isdn_lib.h:277
int sending_complete
TRUE if all digits necessary to complete the call are available. No more INFORMATION messages are nee...
Definition: isdn_lib.h:470
static const char * misdn_get_ch_state(struct chan_list *p)
Definition: chan_misdn.c:4102
static struct chan_list * find_hold_active_call(struct misdn_bchannel *bc)
Definition: chan_misdn.c:8351
Definition: astman.c:222
static void misdn_copy_redirecting_to_ast(struct ast_channel *ast, const struct misdn_party_redirecting *redirect, char *tag)
Definition: chan_misdn.c:6437
#define MISDN_ASTERISK_TECH_PVT(ast)
Definition: chan_misdn.c:683
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
int(* generate)(struct ast_channel *chan, void *data, int len, int samples)
Definition: channel.h:234
static void start_pbx(struct chan_list *ch, struct misdn_bchannel *bc, struct ast_channel *chan)
Definition: chan_misdn.c:8875
int capability
SETUP message bearer capability field code value.
Definition: isdn_lib.h:609
#define ast_mutex_lock(a)
Definition: lock.h:187
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
static const char * misdn_to_str_pres(int presentation)
Definition: chan_misdn.c:2084
int AOCD_need_export
TRUE if AOCDtype and AOCD data are ready to export to Asterisk.
Definition: isdn_lib.h:521
#define NULL
Definition: resample.c:96
char context[AST_MAX_CONTEXT]
Incoming call dialplan context identifier.
Definition: chan_misdn.c:553
#define AST_FRAME_DTMF
struct ast_channel * ast
Associated Asterisk channel structure.
Definition: chan_misdn.c:515
static const char * misdn_to_str_plan(enum mISDN_NUMBER_PLAN number_plan)
Definition: chan_misdn.c:1958
struct misdn_party_id to
Where the call is being redirected toward (Sent to the calling party)
Definition: isdn_lib.h:310
int ast_canmatch_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Looks for a valid matching extension.
Definition: pbx.c:4194
static void do_immediate_setup(struct misdn_bchannel *bc, struct chan_list *ch, struct ast_channel *ast)
Definition: chan_misdn.c:8659
int misdn_cap_is_speech(int cap)
Definition: isdn_lib.c:436
static int misdn_tasks_add_variable(int timeout, ast_sched_cb callback, const void *data)
Definition: chan_misdn.c:3609
static int misdn_is_msn_valid(int port, const struct misdn_party_dialing *dialed)
Definition: chan_misdn.c:9904
struct timeval overlap_tv
Overlap timer start time. Timer restarted for every digit received.
Definition: chan_misdn.c:603
#define AST_PRES_RESTRICTED
Definition: callerid.h:325
#define ast_strlen_zero(foo)
Definition: strings.h:52
static int stop_bc_tones(struct chan_list *cl)
Definition: chan_misdn.c:7772
struct ast_party_id id
Caller party ID.
Definition: channel.h:421
int misdn_inband_avail(struct misdn_bchannel *bc)
Definition: isdn_lib.c:444
#define ast_log
Definition: astobj2.c:42
char number[MISDN_MAX_NUMBER_LEN]
Dialed/Called Phone Number (Address)
Definition: isdn_lib.h:266
#define AST_PRES_USER_NUMBER_UNSCREENED
Definition: callerid.h:318
static int misdn_to_ast_ton(enum mISDN_NUMBER_TYPE number_type)
Definition: chan_misdn.c:1874
void ast_channel_rings_set(struct ast_channel *chan, int value)
int misdn_lib_port_block(int port)
Definition: isdn_lib.c:91
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
void ast_channel_generatordata_set(struct ast_channel *chan, void *value)
int need_release_complete
TRUE if RELEASE_COMPLETE needs to be sent to clear a call.
Definition: isdn_lib.h:392
#define ast_poll(a, b, c)
Definition: poll-compat.h:88
void misdn_cfg_get(int port, enum misdn_cfg_elements elem, void *buf, int bufsize)
Definition: misdn_config.c:569
int overlap_dial_task
Overlap dialing timeout Task ID. -1 if not running.
Definition: chan_misdn.c:593
#define AST_CAUSE_NORMAL_CLEARING
Definition: causes.h:105
#define ast_channel_cleanup(c)
Cleanup a channel reference.
Definition: channel.h:2992
#define ao2_ref(o, delta)
Definition: astobj2.h:464
static const char * misdn_to_str_screen(int screening)
Definition: chan_misdn.c:2173
int nt
TRUE if NT side of protocol (TE otherwise)
Definition: isdn_lib.h:364
enum mISDN_NUMBER_TYPE number_type
Type-of-number in ISDN terms for the number.
Definition: isdn_lib.h:285
void misdn_lib_log_ies(struct misdn_bchannel *bc)
Definition: isdn_lib.c:3431
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
#define ast_format_cap_append(cap, format, framing)
Definition: format_cap.h:103
char infos_pending[MISDN_MAX_NUMBER_LEN]
Collected digits to go into info_dad[] while waiting for a SETUP_ACKNOWLEDGE to come in...
Definition: isdn_lib.h:653
struct misdn_party_id caller
Originating/Caller ID information struct.
Definition: isdn_lib.h:343
static struct chan_list * find_chan_by_bc(struct misdn_bchannel *bc)
Definition: chan_misdn.c:8259
char name[MISDN_MAX_NAME_LEN]
Subscriber Name.
Definition: isdn_lib.h:295
int ast_exists_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Determine whether an extension exists.
Definition: pbx.c:4179
#define ast_format_cap_alloc(flags)
Definition: format_cap.h:52
char * bc_state2str(enum bchannel_state state)
Definition: isdn_lib.c:617
int ast_queue_hold(struct ast_channel *chan, const char *musicclass)
Queue a hold frame.
Definition: channel.c:1191
enum misdn_chan_state state
State of the channel.
Definition: chan_misdn.c:386
int far_alerting
TRUE if we must do the ringback tones.
Definition: chan_misdn.c:570
Structure to describe a channel "technology", ie a channel driver See for examples: ...
Definition: channel.h:629
const char * ast_channel_exten(const struct ast_channel *chan)
int ast_queue_frame(struct ast_channel *chan, struct ast_frame *f)
Queue one or more frames to a channel&#39;s frame queue.
Definition: channel.c:1139
#define AST_CAUSE_DESTINATION_OUT_OF_ORDER
Definition: causes.h:114
int port
Logical port the channel call record is HELD on because the B channel is no longer associated...
Definition: chan_misdn.c:362
int misdn_lib_is_ptp(int port)
Definition: isdn_lib.c:128
struct misdn_party_id connected
Connected-Party/Connected-Line ID information struct.
Definition: isdn_lib.h:353
void export_ch(struct ast_channel *chan, struct misdn_bchannel *bc, struct chan_list *ch)
Export parameters to the dialplan environment variables.
Definition: chan_misdn.c:8811
char allowed_bearers[BUFFERSIZE+1]
The "allowed_bearers" string read in from /etc/asterisk/misdn.conf.
Definition: chan_misdn.c:381
int pid
B channel process ID (1-5000)
Definition: isdn_lib.h:402
int originator
Who originally created this channel. ORG_AST or ORG_MISDN.
Definition: chan_misdn.c:407
struct misdn_party_id from
Who is redirecting the call (Sent to the party the call is redirected toward)
Definition: isdn_lib.h:307
static const char * bearer2str(int cap)
Definition: chan_misdn.c:2373
#define LOG_ERROR
Definition: logger.h:285
struct ast_generator * ast_channel_generator(const struct ast_channel *chan)
int ast_pickup_call(struct ast_channel *chan)
Pickup a call.
Definition: pickup.c:200
Format capabilities structure, holds formats + preference order + etc.
Definition: format_cap.c:54
static void misdn_add_number_prefix(int port, enum mISDN_NUMBER_TYPE number_type, char *number, size_t size)
Definition: chan_misdn.c:3424
int plan
Q.931 Type-Of-Number and Numbering-Plan encoded fields.
Definition: channel.h:294
static struct chan_list * find_hold_call_l3(unsigned long l3_id)
Definition: chan_misdn.c:8317
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)
Definition: chan_misdn.c:6210
int errno
struct misdn_party_redirecting redirecting
Redirecting information struct (Where a call diversion or transfer was invoked)
Definition: isdn_lib.h:358
static int misdn_overlap_dial_task(const void *data)
Definition: chan_misdn.c:3628
int port
Logical Layer 1 port associated with this B channel.
Definition: isdn_lib.h:370
int add_in_calls(int port)
Definition: chan_misdn.c:8844
Redirecting Line information. RDNIS (Redirecting Directory Number Information Service) Where a call d...
Definition: channel.h:523
#define LOG_NOTICE
Definition: logger.h:263
struct misdn_party_dialing dialed
Dialed/Called information struct.
Definition: isdn_lib.h:337
ast_mutex_t overlap_tv_lock
overlap_tv access lock.
Definition: chan_misdn.c:598
#define ORG_MISDN
Definition: chan_misdn.c:345
#define ast_channel_unlock(chan)
Definition: channel.h:2946
int addr
B Channel mISDN driver layer ID from mISDN_get_layerid()
Definition: isdn_lib.h:429
Channel call record structure.
Definition: chan_misdn.c:377
unsigned int l3id
From associated B channel: Layer 3 process ID.
Definition: chan_misdn.c:541
int to_changed
TRUE if the redirecting.to information has changed.
Definition: isdn_lib.h:319
enum misdn_hold_state state
Call HOLD state.
Definition: chan_misdn.c:357
static struct chan_list * chan_list_init(int orig)
Definition: chan_misdn.c:7831
int channel
Original B channel number the HELD call was using.
Definition: chan_misdn.c:368
struct ast_party_redirecting * ast_channel_redirecting(struct ast_channel *chan)
int channel
Assigned B channel number B1, B2... 0 if not assigned.
Definition: isdn_lib.h:411
static void hangup_chan(struct chan_list *ch, struct misdn_bchannel *bc)
Definition: chan_misdn.c:8447
void ast_channel_exten_set(struct ast_channel *chan, const char *value)
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name...
static void print_bearer(struct misdn_bchannel *bc)
Definition: chan_misdn.c:3355
static void export_aoc_vars(int originator, struct ast_channel *ast, struct misdn_bchannel *bc)
Definition: chan_misdn.c:3458
int out_cause
Q.931 Cause for disconnection code (sent)
Definition: isdn_lib.h:677
char * tag
User-set "tag".
Definition: channel.h:355
void ast_deactivate_generator(struct ast_channel *chan)
Definition: channel.c:2902
void ast_party_redirecting_free(struct ast_party_redirecting *doomed)
Destroy the redirecting information contents.
Definition: channel.c:2179
enum mISDN_REDIRECTING_REASON reason
Reason a call is being redirected (Q.931 field value)
Definition: isdn_lib.h:313
int need_release
TRUE if RELEASE needs to be sent to clear a call.
Definition: isdn_lib.h:389
int need_more_infos
TRUE if we send SETUP_ACKNOWLEDGE on incoming calls anyway (instead of PROCEEDING).
Definition: isdn_lib.h:465
int dtmf
Last decoded DTMF digit from mISDN driver.
Definition: isdn_lib.h:452
enum bchannel_state bc_state
Current B Channel state.
Definition: isdn_lib.h:547
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
static int start_bc_tones(struct chan_list *cl)
Definition: chan_misdn.c:7764
struct ast_party_id to
Call is redirecting to a new party (Sent to the caller)
Definition: channel.h:531
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
struct ast_format * ast_format_alaw
Built-in cached alaw format.
Definition: format_cache.c:91
struct timeval ast_tv(ast_time_t sec, ast_suseconds_t usec)
Returns a timeval from sec, usec.
Definition: time.h:226
int need_disconnect
TRUE if DISCONNECT needs to be sent to clear a call.
Definition: isdn_lib.h:386
struct ast_channel * ast_channel_bridge_peer(struct ast_channel *chan)
Get the channel&#39;s bridge peer only if the bridge is two-party.
Definition: channel.c:10765
void ast_party_redirecting_init(struct ast_party_redirecting *init)
Initialize the given redirecting structure.
Definition: channel.c:2122
#define AST_CAUSE_USER_BUSY
Definition: causes.h:106
void ast_channel_transfercapability_set(struct ast_channel *chan, unsigned short value)
int ast_setstate(struct ast_channel *chan, enum ast_channel_state)
Change the state of a channel.
Definition: channel.c:7486
enum mISDN_NOTIFY_CODE notify_description_code
Notification indicator ie description code.
Definition: isdn_lib.h:606
char * ast_transfercapability2str(int transfercapability) attribute_const
Gives the string form of a given transfer capability.
Definition: channel.c:678
Data structure associated with a single frame of data.
int progress_indicator
Progress Indicator IE progress description field. Used to determine if there is an inband audio messa...
Definition: isdn_lib.h:492
int misdn_lib_send_event(struct misdn_bchannel *bc, enum event_e event)
Definition: isdn_lib.c:3523
#define ORG_AST
Definition: chan_misdn.c:343
char * bframe
B channel speech sample data buffer.
Definition: isdn_lib.h:432
void ast_channel_queue_redirecting_update(struct ast_channel *chan, const struct ast_party_redirecting *redirecting, const struct ast_set_party_redirecting *update)
Queue a redirecting update frame on a channel.
Definition: channel.c:10392
int cause
Q.931 Cause for disconnection code (received)
Definition: isdn_lib.h:671
char info_dad[MISDN_MAX_NUMBER_LEN]
Current overlap dialing digits to/from INFORMATION messages.
Definition: isdn_lib.h:650
static void update_name(struct ast_channel *tmp, int port, int c)
Definition: chan_misdn.c:8150
struct misdn_bchannel * bc
Associated B channel structure.
Definition: chan_misdn.c:520
int screening
Number screening code 0=Unscreened, 1=Passed Screen, 2=Failed Screen, 3=Network Number.
Definition: isdn_lib.h:282
#define chan_list_unref(obj, debug)
Definition: chan_misdn.c:372
static int misdn_to_ast_screen(int screening)
Definition: chan_misdn.c:2210
void(* cb_log)(int level, int port, char *tmpl,...)
Definition: isdn_lib.c:32
struct FacParm fac_in
Inbound FACILITY message function type and contents.
Definition: isdn_lib.h:507
int overlap_dial
Enables overlap dialing for the set amount of seconds. (0 = Disabled)
Definition: chan_misdn.c:588
enum mISDN_NUMBER_PLAN number_plan
Type-of-number numbering plan.
Definition: isdn_lib.h:288
void ast_party_redirecting_copy(struct ast_party_redirecting *dest, const struct ast_party_redirecting *src)
Copy the source redirecting information to the destination redirecting.
Definition: channel.c:2135
int noautorespond_on_setup
TRUE of we are not to respond immediately to a SETUP message. Check the dialplan first.
Definition: chan_misdn.c:413
int l3_id
Layer 3 process ID.
Definition: isdn_lib.h:399
static void misdn_facility_ie_handler(enum event_e event, struct misdn_bchannel *bc, struct chan_list *ch)
Definition: chan_misdn.c:9095
#define ast_mutex_unlock(a)
Definition: lock.h:188
Configuration relating to call pickup.
int nttimeout
TRUE if NT should disconnect an overlap dialing call when a timeout occurs.
Definition: chan_misdn.c:576
struct ast_party_number number
Subscriber phone number.
Definition: channel.h:343

◆ chan_list_destructor()

static void chan_list_destructor ( void *  obj)
static

Definition at line 7792 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(), NULL, chan_list::overlap_dial, chan_list::overlap_dial_task, chan_list::overlap_tv_lock, and chan_list::pipe.

Referenced by chan_list_init().

7793 {
7794  struct chan_list *ch = obj;
7795 
7796 #if defined(AST_MISDN_ENHANCEMENTS)
7797  if (ch->peer) {
7798  ao2_ref(ch->peer, -1);
7799  ch->peer = NULL;
7800  }
7801 #endif /* AST_MISDN_ENHANCEMENTS */
7802 
7803  if (ch->dsp) {
7804  ast_dsp_free(ch->dsp);
7805  ch->dsp = NULL;
7806  }
7807 
7808  /* releasing jitterbuffer */
7809  if (ch->jb) {
7810  misdn_jb_destroy(ch->jb);
7811  ch->jb = NULL;
7812  }
7813 
7814  if (ch->overlap_dial) {
7815  if (ch->overlap_dial_task != -1) {
7817  ch->overlap_dial_task = -1;
7818  }
7820  }
7821 
7822  if (-1 < ch->pipe[0]) {
7823  close(ch->pipe[0]);
7824  }
7825  if (-1 < ch->pipe[1]) {
7826  close(ch->pipe[1]);
7827  }
7828 }
struct ast_dsp * dsp
Allocated DSP controller.
Definition: chan_misdn.c:510
void ast_dsp_free(struct ast_dsp *dsp)
Definition: dsp.c:1770
int pipe[2]
Pipe file descriptor handles array. Read from pipe[0], write to pipe[1].
Definition: chan_misdn.c:444
struct misdn_jb * jb
Allocated jitterbuffer controller.
Definition: chan_misdn.c:503
void misdn_jb_destroy(struct misdn_jb *jb)
frees the data and destroys the given jitterbuffer struct
Definition: chan_misdn.c:12639
#define NULL
Definition: resample.c:96
static void misdn_tasks_remove(int task_id)
Definition: chan_misdn.c:3614
int overlap_dial_task
Overlap dialing timeout Task ID. -1 if not running.
Definition: chan_misdn.c:593
#define ao2_ref(o, delta)
Definition: astobj2.h:464
ast_mutex_t overlap_tv_lock
overlap_tv access lock.
Definition: chan_misdn.c:598
Channel call record structure.
Definition: chan_misdn.c:377
#define ast_mutex_destroy(a)
Definition: lock.h:186
int overlap_dial
Enables overlap dialing for the set amount of seconds. (0 = Disabled)
Definition: chan_misdn.c:588

◆ chan_list_init()

static struct chan_list* chan_list_init ( int  orig)
static

Returns a reference to the new chan_list.

Definition at line 7831 of file chan_misdn.c.

References ao2_alloc, chan_list_destructor(), chan_misdn_log(), chan_list::need_busy, chan_list::need_hangup, chan_list::need_queue_hangup, NULL, chan_list::originator, chan_list::overlap_dial_task, and chan_list::pipe.

Referenced by cb_events(), and misdn_request().

7832 {
7833  struct chan_list *cl;
7834 
7835  cl = ao2_alloc(sizeof(*cl), chan_list_destructor);
7836  if (!cl) {
7837  chan_misdn_log(-1, 0, "misdn_request: malloc failed!");
7838  return NULL;
7839  }
7840 
7841  cl->originator = orig;
7842  cl->need_queue_hangup = 1;
7843  cl->need_hangup = 1;
7844  cl->need_busy = 1;
7845  cl->overlap_dial_task = -1;
7846 #if defined(AST_MISDN_ENHANCEMENTS)
7847  cl->record_id = -1;
7848 #endif /* defined(AST_MISDN_ENHANCEMENTS) */
7849  cl->pipe[0] = -1;
7850  cl->pipe[1] = -1;
7851 
7852  return cl;
7853 }
int need_busy
TRUE if we could send an AST_CONTROL_BUSY if needed.
Definition: chan_misdn.c:402
static void chan_misdn_log(int level, int port, char *tmpl,...)
Definition: chan_misdn.c:12768
int need_hangup
TRUE if a channel can be hung up by calling asterisk directly when done.
Definition: chan_misdn.c:397
int need_queue_hangup
TRUE if a hangup needs to be queued.
Definition: chan_misdn.c:392
int pipe[2]
Pipe file descriptor handles array. Read from pipe[0], write to pipe[1].
Definition: chan_misdn.c:444
#define NULL
Definition: resample.c:96
static void chan_list_destructor(void *obj)
Definition: chan_misdn.c:7792
int overlap_dial_task
Overlap dialing timeout Task ID. -1 if not running.
Definition: chan_misdn.c:593
int originator
Who originally created this channel. ORG_AST or ORG_MISDN.
Definition: chan_misdn.c:407
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:411
Channel call record structure.
Definition: chan_misdn.c:377

◆ chan_misdn_jb_empty()

int chan_misdn_jb_empty ( struct misdn_bchannel bc,
char *  buf,
int  len 
)

Definition at line 12574 of file chan_misdn.c.

References chan_list_unref, find_chan_by_bc(), chan_list::jb, and misdn_jb_empty().

Referenced by load_module().

12575 {
12576  struct chan_list *ch;
12577  int res;
12578 
12579  ch = find_chan_by_bc(bc);
12580  if (!ch) {
12581  return 0;
12582  }
12583 
12584  if (ch->jb) {
12585  res = misdn_jb_empty(ch->jb, buf, len);
12586  } else {
12587  res = 0;
12588  }
12589  chan_list_unref(ch, "Done emptying jb");
12590 
12591  return res;
12592 }
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
struct misdn_jb * jb
Allocated jitterbuffer controller.
Definition: chan_misdn.c:503
static struct chan_list * find_chan_by_bc(struct misdn_bchannel *bc)
Definition: chan_misdn.c:8259
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
Channel call record structure.
Definition: chan_misdn.c:377
#define chan_list_unref(obj, debug)
Definition: chan_misdn.c:372
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...
Definition: chan_misdn.c:12716

◆ chan_misdn_log()

static void chan_misdn_log ( int  level,
int  port,
char *  tmpl,
  ... 
)
static

Definition at line 12768 of file chan_misdn.c.

References ast_log, AST_MODFLAG_LOAD_ORDER, AST_MODPRI_CHANNEL_DRIVER, AST_MODULE_INFO(), AST_MODULE_SUPPORT_DEPRECATED, ast_strlen_zero, ast_verbose(), ASTERISK_GPL_KEY, errno, global_tracefile, load_module(), LOG_WARNING, NULL, reload(), tmp(), and unload_module().

Referenced by bearer2str(), cb_events(), chan_list_init(), cl_queue_chan(), config_jitterbuffer(), debug_numtype(), dialtone_indicate(), do_immediate_setup(), export_ch(), find_chan_by_bc(), find_hold_call(), get_chan_by_ast_name(), load_module(), misdn_answer(), misdn_attempt_transfer(), misdn_call(), misdn_check_l2l1(), misdn_digit_end(), misdn_facility_exec(), misdn_facility_ie_handler(), misdn_fixup(), misdn_hangup(), misdn_indication(), misdn_jb_empty(), misdn_jb_fill(), misdn_jb_init(), misdn_l1_task(), misdn_new(), misdn_overlap_dial_task(), misdn_read(), misdn_request(), misdn_set_opt_exec(), misdn_tasks_destroy(), misdn_tasks_init(), misdn_tasks_thread_func(), misdn_write(), print_bearer(), print_facility(), process_ast_dsp(), read_config(), release_chan(), send_cause2ast(), start_pbx(), stop_indicate(), update_config(), update_name(), and wait_for_digits().

12769 {
12770  va_list ap;
12771  char buf[1024];
12772  char port_buf[8];
12773 
12774  if (!(0 <= port && port <= max_ports)) {
12775  ast_log(LOG_WARNING, "chan_misdn_log called with out-of-range port number! (%d)\n", port);
12776  port = 0;
12777  level = -1;
12778  } else if (!(level == -1
12779  || (misdn_debug_only[port]
12780  ? (level == 1 && misdn_debug[port]) || level == misdn_debug[port]
12781  : level <= misdn_debug[port])
12782  || (level <= misdn_debug[0] && !ast_strlen_zero(global_tracefile)))) {
12783  /*
12784  * We are not going to print anything so lets not
12785  * go to all the work of generating a string.
12786  */
12787  return;
12788  }
12789 
12790  snprintf(port_buf, sizeof(port_buf), "P[%2d] ", port);
12791  va_start(ap, tmpl);
12792  vsnprintf(buf, sizeof(buf), tmpl, ap);
12793  va_end(ap);
12794 
12795  if (level == -1) {
12796  ast_log(LOG_WARNING, "%s", buf);
12797  } else if (misdn_debug_only[port]
12798  ? (level == 1 && misdn_debug[port]) || level == misdn_debug[port]
12799  : level <= misdn_debug[port]) {
12800  ast_verbose("%s%s", port_buf, buf);
12801  }
12802 
12803  if (level <= misdn_debug[0] && !ast_strlen_zero(global_tracefile)) {
12804  char ctimebuf[30];
12805  time_t tm;
12806  char *tmp;
12807  char *p;
12808  FILE *fp;
12809 
12810  fp = fopen(global_tracefile, "a+");
12811  if (!fp) {
12812  ast_verbose("Error opening Tracefile: [ %s ] %s\n", global_tracefile, strerror(errno));
12813  return;
12814  }
12815 
12816  tm = time(NULL);
12817  tmp = ctime_r(&tm, ctimebuf);
12818  p = strchr(tmp, '\n');
12819  if (p) {
12820  *p = ':';
12821  }
12822  fputs(tmp, fp);
12823  fputs(" ", fp);
12824  fputs(port_buf, fp);
12825  fputs(" ", fp);
12826  fputs(buf, fp);
12827 
12828  fclose(fp);
12829  }
12830 }
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define LOG_WARNING
Definition: logger.h:274
static int tmp()
Definition: bt_open.c:389
void ast_verbose(const char *fmt,...)
Definition: extconf.c:2207
static int * misdn_debug_only
Definition: chan_misdn.c:695
#define NULL
Definition: resample.c:96
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_log
Definition: astobj2.c:42
static int max_ports
Definition: chan_misdn.c:696
static char global_tracefile[BUFFERSIZE+1]
Definition: chan_misdn.c:127
static int * misdn_debug
Definition: chan_misdn.c:694
int errno

◆ cl_dequeue_chan()

static int cl_dequeue_chan ( struct chan_list chan)
static

Definition at line 8398 of file chan_misdn.c.

References ast_mutex_lock, ast_mutex_unlock, chan_list_unref, and chan_list::next.

Referenced by release_chan(), and release_chan_early().

8399 {
8400  int found_it;
8401  struct chan_list *help;
8402 
8404  if (!cl_te) {
8405  /* List is empty. */
8407  return 0;
8408  }
8409 
8410  if (cl_te == chan) {
8411  /* What we want is the head of the list. */
8412  cl_te = cl_te->next;
8414  chan_list_unref(chan, "Removed chan_list from list head");
8415  return 1;
8416  }
8417 
8418  found_it = 0;
8419  for (help = cl_te; help->next; help = help->next) {
8420  if (help->next == chan) {
8421  /* Found it in the list. */
8422  help->next = help->next->next;
8423  found_it = 1;
8424  break;
8425  }
8426  }
8427 
8429  if (found_it) {
8430  chan_list_unref(chan, "Removed chan_list from list");
8431  }
8432  return found_it;
8433 }
struct chan_list * next
Next channel call record in the list.
Definition: chan_misdn.c:608
#define ast_mutex_lock(a)
Definition: lock.h:187
static struct chan_list * cl_te
Global channel call record list head.
Definition: chan_misdn.c:704
Channel call record structure.
Definition: chan_misdn.c:377
#define chan_list_unref(obj, debug)
Definition: chan_misdn.c:372
static ast_mutex_t cl_te_lock
Definition: chan_misdn.c:705
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ cl_queue_chan()

static void cl_queue_chan ( struct chan_list chan)
static

Definition at line 8377 of file chan_misdn.c.

References ast_mutex_lock, ast_mutex_unlock, chan_list::bc, chan_list_ref, chan_misdn_log(), chan_list::next, NULL, and misdn_bchannel::port.

Referenced by cb_events(), and misdn_request().

8378 {
8379  chan_misdn_log(4, chan->bc ? chan->bc->port : 0, "* Queuing chan %p\n", chan);
8380 
8381  chan_list_ref(chan, "Adding chan_list to list");
8383  chan->next = NULL;
8384  if (!cl_te) {
8385  /* List is empty, make head of list. */
8386  cl_te = chan;
8387  } else {
8388  struct chan_list *help;
8389 
8390  /* Put at end of list. */
8391  for (help = cl_te; help->next; help = help->next) {
8392  }
8393  help->next = chan;
8394  }
8396 }
static void chan_misdn_log(int level, int port, char *tmpl,...)
Definition: chan_misdn.c:12768
struct chan_list * next
Next channel call record in the list.
Definition: chan_misdn.c:608
#define ast_mutex_lock(a)
Definition: lock.h:187
#define NULL
Definition: resample.c:96
static struct chan_list * cl_te
Global channel call record list head.
Definition: chan_misdn.c:704
int port
Logical Layer 1 port associated with this B channel.
Definition: isdn_lib.h:370
Channel call record structure.
Definition: chan_misdn.c:377
#define chan_list_ref(obj, debug)
Definition: chan_misdn.c:371
struct misdn_bchannel * bc
Associated B channel structure.
Definition: chan_misdn.c:520
static ast_mutex_t cl_te_lock
Definition: chan_misdn.c:705
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ complete_ch()

static char * complete_ch ( struct ast_cli_args a)
static

Definition at line 5654 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().

5655 {
5656  return ast_complete_channels(a->line, a->word, a->pos, a->n, 3);
5657 }
const char * line
Definition: cli.h:162
const int n
Definition: cli.h:165
const char * word
Definition: cli.h:163
const int pos
Definition: cli.h:164
char * ast_complete_channels(const char *line, const char *word, int pos, int state, int rpos)
Command completion for the list of active channels.
Definition: main/cli.c:1830

◆ complete_debug_port()

static char * complete_debug_port ( struct ast_cli_args a)
static

Definition at line 5659 of file chan_misdn.c.

References ast_strdup, ast_cli_args::n, NULL, ast_cli_args::pos, and ast_cli_args::word.

Referenced by handle_cli_misdn_set_debug().

5660 {
5661  if (a->n) {
5662  return NULL;
5663  }
5664 
5665  switch (a->pos) {
5666  case 4:
5667  if (a->word[0] == 'p') {
5668  return ast_strdup("port");
5669  } else if (a->word[0] == 'o') {
5670  return ast_strdup("only");
5671  }
5672  break;
5673  case 6:
5674  if (a->word[0] == 'o') {
5675  return ast_strdup("only");
5676  }
5677  break;
5678  }
5679  return NULL;
5680 }
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
#define NULL
Definition: resample.c:96
const int n
Definition: cli.h:165
const char * word
Definition: cli.h:163
const int pos
Definition: cli.h:164

◆ complete_show_config()

static char * complete_show_config ( struct ast_cli_args a)
static

Definition at line 5682 of file chan_misdn.c.

References ast_strdup, BUFFERSIZE, ast_cli_args::line, MISDN_CFG_FIRST, misdn_cfg_get_name(), misdn_cfg_get_next_port(), MISDN_CFG_LAST, MISDN_GEN_FIRST, MISDN_GEN_LAST, ast_cli_args::n, NULL, ast_cli_args::pos, and ast_cli_args::word.

Referenced by handle_cli_misdn_show_config().

5683 {
5684  char buffer[BUFFERSIZE];
5685  enum misdn_cfg_elements elem;
5686  int wordlen = strlen(a->word);
5687  int which = 0;
5688  int port = 0;
5689 
5690  switch (a->pos) {
5691  case 3:
5692  if ((!strncmp(a->word, "description", wordlen)) && (++which > a->n)) {
5693  return ast_strdup("description");
5694  }
5695  if ((!strncmp(a->word, "descriptions", wordlen)) && (++which > a->n)) {
5696  return ast_strdup("descriptions");
5697  }
5698  if ((!strncmp(a->word, "0", wordlen)) && (++which > a->n)) {
5699  return ast_strdup("0");
5700  }
5701  while ((port = misdn_cfg_get_next_port(port)) != -1) {
5702  snprintf(buffer, sizeof(buffer), "%d", port);
5703  if ((!strncmp(a->word, buffer, wordlen)) && (++which > a->n)) {
5704  return ast_strdup(buffer);
5705  }
5706  }
5707  break;
5708  case 4:
5709  if (strstr(a->line, "description ")) {
5710  for (elem = MISDN_CFG_FIRST + 1; elem < MISDN_GEN_LAST; ++elem) {
5711  if ((elem == MISDN_CFG_LAST) || (elem == MISDN_GEN_FIRST)) {
5712  continue;
5713  }
5714  misdn_cfg_get_name(elem, buffer, sizeof(buffer));
5715  if (!wordlen || !strncmp(a->word, buffer, wordlen)) {
5716  if (++which > a->n) {
5717  return ast_strdup(buffer);
5718  }
5719  }
5720  }
5721  } else if (strstr(a->line, "descriptions ")) {
5722  if ((!wordlen || !strncmp(a->word, "general", wordlen)) && (++which > a->n)) {
5723  return ast_strdup("general");
5724  }
5725  if ((!wordlen || !strncmp(a->word, "ports", wordlen)) && (++which > a->n)) {
5726  return ast_strdup("ports");
5727  }
5728  }
5729  break;
5730  }
5731  return NULL;
5732 }
int misdn_cfg_get_next_port(int port)
Definition: misdn_config.c:929
misdn_cfg_elements
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
#define NULL
Definition: resample.c:96
void misdn_cfg_get_name(enum misdn_cfg_elements elem, void *buf, int bufsize)
Definition: misdn_config.c:655
const char * line
Definition: cli.h:162
#define BUFFERSIZE
const int n
Definition: cli.h:165
const char * word
Definition: cli.h:163
const int pos
Definition: cli.h:164

◆ config_jitterbuffer()

static void config_jitterbuffer ( struct chan_list ch)
static

Definition at line 5817 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, NULL, and misdn_bchannel::port.

Referenced by misdn_set_opt_exec(), and read_config().

5818 {
5819  struct misdn_bchannel *bc = ch->bc;
5820  int len = ch->jb_len;
5821  int threshold = ch->jb_upper_threshold;
5822 
5823  chan_misdn_log(5, bc->port, "config_jb: Called\n");
5824 
5825  if (!len) {
5826  chan_misdn_log(1, bc->port, "config_jb: Deactivating Jitterbuffer\n");
5827  bc->nojitter = 1;
5828  } else {
5829  if (len <= 100 || len > 8000) {
5830  chan_misdn_log(0, bc->port, "config_jb: Jitterbuffer out of Bounds, setting to 1000\n");
5831  len = 1000;
5832  }
5833 
5834  if (threshold > len) {
5835  chan_misdn_log(0, bc->port, "config_jb: Jitterbuffer Threshold > Jitterbuffer setting to Jitterbuffer -1\n");
5836  }
5837 
5838  if (ch->jb) {
5839  cb_log(0, bc->port, "config_jb: We've got a Jitterbuffer Already on this port.\n");
5840  misdn_jb_destroy(ch->jb);
5841  ch->jb = NULL;
5842  }
5843 
5844  ch->jb = misdn_jb_init(len, threshold);
5845 
5846  if (!ch->jb) {
5847  bc->nojitter = 1;
5848  }
5849  }
5850 }
static void chan_misdn_log(int level, int port, char *tmpl,...)
Definition: chan_misdn.c:12768
int jb_len
Jitterbuffer length.
Definition: chan_misdn.c:490
#define bc
struct misdn_jb * jb
Allocated jitterbuffer controller.
Definition: chan_misdn.c:503
void misdn_jb_destroy(struct misdn_jb *jb)
frees the data and destroys the given jitterbuffer struct
Definition: chan_misdn.c:12639
int jb_upper_threshold
Jitterbuffer upper threshold.
Definition: chan_misdn.c:496
B channel control structure.
Definition: isdn_lib.h:324
#define NULL
Definition: resample.c:96
threshold
Definition: dsp.h:71
int nojitter
TRUE if we will not use the jitter buffer system.
Definition: isdn_lib.h:477
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
int port
Logical Layer 1 port associated with this B channel.
Definition: isdn_lib.h:370
struct misdn_bchannel * bc
Associated B channel structure.
Definition: chan_misdn.c:520
struct misdn_jb * misdn_jb_init(int size, int upper_threshold)
allocates the jb-structure and initialize the elements
Definition: chan_misdn.c:12602
void(* cb_log)(int level, int port, char *tmpl,...)
Definition: isdn_lib.c:32

◆ debug_numtype()

void debug_numtype ( int  port,
int  numtype,
char *  type 
)

Definition at line 5853 of file chan_misdn.c.

References ast_copy_string(), chan_misdn_log(), MISDN_CFG_ECHOCANCEL, misdn_cfg_get(), NUMTYPE_ABBREVIATED, NUMTYPE_INTERNATIONAL, NUMTYPE_NATIONAL, NUMTYPE_NETWORK_SPECIFIC, NUMTYPE_SUBSCRIBER, NUMTYPE_UNKNOWN, and misdn_bchannel::port.

Referenced by misdn_call(), misdn_get_connected_line(), and read_config().

5854 {
5855  switch (numtype) {
5856  case NUMTYPE_UNKNOWN:
5857  chan_misdn_log(2, port, " --> %s: Unknown\n", type);
5858  break;
5859  case NUMTYPE_INTERNATIONAL:
5860  chan_misdn_log(2, port, " --> %s: International\n", type);
5861  break;
5862  case NUMTYPE_NATIONAL:
5863  chan_misdn_log(2, port, " --> %s: National\n", type);
5864  break;
5866  chan_misdn_log(2, port, " --> %s: Network Specific\n", type);
5867  break;
5868  case NUMTYPE_SUBSCRIBER:
5869  chan_misdn_log(2, port, " --> %s: Subscriber\n", type);
5870  break;
5871  case NUMTYPE_ABBREVIATED:
5872  chan_misdn_log(2, port, " --> %s: Abbreviated\n", type);
5873  break;
5874  /* Maybe we should cut off the prefix if present ? */
5875  default:
5876  chan_misdn_log(0, port, " --> !!!! Wrong dialplan setting, please see the misdn.conf sample file\n ");
5877  break;
5878  }
5879 }
static void chan_misdn_log(int level, int port, char *tmpl,...)
Definition: chan_misdn.c:12768
static const char type[]
Definition: chan_ooh323.c:109
int port
Logical Layer 1 port associated with this B channel.
Definition: isdn_lib.h:370

◆ dialtone_indicate()

static int dialtone_indicate ( struct chan_list cl)
static

AST INDICATIONS END

Definition at line 7707 of file chan_misdn.c.

References chan_list::ast, ast_channel_zone(), 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, and chan_list::ts.

Referenced by wait_for_digits().

7708 {
7709  struct ast_channel *ast = cl->ast;
7710  int nd = 0;
7711 
7712  if (!ast) {
7713  chan_misdn_log(0, cl->bc->port, "No Ast in dialtone_indicate\n");
7714  return -1;
7715  }
7716 
7717  misdn_cfg_get(cl->bc->port, MISDN_CFG_NODIALTONE, &nd, sizeof(nd));
7718 
7719  if (nd) {
7720  chan_misdn_log(1, cl->bc->port, "Not sending Dialtone, because config wants it\n");
7721  return 0;
7722  }
7723 
7724  chan_misdn_log(3, cl->bc->port, " --> Dial\n");
7725 
7726  cl->ts = ast_get_indication_tone(ast_channel_zone(ast), "dial");
7727 
7728  if (cl->ts) {
7729  cl->notxtone = 0;
7730  cl->norxtone = 0;
7731  /* This prods us in misdn_write */
7732  ast_playtones_start(ast, 0, cl->ts->data, 0);
7733  }
7734 
7735  return 0;
7736 }
static void chan_misdn_log(int level, int port, char *tmpl,...)
Definition: chan_misdn.c:12768
Main Channel structure associated with a channel.
struct ast_tone_zone * ast_channel_zone(const struct ast_channel *chan)
int norxtone
Definition: chan_misdn.c:415
struct ast_channel * ast
Associated Asterisk channel structure.
Definition: chan_misdn.c:515
int notxtone
TRUE if we are not to generate tones (Playtones)
Definition: chan_misdn.c:420
void misdn_cfg_get(int port, enum misdn_cfg_elements elem, void *buf, int bufsize)
Definition: misdn_config.c:569
struct ast_tone_zone_sound * ast_get_indication_tone(const struct ast_tone_zone *zone, const char *indication)
Locate a tone zone sound.
Definition: indications.c:455
int port
Logical Layer 1 port associated with this B channel.
Definition: isdn_lib.h:370
struct ast_tone_zone_sound * ts
Tone zone sound used for dialtone generation.
Definition: chan_misdn.c:582
int ast_playtones_start(struct ast_channel *chan, int vol, const char *tonelist, int interruptible)
Start playing a list of tones on a channel.
Definition: indications.c:302
const char * data
Description of a tone.
Definition: indications.h:52
struct misdn_bchannel * bc
Associated B channel structure.
Definition: chan_misdn.c:520

◆ do_immediate_setup()

static void do_immediate_setup ( struct misdn_bchannel bc,
struct chan_list ch,
struct ast_channel ast 
)
static

Definition at line 8659 of file chan_misdn.c.

References chan_list::ast, ast_canmatch_extension(), AST_CAUSE_UNALLOCATED, ast_channel_caller(), ast_channel_context(), ast_channel_exten(), ast_channel_exten_set(), AST_FRAME_DTMF, ast_queue_frame(), ast_strdupa, ast_strlen_zero, ast_tv(), misdn_bchannel::caller, chan_misdn_log(), ast_frame::data, ast_frame::datalen, ast_frame::delivery, EVENT_DISCONNECT, EVENT_PROCEEDING, EVENT_RELEASE_COMPLETE, EVENT_SETUP_ACKNOWLEDGE, ast_frame::frametype, hangup_chan(), hanguptone_indicate(), ast_frame_subclass::integer, ast_frame::mallocd, MISDN_ASTERISK_TECH_PVT, MISDN_DIALING, MISDN_INCOMING_SETUP, misdn_lib_is_ptp(), misdn_lib_send_event(), name, chan_list::noautorespond_on_setup, misdn_bchannel::nt, NULL, misdn_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, and ast_frame::subclass.

Referenced by cb_events().

8660 {
8661  char *predial;
8662  struct ast_frame fr;
8663 
8664  predial = ast_strdupa(ast_channel_exten(ast));
8665 
8666  ch->state = MISDN_DIALING;
8667 
8668  if (!ch->noautorespond_on_setup) {
8669  if (bc->nt) {
8671  } else {
8672  if (misdn_lib_is_ptp(bc->port)) {
8674  } else {
8676  }
8677  }
8678  } else {
8680  }
8681 
8682  chan_misdn_log(1, bc->port,
8683  "* Starting Ast context:%s dialed:%s caller:\"%s\" <%s> with 's' extension\n",
8684  ast_channel_context(ast),
8685  ast_channel_exten(ast),
8686  (ast_channel_caller(ast)->id.name.valid && ast_channel_caller(ast)->id.name.str)
8687  ? ast_channel_caller(ast)->id.name.str : "",
8688  (ast_channel_caller(ast)->id.number.valid && ast_channel_caller(ast)->id.number.str)
8689  ? ast_channel_caller(ast)->id.number.str : "");
8690 
8691  ast_channel_exten_set(ast, "s");
8692 
8693  if (!ast_canmatch_extension(ast, ast_channel_context(ast), ast_channel_exten(ast), 1, bc->caller.number) || pbx_start_chan(ch) < 0) {
8694  ast = NULL;
8696  hangup_chan(ch, bc);
8697  hanguptone_indicate(ch);
8698 
8700  }
8701 
8702 
8703  while (!ast_strlen_zero(predial)) {
8704  fr.frametype = AST_FRAME_DTMF;
8705  fr.subclass.integer = *predial;
8706  fr.src = NULL;
8707  fr.data.ptr = NULL;
8708  fr.datalen = 0;
8709  fr.samples = 0;
8710  fr.mallocd = 0;
8711  fr.offset = 0;
8712  fr.delivery = ast_tv(0,0);
8713 
8714  if (ch->ast && MISDN_ASTERISK_TECH_PVT(ch->ast)) {
8715  ast_queue_frame(ch->ast, &fr);
8716  }
8717  predial++;
8718  }
8719 }
struct ast_party_caller * ast_channel_caller(struct ast_channel *chan)
static void chan_misdn_log(int level, int port, char *tmpl,...)
Definition: chan_misdn.c:12768
static void hanguptone_indicate(struct chan_list *cl)
Definition: chan_misdn.c:7738
char number[MISDN_MAX_NUMBER_LEN]
Phone number (Address)
Definition: isdn_lib.h:298
#define AST_CAUSE_UNALLOCATED
Definition: causes.h:97
static int pbx_start_chan(struct chan_list *ch)
Definition: chan_misdn.c:8438
#define MISDN_ASTERISK_TECH_PVT(ast)
Definition: chan_misdn.c:683
#define NULL
Definition: resample.c:96
#define AST_FRAME_DTMF
struct ast_channel * ast
Associated Asterisk channel structure.
Definition: chan_misdn.c:515
int ast_canmatch_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Looks for a valid matching extension.
Definition: pbx.c:4194
#define ast_strlen_zero(foo)
Definition: strings.h:52
Number structure.
Definition: app_followme.c:154
int nt
TRUE if NT side of protocol (TE otherwise)
Definition: isdn_lib.h:364
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
struct misdn_party_id caller
Originating/Caller ID information struct.
Definition: isdn_lib.h:343
enum misdn_chan_state state
State of the channel.
Definition: chan_misdn.c:386
const char * ast_channel_exten(const struct ast_channel *chan)
int ast_queue_frame(struct ast_channel *chan, struct ast_frame *f)
Queue one or more frames to a channel&#39;s frame queue.
Definition: channel.c:1139
int misdn_lib_is_ptp(int port)
Definition: isdn_lib.c:128
int port
Logical Layer 1 port associated with this B channel.
Definition: isdn_lib.h:370
static const char name[]
Definition: cdr_mysql.c:74
static void hangup_chan(struct chan_list *ch, struct misdn_bchannel *bc)
Definition: chan_misdn.c:8447
void ast_channel_exten_set(struct ast_channel *chan, const char *value)
int out_cause
Q.931 Cause for disconnection code (sent)
Definition: isdn_lib.h:677
struct timeval ast_tv(ast_time_t sec, ast_suseconds_t usec)
Returns a timeval from sec, usec.
Definition: time.h:226
Data structure associated with a single frame of data.
int misdn_lib_send_event(struct misdn_bchannel *bc, enum event_e event)
Definition: isdn_lib.c:3523
const char * ast_channel_context(const struct ast_channel *chan)
int noautorespond_on_setup
TRUE of we are not to respond immediately to a SETUP message. Check the dialplan first.
Definition: chan_misdn.c:413

◆ export_aoc_vars()

static void export_aoc_vars ( int  originator,
struct ast_channel ast,
struct misdn_bchannel bc 
)
static

Definition at line 3458 of file chan_misdn.c.

References misdn_bchannel::AOCD, misdn_bchannel::AOCD_need_export, misdn_bchannel::AOCDtype, ast_channel_bridge_peer(), ast_channel_cleanup, ast_channel_ref, buf, misdn_bchannel::chargingUnit, misdn_bchannel::currency, NULL, ORG_AST, pbx_builtin_setvar_helper(), and RAII_VAR.

Referenced by cb_events(), and misdn_facility_ie_handler().

3459 {
3460  RAII_VAR(struct ast_channel *, chan, NULL, ast_channel_cleanup);
3461  char buf[128];
3462 
3463  if (!bc->AOCD_need_export || !ast) {
3464  return;
3465  }
3466 
3467  if (originator == ORG_AST) {
3468  chan = ast_channel_bridge_peer(ast);
3469  if (!chan) {
3470  return;
3471  }
3472  } else {
3473  chan = ast_channel_ref(ast);
3474  }
3475 
3476  switch (bc->AOCDtype) {
3477  case Fac_AOCDCurrency:
3478  pbx_builtin_setvar_helper(chan, "AOCD_Type", "currency");
3479  if (bc->AOCD.currency.chargeNotAvailable) {
3480  pbx_builtin_setvar_helper(chan, "AOCD_ChargeAvailable", "no");
3481  } else {
3482  pbx_builtin_setvar_helper(chan, "AOCD_ChargeAvailable", "yes");
3483  if (bc->AOCD.currency.freeOfCharge) {
3484  pbx_builtin_setvar_helper(chan, "AOCD_FreeOfCharge", "yes");
3485  } else {
3486  pbx_builtin_setvar_helper(chan, "AOCD_FreeOfCharge", "no");
3487  if (snprintf(buf, sizeof(buf), "%d %s", bc->AOCD.currency.currencyAmount * bc->AOCD.currency.multiplier, bc->AOCD.currency.currency) < sizeof(buf)) {
3488  pbx_builtin_setvar_helper(chan, "AOCD_Amount", buf);
3489  if (bc->AOCD.currency.billingId >= 0 && snprintf(buf, sizeof(buf), "%d", bc->AOCD.currency.billingId) < sizeof(buf)) {
3490  pbx_builtin_setvar_helper(chan, "AOCD_BillingId", buf);
3491  }
3492  }
3493  }
3494  }
3495  break;
3496  case Fac_AOCDChargingUnit:
3497  pbx_builtin_setvar_helper(chan, "AOCD_Type", "charging_unit");
3498  if (bc->AOCD.chargingUnit.chargeNotAvailable) {
3499  pbx_builtin_setvar_helper(chan, "AOCD_ChargeAvailable", "no");
3500  } else {
3501  pbx_builtin_setvar_helper(chan, "AOCD_ChargeAvailable", "yes");
3502  if (bc->AOCD.chargingUnit.freeOfCharge) {
3503  pbx_builtin_setvar_helper(chan, "AOCD_FreeOfCharge", "yes");
3504  } else {
3505  pbx_builtin_setvar_helper(chan, "AOCD_FreeOfCharge", "no");
3506  if (snprintf(buf, sizeof(buf), "%d", bc->AOCD.chargingUnit.recordedUnits) < sizeof(buf)) {
3507  pbx_builtin_setvar_helper(chan, "AOCD_RecordedUnits", buf);
3508  if (bc->AOCD.chargingUnit.billingId >= 0 && snprintf(buf, sizeof(buf), "%d", bc->AOCD.chargingUnit.billingId) < sizeof(buf)) {
3509  pbx_builtin_setvar_helper(chan, "AOCD_BillingId", buf);
3510  }
3511  }
3512  }
3513  }
3514  break;
3515  default:
3516  break;
3517  }
3518 
3519  bc->AOCD_need_export = 0;
3520 }
Main Channel structure associated with a channel.
union misdn_bchannel::@161 AOCD
enum FacFunction AOCDtype
Definition: isdn_lib.h:515
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
int AOCD_need_export
TRUE if AOCDtype and AOCD data are ready to export to Asterisk.
Definition: isdn_lib.h:521
#define NULL
Definition: resample.c:96
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
#define ast_channel_cleanup(c)
Cleanup a channel reference.
Definition: channel.h:2992
struct FacAOCDCurrency currency
Definition: isdn_lib.h:517
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name...
#define ast_channel_ref(c)
Increase channel reference count.
Definition: channel.h:2970
struct ast_channel * ast_channel_bridge_peer(struct ast_channel *chan)
Get the channel&#39;s bridge peer only if the bridge is two-party.
Definition: channel.c:10765
#define ORG_AST
Definition: chan_misdn.c:343
struct FacAOCDChargingUnit chargingUnit
Definition: isdn_lib.h:518

◆ export_ch()

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 8811 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, tmp(), misdn_bchannel::urate, misdn_bchannel::uu, and misdn_bchannel::uulen.

Referenced by cb_events().

8812 {
8813  char tmp[32];
8814 
8815  /*
8816  * The only use for MISDN_PID is if there is a problem and you
8817  * have to use the "misdn restart pid" CLI command. Otherwise,
8818  * the pid is not used by anyone. The internal use of MISDN_PID
8819  * has been deleted.
8820  */
8821  chan_misdn_log(3, bc->port, " --> EXPORT_PID: pid:%d\n", bc->pid);
8822  snprintf(tmp, sizeof(tmp), "%d", bc->pid);
8823  pbx_builtin_setvar_helper(chan, "_MISDN_PID", tmp);
8824 
8825  if (bc->sending_complete) {
8826  snprintf(tmp, sizeof(tmp), "%d", bc->sending_complete);
8827  pbx_builtin_setvar_helper(chan, "MISDN_ADDRESS_COMPLETE", tmp);
8828  }
8829 
8830  if (bc->urate) {
8831  snprintf(tmp, sizeof(tmp), "%d", bc->urate);
8832  pbx_builtin_setvar_helper(chan, "MISDN_URATE", tmp);
8833  }
8834 
8835  if (bc->uulen) {
8836  pbx_builtin_setvar_helper(chan, "MISDN_USERUSER", bc->uu);
8837  }
8838 
8839  if (!ast_strlen_zero(bc->keypad)) {
8840  pbx_builtin_setvar_helper(chan, "MISDN_KEYPAD", bc->keypad);
8841  }
8842 }
static void chan_misdn_log(int level, int port, char *tmpl,...)
Definition: chan_misdn.c:12768
char keypad[MISDN_MAX_KEYPAD_LEN]
Q.931 Keypad Facility IE contents.
Definition: isdn_lib.h:647
int uulen
User-User information string length in uu[].
Definition: isdn_lib.h:666
char uu[256]
User-User information string.
Definition: isdn_lib.h:663
static int tmp()
Definition: bt_open.c:389
int sending_complete
TRUE if all digits necessary to complete the call are available. No more INFORMATION messages are nee...
Definition: isdn_lib.h:470
#define ast_strlen_zero(foo)
Definition: strings.h:52
int pid
B channel process ID (1-5000)
Definition: isdn_lib.h:402
int port
Logical Layer 1 port associated with this B channel.
Definition: isdn_lib.h:370
int urate
Q.931 Bearer Capability IE Layer 1 User Rate field.
Definition: isdn_lib.h:629
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name...

◆ find_chan_by_bc()

static struct chan_list* find_chan_by_bc ( struct misdn_bchannel bc)
static

Returns a reference to the found chan_list.

Definition at line 8259 of file chan_misdn.c.

References ast_mutex_lock, ast_mutex_unlock, chan_list::bc, misdn_bchannel::caller, chan_list_ref, chan_misdn_log(), misdn_bchannel::dialed, misdn_party_id::name, chan_list::next, NULL, misdn_party_dialing::number, misdn_party_id::number, and misdn_bchannel::port.

Referenced by cb_events(), and chan_misdn_jb_empty().

8260 {
8261  struct chan_list *help;
8262 
8264  for (help = cl_te; help; help = help->next) {
8265  if (help->bc == bc) {
8266  chan_list_ref(help, "Found chan_list by bc");
8268  return help;
8269  }
8270  }
8272 
8273  chan_misdn_log(6, bc->port,
8274  "$$$ find_chan_by_bc: No channel found for dialed:%s caller:\"%s\" <%s>\n",
8275  bc->dialed.number,
8276  bc->caller.name,
8277  bc->caller.number);
8278 
8279  return NULL;
8280 }
static void chan_misdn_log(int level, int port, char *tmpl,...)
Definition: chan_misdn.c:12768
struct chan_list * next
Next channel call record in the list.
Definition: chan_misdn.c:608
char number[MISDN_MAX_NUMBER_LEN]
Phone number (Address)
Definition: isdn_lib.h:298
#define ast_mutex_lock(a)
Definition: lock.h:187
#define NULL
Definition: resample.c:96
static struct chan_list * cl_te
Global channel call record list head.
Definition: chan_misdn.c:704
char number[MISDN_MAX_NUMBER_LEN]
Dialed/Called Phone Number (Address)
Definition: isdn_lib.h:266
struct misdn_party_id caller
Originating/Caller ID information struct.
Definition: isdn_lib.h:343
char name[MISDN_MAX_NAME_LEN]
Subscriber Name.
Definition: isdn_lib.h:295
int port
Logical Layer 1 port associated with this B channel.
Definition: isdn_lib.h:370
struct misdn_party_dialing dialed
Dialed/Called information struct.
Definition: isdn_lib.h:337
Channel call record structure.
Definition: chan_misdn.c:377
#define chan_list_ref(obj, debug)
Definition: chan_misdn.c:371
struct misdn_bchannel * bc
Associated B channel structure.
Definition: chan_misdn.c:520
static ast_mutex_t cl_te_lock
Definition: chan_misdn.c:705
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ find_hold_active_call()

static struct chan_list* find_hold_active_call ( struct misdn_bchannel bc)
static

Definition at line 8351 of file chan_misdn.c.

References chan_list::ast, ast_mutex_lock, ast_mutex_unlock, chan_list::bc, chan_list_ref, chan_list::hold, MISDN_ALERTING, MISDN_CONNECTED, MISDN_HOLD_IDLE, MISDN_PROCEEDING, MISDN_PROGRESS, chan_list::next, NULL, misdn_bchannel::port, hold_info::state, and chan_list::state.

Referenced by cb_events().

8352 {
8353  struct chan_list *list;
8354 
8356  for (list = cl_te; list; list = list->next) {
8357  if (list->hold.state == MISDN_HOLD_IDLE && list->bc && list->bc->port == bc->port
8358  && list->ast) {
8359  switch (list->state) {
8360  case MISDN_PROCEEDING:
8361  case MISDN_PROGRESS:
8362  case MISDN_ALERTING:
8363  case MISDN_CONNECTED:
8364  chan_list_ref(list, "Found chan_list hold active call");
8366  return list;
8367  default:
8368  break;
8369  }
8370  }
8371  }
8373  return NULL;
8374 }
struct chan_list * next
Next channel call record in the list.
Definition: chan_misdn.c:608
struct hold_info hold
HELD channel call information.
Definition: chan_misdn.c:535
#define ast_mutex_lock(a)
Definition: lock.h:187
#define NULL
Definition: resample.c:96
static struct chan_list * cl_te
Global channel call record list head.
Definition: chan_misdn.c:704
struct ast_channel * ast
Associated Asterisk channel structure.
Definition: chan_misdn.c:515
enum misdn_chan_state state
State of the channel.
Definition: chan_misdn.c:386
int port
Logical Layer 1 port associated with this B channel.
Definition: isdn_lib.h:370
Channel call record structure.
Definition: chan_misdn.c:377
#define chan_list_ref(obj, debug)
Definition: chan_misdn.c:371
enum misdn_hold_state state
Call HOLD state.
Definition: chan_misdn.c:357
struct misdn_bchannel * bc
Associated B channel structure.
Definition: chan_misdn.c:520
static ast_mutex_t cl_te_lock
Definition: chan_misdn.c:705
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ find_hold_call()

static struct chan_list* find_hold_call ( struct misdn_bchannel bc)
static

Returns a reference to the found chan_list.

Definition at line 8283 of file chan_misdn.c.

References ast_mutex_lock, ast_mutex_unlock, misdn_bchannel::caller, chan_list_ref, chan_misdn_log(), hold_info::channel, misdn_bchannel::channel, misdn_bchannel::dialed, chan_list::hold, MISDN_HOLD_ACTIVE, misdn_party_id::name, chan_list::next, NULL, misdn_party_dialing::number, misdn_party_id::number, hold_info::port, misdn_bchannel::port, misdn_bchannel::pri, and hold_info::state.

Referenced by cb_events().

8284 {
8285  struct chan_list *help;
8286 
8287  if (bc->pri) {
8288  return NULL;
8289  }
8290 
8291  chan_misdn_log(6, bc->port, "$$$ find_hold_call: channel:%d dialed:%s caller:\"%s\" <%s>\n",
8292  bc->channel,
8293  bc->dialed.number,
8294  bc->caller.name,
8295  bc->caller.number);
8297  for (help = cl_te; help; help = help->next) {
8298  chan_misdn_log(4, bc->port, "$$$ find_hold_call: --> hold:%d channel:%d\n", help->hold.state, help->hold.channel);
8299  if (help->hold.state == MISDN_HOLD_ACTIVE && help->hold.port == bc->port) {
8300  chan_list_ref(help, "Found chan_list hold call");
8302  return help;
8303  }
8304  }
8306  chan_misdn_log(6, bc->port,
8307  "$$$ find_hold_call: No channel found for dialed:%s caller:\"%s\" <%s>\n",
8308  bc->dialed.number,
8309  bc->caller.name,
8310  bc->caller.number);
8311 
8312  return NULL;
8313 }
static void chan_misdn_log(int level, int port, char *tmpl,...)
Definition: chan_misdn.c:12768
struct chan_list * next
Next channel call record in the list.
Definition: chan_misdn.c:608
char number[MISDN_MAX_NUMBER_LEN]
Phone number (Address)
Definition: isdn_lib.h:298
struct hold_info hold
HELD channel call information.
Definition: chan_misdn.c:535
#define ast_mutex_lock(a)
Definition: lock.h:187
#define NULL
Definition: resample.c:96
static struct chan_list * cl_te
Global channel call record list head.
Definition: chan_misdn.c:704
char number[MISDN_MAX_NUMBER_LEN]
Dialed/Called Phone Number (Address)
Definition: isdn_lib.h:266
int pri
TRUE if ISDN-PRI (ISDN-BRI otherwise)
Definition: isdn_lib.h:367
struct misdn_party_id caller
Originating/Caller ID information struct.
Definition: isdn_lib.h:343
char name[MISDN_MAX_NAME_LEN]
Subscriber Name.
Definition: isdn_lib.h:295
int port
Logical port the channel call record is HELD on because the B channel is no longer associated...
Definition: chan_misdn.c:362
int port
Logical Layer 1 port associated with this B channel.
Definition: isdn_lib.h:370
struct misdn_party_dialing dialed
Dialed/Called information struct.
Definition: isdn_lib.h:337
Channel call record structure.
Definition: chan_misdn.c:377
#define chan_list_ref(obj, debug)
Definition: chan_misdn.c:371
enum misdn_hold_state state
Call HOLD state.
Definition: chan_misdn.c:357
int channel
Original B channel number the HELD call was using.
Definition: chan_misdn.c:368
int channel
Assigned B channel number B1, B2... 0 if not assigned.
Definition: isdn_lib.h:411
static ast_mutex_t cl_te_lock
Definition: chan_misdn.c:705
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ find_hold_call_l3()

static struct chan_list* find_hold_call_l3 ( unsigned long  l3_id)
static

Returns a reference to the found chan_list.

Definition at line 8317 of file chan_misdn.c.

References ast_mutex_lock, ast_mutex_unlock, chan_list_ref, chan_list::hold, chan_list::l3id, MISDN_HOLD_IDLE, chan_list::next, NULL, and hold_info::state.

Referenced by cb_events().

8318 {
8319  struct chan_list *help;
8320 
8322  for (help = cl_te; help; help = help->next) {
8323  if (help->hold.state != MISDN_HOLD_IDLE && help->l3id == l3_id) {
8324  chan_list_ref(help, "Found chan_list hold call l3");
8326  return help;
8327  }
8328  }
8330 
8331  return NULL;
8332 }
struct chan_list * next
Next channel call record in the list.
Definition: chan_misdn.c:608
struct hold_info hold
HELD channel call information.
Definition: chan_misdn.c:535
#define ast_mutex_lock(a)
Definition: lock.h:187
#define NULL
Definition: resample.c:96
static struct chan_list * cl_te
Global channel call record list head.
Definition: chan_misdn.c:704
Channel call record structure.
Definition: chan_misdn.c:377
unsigned int l3id
From associated B channel: Layer 3 process ID.
Definition: chan_misdn.c:541
#define chan_list_ref(obj, debug)
Definition: chan_misdn.c:371
enum misdn_hold_state state
Call HOLD state.
Definition: chan_misdn.c:357
static ast_mutex_t cl_te_lock
Definition: chan_misdn.c:705
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ free_robin_list()

static void free_robin_list ( void  )
static

Definition at line 629 of file chan_misdn.c.

References ast_free, robin_list::group, robin_list::next, and NULL.

Referenced by reload_config(), and unload_module().

630 {
631  struct robin_list *r;
632  struct robin_list *next;
633 
634  for (r = robin, robin = NULL; r; r = next) {
635  next = r->next;
636  ast_free(r->group);
637  ast_free(r);
638  }
639 }
struct robin_list * next
Definition: chan_misdn.c:623
static struct robin_list * robin
Definition: chan_misdn.c:626
#define NULL
Definition: resample.c:96
char * group
Definition: chan_misdn.c:620
#define ast_free(a)
Definition: astmm.h:182

◆ get_chan_by_ast_name()

static struct chan_list* get_chan_by_ast_name ( const char *  name)
static

Returns a reference to the found chan_list.

Definition at line 786 of file chan_misdn.c.

References ao2_lock, ao2_ref, ao2_unlock, ARRAY_LEN, chan_list::ast, ast_calloc, AST_CAUSE_NORMAL_CLEARING, ast_channel_datastore_find(), ast_channel_lock, ast_channel_name(), ast_channel_trylock, ast_channel_unlock, ast_free, AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_REMOVE_HEAD, AST_LIST_TRAVERSE, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_mutex_lock, ast_mutex_unlock, ast_safe_sleep_conditional(), bc, chan_list_ref, chan_misdn_log(), ast_datastore::data, EVENT_RELEASE_COMPLETE, misdn_lib_send_event(), mISDN_REDIRECTING_REASON_CALL_FWD, mISDN_REDIRECTING_REASON_CALL_FWD_BUSY, mISDN_REDIRECTING_REASON_NO_REPLY, mISDN_REDIRECTING_REASON_UNKNOWN, name, chan_list::next, NULL, NUMPLAN_DATA, NUMPLAN_ISDN, NUMPLAN_NATIONAL, NUMPLAN_PRIVATE, NUMPLAN_TELEX, NUMPLAN_UNKNOWN, NUMTYPE_ABBREVIATED, NUMTYPE_INTERNATIONAL, NUMTYPE_NATIONAL, NUMTYPE_NETWORK_SPECIFIC, NUMTYPE_SUBSCRIBER, NUMTYPE_UNKNOWN, pbx_builtin_setvar_helper(), tmp(), ast_datastore_info::type, type, value, and var.

Referenced by handle_cli_misdn_send_digit(), handle_cli_misdn_send_display(), handle_cli_misdn_send_facility(), and handle_cli_misdn_toggle_echocancel().

787 {
788  struct chan_list *tmp;
789 
791  for (tmp = cl_te; tmp; tmp = tmp->next) {
792  if (tmp->ast && strcmp(ast_channel_name(tmp->ast), name) == 0) {
793  chan_list_ref(tmp, "Found chan_list by ast name");
795  return tmp;
796  }
797  }
799 
800  return NULL;
801 }
struct chan_list * next
Next channel call record in the list.
Definition: chan_misdn.c:608
static int tmp()
Definition: bt_open.c:389
#define ast_mutex_lock(a)
Definition: lock.h:187
#define NULL
Definition: resample.c:96
static struct chan_list * cl_te
Global channel call record list head.
Definition: chan_misdn.c:704
struct ast_channel * ast
Associated Asterisk channel structure.
Definition: chan_misdn.c:515
static const char name[]
Definition: cdr_mysql.c:74
Channel call record structure.
Definition: chan_misdn.c:377
#define chan_list_ref(obj, debug)
Definition: chan_misdn.c:371
const char * ast_channel_name(const struct ast_channel *chan)
static ast_mutex_t cl_te_lock
Definition: chan_misdn.c:705
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ get_robin_position()

static struct robin_list* get_robin_position ( char *  group)
static

Definition at line 641 of file chan_misdn.c.

References ast_calloc, ast_free, ast_strdup, robin_list::group, robin_list::next, NULL, robin_list::prev, and robin.

Referenced by misdn_request().

642 {
643  struct robin_list *new;
644  struct robin_list *iter = robin;
645  for (; iter; iter = iter->next) {
646  if (!strcasecmp(iter->group, group)) {
647  return iter;
648  }
649  }
650  new = ast_calloc(1, sizeof(*new));
651  if (!new) {
652  return NULL;
653  }
654  new->group = ast_strdup(group);
655  if (!new->group) {
656  ast_free(new);
657  return NULL;
658  }
659  new->channel = 1;
660  if (robin) {
661  new->next = robin;
662  robin->prev = new;
663  }
664  robin = new;
665  return robin;
666 }
struct robin_list * next
Definition: chan_misdn.c:623
static struct robin_list * robin
Definition: chan_misdn.c:626
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
#define NULL
Definition: resample.c:96
struct robin_list * prev
Definition: chan_misdn.c:624
char * group
Definition: chan_misdn.c:620
#define ast_free(a)
Definition: astmm.h:182
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204

◆ handle_cli_misdn_port_block()

static char* handle_cli_misdn_port_block ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 3830 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(), NULL, and ast_cli_entry::usage.

3831 {
3832  switch (cmd) {
3833  case CLI_INIT:
3834  e->command = "misdn port block";
3835  e->usage =
3836  "Usage: misdn port block <port>\n"
3837  " Block the specified port by <port>.\n";
3838  return NULL;
3839  case CLI_GENERATE:
3840  return NULL;
3841  }
3842 
3843  if (a->argc != 4) {
3844  return CLI_SHOWUSAGE;
3845  }
3846 
3847  misdn_lib_port_block(atoi(a->argv[3]));
3848 
3849  return CLI_SUCCESS;
3850 }
const int argc
Definition: cli.h:160
Definition: cli.h:152
#define NULL
Definition: resample.c:96
int misdn_lib_port_block(int port)
Definition: isdn_lib.c:91
const char *const * argv
Definition: cli.h:161
#define CLI_SHOWUSAGE
Definition: cli.h:45
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44

◆ handle_cli_misdn_port_down()

static char* handle_cli_misdn_port_down ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 3940 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(), NULL, and ast_cli_entry::usage.

3941 {
3942  switch (cmd) {
3943  case CLI_INIT:
3944  e->command = "misdn port down";
3945  e->usage =
3946  "Usage: misdn port down <port>\n"
3947  " Try to deactivate the L1 on the given port.\n";
3948  return NULL;
3949  case CLI_GENERATE:
3950  return NULL;
3951  }
3952 
3953  if (a->argc != 4) {
3954  return CLI_SHOWUSAGE;
3955  }
3956 
3957  misdn_lib_get_port_down(atoi(a->argv[3]));
3958 
3959  return CLI_SUCCESS;
3960 }
const int argc
Definition: cli.h:160
Definition: cli.h:152
#define NULL
Definition: resample.c:96
const char *const * argv
Definition: cli.h:161
#define CLI_SHOWUSAGE
Definition: cli.h:45
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44
int misdn_lib_get_port_down(int port)
Definition: isdn_lib.c:1805

◆ handle_cli_misdn_port_unblock()

static char* handle_cli_misdn_port_unblock ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 3852 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(), NULL, and ast_cli_entry::usage.

3853 {
3854  switch (cmd) {
3855  case CLI_INIT:
3856  e->command = "misdn port unblock";
3857  e->usage =
3858  "Usage: misdn port unblock <port>\n"
3859  " Unblock the port specified by <port>.\n";
3860  return NULL;
3861  case CLI_GENERATE:
3862  return NULL;
3863  }
3864 
3865  if (a->argc != 4) {
3866  return CLI_SHOWUSAGE;
3867  }
3868 
3869  misdn_lib_port_unblock(atoi(a->argv[3]));
3870 
3871  return CLI_SUCCESS;
3872 }
const int argc
Definition: cli.h:160
Definition: cli.h:152
#define NULL
Definition: resample.c:96
int misdn_lib_port_unblock(int port)
Definition: isdn_lib.c:104
const char *const * argv
Definition: cli.h:161
#define CLI_SHOWUSAGE
Definition: cli.h:45
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44

◆ handle_cli_misdn_port_up()

static char* handle_cli_misdn_port_up ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 3918 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(), NULL, and ast_cli_entry::usage.

3919 {
3920  switch (cmd) {
3921  case CLI_INIT:
3922  e->command = "misdn port up";
3923  e->usage =
3924  "Usage: misdn port up <port>\n"
3925  " Try to establish L1 on the given port.\n";
3926  return NULL;
3927  case CLI_GENERATE:
3928  return NULL;
3929  }
3930 
3931  if (a->argc != 4) {
3932  return CLI_SHOWUSAGE;
3933  }
3934 
3935  misdn_lib_get_port_up(atoi(a->argv[3]));
3936 
3937  return CLI_SUCCESS;
3938 }
const int argc
Definition: cli.h:160
Definition: cli.h:152
#define NULL
Definition: resample.c:96
const char *const * argv
Definition: cli.h:161
#define CLI_SHOWUSAGE
Definition: cli.h:45
int misdn_lib_get_port_up(int port)
Definition: isdn_lib.c:1781
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44

◆ handle_cli_misdn_reload()

static char* handle_cli_misdn_reload ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 4144 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, NULL, reload_config(), and ast_cli_entry::usage.

4145 {
4146  switch (cmd) {
4147  case CLI_INIT:
4148  e->command = "misdn reload";
4149  e->usage =
4150  "Usage: misdn reload\n"
4151  " Reload internal mISDN config, read from the config\n"
4152  " file.\n";
4153  return NULL;
4154  case CLI_GENERATE:
4155  return NULL;
4156  }
4157 
4158  if (a->argc != 2) {
4159  return CLI_SHOWUSAGE;
4160  }
4161 
4162  ast_cli(a->fd, "Reloading mISDN configuration\n");
4163  reload_config();
4164  return CLI_SUCCESS;
4165 }
const int argc
Definition: cli.h:160
Definition: cli.h:152
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
const int fd
Definition: cli.h:159
#define CLI_SHOWUSAGE
Definition: cli.h:45
char * command
Definition: cli.h:186
static void reload_config(void)
Definition: chan_misdn.c:4123
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44

◆ handle_cli_misdn_restart_pid()

static char* handle_cli_misdn_restart_pid ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 3896 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(), NULL, and ast_cli_entry::usage.

3897 {
3898  switch (cmd) {
3899  case CLI_INIT:
3900  e->command = "misdn restart pid";
3901  e->usage =
3902  "Usage: misdn restart pid <pid>\n"
3903  " Restart the given pid\n";
3904  return NULL;
3905  case CLI_GENERATE:
3906  return NULL;
3907  }
3908 
3909  if (a->argc != 4) {
3910  return CLI_SHOWUSAGE;
3911  }
3912 
3913  misdn_lib_pid_restart(atoi(a->argv[3]));
3914 
3915  return CLI_SUCCESS;
3916 }
int misdn_lib_pid_restart(int pid)
Definition: isdn_lib.c:3932
const int argc
Definition: cli.h:160
Definition: cli.h:152
#define NULL
Definition: resample.c:96
const char *const * argv
Definition: cli.h:161
#define CLI_SHOWUSAGE
Definition: cli.h:45
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44

◆ handle_cli_misdn_restart_port()

static char* handle_cli_misdn_restart_port ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 3874 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(), NULL, and ast_cli_entry::usage.

3875 {
3876  switch (cmd) {
3877  case CLI_INIT:
3878  e->command = "misdn restart port";
3879  e->usage =
3880  "Usage: misdn restart port <port>\n"
3881  " Restart the given port.\n";
3882  return NULL;
3883  case CLI_GENERATE:
3884  return NULL;
3885  }
3886 
3887  if (a->argc != 4) {
3888  return CLI_SHOWUSAGE;
3889  }
3890 
3891  misdn_lib_port_restart(atoi(a->argv[3]));
3892 
3893  return CLI_SUCCESS;
3894 }
const int argc
Definition: cli.h:160
Definition: cli.h:152
#define NULL
Definition: resample.c:96
const char *const * argv
Definition: cli.h:161
#define CLI_SHOWUSAGE
Definition: cli.h:45
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44
int misdn_lib_port_restart(int port)
Definition: isdn_lib.c:3982

◆ handle_cli_misdn_send_digit()

static char* handle_cli_misdn_send_digit ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 5509 of file chan_misdn.c.

References ast_cli_args::argc, ast_cli_args::argv, chan_list::ast, ast_cli(), ast_dtmf_stream(), chan_list_unref, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_ch(), ast_cli_args::fd, get_chan_by_ast_name(), NULL, send_digit_to_chan(), tmp(), and ast_cli_entry::usage.

5510 {
5511  const char *channame;
5512  const char *msg;
5513  struct chan_list *tmp;
5514  int i, msglen;
5515 
5516  switch (cmd) {
5517  case CLI_INIT:
5518  e->command = "misdn send digit";
5519  e->usage =
5520  "Usage: misdn send digit <channel> \"<msg>\" \n"
5521  " Send <digit> to <channel> as DTMF Tone\n"
5522  " when channel is a mISDN channel\n";
5523  return NULL;
5524  case CLI_GENERATE:
5525  return complete_ch(a);
5526  }
5527 
5528  if (a->argc != 5) {
5529  return CLI_SHOWUSAGE;
5530  }
5531 
5532  channame = a->argv[3];
5533  msg = a->argv[4];
5534  msglen = strlen(msg);
5535 
5536  ast_cli(a->fd, "Sending %s to %s\n", msg, channame);
5537 
5538  tmp = get_chan_by_ast_name(channame);
5539  if (!tmp) {
5540  ast_cli(a->fd, "Sending %s to %s failed Channel does not exist\n", msg, channame);
5541  return CLI_SUCCESS;
5542  }
5543 #if 1
5544  for (i = 0; i < msglen; i++) {
5545  if (!tmp->ast) {
5546  break;
5547  }
5548  ast_cli(a->fd, "Sending: %c\n", msg[i]);
5549  send_digit_to_chan(tmp, msg[i]);
5550  /* res = ast_safe_sleep(tmp->ast, 250); */
5551  usleep(250000);
5552  /* res = ast_waitfor(tmp->ast,100); */
5553  }
5554 #else
5555  if (tmp->ast) {
5556  ast_dtmf_stream(tmp->ast, NULL, msg, 250);
5557  }
5558 #endif
5559  chan_list_unref(tmp, "Digit(s) sent");
5560 
5561  return CLI_SUCCESS;
5562 }
int ast_dtmf_stream(struct ast_channel *chan, struct ast_channel *peer, const char *digits, int between, unsigned int duration)
Send a string of DTMF digits to a channel.
Definition: main/app.c:981
const int argc
Definition: cli.h:160
static int tmp()
Definition: bt_open.c:389
Definition: cli.h:152
static struct chan_list * get_chan_by_ast_name(const char *name)
Definition: chan_misdn.c:786
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
struct ast_channel * ast
Associated Asterisk channel structure.
Definition: chan_misdn.c:515
static char * complete_ch(struct ast_cli_args *a)
Definition: chan_misdn.c:5654
const int fd
Definition: cli.h:159
const char *const * argv
Definition: cli.h:161
#define CLI_SHOWUSAGE
Definition: cli.h:45
char * command
Definition: cli.h:186
Channel call record structure.
Definition: chan_misdn.c:377
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44
static void send_digit_to_chan(struct chan_list *cl, char digit)
Definition: chan_misdn.c:3681
#define chan_list_unref(obj, debug)
Definition: chan_misdn.c:372

◆ handle_cli_misdn_send_display()

static char* handle_cli_misdn_send_display ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 5611 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(), NULL, tmp(), and ast_cli_entry::usage.

5612 {
5613  const char *channame;
5614  const char *msg;
5615  struct chan_list *tmp;
5616 
5617  switch (cmd) {
5618  case CLI_INIT:
5619  e->command = "misdn send display";
5620  e->usage =
5621  "Usage: misdn send display <channel> \"<msg>\" \n"
5622  " Send <msg> to <channel> as Display Message\n"
5623  " when channel is a mISDN channel\n";
5624  return NULL;
5625  case CLI_GENERATE:
5626  return complete_ch(a);
5627  }
5628 
5629  if (a->argc != 5) {
5630  return CLI_SHOWUSAGE;
5631  }
5632 
5633  channame = a->argv[3];
5634  msg = a->argv[4];
5635 
5636  ast_cli(a->fd, "Sending %s to %s\n", msg, channame);
5637 
5638  tmp = get_chan_by_ast_name(channame);
5639  if (tmp && tmp->bc) {
5640  ast_copy_string(tmp->bc->display, msg, sizeof(tmp->bc->display));
5642  chan_list_unref(tmp, "Done sending display");
5643  } else {
5644  if (tmp) {
5645  chan_list_unref(tmp, "Display failed");
5646  }
5647  ast_cli(a->fd, "No such channel %s\n", channame);
5648  return CLI_SUCCESS;
5649  }
5650 
5651  return CLI_SUCCESS;
5652 }
const int argc
Definition: cli.h:160
static int tmp()
Definition: bt_open.c:389
Definition: cli.h:152
static struct chan_list * get_chan_by_ast_name(const char *name)
Definition: chan_misdn.c:786
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
char display[84]
Display message that can be displayed by the user phone.
Definition: isdn_lib.h:642
static char * complete_ch(struct ast_cli_args *a)
Definition: chan_misdn.c:5654
const int fd
Definition: cli.h:159
const char *const * argv
Definition: cli.h:161
#define CLI_SHOWUSAGE
Definition: cli.h:45
char * command
Definition: cli.h:186
Channel call record structure.
Definition: chan_misdn.c:377
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
int misdn_lib_send_event(struct misdn_bchannel *bc, enum event_e event)
Definition: isdn_lib.c:3523
struct misdn_bchannel * bc
Associated B channel structure.
Definition: chan_misdn.c:520
#define chan_list_unref(obj, debug)
Definition: chan_misdn.c:372

◆ handle_cli_misdn_send_facility()

static char* handle_cli_misdn_send_facility ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 5183 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(), NULL, print_facility(), tmp(), and ast_cli_entry::usage.

5184 {
5185  const char *channame;
5186  const char *nr;
5187  struct chan_list *tmp;
5188  int port;
5189  const char *served_nr;
5190  struct misdn_bchannel dummy, *bc=&dummy;
5191  unsigned max_len;
5192 
5193  switch (cmd) {
5194  case CLI_INIT:
5195  e->command = "misdn send facility";
5196  e->usage = "Usage: misdn send facility <type> <channel|port> \"<args>\" \n"
5197  "\t type is one of:\n"
5198  "\t - calldeflect\n"
5199 #if defined(AST_MISDN_ENHANCEMENTS)
5200  "\t - callrerouting\n"
5201 #endif /* defined(AST_MISDN_ENHANCEMENTS) */
5202  "\t - CFActivate\n"
5203  "\t - CFDeactivate\n";
5204 
5205  return NULL;
5206  case CLI_GENERATE:
5207  return complete_ch(a);
5208  }
5209 
5210  if (a->argc < 5) {
5211  return CLI_SHOWUSAGE;
5212  }
5213 
5214  if (strstr(a->argv[3], "calldeflect")) {
5215  if (a->argc < 6) {
5216  ast_verbose("calldeflect requires 1 arg: ToNumber\n\n");
5217  return 0;
5218  }
5219  channame = a->argv[4];
5220  nr = a->argv[5];
5221 
5222  ast_verbose("Sending Calldeflection (%s) to %s\n", nr, channame);
5223  tmp = get_chan_by_ast_name(channame);
5224  if (!tmp) {
5225  ast_verbose("Sending CD with nr %s to %s failed: Channel does not exist.\n", nr, channame);
5226  return 0;
5227  }
5228  ao2_lock(tmp);
5229 
5230 #if defined(AST_MISDN_ENHANCEMENTS)
5231  max_len = sizeof(tmp->bc->fac_out.u.CallDeflection.Component.Invoke.Deflection.Party.Number) - 1;
5232  if (max_len < strlen(nr)) {
5233  ast_verbose("Sending CD with nr %s to %s failed: Number too long (up to %u digits are allowed).\n",
5234  nr, channame, max_len);
5235  ao2_unlock(tmp);
5236  chan_list_unref(tmp, "Number too long");
5237  return 0;
5238  }
5239  tmp->bc->fac_out.Function = Fac_CallDeflection;
5240  tmp->bc->fac_out.u.CallDeflection.InvokeID = ++misdn_invoke_id;
5241  tmp->bc->fac_out.u.CallDeflection.ComponentType = FacComponent_Invoke;
5242  tmp->bc->fac_out.u.CallDeflection.Component.Invoke.PresentationAllowedToDivertedToUserPresent = 1;
5243  tmp->bc->fac_out.u.CallDeflection.Component.Invoke.PresentationAllowedToDivertedToUser = 0;
5244  tmp->bc->fac_out.u.CallDeflection.Component.Invoke.Deflection.Party.Type = 0;/* unknown */
5245  tmp->bc->fac_out.u.CallDeflection.Component.Invoke.Deflection.Party.LengthOfNumber = strlen(nr);
5246  strcpy((char *) tmp->bc->fac_out.u.CallDeflection.Component.Invoke.Deflection.Party.Number, nr);
5247  tmp->bc->fac_out.u.CallDeflection.Component.Invoke.Deflection.Subaddress.Length = 0;
5248 
5249 #else /* !defined(AST_MISDN_ENHANCEMENTS) */
5250 
5251  max_len = sizeof(tmp->bc->fac_out.u.CDeflection.DeflectedToNumber) - 1;
5252  if (max_len < strlen(nr)) {
5253  ast_verbose("Sending CD with nr %s to %s failed: Number too long (up to %u digits are allowed).\n",
5254  nr, channame, max_len);
5255  ao2_unlock(tmp);
5256  chan_list_unref(tmp, "Number too long");
5257  return 0;
5258  }
5259  tmp->bc->fac_out.Function = Fac_CD;
5260  tmp->bc->fac_out.u.CDeflection.PresentationAllowed = 0;
5261  //tmp->bc->fac_out.u.CDeflection.DeflectedToSubaddress[0] = 0;
5262  strcpy((char *) tmp->bc->fac_out.u.CDeflection.DeflectedToNumber, nr);
5263 #endif /* !defined(AST_MISDN_ENHANCEMENTS) */
5264 
5265  /* Send message */
5266  print_facility(&tmp->bc->fac_out, tmp->bc);
5267  ao2_unlock(tmp);
5269  chan_list_unref(tmp, "Send facility complete");
5270 #if defined(AST_MISDN_ENHANCEMENTS)
5271  } else if (strstr(a->argv[3], "callrerouteing") || strstr(a->argv[3], "callrerouting")) {
5272  if (a->argc < 6) {
5273  ast_verbose("callrerouting requires 1 arg: ToNumber\n\n");
5274  return 0;
5275  }
5276  channame = a->argv[4];
5277  nr = a->argv[5];
5278 
5279  ast_verbose("Sending Callrerouting (%s) to %s\n", nr, channame);
5280  tmp = get_chan_by_ast_name(channame);
5281  if (!tmp) {
5282  ast_verbose("Sending Call Rerouting with nr %s to %s failed: Channel does not exist.\n", nr, channame);
5283  return 0;
5284  }
5285  ao2_lock(tmp);
5286 
5287  max_len = sizeof(tmp->bc->fac_out.u.CallRerouteing.Component.Invoke.CalledAddress.Party.Number) - 1;
5288  if (max_len < strlen(nr)) {
5289  ast_verbose("Sending Call Rerouting with nr %s to %s failed: Number too long (up to %u digits are allowed).\n",
5290  nr, channame, max_len);
5291  ao2_unlock(tmp);
5292  chan_list_unref(tmp, "Number too long");
5293  return 0;
5294  }
5295  tmp->bc->fac_out.Function = Fac_CallRerouteing;
5296  tmp->bc->fac_out.u.CallRerouteing.InvokeID = ++misdn_invoke_id;
5297  tmp->bc->fac_out.u.CallRerouteing.ComponentType = FacComponent_Invoke;
5298 
5299  tmp->bc->fac_out.u.CallRerouteing.Component.Invoke.ReroutingReason = 0;/* unknown */
5300  tmp->bc->fac_out.u.CallRerouteing.Component.Invoke.ReroutingCounter = 1;
5301 
5302  tmp->bc->fac_out.u.CallRerouteing.Component.Invoke.CalledAddress.Party.Type = 0;/* unknown */
5303  tmp->bc->fac_out.u.CallRerouteing.Component.Invoke.CalledAddress.Party.LengthOfNumber = strlen(nr);
5304  strcpy((char *) tmp->bc->fac_out.u.CallRerouteing.Component.Invoke.CalledAddress.Party.Number, nr);
5305  tmp->bc->fac_out.u.CallRerouteing.Component.Invoke.CalledAddress.Subaddress.Length = 0;
5306 
5307  tmp->bc->fac_out.u.CallRerouteing.Component.Invoke.CallingPartySubaddress.Length = 0;
5308 
5309  /* 0x90 0x90 0xa3 3.1 kHz audio, circuit mode, 64kbit/sec, level1/a-Law */
5310  tmp->bc->fac_out.u.CallRerouteing.Component.Invoke.Q931ie.Bc.Length = 3;
5311  tmp->bc->fac_out.u.CallRerouteing.Component.Invoke.Q931ie.Bc.Contents[0] = 0x90;
5312  tmp->bc->fac_out.u.CallRerouteing.Component.Invoke.Q931ie.Bc.Contents[1] = 0x90;
5313  tmp->bc->fac_out.u.CallRerouteing.Component.Invoke.Q931ie.Bc.Contents[2] = 0xa3;
5314  tmp->bc->fac_out.u.CallRerouteing.Component.Invoke.Q931ie.Hlc.Length = 0;
5315  tmp->bc->fac_out.u.CallRerouteing.Component.Invoke.Q931ie.Llc.Length = 0;
5316  tmp->bc->fac_out.u.CallRerouteing.Component.Invoke.Q931ie.UserInfo.Length = 0;
5317 
5318  tmp->bc->fac_out.u.CallRerouteing.Component.Invoke.LastRerouting.Type = 1;/* presentationRestricted */
5319  tmp->bc->fac_out.u.CallRerouteing.Component.Invoke.SubscriptionOption = 0;/* no notification to caller */
5320 
5321  /* Send message */
5322  print_facility(&tmp->bc->fac_out, tmp->bc);
5323  ao2_unlock(tmp);
5325  chan_list_unref(tmp, "Send facility complete");
5326 #endif /* defined(AST_MISDN_ENHANCEMENTS) */
5327  } else if (strstr(a->argv[3], "CFActivate")) {
5328  if (a->argc < 7) {
5329  ast_verbose("CFActivate requires 2 args: 1.FromNumber, 2.ToNumber\n\n");
5330  return 0;
5331  }
5332  port = atoi(a->argv[4]);
5333  served_nr = a->argv[5];
5334  nr = a->argv[6];
5335 
5336  misdn_make_dummy(bc, port, 0, misdn_lib_port_is_nt(port), 0);
5337 
5338  ast_verbose("Sending CFActivate Port:(%d) FromNr. (%s) to Nr. (%s)\n", port, served_nr, nr);
5339 
5340 #if defined(AST_MISDN_ENHANCEMENTS)
5341  bc->fac_out.Function = Fac_ActivationDiversion;
5342  bc->fac_out.u.ActivationDiversion.InvokeID = ++misdn_invoke_id;
5343  bc->fac_out.u.ActivationDiversion.ComponentType = FacComponent_Invoke;
5344  bc->fac_out.u.ActivationDiversion.Component.Invoke.BasicService = 0;/* allServices */
5345  bc->fac_out.u.ActivationDiversion.Component.Invoke.Procedure = 0;/* cfu (Call Forward Unconditional) */
5346  ast_copy_string((char *) bc->fac_out.u.ActivationDiversion.Component.Invoke.ServedUser.Number,
5347  served_nr, sizeof(bc->fac_out.u.ActivationDiversion.Component.Invoke.ServedUser.Number));
5348  bc->fac_out.u.ActivationDiversion.Component.Invoke.ServedUser.LengthOfNumber =
5349  strlen((char *) bc->fac_out.u.ActivationDiversion.Component.Invoke.ServedUser.Number);
5350  bc->fac_out.u.ActivationDiversion.Component.Invoke.ServedUser.Type = 0;/* unknown */
5351  ast_copy_string((char *) bc->fac_out.u.ActivationDiversion.Component.Invoke.ForwardedTo.Party.Number,
5352  nr, sizeof(bc->fac_out.u.ActivationDiversion.Component.Invoke.ForwardedTo.Party.Number));
5353  bc->fac_out.u.ActivationDiversion.Component.Invoke.ForwardedTo.Party.LengthOfNumber =
5354  strlen((char *) bc->fac_out.u.ActivationDiversion.Component.Invoke.ForwardedTo.Party.Number);
5355  bc->fac_out.u.ActivationDiversion.Component.Invoke.ForwardedTo.Party.Type = 0;/* unknown */
5356  bc->fac_out.u.ActivationDiversion.Component.Invoke.ForwardedTo.Subaddress.Length = 0;
5357 
5358 #else /* !defined(AST_MISDN_ENHANCEMENTS) */
5359 
5360  bc->fac_out.Function = Fac_CFActivate;
5361  bc->fac_out.u.CFActivate.BasicService = 0; /* All Services */
5362  bc->fac_out.u.CFActivate.Procedure = 0; /* Unconditional */
5363  ast_copy_string((char *) bc->fac_out.u.CFActivate.ServedUserNumber, served_nr, sizeof(bc->fac_out.u.CFActivate.ServedUserNumber));
5364  ast_copy_string((char *) bc->fac_out.u.CFActivate.ForwardedToNumber, nr, sizeof(bc->fac_out.u.CFActivate.ForwardedToNumber));
5365 #endif /* !defined(AST_MISDN_ENHANCEMENTS) */
5366 
5367  /* Send message */
5368  print_facility(&bc->fac_out, bc);
5370  } else if (strstr(a->argv[3], "CFDeactivate")) {
5371  if (a->argc < 6) {
5372  ast_verbose("CFDeactivate requires 1 arg: FromNumber\n\n");
5373  return 0;
5374  }
5375  port = atoi(a->argv[4]);
5376  served_nr = a->argv[5];
5377 
5378  misdn_make_dummy(bc, port, 0, misdn_lib_port_is_nt(port), 0);
5379  ast_verbose("Sending CFDeactivate Port:(%d) FromNr. (%s)\n", port, served_nr);
5380 
5381 #if defined(AST_MISDN_ENHANCEMENTS)
5382  bc->fac_out.Function = Fac_DeactivationDiversion;
5383  bc->fac_out.u.DeactivationDiversion.InvokeID = ++misdn_invoke_id;
5384  bc->fac_out.u.DeactivationDiversion.ComponentType = FacComponent_Invoke;
5385  bc->fac_out.u.DeactivationDiversion.Component.Invoke.BasicService = 0;/* allServices */
5386  bc->fac_out.u.DeactivationDiversion.Component.Invoke.Procedure = 0;/* cfu (Call Forward Unconditional) */
5387  ast_copy_string((char *) bc->fac_out.u.DeactivationDiversion.Component.Invoke.ServedUser.Number,
5388  served_nr, sizeof(bc->fac_out.u.DeactivationDiversion.Component.Invoke.ServedUser.Number));
5389  bc->fac_out.u.DeactivationDiversion.Component.Invoke.ServedUser.LengthOfNumber =
5390  strlen((char *) bc->fac_out.u.DeactivationDiversion.Component.Invoke.ServedUser.Number);
5391  bc->fac_out.u.DeactivationDiversion.Component.Invoke.ServedUser.Type = 0;/* unknown */
5392 
5393 #else /* !defined(AST_MISDN_ENHANCEMENTS) */
5394 
5395  bc->fac_out.Function = Fac_CFDeactivate;
5396  bc->fac_out.u.CFDeactivate.BasicService = 0; /* All Services */
5397  bc->fac_out.u.CFDeactivate.Procedure = 0; /* Unconditional */
5398  ast_copy_string((char *) bc->fac_out.u.CFActivate.ServedUserNumber, served_nr, sizeof(bc->fac_out.u.CFActivate.ServedUserNumber));
5399 #endif /* !defined(AST_MISDN_ENHANCEMENTS) */
5400 
5401  /* Send message */
5402  print_facility(&bc->fac_out, bc);
5404 #if defined(AST_MISDN_ENHANCEMENTS) && defined(CCBS_TEST_MESSAGES)
5405  } else if (strstr(a->argv[3], "test")) {
5406  int msg_number;
5407 
5408  if (a->argc < 5) {
5409  ast_verbose("test (<port> [<msg#>]) | (<channel-name> <msg#>)\n\n");
5410  return 0;
5411  }
5412  port = atoi(a->argv[4]);
5413 
5414  channame = a->argv[4];
5415  tmp = get_chan_by_ast_name(channame);
5416  if (tmp) {
5417  /* We are going to send this FACILITY message out on an existing connection */
5418  msg_number = atoi(a->argv[5]);
5419  if (msg_number < ARRAY_LEN(Fac_Msgs)) {
5420  ao2_lock(tmp);
5421  tmp->bc->fac_out = Fac_Msgs[msg_number];
5422 
5423  /* Send message */
5424  print_facility(&tmp->bc->fac_out, tmp->bc);
5425  ao2_unlock(tmp);
5427  } else {
5428  ast_verbose("test <channel-name> <msg#>\n\n");
5429  }
5430  chan_list_unref(tmp, "Facility test done");
5431  } else if (a->argc < 6) {
5432  for (msg_number = 0; msg_number < ARRAY_LEN(Fac_Msgs); ++msg_number) {
5433  misdn_make_dummy(bc, port, 0, misdn_lib_port_is_nt(port), 0);
5434  bc->fac_out = Fac_Msgs[msg_number];
5435 
5436  /* Send message */
5437  print_facility(&bc->fac_out, bc);
5439  sleep(1);
5440  }
5441  } else {
5442  msg_number = atoi(a->argv[5]);
5443  if (msg_number < ARRAY_LEN(Fac_Msgs)) {
5444  misdn_make_dummy(bc, port, 0, misdn_lib_port_is_nt(port), 0);
5445  bc->fac_out = Fac_Msgs[msg_number];
5446 
5447  /* Send message */
5448  print_facility(&bc->fac_out, bc);
5450  } else {
5451  ast_verbose("test <port> [<msg#>]\n\n");
5452  }
5453  }
5454  } else if (strstr(a->argv[3], "register")) {
5455  if (a->argc < 5) {
5456  ast_verbose("register <port>\n\n");
5457  return 0;
5458  }
5459  port = atoi(a->argv[4]);
5460 
5461  bc = misdn_lib_get_register_bc(port);
5462  if (!bc) {
5463  ast_verbose("Could not allocate REGISTER bc struct\n\n");
5464  return 0;
5465  }
5466  bc->fac_out = Fac_Msgs[45];
5467 
5468  /* Send message */
5469  print_facility(&bc->fac_out, bc);
5471 #endif /* defined(AST_MISDN_ENHANCEMENTS) && defined(CCBS_TEST_MESSAGES) */
5472  }
5473 
5474  return CLI_SUCCESS;
5475 }
struct FacParm fac_out
Outbound FACILITY message function type and contents.
Definition: isdn_lib.h:512
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
#define bc
const int argc
Definition: cli.h:160
static void dummy(char *unused,...)
Definition: chan_unistim.c:220
void misdn_make_dummy(struct misdn_bchannel *dummybc, int port, int l3id, int nt, int channel)
Definition: isdn_lib.c:77
static int tmp()
Definition: bt_open.c:389
B channel control structure.
Definition: isdn_lib.h:324
Definition: cli.h:152
static struct chan_list * get_chan_by_ast_name(const char *name)
Definition: chan_misdn.c:786
#define ao2_unlock(a)
Definition: astobj2.h:730
void ast_verbose(const char *fmt,...)
Definition: extconf.c:2207
#define NULL
Definition: resample.c:96
static void print_facility(const struct FacParm *fac, const struct misdn_bchannel *bc)
Definition: chan_misdn.c:2762
static char * complete_ch(struct ast_cli_args *a)
Definition: chan_misdn.c:5654
#define ao2_lock(a)
Definition: astobj2.h:718
const char *const * argv
Definition: cli.h:161
#define CLI_SHOWUSAGE
Definition: cli.h:45
char * command
Definition: cli.h:186
Channel call record structure.
Definition: chan_misdn.c:377
int misdn_lib_port_is_nt(int port)
Definition: isdn_lib.c:65
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
int misdn_lib_send_event(struct misdn_bchannel *bc, enum event_e event)
Definition: isdn_lib.c:3523
struct misdn_bchannel * bc
Associated B channel structure.
Definition: chan_misdn.c:520
#define chan_list_unref(obj, debug)
Definition: chan_misdn.c:372

◆ handle_cli_misdn_send_restart()

static char* handle_cli_misdn_send_restart ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 5477 of file chan_misdn.c.

References ast_cli_args::argc, ast_cli_args::argv, misdn_bchannel::channel, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, misdn_lib_send_restart(), NULL, misdn_bchannel::port, and ast_cli_entry::usage.

5478 {
5479  int port;
5480  int channel;
5481 
5482  switch (cmd) {
5483  case CLI_INIT:
5484  e->command = "misdn send restart";
5485  e->usage =
5486  "Usage: misdn send restart [port [channel]]\n"
5487  " Send a restart for every bchannel on the given port.\n";
5488  return NULL;
5489  case CLI_GENERATE:
5490  return NULL;
5491  }
5492 
5493  if (a->argc < 4 || a->argc > 5) {
5494  return CLI_SHOWUSAGE;
5495  }
5496 
5497  port = atoi(a->argv[3]);
5498 
5499  if (a->argc == 5) {
5500  channel = atoi(a->argv[4]);
5501  misdn_lib_send_restart(port, channel);
5502  } else {
5503  misdn_lib_send_restart(port, -1);
5504  }
5505 
5506  return CLI_SUCCESS;
5507 }
const int argc
Definition: cli.h:160
Definition: cli.h:152
#define NULL
Definition: resample.c:96
const char *const * argv
Definition: cli.h:161
#define CLI_SHOWUSAGE
Definition: cli.h:45
int misdn_lib_send_restart(int port, int channel)
Definition: isdn_lib.c:3943
int port
Logical Layer 1 port associated with this B channel.
Definition: isdn_lib.h:370
char * command
Definition: cli.h:186
int channel
Assigned B channel number B1, B2... 0 if not assigned.
Definition: isdn_lib.h:411
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44

◆ handle_cli_misdn_set_crypt_debug()

static char* handle_cli_misdn_set_crypt_debug ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 3807 of file chan_misdn.c.

References ast_cli_args::argc, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, NULL, and ast_cli_entry::usage.

3808 {
3809  switch (cmd) {
3810  case CLI_INIT:
3811  e->command = "misdn set crypt debug";
3812  e->usage =
3813  "Usage: misdn set crypt debug <level>\n"
3814  " Set the crypt debug level of the mISDN channel. Level\n"
3815  " must be 1 or 2.\n";
3816  return NULL;
3817  case CLI_GENERATE:
3818  return NULL;
3819  }
3820 
3821  if (a->argc != 5) {
3822  return CLI_SHOWUSAGE;
3823  }
3824 
3825  /* XXX Is this supposed to not do anything? XXX */
3826 
3827  return CLI_SUCCESS;
3828 }
const int argc
Definition: cli.h:160
Definition: cli.h:152
#define NULL
Definition: resample.c:96
#define CLI_SHOWUSAGE
Definition: cli.h:45
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44

◆ handle_cli_misdn_set_debug()

static char* handle_cli_misdn_set_debug ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 3720 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, NULL, and ast_cli_entry::usage.

3721 {
3722  int level;
3723 
3724  switch (cmd) {
3725  case CLI_INIT:
3726  e->command = "misdn set debug [on|off]";
3727  e->usage =
3728  "Usage: misdn set debug {on|off|<level>} [only] | [port <port> [only]]\n"
3729  " Set the debug level of the mISDN channel.\n";
3730  return NULL;
3731  case CLI_GENERATE:
3732  return complete_debug_port(a);
3733  }
3734 
3735  if (a->argc < 4 || a->argc > 7) {
3736  return CLI_SHOWUSAGE;
3737  }
3738 
3739  if (!strcasecmp(a->argv[3], "on")) {
3740  level = 1;
3741  } else if (!strcasecmp(a->argv[3], "off")) {
3742  level = 0;
3743  } else if (isdigit(a->argv[3][0])) {
3744  level = atoi(a->argv[3]);
3745  } else {
3746  return CLI_SHOWUSAGE;
3747  }
3748 
3749  switch (a->argc) {
3750  case 4:
3751  case 5:
3752  {
3753  int i;
3754  int only = 0;
3755  if (a->argc == 5) {
3756  if (strncasecmp(a->argv[4], "only", strlen(a->argv[4]))) {
3757  return CLI_SHOWUSAGE;
3758  } else {
3759  only = 1;
3760  }
3761  }
3762 
3763  for (i = 0; i <= max_ports; i++) {
3764  misdn_debug[i] = level;
3765  misdn_debug_only[i] = only;
3766  }
3767  ast_cli(a->fd, "changing debug level for all ports to %d%s\n", misdn_debug[0], only ? " (only)" : "");
3768  }
3769  break;
3770  case 6:
3771  case 7:
3772  {
3773  int port;
3774  if (strncasecmp(a->argv[4], "port", strlen(a->argv[4])))
3775  return CLI_SHOWUSAGE;
3776  port = atoi(a->argv[5]);
3777  if (port <= 0 || port > max_ports) {
3778  switch (max_ports) {
3779  case 0:
3780  ast_cli(a->fd, "port number not valid! no ports available so you won't get lucky with any number here...\n");
3781  break;
3782  case 1:
3783  ast_cli(a->fd, "port number not valid! only port 1 is available.\n");
3784  break;
3785  default:
3786  ast_cli(a->fd, "port number not valid! only ports 1 to %d are available.\n", max_ports);
3787  }
3788  return 0;
3789  }
3790  if (a->argc == 7) {
3791  if (strncasecmp(a->argv[6], "only", strlen(a->argv[6]))) {
3792  return CLI_SHOWUSAGE;
3793  } else {
3794  misdn_debug_only[port] = 1;
3795  }
3796  } else {
3797  misdn_debug_only[port] = 0;
3798  }
3799  misdn_debug[port] = level;
3800  ast_cli(a->fd, "changing debug level to %d%s for port %d\n", misdn_debug[port], misdn_debug_only[port] ? " (only)" : "", port);
3801  }
3802  }
3803 
3804  return CLI_SUCCESS;
3805 }
const int argc
Definition: cli.h:160
Definition: cli.h:152
static int * misdn_debug_only
Definition: chan_misdn.c:695
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
const int fd
Definition: cli.h:159
static int max_ports
Definition: chan_misdn.c:696
const char *const * argv
Definition: cli.h:161
#define CLI_SHOWUSAGE
Definition: cli.h:45
static int * misdn_debug
Definition: chan_misdn.c:694
int port
Logical Layer 1 port associated with this B channel.
Definition: isdn_lib.h:370
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44
static char * complete_debug_port(struct ast_cli_args *a)
Definition: chan_misdn.c:5659

◆ handle_cli_misdn_set_tics()

static char* handle_cli_misdn_set_tics ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 4339 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, MAXTICS, NULL, and ast_cli_entry::usage.

4340 {
4341  switch (cmd) {
4342  case CLI_INIT:
4343  e->command = "misdn set tics";
4344  e->usage =
4345  "Usage: misdn set tics <value>\n";
4346  return NULL;
4347  case CLI_GENERATE:
4348  return NULL;
4349  }
4350 
4351  if (a->argc != 4) {
4352  return CLI_SHOWUSAGE;
4353  }
4354 
4355  /* XXX Wow, this does... a whole lot of nothing... XXX */
4356  MAXTICS = atoi(a->argv[3]);
4357 
4358  return CLI_SUCCESS;
4359 }
const int argc
Definition: cli.h:160
Definition: cli.h:152
#define NULL
Definition: resample.c:96
const char *const * argv
Definition: cli.h:161
#define CLI_SHOWUSAGE
Definition: cli.h:45
char * command
Definition: cli.h:186
int MAXTICS
Definition: chan_misdn.c:612
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44

◆ handle_cli_misdn_show_channel()

static char* handle_cli_misdn_show_channel ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 4303 of file chan_misdn.c.

References ast_cli_args::argc, ast_cli_args::argv, chan_list::ast, ast_channel_name(), ast_mutex_lock, ast_mutex_unlock, chan_list::bc, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_ch(), ast_cli_args::fd, chan_list::next, NULL, print_bc_info(), and ast_cli_entry::usage.

4304 {
4305  struct chan_list *help;
4306 
4307  switch (cmd) {
4308  case CLI_INIT:
4309  e->command = "misdn show channel";
4310  e->usage =
4311  "Usage: misdn show channel <channel>\n"
4312  " Show an internal mISDN channel\n.";
4313  return NULL;
4314  case CLI_GENERATE:
4315  return complete_ch(a);
4316  }
4317 
4318  if (a->argc != 4) {
4319  return CLI_SHOWUSAGE;
4320  }
4321 
4323  for (help = cl_te; help; help = help->next) {
4324  struct misdn_bchannel *bc = help->bc;
4325  struct ast_channel *ast = help->ast;
4326 
4327  if (bc && ast) {
4328  if (!strcasecmp(ast_channel_name(ast), a->argv[3])) {
4329  print_bc_info(a->fd, help, bc);
4330  break;
4331  }
4332  }
4333  }
4335 
4336  return CLI_SUCCESS;
4337 }
Main Channel structure associated with a channel.
struct chan_list * next
Next channel call record in the list.
Definition: chan_misdn.c:608
#define bc
const int argc
Definition: cli.h:160
B channel control structure.
Definition: isdn_lib.h:324
Definition: cli.h:152
#define ast_mutex_lock(a)
Definition: lock.h:187
#define NULL
Definition: resample.c:96
static struct chan_list * cl_te
Global channel call record list head.
Definition: chan_misdn.c:704
struct ast_channel * ast
Associated Asterisk channel structure.
Definition: chan_misdn.c:515
static char * complete_ch(struct ast_cli_args *a)
Definition: chan_misdn.c:5654
const int fd
Definition: cli.h:159
static void print_bc_info(int fd, struct chan_list *help, struct misdn_bchannel *bc)
Definition: chan_misdn.c:4167
const char *const * argv
Definition: cli.h:161
#define CLI_SHOWUSAGE
Definition: cli.h:45
char * command
Definition: cli.h:186
Channel call record structure.
Definition: chan_misdn.c:377
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44
const char * ast_channel_name(const struct ast_channel *chan)
struct misdn_bchannel * bc
Associated B channel structure.
Definition: chan_misdn.c:520
static ast_mutex_t cl_te_lock
Definition: chan_misdn.c:705
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ handle_cli_misdn_show_channels()

static char* handle_cli_misdn_show_channels ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 4230 of file chan_misdn.c.

References ast_cli_args::argc, chan_list::ast, ast_channel_caller(), ast_channel_exten(), ast_cli(), ast_mutex_lock, ast_mutex_unlock, chan_list::bc, hold_info::channel, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, chan_list::hold, chan_list::l3id, misdn_dump_chanlist(), MISDN_HOLD_IDLE, name, chan_list::next, NULL, misdn_bchannel::pid, hold_info::port, print_bc_info(), S_COR, hold_info::state, and ast_cli_entry::usage.

4231 {
4232  struct chan_list *help;
4233 
4234  switch (cmd) {
4235  case CLI_INIT:
4236  e->command = "misdn show channels";
4237  e->usage =
4238  "Usage: misdn show channels\n"
4239  " Show the internal mISDN channel list\n";
4240  return NULL;
4241  case CLI_GENERATE:
4242  return NULL;
4243  }
4244 
4245  if (a->argc != 3) {
4246  return CLI_SHOWUSAGE;
4247  }
4248 
4249  ast_cli(a->fd, "Channel List: %p\n", cl_te);
4250 
4251  /*
4252  * Walking the list and dumping the channel information could
4253  * take awhile. With the list locked for the duration, the
4254  * channel driver cannot process signaling messages. However,
4255  * since this is a CLI command it should not be run very often.
4256  */
4258  for (help = cl_te; help; help = help->next) {
4259  struct misdn_bchannel *bc = help->bc;
4260  struct ast_channel *ast = help->ast;
4261  if (!ast) {
4262  if (!bc) {
4263  ast_cli(a->fd, "chan_list obj. with l3id:%x has no bc and no ast Leg\n", help->l3id);
4264  continue;
4265  }
4266  ast_cli(a->fd, "bc with pid:%d has no Ast Leg\n", bc->pid);
4267  }
4268 
4269  if (misdn_debug[0] > 2) {
4270  ast_cli(a->fd, "Bc:%p Ast:%p\n", bc, ast);
4271  }
4272  if (bc) {
4273  print_bc_info(a->fd, help, bc);
4274  } else {
4275  if (help->hold.state != MISDN_HOLD_IDLE) {
4276  ast_cli(a->fd, "ITS A HELD CALL BC:\n");
4277  ast_cli(a->fd, " --> l3_id: %x\n"
4278  " --> dialed:%s\n"
4279  " --> caller:\"%s\" <%s>\n"
4280  " --> hold_port: %d\n"
4281  " --> hold_channel: %d\n",
4282  help->l3id,
4283  ast_channel_exten(ast),
4284  S_COR(ast_channel_caller(ast)->id.name.valid, ast_channel_caller(ast)->id.name.str, ""),
4285  S_COR(ast_channel_caller(ast)->id.number.valid, ast_channel_caller(ast)->id.number.str, ""),
4286  help->hold.port,
4287  help->hold.channel
4288  );
4289  } else {
4290  ast_cli(a->fd, "* Channel in unknown STATE !!! Exten:%s, Callerid:%s\n",
4291  ast_channel_exten(ast),
4292  S_COR(ast_channel_caller(ast)->id.number.valid, ast_channel_caller(ast)->id.number.str, ""));
4293  }
4294  }
4295  }
4297 
4299 
4300  return CLI_SUCCESS;
4301 }
struct ast_party_caller * ast_channel_caller(struct ast_channel *chan)
Main Channel structure associated with a channel.
struct chan_list * next
Next channel call record in the list.
Definition: chan_misdn.c:608
#define bc
void misdn_dump_chanlist(void)
Definition: isdn_lib.c:483
const int argc
Definition: cli.h:160
struct hold_info hold
HELD channel call information.
Definition: chan_misdn.c:535
B channel control structure.
Definition: isdn_lib.h:324
Definition: cli.h:152
#define ast_mutex_lock(a)
Definition: lock.h:187
#define NULL
Definition: resample.c:96
static struct chan_list * cl_te
Global channel call record list head.
Definition: chan_misdn.c:704
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
struct ast_channel * ast
Associated Asterisk channel structure.
Definition: chan_misdn.c:515
Number structure.
Definition: app_followme.c:154
const int fd
Definition: cli.h:159
#define S_COR(a, b, c)
returns the equivalent of logic or for strings, with an additional boolean check: second one if not e...
Definition: strings.h:85
const char * ast_channel_exten(const struct ast_channel *chan)
int port
Logical port the channel call record is HELD on because the B channel is no longer associated...
Definition: chan_misdn.c:362
static void print_bc_info(int fd, struct chan_list *help, struct misdn_bchannel *bc)
Definition: chan_misdn.c:4167
int pid
B channel process ID (1-5000)
Definition: isdn_lib.h:402
#define CLI_SHOWUSAGE
Definition: cli.h:45
static int * misdn_debug
Definition: chan_misdn.c:694
static const char name[]
Definition: cdr_mysql.c:74
char * command
Definition: cli.h:186
Channel call record structure.
Definition: chan_misdn.c:377
unsigned int l3id
From associated B channel: Layer 3 process ID.
Definition: chan_misdn.c:541
enum misdn_hold_state state
Call HOLD state.
Definition: chan_misdn.c:357
int channel
Original B channel number the HELD call was using.
Definition: chan_misdn.c:368
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44
struct misdn_bchannel * bc
Associated B channel structure.
Definition: chan_misdn.c:520
static ast_mutex_t cl_te_lock
Definition: chan_misdn.c:705
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ handle_cli_misdn_show_config()

static char* handle_cli_misdn_show_config ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 3987 of file chan_misdn.c.

References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), BUFFERSIZE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_show_config(), ast_cli_args::fd, MISDN_CFG_FIRST, misdn_cfg_get_config_string(), misdn_cfg_get_elem(), misdn_cfg_get_next_port(), misdn_cfg_is_port_valid(), MISDN_CFG_LAST, MISDN_GEN_FIRST, MISDN_GEN_LAST, NULL, misdn_jb::ok, show_config_description(), and ast_cli_entry::usage.

3988 {
3989  char buffer[BUFFERSIZE];
3990  enum misdn_cfg_elements elem;
3991  int linebreak;
3992  int onlyport = -1;
3993  int ok = 0;
3994 
3995  switch (cmd) {
3996  case CLI_INIT:
3997  e->command = "misdn show config";
3998  e->usage =
3999  "Usage: misdn show config [<port> | description <config element> | descriptions [general|ports]]\n"
4000  " Use 0 for <port> to only print the general config.\n";
4001  return NULL;
4002  case CLI_GENERATE:
4003  return complete_show_config(a);
4004  }
4005 
4006  if (a->argc >= 4) {
4007  if (!strcmp(a->argv[3], "description")) {
4008  if (a->argc == 5) {
4009  enum misdn_cfg_elements elem = misdn_cfg_get_elem(a->argv[4]);
4010  if (elem == MISDN_CFG_FIRST) {
4011  ast_cli(a->fd, "Unknown element: %s\n", a->argv[4]);
4012  } else {
4013  show_config_description(a->fd, elem);
4014  }
4015  return CLI_SUCCESS;
4016  }
4017  return CLI_SHOWUSAGE;
4018  } else if (!strcmp(a->argv[3], "descriptions")) {
4019  if ((a->argc == 4) || ((a->argc == 5) && !strcmp(a->argv[4], "general"))) {
4020  for (elem = MISDN_GEN_FIRST + 1; elem < MISDN_GEN_LAST; ++elem) {
4021  show_config_description(a->fd, elem);
4022  ast_cli(a->fd, "\n");
4023  }
4024  ok = 1;
4025  }
4026  if ((a->argc == 4) || ((a->argc == 5) && !strcmp(a->argv[4], "ports"))) {
4027  for (elem = MISDN_CFG_FIRST + 1; elem < MISDN_CFG_LAST - 1 /* the ptp hack, remove the -1 when ptp is gone */; ++elem) {
4028  show_config_description(a->fd, elem);
4029  ast_cli(a->fd, "\n");
4030  }
4031  ok = 1;
4032  }
4033  return ok ? CLI_SUCCESS : CLI_SHOWUSAGE;
4034  } else if (!sscanf(a->argv[3], "%5d", &onlyport) || onlyport < 0) {
4035  ast_cli(a->fd, "Unknown option: %s\n", a->argv[3]);
4036  return CLI_SHOWUSAGE;
4037  }
4038  }
4039 
4040  if (a->argc == 3 || onlyport == 0) {
4041  ast_cli(a->fd, "mISDN General-Config:\n");
4042  for (elem = MISDN_GEN_FIRST + 1, linebreak = 1; elem < MISDN_GEN_LAST; elem++, linebreak++) {
4043  misdn_cfg_get_config_string(0, elem, buffer, sizeof(buffer));
4044  ast_cli(a->fd, "%-36s%s", buffer, !(linebreak % 2) ? "\n" : "");
4045  }
4046  ast_cli(a->fd, "\n");
4047  }
4048 
4049  if (onlyport < 0) {
4050  int port = misdn_cfg_get_next_port(0);
4051 
4052  for (; port > 0; port = misdn_cfg_get_next_port(port)) {
4053  ast_cli(a->fd, "\n[PORT %d]\n", port);
4054  for (elem = MISDN_CFG_FIRST + 1, linebreak = 1; elem < MISDN_CFG_LAST; elem++, linebreak++) {
4055  misdn_cfg_get_config_string(port, elem, buffer, sizeof(buffer));
4056  ast_cli(a->fd, "%-36s%s", buffer, !(linebreak % 2) ? "\n" : "");
4057  }
4058  ast_cli(a->fd, "\n");
4059  }
4060  }
4061 
4062  if (onlyport > 0) {
4063  if (misdn_cfg_is_port_valid(onlyport)) {
4064  ast_cli(a->fd, "[PORT %d]\n", onlyport);
4065  for (elem = MISDN_CFG_FIRST + 1, linebreak = 1; elem < MISDN_CFG_LAST; elem++, linebreak++) {
4066  misdn_cfg_get_config_string(onlyport, elem, buffer, sizeof(buffer));
4067  ast_cli(a->fd, "%-36s%s", buffer, !(linebreak % 2) ? "\n" : "");
4068  }
4069  ast_cli(a->fd, "\n");
4070  } else {
4071  ast_cli(a->fd, "Port %d is not active!\n", onlyport);
4072  }
4073  }
4074 
4075  return CLI_SUCCESS;
4076 }
int misdn_cfg_get_next_port(int port)
Definition: misdn_config.c:929
const int argc
Definition: cli.h:160
void misdn_cfg_get_config_string(int port, enum misdn_cfg_elements elem, char *buf, int bufsize)
Definition: misdn_config.c:805
misdn_cfg_elements
int misdn_cfg_is_port_valid(int port)
Definition: misdn_config.c:737
Definition: cli.h:152
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
#define BUFFERSIZE
static void show_config_description(int fd, enum misdn_cfg_elements elem)
Definition: chan_misdn.c:3962
const int fd
Definition: cli.h:159
static char * complete_show_config(struct ast_cli_args *a)
Definition: chan_misdn.c:5682
enum misdn_cfg_elements misdn_cfg_get_elem(const char *name)
Definition: misdn_config.c:634
const char *const * argv
Definition: cli.h:161
#define CLI_SHOWUSAGE
Definition: cli.h:45
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44

◆ handle_cli_misdn_show_port()

static char* handle_cli_misdn_show_port ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 4421 of file chan_misdn.c.

References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), buf, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, get_show_stack_details(), NULL, and ast_cli_entry::usage.

4422 {
4423  int port;
4424  char buf[128];
4425 
4426  switch (cmd) {
4427  case CLI_INIT:
4428  e->command = "misdn show port";
4429  e->usage =
4430  "Usage: misdn show port <port>\n"
4431  " Show detailed information for given port.\n";
4432  return NULL;
4433  case CLI_GENERATE:
4434  return NULL;
4435  }
4436 
4437  if (a->argc != 4) {
4438  return CLI_SHOWUSAGE;
4439  }
4440 
4441  port = atoi(a->argv[3]);
4442 
4443  ast_cli(a->fd, "BEGIN STACK_LIST:\n");
4444  get_show_stack_details(port, buf);
4445  ast_cli(a->fd, " %s Debug:%d%s\n", buf, misdn_debug[port], misdn_debug_only[port] ? "(only)" : "");
4446 
4447  return CLI_SUCCESS;
4448 }
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
const int argc
Definition: cli.h:160
Definition: cli.h:152
static int * misdn_debug_only
Definition: chan_misdn.c:695
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
void get_show_stack_details(int port, char *buf)
Definition: isdn_lib.c:168
const int fd
Definition: cli.h:159
const char *const * argv
Definition: cli.h:161
#define CLI_SHOWUSAGE
Definition: cli.h:45
static int * misdn_debug
Definition: chan_misdn.c:694
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44

◆ handle_cli_misdn_show_ports_stats()

static char* handle_cli_misdn_show_ports_stats ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 4392 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(), NULL, and ast_cli_entry::usage.

4393 {
4394  int port;
4395 
4396  switch (cmd) {
4397  case CLI_INIT:
4398  e->command = "misdn show ports stats";
4399  e->usage =
4400  "Usage: misdn show ports stats\n"
4401  " Show mISDNs channel's call statistics per port.\n";
4402  return NULL;
4403  case CLI_GENERATE:
4404  return NULL;
4405  }
4406 
4407  if (a->argc != 4) {
4408  return CLI_SHOWUSAGE;
4409  }
4410 
4411  ast_cli(a->fd, "Port\tin_calls\tout_calls\n");
4412  for (port = misdn_cfg_get_next_port(0); port > 0;
4413  port = misdn_cfg_get_next_port(port)) {
4414  ast_cli(a->fd, "%d\t%d\t\t%d\n", port, misdn_in_calls[port], misdn_out_calls[port]);
4415  }
4416  ast_cli(a->fd, "\n");
4417 
4418  return CLI_SUCCESS;
4419 }
int misdn_cfg_get_next_port(int port)
Definition: misdn_config.c:929
const int argc
Definition: cli.h:160
Definition: cli.h:152
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
const int fd
Definition: cli.h:159
#define CLI_SHOWUSAGE
Definition: cli.h:45
char * command
Definition: cli.h:186
static int * misdn_out_calls
Definition: chan_misdn.c:699
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44
static int * misdn_in_calls
Definition: chan_misdn.c:698

◆ handle_cli_misdn_show_stacks()

static char* handle_cli_misdn_show_stacks ( 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(), buf, 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(), NULL, and ast_cli_entry::usage.

4362 {
4363  int port;
4364 
4365  switch (cmd) {
4366  case CLI_INIT:
4367  e->command = "misdn show stacks";
4368  e->usage =
4369  "Usage: misdn show stacks\n"
4370  " Show internal mISDN stack_list.\n";
4371  return NULL;
4372  case CLI_GENERATE:
4373  return NULL;
4374  }
4375 
4376  if (a->argc != 3) {
4377  return CLI_SHOWUSAGE;
4378  }
4379 
4380  ast_cli(a->fd, "BEGIN STACK_LIST:\n");
4381  for (port = misdn_cfg_get_next_port(0); port > 0;
4382  port = misdn_cfg_get_next_port(port)) {
4383  char buf[128];
4384 
4385  get_show_stack_details(port, buf);
4386  ast_cli(a->fd, " %s Debug:%d%s\n", buf, misdn_debug[port], misdn_debug_only[port] ? "(only)" : "");
4387  }
4388 
4389  return CLI_SUCCESS;
4390 }
int misdn_cfg_get_next_port(int port)
Definition: misdn_config.c:929
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
const int argc
Definition: cli.h:160
Definition: cli.h:152
static int * misdn_debug_only
Definition: chan_misdn.c:695
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
void get_show_stack_details(int port, char *buf)
Definition: isdn_lib.c:168
const int fd
Definition: cli.h:159
#define CLI_SHOWUSAGE
Definition: cli.h:45
static int * misdn_debug
Definition: chan_misdn.c:694
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44

◆ handle_cli_misdn_toggle_echocancel()

static char* handle_cli_misdn_toggle_echocancel ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 5564 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(), NULL, tmp(), chan_list::toggle_ec, update_ec_config(), and ast_cli_entry::usage.

5565 {
5566  const char *channame;
5567  struct chan_list *tmp;
5568 
5569  switch (cmd) {
5570  case CLI_INIT:
5571  e->command = "misdn toggle echocancel";
5572  e->usage =
5573  "Usage: misdn toggle echocancel <channel>\n"
5574  " Toggle EchoCancel on mISDN Channel.\n";
5575  return NULL;
5576  case CLI_GENERATE:
5577  return complete_ch(a);
5578  }
5579 
5580  if (a->argc != 4) {
5581  return CLI_SHOWUSAGE;
5582  }
5583 
5584  channame = a->argv[3];
5585 
5586  ast_cli(a->fd, "Toggling EchoCancel on %s\n", channame);
5587 
5588  tmp = get_chan_by_ast_name(channame);
5589  if (!tmp) {
5590  ast_cli(a->fd, "Toggling EchoCancel %s failed Channel does not exist\n", channame);
5591  return CLI_SUCCESS;
5592  }
5593 
5594  tmp->toggle_ec = tmp->toggle_ec ? 0 : 1;
5595 
5596  if (tmp->toggle_ec) {
5597 #ifdef MISDN_1_2
5598  update_pipeline_config(tmp->bc);
5599 #else
5600  update_ec_config(tmp->bc);
5601 #endif
5602  manager_ec_enable(tmp->bc);
5603  } else {
5604  manager_ec_disable(tmp->bc);
5605  }
5606  chan_list_unref(tmp, "Done toggling echo cancel");
5607 
5608  return CLI_SUCCESS;
5609 }
void manager_ec_enable(struct misdn_bchannel *bc)
Definition: isdn_lib.c:4628
const int argc
Definition: cli.h:160
static int tmp()
Definition: bt_open.c:389
Definition: cli.h:152
static struct chan_list * get_chan_by_ast_name(const char *name)
Definition: chan_misdn.c:786
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
void manager_ec_disable(struct misdn_bchannel *bc)
Definition: isdn_lib.c:4677
static char * complete_ch(struct ast_cli_args *a)
Definition: chan_misdn.c:5654
const int fd
Definition: cli.h:159
const char *const * argv
Definition: cli.h:161
#define CLI_SHOWUSAGE
Definition: cli.h:45
char * command
Definition: cli.h:186
Channel call record structure.
Definition: chan_misdn.c:377
static int update_ec_config(struct misdn_bchannel *bc)
Definition: chan_misdn.c:5903
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44
struct misdn_bchannel * bc
Associated B channel structure.
Definition: chan_misdn.c:520
#define chan_list_unref(obj, debug)
Definition: chan_misdn.c:372
int toggle_ec
TRUE if echo canceller is enabled. Value is toggled.
Definition: chan_misdn.c:425

◆ hangup_chan()

static void hangup_chan ( struct chan_list ch,
struct misdn_bchannel bc 
)
static

Definition at line 8447 of file chan_misdn.c.

References chan_list::ast, ast_hangup(), ast_queue_hangup_with_cause(), misdn_bchannel::cause, cb_log, chan_list::need_hangup, chan_list::need_queue_hangup, misdn_bchannel::port, and send_cause2ast().

Referenced by ast_unreal_hangup(), cb_events(), do_immediate_setup(), and start_pbx().

8448 {
8449  int port = bc->port;
8450 
8451  if (!ch) {
8452  cb_log(1, port, "Cannot hangup chan, no ch\n");
8453  return;
8454  }
8455 
8456  cb_log(5, port, "hangup_chan called\n");
8457 
8458  if (ch->need_hangup) {
8459  cb_log(2, port, " --> hangup\n");
8460  ch->need_hangup = 0;
8461  ch->need_queue_hangup = 0;
8462  if (ch->ast && send_cause2ast(ch->ast, bc, ch)) {
8463  ast_hangup(ch->ast);
8464  }
8465  return;
8466  }
8467 
8468  if (!ch->need_queue_hangup) {
8469  cb_log(2, port, " --> No need to queue hangup\n");
8470  return;
8471  }
8472 
8473  ch->need_queue_hangup = 0;
8474  if (ch->ast) {
8475  if (send_cause2ast(ch->ast, bc, ch)) {
8477  cb_log(2, port, " --> queue_hangup\n");
8478  }
8479  } else {
8480  cb_log(1, port, "Cannot hangup chan, no ast\n");
8481  }
8482 }
int need_hangup
TRUE if a channel can be hung up by calling asterisk directly when done.
Definition: chan_misdn.c:397
int need_queue_hangup
TRUE if a hangup needs to be queued.
Definition: chan_misdn.c:392
struct ast_channel * ast
Associated Asterisk channel structure.
Definition: chan_misdn.c:515
int ast_queue_hangup_with_cause(struct ast_channel *chan, int cause)
Queue a hangup frame with hangupcause set.
Definition: channel.c:1166
static int send_cause2ast(struct ast_channel *ast, struct misdn_bchannel *bc, struct chan_list *ch)
Definition: chan_misdn.c:8725
int port
Logical Layer 1 port associated with this B channel.
Definition: isdn_lib.h:370
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2548
int cause
Q.931 Cause for disconnection code (received)
Definition: isdn_lib.h:671
void(* cb_log)(int level, int port, char *tmpl,...)
Definition: isdn_lib.c:32

◆ hanguptone_indicate()

static void hanguptone_indicate ( struct chan_list cl)
static

Definition at line 7738 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().

7739 {
7741 }
void misdn_lib_send_tone(struct misdn_bchannel *bc, enum tone_e tone)
Definition: isdn_lib.c:4596
struct misdn_bchannel * bc
Associated B channel structure.
Definition: chan_misdn.c:520

◆ import_ch()

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 8786 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, tmp(), misdn_bchannel::uu, and misdn_bchannel::uulen.

Referenced by misdn_call().

8787 {
8788  const char *tmp;
8789 
8790  ast_channel_lock(chan);
8791  tmp = pbx_builtin_getvar_helper(chan, "MISDN_ADDRESS_COMPLETE");
8792  if (tmp && (atoi(tmp) == 1)) {
8793  bc->sending_complete = 1;
8794  }
8795 
8796  tmp = pbx_builtin_getvar_helper(chan, "MISDN_USERUSER");
8797  if (tmp) {
8798  ast_log(LOG_NOTICE, "MISDN_USERUSER: %s\n", tmp);
8799  ast_copy_string(bc->uu, tmp, sizeof(bc->uu));
8800  bc->uulen = strlen(bc->uu);
8801  }
8802 
8803  tmp = pbx_builtin_getvar_helper(chan, "MISDN_KEYPAD");
8804  if (tmp) {
8805  ast_copy_string(bc->keypad, tmp, sizeof(bc->keypad));
8806  }
8807  ast_channel_unlock(chan);
8808 }
char keypad[MISDN_MAX_KEYPAD_LEN]
Q.931 Keypad Facility IE contents.
Definition: isdn_lib.h:647
#define ast_channel_lock(chan)
Definition: channel.h:2945
int uulen
User-User information string length in uu[].
Definition: isdn_lib.h:666
char uu[256]
User-User information string.
Definition: isdn_lib.h:663
static int tmp()
Definition: bt_open.c:389
int sending_complete
TRUE if all digits necessary to complete the call are available. No more INFORMATION messages are nee...
Definition: isdn_lib.h:470
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.
#define ast_log
Definition: astobj2.c:42
#define LOG_NOTICE
Definition: logger.h:263
#define ast_channel_unlock(chan)
Definition: channel.h:2946
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401

◆ load_module()

static int load_module ( void  )
static

Load the module.

Module loading including tests for configuration or dependencies. This function can return AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_DECLINE, or AST_MODULE_LOAD_SUCCESS. If a dependency or environment variable fails tests return AST_MODULE_LOAD_FAILURE. If the module can not load the configuration file or other non-critical problem return AST_MODULE_LOAD_DECLINE. On success return AST_MODULE_LOAD_SUCCESS.

Definition at line 11315 of file chan_misdn.c.

References ast_calloc, ast_channel_register(), ast_cli_register_multiple, ast_custom_function_register, ast_format_alaw, ast_format_cap_alloc, ast_format_cap_append, AST_FORMAT_CAP_FLAG_DEFAULT, ast_free, ast_log, ast_malloc, AST_MODULE_LOAD_DECLINE, ast_mutex_init, ast_register_application, ast_strlen_zero, BUFFERSIZE, ast_channel_tech::capabilities, misdn_lib_iface::cb_event, cb_events(), chan_misdn_jb_empty(), chan_misdn_log(), g_config_initialized, global_tracefile, 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_facility_exec(), MISDN_GEN_DEBUG, MISDN_GEN_NTDEBUGFILE, MISDN_GEN_NTDEBUGFLAGS, MISDN_GEN_NTKEEPCALLS, MISDN_GEN_TRACEFILE, misdn_l1_task(), misdn_lib_init(), misdn_lib_maxports_get(), misdn_lib_nt_debug_init(), misdn_lib_nt_keepcalls(), misdn_ports, misdn_set_opt_exec(), misdn_tasks_add(), NULL, and unload_module().

Referenced by chan_misdn_log().

11316 {
11317  int i, port;
11318  int ntflags = 0, ntkc = 0;
11319  char ports[256] = "";
11320  char tempbuf[BUFFERSIZE + 1];
11321  char ntfile[BUFFERSIZE + 1];
11322  struct misdn_lib_iface iface = {
11323  .cb_event = cb_events,
11324  .cb_log = chan_misdn_log,
11325  .cb_jb_empty = chan_misdn_jb_empty,
11326  };
11327 
11328 
11330  return AST_MODULE_LOAD_DECLINE;
11331  }
11333 
11335 
11336  if (max_ports <= 0) {
11337  ast_log(LOG_ERROR, "Unable to initialize mISDN\n");
11338  return AST_MODULE_LOAD_DECLINE;
11339  }
11340 
11341  if (misdn_cfg_init(max_ports, 0)) {
11342  ast_log(LOG_ERROR, "Unable to initialize misdn_config.\n");
11343  return AST_MODULE_LOAD_DECLINE;
11344  }
11346 
11347 #if defined(AST_MISDN_ENHANCEMENTS)
11348  misdn_cc_init();
11349 #endif /* defined(AST_MISDN_ENHANCEMENTS) */
11350 
11351  misdn_debug = ast_malloc(sizeof(int) * (max_ports + 1));
11352  if (!misdn_debug) {
11353  ast_log(LOG_ERROR, "Out of memory for misdn_debug\n");
11354  return AST_MODULE_LOAD_DECLINE;
11355  }
11356  misdn_ports = ast_malloc(sizeof(int) * (max_ports + 1));
11357  if (!misdn_ports) {
11359  ast_log(LOG_ERROR, "Out of memory for misdn_ports\n");
11360  return AST_MODULE_LOAD_DECLINE;
11361  }
11363  for (i = 1; i <= max_ports; i++) {
11364  misdn_debug[i] = misdn_debug[0];
11365  misdn_ports[i] = i;
11366  }
11367  *misdn_ports = 0;
11368  misdn_debug_only = ast_calloc(max_ports + 1, sizeof(int));
11369  if (!misdn_debug_only) {
11372  ast_log(LOG_ERROR, "Out of memory for misdn_debug_only\n");
11373  return AST_MODULE_LOAD_DECLINE;
11374  }
11375 
11376  misdn_cfg_get(0, MISDN_GEN_TRACEFILE, tempbuf, sizeof(tempbuf));
11377  if (!ast_strlen_zero(tempbuf)) {
11378  tracing = 1;
11379  }
11380 
11381  misdn_in_calls = ast_malloc(sizeof(int) * (max_ports + 1));
11382  if (!misdn_in_calls) {
11386  ast_log(LOG_ERROR, "Out of memory for misdn_in_calls\n");
11387  return AST_MODULE_LOAD_DECLINE;
11388  }
11389  misdn_out_calls = ast_malloc(sizeof(int) * (max_ports + 1));
11390  if (!misdn_out_calls) {
11395  ast_log(LOG_ERROR, "Out of memory for misdn_out_calls\n");
11396  return AST_MODULE_LOAD_DECLINE;
11397  }
11398 
11399  for (i = 1; i <= max_ports; i++) {
11400  misdn_in_calls[i] = 0;
11401  misdn_out_calls[i] = 0;
11402  }
11403 
11406 
11409 
11410  if (!ast_strlen_zero(ports)) {
11411  chan_misdn_log(0, 0, "Got: %s from get_ports\n", ports);
11412  }
11413  if (misdn_lib_init(ports, &iface, NULL)) {
11414  chan_misdn_log(0, 0, "No te ports initialized\n");
11415  }
11416 
11417  misdn_cfg_get(0, MISDN_GEN_NTDEBUGFLAGS, &ntflags, sizeof(ntflags));
11418  misdn_cfg_get(0, MISDN_GEN_NTDEBUGFILE, &ntfile, sizeof(ntfile));
11419  misdn_cfg_get(0, MISDN_GEN_NTKEEPCALLS, &ntkc, sizeof(ntkc));
11420 
11421  misdn_lib_nt_keepcalls(ntkc);
11422  misdn_lib_nt_debug_init(ntflags, ntfile);
11423 
11425  ast_log(LOG_ERROR, "Unable to register channel class %s\n", misdn_type);
11426  unload_module();
11427  return AST_MODULE_LOAD_DECLINE;
11428  }
11429 
11431 
11432  ast_register_application("misdn_set_opt", misdn_set_opt_exec, "misdn_set_opt",
11433  "misdn_set_opt(:<opt><optarg>:<opt><optarg>...):\n"
11434  "Sets mISDN opts. and optargs\n"
11435  "\n"
11436  "The available options are:\n"
11437  " a - Have Asterisk detect DTMF tones on called channel\n"
11438  " c - Make crypted outgoing call, optarg is keyindex\n"
11439  " d - Send display text to called phone, text is the optarg\n"
11440  " e - Perform echo cancellation on this channel,\n"
11441  " takes taps as optarg (32,64,128,256)\n"
11442  " e! - Disable echo cancellation on this channel\n"
11443  " f - Enable fax detection\n"
11444  " h - Make digital outgoing call\n"
11445  " h1 - Make HDLC mode digital outgoing call\n"
11446  " i - Ignore detected DTMF tones, don't signal them to Asterisk,\n"
11447  " they will be transported inband.\n"
11448  " jb - Set jitter buffer length, optarg is length\n"
11449  " jt - Set jitter buffer upper threshold, optarg is threshold\n"
11450  " jn - Disable jitter buffer\n"
11451  " n - Disable mISDN DSP on channel.\n"
11452  " Disables: echo cancel, DTMF detection, and volume control.\n"
11453  " p - Caller ID presentation,\n"
11454  " optarg is either 'allowed' or 'restricted'\n"
11455  " s - Send Non-inband DTMF as inband\n"
11456  " vr - Rx gain control, optarg is gain\n"
11457  " vt - Tx gain control, optarg is gain\n"
11458  );
11459 
11460 
11461  ast_register_application("misdn_facility", misdn_facility_exec, "misdn_facility",
11462  "misdn_facility(<FACILITY_TYPE>|<ARG1>|..)\n"
11463  "Sends the Facility Message FACILITY_TYPE with \n"
11464  "the given Arguments to the current ISDN Channel\n"
11465  "Supported Facilities are:\n"
11466  "\n"
11467  "type=calldeflect args=Nr where to deflect\n"
11468 #if defined(AST_MISDN_ENHANCEMENTS)
11469  "type=callrerouting args=Nr where to deflect\n"
11470 #endif /* defined(AST_MISDN_ENHANCEMENTS) */
11471  );
11472 
11473 
11474  ast_register_application("misdn_check_l2l1", misdn_check_l2l1, "misdn_check_l2l1",
11475  "misdn_check_l2l1(<port>||g:<groupname>,timeout)\n"
11476  "Checks if the L2 and L1 are up on either the given <port> or\n"
11477  "on the ports in the group with <groupname>\n"
11478  "If the L1/L2 are down, check_l2l1 gets up the L1/L2 and waits\n"
11479  "for <timeout> seconds that this happens. Otherwise, nothing happens\n"
11480  "\n"
11481  "This application, ensures the L1/L2 state of the Ports in a group\n"
11482  "it is intended to make the pmp_l1_check option redundant and to\n"
11483  "fix a buggy switch config from your provider\n"
11484  "\n"
11485  "a sample dialplan would look like:\n\n"
11486  "exten => _X.,1,misdn_check_l2l1(g:out|2)\n"
11487  "exten => _X.,n,dial(mISDN/g:out/${EXTEN})\n"
11488  );
11489 
11490 #if defined(AST_MISDN_ENHANCEMENTS)
11491  ast_register_application(misdn_command_name, misdn_command_exec, misdn_command_name,
11492  "misdn_command(<command>[,<options>])\n"
11493  "The following commands are defined:\n"
11494  "cc-initialize\n"
11495  " Setup mISDN support for call completion\n"
11496  " Must call before doing any Dial() involving call completion.\n"
11497  "ccnr-request,${MISDN_CC_RECORD_ID},<notify-context>,<user-a-extension>,<priority>\n"
11498  " Request Call Completion No Reply activation\n"
11499  "ccbs-request,${MISDN_CC_RECORD_ID},<notify-context>,<user-a-extension>,<priority>\n"
11500  " Request Call Completion Busy Subscriber activation\n"
11501  "cc-b-free,${MISDN_CC_RECORD_ID},<notify-context>,<user-a-extension>,<priority>\n"
11502  " Set the dialplan location to notify when User-B is available but User-A is busy.\n"
11503  " Setting this dialplan location is optional.\n"
11504  "cc-a-busy,${MISDN_CC_RECORD_ID},<yes/no>\n"
11505  " Set the busy status of call completion User-A\n"
11506  "cc-deactivate,${MISDN_CC_RECORD_ID}\n"
11507  " Deactivate the identified call completion request\n"
11508  "\n"
11509  "MISDN_CC_RECORD_ID is set when Dial() returns and call completion is possible\n"
11510  "MISDN_CC_STATUS is set to ACTIVATED or ERROR after the call completion\n"
11511  "activation request.\n"
11512  "MISDN_ERROR_MSG is set to a descriptive message on error.\n"
11513  );
11514 
11515  ast_custom_function_register(&misdn_cc_function);
11516 #endif /* defined(AST_MISDN_ENHANCEMENTS) */
11517 
11519 
11520  /* start the l1 watchers */
11521 
11522  for (port = misdn_cfg_get_next_port(0); port >= 0; port = misdn_cfg_get_next_port(port)) {
11523  int l1timeout;
11524  misdn_cfg_get(port, MISDN_CFG_L1_TIMEOUT, &l1timeout, sizeof(l1timeout));
11525  if (l1timeout) {
11526  chan_misdn_log(4, 0, "Adding L1watcher task: port:%d timeout:%ds\n", port, l1timeout);
11527  misdn_tasks_add(l1timeout * 1000, misdn_l1_task, &misdn_ports[port]);
11528  }
11529  }
11530 
11531  chan_misdn_log(0, 0, "-- mISDN Channel Driver Registered --\n");
11532 
11533  return 0;
11534 }
int misdn_lib_maxports_get(void)
Definition: isdn_lib.c:4094
static void chan_misdn_log(int level, int port, char *tmpl,...)
Definition: chan_misdn.c:12768
int misdn_lib_init(char *portlist, struct misdn_lib_iface *iface, void *user_data)
Definition: isdn_lib.c:4143
void misdn_lib_nt_debug_init(int flags, char *file)
Definition: isdn_lib.c:4124
int misdn_cfg_get_next_port(int port)
Definition: misdn_config.c:929
descriptor for a cli entry.
Definition: cli.h:171
int misdn_cfg_init(int max_ports, int reload)
static int misdn_tasks_add(int timeout, ast_sched_cb callback, const void *data)
Definition: chan_misdn.c:3604
#define ast_cli_register_multiple(e, len)
Register multiple commands.
Definition: cli.h:265
int ast_channel_register(const struct ast_channel_tech *tech)
Register a channel technology (a new channel driver) Called by a channel module to register the kind ...
Definition: channel.c:539
static int * misdn_debug_only
Definition: chan_misdn.c:695
#define NULL
Definition: resample.c:96
int chan_misdn_jb_empty(struct misdn_bchannel *bc, char *buf, int len)
Definition: chan_misdn.c:12574
enum event_response_e(* cb_event)(enum event_e event, struct misdn_bchannel *bc, void *user_data)
Definition: isdn_lib.h:729
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define BUFFERSIZE
static int misdn_l1_task(const void *vdata)
Definition: chan_misdn.c:3619
static ast_mutex_t release_lock
Definition: chan_misdn.c:323
#define ast_log
Definition: astobj2.c:42
void misdn_cfg_get(int port, enum misdn_cfg_elements elem, void *buf, int bufsize)
Definition: misdn_config.c:569
static struct ast_cli_entry chan_misdn_clis[]
Definition: chan_misdn.c:5734
#define ast_register_application(app, execute, synopsis, description)
Register an application.
Definition: module.h:610
void misdn_cfg_get_ports_string(char *ports)
Generate a comma separated list of all active ports.
Definition: misdn_config.c:779
#define ast_format_cap_append(cap, format, framing)
Definition: format_cap.h:103
#define ast_malloc(len)
A wrapper for malloc()
Definition: astmm.h:193
static int max_ports
Definition: chan_misdn.c:696
#define ast_format_cap_alloc(flags)
Definition: format_cap.h:52
static char global_tracefile[BUFFERSIZE+1]
Definition: chan_misdn.c:127
void misdn_cfg_update_ptp(void)
void misdn_lib_nt_keepcalls(int kc)
Definition: isdn_lib.c:4112
#define LOG_ERROR
Definition: logger.h:285
static int misdn_check_l2l1(struct ast_channel *chan, const char *data)
Definition: chan_misdn.c:12291
static int tracing
Definition: chan_misdn.c:692
static int * misdn_debug
Definition: chan_misdn.c:694
struct ast_format_cap * capabilities
Definition: channel.h:633
static const char misdn_type[]
Definition: chan_misdn.c:690
static struct ast_channel_tech misdn_tech
Definition: chan_misdn.c:8130
static int unload_module(void)
Definition: chan_misdn.c:11262
#define ast_free(a)
Definition: astmm.h:182
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
static int * misdn_ports
Definition: chan_misdn.c:673
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78
static int * misdn_out_calls
Definition: chan_misdn.c:699
static int g_config_initialized
Definition: chan_misdn.c:129
struct ast_format * ast_format_alaw
Built-in cached alaw format.
Definition: format_cache.c:91
static int * misdn_in_calls
Definition: chan_misdn.c:698
#define ast_mutex_init(pmutex)
Definition: lock.h:184
static int misdn_facility_exec(struct ast_channel *chan, const char *data)
Definition: chan_misdn.c:12168
#define ast_custom_function_register(acf)
Register a custom function.
Definition: pbx.h:1508
static ast_mutex_t cl_te_lock
Definition: chan_misdn.c:705
static int misdn_set_opt_exec(struct ast_channel *chan, const char *data)
Definition: chan_misdn.c:12365
static enum event_response_e cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
Definition: chan_misdn.c:9917

◆ misdn_add_number_prefix()

static void misdn_add_number_prefix ( int  port,
enum mISDN_NUMBER_TYPE  number_type,
char *  number,
size_t  size 
)
static

Definition at line 3424 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().

3425 {
3426  enum misdn_cfg_elements type_prefix;
3427  char num_prefix[MISDN_MAX_NUMBER_LEN];
3428 
3429  /* Get prefix string. */
3430  switch (number_type) {
3431  case NUMTYPE_UNKNOWN:
3432  type_prefix = MISDN_CFG_TON_PREFIX_UNKNOWN;
3433  break;
3434  case NUMTYPE_INTERNATIONAL:
3435  type_prefix = MISDN_CFG_TON_PREFIX_INTERNATIONAL;
3436  break;
3437  case NUMTYPE_NATIONAL:
3438  type_prefix = MISDN_CFG_TON_PREFIX_NATIONAL;
3439  break;
3442  break;
3443  case NUMTYPE_SUBSCRIBER:
3444  type_prefix = MISDN_CFG_TON_PREFIX_SUBSCRIBER;
3445  break;
3446  case NUMTYPE_ABBREVIATED:
3447  type_prefix = MISDN_CFG_TON_PREFIX_ABBREVIATED;
3448  break;
3449  default:
3450  /* Type-of-number does not have a prefix that can be added. */
3451  return;
3452  }
3453  misdn_cfg_get(port, type_prefix, num_prefix, sizeof(num_prefix));
3454 
3455  misdn_prefix_string(num_prefix, number, size);
3456 }
misdn_cfg_elements
Number structure.
Definition: app_followme.c:154
void misdn_cfg_get(int port, enum misdn_cfg_elements elem, void *buf, int bufsize)
Definition: misdn_config.c:569
#define MISDN_MAX_NUMBER_LEN
Definition: isdn_lib.h:246
static void misdn_prefix_string(const char *str_prefix, char *str_main, size_t size)
Definition: chan_misdn.c:3381

◆ misdn_answer()

static int misdn_answer ( struct ast_channel ast)
static

Definition at line 6824 of file chan_misdn.c.

References AST_CAUSE_NETWORK_OUT_OF_ORDER, AST_CAUSE_PROTOCOL_ERROR, ast_channel_lock, ast_channel_unlock, ast_copy_string(), ast_log, ast_queue_hangup_with_cause(), ast_strlen_zero, ast_true(), chan_list::bc, chan_misdn_log(), misdn_bchannel::connected, misdn_bchannel::crypt_key, misdn_bchannel::dialed, EVENT_CONNECT, misdn_bchannel::fac_out, misdn_bchannel::hdlc, LOG_WARNING, MISDN_ASTERISK_TECH_PVT, MISDN_CONNECTED, misdn_lib_send_event(), misdn_bchannel::nodsp, misdn_bchannel::nojitter, misdn_party_dialing::number, misdn_party_id::number, misdn_party_id::number_plan, misdn_party_dialing::number_plan, misdn_party_id::number_type, misdn_party_dialing::number_type, misdn_bchannel::outgoing_colp, pbx_builtin_getvar_helper(), misdn_bchannel::port, misdn_party_id::presentation, misdn_bchannel::presentation, print_facility(), misdn_party_id::screening, start_bc_tones(), chan_list::state, stop_indicate(), and tmp().

6825 {
6826  struct chan_list *p;
6827  const char *tmp;
6828 
6829  if (!ast || !(p = MISDN_ASTERISK_TECH_PVT(ast))) {
6830  return -1;
6831  }
6832 
6833  chan_misdn_log(1, p ? (p->bc ? p->bc->port : 0) : 0, "* ANSWER:\n");
6834 
6835  if (!p) {
6836  ast_log(LOG_WARNING, " --> Channel not connected ??\n");
6838  }
6839 
6840  if (!p->bc) {
6841  chan_misdn_log(1, 0, " --> Got Answer, but there is no bc obj ??\n");
6842 
6844  }
6845 
6846  ast_channel_lock(ast);
6847  tmp = pbx_builtin_getvar_helper(ast, "CRYPT_KEY");
6848  if (!ast_strlen_zero(tmp)) {
6849  chan_misdn_log(1, p->bc->port, " --> Connection will be BF crypted\n");
6850  ast_copy_string(p->bc->crypt_key, tmp, sizeof(p->bc->crypt_key));
6851  } else {
6852  chan_misdn_log(3, p->bc->port, " --> Connection is without BF encryption\n");
6853  }
6854 
6855  tmp = pbx_builtin_getvar_helper(ast, "MISDN_DIGITAL_TRANS");
6856  if (!ast_strlen_zero(tmp) && ast_true(tmp)) {
6857  chan_misdn_log(1, p->bc->port, " --> Connection is transparent digital\n");
6858  p->bc->nodsp = 1;
6859  p->bc->hdlc = 0;
6860  p->bc->nojitter = 1;
6861  }
6862  ast_channel_unlock(ast);
6863 
6864  p->state = MISDN_CONNECTED;
6865  stop_indicate(p);
6866 
6867  if (ast_strlen_zero(p->bc->connected.number)) {
6868  chan_misdn_log(2,p->bc->port," --> empty connected number using dialed number\n");
6870 
6871  /*
6872  * Use the misdn_set_opt() application to set the presentation
6873  * before we answer or you can use the CONECTEDLINE() function
6874  * to set everything before using the Answer() application.
6875  */
6877  p->bc->connected.screening = 0; /* unscreened */
6880  }
6881 
6882  switch (p->bc->outgoing_colp) {
6883  case 1:/* restricted */
6884  case 2:/* blocked */
6885  p->bc->connected.presentation = 1;/* restricted */
6886  break;
6887  default:
6888  break;
6889  }
6890 
6891 #if defined(AST_MISDN_ENHANCEMENTS)
6892  if (p->bc->div_leg_3_tx_pending) {
6893  p->bc->div_leg_3_tx_pending = 0;
6894 
6895  /* Send DivertingLegInformation3 */
6896  p->bc->fac_out.Function = Fac_DivertingLegInformation3;
6897  p->bc->fac_out.u.DivertingLegInformation3.InvokeID = ++misdn_invoke_id;
6898  p->bc->fac_out.u.DivertingLegInformation3.PresentationAllowedIndicator =
6899  (p->bc->connected.presentation == 0) ? 1 : 0;
6900  print_facility(&p->bc->fac_out, p->bc);
6901  }
6902 #endif /* defined(AST_MISDN_ENHANCEMENTS) */
6904  start_bc_tones(p);
6905 
6906  return 0;
6907 }
static void chan_misdn_log(int level, int port, char *tmpl,...)
Definition: chan_misdn.c:12768
#define AST_CAUSE_PROTOCOL_ERROR
Definition: causes.h:144
#define ast_channel_lock(chan)
Definition: channel.h:2945
static int stop_indicate(struct chan_list *cl)
Definition: chan_misdn.c:7743
struct FacParm fac_out
Outbound FACILITY message function type and contents.
Definition: isdn_lib.h:512
char number[MISDN_MAX_NUMBER_LEN]
Phone number (Address)
Definition: isdn_lib.h:298
int nodsp
TRUE if we will not use jollys dsp.
Definition: isdn_lib.h:474
int presentation
User set presentation restriction code 0=Allowed, 1=Restricted, 2=Unavailable.
Definition: isdn_lib.h:600
#define AST_CAUSE_NETWORK_OUT_OF_ORDER
Definition: causes.h:120
#define LOG_WARNING
Definition: logger.h:274
static int tmp()
Definition: bt_open.c:389
int hdlc
TRUE if call made in digital HDLC mode.
Definition: isdn_lib.h:635
int outgoing_colp
Select what to do with outgoing COLP information.
Definition: isdn_lib.h:594
int presentation
Number presentation restriction code 0=Allowed, 1=Restricted, 2=Unavailable.
Definition: isdn_lib.h:277
char crypt_key[255]
Blowfish encryption key string (secret)
Definition: isdn_lib.h:529
#define MISDN_ASTERISK_TECH_PVT(ast)
Definition: chan_misdn.c:683
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.
int ast_queue_hangup_with_cause(struct ast_channel *chan, int cause)
Queue a hangup frame with hangupcause set.
Definition: channel.c:1166
#define ast_strlen_zero(foo)
Definition: strings.h:52
static void print_facility(const struct FacParm *fac, const struct misdn_bchannel *bc)
Definition: chan_misdn.c:2762
#define ast_log
Definition: astobj2.c:42
char number[MISDN_MAX_NUMBER_LEN]
Dialed/Called Phone Number (Address)
Definition: isdn_lib.h:266
enum mISDN_NUMBER_TYPE number_type
Type-of-number in ISDN terms for the number.
Definition: isdn_lib.h:285
int nojitter
TRUE if we will not use the jitter buffer system.
Definition: isdn_lib.h:477
enum misdn_chan_state state
State of the channel.
Definition: chan_misdn.c:386
struct misdn_party_id connected
Connected-Party/Connected-Line ID information struct.
Definition: isdn_lib.h:353
enum mISDN_NUMBER_TYPE number_type
Type-of-number in ISDN terms for the dialed/called number.
Definition: isdn_lib.h:260
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true". This function checks to see whether a string passed to it is an indication of an "true" value. It checks to see if the string is "yes", "true", "y", "t", "on" or "1".
Definition: main/utils.c:1951
int port
Logical Layer 1 port associated with this B channel.
Definition: isdn_lib.h:370
struct misdn_party_dialing dialed
Dialed/Called information struct.
Definition: isdn_lib.h:337
#define ast_channel_unlock(chan)
Definition: channel.h:2946
Channel call record structure.
Definition: chan_misdn.c:377
static int start_bc_tones(struct chan_list *cl)
Definition: chan_misdn.c:7764
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
int misdn_lib_send_event(struct misdn_bchannel *bc, enum event_e event)
Definition: isdn_lib.c:3523
struct misdn_bchannel * bc
Associated B channel structure.
Definition: chan_misdn.c:520
int screening
Number screening code 0=Unscreened, 1=Passed Screen, 2=Failed Screen, 3=Network Number.
Definition: isdn_lib.h:282
enum mISDN_NUMBER_PLAN number_plan
Type-of-number numbering plan.
Definition: isdn_lib.h:288
enum mISDN_NUMBER_PLAN number_plan
Type-of-number numbering plan.
Definition: isdn_lib.h:263

◆ misdn_attempt_transfer()

static int misdn_attempt_transfer ( struct chan_list active_ch,
struct chan_list held_ch 
)
static

Definition at line 8619 of file chan_misdn.c.

References chan_list::ast, ast_bridge_transfer_attended(), AST_BRIDGE_TRANSFER_SUCCESS, ast_channel_lock_both, ast_channel_name(), ast_channel_ref, ast_channel_unlock, ast_channel_unref, chan_misdn_log(), chan_list::hold, MISDN_ALERTING, MISDN_CONNECTED, MISDN_HOLD_TRANSFER, MISDN_PROCEEDING, MISDN_PROGRESS, hold_info::port, retval, hold_info::state, and chan_list::state.

Referenced by cb_events().

8620 {
8621  int retval;
8622  enum ast_transfer_result xfer_res;
8623  struct ast_channel *to_target;
8624  struct ast_channel *to_transferee;
8625 
8626  switch (active_ch->state) {
8627  case MISDN_PROCEEDING:
8628  case MISDN_PROGRESS:
8629  case MISDN_ALERTING:
8630  case MISDN_CONNECTED:
8631  break;
8632  default:
8633  return -1;
8634  }
8635 
8636  ast_channel_lock_both(held_ch->ast, active_ch->ast);
8637  to_target = active_ch->ast;
8638  to_transferee = held_ch->ast;
8639  chan_misdn_log(1, held_ch->hold.port, "TRANSFERRING %s to %s\n",
8640  ast_channel_name(to_transferee), ast_channel_name(to_target));
8641  held_ch->hold.state = MISDN_HOLD_TRANSFER;
8642  ast_channel_ref(to_target);
8643  ast_channel_ref(to_transferee);
8644  ast_channel_unlock(to_target);
8645  ast_channel_unlock(to_transferee);
8646 
8647  retval = 0;
8648  xfer_res = ast_bridge_transfer_attended(to_transferee, to_target);
8649  if (xfer_res != AST_BRIDGE_TRANSFER_SUCCESS) {
8650  retval = -1;
8651  }
8652 
8653  ast_channel_unref(to_target);
8654  ast_channel_unref(to_transferee);
8655  return retval;
8656 }
static void chan_misdn_log(int level, int port, char *tmpl,...)
Definition: chan_misdn.c:12768
Main Channel structure associated with a channel.
enum ast_transfer_result ast_bridge_transfer_attended(struct ast_channel *to_transferee, struct ast_channel *to_transfer_target)
Attended transfer.
Definition: bridge.c:4729
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2981
struct hold_info hold
HELD channel call information.
Definition: chan_misdn.c:535
ast_transfer_result
Definition: bridge.h:1115
struct ast_channel * ast
Associated Asterisk channel structure.
Definition: chan_misdn.c:515
enum misdn_chan_state state
State of the channel.
Definition: chan_misdn.c:386
int port
Logical port the channel call record is HELD on because the B channel is no longer associated...
Definition: chan_misdn.c:362
#define ast_channel_unlock(chan)
Definition: channel.h:2946
enum misdn_hold_state state
Call HOLD state.
Definition: chan_misdn.c:357
#define ast_channel_lock_both(chan1, chan2)
Lock two channels.
Definition: channel.h:2952
#define ast_channel_ref(c)
Increase channel reference count.
Definition: channel.h:2970
const char * ast_channel_name(const struct ast_channel *chan)
static ENTRY retval
Definition: hsearch.c:50

◆ misdn_call()

static int misdn_call ( struct ast_channel ast,
const char *  dest,
int  timeout 
)
static

we should have l3id after sending setup

Definition at line 6554 of file chan_misdn.c.

References add_out_calls(), args, AST_APP_ARG, AST_CAUSE_NORMAL_CIRCUIT_CONGESTION, AST_CAUSE_NORMAL_CLEARING, AST_CAUSE_NORMAL_TEMPORARY_FAILURE, ast_channel_caller(), ast_channel_connected_effective_id(), ast_channel_context(), ast_channel_exten_set(), ast_channel_hangupcause_set(), ast_channel_name(), ast_channel_transfercapability(), 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, misdn_bchannel::caller, misdn_bchannel::capability, chan_misdn_log(), misdn_party_redirecting::count, debug_numtype(), misdn_bchannel::dialed, ENOCHAN, EVENT_SETUP, ext, misdn_bchannel::fac_out, misdn_party_redirecting::from, misdn_bchannel::hdlc, ast_party_caller::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(), misdn_party_id::name, ast_party_id::name, misdn_bchannel::nt, misdn_party_dialing::number, misdn_party_id::number, ast_party_id::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_party_id::presentation, misdn_bchannel::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_name::str, ast_party_number::str, ast_party_id::tag, tmp(), update_config(), ast_party_name::valid, and ast_party_number::valid.

6555 {
6556  int port = 0;
6557  int r;
6558  int exceed;
6559  int number_type;
6560  struct chan_list *ch;
6561  struct misdn_bchannel *newbc;
6562  char *dest_cp;
6563  int append_msn = 0;
6564 
6566  AST_APP_ARG(intf); /* The interface token is discarded. */
6567  AST_APP_ARG(ext); /* extension token */
6568  AST_APP_ARG(opts); /* options token */
6569  );
6570 
6571  if (!ast) {
6572  ast_log(LOG_WARNING, " --> ! misdn_call called on ast_channel *ast where ast == NULL\n");
6573  return -1;
6574  }
6575 
6576  if (((ast_channel_state(ast) != AST_STATE_DOWN) && (ast_channel_state(ast) != AST_STATE_RESERVED)) || !dest) {
6577  ast_log(LOG_WARNING, " --> ! misdn_call called on %s, neither down nor reserved (or dest==NULL)\n", ast_channel_name(ast));
6580  return -1;
6581  }
6582 
6583  ch = MISDN_ASTERISK_TECH_PVT(ast);
6584  if (!ch) {
6585  ast_log(LOG_WARNING, " --> ! misdn_call called on %s, chan_list *ch==NULL\n", ast_channel_name(ast));
6588  return -1;
6589  }
6590 
6591  newbc = ch->bc;
6592  if (!newbc) {
6593  ast_log(LOG_WARNING, " --> ! misdn_call called on %s, newbc==NULL\n", ast_channel_name(ast));
6596  return -1;
6597  }
6598 
6599  port = newbc->port;
6600 
6601 #if defined(AST_MISDN_ENHANCEMENTS)
6602  if ((ch->peer = misdn_cc_caller_get(ast))) {
6603  chan_misdn_log(3, port, " --> Found CC caller data, peer:%s\n",
6604  ch->peer->chan ? "available" : "NULL");
6605  }
6606 
6607  if (ch->record_id != -1) {
6608  struct misdn_cc_record *cc_record;
6609 
6610  /* This is a call completion retry call */
6611  AST_LIST_LOCK(&misdn_cc_records_db);
6612  cc_record = misdn_cc_find_by_id(ch->record_id);
6613  if (!cc_record) {
6614  AST_LIST_UNLOCK(&misdn_cc_records_db);
6615  ast_log(LOG_WARNING, " --> ! misdn_call called on %s, cc_record==NULL\n", ast_channel_name(ast));
6618  return -1;
6619  }
6620 
6621  /* Setup calling parameters to retry the call. */
6622  newbc->dialed = cc_record->redial.dialed;
6623  newbc->caller = cc_record->redial.caller;
6624  memset(&newbc->redirecting, 0, sizeof(newbc->redirecting));
6625  newbc->capability = cc_record->redial.capability;
6626  newbc->hdlc = cc_record->redial.hdlc;
6627  newbc->sending_complete = 1;
6628 
6629  if (cc_record->ptp) {
6630  newbc->fac_out.Function = Fac_CCBS_T_Call;
6631  newbc->fac_out.u.CCBS_T_Call.InvokeID = ++misdn_invoke_id;
6632  } else {
6633  newbc->fac_out.Function = Fac_CCBSCall;
6634  newbc->fac_out.u.CCBSCall.InvokeID = ++misdn_invoke_id;
6635  newbc->fac_out.u.CCBSCall.CCBSReference = cc_record->mode.ptmp.reference_id;
6636  }
6637  AST_LIST_UNLOCK(&misdn_cc_records_db);
6638 
6639  ast_channel_exten_set(ast, newbc->dialed.number);
6640 
6641  chan_misdn_log(1, port, "* Call completion to: %s\n", newbc->dialed.number);
6642  chan_misdn_log(2, port, " --> * tech:%s context:%s\n", ast_channel_name(ast), ast_channel_context(ast));
6643  } else
6644 #endif /* defined(AST_MISDN_ENHANCEMENTS) */
6645  {
6646  struct ast_party_id connected_id = ast_channel_connected_effective_id(ast);
6647 
6648  /*
6649  * dest is ---v
6650  * Dial(mISDN/g:group_name[/extension[/options]])
6651  * Dial(mISDN/port[:preselected_channel][/extension[/options]])
6652  *
6653  * The dial extension could be empty if you are using MISDN_KEYPAD
6654  * to control ISDN provider features.
6655  */
6656  dest_cp = ast_strdupa(dest);
6657  AST_NONSTANDARD_APP_ARGS(args, dest_cp, '/');
6658  if (!args.ext) {
6659  args.ext = "";
6660  }
6661 
6662  chan_misdn_log(1, port, "* CALL: %s\n", dest);
6663  chan_misdn_log(2, port, " --> * dialed:%s tech:%s context:%s\n", args.ext, ast_channel_name(ast), ast_channel_context(ast));
6664 
6665  ast_channel_exten_set(ast, args.ext);
6666  ast_copy_string(newbc->dialed.number, args.ext, sizeof(newbc->dialed.number));
6667 
6668  if (ast_strlen_zero(newbc->caller.name)
6669  && connected_id.name.valid
6670  && !ast_strlen_zero(connected_id.name.str)) {
6671  ast_copy_string(newbc->caller.name, connected_id.name.str, sizeof(newbc->caller.name));
6672  chan_misdn_log(3, port, " --> * set caller:\"%s\" <%s>\n", newbc->caller.name, newbc->caller.number);
6673  }
6674  if (ast_strlen_zero(newbc->caller.number)
6675  && connected_id.number.valid
6676  && !ast_strlen_zero(connected_id.number.str)) {
6677  ast_copy_string(newbc->caller.number, connected_id.number.str, sizeof(newbc->caller.number));
6678  chan_misdn_log(3, port, " --> * set caller:\"%s\" <%s>\n", newbc->caller.name, newbc->caller.number);
6679  }
6680 
6681  misdn_cfg_get(port, MISDN_CFG_APPEND_MSN_TO_CALLERID_TAG, &append_msn, sizeof(append_msn));
6682  if (append_msn) {
6683  strncat(newbc->incoming_cid_tag, "_", sizeof(newbc->incoming_cid_tag) - strlen(newbc->incoming_cid_tag) - 1);
6684  strncat(newbc->incoming_cid_tag, newbc->caller.number, sizeof(newbc->incoming_cid_tag) - strlen(newbc->incoming_cid_tag) - 1);
6685  }
6686 
6688 
6689  misdn_cfg_get(port, MISDN_CFG_LOCALDIALPLAN, &number_type, sizeof(number_type));
6690  if (number_type < 0) {
6691  if (connected_id.number.valid) {
6692  newbc->caller.number_type = ast_to_misdn_ton(connected_id.number.plan);
6693  newbc->caller.number_plan = ast_to_misdn_plan(connected_id.number.plan);
6694  } else {
6696  newbc->caller.number_plan = NUMPLAN_ISDN;
6697  }
6698  } else {
6699  /* Force us to send in SETUP message */
6700  newbc->caller.number_type = number_type;
6701  newbc->caller.number_plan = NUMPLAN_ISDN;
6702  }
6703  debug_numtype(port, newbc->caller.number_type, "LTON");
6704 
6706  pbx_builtin_setvar_helper(ast, "TRANSFERCAPABILITY", ast_transfercapability2str(newbc->capability));
6708  chan_misdn_log(2, port, " --> * Call with flag Digital\n");
6709  }
6710 
6711  /* update caller screening and presentation */
6712  update_config(ch);
6713 
6714  /* fill in some ies from channel dialplan variables */
6715  import_ch(ast, newbc, ch);
6716 
6717  /* Finally The Options Override Everything */
6718  if (!ast_strlen_zero(args.opts)) {
6719  misdn_set_opt_exec(ast, args.opts);
6720  } else {
6721  chan_misdn_log(2, port, "NO OPTS GIVEN\n");
6722  }
6723  if (newbc->set_presentation) {
6724  newbc->caller.presentation = newbc->presentation;
6725  }
6726 
6727  misdn_copy_redirecting_from_ast(newbc, ast);
6728  switch (newbc->outgoing_colp) {
6729  case 1:/* restricted */
6730  case 2:/* blocked */
6731  newbc->redirecting.from.presentation = 1;/* restricted */
6732  break;
6733  default:
6734  break;
6735  }
6736 #if defined(AST_MISDN_ENHANCEMENTS)
6737  if (newbc->redirecting.from.number[0] && misdn_lib_is_ptp(port)) {
6738  if (newbc->redirecting.count < 1) {
6739  newbc->redirecting.count = 1;
6740  }
6741 
6742  /* Create DivertingLegInformation2 facility */
6743  newbc->fac_out.Function = Fac_DivertingLegInformation2;
6744  newbc->fac_out.u.DivertingLegInformation2.InvokeID = ++misdn_invoke_id;
6745  newbc->fac_out.u.DivertingLegInformation2.DivertingPresent = 1;
6746  misdn_PresentedNumberUnscreened_fill(
6747  &newbc->fac_out.u.DivertingLegInformation2.Diverting,
6748  &newbc->redirecting.from);
6749  switch (newbc->outgoing_colp) {
6750  case 2:/* blocked */
6751  /* Block the number going out */
6752  newbc->fac_out.u.DivertingLegInformation2.Diverting.Type = 1;/* presentationRestricted */
6753 
6754  /* Don't tell about any previous diversions or why for that matter. */
6755  newbc->fac_out.u.DivertingLegInformation2.DiversionCounter = 1;
6756  newbc->fac_out.u.DivertingLegInformation2.DiversionReason = 0;/* unknown */
6757  break;
6758  default:
6759  newbc->fac_out.u.DivertingLegInformation2.DiversionCounter =
6760  newbc->redirecting.count;
6761  newbc->fac_out.u.DivertingLegInformation2.DiversionReason =
6762  misdn_to_diversion_reason(newbc->redirecting.reason);
6763  break;
6764  }
6765  newbc->fac_out.u.DivertingLegInformation2.OriginalCalledPresent = 0;
6766  if (1 < newbc->fac_out.u.DivertingLegInformation2.DiversionCounter) {
6767  newbc->fac_out.u.DivertingLegInformation2.OriginalCalledPresent = 1;
6768  newbc->fac_out.u.DivertingLegInformation2.OriginalCalled.Type = 2;/* numberNotAvailableDueToInterworking */
6769  }
6770 
6771  /*
6772  * Expect a DivertingLegInformation3 to update the COLR of the
6773  * redirecting-to party we are attempting to call now.
6774  */
6775  newbc->div_leg_3_rx_wanted = 1;
6776  }
6777 #endif /* defined(AST_MISDN_ENHANCEMENTS) */
6778  }
6779 
6780  exceed = add_out_calls(port);
6781  if (exceed != 0) {
6782  char tmp[16];
6783 
6784  snprintf(tmp, sizeof(tmp), "%d", exceed);
6785  pbx_builtin_setvar_helper(ast, "MAX_OVERFLOW", tmp);
6788  return -1;
6789  }
6790 
6791 #if defined(AST_MISDN_ENHANCEMENTS)
6792  if (newbc->fac_out.Function != Fac_None) {
6793  print_facility(&newbc->fac_out, newbc);
6794  }
6795 #endif /* defined(AST_MISDN_ENHANCEMENTS) */
6796  r = misdn_lib_send_event(newbc, EVENT_SETUP);
6797 
6798  /** we should have l3id after sending setup **/
6799  ch->l3id = newbc->l3_id;
6800 
6801  if (r == -ENOCHAN) {
6802  chan_misdn_log(0, port, " --> * Theres no Channel at the moment .. !\n");
6803  chan_misdn_log(1, port, " --> * SEND: State Down pid:%d\n", newbc ? newbc->pid : -1);
6806  return -1;
6807  }
6808 
6809  chan_misdn_log(2, port, " --> * SEND: State Dialing pid:%d\n", newbc ? newbc->pid : 1);
6810 
6813 
6814  if (newbc->nt) {
6815  stop_bc_tones(ch);
6816  }
6817 
6818  ch->state = MISDN_CALLING;
6819 
6820  return 0;
6821 }
struct ast_party_caller * ast_channel_caller(struct ast_channel *chan)
static void chan_misdn_log(int level, int port, char *tmpl,...)
Definition: chan_misdn.c:12768
Information needed to identify an endpoint in a call.
Definition: channel.h:339
char * str
Subscriber phone number (Malloced)
Definition: channel.h:292
void debug_numtype(int port, int numtype, char *type)
Definition: chan_misdn.c:5853
struct FacParm fac_out
Outbound FACILITY message function type and contents.
Definition: isdn_lib.h:512
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
char number[MISDN_MAX_NUMBER_LEN]
Phone number (Address)
Definition: isdn_lib.h:298
static void update_config(struct chan_list *ch)
Updates caller ID information from config.
Definition: chan_misdn.c:5761
unsigned short ast_channel_transfercapability(const struct ast_channel *chan)
#define AST_CAUSE_NORMAL_TEMPORARY_FAILURE
Definition: causes.h:121
int presentation
User set presentation restriction code 0=Allowed, 1=Restricted, 2=Unavailable.
Definition: isdn_lib.h:600
struct ast_party_name name
Subscriber name.
Definition: channel.h:341
void ast_channel_hangupcause_set(struct ast_channel *chan, int value)
#define LOG_WARNING
Definition: logger.h:274
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
char incoming_cid_tag[MISDN_MAX_NAME_LEN]
Incoming Caller ID string tag for special purpose.
Definition: isdn_lib.h:348
static int tmp()
Definition: bt_open.c:389
int hdlc
TRUE if call made in digital HDLC mode.
Definition: isdn_lib.h:635
int add_out_calls(int port)
Definition: chan_misdn.c:8859
B channel control structure.
Definition: isdn_lib.h:324
int outgoing_colp
Select what to do with outgoing COLP information.
Definition: isdn_lib.h:594
int presentation
Number presentation restriction code 0=Allowed, 1=Restricted, 2=Unavailable.
Definition: isdn_lib.h:277
int sending_complete
TRUE if all digits necessary to complete the call are available. No more INFORMATION messages are nee...
Definition: isdn_lib.h:470
ast_channel_state
ast_channel states
Definition: channelstate.h:35
char * str
Subscriber name (Malloced)
Definition: channel.h:265
#define MISDN_ASTERISK_TECH_PVT(ast)
Definition: chan_misdn.c:683
int capability
SETUP message bearer capability field code value.
Definition: isdn_lib.h:609
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
const char * args
#define AST_CAUSE_NORMAL_CIRCUIT_CONGESTION
Definition: causes.h:119
void import_ch(struct ast_channel *chan, struct misdn_bchannel *bc, struct chan_list *ch)
Import parameters from the dialplan environment variables.
Definition: chan_misdn.c:8786
const char * ext
Definition: http.c:147
#define ast_strlen_zero(foo)
Definition: strings.h:52
static int stop_bc_tones(struct chan_list *cl)
Definition: chan_misdn.c:7772
static void print_facility(const struct FacParm *fac, const struct misdn_bchannel *bc)
Definition: chan_misdn.c:2762
struct ast_party_id id
Caller party ID.
Definition: channel.h:421
#define ast_log
Definition: astobj2.c:42
int set_presentation
TRUE if the user set the presentation restriction code.
Definition: isdn_lib.h:603
char number[MISDN_MAX_NUMBER_LEN]
Dialed/Called Phone Number (Address)
Definition: isdn_lib.h:266
void misdn_cfg_get(int port, enum misdn_cfg_elements elem, void *buf, int bufsize)
Definition: misdn_config.c:569
#define AST_CAUSE_NORMAL_CLEARING
Definition: causes.h:105
int nt
TRUE if NT side of protocol (TE otherwise)
Definition: isdn_lib.h:364
enum mISDN_NUMBER_TYPE number_type
Type-of-number in ISDN terms for the number.
Definition: isdn_lib.h:285
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
struct misdn_party_id caller
Originating/Caller ID information struct.
Definition: isdn_lib.h:343
char name[MISDN_MAX_NAME_LEN]
Subscriber Name.
Definition: isdn_lib.h:295
enum misdn_chan_state state
State of the channel.
Definition: chan_misdn.c:386
int misdn_lib_is_ptp(int port)
Definition: isdn_lib.c:128
int pid
B channel process ID (1-5000)
Definition: isdn_lib.h:402
struct misdn_party_id from
Who is redirecting the call (Sent to the party the call is redirected toward)
Definition: isdn_lib.h:307
struct ast_party_id ast_channel_connected_effective_id(struct ast_channel *chan)
int plan
Q.931 Type-Of-Number and Numbering-Plan encoded fields.
Definition: channel.h:294
#define AST_NONSTANDARD_APP_ARGS(args, parse, sep)
Performs the &#39;nonstandard&#39; argument separation process for an application.
struct misdn_party_redirecting redirecting
Redirecting information struct (Where a call diversion or transfer was invoked)
Definition: isdn_lib.h:358
int port
Logical Layer 1 port associated with this B channel.
Definition: isdn_lib.h:370
struct misdn_party_dialing dialed
Dialed/Called information struct.
Definition: isdn_lib.h:337
static void misdn_copy_redirecting_from_ast(struct misdn_bchannel *bc, struct ast_channel *ast)
Definition: chan_misdn.c:6382
Channel call record structure.
Definition: chan_misdn.c:377
static enum mISDN_NUMBER_TYPE ast_to_misdn_ton(unsigned ast_number_type)
Definition: chan_misdn.c:1916
unsigned int l3id
From associated B channel: Layer 3 process ID.
Definition: chan_misdn.c:541
void ast_channel_exten_set(struct ast_channel *chan, const char *value)
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name...
char * tag
User-set "tag".
Definition: channel.h:355
enum mISDN_REDIRECTING_REASON reason
Reason a call is being redirected (Q.931 field value)
Definition: isdn_lib.h:313
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
const char * ast_channel_name(const struct ast_channel *chan)
int ast_setstate(struct ast_channel *chan, enum ast_channel_state)
Change the state of a channel.
Definition: channel.c:7486
char * ast_transfercapability2str(int transfercapability) attribute_const
Gives the string form of a given transfer capability.
Definition: channel.c:678
int misdn_lib_send_event(struct misdn_bchannel *bc, enum event_e event)
Definition: isdn_lib.c:3523
const char * ast_channel_context(const struct ast_channel *chan)
unsigned char valid
TRUE if the name information is valid/present.
Definition: channel.h:280
struct misdn_bchannel * bc
Associated B channel structure.
Definition: chan_misdn.c:520
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
unsigned char valid
TRUE if the number information is valid/present.
Definition: channel.h:298
enum mISDN_NUMBER_PLAN number_plan
Type-of-number numbering plan.
Definition: isdn_lib.h:288
static int misdn_set_opt_exec(struct ast_channel *chan, const char *data)
Definition: chan_misdn.c:12365
int count
Number of times the call has been redirected.
Definition: isdn_lib.h:316
int l3_id
Layer 3 process ID.
Definition: isdn_lib.h:399
#define AST_APP_ARG(name)
Define an application argument.
static enum mISDN_NUMBER_PLAN ast_to_misdn_plan(unsigned ast_number_plan)
Definition: chan_misdn.c:2042
struct ast_party_number number
Subscriber phone number.
Definition: channel.h:343

◆ misdn_chan_is_valid()

static int misdn_chan_is_valid ( struct chan_list ch)
static

Definition at line 749 of file chan_misdn.c.

References chan_list::ast, ast_mutex_lock, ast_mutex_unlock, chan_list_ref, chan_list::next, NULL, and tmp().

Referenced by misdn_hangup().

750 {
751  struct chan_list *list;
752 
754  for (list = cl_te; list; list = list->next) {
755  if (list == ch) {
757  return 1;
758  }
759  }
761 
762  return 0;
763 }
struct chan_list * next
Next channel call record in the list.
Definition: chan_misdn.c:608
#define ast_mutex_lock(a)
Definition: lock.h:187
static struct chan_list * cl_te
Global channel call record list head.
Definition: chan_misdn.c:704
Channel call record structure.
Definition: chan_misdn.c:377
static ast_mutex_t cl_te_lock
Definition: chan_misdn.c:705
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ misdn_check_l2l1()

static int misdn_check_l2l1 ( struct ast_channel chan,
const char *  data 
)
static

Definition at line 12291 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(), misdn_lib_port_up(), parse(), and timeout.

Referenced by load_module().

12292 {
12293  char *parse;
12294  char group[BUFFERSIZE + 1];
12295  char *port_str;
12296  int port = 0;
12297  int timeout;
12298  int dowait = 0;
12299  int port_up;
12300 
12302  AST_APP_ARG(grouppar);
12303  AST_APP_ARG(timeout);
12304  );
12305 
12306  if (ast_strlen_zero((char *) data)) {
12307  ast_log(LOG_WARNING, "misdn_check_l2l1 Requires arguments\n");
12308  return -1;
12309  }
12310 
12311  parse = ast_strdupa(data);
12312  AST_STANDARD_APP_ARGS(args, parse);
12313 
12314  if (args.argc != 2) {
12315  ast_log(LOG_WARNING, "Wrong argument count\n");
12316  return 0;
12317  }
12318 
12319  /*ast_log(LOG_NOTICE, "Arguments: group/port '%s' timeout '%s'\n", args.grouppar, args.timeout);*/
12320  timeout = atoi(args.timeout);
12321  port_str = args.grouppar;
12322 
12323  if (port_str[0] == 'g' && port_str[1] == ':') {
12324  /* We make a group call lets checkout which ports are in my group */
12325  port_str += 2;
12326  ast_copy_string(group, port_str, sizeof(group));
12327  chan_misdn_log(2, 0, "Checking Ports in group: %s\n", group);
12328 
12329  for (port = misdn_cfg_get_next_port(port);
12330  port > 0;
12331  port = misdn_cfg_get_next_port(port)) {
12332  char cfg_group[BUFFERSIZE + 1];
12333 
12334  chan_misdn_log(2, 0, "trying port %d\n", port);
12335 
12336  misdn_cfg_get(port, MISDN_CFG_GROUPNAME, cfg_group, sizeof(cfg_group));
12337 
12338  if (!strcasecmp(cfg_group, group)) {
12339  port_up = misdn_lib_port_up(port, 1);
12340  if (!port_up) {
12341  chan_misdn_log(2, 0, " --> port '%d'\n", port);
12342  misdn_lib_get_port_up(port);
12343  dowait = 1;
12344  }
12345  }
12346  }
12347  } else {
12348  port = atoi(port_str);
12349  chan_misdn_log(2, 0, "Checking Port: %d\n", port);
12350  port_up = misdn_lib_port_up(port, 1);
12351  if (!port_up) {
12352  misdn_lib_get_port_up(port);
12353  dowait = 1;
12354  }
12355  }
12356 
12357  if (dowait) {
12358  chan_misdn_log(2, 0, "Waiting for '%d' seconds\n", timeout);
12359  ast_safe_sleep(chan, timeout * 1000);
12360  }
12361 
12362  return 0;
12363 }
static void chan_misdn_log(int level, int port, char *tmpl,...)
Definition: chan_misdn.c:12768
int ast_safe_sleep(struct ast_channel *chan, int ms)
Wait for a specified amount of time, looking for hangups.
Definition: channel.c:1574
int misdn_cfg_get_next_port(int port)
Definition: misdn_config.c:929
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the &#39;standard&#39; argument separation process for an application.
#define LOG_WARNING
Definition: logger.h:274
static int timeout
Definition: cdr_mysql.c:86
const char * args
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define BUFFERSIZE
#define ast_log
Definition: astobj2.c:42
void misdn_cfg_get(int port, enum misdn_cfg_elements elem, void *buf, int bufsize)
Definition: misdn_config.c:569
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
int misdn_lib_get_port_up(int port)
Definition: isdn_lib.c:1781
static void parse(struct mgcp_request *req)
Definition: chan_mgcp.c:1872
int misdn_lib_port_up(int port, int check)
Definition: isdn_lib.c:1821
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
#define AST_APP_ARG(name)
Define an application argument.

◆ misdn_copy_redirecting_from_ast()

static void misdn_copy_redirecting_from_ast ( struct misdn_bchannel bc,
struct ast_channel ast 
)
static

Definition at line 6382 of file chan_misdn.c.

References ast_channel_redirecting(), ast_channel_redirecting_effective_from(), ast_channel_redirecting_effective_to(), ast_copy_string(), ast_to_misdn_plan(), ast_to_misdn_pres(), ast_to_misdn_reason(), ast_to_misdn_screen(), ast_to_misdn_ton(), misdn_party_redirecting::count, ast_party_redirecting::count, misdn_party_redirecting::from, misdn_party_id::name, ast_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, misdn_party_id::presentation, ast_party_number::presentation, misdn_party_redirecting::reason, misdn_bchannel::redirecting, S_COR, S_OR, misdn_party_id::screening, ast_party_name::str, ast_party_number::str, misdn_party_redirecting::to, ast_party_name::valid, and ast_party_number::valid.

Referenced by misdn_call(), and misdn_update_redirecting().

6383 {
6386 
6388  S_COR(from_id.name.valid, from_id.name.str, ""),
6389  sizeof(bc->redirecting.from.name));
6390  if (from_id.number.valid) {
6391  ast_copy_string(bc->redirecting.from.number, S_OR(from_id.number.str, ""),
6392  sizeof(bc->redirecting.from.number));
6397  } else {
6398  bc->redirecting.from.number[0] = '\0';
6399  bc->redirecting.from.presentation = 0;/* Allowed */
6400  bc->redirecting.from.screening = 0;/* Unscreened */
6403  }
6404 
6406  S_COR(to_id.name.valid, to_id.name.str, ""),
6407  sizeof(bc->redirecting.to.name));
6408  if (to_id.number.valid) {
6410  sizeof(bc->redirecting.to.number));
6415  } else {
6416  bc->redirecting.to.number[0] = '\0';
6417  bc->redirecting.to.presentation = 0;/* Allowed */
6418  bc->redirecting.to.screening = 0;/* Unscreened */
6421  }
6422 
6425 }
Information needed to identify an endpoint in a call.
Definition: channel.h:339
static int ast_to_misdn_pres(int presentation)
Definition: chan_misdn.c:2145
char * str
Subscriber phone number (Malloced)
Definition: channel.h:292
char number[MISDN_MAX_NUMBER_LEN]
Phone number (Address)
Definition: isdn_lib.h:298
struct ast_party_id ast_channel_redirecting_effective_from(struct ast_channel *chan)
int presentation
Q.931 presentation-indicator and screening-indicator encoded fields.
Definition: channel.h:296
struct ast_party_name name
Subscriber name.
Definition: channel.h:341
int presentation
Number presentation restriction code 0=Allowed, 1=Restricted, 2=Unavailable.
Definition: isdn_lib.h:277
char * str
Subscriber name (Malloced)
Definition: channel.h:265
struct ast_party_id ast_channel_redirecting_effective_to(struct ast_channel *chan)
struct misdn_party_id to
Where the call is being redirected toward (Sent to the calling party)
Definition: isdn_lib.h:310
#define S_COR(a, b, c)
returns the equivalent of logic or for strings, with an additional boolean check: second one if not e...
Definition: strings.h:85
enum mISDN_NUMBER_TYPE number_type
Type-of-number in ISDN terms for the number.
Definition: isdn_lib.h:285
char name[MISDN_MAX_NAME_LEN]
Subscriber Name.
Definition: isdn_lib.h:295
struct misdn_party_id from
Who is redirecting the call (Sent to the party the call is redirected toward)
Definition: isdn_lib.h:307
int plan
Q.931 Type-Of-Number and Numbering-Plan encoded fields.
Definition: channel.h:294
static int ast_to_misdn_screen(int screening)
Definition: chan_misdn.c:2242
struct misdn_party_redirecting redirecting
Redirecting information struct (Where a call diversion or transfer was invoked)
Definition: isdn_lib.h:358
static enum mISDN_NUMBER_TYPE ast_to_misdn_ton(unsigned ast_number_type)
Definition: chan_misdn.c:1916
struct ast_party_redirecting * ast_channel_redirecting(struct ast_channel *chan)
enum mISDN_REDIRECTING_REASON reason
Reason a call is being redirected (Q.931 field value)
Definition: isdn_lib.h:313
int count
Number of times the call was redirected.
Definition: channel.h:549
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:79
unsigned char valid
TRUE if the name information is valid/present.
Definition: channel.h:280
int screening
Number screening code 0=Unscreened, 1=Passed Screen, 2=Failed Screen, 3=Network Number.
Definition: isdn_lib.h:282
static enum mISDN_REDIRECTING_REASON ast_to_misdn_reason(const enum AST_REDIRECTING_REASON ast)
Definition: chan_misdn.c:2274
unsigned char valid
TRUE if the number information is valid/present.
Definition: channel.h:298
enum mISDN_NUMBER_PLAN number_plan
Type-of-number numbering plan.
Definition: isdn_lib.h:288
int count
Number of times the call has been redirected.
Definition: isdn_lib.h:316
static enum mISDN_NUMBER_PLAN ast_to_misdn_plan(unsigned ast_number_plan)
Definition: chan_misdn.c:2042
struct ast_party_number number
Subscriber phone number.
Definition: channel.h:343

◆ misdn_copy_redirecting_to_ast()

static void misdn_copy_redirecting_to_ast ( struct ast_channel ast,
const struct misdn_party_redirecting redirect,
char *  tag 
)
static

Definition at line 6437 of file chan_misdn.c.

References ast_channel_redirecting(), ast_channel_set_redirecting(), ast_party_redirecting_set_init(), ast_party_redirecting_reason::code, misdn_party_redirecting::count, ast_party_redirecting::count, misdn_party_redirecting::from, ast_party_redirecting::from, ast_set_party_redirecting::from, misdn_to_ast_plan(), misdn_to_ast_pres(), misdn_to_ast_reason(), misdn_to_ast_screen(), misdn_to_ast_ton(), misdn_party_id::number, ast_party_id::number, ast_set_party_id::number, misdn_party_id::number_plan, misdn_party_id::number_type, ast_party_number::plan, misdn_party_id::presentation, ast_party_number::presentation, misdn_party_redirecting::reason, ast_party_redirecting::reason, misdn_party_id::screening, ast_party_number::str, ast_party_id::tag, misdn_party_redirecting::to, ast_party_redirecting::to, ast_set_party_redirecting::to, and ast_party_number::valid.

Referenced by cb_events(), and misdn_facility_ie_handler().

6438 {
6439  struct ast_party_redirecting redirecting;
6441 
6443  memset(&update_redirecting, 0, sizeof(update_redirecting));
6444 
6445  update_redirecting.from.number = 1;
6446  redirecting.from.number.valid = 1;
6447  redirecting.from.number.str = (char *) redirect->from.number;
6448  redirecting.from.number.plan =
6449  misdn_to_ast_ton(redirect->from.number_type)
6450  | misdn_to_ast_plan(redirect->from.number_plan);
6451  redirecting.from.number.presentation =
6453  | misdn_to_ast_screen(redirect->from.screening);
6454  redirecting.from.tag = tag;
6455 
6456  update_redirecting.to.number = 1;
6457  redirecting.to.number.valid = 1;
6458  redirecting.to.number.str = (char *) redirect->to.number;
6459  redirecting.to.number.plan =
6460  misdn_to_ast_ton(redirect->to.number_type)
6461  | misdn_to_ast_plan(redirect->to.number_plan);
6462  redirecting.to.number.presentation =
6463  misdn_to_ast_pres(redirect->to.presentation)
6464  | misdn_to_ast_screen(redirect->to.screening);
6465  redirecting.to.tag = tag;
6466 
6467  redirecting.reason.code = misdn_to_ast_reason(redirect->reason);
6468  redirecting.count = redirect->count;
6469 
6470  ast_channel_set_redirecting(ast, &redirecting, &update_redirecting);
6471 }
char number[MISDN_MAX_NUMBER_LEN]
Phone number (Address)
Definition: isdn_lib.h:298
static int misdn_to_ast_plan(enum mISDN_NUMBER_PLAN number_plan)
Definition: chan_misdn.c:2000
static int misdn_to_ast_pres(int presentation)
Definition: chan_misdn.c:2117
int presentation
Number presentation restriction code 0=Allowed, 1=Restricted, 2=Unavailable.
Definition: isdn_lib.h:277
struct misdn_party_id to
Where the call is being redirected toward (Sent to the calling party)
Definition: isdn_lib.h:310
static int misdn_to_ast_ton(enum mISDN_NUMBER_TYPE number_type)
Definition: chan_misdn.c:1874
enum mISDN_NUMBER_TYPE number_type
Type-of-number in ISDN terms for the number.
Definition: isdn_lib.h:285
void ast_channel_set_redirecting(struct ast_channel *chan, const struct ast_party_redirecting *redirecting, const struct ast_set_party_redirecting *update)
Set the redirecting id information in the Asterisk channel.
Definition: channel.c:9215
struct misdn_party_id from
Who is redirecting the call (Sent to the party the call is redirected toward)
Definition: isdn_lib.h:307
Redirecting Line information. RDNIS (Redirecting Directory Number Information Service) Where a call d...
Definition: channel.h:523
static enum AST_REDIRECTING_REASON misdn_to_ast_reason(const enum mISDN_REDIRECTING_REASON q931)
Definition: chan_misdn.c:2314
struct ast_party_redirecting * ast_channel_redirecting(struct ast_channel *chan)
enum mISDN_REDIRECTING_REASON reason
Reason a call is being redirected (Q.931 field value)
Definition: isdn_lib.h:313
Indicate what information in ast_party_redirecting should be set.
Definition: channel.h:556
void ast_party_redirecting_set_init(struct ast_party_redirecting *init, const struct ast_party_redirecting *guide)
Initialize the given redirecting id structure using the given guide for a set update operation...
Definition: channel.c:2153
int screening
Number screening code 0=Unscreened, 1=Passed Screen, 2=Failed Screen, 3=Network Number.
Definition: isdn_lib.h:282
static void update_redirecting(struct sip_pvt *p, const void *data, size_t datalen)
Send a provisional response indicating that a call was redirected.
Definition: chan_sip.c:15755
static int misdn_to_ast_screen(int screening)
Definition: chan_misdn.c:2210
enum mISDN_NUMBER_PLAN number_plan
Type-of-number numbering plan.
Definition: isdn_lib.h:288
int count
Number of times the call has been redirected.
Definition: isdn_lib.h:316

◆ misdn_digit_begin()

static int misdn_digit_begin ( struct ast_channel chan,
char  digit 
)
static

Definition at line 6909 of file chan_misdn.c.

6910 {
6911  /* XXX Modify this callback to support Asterisk controlling the length of DTMF */
6912  return 0;
6913 }

◆ misdn_digit_end()

static int misdn_digit_end ( struct ast_channel ast,
char  digit,
unsigned int  duration 
)
static

Definition at line 6915 of file chan_misdn.c.

References chan_list::ast, ast_channel_exten_set(), ast_copy_string(), ast_log, bc, chan_list::bc, buf, chan_misdn_log(), misdn_bchannel::dialed, digit, EVENT_INFORMATION, 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.

6916 {
6917  struct chan_list *p;
6918  struct misdn_bchannel *bc;
6919  char buf[2] = { digit, 0 };
6920 
6921  if (!ast || !(p = MISDN_ASTERISK_TECH_PVT(ast))) {
6922  return -1;
6923  }
6924 
6925  bc = p->bc;
6926  chan_misdn_log(1, bc ? bc->port : 0, "* IND : Digit %c\n", digit);
6927 
6928  if (!bc) {
6929  ast_log(LOG_WARNING, " --> !! Got Digit Event without having bchannel Object\n");
6930  return -1;
6931  }
6932 
6933  switch (p->state) {
6934  case MISDN_CALLING:
6935  if (strlen(bc->infos_pending) < sizeof(bc->infos_pending) - 1) {
6936  strncat(bc->infos_pending, buf, sizeof(bc->infos_pending) - strlen(bc->infos_pending) - 1);
6937  }
6938  break;
6940  ast_copy_string(bc->info_dad, buf, sizeof(bc->info_dad));
6941  if (strlen(bc->dialed.number) < sizeof(bc->dialed.number) - 1) {
6942  strncat(bc->dialed.number, buf, sizeof(bc->dialed.number) - strlen(bc->dialed.number) - 1);
6943  }
6946  break;
6947  default:
6948  if (bc->send_dtmf) {
6950  }
6951  break;
6952  }
6953 
6954  return 0;
6955 }
static void chan_misdn_log(int level, int port, char *tmpl,...)
Definition: chan_misdn.c:12768
char digit
#define bc
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define LOG_WARNING
Definition: logger.h:274
B channel control structure.
Definition: isdn_lib.h:324
#define MISDN_ASTERISK_TECH_PVT(ast)
Definition: chan_misdn.c:683
struct ast_channel * ast
Associated Asterisk channel structure.
Definition: chan_misdn.c:515
#define ast_log
Definition: astobj2.c:42
char number[MISDN_MAX_NUMBER_LEN]
Dialed/Called Phone Number (Address)
Definition: isdn_lib.h:266
char infos_pending[MISDN_MAX_NUMBER_LEN]
Collected digits to go into info_dad[] while waiting for a SETUP_ACKNOWLEDGE to come in...
Definition: isdn_lib.h:653
enum misdn_chan_state state
State of the channel.
Definition: chan_misdn.c:386
int send_dtmf
TRUE if we should produce DTMF tones ourselves.
Definition: isdn_lib.h:457
int port
Logical Layer 1 port associated with this B channel.
Definition: isdn_lib.h:370
struct misdn_party_dialing dialed
Dialed/Called information struct.
Definition: isdn_lib.h:337
Channel call record structure.
Definition: chan_misdn.c:377
void ast_channel_exten_set(struct ast_channel *chan, const char *value)
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
int misdn_lib_send_event(struct misdn_bchannel *bc, enum event_e event)
Definition: isdn_lib.c:3523
static void send_digit_to_chan(struct chan_list *cl, char digit)
Definition: chan_misdn.c:3681
char info_dad[MISDN_MAX_NUMBER_LEN]
Current overlap dialing digits to/from INFORMATION messages.
Definition: isdn_lib.h:650
struct misdn_bchannel * bc
Associated B channel structure.
Definition: chan_misdn.c:520

◆ misdn_facility_exec()

static int misdn_facility_exec ( struct ast_channel chan,
const char *  data 
)
static

Definition at line 12168 of file chan_misdn.c.

References args, AST_APP_ARG, ast_channel_tech(), 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(), parse(), misdn_bchannel::port, and print_facility().

Referenced by load_module().

12169 {
12170  struct chan_list *ch = MISDN_ASTERISK_TECH_PVT(chan);
12171  char *parse;
12172  unsigned max_len;
12173 
12175  AST_APP_ARG(facility_type);
12176  AST_APP_ARG(arg)[99];
12177  );
12178 
12179  chan_misdn_log(0, 0, "TYPE: %s\n", ast_channel_tech(chan)->type);
12180 
12181  if (strcasecmp(ast_channel_tech(chan)->type, misdn_type)) {
12182  ast_log(LOG_WARNING, "misdn_facility only makes sense with %s channels!\n", misdn_type);
12183  return -1;
12184  }
12185 
12186  if (ast_strlen_zero((char *) data)) {
12187  ast_log(LOG_WARNING, "misdn_facility requires arguments: facility_type[,<args>]\n");
12188  return -1;
12189  }
12190 
12191  parse = ast_strdupa(data);
12192  AST_STANDARD_APP_ARGS(args, parse);
12193 
12194  if (ast_strlen_zero(args.facility_type)) {
12195  ast_log(LOG_WARNING, "misdn_facility requires arguments: facility_type[,<args>]\n");
12196  return -1;
12197  }
12198 
12199  if (!strcasecmp(args.facility_type, "calldeflect")) {
12200  if (ast_strlen_zero(args.arg[0])) {
12201  ast_log(LOG_WARNING, "Facility: Call Deflection requires an argument: Number\n");
12202  }
12203 
12204 #if defined(AST_MISDN_ENHANCEMENTS)
12205  max_len = sizeof(ch->bc->fac_out.u.CallDeflection.Component.Invoke.Deflection.Party.Number) - 1;
12206  if (max_len < strlen(args.arg[0])) {
12208  "Facility: Number argument too long (up to %u digits are allowed). Ignoring.\n",
12209  max_len);
12210  return 0;
12211  }
12212  ch->bc->fac_out.Function = Fac_CallDeflection;
12213  ch->bc->fac_out.u.CallDeflection.InvokeID = ++misdn_invoke_id;
12214  ch->bc->fac_out.u.CallDeflection.ComponentType = FacComponent_Invoke;
12215  ch->bc->fac_out.u.CallDeflection.Component.Invoke.PresentationAllowedToDivertedToUserPresent = 1;
12216  ch->bc->fac_out.u.CallDeflection.Component.Invoke.PresentationAllowedToDivertedToUser = 0;
12217  ch->bc->fac_out.u.CallDeflection.Component.Invoke.Deflection.Party.Type = 0;/* unknown */
12218  ch->bc->fac_out.u.CallDeflection.Component.Invoke.Deflection.Party.LengthOfNumber = strlen(args.arg[0]);
12219  strcpy((char *) ch->bc->fac_out.u.CallDeflection.Component.Invoke.Deflection.Party.Number, args.arg[0]);
12220  ch->bc->fac_out.u.CallDeflection.Component.Invoke.Deflection.Subaddress.Length = 0;
12221 
12222 #else /* !defined(AST_MISDN_ENHANCEMENTS) */
12223 
12224  max_len = sizeof(ch->bc->fac_out.u.CDeflection.DeflectedToNumber) - 1;
12225  if (max_len < strlen(args.arg[0])) {
12227  "Facility: Number argument too long (up to %u digits are allowed). Ignoring.\n",
12228  max_len);
12229  return 0;
12230  }
12231  ch->bc->fac_out.Function = Fac_CD;
12232  ch->bc->fac_out.u.CDeflection.PresentationAllowed = 0;
12233  //ch->bc->fac_out.u.CDeflection.DeflectedToSubaddress[0] = 0;
12234  strcpy((char *) ch->bc->fac_out.u.CDeflection.DeflectedToNumber, args.arg[0]);
12235 #endif /* !defined(AST_MISDN_ENHANCEMENTS) */
12236 
12237  /* Send message */
12238  print_facility(&ch->bc->fac_out, ch->bc);
12240 #if defined(AST_MISDN_ENHANCEMENTS)
12241  } else if (!strcasecmp(args.facility_type, "callrerouteing")
12242  || !strcasecmp(args.facility_type, "callrerouting")) {
12243  if (ast_strlen_zero(args.arg[0])) {
12244  ast_log(LOG_WARNING, "Facility: Call rerouting requires an argument: Number\n");
12245  }
12246 
12247  max_len = sizeof(ch->bc->fac_out.u.CallRerouteing.Component.Invoke.CalledAddress.Party.Number) - 1;
12248  if (max_len < strlen(args.arg[0])) {
12250  "Facility: Number argument too long (up to %u digits are allowed). Ignoring.\n",
12251  max_len);
12252  return 0;
12253  }
12254  ch->bc->fac_out.Function = Fac_CallRerouteing;
12255  ch->bc->fac_out.u.CallRerouteing.InvokeID = ++misdn_invoke_id;
12256  ch->bc->fac_out.u.CallRerouteing.ComponentType = FacComponent_Invoke;
12257 
12258  ch->bc->fac_out.u.CallRerouteing.Component.Invoke.ReroutingReason = 0;/* unknown */
12259  ch->bc->fac_out.u.CallRerouteing.Component.Invoke.ReroutingCounter = 1;
12260 
12261  ch->bc->fac_out.u.CallRerouteing.Component.Invoke.CalledAddress.Party.Type = 0;/* unknown */
12262  ch->bc->fac_out.u.CallRerouteing.Component.Invoke.CalledAddress.Party.LengthOfNumber = strlen(args.arg[0]);
12263  strcpy((char *) ch->bc->fac_out.u.CallRerouteing.Component.Invoke.CalledAddress.Party.Number, args.arg[0]);
12264  ch->bc->fac_out.u.CallRerouteing.Component.Invoke.CalledAddress.Subaddress.Length = 0;
12265 
12266  ch->bc->fac_out.u.CallRerouteing.Component.Invoke.CallingPartySubaddress.Length = 0;
12267 
12268  /* 0x90 0x90 0xa3 3.1 kHz audio, circuit mode, 64kbit/sec, level1/a-Law */
12269  ch->bc->fac_out.u.CallRerouteing.Component.Invoke.Q931ie.Bc.Length = 3;
12270  ch->bc->fac_out.u.CallRerouteing.Component.Invoke.Q931ie.Bc.Contents[0] = 0x90;
12271  ch->bc->fac_out.u.CallRerouteing.Component.Invoke.Q931ie.Bc.Contents[1] = 0x90;
12272  ch->bc->fac_out.u.CallRerouteing.Component.Invoke.Q931ie.Bc.Contents[2] = 0xa3;
12273  ch->bc->fac_out.u.CallRerouteing.Component.Invoke.Q931ie.Hlc.Length = 0;
12274  ch->bc->fac_out.u.CallRerouteing.Component.Invoke.Q931ie.Llc.Length = 0;
12275  ch->bc->fac_out.u.CallRerouteing.Component.Invoke.Q931ie.UserInfo.Length = 0;
12276 
12277  ch->bc->fac_out.u.CallRerouteing.Component.Invoke.LastRerouting.Type = 1;/* presentationRestricted */
12278  ch->bc->fac_out.u.CallRerouteing.Component.Invoke.SubscriptionOption = 0;/* no notification to caller */
12279 
12280  /* Send message */
12281  print_facility(&ch->bc->fac_out, ch->bc);
12283 #endif /* defined(AST_MISDN_ENHANCEMENTS) */
12284  } else {
12285  chan_misdn_log(1, ch->bc->port, "Unknown Facility: %s\n", args.facility_type);
12286  }
12287 
12288  return 0;
12289 }
static void chan_misdn_log(int level, int port, char *tmpl,...)
Definition: chan_misdn.c:12768
static const char type[]
Definition: chan_ooh323.c:109
struct FacParm fac_out
Outbound FACILITY message function type and contents.
Definition: isdn_lib.h:512
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the &#39;standard&#39; argument separation process for an application.
#define LOG_WARNING
Definition: logger.h:274
#define MISDN_ASTERISK_TECH_PVT(ast)
Definition: chan_misdn.c:683
const char * args
#define ast_strlen_zero(foo)
Definition: strings.h:52
static void print_facility(const struct FacParm *fac, const struct misdn_bchannel *bc)
Definition: chan_misdn.c:2762
#define ast_log
Definition: astobj2.c:42
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
int port
Logical Layer 1 port associated with this B channel.
Definition: isdn_lib.h:370
static const char misdn_type[]
Definition: chan_misdn.c:690
static void parse(struct mgcp_request *req)
Definition: chan_mgcp.c:1872
Channel call record structure.
Definition: chan_misdn.c:377
int misdn_lib_send_event(struct misdn_bchannel *bc, enum event_e event)
Definition: isdn_lib.c:3523
struct misdn_bchannel * bc
Associated B channel structure.
Definition: chan_misdn.c:520
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
const struct ast_channel_tech * ast_channel_tech(const struct ast_channel *chan)
#define AST_APP_ARG(name)
Define an application argument.

◆ misdn_facility_ie_handler()

static void misdn_facility_ie_handler ( enum event_e  event,
struct misdn_bchannel bc,
struct chan_list ch 
)
static

Definition at line 9095 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_channel_redirecting(), 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_party_id_reset(), ast_party_redirecting_copy(), ast_party_redirecting_free(), ast_party_redirecting_init(), AST_PRES_ALLOWED, AST_PRES_RESTRICTED, AST_PRES_USER_NUMBER_UNSCREENED, ast_queue_control(), buf, 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, NULL, misdn_party_dialing::number, misdn_party_id::number, ast_party_id::number, misdn_party_id::number_plan, misdn_party_dialing::number_plan, misdn_party_id::number_type, misdn_party_dialing::number_type, NUMPLAN_ISDN, NUMPLAN_UNKNOWN, NUMTYPE_UNKNOWN, chan_list::originator, misdn_bchannel::port, misdn_party_id::presentation, ast_party_number::presentation, print_facility(), ast_party_redirecting::priv_from, ast_party_redirecting::priv_orig, ast_party_redirecting::priv_to, misdn_party_redirecting::reason, misdn_bchannel::redirecting, misdn_party_id::screening, misdn_party_redirecting::to, ast_party_redirecting::to, and misdn_party_redirecting::to_changed.

Referenced by cb_events().

9096 {
9097 #if defined(AST_MISDN_ENHANCEMENTS)
9098  const char *diagnostic_msg;
9099  struct misdn_cc_record *cc_record;
9100  char buf[32];
9101  struct misdn_party_id party_id;
9102  long new_record_id;
9103 #endif /* defined(AST_MISDN_ENHANCEMENTS) */
9104 
9105  print_facility(&bc->fac_in, bc);
9106  switch (bc->fac_in.Function) {
9107 #if defined(AST_MISDN_ENHANCEMENTS)
9108  case Fac_ActivationDiversion:
9109  switch (bc->fac_in.u.ActivationDiversion.ComponentType) {
9110  case FacComponent_Result:
9111  /* Positive ACK to activation */
9112  /* We don't handle this yet */
9113  break;
9114  default:
9115  chan_misdn_log(0, bc->port," --> not yet handled: facility type:0x%04X\n",
9116  bc->fac_in.Function);
9117  break;
9118  }
9119  break;
9120  case Fac_DeactivationDiversion:
9121  switch (bc->fac_in.u.DeactivationDiversion.ComponentType) {
9122  case FacComponent_Result:
9123  /* Positive ACK to deactivation */
9124  /* We don't handle this yet */
9125  break;
9126  default:
9127  chan_misdn_log(0, bc->port," --> not yet handled: facility type:0x%04X\n",
9128  bc->fac_in.Function);
9129  break;
9130  }
9131  break;
9132  case Fac_ActivationStatusNotificationDiv:
9133  /* Sent to other MSN numbers on the line when a user activates call forwarding. */
9134  /* Sent in the first call control message of an outgoing call from the served user. */
9135  /* We do not have anything to do for this message. */
9136  break;
9137  case Fac_DeactivationStatusNotificationDiv:
9138  /* Sent to other MSN numbers on the line when a user deactivates call forwarding. */
9139  /* We do not have anything to do for this message. */
9140  break;
9141 #if 0 /* We don't handle this yet */
9142  case Fac_InterrogationDiversion:
9143  /* We don't handle this yet */
9144  break;
9145  case Fac_InterrogateServedUserNumbers:
9146  /* We don't handle this yet */
9147  break;
9148 #endif /* We don't handle this yet */
9149  case Fac_DiversionInformation:
9150  /* Sent to the served user when a call is forwarded. */
9151  /* We do not have anything to do for this message. */
9152  break;
9153  case Fac_CallDeflection:
9154  if (ch && ch->ast) {
9155  switch (bc->fac_in.u.CallDeflection.ComponentType) {
9156  case FacComponent_Invoke:
9158  sizeof(bc->redirecting.from.number));
9159  bc->redirecting.from.name[0] = 0;
9162  bc->redirecting.from.screening = 0;/* Unscreened */
9163  if (bc->fac_in.u.CallDeflection.Component.Invoke.PresentationAllowedToDivertedToUserPresent) {
9165  bc->fac_in.u.CallDeflection.Component.Invoke.PresentationAllowedToDivertedToUser
9166  ? 0 /* Allowed */ : 1 /* Restricted */;
9167  } else {
9168  bc->redirecting.from.presentation = 0;/* Allowed */
9169  }
9170 
9171  /* Add configured prefix to the call deflection number */
9172  memset(&party_id, 0, sizeof(party_id));
9173  misdn_PartyNumber_extract(&party_id,
9174  &bc->fac_in.u.CallDeflection.Component.Invoke.Deflection.Party);
9175  misdn_add_number_prefix(bc->port, party_id.number_type,
9176  party_id.number, sizeof(party_id.number));
9177  //party_id.presentation = 0;/* Allowed */
9178  //party_id.screening = 0;/* Unscreened */
9179  bc->redirecting.to = party_id;
9180 
9181  ++bc->redirecting.count;
9183 
9185  ast_channel_call_forward_set(ch->ast, bc->redirecting.to.number);
9186 
9187  /* Send back positive ACK */
9188 #if 1
9189  /*
9190  * Since there are no return result arguments it must be a
9191  * generic result message. ETSI 300-196
9192  */
9193  bc->fac_out.Function = Fac_RESULT;
9194  bc->fac_out.u.RESULT.InvokeID = bc->fac_in.u.CallDeflection.InvokeID;
9195 #else
9196  bc->fac_out.Function = Fac_CallDeflection;
9197  bc->fac_out.u.CallDeflection.InvokeID = bc->fac_in.u.CallDeflection.InvokeID;
9198  bc->fac_out.u.CallDeflection.ComponentType = FacComponent_Result;
9199 #endif
9200  print_facility(&bc->fac_out, bc);
9202 
9203  /* This line is BUSY to further attempts by this dialing attempt. */
9205  break;
9206 
9207  case FacComponent_Result:
9208  /* Positive ACK to call deflection */
9209  /*
9210  * Sent in DISCONNECT or FACILITY message depending upon network option.
9211  * It is in the FACILITY message if the call is still offered to the user
9212  * while trying to alert the deflected to party.
9213  */
9214  /* Ignore the ACK */
9215  break;
9216 
9217  default:
9218  break;
9219  }
9220  }
9221  break;
9222 #if 0 /* We don't handle this yet */
9223  case Fac_CallRerouteing:
9224  /* Private-Public ISDN interworking message */
9225  /* We don't handle this yet */
9226  break;
9227 #endif /* We don't handle this yet */
9228  case Fac_DivertingLegInformation1:
9229  /* Private-Public ISDN interworking message */
9230  bc->div_leg_3_rx_wanted = 0;
9231  if (ch && ch->ast) {
9232  bc->redirecting.reason =
9233  diversion_reason_to_misdn(bc->fac_in.u.DivertingLegInformation1.DiversionReason);
9234  if (bc->fac_in.u.DivertingLegInformation1.DivertedToPresent) {
9235  misdn_PresentedNumberUnscreened_extract(&bc->redirecting.to,
9236  &bc->fac_in.u.DivertingLegInformation1.DivertedTo);
9237 
9238  /* Add configured prefix to redirecting.to.number */
9240  bc->redirecting.to.number, sizeof(bc->redirecting.to.number));
9241  } else {
9242  bc->redirecting.to.number[0] = '\0';
9245  bc->redirecting.to.presentation = 1;/* restricted */
9246  bc->redirecting.to.screening = 0;/* unscreened */
9247  }
9249  bc->div_leg_3_rx_wanted = 1;
9250  }
9251  break;
9252  case Fac_DivertingLegInformation2:
9253  /* Private-Public ISDN interworking message */
9254  switch (event) {
9255  case EVENT_SETUP:
9256  /* Comes in on a SETUP with redirecting.from information */
9257  bc->div_leg_3_tx_pending = 1;
9258  if (ch && ch->ast) {
9259  /*
9260  * Setup the redirecting.to informtion so we can identify
9261  * if the user wants to manually supply the COLR for this
9262  * redirected to number if further redirects could happen.
9263  *
9264  * All the user needs to do is set the REDIRECTING(to-pres)
9265  * to the COLR and REDIRECTING(to-num) = ${EXTEN} to be safe
9266  * after determining that the incoming call was redirected by
9267  * checking if there is a REDIRECTING(from-num).
9268  */
9270  sizeof(bc->redirecting.to.number));
9273  bc->redirecting.to.presentation = 1;/* restricted */
9274  bc->redirecting.to.screening = 0;/* unscreened */
9275 
9276  bc->redirecting.reason =
9277  diversion_reason_to_misdn(bc->fac_in.u.DivertingLegInformation2.DiversionReason);
9278  bc->redirecting.count = bc->fac_in.u.DivertingLegInformation2.DiversionCounter;
9279  if (bc->fac_in.u.DivertingLegInformation2.DivertingPresent) {
9280  /* This information is redundant if there was a redirecting ie in the SETUP. */
9281  misdn_PresentedNumberUnscreened_extract(&bc->redirecting.from,
9282  &bc->fac_in.u.DivertingLegInformation2.Diverting);
9283 
9284  /* Add configured prefix to redirecting.from.number */
9286  bc->redirecting.from.number, sizeof(bc->redirecting.from.number));
9287  }
9288 #if 0
9289  if (bc->fac_in.u.DivertingLegInformation2.OriginalCalledPresent) {
9290  /* We have no place to put the OriginalCalled number */
9291  }
9292 #endif
9294  }
9295  break;
9296  default:
9297  chan_misdn_log(0, bc->port," --> Expected in a SETUP message: facility type:0x%04X\n",
9298  bc->fac_in.Function);
9299  break;
9300  }
9301  break;
9302  case Fac_DivertingLegInformation3:
9303  /* Private-Public ISDN interworking message */
9304  if (bc->div_leg_3_rx_wanted) {
9305  bc->div_leg_3_rx_wanted = 0;
9306 
9307  if (ch && ch->ast) {
9308  struct ast_party_redirecting redirecting;
9309 
9311  bc->fac_in.u.DivertingLegInformation3.PresentationAllowedIndicator
9314  ast_party_redirecting_init(&redirecting);
9316 
9317  /*
9318  * Reset any earlier private redirecting id representations and
9319  * make sure that it is invalidated at the remote end.
9320  */
9321  ast_party_id_reset(&redirecting.priv_orig);
9322  ast_party_id_reset(&redirecting.priv_from);
9323  ast_party_id_reset(&redirecting.priv_to);
9324 
9325  ast_channel_queue_redirecting_update(ch->ast, &redirecting, NULL);
9326  ast_party_redirecting_free(&redirecting);
9327  }
9328  }
9329  break;
9330 
9331 #else /* !defined(AST_MISDN_ENHANCEMENTS) */
9332 
9333  case Fac_CD:
9334  if (ch && ch->ast) {
9336  sizeof(bc->redirecting.from.number));
9337  bc->redirecting.from.name[0] = 0;
9340  bc->redirecting.from.screening = 0;/* Unscreened */
9342  bc->fac_in.u.CDeflection.PresentationAllowed
9343  ? 0 /* Allowed */ : 1 /* Restricted */;
9344 
9346  (char *) bc->fac_in.u.CDeflection.DeflectedToNumber,
9347  sizeof(bc->redirecting.to.number));
9348  bc->redirecting.to.name[0] = 0;
9351  bc->redirecting.to.presentation = 0;/* Allowed */
9352  bc->redirecting.to.screening = 0;/* Unscreened */
9353 
9354  ++bc->redirecting.count;
9356 
9358  ast_channel_call_forward_set(ch->ast, bc->redirecting.to.number);
9359 
9361 
9362  /* This line is BUSY to further attempts by this dialing attempt. */
9364  }
9365  break;
9366 #endif /* !defined(AST_MISDN_ENHANCEMENTS) */
9367  case Fac_AOCDCurrency:
9368  if (ch && ch->ast) {
9369  bc->AOCDtype = Fac_AOCDCurrency;
9370  memcpy(&bc->AOCD.currency, &bc->fac_in.u.AOCDcur, sizeof(bc->AOCD.currency));
9371  bc->AOCD_need_export = 1;
9372  export_aoc_vars(ch->originator, ch->ast, bc);
9373  }
9374  break;
9375  case Fac_AOCDChargingUnit:
9376  if (ch && ch->ast) {
9377  bc->AOCDtype = Fac_AOCDChargingUnit;
9378  memcpy(&bc->AOCD.chargingUnit, &bc->fac_in.u.AOCDchu, sizeof(bc->AOCD.chargingUnit));
9379  bc->AOCD_need_export = 1;
9380  export_aoc_vars(ch->originator, ch->ast, bc);
9381  }
9382  break;
9383 #if defined(AST_MISDN_ENHANCEMENTS)
9384  case Fac_ERROR:
9385  diagnostic_msg = misdn_to_str_error_code(bc->fac_in.u.ERROR.errorValue);
9386  chan_misdn_log(1, bc->port, " --> Facility error code: %s\n", diagnostic_msg);
9387  switch (event) {
9388  case EVENT_DISCONNECT:
9389  case EVENT_RELEASE:
9391  /* Possible call failure as a result of Fac_CCBSCall/Fac_CCBS_T_Call */
9392  if (ch && ch->peer) {
9393  misdn_cc_set_peer_var(ch->peer, MISDN_ERROR_MSG, diagnostic_msg);
9394  }
9395  break;
9396  default:
9397  break;
9398  }
9399  AST_LIST_LOCK(&misdn_cc_records_db);
9400  cc_record = misdn_cc_find_by_invoke(bc->port, bc->fac_in.u.ERROR.invokeId);
9401  if (cc_record) {
9402  cc_record->outstanding_message = 0;
9403  cc_record->error_code = bc->fac_in.u.ERROR.errorValue;
9404  }
9405  AST_LIST_UNLOCK(&misdn_cc_records_db);
9406  break;
9407  case Fac_REJECT:
9408  diagnostic_msg = misdn_to_str_reject_code(bc->fac_in.u.REJECT.Code);
9409  chan_misdn_log(1, bc->port, " --> Facility reject code: %s\n", diagnostic_msg);
9410  switch (event) {
9411  case EVENT_DISCONNECT:
9412  case EVENT_RELEASE:
9414  /* Possible call failure as a result of Fac_CCBSCall/Fac_CCBS_T_Call */
9415  if (ch && ch->peer) {
9416  misdn_cc_set_peer_var(ch->peer, MISDN_ERROR_MSG, diagnostic_msg);
9417  }
9418  break;
9419  default:
9420  break;
9421  }
9422  if (bc->fac_in.u.REJECT.InvokeIDPresent) {
9423  AST_LIST_LOCK(&misdn_cc_records_db);
9424  cc_record = misdn_cc_find_by_invoke(bc->port, bc->fac_in.u.REJECT.InvokeID);
9425  if (cc_record) {
9426  cc_record->outstanding_message = 0;
9427  cc_record->reject_code = bc->fac_in.u.REJECT.Code;
9428  }
9429  AST_LIST_UNLOCK(&misdn_cc_records_db);
9430  }
9431  break;
9432  case Fac_RESULT:
9433  AST_LIST_LOCK(&misdn_cc_records_db);
9434  cc_record = misdn_cc_find_by_invoke(bc->port, bc->fac_in.u.RESULT.InvokeID);
9435  if (cc_record) {
9436  cc_record->outstanding_message = 0;
9437  }
9438  AST_LIST_UNLOCK(&misdn_cc_records_db);
9439  break;
9440 #if 0 /* We don't handle this yet */
9441  case Fac_EctExecute:
9442  /* We don't handle this yet */
9443  break;
9444  case Fac_ExplicitEctExecute:
9445  /* We don't handle this yet */
9446  break;
9447  case Fac_EctLinkIdRequest:
9448  /* We don't handle this yet */
9449  break;
9450 #endif /* We don't handle this yet */
9451  case Fac_SubaddressTransfer:
9452  /* We do not have anything to do for this message since we do not handle subaddresses. */
9453  break;
9454  case Fac_RequestSubaddress:
9455  /*
9456  * We do not have anything to do for this message since we do not handle subaddresses.
9457  * However, we do care about some other ie's that should be present.
9458  */
9459  if (bc->redirecting.to_changed) {
9460  /* Add configured prefix to redirecting.to.number */
9462  bc->redirecting.to.number, sizeof(bc->redirecting.to.number));
9463  }
9464  switch (bc->notify_description_code) {
9466  /* Notify ie was not present. */
9467  bc->redirecting.to_changed = 0;
9468  break;
9470  /*
9471  * It would be preferable to update the connected line information
9472  * only when the message callStatus is active. However, the
9473  * optional redirection number may not be present in the active
9474  * message if an alerting message were received earlier.
9475  *
9476  * The consequences if we wind up sending two updates is benign.
9477  * The other end will think that it got transferred twice.
9478  */
9479  if (!bc->redirecting.to_changed) {
9480  break;
9481  }
9482  bc->redirecting.to_changed = 0;
9483  if (!ch || !ch->ast) {
9484  break;
9485  }
9488  bc->incoming_cid_tag);
9489  break;
9491  if (!bc->redirecting.to_changed) {
9492  break;
9493  }
9494  bc->redirecting.to_changed = 0;
9495  if (!ch || !ch->ast) {
9496  break;
9497  }
9500  break;
9501  default:
9502  bc->redirecting.to_changed = 0;
9503  chan_misdn_log(0, bc->port," --> not yet handled: notify code:0x%02X\n",
9505  break;
9506  }
9508  break;
9509  case Fac_EctInform:
9510  /* Private-Public ISDN interworking message */
9511  if (ch && ch->ast && bc->fac_in.u.EctInform.RedirectionPresent) {
9512  /* Add configured prefix to the redirection number */
9513  memset(&party_id, 0, sizeof(party_id));
9514  misdn_PresentedNumberUnscreened_extract(&party_id,
9515  &bc->fac_in.u.EctInform.Redirection);
9516  misdn_add_number_prefix(bc->port, party_id.number_type,
9517  party_id.number, sizeof(party_id.number));
9518 
9519  /*
9520  * It would be preferable to update the connected line information
9521  * only when the message callStatus is active. However, the
9522  * optional redirection number may not be present in the active
9523  * message if an alerting message were received earlier.
9524  *
9525  * The consequences if we wind up sending two updates is benign.
9526  * The other end will think that it got transferred twice.
9527  */
9528  misdn_update_remote_party(ch->ast, &party_id,
9529  (bc->fac_in.u.EctInform.Status == 0 /* alerting */)
9532  bc->incoming_cid_tag);
9533  }
9534  break;
9535 #if 0 /* We don't handle this yet */
9536  case Fac_EctLoopTest:
9537  /* The use of this message is unclear on how it works to detect loops. */
9538  /* We don't handle this yet */
9539  break;
9540 #endif /* We don't handle this yet */
9541  case Fac_CallInfoRetain:
9542  switch (event) {
9543  case EVENT_ALERTING:
9544  case EVENT_DISCONNECT:
9545  /* CCBS/CCNR is available */
9546  if (ch && ch->peer) {
9547  AST_LIST_LOCK(&misdn_cc_records_db);
9548  if (ch->record_id == -1) {
9549  cc_record = misdn_cc_new();
9550  } else {
9551  /*
9552  * We are doing a call-completion attempt
9553  * or the switch is sending us extra call-completion
9554  * availability indications (erroneously?).
9555  *
9556  * Assume that the network request retention option
9557  * is not on and that the current call-completion
9558  * request is disabled.
9559  */
9560  cc_record = misdn_cc_find_by_id(ch->record_id);
9561  if (cc_record) {
9562  if (cc_record->ptp && cc_record->mode.ptp.bc) {
9563  /*
9564  * What? We are getting mixed messages from the
9565  * switch. We are currently setup for
9566  * point-to-point. Now we are switching to
9567  * point-to-multipoint.
9568  *
9569  * Close the call-completion signaling link
9570  */
9571  cc_record->mode.ptp.bc->fac_out.Function = Fac_None;
9572  cc_record->mode.ptp.bc->out_cause = AST_CAUSE_NORMAL_CLEARING;
9573  misdn_lib_send_event(cc_record->mode.ptp.bc, EVENT_RELEASE_COMPLETE);
9574  }
9575 
9576  /*
9577  * Resetup the existing record for a possible new
9578  * call-completion request.
9579  */
9580  new_record_id = misdn_cc_record_id_new();
9581  if (new_record_id < 0) {
9582  /* Looks like we must keep the old id anyway. */
9583  } else {
9584  cc_record->record_id = new_record_id;
9585  ch->record_id = new_record_id;
9586  }
9587  cc_record->ptp = 0;
9588  cc_record->port = bc->port;
9589  memset(&cc_record->mode, 0, sizeof(cc_record->mode));
9590  cc_record->mode.ptmp.linkage_id = bc->fac_in.u.CallInfoRetain.CallLinkageID;
9591  cc_record->invoke_id = ++misdn_invoke_id;
9592  cc_record->activated = 0;
9593  cc_record->outstanding_message = 0;
9594  cc_record->activation_requested = 0;
9595  cc_record->error_code = FacError_None;
9596  cc_record->reject_code = FacReject_None;
9597  memset(&cc_record->remote_user_free, 0, sizeof(cc_record->remote_user_free));
9598  memset(&cc_record->b_free, 0, sizeof(cc_record->b_free));
9599  cc_record->time_created = time(NULL);
9600 
9601  cc_record = NULL;
9602  } else {
9603  /*
9604  * Where did the record go? We will have to recapture
9605  * the call setup information. Unfortunately, some
9606  * setup information may have been changed.
9607  */
9608  ch->record_id = -1;
9609  cc_record = misdn_cc_new();
9610  }
9611  }
9612  if (cc_record) {
9613  ch->record_id = cc_record->record_id;
9614  cc_record->ptp = 0;
9615  cc_record->port = bc->port;
9616  cc_record->mode.ptmp.linkage_id = bc->fac_in.u.CallInfoRetain.CallLinkageID;
9617 
9618  /* Record call information for possible call-completion attempt. */
9619  cc_record->redial.caller = bc->caller;
9620  cc_record->redial.dialed = bc->dialed;
9621  cc_record->redial.setup_bc_hlc_llc = bc->setup_bc_hlc_llc;
9622  cc_record->redial.capability = bc->capability;
9623  cc_record->redial.hdlc = bc->hdlc;
9624  }
9625  AST_LIST_UNLOCK(&misdn_cc_records_db);
9626 
9627  /* Set MISDN_CC_RECORD_ID in original channel */
9628  if (ch->record_id != -1) {
9629  snprintf(buf, sizeof(buf), "%ld", ch->record_id);
9630  } else {
9631  buf[0] = 0;
9632  }
9633  misdn_cc_set_peer_var(ch->peer, MISDN_CC_RECORD_ID, buf);
9634  }
9635  break;
9636  default:
9637  chan_misdn_log(0, bc->port,
9638  " --> Expected in a DISCONNECT or ALERTING message: facility type:0x%04X\n",
9639  bc->fac_in.Function);
9640  break;
9641  }
9642  break;
9643  case Fac_CCBS_T_Call:
9644  case Fac_CCBSCall:
9645  switch (event) {
9646  case EVENT_SETUP:
9647  /*
9648  * This is a call completion retry call.
9649  * If we had anything to do we would do it here.
9650  */
9651  break;
9652  default:
9653  chan_misdn_log(0, bc->port, " --> Expected in a SETUP message: facility type:0x%04X\n",
9654  bc->fac_in.Function);
9655  break;
9656  }
9657  break;
9658  case Fac_CCBSDeactivate:
9659  switch (bc->fac_in.u.CCBSDeactivate.ComponentType) {
9660  case FacComponent_Result:
9661  AST_LIST_LOCK(&misdn_cc_records_db);
9662  cc_record = misdn_cc_find_by_invoke(bc->port, bc->fac_in.u.CCBSDeactivate.InvokeID);
9663  if (cc_record) {
9664  cc_record->outstanding_message = 0;
9665  }
9666  AST_LIST_UNLOCK(&misdn_cc_records_db);
9667  break;
9668 
9669  default:
9670  chan_misdn_log(0, bc->port, " --> not yet handled: facility type:0x%04X\n",
9671  bc->fac_in.Function);
9672  break;
9673  }
9674  break;
9675  case Fac_CCBSErase:
9676  AST_LIST_LOCK(&misdn_cc_records_db);
9677  cc_record = misdn_cc_find_by_reference(bc->port, bc->fac_in.u.CCBSErase.CCBSReference);
9678  if (cc_record) {
9679  misdn_cc_delete(cc_record);
9680  }
9681  AST_LIST_UNLOCK(&misdn_cc_records_db);
9682  break;
9683  case Fac_CCBSRemoteUserFree:
9684  misdn_cc_handle_remote_user_free(bc->port, &bc->fac_in);
9685  break;
9686  case Fac_CCBSBFree:
9687  misdn_cc_handle_b_free(bc->port, &bc->fac_in);
9688  break;
9689  case Fac_CCBSStatusRequest:
9690  misdn_cc_handle_ccbs_status_request(bc->port, &bc->fac_in);
9691  break;
9692  case Fac_EraseCallLinkageID:
9693  AST_LIST_LOCK(&misdn_cc_records_db);
9694  cc_record = misdn_cc_find_by_linkage(bc->port,
9695  bc->fac_in.u.EraseCallLinkageID.CallLinkageID);
9696  if (cc_record && !cc_record->activation_requested) {
9697  /*
9698  * The T-RETENTION timer expired before we requested
9699  * call completion activation. Call completion is no
9700  * longer available.
9701  */
9702  misdn_cc_delete(cc_record);
9703  }
9704  AST_LIST_UNLOCK(&misdn_cc_records_db);
9705  break;
9706  case Fac_CCBSStopAlerting:
9707  /* We do not have anything to do for this message. */
9708  break;
9709  case Fac_CCBSRequest:
9710  case Fac_CCNRRequest:
9711  switch (bc->fac_in.u.CCBSRequest.ComponentType) {
9712  case FacComponent_Result:
9713  AST_LIST_LOCK(&misdn_cc_records_db);
9714  cc_record = misdn_cc_find_by_invoke(bc->port, bc->fac_in.u.CCBSRequest.InvokeID);
9715  if (cc_record && !cc_record->ptp) {
9716  cc_record->outstanding_message = 0;
9717  cc_record->activated = 1;
9718  cc_record->mode.ptmp.recall_mode = bc->fac_in.u.CCBSRequest.Component.Result.RecallMode;
9719  cc_record->mode.ptmp.reference_id = bc->fac_in.u.CCBSRequest.Component.Result.CCBSReference;
9720  }
9721  AST_LIST_UNLOCK(&misdn_cc_records_db);
9722  break;
9723 
9724  default:
9725  chan_misdn_log(0, bc->port, " --> not yet handled: facility type:0x%04X\n",
9726  bc->fac_in.Function);
9727  break;
9728  }
9729  break;
9730 #if 0 /* We don't handle this yet */
9731  case Fac_CCBSInterrogate:
9732  case Fac_CCNRInterrogate:
9733  /* We don't handle this yet */
9734  break;
9735  case Fac_StatusRequest:
9736  /* We don't handle this yet */
9737  break;
9738 #endif /* We don't handle this yet */
9739 #if 0 /* We don't handle this yet */
9740  case Fac_CCBS_T_Suspend:
9741  case Fac_CCBS_T_Resume:
9742  /* We don't handle this yet */
9743  break;
9744 #endif /* We don't handle this yet */
9745  case Fac_CCBS_T_RemoteUserFree:
9746  misdn_cc_handle_T_remote_user_free(bc);
9747  break;
9748  case Fac_CCBS_T_Available:
9749  switch (event) {
9750  case EVENT_ALERTING:
9751  case EVENT_DISCONNECT:
9752  /* CCBS-T/CCNR-T is available */
9753  if (ch && ch->peer) {
9754  int set_id = 1;
9755 
9756  AST_LIST_LOCK(&misdn_cc_records_db);
9757  if (ch->record_id == -1) {
9758  cc_record = misdn_cc_new();
9759  } else {
9760  /*
9761  * We are doing a call-completion attempt
9762  * or the switch is sending us extra call-completion
9763  * availability indications (erroneously?).
9764  */
9765  cc_record = misdn_cc_find_by_id(ch->record_id);
9766  if (cc_record) {
9767  if (cc_record->ptp && cc_record->mode.ptp.retention_enabled) {
9768  /*
9769  * Call-completion is still activated.
9770  * The user does not have to request it again.
9771  */
9772  chan_misdn_log(1, bc->port, " --> Call-completion request retention option is enabled\n");
9773 
9774  set_id = 0;
9775  } else {
9776  if (cc_record->ptp && cc_record->mode.ptp.bc) {
9777  /*
9778  * The network request retention option
9779  * is not on and the current call-completion
9780  * request is to be disabled.
9781  *
9782  * We should get here only if EVENT_DISCONNECT
9783  *
9784  * Close the call-completion signaling link
9785  */
9786  cc_record->mode.ptp.bc->fac_out.Function = Fac_None;
9787  cc_record->mode.ptp.bc->out_cause = AST_CAUSE_NORMAL_CLEARING;
9788  misdn_lib_send_event(cc_record->mode.ptp.bc, EVENT_RELEASE_COMPLETE);
9789  }
9790 
9791  /*
9792  * Resetup the existing record for a possible new
9793  * call-completion request.
9794  */
9795  new_record_id = misdn_cc_record_id_new();
9796  if (new_record_id < 0) {
9797  /* Looks like we must keep the old id anyway. */
9798  } else {
9799  cc_record->record_id = new_record_id;
9800  ch->record_id = new_record_id;
9801  }
9802  cc_record->ptp = 1;
9803  cc_record->port = bc->port;
9804  memset(&cc_record->mode, 0, sizeof(cc_record->mode));
9805  cc_record->invoke_id = ++misdn_invoke_id;
9806  cc_record->activated = 0;
9807  cc_record->outstanding_message = 0;
9808  cc_record->activation_requested = 0;
9809  cc_record->error_code = FacError_None;
9810  cc_record->reject_code = FacReject_None;
9811  memset(&cc_record->remote_user_free, 0, sizeof(cc_record->remote_user_free));
9812  memset(&cc_record->b_free, 0, sizeof(cc_record->b_free));
9813  cc_record->time_created = time(NULL);
9814  }
9815  cc_record = NULL;
9816  } else {
9817  /*
9818  * Where did the record go? We will have to recapture
9819  * the call setup information. Unfortunately, some
9820  * setup information may have been changed.
9821  */
9822  ch->record_id = -1;
9823  cc_record = misdn_cc_new();
9824  }
9825  }
9826  if (cc_record) {
9827  ch->record_id = cc_record->record_id;
9828  cc_record->ptp = 1;
9829  cc_record->port = bc->port;
9830 
9831  /* Record call information for possible call-completion attempt. */
9832  cc_record->redial.caller = bc->caller;
9833  cc_record->redial.dialed = bc->dialed;
9834  cc_record->redial.setup_bc_hlc_llc = bc->setup_bc_hlc_llc;
9835  cc_record->redial.capability = bc->capability;
9836  cc_record->redial.hdlc = bc->hdlc;
9837  }
9838  AST_LIST_UNLOCK(&misdn_cc_records_db);
9839 
9840  /* Set MISDN_CC_RECORD_ID in original channel */
9841  if (ch->record_id != -1 && set_id) {
9842  snprintf(buf, sizeof(buf), "%ld", ch->record_id);
9843  } else {
9844  buf[0] = 0;
9845  }
9846  misdn_cc_set_peer_var(ch->peer, MISDN_CC_RECORD_ID, buf);
9847  }
9848  break;
9849  default:
9850  chan_misdn_log(0, bc->port,
9851  " --> Expected in a DISCONNECT or ALERTING message: facility type:0x%04X\n",
9852  bc->fac_in.Function);
9853  break;
9854  }
9855  break;
9856  case Fac_CCBS_T_Request:
9857  case Fac_CCNR_T_Request:
9858  switch (bc->fac_in.u.CCBS_T_Request.ComponentType) {
9859  case FacComponent_Result:
9860  AST_LIST_LOCK(&misdn_cc_records_db);
9861  cc_record = misdn_cc_find_by_invoke(bc->port, bc->fac_in.u.CCBS_T_Request.InvokeID);
9862  if (cc_record && cc_record->ptp) {
9863  cc_record->outstanding_message = 0;
9864  cc_record->activated = 1;
9865  cc_record->mode.ptp.retention_enabled =
9866  cc_record->mode.ptp.requested_retention
9867  ? bc->fac_in.u.CCBS_T_Request.Component.Result.RetentionSupported
9868  ? 1 : 0
9869  : 0;
9870  }
9871  AST_LIST_UNLOCK(&misdn_cc_records_db);
9872  break;
9873 
9874  case FacComponent_Invoke:
9875  /* We cannot be User-B in ptp mode. */
9876  default:
9877  chan_misdn_log(0, bc->port, " --> not yet handled: facility type:0x%04X\n",
9878  bc->fac_in.Function);
9879  break;
9880  }
9881  break;
9882 
9883 #endif /* defined(AST_MISDN_ENHANCEMENTS) */
9884  case Fac_None:
9885  break;
9886  default:
9887  chan_misdn_log(0, bc->port, " --> not yet handled: facility type:0x%04X\n",
9888  bc->fac_in.Function);
9889  break;
9890  }
9891 }
static void chan_misdn_log(int level, int port, char *tmpl,...)
Definition: chan_misdn.c:12768
struct FacParm fac_out
Outbound FACILITY message function type and contents.
Definition: isdn_lib.h:512
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
char number[MISDN_MAX_NUMBER_LEN]
Phone number (Address)
Definition: isdn_lib.h:298
int ast_queue_control(struct ast_channel *chan, enum ast_control_frame_type control)
Queue a control frame without payload.
Definition: channel.c:1231
union misdn_bchannel::@161 AOCD
int presentation
Q.931 presentation-indicator and screening-indicator encoded fields.
Definition: channel.h:296
void ast_party_id_reset(struct ast_party_id *id)
Destroy and initialize the given party id structure.
Definition: channel.c:1896
enum FacFunction AOCDtype
Definition: isdn_lib.h:515
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
char incoming_cid_tag[MISDN_MAX_NAME_LEN]
Incoming Caller ID string tag for special purpose.
Definition: isdn_lib.h:348
Connected-Line/Calling/Redirecting ID info struct.
Definition: isdn_lib.h:273
int hdlc
TRUE if call made in digital HDLC mode.
Definition: isdn_lib.h:635
int presentation
Number presentation restriction code 0=Allowed, 1=Restricted, 2=Unavailable.
Definition: isdn_lib.h:277
Definition: astman.c:222
static void misdn_copy_redirecting_to_ast(struct ast_channel *ast, const struct misdn_party_redirecting *redirect, char *tag)
Definition: chan_misdn.c:6437
int capability
SETUP message bearer capability field code value.
Definition: isdn_lib.h:609
int AOCD_need_export
TRUE if AOCDtype and AOCD data are ready to export to Asterisk.
Definition: isdn_lib.h:521
#define NULL
Definition: resample.c:96
struct ast_channel * ast
Associated Asterisk channel structure.
Definition: chan_misdn.c:515
struct misdn_party_id to
Where the call is being redirected toward (Sent to the calling party)
Definition: isdn_lib.h:310
#define AST_PRES_RESTRICTED
Definition: callerid.h:325
static void print_facility(const struct FacParm *fac, const struct misdn_bchannel *bc)
Definition: chan_misdn.c:2762
char number[MISDN_MAX_NUMBER_LEN]
Dialed/Called Phone Number (Address)
Definition: isdn_lib.h:266
#define AST_PRES_USER_NUMBER_UNSCREENED
Definition: callerid.h:318
#define AST_CAUSE_NORMAL_CLEARING
Definition: causes.h:105
enum mISDN_NUMBER_TYPE number_type
Type-of-number in ISDN terms for the number.
Definition: isdn_lib.h:285
struct misdn_party_id caller
Originating/Caller ID information struct.
Definition: isdn_lib.h:343
char name[MISDN_MAX_NAME_LEN]
Subscriber Name.
Definition: isdn_lib.h:295
struct FacAOCDCurrency currency
Definition: isdn_lib.h:517
int originator
Who originally created this channel. ORG_AST or ORG_MISDN.
Definition: chan_misdn.c:407
struct misdn_party_id from
Who is redirecting the call (Sent to the party the call is redirected toward)
Definition: isdn_lib.h:307
enum mISDN_NUMBER_TYPE number_type
Type-of-number in ISDN terms for the dialed/called number.
Definition: isdn_lib.h:260
static void misdn_add_number_prefix(int port, enum mISDN_NUMBER_TYPE number_type, char *number, size_t size)
Definition: chan_misdn.c:3424
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)
Definition: chan_misdn.c:6210
struct misdn_party_redirecting redirecting
Redirecting information struct (Where a call diversion or transfer was invoked)
Definition: isdn_lib.h:358
int port
Logical Layer 1 port associated with this B channel.
Definition: isdn_lib.h:370
Redirecting Line information. RDNIS (Redirecting Directory Number Information Service) Where a call d...
Definition: channel.h:523
struct misdn_party_dialing dialed
Dialed/Called information struct.
Definition: isdn_lib.h:337
int to_changed
TRUE if the redirecting.to information has changed.
Definition: isdn_lib.h:319
struct ast_party_redirecting * ast_channel_redirecting(struct ast_channel *chan)
static void export_aoc_vars(int originator, struct ast_channel *ast, struct misdn_bchannel *bc)
Definition: chan_misdn.c:3458
void ast_party_redirecting_free(struct ast_party_redirecting *doomed)
Destroy the redirecting information contents.
Definition: channel.c:2179
enum mISDN_REDIRECTING_REASON reason
Reason a call is being redirected (Q.931 field value)
Definition: isdn_lib.h:313
struct ast_party_id to
Call is redirecting to a new party (Sent to the caller)
Definition: channel.h:531
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
void ast_party_redirecting_init(struct ast_party_redirecting *init)
Initialize the given redirecting structure.
Definition: channel.c:2122
enum mISDN_NOTIFY_CODE notify_description_code
Notification indicator ie description code.
Definition: isdn_lib.h:606
#define AST_PRES_ALLOWED
Definition: callerid.h:324
int misdn_lib_send_event(struct misdn_bchannel *bc, enum event_e event)
Definition: isdn_lib.c:3523
void ast_channel_queue_redirecting_update(struct ast_channel *chan, const struct ast_party_redirecting *redirecting, const struct ast_set_party_redirecting *update)
Queue a redirecting update frame on a channel.
Definition: channel.c:10392
int screening
Number screening code 0=Unscreened, 1=Passed Screen, 2=Failed Screen, 3=Network Number.
Definition: isdn_lib.h:282
struct FacParm fac_in
Inbound FACILITY message function type and contents.
Definition: isdn_lib.h:507
enum mISDN_NUMBER_PLAN number_plan
Type-of-number numbering plan.
Definition: isdn_lib.h:288
struct FacAOCDChargingUnit chargingUnit
Definition: isdn_lib.h:518
void ast_party_redirecting_copy(struct ast_party_redirecting *dest, const struct ast_party_redirecting *src)
Copy the source redirecting information to the destination redirecting.
Definition: channel.c:2135
int count
Number of times the call has been redirected.
Definition: isdn_lib.h:316
enum mISDN_NUMBER_PLAN number_plan
Type-of-number numbering plan.
Definition: isdn_lib.h:263
struct ast_party_number number
Subscriber phone number.
Definition: channel.h:343

◆ misdn_fixup()

static int misdn_fixup ( struct ast_channel oldast,
struct ast_channel ast 
)
static

Definition at line 6958 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.

6959 {
6960  struct chan_list *p;
6961 
6962  if (!ast || !(p = MISDN_ASTERISK_TECH_PVT(ast))) {
6963  return -1;
6964  }
6965 
6966  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);
6967 
6968  p->ast = ast;
6969 
6970  return 0;
6971 }
static void chan_misdn_log(int level, int port, char *tmpl,...)
Definition: chan_misdn.c:12768
static const char * misdn_get_ch_state(struct chan_list *p)
Definition: chan_misdn.c:4102
#define MISDN_ASTERISK_TECH_PVT(ast)
Definition: chan_misdn.c:683
struct ast_channel * ast
Associated Asterisk channel structure.
Definition: chan_misdn.c:515
int port
Logical Layer 1 port associated with this B channel.
Definition: isdn_lib.h:370
Channel call record structure.
Definition: chan_misdn.c:377
unsigned int l3id
From associated B channel: Layer 3 process ID.
Definition: chan_misdn.c:541
struct misdn_bchannel * bc
Associated B channel structure.
Definition: chan_misdn.c:520

◆ misdn_get_ch_state()

static const char* misdn_get_ch_state ( struct chan_list p)
static

Definition at line 4102 of file chan_misdn.c.

References ARRAY_LEN, NULL, chan_list::state, state, and state_struct::txt.

Referenced by cb_events(), misdn_fixup(), misdn_hangup(), misdn_write(), and print_bc_info().

4103 {
4104  int i;
4105  static char state[8];
4106 
4107  if (!p) {
4108  return NULL;
4109  }
4110 
4111  for (i = 0; i < ARRAY_LEN(state_array); i++) {
4112  if (state_array[i].state == p->state) {
4113  return state_array[i].txt;
4114  }
4115  }
4116 
4117  snprintf(state, sizeof(state), "%d", p->state) ;
4118 
4119  return state;
4120 }
enum sip_cc_notify_state state
Definition: chan_sip.c:959
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
char txt[255]
Definition: chan_misdn.c:4080
#define NULL
Definition: resample.c:96
static const struct state_struct state_array[]
Definition: chan_misdn.c:4083
enum misdn_chan_state state
State of the channel.
Definition: chan_misdn.c:386

◆ misdn_get_connected_line()

static void misdn_get_connected_line ( struct ast_channel ast,
struct misdn_bchannel bc,
int  originator 
)
static

Definition at line 6226 of file chan_misdn.c.

References ast_channel_connected_effective_id(), ast_copy_string(), ast_to_misdn_plan(), ast_to_misdn_pres(), ast_to_misdn_screen(), ast_to_misdn_ton(), misdn_bchannel::caller, misdn_bchannel::connected, debug_numtype(), MISDN_CFG_CPNDIALPLAN, misdn_cfg_get(), MISDN_CFG_LOCALDIALPLAN, misdn_party_id::name, ast_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, misdn_party_id::presentation, ast_party_number::presentation, S_COR, S_OR, misdn_party_id::screening, ast_party_name::str, ast_party_number::str, ast_party_name::valid, and ast_party_number::valid.

Referenced by misdn_update_connected_line().

6227 {
6228  int number_type;
6229  struct ast_party_id connected_id = ast_channel_connected_effective_id(ast);
6230 
6231  if (originator == ORG_MISDN) {
6232  /* ORIGINATOR MISDN (incoming call) */
6233 
6235  S_COR(connected_id.name.valid, connected_id.name.str, ""),
6236  sizeof(bc->connected.name));
6237  if (connected_id.number.valid) {
6238  ast_copy_string(bc->connected.number, S_OR(connected_id.number.str, ""),
6239  sizeof(bc->connected.number));
6242  bc->connected.number_type = ast_to_misdn_ton(connected_id.number.plan);
6243  bc->connected.number_plan = ast_to_misdn_plan(connected_id.number.plan);
6244  } else {
6245  bc->connected.number[0] = '\0';
6246  bc->connected.presentation = 0;/* Allowed */
6247  bc->connected.screening = 0;/* Unscreened */
6250  }
6251 
6252  misdn_cfg_get(bc->port, MISDN_CFG_CPNDIALPLAN, &number_type, sizeof(number_type));
6253  if (0 <= number_type) {
6254  /* Force us to send in CONNECT message */
6255  bc->connected.number_type = number_type;
6257  }
6258  debug_numtype(bc->port, bc->connected.number_type, "CTON");
6259  } else {
6260  /* ORIGINATOR Asterisk (outgoing call) */
6261 
6263  S_COR(connected_id.name.valid, connected_id.name.str, ""),
6264  sizeof(bc->caller.name));
6265  if (connected_id.number.valid) {
6266  ast_copy_string(bc->caller.number, S_OR(connected_id.number.str, ""),
6267  sizeof(bc->caller.number));
6270  bc->caller.number_type = ast_to_misdn_ton(connected_id.number.plan);
6271  bc->caller.number_plan = ast_to_misdn_plan(connected_id.number.plan);
6272  } else {
6273  bc->caller.number[0] = '\0';
6274  bc->caller.presentation = 0;/* Allowed */
6275  bc->caller.screening = 0;/* Unscreened */
6278  }
6279 
6280  misdn_cfg_get(bc->port, MISDN_CFG_LOCALDIALPLAN, &number_type, sizeof(number_type));
6281  if (0 <= number_type) {
6282  /* Force us to send in SETUP message */
6283  bc->caller.number_type = number_type;
6285  }
6286  debug_numtype(bc->port, bc->caller.number_type, "LTON");
6287  }
6288 }
Information needed to identify an endpoint in a call.
Definition: channel.h:339
static int ast_to_misdn_pres(int presentation)
Definition: chan_misdn.c:2145
char * str
Subscriber phone number (Malloced)
Definition: channel.h:292
void debug_numtype(int port, int numtype, char *type)
Definition: chan_misdn.c:5853
char number[MISDN_MAX_NUMBER_LEN]
Phone number (Address)
Definition: isdn_lib.h:298
int presentation
Q.931 presentation-indicator and screening-indicator encoded fields.
Definition: channel.h:296
struct ast_party_name name
Subscriber name.
Definition: channel.h:341
int presentation
Number presentation restriction code 0=Allowed, 1=Restricted, 2=Unavailable.
Definition: isdn_lib.h:277
char * str
Subscriber name (Malloced)
Definition: channel.h:265
void misdn_cfg_get(int port, enum misdn_cfg_elements elem, void *buf, int bufsize)
Definition: misdn_config.c:569
#define S_COR(a, b, c)
returns the equivalent of logic or for strings, with an additional boolean check: second one if not e...
Definition: strings.h:85
enum mISDN_NUMBER_TYPE number_type
Type-of-number in ISDN terms for the number.
Definition: isdn_lib.h:285
struct misdn_party_id caller
Originating/Caller ID information struct.
Definition: isdn_lib.h:343
char name[MISDN_MAX_NAME_LEN]
Subscriber Name.
Definition: isdn_lib.h:295
struct misdn_party_id connected
Connected-Party/Connected-Line ID information struct.
Definition: isdn_lib.h:353
struct ast_party_id ast_channel_connected_effective_id(struct ast_channel *chan)
int plan
Q.931 Type-Of-Number and Numbering-Plan encoded fields.
Definition: channel.h:294
static int ast_to_misdn_screen(int screening)
Definition: chan_misdn.c:2242
int port
Logical Layer 1 port associated with this B channel.
Definition: isdn_lib.h:370
#define ORG_MISDN
Definition: chan_misdn.c:345
static enum mISDN_NUMBER_TYPE ast_to_misdn_ton(unsigned ast_number_type)
Definition: chan_misdn.c:1916
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:79
unsigned char valid
TRUE if the name information is valid/present.
Definition: channel.h:280
int screening
Number screening code 0=Unscreened, 1=Passed Screen, 2=Failed Screen, 3=Network Number.
Definition: isdn_lib.h:282
unsigned char valid
TRUE if the number information is valid/present.
Definition: channel.h:298
enum mISDN_NUMBER_PLAN number_plan
Type-of-number numbering plan.
Definition: isdn_lib.h:288
static enum mISDN_NUMBER_PLAN ast_to_misdn_plan(unsigned ast_number_plan)
Definition: chan_misdn.c:2042
struct ast_party_number number
Subscriber phone number.
Definition: channel.h:343

◆ misdn_hangup()

static int misdn_hangup ( struct ast_channel ast)
static

Definition at line 7117 of file chan_misdn.c.

References chan_list::ast, AST_CAUSE_NORMAL_CLEARING, ast_channel_caller(), ast_channel_context(), ast_channel_exten(), ast_channel_hangupcause(), ast_channel_name(), ast_copy_string(), ast_debug, ast_log, ast_mutex_lock, ast_mutex_unlock, AST_STATE_RESERVED, bc, chan_list::bc, misdn_bchannel::cause, chan_list_unref, chan_misdn_log(), EVENT_DISCONNECT, EVENT_RELEASE, EVENT_RELEASE_COMPLETE, hanguptone_indicate(), chan_list::hold, INFO_PI_INBAND_AVAILABLE, chan_list::l3id, LOG_NOTICE, LOG_WARNING, MISDN_ALERTING, MISDN_ASTERISK_TECH_PVT, MISDN_ASTERISK_TECH_PVT_SET, 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, 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, NULL, ORG_AST, chan_list::originator, misdn_bchannel::out_cause, pbx_builtin_getvar_helper(), misdn_bchannel::pid, hold_info::port, misdn_bchannel::port, misdn_bchannel::progress_indicator, release_chan(), release_chan_early(), start_bc_tones(), hold_info::state, chan_list::state, stop_bc_tones(), misdn_bchannel::uu, misdn_bchannel::uulen, and var.

7118 {
7119  struct chan_list *p;
7120  struct misdn_bchannel *bc;
7121  const char *var;
7122 
7123  if (!ast) {
7124  return -1;
7125  }
7126 
7127  ast_debug(1, "misdn_hangup(%s)\n", ast_channel_name(ast));
7128 
7129  /* Take the ast_channel's tech_pvt reference. */
7131  p = MISDN_ASTERISK_TECH_PVT(ast);
7132  if (!p) {
7134  return -1;
7135  }
7137 
7138  if (!misdn_chan_is_valid(p)) {
7140  chan_list_unref(p, "Release ast_channel reference. Was not active?");
7141  return 0;
7142  }
7143 
7144  if (p->hold.state == MISDN_HOLD_IDLE) {
7145  bc = p->bc;
7146  } else {
7148  bc = misdn_lib_find_held_bc(p->hold.port, p->l3id);
7149  if (!bc) {
7150  chan_misdn_log(4, p->hold.port,
7151  "misdn_hangup: Could not find held bc for (%s)\n", ast_channel_name(ast));
7152  release_chan_early(p);
7154  chan_list_unref(p, "Release ast_channel reference");
7155  return 0;
7156  }
7157  }
7158 
7160  /* between request and call */
7161  ast_debug(1, "State Reserved (or nothing) => chanIsAvail\n");
7162  release_chan_early(p);
7163  if (bc) {
7164  misdn_lib_release(bc);
7165  }
7167  chan_list_unref(p, "Release ast_channel reference");
7168  return 0;
7169  }
7170  if (!bc) {
7171  ast_log(LOG_WARNING, "Hangup with private but no bc ? state:%s l3id:%x\n",
7172  misdn_get_ch_state(p), p->l3id);
7173  release_chan_early(p);
7175  chan_list_unref(p, "Release ast_channel reference");
7176  return 0;
7177  }
7178 
7179  p->ast = NULL;
7180  p->need_hangup = 0;
7181  p->need_queue_hangup = 0;
7182  p->need_busy = 0;
7183 
7184  if (!bc->nt) {
7185  stop_bc_tones(p);
7186  }
7187 
7189 
7190  /* Channel lock is already held when we are called. */
7191  //ast_channel_lock(ast);
7192  var = pbx_builtin_getvar_helper(ast, "HANGUPCAUSE");
7193  if (!var) {
7194  var = pbx_builtin_getvar_helper(ast, "PRI_CAUSE");
7195  }
7196  if (var) {
7197  int tmpcause;
7198 
7199  tmpcause = atoi(var);
7200  bc->out_cause = tmpcause ? tmpcause : AST_CAUSE_NORMAL_CLEARING;
7201  }
7202 
7203  var = pbx_builtin_getvar_helper(ast, "MISDN_USERUSER");
7204  if (var) {
7205  ast_log(LOG_NOTICE, "MISDN_USERUSER: %s\n", var);
7206  ast_copy_string(bc->uu, var, sizeof(bc->uu));
7207  bc->uulen = strlen(bc->uu);
7208  }
7209  //ast_channel_unlock(ast);
7210 
7211  chan_misdn_log(1, bc->port,
7212  "* IND : HANGUP\tpid:%d context:%s dialed:%s caller:\"%s\" <%s> State:%s\n",
7213  bc->pid,
7214  ast_channel_context(ast),
7215  ast_channel_exten(ast),
7216  (ast_channel_caller(ast)->id.name.valid && ast_channel_caller(ast)->id.name.str)
7217  ? ast_channel_caller(ast)->id.name.str : "",
7218  (ast_channel_caller(ast)->id.number.valid && ast_channel_caller(ast)->id.number.str)
7219  ? ast_channel_caller(ast)->id.number.str : "",
7220  misdn_get_ch_state(p));
7221  chan_misdn_log(3, bc->port, " --> l3id:%x\n", p->l3id);
7222  chan_misdn_log(3, bc->port, " --> cause:%d\n", bc->cause);
7223  chan_misdn_log(2, bc->port, " --> out_cause:%d\n", bc->out_cause);
7224 
7225  switch (p->state) {
7226  case MISDN_INCOMING_SETUP:
7227  /*
7228  * This is the only place in misdn_hangup, where we
7229  * can call release_chan, else it might create a lot of trouble.
7230  */
7231  ast_log(LOG_NOTICE, "release channel, in INCOMING_SETUP state.. no other events happened\n");
7232  release_chan(p, bc);
7235  chan_list_unref(p, "Release ast_channel reference");
7236  return 0;
7237  case MISDN_DIALING:
7238  if (p->hold.state == MISDN_HOLD_IDLE) {
7239  start_bc_tones(p);
7241  }
7242 
7243  if (bc->need_disconnect) {
7245  }
7246  break;
7248  if (p->hold.state == MISDN_HOLD_IDLE) {
7249  start_bc_tones(p);
7251  }
7252 
7253  if (bc->need_disconnect) {
7255  }
7256  break;
7257 
7258  case MISDN_CALLING:
7259  case MISDN_ALERTING:
7260  case MISDN_PROGRESS:
7261  case MISDN_PROCEEDING:
7262  if (p->originator != ORG_AST && p->hold.state == MISDN_HOLD_IDLE) {
7264  }
7265 
7266  if (bc->need_disconnect) {
7268  }
7269  break;
7270  case MISDN_CONNECTED:
7271  /* Alerting or Disconnect */
7272  if (bc->nt && p->hold.state == MISDN_HOLD_IDLE) {
7273  start_bc_tones(p);
7276  }
7277  if (bc->need_disconnect) {
7279  }
7280  break;
7281  case MISDN_DISCONNECTED:
7282  if (bc->need_release) {
7284  }
7285  break;
7286 
7287  case MISDN_CLEANING:
7289  chan_list_unref(p, "Release ast_channel reference");
7290  return 0;
7291 
7292  case MISDN_BUSY:
7293  break;
7294  default:
7295  if (bc->nt) {
7296  bc->out_cause = -1;
7297  if (bc->need_release) {
7299  }
7300  } else {
7301  if (bc->need_disconnect) {
7303  }
7304  }
7305  break;
7306  }
7307 
7308  p->state = MISDN_CLEANING;
7309  chan_misdn_log(3, bc->port, " --> Channel: %s hungup new state:%s\n", ast_channel_name(ast),
7310  misdn_get_ch_state(p));
7311 
7313  chan_list_unref(p, "Release ast_channel reference");
7314  return 0;
7315 }
struct ast_party_caller * ast_channel_caller(struct ast_channel *chan)
int need_busy
TRUE if we could send an AST_CONTROL_BUSY if needed.
Definition: chan_misdn.c:402
static void chan_misdn_log(int level, int port, char *tmpl,...)
Definition: chan_misdn.c:12768
static void hanguptone_indicate(struct chan_list *cl)
Definition: chan_misdn.c:7738
int need_hangup
TRUE if a channel can be hung up by calling asterisk directly when done.
Definition: chan_misdn.c:397
int need_queue_hangup
TRUE if a hangup needs to be queued.
Definition: chan_misdn.c:392
#define bc
int uulen
User-User information string length in uu[].
Definition: isdn_lib.h:666
char uu[256]
User-User information string.
Definition: isdn_lib.h:663
static void release_chan_early(struct chan_list *ch)
Definition: chan_misdn.c:8561
#define LOG_WARNING
Definition: logger.h:274
static void release_chan(struct chan_list *ch, struct misdn_bchannel *bc)
Definition: chan_misdn.c:8495
#define var
Definition: ast_expr2f.c:614
struct hold_info hold
HELD channel call information.
Definition: chan_misdn.c:535
B channel control structure.
Definition: isdn_lib.h:324
static const char * misdn_get_ch_state(struct chan_list *p)
Definition: chan_misdn.c:4102
ast_channel_state
ast_channel states
Definition: channelstate.h:35
#define MISDN_ASTERISK_TECH_PVT(ast)
Definition: chan_misdn.c:683
#define ast_mutex_lock(a)
Definition: lock.h:187
struct misdn_bchannel * misdn_lib_find_held_bc(int port, int l3_id)
Find a held call&#39;s B channel record.
Definition: isdn_lib.c:4580
#define NULL
Definition: resample.c:96
static int misdn_chan_is_valid(struct chan_list *ch)
Definition: chan_misdn.c:749
struct ast_channel * ast
Associated Asterisk channel structure.
Definition: chan_misdn.c:515
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.
static int stop_bc_tones(struct chan_list *cl)
Definition: chan_misdn.c:7772
Number structure.
Definition: app_followme.c:154
static ast_mutex_t release_lock
Definition: chan_misdn.c:323
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
void misdn_lib_release(struct misdn_bchannel *bc)
Definition: isdn_lib.c:1759
#define AST_CAUSE_NORMAL_CLEARING
Definition: causes.h:105
int nt
TRUE if NT side of protocol (TE otherwise)
Definition: isdn_lib.h:364
enum misdn_chan_state state
State of the channel.
Definition: chan_misdn.c:386
const char * ast_channel_exten(const struct ast_channel *chan)
#define MISDN_ASTERISK_TECH_PVT_SET(ast, value)
Definition: chan_misdn.c:684
int port
Logical port the channel call record is HELD on because the B channel is no longer associated...
Definition: chan_misdn.c:362
int pid
B channel process ID (1-5000)
Definition: isdn_lib.h:402
int originator
Who originally created this channel. ORG_AST or ORG_MISDN.
Definition: chan_misdn.c:407
int port
Logical Layer 1 port associated with this B channel.
Definition: isdn_lib.h:370
#define LOG_NOTICE
Definition: logger.h:263
static const char name[]
Definition: cdr_mysql.c:74
Channel call record structure.
Definition: chan_misdn.c:377
unsigned int l3id
From associated B channel: Layer 3 process ID.
Definition: chan_misdn.c:541
enum misdn_hold_state state
Call HOLD state.
Definition: chan_misdn.c:357
int out_cause
Q.931 Cause for disconnection code (sent)
Definition: isdn_lib.h:677
int need_release
TRUE if RELEASE needs to be sent to clear a call.
Definition: isdn_lib.h:389
int ast_channel_hangupcause(const struct ast_channel *chan)
static int start_bc_tones(struct chan_list *cl)
Definition: chan_misdn.c:7764
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
int need_disconnect
TRUE if DISCONNECT needs to be sent to clear a call.
Definition: isdn_lib.h:386
const char * ast_channel_name(const struct ast_channel *chan)
int progress_indicator
Progress Indicator IE progress description field. Used to determine if there is an inband audio messa...
Definition: isdn_lib.h:492
int misdn_lib_send_event(struct misdn_bchannel *bc, enum event_e event)
Definition: isdn_lib.c:3523
#define ORG_AST
Definition: chan_misdn.c:343
const char * ast_channel_context(const struct ast_channel *chan)
int cause
Q.931 Cause for disconnection code (received)
Definition: isdn_lib.h:671
struct misdn_bchannel * bc
Associated B channel structure.
Definition: chan_misdn.c:520
#define chan_list_unref(obj, debug)
Definition: chan_misdn.c:372
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ misdn_indication()

static int misdn_indication ( struct ast_channel ast,
int  cond,
const void *  data,
size_t  datalen 
)
static

Definition at line 6975 of file chan_misdn.c.

References AST_CAUSE_INVALID_NUMBER_FORMAT, AST_CAUSE_SWITCH_CONGESTION, AST_CAUSE_USER_BUSY, ast_channel_name(), AST_CONTROL_ANSWER, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_CONNECTED_LINE, AST_CONTROL_FLASH, AST_CONTROL_HOLD, AST_CONTROL_INCOMPLETE, AST_CONTROL_MASQUERADE_NOTIFY, AST_CONTROL_OFFHOOK, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_PVT_CAUSE_CODE, AST_CONTROL_REDIRECTING, AST_CONTROL_RING, AST_CONTROL_RINGING, AST_CONTROL_TAKEOFFHOOK, AST_CONTROL_UNHOLD, ast_log, ast_moh_start(), ast_moh_stop(), ast_setstate(), AST_STATE_BUSY, AST_STATE_RING, chan_list::bc, chan_misdn_log(), EVENT_ALERTING, EVENT_DISCONNECT, EVENT_PROCEEDING, EVENT_PROGRESS, hanguptone_indicate(), chan_list::hold, chan_list::incoming_early_audio, LOG_WARNING, MISDN_ALERTING, MISDN_ASTERISK_TECH_PVT, MISDN_CONNECTED, MISDN_HOLD_IDLE, misdn_lib_send_event(), misdn_update_connected_line(), misdn_update_redirecting(), chan_list::mohinterpret, misdn_bchannel::nt, ORG_MISDN, chan_list::originator, misdn_bchannel::out_cause, chan_list::overlap_dial, misdn_bchannel::pid, misdn_bchannel::port, start_bc_tones(), hold_info::state, chan_list::state, and stop_indicate().

6976 {
6977  struct chan_list *p;
6978 
6979  if (!ast || !(p = MISDN_ASTERISK_TECH_PVT(ast))) {
6980  ast_log(LOG_WARNING, "Returned -1 in misdn_indication\n");
6981  return -1;
6982  }
6983 
6984  if (!p->bc) {
6985  if (p->hold.state == MISDN_HOLD_IDLE) {
6986  chan_misdn_log(1, 0, "* IND : Indication [%d] ignored on %s\n", cond,
6987  ast_channel_name(ast));
6988  ast_log(LOG_WARNING, "Private Pointer but no bc ?\n");
6989  } else {
6990  chan_misdn_log(1, 0, "* IND : Indication [%d] ignored on hold %s\n",
6991  cond, ast_channel_name(ast));
6992  }
6993  return -1;
6994  }
6995 
6996  chan_misdn_log(5, p->bc->port, "* IND : Indication [%d] on %s\n", cond, ast_channel_name(ast));
6997 
6998  switch (cond) {
6999  case AST_CONTROL_BUSY:
7000  chan_misdn_log(1, p->bc->port, "* IND :\tbusy pid:%d\n", p->bc->pid);
7002 
7004  if (p->state != MISDN_CONNECTED) {
7005  start_bc_tones(p);
7007  }
7008  return -1;
7009  case AST_CONTROL_RING:
7010  chan_misdn_log(1, p->bc->port, "* IND :\tring pid:%d\n", p->bc->pid);
7011  return -1;
7012  case AST_CONTROL_RINGING:
7013  chan_misdn_log(1, p->bc->port, "* IND :\tringing pid:%d\n", p->bc->pid);
7014  switch (p->state) {
7015  case MISDN_ALERTING:
7016  chan_misdn_log(2, p->bc->port, " --> * IND :\tringing pid:%d but I was Ringing before, so ignoring it\n", p->bc->pid);
7017  break;
7018  case MISDN_CONNECTED:
7019  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);
7020  return -1;
7021  default:
7022  p->state = MISDN_ALERTING;
7023  chan_misdn_log(2, p->bc->port, " --> * IND :\tringing pid:%d\n", p->bc->pid);
7025 
7026  chan_misdn_log(3, p->bc->port, " --> * SEND: State Ring pid:%d\n", p->bc->pid);
7028 
7029  if (!p->bc->nt && (p->originator == ORG_MISDN) && !p->incoming_early_audio) {
7030  chan_misdn_log(2, p->bc->port, " --> incoming_early_audio off\n");
7031  } else {
7032  return -1;
7033  }
7034  }
7035  break;
7036  case AST_CONTROL_ANSWER:
7037  chan_misdn_log(1, p->bc->port, " --> * IND :\tanswer pid:%d\n", p->bc->pid);
7038  start_bc_tones(p);
7039  break;
7041  chan_misdn_log(1, p->bc->port, " --> *\ttakeoffhook pid:%d\n", p->bc->pid);
7042  return -1;
7043  case AST_CONTROL_OFFHOOK:
7044  chan_misdn_log(1, p->bc->port, " --> *\toffhook pid:%d\n", p->bc->pid);
7045  return -1;
7046  case AST_CONTROL_FLASH:
7047  chan_misdn_log(1, p->bc->port, " --> *\tflash pid:%d\n", p->bc->pid);
7048  break;
7049  case AST_CONTROL_PROGRESS:
7050  chan_misdn_log(1, p->bc->port, " --> * IND :\tprogress pid:%d\n", p->bc->pid);
7052  break;
7054  chan_misdn_log(1, p->bc->port, " --> * IND :\tproceeding pid:%d\n", p->bc->pid);
7056  break;
7058  chan_misdn_log(1, p->bc->port, " --> *\tincomplete pid:%d\n", p->bc->pid);
7059  if (!p->overlap_dial) {
7060  /* Overlapped dialing not enabled - send hangup */
7062  start_bc_tones(p);
7064 
7065  if (p->bc->nt) {
7067  }
7068  }
7069  break;
7071  chan_misdn_log(1, p->bc->port, " --> * IND :\tcongestion pid:%d\n", p->bc->pid);
7072 
7074  start_bc_tones(p);
7076 
7077  if (p->bc->nt) {
7079  }
7080  break;
7081  case -1 :
7082  chan_misdn_log(1, p->bc->port, " --> * IND :\t-1! (stop indication) pid:%d\n", p->bc->pid);
7083 
7084  stop_indicate(p);
7085 
7086  if (p->state == MISDN_CONNECTED) {
7087  start_bc_tones(p);
7088  }
7089  break;
7090  case AST_CONTROL_HOLD:
7091  ast_moh_start(ast, data, p->mohinterpret);
7092  chan_misdn_log(1, p->bc->port, " --> *\tHOLD pid:%d\n", p->bc->pid);
7093  break;
7094  case AST_CONTROL_UNHOLD:
7095  ast_moh_stop(ast);
7096  chan_misdn_log(1, p->bc->port, " --> *\tUNHOLD pid:%d\n", p->bc->pid);
7097  break;
7099  chan_misdn_log(1, p->bc->port, "* IND :\tconnected line update pid:%d\n", p->bc->pid);
7101  break;
7103  chan_misdn_log(1, p->bc->port, "* IND :\tredirecting info update pid:%d\n", p->bc->pid);
7104  misdn_update_redirecting(ast, p->bc, p->originator);
7105  break;
7106  default:
7107  chan_misdn_log(1, p->bc->port, " --> * Unknown Indication:%d pid:%d\n", cond, p->bc->pid);
7108  /* fallthrough */
7111  return -1;
7112  }
7113 
7114  return 0;
7115 }
static void chan_misdn_log(int level, int port, char *tmpl,...)
Definition: chan_misdn.c:12768
static int stop_indicate(struct chan_list *cl)
Definition: chan_misdn.c:7743
static void hanguptone_indicate(struct chan_list *cl)
Definition: chan_misdn.c:7738
static void misdn_update_redirecting(struct ast_channel *ast, struct misdn_bchannel *bc, int originator)
Definition: chan_misdn.c:6483
#define AST_CAUSE_SWITCH_CONGESTION
Definition: causes.h:122
#define LOG_WARNING
Definition: logger.h:274
static void misdn_update_connected_line(struct ast_channel *ast, struct misdn_bchannel *bc, int originator)
Definition: chan_misdn.c:6300
struct hold_info hold
HELD channel call information.
Definition: chan_misdn.c:535
#define MISDN_ASTERISK_TECH_PVT(ast)
Definition: chan_misdn.c:683
char mohinterpret[MAX_MUSICCLASS]
The configured music-on-hold class to use for this call.
Definition: chan_misdn.c:559
#define AST_CAUSE_INVALID_NUMBER_FORMAT
Definition: causes.h:115
void ast_moh_stop(struct ast_channel *chan)
Turn off music on hold on a given channel.
Definition: channel.c:7876
#define ast_log
Definition: astobj2.c:42
ast_cond_t cond
Definition: app_meetme.c:1090
int nt
TRUE if NT side of protocol (TE otherwise)
Definition: isdn_lib.h:364
enum misdn_chan_state state
State of the channel.
Definition: chan_misdn.c:386
int pid
B channel process ID (1-5000)
Definition: isdn_lib.h:402
int originator
Who originally created this channel. ORG_AST or ORG_MISDN.
Definition: chan_misdn.c:407
int ast_moh_start(struct ast_channel *chan, const char *mclass, const char *interpclass)
Turn on music on hold on a given channel.
Definition: channel.c:7866
int incoming_early_audio
TRUE if you want to send Tone Indications to an incoming ISDN channel on a TE Port.
Definition: chan_misdn.c:432
int port
Logical Layer 1 port associated with this B channel.
Definition: isdn_lib.h:370
#define ORG_MISDN
Definition: chan_misdn.c:345
Channel call record structure.
Definition: chan_misdn.c:377
enum misdn_hold_state state
Call HOLD state.
Definition: chan_misdn.c:357
int out_cause
Q.931 Cause for disconnection code (sent)
Definition: isdn_lib.h:677
static int start_bc_tones(struct chan_list *cl)
Definition: chan_misdn.c:7764
const char * ast_channel_name(const struct ast_channel *chan)
#define AST_CAUSE_USER_BUSY
Definition: causes.h:106
int ast_setstate(struct ast_channel *chan, enum ast_channel_state)
Change the state of a channel.
Definition: channel.c:7486
int misdn_lib_send_event(struct misdn_bchannel *bc, enum event_e event)
Definition: isdn_lib.c:3523
struct misdn_bchannel * bc
Associated B channel structure.
Definition: chan_misdn.c:520
int overlap_dial
Enables overlap dialing for the set amount of seconds. (0 = Disabled)
Definition: chan_misdn.c:588

◆ misdn_is_msn_valid()

static int misdn_is_msn_valid ( int  port,
const struct misdn_party_dialing dialed 
)
static

Definition at line 9904 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().

9905 {
9906  char number[sizeof(dialed->number)];
9907 
9908  ast_copy_string(number, dialed->number, sizeof(number));
9909  misdn_add_number_prefix(port, dialed->number_type, number, sizeof(number));
9910  return misdn_cfg_is_msn_valid(port, number);
9911 }
Number structure.
Definition: app_followme.c:154
char number[MISDN_MAX_NUMBER_LEN]
Dialed/Called Phone Number (Address)
Definition: isdn_lib.h:266
enum mISDN_NUMBER_TYPE number_type
Type-of-number in ISDN terms for the dialed/called number.
Definition: isdn_lib.h:260
static void misdn_add_number_prefix(int port, enum mISDN_NUMBER_TYPE number_type, char *number, size_t size)
Definition: chan_misdn.c:3424
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
int misdn_cfg_is_msn_valid(int port, char *msn)
Definition: misdn_config.c:712

◆ misdn_jb_destroy()

void misdn_jb_destroy ( struct misdn_jb jb)

frees the data and destroys the given jitterbuffer struct

Definition at line 12639 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().

12640 {
12641  ast_mutex_destroy(&jb->mutexjb);
12642 
12643  ast_free(jb->ok);
12644  ast_free(jb->samples);
12645  ast_free(jb);
12646 }
ast_mutex_t mutexjb
Definition: chan_misdn.c:140
char * ok
Definition: chan_misdn.c:134
char * samples
Definition: chan_misdn.c:134
#define ast_free(a)
Definition: astmm.h:182
#define ast_mutex_destroy(a)
Definition: lock.h:186

◆ misdn_jb_empty()

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 12716 of file chan_misdn.c.

References ast_mutex_lock, ast_mutex_unlock, chan_misdn_log(), len(), 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().

12717 {
12718  int i;
12719  int wp;
12720  int rp;
12721  int read = 0;
12722 
12723  ast_mutex_lock(&jb->mutexjb);
12724 
12725  rp = jb->rp;
12726  wp = jb->wp;
12727 
12728  if (jb->state_empty) {
12729  for (i = 0; i < len; i++) {
12730  if (wp == rp) {
12731  jb->rp = rp;
12732  jb->state_empty = 0;
12733 
12734  ast_mutex_unlock(&jb->mutexjb);
12735 
12736  return read;
12737  } else {
12738  if (jb->ok[rp] == 1) {
12739  data[i] = jb->samples[rp];
12740  jb->ok[rp] = 0;
12741  rp = (rp != jb->size - 1) ? rp + 1 : 0;
12742  read += 1;
12743  }
12744  }
12745  }
12746 
12747  if (wp >= rp) {
12748  jb->state_buffer = wp - rp;
12749  } else {
12750  jb->state_buffer = jb->size - rp + wp;
12751  }
12752  chan_misdn_log(9, 0, "misdn_jb_empty: read:%d | Buffer status:%d p:%p\n", len, jb->state_buffer, jb);
12753 
12754  jb->rp = rp;
12755  } else {
12756  chan_misdn_log(9, 0, "misdn_jb_empty: Wait...requested:%d p:%p\n", len, jb);
12757  }
12758 
12759  ast_mutex_unlock(&jb->mutexjb);
12760 
12761  return read;
12762 }
static void chan_misdn_log(int level, int port, char *tmpl,...)
Definition: chan_misdn.c:12768
ast_mutex_t mutexjb
Definition: chan_misdn.c:140
char * ok
Definition: chan_misdn.c:134
int size
Definition: chan_misdn.c:132
int state_buffer
Definition: chan_misdn.c:138
#define ast_mutex_lock(a)
Definition: lock.h:187
char * samples
Definition: chan_misdn.c:134
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
#define ast_mutex_unlock(a)
Definition: lock.h:188
int state_empty
Definition: chan_misdn.c:136

◆ misdn_jb_fill()

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 12650 of file chan_misdn.c.

References ast_mutex_lock, ast_mutex_unlock, misdn_jb::bytes_wrote, chan_misdn_log(), len(), misdn_jb::mutexjb, misdn_jb::ok, misdn_jb::rp, misdn_jb::samples, misdn_jb::size, misdn_jb::state_buffer, misdn_jb::state_empty, misdn_jb::state_full, misdn_jb::upper_threshold, and misdn_jb::wp.

Referenced by misdn_write().

12651 {
12652  int i;
12653  int j;
12654  int rp;
12655  int wp;
12656 
12657  if (!jb || ! data) {
12658  return 0;
12659  }
12660 
12661  ast_mutex_lock(&jb->mutexjb);
12662 
12663  wp = jb->wp;
12664  rp = jb->rp;
12665 
12666  for (i = 0; i < len; i++) {
12667  jb->samples[wp] = data[i];
12668  jb->ok[wp] = 1;
12669  wp = (wp != jb->size - 1) ? wp + 1 : 0;
12670 
12671  if (wp == jb->rp) {
12672  jb->state_full = 1;
12673  }
12674  }
12675 
12676  if (wp >= rp) {
12677  jb->state_buffer = wp - rp;
12678  } else {
12679  jb->state_buffer = jb->size - rp + wp;
12680  }
12681  chan_misdn_log(9, 0, "misdn_jb_fill: written:%d | Buffer status:%d p:%p\n", len, jb->state_buffer, jb);
12682 
12683  if (jb->state_full) {
12684  jb->wp = wp;
12685 
12686  rp = wp;
12687  for (j = 0; j < jb->upper_threshold; j++) {
12688  rp = (rp != 0) ? rp - 1 : jb->size - 1;
12689  }
12690  jb->rp = rp;
12691  jb->state_full = 0;
12692  jb->state_empty = 1;
12693 
12694  ast_mutex_unlock(&jb->mutexjb);
12695 
12696  return -1;
12697  }
12698 
12699  if (!jb->state_empty) {
12700  jb->bytes_wrote += len;
12701  if (jb->bytes_wrote >= jb->upper_threshold) {
12702  jb->state_empty = 1;
12703  jb->bytes_wrote = 0;
12704  }
12705  }
12706  jb->wp = wp;
12707 
12708  ast_mutex_unlock(&jb->mutexjb);
12709 
12710  return 0;
12711 }
static void chan_misdn_log(int level, int port, char *tmpl,...)
Definition: chan_misdn.c:12768
ast_mutex_t mutexjb
Definition: chan_misdn.c:140
char * ok
Definition: chan_misdn.c:134
int size
Definition: chan_misdn.c:132
int state_buffer
Definition: chan_misdn.c:138
#define ast_mutex_lock(a)
Definition: lock.h:187
char * samples
Definition: chan_misdn.c:134
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
int upper_threshold
Definition: chan_misdn.c:133
int state_full
Definition: chan_misdn.c:137
int bytes_wrote
Definition: chan_misdn.c:139
#define ast_mutex_unlock(a)
Definition: lock.h:188
int state_empty
Definition: chan_misdn.c:136

◆ misdn_jb_init()

struct misdn_jb * misdn_jb_init ( int  size,
int  upper_threshold 
)

allocates the jb-structure and initialize the elements

Definition at line 12602 of file chan_misdn.c.

References ast_calloc, ast_free, ast_mutex_init, chan_misdn_log(), misdn_jb::mutexjb, NULL, misdn_jb::ok, misdn_jb::samples, misdn_jb::size, and misdn_jb::upper_threshold.

Referenced by config_jitterbuffer().

12603 {
12604  struct misdn_jb *jb;
12605 
12606  jb = ast_calloc(1, sizeof(*jb));
12607  if (!jb) {
12608  chan_misdn_log(-1, 0, "No free Mem for jb\n");
12609  return NULL;
12610  }
12611  jb->size = size;
12613  //jb->wp = 0;
12614  //jb->rp = 0;
12615  //jb->state_full = 0;
12616  //jb->state_empty = 0;
12617  //jb->bytes_wrote = 0;
12618  jb->samples = ast_calloc(size, sizeof(*jb->samples));
12619  if (!jb->samples) {
12620  ast_free(jb);
12621  chan_misdn_log(-1, 0, "No free Mem for jb->samples\n");
12622  return NULL;
12623  }
12624 
12625  jb->ok = ast_calloc(size, sizeof(*jb->ok));
12626  if (!jb->ok) {
12627  ast_free(jb->samples);
12628  ast_free(jb);
12629  chan_misdn_log(-1, 0, "No free Mem for jb->ok\n");
12630  return NULL;
12631  }
12632 
12633  ast_mutex_init(&jb->mutexjb);
12634 
12635  return jb;
12636 }
static void chan_misdn_log(int level, int port, char *tmpl,...)
Definition: chan_misdn.c:12768
ast_mutex_t mutexjb
Definition: chan_misdn.c:140
char * ok
Definition: chan_misdn.c:134
int size
Definition: chan_misdn.c:132
#define NULL
Definition: resample.c:96
char * samples
Definition: chan_misdn.c:134
#define ast_free(a)
Definition: astmm.h:182
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
int upper_threshold
Definition: chan_misdn.c:133
#define ast_mutex_init(pmutex)
Definition: lock.h:184

◆ misdn_l1_task()

static int misdn_l1_task ( const void *  vdata)
static

Definition at line 3619 of file chan_misdn.c.

References chan_misdn_log(), and misdn_lib_isdn_l1watcher().

Referenced by load_module().

3620 {
3621  const int *data = vdata;
3622 
3623  misdn_lib_isdn_l1watcher(*data);
3624  chan_misdn_log(5, *data, "L1watcher timeout\n");
3625  return 1;
3626 }
static void chan_misdn_log(int level, int port, char *tmpl,...)
Definition: chan_misdn.c:12768
void misdn_lib_isdn_l1watcher(int port)
Definition: isdn_lib.c:3049

◆ misdn_new()

static struct ast_channel * misdn_new ( struct chan_list cl,
int  state,
char *  exten,
char *  callerid,
struct ast_format_cap cap,
const struct ast_assigned_ids assignedids,
const struct ast_channel requestor,
int  port,
int  c 
)
static

Definition at line 8174 of file chan_misdn.c.

References ast_party_caller::ani, ao2_ref, chan_list::ast, ast_callerid_parse(), ast_channel_alloc, ast_channel_caller(), ast_channel_exten_set(), ast_channel_nativeformats_set(), ast_channel_priority_set(), ast_channel_rings_set(), ast_channel_set_fd(), ast_channel_set_rawreadformat(), ast_channel_set_rawwriteformat(), ast_channel_set_readformat(), ast_channel_set_writeformat(), ast_channel_tech_set(), ast_channel_unlock, ast_format_alaw, ast_format_cap_alloc, ast_format_cap_append, AST_FORMAT_CAP_FLAG_DEFAULT, ast_format_cap_get_format(), ast_jb_configure(), ast_log, AST_STATE_RING, ast_strdup, ast_strlen_zero, chan_list_ref, chan_misdn_log(), cid_name, cid_num, LOG_ERROR, MISDN_ASTERISK_TECH_PVT_SET, misdn_cfg_get_next_port(), misdn_get_global_jbconf(), misdn_lib_port_is_pri(), NULL, ast_party_id::number, chan_list::pipe, ast_party_number::str, tmp(), and ast_party_number::valid.

Referenced by cb_events(), and misdn_request().

8175 {
8176  struct ast_format_cap *native;
8177  struct ast_channel *tmp;
8178  char *cid_name = NULL;
8179  char *cid_num = NULL;
8180  int chan_offset = 0;
8181  int tmp_port = misdn_cfg_get_next_port(0);
8182  struct ast_format *tmpfmt;
8183 
8185  if (!native) {
8186  return NULL;
8187  }
8188 
8189  for (; tmp_port > 0; tmp_port = misdn_cfg_get_next_port(tmp_port)) {
8190  if (tmp_port == port) {
8191  break;
8192  }
8193  chan_offset += misdn_lib_port_is_pri(tmp_port) ? 30 : 2;
8194  }
8195  if (c < 0) {
8196  c = 0;
8197  }
8198 
8199  if (callerid) {
8200  ast_callerid_parse(callerid, &cid_name, &cid_num);
8201  }
8202 
8203  tmp = ast_channel_alloc(1, state, cid_num, cid_name, "", exten, "", assignedids, requestor, 0, "%s/%s%d-u%d", misdn_type, c ? "" : "tmp", chan_offset + c, glob_channel++);
8204  if (tmp) {
8205  chan_misdn_log(2, port, " --> * NEW CHANNEL dialed:%s caller:%s\n", exten, callerid);
8206 
8207  tmpfmt = ast_format_cap_get_format(cap, 0);
8209  ast_channel_nativeformats_set(tmp, native);
8210  ast_channel_set_writeformat(tmp, tmpfmt);
8211  ast_channel_set_rawwriteformat(tmp, tmpfmt);
8212  ast_channel_set_readformat(tmp, tmpfmt);
8213  ast_channel_set_rawreadformat(tmp, tmpfmt);
8214 
8215  ao2_ref(tmpfmt, -1);
8216 
8217  /* Link the channel and private together */
8218  chan_list_ref(chlist, "Give a reference to ast_channel");
8219  MISDN_ASTERISK_TECH_PVT_SET(tmp, chlist);
8220  chlist->ast = tmp;
8221 
8223 
8224  ast_channel_priority_set(tmp, 1);
8225 
8226  if (exten) {
8228  } else {
8229  chan_misdn_log(1, 0, "misdn_new: no exten given.\n");
8230  }
8231 
8232  if (!ast_strlen_zero(cid_num)) {
8233  /* Don't use ast_set_callerid() here because it will
8234  * generate a needless NewCallerID event */
8235  ast_channel_caller(tmp)->ani.number.valid = 1;
8236  ast_channel_caller(tmp)->ani.number.str = ast_strdup(cid_num);
8237  }
8238 
8239  if (pipe(chlist->pipe) < 0) {
8240  ast_log(LOG_ERROR, "Pipe failed\n");
8241  }
8242  ast_channel_set_fd(tmp, 0, chlist->pipe[0]);
8243 
8244  ast_channel_rings_set(tmp, (state == AST_STATE_RING) ? 1 : 0);
8245 
8247 
8248  ast_channel_unlock(tmp);
8249  } else {
8250  chan_misdn_log(-1, 0, "Unable to allocate channel structure\n");
8251  }
8252 
8253  ao2_ref(native, -1);
8254 
8255  return tmp;
8256 }
struct ast_party_caller * ast_channel_caller(struct ast_channel *chan)
static void chan_misdn_log(int level, int port, char *tmpl,...)
Definition: chan_misdn.c:12768
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:118
Main Channel structure associated with a channel.
char * str
Subscriber phone number (Malloced)
Definition: channel.h:292
void ast_channel_set_writeformat(struct ast_channel *chan, struct ast_format *format)
int misdn_cfg_get_next_port(int port)
Definition: misdn_config.c:929
void ast_channel_set_rawwriteformat(struct ast_channel *chan, struct ast_format *format)
struct ast_jb_conf * misdn_get_global_jbconf(void)
static int tmp()
Definition: bt_open.c:389
Definition of a media format.
Definition: format.c:43
static struct test_val c
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
#define NULL
Definition: resample.c:96
static char cid_num[AST_MAX_EXTENSION]
Definition: chan_mgcp.c:164
#define ast_strlen_zero(foo)
Definition: strings.h:52
void ast_channel_tech_set(struct ast_channel *chan, const struct ast_channel_tech *value)
#define ast_log
Definition: astobj2.c:42
void ast_channel_set_rawreadformat(struct ast_channel *chan, struct ast_format *format)
struct ast_party_id ani
Automatic Number Identification (ANI)
Definition: channel.h:428
void ast_channel_rings_set(struct ast_channel *chan, int value)
void ast_channel_nativeformats_set(struct ast_channel *chan, struct ast_format_cap *value)
#define ao2_ref(o, delta)
Definition: astobj2.h:464
void ast_channel_set_readformat(struct ast_channel *chan, struct ast_format *format)
#define ast_format_cap_append(cap, format, framing)
Definition: format_cap.h:103
#define ast_format_cap_alloc(flags)
Definition: format_cap.h:52
#define MISDN_ASTERISK_TECH_PVT_SET(ast, value)
Definition: chan_misdn.c:684
#define LOG_ERROR
Definition: logger.h:285
Format capabilities structure, holds formats + preference order + etc.
Definition: format_cap.c:54
static int glob_channel
Definition: chan_misdn.c:8148
static const char misdn_type[]
Definition: chan_misdn.c:690
static struct ast_channel_tech misdn_tech
Definition: chan_misdn.c:8130
#define ast_channel_unlock(chan)
Definition: channel.h:2946
#define chan_list_ref(obj, debug)
Definition: chan_misdn.c:371
void ast_channel_set_fd(struct ast_channel *chan, int which, int fd)
Definition: channel.c:2431
static char cid_name[AST_MAX_EXTENSION]
Definition: chan_mgcp.c:165
void ast_jb_configure(struct ast_channel *chan, const struct ast_jb_conf *conf)
Configures a jitterbuffer on a channel.
Definition: abstract_jb.c:593
void ast_channel_exten_set(struct ast_channel *chan, const char *value)
struct ast_format * ast_format_alaw
Built-in cached alaw format.
Definition: format_cache.c:91
int misdn_lib_port_is_pri(int port)
Definition: isdn_lib.c:53
struct ast_format * ast_format_cap_get_format(const struct ast_format_cap *cap, int position)
Get the format at a specific index.
Definition: format_cap.c:400
void ast_channel_priority_set(struct ast_channel *chan, int value)
#define ast_channel_alloc(needqueue, state, cid_num, cid_name, acctcode, exten, context, assignedids, requestor, amaflag,...)
Create a channel structure.
Definition: channel.h:1259
unsigned char valid
TRUE if the number information is valid/present.
Definition: channel.h:298
int ast_callerid_parse(char *instr, char **name, char **location)
Destructively parse inbuf into name and location (or number)
Definition: callerid.c:1008
struct ast_party_number number
Subscriber phone number.
Definition: channel.h:343

◆ misdn_overlap_dial_task()

static int misdn_overlap_dial_task ( const void *  data)
static

Definition at line 3628 of file chan_misdn.c.

References chan_list::ast, AST_CAUSE_UNALLOCATED, ast_channel_exten_set(), 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, hanguptone_indicate(), MISDN_CLEANING, MISDN_DIALING, misdn_lib_send_event(), MISDN_WAITING4DIGS, misdn_party_dialing::number, misdn_party_id::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().

3629 {
3630  struct timeval tv_end, tv_now;
3631  int diff;
3632  struct chan_list *ch = (struct chan_list *) data;
3633  char *dad;
3634 
3635  chan_misdn_log(4, ch->bc->port, "overlap dial task, chan_state: %d\n", ch->state);
3636 
3637  if (ch->state != MISDN_WAITING4DIGS) {
3638  ch->overlap_dial_task = -1;
3639  return 0;
3640  }
3641 
3643  tv_end = ch->overlap_tv;
3645 
3646  tv_end.tv_sec += ch->overlap_dial;
3647  tv_now = ast_tvnow();
3648 
3649  diff = ast_tvdiff_ms(tv_end, tv_now);
3650  if (100 < diff) {
3651  return diff;
3652  }
3653 
3654  /* if we are 100ms near the timeout, we are satisfied.. */
3655  stop_indicate(ch);
3656 
3657  if (ast_strlen_zero(ch->bc->dialed.number)) {
3658  dad = "s";
3659  ast_channel_exten_set(ch->ast, dad);
3660  } else {
3661  dad = ch->bc->dialed.number;
3662  }
3663 
3664  if (ast_exists_extension(ch->ast, ch->context, dad, 1, ch->bc->caller.number)) {
3665  ch->state = MISDN_DIALING;
3666  if (pbx_start_chan(ch) < 0) {
3667  chan_misdn_log(-1, ch->bc->port, "ast_pbx_start returned < 0 in misdn_overlap_dial_task\n");
3668  goto misdn_overlap_dial_task_disconnect;
3669  }
3670  } else {
3671 misdn_overlap_dial_task_disconnect:
3672  hanguptone_indicate(ch);
3674  ch->state = MISDN_CLEANING;
3676  }
3677  ch->overlap_dial_task = -1;
3678  return 0;
3679 }
static void chan_misdn_log(int level, int port, char *tmpl,...)
Definition: chan_misdn.c:12768
static int stop_indicate(struct chan_list *cl)
Definition: chan_misdn.c:7743
static void hanguptone_indicate(struct chan_list *cl)
Definition: chan_misdn.c:7738
char number[MISDN_MAX_NUMBER_LEN]
Phone number (Address)
Definition: isdn_lib.h:298
#define AST_CAUSE_UNALLOCATED
Definition: causes.h:97
static int pbx_start_chan(struct chan_list *ch)
Definition: chan_misdn.c:8438
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
#define ast_mutex_lock(a)
Definition: lock.h:187
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
Definition: time.h:98
char context[AST_MAX_CONTEXT]
Incoming call dialplan context identifier.
Definition: chan_misdn.c:553
struct ast_channel * ast
Associated Asterisk channel structure.
Definition: chan_misdn.c:515
struct timeval overlap_tv
Overlap timer start time. Timer restarted for every digit received.
Definition: chan_misdn.c:603
#define ast_strlen_zero(foo)
Definition: strings.h:52
char number[MISDN_MAX_NUMBER_LEN]
Dialed/Called Phone Number (Address)
Definition: isdn_lib.h:266
int overlap_dial_task
Overlap dialing timeout Task ID. -1 if not running.
Definition: chan_misdn.c:593
struct misdn_party_id caller
Originating/Caller ID information struct.
Definition: isdn_lib.h:343
int ast_exists_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Determine whether an extension exists.
Definition: pbx.c:4179
enum misdn_chan_state state
State of the channel.
Definition: chan_misdn.c:386
int port
Logical Layer 1 port associated with this B channel.
Definition: isdn_lib.h:370
struct misdn_party_dialing dialed
Dialed/Called information struct.
Definition: isdn_lib.h:337
ast_mutex_t overlap_tv_lock
overlap_tv access lock.
Definition: chan_misdn.c:598
Channel call record structure.
Definition: chan_misdn.c:377
void ast_channel_exten_set(struct ast_channel *chan, const char *value)
int out_cause
Q.931 Cause for disconnection code (sent)
Definition: isdn_lib.h:677
int misdn_lib_send_event(struct misdn_bchannel *bc, enum event_e event)
Definition: isdn_lib.c:3523
struct misdn_bchannel * bc
Associated B channel structure.
Definition: chan_misdn.c:520
int overlap_dial
Enables overlap dialing for the set amount of seconds. (0 = Disabled)
Definition: chan_misdn.c:588
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ misdn_prefix_string()

static void misdn_prefix_string ( const char *  str_prefix,
char *  str_main,
size_t  size 
)
static

Definition at line 3381 of file chan_misdn.c.

References misdn_jb::size.

Referenced by misdn_add_number_prefix().

3382 {
3383  size_t len_over;
3384  size_t len_total;
3385  size_t len_main;
3386  size_t len_prefix;
3387 
3388  len_prefix = strlen(str_prefix);
3389  if (!len_prefix) {
3390  /* There is no prefix to prepend. */
3391  return;
3392  }
3393  len_main = strlen(str_main);
3394  len_total = len_prefix + len_main;
3395  if (size <= len_total) {
3396  /* We need to truncate since the buffer is too small. */
3397  len_over = len_total + 1 - size;
3398  if (len_over <= len_main) {
3399  len_main -= len_over;
3400  } else {
3401  len_over -= len_main;
3402  len_main = 0;
3403  len_prefix -= len_over;
3404  }
3405  }
3406  if (len_main) {
3407  memmove(str_main + len_prefix, str_main, len_main);
3408  }
3409  memcpy(str_main, str_prefix, len_prefix);
3410  str_main[len_prefix + len_main] = '\0';
3411 }

◆ misdn_queue_connected_line_update()

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 6135 of file chan_misdn.c.

References ast_channel_queue_connected_line_update(), ast_party_connected_line_init(), ast_set_party_id_all(), ast_party_connected_line::id, ast_set_party_connected_line::id, misdn_to_ast_plan(), misdn_to_ast_pres(), misdn_to_ast_screen(), misdn_to_ast_ton(), misdn_party_id::number, ast_party_id::number, ast_set_party_id::number, misdn_party_id::number_plan, misdn_party_id::number_type, ast_party_number::plan, misdn_party_id::presentation, ast_party_number::presentation, ast_set_party_connected_line::priv, misdn_party_id::screening, ast_party_connected_line::source, ast_party_number::str, ast_party_id::tag, and ast_party_number::valid.

Referenced by misdn_update_remote_party().

6136 {
6138  struct ast_set_party_connected_line update_connected;
6139 
6141  memset(&update_connected, 0, sizeof(update_connected));
6142  update_connected.id.number = 1;
6143  connected.id.number.valid = 1;
6144  connected.id.number.str = (char *) id->number;
6145  connected.id.number.plan = misdn_to_ast_ton(id->number_type)
6147  connected.id.number.presentation = misdn_to_ast_pres(id->presentation)
6149 
6150  /*
6151  * Make sure that any earlier private connected id
6152  * representation at the remote end is invalidated
6153  */
6154  ast_set_party_id_all(&update_connected.priv);
6155 
6156  connected.id.tag = cid_tag;
6157  connected.source = source;
6158  ast_channel_queue_connected_line_update(ast, &connected, &update_connected);
6159 }
void ast_party_connected_line_init(struct ast_party_connected_line *init)
Initialize the given connected line structure.
Definition: channel.c:2022
char number[MISDN_MAX_NUMBER_LEN]
Phone number (Address)
Definition: isdn_lib.h:298
static int misdn_to_ast_plan(enum mISDN_NUMBER_PLAN number_plan)
Definition: chan_misdn.c:2000
static int misdn_to_ast_pres(int presentation)
Definition: chan_misdn.c:2117
int presentation
Number presentation restriction code 0=Allowed, 1=Restricted, 2=Unavailable.
Definition: isdn_lib.h:277
void ast_channel_queue_connected_line_update(struct ast_channel *chan, const struct ast_party_connected_line *connected, const struct ast_set_party_connected_line *update)
Queue a connected line update frame on a channel.
Definition: channel.c:9202
static int misdn_to_ast_ton(enum mISDN_NUMBER_TYPE number_type)
Definition: chan_misdn.c:1874
enum mISDN_NUMBER_TYPE number_type
Type-of-number in ISDN terms for the number.
Definition: isdn_lib.h:285
Connected Line/Party information.
Definition: channel.h:457
Indicate what information in ast_party_connected_line should be set.
Definition: channel.h:490
void ast_set_party_id_all(struct ast_set_party_id *update_id)
Set the update marker to update all information of a corresponding party id.
Definition: channel.c:1750
int screening
Number screening code 0=Unscreened, 1=Passed Screen, 2=Failed Screen, 3=Network Number.
Definition: isdn_lib.h:282
char connected
Definition: eagi_proxy.c:82
static int misdn_to_ast_screen(int screening)
Definition: chan_misdn.c:2210
enum mISDN_NUMBER_PLAN number_plan
Type-of-number numbering plan.
Definition: isdn_lib.h:288

◆ misdn_read()

static struct ast_frame* misdn_read ( struct ast_channel ast)
static

Definition at line 7393 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::data, ast_frame::datalen, ast_frame::delivery, errno, chan_list::faxdetect, chan_list::faxdetect_timeout, chan_list::faxdetect_tv, chan_list::faxhandled, ast_frame_subclass::format, chan_list::frame, ast_frame::frametype, chan_list::hold, len(), ast_frame::mallocd, MISDN_ASTERISK_TECH_PVT, MISDN_HOLD_IDLE, NULL, ast_frame::offset, chan_list::pipe, misdn_bchannel::port, process_ast_dsp(), ast_frame::ptr, ast_frame::samples, ast_frame::src, hold_info::state, ast_frame::subclass, and tmp().

7394 {
7395  struct chan_list *tmp;
7396  int len, t;
7397  struct pollfd pfd = { .fd = -1, .events = POLLIN };
7398 
7399  if (!ast) {
7400  chan_misdn_log(1, 0, "misdn_read called without ast\n");
7401  return NULL;
7402  }
7403  if (!(tmp = MISDN_ASTERISK_TECH_PVT(ast))) {
7404  chan_misdn_log(1, 0, "misdn_read called without ast->pvt\n");
7405  return NULL;
7406  }
7407 
7408  if (!tmp->bc && tmp->hold.state == MISDN_HOLD_IDLE) {
7409  chan_misdn_log(1, 0, "misdn_read called without bc\n");
7410  return NULL;
7411  }
7412 
7413  pfd.fd = tmp->pipe[0];
7414  t = ast_poll(&pfd, 1, 20);
7415 
7416  if (t < 0) {
7417  chan_misdn_log(-1, tmp->bc->port, "poll() error (err=%s)\n", strerror(errno));
7418  return NULL;
7419  }
7420 
7421  if (!t) {
7422  chan_misdn_log(3, tmp->bc->port, "poll() timed out\n");
7423  len = 160;
7424  } else if (pfd.revents & POLLIN) {
7425  len = read(tmp->pipe[0], tmp->ast_rd_buf, sizeof(tmp->ast_rd_buf));
7426 
7427  if (len <= 0) {
7428  /* we hangup here, since our pipe is closed */
7429  chan_misdn_log(2, tmp->bc->port, "misdn_read: Pipe closed, hanging up\n");
7430  return NULL;
7431  }
7432  } else {
7433  return NULL;
7434  }
7435 
7438  tmp->frame.datalen = len;
7439  tmp->frame.samples = len;
7440  tmp->frame.mallocd = 0;
7441  tmp->frame.offset = 0;
7442  tmp->frame.delivery = ast_tv(0, 0);
7443  tmp->frame.src = NULL;
7444  tmp->frame.data.ptr = tmp->ast_rd_buf;
7445 
7446  if (tmp->faxdetect && !tmp->faxhandled) {
7447  if (tmp->faxdetect_timeout) {
7448  if (ast_tvzero(tmp->faxdetect_tv)) {
7449  tmp->faxdetect_tv = ast_tvnow();
7450  chan_misdn_log(2, tmp->bc->port, "faxdetect: starting detection with timeout: %ds ...\n", tmp->faxdetect_timeout);
7451  return process_ast_dsp(tmp, &tmp->frame);
7452  } else {
7453  struct timeval tv_now = ast_tvnow();
7454  int diff = ast_tvdiff_ms(tv_now, tmp->faxdetect_tv);
7455  if (diff <= (tmp->faxdetect_timeout * 1000)) {
7456  chan_misdn_log(5, tmp->bc->port, "faxdetect: detecting ...\n");
7457  return process_ast_dsp(tmp, &tmp->frame);
7458  } else {
7459  chan_misdn_log(2, tmp->bc->port, "faxdetect: stopping detection (time ran out) ...\n");
7460  tmp->faxdetect = 0;
7461  return &tmp->frame;
7462  }
7463  }
7464  } else {
7465  chan_misdn_log(5, tmp->bc->port, "faxdetect: detecting ... (no timeout)\n");
7466  return process_ast_dsp(tmp, &tmp->frame);
7467  }
7468  } else {
7469  if (tmp->ast_dsp) {
7470  return process_ast_dsp(tmp, &tmp->frame);
7471  } else {
7472  return &tmp->frame;
7473  }
7474  }
7475 }
int ast_dsp
TRUE if we will use the Asterisk DSP to detect DTMF/Fax.
Definition: chan_misdn.c:484
static void chan_misdn_log(int level, int port, char *tmpl,...)
Definition: chan_misdn.c:12768
int faxdetect
Fax detection option. (0:no 1:yes 2:yes+nojump)
Definition: chan_misdn.c:461
char ast_rd_buf[4096]
Read buffer for inbound audio from pipe[0].
Definition: chan_misdn.c:449
int pipe[2]
Pipe file descriptor handles array. Read from pipe[0], write to pipe[1].
Definition: chan_misdn.c:444
int faxdetect_timeout
Number of seconds to detect a Fax machine when detection enabled.
Definition: chan_misdn.c:468
static int tmp()
Definition: bt_open.c:389
struct ast_frame frame
Inbound audio frame returned by misdn_read().
Definition: chan_misdn.c:454
int ast_tvzero(const struct timeval t)
Returns true if the argument is 0,0.
Definition: time.h:108
struct hold_info hold
HELD channel call information.
Definition: chan_misdn.c:535
#define MISDN_ASTERISK_TECH_PVT(ast)
Definition: chan_misdn.c:683
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
Definition: time.h:98
#define NULL
Definition: resample.c:96
struct ast_frame_subclass subclass
static struct ast_frame * process_ast_dsp(struct chan_list *tmp, struct ast_frame *frame)
Definition: chan_misdn.c:7318
const char * src
#define ast_poll(a, b, c)
Definition: poll-compat.h:88
struct timeval faxdetect_tv
Starting time of fax detection with timeout when nonzero.
Definition: chan_misdn.c:473
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
int errno
int port
Logical Layer 1 port associated with this B channel.
Definition: isdn_lib.h:370
Channel call record structure.
Definition: chan_misdn.c:377
enum misdn_hold_state state
Call HOLD state.
Definition: chan_misdn.c:357
struct timeval delivery
int faxhandled
TRUE if a fax has been detected.
Definition: chan_misdn.c:478
struct ast_format * ast_format_alaw
Built-in cached alaw format.
Definition: format_cache.c:91
struct timeval ast_tv(ast_time_t sec, ast_suseconds_t usec)
Returns a timeval from sec, usec.
Definition: time.h:226
union ast_frame::@263 data
enum ast_frame_type frametype
struct ast_format * format
struct misdn_bchannel * bc
Associated B channel structure.
Definition: chan_misdn.c:520

◆ misdn_request()

static struct ast_channel* misdn_request ( const char *  type,
struct ast_format_cap cap,
const struct ast_assigned_ids assignedids,
const struct ast_channel requestor,
const char *  data,
int *  cause 
)
static

Definition at line 7855 of file chan_misdn.c.

References args, AST_APP_ARG, ast_copy_string(), AST_DECLARE_APP_ARGS, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log, AST_NONSTANDARD_APP_ARGS, AST_STATE_RESERVED, ast_strdupa, ast_strlen_zero, chan_list::bc, BUFFERSIZE, chan_list_init(), chan_list_unref, chan_misdn_log(), misdn_bchannel::channel, robin_list::channel, cl_queue_chan(), misdn_bchannel::dec, ext, get_robin_position(), LOG_ERROR, LOG_WARNING, METHOD_ROUND_ROBIN, METHOD_STANDARD_DEC, misdn_cfg_get(), misdn_cfg_get_next_port(), misdn_cfg_get_next_port_spin(), MISDN_CFG_GROUPNAME, misdn_cfg_is_group_method(), MISDN_CFG_PMP_L1_CHECK, misdn_lib_get_free_bc(), misdn_lib_get_maxchans(), misdn_lib_port_up(), misdn_lib_release(), misdn_new(), chan_list::need_hangup, NULL, ORG_AST, misdn_bchannel::port, robin_list::port, and read_config().

7856 {
7857  struct ast_channel *ast;
7858  char group[BUFFERSIZE + 1] = "";
7859  char dial_str[128];
7860  char *dest_cp;
7861  char *p = NULL;
7862  int channel = 0;
7863  int port = 0;
7864  struct misdn_bchannel *newbc = NULL;
7865  int dec = 0;
7866 #if defined(AST_MISDN_ENHANCEMENTS)
7867  int cc_retry_call = 0; /* TRUE if this is a call completion retry call */
7868  long record_id = -1;
7869  struct misdn_cc_record *cc_record;
7870  const char *err_msg;
7871 #endif /* defined(AST_MISDN_ENHANCEMENTS) */
7872  struct chan_list *cl;
7873 
7875  AST_APP_ARG(intf); /* interface token */
7876  AST_APP_ARG(ext); /* extension token */
7877  AST_APP_ARG(opts); /* options token */
7878  );
7879 
7880  snprintf(dial_str, sizeof(dial_str), "%s/%s", misdn_type, data);
7881 
7882  /*
7883  * data is ---v
7884  * Dial(mISDN/g:group_name[/extension[/options]])
7885  * Dial(mISDN/port[:preselected_channel][/extension[/options]])
7886  * Dial(mISDN/cc/cc-record-id)
7887  *
7888  * The dial extension could be empty if you are using MISDN_KEYPAD
7889  * to control ISDN provider features.
7890  */
7891  dest_cp = ast_strdupa(data);
7892  AST_NONSTANDARD_APP_ARGS(args, dest_cp, '/');
7893  if (!args.ext) {
7894  args.ext = "";
7895  }
7896 
7897  if (!ast_strlen_zero(args.intf)) {
7898  if (args.intf[0] == 'g' && args.intf[1] == ':') {
7899  /* We make a group call lets checkout which ports are in my group */
7900  args.intf += 2;
7901  ast_copy_string(group, args.intf, sizeof(group));
7902  chan_misdn_log(2, 0, " --> Group Call group: %s\n", group);
7903 #if defined(AST_MISDN_ENHANCEMENTS)
7904  } else if (strcmp(args.intf, "cc") == 0) {
7905  cc_retry_call = 1;
7906 #endif /* defined(AST_MISDN_ENHANCEMENTS) */
7907  } else if ((p = strchr(args.intf, ':'))) {
7908  /* we have a preselected channel */
7909  *p++ = 0;
7910  channel = atoi(p);
7911  port = atoi(args.intf);
7912  chan_misdn_log(2, port, " --> Call on preselected Channel (%d).\n", channel);
7913  } else {
7914  port = atoi(args.intf);
7915  }
7916  } else {
7917  ast_log(LOG_WARNING, " --> ! IND : Dial(%s) WITHOUT Port or Group, check extensions.conf\n", dial_str);
7918  return NULL;
7919  }
7920 
7921 #if defined(AST_MISDN_ENHANCEMENTS)
7922  if (cc_retry_call) {
7923  if (ast_strlen_zero(args.ext)) {
7924  ast_log(LOG_WARNING, " --> ! IND : Dial(%s) WITHOUT cc-record-id, check extensions.conf\n", dial_str);
7925  return NULL;
7926  }
7927  if (!isdigit(*args.ext)) {
7928  ast_log(LOG_WARNING, " --> ! IND : Dial(%s) cc-record-id must be a number.\n", dial_str);
7929  return NULL;
7930  }
7931  record_id = atol(args.ext);
7932 
7933  AST_LIST_LOCK(&misdn_cc_records_db);
7934  cc_record = misdn_cc_find_by_id(record_id);
7935  if (!cc_record) {
7936  AST_LIST_UNLOCK(&misdn_cc_records_db);
7937  err_msg = misdn_cc_record_not_found;
7938  ast_log(LOG_WARNING, " --> ! IND : Dial(%s) %s.\n", dial_str, err_msg);
7939  return NULL;
7940  }
7941  if (!cc_record->activated) {
7942  AST_LIST_UNLOCK(&misdn_cc_records_db);
7943  err_msg = "Call completion has not been activated";
7944  ast_log(LOG_WARNING, " --> ! IND : Dial(%s) %s.\n", dial_str, err_msg);
7945  return NULL;
7946  }
7947  port = cc_record->port;
7948  AST_LIST_UNLOCK(&misdn_cc_records_db);
7949  }
7950 #endif /* defined(AST_MISDN_ENHANCEMENTS) */
7951 
7953  chan_misdn_log(4, port, " --> STARTING STANDARD DEC...\n");
7954  dec = 1;
7955  }
7956 
7957  if (!ast_strlen_zero(group)) {
7958  char cfg_group[BUFFERSIZE + 1];
7959  struct robin_list *rr = NULL;
7960 
7961  /* Group dial */
7962 
7964  chan_misdn_log(4, port, " --> STARTING ROUND ROBIN...\n");
7965  rr = get_robin_position(group);
7966  }
7967 
7968  if (rr) {
7969  int port_start;
7970  int bchan_start;
7971  int port_up;
7972  int check;
7973  int maxbchans;
7974  int wraped = 0;
7975 
7976  if (!rr->port) {
7978  }
7979 
7980  if (!rr->channel) {
7981  rr->channel = 1;
7982  }
7983 
7984  bchan_start = rr->channel;
7985  port_start = rr->port;
7986  do {
7987  misdn_cfg_get(rr->port, MISDN_CFG_GROUPNAME, cfg_group, sizeof(cfg_group));
7988  if (strcasecmp(cfg_group, group)) {
7989  wraped = 1;
7991  rr->channel = 1;
7992  continue;
7993  }
7994 
7995  misdn_cfg_get(rr->port, MISDN_CFG_PMP_L1_CHECK, &check, sizeof(check));
7996  port_up = misdn_lib_port_up(rr->port, check);
7997 
7998  if (!port_up) {
7999  chan_misdn_log(1, rr->port, "L1 is not Up on this Port\n");
8001  rr->channel = 1;
8002  } else if (port_up < 0) {
8003  ast_log(LOG_WARNING, "This port (%d) is blocked\n", rr->port);
8005  rr->channel = 1;
8006  } else {
8007  chan_misdn_log(4, rr->port, "portup\n");
8008  maxbchans = misdn_lib_get_maxchans(rr->port);
8009 
8010  for (;rr->channel <= maxbchans;rr->channel++) {
8011  /* ive come full circle and can stop now */
8012  if (wraped && (rr->port == port_start) && (rr->channel == bchan_start)) {
8013  break;
8014  }
8015 
8016  chan_misdn_log(4, rr->port, "Checking channel %d\n", rr->channel);
8017 
8018  if ((newbc = misdn_lib_get_free_bc(rr->port, rr->channel, 0, 0))) {
8019  chan_misdn_log(4, rr->port, " Success! Found port:%d channel:%d\n", newbc->port, newbc->channel);
8020  rr->channel++;
8021  break;
8022  }
8023  }
8024  if (wraped && (rr->port == port_start) && (rr->channel <= bchan_start)) {
8025  break;
8026  } else if (!newbc || (rr->channel == maxbchans)) {
8028  rr->channel = 1;
8029  }
8030 
8031  }
8032  wraped = 1;
8033  } while (!newbc && (rr->port > 0));
8034  } else {
8035  for (port = misdn_cfg_get_next_port(0); port > 0;
8036  port = misdn_cfg_get_next_port(port)) {
8037  misdn_cfg_get(port, MISDN_CFG_GROUPNAME, cfg_group, sizeof(cfg_group));
8038 
8039  chan_misdn_log(3, port, "Group [%s] Port [%d]\n", group, port);
8040  if (!strcasecmp(cfg_group, group)) {
8041  int port_up;
8042  int check;
8043 
8044  misdn_cfg_get(port, MISDN_CFG_PMP_L1_CHECK, &check, sizeof(check));
8045  port_up = misdn_lib_port_up(port, check);
8046 
8047  chan_misdn_log(4, port, "portup:%d\n", port_up);
8048 
8049  if (port_up > 0) {
8050  newbc = misdn_lib_get_free_bc(port, 0, 0, dec);
8051  if (newbc) {
8052  break;
8053  }
8054  }
8055  }
8056  }
8057  }
8058 
8059  /* Group dial failed ?*/
8060  if (!newbc) {
8062  "Could not Dial out on group '%s'.\n"
8063  "\tEither the L2 and L1 on all of these ports where DOWN (see 'show application misdn_check_l2l1')\n"
8064  "\tOr there was no free channel on none of the ports\n\n",
8065  group);
8066  return NULL;
8067  }
8068  } else {
8069  /* 'Normal' Port dial * Port dial */
8070  if (channel) {
8071  chan_misdn_log(1, port, " --> preselected_channel: %d\n", channel);
8072  }
8073  newbc = misdn_lib_get_free_bc(port, channel, 0, dec);
8074  if (!newbc) {
8075  ast_log(LOG_WARNING, "Could not create channel on port:%d for Dial(%s)\n", port, dial_str);
8076  return NULL;
8077  }
8078  }
8079 
8080  /* create ast_channel and link all the objects together */
8081  cl = chan_list_init(ORG_AST);
8082  if (!cl) {
8083  misdn_lib_release(newbc);
8084  ast_log(LOG_ERROR, "Could not create call record for Dial(%s)\n", dial_str);
8085  return NULL;
8086  }
8087  cl->bc = newbc;
8088 
8089  ast = misdn_new(cl, AST_STATE_RESERVED, args.ext, NULL, cap, assignedids, requestor, port, channel);
8090  if (!ast) {
8091  chan_list_unref(cl, "Failed to create a new channel");
8092  misdn_lib_release(newbc);
8093  ast_log(LOG_ERROR, "Could not create Asterisk channel for Dial(%s)\n", dial_str);
8094  return NULL;
8095  }
8096 
8097 #if defined(AST_MISDN_ENHANCEMENTS)
8098  cl->record_id = record_id;
8099 #endif /* defined(AST_MISDN_ENHANCEMENTS) */
8100 
8101  /* register chan in local list */
8102  cl_queue_chan(cl);
8103 
8104  /* fill in the config into the objects */
8105  read_config(cl);
8106 
8107  /* important */
8108  cl->need_hangup = 0;
8109 
8110  chan_list_unref(cl, "Successful misdn_request()");
8111  return ast;
8112 }
static void chan_misdn_log(int level, int port, char *tmpl,...)
Definition: chan_misdn.c:12768
Main Channel structure associated with a channel.
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
int misdn_cfg_get_next_port_spin(int port)
Definition: misdn_config.c:946
static int read_config(struct chan_list *ch)
Definition: chan_misdn.c:5922
int need_hangup
TRUE if a channel can be hung up by calling asterisk directly when done.
Definition: chan_misdn.c:397
int misdn_cfg_get_next_port(int port)
Definition: misdn_config.c:929
static struct ast_channel * misdn_new(struct chan_list *cl, int state, char *exten, char *callerid, struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, int port, int c)
Definition: chan_misdn.c:8174
static void cl_queue_chan(struct chan_list *chan)
Definition: chan_misdn.c:8377
#define LOG_WARNING
Definition: logger.h:274
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
B channel control structure.
Definition: isdn_lib.h:324
Definition: muted.c:95
const char * args
#define NULL
Definition: resample.c:96
const char * ext
Definition: http.c:147
int misdn_lib_get_maxchans(int port)
Definition: isdn_lib.c:137
#define ast_strlen_zero(foo)
Definition: strings.h:52
int misdn_cfg_is_group_method(char *group, enum misdn_cfg_method meth)
Definition: misdn_config.c:744
#define BUFFERSIZE
#define ast_log
Definition: astobj2.c:42
void misdn_cfg_get(int port, enum misdn_cfg_elements elem, void *buf, int bufsize)
Definition: misdn_config.c:569
void misdn_lib_release(struct misdn_bchannel *bc)
Definition: isdn_lib.c:1759
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
int dec
TRUE if allocate higher B channels first.
Definition: isdn_lib.h:395
#define LOG_ERROR
Definition: logger.h:285
#define AST_NONSTANDARD_APP_ARGS(args, parse, sep)
Performs the &#39;nonstandard&#39; argument separation process for an application.
int port
Logical Layer 1 port associated with this B channel.
Definition: isdn_lib.h:370
static const char misdn_type[]
Definition: chan_misdn.c:690
struct misdn_bchannel * misdn_lib_get_free_bc(int port, int channel, int inout, int dec)
Definition: isdn_lib.c:3205
Channel call record structure.
Definition: chan_misdn.c:377
int misdn_lib_port_up(int port, int check)
Definition: isdn_lib.c:1821
static struct chan_list * chan_list_init(int orig)
Definition: chan_misdn.c:7831
int channel
Assigned B channel number B1, B2... 0 if not assigned.
Definition: isdn_lib.h:411
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
#define ORG_AST
Definition: chan_misdn.c:343
static struct robin_list * get_robin_position(char *group)
Definition: chan_misdn.c:641
struct misdn_bchannel * bc
Associated B channel structure.
Definition: chan_misdn.c:520
#define chan_list_unref(obj, debug)
Definition: chan_misdn.c:372
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
#define AST_APP_ARG(name)
Define an application argument.

◆ misdn_send_text()

static int misdn_send_text ( struct ast_channel chan,
const char *  text 
)
static

Definition at line 8115 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, misdn_lib_send_event(), and tmp().

8116 {
8117  struct chan_list *tmp = MISDN_ASTERISK_TECH_PVT(chan);
8118 
8119  if (tmp && tmp->bc) {
8120  ast_copy_string(tmp->bc->display, text, sizeof(tmp->bc->display));
8122  } else {
8123  ast_log(LOG_WARNING, "No chan_list but send_text request?\n");
8124  return -1;
8125  }
8126 
8127  return 0;
8128 }
#define LOG_WARNING
Definition: logger.h:274
static int tmp()
Definition: bt_open.c:389
#define MISDN_ASTERISK_TECH_PVT(ast)
Definition: chan_misdn.c:683
char * text
Definition: app_queue.c:1508
#define ast_log
Definition: astobj2.c:42
char display[84]
Display message that can be displayed by the user phone.
Definition: isdn_lib.h:642
Channel call record structure.
Definition: chan_misdn.c:377
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
int misdn_lib_send_event(struct misdn_bchannel *bc, enum event_e event)
Definition: isdn_lib.c:3523
struct misdn_bchannel * bc
Associated B channel structure.
Definition: chan_misdn.c:520

◆ misdn_set_opt_exec()

static int misdn_set_opt_exec ( struct ast_channel chan,
const char *  data 
)
static

Definition at line 12365 of file chan_misdn.c.

References ast_channel_tech(), 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, keys, LOG_WARNING, MISDN_ASTERISK_TECH_PVT, MISDN_CFG_FAXDETECT_TIMEOUT, misdn_cfg_get(), MISDN_GEN_CRYPT_KEYS, misdn_bchannel::nodsp, misdn_bchannel::nojitter, NULL, misdn_bchannel::orig, chan_list::originator, parse(), misdn_bchannel::port, misdn_bchannel::presentation, misdn_bchannel::rxgain, misdn_bchannel::send_dtmf, misdn_bchannel::set_presentation, strsep(), tmp(), and misdn_bchannel::txgain.

Referenced by load_module(), and misdn_call().

12366 {
12367  struct chan_list *ch = MISDN_ASTERISK_TECH_PVT(chan);
12368  char *tok;
12369  char *tokb;
12370  char *parse;
12371  int keyidx = 0;
12372  int rxgain = 0;
12373  int txgain = 0;
12374  int change_jitter = 0;
12375 
12376  if (strcasecmp(ast_channel_tech(chan)->type, misdn_type)) {
12377  ast_log(LOG_WARNING, "misdn_set_opt makes sense only with %s channels!\n", misdn_type);
12378  return -1;
12379  }
12380 
12381  if (ast_strlen_zero((char *) data)) {
12382  ast_log(LOG_WARNING, "misdn_set_opt Requires arguments\n");
12383  return -1;
12384  }
12385 
12386  parse = ast_strdupa(data);
12387  for (tok = strtok_r(parse, ":", &tokb);
12388  tok;
12389  tok = strtok_r(NULL, ":", &tokb)) {
12390  int neglect = 0;
12391 
12392  if (tok[0] == '!') {
12393  neglect = 1;
12394  tok++;
12395  }
12396 
12397  switch(tok[0]) {
12398  case 'd' :
12399  ast_copy_string(ch->bc->display, ++tok, sizeof(ch->bc->display));
12400  chan_misdn_log(1, ch->bc->port, "SETOPT: Display:%s\n", ch->bc->display);
12401  break;
12402  case 'n':
12403  chan_misdn_log(1, ch->bc->port, "SETOPT: No DSP\n");
12404  ch->bc->nodsp = 1;
12405  break;
12406  case 'j':
12407  chan_misdn_log(1, ch->bc->port, "SETOPT: jitter\n");
12408  tok++;
12409  change_jitter = 1;
12410 
12411  switch (tok[0]) {
12412  case 'b':
12413  ch->jb_len = atoi(++tok);
12414  chan_misdn_log(1, ch->bc->port, " --> buffer_len:%d\n", ch->jb_len);
12415  break;
12416  case 't' :
12417  ch->jb_upper_threshold = atoi(++tok);
12418  chan_misdn_log(1, ch->bc->port, " --> upper_threshold:%d\n", ch->jb_upper_threshold);
12419  break;
12420  case 'n':
12421  ch->bc->nojitter = 1;
12422  chan_misdn_log(1, ch->bc->port, " --> nojitter\n");
12423  break;
12424  default:
12425  ch->jb_len = 4000;
12426  ch->jb_upper_threshold = 0;
12427  chan_misdn_log(1, ch->bc->port, " --> buffer_len:%d (default)\n", ch->jb_len);
12428  chan_misdn_log(1, ch->bc->port, " --> upper_threshold:%d (default)\n", ch->jb_upper_threshold);
12429  break;
12430  }
12431  break;
12432  case 'v':
12433  tok++;
12434 
12435  switch (tok[0]) {
12436  case 'r' :
12437  rxgain = atoi(++tok);
12438  if (rxgain < -8) {
12439  rxgain = -8;
12440  }
12441  if (rxgain > 8) {
12442  rxgain = 8;
12443  }
12444  ch->bc->rxgain = rxgain;
12445  chan_misdn_log(1, ch->bc->port, "SETOPT: Volume:%d\n", rxgain);
12446  break;
12447  case 't':
12448  txgain = atoi(++tok);
12449  if (txgain < -8) {
12450  txgain = -8;
12451  }
12452  if (txgain > 8) {
12453  txgain = 8;
12454  }
12455  ch->bc->txgain = txgain;
12456  chan_misdn_log(1, ch->bc->port, "SETOPT: Volume:%d\n", txgain);
12457  break;
12458  }
12459  break;
12460  case 'c':
12461  keyidx = atoi(++tok);
12462  {
12463  char keys[4096];
12464  char *key = NULL;
12465  char *tmp = keys;
12466  int i;
12467 
12468  misdn_cfg_get(0, MISDN_GEN_CRYPT_KEYS, keys, sizeof(keys));
12469 
12470  for (i = 0; i < keyidx; i++) {
12471  key = strsep(&tmp, ",");
12472  }
12473 
12474  if (key) {
12475  ast_copy_string(ch->bc->crypt_key, key, sizeof(ch->bc->crypt_key));
12476  }
12477 
12478  chan_misdn_log(0, ch->bc->port, "SETOPT: crypt with key:%s\n", ch->bc->crypt_key);
12479  break;
12480  }
12481  case 'e':
12482  chan_misdn_log(1, ch->bc->port, "SETOPT: EchoCancel\n");
12483 
12484  if (neglect) {
12485  chan_misdn_log(1, ch->bc->port, " --> disabled\n");
12486 #ifdef MISDN_1_2
12487  *ch->bc->pipeline = 0;
12488 #else
12489  ch->bc->ec_enable = 0;
12490 #endif
12491  } else {
12492 #ifdef MISDN_1_2
12493  update_pipeline_config(ch->bc);
12494 #else
12495  ch->bc->ec_enable = 1;
12496  ch->bc->orig = ch->originator;
12497  tok++;
12498  if (*tok) {
12499  ch->bc->ec_deftaps = atoi(tok);
12500  }
12501 #endif
12502  }
12503  break;
12504  case 'h':
12505  chan_misdn_log(1, ch->bc->port, "SETOPT: Digital\n");
12506 
12507  if (strlen(tok) > 1 && tok[1] == '1') {
12508  chan_misdn_log(1, ch->bc->port, "SETOPT: HDLC \n");
12509  if (!ch->bc->hdlc) {
12510  ch->bc->hdlc = 1;
12511  }
12512  }
12514  break;
12515  case 's':
12516  chan_misdn_log(1, ch->bc->port, "SETOPT: Send DTMF\n");
12517  ch->bc->send_dtmf = 1;
12518  break;
12519  case 'f':
12520  chan_misdn_log(1, ch->bc->port, "SETOPT: Faxdetect\n");
12521  ch->faxdetect = 1;
12523  break;
12524  case 'a':
12525  chan_misdn_log(1, ch->bc->port, "SETOPT: AST_DSP (for DTMF)\n");
12526  ch->ast_dsp = 1;
12527  break;
12528  case 'p':
12529  chan_misdn_log(1, ch->bc->port, "SETOPT: callerpres: %s\n", &tok[1]);
12530  /* CRICH: callingpres!!! */
12531  if (strstr(tok, "allowed")) {
12532  ch->bc->presentation = 0;
12533  ch->bc->set_presentation = 1;
12534  } else if (strstr(tok, "restricted")) {
12535  ch->bc->presentation = 1;
12536  ch->bc->set_presentation = 1;
12537  } else if (strstr(tok, "not_screened")) {
12538  chan_misdn_log(0, ch->bc->port, "SETOPT: callerpres: not_screened is deprecated\n");
12539  ch->bc->presentation = 1;
12540  ch->bc->set_presentation = 1;
12541  }
12542  break;
12543  case 'i' :
12544  chan_misdn_log(1, ch->bc->port, "Ignoring dtmf tones, just use them inband\n");
12545  ch->ignore_dtmf = 1;
12546  break;
12547  default:
12548  break;
12549  }
12550  }
12551 
12552  if (change_jitter) {
12553  config_jitterbuffer(ch);
12554  }
12555 
12556  if (ch->faxdetect || ch->ast_dsp) {
12557  if (!ch->dsp) {
12558  ch->dsp = ast_dsp_new();
12559  }
12560  if (ch->dsp) {
12562  }
12563  }
12564 
12565  if (ch->ast_dsp) {
12566  chan_misdn_log(1, ch->bc->port, "SETOPT: with AST_DSP we deactivate mISDN_dsp\n");
12567  ch->bc->nodsp = 1;
12568  }
12569 
12570  return 0;
12571 }
int ast_dsp
TRUE if we will use the Asterisk DSP to detect DTMF/Fax.
Definition: chan_misdn.c:484
static void chan_misdn_log(int level, int port, char *tmpl,...)
Definition: chan_misdn.c:12768
static const char type[]
Definition: chan_ooh323.c:109
int jb_len
Jitterbuffer length.
Definition: chan_misdn.c:490
int faxdetect
Fax detection option. (0:no 1:yes 2:yes+nojump)
Definition: chan_misdn.c:461
struct ast_dsp * dsp
Allocated DSP controller.
Definition: chan_misdn.c:510
int nodsp
TRUE if we will not use jollys dsp.
Definition: isdn_lib.h:474
int txgain
Tx gain setting (range -8 to 8)
Definition: isdn_lib.h:708
int ec_enable
TRUE if the echo cancellor is enabled.
Definition: isdn_lib.h:688
int ignore_dtmf
TRUE if DTMF digits are to be passed inband only.
Definition: chan_misdn.c:438
int presentation
User set presentation restriction code 0=Allowed, 1=Restricted, 2=Unavailable.
Definition: isdn_lib.h:600
#define DSP_FEATURE_DIGIT_DETECT
Definition: dsp.h:28
#define LOG_WARNING
Definition: logger.h:274
int faxdetect_timeout
Number of seconds to detect a Fax machine when detection enabled.
Definition: chan_misdn.c:468
struct ast_dsp * ast_dsp_new(void)
Allocates a new dsp, assumes 8khz for internal sample rate.
Definition: dsp.c:1745
static int tmp()
Definition: bt_open.c:389
int hdlc
TRUE if call made in digital HDLC mode.
Definition: isdn_lib.h:635
int jb_upper_threshold
Jitterbuffer upper threshold.
Definition: chan_misdn.c:496
static void config_jitterbuffer(struct chan_list *ch)
Definition: chan_misdn.c:5817
char crypt_key[255]
Blowfish encryption key string (secret)
Definition: isdn_lib.h:529
#define MISDN_ASTERISK_TECH_PVT(ast)
Definition: chan_misdn.c:683
int capability
SETUP message bearer capability field code value.
Definition: isdn_lib.h:609
#define NULL
Definition: resample.c:96
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_log
Definition: astobj2.c:42
int set_presentation
TRUE if the user set the presentation restriction code.
Definition: isdn_lib.h:603
char display[84]
Display message that can be displayed by the user phone.
Definition: isdn_lib.h:642
void misdn_cfg_get(int port, enum misdn_cfg_elements elem, void *buf, int bufsize)
Definition: misdn_config.c:569
#define DSP_FEATURE_FAX_DETECT
Definition: dsp.h:29
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
int nojitter
TRUE if we will not use the jitter buffer system.
Definition: isdn_lib.h:477
int rxgain
Rx gain setting (range -8 to 8)
Definition: isdn_lib.h:714
int originator
Who originally created this channel. ORG_AST or ORG_MISDN.
Definition: chan_misdn.c:407
int send_dtmf
TRUE if we should produce DTMF tones ourselves.
Definition: isdn_lib.h:457
int port
Logical Layer 1 port associated with this B channel.
Definition: isdn_lib.h:370
static const char misdn_type[]
Definition: chan_misdn.c:690
static void parse(struct mgcp_request *req)
Definition: chan_mgcp.c:1872
void ast_dsp_set_features(struct ast_dsp *dsp, int features)
Select feature set.
Definition: dsp.c:1755
Channel call record structure.
Definition: chan_misdn.c:377
char * strsep(char **str, const char *delims)
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
int ec_deftaps
Number of taps in the echo cancellor when enabled.
Definition: isdn_lib.h:693
struct misdn_bchannel * bc
Associated B channel structure.
Definition: chan_misdn.c:520
static struct keys keys
int orig
Who originated the call (ORG_AST, ORG_MISDN)
Definition: isdn_lib.h:702
const struct ast_channel_tech * ast_channel_tech(const struct ast_channel *chan)

◆ misdn_tasks_add()

static int misdn_tasks_add ( int  timeout,
ast_sched_cb  callback,
const void *  data 
)
static

Definition at line 3604 of file chan_misdn.c.

References _misdn_tasks_add_variable().

Referenced by load_module().

3605 {
3606  return _misdn_tasks_add_variable(timeout, callback, data, 0);
3607 }
static int timeout
Definition: cdr_mysql.c:86
static int _misdn_tasks_add_variable(int timeout, ast_sched_cb callback, const void *data, int variable)
Definition: chan_misdn.c:3591

◆ misdn_tasks_add_variable()

static int misdn_tasks_add_variable ( int  timeout,
ast_sched_cb  callback,
const void *  data 
)
static

Definition at line 3609 of file chan_misdn.c.

References _misdn_tasks_add_variable().

Referenced by cb_events().

3610 {
3611  return _misdn_tasks_add_variable(timeout, callback, data, 1);
3612 }
static int timeout
Definition: cdr_mysql.c:86
static int _misdn_tasks_add_variable(int timeout, ast_sched_cb callback, const void *data, int variable)
Definition: chan_misdn.c:3591

◆ misdn_tasks_destroy()

static void misdn_tasks_destroy ( void  )
static

Definition at line 3574 of file chan_misdn.c.

References ast_sched_context_destroy(), cb_log, chan_misdn_log(), misdn_tasks_thread, and NULL.

Referenced by unload_module().

3575 {
3576  if (misdn_tasks) {
3577  chan_misdn_log(4, 0, "Killing misdn_tasks thread\n");
3578  if (pthread_cancel(misdn_tasks_thread) == 0) {
3579  cb_log(4, 0, "Joining misdn_tasks thread\n");
3580  pthread_join(misdn_tasks_thread, NULL);
3581  }
3583  }
3584 }
static void chan_misdn_log(int level, int port, char *tmpl,...)
Definition: chan_misdn.c:12768
#define NULL
Definition: resample.c:96
static pthread_t misdn_tasks_thread
Definition: chan_misdn.c:671
static struct ast_sched_context * misdn_tasks
the main schedule context for stuff like l1 watcher, overlap dial, ...
Definition: chan_misdn.c:670
void(* cb_log)(int level, int port, char *tmpl,...)
Definition: isdn_lib.c:32
void ast_sched_context_destroy(struct ast_sched_context *c)
destroys a schedule context
Definition: sched.c:269

◆ misdn_tasks_init()

static void misdn_tasks_init ( void  )
static

Definition at line 3554 of file chan_misdn.c.

References ast_sched_context_create(), chan_misdn_log(), misdn_tasks_thread, misdn_tasks_thread_func(), NULL, and pthread_create.

Referenced by _misdn_tasks_add_variable().

3555 {
3556  sem_t blocker;
3557  int i = 5;
3558 
3559  if (sem_init(&blocker, 0, 0)) {
3560  perror("chan_misdn: Failed to initialize semaphore!");
3561  exit(1);
3562  }
3563 
3564  chan_misdn_log(4, 0, "Starting misdn_tasks thread\n");
3565 
3568 
3569  while (sem_wait(&blocker) && --i) {
3570  }
3571  sem_destroy(&blocker);
3572 }
static void chan_misdn_log(int level, int port, char *tmpl,...)
Definition: chan_misdn.c:12768
#define NULL
Definition: resample.c:96
static pthread_t misdn_tasks_thread
Definition: chan_misdn.c:671
struct ast_sched_context * ast_sched_context_create(void)
Create a scheduler context.
Definition: sched.c:236
static struct ast_sched_context * misdn_tasks
the main schedule context for stuff like l1 watcher, overlap dial, ...
Definition: chan_misdn.c:670
static void * misdn_tasks_thread_func(void *data)
Definition: chan_misdn.c:3528
#define pthread_create
Definition: lock.h:640

◆ misdn_tasks_remove()

static void misdn_tasks_remove ( int  task_id)
static

Definition at line 3614 of file chan_misdn.c.

References AST_SCHED_DEL.

Referenced by chan_list_destructor().

3615 {
3616  AST_SCHED_DEL(misdn_tasks, task_id);
3617 }
#define AST_SCHED_DEL(sched, id)
Remove a scheduler entry.
Definition: sched.h:46
static struct ast_sched_context * misdn_tasks
the main schedule context for stuff like l1 watcher, overlap dial, ...
Definition: chan_misdn.c:670

◆ misdn_tasks_thread_func()

static void* misdn_tasks_thread_func ( void *  data)
static

Definition at line 3528 of file chan_misdn.c.

References ast_sched_runq(), ast_sched_wait(), chan_misdn_log(), NULL, and sighandler().

Referenced by misdn_tasks_init().

3529 {
3530  int wait;
3531  struct sigaction sa;
3532 
3533  sa.sa_handler = sighandler;
3534  sa.sa_flags = SA_NODEFER;
3535  sigemptyset(&sa.sa_mask);
3536  sigaddset(&sa.sa_mask, SIGUSR1);
3537  sigaction(SIGUSR1, &sa, NULL);
3538 
3539  sem_post((sem_t *)data);
3540 
3541  while (1) {
3542  wait = ast_sched_wait(misdn_tasks);
3543  if (wait < 0) {
3544  wait = 8000;
3545  }
3546  if (poll(NULL, 0, wait) < 0) {
3547  chan_misdn_log(4, 0, "Waking up misdn_tasks thread\n");
3548  }
3550  }
3551  return NULL;
3552 }
static void chan_misdn_log(int level, int port, char *tmpl,...)
Definition: chan_misdn.c:12768
int ast_sched_runq(struct ast_sched_context *con)
Runs the queue.
Definition: sched.c:755
#define NULL
Definition: resample.c:96
static void sighandler(int sig)
Definition: chan_misdn.c:3524
static struct ast_sched_context * misdn_tasks
the main schedule context for stuff like l1 watcher, overlap dial, ...
Definition: chan_misdn.c:670
int ast_sched_wait(struct ast_sched_context *con) attribute_warn_unused_result
Determines number of seconds until the next outstanding event to take place.
Definition: sched.c:431

◆ misdn_tasks_wakeup()

static void misdn_tasks_wakeup ( void  )
inlinestatic

Definition at line 3586 of file chan_misdn.c.

References misdn_tasks_thread.

Referenced by _misdn_tasks_add_variable().

3587 {
3588  pthread_kill(misdn_tasks_thread, SIGUSR1);
3589 }
static pthread_t misdn_tasks_thread
Definition: chan_misdn.c:671

◆ misdn_to_ast_plan()

static int misdn_to_ast_plan ( enum mISDN_NUMBER_PLAN  number_plan)
static

Definition at line 2000 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().

2001 {
2002  int ast_number_plan;
2003 
2004  switch (number_plan) {
2005  default:
2006  case NUMPLAN_UNKNOWN:
2007  ast_number_plan = NUMPLAN_UNKNOWN;
2008  break;
2009 
2010  case NUMPLAN_ISDN:
2011  ast_number_plan = NUMPLAN_ISDN;
2012  break;
2013 
2014  case NUMPLAN_DATA:
2015  ast_number_plan = NUMPLAN_DATA;
2016  break;
2017 
2018  case NUMPLAN_TELEX:
2019  ast_number_plan = NUMPLAN_TELEX;
2020  break;
2021 
2022  case NUMPLAN_NATIONAL:
2023  ast_number_plan = NUMPLAN_NATIONAL;
2024  break;
2025 
2026  case NUMPLAN_PRIVATE:
2027  ast_number_plan = NUMPLAN_PRIVATE;
2028  break;
2029  }
2030 
2031  return ast_number_plan;
2032 }

◆ misdn_to_ast_pres()

static int misdn_to_ast_pres ( int  presentation)
static

Definition at line 2117 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().

2118 {
2119  switch (presentation) {
2120  default:
2121  case 0:
2122  presentation = AST_PRES_ALLOWED;
2123  break;
2124 
2125  case 1:
2126  presentation = AST_PRES_RESTRICTED;
2127  break;
2128 
2129  case 2:
2130  presentation = AST_PRES_UNAVAILABLE;
2131  break;
2132  }
2133 
2134  return presentation;
2135 }
#define AST_PRES_RESTRICTED
Definition: callerid.h:325
#define AST_PRES_ALLOWED
Definition: callerid.h:324
#define AST_PRES_UNAVAILABLE
Definition: callerid.h:326

◆ misdn_to_ast_reason()

static enum AST_REDIRECTING_REASON misdn_to_ast_reason ( const enum mISDN_REDIRECTING_REASON  q931)
static

Definition at line 2314 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().

2315 {
2316  enum AST_REDIRECTING_REASON ast;
2317 
2318  switch (q931) {
2319  default:
2322  break;
2323 
2326  break;
2327 
2330  break;
2331 
2334  break;
2335 
2338  break;
2339 
2342  break;
2343 
2346  break;
2347  }
2348 
2349  return ast;
2350 }
AST_REDIRECTING_REASON
redirecting reason codes.
Definition: callerid.h:390

◆ misdn_to_ast_screen()

static int misdn_to_ast_screen ( int  screening)
static

Definition at line 2210 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().

2211 {
2212  switch (screening) {
2213  default:
2214  case 0:
2215  screening = AST_PRES_USER_NUMBER_UNSCREENED;
2216  break;
2217 
2218  case 1:
2220  break;
2221 
2222  case 2:
2224  break;
2225 
2226  case 3:
2227  screening = AST_PRES_NETWORK_NUMBER;
2228  break;
2229  }
2230 
2231  return screening;
2232 }
#define AST_PRES_USER_NUMBER_FAILED_SCREEN
Definition: callerid.h:320
#define AST_PRES_NETWORK_NUMBER
Definition: callerid.h:321
#define AST_PRES_USER_NUMBER_UNSCREENED
Definition: callerid.h:318
#define AST_PRES_USER_NUMBER_PASSED_SCREEN
Definition: callerid.h:319

◆ misdn_to_ast_ton()

static int misdn_to_ast_ton ( enum mISDN_NUMBER_TYPE  number_type)
static

Definition at line 1874 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().

1875 {
1876  int ast_number_type;
1877 
1878  switch (number_type) {
1879  default:
1880  case NUMTYPE_UNKNOWN:
1881  ast_number_type = NUMTYPE_UNKNOWN << 4;
1882  break;
1883 
1884  case NUMTYPE_INTERNATIONAL:
1885  ast_number_type = NUMTYPE_INTERNATIONAL << 4;
1886  break;
1887 
1888  case NUMTYPE_NATIONAL:
1889  ast_number_type = NUMTYPE_NATIONAL << 4;
1890  break;
1891 
1893  ast_number_type = NUMTYPE_NETWORK_SPECIFIC << 4;
1894  break;
1895 
1896  case NUMTYPE_SUBSCRIBER:
1897  ast_number_type = NUMTYPE_SUBSCRIBER << 4;
1898  break;
1899 
1900  case NUMTYPE_ABBREVIATED:
1901  ast_number_type = NUMTYPE_ABBREVIATED << 4;
1902  break;
1903  }
1904 
1905  return ast_number_type;
1906 }

◆ misdn_to_str_plan()

static const char* misdn_to_str_plan ( enum mISDN_NUMBER_PLAN  number_plan)
static

Definition at line 1958 of file chan_misdn.c.

References NUMPLAN_DATA, NUMPLAN_ISDN, NUMPLAN_NATIONAL, NUMPLAN_PRIVATE, NUMPLAN_TELEX, NUMPLAN_UNKNOWN, and str.

Referenced by cb_events().

1959 {
1960  const char *str;
1961 
1962  switch (number_plan) {
1963  default:
1964  case NUMPLAN_UNKNOWN:
1965  str = "Unknown";
1966  break;
1967 
1968  case NUMPLAN_ISDN:
1969  str = "ISDN";
1970  break;
1971 
1972  case NUMPLAN_DATA:
1973  str = "Data";
1974  break;
1975 
1976  case NUMPLAN_TELEX:
1977  str = "Telex";
1978  break;
1979 
1980  case NUMPLAN_NATIONAL:
1981  str = "National";
1982  break;
1983 
1984  case NUMPLAN_PRIVATE:
1985  str = "Private";
1986  break;
1987  }
1988 
1989  return str;
1990 }
const char * str
Definition: app_jack.c:147

◆ misdn_to_str_pres()

static const char* misdn_to_str_pres ( int  presentation)
static

Definition at line 2084 of file chan_misdn.c.

References str.

Referenced by cb_events(), and update_config().

2085 {
2086  const char *str;
2087 
2088  switch (presentation) {
2089  case 0:
2090  str = "Allowed";
2091  break;
2092 
2093  case 1:
2094  str = "Restricted";
2095  break;
2096 
2097  case 2:
2098  str = "Unavailable";
2099  break;
2100 
2101  default:
2102  str = "Unknown";
2103  break;
2104  }
2105 
2106  return str;
2107 }
const char * str
Definition: app_jack.c:147

◆ misdn_to_str_screen()

static const char* misdn_to_str_screen ( int  screening)
static

Definition at line 2173 of file chan_misdn.c.

References str.

Referenced by cb_events(), and update_config().

2174 {
2175  const char *str;
2176 
2177  switch (screening) {
2178  case 0:
2179  str = "Unscreened";
2180  break;
2181 
2182  case 1:
2183  str = "Passed Screen";
2184  break;
2185 
2186  case 2:
2187  str = "Failed Screen";
2188  break;
2189 
2190  case 3:
2191  str = "Network Number";
2192  break;
2193 
2194  default:
2195  str = "Unknown";
2196  break;
2197  }
2198 
2199  return str;
2200 }
const char * str
Definition: app_jack.c:147

◆ misdn_to_str_ton()

static const char* misdn_to_str_ton ( enum mISDN_NUMBER_TYPE  number_type)
static

Definition at line 1832 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().

1833 {
1834  const char *str;
1835 
1836  switch (number_type) {
1837  default:
1838  case NUMTYPE_UNKNOWN:
1839  str = "Unknown";
1840  break;
1841 
1842  case NUMTYPE_INTERNATIONAL:
1843  str = "International";
1844  break;
1845 
1846  case NUMTYPE_NATIONAL:
1847  str = "National";
1848  break;
1849 
1851  str = "Network Specific";
1852  break;
1853 
1854  case NUMTYPE_SUBSCRIBER:
1855  str = "Subscriber";
1856  break;
1857 
1858  case NUMTYPE_ABBREVIATED:
1859  str = "Abbreviated";
1860  break;
1861  }
1862 
1863  return str;
1864 }
const char * str
Definition: app_jack.c:147

◆ misdn_update_caller_id()

static void misdn_update_caller_id ( struct ast_channel ast,
const struct misdn_party_id id,
char *  cid_tag 
)
static

Definition at line 6171 of file chan_misdn.c.

References ast_party_caller::ani, ast_set_party_caller::ani, ast_channel_caller(), ast_channel_lock, ast_channel_set_caller_event(), ast_channel_unlock, ast_party_caller_set_init(), ast_party_caller::id, ast_set_party_caller::id, misdn_to_ast_plan(), misdn_to_ast_pres(), misdn_to_ast_screen(), misdn_to_ast_ton(), misdn_party_id::number, ast_party_id::number, ast_set_party_id::number, misdn_party_id::number_plan, misdn_party_id::number_type, ast_party_number::plan, misdn_party_id::presentation, ast_party_number::presentation, misdn_party_id::screening, ast_party_number::str, ast_party_id::tag, and ast_party_number::valid.

Referenced by misdn_update_remote_party().

6172 {
6173  struct ast_party_caller caller;
6174  struct ast_set_party_caller update_caller;
6175 
6176  memset(&update_caller, 0, sizeof(update_caller));
6177  update_caller.id.number = 1;
6178  update_caller.ani.number = 1;
6179 
6180  ast_channel_lock(ast);
6182 
6183  caller.id.number.valid = 1;
6184  caller.id.number.str = (char *) id->number;
6185  caller.id.number.plan = misdn_to_ast_ton(id->number_type)
6187  caller.id.number.presentation = misdn_to_ast_pres(id->presentation)
6189 
6190  caller.ani.number = caller.id.number;
6191 
6192  caller.id.tag = cid_tag;
6193  caller.ani.tag = cid_tag;
6194 
6195  ast_channel_set_caller_event(ast, &caller, &update_caller);
6196  ast_channel_unlock(ast);
6197 }
struct ast_party_caller * ast_channel_caller(struct ast_channel *chan)
#define ast_channel_lock(chan)
Definition: channel.h:2945
char number[MISDN_MAX_NUMBER_LEN]
Phone number (Address)
Definition: isdn_lib.h:298
void ast_channel_set_caller_event(struct ast_channel *chan, const struct ast_party_caller *caller, const struct ast_set_party_caller *update)
Set the caller id information in the Asterisk channel and generate an AMI event if the caller id name...
Definition: channel.c:7472
static int misdn_to_ast_plan(enum mISDN_NUMBER_PLAN number_plan)
Definition: chan_misdn.c:2000
static int misdn_to_ast_pres(int presentation)
Definition: chan_misdn.c:2117
int presentation
Number presentation restriction code 0=Allowed, 1=Restricted, 2=Unavailable.
Definition: isdn_lib.h:277
Indicate what information in ast_party_caller should be set.
Definition: channel.h:441
static int misdn_to_ast_ton(enum mISDN_NUMBER_TYPE number_type)
Definition: chan_misdn.c:1874
Caller Party information.
Definition: channel.h:419
enum mISDN_NUMBER_TYPE number_type
Type-of-number in ISDN terms for the number.
Definition: isdn_lib.h:285
void ast_party_caller_set_init(struct ast_party_caller *init, const struct ast_party_caller *guide)
Initialize the given caller structure using the given guide for a set update operation.
Definition: channel.c:1999
#define ast_channel_unlock(chan)
Definition: channel.h:2946
int screening
Number screening code 0=Unscreened, 1=Passed Screen, 2=Failed Screen, 3=Network Number.
Definition: isdn_lib.h:282
static int misdn_to_ast_screen(int screening)
Definition: chan_misdn.c:2210
enum mISDN_NUMBER_PLAN number_plan
Type-of-number numbering plan.
Definition: isdn_lib.h:288

◆ misdn_update_connected_line()

static void misdn_update_connected_line ( struct ast_channel ast,
struct misdn_bchannel bc,
int  originator 
)
static

Definition at line 6300 of file chan_misdn.c.

References misdn_bchannel::caller, misdn_bchannel::connected, EVENT_FACILITY, EVENT_NOTIFY, misdn_bchannel::fac_out, MISDN_ASTERISK_TECH_PVT, MISDN_CONNECTED, misdn_get_connected_line(), misdn_lib_is_ptp(), misdn_lib_port_is_nt(), misdn_lib_send_event(), mISDN_NOTIFY_CODE_CALL_TRANSFER_ACTIVE, misdn_bchannel::notify_description_code, ORG_MISDN, misdn_bchannel::outgoing_colp, misdn_bchannel::port, misdn_party_id::presentation, print_facility(), misdn_bchannel::redirecting, chan_list::state, misdn_party_redirecting::to, and misdn_party_redirecting::to_changed.

Referenced by misdn_indication().

6301 {
6302  struct chan_list *ch;
6303 
6305  if (originator == ORG_MISDN) {
6306  bc->redirecting.to = bc->connected;
6307  } else {
6308  bc->redirecting.to = bc->caller;
6309  }
6310  switch (bc->outgoing_colp) {
6311  case 1:/* restricted */
6312  bc->redirecting.to.presentation = 1;/* restricted */
6313  break;
6314  case 2:/* blocked */
6315  /* Don't tell the remote party that the call was transferred. */
6316  return;
6317  default:
6318  break;
6319  }
6320 
6321  ch = MISDN_ASTERISK_TECH_PVT(ast);
6322  if (ch->state == MISDN_CONNECTED
6323  || originator != ORG_MISDN) {
6324  int is_ptmp;
6325 
6326  is_ptmp = !misdn_lib_is_ptp(bc->port);
6327  if (is_ptmp) {
6328  /*
6329  * We should not send these messages to the network if we are
6330  * the CPE side since phones do not transfer calls within
6331  * themselves. Well... If you consider handing the handset to
6332  * someone else a transfer then how is the network to know?
6333  */
6334  if (!misdn_lib_port_is_nt(bc->port)) {
6335  return;
6336  }
6337  if (ch->state != MISDN_CONNECTED) {
6338  /* Send NOTIFY(Nie(transfer-active), RDNie(redirecting.to data)) */
6339  bc->redirecting.to_changed = 1;
6342 #if defined(AST_MISDN_ENHANCEMENTS)
6343  } else {
6344  /* Send FACILITY(Fie(RequestSubaddress), Nie(transfer-active), RDNie(redirecting.to data)) */
6345  bc->redirecting.to_changed = 1;
6347  bc->fac_out.Function = Fac_RequestSubaddress;
6348  bc->fac_out.u.RequestSubaddress.InvokeID = ++misdn_invoke_id;
6349 
6350  /* Send message */
6351  print_facility(&bc->fac_out, bc);
6353 #endif /* defined(AST_MISDN_ENHANCEMENTS) */
6354  }
6355 #if defined(AST_MISDN_ENHANCEMENTS)
6356  } else {
6357  /* Send FACILITY(Fie(EctInform(transfer-active, redirecting.to data))) */
6358  bc->fac_out.Function = Fac_EctInform;
6359  bc->fac_out.u.EctInform.InvokeID = ++misdn_invoke_id;
6360  bc->fac_out.u.EctInform.Status = 1;/* active */
6361  bc->fac_out.u.EctInform.RedirectionPresent = 1;/* Must be present when status is active */
6362  misdn_PresentedNumberUnscreened_fill(&bc->fac_out.u.EctInform.Redirection,
6363  &bc->redirecting.to);
6364 
6365  /* Send message */
6366  print_facility(&bc->fac_out, bc);
6368 #endif /* defined(AST_MISDN_ENHANCEMENTS) */
6369  }
6370  }
6371 }
struct FacParm fac_out
Outbound FACILITY message function type and contents.
Definition: isdn_lib.h:512
int outgoing_colp
Select what to do with outgoing COLP information.
Definition: isdn_lib.h:594
int presentation
Number presentation restriction code 0=Allowed, 1=Restricted, 2=Unavailable.
Definition: isdn_lib.h:277
#define MISDN_ASTERISK_TECH_PVT(ast)
Definition: chan_misdn.c:683
struct misdn_party_id to
Where the call is being redirected toward (Sent to the calling party)
Definition: isdn_lib.h:310
static void print_facility(const struct FacParm *fac, const struct misdn_bchannel *bc)
Definition: chan_misdn.c:2762
struct misdn_party_id caller
Originating/Caller ID information struct.
Definition: isdn_lib.h:343
enum misdn_chan_state state
State of the channel.
Definition: chan_misdn.c:386
int misdn_lib_is_ptp(int port)
Definition: isdn_lib.c:128
struct misdn_party_id connected
Connected-Party/Connected-Line ID information struct.
Definition: isdn_lib.h:353
int originator
Who originally created this channel. ORG_AST or ORG_MISDN.
Definition: chan_misdn.c:407
struct misdn_party_redirecting redirecting
Redirecting information struct (Where a call diversion or transfer was invoked)
Definition: isdn_lib.h:358
int port
Logical Layer 1 port associated with this B channel.
Definition: isdn_lib.h:370
#define ORG_MISDN
Definition: chan_misdn.c:345
Channel call record structure.
Definition: chan_misdn.c:377
int misdn_lib_port_is_nt(int port)
Definition: isdn_lib.c:65
int to_changed
TRUE if the redirecting.to information has changed.
Definition: isdn_lib.h:319
enum mISDN_NOTIFY_CODE notify_description_code
Notification indicator ie description code.
Definition: isdn_lib.h:606
static void misdn_get_connected_line(struct ast_channel *ast, struct misdn_bchannel *bc, int originator)
Definition: chan_misdn.c:6226
int misdn_lib_send_event(struct misdn_bchannel *bc, enum event_e event)
Definition: isdn_lib.c:3523

◆ misdn_update_redirecting()

static void misdn_update_redirecting ( struct ast_channel ast,
struct misdn_bchannel bc,
int  originator 
)
static

Definition at line 6483 of file chan_misdn.c.

References ast_channel_exten(), EVENT_FACILITY, EVENT_NOTIFY, 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().

6484 {
6485  int is_ptmp;
6486 
6488  switch (bc->outgoing_colp) {
6489  case 1:/* restricted */
6490  bc->redirecting.to.presentation = 1;/* restricted */
6491  break;
6492  case 2:/* blocked */
6493  /* Don't tell the remote party that the call was redirected. */
6494  return;
6495  default:
6496  break;
6497  }
6498 
6499  if (originator != ORG_MISDN) {
6500  return;
6501  }
6502 
6503  is_ptmp = !misdn_lib_is_ptp(bc->port);
6504  if (is_ptmp) {
6505  /*
6506  * We should not send these messages to the network if we are
6507  * the CPE side since phones do not redirect calls within
6508  * themselves. Well... If you consider someone else picking up
6509  * the handset a redirection then how is the network to know?
6510  */
6511  if (!misdn_lib_port_is_nt(bc->port)) {
6512  return;
6513  }
6514  /* Send NOTIFY(call-is-diverting, redirecting.to data) */
6515  bc->redirecting.to_changed = 1;
6518 #if defined(AST_MISDN_ENHANCEMENTS)
6519  } else {
6520  int match; /* TRUE if the dialed number matches the redirecting to number */
6521 
6522  match = (strcmp(ast_channel_exten(ast), bc->redirecting.to.number) == 0) ? 1 : 0;
6523  if (!bc->div_leg_3_tx_pending
6524  || !match) {
6525  /* Send DivertingLegInformation1 */
6526  bc->fac_out.Function = Fac_DivertingLegInformation1;
6527  bc->fac_out.u.DivertingLegInformation1.InvokeID = ++misdn_invoke_id;
6528  bc->fac_out.u.DivertingLegInformation1.DiversionReason =
6529  misdn_to_diversion_reason(bc->redirecting.reason);
6530  bc->fac_out.u.DivertingLegInformation1.SubscriptionOption = 2;/* notificationWithDivertedToNr */
6531  bc->fac_out.u.DivertingLegInformation1.DivertedToPresent = 1;
6532  misdn_PresentedNumberUnscreened_fill(&bc->fac_out.u.DivertingLegInformation1.DivertedTo, &bc->redirecting.to);
6533  print_facility(&bc->fac_out, bc);
6535  }
6536  bc->div_leg_3_tx_pending = 0;
6537 
6538  /* Send DivertingLegInformation3 */
6539  bc->fac_out.Function = Fac_DivertingLegInformation3;
6540  bc->fac_out.u.DivertingLegInformation3.InvokeID = ++misdn_invoke_id;
6541  bc->fac_out.u.DivertingLegInformation3.PresentationAllowedIndicator =
6542  bc->redirecting.to.presentation == 0 ? 1 : 0;
6543  print_facility(&bc->fac_out, bc);
6545 #endif /* defined(AST_MISDN_ENHANCEMENTS) */
6546  }
6547 }
struct FacParm fac_out
Outbound FACILITY message function type and contents.
Definition: isdn_lib.h:512
char number[MISDN_MAX_NUMBER_LEN]
Phone number (Address)
Definition: isdn_lib.h:298
int outgoing_colp
Select what to do with outgoing COLP information.
Definition: isdn_lib.h:594
int presentation
Number presentation restriction code 0=Allowed, 1=Restricted, 2=Unavailable.
Definition: isdn_lib.h:277
static int match(struct ast_sockaddr *addr, unsigned short callno, unsigned short dcallno, const struct chan_iax2_pvt *cur, int check_dcallno)
Definition: chan_iax2.c:2315
struct misdn_party_id to
Where the call is being redirected toward (Sent to the calling party)
Definition: isdn_lib.h:310
static void print_facility(const struct FacParm *fac, const struct misdn_bchannel *bc)
Definition: chan_misdn.c:2762
const char * ast_channel_exten(const struct ast_channel *chan)
int misdn_lib_is_ptp(int port)
Definition: isdn_lib.c:128
int originator
Who originally created this channel. ORG_AST or ORG_MISDN.
Definition: chan_misdn.c:407
struct misdn_party_redirecting redirecting
Redirecting information struct (Where a call diversion or transfer was invoked)
Definition: isdn_lib.h:358
int port
Logical Layer 1 port associated with this B channel.
Definition: isdn_lib.h:370
#define ORG_MISDN
Definition: chan_misdn.c:345
static void misdn_copy_redirecting_from_ast(struct misdn_bchannel *bc, struct ast_channel *ast)
Definition: chan_misdn.c:6382
int misdn_lib_port_is_nt(int port)
Definition: isdn_lib.c:65
int to_changed
TRUE if the redirecting.to information has changed.
Definition: isdn_lib.h:319
enum mISDN_REDIRECTING_REASON reason
Reason a call is being redirected (Q.931 field value)
Definition: isdn_lib.h:313
enum mISDN_NOTIFY_CODE notify_description_code
Notification indicator ie description code.
Definition: isdn_lib.h:606
int misdn_lib_send_event(struct misdn_bchannel *bc, enum event_e event)
Definition: isdn_lib.c:3523

◆ misdn_update_remote_party()

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 6210 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().

6211 {
6212  misdn_update_caller_id(ast, id, cid_tag);
6213  misdn_queue_connected_line_update(ast, id, source, cid_tag);
6214 }
static void misdn_update_caller_id(struct ast_channel *ast, const struct misdn_party_id *id, char *cid_tag)
Definition: chan_misdn.c:6171
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)
Definition: chan_misdn.c:6135

◆ misdn_write()

static int misdn_write ( struct ast_channel ast,
struct ast_frame frame 
)
static

Definition at line 7478 of file chan_misdn.c.

References misdn_bchannel::active, misdn_bchannel::addr, AST_BRIDGE_COMPLETE, AST_BRIDGE_DTMF_CHANNEL_0, AST_BRIDGE_DTMF_CHANNEL_1, AST_BRIDGE_FAILED, AST_BRIDGE_FAILED_NOWARN, ast_channel_caller(), ast_channel_exten(), ast_channel_hangupcause_hash_set(), ast_channel_name(), AST_CONTROL_PVT_CAUSE_CODE, ast_debug, ast_format_alaw, ast_format_cmp(), AST_FORMAT_CMP_NOT_EQUAL, ast_format_get_name(), 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::bc_state, BCHAN_ACTIVATED, BCHAN_BRIDGED, misdn_bchannel::caller, misdn_bchannel::capability, cb_log, chan_list_unref, chan_misdn_log(), ast_frame::data, ast_frame::datalen, chan_list::dropped_frame_cnt, ast_frame_subclass::format, ast_frame::frametype, chan_list::hold, chan_list::ignore_dtmf, ast_frame_subclass::integer, chan_list::jb, misdn_bchannel::l3_id, LOG_NOTICE, LOG_WARNING, max, MISDN_ASTERISK_TECH_PVT, misdn_cap_is_speech(), MISDN_CFG_BRIDGING, misdn_cfg_get(), MISDN_GEN_BRIDGING, misdn_get_ch_state(), MISDN_HOLD_IDLE, misdn_jb_fill(), misdn_lib_bridge(), misdn_lib_split_bridge(), misdn_lib_tone_generator_start(), misdn_lib_tx2misdn_frm(), misdn_party_id::name, misdn_bchannel::nojitter, chan_list::notxtone, misdn_party_id::number, misdn_bchannel::pid, misdn_bchannel::port, ast_frame::ptr, S_COR, ast_frame::samples, ast_frame::src, hold_info::state, ast_frame::subclass, and chan_list::ts.

7479 {
7480  struct chan_list *ch;
7481 
7482  if (!ast || !(ch = MISDN_ASTERISK_TECH_PVT(ast))) {
7483  return -1;
7484  }
7485 
7486  if (ch->hold.state != MISDN_HOLD_IDLE) {
7487  chan_misdn_log(7, 0, "misdn_write: Returning because hold active\n");
7488  return 0;
7489  }
7490 
7491  if (!ch->bc) {
7492  ast_log(LOG_WARNING, "private but no bc\n");
7493  return -1;
7494  }
7495 
7496  if (ch->notxtone) {
7497  chan_misdn_log(7, ch->bc->port, "misdn_write: Returning because notxtone\n");
7498  return 0;
7499  }
7500 
7501 
7502  if (!frame->subclass.format) {
7503  chan_misdn_log(4, ch->bc->port, "misdn_write: * prods us\n");
7504  return 0;
7505  }
7506 
7508  chan_misdn_log(-1, ch->bc->port, "Got Unsupported Frame with Format:%s\n",
7510  return 0;
7511  }
7512 
7513 
7514  if (!frame->samples) {
7515  chan_misdn_log(4, ch->bc->port, "misdn_write: zero write\n");
7516 
7517  if (!strcmp(frame->src,"ast_prod")) {
7518  chan_misdn_log(1, ch->bc->port, "misdn_write: state (%s) prodded.\n", misdn_get_ch_state(ch));
7519 
7520  if (ch->ts) {
7521  chan_misdn_log(4, ch->bc->port, "Starting Playtones\n");
7523  }
7524  return 0;
7525  }
7526 
7527  return -1;
7528  }
7529 
7530  if (!ch->bc->addr) {
7531  chan_misdn_log(8, ch->bc->port, "misdn_write: no addr for bc dropping:%d\n", frame->samples);
7532  return 0;
7533  }
7534 
7535 #ifdef MISDN_DEBUG
7536  {
7537  int i;
7538  int max = 5 > frame->samples ? frame->samples : 5;
7539 
7540  ast_debug(1, "write2mISDN %p %d bytes: ", p, frame->samples);
7541 
7542  for (i = 0; i < max; i++) {
7543  ast_debug(1, "%02hhx ", ((unsigned char *) frame->data.ptr)[i]);
7544  }
7545  }
7546 #endif
7547 
7548  switch (ch->bc->bc_state) {
7549  case BCHAN_ACTIVATED:
7550  case BCHAN_BRIDGED:
7551  break;
7552  default:
7553  if (!ch->dropped_frame_cnt) {
7554  chan_misdn_log(5, ch->bc->port,
7555  "BC not active (nor bridged) dropping: %d frames addr:%x exten:%s cid:%s ch->state:%s bc_state:%d l3id:%x\n",
7556  frame->samples, ch->bc->addr, ast_channel_exten(ast),
7557  S_COR(ast_channel_caller(ast)->id.number.valid, ast_channel_caller(ast)->id.number.str, ""),
7558  misdn_get_ch_state(ch), ch->bc->bc_state, ch->bc->l3_id);
7559  }
7560 
7561  if (++ch->dropped_frame_cnt > 100) {
7562  ch->dropped_frame_cnt = 0;
7563  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);
7564  }
7565 
7566  return 0;
7567  }
7568 
7569  chan_misdn_log(9, ch->bc->port, "Sending :%d bytes to MISDN\n", frame->samples);
7570  if (!ch->bc->nojitter && misdn_cap_is_speech(ch->bc->capability)) {
7571  /* Buffered Transmit (triggered by read from isdn side)*/
7572  if (misdn_jb_fill(ch->jb, frame->data.ptr, frame->samples) < 0) {
7573  if (ch->bc->active) {
7574  cb_log(0, ch->bc->port, "Misdn Jitterbuffer Overflow.\n");
7575  }
7576  }
7577 
7578  } else {
7579  /* transmit without jitterbuffer */
7580  misdn_lib_tx2misdn_frm(ch->bc, frame->data.ptr, frame->samples);
7581  }
7582 
7583  return 0;
7584 }
struct ast_party_caller * ast_channel_caller(struct ast_channel *chan)
static void chan_misdn_log(int level, int port, char *tmpl,...)
Definition: chan_misdn.c:12768
#define LOG_WARNING
Definition: logger.h:274
struct misdn_jb * jb
Allocated jitterbuffer controller.
Definition: chan_misdn.c:503
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: chan_misdn.c:12650
void misdn_lib_tone_generator_start(struct misdn_bchannel *bc)
Definition: isdn_lib.c:2271
struct hold_info hold
HELD channel call information.
Definition: chan_misdn.c:535
static const char * misdn_get_ch_state(struct chan_list *p)
Definition: chan_misdn.c:4102
#define MISDN_ASTERISK_TECH_PVT(ast)
Definition: chan_misdn.c:683
int capability
SETUP message bearer capability field code value.
Definition: isdn_lib.h:609
const char * ast_format_get_name(const struct ast_format *format)
Get the name associated with a format.
Definition: format.c:334
int notxtone
TRUE if we are not to generate tones (Playtones)
Definition: chan_misdn.c:420
struct ast_frame_subclass subclass
int misdn_cap_is_speech(int cap)
Definition: isdn_lib.c:436
Number structure.
Definition: app_followme.c:154
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
enum ast_format_cmp_res ast_format_cmp(const struct ast_format *format1, const struct ast_format *format2)
Compare two formats.
Definition: format.c:201
const char * src
int dropped_frame_cnt
Number of outgoing audio frames dropped since last debug gripe message.
Definition: chan_misdn.c:564
#define S_COR(a, b, c)
returns the equivalent of logic or for strings, with an additional boolean check: second one if not e...
Definition: strings.h:85
int nojitter
TRUE if we will not use the jitter buffer system.
Definition: isdn_lib.h:477
const char * ast_channel_exten(const struct ast_channel *chan)
int misdn_lib_tx2misdn_frm(struct misdn_bchannel *bc, void *data, int len)
Definition: isdn_lib.c:4382
int port
Logical Layer 1 port associated with this B channel.
Definition: isdn_lib.h:370
int addr
B Channel mISDN driver layer ID from mISDN_get_layerid()
Definition: isdn_lib.h:429
int active
Seems to have been intended for something to do with the jitter buffer.
Definition: isdn_lib.h:537
Channel call record structure.
Definition: chan_misdn.c:377
enum misdn_hold_state state
Call HOLD state.
Definition: chan_misdn.c:357
struct ast_tone_zone_sound * ts
Tone zone sound used for dialtone generation.
Definition: chan_misdn.c:582
enum bchannel_state bc_state
Current B Channel state.
Definition: isdn_lib.h:547
struct ast_format * ast_format_alaw
Built-in cached alaw format.
Definition: format_cache.c:91
union ast_frame::@263 data
struct ast_format * format
struct misdn_bchannel * bc
Associated B channel structure.
Definition: chan_misdn.c:520
void(* cb_log)(int level, int port, char *tmpl,...)
Definition: isdn_lib.c:32
int l3_id
Layer 3 process ID.
Definition: isdn_lib.h:399
#define max(a, b)
Definition: f2c.h:198

◆ pbx_start_chan()

static int pbx_start_chan ( struct chan_list ch)
static

Channel Queue End

Definition at line 8438 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().

8439 {
8440  int ret = ast_pbx_start(ch->ast);
8441 
8442  ch->need_hangup = (ret >= 0) ? 0 : 1;
8443 
8444  return ret;
8445 }
int need_hangup
TRUE if a channel can be hung up by calling asterisk directly when done.
Definition: chan_misdn.c:397
enum ast_pbx_result ast_pbx_start(struct ast_channel *c)
Create a new thread and start the PBX.
Definition: pbx.c:4712
struct ast_channel * ast
Associated Asterisk channel structure.
Definition: chan_misdn.c:515

◆ print_bc_info()

static void print_bc_info ( int  fd,
struct chan_list help,
struct misdn_bchannel bc 
)
static

Definition at line 4167 of file chan_misdn.c.

References misdn_bchannel::active, misdn_bchannel::addr, chan_list::addr, chan_list::ast, ast_channel_caller(), ast_channel_context(), ast_channel_exten(), ast_channel_name(), ast_cli(), misdn_bchannel::bc_state, bc_state2str(), bearer2str(), misdn_bchannel::capability, misdn_bchannel::channel, misdn_bchannel::display, misdn_bchannel::ec_enable, misdn_party_redirecting::from, misdn_bchannel::holded, misdn_bchannel::l3_id, chan_list::l3id, misdn_get_ch_state(), name, misdn_party_id::name, chan_list::norxtone, chan_list::notxtone, misdn_bchannel::nt, misdn_party_id::number, ORG_AST, chan_list::originator, misdn_bchannel::pid, misdn_bchannel::port, misdn_bchannel::redirecting, and misdn_party_redirecting::to.

Referenced by handle_cli_misdn_show_channel(), and handle_cli_misdn_show_channels().

4168 {
4169  struct ast_channel *ast = help->ast;
4170 
4171  ast_cli(fd,
4172  "* Pid:%d Port:%d Ch:%d Mode:%s Orig:%s dialed:%s\n"
4173  " --> caller:\"%s\" <%s>\n"
4174  " --> redirecting-from:\"%s\" <%s>\n"
4175  " --> redirecting-to:\"%s\" <%s>\n"
4176  " --> context:%s state:%s\n",
4177  bc->pid,
4178  bc->port,
4179  bc->channel,
4180  bc->nt ? "NT" : "TE",
4181  help->originator == ORG_AST ? "*" : "I",
4182  ast ? ast_channel_exten(ast) : "",
4183  (ast && ast_channel_caller(ast)->id.name.valid && ast_channel_caller(ast)->id.name.str)
4184  ? ast_channel_caller(ast)->id.name.str : "",
4185  (ast && ast_channel_caller(ast)->id.number.valid && ast_channel_caller(ast)->id.number.str)
4186  ? ast_channel_caller(ast)->id.number.str : "",
4187  bc->redirecting.from.name,
4188  bc->redirecting.from.number,
4189  bc->redirecting.to.name,
4190  bc->redirecting.to.number,
4191  ast ? ast_channel_context(ast) : "",
4192  misdn_get_ch_state(help));
4193  if (misdn_debug[bc->port] > 0) {
4194  ast_cli(fd,
4195  " --> astname: %s\n"
4196  " --> ch_l3id: %x\n"
4197  " --> ch_addr: %x\n"
4198  " --> bc_addr: %x\n"
4199  " --> bc_l3id: %x\n"
4200  " --> display: %s\n"
4201  " --> activated: %d\n"
4202  " --> state: %s\n"
4203  " --> capability: %s\n"
4204 #ifdef MISDN_1_2
4205  " --> pipeline: %s\n"
4206 #else
4207  " --> echo_cancel: %d\n"
4208 #endif
4209  " --> notone : rx %d tx:%d\n"
4210  " --> bc_hold: %d\n",
4211  ast ? ast_channel_name(ast) : "",
4212  help->l3id,
4213  help->addr,
4214  bc->addr,
4215  bc->l3_id,
4216  bc->display,
4217  bc->active,
4218  bc_state2str(bc->bc_state),
4219  bearer2str(bc->capability),
4220 #ifdef MISDN_1_2
4221  bc->pipeline,
4222 #else
4223  bc->ec_enable,
4224 #endif
4225  help->norxtone, help->notxtone,
4226  bc->holded);
4227  }
4228 }
struct ast_party_caller * ast_channel_caller(struct ast_channel *chan)
Main Channel structure associated with a channel.
char number[MISDN_MAX_NUMBER_LEN]
Phone number (Address)
Definition: isdn_lib.h:298
int addr
From associated B channel: B Channel mISDN driver layer ID from mISDN_get_layerid() ...
Definition: chan_misdn.c:547
int ec_enable
TRUE if the echo cancellor is enabled.
Definition: isdn_lib.h:688
int norxtone
Definition: chan_misdn.c:415
static const char * misdn_get_ch_state(struct chan_list *p)
Definition: chan_misdn.c:4102
int capability
SETUP message bearer capability field code value.
Definition: isdn_lib.h:609
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
struct ast_channel * ast
Associated Asterisk channel structure.
Definition: chan_misdn.c:515
struct misdn_party_id to
Where the call is being redirected toward (Sent to the calling party)
Definition: isdn_lib.h:310
int notxtone
TRUE if we are not to generate tones (Playtones)
Definition: chan_misdn.c:420
Number structure.
Definition: app_followme.c:154
char display[84]
Display message that can be displayed by the user phone.
Definition: isdn_lib.h:642
int nt
TRUE if NT side of protocol (TE otherwise)
Definition: isdn_lib.h:364
int holded
TRUE if this channel is on hold.
Definition: isdn_lib.h:556
char name[MISDN_MAX_NAME_LEN]
Subscriber Name.
Definition: isdn_lib.h:295
char * bc_state2str(enum bchannel_state state)
Definition: isdn_lib.c:617
const char * ast_channel_exten(const struct ast_channel *chan)
int pid
B channel process ID (1-5000)
Definition: isdn_lib.h:402
int originator
Who originally created this channel. ORG_AST or ORG_MISDN.
Definition: chan_misdn.c:407
struct misdn_party_id from
Who is redirecting the call (Sent to the party the call is redirected toward)
Definition: isdn_lib.h:307
static const char * bearer2str(int cap)
Definition: chan_misdn.c:2373
static int * misdn_debug
Definition: chan_misdn.c:694
struct misdn_party_redirecting redirecting
Redirecting information struct (Where a call diversion or transfer was invoked)
Definition: isdn_lib.h:358
int port
Logical Layer 1 port associated with this B channel.
Definition: isdn_lib.h:370
static const char name[]
Definition: cdr_mysql.c:74
int addr
B Channel mISDN driver layer ID from mISDN_get_layerid()
Definition: isdn_lib.h:429
int active
Seems to have been intended for something to do with the jitter buffer.
Definition: isdn_lib.h:537
unsigned int l3id
From associated B channel: Layer 3 process ID.
Definition: chan_misdn.c:541
int channel
Assigned B channel number B1, B2... 0 if not assigned.
Definition: isdn_lib.h:411
enum bchannel_state bc_state
Current B Channel state.
Definition: isdn_lib.h:547
const char * ast_channel_name(const struct ast_channel *chan)
#define ORG_AST
Definition: chan_misdn.c:343
const char * ast_channel_context(const struct ast_channel *chan)
int l3_id
Layer 3 process ID.
Definition: isdn_lib.h:399

◆ print_bearer()

static void print_bearer ( struct misdn_bchannel bc)
static

Definition at line 3355 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().

3356 {
3357  chan_misdn_log(2, bc->port, " --> Bearer: %s\n", bearer2str(bc->capability));
3358 
3359  switch(bc->law) {
3360  case INFO_CODEC_ALAW:
3361  chan_misdn_log(2, bc->port, " --> Codec: Alaw\n");
3362  break;
3363  case INFO_CODEC_ULAW:
3364  chan_misdn_log(2, bc->port, " --> Codec: Ulaw\n");
3365  break;
3366  }
3367 }
static void chan_misdn_log(int level, int port, char *tmpl,...)
Definition: chan_misdn.c:12768
int capability
SETUP message bearer capability field code value.
Definition: isdn_lib.h:609
static const char * bearer2str(int cap)
Definition: chan_misdn.c:2373
int port
Logical Layer 1 port associated with this B channel.
Definition: isdn_lib.h:370
int law
Companding ALaw/uLaw encoding (INFO_CODEC_ALAW / INFO_CODEC_ULAW)
Definition: isdn_lib.h:612

◆ print_facility()

static void print_facility ( const struct FacParm *  fac,
const struct misdn_bchannel bc 
)
static

Definition at line 2762 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(), misdn_update_redirecting(), reload(), and wait_for_digits().

2763 {
2764 #if defined(AST_MISDN_ENHANCEMENTS)
2765  unsigned Index;
2766 #endif /* defined(AST_MISDN_ENHANCEMENTS) */
2767 
2768  switch (fac->Function) {
2769 #if defined(AST_MISDN_ENHANCEMENTS)
2770  case Fac_ActivationDiversion:
2771  chan_misdn_log(1, bc->port, " --> ActivationDiversion: InvokeID:%d\n",
2772  fac->u.ActivationDiversion.InvokeID);
2773  switch (fac->u.ActivationDiversion.ComponentType) {
2774  case FacComponent_Invoke:
2775  chan_misdn_log(1, bc->port, " --> Invoke: Procedure:%d BasicService:%d\n",
2776  fac->u.ActivationDiversion.Component.Invoke.Procedure,
2777  fac->u.ActivationDiversion.Component.Invoke.BasicService);
2778  chan_misdn_log(1, bc->port, " --> ForwardedTo:\n");
2779  print_facility_Address(3, &fac->u.ActivationDiversion.Component.Invoke.ForwardedTo, bc);
2780  chan_misdn_log(1, bc->port, " --> ServedUserNr:\n");
2781  print_facility_ServedUserNr(3, &fac->u.ActivationDiversion.Component.Invoke.ServedUser, bc);
2782  break;
2783  case FacComponent_Result:
2784  chan_misdn_log(1, bc->port, " --> Result\n");
2785  break;
2786  default:
2787  break;
2788  }
2789  break;
2790  case Fac_DeactivationDiversion:
2791  chan_misdn_log(1, bc->port, " --> DeactivationDiversion: InvokeID:%d\n",
2792  fac->u.DeactivationDiversion.InvokeID);
2793  switch (fac->u.DeactivationDiversion.ComponentType) {
2794  case FacComponent_Invoke:
2795  chan_misdn_log(1, bc->port, " --> Invoke: Procedure:%d BasicService:%d\n",
2796  fac->u.DeactivationDiversion.Component.Invoke.Procedure,
2797  fac->u.DeactivationDiversion.Component.Invoke.BasicService);
2798  chan_misdn_log(1, bc->port, " --> ServedUserNr:\n");
2799  print_facility_ServedUserNr(3, &fac->u.DeactivationDiversion.Component.Invoke.ServedUser, bc);
2800  break;
2801  case FacComponent_Result:
2802  chan_misdn_log(1, bc->port, " --> Result\n");
2803  break;
2804  default:
2805  break;
2806  }
2807  break;
2808  case Fac_ActivationStatusNotificationDiv:
2809  chan_misdn_log(1, bc->port, " --> ActivationStatusNotificationDiv: InvokeID:%d Procedure:%d BasicService:%d\n",
2810  fac->u.ActivationStatusNotificationDiv.InvokeID,
2811  fac->u.ActivationStatusNotificationDiv.Procedure,
2812  fac->u.ActivationStatusNotificationDiv.BasicService);
2813  chan_misdn_log(1, bc->port, " --> ForwardedTo:\n");
2814  print_facility_Address(2, &fac->u.ActivationStatusNotificationDiv.ForwardedTo, bc);
2815  chan_misdn_log(1, bc->port, " --> ServedUserNr:\n");
2816  print_facility_ServedUserNr(2, &fac->u.ActivationStatusNotificationDiv.ServedUser, bc);
2817  break;
2818  case Fac_DeactivationStatusNotificationDiv:
2819  chan_misdn_log(1, bc->port, " --> DeactivationStatusNotificationDiv: InvokeID:%d Procedure:%d BasicService:%d\n",
2820  fac->u.DeactivationStatusNotificationDiv.InvokeID,
2821  fac->u.DeactivationStatusNotificationDiv.Procedure,
2822  fac->u.DeactivationStatusNotificationDiv.BasicService);
2823  chan_misdn_log(1, bc->port, " --> ServedUserNr:\n");
2824  print_facility_ServedUserNr(2, &fac->u.DeactivationStatusNotificationDiv.ServedUser, bc);
2825  break;
2826  case Fac_InterrogationDiversion:
2827  chan_misdn_log(1, bc->port, " --> InterrogationDiversion: InvokeID:%d\n",
2828  fac->u.InterrogationDiversion.InvokeID);
2829  switch (fac->u.InterrogationDiversion.ComponentType) {
2830  case FacComponent_Invoke:
2831  chan_misdn_log(1, bc->port, " --> Invoke: Procedure:%d BasicService:%d\n",
2832  fac->u.InterrogationDiversion.Component.Invoke.Procedure,
2833  fac->u.InterrogationDiversion.Component.Invoke.BasicService);
2834  chan_misdn_log(1, bc->port, " --> ServedUserNr:\n");
2835  print_facility_ServedUserNr(3, &fac->u.InterrogationDiversion.Component.Invoke.ServedUser, bc);
2836  break;
2837  case FacComponent_Result:
2838  chan_misdn_log(1, bc->port, " --> Result:\n");
2839  if (fac->u.InterrogationDiversion.Component.Result.NumRecords) {
2840  for (Index = 0; Index < fac->u.InterrogationDiversion.Component.Result.NumRecords; ++Index) {
2841  chan_misdn_log(1, bc->port, " --> IntResult[%d]:\n", Index);
2842  print_facility_IntResult(3, &fac->u.InterrogationDiversion.Component.Result.List[Index], bc);
2843  }
2844  }
2845  break;
2846  default:
2847  break;
2848  }
2849  break;
2850  case Fac_DiversionInformation:
2851  chan_misdn_log(1, bc->port, " --> DiversionInformation: InvokeID:%d Reason:%d BasicService:%d\n",
2852  fac->u.DiversionInformation.InvokeID,
2853  fac->u.DiversionInformation.DiversionReason,
2854  fac->u.DiversionInformation.BasicService);
2855  if (fac->u.DiversionInformation.ServedUserSubaddress.Length) {
2856  chan_misdn_log(1, bc->port, " --> ServedUserSubaddress:\n");
2857  print_facility_Subaddress(2, &fac->u.DiversionInformation.ServedUserSubaddress, bc);
2858  }
2859  if (fac->u.DiversionInformation.CallingAddressPresent) {
2860  chan_misdn_log(1, bc->port, " --> CallingAddress:\n");
2861  print_facility_PresentedAddressScreened(2, &fac->u.DiversionInformation.CallingAddress, bc);
2862  }
2863  if (fac->u.DiversionInformation.OriginalCalledPresent) {
2864  chan_misdn_log(1, bc->port, " --> OriginalCalledNr:\n");
2865  print_facility_PresentedNumberUnscreened(2, &fac->u.DiversionInformation.OriginalCalled, bc);
2866  }
2867  if (fac->u.DiversionInformation.LastDivertingPresent) {
2868  chan_misdn_log(1, bc->port, " --> LastDivertingNr:\n");
2869  print_facility_PresentedNumberUnscreened(2, &fac->u.DiversionInformation.LastDiverting, bc);
2870  }
2871  if (fac->u.DiversionInformation.LastDivertingReasonPresent) {
2872  chan_misdn_log(1, bc->port, " --> LastDivertingReason:%d\n", fac->u.DiversionInformation.LastDivertingReason);
2873  }
2874  if (fac->u.DiversionInformation.UserInfo.Length) {
2875  chan_misdn_log(1, bc->port, " --> UserInfo Length:%d\n", fac->u.DiversionInformation.UserInfo.Length);
2876  }
2877  break;
2878  case Fac_CallDeflection:
2879  chan_misdn_log(1, bc->port, " --> CallDeflection: InvokeID:%d\n",
2880  fac->u.CallDeflection.InvokeID);
2881  switch (fac->u.CallDeflection.ComponentType) {
2882  case FacComponent_Invoke:
2883  chan_misdn_log(1, bc->port, " --> Invoke:\n");
2884  if (fac->u.CallDeflection.Component.Invoke.PresentationAllowedToDivertedToUserPresent) {
2885  chan_misdn_log(1, bc->port, " --> PresentationAllowed:%d\n",
2886  fac->u.CallDeflection.Component.Invoke.PresentationAllowedToDivertedToUser);
2887  }
2888  chan_misdn_log(1, bc->port, " --> DeflectionAddress:\n");
2889  print_facility_Address(3, &fac->u.CallDeflection.Component.Invoke.Deflection, bc);
2890  break;
2891  case FacComponent_Result:
2892  chan_misdn_log(1, bc->port, " --> Result\n");
2893  break;
2894  default:
2895  break;
2896  }
2897  break;
2898  case Fac_CallRerouteing:
2899  chan_misdn_log(1, bc->port, " --> CallRerouteing: InvokeID:%d\n",
2900  fac->u.CallRerouteing.InvokeID);
2901  switch (fac->u.CallRerouteing.ComponentType) {
2902  case FacComponent_Invoke:
2903  chan_misdn_log(1, bc->port, " --> Invoke: Reason:%d Counter:%d\n",
2904  fac->u.CallRerouteing.Component.Invoke.ReroutingReason,
2905  fac->u.CallRerouteing.Component.Invoke.ReroutingCounter);
2906  chan_misdn_log(1, bc->port, " --> CalledAddress:\n");
2907  print_facility_Address(3, &fac->u.CallRerouteing.Component.Invoke.CalledAddress, bc);
2908  print_facility_Q931_Bc_Hlc_Llc_Uu(2, &fac->u.CallRerouteing.Component.Invoke.Q931ie, bc);
2909  chan_misdn_log(1, bc->port, " --> LastReroutingNr:\n");
2910  print_facility_PresentedNumberUnscreened(3, &fac->u.CallRerouteing.Component.Invoke.LastRerouting, bc);
2911  chan_misdn_log(1, bc->port, " --> SubscriptionOption:%d\n",
2912  fac->u.CallRerouteing.Component.Invoke.SubscriptionOption);
2913  if (fac->u.CallRerouteing.Component.Invoke.CallingPartySubaddress.Length) {
2914  chan_misdn_log(1, bc->port, " --> CallingParty:\n");
2915  print_facility_Subaddress(3, &fac->u.CallRerouteing.Component.Invoke.CallingPartySubaddress, bc);
2916  }
2917  break;
2918  case FacComponent_Result:
2919  chan_misdn_log(1, bc->port, " --> Result\n");
2920  break;
2921  default:
2922  break;
2923  }
2924  break;
2925  case Fac_InterrogateServedUserNumbers:
2926  chan_misdn_log(1, bc->port, " --> InterrogateServedUserNumbers: InvokeID:%d\n",
2927  fac->u.InterrogateServedUserNumbers.InvokeID);
2928  switch (fac->u.InterrogateServedUserNumbers.ComponentType) {
2929  case FacComponent_Invoke:
2930  chan_misdn_log(1, bc->port, " --> Invoke\n");
2931  break;
2932  case FacComponent_Result:
2933  chan_misdn_log(1, bc->port, " --> Result:\n");
2934  if (fac->u.InterrogateServedUserNumbers.Component.Result.NumRecords) {
2935  for (Index = 0; Index < fac->u.InterrogateServedUserNumbers.Component.Result.NumRecords; ++Index) {
2936  chan_misdn_log(1, bc->port, " --> ServedUserNr[%d]:\n", Index);
2937  print_facility_PartyNumber(3, &fac->u.InterrogateServedUserNumbers.Component.Result.List[Index], bc);
2938  }
2939  }
2940  break;
2941  default:
2942  break;
2943  }
2944  break;
2945  case Fac_DivertingLegInformation1:
2946  chan_misdn_log(1, bc->port, " --> DivertingLegInformation1: InvokeID:%d Reason:%d SubscriptionOption:%d\n",
2947  fac->u.DivertingLegInformation1.InvokeID,
2948  fac->u.DivertingLegInformation1.DiversionReason,
2949  fac->u.DivertingLegInformation1.SubscriptionOption);
2950  if (fac->u.DivertingLegInformation1.DivertedToPresent) {
2951  chan_misdn_log(1, bc->port, " --> DivertedToNr:\n");
2952  print_facility_PresentedNumberUnscreened(2, &fac->u.DivertingLegInformation1.DivertedTo, bc);
2953  }
2954  break;
2955  case Fac_DivertingLegInformation2:
2956  chan_misdn_log(1, bc->port, " --> DivertingLegInformation2: InvokeID:%d Reason:%d Count:%d\n",
2957  fac->u.DivertingLegInformation2.InvokeID,
2958  fac->u.DivertingLegInformation2.DiversionReason,
2959  fac->u.DivertingLegInformation2.DiversionCounter);
2960  if (fac->u.DivertingLegInformation2.DivertingPresent) {
2961  chan_misdn_log(1, bc->port, " --> DivertingNr:\n");
2962  print_facility_PresentedNumberUnscreened(2, &fac->u.DivertingLegInformation2.Diverting, bc);
2963  }
2964  if (fac->u.DivertingLegInformation2.OriginalCalledPresent) {
2965  chan_misdn_log(1, bc->port, " --> OriginalCalledNr:\n");
2966  print_facility_PresentedNumberUnscreened(2, &fac->u.DivertingLegInformation2.OriginalCalled, bc);
2967  }
2968  break;
2969  case Fac_DivertingLegInformation3:
2970  chan_misdn_log(1, bc->port, " --> DivertingLegInformation3: InvokeID:%d PresentationAllowed:%d\n",
2971  fac->u.DivertingLegInformation3.InvokeID,
2972  fac->u.DivertingLegInformation3.PresentationAllowedIndicator);
2973  break;
2974 
2975 #else /* !defined(AST_MISDN_ENHANCEMENTS) */
2976 
2977  case Fac_CD:
2978  chan_misdn_log(1, bc->port, " --> calldeflect to: %s, presentable: %s\n", fac->u.CDeflection.DeflectedToNumber,
2979  fac->u.CDeflection.PresentationAllowed ? "yes" : "no");
2980  break;
2981 #endif /* !defined(AST_MISDN_ENHANCEMENTS) */
2982  case Fac_AOCDCurrency:
2983  if (fac->u.AOCDcur.chargeNotAvailable) {
2984  chan_misdn_log(1, bc->port, " --> AOCD currency: charge not available\n");
2985  } else if (fac->u.AOCDcur.freeOfCharge) {
2986  chan_misdn_log(1, bc->port, " --> AOCD currency: free of charge\n");
2987  } else if (fac->u.AOCDchu.billingId >= 0) {
2988  chan_misdn_log(1, bc->port, " --> AOCD currency: currency:%s amount:%d multiplier:%d typeOfChargingInfo:%s billingId:%d\n",
2989  fac->u.AOCDcur.currency, fac->u.AOCDcur.currencyAmount, fac->u.AOCDcur.multiplier,
2990  (fac->u.AOCDcur.typeOfChargingInfo == 0) ? "subTotal" : "total", fac->u.AOCDcur.billingId);
2991  } else {
2992  chan_misdn_log(1, bc->port, " --> AOCD currency: currency:%s amount:%d multiplier:%d typeOfChargingInfo:%s\n",
2993  fac->u.AOCDcur.currency, fac->u.AOCDcur.currencyAmount, fac->u.AOCDcur.multiplier,
2994  (fac->u.AOCDcur.typeOfChargingInfo == 0) ? "subTotal" : "total");
2995  }
2996  break;
2997  case Fac_AOCDChargingUnit:
2998  if (fac->u.AOCDchu.chargeNotAvailable) {
2999  chan_misdn_log(1, bc->port, " --> AOCD charging unit: charge not available\n");
3000  } else if (fac->u.AOCDchu.freeOfCharge) {
3001  chan_misdn_log(1, bc->port, " --> AOCD charging unit: free of charge\n");
3002  } else if (fac->u.AOCDchu.billingId >= 0) {
3003  chan_misdn_log(1, bc->port, " --> AOCD charging unit: recordedUnits:%d typeOfChargingInfo:%s billingId:%d\n",
3004  fac->u.AOCDchu.recordedUnits, (fac->u.AOCDchu.typeOfChargingInfo == 0) ? "subTotal" : "total", fac->u.AOCDchu.billingId);
3005  } else {
3006  chan_misdn_log(1, bc->port, " --> AOCD charging unit: recordedUnits:%d typeOfChargingInfo:%s\n",
3007  fac->u.AOCDchu.recordedUnits, (fac->u.AOCDchu.typeOfChargingInfo == 0) ? "subTotal" : "total");
3008  }
3009  break;
3010 #if defined(AST_MISDN_ENHANCEMENTS)
3011  case Fac_ERROR:
3012  chan_misdn_log(1, bc->port, " --> ERROR: InvokeID:%d, Code:0x%02x\n",
3013  fac->u.ERROR.invokeId, fac->u.ERROR.errorValue);
3014  break;
3015  case Fac_RESULT:
3016  chan_misdn_log(1, bc->port, " --> RESULT: InvokeID:%d\n",
3017  fac->u.RESULT.InvokeID);
3018  break;
3019  case Fac_REJECT:
3020  if (fac->u.REJECT.InvokeIDPresent) {
3021  chan_misdn_log(1, bc->port, " --> REJECT: InvokeID:%d, Code:0x%02x\n",
3022  fac->u.REJECT.InvokeID, fac->u.REJECT.Code);
3023  } else {
3024  chan_misdn_log(1, bc->port, " --> REJECT: Code:0x%02x\n",
3025  fac->u.REJECT.Code);
3026  }
3027  break;
3028  case Fac_EctExecute:
3029  chan_misdn_log(1, bc->port, " --> EctExecute: InvokeID:%d\n",
3030  fac->u.EctExecute.InvokeID);
3031  break;
3032  case Fac_ExplicitEctExecute:
3033  chan_misdn_log(1, bc->port, " --> ExplicitEctExecute: InvokeID:%d LinkID:%d\n",
3034  fac->u.ExplicitEctExecute.InvokeID,
3035  fac->u.ExplicitEctExecute.LinkID);
3036  break;
3037  case Fac_RequestSubaddress:
3038  chan_misdn_log(1, bc->port, " --> RequestSubaddress: InvokeID:%d\n",
3039  fac->u.RequestSubaddress.InvokeID);
3040  break;
3041  case Fac_SubaddressTransfer:
3042  chan_misdn_log(1, bc->port, " --> SubaddressTransfer: InvokeID:%d\n",
3043  fac->u.SubaddressTransfer.InvokeID);
3044  print_facility_Subaddress(1, &fac->u.SubaddressTransfer.Subaddress, bc);
3045  break;
3046  case Fac_EctLinkIdRequest:
3047  chan_misdn_log(1, bc->port, " --> EctLinkIdRequest: InvokeID:%d\n",
3048  fac->u.EctLinkIdRequest.InvokeID);
3049  switch (fac->u.EctLinkIdRequest.ComponentType) {
3050  case FacComponent_Invoke:
3051  chan_misdn_log(1, bc->port, " --> Invoke\n");
3052  break;
3053  case FacComponent_Result:
3054  chan_misdn_log(1, bc->port, " --> Result: LinkID:%d\n",
3055  fac->u.EctLinkIdRequest.Component.Result.LinkID);
3056  break;
3057  default:
3058  break;
3059  }
3060  break;
3061  case Fac_EctInform:
3062  chan_misdn_log(1, bc->port, " --> EctInform: InvokeID:%d Status:%d\n",
3063  fac->u.EctInform.InvokeID,
3064  fac->u.EctInform.Status);
3065  if (fac->u.EctInform.RedirectionPresent) {
3066  chan_misdn_log(1, bc->port, " --> Redirection Number\n");
3067  print_facility_PresentedNumberUnscreened(2, &fac->u.EctInform.Redirection, bc);
3068  }
3069  break;
3070  case Fac_EctLoopTest:
3071  chan_misdn_log(1, bc->port, " --> EctLoopTest: InvokeID:%d\n",
3072  fac->u.EctLoopTest.InvokeID);
3073  switch (fac->u.EctLoopTest.ComponentType) {
3074  case FacComponent_Invoke:
3075  chan_misdn_log(1, bc->port, " --> Invoke: CallTransferID:%d\n",
3076  fac->u.EctLoopTest.Component.Invoke.CallTransferID);
3077  break;
3078  case FacComponent_Result:
3079  chan_misdn_log(1, bc->port, " --> Result: LoopResult:%d\n",
3080  fac->u.EctLoopTest.Component.Result.LoopResult);
3081  break;
3082  default:
3083  break;
3084  }
3085  break;
3086  case Fac_StatusRequest:
3087  chan_misdn_log(1, bc->port, " --> StatusRequest: InvokeID:%d\n",
3088  fac->u.StatusRequest.InvokeID);
3089  switch (fac->u.StatusRequest.ComponentType) {
3090  case FacComponent_Invoke:
3091  chan_misdn_log(1, bc->port, " --> Invoke: Compatibility:%d\n",
3092  fac->u.StatusRequest.Component.Invoke.CompatibilityMode);
3093  break;
3094  case FacComponent_Result:
3095  chan_misdn_log(1, bc->port, " --> Result: Status:%d\n",
3096  fac->u.StatusRequest.Component.Result.Status);
3097  break;
3098  default:
3099  break;
3100  }
3101  break;
3102  case Fac_CallInfoRetain:
3103  chan_misdn_log(1, bc->port, " --> CallInfoRetain: InvokeID:%d, LinkageID:%d\n",
3104  fac->u.CallInfoRetain.InvokeID, fac->u.CallInfoRetain.CallLinkageID);
3105  break;
3106  case Fac_CCBSDeactivate:
3107  chan_misdn_log(1, bc->port, " --> CCBSDeactivate: InvokeID:%d\n",
3108  fac->u.CCBSDeactivate.InvokeID);
3109  switch (fac->u.CCBSDeactivate.ComponentType) {
3110  case FacComponent_Invoke:
3111  chan_misdn_log(1, bc->port, " --> Invoke: CCBSReference:%d\n",
3112  fac->u.CCBSDeactivate.Component.Invoke.CCBSReference);
3113  break;
3114  case FacComponent_Result:
3115  chan_misdn_log(1, bc->port, " --> Result\n");
3116  break;
3117  default:
3118  break;
3119  }
3120  break;
3121  case Fac_CCBSErase:
3122  chan_misdn_log(1, bc->port, " --> CCBSErase: InvokeID:%d, CCBSReference:%d RecallMode:%d, Reason:%d\n",
3123  fac->u.CCBSErase.InvokeID, fac->u.CCBSErase.CCBSReference,
3124  fac->u.CCBSErase.RecallMode, fac->u.CCBSErase.Reason);
3125  chan_misdn_log(1, bc->port, " --> AddressOfB\n");
3126  print_facility_Address(2, &fac->u.CCBSErase.AddressOfB, bc);
3127  print_facility_Q931_Bc_Hlc_Llc(1, &fac->u.CCBSErase.Q931ie, bc);
3128  break;
3129  case Fac_CCBSRemoteUserFree:
3130  chan_misdn_log(1, bc->port, " --> CCBSRemoteUserFree: InvokeID:%d, CCBSReference:%d RecallMode:%d\n",
3131  fac->u.CCBSRemoteUserFree.InvokeID, fac->u.CCBSRemoteUserFree.CCBSReference,
3132  fac->u.CCBSRemoteUserFree.RecallMode);
3133  chan_misdn_log(1, bc->port, " --> AddressOfB\n");
3134  print_facility_Address(2, &fac->u.CCBSRemoteUserFree.AddressOfB, bc);
3135  print_facility_Q931_Bc_Hlc_Llc(1, &fac->u.CCBSRemoteUserFree.Q931ie, bc);
3136  break;
3137  case Fac_CCBSCall:
3138  chan_misdn_log(1, bc->port, " --> CCBSCall: InvokeID:%d, CCBSReference:%d\n",
3139  fac->u.CCBSCall.InvokeID, fac->u.CCBSCall.CCBSReference);
3140  break;
3141  case Fac_CCBSStatusRequest:
3142  chan_misdn_log(1, bc->port, " --> CCBSStatusRequest: InvokeID:%d\n",
3143  fac->u.CCBSStatusRequest.InvokeID);
3144  switch (fac->u.CCBSStatusRequest.ComponentType) {
3145  case FacComponent_Invoke:
3146  chan_misdn_log(1, bc->port, " --> Invoke: CCBSReference:%d RecallMode:%d\n",
3147  fac->u.CCBSStatusRequest.Component.Invoke.CCBSReference,
3148  fac->u.CCBSStatusRequest.Component.Invoke.RecallMode);
3149  print_facility_Q931_Bc_Hlc_Llc(2, &fac->u.CCBSStatusRequest.Component.Invoke.Q931ie, bc);
3150  break;
3151  case FacComponent_Result:
3152  chan_misdn_log(1, bc->port, " --> Result: Free:%d\n",
3153  fac->u.CCBSStatusRequest.Component.Result.Free);
3154  break;
3155  default:
3156  break;
3157  }
3158  break;
3159  case Fac_CCBSBFree:
3160  chan_misdn_log(1, bc->port, " --> CCBSBFree: InvokeID:%d, CCBSReference:%d RecallMode:%d\n",
3161  fac->u.CCBSBFree.InvokeID, fac->u.CCBSBFree.CCBSReference,
3162  fac->u.CCBSBFree.RecallMode);
3163  chan_misdn_log(1, bc->port, " --> AddressOfB\n");
3164  print_facility_Address(2, &fac->u.CCBSBFree.AddressOfB, bc);
3165  print_facility_Q931_Bc_Hlc_Llc(1, &fac->u.CCBSBFree.Q931ie, bc);
3166  break;
3167  case Fac_EraseCallLinkageID:
3168  chan_misdn_log(1, bc->port, " --> EraseCallLinkageID: InvokeID:%d, LinkageID:%d\n",
3169  fac->u.EraseCallLinkageID.InvokeID, fac->u.EraseCallLinkageID.CallLinkageID);
3170  break;
3171  case Fac_CCBSStopAlerting:
3172  chan_misdn_log(1, bc->port, " --> CCBSStopAlerting: InvokeID:%d, CCBSReference:%d\n",
3173  fac->u.CCBSStopAlerting.InvokeID, fac->u.CCBSStopAlerting.CCBSReference);
3174  break;
3175  case Fac_CCBSRequest:
3176  chan_misdn_log(1, bc->port, " --> CCBSRequest: InvokeID:%d\n",
3177  fac->u.CCBSRequest.InvokeID);
3178  switch (fac->u.CCBSRequest.ComponentType) {
3179  case FacComponent_Invoke:
3180  chan_misdn_log(1, bc->port, " --> Invoke: LinkageID:%d\n",
3181  fac->u.CCBSRequest.Component.Invoke.CallLinkageID);
3182  break;
3183  case FacComponent_Result:
3184  chan_misdn_log(1, bc->port, " --> Result: CCBSReference:%d RecallMode:%d\n",
3185  fac->u.CCBSRequest.Component.Result.CCBSReference,
3186  fac->u.CCBSRequest.Component.Result.RecallMode);
3187  break;
3188  default:
3189  break;
3190  }
3191  break;
3192  case Fac_CCBSInterrogate:
3193  chan_misdn_log(1, bc->port, " --> CCBSInterrogate: InvokeID:%d\n",
3194  fac->u.CCBSInterrogate.InvokeID);
3195  switch (fac->u.CCBSInterrogate.ComponentType) {
3196  case FacComponent_Invoke:
3197  chan_misdn_log(1, bc->port, " --> Invoke\n");
3198  if (fac->u.CCBSInterrogate.Component.Invoke.CCBSReferencePresent) {
3199  chan_misdn_log(1, bc->port, " --> CCBSReference:%d\n",
3200  fac->u.CCBSInterrogate.Component.Invoke.CCBSReference);
3201  }
3202  if (fac->u.CCBSInterrogate.Component.Invoke.AParty.LengthOfNumber) {
3203  chan_misdn_log(1, bc->port, " --> AParty\n");
3204  print_facility_PartyNumber(3, &fac->u.CCBSInterrogate.Component.Invoke.AParty, bc);
3205  }
3206  break;
3207  case FacComponent_Result:
3208  chan_misdn_log(1, bc->port, " --> Result: RecallMode:%d\n",
3209  fac->u.CCBSInterrogate.Component.Result.RecallMode);
3210  if (fac->u.CCBSInterrogate.Component.Result.NumRecords) {
3211  for (Index = 0; Index < fac->u.CCBSInterrogate.Component.Result.NumRecords; ++Index) {
3212  chan_misdn_log(1, bc->port, " --> CallDetails[%d]:\n", Index);
3213  print_facility_CallInformation(3, &fac->u.CCBSInterrogate.Component.Result.CallDetails[Index], bc);
3214  }
3215  }
3216  break;
3217  default:
3218  break;
3219  }
3220  break;
3221  case Fac_CCNRRequest:
3222  chan_misdn_log(1, bc->port, " --> CCNRRequest: InvokeID:%d\n",
3223  fac->u.CCNRRequest.InvokeID);
3224  switch (fac->u.CCNRRequest.ComponentType) {
3225  case FacComponent_Invoke:
3226  chan_misdn_log(1, bc->port, " --> Invoke: LinkageID:%d\n",
3227  fac->u.CCNRRequest.Component.Invoke.CallLinkageID);
3228  break;
3229  case FacComponent_Result:
3230  chan_misdn_log(1, bc->port, " --> Result: CCBSReference:%d RecallMode:%d\n",
3231  fac->u.CCNRRequest.Component.Result.CCBSReference,
3232  fac->u.CCNRRequest.Component.Result.RecallMode);
3233  break;
3234  default:
3235  break;
3236  }
3237  break;
3238  case Fac_CCNRInterrogate:
3239  chan_misdn_log(1, bc->port, " --> CCNRInterrogate: InvokeID:%d\n",
3240  fac->u.CCNRInterrogate.InvokeID);
3241  switch (fac->u.CCNRInterrogate.ComponentType) {
3242  case FacComponent_Invoke:
3243  chan_misdn_log(1, bc->port, " --> Invoke\n");
3244  if (fac->u.CCNRInterrogate.Component.Invoke.CCBSReferencePresent) {
3245  chan_misdn_log(1, bc->port, " --> CCBSReference:%d\n",
3246  fac->u.CCNRInterrogate.Component.Invoke.CCBSReference);
3247  }
3248  if (fac->u.CCNRInterrogate.Component.Invoke.AParty.LengthOfNumber) {
3249  chan_misdn_log(1, bc->port, " --> AParty\n");
3250  print_facility_PartyNumber(3, &fac->u.CCNRInterrogate.Component.Invoke.AParty, bc);
3251  }
3252  break;
3253  case FacComponent_Result:
3254  chan_misdn_log(1, bc->port, " --> Result: RecallMode:%d\n",
3255  fac->u.CCNRInterrogate.Component.Result.RecallMode);
3256  if (fac->u.CCNRInterrogate.Component.Result.NumRecords) {
3257  for (Index = 0; Index < fac->u.CCNRInterrogate.Component.Result.NumRecords; ++Index) {
3258  chan_misdn_log(1, bc->port, " --> CallDetails[%d]:\n", Index);
3259  print_facility_CallInformation(3, &fac->u.CCNRInterrogate.Component.Result.CallDetails[Index], bc);
3260  }
3261  }
3262  break;
3263  default:
3264  break;
3265  }
3266  break;
3267  case Fac_CCBS_T_Call:
3268  chan_misdn_log(1, bc->port, " --> CCBS_T_Call: InvokeID:%d\n",
3269  fac->u.CCBS_T_Call.InvokeID);
3270  break;
3271  case Fac_CCBS_T_Suspend:
3272  chan_misdn_log(1, bc->port, " --> CCBS_T_Suspend: InvokeID:%d\n",
3273  fac->u.CCBS_T_Suspend.InvokeID);
3274  break;
3275  case Fac_CCBS_T_Resume:
3276  chan_misdn_log(1, bc->port, " --> CCBS_T_Resume: InvokeID:%d\n",
3277  fac->u.CCBS_T_Resume.InvokeID);
3278  break;
3279  case Fac_CCBS_T_RemoteUserFree:
3280  chan_misdn_log(1, bc->port, " --> CCBS_T_RemoteUserFree: InvokeID:%d\n",
3281  fac->u.CCBS_T_RemoteUserFree.InvokeID);
3282  break;
3283  case Fac_CCBS_T_Available:
3284  chan_misdn_log(1, bc->port, " --> CCBS_T_Available: InvokeID:%d\n",
3285  fac->u.CCBS_T_Available.InvokeID);
3286  break;
3287  case Fac_CCBS_T_Request:
3288  chan_misdn_log(1, bc->port, " --> CCBS_T_Request: InvokeID:%d\n",
3289  fac->u.CCBS_T_Request.InvokeID);
3290  switch (fac->u.CCBS_T_Request.ComponentType) {
3291  case FacComponent_Invoke:
3292  chan_misdn_log(1, bc->port, " --> Invoke\n");
3293  chan_misdn_log(1, bc->port, " --> DestinationAddress:\n");
3294  print_facility_Address(3, &fac->u.CCBS_T_Request.Component.Invoke.Destination, bc);
3295  print_facility_Q931_Bc_Hlc_Llc(2, &fac->u.CCBS_T_Request.Component.Invoke.Q931ie, bc);
3296  if (fac->u.CCBS_T_Request.Component.Invoke.RetentionSupported) {
3297  chan_misdn_log(1, bc->port, " --> RetentionSupported:1\n");
3298  }
3299  if (fac->u.CCBS_T_Request.Component.Invoke.PresentationAllowedIndicatorPresent) {
3300  chan_misdn_log(1, bc->port, " --> PresentationAllowed:%d\n",
3301  fac->u.CCBS_T_Request.Component.Invoke.PresentationAllowedIndicator);
3302  }
3303  if (fac->u.CCBS_T_Request.Component.Invoke.Originating.Party.LengthOfNumber) {
3304  chan_misdn_log(1, bc->port, " --> OriginatingAddress:\n");
3305  print_facility_Address(3, &fac->u.CCBS_T_Request.Component.Invoke.Originating, bc);
3306  }
3307  break;
3308  case FacComponent_Result:
3309  chan_misdn_log(1, bc->port, " --> Result: RetentionSupported:%d\n",
3310  fac->u.CCBS_T_Request.Component.Result.RetentionSupported);
3311  break;
3312  default:
3313  break;
3314  }
3315  break;
3316  case Fac_CCNR_T_Request:
3317  chan_misdn_log(1, bc->port, " --> CCNR_T_Request: InvokeID:%d\n",
3318  fac->u.CCNR_T_Request.InvokeID);
3319  switch (fac->u.CCNR_T_Request.ComponentType) {
3320  case FacComponent_Invoke:
3321  chan_misdn_log(1, bc->port, " --> Invoke\n");
3322  chan_misdn_log(1, bc->port, " --> DestinationAddress:\n");
3323  print_facility_Address(3, &fac->u.CCNR_T_Request.Component.Invoke.Destination, bc);
3324  print_facility_Q931_Bc_Hlc_Llc(2, &fac->u.CCNR_T_Request.Component.Invoke.Q931ie, bc);
3325  if (fac->u.CCNR_T_Request.Component.Invoke.RetentionSupported) {
3326  chan_misdn_log(1, bc->port, " --> RetentionSupported:1\n");
3327  }
3328  if (fac->u.CCNR_T_Request.Component.Invoke.PresentationAllowedIndicatorPresent) {
3329  chan_misdn_log(1, bc->port, " --> PresentationAllowed:%d\n",
3330  fac->u.CCNR_T_Request.Component.Invoke.PresentationAllowedIndicator);
3331  }
3332  if (fac->u.CCNR_T_Request.Component.Invoke.Originating.Party.LengthOfNumber) {
3333  chan_misdn_log(1, bc->port, " --> OriginatingAddress:\n");
3334  print_facility_Address(3, &fac->u.CCNR_T_Request.Component.Invoke.Originating, bc);
3335  }
3336  break;
3337  case FacComponent_Result:
3338  chan_misdn_log(1, bc->port, " --> Result: RetentionSupported:%d\n",
3339  fac->u.CCNR_T_Request.Component.Result.RetentionSupported);
3340  break;
3341  default:
3342  break;
3343  }
3344  break;
3345 #endif /* defined(AST_MISDN_ENHANCEMENTS) */
3346  case Fac_None:
3347  /* No facility so print nothing */
3348  break;
3349  default:
3350  chan_misdn_log(1, bc->port, " --> unknown facility\n");
3351  break;
3352  }
3353 }
static void chan_misdn_log(int level, int port, char *tmpl,...)
Definition: chan_misdn.c:12768
int port
Logical Layer 1 port associated with this B channel.
Definition: isdn_lib.h:370

◆ process_ast_dsp()

static struct ast_frame * process_ast_dsp ( struct chan_list tmp,
struct ast_frame frame 
)
static

Definition at line 7318 of file chan_misdn.c.

References chan_list::ast, ast_async_goto(), ast_channel_caller(), ast_channel_context(), ast_channel_exten(), ast_channel_macrocontext(), ast_channel_name(), ast_debug, chan_list::ast_dsp, ast_dsp_process(), ast_exists_extension(), AST_FRAME_DTMF, ast_log, ast_verb, chan_list::bc, BUFFERSIZE, chan_misdn_log(), context, chan_list::dsp, misdn_bchannel::ec_enable, chan_list::faxdetect, chan_list::faxhandled, ast_frame::frametype, ast_frame_subclass::integer, isdn_lib_stop_dtmf(), isdn_lib_update_ec(), isdn_lib_update_rxgain(), isdn_lib_update_txgain(), LOG_NOTICE, LOG_WARNING, MISDN_CFG_FAXDETECT_CONTEXT, misdn_cfg_get(), NULL, pbx_builtin_setvar_helper(), misdn_bchannel::port, misdn_bchannel::rxgain, S_COR, S_OR, ast_frame::subclass, and misdn_bchannel::txgain.

Referenced by misdn_read().

7319 {
7320  struct ast_frame *f;
7321 
7322  if (tmp->dsp) {
7323  f = ast_dsp_process(tmp->ast, tmp->dsp, frame);
7324  } else {
7325  chan_misdn_log(0, tmp->bc->port, "No DSP-Path found\n");
7326  return NULL;
7327  }
7328 
7329  if (!f || (f->frametype != AST_FRAME_DTMF)) {
7330  return f;
7331  }
7332 
7333  ast_debug(1, "Detected inband DTMF digit: %c\n", f->subclass.integer);
7334 
7335  if (tmp->faxdetect && (f->subclass.integer == 'f')) {
7336  /* Fax tone -- Handle and return NULL */
7337  if (!tmp->faxhandled) {
7338  struct ast_channel *ast = tmp->ast;
7339  tmp->faxhandled++;
7340  chan_misdn_log(0, tmp->bc->port, "Fax detected, preparing %s for fax transfer.\n", ast_channel_name(ast));
7341  tmp->bc->rxgain = 0;
7342  isdn_lib_update_rxgain(tmp->bc);
7343  tmp->bc->txgain = 0;
7344  isdn_lib_update_txgain(tmp->bc);
7345 #ifdef MISDN_1_2
7346  *tmp->bc->pipeline = 0;
7347 #else
7348  tmp->bc->ec_enable = 0;
7349 #endif
7350  isdn_lib_update_ec(tmp->bc);
7351  isdn_lib_stop_dtmf(tmp->bc);
7352  switch (tmp->faxdetect) {
7353  case 1:
7354  if (strcmp(ast_channel_exten(ast), "fax")) {
7355  const char *context;
7356  char context_tmp[BUFFERSIZE];
7357  misdn_cfg_get(tmp->bc->port, MISDN_CFG_FAXDETECT_CONTEXT, &context_tmp, sizeof(context_tmp));
7358  context = S_OR(context_tmp, S_OR(ast_channel_macrocontext(ast), ast_channel_context(ast)));
7359  if (ast_exists_extension(ast, context, "fax", 1,
7360  S_COR(ast_channel_caller(ast)->id.number.valid, ast_channel_caller(ast)->id.number.str, NULL))) {
7361  ast_verb(3, "Redirecting %s to fax extension (context:%s)\n", ast_channel_name(ast), context);
7362  /* Save the DID/DNIS when we transfer the fax call to a "fax" extension */
7363  pbx_builtin_setvar_helper(ast,"FAXEXTEN",ast_channel_exten(ast));
7364  if (ast_async_goto(ast, context, "fax", 1)) {
7365  ast_log(LOG_WARNING, "Failed to async goto '%s' into fax of '%s'\n", ast_channel_name(ast), context);
7366  }
7367  } else {
7368  ast_log(LOG_NOTICE, "Fax detected but no fax extension, context:%s exten:%s\n", context, ast_channel_exten(ast));
7369  }
7370  } else {
7371  ast_debug(1, "Already in a fax extension, not redirecting\n");
7372  }
7373  break;
7374  case 2:
7375  ast_verb(3, "Not redirecting %s to fax extension, nojump is set.\n", ast_channel_name(ast));
7376  break;
7377  default:
7378  break;
7379  }
7380  } else {
7381  ast_debug(1, "Fax already handled\n");
7382  }
7383  }
7384 
7385  if (tmp->ast_dsp && (f->subclass.integer != 'f')) {
7386  chan_misdn_log(2, tmp->bc->port, " --> * SEND: DTMF (AST_DSP) :%c\n", f->subclass.integer);
7387  }
7388 
7389  return f;
7390 }
int ast_dsp
TRUE if we will use the Asterisk DSP to detect DTMF/Fax.
Definition: chan_misdn.c:484
struct ast_party_caller * ast_channel_caller(struct ast_channel *chan)
static void chan_misdn_log(int level, int port, char *tmpl,...)
Definition: chan_misdn.c:12768
struct ast_frame * ast_dsp_process(struct ast_channel *chan, struct ast_dsp *dsp, struct ast_frame *inf)
Return AST_FRAME_NULL frames when there is silence, AST_FRAME_BUSY on busies, and call progress...
Definition: dsp.c:1494
Main Channel structure associated with a channel.
int faxdetect
Fax detection option. (0:no 1:yes 2:yes+nojump)
Definition: chan_misdn.c:461
struct ast_dsp * dsp
Allocated DSP controller.
Definition: chan_misdn.c:510
int txgain
Tx gain setting (range -8 to 8)
Definition: isdn_lib.h:708
int ec_enable
TRUE if the echo cancellor is enabled.
Definition: isdn_lib.h:688
#define LOG_WARNING
Definition: logger.h:274
#define NULL
Definition: resample.c:96
#define AST_FRAME_DTMF
struct ast_channel * ast
Associated Asterisk channel structure.
Definition: chan_misdn.c:515
void isdn_lib_update_rxgain(struct misdn_bchannel *bc)
Definition: isdn_lib.c:4440
#define ast_verb(level,...)
Definition: logger.h:463
struct ast_frame_subclass subclass
void isdn_lib_update_txgain(struct misdn_bchannel *bc)
Definition: isdn_lib.c:4445
void isdn_lib_update_ec(struct misdn_bchannel *bc)
Definition: isdn_lib.c:4450
Number structure.
Definition: app_followme.c:154
#define BUFFERSIZE
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
void misdn_cfg_get(int port, enum misdn_cfg_elements elem, void *buf, int bufsize)
Definition: misdn_config.c:569
#define S_COR(a, b, c)
returns the equivalent of logic or for strings, with an additional boolean check: second one if not e...
Definition: strings.h:85
int rxgain
Rx gain setting (range -8 to 8)
Definition: isdn_lib.h:714
int ast_exists_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Determine whether an extension exists.
Definition: pbx.c:4179
const char * ast_channel_exten(const struct ast_channel *chan)
int port
Logical Layer 1 port associated with this B channel.
Definition: isdn_lib.h:370
#define LOG_NOTICE
Definition: logger.h:263
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name...
int faxhandled
TRUE if a fax has been detected.
Definition: chan_misdn.c:478
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:79
const char * ast_channel_name(const struct ast_channel *chan)
int ast_async_goto(struct ast_channel *chan, const char *context, const char *exten, int priority)
Set the channel to next execute the specified dialplan location.
Definition: pbx.c:7011
void isdn_lib_stop_dtmf(struct misdn_bchannel *bc)
Definition: isdn_lib.c:4462
Data structure associated with a single frame of data.
const char * ast_channel_context(const struct ast_channel *chan)
enum ast_frame_type frametype
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:116
const char * ast_channel_macrocontext(const struct ast_channel *chan)
struct misdn_bchannel * bc
Associated B channel structure.
Definition: chan_misdn.c:520

◆ read_config()

static int read_config ( struct chan_list ch)
static

Definition at line 5922 of file chan_misdn.c.

References chan_list::allowed_bearers, misdn_bchannel::AOCDtype, chan_list::ast, ast_callerid_parse(), ast_channel_callgroup_set(), ast_channel_context_set(), ast_channel_exten_set(), ast_channel_lock, ast_channel_named_callgroups_set(), ast_channel_named_pickupgroups_set(), ast_channel_pickupgroup_set(), ast_channel_unlock, ast_copy_string(), chan_list::ast_dsp, ast_dsp_new(), ast_dsp_set_features(), ast_free, ast_log, ast_mutex_init, ast_print_group(), ast_print_namedgroups(), ast_str_create, ast_str_reset(), ast_strlen_zero, bc, chan_list::bc, buf, buf2, BUFFERSIZE, misdn_bchannel::caller, misdn_bchannel::capability, chan_misdn_log(), cid_name, cid_num, config_jitterbuffer(), 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, 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, 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_NAMEDCALLGROUP, MISDN_CFG_NAMEDPICKUPGROUP, 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, NULL, 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, misdn_bchannel::port, misdn_bchannel::rxgain, misdn_bchannel::send_dtmf, misdn_bchannel::te_choose_channel, misdn_bchannel::txgain, and update_ec_config().

Referenced by cb_events(), and misdn_request().

5923 {
5924  struct ast_channel *ast;
5925  struct misdn_bchannel *bc;
5926  int port;
5927  int hdlc = 0;
5928  char lang[BUFFERSIZE + 1];
5929  char faxdetect[BUFFERSIZE + 1];
5930  char buf[256];
5931  char buf2[256];
5932  ast_group_t pg;
5933  ast_group_t cg;
5934  struct ast_namedgroups *npg;
5935  struct ast_namedgroups *ncg;
5936  struct ast_str *tmp_str;
5937 
5938  if (!ch) {
5939  ast_log(LOG_WARNING, "Cannot configure without chanlist\n");
5940  return -1;
5941  }
5942 
5943  ast = ch->ast;
5944  bc = ch->bc;
5945  if (! ast || ! bc) {
5946  ast_log(LOG_WARNING, "Cannot configure without ast || bc\n");
5947  return -1;
5948  }
5949 
5950  port = bc->port;
5951  chan_misdn_log(1, port, "read_config: Getting Config\n");
5952 
5953  misdn_cfg_get(port, MISDN_CFG_LANGUAGE, lang, sizeof(lang));
5954  ast_channel_lock(ast);
5955  ast_channel_language_set(ast, lang);
5956  ast_channel_unlock(ast);
5957 
5959 
5960  misdn_cfg_get(port, MISDN_CFG_TXGAIN, &bc->txgain, sizeof(bc->txgain));
5961  misdn_cfg_get(port, MISDN_CFG_RXGAIN, &bc->rxgain, sizeof(bc->rxgain));
5962 
5964 
5965  misdn_cfg_get(port, MISDN_CFG_SENDDTMF, &bc->send_dtmf, sizeof(bc->send_dtmf));
5966 
5967  misdn_cfg_get(port, MISDN_CFG_ASTDTMF, &ch->ast_dsp, sizeof(int));
5968  if (ch->ast_dsp) {
5969  ch->ignore_dtmf = 1;
5970  }
5971 
5973  misdn_cfg_get(port, MISDN_CFG_NTTIMEOUT, &ch->nttimeout, sizeof(ch->nttimeout));
5974 
5976 
5978 
5980 
5981  misdn_cfg_get(port, MISDN_CFG_FAXDETECT, faxdetect, sizeof(faxdetect));
5982 
5983  misdn_cfg_get(port, MISDN_CFG_HDLC, &hdlc, sizeof(hdlc));
5984  if (hdlc) {
5985  switch (bc->capability) {
5988  chan_misdn_log(1, bc->port, " --> CONF HDLC\n");
5989  bc->hdlc = 1;
5990  break;
5991  }
5992 
5993  }
5994  /*Initialize new Jitterbuffer*/
5995  misdn_cfg_get(port, MISDN_CFG_JITTERBUFFER, &ch->jb_len, sizeof(ch->jb_len));
5997 
5998  config_jitterbuffer(ch);
5999 
6000  misdn_cfg_get(bc->port, MISDN_CFG_CONTEXT, ch->context, sizeof(ch->context));
6001 
6002  ast_channel_lock(ast);
6003  ast_channel_context_set(ast, ch->context);
6004  ast_channel_unlock(ast);
6005 
6006 #ifdef MISDN_1_2
6007  update_pipeline_config(bc);
6008 #else
6009  update_ec_config(bc);
6010 #endif
6011 
6013 
6017 
6018  misdn_cfg_get(port, MISDN_CFG_PICKUPGROUP, &pg, sizeof(pg));
6019  misdn_cfg_get(port, MISDN_CFG_CALLGROUP, &cg, sizeof(cg));
6020  chan_misdn_log(5, port, " --> * CallGrp:%s PickupGrp:%s\n", ast_print_group(buf, sizeof(buf), cg), ast_print_group(buf2, sizeof(buf2), pg));
6021  ast_channel_lock(ast);
6022  ast_channel_pickupgroup_set(ast, pg);
6023  ast_channel_callgroup_set(ast, cg);
6024  ast_channel_unlock(ast);
6025 
6026  misdn_cfg_get(port, MISDN_CFG_NAMEDPICKUPGROUP, &npg, sizeof(npg));
6027  misdn_cfg_get(port, MISDN_CFG_NAMEDCALLGROUP, &ncg, sizeof(ncg));
6028 
6029  tmp_str = ast_str_create(1024);
6030  if (tmp_str) {
6031  chan_misdn_log(5, port, " --> * NamedCallGrp:%s\n", ast_print_namedgroups(&tmp_str, ncg));
6032  ast_str_reset(tmp_str);
6033  chan_misdn_log(5, port, " --> * NamedPickupGrp:%s\n", ast_print_namedgroups(&tmp_str, npg));
6034  ast_free(tmp_str);
6035  }
6036 
6037  ast_channel_lock(ast);
6040  ast_channel_unlock(ast);
6041 
6042  if (ch->originator == ORG_AST) {
6043  char callerid[BUFFERSIZE + 1];
6044 
6045  /* ORIGINATOR Asterisk (outgoing call) */
6046 
6048 
6049  if (strstr(faxdetect, "outgoing") || strstr(faxdetect, "both")) {
6050  ch->faxdetect = strstr(faxdetect, "nojump") ? 2 : 1;
6051  }
6052 
6053  misdn_cfg_get(port, MISDN_CFG_CALLERID, callerid, sizeof(callerid));
6054  if (!ast_strlen_zero(callerid)) {
6055  char *cid_name = NULL;
6056  char *cid_num = NULL;
6057 
6058  ast_callerid_parse(callerid, &cid_name, &cid_num);
6059  if (cid_name) {
6060  ast_copy_string(bc->caller.name, cid_name, sizeof(bc->caller.name));
6061  } else {
6062  bc->caller.name[0] = '\0';
6063  }
6064  if (cid_num) {
6065  ast_copy_string(bc->caller.number, cid_num, sizeof(bc->caller.number));
6066  } else {
6067  bc->caller.number[0] = '\0';
6068  }
6069  chan_misdn_log(1, port, " --> * Setting caller to \"%s\" <%s>\n", bc->caller.name, bc->caller.number);
6070  }
6071 
6074  debug_numtype(port, bc->dialed.number_type, "TON");
6075 
6076  ch->overlap_dial = 0;
6077  } else {
6078  /* ORIGINATOR MISDN (incoming call) */
6079 
6080  if (strstr(faxdetect, "incoming") || strstr(faxdetect, "both")) {
6081  ch->faxdetect = (strstr(faxdetect, "nojump")) ? 2 : 1;
6082  }
6083 
6084  /* Add configured prefix to caller.number */
6086 
6087  if (ast_strlen_zero(bc->dialed.number) && !ast_strlen_zero(bc->keypad)) {
6088  ast_copy_string(bc->dialed.number, bc->keypad, sizeof(bc->dialed.number));
6089  }
6090 
6091  /* Add configured prefix to dialed.number */
6093 
6094  ast_channel_lock(ast);
6096  ast_channel_unlock(ast);
6097 
6100  } /* ORIG MISDN END */
6101 
6103  if (!ast_strlen_zero(bc->incoming_cid_tag)) {
6104  chan_misdn_log(1, port, " --> * Setting incoming caller id tag to \"%s\"\n", bc->incoming_cid_tag);
6105  }
6106  ch->overlap_dial_task = -1;
6107 
6108  if (ch->faxdetect || ch->ast_dsp) {
6110  if (!ch->dsp) {
6111  ch->dsp = ast_dsp_new();
6112  }
6113  if (ch->dsp) {
6115  }
6116  }
6117 
6118  /* AOCD initialization */
6119  bc->AOCDtype = Fac_None;
6120 
6121  return 0;
6122 }
int ast_dsp
TRUE if we will use the Asterisk DSP to detect DTMF/Fax.
Definition: chan_misdn.c:484
static void chan_misdn_log(int level, int port, char *tmpl,...)
Definition: chan_misdn.c:12768
unsigned long long ast_group_t
Definition: channel.h:214
char keypad[MISDN_MAX_KEYPAD_LEN]
Q.931 Keypad Facility IE contents.
Definition: isdn_lib.h:647
void ast_channel_pickupgroup_set(struct ast_channel *chan, ast_group_t value)
int display_setup
Put a display ie in the SETUP message.
Definition: isdn_lib.h:585
#define ast_channel_lock(chan)
Definition: channel.h:2945
Main Channel structure associated with a channel.
int jb_len
Jitterbuffer length.
Definition: chan_misdn.c:490
int faxdetect
Fax detection option. (0:no 1:yes 2:yes+nojump)
Definition: chan_misdn.c:461
void debug_numtype(int port, int numtype, char *type)
Definition: chan_misdn.c:5853
char number[MISDN_MAX_NUMBER_LEN]
Phone number (Address)
Definition: isdn_lib.h:298
struct ast_dsp * dsp
Allocated DSP controller.
Definition: chan_misdn.c:510
int txgain
Tx gain setting (range -8 to 8)
Definition: isdn_lib.h:708
enum FacFunction AOCDtype
Definition: isdn_lib.h:515
int ignore_dtmf
TRUE if DTMF digits are to be passed inband only.
Definition: chan_misdn.c:438
#define bc
#define DSP_FEATURE_DIGIT_DETECT
Definition: dsp.h:28
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define LOG_WARNING
Definition: logger.h:274
char incoming_cid_tag[MISDN_MAX_NAME_LEN]
Incoming Caller ID string tag for special purpose.
Definition: isdn_lib.h:348
int faxdetect_timeout
Number of seconds to detect a Fax machine when detection enabled.
Definition: chan_misdn.c:468
struct ast_dsp * ast_dsp_new(void)
Allocates a new dsp, assumes 8khz for internal sample rate.
Definition: dsp.c:1745
int hdlc
TRUE if call made in digital HDLC mode.
Definition: isdn_lib.h:635
int jb_upper_threshold
Jitterbuffer upper threshold.
Definition: chan_misdn.c:496
B channel control structure.
Definition: isdn_lib.h:324
int outgoing_colp
Select what to do with outgoing COLP information.
Definition: isdn_lib.h:594
void ast_channel_callgroup_set(struct ast_channel *chan, ast_group_t value)
static void config_jitterbuffer(struct chan_list *ch)
Definition: chan_misdn.c:5817
void ast_channel_named_pickupgroups_set(struct ast_channel *chan, struct ast_namedgroups *value)
static struct ast_threadstorage buf2
int capability
SETUP message bearer capability field code value.
Definition: isdn_lib.h:609
#define NULL
Definition: resample.c:96
char context[AST_MAX_CONTEXT]
Incoming call dialplan context identifier.
Definition: chan_misdn.c:553
char mohinterpret[MAX_MUSICCLASS]
The configured music-on-hold class to use for this call.
Definition: chan_misdn.c:559
struct ast_channel * ast
Associated Asterisk channel structure.
Definition: chan_misdn.c:515
static char cid_num[AST_MAX_EXTENSION]
Definition: chan_mgcp.c:164
char * ast_print_group(char *buf, int buflen, ast_group_t group)
Print call and pickup groups into buffer.
Definition: channel.c:8133
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define BUFFERSIZE
#define ast_log
Definition: astobj2.c:42
char number[MISDN_MAX_NUMBER_LEN]
Dialed/Called Phone Number (Address)
Definition: isdn_lib.h:266
void misdn_cfg_get(int port, enum misdn_cfg_elements elem, void *buf, int bufsize)
Definition: misdn_config.c:569
int overlap_dial_task
Overlap dialing timeout Task ID. -1 if not running.
Definition: chan_misdn.c:593
enum mISDN_NUMBER_TYPE number_type
Type-of-number in ISDN terms for the number.
Definition: isdn_lib.h:285
#define DSP_FEATURE_FAX_DETECT
Definition: dsp.h:29
int display_connected
Put a display ie in the CONNECT message.
Definition: isdn_lib.h:573
struct misdn_party_id caller
Originating/Caller ID information struct.
Definition: isdn_lib.h:343
char name[MISDN_MAX_NAME_LEN]
Subscriber Name.
Definition: isdn_lib.h:295
int rxgain
Rx gain setting (range -8 to 8)
Definition: isdn_lib.h:714
int far_alerting
TRUE if we must do the ringback tones.
Definition: chan_misdn.c:570
char allowed_bearers[BUFFERSIZE+1]
The "allowed_bearers" string read in from /etc/asterisk/misdn.conf.
Definition: chan_misdn.c:381
int originator
Who originally created this channel. ORG_AST or ORG_MISDN.
Definition: chan_misdn.c:407
enum mISDN_NUMBER_TYPE number_type
Type-of-number in ISDN terms for the dialed/called number.
Definition: isdn_lib.h:260
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
static void misdn_add_number_prefix(int port, enum mISDN_NUMBER_TYPE number_type, char *number, size_t size)
Definition: chan_misdn.c:3424
void ast_channel_named_callgroups_set(struct ast_channel *chan, struct ast_namedgroups *value)
int send_dtmf
TRUE if we should produce DTMF tones ourselves.
Definition: isdn_lib.h:457
int incoming_early_audio
TRUE if you want to send Tone Indications to an incoming ISDN channel on a TE Port.
Definition: chan_misdn.c:432
int port
Logical Layer 1 port associated with this B channel.
Definition: isdn_lib.h:370
struct misdn_party_dialing dialed
Dialed/Called information struct.
Definition: isdn_lib.h:337
ast_mutex_t overlap_tv_lock
overlap_tv access lock.
Definition: chan_misdn.c:598
#define ast_channel_unlock(chan)
Definition: channel.h:2946
void ast_dsp_set_features(struct ast_dsp *dsp, int features)
Select feature set.
Definition: dsp.c:1755
#define ast_free(a)
Definition: astmm.h:182
static int update_ec_config(struct misdn_bchannel *bc)
Definition: chan_misdn.c:5903
static char cid_name[AST_MAX_EXTENSION]
Definition: chan_mgcp.c:165
void ast_channel_exten_set(struct ast_channel *chan, const char *value)
void ast_str_reset(struct ast_str *buf)
Reset the content of a dynamic string. Useful before a series of ast_str_append.
Definition: strings.h:653
int need_more_infos
TRUE if we send SETUP_ACKNOWLEDGE on incoming calls anyway (instead of PROCEEDING).
Definition: isdn_lib.h:465
void ast_channel_context_set(struct ast_channel *chan, const char *value)
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
#define ORG_AST
Definition: chan_misdn.c:343
#define ast_mutex_init(pmutex)
Definition: lock.h:184
int te_choose_channel
TRUE if the TE side should choose the B channel to use.
Definition: isdn_lib.h:444
struct misdn_bchannel * bc
Associated B channel structure.
Definition: chan_misdn.c:520
char * ast_print_namedgroups(struct ast_str **buf, struct ast_namedgroups *groups)
Print named call groups and named pickup groups.
Definition: channel.c:8158
int overlap_dial
Enables overlap dialing for the set amount of seconds. (0 = Disabled)
Definition: chan_misdn.c:588
int noautorespond_on_setup
TRUE of we are not to respond immediately to a SETUP message. Check the dialplan first.
Definition: chan_misdn.c:413
enum mISDN_NUMBER_PLAN number_plan
Type-of-number numbering plan.
Definition: isdn_lib.h:263
#define ast_str_create(init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:620
int early_bconnect
TRUE if the call progress indicators can indicate an inband audio message for the user to listen to...
Definition: isdn_lib.h:449
int ast_callerid_parse(char *instr, char **name, char **location)
Destructively parse inbuf into name and location (or number)
Definition: callerid.c:1008
int nttimeout
TRUE if NT should disconnect an overlap dialing call when a timeout occurs.
Definition: chan_misdn.c:576

◆ release_chan()

static void release_chan ( struct chan_list ch,
struct misdn_bchannel bc 
)
static

Definition at line 8495 of file chan_misdn.c.

References chan_list::ast, ast_channel_caller(), ast_channel_context(), ast_channel_exten(), ast_channel_trylock, ast_channel_unlock, ast_mutex_lock, ast_mutex_unlock, ast_setstate(), AST_STATE_DOWN, AST_STATE_RESERVED, chan_list_unref, chan_misdn_log(), cl_dequeue_chan(), DEADLOCK_AVOIDANCE, misdn_bchannel::l3_id, MISDN_ASTERISK_TECH_PVT, MISDN_ASTERISK_TECH_PVT_SET, MISDN_CLEANING, name, NULL, ORG_AST, chan_list::originator, misdn_bchannel::pid, misdn_bchannel::port, S_COR, and chan_list::state.

Referenced by cb_events(), and misdn_hangup().

8496 {
8497  struct ast_channel *ast;
8498 
8499  chan_misdn_log(5, bc->port, "release_chan: bc with pid:%d l3id: %x\n", bc->pid, bc->l3_id);
8500 
8502  for (;;) {
8503  ast = ch->ast;
8504  if (!ast || !ast_channel_trylock(ast)) {
8505  break;
8506  }
8508  }
8509  if (!cl_dequeue_chan(ch)) {
8510  /* Someone already released it. */
8511  if (ast) {
8512  ast_channel_unlock(ast);
8513  }
8515  return;
8516  }
8517  ch->state = MISDN_CLEANING;
8518  ch->ast = NULL;
8519  if (ast) {
8520  struct chan_list *ast_ch;
8521 
8522  ast_ch = MISDN_ASTERISK_TECH_PVT(ast);
8524  chan_misdn_log(1, bc->port,
8525  "* RELEASING CHANNEL pid:%d context:%s dialed:%s caller:\"%s\" <%s>\n",
8526  bc->pid,
8527  ast_channel_context(ast),
8528  ast_channel_exten(ast),
8529  S_COR(ast_channel_caller(ast)->id.name.valid, ast_channel_caller(ast)->id.name.str, ""),
8530  S_COR(ast_channel_caller(ast)->id.number.valid, ast_channel_caller(ast)->id.number.str, ""));
8531 
8532  if (ast_channel_state(ast) != AST_STATE_RESERVED) {
8533  chan_misdn_log(3, bc->port, " --> Setting AST State to down\n");
8535  }
8536  ast_channel_unlock(ast);
8537  if (ast_ch) {
8538  chan_list_unref(ast_ch, "Release ast_channel reference.");
8539  }
8540  }
8541 
8542  if (ch->originator == ORG_AST) {
8543  --misdn_out_calls[bc->port];
8544  } else {
8545  --misdn_in_calls[bc->port];
8546  }
8547 
8549 }
struct ast_party_caller * ast_channel_caller(struct ast_channel *chan)
static void chan_misdn_log(int level, int port, char *tmpl,...)
Definition: chan_misdn.c:12768
Main Channel structure associated with a channel.
#define DEADLOCK_AVOIDANCE(lock)
Definition: lock.h:374
static int cl_dequeue_chan(struct chan_list *chan)
Definition: chan_misdn.c:8398
ast_channel_state
ast_channel states
Definition: channelstate.h:35
#define MISDN_ASTERISK_TECH_PVT(ast)
Definition: chan_misdn.c:683
#define ast_mutex_lock(a)
Definition: lock.h:187
#define NULL
Definition: resample.c:96
struct ast_channel * ast
Associated Asterisk channel structure.
Definition: chan_misdn.c:515
Number structure.
Definition: app_followme.c:154
static ast_mutex_t release_lock
Definition: chan_misdn.c:323
#define S_COR(a, b, c)
returns the equivalent of logic or for strings, with an additional boolean check: second one if not e...
Definition: strings.h:85
enum misdn_chan_state state
State of the channel.
Definition: chan_misdn.c:386
const char * ast_channel_exten(const struct ast_channel *chan)
#define MISDN_ASTERISK_TECH_PVT_SET(ast, value)
Definition: chan_misdn.c:684
int pid
B channel process ID (1-5000)
Definition: isdn_lib.h:402
int originator
Who originally created this channel. ORG_AST or ORG_MISDN.
Definition: chan_misdn.c:407
int port
Logical Layer 1 port associated with this B channel.
Definition: isdn_lib.h:370
#define ast_channel_unlock(chan)
Definition: channel.h:2946
static const char name[]
Definition: cdr_mysql.c:74
Channel call record structure.
Definition: chan_misdn.c:377
static int * misdn_out_calls
Definition: chan_misdn.c:699
int ast_setstate(struct ast_channel *chan, enum ast_channel_state)
Change the state of a channel.
Definition: channel.c:7486
#define ORG_AST
Definition: chan_misdn.c:343
const char * ast_channel_context(const struct ast_channel *chan)
static int * misdn_in_calls
Definition: chan_misdn.c:698
#define ast_channel_trylock(chan)
Definition: channel.h:2947
#define chan_list_unref(obj, debug)
Definition: chan_misdn.c:372
int l3_id
Layer 3 process ID.
Definition: isdn_lib.h:399
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ release_chan_early()

static void release_chan_early ( struct chan_list ch)
static

Definition at line 8561 of file chan_misdn.c.

References 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_ASTERISK_TECH_PVT_SET, MISDN_CLEANING, MISDN_HOLD_IDLE, NULL, ORG_AST, chan_list::originator, hold_info::port, hold_info::state, and chan_list::state.

Referenced by misdn_hangup().

8562 {
8563  struct ast_channel *ast;
8564 
8566  for (;;) {
8567  ast = ch->ast;
8568  if (!ast || !ast_channel_trylock(ast)) {
8569  break;
8570  }
8572  }
8573  if (!cl_dequeue_chan(ch)) {
8574  /* Someone already released it. */
8575  if (ast) {
8576  ast_channel_unlock(ast);
8577  }
8579  return;
8580  }
8581  ch->state = MISDN_CLEANING;
8582  ch->ast = NULL;
8583  if (ast) {
8584  struct chan_list *ast_ch;
8585 
8586  ast_ch = MISDN_ASTERISK_TECH_PVT(ast);
8588 
8589  if (ast_channel_state(ast) != AST_STATE_RESERVED) {
8591  }
8592  ast_channel_unlock(ast);
8593  if (ast_ch) {
8594  chan_list_unref(ast_ch, "Release ast_channel reference.");
8595  }
8596  }
8597 
8598  if (ch->hold.state != MISDN_HOLD_IDLE) {
8599  if (ch->originator == ORG_AST) {
8600  --misdn_out_calls[ch->hold.port];
8601  } else {
8602  --misdn_in_calls[ch->hold.port];
8603  }
8604  }
8605 
8607 }
Main Channel structure associated with a channel.
#define DEADLOCK_AVOIDANCE(lock)
Definition: lock.h:374
static int cl_dequeue_chan(struct chan_list *chan)
Definition: chan_misdn.c:8398
struct hold_info hold
HELD channel call information.
Definition: chan_misdn.c:535
ast_channel_state
ast_channel states
Definition: channelstate.h:35
#define MISDN_ASTERISK_TECH_PVT(ast)
Definition: chan_misdn.c:683
#define ast_mutex_lock(a)
Definition: lock.h:187
#define NULL
Definition: resample.c:96
struct ast_channel * ast
Associated Asterisk channel structure.
Definition: chan_misdn.c:515
static ast_mutex_t release_lock
Definition: chan_misdn.c:323
enum misdn_chan_state state
State of the channel.
Definition: chan_misdn.c:386
#define MISDN_ASTERISK_TECH_PVT_SET(ast, value)
Definition: chan_misdn.c:684
int port
Logical port the channel call record is HELD on because the B channel is no longer associated...
Definition: chan_misdn.c:362
int originator
Who originally created this channel. ORG_AST or ORG_MISDN.
Definition: chan_misdn.c:407
#define ast_channel_unlock(chan)
Definition: channel.h:2946
Channel call record structure.
Definition: chan_misdn.c:377
static int * misdn_out_calls
Definition: chan_misdn.c:699
enum misdn_hold_state state
Call HOLD state.
Definition: chan_misdn.c:357
int ast_setstate(struct ast_channel *chan, enum ast_channel_state)
Change the state of a channel.
Definition: channel.c:7486
#define ORG_AST
Definition: chan_misdn.c:343
static int * misdn_in_calls
Definition: chan_misdn.c:698
#define ast_channel_trylock(chan)
Definition: channel.h:2947
#define chan_list_unref(obj, debug)
Definition: chan_misdn.c:372
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ reload()

static int reload ( void  )
static

◆ reload_config()

static void reload_config ( void  )
static

Definition at line 4123 of file chan_misdn.c.

References ast_log, free_robin_list(), g_config_initialized, global_tracefile, LOG_WARNING, max_ports, misdn_cfg_get(), misdn_cfg_reload(), misdn_cfg_update_ptp(), MISDN_GEN_DEBUG, and MISDN_GEN_TRACEFILE.

Referenced by handle_cli_misdn_reload(), and reload().

4124 {
4125  int i, cfg_debug;
4126 
4127  if (!g_config_initialized) {
4128  ast_log(LOG_WARNING, "chan_misdn is not initialized properly, still reloading ?\n");
4129  return ;
4130  }
4131 
4132  free_robin_list();
4133  misdn_cfg_reload();
4136  misdn_cfg_get(0, MISDN_GEN_DEBUG, &cfg_debug, sizeof(cfg_debug));
4137 
4138  for (i = 0; i <= max_ports; i++) {
4139  misdn_debug[i] = cfg_debug;
4140  misdn_debug_only[i] = 0;
4141  }
4142 }
#define LOG_WARNING
Definition: logger.h:274
void misdn_cfg_reload(void)
static int * misdn_debug_only
Definition: chan_misdn.c:695
#define ast_log
Definition: astobj2.c:42
void misdn_cfg_get(int port, enum misdn_cfg_elements elem, void *buf, int bufsize)
Definition: misdn_config.c:569
static int max_ports
Definition: chan_misdn.c:696
static char global_tracefile[BUFFERSIZE+1]
Definition: chan_misdn.c:127
void misdn_cfg_update_ptp(void)
static void free_robin_list(void)
Definition: chan_misdn.c:629
static int * misdn_debug
Definition: chan_misdn.c:694
static int g_config_initialized
Definition: chan_misdn.c:129

◆ send_cause2ast()

static int send_cause2ast ( struct ast_channel ast,
struct misdn_bchannel bc,
struct chan_list ch 
)
static
Return values
-1if can hangup after calling.
0if cannot hangup after calling.

Definition at line 8725 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_channel_hangupcause_set(), AST_CONTROL_BUSY, ast_queue_control(), misdn_bchannel::cause, chan_misdn_log(), MISDN_BUSY, chan_list::need_busy, misdn_bchannel::pid, misdn_bchannel::port, and chan_list::state.

Referenced by hangup_chan().

8726 {
8727  int can_hangup;
8728 
8729  if (!ast) {
8730  chan_misdn_log(1, 0, "send_cause2ast: No Ast\n");
8731  return 0;
8732  }
8733  if (!bc) {
8734  chan_misdn_log(1, 0, "send_cause2ast: No BC\n");
8735  return 0;
8736  }
8737  if (!ch) {
8738  chan_misdn_log(1, 0, "send_cause2ast: No Ch\n");
8739  return 0;
8740  }
8741 
8743 
8744  can_hangup = -1;
8745  switch (bc->cause) {
8746  case AST_CAUSE_UNALLOCATED:
8749  case 4: /* Send special information tone */
8752  /* Congestion Cases */
8753  /*
8754  * Not Queueing the Congestion anymore, since we want to hear
8755  * the inband message
8756  *
8757  chan_misdn_log(1, bc ? bc->port : 0, " --> * SEND: Queue Congestion pid:%d\n", bc ? bc->pid : -1);
8758  ch->state = MISDN_BUSY;
8759 
8760  ast_queue_control(ast, AST_CONTROL_CONGESTION);
8761  */
8762  break;
8763 
8765  case AST_CAUSE_USER_BUSY:
8766  ch->state = MISDN_BUSY;
8767 
8768  if (!ch->need_busy) {
8769  chan_misdn_log(1, bc ? bc->port : 0, "Queued busy already\n");
8770  break;
8771  }
8772  ch->need_busy = 0;
8773 
8774  chan_misdn_log(1, bc ? bc->port : 0, " --> * SEND: Queue Busy pid:%d\n", bc ? bc->pid : -1);
8776 
8777  /* The BUSY is likely to cause a hangup or the user needs to hear it. */
8778  can_hangup = 0;
8779  break;
8780  }
8781  return can_hangup;
8782 }
int need_busy
TRUE if we could send an AST_CONTROL_BUSY if needed.
Definition: chan_misdn.c:402
static void chan_misdn_log(int level, int port, char *tmpl,...)
Definition: chan_misdn.c:12768
int ast_queue_control(struct ast_channel *chan, enum ast_control_frame_type control)
Queue a control frame without payload.
Definition: channel.c:1231
#define AST_CAUSE_UNALLOCATED
Definition: causes.h:97
void ast_channel_hangupcause_set(struct ast_channel *chan, int value)
#define AST_CAUSE_NO_ROUTE_TRANSIT_NET
Definition: causes.h:98
enum misdn_chan_state state
State of the channel.
Definition: chan_misdn.c:386
#define AST_CAUSE_DESTINATION_OUT_OF_ORDER
Definition: causes.h:114
int pid
B channel process ID (1-5000)
Definition: isdn_lib.h:402
int port
Logical Layer 1 port associated with this B channel.
Definition: isdn_lib.h:370
#define AST_CAUSE_NUMBER_CHANGED
Definition: causes.h:111
#define AST_CAUSE_NO_ROUTE_DESTINATION
Definition: causes.h:99
#define AST_CAUSE_USER_BUSY
Definition: causes.h:106
int cause
Q.931 Cause for disconnection code (received)
Definition: isdn_lib.h:671
#define AST_CAUSE_CALL_REJECTED
Definition: causes.h:110

◆ send_digit_to_chan()

static void send_digit_to_chan ( struct chan_list cl,
char  digit 
)
static

Definition at line 3681 of file chan_misdn.c.

References chan_list::ast, ast_channel_name(), ast_debug, and ast_playtones_start().

Referenced by handle_cli_misdn_send_digit(), and misdn_digit_end().

3682 {
3683  static const char * const dtmf_tones[] = {
3684 /* *INDENT-OFF* */
3685  "!941+1336/100,!0/100", /* 0 */
3686  "!697+1209/100,!0/100", /* 1 */
3687  "!697+1336/100,!0/100", /* 2 */
3688  "!697+1477/100,!0/100", /* 3 */
3689  "!770+1209/100,!0/100", /* 4 */
3690  "!770+1336/100,!0/100", /* 5 */
3691  "!770+1477/100,!0/100", /* 6 */
3692  "!852+1209/100,!0/100", /* 7 */
3693  "!852+1336/100,!0/100", /* 8 */
3694  "!852+1477/100,!0/100", /* 9 */
3695  "!697+1633/100,!0/100", /* A */
3696  "!770+1633/100,!0/100", /* B */
3697  "!852+1633/100,!0/100", /* C */
3698  "!941+1633/100,!0/100", /* D */
3699  "!941+1209/100,!0/100", /* * */
3700  "!941+1477/100,!0/100", /* # */
3701 /* *INDENT-ON* */
3702  };
3703  struct ast_channel *chan = cl->ast;
3704 
3705  if (digit >= '0' && digit <='9') {
3706  ast_playtones_start(chan, 0, dtmf_tones[digit - '0'], 0);
3707  } else if (digit >= 'A' && digit <= 'D') {
3708  ast_playtones_start(chan, 0, dtmf_tones[digit - 'A' + 10], 0);
3709  } else if (digit == '*') {
3710  ast_playtones_start(chan, 0, dtmf_tones[14], 0);
3711  } else if (digit == '#') {
3712  ast_playtones_start(chan, 0, dtmf_tones[15], 0);
3713  } else {
3714  /* not handled */
3715  ast_debug(1, "Unable to handle DTMF tone '%c' for '%s'\n", digit, ast_channel_name(chan));
3716  }
3717 }
char digit
Main Channel structure associated with a channel.
struct ast_channel * ast
Associated Asterisk channel structure.
Definition: chan_misdn.c:515
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
const char * ast_channel_name(const struct ast_channel *chan)
int ast_playtones_start(struct ast_channel *chan, int vol, const char *tonelist, int interruptible)
Start playing a list of tones on a channel.
Definition: indications.c:302

◆ show_config_description()

static void show_config_description ( int  fd,
enum misdn_cfg_elements  elem 
)
inlinestatic

Definition at line 3962 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, term_color(), and tmp().

Referenced by handle_cli_misdn_show_config().

3963 {
3964  char section[BUFFERSIZE];
3965  char name[BUFFERSIZE];
3966  char desc[BUFFERSIZE];
3967  char def[BUFFERSIZE];
3968  char tmp[BUFFERSIZE];
3969 
3970  misdn_cfg_get_name(elem, tmp, sizeof(tmp));
3971  term_color(name, tmp, COLOR_BRWHITE, 0, sizeof(tmp));
3972  misdn_cfg_get_desc(elem, desc, sizeof(desc), def, sizeof(def));
3973 
3974  if (elem < MISDN_CFG_LAST) {
3975  term_color(section, "PORTS SECTION", COLOR_YELLOW, 0, sizeof(section));
3976  } else {
3977  term_color(section, "GENERAL SECTION", COLOR_YELLOW, 0, sizeof(section));
3978  }
3979 
3980  if (*def) {
3981  ast_cli(fd, "[%s] %s (Default: %s)\n\t%s\n", section, name, def, desc);
3982  } else {
3983  ast_cli(fd, "[%s] %s\n\t%s\n", section, name, desc);
3984  }
3985 }
#define COLOR_YELLOW
Definition: term.h:54
static int tmp()
Definition: bt_open.c:389
static const char desc[]
Definition: cdr_mysql.c:73
#define COLOR_BRWHITE
Definition: term.h:62
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
void misdn_cfg_get_name(enum misdn_cfg_elements elem, void *buf, int bufsize)
Definition: misdn_config.c:655
#define BUFFERSIZE
char * term_color(char *outbuf, const char *inbuf, int fgcolor, int bgcolor, int maxout)
Colorize a specified string by adding terminal color codes.
Definition: term.c:184
void misdn_cfg_get_desc(enum misdn_cfg_elements elem, void *buf, int bufsize, void *buf_default, int bufsize_default)
Definition: misdn_config.c:681
static const char name[]
Definition: cdr_mysql.c:74

◆ sighandler()

static void sighandler ( int  sig)
static

Definition at line 3524 of file chan_misdn.c.

Referenced by misdn_tasks_thread_func().

3525 {
3526 }

◆ start_bc_tones()

static int start_bc_tones ( struct chan_list cl)
static

Definition at line 7764 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().

7765 {
7767  cl->notxtone = 0;
7768  cl->norxtone = 0;
7769  return 0;
7770 }
int norxtone
Definition: chan_misdn.c:415
void misdn_lib_tone_generator_stop(struct misdn_bchannel *bc)
Definition: isdn_lib.c:2276
int notxtone
TRUE if we are not to generate tones (Playtones)
Definition: chan_misdn.c:420
struct misdn_bchannel * bc
Associated B channel structure.
Definition: chan_misdn.c:520

◆ start_pbx()

static void start_pbx ( struct chan_list ch,
struct misdn_bchannel bc,
struct ast_channel chan 
)
static

Definition at line 8875 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().

8876 {
8877  if (pbx_start_chan(ch) < 0) {
8878  hangup_chan(ch, bc);
8879  chan_misdn_log(-1, bc->port, "ast_pbx_start returned <0 in SETUP\n");
8880  if (bc->nt) {
8881  hanguptone_indicate(ch);
8883  } else {
8885  }
8886  }
8887 }
static void chan_misdn_log(int level, int port, char *tmpl,...)
Definition: chan_misdn.c:12768
static void hanguptone_indicate(struct chan_list *cl)
Definition: chan_misdn.c:7738
static int pbx_start_chan(struct chan_list *ch)
Definition: chan_misdn.c:8438
int nt
TRUE if NT side of protocol (TE otherwise)
Definition: isdn_lib.h:364
int port
Logical Layer 1 port associated with this B channel.
Definition: isdn_lib.h:370
static void hangup_chan(struct chan_list *ch, struct misdn_bchannel *bc)
Definition: chan_misdn.c:8447
int misdn_lib_send_event(struct misdn_bchannel *bc, enum event_e event)
Definition: isdn_lib.c:3523

◆ stop_bc_tones()

static int stop_bc_tones ( struct chan_list cl)
static

Definition at line 7772 of file chan_misdn.c.

References chan_list::norxtone, and chan_list::notxtone.

Referenced by cb_events(), misdn_call(), and misdn_hangup().

7773 {
7774  if (!cl) {
7775  return -1;
7776  }
7777 
7778  cl->notxtone = 1;
7779  cl->norxtone = 1;
7780 
7781  return 0;
7782 }
int norxtone
Definition: chan_misdn.c:415
int notxtone
TRUE if we are not to generate tones (Playtones)
Definition: chan_misdn.c:420

◆ stop_indicate()

static int stop_indicate ( struct chan_list cl)
static

Definition at line 7743 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().

7744 {
7745  struct ast_channel *ast = cl->ast;
7746 
7747  if (!ast) {
7748  chan_misdn_log(0, cl->bc->port, "No Ast in stop_indicate\n");
7749  return -1;
7750  }
7751 
7752  chan_misdn_log(3, cl->bc->port, " --> None\n");
7754  ast_playtones_stop(ast);
7755 
7756  if (cl->ts) {
7757  cl->ts = ast_tone_zone_sound_unref(cl->ts);
7758  }
7759 
7760  return 0;
7761 }
static void chan_misdn_log(int level, int port, char *tmpl,...)
Definition: chan_misdn.c:12768
Main Channel structure associated with a channel.
void misdn_lib_tone_generator_stop(struct misdn_bchannel *bc)
Definition: isdn_lib.c:2276
void ast_playtones_stop(struct ast_channel *chan)
Stop playing tones on a channel.
Definition: indications.c:393
struct ast_channel * ast
Associated Asterisk channel structure.
Definition: chan_misdn.c:515
static struct ast_tone_zone_sound * ast_tone_zone_sound_unref(struct ast_tone_zone_sound *ts)
Release a reference to an ast_tone_zone_sound.
Definition: indications.h:227
int port
Logical Layer 1 port associated with this B channel.
Definition: isdn_lib.h:370
struct ast_tone_zone_sound * ts
Tone zone sound used for dialtone generation.
Definition: chan_misdn.c:582
struct misdn_bchannel * bc
Associated B channel structure.
Definition: chan_misdn.c:520

◆ unload_module()

static int unload_module ( void  )
static

TE STUFF END

Definition at line 11262 of file chan_misdn.c.

References ao2_cleanup, ast_channel_unregister(), ast_cli_unregister_multiple(), ast_custom_function_unregister(), ast_free, ast_unregister_application(), ast_verb, ast_channel_tech::capabilities, free_robin_list(), g_config_initialized, misdn_cfg_destroy(), misdn_lib_destroy(), misdn_ports, misdn_tasks_destroy(), and NULL.

Referenced by chan_misdn_log(), and load_module().

11263 {
11264  /* First, take us out of the channel loop */
11265  ast_verb(0, "-- Unregistering mISDN Channel Driver --\n");
11266 
11268 
11269  if (!g_config_initialized) {
11270  return 0;
11271  }
11272 
11274 
11275  /* ast_unregister_application("misdn_crypt"); */
11276  ast_unregister_application("misdn_set_opt");
11277  ast_unregister_application("misdn_facility");
11278  ast_unregister_application("misdn_check_l2l1");
11279 #if defined(AST_MISDN_ENHANCEMENTS)
11280  ast_unregister_application(misdn_command_name);
11281  ast_custom_function_unregister(&misdn_cc_function);
11282 #endif /* defined(AST_MISDN_ENHANCEMENTS) */
11283 
11285 
11286  free_robin_list();
11289 
11295 
11296 #if defined(AST_MISDN_ENHANCEMENTS)
11297  misdn_cc_destroy();
11298 #endif /* defined(AST_MISDN_ENHANCEMENTS) */
11301 
11302  return 0;
11303 }
void misdn_cfg_destroy(void)
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
Definition: clicompat.c:30
void ast_channel_unregister(const struct ast_channel_tech *tech)
Unregister a channel technology.
Definition: channel.c:570
descriptor for a cli entry.
Definition: cli.h:171
static int * misdn_debug_only
Definition: chan_misdn.c:695
void misdn_lib_destroy(void)
Definition: isdn_lib.c:4285
#define NULL
Definition: resample.c:96
int ast_unregister_application(const char *app)
Unregister an application.
Definition: pbx_app.c:392
#define ast_verb(level,...)
Definition: logger.h:463
int ast_custom_function_unregister(struct ast_custom_function *acf)
Unregister a custom function.
static void misdn_tasks_destroy(void)
Definition: chan_misdn.c:3574
static struct ast_cli_entry chan_misdn_clis[]
Definition: chan_misdn.c:5734
static void free_robin_list(void)
Definition: chan_misdn.c:629
static int * misdn_debug
Definition: chan_misdn.c:694
struct ast_format_cap * capabilities
Definition: channel.h:633
static struct ast_channel_tech misdn_tech
Definition: chan_misdn.c:8130
#define ast_free(a)
Definition: astmm.h:182
static int * misdn_ports
Definition: chan_misdn.c:673
static int * misdn_out_calls
Definition: chan_misdn.c:699
static int g_config_initialized
Definition: chan_misdn.c:129
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
static int * misdn_in_calls
Definition: chan_misdn.c:698

◆ update_config()

static void update_config ( struct chan_list ch)
static

Updates caller ID information from config.

Definition at line 5761 of file chan_misdn.c.

References chan_list::ast, ast_channel_connected(), ast_log, ast_to_misdn_pres(), ast_to_misdn_screen(), bc, chan_list::bc, misdn_bchannel::caller, misdn_bchannel::capability, chan_misdn_log(), misdn_bchannel::hdlc, 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(), misdn_bchannel::port, misdn_party_id::presentation, and misdn_party_id::screening.

Referenced by misdn_call().

5762 {
5763  struct ast_channel *ast;
5764  struct misdn_bchannel *bc;
5765  int port;
5766  int hdlc = 0;
5767  int pres;
5768  int screen;
5769 
5770  if (!ch) {
5771  ast_log(LOG_WARNING, "Cannot configure without chanlist\n");
5772  return;
5773  }
5774 
5775  ast = ch->ast;
5776  bc = ch->bc;
5777  if (! ast || ! bc) {
5778  ast_log(LOG_WARNING, "Cannot configure without ast || bc\n");
5779  return;
5780  }
5781 
5782  port = bc->port;
5783 
5784  chan_misdn_log(7, port, "update_config: Getting Config\n");
5785 
5786  misdn_cfg_get(port, MISDN_CFG_HDLC, &hdlc, sizeof(int));
5787  if (hdlc) {
5788  switch (bc->capability) {
5791  chan_misdn_log(1, bc->port, " --> CONF HDLC\n");
5792  bc->hdlc = 1;
5793  break;
5794  }
5795  }
5796 
5797 
5798  misdn_cfg_get(port, MISDN_CFG_PRES, &pres, sizeof(pres));
5799  misdn_cfg_get(port, MISDN_CFG_SCREEN, &screen, sizeof(screen));
5800  chan_misdn_log(2, port, " --> pres: %d screen: %d\n", pres, screen);
5801 
5802  if (pres < 0 || screen < 0) {
5803  chan_misdn_log(2, port, " --> pres: %x\n", ast_channel_connected(ast)->id.number.presentation);
5804 
5805  bc->caller.presentation = ast_to_misdn_pres(ast_channel_connected(ast)->id.number.presentation);
5806  chan_misdn_log(2, port, " --> PRES: %s(%d)\n", misdn_to_str_pres(bc->caller.presentation), bc->caller.presentation);
5807 
5808  bc->caller.screening = ast_to_misdn_screen(ast_channel_connected(ast)->id.number.presentation);
5809  chan_misdn_log(2, port, " --> SCREEN: %s(%d)\n", misdn_to_str_screen(bc->caller.screening), bc->caller.screening);
5810  } else {
5811  bc->caller.screening = screen;
5812  bc->caller.presentation = pres;
5813  }
5814 }
static void chan_misdn_log(int level, int port, char *tmpl,...)
Definition: chan_misdn.c:12768
static int ast_to_misdn_pres(int presentation)
Definition: chan_misdn.c:2145
Main Channel structure associated with a channel.
#define bc
#define LOG_WARNING
Definition: logger.h:274
int hdlc
TRUE if call made in digital HDLC mode.
Definition: isdn_lib.h:635
B channel control structure.
Definition: isdn_lib.h:324
int presentation
Number presentation restriction code 0=Allowed, 1=Restricted, 2=Unavailable.
Definition: isdn_lib.h:277
int capability
SETUP message bearer capability field code value.
Definition: isdn_lib.h:609
static const char * misdn_to_str_pres(int presentation)
Definition: chan_misdn.c:2084
struct ast_channel * ast
Associated Asterisk channel structure.
Definition: chan_misdn.c:515
Number structure.
Definition: app_followme.c:154
#define ast_log
Definition: astobj2.c:42
struct ast_party_connected_line * ast_channel_connected(struct ast_channel *chan)
void misdn_cfg_get(int port, enum misdn_cfg_elements elem, void *buf, int bufsize)
Definition: misdn_config.c:569
static const char * misdn_to_str_screen(int screening)
Definition: chan_misdn.c:2173
struct misdn_party_id caller
Originating/Caller ID information struct.
Definition: isdn_lib.h:343
static int ast_to_misdn_screen(int screening)
Definition: chan_misdn.c:2242
int port
Logical Layer 1 port associated with this B channel.
Definition: isdn_lib.h:370
struct misdn_bchannel * bc
Associated B channel structure.
Definition: chan_misdn.c:520
int screening
Number screening code 0=Unscreened, 1=Passed Screen, 2=Failed Screen, 3=Network Number.
Definition: isdn_lib.h:282

◆ update_ec_config()

static int update_ec_config ( struct misdn_bchannel bc)
static

Definition at line 5903 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().

5904 {
5905  int ec;
5906  int port = bc->port;
5907 
5908  misdn_cfg_get(port, MISDN_CFG_ECHOCANCEL, &ec, sizeof(ec));
5909 
5910  if (ec == 1) {
5911  bc->ec_enable = 1;
5912  } else if (ec > 1) {
5913  bc->ec_enable = 1;
5914  bc->ec_deftaps = ec;
5915  }
5916 
5917  return 0;
5918 }
int ec_enable
TRUE if the echo cancellor is enabled.
Definition: isdn_lib.h:688
void misdn_cfg_get(int port, enum misdn_cfg_elements elem, void *buf, int bufsize)
Definition: misdn_config.c:569
int port
Logical Layer 1 port associated with this B channel.
Definition: isdn_lib.h:370
int ec_deftaps
Number of taps in the echo cancellor when enabled.
Definition: isdn_lib.h:693

◆ update_name()

static void update_name ( struct ast_channel tmp,
int  port,
int  c 
)
static

Definition at line 8150 of file chan_misdn.c.

References ast_change_name(), ast_channel_name(), chan_misdn_log(), misdn_cfg_get_next_port(), and misdn_lib_port_is_pri().

Referenced by cb_events().

8151 {
8152  int chan_offset = 0;
8153  int tmp_port = misdn_cfg_get_next_port(0);
8154  char newname[255];
8155 
8156  for (; tmp_port > 0; tmp_port = misdn_cfg_get_next_port(tmp_port)) {
8157  if (tmp_port == port) {
8158  break;
8159  }
8160  chan_offset += misdn_lib_port_is_pri(tmp_port) ? 30 : 2;
8161  }
8162  if (c < 0) {
8163  c = 0;
8164  }
8165 
8166  snprintf(newname, sizeof(newname), "%s/%d-", misdn_type, chan_offset + c);
8167  if (strncmp(ast_channel_name(tmp), newname, strlen(newname))) {
8168  snprintf(newname, sizeof(newname), "%s/%d-u%d", misdn_type, chan_offset + c, glob_channel++);
8169  ast_change_name(tmp, newname);
8170  chan_misdn_log(3, port, " --> updating channel name to [%s]\n", ast_channel_name(tmp));
8171  }
8172 }
static void chan_misdn_log(int level, int port, char *tmpl,...)
Definition: chan_misdn.c:12768
int misdn_cfg_get_next_port(int port)
Definition: misdn_config.c:929
static struct test_val c
void ast_change_name(struct ast_channel *chan, const char *newname)
Change channel name.
Definition: channel.c:6854
int port
Logical Layer 1 port associated with this B channel.
Definition: isdn_lib.h:370
static int glob_channel
Definition: chan_misdn.c:8148
static const char misdn_type[]
Definition: chan_misdn.c:690
int misdn_lib_port_is_pri(int port)
Definition: isdn_lib.c:53
const char * ast_channel_name(const struct ast_channel *chan)

◆ wait_for_digits()

static void wait_for_digits ( struct chan_list ch,
struct misdn_bchannel bc,
struct ast_channel chan 
)
static

Definition at line 8889 of file chan_misdn.c.

References ast_channel_alloc, ast_channel_dialed(), ast_channel_name(), ast_channel_priority_set(), ast_channel_release(), ast_channel_unlock, ast_free, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log, ast_pbx_start(), AST_STATE_DOWN, ast_strdup, ast_verb, chan_misdn_log(), misdn_bchannel::dialed, dialtone_indicate(), EVENT_FACILITY, EVENT_SETUP_ACKNOWLEDGE, misdn_bchannel::fac_out, LOG_ERROR, LOG_WARNING, misdn_lib_port_is_nt(), misdn_lib_send_event(), misdn_make_dummy(), MISDN_WAITING4DIGS, misdn_bchannel::nt, NULL, misdn_party_dialing::number, ast_party_dialed::number, print_facility(), chan_list::state, and ast_party_dialed::str.

Referenced by cb_events().

8890 {
8891  ch->state = MISDN_WAITING4DIGS;
8893  if (bc->nt && !bc->dialed.number[0]) {
8894  dialtone_indicate(ch);
8895  }
8896 }
char number[MISDN_MAX_NUMBER_LEN]
Dialed/Called Phone Number (Address)
Definition: isdn_lib.h:266
int nt
TRUE if NT side of protocol (TE otherwise)
Definition: isdn_lib.h:364
enum misdn_chan_state state
State of the channel.
Definition: chan_misdn.c:386
struct misdn_party_dialing dialed
Dialed/Called information struct.
Definition: isdn_lib.h:337
static int dialtone_indicate(struct chan_list *cl)
Definition: chan_misdn.c:7707
int misdn_lib_send_event(struct misdn_bchannel *bc, enum event_e event)
Definition: isdn_lib.c:3523

Variable Documentation

◆ __mod_info

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 = "30ef0c93b36035ec78c9cfd712d36d9b" , .support_level = AST_MODULE_SUPPORT_DEPRECATED, .load = load_module, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_CHANNEL_DRIVER, }
static

Definition at line 12838 of file chan_misdn.c.

◆ allowed_bearers_array

const struct allowed_bearers allowed_bearers_array[]
static

Definition at line 2362 of file chan_misdn.c.

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 12838 of file chan_misdn.c.

◆ chan_misdn_clis

struct ast_cli_entry chan_misdn_clis[]
static

Definition at line 5734 of file chan_misdn.c.

◆ cl_te

struct chan_list* cl_te =NULL
static

Global channel call record list head.

Definition at line 704 of file chan_misdn.c.

◆ cl_te_lock

ast_mutex_t cl_te_lock
static

Definition at line 705 of file chan_misdn.c.

◆ g_config_initialized

int g_config_initialized = 0
static

Definition at line 129 of file chan_misdn.c.

Referenced by load_module(), reload_config(), and unload_module().

◆ glob_channel

int glob_channel = 0
static

Definition at line 8148 of file chan_misdn.c.

◆ global_tracefile

char global_tracefile[BUFFERSIZE+1]
static
Note
To use the CCBS/CCNR supplementary service feature and other supplementary services using FACILITY messages requires a modified version of mISDN.
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 127 of file chan_misdn.c.

Referenced by chan_misdn_log(), load_module(), and reload_config().

◆ max_ports

int max_ports
static

Definition at line 696 of file chan_misdn.c.

Referenced by handle_cli_misdn_set_debug(), load_module(), and reload_config().

◆ MAXTICS

int MAXTICS = 8

Definition at line 612 of file chan_misdn.c.

Referenced by handle_cli_misdn_set_tics().

◆ misdn_debug

int* misdn_debug
static

Definition at line 694 of file chan_misdn.c.

◆ misdn_debug_only

int* misdn_debug_only
static

Definition at line 695 of file chan_misdn.c.

◆ misdn_in_calls

int* misdn_in_calls
static

Definition at line 698 of file chan_misdn.c.

◆ misdn_out_calls

int* misdn_out_calls
static

Definition at line 699 of file chan_misdn.c.

◆ misdn_ports

int* misdn_ports
static

Definition at line 673 of file chan_misdn.c.

Referenced by load_module(), and unload_module().

◆ misdn_tasks

struct ast_sched_context* misdn_tasks = NULL
static

the main schedule context for stuff like l1 watcher, overlap dial, ...

Definition at line 670 of file chan_misdn.c.

◆ misdn_tasks_thread

pthread_t misdn_tasks_thread
static

Definition at line 671 of file chan_misdn.c.

Referenced by misdn_tasks_destroy(), misdn_tasks_init(), and misdn_tasks_wakeup().

◆ misdn_tech

struct ast_channel_tech misdn_tech
static

Definition at line 8130 of file chan_misdn.c.

◆ misdn_type

const char misdn_type[] = "mISDN"
static

Definition at line 690 of file chan_misdn.c.

◆ release_lock

ast_mutex_t release_lock
static

Definition at line 323 of file chan_misdn.c.

◆ robin

struct robin_list* robin = NULL
static

Definition at line 626 of file chan_misdn.c.

Referenced by get_robin_position().

◆ state_array

const struct state_struct state_array[]
static

Definition at line 4083 of file chan_misdn.c.

◆ tracing

int tracing = 0
static

Definition at line 692 of file chan_misdn.c.