Vishal Phirke wrote:
Hi Ben,

Great work..I would definitely love to integrate your patches. I know media
part is very weak as of now and any effort to improve it is more than
welcome.

To answer your question,  the file ooh323c/src/ooh245.c is the one which
generates the random numbers. The actual function used is
"ooGenerateStatusDeterminationNumber".  It didn't use host name for
randomization. But I now improved it to use process pid to add
randomization. Hopefully this will solve your problem.

Probably so..the problem appears to be that I was starting both phones
within 1 second of each other, so the srand(time(NULL)) was setting to
the same time.  I hacked it up to use the tv_usec clock instead and that
fixed my problem.  The pid should also fix it...

Here is my current diff.  Some stuff still needs a little polish
and removal of verbose logging, for instance, but I think it is
solid enough for you to give feedback...  I am currently able to
make calls.  Today, will be working on getting useful stats out of
the rtp headers and general cleanup...


Thanks,
Ben

--
Ben Greear <[EMAIL PROTECTED]>
Candela Technologies Inc  http://www.candelatech.com

diff -u --exclude CVS --recursive ooh323c-0.7.3/media/ooCommon.c ooh323c-0.7.3.ben/media/ooCommon.c
--- ooh323c-0.7.3/media/ooCommon.c	2005-09-08 12:45:20.000000000 -0700
+++ ooh323c-0.7.3.ben/media/ooCommon.c	2005-09-21 16:07:10.000000000 -0700
@@ -75,6 +75,20 @@
    va_end(arglist);
 }
 
