p_m_mute = 0;
p_m_txdata = 0;
p_m_delay = 0;
+ p_m_tx_dejitter = 0;
p_m_echo = 0;
p_m_tone = 0;
p_m_rxoff = 0;
- p_m_joindata = 0;
p_m_inband_send_on = 0;
p_m_inband_receive_on = 0;
p_m_dtmf = !mISDNport->ifport->nodtmf;
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 && 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_dejitter && mode == B_MODE_TRANSPARENT)
+ ph_control(mISDNport, port, handle, DSP_TX_DEJITTER, port->p_m_tx_dejitter, "DSP-TX_DEJITTER", port->p_m_tx_dejitter);
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 && mode == B_MODE_TRANSPARENT)
}
if (p_tone_name[0] || p_m_crypt_msg_loops || p_m_inband_send_on || p_m_load) {
- schedule_timer(&p_m_loadtimer, 0, ISDN_TRANSMIT*125);
+ schedule_timer(&p_m_loadtimer, 0, PORT_TRANSMIT * 125);
}
}
void PmISDN::bchannel_receive(struct mISDNhead *hh, unsigned char *data, int len)
{
unsigned int cont = *((unsigned int *)data);
- unsigned char *data_temp;
- unsigned int length_temp;
struct lcr_msg *message;
unsigned char *p;
int l;
if (p_m_inband_receive_on)
inband_receive(data, len);
+ /* send to remote, if bridged */
+ bridge_tx(data, len);
+
/* calls will not process any audio data unless
* the call is connected OR tones feature is enabled.
*/
cryptman_listen_bch(data, len);
}
-
- p = data;
-
- /* send data to epoint */
- if (p_m_joindata && ACTIVE_EPOINT(p_epointlist)) { /* only if we have an epoint object */
- length_temp = len;
- data_temp = p;
- while(length_temp) {
- message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DATA);
- message->param.data.len = (length_temp>sizeof(message->param.data.data))?sizeof(message->param.data.data):length_temp;
- memcpy(message->param.data.data, data_temp, message->param.data.len);
- message_put(message);
- if (length_temp <= sizeof(message->param.data.data))
- break;
- data_temp += sizeof(message->param.data.data);
- length_temp -= sizeof(message->param.data.data);
- }
- }
}
set_conf(oldconf, newconf);
break;
- case mISDNSIGNAL_JOINDATA:
- if (p_m_joindata != param->mISDNsignal.joindata) {
- p_m_joindata = param->mISDNsignal.joindata;
- PDEBUG(DEBUG_BCHANNEL, "we change to joindata=%d.\n", p_m_joindata);
- update_rxoff();
- } else
- PDEBUG(DEBUG_BCHANNEL, "we already have joindata=%d.\n", p_m_joindata);
- break;
-
case mISDNSIGNAL_DELAY:
if (p_m_delay != param->mISDNsignal.delay) {
p_m_delay = param->mISDNsignal.delay;
*/
int PmISDN::message_epoint(unsigned int epoint_id, int message_id, union parameter *param)
{
- if (Port::message_epoint(epoint_id, message_id, param))
- return(1);
+ if (Port::message_epoint(epoint_id, message_id, param)) {
+ if (message_id == MESSAGE_BRIDGE)
+ update_rxoff();
+ return 1;
+ }
switch(message_id) {
- case MESSAGE_DATA: /* tx-data from upper layer */
- txfromup(param->data.data, param->data.len);
- return(1);
-
case MESSAGE_mISDNSIGNAL: /* user command */
PDEBUG(DEBUG_ISDN, "PmISDN(%s) received special ISDN SIGNAL %d.\n", p_name, param->mISDNsignal.message);
message_mISDNsignal(epoint_id, message_id, param);
- return(1);
+ return 1;
case MESSAGE_CRYPT: /* crypt control command */
PDEBUG(DEBUG_ISDN, "PmISDN(%s) received encryption command '%d'.\n", p_name, param->crypt.type);
message_crypt(epoint_id, message_id, param);
- return(1);
+ return 1;
}
- return(0);
+ return 0;
}
void PmISDN::update_rxoff(void)
{
+ int tx_dejitter = 0;
+
/* call bridges in user space OR crypto OR recording */
- if (p_m_joindata || p_m_crypt_msg_loops || p_m_crypt_listen || p_record || p_m_inband_receive_on) {
+ if (p_bridge || p_m_crypt_msg_loops || p_m_crypt_listen || p_record || p_m_inband_receive_on) {
/* rx IS required */
if (p_m_rxoff) {
/* turn on RX */
ph_control(p_m_mISDNport, this, p_m_mISDNport->b_sock[p_m_b_index].fd, DSP_TXDATA_OFF, 0, "DSP-TXDATA", 0);
}
}
+ /* dejitter on bridge */
+ if (p_bridge)
+ tx_dejitter = 1;
+ if (p_m_tx_dejitter != tx_dejitter) {
+ p_m_tx_dejitter = tx_dejitter;
+ PDEBUG(DEBUG_BCHANNEL, "we change dejitter mode to delay=%d.\n", p_m_tx_dejitter);
+ if (p_m_b_index > -1)
+ 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_sock[p_m_b_index].fd, DSP_TX_DEJITTER, p_m_tx_dejitter, "DSP-TX_DEJITTER", p_m_tx_dejitter);
+ }
}
static int mISDN_upqueue(struct lcr_fd *fd, unsigned int what, void *instance, int i)
static int b_timer_timeout(struct lcr_timer *timer, void *instance, int i)
{
struct mISDNport *mISDNport = (struct mISDNport *)instance;
-puts("fires");
bchannel_event(mISDNport, i, B_EVENT_TIMEOUT);
struct mISDN_devinfo devinfo;
unsigned int protocol, prop;
-#if defined WITH_GSM_BS && defined WITH_GSM_MS
- loop = ifport->gsm_ms | ifport->gsm_bs;
-#else
-#ifdef WITH_GSM_BS
- loop = ifport->gsm_bs;
-#endif
-#ifdef WITH_GSM_MS
- loop = ifport->gsm_ms;
-#endif
-#endif
+ loop = 0;
//printf("%s == %s\n", ifport->portname, options.loopback_int);
if (!strcmp(ifport->portname, options.loopback_lcr))
loop = 1;
mISDNport->l1link = -1;
mISDNport->l2link = -1;
}
-#ifdef WITH_GSM_BS
- mISDNport->gsm_bs = ifport->gsm_bs;
-#endif
-#ifdef WITH_GSM_MS
- mISDNport->gsm_ms = ifport->gsm_ms;
-#endif
mISDNport->isloopback = loop;
pmemuse++;
*mISDNportp = mISDNport;
/*
* enque data from upper buffer
*/
-void PmISDN::txfromup(unsigned char *data, int length)
+int PmISDN::bridge_rx(unsigned char *data, int length)
{
unsigned char buf[MISDN_HEADER_LEN+((length>ISDN_LOAD)?length:ISDN_LOAD)];
struct mISDNhead *hh = (struct mISDNhead *)buf;
int ret;
if (p_m_b_index < 0)
- return;
+ return -EIO;
if (p_m_mISDNport->b_state[p_m_b_index] != B_STATE_ACTIVE)
- return;
+ return -EINVAL;
/* check if high priority tones exist
* ignore data in this case
*/
if (p_tone_name[0] || p_m_crypt_msg_loops || p_m_inband_send_on)
- return;
+ return -EBUSY;
/* preload procedure
* if transmit buffer in DSP module is empty,
if (ret <= 0)
PERROR("Failed to send to socket %d\n", p_m_mISDNport->b_sock[p_m_b_index].fd);
p_m_load += ISDN_LOAD;
- schedule_timer(&p_m_loadtimer, 0, ISDN_TRANSMIT*125);
+ schedule_timer(&p_m_loadtimer, 0, PORT_TRANSMIT * 125);
}
/* drop if load would exceed ISDN_MAXLOAD
* this keeps the delay not too high
*/
if (p_m_load+length > ISDN_MAXLOAD)
- return;
+ return -EINVAL;
/* make and send frame */
hh->prim = PH_DATA_REQ;
if (ret <= 0)
PERROR("Failed to send to socket %d\n", p_m_mISDNport->b_sock[p_m_b_index].fd);
p_m_load += length;
+
+ return 0;
}
int PmISDN::inband_send(unsigned char *buffer, int len)