backup
authorSuper User <root@isdn.jolly.ten>
Sat, 19 May 2007 17:45:42 +0000 (19:45 +0200)
committerSuper User <root@isdn.jolly.ten>
Sat, 19 May 2007 17:45:42 +0000 (19:45 +0200)
apppbx.cpp
apppbx.h
extension.h
mISDN.cpp
mISDN.h
main.h
message.h
port.cpp
port.h
vbox.cpp

index ba29919..bdec698 100644 (file)
@@ -2895,20 +2895,6 @@ void EndpointAppPBX::ea_message_port(unsigned long port_id, int message_type, un
                port_resume(portlist, message_type, param);
                break;
 
-               case MESSAGE_VBOX_RECORD:
-               PDEBUG(DEBUG_EPOINT, "EPOINT(%d) epoint with terminal '%s' (caller id '%s') received recording message from vbox.\n", ea_endpoint->ep_serial, e_terminal, e_callerinfo.id);
-               /* check if we are a terminal */
-               if (e_terminal[0] == '\0')
-                       PERROR("Port(%d) cannot record because we are not a terminal\n", ea_endpoint->ep_serial);
-               else
-               {
-                       port = find_port_id(portlist->port_id);
-                       if (port)
-                               port->open_record(e_ext.vbox_codec, 2, 0, e_terminal, e_ext.anon_ignore, e_ext.vbox_email, e_ext.vbox_email_file);
-               }
-               /* the recording is done to the vbox directory rather than to the recording directory (using vbox_codec) */
-               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_terminal, e_callerinfo.id, message);
        }
index e424b2f..a93a285 100644 (file)
--- a/apppbx.h
+++ b/apppbx.h
@@ -68,7 +68,6 @@ class EndpointAppPBX : public EndpointApp
 
        /* states */
        int                     e_state;                /* state of endpoint */
-       char                    e_terminal[32];         /* real id of terminal, "" for external calls */
        char                    e_terminal_interface[32];/* current internal isdn interface (usefull for callback to internal phone) */
        struct caller_info      e_callerinfo;           /* information about the caller */
        struct dialing_info     e_dialinginfo;          /* information about dialing */
index c59bb6d..4a09d7f 100644 (file)
@@ -105,7 +105,8 @@ enum {
  */
 
 struct extension {
-       char name[16];
+       char number[32];        /* number of extension */
+       char name[32];
        char prefix[32];
        char next[32];          /* next number to dial when pickup (temp prefix) */
        char alarm[32];
index 0226947..dfb8a6d 100644 (file)
--- a/mISDN.cpp
+++ b/mISDN.cpp
@@ -66,7 +66,7 @@ PmISDN::PmISDN(int type, mISDNport *mISDNport, char *portname, struct port_setti
        p_m_echo = 0;
        p_m_tone = 0;
        p_m_rxoff = 0;
-       p_m_nodata = 1; /* may be 1, because call always notifies us */
+       p_m_calldata = 0;
        p_m_dtmf = !options.nodtmf;
        sollen wir daraus eine interface-option machen?:
        p_m_timeout = 0;
@@ -147,7 +147,7 @@ void ph_control(unsigned long b_addr, int c1, int c2)
        ctrl->prim = PH_CONTROL | REQUEST;
        ctrl->addr = b_addr | FLG_MSG_DOWN;
        ctrl->dinfo = 0;
-       ctrl->len = sizeof(unsigned long)*2;
+       ctrl->len = sizeof(int)*2;
        *d++ = c1;
        *d++ = c2;
        mISDN_write(mISDNdevice, ctrl, mISDN_HEADER_LEN+ctrl->len, TIMEOUT_1SEC);
@@ -162,7 +162,7 @@ void ph_control_block(unsigned long b_addr, int c1, void *c2, int c2_len)
        ctrl->prim = PH_CONTROL | REQUEST;
        ctrl->addr = b_addr | FLG_MSG_DOWN;
        ctrl->dinfo = 0;
-       ctrl->len = sizeof(unsigned long)*2;
+       ctrl->len = sizeof(int)+c2_len;
        *d++ = c1;
        memcpy(d, c2, c2_len);
        mISDN_write(mISDNdevice, ctrl, mISDN_HEADER_LEN+ctrl->len, TIMEOUT_1SEC);
@@ -263,23 +263,7 @@ static void bchannel_activate(struct mISDNport *mISDNport, int i)
                        PDEBUG(DEBUG_BCHANNEL, "during activation, we set crypt to crypt=%d.\n", mISDNport->b_port[i]->p_m_crypt);
                        ph_control_block(mISDNport->b_addr[i], BF_ENABLE_KEY, mISDNport->b_port[i]->p_m_crypt_key, mISDNport->b_port[i]->p_m_crypt_key_len);
                }
-
-               /* preload tx-buffer */
-               pre->len = mISDNport->b_port[i]->read_audio(p, ISDN_PRELOAD, 1);
-               if (pre->len > 0)
-               {
-                       PDEBUG(DEBUG_BCHANNEL, "port is activated, we fill our buffer (ISDN_PRELOAD = %d).\n", pre->len);
-                       /* flip bits */
-#if 0
-                       q = p + pre->len;
-                       while(p != q)
-                                *p++ = flip[*p];
-#endif
-                       pre->prim = DL_DATA | REQUEST;
-                       pre->addr = mISDNport->b_addr[i] | FLG_MSG_DOWN;
-                       pre->dinfo = 0;
-                       mISDN_write(mISDNdevice, pre, mISDN_HEADER_LEN+pre->len, TIMEOUT_1SEC);
-               }
+               todo: wer startet/stoppt eigentlich den audio-transmit
        }
 }
 
