tochka 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +9 -0
- data/.rspec +2 -0
- data/.travis.yml +4 -0
- data/Gemfile +4 -0
- data/README.md +64 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +7 -0
- data/exe/tochka-miniui +36 -0
- data/exe/tochkad +44 -0
- data/ext/tochka-miniui +62 -0
- data/ext/tochkad +62 -0
- data/lib/tochka/agent.rb +116 -0
- data/lib/tochka/athsurvey.rb +109 -0
- data/lib/tochka/channel.rb +39 -0
- data/lib/tochka/command/tochka-miniui.rb +470 -0
- data/lib/tochka/command/tochkad.rb +209 -0
- data/lib/tochka/log.rb +38 -0
- data/lib/tochka/pitft_button.rb +105 -0
- data/lib/tochka/version.rb +3 -0
- data/lib/tochka/wlan.rb +113 -0
- data/lib/tochka.rb +11 -0
- data/tochka.gemspec +35 -0
- metadata +152 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 40dc9ab742d3ff31b82292795a7b905782210488
|
4
|
+
data.tar.gz: 771f090404e1262e0f0e174ac961e60f0cf099f9
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 4b6b2639eecb4a961fa4de138a456b71d0f03167e67549a37ed8e4a3a3697b85288295923ac1f24207e56e50d11005d1f566f654a98f04f41f4bd47f16d970ad
|
7
|
+
data.tar.gz: a7a73e80b4536856fdb045d4ab911f598a1f5acf28db7ea5a5676053970bb5d171ceecd401b88ae2909313fc8c6d3b54eebd72ea8855a0babe9d46b2b8df7dd4
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
# Tochka
|
2
|
+
|
3
|
+
"Tochka" is softwares to build Wi-Fi frame capturing box with Raspberry Pi + PiTFT.
|
4
|
+
|
5
|
+
Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/tochka`. To experiment with that code, run `bin/console` for an interactive prompt.
|
6
|
+
|
7
|
+
TODO: Delete this and the text above, and describe your gem
|
8
|
+
|
9
|
+
## Installation
|
10
|
+
|
11
|
+
Add this line to your application's Gemfile:
|
12
|
+
|
13
|
+
```ruby
|
14
|
+
gem 'tochka'
|
15
|
+
```
|
16
|
+
|
17
|
+
And then execute:
|
18
|
+
|
19
|
+
$ bundle
|
20
|
+
|
21
|
+
Or install it yourself as:
|
22
|
+
|
23
|
+
$ gem install tochka
|
24
|
+
|
25
|
+
### install init.d scripts
|
26
|
+
|
27
|
+
1. copy ext/tochkad, ext/tochka-miniui into /etc/init.d
|
28
|
+
2. do chmod +x onto both
|
29
|
+
3. do 'update-rc.d <name> defaults' to both
|
30
|
+
|
31
|
+
## Usage
|
32
|
+
|
33
|
+
### PiTFT UI
|
34
|
+
|
35
|
+
Tochka provides with user interface to start/stop capture on top of PiTFT.
|
36
|
+
|
37
|
+
![tochka-miniui](http://amber.glenda9.org/~enukane/images/tochka-miniui.jpg)
|
38
|
+
|
39
|
+
TOUCHSCREEN is currently of NO USE. Just make yourself happy with moving cursor :).
|
40
|
+
Use buttons instead: 4 buttons are "START", "STOP", "MODE1", "MODE2".
|
41
|
+
|
42
|
+
### Starting capture
|
43
|
+
|
44
|
+
Press "START" button and "State" turns into "running"
|
45
|
+
|
46
|
+
### Stop capture
|
47
|
+
|
48
|
+
Press "STOP", "MODE1" and "MODE2" buttons in an order. Check that "stop count" is now 3.
|
49
|
+
Then press "STOP" button again will turn off capturing. The "State" will turn into "stop".
|
50
|
+
|
51
|
+
### collecting captured data
|
52
|
+
|
53
|
+
Captured data (pcapng files) are stored in /cap directory
|
54
|
+
|
55
|
+
## Development
|
56
|
+
|
57
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment. Run `bundle exec tochka` to use the gem in this directory, ignoring other installed copies of this gem.
|
58
|
+
|
59
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
60
|
+
|
61
|
+
## Contributing
|
62
|
+
|
63
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/enukane/tochka.
|
64
|
+
|
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "tochka"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start
|
data/bin/setup
ADDED
data/exe/tochka-miniui
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "tochka"
|
4
|
+
require "optparse"
|
5
|
+
|
6
|
+
opt = OptionParser.new
|
7
|
+
OPTS=Tochka::TochkaMiniUI.default_options
|
8
|
+
|
9
|
+
opt.on('-f', "--font [FONT_PATH]", "font to use (default: #{Tochka::TochkaMiniUI.default_options[:font_path]})") {|v|
|
10
|
+
OPTS[:font_path] = v
|
11
|
+
}
|
12
|
+
|
13
|
+
opt.on('-l', "--log-file [LOG_FILE=STDOUT]",
|
14
|
+
"log output file (accepts 'STDOUT', 'STDERR')") {|v|
|
15
|
+
OPTS[:log_file] = v
|
16
|
+
}
|
17
|
+
|
18
|
+
(class<<self;self;end).module_eval do
|
19
|
+
define_method(:usage) do |msg|
|
20
|
+
puts opt.to_s
|
21
|
+
puts "error: #{msg}" if msg
|
22
|
+
exit 1
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
begin
|
27
|
+
res = opt.parse(ARGV)
|
28
|
+
if res.length != 0
|
29
|
+
usage nil
|
30
|
+
end
|
31
|
+
rescue
|
32
|
+
usage $!.to_s
|
33
|
+
end
|
34
|
+
|
35
|
+
$log = Log.new(:output => OPTS[:log_file])
|
36
|
+
Tochka::TochkaMiniUI.new(OPTS[:font_path]).run
|
data/exe/tochkad
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "tochka"
|
4
|
+
require "optparse"
|
5
|
+
|
6
|
+
opt = OptionParser.new
|
7
|
+
OPTS=Tochka::Daemon.default_options
|
8
|
+
|
9
|
+
opt.on('-i', "--interface [IFNAME=#{Tochka::Daemon::DEFAULT_IFNAME}]",
|
10
|
+
"interface to capture") {|v|
|
11
|
+
OPTS[:ifname] = v || Tochka::Daemon::DEFAULT_IFNAME
|
12
|
+
}
|
13
|
+
|
14
|
+
opt.on('-c', "--cap-dir [CAP_PATH=#{Tochka::Daemon::DEFAULT_CAP_PATH}]",
|
15
|
+
"capture directory") {|v|
|
16
|
+
OPTS[:cap_path] = v || TOchka::Daemon::DEFAULT_CAP_PATH
|
17
|
+
}
|
18
|
+
|
19
|
+
opt.on('-l', "--log-file [LOG_FILE=STDOUT]",
|
20
|
+
"log output file (accepts 'STDOUT', 'STDERR')") {|v|
|
21
|
+
OPTS[:log_file] = v
|
22
|
+
}
|
23
|
+
|
24
|
+
(class<<self;self;end).module_eval do
|
25
|
+
define_method(:usage) do |msg|
|
26
|
+
puts opt.to_s
|
27
|
+
puts "error: #{msg}" if msg
|
28
|
+
exit 1
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
begin
|
33
|
+
rest = opt.parse(ARGV)
|
34
|
+
if rest.length != 0
|
35
|
+
usage nil
|
36
|
+
end
|
37
|
+
rescue
|
38
|
+
usage $!.to_s
|
39
|
+
end
|
40
|
+
|
41
|
+
# check root priviledge
|
42
|
+
|
43
|
+
$log = Log.new(:output => OPTS[:log_file])
|
44
|
+
Tochka::Daemon.new(OPTS[:ifname], OPTS[:cap_path]).run
|
data/ext/tochka-miniui
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
#!/bin/sh
|
2
|
+
|
3
|
+
### BEGIN INIT INFO
|
4
|
+
# Provides: tochka-mini
|
5
|
+
# Required-Start: $remote_fs $syslog
|
6
|
+
# Required-Stop: $remote_fs $syslog
|
7
|
+
# Default-Start: 2 3 4 5
|
8
|
+
# Default-Stop: 0 1 6
|
9
|
+
# Short-Description: Put a short description of the service here
|
10
|
+
# Description: Put a long description of the service here
|
11
|
+
### END INIT INFO
|
12
|
+
|
13
|
+
# Change the next 3 lines to suit where you install your script and what you want to call it
|
14
|
+
DIR=/usr/local/bin/
|
15
|
+
DAEMON=$DIR/tochka-miniui
|
16
|
+
DAEMON_NAME=tochka-miniui
|
17
|
+
|
18
|
+
# Add any command line options for your daemon here
|
19
|
+
DAEMON_OPTS="-l /tmp/hoge"
|
20
|
+
|
21
|
+
# This next line determines what user the script runs as.
|
22
|
+
# Root generally not recommended but necessary if you are using the Raspberry Pi GPIO from Python.
|
23
|
+
DAEMON_USER=root
|
24
|
+
|
25
|
+
# The process ID of the script when it runs is stored here:
|
26
|
+
PIDFILE=/var/run/$DAEMON_NAME.pid
|
27
|
+
|
28
|
+
. /lib/lsb/init-functions
|
29
|
+
|
30
|
+
do_start () {
|
31
|
+
log_daemon_msg "Starting system $DAEMON_NAME daemon"
|
32
|
+
start-stop-daemon --start --background --pidfile $PIDFILE --user $DAEMON_USER --chuid $DAEMON_USER --startas $DAEMON -- $DAEMON_OPTS
|
33
|
+
log_end_msg $?
|
34
|
+
}
|
35
|
+
do_stop () {
|
36
|
+
log_daemon_msg "Stopping system $DAEMON_NAME daemon"
|
37
|
+
start-stop-daemon --stop --pidfile $PIDFILE --retry 10
|
38
|
+
log_end_msg $?
|
39
|
+
}
|
40
|
+
|
41
|
+
case "$1" in
|
42
|
+
|
43
|
+
start|stop)
|
44
|
+
do_${1}
|
45
|
+
;;
|
46
|
+
|
47
|
+
restart|reload|force-reload)
|
48
|
+
do_stop
|
49
|
+
do_start
|
50
|
+
;;
|
51
|
+
|
52
|
+
status)
|
53
|
+
status_of_proc "$DAEMON_NAME" "$DAEMON" && exit 0 || exit $?
|
54
|
+
;;
|
55
|
+
|
56
|
+
*)
|
57
|
+
echo "Usage: /etc/init.d/$DAEMON_NAME {start|stop|restart|status}"
|
58
|
+
exit 1
|
59
|
+
;;
|
60
|
+
|
61
|
+
esac
|
62
|
+
exit 0
|
data/ext/tochkad
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
#!/bin/sh
|
2
|
+
|
3
|
+
### BEGIN INIT INFO
|
4
|
+
# Provides: tochkad
|
5
|
+
# Required-Start: $remote_fs $syslog
|
6
|
+
# Required-Stop: $remote_fs $syslog
|
7
|
+
# Default-Start: 2 3 4 5
|
8
|
+
# Default-Stop: 0 1 6
|
9
|
+
# Short-Description: Put a short description of the service here
|
10
|
+
# Description: Put a long description of the service here
|
11
|
+
### END INIT INFO
|
12
|
+
|
13
|
+
# Change the next 3 lines to suit where you install your script and what you want to call it
|
14
|
+
DIR=/usr/local/bin/
|
15
|
+
DAEMON=$DIR/tochkad
|
16
|
+
DAEMON_NAME=tochkad
|
17
|
+
|
18
|
+
# Add any command line options for your daemon here
|
19
|
+
DAEMON_OPTS=""
|
20
|
+
|
21
|
+
# This next line determines what user the script runs as.
|
22
|
+
# Root generally not recommended but necessary if you are using the Raspberry Pi GPIO from Python.
|
23
|
+
DAEMON_USER=root
|
24
|
+
|
25
|
+
# The process ID of the script when it runs is stored here:
|
26
|
+
PIDFILE=/var/run/$DAEMON_NAME.pid
|
27
|
+
|
28
|
+
. /lib/lsb/init-functions
|
29
|
+
|
30
|
+
do_start () {
|
31
|
+
log_daemon_msg "Starting system $DAEMON_NAME daemon"
|
32
|
+
start-stop-daemon --start --background --pidfile $PIDFILE --user $DAEMON_USER --chuid $DAEMON_USER --startas $DAEMON -- $DAEMON_OPTS
|
33
|
+
log_end_msg $?
|
34
|
+
}
|
35
|
+
do_stop () {
|
36
|
+
log_daemon_msg "Stopping system $DAEMON_NAME daemon"
|
37
|
+
start-stop-daemon --stop --pidfile $PIDFILE --retry 10
|
38
|
+
log_end_msg $?
|
39
|
+
}
|
40
|
+
|
41
|
+
case "$1" in
|
42
|
+
|
43
|
+
start|stop)
|
44
|
+
do_${1}
|
45
|
+
;;
|
46
|
+
|
47
|
+
restart|reload|force-reload)
|
48
|
+
do_stop
|
49
|
+
do_start
|
50
|
+
;;
|
51
|
+
|
52
|
+
status)
|
53
|
+
status_of_proc "$DAEMON_NAME" "$DAEMON" && exit 0 || exit $?
|
54
|
+
;;
|
55
|
+
|
56
|
+
*)
|
57
|
+
echo "Usage: /etc/init.d/$DAEMON_NAME {start|stop|restart|status}"
|
58
|
+
exit 1
|
59
|
+
;;
|
60
|
+
|
61
|
+
esac
|
62
|
+
exit 0
|
data/lib/tochka/agent.rb
ADDED
@@ -0,0 +1,116 @@
|
|
1
|
+
module Tochka
|
2
|
+
require "json"
|
3
|
+
require "socket"
|
4
|
+
require "tochka/log"
|
5
|
+
|
6
|
+
class Agent
|
7
|
+
attr_reader :state, :file_name, :file_size, :duration, :current_channel, :frame_count, :channel_walk, :utilization, :utilization_channel
|
8
|
+
SOCKPATH="/var/run/captured.sock"
|
9
|
+
|
10
|
+
CMD_GET_STATUS="get_status"
|
11
|
+
CMD_START_CAPTURE="start_capture"
|
12
|
+
CMD_STOP_CAPTURE="stop_capture"
|
13
|
+
|
14
|
+
STATE_INIT="init"
|
15
|
+
STATE_RUNNING="running"
|
16
|
+
STATE_STOP="stop"
|
17
|
+
STATE_UNKNOWN="unknown"
|
18
|
+
|
19
|
+
def initialize
|
20
|
+
@state = STATE_INIT
|
21
|
+
@file_name = "<None>"
|
22
|
+
@file_size = 0
|
23
|
+
@duration = 0
|
24
|
+
@current_channel = 0
|
25
|
+
@channel_walk = 0
|
26
|
+
@frame_count = 0
|
27
|
+
@utilization = 0
|
28
|
+
@utilization_channel = 0
|
29
|
+
end
|
30
|
+
|
31
|
+
def get_status
|
32
|
+
resp = do_rpc(get_msg(CMD_GET_STATUS))
|
33
|
+
if resp["state"] != nil
|
34
|
+
update_state(resp)
|
35
|
+
return resp
|
36
|
+
end
|
37
|
+
|
38
|
+
# not responded?
|
39
|
+
@state = STATE_UNKNOWN
|
40
|
+
return {}
|
41
|
+
rescue => e
|
42
|
+
$log.err("agent detected unknown error in get_status (#{e})")
|
43
|
+
return {}
|
44
|
+
end
|
45
|
+
|
46
|
+
def start_capture
|
47
|
+
$log.info("requesting start_capture")
|
48
|
+
resp = do_rpc(get_msg(CMD_START_CAPTURE))
|
49
|
+
resp = get_status()
|
50
|
+
if resp["state"] == STATE_RUNNING
|
51
|
+
update_state(resp)
|
52
|
+
return true
|
53
|
+
end
|
54
|
+
|
55
|
+
# not responded or failed
|
56
|
+
@state = STATE_UNKNOWN
|
57
|
+
return false
|
58
|
+
rescue => e
|
59
|
+
$log.err("agent detected unknown error in start_capture (#{e})")
|
60
|
+
return false
|
61
|
+
end
|
62
|
+
|
63
|
+
def stop_capture
|
64
|
+
$log.info("requesting stop_capture")
|
65
|
+
resp = do_rpc(get_msg(CMD_STOP_CAPTURE))
|
66
|
+
resp = get_status()
|
67
|
+
if resp["state"] == STATE_STOP
|
68
|
+
update_state(resp)
|
69
|
+
return true
|
70
|
+
end
|
71
|
+
|
72
|
+
return false
|
73
|
+
rescue => e
|
74
|
+
$log.err("agent detected unknown error in stop_capture (#{e})")
|
75
|
+
return false
|
76
|
+
end
|
77
|
+
|
78
|
+
private
|
79
|
+
def get_msg type=CMD_GET_STATUS
|
80
|
+
JSON.dump(
|
81
|
+
{"command"=> type}
|
82
|
+
)
|
83
|
+
end
|
84
|
+
|
85
|
+
def do_rpc req_json_msg
|
86
|
+
data = {}
|
87
|
+
UNIXSocket.open(SOCKPATH) do |sock|
|
88
|
+
sock.write(req_json_msg+"\n")
|
89
|
+
data = sock.gets
|
90
|
+
end
|
91
|
+
return JSON.parse(data)
|
92
|
+
rescue Errno::EPIPE => e
|
93
|
+
$log.err("RPC failed in do_rpc (EPIPE)")
|
94
|
+
return {}
|
95
|
+
rescue JSON::ParserError => e0
|
96
|
+
$log.err("RPC failed in do_rpc (JSON parser error)")
|
97
|
+
return {}
|
98
|
+
rescue Errno::ENOENT => e1
|
99
|
+
$log.err("RPC failed in do_rpc (no sock file, #{e1})")
|
100
|
+
return {}
|
101
|
+
end
|
102
|
+
|
103
|
+
def update_state msg
|
104
|
+
@state = msg["state"]
|
105
|
+
@file_name = msg["file_name"]
|
106
|
+
@file_size = msg["file_size"]
|
107
|
+
@duration = msg["duration"]
|
108
|
+
@current_channel = msg["current_channel"]
|
109
|
+
@channel_walk = msg["channel_walk"]
|
110
|
+
@frame_count = msg["frame_count"]
|
111
|
+
@utilization = msg["utilization"]
|
112
|
+
@utilization_channel = msg["utilization_channel"]
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
end
|
@@ -0,0 +1,109 @@
|
|
1
|
+
module Tochka
|
2
|
+
class Athsurvey
|
3
|
+
FREQ2CHAN = {
|
4
|
+
0 => 0, # why radiotap.channel.freq can be 0?
|
5
|
+
# 2.4GHz
|
6
|
+
2412 => 1,
|
7
|
+
2417 => 2,
|
8
|
+
2422 => 3,
|
9
|
+
2427 => 4,
|
10
|
+
2432 => 5,
|
11
|
+
2437 => 6,
|
12
|
+
2442 => 7,
|
13
|
+
2447 => 8,
|
14
|
+
2452 => 9,
|
15
|
+
2457 => 10,
|
16
|
+
2462 => 11,
|
17
|
+
2467 => 12,
|
18
|
+
2472 => 13,
|
19
|
+
2484 => 14,
|
20
|
+
|
21
|
+
# japan client only
|
22
|
+
5170 => 34,
|
23
|
+
5190 => 38,
|
24
|
+
5210 => 42,
|
25
|
+
5230 => 46,
|
26
|
+
|
27
|
+
# W52
|
28
|
+
5180 => 36,
|
29
|
+
5200 => 40,
|
30
|
+
5220 => 44,
|
31
|
+
5240 => 48,
|
32
|
+
|
33
|
+
# W53
|
34
|
+
5260 => 52,
|
35
|
+
5280 => 56,
|
36
|
+
5300 => 60,
|
37
|
+
5320 => 64,
|
38
|
+
|
39
|
+
# W56
|
40
|
+
5500 => 100,
|
41
|
+
5520 => 104,
|
42
|
+
5540 => 108,
|
43
|
+
5560 => 112,
|
44
|
+
5580 => 116,
|
45
|
+
5600 => 120,
|
46
|
+
5620 => 124,
|
47
|
+
5640 => 128,
|
48
|
+
5660 => 132,
|
49
|
+
5680 => 136,
|
50
|
+
5700 => 140,
|
51
|
+
5745 => 149,
|
52
|
+
5765 => 153,
|
53
|
+
5785 => 157,
|
54
|
+
5805 => 161,
|
55
|
+
5825 => 165,
|
56
|
+
|
57
|
+
|
58
|
+
# 802.11j
|
59
|
+
4920 => 184,
|
60
|
+
4940 => 188,
|
61
|
+
4960 => 192,
|
62
|
+
4980 => 194,
|
63
|
+
}
|
64
|
+
|
65
|
+
REG_FREQ=/^\s*frequency:\s+(\d+) /
|
66
|
+
REG_ACTIVE=/^\s*channel active time:\s+(\d+) (|m)s$/
|
67
|
+
REG_BUSY=/^\s*channel busy time:\s+(\d+) (|m)s$/
|
68
|
+
|
69
|
+
def initialize ifname
|
70
|
+
@ifname = ifname
|
71
|
+
end
|
72
|
+
|
73
|
+
def current_data
|
74
|
+
str = get_survey_dump()
|
75
|
+
active = 0
|
76
|
+
busy = 0
|
77
|
+
channel = 0
|
78
|
+
|
79
|
+
str.split("\n").map{|line| line.strip}.each do |line|
|
80
|
+
case line
|
81
|
+
when REG_FREQ
|
82
|
+
channel = FREQ2CHAN[$1.to_i]
|
83
|
+
when REG_ACTIVE
|
84
|
+
active = $1.to_i
|
85
|
+
active *= 1000 if $2 != "m"
|
86
|
+
when REG_BUSY
|
87
|
+
busy = $1.to_i
|
88
|
+
busy *= 1000 if $2 != "m"
|
89
|
+
end
|
90
|
+
end
|
91
|
+
return [0, 0, 0, 0] if active == 0
|
92
|
+
|
93
|
+
return [channel, active, busy, fto2f(busy.to_f * 100 / active.to_f) ]
|
94
|
+
end
|
95
|
+
|
96
|
+
def get_survey_dump
|
97
|
+
return `iw #{@ifname} survey dump | grep -A 4 "in use"`
|
98
|
+
end
|
99
|
+
|
100
|
+
def fto2f f
|
101
|
+
return (f * 100).to_i.to_f / 100
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
if __FILE__ == $0
|
107
|
+
aths = Tochka::Athsurvey.new("wlan0")
|
108
|
+
p aths.current_data
|
109
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Tochka
|
2
|
+
require "socket"
|
3
|
+
|
4
|
+
class Channel
|
5
|
+
def initialize recv_handler, sock_data
|
6
|
+
end
|
7
|
+
|
8
|
+
def start
|
9
|
+
end
|
10
|
+
|
11
|
+
def stop
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
class UnixSocketChannel < Channel
|
16
|
+
SOCKPATH="/var/run/captured.sock"
|
17
|
+
|
18
|
+
def initialize recv_handler, sock_path=SOCKPATH
|
19
|
+
@recv_handler = recv_handler
|
20
|
+
@sock_path = sock_path || SOCKPATH
|
21
|
+
@th = nil
|
22
|
+
end
|
23
|
+
|
24
|
+
def start
|
25
|
+
@th = Thread.new do
|
26
|
+
Socket.unix_server_loop(@sock_path) do |sock, addr|
|
27
|
+
data = sock.gets
|
28
|
+
resp = @recv_handler.call(data)
|
29
|
+
sock.write(resp+"\n")
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def stop
|
35
|
+
@th.kill
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|