Mon Oct 8 12:39:23 2012

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 42 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_exten_to_pattern_tree(), 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_get_http_method(), ast_getformatbyname(), ast_getformatname(), ast_getformatname_multiple(), ast_hook_send_action(), 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_set_default_eid(), 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_DEFINE(), 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(), dispatch_thread_handler(), do_message(), 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(), parse_sip_options(), 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_aoc_d_from_ast(), sig_pri_aoc_e_from_ast(), sig_pri_mwi_cache_update(), sig_pri_start_pri(), sig_pri_stop_pri(), 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(), wait_for_winner(), xmldoc_get_syntax_type(), xmldoc_has_specialtags(), and xmldoc_parse_specialtags().

#define ECHOCAN_OFF   124

Definition at line 234 of file isdn_lib.c.

Referenced by manager_ec_disable().

#define ECHOCAN_ON   123

Definition at line 233 of file isdn_lib.c.

Referenced by manager_ec_enable().

#define ISDN_PID_L3_B_USER   0x430000ff

Definition at line 252 of file isdn_lib.c.

#define ISDN_PID_L4_B_USER   0x440000ff

Definition at line 253 of file isdn_lib.c.

#define MISDN_DEBUG   0

Definition at line 237 of file isdn_lib.c.

#define MISDN_DSP

#define MISDN_GEN_SILENCE

#define MISDN_IBUF_SIZE   512

Definition at line 256 of file isdn_lib.c.

Referenced by init_bc().

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

Definition at line 3615 of file isdn_lib.c.

Referenced by misdn_lib_send_event().

#define TONE_ALERT_CNT   41

Definition at line 259 of file isdn_lib.c.

#define TONE_ALERT_SILENCE_CNT   200

Definition at line 260 of file isdn_lib.c.

#define TONE_BUSY_CNT   20

Definition at line 262 of file isdn_lib.c.

#define TONE_BUSY_SILENCE_CNT   48

Definition at line 263 of file isdn_lib.c.


Enumeration Type Documentation

enum global_states

Enumerator:
MISDN_INITIALIZING 
MISDN_INITIALIZED 

Definition at line 196 of file isdn_lib.c.

00196                    {
00197    MISDN_INITIALIZING,
00198    MISDN_INITIALIZED
00199 } ;


Function Documentation

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

Definition at line 672 of file isdn_lib.c.

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

Referenced by misdn_lib_bridge().

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

char* bc_state2str ( enum bchannel_state  state  ) 

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

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

void bc_state_change ( struct misdn_bchannel bc,
enum bchannel_state  state 
)

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

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

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 296 of file isdn_lib.c.

References INFO_CAPABILITY_AUDIO_3_1K, INFO_CAPABILITY_DIGITAL_RESTRICTED, INFO_CAPABILITY_DIGITAL_UNRESTRICTED, and INFO_CAPABILITY_SPEECH.

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

static int clean_up_bc ( struct misdn_bchannel bc  )  [static]

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

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

static void clear_l3 ( struct misdn_stack stack  )  [static]

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

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

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

Definition at line 355 of file isdn_lib.c.

Referenced by misdn_lib_get_l2_down(), and misdn_lib_get_l2_up().

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

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

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

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

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

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

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

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

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

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

static void dump_chan_list ( struct misdn_stack stack  )  [static]

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

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

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

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

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

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

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

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

Definition at line 3446 of file isdn_lib.c.

References ARRAY_LEN, and name.

Referenced by misdn_lib_log_ies().

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

static msg_t* fetch_msg ( int  midev  )  [static]

Definition at line 3114 of file isdn_lib.c.

References cb_log, and errno.

Referenced by misdn_lib_isdn_event_catcher().

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Definition at line 1542 of file isdn_lib.c.

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

Referenced by handle_event_nt().

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

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

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

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

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

Definition at line 340 of file isdn_lib.c.

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

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

struct misdn_stack * get_misdn_stack ( void   ) 

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

04867 {
04868    return glob_mgr->stack_list;
04869 }

void get_show_stack_details ( int  port,
char *  buf 
)

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

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

struct misdn_stack* get_stack_by_bc ( struct misdn_bchannel bc  ) 

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

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

