1# Device::Gsm::Charset - GSM0338 <=> ASCII charset conversion module
2# Copyright (C) 2004-2015 Cosimo Streppone, cosimo@cpan.org
3#
4# This program is free software; you can redistribute it and/or modify
5# it only under the terms of Perl itself.
6#
7# This program is distributed in the hope that it will be useful,
8# but WITHOUT ANY WARRANTY; without even the implied warranty of
9# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10# Perl licensing terms for details.
11
12package Device::Gsm::Charset;
13$VERSION = $Device::Gsm::VERSION;
14
15use strict;
16use constant NPC7   => 0x3F;
17use constant NPC8   => 0x3F;
18use constant ESCAPE => 0x1B;
19
20# The following is the GSM 3.38 standard charset, as shown
21# on some Siemens documentation found on the internet
22
23#my $gsm_charset = join('',
24#	'@�$�������'."\n".'��'."\r".'���',  # 16
25#	'������������߻�',
26#	' !"# %&�()*+,-./',
27#	'0123456789:;<=>?',
28#	'-ABCDEFGHIJKLMNO',
29#	'PQRSTUVWXYZ�ֻܻ',
30#	'�abcdefghijklmno',
31#	'pqrstuvwxyz�����'
32#);
33
34#
35# These conversion tables are taken from pduconv 0.1 library
36# by Mats Engstrom <mats at nerdlabs dot org>. See also:
37# http://www.mikrocontroller.net/attachment/104082/pduconv.c
38# and
39# https://github.com/rdmeneze/SMSBox-PIC/tree/master/source/pdu_conv
40#
41# Un grazie a Stefano!
42#
43
44@Device::Gsm::Charset::GSM0338_TO_ISO8859 = (
45    64,      #  0      @  COMMERCIAL AT                           */
46    163,     #  1      �  POUND SIGN                              */
47    36,      #  2      $  DOLLAR SIGN                             */
48    165,     #  3      �  YEN SIGN                                */
49    232,     #  4      �  LATIN SMALL LETTER E WITH GRAVE         */
50    233,     #  5      �  LATIN SMALL LETTER E WITH ACUTE         */
51    249,     #  6      �  LATIN SMALL LETTER U WITH GRAVE         */
52    236,     #  7      �  LATIN SMALL LETTER I WITH GRAVE         */
53    242,     #  8      �  LATIN SMALL LETTER O WITH GRAVE         */
54    199,     #  9      �  LATIN CAPITAL LETTER C WITH CEDILLA     */
55    10,      #  10        LINE FEED                               */
56    216,     #  11     �  LATIN CAPITAL LETTER O WITH STROKE      */
57    248,     #  12     �  LATIN SMALL LETTER O WITH STROKE        */
58    13,      #  13        CARRIAGE RETURN                         */
59    197,     #  14     �  LATIN CAPITAL LETTER A WITH RING ABOVE  */
60    229,     #  15     �  LATIN SMALL LETTER A WITH RING ABOVE    */
61    NPC8,    #  16        GREEK CAPITAL LETTER DELTA              */
62    95,      #  17     _  LOW LINE                                */
63    NPC8,    #  18        GREEK CAPITAL LETTER PHI                */
64    NPC8,    #  19        GREEK CAPITAL LETTER GAMMA              */
65    NPC8,    #  20        GREEK CAPITAL LETTER LAMBDA             */
66    NPC8,    #  21        GREEK CAPITAL LETTER OMEGA              */
67    NPC8,    #  22        GREEK CAPITAL LETTER PI                 */
68    NPC8,    #  23        GREEK CAPITAL LETTER PSI                */
69    NPC8,    #  24        GREEK CAPITAL LETTER SIGMA              */
70    NPC8,    #  25        GREEK CAPITAL LETTER THETA              */
71    NPC8,    #  26        GREEK CAPITAL LETTER XI                 */
72    27,      #  27        ESCAPE TO EXTENSION TABLE               */
73    198,     #  28     �  LATIN CAPITAL LETTER AE                 */
74    230,     #  29     �  LATIN SMALL LETTER AE                   */
75    223,     #  30     �  LATIN SMALL LETTER SHARP S (German)     */
76    201,     #  31     �  LATIN CAPITAL LETTER E WITH ACUTE       */
77    32,      #  32        SPACE                                   */
78    33,      #  33     !  EXCLAMATION MARK                        */
79    34,      #  34     "  QUOTATION MARK                          */
80    35,      #  35     #  NUMBER SIGN                             */
81    164,     #  36     �  CURRENCY SIGN                           */
82    37,      #  37     %  PERCENT SIGN                            */
83    38,      #  38     &  AMPERSAND                               */
84    39,      #  39     '  APOSTROPHE                              */
85    40,      #  40     (  LEFT PARENTHESIS                        */
86    41,      #  41     )  RIGHT PARENTHESIS                       */
87    42,      #  42     *  ASTERISK                                */
88    43,      #  43     +  PLUS SIGN                               */
89    44,      #  44     ,  COMMA                                   */
90    45,      #  45     -  HYPHEN-MINUS                            */
91    46,      #  46     .  FULL STOP                               */
92    47,      #  47     /  SOLIDUS (SLASH)                         */
93    48,      #  48     0  DIGIT ZERO                              */
94    49,      #  49     1  DIGIT ONE                               */
95    50,      #  50     2  DIGIT TWO                               */
96    51,      #  51     3  DIGIT THREE                             */
97    52,      #  52     4  DIGIT FOUR                              */
98    53,      #  53     5  DIGIT FIVE                              */
99    54,      #  54     6  DIGIT SIX                               */
100    55,      #  55     7  DIGIT SEVEN                             */
101    56,      #  56     8  DIGIT EIGHT                             */
102    57,      #  57     9  DIGIT NINE                              */
103    58,      #  58     :  COLON                                   */
104    59,      #  59     ;  SEMICOLON                               */
105    60,      #  60     <  LESS-THAN SIGN                          */
106    61,      #  61     =  EQUALS SIGN                             */
107    62,      #  62     >  GREATER-THAN SIGN                       */
108    63,      #  63     ?  QUESTION MARK                           */
109    161,     #  64     �  INVERTED EXCLAMATION MARK               */
110    65,      #  65     A  LATIN CAPITAL LETTER A                  */
111    66,      #  66     B  LATIN CAPITAL LETTER B                  */
112    67,      #  67     C  LATIN CAPITAL LETTER C                  */
113    68,      #  68     D  LATIN CAPITAL LETTER D                  */
114    69,      #  69     E  LATIN CAPITAL LETTER E                  */
115    70,      #  70     F  LATIN CAPITAL LETTER F                  */
116    71,      #  71     G  LATIN CAPITAL LETTER G                  */
117    72,      #  72     H  LATIN CAPITAL LETTER H                  */
118    73,      #  73     I  LATIN CAPITAL LETTER I                  */
119    74,      #  74     J  LATIN CAPITAL LETTER J                  */
120    75,      #  75     K  LATIN CAPITAL LETTER K                  */
121    76,      #  76     L  LATIN CAPITAL LETTER L                  */
122    77,      #  77     M  LATIN CAPITAL LETTER M                  */
123    78,      #  78     N  LATIN CAPITAL LETTER N                  */
124    79,      #  79     O  LATIN CAPITAL LETTER O                  */
125    80,      #  80     P  LATIN CAPITAL LETTER P                  */
126    81,      #  81     Q  LATIN CAPITAL LETTER Q                  */
127    82,      #  82     R  LATIN CAPITAL LETTER R                  */
128    83,      #  83     S  LATIN CAPITAL LETTER S                  */
129    84,      #  84     T  LATIN CAPITAL LETTER T                  */
130    85,      #  85     U  LATIN CAPITAL LETTER U                  */
131    86,      #  86     V  LATIN CAPITAL LETTER V                  */
132    87,      #  87     W  LATIN CAPITAL LETTER W                  */
133    88,      #  88     X  LATIN CAPITAL LETTER X                  */
134    89,      #  89     Y  LATIN CAPITAL LETTER Y                  */
135    90,      #  90     Z  LATIN CAPITAL LETTER Z                  */
136    196,     #  91     �  LATIN CAPITAL LETTER A WITH DIAERESIS   */
137    214,     #  92     �  LATIN CAPITAL LETTER O WITH DIAERESIS   */
138    209,     #  93     �  LATIN CAPITAL LETTER N WITH TILDE       */
139    220,     #  94     �  LATIN CAPITAL LETTER U WITH DIAERESIS   */
140    167,     #  95     �  SECTION SIGN                            */
141    191,     #  96     �  INVERTED QUESTION MARK                  */
142    97,      #  97     a  LATIN SMALL LETTER A                    */
143    98,      #  98     b  LATIN SMALL LETTER B                    */
144    99,      #  99     c  LATIN SMALL LETTER C                    */
145    100,     #  100    d  LATIN SMALL LETTER D                    */
146    101,     #  101    e  LATIN SMALL LETTER E                    */
147    102,     #  102    f  LATIN SMALL LETTER F                    */
148    103,     #  103    g  LATIN SMALL LETTER G                    */
149    104,     #  104    h  LATIN SMALL LETTER H                    */
150    105,     #  105    i  LATIN SMALL LETTER I                    */
151    106,     #  106    j  LATIN SMALL LETTER J                    */
152    107,     #  107    k  LATIN SMALL LETTER K                    */
153    108,     #  108    l  LATIN SMALL LETTER L                    */
154    109,     #  109    m  LATIN SMALL LETTER M                    */
155    110,     #  110    n  LATIN SMALL LETTER N                    */
156    111,     #  111    o  LATIN SMALL LETTER O                    */
157    112,     #  112    p  LATIN SMALL LETTER P                    */
158    113,     #  113    q  LATIN SMALL LETTER Q                    */
159    114,     #  114    r  LATIN SMALL LETTER R                    */
160    115,     #  115    s  LATIN SMALL LETTER S                    */
161    116,     #  116    t  LATIN SMALL LETTER T                    */
162    117,     #  117    u  LATIN SMALL LETTER U                    */
163    118,     #  118    v  LATIN SMALL LETTER V                    */
164    119,     #  119    w  LATIN SMALL LETTER W                    */
165    120,     #  120    x  LATIN SMALL LETTER X                    */
166    121,     #  121    y  LATIN SMALL LETTER Y                    */
167    122,     #  122    z  LATIN SMALL LETTER Z                    */
168    228,     #  123    �  LATIN SMALL LETTER A WITH DIAERESIS     */
169    246,     #  124    �  LATIN SMALL LETTER O WITH DIAERESIS     */
170    241,     #  125    �  LATIN SMALL LETTER N WITH TILDE         */
171    252,     #  126    �  LATIN SMALL LETTER U WITH DIAERESIS     */
172    224,     #  127    �  LATIN SMALL LETTER A WITH GRAVE         */
173
174    #   12             27 10      FORM FEED
175    #   94             27 20   ^  CIRCUMFLEX ACCENT
176    #   123            27 40   {  LEFT CURLY BRACKET
177    #   125            27 41   }  RIGHT CURLY BRACKET
178    #   92             27 47   \  REVERSE SOLIDUS (BACKSLASH)
179    #   91             27 60   [  LEFT SQUARE BRACKET
180    #   126            27 61   ~  TILDE
181    #   93             27 62   ]  RIGHT SQUARE BRACKET
182    #   124            27 64   |  VERTICAL BAR                             */
183);
184
185#my $gsm_charset = join '' => map chr => @GSM0338_TO_ISO8859;
186
187@Device::Gsm::Charset::ISO8859_TO_GSM0338 = (
188    NPC7,        #     0      null [NUL]                              */
189    NPC7,        #     1      start of heading [SOH]                  */
190    NPC7,        #     2      start of text [STX]                     */
191    NPC7,        #     3      end of text [ETX]                       */
192    NPC7,        #     4      end of transmission [EOT]               */
193    NPC7,        #     5      enquiry [ENQ]                           */
194    NPC7,        #     6      acknowledge [ACK]                       */
195    NPC7,        #     7      bell [BEL]                              */
196    NPC7,        #     8      backspace [BS]                          */
197    NPC7,        #     9      horizontal tab [HT]                     */
198    10,          #    10      line feed [LF]                          */
199    NPC7,        #    11      vertical tab [VT]                       */
200    10 + 256,    #    12      form feed [FF]                          */
201    13,          #    13      carriage return [CR]                    */
202    NPC7,        #    14      shift out [SO]                          */
203    NPC7,        #    15      shift in [SI]                           */
204    NPC7,        #    16      data link escape [DLE]                  */
205    NPC7,        #    17      device control 1 [DC1]                  */
206    NPC7,        #    18      device control 2 [DC2]                  */
207    NPC7,        #    19      device control 3 [DC3]                  */
208    NPC7,        #    20      device control 4 [DC4]                  */
209    NPC7,        #    21      negative acknowledge [NAK]              */
210    NPC7,        #    22      synchronous idle [SYN]                  */
211    NPC7,        #    23      end of trans. block [ETB]               */
212    NPC7,        #    24      cancel [CAN]                            */
213    NPC7,        #    25      end of medium [EM]                      */
214    NPC7,        #    26      substitute [SUB]                        */
215    NPC7,        #    27      escape [ESC]                            */
216    NPC7,        #    28      file separator [FS]                     */
217    NPC7,        #    29      group separator [GS]                    */
218    NPC7,        #    30      record separator [RS]                   */
219    NPC7,        #    31      unit separator [US]                     */
220    32,          #    32      space                                   */
221    33,          #    33    ! exclamation mark                        */
222    34,          #    34    " double quotation mark                   */
223    35,          #    35    # number sign                             */
224    2,           #    36    $ dollar sign                             */
225    37,          #    37    % percent sign                            */
226    38,          #    38    & ampersand                               */
227    39,          #    39    ' apostrophe                              */
228    40,          #    40    ( left parenthesis                        */
229    41,          #    41    ) right parenthesis                       */
230    42,          #    42    * asterisk                                */
231    43,          #    43    + plus sign                               */
232    44,          #    44    , comma                                   */
233    45,          #    45    - hyphen                                  */
234    46,          #    46    . period                                  */
235    47,          #    47    / slash,                                  */
236    48,          #    48    0 digit 0                                 */
237    49,          #    49    1 digit 1                                 */
238    50,          #    50    2 digit 2                                 */
239    51,          #    51    3 digit 3                                 */
240    52,          #    52    4 digit 4                                 */
241    53,          #    53    5 digit 5                                 */
242    54,          #    54    6 digit 6                                 */
243    55,          #    55    7 digit 7                                 */
244    56,          #    56    8 digit 8                                 */
245    57,          #    57    9 digit 9                                 */
246    58,          #    58    : colon                                   */
247    59,          #    59    ; semicolon                               */
248    60,          #    60    < less-than sign                          */
249    61,          #    61    = equal sign                              */
250    62,          #    62    > greater-than sign                       */
251    63,          #    63    ? question mark                           */
252    0,           #    64    @ commercial at sign                      */
253    65,          #    65    A uppercase A                             */
254    66,          #    66    B uppercase B                             */
255    67,          #    67    C uppercase C                             */
256    68,          #    68    D uppercase D                             */
257    69,          #    69    E uppercase E                             */
258    70,          #    70    F uppercase F                             */
259    71,          #    71    G uppercase G                             */
260    72,          #    72    H uppercase H                             */
261    73,          #    73    I uppercase I                             */
262    74,          #    74    J uppercase J                             */
263    75,          #    75    K uppercase K                             */
264    76,          #    76    L uppercase L                             */
265    77,          #    77    M uppercase M                             */
266    78,          #    78    N uppercase N                             */
267    79,          #    79    O uppercase O                             */
268    80,          #    80    P uppercase P                             */
269    81,          #    81    Q uppercase Q                             */
270    82,          #    82    R uppercase R                             */
271    83,          #    83    S uppercase S                             */
272    84,          #    84    T uppercase T                             */
273    85,          #    85    U uppercase U                             */
274    86,          #    86    V uppercase V                             */
275    87,          #    87    W uppercase W                             */
276    88,          #    88    X uppercase X                             */
277    89,          #    89    Y uppercase Y                             */
278    90,          #    90    Z uppercase Z                             */
279    60 + 256,    #    91    [ left square bracket                     */
280    47 + 256,    #    92    \ backslash                               */
281    62 + 256,    #    93    ] right square bracket                    */
282    20 + 256,    #    94    ^ circumflex accent                       */
283    17,          #    95    _ underscore                              */
284    -39,         #    96    ` back apostrophe                         */
285    97,          #    97    a lowercase a                             */
286    98,          #    98    b lowercase b                             */
287    99,          #    99    c lowercase c                             */
288    100,         #   100    d lowercase d                             */
289    101,         #   101    e lowercase e                             */
290    102,         #   102    f lowercase f                             */
291    103,         #   103    g lowercase g                             */
292    104,         #   104    h lowercase h                             */
293    105,         #   105    i lowercase i                             */
294    106,         #   106    j lowercase j                             */
295    107,         #   107    k lowercase k                             */
296    108,         #   108    l lowercase l                             */
297    109,         #   109    m lowercase m                             */
298    110,         #   110    n lowercase n                             */
299    111,         #   111    o lowercase o                             */
300    112,         #   112    p lowercase p                             */
301    113,         #   113    q lowercase q                             */
302    114,         #   114    r lowercase r                             */
303    115,         #   115    s lowercase s                             */
304    116,         #   116    t lowercase t                             */
305    117,         #   117    u lowercase u                             */
306    118,         #   118    v lowercase v                             */
307    119,         #   119    w lowercase w                             */
308    120,         #   120    x lowercase x                             */
309    121,         #   121    y lowercase y                             */
310    122,         #   122    z lowercase z                             */
311    40 + 256,    #   123    { left brace                              */
312    64 + 256,    #   124    | vertical bar                            */
313    41 + 256,    #   125    } right brace                             */
314    61 + 256,    #   126    ~ tilde accent                            */
315    NPC7,        #   127      delete [DEL]                            */
316    NPC7,        #   128                                              */
317    NPC7,        #   129                                              */
318    -39,         #   130      low left rising single quote            */
319    -102,        #   131      lowercase italic f                      */
320    -34,         #   132      low left rising double quote            */
321    NPC7,        #   133      low horizontal ellipsis                 */
322    NPC7,        #   134      dagger mark                             */
323    NPC7,        #   135      double dagger mark                      */
324    NPC7,        #   136      letter modifying circumflex             */
325    NPC7,        #   137      per thousand (mille) sign               */
326    -83,         #   138      uppercase S caron or hacek              */
327    -39,         #   139      left single angle quote mark            */
328    -214,        #   140      uppercase OE ligature                   */
329    NPC7,        #   141                                              */
330    NPC7,        #   142                                              */
331    NPC7,        #   143                                              */
332    NPC7,        #   144                                              */
333    -39,         #   145      left single quotation mark              */
334    -39,         #   146      right single quote mark                 */
335    -34,         #   147      left double quotation mark              */
336    -34,         #   148      right double quote mark                 */
337    -42,         #   149      round filled bullet                     */
338    -45,         #   150      en dash                                 */
339    -45,         #   151      em dash                                 */
340    -39,         #   152      small spacing tilde accent              */
341    NPC7,        #   153      trademark sign                          */
342    -115,        #   154      lowercase s caron or hacek              */
343    -39,         #   155      right single angle quote mark           */
344    -111,        #   156      lowercase oe ligature                   */
345    NPC7,        #   157                                              */
346    NPC7,        #   158                                              */
347    -89,         #   159      uppercase Y dieresis or umlaut          */
348    -32,         #   160    � non-breaking space                      */
349    64,          #   161    � inverted exclamation mark               */
350    -99,         #   162    � cent sign                               */
351    1,           #   163    � pound sterling sign                     */
352    36,          #   164    � general currency sign                   */
353    3,           #   165    � yen sign                                */
354    -33,         #   166    � broken vertical bar                     */
355    95,          #   167    � section sign                            */
356    -34,         #   168    � spacing dieresis or umlaut              */
357    NPC7,        #   169    � copyright sign                          */
358    NPC7,        #   170    � feminine ordinal indicator              */
359    -60,         #   171    � left (double) angle quote               */
360    NPC7,        #   172    � logical not sign                        */
361    -45,         #   173    � soft hyphen                             */
362    NPC7,        #   174    � registered trademark sign               */
363    NPC7,        #   175    � spacing macron (long) accent            */
364    NPC7,        #   176    � degree sign                             */
365    NPC7,        #   177    � plus-or-minus sign                      */
366    -50,         #   178    � superscript 2                           */
367    -51,         #   179    � superscript 3                           */
368    -39,         #   180    � spacing acute accent                    */
369    -117,        #   181    � micro sign                              */
370    NPC7,        #   182    � paragraph sign, pilcrow sign            */
371    NPC7,        #   183    � middle dot, centered dot                */
372    NPC7,        #   184    � spacing cedilla                         */
373    -49,         #   185    � superscript 1                           */
374    NPC7,        #   186    � masculine ordinal indicator             */
375    -62,         #   187    � right (double) angle quote (guillemet)  */
376    NPC7,        #   188    � fraction 1/4                            */
377    NPC7,        #   189    � fraction 1/2                            */
378    NPC7,        #   190    � fraction 3/4                            */
379    96,          #   191    � inverted question mark                  */
380    -65,         #   192    � uppercase A grave                       */
381    -65,         #   193    � uppercase A acute                       */
382    -65,         #   194    � uppercase A circumflex                  */
383    -65,         #   195    � uppercase A tilde                       */
384    91,          #   196    � uppercase A dieresis or umlaut          */
385    14,          #   197    � uppercase A ring                        */
386    28,          #   198    � uppercase AE ligature                   */
387    9,           #   199    � uppercase C cedilla                     */
388    -31,         #   200    � uppercase E grave                       */
389    31,          #   201    � uppercase E acute                       */
390    -31,         #   202    � uppercase E circumflex                  */
391    -31,         #   203    � uppercase E dieresis or umlaut          */
392    -73,         #   204    � uppercase I grave                       */
393    -73,         #   205    � uppercase I acute                       */
394    -73,         #   206    � uppercase I circumflex                  */
395    -73,         #   207    � uppercase I dieresis or umlaut          */
396    -68,         #   208    � uppercase ETH                           */
397    93,          #   209    � uppercase N tilde                       */
398    -79,         #   210    � uppercase O grave                       */
399    -79,         #   211    � uppercase O acute                       */
400    -79,         #   212    � uppercase O circumflex                  */
401    -79,         #   213    � uppercase O tilde                       */
402    92,          #   214    � uppercase O dieresis or umlaut          */
403    -42,         #   215    � multiplication sign                     */
404    11,          #   216    � uppercase O slash                       */
405    -85,         #   217    � uppercase U grave                       */
406    -85,         #   218    � uppercase U acute                       */
407    -85,         #   219    � uppercase U circumflex                  */
408    94,          #   220    � uppercase U dieresis or umlaut          */
409    -89,         #   221    � uppercase Y acute                       */
410    NPC7,        #   222    � uppercase THORN                         */
411    30,          #   223    � lowercase sharp s, sz ligature          */
412    127,         #   224    � lowercase a grave                       */
413    -97,         #   225    � lowercase a acute                       */
414    -97,         #   226    � lowercase a circumflex                  */
415    -97,         #   227    � lowercase a tilde                       */
416    123,         #   228    � lowercase a dieresis or umlaut          */
417    15,          #   229    � lowercase a ring                        */
418    29,          #   230    � lowercase ae ligature                   */
419    -9,          #   231    � lowercase c cedilla                     */
420    4,           #   232    � lowercase e grave                       */
421    5,           #   233    � lowercase e acute                       */
422    -101,        #   234    � lowercase e circumflex                  */
423    -101,        #   235    � lowercase e dieresis or umlaut          */
424    7,           #   236    � lowercase i grave                       */
425    -7,          #   237    � lowercase i acute                       */
426    -105,        #   238    � lowercase i circumflex                  */
427    -105,        #   239    � lowercase i dieresis or umlaut          */
428    NPC7,        #   240    � lowercase eth                           */
429    125,         #   241    � lowercase n tilde                       */
430    8,           #   242    � lowercase o grave                       */
431    -111,        #   243    � lowercase o acute                       */
432    -111,        #   244    � lowercase o circumflex                  */
433    -111,        #   245    � lowercase o tilde                       */
434    124,         #   246    � lowercase o dieresis or umlaut          */
435    -47,         #   247    � division sign                           */
436    12,          #   248    � lowercase o slash                       */
437    6,           #   249    � lowercase u grave                       */
438    -117,        #   250    � lowercase u acute                       */
439    -117,        #   251    � lowercase u circumflex                  */
440    126,         #   252    � lowercase u dieresis or umlaut          */
441    -121,        #   253    � lowercase y acute                       */
442    NPC7,        #   254    � lowercase thorn                         */
443    -121         #   255    � lowercase y dieresis or umlaut          */
444);
445
446sub iso8859_to_gsm0338 {
447    my $ascii = shift;
448    return '' if !defined $ascii || $ascii eq '';
449
450    my $gsm = '';
451    my $n   = 0;
452    for (; $n < length($ascii); $n++) {
453        my $ch_ascii = ord(substr($ascii, $n, 1));
454        my $ch_gsm = $Device::Gsm::Charset::ISO8859_TO_GSM0338[$ch_ascii];
455
456        # Is this a "replaced" char?
457        if ($ch_gsm <= 0xFF) {
458            $ch_gsm = abs($ch_gsm);
459        }
460        else {
461
462            # Prepend an escape char for extended char
463            $gsm .= chr(ESCAPE);
464
465            # Encode extended char
466            $ch_gsm -= 256;
467        }
468
469        #warn('char ['.$ch_ascii.'] => ['.$ch_gsm.']');
470        $gsm .= chr($ch_gsm);
471    }
472    return $gsm;
473}
474
475sub gsm0338_to_iso8859 {
476    my $gsm = shift;
477    return '' if !defined $gsm || $gsm eq '';
478
479    my $ascii = '';
480    my $n     = 0;
481
482    for (; $n < length($gsm); $n++) {
483
484        my $c = ord(substr($gsm, $n, 1));
485
486        # Extended charset ?
487        if ($c == ESCAPE) {    # "escape extended mode"
488            $n++;
489            $c = ord(substr($gsm, $n, 1));
490            if ($c == 0x0A) {
491                $ascii .= chr(12);
492            }
493            elsif ($c == 0x14) {
494                $ascii .= '^';
495            }
496            elsif ($c == 0x28) {
497                $ascii .= '{';
498            }
499            elsif ($c == 0x29) {
500                $ascii .= '}';
501            }
502            elsif ($c == 0x2F) {
503                $ascii .= '\\';
504            }
505            elsif ($c == 0x3C) {
506                $ascii .= '[';
507            }
508            elsif ($c == 0x3D) {
509                $ascii .= '~';
510            }
511            elsif ($c == 0x3E) {
512                $ascii .= ']';
513            }
514            elsif ($c == 0x40) {
515                $ascii .= '|';
516            }
517            elsif ($c == 0x65) {    # 'e'
518                $ascii .= chr(164)
519                    ;    # iso_8859_15 EURO SIGN or iso_8859_1 CURRENCY_SIGN
520            }
521            else {
522                $ascii .= chr(NPC8);    # Non printable
523            }
524
525        }
526        else {
527
528            # Standard GSM 3.38 encoding
529            $ascii .= chr($Device::Gsm::Charset::GSM0338_TO_ISO8859[$c]);
530        }
531
532        #warn('gsm char ['.$c.'] converted to ascii ['.ord(substr($ascii,-1)).']');
533    }
534
535    return $ascii;
536}
537
538sub gsm0338_length {
539    my $ascii          = shift;
540    my $gsm0338_length = 0;
541    my $n              = 0;
542    for (; $n < length($ascii); $n++) {
543        my $ch_ascii = ord(substr($ascii, $n, 1));
544        my $ch_gsm = $Device::Gsm::Charset::ISO8859_TO_GSM0338[$ch_ascii];
545
546        # Is this a "replaced" char?
547        if ($ch_gsm <= 0xFF) {
548            $gsm0338_length++;
549        }
550        else {
551            $gsm0338_length += 2;
552        }
553    }
554    return $gsm0338_length;
555}
556
557sub gsm0338_split {
558    my $ascii = shift;
559    return '' if !defined $ascii || $ascii eq '';
560    my @parts;
561    my $part;
562    my $chars_count  = 0;
563    my $ascii_length = length($ascii);
564    while ($ascii_length) {
565        my $ch_ascii = substr($ascii, 0, 1);
566        my $ch_gsm
567            = $Device::Gsm::Charset::ISO8859_TO_GSM0338[ ord($ch_ascii) ];
568        if ($chars_count < 153 and $ch_gsm <= 0xFF) {
569            $part .= $ch_ascii;
570            $chars_count++;
571            $ascii = substr($ascii, 1, $ascii_length--);
572        }
573        elsif ($chars_count < 152 and $ch_gsm > 0xFF) {
574            $part .= $ch_ascii;
575            $chars_count += 2;
576            $ascii = substr($ascii, 1, $ascii_length--);
577        }
578        else {
579            push(@parts, $part);
580            $part        = '';
581            $chars_count = 0;
582        }
583    }
584    push(@parts, $part);
585    return (@parts);
586}
5871;
588
589__END__
590
591