From 02dd484ff245da74db26ed03c78b0338d5211d4c Mon Sep 17 00:00:00 2001 From: Sam Kumar Date: Sat, 25 Aug 2018 22:15:45 -0700 Subject: [PATCH 1/6] Fix bug in CoAP retransmission policy --- os/net/app-layer/coap/coap-transactions.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/os/net/app-layer/coap/coap-transactions.c b/os/net/app-layer/coap/coap-transactions.c index 7e34d22e4..a62e8d21f 100644 --- a/os/net/app-layer/coap/coap-transactions.c +++ b/os/net/app-layer/coap/coap-transactions.c @@ -98,12 +98,11 @@ coap_send_transaction(coap_transaction_t *t) { LOG_DBG("Sending transaction %u\n", t->mid); - coap_sendto(&t->endpoint, t->message, t->message_len); - if(COAP_TYPE_CON == ((COAP_HEADER_TYPE_MASK & t->message[0]) >> COAP_HEADER_TYPE_POSITION)) { - if(t->retrans_counter < COAP_MAX_RETRANSMIT) { + if(t->retrans_counter <= COAP_MAX_RETRANSMIT) { /* not timed out yet */ + coap_sendto(&t->endpoint, t->message, t->message_len); LOG_DBG("Keeping transaction %u\n", t->mid); if(t->retrans_counter == 0) { @@ -138,6 +137,7 @@ coap_send_transaction(coap_transaction_t *t) } } } else { + coap_sendto(&t->endpoint, t->message, t->message_len); coap_clear_transaction(t); } } From a73822176ad0a8ce321d0f6460a07721cf6a8d83 Mon Sep 17 00:00:00 2001 From: Nicolas Tsiftes Date: Mon, 20 Aug 2018 14:07:14 +0200 Subject: [PATCH 2/6] Check element size when parsing tokens. --- os/storage/antelope/aql-lexer.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/os/storage/antelope/aql-lexer.c b/os/storage/antelope/aql-lexer.c index 4bdefecf2..0510385b5 100644 --- a/os/storage/antelope/aql-lexer.c +++ b/os/storage/antelope/aql-lexer.c @@ -207,6 +207,10 @@ next_string(lexer_t *lexer, const char *s) *lexer->token = STRING_VALUE; lexer->input = end + 1; /* Skip the closing delimiter. */ + if(length > DB_MAX_ELEMENT_SIZE - 1) { + length = DB_MAX_ELEMENT_SIZE - 1; + } + memcpy(lexer->value, s, length); (*lexer->value)[length] = '\0'; @@ -236,6 +240,10 @@ next_token(lexer_t *lexer, const char *s) *lexer->token = IDENTIFIER; + if(length > DB_MAX_ELEMENT_SIZE - 1) { + length = DB_MAX_ELEMENT_SIZE - 1; + } + memcpy(lexer->value, s, length); (*lexer->value)[length] = '\0'; From f9bc65eab2b416152f06590f8b620904bfd1aae2 Mon Sep 17 00:00:00 2001 From: Nicolas Tsiftes Date: Mon, 20 Aug 2018 15:00:10 +0200 Subject: [PATCH 3/6] Enhanced LVM error checking. --- os/storage/antelope/aql-parser.c | 22 +++-- os/storage/antelope/lvm.c | 151 ++++++++++++++++++++----------- os/storage/antelope/lvm.h | 30 +++--- os/storage/antelope/relation.c | 4 +- 4 files changed, 132 insertions(+), 75 deletions(-) diff --git a/os/storage/antelope/aql-parser.c b/os/storage/antelope/aql-parser.c index 503833b0a..f65a8a6ce 100644 --- a/os/storage/antelope/aql-parser.c +++ b/os/storage/antelope/aql-parser.c @@ -269,8 +269,10 @@ PARSER(operand) NEXT; switch(TOKEN) { case IDENTIFIER: - lvm_register_variable(VALUE, LVM_LONG); - lvm_set_variable(&p, VALUE); + if(LVM_ERROR(lvm_register_variable(VALUE, LVM_LONG)) || + LVM_ERROR(lvm_set_variable(&p, VALUE))) { + RETURN(SYNTAX_ERROR); + } AQL_ADD_PROCESSING_ATTRIBUTE(adt, VALUE); break; case STRING_VALUE: @@ -278,7 +280,9 @@ PARSER(operand) case FLOAT_VALUE: break; case INTEGER_VALUE: - lvm_set_long(&p, *(long *)lexer->value); + if(LVM_ERROR(lvm_set_long(&p, *(long *)lexer->value))) { + RETURN(SYNTAX_ERROR); + } break; default: RETURN(SYNTAX_ERROR); @@ -340,7 +344,9 @@ PARSER(expr) default: RETURN(SYNTAX_ERROR); } - lvm_set_op(&p, op); + if(LVM_ERROR(lvm_set_op(&p, op))) { + RETURN(SYNTAX_ERROR); + } lvm_set_end(&p, saved_end); } @@ -389,7 +395,9 @@ PARSER(comparison) RETURN(SYNTAX_ERROR); } - lvm_set_relation(&p, rel); + if(LVM_ERROR(lvm_set_relation(&p, rel))) { + RETURN(SYNTAX_ERROR); + } lvm_set_end(&p, saved_end); if(!PARSE(expr)) { @@ -422,7 +430,9 @@ PARSER(where) connective = TOKEN == AND ? LVM_AND : LVM_OR; saved_end = lvm_shift_for_operator(&p, saved_end); - lvm_set_relation(&p, connective); + if(LVM_ERROR(lvm_set_relation(&p, connective))) { + RETURN(SYNTAX_ERROR); + } lvm_set_end(&p, saved_end); NEXT; diff --git a/os/storage/antelope/lvm.c b/os/storage/antelope/lvm.c index 731da1622..7abed8d27 100644 --- a/os/storage/antelope/lvm.c +++ b/os/storage/antelope/lvm.c @@ -82,10 +82,10 @@ typedef struct derivation derivation_t; /* Registered variables for a LVM expression. Their values may be changed between executions of the expression. */ -static variable_t variables[LVM_MAX_VARIABLE_ID - 1]; +static variable_t variables[LVM_MAX_VARIABLE_ID]; /* Range derivations of variables that are used for index searches. */ -static derivation_t derivations[LVM_MAX_VARIABLE_ID - 1]; +static derivation_t derivations[LVM_MAX_VARIABLE_ID]; #if DEBUG static void @@ -187,7 +187,7 @@ eval_expr(lvm_instance_t *p, operator_t op, operand_t *result) get_operand(p, &operand[i]); break; default: - return SEMANTIC_ERROR; + return LVM_SEMANTIC_ERROR; } value[i] = operand_to_long(&operand[i]); } @@ -204,18 +204,18 @@ eval_expr(lvm_instance_t *p, operator_t op, operand_t *result) break; case LVM_DIV: if(value[1] == 0) { - return MATH_ERROR; + return LVM_MATH_ERROR; } result_value = value[0] / value[1]; break; default: - return EXECUTION_ERROR; + return LVM_EXECUTION_ERROR; } result->type = LVM_LONG; result->value.l = result_value; - return TRUE; + return LVM_TRUE; } static int @@ -236,7 +236,7 @@ eval_logic(lvm_instance_t *p, operator_t *op) for(i = 0; i < arguments; i++) { type = get_type(p); if(type != LVM_CMP_OP) { - return SEMANTIC_ERROR; + return LVM_SEMANTIC_ERROR; } operator = get_operator(p); logic_result[i] = eval_logic(p, operator); @@ -248,9 +248,9 @@ eval_logic(lvm_instance_t *p, operator_t *op) if(*op == LVM_NOT) { return !logic_result[0]; } else if(*op == LVM_AND) { - return logic_result[0] == TRUE && logic_result[1] == TRUE; + return logic_result[0] == LVM_TRUE && logic_result[1] == LVM_TRUE; } else { - return logic_result[0] == TRUE || logic_result[1] == TRUE; + return logic_result[0] == LVM_TRUE || logic_result[1] == LVM_TRUE; } } @@ -268,7 +268,7 @@ eval_logic(lvm_instance_t *p, operator_t *op) get_operand(p, &operand); break; default: - return SEMANTIC_ERROR; + return LVM_SEMANTIC_ERROR; } result[i] = operand_to_long(&operand); } @@ -294,7 +294,7 @@ eval_logic(lvm_instance_t *p, operator_t *op) break; } - return EXECUTION_ERROR; + return LVM_EXECUTION_ERROR; } void @@ -334,7 +334,8 @@ lvm_shift_for_operator(lvm_instance_t *p, lvm_ip_t end) old_end = p->end; - if(p->end + sizeof(operator_t) > p->size || end >= old_end) { + if(p->end + sizeof(operator_t) + sizeof(node_type_t) > p->size || + end >= old_end) { p->error = __LINE__; return 0; } @@ -369,13 +370,6 @@ lvm_set_end(lvm_instance_t *p, lvm_ip_t end) return old_end; } -void -lvm_set_type(lvm_instance_t *p, node_type_t type) -{ - *(node_type_t *)(p->code + p->end) = type; - p->end += sizeof(type); -} - lvm_status_t lvm_execute(lvm_instance_t *p) { @@ -384,14 +378,14 @@ lvm_execute(lvm_instance_t *p) lvm_status_t status; p->ip = 0; - status = EXECUTION_ERROR; + status = LVM_EXECUTION_ERROR; type = get_type(p); switch(type) { case LVM_CMP_OP: operator = get_operator(p); status = eval_logic(p, operator); if(!LVM_ERROR(status)) { - PRINTF("The statement is %s\n", status == TRUE ? "true" : "false"); + PRINTF("The statement is %s\n", status == LVM_TRUE ? "true" : "false"); } else { PRINTF("Execution error: %d\n", (int)status); } @@ -403,31 +397,80 @@ lvm_execute(lvm_instance_t *p) return status; } -void +lvm_status_t +lvm_set_type(lvm_instance_t *p, node_type_t type) +{ + if(p->end + sizeof(node_type_t) >= DB_VM_BYTECODE_SIZE) { + PRINTF("Error: overflow in lvm_set_type\n"); + return LVM_STACK_OVERFLOW; + } + + *(node_type_t *)(p->code + p->end) = type; + p->end += sizeof(type); + return LVM_TRUE; +} + +lvm_status_t lvm_set_op(lvm_instance_t *p, operator_t op) { - lvm_set_type(p, LVM_ARITH_OP); + lvm_status_t status; + + status = lvm_set_type(p, LVM_ARITH_OP); + if(status != LVM_TRUE) { + return status; + } + + if(p->end + sizeof(op) >= DB_VM_BYTECODE_SIZE) { + PRINTF("Error: overflow in lvm_set_op\n"); + return LVM_STACK_OVERFLOW; + } + memcpy(&p->code[p->end], &op, sizeof(op)); p->end += sizeof(op); + return LVM_TRUE; } -void +lvm_status_t lvm_set_relation(lvm_instance_t *p, operator_t op) { - lvm_set_type(p, LVM_CMP_OP); + lvm_status_t status; + + status = lvm_set_type(p, LVM_CMP_OP); + if(status != LVM_TRUE) { + return status; + } + + if(p->end + sizeof(op) >= DB_VM_BYTECODE_SIZE) { + PRINTF("Error: overflow in lvm_set_relation\n"); + return LVM_STACK_OVERFLOW; + } + memcpy(&p->code[p->end], &op, sizeof(op)); p->end += sizeof(op); + return LVM_TRUE; } -void +lvm_status_t lvm_set_operand(lvm_instance_t *p, operand_t *op) { - lvm_set_type(p, LVM_OPERAND); + lvm_status_t status; + + status = lvm_set_type(p, LVM_OPERAND); + if(status != LVM_TRUE) { + return status; + } + + if(p->end + sizeof(*op) >= DB_VM_BYTECODE_SIZE) { + PRINTF("Error: overflow in lvm_set_operand\n"); + return LVM_STACK_OVERFLOW; + } + memcpy(&p->code[p->end], op, sizeof(*op)); p->end += sizeof(*op); + return LVM_TRUE; } -void +lvm_status_t lvm_set_long(lvm_instance_t *p, long l) { operand_t op; @@ -435,7 +478,7 @@ lvm_set_long(lvm_instance_t *p, long l) op.type = LVM_LONG; op.value.l = l; - lvm_set_operand(p, &op); + return lvm_set_operand(p, &op); } lvm_status_t @@ -446,7 +489,7 @@ lvm_register_variable(char *name, operand_type_t type) id = lookup(name); if(id == LVM_MAX_VARIABLE_ID) { - return VARIABLE_LIMIT_REACHED; + return LVM_VARIABLE_LIMIT_REACHED; } var = &variables[id]; @@ -456,7 +499,7 @@ lvm_register_variable(char *name, operand_type_t type) var->type = type; } - return TRUE; + return LVM_TRUE; } lvm_status_t @@ -466,25 +509,28 @@ lvm_set_variable_value(char *name, operand_value_t value) id = lookup(name); if(id == LVM_MAX_VARIABLE_ID) { - return INVALID_IDENTIFIER; + return LVM_INVALID_IDENTIFIER; } + variables[id].value = value; - return TRUE; + return LVM_TRUE; } -void +lvm_status_t lvm_set_variable(lvm_instance_t *p, char *name) { operand_t op; variable_id_t id; id = lookup(name); - if(id < LVM_MAX_VARIABLE_ID) { - PRINTF("var id = %d\n", id); - op.type = LVM_VARIABLE; - op.value.id = id; - lvm_set_operand(p, &op); + if(id == LVM_MAX_VARIABLE_ID) { + return LVM_INVALID_IDENTIFIER; } + + PRINTF("var id = %d\n", id); + op.type = LVM_VARIABLE; + op.value.id = id; + return lvm_set_operand(p, &op); } void @@ -598,7 +644,7 @@ derive_relation(lvm_instance_t *p, derivation_t *local_derivations) derivation_t d2[LVM_MAX_VARIABLE_ID]; if(*operator != LVM_AND && *operator != LVM_OR) { - return DERIVATION_ERROR; + return LVM_DERIVATION_ERROR; } PRINTF("Attempting to infer ranges from a logical connective\n"); @@ -608,7 +654,7 @@ derive_relation(lvm_instance_t *p, derivation_t *local_derivations) if(LVM_ERROR(derive_relation(p, d1)) || LVM_ERROR(derive_relation(p, d2))) { - return DERIVATION_ERROR; + return LVM_DERIVATION_ERROR; } if(*operator == LVM_AND) { @@ -616,7 +662,7 @@ derive_relation(lvm_instance_t *p, derivation_t *local_derivations) } else if(*operator == LVM_OR) { create_union(local_derivations, d1, d2); } - return TRUE; + return LVM_TRUE; } for(i = 0; i < 2; i++) { @@ -626,18 +672,18 @@ derive_relation(lvm_instance_t *p, derivation_t *local_derivations) get_operand(p, &operand[i]); break; default: - return DERIVATION_ERROR; + return LVM_DERIVATION_ERROR; } } if(operand[0].type == LVM_VARIABLE && operand[1].type == LVM_VARIABLE) { - return DERIVATION_ERROR; + return LVM_DERIVATION_ERROR; } /* Determine which of the operands that is the variable. */ if(operand[0].type == LVM_VARIABLE) { if(operand[1].type == LVM_VARIABLE) { - return DERIVATION_ERROR; + return LVM_DERIVATION_ERROR; } variable_id = operand[0].value.id; value = &operand[1].value; @@ -647,7 +693,7 @@ derive_relation(lvm_instance_t *p, derivation_t *local_derivations) } if(variable_id >= LVM_MAX_VARIABLE_ID) { - return DERIVATION_ERROR; + return LVM_DERIVATION_ERROR; } PRINTF("variable id %d, value %ld\n", variable_id, *(long *)value); @@ -675,12 +721,12 @@ derive_relation(lvm_instance_t *p, derivation_t *local_derivations) derivation->max.l = value->l; break; default: - return DERIVATION_ERROR; + return LVM_DERIVATION_ERROR; } derivation->derived = 1; - return TRUE; + return LVM_TRUE; } lvm_status_t @@ -700,12 +746,12 @@ lvm_get_derived_range(lvm_instance_t *p, char *name, if(derivations[i].derived) { *min = derivations[i].min; *max = derivations[i].max; - return TRUE; + return LVM_TRUE; } - return DERIVATION_ERROR; + return LVM_DERIVATION_ERROR; } } - return INVALID_IDENTIFIER; + return LVM_INVALID_IDENTIFIER; } #if DEBUG @@ -755,7 +801,8 @@ print_operand(lvm_instance_t *p, lvm_ip_t index) switch(operand.type) { case LVM_VARIABLE: - if(operand.value.id >= LVM_MAX_VARIABLE_ID || variables[operand.value.id].name == NULL) { + if(operand.value.id >= LVM_MAX_VARIABLE_ID || + variables[operand.value.id].name == NULL) { PRINTF("var(id:%d):?? ", operand.value.id); } else { PRINTF("var(%s):%ld ", variables[operand.value.id].name, diff --git a/os/storage/antelope/lvm.h b/os/storage/antelope/lvm.h index 0969501d9..6b56d6bd1 100644 --- a/os/storage/antelope/lvm.h +++ b/os/storage/antelope/lvm.h @@ -45,16 +45,16 @@ #include "db-options.h" enum lvm_status { - FALSE = 0, - TRUE = 1, - INVALID_IDENTIFIER = 2, - SEMANTIC_ERROR = 3, - MATH_ERROR = 4, - STACK_OVERFLOW = 5, - TYPE_ERROR = 6, - VARIABLE_LIMIT_REACHED = 7, - EXECUTION_ERROR = 8, - DERIVATION_ERROR = 9 + LVM_FALSE = 0, + LVM_TRUE = 1, + LVM_INVALID_IDENTIFIER = 2, + LVM_SEMANTIC_ERROR = 3, + LVM_MATH_ERROR = 4, + LVM_STACK_OVERFLOW = 5, + LVM_TYPE_ERROR = 6, + LVM_VARIABLE_LIMIT_REACHED = 7, + LVM_EXECUTION_ERROR = 8, + LVM_DERIVATION_ERROR = 9 }; typedef enum lvm_status lvm_status_t; @@ -135,10 +135,10 @@ lvm_ip_t lvm_jump_to_operand(lvm_instance_t *p); lvm_ip_t lvm_shift_for_operator(lvm_instance_t *p, lvm_ip_t end); lvm_ip_t lvm_get_end(lvm_instance_t *p); lvm_ip_t lvm_set_end(lvm_instance_t *p, lvm_ip_t end); -void lvm_set_op(lvm_instance_t *p, operator_t op); -void lvm_set_relation(lvm_instance_t *p, operator_t op); -void lvm_set_operand(lvm_instance_t *p, operand_t *op); -void lvm_set_long(lvm_instance_t *p, long l); -void lvm_set_variable(lvm_instance_t *p, char *name); +lvm_status_t lvm_set_op(lvm_instance_t *p, operator_t op); +lvm_status_t lvm_set_relation(lvm_instance_t *p, operator_t op); +lvm_status_t lvm_set_operand(lvm_instance_t *p, operand_t *op); +lvm_status_t lvm_set_long(lvm_instance_t *p, long l); +lvm_status_t lvm_set_variable(lvm_instance_t *p, char *name); #endif /* LVM_H */ diff --git a/os/storage/antelope/relation.c b/os/storage/antelope/relation.c index c8757bf08..0e939a068 100644 --- a/os/storage/antelope/relation.c +++ b/os/storage/antelope/relation.c @@ -813,9 +813,9 @@ relation_process_select(void *handle_ptr) } } - wanted_result = TRUE; + wanted_result = LVM_TRUE; if(AQL_GET_FLAGS(adt) & AQL_FLAG_INVERSE_LOGIC) { - wanted_result = FALSE; + wanted_result = LVM_FALSE; } /* Check whether the given predicate is true for this tuple. */ From 196accb9b79d39029a9ee07d1191eedf9d588127 Mon Sep 17 00:00:00 2001 From: Nicolas Tsiftes Date: Mon, 20 Aug 2018 15:21:36 +0200 Subject: [PATCH 4/6] Check if too many relations are inserted. --- os/storage/antelope/aql-adt.c | 15 +++++++++++++++ os/storage/antelope/aql.h | 7 ++++--- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/os/storage/antelope/aql-adt.c b/os/storage/antelope/aql-adt.c index d78f3f3c5..e07bffd7a 100644 --- a/os/storage/antelope/aql-adt.c +++ b/os/storage/antelope/aql-adt.c @@ -90,6 +90,21 @@ aql_clear(aql_adt_t *adt) memset(adt->aggregators, 0, sizeof(adt->aggregators)); } +db_result_t +aql_add_relation(aql_adt_t *adt, const char *name) +{ + if(adt->relation_count >= AQL_RELATION_LIMIT) { + return DB_LIMIT_ERROR; + } + + strncpy(adt->relations[adt->relation_count], name, + sizeof(adt->relations[0]) - 1); + adt->relations[adt->relation_count][sizeof(adt->relations[0]) - 1] = '\0'; + adt->relation_count++; + + return DB_OK; +} + db_result_t aql_add_attribute(aql_adt_t *adt, char *name, domain_t domain, unsigned element_size, int processed_only) diff --git a/os/storage/antelope/aql.h b/os/storage/antelope/aql.h index ab29f7e5d..4b898c4ac 100644 --- a/os/storage/antelope/aql.h +++ b/os/storage/antelope/aql.h @@ -188,10 +188,10 @@ typedef struct aql_adt aql_adt_t; #define AQL_SET_FLAG(adt, flag) (((adt)->flags) |= (flag)) #define AQL_GET_FLAGS(adt) ((adt)->flags) -#define AQL_ADD_RELATION(adt, rel) \ - strcpy((adt)->relations[(adt)->relation_count++], (rel)) #define AQL_RELATION_COUNT(adt) ((adt)->relation_count) -#define AQL_ADD_ATTRIBUTE(adt, attr, dom, size) \ +#define AQL_ADD_RELATION(adt, name) \ + aql_add_relation(adt, name) +#define AQL_ADD_ATTRIBUTE(adt, attr, dom, size) \ aql_add_attribute(adt, attr, dom, size, 0) #define AQL_ADD_PROCESSING_ATTRIBUTE(adt, attr) \ aql_add_attribute((adt), (attr), DOMAIN_UNSPECIFIED, 0, 1) @@ -211,6 +211,7 @@ void lexer_rewind(lexer_t *); void aql_clear(aql_adt_t *adt); aql_status_t aql_parse(aql_adt_t *adt, char *query_string); +db_result_t aql_add_relation(aql_adt_t *adt, const char *name); db_result_t aql_add_attribute(aql_adt_t *adt, char *name, domain_t domain, unsigned element_size, int processed_only); From 7860ca5da037c1562793154a70a91a47cbe573de Mon Sep 17 00:00:00 2001 From: Nicolas Tsiftes Date: Mon, 20 Aug 2018 15:43:27 +0200 Subject: [PATCH 5/6] Set a larger default bytecode size since the example on the Contiki-NG wiki requires this. --- os/storage/antelope/db-options.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/os/storage/antelope/db-options.h b/os/storage/antelope/db-options.h index 2be415f4e..ca8587071 100644 --- a/os/storage/antelope/db-options.h +++ b/os/storage/antelope/db-options.h @@ -108,7 +108,7 @@ /* The maximum size of the LVM bytecode compiled from a single database query. */ #ifndef DB_VM_BYTECODE_SIZE -#define DB_VM_BYTECODE_SIZE 128 +#define DB_VM_BYTECODE_SIZE 256 #endif /* DB_VM_BYTECODE_SIZE */ /*----------------------------------------------------------------------------*/ From e19e67b510ccc88273e89fd4b1571625ddde59bb Mon Sep 17 00:00:00 2001 From: Kiril Petrov Date: Tue, 28 Aug 2018 23:38:05 -0700 Subject: [PATCH 6/6] Fix get_temp_value for lwm2m-ipso-object example Signed-off-by: Kiril Petrov --- os/services/ipso-objects/ipso-temperature.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/os/services/ipso-objects/ipso-temperature.c b/os/services/ipso-objects/ipso-temperature.c index c27d8b6ba..db550a5c5 100644 --- a/os/services/ipso-objects/ipso-temperature.c +++ b/os/services/ipso-objects/ipso-temperature.c @@ -74,8 +74,8 @@ static lwm2m_status_t get_temp_value(const ipso_sensor_t *s, int32_t *value) { #ifdef IPSO_TEMPERATURE - if(IPSO_TEMPERATURE.read_value == NULL || - IPSO_TEMPERATURE.read_value(value) != 0) { + if(IPSO_TEMPERATURE.read_value != NULL && + IPSO_TEMPERATURE.read_value(value) == 0) { return LWM2M_STATUS_OK; } #endif /* IPSO_TEMPERATURE */