Category Archives: Work

Genesys Management 2.0

Hi – I’m back! Unfortunately, due to client confidentiality I’ve not been able to blog about Genesys work projects for a few years. Let’s change that ..

This post is about something I have been looking at for several years in the form of a shelved project which gets events from Genesys components via the PSDK and fires them into Esper for some complex event processing (CEP). But why get complex with PSDK code – why not just parse unstructured Genesys log files into structured data – let’s say in a JSON format?

Voxeo / Aspect went down this log processing route using Splunk but in the wider context using Splunk for Genesys log processing was not cost effective. However, the momentum of ELK (now the Elastic Stack) in the last 12 months has changed this significantly and I think it’s time for Genesys Management 2.0!

If you look at the current Genesys Management layer it’s not exactly fit for purpose. Yes, you can alarm and send SNMP traps but that just gets you into the Sh*t in Sh*t out (SISO) problem whereby too many alarms are sent meaning they just get ignored because “that is normal”. Worse still operational incidents occur for which there are no alarms – like SIP INVITEs not being received over a SIP trunk even though it is not OOS.

On top of Management 0.1 which has not changed for years, Genesys have added the Log File Management Tool (LFMT) and the Log Masking Tool which is just a couple of Java lines of code around Regex! Neither are aimed at operational excellence – just making life easier for Genesys Support.

Hence the reason for the post – using an ELK stack for Genesys Management 2.0. Surely a few Logstash Grok filters to parse out the following conf server log lines into events with metadata like the log message Id would without stealing the “Spotlight” would be quite valuable:

16:29:54.229 Std 24200 Object: [CfgFolder], name [Demands], DBID: [268] is created by client, type [SCE], name: [default], user: [default]
16:30:33.262 Std 24202 Object: [CfgFolder], name [Demands], DBID: [268] is deleted by client, type [SCE], name: [default], user: [default]
16:31:20.017 Std 24201 Object: [CfgRouteDN], name [RES Prepayment – Gas], DBID: [283] is changed by client, type [SCE], name: [default], user: [default]

grok {
match => { “message” => “%{TIME:timestamp} %{WORD:loglevel} %{WORD:logMsgId} %{GREEDYDATA:message}” }
break_on_match => false
}

Time to get Grok-ing.

Share

Genesys INAP Integration

Firstly I hope you had a great Xmas 2014 and a very Happy New Year to you all.

In this blog post I want to share with you some of my experiences of INAP integration with Genesys. INAP stands for Intelligent Network Application Part. INAP is the signaling protocol used in Intelligent Networking and is part of the Signaling System 7 (SS7) protocol suite, typically layered on top of the Transaction Capabilities Application Part (TCAP).

An extended form of INAP is CAMEL (Customised Applications for Mobile Enhanced Logic). The CAMEL Application Part (CAP) provides mechanisms to support operator services beyond the standard GSM services for subscribers roaming within or outside the Home PLMN (HPLMN). CAP extends the IN framework to GSM/3G networks for implementing IN based services within GSM/3G networks.

CAMEL is used between the gsmSSF and the gsmSCF (for example Redknee / NSN IN@Vantage). All CAMEL service requests are directed to a gsmSCF. The gsmSCF is a functional entity where the CAMEL services reside. The node in which the gsmSCF resides is called the Service Control Point (SCP).

Image

SEP = Signaling End Point (for example an SSP), SG = Signaling Gateway, IPSP = IP Signaling Point

OK – without boring you too much further let’s assume that we have a requirement to integrate Genesys into an IN network.

In this application INAP Assist Request Instructions (ARI), Prompt and Collect User Information (PCUI) and PCUI result operations will be used to pass IN information to Genesys and to control the call while still under IN control and on a temporary connection (for example to invoke a subsequent Disconnect Forward Connection (DFC) from the downstream Genesys environment where a SIP BYE is not permitted). The initial INVITE to Genesys SIP Server (SIPS) (or in this case my custom FreeSWITCH SG upstream of Genesys SIPS) will contain the SCP correlation Id used on the initial Assist Request Instructions (ARI) IN operation.

So how can this be done?

