Implementing a Perl plugin

Contents

This document describes how to implement a EMG plugin in Perl. First, setup a separate Perl installation according to description here:
https://nordicmessaging.se/emg-5-2-6-and-perl-plugins/

Adding a Perl plugin to EMG configuration

Plugins are defined in a PLUGIN section in server.cfg. The defined plugin can then be used for one or more connectors using the PLUGIN keyword in the connector section. A sample configuration is shown below.

PLUGIN perl-reject <
LIBRARY=/etc/emg/plugins/reject.pl
CONFIG=config parameter
INSTANCES=1
>

CONNECTOR smpp-in1 <
...
PLUGIN=perl-reject
>

When referencing the plugin in connector section the plugin name can optionally be followed by “:” and a string which can be retrieved from request object in function calls. This is useful when using the same plugin on different connectors.

CONNECTOR smpp-in1 <
...
PLUGIN=perl-reject:smpp
>

CONNECTOR ucp-in1 <
...
PLUGIN=perl-reject:ucp
>

Plugin lifecycle

When emgd is started one perl interpretator is created for each plugin instance and the “create_config” hook, if present, is executed for each instance.

Since a separate perl interpretator is created for each instance different instances cannot share data easily. It requires using shared memory or networking.

All plugins are loaded on emgd startup, with all instances being started in sequence. It is therefore critical that this operation is fast, and does not load lots of data.

Any changes to the plugin source code requires an emgd restart to take effect.

Plugin hooks

There are several hooks defined in EMG. For each hook the corresponding function in the plugin will be called, if present.

The plugin hooks are:

# Executed on emgd start when plugins are loaded
sub create_config
{
  my ($plugin_name, $config) = @_;
  my $myconfig = "dummy";
  return $myconfig;
}

# Executed when a message has been received, but before response is sent back
sub before_receive
{
  my ($request, $response) = @_;
  my $myconfig = $request->{'config'};
  # Accept message
  my $status = 0;
  return $status;
}

# Executed before routing logic is applied
sub route
{
  my ($request, $response) = @_;
  $response->{'route'} = 'smpp-out2';
  # Use 'route'
  return 0;
}

# Executed before message send operation
sub before_send
{
  my ($request, $response) = @_;
  return 0;
}

# Executed after message send operation
sub after_send
{
  my ($request, $response) = @_;
  my $status = $request->{'result'};
}

# Executed after a delivery report (DLR) has been received
sub after_dlr
{
 my ($request, $response) = @_;
}

It is possible to modify message options in all plugin hooks.

Plugin hooks sequence diagram

emg-plugincalls

About the route hook

If route returns 0 and $response->route is set to a string with length > 0, then that string is used as the route target connector and no other routing logic is applied.

For other cases, normal routing logic will be applied.

Plugin objects

The following objects (perl hashes) are used in the EMG Perl Plugin API:

Object $request

configObject returned in create_config.
connectorA connector object.
ccargThe string optionally specified when referencing plugin in connector config.
namePlugin name.
qeMessage object.
resultSet to 0 if send operation was successful, otherwise set to non-zero (after_send only).

Object $response

errorcodeNumeric error code (used by “before_*” hooks when return value is non-zero).
errormessageError text (used by “before_*” hooks when return value is non-zero).
routeTarget connector (only used by “route” hook).

Object connector

nameConnector name.
instanceConnector instance number (starting at 0).
loglevelConnector log level.
usernameUsername (outgoing connectors only).
passwordPassword (outgoing connectors only).

Object message (qe)

All message options as key-value pairs with MGP names as key. The message options can be modified from any plugin hook and will take effect regardless of return value.

Sample code:

sub before_receive
{
  my ($request, $response) = @_;
  my $qe = ${$request}{'qe'};
  $qe->{'SOURCEADDR'} = 'sender';
  return 0;
}

Sample plugins

Some sample plugins can be found here:
https://nordicmessaging.se/sample-perl-plugins/