DragonFly On-Line Manual Pages

Search: Section:  


smpp_base_syntax(1)    DragonFly General Commands Manual   smpp_base_syntax(1)

       Authors: Enrique Marcote (enrique.marcote@erlang-consulting.com) Miguel
       Rodriguez (miguel@erlang-consulting.com)

MODULE

smpp_base_syntax

DATATYPES

The following data-types are meta-types used to specify the SMPP parameter types. These meta-types are used to encode and decode values and check that they match the parameter specification. {constant, Value} Types Value = bin() Constant declaration. Constants are defined in binary format and their value is packed as is. {integer, Size, Min, Max} Types Size = int() Min = int() Max = int() Integer data-type declaration. Size is the size in octets, Min the lower limit (included) and Max the upper limit (included). {c_octet_string, Fixed, Size, Format} Types Fixed = bool() Size = int() Format = fun(Str) -> bool() Str = string() C-Octet String data-type declaration. In SMPP, a C-Octet String must always be NULL terminated, thus the minimun length allowed is 1 octet. The Size of a c_octet_string parameter specification must be defined according to SMPP specs. The Size includes the trailing NULL_CHARACTER. When enconding the string corresponding to a c_octet_string the trailing NULL_CHARACTER is automatically included. An of course, this character is also automatically removed at decode time. Fixed is a boolean indicating if the parameter has a fixed length or not. Size indicates the size in octets including trailing NULL_CHARACTER and Format is a format predicate that the C-Octet String must satisfy in order to match the type specification. {octet_string, Fixed, Size, Format} Types Fixed = bool() Size = int() Format = fun(Str) -> bool() Str = string() Octet String data-type declaration. An Octet String is not necessary to be NULL terminated, thus the minimun length allowed is 0 octets. Fixed is true if the parameter is of fixed length, false otherwise. Size is the size in octets and Format is a format predicate that the value must satisfy in order to match the type specification. {list, Type, Size} Types Type = {constant, Value} | {integer, Size, Min, Max} | {c_octet_string, Fixed, Size, Format} | {octet_string, Fixed, Size, Format} | {list, Type, Size} | {composite, Name, Tuple} | {union, Types} Value = bin() Size = int() Min = int() Max = int() Format = fun(Str) -> bool() Str = string() Fixed = bool() Name = atom() Tuple = term() Types = [Type] List data-type declaration. Represents a list with elements of the same Type. Notice that nested data-type definitions are allowed. Type could be: o a constant, even it doesn't make much sense. o basic data-type; integer, c_octet_string or octet_string. A list of basic values. o complex data-type such as tlvs lists, composites or union declarations. Type defines the type of the elements on the list. Any kind of data-type declaration is valid. Size is the maximum number of elements. {composite, Name, Tuple} Types Name = atom() Tuple = term() Composite data-type declaration. If Name is undefined the composite is said to be anonymous and thus represented by a tuple. Named composites are represented by records of type Name. It is responsibility of the programmer to provide the appropriate record definitions. Name is ignored when encoding the value into a binary stream. It is only considered to translate the binary representation of a composite into erlang records. It also helps to document the declaration of nested data structures. It'll be a good practice to give the composite (and the associated record) the same Name that the SMPP Protocol Specification uses SMPP (5.0). Whether named or not, Tuple is a tuple (never a record) defining the type structure of the composite. For example, in a composite with two fields; an integer and an octet_string, Tuple would be something like: {?INTEGER_4, VAR_OCTET_STRING(21)} Nested data-type definitions are allowed. An element on the composite may be of the type: o constants. o basic data-types; integer, c_octet_string or octet_string. o complex data-types such as lists, composites or union declarations. Name is the identifier of the composite. Must be left undefined if the composite is anonymous. Tuple defines the structure of the composite. Any kind of data-type declaration is a valid term of this tuple. {union, Types} Types Types = [Type] Type = {constant, Value} | {integer, Size, Min, Max} | {c_octet_string, Fixed, Size, Format} | {octet_string, Fixed, Size, Format} | {list, Type, Size} | {composite, Name, Tuple} | {union, Types} Value = bin() Size = int() Min = int() Max = int() Fixed = bool() Format = fun(Str) -> bool() Str = string() Name = atom() Tuple = term() Union data-type declaration. Defines a new type which is the union of Types. For example the destination address in a submit_multi command represents either a distribution list or an SME address (these addresses have different data-types). {union, [SmeAddress, DlAddress]} Where SmeAddress and DlAddress are composite data-type definitions. Notice that nested data-type declarations are allowed. In SMPP the union declaration is mainly used in examples like the one above mentioned, where the union types are composites. Types a list with the types of the union.

