Initial checkin of ISDNfax.

This commit is contained in:
Andreas Beck 1998-11-29 22:56:33 +00:00
commit d2f8d601e4
38 changed files with 3865 additions and 0 deletions

29
COPYING Normal file
View File

@ -0,0 +1,29 @@
Licensing information for the isdnfax project.
Authors:
Copyright (C) 1998 Andreas Beck [becka@ggi-project.org]
Copyright (C) 1998 Morten Rolland [Morten.Rolland@asker.mail.telia.com]
Copyright (C) 1998 Oliver Eichler [oliver.eichler@regensburg.netsurf.de]
License:
(2 clause MIT style. Note, that this is compatible to (L)GPL and can be
re-/sublicensed to that)
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.

5
ChangeLog Normal file
View File

@ -0,0 +1,5 @@
Changelog:
----------
98-11-29 [becka]:
* initial release.

57
INSTALL Normal file
View File

@ -0,0 +1,57 @@
Welcome to isdnfax.
-------------------
1. Introduction:
----------------
Isdnfax is a project aimed at providing a fax transmission and reception
system via the audio capabilities of ISDN4Linux or other similar systems.
Note, that this is ALPHA software, not certified by anyone, and comes
without warranty of any kind, express or implied.
CAVEAT EMPTOR. This software _should_ transmit data between ISDN4Linux
and remote modems/faxes, _but_ it might as well set them on fire, take down
the public telephone network or whatever.
The developers are in no respect reliable for any damage arising from the
use or inability to use of this software.
See the file COPYING for details on licensing and warranty.
2. Building:
------------
2.1. Downloading and unpacking:
-------------------------------
You have already done that - else you wouldn't be reading this.
2.2. Configuring:
-----------------
No compiletime configuration is currently available. This may change.
Watch for updates.
2.3. Compiling:
---------------
Just type "make". Should do it all.
2.4. Running:
-------------
The following programs are currently available:
2.4.1. v21_softmodem:
---------------------
Emulate a V.21 (300 Baud) modem via the ISDN4Linux audio layer.
Usage: ./v21_softmodem -i /dev/ttyI[0-9] -m MY_MSN -c NUMBER_TO_CALL
The program is currently originate-only.
Have fun,
Andreas Beck
<becka@ggi-project.org>

20
Makefile Normal file
View File

@ -0,0 +1,20 @@
LDFLAGS=-lm
CFLAGS=-O2 -g -Wall -pedantic -Iinclude
SUBDIRS = lib modules
MODULES = modules/modules.a lib/isdnlib.a
PROGRAMS = v21_softmodem
all: subdirs $(PROGRAMS)
subdirs:
for a in $(SUBDIRS) ; do make -C $$a ; done
v21_softmodem: v21_softmodem.o $(OBJECTS) $(MODULES)
$(CC) -o $@ $^ $(LDFLAGS)
clean:
rm -f $(OBJECTS) $(MODULES) $(PROGRAMS) *~ *.o
for a in $(SUBDIRS) ; do make -C $$a clean; done

13
data/isdn-samples.alaw Normal file

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,8 @@
/* bitreverse.h
*
* Mirror the bits of an unsigned character so that b0 -> b7, b1 -> b6 etc.
*
* (C) 1998 Morten Rolland
*/
unsigned char bitrev(unsigned char v);

21
include/ifax/debug.h Normal file
View File

@ -0,0 +1,21 @@
/*
* Debugging messages for ISDNfax.
* (c) 1998 Andreas Beck <becka@ggi-project.org>
*/
enum debuglevel {
DEBUG_ALL,
DEBUG_JUNK,
DEBUG_DEBUG,
DEBUG_INFO,
DEBUG_NOTICE,
DEBUG_WARNING,
DEBUG_ERROR,
DEBUG_SEVERE,
DEBUG_FATAL,
DEBUG_LAST
};
int ifax_dprintf(enum debuglevel severity,char *format,...);
void ifax_debugsetlevel(enum debuglevel);

40
include/ifax/g711.h Normal file
View File

@ -0,0 +1,40 @@
/*
* This source code is a product of Sun Microsystems, Inc. and is provided
* for unrestricted use. Users may copy or modify this source code without
* charge.
*
* SUN SOURCE CODE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING
* THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
*
* Sun source code is provided with no support and without any obligation on
* the part of Sun Microsystems, Inc. to assist in its use, correction,
* modification or enhancement.
*
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS SOFTWARE
* OR ANY PART THEREOF.
*
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
* or profits or other special, indirect and consequential damages, even if
* Sun has been advised of the possibility of such damages.
*
* Sun Microsystems, Inc.
* 2550 Garcia Avenue
* Mountain View, California 94043
*/
/*
* g711.h
*
* u-law, A-law and linear PCM conversions.
*/
unsigned char linear2alaw(short pcm_val);
short alaw2linear(unsigned char a_val);
unsigned char linear2ulaw(short pcm_val);
short ulaw2linear(unsigned char u_val);
unsigned char alaw2ulaw(unsigned char aval);
unsigned char ulaw2alaw(unsigned char uval);

23
include/ifax/ifax.h Normal file
View File

@ -0,0 +1,23 @@
/*
* Main include file for ISDNfax.
* (c) 1998 Andreas Beck <becka@ggi-project.org>
*/
/*
* ISDN sample rate. We include that in case someone want to use it for
* a different purpose like faxing with a soundcard.
*/
#define SAMPLES_PER_SECOND 8000
/*
* Include all other files here
*/
#include <ifax/debug.h>
#include <ifax/module.h>
#include <ifax/bitreverse.h>
#include <ifax/sincos.h>
#include <ifax/int2alaw.h>
#include <ifax/isdn.h>
#include <ifax/g711.h>

7
include/ifax/int2alaw.h Normal file
View File

@ -0,0 +1,7 @@
/* $Id$
* Integer to aLaw conversion
* (c) 1998 Morten Rolland
*/
unsigned char int2alaw(int value);
int alaw2int(unsigned char value);

12
include/ifax/isdn.h Normal file
View File

@ -0,0 +1,12 @@
/* $Id$
* Isdn abstraction layer
* (c) 1998 Morten Rolland
*/
extern int IsdnCommand(int, char *,int,int);
extern void IsdnReadLine(int, char *, int);
extern int IsdnOpenDevice(char *);
extern void IsdnSendAudio(int, unsigned char *, int);
extern void IsdnReadAudio(int, unsigned char *, int);
extern char cmdresult[];
extern char isdnerr[];

88
include/ifax/module.h Normal file
View File

@ -0,0 +1,88 @@
/* $Id$
* ISDNfax module layer
* (c) 1998 Andreas Beck <becka@ggi-project.org>
*/
#include <stdlib.h>
#include <stdarg.h>
/*
* The ideas here were stolen from the EvStack concept, that was developed
* mainly be me and Jason McMullan for the GGI project
* (http://www.ggi-project.org).
*/
/* Every module instance creates such a control structure through which it
* is referenced.
*/
typedef struct ifax_module {
/* This function destroys this instance and frees all private data.
*/
void (*destroy)(struct ifax_module *self);
/* This function gets called from the previous modules in the chain
* to handle the data generated.
*/
int (*handle_input)(struct ifax_module *self, void *data, size_t len);
/* Use this to implement "commands" to modules like changing operating
* parameters "on-the-fly".
*/
int (*command)(struct ifax_module *self, int command, va_list args);
/* The usual place to store private data.
*/
void *private;
/* The usual place to send resulting data to.
* Some modules (like replicate.c) have their own ideas about that.
*/
struct ifax_module *sendto;
} ifax_module;
/* A module instance is identified by that handle type.
*/
typedef ifax_module *ifax_modp;
/* A module_id is used to reference a module class. It is used to create
* instances.
*/
typedef unsigned int ifax_module_id;
/* Internal registry of modules.
*/
typedef struct ifax_module_registry {
struct ifax_module_registry *next; /* linked list */
ifax_module_id id;
int (*construct)(struct ifax_module *self,va_list args);
char module_name[64];
} ifax_module_registry;
/* This return code signifies failure for ifax_register_module_class.
*/
#define IFAX_MODULE_ID_INVALID 0
/* Register a module for the system. You need to know the constructor call.
*/
ifax_module_id ifax_register_module_class(char *name,int (*construct)(struct ifax_module *self,va_list args));
/* Instantiate a module from its class.
*/
ifax_modp ifax_create_module(ifax_module_id what_kind,...);
/* Send input to a module. Note, that len is defined by the module.
*/
int ifax_handle_input(struct ifax_module *self,void *data,size_t len);
/* Send a command to a module. Semantics are defined by the module.
*/
int ifax_command(struct ifax_module *self, int command, ...);

View File

@ -0,0 +1,11 @@
/* $Id$
*
* Replicator module.
*
* (C) 1998 Andreas Beck <becka@ggi-project.org>
*/
#define CMD_REPLICATE_ADD 0x01000000
#define CMD_REPLICATE_DEL 0x01000001
int replicate_construct(ifax_modp self,va_list args);

View File

@ -0,0 +1,12 @@
/* scrambler17.h
*
* Scramble/descramble a bitstream using a polynomial of
*
* 1 + x-18 + x-23
*
* As defined by the V.17 modulation standard.
*
* (C) 1998 Morten Rolland
*/
extern void scramble17(unsigned char *, unsigned char *, unsigned int *, int);

10
include/ifax/sincos.h Normal file
View File

@ -0,0 +1,10 @@
/* sincos.c
*
* Simple sin/cos table-lookup functions to execute fast (not very
* accurate).
*
* (C) 1998 Morten Rolland
*/
extern int intsin(int);
extern int intcos(int);

12
lib/Makefile Normal file
View File

@ -0,0 +1,12 @@
LDFLAGS=-lm
CFLAGS=-O2 -g -Wall -pedantic -I../include
LIBOBJS = bitreverse.o debug.o int2alaw.o module.o sincos.o isdn.o g711.o
all: isdnlib.a
isdnlib.a: $(LIBOBJS)
$(AR) rcs $@ $^
clean:
rm -f $(LIBOBJS) *~

46
lib/bitreverse.c Normal file
View File

@ -0,0 +1,46 @@
/* bitreverse.c
*
* Mirror the bits of an unsigned character so that b0 -> b7, b1 -> b6 etc.
*
* (C) 1998 Morten Rolland
*/
static unsigned char bitreverse[256] = {
0x00,0x80,0x40,0xc0,0x20,0xa0,0x60,0xe0,
0x10,0x90,0x50,0xd0,0x30,0xb0,0x70,0xf0,
0x08,0x88,0x48,0xc8,0x28,0xa8,0x68,0xe8,
0x18,0x98,0x58,0xd8,0x38,0xb8,0x78,0xf8,
0x04,0x84,0x44,0xc4,0x24,0xa4,0x64,0xe4,
0x14,0x94,0x54,0xd4,0x34,0xb4,0x74,0xf4,
0x0c,0x8c,0x4c,0xcc,0x2c,0xac,0x6c,0xec,
0x1c,0x9c,0x5c,0xdc,0x3c,0xbc,0x7c,0xfc,
0x02,0x82,0x42,0xc2,0x22,0xa2,0x62,0xe2,
0x12,0x92,0x52,0xd2,0x32,0xb2,0x72,0xf2,
0x0a,0x8a,0x4a,0xca,0x2a,0xaa,0x6a,0xea,
0x1a,0x9a,0x5a,0xda,0x3a,0xba,0x7a,0xfa,
0x06,0x86,0x46,0xc6,0x26,0xa6,0x66,0xe6,
0x16,0x96,0x56,0xd6,0x36,0xb6,0x76,0xf6,
0x0e,0x8e,0x4e,0xce,0x2e,0xae,0x6e,0xee,
0x1e,0x9e,0x5e,0xde,0x3e,0xbe,0x7e,0xfe,
0x01,0x81,0x41,0xc1,0x21,0xa1,0x61,0xe1,
0x11,0x91,0x51,0xd1,0x31,0xb1,0x71,0xf1,
0x09,0x89,0x49,0xc9,0x29,0xa9,0x69,0xe9,
0x19,0x99,0x59,0xd9,0x39,0xb9,0x79,0xf9,
0x05,0x85,0x45,0xc5,0x25,0xa5,0x65,0xe5,
0x15,0x95,0x55,0xd5,0x35,0xb5,0x75,0xf5,
0x0d,0x8d,0x4d,0xcd,0x2d,0xad,0x6d,0xed,
0x1d,0x9d,0x5d,0xdd,0x3d,0xbd,0x7d,0xfd,
0x03,0x83,0x43,0xc3,0x23,0xa3,0x63,0xe3,
0x13,0x93,0x53,0xd3,0x33,0xb3,0x73,0xf3,
0x0b,0x8b,0x4b,0xcb,0x2b,0xab,0x6b,0xeb,
0x1b,0x9b,0x5b,0xdb,0x3b,0xbb,0x7b,0xfb,
0x07,0x87,0x47,0xc7,0x27,0xa7,0x67,0xe7,
0x17,0x97,0x57,0xd7,0x37,0xb7,0x77,0xf7,
0x0f,0x8f,0x4f,0xcf,0x2f,0xaf,0x6f,0xef,
0x1f,0x9f,0x5f,0xdf,0x3f,0xbf,0x7f,0xff
};
unsigned char bitrev(unsigned char v)
{
return bitreverse[v];
}

59
lib/debug.c Normal file
View File

@ -0,0 +1,59 @@
/* $Id$
******************************************************************************
Fax program for ISDN.
Debug functions.
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 <stdarg.h>
#include <stdio.h>
#include <ifax/debug.h>
/* All debugging info of a severity of that or higher are printed to stderr.
*/
static enum debuglevel debuglevel=DEBUG_ALL;
/* Print debugging info.
*/
int ifax_dprintf(enum debuglevel severity,char *format,...)
{
int rc=0;
va_list list;
if (severity>debuglevel)
{
va_start(list,format);
rc=vprintf(format,list);
va_end(list);
}
return rc;
}
/* Set the debugging level.
*/
void ifax_debugsetlevel(enum debuglevel severity)
{
debuglevel=severity;
}

311
lib/g711.c Normal file
View File

