wiki:WiMAX/TeltonikaOmfDriver
close Warning: Can't synchronize with repository "(default)" (/common/SVN/wimax does not appear to be a Subversion repository.). Look in the Trac log for more information.

Version 4 (modified by ffund01, 9 years ago) ( diff )

This driver adds functionality to OMF so that you can use a Teltonika WiMAX USB device in an OMF script.

The syntax to connect to a WiMAX channel in OMF is (for example, if the center frequency of the channel is 2.595GHz and the channel bandwidth is 10MHz):

  node.net.t0.channel = "2595000,10"

Note: this work assumes default settings on the Teltonika device (e.g. default telnet settings, IP settings, etc.)

Installing the driver

Patches to omf-resctl

In /usr/share/omf-resctl-5.3/omf-resctl/omf_agent/nodeAgent.rb:

 tel_count = 0
 if (LSUSB)
    IO.popen("#{LSUSB} | grep 'Intel Corp. WiMAX Connection 2400m' | wc -l") {|u|
      wimax_count += u.gets.to_i
    }
    # Note: look for vendor:product rather than string to make sure usb-modeswitch works
    IO.popen("#{LSUSB} | grep '148e:099a' | wc -l") {|u|
      tel_count += u.gets.to_i
    }
  end
  if wimax_count > 0
    require 'omf-resctl/omf_driver/wimaxcu'
    MObject.info "Found Intel WiMAX - using wimaxcu interface"
    AgentCommands::DEV_MAPPINGS['net/x0'] = WimaxcuDevice.new('net/x0', 'wmx0')
    AgentCommands::DEV_MAPPINGS['net/x1'] = WimaxcuDevice.new('net/x1', 'wmx1')
  end
  if tel_count > 0
    require 'omf-resctl/omf_driver/teltonika'
    MObject.info "Found Teltonika WiMAX - using teltonika interface"
    AgentCommands::DEV_MAPPINGS['net/t0'] = TeltonikaDevice.new('net/t0', 'tel0')
    AgentCommands::DEV_MAPPINGS['net/t1'] = TeltonikaDevice.new('net/t1', 'tel1')
  end
end

In /usr/share/omf-resctl-5.3/omf-resctl/omf_driver/teltonika.rb:

# == Description
#
# This file defines the class TeltonikaDevice which is a sub-class of
#
require 'omf-resctl/omf_driver/wimax'
require 'net/telnet'
require 'ipaddr'
 
