orion6_rep 0.2.6

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,112 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Controle de Horas - Sistema para gestão de horas trabalhadas
3
+ # Copyright (C) 2009 O.S. Systems Softwares Ltda.
4
+
5
+ # This program is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU Affero General Public License as
7
+ # published by the Free Software Foundation, either version 3 of the
8
+ # License, or (at your option) any later version.
9
+
10
+ # This program is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU Affero General Public License for more details.
14
+
15
+ # You should have received a copy of the GNU Affero General Public License
16
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
17
+
18
+ # Rua Clóvis Gularte Candiota 132, Pelotas-RS, Brasil.
19
+ # e-mail: contato@ossystems.com.br
20
+
21
+ require "orion6_rep/multi_message_command"
22
+
23
+ module Orion6Rep
24
+ class EmployeeGet < Command
25
+ def initialize(first_employee, employees_number, equipment_number, host_address, tcp_port = 3000)
26
+ raise "employees_number must be from 1 to 11" if employees_number > 12 || employees_number < 1
27
+ @first_employee = first_employee
28
+ @employees_number = employees_number
29
+ @equipment_number = equipment_number
30
+ @host_address = host_address
31
+ @tcp_port = tcp_port
32
+ @reponse_size = (employees_number*RETURNED_RECORD_SIZE)+4+3
33
+ end
34
+
35
+ private
36
+ GET_EMPLOYEE_COMMAND = 0x86
37
+ EMPLOYEE_FIELD_SIZE = 0x1
38
+ EMPLOYEE_FIELD_QUANTITY = 0x9
39
+ # TODO: find what is this constant. It's the size of something, perhaps?
40
+ UNKNOWN_CONSTANT = 0x72
41
+ RETURNED_RECORD_SIZE = 87
42
+
43
+ def get_command
44
+ GET_EMPLOYEE_COMMAND
45
+ end
46
+
47
+ def get_unknown_constant
48
+ UNKNOWN_CONSTANT
49
+ end
50
+
51
+ def get_field_size
52
+ EMPLOYEE_FIELD_SIZE
53
+ end
54
+
55
+ def get_field_quantity
56
+ EMPLOYEE_FIELD_QUANTITY
57
+ end
58
+
59
+ def generate_command_data
60
+ def internal_crc_check(data)
61
+ crc_check(data[3..6])
62
+ end
63
+
64
+ # this data can change:
65
+ data = [0x02, 0x00, 0x04, 0x98]
66
+ data << divide_by_256(@first_employee)
67
+ data << (@first_employee & 255)
68
+ data << @employees_number
69
+ data << internal_crc_check(data)
70
+ data << 0x03
71
+ data << crc_check(data)
72
+ end
73
+
74
+ def get_data_from_response(payload)
75
+ # first byte is aways 2... I don't known why...
76
+ # The next two bytes are probably the record quantity, in big-endian.
77
+ record_quantity = (payload[1].ord*256 + payload[2].ord)
78
+
79
+ # byte #4 it's the beggining of the data:
80
+ start_offset = 4
81
+
82
+ # the end of the data is the size plus the start minus two, since the REP
83
+ # send the CRC at the end of the data and array starts at zero. The last
84
+ # two bytes appear to be the end data marker and a useless 3.
85
+ end_offset = record_quantity + start_offset - crc_size - 1
86
+
87
+ raw_data = payload[start_offset..end_offset]
88
+ slices = slice_raw_data(raw_data)
89
+
90
+ data = []
91
+ slices.each do |slice|
92
+ # the fields are separated by a comma, and the registration comes with a
93
+ # extra number at the end, so drop them:
94
+ registration, name, pis_number = slice.unpack("A20x2A52xA12")
95
+ data << {:name => name.to_s.strip, :registration => registration, :pis_number => pis_number}
96
+ end
97
+ data
98
+ end
99
+
100
+ def slice_raw_data(raw_data)
101
+ slices = []
102
+ index = 0
103
+ while index < raw_data.size
104
+ slice_start = index
105
+ slice_end = slice_start + RETURNED_RECORD_SIZE - 1
106
+ slices << raw_data[slice_start..slice_end]
107
+ index = slice_end + 1
108
+ end
109
+ slices
110
+ end
111
+ end
112
+ end
@@ -0,0 +1,81 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Controle de Horas - Sistema para gestão de horas trabalhadas
3
+ # Copyright (C) 2009 O.S. Systems Softwares Ltda.
4
+
5
+ # This program is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU Affero General Public License as
7
+ # published by the Free Software Foundation, either version 3 of the
8
+ # License, or (at your option) any later version.
9
+
10
+ # This program is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU Affero General Public License for more details.
14
+
15
+ # You should have received a copy of the GNU Affero General Public License
16
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
17
+
18
+ # Rua Clóvis Gularte Candiota 132, Pelotas-RS, Brasil.
19
+ # e-mail: contato@ossystems.com.br
20
+
21
+ require "orion6_rep/multi_message_command"
22
+
23
+ module Orion6Rep
24
+ class EmployeeQuantityGet < Command
25
+ def initialize(equipment_number, host_address, tcp_port = 3000)
26
+ @equipment_number = equipment_number
27
+ @host_address = host_address
28
+ @tcp_port = tcp_port
29
+ @reponse_size = 9
30
+ end
31
+
32
+ private
33
+ GET_EMPLOYEE_QUANTITY_COMMAND = 0x86
34
+ UNKNOWN_CONSTANT = 0x72
35
+ EMPLOYEE_FIELD_SIZE = 0x1
36
+ EMPLOYEE_FIELD_QUANTITY = 0x6
37
+ RETURNED_RECORD_SIZE = 87
38
+
39
+ def get_command
40
+ GET_EMPLOYEE_QUANTITY_COMMAND
41
+ end
42
+
43
+ def get_unknown_constant
44
+ UNKNOWN_CONSTANT
45
+ end
46
+
47
+ def get_field_size
48
+ EMPLOYEE_FIELD_SIZE
49
+ end
50
+
51
+ def get_field_quantity
52
+ EMPLOYEE_FIELD_QUANTITY
53
+ end
54
+
55
+ def get_sleep_time
56
+ 1
57
+ end
58
+
59
+ def generate_command_data
60
+ # this data is probably imutable:
61
+ data = [0x02, 0x00, 0x01, 0x97, 0x97, 0x03]
62
+ # [ 2, 0, 1, 151, 151, 3]
63
+ data << crc_check(data)
64
+ data
65
+ end
66
+
67
+ def get_data_from_response(payload)
68
+ # First byte is aways 2... I don't known why...
69
+ # The next two bytes are probably the record quantity, in big-endian.
70
+ record_quantity = (payload[1].ord*256 + payload[2].ord)
71
+
72
+ # The next three bytes appear to be the employee quantity, in big-endian:
73
+ raw_data = payload[3..(3+record_quantity)]
74
+ employee_quantity = (raw_data[0].ord << 16)+(raw_data[1].ord << 8)+ raw_data[2].ord
75
+
76
+ # The last three bytes appear to be a CRC XOR for the data, a useless 3
77
+ # and the XOR CRC for the whole payload
78
+ employee_quantity
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,104 @@
1
+ # Controle de Horas - Sistema para gestão de horas trabalhadas
2
+ # Copyright (C) 2009 O.S. Systems Softwares Ltda.
3
+
4
+ # This program is free software: you can redistribute it and/or modify
5
+ # it under the terms of the GNU Affero General Public License as
6
+ # published by the Free Software Foundation, either version 3 of the
7
+ # License, or (at your option) any later version.
8
+
9
+ # This program is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ # GNU Affero General Public License for more details.
13
+
14
+ # You should have received a copy of the GNU Affero General Public License
15
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
16
+
17
+ # Rua Clóvis Gularte Candiota 132, Pelotas-RS, Brasil.
18
+ # e-mail: contato@ossystems.com.br
19
+
20
+ require "orion6_rep/command"
21
+
22
+ module Orion6Rep
23
+ class EmployeeSet < Command
24
+ def initialize(operation_type, registration, pis_number, name, equipment_number, host_address, tcp_port = 3000)
25
+ set_operation_type(operation_type)
26
+ @registration = registration
27
+ @pis_number = pis_number
28
+ @name = name
29
+
30
+ @equipment_number = equipment_number
31
+ @host_address = host_address
32
+ @tcp_port = tcp_port
33
+
34
+ @reponse_size = 7 # just send the data and receive the ok
35
+ end
36
+
37
+ def set_operation_type(operation_type)
38
+ case operation_type
39
+ when :add
40
+ @operation_type = 0x31
41
+ when :edit
42
+ @operation_type = 0x32
43
+ when :remove
44
+ @operation_type = 0x33
45
+ else
46
+ raise "Unknown employee operation type received: #{operation_type.to_s}"
47
+ end
48
+ end
49
+
50
+ private
51
+ SET_EMPLOYEE_COMMAND = 0x86
52
+ UNKNOWN_CONSTANT = 0x72
53
+ EMPLOYEE_FIELD_SIZE = 0x1
54
+ EMPLOYEE_FIELD_QUANTITY = 0x5E
55
+
56
+ def get_command
57
+ SET_EMPLOYEE_COMMAND
58
+ end
59
+
60
+ def get_unknown_constant
61
+ UNKNOWN_CONSTANT
62
+ end
63
+
64
+ def get_field_size
65
+ EMPLOYEE_FIELD_SIZE
66
+ end
67
+
68
+ def get_field_quantity
69
+ EMPLOYEE_FIELD_QUANTITY
70
+ end
71
+
72
+ def generate_command_data
73
+ def internal_crc_check(data)
74
+ # crc check for the employee data:
75
+ crc_check(data[3..88])
76
+ end
77
+
78
+ # TODO: find out what is the meaning of the data in the array below:
79
+ data = [0x02, 0x00, 0x59, 0x95]
80
+
81
+ data += get_employee_data
82
+ data << internal_crc_check(data)
83
+ # unknown
84
+ data += [0x03]
85
+ data << crc_check(data)
86
+ end
87
+
88
+ def get_employee_data
89
+ data = [@operation_type]
90
+ data += @registration.to_s.rjust(20, "0").unpack("C*")
91
+ # This is probably the digital check byte; ignore it:
92
+ data += "0".unpack("C*")
93
+ data += ",".unpack("C*") # comma separating the fields
94
+ data += @name.to_s.ljust(52, " ").unpack("C*")
95
+ data += ",".unpack("C*") # comma separating the fields
96
+ data += @pis_number.to_s.rjust(12, "0").unpack("C*")
97
+ data
98
+ end
99
+
100
+ def get_data_from_response(payload)
101
+ true
102
+ end
103
+ end
104
+ end
@@ -0,0 +1,84 @@
1
+ # Controle de Horas - Sistema para gestão de horas trabalhadas
2
+ # Copyright (C) 2009 O.S. Systems Softwares Ltda.
3
+
4
+ # This program is free software: you can redistribute it and/or modify
5
+ # it under the terms of the GNU Affero General Public License as
6
+ # published by the Free Software Foundation, either version 3 of the
7
+ # License, or (at your option) any later version.
8
+
9
+ # This program is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ # GNU Affero General Public License for more details.
13
+
14
+ # You should have received a copy of the GNU Affero General Public License
15
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
16
+
17
+ # Rua Clóvis Gularte Candiota 132, Pelotas-RS, Brasil.
18
+ # e-mail: contato@ossystems.com.br
19
+
20
+ require "orion6_rep/multi_message_command"
21
+
22
+ module Orion6Rep
23
+ class EmployerGet < MultiMessageCommand
24
+ def initialize(equipment_number, host_address, tcp_port = 3000)
25
+ @equipment_number = equipment_number
26
+ @host_address = host_address
27
+ @tcp_port = tcp_port
28
+ end
29
+
30
+ private
31
+ GET_EMPLOYER_COMMAND = 128
32
+ EMPLOYER_FIELD_SIZE = 255
33
+ EMPLOYER_FIELD_QUANTITY = 263
34
+
35
+ def get_command
36
+ @command ||= GET_EMPLOYER_COMMAND
37
+ end
38
+
39
+ def get_field_size
40
+ EMPLOYER_FIELD_SIZE
41
+ end
42
+
43
+ def get_field_quantity
44
+ EMPLOYER_FIELD_QUANTITY
45
+ end
46
+
47
+ def generate_command_data
48
+ []
49
+ end
50
+
51
+ def get_expected_response_size
52
+ first_message_sent? ? 17 : 264
53
+ end
54
+
55
+ # Here is how the data comes from the REP:
56
+ # 0 - Document type:
57
+ # 49 ('1'): CNPJ
58
+ # 50 ('2'): CPF
59
+ # 1-14 - Document number (in hexadecimal long)
60
+ # 15-26 - CEI Document (in hexadecimal long)
61
+ # 27-176 - Company name
62
+ # 177-261 - Company location
63
+ def get_data_from_response(payload)
64
+ hash = {}
65
+
66
+ doc_type_code, document_number, cei_document, company_name, company_location = payload.unpack("CA14A12A150A84")
67
+
68
+ case doc_type_code
69
+ when 49
70
+ hash[:document_type] = :cnpj
71
+ when 50
72
+ hash[:document_type] = :cpf
73
+ else
74
+ raise "Unknown document type received: #{doc_type_code}"
75
+ end
76
+
77
+ hash[:document_number] = document_number
78
+ hash[:cei_document] = cei_document
79
+ hash[:company_name] = company_name.strip
80
+ hash[:company_location] = company_location.strip
81
+ hash
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,90 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Controle de Horas - Sistema para gestão de horas trabalhadas
3
+ # Copyright (C) 2009 O.S. Systems Softwares Ltda.
4
+
5
+ # This program is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU Affero General Public License as
7
+ # published by the Free Software Foundation, either version 3 of the
8
+ # License, or (at your option) any later version.
9
+
10
+ # This program is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU Affero General Public License for more details.
14
+
15
+ # You should have received a copy of the GNU Affero General Public License
16
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
17
+
18
+ # Rua Clóvis Gularte Candiota 132, Pelotas-RS, Brasil.
19
+ # e-mail: contato@ossystems.com.br
20
+
21
+ require "orion6_rep/multi_message_command"
22
+
23
+ module Orion6Rep
24
+ class EmployerSet < Command
25
+ def initialize(employer_name, employer_location, document_type, document_number, cei_number, equipment_number, host_address, tcp_port = 3000)
26
+ @employer_name = employer_name
27
+ @employer_location = employer_location
28
+ @document_type = document_type
29
+ @document_number = document_number
30
+ @cei_number = cei_number
31
+
32
+ @equipment_number = equipment_number
33
+ @host_address = host_address
34
+ @tcp_port = tcp_port
35
+ @reponse_size = 0
36
+ end
37
+
38
+ private
39
+ SET_EMPLOYER_COMMAND = 143
40
+ EMPLOYER_FIELD_SIZE = 1
41
+ EMPLOYER_FIELD_QUANTITY = 263
42
+
43
+ def get_command
44
+ SET_EMPLOYER_COMMAND
45
+ end
46
+
47
+ def get_field_size
48
+ EMPLOYER_FIELD_SIZE
49
+ end
50
+
51
+ def get_field_quantity
52
+ EMPLOYER_FIELD_QUANTITY
53
+ end
54
+
55
+ # Here is how the data goes to the REP:
56
+ # 0 - 1
57
+ # 1 - Document type:
58
+ # 1: CNPJ
59
+ # 2: CPF
60
+ # 2-15 - Document number (in hexadecimal long)
61
+ # 16-27 - CEI Document (in hexadecimal long)
62
+ # 28-177 - Company name
63
+ # 178-263 - Company location
64
+ def generate_command_data
65
+ data = [1] # TODO: find out why this one is needed.
66
+
67
+ # get document type:
68
+ case @document_type
69
+ when :cnpj
70
+ data << 49
71
+ when :cpf
72
+ data << 50
73
+ else
74
+ raise "Unknown document type received: #{@document_type}"
75
+ end
76
+
77
+ data += @document_number.to_s.rjust(14, "0").unpack("C*")
78
+ data += @cei_number.to_s.rjust(12, "0").unpack("C*")
79
+ data += @employer_name.to_s.ljust(150, 0.chr).unpack("C*")
80
+ data += @employer_location.to_s.ljust(85, 0.chr).unpack("C*")
81
+ data << crc_check(data)
82
+
83
+ data
84
+ end
85
+
86
+ def get_data_from_response(payload)
87
+ true
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,64 @@
1
+ # Controle de Horas - Sistema para gestão de horas trabalhadas
2
+ # Copyright (C) 2009 O.S. Systems Softwares Ltda.
3
+
4
+ # This program is free software: you can redistribute it and/or modify
5
+ # it under the terms of the GNU Affero General Public License as
6
+ # published by the Free Software Foundation, either version 3 of the
7
+ # License, or (at your option) any later version.
8
+
9
+ # This program is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ # GNU Affero General Public License for more details.
13
+
14
+ # You should have received a copy of the GNU Affero General Public License
15
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
16
+
17
+ # Rua Clóvis Gularte Candiota 132, Pelotas-RS, Brasil.
18
+ # e-mail: contato@ossystems.com.br
19
+
20
+ require "orion6_rep/command"
21
+
22
+ module Orion6Rep
23
+ class GetSerialNumber < Command
24
+ def initialize(equipment_number, host_address, tcp_port = 3000)
25
+ @equipment_number = equipment_number
26
+ @host_address = host_address
27
+ @tcp_port = tcp_port
28
+ @reponse_size = RETURNED_RECORD_SIZE
29
+ end
30
+
31
+ private
32
+ GET_SERIAL_NUMBER_COMMAND = 0x97
33
+ # TODO: find what is this constant. It's the size of something, perhaps?
34
+ UNKNOWN_CONSTANT = 0x00
35
+ SERIAL_NUMBER_FIELD_SIZE = 0x108
36
+ SERIAL_NUMBER_FIELD_QUANTITY = 0x2a
37
+ RETURNED_RECORD_SIZE = 9
38
+
39
+ def get_command
40
+ GET_SERIAL_NUMBER_COMMAND
41
+ end
42
+
43
+ def get_unknown_constant
44
+ UNKNOWN_CONSTANT
45
+ end
46
+
47
+ def get_field_size
48
+ SERIAL_NUMBER_FIELD_SIZE
49
+ end
50
+
51
+ def get_field_quantity
52
+ SERIAL_NUMBER_FIELD_QUANTITY
53
+ end
54
+
55
+ def generate_command_data
56
+ # No data in this command:
57
+ []
58
+ end
59
+
60
+ def get_data_from_response(payload)
61
+ convert_to_integer_as_big_endian(payload.unpack("C*")).to_s.rjust(17, "0")
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,55 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Adapted from
3
+ # http://blog.frameos.org/2006/12/09/getting-network-interface-addresses-using-ioctl-pure-ruby-2/
4
+ # in 23/02/2011.
5
+
6
+ require 'socket'
7
+ require 'system/getifaddrs'
8
+
9
+ module Orion6Rep
10
+ module Interface
11
+ # From bits/ioctls.h
12
+ SIOCGIFHWADDR = 0x8927 # Get hardware address
13
+ SIOCGIFADDR = 0x8915 # Get PA address
14
+ SIOCGIFBRDADDR = 0x8919 # Get broadcast PA address
15
+
16
+ class << self
17
+ def get_active_interfaces_names
18
+ System.get_ifaddrs.keys.collect{|iface| iface.to_s}
19
+ end
20
+
21
+ def hw_address(iface)
22
+ socket = Socket.new(Socket::AF_INET, Socket::SOCK_DGRAM, 0)
23
+ buf = [iface, ""].pack('a16h16')
24
+ socket.ioctl(SIOCGIFHWADDR, buf)
25
+ socket.close
26
+ to_etheraddr(buf[18..23])
27
+ end
28
+
29
+ def ip_address(iface)
30
+ socket = UDPSocket.new
31
+ buf = [iface, ""].pack('a16h16')
32
+ socket.ioctl(SIOCGIFADDR, buf)
33
+ socket.close
34
+ to_ipaddr4(buf[20..23])
35
+ end
36
+
37
+ def broadcast_address(iface)
38
+ socket = UDPSocket.new
39
+ buf = [iface, ""].pack('a16h16')
40
+ socket.ioctl(SIOCGIFBRDADDR, buf)
41
+ socket.close
42
+ to_ipaddr4(buf[20..23])
43
+ end
44
+
45
+ private
46
+ def to_ipaddr4(string)
47
+ string.unpack("CCCC").join(".")
48
+ end
49
+
50
+ def to_etheraddr(string)
51
+ string.unpack("H2H2H2H2H2H2").join(":")
52
+ end
53
+ end
54
+ end
55
+ end