@ -0,0 +1,311 @@
/*
* This source code is a product of Sun Microsystems, Inc. and is provided
* for unrestricted use. Users may copy or modify this source code without
* charge.
*
* SUN SOURCE CODE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING
* THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
*
* Sun source code is provided with no support and without any obligation on
* the part of Sun Microsystems, Inc. to assist in its use, correction,
* modification or enhancement.
*
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS SOFTWARE
* OR ANY PART THEREOF.
*
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
* or profits or other special, indirect and consequential damages, even if
* Sun has been advised of the possibility of such damages.
*
* Sun Microsystems, Inc.
* 2550 Garcia Avenue
* Mountain View, California 94043
*/
/*
* g711.c
*
* u-law, A-law and linear PCM conversions.
*/
/*
* December 30, 1994:
* Functions linear2alaw, linear2ulaw have been updated to correctly
* convert unquantized 16 bit values.
* Tables for direct u- to A-law and A- to u-law conversions have been
* corrected.
* Borge Lindberg, Center for PersonKommunikation, Aalborg University.
* bli@cpk.auc.dk
*
*/
#include <ifax/g711.h>
#define SIGN_BIT (0x80) /* Sign bit for a A-law byte. */
#define QUANT_MASK (0xf) /* Quantization field mask. */
#define NSEGS (8) /* Number of A-law segments. */
#define SEG_SHIFT (4) /* Left shift for segment number. */
#define SEG_MASK (0x70) /* Segment field mask. */
static short seg_aend[8] = {0x1F, 0x3F, 0x7F, 0xFF,
0x1FF, 0x3FF, 0x7FF, 0xFFF};
static short seg_uend[8] = {0x3F, 0x7F, 0xFF, 0x1FF,
0x3FF, 0x7FF, 0xFFF, 0x1FFF};
/* copy from CCITT G.711 specifications */
unsigned char _u2a[128] = { /* u- to A-law conversions */
1, 1, 2, 2, 3, 3, 4, 4,
5, 5, 6, 6, 7, 7, 8, 8,
9, 10, 11, 12, 13, 14, 15, 16,
17, 18, 19, 20, 21, 22, 23, 24,
25, 27, 29, 31, 33, 34, 35, 36,
37, 38, 39, 40, 41, 42, 43, 44,
46, 48, 49, 50, 51, 52, 53, 54,
55, 56, 57, 58, 59, 60, 61, 62,
64, 65, 66, 67, 68, 69, 70, 71,
72, 73, 74, 75, 76, 77, 78, 79,
/* corrected:
81, 82, 83, 84, 85, 86, 87, 88,
should be: */
80, 82, 83, 84, 85, 86, 87, 88,
89, 90, 91, 92, 93, 94, 95, 96,
97, 98, 99, 100, 101, 102, 103, 104,
105, 106, 107, 108, 109, 110, 111, 112,
113, 114, 115, 116, 117, 118, 119, 120,
121, 122, 123, 124, 125, 126, 127, 128};
unsigned char _a2u[128] = { /* A- to u-law conversions */
1, 3, 5, 7, 9, 11, 13, 15,
16, 17, 18, 19, 20, 21, 22, 23,
24, 25, 26, 27, 28, 29, 30, 31,
32, 32, 33, 33, 34, 34, 35, 35,
36, 37, 38, 39, 40, 41, 42, 43,
44, 45, 46, 47, 48, 48, 49, 49,
50, 51, 52, 53, 54, 55, 56, 57,
58, 59, 60, 61, 62, 63, 64, 64,
65, 66, 67, 68, 69, 70, 71, 72,
/* corrected:
73, 74, 75, 76, 77, 78, 79, 79,
should be: */
73, 74, 75, 76, 77, 78, 79, 80,
80, 81, 82, 83, 84, 85, 86, 87,
88, 89, 90, 91, 92, 93, 94, 95,
96, 97, 98, 99, 100, 101, 102, 103,
104, 105, 106, 107, 108, 109, 110, 111,
112, 113, 114, 115, 116, 117, 118, 119,
120, 121, 122, 123, 124, 125, 126, 127};
static short
search(
short val,
short *table,
short size)
{
short i;
for (i = 0; i < size; i++) {
if (val <= *table++)
return (i);
}
return (size);
}
/*
* linear2alaw() - Convert a 16-bit linear PCM value to 8-bit A-law
*
* linear2alaw() accepts an 16-bit integer and encodes it as A-law data.
*
* Linear Input Code Compressed Code
* ------------------------ ---------------
* 0000000wxyza 000wxyz
* 0000001wxyza 001wxyz
* 000001wxyzab 010wxyz
* 00001wxyzabc 011wxyz
* 0001wxyzabcd 100wxyz
* 001wxyzabcde 101wxyz
* 01wxyzabcdef 110wxyz
* 1wxyzabcdefg 111wxyz
*
* For further information see John C. Bellamy's Digital Telephony, 1982,
* John Wiley & Sons, pps 98-111 and 472-476.
*/
unsigned char
linear2alaw(
short pcm_val) /* 2's complement (16-bit range) */
{
short mask;
short seg;
unsigned char aval;
pcm_val = pcm_val >> 3;
if (pcm_val >= 0) {
mask = 0xD5; /* sign (7th) bit = 1 */
} else {
mask = 0x55; /* sign bit = 0 */
pcm_val = -pcm_val - 1;
}
/* Convert the scaled magnitude to segment number. */
seg = search(pcm_val, seg_aend, 8);
/* Combine the sign, segment, and quantization bits. */
if (seg >= 8) /* out of range, return maximum value. */
return (unsigned char) (0x7F ^ mask);
else {
aval = (unsigned char) seg << SEG_SHIFT;
if (seg < 2)
aval |= (pcm_val >> 1) & QUANT_MASK;
else
aval |= (pcm_val >> seg) & QUANT_MASK;
return (aval ^ mask);
}
}
/*
* alaw2linear() - Convert an A-law value to 16-bit linear PCM
*
*/
short
alaw2linear(
unsigned char a_val)
{
short t;
short seg;
a_val ^= 0x55;
t = (a_val & QUANT_MASK) << 4;
seg = ((unsigned)a_val & SEG_MASK) >> SEG_SHIFT;
switch (seg) {
case 0:
t += 8;
break;
case 1:
t += 0x108;
break;
default:
t += 0x108;
t <<= seg - 1;
}
return ((a_val & SIGN_BIT) ? t : -t);
}
#define BIAS (0x84) /* Bias for linear code. */
#define CLIP 8159
/*
* linear2ulaw() - Convert a linear PCM value to u-law
*
* In order to simplify the encoding process, the original linear magnitude
* is biased by adding 33 which shifts the encoding range from (0 - 8158) to
* (33 - 8191). The result can be seen in the following encoding table:
*
* Biased Linear Input Code Compressed Code
* ------------------------ ---------------
* 00000001wxyza 000wxyz
* 0000001wxyzab 001wxyz
* 000001wxyzabc 010wxyz
* 00001wxyzabcd 011wxyz
* 0001wxyzabcde 100wxyz
* 001wxyzabcdef 101wxyz
* 01wxyzabcdefg 110wxyz
* 1wxyzabcdefgh 111wxyz
*
* Each biased linear code has a leading 1 which identifies the segment
* number. The value of the segment number is equal to 7 minus the number
* of leading 0's. The quantization interval is directly available as the
* four bits wxyz. * The trailing bits (a - h) are ignored.
*
* Ordinarily the complement of the resulting code word is used for
* transmission, and so the code word is complemented before it is returned.
*
* For further information see John C. Bellamy's Digital Telephony, 1982,
* John Wiley & Sons, pps 98-111 and 472-476.
*/
unsigned char
linear2ulaw(
short pcm_val) /* 2's complement (16-bit range) */
{
short mask;
short seg;
unsigned char uval;
/* Get the sign and the magnitude of the value. */
pcm_val = pcm_val >> 2;
if (pcm_val < 0) {
pcm_val = -pcm_val;
mask = 0x7F;
} else {
mask = 0xFF;
}
if ( pcm_val > CLIP ) pcm_val = CLIP; /* clip the magnitude */
pcm_val += (BIAS >> 2);
/* Convert the scaled magnitude to segment number. */
seg = search(pcm_val, seg_uend, 8);
/*
* Combine the sign, segment, quantization bits;
* and complement the code word.
*/
if (seg >= 8) /* out of range, return maximum value. */
return (unsigned char) (0x7F ^ mask);
else {
uval = (unsigned char) (seg << 4) | ((pcm_val >> (seg + 1)) & 0xF);
return (uval ^ mask);
}
}
/*
* ulaw2linear() - Convert a u-law value to 16-bit linear PCM
*
* First, a biased linear code is derived from the code word. An unbiased
* output can then be obtained by subtracting 33 from the biased code.
*
* Note that this function expects to be passed the complement of the
* original code word. This is in keeping with ISDN conventions.
*/
short
ulaw2linear(
unsigned char u_val)
{
short t;
/* Complement to obtain normal u-law value. */
u_val = ~u_val;
/*
* Extract and bias the quantization bits. Then
* shift up by the segment number and subtract out the bias.
*/
t = ((u_val & QUANT_MASK) << 3) + BIAS;
t <<= ((unsigned)u_val & SEG_MASK) >> SEG_SHIFT;
return ((u_val & SIGN_BIT) ? (BIAS - t) : (t - BIAS));
}
/* A-law to u-law conversion */
unsigned char
alaw2ulaw(
unsigned char aval)
{
aval &= 0xff;
return (unsigned char) ((aval & 0x80) ? (0xFF ^ _a2u[aval ^ 0xD5]) :
(0x7F ^ _a2u[aval ^ 0x55]));
}
/* u-law to A-law conversion */
unsigned char
ulaw2alaw(
unsigned char uval)
{
uval &= 0xff;
return (unsigned char) ((uval & 0x80) ? (0xD5 ^ (_u2a[0xFF ^ uval] - 1)) :
(unsigned char) (0x55 ^ (_u2a[0x7F ^ uval] - 1)));
}

253
lib/int2alaw.c Normal file
View File

@ -0,0 +1,253 @@
/* $Id$
******************************************************************************
Fax program for ISDN.
Integer to aLaw conversion.
Copyright (C) 1998 Morten Rolland [Morten.Rolland@asker.mail.telia.com]
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.
******************************************************************************
*/
/* int2alaw.c
*
* Convert an integer value to alaw-encoding as used in Europe for voice
* over ISDN. The input value is in the range:
*
* -2147483648 to 2147483647
*
* This is equal to a full-blown 32 bit signed integer (two's complement).
* Most modern computer equipment should be able to handle this.
* The reason why the full range is used, is to make it possible to
* multiply/accumulate with integers in the application, and make the
* final (and maybe the only) scaling when converting to alaw.
*
* Documentation on this linear to a-law transformation:
*
* Figure out and remember the sign bit of the value to be converted,
* and take the absolute value such that the value -1 becomes 0 to
* index the tables correctly (and -2 becomes 1 etc.).
* If we didn't do this, The number -2147483648 would negate to itself
* and spoil the indexing.
*
* The resulting value is positive (or zero), and is split into two
* ranges, or segments; like this (32 bit binary):
*
* 00000000 00000000 00000000 00000000 (segment 0)
* to 00001111 11111111 11111111 11111111
*
* 00010000 00000000 00000000 00000000 (segment 1)
* to 01111111 11111111 11111111 11111111
*
* These two ranges index into each of four tables (two ranges, two signs).
* The index into the tables are found by using the proper bits from
* the (positive) value:
*
* 0000xxxx xxxx???? ???????? ???????? (segment 0)
* 0xxxxxxx ???????? ???????? ???????? (segment 1)
*
* The 'x' indicate the bits used to index, while '?' is don't care.
*/
static unsigned char pos0[256] = {
0xd5,0xd4,0xd7,0xd6,0xd1,0xd0,0xd3,0xd2,
0xdd,0xdc,0xdf,0xde,0xd9,0xd8,0xdb,0xda,
0xc5,0xc4,0xc7,0xc6,0xc1,0xc0,0xc3,0xc2,
0xcd,0xcc,0xcf,0xce,0xc9,0xc8,0xcb,0xca,
0xf5,0xf5,0xf4,0xf4,0xf7,0xf7,0xf6,0xf6,
0xf1,0xf1,0xf0,0xf0,0xf3,0xf3,0xf2,0xf2,
0xfd,0xfd,0xfc,0xfc,0xff,0xff,0xfe,0xfe,
0xf9,0xf9,0xf8,0xf8,0xfb,0xfb,0xfa,0xfa,
0xe5,0xe5,0xe5,0xe5,0xe4,0xe4,0xe4,0xe4,
0xe7,0xe7,0xe7,0xe7,0xe6,0xe6,0xe6,0xe6,
0xe1,0xe1,0xe1,0xe1,0xe0,0xe0,0xe0,0xe0,
0xe3,0xe3,0xe3,0xe3,0xe2,0xe2,0xe2,0xe2,
0xed,0xed,0xed,0xed,0xec,0xec,0xec,0xec,
0xef,0xef,0xef,0xef,0xee,0xee,0xee,0xee,
0xe9,0xe9,0xe9,0xe9,0xe8,0xe8,0xe8,0xe8,
0xeb,0xeb,0xeb,0xeb,0xea,0xea,0xea,0xea,
0x95,0x95,0x95,0x95,0x95,0x95,0x95,0x95,
0x94,0x94,0x94,0x94,0x94,0x94,0x94,0x94,
0x97,0x97,0x97,0x97,0x97,0x97,0x97,0x97,
0x96,0x96,0x96,0x96,0x96,0x96,0x96,0x96,
0x91,0x91,0x91,0x91,0x91,0x91,0x91,0x91,
0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,
0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,
0x92,0x92,0x92,0x92,0x92,0x92,0x92,0x92,
0x9d,0x9d,0x9d,0x9d,0x9d,0x9d,0x9d,0x9d,
0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,
0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,
0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,
0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,
0x98,0x98,0x98,0x98,0x98,0x98,0x98,0x98,
0x9b,0x9b,0x9b,0x9b,0x9b,0x9b,0x9b,0x9b,
0x9a,0x9a,0x9a,0x9a,0x9a,0x9a,0x9a,0x9a
};
static unsigned char pos1[128] = {
0xd5,0xc5,0xf5,0xfd,0xe5,0xe1,0xed,0xe9,
0x95,0x97,0x91,0x93,0x9d,0x9f,0x99,0x9b,
0x85,0x84,0x87,0x86,0x81,0x80,0x83,0x82,
0x8d,0x8c,0x8f,0x8e,0x89,0x88,0x8b,0x8a,
0xb5,0xb5,0xb4,0xb4,0xb7,0xb7,0xb6,0xb6,
0xb1,0xb1,0xb0,0xb0,0xb3,0xb3,0xb2,0xb2,
0xbd,0xbd,0xbc,0xbc,0xbf,0xbf,0xbe,0xbe,
0xb9,0xb9,0xb8,0xb8,0xbb,0xbb,0xba,0xba,
0xa5,0xa5,0xa5,0xa5,0xa4,0xa4,0xa4,0xa4,
0xa7,0xa7,0xa7,0xa7,0xa6,0xa6,0xa6,0xa6,
0xa1,0xa1,0xa1,0xa1,0xa0,0xa0,0xa0,0xa0,
0xa3,0xa3,0xa3,0xa3,0xa2,0xa2,0xa2,0xa2,
0xad,0xad,0xad,0xad,0xac,0xac,0xac,0xac,
0xaf,0xaf,0xaf,0xaf,0xae,0xae,0xae,0xae,
0xa9,0xa9,0xa9,0xa9,0xa8,0xa8,0xa8,0xa8,
0xab,0xab,0xab,0xab,0xaa,0xaa,0xaa,0xaa
};
static unsigned char neg0[256] = {
0x55,0x54,0x57,0x56,0x51,0x50,0x53,0x52,
0x5d,0x5c,0x5f,0x5e,0x59,0x58,0x5b,0x5a,
0x45,0x44,0x47,0x46,0x41,0x40,0x43,0x42,
0x4d,0x4c,0x4f,0x4e,0x49,0x48,0x4b,0x4a,
0x75,0x75,0x74,0x74,0x77,0x77,0x76,0x76,
0x71,0x71,0x70,0x70,0x73,0x73,0x72,0x72,
0x7d,0x7d,0x7c,0x7c,0x7f,0x7f,0x7e,0x7e,
0x79,0x79,0x78,0x78,0x7b,0x7b,0x7a,0x7a,
0x65,0x65,0x65,0x65,0x64,0x64,0x64,0x64,
0x67,0x67,0x67,0x67,0x66,0x66,0x66,0x66,
0x61,0x61,0x61,0x61,0x60,0x60,0x60,0x60,
0x63,0x63,0x63,0x63,0x62,0x62,0x62,0x62,
0x6d,0x6d,0x6d,0x6d,0x6c,0x6c,0x6c,0x6c,
0x6f,0x6f,0x6f,0x6f,0x6e,0x6e,0x6e,0x6e,
0x69,0x69,0x69,0x69,0x68,0x68,0x68,0x68,
0x6b,0x6b,0x6b,0x6b,0x6a,0x6a,0x6a,0x6a,
0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,
0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,
0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,
0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,
0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,
0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,
0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,
0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,
0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,
0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,
0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,
0x19,0x19,0x19,0x19,0x19,0x19,0x19,0x19,
0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a
};
static unsigned char neg1[128] = {
0x55,0x45,0x75,0x7d,0x65,0x61,0x6d,0x69,
0x15,0x17,0x11,0x13,0x1d,0x1f,0x19,0x1b,
0x05,0x04,0x07,0x06,0x01,0x00,0x03,0x02,
0x0d,0x0c,0x0f,0x0e,0x09,0x08,0x0b,0x0a,
0x35,0x35,0x34,0x34,0x37,0x37,0x36,0x36,
0x31,0x31,0x30,0x30,0x33,0x33,0x32,0x32,
0x3d,0x3d,0x3c,0x3c,0x3f,0x3f,0x3e,0x3e,
0x39,0x39,0x38,0x38,0x3b,0x3b,0x3a,0x3a,
0x25,0x25,0x25,0x25,0x24,0x24,0x24,0x24,
0x27,0x27,0x27,0x27,0x26,0x26,0x26,0x26,
0x21,0x21,0x21,0x21,0x20,0x20,0x20,0x20,
0x23,0x23,0x23,0x23,0x22,0x22,0x22,0x22,
0x2d,0x2d,0x2d,0x2d,0x2c,0x2c,0x2c,0x2c,
0x2f,0x2f,0x2f,0x2f,0x2e,0x2e,0x2e,0x2e,
0x29,0x29,0x29,0x29,0x28,0x28,0x28,0x28,
0x2b,0x2b,0x2b,0x2b,0x2a,0x2a,0x2a,0x2a
};
unsigned char int2alaw(int value)
{
unsigned int idx;
if ( value >= 0 ) {
idx = value;
if ( idx < 0x10000000 ) {
idx >>= 20;
return pos0[idx];
} else {
idx >>= 24;
return pos1[idx];
}
} else {
idx = -(value+1);
if ( idx < 0x10000000 ) {
idx >>= 20;
return neg0[idx];
} else {
idx >>= 24;
return neg1[idx];
}
}
}
static unsigned short alaw2short[256] = {
0xea80,0xeb80,0xe880,0xe980,0xee80,0xef80,0xec80,0xed80,
0xe280,0xe380,0xe080,0xe180,0xe680,0xe780,0xe480,0xe580,
0xf540,0xf5c0,0xf440,0xf4c0,0xf740,0xf7c0,0xf640,0xf6c0,
0xf140,0xf1c0,0xf040,0xf0c0,0xf340,0xf3c0,0xf240,0xf2c0,
0xaa00,0xae00,0xa200,0xa600,0xba00,0xbe00,0xb200,0xb600,
0x8a00,0x8e00,0x8200,0x8600,0x9a00,0x9e00,0x9200,0x9600,
0xd500,0xd700,0xd100,0xd300,0xdd00,0xdf00,0xd900,0xdb00,
0xc500,0xc700,0xc100,0xc300,0xcd00,0xcf00,0xc900,0xcb00,
0xfea8,0xfeb8,0xfe88,0xfe98,0xfee8,0xfef8,0xfec8,0xfed8,
0xfe28,0xfe38,0xfe08,0xfe18,0xfe68,0xfe78,0xfe48,0xfe58,
0xffa8,0xffb8,0xff88,0xff98,0xffe8,0xfff8,0xffc8,0xffd8,
0xff28,0xff38,0xff08,0xff18,0xff68,0xff78,0xff48,0xff58,
0xfaa0,0xfae0,0xfa20,0xfa60,0xfba0,0xfbe0,0xfb20,0xfb60,
0xf8a0,0xf8e0,0xf820,0xf860,0xf9a0,0xf9e0,0xf920,0xf960,
0xfd50,0xfd70,0xfd10,0xfd30,0xfdd0,0xfdf0,0xfd90,0xfdb0,
0xfc50,0xfc70,0xfc10,0xfc30,0xfcd0,0xfcf0,0xfc90,0xfcb0,
0x1580,0x1480,0x1780,0x1680,0x1180,0x1080,0x1380,0x1280,
0x1d80,0x1c80,0x1f80,0x1e80,0x1980,0x1880,0x1b80,0x1a80,
0x0ac0,0x0a40,0x0bc0,0x0b40,0x08c0,0x0840,0x09c0,0x0940,
0x0ec0,0x0e40,0x0fc0,0x0f40,0x0cc0,0x0c40,0x0dc0,0x0d40,
0x5600,0x5200,0x5e00,0x5a00,0x4600,0x4200,0x4e00,0x4a00,
0x7600,0x7200,0x7e00,0x7a00,0x6600,0x6200,0x6e00,0x6a00,
0x2b00,0x2900,0x2f00,0x2d00,0x2300,0x2100,0x2700,0x2500,
0x3b00,0x3900,0x3f00,0x3d00,0x3300,0x3100,0x3700,0x3500,
0x0158,0x0148,0x0178,0x0168,0x0118,0x0108,0x0138,0x0128,
0x01d8,0x01c8,0x01f8,0x01e8,0x0198,0x0188,0x01b8,0x01a8,
0x0058,0x0048,0x0078,0x0068,0x0018,0x0008,0x0038,0x0028,
0x00d8,0x00c8,0x00f8,0x00e8,0x0098,0x0088,0x00b8,0x00a8,
0x0560,0x0520,0x05e0,0x05a0,0x0460,0x0420,0x04e0,0x04a0,
0x0760,0x0720,0x07e0,0x07a0,0x0660,0x0620,0x06e0,0x06a0,
0x02b0,0x0290,0x02f0,0x02d0,0x0230,0x0210,0x0270,0x0250,
0x03b0,0x0390,0x03f0,0x03d0,0x0330,0x0310,0x0370,0x0350
};
int alaw2int(unsigned char value)
{
unsigned int u;
int p;
u = alaw2short[value];
u <<= 16;
p = u;
return p;
}

207
lib/isdn.c Normal file
View File

