microgear 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. checksums.yaml +7 -0
  2. data/lib/microgear.rb +238 -0
  3. metadata +72 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 27c051ae1ca0e033e71a235d0d5ea688a2b168f0
4
+ data.tar.gz: e4f2bb3fd3791bbb30eeb41a51c72d51d89405d2
5
+ SHA512:
6
+ metadata.gz: 6a9d4f99491981de62ed636976c730236a0e73deea8d31c681b3282674e4f9c4268cf7d40672bac20ad411ae006e88ec273b1d4c13e146b3858c49a5cd4d61de
7
+ data.tar.gz: 283449bdf84b0fba083757dbae9516fb3ed6cc9b123d0ec32857ce51a2f3e8b153f017ba9ad68555ba6b76dc076bad3b657871e8d3e661b73d854e56580763c9
@@ -0,0 +1,238 @@
1
+ require "logger"
2
+ require "uri"
3
+ require "oauth"
4
+ require "securerandom"
5
+ require "openssl"
6
+ require "base64"
7
+ require "fiber"
8
+ require "mqtt"
9
+
10
+ require_relative "microgear/cache"
11
+
12
+ class Microgear
13
+
14
+ MINTOKDELAYTIME = 100;
15
+ MAXTOKDELAYTIME = 15000;
16
+ MGREV = 'NJ1';
17
+
18
+ GEARAUTHSITE = "http://61.91.14.29:8080/"
19
+ GEARAUTHREQUESTTOKENENDPOINT = "/oauth/request_token"
20
+ GEARAUTHACCESSTOKENENDPOINT = "/oauth/access_token"
21
+
22
+ def initialize(gearkey,gearsecret, appid, args = {})
23
+ @logger = Logger.new(STDERR)
24
+ @logger = Logger.new(STDOUT)
25
+ if args[:debugmode]
26
+ @logger.level = Logger::DEBUG
27
+ else
28
+ @logger.level = Logger::INFO
29
+ end
30
+
31
+ @gearkey = gearkey
32
+ @gearsecret = gearsecret
33
+
34
+ @appid = appid
35
+ @gearname = nil
36
+
37
+ @accesstoken = nil
38
+ @requesttoken = nil
39
+ @client = nil
40
+ @scope = args[:scope] || ""
41
+
42
+ @gearexaddress = nil
43
+ @gearexport = nil
44
+
45
+ @subscriptions = []
46
+ @callbacks = {}
47
+ end
48
+
49
+ def connect
50
+ get_token
51
+ @logger.info @accesstoken
52
+ @logger.debug "gearID : "+@appid
53
+ nonce = SecureRandom.hex(8)
54
+ hkey = @accesstoken["secret"]+"&"+@gearsecret
55
+ conn_opts = {
56
+ host: @gearexaddress,
57
+ username: @gearkey+'%'+Time.now.to_i.to_s,
58
+ client_id: @accesstoken["token"],
59
+ keep_alive: 10
60
+ }
61
+ digest = OpenSSL::Digest.new('sha1')
62
+ conn_opts[:password] = Base64.encode64(OpenSSL::HMAC.digest(digest, hkey, @accesstoken["token"]+"%"+conn_opts[:username])).strip
63
+ @logger.debug "mqttuser : "+conn_opts[:username]
64
+ @logger.debug "mqttpassword : "+conn_opts[:password]
65
+ @subscriptions.push('/piegear/'+conn_opts[:client_id]+'/#')
66
+ @mqtt_loop = Fiber.new do
67
+ MQTT::Client.connect(conn_opts) do |client|
68
+ @logger.info "Connected"
69
+ gear_state = Fiber.yield [:started,nil]
70
+ @logger.debug "auto subscribe "+@subscriptions.join(",")
71
+ client.subscribe(*@subscriptions)
72
+ loop do
73
+ case gear_state[0]
74
+ when :idle
75
+ unless client.queue_empty?
76
+ topic,message = client.get
77
+ if topic
78
+ Fiber.yield [:message, [topic,message]]
79
+ end
80
+ end
81
+ when :subscribe
82
+ client.subscribe(*gear_state[1])
83
+ when :unsubscribe
84
+ client.unsubscribe(*gear_state[1])
85
+ when :publish
86
+ client.publish(*gear_state[1])
87
+ if @subscriptions.include? gear_state[1][0]
88
+ topic,message = client.get
89
+ if topic and @callbacks[topic]
90
+ @callbacks[topic].call(topic,message)
91
+ end
92
+ end
93
+ when :close
94
+ client.close
95
+ Fiber.yield [:exit, nil]
96
+ end
97
+ gear_state = Fiber.yield [:ready, nil]
98
+ end
99
+ end
100
+ end
101
+ loop do
102
+ if @mqtt_loop.alive?
103
+ mqtt_state = @mqtt_loop.resume [:idle, nil]
104
+ case mqtt_state[0]
105
+ when :started
106
+ gear_state = [:started, nil]
107
+ when :message
108
+ if mqtt_state[1][1].index("/piegear/") == 0
109
+ @logger.debug '* control message > '+mqtt_state[1][1]+' : '+mqtt_state[1][2]
110
+ else
111
+ if @callbacks[mqtt_state[1][0]]
112
+ @callbacks[mqtt_state[1][0]].call(*mqtt_state[1])
113
+ end
114
+ end
115
+ when :ready
116
+ if block_given?
117
+ yield
118
+ end
119
+ when :exit
120
+ break
121
+ end
122
+ else
123
+ break
124
+ end
125
+ end
126
+ end
127
+
128
+ def subscribe(topic, &callback)
129
+ topic = "/"+@appid+topic
130
+ unless @subscriptions.include? topic
131
+ @subscriptions.push(topic)
132
+ end
133
+ if callback.class == Proc
134
+ @callbacks[topic] = callback
135
+ end
136
+ if @mqtt_loop
137
+ @mqtt_loop.resume [:subscribe, [topic]]
138
+ end
139
+ end
140
+
141
+ def unsubscribe(topic)
142
+ @logger.debug @subscriptions.index('/'+@appid+topic)
143
+ @logger.debug @subscriptions.join ","
144
+ if @subscriptions.index('/'+@appid+topic)
145
+ @subscriptions.delete('/'+@appid+topic)
146
+ if @mqtt_loop
147
+ @mqtt_loop.resume [:unsubscribe, ["/"+@appid+topic]]
148
+ end
149
+ end
150
+ end
151
+
152
+ def setname(name, &callback)
153
+ if @gearname
154
+ unsubscribe('/gearname/'+@gearname)
155
+ end
156
+ @gearname = name
157
+ subscribe('/gearname/'+name, &callback)
158
+ end
159
+
160
+ def publish(topic,message)
161
+ if @mqtt_loop and @mqtt_loop.alive?
162
+ @mqtt_loop.resume [:publish, ['/'+@appid+topic, message]]
163
+ else
164
+ raise IOError, "You must connect before publish!"
165
+ end
166
+
167
+ end
168
+
169
+ def chat(who, message)
170
+ publish('/gearname/'+who, message)
171
+ end
172
+
173
+ private
174
+ def get_token
175
+ @logger.debug "Check stored token"
176
+ cache = Cache.get_item("microgear.cache")
177
+ unless cache
178
+ cache = Cache.set_item("microgear.cache", {"_" => {}})
179
+ end
180
+ @logger.debug cache.to_json
181
+ @accesstoken = cache["_"]["accesstoken"]
182
+ if @accesstoken
183
+ endpoint = URI(@accesstoken["endpoint"])
184
+ @gearexaddress = endpoint.host
185
+ @gearexport = endpoint.port
186
+ else
187
+ @requesttoken = cache["_"]["requesttoken"];
188
+ if @requesttoken
189
+ #send requesttoken to obtain accesstoken
190
+ @logger.debug "already has request token"
191
+ @logger.debug "Requesting an access token."
192
+ consumer = OAuth::Consumer.new(@gearkey,@gearsecret,
193
+ :site => GEARAUTHSITE,
194
+ :request_token_path => GEARAUTHREQUESTTOKENENDPOINT,
195
+ :access_token_path => GEARAUTHACCESSTOKENENDPOINT)
196
+ token = OAuth::RequestToken.new consumer, @requesttoken["token"], @requesttoken["secret"]
197
+ access_token = token.get_access_token({oauth_verifier: @requesttoken["verifier"]}) do |args|
198
+ @logger.info args
199
+ end
200
+ cache["_"]["accesstoken"] = {
201
+ token: access_token.token,
202
+ secret: access_token.secret,
203
+ appkey: results.appkey,
204
+ endpoint: results.endpoint
205
+ }
206
+ @accesstoken = cache["_"]["accesstoken"]
207
+ @logger.debug cache
208
+ Cache.set_item("microgear.cache", cache)
209
+ else
210
+ @logger.debug "Requesting a request token."
211
+ consumer = OAuth::Consumer.new(@gearkey,@gearsecret,
212
+ :site => GEARAUTHSITE,
213
+ :request_token_path => GEARAUTHREQUESTTOKENENDPOINT,
214
+ :access_token_path => GEARAUTHACCESSTOKENENDPOINT,
215
+ )
216
+ verifier = SecureRandom.hex(4)
217
+ token = consumer.get_request_token({oauth_callback: "scope=#{@scope}&appid=#{@appid}&verifier=#{verifier}"})
218
+ cache["_"]["requesttoken"] = {
219
+ token: token.token,
220
+ secret: token.secret,
221
+ verifier: verifier
222
+ }
223
+ @requesttoken = cache["_"]["requesttoken"]
224
+ @logger.debug @requesttoken
225
+ access_token = token.get_access_token({oauth_verifier:verifier})
226
+ cache["_"]["accesstoken"] = {
227
+ token: access_token.token,
228
+ secret: access_token.secret,
229
+ appkey: access_token.params[:appkey],
230
+ endpoint: access_token.params[:endpoint]
231
+ }
232
+ @accesstoken = cache["_"]["accesstoken"]
233
+ @logger.debug cache
234
+ Cache.set_item("microgear.cache", cache)
235
+ end
236
+ end
237
+ end
238
+ end
metadata ADDED
@@ -0,0 +1,72 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: microgear
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Ridnarong Promya
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-07-06 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: oauth
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 0.4.7
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: 0.4.7
27
+ - !ruby/object:Gem::Dependency
28
+ name: mqtt
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description: Microgear library for NetPIE platform
42
+ email: ridnarong.promya@nectec.or.th
43
+ executables: []
44
+ extensions: []
45
+ extra_rdoc_files: []
46
+ files:
47
+ - lib/microgear.rb
48
+ homepage: http://rubygems.org/gems/microgear
49
+ licenses:
50
+ - MIT
51
+ metadata: {}
52
+ post_install_message:
53
+ rdoc_options: []
54
+ require_paths:
55
+ - lib
56
+ required_ruby_version: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ required_rubygems_version: !ruby/object:Gem::Requirement
62
+ requirements:
63
+ - - ">="
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ requirements: []
67
+ rubyforge_project:
68
+ rubygems_version: 2.4.7
69
+ signing_key:
70
+ specification_version: 4
71
+ summary: Microgear library
72
+ test_files: []