ruby-sml 0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -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