p3 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. checksums.yaml +4 -4
  2. data/lib/p3.rb +178 -0
  3. metadata +1 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 16ce329ad2b6feeaf74bddc1e3d724f33d0dd4a7
4
- data.tar.gz: 5149473c7dcea16ed55a4b030b9871fe7684641e
3
+ metadata.gz: b7eb67b801a8b88a152d7a5a0d5b0266c4a3ee38
4
+ data.tar.gz: 4dfcd78e495231a0ba38a2d74d6da1c5d2b70beb
5
5
  SHA512:
6
- metadata.gz: 507cccca935c32b2460b4105f196ad0138c82a94f4813f6204ee7a13d3f223ef84b3023606a327cea6f1550a2fb05283a1320d3bbb51c6ce1bdb4296f48d38a0
7
- data.tar.gz: 07ea979133ba9455b29a709678db05a774f880bf6c9c78e20cf0b2a9cf4aa3ef12ea0a6c87ce11d2d42be815250173ad7714b530b794859f7583254d11fa7134
6
+ metadata.gz: 6f26b62209d05fa4264c3f98234f4457bad5164f2412a777e6c19dd8ae52a30adb5960fd39f5d6be5c4aa9fca41d01d751c067631b3dcd50abbfb9ad4c1a6f95
7
+ data.tar.gz: 9923ae7b08f012316bd25882739de4b3efe010a3d0e459827ef6712c0327d4e8e610ed2738041b54bf5824e3334b73eafbe1fb73582848f97ca26e2c0f26e463
data/lib/p3.rb CHANGED
@@ -1 +1,179 @@
1
+ #!/usr/bin/env ruby
2
+ #encoding: UTF-8
1
3
 
