Class: SolverAggregator

Inherits:
Object
  • Object
show all
Defined in:
lib/libowl/solver_aggregator.rb

Constant Summary collapse

KEEP_ALIVE =

Message constants

0
CERTIFICATE =
1
ACK_CERTIFICATE =

There is no message for certificate denial

2
SUBSCRIPTION_REQUEST =
3
SUBSCRIPTION_RESPONSE =
4
DEVICE_POSITION =
5
SERVER_SAMPLE =
6
BUFFER_OVERRUN =
7

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(host, port) ⇒ SolverAggregator

Returns a new instance of SolverAggregator.



25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/libowl/solver_aggregator.rb', line 25

def initialize(host, port)
  @connected = false
  @host = host
  @port = port
  @socket = TCPSocket.open(host, port)
  handshake = ""
  ver_string = "GRAIL solver protocol"
  #The handshake is the length of the message, the protocol string, and the version (0).
  handshake << [ver_string.length].pack('N') << ver_string << "\x00\x00"
  #Receive a handshake and then send one
  @socket.recvfrom(handshake.length)
  @socket.send(handshake, 0)

  @available_packets = []
  @cur_rules = []
end

Instance Attribute Details

#available_packetsObject

Returns the value of attribute available_packets.



21
22
23
# File 'lib/libowl/solver_aggregator.rb', line 21

def available_packets
  @available_packets
end

#connectedObject

Returns the value of attribute connected.



21
22
23
# File 'lib/libowl/solver_aggregator.rb', line 21

def connected
  @connected
end

#cur_rulesObject

Returns the value of attribute cur_rules.



21
22
23
# File 'lib/libowl/solver_aggregator.rb', line 21

def cur_rules
  @cur_rules
end

Instance Method Details

#closeObject



42
43
44
45
# File 'lib/libowl/solver_aggregator.rb', line 42

def close()
  @socket.close()
  @connected = false
end

#decodeServerSample(inbuff) ⇒ Object

Decode a server sample message



92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/libowl/solver_aggregator.rb', line 92

def decodeServerSample(inbuff)
  if (inbuff != nil)
    phy_layer = inbuff.unpack('C')
    rest = inbuff[1, inbuff.length - 1]
    txid = unpackuint128(rest)
    rxid = unpackuint128(rest[16, rest.length - 1])
    rest = rest[32, rest.length - 1]
    timestamp, rssi = rest.unpack('Gg')
    sense_data = rest[12, rest.length - 1]
    @available_packets.push(SensorSample.new(phy_layer, txid, rxid, timestamp, rssi, sense_data))
  end
end

#decodeSubResponse(inbuff) ⇒ Object

Decode a subscription response and store the current rules in @cur_rules



70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/libowl/solver_aggregator.rb', line 70

def decodeSubResponse(inbuff)
  puts "Got subscription response!"
  num_rules = inbuff.unpack('N')[0]
  rest = inbuff[4, inbuff.length - 1]
  rules = []
  for i in 1..num_rules do
    phy_layer, num_txers = rest.unpack('CN')
    txlist = []
    rest = rest[5, rest.length - 1]
    for j in 1..num_txers do
      txlist.push([rest[0, 16], rest[16, 16]])
      rest = rest[32, rest.length - 1]
    end
    update_interval = unpackuint64(rest)
    rest = rest[8, rest.length - 1]
    rule = AggrRule.new(phy_layer, txlist, update_interval)
    rules.push(rule)
  end
  @cur_rules = rules
end

#handleMessageObject

Handle a message of currently unknown type



48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/libowl/solver_aggregator.rb', line 48

def handleMessage()
  #Get the message length as n unsigned integer
  inlen = (@socket.recvfrom(4)[0]).unpack('N')[0]
  if (nil == inlen) then
    return nil
  end
  inbuff = @socket.recvfrom(inlen)[0]
  #Byte that indicates message type
  control = inbuff.unpack('C')[0]
  case control
  when SUBSCRIPTION_RESPONSE
    decodeSubResponse(inbuff[1, inbuff.length - 1])
    return SUBSCRIPTION_RESPONSE
  when SERVER_SAMPLE
    decodeServerSample(inbuff[1, inbuff.length - 1])
    return SERVER_SAMPLE
  else
    KEEP_ALIVE
  end
end

#sendSubscription(rules) ⇒ Object



105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
# File 'lib/libowl/solver_aggregator.rb', line 105

def sendSubscription(rules)
  #Start assembling a request message
  buff = [SUBSCRIPTION_REQUEST].pack('C')
  #Number of rules
  buff += [rules.length].pack('N')
  for rule in rules do
    buff += [rule.phy_layer].pack('C')
    buff += [rule.txers.length].pack('N')
    #Push each transmitter/mask pair
    for txer in rule.txers do
      buff += txer.id + txer.mask
    end
    buff += packuint64(rule.update_interval)
  end
  #Send the message prepended with the length
  @socket.send("#{[buff.length].pack('N')}#{buff}", 0)

  #Get the subscription response
  handleMessage()
end