示例#1
0
lwm2m_observed_t * observe_findByUri(lwm2m_context_t * contextP,
                                     lwm2m_uri_t * uriP)
{
    lwm2m_observed_t * targetP;

    LOG_URI(uriP);
    targetP = contextP->observedList;
    while (targetP != NULL)
    {
        if (targetP->uri.objectId == uriP->objectId)
        {
            if ((!LWM2M_URI_IS_SET_INSTANCE(uriP) && !LWM2M_URI_IS_SET_INSTANCE(&(targetP->uri)))
             || (LWM2M_URI_IS_SET_INSTANCE(uriP) && LWM2M_URI_IS_SET_INSTANCE(&(targetP->uri)) && (uriP->instanceId == targetP->uri.instanceId)))
             {
                 if ((!LWM2M_URI_IS_SET_RESOURCE(uriP) && !LWM2M_URI_IS_SET_RESOURCE(&(targetP->uri)))
                     || (LWM2M_URI_IS_SET_RESOURCE(uriP) && LWM2M_URI_IS_SET_RESOURCE(&(targetP->uri)) && (uriP->resourceId == targetP->uri.resourceId)))
                 {
                     LOG_ARG("Found one with%s observers.", targetP->watcherList ? "" : " no");
                     LOG_URI(&(targetP->uri));
                     return targetP;
                 }
             }
        }
        targetP = targetP->next;
    }

    LOG("Found nothing");
    return NULL;
}
示例#2
0
int lwm2m_dm_read(lwm2m_context_t * contextP,
                  uint16_t clientID,
                  lwm2m_uri_t * uriP,
                  lwm2m_result_callback_t callback,
                  void * userData)
{
    lwm2m_client_t * clientP;
    lwm2m_media_type_t format;

    LOG_ARG("clientID: %d", clientID);
    LOG_URI(uriP);

    clientP = (lwm2m_client_t *)lwm2m_list_find((lwm2m_list_t *)contextP->clientList, clientID);
    if (clientP == NULL) return COAP_404_NOT_FOUND;

    if (clientP->supportJSON == true)
    {
        format = LWM2M_CONTENT_JSON;
    }
    else
    {
        format = LWM2M_CONTENT_TLV;
    }

    return prv_makeOperation(contextP, clientID, uriP,
                             COAP_GET,
                             format,
                             NULL, 0,
                             callback, userData);
}
示例#3
0
int lwm2m_dm_write(lwm2m_context_t * contextP,
                   uint16_t clientID,
                   lwm2m_uri_t * uriP,
                   lwm2m_media_type_t format,
                   uint8_t * buffer,
                   int length,
                   lwm2m_result_callback_t callback,
                   void * userData)
{
    LOG_ARG("clientID: %d, format: %s, length: %d", clientID, STR_MEDIA_TYPE(format), length);
    LOG_URI(uriP);
    if (!LWM2M_URI_IS_SET_INSTANCE(uriP)
     || length == 0)
    {
        return COAP_400_BAD_REQUEST;
    }

    if (LWM2M_URI_IS_SET_RESOURCE(uriP))
    {
        return prv_makeOperation(contextP, clientID, uriP,
                                  COAP_PUT,
                                  format, buffer, length,
                                  callback, userData);
    }
    else
    {
        return prv_makeOperation(contextP, clientID, uriP,
                                  COAP_POST,
                                  format, buffer, length,
                                  callback, userData);
    }
}
示例#4
0
int lwm2m_bootstrap_delete(lwm2m_context_t * contextP,
                           void * sessionH,
                           lwm2m_uri_t * uriP)
{
    lwm2m_transaction_t * transaction;
    bs_data_t * dataP;

    LOG_URI(uriP);
    transaction = transaction_new(sessionH, COAP_DELETE, NULL, uriP, contextP->nextMID++, 4, NULL);
    if (transaction == NULL) return COAP_500_INTERNAL_SERVER_ERROR;

    dataP = (bs_data_t *)lwm2m_malloc(sizeof(bs_data_t));
    if (dataP == NULL)
    {
        transaction_free(transaction);
        return COAP_500_INTERNAL_SERVER_ERROR;
    }
    if (uriP == NULL)
    {
        LWM2M_URI_RESET(&dataP->uri);
    }
    else
    {
        memcpy(&dataP->uri, uriP, sizeof(lwm2m_uri_t));
    }
    dataP->callback = contextP->bootstrapCallback;
    dataP->userData = contextP->bootstrapUserData;

    transaction->callback = prv_resultCallback;
    transaction->userData = (void *)dataP;

    contextP->transactionList = (lwm2m_transaction_t *)LWM2M_LIST_ADD(contextP->transactionList, transaction);

    return transaction_send(contextP, transaction);
}
示例#5
0
uint8_t bootstrap_handleRequest(lwm2m_context_t * contextP,
                                lwm2m_uri_t * uriP,
                                void * fromSessionH,
                                coap_packet_t * message,
                                coap_packet_t * response)
{
    uint8_t result;
    char * name;

    LOG_URI(uriP);
    if (contextP->bootstrapCallback == NULL) return COAP_500_INTERNAL_SERVER_ERROR;
    if (message->code != COAP_POST) return COAP_400_BAD_REQUEST;
    if (message->uri_query == NULL) return COAP_400_BAD_REQUEST;
    if (message->payload != NULL) return COAP_400_BAD_REQUEST;

    if (lwm2m_strncmp((char *)message->uri_query->data, QUERY_NAME, QUERY_NAME_LEN) != 0)
    {
        return COAP_400_BAD_REQUEST;
    }

    if (message->uri_query->len == QUERY_NAME_LEN) return COAP_400_BAD_REQUEST;
    if (message->uri_query->next != NULL) return COAP_400_BAD_REQUEST;

    name = (char *)lwm2m_malloc(message->uri_query->len - QUERY_NAME_LEN + 1);
    if (name == NULL) return COAP_500_INTERNAL_SERVER_ERROR;

    memcpy(name, message->uri_query->data + QUERY_NAME_LEN, message->uri_query->len - QUERY_NAME_LEN);
    name[message->uri_query->len - QUERY_NAME_LEN] = 0;

    result = contextP->bootstrapCallback(fromSessionH, COAP_NO_ERROR, NULL, name, contextP->bootstrapUserData);

    lwm2m_free(name);

    return result;
}
示例#6
0
文件: data.c 项目: bsinno/wakaama
int lwm2m_data_parse(lwm2m_uri_t * uriP,
                     uint8_t * buffer,
                     size_t bufferLen,
                     lwm2m_media_type_t format,
                     lwm2m_data_t ** dataP)
{
    int res;

    LOG_ARG("format: %s, bufferLen: %d", STR_MEDIA_TYPE(format), bufferLen);
    LOG_URI(uriP);
    switch (format)
    {
    case LWM2M_CONTENT_TEXT:
        if (!LWM2M_URI_IS_SET_RESOURCE(uriP)) return 0;
        *dataP = lwm2m_data_new(1);
        if (*dataP == NULL) return 0;
        (*dataP)->id = uriP->resourceId;
        (*dataP)->type = LWM2M_TYPE_STRING;
        res = prv_setBuffer(*dataP, buffer, bufferLen);
        if (res == 0)
        {
            lwm2m_data_free(1, *dataP);
            *dataP = NULL;
        }
        return res;

    case LWM2M_CONTENT_OPAQUE:
        if (!LWM2M_URI_IS_SET_RESOURCE(uriP)) return 0;
        *dataP = lwm2m_data_new(1);
        if (*dataP == NULL) return 0;
        (*dataP)->id = uriP->resourceId;
        (*dataP)->type = LWM2M_TYPE_OPAQUE;
        res = prv_setBuffer(*dataP, buffer, bufferLen);
        if (res == 0)
        {
            lwm2m_data_free(1, *dataP);
            *dataP = NULL;
    }
        return res;

#ifdef LWM2M_OLD_CONTENT_FORMAT_SUPPORT
    case LWM2M_CONTENT_TLV_OLD:
#endif
    case LWM2M_CONTENT_TLV:
        return tlv_parse(buffer, bufferLen, dataP);

#ifdef LWM2M_SUPPORT_JSON
#ifdef LWM2M_OLD_CONTENT_FORMAT_SUPPORT
    case LWM2M_CONTENT_JSON_OLD:
#endif
    case LWM2M_CONTENT_JSON:
        return json_parse(uriP, buffer, bufferLen, dataP);
#endif

    default:
        return 0;
    }
}
示例#7
0
文件: uri.c 项目: drashti304/TizenRT
int uri_toString(lwm2m_uri_t * uriP,
                 uint8_t * buffer,
                 size_t bufferLen,
                 uri_depth_t * depthP)
{
    size_t head;
    int res;

    LOG_ARG("bufferLen: %u", bufferLen);
    LOG_URI(uriP);

    buffer[0] = '/';

    if (uriP == NULL)
    {
        if (depthP) *depthP = URI_DEPTH_OBJECT;
        return 1;
    }

    head = 1;

    res = utils_intToText(uriP->objectId, buffer + head, bufferLen - head);
    if (res <= 0) return -1;
    head += res;
    if (head >= bufferLen - 1) return -1;
    if (depthP) *depthP = URI_DEPTH_OBJECT_INSTANCE;

    if (LWM2M_URI_IS_SET_INSTANCE(uriP))
    {
        buffer[head] = '/';
        head++;
        res = utils_intToText(uriP->instanceId, buffer + head, bufferLen - head);
        if (res <= 0) return -1;
        head += res;
        if (head >= bufferLen - 1) return -1;
        if (depthP) *depthP = URI_DEPTH_RESOURCE;
        if (LWM2M_URI_IS_SET_RESOURCE(uriP))
        {
            buffer[head] = '/';
            head++;
            res = utils_intToText(uriP->resourceId, buffer + head, bufferLen - head);
            if (res <= 0) return -1;
            head += res;
            if (head >= bufferLen - 1) return -1;
            if (depthP) *depthP = URI_DEPTH_RESOURCE_INSTANCE;
        }
    }

    buffer[head] = '/';
    head++;

    LOG_ARG("length: %u, buffer: \"%.*s\"", head, head, buffer);

    return head;
}
示例#8
0
void lwm2m_resource_value_changed(lwm2m_context_t * contextP,
                                  lwm2m_uri_t * uriP)
{
    lwm2m_observed_t * targetP;

    LOG_URI(uriP);
    targetP = contextP->observedList;
    while (targetP != NULL)
    {
        if (targetP->uri.objectId == uriP->objectId)
        {
            if (!LWM2M_URI_IS_SET_INSTANCE(uriP)
             || (targetP->uri.flag & LWM2M_URI_FLAG_INSTANCE_ID) == 0
             || uriP->instanceId == targetP->uri.instanceId)
            {
                if (!LWM2M_URI_IS_SET_RESOURCE(uriP)
                 || (targetP->uri.flag & LWM2M_URI_FLAG_RESOURCE_ID) == 0
                 || uriP->resourceId == targetP->uri.resourceId)
                {
                    lwm2m_watcher_t * watcherP;

                    LOG("Found an observation");
                    LOG_URI(&(targetP->uri));

                    for (watcherP = targetP->watcherList ; watcherP != NULL ; watcherP = watcherP->next)
                    {
                        if (watcherP->active == true)
                        {
                            LOG("Tagging a watcher");
                            watcherP->update = true;
                        }
                    }
                }
            }
        }
        targetP = targetP->next;
    }
}
示例#9
0
int lwm2m_dm_delete(lwm2m_context_t * contextP,
                    uint16_t clientID,
                    lwm2m_uri_t * uriP,
                    lwm2m_result_callback_t callback,
                    void * userData)
{
    LOG_ARG("clientID: %d", clientID);
    LOG_URI(uriP);
    if (!LWM2M_URI_IS_SET_INSTANCE(uriP)
     || LWM2M_URI_IS_SET_RESOURCE(uriP))
    {
        return COAP_400_BAD_REQUEST;
    }

    return prv_makeOperation(contextP, clientID, uriP,
                              COAP_DELETE,
                              LWM2M_CONTENT_TEXT, NULL, 0,
                              callback, userData);
}
示例#10
0
int lwm2m_bootstrap_write(lwm2m_context_t * contextP,
                          void * sessionH,
                          lwm2m_uri_t * uriP,
                          lwm2m_media_type_t format,
                          uint8_t * buffer,
                          size_t length)
{
    lwm2m_transaction_t * transaction;
    bs_data_t * dataP;

    LOG_URI(uriP);
    if (uriP == NULL
    || buffer == NULL
    || length == 0)
    {
        return COAP_400_BAD_REQUEST;
    }

    transaction = transaction_new(sessionH, COAP_PUT, NULL, uriP, contextP->nextMID++, 4, NULL);
    if (transaction == NULL) return COAP_500_INTERNAL_SERVER_ERROR;

    coap_set_header_content_type(transaction->message, format);
    coap_set_payload(transaction->message, buffer, length);

    dataP = (bs_data_t *)lwm2m_malloc(sizeof(bs_data_t));
    if (dataP == NULL)
    {
        transaction_free(transaction);
        return COAP_500_INTERNAL_SERVER_ERROR;
    }
    dataP->isUri = true;
    memcpy(&dataP->uri, uriP, sizeof(lwm2m_uri_t));
    dataP->callback = contextP->bootstrapCallback;
    dataP->userData = contextP->bootstrapUserData;

    transaction->callback = prv_resultCallback;
    transaction->userData = (void *)dataP;

    contextP->transactionList = (lwm2m_transaction_t *)LWM2M_LIST_ADD(contextP->transactionList, transaction);

    return transaction_send(contextP, transaction);
}
示例#11
0
int lwm2m_dm_read(lwm2m_context_t * contextP,
                  uint16_t clientID,
                  lwm2m_uri_t * uriP,
                  lwm2m_result_callback_t callback,
                  void * userData)
{
    lwm2m_client_t * clientP;

    LOG_ARG("clientID: %d", clientID);
    LOG_URI(uriP);

    clientP = (lwm2m_client_t *)lwm2m_list_find((lwm2m_list_t *)contextP->clientList, clientID);
    if (clientP == NULL) return COAP_404_NOT_FOUND;

    return prv_makeOperation(contextP, clientID, uriP,
                             COAP_GET,
                             clientP->format,
                             NULL, 0,
                             callback, userData);
}
示例#12
0
int lwm2m_dm_discover(lwm2m_context_t * contextP,
                      uint16_t clientID,
                      lwm2m_uri_t * uriP,
                      lwm2m_result_callback_t callback,
                      void * userData)
{
    lwm2m_client_t * clientP;
    lwm2m_transaction_t * transaction;
    dm_data_t * dataP;

    LOG_ARG("clientID: %d", clientID);
    LOG_URI(uriP);
    clientP = (lwm2m_client_t *)lwm2m_list_find((lwm2m_list_t *)contextP->clientList, clientID);
    if (clientP == NULL) return COAP_404_NOT_FOUND;

    transaction = transaction_new(clientP->sessionH, COAP_GET, clientP->altPath, uriP, contextP->nextMID++, 4, NULL);
    if (transaction == NULL) return COAP_500_INTERNAL_SERVER_ERROR;

    coap_set_header_accept(transaction->message, LWM2M_CONTENT_LINK);

    if (callback != NULL)
    {
        dataP = (dm_data_t *)lwm2m_malloc(sizeof(dm_data_t));
        if (dataP == NULL)
        {
            transaction_free(transaction);
            return COAP_500_INTERNAL_SERVER_ERROR;
        }
        memcpy(&dataP->uri, uriP, sizeof(lwm2m_uri_t));
        dataP->clientID = clientP->internalID;
        dataP->callback = callback;
        dataP->userData = userData;

        transaction->callback = prv_resultCallback;
        transaction->userData = (void *)dataP;
    }

    contextP->transactionList = (lwm2m_transaction_t *)LWM2M_LIST_ADD(contextP->transactionList, transaction);

    return transaction_send(contextP, transaction);
}
示例#13
0
void observe_clear(lwm2m_context_t * contextP,
                   lwm2m_uri_t * uriP)
{
    lwm2m_observed_t * observedP;

    LOG_URI(uriP);

    observedP = contextP->observedList;
    while(observedP != NULL)
    {
        if (observedP->uri.objectId == uriP->objectId
            && (LWM2M_URI_IS_SET_INSTANCE(uriP) == false
                || observedP->uri.instanceId == uriP->instanceId))
        {
            lwm2m_observed_t * nextP;
            lwm2m_watcher_t * watcherP;

            nextP = observedP->next;

            for (watcherP = observedP->watcherList; watcherP != NULL; watcherP = watcherP->next)
            {
                if (watcherP->parameters != NULL) lwm2m_free(watcherP->parameters);
            }
            LWM2M_LIST_FREE(observedP->watcherList);

            prv_unlinkObserved(contextP, observedP);
            lwm2m_free(observedP);

            observedP = nextP;
        }
        else
        {
            observedP = observedP->next;
        }
    }
}
示例#14
0
int lwm2m_dm_write_attributes(lwm2m_context_t * contextP,
                              uint16_t clientID,
                              lwm2m_uri_t * uriP,
                              lwm2m_attributes_t * attrP,
                              lwm2m_result_callback_t callback,
                              void * userData)
{
#define _PRV_BUFFER_SIZE 32
    lwm2m_client_t * clientP;
    lwm2m_transaction_t * transaction;
    coap_packet_t * coap_pkt;
    uint8_t buffer[_PRV_BUFFER_SIZE];
    size_t length;

    LOG_ARG("clientID: %d", clientID);
    LOG_URI(uriP);
    if (attrP == NULL) return COAP_400_BAD_REQUEST;

    if (0 != (attrP->toSet & attrP->toClear)) return COAP_400_BAD_REQUEST;
    if (0 != (attrP->toSet & ATTR_FLAG_NUMERIC) && !LWM2M_URI_IS_SET_RESOURCE(uriP)) return COAP_400_BAD_REQUEST;
    if (ATTR_FLAG_NUMERIC == (attrP->toSet & ATTR_FLAG_NUMERIC)
     && (attrP->lessThan + 2 * attrP->step >= attrP->greaterThan)) return COAP_400_BAD_REQUEST;

    clientP = (lwm2m_client_t *)lwm2m_list_find((lwm2m_list_t *)contextP->clientList, clientID);
    if (clientP == NULL) return COAP_404_NOT_FOUND;

    transaction = transaction_new(clientP->sessionH, COAP_PUT, clientP->altPath, uriP, contextP->nextMID++, 4, NULL);
    if (transaction == NULL) return COAP_500_INTERNAL_SERVER_ERROR;

    if (callback != NULL)
    {
        dm_data_t * dataP;

        dataP = (dm_data_t *)lwm2m_malloc(sizeof(dm_data_t));
        if (dataP == NULL)
        {
            transaction_free(transaction);
            return COAP_500_INTERNAL_SERVER_ERROR;
        }
        memcpy(&dataP->uri, uriP, sizeof(lwm2m_uri_t));
        dataP->clientID = clientP->internalID;
        dataP->callback = callback;
        dataP->userData = userData;

        transaction->callback = prv_resultCallback;
        transaction->userData = (void *)dataP;
    }

    coap_pkt = (coap_packet_t *)transaction->message;
    free_multi_option(coap_pkt->uri_query);
    if (attrP->toSet & LWM2M_ATTR_FLAG_MIN_PERIOD)
    {
        memcpy(buffer, ATTR_MIN_PERIOD_STR, ATTR_MIN_PERIOD_LEN);
        length = utils_intToText(attrP->minPeriod, buffer + ATTR_MIN_PERIOD_LEN, _PRV_BUFFER_SIZE - ATTR_MIN_PERIOD_LEN);
        if (length == 0)
        {
            transaction_free(transaction);
            return COAP_500_INTERNAL_SERVER_ERROR;
        }
        coap_add_multi_option(&(coap_pkt->uri_query), buffer, ATTR_MIN_PERIOD_LEN + length, 0);
        SET_OPTION(coap_pkt, COAP_OPTION_URI_QUERY);
    }
    if (attrP->toSet & LWM2M_ATTR_FLAG_MAX_PERIOD)
    {
        memcpy(buffer, ATTR_MAX_PERIOD_STR, ATTR_MAX_PERIOD_LEN);
        length = utils_intToText(attrP->maxPeriod, buffer + ATTR_MAX_PERIOD_LEN, _PRV_BUFFER_SIZE - ATTR_MAX_PERIOD_LEN);
        if (length == 0)
        {
            transaction_free(transaction);
            return COAP_500_INTERNAL_SERVER_ERROR;
        }
        coap_add_multi_option(&(coap_pkt->uri_query), buffer, ATTR_MAX_PERIOD_LEN + length, 0);
        SET_OPTION(coap_pkt, COAP_OPTION_URI_QUERY);
    }
    if (attrP->toSet & LWM2M_ATTR_FLAG_GREATER_THAN)
    {
        memcpy(buffer, ATTR_GREATER_THAN_STR, ATTR_GREATER_THAN_LEN);
        length = utils_floatToText(attrP->greaterThan, buffer + ATTR_GREATER_THAN_LEN, _PRV_BUFFER_SIZE - ATTR_GREATER_THAN_LEN);
        if (length == 0)
        {
            transaction_free(transaction);
            return COAP_500_INTERNAL_SERVER_ERROR;
        }
        coap_add_multi_option(&(coap_pkt->uri_query), buffer, ATTR_GREATER_THAN_LEN + length, 0);
        SET_OPTION(coap_pkt, COAP_OPTION_URI_QUERY);
    }
    if (attrP->toSet & LWM2M_ATTR_FLAG_LESS_THAN)
    {
        memcpy(buffer, ATTR_LESS_THAN_STR, ATTR_LESS_THAN_LEN);
        length = utils_floatToText(attrP->lessThan, buffer + ATTR_LESS_THAN_LEN, _PRV_BUFFER_SIZE - ATTR_LESS_THAN_LEN);
        if (length == 0)
        {
            transaction_free(transaction);
            return COAP_500_INTERNAL_SERVER_ERROR;
        }
        coap_add_multi_option(&(coap_pkt->uri_query), buffer, ATTR_LESS_THAN_LEN + length, 0);
        SET_OPTION(coap_pkt, COAP_OPTION_URI_QUERY);
    }
    if (attrP->toSet & LWM2M_ATTR_FLAG_STEP)
    {
        memcpy(buffer, ATTR_STEP_STR, ATTR_STEP_LEN);
        length = utils_floatToText(attrP->step, buffer + ATTR_STEP_LEN, _PRV_BUFFER_SIZE - ATTR_STEP_LEN);
        if (length == 0)
        {
            transaction_free(transaction);
            return COAP_500_INTERNAL_SERVER_ERROR;
        }
        coap_add_multi_option(&(coap_pkt->uri_query), buffer, ATTR_STEP_LEN + length, 0);
        SET_OPTION(coap_pkt, COAP_OPTION_URI_QUERY);
    }
    if (attrP->toClear & LWM2M_ATTR_FLAG_MIN_PERIOD)
    {
        coap_add_multi_option(&(coap_pkt->uri_query), (uint8_t*)ATTR_MIN_PERIOD_STR, ATTR_MIN_PERIOD_LEN -1, 0);
        SET_OPTION(coap_pkt, COAP_OPTION_URI_QUERY);
    }
    if (attrP->toClear & LWM2M_ATTR_FLAG_MAX_PERIOD)
    {
        coap_add_multi_option(&(coap_pkt->uri_query), (uint8_t*)ATTR_MAX_PERIOD_STR, ATTR_MAX_PERIOD_LEN - 1, 0);
        SET_OPTION(coap_pkt, COAP_OPTION_URI_QUERY);
    }
    if (attrP->toClear & LWM2M_ATTR_FLAG_GREATER_THAN)
    {
        coap_add_multi_option(&(coap_pkt->uri_query), (uint8_t*)ATTR_GREATER_THAN_STR, ATTR_GREATER_THAN_LEN - 1, 0);
        SET_OPTION(coap_pkt, COAP_OPTION_URI_QUERY);
    }
    if (attrP->toClear & LWM2M_ATTR_FLAG_LESS_THAN)
    {
        coap_add_multi_option(&(coap_pkt->uri_query), (uint8_t*)ATTR_LESS_THAN_STR, ATTR_LESS_THAN_LEN - 1, 0);
        SET_OPTION(coap_pkt, COAP_OPTION_URI_QUERY);
    }
    if (attrP->toClear & LWM2M_ATTR_FLAG_STEP)
    {
        coap_add_multi_option(&(coap_pkt->uri_query), (uint8_t*)ATTR_STEP_STR, ATTR_STEP_LEN - 1, 0);
        SET_OPTION(coap_pkt, COAP_OPTION_URI_QUERY);
    }

    contextP->transactionList = (lwm2m_transaction_t *)LWM2M_LIST_ADD(contextP->transactionList, transaction);

    return transaction_send(contextP, transaction);
}
示例#15
0
coap_status_t observe_setParameters(lwm2m_context_t * contextP,
                                    lwm2m_uri_t * uriP,
                                    lwm2m_server_t * serverP,
                                    lwm2m_attributes_t * attrP)
{
    uint8_t result;
    lwm2m_watcher_t * watcherP;

    LOG_URI(uriP);
    LOG_ARG("toSet: %08X, toClear: %08X, minPeriod: %d, maxPeriod: %d, greaterThan: %f, lessThan: %f, step: %f",
            attrP->toSet, attrP->toClear, attrP->minPeriod, attrP->maxPeriod, attrP->greaterThan, attrP->lessThan, attrP->step);

    if (!LWM2M_URI_IS_SET_INSTANCE(uriP) && LWM2M_URI_IS_SET_RESOURCE(uriP)) return COAP_400_BAD_REQUEST;

    result = object_checkReadable(contextP, uriP);
    if (COAP_205_CONTENT != result) return result;

    if (0 != (attrP->toSet & ATTR_FLAG_NUMERIC))
    {
        result = object_checkNumeric(contextP, uriP);
        if (COAP_205_CONTENT != result) return result;
    }

    watcherP = prv_getWatcher(contextP, uriP, serverP);
    if (watcherP == NULL) return COAP_500_INTERNAL_SERVER_ERROR;

    // Check rule “lt” value + 2*”stp” values < “gt” value
    if ((((attrP->toSet | (watcherP->parameters?watcherP->parameters->toSet:0)) & ~attrP->toClear) & ATTR_FLAG_NUMERIC) == ATTR_FLAG_NUMERIC)
    {
        float gt;
        float lt;
        float stp;

        if (0 != (attrP->toSet & LWM2M_ATTR_FLAG_GREATER_THAN))
        {
            gt = attrP->greaterThan;
        }
        else
        {
            gt = watcherP->parameters->greaterThan;
        }
        if (0 != (attrP->toSet & LWM2M_ATTR_FLAG_LESS_THAN))
        {
            lt = attrP->lessThan;
        }
        else
        {
            lt = watcherP->parameters->lessThan;
        }
        if (0 != (attrP->toSet & LWM2M_ATTR_FLAG_STEP))
        {
            stp = attrP->step;
        }
        else
        {
            stp = watcherP->parameters->step;
        }

        if (lt + (2 * stp) >= gt) return COAP_400_BAD_REQUEST;
    }

    if (watcherP->parameters == NULL)
    {
        if (attrP->toSet != 0)
        {
            watcherP->parameters = (lwm2m_attributes_t *)lwm2m_malloc(sizeof(lwm2m_attributes_t));
            if (watcherP->parameters == NULL) return COAP_500_INTERNAL_SERVER_ERROR;
            memcpy(watcherP->parameters, attrP, sizeof(lwm2m_attributes_t));
        }
    }
    else
    {
        watcherP->parameters->toSet &= ~attrP->toClear;
        if (attrP->toSet & LWM2M_ATTR_FLAG_MIN_PERIOD)
        {
            watcherP->parameters->minPeriod = attrP->minPeriod;
        }
        if (attrP->toSet & LWM2M_ATTR_FLAG_MAX_PERIOD)
        {
            watcherP->parameters->maxPeriod = attrP->maxPeriod;
        }
        if (attrP->toSet & LWM2M_ATTR_FLAG_GREATER_THAN)
        {
            watcherP->parameters->greaterThan = attrP->greaterThan;
        }
        if (attrP->toSet & LWM2M_ATTR_FLAG_LESS_THAN)
        {
            watcherP->parameters->lessThan = attrP->lessThan;
        }
        if (attrP->toSet & LWM2M_ATTR_FLAG_STEP)
        {
            watcherP->parameters->step = attrP->step;
        }
    }

    LOG_ARG("Final toSet: %08X, minPeriod: %d, maxPeriod: %d, greaterThan: %f, lessThan: %f, step: %f",
            watcherP->parameters->toSet, watcherP->parameters->minPeriod, watcherP->parameters->maxPeriod, watcherP->parameters->greaterThan, watcherP->parameters->lessThan, watcherP->parameters->step);

    return COAP_204_CHANGED;
}
示例#16
0
文件: json.c 项目: sbernard31/wakaama
int json_serialize(lwm2m_uri_t * uriP,
                   int size,
                   lwm2m_data_t * tlvP,
                   uint8_t ** bufferP)
{
    int index;
    size_t head;
    uint8_t bufferJSON[PRV_JSON_BUFFER_SIZE];
    uint8_t baseUriStr[URI_MAX_STRING_LEN];
    int baseUriLen;
    uri_depth_t rootLevel;
    int num;
    lwm2m_data_t * targetP;

    LOG_ARG("size: %d", size);
    LOG_URI(uriP);
    if (size != 0 && tlvP == NULL) return -1;

    baseUriLen = uri_toString(uriP, baseUriStr, URI_MAX_STRING_LEN, &rootLevel);
    if (baseUriLen < 0) return -1;

    num = prv_findAndCheckData(uriP, rootLevel, size, tlvP, &targetP);
    if (num < 0) return -1;

    while (num == 1
        && (targetP->type == LWM2M_TYPE_OBJECT
         || targetP->type == LWM2M_TYPE_OBJECT_INSTANCE
         || targetP->type == LWM2M_TYPE_MULTIPLE_RESOURCE))
    {
        int res;

        res = utils_intToText(targetP->id, baseUriStr + baseUriLen, URI_MAX_STRING_LEN - baseUriLen);
        if (res <= 0) return 0;
        baseUriLen += res;
        if (baseUriLen >= URI_MAX_STRING_LEN -1) return 0;
        num = targetP->value.asChildren.count;
        targetP = targetP->value.asChildren.array;
        baseUriStr[baseUriLen] = '/';
        baseUriLen++;
    }

    if (baseUriLen > 0)
    {
        memcpy(bufferJSON, JSON_BN_HEADER_1, JSON_BN_HEADER_1_SIZE);
        head = JSON_BN_HEADER_1_SIZE;
        memcpy(bufferJSON + head, baseUriStr, baseUriLen);
        head += baseUriLen;
        memcpy(bufferJSON + head, JSON_BN_HEADER_2, JSON_BN_HEADER_2_SIZE);
        head += JSON_BN_HEADER_2_SIZE;
    }
    else
    {
        memcpy(bufferJSON, JSON_HEADER, JSON_HEADER_SIZE);
        head = JSON_HEADER_SIZE;
    }

    for (index = 0 ; index < num && head < PRV_JSON_BUFFER_SIZE ; index++)
    {
        int res;

        res = prv_serializeData(targetP + index, NULL, 0, bufferJSON + head, PRV_JSON_BUFFER_SIZE - head);
        if (res < 0) return res;
        head += res;
    }

    if (head + JSON_FOOTER_SIZE - 1 > PRV_JSON_BUFFER_SIZE) return 0;

    if (num > 0) head = head - 1;

    memcpy(bufferJSON + head, JSON_FOOTER, JSON_FOOTER_SIZE);
    head = head + JSON_FOOTER_SIZE;

    *bufferP = (uint8_t *)lwm2m_malloc(head);
    if (*bufferP == NULL) return -1;
    memcpy(*bufferP, bufferJSON, head);

    return head;
}
示例#17
0
int senml_json_parse(const lwm2m_uri_t * uriP,
                     const uint8_t * buffer,
                     size_t bufferLen,
                     lwm2m_data_t ** dataP)
{
    size_t index;
    int count = 0;
    _record_t * recordArray;
    lwm2m_data_t * parsedP;
    int recordIndex;
    char baseUri[URI_MAX_STRING_LEN + 1];
    time_t baseTime;
    lwm2m_data_t baseValue;

    LOG_ARG("bufferLen: %d, buffer: \"%s\"", bufferLen, (char *)buffer);
    LOG_URI(uriP);
    *dataP = NULL;
    recordArray = NULL;
    parsedP = NULL;

    index = json_skipSpace(buffer, bufferLen);
    if (index == bufferLen) return -1;

    if (buffer[index] != JSON_HEADER) return -1;

    _GO_TO_NEXT_CHAR(index, buffer, bufferLen);
    count = json_countItems(buffer + index, bufferLen - index);
    if (count <= 0) goto error;
    recordArray = (_record_t*)lwm2m_malloc(count * sizeof(_record_t));
    if (recordArray == NULL) goto error;
    /* at this point we are sure buffer[index] is '{' and all { and } are matching */
    recordIndex = 0;
    baseUri[0] = '\0';
    baseTime = 0;
    memset(&baseValue, 0, sizeof(baseValue));
    while (recordIndex < count)
    {
        int itemLen = json_itemLength(buffer + index, bufferLen - index);
        if (itemLen < 0) goto error;
        if (prv_parseItem(buffer + index + 1,
                          itemLen - 2,
                          recordArray + recordIndex,
                          baseUri,
                          &baseTime,
                          &baseValue))
        {
            goto error;
        }
        recordIndex++;
        index += itemLen - 1;
        _GO_TO_NEXT_CHAR(index, buffer, bufferLen);
        switch (buffer[index])
        {
        case JSON_SEPARATOR:
            _GO_TO_NEXT_CHAR(index, buffer, bufferLen);
            break;
        case JSON_FOOTER:
            if (recordIndex != count) goto error;
            break;
        default:
            goto error;
        }
    }

    if (buffer[index] != JSON_FOOTER) goto error;

    lwm2m_data_t * resultP;
    int size;

    count = prv_convertRecord(recordArray, count, &parsedP);
    lwm2m_free(recordArray);
    recordArray = NULL;

    if (count > 0 && uriP != NULL && LWM2M_URI_IS_SET_OBJECT(uriP))
    {
        if (parsedP->type != LWM2M_TYPE_OBJECT) goto error;
        if (parsedP->id != uriP->objectId) goto error;
        if (!LWM2M_URI_IS_SET_INSTANCE(uriP))
        {
            size = parsedP->value.asChildren.count;
            resultP = parsedP->value.asChildren.array;
        }
        else
        {
            int i;

            resultP = NULL;
            /* be permissive and allow full object JSON when requesting for a single instance */
            for (i = 0 ;
                 i < (int)parsedP->value.asChildren.count && resultP == NULL;
                 i++)
            {
                lwm2m_data_t * targetP;

                targetP = parsedP->value.asChildren.array + i;
                if (targetP->id == uriP->instanceId)
                {
                    resultP = targetP->value.asChildren.array;
                    size = targetP->value.asChildren.count;
                }
            }
            if (resultP == NULL) goto error;
            if (LWM2M_URI_IS_SET_RESOURCE(uriP))
            {
                lwm2m_data_t * resP;

                resP = NULL;
                for (i = 0 ; i < size && resP == NULL; i++)
                {
                    lwm2m_data_t * targetP;

                    targetP = resultP + i;
                    if (targetP->id == uriP->resourceId)
                    {
                        if (targetP->type == LWM2M_TYPE_MULTIPLE_RESOURCE
                         && LWM2M_URI_IS_SET_RESOURCE_INSTANCE(uriP))
                        {
                            resP = targetP->value.asChildren.array;
                            size = targetP->value.asChildren.count;
                        }
                        else
                        {
                            size = json_dataStrip(1, targetP, &resP);
                            if (size <= 0) goto error;
                            lwm2m_data_free(count, parsedP);
                            parsedP = NULL;
                        }
                    }
                }
                if (resP == NULL) goto error;
                resultP = resP;
            }
            if (LWM2M_URI_IS_SET_RESOURCE_INSTANCE(uriP))
            {
                lwm2m_data_t * resP;

                resP = NULL;
                for (i = 0 ; i < size && resP == NULL; i++)
                {
                    lwm2m_data_t * targetP;

                    targetP = resultP + i;
                    if (targetP->id == uriP->resourceInstanceId)
                    {
                        size = json_dataStrip(1, targetP, &resP);
                        if (size <= 0) goto error;
                        lwm2m_data_free(count, parsedP);
                        parsedP = NULL;
                    }
                }
                if (resP == NULL) goto error;
                resultP = resP;
            }
        }
    }
    else
    {
        resultP = parsedP;
        size = count;
    }

    if (parsedP != NULL)
    {
        lwm2m_data_t * tempP;

        size = json_dataStrip(size, resultP, &tempP);
        if (size <= 0) goto error;
        lwm2m_data_free(count, parsedP);
        resultP = tempP;
    }
    count = size;
    *dataP = resultP;

    LOG_ARG("Parsing successful. count: %d", count);
    return count;

error:
    LOG("Parsing failed");
    if (parsedP != NULL)
    {
        lwm2m_data_free(count, parsedP);
        parsedP = NULL;
    }
    if (recordArray != NULL)
    {
        lwm2m_free(recordArray);
    }
    return -1;
}
示例#18
0
uint8_t dm_handleRequest(lwm2m_context_t * contextP,
                         lwm2m_uri_t * uriP,
                         lwm2m_server_t * serverP,
                         coap_packet_t * message,
                         coap_packet_t * response)
{
    uint8_t result;
    lwm2m_media_type_t format;

    LOG_ARG("Code: %02X, server status: %s", message->code, STR_STATUS(serverP->status));
    LOG_URI(uriP);

    if (IS_OPTION(message, COAP_OPTION_CONTENT_TYPE))
    {
        format = utils_convertMediaType(message->content_type);
    }
    else
    {
        format = LWM2M_CONTENT_TLV;
    }

    if (uriP->objectId == LWM2M_SECURITY_OBJECT_ID)
    {
        return COAP_404_NOT_FOUND;
    }

    if (serverP->status != STATE_REGISTERED
        && serverP->status != STATE_REG_UPDATE_NEEDED
        && serverP->status != STATE_REG_FULL_UPDATE_NEEDED
        && serverP->status != STATE_REG_UPDATE_PENDING)
    {
        return COAP_IGNORE;
    }

    // TODO: check ACL

    switch (message->code)
    {
    case COAP_GET:
        {
            uint8_t * buffer = NULL;
            size_t length = 0;
            int res;

            if (IS_OPTION(message, COAP_OPTION_OBSERVE))
            {
                lwm2m_data_t * dataP = NULL;
                int size = 0;

                result = object_readData(contextP, uriP, &size, &dataP);
                if (COAP_205_CONTENT == result)
                {
                    result = observe_handleRequest(contextP, uriP, serverP, size, dataP, message, response);
                    if (COAP_205_CONTENT == result)
                    {
                        if (IS_OPTION(message, COAP_OPTION_ACCEPT))
                        {
                            format = utils_convertMediaType(message->accept[0]);
                        }
                        else
                        {
                            format = LWM2M_CONTENT_TLV;
                        }

                        res = lwm2m_data_serialize(uriP, size, dataP, &format, &buffer);
                        if (res < 0)
                        {
                            result = COAP_500_INTERNAL_SERVER_ERROR;
                        }
                        else
                        {
                            length = (size_t)res;
                            LOG_ARG("Observe Request[/%d/%d/%d]: %.*s\n", uriP->objectId, uriP->instanceId, uriP->resourceId, length, buffer);
                        }
                    }
                    lwm2m_data_free(size, dataP);
                }
            }
            else if (IS_OPTION(message, COAP_OPTION_ACCEPT)
                  && message->accept_num == 1
                  && message->accept[0] == APPLICATION_LINK_FORMAT)
            {
                format = LWM2M_CONTENT_LINK;
                result = object_discover(contextP, uriP, serverP, &buffer, &length);
            }
            else
            {
                if (IS_OPTION(message, COAP_OPTION_ACCEPT))
                {
                    format = utils_convertMediaType(message->accept[0]);
                }

                result = object_read(contextP, uriP, &format, &buffer, &length);
            }
            if (COAP_205_CONTENT == result)
            {
                coap_set_header_content_type(response, format);
                coap_set_payload(response, buffer, length);
                // lwm2m_handle_packet will free buffer
            }
            else
            {
                lwm2m_free(buffer);
            }
        }
        break;

    case COAP_POST:
        {
            if (!LWM2M_URI_IS_SET_INSTANCE(uriP))
            {
                result = object_create(contextP, uriP, format, message->payload, message->payload_len);
                if (result == COAP_201_CREATED)
                {
                    //longest uri is /65535/65535 = 12 + 1 (null) chars
                    char location_path[13] = "";
                    //instanceId expected
                    if ((uriP->flag & LWM2M_URI_FLAG_INSTANCE_ID) == 0)
                    {
                        result = COAP_500_INTERNAL_SERVER_ERROR;
                        break;
                    }

                    if (sprintf(location_path, "/%d/%d", uriP->objectId, uriP->instanceId) < 0)
                    {
                        result = COAP_500_INTERNAL_SERVER_ERROR;
                        break;
                    }
                    coap_set_header_location_path(response, location_path);

                    lwm2m_update_registration(contextP, 0, true);
                }
            }
            else if (!LWM2M_URI_IS_SET_RESOURCE(uriP))
            {
                result = object_write(contextP, uriP, format, message->payload, message->payload_len);
            }
            else
            {
                result = object_execute(contextP, uriP, message->payload, message->payload_len);
            }
        }
        break;

    case COAP_PUT:
        {
            if (IS_OPTION(message, COAP_OPTION_URI_QUERY))
            {
                lwm2m_attributes_t attr;

                if (0 != prv_readAttributes(message->uri_query, &attr))
                {
                    result = COAP_400_BAD_REQUEST;
                }
                else
                {
                    result = observe_setParameters(contextP, uriP, serverP, &attr);
                }
            }
            else if (LWM2M_URI_IS_SET_INSTANCE(uriP))
            {
                result = object_write(contextP, uriP, format, message->payload, message->payload_len);
            }
            else
            {
                result = COAP_400_BAD_REQUEST;
            }
        }
        break;

    case COAP_DELETE:
        {
            if (!LWM2M_URI_IS_SET_INSTANCE(uriP) || LWM2M_URI_IS_SET_RESOURCE(uriP))
            {
                result = COAP_400_BAD_REQUEST;
            }
            else
            {
                result = object_delete(contextP, uriP);
                if (result == COAP_202_DELETED)
                {
                    lwm2m_update_registration(contextP, 0, true);
                }
            }
        }
        break;

    default:
        result = COAP_400_BAD_REQUEST;
        break;
    }

    return result;
}
示例#19
0
void observe_step(lwm2m_context_t * contextP,
                  time_t currentTime,
                  time_t * timeoutP)
{
    lwm2m_observed_t * targetP;

    LOG("Entering");
    for (targetP = contextP->observedList ; targetP != NULL ; targetP = targetP->next)
    {
        lwm2m_watcher_t * watcherP;
        uint8_t * buffer = NULL;
        size_t length = 0;
        lwm2m_data_t * dataP = NULL;
        int size = 0;
        double floatValue = 0;
        int64_t integerValue = 0;
        bool storeValue = false;
        coap_packet_t message[1];
        time_t interval;

        LOG_URI(&(targetP->uri));
        if (LWM2M_URI_IS_SET_RESOURCE(&targetP->uri))
        {
            if (COAP_205_CONTENT != object_readData(contextP, &targetP->uri, &size, &dataP)) continue;
            switch (dataP->type)
            {
            case LWM2M_TYPE_INTEGER:
                if (1 != lwm2m_data_decode_int(dataP, &integerValue))
                {
                    lwm2m_data_free(size, dataP);
                    continue;
                }
                storeValue = true;
                break;
            case LWM2M_TYPE_FLOAT:
                if (1 != lwm2m_data_decode_float(dataP, &floatValue))
                {
                    lwm2m_data_free(size, dataP);
                    continue;
                }
                storeValue = true;
                break;
            default:
                break;
            }
        }
        for (watcherP = targetP->watcherList ; watcherP != NULL ; watcherP = watcherP->next)
        {
            if (watcherP->active == true)
            {
                bool notify = false;

                if (watcherP->update == true)
                {
                    // value changed, should we notify the server ?

                    if (watcherP->parameters == NULL || watcherP->parameters->toSet == 0)
                    {
                        // no conditions
                        notify = true;
                        LOG("Notify with no conditions");
                        LOG_URI(&(targetP->uri));
                    }

                    if (notify == false
                     && watcherP->parameters != NULL
                     && (watcherP->parameters->toSet & ATTR_FLAG_NUMERIC) != 0)
                    {
                        if ((watcherP->parameters->toSet & LWM2M_ATTR_FLAG_LESS_THAN) != 0)
                        {
                            LOG("Checking lower threshold");
                            // Did we cross the lower threshold ?
                            switch (dataP->type)
                            {
                            case LWM2M_TYPE_INTEGER:
                                if ((integerValue <= watcherP->parameters->lessThan
                                  && watcherP->lastValue.asInteger > watcherP->parameters->lessThan)
                                 || (integerValue >= watcherP->parameters->lessThan
                                  && watcherP->lastValue.asInteger < watcherP->parameters->lessThan))
                                {
                                    LOG("Notify on lower threshold crossing");
                                    notify = true;
                                }
                                break;
                            case LWM2M_TYPE_FLOAT:
                                if ((floatValue <= watcherP->parameters->lessThan
                                  && watcherP->lastValue.asFloat > watcherP->parameters->lessThan)
                                 || (floatValue >= watcherP->parameters->lessThan
                                  && watcherP->lastValue.asFloat < watcherP->parameters->lessThan))
                                {
                                    LOG("Notify on lower threshold crossing");
                                    notify = true;
                                }
                                break;
                            default:
                                break;
                            }
                        }
                        if ((watcherP->parameters->toSet & LWM2M_ATTR_FLAG_GREATER_THAN) != 0)
                        {
                            LOG("Checking upper threshold");
                            // Did we cross the upper threshold ?
                            switch (dataP->type)
                            {
                            case LWM2M_TYPE_INTEGER:
                                if ((integerValue <= watcherP->parameters->greaterThan
                                  && watcherP->lastValue.asInteger > watcherP->parameters->greaterThan)
                                 || (integerValue >= watcherP->parameters->greaterThan
                                  && watcherP->lastValue.asInteger < watcherP->parameters->greaterThan))
                                {
                                    LOG("Notify on lower upper crossing");
                                    notify = true;
                                }
                                break;
                            case LWM2M_TYPE_FLOAT:
                                if ((floatValue <= watcherP->parameters->greaterThan
                                  && watcherP->lastValue.asFloat > watcherP->parameters->greaterThan)
                                 || (floatValue >= watcherP->parameters->greaterThan
                                  && watcherP->lastValue.asFloat < watcherP->parameters->greaterThan))
                                {
                                    LOG("Notify on lower upper crossing");
                                    notify = true;
                                }
                                break;
                            default:
                                break;
                            }
                        }
                        if ((watcherP->parameters->toSet & LWM2M_ATTR_FLAG_STEP) != 0)
                        {
                            LOG("Checking step");

                            switch (dataP->type)
                            {
                            case LWM2M_TYPE_INTEGER:
                            {
                                int64_t diff;

                                diff = integerValue - watcherP->lastValue.asInteger;
                                if ((diff < 0 && (0 - diff) >= watcherP->parameters->step)
                                 || (diff >= 0 && diff >= watcherP->parameters->step))
                                {
                                    LOG("Notify on step condition");
                                    notify = true;
                                }
                            }
                                break;
                            case LWM2M_TYPE_FLOAT:
                            {
                                double diff;

                                diff = floatValue - watcherP->lastValue.asFloat;
                                if ((diff < 0 && (0 - diff) >= watcherP->parameters->step)
                                 || (diff >= 0 && diff >= watcherP->parameters->step))
                                {
                                    LOG("Notify on step condition");
                                    notify = true;
                                }
                            }
                                break;
                            default:
                                break;
                            }
                        }
                    }

                    if (watcherP->parameters != NULL
                     && (watcherP->parameters->toSet & LWM2M_ATTR_FLAG_MIN_PERIOD) != 0)
                    {
                        LOG_ARG("Checking minimal period (%d s)", watcherP->parameters->minPeriod);

                        if (watcherP->lastTime + watcherP->parameters->minPeriod > currentTime)
                        {
                            // Minimum Period did not elapse yet
                            interval = watcherP->lastTime + watcherP->parameters->minPeriod - currentTime;
                            if (*timeoutP > interval) *timeoutP = interval;
                            notify = false;
                        }
                        else
                        {
                            LOG("Notify on minimal period");
                            notify = true;
                        }
                    }
                }

                // Is the Maximum Period reached ?
                if (notify == false
                 && watcherP->parameters != NULL
                 && (watcherP->parameters->toSet & LWM2M_ATTR_FLAG_MAX_PERIOD) != 0)
                {
                    LOG_ARG("Checking maximal period (%d s)", watcherP->parameters->minPeriod);

                    if (watcherP->lastTime + watcherP->parameters->maxPeriod <= currentTime)
                    {
                        LOG("Notify on maximal period");
                        notify = true;
                    }
                }

                if (notify == true)
                {
                    if (buffer == NULL)
                    {
                        if (dataP != NULL)
                        {
                            int res;

                            res = lwm2m_data_serialize(&targetP->uri, size, dataP, &(watcherP->format), &buffer);
                            if (res < 0)
                            {
                                break;
                            }
                            else
                            {
                                length = (size_t)res;
                            }

                        }
                        else
                        {
                            if (COAP_205_CONTENT != object_read(contextP, &targetP->uri, &(watcherP->format), &buffer, &length))
                            {
                                buffer = NULL;
                                break;
                            }
                        }
                        coap_init_message(message, COAP_TYPE_NON, COAP_205_CONTENT, 0);
                        coap_set_header_content_type(message, watcherP->format);
                        coap_set_payload(message, buffer, length);
                    }
                    watcherP->lastTime = currentTime;
                    watcherP->lastMid = contextP->nextMID++;
                    message->mid = watcherP->lastMid;
                    coap_set_header_token(message, watcherP->token, watcherP->tokenLen);
                    coap_set_header_observe(message, watcherP->counter++);
                    (void)message_send(contextP, message, watcherP->server->sessionH);
                    watcherP->update = false;
                }

                // Store this value
                if (notify == true && storeValue == true)
                {
                    switch (dataP->type)
                    {
                    case LWM2M_TYPE_INTEGER:
                        watcherP->lastValue.asInteger = integerValue;
                        break;
                    case LWM2M_TYPE_FLOAT:
                        watcherP->lastValue.asFloat = floatValue;
                        break;
                    default:
                        break;
                    }
                }

                if (watcherP->parameters != NULL && (watcherP->parameters->toSet & LWM2M_ATTR_FLAG_MAX_PERIOD) != 0)
                {
                    // update timers
                    interval = watcherP->lastTime + watcherP->parameters->maxPeriod - currentTime;
                    if (*timeoutP > interval) *timeoutP = interval;
                }
            }
        }
        if (dataP != NULL) lwm2m_data_free(size, dataP);
        if (buffer != NULL) lwm2m_free(buffer);
    }
}
示例#20
0
文件: uri.cpp 项目: dista/crtmpserver
bool parseURI(string stringUri, URI &uri) {
	/*
	 * schema://[username[:password]@]host[:port][/[path[?parameters]]]
	 */
	LOG_URI("------------------------");
	LOG_URI("stringUri: `%s`", STR(stringUri));
	string fullUri;
	string fullUriWithAuth = stringUri;
	string scheme;
	string authentication;
	string username;
	string password;
	string hostPort;
	string host;
	string portString;
	uint16_t port;
	bool portSpecified;
	string fullDocumentPathWithParameters;
	string fullDocumentPath;
	string fullParameters;
	string documentPath;
	string document;
	string documentWithFullParameters;
	Variant parameters;

	string::size_type cursor = 0;
	string::size_type pos = 0;

	//1. Reset
	uri.Reset();

	//2. trim
	trim(stringUri);
	if (stringUri == "") {
		FATAL("Empty uri");
		return false;
	}

	//2. Get the scheme and the default port
	pos = stringUri.find("://", cursor);
	if (pos == string::npos) {
		FATAL("Unable to determine scheme");
		return false;
	}
	scheme = lowerCase(stringUri.substr(cursor, pos - cursor));
	cursor = pos + 3;
	if (_schemeToPort.size() == 0) {
		_schemeToPort["http"] = 80;
		_schemeToPort["rtmpt"] = 80;
		_schemeToPort["rtmpte"] = 80;
		_schemeToPort["https"] = 443;
		_schemeToPort["rtmps"] = 443;
		_schemeToPort["rtsp"] = 554;
		_schemeToPort["rtmp"] = 1935;
		_schemeToPort["rtmpe"] = 1935;
		_schemeToPort["mms"] = 1755;
	}
	if (MAP_HAS1(_schemeToPort, scheme)) {
		port = _schemeToPort[scheme];
	}
	//	else {
	//		FATAL("Scheme `%s` not supported", STR(scheme));
	//		return false;
	//	}
	LOG_URI("scheme: %s; default port: %"PRIu16, STR(scheme), port);

	//3. get the authentication portion. the search starts from
	//where the scheme detection left and up to the first / character
	string::size_type limit = stringUri.find("/", cursor);
	bool hasAuthentication = false;
	pos = stringUri.find("@", cursor);
	if (pos != string::npos) {
		if (limit != string::npos) {
			hasAuthentication = pos<limit;
		}
		hasAuthentication = true;
	}
	if (hasAuthentication) {
		authentication = stringUri.substr(cursor, pos - cursor);
		fullUri = stringUri.substr(0, cursor);
		fullUri += stringUri.substr(pos + 1);
		cursor = pos + 1;
	} else {
		fullUri = fullUriWithAuth;
	}
	if (authentication != "") {
		pos = authentication.find(":");
		if (pos != string::npos) {
			username = authentication.substr(0, pos);
			password = authentication.substr(pos + 1);
		} else {
			username = authentication;
			password = "";
		}
	}
	LOG_URI("fullUri: `%s`; fullUriWithAuth: `%s`", STR(fullUri), STR(fullUriWithAuth));
	LOG_URI("username: `%s`; password: `%s`", STR(username), STR(password));

	//4. Get the host:port
	pos = stringUri.find("/", cursor);
	if (pos == string::npos) {
		hostPort = stringUri.substr(cursor);
		cursor = stringUri.size() - 1;
		fullDocumentPathWithParameters = "/";
	} else {
		hostPort = stringUri.substr(cursor, pos - cursor);
		cursor = pos + 1;
		fullDocumentPathWithParameters = "/" + stringUri.substr(cursor);
	}
	trim(hostPort);
	if (hostPort == "") {
		FATAL("Invalid host:port specified");
		return false;
	}
	pos = hostPort.find(":");
	if (pos == string::npos) {
		host = hostPort;
		portSpecified = false;
	} else {
		host = hostPort.substr(0, pos);
		trim(host);
		portString = hostPort.substr(pos + 1);
		portSpecified = true;
		port = (uint16_t) atoi(STR(portString));
		if (format("%"PRIu16, port) != portString) {
			FATAL("Invalid port number specified: `%s`", STR(portString));
			return false;
		}
	}
	LOG_URI("host: %s; port: %"PRIu16"; portSpecified: %d", STR(host), port, portSpecified);

	//5. fullDocumentPathWithParameters
	fullDocumentPath = "/";
	fullParameters = "";
	documentPath = "/";
	document = "";
	documentWithFullParameters = "";
	parameters.Reset();
	parameters.IsArray(false);
	if (fullDocumentPathWithParameters != "/") {
		pos = fullDocumentPathWithParameters.find("?");
		if (pos == string::npos) {
			fullDocumentPath = fullDocumentPathWithParameters;
			fullParameters = "";
		} else {
			fullDocumentPath = fullDocumentPathWithParameters.substr(0, pos);
			fullParameters = fullDocumentPathWithParameters.substr(pos + 1);
		}

		trim(fullParameters);
		if (fullParameters != "") {
			vector<string> elements;
			split(fullParameters, "&", elements);
			for (uint32_t i = 0; i < elements.size(); i++) {
				string kvp = elements[i];
				if (kvp == "")
					continue;
				string k = "";
				string v = "";
				pos = kvp.find("=");
				if (pos == string::npos) {
					k = kvp;
					v = "";
				} else {
					k = kvp.substr(0, pos);
					v = kvp.substr(pos + 1);
				}
				if (k == "")
					continue;
				parameters[k] = v;
			}
		}

		for (string::size_type i = fullDocumentPath.size() - 1; i >= 0; i--) {
			if (fullDocumentPath[i] == '/')
				break;
			document = fullDocumentPath[i] + document;
		}
		documentPath = fullDocumentPath.substr(0, fullDocumentPath.size() - document.size());
		documentWithFullParameters = document;
		if (fullParameters != "")
			documentWithFullParameters += "?" + fullParameters;
	}
	LOG_URI("fullDocumentPathWithParameters: `%s`", STR(fullDocumentPathWithParameters));
	LOG_URI("fullDocumentPath: `%s`", STR(fullDocumentPath));
	LOG_URI("fullParameters: `%s`", STR(fullParameters));
	LOG_URI("documentPath: `%s`", STR(documentPath));
	LOG_URI("document: `%s`", STR(document));
	LOG_URI("documentWithFullParameters: `%s`", STR(documentWithFullParameters));
	LOG_URI("parameters:");
#ifdef DEBUG_URI

	FOR_MAP(parameters, string, Variant, i) {
		LOG_URI("\t`%s`: `%s`", STR(MAP_KEY(i)), STR(MAP_VAL(i)));
	}
示例#21
0
int senml_json_serialize(const lwm2m_uri_t * uriP,
                         int size,
                         const lwm2m_data_t * tlvP,
                         uint8_t ** bufferP)
{
    int index;
    size_t head;
    uint8_t bufferJSON[PRV_JSON_BUFFER_SIZE];
    uint8_t baseUriStr[URI_MAX_STRING_LEN];
    int baseUriLen;
    uri_depth_t rootLevel;
    uri_depth_t baseLevel;
    int num;
    lwm2m_data_t * targetP;
    const uint8_t *parentUriStr = NULL;
    size_t parentUriLen = 0;

    LOG_ARG("size: %d", size);
    LOG_URI(uriP);
    if (size != 0 && tlvP == NULL) return -1;

    baseUriLen = uri_toString(uriP, baseUriStr, URI_MAX_STRING_LEN, &baseLevel);
    if (baseUriLen < 0) return -1;
    if (baseUriLen > 1
     && baseLevel != URI_DEPTH_RESOURCE
     && baseLevel != URI_DEPTH_RESOURCE_INSTANCE)
    {
        if (baseUriLen >= URI_MAX_STRING_LEN -1) return 0;
        baseUriStr[baseUriLen++] = '/';
    }

    num = json_findAndCheckData(uriP, json_decreaseLevel(baseLevel), size, tlvP, &targetP);
    if (num < 0) return -1;

    switch (tlvP->type)
    {
    case LWM2M_TYPE_OBJECT:
        rootLevel = URI_DEPTH_OBJECT;
        break;
    case LWM2M_TYPE_OBJECT_INSTANCE:
        rootLevel = URI_DEPTH_OBJECT_INSTANCE;
        break;
    case LWM2M_TYPE_MULTIPLE_RESOURCE:
        if (baseUriLen > 1 && baseUriStr[baseUriLen - 1] != '/')
        {
            if (baseUriLen >= URI_MAX_STRING_LEN -1) return 0;
            baseUriStr[baseUriLen++] = '/';
        }
        rootLevel = URI_DEPTH_RESOURCE_INSTANCE;
        break;
    default:
        if (baseLevel == URI_DEPTH_RESOURCE_INSTANCE)
        {
            rootLevel = URI_DEPTH_RESOURCE_INSTANCE;
        }
        else
        {
            rootLevel = URI_DEPTH_RESOURCE;
        }
        break;
    }

    if (!baseUriLen || baseUriStr[baseUriLen - 1] != '/')
    {
        parentUriStr = (const uint8_t *)"/";
        parentUriLen = 1;
    }

    head = 0;
    bufferJSON[head++] = JSON_HEADER;

    bool baseNameOutput = false;
    for (index = 0 ; index < num && head < PRV_JSON_BUFFER_SIZE ; index++)
    {
        int res;

        if (index != 0)
        {
            if (head + 1 > PRV_JSON_BUFFER_SIZE) return 0;
            bufferJSON[head++] = JSON_SEPARATOR;
        }

        res = prv_serializeData(targetP + index,
                                baseUriStr,
                                baseUriLen,
                                baseLevel,
                                parentUriStr,
                                parentUriLen,
                                rootLevel,
                                &baseNameOutput,
                                bufferJSON + head,
                                PRV_JSON_BUFFER_SIZE - head);
        if (res < 0) return res;
        head += res;
    }

    if (head + 1 > PRV_JSON_BUFFER_SIZE) return 0;
    bufferJSON[head++] = JSON_FOOTER;

    *bufferP = (uint8_t *)lwm2m_malloc(head);
    if (*bufferP == NULL) return -1;
    memcpy(*bufferP, bufferJSON, head);

    return head;
}
示例#22
0
uint8_t bootstrap_handleCommand(lwm2m_context_t * contextP,
                                lwm2m_uri_t * uriP,
                                lwm2m_server_t * serverP,
                                coap_packet_t * message,
                                coap_packet_t * response)
{
    uint8_t result;
    lwm2m_media_type_t format;

    LOG_ARG("Code: %02X", message->code);
    LOG_URI(uriP);
    format = utils_convertMediaType(message->content_type);

    result = prv_checkServerStatus(serverP);
    if (result != COAP_NO_ERROR) return result;

    switch (message->code)
    {
    case COAP_PUT:
        {
            if (LWM2M_URI_IS_SET_INSTANCE(uriP))
            {
                if (object_isInstanceNew(contextP, uriP->objectId, uriP->instanceId))
                {
                    result = object_create(contextP, uriP, format, message->payload, message->payload_len);
                    if (COAP_201_CREATED == result)
                    {
                        result = COAP_204_CHANGED;
                    }
                }
                else
                {
                    result = object_write(contextP, uriP, format, message->payload, message->payload_len);
                    if (uriP->objectId == LWM2M_SECURITY_OBJECT_ID
                     && result == COAP_204_CHANGED)
                    {
                        prv_tagServer(contextP, uriP->instanceId);
                    }
                }
            }
            else
            {
                lwm2m_data_t * dataP = NULL;
                int size = 0;
                int i;

                if (message->payload_len == 0 || message->payload == 0)
                {
                    result = COAP_400_BAD_REQUEST;
                }
                else
                {
                    size = lwm2m_data_parse(uriP, message->payload, message->payload_len, format, &dataP);
                    if (size == 0)
                    {
                        result = COAP_500_INTERNAL_SERVER_ERROR;
                        break;
                    }

                    for (i = 0 ; i < size ; i++)
                    {
                        if(dataP[i].type == LWM2M_TYPE_OBJECT_INSTANCE)
                        {
                            if (object_isInstanceNew(contextP, uriP->objectId, dataP[i].id))
                            {
                                result = object_createInstance(contextP, uriP, &dataP[i]);
                                if (COAP_201_CREATED == result)
                                {
                                    result = COAP_204_CHANGED;
                                }
                            }
                            else
                            {
                                result = object_writeInstance(contextP, uriP, &dataP[i]);
                                if (uriP->objectId == LWM2M_SECURITY_OBJECT_ID
                                 && result == COAP_204_CHANGED)
                                {
                                    prv_tagServer(contextP, dataP[i].id);
                                }
                            }

                            if(result != COAP_204_CHANGED) // Stop object create or write when result is error
                            {
                                break;
                            }
                        }
                        else
                        {
                            result = COAP_400_BAD_REQUEST;
                        }
                    }
                    lwm2m_data_free(size, dataP);
                }
            }
        }
        break;

    case COAP_DELETE:
        {
            if (LWM2M_URI_IS_SET_RESOURCE(uriP))
            {
                result = COAP_400_BAD_REQUEST;
            }
            else
            {
                result = object_delete(contextP, uriP);
                if (uriP->objectId == LWM2M_SECURITY_OBJECT_ID
                 && result == COAP_202_DELETED)
                {
                    if (LWM2M_URI_IS_SET_INSTANCE(uriP))
                    {
                        prv_tagServer(contextP, uriP->instanceId);
                    }
                    else
                    {
                        prv_tagAllServer(contextP, NULL);
                    }
                }
            }
        }
        break;

    case COAP_GET:
    case COAP_POST:
    default:
        result = COAP_400_BAD_REQUEST;
        break;
    }

    if (result == COAP_202_DELETED
     || result == COAP_204_CHANGED)
    {
        if (serverP->status != STATE_BS_PENDING)
        {
            serverP->status = STATE_BS_PENDING;
            contextP->state = STATE_BOOTSTRAPPING;
        }
    }
    LOG_ARG("Server status: %s", STR_STATUS(serverP->status));

    return result;
}
示例#23
0
文件: json.c 项目: sbernard31/wakaama
int json_parse(lwm2m_uri_t * uriP,
               uint8_t * buffer,
               size_t bufferLen,
               lwm2m_data_t ** dataP)
{
    size_t index;
    int count = 0;
    bool eFound = false;
    bool bnFound = false;
    bool btFound = false;
    int bnStart;
    int bnLen;
    _record_t * recordArray;
    lwm2m_data_t * parsedP;

    LOG_ARG("bufferLen: %d, buffer: \"%s\"", bufferLen, (char *)buffer);
    LOG_URI(uriP);
    *dataP = NULL;
    recordArray = NULL;
    parsedP = NULL;

    index = prv_skipSpace(buffer, bufferLen);
    if (index == bufferLen) return -1;

    if (buffer[index] != '{') return -1;
    do
    {
        _GO_TO_NEXT_CHAR(index, buffer, bufferLen);
        if (buffer[index] != '"') goto error;
        if (index++ >= bufferLen) goto error;
        switch (buffer[index])
        {
        case 'e':
        {
            int recordIndex;

            if (bufferLen-index < JSON_MIN_ARRAY_LEN) goto error;
            index++;
            if (buffer[index] != '"') goto error;
            if (eFound == true) goto error;
            eFound = true;

            _GO_TO_NEXT_CHAR(index, buffer, bufferLen);
            if (buffer[index] != ':') goto error;
            _GO_TO_NEXT_CHAR(index, buffer, bufferLen);
            if (buffer[index] != '[') goto error;
            _GO_TO_NEXT_CHAR(index, buffer, bufferLen);
            count = prv_countItems(buffer + index, bufferLen - index);
            if (count <= 0) goto error;
            recordArray = (_record_t*)lwm2m_malloc(count * sizeof(_record_t));
            if (recordArray == NULL) goto error;
            // at this point we are sure buffer[index] is '{' and all { and } are matching
            recordIndex = 0;
            while (recordIndex < count)
            {
                int itemLen;

                if (buffer[index] != '{') goto error;
                itemLen = 0;
                while (buffer[index + itemLen] != '}') itemLen++;
                if (0 != prv_parseItem(buffer + index + 1, itemLen - 1, recordArray + recordIndex))
                {
                    goto error;
                }
                recordIndex++;
                index += itemLen;
                _GO_TO_NEXT_CHAR(index, buffer, bufferLen);
                switch (buffer[index])
                {
                case ',':
                    _GO_TO_NEXT_CHAR(index, buffer, bufferLen);
                    break;
                case ']':
                    if (recordIndex == count) break;
                    // else this is an error
                default:
                    goto error;
                }
            }
            if (buffer[index] != ']') goto error;
        }
        break;

        case 'b':
            if (bufferLen-index < JSON_MIN_BX_LEN) goto error;
            index++;
            switch (buffer[index])
            {
            case 't':
                index++;
                if (buffer[index] != '"') goto error;
                if (btFound == true) goto error;
                btFound = true;

                // TODO: handle timed values
                // temp: skip this token
                while(index < bufferLen && buffer[index] != ',' && buffer[index] != '}') index++;
                if (index == bufferLen) goto error;
                index--;
                // end temp
                break;
            case 'n':
                {
                    int next;
                    int tokenStart;
                    int tokenLen;
                    int itemLen;

                    index++;
                    if (buffer[index] != '"') goto error;
                    if (bnFound == true) goto error;
                    bnFound = true;
                    index -= 3;
                    itemLen = 0;
                    while (buffer[index + itemLen] != '}'
                        && buffer[index + itemLen] != ','
                        && index + itemLen < bufferLen)
                    {
                        itemLen++;
                    }
                    if (index + itemLen == bufferLen) goto error;
                    next = prv_split(buffer+index, itemLen, &tokenStart, &tokenLen, &bnStart, &bnLen);
                    if (next < 0) goto error;
                    bnStart += index;
                    index += next - 1;
                }
                break;
            default:
                goto error;
            }
            break;

        default:
            goto error;
        }

        _GO_TO_NEXT_CHAR(index, buffer, bufferLen);
    } while (buffer[index] == ',');

    if (buffer[index] != '}') goto error;

    if (eFound == true)
    {
        lwm2m_uri_t baseURI;
        lwm2m_uri_t * baseUriP;
        lwm2m_data_t * resultP;
        int size;

        memset(&baseURI, 0, sizeof(lwm2m_uri_t));
        if (bnFound == false)
        {
            baseUriP = uriP;
        }
        else
        {
            int res;

            // we ignore the request URI and use the bn one.

            // Check for " around URI
            if (bnLen < 3
             || buffer[bnStart] != '"'
             || buffer[bnStart+bnLen-1] != '"')
            {
                goto error;
            }
            bnStart += 1;
            bnLen -= 2;

            if (bnLen == 1)
            {
                if (buffer[bnStart] != '/') goto error;
                baseUriP = NULL;
            }
            else
            {
                res = lwm2m_stringToUri((char *)buffer + bnStart, bnLen, &baseURI);
                if (res < 0 || res != bnLen) goto error;
                baseUriP = &baseURI;
            }
        }

        count = prv_convertRecord(baseUriP, recordArray, count, &parsedP);
        lwm2m_free(recordArray);
        recordArray = NULL;

        if (count > 0 && uriP != NULL)
        {
            if (parsedP->type != LWM2M_TYPE_OBJECT || parsedP->id != uriP->objectId) goto error;
            if (!LWM2M_URI_IS_SET_INSTANCE(uriP))
            {
                size = parsedP->value.asChildren.count;
                resultP = parsedP->value.asChildren.array;
            }
            else
            {
                int i;

                resultP = NULL;
                // be permissive and allow full object JSON when requesting for a single instance
                for (i = 0 ; i < (int)parsedP->value.asChildren.count && resultP == NULL; i++)
                {
                    lwm2m_data_t * targetP;

                    targetP = parsedP->value.asChildren.array + i;
                    if (targetP->id == uriP->instanceId)
                    {
                        resultP = targetP->value.asChildren.array;
                        size = targetP->value.asChildren.count;
                    }
                }
                if (resultP == NULL) goto error;
                if (LWM2M_URI_IS_SET_RESOURCE(uriP))
                {
                    lwm2m_data_t * resP;

                    resP = NULL;
                    for (i = 0 ; i < size && resP == NULL; i++)
                    {
                        lwm2m_data_t * targetP;

                        targetP = resultP + i;
                        if (targetP->id == uriP->resourceId)
                        {
                            if (targetP->type == LWM2M_TYPE_MULTIPLE_RESOURCE)
                            {
                                resP = targetP->value.asChildren.array;
                                size = targetP->value.asChildren.count;
                            }
                            else
                            {
                                size = prv_dataStrip(1, targetP, &resP);
                                if (size <= 0) goto error;
                                lwm2m_data_free(count, parsedP);
                                parsedP = NULL;
                            }
                        }
                    }
                    if (resP == NULL) goto error;
                    resultP = resP;
                }
            }
        }
        else
        {
            resultP = parsedP;
            size = count;
        }

        if (parsedP != NULL)
        {
            lwm2m_data_t * tempP;

            size = prv_dataStrip(size, resultP, &tempP);
            if (size <= 0) goto error;
            lwm2m_data_free(count, parsedP);
            resultP = tempP;
        }
        count = size;
        *dataP = resultP;
    }

    LOG_ARG("Parsing successful. count: %d", count);
    return count;

error:
    LOG("Parsing failed");
    if (parsedP != NULL)
    {
        lwm2m_data_free(count, parsedP);
        parsedP = NULL;
    }
    if (recordArray != NULL)
    {
        lwm2m_free(recordArray);
    }
    return -1;
}
示例#24
0
int lwm2m_observe(lwm2m_context_t * contextP,
                  uint16_t clientID,
                  lwm2m_uri_t * uriP,
                  lwm2m_result_callback_t callback,
                  void * userData)
{
    lwm2m_client_t * clientP;
    lwm2m_transaction_t * transactionP;
    lwm2m_observation_t * observationP;
    uint8_t token[4];

    LOG_ARG("clientID: %d", clientID);
    LOG_URI(uriP);

    if (!LWM2M_URI_IS_SET_INSTANCE(uriP) && LWM2M_URI_IS_SET_RESOURCE(uriP)) return COAP_400_BAD_REQUEST;

    clientP = (lwm2m_client_t *)lwm2m_list_find((lwm2m_list_t *)contextP->clientList, clientID);
    if (clientP == NULL) return COAP_404_NOT_FOUND;

    for (observationP = clientP->observationList; observationP != NULL; observationP = observationP->next)
    {
        if (uriP->objectId == observationP->uri.objectId
            && (LWM2M_URI_IS_SET_INSTANCE(uriP) == false
                || observationP->uri.instanceId == uriP->instanceId)
            && (LWM2M_URI_IS_SET_INSTANCE(uriP) == false
                || observationP->uri.instanceId == uriP->instanceId))
        {
            break;
        }
    }
    if (observationP == NULL)
    {
        observationP = (lwm2m_observation_t *)lwm2m_malloc(sizeof(lwm2m_observation_t));
        if (observationP == NULL) return COAP_500_INTERNAL_SERVER_ERROR;
        memset(observationP, 0, sizeof(lwm2m_observation_t));

        observationP->id = lwm2m_list_newId((lwm2m_list_t *)clientP->observationList);
        memcpy(&observationP->uri, uriP, sizeof(lwm2m_uri_t));
        observationP->clientP = clientP;

        observationP->clientP->observationList = (lwm2m_observation_t *)LWM2M_LIST_ADD(observationP->clientP->observationList, observationP);
    }
    observationP->status = STATE_REG_PENDING;
    observationP->callback = callback;
    observationP->userData = userData;

    token[0] = clientP->internalID >> 8;
    token[1] = clientP->internalID & 0xFF;
    token[2] = observationP->id >> 8;
    token[3] = observationP->id & 0xFF;

    transactionP = transaction_new(clientP->sessionH, COAP_GET, clientP->altPath, uriP, contextP->nextMID++, 4, token);
    if (transactionP == NULL)
    {
        observationP->clientP->observationList = (lwm2m_observation_t *)LWM2M_LIST_RM(observationP->clientP->observationList, observationP->id, NULL);
        lwm2m_free(observationP);
        return COAP_500_INTERNAL_SERVER_ERROR;
    }

    coap_set_header_observe(transactionP->message, 0);
    if (clientP->supportJSON == true)
    {
        coap_set_header_accept(transactionP->message, LWM2M_CONTENT_JSON);
    }
    else
    {
        coap_set_header_accept(transactionP->message, LWM2M_CONTENT_TLV);
    }

    transactionP->callback = prv_obsRequestCallback;
    transactionP->userData = (void *)observationP;

    contextP->transactionList = (lwm2m_transaction_t *)LWM2M_LIST_ADD(contextP->transactionList, transactionP);

    return transaction_send(contextP, transactionP);
}
示例#25
0
lwm2m_transaction_t * transaction_new(void * sessionH,
                                      coap_method_t method,
                                      char * altPath,
                                      lwm2m_uri_t * uriP,
                                      uint16_t mID,
                                      uint8_t token_len,
                                      uint8_t* token)
{
    lwm2m_transaction_t * transacP;
    int result;

    LOG_ARG("method: %d, altPath: \"%s\", mID: %d, token_len: %d",
            method, altPath, mID, token_len);
    LOG_URI(uriP);

    // no transactions without peer
    if (NULL == sessionH) return NULL;

    transacP = (lwm2m_transaction_t *)lwm2m_malloc(sizeof(lwm2m_transaction_t));

    if (NULL == transacP) return NULL;
    memset(transacP, 0, sizeof(lwm2m_transaction_t));

    transacP->message = lwm2m_malloc(sizeof(coap_packet_t));
    if (NULL == transacP->message) goto error;

    coap_init_message(transacP->message, COAP_TYPE_CON, method, mID);

    transacP->peerH = sessionH;

    transacP->mID = mID;

    if (altPath != NULL)
    {
        // TODO: Support multi-segment alternative path
        coap_set_header_uri_path_segment(transacP->message, altPath + 1);
    }
    if (NULL != uriP)
    {
        char stringID[LWM2M_STRING_ID_MAX_LEN];

        result = utils_intToText(uriP->objectId, (uint8_t*)stringID, LWM2M_STRING_ID_MAX_LEN);
        if (result == 0) goto error;
        stringID[result] = 0;
        coap_set_header_uri_path_segment(transacP->message, stringID);

        if (LWM2M_URI_IS_SET_INSTANCE(uriP))
        {
            result = utils_intToText(uriP->instanceId, (uint8_t*)stringID, LWM2M_STRING_ID_MAX_LEN);
            if (result == 0) goto error;
            stringID[result] = 0;
            coap_set_header_uri_path_segment(transacP->message, stringID);
        }
        else
        {
            if (LWM2M_URI_IS_SET_RESOURCE(uriP))
            {
                coap_set_header_uri_path_segment(transacP->message, NULL);
            }
        }
        if (LWM2M_URI_IS_SET_RESOURCE(uriP))
        {
            result = utils_intToText(uriP->resourceId, (uint8_t*)stringID, LWM2M_STRING_ID_MAX_LEN);
            if (result == 0) goto error;
            stringID[result] = 0;
            coap_set_header_uri_path_segment(transacP->message, stringID);
        }
    }
    if (0 < token_len)
    {
        if (NULL != token)
        {
            coap_set_header_token(transacP->message, token, token_len);
        }
        else {
            // generate a token
            uint8_t temp_token[COAP_TOKEN_LEN];
            time_t tv_sec = lwm2m_gettime();

            // initialize first 6 bytes, leave the last 2 random
            temp_token[0] = mID;
            temp_token[1] = mID >> 8;
            temp_token[2] = tv_sec;
            temp_token[3] = tv_sec >> 8;
            temp_token[4] = tv_sec >> 16;
            temp_token[5] = tv_sec >> 24;
            // use just the provided amount of bytes
            coap_set_header_token(transacP->message, temp_token, token_len);
        }
    }

    LOG("Exiting on success");
    return transacP;

error:
    LOG("Exiting on failure");
    lwm2m_free(transacP);
    return NULL;
}
示例#26
0
int lwm2m_observe_cancel(lwm2m_context_t * contextP,
                         uint16_t clientID,
                         lwm2m_uri_t * uriP,
                         lwm2m_result_callback_t callback,
                         void * userData)
{
    lwm2m_client_t * clientP;
    lwm2m_observation_t * observationP;

    LOG_ARG("clientID: %d", clientID);
    LOG_URI(uriP);

    clientP = (lwm2m_client_t *)lwm2m_list_find((lwm2m_list_t *)contextP->clientList, clientID);
    if (clientP == NULL) return COAP_404_NOT_FOUND;

    observationP = prv_findObservationByURI(clientP, uriP);
    if (observationP == NULL) return COAP_404_NOT_FOUND;

    switch (observationP->status)
    {
    case STATE_REGISTERED:
    {
        lwm2m_transaction_t * transactionP;
        cancellation_data_t * cancelP;
        uint8_t token[4];

        token[0] = clientP->internalID >> 8;
        token[1] = clientP->internalID & 0xFF;
        token[2] = observationP->id >> 8;
        token[3] = observationP->id & 0xFF;

        transactionP = transaction_new(clientP->sessionH, COAP_GET, clientP->altPath, uriP, contextP->nextMID++, 4, token);
        if (transactionP == NULL)
        {
            return COAP_500_INTERNAL_SERVER_ERROR;
        }
        cancelP = (cancellation_data_t *)lwm2m_malloc(sizeof(cancellation_data_t));
        if (cancelP == NULL)
        {
            lwm2m_free(transactionP);
            return COAP_500_INTERNAL_SERVER_ERROR;
        }

        coap_set_header_observe(transactionP->message, 1);

        cancelP->observationP = observationP;
        cancelP->callbackP = callback;
        cancelP->userDataP = userData;

        transactionP->callback = prv_obsCancelRequestCallback;
        transactionP->userData = (void *)cancelP;

        contextP->transactionList = (lwm2m_transaction_t *)LWM2M_LIST_ADD(contextP->transactionList, transactionP);

        return transaction_send(contextP, transactionP);
    }

    case STATE_REG_PENDING:
        observationP->status = STATE_DEREG_PENDING;
        break;

    default:
        // Should not happen
        break;
    }

    return COAP_NO_ERROR;
}
示例#27
0
文件: uri.c 项目: drashti304/TizenRT
int lwm2m_stringToUri(const char * buffer,
                      size_t buffer_len,
                      lwm2m_uri_t * uriP)
{
    size_t head;
    int readNum;

    LOG_ARG("buffer_len: %u, buffer: \"%.*s\"", buffer_len, buffer_len, buffer);

    if (buffer == NULL || buffer_len == 0 || uriP == NULL) return 0;

    memset(uriP, 0, sizeof(lwm2m_uri_t));

    // Skip any white space
    head = 0;
    while (head < buffer_len && isspace(buffer[head]&0xFF))
    {
        head++;
    }
    if (head == buffer_len) return 0;

    // Check the URI start with a '/'
    if (buffer[head] != '/') return 0;
    head++;
    if (head == buffer_len) return 0;

    // Read object ID
    readNum = prv_parseNumber((uint8_t *)buffer, buffer_len, &head);
    if (readNum < 0 || readNum > LWM2M_MAX_ID) return 0;
    uriP->objectId = (uint16_t)readNum;
    uriP->flag |= LWM2M_URI_FLAG_OBJECT_ID;

    if (buffer[head] == '/') head += 1;
    if (head >= buffer_len)
    {
        LOG_ARG("Parsed characters: %u", head);
        LOG_URI(uriP);
        return head;
    }

    readNum = prv_parseNumber((uint8_t *)buffer, buffer_len, &head);
    if (readNum < 0 || readNum >= LWM2M_MAX_ID) return 0;
    uriP->instanceId = (uint16_t)readNum;
    uriP->flag |= LWM2M_URI_FLAG_INSTANCE_ID;

    if (buffer[head] == '/') head += 1;
    if (head >= buffer_len)
    {
        LOG_ARG("Parsed characters: %u", head);
        LOG_URI(uriP);
        return head;
    }

    readNum = prv_parseNumber((uint8_t *)buffer, buffer_len, &head);
    if (readNum < 0 || readNum >= LWM2M_MAX_ID) return 0;
    uriP->resourceId = (uint16_t)readNum;
    uriP->flag |= LWM2M_URI_FLAG_RESOURCE_ID;

    if (head != buffer_len) return 0;

    LOG_ARG("Parsed characters: %u", head);
    LOG_URI(uriP);

    return head;
}
示例#28
0
文件: data.c 项目: bsinno/wakaama
int lwm2m_data_serialize(lwm2m_uri_t * uriP,
                         int size,
                         lwm2m_data_t * dataP,
                         lwm2m_media_type_t * formatP,
                         uint8_t ** bufferP)
{
    LOG_URI(uriP);
    LOG_ARG("size: %d, formatP: %s", size, STR_MEDIA_TYPE(*formatP));

    // Check format
    if (*formatP == LWM2M_CONTENT_TEXT
     || *formatP == LWM2M_CONTENT_OPAQUE)
    {
        if (size != 1
         || (uriP != NULL && !LWM2M_URI_IS_SET_RESOURCE(uriP))
         || dataP->type == LWM2M_TYPE_OBJECT
         || dataP->type == LWM2M_TYPE_OBJECT_INSTANCE
         || dataP->type == LWM2M_TYPE_MULTIPLE_RESOURCE)
        {
#ifdef LWM2M_SUPPORT_JSON
            *formatP = LWM2M_CONTENT_JSON;
#else
            *formatP = LWM2M_CONTENT_TLV;
#endif
        }
    }

    if (*formatP == LWM2M_CONTENT_OPAQUE
     && dataP->type != LWM2M_TYPE_OPAQUE)
    {
        LOG("Opaque format is reserved to opaque resources.");
        return -1;
    }

    LOG_ARG("Final format: %s", STR_MEDIA_TYPE(*formatP));

    switch (*formatP)
    {
    case LWM2M_CONTENT_TEXT:
        return prv_textSerialize(dataP, bufferP);

    case LWM2M_CONTENT_OPAQUE:
        *bufferP = (uint8_t *)lwm2m_malloc(dataP->value.asBuffer.length);
        if (*bufferP == NULL) return -1;
        memcpy(*bufferP, dataP->value.asBuffer.buffer, dataP->value.asBuffer.length);
        return (int)dataP->value.asBuffer.length;

    case LWM2M_CONTENT_TLV:
    case LWM2M_CONTENT_TLV_OLD:
    {
            bool isResourceInstance;

            if (uriP != NULL && LWM2M_URI_IS_SET_RESOURCE(uriP)
             && (size != 1 || dataP->id != uriP->resourceId))
            {
                isResourceInstance = true;
            }
            else
            {
                isResourceInstance = false;
            }
            return tlv_serialize(isResourceInstance, size, dataP, bufferP);
        }

#ifdef LWM2M_CLIENT_MODE
    case LWM2M_CONTENT_LINK:
        return discover_serialize(NULL, uriP, NULL, size, dataP, bufferP);
#endif
#ifdef LWM2M_SUPPORT_JSON
    case LWM2M_CONTENT_JSON:
    case LWM2M_CONTENT_JSON_OLD:
        return json_serialize(uriP, size, dataP, bufferP);
#endif

    default:
        return -1;
    }
}
示例#29
0
文件: uri.c 项目: drashti304/TizenRT
lwm2m_uri_t * uri_decode(char * altPath,
                         multi_option_t *uriPath)
{
    lwm2m_uri_t * uriP;
    int readNum;

    LOG_ARG("altPath: \"%s\"", altPath);

    uriP = (lwm2m_uri_t *)lwm2m_malloc(sizeof(lwm2m_uri_t));
    if (NULL == uriP) return NULL;

    memset(uriP, 0, sizeof(lwm2m_uri_t));

    // Read object ID
    if (NULL != uriPath
     && URI_REGISTRATION_SEGMENT_LEN == uriPath->len
     && 0 == strncmp(URI_REGISTRATION_SEGMENT, (char *)uriPath->data, uriPath->len))
    {
        uriP->flag |= LWM2M_URI_FLAG_REGISTRATION;
        uriPath = uriPath->next;
        if (uriPath == NULL) return uriP;
    }
    else if (NULL != uriPath
     && URI_BOOTSTRAP_SEGMENT_LEN == uriPath->len
     && 0 == strncmp(URI_BOOTSTRAP_SEGMENT, (char *)uriPath->data, uriPath->len))
    {
        uriP->flag |= LWM2M_URI_FLAG_BOOTSTRAP;
        uriPath = uriPath->next;
        if (uriPath != NULL) goto error;
        return uriP;
    }

    if ((uriP->flag & LWM2M_URI_MASK_TYPE) != LWM2M_URI_FLAG_REGISTRATION)
    {
        // Read altPath if any
        if (altPath != NULL)
        {
            int i;
            if (NULL == uriPath)
            {
                lwm2m_free(uriP);
                return NULL;
            }
            for (i = 0 ; i < uriPath->len ; i++)
            {
                if (uriPath->data[i] != altPath[i+1])
                {
                    lwm2m_free(uriP);
                    return NULL;
                }
            }
            uriPath = uriPath->next;
        }
        if (NULL == uriPath || uriPath->len == 0)
        {
            uriP->flag |= LWM2M_URI_FLAG_DELETE_ALL;
            return uriP;
        }
    }

    readNum = uri_getNumber(uriPath->data, uriPath->len);
    if (readNum < 0 || readNum > LWM2M_MAX_ID) goto error;
    uriP->objectId = (uint16_t)readNum;
    uriP->flag |= LWM2M_URI_FLAG_OBJECT_ID;
    uriPath = uriPath->next;

    if ((uriP->flag & LWM2M_URI_MASK_TYPE) == LWM2M_URI_FLAG_REGISTRATION)
    {
        if (uriPath != NULL) goto error;
        return uriP;
    }
    uriP->flag |= LWM2M_URI_FLAG_DM;

    if (uriPath == NULL) return uriP;

    // Read object instance
    if (uriPath->len != 0)
    {
        readNum = uri_getNumber(uriPath->data, uriPath->len);
        if (readNum < 0 || readNum >= LWM2M_MAX_ID) goto error;
        uriP->instanceId = (uint16_t)readNum;
        uriP->flag |= LWM2M_URI_FLAG_INSTANCE_ID;
    }
    uriPath = uriPath->next;

    if (uriPath == NULL) return uriP;

    // Read resource ID
    if (uriPath->len != 0)
    {
        // resource ID without an instance ID is not allowed
        if ((uriP->flag & LWM2M_URI_FLAG_INSTANCE_ID) == 0) goto error;

        readNum = uri_getNumber(uriPath->data, uriPath->len);
        if (readNum < 0 || readNum > LWM2M_MAX_ID) goto error;
        uriP->resourceId = (uint16_t)readNum;
        uriP->flag |= LWM2M_URI_FLAG_RESOURCE_ID;
    }

    // must be the last segment
    if (NULL == uriPath->next)
    {
        LOG_URI(uriP);
        return uriP;
    }

error:
    LOG("Exiting on error");
    lwm2m_free(uriP);
    return NULL;
}
示例#30
0
coap_status_t registration_handleRequest(lwm2m_context_t * contextP,
                                          lwm2m_uri_t * uriP,
                                          void * fromSessionH,
                                          coap_packet_t * message,
                                          coap_packet_t * response)
{
    coap_status_t result;
    time_t tv_sec;

    LOG_URI(uriP);
    tv_sec = lwm2m_gettime();
    if (tv_sec < 0) return COAP_500_INTERNAL_SERVER_ERROR;

    switch(message->code)
    {
    case COAP_POST:
    {
        char * name = NULL;
        uint32_t lifetime;
        char * msisdn;
        char * altPath;
        lwm2m_binding_t binding;
        lwm2m_client_object_t * objects;
        bool supportJSON;
        lwm2m_client_t * clientP;
        char location[MAX_LOCATION_LENGTH];

        if (0 != prv_getParameters(message->uri_query, &name, &lifetime, &msisdn, &binding))
        {
            return COAP_400_BAD_REQUEST;
        }
        if (message->content_type != LWM2M_CONTENT_LINK
         && message->content_type != LWM2M_CONTENT_TEXT)
        {
            return COAP_400_BAD_REQUEST;
        }

        objects = prv_decodeRegisterPayload(message->payload, message->payload_len, &supportJSON, &altPath);

        switch (uriP->flag & LWM2M_URI_MASK_ID)
        {
        case 0:
            // Register operation

            if (objects == NULL)
            {
                lwm2m_free(name);
                if (msisdn != NULL) lwm2m_free(msisdn);
                return COAP_400_BAD_REQUEST;
            }
            // Endpoint client name is mandatory
            if (name == NULL)
            {
                if (msisdn != NULL) lwm2m_free(msisdn);
                return COAP_400_BAD_REQUEST;
            }
            if (lifetime == 0)
            {
                lifetime = LWM2M_DEFAULT_LIFETIME;
            }

            clientP = prv_getClientByName(contextP, name);
            if (clientP != NULL)
            {
                // we reset this registration
                lwm2m_free(clientP->name);
                if (clientP->msisdn != NULL) lwm2m_free(clientP->msisdn);
                if (clientP->altPath != NULL) lwm2m_free(clientP->altPath);
                prv_freeClientObjectList(clientP->objectList);
                clientP->objectList = NULL;
            }
            else
            {
                clientP = (lwm2m_client_t *)lwm2m_malloc(sizeof(lwm2m_client_t));
                if (clientP == NULL)
                {
                    lwm2m_free(name);
                    lwm2m_free(altPath);
                    if (msisdn != NULL) lwm2m_free(msisdn);
                    prv_freeClientObjectList(objects);
                    return COAP_500_INTERNAL_SERVER_ERROR;
                }
                memset(clientP, 0, sizeof(lwm2m_client_t));
                clientP->internalID = lwm2m_list_newId((lwm2m_list_t *)contextP->clientList);
                contextP->clientList = (lwm2m_client_t *)LWM2M_LIST_ADD(contextP->clientList, clientP);
            }
            clientP->name = name;
            clientP->binding = binding;
            clientP->msisdn = msisdn;
            clientP->altPath = altPath;
            clientP->supportJSON = supportJSON;
            clientP->lifetime = lifetime;
            clientP->endOfLife = tv_sec + lifetime;
            clientP->objectList = objects;
            clientP->sessionH = fromSessionH;

            if (prv_getLocationString(clientP->internalID, location) == 0)
            {
                registration_freeClient(clientP);
                return COAP_500_INTERNAL_SERVER_ERROR;
            }
            if (coap_set_header_location_path(response, location) == 0)
            {
                registration_freeClient(clientP);
                return COAP_500_INTERNAL_SERVER_ERROR;
            }

            if (contextP->monitorCallback != NULL)
            {
                contextP->monitorCallback(clientP->internalID, NULL, COAP_201_CREATED, LWM2M_CONTENT_TEXT, NULL, 0, contextP->monitorUserData);
            }
            result = COAP_201_CREATED;
            break;

        case LWM2M_URI_FLAG_OBJECT_ID:
            clientP = (lwm2m_client_t *)lwm2m_list_find((lwm2m_list_t *)contextP->clientList, uriP->objectId);
            if (clientP == NULL) return COAP_404_NOT_FOUND;

            // Endpoint client name MUST NOT be present
            if (name != NULL)
            {
                lwm2m_free(name);
                if (msisdn != NULL) lwm2m_free(msisdn);
                return COAP_400_BAD_REQUEST;
            }

            if (binding != BINDING_UNKNOWN)
            {
                clientP->binding = binding;
            }
            if (msisdn != NULL)
            {
                if (clientP->msisdn != NULL) lwm2m_free(clientP->msisdn);
                clientP->msisdn = msisdn;
            }
            if (lifetime != 0)
            {
                clientP->lifetime = lifetime;
            }
            // client IP address, port or MSISDN may have changed
            clientP->sessionH = fromSessionH;

            if (objects != NULL)
            {
                lwm2m_observation_t * observationP;

                // remove observations on object/instance no longer existing
                observationP = clientP->observationList;
                while (observationP != NULL)
                {
                    lwm2m_client_object_t * objP;
                    lwm2m_observation_t * nextP;

                    nextP = observationP->next;

                    objP = (lwm2m_client_object_t *)lwm2m_list_find((lwm2m_list_t *)objects, observationP->uri.objectId);
                    if (objP == NULL)
                    {
                        observationP->callback(clientP->internalID,
                                               &observationP->uri,
                                               COAP_202_DELETED,
                                               LWM2M_CONTENT_TEXT, NULL, 0,
                                               observationP->userData);
                        observe_remove(clientP, observationP);
                    }
                    else
                    {
                        if ((observationP->uri.flag & LWM2M_URI_FLAG_INSTANCE_ID) != 0)
                        {
                            if (lwm2m_list_find((lwm2m_list_t *)objP->instanceList, observationP->uri.instanceId) == NULL)
                            {
                                observationP->callback(clientP->internalID,
                                                       &observationP->uri,
                                                       COAP_202_DELETED,
                                                       LWM2M_CONTENT_TEXT, NULL, 0,
                                                       observationP->userData);
                                observe_remove(clientP, observationP);
                            }
                        }
                    }

                    observationP = nextP;
                }

                prv_freeClientObjectList(clientP->objectList);
                clientP->objectList = objects;
            }

            clientP->endOfLife = tv_sec + clientP->lifetime;

            if (contextP->monitorCallback != NULL)
            {
                contextP->monitorCallback(clientP->internalID, NULL, COAP_204_CHANGED, LWM2M_CONTENT_TEXT, NULL, 0, contextP->monitorUserData);
            }
            result = COAP_204_CHANGED;
            break;

            default:
                return COAP_400_BAD_REQUEST;
        }
    }
    break;

    case COAP_DELETE:
    {
        lwm2m_client_t * clientP;

        if ((uriP->flag & LWM2M_URI_MASK_ID) != LWM2M_URI_FLAG_OBJECT_ID) return COAP_400_BAD_REQUEST;

        contextP->clientList = (lwm2m_client_t *)LWM2M_LIST_RM(contextP->clientList, uriP->objectId, &clientP);
        if (clientP == NULL) return COAP_400_BAD_REQUEST;
        if (contextP->monitorCallback != NULL)
        {
            contextP->monitorCallback(clientP->internalID, NULL, COAP_202_DELETED, LWM2M_CONTENT_TEXT, NULL, 0, contextP->monitorUserData);
        }
        registration_freeClient(clientP);
        result = COAP_202_DELETED;
    }
    break;

    default:
        return COAP_400_BAD_REQUEST;
    }

    return result;
}