mISDNuser/i4lnet/tone.c

148 lines
4.0 KiB
C

#include <stdio.h>
#include "isdn_net.h"
#include "tone.h"
#include "bchannel.h"
/*
* These are 10 periods (24 ms) of the 425 Hz tone used by most inband
* signals.
* Its quiet not exacly 425 Hz, but 416,66667, which fit very well
* the 15% tolerance
*/
const unsigned char tone_425[TONE_425_SIZE] = {
0xd5, 0x81, 0xb6, 0xbf, 0xbb, 0xba, 0xb8, 0xb2,
0x8a, 0x9d, 0x15, 0x0e, 0x33, 0x39, 0x3a, 0x3b,
0x3e, 0x31, 0x0d, 0x65, 0x85, 0xb4, 0xbd, 0xb8,
0xba, 0xb8, 0xbd, 0xb4, 0x85, 0x65, 0x0d, 0x31,
0x3e, 0x3b, 0x3a, 0x39, 0x33, 0x0e, 0x15, 0x9d,
0x8a, 0xb2, 0xb8, 0xba, 0xbb, 0xbf, 0xb6, 0x81,
0xd5, 0x01, 0x36, 0x3f, 0x3b, 0x3a, 0x38, 0x32,
0x0a, 0x1d, 0x95, 0x8e, 0xb3, 0xb9, 0xba, 0xbb,
0xbe, 0xb1, 0x8d, 0xe5, 0x05, 0x34, 0x3d, 0x38,
0x3a, 0x38, 0x3d, 0x34, 0x05, 0xe5, 0x8d, 0xb1,
0xbe, 0xbb, 0xba, 0xb9, 0xb3, 0x8e, 0x95, 0x1d,
0x0a, 0x32, 0x38, 0x3a, 0x3b, 0x3f, 0x36, 0x01,
0xd5, 0x81, 0xb6, 0xbf, 0xbb, 0xba, 0xb8, 0xb2,
0x8a, 0x9d, 0x15, 0x0e, 0x33, 0x39, 0x3a, 0x3b,
0x3e, 0x31, 0x0d, 0x65, 0x85, 0xb4, 0xbd, 0xb8,
0xba, 0xb8, 0xbd, 0xb4, 0x85, 0x65, 0x0d, 0x31,
0x3e, 0x3b, 0x3a, 0x39, 0x33, 0x0e, 0x15, 0x9d,
0x8a, 0xb2, 0xb8, 0xba, 0xbb, 0xbf, 0xb6, 0x81,
0xd5, 0x01, 0x36, 0x3f, 0x3b, 0x3a, 0x38, 0x32,
0x0a, 0x1d, 0x95, 0x8e, 0xb3, 0xb9, 0xba, 0xbb,
0xbe, 0xb1, 0x8d, 0xe5, 0x05, 0x34, 0x3d, 0x38,
0x3a, 0x38, 0x3d, 0x34, 0x05, 0xe5, 0x8d, 0xb1,
0xbe, 0xbb, 0xba, 0xb9, 0xb3, 0x8e, 0x95, 0x1d,
0x0a, 0x32, 0x38, 0x3a, 0x3b, 0x3f, 0x36, 0x01
};
/*
* These are 10 ms of silence
*/
const unsigned char tone_SILENCE[TONE_SILENCE_SIZE] = {
0xd5, 0xd5, 0xd5, 0xd5, 0xd5, 0xd5, 0xd5, 0xd5,
0xd5, 0xd5, 0xd5, 0xd5, 0xd5, 0xd5, 0xd5, 0xd5,
0xd5, 0xd5, 0xd5, 0xd5, 0xd5, 0xd5, 0xd5, 0xd5,
0xd5, 0xd5, 0xd5, 0xd5, 0xd5, 0xd5, 0xd5, 0xd5,
0xd5, 0xd5, 0xd5, 0xd5, 0xd5, 0xd5, 0xd5, 0xd5,
0xd5, 0xd5, 0xd5, 0xd5, 0xd5, 0xd5, 0xd5, 0xd5,
0xd5, 0xd5, 0xd5, 0xd5, 0xd5, 0xd5, 0xd5, 0xd5,
0xd5, 0xd5, 0xd5, 0xd5, 0xd5, 0xd5, 0xd5, 0xd5,
0xd5, 0xd5, 0xd5, 0xd5, 0xd5, 0xd5, 0xd5, 0xd5,
0xd5, 0xd5, 0xd5, 0xd5, 0xd5, 0xd5, 0xd5, 0xd5
};
int tone_handler(bchannel_t *bc) {
const unsigned char *tp;
int len;
dprint(DBGM_TONE, "%s:ch%d Flags %x\n", __FUNCTION__,
bc->channel, bc->Flags);
if (bc->bstate != BC_BSTATE_ACTIV)
return(1);
if (bc->smsg)
return(2);
if (!(bc->Flags & FLG_BC_TONE))
return(3);
if (bc->Flags & FLG_BC_TONE_DIAL) {
tp = tone_425;
len = TONE_425_SIZE;
} else if (bc->Flags & FLG_BC_TONE_ALERT) {
if (bc->Flags & FLG_BC_TONE_SILENCE) {
if (bc->ttime > TONE_ALERT_SILENCE_TIME) {
bc->ttime = 0;
tp = tone_425;
len = TONE_425_SIZE;
bc->Flags &= ~FLG_BC_TONE_SILENCE;
} else {
tp = tone_SILENCE;
len = TONE_SILENCE_SIZE;
}
} else {
if (bc->ttime > TONE_ALERT_TIME) {
bc->ttime = 0;
tp = tone_SILENCE;
len = TONE_SILENCE_SIZE;
bc->Flags |= FLG_BC_TONE_SILENCE;
} else {
tp = tone_425;
len = TONE_425_SIZE;
}
}
} else if (bc->Flags & FLG_BC_TONE_BUSY) {
if (bc->Flags & FLG_BC_TONE_SILENCE) {
if (bc->ttime > TONE_BUSY_SILENCE_TIME) {
bc->ttime = 0;
tp = tone_425;
len = TONE_425_SIZE;
bc->Flags &= ~FLG_BC_TONE_SILENCE;
} else {
tp = tone_SILENCE;
len = TONE_SILENCE_SIZE;
}
} else {
if (bc->ttime > TONE_BUSY_TIME) {
bc->ttime = 0;
tp = tone_SILENCE;
len = TONE_SILENCE_SIZE;
bc->Flags |= FLG_BC_TONE_SILENCE;
} else {
tp = tone_425;
len = TONE_425_SIZE;
}
}
} else if (bc->Flags & FLG_BC_TONE_SILENCE) {
tp = tone_SILENCE;
len = TONE_SILENCE_SIZE;
} else
return(4);
if (len > ibuf_freecount(bc->sbuf)) {
dprint(DBGM_TONE, "%s:ch%d not sbuf %d/%d\n", __FUNCTION__,
bc->channel, len, ibuf_freecount(bc->sbuf));
return(5);
}
if (bc->sbuf) {
bc->ttime += len*125;
ibuf_memcpy_w(bc->sbuf, (unsigned char *)tp, len);
sem_post(bc->sbuf->rsem);
}
return(0);
}
int
set_tone(bchannel_t *bc, int tone)
{
bc->Flags &= ~FLG_BC_TONE;
bc->Flags |= tone;
bc->ttime = 0;
if (tone) {
if (bc->sbuf) {
bc->sbuf->rsem = &bc->work;
bc->sbuf->wsem = &bc->work;
}
}
return(bc->Flags & FLG_BC_TONE);
}