@ -0,0 +1,207 @@
/* isdn.c
*
* Implement all functions needed to talk to the ISDN-card and send and
* receive audio.
*/
#include <stdio.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <ifax/ifax.h>
#define CMDRESULTSIZE 128
#define CMDMAXSIZE 128
char isdnerr[128];
static char cmdresult[CMDRESULTSIZE+2];
/* Open the Isdn-device and prepare for audio-transmission */
int IsdnOpenDevice(char *device)
{
int isdnfd;
struct termios isdnsetting;
if ( (isdnfd=open(device,O_RDWR)) < 0 ) {
sprintf(isdnerr,"Unable to open '%s'",device);
return -1;
}
#if 0
/* What is this? Is it needed? */
if ( fcntl(isdnfd, F_SETFL, O_RDWR) < 0 ) {
sprintf(isdnerr,"...");
close(isdnfd);
return -1;
}
#endif
if ( tcgetattr(isdnfd,&isdnsetting) < 0 ) {
sprintf(isdnerr,"Unable to read terminal settings for '%s'",device);
close(isdnfd);
return -1;
}
isdnsetting.c_iflag = 0;
isdnsetting.c_oflag = 0;
isdnsetting.c_lflag = 0;
isdnsetting.c_cflag &= ~(CSIZE | CSTOPB | PARENB | PARODD | CLOCAL);
isdnsetting.c_cflag |= (CS8 | CREAD | HUPCL | CLOCAL | CRTSCTS);
if ( tcsetattr(isdnfd, TCSANOW, &isdnsetting) < 0 ) {
sprintf(isdnerr,"Unable to set terminal settings for '%s'",device);
close(isdnfd);
return -1;
}
return isdnfd;
}
void IsdnPrintChar(char *what, char c)
{
char tmp[32];
if ( c < 0x20 || c > 0x7e ) {
sprintf(tmp,"%02x",(int)c);
} else {
tmp[0] = c;
tmp[1] = 0;
}
if ( c == '\r' ) strcpy(tmp,"'\\r'");
if ( c == '\n' ) strcpy(tmp,"'\\n'");
fprintf(stderr,"<%s: %s>\n",what,tmp);
}
void IsdnReadLine(int isdnfd, char *buf,int size)
{
int t, r, skip, skipcrlf;
skipcrlf = 1;
fprintf(stderr,"---------------------------------------------\n");
for ( t=0; t < size; t++ ) {
r = read(isdnfd,&buf[t],1);
if ( r != 1 ) {
fprintf(stderr,"Read audio-data errno: %d\n",errno);
sprintf(isdnerr,"Can't read device one byte at a time");
buf[t] = 0;
return;
}
/* IsdnPrintChar("Read",buf[t]); */
if ( (buf[t] == '\n' || buf[t] == '\r') && skipcrlf ) {
skip = 1;
skipcrlf = 0;
}
if ( buf[t] != '\n' && buf[t] != '\r' ) {
skipcrlf = 0;
skip = 0;
}
if ( skip ) {
t--;
} else if ( buf[t] == '\r' ) {
buf[t] = 0;
return;
}
}
buf[t+1] = 0;
}
int IsdnCommand(int isdnfd, char *cmd, int checho, int result)
{
char localcmd[CMDMAXSIZE+4];
int cmdlen;
strcpy(localcmd,cmd);
cmdlen = strlen(localcmd);
if ( cmdlen > 0 && localcmd[cmdlen-1] != '\r' ) {
strcat(localcmd,"\r");
cmdlen = strlen(localcmd);
}
if ( cmdlen == 0 ) {
return 0;
}
if ( write(isdnfd,localcmd,cmdlen) != cmdlen ) {
sprintf(isdnerr,"Unable to write command to device");
return 0;
}
if ( checho ) {
IsdnReadLine(isdnfd, cmdresult,CMDRESULTSIZE);
localcmd[cmdlen-1] = 0;
if ( strcmp(cmdresult,localcmd) ) {
sprintf(isdnerr,"Command '%s' echoed back as '%s'",localcmd,cmdresult);
return 0;
}
}
if ( result ) {
IsdnReadLine(isdnfd, cmdresult,CMDRESULTSIZE);
fprintf(stderr,"Command '%s' resulted in '%s'\n",localcmd,cmdresult);
}
return 1;
}
/* ISDN4Linux has the uncommon behaviour of expecting _bitreversed_ aLaw.
* We compensate for that.
*/
void IsdnSendAudio(int isdnfd, unsigned char *data, int size)
{
int t;
unsigned char dathelp;
for ( t=0; t < size; t++ )
{
dathelp=bitrev(data[t]);
if ( dathelp == 0x10 )
{
write(isdnfd,&dathelp,1);
}
write(isdnfd,&dathelp,1);
}
}
/* ISDN4Linux has the uncommon behaviour of expecting _bitreversed_ aLaw.
* We compensate for that.
*/
void IsdnReadAudio(int isdnfd, unsigned char *data, int size)
{
int t;
for ( t=0; t < size; t++ )
{
data[t] = '@';
if ( read(isdnfd,&data[t],1) != 1 )
{
fprintf(stderr,"Oops: %d\n",errno);
}
if ( data[t] == 0x10 )
{
read(isdnfd,&data[t],1);
if ( data[t] != 0x10 )
{
fprintf(stderr,"<%02x>\n",data[t]);
}
}
data[t]=bitrev(data[t]);
}
}

117
lib/module.c Normal file
View File

@ -0,0 +1,117 @@
/* $Id$
******************************************************************************
Fax program for ISDN.
Module functionality.
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 <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <ifax/ifax.h>
static ifax_module_registry *ifax_modreg_root=NULL;
static ifax_module_id ifax_module_lastid=1;
/* Register a module class. Returns a module_id (handle) for the newly
* registered class on success.
*/
ifax_module_id ifax_register_module_class(char *name,int (*construct)(struct ifax_module *self,va_list args))
{
ifax_module_registry *newentry;
if (NULL==(newentry=malloc(sizeof(ifax_module_registry))))
return IFAX_MODULE_ID_INVALID; /* No memory any more. */
newentry->next=ifax_modreg_root;
newentry->id =ifax_module_lastid++;
newentry->construct=construct;
strcpy(newentry->module_name,name);
ifax_modreg_root=newentry;
return newentry->id;
}
/* Instantiate a module of the class what_kind. Returns a modp (handle) for
* the newly created module on success.
*/
ifax_modp ifax_create_module(ifax_module_id what_kind,...)
{
ifax_module_registry *current;
ifax_modp newmodule;
va_list list;
current=ifax_modreg_root;
while(current)
{
if (current->id==what_kind) {
if (NULL==current->construct) {
ifax_dprintf(DEBUG_SEVERE,"No constructor for module %s",
current->module_name);
break;
}
if (NULL==(newmodule=malloc(sizeof(ifax_module))))
break;
memset(newmodule,0,sizeof(ifax_module));
newmodule->sendto=NULL;
va_start(list,what_kind);
if (current->construct(newmodule,list)) {
va_end(list);
free(newmodule);
break;
}
va_end(list);
return newmodule;
}
current=current->next;
}
return NULL;
}
/* Send input to a module. Note, that len is defined by the module.
*/
int ifax_handle_input(struct ifax_module *self,void *data,size_t len)
{
return self->handle_input(self, data,len);
}
/* Send a command to a module. Note, that commands and data are defined
* by the module.
*/
int ifax_command(struct ifax_module *self, int command, ...)
{
va_list list;
int rc;
va_start(list,command);
rc=self->command(self, command, list);
va_end(list);
return rc;
}

543
lib/sincos.c Normal file
View File

