Friday, September 21, 2012

Installing Asterisk 10.8.0 on CentOS 6.3 (64-bit)

The book “Asterisk: The Definitive Guide 3rd Edition” describes installing Asterisk 1.8.x.  This is my attempt to go through the installation instructions and adapt them for an Asterisk 10.8.0 install.  I assume you have CentOS 6.3 installed already and updated (yum update).

This guide follows the book’s installation type.  We will not be installing a pre-built package, but will be installing from the source code.  You can find package installation instructions at http://www.asterisk.org/downloads/yum.  Note that the packages are not always up to date and the book recommends installing the latest version from source.

Note 1: I am relatively new to Linux and completely new to Asterisk.  Perhaps this guide will help someone else perform the same operation I am doing, but this is mainly to chronicle my installation so that I can easily repeat it if necessary.

Note 2: For the purposes of this install, I have removed the “sudo” commands and will run all the commands as root (su –).

Remove any 32-bit libraries, perform a system update and reboot:

yum remove *.i386

image

yum update –y

image

# Reboot system if any updates were installed
reboot

Synchronize time and install the NTP (Network Time Protocol) daemon:

# Verify ntp daemon is installed
yum install –y ntp

image

# Set the current date/time from pool.ntp.org
ntpdate pool.ntp.org

# Verify ntp daemon runs at system startup
chkconfig ntpd on

# Start the NTP daemon
service ntpd start

image

Add a new system user “asteriskpbx”:

adduser asteriskpbx

passwd asteriskpbx

image

# Install sudo if not already present
yum install sudo

# Edit the /etc/sudoers file and add ‘asteriskpbx’
visudo

# NOTE: I added the entry manually using the following
echo 'asteriskpbx ALL=(ALL) ALL' >> /etc/sudoers

image

# Also add an entry for the group “wheel”
echo '%wheel ALL=(ALL) ALL' >> /etc/sudoers

# Edit /etc/group file and modify the line that starts
# with wheel so it reads: wheel:x:10:root,asteriskpbx

Install software dependencies:

yum install gcc.x86_64 gcc-c++.x86_64 make.x86_64 wget.x86_64 subversion.x86_64 libxml2-devel.x86_64 ncurses-devel.x86_64 openssl-devel.x86_64 vim-enhanced.x86_64

image

Create directory structure:

mkdir -p ~/src/asterisk-complete/asterisk

cd ~/src/asterisk-complete/asterisk

Check out the source code with Subversion (we will check out using a specific tag, 10.8.0)

svn co http://svn.asterisk.org/svn/asterisk/tags/10.8.0

image

(NEW) Install the SQLite3 development package:

yum install sqlite-devel.x86_64

To support Google Talk, install ikseml by downloading it from http://code.google.com/p/iksemel/

wget http://iksemel.googlecode.com/files/iksemel-1.4.tar.gz

tar -xvzf iksemel-1.4.tar.gz

cd ~/src/iksemel-1.4

./configure

make

make install

Build and install the software:

cd ~/src/asterisk-complete/asterisk/10.8.0

./configure

make

make install

make config

To install the asterisk program documentation (optional, requires doxygen):

# Verify doxygen is installed (for me, it was already)
yum install doxygen

make progdocs

Install additional sound prompts from menuselect:

cd ~/src/asterisk-complete/asterisk/10.8.0/

make menuselect

make install

Modify file permissions of the folders Asterisk was installed to:

chown -R asteriskpbx:asteriskpbx /usr/lib/asterisk/
chown -R asteriskpbx:asteriskpbx /var/lib/asterisk/
chown -R asteriskpbx:asteriskpbx /var/spool/asterisk/
chown -R asteriskpbx:asteriskpbx /var/log/asterisk/
chown -R asteriskpbx:asteriskpbx /var/run/asterisk/
chown asteriskpbx:asteriskpbx /usr/sbin/asterisk

On CentOS, disable SELinux:

# Change the value of SELINUX from enforcing to disabled, then REBOOT
nano /etc/selinux/config

Create the /etc/asterisk/ directory and copy the indications.conf sample file into it:

mkdir -p /etc/asterisk

chown asteriskpbx:asteriskpbx /etc/asterisk

cd /etc/asterisk/

cp ~/src/asterisk-complete/asterisk/10.8.0/configs/indications.conf.sample ./indications.conf