@@ -468,12 +452,133 @@ void PmISDN::drop_bchannel(void)
        p_m_b_stid = 0;
 }
 
+
+/*
+ * data is to be transmitted to the remote
+ */
+wech void Port::transmit(unsigned char *buffer, int length, int tonelength)
+{
+       /* send tone data to isdn device only if we have data, otherwhise we send nothing */
+       if (tonelength>0 && (p_tone_fh>=0 || p_tone_fetched || p_m_crypt_msg_loops))
+       {
+               unsigned char buf[mISDN_HEADER_LEN+tonelength];
+               iframe_t *frm = (iframe_t *)buf;
+
+               if (p_m_crypt_msg_loops)
+               {
+                       /* send pending message */
+                       int tosend;
+
+                       tosend = p_m_crypt_msg_len - p_m_crypt_msg_current;
+                       if (tosend > newlen)
+                               tosend = newlen;
+                       memcpy(p, p_m_crypt_msg+p_m_crypt_msg_current, tosend);
+                       p_m_crypt_msg_current += tosend;
+                       if (p_m_crypt_msg_current == p_m_crypt_msg_len)
+                       {
+                               p_m_crypt_msg_current = 0;
+                               p_m_crypt_msg_loops--;
+                       }
+               }
+               frm->prim = DL_DATA | REQUEST; 
+               frm->addr = p_m_b_addr | FLG_MSG_DOWN;
+               frm->dinfo = 0;
+               frm->len = tonelength;
+               memcpy(&frm->data.p, buffer, tonelength);
+               mISDN_write(mISDNdevice, frm, mISDN_HEADER_LEN+frm->len, TIMEOUT_1SEC);
+
+               if (p_debug_nothingtosend)
+               {
+                       p_debug_nothingtosend = 0;
+                       PDEBUG((DEBUG_PORT | DEBUG_BCHANNEL), "PmISDN(%s) start sending, because we have tones and/or remote audio.\n", p_name);
+               } 
+       } else
+       {
+               if (!p_debug_nothingtosend)
+               {
+                       p_debug_nothingtosend = 1;
+                       PDEBUG((DEBUG_PORT | DEBUG_BCHANNEL), "PmISDN(%s) stop sending, because we have only silence.\n", p_name);
+               } 
+       }
+}
+
+
 /*
  * handler
  */
 int PmISDN::handler(void)
 {
        struct message *message;
+       int elapsed, length;
+
+       if ((ret = Port::handler()))
+               return(ret);
+
+       /* send tone data to isdn device only if we have data */
+       if (p_tone_fh>=0 || p_tone_fetched || p_m_crypt_msg_loops)
+       {
+               /* calculate how much to transmit */
+               if (!p_last_tv.sec)
+               {
+                       elapsed = ISDN_PRELOAD << 3; /* preload for the first time */
+               } else
+               {
+                       elapsed = 1000 * (now_tv.sec - p_last_tv_sec)
+                               + (now_tv.usec/1000) - p_last_tv_msec;
+                       /* gap was greater preload, so only fill up to preload level */
+                       if (elapsed > ISDN_PRELOAD)
+                       {
+                               elapsed = ISDN_PRELOAD << 3
+                       }
+               }
+               if (elapsed >= ISDN_TRANSMIT)
+               {
+                       unsigned char buf[mISDN_HEADER_LEN+(ISDN_PRELOAD<<3)];
+                       iframe_t *frm = (iframe_t *)buf;
+
+                       length = read_audio(buffer, elapsed);
+                       p_last_tv_sec = now_tv.sec;
+                       p_last_tv_msec = now_tv.usec/1000;
+
+                       if (p_m_crypt_msg_loops)
+                       {
+                               /* send pending message */
+                               int tosend;
+       check!!
+                               tosend = p_m_crypt_msg_len - p_m_crypt_msg_current;
+                               if (tosend > length)
+                                       tosend = length;
+                               memcpy(p, p_m_crypt_msg+p_m_crypt_msg_current, tosend);
+                               p_m_crypt_msg_current += tosend;
+                               if (p_m_crypt_msg_current == p_m_crypt_msg_len)
+                               {
+                                       p_m_crypt_msg_current = 0;
+                                       p_m_crypt_msg_loops--;
+                               }
+                       }
+                       frm->prim = DL_DATA | REQUEST; 
+                       frm->addr = p_m_b_addr | FLG_MSG_DOWN;
+                       frm->dinfo = 0;
+                       frm->len = length;
+                       memcpy(&frm->data.p, buffer, length);
+                       mISDN_write(mISDNdevice, frm, mISDN_HEADER_LEN+frm->len, TIMEOUT_1SEC);
+
+                       if (p_debug_nothingtosend)
+                       {
+                               p_debug_nothingtosend = 0;
+                               PDEBUG((DEBUG_PORT | DEBUG_BCHANNEL), "PmISDN(%s) start sending, because we have tones and/or remote audio.\n", p_name);
+                       } 
+                       return(1);
+               }
+       } else
+       {
+               p_last_tv.sec = p_last_tv.msec = 0; /* flag that we don't transmit data */
+               if (!cwp_debug_nothingtosend)
+               {
+                       p_debug_nothingtosend = 1;
+                       PDEBUG((DEBUG_PORT | DEBUG_BCHANNEL), "PmISDN(%s) stop sending, because we have only silence.\n", p_name);
+               } 
+       }
 
        // NOTE: deletion is done by the child class
 
@@ -598,38 +703,10 @@ void PmISDN::bchannel_receive(iframe_t *frm)
                cryptman_listen_bch((unsigned char *)&frm->data.p, frm->len);
        }
 