static int handle_bchan ( msg_t *  msg  )  [static]

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

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

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

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

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

static int handle_err ( msg_t *  msg  )  [static]

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

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

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

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

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

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

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

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

static int handle_frm ( msg_t *  msg  )  [static]

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

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

static int handle_frm_nt ( msg_t *  msg  )  [static]

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

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

static int handle_l1 ( msg_t *  msg  )  [static]

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

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

static int handle_l2 ( msg_t *  msg  )  [static]

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

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

static int handle_mgmt ( msg_t *  msg  )  [static]

Definition at line 3035 of file isdn_lib.c.

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

Referenced by manager_isdn_handler().

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

static int handle_timers ( msg_t *  msg  )  [static]

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

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

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

IFACE

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

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

static void init_flip_bits ( void   )  [static]

Definition at line 327 of file isdn_lib.c.

Referenced by misdn_lib_init().

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

void isdn_lib_stop_dtmf ( struct misdn_bchannel bc  ) 

Definition at line 4628 of file isdn_lib.c.

References misdn_stack::bc, and manager_ph_control().

Referenced by process_ast_dsp().

04629 {
04630    manager_ph_control(bc, DTMF_TONE_STOP, 0);
04631 }

void isdn_lib_update_ec ( struct misdn_bchannel bc  ) 

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

04617 {
04618 #ifdef MISDN_1_2
04619    if (*bc->pipeline)
04620 #else
04621    if (bc->ec_enable)
04622 #endif
04623       manager_ec_enable(bc);
04624    else
04625       manager_ec_disable(bc);
04626 }

void isdn_lib_update_rxgain ( struct misdn_bchannel bc  ) 

Definition at line 4606 of file isdn_lib.c.

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

Referenced by process_ast_dsp().

04607 {
04608    manager_ph_control(bc, VOL_CHANGE_RX, bc->rxgain);
04609 }

void isdn_lib_update_txgain ( struct misdn_bchannel bc  ) 

Definition at line 4611 of file isdn_lib.c.

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

Referenced by process_ast_dsp().

04612 {
04613    manager_ph_control(bc, VOL_CHANGE_TX, bc->txgain);
04614 }

void manager_bchannel_activate ( struct misdn_bchannel bc  ) 

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

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

void manager_bchannel_cleanup ( struct misdn_bchannel bc  ) 

void manager_bchannel_deactivate ( struct misdn_bchannel bc  ) 

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

04518 {
04519    struct misdn_stack *stack=get_stack_by_bc(bc);
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    mISDN_write_frame(stack->midev, buf, bc->addr | FLG_MSG_DOWN, DL_RELEASE|REQUEST,0,0,NULL, TIMEOUT_1SEC);
04539 
04540    clear_ibuffer(bc->astbuf);
04541 
04542    bc_state_change(bc,BCHAN_RELEASE);
04543 
04544    return;
04545 }

void manager_bchannel_setup ( struct misdn_bchannel bc  ) 

void manager_clean_bc ( struct misdn_bchannel bc  ) 

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

04656 {
04657    struct misdn_stack *stack=get_stack_by_bc(bc);
04658 
04659    if (stack && bc->channel > 0) {
04660       empty_chan_in_stack(stack, bc->channel);
04661    }
04662    empty_bc(bc);
04663    bc->in_use=0;
04664 
04665    cb_event(EVENT_CLEANUP, bc, NULL);
04666 }

void manager_ec_disable ( struct misdn_bchannel bc  ) 

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

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

void manager_ec_enable ( struct misdn_bchannel bc  ) 

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

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

static void manager_event_handler ( void *  arg  )  [static]

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

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

struct misdn_bchannel * manager_find_bc_by_pid ( int  pid  ) 

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

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

char* manager_isdn_get_info ( enum event_e  event  ) 

Definition at line 4490 of file isdn_lib.c.

References isdn_get_info(), and msgs_g.

Referenced by cb_events().

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

int manager_isdn_handler ( iframe_t *  frm,
msg_t *  msg 
)

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

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

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

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

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

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

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

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

int misdn_cap_is_speech ( int  cap  ) 