Copy the sample asterisk.conf file into /etc/asterisk and uncomment and change runuser= and rungroup= to asteriskpbx:

cp ~/src/asterisk-complete/asterisk/10.8.0/configs/asterisk.conf.sample /etc/asterisk/asterisk.conf

nano /etc/asterisk/asterisk.conf

Create the modules.conf file. Enable loading of modules automatically, and disable extra modules:

$ cat >> /etc/asterisk/modules.conf
; The modules.conf file, used to define which modules
; Asterisk should load (or not load).
;
[modules]
autoload=yes
; Resource modules currently not needed
noload => res_speech.so
noload => res_phoneprov.so
noload => res_ael_share.so
noload => res_clialiases.so
noload => res_adsi.so
; PBX modules currently not needed
noload => pbx_ael.so
noload => pbx_dundi.so
; Channel modules currently not needed
noload => chan_oss.so
noload => chan_mgcp.so
noload => chan_skinny.so
noload => chan_phone.so
noload => chan_agent.so
noload => chan_unistim.so
noload => chan_alsa.so
; Application modules currently not needed
noload => app_nbscat.so
noload => app_amd.so
noload => app_minivm.so
noload => app_zapateller.so
noload => app_ices.so
noload => app_sendtext.so
noload => app_speech_utils.so
noload => app_mp3.so
noload => app_flash.so
noload => app_getcpeid.so
noload => app_setcallerid.so
noload => app_adsiprog.so
noload => app_forkcdr.so
noload => app_sms.so
noload => app_morsecode.so
noload => app_followme.so
noload => app_url.so
noload => app_alarmreceiver.so
noload => app_disa.so
noload => app_dahdiras.so
noload => app_senddtmf.so
noload => app_sayunixtime.so
noload => app_test.so
noload => app_externalivr.so
noload => app_image.so
noload => app_dictate.so
noload => app_festival.so

[CTRL+D]

Configure musiconhold.conf:

$ cat >> musiconhold.conf
; musiconhold.conf
[default]
mode=files
directory=moh

[CTRL+D]

At this point the system should be ready to configure the dialplan and channels.  First, log out and then log in as asteriskpbx.  Enter the following command to ensure you have sudo access:

sudo ls /root/

Finally, to make life easier, include /usr/sbin and /sbin in the PATH variable for asteriskpbx.  Edit the file with nano or something similar.

# change PATH=$PATH:$HOME/bin to PATH=$PATH:$HOME/bin:/usr/sbin:/sbin
nano .bash_profile

At this point Asterisk looks to be installed successfully.  I will blog again with any updates.  I will be working on getting this working with our PBX at work (and my VOIP phone) and with Google Talk and with Skype.

Installing FireFox 15 (or latest version) on CentOS 6.3 (or 6.x) via yum

Distilled from http://www.if-not-true-then-false.com/2011/install-firefox-on-fedora-centos-red-hat-rhel/

(Optional) Backup current FireFox profiles

tar -cvzf $HOME/mozilla-firefox-profiles-backup.tar.gz $HOME/.mozilla/firefox/

Change to root user

su -

Install Remi repository

rpm -Uvh http://download.fedoraproject.org/pub/epel/6/i386/epel-release-6-7.noarch.rpm
rpm -Uvh http://rpms.famillecollet.com/enterprise/remi-release-6.rpm

(Optional) Check for available versions

yum --enablerepo=remi list firefox

If you already have an older version of FireFox installed, then UPDATE

yum --enablerepo=remi update firefox

Otherwise INSTALL

yum --enablerepo=remi install firefox

Done!

Thursday, September 20, 2012

Installing VirtualBox Linux Guest Additions for CentOS 6.3

To install the VM Guest Additions for VirtualBox 4.1.22 on CentOS 6.3, I worked through the instructions found at http://wiki.centos.org/HowTos/Virtualization/VirtualBox/CentOSguest

As detailed at http://wiki.centos.org/AdditionalResources/Repositories/RPMForge we must install RPMforge first, so we can install the DKMS (Dynamic Kernel Module Support) required by the Virtual Box Linux Additions.

The following must be done with root privileges. I logged in as root for this operation.

Install RPMforge

