 Okay, hello everyone, my name is Cyril and today I'm going to be talking about Asterisks and Byton. Just to see the audience, how many of you know what Asterisk is? Okay, that's a lot. How many of you have used it in an office or at home? Okay, that's a lot less. Okay, so I'm going to start by introducing Asterisk. Basically what it can do when it can be used and what people usually do with it and how it's organized and how it's configured also. And then I'm going to explain how I've been using Byton to make Asterisk easier and more effective. Before I start, are there any questions? No? Okay, this is a quote from Asterisk websites. It describes what Asterisk is. It's an open-source pbx telephony engine and telephony applications toolkit, which means that you can interconnect different voice networks with it. You can also build telephony applications with it. There's a lot of functionalities that you can use. It's open-source of course, so that means you're free to do whatever you want with it. That's really a key element in Asterisk development because most telephony systems are proprietary and very limited and they cost a lot. Okay, so what you can do with it, you can build a communication network for, say, your internal office. You can have an Asterisk server and you can have VoIP phones for everyone. And that way you can have extensions inside your office so that you can call each other using the internal network instead of going through, I don't know, the usual telephony network because that would cost a lot. And this kind of networks can be built inside the same building and because Asterisk is VoIP, that means you can also build this kind of network between locations. You can have two offices very far away, I don't know, one in France and one in Canada. And that means you can make calls between your two offices without going through the telephony network, which means you don't have to actually pay anything for those calls. You can do the same, I guess, with family members or friends. It's pretty much the same as Skype, I think. You can also use it to build and host IVRs, which is interactive voice response. Thanks. IVRs are usually, I think most of them, it's used for customer services. When you call somewhere and it says, if you're calling for a problem about your internet access, press one or to talk to anyone, you press zero. That's what IVRs are. And that's something that's very easy to do with Asterisk. And, yeah, also I mentioned it, but there are many. That's a very good point because Asterisk is very flexible. So this means that if you have anything you want to do, that's, I don't know, anything you want to use, in fact, to talk to anyone, anywhere, you can build it with Asterisk. And most of the time, you don't even need to have a phone line to use it. You can just use the internet to make calls to anyone. Of course, everyone has to have the proper equipment because you cannot call from the internet to a phone. But if you have some time and I guess the money, you can do it if you're willing to stop paying bail. The structure of Asterisk, it's actually very interesting because it uses modules for really everything. There's a car that loads these modules, but it doesn't do much because Asterisk will load modules for every channel types. Channel types are the equivalent of the lines, I guess. For example, Zap is the name for traditional telephony. If you have a standard telephone line or a T1, that's going to be called a Zap channel and see if it's a virtual line kind of thing through the internet on a local network. It will also load modules for the codecs you can use because CIP or Vipe doesn't necessarily imply a specific codec you can use anyone you want based on the bandwidth that you have and the sound quality that you want. You can choose. Do you have questions? Yes, sure. Is fax a codec? Fax, I'm not sure. I haven't worked a lot with faxes, but I know that it's a specific application, but I think it doesn't use a codec. I think it's, well, not an audio codec. I think it's some kind of encoding, but it doesn't, I don't think there's a codec for that. It doesn't encode audio, so I don't think so. It doesn't encode an audio stream, so I don't think it's a codec for faxes. But a service can handle faxes as well, if you want. And the applications are, yeah, sure. Before we move on, ask us to handle faxes as well. Yeah. But it's not a codec? No, it's not a codec, but it's some kind of application that uses telephone lines, so a service can do it. Okay. There's also modules for applications. Applications are not, per se, applications. They are more like instructions that you can use to tell a service what you want to do with a certain code. For example, dial is just dials. You can specify any destination you want. You have to specify the channel type. And if, for example, someone calls on a certain number and you want it to transfer somewhere else, you use the dial command, and it's going to connect the calls between locations. Meet me is, it's actually a conference. So if you want to, if you want everyone who calls on a specific number, you're assigned to meet me to this number. And that way everyone who calls the number is going to talk to each other. So that's how it's done. And so, yeah, there's modules for all applications that you can use. And there are also modules for resources. I don't really use that, but if you want, you can define a database source, which means that a service when it will require an access to a database, if you haven't specified anyone for the specific module, it's going to load to see what resources are available. And if there's a database module, a database resource, it's going to use this one by default. A service uses the database mostly for CDR, which is called detail record. It's just a list of every code that's going through your server. So, yeah, of course, each module is configured independently. That's implied because everything is modular, but it means also that there are a lot of configuration files for Asterisk. I think on a standard installation of Asterisk, you have like 30, 40 configuration files to edit. You don't have to edit all of them, but it still makes a lot because you have to find out which one does what and it can be messy. For example, SIP.conf, it allows you to configure as well what the server, the SIP server that Asterisk will run on what address and port to bind and what codecs are allowed, but it will also configure the SIP clients. For example, the SIP phones you have in your office, you have to define all your users, and usually it's users for phones because there's a difference between users and peers. Users can place and receive codes and that's it, and peers can do a bit more. I'm not quite sure what they can transfer codes between peers, I think. So, yeah, that's it. You have one configuration file and you have to define two different kinds of things in them, so it can be confusing at the beginning. The most important file is extensions.conf. It defines what to do with every code, depending on the context because the content of extensions.conf is referred to as the dial plan and that's why you define the context. Every code by default goes in a context called default and if you want, for example, your SIP clients to go somewhere else to dial out or something, you can define another context called outgoing and this context will say just dial out and you can, in the default context, you can have what you want to do for every incoming call, for example, play a menu to say press zero to reach the customer support or if you know the extension you're trying to reach, dial it now. You can define this in there. SIP, it's a protocol for VoIP telephony. Yeah, it's, yeah. Is that okay? Station initiation protocol? Okay. It's a protocol you can use between clients and servers on the Internet to send voice. Yeah, this is for a very simple example of a context in extensions.conf, which means everyone who calls on this specific number, you're going to answer the call, playback, this sound file, it's a stupid sound file that's included with Asterisk, it's just a bunch of monkeys. I like to use it. And then you hang up. So that's how you define what to do with a call in extensions.conf. It's always the same format. You have to define which extension, the priority, it has to be ordered. You can use N as next one if you don't want to count or change everything and the application you want to run at that priority. So that's how you have to configure all your numbers, all your extensions if you have many numbers that come in to your server. You have to define all the instructions for all your numbers. Or if you want you can do the same for all of them, but that's not really necessary. Asterisk gateway interface, usually called AGI, it allows for external IVR programming. I say external because you can program IVRs directly into the dial plan, but it's very complicated. It's not very, I don't know, it's too complex because you have to, okay, you have to use go tos in your dial plan to define if someone press one, go to another priority, which means that all your priorities have to be numbered. You cannot use N and that's very difficult to maintain or to update. It's very difficult. So with AGI it's actually you can program using any language you want and Asterisk will execute the program and communicate with your program by standard input and output, which means it's very easy programming and that's what allows you to use any kind of language that you want. If you want to stream a file or get a channel variable, you just print the command that you want to execute and then Asterisk will write back the command result if it failed, if it worked, or the value of the variable that you asked for. Yeah, that's an example with the monkeys again. If you say get data, that means that's the Asterisk console. I did this, but that means the AGI printed this line. Get data means allow the user to input a few numbers. The input is interrupted if one of these touches buttons is pressed. This specifies the timeout of 5 seconds. It's in milliseconds and this specifies the maximum length of the input. So with this command, Asterisk is going to stream this file and wait for some input for 5 seconds and if one of these buttons is pressed, it's going to end and here we can see the result was 57 and post doesn't do anything. It's just the position in the sound file where the input stopped. So it's not very useful. It can be useful if you want to know if someone heard the message completely or not. So that's what you have to work with if you want to build AGI. It's very easy to use. Usually Asterisk is used with Perl and PostgreSQL. I don't really know why, but I thought I should mention it because there's a lot of resources for Perl and PostgreSQL with Asterisk. For example, if you want to use a MySQL database, you have to go through ODBC to set up the connection. But if you want to use PostgreSQL, there's a configuration file directly built in. So that's it. The next part is going to be about Python. Does anyone have any questions on the first part? That depends on the kind of lines you have if you have a T1 or many T1s or just a single line. But we used to have a dual-core server for the gate. There was, I think, 40 ones on it. That means each T1 is the equivalent of 23 phone lines. So that's 102, I think. No. Anyways, four times 23. Yeah. 92. So that's 92 phone lines and the server we had was capable of handling all those calls at the same time. I don't think we ever went to 92 calls, but maybe 80, 70, 80 calls at the same time. Asteroid doesn't use a lot of resources. You don't need a big, big server to... Excuse me? That depends on what you want to do, but usually I think any entry-line server like a core dual with one gig of RAM is going to be enough. It's just if you want to have T1s, you need special cards for it, but that's really all you need. Just to add on, probably the majority of the discount long-distance carriers are going to use an Asteroid service to carry all their traffic across confidence and stuff. Really what's going to limit you more is not so much your call capacity, but how much processing you're doing on board. So if you're doing transcoding from one code audio codec to another, that takes up a lot more capacity than just switching the calls. Same thing if you're doing needy conferencing, and there's a lot of DSP activity arrive being done in software to do these conference calls. So you typically want a separate conference server for that kind of stuff. Yeah, but usually the DSP processing is done on the telephony card that you have. Do you have a card? Yeah, if you have one. Yeah, sure. Any more? Yeah. Do you need a special hardware to connect your phones? To connect the phones. If you use VoIP phones, you don't need anything, but if you want to connect traditional analog phones, you need a small adapter. It's called an ATA. It's a small box. You plug in your phone, and you plug in the network in it, and you just have to configure it, and it just works. It doesn't cost a lot. I think $70 for one box. What did IVR stand for? Interactive voice response. Excuse me? Well, once you're familiar with Asterisk, it's very fast, but you have to learn a lot of... How much did it take? Well, actually, when I started, there was already a complete environment. It took me, I think, four months to be really comfortable with it, and then I started to redo everything using Python, actually. I think it was four months, and I worked with it every day, so it's pretty hard at the beginning. Excuse me? Does anybody make admin tools? Actually, I'm going to talk about this. No, wait. There are a few, but they don't work very well, and the framework that I built, I actually took care of this problem, because I use a database for pretty much everything, so that makes it easier to manage and to change. Okay, so where does it come in? First of all, AGI, of course, because it's a programming language and we need something to do with it. As I said, I also use it for the configuration of my servers. Actually, not as the configuration, but as the middle part in the configuration. It's in between the database holds all the configuration, and Python translates the configuration, and of course debugging, because no, I'll tell it later. There are a few existing frameworks. Fats is... Actually, I don't really know, because it's the one I hear most about, but everything is in Russian, so I don't know lots about it, but I think it's pretty much the same as StarPy. StarPy uses a lot of the twisted modules, but it's very complex. I think it doesn't really simplify the use of Asterisk. I think it complexifies the world. Yeah, okay. It's complicated. And it's also kind of restrictive, because it presupposes... It presupposes... It makes assumptions. That's what I was looking for. It makes assumptions about your environment and what you're going to be using it for, so it's not very friendly to use. The one that I liked actually was Pyst. It's a very simple... Actually, it used to be, but now it's far more complex, but I think it's just two or three classes that handle the exceptions, the interaction with Asterisk. Actually, the main goal of Pyst is to define a complete AGI class. So I think this can be useful if you want a big documentation about the programming, or if you don't want people to really learn the documentation of Asterisk. For example, how does GetData work? So it tries to define a method for every application you can have in an AGI. So I didn't quite like this for that, because it was too much. If you know the Asterisk command, you don't need to know another one. But if you want to start with something, I think it's a good idea. So what we really need, if you want to be using Python with Asterisk, is just to define an AGI class that needs only two methods, actually more, but in the bigger scheme of things. Just the initialization, just read the environment that Asterisk gives it because when Asterisk executes an AGI, it sends a lot of variables, for example what number was dialed, what's the color ID, what's the unique ID of the call and many information like that, and execute which will essentially just send an instruction to Asterisk and return the result. So that's really all you need if you want to be programming AGI with Python. Maybe a log and a database class. These are not really necessary if you want to build very simple applications. And the thing is extensions are all the same because it's always about dialing something else or executing an AGI. One or more depends, but usually those are the two actions that any extension will do. There are not many cases where you'll need to do something else because if you can execute an AGI, that means that you can have a menu, you can decide to transfer someone to somewhere else and so this way it's very easy to simplify actually the configuration. Yeah, extensions.conf, I mentioned it already. Yeah, this file the one I talked about earlier that defines what you want to do with every call you have to define all extensions in it and every single instructions that you want to have. So it can become very heavy, it can become one big file that you cannot understand anymore and you have to be very careful when you edit it because if you have a syntax error in it Asterisk will not work at all and that can be dangerous. So yeah, it will become one big mess. So that's if you want to keep things really simple you define two contexts one that defines what to do with incoming calls and what defines the outgoing calls, yeah? I just want to know when you say Asterisk doesn't work at all does it give nice exceptions or does it... Yeah, it gives exceptions but actually when you edit the configuration file you have to go in the Asterisk console and then type reload and it reloads all modules and all configuration so there's like 400 lines going through so if you don't look at each and every line you might not see it. Yeah, yeah it's... it can be sensitive to work with. So these two contexts define what to do with incoming and outgoing calls the underscore x dot instead of the extension means any extension that starts with a number so that way every call I get in my incoming context will go to this AGI and every call I try to make from a phone or from another AGI will be done like this that's the syntax to get variables in the dive plan for Asterisk and actually what can be confusing is when you try to dial a call it will go in the dive plan and look for the number you're trying to dial so that's why you have to define extensions like this for outgoing calls because otherwise I don't know you have to enter all the numbers you want to dial in your configuration file and that's just stupid. So in the AGI that handles all the incoming calls you just have to get the extension that was dialed you look it up in the database and do what it says in the database and that's all that's really all it needs to do because there are only just a few actions you can in your database you can specify that you want this extension to execute another AGI or you can specify it to dial somewhere else you can have a few sections or a few categories of extensions in it. The consequences of this change in Asterisk configuration means that modifications are safe and easy because you don't have to edit the extensions.conf anymore you don't have to reload the configuration file and any change you make that will cause an error will cause the error just for the number that you edited. So this is a very easy way to have a more robust Asterisk configuration and that's what I was talking about before this way you can design complete management interface with it because all your configuration is in the database so this means you can have a few web pages that you can use to edit everything that your server does so that's pretty cool. This section is about debugging because Python plays a very big role in my debugging. For syntax errors since it won't compile I recommend using PyChecker or PyLint because the debugging methods I have in place require the Python script to compile properly and execute. The inconvenience for the runtime exceptions for example divide by zero or I don't know anything a broken pipe or something since Asterisk runs the AGI you don't necessarily have a log except if you have written a log class to write something but you will not have access to the standard error so that means you cannot see if an AGI just crashes in execution you will just have someone calling customer service saying hey the line dropped I don't know. So that's a very big problem because if you don't know when an AGI will crash you can't really patch it and do anything so the easy solution I had was have all the core of my AGI in a try except block which means my AGI can throw exceptions, it can crash it can do anything but in my except I catch everything and the descent trace method I have is actually very useful because I can using the inspect module I can go back and get the back trace actually all the methods that were called and which files, which line exactly where was they are I just have to send an email with this and as soon as it crashes I know it so that's a very good way to do it and that's it are there any questions?