@ -0,0 +1,543 @@
/* sincos.c
*
* Compute sines/cosines by reading values right out of a table. This
* is not a very good solution, but it is speedy and sufficiently accurate
* for telephone quality signals.
*
* The phase is measured in units of (2*PI/65536), which means a full
* sinus period goes from 0 to 0xFFFF, starting all over at 0x10000.
*/
static unsigned short sintbl[4096] = {
0x0000,0x0032,0x0065,0x0097,0x00c9,0x00fb,0x012e,0x0160,
0x0192,0x01c4,0x01f7,0x0229,0x025b,0x028d,0x02c0,0x02f2,
0x0324,0x0356,0x0389,0x03bb,0x03ed,0x041f,0x0452,0x0484,
0x04b6,0x04e8,0x051b,0x054d,0x057f,0x05b1,0x05e3,0x0616,
0x0648,0x067a,0x06ac,0x06de,0x0711,0x0743,0x0775,0x07a7,
0x07d9,0x080b,0x083e,0x0870,0x08a2,0x08d4,0x0906,0x0938,
0x096a,0x099d,0x09cf,0x0a01,0x0a33,0x0a65,0x0a97,0x0ac9,
0x0afb,0x0b2d,0x0b5f,0x0b92,0x0bc4,0x0bf6,0x0c28,0x0c5a,
0x0c8c,0x0cbe,0x0cf0,0x0d22,0x0d54,0x0d86,0x0db8,0x0dea,
0x0e1c,0x0e4e,0x0e80,0x0eb1,0x0ee3,0x0f15,0x0f47,0x0f79,
0x0fab,0x0fdd,0x100f,0x1041,0x1072,0x10a4,0x10d6,0x1108,
0x113a,0x116c,0x119d,0x11cf,0x1201,0x1233,0x1264,0x1296,
0x12c8,0x12fa,0x132b,0x135d,0x138f,0x13c0,0x13f2,0x1424,
0x1455,0x1487,0x14b9,0x14ea,0x151c,0x154d,0x157f,0x15b0,
0x15e2,0x1613,0x1645,0x1676,0x16a8,0x16d9,0x170b,0x173c,
0x176e,0x179f,0x17d0,0x1802,0x1833,0x1865,0x1896,0x18c7,
0x18f9,0x192a,0x195b,0x198c,0x19be,0x19ef,0x1a20,0x1a51,
0x1a82,0x1ab4,0x1ae5,0x1b16,0x1b47,0x1b78,0x1ba9,0x1bda,
0x1c0b,0x1c3c,0x1c6d,0x1c9e,0x1ccf,0x1d00,0x1d31,0x1d62,
0x1d93,0x1dc4,0x1df5,0x1e26,0x1e57,0x1e87,0x1eb8,0x1ee9,
0x1f1a,0x1f4a,0x1f7b,0x1fac,0x1fdd,0x200d,0x203e,0x206f,
0x209f,0x20d0,0x2100,0x2131,0x2161,0x2192,0x21c2,0x21f3,
0x2223,0x2254,0x2284,0x22b5,0x22e5,0x2315,0x2346,0x2376,
0x23a6,0x23d7,0x2407,0x2437,0x2467,0x2497,0x24c8,0x24f8,
0x2528,0x2558,0x2588,0x25b8,0x25e8,0x2618,0x2648,0x2678,
0x26a8,0x26d8,0x2708,0x2737,0x2767,0x2797,0x27c7,0x27f7,
0x2826,0x2856,0x2886,0x28b5,0x28e5,0x2915,0x2944,0x2974,
0x29a3,0x29d3,0x2a02,0x2a32,0x2a61,0x2a91,0x2ac0,0x2af0,
0x2b1f,0x2b4e,0x2b7d,0x2bad,0x2bdc,0x2c0b,0x2c3a,0x2c6a,
0x2c99,0x2cc8,0x2cf7,0x2d26,0x2d55,0x2d84,0x2db3,0x2de2,
0x2e11,0x2e40,0x2e6e,0x2e9d,0x2ecc,0x2efb,0x2f2a,0x2f58,
0x2f87,0x2fb6,0x2fe4,0x3013,0x3041,0x3070,0x309e,0x30cd,
0x30fb,0x312a,0x3158,0x3187,0x31b5,0x31e3,0x3211,0x3240,
0x326e,0x329c,0x32ca,0x32f8,0x3326,0x3355,0x3383,0x33b1,
0x33df,0x340c,0x343a,0x3468,0x3496,0x34c4,0x34f2,0x351f,
0x354d,0x357b,0x35a8,0x35d6,0x3604,0x3631,0x365f,0x368c,
0x36ba,0x36e7,0x3715,0x3742,0x376f,0x379c,0x37ca,0x37f7,
0x3824,0x3851,0x387e,0x38ab,0x38d9,0x3906,0x3933,0x3960,
0x398c,0x39b9,0x39e6,0x3a13,0x3a40,0x3a6c,0x3a99,0x3ac6,
0x3af2,0x3b1f,0x3b4c,0x3b78,0x3ba5,0x3bd1,0x3bfe,0x3c2a,
0x3c56,0x3c83,0x3caf,0x3cdb,0x3d07,0x3d33,0x3d60,0x3d8c,
0x3db8,0x3de4,0x3e10,0x3e3c,0x3e68,0x3e93,0x3ebf,0x3eeb,
0x3f17,0x3f43,0x3f6e,0x3f9a,0x3fc5,0x3ff1,0x401d,0x4048,
0x4073,0x409f,0x40ca,0x40f6,0x4121,0x414c,0x4177,0x41a2,
0x41ce,0x41f9,0x4224,0x424f,0x427a,0x42a5,0x42d0,0x42fa,
0x4325,0x4350,0x437b,0x43a5,0x43d0,0x43fb,0x4425,0x4450,
0x447a,0x44a5,0x44cf,0x44f9,0x4524,0x454e,0x4578,0x45a3,
0x45cd,0x45f7,0x4621,0x464b,0x4675,0x469f,0x46c9,0x46f3,
0x471c,0x4746,0x4770,0x479a,0x47c3,0x47ed,0x4816,0x4840,
0x4869,0x4893,0x48bc,0x48e5,0x490f,0x4938,0x4961,0x498a,
0x49b4,0x49dd,0x4a06,0x4a2f,0x4a58,0x4a80,0x4aa9,0x4ad2,
0x4afb,0x4b24,0x4b4c,0x4b75,0x4b9d,0x4bc6,0x4bee,0x4c17,
0x4c3f,0x4c68,0x4c90,0x4cb8,0x4ce0,0x4d09,0x4d31,0x4d59,
0x4d81,0x4da9,0x4dd1,0x4df9,0x4e20,0x4e48,0x4e70,0x4e98,
0x4ebf,0x4ee7,0x4f0e,0x4f36,0x4f5d,0x4f85,0x4fac,0x4fd4,
0x4ffb,0x5022,0x5049,0x5070,0x5097,0x50be,0x50e5,0x510c,
0x5133,0x515a,0x5181,0x51a8,0x51ce,0x51f5,0x521b,0x5242,
0x5268,0x528f,0x52b5,0x52dc,0x5302,0x5328,0x534e,0x5374,
0x539b,0x53c1,0x53e7,0x540c,0x5432,0x5458,0x547e,0x54a4,
0x54c9,0x54ef,0x5515,0x553a,0x5560,0x5585,0x55aa,0x55d0,
0x55f5,0x561a,0x563f,0x5664,0x568a,0x56af,0x56d3,0x56f8,
0x571d,0x5742,0x5767,0x578b,0x57b0,0x57d5,0x57f9,0x581e,
0x5842,0x5867,0x588b,0x58af,0x58d3,0x58f8,0x591c,0x5940,
0x5964,0x5988,0x59ac,0x59cf,0x59f3,0x5a17,0x5a3b,0x5a5e,
0x5a82,0x5aa5,0x5ac9,0x5aec,0x5b0f,0x5b33,0x5b56,0x5b79,
0x5b9c,0x5bbf,0x5be2,0x5c05,0x5c28,0x5c4b,0x5c6e,0x5c91,
0x5cb3,0x5cd6,0x5cf9,0x5d1b,0x5d3e,0x5d60,0x5d82,0x5da5,
0x5dc7,0x5de9,0x5e0b,0x5e2d,0x5e4f,0x5e71,0x5e93,0x5eb5,
0x5ed7,0x5ef8,0x5f1a,0x5f3c,0x5f5d,0x5f7f,0x5fa0,0x5fc2,
0x5fe3,0x6004,0x6025,0x6047,0x6068,0x6089,0x60aa,0x60cb,
0x60eb,0x610c,0x612d,0x614e,0x616e,0x618f,0x61af,0x61d0,
0x61f0,0x6211,0x6231,0x6251,0x6271,0x6291,0x62b1,0x62d1,
0x62f1,0x6311,0x6331,0x6351,0x6370,0x6390,0x63af,0x63cf,
0x63ee,0x640e,0x642d,0x644c,0x646c,0x648b,0x64aa,0x64c9,
0x64e8,0x6507,0x6525,0x6544,0x6563,0x6582,0x65a0,0x65bf,
0x65dd,0x65fc,0x661a,0x6638,0x6656,0x6675,0x6693,0x66b1,
0x66cf,0x66ed,0x670a,0x6728,0x6746,0x6764,0x6781,0x679f,
0x67bc,0x67da,0x67f7,0x6814,0x6832,0x684f,0x686c,0x6889,
0x68a6,0x68c3,0x68e0,0x68fc,0x6919,0x6936,0x6952,0x696f,
0x698b,0x69a8,0x69c4,0x69e0,0x69fd,0x6a19,0x6a35,0x6a51,
0x6a6d,0x6a89,0x6aa4,0x6ac0,0x6adc,0x6af8,0x6b13,0x6b2f,
0x6b4a,0x6b65,0x6b81,0x6b9c,0x6bb7,0x6bd2,0x6bed,0x6c08,
0x6c23,0x6c3e,0x6c59,0x6c74,0x6c8e,0x6ca9,0x6cc3,0x6cde,
0x6cf8,0x6d13,0x6d2d,0x6d47,0x6d61,0x6d7b,0x6d95,0x6daf,
0x6dc9,0x6de3,0x6dfd,0x6e16,0x6e30,0x6e4a,0x6e63,0x6e7c,
0x6e96,0x6eaf,0x6ec8,0x6ee1,0x6efb,0x6f14,0x6f2c,0x6f45,
0x6f5e,0x6f77,0x6f90,0x6fa8,0x6fc1,0x6fd9,0x6ff2,0x700a,
0x7022,0x703a,0x7053,0x706b,0x7083,0x709b,0x70b2,0x70ca,
0x70e2,0x70fa,0x7111,0x7129,0x7140,0x7158,0x716f,0x7186,
0x719d,0x71b4,0x71cb,0x71e2,0x71f9,0x7210,0x7227,0x723e,
0x7254,0x726b,0x7281,0x7298,0x72ae,0x72c4,0x72db,0x72f1,
0x7307,0x731d,0x7333,0x7349,0x735e,0x7374,0x738a,0x739f,
0x73b5,0x73ca,0x73e0,0x73f5,0x740a,0x7420,0x7435,0x744a,
0x745f,0x7474,0x7488,0x749d,0x74b2,0x74c6,0x74db,0x74f0,
0x7504,0x7518,0x752d,0x7541,0x7555,0x7569,0x757d,0x7591,
0x75a5,0x75b8,0x75cc,0x75e0,0x75f3,0x7607,0x761a,0x762d,
0x7641,0x7654,0x7667,0x767a,0x768d,0x76a0,0x76b3,0x76c6,
0x76d8,0x76eb,0x76fe,0x7710,0x7722,0x7735,0x7747,0x7759,
0x776b,0x777d,0x778f,0x77a1,0x77b3,0x77c5,0x77d7,0x77e8,
0x77fa,0x780b,0x781d,0x782e,0x783f,0x7850,0x7862,0x7873,
0x7884,0x7894,0x78a5,0x78b6,0x78c7,0x78d7,0x78e8,0x78f8,
0x7909,0x7919,0x7929,0x7939,0x794a,0x795a,0x796a,0x7979,
0x7989,0x7999,0x79a9,0x79b8,0x79c8,0x79d7,0x79e6,0x79f6,
0x7a05,0x7a14,0x7a23,0x7a32,0x7a41,0x7a50,0x7a5f,0x7a6d,
0x7a7c,0x7a8b,0x7a99,0x7aa8,0x7ab6,0x7ac4,0x7ad2,0x7ae0,
0x7aee,0x7afc,0x7b0a,0x7b18,0x7b26,0x7b33,0x7b41,0x7b4f,
0x7b5c,0x7b69,0x7b77,0x7b84,0x7b91,0x7b9e,0x7bab,0x7bb8,
0x7bc5,0x7bd2,0x7bde,0x7beb,0x7bf8,0x7c04,0x7c10,0x7c1d,
0x7c29,0x7c35,0x7c41,0x7c4d,0x7c59,0x7c65,0x7c71,0x7c7d,
0x7c88,0x7c94,0x7c9f,0x7cab,0x7cb6,0x7cc1,0x7ccd,0x7cd8,
0x7ce3,0x7cee,0x7cf9,0x7d04,0x7d0e,0x7d19,0x7d24,0x7d2e,
0x7d39,0x7d43,0x7d4d,0x7d57,0x7d62,0x7d6c,0x7d76,0x7d80,
0x7d89,0x7d93,0x7d9d,0x7da6,0x7db0,0x7db9,0x7dc3,0x7dcc,
0x7dd5,0x7ddf,0x7de8,0x7df1,0x7dfa,0x7e02,0x7e0b,0x7e14,
0x7e1d,0x7e25,0x7e2e,0x7e36,0x7e3e,0x7e47,0x7e4f,0x7e57,
0x7e5f,0x7e67,0x7e6f,0x7e77,0x7e7e,0x7e86,0x7e8d,0x7e95,
0x7e9c,0x7ea4,0x7eab,0x7eb2,0x7eb9,0x7ec0,0x7ec7,0x7ece,
0x7ed5,0x7edc,0x7ee2,0x7ee9,0x7eef,0x7ef6,0x7efc,0x7f02,
0x7f09,0x7f0f,0x7f15,0x7f1b,0x7f21,0x7f26,0x7f2c,0x7f32,
0x7f37,0x7f3d,0x7f42,0x7f48,0x7f4d,0x7f52,0x7f57,0x7f5c,
0x7f61,0x7f66,0x7f6b,0x7f70,0x7f74,0x7f79,0x7f7d,0x7f82,
0x7f86,0x7f8a,0x7f8f,0x7f93,0x7f97,0x7f9b,0x7f9f,0x7fa2,
0x7fa6,0x7faa,0x7fad,0x7fb1,0x7fb4,0x7fb8,0x7fbb,0x7fbe,
0x7fc1,0x7fc4,0x7fc7,0x7fca,0x7fcd,0x7fd0,0x7fd2,0x7fd5,
0x7fd8,0x7fda,0x7fdc,0x7fdf,0x7fe1,0x7fe3,0x7fe5,0x7fe7,
0x7fe9,0x7feb,0x7fec,0x7fee,0x7ff0,0x7ff1,0x7ff3,0x7ff4,
0x7ff5,0x7ff6,0x7ff7,0x7ff8,0x7ff9,0x7ffa,0x7ffb,0x7ffc,
0x7ffd,0x7ffd,0x7ffe,0x7ffe,0x7ffe,0x7fff,0x7fff,0x7fff,
0x7fff,0x7fff,0x7fff,0x7fff,0x7ffe,0x7ffe,0x7ffe,0x7ffd,
0x7ffd,0x7ffc,0x7ffb,0x7ffa,0x7ff9,0x7ff8,0x7ff7,0x7ff6,
0x7ff5,0x7ff4,0x7ff3,0x7ff1,0x7ff0,0x7fee,0x7fec,0x7feb,
0x7fe9,0x7fe7,0x7fe5,0x7fe3,0x7fe1,0x7fdf,0x7fdc,0x7fda,
0x7fd8,0x7fd5,0x7fd2,0x7fd0,0x7fcd,0x7fca,0x7fc7,0x7fc4,
0x7fc1,0x7fbe,0x7fbb,0x7fb8,0x7fb4,0x7fb1,0x7fad,0x7faa,
0x7fa6,0x7fa2,0x7f9f,0x7f9b,0x7f97,0x7f93,0x7f8f,0x7f8a,
0x7f86,0x7f82,0x7f7d,0x7f79,0x7f74,0x7f70,0x7f6b,0x7f66,
0x7f61,0x7f5c,0x7f57,0x7f52,0x7f4d,0x7f48,0x7f42,0x7f3d,
0x7f37,0x7f32,0x7f2c,0x7f26,0x7f21,0x7f1b,0x7f15,0x7f0f,
0x7f09,0x7f02,0x7efc,0x7ef6,0x7eef,0x7ee9,0x7ee2,0x7edc,
0x7ed5,0x7ece,0x7ec7,0x7ec0,0x7eb9,0x7eb2,0x7eab,0x7ea4,
0x7e9c,0x7e95,0x7e8d,0x7e86,0x7e7e,0x7e77,0x7e6f,0x7e67,
0x7e5f,0x7e57,0x7e4f,0x7e47,0x7e3e,0x7e36,0x7e2e,0x7e25,
0x7e1d,0x7e14,0x7e0b,0x7e02,0x7dfa,0x7df1,0x7de8,0x7ddf,
0x7dd5,0x7dcc,0x7dc3,0x7db9,0x7db0,0x7da6,0x7d9d,0x7d93,
0x7d89,0x7d80,0x7d76,0x7d6c,0x7d62,0x7d57,0x7d4d,0x7d43,
0x7d39,0x7d2e,0x7d24,0x7d19,0x7d0e,0x7d04,0x7cf9,0x7cee,
0x7ce3,0x7cd8,0x7ccd,0x7cc1,0x7cb6,0x7cab,0x7c9f,0x7c94,
0x7c88,0x7c7d,0x7c71,0x7c65,0x7c59,0x7c4d,0x7c41,0x7c35,
0x7c29,0x7c1d,0x7c10,0x7c04,0x7bf8,0x7beb,0x7bde,0x7bd2,
0x7bc5,0x7bb8,0x7bab,0x7b9e,0x7b91,0x7b84,0x7b77,0x7b69,
0x7b5c,0x7b4f,0x7b41,0x7b33,0x7b26,0x7b18,0x7b0a,0x7afc,
0x7aee,0x7ae0,0x7ad2,0x7ac4,0x7ab6,0x7aa8,0x7a99,0x7a8b,
0x7a7c,0x7a6d,0x7a5f,0x7a50,0x7a41,0x7a32,0x7a23,0x7a14,
0x7a05,0x79f6,0x79e6,0x79d7,0x79c8,0x79b8,0x79a9,0x7999,
0x7989,0x7979,0x796a,0x795a,0x794a,0x7939,0x7929,0x7919,
0x7909,0x78f8,0x78e8,0x78d7,0x78c7,0x78b6,0x78a5,0x7894,
0x7884,0x7873,0x7862,0x7850,0x783f,0x782e,0x781d,0x780b,
0x77fa,0x77e8,0x77d7,0x77c5,0x77b3,0x77a1,0x778f,0x777d,
0x776b,0x7759,0x7747,0x7735,0x7722,0x7710,0x76fe,0x76eb,
0x76d8,0x76c6,0x76b3,0x76a0,0x768d,0x767a,0x7667,0x7654,
0x7641,0x762d,0x761a,0x7607,0x75f3,0x75e0,0x75cc,0x75b8,
0x75a5,0x7591,0x757d,0x7569,0x7555,0x7541,0x752d,0x7518,
0x7504,0x74f0,0x74db,0x74c6,0x74b2,0x749d,0x7488,0x7474,
0x745f,0x744a,0x7435,0x7420,0x740a,0x73f5,0x73e0,0x73ca,
0x73b5,0x739f,0x738a,0x7374,0x735e,0x7349,0x7333,0x731d,
0x7307,0x72f1,0x72db,0x72c4,0x72ae,0x7298,0x7281,0x726b,
0x7254,0x723e,0x7227,0x7210,0x71f9,0x71e2,0x71cb,0x71b4,
0x719d,0x7186,0x716f,0x7158,0x7140,0x7129,0x7111,0x70fa,
0x70e2,0x70ca,0x70b2,0x709b,0x7083,0x706b,0x7053,0x703a,
0x7022,0x700a,0x6ff2,0x6fd9,0x6fc1,0x6fa8,0x6f90,0x6f77,
0x6f5e,0x6f45,0x6f2c,0x6f14,0x6efb,0x6ee1,0x6ec8,0x6eaf,
0x6e96,0x6e7c,0x6e63,0x6e4a,0x6e30,0x6e16,0x6dfd,0x6de3,
0x6dc9,0x6daf,0x6d95,0x6d7b,0x6d61,0x6d47,0x6d2d,0x6d13,
0x6cf8,0x6cde,0x6cc3,0x6ca9,0x6c8e,0x6c74,0x6c59,0x6c3e,
0x6c23,0x6c08,0x6bed,0x6bd2,0x6bb7,0x6b9c,0x6b81,0x6b65,
0x6b4a,0x6b2f,0x6b13,0x6af8,0x6adc,0x6ac0,0x6aa4,0x6a89,
0x6a6d,0x6a51,0x6a35,0x6a19,0x69fd,0x69e0,0x69c4,0x69a8,
0x698b,0x696f,0x6952,0x6936,0x6919,0x68fc,0x68e0,0x68c3,
0x68a6,0x6889,0x686c,0x684f,0x6832,0x6814,0x67f7,0x67da,
0x67bc,0x679f,0x6781,0x6764,0x6746,0x6728,0x670a,0x66ed,
0x66cf,0x66b1,0x6693,0x6675,0x6656,0x6638,0x661a,0x65fc,
0x65dd,0x65bf,0x65a0,0x6582,0x6563,0x6544,0x6525,0x6507,
0x64e8,0x64c9,0x64aa,0x648b,0x646c,0x644c,0x642d,0x640e,
0x63ee,0x63cf,0x63af,0x6390,0x6370,0x6351,0x6331,0x6311,
0x62f1,0x62d1,0x62b1,0x6291,0x6271,0x6251,0x6231,0x6211,
0x61f0,0x61d0,0x61af,0x618f,0x616e,0x614e,0x612d,0x610c,
0x60eb,0x60cb,0x60aa,0x6089,0x6068,0x6047,0x6025,0x6004,
0x5fe3,0x5fc2,0x5fa0,0x5f7f,0x5f5d,0x5f3c,0x5f1a,0x5ef8,
0x5ed7,0x5eb5,0x5e93,0x5e71,0x5e4f,0x5e2d,0x5e0b,0x5de9,
0x5dc7,0x5da5,0x5d82,0x5d60,0x5d3e,0x5d1b,0x5cf9,0x5cd6,
0x5cb3,0x5c91,0x5c6e,0x5c4b,0x5c28,0x5c05,0x5be2,0x5bbf,
0x5b9c,0x5b79,0x5b56,0x5b33,0x5b0f,0x5aec,0x5ac9,0x5aa5,
0x5a82,0x5a5e,0x5a3b,0x5a17,0x59f3,0x59cf,0x59ac,0x5988,
0x5964,0x5940,0x591c,0x58f8,0x58d3,0x58af,0x588b,0x5867,
0x5842,0x581e,0x57f9,0x57d5,0x57b0,0x578b,0x5767,0x5742,
0x571d,0x56f8,0x56d3,0x56af,0x568a,0x5664,0x563f,0x561a,
0x55f5,0x55d0,0x55aa,0x5585,0x5560,0x553a,0x5515,0x54ef,
0x54c9,0x54a4,0x547e,0x5458,0x5432,0x540c,0x53e7,0x53c1,
0x539b,0x5374,0x534e,0x5328,0x5302,0x52dc,0x52b5,0x528f,
0x5268,0x5242,0x521b,0x51f5,0x51ce,0x51a8,0x5181,0x515a,
0x5133,0x510c,0x50e5,0x50be,0x5097,0x5070,0x5049,0x5022,
0x4ffb,0x4fd4,0x4fac,0x4f85,0x4f5d,0x4f36,0x4f0e,0x4ee7,
0x4ebf,0x4e98,0x4e70,0x4e48,0x4e20,0x4df9,0x4dd1,0x4da9,
0x4d81,0x4d59,0x4d31,0x4d09,0x4ce0,0x4cb8,0x4c90,0x4c68,
0x4c3f,0x4c17,0x4bee,0x4bc6,0x4b9d,0x4b75,0x4b4c,0x4b24,
0x4afb,0x4ad2,0x4aa9,0x4a80,0x4a58,0x4a2f,0x4a06,0x49dd,
0x49b4,0x498a,0x4961,0x4938,0x490f,0x48e5,0x48bc,0x4893,
0x4869,0x4840,0x4816,0x47ed,0x47c3,0x479a,0x4770,0x4746,
0x471c,0x46f3,0x46c9,0x469f,0x4675,0x464b,0x4621,0x45f7,
0x45cd,0x45a3,0x4578,0x454e,0x4524,0x44f9,0x44cf,0x44a5,
0x447a,0x4450,0x4425,0x43fb,0x43d0,0x43a5,0x437b,0x4350,
0x4325,0x42fa,0x42d0,0x42a5,0x427a,0x424f,0x4224,0x41f9,
0x41ce,0x41a2,0x4177,0x414c,0x4121,0x40f6,0x40ca,0x409f,
0x4073,0x4048,0x401d,0x3ff1,0x3fc5,0x3f9a,0x3f6e,0x3f43,
0x3f17,0x3eeb,0x3ebf,0x3e93,0x3e68,0x3e3c,0x3e10,0x3de4,
0x3db8,0x3d8c,0x3d60,0x3d33,0x3d07,0x3cdb,0x3caf,0x3c83,
0x3c56,0x3c2a,0x3bfe,0x3bd1,0x3ba5,0x3b78,0x3b4c,0x3b1f,
0x3af2,0x3ac6,0x3a99,0x3a6c,0x3a40,0x3a13,0x39e6,0x39b9,
0x398c,0x3960,0x3933,0x3906,0x38d9,0x38ab,0x387e,0x3851,
0x3824,0x37f7,0x37ca,0x379c,0x376f,0x3742,0x3715,0x36e7,
0x36ba,0x368c,0x365f,0x3631,0x3604,0x35d6,0x35a8,0x357b,
0x354d,0x351f,0x34f2,0x34c4,0x3496,0x3468,0x343a,0x340c,
0x33df,0x33b1,0x3383,0x3355,0x3326,0x32f8,0x32ca,0x329c,
0x326e,0x3240,0x3211,0x31e3,0x31b5,0x3187,0x3158,0x312a,
0x30fb,0x30cd,0x309e,0x3070,0x3041,0x3013,0x2fe4,0x2fb6,
0x2f87,0x2f58,0x2f2a,0x2efb,0x2ecc,0x2e9d,0x2e6e,0x2e40,
0x2e11,0x2de2,0x2db3,0x2d84,0x2d55,0x2d26,0x2cf7,0x2cc8,
0x2c99,0x2c6a,0x2c3a,0x2c0b,0x2bdc,0x2bad,0x2b7d,0x2b4e,
0x2b1f,0x2af0,0x2ac0,0x2a91,0x2a61,0x2a32,0x2a02,0x29d3,
0x29a3,0x2974,0x2944,0x2915,0x28e5,0x28b5,0x2886,0x2856,
0x2826,0x27f7,0x27c7,0x2797,0x2767,0x2737,0x2708,0x26d8,
0x26a8,0x2678,0x2648,0x2618,0x25e8,0x25b8,0x2588,0x2558,
0x2528,0x24f8,0x24c8,0x2497,0x2467,0x2437,0x2407,0x23d7,
0x23a6,0x2376,0x2346,0x2315,0x22e5,0x22b5,0x2284,0x2254,
0x2223,0x21f3,0x21c2,0x2192,0x2161,0x2131,0x2100,0x20d0,
0x209f,0x206f,0x203e,0x200d,0x1fdd,0x1fac,0x1f7b,0x1f4a,
0x1f1a,0x1ee9,0x1eb8,0x1e87,0x1e57,0x1e26,0x1df5,0x1dc4,
0x1d93,0x1d62,0x1d31,0x1d00,0x1ccf,0x1c9e,0x1c6d,0x1c3c,
0x1c0b,0x1bda,0x1ba9,0x1b78,0x1b47,0x1b16,0x1ae5,0x1ab4,
0x1a82,0x1a51,0x1a20,0x19ef,0x19be,0x198c,0x195b,0x192a,
0x18f9,0x18c7,0x1896,0x1865,0x1833,0x1802,0x17d0,0x179f,
0x176e,0x173c,0x170b,0x16d9,0x16a8,0x1676,0x1645,0x1613,
0x15e2,0x15b0,0x157f,0x154d,0x151c,0x14ea,0x14b9,0x1487,
0x1455,0x1424,0x13f2,0x13c0,0x138f,0x135d,0x132b,0x12fa,
0x12c8,0x1296,0x1264,0x1233,0x1201,0x11cf,0x119d,0x116c,
0x113a,0x1108,0x10d6,0x10a4,0x1072,0x1041,0x100f,0x0fdd,
0x0fab,0x0f79,0x0f47,0x0f15,0x0ee3,0x0eb1,0x0e80,0x0e4e,
0x0e1c,0x0dea,0x0db8,0x0d86,0x0d54,0x0d22,0x0cf0,0x0cbe,
0x0c8c,0x0c5a,0x0c28,0x0bf6,0x0bc4,0x0b92,0x0b5f,0x0b2d,
0x0afb,0x0ac9,0x0a97,0x0a65,0x0a33,0x0a01,0x09cf,0x099d,
0x096a,0x0938,0x0906,0x08d4,0x08a2,0x0870,0x083e,0x080b,
0x07d9,0x07a7,0x0775,0x0743,0x0711,0x06de,0x06ac,0x067a,
0x0648,0x0616,0x05e3,0x05b1,0x057f,0x054d,0x051b,0x04e8,
0x04b6,0x0484,0x0452,0x041f,0x03ed,0x03bb,0x0389,0x0356,
0x0324,0x02f2,0x02c0,0x028d,0x025b,0x0229,0x01f7,0x01c4,
0x0192,0x0160,0x012e,0x00fb,0x00c9,0x0097,0x0065,0x0032,
0x0000,0xffce,0xff9b,0xff69,0xff37,0xff05,0xfed2,0xfea0,
0xfe6e,0xfe3c,0xfe09,0xfdd7,0xfda5,0xfd73,0xfd40,0xfd0e,
0xfcdc,0xfcaa,0xfc77,0xfc45,0xfc13,0xfbe1,0xfbae,0xfb7c,
0xfb4a,0xfb18,0xfae5,0xfab3,0xfa81,0xfa4f,0xfa1d,0xf9ea,
0xf9b8,0xf986,0xf954,0xf922,0xf8ef,0xf8bd,0xf88b,0xf859,
0xf827,0xf7f5,0xf7c2,0xf790,0xf75e,0xf72c,0xf6fa,0xf6c8,
0xf696,0xf663,0xf631,0xf5ff,0xf5cd,0xf59b,0xf569,0xf537,
0xf505,0xf4d3,0xf4a1,0xf46e,0xf43c,0xf40a,0xf3d8,0xf3a6,
0xf374,0xf342,0xf310,0xf2de,0xf2ac,0xf27a,0xf248,0xf216,
0xf1e4,0xf1b2,0xf180,0xf14f,0xf11d,0xf0eb,0xf0b9,0xf087,
0xf055,0xf023,0xeff1,0xefbf,0xef8e,0xef5c,0xef2a,0xeef8,
0xeec6,0xee94,0xee63,0xee31,0xedff,0xedcd,0xed9c,0xed6a,
0xed38,0xed06,0xecd5,0xeca3,0xec71,0xec40,0xec0e,0xebdc,
0xebab,0xeb79,0xeb47,0xeb16,0xeae4,0xeab3,0xea81,0xea50,
0xea1e,0xe9ed,0xe9bb,0xe98a,0xe958,0xe927,0xe8f5,0xe8c4,
0xe892,0xe861,0xe830,0xe7fe,0xe7cd,0xe79b,0xe76a,0xe739,
0xe707,0xe6d6,0xe6a5,0xe674,0xe642,0xe611,0xe5e0,0xe5af,
0xe57e,0xe54c,0xe51b,0xe4ea,0xe4b9,0xe488,0xe457,0xe426,
0xe3f5,0xe3c4,0xe393,0xe362,0xe331,0xe300,0xe2cf,0xe29e,
0xe26d,0xe23c,0xe20b,0xe1da,0xe1a9,0xe179,0xe148,0xe117,
0xe0e6,0xe0b6,0xe085,0xe054,0xe023,0xdff3,0xdfc2,0xdf91,
0xdf61,0xdf30,0xdf00,0xdecf,0xde9f,0xde6e,0xde3e,0xde0d,
0xdddd,0xddac,0xdd7c,0xdd4b,0xdd1b,0xdceb,0xdcba,0xdc8a,
0xdc5a,0xdc29,0xdbf9,0xdbc9,0xdb99,0xdb69,0xdb38,0xdb08,
0xdad8,0xdaa8,0xda78,0xda48,0xda18,0xd9e8,0xd9b8,0xd988,
0xd958,0xd928,0xd8f8,0xd8c9,0xd899,0xd869,0xd839,0xd809,
0xd7da,0xd7aa,0xd77a,0xd74b,0xd71b,0xd6eb,0xd6bc,0xd68c,
0xd65d,0xd62d,0xd5fe,0xd5ce,0xd59f,0xd56f,0xd540,0xd510,
0xd4e1,0xd4b2,0xd483,0xd453,0xd424,0xd3f5,0xd3c6,0xd396,
0xd367,0xd338,0xd309,0xd2da,0xd2ab,0xd27c,0xd24d,0xd21e,
0xd1ef,0xd1c0,0xd192,0xd163,0xd134,0xd105,0xd0d6,0xd0a8,
0xd079,0xd04a,0xd01c,0xcfed,0xcfbf,0xcf90,0xcf62,0xcf33,
0xcf05,0xced6,0xcea8,0xce79,0xce4b,0xce1d,0xcdef,0xcdc0,
0xcd92,0xcd64,0xcd36,0xcd08,0xccda,0xccab,0xcc7d,0xcc4f,
0xcc21,0xcbf4,0xcbc6,0xcb98,0xcb6a,0xcb3c,0xcb0e,0xcae1,
0xcab3,0xca85,0xca58,0xca2a,0xc9fc,0xc9cf,0xc9a1,0xc974,
0xc946,0xc919,0xc8eb,0xc8be,0xc891,0xc864,0xc836,0xc809,
0xc7dc,0xc7af,0xc782,0xc755,0xc727,0xc6fa,0xc6cd,0xc6a0,
0xc674,0xc647,0xc61a,0xc5ed,0xc5c0,0xc594,0xc567,0xc53a,
0xc50e,0xc4e1,0xc4b4,0xc488,0xc45b,0xc42f,0xc402,0xc3d6,
0xc3aa,0xc37d,0xc351,0xc325,0xc2f9,0xc2cd,0xc2a0,0xc274,
0xc248,0xc21c,0xc1f0,0xc1c4,0xc198,0xc16d,0xc141,0xc115,
0xc0e9,0xc0bd,0xc092,0xc066,0xc03b,0xc00f,0xbfe3,0xbfb8,
0xbf8d,0xbf61,0xbf36,0xbf0a,0xbedf,0xbeb4,0xbe89,0xbe5e,
0xbe32,0xbe07,0xbddc,0xbdb1,0xbd86,0xbd5b,0xbd30,0xbd06,
0xbcdb,0xbcb0,0xbc85,0xbc5b,0xbc30,0xbc05,0xbbdb,0xbbb0,
0xbb86,0xbb5b,0xbb31,0xbb07,0xbadc,0xbab2,0xba88,0xba5d,
0xba33,0xba09,0xb9df,0xb9b5,0xb98b,0xb961,0xb937,0xb90d,
0xb8e4,0xb8ba,0xb890,0xb866,0xb83d,0xb813,0xb7ea,0xb7c0,
0xb797,0xb76d,0xb744,0xb71b,0xb6f1,0xb6c8,0xb69f,0xb676,
0xb64c,0xb623,0xb5fa,0xb5d1,0xb5a8,0xb580,0xb557,0xb52e,
0xb505,0xb4dc,0xb4b4,0xb48b,0xb463,0xb43a,0xb412,0xb3e9,
0xb3c1,0xb398,0xb370,0xb348,0xb320,0xb2f7,0xb2cf,0xb2a7,
0xb27f,0xb257,0xb22f,0xb207,0xb1e0,0xb1b8,0xb190,0xb168,
0xb141,0xb119,0xb0f2,0xb0ca,0xb0a3,0xb07b,0xb054,0xb02c,
0xb005,0xafde,0xafb7,0xaf90,0xaf69,0xaf42,0xaf1b,0xaef4,
0xaecd,0xaea6,0xae7f,0xae58,0xae32,0xae0b,0xade5,0xadbe,
0xad98,0xad71,0xad4b,0xad24,0xacfe,0xacd8,0xacb2,0xac8c,
0xac65,0xac3f,0xac19,0xabf4,0xabce,0xaba8,0xab82,0xab5c,
0xab37,0xab11,0xaaeb,0xaac6,0xaaa0,0xaa7b,0xaa56,0xaa30,
0xaa0b,0xa9e6,0xa9c1,0xa99c,0xa976,0xa951,0xa92d,0xa908,
0xa8e3,0xa8be,0xa899,0xa875,0xa850,0xa82b,0xa807,0xa7e2,
0xa7be,0xa799,0xa775,0xa751,0xa72d,0xa708,0xa6e4,0xa6c0,
0xa69c,0xa678,0xa654,0xa631,0xa60d,0xa5e9,0xa5c5,0xa5a2,
0xa57e,0xa55b,0xa537,0xa514,0xa4f1,0xa4cd,0xa4aa,0xa487,
0xa464,0xa441,0xa41e,0xa3fb,0xa3d8,0xa3b5,0xa392,0xa36f,
0xa34d,0xa32a,0xa307,0xa2e5,0xa2c2,0xa2a0,0xa27e,0xa25b,
0xa239,0xa217,0xa1f5,0xa1d3,0xa1b1,0xa18f,0xa16d,0xa14b,
0xa129,0xa108,0xa0e6,0xa0c4,0xa0a3,0xa081,0xa060,0xa03e,
0xa01d,0x9ffc,0x9fdb,0x9fb9,0x9f98,0x9f77,0x9f56,0x9f35,
0x9f15,0x9ef4,0x9ed3,0x9eb2,0x9e92,0x9e71,0x9e51,0x9e30,
0x9e10,0x9def,0x9dcf,0x9daf,0x9d8f,0x9d6f,0x9d4f,0x9d2f,
0x9d0f,0x9cef,0x9ccf,0x9caf,0x9c90,0x9c70,0x9c51,0x9c31,
0x9c12,0x9bf2,0x9bd3,0x9bb4,0x9b94,0x9b75,0x9b56,0x9b37,
0x9b18,0x9af9,0x9adb,0x9abc,0x9a9d,0x9a7e,0x9a60,0x9a41,
0x9a23,0x9a04,0x99e6,0x99c8,0x99aa,0x998b,0x996d,0x994f,
0x9931,0x9913,0x98f6,0x98d8,0x98ba,0x989c,0x987f,0x9861,
0x9844,0x9826,0x9809,0x97ec,0x97ce,0x97b1,0x9794,0x9777,
0x975a,0x973d,0x9720,0x9704,0x96e7,0x96ca,0x96ae,0x9691,
0x9675,0x9658,0x963c,0x9620,0x9603,0x95e7,0x95cb,0x95af,
0x9593,0x9577,0x955c,0x9540,0x9524,0x9508,0x94ed,0x94d1,
0x94b6,0x949b,0x947f,0x9464,0x9449,0x942e,0x9413,0x93f8,
0x93dd,0x93c2,0x93a7,0x938c,0x9372,0x9357,0x933d,0x9322,
0x9308,0x92ed,0x92d3,0x92b9,0x929f,0x9285,0x926b,0x9251,
0x9237,0x921d,0x9203,0x91ea,0x91d0,0x91b6,0x919d,0x9184,
0x916a,0x9151,0x9138,0x911f,0x9105,0x90ec,0x90d4,0x90bb,
0x90a2,0x9089,0x9070,0x9058,0x903f,0x9027,0x900e,0x8ff6,
0x8fde,0x8fc6,0x8fad,0x8f95,0x8f7d,0x8f65,0x8f4e,0x8f36,
0x8f1e,0x8f06,0x8eef,0x8ed7,0x8ec0,0x8ea8,0x8e91,0x8e7a,
0x8e63,0x8e4c,0x8e35,0x8e1e,0x8e07,0x8df0,0x8dd9,0x8dc2,
0x8dac,0x8d95,0x8d7f,0x8d68,0x8d52,0x8d3c,0x8d25,0x8d0f,
0x8cf9,0x8ce3,0x8ccd,0x8cb7,0x8ca2,0x8c8c,0x8c76,0x8c61,
0x8c4b,0x8c36,0x8c20,0x8c0b,0x8bf6,0x8be0,0x8bcb,0x8bb6,
0x8ba1,0x8b8c,0x8b78,0x8b63,0x8b4e,0x8b3a,0x8b25,0x8b10,
0x8afc,0x8ae8,0x8ad3,0x8abf,0x8aab,0x8a97,0x8a83,0x8a6f,
0x8a5b,0x8a48,0x8a34,0x8a20,0x8a0d,0x89f9,0x89e6,0x89d3,
0x89bf,0x89ac,0x8999,0x8986,0x8973,0x8960,0x894d,0x893a,
0x8928,0x8915,0x8902,0x88f0,0x88de,0x88cb,0x88b9,0x88a7,
0x8895,0x8883,0x8871,0x885f,0x884d,0x883b,0x8829,0x8818,
0x8806,0x87f5,0x87e3,0x87d2,0x87c1,0x87b0,0x879e,0x878d,
0x877c,0x876c,0x875b,0x874a,0x8739,0x8729,0x8718,0x8708,
0x86f7,0x86e7,0x86d7,0x86c7,0x86b6,0x86a6,0x8696,0x8687,
0x8677,0x8667,0x8657,0x8648,0x8638,0x8629,0x861a,0x860a,
0x85fb,0x85ec,0x85dd,0x85ce,0x85bf,0x85b0,0x85a1,0x8593,
0x8584,0x8575,0x8567,0x8558,0x854a,0x853c,0x852e,0x8520,
0x8512,0x8504,0x84f6,0x84e8,0x84da,0x84cd,0x84bf,0x84b1,
0x84a4,0x8497,0x8489,0x847c,0x846f,0x8462,0x8455,0x8448,
0x843b,0x842e,0x8422,0x8415,0x8408,0x83fc,0x83f0,0x83e3,
0x83d7,0x83cb,0x83bf,0x83b3,0x83a7,0x839b,0x838f,0x8383,
0x8378,0x836c,0x8361,0x8355,0x834a,0x833f,0x8333,0x8328,
0x831d,0x8312,0x8307,0x82fc,0x82f2,0x82e7,0x82dc,0x82d2,
0x82c7,0x82bd,0x82b3,0x82a9,0x829e,0x8294,0x828a,0x8280,
0x8277,0x826d,0x8263,0x825a,0x8250,0x8247,0x823d,0x8234,
0x822b,0x8221,0x8218,0x820f,0x8206,0x81fe,0x81f5,0x81ec,
0x81e3,0x81db,0x81d2,0x81ca,0x81c2,0x81b9,0x81b1,0x81a9,
0x81a1,0x8199,0x8191,0x8189,0x8182,0x817a,0x8173,0x816b,
0x8164,0x815c,0x8155,0x814e,0x8147,0x8140,0x8139,0x8132,
0x812b,0x8124,0x811e,0x8117,0x8111,0x810a,0x8104,0x80fe,
0x80f7,0x80f1,0x80eb,0x80e5,0x80df,0x80da,0x80d4,0x80ce,
0x80c9,0x80c3,0x80be,0x80b8,0x80b3,0x80ae,0x80a9,0x80a4,
0x809f,0x809a,0x8095,0x8090,0x808c,0x8087,0x8083,0x807e,
0x807a,0x8076,0x8071,0x806d,0x8069,0x8065,0x8061,0x805e,
0x805a,0x8056,0x8053,0x804f,0x804c,0x8048,0x8045,0x8042,
0x803f,0x803c,0x8039,0x8036,0x8033,0x8030,0x802e,0x802b,
0x8028,0x8026,0x8024,0x8021,0x801f,0x801d,0x801b,0x8019,
0x8017,0x8015,0x8014,0x8012,0x8010,0x800f,0x800d,0x800c,
0x800b,0x800a,0x8009,0x8008,0x8007,0x8006,0x8005,0x8004,
0x8003,0x8003,0x8002,0x8002,0x8002,0x8001,0x8001,0x8001,
0x8001,0x8001,0x8001,0x8001,0x8002,0x8002,0x8002,0x8003,
0x8003,0x8004,0x8005,0x8006,0x8007,0x8008,0x8009,0x800a,
0x800b,0x800c,0x800d,0x800f,0x8010,0x8012,0x8014,0x8015,
0x8017,0x8019,0x801b,0x801d,0x801f,0x8021,0x8024,0x8026,
0x8028,0x802b,0x802e,0x8030,0x8033,0x8036,0x8039,0x803c,
0x803f,0x8042,0x8045,0x8048,0x804c,0x804f,0x8053,0x8056,
0x805a,0x805e,0x8061,0x8065,0x8069,0x806d,0x8071,0x8076,
0x807a,0x807e,0x8083,0x8087,0x808c,0x8090,0x8095,0x809a,
0x809f,0x80a4,0x80a9,0x80ae,0x80b3,0x80b8,0x80be,0x80c3,
0x80c9,0x80ce,0x80d4,0x80da,0x80df,0x80e5,0x80eb,0x80f1,
0x80f7,0x80fe,0x8104,0x810a,0x8111,0x8117,0x811e,0x8124,
0x812b,0x8132,0x8139,0x8140,0x8147,0x814e,0x8155,0x815c,
0x8164,0x816b,0x8173,0x817a,0x8182,0x8189,0x8191,0x8199,
0x81a1,0x81a9,0x81b1,0x81b9,0x81c2,0x81ca,0x81d2,0x81db,
0x81e3,0x81ec,0x81f5,0x81fe,0x8206,0x820f,0x8218,0x8221,
0x822b,0x8234,0x823d,0x8247,0x8250,0x825a,0x8263,0x826d,
0x8277,0x8280,0x828a,0x8294,0x829e,0x82a9,0x82b3,0x82bd,
0x82c7,0x82d2,0x82dc,0x82e7,0x82f2,0x82fc,0x8307,0x8312,
0x831d,0x8328,0x8333,0x833f,0x834a,0x8355,0x8361,0x836c,
0x8378,0x8383,0x838f,0x839b,0x83a7,0x83b3,0x83bf,0x83cb,
0x83d7,0x83e3,0x83f0,0x83fc,0x8408,0x8415,0x8422,0x842e,
0x843b,0x8448,0x8455,0x8462,0x846f,0x847c,0x8489,0x8497,
0x84a4,0x84b1,0x84bf,0x84cd,0x84da,0x84e8,0x84f6,0x8504,
0x8512,0x8520,0x852e,0x853c,0x854a,0x8558,0x8567,0x8575,
0x8584,0x8593,0x85a1,0x85b0,0x85bf,0x85ce,0x85dd,0x85ec,
0x85fb,0x860a,0x861a,0x8629,0x8638,0x8648,0x8657,0x8667,
0x8677,0x8687,0x8696,0x86a6,0x86b6,0x86c7,0x86d7,0x86e7,
0x86f7,0x8708,0x8718,0x8729,0x8739,0x874a,0x875b,0x876c,
0x877c,0x878d,0x879e,0x87b0,0x87c1,0x87d2,0x87e3,0x87f5,
0x8806,0x8818,0x8829,0x883b,0x884d,0x885f,0x8871,0x8883,
0x8895,0x88a7,0x88b9,0x88cb,0x88de,0x88f0,0x8902,0x8915,
0x8928,0x893a,0x894d,0x8960,0x8973,0x8986,0x8999,0x89ac,
0x89bf,0x89d3,0x89e6,0x89f9,0x8a0d,0x8a20,0x8a34,0x8a48,
0x8a5b,0x8a6f,0x8a83,0x8a97,0x8aab,0x8abf,0x8ad3,0x8ae8,
0x8afc,0x8b10,0x8b25,0x8b3a,0x8b4e,0x8b63,0x8b78,0x8b8c,
0x8ba1,0x8bb6,0x8bcb,0x8be0,0x8bf6,0x8c0b,0x8c20,0x8c36,
0x8c4b,0x8c61,0x8c76,0x8c8c,0x8ca2,0x8cb7,0x8ccd,0x8ce3,
0x8cf9,0x8d0f,0x8d25,0x8d3c,0x8d52,0x8d68,0x8d7f,0x8d95,
0x8dac,0x8dc2,0x8dd9,0x8df0,0x8e07,0x8e1e,0x8e35,0x8e4c,
0x8e63,0x8e7a,0x8e91,0x8ea8,0x8ec0,0x8ed7,0x8eef,0x8f06,
0x8f1e,0x8f36,0x8f4e,0x8f65,0x8f7d,0x8f95,0x8fad,0x8fc6,
0x8fde,0x8ff6,0x900e,0x9027,0x903f,0x9058,0x9070,0x9089,
0x90a2,0x90bb,0x90d4,0x90ec,0x9105,0x911f,0x9138,0x9151,
0x916a,0x9184,0x919d,0x91b6,0x91d0,0x91ea,0x9203,0x921d,
0x9237,0x9251,0x926b,0x9285,0x929f,0x92b9,0x92d3,0x92ed,
0x9308,0x9322,0x933d,0x9357,0x9372,0x938c,0x93a7,0x93c2,
0x93dd,0x93f8,0x9413,0x942e,0x9449,0x9464,0x947f,0x949b,
0x94b6,0x94d1,0x94ed,0x9508,0x9524,0x9540,0x955c,0x9577,
0x9593,0x95af,0x95cb,0x95e7,0x9603,0x9620,0x963c,0x9658,
0x9675,0x9691,0x96ae,0x96ca,0x96e7,0x9704,0x9720,0x973d,
0x975a,0x9777,0x9794,0x97b1,0x97ce,0x97ec,0x9809,0x9826,
0x9844,0x9861,0x987f,0x989c,0x98ba,0x98d8,0x98f6,0x9913,
0x9931,0x994f,0x996d,0x998b,0x99aa,0x99c8,0x99e6,0x9a04,
0x9a23,0x9a41,0x9a60,0x9a7e,0x9a9d,0x9abc,0x9adb,0x9af9,
0x9b18,0x9b37,0x9b56,0x9b75,0x9b94,0x9bb4,0x9bd3,0x9bf2,
0x9c12,0x9c31,0x9c51,0x9c70,0x9c90,0x9caf,0x9ccf,0x9cef,
0x9d0f,0x9d2f,0x9d4f,0x9d6f,0x9d8f,0x9daf,0x9dcf,0x9def,
0x9e10,0x9e30,0x9e51,0x9e71,0x9e92,0x9eb2,0x9ed3,0x9ef4,
0x9f15,0x9f35,0x9f56,0x9f77,0x9f98,0x9fb9,0x9fdb,0x9ffc,
0xa01d,0xa03e,0xa060,0xa081,0xa0a3,0xa0c4,0xa0e6,0xa108,
0xa129,0xa14b,0xa16d,0xa18f,0xa1b1,0xa1d3,0xa1f5,0xa217,
0xa239,0xa25b,0xa27e,0xa2a0,0xa2c2,0xa2e5,0xa307,0xa32a,
0xa34d,0xa36f,0xa392,0xa3b5,0xa3d8,0xa3fb,0xa41e,0xa441,
0xa464,0xa487,0xa4aa,0xa4cd,0xa4f1,0xa514,0xa537,0xa55b,
0xa57e,0xa5a2,0xa5c5,0xa5e9,0xa60d,0xa631,0xa654,0xa678,
0xa69c,0xa6c0,0xa6e4,0xa708,0xa72d,0xa751,0xa775,0xa799,
0xa7be,0xa7e2,0xa807,0xa82b,0xa850,0xa875,0xa899,0xa8be,
0xa8e3,0xa908,0xa92d,0xa951,0xa976,0xa99c,0xa9c1,0xa9e6,
0xaa0b,0xaa30,0xaa56,0xaa7b,0xaaa0,0xaac6,0xaaeb,0xab11,
0xab37,0xab5c,0xab82,0xaba8,0xabce,0xabf4,0xac19,0xac3f,
0xac65,0xac8c,0xacb2,0xacd8,0xacfe,0xad24,0xad4b,0xad71,
0xad98,0xadbe,0xade5,0xae0b,0xae32,0xae58,0xae7f,0xaea6,
0xaecd,0xaef4,0xaf1b,0xaf42,0xaf69,0xaf90,0xafb7,0xafde,
0xb005,0xb02c,0xb054,0xb07b,0xb0a3,0xb0ca,0xb0f2,0xb119,
0xb141,0xb168,0xb190,0xb1b8,0xb1e0,0xb207,0xb22f,0xb257,
0xb27f,0xb2a7,0xb2cf,0xb2f7,0xb320,0xb348,0xb370,0xb398,
0xb3c1,0xb3e9,0xb412,0xb43a,0xb463,0xb48b,0xb4b4,0xb4dc,
0xb505,0xb52e,0xb557,0xb580,0xb5a8,0xb5d1,0xb5fa,0xb623,
0xb64c,0xb676,0xb69f,0xb6c8,0xb6f1,0xb71b,0xb744,0xb76d,
0xb797,0xb7c0,0xb7ea,0xb813,0xb83d,0xb866,0xb890,0xb8ba,
0xb8e4,0xb90d,0xb937,0xb961,0xb98b,0xb9b5,0xb9df,0xba09,
0xba33,0xba5d,0xba88,0xbab2,0xbadc,0xbb07,0xbb31,0xbb5b,
0xbb86,0xbbb0,0xbbdb,0xbc05,0xbc30,0xbc5b,0xbc85,0xbcb0,
0xbcdb,0xbd06,0xbd30,0xbd5b,0xbd86,0xbdb1,0xbddc,0xbe07,
0xbe32,0xbe5e,0xbe89,0xbeb4,0xbedf,0xbf0a,0xbf36,0xbf61,
0xbf8d,0xbfb8,0xbfe3,0xc00f,0xc03b,0xc066,0xc092,0xc0bd,
0xc0e9,0xc115,0xc141,0xc16d,0xc198,0xc1c4,0xc1f0,0xc21c,
0xc248,0xc274,0xc2a0,0xc2cd,0xc2f9,0xc325,0xc351,0xc37d,
0xc3aa,0xc3d6,0xc402,0xc42f,0xc45b,0xc488,0xc4b4,0xc4e1,
0xc50e,0xc53a,0xc567,0xc594,0xc5c0,0xc5ed,0xc61a,0xc647,
0xc674,0xc6a0,0xc6cd,0xc6fa,0xc727,0xc755,0xc782,0xc7af,
0xc7dc,0xc809,0xc836,0xc864,0xc891,0xc8be,0xc8eb,0xc919,
0xc946,0xc974,0xc9a1,0xc9cf,0xc9fc,0xca2a,0xca58,0xca85,
0xcab3,0xcae1,0xcb0e,0xcb3c,0xcb6a,0xcb98,0xcbc6,0xcbf4,
0xcc21,0xcc4f,0xcc7d,0xccab,0xccda,0xcd08,0xcd36,0xcd64,
0xcd92,0xcdc0,0xcdef,0xce1d,0xce4b,0xce79,0xcea8,0xced6,
0xcf05,0xcf33,0xcf62,0xcf90,0xcfbf,0xcfed,0xd01c,0xd04a,
0xd079,0xd0a8,0xd0d6,0xd105,0xd134,0xd163,0xd192,0xd1c0,
0xd1ef,0xd21e,0xd24d,0xd27c,0xd2ab,0xd2da,0xd309,0xd338,
0xd367,0xd396,0xd3c6,0xd3f5,0xd424,0xd453,0xd483,0xd4b2,
0xd4e1,0xd510,0xd540,0xd56f,0xd59f,0xd5ce,0xd5fe,0xd62d,
0xd65d,0xd68c,0xd6bc,0xd6eb,0xd71b,0xd74b,0xd77a,0xd7aa,
0xd7da,0xd809,0xd839,0xd869,0xd899,0xd8c9,0xd8f8,0xd928,
0xd958,0xd988,0xd9b8,0xd9e8,0xda18,0xda48,0xda78,0xdaa8,
0xdad8,0xdb08,0xdb38,0xdb69,0xdb99,0xdbc9,0xdbf9,0xdc29,
0xdc5a,0xdc8a,0xdcba,0xdceb,0xdd1b,0xdd4b,0xdd7c,0xddac,
0xdddd,0xde0d,0xde3e,0xde6e,0xde9f,0xdecf,0xdf00,0xdf30,
0xdf61,0xdf91,0xdfc2,0xdff3,0xe023,0xe054,0xe085,0xe0b6,
0xe0e6,0xe117,0xe148,0xe179,0xe1a9,0xe1da,0xe20b,0xe23c,
0xe26d,0xe29e,0xe2cf,0xe300,0xe331,0xe362,0xe393,0xe3c4,
0xe3f5,0xe426,0xe457,0xe488,0xe4b9,0xe4ea,0xe51b,0xe54c,
0xe57e,0xe5af,0xe5e0,0xe611,0xe642,0xe674,0xe6a5,0xe6d6,
0xe707,0xe739,0xe76a,0xe79b,0xe7cd,0xe7fe,0xe830,0xe861,
0xe892,0xe8c4,0xe8f5,0xe927,0xe958,0xe98a,0xe9bb,0xe9ed,
0xea1e,0xea50,0xea81,0xeab3,0xeae4,0xeb16,0xeb47,0xeb79,
0xebab,0xebdc,0xec0e,0xec40,0xec71,0xeca3,0xecd5,0xed06,
0xed38,0xed6a,0xed9c,0xedcd,0xedff,0xee31,0xee63,0xee94,
0xeec6,0xeef8,0xef2a,0xef5c,0xef8e,0xefbf,0xeff1,0xf023,
0xf055,0xf087,0xf0b9,0xf0eb,0xf11d,0xf14f,0xf180,0xf1b2,
0xf1e4,0xf216,0xf248,0xf27a,0xf2ac,0xf2de,0xf310,0xf342,
0xf374,0xf3a6,0xf3d8,0xf40a,0xf43c,0xf46e,0xf4a1,0xf4d3,
0xf505,0xf537,0xf569,0xf59b,0xf5cd,0xf5ff,0xf631,0xf663,
0xf696,0xf6c8,0xf6fa,0xf72c,0xf75e,0xf790,0xf7c2,0xf7f5,
0xf827,0xf859,0xf88b,0xf8bd,0xf8ef,0xf922,0xf954,0xf986,
0xf9b8,0xf9ea,0xfa1d,0xfa4f,0xfa81,0xfab3,0xfae5,0xfb18,
0xfb4a,0xfb7c,0xfbae,0xfbe1,0xfc13,0xfc45,0xfc77,0xfcaa,
0xfcdc,0xfd0e,0xfd40,0xfd73,0xfda5,0xfdd7,0xfe09,0xfe3c,
0xfe6e,0xfea0,0xfed2,0xff05,0xff37,0xff69,0xff9b,0xffce
};
int intsin(int arg)
{
unsigned int u;
int p;
u = arg;
u &= 0xffff;
u >>= 4;
p = (signed short)sintbl[u];
return p;
}
int intcos(int arg)
{
return intsin(arg + 16384);
}