Poor mans version

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

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

void misdn_dump_chanlist ( void   ) 

Definition at line 489 of file isdn_lib.c.

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

Referenced by handle_cli_misdn_show_channels().

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

int misdn_inband_avail ( struct misdn_bchannel bc  ) 

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

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

void misdn_join_conf ( struct misdn_bchannel bc,
int  conf_id 
)

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

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

void misdn_lib_bridge ( struct misdn_bchannel bc1,
struct misdn_bchannel bc2 
)

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

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

void misdn_lib_destroy ( void   ) 

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

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

void misdn_lib_echo ( struct misdn_bchannel bc,
int  onoff 
)

Definition at line 4939 of file isdn_lib.c.

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

04940 {
04941    cb_log(3,bc->port, " --> ECHO %s\n", onoff?"ON":"OFF");
04942    manager_ph_control(bc, onoff?CMX_ECHO_ON:CMX_ECHO_OFF, 0);
04943 }

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

04749 {
04750    struct misdn_bchannel *bc;
04751    struct misdn_stack *stack;
04752 
04753    bc = NULL;
04754    for (stack = get_misdn_stack(); stack; stack = stack->next) {
04755       if (stack->port == port) {
04756          bc = stack_holder_find(stack, l3_id);
04757          break;
04758       }
04759    }
04760 
04761    return bc;
04762 }

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

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

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

static int misdn_lib_get_l1_down ( struct misdn_stack stack  )  [static]

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

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

static int misdn_lib_get_l1_up ( struct misdn_stack stack  )  [static]

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

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

static int misdn_lib_get_l2_down ( struct misdn_stack stack  )  [static]

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

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

int misdn_lib_get_l2_up ( struct misdn_stack stack  ) 

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

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

int misdn_lib_get_maxchans ( int  port  ) 

Definition at line 139 of file isdn_lib.c.

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

Referenced by misdn_request().

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

int misdn_lib_get_port_down ( int  port  ) 

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

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

int misdn_lib_get_port_info ( int  port  ) 

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

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

int misdn_lib_get_port_up ( int  port  ) 

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

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

static int misdn_lib_get_short_status ( struct misdn_stack stack  )  [static]

Definition at line 989 of file isdn_lib.c.

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

Referenced by misdn_lib_isdn_l1watcher().

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

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

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

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

int misdn_lib_is_port_blocked ( int  port  ) 

Definition at line 119 of file isdn_lib.c.

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

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

int misdn_lib_is_ptp ( int  port  ) 

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

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

static void misdn_lib_isdn_event_catcher ( void *  arg  )  [static]

Definition at line 3171 of file isdn_lib.c.

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

Referenced by misdn_lib_init().

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

void misdn_lib_isdn_l1watcher ( int  port  ) 

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

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

void misdn_lib_log_ies ( struct misdn_bchannel bc  ) 

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

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

int misdn_lib_maxports_get ( void   ) 

Definition at line 4292 of file isdn_lib.c.

Referenced by load_module().

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

void misdn_lib_nt_debug_init ( int  flags,
char *  file 
)

Definition at line 4322 of file isdn_lib.c.

References f.

Referenced by load_module(), and misdn_lib_init().

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

void misdn_lib_nt_keepcalls ( int  kc  ) 

Definition at line 4310 of file isdn_lib.c.

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

Referenced by load_module().

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

int misdn_lib_pid_restart ( int  pid  ) 

Definition at line 4101 of file isdn_lib.c.

References manager_clean_bc(), and manager_find_bc_by_pid().

Referenced by handle_cli_misdn_restart_pid().

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

int misdn_lib_port_block ( int  port  ) 

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

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

int misdn_lib_port_is_nt ( int  port  ) 

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

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

int misdn_lib_port_is_pri ( int  port  ) 

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

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

int misdn_lib_port_restart ( int  port  ) 

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

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

int misdn_lib_port_unblock ( int  port  ) 

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

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

int misdn_lib_port_up ( int  port,
int  check 
)

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

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

void misdn_lib_reinit_nt_stack ( int  port  ) 

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

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