-       /* prevent jitter */
-       gettimeofday(&tv, &tz);
-       jitter_now = tv.tv_sec;
-       jitter_now = jitter_now*8000 + tv.tv_usec/125;
-       if (p_m_jittercheck == 0)
-       {
-               p_m_jittercheck = jitter_now;
-               p_m_jitterdropped = 0;
-       } else
-               p_m_jittercheck += frm->len;
-       if (p_m_jittercheck < jitter_now)
-       {
-//             PERROR("jitter: ignoring slow data\n");
-               p_m_jittercheck = jitter_now;
-       } else
-       if (p_m_jittercheck-ISDN_JITTERLIMIT > jitter_now)
-       {
-               p_m_jitterdropped += frm->len;
-               p_m_jittercheck -= frm->len;
-               /* must exit here */
-               return;
-       } else
-       if (p_m_jitterdropped)
-       {
-               PERROR("jitter: dropping, caused by fast data: %lld\n", p_m_jitterdropped);
-               p_m_jitterdropped = 0;
-       }
-
        p = (unsigned char *)&frm->data.p;
 
        /* send data to epoint */
-       if (ACTIVE_EPOINT(p_epointlist)) /* only if we have an epoint object */
+       if (p_m_calldata && ACTIVE_EPOINT(p_epointlist)) /* only if we have an epoint object */
        {
 //printf("we are port %s and sending to epoint %d\n", p_m_cardname, p_epoint->serial);
                length_temp = frm->len;
@@ -649,67 +726,6 @@ void PmISDN::bchannel_receive(iframe_t *frm)
                        length_temp -= sizeof(message->param.data.data);
                }
        }
