Added first try of a HDLC decoder.
Added logging to v21_softmodem.
This commit is contained in:
parent
21da018e86
commit
4ce1ba9b68
|
@ -3,7 +3,8 @@ CFLAGS=-O2 -g -Wall -pedantic -I../include
|
|||
|
||||
MODULES = send_to_audio.o pulsegen.o sinegen.o replicate.o \
|
||||
scrambler.o modulator-V29.o fsk_demod.o fsk_mod.o \
|
||||
decode_serial.o encode_serial.o debug.o rateconvert.o
|
||||
decode_serial.o encode_serial.o debug.o rateconvert.o \
|
||||
decode_hdlc.o
|
||||
|
||||
HELPERS =
|
||||
|
||||
|
|
|
@ -0,0 +1,148 @@
|
|||
/* $Id$
|
||||
******************************************************************************
|
||||
|
||||
Fax program for ISDN.
|
||||
Decoder for hdlc data input. Expects a datastream of alternating
|
||||
0/1,confidence bytes at SAMPLES_PER_SECOND.
|
||||
Outputs decoded bytes that came in without any error.
|
||||
Automatically locks onto the start flag and undoes bit stuffing.
|
||||
|
||||
Copyright (C) 1998 Andreas Beck [becka@ggi-project.org]
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
THE AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include <time.h>
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <sys/times.h>
|
||||
#include <ifax/ifax.h>
|
||||
|
||||
#define HDLC_FLAG (0x7e)
|
||||
#define HDLC_STUFFMASK (0x3f)
|
||||
#define HDLC_STUFF (0x3e)
|
||||
|
||||
typedef struct {
|
||||
|
||||
int baud;
|
||||
|
||||
int lastsamp;
|
||||
int bitnum;
|
||||
int sampcount;
|
||||
int syncbitcnt;
|
||||
int bits;
|
||||
int have_stuffed;
|
||||
|
||||
} decode_hdlc_private;
|
||||
|
||||
/* Free the private data
|
||||
*/
|
||||
void decode_hdlc_destroy(ifax_modp self)
|
||||
{
|
||||
decode_hdlc_private *priv=(decode_hdlc_private *)self->private;
|
||||
|
||||
free(self->private);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int decode_hdlc_command(ifax_modp self,int cmd,va_list cmds)
|
||||
{
|
||||
return 0; /* Not yet used. */
|
||||
}
|
||||
|
||||
int decode_hdlc_handle(ifax_modp self, void *data, size_t length)
|
||||
{
|
||||
char *dat=data;
|
||||
int currbit,currconf;
|
||||
int x,result,handled,parity;
|
||||
char hlpres;
|
||||
|
||||
decode_hdlc_private *priv=(decode_hdlc_private *)self->private;
|
||||
|
||||
handled=0;
|
||||
while(length--) {
|
||||
|
||||
currbit =*dat++;
|
||||
currconf=*dat++;
|
||||
priv->sampcount++;
|
||||
|
||||
// printf("%d,%d\n",currbit,currconf);
|
||||
|
||||
if (currconf<10) continue;
|
||||
|
||||
if (priv->lastsamp!=currbit) {
|
||||
// printf("synchronizing due to %d->%d at %d\n",priv->lastsamp,currbit,priv->sampcount);
|
||||
priv->lastsamp=currbit;
|
||||
priv->sampcount=-SAMPLES_PER_SECOND/2/priv->baud;
|
||||
priv->bitnum=0;
|
||||
} else
|
||||
if ( priv->sampcount >= priv->bitnum*
|
||||
SAMPLES_PER_SECOND/priv->baud)
|
||||
{
|
||||
// printf("Bit %d(%d) is %d\n",priv->syncbitcnt,priv->bitnum,currbit);
|
||||
priv->bits<<=1;
|
||||
priv->bits|=!!currbit;
|
||||
priv->syncbitcnt++;
|
||||
if ((priv->bits&0xff)==HDLC_FLAG)
|
||||
{
|
||||
printf("FLAG !\n");
|
||||
priv->syncbitcnt=0;
|
||||
} else if (!priv->have_stuffed &&(priv->bits&HDLC_STUFFMASK)==HDLC_STUFF)
|
||||
{
|
||||
printf("Stuff !\n");
|
||||
priv->bits>>=1;
|
||||
priv->syncbitcnt--;
|
||||
priv->have_stuffed=1;
|
||||
} else if ((priv->syncbitcnt&7)==0)
|
||||
{
|
||||
priv->have_stuffed=0;
|
||||
printf("HDLC %x\n",priv->bits&0xff);
|
||||
}
|
||||
priv->bitnum++;
|
||||
}
|
||||
handled++;
|
||||
}
|
||||
return handled;
|
||||
}
|
||||
|
||||
int decode_hdlc_construct(ifax_modp self,va_list args)
|
||||
{
|
||||
decode_hdlc_private *priv;
|
||||
char *encode;
|
||||
|
||||
if (NULL==(priv=self->private=malloc(sizeof(decode_hdlc_private))))
|
||||
return 1;
|
||||
self->destroy =decode_hdlc_destroy;
|
||||
self->handle_input =decode_hdlc_handle;
|
||||
self->command =decode_hdlc_command;
|
||||
|
||||
priv->baud=va_arg(args,int);
|
||||
|
||||
priv->bitnum=-1; /* Init to "wait for sync" */
|
||||
priv->lastsamp=2; /* Make sure we init */
|
||||
priv->syncbitcnt=0;
|
||||
priv->bits=0;
|
||||
priv->have_stuffed=0;
|
||||
|
||||
return 0;
|
||||
}
|
58
test.c
58
test.c
|
@ -48,6 +48,7 @@ int rateconvert_construct(ifax_modp self, va_list args);
|
|||
int fskdemod_construct(ifax_modp self, va_list args);
|
||||
int fskmod_construct(ifax_modp self, va_list args);
|
||||
int decode_serial_construct(ifax_modp self, va_list args);
|
||||
int decode_hdlc_construct(ifax_modp self, va_list args);
|
||||
int encode_serial_construct(ifax_modp self, va_list args);
|
||||
int debug_construct(ifax_modp self, va_list args);
|
||||
|
||||
|
@ -66,6 +67,7 @@ ifax_module_id IFAX_FSKDEMOD;
|
|||
ifax_module_id IFAX_FSKMOD;
|
||||
ifax_module_id IFAX_DECODE_SERIAL;
|
||||
ifax_module_id IFAX_ENCODE_SERIAL;
|
||||
ifax_module_id IFAX_DECODE_HDLC;
|
||||
ifax_module_id IFAX_DEBUG;
|
||||
|
||||
void setup_all_modules(void)
|
||||
|
@ -78,6 +80,7 @@ void setup_all_modules(void)
|
|||
IFAX_FSKMOD = ifax_register_module_class("FSK modulator",fskmod_construct);
|
||||
IFAX_DECODE_SERIAL= ifax_register_module_class("Serializer",decode_serial_construct);
|
||||
IFAX_ENCODE_SERIAL= ifax_register_module_class("Serial encoder",encode_serial_construct);
|
||||
IFAX_DECODE_HDLC = ifax_register_module_class("HDLC decoder",decode_hdlc_construct);
|
||||
IFAX_SCRAMBLER = ifax_register_module_class("Bitstream scrambler",scrambler_construct);
|
||||
IFAX_MODULATORV29 = ifax_register_module_class("V.29 Modulator",modulator_V29_construct);
|
||||
IFAX_RATECONVERT = ifax_register_module_class("Sample-rate converter",rateconvert_construct);
|
||||
|
@ -192,6 +195,58 @@ void test_scrambler(void)
|
|||
ifax_handle_input(scrambler,source,200);
|
||||
}
|
||||
|
||||
/* HDLC testing code
|
||||
*/
|
||||
static void test_hdlc(void)
|
||||
{
|
||||
/* module handles for all used modules.
|
||||
*/
|
||||
ifax_modp fskd,totty,dehdlc;
|
||||
|
||||
/* helper for data in-/output
|
||||
*/
|
||||
unsigned char data;
|
||||
|
||||
#if 0
|
||||
ifax_modp toaudio,debug,replicate;
|
||||
|
||||
/* debugger */
|
||||
debug=ifax_create_module(IFAX_DEBUG,1);
|
||||
|
||||
/* Replicate the incoming signal. */
|
||||
replicate=ifax_create_module(IFAX_REPLICATE);
|
||||
// ifax_command(replicate,CMD_REPLICATE_ADD,toisdn);
|
||||
#endif
|
||||
|
||||
/* Now for the receiver. When all is decoded, the text is sent
|
||||
* to the outputhandle.
|
||||
*/
|
||||
totty=ifax_create_module(IFAX_TOAUDIO, write, 1/*outputhandle*/);
|
||||
|
||||
/* The deserializer synchronizes on the startbits and decodes
|
||||
* from the 0/1 stream from the demodulator to the bytes.
|
||||
* Its output is sent to the totty module. Seee above.
|
||||
*/
|
||||
dehdlc=ifax_create_module(IFAX_DECODE_HDLC,300);
|
||||
dehdlc->sendto=totty;
|
||||
|
||||
/* The FSK demodulator. Takes the aLaw input stream and sends the
|
||||
* decoded version to the deserializer. See above.
|
||||
*/
|
||||
fskd=ifax_create_module(IFAX_FSKDEMOD,1650,1850,300);
|
||||
fskd->sendto=dehdlc;
|
||||
|
||||
/* Run until explicitly terminated.
|
||||
*/
|
||||
while(1) {
|
||||
|
||||
if (read(0,&data,1)!=1) break;
|
||||
|
||||
/* Send it to the demodulator.
|
||||
*/
|
||||
ifax_handle_input(fskd,&data,1);
|
||||
}
|
||||
}
|
||||
|
||||
void main(int argc,char **argv)
|
||||
{
|
||||
|
@ -199,5 +254,6 @@ void main(int argc,char **argv)
|
|||
|
||||
/* transmit_carrier(); */
|
||||
/* test_modulator_V29(); */
|
||||
test_scrambler();
|
||||
// test_scrambler();
|
||||
test_hdlc();
|
||||
}
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <unistd.h>
|
||||
#include <getopt.h>
|
||||
|
@ -86,7 +87,7 @@ enum MODEM_MODE { ORIGINATE, ANSWER };
|
|||
|
||||
/* The actual "modem" code.
|
||||
*/
|
||||
static void test_v21(enum MODEM_MODE direction)
|
||||
static void test_v21(enum MODEM_MODE direction,int outfd)
|
||||
{
|
||||
/* module handles for all used modules.
|
||||
*/
|
||||
|
@ -174,6 +175,9 @@ static void test_v21(enum MODEM_MODE direction)
|
|||
/* Read data from isdn4linux.
|
||||
*/
|
||||
IsdnReadAudio(isdnhandle,&data,1);
|
||||
/* Log data if requested.
|
||||
*/
|
||||
if (outfd!=-1) write(outfd,&data,1);
|
||||
|
||||
/* Send back a steady 0
|
||||
*/
|
||||
|
@ -223,6 +227,9 @@ static void test_v21(enum MODEM_MODE direction)
|
|||
/* Read data from isdn4linux.
|
||||
*/
|
||||
IsdnReadAudio(isdnhandle,&data,1);
|
||||
/* Log data if requested.
|
||||
*/
|
||||
if (outfd!=-1) write(outfd,&data,1);
|
||||
|
||||
/* Send it to the demodulator.
|
||||
*/
|
||||
|
@ -312,7 +319,10 @@ void answer_isdn(void)
|
|||
*/
|
||||
void usage(char *prgnam)
|
||||
{
|
||||
printf("Usage: %s [-i isdndevice] -m MSN\n",prgnam);
|
||||
printf("Usage: %s [-i isdndevice]\n"
|
||||
" -m MSN \n"
|
||||
" [-d number|'answer']\n"
|
||||
" [-l logfile]\n",prgnam);
|
||||
}
|
||||
|
||||
/* Main program. Get the arguments and set everything up.
|
||||
|
@ -331,6 +341,7 @@ void main(int argc,char **argv)
|
|||
char *isdndevname="/dev/ttyI1";
|
||||
char *numbertodial=NULL;
|
||||
char *sourcemsn=NULL;
|
||||
int outdata=-1;
|
||||
|
||||
/* Register all the modules.
|
||||
*/
|
||||
|
@ -338,7 +349,7 @@ void main(int argc,char **argv)
|
|||
|
||||
/* Get all options from the commandline.
|
||||
*/
|
||||
while(EOF!=(optchr=getopt(argc,argv,"i:m:d:")))
|
||||
while(EOF!=(optchr=getopt(argc,argv,"i:m:d:l:")))
|
||||
{
|
||||
switch(optchr)
|
||||
{
|
||||
|
@ -358,6 +369,11 @@ void main(int argc,char **argv)
|
|||
*/
|
||||
numbertodial=optarg;
|
||||
break;
|
||||
case 'l':
|
||||
/* The logfile name.
|
||||
*/
|
||||
outdata=open(optarg,O_WRONLY|O_CREAT|O_TRUNC,0644);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -394,7 +410,7 @@ void main(int argc,char **argv)
|
|||
answer_isdn();
|
||||
/* Go to transfer mode.
|
||||
*/
|
||||
test_v21(ANSWER);
|
||||
test_v21(ANSWER,outdata);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -403,11 +419,14 @@ void main(int argc,char **argv)
|
|||
dial_isdn(numbertodial);
|
||||
/* Go to transfer mode.
|
||||
*/
|
||||
test_v21(ORIGINATE);
|
||||
test_v21(ORIGINATE,outdata);
|
||||
}
|
||||
|
||||
|
||||
/* Clean up and exit.
|
||||
*/
|
||||
if (outdata!=-1) {
|
||||
close(outdata);
|
||||
}
|
||||
close(isdnhandle);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue