/*
// Copyright (c) 2016 Intel Corporation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
*/

#include <stdbool.h>
#include <stddef.h>
#include <strings.h>

#include "os/mynewt.h"

#include "oic/port/mynewt/config.h"

#include "oic/messaging/coap/constants.h"
#include "messaging/coap/engine.h"
#include "oic/messaging/coap/oc_coap.h"

#include "oic/port/oc_random.h"
#include "port/oc_clock.h"
#include "port/mynewt/adaptor.h"

#include "oic/oc_buffer.h"
#include "oic/oc_core_res.h"
#include "oic/oc_discovery.h"
#include "oic/oc_ri.h"
#include "oic/oc_uuid.h"
#include "oic/oc_ri_const.h"
#include "api/oc_priv.h"

#ifdef OC_SECURITY
#include "security/oc_acl.h"
#include "security/oc_dtls.h"
#endif /* OC_SECURITY */

#ifdef OC_SERVER
static SLIST_HEAD(, oc_resource) oc_app_resources =
    SLIST_HEAD_INITIALIZER(&oc_app_resources);
static struct os_mempool oc_resource_pool;
static uint8_t oc_resource_area[OS_MEMPOOL_BYTES(MAX_APP_RESOURCES,
      sizeof(oc_resource_t))];

static void periodic_observe_handler(struct os_event *ev);
#endif /* OC_SERVER */

#ifdef OC_CLIENT
#include "oc_client_state.h"
static SLIST_HEAD(, oc_client_cb) oc_client_cbs;
static struct os_mempool oc_client_cb_pool;
static uint8_t oc_client_cb_area[OS_MEMPOOL_BYTES(MAX_NUM_CONCURRENT_REQUESTS,
      sizeof(oc_client_cb_t))];
#endif /* OC_CLIENT */

// TODO: Define and use a  complete set of error codes.
int oc_stack_errno;

static const unsigned int oc_coap_status_codes[__NUM_OC_STATUS_CODES__] = {
    /* OK_200 */
    [OC_STATUS_OK] = CONTENT_2_05,
    /* CREATED_201 */
    [OC_STATUS_CREATED] = CREATED_2_01,
    /* NO_CONTENT_204 */
    [OC_STATUS_CHANGED] = CHANGED_2_04,
    /* NO_CONTENT_204 */
    [OC_STATUS_DELETED] = DELETED_2_02,
    /* NOT_MODIFIED_304 */
    [OC_STATUS_NOT_MODIFIED] = VALID_2_03,
    /* BAD_REQUEST_400 */
    [OC_STATUS_BAD_REQUEST] = BAD_REQUEST_4_00,
    /* UNAUTHORIZED_401 */
    [OC_STATUS_UNAUTHORIZED] = UNAUTHORIZED_4_01,
    /* BAD_REQUEST_400 */
    [OC_STATUS_BAD_OPTION] = BAD_OPTION_4_02,
    /* FORBIDDEN_403 */
    [OC_STATUS_FORBIDDEN] = FORBIDDEN_4_03,
    /* NOT_FOUND_404 */
    [OC_STATUS_NOT_FOUND] = NOT_FOUND_4_04,
    /* METHOD_NOT_ALLOWED_405 */
    [OC_STATUS_METHOD_NOT_ALLOWED] = METHOD_NOT_ALLOWED_4_05,
    /* NOT_ACCEPTABLE_406 */
    [OC_STATUS_NOT_ACCEPTABLE] = NOT_ACCEPTABLE_4_06,
    /* REQUEST_ENTITY_TOO_LARGE_413 */
    [OC_STATUS_REQUEST_ENTITY_TOO_LARGE] = REQUEST_ENTITY_TOO_LARGE_4_13,
    /* UNSUPPORTED_MEDIA_TYPE_415 */
    [OC_STATUS_UNSUPPORTED_MEDIA_TYPE] = UNSUPPORTED_MEDIA_TYPE_4_15,
    /* INTERNAL_SERVER_ERROR_500 */
    [OC_STATUS_INTERNAL_SERVER_ERROR] = INTERNAL_SERVER_ERROR_5_00,
    /* NOT_IMPLEMENTED_501 */
    [OC_STATUS_NOT_IMPLEMENTED] = NOT_IMPLEMENTED_5_01,
    /* BAD_GATEWAY_502 */
    [OC_STATUS_BAD_GATEWAY] = BAD_GATEWAY_5_02,
    /* SERVICE_UNAVAILABLE_503 */
    [OC_STATUS_SERVICE_UNAVAILABLE] = SERVICE_UNAVAILABLE_5_03,
    /* GATEWAY_TIMEOUT_504 */
    [OC_STATUS_GATEWAY_TIMEOUT] = GATEWAY_TIMEOUT_5_04,
    /* INTERNAL_SERVER_ERROR_500 */
    [OC_STATUS_PROXYING_NOT_SUPPORTED] = PROXYING_NOT_SUPPORTED_5_05
};

