omf_ec 6.0.0.pre.3 → 6.0.0.pre.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (91) hide show
  1. data/Rakefile +1 -0
  2. data/bin/omf_ec +264 -0
  3. data/example/engine_oedl.rb +52 -0
  4. data/example/engine_test.rb +90 -0
  5. data/example/test_exp/test00.rb +12 -0
  6. data/example/test_exp/test01.rb +22 -0
  7. data/example/test_exp/test02.rb +30 -0
  8. data/{exp_repo/test/exp → example/test_exp}/test03.rb +2 -42
  9. data/{exp_repo/test/exp → example/test_exp}/test04.rb +2 -2
  10. data/{exp_repo/test/exp → example/test_exp}/test05.rb +4 -4
  11. data/{exp_repo/test/exp → example/test_exp}/test06.rb +6 -6
  12. data/example/test_exp/test07.rb +65 -0
  13. data/lib/omf_ec/app_definition.rb +57 -0
  14. data/lib/omf_ec/backward/app_definition.rb +35 -0
  15. data/lib/omf_ec/backward/core_ext/array.rb +19 -0
  16. data/lib/omf_ec/backward/default_events.rb +71 -0
  17. data/lib/omf_ec/backward/dsl.rb +83 -0
  18. data/lib/omf_ec/backward/exp/testbed.rb +47 -0
  19. data/lib/omf_ec/backward/group.rb +72 -0
  20. data/lib/omf_ec/context/app_context.rb +54 -0
  21. data/lib/omf_ec/context/def_app_context.rb +6 -0
  22. data/lib/omf_ec/context/group_context.rb +88 -0
  23. data/lib/omf_ec/context/net_context.rb +46 -0
  24. data/lib/omf_ec/context.rb +10 -0
  25. data/lib/omf_ec/dsl.rb +159 -0
  26. data/lib/omf_ec/experiment.rb +71 -0
  27. data/lib/omf_ec/group.rb +158 -0
  28. data/lib/omf_ec/version.rb +1 -1
  29. data/lib/omf_ec.rb +34 -1
  30. data/omf_ec.gemspec +2 -3
  31. data/test/omf_ec/context_spec.rb +19 -0
  32. data/test/omf_ec/group_spec.rb +14 -0
  33. data/test/test_helper.rb +19 -0
  34. metadata +44 -89
  35. data/bin/omf +0 -147
  36. data/bin/omf_pre +0 -76
  37. data/bin/omf_test +0 -161
  38. data/example/net_devices.rb +0 -75
  39. data/exp_repo/system/exp/eventlib.rb +0 -96
  40. data/exp_repo/system/exp/imageNode.rb +0 -283
  41. data/exp_repo/system/exp/reset.rb +0 -21
  42. data/exp_repo/system/exp/saveNode.rb +0 -99
  43. data/exp_repo/system/exp/stat.rb +0 -49
  44. data/exp_repo/system/exp/stdlib.rb +0 -122
  45. data/exp_repo/system/exp/tell.rb +0 -53
  46. data/exp_repo/system/exp/testlib.rb +0 -12
  47. data/exp_repo/system/exp/winlib.rb +0 -154
  48. data/exp_repo/system/topo/active.rb +0 -9
  49. data/exp_repo/system/topo/all.rb +0 -10
  50. data/exp_repo/system/topo/circle.rb +0 -23
  51. data/exp_repo/test/app/aodvd.rb +0 -73
  52. data/exp_repo/test/app/appDef1.rb +0 -102
  53. data/exp_repo/test/app/athstats.rb +0 -76
  54. data/exp_repo/test/app/echo.rb +0 -36
  55. data/exp_repo/test/app/gennyReceiverAppDef.rb +0 -100
  56. data/exp_repo/test/app/gennySenderAppDef.rb +0 -106
  57. data/exp_repo/test/app/itgdec.rb +0 -79
  58. data/exp_repo/test/app/itgr.rb +0 -77
  59. data/exp_repo/test/app/itgs.rb +0 -105
  60. data/exp_repo/test/app/nop.rb +0 -36
  61. data/exp_repo/test/app/otg2.rb +0 -68
  62. data/exp_repo/test/app/otg2_mp.rb +0 -56
  63. data/exp_repo/test/app/otr2.rb +0 -56
  64. data/exp_repo/test/app/otr2_mp.rb +0 -51
  65. data/exp_repo/test/app/trace_oml2.rb +0 -62
  66. data/exp_repo/test/app/wlanconfig_oml2.rb +0 -42
  67. data/exp_repo/test/exp/conf-room-demo.rb +0 -118
  68. data/exp_repo/test/exp/planetlab.rb +0 -82
  69. data/exp_repo/test/exp/test01.rb +0 -42
  70. data/exp_repo/test/exp/test02.rb +0 -60
  71. data/exp_repo/test/exp/tutorial/hello-world-wired.rb +0 -79
  72. data/exp_repo/test/exp/tutorial/hello-world-wireless.rb +0 -87
  73. data/exp_repo/test/exp/tutorial/using-filters.rb +0 -69
  74. data/exp_repo/test/exp/tutorial/using-groups.rb +0 -64
  75. data/exp_repo/test/exp/tutorial/using-properties.rb +0 -93
  76. data/exp_repo/test/exp/tutorial/using-prototypes.rb +0 -111
  77. data/exp_repo/test/proto/aodvrouter.rb +0 -55
  78. data/exp_repo/test/proto/driverqueryapp.rb +0 -59
  79. data/exp_repo/test/proto/forwarder.rb +0 -73
  80. data/exp_repo/test/proto/itgcbrsender.rb +0 -70
  81. data/exp_repo/test/proto/itgdecoder.rb +0 -64
  82. data/exp_repo/test/proto/itgreceiver.rb +0 -55
  83. data/exp_repo/test/proto/itgvoipsender.rb +0 -64
  84. data/exp_repo/test/proto/listener2.rb +0 -62
  85. data/exp_repo/test/proto/nop.rb +0 -47
  86. data/exp_repo/test/proto/probelink.rb +0 -48
  87. data/exp_repo/test/proto/raw_receiver.rb +0 -64
  88. data/exp_repo/test/proto/receiver2_mp.rb +0 -48
  89. data/exp_repo/test/proto/sender2_mp.rb +0 -54
  90. data/exp_repo/test/proto/udp_receiver.rb +0 -55
  91. data/exp_repo/test/proto/udp_sender.rb +0 -61
