In my last post, I suspected problems with the rotary dial on the Automatic Electric Monophone model 40, and a wiring problem on the Northern Electric 302, both of which kept me from being able to successfully pulse-dial through the HandyTone 502 analog adapter.
Tag Archives: analog
A brief review of the Grandstream HT-502 ATA
The used HT-502 2-FXS analog telephony adapter I bought from eBay arrived earlier this week, and I hoped that by this time I could write about two functional rotary dial phones happily dialing out through this device.
No such luck, but the HT-502 is not to blame. The Northern Electric 302 seems to be mis-wired, because the ATA isn’t detecting the pulse dialing at all. I’ll have to open it up and dig in this weekend. The Automatic Electric Monophone 40, on the other hand, is wired correctly but needs some adjustment: the upper digits (7 through 0) sometimes miss a click, resulting in mis-dialing.
That said, I’m already prepared to give the Grandstream HT-502 ATA very positive reviews. In fact, I might like it even better than my trusty Cisco-Linksys-Sipura SPA3102.
You can read about the device on Grandstream’s web site. Here are the unmentioned features that I really like:
- It accepts rotary/pulse dialing, without any special configuration or modification. This was the reason I bought it, and indeed, it works. The HT-503 (1 FXS and 1 FXO port) can accept pulse dialing on its FXS port, also.
- On an active call, it accepts rotary-dialed input and converts to SIP DTMF codes. Thus you can navigate a menu tree with your rotary phone, as long as you don’t need “*” or “#”.
- You can configure the device with a touch-tone phone (real touch-tone; “*” required), web browser, or telnet. You can also provision the device using TFTP like the “big guys” do.
- It has an excellent debugger. In the Advanced menu, enter the IP address of your syslog server (prerequisite: set up a syslog server), and set the verbosity to DEBUG. The floodgates will open and you will be able to see every action the device performs or receives, including dialed digits from the analog ports. This is how I was able to see where my rotary dial was sticking.
- The device can pull its own firmware upgrades over the Internet. Nice if used carefully.
- It’s super easy to configure. I followed documentation to factory-reset the device, hooked up a laptop to the LAN port, and reconfigured it for my own network in about 5-10 minutes.
- Lastly–and this is a rather obscure bonus–it uses the same power supply specifications as the Cisco-Linksys SPA devices. This hardly matters except that I have one of these–a wireless bridge for Cisco SPA devices with pass-through power. I’m planning to make the HT-502 WiFi.
The HandyTone 502 has made a good first impression and I’m looking forward to getting my rotary phones fully working on it.
A new old phone and rotary dialing, revisited
During the holidays I received and lightly restored another beautiful telephone from the 1940s, this Automatic Electric Monophone model 40:
Automatic Electric was an independent supplier of telephone equipment throughout the 20th century, eventually being purchased by GTE, and in direct competition with the Bell empire (or Western Electric, Bell’s equipment division) throughout its existence. The community-written Wikipedia article tells more of the story.
Some details about this Monophone:
- Manufactured from 1939 to the mid-fifties, but I can’t find a stamp on the inside or outside to date it.
- The coiled handset cable would typically indicate a later model, but the nicked-up brass screws inside the handset where the cable is connected suggest that the coiled cable was an upgrade or repair at some point in this phone’s lifetime. So it may be an old phone body with a newer cable, or it may be a later model, all-original.
- The dial plate seems to be uncommon. Browsing many pictures of AE model 40s on the web, I haven’t seen any others with white-numbered, black dial plates. Also, it has no alphabet markings, only digits.
- It’s all Bakelite, and heavy. The Northern Electric 302, with a thermoplastic shell, is almost a full pound lighter. External data: someone weighed their own collection of phones.
The Northern Electric 302 and the Automatic Electric Monophone 40 ready to duel:
The AE40 works fine and will be a new addition to the analog remix, but I decided to do one more search for VoIP analog telephony adapters (ATAs) that will accept rotary/pulse dialing. Recently, a commenter suggested UTStarcom adapters, but others report of an ATA that is still in service and accepts rotary dialing: the Grandstream HT-502/503. I have a 502 coming from an eBay auction and will report back on how it works out.
Appendix: analog remix debugging and notes
Part 1: Intro, Part 2: Tropo/PHP, Part 3: Asterisk Manager/Perl
These notes are from a weekend of hacking and debugging with Michigan Telephone, the first guinea pig to try out the “analog remix” scripts. Thanks for the extra challenges. 🙂
Asterisk 1.4, 1.8 and the Asterisk Manager Interface
- Asterisk 1.4’s Manager calls the channel that is bridged to the current channel “Link.” Newer versions, more sensibly, call it “BridgedChannel.” I updated the Perl CGI to use whichever is defined, so now the CGI will work with newer versions of Asterisk, and not just 1.4.
- A bug exists on specific versions of Asterisk 1.4, 1.6 and 1.8 that breaks call transfer from the Manager (as well as SIP blind transfers). The current -rc1 versions, as of this writing, have the fix: 1.4.39-rc1, 1.6.2.16-rc1, and 1.8.2-rc1. This bug has been in 1.4 since 1.4.38-rc1; in 1.6 since 1.6.2.15-rc1; and in 1.8 since 1.8.0-rc4. If you’re on a buggy version, the transfer will just hang up the channel.
- How to set up the Manager user may not be obvious. Just make a new user block in manager.conf or manager_custom.conf (FreePBX) with the following permissions:
[tropousername]
secret = tropopassword
deny=0.0.0.0/0.0.0.0
permit=127.0.0.1/255.255.255.0
read = call
write = callSet the username and password to whatever you want, and then use these in the Perl CGI in the
AMI::Common::new()
function. Your manager user needs only “call” permissions to perform the actions in the CGI.
Perl
- MT notes that you may have to install the AnyEvent and parent Perl modules before Asterisk::AMI. Use CPAN’s installer if you can:
perl -MCPAN -e shell
andinstall parent
,AnyEvent
, andAsterisk::AMI
- The Data::Dumper module can be really helpful if you find that things aren’t going well with your CGI. Just
use Data::Dumper
at the top of the CGI, thenprint STDERR Dumper($variablename)
wherever you need it. Try this on a hash, such as $currchan, and you’ll get a dump of the whole thing.
Firewall/ACL
You may want to set up a separate Apache VirtualHost with access controls (username/password and/or IP access list) for your Tropo CGI. Or, if your web server is firewalled, you’ll need to let Tropo in to make the request. Tropo’s support team indicated that requests will come from 66.193.54.21, so this IP can be allowed through your firewall. They will announce any changes to this on changes.tropo.com.
Analog remix part 3: some Perl CGI to route the call
Part 3 of the analog remix ties it all together. We need a way for Tropo to tell Asterisk to transfer the call, since we’re not going to use SIP REFER. A simple Perl CGI that connects to Asterisk Manager Interface (AMI) will do the trick.
I’m sticking with old-school Perl for this one because I really like Ryan Bullock’s Asterisk::AMI modules. His code is easy to use and he keeps it up to date.
Referring back to part 2, you can see where the curl function calls tropo.cgi (the Perl script below) with parameters f=xfer (the only function for now), callid=the SIP Call-ID, and dest=the number the caller requested. The Perl script finds the Call-ID by iterating through the channel list, finding one that’s connected to Tropo, and then checking the Call-ID to make sure it’s the exact one. (You could have more than one channel open to Tropo.) Once it finds that, it transfers the second leg of that call, which is the caller. Output is to STDERR so that I can review the transaction in the Apache error log.
Updated 12/19/2010: This line
my $link = $currchan->{'Link'} || $currchan->{'BridgedChannel'};
is updated to use either the key returned by Asterisk 1.4 (“Link”) or by later versions (“BridgedChannel”) in the channel listing.
The code:
#!/usr/bin/perl
use strict;
use Asterisk::AMI::Common;
use CGI;
use URI::Escape;
select(STDERR);
local $| = 1;
select(STDOUT);
local $| = 1;
my $cgi = CGI->new;
my $func = $cgi->param('f');
my $callid = uri_unescape($cgi->param('callid'));
my $dest = $cgi->param('dest');
print $cgi->header("text/plain");
if(defined $func) {
if($func eq "xfer") {
if(defined $dest && $dest ne "") {
my $ami = Asterisk::AMI::Common->new (PeerAddr => 'localhost',
PeerPort => '5038',
Username => 'USERNAME',
Secret => 'PASSWORD',
Events => 'off',
on_error => &errorHandler
)
or die "Unable to connect to Asterisk Manager.n";
my $channels = $ami->channels;
if (defined($channels)) {
foreach my $channel (keys %{$channels}) {
my $currchan = %{$channels}->{"$channel"};
if ($channel =~ m/tropo.com/) { # find channels connected to Tropo
my $currchan_callid = $ami->get_var($channel, "SIPCALLID");
if ($currchan_callid == $callid) { # make sure it's the right call,
print STDERR "Channel $channel"; # identified by Call-ID
print STDERR "Callid $callid";
my $link = $currchan->{'Link'} || $currchan->{'BridgedChannel'};
if (defined($link)) { # this is the initiating leg of the call
my $transfer = $ami->transfer($link, $dest, "from-internal");
if (defined($transfer)) {
if ($transfer == 1) {
print STDERR "Tropo successfully transferred $link to $dest.";
} else {
print STDERR "Tropo FAILED to transfer $link to $dest.";
}
} else {
print STDERR "System error performing transfer.";
}
} else {
print STDERR "Local channel leg not found.";
}
}
}
}
} else {
print STDERR "Could not get channel list from Asterisk manager.";
}
$ami->disconnect; # close Manager connection
} else {
print STDERR "xfer requested but no dest specified.";
}
} else {
print STDERR "Invalid function sent in CGI.";
}
} else {
print STDERR "No function sent in CGI.";
}
print "Done.n";
exit;
#### Functions ####
sub errorHandler { # A fatal error occurred
my ($amiobj, $errmsg) = @_;
print STDERR "AMI Fatal error: $errmsgn";
exit 1;
}
Summary
Starting with part 1, configure a hot line or warm line for your old analog device to automatically ring an extension on your system. You’ll define that extension as the SIP URI to the Tropo application you made in part 2. The Tropo application, in turn, will connect back to your Asterisk server running web services (Apache) with a CGI that can take the input and connect to the Asterisk Manager Interface and transfer your call. Simple! 🙂
Analog remix part 2: Tropo
- Interactive voice-response (IVR) systems
- Chat or Twitter robot
- Dialer
- Call routing based on logic in the script
- Text-to-speech
- Speech-to-text
- Audio recording
- Whatever you can normally do with the aforementioned scripting languages, but note that the stdout will be a communications outlet such as a SIP channel, a Twitter feed or conversation, a chat, or an SMS–not a web page
SIP/somenumber@sip.tropo.com
. I set mine up as extension 1100, which I mentioned in the previous post.Appendix: the PHP code (Number, Please?)
<?php
// Main
// SSML tags needed for advanced text-to-speech manipulation
$ssml_start = "<?xml version='1.0'?><speak>";
$sayas_end="</say-as>";
$sayas_digits ="<say-as interpret-as='vxml:digits'>";
$ssml_end = "</speak>";
answer();
// These IDs are used to identify the caller and the Asterisk box
$callid = $currentCall->getHeader('x-sbc-call-id');
$hostid = trim((strstr($callid, '@')),'@');
_log("Call-ID is $callid");
_log("Host is $hostid");
wait(1000);
$haveNumber = false;
while (!$haveNumber) {
$number = ask($ssml_start . "Number <emphasis level='reduced'>please?</emphasis>" .
$ssml_end,
array(voice => "allison",
attempts => 3,
bargein => false,
choices => "[4-16 DIGITS]",
minConfidence => 0.4,
timeout => 8,
onBadChoice => "handlerBadChoice",
onError => "handlerError",
onHangup => "handlerHangup",
onTimeout => "handlerTimeout"
));
// Confirm the number with the caller
// 1 and 0 are options for testing with DTMF
$yesno = ask($ssml_start . $sayas_digits . $number->value . $sayas_end .
", is this correct?" . $ssml_end,
array(voice => "allison",
attempts => 2,
bargein => false,
choices => "yes, no, 1, 0",
minConfidence => 0.5,
timeout => 3,
onBadChoice => "handlerBadChoice",
onError => "handlerError",
onHangup => "handlerHangup",
onTimeout => "handlerTimeout"
));
_log("Caller said $yesno->value.");
if ($yesno->value == "yes" || $yesno->value == "1") {
$haveNumber = true;
} else {
say("OK, let's try again.");
}
}
// The CGI callback. Refer to a future posting for the design
// Customize for your server. Use SSL for security if you can.
$url = "http://$hostid/tropo.cgi?f=xfer&callid=" . urlencode($callid) .
"&dest=" . $number->value;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($ch, CURLOPT_USERPWD, "USERNAME:PASSWORD");
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
_log("Received from CGI: " . $result = curl_exec($ch));
if (!$result) {
_log(curl_error($ch));
}
curl_close($ch);
// If the transfer didn't happen, the caller is still here...
if ($currentCall->isActive()) {
_log("Transfer failed and caller still on the line.");
say("I'm sorry, something went wrong. Please try again later.");
hangup();
}
return;
// END OF MAIN
// Function definitions
function handlerBadChoice($event) {
say("I'm sorry, I didn't understand you.");
if($event->attempt >= 3) {
say("Goodbye.");
hangup();
}
return;
}
function handlerError($event) {
_log("Error occurred: $event->value");
say("I'm sorry, an error occurred. Goodbye");
hangup();
return;
}
function handlerHangup($event) {
_log("Caller hung up.");
exit;
}
function handlerTimeout($event) {
say("I'm sorry, I didn't hear you.");
if($event->attempt >= 3) {
say("Goodbye.");
hangup();
}
return;
}
?>
Analog remix part 1: a VoIP manual service exchange
Recently, I decided to revisit the analog side of my home Asterisk VoIP system, specifically, the Northern Electric 302 that I keep hooked up and on display. It’s a conversation piece, for when folks spot the rotary-dial phone, they ask, “Does that thing work?” At that point I explain that I can answer calls on it, but because of the rotary dial (and because I haven’t fashioned or purchased a rotary-to-DTMF converter) I can’t place a call from it.
- configuring the analog adapter as an automatic ringdown (hot-line) or warm-line
- programming the speech-to-text “operator” service on Tropo
- programming the call-back CGI on a web server that can connect to the Asterisk Manager and perform call-handling functions
The following implements a Hot Line phone, which automatically calls 1 212 5551234.
The following provides a Warm Line to a local office operator (1000) after five seconds, unless a four-digit extension is dialed by the user.
| P6 <:1100> |
, which tells the ATA to automatically connect the call to extension 1100 after six seconds of no input.For reliable telephone service, you need batteries, somewhere
In a recent post at mgraves.org, Michael Graves observed that today’s POTS [plain old telephone service] analog equipment seldom runs just off the phone line power, as it used to. It needs “wall power.” And folks who claim that POTS is more reliable than VoIP because the power comes over the phone line are likely forgetting this, or remembering their Trimline from thirty years ago that did indeed run solely on phone line power and worked during an electricity outage.
The telco knew the importance of reliable phone service and set up large banks of batteries at the central office that would power the lines at all times. If the electricity is out, the phone is still up, because the wall or desk phone they leased you (or later, that you bought yourself) ran off that line power. When cordless phones, FAX machines, and other more advanced analog sets came out, many did not or could not run off of phone line power and now required AC electric power. This new requirement undermined the reliability that the telco had put in place long ago.
To keep your advanced analog equipment online during a power outage, now you’d need the telco’s batteries as well as local batteries–an uninterruptible power supply, or UPS. This is what we have in place for PSU VoIP.
Our “central office”–actually, the data centers where the VoIP servers, gateways and other core devices reside–are covered by large UPSes and diesel generators. Anything between the core and the endpoint (your phone) that requires electricity is also on a UPS, including the PoE switch to which your phone is connected. Thus, if the electricity goes out, your VoIP phone will still be online.
Whether you go with POTS or VoIP, you need batteries, somewhere, to keep your phone service alive.
New phone guy meets Old Phone Guy
At a flea market earlier in the year, my mother picked up a Northern Electric (Western Electric’s Canadian counterpart) 302 telephone, manufactured in August 1948, for $20. She gave it to me during a recent visit and I set out to make it work on my home Asterisk setup.
The short of it is, it’s functional. I needed to replace the line and handset cords and give the thing a thorough cleaning, but it works. That is to say, it gets a dial tone from my analog telephone adapter and I can answer calls on it. The ringer is extremely weak as I think my ATA only supports about 2, maybe 2.5 REN and the 302 probably needs about that much current to ring the bells. I had thought that a 302 would be 1 REN but maybe this wasn’t standardized until the 500 set.
What to do about the rotary dial? I’ll buy a pulse-to-tone converter or wire up an inline keypad if I want to get creative–or find a Digium IAXy ATA, now discontinued–but until then, I have a workaround. Some time ago, a friend gave me an old Sharp organizer, the kind that stores a couple hundred names and phone numbers and plays touch tones into your handset for “speed dialing.” He found it in a drawer and gave it to me as a joke. Switch it to manual mode and I now have a dialer for my antique phone.
There are lots of resources on the web for people who want to fix up antique phones. I’m not an antiques person but I’m having fun with this little project and will keep my eyes open for more analog goodness in the future. Oldphoneguy is a great resource for restoring and wiring up old phones to work on modern lines. And Bell System Memorial, which I mentioned in an earlier blog post, has some great historical information.