#ifdef OC_SERVER
oc_resource_t *
oc_ri_get_app_resources(void)
{
    return SLIST_FIRST(&oc_app_resources);
}
#endif

int
oc_status_code(oc_status_t key)
{
  return oc_coap_status_codes[key];
}

int
oc_ri_get_query_nth_key_value(const char *query, int query_len, char **key,
                              int *key_len, char **value, int *value_len, int n)
{
  int next_pos = -1;
  int i = 0;
  char *start = (char *)query, *current, *end = (char *)query + query_len;
  current = start;

  while (i < (n - 1) && current != NULL) {
    current = memchr(start, '&', end - start);
    i++;
    start = current + 1;
  }

  current = memchr(start, '=', end - start);
  if (current != NULL) {
    *key_len = current - start;
    *key = start;
    *value = current + 1;
    current = memchr(*value, '&', end - *value);
    if (current == NULL) {
      *value_len = end - *value;
    } else {
      *value_len = current - *value;
    }
    next_pos = *value + *value_len - query + 1;
  }
  return next_pos;
}

int
oc_ri_get_query_value(const char *query, int query_len, const char *key,
                      char **value)
{
  int next_pos = 0, found = -1, kl, vl;
  char *k;
  while (next_pos < query_len) {
    next_pos += oc_ri_get_query_nth_key_value(
      query + next_pos, query_len - next_pos, &k, &kl, value, &vl, 1);
    if (next_pos == -1)
      return -1;

    if (kl == strlen(key) && strncasecmp(key, k, kl) == 0) {
      found = vl;
      break;
    }
  }
  return found;
}

static void
start_processes(void)
{
  coap_engine_init();

#ifdef OC_SECURITY
  oc_process_start(&oc_dtls_handler, NULL);
#endif
}

static void
stop_processes(void)
{
#ifdef OC_SECURITY
  oc_process_exit(&oc_dtls_handler);
#endif
}

#ifdef OC_SERVER
oc_resource_t *
oc_ri_get_app_resource_by_uri(const char *uri)
{
    oc_resource_t *res;

    SLIST_FOREACH(res, &oc_app_resources, next) {
        if (oc_string_len(res->uri) == strlen(uri) &&
          strncmp(uri, oc_string(res->uri), strlen(uri)) == 0)
            return res;
    }

    return NULL;
}
#endif

void
oc_ri_mem_init(void)
{
#ifdef OC_SERVER
  os_mempool_init(&oc_resource_pool, MAX_APP_RESOURCES, sizeof(oc_resource_t),
                  oc_resource_area, "oc_res");
#endif
#ifdef OC_CLIENT
    os_mempool_init(&oc_client_cb_pool, MAX_NUM_CONCURRENT_REQUESTS,
      sizeof(oc_client_cb_t), oc_client_cb_area, "oc_cl_cbs");
    oc_rep_init();
#endif
    oc_buffer_init();
}

void
oc_ri_init(void)
{
#ifdef OC_CLIENT
    SLIST_INIT(&oc_client_cbs);
#endif

    start_processes();
    oc_create_discovery_resource();
}

void
oc_ri_shutdown(void)
{
  oc_random_destroy();
  stop_processes();
}

#ifdef OC_SERVER
oc_resource_t *
oc_ri_alloc_resource(void)
{
    struct oc_resource *resource;

    resource = os_memblock_get(&oc_resource_pool);
    if (resource) {
        os_callout_init(&resource->callout, oc_evq_get(),
          periodic_observe_handler, resource);
    }
    return resource;
}