@@ -0,0 +1,57 @@
1
+ require 'securerandom'
2
+
3
+ module OmfEc
4
+ # Application Definition used in experiment script
5
+ #
6
+ # @!attribute name [String] name of the resource
7
+ class AppDefinition
8
+
9
+ # TODO: eventually this call would mirror all the properties of the App Proxy
10
+ # right now we just have name, binary_path, parameters
11
+ attr_accessor :name, :properties
12
+
13
+ # @param [String] name name of the application to define
14
+ def initialize(name)
15
+ self.name = name
16
+ self.properties = Hash.new
17
+ end
18
+
19
+ # Add new parameter(s) to this Application Definition
20
+ #
21
+ # @param [Hash] params a hash with the parameters to add
22
+ #
23
+ def define_parameter(params)
24
+ @properties[:parameters] = Hash.new unless @properties.key?(:parameters)
25
+ if params.kind_of? Hash
26
+ @properties[:parameters].merge!(params)
27
+ else
28
+ error "Cannot define parameter for app '#{self.name}'! Parameter "+
29
+ "not passed as a Hash ('#{params.inspect}')"
30
+ end
31
+ end
32
+
33
+ def define_measurement_point(mp)
34
+ @properties[:oml] = Hash.new unless @properties.key?(:oml)
35
+ if mp.kind_of? Hash
36
+ @properties[:oml][:available_mps] = Array.new unless @properties[:oml].key?(:available_mps)
37
+ @properties[:oml][:available_mps] << mp
38
+ else
39
+ error "Cannot define Measurement Point for app '#{self.name}'! MP "+
40
+ "not passed as a Hash ('#{mp.inspect}')"
41
+ end
42
+ end
43
+
44
+ def method_missing(method_name, *args)
45
+ k = method_name.to_sym
46
+ return @properties[k] if @properties.key?(k)
47
+ m = method_name.to_s.match(/(.*?)([=]?)$/)
48
+ if m[2] == '='
49
+ @properties[m[1].to_sym] = args.first
50
+ else
51
+ super
52
+ end
53
+ end
54
+
55
+ include OmfEc::Backward::AppDefinition
56
+ end
57
+ end
@@ -0,0 +1,35 @@
1
+ module OmfEc
2
+ module Backward
3
+ module AppDefinition
4
+ # The following are ODEL 5 methods
5
+
6
+ # Add a new parameter to this Application Definition
7
+ # This method is for backward compatibility with previous OEDL 5
8
+ #
9
+ # @param [String] name name of the application to define
10
+ def defProperty(name = :mandatory, description = nil, parameter = nil, options = {})
11
+ opts = {:description => description, :cmd => parameter}
12
+ # Map old OMF5 types to OMF6
13
+ options[:type] = 'Numeric' if options[:type] == :integer
14
+ options[:type] = 'String' if options[:type] == :string
15
+ options[:type] = 'Boolean' if options[:type] == :boolean
16
+ opts = opts.merge(options)
17
+ define_parameter(Hash[name,opts])
18
+ end
19
+
20
+ def defMetric(name,type)
21
+ @fields << {:field => name, :type => type}
22
+ end
23
+
24
+ def defMeasurement(name,&block)
25
+ mp = {:mp => name, :fields => []}
26
+ @fields = []
27
+ # call the block with ourserlves to process its 'defMetric' statements
28
+ block.call(self) if block
29
+ @fields.each { |f| mp[:fields] << f }
30
+ define_measurement_point(mp)
31
+ end
32
+
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,19 @@
1
+ class Array
2
+ def startApplications
3
+ if !self.empty? && self.all? { |v| v.class == OmfEc::Group }
4
+ self.each { |g| g.startApplications }
5
+ end
6
+ end
7
+
8
+ def stopApplications
9
+ if !self.empty? && self.all? { |v| v.class == OmfEc::Group }
10
+ self.each { |g| g.stopApplications }
11
+ end
12
+ end
13
+
14
+ def exec(name)
15
+ if !self.empty? && self.all? { |v| v.class == OmfEc::Group }
16
+ self.each { |g| g.exec(name) }
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,71 @@
1
+ module OmfEc
2
+ module Backward
3
+ module DefaultEvents
4
+
5
+ class << self
6
+ def included(base)
7
+ base.instance_eval do
8
+
9
+ def_event :ALL_UP do |state|
10
+ !all_groups.empty? && all_groups.all? do |g|
11
+ plan = g.members.uniq.sort
12
+ actual = state.find_all do |v|
13
+ v[:membership] && v[:membership].include?(g.id)
14
+ end.map { |v| v[:uid] }.sort
15
+ plan == actual
16
+ end
17
+ end
18
+
19
+ on_event :ALL_UP do
20
+ all_groups do |group|
21
+ # Deal with brilliant net.w0.ip syntax...
22
+ group.net_ifs && group.net_ifs.each do |nif|
23
+ nif.map_channel_freq
24
+ r_type = nif.conf[:type]
25
+ r_hrn = nif.conf[:hrn]
26
+ r_index = nif.conf[:index]
27
+
28
+ conf_to_send =
29
+ if r_type == 'wlan'
30
+ { type: r_type,
31
+ mode: nif.conf.merge(:phy => "<%= request_wlan_devices[#{r_index}][:name] %>").except(:hrn, :type, :index)
32
+ }
33
+ else
34
+ nif.conf.merge(type: r_type).except(:index)
35
+ end
36
+
37
+ group.create_resource(r_hrn, conf_to_send)
38
+ end
39
+ # Create proxies for each apps that were added to this group
40
+ group.app_contexts.each { |a| group.create_resource(a.name, a.properties) }
41
+ end
42
+ end
43
+
44
+ def_event :ALL_INTERFACE_UP do |state|
45
+ !all_groups.empty? && all_groups.all? do |g|
46
+ plan = g.net_ifs.map { |v| v.conf[:hrn] }.uniq.size * g.members.uniq.size
47
+ actual = state.find_all do |v|
48
+ v[:membership] &&
49
+ (v[:membership].include?("#{g.id}_wlan") || v[:membership].include?("#{g.id}_net"))
50
+ end.size
51
+ plan == actual
52
+ end
53
+ end
54
+
55
+ def_event :ALL_UP_AND_INSTALLED do |state|
56
+ !all_groups.empty? && all_groups.all? do |g|
57
+ plan = g.app_contexts.size * g.members.uniq.size
58
+ actual = state.find_all do |v|
59
+ v[:membership] && v[:membership].include?("#{g.id}_application")
60
+ end.size
61
+ plan == actual
62
+ end
63
+ end
64
+
65
+ end
66
+ end
67
+ end
68
+
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,83 @@
1
+ module OmfEc
2
+ module Backward
3
+ module DSL
4
+ class << self
5
+ def included(base)
6
+ v5_style(:defProperty, base)
7
+ v5_style(:defEvent, base)
8
+ v5_style(:onEvent, base)
9
+ v5_style(:allEqual, base)
10
+ v5_style(:onEvent, base)
11
+ v5_style(:allGroups, base)
12
+ v5_style(:allNodes!, base)
13
+ end
14
+
15
+ def v5_style(name, base)
16
+ new_name = name.to_s.underscore.to_sym
17
+ unless method_defined? new_name
18
+ base.class_eval do
19
+ alias_method name, new_name
20
+ end
21
+ end
22
+ end
23
+ end
24
+
25
+ def defApplication(uri,name,&block)
26
+ # URI parameter was used by previous OMF5 EC, for now we
27
+ # do nothing with it in OMF6
28
+ def_application(name,&block)
29
+ end
30
+
31
+ def defGroup(name, *members, &block)
32
+ group = OmfEc::Group.new(name)
33
+ OmfEc.exp.groups << group
34
+
35
+ members.each do |m|
36
+ m_group = OmfEc.exp.groups.find { |v| v.name == m }
37
+ if m_group
38
+ group.members += m_group.members
39
+ else
40
+ group.members << m
41
+ end
42
+ end
43
+
44
+ block.call(group) if block
45
+
46
+ OmfEc.comm.subscribe(group.id, create_if_non_existent: true) do |m|
47
+ unless m.error?
48
+ members.each do |m|
49
+ group.add_resource(m)
50
+ end
51
+
52
+ rg = OmfEc.comm.get_topic(group.id)
53
+
54
+ rg.on_message lambda {|m| m.operation == :inform && m.read_content('inform_type') == 'FAILED' && m.context_id.nil? } do |i|
55
+ warn "RC reports failure: '#{i.read_content("reason")}'"
56
+ end
57
+
58
+ rg.on_message lambda {|m| m.operation == :inform && m.read_content('inform_type') == 'STATUS' && m.context_id.nil? } do |i|
59
+ r = OmfEc.exp.state.find { |v| v[:uid] == i.read_property(:uid) }
60
+ unless r.nil?
61
+ i.each_property do |p|
62
+ key = p.attr('key').to_sym
63
+ r[key] = i.read_property(key)
64
+ end
65
+ end
66
+ Experiment.instance.process_events
67
+ end
68
+ end
69
+ end
70
+ end
71
+
72
+ # Wait for some time before issuing more commands
73
+ #
74
+ # @param [Fixnum] duration Time to wait in seconds (can be
75
+ #
76
+ def wait(duration)
77
+ info "Request from Experiment Script: Wait for #{duration}s...."
78
+ warn "Calling 'wait' or 'sleep' will block entire EC event loop. Please try 'after' or 'every'"
79
+ sleep duration
80
+ end
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,47 @@
1
+ comm = OmfEc.comm
2
+
3
+ testbed_topic = comm.get_topic('testbed')
4
+
5
+ msgs = {
6
+ create: comm.create_message([type: 'application']),
7
+ req_platform: comm.request_message([:platform]),
8
+ conf_path: comm.configure_message([binary_path: @cmd]),
9
+ run_application: comm.configure_message([state: :run])
10
+ }
11
+
12
+ msgs[:create].on_inform_created do |message|
13
+ app_topic = comm.get_topic(message.resource_id)
14
+ app_topic.subscribe do
15
+ msgs[:req_platform].publish app_topic.id
16
+ sleep 1
17
+ msgs[:conf_path].publish app_topic.id
18
+ sleep 1
19
+ msgs[:run_application].publish app_topic.id
20
+ end
21
+
22
+ app_topic.on_message do |m|
23
+ if m.operation == :inform
24
+ case m.read_content("inform_type")
25
+ when 'STATUS'
26
+ if m.read_property("status_type") == 'APP_EVENT'
27
+ after (2) { comm.disconnect } if m.read_property("event") =~ /DONE.(OK|ERROR)/
28
+ puts m.read_property("msg")
29
+ end
30
+ when 'ERROR'
31
+ logger.error m.read_content('reason') if m.read_content("inform_type") == 'ERROR'
32
+ when 'WARN'
33
+ logger.warn m.read_content('reason') if m.read_content("inform_type") == 'WARN'
34
+ end
35
+ end
36
+ end
37
+ end
38
+
39
+ msgs[:req_platform].on_inform_status do |m|
40
+ m.each_property do |p|
41
+ logger.info "#{p.attr('key')} => #{p.content.strip}"
42
+ end
43
+ end
44
+
45
+ testbed_topic.subscribe do
46
+ msgs[:create].publish testbed_topic.id
47
+ end
@@ -0,0 +1,72 @@
1
+ require 'securerandom'
2
+
3
+ module OmfEc
4
+ module Backward
5
+ module Group
6
+ # The following are ODEL 5 methods
7
+
8
+ # Create an application for the group and start it
9
+ #
10
+ def exec(name)
11
+ create_resource(name, type: 'application', binary_path: name)
12
+
13
+ e_uid = SecureRandom.uuid
14
+
15
+ e_name = "#{self.name}_application_#{name}_created_#{e_uid}"
16
+
17
+ def_event e_name do |state|
18
+ state.find_all { |v| v[:hrn] == name }.size >= self.members.uniq.size
19
+ end
20
+
21
+ on_event e_name do
22
+ resources[type: 'application', name: name].state = :run
23
+ end
24
+ end
25
+
26
+ def startApplications
27
+ resources[type: 'application'].state = :run
28
+ end
29
+
30
+ def stopApplications
31
+ resources[type: 'application'].state = :stop
32
+ end
33
+
34
+ def addApplication(name, &block)
35
+ app_cxt = OmfEc::Context::AppContext.new(name)
36
+ block.call(app_cxt) if block
37
+ self.app_contexts << app_cxt
38
+ end
39
+
40
+ # @example
41
+ # group('actor', 'node1', 'node2') do |g|
42
+ # g.net.w0.ip = '0.0.0.0'
43
+ # g.net.e0.ip = '0.0.0.1'
44
+ # end
45
+ def net
46
+ self.net_ifs ||= []
47
+ self
48
+ end
49
+
50
+ def method_missing(name, *args, &block)
51
+ if name =~ /w(\d+)/
52
+ net = self.net_ifs.find { |v| v.conf[:hrn] == "wlan#{$1}" }
53
+ if net.nil?
54
+ net = OmfEc::Context::NetContext.new(:type => 'wlan', :hrn => "wlan#{$1}", :index => $1)
55
+ self.net_ifs << net
56
+ end
57
+ net
58
+ elsif name =~ /e(\d+)/
59
+ net = self.net_ifs.find { |v| v.conf[:hrn] == "eth#{$1}" }
60
+ if net.nil?
61
+ net = OmfEc::Context::NetContext.new(:type => 'net', :hrn => "eth#{$1}", :index => $1)
62
+ self.net_ifs << net
63
+ end
64
+ net
65
+ else
66
+ super
67
+ end
68
+ end
69
+
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,54 @@
1
+ module OmfEc::Context
2
+ class AppContext
3
+ attr_accessor :name, :app_def, :param_values, :oml_collections
4
+
5
+ # Keep track of contexts for each app, i.e. multiple contexts can share
6
+ # the same app def. This happens for example when a group can have the
7
+ # same applications added to it many times, but with different parameter
8
+ # values for each. Thus we need to distinguish these different context
9
+ @@context_count = Hash.new
10
+
11
+ def initialize(name)
12
+ if OmfEc.exp.app_definitions.key?(name)
13
+ self.app_def = OmfEc.exp.app_definitions[name]
14
+ self.param_values = Hash.new
15
+ self.oml_collections = Array.new
16
+ @@context_count[name] = 0 unless @@context_count.key?(name)
17
+ id = @@context_count[name]
18
+ @@context_count[name] += 1
19
+ self.name = "#{name}_cxt_#{id}"
20
+ self
21
+ else
22
+ raise RuntimeError, "Cannot create context for unknwon application '#{name}'"
23
+ end
24
+ end
25
+
26
+ def setProperty(key, value)
27
+ @param_values[key] = value
28
+ self
29
+ end
30
+
31
+ # For now this follows v5.4 syntax...
32
+ # We have not yet finalised an OML syntax inside OEDL for v6
33
+ def measure(mp,filters)
34
+ collection = {:url => OmfEc.exp.oml_uri, :streams => [] }
35
+ stream = { :mp => mp , :filters => [] }.merge(filters)
36
+ collection[:streams] << stream
37
+ @oml_collections << collection
38
+ end
39
+
40
+ def properties
41
+ # deep copy the properties from the our app definition
42
+ original = Marshal.load(Marshal.dump(app_def.properties))
43
+ p = original.merge({:type => 'application'})
44
+ @param_values.each { |k,v| p[:parameters][k][:value] = v if p[:parameters].key?(k) }
45
+ if @oml_collections.size > 0
46
+ p[:use_oml] = true
47
+ p[:oml][:id] = @name
48
+ p[:oml][:experiment] = OmfEc.exp.id
49
+ p[:oml][:collection] = @oml_collections
50
+ end
51
+ p
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,6 @@
1
+ module OmfEc::Context
2
+ class DefAppContext
3
+ attr_accessor :conf
4
+ end
5
+ end
6
+
@@ -0,0 +1,88 @@
1
+ module OmfEc::Context
2
+ class GroupContext
3
+ attr_accessor :group
4
+ attr_accessor :guard
5
+ attr_accessor :operation
6
+
7
+ def initialize(opts)
8
+ self.group = opts.delete(:group)
9
+ self.guard = opts
10
+ self
11
+ end
12
+
13
+ def [](opts = {})
14
+ self.guard.merge!(opts)
15
+ self
16
+ end
17
+
18
+ def method_missing(name, *args, &block)
19
+ if name =~ /(.+)=/
20
+ self.operation = :configure
21
+ name = $1
22
+ elsif name =~ /release/
23
+ self.operation = :release
24
+ else
25
+ self.operation = :request
26
+ end
27
+ send_message(name, *args, &block)
28
+ end
29
+
30
+ def send_message(name, value = nil, &block)
31
+ send_to = self.group
32
+ send_to = send_to + "_#{self.guard[:type]}" if self.guard[:type]
33
+
34
+ # if release, we need to request resource ids first
35
+ op_name = self.operation == :release ? "request_message" : "#{self.operation}_message"
36
+
37
+ o_m = OmfEc.comm.__send__(op_name, send_to) do |m|
38
+ m.element(:guard) do |g|
39
+ self.guard.each_pair do |k, v|
40
+ g.property(k, v)
41
+ end
42
+ end
43
+
44
+ unless self.operation == :release
45
+ m.property(name, value)
46
+ end
47
+
48
+ unless self.operation == :configure
49
+ m.property(:uid)
50
+ m.property(:hrn)
51
+ end
52
+ end
53
+
54
+ o_m.publish send_to
55
+
56
+ o_m.on_inform_status do |i|
57
+ if self.operation == :release
58
+ uid = i.read_property(:uid)
59
+ info "Going to release #{uid}"
60
+ release_m = OmfEc.comm.release_message(self.group) { |m| m.element('resource_id', uid) }
61
+
62
+ release_m.publish self.group
63
+
64
+ release_m.on_inform_released do |m|
65
+ info "#{m.resource_id} released"
66
+ r = OmfEc.exp.state.find { |v| v[:uid] == m.resource_id }
67
+ r[:released] = true unless r.nil?
68
+ block.call if block
69
+ Experiment.instance.process_events
70
+ end
71
+ end
72
+
73
+ r = OmfEc.exp.state.find { |v| v[:uid] == i.read_property(:uid) }
74
+ unless r.nil?
75
+ i.each_property do |p|
76
+ p_key = p.attr('key').to_sym
77
+ r[p_key] = i.read_property(p_key)
78
+ end
79
+ end
80
+ Experiment.instance.process_events
81
+ end
82
+
83
+ o_m.on_inform_failed do |i|
84
+ warn "RC reports failure: '#{i.read_content("reason")}'"
85
+ end
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,46 @@
1
+ module OmfEc::Context
2
+ class NetContext
3
+ # Wifi frequency channel matching
4
+ FREQUENCY= {
5
+ 1 => 2412, 2 => 2417, 3 => 2422, 4 => 2427, 5 => 2432, 6 => 2437,
6
+ 7 => 2442, 8 => 2447, 9 => 2452, 10 => 2457, 11 => 2462, 12 => 2467,
7
+ 13 => 2472, 14 => 2484, 36 => 5180, 40 => 5200, 44 => 5220, 48 => 5240,
8
+ 52 => 5260, 56 => 5280, 60 => 5300, 64 => 5320, 100 => 5500, 104 => 5520,
9
+ 108 => 5540, 112 => 5560, 116 => 5580, 120 => 5600, 124 => 5620, 128 => 5640,
10
+ 132 => 5660, 136 => 5680, 140 => 5700, 149 => 5745, 153 => 5765, 157 => 5785,
11
+ 161 => 5805, 165 => 5825
12
+ }
13
+
14
+ attr_accessor :conf
15
+
16
+ def initialize(opts)
17
+ self.conf = opts
18
+ self
19
+ end
20
+
21
+ def method_missing(name, *args, &block)
22
+ if name =~ /(.+)=/
23
+ net_prop = $1.to_sym
24
+ net_prop = case net_prop
25
+ when :type then :hw_mode
26
+ when :ip then :ip_addr
27
+ else
28
+ net_prop
29
+ end
30
+ self.conf.merge!(net_prop => args[0])
31
+ else
32
+ super
33
+ end
34
+ end
35
+
36
+ def map_channel_freq
37
+ if self.conf[:channel] && self.conf[:frequency].nil?
38
+ self.conf[:frequency] = FREQUENCY[self.conf[:channel].to_i]
39
+ end
40
+ if self.conf[:channel].nil? && self.conf[:frequency]
41
+ self.conf[:channel] = FREQUENCY.keys.find { |k| FREQUENCY[k] == self.conf[:frequency].to_i }
42
+ end
43
+ self
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,10 @@
1
+ require 'omf_ec/context/group_context'
2
+ require 'omf_ec/context/net_context'
3
+ require 'omf_ec/context/app_context'
4
+ require 'omf_ec/context/def_app_context'
5
+
6
+ module OmfEc
7
+ module Context
8
+ end
9
+ end
10
+