apiotics 0.1.141 → 0.2.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3234b0c682cfe652ef3e745c6b4b3f9e96fb869e
4
- data.tar.gz: b0c7352caa5bd5387c293bab331db8a589bd8953
3
+ metadata.gz: 185f239908233c662b8a5abccb2ae33dedc35ccb
4
+ data.tar.gz: '08ffbf5c91966a2923a9d03bebf966b3c4fadbb8'
5
5
  SHA512:
6
- metadata.gz: 0cc4bbc8b7c956c73a464d640e3a158db671a663a1c30c3dedc864d9b30b504239015de9771314685b94c5aaf99939ffded9145027ad762f2969974684f5d3e3
7
- data.tar.gz: 364f8457d2349f2bef39997f41cfa5c94c782aac336967a12a44d9b16e0d69210d59f38a274b59338ed5cd838203348c35c79faff0fb66c919db3efa5fad4424
6
+ metadata.gz: 656e760acebbc1ca43fd5c6b0e5f01c82815e4004a1dee246793a3ad0964fd4393a0465324075a573b489154350d8d50167a2beea7e816df9d140b7c3a9b04c2
7
+ data.tar.gz: cca8670e92c02c334c731b0a0babd0bc3037d494b6663777613b2c59ff8c231a24f1a5aa9a470eba36fd205385f978b399c339a76801dcaaa7f37cecbdf141ca
@@ -8,6 +8,7 @@ require 'apiotics/extract'
8
8
  require 'apiotics/portal'
9
9
  require 'apiotics/hardware'
10
10
  require 'apiotics/connection_error'
11
+ require 'apiotics/encrypt_decrypt'
11
12
  require 'daemons'
12
13
 
13
14
  module Apiotics
@@ -1,7 +1,7 @@
1
1
  module Apiotics
2
2
  class Configuration
3
3
 
4
- attr_accessor :public_key, :private_key, :local_logging, :targets, :local_port, :server, :server_port, :portal, :push, :tls, :verify_peer, :handshake, :parents, :reduced_metadata, :redis_comms_connection, :interface_kinds, :max_missed_heartbeats, :heartbeat_interval, :heroku, :create_heartbeat_error
4
+ attr_accessor :public_key, :private_key, :local_logging, :targets, :local_port, :server, :server_port, :portal, :push, :tls, :verify_peer, :handshake, :parents, :reduced_metadata, :redis_comms_connection, :interface_kinds, :max_missed_heartbeats, :heartbeat_interval, :heroku, :server_type, :mqtt_port, :aws_endpoint, :create_heartbeat_error
5
5
 
6
6
  def initialize
7
7
  @public_key = nil
@@ -23,6 +23,9 @@ module Apiotics
23
23
  @heartbeat_interval = 5
24
24
  @create_heartbeat_error = false
25
25
  @heroku = false