void
oc_ri_delete_resource(oc_resource_t *resource)
{
    oc_resource_t *tmp;

    SLIST_FOREACH(tmp, &oc_app_resources, next) {
        if (tmp == resource) {
            SLIST_REMOVE(&oc_app_resources, tmp, oc_resource, next);
            break;
        }
    }
    os_memblock_put(&oc_resource_pool, resource);
}

bool
oc_ri_add_resource(oc_resource_t *resource)
{
    bool valid = true;

    if (!resource->get_handler && !resource->put_handler &&
      !resource->post_handler && !resource->delete_handler) {
        valid = false;
    }
    if (resource->properties & OC_PERIODIC &&
      resource->observe_period_mseconds == 0) {
        valid = false;
    }
    if (valid) {
        SLIST_INSERT_HEAD(&oc_app_resources, resource, next);
    }

    return valid;
}
#endif /* OC_SERVER */

#ifdef OC_SERVER

static void
periodic_observe_handler(struct os_event *ev)
{
    struct oc_resource *resource;

    resource = ev->ev_arg;

    if (coap_notify_observers(resource, NULL, NULL)) {
        os_callout_reset(&resource->callout,
          (resource->observe_period_mseconds * OS_TICKS_PER_SEC)/1000);
    }
}

#endif

oc_interface_mask_t
oc_ri_get_interface_mask(char *iface, int if_len)
{
  oc_interface_mask_t interface = 0;
  if (OC_BASELINE_IF_LEN == if_len &&
      strncmp(iface, OC_RSRVD_IF_BASELINE, if_len) == 0)
    interface |= OC_IF_BASELINE;
  if (OC_LL_IF_LEN == if_len && strncmp(iface, OC_RSRVD_IF_LL, if_len) == 0)
    interface |= OC_IF_LL;
  if (OC_B_IF_LEN == if_len && strncmp(iface, OC_RSRVD_IF_B, if_len) == 0)
    interface |= OC_IF_B;
  if (OC_R_IF_LEN == if_len && strncmp(iface, OC_RSRVD_IF_R, if_len) == 0)
    interface |= OC_IF_R;
  if (OC_RW_IF_LEN == if_len && strncmp(iface, OC_RSRVD_IF_RW, if_len) == 0)
    interface |= OC_IF_RW;
  if (OC_A_IF_LEN == if_len && strncmp(iface, OC_RSRVD_IF_A, if_len) == 0)
    interface |= OC_IF_A;
  if (OC_S_IF_LEN == if_len && strncmp(iface, OC_RSRVD_IF_S, if_len) == 0)
    interface |= OC_IF_S;
  return interface;
}

static bool
does_interface_support_method(oc_resource_t *resource,
                              oc_interface_mask_t interface, oc_method_t method)
{
  bool supported = true;
  switch (interface) {
  /* Per section 7.5.3 of the OCF Core spec, the following three interfaces
   * are RETRIEVE-only.
   */
  case OC_IF_LL:
  case OC_IF_S:
  case OC_IF_R:
    if (method != OC_GET)
      supported = false;
    break;
  /* Per section 7.5.3 of the OCF Core spec, the following three interfaces
   * support RETRIEVE, UPDATE.
   * TODO: Refine logic below after adding logic that identifies
   * and handles CREATE requests using PUT/POST.
   */
  case OC_IF_RW:
  case OC_IF_B:
  case OC_IF_BASELINE:
  /* Per section 7.5.3 of the OCF Core spec, the following interface
   * supports CREATE, RETRIEVE and UPDATE.
   */
  case OC_IF_A:
    break;
  }
  return supported;
}

/**
 * Determines if the endpoint meets the specified resource's minimum transport
 * layer security requirements.
 *
 * @param oe                    The endpoint to check.
 * @param res                   The resource being accessed.
 *
 * @return                      true if the endpoint has sufficient security;
 *                              false if the security requirements are not met.
 */
static bool
oc_ri_check_trans_security(const oc_endpoint_t *oe,
                           const oc_resource_t *res)
{
#if MYNEWT_VAL(OC_TRANS_SECURITY)
  oc_resource_properties_t res_sec_flags;

  res_sec_flags = res->properties & OC_TRANS_SEC_MASK;
  if (res_sec_flags == 0) {
    return true;
  }

  if ((oc_get_trans_security(oe) ^ res_sec_flags) != 0) {
    return false;
  }
#endif

  return true;
}

