Home

bitcoder edited this page Feb 6, 2011 · 26 revisions
Clone this wiki locally

Welcome to the “ruby_ucp” wiki!
Contact me if you have any comments/sugestions.
Sergio Freire (sergio.freire at gmail.com)

Introduction

About “ruby_ucp”

“ruby_ucp” is a pure Ruby library implementation of the EMI/UCP v.4.6 specification/protocol used by Large Accounts (e.g. applications) to communicate with SMSC’s, in order to send and receive short messages (“SMS”).
It is licensed under LGPL v2.1, so feel free to use it and contribute with your code or feedback in order to improve it.
The main focus of this library is the correct encoding/decoding of UCP PDUs. By combining low-level with helper methods, the user has full control of the built PDUs, all with ease.
Besides this, two classes are given: one for an UCP client and another for an UCP server. These classes are not perfect (e.g. they dont implement states) but may be used in most scenarios, specially the client, and serve as inspiration to build other ones.

The gem is available for download directly from the RubyGems repository, and is named ruby_ucp.
The UCP specification itself: EMI/UCP v4.6.
Some local info about UCP PDUs: UCP PDUs.
Some local info on SMS alphabets/encodings: SMS alphabets.

Features

Currently, it supports:

  • encoding/decoding most UCP pdu’s: 01,30,31,51,52,53,54,55,56,57,58,60 and 61
  • direct access to UCP pdu fields
  • automatic checksum/length calculation
  • instantiate an UCP pdu object from a given string
  • helper methods within pdu’s, to easily build “submit messages” (AO)
  • support alphanumeric originators
  • en/decoding of 7bit GSM default alphabet text messages for basic text encoding
  • en/decoding of 16bit (UCS2) messages for full character support
  • simple UCP client (MULA), with authentication support
  • simple UCP server (e.g. for simulating a SMSC or a LA application working in UCP SILA mode)
  • automatic create multiple concatenated messages, for a given message text
  • extern, smarter and more correct UCP clients/servers may be implemented using just the UCP pdu encoding/decoding features

Soon:

  • automatic text encoding selection (7bit vs 16bit), for optimum concatenated message creation (reduce the number of SM parts; use only UCS-2 if necessary). (now 7bit is forced in make_multi_ucps() method)

Not so good features :)

  • the library is thought for correctness, not performance (you should not find a problem though)
  • the provided UCP client is synchronous; it does not have a state machine in order to handle UCP windowing features
  • the provided UCP server is also synchronous; it does not support UCP windowing
  • no Ruby v1.9.x support (it would require rewriting sensible parts due to encoding issues and string handling)
  • unitary tests unspecified, yet
  • documentation lacking, yet

Requirements

Ruby v1.8.6 or v.1.8.7. No v1.9.x support!
(tested with Ubuntu 9.10, Redhat AS 5.x)

SMS, SMSC and Large Accounts

SM, or short message, is normally a text message limited in size, than can be concatenated in order to compose a large message (may be text or data).
SMS is the acronym for Short Messaging Service, so it’s the service itself and not a short message.
SMSC is the SMS Center; it corresponds to the network entity responsible for receiving new submission requests and for delivering the SMs to the final endpoints (e.g. mobile users). As initially conceived, it is a signalling entity that accepts requests from mobile originators and that delivers SMs to them, all using signalling.
Later, there was the need to integrate SMSC with applications from the TCP/IP world, so they would be able to send SMs (e.g. marketing campaigns) or to receive them in order to provide value added services.

Integration scenarios

Code snippets

Creating PDU’s

automatic creating concatenated (UCP) messages

When we want to build an UCP message for a given text, we may have a problem: we don’t know if it is going to fit
the UCP pdu. It may be necessary to split the long message in several UCP pdu’s, each one corresponds to a SM part of a
concatenated message.
Using the “UCP.make_multi_ucps()” method returns an array of UCP 51 pdu’s.

ucps=UCP.make_multi_ucps(originator,recipient,message,message_reference)

manually instantiate PDU objects

To instantiate a UCP51 message is easy.

ucp=Ucp51Operation.new

In this case it’s an operation but the same can be done for a result PDU.

ucp=Ucp51Result.new

Likewise, filling some fields is also easy.
The following example overwrites the originator address (“oadc”) and sets its type to alphanumeric.

ucp.set_fields({:oadc=>"10412614190438AB4D",:otoa=>"5039"})

parsing and creating PDU objects from a string

An UCP PDU object (in fact an UcpMessage) can be built from a given string.

ucp=UCP.parse_str(2.chr+"*00/00113/O/51/961234567/1234/////////////////4/120/B49AED86CBC162B219AD66BBE17230//////////0106050003450202///90"+3.chr)

UCP client (e.g. large account)

An UCP client, implementing MULA, may be created using a provided class.

ucp_client=UcpClient.new(“localhost”,port,{:login=>1234,:password=>"portugal"})

Note that the login credentials are optional.

Sending SMS is quite easy; you can use an helper method (e.g. “basic_submit”) in some PDUs (01, 30, 51) in order produce
a PDU with the necessary UCP fields to send a short message.
The “basic_submit” method builds a “submit” message, with the given originator, recipient and message parameters.
The UcpClient class provides a synchronized method (“send_sync”) in order to send a given UCP message; by synchronized it means that the method sends the PDU and waits for the reply.

ucp=Ucp30Operation.new
ucp.basic_submit(1234, 961234567, "hello")
ans=ucp_client.send_sync(ucp)

if ans.is_ack?
  puts "ok!"
else
  puts "nok!"
end

UCP server (e.g. fake SMSC)

An UCP Server listens on a given TCP/IP port and accepts UCP PDUs (operations), processes them and replies back (with the corresponding result PDU).
Whenever creating the server, an handle method must be passed as argument. This method will be called with a SMSRequest object, where the source IP/port, originador, recipient and decoded message can be easily obtained. More, it’s possible to know if it’s a concatenated message.

def handle_me(smsreq)
 puts “handle_me [#{smsreq.source_ip}:#{smsreq.source_port}] (#{smsreq.originator},#{smsreq.recipient}) (#{smsreq.part_nr}/#{smsreq.total_parts}): #{smsreq.text}\n”
end
…
port=12009
server=UcpServer.new(method(:handle_me),port)

An UCP server may be used as a fake SMSC (SMSC simulator) or as a LA used in a SILA context.

==











==