26
+ @server_type = nil
27
+ @mqtt_port = 8883
28
+ @aws_endpoint
26
29
  @interface_kinds = {
27
30
  "string" => "string",
28
31
  "text" => "string",
@@ -0,0 +1,19 @@
1
+ require 'openssl'
2
+
3
+ class String
4
+ def apiotics_encrypt(key)
5
+ cipher = OpenSSL::Cipher.new('DES-EDE3-CBC').encrypt
6
+ cipher.key = Digest::SHA1.hexdigest key
7
+ s = cipher.update(self) + cipher.final
8
+
9
+ s.unpack('H*')[0].upcase
10
+ end
11
+
12
+ def apiotics_decrypt(key)
13
+ cipher = OpenSSL::Cipher.new('DES-EDE3-CBC').decrypt
14
+ cipher.key = Digest::SHA1.hexdigest key
15
+ s = [self].pack("H*").unpack("C*").pack("c*")
16
+
17
+ cipher.update(s) + cipher.final
18
+ end
19
+ end
@@ -9,7 +9,7 @@ module Apiotics
9
9
  puts object.previous_changes
10
10
  object.previous_changes.each do |k,v|
11
11
  if Apiotics::Extract.is_target(object, k)
12
- interfaces[k] = v[1].to_s
12
+ interfaces[k] = v[1]
13
13
  end
14
14
  end
15
15
  if interfaces != {}
@@ -1,5 +1,6 @@
1
1
  require 'os'
2
2
  require 'etc'
3
+ require 'json'
3
4
 
4
5
  module Apiotics
5
6
  class Hardware
@@ -59,7 +60,7 @@ module Apiotics
59
60
  end
60
61
  end
61
62
 
62
- def self.install_firmware(config_script, firmware_path, starting_address)
63
+ def self.openocd_install_firmware(config_script, firmware_path, starting_address)
63
64
  directory = Rails.root.join('lib', 'openocd', 'gnuarmeclipse')
64
65
  unless Dir.exist?(directory)
65
66
  self.save_openocd
@@ -74,19 +75,19 @@ module Apiotics
74
75
  msg = system(string)
75
76
  end
76
77
 
77
- def self.openocd(worker_name, name)
78
+ def self.openocd(worker_name, name, config)
78
79
  msg = ""
79
80
  download_directory = Rails.root.join('lib', 'openocd')
80
81
  Dir.mkdir download_directory unless Dir.exist?(download_directory)
81
82
  download_directory = Rails.root.join('lib', 'openocd', 'downloads')
82
83
  Dir.mkdir download_directory unless Dir.exist?(download_directory)
83
84
  Dir.chdir download_directory
84
- config = Apiotics::Portal.openocd_worker_config(worker_name)
85
- config = JSON.parse(config)
86
85
  unless config["openocd_config_file_name"] == nil || config["openocd_config_file_name"] == ""
87
86
  path = Rails.root.join('lib', 'openocd', 'downloads', config["firmware_file_name"])
88
87
  if File.exist?(path)
88
+ puts "Device firmware already cached at #{path}. Using cached version. To download a new copy of the device firmware, delete the file at #{path}.\n"
89
89
  else
90
+ puts "Downloading device firmware...\n"
90
91
  firmware_data = Apiotics::Portal.download_firmware(worker_name)
91
92
  file = File.new(path, 'w')
92
93
  file.write firmware_data["file"].force_encoding(Encoding::UTF_8)
@@ -114,7 +115,7 @@ module Apiotics
114
115
  IO.write(data, clean_bits.force_encoding(Encoding::UTF_8), offset)
115
116
  data.close
116
117
  end
117
- msg = self.install_firmware(config["openocd_config_file_name"], path, config["openocd_start_address"])
118
+ msg = self.openocd_install_firmware(config["openocd_config_file_name"], path, config["openocd_start_address"])
118
119
  else
119
120
  k = Apiotics.configuration.targets.keys
120
121
  puts "Worker could not be found. The workers associated with your Hive are: #{k.join(',')}"
@@ -122,5 +123,222 @@ module Apiotics
122
123
  return msg
123
124
  end
124
125
 
126
+ def self.check_mac_uniflash_install
127
+ status = false
128
+ puts "Checking for Uniflash installation...\n"
129
+ path = "/Applications/ti/uniflash_4.3.0/dslite.sh"
130
+ if File.exist?(path)
131
+ puts "Uniflash installation found.\n"
132
+ status = true
133
+ else
134
+ puts "No Uniflash installation found.\n"
135
+ end
136
+ return status
137
+ end
138
+
139
+ def self.check_linux_uniflash_install #need a Linux installation to check where UniFlash installs itself
140
+ status = false
141
+ puts "Checking for Uniflash installation...\n"
142
+ path = "#{Dir.home}/ti/uniflash_4.3.0/dslite.sh"
143
+ if File.exist?(path)
144
+ puts "Uniflash installation found.\n"
145
+ status = true
146
+ else
147
+ puts "No Uniflash installation found.\n"
148
+ end
149
+ return status
150
+ end
151
+
152
+ def self.check_uniflash_install
153
+ status = false
154
+ if Hardware.mac == true
155
+ if Hardware.check_mac_uniflash_install == true
156
+ status = "/Applications/ti/uniflash_4.3.0/dslite.sh"
157
+ end
158
+ elsif Hardware.linux == true
159
+ if Hardware.check_linux_uniflash_install == true
160
+ status = "#{Dir.home}/ti/uniflash_4.3.0/dslite.sh"
161
+ end
162
+ else
163
+ puts "Your computer is not running a supported OS. Please use either Mac OS or Linux to install your firmware.\n"
164
+ end
165
+ return status
166
+ end
167
+
168
+ def self.import_uniflash_image(uniflash_path, path, config)
169
+ project_path = "#{Dir.home}/.SLImageCreator/projects/#{config['firmware_file_name'].split(".")[0]}"
170
+ if Dir.exist?(project_path)
171
+ FileUtils.remove_dir(project_path)
172
+ end
173
+ string = "#{uniflash_path} --mode #{config["openocd_config_file_name"]} project import --file #{path}"
174
+ puts "Creating uniflash project... \n"
175
+ msg = system(string)
176
+ end
177
+
178
+ def self.find_uniflash_mac_address(uniflash_path, config)
179
+ mac_addr = nil
180
+ string = "#{uniflash_path} --mode #{config["openocd_config_file_name"]} device info"
181
+ puts "Finding device MAC address... \n"
182
+ msg = `#{string}`
183
+ mac_addr_start = msg.rindex("MAC : ")
184
+ if mac_addr_start != nil
185
+ mac_addr_start = mac_addr_start + 15
186
+ mac_addr_end = msg.rindex("PROG MAC") - 1
187
+ mac_addr = msg[mac_addr_start..mac_addr_end].chomp
188
+ else
189
+ puts "Could not read MAC address. Please press the reset button on your board and try running rake firmware:install again.\n"
190
+ end
191
+ return mac_addr
192
+ end
193
+
194
+ def self.edit_json_config_mac_address(mac_address, config)
195
+ status = false
196
+ puts "Editing device configuration to assign device MAC address..."
197
+ path = "#{Dir.home}/.SLImageCreator/projects/#{config['firmware_file_name'].split(".")[0]}/#{config['firmware_file_name'].split(".")[0]}.json"
198
+ if File.exist?(path)
199
+ puts "json configuration file found...\n"
200
+ file = File.read(path)
201
+ puts "updating MAC address...\n"
202
+ json_config = JSON.parse(file)
203
+ json_config["header"]["DEV_MAC_ADDR"] = mac_address
204
+ json_config["systemFiles"]["CONFIG_TYPE_MAC"]["MAC_ADDR"] = mac_address
205
+ puts "writing updated json configuration file...\n"
206
+ File.write(path, json_config.to_json)
207
+ status = true
208
+ else
209
+ puts "Error: json configuration file could not be found at #{path}\n"
210
+ end
211
+ return status
212
+ end
213
+
214
+ def self.create_uniflash_image(uniflash_path, config)
215
+ puts "Creating uniflash firmware image...\n"
216
+ string = "#{uniflash_path} --mode #{config["openocd_config_file_name"]} project create_image --name #{config['firmware_file_name'].split(".")[0]} --sli_file #{config['firmware_file_name'].split(".")[0]}.sli"
217
+ msg = system(string)
218
+ end
219
+
220
+ def self.brand_uniflash_image(uniflash_path, config)
221
+ puts "Adding Hive and Worker Type details to the firmware image...\n"
222
+ details_hash = {
223
+ "hive_public_key" => config["hive_public_key"],
224
+ "hive_private_key" => config["hive_private_key"],
225
+ "worker_type" => config["worker_type"]
226
+ }
227
+ path = Rails.root.join('lib', 'uniflash', 'downloads', 'branding.json')
228
+ File.write(path, details_hash.to_json)
229
+ target_path = "branding.json"
230
+ string = "#{uniflash_path} --mode #{config["openocd_config_file_name"]} project add_file --name #{config["firmware_file_name"].split(".")[0]} --file #{path} --fs_path #{target_path} --overwrite --flags publicread"
231
+ msg = system(string)
232
+ File.delete(path)
233
+ wifi_path = Rails.root.join('lib', 'uniflash', 'downloads', 'wifi_settings')
234
+ if File.exist?(wifi_path)
235
+ Hardware.add_wifi_details(uniflash_path, config, wifi_path)
236
+ end
237
+ end
238
+
239
+ def self.add_wifi_details(uniflash_path, config, wifi_path)
240
+ pwd = ApioticsSetting.find_by(key: "wifi_key").value
241
+
242
+ encrypted = File.read(wifi_path)
243
+
244
+ decrypted = encrypted.apiotics_decrypt(pwd)
245
+
246
+ target_path = "wifi_settings.json"
247
+ path = Rails.root.join('lib', 'uniflash', 'downloads', 'wifi_settings.json')
248
+ File.write(path, decrypted)
249
+ string = "#{uniflash_path} --mode #{config["openocd_config_file_name"]} project add_file --name #{config["firmware_file_name"].split(".")[0]} --file #{path} --fs_path #{target_path} --overwrite --flags publicread"
250
+ msg = system(string)
251
+ File.delete(path)
252
+ end
253
+
254
+ def self.write_uniflash_image(uniflash_path, config)
255
+ puts "Writing uniflash firmware image...\n"
256
+ string = "#{uniflash_path} --mode #{config["openocd_config_file_name"]} image program --file #{config['firmware_file_name'].split(".")[0]}.sli"
257
+ msg = system(string)
258
+ end
259
+
260
+ def self.uniflash(worker_name, name, config)
261
+ uniflash_path = Hardware.check_uniflash_install
262
+ if uniflash_path != false
263
+ download_directory = Rails.root.join('lib', 'uniflash')
264
+ Dir.mkdir download_directory unless Dir.exist?(download_directory)
265
+ download_directory = Rails.root.join('lib', 'uniflash', 'downloads')
266
+ Dir.mkdir download_directory unless Dir.exist?(download_directory)
267
+ Dir.chdir download_directory
268
+ unless config["openocd_config_file_name"] == nil || config["openocd_config_file_name"] == ""
269
+ path = Rails.root.join('lib', 'uniflash', 'downloads', config["firmware_file_name"])
270
+ if File.exist?(path)
271
+ puts "Device firmware already cached at #{path}. Using cached version. To download a new copy of the device firmware, delete the file at #{path}.\n"
272
+ else
273
+ puts "Downloading device firmware...\n"
274
+ firmware_data = Apiotics::Portal.download_firmware(worker_name)
275
+ file = File.new(path, 'w')
276
+ file.write firmware_data["file"].force_encoding(Encoding::UTF_8)
277
+ file.close
278
+ end
279
+ Hardware.import_uniflash_image(uniflash_path, path, config)
280
+ mac_address = Hardware.find_uniflash_mac_address(uniflash_path, config)
281
+ unless mac_address == nil
282
+ if Hardware.edit_json_config_mac_address(mac_address, config)
283
+ Hardware.brand_uniflash_image(uniflash_path, config)
284
+ Hardware.create_uniflash_image(uniflash_path, config)
285
+ Hardware.write_uniflash_image(uniflash_path, config)
286
+ end
287
+ end
288
+ else
289
+ k = Apiotics.configuration.targets.keys
290
+ puts "Worker could not be found. The workers associated with your Hive are: #{k.join(',')}"
291
+ end
292
+ else
293
+ puts "Could not find Uniflash 4.3.0. If you need to install it, please visit http://processors.wiki.ti.com/index.php/Category:CCS_UniFlash and install version 4.3.0.\n"
294
+ end
295
+ end
296
+
297
+ def self.install(worker_name, name)
298
+ config = Apiotics::Portal.openocd_worker_config(worker_name)
299
+ config = JSON.parse(config)
300
+ if config["installer"] == "Open OCD 0.10"
301
+ Hardware.openocd(worker_name, name, config)
302
+ elsif config["installer"] == "Uniflash 4.3.0"
303
+ Hardware.uniflash(worker_name, name, config)
304
+ else
305
+ puts "Unknown installer for #{worker_name}. Please check the installer settings for the #{worker_name} device on the Apiotics portal.\n"
306
+ end
307
+ end
308
+
309
+ def self.wifi(ssid, password, security_mode)
310
+ args = {
311
+ "ssid" => ssid,
312
+ "password" => password,
313
+ "security_mode" => security_mode
314
+ }
315
+ args.keys.each do |key|
316
+ if args[key] == nil
317
+ args[key] = ""
318
+ end
319
+ end
320
+
321
+ pwd = ApioticsSetting.find_by(key: "wifi_key")
322
+ if pwd == nil
323
+ s = ApioticsSetting.new
324
+ s.key = "wifi_key"
325
+ s.value = SecureRandom.hex
326
+ s.save
327
+ pwd = s.value
328
+ else
329
+ pwd = pwd.value
330
+ end
331
+
332
+ encrypted_wifi_config = args.to_json.apiotics_encrypt(pwd)
333
+
334
+ download_directory = Rails.root.join('lib', 'uniflash')
335
+ Dir.mkdir download_directory unless Dir.exist?(download_directory)
336
+ download_directory = Rails.root.join('lib', 'uniflash', 'downloads')
337
+ Dir.mkdir download_directory unless Dir.exist?(download_directory)
338
+ Dir.chdir download_directory
339
+ path = Rails.root.join('lib', 'uniflash', 'downloads', 'wifi_settings')
340
+ File.write(path, encrypted_wifi_config)
341
+ end
342
+
125
343
  end
126
344
  end
@@ -25,7 +25,7 @@ module Apiotics
25
25
  find_record
26
26
  @methods.each do |k,v|
27
27
  @type = @record.class.columns_hash[k].type
28
- #change_value
28
+ change_value
29
29
  @record.send("#{k}=".to_sym, v)
30
30
  unless Apiotics.configuration.reduced_metadata == true
31
31
  @record.send(("#{k}_action=").to_sym, @action)
@@ -62,6 +62,11 @@ module Apiotics
62
62
  def self.retrieve_configuration
63
63
  json = HTTParty.post("#{Apiotics.configuration.portal}api/hive", :query => {:public_key => Apiotics.configuration.public_key, :private_key => Apiotics.configuration.private_key}).body
64
64
  hash = Apiotics::Parse.portal(json)
65
+ if Apiotics.configuration.server_type == nil
66
+ Apiotics.configuration.server_type = hash["server_version"]
67
+ Apiotics.configuration.aws_endpoint = hash["aws_endpoint"]
68
+ end
69
+ hash
65
70
  end
66
71
 
67
72
  def self.parse_all_interfaces
@@ -264,13 +269,41 @@ module Apiotics
264
269
  if gem_setting == nil
265
270
  gem_setting = ApioticsSetting.new
266
271
  gem_setting.key = "gem_id"
267
- gem_setting.value = hash["guid"]
272
+ gem_setting.value = hash["public_hash"]
268
273
  gem_setting.save
269
274
  else
270
- gem_setting.value = hash["guid"]
275
+ gem_setting.value = hash["public_hash"]
271
276
  gem_setting.save
272
277
  end
273
- hash["guid"]
278
+ s = ApioticsSetting.find_by(key: "private_gem_hash")
279
+ if s == nil
280
+ s = ApioticsSetting.new
281
+ s.key = "private_gem_hash"
282
+ s.value = hash["private_hash"]
283
+ s.save
284
+ end
285
+ s = ApioticsSetting.find_by(key: "public_key")
286
+ if s == nil
287
+ s = ApioticsSetting.new
288
+ s.key = "public_key"
289
+ s.value = hash["public"]
290
+ s.save
291
+ end
292
+ s = ApioticsSetting.find_by(key: "private_key")
293
+ if s == nil
294
+ s = ApioticsSetting.new
295
+ s.key = "private_key"
296
+ s.value = hash["private"]
297
+ s.save
298
+ end
299
+ s = ApioticsSetting.find_by(key: "cert")
300
+ if s == nil
301
+ s = ApioticsSetting.new
302
+ s.key = "cert"
303
+ s.value = hash["cert"]
304
+ s.save
305
+ end
306
+ hash["public_hash"]
274
307
  end
275
308
 
276
309
  end
@@ -6,6 +6,7 @@ require "socket"
6
6
  require 'openssl'
7
7
  require 'json'
8
8
  require "redis"
9
+ require 'aws_iot_device'
9
10
 
10
11
  module Apiotics
11
12
  class Server
@@ -16,93 +17,174 @@ module Apiotics
16
17
  $redis = ::Redis.new
17
18
  end
18
19
  end
20
+ @localport = Apiotics.configuration.local_port
21
+ @error_msg = nil
19
22
  Thread.abort_on_exception = true
20
23
  hive_public_key = ApioticsSetting.find_by(key: "hive_public_key")
21
24
  if hive_public_key == nil || hive_public_key.value != Apiotics.configuration.public_key
22
25
  Server.clear_db_settings
23
26
  end
24
- @error_msg = nil
25
- server_details = Server.lookup
26
- rgs = ApioticsSetting.find_by(key: "server")
27
- rgs_port = ApioticsSetting.find_by(key: "port")
28
- if rgs == nil
29
- if server_details["status"] == "ok"
30
- rgs = server_details["ip"]
31
- c = ApioticsSetting.new
32
- c.key = "server"
33
- c.value = rgs
34
- c.save
35
- rgs_port = server_details["port"]
36
- c = ApioticsSetting.new
37
- c.key = "port"
38
- c.value = rgs_port
39
- c.save
40
- else
41
- @error_msg = server_details["status_msg"]
27
+ if Apiotics::Server.server_type == "aws"
28
+ port = Apiotics.configuration.mqtt_port
29
+ key = Apiotics::Server.key
30
+ cert = Apiotics::Server.cert
31
+ ca_cert = Apiotics::Server.ca_cert
32
+ key_file = Tempfile.new
33
+ cert_file = Tempfile.new
34
+ ca_cert_file = Tempfile.new
35
+ key_file.write(key)
36
+ key_file.rewind
37
+ cert_file.write(cert)
38
+ cert_file.rewind
39
+ ca_cert_file.write(ca_cert)
40
+ ca_cert_file.rewind
41
+ aws_endpoint = Apiotics::Server.aws_endpoint
42
+ gem_id = Apiotics::Server.gem_id
43
+ Server.sync_devices(nil)
44
+
45
+ @server = AwsIotDevice::MqttShadowClient::MqttManager.new
46
+ @server.config_endpoint(aws_endpoint, port)
47
+ @server.config_ssl_context(ca_cert_file.path, key_file.path, cert_file.path)
48
+ #@server.persistent = true
49
+ @server.connect(aws_endpoint, port, true, true, false)
50
+
51
+ @server.on_message do |packet|
52
+ msg = packet.payload
53
+ puts "Message received: " + msg
54
+ Server.parse_message(msg)
42
55
  end
56
+
57
+ PahoMqtt.logger = "/Users/mackie/.apiotics/paho.log"
58
+
59
+ @server.subscribe("topic/#{Apiotics.configuration.public_key}/setcomplete", 1)
60
+ @server.subscribe("topic/#{Apiotics.configuration.public_key}/setrequestack", 1)
61
+ @server.subscribe("topic/#{Apiotics.configuration.public_key}/getack", 1)
62
+
63
+ Server.ping(@server)
64
+
43
65
  else
44
- if server_details["status"] == "ok"
45
- rgs.value = server_details["ip"]
46
- rgs.save
47
- rgs = rgs.value
48
- rgs_port.value = server_details["port"]
49
- rgs_port.save
50
- rgs_port = rgs_port.value
66
+ server_details = Server.lookup
67
+ rgs = ApioticsSetting.find_by(key: "server")
68
+ rgs_port = ApioticsSetting.find_by(key: "port")
69
+ if rgs == nil
70
+ if server_details["status"] == "ok"
71
+ rgs = server_details["ip"]
72
+ c = ApioticsSetting.new
73
+ c.key = "server"
74
+ c.value = rgs
75
+ c.save
76
+ rgs_port = server_details["port"]
77
+ c = ApioticsSetting.new
78
+ c.key = "port"
79
+ c.value = rgs_port
80
+ c.save
81
+ else
82
+ @error_msg = server_details["status_msg"]
83
+ end
51
84
  else
52
- @error_msg = server_details["status_msg"]
53
- end
54
- end
55
- if Apiotics.configuration.tls == true
56
- socket = TCPSocket.new(rgs, rgs_port)
57
- context = OpenSSL::SSL::SSLContext.new
58
- context.key = Server.key
59
- context.cert = Server.cert
60
- if Apiotics.configuration.verify_peer == true
61
- ca_tempfile = Tempfile.new
62
- ca_tempfile.write Server.ca_cert.to_pem
63
- ca_tempfile.rewind
64
- context.ca_file = ca_tempfile.path
65
- context.verify_mode = OpenSSL::SSL::VERIFY_PEER
85
+ if server_details["status"] == "ok"
86
+ rgs.value = server_details["ip"]
87
+ rgs.save
88
+ rgs = rgs.value
89
+ rgs_port.value = server_details["port"]
90
+ rgs_port.save
91
+ rgs_port = rgs_port.value
92
+ else
93
+ @error_msg = server_details["status_msg"]
94
+ end
66
95
  end
67
- @server = OpenSSL::SSL::SSLSocket.new socket, context
68
- @server.sync_close = true
69
- @server.connect
70
- if Apiotics.configuration.verify_peer == true
71
- ca_tempfile.close(true)
96
+ if Apiotics.configuration.tls == true
97
+ socket = TCPSocket.new(rgs, rgs_port)
98
+ context = OpenSSL::SSL::SSLContext.new
99
+ context.key = Server.key
100
+ context.cert = Server.cert
101
+ if Apiotics.configuration.verify_peer == true
102
+ ca_tempfile = Tempfile.new
103
+ ca_tempfile.write Server.ca_cert.to_pem
104
+ ca_tempfile.rewind
105
+ context.ca_file = ca_tempfile.path
106
+ context.verify_mode = OpenSSL::SSL::VERIFY_PEER
107
+ end
108
+ @server = OpenSSL::SSL::SSLSocket.new socket, context
109
+ @server.sync_close = true
110
+ @server.connect
111
+ if Apiotics.configuration.verify_peer == true
112
+ ca_tempfile.close(true)
113
+ end
114
+ else
115
+ @server = TCPSocket.open(rgs, rgs_port)
72
116
  end
73
- else
74
- @server = TCPSocket.open(rgs, rgs_port)
117
+ Server.sync_devices(nil)
118
+
119
+ listen_remote
120
+ @heartbeat_state = Hash.new
121
+ heartbeat = {
122
+ "action" => "heartbeat",
123
+ "hive_id" => Apiotics.configuration.public_key,
124
+ "instance_id" => "0000000000000000000000000000000000000000000000000000000000000000",
125
+ "driver" => "Core::Heartbeat",
126
+ "interface" => nil
127
+ }
128
+ send_heartbeat(heartbeat)
75
129
  end
76
- Server.sync_devices(nil)
77
- @localport = Apiotics.configuration.local_port
78
- listen_remote
79
- @heartbeat_state = Hash.new
80
- heartbeat = {
81
- "action" => "heartbeat",
82
- "hive_id" => Apiotics.configuration.public_key,
83
- "instance_id" => "0000000000000000000000000000000000000000000000000000000000000000",
84
- "driver" => "Core::Heartbeat",
85
- "interface" => nil
86
- }
87
- send_heartbeat(heartbeat)
130
+ puts "Starting local server..."
88
131
  listen_local
89
132
  rescue => e
90
- if @server != nil
91
- @server.close
92
- end
133
+ Server.close
93
134
  puts e.message
94
135
  puts e.backtrace.inspect
95
136
  raise e
96
137
  end
97
138
  end
139
+
140
+ def self.ping(server)
141
+ Thread.abort_on_exception = true
142
+ Thread.new do
143
+ msg = {"p" => "p"}
144
+ loop do
145
+ server.publish("topic/ping", msg.to_json, false, 1)
146
+ sleep 30
147
+ end
148
+ end
149
+ end
98
150
 
99
151
  def send(msg)
100
- puts "Message sent: #{msg}"
101
- @server.puts( msg )
152
+ # need to check for which server.
153
+ if Apiotics.configuration.server_type == "aws"
154
+ msg = JSON.parse(msg)
155
+ if msg["action"] == "get"
156
+ msg["driver"] = msg["driver"].split("::")[1]
157
+ @server.publish("topic/#{Apiotics.configuration.public_key}/get", msg.to_json, false, 1)
158
+ else
159
+ #send_msg = {
160
+ # "state" => {
161
+ # "desired" => {
162
+ # msg["driver"].split("::")[1] => msg["interface"]
163
+ # }
164
+ # }
165
+ #}
166
+ #puts "Message sent: #{send_msg.to_json} to #{"$aws/things/#{msg["instance_id"]}/shadow/update"}"
167
+ #@server.publish("$aws/things/#{msg["instance_id"]}/shadow/update", send_msg.to_json, false, 1)
168
+ puts "Message sent: #{msg.to_json} to #{"topic/#{Apiotics.configuration.public_key}/setrequest"}"
169
+ @server.publish("topic/#{Apiotics.configuration.public_key}/setrequest", msg.to_json, false, 1)
170
+ end
171
+ else
172
+ puts "Message sent: #{msg}"
173
+ @server.puts( msg )
174
+ end
102
175
  end
103
176
 
104
- def close
105
- @server.close
177
+ def self.close
178
+ #need to check for which server.
179
+ if Apiotics.configuration.server_type == "aws"
180
+ if @server != nil
181
+ @server.disconnect
182
+ end
183
+ else
184
+ if @server != nil
185
+ @server.close
186
+ end
187
+ end
106
188
  end
107
189
 
108
190
  def listen_remote
@@ -112,19 +194,7 @@ module Apiotics
112
194
  loop do
113
195
  msg = @server.gets
114
196
  puts "Message received: " + msg
115
- msg_hash = Apiotics::Parse.message(msg)
116
- #puts "Driver: " + msg_hash["driver"]
117
- unless msg_hash["driver"] == "Core::Heartbeat" || msg_hash["action"] == "sync" || msg_hash["error"] != nil
118
- r = Apiotics::Insert.new(msg_hash)
119
- if r.valid == true
120
- if r.action == "set-request-ack" || r.action == "set-complete" || r.action == "get-ack"
121
- r.save
122
- unless Apiotics.configuration.local_logging == false
123
- r.save_log
124
- end
125
- end
126
- end
127
- end
197
+ msg_hash = Server.parse_message(msg)
128
198
  if msg_hash["driver"] == "Core::Heartbeat"
129
199
  monitor_heartbeat(msg_hash)
130
200
  elsif msg_hash["action"] == "sync"
@@ -151,10 +221,28 @@ module Apiotics
151
221
  end
152
222
  end
153
223
 
224
+ def self.parse_message(msg)
225
+ msg_hash = Apiotics::Parse.message(msg)
226
+ #puts "Driver: " + msg_hash["driver"]
227
+ unless msg_hash["driver"] == "Core::Heartbeat" || msg_hash["action"] == "sync" || msg_hash["error"] != nil
228
+ r = Apiotics::Insert.new(msg_hash)
229
+ if r.valid == true
230
+ if r.action == "set-request-ack" || r.action == "set-complete" || r.action == "get-ack"
231
+ r.save
232
+ unless Apiotics.configuration.local_logging == false
233
+ r.save_log
234
+ end
235
+ end
236
+ end
237
+ end
238
+ msg_hash
239
+ end
240
+
154
241
  def listen_local
155
242
  if Apiotics.configuration.redis_comms_connection == false
156
243
  begin
157
244
  @local_server = TCPServer.open(@localport)
245
+ puts "Local server started..."
158
246
  loop do
159
247
  Thread.abort_on_exception = true
160
248
  Thread.fork(@local_server.accept) do |client|
@@ -163,7 +251,7 @@ module Apiotics
163
251
  string = '{"error":"' + error_msg + '"}'
164
252
  client.puts(string)
165
253
  end
166
- #puts s
254
+ #puts "Sending message to Server.send #{s}"
167
255
  self.send(s)
168
256
  end
169
257
  end
@@ -188,12 +276,7 @@ module Apiotics
188
276
 
189
277
  def send_heartbeat(heartbeat)
190
278
  if Apiotics.configuration.handshake == true
191
- gem_id = ApioticsSetting.find_by(key: "gem_id")
192
- if gem_id == nil
193
- gem_id = Apiotics::Portal.register_client
194
- else
195
- gem_id = gem_id.value
196
- end
279
+ gem_id = Server.gem_id
197
280
  connect_msg = {
198
281
  "action" => "connect",
199
282
  "hive_id" => Apiotics.configuration.public_key,
@@ -284,28 +367,34 @@ module Apiotics
284
367
  return hash
285
368
  end
286
369
 
370
+ def self.gem_id
371
+ gem_id = ApioticsSetting.find_by(key: "gem_id")
372
+ if gem_id == nil
373
+ gem_id = Apiotics::Portal.register_client
374
+ else
375
+ gem_id = gem_id.value
376
+ end
377
+ gem_id
378
+ end
379
+
287
380
  def self.key
288
- key = ApioticsSetting.find_by(key: "key")
381
+ key = ApioticsSetting.find_by(key: "private_key")
289
382
  if key == nil
290
- key = Server.generate_key
383
+ Apiotics::Portal.register_client
384
+ key = ApioticsSetting.find_by(key: "private_key")
385
+ key = key.value
291
386
  else
292
387
  key = key.value
293
388
  end
294
- pass_phrase = ApioticsSetting.find_by(key: "key_pass_phrase").value
295
- key = OpenSSL::PKey::RSA.new key, pass_phrase
296
389
  return key
297
390
  end
298
391
 
299
392
  def self.cert
300
393
  cert = ApioticsSetting.find_by(key: "cert")
301
394
  if cert == nil
302
- key = Server.key
303
- public_key = key.public_key
304
- cert = Server.generate_cert(key, public_key)
305
- c = ApioticsSetting.new
306
- c.key = "cert"
307
- c.value = cert
308
- c.save
395
+ Apiotics::Portal.register_client
396
+ cert = ApioticsSetting.find_by(key: "cert")
397
+ cert = cert.value
309
398
  else
310
399
  cert = cert.value
311
400
  end
@@ -313,29 +402,6 @@ module Apiotics
313
402
  return cert
314
403
  end
315
404
 
316
- def self.generate_key
317
- key = OpenSSL::PKey::RSA.new 2048
318
- pass_phrase = 'simbiotes'
319
- cipher = OpenSSL::Cipher.new 'AES-128-CBC'
320
- s = ApioticsSetting.new
321
- s.key = "key_cipher"
322
- s.value = "OpenSSL::Cipher.new 'AES-128-CBC'"
323
- s.save
324
- s = ApioticsSetting.new
325
- s.key = "key_pass_phrase"
326
- s.value = 'simbiotes'
327
- s.save
328
- s = ApioticsSetting.new
329
- s.key = "public_key"
330
- s.value = key.public_key.to_pem
331
- s.save
332
- s = ApioticsSetting.new
333
- s.key = "key"
334
- s.value = key.export(cipher, pass_phrase)
335
- s.save
336
- return s.value
337
- end
338
-
339
405
  def self.generate_cert(key, public_key)
340
406
  csr = OpenSSL::X509::Request.new
341
407
  csr.version = 0
@@ -369,6 +435,42 @@ module Apiotics
369
435
  hive_public_key.save
370
436
  end
371
437
 
438
+ def self.server_type
439
+ s = ApioticsSetting.find_by(key: "server_type")
440
+ if s == nil
441
+ if Apiotics.configuration.server_type == nil
442
+ hash = Apiotics::Portal.retrieve_configuration
443
+ Apiotics.configuration.server_type == hash["server_version"]
444
+ server_type = hash["server_version"]
445
+ else
446
+ server_type = Apiotics.configuration.server_type
447
+ end
448
+ s = ApioticsSetting.new
449
+ s.key = "server_type"
450
+ s.value = server_type
451
+ s.save
452
+ end
453
+ s.value
454
+ end
455
+
456
+ def self.aws_endpoint
457
+ s = ApioticsSetting.find_by(key: "aws_endpoint")
458
+ if s == nil
459
+ if Apiotics.configuration.aws_endpoint == nil
460
+ hash = Apiotics::Portal.retrieve_configuration
461
+ Apiotics.configuration.server_type == hash["aws_endpoint"]
462
+ aws_endpoint = hash["aws_endpoint"]
463
+ else
464
+ aws_endpoint = Apiotics.configuration.aws_endpoint
465
+ end
466
+ s = ApioticsSetting.new
467
+ s.key = "aws_endpoint"
468
+ s.value = aws_endpoint
469
+ s.save
470
+ end
471
+ s.value
472
+ end
473
+
372
474
  def do_at_exit
373
475
  end
374
476
 
@@ -1,3 +1,3 @@
1
1
  module Apiotics
2
- VERSION = '0.1.141'
2
+ VERSION = '0.2.0'
3
3
  end
@@ -7,7 +7,7 @@ module Apiotics
7
7
  @models = Apiotics.configuration.targets[module_name.to_s]
8
8
  template "apiotics_scaffold.rb.erb", "app/controllers/#{module_file_name}/#{module_file_name.pluralize}_controller.rb"
9
9
  generate "apiotics:view", "#{parent}"
10
- route "scope module: :#{module_file_name} do \n\t\tresources :#{module_file_name}s\n\tend\n"
10
+ route "scope module: :#{module_file_name} do \n\t\tresources :#{module_file_name}s\n\tend"
11
11
  generate "simple_form:install"
12
12
  end
13
13
 
@@ -21,6 +21,7 @@ module Apiotics
21
21
  copy_file "dev_comm_server.rake", "lib/tasks/dev_comm_server.rake"
22
22
  copy_file "publish_script.rake", "lib/tasks/publish_script.rake"
23
23
  copy_file "install_firmware.rake", "lib/tasks/install_firmware.rake"
24
+ copy_file "set_wifi.rake", "lib/tasks/set_wifi.rake"
24
25
  FileUtils.chmod 0775, "lib/scripts/server_control.rb"
25
26
  FileUtils.chmod 0775, "lib/scripts/heroku_server_control.rb"
26
27
  end
@@ -2,9 +2,9 @@ namespace :firmware do
2
2
  desc "Install firmware on devices. Use rake firmware:install {worker_name} to install firmware on a device. Use rake firmware:install {worker_name} {instance_name} to install firmware and set a name for the device."
3
3
  task :install, [:worker, :name] => [:environment] do |task, args|
4
4
  if args[:name] == nil
5
- Apiotics::Hardware.openocd(args[:worker], nil)
5
+ Apiotics::Hardware.install(args[:worker], nil)
6
6
  else
7
- Apiotics::Hardware.openocd(args[:worker], args[:name])
7
+ Apiotics::Hardware.install(args[:worker], args[:name])
8
8
  end
9
9
  end
10
10
  end
@@ -0,0 +1,13 @@
1
+ namespace :firmware do
2
+ desc "Set Wifi details for a device (if applicable). Use rake firmware:wifi[ssid, password, security_mode] to set the wifi details for a device."
3
+ task :wifi, [:ssid, :password, :security_mode] => [:environment] do |task, args|
4
+ security_modes = ["WEP", "WPA", "WPA2"]
5
+ if args[:security_mode] != nil
6
+ unless security_modes.include?(args[:security_mode])
7
+ puts "#{args[:security_mode]} is not a supported WiFi security mode. The supported security modes are: #{security_modes.to_s}"
8
+ else
9
+ Apiotics::Hardware.wifi(args[:ssid], args[:password], args[:security_mode])
10
+ end
11
+ end
12
+ end
13
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: apiotics
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.141
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - MicroArx Corporation
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-04-18 00:00:00.000000000 Z
11
+ date: 2018-05-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -108,6 +108,20 @@ dependencies:
108
108
  - - "~>"
109
109
  - !ruby/object:Gem::Version
110
110
  version: '1.0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: apiotics-aws-iot-client
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: '1.0'
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: '1.0'
111
125
  - !ruby/object:Gem::Dependency
112
126
  name: pg
113
127
  requirement: !ruby/object:Gem::Requirement
@@ -163,6 +177,7 @@ files:
163
177
  - lib/apiotics/client.rb
164
178
  - lib/apiotics/configuration.rb
165
179
  - lib/apiotics/connection_error.rb
180
+ - lib/apiotics/encrypt_decrypt.rb
166
181
  - lib/apiotics/extract.rb
167
182
  - lib/apiotics/hardware.rb
168
183
  - lib/apiotics/insert.rb
@@ -220,6 +235,7 @@ files:
220
235
  - lib/generators/apiotics/script/templates/script.rb.erb
221
236
  - lib/generators/apiotics/script/templates/server.rb
222
237
  - lib/generators/apiotics/script/templates/server_control.rb
238
+ - lib/generators/apiotics/script/templates/set_wifi.rake
223
239
  - lib/generators/apiotics/script/templates/test_comm_server.rake
224
240
  - lib/generators/apiotics/script/templates/test_server.rb
225
241
  - lib/generators/apiotics/script/templates/test_server_control.rb
@@ -251,7 +267,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
251
267
  version: '0'
252
268
  requirements: []
253
269
  rubyforge_project:
254
- rubygems_version: 2.5.2
270
+ rubygems_version: 2.6.10
255
271
  signing_key:
256
272
  specification_version: 4
257
273
  summary: IoT For Everybody.