DESCRIPTION

Base syntax used for the SMPP implementation. Even the content of this header file can be considered implementation-specific, the definitions herein included are inspired on the conventions used on SMPP (5.0). As a guideline some comments include references to the specific section numbers on SMPP (5.0). The best way to understand the meaning of the base syntax and how everything works, is by a complete example. On page 72, section 4.2.3.1 of the SMPP specification SMPP (5.0), the following fields are defined as part of the //submit_multi</i> operation Fragment of Table 4-18 submit_multi PDU +--------------------+-------------+----------------+ | Field Name | Size Octets | Type | +--------------------+-------------+----------------+ | number_of_dests | 1 | Integer | +--------------------+-------------+----------------+ | dest_address | Var. max 24 | Composite | +--------------------+-------------+----------------+ | - dest_flag | 1 | Integer | +--------------------+-------------+----------------+ | - dest_addr_ton | 1 | Integer | +--------------------+-------------+----------------+ | - dest_addr_npi | 1 | Integer | +--------------------+-------------+----------------+ | - destination_addr | Var. max 21 | C-Octet String | +--------------------+-------------+----------------+ | dest_address | Var. max 23 | Composite | +--------------------+-------------+----------------+ | - dest_flag | 1 | Integer | +--------------------+-------------+----------------+ | - dl_name | Var. max 21 | C-Octet String | +--------------------+-------------+----------------+ dest_address is a composite field containing a mandatory dest_flag field (dest_flag is a constant) and either an SME address (when dest_flag is 0x01) or a distribution list name (dest_flag is 0x02); thus dest_address is an union. Additionally the field can be encoded multiple times according to the value specified in the number_of_dests field; dest_address is also a list. Using the base syntax, this declaration has the following internal representation: -define(DEST_FLAG_SME_DATATYPE, ?CONSTANT(16#01)). -define(DEST_FLAG_DL_DATATAYPE, ?CONSTANT(16#02)). -define(DEST_ADDR_TON_DATATAYPE, ?BOUND_INTEGER(1, 2#00000110)). -define(DEST_ADDR_NPI_DATATAYPE, ?BOUND_INTEGER(1, 2#00010010)). -define(DESTINATION_ADDR_DATATAYPE, ?VAR_C_OCTET_STRING(21)). -define(DL_NAME_DATATAYPE, ?VAR_C_OCTET_STRING(21)). -define(DEST_ADDRESS_SME_DATATAYPE, ?COMPOSITE(dest_address_sme, {?DEST_FLAG_SME_DATATAYPE, ?DEST_ADDR_TON_DATATAYPE, ?DEST_ADDR_NPI_DATATAYPE, ?DESTINATION_ADDR_DATATAYPE})). -define(DEST_ADDRESS_DL_DATATAYPE, ?COMPOSITE(dest_address_dl, {?DEST_FLAG_DL_DATATAYPE, ?DL_NAME_DATATAYPE})). -define(DEST_ADDRESS_DATATAYPE, ?UNION([?DEST_ADDRESS_SME_DATATAYPE, ?DEST_ADDRESS_DL_DATATAYPE])). -define(DEST_ADDRESS_MULTI_DATATAYPE, ?LIST(?DEST_ADDRESS_DATATAYPE)). Notice that DEST_ADDRESS_MULTI_DATATAYPE embraces the definition of both fields; number_of_dests and dest_address, since a list is encoded in a Length ++ List fashion, number_of_dests doesn't need to be explicitly declared. Additionally, two records must be defined in order to successfully decode named composites: -record(dest_address_sme, {dest_flag, dest_addr_ton, dest_addr_npi, destination_addr}). -record(dest_address_dl, {dest_flag, dl_name}). The record identifiers match the names provided in the composite declaration for the decoding function to work propertly. These names are ignored by the encode function though.

