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.

Changes between Initial Version and Version 1 of WiMAX/TeltonikaOmfDriver


Ignore:
Timestamp:
Oct 17, 2012, 5:02:57 AM (12 years ago)
Author:
ffund01
Comment:

Legend:

Unmodified
Added
Removed
Modified
  • WiMAX/TeltonikaOmfDriver

    v1 v1  
     1[[TOC]]
     2
     3This driver adds functionality to OMF so that you can use a Teltonika WiMAX USB device in an OMF script.
     4
     5
     6The syntax to connect to a WiMAX channel in OMF is (for example, if the center frequency of the channel is 2.59GHz and the channel bandwidth is 10MHz):
     7{{{
     8  node.net.t0.channel = "2595000,10"
     9}}}
     10
     11
     12Note: this work assumes default settings on the Teltonika device (e.g. default telnet settings, IP settings, etc.)
     13
     14== Installing the driver ==
     15
     16=== Patches to omf-resctl ===
     17
     18In /usr/share/omf-resctl-5.3/omf-resctl/omf_agent/nodeAgent.rb:
     19
     20{{{
     21 tel_count = 0
     22 if (LSUSB)
     23    IO.popen("#{LSUSB} | grep 'Intel Corp. WiMAX Connection 2400m' | wc -l") {|u|
     24      wimax_count += u.gets.to_i
     25    }
     26    # Note: look for vendor:product rather than string to make sure usb-modeswitch works
     27    IO.popen("#{LSUSB} | grep '148e:099a' | wc -l") {|u|
     28      tel_count += u.gets.to_i
     29    }
     30  end
     31  if wimax_count > 0
     32    require 'omf-resctl/omf_driver/wimaxcu'
     33    MObject.info "Found Intel WiMAX - using wimaxcu interface"
     34    AgentCommands::DEV_MAPPINGS['net/x0'] = WimaxcuDevice.new('net/x0', 'wmx0')
     35    AgentCommands::DEV_MAPPINGS['net/x1'] = WimaxcuDevice.new('net/x1', 'wmx1')
     36  end
     37  if tel_count > 0
     38    require 'omf-resctl/omf_driver/teltonika'
     39    MObject.info "Found Teltonika WiMAX - using teltonika interface"
     40    AgentCommands::DEV_MAPPINGS['net/t0'] = TeltonikaDevice.new('net/t0', 'tel0')
     41    AgentCommands::DEV_MAPPINGS['net/t1'] = TeltonikaDevice.new('net/t1', 'tel1')
     42  end
     43end
     44}}}
     45
     46In /usr/share/omf-resctl-5.3/omf-resctl/omf_driver/teltonika.rb:
     47
     48{{{
     49# == Description
     50#
     51# This file defines the class TeltonikaDevice which is a sub-class of
     52# WimaxcuDevice.
     53#
     54require 'omf-resctl/omf_driver/wimax'
     55require 'net/telnet'
     56require 'ipaddr'
     57 
     58class TeltonikaDevice < WimaxDevice
     59 
     60  def unload
     61    # don't unload the kernel module
     62    #super()
     63    debug "Disconnecting WiMAX #{@deviceName}"
     64    dconnect = `#{@wget} --http-user admin --http-password admin -qO - "http://192.168.0.1/cgi/cli?stopSs"`
     65    clear = `#{@wget} --http-user admin --http-password admin -qO - "http://192.168.0.1/cgi/cli?clearScannerChannels"`
     66    if @deldef == false
     67        unroute = `#{@route} delete default gw 192.168.0.1`
     68    else
     69        unroute = `#{@route} del -net #{@routip} netmask #{@fnm} gw 192.168.0.1` 
     70    end
     71 
     72    clearIP = deconfig
     73    @mode = @chnnl = @frequency = @bandwidth = @ip = @subnet = @nm = @fnm = @gw = @routip = @oldroutip = @oldnetmask = nil;
     74    @deldef = false
     75  end
     76 
     77  def deconfig
     78    host = Net::Telnet::new("Host" => "192.168.0.1",
     79                             "Timeout" => 10,
     80                             "Port" => 700,
     81                             "Prompt" => /[$%#>] \z/n)
     82    host.login("admin", "admin01") { |c| print c }
     83    host.cmd("export interface=icc0"){ |c| print c }
     84    host.cmd("/etc/udhcpc.script deconfig"){ |c| print c }
     85    host.close
     86  end
     87 
     88  def telnetIfConf
     89   # If values are not set, use defaults
     90    ip = @ip || "0.0.0.0"
     91    netmask = @nm || "255.255.255.0"
     92    subnet = @subnet || 24
     93    router = @gw || ""
     94    rip = IPAddr.new "#{ip}"
     95    @routip = rip.mask(subnet)
     96    deldef = @deldef
     97    if !deldef and ip != "0.0.0.0"
     98      tlres = "#{@route} del default gw 192.168.0.1; sleep 2; #{@route} add -net #{@routip} netmask #{netmask} gw 192.168.0.1"
     99      @deldef = true
     100      @oldroutip = @routip
     101      @oldnetmask = netmask
     102    end
     103    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
     104      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"
     105    end
     106 
     107 
     108    host = Net::Telnet::new("Host" => "192.168.0.1",
     109                             "Timeout" => 10,
     110                             "Port" => 700,
     111                             "Prompt" => /[$%#>] \z/n)
     112    host.login("admin", "admin01") { |c| print c }
     113    host.cmd("ifconfig icc0 #{ip} netmask #{netmask}") { |c| print c }
     114    host.cmd("export ip=#{ip}"){ |c| print c }
     115    host.cmd("export subnet=#{subnet}"){ |c| print c }
     116    host.cmd("export interface=icc0"){ |c| print c }
     117    host.cmd("export router=#{router}"){ |c| print c }
     118    host.cmd("/etc/udhcpc.script bound"){ |c| print c }
     119    host.close
     120 
     121    @fnm = netmask #final netmask. This will be used in 'unload'
     122    return tlres   
     123  end
     124 
     125  def initialize(logicalName, deviceName)
     126    super(logicalName, deviceName)
     127    @mode = @ip = @subnet = @nm = @gw = nil
     128    @ifconfig = '/sbin/ifconfig'
     129    @wget = '/usr/bin/wget'
     130    @route = '/sbin/route'
     131    @deldef = false
     132    IO.popen("#{@ifconfig} #{deviceName} 192.168.0.8 netmask 255.255.255.0")
     133  end
     134 
     135  def buildCmd
     136    return nil if @mode.nil?
     137    cmd = nil
     138    case @mode
     139      when :channel
     140        return nil if @chnnl.nil?
     141       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"
     142      when :ip
     143        return nil if @ip.nil?
     144        comRes = telnetIfConf
     145        cmd = comRes unless comRes.nil?
     146      when :netmask
     147        return nil if @nm.nil?
     148        comRes = telnetIfConf
     149        cmd = comRes unless comRes.nil?
     150      when :gway
     151        return nil if @gw.nil?
     152        comRes = telnetIfConf
     153        cmd = comRes unless comRes.nil?
     154    else
     155      raise "Unknown mode '#{@mode}'. Should be 'initiate', 'channel', 'mtu' or 'ip'"
     156    end
     157    return cmd
     158  end
     159#
     160  # Return the specific command required to configure a given property of this
     161  # device. When a property does not exist for this device, check if it does
     162  # for its super-class.
     163  #
     164  # - prop = the property to configure
     165  # - value = the value to configure that property to
     166  #
     167  def getConfigCmd(prop, value)
     168 
     169    @propertyList[prop.to_sym] = value
     170    case prop
     171      when "ip" #ifconfig 192... etc..
     172        @mode = :ip
     173        @ip = value
     174        return buildCmd
     175      when "netmask" #ifconfig 192... etc..
     176        @mode = :netmask
     177        @nm = value
     178        @subnet = IPAddr.new("#{@nm}").to_i.to_s(2).count("1")
     179        return buildCmd
     180      when "gway"
     181        @mode = :gway
     182        @gw = value
     183        return buildCmd
     184      when "channel" #assign a frequency and a bandwidth
     185        @mode = :channel
     186        @chnnl = value.split(/, */,2)
     187        @frequency = @chnnl[0]
     188        @bandwidth = @chnnl[1]
     189        return buildCmd
     190    end
     191    super
     192  end
     193  def get_property_value(prop)
     194    # Note: for now we are returning values set by a CONFIGURE command
     195    # when refactoring the device handling scheme, we may want to query
     196    # the system here to find out the real value of the property
     197    result = super(prop) #gets mac and ip addresses from ethernetDevice.rb
     198    result = @propertyList[prop] if !result
     199    return result
     200  end
     201 
     202end
     203}}}
     204
     205=== Patches to omf-expctl ===
     206
     207In /usr/share/omf-expctl-5.3/omf-expctl/node/nodeSetPath.rb:
     208
     209{{{
     210class NodeSetPath < MObject
     211  attr_reader :nodeSet, :path
     212 
     213  # List of valid 'PATHS' for a NodeSet
     214  VALID_PATHS_WITH_VALUES = {
     215    "mode=" => %r{net/[ew][01]},
     216    "profile=" => %r{net/[x][01]},
     217    "network=" => %r{net/[x][01]},
     218    "type=" => %r{net/[ew][01]},
     219    "rts=" => %r{net/[ew][01]},
     220    "rate=" => %r{net/[ew][01]},
     221    "essid=" => %r{net/[ew][01]},
     222    "ip=" => %r{net/[ewxt][01]},
     223    "channel=" => %r{net/[ewt][01]},
     224    "tx_power=" => %r{net/[ew][01]},
     225    "netmask=" => %r{net/[ewxt][01]},
     226    "mac=" => %r{net/[ewx][01]},
     227    "mtu=" => %r{net/[ewxt][01]},
     228    "arp=" => %r{net/[ewx][01]},
     229    "enforce_link=" => %r{net/[ewx][01]},
     230    "route" => %r{net/[ewxt][01]},
     231    "gway" => %r{net/[t][01]},
     232    "filter" => %r{net/[ewx][01]},
     233    "net" => //
     234  }
     235  VALID_PATHS_WITHOUT_VALUES = {
     236    "down" => %r{net/[ewxt][01]},
     237    "up" => %r{net/[ewxt][01]},
     238  }
     239  VALID_PATHS = VALID_PATHS_WITH_VALUES.merge(VALID_PATHS_WITHOUT_VALUES)
     240  VALID_PATHS_RE = {
     241    /[ewxt][01]/ => /net/
     242  }
     243}}}
     244
     245=== Other required configuration on node ===
     246
     247Install usb-modeswitch-data and usb-modeswitch (need recent version, >=1.1.9, such as the one provided for oneiric)
     248
     249
     250In /etc/udev/rules.d/70-persistent-net.rules, add the following (so that teltonika device will get the name tel0):
     251{{{
     252KERNEL=="eth*", DRIVERS=="cdc_ether", NAME="tel0"
     253}}}
     254
     255== Usage: Sample Scripts ==
     256=== With Dynamic Addressing ===
     257
     258{{{
     259defProperty('runtime',20,"Time in second for the experiment is to run")
     260defProperty('client',"128.238.66.220","IP address of iperf server")
     261defProperty('interval', 1, "Interval of Iperf measurements")
     262defProperty('sender', 'omf.witest.node10', "ID of sender node")
     263 
     264defGroup('Group', property.sender) do |node|
     265  node.net.t0.channel = "2595000,10"
     266  node.net.t0.mtu=1470
     267  node.addApplication("test:app:iperf") do |app|
     268    app.setProperty('client', property.client)
     269    app.setProperty('interval', property.interval)
     270    app.setProperty('time', property.runtime)
     271    app.measure('TCP_Info', :samples =>1)
     272  end
     273end
     274 
     275onEvent(:ALL_UP_AND_INSTALLED) do |event|
     276  wait 50
     277  info "This is an iperf  experiment using a teltonika modem"
     278  allGroups.startApplications
     279  wait property.runtime
     280  wait 2
     281  allGroups.stopApplications
     282  wait 2
     283  Experiment.done
     284end
     285}}}
     286
     287
     288=== With Static Addressing ===
     289
     290{{{
     291defProperty('runtime',20,"Time in second for the experiment is to run")
     292defProperty('client',"192.168.10.1","IP address of iperf server")
     293defProperty('interval', 1, "Interval of Iperf measurements")
     294defProperty('sender', 'omf.witest.node10', "ID of sender node")
     295defProperty('sender', 'omf.witest.node1', "ID of sender node")
     296 
     297defGroup('Group', property.sender) do |node|
     298  node.net.t0.channel = "2595000,10"
     299  node.net.t0.mtu=1470
     300  node.net.t0.ip = "192.168.10.110"
     301  node.net.t0.netmask = "255.255.255.0"
     302  node.addApplication("test:app:iperf") do |app|
     303    app.setProperty('client', property.client)
     304    app.setProperty('interval', property.interval)
     305    app.setProperty('time', property.runtime)
     306    app.measure('TCP_Info', :samples =>1)
     307  end
     308end
     309 
     310defGroup('Group', property.receiver) do |node|
     311  node.net.x0.profile = '51'
     312  node.net.x0.ip = property.client
     313  node.net.x0.netmask = "255.255.255.0"
     314  node.addApplication("test:app:iperf") do |app|
     315    app.setProperty('server', true)
     316    app.setProperty('interval', property.interval)
     317    app.measure('TCP_Info', :samples =>1)
     318  end
     319end
     320 
     321 
     322onEvent(:ALL_UP_AND_INSTALLED) do |event|
     323  wait 50
     324  info "This is an iperf  experiment using a teltonika modem"
     325  allGroups.startApplications
     326  wait property.runtime
     327  wait 2
     328  allGroups.stopApplications
     329  wait 2
     330  Experiment.done
     331end
     332}}}