void misdn_lib_release ( struct misdn_bchannel bc  ) 

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

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

int misdn_lib_send_event ( struct misdn_bchannel bc,
enum event_e  event 
)

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

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

int misdn_lib_send_restart ( int  port,
int  channel 
)

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

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

void misdn_lib_send_tone ( struct misdn_bchannel bc,
enum tone_e  tone 
)

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

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

void misdn_lib_setup_bc ( struct misdn_bchannel bc  ) 

Definition at line 1068 of file isdn_lib.c.

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

01069 {
01070    clean_up_bc(bc);
01071    setup_bc(bc);
01072 }

void misdn_lib_split_bridge ( struct misdn_bchannel bc1,
struct misdn_bchannel bc2 
)

Definition at line 4919 of file isdn_lib.c.

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

Referenced by misdn_bridge().

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

void misdn_lib_tone_generator_start ( struct misdn_bchannel bc  ) 

Definition at line 2342 of file isdn_lib.c.

References misdn_bchannel::generate_tone.

Referenced by misdn_write().

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

void misdn_lib_tone_generator_stop ( struct misdn_bchannel bc  ) 

Definition at line 2347 of file isdn_lib.c.

References misdn_bchannel::generate_tone.

Referenced by start_bc_tones(), and stop_indicate().

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

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

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

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

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

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

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

static void misdn_send_lock ( struct misdn_bchannel bc  )  [static]

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

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

static void misdn_send_unlock ( struct misdn_bchannel bc  )  [static]

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

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

void misdn_split_conf ( struct misdn_bchannel bc,
int  conf_id 
)

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

04888 {
04889    bc_state_change(bc,BCHAN_ACTIVATED);
04890    manager_ph_control(bc, CMX_RECEIVE_ON, 0);
04891    manager_ph_control(bc, CMX_CONF_SPLIT, conf_id);
04892 
04893    cb_log(4,bc->port, "Splitting bc:%x in conf:%d\n",bc->addr,conf_id);
04894 }

void misdn_tx_jitter ( struct misdn_bchannel bc,
int  len 
)

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

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

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

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

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

int queue_cleanup_bc ( struct misdn_bchannel bc  ) 

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

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

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

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

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

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

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

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

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

Definition at line 498 of file isdn_lib.c.

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

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

int setup_bc ( struct misdn_bchannel bc  ) 

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

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

static void stack_destroy ( struct misdn_stack stack  )  [static]

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

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

void stack_holder_add ( struct misdn_stack stack,
struct misdn_bchannel holder 
)

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

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

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

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

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

void stack_holder_remove ( struct misdn_stack stack,
struct misdn_bchannel holder 
)

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

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

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

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

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

void te_lib_destroy ( int  midev  ) 

Definition at line 3244 of file isdn_lib.c.

References cb_log, and entity.

Referenced by misdn_lib_destroy().

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

static int te_lib_init ( void   )  [static]

App Interface

Definition at line 3219 of file isdn_lib.c.

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

Referenced by misdn_lib_init().

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

static int test_inuse ( struct misdn_bchannel bc  )  [static]

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

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


Variable Documentation

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

Definition at line 30 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 35 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 32 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 265 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 325 of file isdn_lib.c.

struct misdn_lib* glob_mgr [static]

Definition at line 267 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 201 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 4191 of file isdn_lib.c.

struct isdn_msg msgs_g[]

Msg Array

Definition at line 1631 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 439 of file isdn_lib.c.

Referenced by prepare_bc().

int new_te_id = 0 [static]

Definition at line 890 of file isdn_lib.c.

int nt_err_cnt = 0 [static]

Definition at line 194 of file isdn_lib.c.

Referenced by handle_frm_nt().

char tone_425_flip[TONE_425_SIZE] [static]

Definition at line 269 of file isdn_lib.c.

Referenced by misdn_lib_init().

char tone_silence_flip[TONE_SILENCE_SIZE] [static]

Definition at line 270 of file isdn_lib.c.

Referenced by misdn_lib_init(), and misdn_tx_jitter().


Generated on Mon Oct 8 12:39:23 2012 for Asterisk - The Open Source Telephony Project by  doxygen 1.4.7