ruby-sml 0.2

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,98 @@
1
+ require 'digest/sha2'
2
+ require 'openssl'
3
+
4
+ require 'ruby-sml/nilclass-mixin'
5
+ require 'ruby-sml/sml-time'
6
+
7
+ module SML
8
+
9
+ class ListEntry
10
+ attr_accessor :name, :status, :status_type, :value_time, :unit, :scaler, :value, :value_type, :signature
11
+
12
+ def initialize(name, status, status_type, value_time, unit, scaler, value, value_type, signature)
13
+ @name = name
14
+ @status = status
15
+ @status_type = status_type
16
+ @value_time = value_time
17
+ @unit = unit
18
+ @scaler = scaler
19
+ @value = value
20
+ @value_type = value_type
21
+ @signature = signature
22
+ end
23
+
24
+ def self.construct(array_rep)
25
+ return nil if array_rep.nil?
26
+ name = array_rep.shift
27
+ status = array_rep.shift
28
+ status_type = array_rep.shift unless status.nil?
29
+ value_time = SML::Time.construct(array_rep.shift)
30
+ unit = array_rep.shift
31
+ array_rep.shift unless unit.nil?
32
+ scaler = array_rep.shift
33
+ array_rep.shift unless scaler.nil?
34
+ value = array_rep.shift
35
+ case value
36
+ when Fixnum
37
+ value_type = array_rep.shift
38
+ when String
39
+ value_type = :string
40
+ end
41
+ signature = array_rep.shift
42
+
43
+ return nil if (value.nil? or name.nil?)
44
+ return SML::ListEntry.new(name, status, status_type, value_time, unit, scaler, value, value_type, signature)
45
+ end
46
+
47
+ def self.pconstruct(o={})
48
+ return SML::ListEntry.new(o[:name], o[:status], o[:status_type], o[:value_time], o[:unit], o[:scaler], o[:value], o[:value_type], o[:signature])
49
+ end
50
+
51
+ def to_a
52
+ result = [] << name << status << status_type << value_time.to_a << unit << :uint8 << scaler << :int8 << value
53
+ result << value_type if value.class == Fixnum
54
+ return result << signature
55
+ end
56
+
57
+ def calculate_hash(server_id)
58
+ return nil unless [:int8, :int16, :int32, :int64, :uint8, :uint16, :uint32, :uint64].include?(@value_type)
59
+ return nil unless @value_time.type == :timestamp
60
+ return nil unless @name.length == 6
61
+
62
+ bytes = String.new
63
+ bytes += server_id
64
+ (10-server_id.length).times do
65
+ bytes += [0x00].pack('c')
66
+ end
67
+ bytes += [@value_time.value].pack('N')
68
+ bytes += [@status].pack('c')
69
+ bytes += @name
70
+ bytes += [@unit].pack('c')
71
+ bytes += [@scaler].pack('c')
72
+ bytes += [(@value & 0xffff0000) >> 32,(@value & 0x0000ffff)].pack('NN')
73
+ 17.times do
74
+ bytes += [0x00].pack('c')
75
+ end
76
+
77
+ hash = Digest::SHA2.new(256).digest(bytes)[0,24]
78
+
79
+ return hash
80
+ end
81
+ def sign(server_id, private_key)
82
+ hash = calculate_hash(server_id)
83
+ return nil if hash.nil?
84
+
85
+ signature = OpenSSL::PKey::EC.new(private_key).dsa_sign_asn1(hash)
86
+
87
+ @signature = signature
88
+ end
89
+ def verify(server_id, public_key)
90
+ hash = calculate_hash(server_id)
91
+ return nil if hash.nil?
92
+
93
+ return OpenSSL::PKey::EC.new(public_key).dsa_verify_asn1(hash,@signature)
94
+ end
95
+
96
+ end
97
+
98
+ end
@@ -0,0 +1,87 @@
1
+ require 'ruby-sml/nilclass-mixin'
2
+ require 'ruby-sml/sml-messagebody'
3
+
4
+ require 'ruby-sml/encoding-binary'
5
+
6
+ module SML
7
+
8
+ class Message
9
+ attr_accessor :transaction_id, :group_no, :abort_on_error, :body, :checksum
10
+
11
+ def initialize(transaction_id, group_no, abort_on_error, body, checksum)
12
+ @transaction_id = transaction_id
13
+ @group_no = group_no
14
+ @abort_on_error = abort_on_error
15
+ @body = body
16
+ @checksum = checksum
17
+ end
18
+
19
+ def self.construct(array_rep)
20
+ return nil if array_rep.nil?
21
+ transaction_id = array_rep.shift
22
+ group_no = array_rep.shift
23
+ array_rep.shift unless group_no.nil?
24
+ abort_on_error_code = array_rep.shift
25
+ array_rep.shift unless abort_on_error_code.nil?
26
+ abort_on_error = nil
27
+ abort_on_error = case abort_on_error_code
28
+ when 0x00
29
+ :continue
30
+ when 0x01
31
+ :continue_with_next_group
32
+ when 0x02
33
+ :finish_group
34
+ when 0xff
35
+ :abort
36
+ end
37
+ body = SML::MessageBody.construct(array_rep.shift)
38
+ return nil if body.nil?
39
+ checksum = array_rep.shift
40
+ array_rep.shift unless checksum.nil?
41
+
42
+ return nil unless array_rep.shift == :end_of_message
43
+ return SML::Message.new(transaction_id, group_no, abort_on_error, body, checksum)
44
+ end
45
+
46
+ def self.pconstruct(o={})
47
+ return SML::Message.new(o[:transaction_id], o[:group_no], o[:abord_on_error], o[:body], o[:checksum])
48
+ end
49
+
50
+ def to_a
51
+ calculate_checksum
52
+ return to_a_internal
53
+ end
54
+
55
+ def to_a_internal
56
+ abort_on_error_code = case abort_on_error
57
+ when :continue
58
+ 0x00
59
+ when :continue_with_next_group
60
+ 0x01
61
+ when :finish_group
62
+ 0x02
63
+ when :abort
64
+ 0xff
65
+ end
66
+
67
+ result = [] << transaction_id << group_no
68
+ result << :uint8 unless group_no.nil?
69
+ result << abort_on_error_code
70
+ result << :uint8 unless abort_on_error_code.nil?
71
+ result << SML::MessageBody.to_a(body) << checksum
72
+ result << :uint16 unless checksum.nil?
73
+ return result << :end_of_message
74
+ end
75
+
76
+ def calculate_checksum
77
+ encoded = SML::BinaryEncoding.encode_value(self.to_a_internal, :array)
78
+ encoded.slice!(-3,3)
79
+ calculated_checksum = CRC16.crc16(encoded)
80
+ calculated_checksum = (calculated_checksum ^ 0xffff)
81
+ calculated_checksum = ((calculated_checksum & 0xff00) >> 8) | ((calculated_checksum & 0x00ff) << 8)
82
+ @checksum = calculated_checksum
83
+ end
84
+
85
+ end
86
+
87
+ end
@@ -0,0 +1,95 @@
1
+ require 'ruby-sml/nilclass-mixin'
2
+ require 'ruby-sml/sml-publicopen'
3
+ require 'ruby-sml/sml-publicclose'
4
+ require 'ruby-sml/sml-getprofilepack'
5
+ require 'ruby-sml/sml-getprofilelist'
6
+ require 'ruby-sml/sml-getprocparameter'
7
+ require 'ruby-sml/sml-setprocparameter'
8
+ require 'ruby-sml/sml-getlist'
9
+ require 'ruby-sml/sml-attention'
10
+
11
+ module SML
12
+
13
+ class MessageBody
14
+
15
+ def self.construct(array_rep)
16
+ return nil if array_rep.nil?
17
+ choice = array_rep.shift
18
+ array_rep.shift unless choice.nil?
19
+ body_array = array_rep.shift
20
+ return case choice
21
+ when 0x0100
22
+ SML::PublicOpen::Request.construct(body_array)
23
+ when 0x0101
24
+ SML::PublicOpen::Response.construct(body_array)
25
+ when 0x0200
26
+ SML::PublicClose::Request.construct(body_array)
27
+ when 0x0201
28
+ SML::PublicClose::Response.construct(body_array)
29
+ when 0x0300
30
+ SML::GetProfilePack::Request.construct(body_array)
31
+ when 0x0301
32
+ SML::GetProfilePack::Response.construct(body_array)
33
+ when 0x0400
34
+ SML::GetProfileList::Request.construct(body_array)
35
+ when 0x0401
36
+ SML::GetProfileList::Response.construct(body_array)
37
+ when 0x0500
38
+ SML::GetProcParameter::Request.construct(body_array)
39
+ when 0x0501
40
+ SML::GetProcParameter::Response.construct(body_array)
41
+ when 0x0600
42
+ SML::SetProcParameter::Request.construct(body_array)
43
+ when 0x0601
44
+ nil
45
+ # SML::SetProcParameter::Response.construct(body_array)
46
+ # SML_SetProcParameter.Res is supposed to exist, but the standard doesn't define it
47
+ # respones to SetProcParameter.Req are supposed to be SML_Attention.Res'
48
+ when 0x0700
49
+ SML::GetList::Request.construct(body_array)
50
+ when 0x0701
51
+ SML::GetList::Response.construct(body_array)
52
+ when 0xff01
53
+ SML::Attention::Response.construct(body_array)
54
+ end
55
+ end
56
+ def self.to_a(object)
57
+ choice = case object
58
+ when SML::PublicOpen::Request
59
+ 0x0100
60
+ when SML::PublicOpen::Response
61
+ 0x0101
62
+ when SML::PublicClose::Request
63
+ 0x0200
64
+ when SML::PublicClose::Response
65
+ 0x0201
66
+ when SML::GetProfilePack::Request
67
+ 0x0300
68
+ when SML::GetProfilePack::Response
69
+ 0x0301
70
+ when SML::GetProfileList::Request
71
+ 0x0400
72
+ when SML::GetProfileList::Response
73
+ 0x0401
74
+ when SML::GetProcParameter::Request
75
+ 0x0500
76
+ when SML::GetProcParameter::Response
77
+ 0x0501
78
+ when SML::SetProcParameter::Request
79
+ 0x0600
80
+ when SML::GetList::Request
81
+ 0x0700
82
+ when SML::GetList::Response
83
+ 0x0701
84
+ when SML::Attention::Response
85
+ 0xff01
86
+ end
87
+
88
+ result = [] << choice
89
+ result << :uint32 unless choice.nil?
90
+ return result << object.to_a
91
+ end
92
+
93
+ end
94
+
95
+ end
@@ -0,0 +1,38 @@
1
+ require 'ruby-sml/nilclass-mixin'
2
+
3
+ module SML
4
+
5
+ class PeriodEntry
6
+ attr_accessor :name, :unit, :scaler, :value, :value_type, :signature
7
+
8
+ def initialize(name, unit, scaler, value, value_type, signature)
9
+ @name = name
10
+ @unit = unit
11
+ @scaler = scaler
12
+ @value = value
13
+ @value_type = value_type
14
+ @signature = signature
15
+ end
16
+
17
+ def self.construct(array_rep)
18
+ return nil if array_rep.nil?
19
+ name = array_rep.shift
20
+ unit = array_rep.shift
21
+ scaler = array_rep.shift
22
+ array_rep.shift unless scaler.nil?
23
+ value = array_rep.shift
24
+ value_type = array_rep.shift
25
+ signature = array_rep.shift
26
+
27
+ return nil if value.nil?
28
+ return SML::PeriodEntry.new(name, unit, scaler, value, value_type, signature)
29
+ end
30
+ def to_a
31
+ result = [] << name << unit << scaler
32
+ result << :int8 unless scaler.nil?
33
+ return result << value << value_type << signature
34
+ end
35
+
36
+ end
37
+
38
+ end
@@ -0,0 +1,46 @@
1
+ require 'ruby-sml/nilclass-mixin'
2
+ require 'ruby-sml/sml-periodentry'
3
+ require 'ruby-sml/sml-tupelentry'
4
+ require 'ruby-sml/sml-time'
5
+
6
+ module SML
7
+
8
+ class ProcParameterValue
9
+
10
+ def self.construct(array_rep)
11
+ return nil if array_rep.nil?
12
+ choice = array_rep.shift
13
+ array_rep.shift unless choice.nil?
14
+ body_rep = array_rep.shift
15
+
16
+ return case choice
17
+ when 0x01
18
+ body_rep
19
+ when 0x02
20
+ SML::PeriodEntry.construct(body_rep)
21
+ when 0x03
22
+ SML::TupelEntry.construct(body_rep)
23
+ when 0x04
24
+ SML::Time.construct(body_rep)
25
+ end
26
+ end
27
+ def self.to_a(object)
28
+ choice = case object
29
+ when SML::PeriodEntry
30
+ 0x02
31
+ when SML::TupelEntry
32
+ 0x03
33
+ when SML::Time
34
+ 0x04
35
+ else
36
+ 0x01
37
+ end
38
+
39
+ result = [] << choice
40
+ result << :uint8 unless choice.nil?
41
+ return result << object
42
+ end
43
+
44
+ end
45
+
46
+ end
@@ -0,0 +1,31 @@
1
+ require 'ruby-sml/nilclass-mixin'
2
+
3
+ module SML
4
+
5
+ class ProfileObjectHeaderEntry
6
+ attr_accessor :name, :unit, :scaler
7
+
8
+ def initialize(name, unit, scaler)
9
+ @name = name
10
+ @unit = unit
11
+ @scaler = scaler
12
+ end
13
+
14
+ def self.construct(array_rep)
15
+ return nil if array_rep.nil?
16
+ name = array_rep.shift
17
+ unit = array_rep.shift
18
+ scaler = array_rep.shift
19
+ array_rep.shift unless scaler.nil?
20
+
21
+ return SML::ProfileObjectHeaderEntry.new(name, unit, scaler)
22
+ end
23
+ def to_a
24
+ result = [] << name << unit << scaler
25
+ result << :int8 unless scaler.nil?
26
+ return result
27
+ end
28
+
29
+ end
30
+
31
+ end
@@ -0,0 +1,46 @@
1
+ require 'ruby-sml/nilclass-mixin'
2
+ require 'ruby-sml/sml-time'
3
+ require 'ruby-sml/sml-valueentry'
4
+
5
+ module SML
6
+
7
+ class ProfileObjectPeriodEntry
8
+ attr_accessor :val_time, :status, :value_list, :period_signature
9
+
10
+ def initialize(val_time, status, value_list, period_signature)
11
+ @val_time = val_time
12
+ @status = status
13
+ @value_list = value_list
14
+ @period_signature = period_signature
15
+ end
16
+
17
+ def self.construct(array_rep)
18
+ return nil if array_rep.nil?
19
+ val_time = SML::Time.construct(array_rep.shift)
20
+ status = array_rep.shift
21
+ array_rep.shift unless status.nil?
22
+ value_list = []
23
+ array_rep.shift.each do |entry_array_rep|
24
+ entry = SML::ValueEntry.construct(entry_array_rep)
25
+ return nil if entry.nil?
26
+ value_list << entry
27
+ end
28
+ period_signature = array_rep.shift
29
+
30
+ return nil if val_time.nil?
31
+ return SML::ProfileObjectPeriodEntry.new(val_time, status, value_list, period_signature)
32
+ end
33
+ def to_a
34
+ value_list_array = []
35
+ value_list.each do |entry|
36
+ value_list_array << entry.to_a
37
+ end
38
+
39
+ result = [] << val_time.to_a << status
40
+ result << :uint64 unless status.nil?
41
+ return result << value_list_array << period_signature
42
+ end
43
+
44
+ end
45
+
46
+ end