 So some pretty good talk so far, huh? That's gonna be a tough act to follow but So I thought I'd do something really revolutionary here. I'm actually gonna talk about using Alexa and Erlang for telephony application It's pretty funny because you know you go to these these talks in the odd time you'll see it Well, if I'm not talking anyways some about telephony, but I'm gonna actually talk through a Phone server or a soft phone server I'll give you a demonstration I'm gonna first. I'll talk about myself because you have to talk about yourself how we use the looks at work I'm gonna demo the product and I'll go through an overview of it talk a little bit about the architecture the design and then Some questions at the end if we have time So who am I my old age? Goggles on here Okay, so some information there and we already talked about Canada a crapload of experience writing software and in the telephony Area I'm a partner and the R&D lead at a startup company called e-matrotel We've been around for about five years or six years and we provide cost-effective communications We're a bunch of facts nortel people and so we built systems that help Nortel people with nortel equipment Maintain their equipment and give them a cost-effective upgrade to unified communications So how do we do how do we use alexa so? I'm proud to say that we've been developing alexa applications for over two years now I Think I started at alexa row dot seven something My first application was actually had no Phoenix. It was just real telecom stuff. I presented I presented this at the lexicon 2014 so if you want to know any information about this you can look up that video But it was a telephone gateway. It was written in alexa And it's we sell it's a multiple commercial deployments. We're out selling it now and supporting it Road a Notifier application This was an interesting project. I had originally written it with rails Using a product called adhesion for talking to the call server. I'll apologize right now if I used too much Telephony lingo and stop me if you need clarification So some called adhesion to talk to the talk to the telephone switch and Get in there and play play recordings and and get key presses back and I could never get the thing it was it's very concurrent. So the application is you know You load up a list of list of people It was a hospital application. So all hands on deck code orange Call everyone into work. So basically hit a button it goes through about 300 people and one deployment They have about 300 people on staff goes through calls everyone about I think they was configured for 15 calls at a time The answer plays a recording saying you need it at work press one to accept two to decline and there's real-time reporting and all that fun stuff and I could never get it work all the Concurrency I couldn't get it working. Well, so one day I said screw it and I rewrote it in Phoenix and It worked like a charm now It was not an easy job because I used a bunch of stuff that the Alexa Phoenix Community ecosystem didn't have So I had written it with fact of admin So I actually wrote X admin to replace active admin And a lot of the interfacing with the telephone switch wasn't there. So I had to write some libraries for those But that's now we're selling that and we have one production deployment on it And then of course the the one I'm going to talk about today is the web RTC soft phone and it's Currently in alpha testing we're getting ready for beta Hopefully in about a month we should be ready for beta and and then hopefully selling some time before the middle of this year I've got various other prototype applications at elixir conf last year I did a talk on doing a voice survey application so you create a survey and a database of questions and then it someone calls in and it reads out the questions and and choices and then they pick it on their The on their telephone and then you get the summary of that so And that's up on github so The web RTC soft phone. So what were the goals? So I was asked to create a new soft phone for our telephone platform and the requirement was support on multiple desktops so Linux or sorry windows and Mac of course because I run Mac and Also on mobile platforms We're a startup so we have very low R&D budget so and One of the requirements so we have our telephone system has has has phones actually they're The old nortel IP phones and they're very feature rich Much more feature rich than sip clients if you're familiar with the sip protocol So we wanted to use that that protocol for for signaling and managing the telephone I'd had to be able to interface on the system with all the other phones as well as be able to talk Phone your mom so we had to support the psdn trunks, which is a fancy name for Calling everyone else outside the office pbx standing for private branch exchange Features like call logging conference hot desking and Directed pickup and there's hundreds of different features and we also want it to be a future proof for a platform for video Messaging chat rooms presence, etc So we decided to use web RTC so that we could build this phone in a browser And get away get away from having to package it for different versions of windows and Mac and And then separate native clients for all the different mobile platforms. There's just one or two out there So we chose web RTC and for those who don't know web RTC just a real quick overview So it's a new developing standard for real-time communications In the browser without the need for native plugins Or any client software installed So the draft spec involves support for audio video and data And it's supported in some of the major browsers like chrome and firefox natively, I think there's also some plugins you can install on edge and Safari and and so on It's really a set of JavaScript APIs for doing audio video And Media set up it handles the natural verse all we heard about that earlier Has data channels and security It's designed for peer-to-peer communication. So so The media path is actually from from browser to browser. It doesn't require a centralized server But it does not define a signaling protocol to figure out who you can talk to and to Figure out where they are so that you can send them a request to set up a call So before I go into the details actually, let's do a little demo here. You want to give me a call? Yeah, I hope it works. Oh Look at that okay, so I got a call coming in it's up there and I can actually click it and It's all my headset right now. So Let me just test it here Hello No, you can't hear me. Oh, I can hear you now. Okay. Well So now I'll put on speakers say something so so we got a we got a call going there What's that? It's so it works And then there's all kinds of fancy features on here I can put the call on hold whoops, that's you know that's the whole button so Erica it's on hold now so you shouldn't be able to hear me Yeah, yeah, yeah, that's connected. So by the way, this is connected I've got our product our telephone system running in a virtual machine. So Contrary to popular belief virtual machines aren't all bad. So our product runs on Linux So I've got it running on a virtual machine here but you know, it has a bunch of fancy features like you know different lines so I can actually I can Go take that off. I got a problem with my dial tone right now So any any experts with web audio in the audience in JavaScript. I'd love to talk to you So I can't get my oscillators oscillating Get that problem all the time You know, we've got a fancy directory feature in here so basically it goes into the goes into the switch and pulls out all the extensions and You know favorites Favorites so you can add and subtract them from favorites and Lots fun stuff. So I'll hang up the call, you know, we can go to my voicemail and So anyways, that's that's what we're building If if you're familiar with nortel office phones, you'll actually probably recognize this layout. It's very similar to our to our hard phones All right so Let's talk about the extra at the architecture now that you understand what I built. So we have some hard phones and I don't like most And it's connected to the to our call server, which is basically a limit Linux box And then up on the top on the the client side Okay, so we have in the client. I've got use jQuery mobile for the for Just a general way of rendering the client and that way it's it's mobile ready It's essentially a single-page application it has selectable UI themes and It's the UIs mostly driven by web sockets Hence Phoenix So on the Phoenix side heavy on the channel And then a standard architecture controllers blah blah blah And I also use X admin to as an admin interface for it and Then on the kind of the pure Alexa side So I've got you know, probably the main component is is this client state machine client SM It's a gen FSM I've got This proxy that I'll talk about in a minute And then I have some some modules for the telephony signaling We actually talked to the switch through reliable RUDP connection Software that I actually that that was written as part of a previous project and then a couple of state management apps supervisors and that's about it and then finally configuration and packaging so we use RPM to pack a package it up and deliver it as part of inside RPM. We use the XRM and conform So go through a little bit of the design details Client controller is pretty simple. It's basically got In essence one main action to load the phone do authentication Through a plug in in the router I actually use plug off and I've modified it. I've added a database type authentication mode to it and So when we come in for a request, we check see if the client state machine is running for that that session obviously if we have the session and If it's not then we set up the session We store I store the Mac address each phone has a Mac of kind of a virtual Mac address That's how the how the telephone server identifies it. So store that in the session load up the the models And there's a several different models for for settings themes number of keys the selected audio devices I was using a headset there so you have a separate device for For a headset and and the main hands-free option and render the page The client SM so have one gen FSM. That's hard to say Process per every register client It handles the client signaling so it handles the signaling to and from the asterix Switch call server so our product is based on the open source telephone server called asterix And we do that through a reliable UDP and stimulus-based signaling stack and We also handle the signaling to and from the browser through Phoenix channels One of the things I had one of the problems I had to solve is Since a lot of the state is done through channels and there's there's And if you hit the reload brown a reload button on the browser You basically reload everything, but you don't have all the state all the different messages So the the icons against the keys the display and so on So I built a proxy module So when I when I get a message in or a data in from the switch I actually go through this proxy proxy module that basically saves it And then if you do a refresh in the browser after you've logged in then it basically just re-sends out all the the messages so Pretty extensive watchdog handling. So I've got to handle a case of Did this server go away or did the call server go away? so there's a bunch of a bunch of watchdogging in there and So the client will detect, you know all those different scenarios go into a state where Render server unavailable in the display and then if they come back online it starts up again The state machine is fairly large. So this client SM. It's actually very large. So It's handling the messages from the switch. It's handling the messages from the client and so on So the chance of error in in that state machine is fairly high Protect against that. I actually have a separate process that I store a copy of the the state After each each event coming in. So, you know, if you're familiar with gen fsm There's a tuple you you put at the end for next state and blah blah blah So I actually created a function that that I call and in that function It basically sends the state over to another very simple Agent to store that state and so then if the client if the client SM crashes as part of it Then the supervisor restarts it then I just go I detect that and I go out and I get the old state So it comes back in the exact same state. It was Read about that in a book a whole I think really early on and it was about a year and a half later And I thought oh, I think I've read how to do that So the client channel It's fairly simple basically the message comes in so on the on the Receive side from from the client down a message comes in there's MAC address in the in the message So I extract that out. I Check to see if the if the state machine is running If it's not I send a reload message to the client if the state machine is running I tell it the State machine to update. Oh, sorry. I'm on on join. I got lost myself So if I get an on join, which means you've hit the reload button. So on the first one if state machine is not running I I send it to wait and or I tell it to to do an update Handle in is just a bunch of bunch of clauses to handle the incoming messages So couple interesting things in the project. I have So the administration interface Is I put it on a separate port. I didn't want since you know this And everyone in the office is using that right whereas the minute of the interface is just an Admin person so I didn't want to put it on the same port So I actually have two separate ports and so two separate endpoints to manage that Furthermore the Authentication for the admin interface is different It uses a database table as part of our telephone system and not my application So So I have a different authentication plug-in for that or different configuration for that and I also have multiple repos like I just said there's a separate database for For two areas the admin login as well as that directory feature. I showed you It's actually using a different database. They're both my sequel So I have an end point for either so some of the production implications of building a product for production One thing we like to do when we want to make money is protect our intellectual property So I all my projects have this removed debug info and I just gave him a little example in the pinup here So a couple lines in your in your mix file enables that Plus I had to put a little bit of code in my presentation so So packaging use the XRM to to build the release tar file Like I said, we use RPM. So as part of the build the build part in an RPM spec file I actually run the mixed mix depth scat and then the release and so on in the build section and And Configuration we're using conform Pretty standard stuff except we use a different non-standard config file location I also use syslog so all the logging goes to syslog and I use Syslog package that I wrote a while ago. That's in github. So what's happening in the browser? Most of it so the HTML is pretty basic. It's just a big file that you know renders all those controls But all the logics is handling is handled through the channel. So I've got like 50 or so channel on handlers For all the different things that come in so update the display Update the button texts icons You know the keys are context sensitive Setting up media path playing dial tone DTMF tones Starting a stopping the ringer Switching mic and speakers etc a lot less channel pushes. So a lot less traffic going out Going from the from the browser down to the server Said it's a single page application So all all the pages are loaded. I Loaded in one action using jQuery mobile page transitions Ajax requests. So if I go and go into the settings and do a submit it does an Ajax request and Comes back most of them are like that. There's a couple actions that Require a page reload like changing the theme So some of that forces a page reload which is problematic with WebRTC because it doesn't like a Reload of the page when you're when you have a media path connected So I'd actually put some JavaScript code in there to stop or block page reloads when you're on a call And then I have separate controllers for the different the settings and the properties and etc So design a WebRTC So WebRTC most of work's done in in just a few JavaScript APIs There's a concept of a peer and There's a for every call. There's a not traversal Protocol called ice. I actually saw it on a previous presentation So a couple calls like that Phoenix channels are perfect for this So, you know getting getting a request in and passing the passing the sibling information Something called an STP packet You know Phoenix works great for that The media path is done outside Alexa and Phoenix. So the media path is is from the browser in this case We're not doing peer-to-peer so we actually connect the soft phone to our switch and then our switch switches out to some other phones So so we actually had to build some some WebRTC support into our our Channel driver for our phones This was this was interesting When I first started doing this I wanted to try to do more work in elixir So I went out looking for support for a nice client for you know Phoenix works great Found pieces of some of this stuff, but not a full production implementation that I could find also the media path in WebRTC has to be encrypted with DTLS just TLS for UDP and There's no support in Erlang which was a red herring because there's code in there to do it and Posts out there on how to do it, but it doesn't work And if you read further enough further enough down the road down down the Listings it says oh, yeah, well, we only did about half the stack so Yeah, that was a day So we ended up doing the ice and the DTLS in the asterisk channel driver and so I don't I basically Take the take the information from WebRTC down through Phoenix I get the candidates and the the different information But then I pass that through our protocol to to the call server and it handles the rest of it Believe it or not The headset support was a nightmare. So, you know if you ask me is WebRTC ready my answer is no You know for your basic client-to-client very simple applications, you know, it's great But just to be able to Support multiple devices so a headset and hands-free and it'd be able to push a button to switch between them in call It was a nightmare. I I've spent I don't know. I probably spent two weeks on this and that's a lot of time I couldn't find any good examples So I managed to find about three different technologies and things and mush them together and Got it working. So If you're ever trying to do that, let me know I Also have a link here So I wrote a very primitive peer-to-peer WebRTC example Early on in the project just so I could understand how things worked and I have that up in github So if you are playing with that but WebRTC With Phoenix or elixir, you know, you can go there Just another another little What I thought was an interesting little challenge or thing I dealt with was our product is licensed commercially So you actually have to buy it and and it's it's licensed to a server And the licensing is based on the number of clients that you can actually have registered and using it at a time So So basically You know, I have a licensed manager and I have several elixir projects So so I share I share this or I Built it shareable with this project because I had used I had copied it over twice for two other projects And I thought no, that's not good So I actually built a module for this. I have it built so that in development you can actually Mock it out or configure it out so that you don't need a license in in dev But I built that so that you can't actually configure it out in production mode because we don't want customers doing that and You know to do that because of a separate project You actually on the depths on the depths line. You actually have to pass the environment across As I'm showing in this example Okay, what were some of the challenges? Elixir and Phoenix weren't So they're awesome I wish I could spend all my time working in in Elixir and Phoenix on the project, but unfortunately I have to do some JavaScript Web RTC I talked about some of those challenges already Still have a few challenges. I'm fighting some echo and voice quality issues. I have to resolve Single-page web applications can be a little tricky and migrations we're gonna solve this so Yeah, running migrations for production is I actually ended up having to write some of my own code there so I made the mistake of running running echo migrate in the build section of my spec file only to realize that That's run on the on the build the host and not target so anyways, I did solve that and have a solution for that for for just calling the calling the migrate function in echo directly through an RPC call after After the Project is up nor the application is up during the install questions So the question is have I run into any IVR call trees stuff in all of this The so a couple of the applications I've built are based on that so the call out Application as a very simple one press one to accept to decline. So that's that's a you know a binary choice in an IVR the The voice the voice survey application is kind of an IVR application, right? Because when you call in it's actually going to go through the database read the question Read all the choices and then you get to pick and then it has you know It has options to replay and and all that stuff. So it is kind of an IVR. So Part of that I wrote a couple libraries for at for the asterisks call server so that I can interface from Phoenix Or from a elixir to the asterisks call server. And so what happens is You know when they come in that that call is you know That stuff is directed into my elixir application and I'm able to play it recordings and ask choices and and stuff So that's your question cool Because when you call it All right, thanks very much