coap 0.0.16 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/.travis.yml +13 -2
- data/Gemfile +0 -1
- data/LICENSE +2 -2
- data/README.md +37 -33
- data/Rakefile +12 -3
- data/bin/coap +111 -0
- data/coap.gemspec +34 -29
- data/lib/coap.rb +3 -34
- data/lib/core.rb +11 -0
- data/lib/core/coap.rb +42 -0
- data/lib/core/coap/block.rb +98 -0
- data/lib/core/coap/client.rb +314 -0
- data/lib/core/coap/coap.rb +26 -0
- data/lib/core/coap/coding.rb +146 -0
- data/lib/core/coap/fsm.rb +82 -0
- data/lib/core/coap/message.rb +203 -0
- data/lib/core/coap/observer.rb +40 -0
- data/lib/core/coap/options.rb +44 -0
- data/lib/core/coap/registry.rb +32 -0
- data/lib/core/coap/registry/content_formats.yml +7 -0
- data/lib/core/coap/resolver.rb +17 -0
- data/lib/core/coap/transmission.rb +165 -0
- data/lib/core/coap/types.rb +69 -0
- data/lib/core/coap/utility.rb +34 -0
- data/lib/core/coap/version.rb +5 -0
- data/lib/core/core_ext/socket.rb +19 -0
- data/lib/core/hexdump.rb +18 -0
- data/lib/core/link.rb +97 -0
- data/lib/core/os.rb +15 -0
- data/spec/block_spec.rb +160 -0
- data/spec/client_spec.rb +86 -0
- data/spec/fixtures/coap.me.link +1 -0
- data/spec/link_spec.rb +98 -0
- data/spec/registry_spec.rb +39 -0
- data/spec/resolver_spec.rb +19 -0
- data/spec/spec_helper.rb +17 -0
- data/spec/transmission_spec.rb +70 -0
- data/test/helper.rb +15 -0
- data/test/test_client.rb +99 -228
- data/test/test_message.rb +99 -71
- metadata +140 -37
- data/bin/client +0 -42
- data/lib/coap/block.rb +0 -45
- data/lib/coap/client.rb +0 -364
- data/lib/coap/coap.rb +0 -273
- data/lib/coap/message.rb +0 -187
- data/lib/coap/mysocket.rb +0 -81
- data/lib/coap/observer.rb +0 -41
- data/lib/coap/version.rb +0 -3
- data/lib/misc/hexdump.rb +0 -17
- data/test/coap_test_helper.rb +0 -2
- data/test/disabled_econotag_blck.rb +0 -33
data/bin/client
DELETED
@@ -1,42 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
# Usage: client get coap://coap.me:5683/.well-known/core
|
3
|
-
# Usage: client observe coap://vs0.inf.ethz.ch:5683/obs
|
4
|
-
|
5
|
-
$LOAD_PATH.unshift(File.dirname(__FILE__) + '/../lib')
|
6
|
-
|
7
|
-
require 'coap'
|
8
|
-
|
9
|
-
def observe_callback(data, socket)
|
10
|
-
pp socket.inspect if $DEBUG
|
11
|
-
pp data.inspect if $DEBUG
|
12
|
-
end
|
13
|
-
|
14
|
-
PAYLOAD = 'CLILorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra quis, feugiat a, tellus. Phasellus viverra nulla ut metus varius laoreet. Quisque rutrum. Aenean imperdiet. Etiam ultricies nisi vel augue. Curabitur ullamcorper ultricies nisi. Nam eget dui. Etiam rhoncus. Maecenas tempus, tellus eget condimentum rhoncus, sem quam semper libero, sit amet adipiscing sem neque sed ipsum. Nam quam nunc, blandit vel, luctus pulvinar, hendrerit id, lorem. Maecenas nec odio et ante tincidunt tempus. Donec vitae sapien ut libero venenatis faucibus. Nullam quis ante. Etiam sit amet orci eget eros faucibus tincidunt. Duis leo. Sed fringilla mauris sit amet nibh. Donec sodales sagittis magna. Sed consequat, leo eget bibendum sodales, augue velit cursus nunc,Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra quis, feugiat a, tellus. Phasellus viverra nulla ut metus varius laoreet. Quisque rutrum. Aenean imperdiet. Etiam ultricies nisi vel augue. Curabitur ullamcorper ultricies nisi. Nam eget dui. Etiam rhoncus. Maecenas tempus, tellus eget condimentum rhoncus, sem quam semper libero, sit amet adipiscing sem neque sed ipsum. Nam quam nunc, blandit vel, luctus pulvinar, hendrerit id, lorem. Maecenas nec odio et ante tincidunt tempus. Donec vitae sapien ut libero venenatis faucibus. Nullam quis ante. Etiam sit amet orci eget eros faucibus tincidunt. Duis leo. Sed fringilla mauris sit amet nibh. Donec sodales sagittis magna. Sed consequat, leo eget bibendum sodales, augue velit cursus nuncLorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra quis, feugiat a, tellus. Phasellus viverra nulla ut metus varius laoreet. Quisque rutrum. Aenean imperdiet. Etiam ultricies nisi vel augue. Curabitur ullamcorper ultricies nisi. Nam eget dui. Etiam rhoncus. Maecenas tempus, tellus eget condimentum rhoncus, sem quam semper libero, sit amet adipiscing sem neque sed ipsum. Nam quam nunc, blandit vel, luctus pulvinar, hendrerit id, lorem. Maecenas nec odio et ante tincidunt tempus. Donec vitae sapien ut libero venenatis faucibus. Nullam quis ante. Etiam sit amet orci eget eros faucibus tincidunt. Duis leo. Sed fringilla mauris sit amet nibh. Donec sodales sagittis magna. Sed consequat, leo eget bibendum sodales, augue velit cursus nunc,Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra quis, feugiat a, tellus. Phasellus viverra nulla ut metus varius laoreet. Quisque rutrum. Aenean imperdiet. Etiam ultricies nisi vel augue. Curabitur ullamcorper ultricies nisi. Nam eget dui. Etiam rhoncus. Maecenas tempus, tellus eget condimentum rhoncus, sem quam semper libero, sit amet adipiscing sem neque sed ipsum. Nam quam nunc, blandit vel, luctus pulvinar, hendrerit id, lorem. Maecenas nec odio et ante tincidunt tempus. Donec vitae sapien ut libero venenatis faucibus. Nullam quis ante. Etiam sit amet orci eget eros faucibus tincidunt. Duis leo. Sed fringilla mauris sit amet nibh. Donec sodales sagittis magna. Sed consequat, leo eget bibendum sodales, augue velit cursus nunc,Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra quis, feugiat a, tellus. Phasellus viverra nulla ut metus varius laoreet. Quisque rutrum. Aenean imperdiet. Etiam ultricies nisi vel augue. Curabitur ullamcorper ultricies nisi. Nam eget dui. Etiam rhoncus. Maecenas tempus, tellus eget condimentum rhoncus, sem quam semper libero, sit amet adipiscing sem neque sed ipsum. Nam quam nunc, blandit vel, luctus pulvinar, hendrerit id, lorem. Maecenas nec odio et ante tincidunt tempus. Donec vitae sapien ut libero venenatis faucibus. Nullam quis ante. Etiam sit amet orci eget eros faucibus tincidunt. Duis leo. Sed fringilla mauris sit amet nibh. Donec sodales sagittis magna. Sed consequat, leo eget bibendum sodales, augue velit cursus nunc,Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra quis, feugiat a, tellus. Phasellus viverra nulla ut metus varius laoreet. Quisque rutrum. Aenean imperdiet. Etiam ultricies nisi vel augue. Curabitur ullamcorper ultricies nisi. Nam eget dui. Etiam rhoncus. Maecenas tempus, tellus eget condimentum rhoncus, sem quam semper libero, sit amet adipiscing sem neque sed ipsum. Nam quam nunc, blandit vel, luctus pulvinar, hendrerit id, lorem. Maecenas nec odio et ante tincidunt tempus. Donec vitae sapien ut libero venenatis faucibus. Nullam quis ante. Etiam sit amet orci eget eros faucibus tincidunt. Duis leo. Sed fringilla mauris sit amet nibh. Donec sodales sagittis magna. Sed consequat, leo eget bibendum sodales, augue velit cursus nunc,Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra quis, feugiat a, tellus. Phasellus viverra nulla ut metus varius laoreet. Quisque rutrum. Aenean imperdiet. Etiam ultricies nisi vel augue. Curabitur ullamcorper ultricies nisi. Nam eget dui. Etiam rhoncus. Maecenas tempus, tellus eget condimentum rhoncus, sem quam semper libero, sit amet adipiscing sem neque sed ipsum. Nam quam nunc, blandit vel, luctus pulvinar, hendrerit id, lorem. Maecenas nec odio et ante tincidunt tempus. Donec vitae sapien ut libero venenatis faucibus. Nullam quis ante. Etiam sit amet orci eget eros faucibus tincidunt. Duis leo. Sed fringilla mauris sit amet nibh. Donec sodales sagittis magna. Sed consequat, leo eget bibendum sodales, augue velit cursus nunc,Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra quis, feugiat a, tellus. Phasellus viverra nulla ut metus varius laoreet. Quisque rutrum. Aenean imperdiet. Etiam ultricies nisi vel augue. Curabitur ullamcorper ultricies nisi. Nam eget dui. Etiam rhoncus. Maecenas tempus, tellus eget condimentum rhoncus, sem quam semper libero, sit amet adipiscing sem neque sed ipsum. Nam quam nunc, blandit vel, luctus pulvinar, hendrerit id, lorem. Maecenas nec odio et ante tincidunt tempus. Donec vitae sapien ut libero venenatis faucibus. Nullam quis ante. Etiam sit amet orci eget eros faucibus tincidunt. Duis leo. Sed fringilla mauris sit amet nibh. Donec sodales sagittis magna. Sed consequat, leo eget bibendum sodales, augue velit cursus nuncCLI'
|
15
|
-
|
16
|
-
METHODS = %w(get post put delete observe)
|
17
|
-
|
18
|
-
if ARGV.size >= 2 && METHODS.include?(ARGV[0])
|
19
|
-
client = CoAP::Client.new
|
20
|
-
$DEBUG = true
|
21
|
-
$WIREDUMP = true
|
22
|
-
require 'pp'
|
23
|
-
|
24
|
-
case ARGV[0]
|
25
|
-
when 'get'
|
26
|
-
pp client.get_by_url(ARGV[1])
|
27
|
-
|
28
|
-
when 'post'
|
29
|
-
pp client.post_by_url(ARGV[1], PAYLOAD)
|
30
|
-
|
31
|
-
when 'put'
|
32
|
-
pp client.put_by_url(ARGV[1], PAYLOAD)
|
33
|
-
|
34
|
-
when 'delete'
|
35
|
-
pp client.delete_by_url(ARGV[1])
|
36
|
-
|
37
|
-
when 'observe'
|
38
|
-
pp client.observe_by_url(ARGV[1], {}, method(:observe_callback))
|
39
|
-
|
40
|
-
end
|
41
|
-
end
|
42
|
-
exit
|
data/lib/coap/block.rb
DELETED
@@ -1,45 +0,0 @@
|
|
1
|
-
module CoAP
|
2
|
-
# CoAP client library
|
3
|
-
class Block
|
4
|
-
def self.initialize(num, more, szx)
|
5
|
-
@logger = CoAP.logger
|
6
|
-
|
7
|
-
{ more: more, szx: szx, num: num }
|
8
|
-
end
|
9
|
-
|
10
|
-
def self.encode(num, more, szx)
|
11
|
-
block = szx | more << 3 | num << 4
|
12
|
-
|
13
|
-
@logger.debug '### CoAP Block encode ###'
|
14
|
-
@logger.debug block
|
15
|
-
@logger.debug '### CoAP Block encode ###'
|
16
|
-
|
17
|
-
block
|
18
|
-
end
|
19
|
-
|
20
|
-
def self.encode_hash(blockHash)
|
21
|
-
blockHash[:more] ? more = 1 : more = 0
|
22
|
-
block = blockHash[:szx] | more << 3 | blockHash[:num] << 4
|
23
|
-
|
24
|
-
@logger.debug '### CoAP Block encode ###'
|
25
|
-
@logger.debug block
|
26
|
-
@logger.debug '### CoAP Block encode ###'
|
27
|
-
|
28
|
-
block
|
29
|
-
end
|
30
|
-
|
31
|
-
def self.decode(blockOption)
|
32
|
-
more = blockOption != nil && (blockOption & 8) === 8
|
33
|
-
szx = blockOption != nil ? blockOption & 7 : 0
|
34
|
-
num = blockOption != nil ? blockOption >> 4 : 0
|
35
|
-
|
36
|
-
@logger.debug '### CoAP Block decode ###'
|
37
|
-
@logger.debug 'm: ' + more.to_s
|
38
|
-
@logger.debug 'szx: ' + szx.to_s
|
39
|
-
@logger.debug 'num: ' + num.to_s
|
40
|
-
@logger.debug '### CoAP Block decode ###'
|
41
|
-
|
42
|
-
{ more: more, szx: szx, num: num }
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|
data/lib/coap/client.rb
DELETED
@@ -1,364 +0,0 @@
|
|
1
|
-
module CoAP
|
2
|
-
|
3
|
-
# CoAP client library
|
4
|
-
class Client
|
5
|
-
|
6
|
-
# attr_writer
|
7
|
-
#
|
8
|
-
# @param max_payload optional payload size, default 256
|
9
|
-
# @param max_retransmit optional retransmit count, default 4
|
10
|
-
# @param ack_timeout optional ack_timeout, default 2
|
11
|
-
# @param hostname dest optional hostname
|
12
|
-
# @param port dest optional port
|
13
|
-
attr_writer :max_payload, :max_retransmit, :ack_timeout, :hostname, :port
|
14
|
-
|
15
|
-
# new arguments
|
16
|
-
#
|
17
|
-
# @param max_payload optional payload size, default 256
|
18
|
-
# @param max_retransmit optional retransmit count, default 4
|
19
|
-
# @param ack_timeout optional ack_timeout, default 2
|
20
|
-
# @param hostname dest optional hostname
|
21
|
-
# @param port dest optional port
|
22
|
-
def initialize(max_payload = 256, max_retransmit = 4, ack_timeout = 2, hostname = nil, port = nil)
|
23
|
-
@max_payload = max_payload
|
24
|
-
@max_retransmit = max_retransmit
|
25
|
-
@ack_timeout = ack_timeout
|
26
|
-
|
27
|
-
@hostname = hostname
|
28
|
-
@port = port
|
29
|
-
|
30
|
-
# dont change the following stuff
|
31
|
-
@retry_count = 0
|
32
|
-
|
33
|
-
@MySocket = MySocket.new
|
34
|
-
@MySocket.socket_type = UDPSocket
|
35
|
-
@MySocket.ack_timeout = @ack_timeout
|
36
|
-
|
37
|
-
@logger = CoAP.logger
|
38
|
-
end
|
39
|
-
|
40
|
-
# Enable DTLS Socket
|
41
|
-
# Needs CoDTLS Gem
|
42
|
-
def use_dtls
|
43
|
-
@MySocket = MySocket.new
|
44
|
-
@MySocket.socket_type = CoDTLS::SecureSocket
|
45
|
-
@MySocket.ack_timeout = @ack_timeout
|
46
|
-
|
47
|
-
self
|
48
|
-
end
|
49
|
-
|
50
|
-
def chunk(string, size)
|
51
|
-
chunks = []
|
52
|
-
string.bytes.each_slice(size) { |i| chunks << i.pack('C*') }
|
53
|
-
chunks
|
54
|
-
# string.scan(/.{1,#{size}}/)
|
55
|
-
end
|
56
|
-
|
57
|
-
def decode_url(url)
|
58
|
-
url_decoded = CoAP.scheme_and_authority_decode(url)
|
59
|
-
|
60
|
-
@logger.debug 'url decoded: ' + url_decoded.inspect
|
61
|
-
fail ArgumentError, 'Invalid URL' if url_decoded.nil?
|
62
|
-
|
63
|
-
url_decoded
|
64
|
-
end
|
65
|
-
|
66
|
-
# simple coap get
|
67
|
-
#
|
68
|
-
# @param url coap scheme + authority url eg coap://coap.me:5683/time
|
69
|
-
# @param options coap options
|
70
|
-
#
|
71
|
-
# @return CoAP::Message #<struct CoAP::Message ver=1, tt=:ack, mcode=[2, 5], mid=866, options={:max_age=>60, :token=>150, :etag=>[16135160785136240028], :content_format=>40, :block2=>226}, payload=\"\\\";ct=50,</5>;rt=\\\"5\\\";ct=50\">"
|
72
|
-
def get_by_url(url, options = {})
|
73
|
-
url_decoded = CoAP.scheme_and_authority_decode(url)
|
74
|
-
|
75
|
-
@logger.debug 'url decoded: ' + url_decoded.inspect
|
76
|
-
fail ArgumentError, 'Invalid URL' if url_decoded.nil?
|
77
|
-
|
78
|
-
get(url_decoded[0], url_decoded[1], url_decoded[2], options)
|
79
|
-
end
|
80
|
-
|
81
|
-
# simple coap get
|
82
|
-
#
|
83
|
-
# @param hostname hostname or ip address
|
84
|
-
# @param port port to connect to
|
85
|
-
# @param uri eg /.well-known/core
|
86
|
-
# @param options coap options
|
87
|
-
#
|
88
|
-
# @return CoAP::Message #<struct CoAP::Message ver=1, tt=:ack, mcode=[2, 5], mid=866, options={:max_age=>60, :token=>150, :etag=>[16135160785136240028], :content_format=>40, :block2=>226}, payload=\"\\\";ct=50,</5>;rt=\\\"5\\\";ct=50\">"
|
89
|
-
def get(hostname, port, uri, options = {})
|
90
|
-
@retry_count = 0
|
91
|
-
client(hostname, port, uri, :get, nil, options)
|
92
|
-
end
|
93
|
-
|
94
|
-
# coap post
|
95
|
-
#
|
96
|
-
# @param url coap scheme + authority url eg coap://coap.me:5683/time
|
97
|
-
# @param payload payload which should be send
|
98
|
-
# @param options coap options
|
99
|
-
#
|
100
|
-
# @return CoAP::Message #<struct CoAP::Message ver=1, tt=:ack, mcode=[2, 5], mid=866, options={:max_age=>60, :token=>150, :etag=>[16135160785136240028], :content_format=>40, :block2=>226}, payload=\"\\\";ct=50,</5>;rt=\\\"5\\\";ct=50\">"
|
101
|
-
def post_by_url(url, payload, options = {})
|
102
|
-
url_decoded = CoAP.scheme_and_authority_decode(url)
|
103
|
-
|
104
|
-
@logger.debug 'url decoded: ' + url_decoded.inspect
|
105
|
-
fail ArgumentError, 'Invalid URL' if url_decoded.nil?
|
106
|
-
|
107
|
-
post(url_decoded[0], url_decoded[1], url_decoded[2], payload, options)
|
108
|
-
end
|
109
|
-
|
110
|
-
# coap post
|
111
|
-
#
|
112
|
-
# @param hostname hostname or ip address
|
113
|
-
# @param port port to connect to
|
114
|
-
# @param uri eg /.well-known/core
|
115
|
-
# @param payload payload which should be send
|
116
|
-
# @param options coap options
|
117
|
-
#
|
118
|
-
# @return CoAP::Message #<struct CoAP::Message ver=1, tt=:ack, mcode=[2, 5], mid=866, options={:max_age=>60, :token=>150, :etag=>[16135160785136240028], :content_format=>40, :block2=>226}, payload=\"\\\";ct=50,</5>;rt=\\\"5\\\";ct=50\">"
|
119
|
-
def post(hostname, port, uri, payload, options = {})
|
120
|
-
@retry_count = 0
|
121
|
-
client(hostname, port, uri, :post, payload, options)
|
122
|
-
end
|
123
|
-
|
124
|
-
# coap put
|
125
|
-
#
|
126
|
-
# @param url coap scheme + authority url eg coap://coap.me:5683/time
|
127
|
-
# @param payload payload which should be send
|
128
|
-
# @param options coap options
|
129
|
-
#
|
130
|
-
# @return CoAP::Message #<struct CoAP::Message ver=1, tt=:ack, mcode=[2, 5], mid=866, options={:max_age=>60, :token=>150, :etag=>[16135160785136240028], :content_format=>40, :block2=>226}, payload=\"\\\";ct=50,</5>;rt=\\\"5\\\";ct=50\">"
|
131
|
-
def put_by_url(url, payload, options = {})
|
132
|
-
url_decoded = CoAP.scheme_and_authority_decode(url)
|
133
|
-
|
134
|
-
@logger.debug 'url decoded: ' + url_decoded.inspect
|
135
|
-
fail ArgumentError, 'Invalid URL' if url_decoded.nil?
|
136
|
-
|
137
|
-
put(url_decoded[0], url_decoded[1], url_decoded[2], payload, options)
|
138
|
-
end
|
139
|
-
|
140
|
-
# coap put
|
141
|
-
#
|
142
|
-
# @param hostname hostname or ip address
|
143
|
-
# @param port port to connect to
|
144
|
-
# @param uri eg /.well-known/core
|
145
|
-
# @param payload payload which should be send
|
146
|
-
# @param options coap options
|
147
|
-
#
|
148
|
-
# @return CoAP::Message #<struct CoAP::Message ver=1, tt=:ack, mcode=[2, 5], mid=866, options={:max_age=>60, :token=>150, :etag=>[16135160785136240028], :content_format=>40, :block2=>226}, payload=\"\\\";ct=50,</5>;rt=\\\"5\\\";ct=50\">"
|
149
|
-
def put(hostname, port, uri, payload, options = {})
|
150
|
-
@retry_count = 0
|
151
|
-
client(hostname, port, uri, :put, payload, options)
|
152
|
-
end
|
153
|
-
|
154
|
-
# coap delete
|
155
|
-
#
|
156
|
-
# @param url coap scheme + authority url eg coap://coap.me:5683/time
|
157
|
-
# @param options coap options
|
158
|
-
#
|
159
|
-
# @return CoAP::Message #<struct CoAP::Message ver=1, tt=:ack, mcode=[2, 5], mid=866, options={:max_age=>60, :token=>150, :etag=>[16135160785136240028], :content_format=>40, :block2=>226}, payload=\"\\\";ct=50,</5>;rt=\\\"5\\\";ct=50\">"
|
160
|
-
def delete_by_url(hostname, port, uri, options = {})
|
161
|
-
url_decoded = CoAP.scheme_and_authority_decode(url)
|
162
|
-
|
163
|
-
@logger.debug 'url decoded: ' + url_decoded.inspect
|
164
|
-
fail ArgumentError, 'Invalid URL' if url_decoded.nil?
|
165
|
-
|
166
|
-
delete(url_decoded[0], url_decoded[1], url_decoded[2], options)
|
167
|
-
end
|
168
|
-
|
169
|
-
# coap delete
|
170
|
-
#
|
171
|
-
# @param hostname hostname or ip address
|
172
|
-
# @param port port to connect to
|
173
|
-
# @param uri eg /.well-known/core
|
174
|
-
# @param options coap options
|
175
|
-
#
|
176
|
-
# @return CoAP::Message #<struct CoAP::Message ver=1, tt=:ack, mcode=[2, 5], mid=866, options={:max_age=>60, :token=>150, :etag=>[16135160785136240028], :content_format=>40, :block2=>226}, payload=\"\\\";ct=50,</5>;rt=\\\"5\\\";ct=50\">"
|
177
|
-
def delete(hostname, port, uri, options = {})
|
178
|
-
@retry_count = 0
|
179
|
-
client(hostname, port, uri, :delete, nil, options)
|
180
|
-
end
|
181
|
-
|
182
|
-
# coap observe
|
183
|
-
#
|
184
|
-
# @param url coap scheme + authority url eg coap://coap.me:5683/time
|
185
|
-
# @param options coap options
|
186
|
-
# @param callback method to call with the observe data eg. observe_callback(payload, socket)
|
187
|
-
#
|
188
|
-
def observe_by_url(hostname, port, uri, callback, options = {})
|
189
|
-
url_decoded = CoAP.scheme_and_authority_decode(url)
|
190
|
-
|
191
|
-
@logger.debug 'url decoded: ' + url_decoded.inspect
|
192
|
-
fail ArgumentError, 'Invalid URL' if url_decoded.nil?
|
193
|
-
|
194
|
-
observe(url_decoded[0], url_decoded[1], url_decoded[2], callback, options)
|
195
|
-
end
|
196
|
-
|
197
|
-
# coap observe
|
198
|
-
#
|
199
|
-
# @param hostname hostname or ip address
|
200
|
-
# @param port port to connect to
|
201
|
-
# @param uri eg /.well-known/core
|
202
|
-
# @param options coap options
|
203
|
-
# @param callback method to call with the observe data eg. observe_callback(payload, socket)
|
204
|
-
#
|
205
|
-
def observe(hostname, port, uri, callback, options = {})
|
206
|
-
options[:observe] = 0
|
207
|
-
client(hostname, port, uri, :get, nil, options, callback)
|
208
|
-
end
|
209
|
-
|
210
|
-
# custom client for special use
|
211
|
-
#
|
212
|
-
# @param url coap scheme + authority url eg coap://coap.me:5683/time
|
213
|
-
# @param method string get post put delete etc
|
214
|
-
# @param payload message payload
|
215
|
-
# @param options coap options
|
216
|
-
#
|
217
|
-
# @return CoAP::Message #<struct CoAP::Message ver=1, tt=:ack, mcode=[2, 5], mid=866, options={:max_age=>60, :token=>150, :etag=>[16135160785136240028], :content_format=>40, :block2=>226}, payload=\"\\\";ct=50,</5>;rt=\\\"5\\\";ct=50\">"
|
218
|
-
def custom(url, method, payload = nil, options = {})
|
219
|
-
|
220
|
-
url_decoded = decode_url url
|
221
|
-
client(url_decoded[0], url_decoded[1], url_decoded[2], method.to_sym, payload, options)
|
222
|
-
|
223
|
-
end
|
224
|
-
|
225
|
-
private
|
226
|
-
|
227
|
-
def client(hostname, port, uri, method, payload, options, observe_callback = nil)
|
228
|
-
|
229
|
-
# set hostname + port only one time on multiple requests
|
230
|
-
hostname.nil? ? (hostname = @hostname unless @hostname.nil?) : @hostname = hostname
|
231
|
-
port.nil? ? (port = @port unless @port.nil?) : @port = port
|
232
|
-
|
233
|
-
# Error handling for paramaters
|
234
|
-
fail ArgumentError, 'hostname missing' if hostname.nil? || hostname.empty?
|
235
|
-
fail ArgumentError, 'port missing' if port.nil?
|
236
|
-
fail ArgumentError, 'port must ba an integer' unless port.is_a? Integer
|
237
|
-
fail ArgumentError, 'uri missing' if uri.nil? || uri.empty?
|
238
|
-
fail ArgumentError, 'payload must be a string' unless payload.is_a? String unless payload.nil?
|
239
|
-
fail ArgumentError, 'payload shouldnt be empty ' if payload.empty? unless payload.nil?
|
240
|
-
|
241
|
-
# generate random message id
|
242
|
-
mid = Random.rand(999)
|
243
|
-
token = Random.rand(256)
|
244
|
-
szx = Math.log2(@max_payload).floor - 4
|
245
|
-
|
246
|
-
# initialize block 2 with payload size
|
247
|
-
block2 = Block.initialize(0, false, szx)
|
248
|
-
|
249
|
-
# initialize block1 if set
|
250
|
-
block1 = options[:block1].nil? ? Block.initialize(0, false, szx) : Block.decode(options[:block1])
|
251
|
-
|
252
|
-
# initialize chunks if payload size > max_payload
|
253
|
-
chunks = chunk(payload, 2**((Math.log2(@max_payload).floor - 4) + 4)) unless payload.nil?
|
254
|
-
|
255
|
-
# create coap message struct
|
256
|
-
message = Message.new(:con, method, mid, nil, {})
|
257
|
-
# , block2: Block.encode_hash(block2)
|
258
|
-
message.options = { uri_path: CoAP.path_decode(uri), token: token }
|
259
|
-
message.options[:block2] = Block.encode_hash(block2) if @max_payload != 256 # temp fix to disable early negotation
|
260
|
-
message.payload = payload unless payload.nil?
|
261
|
-
|
262
|
-
### initialize stuff end
|
263
|
-
|
264
|
-
# if chunks.size 1 > we need to use block1
|
265
|
-
if !payload.nil? and chunks.size > 1
|
266
|
-
# increase block number
|
267
|
-
block1[:num] += 1 unless options[:block1].nil?
|
268
|
-
# more ?
|
269
|
-
block1[:more] = chunks.size > block1[:num] + 1
|
270
|
-
chunks.size > block1[:num] + 1 ? message.options.delete(:block2) : block1[:more] = false
|
271
|
-
# set final payload
|
272
|
-
message.payload = chunks[block1[:num]]
|
273
|
-
# set message option
|
274
|
-
message.options[:block1] = Block.encode_hash(block1)
|
275
|
-
end
|
276
|
-
|
277
|
-
# preserve user options
|
278
|
-
message.options[:block2] = options[:block2] unless options[:block2] == nil
|
279
|
-
message.options[:observe] = options[:observe] unless options[:observe] == nil
|
280
|
-
message.options.merge(options)
|
281
|
-
|
282
|
-
# debug functions
|
283
|
-
@logger.debug '### CoAP Send Data ###'
|
284
|
-
#@logger.debug message.to_s.hexdump
|
285
|
-
@logger.debug message.inspect
|
286
|
-
@logger.debug '### CoAP Send Data ###'
|
287
|
-
|
288
|
-
# connect via udp/dtls
|
289
|
-
@MySocket.connect hostname, port
|
290
|
-
@MySocket.send message.to_wire, 0
|
291
|
-
|
292
|
-
# send message + retry
|
293
|
-
begin
|
294
|
-
recv_data = @MySocket.receive
|
295
|
-
rescue Timeout::Error
|
296
|
-
@retry_count += 1
|
297
|
-
raise 'Retry Timeout ' + @retry_count.to_s if @retry_count > @max_retransmit
|
298
|
-
return client(hostname, port, uri, method, payload, options, observe_callback)
|
299
|
-
end
|
300
|
-
|
301
|
-
# parse recv data
|
302
|
-
recv_parsed = CoAP.parse(recv_data[0].force_encoding('BINARY'))
|
303
|
-
|
304
|
-
# debug functions
|
305
|
-
@logger.debug '### CoAP Received Data ###'
|
306
|
-
#@logger.debug recv_parsed.to_s.hexdump
|
307
|
-
@logger.debug recv_parsed.inspect
|
308
|
-
@logger.debug '### CoAP Received Data ###'
|
309
|
-
|
310
|
-
# payload is not fully transmitted
|
311
|
-
if block1[:more]
|
312
|
-
fail 'Max Recursion' if @retry_count > 10
|
313
|
-
return client(hostname, port, uri, method, payload, message.options)
|
314
|
-
end
|
315
|
-
|
316
|
-
# separate ?
|
317
|
-
if recv_parsed.tt == :ack && recv_parsed.payload.empty? && recv_parsed.mid == mid && recv_parsed.mcode[0] == 0 && recv_parsed.mcode[1] == 0
|
318
|
-
@logger.debug '### SEPARATE REQUEST ###'
|
319
|
-
|
320
|
-
# wait for answer ...
|
321
|
-
recv_data = @MySocket.receive(600, @retry_count)
|
322
|
-
recv_parsed = CoAP.parse(recv_data[0].force_encoding('BINARY'))
|
323
|
-
|
324
|
-
# debug functions
|
325
|
-
@logger.debug '### CoAP SEPARAT Data ###'
|
326
|
-
#@logger.debug recv_parsed.to_s.hexdump
|
327
|
-
@logger.debug recv_parsed.inspect
|
328
|
-
@logger.debug '### CoAP SEPARAT Data ###'
|
329
|
-
|
330
|
-
if recv_parsed.tt == :con
|
331
|
-
message = Message.new(:ack, 0, recv_parsed.mid, nil, {})
|
332
|
-
message.options = { token: recv_parsed.options[:token] }
|
333
|
-
@MySocket.send message.to_wire, 0
|
334
|
-
end
|
335
|
-
|
336
|
-
@logger.debug '### SEPARATE REQUEST END ###'
|
337
|
-
end
|
338
|
-
|
339
|
-
# test for more block2 payload
|
340
|
-
block2 = Block.decode(recv_parsed.options[:block2])
|
341
|
-
|
342
|
-
if block2[:more]
|
343
|
-
block2[:num] += 1
|
344
|
-
|
345
|
-
options.delete(:block1) # end block1
|
346
|
-
options[:block2] = Block.encode_hash(block2)
|
347
|
-
fail 'Max Recursion' if @retry_count > 50
|
348
|
-
local_recv_parsed = client(hostname, port, uri, method, nil, options)
|
349
|
-
recv_parsed.payload << local_recv_parsed.payload unless local_recv_parsed.nil?
|
350
|
-
end
|
351
|
-
|
352
|
-
# do we need to observe?
|
353
|
-
if recv_parsed.options[:observe]
|
354
|
-
@Observer = CoAP::Observer.new
|
355
|
-
@Observer.observe(recv_parsed, recv_data, observe_callback, @MySocket)
|
356
|
-
end
|
357
|
-
|
358
|
-
# this is bad
|
359
|
-
fail ArgumentError, 'wrong token returned' if recv_parsed.options[:token] != token # create own error class
|
360
|
-
|
361
|
-
recv_parsed
|
362
|
-
end
|
363
|
-
end
|
364
|
-
end
|