1
0
mirror of https://github.com/mainflux/mainflux.git synced 2025-05-12 19:29:30 +08:00
Dušan Borovčanin d6755e4a72 MF-374 - Bring back CoAP adapter (#413)
* Bring old CoAP code back

Signed-off-by: Dušan Borovčanin <dusan.borovcanin@mainflux.com>

* Fix channel ID formatting due to type change

Uncomment error handling for authorization.

Signed-off-by: Dušan Borovčanin <dusan.borovcanin@mainflux.com>

* Update CoAP adapter docs

Signed-off-by: Dušan Borovčanin <dusan.borovcanin@mainflux.com>

* Add copyright headers

Signed-off-by: Dusan Borovcanin <dusan.borovcanin@mainflux.com>

* Remove redundant type declaration

Signed-off-by: Dusan Borovcanin <dusan.borovcanin@mainflux.com>

* Add CoAP adapter to the list of services

Add CoAp adapter in Makefile services list and fix corresponding documentation.

Signed-off-by: Dusan Borovcanin <dusan.borovcanin@mainflux.com>

* Refactor CoAP code

Merge multipe `const` block int single and declare consts before vars.
Un-export notFound handler since there is no need to export it.

Signed-off-by: Dusan Borovcanin <dusan.borovcanin@mainflux.com>

* Update http version endpoint

This separates CoAP and HTTP APIs.

Signed-off-by: Dusan Borovcanin <dusan.borovcanin@mainflux.com>

* Refactor CoAP POST method handling

This PR is a part of CoAP adapter refactoring that will simplify adapter implementation.

Signed-off-by: Dusan Borovcanin <dusan.borovcanin@mainflux.com>

* Refactor CoAP adapter

Change CoAP message handling to simplify adapter implementation.

Signed-off-by: Dusan Borovcanin <dusan.borovcanin@mainflux.com>

* Add backoff timeout for server ping to client

Update CoAP adapter to provide subset of necessary features from
protocol specification.

Signed-off-by: Dusan Borovcanin <dusan.borovcanin@mainflux.com>

* Fix leaking locked goroutine

In case of the stopped ticker, its channel is NOT closed, so pinging might be left stuck waiting for the stopped ticker to send a notification.

Signed-off-by: Dusan Borovcanin <dusan.borovcanin@mainflux.com>

* Format code

Use more meaningful name for Handlers map.

Signed-off-by: Dusan Borovcanin <dusan.borovcanin@mainflux.com>

* Use and stop ticker from the same goroutine

Stop handler Ticker from ping goroutine rather than the cancel goroutine.

Signed-off-by: Dusan Borovcanin <dusan.borovcanin@mainflux.com>

* Check if subscription already exists in put method

Fix potential leak of handlers providing check inside of put method.

Signed-off-by: Dusan Borovcanin <dusan.borovcanin@mainflux.com>

* Use MessageID as Observe option

Since MessageID satisfies observe option behaviour, use Message ID
instead of local timestamp. Remove Thicker from handler and use it on
transport layer.

Signed-off-by: Dusan Borovcanin <dusan.borovcanin@mainflux.com>

* Use name Observer insted of Handler

Name `Observer` is used in protocol specification, so this naming makes
code more self-documenting.

Signed-off-by: Dusan Borovcanin <dusan.borovcanin@mainflux.com>

* Add CoAP adapter to docker-compose.yml

Signed-off-by: Dusan Borovcanin <dusan.borovcanin@mainflux.com>

* Add copyright headers

Signed-off-by: Dusan Borovcanin <dusan.borovcanin@mainflux.com>

* Remove unused constants

Fix service name in startup log message.

Signed-off-by: Dusan Borovcanin <dusan.borovcanin@mainflux.com>

* Add metrics endpoint

Signed-off-by: Dusan Borovcanin <dusan.borovcanin@mainflux.com>

* Refactor code

Config fields from main.go should not be exported; minor style changes.

Signed-off-by: Dusan Borovcanin <dusan.borovcanin@mainflux.com>

* Update authorization URI-Query option

Use `authorization` value in URI-Query option instead of `key`. This
mimics Authorization header in some other protocols (e.g. HTTP). Please
note that this value can be replaced with simple `auth` to save space,
due to constrained URI-Query option size.

Signed-off-by: Dusan Borovcanin <dusan.borovcanin@mainflux.com>
2018-10-31 18:53:25 +01:00

105 lines
2.2 KiB
Go

package mux
import (
"net"
"sync"
coap "github.com/dustin/go-coap"
)
var (
mutex sync.RWMutex
msgVars = make(map[*coap.Message]map[string]string)
)
func setVar(msg *coap.Message, name, data string) {
mutex.Lock()
r, exists := msgVars[msg]
if !exists {
r = make(map[string]string)
}
r[name] = data
mutex.Unlock()
}
func setVars(msg *coap.Message, vars map[string]string) {
mutex.Lock()
msgVars[msg] = vars
mutex.Unlock()
}
// Var retrieves a named variable for this message
func Var(msg *coap.Message, name string) string {
mutex.RLock()
var value = ""
r, exists := msgVars[msg]
if exists {
value = r[name]
}
mutex.RUnlock()
return value
}
func clearVars(msg *coap.Message) {
mutex.Lock()
delete(msgVars, msg)
mutex.Unlock()
}
// Router handles routing CoAP Messages to the correct handlers. Currently
// It doesn't support default routes etc.
type Router struct {
NotFoundHandler coap.Handler
routes []*Route
}
// NewRouter creates a new Router
func NewRouter() *Router {
return &Router{routes: make([]*Route, 0, 50)}
}
// Match matches the incoming message against all routes. The first matching route
// wins.
func (r *Router) Match(msg *coap.Message, addr *net.UDPAddr, match *RouteMatch) bool {
for _, route := range r.routes {
if route.Match(msg, addr, match) {
return true
}
}
return false
}
// NewRoute creates a new unconfigured Route
func (r *Router) NewRoute() *Route {
route := &Route{}
r.routes = append(r.routes, route)
return route
}
// Handle creates a new Route with the given handler and a matcher for the
// given path
func (r *Router) Handle(path string, handler coap.Handler) *Route {
return r.NewRoute().Path(path).Handler(handler)
}
// Path creates a new Route with a matcher for the given path
func (r *Router) Path(tpl string) *Route {
return r.NewRoute().Path(tpl)
}
// This method implements the interface for coap.Handler
func (r *Router) ServeCOAP(l *net.UDPConn, a *net.UDPAddr, m *coap.Message) *coap.Message {
match := &RouteMatch{}
var returnMessage *coap.Message
if r.Match(m, a, match) {
// TODO set vars
setVars(m, match.Vars)
returnMessage = match.Handler.ServeCOAP(l, a, m)
clearVars(m)
} else {
returnMessage = r.NotFoundHandler.ServeCOAP(l, a, m)
}
return returnMessage
}