예제 #1
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;
    }
}
예제 #2
0
coap_status_t object_read(lwm2m_context_t * contextP,
                          lwm2m_uri_t * uriP,
                          lwm2m_media_type_t * formatP,
                          uint8_t ** bufferP,
                          size_t * lengthP)
{
    coap_status_t result;
    lwm2m_data_t * dataP = NULL;
    int size = 0;

    result = object_readData(contextP, uriP, &size, &dataP);

    if (result == COAP_205_CONTENT)
    {
        *lengthP = lwm2m_data_serialize(uriP, size, dataP, formatP, bufferP);
        if (*lengthP == 0)
        {
            if (*formatP != LWM2M_CONTENT_TEXT
                || size != 1
                || dataP->type != LWM2M_TYPE_STRING
                || dataP->value.asBuffer.length != 0)
            {
                result = COAP_500_INTERNAL_SERVER_ERROR;
            }
        }
    }
    lwm2m_data_free(size, dataP);

    return result;
}
예제 #3
0
coap_status_t object_write(lwm2m_context_t * contextP,
                           lwm2m_uri_t * uriP,
                           lwm2m_media_type_t format,
                           uint8_t * buffer,
                           size_t length)
{
    coap_status_t result = NO_ERROR;
    lwm2m_object_t * targetP;
    lwm2m_data_t * dataP = NULL;
    int size = 0;

    targetP = (lwm2m_object_t *)LWM2M_LIST_FIND(contextP->objectList, uriP->objectId);
    if (NULL == targetP)
    {
        result = COAP_404_NOT_FOUND;
    }
    else if (NULL == targetP->writeFunc)
    {
        result = COAP_405_METHOD_NOT_ALLOWED;
    }
    else
    {
        size = lwm2m_data_parse(uriP, buffer, length, format, &dataP);
        if (size == 0)
        {
            result = COAP_406_NOT_ACCEPTABLE;
        }
    }
    if (result == NO_ERROR)
    {
        result = targetP->writeFunc(uriP->instanceId, size, dataP, targetP);
        lwm2m_data_free(size, dataP);
    }
    return result;
}
예제 #4
0
파일: data.c 프로젝트: bsinno/wakaama
void lwm2m_data_free(int size,
                     lwm2m_data_t * dataP)
{
    int i;

    LOG_ARG("size: %d", size);
    if (size == 0 || dataP == NULL) return;

    for (i = 0; i < size; i++)
    {
        switch (dataP[i].type)
        {
        case LWM2M_TYPE_MULTIPLE_RESOURCE:
        case LWM2M_TYPE_OBJECT_INSTANCE:
        case LWM2M_TYPE_OBJECT:
            lwm2m_data_free(dataP[i].value.asChildren.count, dataP[i].value.asChildren.array);
            break;

        case LWM2M_TYPE_STRING:
        case LWM2M_TYPE_OPAQUE:
            if (dataP[i].value.asBuffer.buffer != NULL)
            {
                lwm2m_free(dataP[i].value.asBuffer.buffer);
            }

        default:
            // do nothing
            break;
        }
    }
    lwm2m_free(dataP);
}
예제 #5
0
uint8_t object_checkReadable(lwm2m_context_t * contextP,
                             lwm2m_uri_t * uriP)
{
    coap_status_t result;
    lwm2m_object_t * targetP;
    lwm2m_data_t * dataP = NULL;
    int size;

    targetP = (lwm2m_object_t *)LWM2M_LIST_FIND(contextP->objectList, uriP->objectId);
    if (NULL == targetP) return COAP_404_NOT_FOUND;
    if (NULL == targetP->readFunc) return COAP_405_METHOD_NOT_ALLOWED;

    if (!LWM2M_URI_IS_SET_INSTANCE(uriP)) return COAP_205_CONTENT;

    if (NULL == lwm2m_list_find(targetP->instanceList, uriP->instanceId)) return COAP_404_NOT_FOUND;

    if (!LWM2M_URI_IS_SET_RESOURCE(uriP)) return COAP_205_CONTENT;

    size = 1;
    dataP = lwm2m_data_new(1);
    if (dataP == NULL) return COAP_500_INTERNAL_SERVER_ERROR;

    dataP->id = uriP->resourceId;

    result = targetP->readFunc(uriP->instanceId, &size, &dataP, targetP);
    lwm2m_data_free(1, dataP);

    return result;
}
예제 #6
0
파일: decode.c 프로젝트: weatherxm/wakaama
static void test_JSON(char * testBuf,
                      size_t testLen,
                      char * id)
{
    lwm2m_data_t * tlvP;
    int size;
    int length;
    uint8_t * buffer;
    lwm2m_media_type_t format = LWM2M_CONTENT_JSON;

    size = lwm2m_data_parse((uint8_t *)testBuf, testLen, format, &tlvP);
    if (size <= 0)
    {
        printf("\n\nJSON buffer %s decoding failed !\n", id);
        return;
    }
    else
        printf("\n\nJSON buffer %s decoding:\n", id);

    dump_tlv(stdout, size, tlvP, 0);
    length = lwm2m_data_serialize(size, tlvP, &format, &buffer);
    dump_json(buffer, length);
    lwm2m_data_free(size, tlvP);
    lwm2m_free(buffer);
}
예제 #7
0
void handle_value_changed(lwm2m_context_t * lwm2mH,
                          lwm2m_uri_t * uri,
                          const char * value,
                          size_t valueLength)
{
    lwm2m_object_t * object = (lwm2m_object_t *)LWM2M_LIST_FIND(lwm2mH->objectList, uri->objectId);

    if (NULL != object)
    {
        if (object->writeFunc != NULL)
        {
            lwm2m_data_t * dataP;
            int result;

            dataP = lwm2m_data_new(1);
            if (dataP == NULL)
            {
                fprintf(stderr, "Internal allocation failure !\n");
                return;
            }
            dataP->id = uri->resourceId;
            lwm2m_data_encode_nstring(value, valueLength, dataP);

            result = object->writeFunc(uri->instanceId, 1, dataP, object);
            if (COAP_405_METHOD_NOT_ALLOWED == result)
            {
                switch (uri->objectId)
                {
                case LWM2M_DEVICE_OBJECT_ID:
                    result = device_change(dataP, object);
                    break;
                default:
                    break;
                }
            }

            if (COAP_204_CHANGED != result)
            {
                fprintf(stderr, "Failed to change value!\n");
            }
            else
            {
                fprintf(stderr, "value changed!\n");
                lwm2m_resource_value_changed(lwm2mH, uri);
            }
            lwm2m_data_free(1, dataP);
            return;
        }
        else
        {
            fprintf(stderr, "write not supported for specified resource!\n");
        }
        return;
    }
    else
    {
        fprintf(stderr, "Object not found !\n");
    }
}
예제 #8
0
int64_t security_get_mode(lwm2m_object_t * obj, int instanceId){
    int64_t mode;
    int size = 1;
    lwm2m_data_t * dataP = lwm2m_data_new(size);
    dataP->id = 2; // security mode

    obj->readFunc(instanceId, &size, &dataP, obj);
    if (0 != lwm2m_data_decode_int(dataP,&mode))
    {
        lwm2m_data_free(size, dataP);
        return mode;
    }

    lwm2m_data_free(size, dataP);
    fprintf(stderr, "Unable to get security mode : use not secure mode");
    return LWM2M_SECURITY_MODE_NONE;
}
예제 #9
0
coap_status_t object_create(lwm2m_context_t * contextP,
                            lwm2m_uri_t * uriP,
                            lwm2m_media_type_t format,
                            uint8_t * buffer,
                            size_t length)
{
    lwm2m_object_t * targetP;
    lwm2m_data_t * dataP = NULL;
    int size = 0;
    uint8_t result;

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

    targetP = (lwm2m_object_t *)LWM2M_LIST_FIND(contextP->objectList, uriP->objectId);
    if (NULL == targetP) return COAP_404_NOT_FOUND;
    if (NULL == targetP->createFunc) return COAP_405_METHOD_NOT_ALLOWED;

    size = lwm2m_data_parse(uriP, buffer, length, format, &dataP);
    if (size <= 0) return COAP_400_BAD_REQUEST;

    switch (dataP[0].type)
    {
    case LWM2M_TYPE_OBJECT:
        result = COAP_400_BAD_REQUEST;
        goto exit;

    case LWM2M_TYPE_OBJECT_INSTANCE:
        if (size != 1)
        {
            result = COAP_400_BAD_REQUEST;
            goto exit;
        }
        if (NULL != lwm2m_list_find(targetP->instanceList, dataP[0].id))
        {
            // Instance already exists
            result = COAP_406_NOT_ACCEPTABLE;
            goto exit;
        }
        result = targetP->createFunc(dataP[0].id, dataP[0].value.asChildren.count, dataP[0].value.asChildren.array, targetP);
        uriP->instanceId = dataP[0].id;
        uriP->flag |= LWM2M_URI_FLAG_INSTANCE_ID;
        break;

    default:
        uriP->instanceId = lwm2m_list_newId(targetP->instanceList);
        uriP->flag |= LWM2M_URI_FLAG_INSTANCE_ID;
        result = targetP->createFunc(uriP->instanceId, size, dataP, targetP);
        break;
    }

exit:
    lwm2m_data_free(size, dataP);

    return result;
}
예제 #10
0
/********************* Security Obj Helpers **********************/
char * security_get_uri(lwm2m_object_t * obj, int instanceId, char * uriBuffer, int bufferSize){
    int size = 1;
    lwm2m_data_t * dataP = lwm2m_data_new(size);
    dataP->id = 0; // security server uri

    obj->readFunc(instanceId, &size, &dataP, obj);
    if (dataP != NULL &&
            dataP->type == LWM2M_TYPE_STRING &&
            dataP->value.asBuffer.length > 0)
    {
        if (bufferSize > dataP->value.asBuffer.length){
            memset(uriBuffer,0,dataP->value.asBuffer.length+1);
            strncpy(uriBuffer,dataP->value.asBuffer.buffer,dataP->value.asBuffer.length);
            lwm2m_data_free(size, dataP);
            return uriBuffer;
        }
    }
    lwm2m_data_free(size, dataP);
    return NULL;
}
예제 #11
0
파일: objects.c 프로젝트: weatherxm/wakaama
coap_status_t object_write(lwm2m_context_t * contextP,
                           lwm2m_uri_t * uriP,
                           lwm2m_media_type_t format,
                           uint8_t * buffer,
                           size_t length)
{
    coap_status_t result = NO_ERROR;
    lwm2m_object_t * targetP;
    lwm2m_data_t * dataP = NULL;
    int size = 0;

    targetP = prv_find_object(contextP, uriP->objectId);
    if (NULL == targetP)
    {
        result = NOT_FOUND_4_04;
    }
    else if (NULL == targetP->writeFunc)
    {
        result = METHOD_NOT_ALLOWED_4_05;
    }
    else
    {
        if (LWM2M_URI_IS_SET_RESOURCE(uriP))
        {
            size = 1;
            dataP = lwm2m_data_new(size);
            if (dataP == NULL)
            {
                return COAP_500_INTERNAL_SERVER_ERROR;
            }

            dataP->flags = LWM2M_TLV_FLAG_TEXT_FORMAT | LWM2M_TLV_FLAG_STATIC_DATA;
            dataP->type = LWM2M_TYPE_RESOURCE;
            dataP->id = uriP->resourceId;
            dataP->length = length;
            dataP->value = (uint8_t *)buffer;
        }
        else
        {
            size = lwm2m_data_parse(buffer, length, format, &dataP);
            if (size == 0)
            {
                result = COAP_500_INTERNAL_SERVER_ERROR;
            }
        }
    }
    if (result == NO_ERROR)
    {
        result = targetP->writeFunc(uriP->instanceId, size, dataP, targetP);
        lwm2m_data_free(size, dataP);
    }
    return result;
}
예제 #12
0
파일: objects.c 프로젝트: jollen/node-wot
static int ICACHE_FLASH_ATTR
prv_getMandatoryInfo(lwm2m_object_t * objectP,
                                uint16_t instanceID,
                                lwm2m_server_t * targetP)
{
    lwm2m_data_t * dataP;
    int size;
    int64_t value;

    size = 2;
    dataP = lwm2m_data_new(size);
    if (dataP == NULL) return -1;
    dataP[0].id = LWM2M_SERVER_LIFETIME_ID;
    dataP[1].id = LWM2M_SERVER_BINDING_ID;

    if (objectP->readFunc(instanceID, &size, &dataP, objectP) != COAP_205_CONTENT)
    {
        lwm2m_data_free(size, dataP);
        return -1;
    }

    if (0 == lwm2m_data_decode_int(dataP, &value)
     || value < 0 || value >0xFFFFFFFF)             // This is an implementation limit
    {
        lwm2m_data_free(size, dataP);
        return -1;
    }
    targetP->lifetime = value;

    targetP->binding = lwm2m_stringToBinding(dataP[1].value, dataP[1].length);

    lwm2m_data_free(size, dataP);

    if (targetP->binding == BINDING_UNKNOWN)
    {
        return -1;
    }

    return 0;
}
예제 #13
0
파일: objects.c 프로젝트: jollen/node-wot
static lwm2m_list_t * ICACHE_FLASH_ATTR
prv_findServerInstance(lwm2m_object_t * objectP,
                                             uint16_t shortID)
{
    lwm2m_list_t * instanceP;

    instanceP = objectP->instanceList;
    while (NULL != instanceP)
    {
        int64_t value;
        lwm2m_data_t * dataP;
        int size;

        size = 1;
        dataP = lwm2m_data_new(size);
        if (dataP == NULL) return NULL;
        dataP->id = LWM2M_SERVER_SHORT_ID_ID;

        if (objectP->readFunc(instanceP->id, &size, &dataP, objectP) != COAP_205_CONTENT)
        {
            lwm2m_data_free(size, dataP);
            return NULL;
        }

        if (1 == lwm2m_data_decode_int(dataP, &value))
        {
            if (value == shortID)
            {
                lwm2m_data_free(size, dataP);
                break;
            }
        }
        lwm2m_data_free(size, dataP);
        instanceP = instanceP->next;
    }

    return instanceP;
}
예제 #14
0
int64_t security_get_mode(lwm2m_object_t * obj, int instanceId){
    int size = 1;
    lwm2m_data_t * dataP = lwm2m_data_new(size);
    dataP->id = 2; // security mode

    obj->readFunc(instanceId, &size, &dataP, obj);
    if (dataP != NULL &&
            dataP->dataType == LWM2M_TYPE_INTEGER &&
            dataP->type == LWM2M_TYPE_RESOURCE &&
            dataP->length > 0)
    {
        int64_t mode;
        if (0 != lwm2m_data_decode_int(dataP,&mode))
        {
            lwm2m_data_free(size, dataP);
            return mode;
        }
    }

    lwm2m_data_free(size, dataP);
    printf("Unable to get security mode : use not secure mode");
    return LWM2M_SECURITY_MODE_NONE;
}
예제 #15
0
파일: objects.c 프로젝트: jollen/node-wot
coap_status_t ICACHE_FLASH_ATTR
object_create(lwm2m_context_t * contextP,
                            lwm2m_uri_t * uriP,
                            lwm2m_media_type_t format,
                            uint8_t * buffer,
                            size_t length)
{
    lwm2m_object_t * targetP;
    lwm2m_data_t * dataP = NULL;
    int size = 0;
    uint8_t result;

    if (length == 0 || buffer == 0)
    {
        return BAD_REQUEST_4_00;
    }

    targetP = prv_find_object(contextP, uriP->objectId);
    if (NULL == targetP) return NOT_FOUND_4_04;
    if (NULL == targetP->createFunc) return METHOD_NOT_ALLOWED_4_05;

    if (LWM2M_URI_IS_SET_INSTANCE(uriP))
    {
        if (NULL != lwm2m_list_find(targetP->instanceList, uriP->instanceId))
        {
            // Instance already exists
            return COAP_406_NOT_ACCEPTABLE;
        }
    }
    else
    {
        uriP->instanceId = lwm2m_list_newId(targetP->instanceList);
        uriP->flag |= LWM2M_URI_FLAG_INSTANCE_ID;
    }

    size = lwm2m_data_parse(buffer, length, format, &dataP);
    if (size == 0) return COAP_500_INTERNAL_SERVER_ERROR;
#ifdef ICACHE_FLASH_ATTR
    if (contextP->bsState == BOOTSTRAP_PENDING)
    {
        dataP->flags |= LWM2M_TLV_FLAG_BOOTSTRAPPING;
    }
#endif
    result = targetP->createFunc(uriP->instanceId, size, dataP, targetP);
    lwm2m_data_free(size, dataP);

    return result;
}
예제 #16
0
파일: decode.c 프로젝트: weatherxm/wakaama
static void test_TLV(char * testBuf,
                     size_t testLen,
                     char * id)
{
    lwm2m_data_t * tlvP;
    int size;
    int length;
    uint8_t * buffer;
    lwm2m_media_type_t format = LWM2M_CONTENT_TLV;

    printf("Buffer %s:\n", id);
    decode(testBuf, testLen, 0);
    printf("\n\nBuffer %s using lwm2m_data_t:\n", id);
    size = lwm2m_data_parse((uint8_t *)testBuf, testLen, format, &tlvP);
    dump_tlv(stdout, size, tlvP, 0);
    length = lwm2m_data_serialize(size, tlvP, &format, &buffer);
    if (length != testLen)
    {
        printf("\n\nSerialize Buffer %s to TLV failed: %d bytes instead of %d\n", id, length, testLen);
    }
    else if (memcmp(buffer, testBuf, length) != 0)
    {
        printf("\n\nSerialize Buffer %s to TLV failed:\n", id);
        output_buffer(stdout, buffer, length, 0);
        printf("\ninstead of:\n");
        output_buffer(stdout, testBuf, length, 0);
    }
    else
    {
        printf("\n\nSerialize Buffer %s to TLV OK\n", id);
    }
    lwm2m_free(buffer);
    format = LWM2M_CONTENT_JSON;
    length = lwm2m_data_serialize(size, tlvP, &format, &buffer);
    if (length <= 0)
    {
        printf("\n\nSerialize Buffer %s to JSON failed.\n", id);
    }
    else
    {
        dump_json(buffer, length);
        lwm2m_free(buffer);
    }
    lwm2m_data_free(size, tlvP);
}
예제 #17
0
파일: objects.c 프로젝트: mhshami01/wakaama
coap_status_t object_create(lwm2m_context_t * contextP,
                            lwm2m_uri_t * uriP,
                            lwm2m_media_type_t format,
                            uint8_t * buffer,
                            size_t length)
{
    lwm2m_object_t * targetP;
    lwm2m_data_t * dataP = NULL;
    int size = 0;
    uint8_t result;

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

    targetP = (lwm2m_object_t *)LWM2M_LIST_FIND(contextP->objectList, uriP->objectId);
    if (NULL == targetP) return COAP_404_NOT_FOUND;
    if (NULL == targetP->createFunc) return COAP_405_METHOD_NOT_ALLOWED;

    if (LWM2M_URI_IS_SET_INSTANCE(uriP))
    {
        if (NULL != lwm2m_list_find(targetP->instanceList, uriP->instanceId))
        {
            // Instance already exists
            return COAP_406_NOT_ACCEPTABLE;
        }
    }
    else
    {
        uriP->instanceId = lwm2m_list_newId(targetP->instanceList);
        uriP->flag |= LWM2M_URI_FLAG_INSTANCE_ID;
    }

    size = lwm2m_data_parse(uriP, buffer, length, format, &dataP);
    if (size == 0) return COAP_500_INTERNAL_SERVER_ERROR;
    result = targetP->createFunc(uriP->instanceId, size, dataP, targetP);
    lwm2m_data_free(size, dataP);

    return result;
}
예제 #18
0
파일: objects.c 프로젝트: mhshami01/wakaama
coap_status_t object_read(lwm2m_context_t * contextP,
                          lwm2m_uri_t * uriP,
                          lwm2m_media_type_t * formatP,
                          uint8_t ** bufferP,
                          size_t * lengthP)
{
    coap_status_t result;
    lwm2m_data_t * dataP = NULL;
    int size = 0;

    result = object_readData(contextP, uriP, &size, &dataP);

    if (result == COAP_205_CONTENT)
    {
        *lengthP = lwm2m_data_serialize(uriP, size, dataP, formatP, bufferP);
        if (*lengthP == 0) result = COAP_500_INTERNAL_SERVER_ERROR;
    }
    lwm2m_data_free(size, dataP);

    return result;
}
예제 #19
0
uint8_t object_checkNumeric(lwm2m_context_t * contextP,
                            lwm2m_uri_t * uriP)
{
    coap_status_t result;
    lwm2m_object_t * targetP;
    lwm2m_data_t * dataP = NULL;
    int size;

    if (!LWM2M_URI_IS_SET_RESOURCE(uriP)) return COAP_405_METHOD_NOT_ALLOWED;

    targetP = (lwm2m_object_t *)LWM2M_LIST_FIND(contextP->objectList, uriP->objectId);
    if (NULL == targetP) return COAP_404_NOT_FOUND;
    if (NULL == targetP->readFunc) return COAP_405_METHOD_NOT_ALLOWED;

    size = 1;
    dataP = lwm2m_data_new(1);
    if (dataP == NULL) return COAP_500_INTERNAL_SERVER_ERROR;

    dataP->id = uriP->resourceId;

    result = targetP->readFunc(uriP->instanceId, &size, &dataP, targetP);
    if (result == COAP_205_CONTENT)
    {
        switch (dataP->type)
        {
        case LWM2M_TYPE_INTEGER:
        case LWM2M_TYPE_FLOAT:
            break;
        default:
            result = COAP_405_METHOD_NOT_ALLOWED;
        }
    }

    lwm2m_data_free(1, dataP);

    return result;
}
예제 #20
0
char * security_get_secret_key(lwm2m_object_t * obj, int instanceId, int * length){
    int size = 1;
    lwm2m_data_t * dataP = lwm2m_data_new(size);
    dataP->id = 5; // secret key

    obj->readFunc(instanceId, &size, &dataP, obj);
    if (dataP != NULL &&
        dataP->type == LWM2M_TYPE_OPAQUE)
    {
        char * buff;

        buff = (char*)lwm2m_malloc(dataP->value.asBuffer.length);
        if (buff != 0)
        {
            memcpy(buff, dataP->value.asBuffer.buffer, dataP->value.asBuffer.length);
            *length = dataP->value.asBuffer.length;
        }
        lwm2m_data_free(size, dataP);

        return buff;
    } else {
        return NULL;
    }
}
예제 #21
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;
}
예제 #22
0
int object_getServers(lwm2m_context_t * contextP)
{
    lwm2m_object_t * objectP;
    lwm2m_object_t * securityObjP = NULL;
    lwm2m_object_t * serverObjP = NULL;
    lwm2m_list_t * securityInstP;   // instanceID of the server in the LWM2M Security Object

    for (objectP = contextP->objectList; objectP != NULL; objectP = objectP->next)
    {
        if (objectP->objID == LWM2M_SECURITY_OBJECT_ID)
        {
            securityObjP = objectP;
        }
        else if (objectP->objID == LWM2M_SERVER_OBJECT_ID)
        {
            serverObjP = objectP;
        }
    }

    if (NULL == securityObjP) return -1;

    securityInstP = securityObjP->instanceList;
    while (securityInstP != NULL)
    {
        if (LWM2M_LIST_FIND(contextP->bootstrapServerList, securityInstP->id) == NULL
         && LWM2M_LIST_FIND(contextP->serverList, securityInstP->id) == NULL)
        {
            // This server is new. eg created by last bootstrap

            lwm2m_data_t * dataP;
            int size;
            lwm2m_server_t * targetP;
            bool isBootstrap;
            int64_t value = 0;

            size = 3;
            dataP = lwm2m_data_new(size);
            if (dataP == NULL) return -1;
            dataP[0].id = LWM2M_SECURITY_BOOTSTRAP_ID;
            dataP[1].id = LWM2M_SECURITY_SHORT_SERVER_ID;
            dataP[2].id = LWM2M_SECURITY_HOLD_OFF_ID;

            if (securityObjP->readFunc(securityInstP->id, &size, &dataP, securityObjP) != COAP_205_CONTENT)
            {
                lwm2m_data_free(size, dataP);
                return -1;
            }

            targetP = (lwm2m_server_t *)lwm2m_malloc(sizeof(lwm2m_server_t));
            if (targetP == NULL) {
                lwm2m_data_free(size, dataP);
                return -1;
            }
            memset(targetP, 0, sizeof(lwm2m_server_t));
            targetP->secObjInstID = securityInstP->id;

            if (0 == lwm2m_data_decode_bool(dataP + 0, &isBootstrap))
            {
                lwm2m_free(targetP);
                lwm2m_data_free(size, dataP);
                return -1;
            }

            if (0 == lwm2m_data_decode_int(dataP + 1, &value)
             || value < (isBootstrap ? 0 : 1) || value > 0xFFFF)                // 0 is forbidden as a Short Server ID
            {
                lwm2m_free(targetP);
                lwm2m_data_free(size, dataP);
                return -1;
            }
            targetP->shortID = value;

            if (isBootstrap == true)
            {
                if (0 == lwm2m_data_decode_int(dataP + 2, &value)
                 || value < 0 || value > 0xFFFFFFFF)             // This is an implementation limit
                {
                    lwm2m_free(targetP);
                    lwm2m_data_free(size, dataP);
                    return -1;
                }
                // lifetime of a bootstrap server is set to ClientHoldOffTime
                targetP->lifetime = value;

                contextP->bootstrapServerList = (lwm2m_server_t*)LWM2M_LIST_ADD(contextP->bootstrapServerList, targetP);
            }
            else
            {
                lwm2m_list_t * serverInstP;     // instanceID of the server in the LWM2M Server Object

                serverInstP = prv_findServerInstance(serverObjP, targetP->shortID);
                if (serverInstP == NULL)
                {
                    lwm2m_free(targetP);
                    lwm2m_data_free(size, dataP);
                    return -1;
                }
                if (0 != prv_getMandatoryInfo(serverObjP, serverInstP->id, targetP))
                {
                    lwm2m_free(targetP);
                    lwm2m_data_free(size, dataP);
                    return -1;
                }
                targetP->status = STATE_DEREGISTERED;
                contextP->serverList = (lwm2m_server_t*)LWM2M_LIST_ADD(contextP->serverList, targetP);
            }
            lwm2m_data_free(size, dataP);
        }
        securityInstP = securityInstP->next;
    }

    return 0;
}
예제 #23
0
coap_status_t object_discover(lwm2m_context_t * contextP,
                              lwm2m_uri_t * uriP,
                              uint8_t ** bufferP,
                              size_t * lengthP)
{
    coap_status_t result;
    lwm2m_object_t * targetP;
    lwm2m_data_t * dataP = NULL;
    int size = 0;

    targetP = (lwm2m_object_t *)LWM2M_LIST_FIND(contextP->objectList, uriP->objectId);
    if (NULL == targetP) return COAP_404_NOT_FOUND;
    if (NULL == targetP->discoverFunc) return COAP_501_NOT_IMPLEMENTED;
    if (targetP->instanceList == NULL) return COAP_404_NOT_FOUND;

    if (LWM2M_URI_IS_SET_INSTANCE(uriP))
    {
        if (NULL == lwm2m_list_find(targetP->instanceList, uriP->instanceId)) return COAP_404_NOT_FOUND;

        // single instance read
        if (LWM2M_URI_IS_SET_RESOURCE(uriP))
        {
            size = 1;
            dataP = lwm2m_data_new(size);
            if (dataP == NULL) return COAP_500_INTERNAL_SERVER_ERROR;

            dataP->id = uriP->resourceId;
            uriP->flag &= ~LWM2M_URI_FLAG_RESOURCE_ID;
        }

        result = targetP->discoverFunc(uriP->instanceId, &size, &dataP, targetP);
    }
    else
    {
        // multiple object instances read
        lwm2m_list_t * instanceP;
        int i;

        size = 0;
        for (instanceP = targetP->instanceList; instanceP != NULL ; instanceP = instanceP->next)
        {
            size++;
        }

        dataP = lwm2m_data_new(size);
        if (dataP == NULL) return COAP_500_INTERNAL_SERVER_ERROR;

        result = COAP_205_CONTENT;
        instanceP = targetP->instanceList;
        i = 0;
        while (instanceP != NULL && result == COAP_205_CONTENT)
        {
            result = targetP->discoverFunc(instanceP->id, (int*)&(dataP[i].value.asChildren.count), &(dataP[i].value.asChildren.array), targetP);
            dataP[i].type = LWM2M_TYPE_OBJECT_INSTANCE;
            dataP[i].id = instanceP->id;
            i++;
            instanceP = instanceP->next;
        }
    }

    if (result == COAP_205_CONTENT)
    {
        int len;

        len = discover_serialize(contextP, uriP, size, dataP, bufferP);
        if (len <= 0) result = COAP_500_INTERNAL_SERVER_ERROR;
        else *lengthP = len;
    }
    lwm2m_data_free(size, dataP);

    return result;
}
예제 #24
0
파일: objects.c 프로젝트: jollen/node-wot
coap_status_t ICACHE_FLASH_ATTR
object_read(lwm2m_context_t * contextP,
                          lwm2m_uri_t * uriP,
                          lwm2m_media_type_t * formatP,
                          uint8_t ** bufferP,
                          size_t * lengthP)
{
    coap_status_t result;
    lwm2m_object_t * targetP;
    lwm2m_data_t * dataP = NULL;
    int size = 0;

#ifdef ICACHE_FLASH_ATTR
    if (contextP->bsState == BOOTSTRAP_PENDING) return METHOD_NOT_ALLOWED_4_05;
#endif

    targetP = prv_find_object(contextP, uriP->objectId);
    if (NULL == targetP) return NOT_FOUND_4_04;
    if (NULL == targetP->readFunc) return METHOD_NOT_ALLOWED_4_05;
    if (targetP->instanceList == NULL)
    {
        // this is a single instance object
        if (LWM2M_URI_IS_SET_INSTANCE(uriP) && (uriP->instanceId != 0))
        {
            return COAP_404_NOT_FOUND;
        }
    }
    else
    {
        if (LWM2M_URI_IS_SET_INSTANCE(uriP))
        {
            if (NULL == lwm2m_list_find(targetP->instanceList, uriP->instanceId))
            {
                return COAP_404_NOT_FOUND;
            }
        }
        else
        {
            // multiple object instances read
            lwm2m_list_t * instanceP;
            int i;

            size = 0;
            for (instanceP = targetP->instanceList; instanceP != NULL ; instanceP = instanceP->next)
            {
                size++;
            }

            dataP = lwm2m_data_new(size);
            if (dataP == NULL) return COAP_500_INTERNAL_SERVER_ERROR;

            result = COAP_205_CONTENT;
            instanceP = targetP->instanceList;
            i = 0;
            while (instanceP != NULL && result == COAP_205_CONTENT)
            {
                result = targetP->readFunc(instanceP->id, (int*)&(dataP[i].length), (lwm2m_data_t **)&(dataP[i].value), targetP);
                dataP[i].type = LWM2M_TYPE_OBJECT_INSTANCE;
                dataP[i].id = instanceP->id;
                i++;
                instanceP = instanceP->next;
            }

            if (result == COAP_205_CONTENT)
            {
                *lengthP = lwm2m_data_serialize(size, dataP, formatP, bufferP);
                if (*lengthP == 0) result = COAP_500_INTERNAL_SERVER_ERROR;
            }
            lwm2m_data_free(size, dataP);

            return result;
        }
    }

    // single instance read
    if (LWM2M_URI_IS_SET_RESOURCE(uriP))
    {
        size = 1;
        dataP = lwm2m_data_new(size);
        if (dataP == NULL) return COAP_500_INTERNAL_SERVER_ERROR;

        dataP->type = LWM2M_TYPE_RESOURCE;
        dataP->flags = LWM2M_TLV_FLAG_TEXT_FORMAT;
        dataP->id = uriP->resourceId;
    }
    result = targetP->readFunc(uriP->instanceId, &size, &dataP, targetP);
    if (result == COAP_205_CONTENT)
    {
        if (size == 1
         && dataP->type == LWM2M_TYPE_RESOURCE
         && (dataP->flags && LWM2M_TLV_FLAG_TEXT_FORMAT) != 0 )
        {
            *bufferP = (uint8_t *)c_zalloc(dataP->length);
            if (*bufferP == NULL)
            {
                result = COAP_500_INTERNAL_SERVER_ERROR;
            }
            else
            {
                c_memcpy(*bufferP, dataP->value, dataP->length);
                *lengthP = dataP->length;
            }
        }
        else
        {
            *lengthP = lwm2m_data_serialize(size, dataP, formatP, bufferP);
            if (*lengthP == 0) result = COAP_500_INTERNAL_SERVER_ERROR;
        }
    }
    lwm2m_data_free(size, dataP);

    return result;
}
예제 #25
0
void handle_value_changed(lwm2m_context_t * lwm2mH,
                          lwm2m_uri_t * uri,
                          const char * value,
                          size_t valueLength)
{
    lwm2m_object_t * object = prv_find_object(lwm2mH, uri->objectId);

    if (NULL != object)
    {
        if (object->writeFunc != NULL)
        {
            lwm2m_data_t * dataP;
            int result;
            
            dataP = lwm2m_data_new(1);
            if (dataP == NULL)
            {
                fprintf(stderr, "Internal allocation failure !\n");
                return;
            }
            dataP->flags = LWM2M_TLV_FLAG_STATIC_DATA | LWM2M_TLV_FLAG_TEXT_FORMAT;
#ifdef LWM2M_BOOTSTRAP
            if (lwm2mH->bsState == BOOTSTRAP_PENDING) {
                dataP->flags |= LWM2M_TLV_FLAG_BOOTSTRAPPING;
            }
#endif
            dataP->id = uri->resourceId;
            dataP->length = valueLength;
            dataP->value = (uint8_t*) value;

            result = object->writeFunc(uri->instanceId, 1, dataP, object);
            if (COAP_405_METHOD_NOT_ALLOWED == result)
            {
                switch (uri->objectId)
                {
                case LWM2M_DEVICE_OBJECT_ID:
                    result = device_change(dataP, object);
                    break;
                default:
                    break;
                }
            }
            
            if (COAP_204_CHANGED != result)
            {
                fprintf(stderr, "Failed to change value!\n");
            }
            else
            {
                fprintf(stderr, "value changed!\n");
                lwm2m_resource_value_changed(lwm2mH, uri);
            }
            lwm2m_data_free(1, dataP);
            return;
        }
        else
        {
            fprintf(stderr, "write not supported for specified resource!\n");
        }
        return;
    }
    else
    {
        fprintf(stderr, "Object not found !\n");
    }
}
예제 #26
0
파일: objects.c 프로젝트: jollen/node-wot
coap_status_t ICACHE_FLASH_ATTR
object_write(lwm2m_context_t * contextP,
                           lwm2m_uri_t * uriP,
                           lwm2m_media_type_t format,
                           uint8_t * buffer,
                           size_t length)
{
    coap_status_t result = NO_ERROR;
    lwm2m_object_t * targetP;
    lwm2m_data_t * dataP = NULL;
    int size = 0;

    targetP = prv_find_object(contextP, uriP->objectId);
    if (NULL == targetP)
    {
        result = NOT_FOUND_4_04;
    }
    else if (NULL == targetP->writeFunc)
    {
        result = METHOD_NOT_ALLOWED_4_05;
    }
    else
    {
        if (LWM2M_URI_IS_SET_RESOURCE(uriP))
        {
            size = 1;
            dataP = lwm2m_data_new(size);
            if (dataP == NULL)
            {
                return COAP_500_INTERNAL_SERVER_ERROR;
            }

            dataP->flags = LWM2M_TLV_FLAG_TEXT_FORMAT | LWM2M_TLV_FLAG_STATIC_DATA;
            dataP->type = LWM2M_TYPE_RESOURCE;
            dataP->id = uriP->resourceId;
            dataP->length = length;
            dataP->value = (uint8_t *)buffer;
        }
        else
        {
            size = lwm2m_data_parse(buffer, length, format, &dataP);
            if (size == 0)
            {
                result = COAP_500_INTERNAL_SERVER_ERROR;
            }
        }
    }
    if (result == NO_ERROR)
    {
#ifdef ICACHE_FLASH_ATTR
        if (contextP->bsState == BOOTSTRAP_PENDING)
        {
            dataP->flags |= LWM2M_TLV_FLAG_BOOTSTRAPPING;
        }
#endif
        result = targetP->writeFunc(uriP->instanceId, size, dataP, targetP);
        lwm2m_data_free(size, dataP);
    }
#ifdef ICACHE_FLASH_ATTR
    if (contextP->bsState == BOOTSTRAP_PENDING)
    {
        if (result == COAP_204_CHANGED)
        {
            reset_bootstrap_timer(contextP);
        }
        else
        {
            bootstrap_failed(contextP);
        }
    }
#endif
    return result;
}
예제 #27
0
파일: management.c 프로젝트: bsinno/wakaama
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;
}
예제 #28
0
static int prv_add_server(bs_info_t * infoP,
                          read_server_t * dataP)
{
    lwm2m_data_t * tlvP;
    int size;
    bs_server_tlv_t * serverP;
    lwm2m_media_type_t format;

    switch (dataP->securityMode)
    {
    case LWM2M_SECURITY_MODE_NONE:
        size = 4;
        break;
    case LWM2M_SECURITY_MODE_PRE_SHARED_KEY:
        size = 6;
        break;
    case LWM2M_SECURITY_MODE_RAW_PUBLIC_KEY:
    case LWM2M_SECURITY_MODE_CERTIFICATE:
        size = 7;
        break;
    default:
        return -1;
    }

    serverP = (bs_server_tlv_t *)lwm2m_malloc(sizeof(bs_server_tlv_t));
    if (serverP == NULL) return -1;
    memset(serverP, 0, sizeof(bs_server_tlv_t));

    serverP->id = dataP->id;

    tlvP = lwm2m_data_new(size);
    if (tlvP == NULL) goto error;

    // LWM2M Server URI
    tlvP[0].id = LWM2M_SECURITY_URI_ID;
    lwm2m_data_encode_string(dataP->uri, tlvP);

    // Bootstrap Server
    tlvP[1].id = LWM2M_SECURITY_BOOTSTRAP_ID;
    lwm2m_data_encode_bool(dataP->isBootstrap, tlvP + 1);

    // Short Server ID
    tlvP[2].id = LWM2M_SECURITY_SHORT_SERVER_ID;
    lwm2m_data_encode_int(dataP->id, tlvP + 2);

    // Security Mode
    tlvP[3].id = LWM2M_SECURITY_SECURITY_ID;
    lwm2m_data_encode_int(dataP->securityMode, tlvP + 3);

    if (size > 4)
    {
        tlvP[4].id = LWM2M_SECURITY_PUBLIC_KEY_ID;
        lwm2m_data_encode_opaque(dataP->publicKey, dataP->publicKeyLen, tlvP + 4);

        tlvP[5].id = LWM2M_SECURITY_SECRET_KEY_ID;
        lwm2m_data_encode_opaque(dataP->secretKey, dataP->secretKeyLen, tlvP + 5);

        if (size == 7)
        {
            tlvP[6].id = LWM2M_SECURITY_SERVER_PUBLIC_KEY_ID;
            lwm2m_data_encode_opaque(dataP->serverKey, dataP->serverKeyLen, tlvP + 5);
        }
    }

    format = LWM2M_CONTENT_TLV;
    serverP->securityLen = lwm2m_data_serialize(NULL, size, tlvP, &format, &(serverP->securityData));
    if (serverP->securityLen <= 0) goto error;
    lwm2m_data_free(size, tlvP);

    if (dataP->isBootstrap == false)
    {
        size = 4;
        tlvP = lwm2m_data_new(size);
        if (tlvP == NULL) goto error;

        // Short Server ID
        tlvP[0].id = LWM2M_SERVER_SHORT_ID_ID;
        lwm2m_data_encode_int(dataP->id, tlvP);

        // Lifetime
        tlvP[1].id = LWM2M_SERVER_LIFETIME_ID;
        lwm2m_data_encode_int(dataP->lifetime, tlvP + 1);

        // Notification Storing
        tlvP[2].id = LWM2M_SERVER_STORING_ID;
        lwm2m_data_encode_bool(false, tlvP + 2);

        // Binding
        tlvP[3].id = LWM2M_SERVER_BINDING_ID;
        lwm2m_data_encode_string("U", tlvP + 3);

        serverP->serverLen = lwm2m_data_serialize(NULL, size, tlvP, &format, &(serverP->serverData));
        if (serverP->serverLen <= 0) goto error;
        lwm2m_data_free(size, tlvP);
    }

    infoP->serverList = (bs_server_tlv_t *)LWM2M_LIST_ADD(infoP->serverList, serverP);

    return 0;

error:
    if (tlvP != NULL) lwm2m_data_free(size, tlvP);
    if (serverP->securityData != NULL) lwm2m_free(serverP->securityData);
    if (serverP->serverData != NULL) lwm2m_free(serverP->serverData);
    lwm2m_free(serverP);

    return -1;
}
예제 #29
0
파일: json.c 프로젝트: alex8224/wakaama
static int prv_convertRecord(_record_t * recordArray,
                             int count,
                             lwm2m_data_t ** dataP)
{
    int index;
    int tlvIndex;
    lwm2m_data_t * tlvP;

    // may be overkill
    tlvP = lwm2m_data_new(count);
    if (NULL == tlvP) return -1;
    tlvIndex = 0;

    for (index = 0 ; index < count ; index++)
    {
        lwm2m_data_t * targetP;

        if (recordArray[index].resInstId == LWM2M_MAX_ID)
        {
            targetP = tlvP + tlvIndex;
            targetP->type = LWM2M_TYPE_RESOURCE;
            targetP->id = recordArray[index].resId;
            tlvIndex++;
        }
        else
        {
            int resIndex;

            resIndex = 0;
            while (resIndex < tlvIndex
                && tlvP[resIndex].id != recordArray[index].resId)
            {
                resIndex++;
            }
            if (resIndex == tlvIndex)
            {
                targetP = lwm2m_data_new(1);
                if (NULL == targetP) goto error;

                tlvP[resIndex].type = LWM2M_TYPE_MULTIPLE_RESOURCE;
                tlvP[resIndex].id = recordArray[index].resId;
                tlvP[resIndex].length = 1;
                tlvP[resIndex].value = (uint8_t *)targetP;

                tlvIndex++;
            }
            else
            {
                targetP = lwm2m_data_new(tlvP[resIndex].length + 1);
                if (NULL == targetP) goto error;

                memcpy(targetP + 1, tlvP[resIndex].value, tlvP[resIndex].length * sizeof(lwm2m_data_t));
                lwm2m_free(tlvP[resIndex].value);   // do not use lwm2m_data_free() to preserve value pointers
                tlvP[resIndex].value = (uint8_t *)targetP;
                tlvP[resIndex].length++;
            }

            targetP->type = LWM2M_TYPE_RESOURCE_INSTANCE;
            targetP->id = recordArray[index].resInstId;
        }
        switch (recordArray[index].type)
        {
        case _TYPE_FALSE:
            lwm2m_data_encode_bool(false, targetP);
            break;
        case _TYPE_TRUE:
            lwm2m_data_encode_bool(true, targetP);
            break;
        case _TYPE_FLOAT:
        {
            size_t i;

            i = 0;
            while (i < recordArray[index].valueLen
                && recordArray[index].value[i] != '.')
            {
                i++;
            }
            if (i == recordArray[index].valueLen)
            {
                int64_t value;

                if ( 1 != lwm2m_PlainTextToInt64(recordArray[index].value,
                                                 recordArray[index].valueLen,
                                                 &value))
                {
                    goto error;
                }

                lwm2m_data_encode_int(value, targetP);
            }
            else
            {
                double value;

                if ( 1 != lwm2m_PlainTextToFloat64(recordArray[index].value,
                                                   recordArray[index].valueLen,
                                                   &value))
                {
                    goto error;
                }

                lwm2m_data_encode_float(value, targetP);
            }
        }
        break;

            // TODO: Copy string instead of pointing to it
        case _TYPE_STRING:
            targetP->flags = LWM2M_TLV_FLAG_STATIC_DATA | LWM2M_TLV_FLAG_TEXT_FORMAT;
            targetP->dataType = LWM2M_TYPE_STRING;      // or opaque ?
            targetP->length = recordArray[index].valueLen;
            targetP->value = recordArray[index].value;
            break;

        case _TYPE_UNSET:
        default:
            goto error;
        }
    }

    *dataP = tlvP;
    return tlvIndex;

error:
    lwm2m_data_free(count, tlvP);
    return -1;
}
예제 #30
0
void observe_step(lwm2m_context_t * contextP,
                  time_t currentTime,
                  time_t * timeoutP)
{
    lwm2m_observed_t * targetP;

    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;
        lwm2m_media_type_t format = LWM2M_CONTENT_TEXT;
        coap_packet_t message[1];
        time_t interval;

        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)) continue;
                storeValue = true;
                break;
            case LWM2M_TYPE_FLOAT:
                if (1 != lwm2m_data_decode_float(dataP, &floatValue)) 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("observation_step(/%d/%d/%d) notify[1] = TRUE\n", targetP->uri.objectId, targetP->uri.instanceId, targetP->uri.resourceId);
                    }

                    if (notify == false
                     && watcherP->parameters != NULL
                     && (watcherP->parameters->toSet & ATTR_FLAG_NUMERIC) != 0)
                    {
                        if ((watcherP->parameters->toSet & LWM2M_ATTR_FLAG_LESS_THAN) != 0)
                        {
                            // Did we cross the lower treshold ?
                            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))
                                {
                                    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))
                                {
                                    notify = true;
                                }
                                break;
                            default:
                                break;
                            }
                            LOG("observation_step(/%d/%d/%d) notify[2] = %s\n", targetP->uri.objectId, targetP->uri.instanceId, targetP->uri.resourceId, notify ? "TRUE" : "FALSE");
                        }
                        if ((watcherP->parameters->toSet & LWM2M_ATTR_FLAG_GREATER_THAN) != 0)
                        {
                            // Did we cross the upper treshold ?
                            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))
                                {
                                    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))
                                {
                                    notify = true;
                                }
                                break;
                            default:
                                break;
                            }
                            LOG("observation_step(/%d/%d/%d) notify[3] = %s\n", targetP->uri.objectId, targetP->uri.instanceId, targetP->uri.resourceId, notify ? "TRUE" : "FALSE");
                        }
                        if ((watcherP->parameters->toSet & LWM2M_ATTR_FLAG_STEP) != 0)
                        {
                            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))
                                {
                                    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))
                                {
                                    notify = true;
                                }
                            }
                                break;
                            default:
                                break;
                            }
                            LOG("observation_step(/%d/%d/%d) notify[4] = %s\n", targetP->uri.objectId, targetP->uri.instanceId, targetP->uri.resourceId, notify? "TRUE" : "FALSE");
                        }
                    }

                    if (watcherP->parameters != NULL
                     && (watcherP->parameters->toSet & LWM2M_ATTR_FLAG_MIN_PERIOD) != 0)
                    {
                        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
                        {
                            notify = true;
                        }
                        LOG("observation_step(/%d/%d/%d) notify[5] = %s\n", targetP->uri.objectId, targetP->uri.instanceId, targetP->uri.resourceId, notify ? "TRUE" : "FALSE");
                    }
                }

                // Is the Maximum Period reached ?
                if (notify == false
                 && watcherP->parameters != NULL
                 && (watcherP->parameters->toSet & LWM2M_ATTR_FLAG_MAX_PERIOD) != 0)
                {
                    if (watcherP->lastTime + watcherP->parameters->maxPeriod <= currentTime)
                    {
                        notify = true;
                    }
                    LOG("observation_step(/%d/%d/%d) notify[6] = %s\n", targetP->uri.objectId, targetP->uri.instanceId, targetP->uri.resourceId, notify ? "TRUE" : "FALSE");
                }

                if (notify == true)
                {
                    if (buffer == NULL)
                    {
                        if (dataP != NULL)
                        {
                            length = lwm2m_data_serialize(&targetP->uri, size, dataP, &format, &buffer);
                            if (length == 0) break;
                        }
                        else
                        {
                            if (COAP_205_CONTENT != object_read(contextP, &targetP->uri, &format, &buffer, &length))
                            {
                                buffer = NULL;
                                break;
                            }
                        }
                        coap_init_message(message, COAP_TYPE_NON, COAP_205_CONTENT, 0);
                        coap_set_header_content_type(message, format);
                        coap_set_payload(message, buffer, length);
                        LOG("Observe Update[/%d/%d/%d]: %.*s\n", targetP->uri.objectId, targetP->uri.instanceId, targetP->uri.resourceId, length, buffer);
                    }
                    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);
    }
}