Module: Plug::Blit

Includes:
Base
Defined in:
lib/rbkb/plug/blit.rb

Constant Summary collapse

DEFAULT_IPADDR =
"127.0.0.1"
DEFAULT_PORT =
25195
DEFAULT_PROTOCOL =
:TCP
OPCODES =
{
  0 => :squelch,
  1 => :unsquelch,
  2 => :delete,
  5 => :sendmsg,
  6 => :list_peers,

  0xfe => :clear,
  0xff => :kill,
}
SIG =

Blit protocol stuff

"BLT"
BLIT_HANDLERS =

Convenience methods for blit clients


{
  :TCP => lambda {|msg| 
    s=TCPSocket.new(@blit_addr, @blit_port)
    wl=s.write(msg)
    s.close
    return wl
  },
  :UDP => lambda {|msg|
    s=UDPSocket.new
    wl=s.send( msg, 0, @blit_addr, @blit_port)
    s.close
    return wl
  }
}

Instance Attribute Summary collapse

Attributes included from Base

#no_stop_on_unbind, #peers, #tls, #tls_opts, #transport

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Base

#connection_completed, #name, #plug_peer, #plug_receive, #say

Instance Attribute Details

#kindObject

Returns the value of attribute kind.



23
24
25
# File 'lib/rbkb/plug/blit.rb', line 23

def kind
  @kind
end

Class Method Details

.blit_header(op) ⇒ Object



63
64
65
66
# File 'lib/rbkb/plug/blit.rb', line 63

def self.blit_header(op)
  return nil unless opno = OPCODES.invert[op]
  SIG + opno.chr
end

.blit_init(opts = {}) ⇒ Object



188
189
190
191
192
193
194
# File 'lib/rbkb/plug/blit.rb', line 188

def self.blit_init(opts={})
  @blit_addr = (opts[:addr] || DEFAULT_IPADDR)
  @blit_port = (opts[:port] || DEFAULT_PORT)
  proto = (opts[:protocol] || DEFAULT_PROTOCOL)
  @blit_handler = BLIT_HANDLERS[ proto ]
  raise "invalid blit transport protocol" unless @blit_handler
end

.blit_raw(buf) ⇒ Object



205
206
207
208
# File 'lib/rbkb/plug/blit.rb', line 205

def self.blit_raw(buf)
  raise "use blit_init first!" unless self.initialized?
  @blit_handler.call buf
end

.blit_send(data, idx = 0) ⇒ Object



200
201
202
203
# File 'lib/rbkb/plug/blit.rb', line 200

def self.blit_send(data, idx=0)
  msg = make_sendmsg(idx, data)
  blit_raw(msg)
end

.initialized?Boolean

Returns:

  • (Boolean)


196
197
198
# File 'lib/rbkb/plug/blit.rb', line 196

def self.initialized?
  @blit_addr and @blit_port and @blit_handler
end

.make_clearObject



145
146
147
# File 'lib/rbkb/plug/blit.rb', line 145

def self.make_clear
  self.blit_header(:clear)
end

.make_delete(idx = 0) ⇒ Object



153
154
155
156
# File 'lib/rbkb/plug/blit.rb', line 153

def self.make_delete(idx=0)
  self.blit_header(:delete) +
    idx.to_bytes(:big, 2)
end

.make_kill(idx = nil) ⇒ Object



136
137
138
# File 'lib/rbkb/plug/blit.rb', line 136

def self.make_kill(idx=nil)
  self.blit_header(:kill)
end

.make_list_peersObject



165
166
167
# File 'lib/rbkb/plug/blit.rb', line 165

def self.make_list_peers
  self.blit_header(:list_peers)
end

.make_mute(peerno) ⇒ Object



77
78
79
80
# File 'lib/rbkb/plug/blit.rb', line 77

def self.make_mute(peerno)
  self.blit_header(:squelch) +
    peerno.to_bytes(:big, 2)
end

.make_sendmsg(idx, dat) ⇒ Object

Blit packed message format is (SUBJECT TO CHANGE):

"BLT"
char   opcode
uint16be idx   = index of slave peer to send to
uint32le size  = length of data
str      data


