Wed Apr 6 11:30:05 2011

Asterisk developer's documentation


isdn_lib.c File Reference

Interface to mISDN. More...

#include <syslog.h>
#include <sys/time.h>
#include <mISDNuser/isdn_debug.h>
#include "isdn_lib_intern.h"
#include "isdn_lib.h"
#include "asterisk/causes.h"
#include <mISDNuser/net_l2.h>
#include <mISDNuser/tone.h>
#include <unistd.h>
#include <semaphore.h>
#include <pthread.h>
#include <signal.h>

Go to the source code of this file.

Data Structures

struct  misdn_lib

Defines

#define ARRAY_LEN(a)   (sizeof(a) / sizeof(a[0]))
#define ECHOCAN_OFF   124
#define ECHOCAN_ON   123
#define ISDN_PID_L3_B_USER   0x430000ff
#define ISDN_PID_L4_B_USER   0x440000ff
#define MISDN_DEBUG   0
#define MISDN_DSP
#define MISDN_GEN_SILENCE
#define MISDN_IBUF_SIZE   512
#define RETURN(a, b)   {retval=a; goto b;}
#define TONE_ALERT_CNT   41
#define TONE_ALERT_SILENCE_CNT   200
#define TONE_BUSY_CNT   20
#define TONE_BUSY_SILENCE_CNT   48

Enumerations

enum  global_states { MISDN_INITIALIZING, MISDN_INITIALIZED }

Functions

static void bc_next_state_change (struct misdn_bchannel *bc, enum bchannel_state state)
char * bc_state2str (enum bchannel_state state)
void bc_state_change (struct misdn_bchannel *bc, enum bchannel_state state)
int bchdev_echocancel_activate (struct misdn_bchannel *dev)
void bchdev_echocancel_deactivate (struct misdn_bchannel *dev)
static char * bearer2str (int cap)
static int clean_up_bc (struct misdn_bchannel *bc)
static void clear_l3 (struct misdn_stack *stack)
static msg_t * create_l2msg (int prim, int dinfo, int size)
msg_t * create_l3msg (int prim, int mt, int dinfo, int size, int ntmode)
static int create_process (int midev, struct misdn_bchannel *bc)
static int do_tone (struct misdn_bchannel *bc, int len)
static void dump_chan_list (struct misdn_stack *stack)
void ec_chunk (struct misdn_bchannel *bc, unsigned char *rxchunk, unsigned char *txchunk, int chunk_size)
static void empty_bc (struct misdn_bchannel *bc)
static void empty_chan_in_stack (struct misdn_stack *stack, int channel)
static const char * fac2str (enum FacFunction facility)
static msg_t * fetch_msg (int midev)
static struct misdn_bchannelfind_bc_by_addr (unsigned long addr)
static struct misdn_bchannelfind_bc_by_channel (int port, int channel)
static struct misdn_bchannelfind_bc_by_confid (unsigned long confid)
misdn_bchannelfind_bc_by_l3id (struct misdn_stack *stack, unsigned long l3id)
static struct misdn_bchannelfind_bc_by_masked_l3id (struct misdn_stack *stack, unsigned long l3id, unsigned long mask)
static int find_free_chan_in_stack (struct misdn_stack *stack, struct misdn_bchannel *bc, int channel, int dec)
static struct misdn_stackfind_stack_by_addr (int addr)
static struct misdn_stackfind_stack_by_mgr (manager_t *mgr_nt)
static struct misdn_stackfind_stack_by_port (int port)
static char * flip_buf_bits (char *buf, int len)
misdn_stackget_misdn_stack (void)
void get_show_stack_details (int port, char *buf)
misdn_stackget_stack_by_bc (struct misdn_bchannel *bc)
static int handle_bchan (msg_t *msg)
static int handle_cr (struct misdn_stack *stack, iframe_t *frm)
static int handle_err (msg_t *msg)
static int handle_event (struct misdn_bchannel *bc, enum event_e event, iframe_t *frm)
static int handle_event_nt (void *dat, void *arg)
static int handle_frm (msg_t *msg)
static int handle_frm_nt (msg_t *msg)
static int handle_l1 (msg_t *msg)
static int handle_l2 (msg_t *msg)
static int handle_mgmt (msg_t *msg)
static int handle_timers (msg_t *msg)
static int init_bc (struct misdn_stack *stack, struct misdn_bchannel *bc, int midev, int port, int bidx)
static void init_flip_bits (void)
void isdn_lib_stop_dtmf (struct misdn_bchannel *bc)
void isdn_lib_update_ec (struct misdn_bchannel *bc)
void isdn_lib_update_rxgain (struct misdn_bchannel *bc)
void isdn_lib_update_txgain (struct misdn_bchannel *bc)
void manager_bchannel_activate (struct misdn_bchannel *bc)
void manager_bchannel_cleanup (struct misdn_bchannel *bc)
void manager_bchannel_deactivate (struct misdn_bchannel *bc)
void manager_bchannel_setup (struct misdn_bchannel *bc)
void manager_clean_bc (struct misdn_bchannel *bc)
void manager_ec_disable (struct misdn_bchannel *bc)
void manager_ec_enable (struct misdn_bchannel *bc)
static void manager_event_handler (void *arg)
misdn_bchannelmanager_find_bc_by_pid (int pid)
char * manager_isdn_get_info (enum event_e event)
int manager_isdn_handler (iframe_t *frm, msg_t *msg)
void manager_ph_control (struct misdn_bchannel *bc, int c1, int c2)
void manager_ph_control_block (struct misdn_bchannel *bc, int c1, void *c2, int c2_len)
int misdn_cap_is_speech (int cap)
void misdn_dump_chanlist (void)
int misdn_inband_avail (struct misdn_bchannel *bc)
void misdn_join_conf (struct misdn_bchannel *bc, int conf_id)
void misdn_lib_bridge (struct misdn_bchannel *bc1, struct misdn_bchannel *bc2)
void misdn_lib_destroy (void)
void misdn_lib_echo (struct misdn_bchannel *bc, int onoff)
misdn_bchannelmisdn_lib_find_held_bc (int port, int l3_id)
 Find a held call's B channel record.
misdn_bchannelmisdn_lib_get_free_bc (int port, int channel, int inout, int dec)
static int misdn_lib_get_l1_down (struct misdn_stack *stack)
static int misdn_lib_get_l1_up (struct misdn_stack *stack)
static int misdn_lib_get_l2_down (struct misdn_stack *stack)
int misdn_lib_get_l2_up (struct misdn_stack *stack)
int misdn_lib_get_maxchans (int port)
int misdn_lib_get_port_down (int port)
int misdn_lib_get_port_info (int port)
int misdn_lib_get_port_up (int port)
static int misdn_lib_get_short_status (struct misdn_stack *stack)
int misdn_lib_init (char *portlist, struct misdn_lib_iface *iface, void *user_data)
int misdn_lib_is_port_blocked (int port)
int misdn_lib_is_ptp (int port)
static void misdn_lib_isdn_event_catcher (void *arg)
void misdn_lib_isdn_l1watcher (int port)
void misdn_lib_log_ies (struct misdn_bchannel *bc)
int misdn_lib_maxports_get (void)
void misdn_lib_nt_debug_init (int flags, char *file)
void misdn_lib_nt_keepcalls (int kc)
int misdn_lib_pid_restart (int pid)
int misdn_lib_port_block (int port)
int misdn_lib_port_is_nt (int port)
int misdn_lib_port_is_pri (int port)
int misdn_lib_port_restart (int port)
int misdn_lib_port_unblock (int port)
int misdn_lib_port_up (int port, int check)
void misdn_lib_reinit_nt_stack (int port)
void misdn_lib_release (struct misdn_bchannel *bc)
int misdn_lib_send_event (struct misdn_bchannel *bc, enum event_e event)
int misdn_lib_send_restart (int port, int channel)
void misdn_lib_send_tone (struct misdn_bchannel *bc, enum tone_e tone)
void misdn_lib_setup_bc (struct misdn_bchannel *bc)
void misdn_lib_split_bridge (struct misdn_bchannel *bc1, struct misdn_bchannel *bc2)
void misdn_lib_tone_generator_start (struct misdn_bchannel *bc)
void misdn_lib_tone_generator_stop (struct misdn_bchannel *bc)
int misdn_lib_tx2misdn_frm (struct misdn_bchannel *bc, void *data, int len)
void misdn_make_dummy (struct misdn_bchannel *dummybc, int port, int l3id, int nt, int channel)
static void misdn_send_lock (struct misdn_bchannel *bc)
static void misdn_send_unlock (struct misdn_bchannel *bc)
void misdn_split_conf (struct misdn_bchannel *bc, int conf_id)
void misdn_tx_jitter (struct misdn_bchannel *bc, int len)
static void prepare_bc (struct misdn_bchannel *bc, int channel)
int queue_cleanup_bc (struct misdn_bchannel *bc)
static int release_cr (struct misdn_stack *stack, mISDNuser_head_t *hh)
static int send_msg (int midev, struct misdn_bchannel *bc, msg_t *dmsg)
static int set_chan_in_stack (struct misdn_stack *stack, int channel)
int setup_bc (struct misdn_bchannel *bc)
static void stack_destroy (struct misdn_stack *stack)
void stack_holder_add (struct misdn_stack *stack, struct misdn_bchannel *holder)
misdn_bchannelstack_holder_find (struct misdn_stack *stack, unsigned long l3id)
void stack_holder_remove (struct misdn_stack *stack, struct misdn_bchannel *holder)
static struct misdn_stackstack_init (int midev, int port, int ptp)
void te_lib_destroy (int midev)
static int te_lib_init (void)
static int test_inuse (struct misdn_bchannel *bc)

Variables

enum event_response_e(*) cb_event (enum event_e event, struct misdn_bchannel *bc, void *user_data)
int(*) cb_jb_empty (struct misdn_bchannel *bc, char *buffer, int len)
void(*) cb_log (int level, int port, char *tmpl,...)
static int entity
static char flip_table [256]
static struct misdn_libglob_mgr
static enum global_states global_state = MISDN_INITIALIZING
static sem_t handler_started
isdn_msg msgs_g []
static int mypid = 1
static int new_te_id = 0
static int nt_err_cnt = 0
static char tone_425_flip [TONE_425_SIZE]
static char tone_silence_flip [TONE_SILENCE_SIZE]


Detailed Description

Interface to mISDN.

Author:
Christian Richter <crich@beronet.com>

Definition in file isdn_lib.c.


Define Documentation

#define ARRAY_LEN (  )     (sizeof(a) / sizeof(a[0]))

Definition at line 40 of file isdn_lib.c.

Referenced by __analog_ss_thread(), __ast_channel_alloc_ap(), __ast_cli_generator(), __ast_register_translator(), __init_manager(), __unload_module(), _sip_show_peer(), action_events(), add_publish_event(), add_subscribe_event(), adpcm_sample(), ais_clm_show_members(), ais_err2str(), alarm2str(), alaw_sample(), analog_cidtype_to_str(), analog_sigtype_to_str(), analog_ss_thread(), analog_str_to_cidtype(), analog_str_to_sigtype(), aoc_s_add_entry(), ast_ais_clm_load_module(), ast_ais_clm_unload_module(), ast_ais_evt_load_module(), ast_aoc_add_unit_entry(), ast_aoc_cli_init(), ast_best_codec(), ast_builtins_init(), ast_cause2str(), ast_cc_init(), ast_cel_get_ama_flag_name(), ast_cel_str_to_event_type(), ast_channels_init(), ast_cli_netstats(), ast_codec2str(), ast_codec_choose(), ast_codec_pref_append(), ast_codec_pref_getsize(), ast_codec_pref_prepend(), ast_codec_pref_remove(), ast_codec_pref_setsize(), ast_connected_line_source_describe(), ast_connected_line_source_name(), ast_connected_line_source_parse(), ast_data_init(), ast_describe_caller_presentation(), ast_dsp_prog_reset(), ast_dsp_set_call_progress_zone(), ast_event_check_subscriber(), ast_event_cmp(), ast_event_get_ie_pltype(), ast_event_get_ie_type_name(), ast_event_get_type_name(), ast_event_init(), ast_event_str_to_event_type(), ast_event_str_to_ie_type(), ast_expand_codec_alias(), ast_extension_state2str(), ast_features_init(), ast_file_init(), ast_get_format_list(), ast_getformatbyname(), ast_getformatname(), ast_getformatname_multiple(), ast_http_ftype2mtype(), ast_http_init(), ast_image_init(), ast_indications_init(), ast_logger_register_level(), ast_logger_unregister_level(), ast_named_caller_presentation(), ast_parse_caller_presentation(), ast_party_name_charset_describe(), ast_party_name_charset_parse(), ast_party_name_charset_str(), ast_redirecting_reason_describe(), ast_redirecting_reason_name(), ast_redirecting_reason_parse(), ast_rtp_codecs_payloads_set_rtpmap_type_rate(), ast_rtp_lookup_mime_subtype2(), ast_rtp_lookup_sample_rate2(), ast_security_event_severity_get_name(), ast_str2cause(), ast_str2tos(), ast_str_retrieve_variable(), ast_syslog_facility(), ast_syslog_facility_name(), ast_syslog_priority(), ast_syslog_priority_from_loglevel(), ast_syslog_priority_name(), ast_test_init(), ast_timing_init(), ast_to_misdn_reason(), ast_tos2str(), ast_tps_init(), ast_udptl_init(), ast_utils_init(), ast_xmldoc_printable(), astdb_init(), astobj2_init(), authority_to_str(), autopause2int(), bearer2str(), cache_get_callno_locked(), callerid_read(), callerid_write(), cb_events(), check_blacklist(), clear_l3(), common_exec(), complete_dpreply(), complete_ulimit(), conf_exec(), connectedline_read(), connectedline_write(), convert_attribute_name_from_ldap(), convert_attribute_name_to_ldap(), crypto_init(), data_result_get_color(), destroy_escs(), determine_starting_point(), devstate_cache_cb(), dump_cause(), dump_chan_list(), dump_ies(), dundi_eid_zero(), dundi_ie2str(), dundi_query_read(), empty_chan_in_stack(), event2str(), event_dump_cache(), fac2str(), fill_rxgain(), fill_txgain(), find_alias(), find_cache(), find_free_chan_in_stack(), find_sip_method(), find_subscription_type(), frame_trace_helper(), g722_sample(), g726_sample(), get_esc(), get_folder_by_name(), get_perm(), geteventbyname(), getjustifybyname(), handle_cli_iax2_show_cache(), handle_cli_iax2_show_channels(), handle_cli_iax2_show_stats(), handle_cli_misdn_send_facility(), handle_cli_ulimit(), handle_event(), handle_input(), handle_jack_audio(), handle_logger_set_level(), handle_logger_show_channels(), handle_request_bye(), handle_request_invite(), hook_event_cb(), iax_ie2str(), iax_provflags2str(), iax_showframe(), iax_str2flags(), init_framer(), init_logger(), initialize_escs(), int2strat(), jack_status_to_str(), jb_choose_impl(), load_module(), load_pbx(), main(), make_components(), mbox(), milliwatt_generate(), minivm_accmess_exec(), minivm_greet_exec(), minivm_mwi_exec(), minivm_notify_exec(), minivm_record_exec(), misdn_get_ch_state(), misdn_lib_init(), mute_fragment(), parkandannounce_exec(), parse_naptr(), peers_data_provider_get(), process_echocancel(), process_opcode(), process_returncode(), queue_voice_frame(), redirecting_read(), redirecting_write(), register_config_cli(), resample_frame(), rotate_file(), set_chan_in_stack(), set_queue_result(), sig_pri_start_pri(), sig_pri_stop_pri(), sig_ss7_init_linkset(), sip_reason_code_to_str(), sip_reason_str_to_code(), sip_show_channel(), slin16_sample(), slin8_sample(), str2desc(), str2limit(), strat2int(), strings_to_mask(), subscription_type2str(), type_to_filter_str(), udptl_rx_packet(), ulaw_sample(), unload_module(), update_max_trunk(), xmldoc_get_syntax_type(), xmldoc_has_specialtags(), and xmldoc_parse_specialtags().

#define ECHOCAN_OFF   124

Definition at line 232 of file isdn_lib.c.

Referenced by manager_ec_disable().

#define ECHOCAN_ON   123

Definition at line 231 of file isdn_lib.c.

Referenced by manager_ec_enable().

#define ISDN_PID_L3_B_USER   0x430000ff

Definition at line 250 of file isdn_lib.c.

#define ISDN_PID_L4_B_USER   0x440000ff

Definition at line 251 of file isdn_lib.c.

#define MISDN_DEBUG   0

Definition at line 235 of file isdn_lib.c.

#define MISDN_DSP

#define MISDN_GEN_SILENCE

#define MISDN_IBUF_SIZE   512

Definition at line 254 of file isdn_lib.c.

Referenced by init_bc().

#define RETURN ( a,
 )     {retval=a; goto b;}

Definition at line 3614 of file isdn_lib.c.

Referenced by misdn_lib_send_event().

#define TONE_ALERT_CNT   41

Definition at line 257 of file isdn_lib.c.

#define TONE_ALERT_SILENCE_CNT   200

Definition at line 258 of file isdn_lib.c.

#define TONE_BUSY_CNT   20

Definition at line 260 of file isdn_lib.c.

#define TONE_BUSY_SILENCE_CNT   48

Definition at line 261 of file isdn_lib.c.


Enumeration Type Documentation

enum global_states

Enumerator:
MISDN_INITIALIZING 
MISDN_INITIALIZED 

Definition at line 194 of file isdn_lib.c.

00194                    {
00195    MISDN_INITIALIZING,
00196    MISDN_INITIALIZED
00197 } ;


Function Documentation

static void bc_next_state_change ( struct misdn_bchannel bc,
enum bchannel_state  state 
) [static]

Definition at line 670 of file isdn_lib.c.

References bc_state2str(), cb_log, misdn_bchannel::next_bc_state, and misdn_bchannel::port.

Referenced by misdn_lib_bridge().

00671 {
00672    cb_log(5,bc->port,"BC_NEXT_STATE_CHANGE: from:%s to:%s\n",
00673           bc_state2str(bc->next_bc_state),
00674           bc_state2str(state) );
00675 
00676    bc->next_bc_state=state;
00677 }

char* bc_state2str ( enum bchannel_state  state  ) 

Definition at line 621 of file isdn_lib.c.

References BCHAN_ACTIVATED, BCHAN_ACTIVE, BCHAN_BRIDGE, BCHAN_BRIDGED, BCHAN_CLEAN, BCHAN_CLEAN_REQUEST, BCHAN_CLEANED, BCHAN_EMPTY, BCHAN_ERROR, BCHAN_RELEASE, BCHAN_RELEASED, BCHAN_SETUP, and BCHAN_SETUPED.

Referenced by bc_next_state_change(), bc_state_change(), cb_events(), handle_bchan(), handle_err(), misdn_lib_send_event(), misdn_lib_split_bridge(), misdn_lib_tx2misdn_frm(), print_bc_info(), and setup_bc().

00621                                               {
00622    int i;
00623 
00624    struct bchan_state_s {
00625       char *n;
00626       enum bchannel_state s;
00627    } states[] = {
00628       {"BCHAN_CLEANED", BCHAN_CLEANED },
00629       {"BCHAN_EMPTY", BCHAN_EMPTY},
00630       {"BCHAN_SETUP", BCHAN_SETUP},
00631       {"BCHAN_SETUPED", BCHAN_SETUPED},
00632       {"BCHAN_ACTIVE", BCHAN_ACTIVE},
00633       {"BCHAN_ACTIVATED", BCHAN_ACTIVATED},
00634       {"BCHAN_BRIDGE",  BCHAN_BRIDGE},
00635       {"BCHAN_BRIDGED", BCHAN_BRIDGED},
00636       {"BCHAN_RELEASE", BCHAN_RELEASE},
00637       {"BCHAN_RELEASED", BCHAN_RELEASED},
00638       {"BCHAN_CLEAN", BCHAN_CLEAN},
00639       {"BCHAN_CLEAN_REQUEST", BCHAN_CLEAN_REQUEST},
00640       {"BCHAN_ERROR", BCHAN_ERROR}
00641    };
00642 
00643    for (i=0; i< sizeof(states)/sizeof(struct bchan_state_s); i++)
00644       if ( states[i].s == state)
00645          return states[i].n;
00646 
00647    return "UNKNOWN";
00648 }

void bc_state_change ( struct misdn_bchannel bc,
enum bchannel_state  state 
)

Definition at line 650 of file isdn_lib.c.

References misdn_bchannel::bc_state, bc_state2str(), BCHAN_ACTIVATED, BCHAN_BRIDGED, BCHAN_EMPTY, cb_log, misdn_bchannel::conf_id, misdn_bchannel::l3_id, misdn_join_conf(), misdn_bchannel::next_bc_state, and misdn_bchannel::port.

Referenced by clean_up_bc(), handle_bchan(), handle_frm(), init_bc(), manager_bchannel_deactivate(), misdn_join_conf(), misdn_lib_send_event(), and misdn_split_conf().

00651 {
00652    cb_log(5,bc->port,"BC_STATE_CHANGE: l3id:%x from:%s to:%s\n",
00653       bc->l3_id,
00654           bc_state2str(bc->bc_state),
00655           bc_state2str(state) );
00656 
00657    switch (state) {
00658       case BCHAN_ACTIVATED:
00659          if (bc->next_bc_state ==  BCHAN_BRIDGED) {
00660             misdn_join_conf(bc, bc->conf_id);
00661             bc->next_bc_state = BCHAN_EMPTY;
00662             return;
00663          }
00664       default:
00665          bc->bc_state=state;
00666          break;
00667    }
00668 }

int bchdev_echocancel_activate ( struct misdn_bchannel dev  ) 

void bchdev_echocancel_deactivate ( struct misdn_bchannel dev  ) 

static char* bearer2str ( int  cap  )  [static]

Definition at line 294 of file isdn_lib.c.

References INFO_CAPABILITY_AUDIO_3_1K, INFO_CAPABILITY_DIGITAL_RESTRICTED, INFO_CAPABILITY_DIGITAL_UNRESTRICTED, and INFO_CAPABILITY_SPEECH.

00294                                  {
00295    static char *bearers[]={
00296       "Speech",
00297       "Audio 3.1k",
00298       "Unres Digital",
00299       "Res Digital",
00300       "Unknown Bearer"
00301    };
00302 
00303    switch (cap) {
00304    case INFO_CAPABILITY_SPEECH:
00305       return bearers[0];
00306       break;
00307    case INFO_CAPABILITY_AUDIO_3_1K:
00308       return bearers[1];
00309       break;
00310    case INFO_CAPABILITY_DIGITAL_UNRESTRICTED:
00311       return bearers[2];
00312       break;
00313    case INFO_CAPABILITY_DIGITAL_RESTRICTED:
00314       return bearers[3];
00315       break;
00316    default:
00317       return bearers[4];
00318       break;
00319    }
00320 }

static int clean_up_bc ( struct misdn_bchannel bc  )  [static]

Definition at line 828 of file isdn_lib.c.

References misdn_bchannel::b_stid, misdn_stack::bc, misdn_bchannel::bc_state, bc_state_change(), BCHAN_CLEANED, buff, cb_log, get_stack_by_bc(), misdn_bchannel::layer_id, manager_bchannel_deactivate(), manager_ec_disable(), misdn_stack::midev, misdn_bchannel::pid, misdn_stack::port, and misdn_bchannel::port.

Referenced by clear_l3(), handle_bchan(), handle_cr(), handle_event_nt(), handle_frm(), manager_event_handler(), misdn_lib_release(), misdn_lib_send_event(), misdn_lib_send_restart(), and misdn_lib_setup_bc().

