#!/usr/bin/ruby2.3
# TODO usage example ./usrpse_wrap.rb --args 192.168.40.2 --se_mode ZIGBEE --outputmode 2 --first_channel 13
require 'pty'
require 'optparse'
APPNAME = nil # to be decided later in the program, assume the both the usrpse
APPVERSION = "1.0"
# to make sure the FFT application is killed in a proper way
# it seems OMF donot kill the application via its wrapper
Signal.trap("SIGINT") do
    puts "terminating from sigint!!"
    Process.kill(:INT,$pid_global)
end
Signal.trap("SIGTERM") do
    puts "terminating from sigterm!!"
    Process.kill(:INT,$pid_global)
end


class Wrapper 

  def initialize(args)
    puts "init args now "
    ## default settings measures the first Wi-Fi channel
    @gain = 30
    @spb = nil
    @fftsize = 512 
    @args = nil
    @freqbegin = nil
    @bps = nil
    @numofchannel = nil
    @firstchannel = nil
    @channelwidth = nil
    @channeloffset = nil
    @mode = 1 # default reports average 
    @gui = 0 # enable GUI 
    ## variables for none_sweeping mode
    @freq=nil
    @rate=nil
    @threshold= -70
    $unit='dBm'
    ## global variables used in the database class
    $standard = nil

    argParser = OptionParser.new do |argParser|
	argParser.on("-g", "--gain GAIN", "RFGain, default 30 dB") { |var|
    		@gain = var 
		}
        argParser.on("-s", "--spb SPB", "SamplePerBuffer Default 16777216 for channel occupation mode, else 1048576 ") { |var|
    		@spb = var 
		}
        argParser.on("-n", "--fftsize N", "FFTsize, default 512") { |var| 
    		@fftsize = var 
 		}
        argParser.on("-a", "--args Addr", "The USRP IP address") { |var| 
    		@args = var
		}
        argParser.on("-k", "--first_channel FIRSTCHANNEL", "FirstChannel, required for channel occupation mode, else ignored") { |var| 
    		@firstchannel = var.to_i
		} 
	argParser.on("-m", "--detector_mode MODE", "Detector, allowed values: 0 Channel occupation, 1 Avg, 2 Max, 3 Min, default 1") { |var| 
    		@mode = var.to_i
		}
	#argParser.on("-v", "--gui GUI", "GUI switch: 1 Enable, 0 Disalbe, not available for none_sweeping mode, default 0 ") { |var| 
    	#	@gui = var.to_i
	#	}
        argParser.on("-d", "--se_mode STANDARD", "Standard, allowed values: WLAN_G, ZIGBEE, BLUETOOTH") { |var| 
    		$standard = var
		}
    end
    argParser.parse(args)
    $initsuccess = -1
    if @args.nil? 
	puts " Please specify the usrp IP address with --args option"
	return -1
    end
 
    if @spb.nil?
	if @mode == 0
		@spb= 16777216
	else 
		@spb =1048576
	end
    end
    if $standard.nil?
        puts "Please specify the sensing mode with --se_mode option"
	return -1
    elsif $standard == 'WLAN_G'
        @channelwidth = 20000000
    	@channeloffset = 5000000
	if @mode==0 # the channel occupation mode 
		if @firstchannel.nil? 
			puts "Please specify the first channel with --first_channel option"
			return -1		
		elsif @firstchannel <1 or @firstchannel > 13
			puts "Invalid first channel, "
			return -1
		end
		@numofchannel=1
		@freq=2412000000 + 5000000*(@firstchannel-1)
		@rate = 25000000
		$cmd="./usrpse_nonesweep --freq #{@freq} --rate #{@rate} --gain #{@gain} --spb #{@spb} --fftsize #{@fftsize} --numofchannel #{@numofchannel} --firstchannel #{@freq}  --channelwidth #{@channelwidth} --channeloffset #{@channeloffset} --args addr=#{@args} --mode #{@mode} --threshold #{@threshold}"
		@gui = 0 # disable gui for none sweeping mode 
		$unit='%'
	elsif @mode < 4 and @mode > 0
		@firstchannel = 1
		@numofchannel = 13
		@bps = 4
		@freqbegin = 2410000000
		if @gui > 0 
		$cmd="./usrpse_sweeping_gui --gain #{@gain} --spb #{@spb} --fftsize #{@fftsize} --numofchannel #{@numofchannel} --firstchannel 2412000000 --channelwidth #{@channelwidth} --channeloffset #{@channeloffset} --args addr=#{@args} --bps #{@bps} --freqbegin #{@freqbegin} --mode #{@mode} --gui-ip localhost"
		else
		$cmd="./usrpse_sweeping --gain #{@gain} --spb #{@spb} --fftsize #{@fftsize} --numofchannel #{@numofchannel} --firstchannel 2412000000 --channelwidth #{@channelwidth} --channeloffset #{@channeloffset} --args addr=#{@args} --bps #{@bps} --freqbegin #{@freqbegin} --mode #{@mode}"
		end
	else
	      puts "Invalid output mode"
	      return -1
	end
        
    elsif $standard == 'ZIGBEE'
	$tbname= "sensing_data_zigbee"
	@channelwidth = 4000000
    	@channeloffset = 5000000
	if @mode==0 # the channel occupation mode 
		if @firstchannel.nil? 
			puts "Please specify the first channel with --first_channel option"
			return -1		
		elsif @firstchannel <11 or @firstchannel > 23
			puts "Invalid first channel or the last channel is out of range"
			return -1
		end
		@numofchannel=4
		@freq=2400000000 + 5000000*(@firstchannel-10+1.5)
		@rate = 25000000
		$cmd="./usrpse_nonesweep --freq #{@freq} --rate #{@rate} --gain #{@gain} --spb #{@spb} --fftsize #{@fftsize} --numofchannel #{@numofchannel} --firstchannel #{2400000000 + 5000000*(@firstchannel-10)}  --channelwidth #{@channelwidth} --channeloffset #{@channeloffset} --args addr=#{@args} --mode #{@mode} --threshold #{@threshold}"
		@gui = 0 # disable gui for none sweeping mode
		$unit='%'
	elsif @mode < 4 and @mode > 0
		@firstchannel = 11
		@numofchannel = 16
		@bps = 4
		@freqbegin = 2412000000
		if @gui > 0
		$cmd="./usrpse_sweeping_gui --gain #{@gain} --spb #{@spb} --fftsize #{@fftsize} --numofchannel #{@numofchannel} --firstchannel #{(@firstchannel-10)*5000000+2400000000} --channelwidth #{@channelwidth} --channeloffset #{@channeloffset} --args addr=#{@args} --bps #{@bps} --freqbegin #{@freqbegin} --mode #{@mode} --gui-ip localhost"
		else
		$cmd="./usrpse_sweeping --gain #{@gain} --spb #{@spb} --fftsize #{@fftsize} --numofchannel #{@numofchannel} --firstchannel #{(@firstchannel-10)*5000000+2400000000} --channelwidth #{@channelwidth} --channeloffset #{@channeloffset} --args addr=#{@args} --bps #{@bps} --freqbegin #{@freqbegin} --mode #{@mode}"
		end		
	else
	      puts "Invalid output mode"
	      return -1
	end

    elsif $standard == 'BLUETOOTH'
        $tbname = "sensing_data_bluetooth"
	@channelwidth = 2000000
    	@channeloffset = 1000000
	if @mode==0 # the channel occupation mode 
		if @firstchannel.nil? 
			puts "Please specify the first channel with --first_channel option"
			return -1		
		elsif @firstchannel <1 or @firstchannel > 61
			puts "Invalid first channel or the last channel is out of range"
			return -1
		end
		@numofchannel=20
		@freq=2401000000 + 1000000*(@firstchannel+10)
		@rate = 25000000
		$cmd="./usrpse_nonesweep --freq #{@freq} --rate #{@rate} --gain #{@gain} --spb #{@spb} --fftsize #{@fftsize} --numofchannel #{@numofchannel} --firstchannel #{2401000000 + 1000000*@firstchannel}  --channelwidth #{@channelwidth} --channeloffset #{@channeloffset} --args addr=#{@args} --mode #{@mode} --threshold #{@threshold}"
		@gui = 0 # disable gui for nonesweeping mode 
		$unit='%'
	elsif @mode < 4 and @mode > 0
		@firstchannel = 1
		@numofchannel = 79
		@bps = 4
		@freqbegin = 2410000000
		if @gui > 0
		$cmd="./usrpse_sweeping_gui --gain #{@gain} --spb #{@spb} --fftsize #{@fftsize} --numofchannel #{@numofchannel} --firstchannel #{@firstchannel*1000000+2401000000} --channelwidth #{@channelwidth} --channeloffset #{@channeloffset} --args addr=#{@args} --bps #{@bps} --freqbegin #{@freqbegin} --mode #{@mode} --gui-ip localhost"
		else
		$cmd="./usrpse_sweeping --gain #{@gain} --spb #{@spb} --fftsize #{@fftsize} --numofchannel #{@numofchannel} --firstchannel #{@firstchannel*1000000+2401000000} --channelwidth #{@channelwidth} --channeloffset #{@channeloffset} --args addr=#{@args} --bps #{@bps} --freqbegin #{@freqbegin} --mode #{@mode}"
		end

	else
	      puts "Invalid output mode"
	      return -1
	end

    end

    $initsuccess = 0
    return 0
    
  end

    
  def start()
    cmd = ""
    puts "start execute the usrpse wrapper now :)"
    puts $cmd 
    PTY.spawn $cmd do |r,w,p|
	w.close
	$pid_global=p
  	loop { 
		line=r.gets
  		puts line	
	}
    end
  end

end

###################################################

begin
  app = Wrapper.new(ARGV)

  if $initsuccess < 0
	puts "creating class failed due to previous error"
  else
  	puts "class created"
  	app.start()
  end
rescue Exception => ex
  puts "Received an Exception when executing the wrapper!"
  puts "The Exception is: #{ex}\n"
end