16
modules/Makefile Normal file
View File

@ -0,0 +1,16 @@
LDFLAGS=-lm
CFLAGS=-O2 -g -Wall -pedantic -I../include
MODULES = send_to_audio.o pulsegen.o sinegen.o replicate.o \
mod_scrambler.o modulator-V29.o fsk_demod.o fsk_mod.o \
decode_serial.o encode_serial.o debug.o
HELPERS = scrambler17.o
all: modules.a
modules.a: $(MODULES) $(HELPERS)
$(AR) rcs $@ $^
clean:
rm -f $(MODULES) *~

88
modules/debug.c Normal file
View File

@ -0,0 +1,88 @@
/* $Id$
******************************************************************************
Fax program for ISDN.
Debugging module. Take input stream and print it out to stderr.
Then pass it on.
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 <stdio.h>
#include <stdarg.h>
#include <ifax/ifax.h>
typedef struct {
/* How many bytes are there per "len" unit ? */
int bytes_per_sample;
} debug_private;
/* Free the private data
*/
void debug_destroy(ifax_modp self)
{
free(self->private);
return;
}
int debug_command(ifax_modp self,int cmd,va_list cmds)
{
return 0; /* Not yet used. */
}
int debug_handle(ifax_modp self, void *data, size_t length)
{
unsigned char *dat=data;
int handled=0;
int x;
debug_private *priv=(debug_private *)self->private;
while(handled<length) {
for (x=0;x<priv->bytes_per_sample;x++,dat++)
fprintf(stderr,"%2x(%c) ",*dat,*dat);
fprintf(stderr,"\n");
fflush(stderr);
handled++;
}
if (self->sendto)
ifax_handle_input(self->sendto,data,length);
return handled;
}
int debug_construct(ifax_modp self,va_list args)
{
debug_private *priv;
if (NULL==(priv=self->private=malloc(sizeof(debug_private))))
return 1;
self->destroy =debug_destroy;
self->handle_input =debug_handle;
self->command =debug_command;
priv->bytes_per_sample=va_arg(args,int);
return 0;
}

