<?xml version="1.0" encoding="UTF-8"?>
<!-- generator="wordpress/2.3.1" -->
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	>

<channel>
	<title>Eric's Blog</title>
	<link>http://eric.lubow.org/blog</link>
	<description>Thoughts, musings, and other useless idealistic hoopla.</description>
	<pubDate>Tue, 15 Jan 2008 11:00:21 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.3.1</generator>
	<language>en</language>
			<item>
		<title>1 Extension, Multiple Phones</title>
		<link>http://eric.lubow.org/blog/2008/system-administration/asterisk-pbx/48/1-extension-multiple-phones/</link>
		<comments>http://eric.lubow.org/blog/2008/system-administration/asterisk-pbx/48/1-extension-multiple-phones/#comments</comments>
		<pubDate>Tue, 15 Jan 2008 11:00:21 +0000</pubDate>
		<dc:creator>eric</dc:creator>
		
		<category><![CDATA[Asterisk]]></category>

		<category><![CDATA[asterisk]]></category>

		<category><![CDATA[multiple devices]]></category>

		<category><![CDATA[phantom extension]]></category>

		<guid isPermaLink="false">http://eric.lubow.org/blog/2008/system-administration/asterisk-pbx/48/1-extension-multiple-phones/</guid>
		<description><![CDATA[In order to setup Asterisk to ring multiple phones from the same dialed extension, you will need to create a phantom extension. I accomplished this by doing the following&#8230;
Before we go any further, let&#8217;s use the following information as true.  The extension we want to have ring in multiple places is extension 100.  [...]]]></description>
			<content:encoded><![CDATA[<p>In order to setup Asterisk to ring multiple phones from the same dialed extension, you will need to create a phantom extension. I accomplished this by doing the following&#8230;</p>
<p>Before we go any further, let&#8217;s use the following information as true.  The extension we want to have ring in multiple places is extension 100.  For sanity&#8217;s sake, let&#8217;s say we want it to ring in 3 places (regardless of the reason).  This means that each phone will need its own extension and auth information according to the <strong>sip.conf</strong>.</p>
<p>First you need to assign each device (phone), its own extension.  Let&#8217;s give each device the extension of &lt;ext&gt;&lt;n&gt;.  Therefore our 3 phones will have the extensions of 1001,1002,1003 respectively.  Their entries in the <strong>sip.conf</strong> will look like this:</p>
<pre>
[1001]
type=peer
context=internal
username=1001
callerid=Eric Lubow <100>
host=dynamic
auth=1001@192.168.1.2
call-limit=100
nat=no
canreinvite=yes
mailbox=100@allstaff
disallow=all
allow=gsm
allow=ulaw
astdb=chan2ext/SIP/1001=1001

[1002]
type=peer
context=internal
username=1002
callerid=Eric Lubow <100>
host=dynamic
auth=1002@192.168.1.2
call-limit=100
nat=no
canreinvite=yes
mailbox=100@allstaff
disallow=all
allow=gsm
allow=ulaw
astdb=chan2ext/SIP/1002=1002

[1003]
type=peer
context=internal
username=1003
callerid=Eric Lubow <100>
host=dynamic
auth=1003@192.168.1.2
call-limit=100
nat=no
canreinvite=yes
mailbox=100@allstaff
disallow=all
allow=gsm
allow=ulaw
astdb=chan2ext/SIP/1003=1003
</pre>
<p>Next, in your <strong>extensions.conf</strong>, add the entry to ring all the extensions when the <em>phantom</em> extension is dialed.  The Dial() command should now look as follows:</p>
<pre>
exten => 100,1,Dial(SIP/1001&#038;SIP/1002&#038;SIP1003,18)
</pre>
<p>A nice thing to do to (in order to not confuse the user) is, in your tftp files, ensure that the label on the phone (each phone) is still the actual extension of the phone that one would dial to get to it.  Label the phone elsewhere with your REAL extension to keep track of it.</p>
]]></content:encoded>
			<wfw:commentRss>http://eric.lubow.org/blog/2008/system-administration/asterisk-pbx/48/1-extension-multiple-phones/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Creating a Process Table hash in Perl</title>
		<link>http://eric.lubow.org/blog/2007/perl/47/creating-a-process-table-hash-in-perl/</link>
		<comments>http://eric.lubow.org/blog/2007/perl/47/creating-a-process-table-hash-in-perl/#comments</comments>
		<pubDate>Fri, 28 Dec 2007 11:00:01 +0000</pubDate>
		<dc:creator>eric</dc:creator>
		
		<category><![CDATA[Perl]]></category>

		<category><![CDATA[process]]></category>

		<guid isPermaLink="false">http://eric.lubow.org/blog/2007/perl/47/creating-a-process-table-hash-in-perl/</guid>
		<description><![CDATA[I came across a situation where I needed to access the process table in Perl.  The problem that i found was that the best accessor Proc::ProcessTable only retrieved an array.  Since it seems fairly senseless to keep looping over an array to find the exact process id that I want, you may want [...]]]></description>
			<content:encoded><![CDATA[<p>I came across a situation where I needed to access the process table in Perl.  The problem that i found was that the best accessor <a href="http://search.cpan.org/~durist/Proc-ProcessTable-0.41/ProcessTable.pm">Proc::ProcessTable</a> only retrieved an array.  Since it seems fairly senseless to keep looping over an array to find the exact process id that I want, you may want to turn it into a hash.</p>
<pre>
use strict;
use warnings;
use Proc::ProcessTable;

 # Create a new process table object
 my ($pt) = new Proc::ProcessTable;

 # Initialize your process table hash
 my (%pt_hash);

 # Get the fields that your architecture supports
 my (@fields) = $pt->fields;

 # Outer loop for each process id
 foreach my $proc ( @{$pt->table} ) {
    # Inner loop for each field within the process id
    for my $field (@fields) {
       # Add the field to the hash
       $pt_hash{$proc->pid}{$field} = $proc->$field();
    }
 }
</pre>
<p>It&#8217;s just as simple as that.  If you want to be sure that its in there.  At the end of the file add these two lines for proof:</p>
<pre>
use Data::Dumper;
print Dumper \%pt_hash;
</pre>
<p>The hash is organized with the keys being the process ids.  There is another hash underneath it with all the fields as hash keys.</p>
]]></content:encoded>
			<wfw:commentRss>http://eric.lubow.org/blog/2007/perl/47/creating-a-process-table-hash-in-perl/feed/</wfw:commentRss>
		</item>
		<item>
		<title>MySQL Proxy Query Profiling</title>
		<link>http://eric.lubow.org/blog/2007/lua/44/mysql-proxy-query-profiling/</link>
		<comments>http://eric.lubow.org/blog/2007/lua/44/mysql-proxy-query-profiling/#comments</comments>
		<pubDate>Fri, 07 Dec 2007 23:12:44 +0000</pubDate>
		<dc:creator>eric</dc:creator>
		
		<category><![CDATA[Lua]]></category>

		<category><![CDATA[mysql-proxy]]></category>

		<guid isPermaLink="false">http://eric.lubow.org/blog/2007/lua/44/mysql-proxy-query-profiling/</guid>
		<description><![CDATA[Since I am now finally getting to play with MySQL Proxy, I am going to outline some recipes here that I have found/created/modified that may be useful to someone other than me.  This is a recipe for profiling queries.  It writes the information to the PROXY_LOG_FILE currently name mysql.log.  It is a [...]]]></description>
			<content:encoded><![CDATA[<p>Since I am now finally getting to play with MySQL Proxy, I am going to outline some recipes here that I have found/created/modified that may be useful to someone other than me.  This is a recipe for profiling queries.  It writes the information to the <em>PROXY_LOG_FILE</em> currently name <strong>mysql.log</strong>.  It is a file that will be created in the directory that you run <strong>mysql-proxy</strong> from.  The file itself is mostly commented and should therefore be pretty self-explanatory.  It was adapted from the reference documentation listed at the bottom of this entry.</p>
<pre>
assert(proxy.PROXY_VERSION >= 0x00600,
  "You need to be running mysql-proxy 0.6.0 or greater")

 -- Set up the log file
 local log_file = os.getenv("PROXY_LOG_FILE")
 if (log_file == nil) then
    log_file = "mysql.log"
 end

 -- Open up our log file in append mode
 local fh = io.open(log_file, "a+")

 -- Set some variables
 local original_query = ""
 local executed_query = ""
 local replace = false
 local comment = ""

 -- For profilign
 local profile = 0

-- Push the query onto the Queue
function read_query( packet )
  if string.byte(packet) == proxy.COM_QUERY then
    query = string.sub(packet, 2)

    -- Pull out the comment and store it
    original_query = string.gsub(query, "%s*%*%*%*%s(.+)%s%*%*%*%s*",'')
    comment = string.match(query, "%s*%*%*%*%s(.+)%s%*%*%*%s*")

    -- Add the original packet to the query if we have a comment
    if (comment) then
        if string.match(string.upper(comment), '%s*PROFILE') then
          -- Profile types:
          --   ALL, BLOCK IO, CONTEXT SWITCHES, IPC,
          --        MEMORY, PAGE FAULTS, SOURCE, SWAPS

          -- Set it up for profiling
          -- Generate a new COM_QUERY packet
          --   and inject it with a new id (11)
          original_query = "SET PROFILING=1; " .. original_query
      end -- End if (PROFILE)
    end -- End if (comment)

    executed_query = original_query
    -- Check for a 'SELECT' typo
    if string.match(string.upper(original_query), '^%s*SLECT') then
        executed_query = string.gsub(original_query,'^%s*%w+', 'SELECT')
        replace = true;
    -- matches "CD" as first word of the query
    elseif string.match(string.upper(original_query), '^%s*CD') then
        executed_query = string.gsub(original_query,'^%s*%w+', 'USE')
        replace = true
    end

    -- Postpend the other profiling strings to the query
    if (comment and string.match(string.upper(comment), '%s*PROFILE')) then
        executed_query = executed_query .. "; SHOW " .. comment
    end

    -- Actually execute the query here
    proxy.queries:append(1, string.char(proxy.COM_QUERY) .. executed_query )
    return proxy.PROXY_SEND_QUERY
  else
    executed_query = ""
  end
end

function read_query_result (inj)
  local res = assert(inj.resultset)
  local num_cols = string.byte(res.raw, 1)
  if num_cols > 0 and num_cols < 255 then
     for row in inj.resultset.rows do
         row_count = row_count + 1
     end
  end

  -- Prepend the error tag in the log
  local error_status = ""
  if res.query_status and (res.query_status < 0) then
     error_status = "[ERROR]"
  end

  -- Gets the rows affected by the actual query
  local row_count = 0
  if (res.affected_rows) then
     row_count = res.affected_rows
  end

  -- Prepend the comment line in the log
  if (comment) then
     fh:write( string.format("%s %6d -- [COMMENT] %s\n",
        os.date('%Y-%m-%d %H:%M:%S'),
        proxy.connection.server["thread_id"],
        comment))
  end

  -- Prepend the typo in the log
  if (replace) then
     fh:write( string.format("%s %6d -- [REPLACEMENT] %s\n\t\t\t%s\n",
        os.date('%Y-%m-%d %H:%M:%S'),
        proxy.connection.server["thread_id"],
        ("replaced " .. original_query),
        ("with " .. executed_query)))
  end

  -- Write the query adding the number of rows retrieved and query time
  fh:write( string.format("%s %6d -- %s %s {%d rows} {%d ms}\n",
     os.date('%Y-%m-%d %H:%M:%S'),
     proxy.connection.server["thread_id"],
     error_status,
     executed_query,
     row_count,
     inj.query_time)
  )
  fh:flush()
end
</pre>
<p>To make this work, simply append 3 asterisks &#8216;PROFILE &lt;profile_type&gt;&#8217; and then 3 more asterisks and you will have the profile information returned to you in your query:<br />
<code>*** PROFILE ALL *** SELECT * FROM foo_bar;</code><br />
2 tables will be returned.  Your results and then the profile of your results.</p>
<p>Reference: <a href="http://http://forge.mysql.com/wiki/Writing_LUA_Scripts_for_MySQL_Proxy">Writing LUA Scripts for MySQL Proxy</a></p>
]]></content:encoded>
			<wfw:commentRss>http://eric.lubow.org/blog/2007/lua/44/mysql-proxy-query-profiling/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Deleting Lots Of Files (SysAdmin problem solving exercise)</title>
		<link>http://eric.lubow.org/blog/2007/system-administration/45/deleting-lots-of-files-sysadmin-problem-solving-exercise/</link>
		<comments>http://eric.lubow.org/blog/2007/system-administration/45/deleting-lots-of-files-sysadmin-problem-solving-exercise/#comments</comments>
		<pubDate>Mon, 17 Dec 2007 11:15:12 +0000</pubDate>
		<dc:creator>eric</dc:creator>
		
		<category><![CDATA[System Administration]]></category>

		<category><![CDATA[bash]]></category>

		<category><![CDATA[find]]></category>

		<category><![CDATA[inodes]]></category>

		<category><![CDATA[logrotate]]></category>

		<category><![CDATA[xargs]]></category>

		<guid isPermaLink="false">http://eric.lubow.org/blog/2007/system-administration/45/deleting-lots-of-files-sysadmin-problem-solving-exercise/</guid>
		<description><![CDATA[Since I know I am not the first (or the last) to make a typo in logrotate and not catch it for a while&#8230;someone else must have been in the position of having to delete a lot of files in the same manner.  I recently learned that, as usual, there is more than one [...]]]></description>
			<content:encoded><![CDATA[<p>Since I know I am not the first (or the last) to make a typo in logrotate and not catch it for a while&#8230;someone else must have been in the position of having to delete a lot of files in the same manner.  I recently learned that, as usual, there is more than one way to handle it.</p>
<p>To put the situation in context, I basically allowed thousands of <em>mail.*</em> files to be created.  These files littered the <em>/var/log/</em> directory and basically slowed down the entire file system access.  I figured out this a number of ways.</p>
<p>The first way was when I tried to do an <strong>ls</strong> anywhere, it would just hang.  My first reaction was to check to see what was eating up the CPU.  To do this, I did a <strong>top</strong>. I noticed that <strong>logrotate</strong> was hogging all the CPU cycles.  Since I know that <strong>logrotate</strong> basically only operates on one parent directory (by default) <em>/var/log</em>, I headed on over there and did an <strong>ls</strong>.  Once again, it just hung.  Then I figured the file system was slow and decided to check out some file system information.  The next two commands I ran were <strong>df -h</strong> and <strong>df -i</strong>. I ran the <strong>df -h</strong> to see if we were out of disk space (and yes I lazily use human readable format).  I ran the second to check to see how many inodes were in use. (For more information on inodes, check out the <a href="http://en.wikipedia.org/">wikipedia</a> entry <a href="http://en.wikipedia.org/wiki/Inode">here</a>).</p>
<p>Now that I know the system is short on inodes, I checked out the output of <strong>lsof</strong>.  Now I know that we have some serious problems in the <em>/var/log</em> dir.  After some quick investigation, I realized that there were too many <em>mail.*</em> files.  How do I get rid of them? Glad you asked&#8230; Let&#8217;s assume that we want to delete ALL the <em>mail.*</em> files in the <em>/var/log</em> directory.</p>
<p>1) The easiest way is to do it with <strong>find</strong>:<br />
1a) Using <strong>find</strong>&#8217;s delete command:<br />
<code>[root@eric] /var/log # find ./ -type f -name "mail.*" -delete</code><br />
or<br />
1b) using <strong>find</strong>&#8217;s exec command with <strong>rm</strong>:<br />
<code>[root@eric] /var/log # find ./ -type f -name "mail.*" -exec rm -rf '{}' \;</code><br />
These will work, but either will be slow since they doesn&#8217;t do batch execution.</p>
<p>2) A slightly more preferred way is to use bash:<br />
<code>[root@eric] /var/log # for n in mail.*; do rm -v $n; done;</code><br />
This is a little faster, but will still be relatively slow since there is no batch execution. (Note: The -v in the rm will cause quite a bit of output since it is showing you EVERY file it deletes.  Feel free to leave this out if you really screwed up.)</p>
<p>3) The actual preferred method is to use <strong>find</strong>:<br />
<code>[root@eric] /var/log # find ./ -type f -name "mail.*" | xargs rm -f </code><br />
I believe this is the preferred method because although it removes the files one at a time, it is more efficient for the file system since it batches it up.</p>
<p>There are certainly other ways to accomplish this task.  It can always be done with a Perl one-liner or even using some Perl modules to save some time.  These are just a few ideas to point someone in the right direction.</p>
]]></content:encoded>
			<wfw:commentRss>http://eric.lubow.org/blog/2007/system-administration/45/deleting-lots-of-files-sysadmin-problem-solving-exercise/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Text Messages to Cell Phones via Email</title>
		<link>http://eric.lubow.org/blog/2007/misc/43/text-messages-to-cell-phones-via-email/</link>
		<comments>http://eric.lubow.org/blog/2007/misc/43/text-messages-to-cell-phones-via-email/#comments</comments>
		<pubDate>Mon, 03 Dec 2007 19:23:17 +0000</pubDate>
		<dc:creator>eric</dc:creator>
		
		<category><![CDATA[Misc]]></category>

		<category><![CDATA[cell phones]]></category>

		<category><![CDATA[text messages]]></category>

		<guid isPermaLink="false">http://eric.lubow.org/blog/2007/misc/43/text-messages-to-cell-phones-via-email/</guid>
		<description><![CDATA[I have been compiling a list of the domains that one needs in order to send text messages to cell phones via email.  As a huge user of Nagios, this is how I keep myself aware of the status changes.  Below I have listed the carriers that I use most frequently.  If [...]]]></description>
			<content:encoded><![CDATA[<p>I have been compiling a list of the domains that one needs in order to send text messages to cell phones via email.  As a huge user of <a href="http://www.nagios.org/">Nagios</a>, this is how I keep myself aware of the status changes.  Below I have listed the carriers that I use most frequently.  If you have any others to list here to make this more complete, please add a comment and I will add it to the list.</p>
<p>I have seen other instances of this before, but some are outdated.  These are the newest ones that I have come across.</p>
<p>The assumption here is that the telephone number of the person that you are trying to text message is 2225551212. Just make sure that there is nothing in between the numbers (like a &#8216;.&#8217; or a &#8216;-&#8217;),  Also make sure that you don&#8217;t put the &#8216;1&#8242; before the phone number.</p>
<ul>
<li>ATT:          2225551212@txt.att.net</li>
<li>Verizon:      2225551212@vtext.com</li>
<li>T-Mobile:     2225551212@tmomail.net</li>
<li>Alltell:      2225551212@message.alltel.com</li>
<li>Virgin Mobile:2225551212@vmobl.com</li>
<li>Sprint: 2225551212@messaging.sprintpcs.com</li>
<li>Nextel: 2225551212@messaging.nextel.com</li>
<li>All Other:    2225551212@teleflip.com</li>
</ul>
<p>It should be noted that the last item (<a href="http://www.teleflip.com/">Teleflip</a>), can be used either in place of any of these or as a fall through.  It seems to act as a universal text message system.</p>
<p><strong>UPDATES:</strong><br />
Here are the contributed addresses. The thanks are in parentheses following the numbers:</p>
<ul>
<li>Claro (Brazil): 2225551212@clarotorpedo.com.br (<em>Rodrigo</em>)</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://eric.lubow.org/blog/2007/misc/43/text-messages-to-cell-phones-via-email/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Cloning a Virtual Machine in VMWare VI3 without Virtual Server</title>
		<link>http://eric.lubow.org/blog/2007/virtualization/42/cloning-a-virtual-machine-in-vmware-vi3-without-virtual-server/</link>
		<comments>http://eric.lubow.org/blog/2007/virtualization/42/cloning-a-virtual-machine-in-vmware-vi3-without-virtual-server/#comments</comments>
		<pubDate>Mon, 05 Nov 2007 18:26:24 +0000</pubDate>
		<dc:creator>eric</dc:creator>
		
		<category><![CDATA[Virtualization]]></category>

		<guid isPermaLink="false">http://eric.lubow.org/blog/2007/virtualization/42/cloning-a-virtual-machine-in-vmware-vi3-without-virtual-server/</guid>
		<description><![CDATA[I, like many other people working in a small company, have to fix problems and come up with solutions with cost at the forefront.  I had to make many virtual machines appear from nowhere to create an environment in virtually no time at all.  Since all I had was VMWare Server (for Linux), [...]]]></description>
			<content:encoded><![CDATA[<p>I, like many other people working in a small company, have to fix problems and come up with solutions with cost at the forefront.  I had to make many virtual machines appear from nowhere to create an environment in virtually no time at all.  Since all I had was VMWare Server (for Linux), I started there.  When I realized that those didn&#8217;t translate to ESX, I had to come up with another solution.  I created a single template guest OS (of Gentoo 2006.1 which is our primary server OS here) and decided to clone that.  How did I do it&#8230;well, I am glad you asked.</p>
<p>The key here was to figure out what the VI3 (Virtual Infrastructure 3) client did and mimic it.  In order to figure this out, I copied the entire <em>/etc</em> directory to a place where I could later diff it.  I created 3 VM (virtual machines) with nothing on them to discern the patterns that the client made in its files.  I then diff&#8217;d the 2 version of the <em>/etc</em> directory and now I knew the main changes that had to be made.  It also should be noted that the Temple VM should be powered off before creating the Clone VM.</p>
<p>I also kept a pristine copy of the template VM so I would always have something to copy from when creating a new VM.  For the sake of argument, let&#8217;s go with the following names and terminology so we can all stay on the same page.  The template VM is going to be named <strong>Template</strong>.  The cloned VM is going to be named <strong>Clone</strong>.  I am going to assume that the template VM that you are using is already fully created, configured, and installed.  I am also assuming that you either have console or SSH access to the host since you will need to have access to the commands on the computer itself.</p>
<p>The first step is to copy the template directory.  My volume is named <strong>Array1</strong>, so the command looks like this (Note: I add the &amp; to put the command in the background since it takes a while): </p>
<pre>
[root@vm1 ~]# cp -arp /vmfs/volumes/Array1/Template /vmfs/volumes/Array1/Clone &#038;
</pre>
<p>Now its time to get started on the file editing.  The first group of files we have to mess with are in the <strong>/etc/vmware/hostd/</strong>.</p>
<p><strong>vmInventory.xml</strong>:<br />
Assuming the only virtual machines you have are going to be Template and his buddy Clone, the following is what your <strong>vmInventory.xml</strong> should look like:</p>
<pre>
&lt;ConfigRoot&gt;
  &lt;ConfigEntry id="0001"&gt;
    &lt;objID&gt;32&lt;/objID&gt;
    &lt;vmxCfgPath&gt;/vmfs/volumes/4725ae82-4e276b80-4c76-001c23c38d80/Template/Template.vmx&lt;/vmxCfgPath&gt;
  &lt;/ConfigEntry&gt;
  &lt;ConfigEntry id="0002"&gt;
    &lt;objID&gt;48&lt;/objID&gt;
    &lt;vmxCfgPath&gt;/vmfs/volumes/4725ae82-4e276b80-4c76-001c23c38d80/Clone/Clone.vmx&lt;/vmxCfgPath&gt;
  &lt;/ConfigEntry&gt;
&lt;/ConfigRoot&gt;
</pre>
<p>The 3 items that you have to note here are:</p>
<ol>
<li><strong>id:</strong> This is a 4 digit zero-padded number going up in increments of 1</li>
<li><strong>objID:</strong> This is a number going up in increments of 16</li>
<li><strong>vmxCfgPath:</strong> Here you need to ensure that you have the proper hard path (not sym-linked)</li>
</ol>
<p><strong>pools.xml</strong>:<br />
Using the same assumption as before, the only 2 VMs are <strong>Template</strong> and <strong>Clone</strong></p>
<pre>
&lt;ConfigRoot&gt;
  &lt;resourcePool id="0000"&gt;
    &lt;name&gt;Resources&lt;/name&gt;
    &lt;objID&gt;ha-root-pool&lt;/objID&gt;
    &lt;path&gt;host/user&lt;/path&gt;
  &lt;/resourcePool&gt;
  &lt;vm id="0001"&gt;
    &lt;lastModified&gt;2007-10-30T16:23:57.618151Z&lt;/lastModified&gt;
    &lt;objID&gt;32&lt;/objID&gt;
    &lt;resourcePool&gt;ha-root-pool&lt;/resourcePool&gt;
    &lt;shares&gt;
      &lt;cpu&gt;normal&lt;/cpu&gt;
      &lt;mem&gt;normal&lt;/mem&gt;
    &lt;/shares&gt;
  &lt;/vm&gt;
  &lt;vm id="0002"&gt;
    &lt;lastModified&gt;2007-10-30T16:23:57.618151Z&lt;/lastModified&gt;
    &lt;objID&gt;48&lt;/objID&gt;
    &lt;resourcePool&gt;ha-root-pool&lt;/resourcePool&gt;
    &lt;shares&gt;
      &lt;cpu&gt;normal&lt;/cpu&gt;
      &lt;mem&gt;normal&lt;/mem&gt;
    &lt;/shares&gt;
  &lt;/vm&gt;
&lt;/ConfigRoot&gt;
</pre>
<p>The 3 items that you have to note here are:</p>
<ol>
<li><strong>id:</strong> This is a 4 digit zero-padded number going up in increments of 1 (and it must match the id from <strong>vmInventory.xml</strong></li>
<li><strong>objID:</strong> This is a number going up in increments of 16 (and it must match the id from <strong>vmInventory.xml</strong></li>
<li>The <strong>lastModified</strong> item here doesn&#8217;t matter as it will be changed when you make a change to VM anyway.</li>
</ol>
<p>By now, the Template directory should be finished copying itself over to the directory that we will be using as our clone.  First thing we have to do is rename all the files in the directory to mimic the name of our VM.</p>
<pre>
  # mv Template-flat.vmdk Clone-flat.vmdk
  # mv Template.nvram Clone.nvram
  # mv Template.vmdk Clone.vmdk
  # mv Template.vmx Clone.vmx
  # mv Template.vmxf Clone.vmxf
</pre>
<p>Now we just need to edit some files and we are ready to go.  First let&#8217;s edit the <em>Template.vmdk</em> file.  You need to change the line that reads something similar to (the difference will be in the size of your extents):</p>
<pre>
# Extent description
RW 20971520 VMFS "Template-flat.vmdk"
</pre>
<p>to look like:</p>
<pre>
# Extent description
RW 20971520 VMFS "Clone-flat.vmdk"
</pre>
<p>Save and exit this file. The next file is <em>Template.vmx</em>.  The key here is to change every instance of the word <strong>Template</strong> to <strong>Clone</strong>.  There should be 4 instances:</p>
<ol>
<li>nvram</li>
<li>displayName</li>
<li>extendedConfigFile</li>
<li>scsi0:0.fileName</li>
</ol>
<p>Don&#8217;t forget to change the MAC address(es).  Their variable name(s) should be something like <strong>ethernet0.generateAddress</strong>.  Delete the line that has the variable title <strong>sched.swap.derivedName</strong>.  It will be regenerated and added to the config file.  Lastly, add the following line to the end of the file if it doesn&#8217;t already exist elsewhere in the file:</p>
<pre>
uuid.action = "create"
</pre>
<p>The final item that needs to be done is the one that got me for such a long time.  This is the step that will allow your changes to be seen in the client.  (Drum roll &#8230;..)</p>
<p>Restart the VMWare management console daemon.  So simple.  Just run the following command:</p>
<pre>
  # /etc/init.d/mgmt-vmware restart
</pre>
<p>Note: This will log you out of the client console.  But when you log back in, you will have access to the changes that you have made including the clones.</p>
<p>Good luck, and be careful as XML has a tendency to be easier to break than to fix.</p>
]]></content:encoded>
			<wfw:commentRss>http://eric.lubow.org/blog/2007/virtualization/42/cloning-a-virtual-machine-in-vmware-vi3-without-virtual-server/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Asterisk Caller ID Blocking Recipe</title>
		<link>http://eric.lubow.org/blog/2007/system-administration/asterisk-pbx/41/asterisk-caller-id-blocking-recipe/</link>
		<comments>http://eric.lubow.org/blog/2007/system-administration/asterisk-pbx/41/asterisk-caller-id-blocking-recipe/#comments</comments>
		<pubDate>Tue, 25 Sep 2007 13:36:28 +0000</pubDate>
		<dc:creator>eric</dc:creator>
		
		<category><![CDATA[Asterisk]]></category>

		<guid isPermaLink="false">http://eric.lubow.org/blog/2007/system-administration/asterisk-pbx/41/asterisk-caller-id-blocking-recipe/</guid>
		<description><![CDATA[Here&#8217;s another quick little Asterisk recipe that I threw together.  It&#8217;s a handy because it only takes about 10 minutes to setup and is infinitely useful to the sales types.  Just a note, this was done with Asterisk 1.4.8.
I wanted to do a little in AEL just to get a feel for it. [...]]]></description>
			<content:encoded><![CDATA[<p>Here&#8217;s another quick little Asterisk recipe that I threw together.  It&#8217;s a handy because it only takes about 10 minutes to setup and is infinitely useful to the sales types.  Just a note, this was done with Asterisk 1.4.8.</p>
<p>I wanted to do a little in AEL just to get a feel for it.  It is a little AEL and a little regular <em>extensions.conf</em> type stuff.</p>
<p>The basic way that this CallerID Blocking recipe works is to use the Asterisk DB.  An entry with the family of <strong>CIDBlock</strong> and the key of the dialing users extension will have a value of <strong>1</strong> or <strong>0</strong>.  The user initially sets their preference to either enabled (1) or disabled (0).  When the number gets dialed, the preference gets checked and then the CALLERID(name)/CALLERID(number) values are set accordingly.  In order for the user to enable CID Blocking, they need to dial *81.  It will stay enabled until they dial *82.</p>
<p>How do we accomplish this?  Easy. The sounds come with the asterisk sounds package.  </p>
<p>Open up your extensions.conf and add the following lines (to whichever context works for you):</p>
<pre>
; Enable CallerID Blocking for the dialing extension
exten => *81,1,Set(DB(CIDBlock/${CHANNEL:4:4})=1)
exten => *81,2,Playback(privacy-your-callerid-is)
exten => *81,3,Playback(enabled)
exten => *81,4,Hangup()

; Disable CallerID Blocking for the dialing extension
exten => *82,1,Set(DB(CIDBlock/${CHANNEL:4:4})=0)
exten => *82,2,Playback(privacy-your-callerid-is)
exten => *82,3,Playback(disabled)
exten => *82,4,Hangup()
</pre>
<p>The last modification that needs to happen is that you have to change the <em>exten</em> that dials out to check the DB and react accordingly.  Here is a snippet of mine (with the numbers changed to protect the innocent):</p>
<pre>
; Outbound calling for 111.222.3456 (my phone number)
exten =>_1NXXNXXXXXX,1,Set(CIDBlock=${DB(CIDBlock/${CHANNEL:4:4})})
exten =>_1NXXNXXXXXX,2,Set(${IF($[${CIDBlock} = 1]?CALLERID(name)=Unavailable:CALLERID(name)=MyCompany)})
exten =>_1NXXNXXXXXX,3,Set(${IF($[${CIDBlock} = 1]?CALLERID(number)=0-1-999:CALLERID(number)=1112223456)})
exten =>_1NXXNXXXXXX,4,DIAL(SIP/provider/${EXTEN},60,tr)
exten =>_1NXXNXXXXXX,5,Hangup
</pre>
<p>That&#8217;s really all it takes to set it up.  Quick and handy.</p>
<p>* Note: *81 &#038; *82 are arbitrary number combinations.  Adjust to what works for you.</p>
<p>If you&#8217;re feeling really frisky, I added this AEL extension to check the status of your CallerID Blocking on *83.  For fun, I have also included my *67 script for those who need an idea of how its done.  As with almost anything in Asterisk, there are many ways to do it, this is just how I chose to accomplish this.</p>
<pre>
// Extra's for sending things outbound
context outbound-extra {
   *83 => {
            Playback(privacy-your-callerid-is);
            Set(CIDBlock=${DB(CIDBlock/${CHANNEL:4:4})});
            if(${CIDBlock} == 1) {
                Playback(enabled);
            }
            else {
                Playback(disabled);
            }
            Hangup();
   };

   *67 => {
      // Remove the *67 from the number we are dialing
      Set(dialed_number=${EXTEN:3:11});
      Set(CALLERID(name)=Unavailable):
      Set(CALLERID(number)=0-1-999):
      DIAL(SIP/provider/${dialed_number},60,tr);
      Hangup();
   };
};
</pre>
]]></content:encoded>
			<wfw:commentRss>http://eric.lubow.org/blog/2007/system-administration/asterisk-pbx/41/asterisk-caller-id-blocking-recipe/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Asterisk *69 with 1.4.x</title>
		<link>http://eric.lubow.org/blog/2007/system-administration/asterisk-pbx/39/asterisk-69-with-14x/</link>
		<comments>http://eric.lubow.org/blog/2007/system-administration/asterisk-pbx/39/asterisk-69-with-14x/#comments</comments>
		<pubDate>Mon, 02 Jul 2007 18:32:05 +0000</pubDate>
		<dc:creator>eric</dc:creator>
		
		<category><![CDATA[Asterisk]]></category>

		<guid isPermaLink="false">http://eric.lubow.org/blog/2007/system-administration/asterisk-pbx/39/asterisk-69-with-14x/</guid>
		<description><![CDATA[Many phone users just take for granted the service provided by the Telco called *69 (pronouced &#8220;Star six nine&#8221;).  Since Asterisk is a telephony platform, it doesn&#8217;t just come with *69 built in.  So if you want it, you have to implement it.  To save you some time, I have implemented it [...]]]></description>
			<content:encoded><![CDATA[<p>Many phone users just take for granted the service provided by the Telco called *69 (pronouced &#8220;Star six nine&#8221;).  Since Asterisk is a telephony platform, it doesn&#8217;t just come with *69 built in.  So if you want it, you have to implement it.  To save you some time, I have implemented it with a few tweaks.  This setup works, but YMMV (your mileage may vary).</p>
<p>The concept of the operation here is as follows:  When a call comes in, we grab the caller id number and store it in the Asterisk DB.  When a user makes an outgoing call to *69, we then get that last phone number that called in from the AstDB and dial it using our standard Dial() function. I will get deeper into each phase as I go through the process.</p>
<p>Just to make this all a little clearer, I will say that the context for making outgoing calls is <strong>outbound</strong> and the context for internal calls is <strong>internal</strong>.</p>
<p>1. The first thing to do is to modify the actions a call takes when it comes to the phone.  Assuming the first line of your dialplan for the phone was:<br />
<code>exten => _1[0]XX,1,Dial(SIP/${EXTEN},21)</code><br />
This would take the call and send it to which ever SIP peer matched (be it 1000, 1001, etc).  To ensure that only non-internal calls get saved to our AstDB, I have added a statement to avoid calls coming from the <strong>internal</strong> context.  This is our new step 1. If the call comes from the internal context, goto step 3.<br />
<code>exten => _1[0]XX,1,GotoIf($["${CONTEXT}" = "internal"]?3)</code><br />
If not, continue on to our step 2.  Here we are going to make use of the <em>DB(family/key)</em> function.  (Note: For those who had trouble with this function (like me), the family is like a table and they key is like a column name).  I set the family name to <strong>LastCIDNum</strong> and the key to be the receiving caller&#8217;s extension.  The value was set to the callerid number.  This was done as follows:<br />
<code>exten => _1[0]XX,2,Set(DB(LastCIDNum/${EXTEN})=${CALLERID(number)})</code><br />
I then move the original Dial back to step 3.  Our final internal product looks something like this:<br />
<code>exten => _1[0]XX,1,GotoIf($["${CONTEXT}" = "internal"]?3)<br />
exten => _1[0]XX,2,Set(DB(LastCIDNum/${EXTEN})=${CALLERID(number)})<br />
exten => _1[0]XX,3,Dial(SIP/${EXTEN},21)<br />
exten => _1[0]XX,4,Voicemail(${EXTEN}@voicemail,u)<br />
exten => _1[0]XX,5,Hangup()<br />
exten => _1[0]XX,102,Voicemail(${EXTEN}@voicemail,b)<br />
exten => _1[0]XX,103,Hangup()</code></p>
<p>2. The next step is handle the outbound context for when a *69 call is placed.  Assuming you don&#8217;t have an outbound dialing macro, we will handle this similarly to way an outbound SIP call would be placed.  First we set the outbound callerid information:<br />
<code>exten => *69,1,Set(CALLERID(number)=12345678901)<br />
exten => *69,2,Set(CALLERID(name)=MyCompany)</code><br />
Then we grab the last caller id information obtained.  It would probably be a good idea to check if its there and if its not set to <em>anonymous</em> or something along those lines, but that is something that would be relatively easy to implement after the basics are up and running.  To obtain the caller id information from the AstDB, I use the ${CHANNEL} variable to get the callers extension for the query.  I use the substring variable syntax to pull the 4 digit extension out of the ${CHANNEL} variable.  I then stick it in a temporary variable that I can <strong>lastcall</strong>.<br />
<code>exten => *69,3,Set(lastcall=${DB(LastCIDNum/${CHANNEL:4:4})})</code><br />
Once we have that information, we can dial out almost as normal.  The one issue is that for all US calls, it doesn&#8217;t receive the <em>1</em> in the callerid(num).  So in the Dial function, I add a <strong>1</strong> for domestic calls.<br />
<code>exten => *69,4,DIAL(SIP/yourprovider/1${lastcall},60,tr)</code><br />
(Note: The record in the CDR gets added as the outbound dialed number, not *69.)<br />
Our final product for the outbound context should look something like this:<br />
<code>exten =>exten => *69,1,Set(CALLERID(number)=12345678901)<br />
exten => *69,2,Set(CALLERID(name)=MyCompany)<br />
exten => *69,3,Set(lastcall=${DB(LastCIDNum/${CHANNEL:4:4})})<br />
exten => *69,4,DIAL(SIP/paetec/1${lastcall},60,tr)<br />
exten => *69,5,GotoIf(${DIALSTATUS} = CHANUNAVAIL,7)<br />
exten => *69,6,GotoIf(${DIALSTATUS} = CONGESTION,7)<br />
exten => *69,7,Hangup<br />
exten => *69,101,Congestion</code></p>
<p>In order to see if your DB() calls are working properly, you can run the command <strong>database show</strong> from the Asterisk console.  It will find all the keys entered in the family &#8220;LastCIDNum&#8221;.  If these are all (or mostly) external phone numbers, then you have likely done this setup correctly.</p>
]]></content:encoded>
			<wfw:commentRss>http://eric.lubow.org/blog/2007/system-administration/asterisk-pbx/39/asterisk-69-with-14x/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Configuring a Cisco 7961 for SIP and Asterisk</title>
		<link>http://eric.lubow.org/blog/2007/system-administration/asterisk-pbx/38/configuring-a-cisco-7961-for-sip-and-asterisk/</link>
		<comments>http://eric.lubow.org/blog/2007/system-administration/asterisk-pbx/38/configuring-a-cisco-7961-for-sip-and-asterisk/#comments</comments>
		<pubDate>Tue, 29 May 2007 19:39:28 +0000</pubDate>
		<dc:creator>eric</dc:creator>
		
		<category><![CDATA[Asterisk]]></category>

		<guid isPermaLink="false">http://eric.lubow.org/blog/2007/system-administration/asterisk-pbx/38/configuring-a-cisco-7961-for-sip-and-asterisk/</guid>
		<description><![CDATA[Just prior to writing this, I think I was about ready to kill someone.  Setting up this phone was probably one of the most challenging things I have done in a long time.  So this will be my attempt to explain to other&#8217;s what I did and I will hopefully save some people [...]]]></description>
			<content:encoded><![CDATA[<p>Just prior to writing this, I think I was about ready to kill someone.  Setting up this phone was probably one of the most challenging things I have done in a long time.  So this will be my attempt to explain to other&#8217;s what I did and I will hopefully save some people some time.</p>
<p>Since we all need to be on the same page, let&#8217;s start out with the <em>conventions</em>:</p>
<ul>
<li>Asterisk: Gentoo Linux, 192.168.1.5</li>
<li>Workhorse: Gentoo Linux (DHCP, TFTP, NTP), 192.168.1.20</li>
<li>Phone: Cisco 7961</li>
<li>Anything starting with a <strong>$</strong> means you put your value in it.  I will name the variable something descriptive for you</li>
<li>Remember that all filenames with Cisco are case sensitive
<li>If there are some files you need examples of or access to and aren&#8217;t listed, please don&#8217;t hesitate to contact me.</li>
</ul>
<p>I am not going to go into a lot of detail with things, just give some overview and some examples and it will hopefully be enough to get you in the right direction.  Check throughout the document for some references and read up on those if need be.</p>
<p>DISCLAIMER: I am not an expert.  If you break your phone while doing anything I mention here, I am not responsible.  This is just what I did to get everything to work.</p>
<p>1. The first order of business was to add the phone&#8217;s MAC address to DHCP so I could be sure what was accessing the tftp server.  I also needed to know the MAC address to create the proper files in the tftp directory.  Ensure that you set the tftp server, ntp server, and SIP server in DHCP.</p>
<pre>
group voip {
        option domain-name-servers 192.168.1.20, 1.2.3.4;
        option domain-name "inside.mycompany.com";
        option smtp-server 192.168.1.20;
        option ntp-servers 192.168.1.20;
        option time-servers 192.168.1.20;
        option routers 192.168.1.1;
        option sip-server 192.168.1.5;
        default-lease-time 86400; # 1 day
        max-lease-time 86400;
        server-name "192.168.1.20";
        option tftp-server-name "192.168.1.20";

        host myphone {
            hardware ethernet 00:19:E8:F4:B4:D0;
            fixed-address 192.168.1.200;
        }
}
</pre>
<p>2. When you first plug in the phone, it&#8217;s loaded with the Skinny protocol software only (SCCP), nothing for SIP.  This is because the phone was designed to work best (and really only) with the Cisco Call Manager.  The first thing I had to do was to obtain the files that go in the tftproot on 192.168.1.20.  In the upgrade package were the files:</p>
<ul>
<li>apps41.1-1-3-15.sbn</li>
<li>cnu41.3-1-3-15.sbn</li>
<li>copstart.sh</li>
<li>cvm41sip.8-0-3-16.sbn</li>
<li>dsp41.1-1-3-15.sbn</li>
<li>jar41sip.8-0-3-16.sbn</li>
<li>load115.txt</li>
<li>load30018.txt</li>
<li>load308.txt</li>
<li>load309.txt</li>
<li>SIP41.8-0-4SR1S.loads</li>
<li>term41.default.loads</li>
<li>term61.default.loads</li>
</ul>
<p>3. Once you place these files in the tftp root directory, you are ready for the upgrade.  (Note: You need a Cisco smartnet file (or be good with Google) to find these files).  Upgrading requires a factory reboot of the phone so it will look for the <strong>term61.default.loads</strong> file.  To perform a factory reset of the phone, hold down the &#8216;<strong>#</strong>&#8216; as the phone powers up.  Then dial &#8216;<strong>123456789*0#</strong>&#8216; and then let it work.  The next time it reboots, it should then grab the necessary files from the tftp server and upgrade itself.  You can watch the tftp logs and the phones LCD to ensure that everything that is supposed to be happening is happening.</p>
<p>4. At this point, the phone should be able to completely boot up and will likely just show you the word <em>Unprovisioned</em> at the bottom of the screen.  The next step is to create the files that each phone needs to survive.  The first file we are going to create is the <strong>SEP$MAC.cnf.xml</strong>.  In the case of the phone that I am going to use for this demo, the filename is: <strong>SEP0019E8F490AD.cnf.xml</strong>.  I know that the phone is also requesting the file <strong>CTLSEP0019E8F490AD.tlv</strong>, but you can safely ignore that.  The minimalist version of the SEP$MAC.cnf.xml file:</p>
<pre>
&lt;device&gt;
   &lt;deviceProtocol&gt;SIP&lt;/deviceProtocol&gt;
   &lt;sshUserId&gt;cisco&lt;/sshUserId&gt;
   &lt;sshPassword&gt;cisco&lt;/sshPassword&gt;
   &lt;devicePool&gt;
      &lt;dateTimeSetting&gt;
         &lt;dateTemplate&gt;M/D/Ya&lt;/dateTemplate&gt;
         &lt;timeZone&gt;Eastern Standard/Daylight Time&lt;/timeZone&gt;
         &lt;ntps&gt;
              &lt;ntp&gt;
                  &lt;name&gt;192.168.1.20&lt;/name&gt;
                  &lt;ntpMode&gt;Unicast&lt;/ntpMode&gt;
              &lt;/ntp&gt;
         &lt;/ntps&gt;
      &lt;/dateTimeSetting&gt;
      &lt;callManagerGroup&gt;
         &lt;members&gt;
            &lt;member priority="0"&gt;
               &lt;callManager&gt;
                  &lt;ports&gt;
                     &lt;ethernetPhonePort&gt;2000&lt;/ethernetPhonePort&gt;
                     &lt;sipPort&gt;5060&lt;/sipPort&gt;
                     &lt;securedSipPort&gt;5061&lt;/securedSipPort&gt;
                  &lt;/ports&gt;
                  &lt;processNodeName&gt;192.168.1.5&lt;/processNodeName&gt;
               &lt;/callManager&gt;
            &lt;/member&gt;
         &lt;/members&gt;
      &lt;/callManagerGroup&gt;
   &lt;/devicePool&gt;
   &lt;sipProfile&gt;
      &lt;sipProxies&gt;
         &lt;backupProxy&gt;&lt;/backupProxy&gt;
         &lt;backupProxyPort&gt;&lt;/backupProxyPort&gt;
         &lt;emergencyProxy&gt;&lt;/emergencyProxy&gt;
         &lt;emergencyProxyPort&gt;&lt;/emergencyProxyPort&gt;
         &lt;outboundProxy&gt;&lt;/outboundProxy&gt;
         &lt;outboundProxyPort&gt;&lt;/outboundProxyPort&gt;
         &lt;registerWithProxy&gt;true&lt;/registerWithProxy&gt;
      &lt;/sipProxies&gt;
      &lt;sipCallFeatures&gt;
         &lt;cnfJoinEnabled&gt;true&lt;/cnfJoinEnabled&gt;
         &lt;callForwardURI&gt;x--serviceuri-cfwdall&lt;/callForwardURI&gt;
         &lt;callPickupURI&gt;x-cisco-serviceuri-pickup&lt;/callPickupURI&gt;
         &lt;callPickupListURI&gt;x-cisco-serviceuri-opickup&lt;/callPickupListURI&gt;
         &lt;callPickupGroupURI&gt;x-cisco-serviceuri-gpickup&lt;/callPickupGroupURI&gt;
         &lt;meetMeServiceURI&gt;x-cisco-serviceuri-meetme&lt;/meetMeServiceURI&gt;
         &lt;abbreviatedDialURI&gt;x-cisco-serviceuri-abbrdial&lt;/abbreviatedDialURI&gt;
         &lt;rfc2543Hold&gt;false&lt;/rfc2543Hold&gt;
         &lt;callHoldRingback&gt;2&lt;/callHoldRingback&gt;
         &lt;localCfwdEnable&gt;true&lt;/localCfwdEnable&gt;
         &lt;semiAttendedTransfer&gt;true&lt;/semiAttendedTransfer&gt;
         &lt;anonymousCallBlock&gt;2&lt;/anonymousCallBlock&gt;
         &lt;callerIdBlocking&gt;2&lt;/callerIdBlocking&gt;
         &lt;dndControl&gt;1&lt;/dndControl&gt;
         &lt;remoteCcEnable&gt;true&lt;/remoteCcEnable&gt;
      &lt;/sipCallFeatures&gt;
      &lt;sipStack&gt;
         &lt;sipInviteRetx&gt;6&lt;/sipInviteRetx&gt;
         &lt;sipRetx&gt;10&lt;/sipRetx&gt;
         &lt;timerInviteExpires&gt;180&lt;/timerInviteExpires&gt;
         &lt;timerRegisterExpires&gt;3600&lt;/timerRegisterExpires&gt;
         &lt;timerRegisterDelta&gt;5&lt;/timerRegisterDelta&gt;
         &lt;timerKeepAliveExpires&gt;120&lt;/timerKeepAliveExpires&gt;
         &lt;timerSubscribeExpires&gt;120&lt;/timerSubscribeExpires&gt;
         &lt;timerSubscribeDelta&gt;5&lt;/timerSubscribeDelta&gt;
         &lt;timerT1&gt;500&lt;/timerT1&gt;
         &lt;timerT2&gt;4000&lt;/timerT2&gt;
         &lt;maxRedirects&gt;70&lt;/maxRedirects&gt;
         &lt;remotePartyID&gt;true&lt;/remotePartyID&gt;
         &lt;userInfo&gt;None&lt;/userInfo&gt;
      &lt;/sipStack&gt;
      &lt;autoAnswerTimer&gt;1&lt;/autoAnswerTimer&gt;
      &lt;autoAnswerAltBehavior&gt;false&lt;/autoAnswerAltBehavior&gt;
      &lt;autoAnswerOverride&gt;true&lt;/autoAnswerOverride&gt;
      &lt;transferOnhookEnabled&gt;false&lt;/transferOnhookEnabled&gt;
      &lt;enableVad&gt;false&lt;/enableVad&gt;
      &lt;preferredCodec&gt;g711ulaw&lt;/preferredCodec&gt;
      &lt;dtmfAvtPayload&gt;101&lt;/dtmfAvtPayload&gt;
      &lt;dtmfDbLevel&gt;3&lt;/dtmfDbLevel&gt;
      &lt;dtmfOutofBand&gt;avt&lt;/dtmfOutofBand&gt;
      &lt;alwaysUsePrimeLine&gt;false&lt;/alwaysUsePrimeLine&gt;
      &lt;alwaysUsePrimeLineVoiceMail&gt;false&lt;/alwaysUsePrimeLineVoiceMail&gt;
      &lt;kpml&gt;3&lt;/kpml&gt;
      &lt;natEnabled&gt;0&lt;/natEnabled&gt;
      &lt;natAddress&gt;&lt;/natAddress&gt;
      &lt;phoneLabel&gt;LinkExperts&lt;/phoneLabel&gt;
      &lt;stutterMsgWaiting&gt;1&lt;/stutterMsgWaiting&gt;
      &lt;callStats&gt;true&lt;/callStats&gt;
      &lt;silentPeriodBetweenCallWaitingBursts&gt;10&lt;/silentPeriodBetweenCallWaitingBursts&gt;
      &lt;disableLocalSpeedDialConfig&gt;false&lt;/disableLocalSpeedDialConfig&gt;
      &lt;startMediaPort&gt;16384&lt;/startMediaPort&gt;
      &lt;stopMediaPort&gt;32766&lt;/stopMediaPort&gt;
      &lt;sipLines&gt;
         &lt;line button="1"&gt;
            &lt;featureID&gt;9&lt;/featureID&gt;
            &lt;featureLabel&gt;100&lt;/featureLabel&gt;
            &lt;proxy&gt;192.168.0.205&lt;/proxy&gt;
            &lt;port&gt;5060&lt;/port&gt;
            &lt;name&gt;100&lt;/name&gt;
            &lt;displayName&gt;Eric Lubow&lt;/displayName&gt;
            &lt;autoAnswer&gt;
               &lt;autoAnswerEnabled&gt;2&lt;/autoAnswerEnabled&gt;
            &lt;/autoAnswer&gt;
            &lt;callWaiting&gt;3&lt;/callWaiting&gt;
            &lt;authName&gt;100&lt;/authName&gt;
            &lt;authPassword&gt;&lt;/authPassword&gt;
            &lt;sharedLine&gt;false&lt;/sharedLine&gt;
            &lt;messageWaitingLampPolicy&gt;1&lt;/messageWaitingLampPolicy&gt;
            &lt;messagesNumber&gt;*97&lt;/messagesNumber&gt;
            &lt;ringSettingIdle&gt;4&lt;/ringSettingIdle&gt;
            &lt;ringSettingActive&gt;5&lt;/ringSettingActive&gt;
            &lt;contact&gt;100&lt;/contact&gt;
            &lt;forwardCallInfoDisplay&gt;
               &lt;callerName&gt;true&lt;/callerName&gt;
               &lt;callerNumber&gt;true&lt;/callerNumber&gt;
               &lt;redirectedNumber&gt;false&lt;/redirectedNumber&gt;
               &lt;dialedNumber&gt;true&lt;/dialedNumber&gt;
            &lt;/forwardCallInfoDisplay&gt;
         &lt;/line&gt;
      &lt;/sipLines&gt;
      &lt;voipControlPort&gt;5060&lt;/voipControlPort&gt;
      &lt;dscpForAudio&gt;184&lt;/dscpForAudio&gt;
      &lt;ringSettingBusyStationPolicy&gt;0&lt;/ringSettingBusyStationPolicy&gt;
      &lt;dialTemplate&gt;dialplan.xml&lt;/dialTemplate&gt;
   &lt;/sipProfile&gt;
   &lt;commonProfile&gt;
      &lt;phonePassword&gt;&lt;/phonePassword&gt;
      &lt;backgroundImageAccess&gt;true&lt;/backgroundImageAccess&gt;
      &lt;callLogBlfEnabled&gt;1&lt;/callLogBlfEnabled&gt;
   &lt;/commonProfile&gt;
   &lt;loadInformation&gt;SIP41.8-0-4SR1S&lt;/loadInformation&gt;
   &lt;vendorConfig&gt;
      &lt;disableSpeaker&gt;false&lt;/disableSpeaker&gt;
      &lt;disableSpeakerAndHeadset&gt;false&lt;/disableSpeakerAndHeadset&gt;
      &lt;pcPort&gt;1&lt;/pcPort&gt;
      &lt;settingsAccess&gt;1&lt;/settingsAccess&gt;
      &lt;garp&gt;0&lt;/garp&gt;
      &lt;voiceVlanAccess&gt;0&lt;/voiceVlanAccess&gt;
      &lt;videoCapability&gt;0&lt;/videoCapability&gt;
      &lt;autoSelectLineEnable&gt;0&lt;/autoSelectLineEnable&gt;
      &lt;webAccess&gt;1&lt;/webAccess&gt;
      &lt;spanToPCPort&gt;1&lt;/spanToPCPort&gt;
      &lt;loggingDisplay&gt;1&lt;/loggingDisplay&gt;
      &lt;loadServer&gt;&lt;/loadServer&gt;
   &lt;/vendorConfig&gt;
   &lt;versionStamp&gt;1143565489-a3cbf294-7526-4c29-8791-c4fce4ce4c37&lt;/versionStamp&gt;
   &lt;networkLocale&gt;US&lt;/networkLocale&gt;
   &lt;networkLocaleInfo&gt;
      &lt;name&gt;US&lt;/name&gt;
      &lt;version&gt;5.0(2)&lt;/version&gt;
   &lt;/networkLocaleInfo&gt;
   &lt;deviceSecurityMode&gt;1&lt;/deviceSecurityMode&gt;
   &lt;authenticationURL&gt;&lt;/authenticationURL&gt;
   &lt;directoryURL&gt;&lt;/directoryURL&gt;
   &lt;idleURL&gt;&lt;/idleURL&gt;
   &lt;informationURL&gt;&lt;/informationURL&gt;
   &lt;messagesURL&gt;&lt;/messagesURL&gt;
   &lt;proxyServerURL&gt;proxy:3128&lt;/proxyServerURL&gt;
   &lt;servicesURL&gt;&lt;/servicesURL&gt;
   &lt;dscpForSCCPPhoneConfig&gt;96&lt;/dscpForSCCPPhoneConfig&gt;
   &lt;dscpForSCCPPhoneServices&gt;0&lt;/dscpForSCCPPhoneServices&gt;
   &lt;dscpForCm2Dvce&gt;96&lt;/dscpForCm2Dvce&gt;
   &lt;transportLayerProtocol&gt;4&lt;/transportLayerProtocol&gt;
   &lt;capfAuthMode&gt;0&lt;/capfAuthMode&gt;
   &lt;capfList&gt;
      &lt;capf&gt;
         &lt;phonePort&gt;3804&lt;/phonePort&gt;
      &lt;/capf&gt;
   &lt;/capfList&gt;
   &lt;certHash&gt;&lt;/certHash&gt;
   &lt;encrConfig&gt;false&lt;/encrConfig&gt;
&lt;/device&gt;
</pre>
<p>5. You will also need to create a dialplan so the phone doesn&#8217;t try to dial immediately.  Below is a minimalist <strong>dialplan.xml</strong> (which is the filename we used in the above schema).</p>
<pre>
&lt;DIALTEMPLATE&gt;
  &lt;TEMPLATE MATCH="." TIMEOUT="5" User="Phone" /&gt;
  &lt;TEMPLATE MATCH="2500" TIMEOUT="2" User="Phone" /&gt;
  &lt;TEMPLATE MATCH=".97" TIMEOUT="2" User="Phone" /&gt;
  &lt;TEMPLATE MATCH="5..." TIMEOUT="2" User="Phone" /&gt;
  &lt;TEMPLATE MATCH="1.........." TIMEOUT="2" User="Phone" /&gt;
&lt;/DIALTEMPLATE&gt;
</pre>
<p>6. Although I am still not entirely sure that you need them, here are 2 other files that I was told need to be referenced:<br />
<strong>SIPDefault.cnf:</strong></p>
<pre>
# Image Version
image_version: "P0S3-08-6-00"

# Proxy Server
proxy1_address: "192.168.1.5"

# Proxy Server Port (default - 5060)
proxy1_port:"5060"

# Emergency Proxy info
proxy_emergency: "192.168.1.5" # IP address here alternatively
proxy_emergency_port: "5060"

# Backup Proxy info
proxy_backup: "192.168.0.205"
proxy_backup_port: "5060"

# Outbound Proxy info
outbound_proxy: ""
outbound_proxy_port: "5060"

# NAT/Firewall Traversal
nat_enable: "0"
nat_address: "192.168.1.5"
voip_control_port: "5061"
start_media_port: "16384"
end_media_port: "32766"
nat_received_processing: "0"

# Proxy Registration (0-disable (default), 1-enable)
proxy_register: "1"

# Phone Registration Expiration [1-3932100 sec] (Default - 3600)
timer_register_expires: "3600"

# Codec for media stream (g711ulaw (default), g711alaw, g729)
preferred_codec: "none"

# TOS bits in media stream [0-5] (Default - 5)
tos_media: "5"

# Enable VAD (0-disable (default), 1-enable)
enable_vad: "0"

# Allow for the bridge on a 3way call to join remaining parties upon hangup
cnf_join_enable: "1" ; 0-Disabled, 1-Enabled (default)

# Allow Transfer to be completed while target phone is still ringing
semi_attended_transfer: "0" ; 0-Disabled, 1-Enabled (default)

# Telnet Level (enable or disable the ability to telnet into this phone
telnet_level: "2" ; 0-Disabled (default), 1-Enabled, 2-Privileged

# Inband DTMF Settings (0-disable, 1-enable (default))
dtmf_inband: "1"

# Out of band DTMF Settings (none-disable, avt-avt enable (default), avt_always - always avt ) dtmf_outofband: "avt" ~np~# DTMF dB Level Settings (1-6dB down, 2-3db down, 3-nominal (default), 4-3db up, 5-6dB up)
dtmf_db_level: "3"

# SIP Timers
timer_t1: "500" ; Default 500 msec
timer_t2: "4000" ; Default 4 sec
sip_retx: "10" ; Default 11
sip_invite_retx: "6" ; Default 7
timer_invite_expires: "180" ; Default 180 sec

# Setting for Message speeddial to UOne box
messages_uri: "*97"

# TFTP Phone Specific Configuration File Directory
tftp_cfg_dir: "./"
# Time Server
sntp_mode: "unicast"
sntp_server: "ntp2.usno.navy.mil" # IP address here alternatively
time_zone: "EST"
dst_offset: "1"
dst_start_month: "April"
dst_start_day: ""
dst_start_day_of_week: "Sun"
dst_start_week_of_month: "1"
dst_start_time: "02"
dst_stop_month: "Oct"
dst_stop_day: ""
dst_stop_day_of_week: "Sunday"
dst_stop_week_of_month: "8"
dst_stop_time: "2"
dst_auto_adjust: "1"

# Do Not Disturb Control (0-off, 1-on, 2-off with no user control, 3-on with no user control)
dnd_control: "0" ; Default 0 (Do Not Disturb feature is off)

# Caller ID Blocking (0-disabled, 1-enabled, 2-disabled no user control, 3-enabled no user control)
callerid_blocking: "0" ; Default 0 (Disable sending all calls as anonymous)

# Anonymous Call Blocking (0-disbaled, 1-enabled, 2-disabled no user control, 3-enabled no user control)
anonymous_call_block: "0" ; Default 0 (Disable blocking of anonymous calls)

# Call Waiting (0-disabled, 1-enabled, 2-disabled with no user control, 3-enabled with no user control)
call_waiting: "1" ; Default 1 (Call Waiting enabled)

# DTMF AVT Payload (Dynamic payload range for AVT tones - 96-127)
dtmf_avt_payload: "101" ; Default 100

# XML file that specifies the dialplan desired
dial_template: "dialplan"

# Network Media Type (auto, full100, full10, half100, half10)
network_media_type: "auto"

#Autocompletion During Dial (0-off, 1-on [default])
autocomplete: "0"

#Time Format (0-12hr, 1-24hr [default])
time_format_24hr: "1"

# URL for external Phone Services
services_url: "" # IP address here alternatively

# URL for external Directory location
directory_url: "" # IP address here alternatively

# URL for branding logo
logo_url: "" # IP address here alternatively

# Remote Party ID
remote_party_id: 1 ; 0-Disabled (default), 1-Enabled
</pre>
<p>and<br />
<strong>XmlDefault.cnf.xml</strong></p>
<pre>
&lt;Default&gt;
&lt;callManagerGroup&gt;
    &lt;members&gt;
       &lt;member priority="0"&gt;
          &lt;callManager&gt;
             &lt;ports&gt;
                &lt;ethernetPhonePort&gt;2000&lt;/ethernetPhonePort&gt;
                &lt;mgcpPorts&gt;
                   &lt;listen&gt;2427&lt;/listen&gt;
                   &lt;keepAlive&gt;2428&lt;/keepAlive&gt;
                &lt;/mgcpPorts&gt;
             &lt;/ports&gt;
             &lt;processNodeName&gt;&lt;/processNodeName&gt;
          &lt;/callManager&gt;
       &lt;/member&gt;
    &lt;/members&gt;
 &lt;/callManagerGroup&gt;
&lt;loadInformation30018 model="IP Phone 7961"&gt;P0S3-08-6-00&lt;/loadInformation30018&gt;
&lt;loadInformation308 model="IP Phone 7961G-GE"&gt;P0S3-08-6-00&lt;/loadInformation308&gt;
&lt;authenticationURL&gt;&lt;/authenticationURL&gt;
&lt;directoryURL&gt;&lt;/directoryURL&gt;
&lt;idleURL&gt;&lt;/idleURL&gt;
&lt;informationURL&gt;&lt;/informationURL&gt;
&lt;messagesURL&gt;&lt;/messagesURL&gt;
&lt;servicesURL&gt;&lt;/servicesURL&gt;
&lt;/Default&gt;
</pre>
<p>This should be all the examples and information that you need to get going with your Cisco 7961(|G|GE) phone.  Simplicity at it&#8217;s finest, eh Cisco?</p>
]]></content:encoded>
			<wfw:commentRss>http://eric.lubow.org/blog/2007/system-administration/asterisk-pbx/38/configuring-a-cisco-7961-for-sip-and-asterisk/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Asterisk Echo Cancellation</title>
		<link>http://eric.lubow.org/blog/2007/system-administration/asterisk-pbx/37/asterisk-echo-cancellation/</link>
		<comments>http://eric.lubow.org/blog/2007/system-administration/asterisk-pbx/37/asterisk-echo-cancellation/#comments</comments>
		<pubDate>Thu, 17 May 2007 20:47:49 +0000</pubDate>
		<dc:creator>eric</dc:creator>
		
		<category><![CDATA[Asterisk]]></category>

		<guid isPermaLink="false">http://eric.lubow.org/blog/2007/system-administration/asterisk-pbx/37/asterisk-echo-cancellation/</guid>
		<description><![CDATA[I was lucky (or unlucky) enough to have to rebuild my company&#8217;s Asterisk server to prepare to have a backup.  I took a slightly less powerful machine, installed Debian Etch on it and threw Asterisk 1.2.13 on it.  The goal was to mimic the Asterisk configuration on its sister machine which was a [...]]]></description>
			<content:encoded><![CDATA[<p>I was lucky (or unlucky) enough to have to rebuild my company&#8217;s Asterisk server to prepare to have a backup.  I took a slightly less powerful machine, installed Debian Etch on it and threw Asterisk 1.2.13 on it.  The goal was to mimic the Asterisk configuration on its sister machine which was a Gentoo 1.2.10 install (eventually to be upgraded to 1.4.4).  The FXO cards in both machines are exactly the same.  They are the TDM400P.  Everything went smoothly except when I got the computer in place, the echo that came in was unbearable.</p>
<p>This brings me to the topic title.  There is a lot of information that one needs to know to be good at this.  And like usual, I didn&#8217;t have time to get to it all.  Therefore I will show a summary of commands and tasks and provide you with a few links that helped me out.  Long story short, read the docs so you don&#8217;t completely mess everything up.</p>
<p>It should also be noted that the config files that some of these options reside in may differ slightly depending on your configuration.</p>
<p>One of the first things that should be done is to run <a href="http://www.voip-info.org/wiki/view/Asterisk+fxotune">fxotune</a>.  Ensure Asterisk isn&#8217;t running when you run this and beware because it took approximately 20mins to run on my P4 2.8GHz w/ 256M RAM.  Run it using the following command:<br />
<code>fxotune -i 4</code><br />
The eventual result came out to be below in my /etc/fxotune.conf.  Just be sure that run <code>fxotune -s</code> before starting Asterisk so your settings get used.<br />
<code>1=8,0,0,0,0,0,0,0,0<br />
2=6,0,0,0,0,0,0,0,0<br />
3=6,0,0,0,0,0,0,0,0<br />
4=6,0,0,0,0,0,0,0,0</code></p>
<p>That did a good job, but it just wasn&#8217;t where it needed to be yet.  The next thing I did should have been the first thing I did.  Ensure all the telephone wires are as short as possible (while still being long enough to serve their purpose) and are away from all sources of power.  This helped with the slight hum I would hear on some calls (this whole scenario is scary to me and thankfully it will be fixed shortly).</p>
<p>Next I moved on to the echo cancellation internals that Asterisk has.  First, in the <em>phone.conf</em>, I changed the variable <strong>echocancel</strong> to <strong>high</strong>.  Obviously, you should step through the possible values incrementally, but mine was already set on <strong>medium</strong>, so <strong>high</strong> was the next logical value.</p>
<p>Most of the work was done here in the <em>zapata.conf</em> file.  The first value that I tinkered with here is the <strong>echocancel</strong> (same name as in the <em>phone.conf</em> file).  It was initially set to <strong>yes</strong> which means that Asterisk automatically defaults to a value of 128 taps.  Knowing that this variable has to be a power of 2, I decided to have some fun.  I started at 2 and went straight up through 256.  As it turned out, <strong>64</strong> ended up being the best.  They say it is impossible to hear with the normal ear, but there was enough of a difference that I was able to discern which sounded better.  Sometimes I couldn&#8217;t hear a difference at all (which is what I assume the docs were referencing), but as soon as I heard the difference between 64 and 128, I left it at 64.  The last variable I toyed with was <strong>echotraining</strong>.  <strong>echotraining</strong> was off initially. I tried calls with it on and off and there was a significant difference in initial call quality when <strong>echotraining</strong> was on.  If these didn&#8217;t work, I would have messed with the value of the <strong>jitterbuffers</strong>.  However, it is sufficient at <strong>10</strong> because of the small amount of memory that this machine has.</p>
<p>Eventually, once I have more time (and all sysadmins know this is a rarity), I want to move on to adjusting the <em>rxgain/txgain</em>.  More information on this can be found <a href="http://www.asteriskdocs.org/modules/tinycontent/content/docbook/current/docs-html/x1695.html">here</a>.  I didn&#8217;t have a need for it now since I have reached what is believed to be tolerable.  But ultimately I don&#8217;t want to have to deal with this again and I want to finish the job.</p>
<p>Hope this allows at least one person to have a one stop shop for information on echo cancellation and can save them a long night or headache.</p>
<p>References:</p>
<ul>
<li><a href="http://www.voip-info.org/wiki/view/Causes+of+Echo">Causes of Echo</a></li>
<li><a href="http://www.voip-info.org/wiki/view/Asterisk+echo+cancellation">Asterisk Echo Cancellation</a></li>
<li><a href="http://www.voip-info.org/wiki/index.php?page=Asterisk+echo+analog+lines">Asterisk Echo Analog Lines</a></li>
<li><a href="http://www.google.com/url?sa=t&#038;ct=res&#038;cd=6&#038;url=http%3A%2F%2Fwww.linuxjournal.com%2Farticle%2F8424&#038;ei=CblMRo_FMZj-wQKe04SLDQ&#038;usg=AFrqEzdKLcPiidETUNw0MM7KC6IOFSYg1w&#038;sig2=tmA1U3KxiUuJruARdJ-fng">Echo and SoftVoIP PBX Systems</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://eric.lubow.org/blog/2007/system-administration/asterisk-pbx/37/asterisk-echo-cancellation/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>
