gmsec 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,87 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bundler/setup'
4
+
5
+ require 'gmsec'
6
+ require 'commander'
7
+
8
+ class Program
9
+ include Commander::Methods
10
+ include GMSEC
11
+
12
+ MESSAGE_TYPES = %w[
13
+ LOG ARCHIVE-MESSAGE-RETRIEVAL-REQUEST ARCHIVE-MESSAGE-RETRIEVAL-RESPONSE
14
+ DIRECTIVE-REQUEST DIRECTIVE-RESPONSE C2CX-CONFIGURATION C2CX-CONTROL
15
+ C2CX-DEVICE C2CX-HEARTBEAT C2CX-RESOURCE TELEMETRY-CCSDS-PACKET
16
+ TELEMETRY-CCSDS-FRAME REPLAY-TELEMETRY-REQUEST REPLAY-TELEMETRY-RESPONSE
17
+ MNEMONIC-VALUE-REQUEST MNEMONIC-VALUE-RESPONSE MNEMONIC-VALUE-DATA-MESSAGE
18
+ ARCHIVE-MNEMONIC-VALUE-REQUEST ARCHIVE-MNEMONIC-VALUE-RESPONSE
19
+ ARCHIVE-MNEMONIC-VALUE-DATA DATABASE-ATTRIBUTES-REQUEST
20
+ DB-RESPONSE-LIMIT-SET DB-RESPONSE-TEXT-CONVERSION DB-RESPONSE-CAL-CURVE
21
+ DB-RESPONSE-SHORT-DESCRIPTION DB-RESPONSE-LONG-DESCRIPTION
22
+ DB-RESPONSE-LIST-OF-MNEMONICS COMMAND-REQUEST COMMAND-RESPONSE
23
+ PRODUCT-REQUEST PRODUCT-RESPONSE PRODUCT-MSG]
24
+
25
+ def run
26
+ program :name, 'gm_msg_config'
27
+ program :version, VERSION
28
+ program :description, 'Ruby implementation of the gm_msg_config.c example GMSEC program'
29
+
30
+ default_command :run
31
+
32
+ command :run do |c|
33
+ c.syntax = 'usage: gm_msg_config <filename.xml>'
34
+ c.description = 'Read the contents of a config file and prompt the user to which messages they would like to publish.'
35
+ c.action do |args, options|
36
+
37
+ say API.api_version
38
+
39
+ config_file = ConfigFile.new(args.first)
40
+
41
+ config = GMSEC::Config.from_config_file(config_file, "GMSEC-MESSAGE-BUS").tap do |config|
42
+ say config.to_xml
43
+ end
44
+
45
+ connection = Connection.new(config).tap do |connection|
46
+ connection.connect
47
+ say connection.library_version
48
+ end
49
+
50
+ while
51
+ # Ask user for message type.
52
+ message_type = ask_for_message_type
53
+
54
+ # Create a new message from the connection.
55
+ message = connection.new_message.tap do |message|
56
+ message.load_fields_from_config_file(config_file, message_type)
57
+ say message.to_xml
58
+ end
59
+
60
+ connection.publish(message)
61
+
62
+ break unless agree("Display another format_message? (y/n)")
63
+ end
64
+ end
65
+ end
66
+
67
+ run!
68
+ end
69
+
70
+ def ask_for_message_type
71
+ MESSAGE_TYPES.each_with_index do |config_type, i|
72
+ say "#{i+1}.)\t#{config_type}"
73
+ end
74
+
75
+ message_number = ask(<<-TEXT.gsub(/^\s+/, ""), Integer) do |q|
76
+ ======================================================================
77
+ Select the number of the desired GMSEC Message format to be displayed:
78
+ ======================================================================
79
+ TEXT
80
+ q.in = 1..MESSAGE_TYPES.length
81
+ end
82
+
83
+ MESSAGE_TYPES[message_number]
84
+ end
85
+ end
86
+
87
+ Program.new.run if $0 == __FILE__
@@ -0,0 +1,57 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bundler/setup'
4
+
5
+ require 'gmsec'
6
+ require 'commander'
7
+
8
+ class Program
9
+ include Commander::Methods
10
+ include GMSEC
11
+
12
+ def run
13
+ program :name, 'gm_msg_config'
14
+ program :version, VERSION
15
+ program :description, 'Ruby implementation of the gmconfig.c example GMSEC program'
16
+
17
+ default_command :run
18
+
19
+ command :run do |c|
20
+ c.syntax = 'usage: gmconfig_c <filename>'
21
+ c.description = 'Read a configuration file and publish a preconfigured message several times'
22
+ c.action do |args, options|
23
+
24
+ say API.api_version
25
+
26
+ config_file = ConfigFile.new(args.first)
27
+
28
+ config = GMSEC::Config.from_config_file(config_file, "config1").tap do |config|
29
+ say config.to_xml
30
+ end
31
+
32
+ connection = Connection.new(config).tap do |connection|
33
+ connection.connect
34
+ say connection.library_version
35
+ end
36
+
37
+ subject = config_file.get_subscription("events").tap do |subject|
38
+ say "Subscribe to #{subject}"
39
+ end
40
+
41
+ message = connection.new_message.tap do |message|
42
+ message.load_fields_from_config_file(config_file, "msg1")
43
+ say message.to_xml
44
+ end
45
+
46
+ 10.times do
47
+ say message.to_xml
48
+ connection.publish(message)
49
+ end
50
+ end
51
+ end
52
+
53
+ run!
54
+ end
55
+ end
56
+
57
+ Program.new.run if $0 == __FILE__
@@ -0,0 +1,45 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+
3
+ <!--
4
+ Copyright 2007-2014 United States Government as represented by the
5
+ Administrator of The National Aeronautics and Space Administration.
6
+ All Rights Reserved.
7
+ -->
8
+
9
+
10
+
11
+
12
+ <DEFINITIONS>
13
+ <SUBSCRIPTION NAME="events" PATTERN="GMSEC.MISSION.CONST.SAT.EVT.MSG.>"/>
14
+ <SUBSCRIPTION NAME="custom1" PATTERN="CUSTOM.MESSAGE.SUBJECTS.*"/>
15
+ <CONFIG NAME="config2">
16
+ <PARAMETER NAME="connectiontype">gmsec_mb</PARAMETER>
17
+ <PARAMETER NAME="loglevel">info</PARAMETER>
18
+ <PARAMETER NAME="server">localhost</PARAMETER>
19
+ <PARAMETER NAME="port">9000</PARAMETER>
20
+ </CONFIG>
21
+ <CONFIG NAME="config1">
22
+ <PARAMETER NAME="connectiontype">gmsec_mb</PARAMETER>
23
+ <PARAMETER NAME="loglevel">info</PARAMETER>
24
+ <PARAMETER NAME="server">localhost</PARAMETER>
25
+ <PARAMETER NAME="tracking">true</PARAMETER>
26
+ <PARAMETER NAME="isthreaded">true</PARAMETER>
27
+ <PARAMETER NAME="compress">true</PARAMETER>
28
+ </CONFIG>
29
+ <MESSAGE NAME="msg1" SUBJECT="GMSEC.MISSION.CONST.SAT.EVT.MSG" KIND="PUBLISH">
30
+ <CONFIG NAME="msg_config">
31
+ <PARAMETER NAME="KIND">GMSEC_MSG_PUBLISH</PARAMETER>
32
+ </CONFIG>
33
+ <FIELD TYPE="CHAR" NAME="C">c</FIELD>
34
+ <FIELD TYPE="BOOL" NAME="T">TRUE</FIELD>
35
+ <FIELD TYPE="BOOL" NAME="F">FALSE</FIELD>
36
+ <FIELD TYPE="I16" NAME="J">123</FIELD>
37
+ <FIELD TYPE="U16" NAME="K">123</FIELD>
38
+ <FIELD TYPE="I32" NAME="I">123</FIELD>
39
+ <FIELD TYPE="U32" NAME="U">123</FIELD>
40
+ <FIELD TYPE="STRING" NAME="S">This is a test</FIELD>
41
+ <FIELD TYPE="F32" NAME="E">123</FIELD>
42
+ <FIELD TYPE="F64" NAME="D">123</FIELD>
43
+ <FIELD TYPE="BIN" NAME="X">4a4c4d4e4f5051</FIELD>
44
+ </MESSAGE>
45
+ </DEFINITIONS>
@@ -0,0 +1,76 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bundler/setup'
4
+
5
+ require 'gmsec'
6
+ require 'commander'
7
+
8
+ class Program
9
+ include Commander::Methods
10
+ include GMSEC
11
+
12
+ def run
13
+ program :name, 'gm_msg_config'
14
+ program :version, VERSION
15
+ program :description, 'Ruby implementation of the gmconfig.c example GMSEC program'
16
+
17
+ default_command :run
18
+
19
+ command :run do |c|
20
+ c.syntax = 'usage: gmconfig_c <filename>'
21
+ c.description = 'Read a configuration file and publish a preconfigured message several times'
22
+ c.action do |args, options|
23
+
24
+ say API.api_version
25
+
26
+ config = GMSEC::Config.new.tap do |config|
27
+ args.each do |argument|
28
+ key, value = argument.split("=")
29
+ config[key] = value
30
+ end
31
+ end
32
+
33
+ subject = config["SUBJECT"] || "GMSEC.TEST.PUBLISH"
34
+ iterations = (config["ITERATIONS"] || 1).to_i
35
+ interval_ms = (config["INTERVAL_MS"] || 1000).to_i
36
+
37
+ connection = Connection.new(config).tap do |connection|
38
+ connection.connect
39
+ say connection.library_version
40
+ end
41
+
42
+ (1..iterations).each do |iteration|
43
+ value = iteration + 1
44
+
45
+ message = connection.new_message.tap do |message|
46
+ fields = [Field.new("C", "c", type: :char),
47
+ Field.new("T", true, type: :bool),
48
+ Field.new("F", false, type: :bool),
49
+ Field.new("J", value, type: :i16),
50
+ Field.new("K", value, type: :u16),
51
+ Field.new("I", value, type: :i32),
52
+ Field.new("COUNT", iteration, type: :i32),
53
+ Field.new("U", value, type: :u32),
54
+ Field.new("S", value, type: :str),
55
+ Field.new("E", value, type: :f32),
56
+ Field.new("D", value, type: :f64)]
57
+
58
+ fields.each do |field|
59
+ message << field
60
+ end
61
+ end
62
+
63
+ puts message.to_xml
64
+
65
+ connection.publish(message)
66
+
67
+ sleep interval_ms / 1000.0
68
+ end
69
+ end
70
+ end
71
+
72
+ run!
73
+ end
74
+ end
75
+
76
+ Program.new.run if $0 == __FILE__
@@ -0,0 +1,29 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'gmsec/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'gmsec'
8
+ spec.version = GMSEC::VERSION
9
+ spec.authors = ['Stefan Novak']
10
+ spec.email = ['stefan@novak.io']
11
+ spec.summary = %q{Unofficial Ruby wrapper for NASA's GMSEC.}
12
+ spec.description = %q{Unofficial Ruby wrapper for NASA's GMSEC. For more information, visit http://gmsec.gsfc.nasa.gov/.}
13
+ spec.homepage = 'http://gmsec.gsfc.nasa.gov/'
14
+ spec.license = 'MIT'
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ['lib']
20
+
21
+ spec.add_development_dependency 'bundler', '~> 1.7'
22
+ spec.add_development_dependency 'commander', '~> 4.2.1'
23
+ spec.add_development_dependency 'pry', '~> 0.10.1'
24
+ spec.add_development_dependency 'rake', '~> 10.0'
25
+ spec.add_development_dependency 'rspec', '~> 3.1.0'
26
+
27
+ spec.add_dependency 'ffi', '~> 1.9.6'
28
+ spec.add_dependency 'terminal-table', '~> 1.4.5'
29
+ end
@@ -0,0 +1,15 @@
1
+ require 'ffi'
2
+ require 'terminal-table'
3
+
4
+ require 'gmsec/version'
5
+
6
+ module GMSEC
7
+ autoload :API, 'gmsec/api'
8
+ autoload :Config, 'gmsec/config'
9
+ autoload :ConfigFile, 'gmsec/config_file'
10
+ autoload :Connection, 'gmsec/connection'
11
+ autoload :Definitions, 'gmsec/definitions'
12
+ autoload :Field, 'gmsec/field'
13
+ autoload :Message, 'gmsec/message'
14
+ autoload :Status, 'gmsec/status'
15
+ end
@@ -0,0 +1,157 @@
1
+ module GMSEC::API
2
+
3
+ module Finalizer
4
+
5
+ # Allows us to specify #destroy! to be called on an instance during GC.
6
+ def initialize(*args, **kwargs)
7
+ ObjectSpace.define_finalizer(self, self.class.method(:destroy!).to_proc)
8
+
9
+ # If there is a `native_value` keyword argument supplied, assign
10
+ # the value to native_object
11
+ if native_object = kwargs.delete(:native_object)
12
+ @native_object = native_object
13
+ else
14
+ if respond_to? :native_object_initializer
15
+ initialize_native_object do |pointer|
16
+ native_object_initializer(pointer)
17
+ end
18
+ end
19
+ end
20
+
21
+ if kwargs.empty?
22
+ super(*args)
23
+ else
24
+ super(*args, **kwargs)
25
+ end
26
+ end
27
+ end
28
+
29
+ def self.extended(base)
30
+ base.extend FFI::Library
31
+ base.extend FFI::DataConverter
32
+ base.send :prepend, Finalizer
33
+
34
+ class << base
35
+ def to_native(value, context=nil)
36
+ value.instance_variable_get("@native_object")
37
+ end
38
+
39
+ def from_native(value, context=nil)
40
+ new(native_object: value)
41
+ end
42
+
43
+ def size
44
+ find_type(native_type).size
45
+ end
46
+
47
+ def destroy!(instance)
48
+ if instance.respond_to? :destroy!
49
+ instance.destroy!
50
+ end
51
+ end
52
+
53
+ def api_version
54
+ gmsec_GetAPIVersion
55
+ end
56
+ end
57
+
58
+ # Load the library for each time the API module is extended.
59
+ base.send(:load_library)
60
+ base.include GMSEC::Definitions
61
+ end
62
+
63
+ def bind(object_name, &block)
64
+ native_type find_type(object_name)
65
+
66
+ if block_given?
67
+ define_method(:native_object_initializer, &block)
68
+ end
69
+
70
+ protected
71
+
72
+ # Proxy #find_type through class
73
+ define_method(:find_type) do |type|
74
+ self.class.find_type(type)
75
+ end
76
+
77
+ define_method(:initialize_native_object) do |&block|
78
+ instance_eval do
79
+ pointer = FFI::MemoryPointer.new(self.class.native_type)
80
+ block.call(pointer)
81
+ @native_object = pointer.read_pointer
82
+ end
83
+ end
84
+
85
+ define_method(:with_string_pointer) do |&block|
86
+ pointer = FFI::MemoryPointer.new :pointer
87
+ block.call(pointer)
88
+ if pointer.read_pointer != nil
89
+ pointer.read_pointer.read_string_to_null
90
+ end
91
+ end
92
+ end
93
+
94
+ def has(*objects)
95
+ mapping = {
96
+ config: GMSEC::Config,
97
+ status: GMSEC::Status}
98
+
99
+ objects.select{|object| mapping.keys.include? object}.each do |object|
100
+ attr_accessor object
101
+
102
+ # Overwrite the getter method to memoize a new instance of the mapped object.
103
+ define_method(object) do
104
+ name = "@#{object}"
105
+ instance_variable_set(name, instance_variable_get(name) || mapping[object].new)
106
+ end
107
+ end
108
+ end
109
+
110
+ protected
111
+
112
+ def load_library
113
+ self.ffi_lib gmsec_library_path
114
+ end
115
+
116
+ def search_paths
117
+ @search_paths ||= begin
118
+ if ENV['GMSEC_LIBRARY_PATH']
119
+ ENV['GMSEC_LIBRARY_PATH']
120
+ elsif FFI::Platform.windows?
121
+ ENV['PATH'].split(File::PATH_SEPARATOR)
122
+ else
123
+ [ '/opt/local/{lib64,lib}',
124
+ '/opt/local/{lib64,lib}',
125
+ '/usr/lib/{x86_64,i386}-linux-gnu',
126
+ '/usr/local/{lib64,lib}',
127
+ '/usr/{lib64,lib}']
128
+ end
129
+ end
130
+ end
131
+
132
+ def find_lib(lib)
133
+ if ENV['GMSEC_LIBRARY_PATH'] && File.file?(ENV['GMSEC_LIBRARY_PATH'])
134
+ ENV['GMSEC_LIBRARY_PATH']
135
+ else
136
+ Dir.glob(search_paths.map {|path|
137
+ File.expand_path(File.join(path, "#{lib}.#{FFI::Platform::LIBSUFFIX}"))
138
+ }).first
139
+ end
140
+ end
141
+
142
+ def gmsec_library_path
143
+ @gmsec_library_path ||= begin
144
+ find_lib('{lib,}GMSECAPI{,-?}')
145
+ end
146
+ end
147
+
148
+ extend self
149
+
150
+ load_library
151
+
152
+ def self.api_version
153
+ gmsec_GetAPIVersion
154
+ end
155
+
156
+ attach_function :gmsec_GetAPIVersion, [], :string
157
+ end