-       /* return the same number of tone data, as we recieved */
-       newlen = read_audio(p, frm->len, 1);
-       /* send tone data to isdn device only if we have data, otherwhise we send nothing */
-       if (newlen>0 && (p_tone_fh>=0 || p_tone_fetched || !p_m_nodata || p_m_crypt_msg_loops))
-       {
-//printf("jolly: sending.... %d %d %d %d %d\n", newlen, p_tone_fh, p_tone_fetched, p_m_nodata, p_m_crypt_msg_loops);
-#if 0
-               if (p_m_txmix_on)
-               {
-                       p_m_txmix_on -= newlen;
-                       if (p_m_txmix_on <= 0)
-                       {
-                               p_m_txmix_on = 0;
-                               p_m_txmix = !p_m_nodata;
-                               PDEBUG(DEBUG_BCHANNEL, "after sending message, we set txmix to txmix=%d.\n", p_m_txmix);
-                               if (p_m_txmix)
-                                       ph_control(p_m_b_addr, CMX_MIX_ON, 0);
-                       }
-               }
-#endif 
-               if (p_m_crypt_msg_loops)
-               {
-                       /* send pending message */
-                       int tosend;
-
-                       tosend = p_m_crypt_msg_len - p_m_crypt_msg_current;
-                       if (tosend > newlen)
-                               tosend = newlen;
-                       memcpy(p, p_m_crypt_msg+p_m_crypt_msg_current, tosend);
-                       p_m_crypt_msg_current += tosend;
-                       if (p_m_crypt_msg_current == p_m_crypt_msg_len)
-                       {
-                               p_m_crypt_msg_current = 0;
-                               p_m_crypt_msg_loops--;
-#if 0
-// we need to disable rxmix some time after sending the loops...
-                               if (!p_m_crypt_msg_loops && p_m_txmix)
-                               {
-                                       p_m_txmix_on = 8000; /* one sec */
-                               }
-#endif
-                       }
-               }
-               frm->prim = frm->prim & 0xfffffffc | REQUEST; 
-               frm->addr = p_m_b_addr | FLG_MSG_DOWN;
-               frm->len = newlen;
-               mISDN_write(mISDNdevice, frm, mISDN_HEADER_LEN+frm->len, TIMEOUT_1SEC);
-
-               if (p_debug_nothingtosend)
-               {
-                       p_debug_nothingtosend = 0;
-                       PDEBUG((DEBUG_PORT | DEBUG_BCHANNEL), "PmISDN(%s) start sending, because we have tones and/or remote audio.\n", p_name);
-               } 
-       } else
-       {
-               if (!p_debug_nothingtosend)
-               {
-                       p_debug_nothingtosend = 1;
-                       PDEBUG((DEBUG_PORT | DEBUG_BCHANNEL), "PmISDN(%s) stop sending, because we have only silence.\n", p_name);
-               } 
-       }
 #if 0
        /* response to the data indication */
        rsp.prim = frm->prim & 0xfffffffc | RESPONSE; 