186
modules/decode_serial.c Normal file
View File

@ -0,0 +1,186 @@
/* $Id$
******************************************************************************
Fax program for ISDN.
Decoder for serial 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/stop bits.
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>
enum parity {
PAR_NONE,
PAR_ODD,
PAR_EVEN,
PAR_ONE,
PAR_ZERO
};
typedef struct {
int baud;
int bits;
int stopbits;
enum parity parity;
char lastbits[11];
int bitnum;
int sampcount;
} decode_serial_private;
/* Free the private data
*/
void decode_serial_destroy(ifax_modp self)
{
decode_serial_private *priv=(decode_serial_private *)self->private;
free(self->private);
return;
}
int decode_serial_command(ifax_modp self,int cmd,va_list cmds)
{
return 0; /* Not yet used. */
}
int decode_serial_handle(ifax_modp self, void *data, size_t length)
{
char *dat=data;
int currbit,currconf;
int x,result,handled,parity;
char hlpres;
decode_serial_private *priv=(decode_serial_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->bitnum==-1) {
if (currbit==1) continue;
priv->bitnum=0;
priv->sampcount=-SAMPLES_PER_SECOND/2/priv->baud;
} else
if ( priv->sampcount >= priv->bitnum*
SAMPLES_PER_SECOND/priv->baud)
{
if (priv->bitnum==0 && currbit!=0) {
priv->bitnum=-1;
continue; /* Garbage */
}
if (priv->bitnum==9 && currbit!=1) {
priv->bitnum=-1;
continue; /* Garbage */
}
priv->lastbits[priv->bitnum++]=currbit;
if (priv->bitnum >= 1+8+priv->stopbits) {
result=parity=0;
for (x=0;x<priv->bits;x++)
{
result|=priv->lastbits[x+1]<<x;
parity^=priv->lastbits[x+1];
}
// for (x=0;x<priv->bitnum;x++)
// printf("%d%s",priv->lastbits[x], (x==0 || x==8) ? " " : "");
priv->bitnum=-1;
switch(priv->parity) {
case PAR_NONE: parity=0;break;
case PAR_ODD: parity=(parity==priv->lastbits[8]);break;
case PAR_EVEN: parity=(parity!=priv->lastbits[8]);break;
case PAR_ONE: parity=(1!=priv->lastbits[8]);break;
case PAR_ZERO: parity=(0!=priv->lastbits[8]);break;
}
hlpres=result;
// printf(" %c\n",result);
if (parity==0 && self->sendto)
ifax_handle_input(self->sendto,&hlpres,1);
}
}
handled++;
}
return handled;
}
int decode_serial_construct(ifax_modp self,va_list args)
{
decode_serial_private *priv;
char *encode;
if (NULL==(priv=self->private=malloc(sizeof(decode_serial_private))))
return 1;
self->destroy =decode_serial_destroy;
self->handle_input =decode_serial_handle;
self->command =decode_serial_command;
priv->baud=va_arg(args,int);
encode =va_arg(args,char *);
switch(encode[0])
{
case '7': priv->bits=7;break;
default : fprintf(stderr,"not 7/8 bits !\n");
case '8': priv->bits=8;break;
}
switch(encode[1])
{
default : fprintf(stderr,"invalid parity specified !\n");
case 'N': case 'n': priv->parity=PAR_NONE;break;
case 'O': case 'o': priv->parity=PAR_ODD ;break;
case 'E': case 'e': priv->parity=PAR_EVEN;break;
case '1': priv->parity=PAR_ONE ;break;
case '0': priv->parity=PAR_ZERO;break;
}
switch(encode[2])
{
default : fprintf(stderr,"not 1/2 stopbits !\n");
case '1': priv->stopbits=1;break;
case '2': priv->stopbits=2;break;
}
priv->bitnum=-1; /* Init to "wait for 0->1" */
priv->sampcount=0;
return 0;
}

184
modules/encode_serial.c Normal file
View File

