Sane FreeBSD patch
[asterisk/asterisk.git] / apps / app_intercom.c
index cf078b7..4c2379c 100755 (executable)
@@ -3,7 +3,7 @@
  *
  * Use /dev/dsp as an intercom.
  * 
- * Copyright (C) 1999, Adtran Inc. and Linux Support Services, LLC
+ * Copyright (C) 1999, Mark Spencer
  *
  * Mark Spencer <markster@linux-support.net>
  *
@@ -11,6 +11,7 @@
  * the GNU General Public License
  */
  
+#include <asterisk/lock.h>
 #include <asterisk/file.h>
 #include <asterisk/frame.h>
 #include <asterisk/logger.h>
 #include <stdlib.h>
 #include <pthread.h>
 #include <sys/time.h>
+#ifdef __linux__
 #include <linux/soundcard.h>
+#elif defined(__FreeBSD__)
+#include <machine/soundcard.h>
+#else
+#include <soundcard.h>
+#endif
 #include <netinet/in.h>
 
 #define DEV_DSP "/dev/dsp"
@@ -37,34 +44,40 @@ static char *tdesc = "Intercom using /dev/dsp for output";
 
 static char *app = "Intercom";
 
+static char *synopsis = "(Obsolete) Send to Intercom";
+static char *descrip = 
+"  Intercom(): Sends the user to the intercom (i.e. /dev/dsp).  This program\n"
+"is generally considered  obselete by the chan_oss module.  Returns 0 if the\n"
+"user exits with a DTMF tone, or -1 if they hangup.\n";
+
 STANDARD_LOCAL_USER;
 
 LOCAL_USER_DECL;
 
-static pthread_mutex_t sound_lock = PTHREAD_MUTEX_INITIALIZER;
+static ast_mutex_t sound_lock = AST_MUTEX_INITIALIZER;
 static int sound = -1;
 
 static int write_audio(short *data, int len)
 {
        int res;
        struct audio_buf_info info;
-       pthread_mutex_lock(&sound_lock);
+       ast_mutex_lock(&sound_lock);
        if (sound < 0) {
                ast_log(LOG_WARNING, "Sound device closed?\n");
-               pthread_mutex_unlock(&sound_lock);
+               ast_mutex_unlock(&sound_lock);
                return -1;
        }
     if (ioctl(sound, SNDCTL_DSP_GETOSPACE, &info)) {
                ast_log(LOG_WARNING, "Unable to read output space\n");
-               pthread_mutex_unlock(&sound_lock);
+               ast_mutex_unlock(&sound_lock);
         return -1;
     }
-               res = write(sound, data, len);
-       pthread_mutex_unlock(&sound_lock);
+       res = write(sound, data, len);
+       ast_mutex_unlock(&sound_lock);
        return res;
 }
 
-static int create_audio()
+static int create_audio(void)
 {
        int fmt, desired, res, fd;
        fd = open(DEV_DSP, O_WRONLY);
@@ -97,7 +110,7 @@ static int create_audio()
                return -1;
        }
        if (fmt != desired) {
-               ast_log(LOG_WARNING, "Requested %d Hz, got %d Hz -- sound may be choppy\n");
+               ast_log(LOG_WARNING, "Requested %d Hz, got %d Hz -- sound may be choppy\n", desired, fmt);
        }
 #if 1
        /* 2 bytes * 15 units of 2^5 = 32 bytes per buffer */
@@ -116,48 +129,44 @@ static int intercom_exec(struct ast_channel *chan, void *data)
        int res = 0;
        struct localuser *u;
        struct ast_frame *f;
-       struct ast_channel *trans;
-       if (!data) {
-               ast_log(LOG_WARNING, "Playback requires an argument (filename)\n");
+       int oreadformat;
+       LOCAL_USER_ADD(u);
+       /* Remember original read format */
+       oreadformat = chan->readformat;
+       /* Set mode to signed linear */
+       res = ast_set_read_format(chan, AST_FORMAT_SLINEAR);
+       if (res < 0) {
+               ast_log(LOG_WARNING, "Unable to set format to signed linear on channel %s\n", chan->name);
                return -1;
        }
-       LOCAL_USER_ADD(u);
-       /* See if we need a translator */
-       if (!(chan->format & AST_FORMAT_SLINEAR)) 
-               trans = ast_translator_create(chan, AST_FORMAT_SLINEAR, AST_DIRECTION_IN);
-       else
-               trans = chan;
-       if (trans) {
-               /* Read packets from the channel */
-               while(!res) {
-                       res = ast_waitfor(trans, -1);
-                       if (res > 0) {
-                               res = 0;
-                               f = ast_read(trans);
-                               if (f) {
-                                       if (f->frametype == AST_FRAME_DTMF) {
-                                               ast_frfree(f);
-                                               break;
-                                       } else {
-                                               if (f->frametype == AST_FRAME_VOICE) {
-                                                       if (f->subclass == AST_FORMAT_SLINEAR) {
-                                                               res = write_audio(f->data, f->datalen);
-                                                               if (res > 0)
-                                                                       res = 0;
-                                                       } else
-                                                               ast_log(LOG_DEBUG, "Unable to handle non-signed linear frame (%d)\n", f->subclass);
-                                               }
-                                       }
+       /* Read packets from the channel */
+       while(!res) {
+               res = ast_waitfor(chan, -1);
+               if (res > 0) {
+                       res = 0;
+                       f = ast_read(chan);
+                       if (f) {
+                               if (f->frametype == AST_FRAME_DTMF) {
                                        ast_frfree(f);
-                               } else
-                                       res = -1;
-                       }
+                                       break;
+                               } else {
+                                       if (f->frametype == AST_FRAME_VOICE) {
+                                               if (f->subclass == AST_FORMAT_SLINEAR) {
+                                                       res = write_audio(f->data, f->datalen);
+                                                       if (res > 0)
+                                                               res = 0;
+                                               } else
+                                                       ast_log(LOG_DEBUG, "Unable to handle non-signed linear frame (%d)\n", f->subclass);
+                                       } 
+                               }
+                               ast_frfree(f);
+                       } else
+                               res = -1;
                }
-               if (trans != chan)
-                       ast_translator_destroy(trans);
-       } else
-               ast_log(LOG_WARNING, "Unable to build translator to signed linear format on '%s'\n", chan->name);
+       }
        LOCAL_USER_REMOVE(u);
+       if (!res)
+               ast_set_read_format(chan, oreadformat);
        return res;
 }
 
@@ -173,7 +182,7 @@ int load_module(void)
 {
        if (create_audio())
                return -1;
-       return ast_register_application(app, intercom_exec);
+       return ast_register_application(app, intercom_exec, synopsis, descrip);
 }
 
 char *description(void)
@@ -187,3 +196,8 @@ int usecount(void)
        STANDARD_USECOUNT(res);
        return res;
 }
+
+char *key()
+{
+       return ASTERISK_GPL_KEY;
+}