Experimental crypto feature: Support for libvootp

This commit is contained in:
Andreas Eversberg 2012-12-23 06:45:43 +01:00
parent cdee00aedd
commit e233557e40
23 changed files with 319 additions and 20 deletions

View File

@ -132,6 +132,18 @@ SIP_LIB += $(SOFIA_LIBS)
endif
VOOTP_LIB =
if ENABLE_VOOTP
VOOTP_INCLUDE = -DWITH_VOOTP $(VOOTP_CFLAGS)
VOOTP_SOURCE =
VOOTP_LIB += $(VOOTP_LIBS)
endif
bin_PROGRAMS = lcradmin gentones genwave
sbin_PROGRAMS = lcr genrc genextension
@ -166,17 +178,17 @@ uninstall-hook:
cd '$(DESTDIR)$(astmoddir)' && rm -f chan_lcr.so
endif
AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include $(MISDN_INCLUDE) $(GSM_INCLUDE) $(SS5_INCLUDE) $(SIP_INCLUDE) -Wall $(INSTALLATION_DEFINES)
AM_CPPFLAGS = $(all_includes) $(MISDN_INCLUDE) $(GSM_INCLUDE) $(SS5_INCLUDE) $(SIP_INCLUDE) $(VOOTP_INCLUDE) -Wall $(INSTALLATION_DEFINES)
lcr_SOURCES = \
main.c select.c trace.c options.c tones.c alawulaw.c cause.c interface.c message.c callerid.c socket_server.c \
port.cpp vbox.cpp remote.cpp \
$(MISDN_SOURCE) $(GSM_SOURCE) $(SS5_SOURCE) $(SIP_SOURCE) \
$(MISDN_SOURCE) $(GSM_SOURCE) $(SS5_SOURCE) $(SIP_SOURCE) $(VOOTP_SOURCE) \
endpoint.cpp endpointapp.cpp \
appbridge.cpp apppbx.cpp route.c action.cpp action_efi.cpp action_vbox.cpp extension.c mail.c \
join.cpp joinpbx.cpp
lcr_LDADD = $(LIBCRYPTO) $(MISDN_LIB) -lpthread $(GSM_LIB) $(SIP_LIB)
lcr_LDADD = $(LIBCRYPTO) $(MISDN_LIB) -lpthread $(GSM_LIB) $(SIP_LIB) $(VOOTP_LIB)
lcradmin_SOURCES = lcradmin.c cause.c options.c

View File

