void coap_handle_notification(NetworkAddress * sourceAddress, coap_packet_t * message)
{
    if (message->token_len == sizeof(int))
    {
        int token;
        memcpy(&token, message->token, sizeof(int));
        Observation * observation = NULL;
        int index;
        for (index = 0; index < MAX_COAP_OBSERVATIONS; index++)
        {
            if ((Observations[index].Token == token) && (NetworkAddress_Compare(Observations[index].Address, sourceAddress) == 0))
            {
                observation = &Observations[index];
                break;
            }
        }
        if (observation && observation->Callback)
        {
            AddressType address;
            int ContentType = 0;
            char * payload = NULL;

            NetworkAddress_SetAddressType(sourceAddress, &address);
            coap_get_header_content_format(message, &ContentType);
            int payloadLen = coap_get_payload(message, (const uint8_t **) &payload);

            observation->Callback(observation->Context, &address, observation->Path, COAP_OPTION_TO_RESPONSE_CODE(message->code),
                    ContentType, payload, payloadLen);
        }
    }

}
void coap_CoapRequestCallback(void *callback_data, void *response)
{
    TransactionType * transaction = (TransactionType *)callback_data;
    coap_packet_t * coap_response = (coap_packet_t *)response;
    int ContentType = 0;
    const char *url = NULL;
    char * payload = NULL;
    char uriBuf[64] = {0};

    if(callback_data != NULL)
    {
        if(response != NULL)
        {
            int urlLen = 0;
            if ((urlLen = coap_get_header_location_path(response, &url)))
            {
                uriBuf[0] = '/';
                memcpy(&uriBuf[1], url, urlLen);
            }

            coap_get_header_content_format(response, &ContentType);
            int payloadLen = coap_get_payload(response, (const uint8_t **)&payload);

            transaction->Callback(transaction->Context, &transaction->Address, uriBuf, COAP_OPTION_TO_RESPONSE_CODE(coap_response->code), ContentType, payload, payloadLen);
        }
        else
        {
            transaction->Callback(transaction->Context, NULL, NULL, 0, 0, NULL, 0);
        }

        transaction->TransactionUsed = false;
    }
}
static int coap_HandleRequest(void *packet, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
{
    int result = 1;
    const char *url = NULL;
    int urlLen = 0;
    const uint8_t * payload = NULL;
    int payloadLen = 0;
    int content = -1;

    coap_packet_t * const request = (coap_packet_t *) packet;

    CoapResponse coapResponse =
    { .responseContent = buffer, .responseContentLen = preferred_size, .responseCode = 400, };

    payloadLen = coap_get_payload(request, &payload);

    if ((urlLen = coap_get_header_uri_path(request, &url)))
    {
        char uriBuf[MAX_COAP_PATH] = { 0 };
        rest_resource_flags_t method = (rest_resource_flags_t) (1 << (((coap_packet_t *) packet)->code - 1)); //coap_get_rest_method(request);

        uriBuf[0] = '/';
        memcpy(&uriBuf[1], url, urlLen);

        char queryBuf[128] = "?";
        const char * query = NULL;

        int queryLength = coap_get_header_uri_query(request, &query);
        if (queryLength > 0)
            memcpy(&queryBuf[1], query, queryLength);

        queryBuf[queryLength+1] = '\0';

        CoapRequest coapRequest =
        { .ctxt = context, .addr =
        { 0 }, .path = uriBuf, .query = queryBuf, .token = request->token, .tokenLength = request->token_len, .requestContent = payload,
                .requestContentLen = payloadLen, };

        NetworkAddress_SetAddressType(sourceAddress, &coapRequest.addr);

        switch (method)
        {
        case METHOD_GET:

            coap_get_header_accept(request, &content);
            coapRequest.contentType = content;

            int32_t observe;

            if (!coap_get_header_observe(request, &observe))
                observe = -1;

            switch (observe)
            {
            case -1:
                Lwm2m_Debug("Coap GET for %s\n", uriBuf);
                coapRequest.type = COAP_GET_REQUEST;
                requestHandler(&coapRequest, &coapResponse);
                break;
            case 0:
                Lwm2m_Debug("Coap OBSERVE for %s\n", uriBuf);

                coapRequest.type = COAP_OBSERVE_REQUEST;
                requestHandler(&coapRequest, &coapResponse);
                coap_set_header_observe(response, 1);
                break;
            case 1:
                Lwm2m_Debug("Coap CANCEL OBSERVE for %s\n", uriBuf);

                coapRequest.type = COAP_CANCEL_OBSERVE_REQUEST;
                requestHandler(&coapRequest, &coapResponse);
                break;
            default:
                break;
            }
            coap_set_header_content_format(response, coapResponse.responseContentType); /* text/plain is the default, hence this option could be omitted. */
            break;

        case METHOD_POST:
            coap_get_header_content_format(request, &content);
            coapRequest.contentType = content;
            coapRequest.type = COAP_POST_REQUEST;
            Lwm2m_Debug("Coap POST for %s\n", uriBuf);
            requestHandler(&coapRequest, &coapResponse);
            if (coapResponse.responseContentLen > 0 && coapResponse.responseCode == 201)
            {
                coap_set_header_location_path(response, coapResponse.responseContent);
            }
            break;

        case METHOD_PUT:
            coap_get_header_content_format(request, &content);
            coapRequest.contentType = content;
            coapRequest.type = COAP_PUT_REQUEST;

            Lwm2m_Debug("Coap PUT for %s\n", uriBuf);
            requestHandler(&coapRequest, &coapResponse);
            break;

        case METHOD_DELETE:
            coapRequest.contentType = ContentType_None;
            coapRequest.type = COAP_DELETE_REQUEST;

            Lwm2m_Debug("Coap DELETE for %s\n", uriBuf);
            requestHandler(&coapRequest, &coapResponse);
            break;

        default:
            break;
        }

        if (coapResponse.responseContentLen > 0 && coapResponse.responseCode == 205)
        {
            coap_set_payload(response, coapResponse.responseContent, coapResponse.responseContentLen);
        }
    }

    coap_set_status_code(response, COAP_RESPONSE_CODE(coapResponse.responseCode));
    return result;
}