now gives warning if mISDN branch is wrong.
[lcr.git] / mISDN.cpp
index bdc1780..7bdb30d 100644 (file)
--- a/mISDN.cpp
+++ b/mISDN.cpp
@@ -9,7 +9,6 @@
 **                                                                           **
 \*****************************************************************************/ 
 
-
 #include "main.h"
 #include <poll.h>
 #include <errno.h>
@@ -32,6 +31,43 @@ extern "C" {
 }
 #endif
 
+#ifndef CMX_TXDATA_ON
+#define OLD_MISDN
+#endif
+#ifndef CMX_TXDATA_OFF
+#define OLD_MISDN
+#endif
+#ifndef CMX_DELAY
+#define OLD_MISDN
+#endif
+#ifndef PIPELINE_CFG
+#define OLD_MISDN
+#endif
+#ifndef CMX_TX_DATA
+#define OLD_MISDN
+#endif
+
+#ifdef OLD_MISDN
+#warning
+#warning *********************************************************
+#warning *
+#warning * It seems that you use an older version of mISDN.
+#warning * Features like voice recording or echo will not work.
+#warning * Also it causes problems with loading modules and may
+#warning * not work at all.
+#warning *
+#warning * Please upgrade to newer version. A working version can
+#warning * be found at www.linux-call-router.de.
+#warning *
+#warning * Do not use the mISDN_1_1 branch, it does not have all
+#warning * the features that are required. Use the master branch
+#warning * instead.
+#warning *
+#warning *********************************************************
+#warning
+#error
+#endif
+
 #ifndef ISDN_PID_L4_B_USER
 #define ISDN_PID_L4_B_USER 0x440000ff
 #endif
