The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Net::CIMD - pure Perl implementation of CIMD2 over TCP

SYNOPSIS

  use Net::CIMD;
  my $me=Net::CIMD->login(
                        host    =>      $ip_address,
                        port    =>      $port,
                        user_identity   =>      $login,
                        password        =>      $password,
                        local_ip        =>      $ip_address
                        ) or croak "Cannot connect to $ip_address $!\n";

DESCRIPTION

Computer Interface for Message Distribution protocol, which is frequently used to pass short messages between mobile operators implementing short message service (SMS).

Operations, and parameters names are the same as in cimd specification document.

$me->read_sync() doesn't implement all response messages, but it was tested, and it answers at least to deliver_status_report operation.

This module lack also tests. Tests are ongoing, but you can help by reporting any observed bugs.

Except login method, all other methods work in asychronous mode. Which means it's to the user to wait for the answer for each sent packet. This approach makes it easier to use speed related mechanisms like windowing.

This module in intended to be used as client or server, but current version supports only client mode.

CONSTRUCTORS

login()

Create a new CIMD client object and open conncetion to SMSC host

        my $cimd=Net::CIMD->login(
                        host    =>      $ip_address,    # defaults to 127.0.0.1
                        port    =>      $port,  # defaults to 9971
                        user_identity   =>      $login
                        password        =>      $password,
                        local_ip        =>      $ip_address,    # defaults to 127.0.01: this parameter is very important when we've many network interfaces.
                        subaddr =>      $subaddr,
                        window_size     =>      $size,
                        IP_address      =>      $ip_address     # This is a new parameter not available in SC8.0.
                        ) or croak "Cannot connect to $ip_address $!\n";

It first establish a connexion with the server, and then send the credentials.

METHODS Although current version supports only client mode, all CIMD operations are already implemented

methods:
            login()
            logout()
            submit()
            enquire_message_status()
            delivery_request()
            cancel()
            set_parameters()
            get_parameters()
            submit_status_report()
            deliver_message()
            deliver_status_report()
            alive()
            login_resp()()
            logout_resp()
            submit_resp()
            enquire_message_status_resp()
            delivery_request_resp()
            cancel_resp()
            set_parameters_resp()
            get_parameters_resp()
            submit_status_report_resp()
            deliver_message_resp()
            deliver_status_report_resp()
            alive_resp()
            general_error_resp()
            nack()
parameters:

Previous methods can be used with the folowing parameter names:

            user_identity
            password
            subaddr
            window_size
            destination_address
            originating_address
            originating_IMSI
            alphanumeric_ariginating_address
            originated_visited_MSC_address
            data_coding_scheme
            user_data_header
            user_data
            user_data_binary
            more_messages_to_send
            validity_Period_Relative
            validity_Period_Absolute
            protocol_identifier
            first_delivery_time_relative
            first_delivery_time_absolute
            reply_path
            status_report_request
            cancel_enabled
            cancel_mode
            service_centre_time_stamp
            status_code
            status_error_code
            discharge_time
            tariff_class
            service_description
            message_count
            priority
            delivery_request_mode
            service_center_address
            get_parameter
            SMS_center_time
            error_code
            error_text

As an example, submit message can be wrote like this:

            my $cimd=Net::CIMD->login(
                            host    =>      $ip_address,
                            port    =>      $port,
                            user_identity   =>      $login,
                            password        =>      $password,
                            local_ip        =>      $ip_address
                            ) or croak "Cannot connect to $ip_address $!\n";
            $cimd->submit(
                    destination_address     =>      '00212661093659',
                    originating_address     =>      '2727',
                    data_coding_scheme      =>      0,
                    user_data       =>      'Salam cava ?',
                    first_delivery_time_relative    =>      1,
                    status_report_request   =>      12,
                    priority        =>      1
                    );

Current version assumes that all parameters are optional, unlike in the specification. This is mainly because of the lack of time, and will be fixed in next version. Strong parameters control will be added in future versions.

Receiving PDUs

For reception, this module has methods that send ACK before returning the packet, and other that don't.

receive_packet()

This method returns raw packet without sending ACK.

        my $raw_resp=$cimd->receive_packet();
read_sync()

This method receives a raw packet from network connexion, decodes it into Net::CIMD::PDU, send the ACK to the remote entity, and then return the decoded PDU.

        my $pdu=$cimd->read_sync();
read_async()

Similar to read_sync(), except that it doesn't send any response.

OTHER METHODS

Some other useful methods that doesn't require a connexion to an SMSC are also available.

decode_packet()

This method is used to decode a raw packet. It was separated from reading from the stream, so it can be used for other sources of data (for example NetPacket::TCP).

        my $pdu=$cimd->decode_packet($var);