+/** Convert to miliseconds */
+unsigned long long oo_tv_to_ms(const struct timeval* tv) {
+   unsigned long long ms = tv->tv_usec / 1000;
+   ms += (unsigned long long)tv->tv_sec * 1000;
+   return ms;
+}
+
+unsigned long long ooGetCurMs() {
+   struct timeval tv;
+   gettimeofday(&tv, NULL);
+   return oo_tv_to_ms(&tv);
+}
+
+
 void ooSleep(int milliseconds)
 {
    struct timeval timeout;
diff -u --exclude CVS --recursive ooh323c-0.7.3/media/ooCommon.h ooh323c-0.7.3.ben/media/ooCommon.h
--- ooh323c-0.7.3/media/ooCommon.h	2005-09-08 12:45:20.000000000 -0700
+++ ooh323c-0.7.3.ben/media/ooCommon.h	2005-09-21 15:34:57.000000000 -0700
@@ -67,6 +67,9 @@
  */
 void ooSleep(int milliseconds);
 
+
+unsigned long long ooGetCurMs(); /* in miliseconds */
+
 /** 
  * @} 
  */
diff -u --exclude CVS --recursive ooh323c-0.7.3/media/oomedialx.c ooh323c-0.7.3.ben/media/oomedialx.c
--- ooh323c-0.7.3/media/oomedialx.c	2005-09-08 12:45:20.000000000 -0700
+++ ooh323c-0.7.3.ben/media/oomedialx.c	2005-09-21 16:03:30.000000000 -0700
@@ -21,6 +21,7 @@
 #include <sys/stat.h>
 
 #include <fcntl.h>
+#include <errno.h>
 #include <sys/ioctl.h>
 #include <linux/soundcard.h>
 #include <pthread.h>
@@ -34,7 +35,8 @@
    ghSoundDevice = open("/dev/dsp", O_RDWR);
    if(ghSoundDevice == -1)
    {
-      OOLOG2(1, "Error: Opening sound device for read/write");
+      OOLOG3(1, "Error: Opening sound device: /dev/dsp for read/write, error: %s",
+             strerror(errno));
       return -1;
    }
    OOLOG2(1, "Audio device open successful");
diff -u --exclude CVS --recursive ooh323c-0.7.3/media/oortp.c ooh323c-0.7.3.ben/media/oortp.c
--- ooh323c-0.7.3/media/oortp.c	2005-09-08 12:45:20.000000000 -0700
+++ ooh323c-0.7.3.ben/media/oortp.c	2005-09-22 00:26:05.000000000 -0700
@@ -16,6 +16,8 @@
 
 #include "oortp.h"
 #include "g711.h"
+#include <errno.h>
+
 #ifdef _WIN32
 #include "ooWave.h"
 #include <time.h>
@@ -27,20 +29,31 @@
 /* Initialize the media plug-in */
 int ooInitializePlugin()
 {
+   return ooInitializePlugin(0, "media.log", NULL);
+}
+
+
+/* Initialize the media plug-in */
+int ooInitializePlugin2(struct OoPluginOptions* options) {
+
+   memcpy(&plugin_options, options, sizeof(plugin_options));
+   
    /* Open the log file for write */
    fpLog = NULL;
-   fpLog = fopen("media.log", "w");
-   if(fpLog == NULL)
-   {
-      printf("\nERROR:Failed to open media.log log file");
+   fpLog = fopen(plugin_options.log_fname, "w");
+   if (fpLog == NULL) {
+      printf("\nERROR:Failed to open %s log file, error: %s",
+             plugin_options.log_fname, strerror(errno));
       return -1;
    }
-   
+
 #ifdef _WIN32 
    OOLOG2(1, "Initializing sockets api");
    ooSocketsInit();
 #else
-   ooOpenAudioDevice();
+   if (!(plugin_options.flags & (1<<OO_PLUGIN_NO_AUDIO))) {
+      ooOpenAudioDevice();
+   }
 #endif
    return 0;
 }
@@ -48,11 +61,16 @@
 /* Create a transmit RTP channel. This creates a UDP socket for transmit 
    and initializes the seqNo, timeStamp and ssrc for transmit session
 */
-int ooCreateTransmitRTPChannel(int* channelId, char * destip, int port)
+int ooCreateTransmitRTPChannel(int* channelId, const char* localIface,
+                               const char* localIp, int localPort,
+                               const char* destip, int port)
 {
    int ret;
-   OOLOG4(1, "StartOf:CreateTransmitRTPChannel:Destination %s:%d", destip, 
-          port);
+   OOIPADDR ipAddr;
+   OOLOG4(1, "StartOf:CreateTransmitRTPChannel:Destination %s:%d",
+          destip, port);
+   OOLOG5(1, "  Local Binding: %s:%s:%d",
+          localIface, localIp, localPort);
 #ifdef _WIN32
    InitializeCriticalSection(&gReadMutex);
 #endif
@@ -69,13 +87,29 @@
    memset(&gXmitChannel, 0, sizeof(struct OORTPChannel));
    strcpy(gXmitChannel.ip, destip);
    gXmitChannel.port = port;
-
+   
    /* Create transmit socket */
-   ret = ooSocketCreateUDP (&(gXmitChannel.sock));
-   if(ret != 0)
-   {
-      OOLOG2(1, "ERROR: Creation of rtp socket failed");
-      return -1;
+   if (rtp_sock < 0) {
+      ret = ooSocketCreateUDP (&rtp_sock);
+      if(ret != 0) {
+         OOLOG2(1, "ERROR: Creation of rtp socket failed");
+         return -1;
+      }
+      rtp_sock_use_count = 1;
+      
+      ret = ooSocketStrToAddr (localIp, &ipAddr);
+      if (ret != 0) {
+         OOLOG2(1, "ERROR: IP address conversion failed");
+         return -1;
+      }
+      ret = ooSocketBind (rtp_sock, localIface, ipAddr, localPort);
+      if (ret != 0) {
+         OOLOG2(1, "ERROR: Socket bind failed");
+         return -1;
+      }
+   }
+   else {
+      rtp_sock_use_count++;
    }
    
 #ifdef _WIN32
@@ -129,12 +163,17 @@
 #ifdef _WIN32
       DeleteCriticalSection(&gReadMutex);
 #endif
-      ret = ooSocketClose(gXmitChannel.sock);
-      if(ret != 0) 
-      {
-         OOLOG2(1, "Warning: Failed to close the xmit RTP socket");
-         return -1;
+      rtp_sock_use_count--;
+      if (rtp_sock_use_count <= 0) {
+         ret = ooSocketClose(rtp_sock);
+         rtp_sock = -1;
+         
+         if(ret != 0) {
+            OOLOG2(1, "Warning: Failed to close the xmit RTP socket");
+            return -1;
+         }
       }
+      
       gXmitChannel.status = OO_CHAN_CLOSE;
    }
    OOLOG2(1, "EndOf:CloseTransmitRTPChannel");
@@ -146,12 +185,13 @@
    will be communicated to the remote endpoint via H.245 signalling
 */
 
-int ooCreateReceiveRTPChannel(int* channelId, char * localip, int localport)
+int ooCreateReceiveRTPChannel(int* channelId, const char* localIface,
+                              const char* localip, int localport)
 {
    int ret;
    OOIPADDR ipAddr;
-   OOLOG4(1, "StartOf:CreateReceiveRTPChannel: local %s:%d", localip, 
-          localport);
+   OOLOG5(1, "StartOf:CreateReceiveRTPChannel: local %s:%s:%d",
+          localIface, localip, localport);
 #ifdef _WIN32
    InitializeCriticalSection(&gPlayMutex);
 #endif
@@ -160,24 +200,29 @@
    gRecvChannel.port = localport;
    
    /* Create receive socket */
-   ret = ooSocketCreateUDP (&(gRecvChannel.sock));
-   if(ret != 0)
-   {
-      OOLOG2(1, "ERROR: Creation of rtp socket failed");
-      return -1;
+   if (rtp_sock < 0) {
+      ret = ooSocketCreateUDP (&rtp_sock);
+      if (ret != 0) {
+         OOLOG2(1, "ERROR: Creation of rtp socket failed");
+         return -1;
+      }
+      rtp_sock_use_count = 1;
+
+      ret = ooSocketStrToAddr (localip, &ipAddr);
+      if(ret != 0) {
+         OOLOG2(1, "ERROR: IP address conversion failed");
+         return -1;
+      }
+      ret = ooSocketBind (rtp_sock, localIface, ipAddr, localport); 
+      if(ret != 0) {
+         OOLOG2(1, "ERROR: Socket bind failed");
+         return -1;
+      }
    }
-   ret = ooSocketStrToAddr (localip, &ipAddr);
-   if(ret != 0)
-   {
-      OOLOG2(1, "ERROR: IP address conversion failed");
-      return -1;
-   }
-   ret = ooSocketBind (gRecvChannel.sock, ipAddr, localport); 
-   if(ret != 0)
-   {
-      OOLOG2(1, "ERROR: Socket bind failed");
-      return -1;
+   else {
+      rtp_sock_use_count++;
    }
+
    /* Initailze seqNo, ssrc and timestamp */
    gRecvChannel.seqNo = 0; 
    /* Assign a random value to synchronization source */
@@ -217,11 +262,14 @@
 #ifdef _WIN32
       DeleteCriticalSection(&gPlayMutex);
 #endif
-      ret = ooSocketClose(gRecvChannel.sock);
-      if(ret != 0)
-      {
-         OOLOG2(1, "Warning: Failed to close the receive RTP socket");
-         return -1;
+      rtp_sock_use_count--;
+      if (rtp_sock_use_count <= 0) {
+         ret = ooSocketClose(rtp_sock);
+         rtp_sock = -1;
+         if(ret != 0) {
+            OOLOG2(1, "Warning: Failed to close the receive RTP socket");
+            return -1;
+         }
       }
       gRecvChannel.status = OO_CHAN_CLOSE;
    }
@@ -241,8 +289,13 @@
       OOLOG2(1,"ERROR:Transmit RTP channel is not open");
       return -1;
    }
+
+   if (filename && filename[0]) {
+      strncpy(plugin_options.wav_tx_filename, filename, sizeof(plugin_options.wav_tx_filename) - 1);
+   }
+   
    /* Open the wave file for read */
-   ret = ooOpenWaveFileForRead(filename);
+   ret = ooOpenWaveFileForRead(plugin_options.wav_tx_filename);
    if( ret < 0)
    {
       OOLOG3(1, "ERROR: Failed to open the %s wave file for read", filename);
@@ -368,7 +421,7 @@
    struct timeval timeout;
    fd_set readfds;
    char buffer[1024]; 
-   OOLOG2(1, "StartOf:ReceiveSpeakerThread");
+   OOLOG2(1, "StartOf:ReceiveSpeakerThread-win");
    gRecvPlayLoop = 1; /* start recv loop */
    while(1)
    {
@@ -378,14 +431,13 @@
          break;
       }
       FD_ZERO(&readfds);
-      FD_SET(gRecvChannel.sock, &readfds);
+      FD_SET(rtp_sock, &readfds);
       timeout.tv_sec = 1;
       timeout.tv_usec = 0;
       /* Check whether there is data for read */
-      ret = ooSocketSelect(gRecvChannel.sock+1, &readfds, 0, 
-                           0, &timeout);
+      ret = ooSocketSelect(rtp_sock + 1, &readfds, 0, 0, &timeout);
 
-      if(FD_ISSET(gRecvChannel.sock, &readfds))
+      if(FD_ISSET(rtp_sock, &readfds))
       {
          pcSndBuf = (char*) malloc(1024);
          if(pcSndBuf == 0)
@@ -393,8 +445,7 @@
             OOLOG2(1, "ERROR: Memalloc for playback buffer failed");
          }
          else{
-            ret = ooSocketRecvFrom (gRecvChannel.sock, buffer, 
-                                    1024, 0, 0);
+            ret = ooSocketRecvFrom (rtp_sock, buffer, 1024, 0, 0);
                         
             /* We have a RTP packet in buffer. Assume that data always begins 
                from 12th octet, since standard RTP header length is 12.
@@ -421,7 +472,7 @@
       OOLOG2(1, "ERROR:Closing Speaker device");
    gRecvThrdHdl = 0;
    ExitThread(0);
-   OOLOG2(1, "EndOf:ReceiveSpeakerThread");
+   OOLOG2(1, "EndOf:ReceiveSpeakerThread-win");
    return 0;
 }
 
@@ -450,17 +501,16 @@
 
       audioDataSize = ooReadWaveFileData(databuf, 480);
 
-      if(audioDataSize>0) /* If any data is read */
-      {
+      if (audioDataSize > 0) {
          DataTxed += audioDataSize;
          /* RTP version = 2, padding = 0, extension = 0, CSRC = 0 */
          sendBuf[0] = 0x80; 
          sendBuf[1] = 0x00; /* RTP Payload type PCM ulaw Need to use #define */
-         if(marker)
-         {
+         if (marker) {
             sendBuf[1] |= 0x80; /* Set marker bit for first packet */
             marker = 0;
          }
+         
          /*packet sequence number*/
          *((short *)(sendBuf + 2)) = ooHTONS((short)gXmitChannel.seqNo);
          /*packet timestamp*/
@@ -479,13 +529,12 @@
          gXmitChannel.timestamp += 480;
          tempBuf = (short*) databuf;
          /* Copy PCM audio data into sendBuf as ulaw audio data*/
-         for(i=0; i<(audioDataSize/2); i++)
-         {
+         for(i=0; i<(audioDataSize/2); i++) {
             sendBuf[12+i] = (unsigned char) linear2ulaw((int)*(tempBuf+i));
          }
          /* transmit rtp packet */
-         ret = ooSocketSendTo(gXmitChannel.sock, sendBuf, 
-                     (audioDataSize/2+12), gXmitChannel.ip, gXmitChannel.port);
+         ret = ooSocketSendTo(rtp_sock, sendBuf, (audioDataSize/2+12),
+                              gXmitChannel.ip, gXmitChannel.port);
          if(ret<0)
          {
             OOLOG2(1, "ERROR: Failed to transmit rtp packet");
@@ -578,7 +627,7 @@
             sendBuf[12+i] = (unsigned char) linear2ulaw((int)*(tempBuf+i));
          }
          /* transmit rtp packet */
-         ret = ooSocketSendTo(gXmitChannel.sock, sendBuf, 
+         ret = ooSocketSendTo(rtp_sock, sendBuf, 
                               (gpWaveHead->pWaveHdr->dwBytesRecorded/2+12), 
                               gXmitChannel.ip, gXmitChannel.port);
          if(ret<0)
@@ -663,9 +712,8 @@
  
  
          /* transmit rtp packet */
-         ret = ooSocketSendTo(gXmitChannel.sock, sendBuf,
-                                    (bytesRead/sizeof(short)+12), 
-                                    gXmitChannel.ip, gXmitChannel.port);
+         ret = ooSocketSendTo(rtp_sock, sendBuf, (bytesRead/sizeof(short)+12), 
+                              gXmitChannel.ip, gXmitChannel.port);
 
          if(ret<0)
          {
@@ -694,51 +742,68 @@
    struct timeval timeout;
    short c;
    fd_set readfds;
-   char buffer[1024]; 
-   OOLOG2(1, "StartOf:ReceiveSpeakerThread");
+   char buffer[1024];
+   int rv;
+   OOLOG2(1, "StartOf:ReceiveSpeakerThreadLnx");
    gRecvPlayLoop = 1; /* start recv loop */
    while(1)
    {
       if(!gRecvPlayLoop)
       {
-         OOLOG2(1, "Exiting from RecvPlay loop ");
+         OOLOG2(1, "Exiting from RecvPlay loop -lnx ");
          break;
       }
       FD_ZERO(&readfds);
-      FD_SET(gRecvChannel.sock, &readfds);
+      FD_SET(rtp_sock, &readfds);
       timeout.tv_sec = 1;
       timeout.tv_usec = 0;
       /* Check whether there is data for read */
-      ret = ooSocketSelect(gRecvChannel.sock+1, &readfds, 0, 
-                           0, &timeout);
+      ret = ooSocketSelect(rtp_sock + 1, &readfds, 0, 0, &timeout);
 
-      if(FD_ISSET(gRecvChannel.sock, &readfds))
-      {
-         ret = ooSocketRecvFrom (gRecvChannel.sock, buffer, 
-                                 1024, 0, 0);
-                        
-         /* We have a RTP packet in buffer. Assume that data always begins 
-            from 12th octet, since standard RTP header length is 12.
-            Convert G711 data to 16 bit PCM.
-         */
-         j = 0;
-         for( i =12; i < ret; i++)
-         {                           
-            psSndBuf[j++] = (short)ulaw2linear((unsigned char)(buffer[i]));
-	    /*c = (short)ulaw2linear((unsigned char)(buffer[i]));
-	     pcSndBuf[j++]= (unsigned char) ((c>>8) & 0xff);
-	     pcSndBuf[j++] = (unsigned char) (c & 0xff);
-            */
+      if (FD_ISSET(rtp_sock, &readfds)) {
+         OOLOG3(1, " About to read from recv socket: %d", rtp_sock);
+         ret = ooSocketRecvFrom (rtp_sock, buffer, 1024, 0, 0);
+         OOLOG3(1, "  Done reading, ret: %d", ret);
+         
+         if (ret > 0) {
+
+            // callback for those interested in rtp packets.
+            rv = 0;
+            if (plugin_options.rtpRxCb) {
+               OOLOG2(1, "Calling rtp rx callback.");
+               rv = plugin_options.rtpRxCb(buffer, ret);
+            }
+            else {
+               OOLOG2(1, "NOT Calling rtp rx callback, was NULL.");
+            }
+            
+            if (rv == 0) {
+               /* We have a RTP packet in buffer. Assume that data always begins 
+                  from 12th octet, since standard RTP header length is 12.
+                  Convert G711 data to 16 bit PCM.
+               */
+               j = 0;
+               for( i =12; i < ret; i++) {
+                  psSndBuf[j++] = (short)ulaw2linear((unsigned char)(buffer[i]));
+                  /*c = (short)ulaw2linear((unsigned char)(buffer[i]));
+                    pcSndBuf[j++]= (unsigned char) ((c>>8) & 0xff);
+                    pcSndBuf[j++] = (unsigned char) (c & 0xff);
+                  */
+               }
+               /* Play the data buffer onto the speaker device*/
+               ooPlayAudioBuffer((char*)psSndBuf, j*sizeof(short));
+               /*        ooPlayAudioBuffer(pcSndBuf, j);*/
+            }
          }
-         /* Play the data buffer onto the speaker device*/
-         ooPlayAudioBuffer((char*)psSndBuf, j*sizeof(short));
-	 /*        ooPlayAudioBuffer(pcSndBuf, j);*/
+      }
+      else {
+         OOLOG3(1, "  Nothing to read according to select, ret: %d", ret);
       }
    }
    
    gRecvThrdHdl = 0;
    pthread_exit(0);   
-   OOLOG2(1, "EndOf:ReceiveSpeakerThread");
+   OOLOG2(1, "EndOf:ReceiveSpeakerThreadLnx");
    return 0;
 }
 
@@ -756,20 +821,41 @@
    unsigned char sendBuf[252]; /* additional 12 bytes for RTP header */
    int marker = 1; /* Only first packet has marker bit set */
    int i;
-   OOLOG2(1, "StartOf:TransmitFileThread");
+
+   int pktIntervalMs = 20;   /* 160-byte pkts == 20ms */
+   int rtpFrameSize = 160;
+   int wavFrameSize = rtpFrameSize * 2; /* Assumes 2-byte wav file samples */
+   unsigned long long next_tx_ms = 0;
+   unsigned long long now = 0;
+   unsigned int loops_to_go = plugin_options.loop_count;
    
+   OOLOG2(1, "StartOf:TransmitFileThread");
+
    gXmitFileLoop = 1;
-   while(1)
-   {
-      if(!gXmitFileLoop)
-         break;
+   while(gXmitFileLoop) {
       /* Number of bytes read is returned and stored in audioDataSize */
 
-      audioDataSize = ooReadWaveFileData(databuf, 480);
+      audioDataSize = ooReadWaveFileData(databuf, wavFrameSize);
+
+      if (audioDataSize > 0) { /* If any data is read */
+
+         now = ooGetCurMs();
+      
+         if (next_tx_ms == 0) {
+            next_tx_ms = now;
+         }
+         else {
+            if (next_tx_ms > now) {
+               /* sleep untill 20ms have elapsed */
+               ooSleep(next_tx_ms - now);
+            }
+            else {
+               next_tx_ms = now; /* already late..go fast as we can! */
+            }
+         }
+         
+         next_tx_ms += pktIntervalMs;
 
-      if(audioDataSize>0) /* If any data is read */
-      {
-         DataTxed += audioDataSize;
          /* RTP version = 2, padding = 0, extension = 0, CSRC = 0 */
          sendBuf[0] = 0x80; 
          sendBuf[1] = 0x00; /* RTP Payload type PCM ulaw Need to use #define */
@@ -793,7 +879,7 @@
          /* Next timestamp is current timestamp + play duration of the 
             current buffer.
          */
-         gXmitChannel.timestamp += 480;
+         gXmitChannel.timestamp += rtpFrameSize;
          tempBuf = (short*) databuf;
          /* Copy PCM audio data into sendBuf as ulaw audio data*/
          for(i=0; i<(audioDataSize/2); i++)
@@ -801,26 +887,55 @@
             sendBuf[12+i] = (unsigned char) linear2ulaw((int)*(tempBuf+i));
          }
          /* transmit rtp packet */
-         ret = ooSocketSendTo(gXmitChannel.sock, sendBuf, 
-                     (audioDataSize/2+12), gXmitChannel.ip, gXmitChannel.port);
-         if(ret<0)
-         {
-            OOLOG2(1, "ERROR: Failed to transmit rtp packet");
-            return -1;
+         ret = ooSocketSendTo(rtp_sock, sendBuf, (audioDataSize/2+12),
+                              gXmitChannel.ip, gXmitChannel.port);
+
+         if (ret<0) {
+            OOLOG3(1, "ERROR: Failed to transmit rtp packet, error: %s",
+                   strerror(errno));
+            if (plugin_options.rtpTxCb) {
+               plugin_options.rtpTxCb(sendBuf, (audioDataSize/2+12), -errno);
+            }
+            break;
+         }
+         else {
+            DataTxed += audioDataSize;
+            if (plugin_options.rtpTxCb) {
+               plugin_options.rtpTxCb(sendBuf, (audioDataSize/2+12), ret);
+            }
          }
-         ooSleep(2);/* Just slows down the transmit rate a bit */
       }
-      else{
-         gXmitFileLoop = 0;
-         OOLOG2(1, "End of file transmission");
+      else {
+         /* TODO:  Allow re-opening the file if we are looping the wav file... */
+         loops_to_go--;
+         if (loops_to_go > 0) {
+            ooCloseWaveFile();
+            ret = ooOpenWaveFileForRead(plugin_options.wav_tx_filename);
+            if (ret < 0) {
+               OOLOG4(1, "ERROR: Failed to open the %s wave file for read, error: %s",
+                      plugin_options.wav_tx_filename, strerror(errno));
+               break;
+            }
+         }
+         else {
+            break;
+         }
       }
    }
+
+   gXmitFileLoop = 0;
+   
+   if (plugin_options.rtpTxCompleteCb) {
+      plugin_options.rtpTxCompleteCb();
+   }
+   
+   OOLOG3(1, "End of file transmission, sent: %d RTP payload bytes.",
+          DataTxed);
+
    /* Close the wave file */
    ret = ooCloseWaveFile();
-   if(ret < 0)
-   {
+   if (ret < 0) {
       OOLOG2(1, "ERROR: Failed to close the open wave file");
-      return -1;
    }
    gXmitThrdHdl = 0;
    pthread_exit(0);   
diff -u --exclude CVS --recursive ooh323c-0.7.3/media/oortp.h ooh323c-0.7.3.ben/media/oortp.h
--- ooh323c-0.7.3/media/oortp.h	2005-09-08 12:45:20.000000000 -0700
+++ ooh323c-0.7.3.ben/media/oortp.h	2005-09-21 23:32:28.000000000 -0700
@@ -26,6 +26,7 @@
 #include <stdio.h>
 #include "ooSock.h"
 #include "ooCommon.h"
+#include "ooShare.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -47,10 +48,12 @@
 #define OO_CHAN_CLOSE 0
 #define OO_CHAN_OPEN  1
 
+/* Only need one socket to send and receive..saves IP ports too */
+OOSOCKET rtp_sock = -1;
+int rtp_sock_use_count = 0;
 
 /* Structure for holding RTP channel information*/
 struct OORTPChannel{
-   OOSOCKET sock;
    char    ip[20];/*Remote ip for transmit channel, local ip for recv channel*/
    int port; /*remote port for xmit chan and local port for recv chan*/
    unsigned short seqNo; /* last SeqNo recv or xmitted */
@@ -75,18 +78,31 @@
  */
 EXTERN int ooInitializePlugin();
 
+
+EXTERN struct OoPluginOptions plugin_options;
+
+/**
+ * Initialize the plugin library, with a few options.
+ */
+EXTERN int ooInitializePlugin2(struct OoPluginOptions* options);
+
 /**
  * This function is invoked to create Transmit RTP channel.
  *
  * @param channelId     Pointer to int for returning the newly created channel
  *                      id. Not used currently as only two channels are 
  *                      supported, 1 xmit channel and 1 recv channel.
+ * @param localIface    Interface name, if set:  will bind to it with SO_BINDTODEVICE
+ * @param localIp       If specified, binds to this for local IP address.
+ * @param localPort     If non-zero, binds to this for local port.
  * @param destip        IP address of the destination endpoint.
  * @param port          RTP receive port number at the destination endpoint.
  *
  * @return              Completion status - 0 on success, -1 on failure
  */
-EXTERN int ooCreateTransmitRTPChannel(int* channelId, char * destip, int port);
+EXTERN int ooCreateTransmitRTPChannel(int* channelId, const char* localIface,
+                                      const char* localIp, int localPort,
+                                      const char * destip, int port);
 
 /**
  * This function is invoked to close the Transmit RTP channel.
@@ -105,13 +121,14 @@
  * @param channelId     Pointer to int for returning the newly created channel
  *                      id. Not used currently as only two channels are 
  *                      supported, 1 xmit channel and 1 recv channel.
+ * @param localIface    Interface name, if set:  will bind to it with SO_BINDTODEVICE
  * @param localip       IP address of the local endpoint.
  * @param localport     RTP receive port number at the local endpoint.
  *
  * @return              Completion status - 0 on success, -1 on failure
  */
-EXTERN int ooCreateReceiveRTPChannel(int* channelId, char* localip, 
-                                     int localport);
+EXTERN int ooCreateReceiveRTPChannel(int* channelId, const char* localIface,
+                                     const char* localip, int localport);
 
 /**
  * This function is invoked to close the Receive RTP channel.
Only in ooh323c-0.7.3.ben/media: ooShare.h
diff -u --exclude CVS --recursive ooh323c-0.7.3/media/ooSock.c ooh323c-0.7.3.ben/media/ooSock.c
--- ooh323c-0.7.3/media/ooSock.c	2005-09-08 12:45:20.000000000 -0700
+++ ooh323c-0.7.3.ben/media/ooSock.c	2005-09-20 20:37:37.000000000 -0700
@@ -16,6 +16,8 @@
 
 #include "ooSock.h"
 #include <stdio.h>
+#include <errno.h>
+
 #if defined(_WIN32_WCE)
 static int inited = 0;
 #define SEND_FLAGS     0
@@ -226,7 +228,7 @@
    return ASN_OK;
 }
 
-int ooSocketBind (OOSOCKET socket, OOIPADDR addr, int port) 
+int ooSocketBind (OOSOCKET socket, const char* localIface, OOIPADDR addr, int port) 
 {
    struct sockaddr_in m_addr;
 
@@ -241,6 +243,16 @@
                      sizeof (m_addr)) == -1)
       return ASN_E_INVSOCKET;
 
+#ifndef __WIN32__
+   if (localIface && localIface[0]) {
+      if (setsockopt(socket, SOL_SOCKET, SO_BINDTODEVICE,
+                     localIface, strlen(localIface) + 1)) {
+         printf("ERROR: Socket SO_BINDTODEVICE failed, not usually fatal, error: %s\n",
+                strerror(errno));
+      }
+   }
+#endif
+   
    return ASN_OK;
 }
 
diff -u --exclude CVS --recursive ooh323c-0.7.3/media/ooSock.h ooh323c-0.7.3.ben/media/ooSock.h
--- ooh323c-0.7.3/media/ooSock.h	2005-09-08 12:45:20.000000000 -0700
+++ ooh323c-0.7.3.ben/media/ooSock.h	2005-09-20 00:26:22.000000000 -0700
@@ -127,12 +127,13 @@
  *
  * @param socket       The socket's handle created by call to ::rtSocketCreate
  *                     function.
+ * @param localIface   Interface name, if set:  will bind to it with SO_BINDTODEVICE
  * @param addr         The local IP address to assign to the socket.
  * @param port         The local port number to assign to the socket.
  * @return             Completion status of operation: 0 (ASN_OK) = success,
  *                     negative return value is error.
  */
-EXTERN int ooSocketBind (OOSOCKET socket, OOIPADDR addr, int port);
+EXTERN int ooSocketBind (OOSOCKET socket, const char* localIface, OOIPADDR addr, int port);
 
 /**
  * This function closes an existing socket.
diff -u --exclude CVS --recursive ooh323c-0.7.3/src/ooCalls.c ooh323c-0.7.3.ben/src/ooCalls.c
--- ooh323c-0.7.3/src/ooCalls.c	2005-09-08 12:45:21.000000000 -0700
+++ ooh323c-0.7.3.ben/src/ooCalls.c	2005-09-20 00:49:05.000000000 -0700
@@ -109,6 +109,7 @@
    call->dtmfmode = gH323ep.dtmfmode;
    call->mediaInfo = NULL;
    strcpy(call->localIP, gH323ep.signallingIP);
+   strcpy(call->localIface, gH323ep.signallingIface);
    call->pH225Channel = NULL;
    call->pH245Channel = NULL;
    call->h245listener = NULL;
diff -u --exclude CVS --recursive ooh323c-0.7.3/src/ooCalls.h ooh323c-0.7.3.ben/src/ooCalls.h
--- ooh323c-0.7.3/src/ooCalls.h	2005-09-08 12:45:21.000000000 -0700
+++ ooh323c-0.7.3.ben/src/ooCalls.h	2005-09-20 00:48:40.000000000 -0700
@@ -140,6 +140,7 @@
    int                  dtmfmode;
    OOMediaInfo          *mediaInfo;
    OOCallFwdData        *pCallFwdData;
+   char                 localIface[20]; /* local Interface for binding */
    char                 localIP[20];/* Local IP address */
    OOH323Channel*	pH225Channel;
    OOH323Channel*	pH245Channel;
diff -u --exclude CVS --recursive ooh323c-0.7.3/src/oochannels.c ooh323c-0.7.3.ben/src/oochannels.c
--- ooh323c-0.7.3/src/oochannels.c	2005-09-08 12:45:21.000000000 -0700
+++ ooh323c-0.7.3.ben/src/oochannels.c	2005-09-20 00:49:13.000000000 -0700
@@ -52,7 +52,7 @@
                   "(%s, %s)\n", call->callType, call->callToken);
       return OO_FAILED;
    }
-   ret = ooBindPort (OOTCP, channelSocket, call->localIP); 
+   ret = ooBindPort (OOTCP, channelSocket, call->localIface, call->localIP); 
    if(ret == OO_FAILED)
    {
       OOTRACEERR3("Error:Unable to bind to a TCP port - H245 listener creation"
@@ -100,7 +100,7 @@
          bind socket to a port before connecting. Thus avoiding
          implicit bind done by a connect call.
       */
-      ret = ooBindPort(OOTCP, channelSocket, call->localIP); 
+      ret = ooBindPort(OOTCP, channelSocket, call->localIface, call->localIP); 
       if(ret == OO_FAILED)
       {
          OOTRACEERR3("Error:Unable to bind to a TCP port - h245 connection "
@@ -254,9 +254,9 @@
          to any random port.
       */
 #ifndef _WIN32
-      ret = ooBindPort(OOTCP,channelSocket, call->localIP); 
+      ret = ooBindPort(OOTCP,channelSocket, call->localIface, call->localIP); 
 #else
-      ret = ooBindOSAllocatedPort(channelSocket, call->localIP);
+      ret = ooBindOSAllocatedPort(channelSocket, call->localIface, call->localIP);
 #endif
       
       if(ret == OO_FAILED)
@@ -361,7 +361,7 @@
       return OO_FAILED;
    }
    ret= ooSocketStrToAddr (gH323ep.signallingIP, &ipaddrs);
-   if((ret=ooSocketBind (channelSocket, ipaddrs, 
+   if((ret=ooSocketBind (channelSocket, gH323ep.signallingIface, ipaddrs, 
                          gH323ep.listenPort))==ASN_OK) 
    {
       gH323ep.listener = (OOSOCKET*)memAlloc(&gH323ep.ctxt,sizeof(OOSOCKET));
diff -u --exclude CVS --recursive ooh323c-0.7.3/src/ooGkClient.c ooh323c-0.7.3.ben/src/ooGkClient.c
--- ooh323c-0.7.3/src/ooGkClient.c	2005-09-08 12:45:21.000000000 -0700
+++ ooh323c-0.7.3.ben/src/ooGkClient.c	2005-09-20 00:44:45.000000000 -0700
@@ -65,6 +65,8 @@
    pGkClient->grqRetries = 0;
 
    strcpy(pGkClient->localRASIP, gH323ep.signallingIP);
+   strcpy(pGkClient->localIface, gH323ep.signallingIface);
+   
 #ifndef _WIN32
    if(!strcmp(pGkClient->localRASIP, "0.0.0.0") ||
       !strcmp(pGkClient->localRASIP, "127.0.0.1"))
@@ -257,7 +259,7 @@
    if(pGkClient->localRASPort)
    {
       ret= ooSocketStrToAddr (pGkClient->localRASIP, &ipaddrs);
-      if( (ret=ooSocketBind( pGkClient->rasSocket, ipaddrs, 
+      if( (ret=ooSocketBind( pGkClient->rasSocket, pGkClient->localIface, ipaddrs, 
            pGkClient->localRASPort))!=ASN_OK ) 
       {
          OOTRACEERR1("ERROR:Failed to create RAS channel\n");
@@ -266,7 +268,7 @@
       }
    }
    else {
-      ret = ooBindPort (OOUDP, pGkClient->rasSocket, pGkClient->localRASIP);
+      ret = ooBindPort (OOUDP, pGkClient->rasSocket, pGkClient->localIface, pGkClient->localRASIP);
       if(ret == OO_FAILED)
       {
          OOTRACEERR1("ERROR: Failed to bind port to RAS socket\n");
diff -u --exclude CVS --recursive ooh323c-0.7.3/src/ooGkClient.h ooh323c-0.7.3.ben/src/ooGkClient.h
--- ooh323c-0.7.3/src/ooGkClient.h	2005-09-08 12:45:21.000000000 -0700
+++ ooh323c-0.7.3.ben/src/ooGkClient.h	2005-09-20 00:40:56.000000000 -0700
@@ -181,6 +181,7 @@
    OOCTXT msgCtxt;
    OOSOCKET rasSocket;
    int localRASPort;
+   char localIface[20];
    char localRASIP[20];
    char gkRasIP[20];
    char gkCallSignallingIP[20];
diff -u --exclude CVS --recursive ooh323c-0.7.3/src/ooh245.c ooh323c-0.7.3.ben/src/ooh245.c
--- ooh323c-0.7.3/src/ooh245.c	2005-09-08 12:45:21.000000000 -0700
+++ ooh323c-0.7.3.ben/src/ooh245.c	2005-09-21 20:58:11.000000000 -0700
@@ -659,9 +659,14 @@
 {
    ASN1UINT statusDeterminationNumber;
    ASN1UINT random_factor = (ASN1UINT)rand();
-
-   srand((unsigned)time( NULL )+random_factor );
-   statusDeterminationNumber = rand()%16777215;
+   /* Use low bits of the time...otherwise two programs that start
+    * at the same second collide! --Ben
+    */
+   //srand((unsigned)time( NULL )+random_factor );
+   struct timeval tv;
+   gettimeofday(&tv, NULL);
+   srand((tv.tv_usec ^ tv.tv_sec) + random_factor);
+   statusDeterminationNumber = rand() % 16777215;
    return statusDeterminationNumber;
 }
 /* TODO: Should Send MasterSlave Release when no response from 
diff -u --exclude CVS --recursive ooh323c-0.7.3/src/ooh323ep.c ooh323c-0.7.3.ben/src/ooh323ep.c
--- ooh323c-0.7.3/src/ooh323ep.c	2005-09-08 12:45:21.000000000 -0700
+++ ooh323c-0.7.3.ben/src/ooh323ep.c	2005-09-19 23:54:54.000000000 -0700
@@ -155,12 +155,17 @@
    return OO_OK;
 }
 
-int ooH323EpSetLocalAddress(char * localip, int listenport)
-{
+int ooH323EpSetLocalBinding(const char* ifname, const char * localip, int listenport) {
+   if (ifname) {
+      memset(gH323ep.signallingIface, 0, sizeof(gH323ep.signallingIface));
+      strncpy(gH323ep.signallingIface, ifname, sizeof(gH323ep.signallingIface) - 1);
+      OOTRACEINFO2("Signalling Interface is set to %s\n", ifname);
+   }
+   
    if(localip)
    {
       memset(gH323ep.signallingIP, 0, sizeof(gH323ep.signallingIP));
-      strcpy(gH323ep.signallingIP, localip);
+      strncpy(gH323ep.signallingIP, localip, sizeof(gH323ep.signallingIP) - 1);
       OOTRACEINFO2("Signalling IP address is set to %s\n", localip);
    }
    
@@ -172,6 +177,11 @@
    return OO_OK;
 }
 
+int ooH323EpSetLocalAddress(const char * localip, int listenport)
+{
+   return  ooH323EpSetLocalBinding(NULL, localip, listenport);
+}
+
 int ooH323EpAddAliasH323ID(char *h323id)
 {
    ooAliases * psNewAlias=NULL;
diff -u --exclude CVS --recursive ooh323c-0.7.3/src/ooh323ep.h ooh323c-0.7.3.ben/src/ooh323ep.h
--- ooh323c-0.7.3/src/ooh323ep.h	2005-09-08 12:45:21.000000000 -0700
+++ ooh323c-0.7.3.ben/src/ooh323ep.h	2005-09-20 22:57:46.000000000 -0700
@@ -128,6 +128,7 @@
    int noOfCaps;
    OOH225MsgCallbacks h225Callbacks;
    OOH323CALLBACKS h323Callbacks;
+   char signallingIface[20];
    char signallingIP[20];
    int listenPort;
    OOSOCKET *listener;
@@ -169,7 +170,8 @@
  *
  * @return               OO_OK, on success. OO_FAILED, on failure.
  */ 
-EXTERN int ooH323EpSetLocalAddress(char * localip, int listenport);
+EXTERN int ooH323EpSetLocalBinding(const char* ifname, const char * localip, int listenport);
+EXTERN int ooH323EpSetLocalAddress(const char * localip, int listenport);
 
 /**
  * This function is used to set the range of tcp ports the application will
diff -u --exclude CVS --recursive ooh323c-0.7.3/src/ooports.c ooh323c-0.7.3.ben/src/ooports.c
--- ooh323c-0.7.3/src/ooports.c	2005-09-08 12:45:23.000000000 -0700
+++ ooh323c-0.7.3.ben/src/ooports.c	2005-09-20 00:46:01.000000000 -0700
@@ -58,7 +58,7 @@
    return OO_FAILED;
 }
 
-int ooBindPort (OOH323PortType type, OOSOCKET socket, char *ip)
+int ooBindPort (OOH323PortType type, OOSOCKET socket, const char* localIface, const char *ip)
 {
    int initialPort, bindPort, ret;
    OOIPADDR ipAddrs;
@@ -70,7 +70,7 @@
 
    while(1)
    {
-      if((ret=ooSocketBind(socket, ipAddrs, bindPort))==0)
+      if((ret=ooSocketBind(socket, localIface, ipAddrs, bindPort))==0)
       {
 	 return bindPort;
       }
diff -u --exclude CVS --recursive ooh323c-0.7.3/src/ooports.h ooh323c-0.7.3.ben/src/ooports.h
--- ooh323c-0.7.3/src/ooports.h	2005-09-08 12:45:23.000000000 -0700
+++ ooh323c-0.7.3.ben/src/ooports.h	2005-09-20 00:46:05.000000000 -0700
@@ -60,13 +60,14 @@
  * @param ep        Reference to H323 Endpoint structure.
  * @param type      Type of the port required for the socket.
  * @param socket    The socket to be bound.
+ * @param localIface   Interface name, if set:  will bind to it with SO_BINDTODEVICE
  * @param ip        Dotted Ip address to bind to.
  *
  * @return          In case of success returns the port number to which
  *                  socket is bound and in case of failure just returns
  *                  a negative value.
 */
-EXTERN int ooBindPort (OOH323PortType type, OOSOCKET socket, char *ip);
+   EXTERN int ooBindPort (OOH323PortType type, OOSOCKET socket, const char* localIface, const char *ip);
 
 /**
  * This function is supported for windows version only. 
diff -u --exclude CVS --recursive ooh323c-0.7.3/src/ooSocket.c ooh323c-0.7.3.ben/src/ooSocket.c
--- ooh323c-0.7.3/src/ooSocket.c	2005-09-08 12:45:23.000000000 -0700
+++ ooh323c-0.7.3.ben/src/ooSocket.c	2005-09-20 00:49:35.000000000 -0700
@@ -252,7 +252,7 @@
    return ASN_OK;
 }
 
-int ooSocketBind (OOSOCKET socket, OOIPADDR addr, int port) 
+int ooSocketBind (OOSOCKET socket, const char* localIface, OOIPADDR addr, int port) 
 {
    struct sockaddr_in m_addr;
 
@@ -275,6 +275,15 @@
       return ASN_E_INVSOCKET;
    }
 
+#ifndef __WIN32__
+   if (localIface && localIface[0]) {
+      if (setsockopt(socket, SOL_SOCKET, SO_BINDTODEVICE,
+                     localIface, strlen(localIface) + 1)) {
+         OOTRACEERR1("ERROR: Socket SO_BINDTODEVICE failed, not usually fatal.");
+      }
+   }
+#endif
+   
    return ASN_OK;
 }
 
diff -u --exclude CVS --recursive ooh323c-0.7.3/src/ooSocket.h ooh323c-0.7.3.ben/src/ooSocket.h
--- ooh323c-0.7.3/src/ooSocket.h	2005-09-08 12:45:23.000000000 -0700
+++ ooh323c-0.7.3.ben/src/ooSocket.h	2005-09-20 00:37:52.000000000 -0700
@@ -134,12 +134,13 @@
  *
  * @param socket       The socket's handle created by call to ::rtSocketCreate
  *                     function.
+ * @param localIface   Interface name, if set:  will bind to it with SO_BINDTODEVICE
  * @param addr         The local IP address to assign to the socket.
  * @param port         The local port number to assign to the socket.
  * @return             Completion status of operation: 0 (ASN_OK) = success,
  *                     negative return value is error.
  */
-EXTERN int ooSocketBind (OOSOCKET socket, OOIPADDR addr, int port);
+EXTERN int ooSocketBind (OOSOCKET socket, const char* localIface, OOIPADDR addr, int port);
 
 /**
  * This function closes an existing socket.

Reply via email to