Well the easy (!) way is to build a custom solution based on the Dialogic® Distributed Signaling Interface (DSI) Protocol Stacks (https://www.dialogic.com/products/signaling-and-ss7-components/download/dsi-interface-protocol-stacks.aspx).

DSI consists of a range of hardware and software components for realisation of SS7, SIGTRAN and Diameter signaling nodes and applications. The DSI Protocol Stacks are software implementations of standards-based signaling protocol layers. In addition a suite of API functions is also supplied to provide a convenient interface for the user application as well as coding and decoding of INAP operations.

The DSI M3UA module is a software implementation of the IETF SIGTRAN SS7 MTP3 User Adaptation Layer (M3UA). The M3UA module uses the services provided by the Stream Control Transmission Protocol (SCTP) to exchange signaling messages with M3UA Signaling Gateway Processes (SGP), M3UA Application Server Processes (ASP) or M3UA IP Signaling Processes (IPSP). The M3UA module is intended to be used in conjunction with other DSI Signaling Protocols namely SCTP, ISUP and SCCP. When used as part of an ASP or IPSP, M3UA offers a primitive interface identical to that of MTP3. This allows M3UA to interface directly to protocols that interface with MTP3.

I chose to implement the solution as a separate SIP Signalling Gateway (SG) based on FreeSWITCH with custom dialplan (DP) applications written in Microsoft C# and called via mod_managed (https://wiki.freeswitch.org/wiki/Mod_managed) but there is no reason why this custom code could not be called directly from Genesys routing strategies and URS e.g. invoked as a Web Service.

The diagram below shows a high level overview of the solution. Essentially in this solution FreeSWITCH manages all the IN calls (INAP operations) via custom C# using DSI modules and INAP APIs and passes the required information to Genesys SIP Server (SIPS) in custom SIP headers:

Image

OK – on to the technical implementation.

DSI API is C based so a C++ wrapper (DLL) is used to abstract the complexity. This handles the passing of messages between managed (C#) code and unmanaged (C++) code. For example the MSG message is a C data structure containing a fixed format header field and a buffer for variable length parameter data. The DSI INAP API functions are used to encode and decode INAP messages based on protocol required (such as CAMEL v3).

DSI C++ Wrapper

Image

DSI C# Class

Image

Image

DSI Configuration

There are two configuration files – system.txt and config.txt. The selection of which protocol modules to run on the host is made by editing the system.txt configuration file. A software-only architecture may be configured using the appropriate Dialogic DSI SIGTRAN modules in place of MTP2 and/or MTP3. These modules provide the same interface to upper protocol modules and use the services of the Stream Control Transmission Protocol (SCTP) to transport SS7 signalling reliably over IP. There are two choices of SCTP module – SCTP (used with SCTPD) and SCTPN which utilises the ‘native’ SCTP stack provided by the host Operating System kernel.

Note: Windows does not provide a native SCTP stack!

For trial purposes, a mode of operation is supported that allows DSI Protocol Stacks to run for up to one hour without requiring a run-time license. Trial Mode is enabled by starting the protocol module with the -t option on the command line. For example, in order to start the M3UA module in trial mode using a FORK_PROCESS command in system.txt on a Windows system:

FORK_PROCESS ./HSTBIN/m3ua.exe -t

system.txt:

Image

config.txt:

Image

Image

Image

Image

Image

Enjoy!

 

Share

Genesys Introduces New Cloud-Based Expert Services to Further Enhance Customer Experience Investment

29th May 2014 – Genesys at G-Force New Orleans introduced Genesys Guru, a new portfolio of cloud-based expert services that help customers realize the full power of their investments in the Genesys Customer Experience Platform, with initial offerings focused on Workforce Optimization (WFO). Genesys Guru offers customers expert services to identify, analyze and optimize business processes and workforce issues that may jeopardize their customer experience, impact their ability to meet regulatory requirements, or delay their time to value with their technology investments.

http://www.callcentreclinic.com/news/technology/genesys-introduces-new-cloud-based-expert-services-to-further-enhance-customer-experience-investment-49692.htm

http://www.contactcentrenews.co.uk/

Share

Genesys Environment Manager (GEM)

Another proof of concept (PoC) inspired by my friend Ravi which is destined to be a Boondoggle!

I like to think of this as “Siri for Genesys”! In fact GEM also has an email interface which can be used to collect and ZIP log files to a centralised log location but that is not as much fun as playing with SMS messages!

Anyway video below. Apologies but running CamStudio and Reflector at the same time damn nearly killed my laptop which means what is shown in Reflector is not the same as what was on my iPhone due to lag. Also this caused timing problems talking to the GSM modem which caused some SMS replies not to get sent – I’ll fix that problem at some point.

 

Share

SIP Interceptor

In a SIP environment interoperability issues are unfortunately an expected reality. Sometimes vendor X will not interoperate fully with vendor Y and neither are willing or able to change their product. Equally some vendors may no longer be providing software updates.

So how can this be fixed most of the time with a quick, cheap and importantly still performant solution?

Enter SIP interceptor!

SIP Interceptor is a Linux userspace application. The purpose of SIP interceptor is to intercept and modify SIP packets (actually any IP packet) on the wire and to modify it before it reaches the application layer (userspace program) or after it has been sent from the application layer. SIP interceptor is built on the Linux “libnetfilter_queue” library.  In userspace SIP interceptor uses “libnetfilter_queue” to connect to queue 0 (the default one) and get packets from the kernel. It modifies each packet if required, passes the packet back to the kernel (SIP Interceptor operates in NFQNL_COPY_PACKET mode) and finally issues a verdict on the packet  (NF_ACCEPT the packet).

Regular expressions are used to specify how SIP messages should be modified and this gives SIP Interceptor great flexibility as well as minimising the packet inspection and modification overhead. For example using  simple regular expressions SIP Interceptor can be used to modify SIP messages in the following way in order to quickly resolve SIP interoperability issues which it might not be possible to fix within the SIP application itself:

  • Adding or removing custom SIP headers
  • Removing or reordering Via: headers
  • Adding a default SDP to INVITES without SDP
  • Removing codecs within SDPs
  • Removing multiple crypto attributes in SDPs with SRTP offered
  • Manipulating P-Asserted-Identity headers on withheld numbers
  • Removing non standard tags within the Call-Info header
  • Translating one SIP response code to another
  • Setting of QoS / Differentiated Services Code Point (DSCP) on SIP and RTP traffic
  • Overwriting the Request URI header  to fix redirect bugs
  • Masking identities / implementing P-Asserted-Identity  (PAI)
  • Solving NAT headaches on SIP trunks

SIP Interceptor  relies on NFQUEUE which is a Linux iptables and ip6tables target that delegates the decision on packets to a userspace application. The following command will pass all outgoing ICMP messages to SIP interceptor or, more correctly, it passes them to queue 0 on which SIP interceptor installs itself:

iptables -A OUTPUT -p icmp -j NFQUEUE --queue-num 0

This installs a rule in the OUTPUT chain to direct ICMP traffic to NFQUEUE  and tells NFQUEUE to shunt them into queue 0. Note that if nothing is installed on the queue to set ACCEPT verdicts e.g. SIP Interceptor is not running the packets will be dropped.  To remove the rule:

iptables -D OUTPUT -p icmp -j NFQUEUE --queue-num 0

The following rule will ask for a decision to a listening userspace program for all packets into the server:

iptables -A INPUT -j NFQUEUE --queue-num 0

The level of granularity can be increased by specifying IP addresses, port ranges etc. etc. For example,  to add a rule to pass all packets to SIP Interceptor for incoming TCP packets to port 5060 from  source IP in the 192.168.1.100-192.168.1.200 range only:

iptables -A INPUT -p tcp --dport 5060 -m iprange --src-range 192.168.1.100-192.168.1.200 -j NFQUEUE --queue-num 0
iptables -A INPUT -p udp --dport 5060 -j NFQUEUE --queue-num 0

-p sets the IP protocol for the rule, which can be either icmp, tcp, udp, or all, to match every supported protocol. In addition, any protocols listed in /etc/protocols may also be used. If this option is omitted when creating a rule, the all option is the default.

For more information please see:

https://help.ubuntu.com/community/IptablesHowTo

Of course this solution only works for UDP and TCP transports. For SIP over TLS (and Windows OS for that matter) we would need to consider something a bit more complex like reSIProcate (http://www.resiprocate.org).

But hopefully this is a good start and you can see SIP Interceptor in action below.

 

Share

Sending a SIP INFO message from a Genesys IRD strategy

On my current project we needed to send a SIP INFO message from SIP server. Before I forget here is how it can be done:

  • Assign SIP INFO body to a variable:

  • Assign extensions attributes:

Cat[‘extensions.Content-Type:application/vnd.etsi.sci+xml|extensions.Content-Disposition:render;handling=optional|extensions.Body:’,vBody]

  • Send a private service request. Note that 105 is the ID of AttributePrivateMsgID and 3018 is the message ID for Advice of Charge (AoC). For reference other known values of AttributePrivateMsgID are:

3013 (GSIP_RECORD_START) – Starts GQM recording
3014 (GSIP_RECORD_STOP) – Stops a GQM recording
3015 (GSIP_RECORD_PAUSE ) – Pauses a GQM recording
3016 (GSIP_RECORD_RESUME ) Resumes a GQM  recording
4012 – Start of Customer Greeting (See SIPS option greeting-notification)
4013 – End of Customer Greeting

SendRequest[RequestPrivateService,Cat[‘thisdn:’,Dest[],’|connid:’,ConnID[],’|105:3018|’,vExtensions]]

  • Test it – SIP INFO sent with supplied body:

13:59:12.608 Trc 04541 RequestPrivateService received from [17] (00000004 URS_1 192.168.1.11:44124)

message RequestPrivateService

AttributeThisDN      ‘0150’

AttributeConnID      00890237bba2601a

AttributeReferenceID 259

       AttributeExtensions  [124] 00 03 00 00..

              ‘Content-Type’       ‘application/vnd.etsi.sci+xml’

              ‘Content-Disposition’      ‘render;handling=optional’

              ‘Body’ ‘varData=998000000000’

       AttributePrivateMsgID      3018

13:59:12.608 Int 04543 Interaction message “RequestPrivateService” received from 17 (“URS_1”)

13:59:12.608  — created: CRequest@2aaaac041f20 RequestPrivateService-URS_1[17]/259

13:59:12.608: $+TLIB:CTI:Unknown:0:0

13:59:12.608 +++ CIFace::Request +++

— new invoke

— thisCall by party

Parsed: RequestPrivateService

From: URS_1[17]/259

Numbers: +<0150> -<none>

Calls: 2aaaac035d30:1 none

Parties: 0150.2aaaac042260-2aaaac035d30:1

none

Status: parsed:1 queued:0 sent:0 acked:0 preevent:0 event:0 context:0 transferred:0

—–

— validate

— state check: ok

CIFace: Sent CRequest@2aaaac041f20 RequestPrivateService-URS_1[17]/259

FinishRequest CRequest@2aaaac041f20 RequestPrivateService-URS_1[17]/259

IFace stats: q=0 s=0

— complete

13:59:12.608: SipTServer::PrivateServiceAdviceOfCharge get destination from otherParty: 3001

13:59:12.608: SIPTR(11): Begin step 0 – SipTransactionExecuteCtiRequest(12)

13:59:12.608 SIPCONN(3001): CtiRequest(9)

13:59:12.608: SIPDLG[4]: register TRN[11]

13:59:12.608: Sending  [19,TCP] 570 bytes to 192.168.1.11:5060 >>>>>

INFO sip:gw+Genesys@192.168.1.11:5060;tport=tcp;transport=tcp;gw=Genesys SIP/2.0

From: <sip:4100@192.168.1.11:5360>;tag=00383D6C-79FE-1287-BB5F-0B01A8C0AA77-3

To: “3001 on FS” <sip:3001@192.168.1.11>;tag=SQN3c6629UBNj

Call-ID: 189d697d-c96a-1231-5ea1-e091536f4cb1

CSeq: 2 INFO

Content-Length: 20

Content-Type: application/vnd.etsi.sci+xml

Via: SIP/2.0/TCP 192.168.1.11:5360;branch=z9hG4bK00383D8A-79FE-1287-BB5F-0B01A8C0AA77-8

Contact: <sip:192.168.1.11:5360;transport=tcp>

Content-Disposition: render;handling=optional

Max-Forwards: 68

varData=998000000000

 

Share

Client side email forwarding in Microsoft Outlook

For security reasons the forwarding of emails to external destinations is often disabled server side in Microsoft Exchange. If you really still want / need to do this then here is how:

  • Add the following VBA code in the Visual Basic editor of Outlook (Alt-F11). Be sure to change email@email.com to the address where you want the mail to go and also adjust the days and times when you want forwarding to occur. Comment out the line “myattachments.Remove 1” if you want to forward attachments as well:

Sub AutoForwardEmail(Item As Outlook.MailItem)

Dim myFwd As Outlook.MailItem

Dim currentWeekDay As String

Dim currentHour As Integer

currentWeekDay = WeekdayName(weekDay(Date), False, vbSunday)

currentHour = hour(Time)

If currentWeekDay = “Saturday” Or currentWeekDay = “Sunday” Or currentHour < 9 Or currentHour > 17 Then

Set myFwd = Item.Forward

Set myattachments = myFwd.Attachments

While myattachments.Count > 0

myattachments.Remove 1

Wend

myFwd.Recipients.Add “email@email.com

myFwd.Send

End If

Set myFwd = Nothing

End Sub

  • Enable Macros in Outlook (Tools -> Macro -> Security) and then restart Outlook:

  • Tell Outlook to run this code for each inbound message (Tools -> Rules and Alerts -> New Rule -> Check Messages when they arrive -> Next -> YES -> Checkbox “Run a Script” -> Then select the script you just created e.g.  “AutoForwardEmail”:

  • Make sure that Outlook is running and connected to Exchange for this to work!

Share