00829 {
00830    int ret=0;
00831    unsigned char buff[32];
00832    struct misdn_stack * stack;
00833 
00834    cb_log(3, bc?bc->port:0, "$$$ CLEANUP CALLED pid:%d\n", bc?bc->pid:-1);
00835 
00836    if (!bc  ) return -1;
00837    stack=get_stack_by_bc(bc);
00838 
00839    if (!stack) return -1;
00840 
00841    switch (bc->bc_state ) {
00842    case BCHAN_CLEANED:
00843       cb_log(5, stack->port, "$$$ Already cleaned up bc with stid :%x\n", bc->b_stid);
00844       return -1;
00845 
00846    default:
00847       break;
00848    }
00849 
00850    cb_log(2, stack->port, "$$$ Cleaning up bc with stid :%x pid:%d\n", bc->b_stid, bc->pid);
00851 
00852    manager_ec_disable(bc);
00853 
00854    manager_bchannel_deactivate(bc);
00855 
00856    mISDN_write_frame(stack->midev, buff, bc->layer_id|FLG_MSG_TARGET|FLG_MSG_DOWN, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
00857 
00858    bc->b_stid = 0;
00859    bc_state_change(bc, BCHAN_CLEANED);
00860 
00861    return ret;
00862 }

static void clear_l3 ( struct misdn_stack stack  )  [static]

Definition at line 866 of file isdn_lib.c.

References ARRAY_LEN, misdn_stack::b_num, misdn_stack::bc, cb_event, clean_up_bc(), empty_bc(), empty_chan_in_stack(), EVENT_CLEANUP, global_state, misdn_bchannel::in_use, MAX_BCHANS, and MISDN_INITIALIZED.

Referenced by handle_mgmt(), and misdn_lib_port_restart().

00867 {
00868    int i;
00869 
00870    if (global_state == MISDN_INITIALIZED) {
00871       for (i = 0; i <= stack->b_num; ++i) {
00872          cb_event(EVENT_CLEANUP, &stack->bc[i], NULL);
00873          empty_bc(&stack->bc[i]);
00874          clean_up_bc(&stack->bc[i]);
00875          empty_chan_in_stack(stack, i + 1);
00876          stack->bc[i].in_use = 0;
00877       }
00878 #if defined(AST_MISDN_ENHANCEMENTS)
00879       for (i = MAX_BCHANS + 1; i < ARRAY_LEN(stack->bc); ++i) {
00880          empty_bc(&stack->bc[i]);
00881          empty_chan_in_stack(stack, i + 1);
00882          stack->bc[i].in_use = 0;
00883       }
00884 #endif   /* defined(AST_MISDN_ENHANCEMENTS) */
00885    }
00886 }

static msg_t* create_l2msg ( int  prim,
int  dinfo,
int  size 
) [static]

Definition at line 353 of file isdn_lib.c.

Referenced by misdn_lib_get_l2_down(), and misdn_lib_get_l2_up().

00354 {
00355    int i = 0;
00356    msg_t *dmsg;
00357 
00358    while(i < 10)
00359    {
00360       dmsg = prep_l3data_msg(prim, dinfo, size, 256, NULL);
00361       if (dmsg)
00362          return(dmsg);
00363 
00364       if (!i)
00365          printf("cannot allocate memory, trying again...\n");
00366       i++;
00367       usleep(300000);
00368    }
00369    printf("cannot allocate memory, system overloaded.\n");
00370    exit(-1);
00371 }

msg_t* create_l3msg ( int  prim,
int  mt,
int  dinfo,
int  size,
int  ntmode 
)

Definition at line 375 of file isdn_lib.c.

Referenced by build_alerting(), build_connect(), build_connect_acknowledge(), build_disconnect(), build_facility(), build_hold(), build_hold_acknowledge(), build_hold_reject(), build_information(), build_notify(), build_proceeding(), build_progress(), build_release(), build_release_complete(), build_restart(), build_resume(), build_resume_acknowledge(), build_resume_reject(), build_retrieve(), build_retrieve_acknowledge(), build_retrieve_reject(), build_setup(), build_setup_acknowledge(), build_status(), build_status_enquiry(), build_suspend(), build_suspend_acknowledge(), build_suspend_reject(), build_timeout(), build_user_information(), and handle_event_nt().

00376 {
00377    int i = 0;
00378    msg_t *dmsg;
00379    Q931_info_t *qi;
00380    iframe_t *frm;
00381 
00382    if (!ntmode)
00383       size = sizeof(Q931_info_t)+2;
00384 
00385    while(i < 10) {
00386       if (ntmode) {
00387          dmsg = prep_l3data_msg(prim, dinfo, size, 256, NULL);
00388          if (dmsg) {
00389             return(dmsg);
00390          }
00391       } else {
00392          dmsg = alloc_msg(size+256+mISDN_HEADER_LEN+DEFAULT_HEADROOM);
00393          if (dmsg)
00394          {
00395             memset(msg_put(dmsg,size+mISDN_HEADER_LEN), 0, size+mISDN_HEADER_LEN);
00396             frm = (iframe_t *)dmsg->data;
00397             frm->prim = prim;
00398             frm->dinfo = dinfo;
00399             qi = (Q931_info_t *)(dmsg->data + mISDN_HEADER_LEN);
00400             qi->type = mt;
00401             return(dmsg);
00402          }
00403       }
00404 
00405       if (!i) printf("cannot allocate memory, trying again...\n");
00406       i++;
00407       usleep(300000);
00408    }
00409    printf("cannot allocate memory, system overloaded.\n");
00410    exit(-1);
00411 }

static int create_process ( int  midev,
struct misdn_bchannel bc 
) [static]

Definition at line 1004 of file isdn_lib.c.

References misdn_stack::bc, cb_log, misdn_bchannel::channel, misdn_bchannel::channel_preselected, find_free_chan_in_stack(), get_stack_by_bc(), misdn_bchannel::l3_id, MAXPROCS, misdn_stack::nt, misdn_stack::port, and misdn_stack::procids.

Referenced by misdn_lib_send_event().

01005 {
01006    iframe_t ncr;
01007    int l3_id;
01008    int proc_id;
01009    struct misdn_stack *stack;
01010 
01011    stack = get_stack_by_bc(bc);
01012    if (stack->nt) {
01013       if (find_free_chan_in_stack(stack, bc, bc->channel_preselected ? bc->channel : 0, 0) < 0) {
01014          return -1;
01015       }
01016       cb_log(4, stack->port, " -->  found channel: %d\n", bc->channel);
01017 
01018       for (proc_id = 0; proc_id < MAXPROCS; ++proc_id) {
01019          if (stack->procids[proc_id] == 0) {
01020             break;
01021          }
01022       }
01023       if (proc_id == MAXPROCS) {
01024          cb_log(0, stack->port, "Couldn't Create New ProcId.\n");
01025          return -1;
01026       }
01027 
01028       stack->procids[proc_id] = 1;
01029 
01030       l3_id = 0xff00 | proc_id;
01031       bc->l3_id = l3_id;
01032       cb_log(3, stack->port, " --> new_l3id %x\n", l3_id);
01033    } else {
01034       if ((stack->pri && stack->ptp) || bc->te_choose_channel) {
01035          /* we know exactly which channels are in use */
01036          if (find_free_chan_in_stack(stack, bc, bc->channel_preselected ? bc->channel : 0, bc->dec) < 0) {
01037             return -1;
01038          }
01039          cb_log(2, stack->port, " -->  found channel: %d\n", bc->channel);
01040       } else {
01041          /* other phones could have made a call also on this port (ptmp) */
01042          bc->channel = 0xff;
01043       }
01044 
01045       /* if we are in te-mode, we need to create a process first */
01046       if (++new_te_id > 0xffff) {
01047          new_te_id = 0x0001;
01048       }
01049 
01050       l3_id = (entity << 16) | new_te_id;
01051       bc->l3_id = l3_id;
01052       cb_log(3, stack->port, "--> new_l3id %x\n", l3_id);
01053 
01054       /* send message */
01055       ncr.prim = CC_NEW_CR | REQUEST;
01056       ncr.addr = (stack->upper_id | FLG_MSG_DOWN);
01057       ncr.dinfo = l3_id;
01058       ncr.len = 0;
01059       mISDN_write(midev, &ncr, mISDN_HEADER_LEN + ncr.len, TIMEOUT_1SEC);
01060    }
01061 
01062    return l3_id;
01063 }

static int do_tone ( struct misdn_bchannel bc,
int  len 
) [static]

Definition at line 2352 of file isdn_lib.c.

References cb_event, EVENT_TONE_GENERATE, misdn_bchannel::generate_tone, glob_mgr, misdn_tx_jitter(), misdn_bchannel::nojitter, misdn_bchannel::tone_cnt, and misdn_lib::user_data.

Referenced by handle_bchan().

02353 {
02354    bc->tone_cnt=len;
02355 
02356    if (bc->generate_tone) {
02357       cb_event(EVENT_TONE_GENERATE, bc, glob_mgr->user_data);
02358 
02359       if ( !bc->nojitter ) {
02360          misdn_tx_jitter(bc,len);
02361       }
02362 
02363       return 1;
02364    }
02365 
02366    return 0;
02367 }

static void dump_chan_list ( struct misdn_stack stack  )  [static]

Definition at line 468 of file isdn_lib.c.

References ARRAY_LEN, misdn_stack::b_num, misdn_stack::bc, cb_log, misdn_stack::channels, misdn_bchannel::in_use, MAX_BCHANS, and misdn_stack::port.

Referenced by empty_chan_in_stack(), handle_cr(), misdn_dump_chanlist(), and set_chan_in_stack().

00469 {
00470    int i;
00471 
00472    for (i = 0; i <= stack->b_num; ++i) {
00473       cb_log(6, stack->port, "Idx:%d stack->cchan:%d in_use:%d Chan:%d\n",
00474          i, stack->channels[i], stack->bc[i].in_use, i + 1);
00475    }
00476 #if defined(AST_MISDN_ENHANCEMENTS)
00477    for (i = MAX_BCHANS + 1; i < ARRAY_LEN(stack->bc); ++i) {
00478       if (stack->bc[i].in_use) {
00479          cb_log(6, stack->port, "Idx:%d stack->cchan:%d REGISTER Chan:%d in_use\n",
00480             i, stack->channels[i], i + 1);
00481       }
00482    }
00483 #endif   /* defined(AST_MISDN_ENHANCEMENTS) */
00484 }

void ec_chunk ( struct misdn_bchannel bc,
unsigned char *  rxchunk,
unsigned char *  txchunk,
int  chunk_size 
)

static void empty_bc ( struct misdn_bchannel bc  )  [static]

Definition at line 690 of file isdn_lib.c.

References misdn_bchannel::active, misdn_bchannel::AOCD_need_export, AST_CAUSE_NORMAL_CLEARING, misdn_bchannel::bframe_len, misdn_bchannel::caller, misdn_bchannel::capability, misdn_bchannel::cause, misdn_bchannel::channel, misdn_bchannel::channel_found, misdn_bchannel::conf_id, misdn_bchannel::connected, misdn_party_redirecting::count, misdn_bchannel::crypt, misdn_bchannel::crypt_key, misdn_bchannel::curprx, misdn_bchannel::curptx, misdn_bchannel::cw, misdn_bchannel::dec, misdn_bchannel::dialed, misdn_bchannel::display, misdn_bchannel::display_connected, misdn_bchannel::display_setup, misdn_bchannel::dummy, misdn_bchannel::early_bconnect, misdn_bchannel::ec_deftaps, misdn_bchannel::ec_enable, EVENT_NOTHING, misdn_bchannel::evq, misdn_bchannel::fac_in, misdn_bchannel::fac_out, misdn_party_redirecting::from, misdn_bchannel::generate_tone, misdn_bchannel::hdlc, INFO_CAPABILITY_SPEECH, INFO_CODEC_ALAW, misdn_bchannel::info_dad, misdn_bchannel::infos_pending, misdn_bchannel::last_used, misdn_bchannel::law, mISDN_NOTIFY_CODE_INVALID, mISDN_REDIRECTING_REASON_UNKNOWN, misdn_bchannel::mode, misdn_party_id::name, misdn_bchannel::need_more_infos, misdn_bchannel::nodsp, misdn_bchannel::nojitter, misdn_bchannel::notify_description_code, misdn_party_dialing::number, misdn_party_id::number, misdn_party_dialing::number_plan, misdn_party_id::number_plan, misdn_party_dialing::number_type, misdn_party_id::number_type, NUMPLAN_ISDN, NUMTYPE_UNKNOWN, misdn_bchannel::orig, misdn_bchannel::out_cause, misdn_bchannel::outgoing_colp, misdn_bchannel::presentation, misdn_party_id::presentation, misdn_bchannel::progress_coding, misdn_bchannel::progress_indicator, misdn_bchannel::progress_location, misdn_bchannel::rate, misdn_party_redirecting::reason, misdn_bchannel::redirecting, misdn_bchannel::restart_channel, misdn_bchannel::rxgain, misdn_bchannel::send_dtmf, misdn_bchannel::sending_complete, misdn_bchannel::set_presentation, misdn_party_dialing::subaddress, misdn_party_id::subaddress, misdn_bchannel::te_choose_channel, misdn_bchannel::time_usec, misdn_party_redirecting::to, misdn_party_redirecting::to_changed, misdn_bchannel::tone_cnt, misdn_bchannel::txgain, misdn_bchannel::urate, misdn_bchannel::user1, misdn_bchannel::uu, and misdn_bchannel::uulen.

Referenced by clear_l3(), handle_cr(), handle_event_nt(), handle_frm(), init_bc(), manager_clean_bc(), misdn_lib_release(), misdn_lib_send_event(), and misdn_lib_send_restart().

00691 {
00692    bc->caller.presentation = 0;  /* allowed */
00693    bc->caller.number_plan = NUMPLAN_ISDN;
00694    bc->caller.number_type = NUMTYPE_UNKNOWN;
00695    bc->caller.name[0] = 0;
00696    bc->caller.number[0] = 0;
00697    bc->caller.subaddress[0] = 0;
00698 
00699    bc->connected.presentation = 0;  /* allowed */
00700    bc->connected.number_plan = NUMPLAN_ISDN;
00701    bc->connected.number_type = NUMTYPE_UNKNOWN;
00702    bc->connected.name[0] = 0;
00703    bc->connected.number[0] = 0;
00704    bc->connected.subaddress[0] = 0;
00705 
00706    bc->redirecting.from.presentation = 0; /* allowed */
00707    bc->redirecting.from.number_plan = NUMPLAN_ISDN;
00708    bc->redirecting.from.number_type = NUMTYPE_UNKNOWN;
00709    bc->redirecting.from.name[0] = 0;
00710    bc->redirecting.from.number[0] = 0;
00711    bc->redirecting.from.subaddress[0] = 0;
00712 
00713    bc->redirecting.to.presentation = 0;   /* allowed */
00714    bc->redirecting.to.number_plan = NUMPLAN_ISDN;
00715    bc->redirecting.to.number_type = NUMTYPE_UNKNOWN;
00716    bc->redirecting.to.name[0] = 0;
00717    bc->redirecting.to.number[0] = 0;
00718    bc->redirecting.to.subaddress[0] = 0;
00719 
00720    bc->redirecting.reason = mISDN_REDIRECTING_REASON_UNKNOWN;
00721    bc->redirecting.count = 0;
00722    bc->redirecting.to_changed = 0;
00723 
00724    bc->dummy=0;
00725 
00726    bc->bframe_len=0;
00727 
00728    bc->cw= 0;
00729 
00730    bc->dec=0;
00731    bc->channel = 0;
00732 
00733    bc->sending_complete = 0;
00734 
00735    bc->restart_channel=0;
00736 
00737    bc->conf_id = 0;
00738 
00739    bc->need_more_infos = 0;
00740 
00741    bc->send_dtmf=0;
00742    bc->nodsp=0;
00743    bc->nojitter=0;
00744 
00745    bc->time_usec=0;
00746 
00747    bc->rxgain=0;
00748    bc->txgain=0;
00749 
00750    bc->crypt=0;
00751    bc->curptx=0; bc->curprx=0;
00752 
00753    bc->crypt_key[0] = 0;
00754 
00755    bc->generate_tone=0;
00756    bc->tone_cnt=0;
00757 
00758    bc->active = 0;
00759 
00760    bc->early_bconnect = 1;
00761 
00762 #ifdef MISDN_1_2
00763    *bc->pipeline = 0;
00764 #else
00765    bc->ec_enable = 0;
00766    bc->ec_deftaps = 128;
00767 #endif
00768 
00769    bc->AOCD_need_export = 0;
00770 
00771    bc->orig=0;
00772 
00773    bc->cause = AST_CAUSE_NORMAL_CLEARING;
00774    bc->out_cause = AST_CAUSE_NORMAL_CLEARING;
00775 
00776    bc->display_connected = 0; /* none */
00777    bc->display_setup = 0;  /* none */
00778 
00779    bc->outgoing_colp = 0;/* pass */
00780 
00781    bc->presentation = 0;   /* allowed */
00782    bc->set_presentation = 0;
00783 
00784    bc->notify_description_code = mISDN_NOTIFY_CODE_INVALID;
00785 
00786    bc->evq=EVENT_NOTHING;
00787 
00788    bc->progress_coding=0;
00789    bc->progress_location=0;
00790    bc->progress_indicator=0;
00791 
00792 #if defined(AST_MISDN_ENHANCEMENTS)
00793    bc->div_leg_3_rx_wanted = 0;
00794    bc->div_leg_3_tx_pending = 0;
00795 #endif   /* defined(AST_MISDN_ENHANCEMENTS) */
00796 
00797 /** Set Default Bearer Caps **/
00798    bc->capability=INFO_CAPABILITY_SPEECH;
00799    bc->law=INFO_CODEC_ALAW;
00800    bc->mode=0;
00801    bc->rate=0x10;
00802    bc->user1=0;
00803    bc->urate=0;
00804 
00805    bc->hdlc=0;
00806 
00807    bc->dialed.number_plan = NUMPLAN_ISDN;
00808    bc->dialed.number_type = NUMTYPE_UNKNOWN;
00809    bc->dialed.number[0] = 0;
00810    bc->dialed.subaddress[0] = 0;
00811 
00812    bc->info_dad[0] = 0;
00813    bc->display[0] = 0;
00814    bc->infos_pending[0] = 0;
00815    bc->uu[0]=0;
00816    bc->uulen=0;
00817 
00818    bc->fac_in.Function = Fac_None;
00819    bc->fac_out.Function = Fac_None;
00820 
00821    bc->te_choose_channel = 0;
00822    bc->channel_found= 0;
00823 
00824    gettimeofday(&bc->last_used, NULL);
00825 }

static void empty_chan_in_stack ( struct misdn_stack stack,
int  channel 
) [static]

Definition at line 609 of file isdn_lib.c.

References ARRAY_LEN, cb_log, misdn_stack::channels, dump_chan_list(), and misdn_stack::port.

Referenced by clear_l3(), handle_cr(), handle_event_nt(), handle_frm(), manager_clean_bc(), misdn_lib_release(), and misdn_lib_send_event().

00610 {
00611    if (channel < 1 || ARRAY_LEN(stack->channels) < channel) {
00612       cb_log(0, stack->port, "empty_chan_in_stack: cannot empty channel %d\n", channel);
00613       return;
00614    }
00615 
00616    cb_log(4, stack->port, "empty_chan_in_stack: %d\n", channel);
00617    stack->channels[channel - 1] = 0;
00618    dump_chan_list(stack);
00619 }

static const char* fac2str ( enum FacFunction  facility  )  [static]

Definition at line 3445 of file isdn_lib.c.

References ARRAY_LEN, and name.

Referenced by misdn_lib_log_ies().

03446 {
03447    static const struct {
03448       enum FacFunction facility;
03449       char *name;
03450    } arr[] = {
03451 /* *INDENT-OFF* */
03452       { Fac_None, "Fac_None" },
03453 #if defined(AST_MISDN_ENHANCEMENTS)
03454       { Fac_ERROR, "Fac_ERROR" },
03455       { Fac_RESULT, "Fac_RESULT" },
03456       { Fac_REJECT, "Fac_REJECT" },
03457 
03458       { Fac_ActivationDiversion, "Fac_ActivationDiversion" },
03459       { Fac_DeactivationDiversion, "Fac_DeactivationDiversion" },
03460       { Fac_ActivationStatusNotificationDiv, "Fac_ActivationStatusNotificationDiv" },
03461       { Fac_DeactivationStatusNotificationDiv, "Fac_DeactivationStatusNotificationDiv" },
03462       { Fac_InterrogationDiversion, "Fac_InterrogationDiversion" },
03463       { Fac_DiversionInformation, "Fac_DiversionInformation" },
03464       { Fac_CallDeflection, "Fac_CallDeflection" },
03465       { Fac_CallRerouteing, "Fac_CallRerouteing" },
03466       { Fac_DivertingLegInformation2, "Fac_DivertingLegInformation2" },
03467       { Fac_InterrogateServedUserNumbers, "Fac_InterrogateServedUserNumbers" },
03468       { Fac_DivertingLegInformation1, "Fac_DivertingLegInformation1" },
03469       { Fac_DivertingLegInformation3, "Fac_DivertingLegInformation3" },
03470 
03471       { Fac_EctExecute, "Fac_EctExecute" },
03472       { Fac_ExplicitEctExecute, "Fac_ExplicitEctExecute" },
03473       { Fac_RequestSubaddress, "Fac_RequestSubaddress" },
03474       { Fac_SubaddressTransfer, "Fac_SubaddressTransfer" },
03475       { Fac_EctLinkIdRequest, "Fac_EctLinkIdRequest" },
03476       { Fac_EctInform, "Fac_EctInform" },
03477       { Fac_EctLoopTest, "Fac_EctLoopTest" },
03478 
03479       { Fac_ChargingRequest, "Fac_ChargingRequest" },
03480       { Fac_AOCSCurrency, "Fac_AOCSCurrency" },
03481       { Fac_AOCSSpecialArr, "Fac_AOCSSpecialArr" },
03482       { Fac_AOCDCurrency, "Fac_AOCDCurrency" },
03483       { Fac_AOCDChargingUnit, "Fac_AOCDChargingUnit" },
03484       { Fac_AOCECurrency, "Fac_AOCECurrency" },
03485       { Fac_AOCEChargingUnit, "Fac_AOCEChargingUnit" },
03486 
03487       { Fac_StatusRequest, "Fac_StatusRequest" },
03488 
03489       { Fac_CallInfoRetain, "Fac_CallInfoRetain" },
03490       { Fac_EraseCallLinkageID, "Fac_EraseCallLinkageID" },
03491       { Fac_CCBSDeactivate, "Fac_CCBSDeactivate" },
03492       { Fac_CCBSErase, "Fac_CCBSErase" },
03493       { Fac_CCBSRemoteUserFree, "Fac_CCBSRemoteUserFree" },
03494       { Fac_CCBSCall, "Fac_CCBSCall" },
03495       { Fac_CCBSStatusRequest, "Fac_CCBSStatusRequest" },
03496       { Fac_CCBSBFree, "Fac_CCBSBFree" },
03497       { Fac_CCBSStopAlerting, "Fac_CCBSStopAlerting" },
03498 
03499       { Fac_CCBSRequest, "Fac_CCBSRequest" },
03500       { Fac_CCBSInterrogate, "Fac_CCBSInterrogate" },
03501 
03502       { Fac_CCNRRequest, "Fac_CCNRRequest" },
03503       { Fac_CCNRInterrogate, "Fac_CCNRInterrogate" },
03504 
03505       { Fac_CCBS_T_Call, "Fac_CCBS_T_Call" },
03506       { Fac_CCBS_T_Suspend, "Fac_CCBS_T_Suspend" },
03507       { Fac_CCBS_T_Resume, "Fac_CCBS_T_Resume" },
03508       { Fac_CCBS_T_RemoteUserFree, "Fac_CCBS_T_RemoteUserFree" },
03509       { Fac_CCBS_T_Available, "Fac_CCBS_T_Available" },
03510 
03511       { Fac_CCBS_T_Request, "Fac_CCBS_T_Request" },
03512 
03513       { Fac_CCNR_T_Request, "Fac_CCNR_T_Request" },
03514 
03515 #else
03516 
03517       { Fac_CFActivate, "Fac_CFActivate" },
03518       { Fac_CFDeactivate, "Fac_CFDeactivate" },
03519       { Fac_CD, "Fac_CD" },
03520 
03521       { Fac_AOCDCurrency, "Fac_AOCDCurrency" },
03522       { Fac_AOCDChargingUnit, "Fac_AOCDChargingUnit" },
03523 #endif   /* defined(AST_MISDN_ENHANCEMENTS) */
03524 /* *INDENT-ON* */
03525    };
03526 
03527    unsigned index;
03528 
03529    for (index = 0; index < ARRAY_LEN(arr); ++index) {
03530       if (arr[index].facility == facility) {
03531          return arr[index].name;
03532       }
03533    }
03534 
03535    return "unknown";
03536 }

static msg_t* fetch_msg ( int  midev  )  [static]

Definition at line 3113 of file isdn_lib.c.

References cb_log, and errno.

Referenced by misdn_lib_isdn_event_catcher().

03114 {
03115    msg_t *msg=alloc_msg(MAX_MSG_SIZE);
03116    int r;
03117 
03118    if (!msg) {
03119       cb_log(0, 0, "fetch_msg: alloc msg failed !!");
03120       return NULL;
03121    }
03122 
03123    AGAIN:
03124       r=mISDN_read(midev,msg->data,MAX_MSG_SIZE, TIMEOUT_10SEC);
03125       msg->len=r;
03126 
03127       if (r==0) {
03128          free_msg(msg); /* danger, cause usually freeing in main_loop */
03129          cb_log(6,0,"Got empty Msg..\n");
03130          return NULL;
03131       }
03132 
03133       if (r<0) {
03134          if (errno == EAGAIN) {
03135             /*we wait for mISDN here*/
03136             cb_log(4,0,"mISDN_read wants us to wait\n");
03137             usleep(5000);
03138             goto AGAIN;
03139          }
03140 
03141          cb_log(0,0,"mISDN_read returned :%d error:%s (%d)\n",r,strerror(errno),errno);
03142       }
03143 
03144 #if 0
03145                if  (!(frm->prim == (DL_DATA|INDICATION) )|| (frm->prim == (PH_DATA|INDICATION)))
03146                        cb_log(0,0,"prim: %x dinfo:%x addr:%x msglen:%d frm->len:%d\n",frm->prim, frm->dinfo, frm->addr, msg->len,frm->len );
03147 #endif
03148       return msg;
03149 }

static struct misdn_bchannel* find_bc_by_addr ( unsigned long  addr  )  [static]

Definition at line 1595 of file isdn_lib.c.

References misdn_bchannel::addr, misdn_stack::b_num, misdn_stack::bc, glob_mgr, misdn_bchannel::in_use, misdn_bchannel::layer_id, misdn_stack::next, and misdn_lib::stack_list.

Referenced by handle_bchan().

01596 {
01597    struct misdn_stack *stack;
01598    int i;
01599 
01600    for (stack = glob_mgr->stack_list; stack; stack = stack->next) {
01601       for (i = 0; i <= stack->b_num; i++) {
01602          if (stack->bc[i].in_use
01603             && ((stack->bc[i].addr & STACK_ID_MASK) == (addr & STACK_ID_MASK)
01604                || stack->bc[i].layer_id == addr)) {
01605             return &stack->bc[i];
01606          }
01607       }
01608    }
01609 
01610    return NULL;
01611 }

static struct misdn_bchannel* find_bc_by_channel ( int  port,
int  channel 
) [static]

Definition at line 1629 of file isdn_lib.c.

References misdn_stack::b_num, misdn_stack::bc, misdn_bchannel::channel, find_stack_by_port(), and misdn_bchannel::in_use.

Referenced by handle_err().

01630 {
01631    struct misdn_stack *stack = find_stack_by_port(port);
01632    int i;
01633 
01634    if (!stack) {
01635       return NULL;
01636    }
01637 
01638    for (i = 0; i <= stack->b_num; i++) {
01639       if (stack->bc[i].in_use && stack->bc[i].channel == channel) {
01640          return &stack->bc[i];
01641       }
01642    }
01643 
01644    return NULL;
01645 }

static struct misdn_bchannel* find_bc_by_confid ( unsigned long  confid  )  [static]

Definition at line 1613 of file isdn_lib.c.

References misdn_stack::b_num, misdn_stack::bc, misdn_bchannel::conf_id, glob_mgr, misdn_bchannel::in_use, misdn_stack::next, and misdn_lib::stack_list.

Referenced by misdn_lib_send_event().

01614 {
01615    struct misdn_stack *stack;
01616    int i;
01617 
01618    for (stack = glob_mgr->stack_list; stack; stack = stack->next) {
01619       for (i = 0; i <= stack->b_num; i++) {
01620          if (stack->bc[i].in_use && stack->bc[i].conf_id == confid) {
01621             return &stack->bc[i];
01622          }
01623       }
01624    }
01625    return NULL;
01626 }

struct misdn_bchannel * find_bc_by_l3id ( struct misdn_stack stack,
unsigned long  l3id 
)

Definition at line 1575 of file isdn_lib.c.

References misdn_stack::b_num, misdn_stack::bc, misdn_bchannel::in_use, and misdn_bchannel::l3_id.

Referenced by handle_cr(), handle_event_nt(), handle_frm(), manager_event_handler(), and release_cr().

01576 {
01577    int i;
01578 
01579    for (i = 0; i <= stack->b_num; ++i) {
01580       if (stack->bc[i].in_use && stack->bc[i].l3_id == l3id) {
01581          return &stack->bc[i];
01582       }
01583    }
01584 #if defined(AST_MISDN_ENHANCEMENTS)
01585    /* Search the B channel records for a REGISTER signaling link. */
01586    for (i = MAX_BCHANS + 1; i < ARRAY_LEN(stack->bc); ++i) {
01587       if (stack->bc[i].in_use && stack->bc[i].l3_id == l3id) {
01588          return &stack->bc[i];
01589       }
01590    }
01591 #endif   /* defined(AST_MISDN_ENHANCEMENTS) */
01592    return stack_holder_find(stack, l3id);
01593 }

static struct misdn_bchannel* find_bc_by_masked_l3id ( struct misdn_stack stack,
unsigned long  l3id,
unsigned long  mask 
) [static]

Definition at line 1554 of file isdn_lib.c.

References misdn_stack::b_num, misdn_stack::bc, misdn_bchannel::in_use, and misdn_bchannel::l3_id.

Referenced by handle_event_nt().

01555 {
01556    int i;
01557 
01558    for (i = 0; i <= stack->b_num; ++i) {
01559       if (stack->bc[i].in_use && (stack->bc[i].l3_id & mask) == (l3id & mask)) {
01560          return &stack->bc[i];
01561       }
01562    }
01563 #if defined(AST_MISDN_ENHANCEMENTS)
01564    /* Search the B channel records for a REGISTER signaling link. */
01565    for (i = MAX_BCHANS + 1; i < ARRAY_LEN(stack->bc); ++i) {
01566       if (stack->bc[i].in_use && (stack->bc[i].l3_id & mask) == (l3id & mask)) {
01567          return &stack->bc[i];
01568       }
01569    }
01570 #endif   /* defined(AST_MISDN_ENHANCEMENTS) */
01571    return stack_holder_find(stack, l3id);
01572 }

static int find_free_chan_in_stack ( struct misdn_stack stack,
struct misdn_bchannel bc,
int  channel,
int  dec 
) [static]

Definition at line 517 of file isdn_lib.c.

References ARRAY_LEN, misdn_stack::b_num, misdn_stack::bc, cb_log, misdn_bchannel::channel_found, misdn_stack::channels, misdn_bchannel::is_register_pool, MAX_BCHANS, misdn_stack::port, misdn_stack::pri, pthread_mutex_lock, and misdn_stack::st_lock.

Referenced by create_process(), handle_event(), handle_event_nt(), and misdn_lib_send_event().

00518 {
00519    int i;
00520    int chan = 0;
00521    int bnums;
00522 
00523    if (bc->channel_found) {
00524       return 0;
00525    }
00526 
00527    bc->channel_found = 1;
00528 
00529 #if defined(AST_MISDN_ENHANCEMENTS)
00530    if (bc->is_register_pool) {
00531       pthread_mutex_lock(&stack->st_lock);
00532       for (i = MAX_BCHANS + 1; i < ARRAY_LEN(stack->channels); ++i) {
00533          if (!stack->channels[i]) {
00534             chan = i + 1;
00535             cb_log(3, stack->port, " --> found REGISTER chan: %d\n", chan);
00536             break;
00537          }
00538       }
00539    } else
00540 #endif   /* defined(AST_MISDN_ENHANCEMENTS) */
00541    {
00542       cb_log(5, stack->port, "find_free_chan: req_chan:%d\n", channel);
00543 
00544       if (channel < 0 || channel > MAX_BCHANS) {
00545          cb_log(0, stack->port, " !! out of bound call to find_free_chan_in_stack! (ch:%d)\n", channel);
00546          return 0;
00547       }
00548 
00549       --channel;
00550 
00551       pthread_mutex_lock(&stack->st_lock);
00552       bnums = stack->pri ? stack->b_num : stack->b_num - 1;
00553       if (dec) {
00554          for (i = bnums; i >= 0; --i) {
00555             if (i != 15 && (channel < 0 || i == channel)) { /* skip E1 D channel ;) and work with chan preselection */
00556                if (!stack->channels[i]) {
00557                   chan = i + 1;
00558                   cb_log(3, stack->port, " --> found chan%s: %d\n", channel >= 0 ? " (preselected)" : "", chan);
00559                   break;
00560                }
00561             }
00562          }
00563       } else {
00564          for (i = 0; i <= bnums; ++i) {
00565             if (i != 15 && (channel < 0 || i == channel)) { /* skip E1 D channel ;) and work with chan preselection */
00566                if (!stack->channels[i]) {
00567                   chan = i + 1;
00568                   cb_log(3, stack->port, " --> found chan%s: %d\n", channel >= 0 ? " (preselected)" : "", chan);
00569                   break;
00570                }
00571             }
00572          }
00573       }
00574    }
00575 
00576    if (!chan) {
00577       pthread_mutex_unlock(&stack->st_lock);
00578       cb_log(1, stack->port, " !! NO FREE CHAN IN STACK\n");
00579       dump_chan_list(stack);
00580       bc->out_cause = AST_CAUSE_NORMAL_CIRCUIT_CONGESTION;
00581       return -1;
00582    }
00583 
00584    if (set_chan_in_stack(stack, chan) < 0) {
00585       pthread_mutex_unlock(&stack->st_lock);
00586       cb_log(0, stack->port, "Channel Already in use:%d\n", chan);
00587       bc->out_cause = AST_CAUSE_REQUESTED_CHAN_UNAVAIL;
00588       return -1;
00589    }
00590    pthread_mutex_unlock(&stack->st_lock);
00591 
00592    bc->channel = chan;
00593    return 0;
00594 }

static struct misdn_stack* find_stack_by_addr ( int  addr  )  [static]

Definition at line 1511 of file isdn_lib.c.

References glob_mgr, misdn_stack::next, misdn_lib::stack_list, and misdn_stack::upper_id.

Referenced by handle_frm(), handle_frm_nt(), handle_l1(), handle_l2(), and handle_mgmt().

01512 {
01513    struct misdn_stack *stack;
01514 
01515    for (stack = glob_mgr->stack_list; stack; stack = stack->next) {
01516       if ((stack->upper_id & STACK_ID_MASK) == (addr & STACK_ID_MASK)) {
01517          /* Found the stack */
01518          break;
01519       }
01520    }
01521 
01522    return stack;
01523 }

static struct misdn_stack* find_stack_by_mgr ( manager_t *  mgr_nt  )  [static]

Definition at line 1540 of file isdn_lib.c.

References glob_mgr, misdn_stack::mgr, misdn_stack::next, and misdn_lib::stack_list.

Referenced by handle_event_nt().

01541 {
01542    struct misdn_stack *stack;
01543 
01544    for (stack = glob_mgr->stack_list; stack; stack = stack->next) {
01545       if (&stack->mgr == mgr_nt) {
01546          /* Found the stack */
01547          break;
01548       }
01549    }
01550 
01551    return stack;
01552 }

static struct misdn_stack* find_stack_by_port ( int  port  )  [static]

Definition at line 1526 of file isdn_lib.c.

References glob_mgr, misdn_stack::next, misdn_stack::port, and misdn_lib::stack_list.

Referenced by find_bc_by_channel(), handle_err(), manager_event_handler(), misdn_lib_get_free_bc(), misdn_lib_get_port_info(), misdn_lib_port_restart(), misdn_lib_reinit_nt_stack(), and misdn_lib_send_restart().

01527 {
01528    struct misdn_stack *stack;
01529 
01530    for (stack = glob_mgr->stack_list; stack; stack = stack->next) {
01531       if (stack->port == port) {
01532          /* Found the stack */
01533          break;
01534       }
01535    }
01536 
01537    return stack;
01538 }

static char* flip_buf_bits ( char *  buf,
int  len 
) [static]

Definition at line 338 of file isdn_lib.c.

Referenced by handle_bchan(), misdn_lib_init(), misdn_lib_tx2misdn_frm(), and misdn_tx_jitter().

00339 {
00340    int i;
00341    char * start = buf;
00342 
00343    for (i = 0 ; i < len; i++) {
00344       buf[i] = flip_table[(unsigned char)buf[i]];
00345    }
00346 
00347    return start;
00348 }

struct misdn_stack * get_misdn_stack ( void   ) 

Definition at line 4871 of file isdn_lib.c.

References glob_mgr, and misdn_lib::stack_list.

Referenced by get_show_stack_details(), get_stack_by_bc(), misdn_dump_chanlist(), misdn_lib_find_held_bc(), misdn_lib_get_maxchans(), misdn_lib_is_port_blocked(), misdn_lib_is_ptp(), misdn_lib_nt_keepcalls(), misdn_lib_port_block(), misdn_lib_port_is_nt(), misdn_lib_port_is_pri(), and misdn_lib_port_unblock().

04872 {
04873    return glob_mgr->stack_list;
04874 }

void get_show_stack_details ( int  port,
char *  buf 
)

Definition at line 168 of file isdn_lib.c.

References get_misdn_stack(), misdn_stack::next, and misdn_stack::port.

Referenced by handle_cli_misdn_show_port(), and handle_cli_misdn_show_stacks().

00169 {
00170    struct misdn_stack *stack = get_misdn_stack();
00171 
00172    for (; stack; stack = stack->next) {
00173       if (stack->port == port) {
00174          break;
00175       }
00176    }
00177 
00178    if (stack) {
00179       sprintf(buf, "* Port %2d Type %s Prot. %s L2Link %s L1Link:%s Blocked:%d",
00180          stack->port,
00181          stack->nt ? "NT" : "TE",
00182          stack->ptp ? "PTP" : "PMP",
00183          stack->l2link ? "UP  " : "DOWN",
00184          stack->l1link ? "UP  " : "DOWN",
00185          stack->blocked);
00186    } else {
00187       buf[0] = 0;
00188    }
00189 }

struct misdn_stack* get_stack_by_bc ( struct misdn_bchannel bc  ) 

Definition at line 152 of file isdn_lib.c.

References misdn_stack::bc, get_misdn_stack(), misdn_stack::next, misdn_bchannel::port, and misdn_stack::port.

Referenced by clean_up_bc(), create_process(), dec_ie_channel_id(), enc_ie_channel_id(), handle_bchan(), handle_event(), manager_bchannel_activate(), manager_bchannel_deactivate(), manager_clean_bc(), manager_ec_disable(), manager_ec_enable(), misdn_lib_log_ies(), misdn_lib_release(), misdn_lib_send_event(), misdn_lib_tx2misdn_frm(), parse_release_complete(), parse_restart(), send_msg(), and setup_bc().

00153 {
00154    struct misdn_stack *stack = get_misdn_stack();
00155 
00156    if (!bc)
00157       return NULL;
00158 
00159    for ( ; stack; stack = stack->next) {
00160       if (bc->port == stack->port)
00161          return stack;
00162    }
00163 
00164    return NULL;
00165 }

static int handle_bchan ( msg_t *  msg  )  [static]

Definition at line 2465 of file isdn_lib.c.

References misdn_bchannel::addr, misdn_bchannel::b_stid, misdn_stack::bc, misdn_bchannel::bc_state, bc_state2str(), bc_state_change(), BCHAN_ACTIVATED, BCHAN_CLEAN_REQUEST, BCHAN_SETUP, BCHAN_SETUPED, misdn_bchannel::bframe, misdn_bchannel::bframe_len, misdn_bchannel::caller, misdn_bchannel::capability, cb_event, cb_log, misdn_bchannel::channel, clean_up_bc(), misdn_bchannel::dialed, do_tone(), misdn_bchannel::dtmf, errno, EVENT_BCHAN_DATA, EVENT_DTMF_TONE, find_bc_by_addr(), flip_buf_bits(), get_stack_by_bc(), glob_mgr, misdn_bchannel::layer, misdn_stack::midev, misdn_cap_is_speech(), misdn_tx_jitter(), misdn_party_id::name, misdn_bchannel::nojitter, misdn_party_dialing::number, misdn_party_id::number, misdn_party_dialing::number_type, misdn_party_id::number_type, misdn_bchannel::pid, misdn_stack::port, misdn_bchannel::port, and misdn_lib::user_data.

Referenced by handle_err(), and manager_isdn_handler().

02466 {
02467    iframe_t *frm= (iframe_t*)msg->data;
02468    struct misdn_bchannel *bc=find_bc_by_addr(frm->addr);
02469    struct misdn_stack *stack;
02470 
02471    if (!bc) {
02472       cb_log(1,0,"handle_bchan: BC not found for prim:%x with addr:%x dinfo:%x\n", frm->prim, frm->addr, frm->dinfo);
02473       return 0 ;
02474    }
02475 
02476    stack = get_stack_by_bc(bc);
02477 
02478    if (!stack) {
02479       cb_log(0, bc->port,"handle_bchan: STACK not found for prim:%x with addr:%x dinfo:%x\n", frm->prim, frm->addr, frm->dinfo);
02480       return 0;
02481    }
02482 
02483    switch (frm->prim) {
02484 
02485    case MGR_SETSTACK| CONFIRM:
02486       cb_log(3, stack->port, "BCHAN: MGR_SETSTACK|CONFIRM pid:%d\n",bc->pid);
02487       break;
02488 
02489    case MGR_SETSTACK| INDICATION:
02490       cb_log(3, stack->port, "BCHAN: MGR_SETSTACK|IND pid:%d\n",bc->pid);
02491    break;
02492 #if 0
02493    AGAIN:
02494       bc->addr = mISDN_get_layerid(stack->midev, bc->b_stid, bc->layer);
02495       if (!bc->addr) {
02496 
02497          if (errno == EAGAIN) {
02498             usleep(1000);
02499             goto AGAIN;
02500          }
02501 
02502          cb_log(0,stack->port,"$$$ Get Layer (%d) Id Error: %s\n",bc->layer,strerror(errno));
02503 
02504          /* we kill the channel later, when we received some
02505             data. */
02506          bc->addr= frm->addr;
02507       } else if ( bc->addr < 0) {
02508          cb_log(0, stack->port,"$$$ bc->addr <0 Error:%s\n",strerror(errno));
02509          bc->addr=0;
02510       }
02511 
02512       cb_log(4, stack->port," --> Got Adr %x\n", bc->addr);
02513 
02514       free_msg(msg);
02515 
02516 
02517       switch(bc->bc_state) {
02518       case BCHAN_SETUP:
02519          bc_state_change(bc,BCHAN_SETUPED);
02520       break;
02521 
02522       case BCHAN_CLEAN_REQUEST:
02523       default:
02524          cb_log(0, stack->port," --> STATE WASN'T SETUP (but %s) in SETSTACK|IND pid:%d\n",bc_state2str(bc->bc_state), bc->pid);
02525          clean_up_bc(bc);
02526       }
02527       return 1;
02528 #endif
02529 
02530    case MGR_DELLAYER| INDICATION:
02531       cb_log(3, stack->port, "BCHAN: MGR_DELLAYER|IND pid:%d\n",bc->pid);
02532       break;
02533 
02534    case MGR_DELLAYER| CONFIRM:
02535       cb_log(3, stack->port, "BCHAN: MGR_DELLAYER|CNF pid:%d\n",bc->pid);
02536 
02537       bc->pid=0;
02538       bc->addr=0;
02539 
02540       free_msg(msg);
02541       return 1;
02542 
02543    case PH_ACTIVATE | INDICATION:
02544    case DL_ESTABLISH | INDICATION:
02545       cb_log(3, stack->port, "BCHAN: ACT Ind pid:%d\n", bc->pid);
02546 
02547       free_msg(msg);
02548       return 1;
02549 
02550    case PH_ACTIVATE | CONFIRM:
02551    case DL_ESTABLISH | CONFIRM:
02552 
02553       cb_log(3, stack->port, "BCHAN: bchan ACT Confirm pid:%d\n",bc->pid);
02554       free_msg(msg);
02555 
02556       return 1;
02557 
02558    case DL_ESTABLISH | REQUEST:
02559       {
02560          char buf[128];
02561          mISDN_write_frame(stack->midev, buf, bc->addr | FLG_MSG_TARGET | FLG_MSG_DOWN,  DL_ESTABLISH | CONFIRM, 0,0, NULL, TIMEOUT_1SEC);
02562       }
02563       free_msg(msg);
02564       return 1;
02565 
02566    case DL_RELEASE|REQUEST:
02567       {
02568          char buf[128];
02569          mISDN_write_frame(stack->midev, buf, bc->addr | FLG_MSG_TARGET | FLG_MSG_DOWN,  DL_RELEASE| CONFIRM, 0,0, NULL, TIMEOUT_1SEC);
02570       }
02571       free_msg(msg);
02572       return 1;
02573 
02574    case PH_DEACTIVATE | INDICATION:
02575    case DL_RELEASE | INDICATION:
02576       cb_log (3, stack->port, "BCHAN: DeACT Ind pid:%d\n",bc->pid);
02577 
02578       free_msg(msg);
02579       return 1;
02580 
02581    case PH_DEACTIVATE | CONFIRM:
02582    case DL_RELEASE | CONFIRM:
02583       cb_log(3, stack->port, "BCHAN: DeACT Conf pid:%d\n",bc->pid);
02584 
02585       free_msg(msg);
02586       return 1;
02587 
02588    case PH_CONTROL|INDICATION:
02589    {
02590       unsigned int *cont = (unsigned int *) &frm->data.p;
02591 
02592       cb_log(4, stack->port,
02593          "PH_CONTROL: channel:%d caller%d:\"%s\" <%s> dialed%d:%s \n",
02594          bc->channel,
02595          bc->caller.number_type,
02596          bc->caller.name,
02597          bc->caller.number,
02598          bc->dialed.number_type,
02599          bc->dialed.number);
02600 
02601       if ((*cont & ~DTMF_TONE_MASK) == DTMF_TONE_VAL) {
02602          int dtmf = *cont & DTMF_TONE_MASK;
02603          cb_log(4, stack->port, " --> DTMF TONE: %c\n",dtmf);
02604          bc->dtmf=dtmf;
02605          cb_event(EVENT_DTMF_TONE, bc, glob_mgr->user_data);
02606 
02607          free_msg(msg);
02608          return 1;
02609       }
02610       if (*cont == BF_REJECT) {
02611          cb_log(4, stack->port, " --> BF REJECT\n");
02612          free_msg(msg);
02613          return 1;
02614       }
02615       if (*cont == BF_ACCEPT) {
02616          cb_log(4, stack->port, " --> BF ACCEPT\n");
02617          free_msg(msg);
02618          return 1;
02619       }
02620    }
02621    break;
02622 
02623    case PH_DATA|REQUEST:
02624    case DL_DATA|REQUEST:
02625       cb_log(0, stack->port, "DL_DATA REQUEST \n");
02626       do_tone(bc, 64);
02627 
02628       free_msg(msg);
02629       return 1;
02630 
02631 
02632    case PH_DATA|INDICATION:
02633    case DL_DATA|INDICATION:
02634    {
02635       bc->bframe = (void*)&frm->data.i;
02636       bc->bframe_len = frm->len;
02637 
02638       /** Anyway flip the bufbits **/
02639       if ( misdn_cap_is_speech(bc->capability) )
02640          flip_buf_bits(bc->bframe, bc->bframe_len);
02641 
02642 
02643       if (!bc->bframe_len) {
02644          cb_log(2, stack->port, "DL_DATA INDICATION bc->addr:%x frm->addr:%x\n", bc->addr, frm->addr);
02645          free_msg(msg);
02646          return 1;
02647       }
02648 
02649       if ( (bc->addr&STACK_ID_MASK) != (frm->addr&STACK_ID_MASK) ) {
02650          cb_log(2, stack->port, "DL_DATA INDICATION bc->addr:%x frm->addr:%x\n", bc->addr, frm->addr);
02651          free_msg(msg);
02652          return 1;
02653       }
02654 
02655 #if MISDN_DEBUG
02656       cb_log(0, stack->port, "DL_DATA INDICATION Len %d\n", frm->len);
02657 
02658 #endif
02659 
02660       if ( (bc->bc_state == BCHAN_ACTIVATED) && frm->len > 0) {
02661          int t;
02662 
02663 #ifdef MISDN_B_DEBUG
02664          cb_log(0,bc->port,"do_tone START\n");
02665 #endif
02666          t=do_tone(bc,frm->len);
02667 
02668 #ifdef MISDN_B_DEBUG
02669          cb_log(0,bc->port,"do_tone STOP (%d)\n",t);
02670 #endif
02671          if (  !t ) {
02672             int i;
02673 
02674             if ( misdn_cap_is_speech(bc->capability)) {
02675                if ( !bc->nojitter ) {
02676 #ifdef MISDN_B_DEBUG
02677                   cb_log(0,bc->port,"tx_jitter START\n");
02678 #endif
02679                   misdn_tx_jitter(bc,frm->len);
02680 #ifdef MISDN_B_DEBUG
02681                   cb_log(0,bc->port,"tx_jitter STOP\n");
02682 #endif
02683                }
02684             }
02685 
02686 #ifdef MISDN_B_DEBUG
02687             cb_log(0,bc->port,"EVENT_B_DATA START\n");
02688 #endif
02689 
02690             i = cb_event(EVENT_BCHAN_DATA, bc, glob_mgr->user_data);
02691 #ifdef MISDN_B_DEBUG
02692             cb_log(0,bc->port,"EVENT_B_DATA STOP\n");
02693 #endif
02694 
02695             if (i<0) {
02696                cb_log(10,stack->port,"cb_event returned <0\n");
02697                /*clean_up_bc(bc);*/
02698             }
02699          }
02700       }
02701       free_msg(msg);
02702       return 1;
02703    }
02704 
02705 
02706    case PH_CONTROL | CONFIRM:
02707       cb_log(4, stack->port, "PH_CONTROL|CNF bc->addr:%x\n", frm->addr);
02708       free_msg(msg);
02709       return 1;
02710 
02711    case PH_DATA | CONFIRM:
02712    case DL_DATA|CONFIRM:
02713 #if MISDN_DEBUG
02714 
02715       cb_log(0, stack->port, "Data confirmed\n");
02716 
02717 #endif
02718       free_msg(msg);
02719       return 1;
02720    case DL_DATA|RESPONSE:
02721 #if MISDN_DEBUG
02722       cb_log(0, stack->port, "Data response\n");
02723 
02724 #endif
02725       break;
02726    }
02727 
02728    return 0;
02729 }

static int handle_cr ( struct misdn_stack stack,
iframe_t *  frm 
) [static]

Definition at line 1751 of file isdn_lib.c.

References cb_event, cb_log, misdn_bchannel::channel, clean_up_bc(), dump_chan_list(), empty_bc(), empty_chan_in_stack(), EVENT_CLEANUP, find_bc_by_l3id(), free, glob_mgr, misdn_bchannel::in_use, misdn_bchannel::l3_id, misdn_lib_get_free_bc(), misdn_make_dummy(), misdn_bchannel::need_disconnect, misdn_bchannel::need_release, misdn_bchannel::need_release_complete, misdn_stack::nt, misdn_stack::port, misdn_bchannel::stack_holder, stack_holder_remove(), and misdn_lib::user_data.

Referenced by handle_event_nt(), handle_frm(), and release_cr().

01752 {
01753    struct misdn_bchannel dummybc;
01754    struct misdn_bchannel *bc;
01755    int channel;
01756 
01757    if (!stack) return -1;
01758 
01759    switch (frm->prim) {
01760    case CC_NEW_CR|INDICATION:
01761       cb_log(7, stack->port, " --> lib: NEW_CR Ind with l3id:%x on this port.\n",frm->dinfo);
01762 
01763       bc = misdn_lib_get_free_bc(stack->port, 0, 1, 0);
01764       if (!bc) {
01765          cb_log(0, stack->port, " --> !! lib: No free channel!\n");
01766          return -1;
01767       }
01768 
01769       cb_log(7, stack->port, " --> new_process: New L3Id: %x\n",frm->dinfo);
01770       bc->l3_id=frm->dinfo;
01771       return 1;
01772    case CC_NEW_CR|CONFIRM:
01773       return 1;
01774    case CC_NEW_CR|REQUEST:
01775       return 1;
01776    case CC_RELEASE_CR|REQUEST:
01777       return 1;
01778    case CC_RELEASE_CR|CONFIRM:
01779       break;
01780    case CC_RELEASE_CR|INDICATION:
01781       cb_log(4, stack->port, " --> lib: RELEASE_CR Ind with l3id:%x\n", frm->dinfo);
01782       bc = find_bc_by_l3id(stack, frm->dinfo);
01783       if (!bc) {
01784          cb_log(4, stack->port, " --> Didn't find BC so temporarily creating dummy BC (l3id:%x) on this port.\n", frm->dinfo);
01785          misdn_make_dummy(&dummybc, stack->port, frm->dinfo, stack->nt, 0);
01786          bc = &dummybc;
01787       }
01788 
01789       channel = bc->channel;
01790       cb_log(4, stack->port, " --> lib: CLEANING UP l3id: %x\n", frm->dinfo);
01791 
01792       /* bc->pid = 0; */
01793       bc->need_disconnect = 0;
01794       bc->need_release = 0;
01795       bc->need_release_complete = 0;
01796 
01797       cb_event(EVENT_CLEANUP, bc, glob_mgr->user_data);
01798 
01799       empty_bc(bc);
01800       clean_up_bc(bc);
01801 
01802       if (channel > 0)
01803          empty_chan_in_stack(stack, channel);
01804       bc->in_use = 0;
01805 
01806       dump_chan_list(stack);
01807 
01808       if (bc->stack_holder) {
01809          cb_log(4, stack->port, "REMOVING Holder\n");
01810          stack_holder_remove(stack, bc);
01811          free(bc);
01812       }
01813 
01814       return 1;
01815    default:
01816       break;
01817    }
01818 
01819    return 0;
01820 }

static int handle_err ( msg_t *  msg  )  [static]

Definition at line 3880 of file isdn_lib.c.

References misdn_stack::bc, misdn_bchannel::bc_state, bc_state2str(), cb_log, find_bc_by_channel(), find_stack_by_port(), handle_bchan(), misdn_stack::l1link, misdn_stack::l2link, misdn_lib_get_l1_down(), and misdn_lib_get_l2_down().

Referenced by manager_isdn_handler().

03881 {
03882    iframe_t *frm = (iframe_t*) msg->data;
03883 
03884 
03885    if (!frm->addr) {
03886       static int cnt=0;
03887       if (!cnt)
03888          cb_log(0,0,"mISDN Msg without Address pr:%x dinfo:%x\n",frm->prim,frm->dinfo);
03889       cnt++;
03890       if (cnt>100) {
03891          cb_log(0,0,"mISDN Msg without Address pr:%x dinfo:%x (already more than 100 of them)\n",frm->prim,frm->dinfo);
03892          cnt=0;
03893       }
03894 
03895       free_msg(msg);
03896       return 1;
03897 
03898    }
03899 
03900    switch (frm->prim) {
03901       case MGR_SETSTACK|INDICATION:
03902          return handle_bchan(msg);
03903       break;
03904 
03905       case MGR_SETSTACK|CONFIRM:
03906       case MGR_CLEARSTACK|CONFIRM:
03907          free_msg(msg) ;
03908          return 1;
03909       break;
03910 
03911       case DL_DATA|CONFIRM:
03912          cb_log(4,0,"DL_DATA|CONFIRM\n");
03913          free_msg(msg);
03914          return 1;
03915 
03916       case PH_CONTROL|CONFIRM:
03917          cb_log(4,0,"PH_CONTROL|CONFIRM\n");
03918          free_msg(msg);
03919          return 1;
03920 
03921       case DL_DATA|INDICATION:
03922       {
03923          int port=(frm->addr&MASTER_ID_MASK) >> 8;
03924          int channel=(frm->addr&CHILD_ID_MASK) >> 16;
03925          struct misdn_bchannel *bc;
03926 
03927          /*we flush the read buffer here*/
03928 
03929          cb_log(9,0,"BCHAN DATA without BC: addr:%x port:%d channel:%d\n",frm->addr, port,channel);
03930 
03931          free_msg(msg);
03932          return 1;
03933 
03934 
03935          bc = find_bc_by_channel(port, channel);
03936 
03937          if (!bc) {
03938             struct misdn_stack *stack = find_stack_by_port(port);
03939 
03940             if (!stack) {
03941                cb_log(0,0," --> stack not found\n");
03942                free_msg(msg);
03943                return 1;
03944             }
03945 
03946             cb_log(0,0," --> bc not found by channel\n");
03947             if (stack->l2link)
03948                misdn_lib_get_l2_down(stack);
03949 
03950             if (stack->l1link)
03951                misdn_lib_get_l1_down(stack);
03952 
03953             free_msg(msg);
03954             return 1;
03955          }
03956 
03957          cb_log(3,port," --> BC in state:%s\n", bc_state2str(bc->bc_state));
03958       }
03959    }
03960 
03961    return 0;
03962 }

static int handle_event ( struct misdn_bchannel bc,
enum event_e  event,
iframe_t *  frm 
) [static]

Definition at line 1651 of file isdn_lib.c.

References misdn_stack::bc, cb_log, EVENT_ALERTING, EVENT_CONNECT, EVENT_CONNECT_ACKNOWLEDGE, EVENT_PROCEEDING, EVENT_PROGRESS, EVENT_RELEASE, EVENT_RELEASE_COMPLETE, EVENT_SETUP, EVENT_SETUP_ACKNOWLEDGE, find_free_chan_in_stack(), get_stack_by_bc(), manager_ec_enable(), manager_ph_control(), manager_ph_control_block(), misdn_cap_is_speech(), misdn_lib_send_event(), misdn_stack::nt, misdn_stack::port, misdn_stack::pri, misdn_stack::ptp, and setup_bc().

Referenced by ast_event_queue(), and handle_frm().

01652 {
01653    struct misdn_stack *stack=get_stack_by_bc(bc);
01654 
01655    if (!stack->nt) {
01656 
01657       switch (event) {
01658 
01659       case EVENT_CONNECT_ACKNOWLEDGE:
01660          setup_bc(bc);
01661 
01662          if ( *bc->crypt_key ) {
01663             cb_log(4, stack->port,
01664                "ENABLING BLOWFISH channel:%d caller%d:\"%s\" <%s> dialed%d:%s\n",
01665                bc->channel,
01666                bc->caller.number_type,
01667                bc->caller.name,
01668                bc->caller.number,
01669                bc->dialed.number_type,
01670                bc->dialed.number);
01671             manager_ph_control_block(bc,  BF_ENABLE_KEY, bc->crypt_key, strlen(bc->crypt_key) );
01672          }
01673 
01674          if (misdn_cap_is_speech(bc->capability)) {
01675             if (  !bc->nodsp) manager_ph_control(bc,  DTMF_TONE_START, 0);
01676             manager_ec_enable(bc);
01677 
01678             if ( bc->txgain != 0 ) {
01679                cb_log(4, stack->port, "--> Changing txgain to %d\n", bc->txgain);
01680                manager_ph_control(bc, VOL_CHANGE_TX, bc->txgain);
01681             }
01682             if ( bc->rxgain != 0 ) {
01683                cb_log(4, stack->port, "--> Changing rxgain to %d\n", bc->rxgain);
01684                manager_ph_control(bc, VOL_CHANGE_RX, bc->rxgain);
01685             }
01686          }
01687 
01688          break;
01689       case EVENT_CONNECT:
01690 
01691          if ( *bc->crypt_key ) {
01692             cb_log(4, stack->port,
01693                "ENABLING BLOWFISH channel:%d caller%d:\"%s\" <%s> dialed%d:%s\n",
01694                bc->channel,
01695                bc->caller.number_type,
01696                bc->caller.name,
01697                bc->caller.number,
01698                bc->dialed.number_type,
01699                bc->dialed.number);
01700             manager_ph_control_block(bc,  BF_ENABLE_KEY, bc->crypt_key, strlen(bc->crypt_key) );
01701          }
01702       case EVENT_ALERTING:
01703       case EVENT_PROGRESS:
01704       case EVENT_PROCEEDING:
01705       case EVENT_SETUP_ACKNOWLEDGE:
01706       case EVENT_SETUP:
01707       {
01708          if (bc->channel == 0xff || bc->channel<=0)
01709             bc->channel=0;
01710 
01711          if (find_free_chan_in_stack(stack, bc, bc->channel, 0)<0){
01712             if (!stack->pri && !stack->ptp)  {
01713                bc->cw=1;
01714                break;
01715             }
01716 
01717             if (!bc->channel) {
01718                cb_log(0, stack->port, "Any Channel Requested, but we have no more!!\n");
01719             } else {
01720                cb_log(0, stack->port,
01721                   "Requested Channel Already in Use releasing this call with cause %d!!!!\n",
01722                   bc->out_cause);
01723             }
01724 
01725             /* when the channel is already in use, we can't
01726              * simply clear it, we need to make sure that
01727              * it will still be marked as in_use in the
01728              * available channels list.*/
01729             bc->channel=0;
01730 
01731             misdn_lib_send_event(bc,EVENT_RELEASE_COMPLETE);
01732             return -1;
01733          }
01734 
01735          setup_bc(bc);
01736          break;
01737       }
01738 
01739       case EVENT_RELEASE_COMPLETE:
01740       case EVENT_RELEASE:
01741          break;
01742       default:
01743          break;
01744       }
01745    } else {    /** NT MODE **/
01746 
01747    }
01748    return 0;
01749 }

static int handle_event_nt ( void *  dat,
void *  arg 
) [static]

Definition at line 1953 of file isdn_lib.c.

References AST_CAUSE_USER_BUSY, misdn_stack::bc, misdn_bchannel::cause, cb_event, cb_log, misdn_bchannel::channel, clean_up_bc(), create_l3msg(), empty_bc(), empty_chan_in_stack(), EVENT_NEW_L3ID, EVENT_PORT_ALARM, EVENT_RELEASE, EVENT_RELEASE_COMPLETE, EVENT_SETUP, find_bc_by_l3id(), find_bc_by_masked_l3id(), find_free_chan_in_stack(), find_stack_by_mgr(), free, glob_mgr, handle_cr(), misdn_bchannel::in_use, misdn_bchannel::is_register_pool, isdn_get_info(), isdn_msg_get_event(), isdn_msg_parse_event(), misdn_stack::l1link, misdn_stack::l2link, misdn_stack::l2upcnt, misdn_bchannel::l3_id, misdn_lib_get_free_bc(), misdn_lib_get_l2_up(), misdn_lib_reinit_nt_stack(), misdn_lib_send_event(), misdn_lib_send_restart(), misdn_make_dummy(), mISDNUSER_HEAD_SIZE, msgs_g, misdn_stack::nst, misdn_stack::nstlock, misdn_stack::nt, misdn_bchannel::port, misdn_stack::port, misdn_stack::procids, pthread_mutex_lock, pthread_mutex_unlock, misdn_stack::ptp, release_cr(), misdn_stack::restart_sent, stack_holder_find(), stack_holder_remove(), misdn_stack::upper_id, and misdn_lib::user_data.

Referenced by misdn_lib_reinit_nt_stack().

01954 {
01955    struct misdn_bchannel dummybc;
01956    struct misdn_bchannel *bc;
01957    manager_t *mgr = (manager_t *)dat;
01958    msg_t *msg = (msg_t *)arg;
01959    msg_t *dmsg;
01960    mISDNuser_head_t *hh;
01961    struct misdn_stack *stack;
01962    enum event_e event;
01963    int reject=0;
01964    int l3id;
01965    int channel;
01966    int tmpcause;
01967 
01968    if (!msg || !mgr)
01969       return(-EINVAL);
01970 
01971    stack = find_stack_by_mgr(mgr);
01972    hh=(mISDNuser_head_t*)msg->data;
01973 
01974    /*
01975     * When we are called from the mISDNuser lib, the nstlock is held and it
01976     * must be held when we return.  We unlock here because the lib may be
01977     * entered again recursively.
01978     */
01979    pthread_mutex_unlock(&stack->nstlock);
01980 
01981    cb_log(5, stack->port, " --> lib: prim %x dinfo %x\n",hh->prim, hh->dinfo);
01982    switch(hh->prim) {
01983    case CC_RETRIEVE|INDICATION:
01984    {
01985       struct misdn_bchannel *hold_bc;
01986       iframe_t frm; /* fake te frm to add callref to global callreflist */
01987 
01988       frm.dinfo = hh->dinfo;
01989       frm.addr=stack->upper_id | FLG_MSG_DOWN;
01990       frm.prim = CC_NEW_CR|INDICATION;
01991       if (handle_cr( stack, &frm)< 0) {
01992          goto ERR_NO_CHANNEL;
01993       }
01994 
01995       bc = find_bc_by_l3id(stack, hh->dinfo);
01996       hold_bc = stack_holder_find(stack, bc->l3_id);
01997       cb_log(4, stack->port, "bc_l3id:%x holded_bc_l3id:%x\n",bc->l3_id, hold_bc->l3_id);
01998 
01999       if (hold_bc) {
02000          cb_log(4, stack->port, "REMOVING Holder\n");
02001 
02002          /* swap the backup to our new channel back */
02003          stack_holder_remove(stack, hold_bc);
02004          memcpy(bc, hold_bc, sizeof(*bc));
02005          free(hold_bc);
02006 
02007          bc->holded=0;
02008          bc->b_stid=0;
02009       }
02010       break;
02011    }
02012 
02013    case CC_SETUP | CONFIRM:
02014       l3id = *((int *) (msg->data + mISDNUSER_HEAD_SIZE));
02015 
02016       cb_log(4, stack->port, " --> lib: Event_ind:SETUP CONFIRM [NT] : new L3ID is %x\n", l3id);
02017 
02018       bc = find_bc_by_l3id(stack, hh->dinfo);
02019       if (bc) {
02020          cb_log (2, bc->port, "I IND :CC_SETUP|CONFIRM: old l3id:%x new l3id:%x\n", bc->l3_id, l3id);
02021          bc->l3_id = l3id;
02022          cb_event(EVENT_NEW_L3ID, bc, glob_mgr->user_data);
02023       } else {
02024          cb_log(4, stack->port, "Bc Not found (after SETUP CONFIRM)\n");
02025       }
02026       free_msg(msg);
02027       pthread_mutex_lock(&stack->nstlock);
02028       return 0;
02029 
02030    case CC_SETUP | INDICATION:
02031       bc = misdn_lib_get_free_bc(stack->port, 0, 1, 0);
02032       if (!bc) {
02033          goto ERR_NO_CHANNEL;
02034       }
02035 
02036       cb_log(4, stack->port, " --> new_process: New L3Id: %x\n",hh->dinfo);
02037       bc->l3_id=hh->dinfo;
02038       break;
02039 
02040 #if defined(AST_MISDN_ENHANCEMENTS)
02041    case CC_REGISTER | CONFIRM:
02042       l3id = *((int *) (msg->data + mISDNUSER_HEAD_SIZE));
02043 
02044       cb_log(4, stack->port, " --> lib: Event_ind:REGISTER CONFIRM [NT] : new L3ID is %x\n", l3id);
02045 
02046       bc = find_bc_by_l3id(stack, hh->dinfo);
02047       if (bc) {
02048          cb_log (2, bc->port, "I IND :CC_REGISTER|CONFIRM: old l3id:%x new l3id:%x\n", bc->l3_id, l3id);
02049          bc->l3_id = l3id;
02050       } else {
02051          cb_log(4, stack->port, "Bc Not found (after REGISTER CONFIRM)\n");
02052       }
02053       free_msg(msg);
02054       pthread_mutex_lock(&stack->nstlock);
02055       return 0;
02056 #endif   /* defined(AST_MISDN_ENHANCEMENTS) */
02057 
02058 #if defined(AST_MISDN_ENHANCEMENTS)
02059    case CC_REGISTER | INDICATION:
02060       bc = misdn_lib_get_register_bc(stack->port);
02061       if (!bc) {
02062          goto ERR_NO_CHANNEL;
02063       }
02064 
02065       cb_log(4, stack->port, " --> new_process: New L3Id: %x\n",hh->dinfo);
02066       bc->l3_id=hh->dinfo;
02067       break;
02068 #endif   /* defined(AST_MISDN_ENHANCEMENTS) */
02069 
02070    case CC_CONNECT_ACKNOWLEDGE|INDICATION:
02071       break;
02072 
02073    case CC_ALERTING|INDICATION:
02074    case CC_PROCEEDING|INDICATION:
02075    case CC_SETUP_ACKNOWLEDGE|INDICATION:
02076    case CC_CONNECT|INDICATION:
02077       break;
02078    case CC_DISCONNECT|INDICATION:
02079       bc = find_bc_by_l3id(stack, hh->dinfo);
02080       if (!bc) {
02081          bc=find_bc_by_masked_l3id(stack, hh->dinfo, 0xffff0000);
02082          if (bc) {
02083             int myprocid=bc->l3_id&0x0000ffff;
02084 
02085             hh->dinfo=(hh->dinfo&0xffff0000)|myprocid;
02086             cb_log(3,stack->port,"Reject dinfo: %x cause:%d\n",hh->dinfo,bc->cause);
02087             reject=1;
02088          }
02089       }
02090       break;
02091 
02092    case CC_FACILITY|INDICATION:
02093       bc = find_bc_by_l3id(stack, hh->dinfo);
02094       if (!bc) {
02095          bc=find_bc_by_masked_l3id(stack, hh->dinfo, 0xffff0000);
02096          if (bc) {
02097             int myprocid=bc->l3_id&0x0000ffff;
02098 
02099             hh->dinfo=(hh->dinfo&0xffff0000)|myprocid;
02100             cb_log(4,bc->port,"Repaired reject Bug, new dinfo: %x\n",hh->dinfo);
02101          }
02102       }
02103       break;
02104 
02105    case CC_RELEASE_COMPLETE|INDICATION:
02106       break;
02107 
02108    case CC_SUSPEND|INDICATION:
02109       cb_log(4, stack->port, " --> Got Suspend, sending Reject for now\n");
02110       dmsg = create_l3msg(CC_SUSPEND_REJECT | REQUEST,MT_SUSPEND_REJECT, hh->dinfo,sizeof(RELEASE_COMPLETE_t), 1);
02111       pthread_mutex_lock(&stack->nstlock);
02112       stack->nst.manager_l3(&stack->nst, dmsg);
02113       free_msg(msg);
02114       return 0;
02115 
02116    case CC_RESUME|INDICATION:
02117       break;
02118 
02119    case CC_RELEASE|CONFIRM:
02120       bc = find_bc_by_l3id(stack, hh->dinfo);
02121       if (bc) {
02122          cb_log(1, stack->port, "CC_RELEASE|CONFIRM (l3id:%x), sending RELEASE_COMPLETE\n", hh->dinfo);
02123          misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE);
02124       }
02125       break;
02126 
02127    case CC_RELEASE|INDICATION:
02128       break;
02129 
02130    case CC_RELEASE_CR|INDICATION:
02131       release_cr(stack, hh);
02132       free_msg(msg);
02133       pthread_mutex_lock(&stack->nstlock);
02134       return 0;
02135 
02136    case CC_NEW_CR|INDICATION:
02137       /*  Got New CR for bchan, for now I handle this one in */
02138       /*  connect_ack, Need to be changed */
02139       l3id = *((int *) (msg->data + mISDNUSER_HEAD_SIZE));
02140 
02141       bc = find_bc_by_l3id(stack, hh->dinfo);
02142       if (!bc) {
02143          cb_log(0, stack->port, " --> In NEW_CR: didn't found bc ??\n");
02144          pthread_mutex_lock(&stack->nstlock);
02145          return -1;
02146       }
02147       if (((l3id&0xff00)!=0xff00) && ((bc->l3_id&0xff00)==0xff00)) {
02148          cb_log(4, stack->port, " --> Removing Process Id:%x on this port.\n", 0xff&bc->l3_id);
02149          stack->procids[bc->l3_id&0xff] = 0 ;
02150       }
02151       cb_log(4, stack->port, "lib: Event_ind:CC_NEW_CR : very new L3ID  is %x\n",l3id );
02152 
02153       bc->l3_id =l3id;
02154       if (!bc->is_register_pool) {
02155          cb_event(EVENT_NEW_L3ID, bc, glob_mgr->user_data);
02156       }
02157 
02158       free_msg(msg);
02159       pthread_mutex_lock(&stack->nstlock);
02160       return 0;
02161 
02162    case DL_ESTABLISH | INDICATION:
02163    case DL_ESTABLISH | CONFIRM:
02164       cb_log(3, stack->port, "%% GOT L2 Activate Info.\n");
02165 
02166       if (stack->ptp && stack->l2link) {
02167          cb_log(0, stack->port, "%% GOT L2 Activate Info. but we're activated already.. this l2 is faulty, blocking port\n");
02168          cb_event(EVENT_PORT_ALARM, &stack->bc[0], glob_mgr->user_data);
02169       }
02170 
02171       if (stack->ptp && !stack->restart_sent) {
02172          /* make sure we restart the interface of the
02173           * other side */
02174          stack->restart_sent=1;
02175          misdn_lib_send_restart(stack->port, -1);
02176 
02177       }
02178 
02179       /* when we get the L2 UP, the L1 is UP definitely too*/
02180       stack->l2link = 1;
02181       stack->l2upcnt=0;
02182 
02183       free_msg(msg);
02184       pthread_mutex_lock(&stack->nstlock);
02185       return 0;
02186 
02187    case DL_RELEASE | INDICATION:
02188    case DL_RELEASE | CONFIRM:
02189       if (stack->ptp) {
02190          cb_log(3 , stack->port, "%% GOT L2 DeActivate Info.\n");
02191 
02192          if (stack->l2upcnt>3) {
02193             cb_log(0 , stack->port, "!!! Could not Get the L2 up after 3 Attempts!!!\n");
02194          } else {
02195 #if 0
02196             if (stack->nt)
02197                misdn_lib_reinit_nt_stack(stack->port);
02198 #endif
02199             if (stack->l1link) {
02200                misdn_lib_get_l2_up(stack);
02201                stack->l2upcnt++;
02202             }
02203          }
02204 
02205       } else
02206          cb_log(3, stack->port, "%% GOT L2 DeActivate Info.\n");
02207 
02208       stack->l2link = 0;
02209       free_msg(msg);
02210       pthread_mutex_lock(&stack->nstlock);
02211       return 0;
02212 
02213    default:
02214       break;
02215    }
02216 
02217    /*  Parse Events and fire_up to App. */
02218    event = isdn_msg_get_event(msgs_g, msg, 1);
02219 
02220    bc = find_bc_by_l3id(stack, hh->dinfo);
02221    if (!bc) {
02222       cb_log(4, stack->port, " --> Didn't find BC so temporarily creating dummy BC (l3id:%x).\n", hh->dinfo);
02223       misdn_make_dummy(&dummybc, stack->port,  hh->dinfo, stack->nt, 0);
02224       bc = &dummybc;
02225    }
02226 
02227    isdn_msg_parse_event(msgs_g, msg, bc, 1);
02228 
02229    switch (event) {
02230    case EVENT_SETUP:
02231       if (bc->channel <= 0 || bc->channel == 0xff) {
02232          bc->channel = 0;
02233       }
02234 
02235       if (find_free_chan_in_stack(stack, bc, bc->channel, 0) < 0) {
02236          goto ERR_NO_CHANNEL;
02237       }
02238       break;
02239    case EVENT_RELEASE:
02240    case EVENT_RELEASE_COMPLETE:
02241       channel = bc->channel;
02242       tmpcause = bc->cause;
02243 
02244       empty_bc(bc);
02245       bc->cause = tmpcause;
02246       clean_up_bc(bc);
02247 
02248       if (channel > 0)
02249          empty_chan_in_stack(stack, channel);
02250       bc->in_use = 0;
02251       break;
02252    default:
02253       break;
02254    }
02255 
02256    if(!isdn_get_info(msgs_g, event, 1)) {
02257       cb_log(4, stack->port, "Unknown Event Ind: prim %x dinfo %x\n", hh->prim, hh->dinfo);
02258    } else {
02259       if (reject) {
02260          switch(bc->cause) {
02261          case AST_CAUSE_USER_BUSY:
02262             cb_log(1, stack->port, "Siemens Busy reject..\n");
02263             break;
02264          default:
02265             break;
02266          }
02267       }
02268       cb_event(event, bc, glob_mgr->user_data);
02269    }
02270 
02271    free_msg(msg);
02272    pthread_mutex_lock(&stack->nstlock);
02273    return 0;
02274 
02275 ERR_NO_CHANNEL:
02276    cb_log(4, stack->port, "Patch from MEIDANIS:Sending RELEASE_COMPLETE %x (No free Chan for you..)\n", hh->dinfo);
02277    dmsg = create_l3msg(CC_RELEASE_COMPLETE | REQUEST, MT_RELEASE_COMPLETE, hh->dinfo, sizeof(RELEASE_COMPLETE_t), 1);
02278    pthread_mutex_lock(&stack->nstlock);
02279    stack->nst.manager_l3(&stack->nst, dmsg);
02280    free_msg(msg);
02281    return 0;
02282 }

