Commit b5df5a5c authored by Andreas Eversberg's avatar Andreas Eversberg Committed by David S. Miller

mISDN: Fix DTMF locking bug issue

DTMF digits were sent up to socket in locked state.
Receive audio stream was not enabled in certain condition.
Signed-off-by: default avatarAndreas Eversberg <andreas@eversberg.eu>
Signed-off-by: default avatarKarsten Keil <keil@b1-systems.de>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent e73f6b22
...@@ -1817,8 +1817,8 @@ hfcmulti_dtmf(struct hfc_multi *hc) ...@@ -1817,8 +1817,8 @@ hfcmulti_dtmf(struct hfc_multi *hc)
coeff[(co<<1)|1] = mantissa; coeff[(co<<1)|1] = mantissa;
} }
if (debug & DEBUG_HFCMULTI_DTMF) if (debug & DEBUG_HFCMULTI_DTMF)
printk("%s: DTMF ready %08x %08x %08x %08x " printk(" DTMF ready %08x %08x %08x %08x "
"%08x %08x %08x %08x\n", __func__, "%08x %08x %08x %08x\n",
coeff[0], coeff[1], coeff[2], coeff[3], coeff[0], coeff[1], coeff[2], coeff[3],
coeff[4], coeff[5], coeff[6], coeff[7]); coeff[4], coeff[5], coeff[6], coeff[7]);
hc->chan[ch].coeff_count++; hc->chan[ch].coeff_count++;
......
...@@ -124,7 +124,7 @@ struct dsp_dtmf { ...@@ -124,7 +124,7 @@ struct dsp_dtmf {
/* buffers one full dtmf frame */ /* buffers one full dtmf frame */
u8 lastwhat, lastdigit; u8 lastwhat, lastdigit;
int count; int count;
u8 digits[16]; /* just the dtmf result */ u8 digits[16]; /* dtmf result */
}; };
......
...@@ -311,6 +311,7 @@ dsp_control_req(struct dsp *dsp, struct mISDNhead *hh, struct sk_buff *skb) ...@@ -311,6 +311,7 @@ dsp_control_req(struct dsp *dsp, struct mISDNhead *hh, struct sk_buff *skb)
/* check dtmf hardware */ /* check dtmf hardware */
dsp_dtmf_hardware(dsp); dsp_dtmf_hardware(dsp);
dsp_rx_off(dsp);
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)
...@@ -657,11 +658,10 @@ get_features(struct mISDNchannel *ch) ...@@ -657,11 +658,10 @@ get_features(struct mISDNchannel *ch)
static int static int
dsp_function(struct mISDNchannel *ch, struct sk_buff *skb) dsp_function(struct mISDNchannel *ch, struct sk_buff *skb)
{ {
struct dsp *dsp = container_of(ch, struct dsp, ch); struct dsp *dsp = container_of(ch, struct dsp, ch);
struct mISDNhead *hh; struct mISDNhead *hh;
int ret = 0; int ret = 0;
u8 *digits; u8 *digits = NULL;
int cont;
u_long flags; u_long flags;
hh = mISDN_HEAD_P(skb); hh = mISDN_HEAD_P(skb);
...@@ -716,40 +716,43 @@ dsp_function(struct mISDNchannel *ch, struct sk_buff *skb) ...@@ -716,40 +716,43 @@ dsp_function(struct mISDNchannel *ch, struct sk_buff *skb)
/* change volume if requested */ /* change volume if requested */
if (dsp->rx_volume) if (dsp->rx_volume)
dsp_change_volume(skb, dsp->rx_volume); dsp_change_volume(skb, dsp->rx_volume);
/* check if dtmf soft decoding is turned on */ /* check if dtmf soft decoding is turned on */
if (dsp->dtmf.software) { if (dsp->dtmf.software) {
digits = dsp_dtmf_goertzel_decode(dsp, skb->data, digits = dsp_dtmf_goertzel_decode(dsp, skb->data,
skb->len, (dsp_options&DSP_OPT_ULAW)?1:0); skb->len, (dsp_options&DSP_OPT_ULAW)?1:0);
}
/* we need to process receive data if software */
if (dsp->pcm_slot_tx < 0 && dsp->pcm_slot_rx < 0) {
/* process data from card at cmx */
dsp_cmx_receive(dsp, skb);
}
spin_unlock_irqrestore(&dsp_lock, flags);
/* send dtmf result, if any */
if (digits) {
while (*digits) { while (*digits) {
int k;
struct sk_buff *nskb; struct sk_buff *nskb;
if (dsp_debug & DEBUG_DSP_DTMF) if (dsp_debug & DEBUG_DSP_DTMF)
printk(KERN_DEBUG "%s: digit" printk(KERN_DEBUG "%s: digit"
"(%c) to layer %s\n", "(%c) to layer %s\n",
__func__, *digits, dsp->name); __func__, *digits, dsp->name);
cont = DTMF_TONE_VAL | *digits; k = *digits | DTMF_TONE_VAL;
nskb = _alloc_mISDN_skb(PH_CONTROL_IND, nskb = _alloc_mISDN_skb(PH_CONTROL_IND,
MISDN_ID_ANY, sizeof(int), &cont, MISDN_ID_ANY, sizeof(int), &k,
GFP_ATOMIC); GFP_ATOMIC);
if (nskb) { if (nskb) {
if (dsp->up) { if (dsp->up) {
if (dsp->up->send( if (dsp->up->send(
dsp->up, nskb)) dsp->up, nskb))
dev_kfree_skb(nskb); dev_kfree_skb(nskb);
} else } else
dev_kfree_skb(nskb); dev_kfree_skb(nskb);
} }
digits++; digits++;
} }
} }
/* we need to process receive data if software */
if (dsp->pcm_slot_tx < 0 && dsp->pcm_slot_rx < 0) {
/* process data from card at cmx */
dsp_cmx_receive(dsp, skb);
}
spin_unlock_irqrestore(&dsp_lock, flags);
if (dsp->rx_disabled) { if (dsp->rx_disabled) {
/* if receive is not allowed */ /* if receive is not allowed */
break; break;
...@@ -789,7 +792,7 @@ dsp_function(struct mISDNchannel *ch, struct sk_buff *skb) ...@@ -789,7 +792,7 @@ dsp_function(struct mISDNchannel *ch, struct sk_buff *skb)
if (dsp->up) { if (dsp->up) {
if (dsp->up->send( if (dsp->up->send(
dsp->up, nskb)) dsp->up, nskb))
dev_kfree_skb(nskb); dev_kfree_skb(nskb);
} else } else
dev_kfree_skb(nskb); dev_kfree_skb(nskb);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment