void CAParseURI(const char* uriInfo, coap_list_t **optlist)
{
    OIC_LOG(DEBUG, TAG, "parse URI");

    unsigned char portbuf[2];
    unsigned char _buf[CA_BUFSIZE];
    unsigned char *buf = _buf;
    coap_uri_t uri;
    size_t buflen;
    uint32_t res;

    OIC_LOG_V(DEBUG, TAG, "url : %s", uriInfo);

    /* split arg into Uri-* options */
    coap_split_uri((unsigned char *) uriInfo, strlen(uriInfo), &uri);

    if (uri.port != COAP_DEFAULT_PORT)
    {
        coap_insert(optlist,
                CACreateNewOptionNode(COAP_OPTION_URI_PORT,
                        coap_encode_var_bytes(portbuf, uri.port), portbuf), CAOrderOpts);
    }

    if (uri.path.length)
    {
        buflen = CA_BUFSIZE;
        res = coap_split_path(uri.path.s, uri.path.length, buf, &buflen);

        while (res--)
        {
            coap_insert(optlist,
                    CACreateNewOptionNode(COAP_OPTION_URI_PATH, COAP_OPT_LENGTH(buf),
                            COAP_OPT_VALUE(buf)), CAOrderOpts);
            buf += COAP_OPT_SIZE(buf);
        }
    }

    if (uri.query.length)
    {
        buflen = CA_BUFSIZE;
        buf = _buf;
        res = coap_split_query(uri.query.s, uri.query.length, buf, &buflen);

        while (res--)
        {
            coap_insert(optlist,
                    CACreateNewOptionNode(COAP_OPTION_URI_QUERY, COAP_OPT_LENGTH(buf),
                            COAP_OPT_VALUE(buf)), CAOrderOpts);

            buf += COAP_OPT_SIZE(buf);
        }
    }

}
Esempio n. 2
0
void CoAP_RD_Resource::response_ok(CoAPResource *node, CoAPCallback &callback)
{
#define LOCSIZE 68

    coap_pdu_t *response = (coap_pdu_t*)callback.response_;
    
    /* create response */
    response->hdr->code = COAP_RESPONSE_CODE(201);

    {
        /* split path into segments and add Location-Path options */
        unsigned char _b[LOCSIZE];
        unsigned char *b = _b;
        size_t buflen = sizeof(_b);
        int nseg;

        nseg = coap_split_path((unsigned char*)node->uri().c_str(), node->uri().length(), b, &buflen);
        while (nseg--)
        {
            coap_add_option(response, COAP_OPTION_LOCATION_PATH,
                            COAP_OPT_LENGTH(b), COAP_OPT_VALUE(b));
            b += COAP_OPT_SIZE(b);
        }
    }
    
}
Esempio n. 3
0
void hnd_get_async(coap_context_t  *ctx, struct coap_resource_t *resource, 
              coap_address_t *peer, coap_pdu_t *request, str *token,
              coap_pdu_t *response) {
    coap_opt_iterator_t opt_iter;
    coap_opt_t *option;
    unsigned long delay = 5;
    size_t size;

    if (async) {
        if (async->id != request->hdr->id) {
            coap_opt_filter_t f;
            coap_option_filter_clear(f);
            response->hdr->code = COAP_RESPONSE_CODE(503);
        }
        return;
    }

    option = coap_check_option(request, COAP_OPTION_URI_QUERY, &opt_iter);
    if (option) {
        unsigned char *p = COAP_OPT_VALUE(option);

        delay = 0;
        for (size = COAP_OPT_LENGTH(option); size; --size, ++p)
            delay = delay * 10 + (*p - '0');
    }

    async = coap_register_async(ctx, peer, request, 
                                COAP_ASYNC_SEPARATE | COAP_ASYNC_CONFIRM,
                                (void *)(COAP_TICKS_PER_SECOND * delay));
}
Esempio n. 4
0
rd_t *
make_rd(coap_address_t *peer, coap_pdu_t *pdu) {    
  rd_t *rd;
  unsigned char *data;
  coap_opt_iterator_t opt_iter;
  coap_opt_t *etag;

  rd = rd_new();
  
  if (!rd) {
    debug("hnd_get_rd: cannot allocate storage for rd\n");
    return NULL;
  }

  if (coap_get_data(pdu, &rd->data.length, &data)) {
    rd->data.s = (unsigned char *)coap_malloc(rd->data.length);
    if (!rd->data.s) {
      debug("hnd_get_rd: cannot allocate storage for rd->data\n");
      rd_delete(rd);
      return NULL;
    }
    memcpy(rd->data.s, data, rd->data.length);
  }

  etag = coap_check_option(pdu, COAP_OPTION_ETAG, &opt_iter);
  if (etag) {
    rd->etag_len = min(COAP_OPT_LENGTH(etag), sizeof(rd->etag));
    memcpy(rd->etag, COAP_OPT_VALUE(etag), rd->etag_len);
  }

  return rd;
}
Esempio n. 5
0
/* handler for TD_COAP_CORE_16 */
void 
hnd_get_separate(coap_context_t  *ctx, struct coap_resource_t *resource, 
		 coap_address_t *peer, coap_pdu_t *request, str *token,
		 coap_pdu_t *response) {
  coap_opt_iterator_t opt_iter;
  coap_opt_t *option;
  coap_opt_filter_t f;
  unsigned long delay = 5;

  (void)resource;
  (void)token;

  if (async) {
    if (async->id != request->hdr->id) {
      coap_opt_filter_t f;
      coap_option_filter_clear(f);
      response->hdr->code = COAP_RESPONSE_CODE(503);
    }
    return;
  }

  /* search for option delay in query list */
  coap_option_filter_clear(f);
  coap_option_setb(f, COAP_OPTION_URI_QUERY);
  
  coap_option_iterator_init(request, &opt_iter, f);
  
  while ((option = coap_option_next(&opt_iter))) {
    if (strncmp("delay=", (char *)COAP_OPT_VALUE(option), 6) == 0) {
      int i;
      unsigned long d = 0;
      
      for (i = 6; i < COAP_OPT_LENGTH(option); ++i)
	d = d * 10 + COAP_OPT_VALUE(option)[i] - '0';

      /* don't allow delay to be less than COAP_RESOURCE_CHECK_TIME*/
      delay = d < COAP_RESOURCE_CHECK_TIME_SEC 
	? COAP_RESOURCE_CHECK_TIME_SEC
	: d;
      debug("set delay to %lu\n", delay);
      break;
    }
  }

  async = coap_register_async(ctx, peer, request, COAP_ASYNC_SEPARATE,
			      (void *)(COAP_TICKS_PER_SECOND * delay));
}
CAResult_t CAParseUriPartial(const unsigned char *str, size_t length, int target,
                             coap_list_t **optlist)
{
    if (!optlist)
    {
        OIC_LOG(ERROR, TAG, "optlist is null");
        return CA_STATUS_INVALID_PARAM;
    }

    if ((target != COAP_OPTION_URI_PATH) && (target != COAP_OPTION_URI_QUERY))
    {
        // should never occur. Log just in case.
        OIC_LOG(DEBUG, TAG, "Unexpected URI component.");
        return CA_NOT_SUPPORTED;
    }
    else if (str && length)
    {
        unsigned char uriBuffer[CA_BUFSIZE] = { 0 };
        unsigned char *pBuf = uriBuffer;
        size_t buflen = sizeof(uriBuffer);
        int res = (target == COAP_OPTION_URI_PATH) ? coap_split_path(str, length, pBuf, &buflen) :
                  coap_split_query(str, length, pBuf, &buflen);

        if (res > 0)
        {
            size_t prevIdx = 0;
            while (res--)
            {
                int ret = coap_insert(optlist,
                                      CACreateNewOptionNode(target, COAP_OPT_LENGTH(pBuf),
                                              (char *)COAP_OPT_VALUE(pBuf)),
                                      CAOrderOpts);
                if (ret <= 0)
                {
                    return CA_STATUS_INVALID_PARAM;
                }

                size_t optSize = COAP_OPT_SIZE(pBuf);
                if ((prevIdx + optSize) < buflen)
                {
                    pBuf += optSize;
                    prevIdx += optSize;
                }
            }
        }
        else
        {
            OIC_LOG_V(ERROR, TAG, "Problem parsing URI : %d for %d", res, target);
            return CA_STATUS_FAILED;
        }
    }
    else
    {
        OIC_LOG(ERROR, TAG, "str or length is not available");
        return CA_STATUS_FAILED;
    }

    return CA_STATUS_OK;
}
Esempio n. 7
0
void 
hnd_put_test(coap_context_t  *ctx, struct coap_resource_t *resource, 
	      coap_address_t *peer, coap_pdu_t *request, str *token,
	      coap_pdu_t *response) {
  coap_opt_iterator_t opt_iter;
  coap_opt_t *option;
  coap_payload_t *payload;
  size_t len;
  unsigned char *data;

  (void)ctx;
  (void)peer;
  (void)token;

  response->hdr->code = COAP_RESPONSE_CODE(204);

  coap_get_data(request, &len, &data);

  payload = coap_find_payload(resource->key);
  if (payload && payload->max_data < len) { /* need more storage */
    coap_delete_payload(payload);
    payload = NULL;
    /* bug: when subsequent coap_new_payload() fails, our old contents
       is gone */
  }

  if (!payload) {		/* create new payload */
    payload = coap_new_payload(len);
    if (!payload)
      goto error;

    coap_add_payload(resource->key, payload, NULL);
  } 
  payload->length = len;
  memcpy(payload->data, data, len);

  option = coap_check_option(request, COAP_OPTION_CONTENT_TYPE, &opt_iter);
  if (option) {
    /* set media type given in request */
    payload->media_type = 
      coap_decode_var_bytes(COAP_OPT_VALUE(option), COAP_OPT_LENGTH(option));
  } else {
    /* set default value */
    payload->media_type = COAP_MEDIATYPE_TEXT_PLAIN;
  }
  /* FIXME: need to change attribute ct of resource. 
     To do so, we need dynamic management of the attribute value
  */

  return;
 error:
  warn("cannot modify resource\n");
  response->hdr->code = COAP_RESPONSE_CODE(500);
}
Esempio n. 8
0
File: net.c Progetto: Akihtrak/prod
void 
for_each_option(coap_pdu_t *pdu, 
		void (*f)(coap_opt_t *, unsigned char, unsigned int, const unsigned char *) ) {
  unsigned char cnt;
  coap_opt_t *opt;
  unsigned char opt_code = 0;
  
  if (! pdu )
    return;

  opt = options_start( pdu );
  for ( cnt = pdu->hdr->optcnt; cnt; --cnt ) {
    opt_code += COAP_OPT_DELTA(*opt);

    f ( opt, opt_code, COAP_OPT_LENGTH(*opt), COAP_OPT_VALUE(*opt) );
    opt = (coap_opt_t *)( (unsigned char *)opt + COAP_OPT_SIZE(*opt) );
  }
}
Esempio n. 9
0
static void query_value(coap_pdu_t *pdu, 
                            std::string &key, 
                            std::string &value)
{
    coap_opt_iterator_t opt_iter;
    coap_opt_t *query;
    str v = {0, NULL};

    query = coap_check_option(pdu, COAP_OPTION_URI_QUERY, &opt_iter);

    if (query) 
    {   
        parse_param((unsigned char *)key.c_str(), key.length(), 
		    COAP_OPT_VALUE(query), COAP_OPT_LENGTH(query), &v);
    }
    
    if (v.length > 0)
        value.assign((const char*)v.s, v.length);
}
Esempio n. 10
0
void 
hnd_get_query(coap_context_t  *ctx, struct coap_resource_t *resource, 
	      coap_address_t *peer, coap_pdu_t *request, str *token,
	      coap_pdu_t *response) {
  coap_opt_iterator_t opt_iter;
  coap_opt_filter_t f;
  coap_opt_t *q;
  size_t len, L;
  unsigned char buf[70];

  (void)ctx;
  (void)resource;
  (void)peer;
  (void)token;

  response->hdr->code = COAP_RESPONSE_CODE(205);

  coap_add_option(response, COAP_OPTION_CONTENT_TYPE,
	  coap_encode_var_bytes(buf, COAP_MEDIATYPE_TEXT_PLAIN), buf);

  coap_option_filter_clear(f);
  coap_option_setb(f, COAP_OPTION_URI_QUERY);
  
  coap_option_iterator_init(request, &opt_iter, f);
  
  len = 0;
  while ((len < sizeof(buf)) && (q = coap_option_next(&opt_iter))) {
    L = min(sizeof(buf) - len, 11);
    memcpy(buf + len, "Uri-Query: ", L);
    len += L;

    L = min(sizeof(buf) - len, COAP_OPT_LENGTH(q));
    memcpy(buf + len, COAP_OPT_VALUE(q), L);
    len += L;
    
    if (len < sizeof(buf))
      buf[len++] = '\n';
  }
  
  coap_add_data(response, len, buf);
}
Esempio n. 11
0
// When we receive the CoAP response we build and send the HTTP response
void coap_response_handler(struct coap_context_t *ctx, const coap_endpoint_t *local_interface,
                           const coap_address_t *remote, coap_pdu_t *sent, coap_pdu_t *received, const coap_tid_t id) {
    printf("COAP %13s:%-5u -> ",
           inet_ntoa((&remote->addr.sin)->sin_addr),
           ntohs((&remote->addr.sin)->sin_port));
    coap_show_pdu(received);

    for(int i = 0; i < MAX_HTTP_CONNECTIONS; i++) {
        if(http_coap_pairs[i].message_id == received->hdr->id) {
            struct MHD_Connection *connection = http_coap_pairs[i].connection;
            size_t len = 0;
            unsigned char *databuf = NULL;

            struct MHD_Response *response = MHD_create_response_from_buffer(len, databuf, MHD_RESPMEM_MUST_COPY);

            int read_result = coap_get_data(received, &len, &databuf);
            if(received->hdr->code == COAP_RESPONSE_CODE(205) && read_result == 0) {
                coap_abort_to_http(connection, "coap_get_data: cannot read CoAP response data\n");
            }

            static char tid_str[8];
            snprintf(tid_str, sizeof(tid_str), "%u", ntohs(received->hdr->id));
            MHD_add_response_header(response, "X-CoAP-Message-Id", tid_str);
            MHD_add_response_header(response, "X-CoAP-Response-Code", msg_code_string(received->hdr->code));

            // HTTP Content-Type
            const char *http_content_type;
            int coap_content_format;
            coap_opt_iterator_t opt_iter;
            coap_opt_t *option;
            coap_option_iterator_init(received, &opt_iter, COAP_OPT_ALL);
            while((option = coap_option_next(&opt_iter))) {
                switch(opt_iter.type) {
                    case COAP_OPTION_CONTENT_FORMAT:
                        coap_content_format = (int)coap_decode_var_bytes(COAP_OPT_VALUE(option),
                                                                         COAP_OPT_LENGTH(option));
                        break;
                    default:
                        continue;
                }
            }
            switch(coap_content_format) {
                case COAP_MEDIATYPE_TEXT_PLAIN:                 http_content_type = "text/plain"; break;
                case COAP_MEDIATYPE_APPLICATION_LINK_FORMAT:    http_content_type = "application/link-format"; break;
                case COAP_MEDIATYPE_APPLICATION_XML:            http_content_type = "application/xml"; break;
                case COAP_MEDIATYPE_APPLICATION_OCTET_STREAM:   http_content_type = "application/octet-stream"; break;
                case COAP_MEDIATYPE_APPLICATION_EXI:            http_content_type = "application/exi"; break;
                case COAP_MEDIATYPE_APPLICATION_JSON:           http_content_type = "application/json"; break;
                case COAP_MEDIATYPE_APPLICATION_CBOR:           http_content_type = "application/cbor"; break;
                default:                                        http_content_type = "unknown"; break;
            }
            MHD_add_response_header(response, MHD_HTTP_HEADER_CONTENT_TYPE, http_content_type);

            // HTTP Code
            unsigned int http_code;
            switch(received->hdr->code) {
                case COAP_RESPONSE_200:         http_code = MHD_HTTP_NO_CONTENT;            break; /* 2.00 OK */
                case COAP_RESPONSE_201:         http_code = MHD_HTTP_CREATED;               break; /* 2.01 Created */
                case COAP_RESPONSE_CODE(205):   http_code = MHD_HTTP_OK;                    break;
                case COAP_RESPONSE_304:         http_code = MHD_HTTP_ACCEPTED;              break; /* 2.03 Valid */
                case COAP_RESPONSE_400:         http_code = MHD_HTTP_BAD_REQUEST;           break; /* 4.00 Bad Request */
                case COAP_RESPONSE_404:         http_code = MHD_HTTP_NOT_FOUND;             break; /* 4.04 Not Found */
                case COAP_RESPONSE_405:         http_code = MHD_HTTP_NOT_ACCEPTABLE;        break; /* 4.05 Method Not Allowed */
                case COAP_RESPONSE_415:         http_code = MHD_HTTP_UNSUPPORTED_MEDIA_TYPE;break; /* 4.15 Unsupported Media Type */
                case COAP_RESPONSE_500:         http_code = MHD_HTTP_INTERNAL_SERVER_ERROR; break; /* 5.00 Internal Server Error */
                case COAP_RESPONSE_501:         http_code = MHD_HTTP_NOT_IMPLEMENTED;       break; /* 5.01 Not Implemented */
                case COAP_RESPONSE_503:         http_code = MHD_HTTP_SERVICE_UNAVAILABLE;   break; /* 5.03 Service Unavailable */
                case COAP_RESPONSE_504:         http_code = MHD_HTTP_GATEWAY_TIMEOUT;       break; /* 5.04 Gateway Timeout */
                default:                        http_code = MHD_HTTP_INTERNAL_SERVER_ERROR; break;
            }

            // Send the response
            MHD_queue_response(connection, http_code, response);
            MHD_destroy_response(response);

            const struct sockaddr_in *client_addr = (const struct sockaddr_in *)
                    MHD_get_connection_info(connection, MHD_CONNECTION_INFO_CLIENT_ADDRESS)->client_addr;
            printf("HTTP %13s:%-5u <- %u %s [ %s, %zu bytes, \"%s\" ]\n", inet_ntoa(client_addr->sin_addr),
                   ntohs(client_addr->sin_port), http_code, http_reason_phrase_for(http_code),
                   http_content_type, len, (databuf != NULL) ? (char *)databuf : "");
        }

        // clear the association
        http_coap_pairs[i].connection = NULL;
        return;
    }
}
Esempio n. 12
0
CAResult_t CAGetInfoFromPDU(const coap_pdu_t *pdu, uint32_t *outCode, CAInfo_t *outInfo)
{
    OIC_LOG(DEBUG, TAG, "IN");

    if (!pdu || !outCode || !outInfo)
    {
        OIC_LOG(ERROR, TAG, "NULL pointer param");
        return CA_STATUS_INVALID_PARAM;
    }

    coap_opt_iterator_t opt_iter;
    coap_option_iterator_init((coap_pdu_t *) pdu, &opt_iter, COAP_OPT_ALL);

    if (outCode)
    {
        (*outCode) = (uint32_t) CA_RESPONSE_CODE(pdu->hdr->code);
    }

    // init HeaderOption list
    uint32_t count = CAGetOptionCount(opt_iter);
    memset(outInfo, 0, sizeof(*outInfo));

    outInfo->numOptions = count;

    // set type
    outInfo->type = pdu->hdr->type;

    // set message id
    outInfo->messageId = pdu->hdr->id;
    outInfo->payloadFormat = CA_FORMAT_UNDEFINED;

    if (count > 0)
    {
        outInfo->options = (CAHeaderOption_t *) OICCalloc(count, sizeof(CAHeaderOption_t));
        if (NULL == outInfo->options)
        {
            OIC_LOG(ERROR, TAG, "Out of memory");
            return CA_MEMORY_ALLOC_FAILED;
        }
    }

    coap_opt_t *option;
    char optionResult[CA_MAX_URI_LENGTH] = {0};
    uint32_t idx = 0;
    uint32_t optionLength = 0;
    bool isfirstsetflag = false;
    bool isQueryBeingProcessed = false;

    while ((option = coap_option_next(&opt_iter)))
    {
        char buf[COAP_MAX_PDU_SIZE] = {0};
        uint32_t bufLength =
            CAGetOptionData(opt_iter.type, (uint8_t *)(COAP_OPT_VALUE(option)),
                            COAP_OPT_LENGTH(option), (uint8_t *)buf, sizeof(buf));
        if (bufLength)
        {
            OIC_LOG_V(DEBUG, TAG, "COAP URI element : %s", buf);
            if (COAP_OPTION_URI_PATH == opt_iter.type || COAP_OPTION_URI_QUERY == opt_iter.type)
            {
                if (false == isfirstsetflag)
                {
                    isfirstsetflag = true;
                    optionResult[optionLength] = '/';
                    optionLength++;
                    // Make sure there is enough room in the optionResult buffer
                    if ((optionLength + bufLength) < sizeof(optionResult))
                    {
                        memcpy(&optionResult[optionLength], buf, bufLength);
                        optionLength += bufLength;
                    }
                    else
                    {
                        goto exit;
                    }
                }
                else
                {
                    if (COAP_OPTION_URI_PATH == opt_iter.type)
                    {
                        // Make sure there is enough room in the optionResult buffer
                        if (optionLength < sizeof(optionResult))
                        {
                            optionResult[optionLength] = '/';
                            optionLength++;
                        }
                        else
                        {
                            goto exit;
                        }
                    }
                    else if (COAP_OPTION_URI_QUERY == opt_iter.type)
                    {
                        if (false == isQueryBeingProcessed)
                        {
                            // Make sure there is enough room in the optionResult buffer
                            if (optionLength < sizeof(optionResult))
                            {
                                optionResult[optionLength] = '?';
                                optionLength++;
                                isQueryBeingProcessed = true;
                            }
                            else
                            {
                                goto exit;
                            }
                        }
                        else
                        {
                            // Make sure there is enough room in the optionResult buffer
                            if (optionLength < sizeof(optionResult))
                            {
                                optionResult[optionLength] = ';';
                                optionLength++;
                            }
                            else
                            {
                                goto exit;
                            }
                        }
                    }
                    // Make sure there is enough room in the optionResult buffer
                    if ((optionLength + bufLength) < sizeof(optionResult))
                    {
                        memcpy(&optionResult[optionLength], buf, bufLength);
                        optionLength += bufLength;
                    }
                    else
                    {
                        goto exit;
                    }
                }
            }
            else if (COAP_OPTION_BLOCK1 == opt_iter.type || COAP_OPTION_BLOCK2 == opt_iter.type
                     || COAP_OPTION_SIZE1 == opt_iter.type || COAP_OPTION_SIZE2 == opt_iter.type)
            {
                OIC_LOG_V(DEBUG, TAG, "option[%d] will be filtering", opt_iter.type);
            }
            else if (COAP_OPTION_CONTENT_FORMAT == opt_iter.type)
            {
                if (1 == COAP_OPT_LENGTH(option) && COAP_MEDIATYPE_APPLICATION_CBOR == buf[0])
                {
                    outInfo->payloadFormat = CA_FORMAT_CBOR;
                }
                else
                {
                    outInfo->payloadFormat = CA_FORMAT_UNSUPPORTED;
                }
                OIC_LOG_V(DEBUG, TAG, "option[%d] has format [%d]", opt_iter.type, (uint8_t)buf[0]);
            }
            else
            {
                if (idx < count)
                {
                    uint32_t length = bufLength;

                    if (length <= CA_MAX_HEADER_OPTION_DATA_LENGTH)
                    {
                        outInfo->options[idx].optionID = opt_iter.type;
                        outInfo->options[idx].optionLength = length;
                        outInfo->options[idx].protocolID = CA_COAP_ID;
                        memcpy(outInfo->options[idx].optionData, buf, length);
                        idx++;
                    }
                }
            }
        }
    }

    // set token data
    if (pdu->hdr->token_length > 0)
    {
        OIC_LOG_V(DEBUG, TAG, "inside token length : %d", pdu->hdr->token_length);
        outInfo->token = (char *) OICMalloc(pdu->hdr->token_length);
        if (NULL == outInfo->token)
        {
            OIC_LOG(ERROR, TAG, "Out of memory");
            OICFree(outInfo->options);
            return CA_MEMORY_ALLOC_FAILED;
        }
        memcpy(outInfo->token, pdu->hdr->token, pdu->hdr->token_length);
    }

    outInfo->tokenLength = pdu->hdr->token_length;

    // set payload data
    size_t dataSize;
    uint8_t *data;
    if (coap_get_data(pdu, &dataSize, &data))
    {
        OIC_LOG(DEBUG, TAG, "inside pdu->data");
        outInfo->payload = (uint8_t *) OICMalloc(dataSize);
        if (NULL == outInfo->payload)
        {
            OIC_LOG(ERROR, TAG, "Out of memory");
            OICFree(outInfo->options);
            OICFree(outInfo->token);
            return CA_MEMORY_ALLOC_FAILED;
        }
        memcpy(outInfo->payload, pdu->data, dataSize);
        outInfo->payloadSize = dataSize;
    }

    if (optionResult[0] != '\0')
    {
        OIC_LOG_V(DEBUG, TAG, "URL length:%d", strlen(optionResult));
        outInfo->resourceUri = OICStrdup(optionResult);
        if (!outInfo->resourceUri)
        {
            OIC_LOG(ERROR, TAG, "Out of memory");
            OICFree(outInfo->options);
            OICFree(outInfo->token);
            return CA_MEMORY_ALLOC_FAILED;
        }
    }

    OIC_LOG(DEBUG, TAG, "OUT");
    return CA_STATUS_OK;

exit:
    OIC_LOG(ERROR, TAG, "buffer too small");
    OICFree(outInfo->options);
    return CA_STATUS_FAILED;
}
Esempio n. 13
0
void hnd_get_time(coap_context_t  *ctx, struct coap_resource_t *resource, 
             coap_address_t *peer, coap_pdu_t *request, str *token,
             coap_pdu_t *response) {
    coap_opt_iterator_t opt_iter;
    coap_opt_t *option;
    unsigned char buf[40];
    size_t len;
    time_t now;
    coap_tick_t t;
    coap_subscription_t *subscription;

    /* FIXME: return time, e.g. in human-readable by default and ticks
     * when query ?ticks is given. */

    /* if my_clock_base was deleted, we pretend to have no such resource */
    response->hdr->code = 
        my_clock_base ? COAP_RESPONSE_CODE(205) : COAP_RESPONSE_CODE(404);

    if (request != NULL &&
        coap_check_option(request, COAP_OPTION_OBSERVE, &opt_iter)) {
        subscription = coap_add_observer(resource, peer, token);
        if (subscription) {
            subscription->non = request->hdr->type == COAP_MESSAGE_NON;
            coap_add_option(response, COAP_OPTION_OBSERVE, 0, NULL);
        }
    }
    if (resource->dirty == 1)
        coap_add_option(response, COAP_OPTION_OBSERVE, 
                        coap_encode_var_bytes(buf, ctx->observe), buf);


    if (my_clock_base)
        coap_add_option(response, COAP_OPTION_CONTENT_FORMAT,
                        coap_encode_var_bytes(buf, COAP_MEDIATYPE_TEXT_PLAIN), buf);

    coap_add_option(response, COAP_OPTION_MAXAGE,
                    coap_encode_var_bytes(buf, 0x01), buf);

    if (my_clock_base) {

        /* calculate current time */
        coap_ticks(&t);
        now = my_clock_base + (t / COAP_TICKS_PER_SECOND);

        if (request != NULL
            && (option = coap_check_option(request, COAP_OPTION_URI_QUERY, &opt_iter))
            && memcmp(COAP_OPT_VALUE(option), "ticks",
                      min(5, COAP_OPT_LENGTH(option))) == 0) {
            /* output ticks */
            len = snprintf((char *)buf, 
                           min(sizeof(buf), response->max_size - response->length),
                           "%u", (unsigned int)now);
            coap_add_data(response, len, buf);

        } else {			/* output human-readable time */
            struct tm *tmp;
            tmp = gmtime(&now);
            len = strftime((char *)buf, 
                           min(sizeof(buf), response->max_size - response->length),
                           "%b %d %H:%M:%S", tmp);
            coap_add_data(response, len, buf);
        }
    }
}
Esempio n. 14
0
void CAGetRequestPDUInfo(const coap_pdu_t *pdu, uint32_t* outCode, CAInfo_t* outInfo)
{
    unsigned char buf[COAP_MAX_PDU_SIZE]; /* need some space for output creation */
    uint32_t encode = 0;
    coap_opt_iterator_t opt_iter;
    coap_opt_t *option;
    char optionResult[CA_URI_MAX_SIZE] =
    { 0, };
    uint32_t count = 0;
    uint32_t isfirstsetflag = 0;

    /* show options, if any */
    coap_option_iterator_init((coap_pdu_t *) pdu, &opt_iter, COAP_OPT_ALL);

    memset(optionResult, 0, sizeof(optionResult));
    while ((option = coap_option_next(&opt_iter)))
    {

        if (print_readable(COAP_OPT_VALUE(option), COAP_OPT_LENGTH(option), buf, sizeof(buf),
                encode))
        {
            if (opt_iter.type == COAP_OPTION_URI_PATH || opt_iter.type == COAP_OPTION_URI_QUERY)
            {
                if (0 == isfirstsetflag)
                {
                    isfirstsetflag = 1;
                    memcpy(optionResult + count, buf, strlen(buf));
                    count += strlen(buf);

                }
                else
                {
                    if (opt_iter.type == COAP_OPTION_URI_PATH)
                    {
                        memcpy(optionResult + count, "/", 1);
                        count++;
                    }
                    else if (opt_iter.type == COAP_OPTION_URI_QUERY)
                    {
                        memcpy(optionResult + count, "?", 1);
                        count++;
                    }
                    memcpy(optionResult + count, buf, strlen(buf));
                    count += strlen(buf);
                }
            }
        }
    }

    OIC_LOG(DEBUG, TAG, "set CAInfo_t after parsing");

    // set pdu info
    (*outCode) = (uint32_t) pdu->hdr->code;
    memset(outInfo, 0, sizeof(CAInfo_t));

    outInfo->options = (CAHeaderOption_t*) OICMalloc(sizeof(CAHeaderOption_t));
    memset(outInfo->options, 0, sizeof(CAHeaderOption_t));

    outInfo->options->optionID = opt_iter.type;
    outInfo->options->optionLength = count;
    memcpy(outInfo->options->optionData, optionResult, CA_MAX_HEADER_OPTION_DATA_LENGTH);

    if (pdu->hdr->token_length > 0)
    {
        outInfo->token = (char*) OICMalloc(pdu->hdr->token_length);
        memcpy(outInfo->token, pdu->hdr->token, pdu->hdr->token_length);
    }

    if (NULL != pdu->data)
    {
        outInfo->payload = (char*) OICMalloc(strlen(pdu->data) + 1);
        memcpy(outInfo->payload, pdu->data, strlen(pdu->data) + 1);
    }
}
Esempio n. 15
0
void 
hnd_put_resource(coap_context_t  *ctx, struct coap_resource_t *resource, 
		 const coap_endpoint_t *local_interface,
		 coap_address_t *peer, coap_pdu_t *request, str *token,
		 coap_pdu_t *response) {
#if 1
  response->hdr->code = COAP_RESPONSE_CODE(501);
#else /* FIXME */
  coap_opt_iterator_t opt_iter;
  coap_opt_t *token, *etag;
  coap_pdu_t *response;
  size_t size = sizeof(coap_hdr_t);
  int type = (request->hdr->type == COAP_MESSAGE_CON) 
    ? COAP_MESSAGE_ACK : COAP_MESSAGE_NON;
  rd_t *rd = NULL;
  unsigned char code;		/* result code */
  unsigned char *data;
  str tmp;

  HASH_FIND(hh, resources, resource->key, sizeof(coap_key_t), rd);
  if (rd) {
    /* found resource object, now check Etag */
    etag = coap_check_option(request, COAP_OPTION_ETAG, &opt_iter);
    if (!etag || (COAP_OPT_LENGTH(etag) != rd->etag_len)
	|| memcmp(COAP_OPT_VALUE(etag), rd->etag, rd->etag_len) != 0) {
      
      if (coap_get_data(request, &tmp.length, &data)) {

	tmp.s = (unsigned char *)coap_malloc(tmp.length);
	if (!tmp.s) {
	  debug("hnd_put_rd: cannot allocate storage for new rd\n");
	  code = COAP_RESPONSE_CODE(503);
	  goto finish;
	}

	coap_free(rd->data.s);
	rd->data.s = tmp.s;
	rd->data.length = tmp.length;
	memcpy(rd->data.s, data, rd->data.length);
      }
    }

    if (etag) {
      rd->etag_len = min(COAP_OPT_LENGTH(etag), sizeof(rd->etag));
      memcpy(rd->etag, COAP_OPT_VALUE(etag), rd->etag_len);
    }

    code = COAP_RESPONSE_CODE(204);
    /* FIXME: update lifetime */
    
    } else {
    
    code = COAP_RESPONSE_CODE(503);
  }

  finish:
  /* FIXME: do not create a new response but use the old one instead */
  response = coap_pdu_init(type, code, request->hdr->id, size);

  if (!response) {
    debug("cannot create response for message %d\n", request->hdr->id);
    return;
  }

  if (request->hdr->token_length)
    coap_add_token(response, request->hdr->token_length, request->hdr->token);

  if (coap_send(ctx, peer, response) == COAP_INVALID_TID) {
    debug("hnd_get_rd: cannot send response for message %d\n", 
	  request->hdr->id);
  }
  coap_delete_pdu(response);
#endif
}
Esempio n. 16
0
void 
hnd_post_test(coap_context_t  *ctx, struct coap_resource_t *resource, 
	      coap_address_t *peer, coap_pdu_t *request, str *token,
	      coap_pdu_t *response) {
  coap_opt_iterator_t opt_iter;
  coap_opt_t *option;
  coap_payload_t *test_payload;
  size_t len;
  size_t l = 6 + sizeof(void *);
  coap_dynamic_uri_t *uri;
  unsigned char *data;

#define BUFSIZE 20
  int res;
  unsigned char _buf[BUFSIZE];
  unsigned char *buf = _buf;
  size_t buflen = BUFSIZE;

  (void)resource;
  (void)peer;
  (void)token;

  coap_get_data(request, &len, &data);

  /* allocate storage for resource and to hold URI */
  test_payload = coap_new_payload(len);
  uri = (coap_dynamic_uri_t *)coap_malloc(sizeof(coap_dynamic_uri_t) + l);
  if (!(test_payload && uri)) {
    coap_log(LOG_CRIT, "cannot allocate new resource under /test");
    response->hdr->code = COAP_RESPONSE_CODE(500);    
    coap_free(test_payload);
    coap_free(uri);
  } else {
    coap_resource_t *r;

    memset(uri, 0, sizeof(coap_dynamic_uri_t));
    uri->length = min(l, (size_t)snprintf((char *)uri->data, l, "test/%p", (void*)test_payload));
    test_payload->length = len;

    memcpy(test_payload->data, data, len);

    r = coap_resource_init(uri->data, uri->length, 0);
    coap_register_handler(r, COAP_REQUEST_GET, hnd_get_resource);
    coap_register_handler(r, COAP_REQUEST_DELETE, hnd_delete_resource);

    /* set media_type if available */
    option = coap_check_option(request, COAP_OPTION_CONTENT_TYPE, &opt_iter);
    if (option) {
      test_payload->media_type = 
	coap_decode_var_bytes(COAP_OPT_VALUE(option), COAP_OPT_LENGTH(option));
    }

    coap_add_resource(ctx, r);
    coap_add_payload(r->key, test_payload, uri);

    /* add Location-Path */
    res = coap_split_path(uri->data, uri->length, buf, &buflen);

    while (res--) {
      coap_add_option(response, COAP_OPTION_LOCATION_PATH,
		      COAP_OPT_LENGTH(buf), COAP_OPT_VALUE(buf));
      
      buf += COAP_OPT_SIZE(buf);      
    }

    response->hdr->code = COAP_RESPONSE_CODE(201);
  }

}
Esempio n. 17
0
void 
hnd_post_rd(coap_context_t  *ctx, struct coap_resource_t *resource, 
	    const coap_endpoint_t *local_interface,
	      coap_address_t *peer, coap_pdu_t *request, str *token,
	      coap_pdu_t *response) {

  size_t len=0;
  unsigned char *databuf;

  unsigned char strBuf[100];
  
  
  unsigned char s[100];

  coap_print_addr(peer, s, 100);

  if (coap_get_data(request, &len, &databuf)){	
    memcpy(strBuf, databuf, len);
    strBuf[len]='\0';
    fprintf(stdout, "%s %s\n", s, strBuf);
  }else{
    fprintf(stdout, "%s\n", s);
  }

  fflush(stdout);
  coap_resource_t *r;
  coap_opt_iterator_t opt_iter;
  coap_opt_t *query;
#define LOCSIZE 68
  unsigned char *loc;
  size_t loc_size;
  str h = {0, NULL}, ins = {0, NULL}, rt = {0, NULL}, lt = {0, NULL};		/* store query parameters */
  unsigned char *buf;

  loc = (unsigned char *)coap_malloc(LOCSIZE);
  if (!loc) {
    response->hdr->code = COAP_RESPONSE_CODE(500);
    return;
  }
  memcpy(loc, RD_ROOT_STR, RD_ROOT_SIZE);

  loc_size = RD_ROOT_SIZE;
  loc[loc_size++] = '/';
  
  /* store query parameters for later use */
  query = coap_check_option(request, COAP_OPTION_URI_QUERY, &opt_iter);
  if (query) {
    parse_param((unsigned char *)"h", 1, 
		COAP_OPT_VALUE(query), COAP_OPT_LENGTH(query), &h);
    parse_param((unsigned char *)"ins", 3, 
		COAP_OPT_VALUE(query), COAP_OPT_LENGTH(query), &ins);
    parse_param((unsigned char *)"lt", 2, 
		COAP_OPT_VALUE(query), COAP_OPT_LENGTH(query), &lt);
    parse_param((unsigned char *)"rt", 2, 
		COAP_OPT_VALUE(query), COAP_OPT_LENGTH(query), &rt);
  } 
  
  if (h.length) {		/* client has specified a node name */
    memcpy(loc + loc_size, h.s, min(h.length, LOCSIZE - loc_size - 1));
    loc_size += min(h.length, LOCSIZE - loc_size - 1);

    if (ins.length && loc_size > 1) {
      loc[loc_size++] = '-';
      memcpy((char *)(loc + loc_size), 
	     ins.s, min(ins.length, LOCSIZE - loc_size - 1));
      loc_size += min(ins.length, LOCSIZE - loc_size - 1);
    }
 
  } else {			/* generate node identifier */
    loc_size += 
      snprintf((char *)(loc + loc_size), LOCSIZE - loc_size - 1, 
	       "%x", request->hdr->id);
    
    if (loc_size > 1) {
      if (ins.length) {
	loc[loc_size++] = '-';
	memcpy((char *)(loc + loc_size), 
	       ins.s, min(ins.length, LOCSIZE - loc_size - 1));
	loc_size += min(ins.length, LOCSIZE - loc_size - 1);
      } else {
	coap_tick_t now;
	coap_ticks(&now);
	
	loc_size += 
	  snprintf((char *)(loc + loc_size), LOCSIZE - loc_size - 1, 
		   "-%x", now);
      }
    }
  }

  /* TODO:
   *   - use lt to check expiration
   */
  
  r = coap_resource_init(loc, loc_size, COAP_RESOURCE_FLAGS_RELEASE_URI);
  coap_register_handler(r, COAP_REQUEST_GET, hnd_get_resource);
  coap_register_handler(r, COAP_REQUEST_PUT, hnd_put_resource);
  coap_register_handler(r, COAP_REQUEST_DELETE, hnd_delete_resource);

  if (ins.s) {
    buf = (unsigned char *)coap_malloc(ins.length + 2);
    if (buf) {
      /* add missing quotes */
      buf[0] = '"';
      memcpy(buf + 1, ins.s, ins.length);
      buf[ins.length + 1] = '"';
      coap_add_attr(r, (unsigned char *)"ins", 3, buf, ins.length + 2, COAP_ATTR_FLAGS_RELEASE_VALUE);
    }
  }

  if (rt.s) {
    buf = (unsigned char *)coap_malloc(rt.length + 2);
    if (buf) {
      /* add missing quotes */
      buf[0] = '"';
      memcpy(buf + 1, rt.s, rt.length);
      buf[rt.length + 1] = '"';
      coap_add_attr(r, (unsigned char *)"rt", 2, buf, rt.length + 2, COAP_ATTR_FLAGS_RELEASE_VALUE);
    }
  }

  add_source_address(r, peer);

  {
    rd_t *rd;
    rd = make_rd(peer, request);
    if (rd) {
      coap_hash_path(loc, loc_size, rd->key);
      HASH_ADD(hh, resources, key, sizeof(coap_key_t), rd);
    } else {
      /* FIXME: send error response and delete r */
    }
  }

  coap_add_resource(ctx, r);


  /* create response */

  response->hdr->code = COAP_RESPONSE_CODE(201);

  { /* split path into segments and add Location-Path options */
    unsigned char _b[LOCSIZE];
    unsigned char *b = _b;
    size_t buflen = sizeof(_b);
    int nseg;
    
    nseg = coap_split_path(loc, loc_size, b, &buflen);
    while (nseg--) {
      coap_add_option(response, COAP_OPTION_LOCATION_PATH,
		      COAP_OPT_LENGTH(b), COAP_OPT_VALUE(b));
      b += COAP_OPT_SIZE(b);
    }
  }
}