@ -525,6 +525,18 @@ void EndpointAppPBX::keypad_function(char digit)
join_join_dss1();
break;
/* VOOTP on */
case '1':
PDEBUG(DEBUG_EPOINT, "EPOINT(%d) enable VoOTP.\n", ea_endpoint->ep_serial);
vootp_on(1);
break;
/* VOOTP off */
case '2':
PDEBUG(DEBUG_EPOINT, "EPOINT(%d) disable VoOTP.\n", ea_endpoint->ep_serial);
vootp_on(0);
break;
#ifdef WITH_CRYPT
/* crypt shared */
case '7':
@ -544,7 +556,6 @@ void EndpointAppPBX::keypad_function(char digit)
encrypt_off();
break;
#endif
default:
PDEBUG(DEBUG_EPOINT, "EPOINT(%d) unsupported keypad digit '%c'.\n", ea_endpoint->ep_serial, digit);
}
@ -2430,6 +2441,24 @@ void EndpointAppPBX::port_disable_dejitter(struct port_list *portlist, int messa
}
/* port MESSAGE_UPDATEBRIDGE */
void EndpointAppPBX::port_updatebridge(struct port_list *portlist, int message_type, union parameter *param)
{
struct lcr_msg *message;
message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, MESSAGE_UPDATEBRIDGE);
message_put(message);
}
/* port MESSAGE_VOOTP */
void EndpointAppPBX::port_vootp(struct port_list *portlist, int message_type, union parameter *param)
{
if (param->vootp.failed)
set_tone(ea_endpoint->ep_portlist, "crypt_off");
}
/* port sends message to the endpoint
*/
void EndpointAppPBX::ea_message_port(unsigned int port_id, int message_type, union parameter *param)
@ -2626,6 +2655,16 @@ void EndpointAppPBX::ea_message_port(unsigned int port_id, int message_type, uni
port_disable_dejitter(portlist, message_type, param);
break;
case MESSAGE_UPDATEBRIDGE:
PDEBUG(DEBUG_EPOINT, "EPOINT(%d) incoming updatebridge message (terminal '%s', caller id '%s')\n", ea_endpoint->ep_serial, e_ext.number, e_callerinfo.id);
port_updatebridge(portlist, message_type, param);
break;
case MESSAGE_VOOTP:
PDEBUG(DEBUG_EPOINT, "EPOINT(%d) incoming vootp message (terminal '%s', caller id '%s')\n", ea_endpoint->ep_serial, e_ext.number, e_callerinfo.id);
port_vootp(portlist, message_type, param);
break;
default:
PDEBUG(DEBUG_EPOINT, "EPOINT(%d) epoint with terminal '%s' (caller id '%s') received a wrong message: %d\n", ea_endpoint->ep_serial, e_ext.number, e_callerinfo.id, message_type);
@ -4302,6 +4341,30 @@ int EndpointAppPBX::check_external(const char **errstr, class Port **port)
return(0);
}
int EndpointAppPBX::vootp_on(int on)
{
#ifndef WITH_VOOTP
set_tone(ea_endpoint->ep_portlist, "crypt_off");
#else
if (!e_ext.otp_ident[0]) {
set_tone(ea_endpoint->ep_portlist, "crypt_off");
return -EINVAL;
}
if(ea_endpoint->ep_portlist) {
struct lcr_msg *message;
message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_portlist->port_id, EPOINT_TO_PORT, MESSAGE_VOOTP);
message->param.vootp.enable = on;
SCPY(message->param.vootp.id, e_ext.otp_ident);
message_put(message);
}
if (!on)
set_tone(ea_endpoint->ep_portlist, "crypt_off");
#endif
return 0;
}
void EndpointAppPBX::logmessage(int message_type, union parameter *param, unsigned int port_id, int dir)
{
const char *logtext = "unknown";

View File

@ -217,6 +217,8 @@ class EndpointAppPBX : public EndpointApp
void port_resume(struct port_list *portlist, int message_type, union parameter *param);
void port_enablekeypad(struct port_list *portlist, int message_type, union parameter *param);
void port_disable_dejitter(struct port_list *portlist, int message_type, union parameter *param);
void port_updatebridge(struct port_list *portlist, int message_type, union parameter *param);
void port_vootp(struct port_list *portlist, int message_type, union parameter *param);
void ea_message_join(unsigned int join_id, int message, union parameter *param);
void join_crypt(struct port_list *portlist, int message_type, union parameter *param);
void join_mISDNsignal(struct port_list *portlist, int message_type, union parameter *param);
@ -365,6 +367,8 @@ class EndpointAppPBX : public EndpointApp
void cryptman_msg2crengine(int msg, unsigned char *buf, int len);
void cryptman_state(int state);
void cryptman_timeout(int secs);
int vootp_on(int enable);
void message_disconnect_port(struct port_list *portlist, int cause, int location, const char *display);
void logmessage(int message_type, union parameter *param, unsigned int port_id, int dir);
void trace_header(const char *name, int direction);

View File

@ -230,6 +230,20 @@ AS_IF([test "x$with_sip" == xyes -o "x$with_sip" == xyes], [
PKG_CHECK_MODULES(SOFIA, sofia-sip-ua >= 1.12)
])
# check for VoOTP
AC_ARG_WITH([vootp],
[AS_HELP_STRING([--with-vootp],
[compile with VoOTP support (libvootp is required) @<:@default=no@:>@])
],
[],
[with_vootp="check"])
AM_CONDITIONAL(ENABLE_VOOTP, test "x$with_vootp" == "xyes" )
AS_IF([test "x$with_vootp" == xyes -o "x$with_vootp" == xyes], [
PKG_CHECK_MODULES(VOOTP, libvootp >= 0.0)
])
# Checks for libraries.
AC_CHECK_LIB([m], [main])
AC_CHECK_LIB([ncurses], [main])
@ -275,4 +289,5 @@ AS_IF([test "x$found_opencore_amrnb" == xyes],[AC_MSG_NOTICE( Compiled with GSM
AS_IF([test "x$with_asterisk" == xyes],[AC_MSG_NOTICE( Compiled with Asterisk channel driver support )],[AC_MSG_NOTICE( Not compiled with Asterisk channel driver support)])
AS_IF([test "x$with_ss5" == xyes],[AC_MSG_NOTICE( Compiled with CCITT No.5 support )],[AC_MSG_NOTICE( Not compiled with CCITT No.5 support)])
AS_IF([test "x$with_sip" == xyes],[AC_MSG_NOTICE( Compiled with SIP support )],[AC_MSG_NOTICE( Not compiled with SIP support)])
AS_IF([test "x$with_vootp" == xyes],[AC_MSG_NOTICE( Compiled with VoOTP support )],[AC_MSG_NOTICE( Not compiled with VoOTP support)])

View File

@ -109,3 +109,7 @@
# This feature is temporarily for test purpose. Don't enable it
#polling
# Define OTP directory and identity
#otp-dir /root/
#otp-ident myname

View File

@ -2552,18 +2552,7 @@ void Pdss1::message_connect(unsigned int epoint_id, int message_id, union parame
/* screen outgoing caller id */
do_screen(1, p_connectinfo.id, sizeof(p_connectinfo.id), &p_connectinfo.ntype, &p_connectinfo.present, p_m_mISDNport->ifport->interface->name);
/* only display at connect state */
if (p_state == PORT_STATE_CONNECT)
if (p_connectinfo.display[0]) {
/* sending information */
l3m = create_l3msg();
l1l2l3_trace_header(p_m_mISDNport, this, L3_INFORMATION_REQ, DIRECTION_OUT);
if (p_m_d_ntmode || p_m_d_tespecial)
enc_ie_display(l3m, (unsigned char *)p_connectinfo.display);
end_trace();
p_m_mISDNport->ml3->to_layer3(p_m_mISDNport->ml3, MT_INFORMATION, p_m_d_l3id, l3m);
return;
}
set_display(p_connectinfo.display);
if (p_state!=PORT_STATE_IN_SETUP && p_state!=PORT_STATE_IN_OVERLAP && p_state!=PORT_STATE_IN_PROCEEDING && p_state!=PORT_STATE_IN_ALERTING) {
/* connect command only possible in setup, proceeding or alerting state */
@ -3088,6 +3077,23 @@ int stack2manager(struct mISDNport *mISDNport, unsigned int cmd, unsigned int pi
return(0);
}
void Pdss1::set_display(const char *text)
{
l3_msg *l3m;
/* only display at connect state */
if (p_state == PORT_STATE_CONNECT)
if (text[0]) {
/* sending information */
l3m = create_l3msg();
l1l2l3_trace_header(p_m_mISDNport, this, L3_INFORMATION_REQ, DIRECTION_OUT);
if (p_m_d_ntmode || p_m_d_tespecial)
enc_ie_display(l3m, (unsigned char *)text);
end_trace();
p_m_mISDNport->ml3->to_layer3(p_m_mISDNport->ml3, MT_INFORMATION, p_m_d_l3id, l3m);
return;
}
}

1
dss1.h
View File

@ -20,6 +20,7 @@ class Pdss1 : public PmISDN
void message_isdn(unsigned int cmd, unsigned int pid, struct l3_msg *l3m);
int p_m_d_ces; /* ntmode: tei&sapi */
int message_epoint(unsigned int epoint_id, int message, union parameter *param);
void set_display(const char *text);
int p_m_d_ntmode; /* flags the nt-mode */
int p_m_d_tespecial; /* special te-mode with all nt-mode IEs */

View File

@ -755,6 +755,10 @@ int read_extension(struct extension *ext, char *num)
} else {
PDEBUG(DEBUG_CONFIG, "unknown param for seconds: %s\n", param);
}
} else
if (!strcmp(option,"otp-ident")) {
SCPY(ext->otp_ident, param);
PDEBUG(DEBUG_CONFIG, "otp-ident: %s\n",param);
} else {
PERROR_RUNTIME("Error in %s (line %d): wrong option keyword %s.\n",filename,line,option);
}
@ -1144,6 +1148,9 @@ int write_extension(struct extension *ext, char *number)
fprintf(fp,"# Include seconds (time) in the connect message. (Should be always enabled.)\n");
fprintf(fp,"seconds %s\n\n",ext_yesno[1-ext->no_seconds]);
fprintf(fp,"# Identity string for VoOTP encryption\n");
fprintf(fp,"otp-ident %s\n\n", ext->otp_ident);
fprintf(fp,"# Last outgoing and incoming numbers (including prefix)\n");
i = 0;
while(i < MAX_REMEMBER) {

View File

@ -169,6 +169,8 @@ struct extension {
int facility; /* must be set to forward facility to terminal */
int datacall; /* data calls are handled as voice calls */
int no_seconds; /* don't include seconds in the connect message */
char otp_ident[9]; /* up to 8 bytes of ident */
};
int read_extension(struct extension *ext, char *number);

View File

@ -412,6 +412,11 @@ bfi:
/* send traffic to gsm */
int Pgsm::bridge_rx(unsigned char *data, int len)
{
int ret;
if ((ret = Port::bridge_rx(data, len)))
return ret;
if (p_tone_name[0])
return -EINVAL;

View File

@ -358,6 +358,17 @@ void JoinPBX::bridge(void)
relation = relation->next;
continue;
}
#ifdef WITH_VOOTP
if (port->p_vootp) {
PDEBUG(DEBUG_JOIN, "join%d ignoring relation ep%d because it's port uses VoOTP.\n", j_serial, epoint->ep_serial);
if (allmISDN) {
PDEBUG(DEBUG_JOIN, "join%d not all endpoints can support mISDN bridging.\n", j_serial);
allmISDN = 0;
}
relation = relation->next;
continue;
}
#endif
relation = relation->next;
}
@ -412,6 +423,17 @@ no need to count, because j_3pty is taken into account below when checking relat
relation = relation->next;
continue;
}
#ifdef WITH_VOOTP
if (port->p_vootp) {
PDEBUG(DEBUG_JOIN, "join%d ignoring relation ep%d because it's port uses VoOTP.\n", joinpbx_3pty->j_serial, epoint->ep_serial);
if (allmISDN) {
PDEBUG(DEBUG_JOIN, "join%d not all endpoints can support mISDN bridging.\n", joinpbx_3pty->j_serial);
allmISDN = 0;
}
relation = relation->next;
continue;
}
#endif
relation = relation->next;
}
@ -807,6 +829,11 @@ void JoinPBX::message_epoint(unsigned int epoint_id, int message_type, union par
}
return;
case MESSAGE_UPDATEBRIDGE:
trigger_work(&j_updatebridge);
joinpbx_debug(this, "Join::message_epoint{bridge is updated due to request from mISDN port}");
break;
/* track notify */
case MESSAGE_NOTIFY:
switch(param->notifyinfo.notify) {

View File

@ -1435,17 +1435,44 @@ void PmISDN::message_crypt(unsigned int epoint_id, int message_id, union paramet
}
/* MESSAGE_VOOTP */
void PmISDN::message_vootp(unsigned int epoint_id, int message_id, union parameter *param)
{
struct lcr_msg *message;
message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_UPDATEBRIDGE);
message_put(message);
#if 0
does not make sense, since remote port may dejitter
if (param->vootp.enable) {
PDEBUG(DEBUG_ISDN, "PmISDN(%s) received vootp enable order, so we disable de-jitter.\n", p_name);
p_m_disable_dejitter = 1;
}
#endif
update_rxoff();
}
/*
* endpoint sends messages to the port
*/
int PmISDN::message_epoint(unsigned int epoint_id, int message_id, union parameter *param)
{
/* messages also handled by base class */
switch(message_id) {
case MESSAGE_VOOTP: /* crypt control command */
PDEBUG(DEBUG_ISDN, "PmISDN(%s) received VoOTP encryption\n", p_name);
message_vootp(epoint_id, message_id, param);
break;
}
if (Port::message_epoint(epoint_id, message_id, param)) {
if (message_id == MESSAGE_BRIDGE)
update_rxoff();
return 1;
}
/* messages not handled by base class */
switch(message_id) {
case MESSAGE_mISDNSIGNAL: /* user command */
PDEBUG(DEBUG_ISDN, "PmISDN(%s) received special ISDN SIGNAL %d.\n", p_name, param->mISDNsignal.message);
@ -2275,6 +2302,9 @@ int PmISDN::bridge_rx(unsigned char *data, int length)
struct mISDNhead *hh = (struct mISDNhead *)buf;
int ret;
if ((ret = Port::bridge_rx(data, length)))
return ret;
if (p_m_b_index < 0)
return -EIO;
if (p_m_mISDNport->b_state[p_m_b_index] != B_STATE_ACTIVE)

View File

@ -109,6 +109,7 @@ class PmISDN : public Port
int message_epoint(unsigned int epoint_id, int message, union parameter *param);
void message_mISDNsignal(unsigned int epoint_id, int message_id, union parameter *param);
void message_crypt(unsigned int epoint_id, int message_id, union parameter *param);
void message_vootp(unsigned int epoint_id, int message_id, union parameter *param);
struct mISDNport *p_m_mISDNport; /* pointer to port */
int p_m_delay; /* use delay instead of dejitter */
int p_m_tx_dejitter; /* use dejitter on transmit data to DSP */

6
main.c
View File

@ -221,6 +221,12 @@ int main(int argc, char *argv[])
crc_init();
#endif
#ifdef WITH_VOOTP
/* init VoOTP */
vootp_init(stderr);
vootp_loglevel(VOOTP_LOGL_INFO);
#endif
/* the mutex init */
if (pthread_mutex_init(&mutexd, NULL)) {
fprintf(stderr, "cannot create 'PDEBUG' mutex\n");

10
main.h
View File

@ -11,6 +11,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdarg.h>
#include <unistd.h>
#include <string.h>
@ -147,6 +148,15 @@ void debug(const char *file, const char *function, int line, const char *prefix,
#include "appbridge.h"
#include "callerid.h"
#include "route.h"
#ifdef WITH_VOOTP
#ifdef __cplusplus
extern "C" {
#endif
#include <vootp.h>
#ifdef __cplusplus
}
#endif
#endif
#include "port.h"
#include "remote.h"
#ifdef WITH_MISDN

View File

@ -351,6 +351,12 @@ struct param_3pty {
unsigned char invoke_id;
};
struct param_vootp {
int enable;
int failed;
char id[32];
};
/* structure of message parameter */
union parameter {
struct param_tone tone; /* MESSAGE_TONE */
@ -379,6 +385,7 @@ union parameter {
struct param_traffic traffic; /* MESSAGE_TRAFFIC */
struct param_3pty threepty; /* MESSAGE_TRAFFIC */
unsigned int queue; /* MESSAGE_DISABLE_DEJITTER */
struct param_vootp vootp; /* MESSAGE_VOOTP */
};
enum { /* message flow */
@ -435,7 +442,9 @@ enum { /* messages between entities */
MESSAGE_TRAFFIC, /* exchange bchannel traffic */
MESSAGE_3PTY, /* 3PTY call invoke */
MESSAGE_TRANSFER, /* call transfer invoke */
MESSAGE_DISABLE_DEJITTER/* tell (mISDN) port not to dejitter */
MESSAGE_DISABLE_DEJITTER,/* tell (mISDN) port not to dejitter */
MESSAGE_UPDATEBRIDGE, /* tell join to update bridge. (sent by mISDN port) */
MESSAGE_VOOTP, /* enable/disable VoOTP */
};
#define MESSAGES static const char *messages_txt[] = { \
@ -475,6 +484,8 @@ enum { /* messages between entities */
"MESSAGE_3PTY", \
"MESSAGE_TRANSFER", \
"MESSAGE_DISABLE_DEJITTER", \
"MESSAGE_UPDATEBRIDGE", \
"MESSAGE_VOOTP", \
};

View File

@ -35,7 +35,8 @@ struct options options = {
0700, /* rights of lcr admin socket */
-1, /* socket user (-1= no change) */
-1, /* socket group (-1= no change) */
1, /* use polling of main loop */
0, /* use polling of main loop */
"/root", /* OTP directory */
};
char options_error[256];
@ -235,6 +236,13 @@ int read_options(char *options_error)
} else
if (!strcmp(option,"polling")) {
options.polling = 1;
} else
if (!strcmp(option,"otp-dir")) {
if (param[0]==0) {
UPRINT(options_error, "Error in %s (line %d): parameter for option %s missing.\n", filename,line,option);
goto error;
}
SCPY(options.otp_dir, param);
} else {
UPRINT(options_error, "Error in %s (line %d): wrong option keyword %s.\n", filename,line,option);
goto error;

View File

@ -30,6 +30,7 @@ struct options {
int socketuser; /* socket chown to this user */
int socketgroup; /* socket chgrp to this group */
int polling;
char otp_dir[256]; /* directory of OTP files */
};
extern struct options options;

View File

@ -188,6 +188,11 @@ Port::Port(int type, const char *portname, struct port_settings *settings, struc
p_record_buffer_writep = 0;
p_record_buffer_dir = 0;
/* VoOTP */
#ifdef WITH_VOOTP
p_vootp = NULL;
#endif
/* append port to chain */
next = NULL;
temp = port_first;
@ -214,6 +219,13 @@ Port::~Port(void)
PDEBUG(DEBUG_PORT, "removing port (%d) of type 0x%x, name '%s' interface '%s'\n", p_serial, p_type, p_name, p_interface_name);
#ifdef WITH_VOOTP
if (p_vootp) {
vootp_destroy(p_vootp);
p_vootp = NULL;
}
#endif
if (p_bridge) {
PDEBUG(DEBUG_PORT, "Removing us from bridge %u\n", p_bridge->bridge_id);
remove_bridge(p_bridge, this);
@ -377,6 +389,10 @@ void Port::set_tone(const char *dir, const char *name)
}
void Port::set_display(const char *text)
{
}
/*
* set the file in the tone directory for vbox playback
* also set the play_eof-flag
@ -637,6 +653,13 @@ int Port::message_epoint(unsigned int epoint_id, int message_id, union parameter
PDEBUG(DEBUG_PORT, "PORT(%s) bridging to id %d\n", p_name, param->bridge_id);
bridge(param->bridge_id);
return 1;
#ifdef WITH_VOOTP
case MESSAGE_VOOTP: /* enable / disable VoOTP */
PDEBUG(DEBUG_PORT, "PORT(%s) VoOTP enabled: %d\n", p_name, param->vootp.enable);
set_vootp(&param->vootp);
return 1;
#endif
}
return 0;
@ -1312,6 +1335,11 @@ int Port::bridge_tx(unsigned char *data, int len)
signed long *sum;
unsigned char *buf;
#ifdef WITH_VOOTP
if (p_vootp)
vootp_encrypt_stream(p_vootp, data, len);
#endif
/* less than two ports, so drop */
if (!p_bridge || !p_bridge->first || !p_bridge->first->next)
return -EIO;
@ -1427,9 +1455,47 @@ int bridge_timeout(struct lcr_timer *timer, void *instance, int index)
}
/* receive data from remote Port (dummy, needs to be inherited) */
/* receive data from remote Port */
int Port::bridge_rx(unsigned char *data, int len)
{
return 0; /* datenklo */
#ifdef WITH_VOOTP
if (p_vootp)
vootp_decrypt_stream(p_vootp, data, len);
#endif
return 0;
}
#ifdef WITH_VOOTP
static void vootp_info(void *priv, const char *text)
{
class Port *port = (class Port *)priv;
char display[strlen(text) + 1];
SCPY(display, text);
if (display[0])
display[strlen(display) - 1] = '\0';
port->set_display(display);
}
void Port::set_vootp(struct param_vootp *vootp)
{
if (p_vootp) {
vootp_destroy(p_vootp);
p_vootp = NULL;
}
if (vootp->enable) {
p_vootp = vootp_create(this, (options.law=='a'), options.otp_dir, NULL, NULL, vootp->id, vootp_info);
// vootp_loglevel(VOOTP_LOGL_DEBUG);
if (!p_vootp) {
struct lcr_msg *message;
message = message_create(p_serial, p_epointlist->epoint_id, PORT_TO_EPOINT, MESSAGE_VOOTP);
message->param.vootp.failed = 1;
message_put(message);
}
}
}
#endif

6
port.h
View File

@ -196,6 +196,7 @@ class Port
virtual void set_tone(const char *dir, const char *name);
virtual int read_audio(unsigned char *buffer, int length);
virtual void update_load(void);
virtual void set_display(const char *text);
struct port_settings p_settings;
char p_interface_name[64];
@ -270,6 +271,11 @@ class Port
int p_record_vbox_email_file;
virtual void update_rxoff(void); /* inherited by mISDNport, to control rxoff */
#ifdef WITH_VOOTP
vootp_t *p_vootp; /* VoOTP instance */
void set_vootp(struct param_vootp *vootp);
#endif
void free_epointlist(struct epoint_list *epointlist);
void free_epointid(unsigned int epoint_id);
struct epoint_list *epointlist_new(unsigned int epoint_id);

View File

@ -233,6 +233,10 @@ int Premote::bridge_rx(unsigned char *data, int len)
{
union parameter newparam;
int l;
int ret;
if ((ret = Port::bridge_rx(data, len)))
return ret;
/* send tones, if connected, or if early audio is enabled in proceeding/alerting state */
if (p_state != PORT_STATE_CONNECT

View File

@ -597,10 +597,15 @@ we only support alaw and ulaw!
/* receive from remote */
int Psip::bridge_rx(unsigned char *data, int len)
{
int ret;
/* don't bridge, if tones are provided */
if (p_tone_name[0])
return -EBUSY;
if ((ret = Port::bridge_rx(data, len)))
return ret;
/* write to rx buffer */
while(len--) {
p_s_rxdata[p_s_rxpos++] = flip[*data++];

View File

@ -191,6 +191,11 @@ void VBoxPort::send_announcement(void)
int VBoxPort::bridge_rx(unsigned char *data, int len)
{
int ret;
if ((ret = Port::bridge_rx(data, len)))
return ret;
if (p_record)
record(data, len, 1); // from up
return 0;