On Mon, Feb 17, 2014 at 4:34 AM, Alistair Cunningham <acunningham@xxxxxxxxxxxxx> wrote: > On 17/02/14 03:27, Matthew Jordan wrote: >> >> In general, I'm against the idea of having a mechanism to execute >> dialplan applications through ARI. > > > I worry that not allowing this will make it difficult, perhaps impossible, > for those with large AGI applications to reap the benefits of ARI. > > In particular, those doing billing cannot risk losing the control of the > call and having an important billing event such as a hangup or transfer > going unnoticed (or noticed late). Passing control of the call from Stasis() > to back extensions.conf seems to me to be high risk for this (though I hope > I'm wrong). I, and I suspect others too, would much prefer to have Asterisk > call Statis() as soon as it receives an incoming call, and then have the > statis application keep control of the call throughout. Thinking about the concept of transfers: * Today, if a SIP transfer occurs, the channel is removed from the currently executing AGI and transferred to the specified destination. When that occurs, for all intents and purposes, it looks like the channel has hung up and returned to the dialplan. The same is true for Asterisk's feature transfers - if you Dial from an AGI and you allow blind transfers, the blind transfer will not return the channel to the AGI - it will return it to the dialplan. The act of transferring a channel from an external process or an internal process is completely dialplan dependent today. * ARI has the same behaviour as AGI, with one key difference: right now, there is no mechanism to use the features. Instead, you can implement your own features by capturing the DTMF and choosing to take some action. While you could release the channel back to the dialplan - or send it to Park - you could just as easily create your own 'blind', 'attended', 'parking' - or virtually anything else. In this regard, ARI has the same limitation as AGI - and externally initiated transfer will trigger the same results - but is more flexible internally. Note that you can always prevent externally initiated transfers at the channel driver level, if you wish. Also note that due to the new bridging core, things are far less likely to randomly steal your channel and not tell you about it. Channels have a well defined lifetime in bridges. When an externally initiated transfer occurs, ARI now also receives additional information about what just occurred via the BridgeBlindTransfer [1] and BridgeAttendedTransfer [2] events. [1] https://wiki.asterisk.org/wiki/display/AST/Asterisk+12+REST+Data+Models#Asterisk12RESTDataModels-BridgeBlindTransfer [2] https://wiki.asterisk.org/wiki/display/AST/Asterisk+12+REST+Data+Models#Asterisk12RESTDataModels-BridgeAttendedTransfer >> (1) It confuses AGI and ARI. AGI does it's job well: allow for remote >> execution of the dialplan from an external source. Heck, you can even >> use an AGI to exec a Stasis application to toss the channel over to >> ARI - that direction is just fine. > > That appears to me to mean that those who need AGI features are stuck with > AGI and cannot fully migrate to ARI. Maybe they can partially, but they're > going to end up with a hybrid AGI/ARI application in the same way they have > a hybrid AGI/AMI application now. > I think it all depends on what you're trying to do. Remember: the stated goal of ARI was not to fully replace AGI/AMI. It may, for some people - and who knows, it may get to that point. I'd certainly like it to. But the goal is to allow someone to replace Queue or VoiceMail. >> (2b) Remote execution of other dialplan applications opens up a whole >> world of permission escalation vulnerabilities. For example, would it >> be allowable for me to run the System dialplan application through >> that exec statement? > > Don't we already allow that in AGI? Yes, I'm not sure it's such a good idea. :-) AGI "gets away" with this by not having any permissions - it's hard to have a permission escalation vulnerability when there are no permissions! ARI has authentication with some very coarse grained permissions (read/write). Since we authenticate and provide permissions, it by its very nature opens us up to possible permission escalation vulnerabilities. I don't think that's a bad thing, but it is something to keep in mind. I do feel like we avoided the worst of AMI's flaws by not implementing nearly arbitrary authorization levels that don't have a logical mapping in the core - but it's worth keeping in mind that the dialplan is powerful. Asterisk is powerful. I'm not sure we need system altering power exposed through an external facing interface. > >> (3) As time goes on and more resources are added, the need for this >> functionality will diminish. Right now, channel technology agnostic >> text messaging, i.e., MessageSend, speech recognition, and text to >> speech are some of the more obvious candidates for resources; however, >> I think we've already hit that "90% of the dialplan functionality is >> doable through ARI" point. As we continue to find and build the things >> that people need, I think the desire for this feature will be less - >> other than some people will always like the dialplan :-) > > > I agree that this is the long-term answer. Here are the Asterisk > applications Enswitch does an AGI EXEC on: > > AGI(), because we support AGI user plugins. > AMD() AMD is a weird one. There's a category of modules written for Asterisk that do media stream analysis that are hard to replicate in any interface, and admittedly, this would be one. Right now, this would have to be done outside of ARI. > Answer() POST /channels/{id}/answer > Background() As ARI is asynchronous, this always happens. POST /channels/{id}/play and handle the DTMF events. > Busy() DELETE /channels/{id}?reason=busy > ChanSpy() POST /channels/{id}/snoop > ConfBridge() You can create your own conferences with your own business logic using holding bridges, mixing bridges, and their respective operations. > Congestion() DELETE /channels/{id}?reason=congestion > Dial() Dial is a few steps: (1) Originate a new channel using POST /channels (2) When you get a ChannelStateChanged event for the originated channel indicating that it is ringing. optionally POST /channels/{caller}/ring (or play music, or do nothing) (3) When you get a ChannelStateChanged event for the originated channel indicating that it answered, POST /bridges, then add the channels to the newly created bridge. Or don't put them in a bridge - you can do whatever you want with them. > Echo() You could probably create Echo in a perverse fashion using some convoluted bridges and Local channels, but otherwise, currently there is no way to create an Echo loop on a channel. (How useful is this really - or is a channel getting put into Echo merely to hold it forever?) > Hangup() DELETE /channels/{id} > Monitor() (1) Issue a POST /channels/{id}/snoop (2) Take the newly created snoop channel and issue a POST /channels/{id}/record on it > MusicOnHold() Issue a POST /channels/{id}/moh > Page() (1) Issue a *lot* of POST /channels (2) For each posted channel, issue a POST /channels/{id}/mute (3) Create a bridge via POST /bridges. Put all channels in it. (4) Put your announcer in the bridge and broadcast to the world. > Playback() POST /channels/{id}/play > Playtones() Not yet, but it'd be easy to add as a URI scheme to /play - and we probably should. > Progress() Happens automatically if the channel isn't answered and a media operation starts. > ReceiveFax() Nope! > Record() POST /channels/{id}/record > Ringing() POST /channels/{id}/ring > SendFax() Negatory. > StartMusicOnHold() POST /channels/{id}/moh > StopMonitor() For the channel that you created as a snooping channel; delete it. > StopPlaytones() > UserEvent() No, but this is on the short list now that we have JSON bodies. > > Before we re-write our code to use ARI, we need to be confident that there's > a way to implement (or elegantly work around) all of these. Many are no > problem. Answer() is already implemented, for example. There are some that > worry me though, such as AMD(), ReceiveFax(), and SendFax(). Of course > checking all of them in detail is my job, but if you could quickly cast your > eye down the list and see if there are any obvious problems it would be much > appreciated. So the three you that you called out are also the three that would be the most problematic. But let's think about the use cases for these: * SendFax/ReceiveFax are highly specialized for specific types of calls. Once a call has been determined to be servicing a fax, it's usually only going to get dropped into one of these two applications and then the call doesn't do much else. There's little business logic in these applications as well - other than knowing whether or not it worked and doing something with the resulting fax, you basically just want it to either send the image or receive it. Since the goal for ARI is to allow people to implement business logic outside of Asterisk - and these two applications by the nature of what they do eschew much business logic in the first place - there's not a lot of value in putting them in ARI, save to prevent someone from writing any dialplan. I wouldn't say that we would never put a /fax resource in ARI, but that doesn't feel quite as important as some of the others. * AMD - as I mentioned above, this one is odd. I'd put Zapateller in there as well. I'd have to think about that one some more. But think about it this way: out of all of the Asterisk applications you listed, there's really only three that are not readily doable, and all three of those are highly special purposed. Putting a call to AMD in front of Stasis for outbound dialers or using the fax extension for ReceiveFax is a small short term solution. And I think the flexibility afforded by the other operations is still pretty worthwhile. Matt -- Matthew Jordan Digium, Inc. | Engineering Manager 445 Jan Davis Drive NW - Huntsville, AL 35806 - USA Check us out at: http://digium.com & http://asterisk.org _______________________________________________ asterisk-app-dev mailing list asterisk-app-dev@xxxxxxxxxxxxxxxx http://lists.digium.com/cgi-bin/mailman/listinfo/asterisk-app-dev