Search

Tuesday, April 27, 2010

Connection refused by localdomain

Recently, one of my clients could not send out emails through his web conferencing platform.  More precisely, he could not send out conference invitation emails to some receipients, for example, hotmail.com.
 
His /var/log/maillog showed a number of  "connection refused by XXX.localdomain" messages and he suspected that it is the root cause of failed delivery.
 
In fact, "connection refused" was due to missing hostname in /etc/mail/access and local-host-names.  To fix it, I firstly added back his hostname XXX in access:
"XXX    RELAY"
and recompiled the access.db by:
"makemap  hash access.db < access"
 
Then I updated /etc/mail/local-host-names which tells sendmail the machine name.
 
After making these changes effective by restarting sendmail daemon via "service sendmail restart", we finally understood why some emails could not be delivered.
 
The maillog now showed that the client's ip address was blacklisted in SPAMHAUS, a free internet blacklist service used by many email servers, including hotmail, as spam filter.
 
I guessed the client's server had been compromised some time ago and was captured by SPAMHAUS.
 
 
 
 
 
 
 
 
 
 

Wednesday, April 21, 2010

app_meetme, zaptel, DAHDI on asterisk 1.4.22 and fc11

app_meetme, zaptel, DAHDI on asterisk 1.4.22 and fc11
=====================================================
App_meetme requires a timer (or ztdummy if we don't have hardware card installed).  Prior to asterisk 1.4.22,
we usually deploy zaptel and load ztdummy module.
 
However, zaptel is too old to work on fc11.  You will probably encounter 
"error: 'struct hrtimer' has no member named 'expires'" when building zaptel.
 
Starting from asterisk 1.4.22, DAHDI (Digium Asterisk Hardware Device Interface) is supported.
We could use DAHDI instead of zaptel to provide a timing source to app_meetme.
 
DAHDI is the new name for 'Zaptel' as of May 19th 2008.
The post at http://blogs.digium.com/2008/05/19/zaptel-project-being-renamed-to-dahdi/ details the reason for the change. Asterisk 1.4 releases later than 1.4.21, and all releases of Asterisk 1.6, will automatically use DAHDI in preference to Zaptel, even if Zaptel is still installed on the system.
 
Below shows how to download and install DAHDI.
Download the DAHDI tarball from :
cd /usr/src
wget http://www.asterisk.org/downloads
// you'd better select the full package, ie both drivers and tools
cd <the DAHDI directory>
make all
make install
make config
 
// now rebuild Asterisk
cd /usr/src/<asterisk>
./configure
make menuselect // make sure packages app_meetme, dahdi are selected
make
make install
 
// make DAHDI  run on reboot
chkconfig --add dahdi
 
// start
service dahdi start
if you don't have hardware card installed, you'll probably see dahdi_dummy loaded
No hardware timing source found in /proc/dahdi, loading dahdi_dummy
Running dahdi_cfg:                                         [  OK  ]
 

// and you can also verify what is up by
[root@virtualbox01 tools]# lsmod |grep dahdi
dahdi_transcode         6140  1 wctc4xxp
dahdi_voicebus         35752  2 wctdm24xxp,wcte12xp
dahdi                 182880  11 xpp,dahdi_transcode,wcb4xxp,wctdm,wcfxo,wctdm24                                              xxp,wcte11xp,wct1xxp,wcte12xp,dahdi_voicebus,wct4xxp
crc_ccitt               1588  2 wctdm24xxp,dahdi
 

// bring up asterisk
service asterisk start
 
// and check that app_meetme and dahdi are there
CLI> module show like dahdi
Module                         Description                              Use Count
codec_dahdi.so                 Generic DAHDI Transcoder Codec Translato 0      
app_dahdiras.so                DAHDI RAS Application                    0      
app_dahdiscan.so               Scan Zap channels application            0      
app_dahdibarge.so              Barge in on channel application          0      
chan_dahdi.so                  DAHDI Telephony                          0      
 
CLI> module show like meetme
Module                         Description                              Use Count
app_meetme.so                  MeetMe conference bridge                 0      
 

// now you should be able to run app_meetme using the dahdi_dummy timer
 
 
 

Tuesday, April 20, 2010

Call center monitoring and recording

We can use Asterisk to build a call center system using below asterisk features:
- app_queue
- chan_agent
 
Agent conversation is recorded using Monitor() in the dial plan.
 
At the same time, the call center manager can monitor agent conversation via ChanSpy(), e.g., Chanspy(SIP/xxxx|bq) where SIP/XXXX is the agent extension.
 
We need to enable transmit_silence_during_record in asterisk.conf.  Otherwise, chanspy could not listen on the bridged channels which are being recorded at the same time.
 
asterisk.conf
==========
transmit_silence_during_record = yes ; Transmit SLINEAR silence while a channel is being recorded

Wednesday, April 14, 2010

Ringall in asterisk queue does not ring 'all' agent

The asterisk app_queue provides several distribution strategies with ringall as the default one.  This setting is supposed to ring all available agents until one answers.

 

If ringall does not behave as expected, we should check that autofill is enabled or not.

 

The autofill indicator is specified in queue.conf for static queue.  If realtime queue is adopted, there should be a field autofill in  asterisk.queue_table. 

desc queue_table;

+-----------------------------+--------------+------+-----+---------+-------+

| Field                       | Type         | Null | Key | Default | Extra |

+-----------------------------+--------------+------+-----+---------+-------+

| name                        | varchar(128) | NO   | PRI |         |       |

| musiconhold                 | varchar(128) | YES  |     | NULL    |       |

| announce                    | varchar(128) | YES  |     | NULL    |       |

| context                     | varchar(128) | YES  |     | NULL    |       |

| timeout                     | int(11)      | YES  |     | NULL    |       |

| monitor_join                | tinyint(1)   | YES  |     | NULL    |       |

| monitor_format              | varchar(128) | YES  |     | NULL    |       |

| queue_youarenext            | varchar(128) | YES  |     | NULL    |       |

| queue_thereare              | varchar(128) | YES  |     | NULL    |       |

| queue_callswaiting          | varchar(128) | YES  |     | NULL    |       |

| queue_holdtime              | varchar(128) | YES  |     | NULL    |       |

| queue_minutes               | varchar(128) | YES  |     | NULL    |       |

| queue_seconds               | varchar(128) | YES  |     | NULL    |       |

| queue_lessthan              | varchar(128) | YES  |     | NULL    |       |

| queue_thankyou              | varchar(128) | YES  |     | NULL    |       |

| queue_reporthold            | varchar(128) | YES  |     | NULL    |       |

| announce_frequency          | int(11)      | YES  |     | NULL    |       |

| announce_round_seconds      | int(11)      | YES  |     | NULL    |       |

| announce_holdtime           | varchar(128) | YES  |     | NULL    |       |

| retry                       | int(11)      | YES  |     | NULL    |       |

| wrapuptime                  | int(11)      | YES  |     | NULL    |       |

| maxlen                      | int(11)      | YES  |     | NULL    |       |

| servicelevel                | int(11)      | YES  |     | NULL    |       |

| strategy                    | varchar(128) | YES  |     | NULL    |       |

| joinempty                   | varchar(128) | YES  |     | NULL    |       |

| leavewhenempty              | varchar(128) | YES  |     | NULL    |       |

| eventmemberstatus           | tinyint(1)   | YES  |     | NULL    |       |

| eventwhencalled             | tinyint(1)   | YES  |     | NULL    |       |

| reportholdtime              | tinyint(1)   | YES  |     | NULL    |       |

| memberdelay                 | int(11)      | YES  |     | NULL    |       |

| weight                      | int(11)      | YES  |     | NULL    |       |

| timeoutrestart              | tinyint(1)   | YES  |     | NULL    |       |

| periodic_announce           | varchar(50)  | YES  |     | NULL    |       |

| periodic_announce_frequency | int(11)      | YES  |     | NULL    |       |

| ringinuse                   | tinyint(1)   | YES  |     | NULL    |       |

| setinterfacevar             | tinyint(1)   | YES  |     | NULL    |       |

| autofill                    | tinyint(1)   | YES  |     | NULL    |       |

+-----------------------------+--------------+------+-----+---------+-------+

 

When autofill is undefined or is 0, incoming calls are delivered in FIFO manner.  The log file : /var/log/asterisk/queue_log provides detailed information about the incoming call and ringing progress.  Look for event with 'RINGNOANSWER' to spot whether your incoming call is serialized or delivered to all available agents.

 

Tuesday, April 13, 2010

Detect incoming fax on sip channels

 

To detect incoming fax on sip channel, we need to install nvfaxdetect (vs zap channel can support fax detection natively)

 

cd /usr/src

wget http://nerdvittles.com/aah15/app_nv_faxdetect.c

 

Howerver, you might need to make some modifications in the source code to order to compile the nvfaxdetect.

 

  • Search for and comment out all lines with: "LOCAL_USER_ADD(u);".
  • Search for and comment out all lines with: "LOCAL_USER_REMOVE(u);".
  • Search for and comment out all lines with: "STANDARD_HANGUP_LOCALUSERS;".
  • Add the following line to the very end of the file (change the second parameter/description to something that is applicable): "AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Fax Detection Application");".
  • #include <stdio.h>