static int handle_frm ( msg_t *  msg  )  [static]

Definition at line 2768 of file isdn_lib.c.

References AST_CAUSE_NORMAL_CLEARING, AST_CAUSE_REQUESTED_CHAN_UNAVAIL, misdn_stack::bc, bc_state_change(), BCHAN_CLEANED, misdn_bchannel::cause, cb_event, cb_log, misdn_bchannel::channel, clean_up_bc(), empty_bc(), empty_chan_in_stack(), EVENT_RELEASE_COMPLETE, EVENT_RESTART, EVENT_SETUP, find_bc_by_l3id(), find_stack_by_addr(), glob_mgr, handle_cr(), handle_event(), misdn_bchannel::in_use, isdn_get_info(), isdn_msg_get_event(), isdn_msg_parse_event(), misdn_bchannel::l3_id, misdn_lib_send_event(), misdn_lib_send_restart(), misdn_make_dummy(), msgs_g, misdn_stack::nt, misdn_bchannel::out_cause, misdn_stack::port, RESPONSE_IGNORE_SETUP, RESPONSE_IGNORE_SETUP_WITHOUT_CLOSE, RESPONSE_OK, RESPONSE_RELEASE_SETUP, misdn_bchannel::restart_channel, and misdn_lib::user_data.

Referenced by manager_event_handler(), and manager_isdn_handler().