EXTERNAL EXPORTS

Functions for the SMPP base syntax manipulation. decode(Binary, Type) -> {ok, Value, Rest} | {error, Reason} Types Binary = bin() Type = {constant, Constant} | {integer, Size, Min, Max} | {c_octet_string, Fixed, Size, Format} | {octet_string, Fixed, Size, Format} | {list, Type, Size} | {composite, Name, Tuple} | {union, Types} Constant = bin() Size = int() Min = int() Max = int() Fixed = bool() Format = fun(Str) -> bool()`` Str = string() Name = atom() Tuple = term() Types = [Type] Value = term() Rest = bin() Reason = {type_mismatch, Type, Details} Details = Data | Reason Data = bin() | int() | string() Decodes a Value from the head of a Binary using a Type specifier. As the Value is decoded a type checking operation is performed, if successful the term {ok, Value, Rest} is returned (where Rest is the remainder of the unused binary), otherwise {error, {type_mismatch, Type, Details}} is returned. Every type is decoded according to SMPP (5.0). constant Binaries, strings and integers are valid constants. If the binary representation of the Constant is at the head of Binary, the Constant is returned as Value. Otherwise an error is reported. integer Checks if Value is a valid Size octets integer. Must be an integer between 0 and math:pow(256, Size) - 1. An integer of Size octets is taken from the head of the Binary, if not enough bytes an error is reported. c_octet_string Checks if Value is a valid C-Octet String. A C-Octet String must be NULL_CHARACTER ($\0) terminated. When a fixed size is given and the Size-th octet on the Binary is the NULL_CHARACTER, a Size - 1 long binary is taken an translated into string using the binary_to_list BIF. On variable length strings, every octet until the NULL_CHARACTER is taken using the function cl_binary:take_until/3 (common_lib). The result is translated to a list with the BIF binary_to_list. Notice that the resulting Value is always smaller than Size characters long. <font color="red">Important (Since version 0.2).</font> The base syntax takes care of trailing NULL_CHARACTERs for you so, even though you have to count this character when setting the Size field, <b>do not</b> add a trailing NULL_CHARACTER in your c_octet_string values, base_syntax:decode/2 handles NULLs on its own. As a rule of thumb. Set the Size of your c_octet_string accordingly to SMPP specs. Do not expect decoded c_octet_string values to have a trailing NULL_CHARACTER. This character is automatically removed at decode time. octet_string When a fixed size is given the Value must be exactly 0 or Size characters long. For variable lengths any range between 0 and Size octets is considered to be correct. Fixed size Octet Strings are decoded pretty much like a C-Octet String, but no terminating NULL_CHARACTER is required. It's not easy to guess where a variable Octet String ends, in fact this data-type makes sense only if encapsulated inside a TLV. In order to let a TLV recursively decode an inner variable Octet String the following rule applies; if size(Binary) less than Size, the whole ``Binary is translated to a list (string), otherwise the first Size octets of the Binary are taken. list Every Value in the list must conform the given Type. To decode a list, a (Size / 256) + 1 octets integer indicating the total number Num of values is extracted from the head of the Binary, then a list with Num elements is decoded using the base Type of the list. This list of Values is returned, Num is discarded. composite In a composite every field is checked against the corresponding field in the tuple with the types. Every field in the composite is decoded, one at a time, using the corresponding field in the type descriptor. On anonymous composites (Name = undefined) the returning Value is a tuple built from the individual fields, named composites tuples are translated to a record of type Name. union The Value must conform at least one of the given types. An union value is decoded using the first type descriptor conformed by the value. encode(Value, Type) -> {ok, Binary} | {error, Reason} Types Value = term() Type = {constant, Constant} | {integer, Size, Min, Max} | {c_octet_string, Fixed, Size, Format} | {octet_string, Fixed, Size, Format} | {list, Type, Size} | {composite, Name, Tuple} | {union, Types} Constant = bin() Size = int() Min = int() Max = int() Fixed = bool() Format = fun(Str) -> bool() Str = string() Name = atom() Tuple = term() Types = [Type] Binary = bin() Reason = {type_mismatch, Type, Details} Details = Data | Reason Data = bin() | int() | string() Encodes a Value using a Type specifier. Before encoding the value a type checking operation is done, if unsuccessful the term {error, {type_mismatch, Type, Details}} is returned. Every type is encoded according to SMPP (5.0). constant Value must be identical to given constant. Binaries, strings and integers are valid constants. The Value is directly encoded into a binary. integer Checks if Value is a valid Size octets integer. Must be an integer between 0 and math:pow(256, Size) - 1. The integer is translated into binary using Size octets. c_octet_string Checks if Value is a valid C-Octet String: Just a string with Size - 1 characters. Notice that C-Octet Strings (erlang) values should not include the terminating NULL_CHARACTER ($\0), it is automatically included by the encode function. When a fixed size is given, the Value (having no terminating NULL_CHARACTER) must be exactly 0 or Size - 1 characters long. For variable lengths any range between 0 and Size - 1 octets is considered to be correct. The string is translated into binary using the BIF list_to_binary, thus one octet per character. As a rule of thumb. Set the Size of the c_octet_string declaration accordingly to SMPP specs. Do not add the trailing NULL_CHARACTER to the values of the c_octet_string parameters. The NULL_CHARACTER is automatically included at encode time. octet_string When a fixed size is given the Value must be exactly 0 or Size characters long. For variable lengths any range between 0 and Size octets is considered to be correct. An string is translated into binary using the BIF list_to_binary, thus one octet per character. list Every Value in the list must conform the given Type. To encode a list, a (Size / 256) + 1 octets integer indicating the total number of values is prepended to the list of encoded values. Every element on the list is encoded (and appended) according to the given type. composite In a composite every field is checked against the corresponding field in the tuple with the types. Every field in the composite is encoded using the corresponding field in the type descriptor. The global result is obtained concatenating every encoded field in the same order of appearance in the composite. On named composites the identifier of the record is discarded (not encoded). union The Value must conform at least one of the given types. An union value is encoded using the first type descriptor conformed by the value. fit(Type, Size) -> NewType Types Type = {constant, Constant} | {integer, Size, Min, Max} | {c_octet_string, Fixed, Size, Format} | {octet_string, Fixed, Size, Format} | {list, Type, Size} | {composite, Name, Tuple} | {union, Types} Constant = bin() Size = int() Min = int() Max = int() Fixed = bool() Format = fun(Str) -> bool()`` Str = string() Name = atom() Tuple = term() Types = [Type] NewType = Type Fits a type specifier to a given Size. o Constants, composites and union specifiers are left unchanged. o On strings (c_octet_string and octet_string), besides the size field, the length is set to fixed (fixed = true). o The min and max fields are not changed on integers, the size is changed with no further checking. o If the new Size is greater than the one permitted by the Type, the Type is returned unchanged. This function was mainly conceived to adapt the type specification to a TLV parameter definition.

REFERENCES

SMPP (5.0) Short Message Peer-to-Peer Protocol Specification. Version 5.0. SMS Forum. 3GPP TS (23.040) Technical Realization of the Short Message Service (SMS) Release 4. Version 5.0.0. 3GPP (http://www.3gpp.org).

SEE ALSO

oserl(1) oserl Version: smpp_base_syntax(1)

Search: Section: