p3 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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