bin/coap

Summary

Maintainability
Test Coverage
#!/usr/bin/env ruby

require 'getoptlong'
require 'pp'
require 'uri'

$:.unshift File.expand_path('../lib', File.dirname(__FILE__))
require 'coap'

def usage
  $stderr.puts <<EOF
Usage: #{File.basename($0)} [options] <method> <uri>

  --content-format, -c  <string>  Content format.
  --debug, -d                     Extra debug output.
  --output, -o          <target>  Redirect payload output. Target can be "-" for
                                  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.
  --type, -t            <type>    Message type (con, non, ack, rst).
  --help, -h                      This usage message.

EOF
  exit 1
end

METHODS = CoAP::METHODS + [:observe]

opts = GetoptLong.new(
  ['--content-format',  '-c', GetoptLong::REQUIRED_ARGUMENT],
  ['--debug',           '-d', GetoptLong::NO_ARGUMENT],
  ['--output',          '-o', GetoptLong::REQUIRED_ARGUMENT],
  ['--payload',         '-p', GetoptLong::REQUIRED_ARGUMENT],
  ['--payload-file',    '-f', GetoptLong::REQUIRED_ARGUMENT],
  ['--type',            '-t', GetoptLong::REQUIRED_ARGUMENT],
  ['--help',            '-h', GetoptLong::NO_ARGUMENT]
)

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

opts.each do |opt, arg|
  case opt
  when '--content-format'
    cf = CoAP::Registry.convert_content_format(arg)
    options[:content_format] = cf
  when '--debug'
    $DEBUG = true
  when '--output'
    if arg == '-'
      output = $stdout
    else
      output = File.open(arg, 'w')
    end
  when '--payload'
    payload = arg
  when '--payload-file'
    payload = File.read(arg)
  when '--type'
    options[:tt] = arg.to_sym
  when '--help'
    usage
  end
end

usage if ARGV.size != 2

method = ARGV.shift
uri    = ARGV.shift

method = method.to_sym
usage unless METHODS.include? method

uri = 'coap://' + uri unless uri[/^coap[s]?:\/\//]
uri = URI.parse(uri)

usage unless uri.scheme[/^coap/]

client = CoAP::Client.new

answer = case method
when :get
  client.get_by_uri(uri, payload, options)

when :post
  client.post_by_uri(uri, payload, options)

when :put
  client.put_by_uri(uri, payload, options)

when :delete
  client.delete_by_uri(uri, payload, options)

when :observe
  callback = ->(socket, message) do
    if output
      output.puts message.payload
    else
      pp message
    end
  end

  begin
    client.observe_by_uri(uri, callback)
  rescue Interrupt
    exit
  end
end

if output
  output.puts answer.payload
else
  pp answer
  case answer.options[:content_format]
  when 50
    require 'json'
    pp JSON.parse(answer.payload)
  when 60
    require 'cbor'
    pp CBOR.load(answer.payload)
  end
end