Simple Remote-CAPI-Server implementation

You also need the CAPI-Library by AVM

Special thanks to Thomas Pfeiffer <pfeiffer@pds.de> for his kind support.
This commit is contained in:
cal 1998-05-19 18:10:11 +00:00
parent 0e05b7663d
commit 4b8c82528d
13 changed files with 2386 additions and 2 deletions

View File

@ -1,4 +1,4 @@
# $Id: Makefile,v 1.20 1998/03/31 20:11:33 keil Exp $
# $Id: Makefile,v 1.21 1998/05/19 18:10:11 cal Exp $
#
# Toplevel Makefile for isdn4k-utils
#
@ -87,6 +87,9 @@ endif
ifeq ($(CONFIG_VBOX),y)
SUBDIRS := $(SUBDIRS) vbox
endif
ifeq ($(CONFIG_RCAPID),y)
SUBDIRS := $(SUBDIRS) rcapid
endif
ifeq ($(CONFIG_GENMAN),y)
SUBDIRS := $(SUBDIRS) doc
endif

4
rcapid/.Config.in Normal file
View File

@ -0,0 +1,4 @@
mainmenu_option next_comment
comment 'Options for rcapid package'
string 'CAPI-ADK directory' CONFIG_C20LIBDIR
endmenu

53
rcapid/Makefile.in Normal file
View File

@ -0,0 +1,53 @@
#
# Makefile for rcapid
# (C) 1998 Christian A. Lademann (cal@zls.de)
#
#
SHELL = /bin/sh
CFLAGS = -O2
INCLUDES = -I. -I@CONFIG_C20LIBDIR@/source -I@CONFIG_KERNELDIR@/driver/isdn/avmb1
DEFS = -DTARGET_32BIT
LDFLAGS = -L@CONFIG_C20LIBDIR@/linux -lc20 @LIBS@
PROGRAM = rcapid
MODULES = rcapid.o
MANPAGE =
INSTALL = @INSTALL@
SBINDIR = @CONFIG_SBINDIR@
INSTALL_PROGRAM = $(INSTALL) -o 0 -g 0 -m 0750
CC = @CC@
COPTS =
.SUFFIXES:
.SUFFIXES: .c .o
%.o: %.c Makefile
$(CC) $(CFLAGS) $(INCLUDES) $(DEFS) $(COPTS) -c -o $@ $<
all: $(PROGRAM)
config:
@./configure
Makefile: Makefile.in config.status
./config.status
config.status: configure
./config.status --recheck
$(PROGRAM): $(MODULES)
$(CC) $(CFLAGS) $(INCLUDES) $(DEFS) $? $(LDFLAGS) -o $@
install: $(PROGRAM)
$(INSTALL_PROGRAM) $(PROGRAM) $(SBINDIR)/$(PROGRAM)
install-strip: $(PROGRAM)
$(INSTALL_PROGRAM) -s $(PROGRAM) $(SBINDIR)/$(PROGRAM)
uninstall:
rm -f $(SBINDIR)/$(PROGRAM)
clean:
rm -f *.o *~ $(PROGRAM)
distclean: clean
rm -f config.status config.cache config.log Makefile

16
rcapid/README Normal file
View File

@ -0,0 +1,16 @@
First implementation of a simple Remote-CAPI server. It works with
the CAPI-2.0 interface offered by the AVM-B1-card.
Installation:
- add the following line to /etc/services:
capi 6000/tcp
- add the following line to /etc/inetd.conf:
capi stream tcp nowait.9999 /sbin/rcapid rcapid
- restart inetd

41
rcapid/aclocal.m4 vendored Normal file
View File

