func newEvent (ev C.coap_event_t) Event {
    switch ev {
    case C.COAP_EVENT_DTLS_CLOSED:      return EventSessionDisconnected
    case C.COAP_EVENT_DTLS_CONNECTED:   return EventSessionConnected
    case C.COAP_EVENT_DTLS_RENEGOTIATE: return EventSessionRenegotiate
    case C.COAP_EVENT_DTLS_ERROR:       return EventSessionError
    default: return -1
    }
}
Create Event type from coap_event_t
package libcoap
import "C"
import "errors"
import "unsafe"
import "strings"
import "strconv"
import log "github.com/sirupsen/logrus"
import cache "github.com/patrickmn/go-cache"
type MethodHandler func(*Context, *Resource, *Session, *Pdu, *[]byte, *string, *Pdu)
type EventHandler func(*Context, Event, *Session)
type EndPoint struct {
    ptr *C.coap_endpoint_t
}
var mitigationMap = make(map[string]bool)
func SetMitigationMap(key string, value bool) {
    mitigationMap[key] = value
}
func GetMitigationMapByKey(key string) bool {
    return mitigationMap[key]
}
func DeleteMitigationMapByKey(key string) {
    delete(mitigationMap, key)
}
type Event int
const (
    EventSessionDisconnected Event = C.COAP_EVENT_DTLS_CLOSED
    EventSessionConnected    Event = C.COAP_EVENT_DTLS_CONNECTED
    EventSessionRenegotiate  Event = C.COAP_EVENT_DTLS_RENEGOTIATE
    EventSessionError        Event = C.COAP_EVENT_DTLS_ERROR
)
func (context *Context) ContextSetPSK(identity string, key []byte) {
    cid := C.CString(identity)
    defer C.free(unsafe.Pointer(cid))
    C.coap_context_set_psk(context.ptr,
                           cid,
                           (*C.uint8_t)(&key[0]),
                           C.size_t(len(key)))
}
func export_method_handler(ctx   *C.coap_context_t,
                           rsrc  *C.coap_resource_t,
                           sess  *C.coap_session_t,
                           req   *C.coap_pdu_t,
                           tok   *C.coap_string_t,
                           query *C.coap_string_t,
                           resp  *C.coap_pdu_t) {
    context, ok := contexts[ctx]
    if !ok {
        return
    }
    resource, ok := resources[rsrc]
    if !ok {
        return
    }
    is_observe := false
    if req == nil {
        is_observe = true
        req = resp
    }
    session, ok := sessions[sess]
    if !ok {
		return
    }
    request, err := req.toGo()
    if err != nil {
        return
    }
    if is_observe {
        request.Code = RequestGet
        request.Options = make([]Option, 0)
        var uri []string
        tmpUri := strings.Split(*(rsrc.uri_path.toString()), "?")
        if len(tmpUri) > 1 {
            uri = strings.Split(tmpUri[0], "/")
            queries := strings.Split(tmpUri[1], "&")
            uri = append(uri, queries...)
        } else {
            uri = strings.Split(*(rsrc.uri_path.toString()), "/")
        }
        request.SetPath(uri)
        session.SetIsNotification(true)
        log.WithField("Request:", request).Debug("Re-create request for handling obervation\n")
    }
    token := tok.toBytes()
    queryString := query.toString()
    isObserveOne := false
    mid := ""
    resourceOneUriPaths := strings.Split(*(rsrc.uri_path.toString()), "/mid=")
    if len(resourceOneUriPaths) > 1 && queryString == nil {
        isObserveOne = true
        mid = resourceOneUriPaths[1]
    }
    handler, ok := resource.handlers[request.Code]
    if ok {
        etag, err := request.GetOptionIntegerValue(OptionEtag)
        if err != nil {
            log.WithError(err).Warn("Get Etag option value failed.")
            return
        }
        itemKey := strconv.Itoa(etag)
        if isObserveOne {
            itemKey = itemKey + mid
        }
        response := Pdu{}
        res, isFound := caches.Get(itemKey)
        if !isFound {
            SetBlockOptionFirstRequest(request)
            handler(context, resource, session, request, token, queryString, &response)
        } else {
            response = res.(Pdu)
            response.MessageID = request.MessageID
            response.Token = request.Token
        }
        if is_observe && response.Type != TypeNon {
            response.SetOption(OptionObserve, rsrc.observe)
        }
        response.fillC(resp)
        if request.Code == RequestGet && response.Code == ResponseContent && response.Type == TypeNon {
            maxAge, err := response.GetOptionIntegerValue(OptionMaxage)
            if err != nil || maxAge < 0 {
                maxAge = 0
            }
            response.RemoveOption(OptionMaxage)
            coapToken := &C.coap_binary_t{}
            coapToken.s = req.token
            coapToken.length = C.size_t(len(string(*token)))
            if is_observe {
                req = nil
            }
            C.coap_add_data_blocked_response(resource.ptr, session.ptr, req, resp, coapToken, C.COAP_MEDIATYPE_APPLICATION_CBOR, C.int(maxAge),
                                            C.size_t(len(response.Data)), (*C.uint8_t)(unsafe.Pointer(&response.Data[0])))
            resPdu,_ := resp.toGo()
            HandleCache(resPdu, response, resource, context, isObserveOne, mid)
        }
    }
}