After source code modification, we can proceed to Make.

  • Type "cd /usr/src/asterisk" (or respective Asterisk directory)
  • Type "make".
  • Type "make install".
  • Restart Asterisk by asterisk -rx "restart now"".
  • Verify by "show application like NVFaxDetect"  in the Asterisk CLI
  • If NVFaxDetect is installed, you should see below messages:
  •   -= Info about application 'NVFaxDetect' =-
  • [Synopsis]
    Detects fax sounds on all channel types (IAX and SIP too)
  • [Description]
      NVFaxDetect([waitdur[|options[|sildur[|mindur[|maxdur]]]]]):
    This application listens for fax tones (on IAX and SIP channels too)
    for waitdur seconds of time. In addition, it can be interrupted by digits,
    or non-silence. Audio is only monitored in the receive direction. If
    digits interrupt, they must be the start of a valid extension unless the
    option is included to ignore. If fax is detected, it will jump to the
    'fax' extension. If a period of non-silence greater than 'mindur' ms,
    yet less than 'maxdur' ms is followed by silence at least 'sildur' ms
    then the app is aborted and processing jumps to the 'talk' extension.
    If all undetected, control will continue at the next priority.
          waitdur:  Maximum number of seconds to wait (default=4)
          options:
            'n':  Attempt on-hook if unanswered (default=no)
            'x':  DTMF digits terminate without extension (default=no)
            'd':  Ignore DTMF digit detection (default=no)
            'f':  Ignore fax detection (default=no)
            't':  Ignore talk detection (default=no)
          sildur:  Silence ms after mindur/maxdur before aborting (default=1000)
          mindur:  Minimum non-silence ms needed (default=100)
          maxdur:  Maximum non-silence ms allowed (default=0/forever)
    Returns -1 on hangup, and 0 on successful completion with no exit conditions.
