mirror of
https://github.com/mainflux/mainflux.git
synced 2025-05-12 19:29:30 +08:00

* 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>
105 lines
2.2 KiB
Go
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
|
|
}
|