@ -0,0 +1,184 @@
/* $Id$
******************************************************************************
Fax program for ISDN.
Serial bits encoder. Takes bytes as input and generates 0/1 bytes at
SAMPLES_PER_SECOND. Take care not to overflow the input buffer.
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 <string.h>
#include <sys/times.h>
#include <ifax/ifax.h>
enum parity {
PAR_NONE,
PAR_ODD,
PAR_EVEN,
PAR_ONE,
PAR_ZERO
};
#define MAXBUFLEN 256
typedef struct {
int baud;
int bits;
int stopbits;
enum parity parity;
char lastbits[11];
int bitnum;
int sampcount;
char buffer[MAXBUFLEN];
int bufferlen;
} encode_serial_private;
/* Free the private data
*/
void encode_serial_destroy(ifax_modp self)
{
encode_serial_private *priv=(encode_serial_private *)self->private;
free(self->private);
return;
}
int encode_serial_command(ifax_modp self,int cmd,va_list cmds)
{
return 0; /* Not yet used. */
}
int encode_serial_handle(ifax_modp self, void *data, size_t length)
{
char *dat=data;
int x,handled,parity;
char hlpres;
encode_serial_private *priv=(encode_serial_private *)self->private;
handled=0;
while(length--) {
if (priv->bufferlen<MAXBUFLEN) {
priv->buffer[priv->bufferlen++]=*dat++;
handled++;
} else
fprintf(stderr,"encode_serial: buffer overrun.");
}
if (priv->bufferlen && priv->bitnum==-1)
{
priv->lastbits[0]=0; /* START BIT */
parity=0;
for(x=0;x<priv->bits;x++)
{
priv->lastbits[x+1]=((priv->buffer[0]&(1<<x))!=0);
parity^=priv->lastbits[x+1];
}
switch(priv->parity) {
case PAR_NONE: break;
case PAR_ODD: priv->lastbits[8]=!parity;break;
case PAR_EVEN: priv->lastbits[8]= parity;break;
case PAR_ONE: priv->lastbits[8]= 1 ;break;
case PAR_ZERO: priv->lastbits[8]= 0 ;break;
}
priv->lastbits[9]=1; /* STOP BIT */
priv->lastbits[10]=1; /* STOP BIT - maybe not used */
memmove(priv->buffer,priv->buffer+1,--priv->bufferlen);
priv->bitnum=0;
priv->sampcount=0;
}
hlpres=1; /* constant 1 for no activity */
if (priv->bitnum>=0)
{
hlpres=priv->lastbits[priv->bitnum];
priv->sampcount++;
if ( priv->sampcount >= (priv->bitnum+1)*
SAMPLES_PER_SECOND/priv->baud)
{
priv->bitnum++;
if (priv->bitnum>= 1+8+priv->stopbits)
priv->bitnum=-1;
}
}
ifax_handle_input(self->sendto,&hlpres,1);
return handled;
}
int encode_serial_construct(ifax_modp self,va_list args)
{
encode_serial_private *priv;
char *encode;
if (NULL==(priv=self->private=malloc(sizeof(encode_serial_private))))
return 1;
self->destroy =encode_serial_destroy;
self->handle_input =encode_serial_handle;
self->command =encode_serial_command;
priv->baud=va_arg(args,int);
encode =va_arg(args,char *);
switch(encode[0])
{
case '7': priv->bits=7;break;
default : fprintf(stderr,"not 7/8 bits !\n");
case '8': priv->bits=8;break;
}
switch(encode[1])
{
default : fprintf(stderr,"invalid parity specified !\n");
case 'N': case 'n': priv->parity=PAR_NONE;break;
case 'O': case 'o': priv->parity=PAR_ODD ;break;
case 'E': case 'e': priv->parity=PAR_EVEN;break;
case '1': priv->parity=PAR_ONE ;break;
case '0': priv->parity=PAR_ZERO;break;
}
switch(encode[2])
{
default : fprintf(stderr,"not 1/2 stopbits !\n");
case '1': priv->stopbits=1;break;
case '2': priv->stopbits=2;break;
}
priv->bitnum=-1; /* Init to "wait for 0->1" */
priv->sampcount=0;
priv->bufferlen=0;
return 0;
}

215
modules/fsk_demod.c Normal file
View File

@ -0,0 +1,215 @@
/* $Id$
******************************************************************************
Fax program for ISDN.
FSK demodulator. Takes alaw data and demodulates it to a stream of
0/1,conf pairs.
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>
/* Turn on to generate a big bunch of debugging code.
*/
#undef BIGDEBUG
typedef struct four_help {
int depth,depthsquare,currpos;
int currreal,currimag;
char *histreal,*histimag;
int stpos,ctpos,stdepth;
char *fasttable;
} four_help;
typedef struct {
four_help freq1,freq2;
int f1,f2;
int baud;
} fskdemod_private;
int gcd(int d1,int d2)
{
/* FIXME ! Is this correct ? Pretty long ago that I did that last time ... */
while(d1!=d2)
{
if (d1>d2) d1-=d2;
else d2-=d1;
}
dprintf(DEBUG_INFO,"GCD is %d\n",d1);
return d1;
}
/* The following do the DFT "on the fly" with a sliding window.
*/
static void init_four_help(four_help *hlp,int depth,int freq)
{
int x,y;
char *ftptr;
double sinval;
hlp->depth=depth;
hlp->depthsquare=depth*depth;
hlp->currpos=0;
hlp->currreal=hlp->currimag=0;
hlp->histreal=malloc(sizeof(hlp->histreal[0])*depth);
hlp->histimag=malloc(sizeof(hlp->histimag[0])*depth);
while(depth--)
hlp->histreal[depth]=
hlp->histimag[depth]=0;
x=gcd(freq,SAMPLES_PER_SECOND);x=SAMPLES_PER_SECOND/x;
if (x%4) {
fprintf(stderr,"fsk_demod: ERROR: sinetable size not divideable by 4.\n"
"Cosine shift is slighty incorrect.\n");
}
hlp->stdepth=256*x;
hlp->stpos=0;
hlp->ctpos=256*(x/4); /* The bracket _IS_ important. Do not optimize. */
hlp->fasttable=malloc(sizeof(hlp->fasttable[0])*hlp->stdepth);
ftptr=hlp->fasttable;
for(x=0;x<hlp->stdepth/256;x++)
{
sinval=sin(x*2.0*M_PI*(double)freq/(double)SAMPLES_PER_SECOND);
for(y=0;y<256;y++)
*ftptr++=((int)(sinval*alaw2int(y))) >>
((sizeof(int)-sizeof(char))*8);
}
}
/* Free the private data
*/
static void destroy_four_help(four_help *hlp)
{
free(hlp->histreal); hlp->histreal=NULL;
free(hlp->histimag); hlp->histimag=NULL;
free(hlp->fasttable);hlp->fasttable=NULL;
}
inline void add_samp(four_help *hlp,char sample)
{
hlp->currreal-=hlp->histreal[hlp->currpos];
hlp->currimag-=hlp->histimag[hlp->currpos];
hlp->currreal+=
(hlp->histreal[hlp->currpos]=hlp->fasttable[hlp->stpos+(unsigned char)sample]);
hlp->currimag+=
(hlp->histimag[hlp->currpos]=hlp->fasttable[hlp->ctpos+(unsigned char)sample]);
hlp->currpos++ ;if (hlp->currpos>=hlp->depth ) hlp->currpos=0;
hlp->stpos+=256;if (hlp->stpos >=hlp->stdepth) hlp->stpos=0;
hlp->ctpos+=256;if (hlp->ctpos >=hlp->stdepth) hlp->ctpos=0;
}
void fskdemod_destroy(ifax_modp self)
{
fskdemod_private *priv=(fskdemod_private *)self->private;
destroy_four_help(&priv->freq1);
destroy_four_help(&priv->freq2);
free(self->private);
return;
}
int fskdemod_command(ifax_modp self,int cmd,va_list cmds)
{
return 0; /* Not yet used. */
}
int fskdemod_handle(ifax_modp self, void *data, size_t length)
{
unsigned char dat[2];
char *input=data;
int a1,a2,conf,pwr;
int handled=0;
fskdemod_private *priv=(fskdemod_private *)self->private;
while(length--) {
add_samp(&priv->freq1,*input);
add_samp(&priv->freq2,*input);
input++;
a1=priv->freq1.currreal*priv->freq1.currreal+
priv->freq1.currimag*priv->freq1.currimag;
a2=priv->freq2.currreal*priv->freq2.currreal+
priv->freq2.currimag*priv->freq2.currimag;
#ifdef BIGDEBUG
printf("Power: %d: %8d, %d: %8d",
priv->f1,a1,priv->f2,a2);
#endif
if (!a2) a2=1;if (!a1) a1=1;
if (a1>a2) { conf=100-100*a2/a1; pwr=a1/priv->freq1.depthsquare; }
else { conf=100-100*a1/a2; pwr=a2/priv->freq2.depthsquare; }
#ifdef BIGDEBUG
printf(" dec: %d conf=%d pwr=%d\n",
a1 > a2 ? 1 : 0,
conf,
pwr );
#endif
dat[0]= a1 > a2 ? 1 : 0;
dat[1]= pwr<10 ? 0 : conf; /* Don't trust weak signals. */
ifax_handle_input(self->sendto,dat,1);
handled++;
}
return handled;
}
int fskdemod_construct(ifax_modp self,va_list args)
{
fskdemod_private *priv;
int sampbaud;
if (NULL==(priv=self->private=malloc(sizeof(fskdemod_private))))
return 1;
self->destroy =fskdemod_destroy;
self->handle_input =fskdemod_handle;
self->command =fskdemod_command;
priv->f1 =va_arg(args,int);
priv->f2 =va_arg(args,int);
priv->baud=va_arg(args,int);
sampbaud=(SAMPLES_PER_SECOND+priv->baud)/priv->baud;
init_four_help(&priv->freq1,sampbaud,priv->f1);
init_four_help(&priv->freq2,sampbaud,priv->f2);
return 0;
}

112
modules/fsk_mod.c Normal file
View File

@ -0,0 +1,112 @@
/* $Id$
******************************************************************************
Fax program for ISDN.
FSK modulator. This is a pretty simple one. It takes a stream of 0/1
and generates an FSK modulated signal.
BUGBUG: The output encoding isn't well defined. It is configured in the
source at the moment ...
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>
/* Turn on to generate a big bunch of debugging code.
*/
#undef BIGDEBUG
typedef struct {
int f1,f2;
double p1,p2;
double currphase;
} fskmod_private;
/* Free the private data
*/
void fskmod_destroy(ifax_modp self)
{
fskmod_private *priv=(fskmod_private *)self->private;
free(self->private);
return;
}
int fskmod_command(ifax_modp self,int cmd,va_list cmds)
{
return 0; /* Not yet used. */
}
int fskmod_handle(ifax_modp self, void *data, size_t length)
{
unsigned char dat;
char *input=data;
int handled=0;
fskmod_private *priv=(fskmod_private *)self->private;
while(length--) {
priv->currphase+= *input++ ? priv->p1 : priv->p2 ;
dat=int2alaw((int)(0.62*2147483647.0*sin(priv->currphase)));
// dat=linear2ulaw((short)(25000.0*sin(priv->currphase)));
#if 0
printf("Phases: %8.5f %11d %5d %11d %11d\n",sin(priv->currphase),
(int)(2147483647.0*sin(priv->currphase)),
dat, alaw2int(dat),
(int)(2147483647.0*sin(priv->currphase))-alaw2int(dat));
#endif
ifax_handle_input(self->sendto,&dat,1);
handled++;
}
return handled;
}
int fskmod_construct(ifax_modp self,va_list args)
{
fskmod_private *priv;
if (NULL==(priv=self->private=malloc(sizeof(fskmod_private))))
return 1;
self->destroy =fskmod_destroy;
self->handle_input =fskmod_handle;
self->command =fskmod_command;
priv->f1 =va_arg(args,int);
priv->f2 =va_arg(args,int);
priv->p1 =(double)2.0*M_PI * (double)priv->f1 / SAMPLES_PER_SECOND ;
priv->p2 =(double)2.0*M_PI * (double)priv->f2 / SAMPLES_PER_SECOND ;
priv->currphase=0.0;
printf("Phases : %f %f\n",priv->p1,priv->p2);
return 0;
}

84
modules/mod_scrambler.c Normal file
View File

@ -0,0 +1,84 @@
/* $Id$
******************************************************************************
Fax program for ISDN.
Scrambler.
Copyright (C) 1998 Morten Rolland [Morten.Rolland@asker.mail.telia.com]
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 <stdarg.h>
#include <ifax/ifax.h>
#include <ifax/modules/scrambler17.h>
#define MAXBUFFERING 256
typedef struct {
unsigned int state;
unsigned char buffer[MAXBUFFERING];
} scrambler_private;
/* Free the private data
*/
void scrambler_destroy(ifax_modp self)
{
free(self->private);
return;
}
int scrambler_command(ifax_modp self,int cmd,va_list cmds)
{
return 0;
}
int scrambler_handle(ifax_modp self, void *data, size_t length)
{
scrambler_private *priv=(scrambler_private *)self->private;
size_t chunk, remaining=length;
while ( remaining > 0 ) {
chunk = remaining;
if ( chunk > MAXBUFFERING )
chunk = MAXBUFFERING;
scramble17(data,priv->buffer,&priv->state,chunk);
ifax_handle_input(self->sendto,priv->buffer,chunk);
remaining -= chunk;
}
return length;
}
int scrambler_construct(ifax_modp self,va_list args)
{
scrambler_private *priv;
if (NULL==(priv=self->private=malloc(sizeof(scrambler_private))))
return 1;
self->destroy =scrambler_destroy;
self->handle_input =scrambler_handle;
self->command =scrambler_command;
priv->state=0;
return 0;
}

158
modules/modulator-V29.c Normal file
View File

@ -0,0 +1,158 @@
/* $Id$
******************************************************************************
Fax program for ISDN.
V.29 modulator.
Copyright (C) 1998 Morten Rolland [Morten.Rolland@asker.mail.telia.com]
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.
******************************************************************************
*/
/* modulator-V29.c
*
* Modulate a bitstream into 9600 bit/s according to V.29
*
* (C) 1998 Morten Rolland
*/
/* Bugs: Can only do 9600 */
#include <stdio.h>
#include <stdarg.h>
#include <ifax/ifax.h>
/* Samplerate and samples/symbol is closely related here */
#define SAMPLERATE 9600
#define SAMPLESPERSYMBOL 4
/* Carrier frequency */
#define CARRIERFREQ 1700
/* This is the delta-phase for the carrier */
#define SAMPLEPHASEINC ((0x10000*CARRIERFREQ)/SAMPLERATE)
#define MAXBUFFERING 128
typedef struct {
unsigned int prev_phase;
unsigned short w;
signed short buffer[MAXBUFFERING+2*SAMPLESPERSYMBOL];
/* unsigned char watingbits; (For use when symbol != 4 bits
int waitingbits_count; */
} modulator_V29_private;
unsigned char bits2phase[] = { 1,0,2,3,6,7,5,4 };
/* Free the private data
*/
void modulator_V29_destroy(ifax_modp self)
{
free(self->private);
return;
}
int modulator_V29_command(ifax_modp self,int cmd,va_list cmds)
{
return 0;
}
void modulate_symbol(unsigned char bits, signed short *dst,
unsigned int *prev_phase, unsigned short *w)
{
unsigned int p;
signed short wave, amp;
signed int sample;
int t;
p = (*prev_phase + bits2phase[bits>>1]) & 0x7;
*prev_phase = p;
fprintf(stderr,"%d\n",p*45);
if ( p & 1 ) {
/* 45 + 90*n */
if ( bits & 1 ) {
amp = 27798;
} else {
amp = 9266;
}
} else {
/* 0 + 90*n */
if ( bits & 1 ) {
amp = 32760;
} else {
amp = 19656;
}
}
p *= 0x2000;
for ( t=0; t < SAMPLESPERSYMBOL; t++ ) {
wave = intsin(*w + p);
sample = wave * amp;
sample /= 0x10000;
printf("%d\n",sample);
*dst++ = sample;
*w += SAMPLEPHASEINC;
}
}
int modulator_V29_handle(ifax_modp self, void *data, size_t length)
{
modulator_V29_private *priv=(modulator_V29_private *)self->private;
size_t chunk, remaining=length;
signed short *bp = priv->buffer;
unsigned char *dp = data;
int t;
while ( remaining > 0 ) {
chunk = remaining;
if ( chunk > MAXBUFFERING )
chunk = MAXBUFFERING;
for ( t=0; t < chunk; t++ ) {
modulate_symbol(dp[t]&0xf,bp,&priv->prev_phase,&priv->w);
bp += SAMPLESPERSYMBOL;
modulate_symbol(dp[t]>>4,bp,&priv->prev_phase,&priv->w);
bp += SAMPLESPERSYMBOL;
}
/* ifax_handle_input(self->sendto,priv->buffer,chunk); */
remaining -= chunk;
}
return length;
}
int modulator_V29_construct(ifax_modp self,va_list args)
{
modulator_V29_private *priv;
if (NULL==(priv=self->private=malloc(sizeof(modulator_V29_private))))
return 1;
self->destroy = modulator_V29_destroy;
self->handle_input = modulator_V29_handle;
self->command = modulator_V29_command;
priv->w = 0;
priv->prev_phase = 0;
return 0;
}

89
modules/pulsegen.c Normal file
View File

@ -0,0 +1,89 @@
/* $Id$
******************************************************************************
Fax program for ISDN.
Pulse generator. Takes a dummy input stream and generates a pulsed
output of 0/1.
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 <stdarg.h>
#include <ifax/ifax.h>
typedef struct {
int on,off;
int counter,state;
} pulsegen_private;
/* Free the private data
*/
void pulsegen_destroy(ifax_modp self)
{
free(self->private);
return;
}
int pulsegen_command(ifax_modp self,int cmd,va_list cmds)
{
return 0; /* Not yet used. */
}
int pulsegen_handle(ifax_modp self, void *data, size_t length)
{
unsigned char dat;
int handled=0;
pulsegen_private *priv=(pulsegen_private *)self->private;
while(length--) {
dat= priv->state ? 255 : 0;
if (--priv->counter==0) {
priv->state = !priv->state;
priv->counter = priv->state ? priv->on : priv->off ;
}
ifax_handle_input(self->sendto,&dat,1);
handled++;
}
return handled;
}
int pulsegen_construct(ifax_modp self,va_list args)
{
pulsegen_private *priv;
if (NULL==(priv=self->private=malloc(sizeof(pulsegen_private))))
return 1;
self->destroy =pulsegen_destroy;
self->handle_input =pulsegen_handle;
self->command =pulsegen_command;
priv->on =va_arg(args,int);
priv->off=va_arg(args,int);
priv->counter=priv->on; /* Start in the "on" state */
priv->state=1;
return 0;
}

94
modules/replicate.c Normal file
View File

@ -0,0 +1,94 @@
/* $Id$
******************************************************************************
Fax program for ISDN.
Replicator module. Gives incoming data to all attached modules.
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 <stdarg.h>
#include <math.h>
#include <ifax/ifax.h>
#include <ifax/modules/replicate.h>
#define MAXSUB 10
typedef struct {
int subnum;
ifax_modp subs[MAXSUB];
} replicate_private;
/* Free the private data
*/
void replicate_destroy(ifax_modp self)
{
free(self->private);
return;
}
int replicate_command(ifax_modp self,int cmd,va_list cmds)
{
replicate_private *priv=(replicate_private *)self->private;
switch(cmd)
{ case CMD_REPLICATE_ADD:
if (priv->subnum>=MAXSUB) return -1;
priv->subs[priv->subnum++]=va_arg(cmds,ifax_modp);
break;
case CMD_REPLICATE_DEL:
/* FIXME ! Search and destroy references */
{};
}
return 0; /* Not yet used. */
}
int replicate_handle(ifax_modp self, void *data, size_t length)
{
replicate_private *priv=(replicate_private *)self->private;
int rc,x;
rc=0;
for(x=0;x<priv->subnum;x++)
rc=ifax_handle_input(priv->subs[x],data,length);
if (self->sendto)
rc=ifax_handle_input(self->sendto,data,length);
return rc;
}
int replicate_construct(ifax_modp self,va_list args)
{
replicate_private *priv;
if (NULL==(priv=self->private=malloc(sizeof(replicate_private))))
return 1;
self->destroy =replicate_destroy;
self->handle_input =replicate_handle;
self->command =replicate_command;
priv->subnum=0;
return 0;
}