02769 {
02770    struct misdn_bchannel dummybc;
02771    struct misdn_bchannel *bc;
02772    iframe_t *frm;
02773    struct misdn_stack *stack;
02774    enum event_e event;
02775    enum event_response_e response;
02776    int ret;
02777    int channel;
02778    int tmpcause;
02779    int tmp_out_cause;
02780 
02781    frm = (iframe_t*) msg->data;
02782    stack = find_stack_by_addr(frm->addr);
02783    if (!stack || stack->nt) {
02784       return 0;
02785    }
02786 
02787    cb_log(4, stack ? stack->port : 0, "handle_frm: frm->addr:%x frm->prim:%x\n", frm->addr, frm->prim);
02788 
02789    ret = handle_cr(stack, frm);
02790    if (ret < 0) {
02791       cb_log(3, stack ? stack->port : 0, "handle_frm: handle_cr <0 prim:%x addr:%x\n", frm->prim, frm->addr);
02792    }
02793    if (ret) {
02794       free_msg(msg);
02795       return 1;
02796    }
02797 
02798    bc = find_bc_by_l3id(stack, frm->dinfo);
02799    if (!bc) {
02800       misdn_make_dummy(&dummybc, stack->port, 0, stack->nt, 0);
02801       switch (frm->prim) {
02802       case CC_RESTART | CONFIRM:
02803          dummybc.l3_id = MISDN_ID_GLOBAL;
02804          bc = &dummybc;
02805          break;
02806       case CC_SETUP | INDICATION:
02807          dummybc.l3_id = frm->dinfo;
02808          bc = &dummybc;
02809 
02810          misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE);
02811 
02812          free_msg(msg);
02813          return 1;
02814       default:
02815          if (frm->prim == (CC_FACILITY | INDICATION)) {
02816             cb_log(5, stack->port, " --> Using Dummy BC for FACILITY\n");
02817          } else {
02818             cb_log(0, stack->port, " --> Didn't find BC so temporarily creating dummy BC (l3id:%x) on this port.\n", frm->dinfo);
02819             dummybc.l3_id = frm->dinfo;
02820          }
02821          bc = &dummybc;
02822          break;
02823       }
02824    }
02825 
02826    event = isdn_msg_get_event(msgs_g, msg, 0);
02827    isdn_msg_parse_event(msgs_g, msg, bc, 0);
02828 
02829    /* Preprocess some Events */
02830    ret = handle_event(bc, event, frm);
02831    if (ret < 0) {
02832       cb_log(0, stack->port, "couldn't handle event\n");
02833       free_msg(msg);
02834       return 1;
02835    }
02836 
02837    /* shoot up event to App: */
02838    cb_log(5, stack->port, "lib Got Prim: Addr %x prim %x dinfo %x\n", frm->addr, frm->prim, frm->dinfo);
02839 
02840    if (!isdn_get_info(msgs_g, event, 0)) {
02841       cb_log(0, stack->port, "Unknown Event Ind: Addr:%x prim %x dinfo %x\n", frm->addr, frm->prim, frm->dinfo);
02842       response = RESPONSE_OK;
02843    } else {
02844       response = cb_event(event, bc, glob_mgr->user_data);
02845    }
02846 
02847    switch (event) {
02848    case EVENT_SETUP:
02849       switch (response) {
02850       case RESPONSE_IGNORE_SETUP_WITHOUT_CLOSE:
02851          cb_log(0, stack->port, "TOTALLY IGNORING SETUP\n");
02852          break;
02853       case RESPONSE_IGNORE_SETUP:
02854          /* I think we should send CC_RELEASE_CR, but am not sure*/
02855          bc->out_cause = AST_CAUSE_NORMAL_CLEARING;
02856          /* fall through */
02857       case RESPONSE_RELEASE_SETUP:
02858          misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE);
02859          if (bc->channel > 0) {
02860             empty_chan_in_stack(stack, bc->channel);
02861          }
02862          empty_bc(bc);
02863          bc_state_change(bc, BCHAN_CLEANED);
02864          bc->in_use = 0;
02865 
02866          cb_log(0, stack->port, "GOT IGNORE SETUP\n");
02867          break;
02868       case RESPONSE_OK:
02869          cb_log(4, stack->port, "GOT SETUP OK\n");
02870          break;
02871       default:
02872          break;
02873       }
02874       break;
02875    case EVENT_RELEASE_COMPLETE:
02876       /* release bchannel only after we've announced the RELEASE_COMPLETE */
02877       channel = bc->channel;
02878       tmpcause = bc->cause;
02879       tmp_out_cause = bc->out_cause;
02880 
02881       empty_bc(bc);
02882       bc->cause = tmpcause;
02883       bc->out_cause = tmp_out_cause;
02884       clean_up_bc(bc);
02885       bc->in_use = 0;
02886 
02887       if (tmpcause == AST_CAUSE_REQUESTED_CHAN_UNAVAIL) {
02888          cb_log(0, stack->port, "**** Received CAUSE:%d, restarting channel %d\n", AST_CAUSE_REQUESTED_CHAN_UNAVAIL, channel);
02889          misdn_lib_send_restart(stack->port, channel);
02890       }
02891       if (channel > 0) {
02892          empty_chan_in_stack(stack, channel);
02893       }
02894       break;
02895    case EVENT_RESTART:
02896       cb_log(0, stack->port, "**** Received RESTART channel:%d\n", bc->restart_channel);
02897       empty_chan_in_stack(stack, bc->restart_channel);
02898       break;
02899    default:
02900       break;
02901    }
02902 
02903    cb_log(5, stack->port, "Freeing Msg on prim:%x \n", frm->prim);
02904    free_msg(msg);
02905    return 1;
02906 }

static int handle_frm_nt ( msg_t *  msg  )  [static]

Definition at line 2733 of file isdn_lib.c.

References cb_log, find_stack_by_addr(), nt_err_cnt, pthread_mutex_lock, and pthread_mutex_unlock.

Referenced by manager_event_handler(), and manager_isdn_handler().

02734 {
02735    iframe_t *frm= (iframe_t*)msg->data;
02736    struct misdn_stack *stack;
02737    int err=0;
02738 
02739    stack=find_stack_by_addr( frm->addr );
02740 
02741 
02742 
02743    if (!stack || !stack->nt) {
02744       return 0;
02745    }
02746 
02747 
02748    pthread_mutex_lock(&stack->nstlock);
02749    if ((err=stack->nst.l1_l2(&stack->nst,msg))) {
02750       pthread_mutex_unlock(&stack->nstlock);
02751       if (nt_err_cnt > 0 ) {
02752          if (nt_err_cnt < 100) {
02753             nt_err_cnt++;
02754             cb_log(0, stack->port, "NT Stack sends us error: %d \n", err);
02755          } else if (nt_err_cnt < 105){
02756             cb_log(0, stack->port, "NT Stack sends us error: %d over 100 times, so I'll stop this message\n", err);
02757             nt_err_cnt = - 1;
02758          }
02759       }
02760       free_msg(msg);
02761       return 1;
02762    }
02763    pthread_mutex_unlock(&stack->nstlock);
02764    return 1;
02765 }

static int handle_l1 ( msg_t *  msg  )  [static]

Definition at line 2909 of file isdn_lib.c.

References cb_event, cb_log, EVENT_CLEANUP, EVENT_NOTHING, find_stack_by_addr(), glob_mgr, global_state, isdn_get_info(), MISDN_INITIALIZED, misdn_lib_get_l2_up(), misdn_lib_send_event(), msgs_g, pthread_mutex_lock, pthread_mutex_unlock, and misdn_lib::user_data.

Referenced by manager_isdn_handler().

02910 {
02911    iframe_t *frm = (iframe_t*) msg->data;
02912    struct misdn_stack *stack = find_stack_by_addr(frm->addr);
02913    int i ;
02914 
02915    if (!stack) return 0 ;
02916 
02917    switch (frm->prim) {
02918    case PH_ACTIVATE | CONFIRM:
02919    case PH_ACTIVATE | INDICATION:
02920       cb_log (3, stack->port, "L1: PH L1Link Up!\n");
02921       stack->l1link=1;
02922 
02923       if (stack->nt) {
02924 
02925          pthread_mutex_lock(&stack->nstlock);
02926          if (stack->nst.l1_l2(&stack->nst, msg))
02927             free_msg(msg);
02928          pthread_mutex_unlock(&stack->nstlock);
02929 
02930          if (stack->ptp)
02931             misdn_lib_get_l2_up(stack);
02932       } else {
02933          free_msg(msg);
02934       }
02935 
02936       for (i=0;i<=stack->b_num; i++) {
02937          if (stack->bc[i].evq != EVENT_NOTHING) {
02938             cb_log(4, stack->port, "Firing Queued Event %s because L1 got up\n", isdn_get_info(msgs_g, stack->bc[i].evq, 0));
02939             misdn_lib_send_event(&stack->bc[i],stack->bc[i].evq);
02940             stack->bc[i].evq=EVENT_NOTHING;
02941          }
02942 
02943       }
02944       return 1;
02945 
02946    case PH_ACTIVATE | REQUEST:
02947       free_msg(msg);
02948       cb_log(3,stack->port,"L1: PH_ACTIVATE|REQUEST \n");
02949       return 1;
02950 
02951    case PH_DEACTIVATE | REQUEST:
02952       free_msg(msg);
02953       cb_log(3,stack->port,"L1: PH_DEACTIVATE|REQUEST \n");
02954       return 1;
02955 
02956    case PH_DEACTIVATE | CONFIRM:
02957    case PH_DEACTIVATE | INDICATION:
02958       cb_log (3, stack->port, "L1: PH L1Link Down! \n");
02959 
02960 #if 0
02961       for (i=0; i<=stack->b_num; i++) {
02962          if (global_state == MISDN_INITIALIZED)  {
02963             cb_event(EVENT_CLEANUP, &stack->bc[i], glob_mgr->user_data);
02964          }
02965       }
02966 #endif
02967 
02968       if (stack->nt) {
02969          pthread_mutex_lock(&stack->nstlock);
02970          if (stack->nst.l1_l2(&stack->nst, msg))
02971             free_msg(msg);
02972          pthread_mutex_unlock(&stack->nstlock);
02973       } else {
02974          free_msg(msg);
02975       }
02976 
02977       stack->l1link=0;
02978       stack->l2link=0;
02979       return 1;
02980    }
02981 
02982    return 0;
02983 }

static int handle_l2 ( msg_t *  msg  )  [static]

Definition at line 2985 of file isdn_lib.c.

References cb_event, cb_log, EVENT_PORT_ALARM, find_stack_by_addr(), glob_mgr, and misdn_lib::user_data.

Referenced by manager_isdn_handler().

02986 {
02987    iframe_t *frm = (iframe_t*) msg->data;
02988 
02989    struct misdn_stack *stack = find_stack_by_addr(frm->addr);
02990 
02991    if (!stack) {
02992       return 0 ;
02993    }
02994 
02995    switch(frm->prim) {
02996 
02997    case DL_ESTABLISH | REQUEST:
02998       cb_log(1,stack->port,"DL_ESTABLISH|REQUEST \n");
02999       free_msg(msg);
03000       return 1;
03001    case DL_RELEASE | REQUEST:
03002       cb_log(1,stack->port,"DL_RELEASE|REQUEST \n");
03003       free_msg(msg);
03004       return 1;
03005 
03006    case DL_ESTABLISH | INDICATION:
03007    case DL_ESTABLISH | CONFIRM:
03008    {
03009       cb_log (3, stack->port, "L2: L2Link Up! \n");
03010       if (stack->ptp && stack->l2link) {
03011          cb_log (-1, stack->port, "L2: L2Link Up! but it's already UP.. must be faulty, blocking port\n");
03012          cb_event(EVENT_PORT_ALARM, &stack->bc[0], glob_mgr->user_data);
03013       }
03014       stack->l2link=1;
03015       free_msg(msg);
03016       return 1;
03017    }
03018    break;
03019 
03020    case DL_RELEASE | INDICATION:
03021    case DL_RELEASE | CONFIRM:
03022    {
03023       cb_log (3, stack->port, "L2: L2Link Down! \n");
03024       stack->l2link=0;
03025 
03026       free_msg(msg);
03027       return 1;
03028    }
03029    break;
03030    }
03031    return 0;
03032 }

static int handle_mgmt ( msg_t *  msg  )  [static]

Definition at line 3034 of file isdn_lib.c.

References cb_log, clear_l3(), and find_stack_by_addr().

Referenced by manager_isdn_handler().

03035 {
03036    iframe_t *frm = (iframe_t*) msg->data;
03037    struct misdn_stack *stack;
03038 
03039    if ( (frm->addr == 0) && (frm->prim == (MGR_DELLAYER|CONFIRM)) ) {
03040       cb_log(2, 0, "MGMT: DELLAYER|CONFIRM Addr: 0 !\n") ;
03041       free_msg(msg);
03042       return 1;
03043    }
03044 
03045    stack = find_stack_by_addr(frm->addr);
03046 
03047    if (!stack) {
03048       if (frm->prim == (MGR_DELLAYER|CONFIRM)) {
03049          cb_log(2, 0, "MGMT: DELLAYER|CONFIRM Addr: %x !\n",
03050                frm->addr) ;
03051          free_msg(msg);
03052          return 1;
03053       }
03054 
03055       return 0;
03056    }
03057 
03058    switch(frm->prim) {
03059    case MGR_SHORTSTATUS | INDICATION:
03060    case MGR_SHORTSTATUS | CONFIRM:
03061       cb_log(5, stack->port, "MGMT: Short status dinfo %x\n",frm->dinfo);
03062 
03063       switch (frm->dinfo) {
03064       case SSTATUS_L1_ACTIVATED:
03065          cb_log(3, stack->port, "MGMT: SSTATUS: L1_ACTIVATED \n");
03066          stack->l1link=1;
03067 
03068          break;
03069       case SSTATUS_L1_DEACTIVATED:
03070          cb_log(3, stack->port, "MGMT: SSTATUS: L1_DEACTIVATED \n");
03071          stack->l1link=0;
03072 #if 0
03073          clear_l3(stack);
03074 #endif
03075          break;
03076 
03077       case SSTATUS_L2_ESTABLISHED:
03078          cb_log(3, stack->port, "MGMT: SSTATUS: L2_ESTABLISH \n");
03079          stack->l2link=1;
03080          break;
03081 
03082       case SSTATUS_L2_RELEASED:
03083          cb_log(3, stack->port, "MGMT: SSTATUS: L2_RELEASED \n");
03084          stack->l2link=0;
03085          break;
03086       }
03087 
03088       free_msg(msg);
03089       return 1;
03090 
03091    case MGR_SETSTACK | INDICATION:
03092       cb_log(4, stack->port, "MGMT: SETSTACK|IND dinfo %x\n",frm->dinfo);
03093       free_msg(msg);
03094       return 1;
03095    case MGR_DELLAYER | CONFIRM:
03096       cb_log(4, stack->port, "MGMT: DELLAYER|CNF dinfo %x\n",frm->dinfo) ;
03097       free_msg(msg);
03098       return 1;
03099 
03100    }
03101 
03102    /*
03103    if ( (frm->prim & 0x0f0000) ==  0x0f0000) {
03104    cb_log(5, 0, "$$$ MGMT FRAME: prim %x addr %x dinfo %x\n",frm->prim, frm->addr, frm->dinfo) ;
03105    free_msg(msg);
03106    return 1;
03107    } */
03108 
03109    return 0;
03110 }

static int handle_timers ( msg_t *  msg  )  [static]

Definition at line 2285 of file isdn_lib.c.

References cb_log, glob_mgr, misdn_stack::midev, misdn_stack::next, misdn_stack::nst, misdn_stack::nstlock, misdn_stack::nt, pthread_mutex_lock, pthread_mutex_unlock, and misdn_lib::stack_list.

Referenced by manager_isdn_handler().

02286 {
02287    iframe_t *frm= (iframe_t*)msg->data;
02288    struct misdn_stack *stack;
02289 
02290    /* Timer Stuff */
02291    switch (frm->prim) {
02292    case MGR_INITTIMER | CONFIRM:
02293    case MGR_ADDTIMER | CONFIRM:
02294    case MGR_DELTIMER | CONFIRM:
02295    case MGR_REMOVETIMER | CONFIRM:
02296       free_msg(msg);
02297       return(1);
02298    }
02299 
02300 
02301 
02302    if (frm->prim==(MGR_TIMER | INDICATION) ) {
02303       for (stack = glob_mgr->stack_list;
02304            stack;
02305            stack = stack->next) {
02306          itimer_t *it;
02307 
02308          if (!stack->nt) continue;
02309 
02310          it = stack->nst.tlist;
02311          /* find timer */
02312          for(it=stack->nst.tlist;
02313              it;
02314              it=it->next) {
02315             if (it->id == (int)frm->addr)
02316                break;
02317          }
02318          if (it) {
02319             int ret;
02320             ret = mISDN_write_frame(stack->midev, msg->data, frm->addr,
02321                      MGR_TIMER | RESPONSE, 0, 0, NULL, TIMEOUT_1SEC);
02322             test_and_clear_bit(FLG_TIMER_RUNING, (long unsigned int *)&it->Flags);
02323             pthread_mutex_lock(&stack->nstlock);
02324             ret = it->function(it->data);
02325             pthread_mutex_unlock(&stack->nstlock);
02326             free_msg(msg);
02327             return 1;
02328          }
02329       }
02330 
02331       cb_log(0, 0, "Timer Msg without Timer ??\n");
02332       free_msg(msg);
02333       return 1;
02334    }
02335 
02336    return 0;
02337 }

static int init_bc ( struct misdn_stack stack,
struct misdn_bchannel bc,
int  midev,
int  port,
int  bidx 
) [static]

IFACE

Definition at line 1245 of file isdn_lib.c.

References misdn_bchannel::astbuf, misdn_stack::b_num, misdn_stack::bc, bc_state_change(), BCHAN_CLEANED, buff, cb_log, empty_bc(), send_lock::lock, malloc, MISDN_IBUF_SIZE, misdn_stack::nt, misdn_bchannel::nt, misdn_stack::port, misdn_bchannel::port, misdn_stack::pri, misdn_bchannel::pri, pthread_mutex_init, and misdn_bchannel::send_lock.

Referenced by misdn_lib_init().

