Skip to content
zlu edited this page Jan 5, 2011 · 38 revisions

new ec2 instance: uat (user acceptance testing)
login with googlegroups credential for orange-status@googlegroups.com

ssh access: ssh -i config/keys/orange-status.pem ubuntu@ec2-50-16-198-91.compute-1.amazonaws.com

Install passenger with nginx support:

rvm ree@status-server
gem install passenger
rvmsudo passenger-install-nginx-module

Created Ngnix upstart script under /etc/init/ngnix.conf:

description "nginx http daemon"
start on runlevel 2
stop on runlevel [016]
console output
exec /opt/ngnix/sbin/nginx -c /opt/nginx/conf/nginx.conf  -g "daemon off;"
respawn

Created Ngnix config under /opt/nginx/conf/ngnix.conf:

two things in this config:
first is the passenger definition which should be generated with the correct gemset status-server if we use this command: rvm wrapper reestatus-server passenger

http {
    passenger_root /home/ubuntu/.rvm/gems/ree-1.8.7-2010.02/gems/passenger-3.0.2;
    passenger_ruby /home/ubuntu/.rvm/wrappers/ree-1.8.7-2010.02@status-server/ruby;

and
  server  {
             listen 80;
             server_name localhost;
             root /var/www/status-server/current/public;
             passenger_enabled on;
             rails_env uat;
      }

Setting up RDS with the default security group allowing default ec2 security group access.

New multistage capistrano deployment scripts (TODO clean up the script)

voicemail subsystem:
creating new gemset
balboa:~/workspace $ rvm ree
balboa:~/workspace $ rvm gemset create voicemail
‘voicemail’ gemset created (/Users/pivotal/.rvm/gems/ree-1.8.7-2010.02@voicemail).
balboa:~/workspace $ rvm gemset use voicemail
Now using gemset ‘voicemail’

$ rails new voicemail -J -T

skipping jquery -J
skipping testunit -T

we use jquery and rspec for this project

===================

System Diagram

Amazon

Using EC2 @ http://aws.amazon.com to deploy the Adhearsion/Asterisk/Rails application server.
EC2’s elastic IP: 174.129.215.197

Amazon Access Keys

  • Account #: 136724391213
  • Access Key: AKIAJRXIWPHZH6ICEN4A
  • Access Pass: BIhzEoqhntop+F0gQ5eggWy2LthrnDzgALUHtsjs
  • Private Key: /root/.ec2/pk-RNTWAIA3QREJJAWMFJSPM34JYMA7TOY4.pem
  • Certificate: /root/.ec2/cert-RNTWAIA3QREJJAWMFJSPM34JYMA7TOY4.pem

Amazon Machine Image (AMI)

Current image: ami-2bbc5d42 (zlu-ec2-images/asterisk-ahn-rails-1_3.manifest.xml)

To create a new image if you have changed the configuration of the Ubuntu server is to modify the /root/bin/image.sh file to reflect the new image version (ie – BUNDLE_NAME=asterisk-ahn-rails-1_3). Then, simply run the script to bundle, push to S3 and then register the new image as an AMI.

Booting the image

Go to the aws web console, go to AMIs, view images owned by me, select the latest image to boot from. Boot the image from east-1b (availability zone in advanced options) because it is where our elastic block storage is at.

After booting the image

  • We need to load the Elastic Block Storage volume (/vol)
    • Assign Elastic IP – Run /etc/init.d/assignip2instance.sh start
    • Mount Volume – Run /etc/init.d/mountec2vol.sh start (You may have to re-login as the ip has changed)
    • Start MySQL with /etc/init.d/mysql start
    • Make sure asterisk, nginx, ahn, and rails are started, to start them use:
  • These should start automatically with update-rc.d
    • monit start asterisk
    • monit start nginx
  • These may need to be started manually
    • monit start adhearsion
    • Rails is started by NGINX/Passenger, no extra step

Configuration

Firewall (Security Groups on the Amazon WS Management Portal)

  • Asterisk ports
    • SIP – 5060
    • RTP – 20001 through 21000 (defined in /etc/asterisk/rtp.conf)
  • Rails ports
    • HTTP – 80/443 (80 will forward to 443 for HTTPS)
  • Other ports
    • SSH – 22

Zone

  • east-1b (Server and EBS must be in same zone)

Nginx

Installation

The installation by Passenger does not automatically support SSL. Therefore, when installing you need to do the following:

  • Download and untar the source code for NGINX
  • gem install passenger
  • passenger-install-nginx-module
  • Select option 2 to customize the installation
  • Give it the location of the source code you downloaded
  • Then give it the custom option —with-http_ssl_module

Original post here.

Configuration


file: /opt/nginx/conf/nginx.conf
   #rewrite for http to https is not yet working correctly 
   server {
           listen               80;
           server_name          phonestat.com;
           rewrite              ^(.*)$ https://phonestat.com$1 permanent;
    }

    server {
           server_name          phonestat.com;
           listen               443;
           ssl                  on;
           ssl_certificate      /vol/data/ssl/phonestat_combined.crt;
           ssl_certificate_key  /vol/data/ssl/phonestat.com.key;
           include              phonestat.conf;
    }

This creates 2 locations in the server. The first location serves the rails app using passenger; the second application serves static voicemail files.

Asterisk

Installed as a deb package on Ubuntu Jaunty.

Installation

Install:

  • apt-get install asterisk
  • apt-get install asterisk-mp3 (if you want MP3 playback support)

Configuration

After installation, you must configure these three files:

  • sip.conf
    • This controls your SIP users (aka – XLite/SJPhone)
    • Also controls your SIP trunks (aka – Flowroute)
    • SIP runs by default on port 5060, so this must be open in the firewall/security group settings
    • Pay attention to your NAT configuration here, need to have externip, localnet and nat=yes set
  • extension.conf
    • This is the Asterisk dialplan, all it should do is call an AGI to Adhearsion:

[adhearsion]
exten => _X.,1,AGI(agi://localhost)
exten => _X.,n,Hangup
  • rtp.conf
    • This controls the ports that are open for the audio channels (Real Time Control Protocol)
    • These ports must also be opened in the firewall/security group settings
    • Generally calculate two ports per simultaneous call to determine the number of ports to configured in this file

SIP Phone Setup and Testing

Notes

  • Asterisk may playback MP3, but not encode MP3, hence why we use wavs in the system.
  • Set UMASK to 022 in /etc/init.d/asterisk so that audio files are readable by NGINX

Text to Speech

The Adhearsion component will speak back the text status if the voice status is not present. For this, we use the Festival open source text to speech engine.

Installation

This is available as a package on Ubuntu:

  • apt-get install festival

Installs Festival and the command line utility text2wav which is used by Adhearsion for TTS.

Use


methods_for :global do
  # It generates an audio file based on a given text status
  # @param [String] the text status to be converted to an audio file
  # @return [String] the file_name of the audio file
  def generate_tts_file(text_status)
    text_status = sprintf("%p", text_status)
    file_name = '/tmp/' + new_guid
    system("echo \"#{text_status}\" | text2wave -o #{ file_name + '.ulaw' } -otype ulaw")
    ahn_log.play_vm_greeting.debug file_name
    file_name
  end
end

Adhearsion

Best to install the master branch from Github known as ‘EDGE’.

Installation

You may install the latest release version, from Rubyforge, as ‘gem install adhearsion’.

Edge v.s. Gem

The recommend way is to do the following:

  • git clone http://github.com/jicksta/adhearsion.git
  • cd into the ~/adhearsion directory
  • rake package
  • gem install pkg/adhearsion{…}.gem

Configuration

The main configuration file is in ~/ahn-project/config/startup.rb. Details may be found here:

Startup.rb on Adhearsion Wiki

Start/Stop Adhearsion

monit adhearsion {start, stop}

More info on Adhearsion

Flowroute

Flowroute is the service provider that gives us the phone number to forward redirected calls to our Asterisk server on Amazon/Asterisk. This works by configuring Asterisk in sip.conf to connect to the provider.

Configuration

  • sip.conf

[general]
register => 70251933:SWF0YmXURGdp@sip.flowroute.com

;Trunks - outbound and inbound to other networks
[flowroute] ;keep this lowercase, do not change format
type=friend
secret=SWF0YmXURGdp
username=70251933
host=sip.flowroute.com
dtmfmode=rfc2833
context=adhearsion ;change to 'ext-did' or 'from-trunk' for asterisk@home
canreinvite=no
disallow=all
allow=ulaw
allow=g729
insecure=port,invite
qualify=yes

Phone Number

  • +1.415.534.0223

Status – Server

User Authentication and SSL

  • Audio conversion: mpeg4 to gsm formatted wav for voicemail greetings

Status – Android Client

Audio Conversion Process

The audio on the Android client is recorded in MP4 or 3GP formats. These are video formats not supported by Asterisk directly. Therefore we must both extract the audio channel from these files as well as convert them to gsm/wav. We use FFMPEG for both the audio extraction and conversion. The standard FFMPEG on Ubuntu does not have direct MP3, 3GP or GSM support. Therefore we must compile and install as follows:

Installing AMR libraries:
Grab the AMR Codec Libraries (The FFmpeg documentation has a section about installing AMR):
e.g. amrnb-6.1.0.4.tar.bz2 and amrwb-7.0.0.1.tar.bz2
Decompress sources:
bunzip2 amrnb-6.1.0.4.tar.bz2
tar xvf amrnb-6.1.0.4.tar
Change directory:
cd amrnb-6.1.0.4
Configure and install:
./configure
make
checkinstall -install=yes
Repeat same steps 2,3 and 4 for amrwb-7.0.0.1.tar.bz2
Type in ldconfig as sudo user to ensure the new modules are available when running ffmpeg
Howto install x264/ffmpeg:

http://ubuntuforums.org/showthread.php?t=786095

- Note: Except for the line on the ./configure for ffmpeg, should be this (adding support for AMR/3GP and GSM):

./configure --enable-gpl --enable-nonfree --enable-pthreads --enable-libfaac --enable-libfaad --enable-libmp3lame --enable-libtheora --enable-libx264 --enable-libxvid --enable-x11grab --enable-libamr-nb --enable-libamr-wb --enable-libgsm

Command for mp4 (Android) to gsm (works for 3gp or mp4 formats):

ffmpeg -i input.3gp -f gsm input.wav

Then, in the Adhearsion component we do the conversion as follows:


      if user
        file = env["rack.input"]
        new_file = "/vol/recordings/greetings/#{user_id}_#{Time.now.to_i}"
        new_path = new_file +".mp4"
        convert_to_file = new_file + ".wav"
        system_cmd = "ffmpeg -i #{new_path} -f gsm #{convert_to_file}"
        p system_cmd
              tempfile = req.POST["file"][:tempfile]
        FileUtils.mv tempfile.path, new_path
        system(system_cmd)
        #File.open(new_path, "w+") { |fh| fh.write(env["rack.request.form_hash"]["file"]) }
              user.update_status_with_recording :recording_path => new_file
        [200, {"Content-Type" => "text/html"}, ["Voice status file: (#{file.read.size} bytes)"]]

Logging with Splunk
// TODO document how to use splunk

User and Groups

teresa:teresa teresa is specified as a sudoer in /etc/sudoers:


# /etc/sudoers
# User privilege specification
root    ALL=(ALL) ALL
teresa  ALL=(ALL) ALL

adhearsion and rails run as teresa

asterisk:asterisk
nginx:nginx