1 require 'serialport'
2 require 'time'
3
4 class GSM
5
6 SMSC = "+447785016005"
7
8 def initialize(options = {})
9 @port = SerialPort.new(options[:port] || 3, options[:baud] || 38400, options[:bits] || 8, options[:stop] || 1, SerialPort::NONE)
10 @debug = options[:debug]
11 cmd("AT")
12
13 cmd("AT+CMGF=1")
14
15 cmd("AT+CSCA=\"#{SMSC}\"")
16 end
17
18 def close
19 @port.close
20 end
21
22 def cmd(cmd)
23 @port.write(cmd + "\r")
24 wait
25 end
26
27 def wait
28 buffer = ''
29 while IO.select([@port], [], [], 0.25)
30 chr = @port.getc.chr;
31 print chr if @debug == true
32 buffer += chr
33 end
34 buffer
35 end
36
37 def send_sms(options)
38 cmd("AT+CMGS=\"#{options[:number]}\"")
39 cmd("#{options[:message][0..140]}#{26.chr}\r\r")
40 sleep 3
41 wait
42 cmd("AT")
43 end
44
45 class SMS
46 attr_accessor :id, :sender, :message, :connection
47 attr_writer :time
48
49 def initialize(params)
50 @id = params[:id]; @sender = params[:sender]; @time = params[:time]; @message = params[:message]; @connection = params[:connection]
51 end
52
53 def delete
54 @connection.cmd("AT+CMGD=#{@id}")
55 end
56
57 def time
58
59
60 Time.parse(@time.sub(/(\d+)\D+(\d+)\D+(\d+)/, '\2/\3/20\1'))
61 end
62 end
63
64 def messages
65 sms = cmd("AT+CMGL=\"ALL\"")
66
67 msgs = sms.scan(/\+CMGL\:\s*?(\d+)\,.*?\,\"(.+?)\"\,.*?\,\"(.+?)\".*?\n(.*)/)
68 return nil unless msgs
69 msgs.collect!{ |m| GSM::SMS.new(:connection => self, :id => m[0], :sender => m[1], :time => m[2], :message => m[3].chomp) } rescue nil
70 end
71 end
72
73
74 destination_number = "+44 someone else"
75
76 p = GSM.new(:debug => false)
77
78
79 p.send_sms(:number => destination_number, :message => "Test at #{Time.now}")
80
81
82 p.messages.each do |msg|
83 puts "#{msg.id} - #{msg.time} - #{msg.sender} - #{msg.message}"
84
85 end