Monday, January 19, 2015

Integrating Asterisk with Freeswitch

Read all about connecting Freeswitch with Asterisk http://wiki.freeswitch.org/wiki/Connecting_Freeswitch_And_Asterisk

in sip.conf add under queue agents SIP/freeswitch_1

Queues.conf


[customer-service]
        context                         = default
        joinempty                       = no
        member                          = agent/92028
        member                          = sip/cs2
        member                          = sip/cs3
        musiconhold                     = default
        strategy                        = roundrobin
        timeout                         = 20

[tps2-customer-service]
        context                         = default
        joinempty                       = no
        member                          = agent/92028
        member                          = sip/cs11
        member                          = sip/cs12
        member                          = sip/cs13
        ;member                         = sip/cs14
        member                          = sip/freeswitch_1
        musiconhold                     = default

Sip.conf

[freeswitch_1]
type=peer
host=10.0.112.21
port=5060
disallow=all
allow=ulaw
trustrpid=yes
sendrpid=yes
context=customer-service

In conf/dialplan/default.xml on Freeswitch

<include>
  <context name="public">
        <extension name="1000">
                <condition field="destination_number" expression="^\d{12}$">
                        <action application="answer"/>
                        <action application="javascript" data="apiOnMedia.js"/>
                </condition>
        </extension>

apiOnMedia.js

use("TeleTone");
   // If not answered answer the call
        session.answer();
        session.sayPhrase("speak", "welcome to the T P S customer service application", "en");
        if(session.ready()) {
                var randomNumber=0;
/*              do {
                        randomNumber=Math.floor(Math.random()*10);
                }
                while (randomNumber < 40);
*/
                //console_log("notice", "randomNumber=" + randomNumber);
                tea_break(5 * 1000);
                //console_log("notice", "sending wave");
                //session.streamFile("/tmp/p3p.wav");
                var pound3pound ="v=-7;%(200,0,941.0,1477.0);%(200,0,697.0, 1477.0);%(200,0,941.0,1477.0)";
                var pound7pound ="v=-7;%(200,0,941.0,1477.0);%(200,0,852.0, 1209.0);%(200,0,941.0,1477.0)";
                var pound8pound ="v=-7;%(200,0,941.0,1477.0);%(200,0,852.0, 1336.0);%(200,0,941.0,1477.0)";

                //var pound ="v=-7;%(200,0,941.0,1477.0);%(200,0,941.0,1477.0)";
                var tts = new TeleTone(session);
                tts.generate(pound7pound);
                tea_break(5 * 1000);
        }
   console_log("notice", "called api on media");
   function tea_break(msec) {
                console_log("notice", "in tea break " + msec);
                var date = new Date();
                var curDate = null;
                do {
                        curDate = new Date();
                }
                while(curDate - date < msec);

package net.xxx.dtmf;

/*
 * Copyright 2010 david varnes.
 *
 * Licensed under the Apache License, version 2.0 (the "License"); 
 * you may not use this file except in compliance with the License. 
 * You may obtain a copy of the License at:
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, 
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map.Entry;
import java.util.UUID;

import org.apache.log4j.Logger;
import org.freeswitch.esl.client.inbound.Client;
import org.freeswitch.esl.client.inbound.InboundConnectionFailure;
import org.freeswitch.esl.client.transport.CommandResponse;
import org.freeswitch.esl.client.transport.SendMsg;
import org.freeswitch.esl.client.transport.message.EslHeaders.Name;
import org.freeswitch.esl.client.transport.message.EslMessage;
public class AsteriskBridge
{
 public static Logger log = Logger.getLogger(AsteriskBridge.class);
    private String host = "127.0.0.1";
    private int port = 8021;
    private String password = "ClueCon"; 
    private String digits="";   
    private Long id;
    public AsteriskBridge(Long id) {
     this.id = id;
    }
    public void do_connect() throws InterruptedException, IOException
    {
     EslMessage resp = null;
     Client client = new Client();
        
        
        log.info( "Client connecting .." );
        try
        {
            client.connect( host, port, password, 20 );
        }
        catch ( InboundConnectionFailure e )
        {
            log.info( "Connect failed" );
            return;
        }
        log.info( "Client connected .." );
        BufferedReader bis=null;
        try {
         bis = new BufferedReader(new FileReader("/tmp/agentsQa.csv"));
        } catch (Exception e) {};
        String line="";
        int agentCounter=0;
        List uuidList=new ArrayList();
        final int sleepTime=3000;
        while ((line=bis.readLine()) != null) {
         if (line==null || line.trim().equals(""))
          continue;
         String [] line_arr = line.split(",");
         if (line_arr[0] == null || line_arr[1] == null)
          continue;
         agentCounter++;
         String fulfillmentAgentId =  line_arr[0];
         String fulfillmentAgentPassword = line_arr[1];
         if (agentCounter > 40) break;
         new AsteriskThread(agentCounter, fulfillmentAgentId, fulfillmentAgentPassword, client).start();
        }
        
        if (1==1) {
         while(1==1) {
  /*        for(int i=0; i < uuidList.size(); i++) {
           resp=client.sendSyncApiCommand("uuid_broadcast ", uuidList.get(i) + " c:/FreeSWITCH/freeswitch/libs/libcodec2/wav/hts2a.wav");
           log.info("playing agent uuid=" + uuidList.get(i));
           Thread.sleep(1000);
         }
        */
          log.info("waiting agent");
           Thread.sleep(1000);
         }
        }
        Thread.sleep(600000);
        for(int i=0; i < uuidList.size(); i++) {
         hangup(client, uuidList.get(i));
         log.info("hanging up agent uuid=" + uuidList.get(i));
        }
        client.close();
    }

    
   private void hangup(Client client, String uuid) {
    SendMsg hangupMsg = new SendMsg(uuid);
       hangupMsg.addCallCommand( "execute" );
       hangupMsg.addExecuteAppName( "hangup" );
       
       CommandResponse response = client.sendMessage(hangupMsg);
       
   }

   public static void main(String [] args) throws IOException {
      AsteriskBridge client = new AsteriskBridge(0L);
       
       log.info( "Client connecting .." );
       try
       {
           client.do_connect();
       }
       catch ( InterruptedException e )
       {
           log.error( "Connect failed", e );
           return;
       }
       log.info( "Client connected .." );
   }
}

