Experimental crypto feature: Support for libvootp
This commit is contained in:
parent
cdee00aedd
commit
e233557e40
18
Makefile.am
18
Makefile.am
|
@ -132,6 +132,18 @@ SIP_LIB += $(SOFIA_LIBS)
|
||||||
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
VOOTP_LIB =
|
||||||
|
|
||||||
|
if ENABLE_VOOTP
|
||||||
|
|
||||||
|
VOOTP_INCLUDE = -DWITH_VOOTP $(VOOTP_CFLAGS)
|
||||||
|
|
||||||
|
VOOTP_SOURCE =
|
||||||
|
|
||||||
|
VOOTP_LIB += $(VOOTP_LIBS)
|
||||||
|
|
||||||
|
endif
|
||||||
|
|
||||||
bin_PROGRAMS = lcradmin gentones genwave
|
bin_PROGRAMS = lcradmin gentones genwave
|
||||||
|
|
||||||
sbin_PROGRAMS = lcr genrc genextension
|
sbin_PROGRAMS = lcr genrc genextension
|
||||||
|
@ -166,17 +178,17 @@ uninstall-hook:
|
||||||
cd '$(DESTDIR)$(astmoddir)' && rm -f chan_lcr.so
|
cd '$(DESTDIR)$(astmoddir)' && rm -f chan_lcr.so
|
||||||
endif
|
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 = \
|
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 \
|
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 \
|
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 \
|
endpoint.cpp endpointapp.cpp \
|
||||||
appbridge.cpp apppbx.cpp route.c action.cpp action_efi.cpp action_vbox.cpp extension.c mail.c \
|
appbridge.cpp apppbx.cpp route.c action.cpp action_efi.cpp action_vbox.cpp extension.c mail.c \
|
||||||
join.cpp joinpbx.cpp
|
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
|
lcradmin_SOURCES = lcradmin.c cause.c options.c
|
||||||
|
|
65
apppbx.cpp
65
apppbx.cpp
|
@ -525,6 +525,18 @@ void EndpointAppPBX::keypad_function(char digit)
|
||||||
join_join_dss1();
|
join_join_dss1();
|
||||||
break;
|
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
|
#ifdef WITH_CRYPT
|
||||||
/* crypt shared */
|
/* crypt shared */
|
||||||
case '7':
|
case '7':
|
||||||
|
@ -544,7 +556,6 @@ void EndpointAppPBX::keypad_function(char digit)
|
||||||
encrypt_off();
|
encrypt_off();
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
default:
|
default:
|
||||||
PDEBUG(DEBUG_EPOINT, "EPOINT(%d) unsupported keypad digit '%c'.\n", ea_endpoint->ep_serial, digit);
|
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
|
/* port sends message to the endpoint
|
||||||
*/
|
*/
|
||||||
void EndpointAppPBX::ea_message_port(unsigned int port_id, int message_type, union parameter *param)
|
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);
|
port_disable_dejitter(portlist, message_type, param);
|
||||||
break;
|
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:
|
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);
|
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);
|
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)
|
void EndpointAppPBX::logmessage(int message_type, union parameter *param, unsigned int port_id, int dir)
|
||||||
{
|
{
|
||||||
const char *logtext = "unknown";
|
const char *logtext = "unknown";
|
||||||
|
|
4
apppbx.h
4
apppbx.h
|
@ -217,6 +217,8 @@ class EndpointAppPBX : public EndpointApp
|
||||||
void port_resume(struct port_list *portlist, int message_type, union parameter *param);
|
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_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_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 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_crypt(struct port_list *portlist, int message_type, union parameter *param);
|
||||||
void join_mISDNsignal(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_msg2crengine(int msg, unsigned char *buf, int len);
|
||||||
void cryptman_state(int state);
|
void cryptman_state(int state);
|
||||||
void cryptman_timeout(int secs);
|
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 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 logmessage(int message_type, union parameter *param, unsigned int port_id, int dir);
|
||||||
void trace_header(const char *name, int direction);
|
void trace_header(const char *name, int direction);
|
||||||
|
|
15
configure.ac
15
configure.ac
|
@ -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)
|
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.
|
# Checks for libraries.
|
||||||
AC_CHECK_LIB([m], [main])
|
AC_CHECK_LIB([m], [main])
|
||||||
AC_CHECK_LIB([ncurses], [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_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_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_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)])
|
||||||
|
|
||||||
|
|
|
@ -109,3 +109,7 @@
|
||||||
# This feature is temporarily for test purpose. Don't enable it
|
# This feature is temporarily for test purpose. Don't enable it
|
||||||
#polling
|
#polling
|
||||||
|
|
||||||
|
# Define OTP directory and identity
|
||||||
|
#otp-dir /root/
|
||||||
|
#otp-ident myname
|
||||||
|
|
||||||
|
|
30
dss1.cpp
30
dss1.cpp
|
@ -2552,18 +2552,7 @@ void Pdss1::message_connect(unsigned int epoint_id, int message_id, union parame
|
||||||
/* screen outgoing caller id */
|
/* 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);
|
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 */
|
set_display(p_connectinfo.display);
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
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) {
|
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 */
|
/* 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);
|
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
1
dss1.h
|
@ -20,6 +20,7 @@ class Pdss1 : public PmISDN
|
||||||
void message_isdn(unsigned int cmd, unsigned int pid, struct l3_msg *l3m);
|
void message_isdn(unsigned int cmd, unsigned int pid, struct l3_msg *l3m);
|
||||||
int p_m_d_ces; /* ntmode: tei&sapi */
|
int p_m_d_ces; /* ntmode: tei&sapi */
|
||||||
int message_epoint(unsigned int epoint_id, int message, union parameter *param);
|
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_ntmode; /* flags the nt-mode */
|
||||||
int p_m_d_tespecial; /* special te-mode with all nt-mode IEs */
|
int p_m_d_tespecial; /* special te-mode with all nt-mode IEs */
|
||||||
|
|
|
@ -755,6 +755,10 @@ int read_extension(struct extension *ext, char *num)
|
||||||
} else {
|
} else {
|
||||||
PDEBUG(DEBUG_CONFIG, "unknown param for seconds: %s\n", param);
|
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 {
|
} else {
|
||||||
PERROR_RUNTIME("Error in %s (line %d): wrong option keyword %s.\n",filename,line,option);
|
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,"# 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,"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");
|
fprintf(fp,"# Last outgoing and incoming numbers (including prefix)\n");
|
||||||
i = 0;
|
i = 0;
|
||||||
while(i < MAX_REMEMBER) {
|
while(i < MAX_REMEMBER) {
|
||||||
|
|
|
@ -169,6 +169,8 @@ struct extension {
|
||||||
int facility; /* must be set to forward facility to terminal */
|
int facility; /* must be set to forward facility to terminal */
|
||||||
int datacall; /* data calls are handled as voice calls */
|
int datacall; /* data calls are handled as voice calls */
|
||||||
int no_seconds; /* don't include seconds in the connect message */
|
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);
|
int read_extension(struct extension *ext, char *number);
|
||||||
|
|
5
gsm.cpp
5
gsm.cpp
|
@ -412,6 +412,11 @@ bfi:
|
||||||
/* send traffic to gsm */
|
/* send traffic to gsm */
|
||||||
int Pgsm::bridge_rx(unsigned char *data, int len)
|
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])
|
if (p_tone_name[0])
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
|
27
joinpbx.cpp
27
joinpbx.cpp
|
@ -358,6 +358,17 @@ void JoinPBX::bridge(void)
|
||||||
relation = relation->next;
|
relation = relation->next;
|
||||||
continue;
|
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;
|
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;
|
relation = relation->next;
|
||||||
continue;
|
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;
|
relation = relation->next;
|
||||||
}
|
}
|
||||||
|
@ -807,6 +829,11 @@ void JoinPBX::message_epoint(unsigned int epoint_id, int message_type, union par
|
||||||
}
|
}
|
||||||
return;
|
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 */
|
/* track notify */
|
||||||
case MESSAGE_NOTIFY:
|
case MESSAGE_NOTIFY:
|
||||||
switch(param->notifyinfo.notify) {
|
switch(param->notifyinfo.notify) {
|
||||||
|
|
30
mISDN.cpp
30
mISDN.cpp
|
@ -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
|
* endpoint sends messages to the port
|
||||||
*/
|
*/
|
||||||
int PmISDN::message_epoint(unsigned int epoint_id, int message_id, union parameter *param)
|
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 (Port::message_epoint(epoint_id, message_id, param)) {
|
||||||
if (message_id == MESSAGE_BRIDGE)
|
if (message_id == MESSAGE_BRIDGE)
|
||||||
update_rxoff();
|
update_rxoff();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* messages not handled by base class */
|
||||||
switch(message_id) {
|
switch(message_id) {
|
||||||
case MESSAGE_mISDNSIGNAL: /* user command */
|
case MESSAGE_mISDNSIGNAL: /* user command */
|
||||||
PDEBUG(DEBUG_ISDN, "PmISDN(%s) received special ISDN SIGNAL %d.\n", p_name, param->mISDNsignal.message);
|
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;
|
struct mISDNhead *hh = (struct mISDNhead *)buf;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
if ((ret = Port::bridge_rx(data, length)))
|
||||||
|
return ret;
|
||||||
|
|
||||||
if (p_m_b_index < 0)
|
if (p_m_b_index < 0)
|
||||||
return -EIO;
|
return -EIO;
|
||||||
if (p_m_mISDNport->b_state[p_m_b_index] != B_STATE_ACTIVE)
|
if (p_m_mISDNport->b_state[p_m_b_index] != B_STATE_ACTIVE)
|
||||||
|
|
1
mISDN.h
1
mISDN.h
|
@ -109,6 +109,7 @@ class PmISDN : public Port
|
||||||
int message_epoint(unsigned int epoint_id, int message, union parameter *param);
|
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_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_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 */
|
struct mISDNport *p_m_mISDNport; /* pointer to port */
|
||||||
int p_m_delay; /* use delay instead of dejitter */
|
int p_m_delay; /* use delay instead of dejitter */
|
||||||
int p_m_tx_dejitter; /* use dejitter on transmit data to DSP */
|
int p_m_tx_dejitter; /* use dejitter on transmit data to DSP */
|
||||||
|
|
6
main.c
6
main.c
|
@ -221,6 +221,12 @@ int main(int argc, char *argv[])
|
||||||
crc_init();
|
crc_init();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef WITH_VOOTP
|
||||||
|
/* init VoOTP */
|
||||||
|
vootp_init(stderr);
|
||||||
|
vootp_loglevel(VOOTP_LOGL_INFO);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* the mutex init */
|
/* the mutex init */
|
||||||
if (pthread_mutex_init(&mutexd, NULL)) {
|
if (pthread_mutex_init(&mutexd, NULL)) {
|
||||||
fprintf(stderr, "cannot create 'PDEBUG' mutex\n");
|
fprintf(stderr, "cannot create 'PDEBUG' mutex\n");
|
||||||
|
|
10
main.h
10
main.h
|
@ -11,6 +11,7 @@
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <string.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 "appbridge.h"
|
||||||
#include "callerid.h"
|
#include "callerid.h"
|
||||||
#include "route.h"
|
#include "route.h"
|
||||||
|
#ifdef WITH_VOOTP
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
#include <vootp.h>
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
#include "port.h"
|
#include "port.h"
|
||||||
#include "remote.h"
|
#include "remote.h"
|
||||||
#ifdef WITH_MISDN
|
#ifdef WITH_MISDN
|
||||||
|
|
13
message.h
13
message.h
|
@ -351,6 +351,12 @@ struct param_3pty {
|
||||||
unsigned char invoke_id;
|
unsigned char invoke_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct param_vootp {
|
||||||
|
int enable;
|
||||||
|
int failed;
|
||||||
|
char id[32];
|
||||||
|
};
|
||||||
|
|
||||||
/* structure of message parameter */
|
/* structure of message parameter */
|
||||||
union parameter {
|
union parameter {
|
||||||
struct param_tone tone; /* MESSAGE_TONE */
|
struct param_tone tone; /* MESSAGE_TONE */
|
||||||
|
@ -379,6 +385,7 @@ union parameter {
|
||||||
struct param_traffic traffic; /* MESSAGE_TRAFFIC */
|
struct param_traffic traffic; /* MESSAGE_TRAFFIC */
|
||||||
struct param_3pty threepty; /* MESSAGE_TRAFFIC */
|
struct param_3pty threepty; /* MESSAGE_TRAFFIC */
|
||||||
unsigned int queue; /* MESSAGE_DISABLE_DEJITTER */
|
unsigned int queue; /* MESSAGE_DISABLE_DEJITTER */
|
||||||
|
struct param_vootp vootp; /* MESSAGE_VOOTP */
|
||||||
};
|
};
|
||||||
|
|
||||||
enum { /* message flow */
|
enum { /* message flow */
|
||||||
|
@ -435,7 +442,9 @@ enum { /* messages between entities */
|
||||||
MESSAGE_TRAFFIC, /* exchange bchannel traffic */
|
MESSAGE_TRAFFIC, /* exchange bchannel traffic */
|
||||||
MESSAGE_3PTY, /* 3PTY call invoke */
|
MESSAGE_3PTY, /* 3PTY call invoke */
|
||||||
MESSAGE_TRANSFER, /* call transfer 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[] = { \
|
#define MESSAGES static const char *messages_txt[] = { \
|
||||||
|
@ -475,6 +484,8 @@ enum { /* messages between entities */
|
||||||
"MESSAGE_3PTY", \
|
"MESSAGE_3PTY", \
|
||||||
"MESSAGE_TRANSFER", \
|
"MESSAGE_TRANSFER", \
|
||||||
"MESSAGE_DISABLE_DEJITTER", \
|
"MESSAGE_DISABLE_DEJITTER", \
|
||||||
|
"MESSAGE_UPDATEBRIDGE", \
|
||||||
|
"MESSAGE_VOOTP", \
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
10
options.c
10
options.c
|
@ -35,7 +35,8 @@ struct options options = {
|
||||||
0700, /* rights of lcr admin socket */
|
0700, /* rights of lcr admin socket */
|
||||||
-1, /* socket user (-1= no change) */
|
-1, /* socket user (-1= no change) */
|
||||||
-1, /* socket group (-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];
|
char options_error[256];
|
||||||
|
@ -235,6 +236,13 @@ int read_options(char *options_error)
|
||||||
} else
|
} else
|
||||||
if (!strcmp(option,"polling")) {
|
if (!strcmp(option,"polling")) {
|
||||||
options.polling = 1;
|
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 {
|
} else {
|
||||||
UPRINT(options_error, "Error in %s (line %d): wrong option keyword %s.\n", filename,line,option);
|
UPRINT(options_error, "Error in %s (line %d): wrong option keyword %s.\n", filename,line,option);
|
||||||
goto error;
|
goto error;
|
||||||
|
|
|
@ -30,6 +30,7 @@ struct options {
|
||||||
int socketuser; /* socket chown to this user */
|
int socketuser; /* socket chown to this user */
|
||||||
int socketgroup; /* socket chgrp to this group */
|
int socketgroup; /* socket chgrp to this group */
|
||||||
int polling;
|
int polling;
|
||||||
|
char otp_dir[256]; /* directory of OTP files */
|
||||||
};
|
};
|
||||||
|
|
||||||
extern struct options options;
|
extern struct options options;
|
||||||
|
|
70
port.cpp
70
port.cpp
|
@ -188,6 +188,11 @@ Port::Port(int type, const char *portname, struct port_settings *settings, struc
|
||||||
p_record_buffer_writep = 0;
|
p_record_buffer_writep = 0;
|
||||||
p_record_buffer_dir = 0;
|
p_record_buffer_dir = 0;
|
||||||
|
|
||||||
|
/* VoOTP */
|
||||||
|
#ifdef WITH_VOOTP
|
||||||
|
p_vootp = NULL;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* append port to chain */
|
/* append port to chain */
|
||||||
next = NULL;
|
next = NULL;
|
||||||
temp = port_first;
|
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);
|
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) {
|
if (p_bridge) {
|
||||||
PDEBUG(DEBUG_PORT, "Removing us from bridge %u\n", p_bridge->bridge_id);
|
PDEBUG(DEBUG_PORT, "Removing us from bridge %u\n", p_bridge->bridge_id);
|
||||||
remove_bridge(p_bridge, this);
|
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
|
* set the file in the tone directory for vbox playback
|
||||||
* also set the play_eof-flag
|
* 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);
|
PDEBUG(DEBUG_PORT, "PORT(%s) bridging to id %d\n", p_name, param->bridge_id);
|
||||||
bridge(param->bridge_id);
|
bridge(param->bridge_id);
|
||||||
return 1;
|
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(¶m->vootp);
|
||||||
|
return 1;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1312,6 +1335,11 @@ int Port::bridge_tx(unsigned char *data, int len)
|
||||||
signed long *sum;
|
signed long *sum;
|
||||||
unsigned char *buf;
|
unsigned char *buf;
|
||||||
|
|
||||||
|
#ifdef WITH_VOOTP
|
||||||
|
if (p_vootp)
|
||||||
|
vootp_encrypt_stream(p_vootp, data, len);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* less than two ports, so drop */
|
/* less than two ports, so drop */
|
||||||
if (!p_bridge || !p_bridge->first || !p_bridge->first->next)
|
if (!p_bridge || !p_bridge->first || !p_bridge->first->next)
|
||||||
return -EIO;
|
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)
|
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
6
port.h
|
@ -196,6 +196,7 @@ class Port
|
||||||
virtual void set_tone(const char *dir, const char *name);
|
virtual void set_tone(const char *dir, const char *name);
|
||||||
virtual int read_audio(unsigned char *buffer, int length);
|
virtual int read_audio(unsigned char *buffer, int length);
|
||||||
virtual void update_load(void);
|
virtual void update_load(void);
|
||||||
|
virtual void set_display(const char *text);
|
||||||
|
|
||||||
struct port_settings p_settings;
|
struct port_settings p_settings;
|
||||||
char p_interface_name[64];
|
char p_interface_name[64];
|
||||||
|
@ -270,6 +271,11 @@ class Port
|
||||||
int p_record_vbox_email_file;
|
int p_record_vbox_email_file;
|
||||||
virtual void update_rxoff(void); /* inherited by mISDNport, to control rxoff */
|
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_epointlist(struct epoint_list *epointlist);
|
||||||
void free_epointid(unsigned int epoint_id);
|
void free_epointid(unsigned int epoint_id);
|
||||||
struct epoint_list *epointlist_new(unsigned int epoint_id);
|
struct epoint_list *epointlist_new(unsigned int epoint_id);
|
||||||
|
|
|
@ -233,6 +233,10 @@ int Premote::bridge_rx(unsigned char *data, int len)
|
||||||
{
|
{
|
||||||
union parameter newparam;
|
union parameter newparam;
|
||||||
int l;
|
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 */
|
/* send tones, if connected, or if early audio is enabled in proceeding/alerting state */
|
||||||
if (p_state != PORT_STATE_CONNECT
|
if (p_state != PORT_STATE_CONNECT
|
||||||
|
|
5
sip.cpp
5
sip.cpp
|
@ -597,10 +597,15 @@ we only support alaw and ulaw!
|
||||||
/* receive from remote */
|
/* receive from remote */
|
||||||
int Psip::bridge_rx(unsigned char *data, int len)
|
int Psip::bridge_rx(unsigned char *data, int len)
|
||||||
{
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
/* don't bridge, if tones are provided */
|
/* don't bridge, if tones are provided */
|
||||||
if (p_tone_name[0])
|
if (p_tone_name[0])
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
|
|
||||||
|
if ((ret = Port::bridge_rx(data, len)))
|
||||||
|
return ret;
|
||||||
|
|
||||||
/* write to rx buffer */
|
/* write to rx buffer */
|
||||||
while(len--) {
|
while(len--) {
|
||||||
p_s_rxdata[p_s_rxpos++] = flip[*data++];
|
p_s_rxdata[p_s_rxpos++] = flip[*data++];
|
||||||
|
|
5
vbox.cpp
5
vbox.cpp
|
@ -191,6 +191,11 @@ void VBoxPort::send_announcement(void)
|
||||||
|
|
||||||
int VBoxPort::bridge_rx(unsigned char *data, int len)
|
int VBoxPort::bridge_rx(unsigned char *data, int len)
|
||||||
{
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if ((ret = Port::bridge_rx(data, len)))
|
||||||
|
return ret;
|
||||||
|
|
||||||
if (p_record)
|
if (p_record)
|
||||||
record(data, len, 1); // from up
|
record(data, len, 1); // from up
|
||||||
return 0;
|
return 0;
|
||||||
|
|
Loading…
Reference in New Issue