4
+ require "pp"
5
+ require 'socket'
6
+
7
+ class P3
8
+
9
+ P3_START='~'.ord
10
+ P3_END='~'.ord
11
+ P3_ESC='#'.ord
12
+
13
+ def initialize(hash={},&block)
14
+ @p3mode=false
15
+ @p3start=0
16
+ @p3buf=[]
17
+ @p3esc=false
18
+ @clients={}
19
+ @block=block
20
+ end
21
+
22
+ def unpack buf #buils object from packet byte array
23
+ blen=buf.size
24
+ #puts "GOT: buf<#{buf}> buflen=#{buf.size}"
25
+ return if blen<4
26
+ check2=0
27
+ buf[0...blen-1].each do |b|
28
+ check2^=b
29
+ end
30
+ i=0
31
+ proto=buf[i].chr
32
+ i+=1
33
+ mac=sprintf "%02X:%02X",buf[i],buf[i+1]
34
+ i+=4
35
+ ip=sprintf "%d.%d.%d.%d",buf[i+3],buf[i+2],buf[i+1],buf[i]
36
+ i+=4
37
+ port=buf[i]*0x100+buf[i+1]
38
+ i+=2
39
+ len=buf[i]
40
+ i+=1
41
+ check=buf[i+len]
42
+ data=buf[i...i+len]
43
+ pac={
44
+ proto:proto,
45
+ mac: mac,
46
+ ip: ip,
47
+ port:port,
48
+ data:data,
49
+ }
50
+ #puts "proto=#{proto},mac=#{mac},ip=#{ip},socket=#{socket},len=#{len},check=#{check}==#{check2},data='#{data.pack("C*")}'"
51
+ end
52
+
53
+
54
+
55
+ def pack pac #builds p3 packet from pac object
56
+ #pp pac
57
+ begin
58
+ buf=[]
59
+ buf<<pac[:proto].ord
60
+ macs=pac[:mac].split(":")
61
+ buf<<macs[0].to_i(16)
62
+ buf<<macs[1].to_i(16)
63
+ buf<<0
64
+ buf<<0
65
+ ips=pac[:ip].split(".")
66
+ buf<<ips[3].to_i
67
+ buf<<ips[2].to_i
68
+ buf<<ips[1].to_i
69
+ buf<<ips[0].to_i
70
+ buf<<pac[:port]/0x100
71
+ buf<<(pac[:port]&0xff)
72
+ buf<<pac[:data].size
73
+ buf+=pac[:data].unpack("C*")
74
+ check=0
75
+ buf.each do |b|
76
+ check^=b
77
+ end
78
+ buf<<check
79
+ #pp buf
80
+ #pp "~#{buf.pack("C*")}~"
81
+ return "~#{buf.pack("C*")}~"
82
+ rescue => e
83
+ p e
84
+ p e.backtrace
85
+ end
86
+ return nil
87
+ end
88
+
89
+ def p3_packet_in buf
90
+ #puts "packet in #{buf}"
91
+ pac= unpack buf
92
+ return if not pac
93
+ pp pac
94
+ pp @clients
95
+ if pac[:proto]=="U"
96
+ if not @clients[pac[:mac]]
97
+ puts "new client #{pac[:mac]}"
98
+ @clients[pac[:mac]]={socket: UDPSocket.new,created:Time.now,count_r:0, count_s:0}
99
+ @clients[pac[:mac]][:thread]=Thread.new(pac[:mac]) do |my_mac|
100
+ loop do
101
+ begin
102
+ r,stuff=@clients[my_mac][:socket].recvfrom(2000) #get_packet --high level func!
103
+ ip=stuff[2]
104
+ port=stuff[1]
105
+ #puts "got reply '#{r}' from server #{ip}:#{port} to our mac #{my_mac}"
106
+ pac={
107
+ proto:'U',
108
+ mac: my_mac,
109
+ ip: ip,
110
+ port:port,
111
+ data:r,
112
+ }
113
+ #pp pac
114
+ # received return packet from server!
115
+ if @block
116
+ @block.call pac
117
+ end
118
+ #$sp.write pack pac
119
+ @clients[my_mac][:last_r]=Time.now
120
+ @clients[my_mac][:count_r]+=1
121
+ rescue => e
122
+ puts "thread dies..."
123
+ p e
124
+ p e.backtrace
125
+ end
126
+ end
127
+ end
128
+ pp @clients
129
+ end
130
+ @clients[pac[:mac]][:socket].send(pac[:data].pack("C*"), 0, pac[:ip], pac[:port])
131
+ _,port,_,_ = @clients[pac[:mac]][:socket].addr
132
+ @clients[pac[:mac]][:gw_port]=port
133
+ @clients[pac[:mac]][:last_s]=Time.now
134
+ @clients[pac[:mac]][:count_s]+=1
135
+ pp @clients
136
+ end
137
+ end
138
+
139
+ def shutdown
140
+ @clients.each do |k,c|
141
+ if c[:socket]
142
+ c[:socket].close
143
+ puts "closed #{k}: #{c[:socket]}"
144
+ end
145
+ if c[:thread]
146
+ c[:thread].kill
147
+ puts "killed #{k}: #{c[:thread]}"
148
+ end
149
+ end
150
+ @clients={}
151
+ end
152
+
153
+ def inchar ch
154
+ #puts "got:#{ch}"
155
+ if ch==P3_START and not @p3esc and not @p3mode
156
+ @p3mode=true
157
+ @p3start=Time.now
158
+ @p3buf=[]
159
+ elsif ch==P3_END and not @p3esc and @p3mode
160
+ @p3mode=false
161
+ p3_packet_in @p3buf
162
+ @p3buf=[]
163
+ else
164
+ if not @p3mode
165
+ return false #not done, please process .. show to user
166
+ else
167
+ if @p3esc
168
+ @p3esc=false
169
+ elsif ch==P3_ESC
170
+ @p3esc=true
171
+ return
172
+ end
173
+ @p3buf<<ch
174
+ end
175
+ end
176
+ return true #char was done -- do not process
177
+ end
178
+
179
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: p3
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ari Siitonen