Class: ScanBeacon::BLE112Device

Inherits:
Object
  • Object
show all
Defined in:
lib/scan_beacon/ble112_device.rb

Defined Under Namespace

Classes: BLE112Response

Constant Summary collapse

BG_COMMAND =

define a bunch of constants

0
BG_EVENT =
0x80
BG_MSG_CLASS_SYSTEM =

msg classes

0
BG_MSG_CLASS_CONNECTION =
3
BG_MSG_CLASS_GAP =
6
BG_RESET =

messages

0
BG_DISCONNECT =
0
BG_SET_MODE =
1
BG_GAP_SET_PRIVACY_FLAGS =
0
BG_GAP_SET_ADV_PARAM =
8
BG_GAP_SET_ADV_DATA =
9
BG_DISCOVER =
2
BG_DISCOVER_STOP =
4
BG_SCAN_PARAMS =
7
BG_GAP_DISCOVER_ALL =

constants/enums

2
BG_GAP_NON_DISCOVERABLE =
0
BG_GAP_NON_CONNECTABLE =
0
BG_GAP_USER_DATA =
4
BG_GAP_CONNECTABLE =
2

Instance Method Summary collapse

Constructor Details

#initialize(port = nil) ⇒ BLE112Device



29
30
31
# File 'lib/scan_beacon/ble112_device.rb', line 29

def initialize(port=nil)
  @port = port || Dir.glob("/dev/{cu.usbmodem,ttyACM}*")[0]
end

Instance Method Details

#configure_portObject



42
43
44
45
46
# File 'lib/scan_beacon/ble112_device.rb', line 42

def configure_port
  if RUBY_PLATFORM =~ /linux/
    system("stty -F #{@port} 115200 raw -brkint -icrnl -imaxbel -opost -isig -icanon -iexten -echo -echoe -echok -echoctl -echoke")
  end
end

#openObject



33
34
35
36
37
38
39
40
# File 'lib/scan_beacon/ble112_device.rb', line 33

def open
  configure_port
  File.open(@port, 'r+b') do |file|
    @file = file
    yield self
  end
  @file = nil
end

#readObject



98
99
100
# File 'lib/scan_beacon/ble112_device.rb', line 98

def read
  BLE112Response.new( bg_read(@file) )
end

#resetObject



102
103
104
105
106
107
108
109
# File 'lib/scan_beacon/ble112_device.rb', line 102

def reset
  open do
    @file.write([BG_COMMAND, 1, BG_MSG_CLASS_SYSTEM, BG_RESET, 0].pack('C*'))
  end
  # give time for the device to reboot.
  # TODO: figure out a way that doesn't involve sleeping arbitrarily.
  sleep 1
end

#rotate_addrObject



86
87
88
89
90
91
92
# File 'lib/scan_beacon/ble112_device.rb', line 86

def rotate_addr
  # set peripheral into private mode is not needed, as the mac is rotated every time gap_set_mode is called
  bg_command(@file, BG_MSG_CLASS_GAP, BG_GAP_SET_PRIVACY_FLAGS, [1, 0])

  # set gap mode
  bg_command(@file, BG_MSG_CLASS_GAP, BG_SET_MODE, [BG_GAP_USER_DATA, BG_GAP_CONNECTABLE])
end

#start_advertising(ad_data, privacy = false) ⇒ Object



65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/scan_beacon/ble112_device.rb', line 65

def start_advertising(ad_data, privacy = false)
  # disconnect any connections
  bg_command(@file, BG_MSG_CLASS_CONNECTION, BG_DISCONNECT,0)

  # set advertising interval 0x00A0 = 100 ms interval, 7 = all channels
  bg_command(@file, BG_MSG_CLASS_GAP, BG_GAP_SET_ADV_PARAM, [0xA0, 0x00, 0xA0, 0x00, 7])

  # set privacy mode (rotate bluetooth address)
  if privacy
    bg_command(@file, BG_MSG_CLASS_GAP, BG_GAP_SET_PRIVACY_FLAGS, [1, 0])
  end

  # add flags header
  ad_data = "\x02\x01\x06" + ad_data
  ad_data = [0,ad_data.size].pack("C*") + ad_data

  stop_advertising
  bg_command(@file, BG_MSG_CLASS_GAP, BG_GAP_SET_ADV_DATA, ad_data.unpack("C*"))
  bg_command(@file, BG_MSG_CLASS_GAP, BG_SET_MODE, [BG_GAP_USER_DATA, BG_GAP_CONNECTABLE])
end

#start_scanObject



48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/scan_beacon/ble112_device.rb', line 48

def start_scan
  # disconnect any connections
  bg_command(@file, BG_MSG_CLASS_CONNECTION, BG_DISCONNECT,0)
  # turn off adverts
  bg_command(@file, BG_MSG_CLASS_GAP, BG_SET_MODE, [BG_GAP_NON_DISCOVERABLE, BG_GAP_NON_CONNECTABLE])
  # stop previous scan
  bg_command(@file, BG_MSG_CLASS_GAP, BG_DISCOVER_STOP)
  # write new scan params
  bg_command(@file, BG_MSG_CLASS_GAP, BG_SCAN_PARAMS, [200,200, 0], "S<S<C")
  # start new scan
  bg_command(@file, BG_MSG_CLASS_GAP, BG_DISCOVER, BG_GAP_DISCOVER_ALL)
end

#stop_advertisingObject



94
95
96
# File 'lib/scan_beacon/ble112_device.rb', line 94

def stop_advertising
  bg_command(@file, BG_MSG_CLASS_GAP, BG_SET_MODE, [BG_GAP_NON_DISCOVERABLE, BG_GAP_NON_CONNECTABLE])
end

#stop_scanObject



61
62
63
# File 'lib/scan_beacon/ble112_device.rb', line 61

def stop_scan
  bg_command(@file, BG_MSG_CLASS_GAP, BG_DISCOVER_STOP)
end