@@ -1034,6 +1050,14 @@ int PmISDN::message_epoint(unsigned long epoint_id, int message_id, union parame
 
 
 /*
+ * transmit function for data to mISDN b-channel
+ */
+void Port::transmit(unsigned char *buffer, int length)
+{
+}
+
+
+/*
  * main loop for processing messages from mISDN device
  */
 int mISDN_handler(void)
@@ -1048,22 +1072,19 @@ int mISDN_handler(void)
        mISDNuser_head_t *hh;
        int i;
 
-       if ((ret = Port::handler()))
-               return(ret);
-
        /* the que avoids loopbacks when replying to stack after receiving
          * from stack. */
        mISDNport = mISDNport_first;
        while(mISDNport)
        {
-               /* process turning off rx */
+               /* process turning on/off rx */
                i = 0;
                while(i < mISDNport->b_num)
                {
                        if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
                        {
                                isdnport=mISDNport->b_port[i];
-                               if (isdnport->p_tone_name[0] || isdnport->p_tone_fh>=0 || isdnport->p_tone_fetched || !isdnport->p_m_nodata || isdnport->p_m_crypt_msg_loops || isdnport->p_m_crypt_listen || isdnport->p_record)
+                               if (isdnport->p_m_calldata || isdnport->p_m_crypt_msg_loops || isdnport->p_m_crypt_listen || isdnport->p_record)
                                {
                                        /* rx IS required */
                                        if (isdnport->p_m_rxoff)
@@ -1072,6 +1093,7 @@ int mISDN_handler(void)
                                                isdnport->p_m_rxoff = 0;
                                                PDEBUG(DEBUG_BCHANNEL, "%s: receive data is required, so we turn them on\n");
                                                ph_control(isdnport->p_m_b_addr, CMX_RECEIVE_ON, 0);
+                                               return(1);
                                        }
                                } else
                                {
@@ -1082,9 +1104,9 @@ int mISDN_handler(void)
                                                isdnport->p_m_rxoff = 1;
                                                PDEBUG(DEBUG_BCHANNEL, "%s: receive data is not required, so we turn them off\n");
                                                ph_control(isdnport->p_m_b_addr, CMX_RECEIVE_OFF, 0);
+                                               return(1);
                                        }
                                }
-                               isdnport->p_m_jittercheck = 0; /* reset jitter detection check */
                        }
                        i++;
                }
@@ -1118,6 +1140,7 @@ int mISDN_handler(void)
                                        act.len = 0;
                                        mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
                                }
+                               return(1);
                        }
                }
                if ((dmsg = msg_dequeue(&mISDNport->downqueue)))
diff --git a/mISDN.h b/mISDN.h
index 5aba535..49ff539 100644 (file)
--- a/mISDN.h
+++ b/mISDN.h
@@ -91,6 +91,7 @@ class PmISDN : public Port
        ~PmISDN();
        void bchannel_receive(iframe_t *frm);
        int handler(void);
+       void transmit(unsigned char *buffer, int length);
        int message_epoint(unsigned long epoint_id, int message, union parameter *param);
        void message_mISDNsignal(unsigned long epoint_id, int message_id, union parameter *param);
        void message_crypt(unsigned long epoint_id, int message_id, union parameter *param);
diff --git a/main.h b/main.h
index 2519970..034ae13 100644 (file)
--- a/main.h
+++ b/main.h
@@ -58,17 +58,16 @@ void _printerror(const char *function, int line, const char *fmt, ...);
  */
 #define DEBUG_LOG      0x7fff
 
-/* 
- * transmit interval for tones and announcements (or samples of all kind)
- * 
- */
-#define ISDN_TRANSMIT  128
-
 /*
  * preload transmit buffer to avoid gaps at the beginning due to jitter
- * keep this 0 for minimum delay
+ * this is also the maximum load that will be kept in tx-buffer
+ */
+#define ISDN_PRELOAD   128 // 1024 samples
+
+/* 
+ * interval for refreshing transmit buffer
  */
-#define ISDN_PRELOAD   0
+#define ISDN_TRANSMIT  32 // 256 samples
 
 /* give sendmail program. if not inside $PATH, give absolute path here (e.g. "/usr/sbin/sendmail")
  */
index ce1bb76..afc14fb 100644 (file)
--- a/message.h
+++ b/message.h
@@ -351,7 +351,6 @@ enum { /* messages between entities */
        MESSAGE_VBOX_TONE,      /* set answering VBOX tone */
        MESSAGE_TONE_COUNTER,   /* tone counter (for VBOX tone use) */
        MESSAGE_TONE_EOF,       /* tone is end of file */
-       MESSAGE_VBOX_RECORD,    /* tell endpoint to start recording */
 };
 
 #define MESSAGES static const char *messages_txt[] = { \