111
modules/scrambler17.c Normal file
View File

@ -0,0 +1,111 @@
/* $Id$
******************************************************************************
Fax program for ISDN.
Helper for scrambler module.
Copyright (C) 1998 Morten Rolland [Morten.Rolland@asker.mail.telia.com]
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.
******************************************************************************
*/
/* scrambler17.c
*
* Scramble/descramble a bitstream using a polynomial of
*
* 1 + x-18 + x-23
*
* As defined by the V.17 modulation standard.
*
* (C) 1998 Morten Rolland
*/
#include <ifax/ifax.h>
static unsigned char rotate_self[64] = {
0x00,0xfa,0x0f,0xf5,0x1f,0xe5,0x10,0xea,
0x3f,0xc5,0x30,0xca,0x20,0xda,0x2f,0xd5,
0x7e,0x84,0x71,0x8b,0x61,0x9b,0x6e,0x94,
0x41,0xbb,0x4e,0xb4,0x5e,0xa4,0x51,0xab,
0xfd,0x07,0xf2,0x08,0xe2,0x18,0xed,0x17,
0xc2,0x38,0xcd,0x37,0xdd,0x27,0xd2,0x28,
0x83,0x79,0x8c,0x76,0x9c,0x66,0x93,0x69,
0xbc,0x46,0xb3,0x49,0xa3,0x59,0xac,0x56
};
static unsigned char rotate_byte[256] = {
0x00,0xfd,0x7e,0x83,0x3f,0xc2,0x41,0xbc,
0x1f,0xe2,0x61,0x9c,0x20,0xdd,0x5e,0xa3,
0x0f,0xf2,0x71,0x8c,0x30,0xcd,0x4e,0xb3,
0x10,0xed,0x6e,0x93,0x2f,0xd2,0x51,0xac,
0x07,0xfa,0x79,0x84,0x38,0xc5,0x46,0xbb,
0x18,0xe5,0x66,0x9b,0x27,0xda,0x59,0xa4,
0x08,0xf5,0x76,0x8b,0x37,0xca,0x49,0xb4,
0x17,0xea,0x69,0x94,0x28,0xd5,0x56,0xab,
0x03,0xfe,0x7d,0x80,0x3c,0xc1,0x42,0xbf,
0x1c,0xe1,0x62,0x9f,0x23,0xde,0x5d,0xa0,
0x0c,0xf1,0x72,0x8f,0x33,0xce,0x4d,0xb0,
0x13,0xee,0x6d,0x90,0x2c,0xd1,0x52,0xaf,
0x04,0xf9,0x7a,0x87,0x3b,0xc6,0x45,0xb8,
0x1b,0xe6,0x65,0x98,0x24,0xd9,0x5a,0xa7,
0x0b,0xf6,0x75,0x88,0x34,0xc9,0x4a,0xb7,
0x14,0xe9,0x6a,0x97,0x2b,0xd6,0x55,0xa8,
0x01,0xfc,0x7f,0x82,0x3e,0xc3,0x40,0xbd,
0x1e,0xe3,0x60,0x9d,0x21,0xdc,0x5f,0xa2,
0x0e,0xf3,0x70,0x8d,0x31,0xcc,0x4f,0xb2,
0x11,0xec,0x6f,0x92,0x2e,0xd3,0x50,0xad,
0x06,0xfb,0x78,0x85,0x39,0xc4,0x47,0xba,
0x19,0xe4,0x67,0x9a,0x26,0xdb,0x58,0xa5,
0x09,0xf4,0x77,0x8a,0x36,0xcb,0x48,0xb5,
0x16,0xeb,0x68,0x95,0x29,0xd4,0x57,0xaa,
0x02,0xff,0x7c,0x81,0x3d,0xc0,0x43,0xbe,
0x1d,0xe0,0x63,0x9e,0x22,0xdf,0x5c,0xa1,
0x0d,0xf0,0x73,0x8e,0x32,0xcf,0x4c,0xb1,
0x12,0xef,0x6c,0x91,0x2d,0xd0,0x53,0xae,
0x05,0xf8,0x7b,0x86,0x3a,0xc7,0x44,0xb9,
0x1a,0xe7,0x64,0x99,0x25,0xd8,0x5b,0xa6,
0x0a,0xf7,0x74,0x89,0x35,0xc8,0x4b,0xb6,
0x15,0xe8,0x6b,0x96,0x2a,0xd7,0x54,0xa9
};
/* scramble a series of bytes from source (s) to destination (d) buffer.
* The state is used and updated, and buffer size is in *bytes*.
* First bit to pass through the scrambling is bit 0 of s[0], and
* the last is bit 7 of s[size-1].
* First bit to pop out of the scrambling is bit 0 of d[0] etc.
*/
void scramble17(unsigned char *s, unsigned char *d,
unsigned int *state, int size)
{
unsigned char next;
unsigned int st;
st = *state;
while ( size-- ) {
next = rotate_self[st&0x3f] ^
rotate_byte[*s] ^
rotate_byte[bitrev((st>>16)&0xff)];
st = (st<<8) | next;
*d = bitrev(next);
s++, d++;
}
*state = st;
}

67
modules/send_to_audio.c Normal file
View File

@ -0,0 +1,67 @@
/* $Id$
******************************************************************************
Fax program for ISDN.
Send the received data to a write()-compatible function.
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 <stdarg.h>
#include <ifax/ifax.h>
typedef int (*auw)(int handle,void *ptr,size_t length);
typedef struct {
auw audio_write;
int handle;
} send_to_audio_private;
/* Free the private data
*/
void send_to_audio_destroy(ifax_modp self)
{
free(self->private);
return;
}
int send_to_audio_handle(ifax_modp self, void *data, size_t length)
{
send_to_audio_private *priv=(send_to_audio_private *)self->private;
return priv->audio_write(priv->handle,data,length);
}
int send_to_audio_construct(ifax_modp self,va_list args)
{
send_to_audio_private *priv;
if (NULL==(priv=self->private=malloc(sizeof(send_to_audio_private))))
return 1;
self->destroy =send_to_audio_destroy;
self->handle_input =send_to_audio_handle;
self->command =NULL;
priv->audio_write=va_arg(args,auw);
priv->handle =va_arg(args,int);
return 0;
}

86
modules/sinegen.c Normal file
View File

@ -0,0 +1,86 @@
/* $Id$
******************************************************************************
Fax program for ISDN.
Sine generator. Create an aLaw encoded sine pattern.
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 <stdarg.h>
#include <math.h>
#include <ifax/ifax.h>
typedef struct {
double step;
double currphase;
} sinegen_private;
void sinegen_destroy(ifax_modp self)
{
free(self->private);
return;
}
int sinegen_command(ifax_modp self,int cmd,va_list cmds)
{
return 0; /* Not yet used. */
}
int sinegen_handle(ifax_modp self, void *data, size_t length)
{
unsigned char *dat=data;
unsigned char out;
int handled=0;
sinegen_private *priv=(sinegen_private *)self->private;
while(length--) {
out=int2alaw(2147483647*(*dat/255)*sin(priv->currphase));
priv->currphase+=priv->step;
ifax_handle_input(self->sendto,&out,1);
handled++;
}
return handled;
}
int sinegen_construct(ifax_modp self,va_list args)
{
sinegen_private *priv;
int frequency;
if (NULL==(priv=self->private=malloc(sizeof(sinegen_private))))
return 1;
self->destroy =sinegen_destroy;
self->handle_input =sinegen_handle;
self->command =sinegen_command;
frequency=va_arg(args,int);
priv->step=2.0*M_PI*(double)frequency/SAMPLES_PER_SECOND;
priv->currphase=0.0;
return 0;
}

130
test.c Normal file
View File

@ -0,0 +1,130 @@
/* $Id$
******************************************************************************
Fax program for ISDN.
Copyright (C) 1998 Andreas Beck [becka@ggi-project.org]
Copyright (C) 1998 Morten Rolland [Morten.Rolland@asker.mail.telia.com]
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 <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/time.h>
#include <sys/types.h>
#include <ifax/ifax.h>
int send_to_audio_construct(ifax_modp self,va_list args);
int pulsegen_construct(ifax_modp self,va_list args);
int sinegen_construct(ifax_modp self,va_list args);
int scrambler_construct(ifax_modp self, va_list args);
int modulator_V29_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 encode_serial_construct(ifax_modp self, va_list args);
int debug_construct(ifax_modp self, va_list args);
#include <ifax/modules/replicate.h>
ifax_module_id IFAX_TOAUDIO;
ifax_module_id IFAX_PULSEGEN;
ifax_module_id IFAX_SINEGEN;
ifax_module_id IFAX_REPLICATE;
ifax_module_id IFAX_SCRAMBLER;
ifax_module_id IFAX_MODULATORV29;
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_DEBUG;
void setup_all_modules(void)
{
IFAX_TOAUDIO = ifax_register_module_class("Audio output",send_to_audio_construct);
IFAX_PULSEGEN = ifax_register_module_class("Square wave generator",pulsegen_construct);
IFAX_SINEGEN = ifax_register_module_class("Sine wave generator",sinegen_construct);
IFAX_REPLICATE = ifax_register_module_class("Replicator",replicate_construct);
IFAX_FSKDEMOD = ifax_register_module_class("FSK demodulator",fskdemod_construct);
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_SCRAMBLER = ifax_register_module_class("Bitstream scrambler",scrambler_construct);
IFAX_MODULATORV29 = ifax_register_module_class("V.29 Modulator 9600",modulator_V29_construct);
IFAX_DEBUG = ifax_register_module_class("Debugger",debug_construct);
}
void transmit_carrier(void)
{
ifax_modp toaudio,square,sine,replicate;
char data;
int cnt;
/* Replicate the incoming signal. */
replicate=ifax_create_module(IFAX_REPLICATE);
/* Generate an square wave of 0.5s on, 3s off - CNG */
square=ifax_create_module(IFAX_PULSEGEN, SAMPLES_PER_SECOND/2,
3*SAMPLES_PER_SECOND);
/* Generate 1100Hz */
sine=ifax_create_module(IFAX_SINEGEN, 1100);
/* Test - go to stdout */
toaudio=ifax_create_module(IFAX_TOAUDIO, write, 1);
ifax_command(replicate,CMD_REPLICATE_ADD,square);
square->sendto=sine;
sine ->sendto=toaudio;
/* Feed in dummy input data. */
for(cnt=0;cnt<10*SAMPLES_PER_SECOND;cnt++)
ifax_handle_input(replicate,&data,1);
}
void test_modulator(void)
{
ifax_modp scrambler, modulator;
unsigned char data;
/* Test scrambler as a module */
scrambler = ifax_create_module(IFAX_SCRAMBLER);
/* Modulate into signed shorts */
modulator = ifax_create_module(IFAX_MODULATORV29);
scrambler->sendto = modulator;
/* Count from 0 to 20 and see what the scrambler/modulator says */
for ( data=0; data <= 20; data++ )
ifax_handle_input(scrambler,&data,1);
}
void main(int argc,char **argv)
{
setup_all_modules();
transmit_carrier();
}

341
v21_softmodem.c Normal file
View File

@ -0,0 +1,341 @@
/* $Id$
******************************************************************************
Fax program for ISDN.
V21 Softmodem implementation.
Copyright (C) 1998 Andreas Beck [becka@ggi-project.org]
Copyright (C) 1998 Morten Rolland [Morten.Rolland@asker.mail.telia.com]
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 <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <unistd.h>
#include <getopt.h>
#include <fcntl.h>
#include <sys/time.h>
#include <sys/types.h>
#include <ifax/ifax.h>
/* Prototypes for all the modules. We should probably move them to a big
* bunch of .h files.
*/
int send_to_audio_construct(ifax_modp self,va_list args);
int pulsegen_construct(ifax_modp self,va_list args);
int sinegen_construct(ifax_modp self,va_list args);
int scrambler_construct(ifax_modp self, va_list args);
int modulator_V29_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 encode_serial_construct(ifax_modp self, va_list args);
int debug_construct(ifax_modp self, va_list args);
#include <ifax/modules/replicate.h>
/* Module-IDs for all the modules. Needed for instantiating them.
*/
ifax_module_id IFAX_TOAUDIO;
ifax_module_id IFAX_REPLICATE;
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_DEBUG;
/* Register all needed modules.
*/
static void setup_all_modules(void)
{
IFAX_TOAUDIO = ifax_register_module_class("Audio output",send_to_audio_construct);
IFAX_REPLICATE = ifax_register_module_class("Replicator",replicate_construct);
IFAX_FSKDEMOD = ifax_register_module_class("FSK demodulator",fskdemod_construct);
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_DEBUG = ifax_register_module_class("Debugger",debug_construct);
}
/* Handles for the ISDN device, and the in- and output.
*/
static int isdnhandle=-1;
static int inputhandle=0;
static int outputhandle=1;
/* The actual "modem" code.
*/
static void test_v21(void)
{
/* module handles for all used modules.
*/
ifax_modp fskd,fskenc,toisdn,totty,deserial,enserial;
/* helper for data in-/output
*/
char data;
/* helper to avoid overflowing the send buffer.
*/
int wait;
/* The lines below are commented out. They were once used
* for debugging.
*/
#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
/* Output wave to ISDN
*/
toisdn=ifax_create_module(IFAX_TOAUDIO, IsdnSendAudio, isdnhandle);
/* The FSK modulator. Its output is send to the ISDN line.
*/
fskenc=ifax_create_module(IFAX_FSKMOD,980,1180);
fskenc->sendto=toisdn;
/* The serializer. Its output is sent to the FSK modulator.
* These three modules make up the sender.
*/
enserial=ifax_create_module(IFAX_ENCODE_SERIAL,300,"8N1");
enserial->sendto=fskenc;
/* Now for the receiver. When all is decoded, the text is sent
* to the outputhandle.
*/
totty=ifax_create_module(IFAX_TOAUDIO, write, 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.
*/
deserial=ifax_create_module(IFAX_DECODE_SERIAL,300,"8N1");
deserial->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=deserial;
/* The first two seconds are reserved to send a steady carrier.
* No output is made until the "wait" variable is down to zero.
*/
wait=2*SAMPLES_PER_SECOND; /* 2s steady carrier ! */
/* Run until explicitly terminated.
*/
while(1) {
/* helpers for select()ing on input.
*/
struct timeval tv={0,0};
fd_set rfds;
/* Count down wait.
*/
if (wait) wait--;
/* Prepare for select()ing on input. If wait() is still
* active, don't ask for input.
*/
FD_ZERO(&rfds);
FD_SET(inputhandle,&rfds);
if (!wait && select(inputhandle+1,&rfds,NULL,NULL,&tv)>0)
{
/* Send the received data.
*/
ifax_handle_input(enserial,&data,
read(inputhandle,&data,1));
/* Wait for 11 bits (plus a little extra space).
* Avoid overflowing the send buffer.
* FIXME. We should rather check the return code.
*/
wait=11*SAMPLES_PER_SECOND/300+100;
} else
/* Send a dummy packet, to keep the sender going.
*/
ifax_handle_input(enserial,&data,0);
/* Read data from isdn4linux.
*/
IsdnReadAudio(isdnhandle,&data,1);
/* Send it to the demodulator.
*/
ifax_handle_input(fskd,&data,1);
}
}
/* A function that more or less implements the "ATZ" function of a modem.
*/
void setup_isdn(char *sourcemsn)
{
char cmdbuffer[128];
/* Set up the MSN.
*/
sprintf(cmdbuffer,"AT&E%s",sourcemsn);
IsdnCommand(isdnhandle,cmdbuffer,1,1);
/* Go to VOICE mode.
*/
IsdnCommand(isdnhandle,"AT+FCLASS=8",1,1);
/* Set the service identifier to "audio".
*/
IsdnCommand(isdnhandle,"ATS18=1",1,1); /* service == audio */
/* Set the data format to aLaw, and the device to "phone-line".
*/
IsdnCommand(isdnhandle,"AT+VSM=5+VLS=2",1,1);
}
/* A function that more or less implements the "ATDxxx" function of a modem.
*/
void dial_isdn(char *number)
{
char cmdbuffer[128];
/* Dial the given number.
*/
sprintf(cmdbuffer,"ATD%s",number);
IsdnCommand(isdnhandle,cmdbuffer,1,1);
/* Set up the packet size.
*/
IsdnCommand(isdnhandle,"ATS16=48",1,1); /* Sendpacketsize/16 WHY ??? */
/* Start full duplex audio transmission.
*/
IsdnCommand(isdnhandle,"AT+VTX+VRX",1,0);
}
/* A function that more or less implements the "ATA" function of a modem.
*/
void answer_isdn(void)
{
/* Answer the pending call - hope there is one ...
*/
IsdnCommand(isdnhandle,"ATA",1,1);
/* Set up the packet size.
*/
IsdnCommand(isdnhandle,"ATS16=48",1,1); /* Sendpacketsize/16 WHY ??? */
/* Start full duplex audio transmission.
*/
IsdnCommand(isdnhandle,"AT+VTX+VRX",1,0);
}
/* Print out how to use this program.
*/
void usage(char *prgnam)
{
printf("Usage: %s [-i isdndevice] -m MSN\n",prgnam);
}
/* Main program. Get the arguments and set everything up.
* It _should_ then open a pty and emulate a modem there.
* This is not yet implemented. It just calls out and connects.
*/
void main(int argc,char **argv)
{
/* Remember the character we get from getopts().
*/
int optchr;
/* Defaults for the options. We cannot guess an MSN, so this is
* an error, if it remains unset.
*/
char *isdndevname="/dev/ttyI1";
char *numbertodial=NULL;
char *sourcemsn=NULL;
/* Register all the modules.
*/
setup_all_modules();
/* Get all options from the commandline.
*/
while(EOF!=(optchr=getopt(argc,argv,"i:m:d:")))
{
switch(optchr)
{
case 'i':
/* Device name for IsdnOpenDevice.
*/
isdndevname=optarg;
break;
case 'm':
/* The MSN to use as source-MSN. Or for
* incoming calls, the one to listen for.
*/
sourcemsn=optarg;
break;
case 'd':
/* The number to dial.
*/
numbertodial=optarg;
break;
}
}
/* We cannot guess an MSN.
*/
if (!sourcemsn) {
usage(argv[0]);
exit(1);
}
/* Open the ISDN device
*/
if (-1==(isdnhandle=IsdnOpenDevice(isdndevname)))
{
fprintf(stderr,"%s: cannot open isdn-device %s.\n",argv[0],isdndevname);
exit(1);
}
/* Set it up.
*/
setup_isdn(sourcemsn);
/* Call the remote station.
*/
dial_isdn(numbertodial);
/* Go to transfer mode.
*/
test_v21();
/* Clean up and exit.
*/
close(isdnhandle);
}