package net.xxx.dtmf;

import java.util.UUID;
import java.util.Map.Entry;

import org.apache.log4j.Logger;
import org.freeswitch.esl.client.inbound.Client;
import org.freeswitch.esl.client.transport.message.EslMessage;
import org.freeswitch.esl.client.transport.message.EslHeaders.Name;

public class AsteriskThread extends Thread{
 public static Logger log = Logger.getLogger(AsteriskThread.class);
 int agentCounter;
 String fulfillmentAgentId;
 String fulfillmentAgentPassword;
 EslMessage resp = null;
 Client client;
 public AsteriskThread(int agentCounter, String fulfillmentAgentId, String fulfillmentAgentPassword, Client client ) {
  // TODO Auto-generated constructor stub
  this.client = client;
  this.agentCounter = agentCounter;
  this.fulfillmentAgentId = fulfillmentAgentId;
  this.fulfillmentAgentPassword = fulfillmentAgentPassword;
 }

 public void run() {
   final int sleepTime=3000;
  log.info(agentCounter + " Logging in agent id=" + fulfillmentAgentId + " password=" + fulfillmentAgentPassword);
     String uuid=UUID.randomUUID().toString();
     //uuidList.add(uuid);
     //EslMessage resp=client.sendSyncApiCommand("originate ", "{origination_uuid=" + uuid + "}sofia/public/2000  &park()" );
     //EslMessage resp=client.sendSyncApiCommand("originate ", "{origination_uuid=" + uuid + "}sofia/external/2001@10.0.112.61  &park()" );
     resp=client.sendSyncApiCommand("originate ", "{origination_uuid=" + uuid + "}sofia/external/8183518496@blvdqa-ap30.xxx.net &park()" );
     //EslMessage resp=client.sendSyncApiCommand("originate ", "{origination_uuid=" + uuid + "}sofia/gateway/fs-lab-1/OUTBOUND+18557516246  &park()" );
     log.info( "Response to 'park1': [{}]" + resp );
        for ( Entry header : resp.getHeaders().entrySet() )
        {
            log.info( " * header [{}]" + header );
        }
        for ( String bodyLine : resp.getBodyLines() )
        {
            log.info( " * body [{}]" + bodyLine );
        }
        log.info("sleeping for 10....uuid=" + uuid);
       try {
        Thread.sleep( sleepTime );
       }catch (Exception e) {}
       resp=client.sendSyncApiCommand("uuid_send_dtmf ",  uuid + " 1");
       log.info( "Response to play dtmf: [{}]" + resp );
       for ( Entry header : resp.getHeaders().entrySet() )
       {
           log.info( " * header [{}]" + header );
       }
       for ( String bodyLine : resp.getBodyLines() )
       {
           log.info( " * body [{}]" + bodyLine );
       }
       try {
       Thread.sleep( sleepTime );
       } catch (Exception e) {}
       resp=client.sendSyncApiCommand("uuid_send_dtmf ",  uuid + " " + fulfillmentAgentId + "#");
        log.info( "Response to enter id: [{}]" + resp );
        for ( Entry header : resp.getHeaders().entrySet() )
        {
            log.info( " * header [{}]" + header );
        }
        for ( String bodyLine : resp.getBodyLines() )
        {
            log.info( " * body [{}]" + bodyLine );
        }
        try {
            Thread.sleep( sleepTime );
        }catch (Exception e) {}//give time to connect to the queue
        //resp=client.sendSyncApiCommand("uuid_broadcast ", uuid + " c:/FreeSWITCH/freeswitch/libs/libcodec2/wav/hts2a.wav");
        resp=client.sendSyncApiCommand("uuid_send_dtmf ",  uuid + " " + fulfillmentAgentPassword + "#");
        
        log.info( "Response tenter o password: [{}]" + resp );
        for ( Entry header : resp.getHeaders().entrySet() )
        {
            log.info( " * header [{}]" + header );
        }
        for ( String bodyLine : resp.getBodyLines() )
        {
            log.info( " * body [{}]" + bodyLine );
        }
        if (1==1)
        while(1==1) {
            resp=client.sendSyncApiCommand("uuid_broadcast ", uuid + " c:/FreeSWITCH/freeswitch/libs/libcodec2/wav/hts2a.wav");
            //log.info("playing agent uuid=" + uuid);
           try {
                Thread.sleep( 5000 );
                }catch (Exception e) {}
         }
 }
}