We can use NVFaxDetect in dial plan similar to below.
exten => 120,n,NVFaxDetect(4|dt)
exten => 120,n,MoOp(CALLERID)
exten => 120,n,Macro(take-msg,${CALLERID(num)}, ${EXTEN}) // send to voicemail if voice
; if fax, send to a real fax maachine
exten => fax,1,NoOp
exten => fax,n,StopPlaytones
exten => fax,n,Dial(IAX2/zonefax29)

Conference recordings for inbound and outbound participant in asterisk web-mm

It is the default behaviour of web-mm to start conference recording when moderator joins a conference room.  If your conference consists nothing but outbound participants, you have to modify the two files below to enable recording.

 

1.    /var/www/web-mm/app_cbmysql.c

static int cb_exec(struct ast_channel *chan, void *data)
{

........

        if (info){
                char *tmp = strsep(&info, "|");
                ast_copy_string(confno, tmp, sizeof(confno));
        }

        if (!ast_strlen_zero(confno)){
                strcpy(dtmfinput.inroom, confno);
                skippass=1; // if confno is in parameter, we assume it is from outbound conference
        } else {
        strcpy(dtmfinput.inroom, "");
        }
.......

                if(res==1 && skippass ==0){ //  if skippass is 1, then do not prompt password
                        res = getPass(chan, dtmfinput, &dtmfmatch);
                        ast_log(LOG_NOTICE, "getPass: %i\n", res);
                } else {

 

2.    /var/www/web-mm/batchcall.php

if($_SESSION["firstcall"]=="yes"){

        $as = new AGI_AsteriskManager();
        $res = $as->connect();
        if (!$res){ echo 'Error connection to the manager!'; exit();}

//      $application = MeetMe;

//      bridge the outbound party with application cbmysql, instead of meetme
        $application = cbmysql;
        $rnc = $data;

        $data = $data . "|d1qr"

        $priority = 1;
        $context = OUT_CONTEXT;

 

The result is:

1.    you call out from web-mm to a participant

2.    once the participant answers, he is bridged with the application cbmysql

3.    attributed to the use of cbmysql instead of meetme, recording option and voice file path are consistent  in both inbound and outbound conference.

 

Note that if conference is recording-enabled:

q       Recording starts when the first outbound party is connected and stops when all parties leave the conference (in the meantime, inbound by host would not trigger another recoding)

q       A new recording is created if outbound party is connected again

 

Monday, April 12, 2010

Merge fields in hylafax sendfax

 

We occasionally need to merge variables (e.g., customer name, customer number, etc.) in fax contents.  There is no easy way to merge information within the page data.

 

However, the hylafax sendfax command supports parameters for merging in cover page.   These parameters are denoted by special variables in the postscript file used to generate cover page.  

%% to   destination person

%% from   sending person

%% to-company       destination company

%% from-company  sender's company

%% to-location  destination geographic location

%% from-location sender geographic location

%% to-voice-number person's voice phone number

%% from-voice-number sender's voice phone number

%% to-fax-number destination fax phone number

%% from-fax-number sender's fax phone number

%% comments  unbroken comment string

%% commentsX  X'th line of comments

%% regarding  Re: subject

%% page-count  # pages other than cover page

%% pageWidth  page width in millimeters

%% todays-date  current date and time

%% pageLength  page length in millimeters

 

Following the steps below to create a custom cover page.

Print the required cover page to tiff e.g infile.tif

  • Make sure tiff is output as black and white (can use Zan printer driver to output to tiff)
  • Dpi 200x200
  • Paper size is A4
  • tiff2ps –e infile.tif > job_cover.ps

Based on the add-on.ps below, create a specific add-on.ps for this cover page

·        the add-on.ps is an eps to specify location and font to print variables passed from faxcover()

·        the center of coordinates is the left bottom corner of the fax cover

·        one inch equal to 72 points

·        for example, the statement "72 72 moveto to-company show" instructs postscript to print the variable to-company at 1 inch above and right relative to the bottom left cornet

 

Append /tmp/make_faxcover/add-on.ps to job_cover.ps

  • just before the 'showpage' operator
  • if no 'showpage' operator exists, add it to the end of job_cover.ps as below.

%%

showpage

%%Trailer

%%Pages: 1

%%EOF

  • refer to the system default faxcover.ps for available fonts

 

In sendfax, use –C full-path-of-job_cover.ps to specify the cover template

 

Sample add-on.ps

%% whfc.template---------------------------START HERE

%%

%% Place this at the end of your postscript file, immediately above the

%% showpage operator.

%%

%% The initmatrix operator resets the way the text is placed.  Without it

%% You may find your text upside down, sideways, or worse.

%%

%% The scale operator resets your scale to points (72 per inch)

%%

%% The garbage in front of the findfont operator is postscript's way of

%% describing a microsoft font.  You can use any of the fonts on your

%% document, but it will be necessary to get the code first.  Search for

%% the name of the font (exp. Arial).  The description code will be

%% close by.

%%

%% The scalefont setfont lines set the point size for the font and tells

%% postscript to use that font for the following lines

%%

%% The moveto operator moves from the bottom left hand corner x number

%% of points to the right (the first number) and y number of points up

%% (the second number)

%%

%% The fields placed are described below and are printed with the show

%% command.  This example uses 4 comment lines; your coverpage may have

%% more.  I have not used all of the fields, additionally, I believe

%% that the pageLength and pageWidth operators are set by the original

%% postscript generator, so I didn't use them.

%%

%% Make sure to download all fonts when you print your coverpage to disk!

%%

%% I didn't have any luck figuring out the CommentsX crapola, (Bug 87??!!)

%% So I just used four lines in my comment section.  If you're using WHFC,

%% this would correspond to the first four lines of the comments box

%% If you want more, just make them.

%%

%%

%%

%% to   destination person

%% from   sending person

%% to-company       destination company

%% from-company  sender's company

%% to-location  destination geographic location

%% from-location sender geographic location

%% to-voice-number person's voice phone number

%% from-voice-number sender's voice phone number

%% to-fax-number destination fax phone number

%% from-fax-number sender's fax phone number

%% comments  unbroken comment string

%% commentsX  X'th line of comments

%% regarding  Re: subject

%% page-count  # pages other than cover page

%% pageWidth  page width in millimeters

%% todays-date  current date and time

%% pageLength  page length in millimeters

%%

%%

%% initmatrix as per instructions above

%%

initmatrix

%%

%% initialize the scaling

%%

1 1 scale

%%

%% The following is an instruction to load a particular font

%%

%%/Helvetica-Bold findfont

%%

%%

%%

%% Now let's set the size

%%

%%10 scalefont setfont

%%

%%

%% Now move to where we're going to place it

%%

%%130 501 moveto

%%

%%

%% Now print the "to" field on the cover page

%%

%%to show

%%

%%

%%

%% Now the to-company field

%%

/Helvetica-Bold findfont

10 scalefont setfont

72 72 moveto to-company show

%%

/Times-Bold-SHOWISO findfont

12 scalefont setfont

144 144 moveto to-company show

%%

/Courier findfont

14 scalefont setfont

216 216 moveto to-company show

%%

/Courier findfont

16 scalefont setfont

288 288 moveto to-company show

%% at 4.5 inch

/unifont findfont

10 scalefont setfont

323 323 moveto to-company show

%%

%% The from line

%%

%%130 474 moveto

%%from show

%%

%%

%% Now change the font (Hey, why not?)

%% Of course if you can't find the "MSTT_Whatever" string in your postscript

%% Then naturally you can't use that font.  Did I need to say that?

%%

%%/Times-Bold-SHOWISO findfont

%%

%%

%% Scale the font again

%%

%%10 scalefont setfont

%%

%% Ok, You can figure out the rest

%%

%%

%%380 633 moveto

%%todays-date show

%%520 589 moveto

%%page-count show

%%/Times-Bold-SHOWISO findfont

%%10 scalefont setfont

%%220 98 moveto

%%regarding show

%%/Times-Bold-SHOWISO findfont

%%10 scalefont setfont

%%130 420 moveto

%%comments1 show

%%130 393 moveto

%%comments2 show

%%130 366 moveto

%%comments3 show

%%130 339 moveto

%%comments4 show

%% whfc.template---------------------------END HERE

%%/Helvetica-Bold findfont

%%/Helvetica-Bold-SHOWISO exch definefont pop

%%/Helvetica findfont

%%/Helvetica-SHOWISO exch definefont pop

%%/Courier findfont

%%/Courier-SHOWISO exch definefont pop

%%/Times-Bold findfont

%%/Times-Bold-SHOWISO exch definefont pop

%%/Helvetica-SHOWISO findfont 14 scalefont setfont

%% /Helvetica-Bold-SHOWISO findfont 18 scalefont setfont

%%/Helvetica-Bold-SHOWISO findfont 24 scalefont setfont

%%/Times-Bold-SHOWISO findfont 10 scalefont setfont

%%/Helvetica-Bold-SHOWISO findfont 24 scalefont setfont

%%/Helvetica-Bold-SHOWISO findfont 24 scalefont setfont

%%/Helvetica-Bold-SHOWISO findfont 24 scalefont setfont

%%

%%

%%

 

 

4KN82D7KF429

4KN82D7KF429
 

Text-to-speech in asterisk

 

There are many TTS engines for asterisk.  One of them is 'swift' .  We can install swift as below in FC.

 

Login as root

Cd /usr/source

wget http://downloads.cepstral.com/cepstral/i386-linux/Cepstral_Diane-8kHz_i386-linux_5.1.0.tar.gz

 

; we need to install the voice first

gunzip Cepstral_Diane-8kHz_i386-linux_5.1.0.tar.gz

tar xvf Cepstral_Diane-8kHz_i386-linux_5.1.0.tar

cd Cepstral_Diane-8kHz_i386-linux_5.1.0

./install.sh  ; should see the below message

***************************************************************************

****************** Installation Completed Successfully! *******************

***************************************************************************

 

tar xvf app_swift-1.4.2.tar

cd app_swift-1.4.2

make

make install

 

Then we can create a gsm file recognized by asterisk.

swift "Thank you for calling XXXX Technologies Limited" -o welcome.wav

; converting to gsm and put into the asterisk sound location

sox welcome.wav -g welcome.gsm

cp welcome.gsm /var/lib/asterisk/sounds/

 

Note that the free-version of swift automatically puts a license message in each generated file.