Merge Mahmut's recording patches
[asterisk/asterisk.git] / channel.c
index 9a4d2de..f1ea7f7 100755 (executable)
--- a/channel.c
+++ b/channel.c
@@ -33,6 +33,7 @@
 #include <asterisk/chanvars.h>
 #include <asterisk/linkedlists.h>
 #include <asterisk/indications.h>
 #include <asterisk/chanvars.h>
 #include <asterisk/linkedlists.h>
 #include <asterisk/indications.h>
+#include <asterisk/monitor.h>
 
 
 static int shutting_down = 0;
 
 
 static int shutting_down = 0;
@@ -347,7 +348,8 @@ int ast_queue_frame(struct ast_channel *chan, struct ast_frame *fin, int lock)
                cur = cur->next;
                qlen++;
        }
                cur = cur->next;
                qlen++;
        }
-       if (qlen  > 128) {
+       /* Allow up to 96 voice frames outstanding, and up to 128 total frames */
+       if (((fin->frametype == AST_FRAME_VOICE) && (qlen > 96)) || (qlen  > 128)) {
                if (fin->frametype != AST_FRAME_VOICE) {
                        ast_log(LOG_WARNING, "Exceptionally long queue length queuing to %s\n", chan->name);
                        CRASH;
                if (fin->frametype != AST_FRAME_VOICE) {
                        ast_log(LOG_WARNING, "Exceptionally long queue length queuing to %s\n", chan->name);
                        CRASH;
@@ -487,6 +489,10 @@ void ast_channel_free(struct ast_channel *chan)
                ast_log(LOG_WARNING, "Unable to find channel in list\n");
        if (chan->pvt->pvt)
                ast_log(LOG_WARNING, "Channel '%s' may not have been hung up properly\n", chan->name);
                ast_log(LOG_WARNING, "Unable to find channel in list\n");
        if (chan->pvt->pvt)
                ast_log(LOG_WARNING, "Channel '%s' may not have been hung up properly\n", chan->name);
+       /* Stop monitoring */
+       if (chan->monitor) {
+               chan->monitor->stop( chan, 0 );
+       }
        /* Free translatosr */
        if (chan->pvt->readtrans)
                ast_translator_free_path(chan->pvt->readtrans);
        /* Free translatosr */
        if (chan->pvt->readtrans)
                ast_translator_free_path(chan->pvt->readtrans);
@@ -1026,6 +1032,10 @@ struct ast_frame *ast_read(struct ast_channel *chan)
                /* Answer the CDR */
                ast_setstate(chan, AST_STATE_UP);
                ast_cdr_answer(chan->cdr);
                /* Answer the CDR */
                ast_setstate(chan, AST_STATE_UP);
                ast_cdr_answer(chan->cdr);
+       } else if( ( f->frametype == AST_FRAME_VOICE ) && chan->monitor && chan->monitor->read_stream ) {
+               if( ast_writestream( chan->monitor->read_stream, f ) < 0 ) {
+                       ast_log(LOG_WARNING, "Failed to write data to channel monitor read stream\n");
+               }
        }
        pthread_mutex_unlock(&chan->lock);
 
        }
        pthread_mutex_unlock(&chan->lock);
 
@@ -1080,7 +1090,7 @@ int ast_indicate(struct ast_channel *chan, int condition)
                        }
                        if (ts && ts->data[0]) {
                                ast_log(LOG_DEBUG, "Driver for channel '%s' does not support indication %d, emulating it\n", chan->name, condition);
                        }
                        if (ts && ts->data[0]) {
                                ast_log(LOG_DEBUG, "Driver for channel '%s' does not support indication %d, emulating it\n", chan->name, condition);
-                               ast_playtones_start(chan,0,ts->data);
+                               ast_playtones_start(chan,0,ts->data, 1);
                        }
                        else  {
                                /* not handled */
                        }
                        else  {
                                /* not handled */
@@ -1164,13 +1174,13 @@ static int do_senddigit(struct ast_channel *chan, char digit)
                        "!941+1209/50,!0/50",   /* * */
                        "!941+1477/50,!0/50" }; /* # */
                if (digit >= '0' && digit <='9')
                        "!941+1209/50,!0/50",   /* * */
                        "!941+1477/50,!0/50" }; /* # */
                if (digit >= '0' && digit <='9')
