Move AT commands in Hayes class and use Modem to send to SerialPort
parent
b1568bbf24
commit
67571dd12e
|
@ -15,8 +15,8 @@ Gem::Specification.new do |gem|
|
||||||
gem.require_paths = ["lib"]
|
gem.require_paths = ["lib"]
|
||||||
gem.version = Biju::VERSION
|
gem.version = Biju::VERSION
|
||||||
|
|
||||||
gem.add_development_dependency "minitest", "3.0.0"
|
gem.add_development_dependency "rspec", "~> 2.14.0"
|
||||||
|
|
||||||
gem.add_dependency "serialport", ">=1.0.4"
|
gem.add_dependency "serialport", "~> 1.1.0"
|
||||||
gem.add_dependency "parslet", "~> 1.5.0"
|
gem.add_dependency "parslet", "~> 1.5.0"
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
require 'biju/version'
|
require 'biju/version'
|
||||||
require "biju/modem"
|
require 'biju/modem'
|
||||||
require "biju/sms"
|
require 'biju/to_hayes'
|
||||||
require "biju/hayes"
|
require 'biju/hayes'
|
||||||
|
require 'biju/sms'
|
||||||
|
require 'biju/parser'
|
||||||
|
|
|
@ -1,69 +1,92 @@
|
||||||
module Biju
|
module Biju
|
||||||
class Hayes
|
class Hayes
|
||||||
attr_accessor :command, :attributes, :ok
|
attr_reader :modem
|
||||||
attr_reader :answer
|
|
||||||
|
|
||||||
#def method_missing(m, *args, &block)
|
def initialize(port, options = {})
|
||||||
#end
|
pin = options.delete(:pin) || '0000'
|
||||||
|
@modem = Modem.new(port, options)
|
||||||
|
|
||||||
|
attention
|
||||||
|
init_modem
|
||||||
|
unlock_pin pin
|
||||||
|
|
||||||
|
text_mode
|
||||||
|
extended_error
|
||||||
|
end
|
||||||
|
|
||||||
|
def at_command(cmd = nil, *args, &block)
|
||||||
|
command = ['AT', cmd].compact.join
|
||||||
|
command_args = args.compact.to_hayes
|
||||||
|
|
||||||
|
full_command = [command, (command_args.empty? ? nil : command_args)]
|
||||||
|
.compact.join('=')
|
||||||
|
|
||||||
|
answer = write(full_command)
|
||||||
|
|
||||||
|
return block.call(answer) if block_given?
|
||||||
|
answer
|
||||||
|
end
|
||||||
|
|
||||||
def attention
|
def attention
|
||||||
at_command { |response| response =~ /OK/ }
|
at_command[:status]
|
||||||
#at_command { |response| true }
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def init_modem
|
def init_modem
|
||||||
at_command('Z') { |response| response =~ /OK/ }
|
at_command('Z')[:status]
|
||||||
end
|
end
|
||||||
|
|
||||||
def text_mode(enabled = true)
|
def text_mode(enabled = true)
|
||||||
at_command('+CMGF', enabled) { |response| response =~ /OK/ }
|
at_command('+CMGF', enabled)[:status]
|
||||||
end
|
end
|
||||||
|
|
||||||
def prefered_storage?
|
def extended_error(enabled = true)
|
||||||
at_command('+CPMS') { |response| response =~ /OK/ }
|
at_command('+CMEE', enabled)[:status]
|
||||||
end
|
end
|
||||||
|
|
||||||
def answer=(ret)
|
def prefered_storage(pms = nil)
|
||||||
@answer = ret
|
result = at_command('+CPMS', pms)
|
||||||
ok?
|
return result[:array] if result[:cmd] == '+CPMS'
|
||||||
|
nil
|
||||||
end
|
end
|
||||||
|
|
||||||
def ok?
|
def unlock_pin(pin)
|
||||||
ok.nil? ? true : !ok.call(answer).nil?
|
at_command('+CPIN', pin)[:status]
|
||||||
|
end
|
||||||
|
|
||||||
|
def messages(which = "ALL")
|
||||||
|
prefered_storage 'MT'
|
||||||
|
sms = at_command('+CMGL', which)
|
||||||
|
|
||||||
|
return sms[:status] if !sms.has_key?(:sms) || sms[:sms].empty?
|
||||||
|
sms[:sms].map do |msg|
|
||||||
|
Biju::Sms.new(
|
||||||
|
id: msg[:infos][0],
|
||||||
|
phone_number: msg[:infos][2],
|
||||||
|
datetime: msg[:infos][4],
|
||||||
|
message: msg[:message].chomp)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Delete a sms message by id.
|
||||||
|
# @param [Fixnum] Id of sms message on modem.
|
||||||
|
def delete(id)
|
||||||
|
at_command('+CMGD', id)
|
||||||
|
end
|
||||||
|
|
||||||
|
def send(sms, options = {})
|
||||||
|
at_command('+CMGS', sms.phone_number)
|
||||||
|
write("#{sms.message}#{26.chr}")
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def at_command(cmd = nil, *args, &block)
|
def write(text)
|
||||||
option_prefix = nil #options[:prefix] || nil
|
modem.write(text)
|
||||||
cmd_root = ['AT', cmd].compact.join(option_prefix)
|
hayes_to_obj(modem.wait_answer)
|
||||||
cmd_args = args.compact.map { |arg| to_hayes_string(arg) } unless args.empty?
|
|
||||||
self.command = [cmd_root, cmd_args].compact.join('=')
|
|
||||||
self.ok = block if block_given?
|
|
||||||
command
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def hayes_to_obj(str)
|
def hayes_to_obj(str)
|
||||||
end
|
ATTransform.new.apply(ATParser.new.parse(str))
|
||||||
|
|
||||||
# OPTIMIZE : add () to array
|
|
||||||
def to_hayes_string(arg)
|
|
||||||
case arg
|
|
||||||
when String
|
|
||||||
"\"#{arg}\""
|
|
||||||
when Array
|
|
||||||
arg.join(',')
|
|
||||||
when TrueClass, FalseClass
|
|
||||||
!!arg ? 1 : 0
|
|
||||||
else
|
|
||||||
"?"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class HayesSms < Hayes
|
|
||||||
def unlock_pin(pin)
|
|
||||||
at_command("+CPIN=#{to_hayes_string(pin)}") { |response| response =~ /OK/ }
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,36 +1,19 @@
|
||||||
require 'serialport'
|
require 'serialport'
|
||||||
require_relative 'sms'
|
|
||||||
|
|
||||||
module Biju
|
module Biju
|
||||||
class Modem
|
class Modem
|
||||||
|
DEFAULT_OPTIONS = { baud: 9600, data_bits: 8,
|
||||||
|
stop_bits: 1, parity: SerialPort::NONE }
|
||||||
|
|
||||||
attr_reader :connection
|
attr_reader :connection
|
||||||
|
|
||||||
# @param [Hash] Options to serial connection.
|
# @param [Hash] Options to serial connection.
|
||||||
# @option options [String] :port The modem port to connect
|
# @option options [String] :port The modem port to connect
|
||||||
#
|
#
|
||||||
# Biju::Modem.new(:port => '/dev/ttyUSB0')
|
# Biju::Modem.new('/dev/ttyUSB0')
|
||||||
#
|
#
|
||||||
def initialize(options={}, &block)
|
def initialize(port, options = {})
|
||||||
raise Exception.new("Port is required") unless options[:port]
|
@connection = SerialPort.new(port, DEFAULT_OPTIONS.merge!(options))
|
||||||
pin = options[:pin] || '0000'
|
|
||||||
@connection = connect(options)
|
|
||||||
cmd("AT")
|
|
||||||
# initialize modem
|
|
||||||
cmd("ATZ")
|
|
||||||
# unlock pin code
|
|
||||||
cmd("AT+CPIN=\"#{pin}\"") if pin
|
|
||||||
|
|
||||||
cmd("AT+CPMS=?")
|
|
||||||
|
|
||||||
# set SMS text mode
|
|
||||||
cmd("AT+CMGF=1")
|
|
||||||
# set extended error reports
|
|
||||||
cmd('AT+CMEE=1')
|
|
||||||
#instance_eval &block if block_given?
|
|
||||||
if block_given?
|
|
||||||
yield connection
|
|
||||||
close
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Close the serial connection.
|
# Close the serial connection.
|
||||||
|
@ -38,59 +21,16 @@ module Biju
|
||||||
connection.close
|
connection.close
|
||||||
end
|
end
|
||||||
|
|
||||||
# Return an Array of Sms if there is messages nad return nil if not.
|
def write(text)
|
||||||
def messages(which = "ALL")
|
connection.write(text + "\r")
|
||||||
# read message from all storage in the mobile phone (sim+mem)
|
|
||||||
cmd('AT+CPMS="MT"')
|
|
||||||
# get message list
|
|
||||||
sms = cmd('AT+CMGL="%s"' % which )
|
|
||||||
# collect messages
|
|
||||||
msgs = sms.scan(/\+CMGL\:\s*?(\d+)\,.*?\,\"(.+?)\"\,.*?\,\"(.+?)\".*?\n(.*)/)
|
|
||||||
return nil unless msgs
|
|
||||||
msgs.collect!{ |msg| Biju::Sms.new(:id => msg[0], :phone_number => msg[1], :datetime => msg[2], :message => msg[3].chomp) }
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Delete a sms message by id.
|
def wait_answer
|
||||||
# @param [Fixnum] Id of sms message on modem.
|
|
||||||
def delete(id)
|
|
||||||
cmd("AT+CMGD=#{id}")
|
|
||||||
end
|
|
||||||
|
|
||||||
def send(sms, options = {})
|
|
||||||
# initiate the sms, and wait for either
|
|
||||||
# the text prompt or an error message
|
|
||||||
cmd("AT+CMGS=\"#{sms.phone_number}\"")
|
|
||||||
|
|
||||||
# send the sms, and wait until
|
|
||||||
# it is accepted or rejected
|
|
||||||
cmd("#{sms.message}#{26.chr}")
|
|
||||||
# ... check reception
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
def connect(options)
|
|
||||||
port = options.delete(:port)
|
|
||||||
SerialPort.new(port, default_options.merge!(options))
|
|
||||||
end
|
|
||||||
|
|
||||||
def default_options
|
|
||||||
{ :baud => 9600, :data_bits => 8, :stop_bits => 1, :parity => SerialPort::NONE }
|
|
||||||
end
|
|
||||||
|
|
||||||
def cmd(cmd)
|
|
||||||
puts "SENDING : #{cmd}"
|
|
||||||
connection.write(cmd + "\r")
|
|
||||||
wait_str = wait
|
|
||||||
#p "#{cmd} --> #{wait_str}"
|
|
||||||
end
|
|
||||||
|
|
||||||
def wait
|
|
||||||
buffer = ''
|
buffer = ''
|
||||||
while IO.select([connection], [], [], 0.25)
|
while IO.select([connection], [], [], 0.25)
|
||||||
chr = connection.getc.chr;
|
buffer << connection.getc.chr
|
||||||
buffer += chr
|
|
||||||
end
|
end
|
||||||
puts "RECEIVING : #{buffer}"
|
|
||||||
buffer
|
buffer
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue