CoAP Client/Server implementing RFC 7252 for the Go Language
Switch branches/tags
Nothing to show
Clone or download
zubairhamed Merge pull request #94 from zltl/patch-1
calculate blockPayloadStart wrong when send blocks
Latest commit e374f5b Feb 7, 2018
Permalink
Failed to load latest commit information.
Godeps Adding Godep file (and removing Gomfile) Dec 5, 2016
examples update NewRequest syntax in DTLS example Apr 30, 2017
openssl @ b9b5181 OpenSSL Submodule Dec 13, 2016
.gitignore - OpenSSL Submodule Dec 13, 2016
.gitmodules OpenSSL Submodule Dec 13, 2016
LICENSE Update LICENSE Jul 6, 2015
README.md - OpenSSL Submodule Dec 13, 2016
bytecontent.go (unstable) refactoring Nov 7, 2016
canopus.go Refactor to make GenerateMessageId() optional in some methods Dec 14, 2016
client.go - implement dtls Nov 20, 2016
conn.go calculate blockPayloadStart wrong when send blocks Jun 8, 2017
corelink.go (unstable) refactoring Nov 7, 2016
coreresource.go (unstable) refactoring Nov 7, 2016
coreresource_test.go Lots of refactoring Nov 3, 2016
dtls.go Refactor to make GenerateMessageId() optional in some methods Dec 14, 2016
empty.go (unstable) refactoring Nov 7, 2016
event.go Fix compilation problems, refactoring Nov 7, 2016
event_test.go Fix tests Dec 8, 2016
init.go - implement dtls Nov 20, 2016
json.go (unstable) refactoring Nov 7, 2016
message.go For issue #81 Dec 14, 2016
message_test.go Fix tests Dec 8, 2016
options.go Refactor Session struct Nov 6, 2016
plaintext.go (unstable) refactoring Nov 7, 2016
proxy.go - implement dtls Nov 20, 2016
request.go Refactor to make GenerateMessageId() optional in some methods Dec 14, 2016
request_test.go Fix tests Dec 8, 2016
response.go refactoring Nov 7, 2016
response_test.go Fix tests Dec 8, 2016
routes.go refactoring Nov 7, 2016
routes_test.go Fix tests Dec 8, 2016
server.go Refactor to make GenerateMessageId() optional in some methods Dec 14, 2016
server_test.go Fix tests Dec 8, 2016
serverconn.go unstable commit, move dtls code to .c Nov 12, 2016
session.go Refactor dTLS Code a bit Nov 25, 2016
test-coverage.sh Test coverage script Jul 13, 2015
types.go (unstable) refactoring Nov 7, 2016
utilconn_test.go Fix tests Dec 8, 2016
utildebug.go Refactor dTLS Code a bit Nov 25, 2016
utils.go Apply Mutex Lock to CurrentMessageID Dec 14, 2016
utils_test.go Lots of refactoring Nov 3, 2016
xml.go (unstable) refactoring Nov 7, 2016

README.md

Canopus

GoDoc Build Status Coverage Status Go Report Card

Canopus is a client/server implementation of the Constrained Application Protocol (CoAP)

Updates

25.11.2016

I've added basic dTLS Support based on [Julien Vermillard's][JVERMILLARD] [implementation][NATIVEDTLS]. Thanks Julien! It should now support PSK-based authentication. I've also gone ahead and refactored the APIs to make it that bit more Go idiomatic. [JVERMILLARD]: https://github.com/jvermillard [NATIVEDTLS]: https://github.com/jvermillard/nativedtls

Building and running

  1. git submodule update --init --recursive
  2. cd openssl
  3. ./config && make
  4. You should then be able to run the examples in the /examples folder

Simple Example

	// Server
	// See /examples/simple/server/main.go
	server := canopus.NewServer()

	server.Get("/hello", func(req canopus.Request) canopus.Response {
		msg := canopus.ContentMessage(req.GetMessage().GetMessageId(), canopus.MessageAcknowledgment)
		msg.SetStringPayload("Acknowledged: " + req.GetMessage().GetPayload().String())

		res := canopus.NewResponse(msg, nil)
		return res
	})

	server.ListenAndServe(":5683")

	// Client
	// See /examples/simple/client/main.go
	conn, err := canopus.Dial("localhost:5683")
	if err != nil {
		panic(err.Error())
	}

	req := canopus.NewRequest(canopus.MessageConfirmable, canopus.Get, canopus.GenerateMessageID()).(*canopus.CoapRequest)
	req.SetStringPayload("Hello, canopus")
	req.SetRequestURI("/hello")

	resp, err := conn.Send(req)
	if err != nil {
		panic(err.Error())
	}

	fmt.Println("Got Response:" + resp.GetMessage().GetPayload().String())

