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);
}
/* 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
}
}
{
if (mISDNport->b_port[i]->p_m_delay)
{
+ 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);
ph_control(mISDNport->b_addr[i], CMX_JITTER, 0);
}
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);
+
+ /* send tone data to isdn device only if we have data */
+ if (p_tone_fh>=0 || p_tone_fetched || p_m_crypt_msg_loops)
+ {
+ /* 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)
+ {
+ elapsed = ISDN_PRELOAD << 3
+ }
+ }
+ if (elapsed >= ISDN_TRANSMIT)
+ {
+ unsigned char buf[mISDN_HEADER_LEN+(ISDN_PRELOAD<<3)];
+ iframe_t *frm = (iframe_t *)buf;
+
+ length = read_audio(buffer, elapsed);
+ p_last_tv_sec = now_tv.sec;
+ p_last_tv_msec = now_tv.usec/1000;
+
+ if (p_m_crypt_msg_loops)
+ {
+ /* send pending message */
+ int tosend;
+ check!!
+ tosend = p_m_crypt_msg_len - p_m_crypt_msg_current;
+ if (tosend > length)
+ tosend = length;
+ 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 = 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
+ {
+ p_last_tv.sec = p_last_tv.msec = 0; /* flag that we don't transmit data */
+ 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
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
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];
- 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)
+ if (isdnport->p_m_calldata || isdnport->p_m_crypt_msg_loops || isdnport->p_m_crypt_listen || isdnport->p_record)
{
/* rx IS required */
if (isdnport->p_m_rxoff)
isdnport->p_m_rxoff = 0;
PDEBUG(DEBUG_BCHANNEL, "%s: receive data is required, so we turn them on\n");
ph_control(isdnport->p_m_b_addr, CMX_RECEIVE_ON, 0);
+ return(1);
}
} else
{
isdnport->p_m_rxoff = 1;
PDEBUG(DEBUG_BCHANNEL, "%s: receive data is not required, so we turn them off\n");
ph_control(isdnport->p_m_b_addr, CMX_RECEIVE_OFF, 0);
+ return(1);
}
}
- isdnport->p_m_jittercheck = 0; /* reset jitter detection check */
}
i++;
}
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, "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)