ruby_ucp 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. data/CHANGELOG +42 -0
  2. data/LICENSE +505 -0
  3. data/README +10 -0
  4. data/Rakefile +118 -0
  5. data/Rakefile.orig +45 -0
  6. data/VERSION +1 -0
  7. data/lib/ruby_ucp.rb +42 -0
  8. data/lib/samples/main.rb +182 -0
  9. data/lib/ucp/base.rb +24 -0
  10. data/lib/ucp/pdu/base.rb +22 -0
  11. data/lib/ucp/pdu/ucp01.rb +37 -0
  12. data/lib/ucp/pdu/ucp01_operation.rb +61 -0
  13. data/lib/ucp/pdu/ucp01_result.rb +60 -0
  14. data/lib/ucp/pdu/ucp30.rb +28 -0
  15. data/lib/ucp/pdu/ucp30_operation.rb +59 -0
  16. data/lib/ucp/pdu/ucp30_result.rb +63 -0
  17. data/lib/ucp/pdu/ucp31.rb +29 -0
  18. data/lib/ucp/pdu/ucp31_operation.rb +50 -0
  19. data/lib/ucp/pdu/ucp31_result.rb +61 -0
  20. data/lib/ucp/pdu/ucp51_operation.rb +167 -0
  21. data/lib/ucp/pdu/ucp51_result.rb +64 -0
  22. data/lib/ucp/pdu/ucp52_operation.rb +31 -0
  23. data/lib/ucp/pdu/ucp52_result.rb +31 -0
  24. data/lib/ucp/pdu/ucp53_operation.rb +31 -0
  25. data/lib/ucp/pdu/ucp53_result.rb +31 -0
  26. data/lib/ucp/pdu/ucp54_operation.rb +31 -0
  27. data/lib/ucp/pdu/ucp54_result.rb +31 -0
  28. data/lib/ucp/pdu/ucp55_operation.rb +31 -0
  29. data/lib/ucp/pdu/ucp55_result.rb +31 -0
  30. data/lib/ucp/pdu/ucp56_operation.rb +31 -0
  31. data/lib/ucp/pdu/ucp56_result.rb +31 -0
  32. data/lib/ucp/pdu/ucp57_operation.rb +31 -0
  33. data/lib/ucp/pdu/ucp57_result.rb +31 -0
  34. data/lib/ucp/pdu/ucp58_operation.rb +31 -0
  35. data/lib/ucp/pdu/ucp58_result.rb +31 -0
  36. data/lib/ucp/pdu/ucp5x.rb +40 -0
  37. data/lib/ucp/pdu/ucp60.rb +30 -0
  38. data/lib/ucp/pdu/ucp60_operation.rb +58 -0
  39. data/lib/ucp/pdu/ucp60_result.rb +60 -0
  40. data/lib/ucp/pdu/ucp61.rb +31 -0
  41. data/lib/ucp/pdu/ucp61_operation.rb +49 -0
  42. data/lib/ucp/pdu/ucp61_result.rb +60 -0
  43. data/lib/ucp/pdu/ucp_operation.rb +27 -0
  44. data/lib/ucp/pdu/ucp_result.rb +26 -0
  45. data/lib/ucp/pdu/ucpmessage.rb +125 -0
  46. data/lib/ucp/util/base.rb +22 -0
  47. data/lib/ucp/util/gsm_packed_msg.rb +50 -0
  48. data/lib/ucp/util/packed_msg.rb +34 -0
  49. data/lib/ucp/util/sms_request.rb +48 -0
  50. data/lib/ucp/util/ucp.rb +885 -0
  51. data/lib/ucp/util/ucp_client.rb +207 -0
  52. data/lib/ucp/util/ucp_server.rb +122 -0
  53. data/lib/ucp/util/ucs2_packed_msg.rb +29 -0
  54. metadata +120 -0
