Experimental crypto feature: Support for libvootp
authorAndreas Eversberg <jolly@eversberg.eu>
Sun, 23 Dec 2012 05:45:43 +0000 (06:45 +0100)
committerAndreas Eversberg <jolly@eversberg.eu>
Tue, 15 Dec 2015 06:59:12 +0000 (07:59 +0100)
23 files changed:
Makefile.am
apppbx.cpp
apppbx.h
configure.ac
default/options.conf
dss1.cpp
dss1.h
extension.c
extension.h
gsm.cpp
joinpbx.cpp
mISDN.cpp
mISDN.h
main.c
main.h
message.h
options.c
options.h
port.cpp
port.h
remote.cpp
sip.cpp
vbox.cpp

index 6330219..fd0cbea 100644 (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
index b976393..7dfdf45 100644 (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";
index 1d372b1..aea434e 100644 (file)
--- a/apppbx.h
+++ b/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_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);
index 3cb6cb5..dafd9e2 100644 (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)])
 
index 9ee0860..a8dfa2a 100644 (file)
 # This feature is temporarily for test purpose. Don't enable it
 #polling
 
+# Define OTP directory and identity
+#otp-dir /root/
+#otp-ident myname
+
index 4f3d000..43452bb 100644 (file)
--- a/dss1.cpp
+++ b/dss1.cpp
@@ -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;
+       }
+}
 
 
 
diff --git a/dss1.h b/dss1.h
index 0c603d4..d9487b3 100644 (file)
--- a/dss1.h
+++ b/dss1.h
@@ -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 */
index edfe5eb..7332551 100644 (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) {
index cb5f149..29f81b1 100644 (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);
diff --git a/gsm.cpp b/gsm.cpp
index 5d4b64d..ec33695 100644 (file)
--- a/gsm.cpp
+++ b/gsm.cpp
@@ -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;
 
index 5d88fa2..71e7e1c 100644 (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) {
index 179646b..bac0e84 100644 (file)
--- a/mISDN.cpp
+++ b/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
  */
 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)
diff --git a/mISDN.h b/mISDN.h
index e3c278d..6c704f4 100644 (file)
--- a/mISDN.h
+++ b/mISDN.h
@@ -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 */
diff --git a/main.c b/main.c
index dddc64a..1e85e39 100644 (file)
--- a/main.c
+++ b/main.c
@@ -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");
diff --git a/main.h b/main.h
index b1c407c..17ea68c 100644 (file)
--- a/main.h
+++ b/main.h
@@ -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
index 68abd5d..8a8bc44 100644 (file)
--- a/message.h
+++ b/message.h
@@ -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", \
 };
 
 
index 081e2c5..9274eb1 100644 (file)
--- a/options.c
+++ b/options.c
@@ -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;
index 574cd68..d7e7603 100644 (file)
--- a/options.h
+++ b/options.h
@@ -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;
index 3dc5f68..16fcd72 100644 (file)
--- a/port.cpp
+++ b/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_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
diff --git a/port.h b/port.h
index 6cfc6b5..56bd47b 100644 (file)
--- a/port.h
+++ b/port.h
@@ -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);
index f8c8621..273779c 100644 (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
diff --git a/sip.cpp b/sip.cpp
index 4e33421..640631b 100644 (file)
--- a/sip.cpp
+++ b/sip.cpp
@@ -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++];
index 15475d9..8447b89 100644 (file)
--- a/vbox.cpp
+++ b/vbox.cpp
@@ -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;