#!/usr/bin/env ruby # frozen_string_literal: false require 'pwn' require 'optparse' opts = {} OptionParser.new do |options| options.banner = "USAGE: #{$PROGRAM_NAME} [opts] " options.on('-tFREQ', '--target-freq=FREQ', '') do |s| opts[:start_freq] = s end options.on('-dMODE', '--demodulator-mode=MODE', '') do |d| opts[:demodulator_mode] = d end options.on('-sFREQ', '--start-freq=FREQ', '') do |s| opts[:start_freq] = s end options.on('-hHOST', '--host=HOST', '') do |h| opts[:host] = h end options.on('-pPORT', '--port=PORT', '') do |p| opts[:port] = p end end.parse! if opts.empty? puts `#{$PROGRAM_NAME} --help` exit 1 end def gqrx_cmd(opts = {}) # f - Get frequency [Hz] # F - Set frequency [Hz] # m - Get demodulator mode # M - Set demodulator mode (OFF, RAW, AM, FM, WFM, WFM_ST, # WFM_ST_OIRT, LSB, USB, CW, CWL, CWU) # l STRENGTH - Get signal strength [dBFS] # l SQL - Get squelch threshold [dBFS] # L SQL - Set squelch threshold to [dBFS] # u RECORD - Get status of audio recorder # U RECORD - Set status of audio recorder to # c - Close connection # AOS - Acquisition of signal (AOS) event, start audio recording # LOS - Loss of signal (LOS) event, stop audio recording # \dump_state - Dump state (only usable for compatibility) gqrx_sock = opts[:gqrx_sock] cmd = opts[:cmd] gqrx_sock.write("#{cmd}\n") does_respond = gqrx_sock.wait_readable gqrx_sock.readline.chomp if does_respond end begin pwn_provider = 'ruby-gem' pwn_provider = ENV.fetch('PWN_PROVIDER') if ENV.keys.any? { |s| s == 'PWN_PROVIDER' } demodulator_mode = opts[:demodulator_mode] ||= 'AM' raise "ERROR: Invalid demodulator mode: #{demodulator_mode}" unless %w[OFF RAW AM FM WFM WFM_ST WFM_ST_OIRT LSB USB CW CWL CWU].include?(demodulator_mode) puts "Setting demodulator mode to #{demodulator_mode}..." demod_resp = gqrx_cmd(gqrx_sock: gqrx_sock, cmd: "M #{demodulator_mode}") puts demod_resp start_freq = opts[:start_freq].to_i start_freq = gqrx_cmd(gqrx_sock: gqrx_sock, cmd: 'f').to_i if start_freq.zero? end_freq = opts[:end_freq].to_i raise 'ERROR: Invalid end frequency' if end_freq.zero? puts "Scanning from #{start_freq} to #{end_freq}..." host = opts[:host] ||= '127.0.0.1' port = opts[:port] ||= 7356 puts "Connecting to GQRX at #{host}:#{port}..." gqrx_sock = PWN::Plugins::Sock.connect(target: host, port: port) # If start value is greater than end value, go in reverse if start_freq > end_freq end_freq.downto(start_freq) do |freq| gqrx_cmd(gqrx_sock: gqrx_sock, cmd: "F #{freq}") resp = gqrx_cmd(gqrx_sock: gqrx_sock, cmd: 'f') puts "Reached #{resp}..." end else (start_freq..end_freq).each do |freq| puts "Scanning #{freq}..." gqrx_cmd(gqrx_sock: gqrx_sock, cmd: "F #{freq}") resp = gqrx_cmd(gqrx_sock: gqrx_sock, cmd: 'f') puts "Reached #{resp}..." end end rescue SystemExit, Interrupt puts "\nGoodbye." ensure resp = gqrx_cmd(gqrx_sock: gqrx_sock, cmd: 'c') gqrx_sock = PWN::Plugins::Sock.disconnect(sock_obj: gqrx_sock) end