Observe / Notify

	// Server
	// See /examples/observe/server/main.go
	server := canopus.NewServer()
	server.Get("/watch/this", func(req canopus.Request) canopus.Response {
		msg := canopus.NewMessageOfType(canopus.MessageAcknowledgment, req.GetMessage().GetMessageId(), canopus.NewPlainTextPayload("Acknowledged"))
		res := canopus.NewResponse(msg, nil)

		return res
	})

	ticker := time.NewTicker(3 * time.Second)
	go func() {
		for {
			select {
			case <-ticker.C:
				changeVal := strconv.Itoa(rand.Int())
				fmt.Println("[SERVER << ] Change of value -->", changeVal)

				server.NotifyChange("/watch/this", changeVal, false)
			}
		}
	}()

	server.OnObserve(func(resource string, msg canopus.Message) {
		fmt.Println("[SERVER << ] Observe Requested for " + resource)
	})

	server.ListenAndServe(":5683")

	// Client
	// See /examples/observe/client/main.go
	conn, err := canopus.Dial("localhost:5683")

	tok, err := conn.ObserveResource("/watch/this")
	if err != nil {
		panic(err.Error())
	}

	obsChannel := make(chan canopus.ObserveMessage)
	done := make(chan bool)
	go conn.Observe(obsChannel)

	notifyCount := 0
	for {
		select {
		case obsMsg, _ := <-obsChannel:
			if notifyCount == 5 {
				fmt.Println("[CLIENT >> ] Canceling observe after 5 notifications..")
				go conn.CancelObserveResource("watch/this", tok)
				go conn.StopObserve(obsChannel)
				return
			} else {
				notifyCount++
				// msg := obsMsg.Msg\
				resource := obsMsg.GetResource()
				val := obsMsg.GetValue()

				fmt.Println("[CLIENT >> ] Got Change Notification for resource and value: ", notifyCount, resource, val)
			}
		}
	}

dTLS with PSK

	// Server
	// See /examples/dtls/simple-psk/server/main.go
	server := canopus.NewServer()

	server.Get("/hello", func(req canopus.Request) canopus.Response {
		msg := canopus.ContentMessage(req.GetMessage().GetMessageId(), canopus.MessageAcknowledgment)
		msg.SetStringPayload("Acknowledged: " + req.GetMessage().GetPayload().String())
		res := canopus.NewResponse(msg, nil)

		return res
	})

	server.HandlePSK(func(id string) []byte {
		return []byte("secretPSK")
	})

	server.ListenAndServeDTLS(":5684")

	// Client
	// See /examples/dtls/simple-psk/client/main.go
	conn, err := canopus.DialDTLS("localhost:5684", "canopus", "secretPSK")
	if err != nil {
		panic(err.Error())
	}

	req := canopus.NewRequest(canopus.MessageConfirmable, canopus.Get, canopus.GenerateMessageID())
	req.SetStringPayload("Hello, canopus")
	req.SetRequestURI("/hello")

	resp, err := conn.Send(req)
	if err != nil {
		panic(err.Error())
	}

	fmt.Println("Got Response:" + resp.GetMessage().GetPayload().String())

CoAP-CoAP Proxy

	// Server
	// See /examples/proxy/coap/server/main.go
	server := canopus.NewServer()

	server.Get("/proxycall", func(req canopus.Request) canopus.Response {
		msg := canopus.ContentMessage(req.GetMessage().GetMessageId(), canopus.MessageAcknowledgment)
		msg.SetStringPayload("Data from :5685 -- " + req.GetMessage().GetPayload().String())
		res := canopus.NewResponse(msg, nil)

		return res
	})
	server.ListenAndServe(":5685")

	// Proxy Server
	// See /examples/proxy/coap/proxy/main.go
	server := canopus.NewServer()
	server.ProxyOverCoap(true)

	server.Get("/proxycall", func(req canopus.Request) canopus.Response {
		canopus.PrintMessage(req.GetMessage())
		msg := canopus.ContentMessage(req.GetMessage().GetMessageId(), canopus.MessageAcknowledgment)
		msg.SetStringPayload("Acknowledged: " + req.GetMessage().GetPayload().String())
		res := canopus.NewResponse(msg, nil)

		return res
	})
	server.ListenAndServe(":5683")

	// Client
	// See /examples/proxy/coap/client/main.go
	conn, err := canopus.Dial("localhost:5683")
	if err != nil {
		panic(err.Error())
	}

	req := canopus.NewRequest(canopus.MessageConfirmable, canopus.Get, canopus.GenerateMessageID())
	req.SetProxyURI("coap://localhost:5685/proxycall")

	resp, err := conn.Send(req)
	if err != nil {
		println("err", err)
	}
	canopus.PrintMessage(resp.GetMessage())

CoAP-HTTP Proxy

	// Server
	// See /examples/proxy/http/server/main.go
	server := canopus.NewServer()
	server.ProxyOverHttp(true)

	server.ListenAndServe(":5683")

	// Client
	// See /examples/proxy/http/client/main.go
	conn, err := canopus.Dial("localhost:5683")
	if err != nil {
		panic(err.Error())
	}

	req := canopus.NewRequest(canopus.MessageConfirmable, canopus.Get, canopus.GenerateMessageID())
	req.SetProxyURI("https://httpbin.org/get")

	resp, err := conn.Send(req)
	if err != nil {
		println("err", err)
	}
	canopus.PrintMessage(resp.GetMessage())