bool
oc_ri_invoke_coap_entity_handler(struct coap_packet_rx *request,
                                 coap_packet_t *response, int32_t *offset,
                                 oc_endpoint_t *endpoint)
{
  /* Flags that capture status along various stages of processing
   *  the request.
   */
  bool method_impl = true, bad_request = false, success = true;
  bool authorized = true;

  /* This function is a server-side entry point solely for requests.
   *  Hence, "code" contains the CoAP method code.
   */
  oc_method_t method = request->code;

  /* Initialize request/response objects to be sent up to the app layer. */
  oc_request_t request_obj;
  oc_response_buffer_t response_buffer;
  oc_response_t response_obj;
  struct os_mbuf *m = NULL;

  response_buffer.buffer = NULL;
  response_buffer.block_offset = offset;
  response_buffer.code = 0;
  response_buffer.response_length = 0;

  response_obj.separate_response = 0;
  response_obj.response_buffer = &response_buffer;

  request_obj.response = &response_obj;
  request_obj.query_len = 0;
  request_obj.resource = 0;
  request_obj.origin = endpoint;
  request_obj.packet = request;

  /* Initialize OCF interface selector. */
  oc_interface_mask_t interface = 0;

  /* Obtain request uri from the CoAP packet. */
  char uri_path[COAP_MAX_URI];
  int uri_path_len = coap_get_header_uri_path(request, uri_path,
                                              sizeof(uri_path));

  /* Obtain query string from CoAP packet. */
  char uri_query[COAP_MAX_URI_QUERY];
  int uri_query_len = coap_get_header_uri_query(request, uri_query,
                                                sizeof(uri_query));

  if (uri_query_len) {
    request_obj.query = uri_query;
    request_obj.query_len = uri_query_len;

    /* Check if query string includes interface selection. */
    char *iface;
    int if_len = oc_ri_get_query_value(uri_query, uri_query_len, "if", &iface);
    if (if_len != -1) {
      interface |= oc_ri_get_interface_mask(iface, if_len);
    }
  }

  oc_resource_t *resource, *cur_resource = NULL;

  /* If there were no errors thus far, attempt to locate the specific
   * resource object that will handle the request using the request uri.
   */
  /* Check against list of declared core resources.
   */
  if (!bad_request) {
    int i;
    for (i = 0; i < NUM_OC_CORE_RESOURCES; i++) {
      resource = oc_core_get_resource_by_index(i);
      if (oc_string_len(resource->uri) == (uri_path_len + 1) &&
          strncmp((const char *)oc_string(resource->uri) + 1, uri_path,
                  uri_path_len) == 0) {
        request_obj.resource = cur_resource = resource;
        break;
      }
    }
  }

#ifdef OC_SERVER
  /* Check against list of declared application resources.
   */
  if (!cur_resource && !bad_request) {
      SLIST_FOREACH(resource, &oc_app_resources, next) {
          if (oc_string_len(resource->uri) == (uri_path_len + 1) &&
            strncmp((const char *)oc_string(resource->uri) + 1, uri_path,
              uri_path_len) == 0) {
              request_obj.resource = cur_resource = resource;
              break;
          }
      }
  }
#endif

  if (cur_resource) {
    /* If there was no interface selection, pick the "default interface". */
    if (interface == 0)
      interface = cur_resource->default_interface;

    /* Found the matching resource object. Now verify that:
     * 1) the selected interface is one that is supported by
     *    the resource, and,
     * 2) the selected interface supports the request method.
     *
     * If not, return a 4.00 response.
     */
    if (((interface & ~cur_resource->interfaces) != 0) ||
        !does_interface_support_method(cur_resource, interface, method))
      bad_request = true;
  }

  m = os_msys_get_pkthdr(0, 0);
  if (!m) {
      bad_request = true;
  }
  response_buffer.buffer = m;

  if (cur_resource && !bad_request) {
    /* Process a request against a valid resource, request payload, and
     * interface.
     */

    /* Initialize oc_rep with a buffer to hold the response payload. "buffer"
     * points to memory allocated in the messaging layer for the "CoAP
     * Transaction" to service this request.
     */
    oc_rep_new(m);

#ifdef OC_SECURITY
    /* If cur_resource is a coaps:// resource, then query ACL to check if
     * the requestor (the subject) is authorized to issue this request to
     * the resource.
     */
    if ((cur_resource->properties & OC_SECURE) &&
        !oc_sec_check_acl(method, cur_resource, endpoint)) {
      authorized = false;
    } else
#endif
    if (!oc_ri_check_trans_security(endpoint, cur_resource)) {
      authorized = false;
    } else {
      /* Invoke a specific request handler for the resource
             * based on the request method. If the resource has not
             * implemented that method, then return a 4.05 response.
             */
      if (method == OC_GET && cur_resource->get_handler) {
        cur_resource->get_handler(&request_obj, interface);
      } else if (method == OC_POST && cur_resource->post_handler) {
        cur_resource->post_handler(&request_obj, interface);
      } else if (method == OC_PUT && cur_resource->put_handler) {
        cur_resource->put_handler(&request_obj, interface);
      } else if (method == OC_DELETE && cur_resource->delete_handler) {
        cur_resource->delete_handler(&request_obj, interface);
      } else {
        method_impl = false;
      }
    }
  }

  if (bad_request) {
    if (!m) {
        OC_LOG(ERROR, "ocri: No bufs\n");
        response_buffer.code = oc_status_code(OC_STATUS_SERVICE_UNAVAILABLE);
    } else {
        OC_LOG(ERROR, "ocri: Bad request\n");
        /* Return a 4.00 response */
        response_buffer.code = oc_status_code(OC_STATUS_BAD_REQUEST);
    }
    success = false;
  } else if (!cur_resource) {
    OC_LOG(ERROR, "ocri: Could not find resource\n");
    /* Return a 4.04 response if the requested resource was not found */
    response_buffer.response_length = 0;
    response_buffer.code = oc_status_code(OC_STATUS_NOT_FOUND);
    success = false;
  } else if (!method_impl) {
    OC_LOG(ERROR, "ocri: Could not find method\n");
    /* Return a 4.05 response if the resource does not implement the
     * request method.
     */
    response_buffer.response_length = 0;
    response_buffer.code = oc_status_code(OC_STATUS_METHOD_NOT_ALLOWED);
    success = false;
  }
  else if (!authorized) {
    OC_LOG(ERROR, "ocri: Subject not authorized\n");
    /* If the requestor (subject) does not have access granted via an
     * access control entry in the ACL, then it is not authorized to
     * access the resource. A 4.03 response is sent.
     */
    response_buffer.response_length = 0;
    response_buffer.code = oc_status_code(OC_STATUS_FORBIDDEN);
    success = false;
  }

#ifdef OC_SERVER
  /* If a GET request was successfully processed, then check its
   *  observe option.
   */
  uint32_t observe = 2;
  if (success && coap_get_header_observe(request, &observe)) {
    /* Check if the resource is OBSERVABLE */
    if (cur_resource->properties & OC_OBSERVABLE) {
      /* If the observe option is set to 0, make an attempt to add the
       * requesting client as an observer.
       */
      if (observe == 0) {
        if (coap_observe_handler(request, response, cur_resource, endpoint) ==
            0) {
          /* If the resource is marked as periodic observable it means
           * it must be polled internally for updates (which would lead to
           * notifications being sent). If so, add the resource to a list of
           * periodic GET callbacks to utilize the framework's internal
           * polling mechanism.
           */
          bool set_observe_option = true;
          if (cur_resource->properties & OC_PERIODIC) {
              os_callout_reset(&cur_resource->callout,
                (cur_resource->observe_period_mseconds * OS_TICKS_PER_SEC)/1000);
          }

          if (set_observe_option) {
            coap_set_header_observe(response, 0);
          }
        }
      }
      /* If the observe option is set to 1, make an attempt to remove
       * the requesting client from the list of observers. In addition,
       * remove the resource from the list periodic GET callbacks if it
       * is periodic observable.
       */
      else if (observe == 1) {
        if (coap_observe_handler(request, response, cur_resource, endpoint) >
            0) {
          if (cur_resource->properties & OC_PERIODIC) {
              os_callout_stop(&cur_resource->callout);
          }
        }
      }
    }
  }
#endif

#if defined(OC_SERVER) && MYNEWT_VAL(OC_SEPARATE_RESPONSES)
  /* The presence of a separate response handle here indicates a
   * successful handling of the request by a slow resource.
   */
  if (response_obj.separate_response != NULL) {
    /* Attempt to register a client request to the separate response tracker
     * and pass in the observe option (if present) or the value 2 as
     * determined by the code block above. Values 0 and 1 result in their
     * expected behaviors whereas 2 indicates an absence of an observe
     * option and hence a one-off request.
     * Following a successful registration, the separate response tracker
     * is flagged as "active". In this way, the function that later executes
     * out-of-band upon availability of the resource state knows it must
     * send out a response with it.
     */
    if (coap_separate_accept(request, response_obj.separate_response, endpoint,
                             observe) == 1)
      response_obj.separate_response->active = 1;
  } else
#endif /* OC_SERVER && OC_SEPARATE_RESPONSES */
    if (response_buffer.code == OC_IGNORE) {
    /* If the server-side logic chooses to reject a request, it sends
     * below a response code of IGNORE, which results in the messaging
     * layer freeing the CoAP transaction associated with the request.
     */
    erbium_status_code = CLEAR_TRANSACTION;
  } else {
#ifdef OC_SERVER
    /* If the recently handled request was a PUT/POST, it conceivably
     * altered the resource state, so attempt to notify all observers
     * of that resource with the change.
     */
    if ((method == OC_PUT || method == OC_POST) &&
        response_buffer.code < oc_status_code(OC_STATUS_BAD_REQUEST)) {
        coap_notify_observers(cur_resource, NULL, NULL);
    }
#endif
    if (response_buffer.response_length) {
        response->payload_m = response_buffer.buffer;
        response->payload_len = OS_MBUF_PKTLEN(response_buffer.buffer);
        response_buffer.buffer = NULL; /* freed in coap_serialize_message() */
        coap_set_header_content_format(response, APPLICATION_CBOR);
    }
    /* response_buffer.code at this point contains a valid CoAP status
     *  code.
     */
    coap_set_status_code(response, response_buffer.code);
  }
  if (response_buffer.buffer) {
      os_mbuf_free_chain(response_buffer.buffer);
  }
  return success;
}