@@ -383,7 +382,6 @@ enum { /* messages between entities */
        "MESSAGE_VBOX_TONE", \
        "MESSAGE_TONE_COUNTER", \
        "MESSAGE_TONE_EOF", \
-       "MESSAGE_VBOX_RECORD", \
 };
 
 
index a3a33c8..0c043df 100644 (file)
--- a/port.cpp
+++ b/port.cpp
@@ -141,7 +141,8 @@ Port::Port(int type, char *portname, struct port_settings *settings)
        }
        SCPY(p_name, portname);
        SCPY(p_tone_dir, p_settings.tones_dir); // just to be sure
-       p_clock = 0;
+       p_last_tv_sec = 0;
+       p_last_tv_msec = 0;
        p_type = type;
        p_serial = port_serial++;
        p_debug_nothingtosend = 0;
@@ -474,6 +475,7 @@ void Port::set_vbox_speed(int speed)
 
 /*
  * read from the given file as specified in port_set_tone and return sample data
+ * silence is appended if sample ends, but only the number of samples with tones are returned
  */
 int Port::read_audio(unsigned char *buffer, int length)
 {
@@ -636,7 +638,15 @@ try_loop:
        goto read_more;
 
 done:
-       return(length);
+       return(length-len);
+}
+
+
+/*
+ * dummy for transmit function, since this must be inherited
+ */
+void Port::transmit(unsigned char *buffer, int length, int tonelength)
+{
 }
 
 
@@ -644,8 +654,6 @@ done:
  * process transmission clock */
 int Port::handler(void)
 {
-       port
-
        return(0);
 }
 
diff --git a/port.h b/port.h
index bb93479..6e29653 100644 (file)
--- a/port.h
+++ b/port.h
@@ -143,7 +143,8 @@ class Port
        virtual int message_epoint(unsigned long epoint_id, int message, union parameter *param);
        virtual void set_echotest(int echotest);
        virtual void set_tone(char *dir, char *name);
-       virtual int read_audio(unsigned char *buffer, int length, int compressed);
+       virtual int read_audio(unsigned char *buffer, int length);
+       virtual void transmit(unsigned char *buffer, int length);
 
        struct port_settings p_settings;
        
index a059898..a1f371a 100644 (file)
--- a/vbox.cpp
+++ b/vbox.cpp
@@ -62,7 +62,7 @@ int VBoxPort::handler(void)
 {
        struct message  *message;
        unsigned long   tosend;
-       signed short    buffer[128];
+       unsigned char   buffer[ISDN_TRANSMIT<<3];
        time_t          currenttime;
        class Endpoint  *epoint;
        int             ret;
@@ -91,88 +91,82 @@ int VBoxPort::handler(void)
                }
        }
 
+       /* set time the first time */
        if (p_vbox_audio_start < 1)
        {
-               /* set time the first time */
                p_vbox_audio_start = now_d;
-       } else
-       {
-               /* calculate the number of bytes */
-               tosend = (unsigned long)((now_d-p_vbox_audio_start)*8000) - p_vbox_audio_transferred;
-
-               /* wait for more */
-               if (tosend < 32)
-                       return(Port::handler());
-
-               /* too many samples, so we just process 128 bytes until the next call of handler() */
-               if (tosend > 128)
-                       tosend = 128;
+               return(0);
+       }
+       
+       /* calculate the number of bytes */
+       tosend = (unsigned long)((now_d-p_vbox_audio_start)*8000) - p_vbox_audio_transferred;
 
-               /* dummy read, to clock record buffer */
-               read_audio((unsigned char *)buffer, tosend, 0);
+       /* wait for more */
+       if (tosend < sizeof(buffer))
+               return(0);
+       tosend = sizeof(buffer);
 
-               /* add the number of samples elapsed */
-               p_vbox_audio_transferred += tosend;
+       /* add the number of samples elapsed */
+       p_vbox_audio_transferred += tosend;
 