124
125
126
127
128
129
# File 'lib/rbkb/plug/blit.rb', line 124

def self.make_sendmsg(idx, dat)
  self.blit_header(:sendmsg) +
    idx.to_bytes(:big, 2) + 
    dat.size.to_bytes(:big, 4) + 
    dat
end

.make_squelch(peerno) ⇒ Object



90
91
92
93
# File 'lib/rbkb/plug/blit.rb', line 90

def self.make_squelch(peerno)
  self.blit_header(:squelch) +
    peerno.to_bytes(:big, 2)
end

Instance Method Details

#clearObject



140
141
142
143
# File 'lib/rbkb/plug/blit.rb', line 140

def clear
  @peers.each { |p| p.close }
  @peers.replace []
end

#delete(peerno) ⇒ Object



149
150
151
# File 'lib/rbkb/plug/blit.rb', line 149

def delete(peerno)
  @peers.delete(peerno)
end

#initbufObject

(re)initializes the blit buffer



47
48
49
# File 'lib/rbkb/plug/blit.rb', line 47

def initbuf
  @buf = StringIO.new
end

#initialize(transport, slave) ⇒ Object



25
26
27
28
29
30
31
32
# File 'lib/rbkb/plug/blit.rb', line 25

def initialize(transport, slave)
  super(transport)

  @kind = :blitsrv
  @slave = slave
  @peers = slave.peers
  initbuf
end

#killObject



131
132
133
134
# File 'lib/rbkb/plug/blit.rb', line 131

def kill
  UI.log("** BLIT-KILL - Received shutdown command")
  EM.stop
end

#list_peersObject



158
159
160
161
162
163
# File 'lib/rbkb/plug/blit.rb', line 158

def list_peers
  UI.log("** BLIT-LISTPEERS - Received list peers command")

  @peers.each_index {|i| UI.log "**   #{i} - #{@peers[i].name}"}
  UI.log("** BLIT-LISTPEERS-END - End of peer list")
end

#muteObject



68
69
70
71
72
73
74
75
# File 'lib/rbkb/plug/blit.rb', line 68

def mute
  unless ( peerno=@buf.read(2) and peerno.size == 2 and
           peer=@peers[peerno.dat_to_num(:big)] )

    UI.log "** BLIT-ERROR(Malformed or missing peer for mute)"
    return true
  end
end

#post_initObject



34
35
36
# File 'lib/rbkb/plug/blit.rb', line 34

def post_init
  # override so we don't get unneccessary "Start" message from Base
end

#receive_data(dat) ⇒ Object



51
52
53
54
55
56
57
58
59
60
# File 'lib/rbkb/plug/blit.rb', line 51

def receive_data dat
  return unless (@buf.write(dat) > SIG.size) or (@buf.pos > (SIG.size + 1))

  @buf.rewind

  return unless @buf.read(SIG.size) == SIG and
                op = OPCODES[ @buf.read(1)[0] ]

  initbuf if self.send(op)
end

#sendmsgObject



95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/rbkb/plug/blit.rb', line 95

def sendmsg
  unless peerno=@buf.read(2) and peerno.size == 2 and
         bufsiz=@buf.read(4) and bufsiz.size == 4
    UI.log "** BLIT-ERROR(Malformed sendmsg)"
    return true
  end

  peerno = peerno.dat_to_num(:big)
  bufsiz = bufsiz.dat_to_num(:big)

  if (rdat=@buf.read(bufsiz)).size == bufsiz
    if peer=@peers[peerno]
      peer.say(rdat, self)
      return true
    else
      UI.log "** BLIT-ERROR(Invalid peer index #{peerno})"
      return true
    end
  else
    return nil
  end
end

#unbindObject



38
39
40
# File 'lib/rbkb/plug/blit.rb', line 38

def unbind
  # override so we don't get unneccessary "closed" message from Base
end

#unmuteObject



82
83
84
85
86
87
88
# File 'lib/rbkb/plug/blit.rb', line 82

def unmute
  unless ( peerno=@buf.read(2) and peerno.size == 2 and
           peer=@peers[peerno.dat_to_num(:big)] )
    UI.log "** BLIT-ERROR(Malformed or missing peer for unmute)"
    return true
  end
end