01246 {
01247    if (!bc) {
01248       return -1;
01249    }
01250 
01251    cb_log(8, port, "Init.BC %d.\n",bidx);
01252 
01253    bc->send_lock=malloc(sizeof(struct send_lock));
01254    if (!bc->send_lock) {
01255       return -1;
01256    }
01257    pthread_mutex_init(&bc->send_lock->lock, NULL);
01258 
01259    empty_bc(bc);
01260    bc_state_change(bc, BCHAN_CLEANED);
01261 
01262    bc->port=stack->port;
01263    bc->nt=stack->nt?1:0;
01264    bc->pri=stack->pri;
01265 
01266    {
01267       ibuffer_t* ibuf= init_ibuffer(MISDN_IBUF_SIZE);
01268 
01269       if (!ibuf) return -1;
01270 
01271       clear_ibuffer( ibuf);
01272 
01273       ibuf->rsem=malloc(sizeof(sem_t));
01274       if (!ibuf->rsem) {
01275          return -1;
01276       }
01277 
01278       bc->astbuf=ibuf;
01279 
01280       if (sem_init(ibuf->rsem,1,0)<0)
01281          sem_init(ibuf->rsem,0,0);
01282 
01283    }
01284 
01285 #if 0 /* This code does not seem to do anything useful */
01286    if (bidx <= stack->b_num) {
01287       unsigned char buff[1025];
01288       iframe_t *frm = (iframe_t *) buff;
01289       stack_info_t *stinf;
01290       int ret;
01291 
01292       ret = mISDN_get_stack_info(midev, stack->port, buff, sizeof(buff));
01293       if (ret < 0) {
01294          cb_log(0, port, "%s: Cannot get stack info for this port. (ret=%d)\n", __FUNCTION__, ret);
01295          return -1;
01296       }
01297 
01298       stinf = (stack_info_t *)&frm->data.p;
01299 
01300       cb_log(8, port, " --> Child %x\n",stinf->child[bidx]);
01301    }
01302 #endif
01303 
01304    return 0;
01305 }

static void init_flip_bits ( void   )  [static]

Definition at line 325 of file isdn_lib.c.

Referenced by misdn_lib_init().

00326 {
00327    int i,k;
00328 
00329    for (i = 0 ; i < 256 ; i++) {
00330       unsigned char sample = 0 ;
00331       for (k = 0; k<8; k++) {
00332          if ( i & 1 << k ) sample |= 0x80 >>  k;
00333       }
00334       flip_table[i] = sample;
00335    }
00336 }

void isdn_lib_stop_dtmf ( struct misdn_bchannel bc  ) 

Definition at line 4633 of file isdn_lib.c.

References misdn_stack::bc, and manager_ph_control().

Referenced by process_ast_dsp().

04634 {
04635    manager_ph_control(bc, DTMF_TONE_STOP, 0);
04636 }

void isdn_lib_update_ec ( struct misdn_bchannel bc  ) 

Definition at line 4621 of file isdn_lib.c.

References misdn_stack::bc, misdn_bchannel::ec_enable, manager_ec_disable(), and manager_ec_enable().

Referenced by process_ast_dsp().

04622 {
04623 #ifdef MISDN_1_2
04624    if (*bc->pipeline)
04625 #else
04626    if (bc->ec_enable)
04627 #endif
04628       manager_ec_enable(bc);
04629    else
04630       manager_ec_disable(bc);
04631 }

void isdn_lib_update_rxgain ( struct misdn_bchannel bc  ) 

Definition at line 4611 of file isdn_lib.c.

References misdn_stack::bc, manager_ph_control(), and misdn_bchannel::rxgain.

Referenced by process_ast_dsp().

04612 {
04613    manager_ph_control(bc, VOL_CHANGE_RX, bc->rxgain);
04614 }

void isdn_lib_update_txgain ( struct misdn_bchannel bc  ) 

Definition at line 4616 of file isdn_lib.c.

References misdn_stack::bc, manager_ph_control(), and misdn_bchannel::txgain.

Referenced by process_ast_dsp().

04617 {
04618    manager_ph_control(bc, VOL_CHANGE_TX, bc->txgain);
04619 }

void manager_bchannel_activate ( struct misdn_bchannel bc  ) 

Definition at line 4494 of file isdn_lib.c.

References misdn_bchannel::addr, misdn_bchannel::astbuf, misdn_stack::bc, cb_log, get_stack_by_bc(), misdn_stack::midev, misdn_bchannel::port, and misdn_stack::port.

04495 {
04496    char buf[128];
04497 
04498    struct misdn_stack *stack=get_stack_by_bc(bc);
04499 
04500    if (!stack) {
04501       cb_log(0, bc->port, "bchannel_activate: Stack not found !");
04502       return ;
04503    }
04504 
04505    /* we must activate if we are deactivated */
04506    clear_ibuffer(bc->astbuf);
04507 
04508    cb_log(5, stack->port, "$$$ Bchan Activated addr %x\n", bc->addr);
04509 
04510    mISDN_write_frame(stack->midev, buf, bc->addr | FLG_MSG_DOWN,  DL_ESTABLISH | REQUEST, 0,0, NULL, TIMEOUT_1SEC);
04511 
04512    return ;
04513 }

void manager_bchannel_cleanup ( struct misdn_bchannel bc  ) 

void manager_bchannel_deactivate ( struct misdn_bchannel bc  ) 

Definition at line 4516 of file isdn_lib.c.

References misdn_bchannel::addr, misdn_bchannel::astbuf, misdn_stack::bc, misdn_bchannel::bc_state, bc_state_change(), BCHAN_ACTIVATED, BCHAN_BRIDGED, BCHAN_RELEASE, cb_log, misdn_bchannel::conf_id, misdn_bchannel::generate_tone, get_stack_by_bc(), misdn_stack::midev, misdn_split_conf(), misdn_bchannel::port, and misdn_stack::port.

Referenced by clean_up_bc().

04517 {
04518    struct misdn_stack *stack=get_stack_by_bc(bc);
04519    iframe_t dact;
04520    char buf[128];
04521 
04522    switch (bc->bc_state) {
04523       case BCHAN_ACTIVATED:
04524          break;
04525       case BCHAN_BRIDGED:
04526          misdn_split_conf(bc,bc->conf_id);
04527          break;
04528       default:
04529          cb_log( 4, bc->port,"bchan_deactivate: called but not activated\n");
04530          return ;
04531 
04532    }
04533 
04534    cb_log(5, stack->port, "$$$ Bchan deActivated addr %x\n", bc->addr);
04535 
04536    bc->generate_tone=0;
04537 
04538    dact.prim = DL_RELEASE | REQUEST;
04539    dact.addr = bc->addr | FLG_MSG_DOWN;
04540    dact.dinfo = 0;
04541    dact.len = 0;
04542    mISDN_write_frame(stack->midev, buf, bc->addr | FLG_MSG_DOWN, DL_RELEASE|REQUEST,0,0,NULL, TIMEOUT_1SEC);
04543 
04544    clear_ibuffer(bc->astbuf);
04545 
04546    bc_state_change(bc,BCHAN_RELEASE);
04547 
04548    return;
04549 }

void manager_bchannel_setup ( struct misdn_bchannel bc  ) 

void manager_clean_bc ( struct misdn_bchannel bc  ) 

Definition at line 4660 of file isdn_lib.c.

References misdn_stack::bc, cb_event, misdn_bchannel::channel, empty_bc(), empty_chan_in_stack(), EVENT_CLEANUP, get_stack_by_bc(), and misdn_bchannel::in_use.

Referenced by misdn_lib_pid_restart().

04661 {
04662    struct misdn_stack *stack=get_stack_by_bc(bc);
04663 
04664    if (stack && bc->channel > 0) {
04665       empty_chan_in_stack(stack, bc->channel);
04666    }
04667    empty_bc(bc);
04668    bc->in_use=0;
04669 
04670    cb_event(EVENT_CLEANUP, bc, NULL);
04671 }

void manager_ec_disable ( struct misdn_bchannel bc  ) 

Definition at line 4850 of file isdn_lib.c.

References misdn_stack::bc, misdn_bchannel::capability, cb_log, misdn_bchannel::ec_enable, ECHOCAN_OFF, get_stack_by_bc(), manager_ph_control(), manager_ph_control_block(), misdn_cap_is_speech(), and misdn_stack::port.

Referenced by clean_up_bc(), handle_cli_misdn_toggle_echocancel(), and isdn_lib_update_ec().

04851 {
04852    struct misdn_stack *stack=get_stack_by_bc(bc);
04853 
04854    cb_log(4, stack?stack->port:0," --> ec_disable\n");
04855 
04856    if (!misdn_cap_is_speech(bc->capability)) {
04857       cb_log(1, stack?stack->port:0, " --> no speech? cannot disable EC\n");
04858       return;
04859    }
04860 
04861 #ifdef MISDN_1_2
04862    manager_ph_control_block(bc, PIPELINE_CFG, "", 0);
04863 #else
04864    if ( ! bc->ec_enable) {
04865       cb_log(3, stack?stack->port:0, "Sending Control ECHOCAN_OFF\n");
04866       manager_ph_control(bc,  ECHOCAN_OFF, 0);
04867    }
04868 #endif
04869 }

void manager_ec_enable ( struct misdn_bchannel bc  ) 

Definition at line 4801 of file isdn_lib.c.

References misdn_stack::bc, misdn_bchannel::capability, cb_log, misdn_bchannel::ec_deftaps, misdn_bchannel::ec_enable, ECHOCAN_ON, get_stack_by_bc(), manager_ph_control_block(), misdn_cap_is_speech(), and misdn_stack::port.

Referenced by handle_cli_misdn_toggle_echocancel(), handle_event(), isdn_lib_update_ec(), and misdn_lib_send_event().

04802 {
04803    struct misdn_stack *stack=get_stack_by_bc(bc);
04804 
04805    cb_log(4, stack?stack->port:0,"ec_enable\n");
04806 
04807    if (!misdn_cap_is_speech(bc->capability)) {
04808       cb_log(1, stack?stack->port:0, " --> no speech? cannot enable EC\n");
04809    } else {
04810 
04811 #ifdef MISDN_1_2
04812    if (*bc->pipeline) {
04813       cb_log(3, stack?stack->port:0,"Sending Control PIPELINE_CFG %s\n",bc->pipeline);
04814       manager_ph_control_block(bc, PIPELINE_CFG, bc->pipeline, strlen(bc->pipeline) + 1);
04815    }
04816 #else
04817    int ec_arr[2];
04818 
04819    if (bc->ec_enable) {
04820       cb_log(3, stack?stack->port:0,"Sending Control ECHOCAN_ON taps:%d\n",bc->ec_deftaps);
04821 
04822       switch (bc->ec_deftaps) {
04823       case 4:
04824       case 8:
04825       case 16:
04826       case 32:
04827       case 64:
04828       case 128:
04829       case 256:
04830       case 512:
04831       case 1024:
04832          cb_log(4, stack->port, "Taps is %d\n",bc->ec_deftaps);
04833          break;
04834       default:
04835          cb_log(0, stack->port, "Taps should be power of 2\n");
04836          bc->ec_deftaps=128;
04837       }
04838 
04839       ec_arr[0]=bc->ec_deftaps;
04840       ec_arr[1]=0;
04841 
04842       manager_ph_control_block(bc,  ECHOCAN_ON,  ec_arr, sizeof(ec_arr));
04843    }
04844 #endif
04845    }
04846 }

static void manager_event_handler ( void *  arg  )  [static]

Definition at line 4193 of file isdn_lib.c.

References misdn_lib::activatequeue, cb_log, clean_up_bc(), misdn_stack::downqueue, find_bc_by_l3id(), find_stack_by_port(), glob_mgr, handle_frm(), handle_frm_nt(), misdn_lib::midev, misdn_make_dummy(), misdn_lib::new_msg, misdn_stack::next, misdn_stack::nst, misdn_stack::nstlock, misdn_stack::nt, misdn_stack::port, misdn_bchannel::port, pthread_mutex_lock, pthread_mutex_unlock, send_msg(), misdn_lib::stack_list, and misdn_stack::upqueue.

Referenced by misdn_lib_init().

04194 {
04195    sem_post(&handler_started);
04196    while (1) {
04197       struct misdn_stack *stack;
04198       msg_t *msg;
04199 
04200       /** wait for events **/
04201       sem_wait(&glob_mgr->new_msg);
04202 
04203       for (msg=msg_dequeue(&glob_mgr->activatequeue);
04204            msg;
04205            msg=msg_dequeue(&glob_mgr->activatequeue)
04206          )
04207       {
04208 
04209          iframe_t *frm =  (iframe_t*) msg->data ;
04210 
04211          switch ( frm->prim) {
04212 
04213          case MGR_CLEARSTACK | REQUEST:
04214             /*a queued bchannel cleanup*/
04215             {
04216                struct misdn_stack *stack=find_stack_by_port(frm->dinfo);
04217                struct misdn_bchannel *bc;
04218                if (!stack) {
04219                   cb_log(0,0,"no stack found with port [%d]!! so we cannot cleanup the bc\n",frm->dinfo);
04220                   free_msg(msg);
04221                   break;
04222                }
04223 
04224                bc = find_bc_by_l3id(stack, frm->addr);
04225                if (bc) {
04226                   cb_log(1,bc->port,"CLEARSTACK queued, cleaning up\n");
04227                   clean_up_bc(bc);
04228                } else {
04229                   cb_log(0,stack->port,"bc could not be cleaned correctly !! addr [%x]\n",frm->addr);
04230                }
04231             }
04232             free_msg(msg);
04233             break;
04234          case MGR_SETSTACK | REQUEST :
04235             free_msg(msg);
04236             break;
04237          default:
04238             mISDN_write(glob_mgr->midev, frm, mISDN_HEADER_LEN+frm->len, TIMEOUT_1SEC);
04239             free_msg(msg);
04240          }
04241       }
04242 
04243       for (stack=glob_mgr->stack_list;
04244            stack;
04245            stack=stack->next ) {
04246 
04247          while ( (msg=msg_dequeue(&stack->upqueue)) ) {
04248             /** Handle L2/3 Signalling after bchans **/
04249             if (!handle_frm_nt(msg)) {
04250                /* Maybe it's TE */
04251                if (!handle_frm(msg)) {
04252                   /* wow none! */
04253                   cb_log(0,stack->port,"Wow we've got a strange issue while dequeueing a Frame\n");
04254                }
04255             }
04256          }
04257 
04258          /* Here we should check if we really want to
04259             send all the messages we've queued, lets
04260             assume we've queued a Disconnect, but
04261             received it already from the other side!*/
04262 
04263          while ( (msg=msg_dequeue(&stack->downqueue)) ) {
04264             if (stack->nt ) {
04265                pthread_mutex_lock(&stack->nstlock);
04266                if (stack->nst.manager_l3(&stack->nst, msg))
04267                   cb_log(0, stack->port, "Error@ Sending Message in NT-Stack.\n");
04268                pthread_mutex_unlock(&stack->nstlock);
04269             } else {
04270                iframe_t *frm = (iframe_t *)msg->data;
04271                struct misdn_bchannel *bc = find_bc_by_l3id(stack, frm->dinfo);
04272                if (bc)
04273                   send_msg(glob_mgr->midev, bc, msg);
04274                else  {
04275                   if (frm->dinfo == MISDN_ID_GLOBAL || frm->dinfo == MISDN_ID_DUMMY ) {
04276                      struct misdn_bchannel dummybc;
04277                      cb_log(5,0," --> GLOBAL/DUMMY\n");
04278                      misdn_make_dummy(&dummybc, stack->port, frm->dinfo, stack->nt, 0);
04279                      send_msg(glob_mgr->midev, &dummybc, msg);
04280                   } else {
04281                      cb_log(0,0,"No bc for Message\n");
04282                   }
04283                }
04284             }
04285          }
04286       }
04287    }
04288 }

struct misdn_bchannel * manager_find_bc_by_pid ( int  pid  ) 

Definition at line 3253 of file isdn_lib.c.

References misdn_stack::b_num, misdn_stack::bc, glob_mgr, misdn_bchannel::in_use, misdn_stack::next, misdn_bchannel::pid, and misdn_lib::stack_list.

Referenced by misdn_lib_pid_restart().

03254 {
03255    struct misdn_stack *stack;
03256    int i;
03257 
03258    for (stack = glob_mgr->stack_list; stack; stack = stack->next) {
03259       for (i = 0; i <= stack->b_num; i++) {
03260          if (stack->bc[i].in_use && stack->bc[i].pid == pid) {
03261             return &stack->bc[i];
03262          }
03263       }
03264    }
03265 
03266    return NULL;
03267 }

char* manager_isdn_get_info ( enum event_e  event  ) 

Definition at line 4489 of file isdn_lib.c.

References isdn_get_info(), and msgs_g.

Referenced by cb_events().

04490 {
04491    return isdn_get_info(msgs_g , event, 0);
04492 }

int manager_isdn_handler ( iframe_t *  frm,
msg_t *  msg 
)

Definition at line 3982 of file isdn_lib.c.

References cb_log, handle_bchan(), handle_err(), handle_frm(), handle_frm_nt(), handle_l1(), handle_l2(), handle_mgmt(), handle_timers(), LOG_NOTICE, and misdn_stack::port.

Referenced by misdn_lib_isdn_event_catcher().

03983 {
03984 
03985    if (frm->dinfo==0xffffffff && frm->prim==(PH_DATA|CONFIRM)) {
03986       cb_log(0,0,"SERIOUS BUG, dinfo == 0xffffffff, prim == PH_DATA | CONFIRM !!!!\n");
03987    }
03988 
03989    if ( ((frm->addr | ISDN_PID_BCHANNEL_BIT )>> 28 ) == 0x5) {
03990       static int unhandled_bmsg_count=1000;
03991       if (handle_bchan(msg)) {
03992          return 0 ;
03993       }
03994 
03995       if (unhandled_bmsg_count==1000) {
03996          cb_log(0, 0, "received 1k Unhandled Bchannel Messages: prim %x len %d from addr %x, dinfo %x on this port.\n",frm->prim, frm->len, frm->addr, frm->dinfo);
03997          unhandled_bmsg_count=0;
03998       }
03999 
04000       unhandled_bmsg_count++;
04001       free_msg(msg);
04002       return 0;
04003    }
04004 
04005 #ifdef RECV_FRM_SYSLOG_DEBUG
04006    syslog(LOG_NOTICE,"mISDN recv: P(%02d): ADDR:%x PRIM:%x DINFO:%x\n",stack->port, frm->addr, frm->prim, frm->dinfo);
04007 #endif
04008 
04009    if (handle_timers(msg))
04010       return 0 ;
04011 
04012 
04013    if (handle_mgmt(msg))
04014       return 0 ;
04015 
04016    if (handle_l2(msg))
04017       return 0 ;
04018 
04019    /* Its important to handle l1 AFTER l2  */
04020    if (handle_l1(msg))
04021       return 0 ;
04022 
04023    if (handle_frm_nt(msg)) {
04024       return 0;
04025    }
04026 
04027    if (handle_frm(msg)) {
04028       return 0;
04029    }
04030 
04031    if (handle_err(msg)) {
04032       return 0 ;
04033    }
04034 
04035    cb_log(0, 0, "Unhandled Message: prim %x len %d from addr %x, dinfo %x on this port.\n",frm->prim, frm->len, frm->addr, frm->dinfo);
04036    free_msg(msg);
04037 
04038 
04039    return 0;
04040 }

void manager_ph_control ( struct misdn_bchannel bc,
int  c1,
int  c2 
)

Definition at line 4590 of file isdn_lib.c.

References misdn_bchannel::addr, misdn_stack::bc, cb_log, glob_mgr, misdn_lib::midev, and misdn_bchannel::port.

Referenced by handle_event(), isdn_lib_stop_dtmf(), isdn_lib_update_rxgain(), isdn_lib_update_txgain(), manager_ec_disable(), misdn_join_conf(), misdn_lib_echo(), misdn_lib_send_event(), misdn_lib_send_tone(), and misdn_split_conf().

04591 {
04592    unsigned char buffer[mISDN_HEADER_LEN+2*sizeof(int)];
04593    iframe_t *ctrl = (iframe_t *)buffer; /* preload data */
04594    unsigned int *d = (unsigned int*)&ctrl->data.p;
04595    /*struct misdn_stack *stack=get_stack_by_bc(bc);*/
04596 
04597    cb_log(4,bc->port,"ph_control: c1:%x c2:%x\n",c1,c2);
04598 
04599    ctrl->prim = PH_CONTROL | REQUEST;
04600    ctrl->addr = bc->addr | FLG_MSG_DOWN;
04601    ctrl->dinfo = 0;
04602    ctrl->len = sizeof(unsigned int)*2;
04603    *d++ = c1;
04604    *d++ = c2;
04605    mISDN_write(glob_mgr->midev, ctrl, mISDN_HEADER_LEN+ctrl->len, TIMEOUT_1SEC);
04606 }

void manager_ph_control_block ( struct misdn_bchannel bc,
int  c1,
void *  c2,
int  c2_len 
)

Definition at line 4641 of file isdn_lib.c.

References misdn_bchannel::addr, misdn_stack::bc, glob_mgr, and misdn_lib::midev.

Referenced by handle_event(), manager_ec_disable(), manager_ec_enable(), and misdn_lib_send_event().

04642 {
04643    unsigned char buffer[mISDN_HEADER_LEN+sizeof(int)+c2_len];
04644    iframe_t *ctrl = (iframe_t *)buffer;
04645    unsigned int *d = (unsigned int *)&ctrl->data.p;
04646    /*struct misdn_stack *stack=get_stack_by_bc(bc);*/
04647 
04648    ctrl->prim = PH_CONTROL | REQUEST;
04649    ctrl->addr = bc->addr | FLG_MSG_DOWN;
04650    ctrl->dinfo = 0;
04651    ctrl->len = sizeof(unsigned int) + c2_len;
04652    *d++ = c1;
04653    memcpy(d, c2, c2_len);
04654    mISDN_write(glob_mgr->midev, ctrl, mISDN_HEADER_LEN+ctrl->len, TIMEOUT_1SEC);
04655 }

int misdn_cap_is_speech ( int  cap  ) 

Poor mans version

Definition at line 440 of file isdn_lib.c.

References INFO_CAPABILITY_DIGITAL_RESTRICTED, and INFO_CAPABILITY_DIGITAL_UNRESTRICTED.

Referenced by cb_events(), handle_bchan(), handle_event(), manager_ec_disable(), manager_ec_enable(), misdn_lib_send_event(), and misdn_lib_tx2misdn_frm().

00442 {
00443    if ( (cap != INFO_CAPABILITY_DIGITAL_UNRESTRICTED) &&
00444         (cap != INFO_CAPABILITY_DIGITAL_RESTRICTED) ) return 1;
00445    return 0;
00446 }

void misdn_dump_chanlist ( void   ) 

Definition at line 487 of file isdn_lib.c.

References dump_chan_list(), get_misdn_stack(), and misdn_stack::next.

Referenced by handle_cli_misdn_show_channels().

00488 {
00489    struct misdn_stack *stack=get_misdn_stack();
00490    for ( ; stack; stack=stack->next) {
00491       dump_chan_list(stack);
00492    }
00493 
00494 }

int misdn_inband_avail ( struct misdn_bchannel bc  ) 

Definition at line 448 of file isdn_lib.c.

References misdn_bchannel::early_bconnect, INFO_PI_CALL_NOT_E2E_ISDN, INFO_PI_CALLED_NOT_ISDN, INFO_PI_INBAND_AVAILABLE, and misdn_bchannel::progress_indicator.

Referenced by cb_events().

00449 {
00450 
00451    if (!bc->early_bconnect) {
00452       /* We have opted to never receive any available inband recorded messages */
00453       return 0;
00454    }
00455 
00456    switch (bc->progress_indicator) {
00457    case INFO_PI_INBAND_AVAILABLE:
00458    case INFO_PI_CALL_NOT_E2E_ISDN:
00459    case INFO_PI_CALLED_NOT_ISDN:
00460       return 1;
00461    default:
00462       return 0;
00463    }
00464    return 0;
00465 }

void misdn_join_conf ( struct misdn_bchannel bc,
int  conf_id 
)

Definition at line 4878 of file isdn_lib.c.

References misdn_bchannel::addr, misdn_stack::bc, bc_state_change(), BCHAN_BRIDGED, cb_log, manager_ph_control(), misdn_lib_tx2misdn_frm(), and misdn_bchannel::port.

Referenced by bc_state_change(), and misdn_lib_bridge().

04879 {
04880    char data[16] = "";
04881 
04882    bc_state_change(bc,BCHAN_BRIDGED);
04883    manager_ph_control(bc, CMX_RECEIVE_OFF, 0);
04884    manager_ph_control(bc, CMX_CONF_JOIN, conf_id);
04885 
04886    cb_log(3,bc->port, "Joining bc:%x in conf:%d\n",bc->addr,conf_id);
04887 
04888    misdn_lib_tx2misdn_frm(bc, data, sizeof(data) - 1);
04889 }

void misdn_lib_bridge ( struct misdn_bchannel bc1,
struct misdn_bchannel bc2 
)

Definition at line 4901 of file isdn_lib.c.

References bc_next_state_change(), BCHAN_ACTIVATED, BCHAN_BRIDGED, cb_log, misdn_join_conf(), misdn_bchannel::pid, and misdn_bchannel::port.

Referenced by misdn_bridge().

04902 {
04903    int conf_id = bc1->pid + 1;
04904    struct misdn_bchannel *bc_list[] = { bc1, bc2, NULL };
04905    struct misdn_bchannel **bc;
04906 
04907    cb_log(4, bc1->port, "I Send: BRIDGE from:%d to:%d\n",bc1->port,bc2->port);
04908 
04909    for (bc=bc_list; *bc;  bc++) {
04910       (*bc)->conf_id=conf_id;
04911       cb_log(4, (*bc)->port, " --> bc_addr:%x\n",(*bc)->addr);
04912 
04913       switch((*bc)->bc_state) {
04914          case BCHAN_ACTIVATED:
04915             misdn_join_conf(*bc,conf_id);
04916             break;
04917          default:
04918             bc_next_state_change(*bc,BCHAN_BRIDGED);
04919             break;
04920       }
04921    }
04922 }

void misdn_lib_destroy ( void   ) 

Definition at line 4456 of file isdn_lib.c.

References misdn_bchannel::addr, misdn_stack::b_num, misdn_stack::bc, cb_log, misdn_lib::event_handler_thread, misdn_lib::event_thread, glob_mgr, global_state, misdn_stack::midev, misdn_lib::midev, MISDN_INITIALIZED, misdn_stack::next, misdn_stack::port, stack_destroy(), misdn_lib::stack_list, and te_lib_destroy().

Referenced by unload_module().