-               /* if announcement is currently played, send audio data */
-               if (p_vbox_announce_fh >=0)
+       /* if announcement is currently played, send audio data */
+       if (p_vbox_announce_fh >=0)
+       {
+               tosend = read_tone(p_vbox_announce_fh, buffer, p_vbox_announce_codec, tosend, p_vbox_announce_size, &p_vbox_announce_left, 1);
+               if (tosend <= 0)
                {
-                       tosend = read_tone(p_vbox_announce_fh, buffer, p_vbox_announce_codec, tosend, p_vbox_announce_size, &p_vbox_announce_left, 1);
-                       if (tosend <= 0)
-                       {
-                               /* end of file */
-                               close(p_vbox_announce_fh);
-                               p_vbox_announce_fh = -1;
-                               fhuse--;
+                       /* end of file */
+                       close(p_vbox_announce_fh);
+                       p_vbox_announce_fh = -1;
+                       fhuse--;
 
-                               time(&currenttime);
-                               p_vbox_record_start = currenttime;
+                       time(&currenttime);
+                       p_vbox_record_start = currenttime;
 
-                               /* connect if not already */
-                               epoint = find_epoint_id(ACTIVE_EPOINT(p_epointlist));
-                               if (epoint)
-                               {
-                                       /* if we sent our announcement during ringing, we must now connect */
-                                       if (p_vbox_apppbx->e_ext.vbox_free)
-                                       {
-                                               /* send connect message */
-                                               message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CONNECT);
-                                               memcpy(&message->param.connectinfo, &p_connectinfo, sizeof(struct connect_info));
-                                               message_put(message);
-                                               new_state(PORT_STATE_CONNECT);
-                                       }
-                               }
-
-                               /* start recording, if not already */
-                               if (p_vbox_mode == VBOX_MODE_NORMAL)
-                               {
-                                       /* send recording start message */
-                                       message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_VBOX_RECORD);
-                                       message_put(message);
-                               } else // else!!
-                               if (p_vbox_mode == VBOX_MODE_ANNOUNCEMENT)
+                       /* connect if not already */
+                       epoint = find_epoint_id(ACTIVE_EPOINT(p_epointlist));
+                       if (epoint)
+                       {
+                               /* if we sent our announcement during ringing, we must now connect */
+                               if (p_vbox_ext.vbox_free)
                                {
-                                       /* send release */
-                                       message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_RELEASE);
-                                       message->param.disconnectinfo.cause = 16;
-                                       message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
+                                       /* send connect message */
+                                       message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CONNECT);
+                                       memcpy(&message->param.connectinfo, &p_connectinfo, sizeof(struct connect_info));
                                        message_put(message);
-                                       /* recording is close during destruction */
-                                       delete this;
-                                       return(-1); /* must return because port is gone */
+                                       new_state(PORT_STATE_CONNECT);
                                }
-                       } else
+                       }
+
+                       /* start recording, if not already */
+                       if (p_vbox_mode == VBOX_MODE_NORMAL)
                        {
-                               message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DATA);
-                               message->param.data.port_type = p_type;
-                               message->param.data.port_id = p_serial;
-                               message->param.data.len = tosend;
-                               memcpy(message->param.data.data, buffer, tosend);
+                               /* send recording start message */
+                               message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_VBOX_RECORD);
                                message_put(message);
+                       } else // else!!
+                       if (p_vbox_mode == VBOX_MODE_ANNOUNCEMENT)
+                       {
+                               /* send release */
+                               message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_RELEASE);
+                               message->param.disconnectinfo.cause = 16;
+                               message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
+                               message_put(message);
+                               /* recording is close during destruction */
+                               delete this;
+                               return(-1); /* must return because port is gone */
                        }
+               } else
+               {
+                       message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DATA);
+                       message->param.data.port_type = p_type;
+                       message->param.data.port_id = p_serial;
+                       message->param.data.len = tosend;
+                       memcpy(message->param.data.data, buffer, tosend);
+                       message_put(message);
                }
-
        }
+
         return(1);
 }
 