#ifdef OC_CLIENT
static void
free_client_cb(oc_client_cb_t *cb)
{
    os_callout_stop(&cb->callout);
    oc_free_string(&cb->uri);
    SLIST_REMOVE(&oc_client_cbs, cb, oc_client_cb, next);
    os_memblock_put(&oc_client_cb_pool, cb);
}

void
oc_ri_remove_client_cb_by_mid(uint16_t mid)
{
    oc_client_cb_t *cb;

    SLIST_FOREACH(cb, &oc_client_cbs, next) {
        if (cb->mid == mid) {
            break;
        }
    }
    if (cb) {
        free_client_cb(cb);
    }
}

bool
oc_ri_send_rst(oc_endpoint_t *endpoint, uint8_t *token, uint8_t token_len,
               uint16_t mid)
{
    coap_packet_t rst[1];
    struct os_mbuf *m;

    coap_init_message(rst, COAP_TYPE_RST, 0, mid);
    coap_set_header_observe(rst, 1);
    coap_set_token(rst, token, token_len);
    m = oc_allocate_mbuf(endpoint);
    if (m) {
        if (!coap_serialize_message(rst, m)) {
            coap_send_message(m, 0);
        } else {
            os_mbuf_free_chain(m);
        }
        return true;
    }
    return false;
}