wget http://packages.sw.be/rpmforge-release/rpmforge-release-0.5.2-2.el6.rf.x86_64.rpm

rpm --import http://apt.sw.be/RPM-GPG-KEY.dag.txt

rpm -K rpmforge-release-0.5.2-2.el6.rf.x86_64.rpm

rpm -i rpmforge-release-0.5.2-2.el6.rf.x86_64.rpm

Install DKMS (Dynamic Kernel Module Support)

yum --enablerepo rpmforge install dkms

Ensure the development environment and kernel source are installed

yum groupinstall "Development Tools"

yum install kernel-devel

Install Guest Additions

In VirtualBox, under the Devices menu, select the VBoxGuestAdditions.iso image for the CD/DVD drive.  The autorun should execute and you should be able to install it from there.  If the autorun does not kick in, go to a terminal prompt and CD to the mountpoint and issue the command:

./VBoxLinuxAdditions.run

image

Once I performed those actions, I logged out of root and logged in under my own account.  The mouse no longer needed to be captured by the virtual machine.  You can resize the Virtual Box window and the CentOS desktop will resize.  Much better.

Wednesday, September 19, 2012

Console Progress/Status Output and Clear To End Of Line (EOL) (VB.NET)

When writing a .NET Console application, I sometimes have long-running processes for which I like to see status information displayed.  I could simply issue WriteLine statements and have the console window continuously scroll text, but I much prefer information to be displayed and updated in a single location.  Traditionally, what you would do is write some text (of length N) and then write N Ctrl-H characters (Backspace) which moves the cursor back to where it started.  Then when you write again, it overwrites the previous text.  Though, if the new text is shorter than the previous text, you end up with those extra characters – so what you want to do is write your text and then “clear to end of line” (EOL).  I finally got around to implementing that.

There are various ways to tackle this, but I use a couple functions: CONSOLE__WRITE to display text and backspace the cursor to where it started, and CONSOLE__CLEAR_EOL which clears text to the end of the line.  Actually, I incorporated the CONSOLE__CLEAR_EOL as an optional (default True) parameter to CONSOLE__WRITE.

Here are the routines..

    Public Sub CONSOLE__WRITE(ByRef szText As String, Optional ByVal bClearEOL As Boolean = True)
        'Output the text
        Console.Write(szText)
        'Optionally clear to end of line (EOL)
        If bClearEOL Then CONSOLE__CLEAR_EOL()
        'Move cursor back to where we started, using Backspaces
        Console.Write(Microsoft.VisualBasic.StrDup(szText.Length(), Chr(8)))
    End Sub
 
    Public Sub CONSOLE__CLEAR_EOL()
        'Clear to End of line (EOL)
        'Save window and cursor positions
        Dim x As Integer = Console.CursorLeft
        Dim y As Integer = Console.CursorTop
        Dim wx As Integer = Console.WindowLeft
        Dim wy As Integer = Console.WindowTop
        'Write spaces until end of buffer width
        Console.Write(Space(Console.BufferWidth - x))
        'Restore window and cursor position
        Console.SetWindowPosition(wx, wy)
        Console.SetCursorPosition(x, y)
    End Sub

Here is a little test program…

image

Here is a sample of it running..

image

And when it has completed..

image

Thursday, August 30, 2012

Juice Fasting

(click image to enlarge)

2012-08-30_133952_JuiceFasting

Well, I am getting ready for a real juice fast.  I have been reading and hearing (movies, documentaries) for over a couple years.  I’ve juiced like this before but never gone on a fast.  Last year, after my wife and I married and returned from our honeymoon in Aruba, we are 100% raw food for a month.

Now I am interested in a juice fast, only drinking vegetable+fruit juices for 30 days; more if I feel like I am on a roll.  For the most part I am pretty lean, but I would like to drop the excess adipose fat and then concentrate on building more muscle.  Exercise make ‘em grow, nutrition make ‘em show!

Some of the documentaries I have watched include “Fat, Sick and Nearly Dead (2010)”, “Food Matters (2008)”, “Forks over Knives (2011)”, “Raw For Life (2007)”, “Simply Raw (2009)” and plenty of others like “Super Size Me (2004)” as well as a generous helping of Dan “The Man” on YouTube (life regenerator!) – including a couple of his CD’s “Raw Kitchen Essentials” and “Life Saving Salads & Dressings”.