@@ -168,7 +204,8 @@ PmISDN::PmISDN(int type, mISDNport *mISDNport, char *portname, struct port_setti
        p_m_b_reserve = 0;
        p_m_delete = 0;
        p_m_hold = 0;
-       p_m_txvol = p_m_rxvol = 0;
+       p_m_tx_gain = mISDNport->ifport->interface->tx_gain;
+       p_m_rx_gain = mISDNport->ifport->interface->rx_gain;
        p_m_conf = 0;
        p_m_txdata = 0;
        p_m_delay = 0;
@@ -181,7 +218,8 @@ PmISDN::PmISDN(int type, mISDNport *mISDNport, char *portname, struct port_setti
        p_m_timer = 0;
        p_m_remote_ref = 0; /* channel shall be exported to given remote */
        p_m_remote_id = 0; /* channel shall be exported to given remote */
-
+       SCPY(p_m_pipeline, mISDNport->ifport->interface->pipeline);
+       
        /* audio */
        p_m_load = 0;
        p_m_last_tv_sec = 0;
@@ -194,13 +232,18 @@ PmISDN::PmISDN(int type, mISDNport *mISDNport, char *portname, struct port_setti
        p_m_crypt_msg_len = 0;
        p_m_crypt_msg[0] = '\0';
        p_m_crypt_msg_current = 0;
-       p_m_crypt_key[0] = '\0';
        p_m_crypt_key_len = 0;
        p_m_crypt_listen = 0;
        p_m_crypt_listen_state = 0;
        p_m_crypt_listen_len = 0;
        p_m_crypt_listen_msg[0] = '\0';
        p_m_crypt_listen_crc = 0;
+       if (mISDNport->ifport->interface->bf_len >= 4 && mISDNport->ifport->interface->bf_len <= 56)
+       {
+               memcpy(p_m_crypt_key, mISDNport->ifport->interface->bf_key, p_m_crypt_key_len);
+               p_m_crypt_key_len = mISDNport->ifport->interface->bf_len;
+               p_m_crypt = 1;
+       }
 
        /* if any channel requested by constructor */
        if (channel == CHANNEL_ANY)
@@ -460,7 +503,7 @@ static int _bchannel_create(struct mISDNport *mISDNport, int i)
 
        /* open socket */
        mISDNport->b_socket[i] = socket(PF_ISDN, SOCK_DGRAM, ISDN_P_B_L2DSP);
-       if (mISDNport->b_socket[i])
+       if (mISDNport->b_socket[i] < 0)
        {
                PERROR("Error: Failed to open bchannel-socket for index %d with mISDN-DSP layer. Did you load mISDNdsp.ko?\n", i);
                return(0);
@@ -626,14 +669,20 @@ static void _bchannel_configure(struct mISDNport *mISDNport, int i)
        }
 
        /* set dsp features */
+#ifndef OLD_MISDN
        if (port->p_m_txdata)
                ph_control(mISDNport, port, handle, (port->p_m_txdata)?CMX_TXDATA_ON:CMX_TXDATA_OFF, 0, "DSP-TXDATA", port->p_m_txdata);
        if (port->p_m_delay)
                ph_control(mISDNport, port, handle, CMX_DELAY, port->p_m_delay, "DSP-DELAY", port->p_m_delay);
-       if (port->p_m_txvol)
-               ph_control(mISDNport, port, handle, VOL_CHANGE_TX, port->p_m_txvol, "DSP-TXVOL", port->p_m_txvol);
-       if (port->p_m_rxvol)
-               ph_control(mISDNport, port, handle, VOL_CHANGE_RX, port->p_m_rxvol, "DSP-RXVOL", port->p_m_rxvol);
+#endif
+       if (port->p_m_tx_gain)
+               ph_control(mISDNport, port, handle, VOL_CHANGE_TX, port->p_m_tx_gain, "DSP-TX_GAIN", port->p_m_tx_gain);
+       if (port->p_m_rx_gain)
+               ph_control(mISDNport, port, handle, VOL_CHANGE_RX, port->p_m_rx_gain, "DSP-RX_GAIN", port->p_m_rx_gain);
+#ifndef OLD_MISDN
+       if (port->p_m_pipeline[0])
+               ph_control_block(mISDNport, port, handle, PIPELINE_CFG, port->p_m_pipeline, strlen(port->p_m_pipeline)+1, "DSP-PIPELINE", 0);
+#endif
        if (port->p_m_conf)
                ph_control(mISDNport, port, handle, CMX_CONF_JOIN, port->p_m_conf, "DSP-CONF", port->p_m_conf);
        if (port->p_m_echo)
@@ -779,16 +828,28 @@ void bchannel_event(struct mISDNport *mISDNport, int i, int event)
        int state = mISDNport->b_state[i];
        unsigned long p_m_remote_ref = 0;
        unsigned long p_m_remote_id = 0;
+       int p_m_tx_gain = 0;
+       int p_m_rx_gain = 0;
+       char *p_m_pipeline = NULL;
+       unsigned char *p_m_crypt_key = NULL;
+       int p_m_crypt_key_len = 0;
+       int p_m_crypt_key_type = 0;
 #ifdef SOCKET_MISDN
        unsigned long portid = (mISDNport->portnum<<8) + i+1+(i>=15);
 #else
-       unsigned long portid = mISDNport->b_addr[i];
+       unsigned long portid = mISDNport->b_stid[i];
 #endif
 
        if (b_port)
        {
                p_m_remote_id = b_port->p_m_remote_id;
                p_m_remote_ref = b_port->p_m_remote_ref;
+               p_m_tx_gain = b_port->p_m_tx_gain;
+               p_m_rx_gain = b_port->p_m_rx_gain;
+               p_m_pipeline = b_port->p_m_pipeline;
+               p_m_crypt_key = b_port->p_m_crypt_key;
+               p_m_crypt_key_len = b_port->p_m_crypt_key_len;
+               p_m_crypt_key_type = /*b_port->p_m_crypt_key_type*/1;
        }
 
        switch(event)
@@ -803,7 +864,7 @@ void bchannel_event(struct mISDNport *mISDNport, int i, int event)
                        if (p_m_remote_ref)
                        {
                                /* export bchannel */
-                               message_bchannel_to_join(p_m_remote_id, p_m_remote_ref, BCHANNEL_ASSIGN, portid);
+                               message_bchannel_to_join(p_m_remote_id, p_m_remote_ref, BCHANNEL_ASSIGN, portid, p_m_tx_gain, p_m_rx_gain, p_m_pipeline, p_m_crypt_key, p_m_crypt_key_len, p_m_crypt_key_type);
                                chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
                                add_trace("type", NULL, "assign");
 #ifdef SOCKET_MISDN
@@ -858,7 +919,7 @@ void bchannel_event(struct mISDNport *mISDNport, int i, int event)
                        /* in case, the bchannel is exported right after seize_bchannel */
                        /* export bchannel */
                        /* p_m_remote_id is set, when this event happens. */
-                       message_bchannel_to_join(p_m_remote_id, p_m_remote_ref, BCHANNEL_ASSIGN, portid);
+                       message_bchannel_to_join(p_m_remote_id, p_m_remote_ref, BCHANNEL_ASSIGN, portid, p_m_tx_gain, p_m_rx_gain, p_m_pipeline, p_m_crypt_key, p_m_crypt_key_len, p_m_crypt_key_type);
                        chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
                        add_trace("type", NULL, "assign");
 #ifdef SOCKET_MISDN
@@ -933,7 +994,7 @@ void bchannel_event(struct mISDNport *mISDNport, int i, int event)
                                 * OR bchannel is not used anymore
                                 * OR bchannel has been exported to an obsolete ref,
                                 * so reimport, to later export to new remote */
-                               message_bchannel_to_join(mISDNport->b_remote_id[i], 0, BCHANNEL_REMOVE, portid);
+                               message_bchannel_to_join(mISDNport->b_remote_id[i], 0, BCHANNEL_REMOVE, portid, 0,0,0,0,0,0);
                                chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
                                add_trace("type", NULL, "remove");
 #ifdef SOCKET_MISDN
@@ -973,7 +1034,7 @@ void bchannel_event(struct mISDNport *mISDNport, int i, int event)
 
                        case B_STATE_REMOTE:
                        /* bchannel is exported, so we re-import */
-                       message_bchannel_to_join(mISDNport->b_remote_id[i], 0, BCHANNEL_REMOVE, portid);
+                       message_bchannel_to_join(mISDNport->b_remote_id[i], 0, BCHANNEL_REMOVE, portid, 0,0,0,0,0,0);
                        chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
                        add_trace("type", NULL, "remove");
 #ifdef SOCKET_MISDN
@@ -1010,7 +1071,7 @@ void bchannel_event(struct mISDNport *mISDNport, int i, int event)
                                /* bchannel is now deactivate, but is requied by Port class, so we reactivate / export */
                                if (p_m_remote_ref)
                                {
-                                       message_bchannel_to_join(p_m_remote_id, p_m_remote_ref, BCHANNEL_ASSIGN, portid);
+                                       message_bchannel_to_join(p_m_remote_id, p_m_remote_ref, BCHANNEL_ASSIGN, portid, p_m_tx_gain, p_m_rx_gain, p_m_pipeline, p_m_crypt_key, p_m_crypt_key_len, p_m_crypt_key_type);
                                        chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
                                        add_trace("type", NULL, "assign");
 #ifdef SOCKET_MISDN
@@ -1050,7 +1111,7 @@ void bchannel_event(struct mISDNport *mISDNport, int i, int event)
                                /* bchannel is now imported, but is requied by Port class, so we reactivate / export */
                                if (p_m_remote_ref)
                                {
-                                       message_bchannel_to_join(p_m_remote_id, p_m_remote_ref, BCHANNEL_ASSIGN, portid);
+                                       message_bchannel_to_join(p_m_remote_id, p_m_remote_ref, BCHANNEL_ASSIGN, portid, p_m_tx_gain, p_m_rx_gain, p_m_pipeline, p_m_crypt_key, p_m_crypt_key_len, p_m_crypt_key_type);
                                        chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
                                        add_trace("type", NULL, "assign");
 #ifdef SOCKET_MISDN
@@ -1173,15 +1234,14 @@ seize:
  */
 void PmISDN::drop_bchannel(void)
 {
-       if (p_m_b_index < 0)
-               return;
-
        /* unreserve channel */
        if (p_m_b_reserve)
                p_m_mISDNport->b_reserved--;
        p_m_b_reserve = 0;
 
        /* if not in use */
+       if (p_m_b_index < 0)
+               return;
        if (!p_m_b_channel)
                return;
 
@@ -1383,7 +1443,9 @@ int PmISDN::handler(void)
                        p_m_load = 0;
 
                /* to send data, tone must be active OR crypt messages must be on */
-               if ((p_tone_name[0] || p_m_crypt_msg_loops) && p_m_load < ISDN_LOAD)
+               if ((p_tone_name[0] || p_m_crypt_msg_loops)
+                && (p_m_load < ISDN_LOAD)
+                && (p_state==PORT_STATE_CONNECT || p_m_mISDNport->tones))
                {
                        int tosend = ISDN_LOAD - p_m_load, length; 
 #ifdef SOCKET_MISDN
@@ -1416,6 +1478,7 @@ int PmISDN::handler(void)
                                        /* next loop */
                                        p_m_crypt_msg_current = 0;
                                        p_m_crypt_msg_loops--;
+//                                     puts("eine loop weniger");
                                }
 
                                /* new length */
@@ -1547,6 +1610,7 @@ void PmISDN::bchannel_receive(iframe_t *frm)
        {
                switch(frm->dinfo)
                {
+#ifndef OLD_MISDN
                        case CMX_TX_DATA:
                        if (!p_m_txdata)
                        {
@@ -1562,6 +1626,7 @@ void PmISDN::bchannel_receive(iframe_t *frm)
                        if (p_record)
                                record(data, len, 1); // from up
                        break;
+#endif
 
                        default:
                        chan_trace_header(p_m_mISDNport, this, "BCHANNEL signal", DIRECTION_IN);
@@ -1784,32 +1849,32 @@ void PmISDN::message_mISDNsignal(unsigned long epoint_id, int message_id, union
        switch(param->mISDNsignal.message)
        {
                case mISDNSIGNAL_VOLUME:
-               if (p_m_txvol != param->mISDNsignal.txvol)
+               if (p_m_tx_gain != param->mISDNsignal.tx_gain)
                {
-                       p_m_txvol = param->mISDNsignal.txvol;
-                       PDEBUG(DEBUG_BCHANNEL, "we change tx-volume to shift=%d.\n", p_m_txvol);
+                       p_m_tx_gain = param->mISDNsignal.tx_gain;
+                       PDEBUG(DEBUG_BCHANNEL, "we change tx-volume to shift=%d.\n", p_m_tx_gain);
                        if (p_m_b_index >= 0)
                        if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
 #ifdef SOCKET_MISDN
-                               ph_control(p_m_mISDNport, this, p_m_mISDNport->b_socket[p_m_b_index], VOL_CHANGE_TX, p_m_txvol, "DSP-TXVOL", p_m_txvol);
+                               ph_control(p_m_mISDNport, this, p_m_mISDNport->b_socket[p_m_b_index], VOL_CHANGE_TX, p_m_tx_gain, "DSP-TX_GAIN", p_m_tx_gain);
 #else
-                               ph_control(p_m_mISDNport, this, p_m_mISDNport->b_addr[p_m_b_index], VOL_CHANGE_TX, p_m_txvol, "DSP-TXVOL", p_m_txvol);
+                               ph_control(p_m_mISDNport, this, p_m_mISDNport->b_addr[p_m_b_index], VOL_CHANGE_TX, p_m_tx_gain, "DSP-TX_GAIN", p_m_tx_gain);
 #endif
                } else
-                       PDEBUG(DEBUG_BCHANNEL, "we already have tx-volume shift=%d.\n", p_m_rxvol);
-               if (p_m_rxvol != param->mISDNsignal.rxvol)
+                       PDEBUG(DEBUG_BCHANNEL, "we already have tx-volume shift=%d.\n", p_m_rx_gain);
+               if (p_m_rx_gain != param->mISDNsignal.rx_gain)
                {
-                       p_m_rxvol = param->mISDNsignal.rxvol;
-                       PDEBUG(DEBUG_BCHANNEL, "we change rx-volume to shift=%d.\n", p_m_rxvol);
+                       p_m_rx_gain = param->mISDNsignal.rx_gain;
+                       PDEBUG(DEBUG_BCHANNEL, "we change rx-volume to shift=%d.\n", p_m_rx_gain);
                        if (p_m_b_index >= 0)
                        if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
 #ifdef SOCKET_MISDN
-                               ph_control(p_m_mISDNport, this, p_m_mISDNport->b_socket[p_m_b_index], VOL_CHANGE_RX, p_m_rxvol, "DSP-RXVOL", p_m_rxvol);
+                               ph_control(p_m_mISDNport, this, p_m_mISDNport->b_socket[p_m_b_index], VOL_CHANGE_RX, p_m_rx_gain, "DSP-RX_GAIN", p_m_rx_gain);
 #else
-                               ph_control(p_m_mISDNport, this, p_m_mISDNport->b_addr[p_m_b_index], VOL_CHANGE_RX, p_m_rxvol, "DSP-RXVOL", p_m_rxvol);
+                               ph_control(p_m_mISDNport, this, p_m_mISDNport->b_addr[p_m_b_index], VOL_CHANGE_RX, p_m_rx_gain, "DSP-RX_GAIN", p_m_rx_gain);
 #endif
                } else
-                       PDEBUG(DEBUG_BCHANNEL, "we already have rx-volume shift=%d.\n", p_m_rxvol);
+                       PDEBUG(DEBUG_BCHANNEL, "we already have rx-volume shift=%d.\n", p_m_rx_gain);
                break;
 
                case mISDNSIGNAL_CONF:
@@ -1847,6 +1912,7 @@ void PmISDN::message_mISDNsignal(unsigned long epoint_id, int message_id, union
                {
                        p_m_delay = param->mISDNsignal.delay;
                        PDEBUG(DEBUG_BCHANNEL, "we change delay mode to delay=%d.\n", p_m_delay);
+#ifndef OLD_MISDN
                        if (p_m_b_index >= 0)
                        if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
 #ifdef SOCKET_MISDN
@@ -1854,6 +1920,7 @@ void PmISDN::message_mISDNsignal(unsigned long epoint_id, int message_id, union
 #else
                                ph_control(p_m_mISDNport, this, p_m_mISDNport->b_addr[p_m_b_index], p_m_delay?CMX_DELAY:CMX_JITTER, p_m_delay, "DSP-DELAY", p_m_delay);
 #endif
+#endif
                } else
                        PDEBUG(DEBUG_BCHANNEL, "we already have delay=%d.\n", p_m_delay);
                break;
@@ -1915,7 +1982,7 @@ void PmISDN::message_crypt(unsigned long epoint_id, int message_id, union parame
                        break;
                }
                p_m_crypt_msg_current = 0; /* reset */
-               p_m_crypt_msg_loops = 3; /* enable */
+               p_m_crypt_msg_loops = 6; /* enable */
 #if 0
                /* disable txmix, or we get corrupt data due to audio process */
                if (p_m_txmix && p_m_b_index>=0)
@@ -1971,7 +2038,7 @@ int PmISDN::message_epoint(unsigned long epoint_id, int message_id, union parame
 #ifdef SOCKET_MISDN
 int mISDN_handler(void)
 {
-       int ret;
+       int ret, work = 0;
        struct mISDNport *mISDNport;
        class PmISDN *isdnport;
        int i;
@@ -2050,6 +2117,7 @@ int mISDN_handler(void)
                                ret = recv(mISDNport->b_stack[i], buffer, sizeof(buffer), 0);
                                if (ret >= MISDN_HEADER_LEN)
                                {
+                                       work = 1;
                                        switch(hh->prim)
                                        {
                                                /* we don't care about confirms, we use rx data to sync tx */
@@ -2060,6 +2128,7 @@ int mISDN_handler(void)
                                                /* we receive audio data, we respond to it AND we send tones */
                                                case PH_DATA_IND:
                                                case DL_DATA_IND:
+                                               case PH_SIGNAL_IND:
                                                case PH_CONTROL_IND:
                                                if (mISDNport->b_port[i])
                                                        mISDNport->b_port[i]->bchannel_receive(hh, buffer+MISDN_HEADER_LEN, ret-MISDN_HEADER_LEN);
@@ -2120,6 +2189,8 @@ int mISDN_handler(void)
                mISDNport = mISDNport->next;
        }
 
+       /* if we received at least one b-frame, we will return 1 */
+       return(work);
 }
 #else
 int mISDN_handler(void)
@@ -2181,8 +2252,10 @@ int mISDN_handler(void)
                                                /* turn on RX */
                                                isdnport->p_m_txdata = 1;
                                                PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is required, so we turn them on\n");
+#ifndef OLD_MISDN
                                                if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
                                                        ph_control(mISDNport, isdnport, mISDNport->b_addr[isdnport->p_m_b_index], CMX_TXDATA_ON, 0, "DSP-TXDATA", 1);
+#endif
                                                return(1);
                                        }
                                } else
@@ -2193,8 +2266,10 @@ int mISDN_handler(void)
                                                /* turn off RX */
                                                isdnport->p_m_txdata = 0;
                                                PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is not required, so we turn them off\n");
+#ifndef OLD_MISDN
                                                if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
                                                        ph_control(mISDNport, isdnport, mISDNport->b_addr[isdnport->p_m_b_index], CMX_TXDATA_OFF, 0, "DSP-TXDATA", 0);
+#endif
                                                return(1);
                                        }
                                }