bool
oc_ri_invoke_client_cb(struct coap_packet_rx *rsp, oc_endpoint_t *endpoint)
{
    oc_client_cb_t *cb, *tmp;
    oc_client_response_t client_response;
    unsigned int content_format = APPLICATION_CBOR;
    oc_response_handler_t handler;
    int i;

    /*
      if con then send ack and process as above
      -empty ack sent from below by engine
      if ack with piggyback then process as above
      -processed below
      if ack and empty then it is a separate response, and keep cb
      -handled by separate flag
      if ack is for block then store data and pass to client
    */
    coap_get_header_content_format(rsp, &content_format);

    cb = SLIST_FIRST(&oc_client_cbs);
    while (cb != NULL) {
        tmp = SLIST_NEXT(cb, next);
        if (cb->token_len != rsp->token_len ||
            memcmp(cb->token, rsp->token, rsp->token_len)) {
            cb = tmp;
            continue;
        }

        /* If content format is not CBOR, then reject response
           and clear callback
           If incoming response type is RST, then clear callback
        */
        if (content_format != APPLICATION_CBOR || rsp->type == COAP_TYPE_RST) {
            free_client_cb(cb);
            break;
        }

        /* Check code, translate to oc_status_code, store
           Check observe option:
           if no observe option, set to -1, else store observe seq
        */
        client_response.packet = NULL;
        client_response.observe_option = -1;

        for (i = 0; i < __NUM_OC_STATUS_CODES__; i++) {
            if (oc_coap_status_codes[i] == rsp->code) {
                client_response.code = i;
                break;
            }
        }
        coap_get_header_observe(rsp, &client_response.observe_option);

        bool separate = false;
        /*
          if payload exists, process payload and save in client response
          send client response to callback and return
        */
        if (rsp->payload_len) {
            if (cb->discovery) {
#if MYNEWT_VAL(OC_CLIENT_DISCOVERY_ENABLE)
                if (oc_ri_process_discovery_payload(rsp, cb->handler,
                                              endpoint) == OC_STOP_DISCOVERY) {
                    free_client_cb(cb);
                    return true;
                }
#else
                /* XXX should never be here */
                free_client_cb(cb);
                return true;
#endif
            } else {
                client_response.packet = rsp;
                client_response.origin = endpoint;
                handler = (oc_response_handler_t)cb->handler;
                handler(&client_response);
            }
        } else { // no payload
            if (rsp->type == COAP_TYPE_ACK && rsp->code == 0) {
                separate = true;
            } else if (!cb->discovery) {
                handler = (oc_response_handler_t)cb->handler;
                handler(&client_response);
            }
        }

        /* check observe sequence number:
           if -1 then remove cb, else keep cb
           if it is an ACK for a separate response, keep cb
           if it is a discovery response, keep cb so that it will last
           for the entirety of OC_CLIENT_CB_TIMEOUT_SECS
        */
        if (client_response.observe_option == -1 && !separate &&
            !cb->discovery) {
            free_client_cb(cb);
        } else {
            cb->observe_seq = client_response.observe_option;
        }
        break;
    }

    return true;
}