sipp test script

<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE scenario SYSTEM "sipp.dtd">

<!-- This program is free software; you can redistribute it and/or      -->
<!-- modify it under the terms of the GNU General Public License as     -->
<!-- published by the Free Software Foundation; either version 2 of the -->
<!-- License, or (at your option) any later version.                    -->
<!--                                                                    -->
<!-- This program is distributed in the hope that it will be useful,    -->
<!-- but WITHOUT ANY WARRANTY; without even the implied warranty of     -->
<!-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the      -->
<!-- GNU General Public License for more details.                       -->
<!--                                                                    -->
<!-- You should have received a copy of the GNU General Public License  -->
<!-- along with this program; if not, write to the                      -->
<!-- Free Software Foundation, Inc.,                                    -->
<!-- 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA             -->
<!--                                                                    -->
<!--                 Sipp default 'uac' scenario.                       -->
<!--                                                                    -->

<scenario name="Basic Sipstone UAC">
  <!-- In client mode (sipp placing calls), the Call-ID MUST be         -->
  <!-- generated by sipp. To do so, use [call_id] keyword.                -->
  <send retrans="500">
    <![CDATA[

      INVITE sip:[field2]@[remote_ip]:[remote_port] SIP/2.0
      Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
      From: sipp <sip:[field3]@[local_ip]:[local_port]>;tag=[pid]SIPpTag00[call_number]
      To: <sip:[field3]@[remote_ip]:[remote_port]>
      CALL-ID: [call_id]
      CSeq: 1 INVITE
      Contact: sip:[field3]@[local_ip]:[local_port]
      Max-Forwards: 70
      Subject: Performance Test
      Content-Type: application/sdp
      Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY, INFO
      User-Agent: Asterisk PBX
      Content-Length: 258
      Supported: replaces
      Date: Wed, 06 Dec 2009 14:12:45 GMT

     v=0
      o=root 1821 1821 IN IP4 [remote_ip]
      s=session
      c=IN IP4 [remote_ip]
      t=0 0
      m=audio [media_port] RTP/AVP 96 0
      a=rtpmap:18 G711a/8000
      a=silenceSupp:on - - - -
     a=ptime:20
     a=sendrecv
     a=rtpmap:0 PCMU/8000
     a=rtpmap:96 telephone-event/8000
     a=fmtp:96 0-16
]]>
  </send>

  <recv response="100"
        optional="true">
  </recv>