My tools of choice are a Vitamix 5200 ($450) and a Breville 800JEXL ($300).

Wednesday, August 29, 2012

from Doug Casey on the 'Worsening Storm,' QE3 and the Hard Assets Alliance

Daily Bell: Can government be cut?

Doug Casey: No, I don't think so, because people have become too reliant on it. Americans are no longer self-reliant frontiersmen; they're now mostly dependent, inert and overweight consumers. You never hear people referred to as "producers," just as "consumers" − as if that were a good thing. The government is a major factor in their lives, and they like it. You can't cut Social Security because a huge swath of Americans are living on it and most retirees have no other assets or income.

http://www.thedailybell.com/4217/Anthony-Wile-Doug-Casey-on-the-Worsening-Storm-QE3-and-the-Hard-Assets-Alliance

Tuesday, August 28, 2012

Parsing URL query string in your web page (JavaScript)

This is a quick function I wrote that will parse out the query string name=value pairs and return an object with those names defined.  If no query parameters were supplied, the function returns undefined.

   1:  function getDocumentQueryVariables() {
   2:   
   3:      // Return undefined if there are no query variables
   4:      if (window.location.search.length == 0)
   5:          return undefined;
   6:      var objVars = {};
   7:      var vars = window.location.search.substring(1).split('&');
   8:      for (var i = 0; i < vars.length; i++) {
   9:          var pair = vars[i].split('=');
  10:          if(pair.length == 2) {
  11:              objVars[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1]);
  12:          }
  13:      }
  14:      return objVars;
  15:  }

For example, you could have “?search=something” at the end of your web page.  This function will pass back an object with a property called “search” set to whatever value was supplied.

For example

   1:      // Exit if there's no query variable(s)
   2:      var Q = getDocumentQueryVariables();
   3:      if (Q === undefined)
   4:          return;
   5:   
   6:      // Perform search if we have one
   7:      if (Q.search) {
   8:          
   9:      }

Bug-Out Bag

• Food
• Water and water filters
• Emergency medicine
• Light sources
• Blankets and thermal protection
• Firearms and self defense gear
• Radio and communications gear
• Extra fuel for vehicles
• Maps and navigation aids
• Spare cash
• Important documents such as passports
• Personal hygiene items such as soap, toothpaste, etc.
• Spare clothing and quality shoes (NO FLIP FLOPS!)

http://www.naturalnews.com/036966_Hurricane_Isaac_preparedness_Bug_Out_Bag.html

Friday, June 1, 2012

World of Tanks

This is a really cool game, and it’s free (unless you want some perks, then you can buy in-game gold, but that’s not necessary.)  This hilarious fan video gives an idea of what the gameplay is like.

http://www.WorldOfTanks.com

World of Tanks

Tuesday, May 1, 2012

Generic Scalar And List type SQL Select Function (VB.NET)

Here are a couple of utility functions I wrote to select basic types from a database, given that you have an open SqlConnection object. 

SqlSelect returns a single element of the specified type.

   1:      Public Function SqlSelect(Of T)(ByVal CN As SqlConnection, ByVal szSQL As String, ByRef szError As String) As T
   2:   
   3:          Dim T_value As T
   4:   
   5:          szError = String.Empty
   6:   
   7:          Try
   8:              Using sqlCmd As SqlCommand = New SqlCommand(szSQL, CN)
   9:                  T_value = CType(sqlCmd.ExecuteScalar(), T)
  10:              End Using
  11:          Catch ex As Exception
  12:              szError = ex.Message()
  13:          End Try
  14:   
  15:          Return T_value
  16:   
  17:      End Function

 

SqlSelectList returns a List of the specified type.

   1:      Public Function SqlSelectList(Of T)(ByVal CN As SqlConnection, ByVal szSQL As String, ByRef szError As String) As List(Of T)
   2:   
   3:          Dim T_LIST As New List(Of T)
   4:          szError = String.Empty
   5:   
   6:          Try
   7:              Using sqlCmd As SqlCommand = New SqlCommand(szSQL, CN)
   8:   
   9:                  Dim sqlReader As SqlDataReader = sqlCmd.ExecuteReader()
  10:                  If sqlReader.HasRows() = True Then
  11:                      Do While sqlReader.Read() = True
  12:                          T_LIST.Add(CType(sqlReader.GetValue(0), T))
  13:                      Loop
  14:                  End If
  15:                  sqlReader.Close()
  16:   
  17:              End Using
  18:          Catch ex As Exception
  19:              szError = ex.Message()
  20:          End Try
  21:   
  22:          Return T_LIST
  23:   
  24:      End Function