04457 {
04458    struct misdn_stack *help;
04459    int i;
04460 
04461    for ( help=glob_mgr->stack_list; help; help=help->next ) {
04462       for(i=0;i<=help->b_num; i++) {
04463          char buf[1024];
04464          mISDN_write_frame(help->midev, buf, help->bc[i].addr, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
04465          help->bc[i].addr = 0;
04466       }
04467       cb_log (1, help->port, "Destroying this port.\n");
04468       stack_destroy(help);
04469    }
04470 
04471    if (global_state == MISDN_INITIALIZED) {
04472       cb_log(4, 0, "Killing Handler Thread\n");
04473       if ( pthread_cancel(glob_mgr->event_handler_thread) == 0 ) {
04474          cb_log(4, 0, "Joining Handler Thread\n");
04475          pthread_join(glob_mgr->event_handler_thread, NULL);
04476       }
04477 
04478       cb_log(4, 0, "Killing Main Thread\n");
04479       if ( pthread_cancel(glob_mgr->event_thread) == 0 ) {
04480          cb_log(4, 0, "Joining Main Thread\n");
04481          pthread_join(glob_mgr->event_thread, NULL);
04482       }
04483    }
04484 
04485    cb_log(1, 0, "Closing mISDN device\n");
04486    te_lib_destroy(glob_mgr->midev);
04487 }

void misdn_lib_echo ( struct misdn_bchannel bc,
int  onoff 
)

Definition at line 4944 of file isdn_lib.c.

References cb_log, manager_ph_control(), and misdn_bchannel::port.

04945 {
04946    cb_log(3,bc->port, " --> ECHO %s\n", onoff?"ON":"OFF");
04947    manager_ph_control(bc, onoff?CMX_ECHO_ON:CMX_ECHO_OFF, 0);
04948 }

struct misdn_bchannel* misdn_lib_find_held_bc ( int  port,
int  l3_id 
)

Find a held call's B channel record.

Parameters:
port Port the call is on.
l3_id mISDN Layer 3 ID of held call.
Returns:
Found bc-record or NULL.

Definition at line 4753 of file isdn_lib.c.

References misdn_stack::bc, get_misdn_stack(), misdn_stack::next, misdn_stack::port, and stack_holder_find().

Referenced by misdn_hangup().

04754 {
04755    struct misdn_bchannel *bc;
04756    struct misdn_stack *stack;
04757 
04758    bc = NULL;
04759    for (stack = get_misdn_stack(); stack; stack = stack->next) {
04760       if (stack->port == port) {
04761          bc = stack_holder_find(stack, l3_id);
04762          break;
04763       }
04764    }
04765 
04766    return bc;
04767 }

struct misdn_bchannel* misdn_lib_get_free_bc ( int  port,
int  channel,
int  inout,
int  dec 
)

Definition at line 3312 of file isdn_lib.c.

References misdn_stack::b_num, misdn_stack::bc, misdn_stack::blocked, cb_log, misdn_bchannel::channel, find_stack_by_port(), MAX_BCHANS, prepare_bc(), pthread_mutex_lock, pthread_mutex_unlock, misdn_stack::st_lock, and test_inuse().

Referenced by handle_cr(), handle_event_nt(), and misdn_request().

03313 {
03314    struct misdn_stack *stack;
03315    int i;
03316    int maxnum;
03317 
03318    if (channel < 0 || channel > MAX_BCHANS) {
03319       cb_log(0, port, "Requested channel out of bounds (%d)\n", channel);
03320       return NULL;
03321    }
03322 
03323    /* Find the port stack structure */
03324    stack = find_stack_by_port(port);
03325    if (!stack) {
03326       cb_log(0, port, "Port is not configured (%d)\n", port);
03327       return NULL;
03328    }
03329 
03330    if (stack->blocked) {
03331       cb_log(0, port, "Port is blocked\n");
03332       return NULL;
03333    }
03334 
03335    pthread_mutex_lock(&stack->st_lock);
03336    if (channel > 0) {
03337       if (channel <= stack->b_num) {
03338          for (i = 0; i < stack->b_num; i++) {
03339             if (stack->bc[i].channel == channel) {
03340                if (test_inuse(&stack->bc[i])) {
03341                   pthread_mutex_unlock(&stack->st_lock);
03342                   cb_log(0, port, "Requested channel:%d on port:%d is already in use\n", channel, port);
03343                   return NULL;
03344                } else {
03345                   prepare_bc(&stack->bc[i], channel);
03346                   pthread_mutex_unlock(&stack->st_lock);
03347                   return &stack->bc[i];
03348                }
03349             }
03350          }
03351       } else {
03352          pthread_mutex_unlock(&stack->st_lock);
03353          cb_log(0, port, "Requested channel:%d is out of bounds on port:%d\n", channel, port);
03354          return NULL;
03355       }
03356    }
03357 
03358    /* Note: channel == 0 here */
03359    maxnum = (inout && !stack->pri && !stack->ptp) ? stack->b_num + 1 : stack->b_num;
03360    if (dec) {
03361       for (i = maxnum - 1; i >= 0; --i) {
03362          if (!test_inuse(&stack->bc[i])) {
03363             /* 3. channel on bri means CW*/
03364             if (!stack->pri && i == stack->b_num) {
03365                stack->bc[i].cw = 1;
03366             }
03367 
03368             prepare_bc(&stack->bc[i], channel);
03369             stack->bc[i].dec = 1;
03370             pthread_mutex_unlock(&stack->st_lock);
03371             return &stack->bc[i];
03372          }
03373       }
03374    } else {
03375       for (i = 0; i < maxnum; ++i) {
03376          if (!test_inuse(&stack->bc[i])) {
03377             /* 3. channel on bri means CW */
03378             if (!stack->pri && i == stack->b_num) {
03379                stack->bc[i].cw = 1;
03380             }
03381 
03382             prepare_bc(&stack->bc[i], channel);
03383             pthread_mutex_unlock(&stack->st_lock);
03384             return &stack->bc[i];
03385          }
03386       }
03387    }
03388    pthread_mutex_unlock(&stack->st_lock);
03389 
03390    cb_log(1, port, "There is no free channel on port (%d)\n", port);
03391    return NULL;
03392 }

static int misdn_lib_get_l1_down ( struct misdn_stack stack  )  [static]

Definition at line 890 of file isdn_lib.c.

References cb_log, misdn_stack::lower_id, misdn_stack::midev, and misdn_stack::port.

Referenced by handle_err(), and misdn_lib_get_port_down().

00891 {
00892    /* Pull Up L1 */
00893    iframe_t act;
00894    act.prim = PH_DEACTIVATE | REQUEST;
00895    act.addr = stack->lower_id|FLG_MSG_DOWN;
00896    act.dinfo = 0;
00897    act.len = 0;
00898 
00899    cb_log(1, stack->port, "SENDING PH_DEACTIVATE | REQ\n");
00900    return mISDN_write(stack->midev, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
00901 }

static int misdn_lib_get_l1_up ( struct misdn_stack stack  )  [static]

Definition at line 931 of file isdn_lib.c.

References misdn_stack::midev, and misdn_stack::upper_id.

Referenced by misdn_lib_get_port_up(), misdn_lib_isdn_l1watcher(), misdn_lib_reinit_nt_stack(), and misdn_lib_send_event().

00932 {
00933    /* Pull Up L1 */
00934    iframe_t act;
00935    act.prim = PH_ACTIVATE | REQUEST;
00936    act.addr = (stack->upper_id | FLG_MSG_DOWN)  ;
00937 
00938 
00939    act.dinfo = 0;
00940    act.len = 0;
00941 
00942    return mISDN_write(stack->midev, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
00943 
00944 }

static int misdn_lib_get_l2_down ( struct misdn_stack stack  )  [static]

Definition at line 904 of file isdn_lib.c.

References create_l2msg(), misdn_stack::midev, misdn_stack::nst, misdn_stack::nstlock, misdn_stack::nt, pthread_mutex_lock, pthread_mutex_unlock, misdn_stack::ptp, and misdn_stack::upper_id.

Referenced by handle_err(), and misdn_lib_get_port_down().

00905 {
00906 
00907    if (stack->ptp && (stack->nt) ) {
00908       msg_t *dmsg;
00909       /* L2 */
00910       dmsg = create_l2msg(DL_RELEASE| REQUEST, 0, 0);
00911 
00912       pthread_mutex_lock(&stack->nstlock);
00913       if (stack->nst.manager_l3(&stack->nst, dmsg))
00914          free_msg(dmsg);
00915       pthread_mutex_unlock(&stack->nstlock);
00916    } else {
00917       iframe_t act;
00918 
00919       act.prim = DL_RELEASE| REQUEST;
00920       act.addr = (stack->upper_id |FLG_MSG_DOWN)  ;
00921 
00922       act.dinfo = 0;
00923       act.len = 0;
00924       return mISDN_write(stack->midev, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
00925    }
00926 
00927    return 0;
00928 }

int misdn_lib_get_l2_up ( struct misdn_stack stack  ) 

Definition at line 946 of file isdn_lib.c.

References create_l2msg(), misdn_stack::midev, misdn_stack::nst, misdn_stack::nstlock, misdn_stack::nt, pthread_mutex_lock, pthread_mutex_unlock, misdn_stack::ptp, and misdn_stack::upper_id.

Referenced by handle_event_nt(), handle_l1(), misdn_lib_get_port_up(), misdn_lib_isdn_l1watcher(), and misdn_lib_reinit_nt_stack().

00947 {
00948 
00949    if (stack->ptp && (stack->nt) ) {
00950       msg_t *dmsg;
00951       /* L2 */
00952       dmsg = create_l2msg(DL_ESTABLISH | REQUEST, 0, 0);
00953 
00954       pthread_mutex_lock(&stack->nstlock);
00955       if (stack->nst.manager_l3(&stack->nst, dmsg))
00956          free_msg(dmsg);
00957       pthread_mutex_unlock(&stack->nstlock);
00958    } else {
00959       iframe_t act;
00960 
00961       act.prim = DL_ESTABLISH | REQUEST;
00962       act.addr = (stack->upper_id |FLG_MSG_DOWN)  ;
00963 
00964       act.dinfo = 0;
00965       act.len = 0;
00966       return mISDN_write(stack->midev, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
00967    }
00968 
00969    return 0;
00970 }

int misdn_lib_get_maxchans ( int  port  ) 

Definition at line 137 of file isdn_lib.c.

References get_misdn_stack(), misdn_stack::next, misdn_stack::port, and misdn_stack::pri.

Referenced by misdn_request().

00138 {
00139    struct misdn_stack *stack=get_misdn_stack();
00140    for ( ; stack; stack=stack->next) {
00141       if (stack->port == port) {
00142          if (stack->pri)
00143             return 30;
00144          else
00145             return 2;
00146       }
00147    }
00148    return -1;
00149 }

int misdn_lib_get_port_down ( int  port  ) 

Definition at line 1868 of file isdn_lib.c.

References glob_mgr, misdn_stack::l2link, misdn_lib_get_l1_down(), misdn_lib_get_l2_down(), misdn_stack::next, misdn_stack::port, and misdn_lib::stack_list.

Referenced by handle_cli_misdn_port_down().

01869 { /* Pull Down L1 */
01870    struct misdn_stack *stack;
01871    for (stack=glob_mgr->stack_list;
01872         stack;
01873         stack=stack->next) {
01874       if (stack->port == port) {
01875             if (stack->l2link)
01876                misdn_lib_get_l2_down(stack);
01877             misdn_lib_get_l1_down(stack);
01878          return 0;
01879       }
01880    }
01881    return 0;
01882 }

int misdn_lib_get_port_info ( int  port  ) 

Definition at line 4045 of file isdn_lib.c.

References misdn_lib::activatequeue, cb_log, find_stack_by_port(), glob_mgr, misdn_lib::new_msg, and misdn_stack::upper_id.

04046 {
04047    msg_t *msg=alloc_msg(MAX_MSG_SIZE);
04048    iframe_t *frm;
04049    struct misdn_stack *stack=find_stack_by_port(port);
04050    if (!msg) {
04051       cb_log(0, port, "misdn_lib_get_port_info: alloc_msg failed!\n");
04052       return -1;
04053    }
04054    frm=(iframe_t*)msg->data;
04055    if (!stack ) {
04056       cb_log(0, port, "There is no Stack for this port.\n");
04057       return -1;
04058    }
04059    /* activate bchannel */
04060    frm->prim = CC_STATUS_ENQUIRY | REQUEST;
04061 
04062    frm->addr = stack->upper_id| FLG_MSG_DOWN;
04063 
04064    frm->dinfo = 0;
04065    frm->len = 0;
04066 
04067    msg_queue_tail(&glob_mgr->activatequeue, msg);
04068    sem_post(&glob_mgr->new_msg);
04069 
04070 
04071    return 0;
04072 }

int misdn_lib_get_port_up ( int  port  ) 

Definition at line 1846 of file isdn_lib.c.

References glob_mgr, misdn_stack::l1link, misdn_stack::l2link, misdn_lib_get_l1_up(), misdn_lib_get_l2_up(), misdn_stack::next, misdn_stack::port, and misdn_lib::stack_list.

Referenced by handle_cli_misdn_port_up(), and misdn_check_l2l1().

01847 { /* Pull Up L1 */
01848    struct misdn_stack *stack;
01849 
01850    for (stack=glob_mgr->stack_list;
01851         stack;
01852         stack=stack->next) {
01853 
01854       if (stack->port == port) {
01855 
01856          if (!stack->l1link)
01857             misdn_lib_get_l1_up(stack);
01858          if (!stack->l2link)
01859             misdn_lib_get_l2_up(stack);
01860 
01861          return 0;
01862       }
01863    }
01864    return 0;
01865 }

static int misdn_lib_get_short_status ( struct misdn_stack stack  )  [static]

Definition at line 987 of file isdn_lib.c.

References misdn_stack::midev, and misdn_stack::upper_id.

Referenced by misdn_lib_isdn_l1watcher().

00988 {
00989    iframe_t act;
00990 
00991 
00992    act.prim = MGR_SHORTSTATUS | REQUEST;
00993 
00994    act.addr = (stack->upper_id | MSG_BROADCAST)  ;
00995 
00996    act.dinfo = SSTATUS_BROADCAST_BIT | SSTATUS_ALL;
00997 
00998    act.len = 0;
00999    return mISDN_write(stack->midev, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
01000 }

int misdn_lib_init ( char *  portlist,
struct misdn_lib_iface iface,
void *  user_data 
)

Definition at line 4340 of file isdn_lib.c.

References misdn_lib::activatequeue, ARRAY_LEN, misdn_stack::b_num, misdn_stack::bc, calloc, cb_event, misdn_lib_iface::cb_event, cb_jb_empty, misdn_lib_iface::cb_jb_empty, cb_log, misdn_lib_iface::cb_log, flip_buf_bits(), glob_mgr, global_state, init_bc(), init_flip_bits(), misdn_bchannel::is_register_pool, manager_event_handler(), MAX_BCHANS, misdn_stack::mgr, misdn_lib::midev, misdn_stack::midev, MISDN_INITIALIZED, misdn_lib_isdn_event_catcher(), misdn_lib_nt_debug_init(), misdn_lib::new_msg, misdn_stack::next, pthread_create, ptp, stack_init(), te_lib_init(), tone_425_flip, and tone_silence_flip.

Referenced by load_module().

04341 {
04342    struct misdn_lib *mgr=calloc(1, sizeof(struct misdn_lib));
04343    char *tok, *tokb;
04344    char plist[1024];
04345    int midev;
04346    int port_count=0;
04347 
04348    cb_log = iface->cb_log;
04349    cb_event = iface->cb_event;
04350    cb_jb_empty = iface->cb_jb_empty;
04351 
04352    glob_mgr = mgr;
04353 
04354    msg_init();
04355 
04356    misdn_lib_nt_debug_init(0,NULL);
04357 
04358    if (!portlist || (*portlist == 0) ) return 1;
04359 
04360    init_flip_bits();
04361 
04362    {
04363       strncpy(plist,portlist, 1024);
04364       plist[1023] = 0;
04365    }
04366 
04367    memcpy(tone_425_flip,tone_425,TONE_425_SIZE);
04368    flip_buf_bits(tone_425_flip,TONE_425_SIZE);
04369 
04370    memcpy(tone_silence_flip,tone_SILENCE,TONE_SILENCE_SIZE);
04371    flip_buf_bits(tone_silence_flip,TONE_SILENCE_SIZE);
04372 
04373    midev=te_lib_init();
04374    mgr->midev=midev;
04375 
04376    port_count=mISDN_get_stack_count(midev);
04377 
04378    msg_queue_init(&mgr->activatequeue);
04379 
04380    if (sem_init(&mgr->new_msg, 1, 0)<0)
04381       sem_init(&mgr->new_msg, 0, 0);
04382 
04383    for (tok=strtok_r(plist," ,",&tokb );
04384         tok;
04385         tok=strtok_r(NULL," ,",&tokb)) {
04386       int port = atoi(tok);
04387       struct misdn_stack *stack;
04388       struct misdn_stack *help;
04389       int ptp=0;
04390       int i;
04391       int r;
04392 
04393       if (strstr(tok, "ptp"))
04394          ptp=1;
04395 
04396       if (port > port_count) {
04397          cb_log(0, port, "Couldn't Initialize this port since we have only %d ports\n", port_count);
04398          exit(1);
04399       }
04400 
04401       stack = stack_init(midev, port, ptp);
04402       if (!stack) {
04403          perror("stack_init");
04404          exit(1);
04405       }
04406 
04407       /* Initialize the B channel records for real B channels. */
04408       for (i = 0; i <= stack->b_num; i++) {
04409          r = init_bc(stack, &stack->bc[i], stack->midev, port, i);
04410          if (r < 0) {
04411             cb_log(0, port, "Got Err @ init_bc :%d\n", r);
04412             exit(1);
04413          }
04414       }
04415 #if defined(AST_MISDN_ENHANCEMENTS)
04416       /* Initialize the B channel records for REGISTER signaling links. */
04417       for (i = MAX_BCHANS + 1; i < ARRAY_LEN(stack->bc); ++i) {
04418          r = init_bc(stack, &stack->bc[i], stack->midev, port, i);
04419          if (r < 0) {
04420             cb_log(0, port, "Got Err @ init_bc :%d\n", r);
04421             exit(1);
04422          }
04423          stack->bc[i].is_register_pool = 1;
04424       }
04425 #endif   /* defined(AST_MISDN_ENHANCEMENTS) */
04426 
04427       /* Add the new stack to the end of the list */
04428       help = mgr->stack_list;
04429       if (!help) {
04430          mgr->stack_list = stack;
04431       } else {
04432          while (help->next) {
04433             help = help->next;
04434          }
04435          help->next = stack;
04436       }
04437    }
04438 
04439    if (sem_init(&handler_started, 1, 0)<0)
04440       sem_init(&handler_started, 0, 0);
04441 
04442    cb_log(8, 0, "Starting Event Handler\n");
04443    pthread_create( &mgr->event_handler_thread, NULL,(void*)manager_event_handler, mgr);
04444 
04445    sem_wait(&handler_started) ;
04446    cb_log(8, 0, "Starting Event Catcher\n");
04447    pthread_create( &mgr->event_thread, NULL, (void*)misdn_lib_isdn_event_catcher, mgr);
04448 
04449    cb_log(8, 0, "Event Catcher started\n");
04450 
04451    global_state= MISDN_INITIALIZED;
04452 
04453    return (mgr == NULL);
04454 }

int misdn_lib_is_port_blocked ( int  port  ) 

Definition at line 117 of file isdn_lib.c.

References misdn_stack::blocked, get_misdn_stack(), misdn_stack::next, and misdn_stack::port.

00118 {
00119    struct misdn_stack *stack=get_misdn_stack();
00120    for ( ; stack; stack=stack->next) {
00121       if (stack->port == port) {
00122          return stack->blocked;
00123       }
00124    }
00125    return -1;
00126 }

int misdn_lib_is_ptp ( int  port  ) 

Definition at line 128 of file isdn_lib.c.

References get_misdn_stack(), misdn_stack::next, misdn_stack::port, and misdn_stack::ptp.

Referenced by build_setup(), cb_events(), do_immediate_setup(), misdn_call(), misdn_update_connected_line(), and misdn_update_redirecting().

00129 {
00130    struct misdn_stack *stack=get_misdn_stack();
00131    for ( ; stack; stack=stack->next) {
00132       if (stack->port == port) return stack->ptp;
00133    }
00134    return -1;
00135 }

static void misdn_lib_isdn_event_catcher ( void *  arg  )  [static]

Definition at line 3170 of file isdn_lib.c.

References cb_log, fetch_msg(), manager_isdn_handler(), and misdn_lib::midev.

Referenced by misdn_lib_init().

03171 {
03172    struct misdn_lib *mgr = arg;
03173    int zero_frm=0 , fff_frm=0 ;
03174    int midev= mgr->midev;
03175    int port=0;
03176 
03177    while (1) {
03178       msg_t *msg = fetch_msg(midev);
03179       iframe_t *frm;
03180 
03181 
03182       if (!msg) continue;
03183 
03184       frm = (iframe_t*) msg->data;
03185 
03186       /** When we make a call from NT2Ast we get these frames **/
03187       if (frm->len == 0 && frm->addr == 0 && frm->dinfo == 0 && frm->prim == 0 ) {
03188          zero_frm++;
03189          free_msg(msg);
03190          continue;
03191       } else {
03192          if (zero_frm) {
03193             cb_log(0, port, "*** Alert: %d zero_frms caught\n", zero_frm);
03194             zero_frm = 0 ;
03195          }
03196       }
03197 
03198       /** I get this sometimes after setup_bc **/
03199       if (frm->len == 0 &&  frm->dinfo == 0 && frm->prim == 0xffffffff ) {
03200          fff_frm++;
03201          free_msg(msg);
03202          continue;
03203       } else {
03204          if (fff_frm) {
03205             cb_log(0, port, "*** Alert: %d fff_frms caught\n", fff_frm);
03206             fff_frm = 0 ;
03207          }
03208       }
03209 
03210       manager_isdn_handler(frm, msg);
03211    }
03212 
03213 }

void misdn_lib_isdn_l1watcher ( int  port  ) 

Definition at line 3151 of file isdn_lib.c.

References cb_log, glob_mgr, misdn_stack::l1link, misdn_lib_get_l1_up(), misdn_lib_get_l2_up(), misdn_lib_get_short_status(), misdn_stack::next, misdn_stack::port, and misdn_lib::stack_list.

Referenced by misdn_l1_task().

03152 {
03153    struct misdn_stack *stack;
03154 
03155    for (stack = glob_mgr->stack_list; stack && (stack->port != port); stack = stack->next)
03156       ;
03157 
03158    if (stack) {
03159       cb_log(4, port, "Checking L1 State\n");
03160       if (!stack->l1link) {
03161          cb_log(4, port, "L1 State Down, trying to get it up again\n");
03162          misdn_lib_get_short_status(stack);
03163          misdn_lib_get_l1_up(stack);
03164          misdn_lib_get_l2_up(stack);
03165       }
03166    }
03167 }

void misdn_lib_log_ies ( struct misdn_bchannel bc  ) 

Definition at line 3538 of file isdn_lib.c.

References misdn_bchannel::addr, misdn_bchannel::b_stid, misdn_stack::bc, bearer2str(), misdn_bchannel::caller, misdn_bchannel::capability, misdn_bchannel::cause, cb_log, misdn_bchannel::channel, misdn_bchannel::connected, misdn_party_redirecting::count, misdn_bchannel::dialed, fac2str(), misdn_bchannel::fac_in, misdn_bchannel::fac_out, misdn_party_redirecting::from, get_stack_by_bc(), misdn_bchannel::holded, misdn_bchannel::info_dad, misdn_bchannel::keypad, misdn_bchannel::l3_id, misdn_bchannel::layer_id, misdn_bchannel::mode, misdn_party_id::name, misdn_stack::nt, misdn_party_id::number, misdn_party_dialing::number_plan, misdn_party_id::number_plan, misdn_party_dialing::number_type, misdn_party_id::number_type, misdn_bchannel::out_cause, misdn_stack::port, misdn_party_id::presentation, misdn_bchannel::presentation, misdn_bchannel::progress_indicator, misdn_bchannel::rate, misdn_party_redirecting::reason, misdn_bchannel::redirecting, misdn_party_id::screening, misdn_bchannel::sending_complete, misdn_bchannel::set_presentation, misdn_bchannel::stack_holder, misdn_party_redirecting::to, misdn_bchannel::urate, and misdn_bchannel::user1.

Referenced by cb_events(), and misdn_lib_send_event().

03539 {
03540    struct misdn_stack *stack;
03541 
03542    if (!bc) return;
03543 
03544    stack = get_stack_by_bc(bc);
03545 
03546    if (!stack) return;
03547 
03548    cb_log(2, stack->port,
03549       " --> channel:%d mode:%s cause:%d ocause:%d\n",
03550       bc->channel,
03551       stack->nt ? "NT" : "TE",
03552       bc->cause,
03553       bc->out_cause);
03554 
03555    cb_log(2, stack->port,
03556       " --> info_dad:%s dialed numtype:%d plan:%d\n",
03557       bc->info_dad,
03558       bc->dialed.number_type,
03559       bc->dialed.number_plan);
03560 
03561    cb_log(2, stack->port,
03562       " --> caller:\"%s\" <%s> type:%d plan:%d pres:%d screen:%d\n",
03563       bc->caller.name,
03564       bc->caller.number,
03565       bc->caller.number_type,
03566       bc->caller.number_plan,
03567       bc->caller.presentation,
03568       bc->caller.screening);
03569 
03570    cb_log(2, stack->port,
03571       " --> redirecting-from:\"%s\" <%s> type:%d plan:%d pres:%d screen:%d\n",
03572       bc->redirecting.from.name,
03573       bc->redirecting.from.number,
03574       bc->redirecting.from.number_type,
03575       bc->redirecting.from.number_plan,
03576       bc->redirecting.from.presentation,
03577       bc->redirecting.from.screening);
03578    cb_log(2, stack->port,
03579       " --> redirecting-to:\"%s\" <%s> type:%d plan:%d pres:%d screen:%d\n",
03580       bc->redirecting.to.name,
03581       bc->redirecting.to.number,
03582       bc->redirecting.to.number_type,
03583       bc->redirecting.to.number_plan,
03584       bc->redirecting.to.presentation,
03585       bc->redirecting.to.screening);
03586    cb_log(2, stack->port,
03587       " --> redirecting reason:%d count:%d\n",
03588       bc->redirecting.reason,
03589       bc->redirecting.count);
03590 
03591    cb_log(2, stack->port,
03592       " --> connected:\"%s\" <%s> type:%d plan:%d pres:%d screen:%d\n",
03593       bc->connected.name,
03594       bc->connected.number,
03595       bc->connected.number_type,
03596       bc->connected.number_plan,
03597       bc->connected.presentation,
03598       bc->connected.screening);
03599 
03600    cb_log(3, stack->port, " --> caps:%s pi:%x keypad:%s sending_complete:%d\n", bearer2str(bc->capability),bc->progress_indicator, bc->keypad, bc->sending_complete);
03601 
03602    cb_log(4, stack->port, " --> set_pres:%d pres:%d\n", bc->set_presentation, bc->presentation);
03603 
03604    cb_log(4, stack->port, " --> addr:%x l3id:%x b_stid:%x layer_id:%x\n", bc->addr, bc->l3_id, bc->b_stid, bc->layer_id);
03605 
03606    cb_log(4, stack->port, " --> facility in:%s out:%s\n", fac2str(bc->fac_in.Function), fac2str(bc->fac_out.Function));
03607 
03608    cb_log(5, stack->port, " --> urate:%d rate:%d mode:%d user1:%d\n", bc->urate, bc->rate, bc->mode,bc->user1);
03609 
03610    cb_log(5, stack->port, " --> bc:%p h:%d sh:%d\n", bc, bc->holded, bc->stack_holder);
03611 }

int misdn_lib_maxports_get ( void   ) 

Definition at line 4291 of file isdn_lib.c.

Referenced by load_module().

04292 {
04293    /* BE AWARE WE HAVE NO cb_log() HERE! */
04294 
04295    int i = mISDN_open();
04296    int max=0;
04297 
04298    if (i<0)
04299       return -1;
04300 
04301    max = mISDN_get_stack_count(i);
04302 
04303    mISDN_close(i);
04304 
04305    return max;
04306 }

void misdn_lib_nt_debug_init ( int  flags,
char *  file 
)

Definition at line 4321 of file isdn_lib.c.

References f.

Referenced by load_module(), and misdn_lib_init().

04322 {
04323    static int init=0;
04324    char *f;
04325 
04326    if (!flags)
04327       f=NULL;
04328    else
04329       f=file;
04330 
04331    if (!init) {
04332       debug_init( flags , f, f, f);
04333       init=1;
04334    } else {
04335       debug_close();
04336       debug_init( flags , f, f, f);
04337    }
04338 }

void misdn_lib_nt_keepcalls ( int  kc  ) 

Definition at line 4309 of file isdn_lib.c.

References get_misdn_stack(), misdn_stack::next, and misdn_stack::nst.

Referenced by load_module().

04310 {
04311 #ifdef FEATURE_NET_KEEPCALLS
04312    if (kc) {
04313       struct misdn_stack *stack=get_misdn_stack();
04314       for ( ; stack; stack=stack->next) {
04315          stack->nst.feature |= FEATURE_NET_KEEPCALLS;
04316       }
04317    }
04318 #endif
04319 }

int misdn_lib_pid_restart ( int  pid  ) 

Definition at line 4100 of file isdn_lib.c.

References manager_clean_bc(), and manager_find_bc_by_pid().

Referenced by handle_cli_misdn_restart_pid().

04101 {
04102    struct misdn_bchannel *bc=manager_find_bc_by_pid(pid);
04103 
04104    if (bc) {
04105       manager_clean_bc(bc);
04106    }
04107    return 0;
04108 }

int misdn_lib_port_block ( int  port  ) 

Definition at line 91 of file isdn_lib.c.

References misdn_stack::blocked, get_misdn_stack(), misdn_stack::next, and misdn_stack::port.

Referenced by cb_events(), and handle_cli_misdn_port_block().

00092 {
00093    struct misdn_stack *stack=get_misdn_stack();
00094    for ( ; stack; stack=stack->next) {
00095       if (stack->port == port) {
00096          stack->blocked=1;
00097          return 0;
00098       }
00099    }
00100    return -1;
00101 
00102 }

int misdn_lib_port_is_nt ( int  port  ) 

Definition at line 65 of file isdn_lib.c.

References get_misdn_stack(), misdn_stack::next, misdn_stack::nt, and misdn_stack::port.

Referenced by handle_cli_misdn_send_facility(), misdn_update_connected_line(), and misdn_update_redirecting().

00066 {
00067    struct misdn_stack *stack=get_misdn_stack();
00068    for ( ; stack; stack=stack->next) {
00069       if (stack->port == port) {
00070          return stack->nt;
00071       }
00072    }
00073 
00074    return -1;
00075 }

int misdn_lib_port_is_pri ( int  port  ) 

Definition at line 53 of file isdn_lib.c.

References get_misdn_stack(), misdn_stack::next, misdn_stack::port, and misdn_stack::pri.

Referenced by misdn_new(), test_inuse(), and update_name().

00054 {
00055    struct misdn_stack *stack=get_misdn_stack();
00056    for ( ; stack; stack=stack->next) {
00057       if (stack->port == port) {
00058          return stack->pri;
00059       }
00060    }
00061 
00062    return -1;
00063 }

int misdn_lib_port_restart ( int  port  ) 

Definition at line 4150 of file isdn_lib.c.

References misdn_lib::activatequeue, cb_log, clear_l3(), find_stack_by_port(), glob_mgr, misdn_lib_reinit_nt_stack(), misdn_lib::new_msg, misdn_stack::nt, misdn_stack::port, and misdn_stack::upper_id.

Referenced by handle_cli_misdn_restart_port().

04151 {
04152    struct misdn_stack *stack=find_stack_by_port(port);
04153 
04154    cb_log(0, port, "Restarting this port.\n");
04155    if (stack) {
04156       cb_log(0, port, "Stack:%p\n",stack);
04157 
04158       clear_l3(stack);
04159       {
04160          msg_t *msg=alloc_msg(MAX_MSG_SIZE);
04161          iframe_t *frm;
04162 
04163          if (!msg) {
04164             cb_log(0, port, "port_restart: alloc_msg failed\n");
04165             return -1;
04166          }
04167 
04168          frm=(iframe_t*)msg->data;
04169          /* we must activate if we are deactivated */
04170          /* activate bchannel */
04171          frm->prim = DL_RELEASE | REQUEST;
04172          frm->addr = stack->upper_id | FLG_MSG_DOWN;
04173 
04174          frm->dinfo = 0;
04175          frm->len = 0;
04176          msg_queue_tail(&glob_mgr->activatequeue, msg);
04177          sem_post(&glob_mgr->new_msg);
04178       }
04179 
04180       if (stack->nt)
04181          misdn_lib_reinit_nt_stack(stack->port);
04182 
04183    }
04184 
04185    return 0;
04186 }

int misdn_lib_port_unblock ( int  port  ) 

Definition at line 104 of file isdn_lib.c.

References misdn_stack::blocked, get_misdn_stack(), misdn_stack::next, and misdn_stack::port.

Referenced by handle_cli_misdn_port_unblock().

00105 {
00106    struct misdn_stack *stack=get_misdn_stack();
00107    for ( ; stack; stack=stack->next) {
00108       if (stack->port == port) {
00109          stack->blocked=0;
00110          return 0;
00111       }
00112    }
00113    return -1;
00114 
00115 }

int misdn_lib_port_up ( int  port,
int  check 
)

Definition at line 1884 of file isdn_lib.c.

References misdn_stack::blocked, cb_log, glob_mgr, misdn_stack::l1link, misdn_stack::l2link, misdn_stack::next, misdn_stack::port, misdn_stack::ptp, and misdn_lib::stack_list.

Referenced by misdn_check_l2l1(), and misdn_request().

01885 {
01886    struct misdn_stack *stack;
01887 
01888 
01889    for (stack=glob_mgr->stack_list;
01890         stack;
01891         stack=stack->next) {
01892 
01893       if (stack->port == port) {
01894 
01895          if (stack->blocked) {
01896             cb_log(0,port, "Port Blocked:%d L2:%d L1:%d\n", stack->blocked, stack->l2link, stack->l1link);
01897             return -1;
01898          }
01899 
01900          if (stack->ptp ) {
01901 
01902             if (stack->l1link && stack->l2link) {
01903                return 1;
01904             } else {
01905                cb_log(1,port, "Port Down L2:%d L1:%d\n",
01906                   stack->l2link, stack->l1link);
01907                return 0;
01908             }
01909          } else {
01910             if ( !check || stack->l1link )
01911                return 1;
01912             else {
01913                cb_log(1,port, "Port down PMP\n");
01914                return 0;
01915             }
01916          }
01917       }
01918    }
01919 
01920    return -1;
01921 }

void misdn_lib_reinit_nt_stack ( int  port  ) 

Definition at line 4952 of file isdn_lib.c.

References misdn_stack::blocked, misdn_stack::d_stid, find_stack_by_port(), glob_mgr, handle_event_nt(), misdn_stack::l2link, misdn_stack::lower_id, misdn_stack::mgr, misdn_lib::midev, misdn_lib_get_l1_up(), misdn_lib_get_l2_up(), misdn_stack::nst, misdn_stack::pri, misdn_stack::ptp, and misdn_stack::upper_id.

Referenced by handle_event_nt(), and misdn_lib_port_restart().

04953 {
04954    struct misdn_stack *stack=find_stack_by_port(port);
04955 
04956    if (stack) {
04957       stack->l2link=0;
04958       stack->blocked=0;
04959 
04960       cleanup_Isdnl3(&stack->nst);
04961       cleanup_Isdnl2(&stack->nst);
04962 
04963 
04964       memset(&stack->nst, 0, sizeof(net_stack_t));
04965       memset(&stack->mgr, 0, sizeof(manager_t));
04966 
04967       stack->mgr.nst = &stack->nst;
04968       stack->nst.manager = &stack->mgr;
04969 
04970       stack->nst.l3_manager = handle_event_nt;
04971       stack->nst.device = glob_mgr->midev;
04972       stack->nst.cardnr = port;
04973       stack->nst.d_stid = stack->d_stid;
04974 
04975       stack->nst.feature = FEATURE_NET_HOLD;
04976       if (stack->ptp)
04977          stack->nst.feature |= FEATURE_NET_PTP;
04978       if (stack->pri)
04979          stack->nst.feature |= FEATURE_NET_CRLEN2 | FEATURE_NET_EXTCID;
04980 
04981       stack->nst.l1_id = stack->lower_id;
04982       stack->nst.l2_id = stack->upper_id;
04983 
04984       msg_queue_init(&stack->nst.down_queue);
04985 
04986       Isdnl2Init(&stack->nst);
04987       Isdnl3Init(&stack->nst);
04988 
04989       if (!stack->ptp)
04990          misdn_lib_get_l1_up(stack);
04991       misdn_lib_get_l2_up(stack);
04992    }
04993 }

void misdn_lib_release ( struct misdn_bchannel bc  ) 

Definition at line 1824 of file isdn_lib.c.

References misdn_stack::bc, cb_log, misdn_bchannel::channel, clean_up_bc(), empty_bc(), empty_chan_in_stack(), get_stack_by_bc(), and misdn_bchannel::in_use.

Referenced by misdn_hangup().

01825 {
01826    int channel;
01827    struct misdn_stack *stack=get_stack_by_bc(bc);
01828 
01829    if (!stack) {
01830       cb_log(1,0,"misdn_release: No Stack found\n");
01831       return;
01832    }
01833 
01834    channel = bc->channel;
01835    empty_bc(bc);
01836    clean_up_bc(bc);
01837    if (channel > 0) {
01838       empty_chan_in_stack(stack, channel);
01839    }
01840    bc->in_use=0;
01841 }

int misdn_lib_send_event ( struct misdn_bchannel bc,
enum event_e  event 
)

Definition at line 3630 of file isdn_lib.c.

References misdn_stack::bc, misdn_bchannel::bc_state, bc_state2str(), bc_state_change(), BCHAN_BRIDGED, BCHAN_CLEANED, misdn_bchannel::caller, misdn_bchannel::capability, misdn_bchannel::cause, cb_log, misdn_bchannel::channel, misdn_bchannel::channel_found, misdn_bchannel::channel_preselected, clean_up_bc(), misdn_bchannel::conf_id, create_process(), misdn_bchannel::crypt_key, misdn_bchannel::dialed, misdn_stack::downqueue, empty_bc(), empty_chan_in_stack(), ENOCHAN, EVENT_ALERTING, EVENT_CONNECT, EVENT_CONNECT_ACKNOWLEDGE, EVENT_DISCONNECT, EVENT_HOLD_ACKNOWLEDGE, EVENT_PROCEEDING, EVENT_PROGRESS, EVENT_REGISTER, EVENT_RELEASE, EVENT_RELEASE_COMPLETE, EVENT_RETRIEVE_ACKNOWLEDGE, EVENT_SETUP, EVENT_SETUP_ACKNOWLEDGE, misdn_bchannel::evq, find_bc_by_confid(), find_free_chan_in_stack(), get_stack_by_bc(), glob_mgr, misdn_bchannel::holded, misdn_bchannel::in_use, isdn_get_info(), isdn_msg_build_event(), misdn_stack::l1link, malloc, manager_ec_enable(), manager_ph_control(), manager_ph_control_block(), misdn_lib::midev, misdn_cap_is_speech(), misdn_lib_get_l1_up(), misdn_lib_log_ies(), misdn_send_lock(), misdn_send_unlock(), misdn_split_conf(), msgs_g, misdn_party_id::name, misdn_bchannel::need_disconnect, misdn_bchannel::need_release, misdn_bchannel::need_release_complete, misdn_lib::new_msg, misdn_bchannel::nodsp, misdn_stack::nt, misdn_bchannel::nt, misdn_party_id::number, misdn_party_dialing::number, misdn_party_id::number_type, misdn_party_dialing::number_type, misdn_bchannel::out_cause, misdn_bchannel::pid, misdn_bchannel::port, misdn_stack::port, RETURN, misdn_bchannel::rxgain, setup_bc(), stack_holder_add(), misdn_bchannel::txgain, and misdn_stack::upper_id.

Referenced by cb_events(), do_immediate_setup(), handle_cli_misdn_send_display(), handle_cli_misdn_send_facility(), handle_event(), handle_event_nt(), handle_frm(), handle_l1(), misdn_answer(), misdn_call(), misdn_digit_end(), misdn_facility_exec(), misdn_facility_ie_handler(), misdn_hangup(), misdn_indication(), misdn_lib_send_restart(), misdn_overlap_dial_task(), misdn_send_text(), misdn_update_connected_line(), misdn_update_redirecting(), start_pbx(), and wait_for_digits().

03631 {
03632    msg_t *msg;
03633    struct misdn_bchannel *bc2;
03634    struct misdn_bchannel *held_bc;
03635    struct misdn_stack *stack;
03636    int retval = 0;
03637    int channel;
03638    int tmpcause;
03639    int tmp_out_cause;
03640 
03641    if (!bc)
03642       RETURN(-1,OUT_POST_UNLOCK);
03643 
03644    stack = get_stack_by_bc(bc);
03645    if (!stack) {
03646       cb_log(0,bc->port,
03647          "SENDEVENT: no Stack for event:%s caller:\"%s\" <%s> dialed:%s \n",
03648          isdn_get_info(msgs_g, event, 0),
03649          bc->caller.name,
03650          bc->caller.number,
03651          bc->dialed.number);
03652       RETURN(-1,OUT);
03653    }
03654 
03655    misdn_send_lock(bc);
03656 
03657 
03658    cb_log(6,stack->port,"SENDEVENT: stack->nt:%d stack->upperid:%x\n",stack->nt, stack->upper_id);
03659 
03660    if ( stack->nt && !stack->l1link) {
03661       /** Queue Event **/
03662       bc->evq=event;
03663       cb_log(1, stack->port, "Queueing Event %s because L1 is down (btw. Activating L1)\n", isdn_get_info(msgs_g, event, 0));
03664       misdn_lib_get_l1_up(stack);
03665       RETURN(0,OUT);
03666    }
03667 
03668    cb_log(1, stack->port,
03669       "I SEND:%s caller:\"%s\" <%s> dialed:%s pid:%d\n",
03670       isdn_get_info(msgs_g, event, 0),
03671       bc->caller.name,
03672       bc->caller.number,
03673       bc->dialed.number,
03674       bc->pid);
03675    cb_log(4, stack->port, " --> bc_state:%s\n",bc_state2str(bc->bc_state));
03676    misdn_lib_log_ies(bc);
03677 
03678    switch (event) {
03679    case EVENT_REGISTER:
03680    case EVENT_SETUP:
03681       if (create_process(glob_mgr->midev, bc) < 0) {
03682          cb_log(0, stack->port, " No free channel at the moment @ send_event\n");
03683 
03684          RETURN(-ENOCHAN,OUT);
03685       }
03686       break;
03687 
03688    case EVENT_PROGRESS:
03689    case EVENT_ALERTING:
03690    case EVENT_PROCEEDING:
03691    case EVENT_SETUP_ACKNOWLEDGE:
03692    case EVENT_CONNECT:
03693       if (!stack->nt)
03694          break;
03695 
03696    case EVENT_RETRIEVE_ACKNOWLEDGE:
03697       if (stack->nt) {
03698          if (bc->channel <=0 ) { /*  else we have the channel already */
03699             if (find_free_chan_in_stack(stack, bc, 0, 0)<0) {
03700                cb_log(0, stack->port, " No free channel at the moment\n");
03701                /*FIXME: add disconnect*/
03702                RETURN(-ENOCHAN,OUT);
03703             }
03704          }
03705          /* Its that i generate channels */
03706       }
03707 
03708       retval=setup_bc(bc);
03709       if (retval == -EINVAL) {
03710          cb_log(0,bc->port,"send_event: setup_bc failed\n");
03711       }
03712 
03713       if (misdn_cap_is_speech(bc->capability)) {
03714          if ((event==EVENT_CONNECT)||(event==EVENT_RETRIEVE_ACKNOWLEDGE)) {
03715             if ( *bc->crypt_key ) {
03716                cb_log(4, stack->port,
03717                   " --> ENABLING BLOWFISH channel:%d caller%d:\"%s\" <%s> dialed%d:%s\n",
03718                   bc->channel,
03719                   bc->caller.number_type,
03720                   bc->caller.name,
03721                   bc->caller.number,
03722                   bc->dialed.number_type,
03723                   bc->dialed.number);
03724 
03725                manager_ph_control_block(bc,  BF_ENABLE_KEY, bc->crypt_key, strlen(bc->crypt_key) );
03726             }
03727 
03728             if (!bc->nodsp) manager_ph_control(bc,  DTMF_TONE_START, 0);
03729             manager_ec_enable(bc);
03730 
03731             if (bc->txgain != 0) {
03732                cb_log(4, stack->port,  "--> Changing txgain to %d\n", bc->txgain);
03733                manager_ph_control(bc, VOL_CHANGE_TX, bc->txgain);
03734             }
03735 
03736             if ( bc->rxgain != 0 ) {
03737                cb_log(4, stack->port,  "--> Changing rxgain to %d\n", bc->rxgain);
03738                manager_ph_control(bc, VOL_CHANGE_RX, bc->rxgain);
03739             }
03740          }
03741       }
03742       break;
03743 
03744    case EVENT_HOLD_ACKNOWLEDGE:
03745       held_bc = malloc(sizeof(struct misdn_bchannel));
03746       if (!held_bc) {
03747          cb_log(0, bc->port, "Could not allocate held_bc!!!\n");
03748          RETURN(-1,OUT);
03749       }
03750 
03751       /* backup the bc and put it in storage */
03752       *held_bc = *bc;
03753       held_bc->holded = 1;
03754       held_bc->channel = 0;/* A held call does not have a channel anymore. */
03755       held_bc->channel_preselected = 0;
03756       held_bc->channel_found = 0;
03757       bc_state_change(held_bc, BCHAN_CLEANED);
03758       stack_holder_add(stack, held_bc);
03759 
03760       /* kill the bridge and clean the real b-channel record */
03761       if (stack->nt) {
03762          if (bc->bc_state == BCHAN_BRIDGED) {
03763             misdn_split_conf(bc,bc->conf_id);
03764             bc2 = find_bc_by_confid(bc->conf_id);
03765             if (!bc2) {
03766                cb_log(0,bc->port,"We have no second bc in bridge???\n");
03767             } else {
03768                misdn_split_conf(bc2,bc->conf_id);
03769             }
03770          }
03771 
03772          channel = bc->channel;
03773 
03774          empty_bc(bc);
03775          clean_up_bc(bc);
03776 
03777          if (channel>0)
03778             empty_chan_in_stack(stack,channel);
03779 
03780          bc->in_use=0;
03781       }
03782       break;
03783 
03784    /* finishing the channel eh ? */
03785    case EVENT_DISCONNECT:
03786       if (!bc->need_disconnect) {
03787          cb_log(0, bc->port, " --> we have already sent DISCONNECT\n");
03788          RETURN(-1,OUT);
03789       }
03790 
03791       bc->need_disconnect=0;
03792       break;
03793    case EVENT_RELEASE:
03794       if (!bc->need_release) {
03795          cb_log(0, bc->port, " --> we have already sent RELEASE\n");
03796          RETURN(-1,OUT);
03797       }
03798       bc->need_disconnect=0;
03799       bc->need_release=0;
03800       break;
03801    case EVENT_RELEASE_COMPLETE:
03802       if (!bc->need_release_complete) {
03803          cb_log(0, bc->port, " --> we have already sent RELEASE_COMPLETE\n");
03804          RETURN(-1,OUT);
03805       }
03806       bc->need_disconnect=0;
03807       bc->need_release=0;
03808       bc->need_release_complete=0;
03809 
03810       if (!stack->nt) {
03811          /* create cleanup in TE */
03812          channel = bc->channel;
03813          tmpcause = bc->cause;
03814          tmp_out_cause = bc->out_cause;
03815 
03816          empty_bc(bc);
03817          bc->cause=tmpcause;
03818          bc->out_cause=tmp_out_cause;
03819          clean_up_bc(bc);
03820 
03821          if (channel>0)
03822             empty_chan_in_stack(stack,channel);
03823 
03824          bc->in_use=0;
03825       }
03826       break;
03827 
03828    case EVENT_CONNECT_ACKNOWLEDGE:
03829       if ( bc->nt || misdn_cap_is_speech(bc->capability)) {
03830          int retval=setup_bc(bc);
03831          if (retval == -EINVAL){
03832             cb_log(0,bc->port,"send_event: setup_bc failed\n");
03833 
03834          }
03835       }
03836 
03837       if (misdn_cap_is_speech(bc->capability)) {
03838          if (  !bc->nodsp) manager_ph_control(bc,  DTMF_TONE_START, 0);
03839          manager_ec_enable(bc);
03840 
03841          if ( bc->txgain != 0 ) {
03842             cb_log(4, stack->port, "--> Changing txgain to %d\n", bc->txgain);
03843             manager_ph_control(bc, VOL_CHANGE_TX, bc->txgain);
03844          }
03845          if ( bc->rxgain != 0 ) {
03846             cb_log(4, stack->port, "--> Changing rxgain to %d\n", bc->rxgain);
03847             manager_ph_control(bc, VOL_CHANGE_RX, bc->rxgain);
03848          }
03849       }
03850       break;
03851 
03852    default:
03853       break;
03854    }
03855 
03856    /* Later we should think about sending bchannel data directly to misdn. */
03857    msg = isdn_msg_build_event(msgs_g, bc, event, stack->nt);
03858    if (!msg) {
03859       /*
03860        * The message was not built.
03861        *
03862        * NOTE:  The only time that the message will fail to build
03863        * is because the requested FACILITY message is not supported.
03864        * A failed malloc() results in exit() being called.
03865        */
03866       RETURN(-1, OUT);
03867    } else {
03868       msg_queue_tail(&stack->downqueue, msg);
03869       sem_post(&glob_mgr->new_msg);
03870    }
03871 
03872 OUT:
03873    misdn_send_unlock(bc);
03874 
03875 OUT_POST_UNLOCK:
03876    return retval;
03877 }

int misdn_lib_send_restart ( int  port,
int  channel 
)

Definition at line 4111 of file isdn_lib.c.

References misdn_stack::b_num, misdn_stack::bc, cb_log, misdn_bchannel::channel, clean_up_bc(), empty_bc(), EVENT_RESTART, find_stack_by_port(), misdn_bchannel::in_use, misdn_lib_send_event(), misdn_make_dummy(), misdn_stack::nt, and misdn_stack::port.

Referenced by handle_cli_misdn_send_restart(), handle_event_nt(), and handle_frm().

04112 {
04113    struct misdn_stack *stack=find_stack_by_port(port);
04114    struct misdn_bchannel dummybc;
04115    /*default is all channels*/
04116    cb_log(0, port, "Sending Restarts on this port.\n");
04117 
04118    misdn_make_dummy(&dummybc, stack->port, MISDN_ID_GLOBAL, stack->nt, 0);
04119 
04120    /*default is all channels*/
04121    if (channel <0) {
04122       dummybc.channel=-1;
04123       cb_log(0, port, "Restarting and all Interfaces\n");
04124       misdn_lib_send_event(&dummybc, EVENT_RESTART);
04125 
04126       return 0;
04127    }
04128 
04129    /*if a channel is specified we restart only this one*/
04130    if (channel >0) {
04131       int cnt;
04132       dummybc.channel=channel;
04133       cb_log(0, port, "Restarting and cleaning channel %d\n",channel);
04134       misdn_lib_send_event(&dummybc, EVENT_RESTART);
04135       /* clean up chan in stack, to be sure we don't think it's
04136        * in use anymore */
04137       for (cnt=0; cnt<=stack->b_num; cnt++) {
04138          if (stack->bc[cnt].in_use && stack->bc[cnt].channel == channel) {
04139             empty_bc(&stack->bc[cnt]);
04140             clean_up_bc(&stack->bc[cnt]);
04141             stack->bc[cnt].in_use=0;
04142          }
04143       }
04144    }
04145 
04146    return 0;
04147 }

void misdn_lib_send_tone ( struct misdn_bchannel bc,
enum tone_e  tone 
)

Definition at line 4769 of file isdn_lib.c.

References misdn_bchannel::addr, misdn_stack::bc, glob_mgr, manager_ph_control(), misdn_lib::midev, TONE_ALERTING, TONE_DIAL, TONE_HANGUP, and TONE_NONE.

Referenced by hanguptone_indicate().

04770 {
04771    char buf[mISDN_HEADER_LEN + 128] = "";
04772    iframe_t *frm = (iframe_t*)buf;
04773 
04774    switch(tone) {
04775    case TONE_DIAL:
04776       manager_ph_control(bc, TONE_PATT_ON, TONE_GERMAN_DIALTONE);
04777    break;
04778 
04779    case TONE_ALERTING:
04780       manager_ph_control(bc, TONE_PATT_ON, TONE_GERMAN_RINGING);
04781    break;
04782 
04783    case TONE_HANGUP:
04784       manager_ph_control(bc, TONE_PATT_ON, TONE_GERMAN_HANGUP);
04785    break;
04786 
04787    case TONE_NONE:
04788    default:
04789       manager_ph_control(bc, TONE_PATT_OFF, TONE_GERMAN_HANGUP);
04790    }
04791 
04792    frm->prim=DL_DATA|REQUEST;
04793    frm->addr=bc->addr|FLG_MSG_DOWN;
04794    frm->dinfo=0;
04795    frm->len=128;
04796 
04797    mISDN_write(glob_mgr->midev, frm, mISDN_HEADER_LEN+frm->len, TIMEOUT_1SEC);
04798 }

void misdn_lib_setup_bc ( struct misdn_bchannel bc  ) 

Definition at line 1066 of file isdn_lib.c.

References misdn_stack::bc, clean_up_bc(), and setup_bc().

01067 {
01068    clean_up_bc(bc);
01069    setup_bc(bc);
01070 }

void misdn_lib_split_bridge ( struct misdn_bchannel bc1,
struct misdn_bchannel bc2 
)

Definition at line 4924 of file isdn_lib.c.

References bc_state2str(), BCHAN_BRIDGED, cb_log, misdn_bchannel::conf_id, and misdn_split_conf().

Referenced by misdn_bridge().

04925 {
04926 
04927    struct misdn_bchannel *bc_list[]={
04928       bc1,bc2,NULL
04929    };
04930    struct misdn_bchannel **bc;
04931 
04932    for (bc=bc_list; *bc;  bc++) {
04933       if ( (*bc)->bc_state == BCHAN_BRIDGED){
04934          misdn_split_conf( *bc, (*bc)->conf_id);
04935       } else {
04936          cb_log( 2, (*bc)->port, "BC not bridged (state:%s) so not splitting it\n",bc_state2str((*bc)->bc_state));
04937       }
04938    }
04939 
04940 }

void misdn_lib_tone_generator_start ( struct misdn_bchannel bc  ) 

Definition at line 2341 of file isdn_lib.c.

References misdn_bchannel::generate_tone.

Referenced by misdn_write().

02342 {
02343    bc->generate_tone=1;
02344 }

void misdn_lib_tone_generator_stop ( struct misdn_bchannel bc  ) 

Definition at line 2346 of file isdn_lib.c.

References misdn_bchannel::generate_tone.

Referenced by start_bc_tones(), and stop_indicate().

02347 {
02348    bc->generate_tone=0;
02349 }

int misdn_lib_tx2misdn_frm ( struct misdn_bchannel bc,
void *  data,
int  len 
)

Definition at line 4552 of file isdn_lib.c.

References misdn_bchannel::addr, misdn_stack::bc, misdn_bchannel::bc_state, bc_state2str(), BCHAN_ACTIVATED, BCHAN_BRIDGED, misdn_bchannel::capability, cb_log, flip_buf_bits(), get_stack_by_bc(), misdn_stack::midev, misdn_cap_is_speech(), misdn_bchannel::port, and misdn_stack::port.

Referenced by misdn_join_conf().

04553 {
04554    struct misdn_stack *stack=get_stack_by_bc(bc);
04555    char buf[4096 + mISDN_HEADER_LEN];
04556    iframe_t *frm = (iframe_t*)buf;
04557    int r;
04558 
04559    switch (bc->bc_state) {
04560       case BCHAN_ACTIVATED:
04561       case BCHAN_BRIDGED:
04562          break;
04563       default:
04564          cb_log(3, bc->port, "BC not yet activated (state:%s)\n",bc_state2str(bc->bc_state));
04565          return -1;
04566    }
04567 
04568    frm->prim = DL_DATA|REQUEST;
04569    frm->dinfo = 0;
04570    frm->addr = bc->addr | FLG_MSG_DOWN ;
04571 
04572    frm->len = len;
04573    memcpy(&buf[mISDN_HEADER_LEN], data,len);
04574 
04575    if ( misdn_cap_is_speech(bc->capability) )
04576       flip_buf_bits( &buf[mISDN_HEADER_LEN], len);
04577    else
04578       cb_log(6, stack->port, "Writing %d data bytes\n",len);
04579 
04580    cb_log(9, stack->port, "Writing %d bytes 2 mISDN\n",len);
04581    r=mISDN_write(stack->midev, buf, frm->len + mISDN_HEADER_LEN, TIMEOUT_INFINIT);
04582    return 0;
04583 }

void misdn_make_dummy ( struct misdn_bchannel dummybc,
int  port,
int  l3id,
int  nt,
int  channel 
)

Definition at line 77 of file isdn_lib.c.

References misdn_bchannel::channel, misdn_bchannel::dummy, misdn_bchannel::l3_id, misdn_bchannel::nt, and misdn_bchannel::port.

Referenced by handle_cli_misdn_send_facility(), handle_cr(), handle_event_nt(), handle_frm(), manager_event_handler(), misdn_lib_send_restart(), and release_cr().

00078 {
00079    memset (dummybc,0,sizeof(struct misdn_bchannel));
00080    dummybc->port=port;
00081    if (l3id==0)
00082       dummybc->l3_id = MISDN_ID_DUMMY;
00083    else
00084       dummybc->l3_id=l3id;
00085 
00086    dummybc->nt=nt;
00087    dummybc->dummy=1;
00088    dummybc->channel=channel;
00089 }

static void misdn_send_lock ( struct misdn_bchannel bc  )  [static]

Definition at line 3616 of file isdn_lib.c.

References misdn_stack::bc, send_lock::lock, pthread_mutex_lock, and misdn_bchannel::send_lock.

Referenced by misdn_lib_send_event().

03617 {
03618    //cb_log(0,bc->port,"Locking bc->pid:%d\n", bc->pid);
03619    if (bc->send_lock)
03620       pthread_mutex_lock(&bc->send_lock->lock);
03621 }

static void misdn_send_unlock ( struct misdn_bchannel bc  )  [static]

Definition at line 3623 of file isdn_lib.c.

References misdn_stack::bc, send_lock::lock, pthread_mutex_unlock, and misdn_bchannel::send_lock.

Referenced by misdn_lib_send_event().

03624 {
03625    //cb_log(0,bc->port,"UnLocking bc->pid:%d\n", bc->pid);
03626    if (bc->send_lock)
03627       pthread_mutex_unlock(&bc->send_lock->lock);
03628 }

void misdn_split_conf ( struct misdn_bchannel bc,
int  conf_id 
)

Definition at line 4892 of file isdn_lib.c.

References misdn_bchannel::addr, misdn_stack::bc, bc_state_change(), BCHAN_ACTIVATED, cb_log, manager_ph_control(), and misdn_bchannel::port.

Referenced by manager_bchannel_deactivate(), misdn_lib_send_event(), and misdn_lib_split_bridge().

04893 {
04894    bc_state_change(bc,BCHAN_ACTIVATED);
04895    manager_ph_control(bc, CMX_RECEIVE_ON, 0);
04896    manager_ph_control(bc, CMX_CONF_SPLIT, conf_id);
04897 
04898    cb_log(4,bc->port, "Splitting bc:%x in conf:%d\n",bc->addr,conf_id);
04899 }

void misdn_tx_jitter ( struct misdn_bchannel bc,
int  len 
)

Definition at line 2400 of file isdn_lib.c.

References misdn_bchannel::addr, misdn_bchannel::bframe, misdn_bchannel::bframe_len, cb_jb_empty, cb_log, misdn_bchannel::channel, errno, flip_buf_bits(), glob_mgr, misdn_lib::midev, misdn_bchannel::port, and tone_silence_flip.

Referenced by do_tone(), and handle_bchan().

02401 {
02402    char buf[4096 + mISDN_HEADER_LEN];
02403    char *data=&buf[mISDN_HEADER_LEN];
02404    iframe_t *txfrm= (iframe_t*)buf;
02405    int jlen, r;
02406 
02407    jlen=cb_jb_empty(bc,data,len);
02408 
02409    if (jlen) {
02410 #ifdef MISDN_SAVE_DATA
02411       misdn_save_data((bc->port*100+bc->channel), data, jlen, bc->bframe, bc->bframe_len);
02412 #endif
02413       flip_buf_bits( data, jlen);
02414 
02415       if (jlen < len) {
02416          cb_log(1, bc->port, "Jitterbuffer Underrun. Got %d of expected %d\n", jlen, len);
02417       }
02418 
02419       txfrm->prim = DL_DATA|REQUEST;
02420 
02421       txfrm->dinfo = 0;
02422 
02423       txfrm->addr = bc->addr|FLG_MSG_DOWN; /*  | IF_DOWN; */
02424 
02425       txfrm->len =jlen;
02426       cb_log(9, bc->port, "Transmitting %d samples 2 misdn\n", txfrm->len);
02427 
02428       r=mISDN_write( glob_mgr->midev, buf, txfrm->len + mISDN_HEADER_LEN, 8000 );
02429    } else {
02430 #define MISDN_GEN_SILENCE
02431 #ifdef MISDN_GEN_SILENCE
02432       int cnt=len/TONE_SILENCE_SIZE;
02433       int rest=len%TONE_SILENCE_SIZE;
02434       int i;
02435 
02436       for (i=0; i<cnt; i++) {
02437          memcpy(data, tone_silence_flip, TONE_SILENCE_SIZE );
02438          data +=TONE_SILENCE_SIZE;
02439       }
02440 
02441       if (rest) {
02442          memcpy(data, tone_silence_flip, rest);
02443       }
02444 
02445       txfrm->prim = DL_DATA|REQUEST;
02446 
02447       txfrm->dinfo = 0;
02448 
02449       txfrm->addr = bc->addr|FLG_MSG_DOWN; /*  | IF_DOWN; */
02450 
02451       txfrm->len =len;
02452       cb_log(5, bc->port, "Transmitting %d samples of silence to misdn\n", len);
02453 
02454       r=mISDN_write( glob_mgr->midev, buf, txfrm->len + mISDN_HEADER_LEN, 8000 );
02455 #else
02456       r = 0;
02457 #endif
02458    }
02459 
02460    if (r < 0) {
02461       cb_log(1, bc->port, "Error in mISDN_write (%s)\n", strerror(errno));
02462    }
02463 }

static void prepare_bc ( struct misdn_bchannel bc,
int  channel 
) [static]

Definition at line 3291 of file isdn_lib.c.

References misdn_bchannel::addr, AST_CAUSE_NORMAL_CLEARING, misdn_bchannel::b_stid, misdn_bchannel::cause, misdn_bchannel::channel, misdn_bchannel::channel_preselected, misdn_bchannel::in_use, misdn_bchannel::layer_id, mypid, misdn_bchannel::need_disconnect, misdn_bchannel::need_release, misdn_bchannel::need_release_complete, and misdn_bchannel::pid.

Referenced by misdn_lib_get_free_bc().

03292 {
03293    bc->channel = channel;
03294    bc->channel_preselected = channel?1:0;
03295    bc->need_disconnect=1;
03296    bc->need_release=1;
03297    bc->need_release_complete=1;
03298    bc->cause = AST_CAUSE_NORMAL_CLEARING;
03299 
03300    if (++mypid>5000) mypid=1;
03301    bc->pid=mypid;
03302 
03303 #if 0
03304    bc->addr=0;
03305    bc->b_stid=0;
03306    bc->layer_id=0;
03307 #endif
03308 
03309    bc->in_use = 1;
03310 }

int queue_cleanup_bc ( struct misdn_bchannel bc  ) 

Definition at line 4075 of file isdn_lib.c.

References misdn_lib::activatequeue, misdn_stack::bc, cb_log, glob_mgr, misdn_bchannel::l3_id, misdn_lib::new_msg, and misdn_bchannel::port.

04076 {
04077    msg_t *msg=alloc_msg(MAX_MSG_SIZE);
04078    iframe_t *frm;
04079    if (!msg) {
04080       cb_log(0, bc->port, "queue_cleanup_bc: alloc_msg failed!\n");
04081       return -1;
04082    }
04083    frm=(iframe_t*)msg->data;
04084 
04085    /* activate bchannel */
04086    frm->prim = MGR_CLEARSTACK| REQUEST;
04087 
04088    frm->addr = bc->l3_id;
04089 
04090    frm->dinfo = bc->port;
04091    frm->len = 0;
04092 
04093    msg_queue_tail(&glob_mgr->activatequeue, msg);
04094    sem_post(&glob_mgr->new_msg);
04095 
04096    return 0;
04097 
04098 }

static int release_cr ( struct misdn_stack stack,
mISDNuser_head_t *  hh 
) [static]

Definition at line 1924 of file isdn_lib.c.

References misdn_bchannel::addr, cb_log, find_bc_by_l3id(), handle_cr(), misdn_bchannel::l3_id, misdn_make_dummy(), misdn_stack::nt, misdn_stack::port, misdn_stack::procids, and misdn_stack::upper_id.

Referenced by handle_event_nt().

01925 {
01926    struct misdn_bchannel *bc=find_bc_by_l3id(stack, hh->dinfo);
01927    struct misdn_bchannel dummybc;
01928    iframe_t frm; /* fake te frm to remove callref from global callreflist */
01929 
01930    frm.dinfo = hh->dinfo;
01931    frm.addr=stack->upper_id | FLG_MSG_DOWN;
01932    frm.prim = CC_RELEASE_CR|INDICATION;
01933    cb_log(4, stack->port, " --> CC_RELEASE_CR: Faking Release_cr for %x l3id:%x\n",frm.addr, frm.dinfo);
01934 
01935    /** removing procid **/
01936    if (!bc) {
01937       cb_log(4, stack->port, " --> Didn't find BC so temporarily creating dummy BC (l3id:%x) on this port.\n", hh->dinfo);
01938       misdn_make_dummy(&dummybc, stack->port, hh->dinfo, stack->nt, 0);
01939       bc=&dummybc;
01940    }
01941 
01942    if ((bc->l3_id & 0xff00) == 0xff00) {
01943       cb_log(4, stack->port, " --> Removing Process Id:%x on this port.\n", bc->l3_id & 0xff);
01944       stack->procids[bc->l3_id & 0xff] = 0;
01945    }
01946 
01947    if (handle_cr(stack, &frm)<0) {
01948    }
01949 
01950    return 0 ;
01951 }

static int send_msg ( int  midev,
struct misdn_bchannel bc,
msg_t *  dmsg 
) [static]

Definition at line 414 of file isdn_lib.c.

References cb_log, get_stack_by_bc(), misdn_bchannel::l3_id, and misdn_bchannel::port.

Referenced by manager_event_handler().

00415 {
00416    iframe_t *frm = (iframe_t *)dmsg->data;
00417    struct misdn_stack *stack=get_stack_by_bc(bc);
00418 
00419    if (!stack) {
00420       cb_log(0,bc->port,"send_msg: IEK!! no stack\n ");
00421       return -1;
00422    }
00423 
00424    frm->addr = (stack->upper_id | FLG_MSG_DOWN);
00425    frm->dinfo = bc->l3_id;
00426    frm->len = (dmsg->len) - mISDN_HEADER_LEN;
00427 
00428    cb_log(4,stack->port,"Sending msg, prim:%x addr:%x dinfo:%x\n",frm->prim,frm->addr,frm->dinfo);
00429 
00430    mISDN_write(midev, dmsg->data, dmsg->len, TIMEOUT_1SEC);
00431    free_msg(dmsg);
00432 
00433    return 0;
00434 }

static int set_chan_in_stack ( struct misdn_stack stack,
int  channel 
) [static]

Definition at line 496 of file isdn_lib.c.

References ARRAY_LEN, cb_log, misdn_stack::channels, dump_chan_list(), and misdn_stack::port.

00497 {
00498    cb_log(4,stack->port,"set_chan_in_stack: %d\n",channel);
00499    dump_chan_list(stack);
00500    if (1 <= channel && channel <= ARRAY_LEN(stack->channels)) {
00501       if (!stack->channels[channel-1])
00502          stack->channels[channel-1] = 1;
00503       else {
00504          cb_log(4,stack->port,"channel already in use:%d\n", channel );
00505          return -1;
00506       }
00507    } else {
00508       cb_log(0,stack->port,"couldn't set channel %d in\n", channel );
00509       return -1;
00510    }
00511 
00512    return 0;
00513 }

int setup_bc ( struct misdn_bchannel bc  ) 

Definition at line 1073 of file isdn_lib.c.

References misdn_stack::b_num, misdn_bchannel::b_stid, misdn_stack::b_stids, misdn_stack::bc, misdn_bchannel::bc_state, bc_state2str(), BCHAN_CLEANED, buff, cb_log, misdn_bchannel::channel, get_stack_by_bc(), misdn_stack::midev, misdn_stack::port, and misdn_bchannel::port.

Referenced by handle_event(), misdn_lib_send_event(), and misdn_lib_setup_bc().

01074 {
01075    unsigned char buff[1025];
01076    int midev;
01077    int channel;
01078    int b_stid;
01079    int i;
01080    mISDN_pid_t pid;
01081    int ret;
01082 
01083    struct misdn_stack *stack=get_stack_by_bc(bc);
01084 
01085    if (!stack) {
01086       cb_log(0, bc->port, "setup_bc: NO STACK FOUND!!\n");
01087       return -1;
01088    }
01089 
01090    midev = stack->midev;
01091    channel = bc->channel - 1 - (bc->channel > 16);
01092    b_stid = stack->b_stids[channel >= 0 ? channel : 0];
01093 
01094    switch (bc->bc_state) {
01095       case BCHAN_CLEANED:
01096          break;
01097       default:
01098          cb_log(4, stack->port, "$$$ bc already setup stid :%x (state:%s)\n", b_stid, bc_state2str(bc->bc_state) );
01099          return -1;
01100    }
01101 
01102    cb_log(5, stack->port, "$$$ Setting up bc with stid :%x\n", b_stid);
01103 
01104    /*check if the b_stid is already initialized*/
01105    for (i=0; i <= stack->b_num; i++) {
01106       if (stack->bc[i].b_stid == b_stid) {
01107          cb_log(0, bc->port, "setup_bc: b_stid:%x already in use !!!\n", b_stid);
01108          return -1;
01109       }
01110    }
01111 
01112    if (b_stid <= 0) {
01113       cb_log(0, stack->port," -- Stid <=0 at the moment in channel:%d\n",channel);
01114 
01115       bc_state_change(bc,BCHAN_ERROR);
01116       return 1;
01117    }
01118 
01119    bc->b_stid = b_stid;
01120 
01121    {
01122       layer_info_t li;
01123       memset(&li, 0, sizeof(li));
01124 
01125       li.object_id = -1;
01126       li.extentions = 0;
01127 
01128       li.st = bc->b_stid; /*  given idx */
01129 
01130 
01131 #define MISDN_DSP
01132 #ifndef MISDN_DSP
01133       bc->nodsp=1;
01134 #endif
01135       if ( bc->hdlc || bc->nodsp) {
01136          cb_log(4, stack->port,"setup_bc: without dsp\n");
01137          {
01138             int l = sizeof(li.name);
01139             strncpy(li.name, "B L3", l);
01140             li.name[l-1] = 0;
01141          }
01142          li.pid.layermask = ISDN_LAYER((3));
01143          li.pid.protocol[3] = ISDN_PID_L3_B_USER;
01144 
01145          bc->layer=3;
01146       } else {
01147          cb_log(4, stack->port,"setup_bc: with dsp\n");
01148          {
01149             int l = sizeof(li.name);
01150             strncpy(li.name, "B L4", l);
01151             li.name[l-1] = 0;
01152          }
01153          li.pid.layermask = ISDN_LAYER((4));
01154          li.pid.protocol[4] = ISDN_PID_L4_B_USER;
01155 
01156          bc->layer=4;
01157       }
01158 
01159       ret = mISDN_new_layer(midev, &li);
01160       if (ret ) {
01161          cb_log(0, stack->port,"New Layer Err: %d %s\n",ret,strerror(errno));
01162 
01163          bc_state_change(bc,BCHAN_ERROR);
01164          return(-EINVAL);
01165       }
01166 
01167       bc->layer_id = li.id;
01168    }
01169 
01170    memset(&pid, 0, sizeof(pid));
01171 
01172 
01173 
01174    cb_log(4, stack->port," --> Channel is %d\n", bc->channel);
01175 
01176    if (bc->nodsp) {
01177       cb_log(2, stack->port," --> TRANSPARENT Mode (no DSP, no HDLC)\n");
01178       pid.protocol[1] = ISDN_PID_L1_B_64TRANS;
01179       pid.protocol[2] = ISDN_PID_L2_B_TRANS;
01180       pid.protocol[3] = ISDN_PID_L3_B_USER;
01181       pid.layermask = ISDN_LAYER((1)) | ISDN_LAYER((2)) | ISDN_LAYER((3));
01182 
01183    } else if ( bc->hdlc ) {
01184       cb_log(2, stack->port," --> HDLC Mode\n");
01185       pid.protocol[1] = ISDN_PID_L1_B_64HDLC ;
01186       pid.protocol[2] = ISDN_PID_L2_B_TRANS  ;
01187       pid.protocol[3] = ISDN_PID_L3_B_USER;
01188       pid.layermask = ISDN_LAYER((1)) | ISDN_LAYER((2)) | ISDN_LAYER((3)) ;
01189    } else {
01190       cb_log(2, stack->port," --> TRANSPARENT Mode\n");
01191       pid.protocol[1] = ISDN_PID_L1_B_64TRANS;
01192       pid.protocol[2] = ISDN_PID_L2_B_TRANS;
01193       pid.protocol[3] = ISDN_PID_L3_B_DSP;
01194       pid.protocol[4] = ISDN_PID_L4_B_USER;
01195       pid.layermask = ISDN_LAYER((1)) | ISDN_LAYER((2)) | ISDN_LAYER((3)) | ISDN_LAYER((4));
01196 
01197    }
01198 
01199    ret = mISDN_set_stack(midev, bc->b_stid, &pid);
01200 
01201    if (ret){
01202       cb_log(0, stack->port,"$$$ Set Stack Err: %d %s\n",ret,strerror(errno));
01203 
01204       mISDN_write_frame(midev, buff, bc->layer_id, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
01205 
01206       bc_state_change(bc,BCHAN_ERROR);
01207       cb_event(EVENT_BCHAN_ERROR, bc, glob_mgr->user_data);
01208       return(-EINVAL);
01209    }
01210 
01211    ret = mISDN_get_setstack_ind(midev, bc->layer_id);
01212 
01213    if (ret) {
01214       cb_log(0, stack->port,"$$$ Set StackIND Err: %d %s\n",ret,strerror(errno));
01215       mISDN_write_frame(midev, buff, bc->layer_id, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
01216 
01217       bc_state_change(bc,BCHAN_ERROR);
01218       cb_event(EVENT_BCHAN_ERROR, bc, glob_mgr->user_data);
01219       return(-EINVAL);
01220    }
01221 
01222    ret = mISDN_get_layerid(midev, bc->b_stid, bc->layer) ;
01223 
01224    bc->addr = ret>0? ret : 0;
01225 
01226    if (!bc->addr) {
01227       cb_log(0, stack->port,"$$$ Get Layerid Err: %d %s\n",ret,strerror(errno));
01228       mISDN_write_frame(midev, buff, bc->layer_id, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
01229 
01230       bc_state_change(bc,BCHAN_ERROR);
01231       cb_event(EVENT_BCHAN_ERROR, bc, glob_mgr->user_data);
01232       return (-EINVAL);
01233    }
01234 
01235    manager_bchannel_activate(bc);
01236 
01237    bc_state_change(bc,BCHAN_ACTIVATED);
01238 
01239    return 0;
01240 }

static void stack_destroy ( struct misdn_stack stack  )  [static]

Definition at line 1490 of file isdn_lib.c.

References misdn_stack::lower_id, misdn_stack::midev, misdn_stack::nst, misdn_stack::nstlock, misdn_stack::nt, pthread_mutex_destroy, misdn_stack::st_lock, and misdn_stack::upper_id.

Referenced by misdn_lib_destroy().

01491 {
01492    char buf[1024];
01493    if (!stack) return;
01494 
01495    if (stack->nt) {
01496       pthread_mutex_destroy(&stack->nstlock);
01497       cleanup_Isdnl2(&stack->nst);
01498       cleanup_Isdnl3(&stack->nst);
01499    }
01500 
01501    if (stack->lower_id)
01502       mISDN_write_frame(stack->midev, buf, stack->lower_id, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
01503 
01504    if (stack->upper_id)
01505       mISDN_write_frame(stack->midev, buf, stack->upper_id, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
01506 
01507    pthread_mutex_destroy(&stack->st_lock);
01508 }

void stack_holder_add ( struct misdn_stack stack,
struct misdn_bchannel holder 
)

Definition at line 4674 of file isdn_lib.c.

References cb_log, misdn_stack::holding, misdn_bchannel::l3_id, misdn_bchannel::next, misdn_stack::port, and misdn_bchannel::stack_holder.

Referenced by misdn_lib_send_event().

04675 {
04676    struct misdn_bchannel *help;
04677    cb_log(4,stack->port, "*HOLDER: add %x\n",holder->l3_id);
04678 
04679    holder->stack_holder=1;
04680    holder->next=NULL;
04681 
04682    if (!stack->holding) {
04683       stack->holding = holder;
04684       return;
04685    }
04686 
04687    for (help=stack->holding;
04688         help;
04689         help=help->next) {
04690       if (!help->next) {
04691          help->next=holder;
04692          break;
04693       }
04694    }
04695 
04696 }

struct misdn_bchannel * stack_holder_find ( struct misdn_stack stack,
unsigned long  l3id 
)

Definition at line 4724 of file isdn_lib.c.

References cb_log, misdn_stack::holding, misdn_bchannel::l3_id, misdn_bchannel::next, and misdn_stack::port.

Referenced by handle_event_nt(), and misdn_lib_find_held_bc().

04725 {
04726    struct misdn_bchannel *help;
04727 
04728    cb_log(4,stack?stack->port:0, "*HOLDER: find %lx\n",l3id);
04729 
04730    if (!stack) return NULL;
04731 
04732    for (help=stack->holding;
04733         help;
04734         help=help->next) {
04735       if (help->l3_id == l3id) {
04736          cb_log(4,stack->port, "*HOLDER: found bc\n");
04737          return help;
04738       }
04739    }
04740 
04741    cb_log(4,stack->port, "*HOLDER: find nothing\n");
04742    return NULL;
04743 }

void stack_holder_remove ( struct misdn_stack stack,
struct misdn_bchannel holder 
)

Definition at line 4698 of file isdn_lib.c.

References cb_log, misdn_stack::holding, misdn_bchannel::l3_id, misdn_bchannel::next, misdn_stack::port, and misdn_bchannel::stack_holder.

Referenced by handle_cr(), and handle_event_nt().

04699 {
04700    struct misdn_bchannel *h1;
04701 
04702    if (!holder->stack_holder) return;
04703 
04704    holder->stack_holder=0;
04705 
04706    cb_log(4,stack->port, "*HOLDER: remove %x\n",holder->l3_id);
04707    if (!stack || ! stack->holding) return;
04708 
04709    if (holder == stack->holding) {
04710       stack->holding = stack->holding->next;
04711       return;
04712    }
04713 
04714    for (h1=stack->holding;
04715         h1;
04716         h1=h1->next) {
04717       if (h1->next == holder) {
04718          h1->next=h1->next->next;
04719          return ;
04720       }
04721    }
04722 }

static struct misdn_stack* stack_init ( int  midev,
int  port,
int  ptp 
) [static]

Definition at line 1309 of file isdn_lib.c.

References misdn_stack::b_num, misdn_stack::b_stids, buff, calloc, cb_log, misdn_stack::d_stid, misdn_stack::downqueue, misdn_stack::holding, misdn_stack::midev, misdn_stack::nt, misdn_stack::port, misdn_stack::pri, pthread_mutex_init, misdn_stack::ptp, misdn_stack::st_lock, and misdn_stack::upqueue.

Referenced by misdn_lib_init().

01310 {
01311    int ret;
01312    unsigned char buff[1025];
01313    iframe_t *frm = (iframe_t *)buff;
01314    stack_info_t *stinf;
01315    struct misdn_stack *stack;
01316    int i;
01317    layer_info_t li;
01318 
01319    stack = calloc(1, sizeof(struct misdn_stack));
01320    if (!stack) {
01321       return NULL;
01322    }
01323 
01324    cb_log(8, port, "Init. Stack.\n");
01325 
01326    stack->port=port;
01327    stack->midev=midev;
01328    stack->ptp=ptp;
01329 
01330    stack->holding=NULL;
01331    stack->pri=0;
01332 
01333    msg_queue_init(&stack->downqueue);
01334    msg_queue_init(&stack->upqueue);
01335 
01336    pthread_mutex_init(&stack->st_lock, NULL);
01337 
01338    /* query port's requirements */
01339    ret = mISDN_get_stack_info(midev, port, buff, sizeof(buff));
01340    if (ret < 0) {
01341       cb_log(0, port, "%s: Cannot get stack info for this port. (ret=%d)\n", __FUNCTION__, ret);
01342       return(NULL);
01343    }
01344 
01345    stinf = (stack_info_t *)&frm->data.p;
01346 
01347    stack->d_stid = stinf->id;
01348    stack->b_num = stinf->childcnt;
01349 
01350    for (i=0; i<=stinf->childcnt; i++)
01351       stack->b_stids[i] = stinf->child[i];
01352 
01353    switch(stinf->pid.protocol[0] & ~ISDN_PID_FEATURE_MASK) {
01354    case ISDN_PID_L0_TE_S0:
01355       stack->nt=0;
01356       break;
01357    case ISDN_PID_L0_NT_S0:
01358       cb_log(8, port, "NT Stack\n");
01359 
01360       stack->nt=1;
01361       break;
01362    case ISDN_PID_L0_TE_E1:
01363       cb_log(8, port, "TE S2M Stack\n");
01364       stack->nt=0;
01365       stack->pri=1;
01366       break;
01367    case ISDN_PID_L0_NT_E1:
01368       cb_log(8, port, "TE S2M Stack\n");
01369       stack->nt=1;
01370       stack->pri=1;
01371 
01372       break;
01373    default:
01374       cb_log(0, port, "this is a unknown port type 0x%08x\n", stinf->pid.protocol[0]);
01375 
01376    }
01377 
01378    if (!stack->nt) {
01379       if (stinf->pid.protocol[2] & ISDN_PID_L2_DF_PTP ) {
01380          stack->ptp = 1;
01381       } else {
01382          stack->ptp = 0;
01383       }
01384    }
01385 
01386    {
01387       int ret;
01388       int nt=stack->nt;
01389 
01390       cb_log(8, port, "Init. Stack.\n");
01391 
01392       memset(&li, 0, sizeof(li));
01393       {
01394          int l = sizeof(li.name);
01395          strncpy(li.name,nt?"net l2":"user l4", l);
01396          li.name[l-1] = 0;
01397       }
01398       li.object_id = -1;
01399       li.extentions = 0;
01400       li.pid.protocol[nt?2:4] = nt?ISDN_PID_L2_LAPD_NET:ISDN_PID_L4_CAPI20;
01401       li.pid.layermask = ISDN_LAYER((nt?2:4));
01402       li.st = stack->d_stid;
01403 
01404 
01405       ret = mISDN_new_layer(midev, &li);
01406       if (ret) {
01407          cb_log(0, port, "%s: Cannot add layer %d to this port.\n", __FUNCTION__, nt?2:4);
01408          return(NULL);
01409       }
01410 
01411 
01412       stack->upper_id = li.id;
01413       ret = mISDN_register_layer(midev, stack->d_stid, stack->upper_id);
01414       if (ret)
01415       {
01416          cb_log(0,port,"Cannot register layer %d of this port.\n", nt?2:4);
01417          return(NULL);
01418       }
01419 
01420       stack->lower_id = mISDN_get_layerid(midev, stack->d_stid, nt?1:3);
01421       if (stack->lower_id < 0) {
01422          cb_log(0, port, "%s: Cannot get layer(%d) id of this port.\n", __FUNCTION__, nt?1:3);
01423          return(NULL);
01424       }
01425 
01426       stack->upper_id = mISDN_get_layerid(midev, stack->d_stid, nt?2:4);
01427       if (stack->upper_id < 0) {
01428          cb_log(0, port, "%s: Cannot get layer(%d) id of this port.\n", __FUNCTION__, 2);
01429          return(NULL);
01430       }
01431 
01432       cb_log(8, port, "NT Stacks upper_id %x\n",stack->upper_id);
01433 
01434 
01435       /* create nst (nt-mode only) */
01436       if (nt) {
01437 
01438          memset(&stack->nst, 0, sizeof(net_stack_t));
01439          memset(&stack->mgr, 0, sizeof(manager_t));
01440 
01441          stack->mgr.nst = &stack->nst;
01442          stack->nst.manager = &stack->mgr;
01443 
01444          stack->nst.l3_manager = handle_event_nt;
01445          stack->nst.device = midev;
01446          stack->nst.cardnr = port;
01447          stack->nst.d_stid = stack->d_stid;
01448 
01449          stack->nst.feature = FEATURE_NET_HOLD;
01450          if (stack->ptp)
01451             stack->nst.feature |= FEATURE_NET_PTP;
01452          if (stack->pri)
01453             stack->nst.feature |= FEATURE_NET_CRLEN2 | FEATURE_NET_EXTCID;
01454 
01455          stack->nst.l1_id = stack->lower_id;
01456          stack->nst.l2_id = stack->upper_id;
01457 
01458          msg_queue_init(&stack->nst.down_queue);
01459          pthread_mutex_init(&stack->nstlock, NULL);
01460 
01461          Isdnl2Init(&stack->nst);
01462          Isdnl3Init(&stack->nst);
01463 
01464       }
01465 
01466       stack->l1link=0;
01467       stack->l2link=0;
01468 #if 0
01469       if (!stack->nt) {
01470          misdn_lib_get_short_status(stack);
01471       } else {
01472          misdn_lib_get_l1_up(stack);
01473          if (!stack->ptp) misdn_lib_get_l1_up(stack);
01474          misdn_lib_get_l2_up(stack);
01475       }
01476 #endif
01477 
01478       misdn_lib_get_short_status(stack);
01479       misdn_lib_get_l1_up(stack);
01480       misdn_lib_get_l2_up(stack);
01481 
01482    }
01483 
01484    cb_log(8,0,"stack_init: port:%d lowerId:%x  upperId:%x\n",stack->port,stack->lower_id, stack->upper_id);
01485 
01486    return stack;
01487 }

void te_lib_destroy ( int  midev  ) 

Definition at line 3243 of file isdn_lib.c.

References cb_log, and entity.

Referenced by misdn_lib_destroy().

03244 {
03245    char buf[1024];
03246    mISDN_write_frame(midev, buf, 0, MGR_DELENTITY | REQUEST, entity, 0, NULL, TIMEOUT_1SEC);
03247 
03248    cb_log(4, 0, "Entity deleted\n");
03249    mISDN_close(midev);
03250    cb_log(4, 0, "midev closed\n");
03251 }

static int te_lib_init ( void   )  [static]

App Interface

Definition at line 3218 of file isdn_lib.c.

References buff, entity, errno, and misdn_lib::midev.

Referenced by misdn_lib_init().

03219 {
03220    char buff[1025] = "";
03221    iframe_t *frm = (iframe_t *) buff;
03222    int midev;
03223    int ret;
03224 
03225    midev = mISDN_open();
03226    if (midev <= 0) {
03227       return midev;
03228    }
03229 
03230    /* create entity for layer 3 TE-mode */
03231    mISDN_write_frame(midev, buff, 0, MGR_NEWENTITY | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
03232 
03233    ret = mISDN_read_frame(midev, frm, sizeof(iframe_t), 0, MGR_NEWENTITY | CONFIRM, TIMEOUT_1SEC);
03234    entity = frm->dinfo & 0xffff;
03235    if (ret < mISDN_HEADER_LEN || !entity) {
03236       fprintf(stderr, "cannot request MGR_NEWENTITY from mISDN: %s\n", strerror(errno));
03237       exit(-1);
03238    }
03239 
03240    return midev;
03241 }

static int test_inuse ( struct misdn_bchannel bc  )  [static]

Definition at line 3269 of file isdn_lib.c.

References misdn_bchannel::b_stid, cb_log, misdn_bchannel::in_use, misdn_bchannel::last_used, misdn_lib_port_is_pri(), and misdn_bchannel::port.

Referenced by misdn_lib_get_free_bc().

03270 {
03271    struct timeval now;
03272 
03273    if (!bc->in_use) {
03274       gettimeofday(&now, NULL);
03275       if (bc->last_used.tv_sec == now.tv_sec
03276          && misdn_lib_port_is_pri(bc->port)) {
03277          cb_log(2, bc->port, "channel with stid:%x for one second still in use! (n:%d lu:%d)\n",
03278             bc->b_stid, (int) now.tv_sec, (int) bc->last_used.tv_sec);
03279          return 1;
03280       }
03281 
03282       cb_log(3,bc->port, "channel with stid:%x not in use!\n", bc->b_stid);
03283       return 0;
03284    }
03285 
03286    cb_log(2,bc->port, "channel with stid:%x in use!\n", bc->b_stid);
03287    return 1;
03288 }


Variable Documentation

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

Definition at line 28 of file isdn_lib.c.

Referenced by clear_l3(), do_tone(), handle_bchan(), handle_cr(), handle_event_nt(), handle_frm(), handle_l1(), handle_l2(), manager_clean_bc(), misdn_lib_init(), and set_channel().

int(*) cb_jb_empty(struct misdn_bchannel *bc, char *buffer, int len)

Definition at line 33 of file isdn_lib.c.

Referenced by misdn_lib_init(), and misdn_tx_jitter().

void(*) cb_log(int level, int port, char *tmpl,...)

Definition at line 30 of file isdn_lib.c.

Referenced by bc_next_state_change(), bc_state_change(), build_connect(), build_disconnect(), build_release(), build_release_complete(), build_restart(), build_setup(), cb_events(), clean_up_bc(), config_jitterbuffer(), create_process(), dec_ie_facility(), dump_chan_list(), empty_chan_in_stack(), fetch_msg(), find_free_chan_in_stack(), handle_bchan(), handle_cr(), handle_err(), handle_event(), handle_event_nt(), handle_frm(), handle_frm_nt(), handle_l1(), handle_l2(), handle_mgmt(), handle_timers(), hangup_chan(), init_bc(), isdn_msg_get_index_by_event(), manager_bchannel_activate(), manager_bchannel_deactivate(), manager_ec_disable(), manager_ec_enable(), manager_event_handler(), manager_isdn_handler(), manager_ph_control(), misdn_join_conf(), misdn_lib_bridge(), misdn_lib_destroy(), misdn_lib_echo(), misdn_lib_get_free_bc(), misdn_lib_get_l1_down(), misdn_lib_get_port_info(), misdn_lib_init(), misdn_lib_isdn_event_catcher(), misdn_lib_isdn_l1watcher(), misdn_lib_log_ies(), misdn_lib_port_restart(), misdn_lib_port_up(), misdn_lib_release(), misdn_lib_send_event(), misdn_lib_send_restart(), misdn_lib_split_bridge(), misdn_lib_tx2misdn_frm(), misdn_split_conf(), misdn_tasks_destroy(), misdn_tx_jitter(), parse_facility(), parse_release_complete(), parse_restart(), parse_setup(), queue_cleanup_bc(), release_cr(), send_msg(), set_chan_in_stack(), set_channel(), setup_bc(), stack_holder_add(), stack_holder_find(), stack_holder_remove(), stack_init(), te_lib_destroy(), and test_inuse().

int entity [static]

Definition at line 263 of file isdn_lib.c.

Referenced by pidf_validate_presence(), te_lib_destroy(), and te_lib_init().

char flip_table[256] [static]

Definition at line 323 of file isdn_lib.c.

struct misdn_lib* glob_mgr [static]

Definition at line 265 of file isdn_lib.c.

Referenced by do_tone(), find_bc_by_addr(), find_bc_by_confid(), find_stack_by_addr(), find_stack_by_mgr(), find_stack_by_port(), get_misdn_stack(), handle_bchan(), handle_cr(), handle_event_nt(), handle_frm(), handle_l1(), handle_l2(), handle_timers(), manager_event_handler(), manager_find_bc_by_pid(), manager_ph_control(), manager_ph_control_block(), misdn_lib_destroy(), misdn_lib_get_port_down(), misdn_lib_get_port_info(), misdn_lib_get_port_up(), misdn_lib_init(), misdn_lib_isdn_l1watcher(), misdn_lib_port_restart(), misdn_lib_port_up(), misdn_lib_reinit_nt_stack(), misdn_lib_send_event(), misdn_lib_send_tone(), misdn_tx_jitter(), and queue_cleanup_bc().

enum global_states global_state = MISDN_INITIALIZING [static]

Definition at line 199 of file isdn_lib.c.

Referenced by clear_l3(), handle_l1(), misdn_lib_destroy(), and misdn_lib_init().

sem_t handler_started [static]

Definition at line 4190 of file isdn_lib.c.

struct isdn_msg msgs_g[]

Msg Array

Definition at line 1689 of file isdn_msg_parser.c.

Referenced by handle_event_nt(), handle_frm(), handle_l1(), manager_isdn_get_info(), and misdn_lib_send_event().

int mypid = 1 [static]

Definition at line 437 of file isdn_lib.c.

Referenced by prepare_bc().

int new_te_id = 0 [static]

Definition at line 888 of file isdn_lib.c.

int nt_err_cnt = 0 [static]

Definition at line 192 of file isdn_lib.c.

Referenced by handle_frm_nt().

char tone_425_flip[TONE_425_SIZE] [static]

Definition at line 267 of file isdn_lib.c.

Referenced by misdn_lib_init().

char tone_silence_flip[TONE_SILENCE_SIZE] [static]

Definition at line 268 of file isdn_lib.c.

Referenced by misdn_lib_init(), and misdn_tx_jitter().


Generated on Wed Apr 6 11:30:05 2011 for Asterisk - The Open Source Telephony Project by  doxygen 1.4.7