<div dir="ltr"><div>Hey all:</div><div><br></div><div>We've known we're going to need ChanSpy functionality in ARI for some time. The</div><div>ability to have a channel direct its audio specifically into another channel</div>
<div>while that channel is in a bridge or is otherwise engaged with another party</div><div>is an important use case for Queues and other systems.</div><div><br></div><div>Currently, ChanSpy-ing in Asterisk is implemented using audio hooks and what</div>
<div>amounts to a very specific 'mini-bridge' in app_chanspy:</div><div><br></div><div><font face="courier new, monospace"> Spied channel Unwitting participant</font></div><div><font face="courier new, monospace"> <-------[[-------> ( Bridge ) <-----------------------></font></div>
<div><font face="courier new, monospace"> ^</font></div><div><font face="courier new, monospace"> |</font></div><div><font face="courier new, monospace"> |</font></div><div><font face="courier new, monospace"> | Spyer Channel</font></div>
<div><font face="courier new, monospace"> |</font></div><div><font face="courier new, monospace"> </font></div><div>Flags on the operation determine whether or not audio is written from the spyer</div><div>channel into the spied channel as well as having the audio from the spied</div>
<div>channel relayed to the spyer channel.</div><div><br></div><div>This works well, but has a few issues:</div><div><br></div><div>(1) Most of the logic is baked directly into app_chanspy. Ideally, this would be</div><div>
a core operation of some sort, so that other entities could use it as a</div><div> an operation with their own business logic placed on top of it. Extracting</div><div> it wouldn't be terribly difficult, but is a bit of a pain.</div>
<div>(2) It is a very channel centric implementation for what feels like a bridging</div><div> operation: that is, I want to know what is going on in this bridge but I</div><div> only want some subset of the channels to hear me. This made sense when we</div>
<div> had no bridging framework and the only unit of operation was the channel;</div><div> now, however, there are other options available to us.</div><div>(3) The biggest issue using the new framework is that there isn't an easy way</div>
<div> to go from being a spyer to a full participant in the bridge. For example,</div><div> a supervisor listening in on an agent and a caller may want to jump into</div><div> the bridge as a full participant. Using this implementation, we'd have to:</div>
<div> (a) Detach ourselves and the audio hook from the spied channel</div><div> (b) Take control of the spyer channel (possibly yanking them: this depends</div><div> on how we refactor the existing code)</div>
<div> (c) Place them into the bridge</div><div><br></div><div>All of which feels a bit cumbersome.</div><div><br></div><div>Another approach would be to make use of the bridging framework to create a true</div><div>softmix bridge that understands the concept of media paths. Currently, in</div>
<div>the softmix bridge, all frames for all channels are mixed together and resent</div><div>to all channels. It doesn't have to be that way however.</div><div><br></div><div>We could conceivably have a different mixing technology that allowed for paths</div>
<div>to be set up:</div><div><font face="courier new, monospace"> Channel A Channel B Channel C</font></div><div><font face="courier new, monospace">Channel A X Y Y</font></div>
<div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">Channel B Y X Y</font></div><div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">Channel C Y N X</font></div>
<div><br></div><div>That is, Channel A's audio is mixed and sent to B and C; Channel B's audio is</div><div>mixed and sent to A and C; but Channel C's audio is mixed and sent only to A.</div><div>This let's them effectively spy on B without them knowing they're there.</div>
<div><br></div><div>Modifying the 'spying' would require allowing the routes to be changed</div><div>dynamically. The benefit here is that there aren't any Bridge Enter/Leave</div><div>operations that have to be performed, and a channel can easily toggle back and</div>
<div>forth between spying and not spying.</div><div><br></div><div>I'd imagine the API would look something like this:</div><div><br></div><div><font face="courier new, monospace">POST /bridges/{id}/mediaRoute</font></div>
<div><font face="courier new, monospace"> parameters:</font></div><div><font face="courier new, monospace"> writeChannels: IDs of the channels that media can be sent to</font></div><div><font face="courier new, monospace"> readChannels: IDs of the channels that media can be recieved from</font></div>
<div><font face="courier new, monospace">DELETE /bridges/{id}/mediaRoute</font></div><div><font face="courier new, monospace"> parameters:</font></div><div><font face="courier new, monospace"> (Same, just removes routes instead)</font></div>
<div><br></div><div>You could go rather crazy with this functionality, and set up some rather</div><div>interesting advanced conferencing applications as well.</div><div><br></div><div>I would, however, prefer not to mangle softmix with this feature.</div>
<div>Softmix is a performant mixing technology used by a lot of things, and this</div><div>feature is overkill except for some advanced queueing/conferencing use cases.</div><div>The act of maintaining the routes (which are basically adjacency lists or an</div>
<div>adjacency matrix) isn't as "cheap" as the mixing that softmix performs, so</div><div>it feels like a bad idea to impose this functionality on all multi-party</div><div>bridges. Maybe 'smartmix'?</div>
<div><br></div><div>Thoughts?</div><div><br></div><div><br></div>-- <br><div dir="ltr"><div>Matthew Jordan<br></div><div>Digium, Inc. | Engineering Manager</div><div>445 Jan Davis Drive NW - Huntsville, AL 35806 - USA</div>
<div>Check us out at: <a href="http://digium.com" target="_blank">http://digium.com</a> & <a href="http://asterisk.org" target="_blank">http://asterisk.org</a></div></div>
</div>