changed CMX processing to older version process.

note: recevie data to CMX is always required, even on hardware bridging
also it is required even if no conference or bridge is formed.
CMX process reclocks receive data and also processes echo, even with no bridge
or conference.

the queue_conf_id is left as is, additionally i added queue_dtmf flag to enable hardware or software dtmf as the features arrive.

what we can do later: hfcmulti can reply the feature message and bring features
by data body and not by writing to a pointer.

Modified Files:
 	mISDN/CHANGES mISDN/drivers/isdn/hardware/mISDN/dsp.h
 	mISDN/drivers/isdn/hardware/mISDN/dsp_cmx.c
 	mISDN/drivers/isdn/hardware/mISDN/dsp_core.c
This commit is contained in:
Andreas Eversberg 2007-04-03 17:47:26 +00:00
parent c24e757ff4
commit 34458d894d
4 changed files with 42 additions and 53 deletions

View File

@ -4,3 +4,4 @@ mISDN-1-1-2:
- jollys mail has changed - jollys mail has changed
- minor tweaks to misdn-init and to the Kernel-Patch script - minor tweaks to misdn-init and to the Kernel-Patch script
- fix in CMX: sending is required even during PCM bridge, because sending data overrides bridging temporarily (for sending info tones during bridge) - fix in CMX: sending is required even during PCM bridge, because sending data overrides bridging temporarily (for sending info tones during bridge)
- enabled CMX audio processing for RX data in all cases, because it is essential

View File

@ -194,6 +194,7 @@ typedef struct _dsp {
int tx_mix; int tx_mix;
tone_t tone; tone_t tone;
dtmf_t dtmf; dtmf_t dtmf;
int queue_dtmf; /* flags enabled dtmf, prior feature reply */
int tx_volume, rx_volume; int tx_volume, rx_volume;
/* conference stuff */ /* conference stuff */
@ -202,7 +203,7 @@ typedef struct _dsp {
conf_member_t *member; conf_member_t *member;
/* while we're waiting for the hw */ /* while we're waiting for the hw */
u32 queue_conf_id; u32 queue_conf_id; /* stores conf id prior feature reply */
/* buffer stuff */ /* buffer stuff */
int rx_W; /* current write pos for data without timestamp */ int rx_W; /* current write pos for data without timestamp */
@ -239,7 +240,7 @@ typedef struct _dsp {
int bf_sync; int bf_sync;
/* echo cancellation stuff */ /* echo cancellation stuff */
int queue_cancel[3]; int queue_cancel[3]; /* stores cancel values prior feature reply */
int cancel_enable; int cancel_enable;
int cancel_hardware; /*we are using hw echo canc*/ int cancel_hardware; /*we are using hw echo canc*/
struct echo_can_state * ec; /**< == NULL: echo cancellation disabled; struct echo_can_state * ec; /**< == NULL: echo cancellation disabled;

View File

@ -1279,7 +1279,7 @@ void dsp_cmx_send(void *data)
} }
/* transmission required */ /* transmission required */
if (!mustmix && dsp->conf_id) if (!mustmix)
dsp_cmx_send_member(dsp, dsp_poll, mixbuffer, members); // unused mixbuffer is given to prevent a potential null-pointer-bug dsp_cmx_send_member(dsp, dsp_poll, mixbuffer, members); // unused mixbuffer is given to prevent a potential null-pointer-bug
} }
@ -1311,8 +1311,7 @@ void dsp_cmx_send(void *data)
/* process each member */ /* process each member */
list_for_each_entry(member, &conf->mlist, list) { list_for_each_entry(member, &conf->mlist, list) {
/* transmission */ /* transmission */
if (member->dsp->conf_id) dsp_cmx_send_member(member->dsp, dsp_poll, mixbuffer, members);
dsp_cmx_send_member(member->dsp, dsp_poll, mixbuffer, members);
} }
} }
} }

View File

