initial commit

This commit is contained in:
Dan Bastone committed 2021-10-29 14:41:03 -04:00
commit 636959b37b
2474 files changed
+1343178

No files matched your search

+34
View File
@@ -0,0 +1,34 @@
/*
*
* Copyright (c) 2001, Smart Link Ltd.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* 3. Neither the name of the Smart Link Ltd. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
+92
View File
@@ -0,0 +1,92 @@
###########################################################################
#
#
# Makefile -- modem application Makefile.
#
# Copyright(c) 2003, Smart Link Ltd. (www.smlink.com)
# All rights reserved.
#
# Author: Sasha K (sashak@smlink.com)
#
#
###########################################################################
#
###########################################################################
ARCH64:=$(shell uname -m | sed -e '/amd64/s//x86_64/' | grep -c x86_64)
ifeq ($(ARCH64), 0)
CC:= gcc
else
# SUPPORT_ALSA:=1
CC:= gcc -m32
endif
RM:= rm -f
CFLAGS+= -Wall -g -O -I. -DCONFIG_DEBUG_MODEM
modem-objs:= \
modem.o modem_datafile.o modem_at.o modem_timer.o \
modem_pack.o modem_ec.o modem_comp.o \
modem_param.o modem_debug.o homolog_data.o
dp-objs:= dp_sinus.o dp_dummy.o
sysdep-objs:= sysdep_common.o
all-objs:= modem_cmdline.o $(modem-objs) $(dp-objs) dsplibs.o $(sysdep-objs)
all: slmodemd modem_test
slmodemd: modem_main.o $(all-objs)
modem_test: modem_test.o $(all-objs)
ifdef SUPPORT_ALSA
CFLAGS+= -DSUPPORT_ALSA=1
ifeq ($(ARCH64), 0)
LFLAGS+= /usr/lib/libasound.so
else
# LFLAGS+= /usr/lib32/libasound.so , replaced by -l commands search for asound
LFLAGS+= -lasound
endif
endif
slmodemd:
$(CC) -o slmodemd modem_main.o $(all-objs) $(LFLAGS)
modem_test:
$(CC) -o modem_test modem_test.o $(all-objs) $(LFLAGS)
clean:
$(RM) slmodemd modem_test modem_main.o modem_cmdline.o modem_test.o $(modem-objs) $(dp-objs) $(sysdep-objs)
$(RM) *~ *.orig *.rej
.PHONY: all dep generic-dep clean clean-build-profile
#
# rules
#
%.o: %.c .build_profile
$(CC) $(CFLAGS) $(CPPFLAGS) $(EXTRA_CFLAGS) $(CFLAGS_$@) -o $@ -c $<
dep: generic-dep
generic-dep:
$(RM) .depend
$(foreach src,$(wildcard *.c),$(CC) -M $(CFLAGS) $(EXTRA_CFLAGS) $(CFLAGS_$(src:.c=.o)) -c $(src) >> .depend ;)
-include .depend
# build_profile
-include .build_profile
.build_profile::
ifneq ($(CFLAGS),$(PROFILE_CFLAGS))
@if [ "$(CFLAGS) $(EXTRA_CFLAGS)" != "$(PROFILE_CFLAGS)" ] ; then \
echo "rebuild profile..." ; \
echo "PROFILE_CFLAGS=$(CFLAGS) $(EXTRA_CFLAGS)" > $(@) ; fi
endif
clean: clean-build-profile
clean-build-profile:
@$(RM) -f .build_profile
+92
View File
@@ -0,0 +1,92 @@
###########################################################################
#
#
# Makefile -- modem application Makefile.
#
# Copyright(c) 2003, Smart Link Ltd. (www.smlink.com)
# All rights reserved.
#
# Author: Sasha K (sashak@smlink.com)
#
#
###########################################################################
#
###########################################################################
ARCH64:=$(shell uname -m | sed -e '/amd64/s//x86_64/' | grep -c x86_64)
ifeq ($(ARCH64), 0)
CC:= gcc
else
# SUPPORT_ALSA:=1
CC:= gcc -m32
endif
RM:= rm -f
CFLAGS+= -Wall -g -O -I. -DCONFIG_DEBUG_MODEM
modem-objs:= \
modem.o modem_datafile.o modem_at.o modem_timer.o \
modem_pack.o modem_ec.o modem_comp.o \
modem_param.o modem_debug.o homolog_data.o
dp-objs:= dp_sinus.o dp_dummy.o
sysdep-objs:= sysdep_common.o
all-objs:= modem_cmdline.o $(modem-objs) $(dp-objs) dsplibs.o $(sysdep-objs)
all: slmodemd modem_test
slmodemd: modem_main.o $(all-objs)
modem_test: modem_test.o $(all-objs)
ifdef SUPPORT_ALSA
CFLAGS+= -DSUPPORT_ALSA=1
ifeq ($(ARCH64), 0)
LFLAGS+= /usr/lib/libasound.so
else
# LFLAGS+= /usr/lib32/libasound.so , replaced by -l commands search for asound
LFLAGS+= -lasound
endif
endif
slmodemd:
$(CC) -o slmodemd modem_main.o $(all-objs) $(LFLAGS)
modem_test:
$(CC) -o modem_test modem_test.o $(all-objs) $(LFLAGS)
clean:
$(RM) slmodemd modem_test modem_main.o modem_cmdline.o modem_test.o $(modem-objs) $(dp-objs) $(sysdep-objs)
$(RM) *~ *.orig *.rej
.PHONY: all dep generic-dep clean clean-build-profile
#
# rules
#
%.o: %.c .build_profile
$(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(CFLAGS_$@) -o $@ -c $<
dep: generic-dep
generic-dep:
$(RM) .depend
$(foreach src,$(wildcard *.c),$(CC) -M $(CFLAGS) $(EXTRA_CFLAGS) $(CFLAGS_$(src:.c=.o)) -c $(src) >> .depend ;)
-include .depend
# build_profile
-include .build_profile
.build_profile::
ifneq ($(CFLAGS),$(PROFILE_CFLAGS))
@if [ "$(CFLAGS) $(EXTRA_CFLAGS)" != "$(PROFILE_CFLAGS)" ] ; then \
echo "rebuild profile..." ; \
echo "PROFILE_CFLAGS=$(CFLAGS) $(EXTRA_CFLAGS)" > $(@) ; fi
endif
clean: clean-build-profile
clean-build-profile:
@$(RM) -f .build_profile
+153
View File
@@ -0,0 +1,153 @@
/*
*
* Copyright (c) 2002, Smart Link Ltd.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* 3. Neither the name of the Smart Link Ltd. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/*
*
* dp_dummy.c -- dummy data pump (very stupid simulator).
*
* Author: Sasha K (sashak@smlink.com)
*
*
*/
#include <modem.h>
#include <modem_debug.h>
#define DUMMY_SKIP 100
#define DUMMY_TIMEOUT 300
#define DUMMY_A1 0xff
struct dummy_dp {
struct dp dp;
unsigned long count;
unsigned long linked;
u8 buf[1024];
void *dcr;
};
static struct dp *dummy_create(struct modem *m, enum DP_ID id,
int caller, int srate, int max_frag,
struct dp_operations *op)
{
struct dummy_dp *d;
dprintf("dummy_create...\n");
d = malloc(sizeof(*d));
memset(d,0,sizeof(*d));
d->dp.id = id;
d->dp.modem = m;
d->dp.op = op;
d->dp.dp_data = d;
d->dcr = m->dcr;
m->dcr = NULL;
return (struct dp *)d;
}
static int dummy_delete(struct dp *dp)
{
struct dummy_dp *d = (struct dummy_dp *)dp;
dprintf("dummy_delete...\n");
dp->modem->dcr = d->dcr;
free(d);
return 0;
}
static int dummy_process(struct dp *dp, void *in, void *out, int cnt)
{
struct dummy_dp *d = (struct dummy_dp *)dp;
int n = cnt << MFMT_SHIFT(dp->modem->format);
s16 *s;
int i;
d->count++;
if (!d->linked) {
if (d->count < DUMMY_SKIP) {
memset(out,0,n);
return DPSTAT_OK;
}
else if(d->count > DUMMY_TIMEOUT)
return DPSTAT_ERROR;
s = out;
for(i = 0 ; i < cnt ; i++) {
*s = (1-2*(i&1))*('A');
s++;
}
s = in;
for(i = 0 ; i < cnt ; i++) {
if(abs(*s) == 'A') {
d->linked = 1;
return DPSTAT_CONNECT;
}
s++;
}
}
else {
s = in;
for(i = 0 ; i < cnt ; i++) {
d->buf[i] = *s&0x1;
s++;
}
modem_put_bits(dp->modem,1,d->buf,cnt);
s = out;
modem_get_bits(dp->modem,1,d->buf,cnt);
for(i = 0 ; i < cnt ; i++) {
*s = d->buf[i]&1 ;
s++;
}
}
return DPSTAT_OK;
}
static struct dp_operations dummy_operations = {
name : "Dummy DataPump driver",
create: dummy_create,
delete: dummy_delete,
process:dummy_process
};
int dp_dummy_init(void)
{
return modem_dp_register(DP_DUMMY,&dummy_operations);
}
void dp_dummy_exit(void)
{
modem_dp_deregister(DP_DUMMY,&dummy_operations);
}
+133
View File
@@ -0,0 +1,133 @@
/*
*
* Copyright (c) 2002, Smart Link Ltd.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* 3. Neither the name of the Smart Link Ltd. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/*
*
* sinus.c -- sinus data pump.
*
* Author: Sasha K (sashak@smlink.com)
*
*
*/
#include <modem.h>
#include <modem_debug.h>
#ifdef __KERNEL__
#define malloc(size) kmalloc(size,GFP_KERNEL)
#define free(mem) kfree(mem)
#endif
#define SIN_AMPLITUDE 16384
#define SIN_PERIOD (sizeof(sintab)/sizeof(sintab[0]))
static
const s16 sintab[] = {
0, 3196, 6269, 9102, 11585, 13622, 15136, 16069,
16384, 16069, 15136, 13622, 11585, 9102, 6269, 3196,
0, -3196, -6269, -9102, -11585, -13622, -15136, -16069,
-16384, -16069, -15136, -13622, -11585, -9102, -6269, -3196};
#define SIN_DBG(fmt,arg...) dprintf("sin: " fmt , ##arg)
struct sin_state {
struct dp dp;
int count;
int linked;
u8 buf[1024];
int amp;
unsigned period;
unsigned phase;
};
static struct dp *sin_create(struct modem *m, enum DP_ID id,
int caller, int srate, int max_frag,
struct dp_operations *op)
{
struct sin_state *s;
SIN_DBG("create...\n");
s = malloc(sizeof(*s));
if (!s) return NULL;
memset(s,0,sizeof(*s));
s->dp.id = id;
s->dp.modem = m;
s->dp.op = op;
s->dp.dp_data = s;
s->phase = 0;
s->amp = SIN_AMPLITUDE;
s->period= SIN_PERIOD;
return &s->dp;
}
static int sin_delete(struct dp *dp)
{
struct sin_state *s = dp->dp_data;
SIN_DBG("delete...\n");
free(s);
return 0;
}
static int sin_run(struct dp *dp, void *in, void *out, int cnt)
{
struct sin_state *s = dp->dp_data;
s16 *smpl = out;
int i;
//SIN_DBG("run...\n");
for (i=0;i<cnt;i++) {
smpl[i] = sintab[s->phase%SIN_PERIOD];
s->phase = s->phase+1;
}
return DPSTAT_OK;
}
static struct dp_operations sin_operations = {
name : "Sinus DP driver",
create: sin_create,
delete: sin_delete,
process:sin_run
};
int dp_sinus_init(void)
{
return modem_dp_register(DP_SINUS,&sin_operations);
}
void dp_sinus_exit(void)
{
modem_dp_deregister(DP_SINUS,&sin_operations);
}
Binary file not shown.
+131
View File
@@ -0,0 +1,131 @@
/* generated at Jun 1 2004 19:11:22 */
#include <modem.h>
#include <modem_homolog.h>
static const struct homolog_params params000 = {0x22,0x43,0x01,0x08,0x5a,0x28,0x3f,0x02,0x25,0x3f,0x00,0x1b,0x02,0x09,0x01,0x10,0x02,0x01,0x2b,0x00,0x1e,0x00,0x50,0x04,0x00,0x00,0x00,0x029a,0x00,};
static const struct homolog_params params001 = {0x24,0x40,0x01,0x06,0x64,0x12,0x3c,0x04,0x12,0x3c,0x00,0x32,0x02,0x0a,0x00,0x19,0x02,0x05,0x2b,0x00,0xff,0x06,0x50,0x02,0x00,0x00,0x00,0x029a,0x00,};
static const struct homolog_params params002 = {0x21,0x43,0x01,0x08,0x5a,0x23,0x27,0x04,0x23,0x27,0x00,0x09,0x02,0x09,0x00,0x19,0x02,0x01,0x2b,0x00,0x1e,0x00,0x50,0x04,0x00,0x00,0x00,0x029a,0x00,};
static const struct homolog_params params003 = {0x28,0x3c,0x01,0x08,0x5a,0x00,0x00,0x02,0x00,0x00,0x00,0x09,0x04,0x09,0x01,0x08,0x02,0x06,0x2d,0x00,0x1e,0x00,0x50,0x04,0x00,0x00,0x00,0x029a,0x00,};
static const struct homolog_params params005 = {0x21,0x43,0x01,0x08,0x5a,0x00,0x00,0x04,0x00,0x00,0x00,0x0c,0x04,0x09,0x01,0x07,0x02,0x04,0x2b,0x00,0x1e,0x00,0x50,0x04,0x00,0x00,0x00,0x029a,0x00,};
static const struct homolog_params params006 = {0x24,0x40,0x01,0x06,0x64,0x12,0x50,0x04,0x12,0x50,0x00,0x32,0x02,0x0a,0x00,0x19,0x02,0x05,0x2b,0x00,0xff,0x00,0x50,0x02,0x00,0x00,0x00,0x029a,0x00,};
static const struct homolog_params params007 = {0x21,0x43,0x01,0x06,0x69,0x2a,0x50,0x04,0x2a,0x50,0x00,0x3c,0x02,0x0a,0x00,0x19,0x02,0x01,0x2b,0x00,0x1e,0x00,0x50,0x03,0x00,0x00,0x00,0x029a,0x00,};
static const struct homolog_params params008 = {0x28,0x3c,0x01,0x08,0x5a,0x00,0x00,0x04,0x00,0x00,0x00,0x07,0x04,0x09,0x00,0x02,0x02,0x03,0x2d,0x00,0x1e,0x00,0x50,0x04,0x00,0x00,0x00,0x029a,0x00,};
static const struct homolog_params params011 = {0x24,0x40,0x01,0x06,0x64,0x00,0x00,0x04,0x00,0x00,0x00,0x32,0x02,0x0a,0x00,0x19,0x02,0x01,0x2b,0x00,0x1e,0x00,0x50,0x02,0x00,0x00,0x00,0x029a,0x00,};
static const struct homolog_params params012 = {0x21,0x43,0x01,0x08,0x5a,0x00,0x00,0x04,0x00,0x00,0x00,0x07,0x04,0x09,0x00,0x02,0x02,0x03,0x2d,0x00,0x1e,0x00,0x50,0x04,0x00,0x00,0x00,0x029a,0x00,};
static const struct homolog_params params013 = {0x21,0x43,0x01,0x08,0x5a,0x2a,0x50,0x04,0x2a,0x50,0x00,0x07,0x04,0x09,0x00,0x02,0x02,0x03,0x2d,0x00,0x1e,0x00,0x50,0x04,0x00,0x00,0x00,0x029a,0x00,};
static const struct homolog_params params014 = {0x28,0x3c,0x01,0x06,0x5a,0x06,0x2a,0x08,0x0d,0x3c,0x01,0x0a,0x04,0x09,0x01,0x0e,0x02,0x00,0x22,0x00,0x1e,0x00,0x50,0x04,0x00,0x00,0x00,0x029a,0x00,};
static const struct homolog_params params015 = {0x24,0x40,0x01,0x08,0x5a,0x00,0x00,0x04,0x00,0x00,0x00,0x09,0x02,0x09,0x01,0x19,0x02,0x00,0x26,0x00,0x1e,0x00,0x50,0x04,0x00,0x00,0x00,0x029a,0x00,};
static const struct homolog_params params016 = {0x21,0x43,0x01,0x09,0x5a,0x00,0x00,0x04,0x00,0x00,0x00,0x07,0x04,0x09,0x00,0x02,0x02,0x03,0x2d,0x00,0x1e,0x00,0x50,0x04,0x00,0x00,0x00,0x029a,0x00,};
static const struct homolog_params params018 = {0x28,0x3c,0x01,0x08,0x5a,0x0a,0x42,0x04,0x0a,0x41,0x00,0x09,0x04,0x09,0x01,0x19,0x02,0x01,0x2b,0x00,0x1e,0x00,0x50,0x04,0x00,0x00,0x00,0x029a,0x00,};
static const struct homolog_params params020 = {0x29,0x3c,0x01,0x08,0x5a,0x0f,0x3c,0x04,0x23,0x3c,0x00,0x12,0x04,0x09,0x01,0x19,0x02,0x05,0x2b,0x00,0x1e,0x00,0x50,0x04,0x00,0x00,0x00,0x029a,0x00,};
static const struct homolog_params params022 = {0x24,0x40,0x01,0x06,0x64,0x00,0x00,0x04,0x00,0x00,0x00,0x32,0x02,0x0a,0x00,0x19,0x02,0x01,0x2b,0x00,0x1e,0x06,0x50,0x02,0x00,0x00,0x00,0x029a,0x00,};
static const struct homolog_params params023 = {0x21,0x43,0x01,0x06,0x5a,0x0b,0x3c,0x02,0x0b,0x3c,0x00,0x09,0x04,0x09,0x01,0x08,0x02,0x06,0x2d,0x00,0x1e,0x00,0x50,0x04,0x00,0x00,0x00,0x029a,0x00,};
static const struct homolog_params params025 = {0x24,0x40,0x01,0x06,0x64,0x41,0x55,0x04,0x41,0x55,0x00,0x32,0x02,0x0a,0x00,0x19,0x02,0x01,0x2b,0x00,0x2e,0x00,0x50,0x02,0x00,0x00,0x00,0x029a,0x00,};
static const struct homolog_params params027 = {0x22,0x43,0x01,0x08,0x5a,0x00,0x00,0x04,0x00,0x00,0x00,0x07,0x04,0x09,0x00,0x19,0x02,0x02,0x2b,0x00,0x1e,0x00,0x50,0x04,0x00,0x00,0x00,0x029a,0x00,};
static const struct homolog_params params028 = {0x24,0x40,0x01,0x06,0x64,0x12,0x3c,0x04,0x12,0x3c,0x00,0x32,0x02,0x0a,0x00,0x19,0x02,0x05,0x2b,0x00,0xff,0x00,0x50,0x02,0x00,0x00,0x00,0x029a,0x00,};
static const struct homolog_params params029 = {0x29,0x41,0x01,0x08,0x5a,0x00,0x00,0x02,0x00,0x00,0x00,0x0b,0x02,0x09,0x01,0x0f,0x02,0x04,0x28,0x00,0x1e,0x00,0x50,0x06,0x00,0x00,0x00,0x029a,0x00,};
static const struct homolog_params params030 = {0x22,0x42,0x01,0x08,0x64,0x00,0x00,0x04,0x00,0x00,0x00,0x32,0x02,0x0e,0x00,0x19,0x02,0x01,0x2b,0x00,0x1e,0x00,0x50,0x04,0x00,0x00,0x00,0x029a,0x00,};
static const struct homolog_params params032 = {0x22,0x42,0x01,0x06,0x64,0x00,0x00,0x04,0x00,0x00,0x00,0x32,0x02,0x08,0x00,0x19,0x02,0x01,0x2b,0x00,0x1e,0x06,0x50,0x04,0x00,0x00,0x00,0x029a,0x00,};
static const struct homolog_params params033 = {0x24,0x40,0x01,0x06,0x64,0x00,0x00,0x04,0x00,0x00,0x00,0x32,0x02,0x0a,0x00,0x19,0x02,0x00,0x2b,0x00,0xff,0x00,0x50,0x02,0x00,0x00,0x00,0x029a,0x00,};
static const struct homolog_params params035 = {0x21,0x43,0x01,0x08,0x5a,0x21,0x30,0x04,0x0e,0x19,0x00,0x07,0x04,0x09,0x00,0x02,0x02,0x03,0x2d,0x00,0x1e,0x00,0x50,0x04,0x00,0x00,0x00,0x029a,0x00,};
static const struct homolog_params params036 = {0x28,0x3c,0x01,0x06,0x5a,0x00,0x00,0x04,0x00,0x00,0x00,0x12,0x04,0x09,0x01,0x19,0x02,0x05,0x2b,0x00,0x1e,0x00,0x50,0x04,0x00,0x00,0x00,0x029a,0x00,};
static const struct homolog_params params038 = {0x21,0x43,0x01,0x06,0x64,0x00,0x00,0x04,0x00,0x00,0x00,0x32,0x02,0x0a,0x00,0x19,0x02,0x01,0x2b,0x00,0x1e,0x00,0x50,0x03,0x00,0x00,0x00,0x029a,0x00,};
static const struct homolog_params params039 = {0x21,0x43,0x01,0x08,0x5a,0x21,0x3c,0x04,0x21,0x3c,0x00,0x07,0x04,0x09,0x00,0x02,0x02,0x03,0x2d,0x00,0x1e,0x00,0x50,0x04,0x00,0x00,0x00,0x029a,0x00,};
static const struct homolog_params params040 = {0x24,0x40,0x01,0x06,0x64,0x00,0x00,0x04,0x00,0x00,0x00,0x32,0x02,0x0a,0x00,0x19,0x02,0x01,0x2b,0x00,0x2e,0x00,0x50,0x02,0x00,0x00,0x00,0x029a,0x00,};
static const struct homolog_params params041 = {0x21,0x43,0x01,0x06,0x5a,0x00,0x00,0x04,0x00,0x00,0x00,0x07,0x04,0x09,0x00,0x02,0x02,0x03,0x2d,0x00,0x1e,0x00,0x50,0x04,0x00,0x00,0x00,0x029a,0x00,};
static const struct homolog_params params042 = {0x28,0x3c,0x01,0x08,0x5a,0x00,0x00,0x04,0x00,0x00,0x00,0x0b,0x02,0x09,0x01,0x0f,0x02,0x07,0x20,0x00,0x1e,0x00,0x50,0x05,0x00,0x00,0x00,0x029a,0x00,};
static const struct homolog_params params043 = {0x21,0x43,0x03,0x07,0x5a,0x00,0x00,0x04,0x00,0x00,0x00,0x46,0x04,0x09,0x00,0x19,0x01,0x01,0x2b,0x00,0x1e,0x00,0x50,0x04,0x00,0x00,0x00,0x029a,0x00,};
static const struct homolog_params params044 = {0x24,0x40,0x01,0x08,0x5a,0x0a,0x42,0x02,0x0a,0x41,0x00,0x0a,0x04,0x09,0x01,0x0f,0x02,0x00,0x27,0x00,0x1e,0x00,0x50,0x04,0x00,0x00,0x00,0x029a,0x00,};
static const struct homolog_params params045 = {0x21,0x43,0x01,0x08,0x69,0x00,0x00,0x04,0x00,0x00,0x00,0x09,0x02,0x0a,0x00,0x19,0x02,0x01,0x2b,0x00,0x1e,0x00,0x50,0x03,0x00,0x00,0x00,0x029a,0x00,};
static const struct homolog_params params049 = {0x21,0x43,0x01,0x06,0x5a,0x0b,0x3c,0x02,0x0b,0x3c,0x00,0x09,0x04,0x09,0x01,0x08,0x02,0x05,0x2d,0x00,0x1e,0x00,0x50,0x04,0x00,0x00,0x00,0x029a,0x00,};
static const struct homolog_params params050 = {0x21,0x43,0x01,0x08,0x5a,0x00,0x00,0x04,0x00,0x00,0x00,0x14,0x02,0x09,0x01,0x19,0x02,0x03,0x23,0x01,0x1e,0x00,0x50,0x04,0x00,0x00,0x00,0x029a,0x00,};
static const struct homolog_params params051 = {0x28,0x3c,0x01,0x07,0x5a,0x0c,0x16,0x04,0x0c,0x16,0x00,0x12,0x04,0x09,0x01,0x19,0x02,0x05,0x2b,0x00,0x1e,0x00,0x50,0x04,0x00,0x00,0x00,0x029a,0x00,};
static const struct homolog_params params052 = {0x26,0x3e,0x01,0x04,0x69,0x22,0x2e,0x04,0x22,0x2e,0x00,0x09,0x02,0x0a,0x00,0x19,0x03,0x01,0x2b,0x00,0x1e,0x00,0x32,0x03,0x00,0x00,0x00,0x029a,0x00,};
static const struct homolog_params params054 = {0x21,0x43,0x01,0x07,0x69,0x48,0x4e,0x04,0x48,0x4e,0x00,0x09,0x02,0x0a,0x00,0x19,0x02,0x01,0x2b,0x00,0x1e,0x00,0x50,0x03,0x00,0x00,0x00,0x029a,0x00,};
static const struct homolog_params params055 = {0x28,0x3c,0x01,0x07,0x5a,0x00,0x00,0x04,0x00,0x00,0x00,0x0a,0x04,0x09,0x01,0x19,0x02,0x05,0x2b,0x00,0x1e,0x00,0x55,0x04,0x00,0x00,0x00,0x029a,0x00,};
static const struct homolog_params params056 = {0x28,0x3c,0x01,0x07,0x5a,0x00,0x00,0x04,0x00,0x00,0x00,0x12,0x04,0x09,0x01,0x19,0x02,0x05,0x2b,0x00,0x1e,0x00,0x50,0x04,0x00,0x00,0x00,0x029a,0x00,};
static const struct homolog_params params057 = {0x28,0x3c,0x01,0x09,0x5a,0x2a,0x50,0x04,0x2a,0x50,0x00,0x07,0x04,0x09,0x00,0x02,0x02,0x03,0x2d,0x00,0x1e,0x00,0x50,0x04,0x00,0x00,0x00,0x029a,0x00,};
static const struct homolog_params params059 = {0x21,0x43,0x01,0x08,0x5a,0x05,0x3c,0x04,0x05,0x3c,0x00,0x0a,0x05,0x09,0x01,0x0c,0x02,0x05,0x29,0x00,0x1e,0x00,0x50,0x04,0x00,0x00,0x00,0x029a,0x00,};
static const struct homolog_params params061 = {0x28,0x3c,0x02,0x08,0x5a,0x14,0x1e,0x04,0x14,0x55,0x00,0x09,0x04,0x09,0x01,0x0f,0x02,0x00,0x1f,0x00,0x1e,0x00,0x50,0x04,0x00,0x00,0x00,0x029a,0x00,};
static const struct homolog_params params062 = {0x28,0x3c,0x01,0x08,0x5a,0x08,0x50,0x02,0x08,0x50,0x00,0x0c,0x04,0x09,0x01,0x0f,0x02,0x00,0x25,0x00,0x1e,0x00,0x50,0x04,0x00,0x00,0x00,0x029a,0x01,};
static const struct homolog_params params063 = {0x21,0x43,0x01,0x06,0x64,0x14,0x3c,0x04,0x14,0x3c,0x00,0x32,0x02,0x0a,0x00,0x0a,0x02,0x01,0x2b,0x00,0x1e,0x06,0x50,0x03,0x00,0x00,0x00,0x012c,0x00,};
static const struct homolog_params params064 = {0x28,0x3c,0x01,0x06,0x64,0x00,0x00,0x04,0x00,0x00,0x00,0x09,0x02,0x0a,0x00,0x19,0x02,0x01,0x23,0x00,0x1e,0x00,0x50,0x02,0x00,0x00,0x00,0x029a,0x00,};
static const struct homolog_params params067 = {0x21,0x43,0x01,0x07,0x5a,0x00,0x00,0x04,0x00,0x00,0x00,0x07,0x04,0x09,0x00,0x02,0x02,0x03,0x2d,0x00,0x1e,0x00,0x15,0x04,0x00,0x00,0x00,0x029a,0x00,};
static const struct homolog_params params068 = {0x22,0x48,0x01,0x08,0x5a,0x23,0x27,0x04,0x23,0x27,0x00,0x07,0x04,0x09,0x00,0x19,0x02,0x01,0x2b,0x00,0x1e,0x00,0x50,0x04,0x00,0x00,0x00,0x029a,0x00,};
const struct homolog_set homolog_set[] = {
{0x0002,"ALGERIA",&params000},
{0x0007,"ARGENTINA",&params001},
{0x0009,"AUSTRALIA",&params002},
{0x000a,"AUSTRIA",&params003},
{0x000c,"BAHREIN",&params001},
{0x000f,"BELGIUM",&params005},
{0x0016,"BRAZIL",&params006},
{0x001a,"BRUNEI",&params007},
{0x001b,"BULGARIA",&params008},
{0x0020,"CANADA",&params001},
{0x0025,"CHILE",&params001},
{0x0026,"CHINA",&params011},
{0x0100,"CTR21EUROPE",&params012},
{0x002d,"CYPRUS",&params013},
{0x002e,"CZECH_REPUBLIC",&params014},
{0x0031,"DENMARK",&params015},
{0x0036,"EGYPT",&params016},
{0x0101,"ESTONIA",&params012},
{0x003c,"FINLAND",&params018},
{0x003d,"FRANCE",&params000},
{0x0042,"GERMANY",&params020},
{0x0046,"GREECE",&params012},
{0x0050,"HONG_KONG",&params022},
{0x0051,"HUNGARY",&params023},
{0x0052,"ICELAND",&params012},
{0x0053,"INDIA",&params025},
{0x0054,"INDONESIA",&params011},
{0x0057,"IRELAND",&params027},
{0x0058,"ISRAEL",&params028},
{0x0059,"ITALY",&params029},
{0x0000,"JAPAN",&params030},
{0x005e,"JORDAN",&params013},
{0x0061,"KOREA",&params032},
{0x0062,"KUWAIT",&params033},
{0x0103,"LATVIA",&params008},
{0x0064,"LEBANON",&params035},
{0x0104,"LITHUANIA",&params036},
{0x0069,"LUXEMBOURG",&params012},
{0x006c,"MALAYSIA",&params038},
{0x0070,"MALTA",&params039},
{0x0073,"MEXICO",&params040},
{0x0077,"MOROCCO",&params041},
{0x007b,"NETHERLANDS",&params042},
{0x007e,"NEW_ZEALAND",&params043},
{0x0082,"NORWAY",&params044},
{0x0083,"OMAN",&params045},
{0x0084,"PAKISTAN",&params040},
{0x0088,"PERU",&params001},
{0x0089,"PHILIPPINES",&params040},
{0x008a,"POLAND",&params049},
{0x008b,"PORTUGAL",&params050},
{0x008e,"ROMANIA",&params051},
{0x00b8,"RUSSIA",&params052},
{0x0098,"SAUDIARABIA",&params001},
{0x009c,"SINGAPORE",&params054},
{0x00c5,"SLOVAKIA",&params055},
{0x00c6,"SLOVENIA",&params056},
{0x009f,"SOUTHAFRICA",&params057},
{0x0107,"SOUTHKOREA",&params001},
{0x00a0,"SPAIN",&params059},
{0x00a1,"SRILANKA",&params054},
{0x00a5,"SWEDEN",&params061},
{0x00a6,"SWITZERLAND",&params062},
{0x0108,"TAIWAN",&params063},
{0x00a9,"THAILAND",&params064},
{0x00ad,"TUNISIA",&params000},
{0x00ae,"TURKEY",&params012},
{0x00b3,"UAE",&params067},
{0x00b4,"UK",&params068},
{0x00b7,"URUGUAY",&params001},
{0x00b5,"USA",&params001},
{0x00bc,"VIETNAM",&params040},
{}};
+1973
View File
File diff suppressed because it is too large. Load diff
+460
View File
@@ -0,0 +1,460 @@
/*
*
* Copyright (c) 2002, Smart Link Ltd.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* 3. Neither the name of the Smart Link Ltd. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/*
*
* modem.h - modem definitions
*
* Author: sashak@smlink.com
*/
#ifndef __MODEM_H__
#define __MODEM_H__
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <termios.h>
#include <modem_defs.h>
#include <modem_homolog.h>
#include <modem_dp.h>
#include <modem_timer.h>
/* modem modes */
enum MODEM_MODE {
MODEM_MODE_DATA = 0,
MODEM_MODE_FAX = 1,
MODEM_MODE_VOICE = 8
};
/* modem status */
#define STATUS_OK 0x0
#define STATUS_NOCARRIER 0x0002 // 3
#define STATUS_ERROR 0x0004 // 4
#define STATUS_NODIALTONE 0x0010 // 6
#define STATUS_BUSY 0x0020 // 7
#define STATUS_NOANSWER 0x0040 // 8
#define STATUS_DP_LINK 0x0100 // 13
#define STATUS_DP_ERROR 0x0200 // 14
#define STATUS_PACK_LINK 0x0400 // 15
#define STATUS_PACK_ERROR 0x0800 // 16
#define STATUS_EC_LINK 0x1000 // 17
#define STATUS_EC_RELEASE 0x2000 // 18
#define STATUS_EC_ERROR 0x4000 // 19
/*
* parameters
*
*/
#define MODEM_FORMAT MFMT_S16_LE
#define MODEM_RATE 9600 /* 8000 */
#define MODEM_FRAG (MODEM_RATE/200)
#define MODEM_MIN_RATE 300
#define MODEM_MAX_RATE 56000
#define MODEM_DEFAULT_COUNTRY_CODE 0xb5 /* USA */
#define MODEM_CONFIG_CID 1
#define MODEM_CONFIG_VOICE 1
#define MODEM_CONFIG_FAX 1
#define MODEM_CONFIG_FAX_CLASS1 1
#define MODEM_CONFIG_RING_DETECTOR 1
/*
* type definitions
*
*/
/* modem driver struct */
struct modem_driver {
const char *name;
int (*start)(struct modem *m);
int (*stop )(struct modem *m);
int (*ioctl)(struct modem *m,unsigned cmd, unsigned long arg);
};
/* modem data pumps driver struct */
struct dp_driver {
const enum DP_ID id;
const char *name;
const char *code;
struct dp_operations *op;
};
/*
*
* compressor definitions
*
*/
#define COMP_MAX_CODEWORDS 2048 /* dictionary size */
#define COMP_MAX_STRING 34 /* max string length */
/* encoder and decoder states */
struct comp_state {
const char *name;
enum COMP_MODE {TRANSPARENT,COMPRESSED} mode;
int escape; /* escape state: decoder only */
u16 update_at; /* update dict. at node */
u16 next_free; /* next free dict entry */
u16 last_matched; /* last matched dict entry */
u16 last_added; /* last added dict entry */
u16 cw_size; /* cw size */
u16 threshold; /* cw size threshold */
u8 escape_char; /* escape char value */
int max_string; /* max string length */
int dict_size; /* dictionary size */
struct dict {
u8 ch;
u16 parent;
u16 child;
u16 next;
} *dict; /* dictionary */
/* fixme: union may be used? */
int bit_len;
u32 bit_data;
int flushed_len; /* string length already sent */
int str_len; /* string length */
u8 str_data[COMP_MAX_STRING];
/* test statistics info : encoder only */
u16 cmp_last; /* compressed bits per last TEST_SLICE chars */
u32 cmp_bits; /* total compressed bits */
u32 raw_bits; /* total non-compressed bits */
/* temporary */
int olen;
int ohead;
char obuf[1024];
};
extern int modem_comp_init(struct modem *m);
extern int modem_comp_config(struct modem *m, int dict_size, int max_str);
extern void modem_comp_exit(struct modem *m);
extern int modem_comp_encode(struct modem *m, u8 ch, char *buf, int n);
extern int modem_comp_decode(struct modem *m, u8 ch, char *buf, int n);
extern int modem_comp_flush_encoder(struct modem *m, char *buf, int n);
extern int modem_comp_flush_decoder(struct modem *m, char *buf, int n);
/*
*
* HDLC definitions
*
*/
typedef struct hdlc_frame {
struct hdlc_frame *next;
int count;
int size;
//u16 addr;
//u16 ctrl;
u16 fcs;
u8 *buf;
} frame_t;
/*
* LAPM definitions
*
*/
#define LAPM_MAX_WIN_SIZE 15 /* max supported winsize */
#define LAPM_MAX_INFO_SIZE 128 /* max supported infosize */
#define LAPM_INFO_FRAMES LAPM_MAX_WIN_SIZE + 1 /* number of info frames */
#define LAPM_CTRL_FRAMES 8 /* number of ctrl frames */
/* lapm state */
struct lapm_state {
/* modem link */
struct modem *modem;
int state;
/* sub-states: may be optimized */
int config;
/* those DATA sub-states may be optimized */
int reject;
int busy;
int peer_busy;
u8 cmd_addr;
u8 rsp_addr;
u8 vs;
u8 va;
u8 vr;
int rtx_count; /* retransmission counter () */
unsigned int tx_win_size;
unsigned int rx_win_size;
unsigned int tx_info_size;
unsigned int rx_info_size;
frame_t *sent_info;
frame_t *tx_info;
frame_t *info_list;
frame_t *tx_ctrl;
frame_t *ctrl_list;
/* temporary: internal buffs */
/* rx buf (used when enter busy state) */
int rx_count;
int rx_head;
u8 rx_buf[LAPM_MAX_INFO_SIZE];
/* temporary: frames bufs */
struct {
frame_t frame;
u8 ctrl[4];
u8 info[LAPM_MAX_INFO_SIZE];
} info_buf[LAPM_INFO_FRAMES];
struct {
frame_t frame;
u8 ctrl[4];
u8 info[LAPM_MAX_INFO_SIZE];
} ctrl_buf[LAPM_CTRL_FRAMES];
/* temporary: debug counters: remove it */
int info_count; // debug
int tx_count; // debug
int sent_count; // debug
int ctrl_count; // debug
};
/* modem struct */
struct modem {
const char *name;
int pty; /* pty descriptor */
const char *dev_name, *pty_name; /* and names */
struct termios termios;
/* device driver */
struct modem_driver driver;
void *dev_data;
/* modem states */
unsigned modem_info;
unsigned state;
unsigned started;
unsigned command;
unsigned result_code;
unsigned hook;
unsigned caller;
unsigned rx_rate;
unsigned tx_rate;
enum MODEM_MODE mode; /* data,fax,voice */
/* modem events (ring,escape,waiting for connect,etc) */
unsigned event;
unsigned new_event;
struct timer event_timer;
/* modem parameters */
unsigned min_rate;
unsigned max_rate;
unsigned char sregs[256]; /* s-registers */
const struct homolog_set *homolog; /* homologation parameters */
/* at processor */
unsigned int at_count;
char at_line[64];
char at_cmd[64];
/* ring detector */
unsigned int ring_count;
unsigned long ring_first;
unsigned long ring_last;
#ifdef MODEM_CONFIG_RING_DETECTOR
void *rd_obj;
#endif
/* cid */
#ifdef MODEM_CONFIG_CID
unsigned cid_requested;
void *cid;
#endif
/* dialer */
char dial_string[128];
/* escape counter */
unsigned escape_count;
unsigned long last_esc_check;
/* xmit queue */
struct xmit_queue {
int count;
unsigned int head;
unsigned int tail;
unsigned int size;
unsigned char *buf;
} xmit;
/* run time configuration */
struct modem_config {
/* ec params */
u8 ec;
u8 ec_detector;
u8 ec_tx_win_size;
u8 ec_rx_win_size;
u16 ec_tx_info_size;
u16 ec_rx_info_size;
/* compressor params */
u8 comp;
int comp_dict_size;
int comp_max_string;
} cfg;
/* modem packer */
int (*get_chars)(struct modem *m, char *buf, int n);
int (*put_chars)(struct modem *m, const char *buf, int n);
//int tx_window;
//int rx_window;
int bit_timer;
void (*bit_timer_func)(struct modem *m);
void (*packer_process)(struct modem *m, int bits);
struct bits_state {
int bit;
u32 data;
} pack,unpack;
int (*get_bits)(struct modem *m, int nbits, u8 *buf, int n);
int (*put_bits)(struct modem *m, int nbits, u8 *buf, int n);
union packer_union {
struct async_state {
struct packer *packer;
int data_bits;
int stop_bits;
int parity;
int char_size;
} async;
struct detect_state {
int tx_count;
u8 tx_pattern[2];
int rx_count;
u8 rx_pattern[2];
int ec_enable;
} detector;
struct hdlc_state {
struct hdlc_frame *tx_frame;
struct hdlc_frame *rx_frame;
int rx_error;
int rx_ones,tx_ones;
/* framer interface */
struct hdlc_frame *(*get_tx_frame)(void *framer);
void (*tx_complete)(void *framer, frame_t *fr);
void (*rx_complete)(void *framer, frame_t *fr);
void *framer;
/* temporary: internal bufs */
struct hdlc_frame _rx_frame;
u8 _rx_buf[512];
} hdlc;
} packer;
/* error corrector */
union {
struct lapm_state lapm;
} ec;
/* compressor */
struct comp_struct {
// fixme: redo interface
int head,count;
char buf[256];
struct comp_state encoder;
struct comp_state decoder;
} comp;
/* modem data pump interface */
unsigned srate;
unsigned format;
unsigned frag;
unsigned dp_requested;
unsigned automode_requested;
int update_delay;
void (*process)(struct modem *m,void *in,void *out,int cnt);
/* process counter and sample timer */
unsigned long count;
unsigned long sample_timer;
void (*sample_timer_func)(struct modem *);
/* data pump */
struct dp_operations **dp_ops;
struct dp *dp;
void *dp_runtime;
/* dc evaluator and cleaner */
void *dcr;
/* dsp info data */
struct dsp_info dsp_info;
/* voice info */
#ifdef MODEM_CONFIG_VOICE
void *voice_obj;
struct voice_info voice_info;
#endif
#ifdef MODEM_CONFIG_FAX
void *fax_obj;
#endif
};
/*
* prototypes
*
*/
/* device driver --> modem */
extern struct modem *modem_create(struct modem_driver *drv, const char *dev_name);
extern void modem_delete(struct modem *m);
extern int modem_write(struct modem *m, const char *buf, int n);
extern void modem_hangup(struct modem *m);
extern void modem_update_termios(struct modem *m, struct termios *tios);
extern void modem_error (struct modem *m);
extern void modem_ring (struct modem *m);
extern void modem_event (struct modem *m);
extern void modem_process(struct modem *m,void *in,void *out,int cnt);
/* packers && EC */ // FIXME: improve interface
extern void modem_async_start(struct modem *m);
extern int modem_async_get_bits(struct modem *m,int nbits,u8 *buf,int cnt);
extern int modem_async_put_bits(struct modem *m,int nbits,u8 *buf,int cnt);
extern void modem_detector_start(struct modem *m);
extern int modem_detector_get_bits(struct modem *m,int nbits,u8 *buf,int cnt);
extern int modem_detector_put_bits(struct modem *m,int nbits,u8 *buf,int cnt);
extern void modem_hdlc_start(struct modem *m);
extern int modem_hdlc_get_bits(struct modem *m,int nbits,u8 *buf,int cnt);
extern int modem_hdlc_put_bits(struct modem *m,int nbits,u8 *buf,int cnt);
extern int modem_ec_init(struct modem *m);
extern void modem_ec_exit(struct modem *m);
extern void modem_ec_start(struct modem *m);
extern void modem_ec_stop(struct modem *m);
/* status & config */
extern void modem_update_status(struct modem *m, unsigned status);
extern void modem_update_config(struct modem *m, struct modem_config *cfg);
/* modem parameters access macros */
#define CRLF_CHARS(m) ((char *)((m)->sregs+SREG_CR_CHAR))
#define MODEM_DP(m) ((m)->sregs[SREG_DP])
#define MODEM_AUTOMODE(m) ((m)->sregs[SREG_AUTOMODE])
#endif /* __MODEM_H__ */
+1204
View File
File diff suppressed because it is too large. Load diff
+296
View File
@@ -0,0 +1,296 @@
/*
*
* Copyright (c) 2002, Smart Link Ltd.
* Copyright (c) 2021, Aon plc
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* 3. Neither the name of the Smart Link Ltd. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/*
*
* modem_cmdline.c -- simple command line processor,
* define config parameters.
*
* Author: Sasha K (sashak@smlink.com)
*
*
*/
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <ctype.h>
#include <modem.h>
#include <modem_homolog.h>
#include <modem_debug.h>
#define PR_INFO(fmt...) fprintf(stderr, fmt )
/* global config data */
/* modem.c */
extern const char *modem_default_country;
/* modem_debug.c */
extern unsigned int modem_debug_level;
extern unsigned int modem_debug_logging;
/* config parameters */
const char *modem_dev_name = NULL;
const char *modem_default_dev_name = "/dev/slamr0";
const char *modem_alsa_dev_name = "modem:1";
const char *modem_exec = NULL;
unsigned int need_realtime = 1;
#ifdef MODEM_CONFIG_RING_DETECTOR
unsigned int ring_detector = 0;
#endif
unsigned int use_alsa = 0;
const char *modem_group = "dialout";
unsigned int use_short_buffer = 0;
mode_t modem_perm = 0660;
enum {
OPT_HELP = 0,
OPT_USAGE,
OPT_VERSION,
OPT_COUNTRY,
OPT_COUNTRYLIST,
OPT_ALSA,
OPT_GROUP,
OPT_PERM,
#ifdef MODEM_CONFIG_RING_DETECTOR
OPT_RINGDET,
#endif
OPT_USER,
OPT_SHORTBUF,
OPT_DEBUG,
OPT_LOG,
OPT_EXEC,
OPT_LAST
};
static struct opt {
int ch;
const char *name;
const char *desc;
enum {NONE=0,MANDATORY,OPTIONAL} arg;
enum {INTEGER,STRING} arg_type;
const char *arg_val;
unsigned found;
} opt_list[] = {
{'h',"help","this usage"},
{'u',"usage","this usage"},
{'v',"version","show version and exit"},
{'c',"country","default modem country name",MANDATORY,STRING,"USA"},
{ 0 ,"countrylist","show list of supported countries"},
{'a',"alsa","ALSA mode (see README for howto)"},
{'g',"group","Modem TTY group",MANDATORY,STRING,"dialout"},
{'p',"perm","Modem TTY permission",MANDATORY,INTEGER,"0660"},
#ifdef MODEM_CONFIG_RING_DETECTOR
{'r',"ringdetector","with internal ring detector (software)"},
#endif
{'n',"nortpriority","run with regular priority"},
{'s',"shortbuffer","use short buffer (4 periods length)"},
{'d',"debug","debug level (developers only, for ./sl...)",OPTIONAL,INTEGER,"0"},
{'l',"log","logging mode",OPTIONAL,INTEGER,"5"},
{'e',"exec","path to external application that transmits audio over the socket (required)"},
{}
};
static void usage(const char *prog_name)
{
struct opt *opt;
PR_INFO("Usage: %s [option...] <device>\n"
"Where 'device' is name of modem device (default `%s')\n"
" and 'option' may be:\n", prog_name, modem_default_dev_name);
for (opt = opt_list ; opt->name ; opt++ ) {
int n = 0;
if(opt->ch)
n = PR_INFO(" -%c, ",opt->ch);
else
n = PR_INFO(" ");
n += PR_INFO("--%s%s ",opt->name,opt->arg?"=VAL":"");
n += PR_INFO("%*s%s",24-n,"",opt->desc);
if(opt->arg) {
n+= PR_INFO(" (default `%s')",opt->arg_val);
}
PR_INFO("\n");
}
exit(1);
}
static void opt_parse(int argc, char *argv[])
{
const char *prog_name;
const char *dev_name = NULL;
struct opt *opt;
char *p, *arg;
int found, i;
prog_name = argv[0];
for( i = 1 ; i < argc ; i++ ) {
p = argv[i];
if(*p != '-') {
if(dev_name)
usage(prog_name);
dev_name = p;
continue;
}
found = 0;
arg = NULL;
do { p++; } while( *p == '-' );
for (opt = opt_list ; opt->name ; opt++ ) {
if(!strncmp(p,opt->name,strlen(opt->name)) ||
(opt->ch && *p == opt->ch) ) {
char *q;
if(!strncmp(p,opt->name,strlen(opt->name)))
q = p + strlen(opt->name);
else
q = p + 1;
if( *q == '\0' )
found = 1;
else if (*q == '=' && opt->arg ) {
arg = q + 1;
found = 1;
}
else if(isdigit(*q) && opt->arg ) {
arg = q;
found = 1;
}
}
if ( !found )
continue;
if ( arg && !opt->arg )
usage(prog_name);
if (!arg && opt->arg &&
(i < argc - 1 && *argv[i+1] != '-') &&
(!opt->arg_type == INTEGER || isdigit(*argv[i+1])))
arg = argv[++i];
if(!arg && opt->arg == MANDATORY)
usage(prog_name);
opt->found++;
if(opt->arg && arg)
opt->arg_val = arg;
break;
}
if(!found)
usage(prog_name);
}
if(dev_name)
modem_dev_name = dev_name;
}
void modem_cmdline(int argc, char *argv[])
{
const char *prog_name = argv[0];
int val;
opt_parse(argc,argv);
if(opt_list[OPT_HELP].found ||
opt_list[OPT_USAGE].found )
usage(prog_name);
if(opt_list[OPT_VERSION].found) {
extern void modem_print_version();
modem_print_version();
exit(0);
}
if(opt_list[OPT_COUNTRYLIST].found) {
const struct homolog_set *s ;
for( s = homolog_set; s->name ; s++ ) {
PR_INFO("%02x: %s\n",s->id,s->name);
}
exit(0);
}
if(opt_list[OPT_COUNTRY].found)
modem_default_country = opt_list[OPT_COUNTRY].arg_val;
if(opt_list[OPT_ALSA].found) {
#ifndef SUPPORT_ALSA
PR_INFO("ALSA support is not compiled in (see README for howto).\n");
exit(1);
#endif
use_alsa = 1;
}
if(opt_list[OPT_GROUP].found)
modem_group = opt_list[OPT_GROUP].arg_val;
if(opt_list[OPT_PERM].found) {
val = strtol(opt_list[OPT_PERM].arg_val,NULL,8);
if (val <= 0)
usage(prog_name);
modem_perm = val;
}
#ifdef MODEM_CONFIG_RING_DETECTOR
if(opt_list[OPT_RINGDET].found)
ring_detector = 1;
#endif
if(opt_list[OPT_USER].found)
need_realtime = 0;
if(opt_list[OPT_SHORTBUF].found)
use_short_buffer = 1;
if(opt_list[OPT_DEBUG].found) {
modem_debug_level = 1 ;
if(opt_list[OPT_DEBUG].arg_val &&
(val= strtol(opt_list[OPT_DEBUG].arg_val,NULL,0)) > 0 )
modem_debug_level = val;
}
if(opt_list[OPT_LOG].found) {
modem_debug_logging = 5;
if(opt_list[OPT_LOG].arg_val &&
(val= strtol(opt_list[OPT_LOG].arg_val,NULL,0)) > 0 )
modem_debug_logging = val;
}
if(opt_list[OPT_EXEC].found) {
modem_exec = opt_list[OPT_EXEC].arg_val;
} else {
usage(prog_name);
}
if(!modem_dev_name) {
modem_dev_name = use_alsa ? modem_alsa_dev_name : modem_default_dev_name;
}
}
+887
View File
@@ -0,0 +1,887 @@
/*
*
* Copyright (c) 2002, Smart Link Ltd.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* 3. Neither the name of the Smart Link Ltd. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/*
*
* modem_comp.c -- modem compressor module.
*
* Author: Sasha K (sashak@smlink.com)
*
*
*/
#include <modem.h>
#include <modem_debug.h>
/*
* TODO list:
* - modify interface: clean temporary out buffs
* - char char encoding/decoding
* - simplify and clean code:
* - decoder
* - encoder test compression case, do it after string finishing
* - preformance trace and optimize
*
*/
//#define COMP_TEST 1
//#define COMP_DEBUG 1
/* V42bis parameters limitation */
#define MIN_DICT_SIZE 512 /* min dictionary size enabled by protocol */
#define MIN_STR_SIZE 6 /* min string size enabled by protocol */
#define MAX_STR_SIZE 250 /* max string size enabled by protocol */
/* V42bis constants */
#define CHAR_SIZE 8 /* char size (bits) N3 */
#define TOTAL_CHARS 256 /* number of chars N4 */
#define TOTAL_CTRLS 3 /* number of control cw N6 */
#define FIRST_ENTRY TOTAL_CTRLS /* first dictionary entry */
#define FIRST_FREE TOTAL_CHARS+FIRST_ENTRY /* initial val of free entry N5 */
/* control codewords */
#define CCW_ETM 0 /* Enter transparent mode */
#define CCW_FLUSH 1 /* Flash data */
#define CCW_STEPUP 2 /* Step up codeword size */
/* command codes */
#define CC_ECM 0 /* Enter compression mode */
#define CC_EID 1 /* Escape charactrer in data */
#define CC_RESET 2 /* Force reinitialization */
#define ESCAPE_STEP 51 /* escape char value step */
#define TEST_SLICE 256 /* compression test slice (bytes) */
/* fixme: use get pages */
#define COMP_ALLOC(size) malloc(size)
#define COMP_FREE(mem) free(mem)
/* debug stuff */
#if COMP_DEBUG
#define INLINE_FUNC static
#define COMP_DBG(fmt,arg...) dprintf("comp %d/%d: " fmt , \
c->cmp_bits , c->raw_bits , ##arg)
#if 1
#define COMP_DBG1(fmt,arg...)
#else
#define COMP_DBG1(fmt,arg...) COMP_DBG(fmt , ##arg)
static char *show_string(struct comp_state *c, u16 cw)
{
static char _str[COMP_MAX_STRING+1];
int j;
_str[COMP_MAX_STRING] = 0;
for(j = COMP_MAX_STRING-1; cw && j >= 0 ; j--) {
_str[j] = c->dict[cw].ch;
cw = c->dict[cw].parent;
}
return _str+j+1;
}
#endif // 0
#else /* !COMP_DEBUG */
#define INLINE_FUNC extern inline
#define COMP_DBG(fmt,arg...)
#define COMP_DBG1(fmt,arg...)
#endif /* !COMP_DEBUG */
#define COMP_ERR(fmt,arg...) eprintf("err: " fmt , ##arg)
/*
* common procedures
*
*/
/* initialize dictionary and params */
static void dict_init(struct comp_state *c)
{
int i;
for(i=0;i<c->dict_size;i++) {
c->dict[i].parent = 0;
c->dict[i].child = 0;
c->dict[i].next = 0;
}
c->next_free = FIRST_FREE;
c->last_matched = 0;
c->update_at = 0;
c->last_added = 0;
c->cw_size = CHAR_SIZE + 1;
c->threshold = TOTAL_CHARS<<1;
c->bit_len = 0;
c->flushed_len = 0;
c->str_len = 0;
c->escape_char = 0;
c->cmp_last = TEST_SLICE<<3;
c->mode = TRANSPARENT;
c->escape = 0;
}
/* match one char */
INLINE_FUNC u16 match_char(struct comp_state *c, u16 at, u8 ch)
{
register u16 e;
if (!at)
return ch + FIRST_ENTRY;
e = c->dict[at].child;
while(e) {
if (c->dict[e].ch == ch)
return e;
e = c->dict[e].next;
}
return 0;
}
/* add one char */
INLINE_FUNC u16 add_char(struct comp_state *c, u16 at, u8 ch)
{
register u16 new = c->next_free;
register u16 next;
/* add */
c->dict[new].ch = ch;
c->dict[new].parent = at;
c->dict[new].child = 0;
c->dict[new].next = c->dict[at].child;
c->dict[at].child = new;
/* update next free */;
next = new;
do {
if (++next == c->dict_size)
next = FIRST_FREE;
} while(c->dict[next].child);
if (c->dict[next].parent) {
u16 e = c->dict[next].parent;
if(c->dict[e].child == next)
c->dict[e].child = c->dict[next].next;
else {
e = c->dict[e].child;
while(c->dict[e].next != next)
e = c->dict[e].next;
c->dict[e].next = c->dict[next].next;
}
}
c->next_free = next;
return new;
}
/*
* decoder
*
*/
/* out decoded string */
INLINE_FUNC int send_string(struct comp_state *c)
{
int ret;
#if 0
c->str_data[c->str_len] = 0;
COMP_DBG("out string %d: '%s'\n",c->last_matched,c->str_data);
#endif
memcpy(c->obuf+c->olen,c->str_data,c->str_len);
ret = c->str_len;
c->olen += ret;
c->str_len = 0;
c->flushed_len = 0;
return ret;
}
/* receive encoded data */
INLINE_FUNC int recv_data(struct comp_state *c, u16 cw)
{
int i,ret = 0;
u16 p = cw;
COMP_DBG1("dec recv %d: '%s'\n",cw,show_string(c,cw));
for (ret = 0 ; p ; ret++) {
p = c->dict[p].parent;
}
p = cw;
i = c->str_len + ret - 1;
while(p) {
c->str_data[i--] = c->dict[p].ch;
p = c->dict[p].parent;
}
c->str_len += ret;
return ret;
}
/* flush decoder */
int comp_flush_decoder(struct comp_state *c)
{
int ret, total_len;
total_len = c->flushed_len + c->str_len;
ret = send_string(c);
c->flushed_len = total_len;
if (ret) {
COMP_DBG("flush_decoder: %d...\n", ret);
}
return ret;
}
/* decoder */
int comp_decode(struct comp_state *c, u8 *in, int n)
{
register int i, ret = 0;
register u16 cw, p;
u8 ch;
for (i = 0 ; i<n ;) {
switch (c->mode) {
case COMPRESSED:
/* get cw from input */
while (c->bit_len < c->cw_size && i<n) {
c->bit_data |= *in++ << c->bit_len;
c->bit_len += 8;
i++;
}
if (c->bit_len < c->cw_size)
break;
cw = c->bit_data&((1<<c->cw_size)-1);
c->bit_data >>= c->cw_size;
c->bit_len -= c->cw_size;
/* process cw */
switch (cw) {
/* control cw */
case CCW_ETM: /* enter transparent mode */
COMP_DBG("C decoder: ETM\n");
c->bit_len = 0;
c->mode = TRANSPARENT;
c->last_matched = 0;
c->last_added = 0;
break;
case CCW_FLUSH: /* flush signal */
COMP_DBG("C decoder: FLUSH\n");
c->bit_len = 0;
break;
case CCW_STEPUP: /* increase cw size */
c->cw_size++;
c->threshold <<= 1;
COMP_DBG("C decoder: STEPUP %d\n", c->cw_size);
if (c->cw_size > (c->dict_size>>3)) { /* C-ERROR */
COMP_ERR("fatal: cw size too big!\n");
return -1;
}
break;
default: /* regular codeword */
if (cw == c->next_free) { /* C-ERROR */
COMP_ERR("fatal: next free!\n");
return -1;
}
ret += recv_data(c,cw);
if (c->update_at) {
ch = c->str_data[0];
p = match_char(c,c->update_at,ch);
if (!p) {
// fixme: prevent case add 303 at 303
c->last_added = add_char(c,c->update_at,ch);
COMP_DBG1("C dec add %d at %d: %d(%c) '%s'\n",
c->last_added,c->update_at,
ch,ch,show_string(c,c->last_added));
if (cw == c->next_free) { /* C-ERROR */
COMP_ERR("fatal: empty cw!\n");
return -1;
}
}
else if (p == c->last_added)
c->last_added = 0;
}
if (c->str_len + c->flushed_len == c->max_string) {
c->update_at = 0;
}
else {
c->update_at = cw;
}
/* process escape */
// fixme: separate it in func (send_string ?)
{ int j;
for (j=0;j<c->str_len;j++) {
if(c->str_data[j]==c->escape_char) {
COMP_DBG("C dec: ESCAPE %d\n", c->escape_char);
c->escape_char+=ESCAPE_STEP;
}
}
}
send_string(c);
break;
}
break;
case TRANSPARENT:
if (c->escape) { /* command */
c->escape = 0;
switch(*in) {
case CC_ECM: /* enter compressed mode */
COMP_DBG("T decoder: ECM\n");
ret += send_string(c);
c->mode = COMPRESSED;
c->update_at = c->last_matched;
c->last_matched = 0;
in++;i++;
continue;
//break;
case CC_EID: /* escape symbol */
COMP_DBG("T decoder: EID\n");
// fixme: don't rewrite in buf
*in = c->escape_char;
c->escape_char += ESCAPE_STEP;
break;
case CC_RESET: /* reset dict */
COMP_DBG("T decoder: RESET\n");
// TBD
ret += send_string(c);
dict_init(c);
in++;i++;
continue;
//break;
default: /* C-ERROR */
COMP_ERR("fatal: invalid cmd!\n");
return -1;
}
}
else if (*in == c->escape_char) {
COMP_DBG("T dec ESCAPE %d\n", *in);
c->escape = 1;
in++; i++;
break;
}
//COMP_DBG1("dec rcv: %d(%c)\n", *in, *in);
if (c->update_at) {
if(!match_char(c,c->update_at,*in)) {
c->last_added = add_char(c,c->update_at,*in);
COMP_DBG1("T dec add %d at %d: %d(%c) '%s'\n",
c->last_added,c->update_at,
*in,*in,show_string(c,c->last_added));
}
c->update_at = 0;
}
cw = match_char(c,c->last_matched,*in);
if(!cw) {
c->update_at = c->last_matched;
/* out string */
ret += send_string(c);
c->last_matched = 0;
}
else if (cw == c->last_added) {
c->last_added = 0;
/* out string */
ret += send_string(c);
c->last_matched = 0;
}
else {
c->last_matched = cw;
c->str_data[c->str_len++] = *in++;
if (c->str_len + c->flushed_len == c->max_string) {
/* out string */
ret += send_string(c);
c->last_matched = 0;
}
i++;
}
break;
default:
return -1;
}
}
return ret;
}
/*
* encoder
*
*/
#define SEND_CW(c,cw) { (c)->bit_data |= (cw) << (c)->bit_len; \
(c)->bit_len += (c)->cw_size; }
#define ALIGN_BITS(c) { if((c)->bit_len%8) \
(c)->bit_len += 8 - (c)->bit_len%8; }
#define SEND_BITS(c) { while((c)->bit_len >= 8) { \
(c)->obuf[c->olen++]=(c)->bit_data&0xff; \
(c)->bit_data >>= 8; \
(c)->bit_len -= 8; ret++; \
} }
/* send encoded data */
static int send_data(struct comp_state *c, u16 cw)
{
register int i, ret = 0;
/* update test info */
c->raw_bits += c->str_len<<3;
c->cmp_bits += c->cw_size;
c->cmp_last += c->cw_size - c->cmp_last*c->str_len/TEST_SLICE;
switch(c->mode) {
case TRANSPARENT:
for (i = 0;i<c->str_len;i++) {
c->obuf[c->olen++] = c->str_data[i];
ret++;
if (c->str_data[i] == c->escape_char) {
COMP_DBG("T enc ESCAPE %d\n", c->escape_char);
c->obuf[c->olen++] = CC_EID;
ret++;
c->escape_char += ESCAPE_STEP;
}
COMP_DBG1("enc send: %d(%c)\n",c->str_data[i],c->str_data[i]);
}
break;
case COMPRESSED:
/* process escape */
for (i = 0;i<c->str_len;i++) {
if (c->str_data[i] == c->escape_char) {
COMP_DBG("C enc ESCAPE %d\n", c->escape_char);
c->escape_char += ESCAPE_STEP;
}
}
/* send codeword */
/* check cw size and send STEPUP if need */
while (cw >= c->threshold) {
SEND_CW(c,CCW_STEPUP);
SEND_BITS(c);
c->threshold <<= 1;
c->cw_size++;
COMP_DBG("C enc STEPUP %d\n",c->cw_size);
}
SEND_CW(c,cw);
SEND_BITS(c);
COMP_DBG1("enc send %d: '%s'\n",cw,show_string(c,cw));
break;
}
c->str_len = 0;
c->flushed_len = 0;
return ret;
}
/* test compression */
static int test_mode(struct comp_state *c)
{
int ret = 0;
switch(c->mode) {
case TRANSPARENT:
/* fixme: why 11 ? */
if (c->cmp_last < (TEST_SLICE<<3) - 11) {
/* switch to compressed mode */
COMP_DBG("encoder %d/%d %d: --> COMPRESSED mode.\n",
c->cmp_bits,c->raw_bits,c->cmp_last);
if (c->last_matched) {
c->update_at = c->last_matched;
ret += send_data(c,c->last_matched);
c->last_matched = 0;
}
c->obuf[c->olen++] = c->escape_char;
c->obuf[c->olen++] = CC_ECM;
ret += 2;
c->bit_data = 0;
c->mode = COMPRESSED;
}
#if 0
else if (0) { /* fixme: when RESET? */
COMP_DBG("encoder RESET\n");
}
#endif
break;
case COMPRESSED:
if (c->cmp_last > (TEST_SLICE<<3)) {
/* switch to transparent mode */
COMP_DBG("encoder %d/%d %d: --> TRANSPARENT mode.\n",
c->cmp_bits,c->raw_bits,c->cmp_last);
if (c->last_matched) {
c->update_at = c->last_matched;
ret += send_data(c,c->last_matched);
c->last_matched = 0;
}
c->last_added = 0;
SEND_CW(c,CCW_ETM);
ALIGN_BITS(c);
SEND_BITS(c);
c->mode = TRANSPARENT;
}
break;
}
return ret;
}
/* flush encoder data */
int comp_flush_encoder(struct comp_state *c)
{
int ret = 0;
//COMP_DBG1("flush_encoder...\n");
#if 1 /* fixme: use something better */
if (c->update_at) {
return 0;
}
#endif
if (c->last_matched) {
int total_len = c->flushed_len + c->str_len;
ret = send_data(c,c->last_matched);
c->flushed_len = total_len;
}
if(c->mode == COMPRESSED) {
c->update_at = c->last_matched;
c->last_matched = 0;
c->flushed_len = 0;
//if (c->bit_len > 0) {
COMP_DBG("flush_encoder: send FLUSH\n");
/* send FLUSH and align by zeros */
SEND_CW(c,CCW_FLUSH);
ALIGN_BITS(c);
SEND_BITS(c);
//}
}
if (ret)
COMP_DBG("flush_encoder %d...\n", ret);
return ret;
}
/* encoder */
#define NEW_ENCODER 1
int comp_encode(struct comp_state *c, u8 *in, int n)
{
register int i, ret=0;
register u16 cw = 0;
for(i=0;i<n;) {
if (c->update_at) {
if (!match_char(c,c->update_at,*in)) {
c->last_added = add_char(c,c->update_at,*in);
COMP_DBG1("enc add %d at %d: %d(%c) '%s'\n",
c->last_added,c->update_at,
*in,*in,show_string(c,c->last_added));
}
c->update_at = 0;
}
#if NEW_ENCODER
/* match string */
while(i<n) {
cw = match_char(c,c->last_matched,*in);
if (!cw) {
c->update_at = c->last_matched;
ret += send_data(c,c->last_matched);
c->last_matched = 0;
break;
}
if (cw == c->last_added) {
c->last_added = 0;
ret += send_data(c,c->last_matched);
c->last_matched = 0;
break;
}
c->last_matched = cw;
/* collect char */
c->str_data[c->str_len++] = *in++; i++;
if ( c->str_len + c->flushed_len == c->max_string ) {
ret += send_data(c,c->last_matched);
c->last_matched = 0;
break;
}
}
ret += test_mode(c);
}
#else
/* match char */
cw = match_char(c,c->last_matched,*in);
if (!cw) {
/* add char */
c->update_at = c->last_matched;
/* send and reset string */
ret += send_data(c,c->last_matched);
c->last_matched = 0;
}
else if (cw == c->last_added) {
c->last_added = 0;
/* send and reset string */
ret += send_data(c,c->last_matched);
c->last_matched = 0;
}
else {
c->last_matched = cw;
/* collect char */
c->str_data[c->str_len++] = *in++;
if ( c->str_len + c->flushed_len == c->max_string ) {
/* send and reset string */
ret += send_data(c,c->last_matched);
c->last_matched = 0;
}
i++;
}
}
ret += test_mode(c);
#endif
return ret;
}
#if COMP_TEST
/*
* Test encoder procedures
*
*/
/* force reset */
int comp_force_reset(struct comp_state *c)
{
int ret = 0;
if (c->mode != TRANSPARENT)
return 0;
COMP_DBG("comp_reset...\n");
if (c->last_matched) {
ret = send_data(c,c->last_matched);
c->last_matched = 0;
}
c->obuf[c->olen++] = c->escape_char;
c->obuf[c->olen++] = CC_RESET;
ret += 2;
c->bit_data = 0;
dict_init(c);
return ret;
}
/* force change compression mode */
int comp_force_change_mode(struct comp_state *c, enum COMP_MODE mode)
{
int ret = 0;
if (mode == c->mode)
return 0;
COMP_DBG("change_mode...\n");
if (c->last_matched) {
c->update_at = c->last_matched;
ret += send_data(c,c->last_matched);
c->last_matched = 0;
}
/* switch to compressed mode */
if (c->mode == TRANSPARENT) {
COMP_DBG("encoder %ld/%ld %d: switch to COMPRESSED mode.\n",
c->cmp_bits,c->raw_bits,c->cmp_last);
c->obuf[c->olen++] = c->escape_char;
c->obuf[c->olen++] = CCW_ECM;
ret += 2;
c->bit_data = 0;
c->mode = COMPRESSED;
}
/* switch to transparent mode */
else if (c->mode == COMPRESSED) {
COMP_DBG("encoder %ld/%ld %d: switch to TRANSPARENT mode.\n",
c->cmp_bits,c->raw_bits,c->cmp_last);
SEND_CW(c,CCW_ETM);
ALIGN_BITS(c);
SEND_BITS(c);
c->mode = TRANSPARENT;
}
return ret;
}
#endif
/*
* init procedures
*
*/
int comp_init(struct comp_state *c,int dict_size,int max_str)
{
struct dict *d;
int i;
memset(c,0,sizeof(*c));
if (dict_size < MIN_DICT_SIZE ||
max_str < MIN_STR_SIZE || max_str > MAX_STR_SIZE)
return -1;
/* alloc dict */
d = COMP_ALLOC(dict_size*sizeof(*d));
if (!d)
return -1;
COMP_DBG("comp_init: dict size %d, max str %d (dict %d bytes).\n",
dict_size,max_str,dict_size*sizeof(*d));
memset(d,0,dict_size*sizeof(*d));
c->max_string= max_str;
c->dict_size = dict_size;
c->dict = d;
/* init dict */
for(i=0;i<TOTAL_CHARS;i++) {
c->dict[i+FIRST_ENTRY].ch = i;
}
dict_init(c);
/* temporary */
c->olen = 0;
return 0;
}
int comp_config(struct comp_state *c,int dict_size,int max_str)
{
if (dict_size < MIN_DICT_SIZE ||
max_str < MIN_STR_SIZE || max_str > MAX_STR_SIZE)
return -1;
if (dict_size > c->dict_size || max_str > sizeof(c->str_data))
return -1;
c->max_string= max_str;
c->dict_size = dict_size;
//dict_init(c);
/* temporary */
//c->olen = 0;
return 0;
}
int comp_exit(struct comp_state *c)
{
COMP_DBG("comp exit: %d/%d %d\n",
c->cmp_bits,c->raw_bits,c->cmp_last);
c->dict_size = 0;
if(c->dict) {
COMP_FREE(c->dict);
c->dict = NULL;
}
return 0;
}
/*
* modem init procedures
*
*/
/* exported functions prototypes */
extern int comp_init(struct comp_state *c,int dict_size,int max_str);
extern int comp_config(struct comp_state *c,int dict_size,int max_str);
extern int comp_exit(struct comp_state *c);
extern int comp_encode(struct comp_state *c, u8 *in, int n);
extern int comp_decode(struct comp_state *c, u8 *in, int n);
extern int comp_flush_encoder(struct comp_state *c);
extern int comp_flush_decoder(struct comp_state *c);
int modem_comp_init(struct modem *m)
{
int ret;
ret = comp_init(&m->comp.encoder,
m->cfg.comp_dict_size,m->cfg.comp_max_string);
if(ret)
return ret;
ret = comp_init(&m->comp.decoder,
m->cfg.comp_dict_size,m->cfg.comp_max_string);
if (ret) {
comp_exit(&m->comp.encoder);
return ret;
}
return 0;
}
int modem_comp_config(struct modem *m,int dict_size,int max_str)
{
int ret = 0;
if ((ret = comp_config(&m->comp.encoder,dict_size,max_str)) ||
(ret = comp_config(&m->comp.decoder,dict_size,max_str)) )
COMP_ERR("modem_comp_config: setup failed (%d/%d).\n",
dict_size,max_str);
return ret;
}
void modem_comp_exit(struct modem *m)
{
comp_exit(&m->comp.encoder);
comp_exit(&m->comp.decoder);
// temproary
m->comp.head = m->comp.count = 0;
}
// FIXME: remove this stupest things
static int get_odata(struct comp_state *c, char *buf, int n)
{
int ret = 0;
if(c->olen > 0) {
ret = c->olen - c->ohead < n ?
c->olen - c->ohead : n;
memcpy(buf,c->obuf+c->ohead,ret);
c->ohead += ret;
if (c->ohead == c->olen) {
c->ohead = 0;
c->olen = 0;
}
}
return ret;
}
int modem_comp_encode(struct modem *m, u8 ch, char *buf, int n)
{
int ret;
ret = get_odata(&m->comp.encoder,buf,n);
if (ret == n) return ret;
if(comp_encode(&m->comp.encoder,&ch,1)<0)
return -1;
ret += get_odata(&m->comp.encoder,buf+ret,n-ret);
return ret;
}
int modem_comp_decode(struct modem *m, u8 ch, char *buf, int n)
{
int ret;
ret = get_odata(&m->comp.decoder,buf,n);
if(ret == n) return ret;
if(comp_decode(&m->comp.decoder,&ch,1)<0)
return -1;
ret += get_odata(&m->comp.decoder,buf+ret,n-ret);
return ret;
}
int modem_comp_flush_encoder(struct modem *m, char *buf, int n)
{
int ret;
ret = get_odata(&m->comp.encoder,buf,n);
if (ret == n) return ret;
if(comp_flush_encoder(&m->comp.encoder) < 0)
return -1;
ret += get_odata(&m->comp.encoder,buf+ret,n-ret);
return ret;
}
int modem_comp_flush_decoder(struct modem *m, char *buf, int n)
{
int ret;
ret = get_odata(&m->comp.decoder,buf,n);
if (ret == n) return ret;
if(comp_flush_decoder(&m->comp.decoder) < 0)
return -1;
ret += get_odata(&m->comp.decoder,buf+ret,n-ret);
return ret;
}
+137
View File
@@ -0,0 +1,137 @@
/*****************************************************************************/
/*
*
* Copyright (c) 2002, Smart Link Ltd.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* 3. Neither the name of the Smart Link Ltd. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/*
*
* modem_datafile.c -- modem data file stuff.
*
* Author: Sasha K (sashak@smlink.com)
*
*/
/*****************************************************************************/
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <modem_defs.h>
#include <modem_debug.h>
#define DBG(fmt,args...) dprintf( fmt , ##args );
struct datafile_record {
unsigned minor;
struct dsp_info dsp_info;
unsigned size;
};
int datafile_load_info(char *file_name,struct dsp_info *info)
{
struct datafile_record *dr;
int ret = -1;
int fd;
DBG("open file: %s...\n",file_name);
fd = open(file_name, 0, 0);
if(fd < 0) {
DBG("cannot open '%s': %s\n",
file_name,strerror(errno));
return -errno;
}
dr = (struct datafile_record *)malloc(sizeof(*dr));
if (!dr) {
close(fd);
return -errno;
}
ret = read(fd,(char *)dr,sizeof(*dr));
if (ret < 0) {
free(dr);
close(fd);
return -errno;
}
/* simple validation */
if(dr->size != sizeof(*dr)) {
free(dr);
close(fd);
return -1;
}
memcpy(info,&dr->dsp_info,sizeof(*info));
free(dr);
close(fd);
return ret;
}
int datafile_save_info(char *file_name,struct dsp_info *info)
{
struct datafile_record *dr;
int ret = -1;
int fd;
fd = open(file_name,O_CREAT|O_WRONLY,(S_IRUSR|S_IWUSR));
if(fd < 0)
return -errno;
dr = (struct datafile_record *)malloc(sizeof(*dr));
if (!dr) {
return -errno;
close(fd);
}
memcpy(&dr->dsp_info,info,sizeof(*info));
dr->size = sizeof(*dr);
ret = write(fd,(char *)dr,sizeof(*dr));
free(dr);
close(fd);
return ret;
}
+169
View File
@@ -0,0 +1,169 @@
/*****************************************************************************/
/*
*
* Copyright (c) 2002, Smart Link Ltd.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* 3. Neither the name of the Smart Link Ltd. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/*
*
* modem_debug.c -- modem debug module (dummy).
*
* Author: Sasha K (sashak@smlink.com)
*
*
*/
/*****************************************************************************/
#include <stdarg.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <fcntl.h>
#include <limits.h>
#include <modem.h>
#include <modem_debug.h>
unsigned int modem_debug_level=0;
unsigned int modem_debug_logging=0;
unsigned int dsplibs_debug_level=0;
static const char *modem_debug_logfile = "slmodem.log";
static int modem_log_fd;
/* logging */
int modem_debug_log_data(struct modem *m, unsigned id, const void *data, int count)
{
struct sllog_header hdr;
int ret = 0;
if(id <= modem_debug_logging && modem_log_fd > 0) {
hdr.modem_id = (unsigned)m ;
hdr.id = id;
hdr.length = count;
ret = write(modem_log_fd,&hdr,sizeof(hdr));
if(ret < 0) {
fprintf(stderr,"log_data: cannot write header: %s\n",
strerror(errno));
return ret;
}
ret = write(modem_log_fd,data,count);
if(ret < 0) {
fprintf(stderr,"log_data: cannot write data: %s\n",
strerror(errno));
return ret;
}
}
return ret;
}
/* printing */
static int debug_vprintf(unsigned level, const char *fmt, va_list args)
{
static char debug_temp[512];
struct timeval tv;
int i, len;
gettimeofday(&tv,NULL);
i = snprintf(debug_temp,sizeof(debug_temp),"<%03ld.%06ld> ",
(tv.tv_sec % 1000), tv.tv_usec);
len = vsnprintf(debug_temp + i, sizeof(debug_temp) - i, fmt, args);
if(modem_debug_logging)
modem_debug_log_data(0,
MODEM_DBG_PRINT_MSG,debug_temp,len + i);
if(level <= modem_debug_level)
fprintf( stderr, "%s", debug_temp);
return len;
}
int dsplibs_debug_printf(const char *fmt, ...)
{
va_list args;
int len;
va_start(args, fmt);
len = debug_vprintf(dsplibs_debug_level, fmt, args);
va_end(args);
return len;
}
int modem_debug_printf(const char *fmt, ...)
{
va_list args;
int len;
va_start(args, fmt);
len = debug_vprintf(1, fmt, args);
va_end(args);
return len;
}
int modem_debug_init(const char *suffix)
{
dsplibs_debug_level = modem_debug_level;
if(modem_debug_logging) {
char path_name[PATH_MAX];
const char *name;
if(suffix) {
snprintf(path_name, sizeof(path_name),
"%s.%s", modem_debug_logfile, suffix);
name = path_name;
}
else
name = modem_debug_logfile;
modem_log_fd = creat(name,S_IREAD|S_IWRITE);
if(modem_log_fd < 0) {
fprintf(stderr,"cannot create `%s': %s\n",
name,strerror(errno));
return -1;
}
if(dsplibs_debug_level < 3)
dsplibs_debug_level = 3;
}
return 0;
}
void modem_debug_exit()
{
if(modem_log_fd > 0) {
close(modem_log_fd);
modem_log_fd = 0;
}
}
+104
View File
@@ -0,0 +1,104 @@
/*
*
* Copyright (c) 2002, Smart Link Ltd.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* 3. Neither the name of the Smart Link Ltd. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/*
*
* modem_debug.h - modem debug definitions.
*
* Author: SashaK <sashak@smlink.com>
*
* Change History:
*
*/
#ifndef __MODEM_DEBUG_H__
#define __MODEM_DEBUG_H__
/* constant definitions */
enum MODEM_LOG_CATEGORIES {
/* 0-3 */
MODEM_DBG_PRINT_MSG = 0,
MODEM_DBG_RX_SAMPLES,
MODEM_DBG_TX_SAMPLES,
MODEM_DBG_ECHOC_SAMPLES,
/* 4-5 */
MODEM_DBG_MISC_DATA,
MODEM_DBG_MISC1_DATA,
/* 6-9 */
MODEM_DBG_RX_BITS,
MODEM_DBG_TX_BITS,
MODEM_DBG_RX_DATA,
MODEM_DBG_TX_DATA,
/* 10-11 */
MODEM_DBG_RX_CHARS,
MODEM_DBG_TX_CHARS,
/* 'overflow marker' */
MODEM_DBG_OVERFLOW
};
struct sllog_header {
unsigned modem_id;
unsigned id;
unsigned length;
char data[0];
};
struct modem;
#ifdef CONFIG_DEBUG_MODEM
extern unsigned modem_debug_level;
extern int modem_debug_printf(const char *fmt,...)
__attribute__ ((format (printf, 1, 2)));
#define eprintf(args...) { modem_debug_printf("err: " args) ; }
#define dprintf(args...) { modem_debug_printf(args) ; }
extern int modem_debug_log_data(struct modem *m, unsigned id, const void *, int);
#else /* not CONFIG_DEBUG_MODEM */
#define eprintf(fmt...)
#define dprintf(fmt...)
#define modem_debug_log_data(m,id,data,cnt)
#endif /* not CONFIG_DEBUG_MODEM */
extern int modem_debug_init(const char *suffix);
extern void modem_debug_exit();
#endif /* __MODEM_DEBUG_H__ */
+443
View File
@@ -0,0 +1,443 @@
/*
*
* Copyright (c) 2002, Smart Link Ltd.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* 3. Neither the name of the Smart Link Ltd. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/*
*
* modem_defs.h - modem common definitions
*
* Author: sashak@smlink.com
*/
#ifndef __MODEM_DEFS_H__
#define __MODEM_DEFS_H__
#ifdef __KERNEL__
#include <linux/types.h>
#else
#include <sys/types.h>
typedef __uint8_t u8;
typedef __uint16_t u16;
typedef __uint32_t u32;
typedef __int8_t s8;
typedef __int16_t s16;
typedef __int32_t s32;
#endif /* !__KERNEL__ */
/* hook states */
#define MODEM_HOOK_ON 0
#define MODEM_HOOK_OFF 1
#define MODEM_HOOK_SNOOPING 2
/* modem device ctrl interface */
#define MDMCTL_CAPABILITIES 0x01
#define MDMCTL_HOOKSTATE 0x02
#define MDMCTL_SPEED 0x04
#define MDMCTL_GETFMTS 0x05
#define MDMCTL_SETFMT 0x06
#define MDMCTL_SETFRAG 0x07
#define MDMCTL_SETFRAGMENT MDMCTL_SETFRAG
#define MDMCTL_SPEAKERVOL 0x08
#define MDMCTL_IODELAY 0x10
#define MDMCTL_CODECTYPE 0x11
#define MDMCTL_PULSEDIAL 0x12
#define MDMCTL_GETSTAT 0x20
#define MDMCTL_START 0x21
#define MDMCTL_STOP 0x22
/* modem device status mask */
#define MDMSTAT_ERROR 0x1
#define MDMSTAT_RING 0x2
#define MDMSTAT_DATA 0x4
/* codec types - numbers important */
enum codec_types {
CODEC_UNKNOWN = 0,
CODEC_AD1821 = 1,
CODEC_STLC7550= 4,
CODEC_SILABS = 9,
CODEC_SIL3052 = 10,
CODEC_SIL3054 = 11,
CODEC_AD1803 = 12,
CODEC_ALC545A = 13,
};
/* sample formats + extensions */
#define MFMT_SIZE_MASK 0x000f
#define MFMT_SIZE_8 0x0000
#define MFMT_SIZE_16 0x0001
#define MFMT_SIGN_MASK 0x00f0
#define MFMT_SIGNED 0x0010
#define MFMT_UNSIGNED 0x0000
#define MFMT_ORDER_MASK 0x0f00
#define MFMT_ORDER_LE 0x0100
#define MFMT_ORDER_BE 0x0000
#define MFMT_QUERY 0x0
#define MFMT_S8 (MFMT_SIZE_8|MFMT_SIGNED)
#define MFMT_U8 (MFMT_SIZE_8|MFMT_UNSIGNED)
#define MFMT_S16_LE (MFMT_SIZE_16|MFMT_SIGNED|MFMT_ORDER_LE)
#define MFMT_S16_BE (MFMT_SIZE_16|MFMT_SIGNED|MFMT_ORDER_BE)
#define MFMT_U16_LE (MFMT_SIZE_16|MFMT_UNSIGNED|MFMT_ORDER_LE)
#define MFMT_U16_BE (MFMT_SIZE_16|MFMT_UNSIGNED|MFMT_ORDER_BE)
#define MFMT_IS_16BIT(x) ((x)&MFMT_SIZE_16)
#define MFMT_IS_LE(x) ((x)&MFMT_ORDER_LE)
#define MFMT_BYTESSHIFT(x) ((x)&MFMT_SIZE_MASK)
#define MFMT_SHIFT(x) (MFMT_BYTESSHIFT(x))
#define MFMT_BYTES(x) (1<<MFMT_BYTESSHFIT(x))
/* s-registers */
enum S_REGISTER {
SREG_RINGS_TO_AUTO_ANSWER = 0,
SREG_RING_COUNTER = 1,
SREG_ESCAPE_CHAR = 2,
SREG_CR_CHAR = 3,
SREG_LF_CHAR = 4,
SREG_BS_CHAR = 5,
SREG_DIAL_TONE_WAIT_TIME = 6,
SREG_WAIT_CARRIER_AFTER_DIAL = 7,
SREG_DIAL_PAUSE_TIME = 8,
SREG_CARRIER_DETECT_RESPONSE_TIME = 9,
SREG_CARRIER_LOSS_DISCONNECT_TIME = 10,
SREG_DTMF_DURATION = 11,
SREG_ESCAPE_PROMPT_DELAY = 12,
SREG_ECHO = 13,
SREG_QUIET = 14,
SREG_VERBOSE = 15,
SREG_TONE_OR_PULSE = 16,
SREG_TEST_TIMER = 18,
SREG_INACTIVITY_TIMEOUT = 19,
SREG_BREAK_LENGTH = 21,
SREG_ORIGIN_OR_ANSWER = 22,
SREG_XOFF_CHAR = 23,
SREG_FLASH_TIMER = 24,
SREG_DELAY_TO_DTR_OFF = 25, /* (NA) */
SREG_RTS_TO_CTS_DELAY = 26, /* (NA) */
SREG_AUTOANSWER_CLEAR_TIMEOUT = 27,
SREG_PULSE_RATIO = 28,
SREG_SPEAKER_CONTROL = 29,
SREG_SPEAKER_VOLUME = 30,
SREG_SPEAKER_LEVEL = 30,
SREG_AUTOMODE = 31,
SREG_DP = 32,
#if 1
SREG_LINE_QUALITY_CONTROL = 39,
SREG_X_CODE = 56,
SREG_CD = 60, /* (&CN) */
SREG_FLOW_CONTROL = 62, /* (&HN) */
SREG_CONNNECT_MSG_FORMAT = 70,
SREG_CONNNECT_MSG_SPEED_SRC = 71,
SREG_ANS_DELAY = 92,
/* new sgregs */
SREG_EC = 103,
SREG_COMP = 104,
SREG_DEFAULT_SETTING = 161, // AT used
#else
SREG_REQUESTED_DP = SREG_DP,
SREG_REQUESTED_MIN_SPEED = 33,
SREG_REQUESTED_MAX_SPEED = 34,
SREG_ACTUAL_SPEED = 35,
SREG_CONNECT_RESULT_CODE = 35,
SREG_DATA_PUMP_STATUS = 36,
SREG_VXX_STATUS = 36,
SREG_ACTUAL_DP = 37,
SREG_ACTUAL_RX_SPEED = 38,
SREG_LINE_QUALITY_CONTROL = 39,
SREG_SIGNAL_RECEPTION_GAIN = 41,
SREG_SNR = 42,
SREG_RESULT_CODES_CONTROL = 43,
SREG_CONFIGURATION_SETTING = 44,
SREG_SIGNAL_TRANSMISSION_LEVEL = 45,
SREG_DISTINCTIVE_RING_SILENCE_PERIOD = 48,
SREG_ADAPTIVE_ANSWER_MODE = 49,
SREG_TEST_BASE = 50,
SREG_TEST_MODE = SREG_TEST_BASE,
SREG_TEST_PAR1 = (SREG_TEST_BASE+1),
SREG_MAPPED_S28 = 52,
SREG_MAPPED_S37 = 53,
SREG_TEST_RES1 = (SREG_TEST_BASE+4),
SREG_TEST_RES2 = (SREG_TEST_BASE+5),
SREG_X_CODE = 56,
SREG_MESSAGE_DETAIL = 57,
SREG_CURRENT_SETTING = 59, /* (ZN,&FN) */
SREG_CD = 60, /* (&CN) */
SREG_FLOW_CONTROL = 62, /* (&HN) */
SREG_CIRCUIT_106 = 66,
SREG_CIRCUIT_107 = 67,
SREG_CIRCUIT_109 = 68,
SREG_CONNNECT_MSG_FORMAT = 70,
SREG_COMMAND_AT_A = 70,
SREG_CONNNECT_MSG_SPEED_SRC = 71,
/* Modem Support registers */
SREG_HANDSET_GANE = 72,
SREG_RECBUF_PURGE_UPON_ABORT = 73,
SREG_VOICE_DIALTONE_DETECT_DELAY = 73, /* in seconds */
SREG_PLAYBACK_VALUME = 74, /* #VGT */
SREG_CID_ENABLE = 75, /* #CID */
SREG_ADPCM_BPS = 76, /* #VBS */
SREG_BEEP_TONE_TIMER = 77, /* #VBT */
SREG_VOICE_SRC_SELECT = 78, /* #VLS */
SREG_RING_GOES_AWAY_TIMER = 79, /* #VRA */
SREG_RING_NEVER_CAME_TIMER = 80, /* #VRN */
SREG_SILENCE_DETECT_ENABLE = 81, /* #VSD */
SREG_SILENCE_DETECT_SENSITIVITY = 82, /* #VSS */
SREG_SILENCE_DETECT_DURATION = 83, /* #VSP */
SREG_DTMF_TONE_REPORTS_CAP0 = 84, /* #VTD */
SREG_DTMF_TONE_REPORTS_CAP1 = 85,
SREG_DTMF_TONE_REPORTS_CAP2 = 86,
SREG_TIME_MARK_PLACEMENT = 87, /* #VTM */
SREG_SPK_MUTE = 88, /* #SPK */
SREG_SPK_SPKR = 89, /* #SPK 2 */
SREG_SPK_MICROPHONE = 90, /* #SPK 3 */
SREG_ADPCM_SAMPLE_RATE = 91, /* #VSR */
SREG_ANS_DELAY = 92,
/* Voice Modem Support registers */
SREG_DP_CYCLE_TIME = 93,
SREG_ENV_CYCLE_TIME = 94,
SREG_V42_CYCLE_TIME = 95,
/* Sample Rate Sregister: */
SREG_AUDIO_SAMPLE_RATE = 96,
SREG_RAW_RMS_ENABLE = 97,
SREG_RAW_RMS_IN = 98,
SREG_RAW_RMS_OUT = 99,
SREG_V42_BASEREG = 100,
SREG_V42_DATA_LINK = SREG_V42_BASEREG,
SREG_V42_MNP_BLOCK_SIZE = (SREG_V42_BASEREG + 1),
SREG_V42_DATA_COMPRESSION = (SREG_V42_BASEREG + 2),
SREG_V42_OUTPUT_PROTOCOL = (SREG_V42_BASEREG + 24),
SREG_V42_OUTPUT_COMRESION = (SREG_V42_BASEREG + 26),
SREG_V42_ORIG_REQUEST = (SREG_V42_BASEREG + 29),
SREG_V42_ORIG_FALLBACK = (SREG_V42_BASEREG + 30),
SREG_V42_ANSWER_FALLBACK = (SREG_V42_BASEREG + 31),
SREG_V42_COMPRESSION_RATIO_REPORT = (SREG_V42_BASEREG + 32),
SREG_V42_BAD_BYTES_PERCENTAGE = (SREG_V42_BASEREG + 33),
SREG_RS_DEBUG_LEVEL = (SREG_V42_BASEREG + 34),
SREG_V42_EA_SINGLE_UNIT_TIME = (SREG_V42_BASEREG + 35),
SREG_V42_EA_USED_UNITS_NUMBER = (SREG_V42_BASEREG + 36),
SREG_V42_EA_CRITICAL_BAD_UNITS_NUMBER = (SREG_V42_BASEREG + 37),
SREG_MIC_GAIN = 138,
SREG_LINE_RECORD_GAIN = 139,
SREG_LOCAL_FLASH = 140,
SREG_V42_EA_CRITICAL_BAD_UNITS_NUMBER_FOR_V34 = (SREG_V42_BASEREG+41),
SREG_ATH1_FLAG = 142,
SREG_BELL_MODE = 143,
SREG_MAPPED_S35 = 144,
SREG_TEST_COMMAND_SUBMODE = 145,
SREG_PULSE_MAKE = 146, /* Percent */
SREG_PULSE_PPS = 147, /* 10,20 */
SREG_PULSE_PAUSE = 148, /* * 10ms */
SREG_PULSE_REFRESH = 149, /* ms */
SREG_FCLASS_CURRENT = 150,
SREG_FAE_CURRENT = 151,
SREG_LINE_OUT_GAIN = 152,
SREG_SPK_OUT_GAIN = 153,
SREG_HS_OUT_GAIN = 154,
SREG_DTMF_LOW_GAIN_DB_2SCOMP = 155,
SREG_DTMF_HIGH_GAIN_DB_2SCOMP = 156,
SREG_SINUS_SAMPLE_RATE_REG_1 = 157,
SREG_SINUS_SAMPLE_RATE_REG_2 = 158,
SREG_PULSEDIAL_DISABLE = 159,
/* ---------- Unsaved region from 160 ------------------- */
SREG_DEFAULT_SETTING = 161, // AT used
SREG_CALL_PROGRESS_CODE = 162,
SREG_COUNTRY_CODE = 162,
SREG_DEBUG_REG_0 = 170,
SREG_DEBUG_REG_1 = 171,
SREG_DEBUG_REG_2 = 172,
SREG_DEBUG_REG_3 = 173,
SREG_DEBUG_REG_4 = 174,
SREG_DIAG_PROC_CNT1_ID = 180,
SREG_DIAG_PROC_CNT2_ID = 181,
SREG_DIAG_RING = 182,
SREG_DIAG_COUNT_TYPE = 183,
SREG_DIAG_TYPE = 184,
SREG_DIAG_SCOPE = 185,
SREG_PM_UPPER_THR = 186,
SREG_PM_LOWER_THR = 187,
SREG_PM_WEIGHT1 = 188,
SREG_PM_WEIGHT2 = 189,
SREG_PM_DEGRADE_ENABLE = 190,
SREG_PM_DECISION_VALUE = 191,
SREG_PROCESSOR_TYPE = 193,
SREG_HW_TRACE_LEVEL = 197,
SREG_HARDWARE_CONTROL = 197,
SREG_STRM_TRACE_LEVEL = 198,
SREG_STREAM_MANAGER_DEBUG_LEVEL = 198,
SREG_BLACKLISTING_ENABLED_FLAG = 200,
SREG_FAILED_ATTEMPTS_BEFORE_BLACKLISTING = 201,
SREG_BLACKLISTING_DURATION = 202,
SREG_BLACKLIST_TIMEOUT = 203,
SREG_AT_P_COMMAND_DISABLED = 204,
SREG_CID_TIMEOUT_IN_100MS = 205,
SREG_V90_PAD_TYPE = 210,
SREG_V90_POWER_REDUCTION = 211,
SREG_V90_PROBING_MODE = 212,
SREG_V90_COMPUTATIONAL_MODE = 213,
SREG_CALL_PROGRESS_SIGNAL_RECEPTION_GAIN = 214,
SREG_LINE_QUALITY = 215,
SREG_DC_RECALIBRATION_PERIOD = 216,
SREG_UPSTREAM_MIN_RATE = 217,
SREG_UPSTREAM_MAX_RATE = 218,
SREG_V22_LEVEL_CONTROL = 220,
SREG_CALLING_TONE_LEVEL_CONTROL = 221,
#endif
};
/* data pumps identifiers */
enum DP_ID {
DP_CALLPROG = 2,
DP_DUMMY = 3,
DP_AUTOMODE = 4,
DP_V8 = 8,
DP_V17 = 17,
DP_V21 = 21,
DP_V22 = 22,
DP_V23 = 23,
DP_V22BIS = 122,
DP_V32 = 32,
DP_V32BIS = 132,
DP_V34 = 34,
DP_V34BIS = 134,
DP_B103 = 103,
DP_B212 = 212,
DP_FAX = 100,
DP_K56 = 56,
DP_K56_OR_V90 = 65,
DP_V8BIS = 108,
DP_V90 = 90,
DP_V90_NO_V8BIS = 91,
DP_V92 = 92,
DP_TEST = 126,
DP_SINUS = 127,
DP_MAX = 128,
MAX_DP = 128
};
/* dp status */
#define DPSTAT_OK 0
#define DPSTAT_CONNECT 1
#define DPSTAT_ERROR 4
#define DPSTAT_NODIALTONE 6
#define DPSTAT_BUSY 7
#define DPSTAT_NOANSWER 8
#define DPSTAT_CHANGEDP 10
/* dsp info structure */
struct dsp_info {
unsigned connection_type;
long clock_deviation;
unsigned qc_lapm;
unsigned qc_index;
};
/* fax definitions */
#define FAX_STATUS_OK 1
#define FAX_STATUS_ERROR 2
#define FAX_STATUS_CONNECT 3
#define FAX_STATUS_NOCARRIER 4
enum FAX_CMD {
FAX_CMD_FTS,
FAX_CMD_FRS,
FAX_CMD_FTM,
FAX_CMD_FRM,
FAX_CMD_FTH,
FAX_CMD_FRH,
};
/* voice definitions */
enum VOICE_CMD {
VOICE_CMD_STATE_COMMAND,
VOICE_CMD_STATE_RX,
VOICE_CMD_STATE_TX,
VOICE_CMD_STATE_DUPLEX,
VOICE_CMD_STATE_SPEAKER,
VOICE_CMD_BEEP,
VOICE_CMD_DTMF,
VOICE_CMD_ABORT,
};
#define VOICE_STATUS_OK 1
#define VOICE_STATUS_ERROR 2
#define VOICE_STATUS_CONNECT 3
#define VOICE_STATE_COMMAND 0x00
#define VOICE_STATE_RX 0x01
#define VOICE_STATE_TX 0x02
#define VOICE_STATE_DUPLEX (VOICE_STATE_TX|VOICE_STATE_RX)
#define VOICE_STATE_SPEAKER 0x08
#define VOICE_DEVICE_NONE 0
#define VOICE_DEVICE_LINE 1
struct voice_info {
unsigned comp_method;
unsigned sample_rate;
unsigned rx_gain;
unsigned tx_gain;
unsigned dtmf_symbol;
unsigned tone1_freq;
unsigned tone2_freq;
unsigned tone_duration;
unsigned inactivity_timer;
unsigned silence_detect_sensitivity;
unsigned silence_detect_period;
};
/*
* prototypes
*
*/
struct modem;
extern int modem_get_sreg(struct modem *m, unsigned int num);
extern int modem_set_sreg(struct modem *m, unsigned int num, int val);
#endif /* __MODEM_DEFS_H__ */
+91
View File
@@ -0,0 +1,91 @@
/*
*
* Copyright (c) 2002, Smart Link Ltd.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* 3. Neither the name of the Smart Link Ltd. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/*
*
* modem_dp.h - modem data pumps interface definitions
*
* Author: sashak@smlink.com
*/
#ifndef __MODEM_DP_H__
#define __MODEM_DP_H__
#include <modem_defs.h>
/*
* type definitions
*
*/
/* data pump operations structure */
struct dp_operations {
const char *name;
int use_count;
/* dp interface */
struct dp *(*create)(struct modem *, enum DP_ID id,
int caller, int srate, int max_frag,
struct dp_operations *);
int (*delete)(struct dp *);
int (*process)(struct dp *, void *in, void *out, int cnt);
int (*hangup)(struct dp *);
};
/* data pump structure */
struct dp {
enum DP_ID id;
struct modem *modem;
unsigned status;
struct dp_operations *op;
void *dp_data;
};
/*
* prototypes
*
*/
/* bit interface */
extern int modem_get_bits(struct modem *m, int nbits, u8 *buf, int n);
extern int modem_put_bits(struct modem *m, int nbits, u8 *buf, int n);
/* modem dp registration */
extern int modem_dp_register(enum DP_ID id, struct dp_operations *op);
extern void modem_dp_deregister(enum DP_ID id, struct dp_operations *op);
#endif /* __MODEM_DP_H__ */
+1425
View File
File diff suppressed because it is too large. Load diff
+111
View File
@@ -0,0 +1,111 @@
/*****************************************************************************/
/*
*
* Copyright (c) 2002, Smart Link Ltd.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* 3. Neither the name of the Smart Link Ltd. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/*
*
* modem_homolog.h -- Modem Homologation definitions.
*
* Author: Sasha K (sashak@smlink.com)
*
*
*/
/*****************************************************************************/
#ifndef __MODEM_HOMOLOG_H__
#define __MODEM_HOMOLOG_H__
/* homologation parameters struct */
struct homolog_params {
u8 PulseDialMakeTime;
u8 PulseDialBreakTime;
u8 PulseDialDigitPattern;
u8 DTMFHighToneLevel;
u8 DTMFDialSpeed;
u8 MinBusyCadenceOnTime;
u8 MaxBusyCadenceOnTime;
u8 BusyDetectionCyclesNumber;
u8 MinBusyCadenceOffTime;
u8 MaxBusyCadenceOffTime;
u8 CallingToneFlag;
u8 HookFlashTime;
u8 DialPauseTime; // ?
u8 TransmitLevel;
u8 DialModifierValidation;
u8 DialToneValidationTime;
//u8 BusyToneDiffTime;
u8 DTMFHighAndLowToneLevelDifference;
u8 DialToneCallProgressFilterIndex;
u8 DialToneDetectionThreshold;
u8 ABCDDialingPermittedFlag;
u8 ComaPauseDurationLimit;
//u8 PulseAndToneDialInSameDialStringPermittedFlag;
u8 BusyToneCallProgressFilterIndex;
u8 PulseBetweenDigitsInterval;
u8 DialToneWaitTime;
u8 MinRingbackCadenceOnTime;
u8 MaxRingbackCadenceOnTime;
u8 RingbackDetectionCyclesNumber;
//u8 MinRingbackCadenceOffTime;
//u8 MaxRingbackCadenceOffTime;
//u8 RingbackToneCallProgressFilterIndex;
//u8 MinCongestionCadenceOnTime;
//u8 MaxCongestionCadenceOnTime;
//u8 CongestionDetectionCyclesNumber;
//u8 MinCongestionCadenceOffTime;
//u8 MaxCongestionCadenceOffTime;
//u8 CongestionToneCallProgressFilterIndex;
u16 CallProgressSamplesBufferLength;
u8 MustNoiseFilterBeApplied;
//u32 DigitalImpairmentsMask;
//u8 DialToneFilterSubindex;
//u8 BusyToneLooseDetectionEnabled;
//u8 CallWaitingIntegrationTimeMiliSec;
//u8 CallWaitingThresholdPercentage;
};
/* homologation country set */
struct homolog_set {
const u16 id;
const char *name;
const struct homolog_params *params;
};
/* 'nulled'-terminated homologation array */
extern const struct homolog_set homolog_set[];
#endif /* __MODEM_HOMOLOG_H__ */
File diff suppressed because it is too large. Load diff
+634
View File
@@ -0,0 +1,634 @@
/*
*
* Copyright (c) 2002, Smart Link Ltd.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* 3. Neither the name of the Smart Link Ltd. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/*
*
* modem_pack.c -- modem packer module.
*
* Author: Sasha K (sashak@smlink.com)
*
*
*/
#include <modem.h>
#include <modem_debug.h>
#define PACK_DBG(fmt,arg...) dprintf("%s: " fmt , m->name , ##arg)
#define PACK_ERR(fmt,arg...) eprintf("%s: " fmt , m->name , ##arg)
/* HDLC definitions */
#define HDLC_FLAG 0x7e
#define HDLC_ESCAPE (0x1f<<3)
/* bit ordering (reverse) table */
static const u8 _ordered[] = {
0x0,0x8,0x4,0xc,0x2,0xa,0x6,0xe,
0x1,0x9,0x5,0xd,0x3,0xb,0x7,0xf};
#define REVERSE_BITS(c) { (c) = _ordered[(c)&0xf]<<4 | _ordered[(c)>>4] ; }
/*
* Async packer
*
*/
#define START_BIT 0
#define STOP_BIT 1
#if 0
#define STOP_BITS(p) ((p)->stop_bits)
#define DATA_SIZE(p) ((p)->data_bits)
#define CHAR_SIZE(p) ((p)->char_size)
#define CHAR_DATA(p,ch) ( ( ~(0x1<<(CHAR_SIZE(p)-1)) & \
((ch)<<(p)->stop_bits) ) | \
((0x1<<(p)->stop_bits)-1) )
#else
#define STOP_BITS(p) 1
#define DATA_SIZE(p) 8
#define CHAR_SIZE(p) 10
#define CHAR_DATA(p,ch) (((ch)<<1)|0x1)
#endif
int modem_async_get_bits(struct modem *m, int nbits, u8 *bit_buf, int bit_cnt)
{
struct bits_state *s = &m->pack;
int ret = 0;
u8 ch;
do {
/* fill bits */
while ( bit_cnt > 0 && s->bit >= nbits) {
*bit_buf++ = (s->data>>(s->bit-nbits));
s->bit -= nbits;
ret ++;
bit_cnt--;
}
if (bit_cnt <= 0)
break;
/* get char */
if (!m->get_chars || m->get_chars(m, (char*)&ch, 1) != 1)
break;
REVERSE_BITS(ch);
s->data <<= CHAR_SIZE(m);
s->data |= CHAR_DATA(m,ch);
s->bit += CHAR_SIZE(m);
} while (1);
if (s->bit && bit_cnt > 0) {
/* left data + stops */
*bit_buf++ = (s->data<<(nbits-s->bit))|((0x1<<(nbits-s->bit))-1);
ret ++;
bit_cnt--;
s->bit = 0;
}
#if 0
memcpy(bit_buf,(1<<nbits)-1,bit_cnt);
ret += bit_cnt;
#else
while (bit_cnt > 0) {
/* fill stops */
*bit_buf++ = (1<<nbits)-1;
bit_cnt --;
ret ++;
}
#endif
return ret;
}
int modem_async_put_bits(struct modem *m, int nbits, u8 *bit_buf, int bit_cnt)
{
struct bits_state *s = &m->unpack;
int ret = 0;
u8 ch;
while(bit_cnt > 0) {
s->data<<= nbits;
s->data |= *bit_buf++ & ((0x1<<nbits)-1);
s->bit += nbits;
bit_cnt --;
ret++;
while(s->bit && s->data&(0x1<<(s->bit-1))) /* stop bit */
s->bit--;
while (s->bit >= CHAR_SIZE(m)) {
ch = s->data >>
(s->bit-(CHAR_SIZE(m)-STOP_BITS(m)));
s->bit-= CHAR_SIZE(m);
REVERSE_BITS(ch);
if (m->put_chars)
m->put_chars(m,(const char*)&ch,1);
}
}
return ret;
}
void modem_async_start(struct modem *m)
{
m->pack.bit = m->unpack.bit = 0;
m->pack.data = m->unpack.data = 0;
m->bit_timer_func = NULL;
m->bit_timer = 0;
}
/*
* Packer detector
*
*/
/*
* Detection phase description.
* originator - transmits ODPs until T400 timer is expired
* or until ADP is received.
*
* answer - transmits marks(1) until: detect phase termination,
* ODP receipt - send at least 10 ADPs,
* detection of start protocol phase (continuous flags).
*
*
*/
/* ODP: 0100010001 11111111 0100010011 11111111 */
#define ODP0 0x88
#define ODP1 0x89
/* ADP v42: 0101000101 11111111 0110000101 11111111 */
/* ADP v14: 0101000101 11111111 0000000001 11111111 */
#define ADP0 0xa2
#define ADP1_V14 0x00
#define ADP1_V42 0xc2
#define ADP1 ADP1_V42
#define MIN_RX_PATTERNS 2
#define MAX_TX_PATTERNS 16
#define PATTERN_SIZE 36
#define FILL_PATTERN_ODP(pat) { (pat)[0]=ODP0 ; (pat)[1]=ODP1; }
#define FILL_PATTERN_ADP(pat) { (pat)[0]=ADP0 ; (pat)[1]=ADP1; }
static void detector_start(struct modem *m)
{
PACK_DBG("detector start...\n");
m->packer.detector.tx_count = 1;
}
static void detector_finish(struct modem *m)
{
PACK_DBG("detector finished.\n");
// fixme: modem update config
m->cfg.ec = m->packer.detector.ec_enable;
modem_update_status(m,STATUS_PACK_LINK);
}
int modem_detector_get_bits(struct modem *m, int nbits, u8 *bit_buf, int bit_cnt)
{
struct bits_state *s = &m->pack;
struct detect_state *d = &m->packer.detector;
int ret = 0;
do {
/* fill bits */
while ( bit_cnt > 0 && s->bit >= nbits) {
*bit_buf++ = (s->data>>(s->bit-nbits));
s->bit -= nbits;
ret ++;
bit_cnt--;
}
if (bit_cnt <= 0)
break;
#if 0
s->data <<= 18;
s->data |= (0x1ff<<9)|(d->tx_pattern[d->tx_count++%2]);
s->bit += 18;
#else
/* get char */
s->data <<= 9;
s->data |= 0x1ff;
s->bit += 9;
if (d->tx_count > 0) {
s->data <<= 9;
s->data |= d->tx_pattern[d->tx_count++%2];
s->bit += 9;
}
#endif
} while (1);
return ret;
}
int modem_detector_put_bits(struct modem *m, int nbits, u8 *bit_buf, int bit_cnt)
{
struct bits_state *s = &m->unpack;
struct detect_state *d = &m->packer.detector;
int ret = 0;
u8 ch;
while(bit_cnt > 0) {
s->data<<= nbits;
s->data |= *bit_buf++ & ((0x1<<nbits)-1);
s->bit += nbits;
bit_cnt --;
ret++;
while(s->bit && s->data&(0x1<<(s->bit-1))) /* skip marks */
s->bit--;
while (s->bit >= 10 ) {
ch = s->data >> (s->bit-9);
s->bit-= 10;
PACK_DBG("rx pattern: 0x%02x.\n",ch);
if (ch == HDLC_FLAG) {
PACK_DBG("hdlc flag detected.\n");
d->ec_enable = 1;
m->bit_timer_func = detector_finish;
m->bit_timer = PATTERN_SIZE;
continue;
}
if (!d->rx_count) {
d->rx_count = (ch == d->rx_pattern[0]);
continue;
}
if (d->rx_count >= 2)
continue;
switch(ch) {
case ODP1:
//PACK_DBG("rx ODP.\n");
if (!m->caller) {
/* start replay ADP and leave detector */
d->tx_count = 1;
d->rx_count = 2;
d->ec_enable = 1;
m->bit_timer_func = detector_finish;
m->bit_timer = MAX_TX_PATTERNS*PATTERN_SIZE;
}
else
d->rx_count = 0;
break;
case ADP1_V14:
//PACK_DBG("rx ADP non v42.\n");
d->rx_count = 2;
d->ec_enable = 0;
m->bit_timer_func = detector_finish;
m->bit_timer = PATTERN_SIZE;
break;
case ADP1_V42:
//PACK_DBG("rx ADP v42.\n");
m->cfg.ec = 1;
d->rx_count = 2;
d->ec_enable = 1;
m->bit_timer_func = detector_finish;
m->bit_timer = PATTERN_SIZE;
break;
default:
d->rx_count = 0;
break;
}
}
}
return ret;
}
void modem_detector_start(struct modem *m) {
struct detect_state *d = &m->packer.detector;
int rate = 28800 ; // fixme: use real bit rate from modem
d->tx_count = 0; /* mute transmitter */
d->rx_count = 0;
d->ec_enable = 0;
if (m->caller) {
FILL_PATTERN_ODP(d->tx_pattern);
FILL_PATTERN_ADP(d->rx_pattern);
m->bit_timer_func = detector_start;
m->bit_timer = 64*8 ;
}
else {
FILL_PATTERN_ADP(d->tx_pattern);
FILL_PATTERN_ODP(d->rx_pattern);
m->bit_timer_func = detector_finish;
m->bit_timer = rate*3/4; /* T400 timeout */
}
m->pack.bit = m->unpack.bit = 0;
m->pack.data = m->unpack.data = 0;
}
/*
* HDLC packer
*
*/
/* static data */
/* fcs16 table */
static const
u16 fcs16_tab[256] = {
0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
};
#define fcstab fcs16_tab
#define INIT_FCS16 0xffff /* Initial FCS16 value */
#define GOOD_FCS16 0xf0b8 /* Good final FCS16 value */
#define GET_FCS(fcs,c) (((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff])
#define INIT_FCS INIT_FCS16 /* Initial FCS value */
#define GOOD_FCS GOOD_FCS16 /* Good final FCS value */
/* hdlc bit generators */
#define HDLC_PUT_BYTE { \
for( i = 0 ; i < 8 ; i++ ) { \
s->data<<=1; \
s->bit++; \
if(in&0x1) { \
h->tx_ones++; \
s->data |= 0x1; \
if (h->tx_ones==5) { \
s->data<<=1; \
s->bit++; \
h->tx_ones = 0; \
} \
} \
else { \
h->tx_ones = 0; \
} \
in>>=1; \
} }
int modem_hdlc_get_bits(struct modem *m, int nbits,
u8 *bit_buf, int bit_cnt)
{
struct hdlc_state *h = &m->packer.hdlc;
register struct bits_state *s = &m->pack;
register int i, ret = 0;
register u8 in, mask = ((1<<nbits) - 1);
do {
/* fill bits */
while ( bit_cnt > 0 && s->bit >= nbits) {
*bit_buf++ = (s->data>>(s->bit-nbits))&mask;
s->bit -= nbits;
ret ++;
bit_cnt--;
}
if (bit_cnt <= 0)
break;
if (!h->tx_frame) {
s->data <<= 8;
s->data |= HDLC_FLAG;
s->bit += 8;
if (h->get_tx_frame &&
(h->tx_frame = h->get_tx_frame(h->framer))) {
h->tx_frame->fcs = INIT_FCS;
h->tx_frame->count = 0;
}
}
else if(h->tx_frame->count == h->tx_frame->size) {
/* end frame */
/* put fcs */
h->tx_frame->fcs ^= 0xffff;
in = h->tx_frame->fcs&0xff;
HDLC_PUT_BYTE;
in = (h->tx_frame->fcs>>8)&0xff;
HDLC_PUT_BYTE;
h->tx_ones = 0;
/* frame complete callback */
if (h->tx_complete)
h->tx_complete(h->framer, h->tx_frame);
/* reset tx frame */
h->tx_frame = NULL;
/* put flags will done automatically */
}
else {
in = h->tx_frame->buf[h->tx_frame->count];
h->tx_frame->count++;
/* fixme: in order to speed up
fcs calc: copy it to local var */
h->tx_frame->fcs = GET_FCS(h->tx_frame->fcs,in);
HDLC_PUT_BYTE;
}
} while (1);
return ret;
}
int modem_hdlc_put_bits(struct modem *m, int nbits,
u8 *bit_buf, int bit_cnt)
{
struct hdlc_state *h = &m->packer.hdlc;
register struct bits_state *s = &m->unpack;
register int ret = 0;
register int i;
register u8 in, out, mask = ((0x1<<nbits)-1);
while(bit_cnt > 0) {
s->data <<= nbits;
s->data |= *bit_buf++ & mask;
s->bit += nbits;
bit_cnt--;
ret++;
/* 8 char, 2 possible escapes, +8 estimated flag */
if ( s->bit < 8 + 8 + 2)
continue;
out = 0;
// fixme: probably may be optimized by handling whole
// byte with masking
/* mask = 0x80; */
for ( i=0 ; i<8 ; i++ ) {
in = s->data >> (s->bit-8) ;
/* flag: finish frame */
if (in == HDLC_FLAG) {
/* end of frame */;
if ( !h->rx_frame->count ) {
//HDLC_DBG("empty.\n");
}
/* check frame for errors */
else if (h->rx_error) {
PACK_DBG("hdlc frame error.\n");
}
else if (i) {
PACK_DBG("hdlc frame integrity error.\n");
}
#if 1
else if ( h->rx_frame->count < 3 ) {
#else
else if ( h->rx_frame->count < 4 ) {
#endif
PACK_DBG("hdlc frame size error.\n");
}
else if ( h->rx_frame->fcs != GOOD_FCS ) {
PACK_DBG("hdlc frame fcs error.\n");
}
/* good frame */
else if ( h->rx_complete ) {
/* reduce fcs size */
h->rx_frame->count -= 2;
h->rx_complete(h->framer,h->rx_frame);
}
s->bit -= 8;
h->rx_ones = 0;
h->rx_error = 0;
h->rx_frame->fcs = INIT_FCS;
h->rx_frame->count = 0;
break;
}
else if(h->rx_error) {
s->bit--;
continue;
}
/* put reversed data bit */
out >>= 1;
if (in&0x80) {
out |= 0x80;
h->rx_ones++;
/* escape or idle reached */
if (h->rx_ones == 5) {
if (in&0x40) {
h->rx_error++;
h->rx_frame->count = 0;
}
s->bit--;
h->rx_ones = 0;
}
}
else
h->rx_ones = 0;
s->bit--;
}
/* finish char */
if(i==8 && !h->rx_error) {
if (h->rx_frame->count < h->rx_frame->size) {
h->rx_frame->buf[h->rx_frame->count] = out;
h->rx_frame->count++;
h->rx_frame->fcs = GET_FCS(h->rx_frame->fcs,out);
}
else { /* overflow */
PACK_DBG("hdlc rx frame overflow.\n");
h->rx_error++;
h->rx_frame->count = 0;
}
}
}
return ret;
}
void modem_hdlc_start(struct modem *m)
{
struct hdlc_state *h = &m->packer.hdlc;
PACK_DBG("hdlc_start...\n");
memset(h,0,sizeof(*h));
/* wait for flag to clear rx error state */
h->rx_error = 1;
/* rx frame */
h->rx_frame = &h->_rx_frame;
h->rx_frame->buf = h->_rx_buf;
h->rx_frame->count= 0;
h->rx_frame->size = sizeof(h->_rx_buf);
h->rx_frame->fcs = INIT_FCS;
/* tx frame */
h->tx_frame = 0;
m->pack.bit = m->unpack.bit = 0;
m->pack.data = m->unpack.data = 0;
m->bit_timer_func = NULL;
m->bit_timer = 0;
}
#if 0
// temp stupid things
static struct hdlc_frame *tmp_get_frame(void *framer)
{
frame_t *f;
struct modem *m = framer;
if(m->get_chars) {
f = &m->packer.hdlc._tx_frame;
f->buf = m->packer.hdlc._tx_buf;
f->size = m->get_chars(m,f->buf,sizeof(m->packer.hdlc._tx_buf));
if(f->size <= 0) {
return NULL;
}
PACK_DBG("get frame: %d...\n",f->size);
return f;
}
return NULL;
}
static void tmp_put_frame(void *framer, frame_t *fr)
{
struct modem *m = framer;
if(fr->count > 0 && m->put_chars) {
PACK_DBG("put frame: %d...\n",fr->count);
m->put_chars(m,fr->buf,fr->count);
}
return;
}
void tmp_init(struct modem *m)
{
m->packer.hdlc.get_tx_frame = tmp_get_frame;
m->packer.hdlc.rx_complete = tmp_put_frame;
m->packer.hdlc.framer = m;
}
#endif
+207
View File
@@ -0,0 +1,207 @@
/*
*
* Copyright (c) 2002, Smart Link Ltd.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* 3. Neither the name of the Smart Link Ltd. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/*
*
* modem_param.c -- modem parameters access module.
*
* Author: Sasha K (sashak@smlink.com)
*
*
*/
#include <modem.h>
#include <modem_homolog.h>
#include <modem_param.h>
/* param access services */
long modem_get_sreg_param(struct modem *m,unsigned sreg_num)
{
return modem_get_sreg(m,sreg_num);
}
long modem_get_param(struct modem *m, unsigned param_name)
{
int val;
switch (param_name) {
case MDMPRM_NONE:
break;
case MDMPRM_MIN_RATE:
return m->min_rate;
case MDMPRM_MAX_RATE:
return m->max_rate;
case MDMPRM_IODELAY:
return m->driver.ioctl(m,MDMCTL_IODELAY,0);
case MDMPRM_CODECTYPE:
val = m->driver.ioctl(m,MDMCTL_CODECTYPE,0);
if(val<0)
return CODEC_UNKNOWN; /* unknown */
return val;
case MDMPRM_DIALSTR:
return (long)m->dial_string;
case MDMPRM_AUTOMODE:
return 0 /* MODEM_AUTOMODE(m)*/;
case MDMPRM_DPRUNTIME:
return (long)(m->dp_runtime);
case MDMPRM_DSPINFO:
return (long)(&m->dsp_info);
#ifdef MODEM_CONFIG_VOICE
case MDMPRM_VOICEINFO:
return (long)(&m->voice_info);
#endif
case MDMPRM_DP_ADDR:
return (long)(m->dp);
case GetPulseDialMakeTime:
return m->homolog->params->PulseDialMakeTime;
case GetPulseDialBreakTime:
return m->homolog->params->PulseDialBreakTime;
case GetPulseDialDigitPattern:
return m->homolog->params->PulseDialDigitPattern;
case GetDTMFHighToneLevel:
return m->homolog->params->DTMFHighToneLevel;
case GetDTMFDialSpeed:
return modem_get_sreg(m,SREG_DTMF_DURATION);
case GetMinBusyCadenceOnTime:
return m->homolog->params->MinBusyCadenceOnTime;
case GetMaxBusyCadenceOnTime:
return m->homolog->params->MaxBusyCadenceOnTime;
case GetBusyDetectionCyclesNumber:
return m->homolog->params->BusyDetectionCyclesNumber;
case GetMinBusyCadenceOffTime:
return m->homolog->params->MinBusyCadenceOffTime;
case GetMaxBusyCadenceOffTime:
return m->homolog->params->MaxBusyCadenceOffTime;
case GetCallingToneFlag:
return m->homolog->params->CallingToneFlag;
case GetHookFlashTime:
#if 0
return modem_get_sreg(m,SREG_FLASH_TIMER);
#else
return m->homolog->params->HookFlashTime;
#endif
case GetBlindDialPause:
return modem_get_sreg(m,SREG_DIAL_TONE_WAIT_TIME);
case GetNoAnswerTimeOut:
return modem_get_sreg(m,SREG_WAIT_CARRIER_AFTER_DIAL);
case GetDialPauseTime:
return modem_get_sreg(m,SREG_DIAL_PAUSE_TIME);
case GetTransmitLevel:
return m->homolog->params->TransmitLevel;
case GetDialModifierValidation:
return m->homolog->params->DialModifierValidation;
case GetDialToneValidationTime:
return m->homolog->params->DialToneValidationTime;
case GetBusyToneDiffTime:
return 0;
case GetDTMFHighAndLowToneLevelDifference:
return m->homolog->params->DTMFHighAndLowToneLevelDifference;
case GetPulseDialingFlag:
return !modem_get_sreg(m,SREG_TONE_OR_PULSE);
case GetDialToneCallProgressFilterIndex:
return m->homolog->params->DialToneCallProgressFilterIndex;
case GetDialToneDetectionThreshold:
return m->homolog->params->DialToneDetectionThreshold;
case GetABCDDialingPermittedFlag:
return m->homolog->params->ABCDDialingPermittedFlag;
case GetComaPauseDurationLimit:
return m->homolog->params->ComaPauseDurationLimit;
case GetPulseAndToneDialInSameDialStringPermittedFlag:
return 0;
case GetBusyToneCallProgressFilterIndex:
return m->homolog->params->BusyToneCallProgressFilterIndex;
case GetPulseBetweenDigitsInterval:
return m->homolog->params->PulseBetweenDigitsInterval;
case GetDialToneWaitTime:
return modem_get_sreg(m,SREG_DIAL_TONE_WAIT_TIME);
case GetMinRingbackCadenceOnTime:
return m->homolog->params->MinRingbackCadenceOnTime;
case GetMaxRingbackCadenceOnTime:
return m->homolog->params->MaxRingbackCadenceOnTime;
case GetRingbackDetectionCyclesNumber:
return m->homolog->params->RingbackDetectionCyclesNumber;
case GetMinRingbackCadenceOffTime:
case GetMaxRingbackCadenceOffTime:
case GetRingbackToneCallProgressFilterIndex:
case GetMinCongestionCadenceOnTime:
case GetMaxCongestionCadenceOnTime:
case GetCongestionDetectionCyclesNumber:
case GetMinCongestionCadenceOffTime:
case GetMaxCongestionCadenceOffTime:
case GetCongestionToneCallProgressFilterIndex:
return 0;
case GetCallProgressSamplesBufferLength:
return m->homolog->params->CallProgressSamplesBufferLength;
case MustNoiseFilterBeApplied:
return m->homolog->params->MustNoiseFilterBeApplied;
case GetAdditAttenToBeepgenVoice:
return 0;
case GetDialToneFilterSubindex:
return 0;
case GetBusyToneLooseDetectionEnabled:
return 0;
}
return -1;
}
long modem_set_param(struct modem *m, unsigned name, int val)
{
switch(name) {
case MDMPRM_NONE:
break;
case MDMPRM_RX_RATE:
m->rx_rate = val;
break;
case MDMPRM_TX_RATE:
m->tx_rate = val;
break;
case MDMPRM_DP_REQUESTED:
m->dp_requested = val;
break;
case MDMPRM_UPDATE_DELAY:
m->update_delay = val;
break;
case MDMPRM_HOOK_ON:
return m->driver.ioctl(m, MDMCTL_HOOKSTATE,
val ? MODEM_HOOK_ON : MODEM_HOOK_OFF );
case MDMPRM_PULSE_DIAL:
// bla-bla
return m->driver.ioctl(m, MDMCTL_PULSEDIAL, val);
default:
return -1;
}
return 0;
}
+202
View File
@@ -0,0 +1,202 @@
/*
*
* Copyright (c) 2002, Smart Link Ltd.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* 3. Neither the name of the Smart Link Ltd. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/*
*
* modem_param.h -- modem parameters access definitions.
*
* Author: Sasha K (sashak@smlink.com)
*
*
*/
#ifndef __MODEM_PARAM_H__
#define __MODEM_PARAM_H__
/* param names */
enum MODEM_PARAMETER_NAMES {
MDMPRM_NONE,
MDMPRM_RX_RATE,
MDMPRM_RATE = MDMPRM_RX_RATE,
MDMPRM_TX_RATE,
MDMPRM_MIN_RATE,
MDMPRM_MAX_RATE,
MDMPRM_IODELAY,
MDMPRM_CODECTYPE,
MDMPRM_DIALSTR,
MDMPRM_AUTOMODE,
MDMPRM_DP_REQUESTED,
MDMPRM_DPRUNTIME,
MDMPRM_DSPINFO,
MDMPRM_VOICEINFO,
MDMPRM_UPDATE_DELAY,
MDMPRM_DP_ADDR,
MDMPRM_HOOK_ON,
MDMPRM_PULSE_DIAL,
//GetDTMFBetweenDigitsInterval,
GetPulseDialMakeTime,
GetPulseDialBreakTime,
GetPulseDialDigitPattern,
GetDTMFHighToneLevel,
GetDTMFDialSpeed,
//GetCallProgressDetectionThreshold,
//GetDialToneDelay,
//GetDialToneHoleTime,
//GetDelayBeforeRingCountResettingInMcs,
//GetRingCountForAutoanswer,
//GetMinRingSignalPeriodInMcs,
//GetMaxRingSignalPeriodInMcs,
//GetMinRingCadenceOnTimeInMcs,
//GetRingCadenceOffTimeInMcs,
GetMinBusyCadenceOnTime,
GetMaxBusyCadenceOnTime,
GetBusyDetectionCyclesNumber,
GetMinBusyCadenceOffTime,
GetMaxBusyCadenceOffTime,
//GetContinuousUnavailableDetectionFlag,
//GetAnswerToneValidationTime,
//GetBlacklistingDelayedFlag,
//GetFailedAttemptsAllowedInFirstStage,
//GetFailedAttemptsNumberBeforeBlacklisting,
//GetTroubledCallDelay,
//GetIneffectiveCallDelay,
//GetErroneousCallDelay,
//GetBlackListingDuration,
//GetLoopCurrentSenseWaitingTime,
GetCallingToneFlag,
//GetBlindDialFlag,
//GetBusyDetectDisable,
//GetGuardToneType,
//GetBellModesPermittedFlag,
//GetOffHookRestrictions,
//GetShuntRelayOnTimeDuringOffHook,
GetHookFlashTime,
GetBlindDialPause,
GetNoAnswerTimeOut,
GetDialPauseTime,
//GetNoCarrierDisconnectTime,
GetTransmitLevel,
GetDialModifierValidation,
//GetTADReceiveGain,
//GetHalfOrFullWaveRingDetection,
//GetFailedAttemptsNumberBeforeBlockingFurtherAttempts,
//GetErroneousCallIncrementCount,
GetDialToneValidationTime,
//GetDialToneMinOnTimePeriod,
GetBusyToneDiffTime,
//GetBusyToneDetectionDuringDialToneDetectionFlag,
GetDTMFHighAndLowToneLevelDifference,
//GetLocalPhoneDetectionInSpeakerphone,
GetPulseDialingFlag,
GetDialToneCallProgressFilterIndex,
GetDialToneDetectionThreshold,
GetABCDDialingPermittedFlag,
GetComaPauseDurationLimit,
//GetTADTransmitLevel,
//GetDataFAXCarrierReceiveThreshold,
//GetNoDialToneTimeOutDuration,
//GetFAXDataAnswerToneDetectionThreshold,
//GetDialToneLevel,
//GetFAXCallingToneLevel,
GetPulseAndToneDialInSameDialStringPermittedFlag,
//GetRingerImpedanceRelayFlag,
//GetDCLoopVICharacteristicsRelayFlag,
//GetDCLoopLimitingRelayFlag,
//GetRealOrComplexImpedance,
//GetMinPauseBetweenRingSequencesInMcs,
//GetMaxPauseBetweenRingSequencesInMcs,
//GetMinRingCadenceOnTimeFirstInMcs,
//GetMaxRingCadenceOnTimeFirstInMcs,
//GetMinRingCadenceOnTimeForFirstSequenceInMcs,
//GetMaxRingCadenceOnTimeForFirstSequenceInMcs,
//GetMaxRingCadenceOnTimeInMcs,
//GetNumberOfSequencesInFirstRing,
//GetNumberOfSequencesInRegularRing,
//IsALaw,
GetBusyToneCallProgressFilterIndex,
//GetCoefficientTableIndex,
GetPulseBetweenDigitsInterval,
GetDialToneWaitTime,
//GetAnswerDelay,
//GetPulseRefresh,
//GetHandsetGain,
//GetSpecificHardwareBitmask,
//GetDefaultDTMFDialSpeed,
//GetDefaultNoAnswerTimeout,
//GetBlacklistingTimeout,
//IsATPCommandDisabled,
//GetDelayAfterCounterpartDisconnection,
//IsFloatModeForced,
//GetDataFaxCarrierDisconnectThreshold,
//GetFaxTransmitLevel,
//GetPulseDialingRefreshScheme,
GetMinRingbackCadenceOnTime,
GetMaxRingbackCadenceOnTime,
GetRingbackDetectionCyclesNumber,
GetMinRingbackCadenceOffTime,
GetMaxRingbackCadenceOffTime,
GetRingbackToneCallProgressFilterIndex,
GetMinCongestionCadenceOnTime,
GetMaxCongestionCadenceOnTime,
GetCongestionDetectionCyclesNumber,
GetMinCongestionCadenceOffTime,
GetMaxCongestionCadenceOffTime,
GetCongestionToneCallProgressFilterIndex,
GetCallProgressSamplesBufferLength,
MustNoiseFilterBeApplied,
//GetDigitalImpairmentsMask,
GetAdditAttenToBeepgenVoice,
GetDialToneFilterSubindex,
GetBusyToneLooseDetectionEnabled,
//GetRingFreqValueInHz(int);
//GetEndUniversalRingTimeoutInMcs,
//GetRingIntsForFreq,
//GetDelayBeforeUniversalRingCountResettingInMcs,
//GetUniversalRingDetectorEnabled,
//GetCallWaitingIntegrationTimeMiliSec,
//GetCallWaitingThresholdPercentage,
//GetDialStringAfterFlash(char *dialString);
MDMPRM_LAST
};
struct modem;
extern long modem_get_param(struct modem *m, unsigned param);
extern long modem_set_param(struct modem *m, unsigned name, int val);
extern long modem_get_sreg_param(struct modem *m, unsigned sreg_param);
#endif /* __MODEM_PARAM_H__ */
+481
View File
@@ -0,0 +1,481 @@
/*
*
* Copyright (c) 2002, Smart Link Ltd.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* 3. Neither the name of the Smart Link Ltd. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/*
*
* modem_test.c -- modem simulator.
*
* Author: Sasha K (sashak@smlink.com)
*
*
*/
#define _GNU_SOURCE
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <signal.h>
#include <termios.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <modem.h>
#include <modem_debug.h>
#define INFO(fmt,args...) fprintf(stderr, fmt , ##args );
#define ERR(fmt,args...) fprintf(stderr, "error: " fmt , ##args );
#define DBG(fmt,args...) if(modem_debug_level) \
fprintf(stderr, "main: " fmt , ##args );
//#define SIMULATE_RING 1
/* modem init externals : FIXME remove it */
extern int dp_dummy_init(void);
extern void dp_dummy_exit(void);
extern int dp_sinus_init(void);
extern void dp_sinus_exit(void);
extern int prop_dp_init(void);
extern void prop_dp_exit(void);
extern int datafile_load_info(char *name,struct dsp_info *info);
extern int datafile_save_info(char *name,struct dsp_info *info);
/* global config data */
extern unsigned modem_debug_logging;
struct modem_test {
struct modem *modem;
struct modem_test *link;
int in,out;
unsigned int delay;
unsigned int started;
unsigned pty_closed;
unsigned close_count;
};
#define CLOSE_COUNT_MAX 100
/* static data */
static char inbuf[4096];
static char outbuf[4096];
/* 'driver' simulation */
static int modem_test_start (struct modem *m)
{
struct modem_test *t = m->dev_data;
DBG("modem_test_start...\n");
t->delay = 256;
t->started = 1;
memset(outbuf,0,t->delay);
write(t->out,outbuf,t->delay);
return 0;
}
static int modem_test_stop (struct modem *m)
{
struct modem_test *t = m->dev_data;
DBG("modem_test_stop...\n");
t->started = 0;
t->delay = 0;
return 0;
}
static int modem_test_ioctl(struct modem *m, unsigned int cmd, unsigned long arg)
{
struct modem_test *t = m->dev_data;
DBG("modem_test_ioctl: cmd %x, arg %lx...\n",cmd,arg);
switch (cmd) {
case MDMCTL_CAPABILITIES:
return -1;
case MDMCTL_HOOKSTATE:
return 0;
case MDMCTL_SPEED:
return 0;
case MDMCTL_GETFMTS:
case MDMCTL_SETFMT:
return 0;
case MDMCTL_SETFRAGMENT:
return 0;
case MDMCTL_SPEAKERVOL:
return 0;
case MDMCTL_CODECTYPE:
return CODEC_UNKNOWN;
case MDMCTL_IODELAY:
return t->delay/2;
default:
break;
}
return -2;
}
struct modem_driver modem_test_driver = {
.name = "modem_test driver",
.start = modem_test_start,
.stop = modem_test_stop,
.ioctl = modem_test_ioctl,
};
/*
*
*/
static volatile sig_atomic_t keep_running = 1;
void mark_termination(int signum)
{
DBG("signal %d: mark termination.\n",signum);
keep_running = 0;
}
static int modem_test_run(struct modem_test *modems)
{
struct timeval tmo;
fd_set rset,eset;
struct termios termios;
struct modem_test *t;
void *in;
int max_fd = 0;
int count, ret;
#ifdef SIMULATE_RING
#define RING_HZ 20
#define RING_ON 1*RING_HZ
#define RING_OFF 4*RING_HZ
unsigned rcount = RING_ON;
#endif
while(keep_running) {
for( t = modems ; t->modem ; t++ )
if(t->modem->event)
modem_event(t->modem);
#ifdef SIMULATE_RING
tmo.tv_sec = 0;
tmo.tv_usec= 1000000/RING_HZ;
#else
tmo.tv_sec = 1;
tmo.tv_usec= 0;
#endif
FD_ZERO(&rset);
FD_ZERO(&eset);
max_fd = 0;
for( t = modems ; t->modem ; t++ ) {
FD_SET(t->in,&rset);
FD_SET(t->in,&eset);
if(t->in > max_fd)
max_fd = t->in;
if( t->pty_closed && t->close_count ) {
if ( !t->started ||
t->close_count++ > CLOSE_COUNT_MAX )
t->close_count = 0;
}
else if (t->modem->xmit.size - t->modem->xmit.count > 0) {
FD_SET(t->modem->pty,&rset);
if(t->modem->pty > max_fd)
max_fd = t->modem->pty;
}
}
ret = select(max_fd + 1,&rset,NULL,&eset,&tmo);
if (ret < 0) {
if (errno == EINTR) {
continue;
}
ERR("select: %s\n",strerror(errno));
return ret;
}
//DBG("select = %d\n",ret);
if (ret == 0) {
#ifdef SIMULATE_RING
if(!modems->modem->started) {
rcount++;
if (rcount <= RING_ON)
modem_ring(modems->modem);
else if (rcount > RING_OFF)
rcount = 0;
}
#endif
continue;
}
for( t = modems ; t->modem ; t++ ) {
if(FD_ISSET(t->in,&eset)) {
DBG("dev exception...\n");
}
}
for( t = modems ; t->modem ; t++ ) {
if(FD_ISSET(t->in,&rset)) {
//DBG("dev read...\n");
count = read(t->in,inbuf,sizeof(inbuf)/2);
if(count < 0) {
ERR("dev read: %s\n",strerror(errno));
return -1;
}
else if (count == 0) {
DBG("dev read = 0\n");
continue;
}
in = inbuf;
if(t->modem->update_delay < 0) {
if ( -t->modem->update_delay >= count/2) {
DBG("change delay -%d...\n", count/2);
t->delay -= count;
t->modem->update_delay += count/2;
continue;
}
DBG("change delay %d...\n", t->modem->update_delay);
in -= t->modem->update_delay*2;
count += t->modem->update_delay*2;
t->delay += t->modem->update_delay*2;
t->modem->update_delay = 0;
}
if(t->started) {
modem_process(t->modem,in,outbuf,count>>1);
}
else {
memset(outbuf,0,count);
/* ring here */
}
count = write(t->out,outbuf,count);
if(count < 0) {
ERR("dev write: %s\n",strerror(errno));
return -1;
}
else if (count == 0) {
DBG("dev write = 0\n");
}
if(t->modem->update_delay > 0) {
DBG("change delay %d...\n", t->modem->update_delay);
memset(outbuf, 0, t->modem->update_delay*2);
count = write(t->out,outbuf,t->modem->update_delay*2);
if(count < 0) {
ERR("dev write: %s\n",strerror(errno));
return -1;
}
t->delay += t->modem->update_delay*2;
t->modem->update_delay = 0;
}
}
}
for( t = modems ; t->modem ; t++ ) {
int pty = t->modem->pty;
if(FD_ISSET(pty,&rset)) {
//DBG("pty read...\n");
/* check termios */
tcgetattr(pty,&termios);
if(memcmp(&termios,&t->modem->termios,
sizeof(termios))) {
DBG("termios changed.\n");
modem_update_termios(t->modem, &termios);
}
/* read data */
count = t->modem->xmit.size - t->modem->xmit.count;
if(count == 0)
continue;
if (count > sizeof(inbuf))
count = sizeof(inbuf);
count = read(pty,inbuf,count);
if(count < 0) {
if(errno == EAGAIN) {
DBG("pty read, errno = EAGAIN\n");
continue;
}
if(errno == EIO) {
if(!t->pty_closed) {
DBG("pty closed.\n");
t->pty_closed = 1;
if(termios.c_cflag&HUPCL)
modem_hangup(t->modem);
}
t->close_count = 1;
//DBG("pty read, errno=EIO\n");
continue;
}
else
ERR("pty read: %s\n",
strerror(errno));
return -1;
}
else if (count == 0) {
DBG("pty read = 0\n");
}
t->pty_closed = 0;
//DBG("pty read %d\n",count);
count = modem_write(t->modem,inbuf,count);
if(count < 0) {
DBG("modem_write failed.\n");
return -1;
}
}
}
}
return 0;
}
static int modem_test_init(struct modem_test *t, const char *name, int in, int out)
{
struct termios termios;
char *pty_name;
int pty;
int ret;
memset(t,0,sizeof(*t));
t->in = in;
t->out = out;
pty = getpt();
if (pty < 0 || grantpt(pty) < 0 || unlockpt(pty) < 0) {
ERR("getpt: %s\n",strerror(errno));
exit(-1);
}
ret = tcgetattr(pty, &termios);
/* non canonical raw tty */
cfmakeraw(&termios);
cfsetispeed(&termios, B115200);
cfsetospeed(&termios, B115200);
ret = tcsetattr(pty, TCSANOW, &termios);
if (ret) {
ERR("tcsetattr: %s\n",strerror(errno));
exit(-1);
}
fcntl(pty,F_SETFL,O_NONBLOCK);
pty_name = ptsname(pty);
t->modem = modem_create(&modem_test_driver,name);
if(!t->modem) {
return -1;
}
t->modem->name = name;
t->modem->pty = pty;
//t->modem->dev = dev;
t->modem->dev_name = name;
t->modem->pty_name = pty_name;
// datafile_load_info(basename(dev_name),&t->modem->dsp_info);
modem_update_termios(t->modem,&termios);
t->modem->dev_data = t;
DBG("created %s: %s\n",t->modem->name,t->modem->pty_name);
return 0;
}
static void modem_test_free(struct modem_test *t)
{
int pty = t->modem->pty;
modem_delete(t->modem);
close(pty);
}
int modem_test()
{
struct modem_test *ma, *mb;
struct modem_test modems[3] = {};
int pipe1[2], pipe2[2];
int ret = 0;
modem_debug_init("test");
memset(modems,0,sizeof(modems));
dp_dummy_init();
dp_sinus_init();
prop_dp_init();
modem_timer_init();
ma = &modems[0];
mb = &modems[1];
if(pipe(pipe1) < 0 || pipe(pipe2) < 0) {
ERR("pipe: %s\n",strerror(errno));
exit(-1);
}
modem_test_init(ma,"modemA",pipe1[0],pipe2[1]);
modem_test_init(mb,"modemB",pipe2[0],pipe1[1]);
ma->link = mb;
mb->link = ma;
signal(SIGINT, mark_termination);
signal(SIGTERM, mark_termination);
/* main loop here */
ret = modem_test_run(modems);
modem_test_free(ma);
modem_test_free(mb);
dp_dummy_exit();
dp_sinus_exit();
prop_dp_exit();
exit(ret);
return 0;
}
int main(int argc, char *argv[])
{
extern void modem_cmdline(int argc, char *argv[]);
modem_debug_level = 1;
modem_cmdline(argc,argv);
return modem_test();
}
+205
View File
@@ -0,0 +1,205 @@
/*
*
* Copyright (c) 2002, Smart Link Ltd.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* 3. Neither the name of the Smart Link Ltd. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/*
*
* modem_timer.c -- simple timer (will not in multithreaded env).
*
* Author: Sasha K (sashak@smlink.com)
*
*
*/
#include <unistd.h>
#include <signal.h>
#include <sys/time.h>
#include <limits.h>
#include <modem_timer.h>
#if 0
#include <stdio.h>
#define WARN(fmt...) fprintf(stderr, fmt);
#else
#define WARN(fmt...)
#endif
#define MAX_TIME LONG_MAX
static struct timeval tv_init;
static struct timer_list_struct {
struct timer *list;
unsigned long when;
struct sigaction old_act;
} timer_list;
unsigned long get_time()
{
struct timeval tv_now,tv;
gettimeofday(&tv_now,NULL);
timersub(&tv_now,&tv_init,&tv);
return tv.tv_sec*MODEM_HZ + tv.tv_usec/(1000000/MODEM_HZ);
}
static void set_timer(unsigned long when)
{
struct itimerval it;
long t;
t = (long)(when - get_time());
if( t <= 0) t = 1;
it.it_interval.tv_usec = 0;
it.it_interval.tv_sec = 0;
it.it_value.tv_usec = (t%MODEM_HZ)*(1000000/MODEM_HZ);
it.it_value.tv_sec = t/MODEM_HZ;
setitimer(ITIMER_REAL,&it,NULL);
}
static void timer_list_handler(int num)
{
unsigned long now;
struct timer *t,*next;
now = get_time();
t = timer_list.list;
timer_list.list = NULL;
while(t) {
next = t->next;
t->next = NULL;
if( (long)(t->expires - now) <= 0 ) {
t->added = 0;
if(t->func) {
t->func(t->data);
}
}
else {
t->next = timer_list.list;
timer_list.list = t;
}
t = next;
}
timer_list.when = now + MAX_TIME;
t = timer_list.list;
while(t) {
if((long)(timer_list.when - t->expires) > 0)
timer_list.when = t->expires;
t = t->next;
}
set_timer(timer_list.when);
}
void timer_init(struct timer *t)
{
t->next = 0;
t->added = 0;
t->expires = 0;
t->func = NULL;
t->data = NULL;
}
int timer_add(struct timer *t)
{
sigset_t set, old_set;
sigemptyset(&set);
sigaddset(&set,SIGALRM);
sigprocmask(SIG_BLOCK,&set,&old_set);
if(t->added) {
WARN("timer_add: already.\n");
}
else {
t->added = 1;
t->next = timer_list.list;
timer_list.list = t;
}
if((long)(timer_list.when - t->expires) > 0) {
timer_list.when = t->expires;
set_timer(timer_list.when);
}
sigprocmask(SIG_SETMASK,&old_set,NULL);
return 0;
}
int timer_del(struct timer *t)
{
sigset_t set, old_set;
struct timer *p, **prev;
sigemptyset(&set);
sigaddset(&set,SIGALRM);
sigprocmask(SIG_BLOCK,&set,&old_set);
if(t->added) {
p = timer_list.list;
prev = &timer_list.list;
while(p) {
if(p == t) {
*prev = t->next;
t->next = NULL;
t->added = 0;
break;
}
prev = &((*prev)->next);
p = p->next;
}
}
else {
WARN("timer_del: not added\n");
}
sigprocmask(SIG_SETMASK,&old_set,NULL);
return 0;
}
int modem_timer_init()
{
struct sigaction act;
gettimeofday(&tv_init,NULL);
timer_list.list = NULL;
timer_list.when = get_time() + MAX_TIME;
act.sa_handler = timer_list_handler;
sigemptyset(&act.sa_mask);
sigaddset(&act.sa_mask, SIGALRM);
act.sa_flags = SA_SIGINFO;
sigaction(SIGALRM,&act,&timer_list.old_act);
set_timer(timer_list.when);
return 0;
}
void modem_timer_exit()
{
sigaction(SIGALRM,&timer_list.old_act,NULL);
}
+70
View File
@@ -0,0 +1,70 @@
/*
*
* Copyright (c) 2002, Smart Link Ltd.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* 3. Neither the name of the Smart Link Ltd. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/*
*
* modem_timer.h -- definitions for simple timer.
*
* Author: Sasha K (sashak@smlink.com)
*
*
*/
#ifndef __MODEM_TIMER_H__
#define __MODEM_TIMER_H__
#define MODEM_HZ 100
struct timer {
struct timer *next;
unsigned added;
unsigned expires;
void (*func)(void *);
void *data;
};
#define time_before(t1,t2) ((long)((t2)-(t1)) > 0)
#define time_after(t1,t2) (!time_before(t1,t2))
unsigned long get_time(void);
extern void timer_init(struct timer *t);
extern int timer_add(struct timer *t);
extern int timer_del(struct timer *t);
extern int modem_timer_init(void);
#endif /* __MODEM_TIMER_H__ */
+112
View File
@@ -0,0 +1,112 @@
/*****************************************************************************/
/*
*
* Copyright (c) 2002, Smart Link Ltd.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* 3. Neither the name of the Smart Link Ltd. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/*
*
* sysdep_common.c -- sysdep API.
*
* Author: Sasha K (sashak@smlink.com)
*
*
*/
/*****************************************************************************/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
/* memory allocations */
void *sysdep_malloc (unsigned int size)
{
return malloc(size);
}
void sysdep_free (void *mem)
{
free(mem);
}
/* strings */
size_t sysdep_strlen(const char *s)
{
return strlen(s);
}
char *sysdep_strcpy(char *d,const char *s)
{
return strcpy(d,s);
}
char *sysdep_strcat(char *d, const char *s)
{
return strcat(d,s);
}
int sysdep_strcmp(const char *s1,const char *s2)
{
return strcmp(s1, s2);
}
char *sysdep_strstr(const char *s1,const char *s2)
{
return strstr(s1,s2);
}
void *sysdep_memset(void *d,int c,size_t l)
{
return memset(d,c,l);
}
void *sysdep_memcpy(void *d,const void *s,size_t l)
{
return memcpy(d,s,l);
}
void *sysdep_memchr(const void *s,int c,size_t l)
{
return memchr (s,c,l);
}
int sysdep_vsnprintf(char *str, unsigned size, const char *format, va_list ap)
{
return vsnprintf(str, size, format, ap);
}
int sysdep_sprintf(char *buf, const char *fmt, ...)
{
va_list args;
int i;
va_start(args, fmt);
i=vsprintf(buf,fmt,args);
va_end(args);
return i;
}