class TeltonikaDevice < WimaxDevice
 
  def unload
    # don't unload the kernel module
    #super()
    debug "Disconnecting WiMAX #{@deviceName}"
    dconnect = `#{@wget} --http-user admin --http-password admin -qO - "http://192.168.0.1/cgi/cli?stopSs"`
    clear = `#{@wget} --http-user admin --http-password admin -qO - "http://192.168.0.1/cgi/cli?clearScannerChannels"`
    if @deldef == false
    	unroute = `#{@route} delete default gw 192.168.0.1`
    else
        unroute = `#{@route} del -net #{@routip} netmask #{@fnm} gw 192.168.0.1`  
    end 
 
    clearIP = deconfig
    @mode = @chnnl = @frequency = @bandwidth = @ip = @subnet = @nm = @fnm = @gw = @routip = @oldroutip = @oldnetmask = nil;
    @deldef = false 
  end
 
  def deconfig
    host = Net::Telnet::new("Host" => "192.168.0.1",
                             "Timeout" => 10,
                             "Port" => 700,
                             "Prompt" => /[$%#>] \z/n)
    host.login("admin", "admin01") { |c| print c }
    host.cmd("export interface=icc0"){ |c| print c }
    host.cmd("/etc/udhcpc.script deconfig"){ |c| print c }
    host.close
  end
 
  def telnetIfConf
   # If values are not set, use defaults
    ip = @ip || "0.0.0.0"
    netmask = @nm || "255.255.255.0"
    subnet = @subnet || 24
    router = @gw || ""
    rip = IPAddr.new "#{ip}"
    @routip = rip.mask(subnet)
    deldef = @deldef
    if !deldef and ip != "0.0.0.0"
      tlres = "#{@route} del default gw 192.168.0.1; sleep 2; #{@route} add -net #{@routip} netmask #{netmask} gw 192.168.0.1"
      @deldef = true
      @oldroutip = @routip
      @oldnetmask = netmask
    end 
    if netmask != "255.255.255.0" and deldef and ip != "0.0.0.0"#del route and add a new one if the netmask is different than the default
      tlres = "#{@route} del -net #{@oldroutip} netmask #{@oldnetmask} gw 192.168.0.1; sleep 2; #{@route} add -net #{@routip} netmask #{netmask} gw 192.168.0.1"
    end
 
 
    host = Net::Telnet::new("Host" => "192.168.0.1",
                             "Timeout" => 10,
                             "Port" => 700,
                             "Prompt" => /[$%#>] \z/n)
    host.login("admin", "admin01") { |c| print c }
    host.cmd("ifconfig icc0 #{ip} netmask #{netmask}") { |c| print c }
    host.cmd("export ip=#{ip}"){ |c| print c }
    host.cmd("export subnet=#{subnet}"){ |c| print c }
    host.cmd("export interface=icc0"){ |c| print c }
    host.cmd("export router=#{router}"){ |c| print c }
    host.cmd("/etc/udhcpc.script bound"){ |c| print c }
    host.close
 
    @fnm = netmask #final netmask. This will be used in 'unload'
    return tlres   
  end
 
  def initialize(logicalName, deviceName)
    super(logicalName, deviceName)
    @mode = @ip = @subnet = @nm = @gw = nil
    @ifconfig = '/sbin/ifconfig'
    @wget = '/usr/bin/wget'
    @route = '/sbin/route'
    @deldef = false
    IO.popen("#{@ifconfig} #{deviceName} 192.168.0.8 netmask 255.255.255.0")
  end
 
  def buildCmd
    return nil if @mode.nil?
    cmd = nil
    case @mode
      when :channel
        return nil if @chnnl.nil?
       cmd =  "#{@wget} --http-user admin --http-password admin -qO - 'http://192.168.0.1/cgi/cli?stopSs'; #{@wget} --http-user admin --http-password admin -qO - 'http://192.168.0.1/cgi/cli?addChannel frequency=#{@frequency} bandwidth=#{@bandwidth}'; #{@wget} --http-user admin --http-password admin -qO - 'http://192.168.0.1/cgi/cli?startSs'; #{@route} add default gw 192.168.0.1"
      when :ip
        return nil if @ip.nil?
        comRes = telnetIfConf
        cmd = comRes unless comRes.nil?
      when :netmask
        return nil if @nm.nil?
        comRes = telnetIfConf
        cmd = comRes unless comRes.nil?
      when :gway
        return nil if @gw.nil?
        comRes = telnetIfConf
        cmd = comRes unless comRes.nil?
    else
      raise "Unknown mode '#{@mode}'. Should be 'initiate', 'channel', 'mtu' or 'ip'"
    end
    return cmd
  end
#
  # Return the specific command required to configure a given property of this
  # device. When a property does not exist for this device, check if it does
  # for its super-class.
  #
  # - prop = the property to configure
  # - value = the value to configure that property to
  #
  def getConfigCmd(prop, value)
 
    @propertyList[prop.to_sym] = value
    case prop
      when "ip" #ifconfig 192... etc..
        @mode = :ip
        @ip = value
        return buildCmd
      when "netmask" #ifconfig 192... etc..
        @mode = :netmask
        @nm = value
        @subnet = IPAddr.new("#{@nm}").to_i.to_s(2).count("1")
        return buildCmd
      when "gway"
        @mode = :gway
        @gw = value
        return buildCmd
      when "channel" #assign a frequency and a bandwidth
        @mode = :channel
        @chnnl = value.split(/, */,2)
        @frequency = @chnnl[0]
        @bandwidth = @chnnl[1]
        return buildCmd
    end
    super
  end
  def get_property_value(prop)
    # Note: for now we are returning values set by a CONFIGURE command
    # when refactoring the device handling scheme, we may want to query
    # the system here to find out the real value of the property
    result = super(prop) #gets mac and ip addresses from ethernetDevice.rb
    result = @propertyList[prop] if !result
    return result
  end
 
end

Patches to omf-expctl

In /usr/share/omf-expctl-5.3/omf-expctl/node/nodeSetPath.rb:

class NodeSetPath < MObject
  attr_reader :nodeSet, :path
 
  # List of valid 'PATHS' for a NodeSet
  VALID_PATHS_WITH_VALUES = {
    "mode=" => %r{net/[ew][01]},
    "profile=" => %r{net/[x][01]},
    "network=" => %r{net/[x][01]},
    "type=" => %r{net/[ew][01]},
    "rts=" => %r{net/[ew][01]},
    "rate=" => %r{net/[ew][01]},
    "essid=" => %r{net/[ew][01]},
    "ip=" => %r{net/[ewxt][01]},
    "channel=" => %r{net/[ewt][01]},
    "tx_power=" => %r{net/[ew][01]},
    "netmask=" => %r{net/[ewxt][01]},
    "mac=" => %r{net/[ewx][01]},
    "mtu=" => %r{net/[ewxt][01]},
    "arp=" => %r{net/[ewx][01]},
    "enforce_link=" => %r{net/[ewx][01]},
    "route" => %r{net/[ewxt][01]},
    "gway" => %r{net/[t][01]},
    "filter" => %r{net/[ewx][01]},
    "net" => //
  }
  VALID_PATHS_WITHOUT_VALUES = {
    "down" => %r{net/[ewxt][01]},
    "up" => %r{net/[ewxt][01]},
  }
  VALID_PATHS = VALID_PATHS_WITH_VALUES.merge(VALID_PATHS_WITHOUT_VALUES)
  VALID_PATHS_RE = {
    /[ewxt][01]/ => /net/
  }

Other required configuration on node

Install usb-modeswitch-data and usb-modeswitch (need recent version, ≥1.1.9, such as the one provided for oneiric)

In /etc/udev/rules.d/70-persistent-net.rules, add the following (so that teltonika device will get the name tel0):

KERNEL=="eth*", DRIVERS=="cdc_ether", NAME="tel0"

If /etc/udev/rules.d/75-persistent-net-generator.rules exists, remove it so that your /etc/udev/rules.d/70-persistent-net.rules will not be overwritten. Make sure you have all the other rules you need (e.g. for Ethernet control interface) in /etc/udev/rules.d/70-persistent-net.rules because new ones will not be generated anymore.

Usage: Sample Scripts

With Dynamic Addressing

defProperty('runtime',20,"Time in second for the experiment is to run")
defProperty('client',"128.238.66.220","IP address of iperf server")
defProperty('interval', 1, "Interval of Iperf measurements")
defProperty('sender', 'omf.witest.node10', "ID of sender node")
 
defGroup('Group', property.sender) do |node|
  node.net.t0.channel = "2595000,10"
  node.net.t0.mtu=1470
  node.addApplication("test:app:iperf") do |app|
    app.setProperty('client', property.client)
    app.setProperty('interval', property.interval)
    app.setProperty('time', property.runtime)
    app.measure('TCP_Info', :samples =>1)
  end
end
 
onEvent(:ALL_UP_AND_INSTALLED) do |event|
  wait 50
  info "This is an iperf  experiment using a teltonika modem"
  allGroups.startApplications
  wait property.runtime
  wait 2
  allGroups.stopApplications
  wait 2
  Experiment.done
end

With Static Addressing

defProperty('runtime',20,"Time in second for the experiment is to run")
defProperty('client',"192.168.10.1","IP address of iperf server")
defProperty('interval', 1, "Interval of Iperf measurements")
defProperty('sender', 'omf.witest.node10', "ID of sender node")
defProperty('sender', 'omf.witest.node1', "ID of sender node")
 
defGroup('Group', property.sender) do |node|
  node.net.t0.channel = "2595000,10"
  node.net.t0.mtu=1470
  node.net.t0.ip = "192.168.10.110"
  node.net.t0.netmask = "255.255.255.0"
  node.addApplication("test:app:iperf") do |app|
    app.setProperty('client', property.client)
    app.setProperty('interval', property.interval)
    app.setProperty('time', property.runtime)
    app.measure('TCP_Info', :samples =>1)
  end
end
 
defGroup('Group', property.receiver) do |node|
  node.net.x0.profile = '51'
  node.net.x0.ip = property.client
  node.net.x0.netmask = "255.255.255.0"
  node.addApplication("test:app:iperf") do |app|
    app.setProperty('server', true)
    app.setProperty('interval', property.interval)
    app.measure('TCP_Info', :samples =>1)
  end
end
 
 
onEvent(:ALL_UP_AND_INSTALLED) do |event|
  wait 50
  info "This is an iperf  experiment using a teltonika modem"
  allGroups.startApplications
  wait property.runtime
  wait 2
  allGroups.stopApplications
  wait 2
  Experiment.done
end
Note: See TracWiki for help on using the wiki.