<recv response="180" optional="true">
  </recv>

  <recv response="183" optional="true">
  </recv>
  <!-- By adding rrs="true" (Record Route Sets), the route sets         -->
  <!-- are saved and used for following messages sent. Useful to test   -->
  <!-- against stateful SIP proxies/B2BUAs.                             -->
  <recv response="200" rtd="true">
  </recv>
  <!-- Packet lost can be simulated in any send/recv message by         -->
  <!-- by adding the 'lost = "10"'. Value can be [1-100] percent.       -->
  <send>
    <![CDATA[

      ACK sip:[field2]@[remote_ip]:[remote_port] SIP/2.0
      Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
      From: sipp <sip:[field3]@[local_ip]:[local_port]>;tag=[pid]SIPpTag00[call_number]
      To: <sip:[field2]@[remote_ip]:[remote_port]>[peer_tag_param]
      Call-ID: [call_id]
      CSeq: 1 ACK
      Contact: sip:[field1]@[local_ip]:[local_port]
      Max-Forwards: 70
      Subject: Performance Test
      Content-Length: 0
    ]]>
  </send>
<pause milliseconds="10000"/>
<nop>
<action>
<exec play_dtmf="[field0]"/>
</action>
</nop>
<pause milliseconds="10000"/>
<nop>
<action>
<exec play_dtmf="[field1]"/>
</action>
</nop>
<pause milliseconds="10000"/>
<nop>
<action>
<exec play_dtmf="1"/>
</action>
</nop>
<pause milliseconds="20000"/>
<nop>
<action>
<exec play_pcap_audio="/tmp/mobydick003.pcap"/>
</action>
</nop>
<pause milliseconds="600000"/>
  <send retrans="500">
    <![CDATA[

      BYE sip:[field2]@[remote_ip]:[remote_port] SIP/2.0
      Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
      From: sipp <sip:[field3]@[local_ip]:[local_port]>;tag=[pid]SIPpTag00[call_number]
      To: <sip:[field0]@[remote_ip]:[remote_port]>[peer_tag_param]
      Call-ID: [call_id]
      CSeq: 2 BYE
      Contact: sip:[field3]@[local_ip]:[local_port]
Max-Forwards: 70
      Subject: Performance Test
      Content-Length: 0
    ]]>
  </send>

  <recv response="200" crlf="true">
  </recv>
  <recv response="503" crlf="true">
  </recv>
  <recv response="480" crlf="true">
  </recv>

  <!-- definition of the response time repartition table (unit is ms)   -->
  <ResponseTimeRepartition value="10, 20, 30, 40, 50, 100, 150, 200"/>

  <!-- definition of the call length repartition table (unit is ms)     -->
  <CallLengthRepartition value="10, 50, 100, 500, 1000, 5000, 10000"/>

</scenario>

SIPp invocation

/usr/local/bin/sipp 10.0.144.3 -mi 10.0.144.2 -sf dev_ftc.xml -inf /tmp/ftc_appr
oved.csv -m 3 -r 1 -rp 5000 -aa -t un -trace_err -trace_msg -trace_logs

No comments:

Post a Comment