@@ -229,19 +223,18 @@ int VBoxPort::message_epoint(unsigned long epoint_id, int message_id, union para
 
                case MESSAGE_SETUP: /* dial-out command received from epoint, answer with connect */
                /* get apppbx */
-               eapp = (class EndpointAppPBX *)(epoint->ep_app);
-               p_vbox_apppbx = eapp;
+               memcpy(&p_vbox_ext, ((class EndpointAppPBX *)(epoint->ep_app))->e_ext, sizeof(p_vbox_ext));
                /* extract optional announcement file */
                if ((c = strchr(param->setup.dialinginfo.number, ',')))
                {
                        if (c[1] == '/')
                                SPRINT(filename, c+1);
                        else
-                               SPRINT(filename, "%s/%s/%s/vbox/%s", INSTALL_DATA, options.extensions_dir, p_vbox_apppbx->e_terminal);
+                               SPRINT(filename, "%s/%s/%s/vbox/%s", INSTALL_DATA, options.extensions_dir, p_vbox_ext.number);
                        *c = '\0';
                } else
                {
-                       SPRINT(filename, "%s/%s/%s/vbox/announcement", INSTALL_DATA, options.extensions_dir, p_vbox_apppbx->e_terminal);
+                       SPRINT(filename, "%s/%s/%s/vbox/announcement", INSTALL_DATA, options.extensions_dir, p_vbox_ext.number);
                }
                PDEBUG(DEBUG_VBOX, "PORT(%s) vbox port received setup from '%s' to '%s'\n", p_name, param->setup.callerinfo.id, param->setup.dialinginfo.number);
                memcpy(&p_callerinfo, &param->setup.callerinfo, sizeof(p_callerinfo));
@@ -268,7 +261,7 @@ int VBoxPort::message_epoint(unsigned long epoint_id, int message_id, union para
                p_connectinfo.screen = INFO_SCREEN_NETWORK;
 
                /* connect unless we can send announcement while ringing */
-               if (!p_vbox_apppbx->e_ext.vbox_free)
+               if (!p_vbox_ext.vbox_free)
                {
                        /* send connect message */
                        message = message_create(p_serial, epoint_id, PORT_TO_EPOINT, MESSAGE_CONNECT);
@@ -285,24 +278,18 @@ int VBoxPort::message_epoint(unsigned long epoint_id, int message_id, union para
 
                /* start recording during announcement */
                /* start parallel recording if desired */
-               p_vbox_mode = p_vbox_apppbx->e_ext.vbox_mode;
-               p_vbox_record_limit = p_vbox_apppbx->e_ext.vbox_time;
-               if (p_vbox_mode == VBOX_MODE_PARALLEL)
-               {
-                       /* send recording start message */
-                       message = message_create(p_serial, epoint_id, PORT_TO_EPOINT, MESSAGE_VBOX_RECORD);
-                       message_put(message);
-               }
+               p_vbox_mode = p_vbox_ext.vbox_mode;
+               p_vbox_record_limit = p_vbox_ext.vbox_time;
                /* play the announcement */
                if ((p_vbox_announce_fh = open_tone(filename, &p_vbox_announce_codec, &p_vbox_announce_size, &p_vbox_announce_left)) >= 0)
                {
                        fhuse++;
-               } else
+               } 
+               if (!p_vbox_announce_fh || p_vbox_mode==VBOX_MODE_PARALLEL)
                {
-                       PDEBUG(DEBUG_VBOX, "PORT(%s) no announcement found at: '%s' so we start recording now.\n", p_name, filename);
-                       /* send recording start message */
-                       message = message_create(p_serial, epoint_id, PORT_TO_EPOINT, MESSAGE_VBOX_RECORD);
-                       message_put(message);
+                       PDEBUG(DEBUG_VBOX, "PORT(%s) parallel mode OR no announcement found at: '%s' so we start recording now.\n", p_name, filename);
+                       /* recording start */
+                       open_record(p_vbox_ext.vbox_codec, 2, 0, p_vbox_ext.number, p_vbox_ext.anon_ignore, p_vbox_ext.vbox_email, p_vbox_ext.vbox_email_file);
                }
                break;