@ -0,0 +1,41 @@
dnl
dnl Try finding linux sourcetree
dnl
AC_DEFUN(AC_FIND_KERNEL, [
OLD_CPPFLAGS="$CPPFLAGS"
lxdir="no"
eval tst_kerneldir=$CONFIG_KERNELDIR
AC_ARG_WITH(kernel,
[ --with-kernel=DIR Set kernel source directory [/usr/src/linux]],
DOTEST="y"; tst_kerneldir="${withval}")
if test "$DOTEST" = "y" || test $CONFIG_KERNELDIR != "" ; then
AC_MSG_CHECKING([for linux kernel source in ${tst_kerneldir}])
CPPFLAGS="-nostdinc -I${tst_kerneldir}/drivers/isdn"
AC_TRY_CPP([#include <isdn_common.h>], lxdir=${tst_kerneldir},
AC_MSG_RESULT("no"))
fi
if test "$lxdir" = "no" ; then
AC_MSG_CHECKING([for linux kernel source in /usr/src/linux])
CPPFLAGS="-nostdinc -I/usr/src/linux/drivers/isdn"
AC_TRY_CPP([#include <isdn_common.h>], lxdir=/usr/src/linux)
fi
if test "$lxdir" = "no" ; then
AC_MSG_RESULT("$lxdir")
AC_MSG_CHECKING([for linux kernel source in /usr/local/src/linux])
CPPFLAGS="-nostdinc -I/usr/local/src/linux/drivers/isdn"
AC_TRY_CPP([#include <isdn_common.h>], lxdir=/usr/local/src/linux)
fi
if test "$lxdir" != "no" ; then
AC_MSG_RESULT("yes")
else
lxdir=""
AC_MSG_ERROR("Kernel source not found. You MUST specify a correct path to the linux source in the configuration.")
fi
CONFIG_KERNELDIR="$lxdir"
CPPFLAGS="$OLD_CPPFLAGS"
AC_DEFINE_UNQUOTED(CONFIG_KERNELDIR,"$lxdir")
AC_SUBST(CONFIG_KERNELDIR)
])

126
rcapid/capicmd.h Normal file
View File

@ -0,0 +1,126 @@
/*
* $Id: capicmd.h,v 1.1 1998/05/19 18:10:18 cal Exp $
*
* CAPI 2.0 Interface for Linux
*
* Copyright 1997 by Carsten Paeth (calle@calle.in-berlin.de)
*
* $Log: capicmd.h,v $
* Revision 1.1 1998/05/19 18:10:18 cal
* Simple Remote-CAPI-Server implementation
*
* You also need the CAPI-Library by AVM
*
* Special thanks to Thomas Pfeiffer <pfeiffer@pds.de> for his kind support.
*
* Revision 1.1 1997/03/04 21:50:30 calle
* Frirst version in isdn4linux
*
* Revision 2.2 1997/02/12 09:31:39 calle
* new version
*
* Revision 1.1 1997/01/31 10:32:20 calle
* Initial revision
*
*
*/
#ifndef __CAPICMD_H__
#define __CAPICMD_H__
/*----- CAPI commands -----*/
#define CAPI_ALERT 0x01
#define CAPI_CONNECT 0x02
#define CAPI_CONNECT_ACTIVE 0x03
#define CAPI_CONNECT_B3_ACTIVE 0x83
#define CAPI_CONNECT_B3 0x82
#define CAPI_CONNECT_B3_T90_ACTIVE 0x88
#define CAPI_DATA_B3 0x86
#define CAPI_DISCONNECT_B3 0x84
#define CAPI_DISCONNECT 0x04
#define CAPI_FACILITY 0x80
#define CAPI_INFO 0x08
#define CAPI_LISTEN 0x05
#define CAPI_MANUFACTURER 0xff
#define CAPI_RESET_B3 0x87
#define CAPI_SELECT_B_PROTOCOL 0x41
/*----- CAPI subcommands -----*/
#define CAPI_REQ 0x80
#define CAPI_CONF 0x81
#define CAPI_IND 0x82
#define CAPI_RESP 0x83
/*----- CAPI combined commands -----*/
#define CAPICMD(cmd,subcmd) (((cmd)<<8)|(subcmd))
#define CAPI_DISCONNECT_REQ CAPICMD(CAPI_DISCONNECT,CAPI_REQ)
#define CAPI_DISCONNECT_CONF CAPICMD(CAPI_DISCONNECT,CAPI_CONF)
#define CAPI_DISCONNECT_IND CAPICMD(CAPI_DISCONNECT,CAPI_IND)
#define CAPI_DISCONNECT_RESP CAPICMD(CAPI_DISCONNECT,CAPI_RESP)
#define CAPI_ALERT_REQ CAPICMD(CAPI_ALERT,CAPI_REQ)
#define CAPI_ALERT_CONF CAPICMD(CAPI_ALERT,CAPI_CONF)
#define CAPI_CONNECT_REQ CAPICMD(CAPI_CONNECT,CAPI_REQ)
#define CAPI_CONNECT_CONF CAPICMD(CAPI_CONNECT,CAPI_CONF)
#define CAPI_CONNECT_IND CAPICMD(CAPI_CONNECT,CAPI_IND)
#define CAPI_CONNECT_RESP CAPICMD(CAPI_CONNECT,CAPI_RESP)
#define CAPI_CONNECT_ACTIVE_REQ CAPICMD(CAPI_CONNECT_ACTIVE,CAPI_REQ)
#define CAPI_CONNECT_ACTIVE_CONF CAPICMD(CAPI_CONNECT_ACTIVE,CAPI_CONF)
#define CAPI_CONNECT_ACTIVE_IND CAPICMD(CAPI_CONNECT_ACTIVE,CAPI_IND)
#define CAPI_CONNECT_ACTIVE_RESP CAPICMD(CAPI_CONNECT_ACTIVE,CAPI_RESP)
#define CAPI_SELECT_B_PROTOCOL_REQ CAPICMD(CAPI_SELECT_B_PROTOCOL,CAPI_REQ)
#define CAPI_SELECT_B_PROTOCOL_CONF CAPICMD(CAPI_SELECT_B_PROTOCOL,CAPI_CONF)
#define CAPI_CONNECT_B3_ACTIVE_REQ CAPICMD(CAPI_CONNECT_B3_ACTIVE,CAPI_REQ)
#define CAPI_CONNECT_B3_ACTIVE_CONF CAPICMD(CAPI_CONNECT_B3_ACTIVE,CAPI_CONF)
#define CAPI_CONNECT_B3_ACTIVE_IND CAPICMD(CAPI_CONNECT_B3_ACTIVE,CAPI_IND)
#define CAPI_CONNECT_B3_ACTIVE_RESP CAPICMD(CAPI_CONNECT_B3_ACTIVE,CAPI_RESP)
#define CAPI_CONNECT_B3_REQ CAPICMD(CAPI_CONNECT_B3,CAPI_REQ)
#define CAPI_CONNECT_B3_CONF CAPICMD(CAPI_CONNECT_B3,CAPI_CONF)
#define CAPI_CONNECT_B3_IND CAPICMD(CAPI_CONNECT_B3,CAPI_IND)
#define CAPI_CONNECT_B3_RESP CAPICMD(CAPI_CONNECT_B3,CAPI_RESP)
#define CAPI_CONNECT_B3_T90_ACTIVE_IND CAPICMD(CAPI_CONNECT_B3_T90_ACTIVE,CAPI_IND)
#define CAPI_CONNECT_B3_T90_ACTIVE_RESP CAPICMD(CAPI_CONNECT_B3_T90_ACTIVE,CAPI_RESP)
#define CAPI_DATA_B3_REQ CAPICMD(CAPI_DATA_B3,CAPI_REQ)
#define CAPI_DATA_B3_CONF CAPICMD(CAPI_DATA_B3,CAPI_CONF)
#define CAPI_DATA_B3_IND CAPICMD(CAPI_DATA_B3,CAPI_IND)
#define CAPI_DATA_B3_RESP CAPICMD(CAPI_DATA_B3,CAPI_RESP)
#define CAPI_DISCONNECT_B3_REQ CAPICMD(CAPI_DISCONNECT_B3,CAPI_REQ)
#define CAPI_DISCONNECT_B3_CONF CAPICMD(CAPI_DISCONNECT_B3,CAPI_CONF)
#define CAPI_DISCONNECT_B3_IND CAPICMD(CAPI_DISCONNECT_B3,CAPI_IND)
#define CAPI_DISCONNECT_B3_RESP CAPICMD(CAPI_DISCONNECT_B3,CAPI_RESP)
#define CAPI_RESET_B3_REQ CAPICMD(CAPI_RESET_B3,CAPI_REQ)
#define CAPI_RESET_B3_CONF CAPICMD(CAPI_RESET_B3,CAPI_CONF)
#define CAPI_RESET_B3_IND CAPICMD(CAPI_RESET_B3,CAPI_IND)
#define CAPI_RESET_B3_RESP CAPICMD(CAPI_RESET_B3,CAPI_RESP)
#define CAPI_LISTEN_REQ CAPICMD(CAPI_LISTEN,CAPI_REQ)
#define CAPI_LISTEN_CONF CAPICMD(CAPI_LISTEN,CAPI_CONF)
#define CAPI_MANUFACTURER_REQ CAPICMD(CAPI_MANUFACTURER,CAPI_REQ)
#define CAPI_MANUFACTURER_CONF CAPICMD(CAPI_MANUFACTURER,CAPI_CONF)
#define CAPI_MANUFACTURER_IND CAPICMD(CAPI_MANUFACTURER,CAPI_IND)
#define CAPI_MANUFACTURER_RESP CAPICMD(CAPI_MANUFACTURER,CAPI_RESP)
#define CAPI_FACILITY_REQ CAPICMD(CAPI_FACILITY,CAPI_REQ)
#define CAPI_FACILITY_CONF CAPICMD(CAPI_FACILITY,CAPI_CONF)
#define CAPI_FACILITY_IND CAPICMD(CAPI_FACILITY,CAPI_IND)
#define CAPI_FACILITY_RESP CAPICMD(CAPI_FACILITY,CAPI_RESP)
#define CAPI_INFO_REQ CAPICMD(CAPI_INFO,CAPI_REQ)
#define CAPI_INFO_CONF CAPICMD(CAPI_INFO,CAPI_CONF)
#define CAPI_INFO_IND CAPICMD(CAPI_INFO,CAPI_IND)
#define CAPI_INFO_RESP CAPICMD(CAPI_INFO,CAPI_RESP)
#endif /* __CAPICMD_H__ */

1364
rcapid/configure vendored Executable file

File diff suppressed because it is too large Load Diff

59
rcapid/configure.in Normal file
View File

@ -0,0 +1,59 @@
dnl Process this file with autoconf to produce a configure script.
AC_INIT(rcapid.c)
AC_PREFIX_DEFAULT(/usr)
I4LVERSION=${I4LVERSION:-"?.?"}
CONFIG_SBINDIR=${CONFIG_SBINDIR:-"/sbin"}
CONFIG_MANDIR=${CONFIG_MANDIR:-"/usr/man"}
CONFIG_KERNELDIR=`eval echo ${CONFIG_KERNELDIR:-"/usr/src/linux"}`
CONFIG_C20LIBDIR=`eval echo ${CONFIG_C20LIBDIR:-"/usr/src/capi-adk/c20lib"}`
dnl Checks for programs.
AC_PROG_CC
AC_PROG_CPP
AC_PROG_INSTALL
dnl Checks for libraries.
dnl Checks for header files.
AC_CHECK_HEADERS(fcntl.h sys/ioctl.h)
AC_FIND_KERNEL
dnl Checks for typedefs, structures, and compiler characteristics.
dnl Checks for library functions.
AC_PROG_GCC_TRADITIONAL
AC_HEADER_STDC
AC_TYPE_SIGNAL
AC_CHECK_FUNCS(socket)
dnl Optional sbin directory
AC_ARG_WITH(sbin,
[ --with-sbin=DIR Set dir where binary is installed. [/sbin]],
CONFIG_SBINDIR="${withval}"
AC_DEFINE(CONFIG_SBINDIR,"${withval}"),
)
dnl Optional man directory
AC_ARG_WITH(man,
[ --with-man=DIR Set manpage dir. [/usr/man]],
CONFIG_MANDIR="${withval}"
AC_DEFINE(CONFIG_MANDIR,"${withval}"),
)
dnl Optional c20lib directory
AC_ARG_WITH(c20lib,
[ --with-c20lib=DIR Set c20lib dir. [/usr/src/capi-adk/c20lib]],
CONFIG_C20LIBDIR="${withval}"
AC_DEFINE(CONFIG_C20LIBDIR,"${withval}"),
)
AC_SUBST(I4lVERSION)
AC_SUBST(MANDATE)
AC_SUBST(CONFIG_SBINDIR)
AC_SUBST(CONFIG_MANDIR)
AC_SUBST(CONFIG_KERNELDIR)
AC_SUBST(CONFIG_C20LIBDIR)
AC_SUBST(INSTALL)
AC_OUTPUT(Makefile)

2
rcapid/install-sh Executable file
View File

@ -0,0 +1,2 @@
#!/bin/sh
exit 0

38
rcapid/rcapicmd.h Normal file
View File

@ -0,0 +1,38 @@
/*
* ISDN4Linux Remote-CAPI Server
*
* Copyright 1998 by Christian A. Lademann (cal@zls.de)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#ifndef __RCAPICMD_H__
#define __RCAPICMD_H__
/* REMOTE-CAPI commands */
#define RCAPI_REGISTER_REQ CAPICMD(0xf2, 0xff)
#define RCAPI_REGISTER_CONF CAPICMD(0xf3, 0xff)
#define RCAPI_GET_MANUFACTURER_REQ CAPICMD(0xfa, 0xff)
#define RCAPI_GET_MANUFACTURER_CONF CAPICMD(0xfb, 0xff)
#define RCAPI_GET_SERIAL_NUMBER_REQ CAPICMD(0xfe, 0xff)
#define RCAPI_GET_SERIAL_NUMBER_CONF CAPICMD(0xff, 0xff)
#define RCAPI_GET_VERSION_REQ CAPICMD(0xfc, 0xff)
#define RCAPI_GET_VERSION_CONF CAPICMD(0xfd, 0xff)
#define RCAPI_GET_PROFILE_REQ CAPICMD(0xe0, 0xff)
#define RCAPI_GET_PROFILE_CONF CAPICMD(0xe1, 0xff)
#endif /* __RCAPICMD_H__ */

669
rcapid/rcapid.c Normal file
View File

@ -0,0 +1,669 @@
/*
* ISDN4Linux Remote-CAPI Server
*
* Copyright 1998 by Christian A. Lademann (cal@zls.de)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include <linux/capi.h>
#include <capicmd.h>
#include "rcapicmd.h"
#include "capi20.h"
#define RCAPID_MANUFACTURER "ISDN4Linux, Christian A. Lademann <cal@zls.de>"
#define RCAPID_SERIAL_NUMBER "0000 (we don't need that ;-)"
#define RCAPID_VERSION_INFO "CAPI 2.0"
#define MAX_CAPIMSGLEN 64 * 1024
#define LOGFILE_PATH_TEMPL "/tmp/rcapid.log"
char logfile_path [64];
FILE *logfile = NULL;
int loglevel = 0;
#define log(level,args...) (void)(((level) <= loglevel) && \
((logfile || (logfile = fopen(logfile_path, "a+"))) && \
fprintf(logfile, "%d: ", getpid()) && \
fprintf(logfile, ## args) && \
fflush(logfile)))
char logbuf [10240], *lptr;
typedef unsigned char byte;
typedef unsigned short word;
typedef unsigned int dword;
typedef struct {
int len;
char *data;
} structure;
struct capi_message {
structure raw;
word TotalLength,
ApplID;
byte Command,
Subcommand;
word MessageNumber;
structure Parameters;
};
word remote_ApplID, local_ApplID;
int capi_fd = -1;
#define SIZE_TABMNR2DHDL 16
struct {
int used;
word MessageNumber;
word DataHandle;
} tabMnr2Dhdl [SIZE_TABMNR2DHDL];
int tabMnr2Dhdl_initd = 0;
int
setDataHandle(word mnr, word dhdl) {
int i;
if(! tabMnr2Dhdl_initd) {
for(i = 0; i < SIZE_TABMNR2DHDL; i++)
tabMnr2Dhdl [i] .used = 0;
tabMnr2Dhdl_initd = 1;
}
for(i = 0; i < SIZE_TABMNR2DHDL; i++)
if(! tabMnr2Dhdl [i] .used) {
tabMnr2Dhdl [i] .used = 1;
tabMnr2Dhdl [i] .MessageNumber = mnr;
tabMnr2Dhdl [i] .DataHandle = dhdl;
log(9, "set mnr/dhdl (0x%04x, 0x%04x)\n", mnr, dhdl);
return(0);
}
return(-1);
}
int
getDataHandle(word mnr, word *dhdl) {
int i;
if(! tabMnr2Dhdl_initd)
return(-1);
for(i = 0; i < SIZE_TABMNR2DHDL; i++)
if(tabMnr2Dhdl [i] .used && tabMnr2Dhdl [i] .MessageNumber == mnr) {
*dhdl = tabMnr2Dhdl [i] .DataHandle;
tabMnr2Dhdl [i] .used = 0;
log(9, "get mnr/dhdl (0x%04x, 0x%04x)\n", mnr, *dhdl);
return(0);
}
return(1);
}
void
log_hd(int level, char *buf, int len) {
char hline [50], aline [17], *p, *q;
unsigned char c;
int i;
if(level > loglevel)
return;
memset(hline, 0, sizeof(hline));
memset(aline, 0, sizeof(aline));
p = hline;
q = aline;
for(i = 0; i < len; i++) {
c = (unsigned char)buf [i];
p += sprintf(p, "%02x ", c);
if(i % 8 == 0)
p += sprintf(p, " ");
q += sprintf(q, "%c", (isprint(c) ? c : '.'));
if(i == len - 1 || (i + 1) % 16 == 0) {
log(level, " %-50.50s%s\n", hline, aline);
p = hline;
q = aline;
}
}
}
byte
get_byte(char **p) {
*p += 1;
return((unsigned char)*(*p - 1));
}
word
get_word(char **p) {
return(get_byte(p) | (get_byte(p) << 8));
}
word
get_netword(char **p) {
return((get_byte(p) << 8) | get_byte(p));
}
dword
get_dword(char **p) {
return(get_word(p) | (get_word(p) << 16));
}
char *
put_byte(char **p, byte val) {
**p = val;
*p += 1;
return(*p);
}
char *
put_word(char **p, word val) {
put_byte(p, val & 0xff);
put_byte(p, (val & 0xff00) >> 8);
return(*p);
}
char *
put_netword(char **p, word val) {
put_byte(p, (val & 0xff00) >> 8);
put_byte(p, val & 0xff);
return(*p);
}
char *
put_dword(char **p, dword val) {
put_word(p, val & 0xffff);
put_word(p, (val & 0xffff0000) >> 16);
return(*p);
}
char *
put_struct(char **p, int len, char *val) {
if(len < 255)
put_byte(p, len);
else {
put_byte(p, 0xff);
put_word(p, len);
}
if(len) {
memcpy(*p, val, len);
*p += len;
}
return(*p);
}
int
getMessageFromBuffer(struct capi_message *msg, char *buf, int len) {
char *p = buf;
msg->raw.len = len;
msg->raw.data = buf;
msg->TotalLength = get_word(&p);
msg->ApplID = get_word(&p);
msg->Command = get_byte(&p);
msg->Subcommand = get_byte(&p);
msg->MessageNumber = get_word(&p);
if(p - buf < len) {
msg->Parameters.len = p - buf + 1;
msg->Parameters.data = p;
} else {
msg->Parameters.len = 0;
msg->Parameters.data = NULL;
}
log(9, "gotMessageFromBuffer: cmd=(%02x/%02x)\n", msg->Command, msg->Subcommand);
return(0);
}
int
rcv_message(struct capi_message *msg) {
static char buf [MAX_CAPIMSGLEN],
*p;
int len, rlen, i;
if(read(0, buf, 2) == 2) {
p = buf;
len = (int)get_netword(&p);
log(5, "rcapi-message: len=%d (%02.2x%02.2x)\n", len, buf [0], buf [1]);
len -= 2;
if((rlen = read(0, buf, len)) != len) {
log(5, "short message received! (received=%d, expected=%d)\n", rlen, len);
/* exit(1); */
return(-1);
}
log_hd(6, buf, len);
getMessageFromBuffer(msg, buf, rlen);
return(0);
}
return(-1);
}
int
snd_message(struct capi_message *orig, int cmd, structure *params, structure *data) {
static char buf [MAX_CAPIMSGLEN],
*p;
int len, rlen, slen, i;
len = 8;
if(params)
len += params->len;
rlen = len + 2;
if(data)
rlen += data->len;
p = buf;
put_netword(&p, rlen);
put_word(&p, len);
put_word(&p, orig->ApplID);
put_byte(&p, (cmd >> 8) & 0xff);
put_byte(&p, cmd & 0xff);
put_word(&p, orig->MessageNumber);
if(params) {
memcpy(p, params->data, params->len);
p += params->len;
}
if(data) {
memcpy(p, data->data, data->len);
p += data->len;
}
log(5, "send rcapi-message: %d bytes\n", rlen);
log_hd(6, buf, rlen);
if((slen = write(1, buf, rlen)) < rlen) {
log(5, "sending interrupted (%d of %d bytes).\n", slen, rlen);
return(-1);
}
return(0);
}
int
hdl_RCAPI_REGISTER_REQ(struct capi_message *msg) {
CAPI_REGISTER_ERROR err;
char *p;
dword Buffer;
word messageBufferSize,
maxLogicalConnections,
maxBDataBlocks,
maxBDataLen;
byte capiVersion;
int capierr = 0;
structure retstruct;
char retstr [8];
if(! (p = msg->Parameters.data)) {
log(5, "RCAPI_REGISTER_REQ: parameters missing.\n");
return(-1);
}
Buffer = get_dword(&p);
messageBufferSize = get_word(&p);
maxLogicalConnections = get_word(&p);
maxBDataBlocks = get_word(&p);
maxBDataLen = get_word(&p);
capiVersion = get_byte(&p);
log(5, "RCAPI_REGISTER_REQ\n");
log(5, "\tBuffer: 0x%x\n", Buffer);
log(5, "\tmessageBufferSize: %d\n", messageBufferSize);
log(5, "\tmaxLogicalConnections: %d\n", maxLogicalConnections);
log(5, "\tmaxBDataBlocks: %d\n", maxBDataBlocks);
log(5, "\tmaxBDataLen: %d\n", maxBDataLen);
log(5, "\tcapiVersion: %d\n", capiVersion);
p = retstr;
if(capiVersion == 2) {
if((capi_fd = CAPI20_REGISTER(maxLogicalConnections, maxBDataBlocks, maxBDataLen, &err)) < 0)
capierr = err;
else {
local_ApplID = capi_fd;
log(5, "registration successful: appl_id = %d\n", capi_fd);
capi_fd = applid2fd(capi_fd);
log(5, " capi_fd = %d\n", capi_fd);
}
} else
capierr = 0x0003;
put_word(&p, capierr);
retstruct.len = sizeof(word);
retstruct.data = retstr;
return(snd_message(msg, RCAPI_REGISTER_CONF, &retstruct, NULL));
}
int
hdl_RCAPI_GET_SERIAL_NUMBER_REQ(struct capi_message *msg) {
char *p;
structure retstruct;
char retval [80];
char serial_number [64], sn [16];
log(5, "RCAPI_GET_SERIAL_NUMBER_REQ\n");
memset(serial_number, 0, sizeof(serial_number));
sprintf(serial_number, "%s\0", RCAPID_SERIAL_NUMBER);
memset(serial_number + strlen(serial_number), 0, sizeof(serial_number) - strlen(serial_number));
p = retval;
put_struct(&p, /* strlen(serial_number) + 1 */ 64, serial_number);
retstruct.len = p - retval;
retstruct.data = (char *)&retval;
return(snd_message(msg, RCAPI_GET_SERIAL_NUMBER_CONF, &retstruct, NULL));
}
int
hdl_RCAPI_GET_MANUFACTURER_REQ(struct capi_message *msg) {
char *p;
structure retstruct;
char retval [80];
char manufacturer [64];
log(5, "RCAPI_GET_MANUFACTURER_REQ\n");
memset(manufacturer, 0, sizeof(manufacturer));
sprintf(manufacturer, "%s\0", RCAPID_MANUFACTURER);
memset(manufacturer + strlen(manufacturer), 0, sizeof(manufacturer)) + strlen(manufacturer);
p = retval;
put_struct(&p, /* strlen(manufacturer) + 1 */ 64, manufacturer);
retstruct.len = p - retval;
retstruct.data = (char *)&retval;
return(snd_message(msg, RCAPI_GET_MANUFACTURER_CONF, &retstruct, NULL));
}
int
hdl_RCAPI_GET_VERSION_REQ(struct capi_message *msg) {
char *p;
structure retstruct;
char retval [80];
char info [64];
log(5, "RCAPI_GET_VERSION_REQ\n");
memset(info, 0, sizeof(info));
sprintf(info, "%s\0", RCAPID_VERSION_INFO);
memset(info + strlen(info), 0, sizeof(info) - strlen(info));
p = retval;
put_word(&p, /* 2 */ 0x64);
put_word(&p, /* 1 */ 0);
put_struct(&p, /* strlen(info) + 1 */ 64, info);
retstruct.len = p - retval;
retstruct.data = (char *)&retval;
return(snd_message(msg, RCAPI_GET_VERSION_CONF, &retstruct, NULL));
}
int
hdl_RCAPI_GET_PROFILE_REQ(struct capi_message *msg) {
word CtrlNr;
char *p;
int i;
structure retstruct;
char retval [80];
log(5, "RCAPI_GET_PROFILE_REQ\n");
if(! (p = msg->Parameters.data)) {
log(5, "RCAPI_GET_PROFILE_REG: parameters missing.\n");
return(-1);
}
CtrlNr = get_dword(&p);
log(5, "\tCtrlNr: %d\n", CtrlNr);
p = retval;
put_word(&p, 0); /* Info */
put_word(&p, 1); /* CtrlNr */
put_word(&p, 2); /* nChannel */
put_dword(&p, 1); /* options */
put_dword(&p, 31); /* b1protocols */
put_dword(&p, 51); /* b2protocols */
put_dword(&p, 19); /* b3protocols */
for(i = 0; i < 11; i++)
put_dword(&p, 0);
retstruct.len = p - retval;
retstruct.data = (char *)&retval;
return(snd_message(msg, RCAPI_GET_PROFILE_CONF, &retstruct, NULL));
}
int
hdl_raw(struct capi_message *msg) {
char *p;
word dhdl;
if(capi_fd < 0)
return(-1);
p = msg->raw.data + 2;
put_word(&p, local_ApplID);
switch(CAPICMD(msg->Command, msg->Subcommand)) {
case CAPI_DATA_B3_RESP:
if(getDataHandle(msg->MessageNumber, &dhdl) == 0) {
p = msg->raw.data + 12;
put_word(&p, dhdl);
}
}
log(5, "forward raw message: %d bytes, capi_fd = %d\n", msg->raw.len, capi_fd);
log_hd(6, msg->raw.data, msg->raw.len);
write(capi_fd, msg->raw.data, msg->raw.len);
return(0);
}
int
hdl_message(struct capi_message *msg) {
log(5, "message: Tl=%d, AI=%x, C=%x, Sc=%x, Mn=%d\n",
msg->TotalLength,
msg->ApplID,
msg->Command,
msg->Subcommand,
msg->MessageNumber);
remote_ApplID = msg->ApplID;
switch(CAPICMD(msg->Command, msg->Subcommand)) {
case RCAPI_REGISTER_REQ:
return(hdl_RCAPI_REGISTER_REQ(msg));
break;
case RCAPI_GET_SERIAL_NUMBER_REQ:
return(hdl_RCAPI_GET_SERIAL_NUMBER_REQ(msg));
break;
case RCAPI_GET_MANUFACTURER_REQ:
return(hdl_RCAPI_GET_MANUFACTURER_REQ(msg));
break;
case RCAPI_GET_VERSION_REQ:
return(hdl_RCAPI_GET_VERSION_REQ(msg));
break;
case RCAPI_GET_PROFILE_REQ:
return(hdl_RCAPI_GET_PROFILE_REQ(msg));
break;
default:
msg->ApplID = local_ApplID;
return(hdl_raw(msg));
break;
}
}
main(int argc, char *argv []) {
struct capi_message msg;
extern int optind;
extern char *optarg;
char c;
int i;
loglevel = 0;
while((c = getopt(argc, argv, "l:")) != EOF)
switch(c) {
case 'l': loglevel = atoi(optarg); break;
}
sprintf(logfile_path, "/tmp/rcapid.log");
log(5, "rcapid started (PID=%d)\n", getpid());
while(! feof(stdin)) {
fd_set ifd, ofd, efd;
int max_fd, s;
FD_ZERO(&ifd);
FD_ZERO(&efd);
FD_SET(0, &ifd);
FD_SET(0, &efd);
max_fd = 1;
if(capi_fd >= 0) {
FD_SET(capi_fd, &ifd);
max_fd = capi_fd + 1;
}
s = select(max_fd, &ifd, NULL, &efd, NULL);
if(s <= 0) {
log(5, "exit: %s, %d\n", __FILE__, __LINE__);
exit(1);
}
if(FD_ISSET(0, &ifd)) {
if(rcv_message(&msg) == 0)
hdl_message(&msg);
else
exit(1);
}
if(capi_fd >= 0 && FD_ISSET(capi_fd, &ifd)) {
char buf [MAX_CAPIMSGLEN], *p;
int len, i;
struct capi_message msg;
word dhdl;
if((len = read(capi_fd, buf + 2, sizeof(buf) - 2)) <= 0)
continue;
p = buf;
len += 2;
put_netword(&p, len);
p = buf + 4;
put_word(&p, remote_ApplID);
log(5, "forward raw answer: %d bytes\n", len);
log_hd(6, buf, len);
i = write(1, buf, len);
log(5, "written %d bytes\n", i);
getMessageFromBuffer(&msg, buf + 2, len - 2);
switch(CAPICMD(msg.Command, msg.Subcommand)) {
case CAPI_DATA_B3_IND:
p = msg.raw.data + 18;
dhdl = get_word(&p);
setDataHandle(msg.MessageNumber, dhdl);
break;
}
}
if(FD_ISSET(0, &efd)) {
log(5, "exit: %s, %d\n", __FILE__, __LINE__);
exit(0);
}
}
}

View File

@ -1,5 +1,5 @@
#
# $Id: config.in,v 1.22 1998/03/07 18:26:06 cal Exp $
# $Id: config.in,v 1.23 1998/05/19 18:10:28 cal Exp $
#
# The whole configuration stuff is borrowed from the kernel
# configuration.
@ -108,6 +108,12 @@ bool 'ipppd' CONFIG_IPPPD
if [ "$CONFIG_IPPPD" = "y" ]; then
source ipppd/.Config.in
fi
if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
bool 'rcapid' CONFIG_RCAPID
if [ "$CONFIG_RCAPID" = "y" ]; then
source rcapid/.Config.in
fi
fi
endmenu
mainmenu_option nextcomment
comment 'Documentation'

View File

@ -106,6 +106,9 @@ CONFIG_IPPPD=y
#
CONFIG_IPPD_MSCHAP=y
CONFIG_RCAPID=n
# CONFIG_C20LIBDIR='/usr/src/capi-adk/c20lib'
#
# Documentation
#