- Preface
- About
- Technical details
- Install
- Configuration
5.1. Realtime
5.2. General - Command Line Interface
6.1. Debug
6.2. Notify
6.3. Reload
6.4. Show subscription
6.5. Status
##Preface I started this work mostly to get better understanding of Asterisk development environment and learn how to develop Asterisk modules. The task can be solved with bash or perl scripts using some additional tools like sipsak and Asterisk voicemail configuration "externnotify" parameter. But this will take additional tricks like making database connection within script while module is using Asterisk realtime functions. Also module logs additional debug information to Asterisk log files which facilitates debugging. Additionally, module has command line interface which allows to test functionality and can be used as an interface for external scripts.
##About This is Asterisk module is developed in frames of Modulis VoIP platform Zonkey. The module is a part of integration of OpenSIPS with Asterisk servers to facilitate MWI notification via OpenSIPS to destination user agent clients (phones). The idea of Zonkey platform resembles concept described in OpenSIPS tutorial Realtime OpenSIPS - Asterisk Integration. The main difference is that there is no realtime sip peers integration. Actualy, Asterisk media servers do not need to know about sip peers to provide media services like voice mail or IVR. All communication is going through OpenSIPS and access to SIP port of Asterisk should be restricted to only OpenSIPS server IP. Following flow chart should make it more clear:
This is not SIP message flow, so there is no request/response messages as they appear in SIP transactions.
- F1: When registering to system, UAC (phone) subscribes to OpenSIPS to event "message-summary".
- F2: OpenSIPS stores presentity information into DataBase. Usually done by
handle_publish
function from "presence" module. - F3: Someone calls to user registered in OpenSIPS.
- F4: When user is not available or busy, OpenSIPS sends call to one of the Asterisk Voicemail servers with load_balancer module.
- F5: Asterisk send incoming call to Voicemail application, saves message. Asterisk core event system will publish mwi event which is available for modules subscribed to that event. Module res_zonkey_mwi subscribes to that event when loaded.
- F6: Module will get information about user and context from event and send request to DataBase to get subscription data: call-id, to tag, from tag, cseq number etc.
- F7: Module will generate NOTIFY message using these data, opens socket and send this NOTIFY packet to OpenSIPS.
- F8: OpenSIPS recieves NOTIFY and will send NOTIFY to UAC IP from location stored in OpenSIPS memory for user registration.
When module is loaded, it subscribes to Asterik core event AST_EVENT_MWI and register call-back function "zonkey_mwi_cb". This function will be called whenever Asterisk read/store user's voicemail. Then function extracts user mailbox and context value from received publish event from Asterisk and uses these values to get subscription data from OpenSIPS database table "active_watchers". To get this data module uses Asterisk realtime functions. How to configure module with Asterisk realtime see in configuration section.
If subscription data is found, then it stores values like to-tag, from-tag, call-id etc. into the internal structure "subscription". Then generates NOTIFY packet (function notify_create) using these data. Finally, it creates UDP socket and send packet to OpenSIPS.
Now, why to create local socket? The point that Asterisk, up to version 11, has pretty monolithic and close SIP channel. Unfortunately, There is no API to SIP channel that would allow using Asterisk sockets and generating SIP packets. This should change in version 12 where Asterisk will use PJSIP framework. Right now, to use SIP you have to both change core channel chan_sip and add your functions (see sip_info module for example) or to write your own functionality in your module.
Module res_zonkey_mwi uses only one packet NOTIFY so it is easier to use local network socket. Besides, header file netsock2.h provides nice functions for that and really simplify socket programming. See module function "send_notify" for implementation details.
For the sake of simplicity this module sends NOTIFY packet and that’s it. The implementation compliant with rfc3261 should account responses and do packet retransmissions but this would implicate much more sophisticated implementation. So for now I keep it like this and may be will change it in version for Asterisk 12 which should provide API for that.
git clone git@github.com:staskobzar/res_zonkey_mwi.git
cd res_zonkey_mwi/
make && make install
Load module to Asterisk with command:
module load res_zonkey_mwi.so
or restart Asterisk.
##Configuration Module requires realtime connection configured with OpenSIPS table "active_watchers". Also module comes with default configuration file "zonkeymwi.conf". Install will copy this file to "/etc/asterisk/" directory.
###Realtime Realtime if configured as any other realtime configuration in "extconfig.conf" file. Add the line to configure your realtime family. For example:
zonkeymwi => odbc,opensips,active_watchers
You can use any engine (odbc, mysql, postgres etc) supported by Asterisk realtime.
Reload Asterisk configuration with command core reload
or restart. Then run the command in Asterisk CLI:
asterisk*CLI> zonkeymwi status
If everything is ok and module recognizes realtime, then you should see output like this: Module ENABLED
.
###General General configuration file comes with examples of configuration parameters. Required parameter is only one: proxy. It must contain IP address or host name of OpenSIPS proxy and port separated by column ":". For example:
proxy=232.233.10.1:5060
or
proxy=proxy.opensips.org:5060
Next option is setting IP address or host of Asterisk which will be used in Contact and Via headers of NOTIFY packet. If this parameter is not set then local loop address will be used 127.0.0.1. Setting example:
bindip=101.102.103.1
Another option is value of User-Agent header of SIP packet. Default value is "Asterisk". Example:
useragent=Asterisk Media Server01
Next is user part of Contact URI. Contact header field will contain this value and "bindip" value as URI domain part. Default value "asterisk". Example of parameter setting is:
contactuser=voicemail-user
With this configuration Contact field will look like this:
Contact: <voicemail-user@101.102.103.1
And last parameter is Voicemail extension. It is user in NOTIFY body header "Message-Account". Example:
vmexten=*97
When done, send command in Asterisk CLI:
zonkeymwi reload
Check Asterisk log file which should have in output line like this:
[2013-12-27 16:51:49] DEBUG[4029] res_zonkey_mwi.c: Module values: proxy=232.233.10.1:5060; bindip=101.102.103.1, useragent=Asterisk Media Server01; contactuser=voicemail-user; vmexten=*97
Module comes with several CLI commands that can be helpful to debug module work.
###Debug
Enable/Disable debugging with command zonkeymwi debug <param>
. Parameter can be "on" or "off". If debug is on then module will send to output generated NOTIFY packet. Command example:
asterisk*CLI> zonkeymwi debug on
Debug enabled.
###Notify Command "notify" will send NOTIFY to given user in domain with number of new and old voicemail messages. Command usage:
zonkeymwi notify <user> <domain> <msgnew> <msgold>
This will get data from realtime for given user, domain then generate and send NOTIFY packet to proxy. Below is example of command with debug enabled:
asterisk*CLI> zonkeymwi notify 202 domain.example.com 3 5
Notify 202@domain.example.com with 3 new messages and 5 old messages was sent
DEBUG------------------>
NOTIFY sip:202@domain.example.com SIP/2.0
Via: SIP/2.0/UDP 101.102.103.1;branch=z9hG4bK0caac598
To: sip:202@domain.example.com;tag=944cfec2ae51664c1f4ff1ec5d501247-9753
From: sip:202@domain.example.com;tag=B22C69FD-D3E2550A
Date: Thu, 26 Nov 2013 22:04:22 GMT
Call-id: 43abd53c-c0f8fbdd-c6ba116a@232.133.10.1
CSeq: 149 NOTIFY
Contact: <sip:voicemail-user@101.102.103.1>
User-Agent: Asterisk Media Server01
Event: message-summary
Subscription-State: active
Content-Type: application/simple-message-summary
Content-Length: 104
Messages-Waiting: yes
Message-Account: sip:*97@domain.example.com
Voice-Message: 3/5 (0/0)
DEBUG<------------------
###Reload Command "reload" will reload configuration file if changes found. Example:
zonkeymwi reload
###Show subscription Get and output subscription data. Command parameters are user and domain. Usage example:
asterisk*CLI> zonkeymwi show subscription 202 domain.example.com
MWI subscription details for 202@office.modulis.clusterpbx.ca:
To tag: 944cfec2ae51664c1f4ff1ec5d501247-9753
From tag: B22C69FD-D3E2550A
Call-ID: 43abd53c-c0f8fbdd-c6ba116a@101.102.103.1
Expires: 1388099275
CSeq: 149
###Status Command "status" shows if module enabled or disabled. Example:
asterisk*CLI> zonkeymwi status
Module ENABLED