Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 14 additions & 5 deletions bin/coap
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ Usage: #{File.basename($0)} [options] <method> <uri>
STDOUT or a file path.
--payload, -p <string> Payload for POST and PUT as string.
--payload-file, -f <file> Read payload for POST and PUT from file.
--identity-file, -i <file> Read DTLS identity from file.
--key-file, -k <file> Read DTLS PSK form file.
--type, -t <type> Message type (con, non, ack, rst).
--help, -h This usage message.

Expand All @@ -27,6 +29,8 @@ end
METHODS = CoAP::METHODS + [:observe]

opts = GetoptLong.new(
['--identity-file', '-i', GetoptLong::REQUIRED_ARGUMENT],
['--key-file', '-k', GetoptLong::REQUIRED_ARGUMENT],
['--content-format', '-c', GetoptLong::REQUIRED_ARGUMENT],
['--debug', '-d', GetoptLong::NO_ARGUMENT],
['--output', '-o', GetoptLong::REQUIRED_ARGUMENT],
Expand All @@ -36,13 +40,18 @@ opts = GetoptLong.new(
['--help', '-h', GetoptLong::NO_ARGUMENT]
)

$DEBUG = false
output = nil
payload = nil
options = {}
$DEBUG = false
output = nil
payload = nil
options = {}
initopts = {}

opts.each do |opt, arg|
case opt
when '--identity-file'
initopts[:dtls_id] = File.read(arg)
when '--key-file'
initopts[:dtls_key] = File.read(arg)
when '--content-format'
cf = CoAP::Registry.convert_content_format(arg)
options[:content_format] = cf
Expand Down Expand Up @@ -78,7 +87,7 @@ uri = URI.parse(uri)

usage unless uri.scheme[/^coap/]

client = CoAP::Client.new
client = CoAP::Client.new(initopts)

answer = case method
when :get
Expand Down
24 changes: 20 additions & 4 deletions lib/core/coap/client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ class Client
# (maximum retransmission count, default 4),
# recv_timeout (timeout for ACK responses, default: 2),
# host (destination host), post (destination port,
# default 5683).
# default 5683), dtls_id (DTLS client identity)
# and dtls_key (DTLS pre-shared key).
def initialize(options = {})
@max_payload = options[:max_payload] || 256

Expand All @@ -25,8 +26,18 @@ def initialize(options = {})

# Enable DTLS socket.
def use_dtls
require 'CoDTLS'
@options[:socket] = CoDTLS::SecureSocket
require 'tinydtls'

id = @options[:dtls_id]
key = @options[:dtls_key]

if id.nil? or key.nil?
raise ArgumentError.new("DTLS support requires specification of an identity/key pair")
end

@options[:socket] = TinyDTLS::UDPSocket.new
@options[:socket].add_client(id, key)

self
end

Expand Down Expand Up @@ -267,7 +278,12 @@ def decode_uri(uri)
@logger.debug 'URI decoded: ' + uri.inspect
fail ArgumentError, 'Invalid URI' if uri.nil?

uri
scheme = uri.first
if scheme == "coaps"
self.use_dtls
end

uri.drop(1)
end

def initialize_message(method, path, query = nil, payload = nil)
Expand Down
15 changes: 11 additions & 4 deletions lib/core/coap/coding.rb
Original file line number Diff line number Diff line change
Expand Up @@ -89,10 +89,17 @@ def scheme_and_authority_encode(host, port)
end

def scheme_and_authority_decode(s)
if s =~ %r{\A(?:coap://)((?:\[|%5B)([^\]]*)(?:\]|%5D)|([^:/]*))(:(\d+))?(/.*)?\z}i
host = $2 || $3 # Should check syntax...
port = $5 || CoAP::PORT
[$6, host, port.to_i]
if s =~ %r{\A(?:(coap|coaps)://)((?:\[|%5B)([^\]]*)(?:\]|%5D)|([^:/]*))(:(\d+))?(/.*)?\z}i
scheme = $1 || "coap"
host = $3 || $4 # Should check syntax...
port = $6

if port.nil?
port = scheme == "coap" ?
CoAP::PORT : CoAP::PORT_DTLS
end

[scheme, $7, host, port.to_i]
end
end

Expand Down
10 changes: 6 additions & 4 deletions test/test_message.rb
Original file line number Diff line number Diff line change
Expand Up @@ -71,10 +71,12 @@ def test_scheme_and_authority_encode
end

def test_scheme_and_authority_decode
assert_equal [nil, "foo.bar", 4711], CoRE::CoAP.scheme_and_authority_decode("coap://foo.bar:4711")
assert_equal [nil, "foo.bar", 5683], CoRE::CoAP.scheme_and_authority_decode("coap://foo.bar")
assert_equal [nil, "foo:bar", 4711], CoRE::CoAP.scheme_and_authority_decode("coap://[foo:bar]:4711")
assert_equal [nil, "foo:bar", 5683], CoRE::CoAP.scheme_and_authority_decode("coap://%5Bfoo:bar%5D")
assert_equal ["coap", nil, "foo.bar", 4711], CoRE::CoAP.scheme_and_authority_decode("coap://foo.bar:4711")
assert_equal ["coap", nil, "foo.bar", 5683], CoRE::CoAP.scheme_and_authority_decode("coap://foo.bar")
assert_equal ["coap", nil, "foo:bar", 4711], CoRE::CoAP.scheme_and_authority_decode("coap://[foo:bar]:4711")
assert_equal ["coap", nil, "foo:bar", 5683], CoRE::CoAP.scheme_and_authority_decode("coap://%5Bfoo:bar%5D")

assert_equal ["coaps", nil, "foo.bar", 5684], CoRE::CoAP.scheme_and_authority_decode("coaps://foo.bar")
end

def test_coap_message
Expand Down