or
        my $pdu=Net::CIMD->decode_packet($var);
pack_7bit()

This function is used to calculate GSM7bit encoding of a ASCII coded string. Special characters encoding is still missing. Actually, it encodes only characters that have the same value in ASCII and GSM7Bits.

unpack_7bit()

This function is used to convert text from GSM7bits encoding to ASCII.

EXAMPLES

Typical client:

            #!/bin/env perl
            
            use Net::CIMD;
            use v5.8;
            use Data::Dumper;
            use Carp;
            
            my $ip_address='127.0.0.1';
            my $port='9971';
            my $login='login';
            my $password='secret';
            
            local $Carp::CarpLevel = 1;
            
            my $cimd=Net::CIMD->login(
                    host    =>      $ip_address,
                    port    =>      $port,
                    user_identity   =>      $login,
                    password        =>      $password,
                    local_ip        =>      $ip_address
                    ) or croak "Cannot connect to $ip_address $!\n";
            $cimd->submit(
                    destination_address     =>      '00212661093659',
                    originating_address     =>      '2727',
                    data_coding_scheme      =>      0,
                    user_data       =>      'Salam cava ?',
                    first_delivery_time_relative    =>      1,
                    status_report_request   =>      12,
                    priority        =>      1
                    );
            
            
            my $resp=$cimd->read_sync();
            
            print Dumper($resp)."\n";

Typical server:

            #!/bin/env perl
            use Net::CIMD qw(pack_7bit unpack_7bit);
            use Data::Dumper;
            
            use constant tunnel_file => '/tmp/ttt';
            use constant reply_tab  =>      {
                    'login' =>      sub     {
                                    my ($server, $pdu)=@_;
                                    $server->login_resp();
                                    },
                    'submit'        =>      sub     {
                                    my ($server, $pdu)=@_;
                                    $server->submit_resp(
                                    destination_address     =>      $pdu->{destination_address},
                                    service_centre_time_stamp       =>      &now()
                                    );
                                    },
                    'logout'        =>      sub     {
                                    my ($server, $pdu)=@_;
                                    $server->logout_resp();
                                    },
                    'deliver_message_resp'  =>      sub     {}
            };
            
            my $listener=Net::CIMD->listen(
                                            queue_size      =>      120,
                                            port    =>      51050,
                                            timeout =>      300);
            print Dumper($listener)."\n";
            
            my $server=$listener->accept();
            
            print Dumper($server)."\n";
            
            my $pid=fork;
            
            if($pid==0)
            {
                    my $resp=$server->read_async();
                    while($resp->{operation})
                    {
                            print Dumper($resp)."\n";
                            &{reply_tab->{$resp->{operation}}}($server, $resp);
                            $resp=$server->read_async();
                    }
            }
            else
            {
                    while(1)
                    {
                    #your logic for sending messages goes here.
                    # For example, we check the existence of a file containing the message
                            if(-w tunnel_file)
                            {
                                    open FH, tunnel_file;
                                    while(chomp($_=<FH>))
                                    {
                                    @_=split /\|/;
                                    $server->deliver_message(
                                    destination_address     =>      $_[0],
                                    originating_address     =>      $_[1],
                                    user_data       =>      pack_7bit($_[2]),
                                    service_centre_time_stamp       =>      &now()
                                    );
                                    }
                                    close FH;
                                    unlink tunnel_file;
                            }
                            sleep 1;
                    }
            }
            sub now {
                    @_=localtime(time());
                    @_=reverse @_[0..5];
                    $_[1]++;
                    $_[0]+=1900;
                    return sprintf("%d%02d%02d%02d%02d%02d", @_);
            }
            
            

Limitations

Current version supports only client mode.

CIMD Specific abreviations should be added with encoding methods.

Connexion check is not performed. (when connexion is closed for some reason, the module still use the session).

Text encoding methode should be added.

No restrictions are applied to parameters.

NET::CIMD COMES WITH ABSOLUTELY NO WARRANTY.

AUTHOR

Badr Zarhri <badr.zarhri@gmail.com>

COPYRIGHT AND LICENSE

Copyright (C) 2013 by Badr Zarhri <badr.zarhri@gmail.com>

Net::CIMD is copyright (c) 2013 by Badr Zarhri, All rights reserved. You may use and distribute Net::CIMD under same terms as perl itself.

6 POD Errors

The following errors were encountered while parsing the POD:

Around line 353:

'=item' outside of any '=over'

Around line 371:

You forgot a '=back' before '=head1'

Around line 481:

You forgot a '=back' before '=head1'

Around line 503:

You forgot a '=back' before '=head1'

Around line 527:

You forgot a '=back' before '=head1'

Around line 655:

You forgot a '=back' before '=head1'