Now, with an open SqlConnection object CN, you can easily retrieve a scalar or list of scalar values like this:

   1:  szSQL = "SELECT COUNT(*) FROM [Users]"
   2:  Dim n As Integer = SqlSelect(Of Integer)(CN, szSQL, szError)
   3:   
   4:  szSQL = "SELECT name FROM sysobjects where type='U' and name <> 'sysdiagrams' order by name"
   5:  Dim TableList As List(Of String) = SqlSelectList(Of String)(CN, szSQL, szError)

enso

Tuesday, April 24, 2012

Recipe: Homemade Sauerkraut




2 Lbs green cabbage
2 Tbsp coarse pink sea salt 
1 tsp sugar

(Yield: about 5 cups)

Shred the green cabbage, with a food processor or knife, and place all ingredients in a large bowl.  Cover and allow mixture to sit at room temperature for about an hour, until the cabbage has released a lot of liquid (brine).

Move the cabbage to a new container, preferably glass or porcelain (if plastic, avoid BPA: plastics tend to leech into food!) and squeeze out the brine as you move it.  Once you have moved the squeezed cabbage, compact it a little and cover with brine, which was just squeezed out, until it is submerged by about an inch.

Next you want to cover the cabbage mixture with something that will apply a little pressure and keep the cabbage submerged in the brine.  Most people use a plate, upside down, with some sort of weight on top (a rock would do!).  You don't want the plate to float.  Finally, cover the entire thing with a cloth to keep any air-borne dust from getting in.

Let sit for 2 to 4 weeks, but check it once a day to be sure the plate and cabbage is submerged.  If there is any "froth", use a spoon to remove it.

Temperature should be in the range of 72 to 74 degrees.  At 75 degrees, allow 3 weeks for fermentation.  At 70 degrees, allow 4 weeks.  At 65 degrees, allow 5 weeks.  At 60 degrees, allow 6 weeks.  It's not advised to allow the temperature go above 75: it may not ferment and could spoil.

  • Do not use aluminum utensils!  Aluminum is a reactive metal that will alter the taste.
  • Cleanliness is important to avoid bacterial contamination: wash utensils, containers and hands! 

Eating sauerkraut is a great way to protect the balance of bacteria in your GI tract
Sauerkraut is one of the few foods that contain the beneficial bacteria called Lactobacilli plantarumL. plantarum is found in certain food products that undergo fermentation (sauerkraut, green olives, sourdough bread, naturally brewed wines and beer).  Until rather recently, L. plantarum was a common part of the human diet.

Friday, April 20, 2012

HttpWebRequest.GetResponse() taking a long time (Microsoft Security Essentials, DefaultProxy)

I wrote a simple VB.NET command-line (Console) program to grab a web page using HttpWebRequest and HttpWebResponse.

The following code snippet (req is an HttpWebRequest) would take 13 to 17 seconds to grab a simple 4k web page that would come up instantly under the IE or Chrome browser.

   1:  SWATCH = Stopwatch.StartNew()
   2:  Dim resp As HttpWebResponse = DirectCast(req.GetResponse(), HttpWebResponse)
   3:  SWATCH.Stop()
   4:  Console.WriteLine("OK - Elapsed Time: " & SWATCH.Elapsed.ToString())
   5:   

I did some fiddling around and found TWO areas that I had to make modifications.

The first modification I made was inside the settings for my anti-virus program: Microsoft Security Essentials.  After playing around, I found that one particular setting was causing 10 seconds of the 13+ second delay: the Enable behavior monitoring setting.

image

The next culprit was the fact that HttpWebRequest will use the default proxy set in IE.  I do not have a proxy set, but it was still causing about a 3 second delay.  The solution was to create a .config file for my program that turned this behavior off.

   1:  <?xml version="1.0" encoding="utf-8"?>
   2:  <configuration>
   3:      <system.net>
   4:          <defaultProxy>
   5:               <proxy autoDetect="false" />
   6:          </defaultProxy>
   7:      </system.net>
   8:  </configuration>

 