@@ -0,0 +1,885 @@
1
+ =begin
2
+ Ruby library implementation of EMI/UCP protocol v4.6 for SMS
3
+ Copyright (C) 2011, Sergio Freire <sergio.freire@gmail.com>
4
+
5
+ This library is free software; you can redistribute it and/or
6
+ modify it under the terms of the GNU Lesser General Public
7
+ License as published by the Free Software Foundation; either
8
+ version 2.1 of the License, or (at your option) any later version.
9
+
10
+ This library is distributed in the hope that it will be useful,
11
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
+ Lesser General Public License for more details.
14
+
15
+ You should have received a copy of the GNU Lesser General Public
16
+ License along with this library; if not, write to the Free Software
17
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18
+ =end
19
+
20
+
21
+ require "iconv"
22
+
23
+ $KCODE = 'UTF8'
24
+ require 'jcode'
25
+
26
+ include Ucp::Pdu
27
+
28
+ class Ucp::Util::UCP
29
+
30
+ @gsmtable={}
31
+ @asciitable={}
32
+ @extensiontable={}
33
+ @extensiontable_rev={}
34
+
35
+ :private
36
+ def self.add_char(value,char)
37
+ @gsmtable[char]=value
38
+ @asciitable[value]=char
39
+ end
40
+
41
+ :private
42
+ def self.add_extchar(value,char)
43
+ @extensiontable[char]=value
44
+ @extensiontable_rev[value]=char
45
+ end
46
+
47
+ def self.initialize_ascii2ira
48
+
49
+ ('A'..'Z').each { |c|
50
+ add_char(c[0],c)
51
+ }
52
+ ('a'..'z').each { |c|
53
+ #@gsmtable[c]=c[0]
54
+ #@asciitable[c[0]]=c
55
+ add_char(c[0],c)
56
+ }
57
+ ('0'..'9').each { |c|
58
+ add_char(c[0],c)
59
+ }
60
+
61
+
62
+ add_char(0x00,"@")
63
+ add_char(0x01,"£")
64
+ add_char(0x02,"$")
65
+ #add_char(0x03," ")
66
+ add_char(0x04,"è")
67
+ add_char(0x05,"é")
68
+ add_char(0x06,"ù")
69
+ add_char(0x07,"ì")
70
+ add_char(0x08,"ò")
71
+ add_char(0x09,"Ç")
72
+ add_char(0x0A,"\n")
73
+ #add_char(0x0B," ")
74
+ #add_char(0x0C," ")
75
+ add_char(0x0D,"\r")
76
+ #add_char(0x0E,"A")
77
+ #add_char(0x0F,"a")
78
+
79
+ add_char(0x1F,"É")
80
+
81
+
82
+
83
+ add_char(0x20," ")
84
+ add_char(0x21,"!")
85
+ add_char(0x22,'"')
86
+ add_char(0x23,"#")
87
+ #add_char(0x24," ")
88
+ add_char(0x25,"%")
89
+ add_char(0x26,"&")
90
+ add_char(0x27,"'")
91
+ add_char(0x28,"(")
92
+ add_char(0x29,")")
93
+ add_char(0x2A,"*")
94
+ add_char(0x2B,"+")
95
+ add_char(0x2C,",")
96
+ add_char(0x2D,"-")
97
+ add_char(0x2E,".")
98
+ add_char(0x2F,"/")
99
+
100
+ add_char(0x3A,":")
101
+ add_char(0x3B,";")
102
+ add_char(0x3C,"<")
103
+ add_char(0x3D,"=")
104
+ add_char(0x3E,">")
105
+ add_char(0x3F,"?")
106
+
107
+
108
+
109
+ #@extensiontable["€"]=0x65
110
+ #@extensiontable_rev[0x65]="€"
111
+ add_extchar(0x65,"€")
112
+ add_extchar(0x14,"^")
113
+ add_extchar(0x28,"{")
114
+ add_extchar(0x29,"}")
115
+ add_extchar(0x2F,"\\")
116
+ add_extchar(0x3C,"[")
117
+ add_extchar(0x3D,"~")
118
+ add_extchar(0x3E,"]")
119
+ add_extchar(0x40,"|")
120
+
121
+
122
+
123
+ end
124
+
125
+ def self.pack7bits(str)
126
+ #UCP.initialize_ascii2ira
127
+
128
+ s=""
129
+ str.each_char { |c|
130
+
131
+ ext=""
132
+ gsmchar=@gsmtable[c]
133
+
134
+ if gsmchar.nil?
135
+ if @extensiontable.has_key?(c)
136
+ ext="0011011" # 1B
137
+ gsmchar=@extensiontable[c]
138
+ else
139
+ gsmchar=@gsmtable[" "]
140
+ end
141
+ end
142
+
143
+ #gsmchar=c[0]
144
+ #puts "#{c} : #{gsmchar} xxx"
145
+ #gsmchar=@gsmtable[" "] if gsmchar.nil?
146
+
147
+ tmp= gsmchar.to_s(2)
148
+
149
+ remainder=tmp.length%7
150
+ if remainder!=0
151
+ nfillbits=7-remainder
152
+ tmp="0"*nfillbits+tmp
153
+ end
154
+
155
+ s=tmp+ext+s
156
+
157
+ }
158
+
159
+ remainder=s.length%8
160
+ if remainder!=0
161
+ nfillbits=8-remainder
162
+ s="0"*nfillbits+s
163
+ end
164
+
165
+ #puts "S: #{s}"
166
+
167
+ i=s.length-8
168
+ hexstr=""
169
+ while i>=0
170
+ c=s[i,8]
171
+
172
+ tmp=c.to_i(2).to_s(16).upcase
173
+ if tmp.length==1
174
+ tmp="0"+tmp
175
+ end
176
+ # puts tmp
177
+ hexstr+=tmp
178
+ i-=8
179
+ end
180
+
181
+
182
+
183
+ return hexstr
184
+ end
185
+
186
+
187
+ def self.pack7bits2(str,max_bytes)
188
+
189
+ tainted=false
190
+ s=""
191
+ idx=0
192
+ str.each_char { |c|
193
+
194
+ ext=""
195
+ gsmchar=@gsmtable[c]
196
+
197
+ if gsmchar.nil?
198
+ if @extensiontable.has_key?(c)
199
+ ext="0011011" # 1B
200
+ gsmchar=@extensiontable[c]
201
+ else
202
+ gsmchar=@gsmtable[" "]
203
+ tainted=true
204
+ end
205
+ end
206
+
207
+ #gsmchar=c[0]
208
+ #puts "#{c} : #{gsmchar} xxx"
209
+ #gsmchar=@gsmtable[" "] if gsmchar.nil?
210
+
211
+ tmp= gsmchar.to_s(2)
212
+
213
+ remainder=tmp.length%7
214
+ if remainder!=0
215
+ nfillbits=7-remainder
216
+ tmp="0"*nfillbits+tmp
217
+ end
218
+
219
+ # if adding this character exceeds the max allowed nr of bytes, break
220
+ if ((tmp+ext+s).length*1.0/8).ceil>max_bytes
221
+ break
222
+ end
223
+
224
+ s=tmp+ext+s
225
+
226
+ # if reached the max allowed nr of bytes, break
227
+ if (s.length*1.0/8).ceil==max_bytes
228
+ idx+=1
229
+ break
230
+ end
231
+
232
+ idx+=1
233
+ }
234
+
235
+
236
+ required_septets=s.length/7
237
+ remainder=s.length%8
238
+ if remainder!=0
239
+ nfillbits=8-remainder
240
+ s="0"*nfillbits+s
241
+ end
242
+
243
+ #puts "S: #{s}"
244
+
245
+ i=s.length-8
246
+ hexstr=""
247
+ while i>=0
248
+ c=s[i,8]
249
+
250
+ tmp=c.to_i(2).to_s(16).upcase
251
+ if tmp.length==1
252
+ tmp="0"+tmp
253
+ end
254
+ # puts tmp
255
+ hexstr+=tmp
256
+ i-=8
257
+ end
258
+
259
+
260
+ return GsmPackedMsg.new(hexstr,str[0,idx],idx,required_septets,tainted)
261
+ end
262
+
263
+ # @deprecated remove because unecessary
264
+ def self.multi_pack7bits(str,max_bytes)
265
+ msgparts=[]
266
+ idx=0
267
+ while true
268
+ packedmsg=UCP.pack7bits2(str[idx..-1],max_bytes)
269
+ msgparts<<packedmsg
270
+ if idx+packedmsg.chars<str.length
271
+ idx+=packedmsg.chars
272
+ else
273
+ break
274
+ end
275
+ end
276
+ return msgparts
277
+ end
278
+
279
+
280
+ # convert standard string to IRA encoded hexstring
281
+ def self.ascii2ira(str,max_bytes=nil)
282
+
283
+ tainted=false # true if not able to convert a character
284
+ s=""
285
+ idx=0
286
+ str.each_char { |c|
287
+ gsmchar=@gsmtable[c]
288
+
289
+ ext=""
290
+ if gsmchar.nil?
291
+ if @extensiontable.has_key?(c)
292
+ ext="1B"
293
+ gsmchar=@extensiontable[c]
294
+ else
295
+ gsmchar=@gsmtable[" "]
296
+ tainted=true
297
+ end
298
+ end
299
+
300
+
301
+ tmp=int2hex(gsmchar)
302
+
303
+
304
+ if !max_bytes.nil?
305
+ # if adding this character exceeds the max allowed nr of bytes, break
306
+ if ((tmp+ext+s).length*7.0/16).ceil>max_bytes
307
+ break
308
+ end
309
+ end
310
+
311
+ s+=ext+tmp
312
+ idx+=(ext+tmp).length/2
313
+
314
+ # if reached the max allowed nr of bytes, break
315
+ # if (s.length*7.0/16).floor==max_bytes
316
+ # break
317
+ # end
318
+
319
+ }
320
+
321
+ required_septets=s.length/2
322
+ #puts "idx: #{idx}; req_sep: #{required_septets}"
323
+ return GsmPackedMsg.new(s,UCP.utf8_substr(str,0,idx-1),idx,required_septets,tainted)
324
+ end
325
+
326
+
327
+ def self.utf8_substr(str,idxs,idxe=nil)
328
+ s=""
329
+ i=0
330
+ idxe=str.jlength-1 if idxe.nil?
331
+ str.each_char{ |c|
332
+ s+=c if i>=idxs and i<=idxe
333
+ i+=1
334
+ }
335
+ return s
336
+ end
337
+
338
+ def self.multi_ascii2ira(str,max_bytes)
339
+ msgparts=[]
340
+ idx=0
341
+
342
+ if str.jlength<=160
343
+ packedmsg=UCP.ascii2ira(UCP.utf8_substr(str,idx),140)
344
+ #puts "pckd_chars: #{packedmsg.chars}; strlen: #{str.jlength}"
345
+ if packedmsg.chars==str.jlength
346
+ msgparts<<packedmsg
347
+ return msgparts
348
+ end
349
+ end
350
+
351
+ while true
352
+ #packedmsg=UCP.ascii2ira(str[idx..-1],max_bytes)
353
+ #puts "bla: #{UCP.utf8_substr(str,idx)}"
354
+ packedmsg=UCP.ascii2ira(UCP.utf8_substr(str,idx),max_bytes)
355
+ msgparts<<packedmsg
356
+ #break
357
+ #puts "idx: #{idx}; pckd_chars: #{packedmsg.chars}; strlen: #{str.jlength}"
358
+
359
+ #puts "sL: #{UCP.utf8_substr(str,idx,idx+packedmsg.chars- 1)} ; #{str[0,idx+packedmsg.chars].length}#"
360
+
361
+ #if idx+packedmsg.chars<str.length
362
+ if idx+packedmsg.chars<str.jlength
363
+ idx+=packedmsg.chars
364
+ else
365
+ break
366
+ end
367
+ end
368
+ return msgparts
369
+ end
370
+
371
+
372
+ def self.str2ucs2(str,max_bytes=nil)
373
+ hexstr=""
374
+ str=Iconv.iconv("utf-16be", "utf-8", str).first
375
+ i=0
376
+ str.each_byte{ |c|
377
+ hexstr+=UCP.int2hex(c)
378
+ i+=1
379
+ if (!max_bytes.nil?) && (i == max_bytes)
380
+ break
381
+ end
382
+ }
383
+
384
+ return Ucs2PackedMsg.new(hexstr,UCP.utf8_substr(str,0,i-1),i/2,i)
385
+ end
386
+
387
+ def self.multi_ucs2(str,max_bytes)
388
+ msgparts=[]
389
+ idx=0
390
+
391
+ if str.jlength<=70
392
+ packedmsg=UCP.str2ucs2(str,140)
393
+ #puts "pckd_chars: #{packedmsg.chars}; strlen: #{str.jlength}"
394
+ if packedmsg.chars==str.jlength
395
+ msgparts<<packedmsg
396
+ return msgparts
397
+ end
398
+ end
399
+
400
+ while true
401
+
402
+ #puts "bla: #{UCP.utf8_substr(str,idx)}"
403
+ packedmsg=UCP.str2ucs2(UCP.utf8_substr(str,idx),max_bytes)
404
+ msgparts<<packedmsg
405
+ #break
406
+ #puts "idx: #{idx}; pckd_chars: #{packedmsg.chars}; strlen: #{str.jlength}"
407
+ #puts "sL: #{UCP.utf8_substr(str,idx,idx+packedmsg.chars- 1)} ; #{str[0,idx+packedmsg.chars].length}#"
408
+
409
+ if idx+packedmsg.chars<str.jlength
410
+ idx+=packedmsg.chars
411
+ else
412
+ break
413
+ end
414
+ end
415
+ return msgparts
416
+ end
417
+
418
+
419
+
420
+ def self.make_multi_ucps(originator,recipient,message,mr=0)
421
+ ucps=[]
422
+
423
+ gsm7bit_encodable=false
424
+
425
+ if gsm7bit_encodable
426
+ gsmparts= UCP.multi_ascii2ira(message,134)
427
+ else
428
+ gsmparts= UCP.multi_ucs2(message,134)
429
+ end
430
+
431
+
432
+ part_nr=1
433
+ gsmparts.each { |gsmpart|
434
+ ucp=Ucp51Operation.new
435
+ ucp.basic_submit(originator,recipient,nil)
436
+
437
+ if gsmparts.length>1
438
+ # concatenated xser
439
+ ucp.add_xser("01","050003"+UCP.int2hex(mr)+UCP.int2hex(gsmparts.length)+UCP.int2hex(part_nr))
440
+ end
441
+
442
+ if gsm7bit_encodable
443
+ ucp.set_fields({:mt=>3, :msg=>gsmpart.encoded})
444
+ # DCS xser
445
+ ucp.add_xser("02","01")
446
+ else
447
+ ucp.set_fields({:msg=>gsmpart.encoded,:mt=>4,:nb=>gsmpart.encoded.length*4})
448
+ # DCS xser
449
+ ucp.add_xser("02","08")
450
+ end
451
+
452
+ #ucp.trn=UCP.int2hex(initial_trn)
453
+ #initial_trn+=1
454
+
455
+ #puts "part: #{ucp.to_s}"
456
+ ucps<<ucp
457
+ part_nr+=1
458
+ }
459
+ return ucps
460
+ end
461
+
462
+
463
+
464
+ def self.packucs2(str)
465
+ hexstr=""
466
+ s= Iconv.iconv("ucs-2be", "utf-8", str).first
467
+ s.each_char{ |c|
468
+
469
+ tmp=c[0].to_s(16).upcase
470
+ if tmp.length==1
471
+ tmp="0"+tmp
472
+ end
473
+
474
+ hexstr+=tmp
475
+
476
+ }
477
+ #puts s
478
+ return hexstr
479
+ end
480
+
481
+ def self.packoadc(oa)
482
+ packedoa=UCP.pack7bits(oa)
483
+
484
+ # esta conta nao esta correcta... por causa das extensoes...
485
+ #useful_nibbles=packedoa.length
486
+ useful_nibbles=(oa.length*7.0/4).ceil
487
+
488
+ tmp=useful_nibbles.to_s(16).upcase
489
+ if tmp.length==1
490
+ tmp="0"+tmp
491
+ end
492
+
493
+ return tmp+packedoa
494
+ end
495
+
496
+ def self.hextobin(hstr)
497
+ bstr=""
498
+ i=0
499
+ while i<hstr.length
500
+ tmp=hstr[i,2].to_i(16).to_s(2)
501
+
502
+ nfillbits=8-tmp.length
503
+ if nfillbits!=0
504
+ tmp="0"*nfillbits+tmp
505
+ end
506
+
507
+ bstr+=tmp
508
+ i+=2
509
+ end
510
+ return bstr
511
+ end
512
+
513
+
514
+ def self.hextobin_reversed(hstr)
515
+ bstr=""
516
+ i=0
517
+ while i<hstr.length
518
+ tmp=hstr[i,2].to_i(16).to_s(2)
519
+
520
+ nfillbits=8-tmp.length
521
+ if nfillbits!=0
522
+ tmp="0"*nfillbits+tmp
523
+ end
524
+
525
+ bstr=tmp+bstr
526
+ i+=2
527
+ end
528
+ return bstr
529
+ end
530
+
531
+
532
+ def self.decode7bitgsm(str)
533
+
534
+ # retirar isto!!
535
+ #initialize_ascii2ira
536
+
537
+ unencoded=""
538
+ #puts "#{str}"
539
+ bstr=UCP.hextobin_reversed(str)
540
+ #puts "#{bstr}"
541
+ # 110 1111 110 1100 110 0001
542
+ # 1000011 1011101 0110111 000
543
+
544
+ i=bstr.length-7
545
+ while i>=0
546
+ value=bstr[i,7].to_i(2)
547
+ if value==0x1B
548
+ i-=7
549
+ value=@extensiontable_rev[bstr[i,7].to_i(2)]
550
+ value=" " if value.nil?
551
+ unencoded+=value
552
+ else
553
+ val=@asciitable[value]
554
+ #puts "value: #{value} ; val: #{val}"
555
+ val=" " if val.nil?
556
+ unencoded+=val
557
+ #unencoded+=value.chr
558
+ end
559
+
560
+
561
+
562
+
563
+ i-=7
564
+ end
565
+
566
+
567
+ # i=0
568
+ # while i<str.length
569
+ # hexv=str[i,2]
570
+ # if "1B".eql?(hexv)
571
+ # i+=2
572
+ # hexv=str[i,2]
573
+ # end
574
+ #
575
+ # unencoded+=hexv.to_i(16).chr
576
+ #
577
+ # i+=2
578
+ # end
579
+
580
+
581
+ return unencoded
582
+ end
583
+
584
+
585
+
586
+ def self.decode_ira(str)
587
+ unencoded=""
588
+
589
+ i=0
590
+ while i<str.length
591
+ hexv=str[i,2]
592
+ if "1B".eql?(hexv)
593
+ i+=2
594
+ hexv=str[i,2]
595
+
596
+ value=@extensiontable_rev[hexv.to_i(16)]
597
+ value=" " if value.nil?
598
+ unencoded+=value
599
+ else
600
+ val=@asciitable[hexv.to_i(16)]
601
+ val=" " if val.nil?
602
+ unencoded+=val
603
+ end
604
+
605
+ i+=2
606
+ end
607
+
608
+ return unencoded
609
+ end
610
+
611
+
612
+
613
+
614
+ def self.int2hex(i,max_nibbles=2)
615
+ tmp=i.to_s(16).upcase
616
+ if tmp.length%2!=0
617
+ tmp="0"+tmp
618
+ end
619
+
620
+ remaining_nibbles=max_nibbles-tmp.length
621
+ if remaining_nibbles>0
622
+ tmp="0"*remaining_nibbles+tmp;
623
+ end
624
+
625
+ return tmp
626
+ end
627
+
628
+
629
+
630
+ # usado para construir um UCP duma string
631
+ def self.parse_str(ustr)
632
+ #puts "parse_str(#{ustr})"
633
+
634
+ if ustr.nil?
635
+ return nil
636
+ end
637
+
638
+ arr=ustr[(ustr.index(2.chr)+1)..-2].split("/")
639
+ trn=arr[0]
640
+ #puts "#{trn}"
641
+ # length
642
+ operation_type=arr[2]
643
+ #puts "#{operation_type}"
644
+ operation=arr[3]
645
+ #puts "#{operation}"
646
+
647
+ ucpmsg=nil
648
+
649
+ if operation.eql?("01")
650
+ if operation_type.eql?("O")
651
+ # puts "parsing a ucp01"
652
+ ucpmsg=Ucp01Operation.new(arr)
653
+ elsif operation_type.eql?("R")
654
+ # puts "parsing a result of a ucp01"
655
+ ucpmsg=Ucp01Result.new(arr)
656
+ end
657
+ elsif operation.eql?("30")
658
+ if operation_type.eql?("O")
659
+ # puts "parsing a ucp30"
660
+ ucpmsg=Ucp30Operation.new(arr)
661
+ elsif operation_type.eql?("R")
662
+ #puts "parsing a result of a ucp30"
663
+ ucpmsg=Ucp30Result.new(arr)
664
+ end
665
+ elsif operation.eql?("31")
666
+ if operation_type.eql?("O")
667
+ #puts "parsing a ucp31"
668
+ ucpmsg=Ucp31Operation.new(arr)
669
+ elsif operation_type.eql?("R")
670
+ #puts "parsing a result of a ucp31"
671
+ ucpmsg=Ucp31Result.new(arr)
672
+ end
673
+ elsif operation.eql?("51")
674
+ if operation_type.eql?("O")
675
+ #puts "parsing a ucp51"
676
+ ucpmsg=Ucp51Operation.new(arr)
677
+ elsif operation_type.eql?("R")
678
+ #puts "parsing a result of a ucp51"
679
+ ucpmsg=Ucp51Result.new(arr)
680
+ end
681
+ elsif operation.eql?("52")
682
+ if operation_type.eql?("O")
683
+ #puts "parsing a ucp52"
684
+ ucpmsg=Ucp52Operation.new(arr)
685
+ elsif operation_type.eql?("R")
686
+ #puts "parsing a result of a ucp52"
687
+ ucpmsg=Ucp52Result.new(arr)
688
+ end
689
+ elsif operation.eql?("53")
690
+ if operation_type.eql?("O")
691
+ #puts "parsing a ucp53"
692
+ ucpmsg=Ucp53Operation.new(arr)
693
+ elsif operation_type.eql?("R")
694
+ #puts "parsing a result of a ucp53"
695
+ ucpmsg=Ucp53Result.new(arr)
696
+ end
697
+ elsif operation.eql?("54")
698
+ if operation_type.eql?("O")
699
+ #puts "parsing a ucp54"
700
+ ucpmsg=Ucp54Operation.new(arr)
701
+ elsif operation_type.eql?("R")
702
+ #puts "parsing a result of a ucp54"
703
+ ucpmsg=Ucp54Result.new(arr)
704
+ end
705
+ elsif operation.eql?("55")
706
+ if operation_type.eql?("O")
707
+ #puts "parsing a ucp55"
708
+ ucpmsg=Ucp55Operation.new(arr)
709
+ elsif operation_type.eql?("R")
710
+ #puts "parsing a result of a ucp55"
711
+ ucpmsg=Ucp55Result.new(arr)
712
+ end
713
+ elsif operation.eql?("56")
714
+ if operation_type.eql?("O")
715
+ #puts "parsing a ucp56"
716
+ ucpmsg=Ucp56Operation.new(arr)
717
+ elsif operation_type.eql?("R")
718
+ #puts "parsing a result of a ucp56"
719
+ ucpmsg=Ucp56Result.new(arr)
720
+ end
721
+ elsif operation.eql?("57")
722
+ if operation_type.eql?("O")
723
+ #puts "parsing a ucp57"
724
+ ucpmsg=Ucp57Operation.new(arr)
725
+ elsif operation_type.eql?("R")
726
+ #puts "parsing a result of a ucp57"
727
+ ucpmsg=Ucp57Result.new(arr)
728
+ end
729
+ elsif operation.eql?("58")
730
+ if operation_type.eql?("O")
731
+ #puts "parsing a ucp58"
732
+ ucpmsg=Ucp58Operation.new(arr)
733
+ elsif operation_type.eql?("R")
734
+ #puts "parsing a result of a ucp58"
735
+ ucpmsg=Ucp58Result.new(arr)
736
+ end
737
+ elsif operation.eql?("60")
738
+ if operation_type.eql?("O")
739
+ #puts "parsing a ucp60"
740
+ ucpmsg=Ucp60Operation.new(arr)
741
+ elsif operation_type.eql?("R")
742
+ #puts "parsing a result of a ucp60"
743
+ ucpmsg=Ucp60Result.new(arr)
744
+ end
745
+ elsif operation.eql?("61")
746
+ if operation_type.eql?("O")
747
+ #puts "parsing a ucp61"
748
+ ucpmsg=Ucp61Operation.new(arr)
749
+ elsif operation_type.eql?("R")
750
+ #puts "parsing a result of a ucp61"
751
+ ucpmsg=Ucp61Result.new(arr)
752
+ end
753
+ end
754
+
755
+ #ucpmsg.trn=trn
756
+ return ucpmsg
757
+ end
758
+
759
+
760
+
761
+
762
+ # usado para construir uma resposta UCP a partir dum UCP
763
+ def self.make_ucp_result(ucp)
764
+ puts "make_ucp_result(#{ucp.to_s})"
765
+
766
+ if ucp.nil?
767
+ return nil
768
+ end
769
+
770
+ trn=ucp.trn
771
+ #puts "#{trn}"
772
+ # length
773
+ operation_type=ucp.operation_type
774
+ #puts "#{operation_type}"
775
+ operation=ucp.operation
776
+ #puts "#{operation}"
777
+
778
+ ucpmsg=nil
779
+
780
+ if operation.eql?("01")
781
+ ucpmsg=Ucp01Result.new
782
+ elsif operation.eql?("30")
783
+ ucpmsg=Ucp30Result.new
784
+ elsif operation.eql?("31")
785
+ ucpmsg=Ucp31Result.new
786
+ elsif operation.eql?("51")
787
+ ucpmsg=Ucp51Result.new
788
+ elsif operation.eql?("52")
789
+ ucpmsg=Ucp52Result.new
790
+ elsif operation.eql?("53")
791
+ ucpmsg=Ucp53Result.new
792
+ elsif operation.eql?("54")
793
+ ucpmsg=Ucp54Result.new
794
+ elsif operation.eql?("55")
795
+ ucpmsg=Ucp55Result.new
796
+ elsif operation.eql?("56")
797
+ ucpmsg=Ucp56Result.new
798
+ elsif operation.eql?("57")
799
+ ucpmsg=Ucp57Result.new
800
+ elsif operation.eql?("58")
801
+ ucpmsg=Ucp58Result.new
802
+ elsif operation.eql?("60")
803
+ ucpmsg=Ucp60Result.new
804
+ elsif operation.eql?("61")
805
+ ucpmsg=Ucp61Result.new
806
+ else
807
+ return nil
808
+ end
809
+
810
+ ucpmsg.trn=trn
811
+ return ucpmsg
812
+ end
813
+
814
+ def self.hex2str(hexstr)
815
+ str=""
816
+ hexstr.scan(/../).each { | tuple | str+=tuple.hex.chr }
817
+ return str
818
+ end
819
+
820
+ def self.decode_ucp_msg(ucp)
821
+ text=nil
822
+ dcs=ucp.dcs.to_i(16)
823
+
824
+ if (dcs & 0x0F == 0x01) || (dcs & 0x0F == 0x00)
825
+
826
+ if ucp.operation.eql?("30")
827
+ text=UCP.decode_ira(ucp.get_field(:amsg))
828
+ else
829
+
830
+ if ucp.operation.eql?("51") || ucp.operation.eql?("52") || ucp.operation.eql?("53")
831
+ mt=ucp.get_field(:msg)
832
+ if mt.eql?("2")
833
+ # numeric message.. return it as it is
834
+ text=ucp.get_field(:msg)
835
+ elsif mt.eql?("3")
836
+ text=UCP.decode_ira(ucp.get_field(:msg))
837
+ else
838
+ # unexpected "mt" value. return nil explicitely
839
+ return nil
840
+ end
841
+ elsif ucp.operation.eql?("01")
842
+ text=UCP.decode_ira(ucp.get_field(:msg))
843
+ else
844
+ # unexpected operation. return nil explicitely
845
+ return nil
846
+ end
847
+
848
+ end
849
+ elsif (dcs & 0x0F == 0x08) || (dcs & 0x0F == 0x09)
850
+ str=UCP.hex2str(ucp.get_field(:msg))
851
+ text=Iconv.iconv("utf-8","utf-16be",str).first
852
+ else
853
+ # cant decode text; unsupported DCS
854
+ return nil
855
+ end
856
+
857
+ return text
858
+ end
859
+
860
+ def self.decode_ucp_oadc(ucp)
861
+ otoa=nil
862
+ oadc=ucp.get_field(:oadc)
863
+
864
+ if ucp.is_a?(Ucp51Operation) || ucp.is_a?(Ucp52Operation) || ucp.is_a?(Ucp53Operation) || ucp.is_a?(Ucp54Operation) || ucp.is_a?(Ucp55Operation) || ucp.is_a?(Ucp56Operation) || ucp.is_a?(Ucp57Operation) || ucp.is_a?(Ucp58Operation)
865
+ otoa=ucp.get_field(:otoa)
866
+ end
867
+
868
+ if otoa.nil? || otoa.eql?("1139")
869
+ return oadc
870
+ elsif otoa.eql?("5039")
871
+ #useful_nibbles=oadc[0,2].to_i(16)
872
+ return UCP.decode7bitgsm(oadc[2..-1])
873
+ else
874
+ #
875
+ end
876
+
877
+ # by default, return oadc
878
+ return oadc
879
+ end
880
+
881
+
882
+ # initialize tables on first class reference, in fact when loading it
883
+ initialize_ascii2ira()
884
+
885
+ end