X-Git-Url: http://git.eversberg.eu/gitweb.cgi?p=lcr.git;a=blobdiff_plain;f=mISDN.cpp;h=98e2c6c4c5a0ac74c91399663121bab2361cde47;hp=8e7d71206e44a548097a437f41584de52ab2f383;hb=b2a665f8f1cdeb7d02c3f665d95e6a80297e21d1;hpb=d2b113f2c4f11acfaee1b2e0fd2f03744a89f6d4 diff --git a/mISDN.cpp b/mISDN.cpp index 8e7d712..98e2c6c 100644 --- a/mISDN.cpp +++ b/mISDN.cpp @@ -13,6 +13,8 @@ #include "myisdn.h" extern "C" { +#define MISDN_OLD_AF_COMPATIBILITY 1 +#include } #include @@ -46,6 +48,8 @@ int mISDN_initialize(void) { char filename[256]; + init_af_isdn(); + /* try to open raw socket to check kernel */ mISDNsocket = socket(PF_ISDN, SOCK_RAW, ISDN_P_BASE); if (mISDNsocket < 0) @@ -91,7 +95,7 @@ void mISDN_deinitialize(void) /* * constructor */ -PmISDN::PmISDN(int type, mISDNport *mISDNport, char *portname, struct port_settings *settings, int channel, int exclusive) : Port(type, portname, settings) +PmISDN::PmISDN(int type, mISDNport *mISDNport, char *portname, struct port_settings *settings, int channel, int exclusive, int mode) : Port(type, portname, settings) { p_m_mISDNport = mISDNport; p_m_portnum = mISDNport->portnum; @@ -99,6 +103,7 @@ PmISDN::PmISDN(int type, mISDNport *mISDNport, char *portname, struct port_setti p_m_b_channel = 0; p_m_b_exclusive = 0; p_m_b_reserve = 0; + p_m_b_mode = mode; p_m_delete = 0; p_m_hold = 0; p_m_tx_gain = mISDNport->ifport->interface->tx_gain; @@ -191,10 +196,10 @@ PmISDN::~PmISDN() /* * trace */ -void chan_trace_header(struct mISDNport *mISDNport, class PmISDN *port, char *msgtext, int direction) +void chan_trace_header(struct mISDNport *mISDNport, class PmISDN *port, const char *msgtext, int direction) { /* init trace with given values */ - start_trace(mISDNport?mISDNport->portnum:0, + start_trace(mISDNport?mISDNport->portnum:-1, (mISDNport)?((mISDNport->ifport)?mISDNport->ifport->interface:NULL):NULL, port?numberrize_callerinfo(port->p_callerinfo.id, port->p_callerinfo.ntype, options.national, options.international):NULL, port?port->p_dialinginfo.id:NULL, @@ -209,7 +214,7 @@ void chan_trace_header(struct mISDNport *mISDNport, class PmISDN *port, char *ms * layer trace header */ static struct isdn_message { - char *name; + const char *name; unsigned int value; } isdn_message[] = { {"PH_ACTIVATE", L1_ACTIVATE_REQ}, @@ -249,7 +254,7 @@ static struct isdn_message { {"MT_RELEASE_L3ID", L3_RELEASE_L3ID_REQ}, {NULL, 0}, }; -static char *isdn_prim[4] = { +static const char *isdn_prim[4] = { " REQUEST", " CONFIRM", " INDICATION", @@ -258,8 +263,9 @@ static char *isdn_prim[4] = { void l1l2l3_trace_header(struct mISDNport *mISDNport, class PmISDN *port, unsigned int msg, int direction) { int i; - char msgtext[64] = "<>"; + char msgtext[64]; + SCPY(msgtext, "<>"); /* select message and primitive text */ i = 0; while(isdn_message[i].name) @@ -295,7 +301,7 @@ void l1l2l3_trace_header(struct mISDNport *mISDNport, class PmISDN *port, unsign } /* init trace with given values */ - start_trace(mISDNport?mISDNport->portnum:0, + start_trace(mISDNport?mISDNport->portnum:-1, mISDNport?(mISDNport->ifport?mISDNport->ifport->interface:NULL):NULL, port?numberrize_callerinfo(port->p_callerinfo.id, port->p_callerinfo.ntype, options.national, options.international):NULL, port?port->p_dialinginfo.id:NULL, @@ -309,7 +315,7 @@ void l1l2l3_trace_header(struct mISDNport *mISDNport, class PmISDN *port, unsign /* * send control information to the channel (dsp-module) */ -void ph_control(struct mISDNport *mISDNport, class PmISDN *isdnport, int sock, unsigned int c1, unsigned int c2, char *trace_name, int trace_value) +void ph_control(struct mISDNport *mISDNport, class PmISDN *isdnport, int sock, unsigned int c1, unsigned int c2, const char *trace_name, int trace_value) { unsigned char buffer[MISDN_HEADER_LEN+sizeof(int)+sizeof(int)]; struct mISDNhead *ctrl = (struct mISDNhead *)buffer; @@ -334,7 +340,7 @@ void ph_control(struct mISDNport *mISDNport, class PmISDN *isdnport, int sock, u end_trace(); } -void ph_control_block(struct mISDNport *mISDNport, class PmISDN *isdnport, int sock, unsigned int c1, void *c2, int c2_len, char *trace_name, int trace_value) +void ph_control_block(struct mISDNport *mISDNport, class PmISDN *isdnport, int sock, unsigned int c1, void *c2, int c2_len, const char *trace_name, int trace_value) { unsigned char buffer[MISDN_HEADER_LEN+sizeof(int)+c2_len]; struct mISDNhead *ctrl = (struct mISDNhead *)buffer; @@ -375,8 +381,8 @@ static int _bchannel_create(struct mISDNport *mISDNport, int i) /* open socket */ //#warning testing without DSP -// mISDNport->b_socket[i] = socket(PF_ISDN, SOCK_DGRAM, ISDN_P_B_RAW); - mISDNport->b_socket[i] = socket(PF_ISDN, SOCK_DGRAM, ISDN_P_B_L2DSP); +// mISDNport->b_socket[i] = socket(PF_ISDN, SOCK_DGRAM, (mISDNport->b_mode[i]==B_MODE_HDLC)?ISDN_P_B_HDLC:ISDN_P_B_RAW); + mISDNport->b_socket[i] = socket(PF_ISDN, SOCK_DGRAM, (mISDNport->b_mode[i]==B_MODE_HDLC)?ISDN_P_B_L2DSPHDLC:ISDN_P_B_L2DSP); if (mISDNport->b_socket[i] < 0) { PERROR("Error: Failed to open bchannel-socket for index %d with mISDN-DSP layer. Did you load mISDNdsp.ko?\n", i); @@ -395,7 +401,7 @@ static int _bchannel_create(struct mISDNport *mISDNport, int i) /* bind socket to bchannel */ addr.family = AF_ISDN; - addr.dev = mISDNport->portnum-1; + addr.dev = mISDNport->portnum; addr.channel = i+1+(i>=15); ret = bind(mISDNport->b_socket[i], (struct sockaddr *)&addr, sizeof(addr)); if (ret < 0) @@ -433,7 +439,7 @@ static void _bchannel_activate(struct mISDNport *mISDNport, int i, int activate) PERROR("Failed to send to socket %d\n", mISDNport->b_socket[i]); /* trace */ - chan_trace_header(mISDNport, mISDNport->b_port[i], activate?(char*)"BCHANNEL activate":(char*)"BCHANNEL deactivate", DIRECTION_OUT); + chan_trace_header(mISDNport, mISDNport->b_port[i], activate ? "BCHANNEL activate" : "BCHANNEL deactivate", DIRECTION_OUT); add_trace("channel", NULL, "%d", i+1+(i>=15)); if (mISDNport->b_timer[i]) add_trace("event", NULL, "timeout recovery"); @@ -448,12 +454,13 @@ static void _bchannel_activate(struct mISDNport *mISDNport, int i, int activate) static void _bchannel_configure(struct mISDNport *mISDNport, int i) { struct PmISDN *port; - int handle; + int handle, mode; if (mISDNport->b_socket[i] < 0) return; handle = mISDNport->b_socket[i]; port = mISDNport->b_port[i]; + mode = mISDNport->b_mode[i]; if (!port) { PERROR("bchannel index i=%d not associated with a port object\n", i); @@ -463,27 +470,27 @@ static void _bchannel_configure(struct mISDNport *mISDNport, int i) /* set dsp features */ if (port->p_m_txdata) ph_control(mISDNport, port, handle, (port->p_m_txdata)?DSP_TXDATA_ON:DSP_TXDATA_OFF, 0, "DSP-TXDATA", port->p_m_txdata); - if (port->p_m_delay) + if (port->p_m_delay && mode == B_MODE_TRANSPARENT) ph_control(mISDNport, port, handle, DSP_DELAY, port->p_m_delay, "DSP-DELAY", port->p_m_delay); - if (port->p_m_tx_gain) + if (port->p_m_tx_gain && mode == B_MODE_TRANSPARENT) ph_control(mISDNport, port, handle, DSP_VOL_CHANGE_TX, port->p_m_tx_gain, "DSP-TX_GAIN", port->p_m_tx_gain); - if (port->p_m_rx_gain) + if (port->p_m_rx_gain && mode == B_MODE_TRANSPARENT) ph_control(mISDNport, port, handle, DSP_VOL_CHANGE_RX, port->p_m_rx_gain, "DSP-RX_GAIN", port->p_m_rx_gain); - if (port->p_m_pipeline[0]) + if (port->p_m_pipeline[0] && mode == B_MODE_TRANSPARENT) ph_control_block(mISDNport, port, handle, DSP_PIPELINE_CFG, port->p_m_pipeline, strlen(port->p_m_pipeline)+1, "DSP-PIPELINE", 0); if (port->p_m_conf) ph_control(mISDNport, port, handle, DSP_CONF_JOIN, port->p_m_conf, "DSP-CONF", port->p_m_conf); if (port->p_m_echo) ph_control(mISDNport, port, handle, DSP_ECHO_ON, 0, "DSP-ECHO", 1); - if (port->p_m_tone) + if (port->p_m_tone && mode == B_MODE_TRANSPARENT) ph_control(mISDNport, port, handle, DSP_TONE_PATT_ON, port->p_m_tone, "DSP-TONE", port->p_m_tone); if (port->p_m_rxoff) ph_control(mISDNport, port, handle, DSP_RECEIVE_OFF, 0, "DSP-RXOFF", 1); -// if (port->p_m_txmix) +// if (port->p_m_txmix && mode == B_MODE_TRANSPARENT) // ph_control(mISDNport, port, handle, DSP_MIX_ON, 0, "DSP-MIX", 1); - if (port->p_m_dtmf) + if (port->p_m_dtmf && mode == B_MODE_TRANSPARENT) ph_control(mISDNport, port, handle, DTMF_TONE_START, 0, "DSP-DTMF", 1); - if (port->p_m_crypt) + if (port->p_m_crypt && mode == B_MODE_TRANSPARENT) ph_control_block(mISDNport, port, handle, DSP_BF_ENABLE_KEY, port->p_m_crypt_key, port->p_m_crypt_key_len, "DSP-CRYPT", port->p_m_crypt_key_len); } @@ -772,6 +779,7 @@ void bchannel_event(struct mISDNport *mISDNport, int i, int event) /* bchannel is active and used by Port class, so we configure bchannel */ _bchannel_configure(mISDNport, i); state = B_STATE_ACTIVE; + b_port->p_m_load = 0; } else { /* bchannel is active, but exported OR not used anymore (or has wrong stack config), so we deactivate */ @@ -1030,11 +1038,12 @@ int PmISDN::seize_bchannel(int channel, int exclusive) seize: PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) seizing bchannel %d (index %d)\n", p_name, channel, i); - /* link Port */ + /* link Port, set parameters */ p_m_mISDNport->b_port[i] = this; p_m_b_index = i; p_m_b_channel = channel; p_m_b_exclusive = exclusive; + p_m_mISDNport->b_mode[i] = p_m_b_mode; /* reserve channel */ if (!p_m_b_reserve) @@ -1068,6 +1077,7 @@ void PmISDN::drop_bchannel(void) if (p_m_mISDNport->b_state[p_m_b_index] != B_STATE_IDLE) bchannel_event(p_m_mISDNport, p_m_b_index, B_EVENT_DROP); p_m_mISDNport->b_port[p_m_b_index] = NULL; + p_m_mISDNport->b_mode[p_m_b_index] = 0; p_m_b_index = -1; p_m_b_channel = 0; p_m_b_exclusive = 0; @@ -1259,7 +1269,8 @@ int PmISDN::handler(void) p_m_last_tv_msec = now_tv.tv_usec/1000; } /* process only if we have a minimum of samples, to make packets not too small */ - if (elapsed >= ISDN_TRANSMIT) + if (elapsed >= ISDN_TRANSMIT + && p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE) { /* set clock of last process! */ p_m_last_tv_sec = now_tv.tv_sec; @@ -1315,15 +1326,15 @@ int PmISDN::handler(void) } /* send data */ - if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE && ISDN_LOAD-p_m_load-tosend > 0) + if (ISDN_LOAD - p_m_load - tosend > 0) { frm->prim = PH_DATA_REQ; frm->id = 0; ret = sendto(p_m_mISDNport->b_socket[p_m_b_index], buf, MISDN_HEADER_LEN+ISDN_LOAD-p_m_load-tosend, 0, NULL, 0); if (ret <= 0) PERROR("Failed to send to socket %d (samples = %d)\n", p_m_mISDNport->b_socket[p_m_b_index], ISDN_LOAD-p_m_load-tosend); + p_m_load += ISDN_LOAD - p_m_load - tosend; } - p_m_load += ISDN_LOAD - p_m_load - tosend; } } @@ -1521,7 +1532,7 @@ void PmISDN::set_echotest(int echo) /* * set tone */ -void PmISDN::set_tone(char *dir, char *tone) +void PmISDN::set_tone(const char *dir, const char *tone) { int id; @@ -1540,7 +1551,7 @@ void PmISDN::set_tone(char *dir, char *tone) nodsp: if (p_m_tone) if (p_m_b_index > -1) - if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE) + if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE && p_m_mISDNport->b_mode[p_m_b_index] == B_MODE_TRANSPARENT) { PDEBUG(DEBUG_ISDN, "we reset tone from id=%d to OFF.\n", p_m_tone); ph_control(p_m_mISDNport, this, p_m_mISDNport->b_socket[p_m_b_index], DSP_TONE_PATT_OFF, 0, "DSP-TONE", 0); @@ -1624,7 +1635,7 @@ void PmISDN::set_tone(char *dir, char *tone) p_m_tone = id; PDEBUG(DEBUG_ISDN, "we set tone to id=%d.\n", p_m_tone); if (p_m_b_index > -1) - if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE) + if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE && p_m_mISDNport->b_mode[p_m_b_index] == B_MODE_TRANSPARENT) ph_control(p_m_mISDNport, this, p_m_mISDNport->b_socket[p_m_b_index], p_m_tone?DSP_TONE_PATT_ON:DSP_TONE_PATT_OFF, p_m_tone, "DSP-TONE", p_m_tone); } /* turn user-space tones off in cases of no tone OR dsp tone */ @@ -1644,7 +1655,7 @@ void PmISDN::message_mISDNsignal(unsigned int epoint_id, int message_id, union p p_m_tx_gain = param->mISDNsignal.tx_gain; PDEBUG(DEBUG_BCHANNEL, "we change tx-volume to shift=%d.\n", p_m_tx_gain); if (p_m_b_index > -1) - if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE) + if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE && p_m_mISDNport->b_mode[p_m_b_index] == B_MODE_TRANSPARENT) ph_control(p_m_mISDNport, this, p_m_mISDNport->b_socket[p_m_b_index], DSP_VOL_CHANGE_TX, p_m_tx_gain, "DSP-TX_GAIN", p_m_tx_gain); } else PDEBUG(DEBUG_BCHANNEL, "we already have tx-volume shift=%d.\n", p_m_rx_gain); @@ -1653,7 +1664,7 @@ void PmISDN::message_mISDNsignal(unsigned int epoint_id, int message_id, union p p_m_rx_gain = param->mISDNsignal.rx_gain; PDEBUG(DEBUG_BCHANNEL, "we change rx-volume to shift=%d.\n", p_m_rx_gain); if (p_m_b_index > -1) - if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE) + if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE && p_m_mISDNport->b_mode[p_m_b_index] == B_MODE_TRANSPARENT) ph_control(p_m_mISDNport, this, p_m_mISDNport->b_socket[p_m_b_index], DSP_VOL_CHANGE_RX, p_m_rx_gain, "DSP-RX_GAIN", p_m_rx_gain); } else PDEBUG(DEBUG_BCHANNEL, "we already have rx-volume shift=%d.\n", p_m_rx_gain); @@ -1691,7 +1702,7 @@ void PmISDN::message_mISDNsignal(unsigned int epoint_id, int message_id, union p p_m_delay = param->mISDNsignal.delay; PDEBUG(DEBUG_BCHANNEL, "we change delay mode to delay=%d.\n", p_m_delay); if (p_m_b_index > -1) - if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE) + if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE && p_m_mISDNport->b_mode[p_m_b_index] == B_MODE_TRANSPARENT) ph_control(p_m_mISDNport, this, p_m_mISDNport->b_socket[p_m_b_index], p_m_delay?DSP_DELAY:DSP_JITTER, p_m_delay, "DSP-DELAY", p_m_delay); } else PDEBUG(DEBUG_BCHANNEL, "we already have delay=%d.\n", p_m_delay); @@ -1724,7 +1735,7 @@ void PmISDN::message_crypt(unsigned int epoint_id, int message_id, union paramet crypt_off: PDEBUG(DEBUG_BCHANNEL, "we set encryption to crypt=%d. (0 means OFF)\n", p_m_crypt); if (p_m_b_index > -1) - if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE) + if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE && p_m_mISDNport->b_mode[p_m_b_index] == B_MODE_TRANSPARENT) ph_control_block(p_m_mISDNport, this, p_m_mISDNport->b_socket[p_m_b_index], p_m_crypt?DSP_BF_ENABLE_KEY:DSP_BF_DISABLE, p_m_crypt_key, p_m_crypt_key_len, "DSP-CRYPT", p_m_crypt_key_len); break; @@ -1753,7 +1764,7 @@ void PmISDN::message_crypt(unsigned int epoint_id, int message_id, union paramet p_m_crypt_msg_loops = 6; /* enable */ #if 0 /* disable txmix, or we get corrupt data due to audio process */ - if (p_m_txmix && p_m_b_index>=0) + if (p_m_txmix && p_m_b_index>=0 && p_m_mISDNport->b_mode[p_m_b_index] == B_MODE_TRANSPARENT) { PDEBUG(DEBUG_BCHANNEL, "for sending CR_MESSAGE_REQ, we reset txmix from txmix=%d.\n", p_m_txmix); ph_control(p_m_mISDNport, this, p_mISDNport->b_socket[p_m_b_index], DSP_MIX_OFF, 0, "DSP-TXMIX", 0); @@ -1838,7 +1849,7 @@ int mISDN_handler(void) isdnport->p_m_rxoff = 0; PDEBUG(DEBUG_BCHANNEL, "%s: receive data is required, so we turn them on\n", __FUNCTION__); if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE) - ph_control(mISDNport, isdnport, mISDNport->b_socket[isdnport->p_m_b_index], DSP_RECEIVE_ON, 0, "DSP-RXOFF", 0); + ph_control(mISDNport, isdnport, mISDNport->b_socket[i], DSP_RECEIVE_ON, 0, "DSP-RXOFF", 0); return(1); } } else @@ -1850,7 +1861,7 @@ int mISDN_handler(void) isdnport->p_m_rxoff = 1; PDEBUG(DEBUG_BCHANNEL, "%s: receive data is not required, so we turn them off\n", __FUNCTION__); if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE) - ph_control(mISDNport, isdnport, mISDNport->b_socket[isdnport->p_m_b_index], DSP_RECEIVE_OFF, 0, "DSP-RXOFF", 1); + ph_control(mISDNport, isdnport, mISDNport->b_socket[i], DSP_RECEIVE_OFF, 0, "DSP-RXOFF", 1); return(1); } } @@ -1864,7 +1875,7 @@ int mISDN_handler(void) isdnport->p_m_txdata = 1; PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is required, so we turn them on\n", __FUNCTION__); if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE) - ph_control(mISDNport, isdnport, mISDNport->b_socket[isdnport->p_m_b_index], DSP_TXDATA_ON, 0, "DSP-TXDATA", 1); + ph_control(mISDNport, isdnport, mISDNport->b_socket[i], DSP_TXDATA_ON, 0, "DSP-TXDATA", 1); return(1); } } else @@ -1876,7 +1887,7 @@ int mISDN_handler(void) isdnport->p_m_txdata = 0; PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is not required, so we turn them off\n", __FUNCTION__); if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE) - ph_control(mISDNport, isdnport, mISDNport->b_socket[isdnport->p_m_b_index], DSP_TXDATA_OFF, 0, "DSP-TXDATA", 0); + ph_control(mISDNport, isdnport, mISDNport->b_socket[i], DSP_TXDATA_OFF, 0, "DSP-TXDATA", 0); return(1); } } @@ -2001,16 +2012,20 @@ int mISDN_handler(void) break; case MT_L2RELEASE: - l1l2l3_trace_header(mISDNport, NULL, L2_RELEASE_IND, DIRECTION_IN); - add_trace("tei", NULL, "%d", l3m->pid); - end_trace(); + if (!mISDNport->l2establish) + { + l1l2l3_trace_header(mISDNport, NULL, L2_RELEASE_IND, DIRECTION_IN); + add_trace("tei", NULL, "%d", l3m->pid); + end_trace(); + } if ((!mISDNport->ntmode || mISDNport->ptp) && l3m->pid < 127) { mISDNport->l2link = 0; - if (mISDNport->l2hold) + if (!mISDNport->l2establish && mISDNport->l2hold) { + PDEBUG(DEBUG_ISDN, "set timer and establish.\n"); time(&mISDNport->l2establish); - PDEBUG(DEBUG_ISDN, "because we are ptp, we set a l2establish timer.\n"); + mISDNport->ml3->to_layer3(mISDNport->ml3, MT_L2ESTABLISH, 0, NULL); } } break; @@ -2041,9 +2056,6 @@ int mISDN_handler(void) PDEBUG(DEBUG_ISDN, "the L2 establish timer expired, we try to establish the link portnum=%d.\n", mISDNport->portnum); mISDNport->ml3->to_layer3(mISDNport->ml3, MT_L2ESTABLISH, 0, NULL); - l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_REQ, DIRECTION_OUT); - add_trace("tei", NULL, "%d", 0); - end_trace(); time(&mISDNport->l2establish); return(1); } @@ -2105,7 +2117,7 @@ int do_layer3(struct mlayer3 *ml3, unsigned int cmd, unsigned int pid, struct l3 /* * global function to add a new card (port) */ -struct mISDNport *mISDNport_open(int port, int ptp, int force_nt, int l2hold, struct interface *interface) +struct mISDNport *mISDNport_open(int port, char *portname, int ptp, int force_nt, int l2hold, struct interface *interface) { int ret; struct mISDNport *mISDNport, **mISDNportp; @@ -2116,6 +2128,7 @@ struct mISDNport *mISDNport_open(int port, int ptp, int force_nt, int l2hold, st struct mISDN_devinfo devinfo; unsigned int protocol, prop; + /* check port counts */ ret = ioctl(mISDNsocket, IMGETCOUNT, &cnt); if (ret < 0) { @@ -2128,21 +2141,45 @@ struct mISDNport *mISDNport_open(int port, int ptp, int force_nt, int l2hold, st PERROR_RUNTIME("Found no card. Please be sure to load card drivers.\n"); return(NULL); } - if (port>cnt || port<1) + if (port < 0) + { + /* resolve name */ + port = 0; + while (port < cnt) + { + devinfo.id = port; + ret = ioctl(mISDNsocket, IMGETDEVINFO, &devinfo); + if (ret < 0) + { + PERROR_RUNTIME("Cannot get device information for port %d. (ioctl IMGETDEVINFO failed ret=%d)\n", port, ret); + return(NULL); + } + if (!strcasecmp(devinfo.name, portname)) + break; + port++; + } + if (port == cnt) + { + PERROR_RUNTIME("Port name '%s' no found, use 'isdninfo' tool to list all existing ports.\n", portname); + return(NULL); + } + // note: 'port' has still the port number + } + if (port>cnt || port<0) { - PERROR_RUNTIME("Port (%d) given at 'ports' (options.conf) is out of existing port range (%d-%d)\n", port, 1, cnt); + PERROR_RUNTIME("Port (%d) given at 'ports' (options.conf) is out of existing port range (%d-%d)\n", port, 0, cnt); return(NULL); } + /* get port attributes */ pri = bri = pots = nt = te = 0; - devinfo.id = port - 1; + devinfo.id = port; ret = ioctl(mISDNsocket, IMGETDEVINFO, &devinfo); if (ret < 0) { - PERROR_RUNTIME("Cannot get device information for port %d. (ioctl IMGETDEVINFO failed ret=%d)\n", i, ret); + PERROR_RUNTIME("Cannot get device information for port %d. (ioctl IMGETDEVINFO failed ret=%d)\n", port, ret); return(NULL); } - /* output the port info */ if (devinfo.Dprotocols & (1 << ISDN_P_TE_S0)) { bri = 1; @@ -2209,11 +2246,30 @@ struct mISDNport *mISDNport_open(int port, int ptp, int force_nt, int l2hold, st if (te && nt) nt = 0; + /* check for double use of port */ + if (nt) + { + mISDNport = mISDNport_first; + while(mISDNport) + { + if (mISDNport->portnum == port) + break; + mISDNport = mISDNport->next; + } + if (mISDNport) + { + PERROR_RUNTIME("Port %d already in use by LCR. You can't use a NT port multiple times.\n", port); + return(NULL); + } + } + + /* add mISDNport structure */ mISDNportp = &mISDNport_first; while(*mISDNportp) mISDNportp = &((*mISDNportp)->next); mISDNport = (struct mISDNport *)MALLOC(sizeof(struct mISDNport)); + mISDNport->l1link = -1; pmemuse++; *mISDNportp = mISDNport; @@ -2250,7 +2306,7 @@ struct mISDNport *mISDNport_open(int port, int ptp, int force_nt, int l2hold, st prop |= (1 << MISDN_FLG_L2_HOLD); /* queue must be initializes, because l3-thread may send messages during open_layer3() */ mqueue_init(&mISDNport->upqueue); - mISDNport->ml3 = open_layer3(port-1, protocol, prop , do_layer3, mISDNport); + mISDNport->ml3 = open_layer3(port, protocol, prop , do_layer3, mISDNport); if (!mISDNport->ml3) { mqueue_purge(&mISDNport->upqueue); @@ -2422,138 +2478,6 @@ void mISDNport_close(struct mISDNport *mISDNport) /* - * global function to show all available isdn ports - */ -void mISDN_port_info(void) -{ - int ret; - int i, ii; - int useable, nt, te, pri, bri, pots; - struct mISDN_devinfo devinfo; - int sock; - - /* open mISDN */ - sock = socket(PF_ISDN, SOCK_RAW, ISDN_P_BASE); - if (sock < 0) - { - fprintf(stderr, "Cannot open mISDN due to %s. (Does your Kernel support socket based mISDN?)\n", strerror(errno)); - exit(EXIT_FAILURE); - } - - /* get number of stacks */ - i = 1; - ret = ioctl(sock, IMGETCOUNT, &ii); - if (ret < 0) - { - fprintf(stderr, "Cannot get number of mISDN devices. (ioctl IMGETCOUNT failed ret=%d)\n", ret); - goto done; - } - printf("\n"); - if (ii <= 0) - { - printf("Found no card. Please be sure to load card drivers.\n"); - goto done; - } - - /* loop the number of cards and get their info */ - while(i <= ii) - { - nt = te = bri = pri = pots = 0; - useable = 0; - - devinfo.id = i - 1; - ret = ioctl(sock, IMGETDEVINFO, &devinfo); - if (ret < 0) - { - fprintf(stderr, "Cannot get device information for port %d. (ioctl IMGETDEVINFO failed ret=%d)\n", i, ret); - break; - } - - /* output the port info */ - printf("Port %2d name='%s': ", i, devinfo.name); - if (devinfo.Dprotocols & (1 << ISDN_P_TE_S0)) - { - bri = 1; - te = 1; - } - if (devinfo.Dprotocols & (1 << ISDN_P_NT_S0)) - { - bri = 1; - nt = 1; - } - if (devinfo.Dprotocols & (1 << ISDN_P_TE_E1)) - { - pri = 1; - te = 1; - } - if (devinfo.Dprotocols & (1 << ISDN_P_NT_E1)) - { - pri = 1; - nt = 1; - } -#ifdef ISDN_P_FXS - if (devinfo.Dprotocols & (1 << ISDN_P_FXS)) - { - pots = 1; - te = 1; - } -#endif -#ifdef ISDN_P_FXO - if (devinfo.Dprotocols & (1 << ISDN_P_FXO)) - { - pots = 1; - nt = 1; - } -#endif - if ((te || nt) && (bri || pri || pots)) - useable = 1; - - if (te && nt && bri) - printf("TE/NT-mode BRI S/T (for phone lines & phones)"); - if (te && !nt && bri) - printf("TE-mode BRI S/T (for phone lines)"); - if (nt && !te && bri) - printf("NT-mode BRI S/T (for phones)"); - if (te && nt && pri) - printf("TE/NT-mode PRI E1 (for phone lines & E1 devices)"); - if (te && !nt && pri) - printf("TE-mode PRI E1 (for phone lines)"); - if (nt && !te && pri) - printf("NT-mode PRI E1 (for E1 devices)"); - if (te && nt && pots) - printf("FXS/FXO POTS (for analog lines & phones)"); - if (te && !nt && pots) - printf("FXS POTS (for analog lines)"); - if (nt && !te && pots) - printf("FXO POTS (for analog phones)"); - if (pots) - { - useable = 0; - printf("\n -> Analog interfaces are not supported."); - } else - if (!useable) - { - printf("unsupported interface protocol bits 0x%016x", devinfo.Dprotocols); - } - printf("\n"); - - printf(" - %d B-channels\n", devinfo.nrbchan); - - if (!useable) - printf(" * Port NOT useable for LCR\n"); - - printf("--------\n"); - - i++; - } - printf("\n"); - -done: - close(sock); -} - - -/* * enque data from upper buffer */ void PmISDN::txfromup(unsigned char *data, int length)