-                       ast_playtones_start(chan,0,dtmf_tones[digit-'0']);
+                       ast_playtones_start(chan,0,dtmf_tones[digit-'0'], 0);
                else if (digit >= 'A' && digit <= 'D')
                else if (digit >= 'A' && digit <= 'D')
-                       ast_playtones_start(chan,0,dtmf_tones[digit-'A'+10]);
+                       ast_playtones_start(chan,0,dtmf_tones[digit-'A'+10], 0);
                else if (digit == '*')
                else if (digit == '*')
-                       ast_playtones_start(chan,0,dtmf_tones[14]);
+                       ast_playtones_start(chan,0,dtmf_tones[14], 0);
                else if (digit == '#')
                else if (digit == '#')
-                       ast_playtones_start(chan,0,dtmf_tones[15]);
+                       ast_playtones_start(chan,0,dtmf_tones[15], 0);
                else {
                        /* not handled */
                        ast_log(LOG_WARNING, "Unable to handle DTMF tone '%c' for '%s'\n", digit, chan->name);
                else {
                        /* not handled */
                        ast_log(LOG_WARNING, "Unable to handle DTMF tone '%c' for '%s'\n", digit, chan->name);
@@ -1224,7 +1234,16 @@ int ast_write(struct ast_channel *chan, struct ast_frame *fr)
                        } else
                                f = fr;
                        if (f)  
                        } else
                                f = fr;
                        if (f)  
+                       {
                                res = chan->pvt->write(chan, f);
                                res = chan->pvt->write(chan, f);
+                               if( chan->monitor &&
+                                               chan->monitor->write_stream &&
+                                               f && ( f->frametype == AST_FRAME_VOICE ) ) {
+                                       if( ast_writestream( chan->monitor->write_stream, f ) < 0 ) {
+                                               ast_log(LOG_WARNING, "Failed to write data to channel monitor write stream\n");
+                                       }
+                               }
+                       }
                        else
                                res = 0;
                }
                        else
                                res = 0;
                }
@@ -1855,7 +1874,7 @@ int ast_channel_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags
                        break;
                }
                if (c0->pvt->bridge && 
                        break;
                }
                if (c0->pvt->bridge && 
-                       (c0->pvt->bridge == c1->pvt->bridge) && !nativefailed) {
+                       (c0->pvt->bridge == c1->pvt->bridge) && !nativefailed && !c0->monitor && !c1->monitor) {
                                /* Looks like they share a bridge code */
                        if (option_verbose > 2) 
                                ast_verbose(VERBOSE_PREFIX_3 "Attempting native bridge of %s and %s\n", c0->name, c1->name);
                                /* Looks like they share a bridge code */
                        if (option_verbose > 2) 
                                ast_verbose(VERBOSE_PREFIX_3 "Attempting native bridge of %s and %s\n", c0->name, c1->name);
@@ -1942,12 +1961,10 @@ int ast_channel_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags
 tackygoto:
                                /* Don't copy packets if there is a generator on either one, since they're
                                   not supposed to be listening anyway */
 tackygoto:
                                /* Don't copy packets if there is a generator on either one, since they're
                                   not supposed to be listening anyway */
-                               if (!c0->generator && !c1->generator) {
-                                       if (who == c0) 
-                                               ast_write(c1, f);
-                                       else 
-                                               ast_write(c0, f);
-                               }
+                               if (who == c0) 
+                                       ast_write(c1, f);
+                               else 
+                                       ast_write(c0, f);
                        }
                        ast_frfree(f);
                } else
                        }
                        ast_frfree(f);
                } else
@@ -2117,3 +2134,5 @@ int ast_tonepair(struct ast_channel *chan, int freq1, int freq2, int duration, i
        }
        return 0;
 }
        }
        return 0;
 }
+
+