p_m_hold = 0;
p_m_txvol = p_m_rxvol = 0;
p_m_conf = 0;
+ p_m_txdata = 0;
#warning set delay by routing parameter or interface config
p_m_delay = 0;
p_m_echo = 0;
p_m_tone = 0;
p_m_rxoff = 0;
- p_m_txmix = 0;
- p_m_txmix_on = 0;
- p_m_nodata = 1; /* may be 1, because call always notifies us */
+ p_m_calldata = 0;
p_m_dtmf = !options.nodtmf;
+ sollen wir daraus eine interface-option machen?:
p_m_timeout = 0;
p_m_timer = 0;
#warning denke auch an die andere seite. also das setup sollte dies weitertragen
ctrl->prim = PH_CONTROL | REQUEST;
ctrl->addr = b_addr | FLG_MSG_DOWN;
ctrl->dinfo = 0;
- ctrl->len = sizeof(unsigned long)*2;
+ ctrl->len = sizeof(int)*2;
*d++ = c1;
*d++ = c2;
mISDN_write(mISDNdevice, ctrl, mISDN_HEADER_LEN+ctrl->len, TIMEOUT_1SEC);
ctrl->prim = PH_CONTROL | REQUEST;
ctrl->addr = b_addr | FLG_MSG_DOWN;
ctrl->dinfo = 0;
- ctrl->len = sizeof(unsigned long)*2;
+ ctrl->len = sizeof(int)+c2_len;
*d++ = c1;
memcpy(d, c2, c2_len);
mISDN_write(mISDNdevice, ctrl, mISDN_HEADER_LEN+ctrl->len, TIMEOUT_1SEC);
/* if we are active, we configure our channel */
if (mISDNport->b_state[i] == B_STATE_ACTIVE)
{
- unsigned char buffer[mISDN_HEADER_LEN+ISDN_PRELOAD];
+ unsigned char buffer[mISDN_HEADER_LEN+(ISDN_PRELOAD<<3)];
iframe_t *pre = (iframe_t *)buffer; /* preload data */
unsigned char *p = (unsigned char *)&pre->data.p;
}
/* configure dsp features */
+ if (mISDNport->b_port[i]->p_m_txdata)
+ {
+ PDEBUG(DEBUG_BCHANNEL, "during activation, we set txdata to txdata=%d.\n", mISDNport->b_port[i]->p_m_txdata);
+ ph_control(mISDNport->b_addr[i], (mISDNport->b_port[i]->p_m_txdata)?CMX_TXDATA_ON:CMX_TXDATA_OFF);
+ }
if (mISDNport->b_port[i]->p_m_delay)
{
PDEBUG(DEBUG_BCHANNEL, "during activation, we set delay to delay=%d.\n", mISDNport->b_port[i]->p_m_delay);
PDEBUG(DEBUG_BCHANNEL, "during activation, we set rxoff to rxoff=%d.\n", mISDNport->b_port[i]->p_m_rxoff);
ph_control(mISDNport->b_addr[i], CMX_RECEIVE_OFF, 0);
}
+#if 0
if (mISDNport->b_port[i]->p_m_txmix)
{
PDEBUG(DEBUG_BCHANNEL, "during activation, we set txmix to txmix=%d.\n", mISDNport->b_port[i]->p_m_txmix);
ph_control(mISDNport->b_addr[i], CMX_MIX_ON, 0);
}
+#endif
if (mISDNport->b_port[i]->p_m_dtmf)
{
PDEBUG(DEBUG_BCHANNEL, "during activation, we set dtmf to dtmf=%d.\n", mISDNport->b_port[i]->p_m_dtmf);
PDEBUG(DEBUG_BCHANNEL, "during activation, we set crypt to crypt=%d.\n", mISDNport->b_port[i]->p_m_crypt);
ph_control_block(mISDNport->b_addr[i], BF_ENABLE_KEY, mISDNport->b_port[i]->p_m_crypt_key, mISDNport->b_port[i]->p_m_crypt_key_len);
}
-
- /* preload tx-buffer */
- pre->len = mISDNport->b_port[i]->read_audio(p, ISDN_PRELOAD, 1);
- if (pre->len > 0)
- {
- PDEBUG(DEBUG_BCHANNEL, "port is activated, we fill our buffer (ISDN_PRELOAD = %d).\n", pre->len);
- /* flip bits */
-#if 0
- q = p + pre->len;
- while(p != q)
- *p++ = flip[*p];
-#endif
- pre->prim = DL_DATA | REQUEST;
- pre->addr = mISDNport->b_addr[i] | FLG_MSG_DOWN;
- pre->dinfo = 0;
- mISDN_write(mISDNdevice, pre, mISDN_HEADER_LEN+pre->len, TIMEOUT_1SEC);
- }
+ todo: wer startet/stoppt eigentlich den audio-transmit
}
}
/* reset dsp features */
if (mISDNport->b_port[i])
{
+ if (mISDNport->b_port[i]->p_m_txdata)
+ {
+ PDEBUG(DEBUG_BCHANNEL, "during deactivation, we reset txdata from txdata=%d.\n", mISDNport->b_port[i]->p_m_txdata);
+ ph_control(mISDNport->b_addr[i], CMX_TXDATA_OFF, 0);
+ }
if (mISDNport->b_port[i]->p_m_delay)
{
PDEBUG(DEBUG_BCHANNEL, "during deactivation, we reset delay from delay=%d.\n", mISDNport->b_port[i]->p_m_delay);
PDEBUG(DEBUG_BCHANNEL, "during deactivation, we reset rxoff from rxoff=%d.\n", mISDNport->b_port[i]->p_m_rxoff);
ph_control(mISDNport->b_addr[i], CMX_RECEIVE_ON, 0);
}
+#if 0
if (mISDNport->b_port[i]->p_m_txmix)
{
PDEBUG(DEBUG_BCHANNEL, "during deactivation, we reset txmix from txmix=%d.\n", mISDNport->b_port[i]->p_m_txmix);
ph_control(mISDNport->b_addr[i], CMX_MIX_OFF, 0);
}
+#endif
if (mISDNport->b_port[i]->p_m_dtmf)
{
PDEBUG(DEBUG_BCHANNEL, "during deactivation, we reset dtmf from dtmf=%d.\n", mISDNport->b_port[i]->p_m_dtmf);
p_m_b_stid = 0;
}
+
+/*
+ * data is to be transmitted to the remote
+ */
+wech void Port::transmit(unsigned char *buffer, int length, int tonelength)
+{
+ /* send tone data to isdn device only if we have data, otherwhise we send nothing */
+ if (tonelength>0 && (p_tone_fh>=0 || p_tone_fetched || p_m_crypt_msg_loops))
+ {
+ unsigned char buf[mISDN_HEADER_LEN+tonelength];
+ iframe_t *frm = (iframe_t *)buf;
+
+ if (p_m_crypt_msg_loops)
+ {
+ /* send pending message */
+ int tosend;
+
+ tosend = p_m_crypt_msg_len - p_m_crypt_msg_current;
+ if (tosend > newlen)
+ tosend = newlen;
+ memcpy(p, p_m_crypt_msg+p_m_crypt_msg_current, tosend);
+ p_m_crypt_msg_current += tosend;
+ if (p_m_crypt_msg_current == p_m_crypt_msg_len)
+ {
+ p_m_crypt_msg_current = 0;
+ p_m_crypt_msg_loops--;
+ }
+ }
+ frm->prim = DL_DATA | REQUEST;
+ frm->addr = p_m_b_addr | FLG_MSG_DOWN;
+ frm->dinfo = 0;
+ frm->len = tonelength;
+ memcpy(&frm->data.p, buffer, tonelength);
+ mISDN_write(mISDNdevice, frm, mISDN_HEADER_LEN+frm->len, TIMEOUT_1SEC);
+
+ if (p_debug_nothingtosend)
+ {
+ p_debug_nothingtosend = 0;
+ PDEBUG((DEBUG_PORT | DEBUG_BCHANNEL), "PmISDN(%s) start sending, because we have tones and/or remote audio.\n", p_name);
+ }
+ } else
+ {
+ if (!p_debug_nothingtosend)
+ {
+ p_debug_nothingtosend = 1;
+ PDEBUG((DEBUG_PORT | DEBUG_BCHANNEL), "PmISDN(%s) stop sending, because we have only silence.\n", p_name);
+ }
+ }
+}
+
+
/*
* handler
*/
int PmISDN::handler(void)
{
struct message *message;
+ int elapsed, length;
+
+ if ((ret = Port::handler()))
+ return(ret);
+
+ inbuffer = (p_fromup_buffer_writep - p_fromup_buffer_readp) & FROMUP_BUFFER_MASK
+ /* send tone data to isdn device only if we have data */
+ if (p_tone_fh>=0 || p_tone_fetched || p_m_crypt_msg_loops || inbuffer)
+ {
+ /* calculate how much to transmit */
+ if (!p_last_tv.sec)
+ {
+ elapsed = ISDN_PRELOAD << 3; /* preload for the first time */
+ } else
+ {
+ elapsed = 1000 * (now_tv.sec - p_last_tv_sec)
+ + (now_tv.usec/1000) - p_last_tv_msec;
+ /* gap was greater preload, so only fill up to preload level */
+ if (elapsed > (ISDN_PRELOAD<<3))
+ {
+ elapsed = ISDN_PRELOAD << 3
+ }
+ }
+ if (elapsed >= ISDN_TRANSMIT)
+ {
+ unsigned char buf[mISDN_HEADER_LEN+(ISDN_PRELOAD<<3)], *p = buf;
+ iframe_t *frm = (iframe_t *)buf;
+
+ p_last_tv_sec = now_tv.sec;
+ p_last_tv_msec = now_tv.usec/1000;
+
+ /* read tones */
+ length = read_audio(buffer, elapsed);
+
+ /*
+ * get data from up
+ * the fromup_buffer data is written to the beginning of the buffer
+ * the part that is filles with tones (length) is skipped, so tones have priority
+ * the length value is increased by the number of data copied from fromup_buffer
+ */
+ if (inbuffer)
+ {
+ /* inbuffer might be less than we skip due to audio */
+ if (inbuffer <= length)
+ {
+ /* clear buffer */
+ p_fromup_buffer_readp = p_fromup_buffer_writep;
+ inbuffer = 0;
+ } else
+ {
+ /* skip what we already have with tones */
+ p_fromup_buffer_readp = (p_fromup_buffer_readp + length) & FROMUP_BUFFER_MASK;
+ inbuffer -= length;
+ }
+ /* if we have more in buffer, than we send this time */
+ if (inbuffer > (elapsed-length))
+ inbuffer = elapsed - length;
+ /* set length to what we actually have */
+ length = length + inbuffer;
+ /* now fill up with fromup_buffer */
+ while (inbuffer)
+ {
+ *p++ = p_fromup_buffer[p_fromup_buffer_readp];
+ p_fromup_buffer_readp = (p_fromup_buffer_readp + 1) & FROMUP_BUFFER_MASK;
+ inbuffer--;
+ }
+ }
+
+ /* overwrite buffer with crypto stuff */
+ if (p_m_crypt_msg_loops)
+ {
+ /* send pending message */
+ int tosend;
+
+ /* we need full length */
+ length = elapsed;
+ check!!
+ tosend = p_m_crypt_msg_len - p_m_crypt_msg_current;
+ if (tosend > length)
+ tosend = length;
+ memcpy(buffer, p_m_crypt_msg+p_m_crypt_msg_current, tosend);
+ p_m_crypt_msg_current += tosend;
+ if (p_m_crypt_msg_current == p_m_crypt_msg_len)
+ {
+ p_m_crypt_msg_current = 0;
+ p_m_crypt_msg_loops--;
+ }
+ }
+ frm->prim = DL_DATA | REQUEST;
+ frm->addr = p_m_b_addr | FLG_MSG_DOWN;
+ frm->dinfo = 0;
+ frm->len = length;
+ memcpy(&frm->data.p, buffer, length);
+ mISDN_write(mISDNdevice, frm, mISDN_HEADER_LEN+frm->len, TIMEOUT_1SEC);
+
+ if (p_debug_nothingtosend)
+ {
+ p_debug_nothingtosend = 0;
+ PDEBUG((DEBUG_PORT | DEBUG_BCHANNEL), "PmISDN(%s) start sending, because we have tones and/or remote audio.\n", p_name);
+ }
+ return(1);
+ }
+ } else
+ {
+ if (!cwp_debug_nothingtosend)
+ {
+ p_debug_nothingtosend = 1;
+ PDEBUG((DEBUG_PORT | DEBUG_BCHANNEL), "PmISDN(%s) stop sending, because we have only silence.\n", p_name);
+ }
+ }
// NOTE: deletion is done by the child class
if (frm->prim == (PH_CONTROL | INDICATION))
{
+ if (frm->len < 4)
+ {
+ PERROR("SHORT READ OF PH_CONTROL INDICATION\n");
+ return;
+ }
cont = *((unsigned long *)&frm->data.p);
// PDEBUG(DEBUG_PORT, "PmISDN(%s) received a PH_CONTROL INDICATION 0x%x\n", p_name, cont);
if ((cont&(~DTMF_TONE_MASK)) == DTMF_TONE_VAL)
{
message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DTMF);
message->param.dtmf = cont & DTMF_TONE_MASK;
- PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL DTMF digit '%c'\n", p_name, message->param.dtmf);
+ PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION DTMF digit '%c'\n", p_name, message->param.dtmf);
message_put(message);
+ return;
}
switch(cont)
{
case BF_REJECT:
message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
message->param.crypt.type = CC_ERROR_IND;
- PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL reject of blowfish.\n", p_name);
+ PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION reject of blowfish.\n", p_name);
message_put(message);
break;
case BF_ACCEPT:
message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
message->param.crypt.type = CC_ACTBF_CONF;
- PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL accept of blowfish.\n", p_name);
+ PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION accept of blowfish.\n", p_name);
message_put(message);
break;
+
+ case CMX_TX_DATA:
+ if (!p_m_txdatad)
+ {
+ /* if rx is off, it may happen that fifos send us pending informations, we just ignore them */
+ PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) ignoring rx data, because 'txdata' is turned off\n", p_name);
+ return;
+ }
+ if (p_record)
+ record(&(cont+1), frm->len - 4, 1); // from up
+ break;
+
+ default:
+ PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION unknown 0x%x.\n", p_name, cont);
}
return;
+ }
+ if (frm->prim != (PH_DATA | INDICATION))
+ {
+ PERROR("Bchannel received unknown primitve: 0x%x\n", frm->prim);
+ return;
}
- /* external incoming calls will not process any audio data unless
- * the call is connected OR inbandpattern feature is enabled.
+ /* calls will not process any audio data unless
+ * the call is connected OR tones feature is enabled.
*/
- if (p_type==PORT_TYPE_DSS1_TE_IN
- && p_state!=PORT_STATE_CONNECT
- && !options.inbandpattern)
+ if (p_state!=PORT_STATE_CONNECT
+ && !p_m_mISDNport->is_tones)
return;
#if 0
return;
}
+ /* record data */
+ if (p_record)
+ record((unsigned char *)&frm->data.p, frm->len, 0); // from down
+
/* randomize and listen to crypt message if enabled */
if (p_m_crypt_listen)
{
cryptman_listen_bch((unsigned char *)&frm->data.p, frm->len);
}
- /* prevent jitter */
- gettimeofday(&tv, &tz);
- jitter_now = tv.tv_sec;
- jitter_now = jitter_now*8000 + tv.tv_usec/125;
- if (p_m_jittercheck == 0)
- {
- p_m_jittercheck = jitter_now;
- p_m_jitterdropped = 0;
- } else
- p_m_jittercheck += frm->len;
- if (p_m_jittercheck < jitter_now)
- {
-// PERROR("jitter: ignoring slow data\n");
- p_m_jittercheck = jitter_now;
- } else
- if (p_m_jittercheck-ISDN_JITTERLIMIT > jitter_now)
- {
- p_m_jitterdropped += frm->len;
- p_m_jittercheck -= frm->len;
- /* must exit here */
- return;
- } else
- if (p_m_jitterdropped)
- {
- PERROR("jitter: dropping, caused by fast data: %lld\n", p_m_jitterdropped);
- p_m_jitterdropped = 0;
- }
-
p = (unsigned char *)&frm->data.p;
/* send data to epoint */
- if (ACTIVE_EPOINT(p_epointlist)) /* only if we have an epoint object */
+ if (p_m_calldata && ACTIVE_EPOINT(p_epointlist)) /* only if we have an epoint object */
{
//printf("we are port %s and sending to epoint %d\n", p_m_cardname, p_epoint->serial);
length_temp = frm->len;
length_temp -= sizeof(message->param.data.data);
}
}
- /* return the same number of tone data, as we recieved */
- newlen = read_audio(p, frm->len, 1);
- /* send tone data to isdn device only if we have data, otherwhise we send nothing */
- if (newlen>0 && (p_tone_fh>=0 || p_tone_fetched || !p_m_nodata || p_m_crypt_msg_loops))
- {
-//printf("jolly: sending.... %d %d %d %d %d\n", newlen, p_tone_fh, p_tone_fetched, p_m_nodata, p_m_crypt_msg_loops);
- if (p_m_txmix_on)
- {
- p_m_txmix_on -= newlen;
- if (p_m_txmix_on <= 0)
- {
- p_m_txmix_on = 0;
- p_m_txmix = !p_m_nodata;
- PDEBUG(DEBUG_BCHANNEL, "after sending message, we set txmix to txmix=%d.\n", p_m_txmix);
- if (p_m_txmix)
- ph_control(p_m_b_addr, CMX_MIX_ON, 0);
- }
- }
- if (p_m_crypt_msg_loops)
- {
- /* send pending message */
- int tosend;
-
- tosend = p_m_crypt_msg_len - p_m_crypt_msg_current;
- if (tosend > newlen)
- tosend = newlen;
- memcpy(p, p_m_crypt_msg+p_m_crypt_msg_current, tosend);
- p_m_crypt_msg_current += tosend;
- if (p_m_crypt_msg_current == p_m_crypt_msg_len)
- {
- p_m_crypt_msg_current = 0;
- p_m_crypt_msg_loops--;
-// we need to disable rxmix some time after sending the loops...
- if (!p_m_crypt_msg_loops && p_m_txmix)
- {
- p_m_txmix_on = 8000; /* one sec */
- }
- }
- }
- frm->prim = frm->prim & 0xfffffffc | REQUEST;
- frm->addr = p_m_b_addr | FLG_MSG_DOWN;
- frm->len = newlen;
- mISDN_write(mISDNdevice, frm, mISDN_HEADER_LEN+frm->len, TIMEOUT_1SEC);
-
- if (p_debug_nothingtosend)
- {
- p_debug_nothingtosend = 0;
- PDEBUG((DEBUG_PORT | DEBUG_BCHANNEL), "PmISDN(%s) start sending, because we have tones and/or remote audio.\n", p_name);
- }
- } else
- {
- if (!p_debug_nothingtosend)
- {
- p_debug_nothingtosend = 1;
- PDEBUG((DEBUG_PORT | DEBUG_BCHANNEL), "PmISDN(%s) stop sending, because we have only silence.\n", p_name);
- }
- }
#if 0
/* response to the data indication */
rsp.prim = frm->prim & 0xfffffffc | RESPONSE;
//if (dddebug) PDEBUG(DEBUG_ISDN, "dddebug = %d\n", dddebug->type);
break;
+ case mISDNSIGNAL_CALLDATA:
+ if (p_m_calldata != param->mISDNsignal.calldata)
+ {
+ p_m_calldata = param->mISDNsignal.calldata;
+ PDEBUG(DEBUG_BCHANNEL, "we change to calldata=%d.\n", p_m_calldata);
+ auch senden
+ }
+ break;
+
+#if 0
case mISDNSIGNAL_NODATA:
p_m_nodata = param->mISDNsignal.nodata;
if (p_m_txmix == p_m_nodata) /* txmix != !nodata */
ph_control(p_m_b_addr, p_m_txmix?CMX_MIX_ON:CMX_MIX_OFF, 0);
}
break;
+#endif
#if 0
case mISDNSIGNAL_RXOFF:
}
p_m_crypt_msg_current = 0; /* reset */
p_m_crypt_msg_loops = 3; /* enable */
+#if 0
/* disable txmix, or we get corrupt data due to audio process */
if (p_m_txmix)
{
PDEBUG(DEBUG_BCHANNEL, "for sending CR_MESSAGE_REQ, we reset txmix from txmix=%d.\n", p_m_txmix);
ph_control(p_m_b_addr, CMX_MIX_OFF, 0);
}
+#endif
break;
default:
/*
+ * transmit function for data to mISDN b-channel
+ */
+void Port::transmit(unsigned char *buffer, int length)
+{
+}
+
+
+/*
* main loop for processing messages from mISDN device
*/
int mISDN_handler(void)
mISDNport = mISDNport_first;
while(mISDNport)
{
- /* process turning off rx */
+ /* process turning on/off rx */
i = 0;
while(i < mISDNport->b_num)
{
- if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
+ isdnport=mISDNport->b_port[i];
+ /* call bridges in user space OR crypto OR recording */
+ if (isdnport->p_m_calldata || isdnport->p_m_crypt_msg_loops || isdnport->p_m_crypt_listen || isdnport->p_record)
{
- isdnport=mISDNport->b_port[i];
- if (isdnport->p_tone_name[0] || isdnport->p_tone_fh>=0 || isdnport->p_tone_fetched || !isdnport->p_m_nodata || isdnport->p_m_crypt_msg_loops || isdnport->p_m_crypt_listen || isdnport->p_record)
+ /* rx IS required */
+ if (isdnport->p_m_rxoff)
{
- /* rx IS required */
- if (isdnport->p_m_rxoff)
- {
- /* turn on RX */
- isdnport->p_m_rxoff = 0;
- PDEBUG(DEBUG_BCHANNEL, "%s: receive data is required, so we turn them on\n");
+ /* turn on RX */
+ isdnport->p_m_rxoff = 0;
+ PDEBUG(DEBUG_BCHANNEL, "%s: receive data is required, so we turn them on\n");
+ if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
ph_control(isdnport->p_m_b_addr, CMX_RECEIVE_ON, 0);
- }
- } else
+ return(1);
+ }
+ } else
+ {
+ /* rx NOT required */
+ if (!isdnport->p_m_rxoff)
{
- /* rx NOT required */
- if (!isdnport->p_m_rxoff)
- {
- /* turn off RX */
- isdnport->p_m_rxoff = 1;
- PDEBUG(DEBUG_BCHANNEL, "%s: receive data is not required, so we turn them off\n");
+ /* turn off RX */
+ isdnport->p_m_rxoff = 1;
+ PDEBUG(DEBUG_BCHANNEL, "%s: receive data is not required, so we turn them off\n");
+ if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
ph_control(isdnport->p_m_b_addr, CMX_RECEIVE_OFF, 0);
- }
+ return(1);
}
- isdnport->p_m_jittercheck = 0; /* reset jitter detection check */
}
+ /* recordin */
+ if (isdnport->p_record)
+ {
+ /* txdata IS required */
+ if (!isdnport->p_m_txdata)
+ {
+ /* turn on RX */
+ isdnport->p_m_txdata = 1;
+ PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is required, so we turn them on\n");
+ if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
+ ph_control(isdnport->p_m_b_addr, CMX_TXDATA_ON, 0);
+ return(1);
+ }
+ } else
+ {
+ /* txdata NOT required */
+ if (isdnport->p_m_txdata)
+ {
+ /* turn off RX */
+ isdnport->p_m_txdata = 0;
+ PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is not required, so we turn them off\n");
+ if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
+ ph_control(isdnport->p_m_b_addr, CMX_TXDATA_OFF, 0);
+ return(1);
+ }
i++;
}
#if 0
act.len = 0;
mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
}
+ return(1);
}
}
if ((dmsg = msg_dequeue(&mISDNport->downqueue)))
/*
* global function to add a new card (port)
*/
-struct mISDNport *mISDN_port_open(int port, int ptp)
+struct mISDNport *mISDN_port_open(int port, int ptp, int ptmp)
{
int ret;
unsigned char buff[1025];
PDEBUG(DEBUG_ISDN, "NT-mode BRI S/T interface port\n");
nt = 1;
break;
- case ISDN_PID_L0_TE_U:
- PDEBUG(DEBUG_ISDN, "TE-mode BRI U interface line\n");
- break;
- case ISDN_PID_L0_NT_U:
- PDEBUG(DEBUG_ISDN, "NT-mode BRI U interface port\n");
- nt = 1;
- break;
- case ISDN_PID_L0_TE_UP2:
- PDEBUG(DEBUG_ISDN, "TE-mode BRI Up2 interface line\n");
- break;
- case ISDN_PID_L0_NT_UP2:
- PDEBUG(DEBUG_ISDN, "NT-mode BRI Up2 interface port\n");
- nt = 1;
- break;
case ISDN_PID_L0_TE_E1:
PDEBUG(DEBUG_ISDN, "TE-mode PRI E1 interface line\n");
pri = 1;
{
PDEBUG(DEBUG_ISDN, "Port is point-to-point.\n");
mISDNport->ptp = ptp = 1;
+ if (ptmp && nt)
+ {
+ PDEBUG(DEBUG_ISDN, "Port is forced to point-to-multipoint.\n");
+ mISDNport->ptp = ptp = 0;
+ }
}
i = 0;
while(i < stinf->childcnt)
printf(" HFC multiport card");
#endif
break;
- case ISDN_PID_L0_TE_U:
- printf("TE-mode BRI U interface line");
- break;
- case ISDN_PID_L0_NT_U:
- nt = 1;
- printf("NT-mode BRI U interface port");
- break;
- case ISDN_PID_L0_TE_UP2:
- printf("TE-mode BRI Up2 interface line");
- break;
- case ISDN_PID_L0_NT_UP2:
- nt = 1;
- printf("NT-mode BRI Up2 interface port");
- break;
case ISDN_PID_L0_TE_E1:
pri = 1;
printf("TE-mode PRI E1 interface line (for phone lines)");