Another method is to disable the Automatic Proxy Detection in Internet Explorer:

image

image

#WINNING!

The offending 13+ seconds was reduced to 0.12 seconds!

image

enso

Wednesday, March 21, 2012

Add Hints & Auto Focus Form Fields (jQuery)

1: $(document).ready(function () {

   2:          //Focus auto-focus fields
   3:          //  add class="auto-focus" to first field
   4:          $('.auto-focus:first').focus();
   5:          //Initialize auto-hint fields
   6:          //  add class="auto-hint" to fields
   7:          //  needs CSS: .auto-hint{color: #AAAAAA;}
   8:          $('INPUT.auto-hint, TEXTAREA.auto-hint').focus(function () {
   9:                 if ($(this).val() == $(this).attr('title')) {
  10:                         $(this).val('');
  11:                         $(this).removeClass('auto-hint');
  12:                 }
  13:          });
  14:          $('INPUT.auto-hint, TEXTAREA.auto-hint').blur(function () {
  15:                 if ($(this).val() == '' && $(this).attr('title') != '') {
  16:                         $(this).val($(this).attr('title'));
  17:                         $(this).addClass('auto-hint');
  18:                 }
  19:          });
  20:          $('INPUT.auto-hint, TEXTAREA.auto-hint').each(function () {
  21:                 if ($(this).attr('title') == '') { return; }
  22:                 if ($(this).val() == '') { $(this).val($(this).attr('title')); }
  23:                 else { $(this).removeClass('auto-hint'); }
  24:          });
  25:  });

Tuesday, March 6, 2012

Restoring PDF Thumbnails to display in Windows Explorer (x64)

I recently upgraded from Windows 7 32-bit to Windows 7 64-bit.  Under the 32-bit OS, I was able to see thumbnails of PDF files (the first page) as the file’s icon.  Under 64-bit Windows 7 I only get the Adobe PDF icon and no thumbnail.

The reason Windows Explorer 64 won’t generate thumbnails?  This occurs because a 64-bit process that runs on a computer that is running an x64-based version of Windows cannot load the 32-bit DLL file that is required to generate the thumbnails.

This describes how you can generate thumbnails for specific PDF files (it’s a little tedious) – however, this will not restore Windows Explorer’s ability to generate them itself.  Pity!

image

The first thing to do is to be sure you have the folder options set correctly- though this will not take care of the problem, there is another step.  Open up the Folder Options dialog in Windows Explorer:

image

Ensure the “Always show icons, never thumbnails” is unchecked:

image

Next open Adobe Acrobat Reader and click the “Open Files” dialog and navigate to a folder with PDF files.

Adobe Reader will generate thumbnails for the files that are in view.

image

Go back to Explorer and you should see the thumbnails generated by Adobe.  Notice that thumbnails are displayed only for those PDF files that were processed by Adobe.

image

awesome

Tuesday, February 14, 2012

(VB.NET) Remember Application Window Size and Position

This is pretty common, to remember your form’s size and position.  I will use the Application Settings feature to persist the required information, but you could just as easily save it to a text file, .INI file, XML or database.  Whatever floats your app.

We want to remember the size and location of our main window, so we’ll add two settings for that.  We will initialize the settings with negative numbers to signal that they have not been set yet.  In my current case, I also have a splitter bar on the main form, so I’m going to include a setting for it’s size – I’d like the application to remember that also.

Here are the Settings I created.  It doesn’t matter what you call them.  I used WindowLocation, WindowSize and WindowSplitterPosition.

image

In the Form’s Load event, we’ll call LoadWindowPosition to load and apply the settings:

image

I have a dual monitor setup with the following Screens (DeviceName, Bounds, WorkingArea)

image

When we restore our window’s size and position, I’d like to ensure that the top left corner of our form is visible on one of the screens.

Here is a LoadWindowPosition() function to check the screens and abort if the upper left corner isn’t visible on any screen.  You could, if you wanted to, replace the “Bounds” with “WorkingArea”.  See the MSDN Docs for the difference and decide for yourself.

image

Finally, to make this work, we need to save our settings so they can be loaded the next time the application is run.  I’ll put the code in the FormClosing event of my main window:

image

Pretty trivial, really!

image