updated to ruby1.9 (I may have missed some), and fixed some bugs/typos
This commit is contained in:
parent
9bb57d7ac6
commit
81db0e7926
|
@ -18,7 +18,7 @@ along with sofSIM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
Copyright (C) 2011 Kevin "tsaitgaist" Redon kevredon@mail.tsaitgaist.info
|
Copyright (C) 2011 Kevin "tsaitgaist" Redon kevredon@mail.tsaitgaist.info
|
||||||
=end
|
=end
|
||||||
# this programm will forward APDU from an IO to a SAP server
|
# this programm will forward APDU from an IO to a SAP server
|
||||||
require 'sap/client'
|
require './sap/client.rb'
|
||||||
require 'socket'
|
require 'socket'
|
||||||
|
|
||||||
SAP_HOST = "localhost"
|
SAP_HOST = "localhost"
|
||||||
|
|
|
@ -17,8 +17,8 @@ along with sofSIM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
Copyright (C) 2011 Kevin "tsaitgaist" Redon kevredon@mail.tsaitgaist.info
|
Copyright (C) 2011 Kevin "tsaitgaist" Redon kevredon@mail.tsaitgaist.info
|
||||||
=end
|
=end
|
||||||
# this class copies all files from the SIM to an xml file
|
# this class copies all files from the SIM to an xml file
|
||||||
require 'sap/client'
|
require './sap/client.rb'
|
||||||
require 'lib/apdu'
|
require './lib/apdu.rb'
|
||||||
require 'xml'
|
require 'xml'
|
||||||
|
|
||||||
class Copy
|
class Copy
|
||||||
|
@ -52,7 +52,7 @@ class Copy
|
||||||
# verify CHV1
|
# verify CHV1
|
||||||
while chv_enabled? do
|
while chv_enabled? do
|
||||||
|
|
||||||
print "enter PIN : "
|
print "enter PIN: "
|
||||||
STDOUT.flush
|
STDOUT.flush
|
||||||
pin = gets.chomp
|
pin = gets.chomp
|
||||||
# pin is between 4 and 8 digits
|
# pin is between 4 and 8 digits
|
||||||
|
@ -254,7 +254,7 @@ class Copy
|
||||||
@nb_files = 0 unless @nb_files
|
@nb_files = 0 unless @nb_files
|
||||||
@nb_files += 1
|
@nb_files += 1
|
||||||
rescue Exception => e
|
rescue Exception => e
|
||||||
puts "file error : #{e.to_s}"
|
puts "file errors: #{e.to_s}"
|
||||||
select_decode(select(id))
|
select_decode(select(id))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -18,10 +18,10 @@ along with sofSIM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
Copyright (C) 2011 Kevin "tsaitgaist" Redon kevredon@mail.tsaitgaist.info
|
Copyright (C) 2011 Kevin "tsaitgaist" Redon kevredon@mail.tsaitgaist.info
|
||||||
=end
|
=end
|
||||||
# this programm will create a client which can be used to test servers
|
# this programm will create a client which can be used to test servers
|
||||||
require 'sap/client'
|
require './sap/client.rb'
|
||||||
require 'lib/apdu'
|
require './lib/apdu.rb'
|
||||||
require 'info_client'
|
require './info_client.rb'
|
||||||
require 'copy_client'
|
require './copy_client.rb'
|
||||||
|
|
||||||
#=============
|
#=============
|
||||||
#== default ==
|
#== default ==
|
||||||
|
@ -64,8 +64,8 @@ def print_help
|
||||||
puts ""
|
puts ""
|
||||||
puts "options :"
|
puts "options :"
|
||||||
puts " --help,-h\t\tprint this help"
|
puts " --help,-h\t\tprint this help"
|
||||||
puts " --type,-t client\tclient type : demo,info,copy (default #{@type})"
|
puts " --type,-t client\tclient type: demo,info,copy (default #{@type})"
|
||||||
puts " --socket,-s type\tsocket type : tcp,unix,bt (default #{@socket})"
|
puts " --socket,-s type\tsocket type: tcp,unix,bt (default #{@socket})"
|
||||||
puts " --tcp,-p port\t\ttcp port (default #{@port})"
|
puts " --tcp,-p port\t\ttcp port (default #{@port})"
|
||||||
puts " --host,-l host\t\ttcp host (default #{@host})"
|
puts " --host,-l host\t\ttcp host (default #{@host})"
|
||||||
puts " --unix,-u file\t\tunix socket (default #{@unix})"
|
puts " --unix,-u file\t\tunix socket (default #{@unix})"
|
||||||
|
@ -130,7 +130,7 @@ when "bt"
|
||||||
if @bt then
|
if @bt then
|
||||||
io = SerialPort.new(@bt)
|
io = SerialPort.new(@bt)
|
||||||
else
|
else
|
||||||
require 'lib/bluetooth_sap_serial'
|
require './tools/bluetooth_sap_serial.rb'
|
||||||
bt = BluetoothSAPSerial.new
|
bt = BluetoothSAPSerial.new
|
||||||
# using SerialPort because reading the File does not work (have to find right stty options)
|
# using SerialPort because reading the File does not work (have to find right stty options)
|
||||||
io = SerialPort.new(bt.connect)
|
io = SerialPort.new(bt.connect)
|
||||||
|
@ -148,7 +148,7 @@ when "demo"
|
||||||
|
|
||||||
# get ATR
|
# get ATR
|
||||||
atr = @client.atr
|
atr = @client.atr
|
||||||
puts atr ? "ATR : #{atr.to_hex_disp}" : "could not get ATR"
|
puts atr ? "ATR: #{atr.to_hex_disp}" : "could not get ATR"
|
||||||
|
|
||||||
# get IMSI
|
# get IMSI
|
||||||
imsi = read_ef([MF,DF_GSM,EF_IMSI])
|
imsi = read_ef([MF,DF_GSM,EF_IMSI])
|
||||||
|
@ -166,7 +166,7 @@ when "demo"
|
||||||
rands << [(i<<4)+i]*16
|
rands << [(i<<4)+i]*16
|
||||||
end
|
end
|
||||||
# the results
|
# the results
|
||||||
puts "some KCs (RAND SRES Kc) :"
|
puts "some KCs (RAND SRES Kc):"
|
||||||
rands.each do |r|
|
rands.each do |r|
|
||||||
response = a38(r)
|
response = a38(r)
|
||||||
puts " - #{r.to_hex_disp.gsub(' ','')} #{response[0,4].to_hex_disp.gsub(' ','')} #{response[4..-1].to_hex_disp.gsub(' ','')}"
|
puts " - #{r.to_hex_disp.gsub(' ','')} #{response[0,4].to_hex_disp.gsub(' ','')} #{response[4..-1].to_hex_disp.gsub(' ','')}"
|
||||||
|
|
|
@ -48,8 +48,8 @@ def print_help
|
||||||
puts ""
|
puts ""
|
||||||
puts "options :"
|
puts "options :"
|
||||||
puts " --help,-h\t\tprint this help"
|
puts " --help,-h\t\tprint this help"
|
||||||
puts " --type,-t type\tserver type : pcsc,sim (default #{@type})"
|
puts " --type,-t type\tserver type: pcsc,sim (default #{@type})"
|
||||||
puts " --socket,-s type\tsocket type : tcp,unix,bt (default #{@socket})"
|
puts " --socket,-s type\tsocket type: tcp,unix (default #{@socket})"
|
||||||
puts " --port,-p port\t\ttcp listeing port (default #{@port})"
|
puts " --port,-p port\t\ttcp listeing port (default #{@port})"
|
||||||
puts " --unix,-u file\t\tunix socket (default #{@unix})"
|
puts " --unix,-u file\t\tunix socket (default #{@unix})"
|
||||||
puts " --file,-f file\t\tfile for sim type (default #{@file})"
|
puts " --file,-f file\t\tfile for sim type (default #{@file})"
|
||||||
|
@ -107,10 +107,10 @@ io = socket.accept
|
||||||
|
|
||||||
case @type
|
case @type
|
||||||
when "pcsc"
|
when "pcsc"
|
||||||
require 'pcsc_server'
|
require './pcsc_server.rb'
|
||||||
server = PCSCServer.new(io)
|
server = PCSCServer.new(io)
|
||||||
when "sim"
|
when "sim"
|
||||||
require 'simos_server'
|
require './simos_server.rb'
|
||||||
server = SIMServer.new(io)
|
server = SIMServer.new(io)
|
||||||
else
|
else
|
||||||
raise "unkown server type"
|
raise "unkown server type"
|
||||||
|
|
|
@ -18,8 +18,8 @@ along with sofSIM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
Copyright (C) 2011 Kevin "tsaitgaist" Redon kevredon@mail.tsaitgaist.info
|
Copyright (C) 2011 Kevin "tsaitgaist" Redon kevredon@mail.tsaitgaist.info
|
||||||
=end
|
=end
|
||||||
# this programm will display information stored in the SIM
|
# this programm will display information stored in the SIM
|
||||||
require 'sap/client'
|
require './sap/client.rb'
|
||||||
require 'lib/apdu'
|
require './lib/apdu.rb'
|
||||||
|
|
||||||
#=============
|
#=============
|
||||||
#== methods ==
|
#== methods ==
|
||||||
|
@ -104,11 +104,11 @@ class Info
|
||||||
# display the information stored on the SIM
|
# display the information stored on the SIM
|
||||||
def display
|
def display
|
||||||
# get the ATR
|
# get the ATR
|
||||||
puts "ATR : #{@client.atr.to_hex_disp}"
|
puts "ATR: #{@client.atr.to_hex_disp}"
|
||||||
|
|
||||||
# verify CHV1
|
# verify CHV1
|
||||||
while chv_enabled? do
|
while chv_enabled? do
|
||||||
print "enter PIN : "
|
print "enter PIN: "
|
||||||
$stdout.flush
|
$stdout.flush
|
||||||
pin = gets.chomp
|
pin = gets.chomp
|
||||||
# pin is between 4 and 8 digits
|
# pin is between 4 and 8 digits
|
||||||
|
@ -138,7 +138,7 @@ class Info
|
||||||
iccid = read_ef([MF,EF_ICCID])
|
iccid = read_ef([MF,EF_ICCID])
|
||||||
# get rid of the padding
|
# get rid of the padding
|
||||||
iccid = iccid.nibble_str(true)
|
iccid = iccid.nibble_str(true)
|
||||||
puts "ICCID : "+iccid
|
puts "ICCID: "+iccid
|
||||||
|
|
||||||
# get IMSI
|
# get IMSI
|
||||||
imsi = read_ef([MF,DF_GSM,EF_IMSI])
|
imsi = read_ef([MF,DF_GSM,EF_IMSI])
|
||||||
|
@ -147,7 +147,7 @@ class Info
|
||||||
imsi = imsi[1,imsi_length]
|
imsi = imsi[1,imsi_length]
|
||||||
# first nibble is for parity check (not done)
|
# first nibble is for parity check (not done)
|
||||||
imsi = imsi.nibble_str[1..-1]
|
imsi = imsi.nibble_str[1..-1]
|
||||||
puts "IMSI : "+imsi
|
puts "IMSI: "+imsi
|
||||||
|
|
||||||
# service provider name
|
# service provider name
|
||||||
begin
|
begin
|
||||||
|
@ -195,7 +195,7 @@ class Info
|
||||||
"reserved"
|
"reserved"
|
||||||
end
|
end
|
||||||
msisdn_str += ", "
|
msisdn_str += ", "
|
||||||
msisdn_str += "numbering plan identifier : #{npi}"
|
msisdn_str += "numbering plan identifier: #{npi}"
|
||||||
ton = case (msisdn[-13]>>4)&0x7
|
ton = case (msisdn[-13]>>4)&0x7
|
||||||
when 0
|
when 0
|
||||||
"unknown"
|
"unknown"
|
||||||
|
@ -211,7 +211,7 @@ class Info
|
||||||
"reserved"
|
"reserved"
|
||||||
end
|
end
|
||||||
msisdn_str += ", "
|
msisdn_str += ", "
|
||||||
msisdn_str += "type of number : #{ton}"
|
msisdn_str += "type of number: #{ton}"
|
||||||
number = msisdn[-12,msisdn[-14]-1].nibble_str(true)
|
number = msisdn[-12,msisdn[-14]-1].nibble_str(true)
|
||||||
number.gsub!(/[Aa]/,"*")
|
number.gsub!(/[Aa]/,"*")
|
||||||
number.gsub!(/[Bb]/,"#")
|
number.gsub!(/[Bb]/,"#")
|
||||||
|
@ -219,13 +219,13 @@ class Info
|
||||||
number.gsub!(/[Dd]/,"§")
|
number.gsub!(/[Dd]/,"§")
|
||||||
number.gsub!(/[Ee]/,"1")
|
number.gsub!(/[Ee]/,"1")
|
||||||
msisdn_str += ", "
|
msisdn_str += ", "
|
||||||
msisdn_str += "number : #{number}"
|
msisdn_str += "number: #{number}"
|
||||||
msisdn_str += ", capability in EF_CCP #{msisdn[-2]}" unless msisdn[-2]==0xff
|
msisdn_str += ", capability in EF_CCP #{msisdn[-2]}" unless msisdn[-2]==0xff
|
||||||
msisdn_str += ", entension in EF_EXT #{msisdn[-1]}" unless msisdn[-1]==0xff
|
msisdn_str += ", entension in EF_EXT #{msisdn[-1]}" unless msisdn[-1]==0xff
|
||||||
msisdn_str += "\n"
|
msisdn_str += "\n"
|
||||||
end
|
end
|
||||||
if msisdn_str.length>0 then
|
if msisdn_str.length>0 then
|
||||||
puts "MSISIDN :"
|
puts "MSISIDN:"
|
||||||
puts msisdn_str
|
puts msisdn_str
|
||||||
else
|
else
|
||||||
puts "MSISDN empty"
|
puts "MSISDN empty"
|
||||||
|
@ -237,7 +237,7 @@ class Info
|
||||||
# get PLMsel
|
# get PLMsel
|
||||||
plmn = read_ef([DF_GSM,EF_PLMNSEL])
|
plmn = read_ef([DF_GSM,EF_PLMNSEL])
|
||||||
# transform to MCC MNC
|
# transform to MCC MNC
|
||||||
print "PLMN selector : "
|
print "PLMN selector: "
|
||||||
plmns = ""
|
plmns = ""
|
||||||
(plmn.length/3).times do |i|
|
(plmn.length/3).times do |i|
|
||||||
mcc = plmn[3*i,2].nibble_str(true)
|
mcc = plmn[3*i,2].nibble_str(true)
|
||||||
|
@ -256,7 +256,7 @@ class Info
|
||||||
if plmn[0,3]==[0xff]*3 then
|
if plmn[0,3]==[0xff]*3 then
|
||||||
puts "no forbidden PLMN"
|
puts "no forbidden PLMN"
|
||||||
else
|
else
|
||||||
print "forbidden PLMN : "
|
print "forbidden PLMN: "
|
||||||
plmns = ""
|
plmns = ""
|
||||||
(plmn.length/3).times do |i|
|
(plmn.length/3).times do |i|
|
||||||
mcc = plmn[3*i,2].nibble_str(true)
|
mcc = plmn[3*i,2].nibble_str(true)
|
||||||
|
@ -270,7 +270,7 @@ class Info
|
||||||
begin
|
begin
|
||||||
plmn = read_ef([MF,DF_GSM,EF_PLMNWACT])
|
plmn = read_ef([MF,DF_GSM,EF_PLMNWACT])
|
||||||
# transform to MCC MNC
|
# transform to MCC MNC
|
||||||
print "user controlled PLMN : "
|
print "user controlled PLMN: "
|
||||||
plmns = ""
|
plmns = ""
|
||||||
(plmn.length/5).times do |i|
|
(plmn.length/5).times do |i|
|
||||||
mcc = plmn[3*i,2].nibble_str(true)
|
mcc = plmn[3*i,2].nibble_str(true)
|
||||||
|
@ -286,7 +286,7 @@ class Info
|
||||||
begin
|
begin
|
||||||
plmn = read_ef([MF,DF_GSM,EF_OPLMNWACT])
|
plmn = read_ef([MF,DF_GSM,EF_OPLMNWACT])
|
||||||
# transform to MCC MNC
|
# transform to MCC MNC
|
||||||
print "operator controlled PLMN : "
|
print "operator controlled PLMN: "
|
||||||
plmns = ""
|
plmns = ""
|
||||||
(plmn.length/5).times do |i|
|
(plmn.length/5).times do |i|
|
||||||
mcc = plmn[3*i,2].nibble_str(true)
|
mcc = plmn[3*i,2].nibble_str(true)
|
||||||
|
@ -319,7 +319,7 @@ class Info
|
||||||
rands << [(i<<4)+i]*16
|
rands << [(i<<4)+i]*16
|
||||||
end
|
end
|
||||||
# the results
|
# the results
|
||||||
puts "some KCs (RAND SRES Kc) :"
|
puts "some KCs (RAND SRES Kc):"
|
||||||
rands.each do |r|
|
rands.each do |r|
|
||||||
response = a38(r)
|
response = a38(r)
|
||||||
puts " - #{r.to_hex_disp.gsub(' ','')} #{response[0,4].to_hex_disp.gsub(' ','')} #{response[4..-1].to_hex_disp.gsub(' ','')}"
|
puts " - #{r.to_hex_disp.gsub(' ','')} #{response[0,4].to_hex_disp.gsub(' ','')} #{response[4..-1].to_hex_disp.gsub(' ','')}"
|
||||||
|
@ -339,7 +339,7 @@ class Info
|
||||||
end
|
end
|
||||||
|
|
||||||
# get EFsst
|
# get EFsst
|
||||||
puts "SIM service table :"
|
puts "SIM service table:"
|
||||||
sst = read_ef([MF,DF_GSM,EF_SST])
|
sst = read_ef([MF,DF_GSM,EF_SST])
|
||||||
sst.each_index do |i|
|
sst.each_index do |i|
|
||||||
(0..4).each do |j|
|
(0..4).each do |j|
|
||||||
|
@ -362,8 +362,8 @@ class Info
|
||||||
|
|
||||||
# get the phase
|
# get the phase
|
||||||
ad = read_ef([MF,DF_GSM,EF_AD])
|
ad = read_ef([MF,DF_GSM,EF_AD])
|
||||||
puts "administration data :"
|
puts "administration data:"
|
||||||
ms = " - MS operation mode : "
|
ms = " - MS operation mode: "
|
||||||
ms += case ad[0]
|
ms += case ad[0]
|
||||||
when 0x00
|
when 0x00
|
||||||
"normal operation"
|
"normal operation"
|
||||||
|
@ -379,16 +379,16 @@ class Info
|
||||||
"cell test operation"
|
"cell test operation"
|
||||||
end
|
end
|
||||||
puts ms
|
puts ms
|
||||||
ofm = " - OFM (Operational Feature Monitor) : "
|
ofm = " - OFM (Operational Feature Monitor): "
|
||||||
ofm += ad[2]&0x01==0x00 ? "disabled" : "enabled"
|
ofm += ad[2]&0x01==0x00 ? "disabled" : "enabled"
|
||||||
puts ofm
|
puts ofm
|
||||||
if ad.length>3 then
|
if ad.length>3 then
|
||||||
puts " - length of MNC in the IMSI : #{ad[3]}"
|
puts " - length of MNC in the IMSI: #{ad[3]}"
|
||||||
end
|
end
|
||||||
|
|
||||||
# location information
|
# location information
|
||||||
loci = read_ef([MF,DF_GSM,EF_LOCI])
|
loci = read_ef([MF,DF_GSM,EF_LOCI])
|
||||||
puts "location informtion :"
|
puts "location informtion:"
|
||||||
puts " - TMSI : #{loci[0,4].to_hex_disp.gsub(' ','')}"
|
puts " - TMSI : #{loci[0,4].to_hex_disp.gsub(' ','')}"
|
||||||
puts " - LAI : #{loci[4,5].to_hex_disp.gsub(' ','')}"
|
puts " - LAI : #{loci[4,5].to_hex_disp.gsub(' ','')}"
|
||||||
puts " - TMSI TIME : #{loci[9]==0 ? 'infinite' : (loci[9]*6).to_s+' min'}"
|
puts " - TMSI TIME : #{loci[9]==0 ? 'infinite' : (loci[9]*6).to_s+' min'}"
|
||||||
|
|
|
@ -17,7 +17,7 @@ along with sofSIM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
Copyright (C) 2011 Kevin "tsaitgaist" Redon kevredon@mail.tsaitgaist.info
|
Copyright (C) 2011 Kevin "tsaitgaist" Redon kevredon@mail.tsaitgaist.info
|
||||||
=end
|
=end
|
||||||
require 'sap/server'
|
require './sap/server.rb'
|
||||||
require 'rubygems'
|
require 'rubygems'
|
||||||
require 'smartcard'
|
require 'smartcard'
|
||||||
=begin
|
=begin
|
||||||
|
@ -67,18 +67,18 @@ class PCSCServer < Server
|
||||||
# reader already selected
|
# reader already selected
|
||||||
else
|
else
|
||||||
# select reader
|
# select reader
|
||||||
puts "readers :"
|
puts "readers:"
|
||||||
readers.each_index do |i|
|
readers.each_index do |i|
|
||||||
puts "#{i}) #{readers[i]}"
|
puts "#{i}) #{readers[i]}"
|
||||||
end
|
end
|
||||||
reader = nil
|
reader = nil
|
||||||
until reader do
|
until reader do
|
||||||
print "select reader [0] : "
|
print "select reader [0]: "
|
||||||
@reader_id = gets.chomp.to_i
|
@reader_id = gets.chomp.to_i
|
||||||
reader = readers[@reader_id]
|
reader = readers[@reader_id]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
puts "using reader : #{reader}"
|
puts "using reader: #{reader}"
|
||||||
|
|
||||||
# connect to the card
|
# connect to the card
|
||||||
verb = true
|
verb = true
|
||||||
|
|
|
@ -18,7 +18,7 @@ Copyright (C) 2011 Kevin "tsaitgaist" Redon kevredon@mail.tsaitgaist.info
|
||||||
=end
|
=end
|
||||||
# this is the client part of the SAP
|
# this is the client part of the SAP
|
||||||
# it implements the state machine for the client
|
# it implements the state machine for the client
|
||||||
require 'sap/common'
|
require './sap/common.rb'
|
||||||
|
|
||||||
# this is an abstract class
|
# this is an abstract class
|
||||||
# TODO :
|
# TODO :
|
||||||
|
|
|
@ -19,7 +19,7 @@ Copyright (C) 2011 Kevin "tsaitgaist" Redon kevredon@mail.tsaitgaist.info
|
||||||
# this is the server part of the SAP
|
# this is the server part of the SAP
|
||||||
# it implements the state machine for the server
|
# it implements the state machine for the server
|
||||||
# this is an abstract class
|
# this is an abstract class
|
||||||
require 'sap/common'
|
require './sap/common.rb'
|
||||||
|
|
||||||
# this is an bastract class
|
# this is an bastract class
|
||||||
# TODO (not implemented) :
|
# TODO (not implemented) :
|
||||||
|
|
|
@ -17,8 +17,8 @@ along with sofSIM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
Copyright (C) 2011 Kevin "tsaitgaist" Redon kevredon@mail.tsaitgaist.info
|
Copyright (C) 2011 Kevin "tsaitgaist" Redon kevredon@mail.tsaitgaist.info
|
||||||
=end
|
=end
|
||||||
require 'sap/server'
|
require './sap/server.rb'
|
||||||
require 'lib/apdu'
|
require './lib/apdu.rb'
|
||||||
require 'socket'
|
require 'socket'
|
||||||
require 'xml'
|
require 'xml'
|
||||||
|
|
||||||
|
|
|
@ -84,7 +84,6 @@ class BluetoothSAPSerial
|
||||||
bt_adapter = bt_service.object(adapter)
|
bt_adapter = bt_service.object(adapter)
|
||||||
bt_adapter.introspect
|
bt_adapter.introspect
|
||||||
bt_adapter.default_iface = "org.bluez.Adapter"
|
bt_adapter.default_iface = "org.bluez.Adapter"
|
||||||
#$stdout.puts bt_abapter_object["org.bluez.Adapter"].Address
|
|
||||||
bt_adapter = bt_adapter.GetProperties()[0]
|
bt_adapter = bt_adapter.GetProperties()[0]
|
||||||
bt_adapters << {
|
bt_adapters << {
|
||||||
:object => adapter,
|
:object => adapter,
|
||||||
|
@ -101,12 +100,12 @@ class BluetoothSAPSerial
|
||||||
elsif bt_adapters.size==1 then
|
elsif bt_adapters.size==1 then
|
||||||
bt_adapter = bt_adapters[0]
|
bt_adapter = bt_adapters[0]
|
||||||
else
|
else
|
||||||
$stdout.puts "multiple bluetooth adapter "
|
$stdout.puts "multiple bluetooth adapter:"
|
||||||
bt_adapters.each_index do |i|
|
bt_adapters.each_index do |i|
|
||||||
bt_adapter = bt_adapters[i]
|
bt_adapter = bt_adapters[i]
|
||||||
$stdout.puts "#{i}) #{bt_adapter[:adapter]} (#{bt_adapter[:address]} - #{bt_adapter[:name]})#{bt_adapter[:default] ? ' [default]' : ''}"
|
$stdout.puts "#{i}) #{bt_adapter[:adapter]} (#{bt_adapter[:address]} - #{bt_adapter[:name]})#{bt_adapter[:default] ? ' [default]' : ''}"
|
||||||
end
|
end
|
||||||
$stdout.print "select adapter : "
|
$stdout.print "select adapter: "
|
||||||
adapter = $stdin.gets.chomp
|
adapter = $stdin.gets.chomp
|
||||||
if adapter.length==0 then
|
if adapter.length==0 then
|
||||||
bt_adapters.each_index do |i|
|
bt_adapters.each_index do |i|
|
||||||
|
@ -153,13 +152,13 @@ class BluetoothSAPSerial
|
||||||
puts "no devices found"
|
puts "no devices found"
|
||||||
exit 0
|
exit 0
|
||||||
end
|
end
|
||||||
$stdout.puts "#{devices.size} device(s) found :"
|
$stdout.puts "#{devices.size} device(s) found:"
|
||||||
devices.each do |address,properties|
|
devices.each do |address,properties|
|
||||||
$stdout.puts "- #{properties["Name"]} (#{properties["Address"]})"
|
$stdout.puts "- #{properties["Name"]} (#{properties["Address"]})"
|
||||||
end
|
end
|
||||||
|
|
||||||
# check for SAP
|
# check for SAP
|
||||||
$stdout.puts "SAP capable devices :"
|
$stdout.puts "SAP capable devices:"
|
||||||
sap_devices = []
|
sap_devices = []
|
||||||
devices.each do |address,properties|
|
devices.each do |address,properties|
|
||||||
|
|
||||||
|
@ -171,7 +170,25 @@ class BluetoothSAPSerial
|
||||||
end
|
end
|
||||||
# get the device (create it if it does not exist)
|
# get the device (create it if it does not exist)
|
||||||
if !device_exists then
|
if !device_exists then
|
||||||
device_object = bt_adapter.CreateDevice(properties["Address"])[0]
|
tries = 3
|
||||||
|
wait_time = 1
|
||||||
|
begin
|
||||||
|
device_object = bt_adapter.CreateDevice(properties["Address"])[0]
|
||||||
|
rescue DBus::Error => e
|
||||||
|
if e.to_s.include? "Host is down" then
|
||||||
|
if tries>0 then
|
||||||
|
puts "host is down, retrying #{tries} in #{wait_time}s"
|
||||||
|
tries -= 1;
|
||||||
|
sleep wait_time;
|
||||||
|
retry
|
||||||
|
else
|
||||||
|
puts "host is down, exiting"
|
||||||
|
exit 1
|
||||||
|
end
|
||||||
|
else
|
||||||
|
raise
|
||||||
|
end
|
||||||
|
end
|
||||||
else
|
else
|
||||||
device_object = bt_adapter.path+"/"+device_object
|
device_object = bt_adapter.path+"/"+device_object
|
||||||
end
|
end
|
||||||
|
@ -203,12 +220,12 @@ class BluetoothSAPSerial
|
||||||
elsif sap_devices.size == 1 then
|
elsif sap_devices.size == 1 then
|
||||||
sap_device = sap_devices[0]
|
sap_device = sap_devices[0]
|
||||||
else
|
else
|
||||||
$stdout.puts "multiple devices possible"
|
$stdout.puts "multiple devices possible:"
|
||||||
sap_devices.each_index do |i|
|
sap_devices.each_index do |i|
|
||||||
$stdout.puts "- #{sap_devices[0][:name]} (#{sap_devices[0][:addr]}"
|
$stdout.puts "#{i}) #{sap_devices[i][:name]} (#{sap_devices[i][:addr]})"
|
||||||
end
|
end
|
||||||
$stdout.print "select device : "
|
$stdout.print "select device: "
|
||||||
sap_device = $stdin.gets.chomp
|
sap_device = $stdin.gets.chomp.to_i
|
||||||
sap_device = sap_devices[sap_device]
|
sap_device = sap_devices[sap_device]
|
||||||
end
|
end
|
||||||
$stdout.puts "using device #{sap_device[:name]} (#{sap_device[:addr]})"
|
$stdout.puts "using device #{sap_device[:name]} (#{sap_device[:addr]})"
|
||||||
|
@ -243,16 +260,16 @@ class BluetoothSAPSerial
|
||||||
unless @paired then
|
unless @paired then
|
||||||
$stdout.puts "enter PIN (16 digits) on the device, then confirm it on the computer"
|
$stdout.puts "enter PIN (16 digits) on the device, then confirm it on the computer"
|
||||||
end
|
end
|
||||||
|
|
||||||
# connect to device
|
# connect to device
|
||||||
@bt_sap.default_iface = "org.bluez.Serial"
|
@bt_sap.default_iface = "org.bluez.Serial"
|
||||||
begin
|
begin
|
||||||
@rfcomm = @bt_sap.Connect(SAP_UUID)[0]
|
@rfcomm = @bt_sap.Connect(SAP_UUID)[0]
|
||||||
rescue DBus::Error => e
|
rescue DBus::Error => e
|
||||||
if e.to_s == "org.bluez.Error.Failed: Connection refused (111)" then
|
if e.to_s.include? "Connection refused (111)" then
|
||||||
$stderr.puts "Connection to device failed. Restarting the device might help"
|
$stderr.puts "Connection to device failed. Restarting the device might help"
|
||||||
exit 1
|
exit 1
|
||||||
elsif e.to_s == "org.bluez.Error.Failed: Connection timed out" then
|
elsif e.to_s.include? "Connection timed out" then
|
||||||
$stderr.puts "Device does not respond to connection request"
|
$stderr.puts "Device does not respond to connection request"
|
||||||
exit 1
|
exit 1
|
||||||
else
|
else
|
||||||
|
|
Loading…
Reference in New Issue