Asterisk Cti
Asterisk Cti
[todo]
Update server structure and diagrams with SQLite support Update Database structure to better support queues and priorities, and agents initially in pause. Complete commands Add all the AsteriskCTI Client project
Asterisk CTI
1. Introduction
In my idea AsteriskCTI should be basically a multiplatform easy to use client/ server CTI solution integrated with the Open Source Digiums Asterisk PBX Server. C.T.I. is an acronym of Computer Telephony Integration: so a CTI is a software that make possible to transfer from the telephone interface to the client pc a set of useful informations like calling party telephone number, digits grabbed by IVRs and so on. These information should be made available to a client software for database queries and/or other usage. Actually, the advent of Web 2.0 technologies have to reflect on the concept of CTI: today a lot of backoffice softwares runs like web pages into browsers, and thus the most important innovation that a new CTI platform can carry is the web integration. Call Data builded on the PBX logic should be passed to a middleware able to perform the most disparate operations such as execute an external application or open a browser, allowing to transfer them the variables as telephone parameters. This new model make possible to build callcenter logics without the knowledge of complex API manageable only with advanced C/C++ skills, like TAPI. Finally, this application should be available and runnable, client and server, on all (or almost all) modern operating systems: to achieve this objective Ive selected, after trying various solutions (like mono/.net on GTK), to use the QT toolkit and by consequence - C++ language. QT seems to be very easy to learn, very quick and stable, really multiplatform and now also with a multiplatform IDE. The same sources can be ported from Win32 to Linux just by compiling and packaging them.
2. Architecture
By initial design, AsteriskCTI is composed of various parts: the core is Digium Asterisk PBX with its AMI (Asterisk Manager Interface). The Asterisk Manager allows a client program to connect to an Asterisk instance and issue commands or read PBX events over a TCP/IP stream. The AMI is well documented on voip-info.org (http://www.voipinfo.org/wiki/view/Asterisk+manager+API). Actually, various mini-CTI application that make use of AMI opens a lot of AMI connections, once per client: this approach is not optimal because may slow down
Page 1 of 11 rev. 33
AsteriskCTI Project last save by bruno on 2009-01-04 22:42 Asterisk PBX, decuplicate network traffic (dont forget that on AMI flows a lot of PBX events) and generally decentralize on CTI Client the application logic. For this reason, AsteriskCTI should provide a Server daemon that opens just one AMI connection and listen for AsteriskCTI clients connections. This means that on large installations, AsteriskCTI server can be run on a server different from the one that runs Asterisk PBX: calls, queues, ivrs runs separate from cti server and without a great waste of resources. On small installations both software may runs on a single linux server lowering TCO. The AsteriskCTI Server should also be able to watch dialplan flow and match the events that carry in variables and store them for latter notify the client. These information will be collected on a per-call basis: each call will be tracked as an object. For client integration AsteriskCTI should provide a Client software that have to be installed on all the PC of the callcenter seats. The AsteriskCTI Client will be paired to the seat telephone by the phone extension number: the Client will know by its configuration which phone the server should monitors for incoming calls. When the call is answered by that phone, the paired Client will perform the actions preconfigured on the Server. This allows another reflection: not all the calls have to be notified from the server to the client: only the ones that arrive on a predetermined telephone service (this means a specified call queue).
Figure 1 - Diagram
Page 2 of 11 rev. 33
AsteriskCTI Project last save by bruno on 2009-01-04 22:42 The last part of our software is a AsteriskCTI Configurator that can be a web application that reads and store CTI configuration in a database and persists them in a XML file. This persistency file will be used then by the AsteriskCTI Server to avoid that the absence of database connection can cause crashes. Resume: 1) Asterisk PBX core telephony 2) AsteriskCTI Server use AMI to read PBX events 3) Asterisk CTI Client Connects to AsteriskCTI Server and receive incoming call notifications to popup applications or web pages 4) Asterisk CTI Configurator Used to configure services, users and variables.
Page 3 of 11 rev. 33
For each single service, you can define: the type of the context (inbound or outbound, to let the user originate calls on outbound services and lock the outbound call feature when selected an inbound context) The context name that should match the one configured on asterisk dialplan The type of application to popup when a call for this context is matched: Application for external applications; Internal Browser to popup an AsteriskCTI Browser window. Application and Parameters the path of the application to run (when type is application) and the parameters to pass. Parameters can contains variables defined in services_variables. Enabled if this context should be monitored by the Server
Each service can have zero or more variables. These are defined in services_variables. This table contains only the variables names because the value is read from the server from the dialplan! Operators are defined in the operator table and are bound to services through the service_operators table. One operator can be on zero or more services. This simple database schema should be managed from the AsteriskCTI Configurator. From the configurator it should be possible to save the runtime configuration in an XML
Page 4 of 11 rev. 33
AsteriskCTI Project last save by bruno on 2009-01-04 22:42 file. This file will persist the configuration and, as stated before, this will preserve the AsteriskCTI Server from opening database connection. The file will have to be transferred some-way to the AsteriskCTI Server. I imagine a file copy service to the AsteriskCTI server configuration directory. A filesystem watcher will then notify the server if the configuration file has changed. Once read the new configuration, and in case of no errors, the AsteriskCTI server will use the new configuration immediately.
At the startup the server will perform base checks (configuration for example) and if all is ok, will try to connect to AMI. In case of failure, the server will retry to connect for 0 to infinite times (configurable) with pause of 5 or more seconds (configurable) between each try. After successful AMI connection, the server will begin to accept client connections and spawn new threads for each client connection.
3.1.2.2 Events
All Asterisk Events are related to one or more Uniqueid: this means that we can build an object (named AsteriskCall) that store all the call information when a new Uniqueid is generated (Newchannel) and destroy that object when the call is destroyed (Hangup). All the AsteriskCall will be referenced with the Uniqueid and stored in a Hash for quick save and retrieve operations. We can parse Source and Destination of each Call and store only calls that match our registered extensions. When a CTI event is matched Page 5 of 11 rev. 33
AsteriskCTI Project last save by bruno on 2009-01-04 22:42 against a registered extension, that Event will be then notified to the right AsteriskCTI Client. Newchannel - This event always happens when a new channel is created , so it is generated everytime a call begins. When this event is intercepted by the AsteriskCTI Server Dial Someone is Dialing a call. This is the right place to intercept CallerId on calls from extensions. When a call is dialed, means that the call doesnt come from a queue. So we shouldnt check callerid on Newstate event when State is Ringing. Newstate This event reflect a asterisks call status change. When we match the State Ringing and the call has not been dialed, we can grab the CallerId and generate a Callerid event to AsteriskCTI Client. We should ever save the new AsteriskCall State. OriginateResponse This Event is generated when AsteriskCTI Client ask AsteriskCTI Server to send an Originate command to the Asterisk PBX. Asterisk PBX will parse the originate command and then will send a Response. When the Response field is Success we can generate a new AsteriskCall object with the Uniqueid and Context passed by OriginateResponse. Newexten - This event is generated everytime a new step in the dialplan is done: a new extension of type Set may contains our calldata. The AsteriskCTI Server should verify if the Application event is Set and if the Channel field match a registered extension. In this case another check is requested: AsteriskCTI Server should read AppData and split key=value pair. If key match a variable registered for the Context specified on the event, we can save AppData on the AsteriskCall Object. So when the call is notified to the AsteriskCTI Client. Link This event is important, because two calls are bound from the Asterisk PBX. Here we should notify the client if the call match registered extensions. On the Link event we receive two Uniqueid: once for the caller call and once of the called call. Hangup - When an hangup event is fired, we've to remove the call with the uniqueid matched. Events related to Queues needs to be commented watching relative Actions: Action
Action: QueueAdd Queue: astcti Interface: SIP/201 Penalty: 1 Paused: false
Dir
Response/Event
Description We ask to dinamically add an interface (phone, extension, other) on a specified queue. AsteriskCTI Server should automatically add the extension related to a user on all the queues (services) configured (see the services_operators
Page 6 of 11 rev. 33
Asterisk response is immediate: Success or Error After the response, an Event is generated: QueueMemberAdded. We can wait these events and then notify the AsteriskCTI Client that he is on that queue When AsteriskCTI Client asks to go in pause, AsteriskCTI Server will send a QueuePause command on AMI. On the Pause request, we send a PENDING PAUSE REQUESTED to AsteriskCTI Client. The Pause will be effective if Reponse is Success and after received QueueMemberPaused event.
Response: Success | Error Message: [describe success or error status] Event: QueueMemberPaused Privilege: agent,all Queue: astcti Location: SIP/201 MemberName: SIP/201 Paused: 1 Event: QueueMemberStatus Privilege: agent,all Queue: astcti Location: SIP/201 MemberName: SIP/201 Membership: dynamic Penalty: 1 CallsTaken: 0 LastCall: 0 Status: 5 Paused: 1
Asterisk response is immediate: Success or Error After the response, an Event is generated: QueueMemberPaused.
Status 5 = not available for calls, its device related. Please check here Maybe we can skip this Event?
Page 7 of 11 rev. 33
pause.
Response: Success | Error Message: [describe success or error status] Event: QueueMemberPaused Privilege: agent,all Queue: astcti Location: SIP/201 MemberName: SIP/201 Paused: 0
When AsteriskCTI Client disconnects from AstCTI Server for any reason, we should dynamically remove the associated interface from queues.
Response: Success | Error Message: [describe success or error status] Event: QueueMemberRemoved Privilege: agent,all Queue: astcti Location: SIP/201 MemberName: SIP/201
3.1.2.3 Commands
QueueAdd This command is used to dynamically add extensions on queues. Example:
Action: QueueAdd Queue: [queue-name] Interface: [technology/extension] (ex. SIP/200) Penalty: [operator penalty] Paused: [true/false] if the interface is initially paused
With this command AsteriskCTI Server can dynamically login callcenter operators on the configured queues. QueueRemove With this command AsteriskCTI should remove callcenter operators on AsteriskCTI request or disconnect.
Action: QueueRemove Queue: [queue-name] Interface: [technology/extension] (ex. SIP/200)
QueuePause This command will be used to pause / unpause an operator. Queue parameter is optional and infact we dont need to specify for our purpose: when omitted, the operator will be paused in all queue he belongs to.
Action: QueuePause
Page 8 of 11 rev. 33
Originate TODO
USER [username]
This will begin the handshake process The Client sends the Username and wait for a response If the Command has completed successfully on server If the Command has not successfully completed on server.
PASS [md5pass]
100 OK
101 KO [reason]
The client sends an md5 encrypted password to the server The server authenticated successfully the client. The AsteriskCTI Server should dynamically add the extension associated with the client on all services configured If the Command has not successfully completed on server.
102 OK
101 KO [reason]
AsteriskCTI Project last save by bruno on 2009-01-04 22:42 The Server sends this response and then 900 OK close the TCP connection Keepalive The Client should send this command to keep alive connection avoiding socket timeout. If the server will not receive a NOOP command at predefined (configurable) time, the socket will be closed This is sent before the AsteriskCTI Server close the connection to the client.
NOOP
100 OK
Originate (let the client originate a call from asterisk server) The client will ask the AsteriskCTI server to generate an Originate command on the Asterisk Server. The Originate command need to know Extension (exten=number to call) on the specified context (cntxt) with the specified priority (usually 1) If the AsteriskCTI server successfully send data to asterisk server. If some parameter is missing or unsuccessful communication with asterisk server.
ORIG exten|cntx t |p r i o
100 OK
101 KO [reason]
Avaiable on queues
200 [queuename]
AsteriskCTI Server notify the client that he is available on a specified queue (service).
AsteriskCTI Client request a pause AsteriskCTI Server have submitted pause request to AMI. Pause accorded There was an error
PAUSE OUT
Page 10 of 11 rev. 33
Example:
<event id="Newchannel"> <call> <uniqueid>1094154427.10</uniqueid> <channel>SIP/101-3f3f </channel> <calleridnum>102</calleridnum> <calleridname>Demo 2</calleridname> <context>asteriskcti-demo</context> <appdata> <data key=""></data> </appdata> <state>Ringing</state> </call> </event>
3.2.1 GUI
[to fill]
Page 11 of 11 rev. 33