@ -242,18 +242,27 @@ dsp_control_req(dsp_t *dsp, mISDN_head_t *hh, struct sk_buff *skb)
#endif #endif
dsp_dtmf_goertzel_init(dsp); dsp_dtmf_goertzel_init(dsp);
dsp->dtmf.software = 0;
dsp->dtmf.hardware = 0;
/* checking for hardware capability */ /* checking for hardware capability */
spin_lock(&dsp->feature_lock);
if (dsp->feature_state != FEAT_STATE_RECEIVED) {
dsp->queue_dtmf=1;
spin_unlock(&dsp->feature_lock);
break;
}
spin_unlock(&dsp->feature_lock);
if (dsp->features.hfc_dtmf) { if (dsp->features.hfc_dtmf) {
dsp->dtmf.hardware = 1; dsp->dtmf.hardware = 1;
dsp->dtmf.software = 0;
} else { } else {
dsp->dtmf.hardware = 0;
dsp->dtmf.software = 1; dsp->dtmf.software = 1;
} }
break; break;
case DTMF_TONE_STOP: /* turn off DTMF */ case DTMF_TONE_STOP: /* turn off DTMF */
if (dsp_debug & DEBUG_DSP_CORE) if (dsp_debug & DEBUG_DSP_CORE)
printk(KERN_DEBUG "%s: stop dtmf\n", __FUNCTION__); printk(KERN_DEBUG "%s: stop dtmf\n", __FUNCTION__);
dsp->queue_dtmf=0;
dsp->dtmf.hardware = 0; dsp->dtmf.hardware = 0;
dsp->dtmf.software = 0; dsp->dtmf.software = 0;
break; break;
@ -452,44 +461,13 @@ dsp_from_up(mISDNinstance_t *inst, struct sk_buff *skb)
if (skb->len < 1) if (skb->len < 1)
return(-EINVAL); return(-EINVAL);
if (!dsp->conf_id) { /* send data to tx-buffer (if no tone is played) */
/* PROCESS TONES/TX-DATA ONLY */ spin_lock_irqsave(&dsp_obj.lock, flags);
if (dsp->tone.tone) { if (!dsp->tone.tone)
/* -> copy tone */ dsp_cmx_transmit(dsp, skb);
dsp_tone_copy(dsp, skb->data, skb->len); spin_unlock_irqrestore(&dsp_obj.lock, flags);
}
if (dsp->tx_volume) dev_kfree_skb(skb);
dsp_change_volume(skb, dsp->tx_volume);
/* cancel echo */
if (dsp->cancel_enable)
dsp_cancel_tx(dsp, skb->data, skb->len);
/* crypt */
if (dsp->bf_enable)
dsp_bf_encrypt(dsp, skb->data, skb->len);
/* send packet */
if (mISDN_queue_down(&dsp->inst, 0, skb)) {
dev_kfree_skb(skb);
printk(KERN_ERR "%s: failed to send tx-packet\n", __FUNCTION__);
return (-EIO);
}
} else {
if (dsp->features.pcm_id>=0) {
printk("Not sending Data to CMX -- > returning because of HW bridge\n");
dev_kfree_skb(skb);
break;
}
/* send data to tx-buffer (if no tone is played) */
spin_lock_irqsave(&dsp_obj.lock, flags);
if (!dsp->tone.tone) {
dsp_cmx_transmit(dsp, skb);
}
spin_unlock_irqrestore(&dsp_obj.lock, flags);
dev_kfree_skb(skb);
}
break; break;
case PH_CONTROL | REQUEST: case PH_CONTROL | REQUEST:
@ -589,15 +567,13 @@ dsp_from_down(mISDNinstance_t *inst, struct sk_buff *skb)
if (dsp->rx_volume) if (dsp->rx_volume)
dsp_change_volume(skb, dsp->rx_volume); dsp_change_volume(skb, dsp->rx_volume);
if (dsp->conf_id) { /* we need to process receive data if software */
/* we need to process receive data if software */ spin_lock_irqsave(&dsp_obj.lock, flags);
spin_lock_irqsave(&dsp_obj.lock, flags); if (dsp->pcm_slot_tx<0 && dsp->pcm_slot_rx<0) {
if (dsp->pcm_slot_tx<0 && dsp->pcm_slot_rx<0) { /* process data from card at cmx */
/* process data from card at cmx */ dsp_cmx_receive(dsp, skb);
dsp_cmx_receive(dsp, skb);
}
spin_unlock_irqrestore(&dsp_obj.lock, flags);
} }
spin_unlock_irqrestore(&dsp_obj.lock, flags);
if (dsp->rx_disabled) { if (dsp->rx_disabled) {
/* if receive is not allowed */ /* if receive is not allowed */
@ -802,12 +778,23 @@ dsp_feat(void *arg)
spin_unlock(&dsp->feature_lock); spin_unlock(&dsp->feature_lock);
if (dsp->queue_conf_id) { if (dsp->queue_conf_id) {
/*work on queued conf id*/ /* work on queued conf id*/
dsp_cmx_conf(dsp, dsp->queue_conf_id ); dsp_cmx_conf(dsp, dsp->queue_conf_id );
if (dsp_debug & DEBUG_DSP_CMX) if (dsp_debug & DEBUG_DSP_CMX)
dsp_cmx_debug(dsp); dsp_cmx_debug(dsp);
} }
if (dsp->queue_dtmf) {
/* work on queued dtmf */
if (dsp->features.hfc_dtmf) {
dsp->dtmf.software = 0;
dsp->dtmf.hardware = 1;
} else {
dsp->dtmf.hardware = 0;
dsp->dtmf.software = 1;
}
}
if (dsp->queue_cancel[2]) { if (dsp->queue_cancel[2]) {
dsp_cancel_init(dsp, dsp_cancel_init(dsp,
dsp->queue_cancel[0], dsp->queue_cancel[0],
@ -873,6 +860,7 @@ new_dsp(mISDNstack_t *st, mISDN_pid_t *pid)
if (dtmfthreshold < 20 || dtmfthreshold> 500) { if (dtmfthreshold < 20 || dtmfthreshold> 500) {
dtmfthreshold=200; dtmfthreshold=200;
} }
#warning CHRISTIAN: my define was 200000, but your default is 200*10000=2000000. what shall we do? *1000 or dtmftreshold=20 ??
ndsp->dtmf.treshold=dtmfthreshold*10000; ndsp->dtmf.treshold=dtmfthreshold*10000;
spin_lock_init(&ndsp->feature_lock); spin_lock_init(&ndsp->feature_lock);