oc_client_cb_t *
oc_ri_get_client_cb(const char *uri, oc_server_handle_t *server,
                    oc_method_t method)
{
    oc_client_cb_t *cb;

    SLIST_FOREACH(cb, &oc_client_cbs, next) {
        if (oc_string_len(cb->uri) == strlen(uri) &&
          strncmp(oc_string(cb->uri), uri, strlen(uri)) == 0 &&
          memcmp(&cb->server.endpoint, &server->endpoint,
                 oc_endpoint_size(&cb->server.endpoint)) == 0 &&
          cb->method == method) {
            return cb;
        }
    }

    return NULL;
}

static void
oc_ri_remove_cb(struct os_event *ev)
{
    struct oc_client_cb *cb;

    cb = ev->ev_arg;

    free_client_cb(cb);
}

oc_client_cb_t *
oc_ri_alloc_client_cb(const char *uri, oc_server_handle_t *server,
                      oc_method_t method, void *handler, oc_qos_t qos)
{
    oc_client_cb_t *cb;

    cb = os_memblock_get(&oc_client_cb_pool);
    if (!cb) {
        return NULL;
    }
    cb->mid = coap_get_mid();
    oc_new_string(&cb->uri, uri);
    cb->method = method;
    cb->qos = qos;
    cb->handler = handler;
    cb->token_len = 8;
    int i = 0;
    uint16_t r;
    while (i < cb->token_len) {
        r = oc_random_rand();
        memcpy(cb->token + i, &r, sizeof(r));
        i += sizeof(r);
    }
    cb->discovery = false;
    cb->timestamp = oc_clock_time();
    cb->observe_seq = -1;
    memcpy(&cb->server, server, sizeof(oc_server_handle_t));

    os_callout_init(&cb->callout, oc_evq_get(), oc_ri_remove_cb, cb);

    SLIST_INSERT_HEAD(&oc_client_cbs, cb, next);
    return cb;
}
#endif /* OC_CLIENT */

// TODO:
// resource collections
// if method accepted by interface selection
// resources for presence based discovery
