make: Client examples as individual projects

The client example projects now use Wakaama as a direct dependency. They
have also been split into three different projects (udp, tinydtls and
raw_block1). The CI and integration tests were adjusted for the new
project.
This commit is contained in:
Lukas Woodtli 2024-09-02 09:23:03 +02:00 committed by Lukas Woodtli
parent 1f57c8ea54
commit 9ee63a22ca
23 changed files with 2040 additions and 2902 deletions

View File

@ -42,7 +42,7 @@ jobs:
strategy:
matrix:
example: ["bootstrap_server", "client", "lightclient", "server"]
example: ["bootstrap_server", "client/udp", "client/tinydtls", "client/raw_block1", "lightclient", "server"]
steps:
- name: Checkout code including full history and submodules

View File

@ -45,7 +45,7 @@ jobs:
- name: Build examples for integration tests
run: |
for example in "server" "bootstrap_server"
for example in "server" "bootstrap_server" "client/udp"
do
echo "Building example ${example}"
tools/ci/run_ci.sh \

View File

@ -202,11 +202,11 @@ Options:
### Test client example
* ``cmake -S examples/client -B build-client -DWAKAAMA_MODE_CLIENT=ON``
* ``cmake --build build-client``
* ``./build-client/lwm2mclient [Options]``
* ``cmake -S examples/client/udp -B build-client-udp``
* ``cmake --build build-client-udp``
* ``./build-client-udp/lwm2mclient [Options]``
Next to lwm2mclient a DTLS enabled variant named lwm2mclient_tinydtls gets built.
Next to lwm2mclient there are also examples with DTLS enabled and with raw block1 transfer enabled.
The lwm2mclient features nine LWM2M objects:
- Security Object (id: 0)

View File

@ -2,5 +2,3 @@ cmake_minimum_required(VERSION 3.21)
# Our examples are designed for POSIX systems
add_compile_definitions(_POSIX_C_SOURCE=200809)
add_subdirectory(client)

View File

@ -1,51 +0,0 @@
cmake_minimum_required(VERSION 3.21)
project(lwm2mclient C)
include(../../wakaama.cmake)
if(WAKAAMA_ENABLE_EXAMPLES
AND WAKAAMA_MODE_CLIENT
AND WAKAAMA_CLIENT_INITIATED_BOOTSTRAP
AND WAKAAMA_DATA_SENML_JSON
)
set(SOURCES
lwm2mclient.c
lwm2mclient.h
object_access_control.c
object_connectivity_moni.c
object_connectivity_stat.c
object_device.c
object_firmware.c
object_location.c
object_security.c
object_server.c
object_test.c
system_api.c
)
# Client without DTLS support
add_executable(lwm2mclient ${SOURCES})
target_compile_definitions(lwm2mclient PRIVATE LWM2M_CLIENT_MODE LWM2M_BOOTSTRAP LWM2M_SUPPORT_SENML_JSON)
target_sources_wakaama(lwm2mclient)
target_sources_shared(lwm2mclient)
if(WAKAAMA_COAP_RAW_BLOCK1_REQUESTS)
# Client with raw block 1 requests and without DTLS support
add_executable(lwm2mclient_raw_block1 ${SOURCES})
target_compile_definitions(
lwm2mclient_raw_block1 PRIVATE LWM2M_CLIENT_MODE LWM2M_BOOTSTRAP LWM2M_SUPPORT_SENML_JSON
LWM2M_RAW_BLOCK1_REQUESTS
)
target_sources_wakaama(lwm2mclient_raw_block1)
target_sources_shared(lwm2mclient_raw_block1)
endif()
# Client with DTLS support provided by tinydtls
add_executable(lwm2mclient_tinydtls ${SOURCES})
set_target_properties(lwm2mclient_tinydtls PROPERTIES CONNECTION_IMPLEMENTATION "tinydtls")
target_compile_definitions(lwm2mclient_tinydtls PRIVATE LWM2M_CLIENT_MODE LWM2M_BOOTSTRAP LWM2M_SUPPORT_SENML_JSON)
target_sources_wakaama(lwm2mclient_tinydtls)
target_sources_shared(lwm2mclient_tinydtls)
endif()

View File

@ -0,0 +1,111 @@
/*******************************************************************************
*
* Copyright (c) 2014 Bosch Software Innovations GmbH, Germany.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v20.html
* The Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Bosch Software Innovations GmbH - Please refer to git log
*
*******************************************************************************/
/*
* lwm2mclient.h
*
* General functions of lwm2m test client.
*
* Created on: 22.01.2015
* Author: Achim Kraus
* Copyright (c) 2015 Bosch Software Innovations GmbH, Germany. All rights reserved.
*/
#ifndef LWM2MCLIENT_H_
#define LWM2MCLIENT_H_
#include "liblwm2m.h"
extern int g_reboot;
/*
* object_device.c
*/
lwm2m_object_t *get_object_device(void);
void free_object_device(lwm2m_object_t *objectP);
uint8_t device_change(lwm2m_data_t *dataArray, lwm2m_object_t *objectP);
void display_device_object(lwm2m_object_t *objectP);
/*
* object_firmware.c
*/
lwm2m_object_t *get_object_firmware(void);
void free_object_firmware(lwm2m_object_t *objectP);
void display_firmware_object(lwm2m_object_t *objectP);
/*
* object_location.c
*/
lwm2m_object_t *get_object_location(void);
void free_object_location(lwm2m_object_t *object);
void display_location_object(lwm2m_object_t *objectP);
/*
* object_test.c
*/
#define TEST_OBJECT_ID 31024
lwm2m_object_t *get_test_object(void);
void free_test_object(lwm2m_object_t *object);
void display_test_object(lwm2m_object_t *objectP);
/*
* object_server.c
*/
lwm2m_object_t *get_server_object(int serverId, const char *binding, int lifetime, bool storing);
void clean_server_object(lwm2m_object_t *object);
void display_server_object(lwm2m_object_t *objectP);
void copy_server_object(lwm2m_object_t *objectDest, lwm2m_object_t *objectSrc);
/*
* object_connectivity_moni.c
*/
lwm2m_object_t *get_object_conn_m(void);
void free_object_conn_m(lwm2m_object_t *objectP);
uint8_t connectivity_moni_change(lwm2m_data_t *dataArray, lwm2m_object_t *objectP);
/*
* object_connectivity_stat.c
*/
extern lwm2m_object_t *get_object_conn_s(void);
void free_object_conn_s(lwm2m_object_t *objectP);
extern void conn_s_updateTxStatistic(lwm2m_object_t *objectP, uint16_t txDataByte, bool smsBased);
extern void conn_s_updateRxStatistic(lwm2m_object_t *objectP, uint16_t rxDataByte, bool smsBased);
/*
* object_access_control.c
*/
lwm2m_object_t *acc_ctrl_create_object(void);
void acl_ctrl_free_object(lwm2m_object_t *objectP);
bool acc_ctrl_obj_add_inst(lwm2m_object_t *accCtrlObjP, uint16_t instId, uint16_t acObjectId, uint16_t acObjInstId,
uint16_t acOwner);
bool acc_ctrl_oi_add_ac_val(lwm2m_object_t *accCtrlObjP, uint16_t instId, uint16_t aclResId, uint16_t acValue);
/*
* lwm2mclient.c
*/
void handle_value_changed(lwm2m_context_t *lwm2mH, lwm2m_uri_t *uri, const char *value, size_t valueLength);
/*
* system_api.c
*/
void init_value_change(lwm2m_context_t *lwm2m);
void system_reboot(void);
/*
* object_security.c
*/
lwm2m_object_t *get_security_object(int serverId, const char *serverUri, char *bsPskId, char *psk, uint16_t pskLen,
bool isBootstrap);
void clean_security_object(lwm2m_object_t *objectP);
char *get_server_uri(lwm2m_object_t *objectP, uint16_t secObjInstID);
void display_security_object(lwm2m_object_t *objectP);
void copy_security_object(lwm2m_object_t *objectDest, lwm2m_object_t *objectSrc);
#endif /* LWM2MCLIENT_H_ */

View File

@ -19,7 +19,7 @@
/*
* This "Access Control" object is optional and multiple instantiated
*
*
* Resources:
*
* Name | ID | Oper. | Inst. | Mand.| Type | Range | Units |
@ -32,212 +32,178 @@
#include "liblwm2m.h"
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
// Resource Id's:
#define RES_M_OBJECT_ID 0
#define RES_M_OBJECT_INSTANCE_ID 1
#define RES_O_ACL 2
#define RES_M_ACCESS_CONTROL_OWNER 3
#define RES_M_OBJECT_ID 0
#define RES_M_OBJECT_INSTANCE_ID 1
#define RES_O_ACL 2
#define RES_M_ACCESS_CONTROL_OWNER 3
typedef struct acc_ctrl_ri_s
{ // linked list:
struct acc_ctrl_ri_s* next; // matches lwm2m_list_t::next
uint16_t resInstId; // matches lwm2m_list_t::id, ..serverID
typedef struct acc_ctrl_ri_s { // linked list:
struct acc_ctrl_ri_s *next; // matches lwm2m_list_t::next
uint16_t resInstId; // matches lwm2m_list_t::id, ..serverID
// resource data:
uint16_t accCtrlValue;
uint16_t accCtrlValue;
} acc_ctrl_ri_t;
typedef struct acc_ctrl_oi_s
{ //linked list:
struct acc_ctrl_oi_s* next; // matches lwm2m_list_t::next
uint16_t objInstId; // matches lwm2m_list_t::id
typedef struct acc_ctrl_oi_s { // linked list:
struct acc_ctrl_oi_s *next; // matches lwm2m_list_t::next
uint16_t objInstId; // matches lwm2m_list_t::id
// resources
uint16_t objectId;
uint16_t objectInstId;
uint16_t accCtrlOwner;
acc_ctrl_ri_t* accCtrlValList;
uint16_t objectId;
uint16_t objectInstId;
uint16_t accCtrlOwner;
acc_ctrl_ri_t *accCtrlValList;
} acc_ctrl_oi_t;
static uint8_t prv_delete(lwm2m_context_t *contextP, uint16_t id, lwm2m_object_t * objectP);
static uint8_t prv_create(lwm2m_context_t *contextP, uint16_t objInstId, int numData,
lwm2m_data_t * tlvArray, lwm2m_object_t * objectP);
static uint8_t prv_delete(lwm2m_context_t *contextP, uint16_t id, lwm2m_object_t *objectP);
static uint8_t prv_create(lwm2m_context_t *contextP, uint16_t objInstId, int numData, lwm2m_data_t *tlvArray,
lwm2m_object_t *objectP);
static uint8_t prv_set_tlv(lwm2m_data_t* dataP, acc_ctrl_oi_t* accCtrlOiP)
{
static uint8_t prv_set_tlv(lwm2m_data_t *dataP, acc_ctrl_oi_t *accCtrlOiP) {
switch (dataP->id) {
case RES_M_OBJECT_ID:
if (dataP->type == LWM2M_TYPE_MULTIPLE_RESOURCE) return COAP_404_NOT_FOUND;
if (dataP->type == LWM2M_TYPE_MULTIPLE_RESOURCE)
return COAP_404_NOT_FOUND;
lwm2m_data_encode_int(accCtrlOiP->objectId, dataP);
return COAP_205_CONTENT;
case RES_M_OBJECT_INSTANCE_ID:
if (dataP->type == LWM2M_TYPE_MULTIPLE_RESOURCE) return COAP_404_NOT_FOUND;
if (dataP->type == LWM2M_TYPE_MULTIPLE_RESOURCE)
return COAP_404_NOT_FOUND;
lwm2m_data_encode_int(accCtrlOiP->objectInstId, dataP);
return COAP_205_CONTENT;
case RES_O_ACL:
{
case RES_O_ACL: {
size_t count;
acc_ctrl_ri_t* accCtrlRiP;
for (accCtrlRiP = accCtrlOiP->accCtrlValList, count=0;
accCtrlRiP != NULL;
accCtrlRiP = accCtrlRiP->next, count++);
acc_ctrl_ri_t *accCtrlRiP;
for (accCtrlRiP = accCtrlOiP->accCtrlValList, count = 0; accCtrlRiP != NULL;
accCtrlRiP = accCtrlRiP->next, count++)
;
if (count == 0) // no values!
if (count == 0) // no values!
{
return COAP_404_NOT_FOUND;
}
else
{
lwm2m_data_t * subTlvP;
} else {
lwm2m_data_t *subTlvP;
size_t i;
if (dataP->type == LWM2M_TYPE_MULTIPLE_RESOURCE)
{
if (dataP->type == LWM2M_TYPE_MULTIPLE_RESOURCE) {
count = dataP->value.asChildren.count;
subTlvP = dataP->value.asChildren.array;
}
else
{
} else {
subTlvP = lwm2m_data_new(count);
for (accCtrlRiP = accCtrlOiP->accCtrlValList, i=0;
accCtrlRiP != NULL;
accCtrlRiP = accCtrlRiP->next, i++)
{
for (accCtrlRiP = accCtrlOiP->accCtrlValList, i = 0; accCtrlRiP != NULL;
accCtrlRiP = accCtrlRiP->next, i++) {
subTlvP[i].id = accCtrlRiP->resInstId;
}
lwm2m_data_encode_instances(subTlvP, count, dataP);
}
for (i = 0; i < count; i++)
{
for (accCtrlRiP = accCtrlOiP->accCtrlValList;
accCtrlRiP != NULL;
accCtrlRiP = accCtrlRiP->next)
{
if (subTlvP[i].id == accCtrlRiP->resInstId)
{
for (i = 0; i < count; i++) {
for (accCtrlRiP = accCtrlOiP->accCtrlValList; accCtrlRiP != NULL; accCtrlRiP = accCtrlRiP->next) {
if (subTlvP[i].id == accCtrlRiP->resInstId) {
lwm2m_data_encode_int(accCtrlRiP->accCtrlValue, subTlvP + i);
break;
}
}
if (accCtrlRiP == NULL) return COAP_404_NOT_FOUND;
if (accCtrlRiP == NULL)
return COAP_404_NOT_FOUND;
}
return COAP_205_CONTENT;
}
}
case RES_M_ACCESS_CONTROL_OWNER:
if (dataP->type == LWM2M_TYPE_MULTIPLE_RESOURCE) return COAP_404_NOT_FOUND;
if (dataP->type == LWM2M_TYPE_MULTIPLE_RESOURCE)
return COAP_404_NOT_FOUND;
lwm2m_data_encode_int(accCtrlOiP->accCtrlOwner, dataP);
return COAP_205_CONTENT;
default:
return COAP_404_NOT_FOUND ;
return COAP_404_NOT_FOUND;
}
}
static uint8_t prv_read(lwm2m_context_t *contextP, uint16_t instanceId, int * numDataP,
lwm2m_data_t** dataArrayP, lwm2m_object_t * objectP)
{
static uint8_t prv_read(lwm2m_context_t *contextP, uint16_t instanceId, int *numDataP, lwm2m_data_t **dataArrayP,
lwm2m_object_t *objectP) {
uint8_t result;
int ri, ni;
int ri, ni;
/* unused parameter */
(void)contextP;
// multi-instance object: search instance
acc_ctrl_oi_t* accCtrlOiP =
(acc_ctrl_oi_t *)lwm2m_list_find(objectP->instanceList, instanceId);
if (accCtrlOiP == NULL)
{
return COAP_404_NOT_FOUND ;
acc_ctrl_oi_t *accCtrlOiP = (acc_ctrl_oi_t *)lwm2m_list_find(objectP->instanceList, instanceId);
if (accCtrlOiP == NULL) {
return COAP_404_NOT_FOUND;
}
// is the server asking for the full object ?
if (*numDataP == 0)
{
uint16_t resList[] = {
RES_M_OBJECT_ID,
RES_M_OBJECT_INSTANCE_ID,
RES_O_ACL, // prv_set_tlv will return COAP_404_NOT_FOUND w/o values!
RES_M_ACCESS_CONTROL_OWNER
};
if (*numDataP == 0) {
uint16_t resList[] = {RES_M_OBJECT_ID, RES_M_OBJECT_INSTANCE_ID,
RES_O_ACL, // prv_set_tlv will return COAP_404_NOT_FOUND w/o values!
RES_M_ACCESS_CONTROL_OWNER};
int nbRes = sizeof(resList) / sizeof(uint16_t);
*dataArrayP = lwm2m_data_new(nbRes);
if (*dataArrayP == NULL)
return COAP_500_INTERNAL_SERVER_ERROR ;
return COAP_500_INTERNAL_SERVER_ERROR;
*numDataP = nbRes;
for (ri = 0; ri < nbRes; ri++)
{
for (ri = 0; ri < nbRes; ri++) {
(*dataArrayP)[ri].id = resList[ri];
}
}
ni = ri = 0;
do
{
do {
result = prv_set_tlv((*dataArrayP) + ni, accCtrlOiP);
if (result==COAP_404_NOT_FOUND) {
if (result == COAP_404_NOT_FOUND) {
ri++;
if (*numDataP>1) result = COAP_205_CONTENT;
}
else if (ri > 0) // copy new one by ri skipped ones in front
if (*numDataP > 1)
result = COAP_205_CONTENT;
} else if (ri > 0) // copy new one by ri skipped ones in front
{
(*dataArrayP)[ni-ri] = (*dataArrayP)[ni];
(*dataArrayP)[ni - ri] = (*dataArrayP)[ni];
}
ni++;
} while (ni < *numDataP && result == COAP_205_CONTENT);
*numDataP = ni-ri;
*numDataP = ni - ri;
return result;
}
static bool prv_add_ac_val(acc_ctrl_oi_t* accCtrlOiP,
uint16_t acResId, uint16_t acValue)
{
static bool prv_add_ac_val(acc_ctrl_oi_t *accCtrlOiP, uint16_t acResId, uint16_t acValue) {
bool ret = false;
acc_ctrl_ri_t *accCtrlRiP;
accCtrlRiP = (acc_ctrl_ri_t *)lwm2m_malloc(sizeof(acc_ctrl_ri_t));
if (accCtrlRiP==NULL)
{
if (accCtrlRiP == NULL) {
return ret;
}
else
{
} else {
memset(accCtrlRiP, 0, sizeof(acc_ctrl_ri_t));
accCtrlRiP->resInstId = acResId;
accCtrlRiP->accCtrlValue = acValue;
accCtrlRiP->resInstId = acResId;
accCtrlRiP->accCtrlValue = acValue;
accCtrlOiP->accCtrlValList = (acc_ctrl_ri_t*)
LWM2M_LIST_ADD(accCtrlOiP->accCtrlValList, accCtrlRiP);
accCtrlOiP->accCtrlValList = (acc_ctrl_ri_t *)LWM2M_LIST_ADD(accCtrlOiP->accCtrlValList, accCtrlRiP);
ret = true;
}
return ret;
}
static uint8_t prv_write_resources(lwm2m_context_t *contextP,
uint16_t instanceId, int numData,
lwm2m_data_t* tlvArray, lwm2m_object_t* objectP, bool doCreate,
lwm2m_write_type_t writeType)
{
static uint8_t prv_write_resources(lwm2m_context_t *contextP, uint16_t instanceId, int numData, lwm2m_data_t *tlvArray,
lwm2m_object_t *objectP, bool doCreate, lwm2m_write_type_t writeType) {
int i;
uint8_t result = COAP_500_INTERNAL_SERVER_ERROR;
int64_t value;
acc_ctrl_oi_t* accCtrlOiP = (acc_ctrl_oi_t *)
lwm2m_list_find(objectP->instanceList, instanceId);
acc_ctrl_oi_t *accCtrlOiP = (acc_ctrl_oi_t *)lwm2m_list_find(objectP->instanceList, instanceId);
if (NULL == accCtrlOiP)
return COAP_404_NOT_FOUND ;
return COAP_404_NOT_FOUND;
if (writeType == LWM2M_WRITE_REPLACE_INSTANCE)
{
if (writeType == LWM2M_WRITE_REPLACE_INSTANCE) {
result = prv_delete(contextP, instanceId, objectP);
if (result == COAP_202_DELETED)
{
if (result == COAP_202_DELETED) {
result = prv_create(contextP, instanceId, numData, tlvArray, objectP);
if (result == COAP_201_CREATED)
{
if (result == COAP_201_CREATED) {
result = COAP_204_CHANGED;
}
}
@ -245,140 +211,91 @@ static uint8_t prv_write_resources(lwm2m_context_t *contextP,
}
i = 0;
do
{
switch (tlvArray[i].id)
{
do {
switch (tlvArray[i].id) {
case RES_M_OBJECT_ID:
if (doCreate==false)
{
if (doCreate == false) {
result = COAP_405_METHOD_NOT_ALLOWED;
}
else if (tlvArray[i].type == LWM2M_TYPE_MULTIPLE_RESOURCE)
{
} else if (tlvArray[i].type == LWM2M_TYPE_MULTIPLE_RESOURCE) {
result = COAP_404_NOT_FOUND;
}
else
{
if (1 != lwm2m_data_decode_int(&tlvArray[i], &value))
{
} else {
if (1 != lwm2m_data_decode_int(&tlvArray[i], &value)) {
result = COAP_400_BAD_REQUEST;
}
else if (value < 1 || value > 65534)
{
} else if (value < 1 || value > 65534) {
result = COAP_406_NOT_ACCEPTABLE;
}
else
{
} else {
accCtrlOiP->objectId = value;
result = COAP_204_CHANGED;
}
}
break;
case RES_M_OBJECT_INSTANCE_ID:
if (doCreate==false)
{
if (doCreate == false) {
result = COAP_405_METHOD_NOT_ALLOWED;
}
else if (tlvArray[i].type == LWM2M_TYPE_MULTIPLE_RESOURCE)
{
} else if (tlvArray[i].type == LWM2M_TYPE_MULTIPLE_RESOURCE) {
result = COAP_404_NOT_FOUND;
}
else
{
if (1 != lwm2m_data_decode_int(&tlvArray[i], &value))
{
} else {
if (1 != lwm2m_data_decode_int(&tlvArray[i], &value)) {
result = COAP_400_BAD_REQUEST;
}
else if (value < 0 || value > 65535)
{
} else if (value < 0 || value > 65535) {
result = COAP_406_NOT_ACCEPTABLE;
}
else
{
} else {
accCtrlOiP->objectInstId = value;
result = COAP_204_CHANGED;
}
}
break;
case RES_O_ACL:
{
if (tlvArray[i].type!= LWM2M_TYPE_MULTIPLE_RESOURCE)
{
case RES_O_ACL: {
if (tlvArray[i].type != LWM2M_TYPE_MULTIPLE_RESOURCE) {
result = COAP_400_BAD_REQUEST;
}
else
{
} else {
// 1st: save accValueList!
acc_ctrl_ri_t* acValListSave = accCtrlOiP->accCtrlValList;
acc_ctrl_ri_t *acValListSave = accCtrlOiP->accCtrlValList;
accCtrlOiP->accCtrlValList = NULL;
size_t ri;
lwm2m_data_t* subTlvArray = tlvArray[i].value.asChildren.array;
lwm2m_data_t *subTlvArray = tlvArray[i].value.asChildren.array;
if (writeType == LWM2M_WRITE_PARTIAL_UPDATE)
{
if (writeType == LWM2M_WRITE_PARTIAL_UPDATE) {
result = COAP_204_CHANGED;
if (tlvArray[i].value.asChildren.count == 0)
{
if (tlvArray[i].value.asChildren.count == 0) {
acValListSave = NULL;
accCtrlOiP->accCtrlValList = acValListSave;
}
else if (subTlvArray==NULL)
{
} else if (subTlvArray == NULL) {
result = COAP_400_BAD_REQUEST;
}
else
{
} else {
// Duplicate original list
acc_ctrl_ri_t* acValListElement;
for (acValListElement = acValListSave;
acValListElement != NULL;
acValListElement = acValListElement->next)
{
if (!prv_add_ac_val(accCtrlOiP,
acValListElement->resInstId,
acValListElement->accCtrlValue))
{
acc_ctrl_ri_t *acValListElement;
for (acValListElement = acValListSave; acValListElement != NULL;
acValListElement = acValListElement->next) {
if (!prv_add_ac_val(accCtrlOiP, acValListElement->resInstId,
acValListElement->accCtrlValue)) {
result = COAP_500_INTERNAL_SERVER_ERROR;
break;
}
}
if (result == COAP_204_CHANGED)
{
if (result == COAP_204_CHANGED) {
// Add or replace based on new values
for (ri=0; ri < tlvArray[i].value.asChildren.count; ri++)
{
if (1 != lwm2m_data_decode_int(&subTlvArray[ri], &value))
{
for (ri = 0; ri < tlvArray[i].value.asChildren.count; ri++) {
if (1 != lwm2m_data_decode_int(&subTlvArray[ri], &value)) {
result = COAP_400_BAD_REQUEST;
break;
}
else if (value < 0 || value > 0xFFFF)
{
} else if (value < 0 || value > 0xFFFF) {
result = COAP_406_NOT_ACCEPTABLE;
break;
}
else
{
for (acValListElement = accCtrlOiP->accCtrlValList;
acValListElement != NULL;
acValListElement = acValListElement->next)
{
if (subTlvArray[ri].id == acValListElement->resInstId)
{
} else {
for (acValListElement = accCtrlOiP->accCtrlValList; acValListElement != NULL;
acValListElement = acValListElement->next) {
if (subTlvArray[ri].id == acValListElement->resInstId) {
acValListElement->accCtrlValue = (uint16_t)value;
break;
}
}
if (acValListElement == NULL &&
!prv_add_ac_val(accCtrlOiP,
subTlvArray[ri].id,
(uint16_t)value))
{
!prv_add_ac_val(accCtrlOiP, subTlvArray[ri].id, (uint16_t)value)) {
result = COAP_500_INTERNAL_SERVER_ERROR;
break;
}
@ -386,111 +303,79 @@ static uint8_t prv_write_resources(lwm2m_context_t *contextP,
}
}
}
}
else
{
if (tlvArray[i].value.asChildren.count == 0)
{
} else {
if (tlvArray[i].value.asChildren.count == 0) {
result = COAP_204_CHANGED;
}
else if (subTlvArray==NULL)
{
} else if (subTlvArray == NULL) {
result = COAP_400_BAD_REQUEST;
}
else
{
for (ri=0; ri < tlvArray[i].value.asChildren.count; ri++)
{
if (1 != lwm2m_data_decode_int(&subTlvArray[ri], &value))
{
} else {
for (ri = 0; ri < tlvArray[i].value.asChildren.count; ri++) {
if (1 != lwm2m_data_decode_int(&subTlvArray[ri], &value)) {
result = COAP_400_BAD_REQUEST;
break;
}
else if (value < 0 || value > 0xFFFF)
{
} else if (value < 0 || value > 0xFFFF) {
result = COAP_406_NOT_ACCEPTABLE;
break;
}
else if (!prv_add_ac_val(accCtrlOiP, subTlvArray[ri].id,
(uint16_t)value))
{
} else if (!prv_add_ac_val(accCtrlOiP, subTlvArray[ri].id, (uint16_t)value)) {
result = COAP_500_INTERNAL_SERVER_ERROR;
break;
}
else
{
} else {
result = COAP_204_CHANGED;
}
}
}
}
if (result != COAP_204_CHANGED)
{
if (result != COAP_204_CHANGED) {
// free pot. partial created new ones
LWM2M_LIST_FREE(accCtrlOiP->accCtrlValList);
// restore old values:
accCtrlOiP->accCtrlValList = acValListSave;
}
else
{
} else {
// final free saved value list
LWM2M_LIST_FREE(acValListSave);
}
}
} break;
} break;
case RES_M_ACCESS_CONTROL_OWNER: {
if (tlvArray[i].type == LWM2M_TYPE_MULTIPLE_RESOURCE)
{
if (tlvArray[i].type == LWM2M_TYPE_MULTIPLE_RESOURCE) {
result = COAP_404_NOT_FOUND;
}
else
{
if (1 == lwm2m_data_decode_int(tlvArray + i, &value))
{
if (value >= 0 && value <= 0xFFFF)
{
} else {
if (1 == lwm2m_data_decode_int(tlvArray + i, &value)) {
if (value >= 0 && value <= 0xFFFF) {
accCtrlOiP->accCtrlOwner = value;
result = COAP_204_CHANGED;
}
else
{
} else {
result = COAP_406_NOT_ACCEPTABLE;
}
}
else
{
} else {
result = COAP_400_BAD_REQUEST;
}
}
}
break;
} break;
default:
return COAP_404_NOT_FOUND ;
return COAP_404_NOT_FOUND;
}
i++;
} while (i < numData && result == COAP_204_CHANGED );
} while (i < numData && result == COAP_204_CHANGED);
return result;
}
static uint8_t prv_write(lwm2m_context_t *contextP, uint16_t instanceId, int numData,
lwm2m_data_t* tlvArray, lwm2m_object_t* objectP,
lwm2m_write_type_t writeType)
{
static uint8_t prv_write(lwm2m_context_t *contextP, uint16_t instanceId, int numData, lwm2m_data_t *tlvArray,
lwm2m_object_t *objectP, lwm2m_write_type_t writeType) {
return prv_write_resources(contextP, instanceId, numData, tlvArray, objectP, false, writeType);
}
static uint8_t prv_delete(lwm2m_context_t *contextP, uint16_t id, lwm2m_object_t * objectP)
{
acc_ctrl_oi_t* targetP;
static uint8_t prv_delete(lwm2m_context_t *contextP, uint16_t id, lwm2m_object_t *objectP) {
acc_ctrl_oi_t *targetP;
/* unused parameter */
(void)contextP;
objectP->instanceList = lwm2m_list_remove(objectP->instanceList, id,
(lwm2m_list_t**)&targetP);
if (NULL == targetP) return COAP_404_NOT_FOUND;
objectP->instanceList = lwm2m_list_remove(objectP->instanceList, id, (lwm2m_list_t **)&targetP);
if (NULL == targetP)
return COAP_404_NOT_FOUND;
LWM2M_LIST_FREE(targetP->accCtrlValList);
lwm2m_free(targetP);
@ -498,27 +383,24 @@ static uint8_t prv_delete(lwm2m_context_t *contextP, uint16_t id, lwm2m_object_t
return COAP_202_DELETED;
}
static uint8_t prv_create(lwm2m_context_t *contextP, uint16_t objInstId, int numData,
lwm2m_data_t * tlvArray, lwm2m_object_t * objectP)
{
acc_ctrl_oi_t * targetP;
static uint8_t prv_create(lwm2m_context_t *contextP, uint16_t objInstId, int numData, lwm2m_data_t *tlvArray,
lwm2m_object_t *objectP) {
acc_ctrl_oi_t *targetP;
uint8_t result;
targetP = (acc_ctrl_oi_t *)lwm2m_malloc(sizeof(acc_ctrl_oi_t));
if (NULL == targetP) return COAP_500_INTERNAL_SERVER_ERROR;
if (NULL == targetP)
return COAP_500_INTERNAL_SERVER_ERROR;
memset(targetP, 0, sizeof(acc_ctrl_oi_t));
targetP->objInstId = objInstId;
targetP->objInstId = objInstId;
objectP->instanceList = LWM2M_LIST_ADD(objectP->instanceList, targetP);
result = prv_write_resources(contextP, objInstId, numData, tlvArray, objectP, true, LWM2M_WRITE_REPLACE_RESOURCES);
if (result != COAP_204_CHANGED)
{
if (result != COAP_204_CHANGED) {
prv_delete(contextP, objInstId, objectP);
}
else
{
} else {
result = COAP_201_CREATED;
}
return result;
@ -527,18 +409,16 @@ static uint8_t prv_create(lwm2m_context_t *contextP, uint16_t objInstId, int num
/*
* Create an empty multiple instance LWM2M Object: Access Control
*/
lwm2m_object_t * acc_ctrl_create_object(void)
{
lwm2m_object_t *acc_ctrl_create_object(void) {
/*
* The acc_ctrl_create_object() function creates an empty object
* and returns a pointer to the structure that represents it.
*/
lwm2m_object_t* accCtrlObj = NULL;
lwm2m_object_t *accCtrlObj = NULL;
accCtrlObj = (lwm2m_object_t *) lwm2m_malloc(sizeof(lwm2m_object_t));
accCtrlObj = (lwm2m_object_t *)lwm2m_malloc(sizeof(lwm2m_object_t));
if (NULL != accCtrlObj)
{
if (NULL != accCtrlObj) {
memset(accCtrlObj, 0, sizeof(lwm2m_object_t));
/*
* It assign his unique object ID
@ -546,20 +426,18 @@ lwm2m_object_t * acc_ctrl_create_object(void)
*/
accCtrlObj->objID = 2;
// Init callbacks, empty instanceList!
accCtrlObj->readFunc = prv_read;
accCtrlObj->writeFunc = prv_write;
accCtrlObj->createFunc = prv_create;
accCtrlObj->deleteFunc = prv_delete;
accCtrlObj->readFunc = prv_read;
accCtrlObj->writeFunc = prv_write;
accCtrlObj->createFunc = prv_create;
accCtrlObj->deleteFunc = prv_delete;
}
return accCtrlObj;
}
void acl_ctrl_free_object(lwm2m_object_t * objectP)
{
void acl_ctrl_free_object(lwm2m_object_t *objectP) {
acc_ctrl_oi_t *accCtrlOiT;
acc_ctrl_oi_t *accCtrlOiP = (acc_ctrl_oi_t*)objectP->instanceList;
while (accCtrlOiP != NULL)
{
acc_ctrl_oi_t *accCtrlOiP = (acc_ctrl_oi_t *)objectP->instanceList;
while (accCtrlOiP != NULL) {
// first free acl (multiple resource!):
LWM2M_LIST_FREE(accCtrlOiP->accCtrlValList);
accCtrlOiT = accCtrlOiP;
@ -569,51 +447,40 @@ void acl_ctrl_free_object(lwm2m_object_t * objectP)
lwm2m_free(objectP);
}
bool acc_ctrl_obj_add_inst (lwm2m_object_t* accCtrlObjP, uint16_t instId,
uint16_t acObjectId, uint16_t acObjInstId, uint16_t acOwner)
{
bool acc_ctrl_obj_add_inst(lwm2m_object_t *accCtrlObjP, uint16_t instId, uint16_t acObjectId, uint16_t acObjInstId,
uint16_t acOwner) {
bool ret = false;
if (NULL == accCtrlObjP)
{
if (NULL == accCtrlObjP) {
return ret;
}
else
{
} else {
// create an access control object instance
acc_ctrl_oi_t* accCtrlOiP;
acc_ctrl_oi_t *accCtrlOiP;
accCtrlOiP = (acc_ctrl_oi_t *)lwm2m_malloc(sizeof(acc_ctrl_oi_t));
if (NULL == accCtrlOiP)
{
if (NULL == accCtrlOiP) {
return ret;
}
else
{
} else {
memset(accCtrlOiP, 0, sizeof(acc_ctrl_oi_t));
// list: key
accCtrlOiP->objInstId = instId;
accCtrlOiP->objInstId = instId;
// object instance data:
accCtrlOiP->objectId = acObjectId;
accCtrlOiP->objectId = acObjectId;
accCtrlOiP->objectInstId = acObjInstId;
accCtrlOiP->accCtrlOwner = acOwner;
accCtrlObjP->instanceList =
LWM2M_LIST_ADD(accCtrlObjP->instanceList, accCtrlOiP);
accCtrlObjP->instanceList = LWM2M_LIST_ADD(accCtrlObjP->instanceList, accCtrlOiP);
ret = true;
}
}
return ret;
}
bool acc_ctrl_oi_add_ac_val (lwm2m_object_t* accCtrlObjP, uint16_t instId,
uint16_t acResId, uint16_t acValue)
{
bool acc_ctrl_oi_add_ac_val(lwm2m_object_t *accCtrlObjP, uint16_t instId, uint16_t acResId, uint16_t acValue) {
bool ret = false;
acc_ctrl_oi_t* accCtrlOiP = (acc_ctrl_oi_t *)
lwm2m_list_find(accCtrlObjP->instanceList, instId);
acc_ctrl_oi_t *accCtrlOiP = (acc_ctrl_oi_t *)lwm2m_list_find(accCtrlObjP->instanceList, instId);
if (NULL == accCtrlOiP)
return ret;
return prv_add_ac_val (accCtrlOiP, acResId, acValue);
return prv_add_ac_val(accCtrlOiP, acResId, acValue);
}

View File

@ -19,7 +19,7 @@
/*
* This Connectivity Monitoring object is optional and has a single instance
*
*
* Resources:
*
* Name | ID | Oper. | Inst. | Mand.| Type | Range | Units |
@ -39,47 +39,46 @@
#include "liblwm2m.h"
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
// Resource Id's:
#define RES_M_NETWORK_BEARER 0
#define RES_M_AVL_NETWORK_BEARER 1
#define RES_M_RADIO_SIGNAL_STRENGTH 2
#define RES_O_LINK_QUALITY 3
#define RES_M_IP_ADDRESSES 4
#define RES_O_ROUTER_IP_ADDRESS 5
#define RES_O_LINK_UTILIZATION 6
#define RES_O_APN 7
#define RES_O_CELL_ID 8
#define RES_O_SMNC 9
#define RES_O_SMCC 10
#define RES_M_NETWORK_BEARER 0
#define RES_M_AVL_NETWORK_BEARER 1
#define RES_M_RADIO_SIGNAL_STRENGTH 2
#define RES_O_LINK_QUALITY 3
#define RES_M_IP_ADDRESSES 4
#define RES_O_ROUTER_IP_ADDRESS 5
#define RES_O_LINK_UTILIZATION 6
#define RES_O_APN 7
#define RES_O_CELL_ID 8
#define RES_O_SMNC 9
#define RES_O_SMCC 10
#define VALUE_NETWORK_BEARER_GSM 0 //GSM see
#define VALUE_AVL_NETWORK_BEARER_1 0 //GSM
#define VALUE_AVL_NETWORK_BEARER_2 21 //WLAN
#define VALUE_AVL_NETWORK_BEARER_3 41 //Ethernet
#define VALUE_AVL_NETWORK_BEARER_4 42 //DSL
#define VALUE_AVL_NETWORK_BEARER_5 43 //PLC
#define VALUE_IP_ADDRESS_1 "192.168.178.101"
#define VALUE_IP_ADDRESS_2 "192.168.178.102"
#define VALUE_ROUTER_IP_ADDRESS_1 "192.168.178.001"
#define VALUE_ROUTER_IP_ADDRESS_2 "192.168.178.002"
#define VALUE_APN_1 "web.vodafone.de"
#define VALUE_APN_2 "cda.vodafone.de"
#define VALUE_CELL_ID 69696969
#define VALUE_RADIO_SIGNAL_STRENGTH 80 //dBm
#define VALUE_LINK_QUALITY 98
#define VALUE_LINK_UTILIZATION 666
#define VALUE_SMNC 33
#define VALUE_SMCC 44
#define VALUE_NETWORK_BEARER_GSM 0 // GSM see
#define VALUE_AVL_NETWORK_BEARER_1 0 // GSM
#define VALUE_AVL_NETWORK_BEARER_2 21 // WLAN
#define VALUE_AVL_NETWORK_BEARER_3 41 // Ethernet
#define VALUE_AVL_NETWORK_BEARER_4 42 // DSL
#define VALUE_AVL_NETWORK_BEARER_5 43 // PLC
#define VALUE_IP_ADDRESS_1 "192.168.178.101"
#define VALUE_IP_ADDRESS_2 "192.168.178.102"
#define VALUE_ROUTER_IP_ADDRESS_1 "192.168.178.001"
#define VALUE_ROUTER_IP_ADDRESS_2 "192.168.178.002"
#define VALUE_APN_1 "web.vodafone.de"
#define VALUE_APN_2 "cda.vodafone.de"
#define VALUE_CELL_ID 69696969
#define VALUE_RADIO_SIGNAL_STRENGTH 80 // dBm
#define VALUE_LINK_QUALITY 98
#define VALUE_LINK_UTILIZATION 666
#define VALUE_SMNC 33
#define VALUE_SMCC 44
typedef struct
{
char ipAddresses[2][16]; // limited to 2!
char routerIpAddresses[2][16]; // limited to 2!
typedef struct {
char ipAddresses[2][16]; // limited to 2!
char routerIpAddresses[2][16]; // limited to 2!
long cellId;
int signalStrength;
int linkQuality;
@ -99,28 +98,23 @@ static void reduce_single_instance(lwm2m_data_t *const dataP, lwm2m_data_t **con
}
}
static uint8_t prv_set_value(lwm2m_data_t * dataP,
conn_m_data_t * connDataP)
{
lwm2m_data_t * subTlvP;
static uint8_t prv_set_value(lwm2m_data_t *dataP, conn_m_data_t *connDataP) {
lwm2m_data_t *subTlvP;
size_t count;
size_t i;
switch (dataP->id)
{
switch (dataP->id) {
case RES_M_NETWORK_BEARER:
if (dataP->type == LWM2M_TYPE_MULTIPLE_RESOURCE) return COAP_404_NOT_FOUND;
if (dataP->type == LWM2M_TYPE_MULTIPLE_RESOURCE)
return COAP_404_NOT_FOUND;
lwm2m_data_encode_int(VALUE_NETWORK_BEARER_GSM, dataP);
return COAP_205_CONTENT;
case RES_M_AVL_NETWORK_BEARER:
{
case RES_M_AVL_NETWORK_BEARER: {
reduce_single_instance(dataP, &subTlvP, &count);
for (i = 0; i < count; i++)
{
switch (subTlvP[i].id)
{
for (i = 0; i < count; i++) {
switch (subTlvP[i].id) {
case 0:
lwm2m_data_encode_int(VALUE_AVL_NETWORK_BEARER_1, subTlvP + i);
break;
@ -128,79 +122,71 @@ static uint8_t prv_set_value(lwm2m_data_t * dataP,
return COAP_404_NOT_FOUND;
}
}
return COAP_205_CONTENT ;
return COAP_205_CONTENT;
}
case RES_M_RADIO_SIGNAL_STRENGTH: //s-int
if (dataP->type == LWM2M_TYPE_MULTIPLE_RESOURCE) return COAP_404_NOT_FOUND;
case RES_M_RADIO_SIGNAL_STRENGTH: // s-int
if (dataP->type == LWM2M_TYPE_MULTIPLE_RESOURCE)
return COAP_404_NOT_FOUND;
lwm2m_data_encode_int(connDataP->signalStrength, dataP);
return COAP_205_CONTENT;
case RES_O_LINK_QUALITY: //s-int
if (dataP->type == LWM2M_TYPE_MULTIPLE_RESOURCE) return COAP_404_NOT_FOUND;
case RES_O_LINK_QUALITY: // s-int
if (dataP->type == LWM2M_TYPE_MULTIPLE_RESOURCE)
return COAP_404_NOT_FOUND;
lwm2m_data_encode_int(connDataP->linkQuality, dataP);
return COAP_205_CONTENT ;
return COAP_205_CONTENT;
case RES_M_IP_ADDRESSES:
{
case RES_M_IP_ADDRESSES: {
reduce_single_instance(dataP, &subTlvP, &count);
for (i = 0; i < count; i++)
{
switch (subTlvP[i].id)
{
for (i = 0; i < count; i++) {
switch (subTlvP[i].id) {
case 0:
lwm2m_data_encode_string(connDataP->ipAddresses[i], subTlvP + i);
lwm2m_data_encode_string(connDataP->ipAddresses[i], subTlvP + i); // NOSONAR
break;
default:
return COAP_404_NOT_FOUND;
}
}
return COAP_205_CONTENT ;
return COAP_205_CONTENT;
}
case RES_O_ROUTER_IP_ADDRESS:
{
if (dataP->type == LWM2M_TYPE_MULTIPLE_RESOURCE)
{
case RES_O_ROUTER_IP_ADDRESS: {
if (dataP->type == LWM2M_TYPE_MULTIPLE_RESOURCE) {
count = dataP->value.asChildren.count;
subTlvP = dataP->value.asChildren.array;
}
else
{
} else {
count = 1; // reduced to 1 instance to fit in one block size
subTlvP = lwm2m_data_new(count);
for (i = 0; i < count; i++) subTlvP[i].id = i;
for (i = 0; i < count; i++)
subTlvP[i].id = i;
lwm2m_data_encode_instances(subTlvP, count, dataP);
}
for (i = 0; i < count; i++)
{
switch (subTlvP[i].id)
{
for (i = 0; i < count; i++) {
switch (subTlvP[i].id) {
case 0:
lwm2m_data_encode_string(connDataP->routerIpAddresses[i], subTlvP + i);
lwm2m_data_encode_string(connDataP->routerIpAddresses[i], subTlvP + i); // NOSONAR
break;
default:
return COAP_404_NOT_FOUND;
}
}
return COAP_205_CONTENT ;
return COAP_205_CONTENT;
}
case RES_O_LINK_UTILIZATION:
if (dataP->type == LWM2M_TYPE_MULTIPLE_RESOURCE) return COAP_404_NOT_FOUND;
if (dataP->type == LWM2M_TYPE_MULTIPLE_RESOURCE)
return COAP_404_NOT_FOUND;
lwm2m_data_encode_int(connDataP->linkUtilization, dataP);
return COAP_205_CONTENT;
case RES_O_APN:
{
case RES_O_APN: {
reduce_single_instance(dataP, &subTlvP, &count);
for (i = 0; i < count; i++)
{
switch (subTlvP[i].id)
{
for (i = 0; i < count; i++) {
switch (subTlvP[i].id) {
case 0:
lwm2m_data_encode_string(VALUE_APN_1, subTlvP + i);
break;
@ -212,31 +198,30 @@ static uint8_t prv_set_value(lwm2m_data_t * dataP,
}
case RES_O_CELL_ID:
if (dataP->type == LWM2M_TYPE_MULTIPLE_RESOURCE) return COAP_404_NOT_FOUND;
if (dataP->type == LWM2M_TYPE_MULTIPLE_RESOURCE)
return COAP_404_NOT_FOUND;
lwm2m_data_encode_int(connDataP->cellId, dataP);
return COAP_205_CONTENT ;
return COAP_205_CONTENT;
case RES_O_SMNC:
if (dataP->type == LWM2M_TYPE_MULTIPLE_RESOURCE) return COAP_404_NOT_FOUND;
if (dataP->type == LWM2M_TYPE_MULTIPLE_RESOURCE)
return COAP_404_NOT_FOUND;
lwm2m_data_encode_int(VALUE_SMNC, dataP);
return COAP_205_CONTENT ;
return COAP_205_CONTENT;
case RES_O_SMCC:
if (dataP->type == LWM2M_TYPE_MULTIPLE_RESOURCE) return COAP_404_NOT_FOUND;
if (dataP->type == LWM2M_TYPE_MULTIPLE_RESOURCE)
return COAP_404_NOT_FOUND;
lwm2m_data_encode_int(VALUE_SMCC, dataP);
return COAP_205_CONTENT ;
return COAP_205_CONTENT;
default:
return COAP_404_NOT_FOUND ;
return COAP_404_NOT_FOUND;
}
}
static uint8_t prv_read(lwm2m_context_t *contextP,
uint16_t instanceId,
int * numDataP,
lwm2m_data_t ** dataArrayP,
lwm2m_object_t * objectP)
{
static uint8_t prv_read(lwm2m_context_t *contextP, uint16_t instanceId, int *numDataP, lwm2m_data_t **dataArrayP,
lwm2m_object_t *objectP) {
uint8_t result;
int i;
@ -244,86 +229,76 @@ static uint8_t prv_read(lwm2m_context_t *contextP,
(void)contextP;
// this is a single instance object
if (instanceId != 0)
{
return COAP_404_NOT_FOUND ;
if (instanceId != 0) {
return COAP_404_NOT_FOUND;
}
// is the server asking for the full object ?
if (*numDataP == 0)
{
uint16_t resList[] = {
RES_M_NETWORK_BEARER,
RES_M_AVL_NETWORK_BEARER,
RES_M_RADIO_SIGNAL_STRENGTH,
RES_O_LINK_QUALITY,
RES_M_IP_ADDRESSES,
RES_O_ROUTER_IP_ADDRESS,
RES_O_LINK_UTILIZATION,
RES_O_APN,
RES_O_CELL_ID,
RES_O_SMNC,
RES_O_SMCC
};
if (*numDataP == 0) {
uint16_t resList[] = {RES_M_NETWORK_BEARER,
RES_M_AVL_NETWORK_BEARER,
RES_M_RADIO_SIGNAL_STRENGTH,
RES_O_LINK_QUALITY,
RES_M_IP_ADDRESSES,
RES_O_ROUTER_IP_ADDRESS,
RES_O_LINK_UTILIZATION,
RES_O_APN,
RES_O_CELL_ID,
RES_O_SMNC,
RES_O_SMCC};
int nbRes = sizeof(resList) / sizeof(uint16_t);
*dataArrayP = lwm2m_data_new(nbRes);
if (*dataArrayP == NULL)
return COAP_500_INTERNAL_SERVER_ERROR ;
return COAP_500_INTERNAL_SERVER_ERROR;
*numDataP = nbRes;
for (i = 0; i < nbRes; i++)
{
for (i = 0; i < nbRes; i++) {
(*dataArrayP)[i].id = resList[i];
}
}
i = 0;
do
{
result = prv_set_value((*dataArrayP) + i, (conn_m_data_t*) (objectP->userData));
do {
result = prv_set_value((*dataArrayP) + i, (conn_m_data_t *)(objectP->userData));
i++;
} while (i < *numDataP && result == COAP_205_CONTENT );
} while (i < *numDataP && result == COAP_205_CONTENT);
return result;
}
lwm2m_object_t * get_object_conn_m(void)
{
lwm2m_object_t *get_object_conn_m(void) {
/*
* The get_object_conn_m() function create the object itself and return a pointer to the structure that represent it.
* The get_object_conn_m() function create the object itself and return a pointer to the structure that represent
* it.
*/
lwm2m_object_t * connObj;
lwm2m_object_t *connObj;
connObj = (lwm2m_object_t *) lwm2m_malloc(sizeof(lwm2m_object_t));
connObj = (lwm2m_object_t *)lwm2m_malloc(sizeof(lwm2m_object_t));
if (NULL != connObj)
{
if (NULL != connObj) {
memset(connObj, 0, sizeof(lwm2m_object_t));
/*
* It assigns his unique ID
*/
connObj->objID = LWM2M_CONN_MONITOR_OBJECT_ID;
/*
* and its unique instance
*
*/
connObj->instanceList = (lwm2m_list_t *)lwm2m_malloc(sizeof(lwm2m_list_t));
if (NULL != connObj->instanceList)
{
if (NULL != connObj->instanceList) {
memset(connObj->instanceList, 0, sizeof(lwm2m_list_t));
}
else
{
} else {
lwm2m_free(connObj);
return NULL;
}
/*
* And the private function that will access the object.
* Those function will be called when a read/write/execute query is made by the server. In fact the library don't need to
* know the resources of the object, only the server does.
* Those function will be called when a read/write/execute query is made by the server. In fact the library
* don't need to know the resources of the object, only the server does.
*/
connObj->readFunc = prv_read;
connObj->executeFunc = NULL;
@ -332,20 +307,17 @@ lwm2m_object_t * get_object_conn_m(void)
/*
* Also some user data can be stored in the object with a private structure containing the needed variables
*/
if (NULL != connObj->userData)
{
conn_m_data_t *myData = (conn_m_data_t*) connObj->userData;
myData->cellId = VALUE_CELL_ID;
myData->signalStrength = VALUE_RADIO_SIGNAL_STRENGTH;
myData->linkQuality = VALUE_LINK_QUALITY;
if (NULL != connObj->userData) {
conn_m_data_t *myData = (conn_m_data_t *)connObj->userData;
myData->cellId = VALUE_CELL_ID;
myData->signalStrength = VALUE_RADIO_SIGNAL_STRENGTH;
myData->linkQuality = VALUE_LINK_QUALITY;
myData->linkUtilization = VALUE_LINK_UTILIZATION;
strcpy(myData->ipAddresses[0], VALUE_IP_ADDRESS_1);
strcpy(myData->ipAddresses[1], VALUE_IP_ADDRESS_2);
strcpy(myData->routerIpAddresses[0], VALUE_ROUTER_IP_ADDRESS_1);
strcpy(myData->routerIpAddresses[1], VALUE_ROUTER_IP_ADDRESS_2);
}
else
{
strcpy(myData->ipAddresses[0], VALUE_IP_ADDRESS_1); // NOSONAR
strcpy(myData->ipAddresses[1], VALUE_IP_ADDRESS_2); // NOSONAR
strcpy(myData->routerIpAddresses[0], VALUE_ROUTER_IP_ADDRESS_1); // NOSONAR
strcpy(myData->routerIpAddresses[1], VALUE_ROUTER_IP_ADDRESS_2); // NOSONAR
} else {
lwm2m_free(connObj);
connObj = NULL;
}
@ -353,55 +325,42 @@ lwm2m_object_t * get_object_conn_m(void)
return connObj;
}
void free_object_conn_m(lwm2m_object_t * objectP)
{
void free_object_conn_m(lwm2m_object_t *objectP) {
lwm2m_free(objectP->userData);
lwm2m_list_free(objectP->instanceList);
lwm2m_free(objectP);
}
uint8_t connectivity_moni_change(lwm2m_data_t * dataArray,
lwm2m_object_t * objectP)
{
uint8_t connectivity_moni_change(lwm2m_data_t *dataArray, lwm2m_object_t *objectP) {
int64_t value;
uint8_t result;
conn_m_data_t * data;
conn_m_data_t *data;
data = (conn_m_data_t*) (objectP->userData);
data = (conn_m_data_t *)(objectP->userData);
switch (dataArray->id)
{
switch (dataArray->id) {
case RES_M_RADIO_SIGNAL_STRENGTH:
if (1 == lwm2m_data_decode_int(dataArray, &value))
{
if (1 == lwm2m_data_decode_int(dataArray, &value)) {
data->signalStrength = value;
result = COAP_204_CHANGED;
}
else
{
} else {
result = COAP_400_BAD_REQUEST;
}
break;
case RES_O_LINK_QUALITY:
if (1 == lwm2m_data_decode_int(dataArray, &value))
{
if (1 == lwm2m_data_decode_int(dataArray, &value)) {
data->linkQuality = value;
result = COAP_204_CHANGED;
}
else
{
} else {
result = COAP_400_BAD_REQUEST;
}
break;
case RES_M_IP_ADDRESSES:
if (sizeof(data->ipAddresses[0]) <= dataArray->value.asBuffer.length)
{
if (sizeof(data->ipAddresses[0]) <= dataArray->value.asBuffer.length) {
result = COAP_400_BAD_REQUEST;
}
else
{
} else {
memset(data->ipAddresses[0], 0, sizeof(data->ipAddresses[0]));
memcpy(data->ipAddresses[0], dataArray->value.asBuffer.buffer, dataArray->value.asBuffer.length);
data->ipAddresses[0][dataArray->value.asBuffer.length] = 0;
@ -410,12 +369,9 @@ uint8_t connectivity_moni_change(lwm2m_data_t * dataArray,
break;
case RES_O_ROUTER_IP_ADDRESS:
if (sizeof(data->routerIpAddresses[0]) <= dataArray->value.asBuffer.length)
{
if (sizeof(data->routerIpAddresses[0]) <= dataArray->value.asBuffer.length) {
result = COAP_400_BAD_REQUEST;
}
else
{
} else {
memset(data->routerIpAddresses[0], 0, sizeof(data->routerIpAddresses[0]));
memcpy(data->routerIpAddresses[0], dataArray->value.asBuffer.buffer, dataArray->value.asBuffer.length);
data->routerIpAddresses[0][dataArray->value.asBuffer.length] = 0;
@ -424,13 +380,10 @@ uint8_t connectivity_moni_change(lwm2m_data_t * dataArray,
break;
case RES_O_CELL_ID:
if (1 == lwm2m_data_decode_int(dataArray, &value))
{
if (1 == lwm2m_data_decode_int(dataArray, &value)) {
data->cellId = value;
result = COAP_204_CHANGED;
}
else
{
} else {
result = COAP_400_BAD_REQUEST;
}
break;
@ -441,4 +394,3 @@ uint8_t connectivity_moni_change(lwm2m_data_t * dataArray,
return result;
}

View File

@ -18,7 +18,7 @@
/*
* This connectivity statistics object is optional and single instance only
*
*
* Resources:
*
* Name | ID | Oper. | Inst. | Mand.| Type | Range | Units | Description |
@ -33,34 +33,32 @@
#include "liblwm2m.h"
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
// Resource Id's:
#define RES_O_SMS_TX_COUNTER 0
#define RES_O_SMS_RX_COUNTER 1
#define RES_O_TX_DATA 2
#define RES_O_RX_DATA 3
#define RES_O_MAX_MESSAGE_SIZE 4
#define RES_O_AVERAGE_MESSAGE_SIZE 5
#define RES_M_START_OR_RESET 6
#define RES_O_SMS_TX_COUNTER 0
#define RES_O_SMS_RX_COUNTER 1
#define RES_O_TX_DATA 2
#define RES_O_RX_DATA 3
#define RES_O_MAX_MESSAGE_SIZE 4
#define RES_O_AVERAGE_MESSAGE_SIZE 5
#define RES_M_START_OR_RESET 6
typedef struct
{
int64_t smsTxCounter;
int64_t smsRxCounter;
int64_t txDataByte; // report in kByte!
int64_t rxDataByte; // report in kByte!
int64_t maxMessageSize;
int64_t avrMessageSize;
int64_t messageCount; // private for incremental average calc.
bool collectDataStarted;
typedef struct {
int64_t smsTxCounter;
int64_t smsRxCounter;
int64_t txDataByte; // report in kByte!
int64_t rxDataByte; // report in kByte!
int64_t maxMessageSize;
int64_t avrMessageSize;
int64_t messageCount; // private for incremental average calc.
bool collectDataStarted;
} conn_s_data_t;
static uint8_t prv_set_tlv(lwm2m_data_t * dataP, conn_s_data_t * connStDataP)
{
static uint8_t prv_set_tlv(lwm2m_data_t *dataP, conn_s_data_t *connStDataP) {
switch (dataP->id) {
case RES_O_SMS_TX_COUNTER:
lwm2m_data_encode_int(connStDataP->smsTxCounter, dataP);
@ -69,10 +67,10 @@ static uint8_t prv_set_tlv(lwm2m_data_t * dataP, conn_s_data_t * connStDataP)
lwm2m_data_encode_int(connStDataP->smsRxCounter, dataP);
return COAP_205_CONTENT;
case RES_O_TX_DATA:
lwm2m_data_encode_int(connStDataP->txDataByte/1024, dataP);
lwm2m_data_encode_int(connStDataP->txDataByte / 1024, dataP);
return COAP_205_CONTENT;
case RES_O_RX_DATA:
lwm2m_data_encode_int(connStDataP->rxDataByte/1024, dataP);
lwm2m_data_encode_int(connStDataP->rxDataByte / 1024, dataP);
return COAP_205_CONTENT;
case RES_O_MAX_MESSAGE_SIZE:
lwm2m_data_encode_int(connStDataP->maxMessageSize, dataP);
@ -81,16 +79,12 @@ static uint8_t prv_set_tlv(lwm2m_data_t * dataP, conn_s_data_t * connStDataP)
lwm2m_data_encode_int(connStDataP->avrMessageSize, dataP);
return COAP_205_CONTENT;
default:
return COAP_404_NOT_FOUND ;
return COAP_404_NOT_FOUND;
}
}
static uint8_t prv_read(lwm2m_context_t *contextP,
uint16_t instanceId,
int * numDataP,
lwm2m_data_t** dataArrayP,
lwm2m_object_t * objectP)
{
static uint8_t prv_read(lwm2m_context_t *contextP, uint16_t instanceId, int *numDataP, lwm2m_data_t **dataArrayP,
lwm2m_object_t *objectP) {
uint8_t result;
int i;
@ -98,84 +92,64 @@ static uint8_t prv_read(lwm2m_context_t *contextP,
(void)contextP;
// this is a single instance object
if (instanceId != 0)
{
return COAP_404_NOT_FOUND ;
if (instanceId != 0) {
return COAP_404_NOT_FOUND;
}
// is the server asking for the full object ?
if (*numDataP == 0)
{
uint16_t resList[] = {
RES_O_SMS_TX_COUNTER,
RES_O_SMS_RX_COUNTER,
RES_O_TX_DATA,
RES_O_RX_DATA,
RES_O_MAX_MESSAGE_SIZE,
RES_O_AVERAGE_MESSAGE_SIZE
};
if (*numDataP == 0) {
uint16_t resList[] = {RES_O_SMS_TX_COUNTER, RES_O_SMS_RX_COUNTER, RES_O_TX_DATA,
RES_O_RX_DATA, RES_O_MAX_MESSAGE_SIZE, RES_O_AVERAGE_MESSAGE_SIZE};
int nbRes = sizeof(resList) / sizeof(uint16_t);
*dataArrayP = lwm2m_data_new(nbRes);
if (*dataArrayP == NULL)
return COAP_500_INTERNAL_SERVER_ERROR ;
return COAP_500_INTERNAL_SERVER_ERROR;
*numDataP = nbRes;
for (i = 0; i < nbRes; i++)
{
for (i = 0; i < nbRes; i++) {
(*dataArrayP)[i].id = resList[i];
}
}
i = 0;
do
{
if ((*dataArrayP)[i].type == LWM2M_TYPE_MULTIPLE_RESOURCE)
{
do {
if ((*dataArrayP)[i].type == LWM2M_TYPE_MULTIPLE_RESOURCE) {
result = COAP_404_NOT_FOUND;
}
else
{
result = prv_set_tlv((*dataArrayP) + i, (conn_s_data_t*) (objectP->userData));
} else {
result = prv_set_tlv((*dataArrayP) + i, (conn_s_data_t *)(objectP->userData));
}
i++;
} while (i < *numDataP && result == COAP_205_CONTENT );
} while (i < *numDataP && result == COAP_205_CONTENT);
return result;
}
static void prv_resetCounter(lwm2m_object_t* objectP, bool start)
{
conn_s_data_t *myData = (conn_s_data_t*) objectP->userData;
myData->smsTxCounter = 0;
myData->smsRxCounter = 0;
myData->txDataByte = 0;
myData->rxDataByte = 0;
myData->maxMessageSize = 0;
myData->avrMessageSize = 0;
myData->messageCount = 0;
myData->collectDataStarted = start;
static void prv_resetCounter(lwm2m_object_t *objectP, bool start) {
conn_s_data_t *myData = (conn_s_data_t *)objectP->userData;
myData->smsTxCounter = 0;
myData->smsRxCounter = 0;
myData->txDataByte = 0;
myData->rxDataByte = 0;
myData->maxMessageSize = 0;
myData->avrMessageSize = 0;
myData->messageCount = 0;
myData->collectDataStarted = start;
}
static uint8_t prv_exec(lwm2m_context_t *contextP,
uint16_t instanceId,
uint16_t resourceId,
uint8_t * buffer,
int length,
lwm2m_object_t * objectP)
{
static uint8_t prv_exec(lwm2m_context_t *contextP, uint16_t instanceId, uint16_t resourceId, uint8_t *buffer,
int length, lwm2m_object_t *objectP) {
/* unused parameter */
(void)contextP;
// this is a single instance object
if (instanceId != 0)
{
if (instanceId != 0) {
return COAP_404_NOT_FOUND;
}
if (length != 0) return COAP_400_BAD_REQUEST;
if (length != 0)
return COAP_400_BAD_REQUEST;
switch (resourceId)
{
switch (resourceId) {
case RES_M_START_OR_RESET:
prv_resetCounter(objectP, true);
return COAP_204_CHANGED;
@ -184,50 +158,43 @@ static uint8_t prv_exec(lwm2m_context_t *contextP,
}
}
void conn_s_updateTxStatistic(lwm2m_object_t * objectP, uint16_t txDataByte, bool smsBased)
{
conn_s_data_t* myData = (conn_s_data_t*) (objectP->userData);
if (myData->collectDataStarted)
{
void conn_s_updateTxStatistic(lwm2m_object_t *objectP, uint16_t txDataByte, bool smsBased) {
conn_s_data_t *myData = (conn_s_data_t *)(objectP->userData);
if (myData->collectDataStarted) {
myData->txDataByte += txDataByte;
myData->messageCount++;
myData->avrMessageSize = (myData->txDataByte+myData->rxDataByte) /
myData->messageCount;
myData->avrMessageSize = (myData->txDataByte + myData->rxDataByte) / myData->messageCount;
if (txDataByte > myData->maxMessageSize)
myData->maxMessageSize = txDataByte;
if (smsBased) myData->smsTxCounter++;
if (smsBased)
myData->smsTxCounter++;
}
}
void conn_s_updateRxStatistic(lwm2m_object_t * objectP, uint16_t rxDataByte, bool smsBased)
{
conn_s_data_t* myData = (conn_s_data_t*) (objectP->userData);
if (myData->collectDataStarted)
{
void conn_s_updateRxStatistic(lwm2m_object_t *objectP, uint16_t rxDataByte, bool smsBased) {
conn_s_data_t *myData = (conn_s_data_t *)(objectP->userData);
if (myData->collectDataStarted) {
myData->rxDataByte += rxDataByte;
myData->messageCount++;
myData->avrMessageSize = (myData->txDataByte+myData->rxDataByte) /
myData->messageCount;
myData->avrMessageSize = (myData->txDataByte + myData->rxDataByte) / myData->messageCount;
if (rxDataByte > myData->maxMessageSize)
myData->maxMessageSize = rxDataByte;
myData->txDataByte += rxDataByte;
if (smsBased) myData->smsRxCounter++;
if (smsBased)
myData->smsRxCounter++;
}
}
lwm2m_object_t * get_object_conn_s(void)
{
lwm2m_object_t *get_object_conn_s(void) {
/*
* The get_object_conn_s() function create the object itself and return
* a pointer to the structure that represent it.
*/
lwm2m_object_t * connObj;
lwm2m_object_t *connObj;
connObj = (lwm2m_object_t *) lwm2m_malloc(sizeof(lwm2m_object_t));
connObj = (lwm2m_object_t *)lwm2m_malloc(sizeof(lwm2m_object_t));
if (NULL != connObj)
{
if (NULL != connObj) {
memset(connObj, 0, sizeof(lwm2m_object_t));
/*
@ -236,11 +203,9 @@ lwm2m_object_t * get_object_conn_s(void)
*/
connObj->objID = LWM2M_CONN_STATS_OBJECT_ID;
connObj->instanceList = lwm2m_malloc(sizeof(lwm2m_list_t));
if (NULL != connObj->instanceList)
{
if (NULL != connObj->instanceList) {
memset(connObj->instanceList, 0, sizeof(lwm2m_list_t));
}
else {
} else {
lwm2m_free(connObj);
return NULL;
}
@ -251,20 +216,17 @@ lwm2m_object_t * get_object_conn_s(void)
* query is made by the server or core. In fact the library don't need
* to know the resources of the object, only the server does.
*/
connObj->readFunc = prv_read;
connObj->executeFunc = prv_exec;
connObj->userData = lwm2m_malloc(sizeof(conn_s_data_t));
connObj->readFunc = prv_read;
connObj->executeFunc = prv_exec;
connObj->userData = lwm2m_malloc(sizeof(conn_s_data_t));
/*
* Also some user data can be stored in the object with a private
* structure containing the needed variables.
*/
if (NULL != connObj->userData)
{
if (NULL != connObj->userData) {
prv_resetCounter(connObj, false);
}
else
{
} else {
lwm2m_free(connObj);
connObj = NULL;
}
@ -272,8 +234,7 @@ lwm2m_object_t * get_object_conn_s(void)
return connObj;
}
void free_object_conn_s(lwm2m_object_t * objectP)
{
void free_object_conn_s(lwm2m_object_t *objectP) {
lwm2m_free(objectP->userData);
lwm2m_list_free(objectP->instanceList);
lwm2m_free(objectP);

View File

@ -59,60 +59,57 @@
#include "liblwm2m.h"
#include "lwm2mclient.h"
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <time.h>
#define PRV_MANUFACTURER "Open Mobile Alliance"
#define PRV_MODEL_NUMBER "Lightweight M2M Client"
#define PRV_SERIAL_NUMBER "345000123"
#define PRV_FIRMWARE_VERSION "1.0"
#define PRV_POWER_SOURCE_1 1
#define PRV_POWER_SOURCE_2 5
#define PRV_POWER_VOLTAGE_1 3800
#define PRV_POWER_VOLTAGE_2 5000
#define PRV_POWER_CURRENT_1 125
#define PRV_POWER_CURRENT_2 900
#define PRV_BATTERY_LEVEL 100
#define PRV_MEMORY_FREE 15
#define PRV_ERROR_CODE 0
#define PRV_TIME_ZONE "Europe/Berlin"
#define PRV_BINDING_MODE "U"
#define PRV_MANUFACTURER "Open Mobile Alliance"
#define PRV_MODEL_NUMBER "Lightweight M2M Client"
#define PRV_SERIAL_NUMBER "345000123"
#define PRV_FIRMWARE_VERSION "1.0"
#define PRV_POWER_SOURCE_1 1
#define PRV_POWER_SOURCE_2 5
#define PRV_POWER_VOLTAGE_1 3800
#define PRV_POWER_VOLTAGE_2 5000
#define PRV_POWER_CURRENT_1 125
#define PRV_POWER_CURRENT_2 900
#define PRV_BATTERY_LEVEL 100
#define PRV_MEMORY_FREE 15
#define PRV_ERROR_CODE 0
#define PRV_TIME_ZONE "Europe/Berlin"
#define PRV_BINDING_MODE "U"
#define PRV_OFFSET_MAXLEN 7 //+HH:MM\0 at max
#define PRV_OFFSET_MAXLEN 7 //+HH:MM\0 at max
#define PRV_TLV_BUFFER_SIZE 128
// Resource Id's:
#define RES_O_MANUFACTURER 0
#define RES_O_MODEL_NUMBER 1
#define RES_O_SERIAL_NUMBER 2
#define RES_O_FIRMWARE_VERSION 3
#define RES_M_REBOOT 4
#define RES_O_FACTORY_RESET 5
#define RES_O_AVL_POWER_SOURCES 6
#define RES_O_POWER_SOURCE_VOLTAGE 7
#define RES_O_POWER_SOURCE_CURRENT 8
#define RES_O_BATTERY_LEVEL 9
#define RES_O_MEMORY_FREE 10
#define RES_M_ERROR_CODE 11
#define RES_O_RESET_ERROR_CODE 12
#define RES_O_CURRENT_TIME 13
#define RES_O_UTC_OFFSET 14
#define RES_O_TIMEZONE 15
#define RES_M_BINDING_MODES 16
#define RES_O_MANUFACTURER 0
#define RES_O_MODEL_NUMBER 1
#define RES_O_SERIAL_NUMBER 2
#define RES_O_FIRMWARE_VERSION 3
#define RES_M_REBOOT 4
#define RES_O_FACTORY_RESET 5
#define RES_O_AVL_POWER_SOURCES 6
#define RES_O_POWER_SOURCE_VOLTAGE 7
#define RES_O_POWER_SOURCE_CURRENT 8
#define RES_O_BATTERY_LEVEL 9
#define RES_O_MEMORY_FREE 10
#define RES_M_ERROR_CODE 11
#define RES_O_RESET_ERROR_CODE 12
#define RES_O_CURRENT_TIME 13
#define RES_O_UTC_OFFSET 14
#define RES_O_TIMEZONE 15
#define RES_M_BINDING_MODES 16
// since TS 20141126-C:
#define RES_O_DEVICE_TYPE 17
#define RES_O_HARDWARE_VERSION 18
#define RES_O_SOFTWARE_VERSION 19
#define RES_O_BATTERY_STATUS 20
#define RES_O_MEMORY_TOTAL 21
#define RES_O_DEVICE_TYPE 17
#define RES_O_HARDWARE_VERSION 18
#define RES_O_SOFTWARE_VERSION 19
#define RES_O_BATTERY_STATUS 20
#define RES_O_MEMORY_TOTAL 21
typedef struct
{
typedef struct {
int64_t free_memory;
int64_t error;
int64_t time;
@ -120,74 +117,77 @@ typedef struct
char time_offset[PRV_OFFSET_MAXLEN];
} device_data_t;
// basic check that the time offset value is at ISO 8601 format
// bug: +12:30 is considered a valid value by this function
static int prv_check_time_offset(char * buffer,
int length)
{
static int prv_check_time_offset(char *buffer, int length) {
int min_index;
if (length != 3 && length != 5 && length != 6) return 0;
if (buffer[0] != '-' && buffer[0] != '+') return 0;
switch (buffer[1])
{
if (length != 3 && length != 5 && length != 6)
return 0;
if (buffer[0] != '-' && buffer[0] != '+')
return 0;
switch (buffer[1]) {
case '0':
if (buffer[2] < '0' || buffer[2] > '9') return 0;
if (buffer[2] < '0' || buffer[2] > '9')
return 0;
break;
case '1':
if (buffer[2] < '0' || (buffer[0] == '-' && buffer[2] > '2') || (buffer[0] == '+' && buffer[2] > '4')) return 0;
if (buffer[2] < '0' || (buffer[0] == '-' && buffer[2] > '2') || (buffer[0] == '+' && buffer[2] > '4'))
return 0;
break;
default:
return 0;
}
switch (length)
{
switch (length) {
case 3:
return 1;
case 5:
min_index = 3;
break;
case 6:
if (buffer[3] != ':') return 0;
if (buffer[3] != ':')
return 0;
min_index = 4;
break;
default:
// never happen
return 0;
}
if (buffer[min_index] < '0' || buffer[min_index] > '5') return 0;
if (buffer[min_index+1] < '0' || buffer[min_index+1] > '9') return 0;
if (buffer[min_index] < '0' || buffer[min_index] > '5')
return 0;
if (buffer[min_index + 1] < '0' || buffer[min_index + 1] > '9')
return 0;
return 1;
}
static uint8_t prv_set_value(lwm2m_data_t * dataP,
device_data_t * devDataP)
{
lwm2m_data_t * subTlvP;
static uint8_t prv_set_value(lwm2m_data_t *dataP, device_data_t *devDataP) {
lwm2m_data_t *subTlvP;
size_t count;
size_t i;
// a simple switch structure is used to respond at the specified resource asked
switch (dataP->id)
{
switch (dataP->id) {
case RES_O_MANUFACTURER:
if (dataP->type == LWM2M_TYPE_MULTIPLE_RESOURCE) return COAP_404_NOT_FOUND;
if (dataP->type == LWM2M_TYPE_MULTIPLE_RESOURCE)
return COAP_404_NOT_FOUND;
lwm2m_data_encode_string(PRV_MANUFACTURER, dataP);
return COAP_205_CONTENT;
case RES_O_MODEL_NUMBER:
if (dataP->type == LWM2M_TYPE_MULTIPLE_RESOURCE) return COAP_404_NOT_FOUND;
if (dataP->type == LWM2M_TYPE_MULTIPLE_RESOURCE)
return COAP_404_NOT_FOUND;
lwm2m_data_encode_string(PRV_MODEL_NUMBER, dataP);
return COAP_205_CONTENT;
case RES_O_SERIAL_NUMBER:
if (dataP->type == LWM2M_TYPE_MULTIPLE_RESOURCE) return COAP_404_NOT_FOUND;
if (dataP->type == LWM2M_TYPE_MULTIPLE_RESOURCE)
return COAP_404_NOT_FOUND;
lwm2m_data_encode_string(PRV_SERIAL_NUMBER, dataP);
return COAP_205_CONTENT;
case RES_O_FIRMWARE_VERSION:
if (dataP->type == LWM2M_TYPE_MULTIPLE_RESOURCE) return COAP_404_NOT_FOUND;
if (dataP->type == LWM2M_TYPE_MULTIPLE_RESOURCE)
return COAP_404_NOT_FOUND;
lwm2m_data_encode_string(PRV_FIRMWARE_VERSION, dataP);
return COAP_205_CONTENT;
@ -197,25 +197,20 @@ static uint8_t prv_set_value(lwm2m_data_t * dataP,
case RES_O_FACTORY_RESET:
return COAP_405_METHOD_NOT_ALLOWED;
case RES_O_AVL_POWER_SOURCES:
{
if (dataP->type == LWM2M_TYPE_MULTIPLE_RESOURCE)
{
case RES_O_AVL_POWER_SOURCES: {
if (dataP->type == LWM2M_TYPE_MULTIPLE_RESOURCE) {
count = dataP->value.asChildren.count;
subTlvP = dataP->value.asChildren.array;
}
else
{
} else {
count = 2;
subTlvP = lwm2m_data_new(count);
for (i = 0; i < count; i++) subTlvP[i].id = i;
for (i = 0; i < count; i++)
subTlvP[i].id = i;
lwm2m_data_encode_instances(subTlvP, count, dataP);
}
for (i = 0; i < count; i++)
{
switch (subTlvP[i].id)
{
for (i = 0; i < count; i++) {
switch (subTlvP[i].id) {
case 0:
lwm2m_data_encode_int(PRV_POWER_SOURCE_1, subTlvP + i);
break;
@ -230,25 +225,20 @@ static uint8_t prv_set_value(lwm2m_data_t * dataP,
return COAP_205_CONTENT;
}
case RES_O_POWER_SOURCE_VOLTAGE:
{
if (dataP->type == LWM2M_TYPE_MULTIPLE_RESOURCE)
{
case RES_O_POWER_SOURCE_VOLTAGE: {
if (dataP->type == LWM2M_TYPE_MULTIPLE_RESOURCE) {
count = dataP->value.asChildren.count;
subTlvP = dataP->value.asChildren.array;
}
else
{
} else {
count = 2;
subTlvP = lwm2m_data_new(count);
for (i = 0; i < count; i++) subTlvP[i].id = i;
for (i = 0; i < count; i++)
subTlvP[i].id = i;
lwm2m_data_encode_instances(subTlvP, count, dataP);
}
for (i = 0; i < count; i++)
{
switch (subTlvP[i].id)
{
for (i = 0; i < count; i++) {
switch (subTlvP[i].id) {
case 0:
lwm2m_data_encode_int(PRV_POWER_VOLTAGE_1, subTlvP + i);
break;
@ -263,25 +253,20 @@ static uint8_t prv_set_value(lwm2m_data_t * dataP,
return COAP_205_CONTENT;
}
case RES_O_POWER_SOURCE_CURRENT:
{
if (dataP->type == LWM2M_TYPE_MULTIPLE_RESOURCE)
{
case RES_O_POWER_SOURCE_CURRENT: {
if (dataP->type == LWM2M_TYPE_MULTIPLE_RESOURCE) {
count = dataP->value.asChildren.count;
subTlvP = dataP->value.asChildren.array;
}
else
{
} else {
count = 2;
subTlvP = lwm2m_data_new(count);
for (i = 0; i < count; i++) subTlvP[i].id = i;
for (i = 0; i < count; i++)
subTlvP[i].id = i;
lwm2m_data_encode_instances(subTlvP, count, dataP);
}
for (i = 0; i < count; i++)
{
switch (subTlvP[i].id)
{
for (i = 0; i < count; i++) {
switch (subTlvP[i].id) {
case 0:
lwm2m_data_encode_int(PRV_POWER_CURRENT_1, subTlvP + i);
break;
@ -297,34 +282,31 @@ static uint8_t prv_set_value(lwm2m_data_t * dataP,
}
case RES_O_BATTERY_LEVEL:
if (dataP->type == LWM2M_TYPE_MULTIPLE_RESOURCE) return COAP_404_NOT_FOUND;
if (dataP->type == LWM2M_TYPE_MULTIPLE_RESOURCE)
return COAP_404_NOT_FOUND;
lwm2m_data_encode_int(devDataP->battery_level, dataP);
return COAP_205_CONTENT;
case RES_O_MEMORY_FREE:
if (dataP->type == LWM2M_TYPE_MULTIPLE_RESOURCE) return COAP_404_NOT_FOUND;
if (dataP->type == LWM2M_TYPE_MULTIPLE_RESOURCE)
return COAP_404_NOT_FOUND;
lwm2m_data_encode_int(devDataP->free_memory, dataP);
return COAP_205_CONTENT;
case RES_M_ERROR_CODE:
{
if (dataP->type == LWM2M_TYPE_MULTIPLE_RESOURCE)
{
case RES_M_ERROR_CODE: {
if (dataP->type == LWM2M_TYPE_MULTIPLE_RESOURCE) {
count = dataP->value.asChildren.count;
subTlvP = dataP->value.asChildren.array;
}
else
{
} else {
count = 1;
subTlvP = lwm2m_data_new(count);
for (i = 0; i < count; i++) subTlvP[i].id = i;
for (i = 0; i < count; i++)
subTlvP[i].id = i;
lwm2m_data_encode_instances(subTlvP, count, dataP);
}
for (i = 0; i < count; i++)
{
switch (subTlvP[i].id)
{
for (i = 0; i < count; i++) {
switch (subTlvP[i].id) {
case 0:
lwm2m_data_encode_int(devDataP->error, subTlvP + i);
break;
@ -334,27 +316,31 @@ static uint8_t prv_set_value(lwm2m_data_t * dataP,
}
return COAP_205_CONTENT;
}
}
case RES_O_RESET_ERROR_CODE:
return COAP_405_METHOD_NOT_ALLOWED;
case RES_O_CURRENT_TIME:
if (dataP->type == LWM2M_TYPE_MULTIPLE_RESOURCE) return COAP_404_NOT_FOUND;
if (dataP->type == LWM2M_TYPE_MULTIPLE_RESOURCE)
return COAP_404_NOT_FOUND;
lwm2m_data_encode_int(time(NULL) + devDataP->time, dataP);
return COAP_205_CONTENT;
case RES_O_UTC_OFFSET:
if (dataP->type == LWM2M_TYPE_MULTIPLE_RESOURCE) return COAP_404_NOT_FOUND;
if (dataP->type == LWM2M_TYPE_MULTIPLE_RESOURCE)
return COAP_404_NOT_FOUND;
lwm2m_data_encode_string(devDataP->time_offset, dataP);
return COAP_205_CONTENT;
case RES_O_TIMEZONE:
if (dataP->type == LWM2M_TYPE_MULTIPLE_RESOURCE) return COAP_404_NOT_FOUND;
if (dataP->type == LWM2M_TYPE_MULTIPLE_RESOURCE)
return COAP_404_NOT_FOUND;
lwm2m_data_encode_string(PRV_TIME_ZONE, dataP);
return COAP_205_CONTENT;
case RES_M_BINDING_MODES:
if (dataP->type == LWM2M_TYPE_MULTIPLE_RESOURCE) return COAP_404_NOT_FOUND;
if (dataP->type == LWM2M_TYPE_MULTIPLE_RESOURCE)
return COAP_404_NOT_FOUND;
lwm2m_data_encode_string(PRV_BINDING_MODE, dataP);
return COAP_205_CONTENT;
@ -363,12 +349,8 @@ static uint8_t prv_set_value(lwm2m_data_t * dataP,
}
}
static uint8_t prv_device_read(lwm2m_context_t *contextP,
uint16_t instanceId,
int * numDataP,
lwm2m_data_t ** dataArrayP,
lwm2m_object_t * objectP)
{
static uint8_t prv_device_read(lwm2m_context_t *contextP, uint16_t instanceId, int *numDataP, lwm2m_data_t **dataArrayP,
lwm2m_object_t *objectP) {
uint8_t result;
int i;
@ -376,60 +358,41 @@ static uint8_t prv_device_read(lwm2m_context_t *contextP,
(void)contextP;
// this is a single instance object
if (instanceId != 0)
{
if (instanceId != 0) {
return COAP_404_NOT_FOUND;
}
// is the server asking for the full object ?
if (*numDataP == 0)
{
uint16_t resList[] = {
RES_O_MANUFACTURER,
RES_O_MODEL_NUMBER,
RES_O_SERIAL_NUMBER,
RES_O_FIRMWARE_VERSION,
//E: RES_M_REBOOT,
//E: RES_O_FACTORY_RESET,
RES_O_AVL_POWER_SOURCES,
RES_O_POWER_SOURCE_VOLTAGE,
RES_O_POWER_SOURCE_CURRENT,
RES_O_BATTERY_LEVEL,
RES_O_MEMORY_FREE,
RES_M_ERROR_CODE,
//E: RES_O_RESET_ERROR_CODE,
RES_O_CURRENT_TIME,
RES_O_UTC_OFFSET,
RES_O_TIMEZONE,
RES_M_BINDING_MODES
};
int nbRes = sizeof(resList)/sizeof(uint16_t);
if (*numDataP == 0) {
uint16_t resList[] = {RES_O_MANUFACTURER, RES_O_MODEL_NUMBER, RES_O_SERIAL_NUMBER, RES_O_FIRMWARE_VERSION,
// E: RES_M_REBOOT,
// E: RES_O_FACTORY_RESET,
RES_O_AVL_POWER_SOURCES, RES_O_POWER_SOURCE_VOLTAGE, RES_O_POWER_SOURCE_CURRENT,
RES_O_BATTERY_LEVEL, RES_O_MEMORY_FREE, RES_M_ERROR_CODE,
// E: RES_O_RESET_ERROR_CODE,
RES_O_CURRENT_TIME, RES_O_UTC_OFFSET, RES_O_TIMEZONE, RES_M_BINDING_MODES};
int nbRes = sizeof(resList) / sizeof(uint16_t);
*dataArrayP = lwm2m_data_new(nbRes);
if (*dataArrayP == NULL) return COAP_500_INTERNAL_SERVER_ERROR;
if (*dataArrayP == NULL)
return COAP_500_INTERNAL_SERVER_ERROR;
*numDataP = nbRes;
for (i = 0 ; i < nbRes ; i++)
{
for (i = 0; i < nbRes; i++) {
(*dataArrayP)[i].id = resList[i];
}
}
i = 0;
do
{
result = prv_set_value((*dataArrayP) + i, (device_data_t*)(objectP->userData));
do {
result = prv_set_value((*dataArrayP) + i, (device_data_t *)(objectP->userData));
i++;
} while (i < *numDataP && result == COAP_205_CONTENT);
return result;
}
static uint8_t prv_device_discover(lwm2m_context_t *contextP,
uint16_t instanceId,
int * numDataP,
lwm2m_data_t ** dataArrayP,
lwm2m_object_t * objectP)
{
static uint8_t prv_device_discover(lwm2m_context_t *contextP, uint16_t instanceId, int *numDataP,
lwm2m_data_t **dataArrayP, lwm2m_object_t *objectP) {
uint8_t result;
int i;
@ -437,51 +400,43 @@ static uint8_t prv_device_discover(lwm2m_context_t *contextP,
(void)contextP;
// this is a single instance object
if (instanceId != 0)
{
if (instanceId != 0) {
return COAP_404_NOT_FOUND;
}
result = COAP_205_CONTENT;
// is the server asking for the full object ?
if (*numDataP == 0)
{
uint16_t resList[] = {
RES_O_MANUFACTURER,
RES_O_MODEL_NUMBER,
RES_O_SERIAL_NUMBER,
RES_O_FIRMWARE_VERSION,
RES_M_REBOOT,
RES_O_FACTORY_RESET,
RES_O_AVL_POWER_SOURCES,
RES_O_POWER_SOURCE_VOLTAGE,
RES_O_POWER_SOURCE_CURRENT,
RES_O_BATTERY_LEVEL,
RES_O_MEMORY_FREE,
RES_M_ERROR_CODE,
RES_O_RESET_ERROR_CODE,
RES_O_CURRENT_TIME,
RES_O_UTC_OFFSET,
RES_O_TIMEZONE,
RES_M_BINDING_MODES
};
if (*numDataP == 0) {
uint16_t resList[] = {RES_O_MANUFACTURER,
RES_O_MODEL_NUMBER,
RES_O_SERIAL_NUMBER,
RES_O_FIRMWARE_VERSION,
RES_M_REBOOT,
RES_O_FACTORY_RESET,
RES_O_AVL_POWER_SOURCES,
RES_O_POWER_SOURCE_VOLTAGE,
RES_O_POWER_SOURCE_CURRENT,
RES_O_BATTERY_LEVEL,
RES_O_MEMORY_FREE,
RES_M_ERROR_CODE,
RES_O_RESET_ERROR_CODE,
RES_O_CURRENT_TIME,
RES_O_UTC_OFFSET,
RES_O_TIMEZONE,
RES_M_BINDING_MODES};
int nbRes = sizeof(resList) / sizeof(uint16_t);
*dataArrayP = lwm2m_data_new(nbRes);
if (*dataArrayP == NULL) return COAP_500_INTERNAL_SERVER_ERROR;
if (*dataArrayP == NULL)
return COAP_500_INTERNAL_SERVER_ERROR;
*numDataP = nbRes;
for (i = 0; i < nbRes; i++)
{
for (i = 0; i < nbRes; i++) {
(*dataArrayP)[i].id = resList[i];
}
}
else
{
for (i = 0; i < *numDataP && result == COAP_205_CONTENT; i++)
{
switch ((*dataArrayP)[i].id)
{
} else {
for (i = 0; i < *numDataP && result == COAP_205_CONTENT; i++) {
switch ((*dataArrayP)[i].id) {
case RES_O_MANUFACTURER:
case RES_O_MODEL_NUMBER:
case RES_O_SERIAL_NUMBER:
@ -509,13 +464,8 @@ static uint8_t prv_device_discover(lwm2m_context_t *contextP,
return result;
}
static uint8_t prv_device_write(lwm2m_context_t *contextP,
uint16_t instanceId,
int numData,
lwm2m_data_t * dataArray,
lwm2m_object_t * objectP,
lwm2m_write_type_t writeType)
{
static uint8_t prv_device_write(lwm2m_context_t *contextP, uint16_t instanceId, int numData, lwm2m_data_t *dataArray,
lwm2m_object_t *objectP, lwm2m_write_type_t writeType) {
int i;
uint8_t result;
@ -526,54 +476,46 @@ static uint8_t prv_device_write(lwm2m_context_t *contextP,
(void)writeType;
// this is a single instance object
if (instanceId != 0)
{
if (instanceId != 0) {
return COAP_404_NOT_FOUND;
}
i = 0;
do
{
do {
/* No multiple instance resources */
if (dataArray[i].type == LWM2M_TYPE_MULTIPLE_RESOURCE)
{
if (dataArray[i].type == LWM2M_TYPE_MULTIPLE_RESOURCE) {
result = COAP_404_NOT_FOUND;
continue;
}
switch (dataArray[i].id)
{
switch (dataArray[i].id) {
case RES_O_CURRENT_TIME:
if (1 == lwm2m_data_decode_int(dataArray + i, &((device_data_t*)(objectP->userData))->time))
{
((device_data_t*)(objectP->userData))->time -= time(NULL);
if (1 == lwm2m_data_decode_int(dataArray + i, &((device_data_t *)(objectP->userData))->time)) {
((device_data_t *)(objectP->userData))->time -= time(NULL);
result = COAP_204_CHANGED;
}
else
{
} else {
result = COAP_400_BAD_REQUEST;
}
break;
case RES_O_UTC_OFFSET:
if (1 == prv_check_time_offset((char*)dataArray[i].value.asBuffer.buffer, dataArray[i].value.asBuffer.length))
{
strncpy(((device_data_t*)(objectP->userData))->time_offset, (char*)dataArray[i].value.asBuffer.buffer, dataArray[i].value.asBuffer.length);
((device_data_t*)(objectP->userData))->time_offset[dataArray[i].value.asBuffer.length] = 0;
if (1 ==
prv_check_time_offset((char *)dataArray[i].value.asBuffer.buffer, dataArray[i].value.asBuffer.length)) {
strncpy(((device_data_t *)(objectP->userData))->time_offset, // NOSONAR
(char *)dataArray[i].value.asBuffer.buffer, dataArray[i].value.asBuffer.length);
((device_data_t *)(objectP->userData))->time_offset[dataArray[i].value.asBuffer.length] = 0;
result = COAP_204_CHANGED;
}
else
{
} else {
result = COAP_400_BAD_REQUEST;
}
break;
case RES_O_TIMEZONE:
//ToDo IANA TZ Format
// ToDo IANA TZ Format
result = COAP_501_NOT_IMPLEMENTED;
break;
default:
result = COAP_405_METHOD_NOT_ALLOWED;
}
@ -584,26 +526,20 @@ static uint8_t prv_device_write(lwm2m_context_t *contextP,
return result;
}
static uint8_t prv_device_execute(lwm2m_context_t *contextP,
uint16_t instanceId,
uint16_t resourceId,
uint8_t * buffer,
int length,
lwm2m_object_t * objectP)
{
static uint8_t prv_device_execute(lwm2m_context_t *contextP, uint16_t instanceId, uint16_t resourceId, uint8_t *buffer,
int length, lwm2m_object_t *objectP) {
/* unused parameter */
(void)contextP;
// this is a single instance object
if (instanceId != 0)
{
if (instanceId != 0) {
return COAP_404_NOT_FOUND;
}
if (length != 0) return COAP_400_BAD_REQUEST;
if (length != 0)
return COAP_400_BAD_REQUEST;
switch (resourceId)
{
switch (resourceId) {
case RES_M_REBOOT:
fprintf(stdout, "\n\t REBOOT\r\n\n");
g_reboot = 1;
@ -613,21 +549,18 @@ static uint8_t prv_device_execute(lwm2m_context_t *contextP,
return COAP_204_CHANGED;
case RES_O_RESET_ERROR_CODE:
fprintf(stdout, "\n\t RESET ERROR CODE\r\n\n");
((device_data_t*)(objectP->userData))->error = 0;
((device_data_t *)(objectP->userData))->error = 0;
return COAP_204_CHANGED;
default:
return COAP_405_METHOD_NOT_ALLOWED;
}
}
void display_device_object(lwm2m_object_t * object)
{
device_data_t * data = (device_data_t *)object->userData;
void display_device_object(lwm2m_object_t *object) {
device_data_t *data = (device_data_t *)object->userData;
fprintf(stdout, " /%u: Device object:\r\n", object->objID);
if (NULL != data)
{
fprintf(stdout, " time: %lld, time_offset: %s\r\n",
(long long) data->time, data->time_offset);
if (NULL != data) {
fprintf(stdout, " time: %lld, time_offset: %s\r\n", (long long)data->time, data->time_offset);
}
}
@ -635,12 +568,11 @@ lwm2m_object_t *get_object_device(void) {
/*
* The get_object_device function create the object itself and return a pointer to the structure that represent it.
*/
lwm2m_object_t * deviceObj;
lwm2m_object_t *deviceObj;
deviceObj = (lwm2m_object_t *)lwm2m_malloc(sizeof(lwm2m_object_t));
if (NULL != deviceObj)
{
if (NULL != deviceObj) {
memset(deviceObj, 0, sizeof(lwm2m_object_t));
/*
@ -654,40 +586,34 @@ lwm2m_object_t *get_object_device(void) {
*
*/
deviceObj->instanceList = (lwm2m_list_t *)lwm2m_malloc(sizeof(lwm2m_list_t));
if (NULL != deviceObj->instanceList)
{
if (NULL != deviceObj->instanceList) {
memset(deviceObj->instanceList, 0, sizeof(lwm2m_list_t));
}
else
{
} else {
lwm2m_free(deviceObj);
return NULL;
}
/*
* And the private function that will access the object.
* Those function will be called when a read/write/execute query is made by the server. In fact the library don't need to
* know the resources of the object, only the server does.
* Those function will be called when a read/write/execute query is made by the server. In fact the library
* don't need to know the resources of the object, only the server does.
*/
deviceObj->readFunc = prv_device_read;
deviceObj->readFunc = prv_device_read;
deviceObj->discoverFunc = prv_device_discover;
deviceObj->writeFunc = prv_device_write;
deviceObj->executeFunc = prv_device_execute;
deviceObj->writeFunc = prv_device_write;
deviceObj->executeFunc = prv_device_execute;
deviceObj->userData = lwm2m_malloc(sizeof(device_data_t));
/*
* Also some user data can be stored in the object with a private structure containing the needed variables
* Also some user data can be stored in the object with a private structure containing the needed variables
*/
if (NULL != deviceObj->userData)
{
((device_data_t*)deviceObj->userData)->battery_level = PRV_BATTERY_LEVEL;
((device_data_t*)deviceObj->userData)->free_memory = PRV_MEMORY_FREE;
((device_data_t*)deviceObj->userData)->error = PRV_ERROR_CODE;
((device_data_t*)deviceObj->userData)->time = 1367491215;
strcpy(((device_data_t*)deviceObj->userData)->time_offset, "+01:00");
}
else
{
if (NULL != deviceObj->userData) {
((device_data_t *)deviceObj->userData)->battery_level = PRV_BATTERY_LEVEL;
((device_data_t *)deviceObj->userData)->free_memory = PRV_MEMORY_FREE;
((device_data_t *)deviceObj->userData)->error = PRV_ERROR_CODE;
((device_data_t *)deviceObj->userData)->time = 1367491215;
strcpy(((device_data_t *)deviceObj->userData)->time_offset, "+01:00"); // NOSONAR
} else {
lwm2m_free(deviceObj->instanceList);
lwm2m_free(deviceObj);
deviceObj = NULL;
@ -697,15 +623,12 @@ lwm2m_object_t *get_object_device(void) {
return deviceObj;
}
void free_object_device(lwm2m_object_t * objectP)
{
if (NULL != objectP->userData)
{
void free_object_device(lwm2m_object_t *objectP) {
if (NULL != objectP->userData) {
lwm2m_free(objectP->userData);
objectP->userData = NULL;
}
if (NULL != objectP->instanceList)
{
if (NULL != objectP->instanceList) {
lwm2m_free(objectP->instanceList);
objectP->instanceList = NULL;
}
@ -713,58 +636,41 @@ void free_object_device(lwm2m_object_t * objectP)
lwm2m_free(objectP);
}
uint8_t device_change(lwm2m_data_t * dataArray,
lwm2m_object_t * objectP)
{
uint8_t device_change(lwm2m_data_t *dataArray, lwm2m_object_t *objectP) {
uint8_t result;
switch (dataArray->id)
{
case RES_O_BATTERY_LEVEL:
{
int64_t value;
if (1 == lwm2m_data_decode_int(dataArray, &value))
{
if ((0 <= value) && (100 >= value))
{
((device_data_t*)(objectP->userData))->battery_level = value;
result = COAP_204_CHANGED;
}
else
{
result = COAP_400_BAD_REQUEST;
}
}
else
{
result = COAP_400_BAD_REQUEST;
}
}
break;
case RES_M_ERROR_CODE:
if (1 == lwm2m_data_decode_int(dataArray, &((device_data_t*)(objectP->userData))->error))
{
switch (dataArray->id) {
case RES_O_BATTERY_LEVEL: {
int64_t value;
if (1 == lwm2m_data_decode_int(dataArray, &value)) {
if ((0 <= value) && (100 >= value)) {
((device_data_t *)(objectP->userData))->battery_level = value;
result = COAP_204_CHANGED;
}
else
{
} else {
result = COAP_400_BAD_REQUEST;
}
break;
case RES_O_MEMORY_FREE:
if (1 == lwm2m_data_decode_int(dataArray, &((device_data_t*)(objectP->userData))->free_memory))
{
result = COAP_204_CHANGED;
}
else
{
result = COAP_400_BAD_REQUEST;
}
break;
default:
result = COAP_405_METHOD_NOT_ALLOWED;
break;
} else {
result = COAP_400_BAD_REQUEST;
}
} break;
case RES_M_ERROR_CODE:
if (1 == lwm2m_data_decode_int(dataArray, &((device_data_t *)(objectP->userData))->error)) {
result = COAP_204_CHANGED;
} else {
result = COAP_400_BAD_REQUEST;
}
break;
case RES_O_MEMORY_FREE:
if (1 == lwm2m_data_decode_int(dataArray, &((device_data_t *)(objectP->userData))->free_memory)) {
result = COAP_204_CHANGED;
} else {
result = COAP_400_BAD_REQUEST;
}
break;
default:
result = COAP_405_METHOD_NOT_ALLOWED;
break;
}
return result;
}

View File

@ -41,28 +41,27 @@
#include "liblwm2m.h"
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
// ---- private object "Firmware" specific defines ----
// Resource Id's:
#define RES_M_PACKAGE 0
#define RES_M_PACKAGE_URI 1
#define RES_M_UPDATE 2
#define RES_M_STATE 3
#define RES_M_UPDATE_RESULT 5
#define RES_O_PKG_NAME 6
#define RES_O_PKG_VERSION 7
#define RES_O_UPDATE_PROTOCOL 8
#define RES_M_UPDATE_METHOD 9
#define RES_M_PACKAGE 0
#define RES_M_PACKAGE_URI 1
#define RES_M_UPDATE 2
#define RES_M_STATE 3
#define RES_M_UPDATE_RESULT 5
#define RES_O_PKG_NAME 6
#define RES_O_PKG_VERSION 7
#define RES_O_UPDATE_PROTOCOL 8
#define RES_M_UPDATE_METHOD 9
#define LWM2M_FIRMWARE_PROTOCOL_NUM 4
#define LWM2M_FIRMWARE_PROTOCOL_NULL ((uint8_t)-1)
#define LWM2M_FIRMWARE_PROTOCOL_NUM 4
#define LWM2M_FIRMWARE_PROTOCOL_NULL ((uint8_t) - 1)
typedef struct
{
typedef struct {
uint8_t state;
uint8_t result;
char pkg_name[256];
@ -71,30 +70,25 @@ typedef struct
uint8_t delivery_method;
} firmware_data_t;
static uint8_t prv_firmware_read(lwm2m_context_t *contextP,
uint16_t instanceId,
int * numDataP,
lwm2m_data_t ** dataArrayP,
lwm2m_object_t * objectP)
{
static uint8_t prv_firmware_read(lwm2m_context_t *contextP, uint16_t instanceId, int *numDataP,
lwm2m_data_t **dataArrayP, lwm2m_object_t *objectP) {
int i;
uint8_t result;
firmware_data_t * data = (firmware_data_t*)(objectP->userData);
firmware_data_t *data = (firmware_data_t *)(objectP->userData);
/* unused parameter */
(void)contextP;
// this is a single instance object
if (instanceId != 0)
{
if (instanceId != 0) {
return COAP_404_NOT_FOUND;
}
// is the server asking for the full object ?
if (*numDataP == 0)
{
if (*numDataP == 0) {
*dataArrayP = lwm2m_data_new(6);
if (*dataArrayP == NULL) return COAP_500_INTERNAL_SERVER_ERROR;
if (*dataArrayP == NULL)
return COAP_500_INTERNAL_SERVER_ERROR;
*numDataP = 6;
(*dataArrayP)[0].id = 3;
(*dataArrayP)[1].id = 5;
@ -105,10 +99,8 @@ static uint8_t prv_firmware_read(lwm2m_context_t *contextP,
}
i = 0;
do
{
switch ((*dataArrayP)[i].id)
{
do {
switch ((*dataArrayP)[i].id) {
case RES_M_PACKAGE:
case RES_M_PACKAGE_URI:
case RES_M_UPDATE:
@ -117,69 +109,66 @@ static uint8_t prv_firmware_read(lwm2m_context_t *contextP,
case RES_M_STATE:
// firmware update state (int)
if ((*dataArrayP)[i].type == LWM2M_TYPE_MULTIPLE_RESOURCE) return COAP_404_NOT_FOUND;
if ((*dataArrayP)[i].type == LWM2M_TYPE_MULTIPLE_RESOURCE)
return COAP_404_NOT_FOUND;
lwm2m_data_encode_int(data->state, *dataArrayP + i);
result = COAP_205_CONTENT;
break;
case RES_M_UPDATE_RESULT:
if ((*dataArrayP)[i].type == LWM2M_TYPE_MULTIPLE_RESOURCE) return COAP_404_NOT_FOUND;
if ((*dataArrayP)[i].type == LWM2M_TYPE_MULTIPLE_RESOURCE)
return COAP_404_NOT_FOUND;
lwm2m_data_encode_int(data->result, *dataArrayP + i);
result = COAP_205_CONTENT;
break;
case RES_O_PKG_NAME:
if ((*dataArrayP)[i].type == LWM2M_TYPE_MULTIPLE_RESOURCE) return COAP_404_NOT_FOUND;
if ((*dataArrayP)[i].type == LWM2M_TYPE_MULTIPLE_RESOURCE)
return COAP_404_NOT_FOUND;
lwm2m_data_encode_string(data->pkg_name, *dataArrayP + i);
result = COAP_205_CONTENT;
break;
case RES_O_PKG_VERSION:
if ((*dataArrayP)[i].type == LWM2M_TYPE_MULTIPLE_RESOURCE) return COAP_404_NOT_FOUND;
if ((*dataArrayP)[i].type == LWM2M_TYPE_MULTIPLE_RESOURCE)
return COAP_404_NOT_FOUND;
lwm2m_data_encode_string(data->pkg_version, *dataArrayP + i);
result = COAP_205_CONTENT;
break;
case RES_O_UPDATE_PROTOCOL:
{
lwm2m_data_t * subTlvP;
case RES_O_UPDATE_PROTOCOL: {
lwm2m_data_t *subTlvP;
size_t count;
size_t ri;
int num = 0;
while ((num < LWM2M_FIRMWARE_PROTOCOL_NUM) &&
(data->protocol_support[num] != LWM2M_FIRMWARE_PROTOCOL_NULL))
while ((num < LWM2M_FIRMWARE_PROTOCOL_NUM) && (data->protocol_support[num] != LWM2M_FIRMWARE_PROTOCOL_NULL))
num++;
if ((*dataArrayP)[i].type == LWM2M_TYPE_MULTIPLE_RESOURCE)
{
if ((*dataArrayP)[i].type == LWM2M_TYPE_MULTIPLE_RESOURCE) {
count = (*dataArrayP)[i].value.asChildren.count;
subTlvP = (*dataArrayP)[i].value.asChildren.array;
}
else
{
} else {
count = num;
if (!count) count = 1;
if (!count)
count = 1;
subTlvP = lwm2m_data_new(count);
for (ri = 0; ri < count; ri++) subTlvP[ri].id = ri;
for (ri = 0; ri < count; ri++)
subTlvP[ri].id = ri;
lwm2m_data_encode_instances(subTlvP, count, *dataArrayP + i);
}
if (num)
{
for (ri = 0; ri < count; ri++)
{
if (subTlvP[ri].id >= num) return COAP_404_NOT_FOUND;
lwm2m_data_encode_int(data->protocol_support[subTlvP[ri].id],
subTlvP + ri);
if (num) {
for (ri = 0; ri < count; ri++) {
if (subTlvP[ri].id >= num)
return COAP_404_NOT_FOUND;
lwm2m_data_encode_int(data->protocol_support[subTlvP[ri].id], subTlvP + ri);
}
}
else
{
} else {
/* If no protocol is provided, use CoAP as default (per spec) */
for (ri = 0; ri < count; ri++)
{
if (subTlvP[ri].id != 0) return COAP_404_NOT_FOUND;
for (ri = 0; ri < count; ri++) {
if (subTlvP[ri].id != 0)
return COAP_404_NOT_FOUND;
lwm2m_data_encode_int(0, subTlvP + ri);
}
}
@ -188,7 +177,8 @@ static uint8_t prv_firmware_read(lwm2m_context_t *contextP,
}
case RES_M_UPDATE_METHOD:
if ((*dataArrayP)[i].type == LWM2M_TYPE_MULTIPLE_RESOURCE) return COAP_404_NOT_FOUND;
if ((*dataArrayP)[i].type == LWM2M_TYPE_MULTIPLE_RESOURCE)
return COAP_404_NOT_FOUND;
lwm2m_data_encode_int(data->delivery_method, *dataArrayP + i);
result = COAP_205_CONTENT;
break;
@ -203,13 +193,8 @@ static uint8_t prv_firmware_read(lwm2m_context_t *contextP,
return result;
}
static uint8_t prv_firmware_write(lwm2m_context_t *contextP,
uint16_t instanceId,
int numData,
lwm2m_data_t * dataArray,
lwm2m_object_t * objectP,
lwm2m_write_type_t writeType)
{
static uint8_t prv_firmware_write(lwm2m_context_t *contextP, uint16_t instanceId, int numData, lwm2m_data_t *dataArray,
lwm2m_object_t *objectP, lwm2m_write_type_t writeType) {
int i;
uint8_t result;
@ -220,24 +205,20 @@ static uint8_t prv_firmware_write(lwm2m_context_t *contextP,
(void)writeType;
// this is a single instance object
if (instanceId != 0)
{
if (instanceId != 0) {
return COAP_404_NOT_FOUND;
}
i = 0;
do
{
do {
/* No multiple instance resources */
if (dataArray[i].type == LWM2M_TYPE_MULTIPLE_RESOURCE)
{
if (dataArray[i].type == LWM2M_TYPE_MULTIPLE_RESOURCE) {
result = COAP_404_NOT_FOUND;
continue;
}
switch (dataArray[i].id)
{
switch (dataArray[i].id) {
case RES_M_PACKAGE:
// inline firmware binary
result = COAP_204_CHANGED;
@ -258,39 +239,30 @@ static uint8_t prv_firmware_write(lwm2m_context_t *contextP,
return result;
}
static uint8_t prv_firmware_execute(lwm2m_context_t *contextP,
uint16_t instanceId,
uint16_t resourceId,
uint8_t * buffer,
int length,
lwm2m_object_t * objectP)
{
firmware_data_t * data = (firmware_data_t*)(objectP->userData);
static uint8_t prv_firmware_execute(lwm2m_context_t *contextP, uint16_t instanceId, uint16_t resourceId,
uint8_t *buffer, int length, lwm2m_object_t *objectP) {
firmware_data_t *data = (firmware_data_t *)(objectP->userData);
/* unused parameter */
(void)contextP;
// this is a single instance object
if (instanceId != 0)
{
if (instanceId != 0) {
return COAP_404_NOT_FOUND;
}
if (length != 0) return COAP_400_BAD_REQUEST;
if (length != 0)
return COAP_400_BAD_REQUEST;
// for execute callback, resId is always set.
switch (resourceId)
{
switch (resourceId) {
case RES_M_UPDATE:
if (data->state == 1)
{
if (data->state == 1) {
fprintf(stdout, "\n\t FIRMWARE UPDATE\r\n\n");
// trigger your firmware download and update logic
data->state = 2;
return COAP_204_CHANGED;
}
else
{
} else {
// firmware update already running
return COAP_400_BAD_REQUEST;
}
@ -313,28 +285,24 @@ static uint8_t prv_firmware_raw_block1_write(lwm2m_context_t *contextP, lwm2m_ur
}
#endif
void display_firmware_object(lwm2m_object_t * object)
{
firmware_data_t * data = (firmware_data_t *)object->userData;
void display_firmware_object(lwm2m_object_t *object) {
firmware_data_t *data = (firmware_data_t *)object->userData;
fprintf(stdout, " /%u: Firmware object:\r\n", object->objID);
if (NULL != data)
{
fprintf(stdout, " state: %u, result: %u\r\n", data->state,
data->result);
if (NULL != data) {
fprintf(stdout, " state: %u, result: %u\r\n", data->state, data->result);
}
}
lwm2m_object_t * get_object_firmware(void)
{
lwm2m_object_t *get_object_firmware(void) {
/*
* The get_object_firmware function create the object itself and return a pointer to the structure that represent it.
* The get_object_firmware function create the object itself and return a pointer to the structure that represent
* it.
*/
lwm2m_object_t * firmwareObj;
lwm2m_object_t *firmwareObj;
firmwareObj = (lwm2m_object_t *)lwm2m_malloc(sizeof(lwm2m_object_t));
if (NULL != firmwareObj)
{
if (NULL != firmwareObj) {
memset(firmwareObj, 0, sizeof(lwm2m_object_t));
/*
@ -348,40 +316,36 @@ lwm2m_object_t * get_object_firmware(void)
*
*/
firmwareObj->instanceList = (lwm2m_list_t *)lwm2m_malloc(sizeof(lwm2m_list_t));
if (NULL != firmwareObj->instanceList)
{
if (NULL != firmwareObj->instanceList) {
memset(firmwareObj->instanceList, 0, sizeof(lwm2m_list_t));
}
else
{
} else {
lwm2m_free(firmwareObj);
return NULL;
}
/*
* And the private function that will access the object.
* Those function will be called when a read/write/execute query is made by the server. In fact the library don't need to
* know the resources of the object, only the server does.
* Those function will be called when a read/write/execute query is made by the server. In fact the library
* don't need to know the resources of the object, only the server does.
*/
firmwareObj->readFunc = prv_firmware_read;
firmwareObj->writeFunc = prv_firmware_write;
firmwareObj->readFunc = prv_firmware_read;
firmwareObj->writeFunc = prv_firmware_write;
firmwareObj->executeFunc = prv_firmware_execute;
#ifdef LWM2M_RAW_BLOCK1_REQUESTS
firmwareObj->rawBlock1WriteFunc = prv_firmware_raw_block1_write;
#endif
firmwareObj->userData = lwm2m_malloc(sizeof(firmware_data_t));
firmwareObj->userData = lwm2m_malloc(sizeof(firmware_data_t));
/*
* Also some user data can be stored in the object with a private structure containing the needed variables
*/
if (NULL != firmwareObj->userData)
{
firmware_data_t *data = (firmware_data_t*)(firmwareObj->userData);
if (NULL != firmwareObj->userData) {
firmware_data_t *data = (firmware_data_t *)(firmwareObj->userData);
data->state = 1;
data->result = 0;
strcpy(data->pkg_name, "lwm2mclient");
strcpy(data->pkg_version, "1.0");
strcpy(data->pkg_name, "lwm2mclient"); // NOSONAR
strcpy(data->pkg_version, "1.0"); // NOSONAR
/* Only support CoAP based protocols */
data->protocol_support[0] = 0;
@ -389,11 +353,9 @@ lwm2m_object_t * get_object_firmware(void)
data->protocol_support[2] = LWM2M_FIRMWARE_PROTOCOL_NULL;
data->protocol_support[3] = LWM2M_FIRMWARE_PROTOCOL_NULL;
/* Only support push method */
data->delivery_method = 1;
}
else
{
/* Only support push method */
data->delivery_method = 1;
} else {
lwm2m_free(firmwareObj);
firmwareObj = NULL;
}
@ -402,18 +364,14 @@ lwm2m_object_t * get_object_firmware(void)
return firmwareObj;
}
void free_object_firmware(lwm2m_object_t * objectP)
{
if (NULL != objectP->userData)
{
void free_object_firmware(lwm2m_object_t *objectP) {
if (NULL != objectP->userData) {
lwm2m_free(objectP->userData);
objectP->userData = NULL;
}
if (NULL != objectP->instanceList)
{
if (NULL != objectP->instanceList) {
lwm2m_free(objectP->instanceList);
objectP->instanceList = NULL;
}
lwm2m_free(objectP);
}

View File

@ -0,0 +1,313 @@
/*******************************************************************************
*
* Copyright (c) 2014 Bosch Software Innovations GmbH, Germany.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v20.html
* The Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Bosch Software Innovations GmbH - Please refer to git log
* Pascal Rieux - Please refer to git log
* Scott Bertin, AMETEK, Inc. - Please refer to git log
*
******************************************************************************/
/*! \file
LWM2M object "Location" implementation
\author Joerg Hubschneider
*/
/*
* Object | | Multiple | | Description |
* Name | ID | Instances |Mand.| |
*-------------+------+-----------+-----+-------------------------------+
* Location | 6 | No | No | see TS E.7 page 101 |
*
* Resources:
* Name | ID | Oper.|Instances|Mand.| Type | Range | Units | Description |
* -------------+-----+------+---------+-----+---------+-------+-------+----------------------------------------------------------------------------------+
* Latitude | 0 | R | Single | Yes | Float | | Deg | The decimal notation of latitude e.g.
*- 45.5723 [Worlds Geodetic System 1984].| Longitude | 1 | R | Single | Yes | Float | | Deg | The
*decimal notation of longitude e.g. - 153.21760 [Worlds Geodetic System 1984].| Altitude | 2 | R | Single | No
*| Float | | m | The decimal notation of altitude in meters above sea level. | Radius
*| 3 | R | Single | No | Float | | m | The value in the Radius Resource indicates the size in meters
*of a circular area | | | | | | | | | around a point of geometry. | Velocity
*| 4 | R | Single | No | Opaque | | * | The velocity of the device as defined in 3GPP 23.032 GAD
*specification(*). | | | | | | | | | This set of values may not be
*available if the device is static. | | | | | | | | | opaque:
*see OMA_TS 6.3.2 | Timestamp | 5 | R | Single | Yes |
*Time | | s | The timestamp when the location measurement was performed. | Speed |
*6 | R | Single | No | Float | | m/s | Speed is the time rate of change in position of a LwM2M Client
*without regard | | | | | | | | | for direction: the scalar component of
*velocity. |
*/
#include "liblwm2m.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#ifdef LWM2M_CLIENT_MODE
// ---- private "object location" specific defines ----
// Resource Id's:
#define RES_M_LATITUDE 0
#define RES_M_LONGITUDE 1
#define RES_O_ALTITUDE 2
#define RES_O_RADIUS 3
#define RES_O_VELOCITY 4
#define RES_M_TIMESTAMP 5
#define RES_O_SPEED 6
//----- 3GPP TS 23.032 V11.0.0(2012-09) ---------
#define HORIZONTAL_VELOCITY 0 // for Octet-1 upper half(..<<4)
#define HORIZONTAL_VELOCITY_VERTICAL 1 // set vertical direction bit!
#define HORIZONTAL_VELOCITY_WITH_UNCERTAINTY 2
#define HORIZONTAL_VELOCITY_VERTICAL_WITH_UNCERTAINTY 3
#define VELOCITY_OCTETS 7 // for HORIZONTAL_VELOCITY_VERTICAL_WITH_UNCERTAINTY
typedef struct {
float latitude;
float longitude;
float altitude;
float radius;
uint8_t velocity[VELOCITY_OCTETS]; // 3GPP notation 1st step: HORIZONTAL_VELOCITY_WITH_UNCERTAINTY
unsigned long timestamp;
float speed;
} location_data_t;
/**
implementation for all read-able resources
*/
static uint8_t prv_res2tlv(lwm2m_data_t *dataP, location_data_t *locDataP) {
//-------------------------------------------------------------------- JH --
uint8_t ret = COAP_205_CONTENT;
switch (dataP->id) // location resourceId
{
case RES_M_LATITUDE:
lwm2m_data_encode_float(locDataP->latitude, dataP);
break;
case RES_M_LONGITUDE:
lwm2m_data_encode_float(locDataP->longitude, dataP);
break;
case RES_O_ALTITUDE:
lwm2m_data_encode_float(locDataP->altitude, dataP);
break;
case RES_O_RADIUS:
lwm2m_data_encode_float(locDataP->radius, dataP);
break;
case RES_O_VELOCITY: {
size_t length;
switch (locDataP->velocity[0] >> 4) {
case HORIZONTAL_VELOCITY: {
length = 4;
break;
}
case HORIZONTAL_VELOCITY_VERTICAL: {
length = 5;
break;
}
case HORIZONTAL_VELOCITY_WITH_UNCERTAINTY: {
length = 5;
break;
}
case HORIZONTAL_VELOCITY_VERTICAL_WITH_UNCERTAINTY: {
length = 7;
break;
}
default: {
length = 0;
break;
}
}
lwm2m_data_encode_opaque(locDataP->velocity, length, dataP);
break;
}
case RES_M_TIMESTAMP:
lwm2m_data_encode_int(locDataP->timestamp, dataP);
break;
case RES_O_SPEED:
lwm2m_data_encode_float(locDataP->speed, dataP);
break;
default:
ret = COAP_404_NOT_FOUND;
break;
}
return ret;
}
/**
* Implementation (callback-) function of reading object resources. For whole
* object, single resources or a sequence of resources
* see 3GPP TS 23.032 V11.0.0(2012-09) page 23,24.
* implemented for: HORIZONTAL_VELOCITY_WITH_UNCERTAINT
* @param contextP in, unused pointer to LWM2M context
* @param objInstId in, instances ID of the location object to read
* @param numDataP in/out, pointer to the number of resource to read. 0 is the
* exception for all readable resource of object instance
* @param tlvArrayP in/out, TLV data sequence with initialized resource ID to read
* @param objectP in, private location data structure
*/
static uint8_t prv_location_read(lwm2m_context_t *contextP, uint16_t objInstId, int *numDataP, lwm2m_data_t **tlvArrayP,
lwm2m_object_t *objectP) {
//-------------------------------------------------------------------- JH --
int i;
uint8_t result = COAP_500_INTERNAL_SERVER_ERROR;
location_data_t *locDataP = (location_data_t *)(objectP->userData);
/* unused parameter */
(void)contextP;
// defined as single instance object!
if (objInstId != 0)
return COAP_404_NOT_FOUND;
if (*numDataP == 0) // full object, readable resources!
{
uint16_t readResIds[] = {RES_M_LATITUDE, RES_M_LONGITUDE, RES_O_ALTITUDE, RES_O_RADIUS,
RES_O_VELOCITY, RES_M_TIMESTAMP, RES_O_SPEED}; // readable resources!
*numDataP = sizeof(readResIds) / sizeof(uint16_t);
*tlvArrayP = lwm2m_data_new(*numDataP);
if (*tlvArrayP == NULL)
return COAP_500_INTERNAL_SERVER_ERROR;
// init readable resource id's
for (i = 0; i < *numDataP; i++) {
(*tlvArrayP)[i].id = readResIds[i];
}
}
for (i = 0; i < *numDataP; i++) {
if ((*tlvArrayP)[i].type == LWM2M_TYPE_MULTIPLE_RESOURCE) {
result = COAP_404_NOT_FOUND;
} else {
result = prv_res2tlv((*tlvArrayP) + i, locDataP);
}
if (result != COAP_205_CONTENT)
break;
}
return result;
}
void display_location_object(lwm2m_object_t *object) {
location_data_t *data = (location_data_t *)object->userData;
fprintf(stdout, " /%u: Location object:\r\n", object->objID);
if (NULL != data) {
fprintf(stdout,
" latitude: %.6f, longitude: %.6f, altitude: %.6f, radius: %.6f, timestamp: %lu, speed: %.6f\r\n",
data->latitude, data->longitude, data->altitude, data->radius, data->timestamp, data->speed);
}
}
/**
* Convenience function to set the velocity attributes.
* see 3GPP TS 23.032 V11.0.0(2012-09) page 23,24.
* implemented for: HORIZONTAL_VELOCITY_WITH_UNCERTAINTY
* @param locationObj location object reference (to be casted!)
* @param bearing [Deg] 0 - 359 resolution: 1 degree
* @param horizontalSpeed [km/h] 1 - s^16-1 resolution: 1 km/h steps
* @param speedUncertainty [km/h] 1-254 resolution: 1 km/h (255=undefined!)
*/
void location_setVelocity(lwm2m_object_t *locationObj, uint16_t bearing, uint16_t horizontalSpeed,
uint8_t speedUncertainty) {
//-------------------------------------------------------------------- JH --
location_data_t *pData = locationObj->userData;
pData->velocity[0] = HORIZONTAL_VELOCITY_WITH_UNCERTAINTY << 4;
pData->velocity[0] |= (bearing & 0x100) >> 8;
pData->velocity[1] = (bearing & 0x0FF);
pData->velocity[2] = horizontalSpeed >> 8;
pData->velocity[3] = horizontalSpeed & 0xff;
pData->velocity[4] = speedUncertainty;
}
/**
* A convenience function to set the location coordinates with its timestamp.
* @see testMe()
* @param locationObj location object reference (to be casted!)
* @param latitude the second argument.
* @param longitude the second argument.
* @param altitude the second argument.
* @param timestamp the related timestamp. Seconds since 1970.
*/
void location_setLocationAtTime(lwm2m_object_t *locationObj, float latitude, float longitude, float altitude,
uint64_t timestamp) {
//-------------------------------------------------------------------- JH --
location_data_t *pData = locationObj->userData;
pData->latitude = latitude;
pData->longitude = longitude;
pData->altitude = altitude;
pData->timestamp = timestamp;
}
/**
* This function creates the LWM2M Location.
* @return gives back allocated LWM2M data object structure pointer. On error,
* NULL value is returned.
*/
lwm2m_object_t *get_object_location(void) {
//-------------------------------------------------------------------- JH --
lwm2m_object_t *locationObj;
locationObj = (lwm2m_object_t *)lwm2m_malloc(sizeof(lwm2m_object_t));
if (NULL != locationObj) {
memset(locationObj, 0, sizeof(lwm2m_object_t));
// It assigns its unique ID
// The 6 is the standard ID for the optional object "Location".
locationObj->objID = LWM2M_LOCATION_OBJECT_ID;
// and its unique instance
locationObj->instanceList = (lwm2m_list_t *)lwm2m_malloc(sizeof(lwm2m_list_t));
if (NULL != locationObj->instanceList) {
memset(locationObj->instanceList, 0, sizeof(lwm2m_list_t));
} else {
lwm2m_free(locationObj);
return NULL;
}
// And the private function that will access the object.
// Those function will be called when a read query is made by the server.
// In fact the library don't need to know the resources of the object, only the server does.
//
locationObj->readFunc = prv_location_read;
locationObj->userData = lwm2m_malloc(sizeof(location_data_t));
// initialize private data structure containing the needed variables
if (NULL != locationObj->userData) {
location_data_t *data = (location_data_t *)locationObj->userData;
data->latitude = 27.986065; // Mount Everest :)
data->longitude = 86.922623;
data->altitude = 8495.0000;
data->radius = 0.0;
location_setVelocity(locationObj, 0, 0, 255); // 255: speedUncertainty not supported!
data->timestamp = time(NULL);
data->speed = 0.0;
} else {
lwm2m_free(locationObj);
locationObj = NULL;
}
}
return locationObj;
}
void free_object_location(lwm2m_object_t *object) {
lwm2m_list_free(object->instanceList);
lwm2m_free(object->userData);
lwm2m_free(object);
}
#endif // LWM2M_CLIENT_MODE

View File

@ -45,38 +45,34 @@
#include "liblwm2m.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
typedef struct _security_instance_
{
struct _security_instance_ * next; // matches lwm2m_list_t::next
uint16_t instanceId; // matches lwm2m_list_t::id
char * uri;
bool isBootstrap;
uint8_t securityMode;
char * publicIdentity;
uint16_t publicIdLen;
char * serverPublicKey;
uint16_t serverPublicKeyLen;
char * secretKey;
uint16_t secretKeyLen;
uint8_t smsSecurityMode;
char * smsParams; // SMS binding key parameters
uint16_t smsParamsLen;
char * smsSecret; // SMS binding secret key
uint16_t smsSecretLen;
uint16_t shortID;
uint32_t clientHoldOffTime;
uint32_t bootstrapServerAccountTimeout;
typedef struct _security_instance_ {
struct _security_instance_ *next; // matches lwm2m_list_t::next
uint16_t instanceId; // matches lwm2m_list_t::id
char *uri;
bool isBootstrap;
uint8_t securityMode;
char *publicIdentity;
uint16_t publicIdLen;
char *serverPublicKey;
uint16_t serverPublicKeyLen;
char *secretKey;
uint16_t secretKeyLen;
uint8_t smsSecurityMode;
char *smsParams; // SMS binding key parameters
uint16_t smsParamsLen;
char *smsSecret; // SMS binding secret key
uint16_t smsSecretLen;
uint16_t shortID;
uint32_t clientHoldOffTime;
uint32_t bootstrapServerAccountTimeout;
} security_instance_t;
static uint8_t prv_get_value(lwm2m_data_t * dataP,
security_instance_t * targetP)
{
switch (dataP->id)
{
static uint8_t prv_get_value(lwm2m_data_t *dataP, security_instance_t *targetP) {
switch (dataP->id) {
case LWM2M_SECURITY_URI_ID:
lwm2m_data_encode_string(targetP->uri, dataP);
return COAP_205_CONTENT;
@ -90,15 +86,15 @@ static uint8_t prv_get_value(lwm2m_data_t * dataP,
return COAP_205_CONTENT;
case LWM2M_SECURITY_PUBLIC_KEY_ID:
lwm2m_data_encode_opaque((uint8_t*)targetP->publicIdentity, targetP->publicIdLen, dataP);
lwm2m_data_encode_opaque((uint8_t *)targetP->publicIdentity, targetP->publicIdLen, dataP);
return COAP_205_CONTENT;
case LWM2M_SECURITY_SERVER_PUBLIC_KEY_ID:
lwm2m_data_encode_opaque((uint8_t*)targetP->serverPublicKey, targetP->serverPublicKeyLen, dataP);
lwm2m_data_encode_opaque((uint8_t *)targetP->serverPublicKey, targetP->serverPublicKeyLen, dataP);
return COAP_205_CONTENT;
case LWM2M_SECURITY_SECRET_KEY_ID:
lwm2m_data_encode_opaque((uint8_t*)targetP->secretKey, targetP->secretKeyLen, dataP);
lwm2m_data_encode_opaque((uint8_t *)targetP->secretKey, targetP->secretKeyLen, dataP);
return COAP_205_CONTENT;
case LWM2M_SECURITY_SMS_SECURITY_ID:
@ -106,11 +102,11 @@ static uint8_t prv_get_value(lwm2m_data_t * dataP,
return COAP_205_CONTENT;
case LWM2M_SECURITY_SMS_KEY_PARAM_ID:
lwm2m_data_encode_opaque((uint8_t*)targetP->smsParams, targetP->smsParamsLen, dataP);
lwm2m_data_encode_opaque((uint8_t *)targetP->smsParams, targetP->smsParamsLen, dataP);
return COAP_205_CONTENT;
case LWM2M_SECURITY_SMS_SECRET_KEY_ID:
lwm2m_data_encode_opaque((uint8_t*)targetP->smsSecret, targetP->smsSecretLen, dataP);
lwm2m_data_encode_opaque((uint8_t *)targetP->smsSecret, targetP->smsSecretLen, dataP);
return COAP_205_CONTENT;
case LWM2M_SECURITY_SMS_SERVER_NUMBER_ID:
@ -134,13 +130,9 @@ static uint8_t prv_get_value(lwm2m_data_t * dataP,
}
}
static uint8_t prv_security_read(lwm2m_context_t *contextP,
uint16_t instanceId,
int * numDataP,
lwm2m_data_t ** dataArrayP,
lwm2m_object_t * objectP)
{
security_instance_t * targetP;
static uint8_t prv_security_read(lwm2m_context_t *contextP, uint16_t instanceId, int *numDataP,
lwm2m_data_t **dataArrayP, lwm2m_object_t *objectP) {
security_instance_t *targetP;
uint8_t result;
int i;
@ -148,11 +140,11 @@ static uint8_t prv_security_read(lwm2m_context_t *contextP,
(void)contextP;
targetP = (security_instance_t *)lwm2m_list_find(objectP->instanceList, instanceId);
if (NULL == targetP) return COAP_404_NOT_FOUND;
if (NULL == targetP)
return COAP_404_NOT_FOUND;
// is the server asking for the full instance ?
if (*numDataP == 0)
{
if (*numDataP == 0) {
uint16_t resList[] = {LWM2M_SECURITY_URI_ID,
LWM2M_SECURITY_BOOTSTRAP_ID,
LWM2M_SECURITY_SECURITY_ID,
@ -166,26 +158,22 @@ static uint8_t prv_security_read(lwm2m_context_t *contextP,
LWM2M_SECURITY_SHORT_SERVER_ID,
LWM2M_SECURITY_HOLD_OFF_ID,
LWM2M_SECURITY_BOOTSTRAP_TIMEOUT_ID};
int nbRes = sizeof(resList)/sizeof(uint16_t);
int nbRes = sizeof(resList) / sizeof(uint16_t);
*dataArrayP = lwm2m_data_new(nbRes);
if (*dataArrayP == NULL) return COAP_500_INTERNAL_SERVER_ERROR;
if (*dataArrayP == NULL)
return COAP_500_INTERNAL_SERVER_ERROR;
*numDataP = nbRes;
for (i = 0 ; i < nbRes ; i++)
{
for (i = 0; i < nbRes; i++) {
(*dataArrayP)[i].id = resList[i];
}
}
i = 0;
do
{
if ((*dataArrayP)[i].type == LWM2M_TYPE_MULTIPLE_RESOURCE)
{
do {
if ((*dataArrayP)[i].type == LWM2M_TYPE_MULTIPLE_RESOURCE) {
result = COAP_404_NOT_FOUND;
}
else
{
} else {
result = prv_get_value((*dataArrayP) + i, targetP);
}
i++;
@ -196,14 +184,9 @@ static uint8_t prv_security_read(lwm2m_context_t *contextP,
#ifdef LWM2M_BOOTSTRAP
static uint8_t prv_security_write(lwm2m_context_t *contextP,
uint16_t instanceId,
int numData,
lwm2m_data_t * dataArray,
lwm2m_object_t * objectP,
lwm2m_write_type_t writeType)
{
security_instance_t * targetP;
static uint8_t prv_security_write(lwm2m_context_t *contextP, uint16_t instanceId, int numData, lwm2m_data_t *dataArray,
lwm2m_object_t *objectP, lwm2m_write_type_t writeType) {
security_instance_t *targetP;
int i;
uint8_t result = COAP_204_CHANGED;
@ -214,114 +197,96 @@ static uint8_t prv_security_write(lwm2m_context_t *contextP,
(void)writeType;
targetP = (security_instance_t *)lwm2m_list_find(objectP->instanceList, instanceId);
if (NULL == targetP)
{
if (NULL == targetP) {
return COAP_404_NOT_FOUND;
}
i = 0;
do {
/* No multiple instance resources */
if (dataArray[i].type == LWM2M_TYPE_MULTIPLE_RESOURCE)
{
if (dataArray[i].type == LWM2M_TYPE_MULTIPLE_RESOURCE) {
result = COAP_404_NOT_FOUND;
continue;
}
switch (dataArray[i].id)
{
switch (dataArray[i].id) {
case LWM2M_SECURITY_URI_ID:
if (targetP->uri != NULL) lwm2m_free(targetP->uri);
if (targetP->uri != NULL)
lwm2m_free(targetP->uri);
targetP->uri = (char *)lwm2m_malloc(dataArray[i].value.asBuffer.length + 1);
memset(targetP->uri, 0, dataArray[i].value.asBuffer.length + 1);
if (targetP->uri != NULL)
{
strncpy(targetP->uri, (char*)dataArray[i].value.asBuffer.buffer, dataArray[i].value.asBuffer.length);
if (targetP->uri != NULL) {
strncpy(targetP->uri, (char *)dataArray[i].value.asBuffer.buffer, // NOSONAR
dataArray[i].value.asBuffer.length);
result = COAP_204_CHANGED;
}
else
{
} else {
result = COAP_500_INTERNAL_SERVER_ERROR;
}
break;
case LWM2M_SECURITY_BOOTSTRAP_ID:
if (1 == lwm2m_data_decode_bool(dataArray + i, &(targetP->isBootstrap)))
{
if (1 == lwm2m_data_decode_bool(dataArray + i, &(targetP->isBootstrap))) {
result = COAP_204_CHANGED;
}
else
{
} else {
result = COAP_400_BAD_REQUEST;
}
break;
case LWM2M_SECURITY_SECURITY_ID:
{
case LWM2M_SECURITY_SECURITY_ID: {
int64_t value;
if (1 == lwm2m_data_decode_int(dataArray + i, &value))
{
if (value >= 0 && value <= 3)
{
if (1 == lwm2m_data_decode_int(dataArray + i, &value)) {
if (value >= 0 && value <= 3) {
targetP->securityMode = value;
result = COAP_204_CHANGED;
}
else
{
} else {
result = COAP_406_NOT_ACCEPTABLE;
}
}
else
{
} else {
result = COAP_400_BAD_REQUEST;
}
}
break;
} break;
case LWM2M_SECURITY_PUBLIC_KEY_ID:
if (targetP->publicIdentity != NULL) lwm2m_free(targetP->publicIdentity);
targetP->publicIdentity = (char *)lwm2m_malloc(dataArray[i].value.asBuffer.length +1);
memset(targetP->publicIdentity, 0, dataArray[i].value.asBuffer.length + 1);
if (targetP->publicIdentity != NULL)
{
memcpy(targetP->publicIdentity, (char*)dataArray[i].value.asBuffer.buffer, dataArray[i].value.asBuffer.length);
lwm2m_free(targetP->publicIdentity);
targetP->publicIdentity = (char *)lwm2m_malloc(dataArray[i].value.asBuffer.length + 1);
memset(targetP->publicIdentity, 0, dataArray[i].value.asBuffer.length + 1);
if (targetP->publicIdentity != NULL) {
memcpy(targetP->publicIdentity, (char *)dataArray[i].value.asBuffer.buffer,
dataArray[i].value.asBuffer.length);
targetP->publicIdLen = dataArray[i].value.asBuffer.length;
result = COAP_204_CHANGED;
}
else
{
} else {
result = COAP_500_INTERNAL_SERVER_ERROR;
}
break;
case LWM2M_SECURITY_SERVER_PUBLIC_KEY_ID:
if (targetP->serverPublicKey != NULL) lwm2m_free(targetP->serverPublicKey);
targetP->serverPublicKey = (char *)lwm2m_malloc(dataArray[i].value.asBuffer.length +1);
memset(targetP->serverPublicKey, 0, dataArray[i].value.asBuffer.length + 1);
if (targetP->serverPublicKey != NULL)
{
memcpy(targetP->serverPublicKey, (char*)dataArray[i].value.asBuffer.buffer, dataArray[i].value.asBuffer.length);
lwm2m_free(targetP->serverPublicKey);
targetP->serverPublicKey = (char *)lwm2m_malloc(dataArray[i].value.asBuffer.length + 1);
memset(targetP->serverPublicKey, 0, dataArray[i].value.asBuffer.length + 1);
if (targetP->serverPublicKey != NULL) {
memcpy(targetP->serverPublicKey, (char *)dataArray[i].value.asBuffer.buffer,
dataArray[i].value.asBuffer.length);
targetP->serverPublicKeyLen = dataArray[i].value.asBuffer.length;
result = COAP_204_CHANGED;
}
else
{
} else {
result = COAP_500_INTERNAL_SERVER_ERROR;
}
break;
case LWM2M_SECURITY_SECRET_KEY_ID:
if (targetP->secretKey != NULL) lwm2m_free(targetP->secretKey);
targetP->secretKey = (char *)lwm2m_malloc(dataArray[i].value.asBuffer.length +1);
memset(targetP->secretKey, 0, dataArray[i].value.asBuffer.length + 1);
if (targetP->secretKey != NULL)
{
memcpy(targetP->secretKey, (char*)dataArray[i].value.asBuffer.buffer, dataArray[i].value.asBuffer.length);
lwm2m_free(targetP->secretKey);
targetP->secretKey = (char *)lwm2m_malloc(dataArray[i].value.asBuffer.length + 1);
memset(targetP->secretKey, 0, dataArray[i].value.asBuffer.length + 1);
if (targetP->secretKey != NULL) {
memcpy(targetP->secretKey, (char *)dataArray[i].value.asBuffer.buffer,
dataArray[i].value.asBuffer.length);
targetP->secretKeyLen = dataArray[i].value.asBuffer.length;
result = COAP_204_CHANGED;
}
else
{
} else {
result = COAP_500_INTERNAL_SERVER_ERROR;
}
break;
@ -346,70 +311,48 @@ static uint8_t prv_security_write(lwm2m_context_t *contextP,
result = COAP_204_CHANGED;
break;
case LWM2M_SECURITY_SHORT_SERVER_ID:
{
case LWM2M_SECURITY_SHORT_SERVER_ID: {
int64_t value;
if (1 == lwm2m_data_decode_int(dataArray + i, &value))
{
if (value >= 0 && value <= 0xFFFF)
{
if (1 == lwm2m_data_decode_int(dataArray + i, &value)) {
if (value >= 0 && value <= 0xFFFF) {
targetP->shortID = value;
result = COAP_204_CHANGED;
}
else
{
} else {
result = COAP_406_NOT_ACCEPTABLE;
}
}
else
{
} else {
result = COAP_400_BAD_REQUEST;
}
}
break;
} break;
case LWM2M_SECURITY_HOLD_OFF_ID:
{
case LWM2M_SECURITY_HOLD_OFF_ID: {
int64_t value;
if (1 == lwm2m_data_decode_int(dataArray + i, &value))
{
if (value >= 0 && value <= UINT32_MAX)
{
if (1 == lwm2m_data_decode_int(dataArray + i, &value)) {
if (value >= 0 && value <= UINT32_MAX) {
targetP->clientHoldOffTime = value;
result = COAP_204_CHANGED;
}
else
{
} else {
result = COAP_406_NOT_ACCEPTABLE;
}
}
else
{
} else {
result = COAP_400_BAD_REQUEST;
}
break;
}
case LWM2M_SECURITY_BOOTSTRAP_TIMEOUT_ID:
{
case LWM2M_SECURITY_BOOTSTRAP_TIMEOUT_ID: {
int64_t value;
if (1 == lwm2m_data_decode_int(dataArray + i, &value))
{
if (value >= 0 && value <= UINT32_MAX)
{
if (1 == lwm2m_data_decode_int(dataArray + i, &value)) {
if (value >= 0 && value <= UINT32_MAX) {
targetP->bootstrapServerAccountTimeout = value;
result = COAP_204_CHANGED;
}
else
{
} else {
result = COAP_406_NOT_ACCEPTABLE;
}
}
else
{
} else {
result = COAP_400_BAD_REQUEST;
}
break;
@ -424,19 +367,16 @@ static uint8_t prv_security_write(lwm2m_context_t *contextP,
return result;
}
static uint8_t prv_security_delete(lwm2m_context_t *contextP,
uint16_t id,
lwm2m_object_t * objectP)
{
security_instance_t * targetP;
static uint8_t prv_security_delete(lwm2m_context_t *contextP, uint16_t id, lwm2m_object_t *objectP) {
security_instance_t *targetP;
/* unused parameter */
(void)contextP;
objectP->instanceList = lwm2m_list_remove(objectP->instanceList, id, (lwm2m_list_t **)&targetP);
if (NULL == targetP) return COAP_404_NOT_FOUND;
if (NULL != targetP->uri)
{
if (NULL == targetP)
return COAP_404_NOT_FOUND;
if (NULL != targetP->uri) {
lwm2m_free(targetP->uri);
}
@ -445,17 +385,14 @@ static uint8_t prv_security_delete(lwm2m_context_t *contextP,
return COAP_202_DELETED;
}
static uint8_t prv_security_create(lwm2m_context_t *contextP,
uint16_t instanceId,
int numData,
lwm2m_data_t * dataArray,
lwm2m_object_t * objectP)
{
security_instance_t * targetP;
static uint8_t prv_security_create(lwm2m_context_t *contextP, uint16_t instanceId, int numData, lwm2m_data_t *dataArray,
lwm2m_object_t *objectP) {
security_instance_t *targetP;
uint8_t result;
targetP = (security_instance_t *)lwm2m_malloc(sizeof(security_instance_t));
if (NULL == targetP) return COAP_500_INTERNAL_SERVER_ERROR;
if (NULL == targetP)
return COAP_500_INTERNAL_SERVER_ERROR;
memset(targetP, 0, sizeof(security_instance_t));
targetP->instanceId = instanceId;
@ -463,12 +400,9 @@ static uint8_t prv_security_create(lwm2m_context_t *contextP,
result = prv_security_write(contextP, instanceId, numData, dataArray, objectP, LWM2M_WRITE_REPLACE_RESOURCES);
if (result != COAP_204_CHANGED)
{
if (result != COAP_204_CHANGED) {
(void)prv_security_delete(contextP, instanceId, objectP);
}
else
{
} else {
result = COAP_201_CREATED;
}
@ -476,67 +410,53 @@ static uint8_t prv_security_create(lwm2m_context_t *contextP,
}
#endif
void copy_security_object(lwm2m_object_t * objectDest, lwm2m_object_t * objectSrc)
{
void copy_security_object(lwm2m_object_t *objectDest, lwm2m_object_t *objectSrc) {
memcpy(objectDest, objectSrc, sizeof(lwm2m_object_t));
objectDest->instanceList = NULL;
objectDest->userData = NULL;
security_instance_t * instanceSrc = (security_instance_t *)objectSrc->instanceList;
security_instance_t * previousInstanceDest = NULL;
while (instanceSrc != NULL)
{
security_instance_t * instanceDest = (security_instance_t *)lwm2m_malloc(sizeof(security_instance_t));
if (NULL == instanceDest)
{
security_instance_t *instanceSrc = (security_instance_t *)objectSrc->instanceList;
security_instance_t *previousInstanceDest = NULL;
while (instanceSrc != NULL) {
security_instance_t *instanceDest = (security_instance_t *)lwm2m_malloc(sizeof(security_instance_t));
if (NULL == instanceDest) {
return;
}
memcpy(instanceDest, instanceSrc, sizeof(security_instance_t));
instanceDest->uri = (char*)lwm2m_malloc(strlen(instanceSrc->uri) + 1);
strcpy(instanceDest->uri, instanceSrc->uri);
if (instanceSrc->securityMode == LWM2M_SECURITY_MODE_PRE_SHARED_KEY)
{
instanceDest->uri = (char *)lwm2m_malloc(strlen(instanceSrc->uri) + 1); // NOSONAR
strcpy(instanceDest->uri, instanceSrc->uri); // NOSONAR
if (instanceSrc->securityMode == LWM2M_SECURITY_MODE_PRE_SHARED_KEY) {
instanceDest->publicIdentity = lwm2m_strdup(instanceSrc->publicIdentity);
instanceDest->secretKey = lwm2m_strdup(instanceSrc->secretKey);
}
instanceSrc = (security_instance_t *)instanceSrc->next;
if (previousInstanceDest == NULL)
{
if (previousInstanceDest == NULL) {
objectDest->instanceList = (lwm2m_list_t *)instanceDest;
}
else
{
} else {
previousInstanceDest->next = instanceDest;
}
previousInstanceDest = instanceDest;
}
}
void display_security_object(lwm2m_object_t * object)
{
void display_security_object(lwm2m_object_t *object) {
fprintf(stdout, " /%u: Security object, instances:\r\n", object->objID);
security_instance_t * instance = (security_instance_t *)object->instanceList;
while (instance != NULL)
{
security_instance_t *instance = (security_instance_t *)object->instanceList;
while (instance != NULL) {
fprintf(stdout, " /%u/%u: instanceId: %u, uri: %s, isBootstrap: %s, shortId: %u, clientHoldOffTime: %u\r\n",
object->objID, instance->instanceId,
instance->instanceId, instance->uri, instance->isBootstrap ? "true" : "false",
instance->shortID, instance->clientHoldOffTime);
object->objID, instance->instanceId, instance->instanceId, instance->uri,
instance->isBootstrap ? "true" : "false", instance->shortID, instance->clientHoldOffTime);
instance = (security_instance_t *)instance->next;
}
}
void clean_security_object(lwm2m_object_t * objectP)
{
while (objectP->instanceList != NULL)
{
security_instance_t * securityInstance = (security_instance_t *)objectP->instanceList;
void clean_security_object(lwm2m_object_t *objectP) {
while (objectP->instanceList != NULL) {
security_instance_t *securityInstance = (security_instance_t *)objectP->instanceList;
objectP->instanceList = objectP->instanceList->next;
if (NULL != securityInstance->uri)
{
if (NULL != securityInstance->uri) {
lwm2m_free(securityInstance->uri);
}
if (securityInstance->securityMode == LWM2M_SECURITY_MODE_PRE_SHARED_KEY)
{
if (securityInstance->securityMode == LWM2M_SECURITY_MODE_PRE_SHARED_KEY) {
lwm2m_free(securityInstance->publicIdentity);
lwm2m_free(securityInstance->secretKey);
}
@ -544,20 +464,14 @@ void clean_security_object(lwm2m_object_t * objectP)
}
}
lwm2m_object_t * get_security_object(int serverId,
const char* serverUri,
char * bsPskId,
char * psk,
uint16_t pskLen,
bool isBootstrap)
{
lwm2m_object_t * securityObj;
lwm2m_object_t *get_security_object(int serverId, const char *serverUri, char *bsPskId, char *psk, uint16_t pskLen,
bool isBootstrap) {
lwm2m_object_t *securityObj;
securityObj = (lwm2m_object_t *)lwm2m_malloc(sizeof(lwm2m_object_t));
if (NULL != securityObj)
{
security_instance_t * targetP;
if (NULL != securityObj) {
security_instance_t *targetP;
memset(securityObj, 0, sizeof(lwm2m_object_t));
@ -565,35 +479,31 @@ lwm2m_object_t * get_security_object(int serverId,
// Manually create an hardcoded instance
targetP = (security_instance_t *)lwm2m_malloc(sizeof(security_instance_t));
if (NULL == targetP)
{
if (NULL == targetP) {
lwm2m_free(securityObj);
return NULL;
}
memset(targetP, 0, sizeof(security_instance_t));
targetP->instanceId = 0;
targetP->uri = (char*)lwm2m_malloc(strlen(serverUri)+1);
strcpy(targetP->uri, serverUri);
targetP->uri = (char *)lwm2m_malloc(strlen(serverUri) + 1); // NOSONAR
strcpy(targetP->uri, serverUri); // NOSONAR
targetP->securityMode = LWM2M_SECURITY_MODE_NONE;
targetP->publicIdentity = NULL;
targetP->publicIdLen = 0;
targetP->secretKey = NULL;
targetP->secretKeyLen = 0;
if (bsPskId != NULL || psk != NULL)
{
if (bsPskId != NULL || psk != NULL) {
targetP->securityMode = LWM2M_SECURITY_MODE_PRE_SHARED_KEY;
if (bsPskId)
{
if (bsPskId) {
targetP->publicIdentity = strdup(bsPskId);
targetP->publicIdLen = strlen(bsPskId);
targetP->publicIdLen = strlen(bsPskId); // NOSONAR
targetP->publicIdLen = strlen(bsPskId); // NOSONAR
}
if (pskLen > 0)
{
targetP->secretKey = (char*)lwm2m_malloc(pskLen);
if (targetP->secretKey == NULL)
{
if (pskLen > 0) {
targetP->secretKey = (char *)lwm2m_malloc(pskLen);
if (targetP->secretKey == NULL) {
clean_security_object(securityObj);
return NULL;
}
@ -618,13 +528,10 @@ lwm2m_object_t * get_security_object(int serverId,
return securityObj;
}
char * get_server_uri(lwm2m_object_t * objectP,
uint16_t secObjInstID)
{
security_instance_t * targetP = (security_instance_t *)LWM2M_LIST_FIND(objectP->instanceList, secObjInstID);
char *get_server_uri(lwm2m_object_t *objectP, uint16_t secObjInstID) {
security_instance_t *targetP = (security_instance_t *)LWM2M_LIST_FIND(objectP->instanceList, secObjInstID);
if (NULL != targetP)
{
if (NULL != targetP) {
return lwm2m_strdup(targetP->uri);
}

View File

@ -52,44 +52,35 @@
#include <stdlib.h>
#include <string.h>
typedef struct _server_instance_
{
struct _server_instance_ * next; // matches lwm2m_list_t::next
uint16_t instanceId; // matches lwm2m_list_t::id
uint16_t shortServerId;
uint32_t lifetime;
uint32_t defaultMinPeriod;
uint32_t defaultMaxPeriod;
uint32_t disableTimeout;
bool storing;
char binding[4];
typedef struct _server_instance_ {
struct _server_instance_ *next; // matches lwm2m_list_t::next
uint16_t instanceId; // matches lwm2m_list_t::id
uint16_t shortServerId;
uint32_t lifetime;
uint32_t defaultMinPeriod;
uint32_t defaultMaxPeriod;
uint32_t disableTimeout;
bool storing;
char binding[4];
#ifndef LWM2M_VERSION_1_0
int registrationPriorityOrder; // <0 when it doesn't exist
int initialRegistrationDelayTimer; // <0 when it doesn't exist
int8_t registrationFailureBlock; // <0 when it doesn't exist, 0 for false, > 0 for true
int8_t bootstrapOnRegistrationFailure; // <0 when it doesn't exist, 0 for false, > 0 for true
int communicationRetryCount; // <0 when it doesn't exist
int communicationRetryTimer; // <0 when it doesn't exist
int communicationSequenceDelayTimer; // <0 when it doesn't exist
int communicationSequenceRetryCount; // <0 when it doesn't exist
int registrationPriorityOrder; // <0 when it doesn't exist
int initialRegistrationDelayTimer; // <0 when it doesn't exist
int8_t registrationFailureBlock; // <0 when it doesn't exist, 0 for false, > 0 for true
int8_t bootstrapOnRegistrationFailure; // <0 when it doesn't exist, 0 for false, > 0 for true
int communicationRetryCount; // <0 when it doesn't exist
int communicationRetryTimer; // <0 when it doesn't exist
int communicationSequenceDelayTimer; // <0 when it doesn't exist
int communicationSequenceRetryCount; // <0 when it doesn't exist
bool muteSend;
#endif
} server_instance_t;
static uint8_t prv_server_delete(lwm2m_context_t *contextP,
uint16_t id,
lwm2m_object_t * objectP);
static uint8_t prv_server_create(lwm2m_context_t *contextP,
uint16_t instanceId,
int numData,
lwm2m_data_t * dataArray,
lwm2m_object_t * objectP);
static uint8_t prv_server_delete(lwm2m_context_t *contextP, uint16_t id, lwm2m_object_t *objectP);
static uint8_t prv_server_create(lwm2m_context_t *contextP, uint16_t instanceId, int numData, lwm2m_data_t *dataArray,
lwm2m_object_t *objectP);
static uint8_t prv_get_value(lwm2m_data_t * dataP,
server_instance_t * targetP)
{
switch (dataP->id)
{
static uint8_t prv_get_value(lwm2m_data_t *dataP, server_instance_t *targetP) {
switch (dataP->id) {
case LWM2M_SERVER_SHORT_ID_ID:
lwm2m_data_encode_int(targetP->shortServerId, dataP);
return COAP_205_CONTENT;
@ -126,90 +117,66 @@ static uint8_t prv_get_value(lwm2m_data_t * dataP,
#ifndef LWM2M_VERSION_1_0
case LWM2M_SERVER_REG_ORDER_ID:
if (targetP->registrationPriorityOrder >= 0)
{
if (targetP->registrationPriorityOrder >= 0) {
lwm2m_data_encode_uint(targetP->registrationPriorityOrder, dataP);
return COAP_205_CONTENT;
}
else
{
} else {
return COAP_404_NOT_FOUND;
}
case LWM2M_SERVER_INITIAL_REG_DELAY_ID:
if (targetP->initialRegistrationDelayTimer >= 0)
{
if (targetP->initialRegistrationDelayTimer >= 0) {
lwm2m_data_encode_uint(targetP->initialRegistrationDelayTimer, dataP);
return COAP_205_CONTENT;
}
else
{
} else {
return COAP_404_NOT_FOUND;
}
case LWM2M_SERVER_REG_FAIL_BLOCK_ID:
if (targetP->registrationFailureBlock >= 0)
{
if (targetP->registrationFailureBlock >= 0) {
lwm2m_data_encode_bool(targetP->registrationFailureBlock > 0, dataP);
return COAP_205_CONTENT;
}
else
{
} else {
return COAP_404_NOT_FOUND;
}
case LWM2M_SERVER_REG_FAIL_BOOTSTRAP_ID:
if (targetP->bootstrapOnRegistrationFailure >= 0)
{
if (targetP->bootstrapOnRegistrationFailure >= 0) {
lwm2m_data_encode_bool(targetP->bootstrapOnRegistrationFailure > 0, dataP);
return COAP_205_CONTENT;
}
else
{
} else {
return COAP_404_NOT_FOUND;
}
case LWM2M_SERVER_COMM_RETRY_COUNT_ID:
if (targetP->communicationRetryCount >= 0)
{
if (targetP->communicationRetryCount >= 0) {
lwm2m_data_encode_uint(targetP->communicationRetryCount, dataP);
return COAP_205_CONTENT;
}
else
{
} else {
return COAP_404_NOT_FOUND;
}
case LWM2M_SERVER_COMM_RETRY_TIMER_ID:
if (targetP->communicationRetryTimer >= 0)
{
if (targetP->communicationRetryTimer >= 0) {
lwm2m_data_encode_uint(targetP->communicationRetryTimer, dataP);
return COAP_205_CONTENT;
}
else
{
} else {
return COAP_404_NOT_FOUND;
}
case LWM2M_SERVER_SEQ_DELAY_TIMER_ID:
if (targetP->communicationSequenceDelayTimer >= 0)
{
if (targetP->communicationSequenceDelayTimer >= 0) {
lwm2m_data_encode_uint(targetP->communicationSequenceDelayTimer, dataP);
return COAP_205_CONTENT;
}
else
{
} else {
return COAP_404_NOT_FOUND;
}
case LWM2M_SERVER_SEQ_RETRY_COUNT_ID:
if (targetP->communicationSequenceRetryCount >= 0)
{
if (targetP->communicationSequenceRetryCount >= 0) {
lwm2m_data_encode_uint(targetP->communicationSequenceRetryCount, dataP);
return COAP_205_CONTENT;
}
else
{
} else {
return COAP_404_NOT_FOUND;
}
@ -272,24 +239,20 @@ static uint8_t prv_get_all_values(const int *numDataP, lwm2m_data_t *const *data
} while (i < *numDataP && result == COAP_205_CONTENT);
return result;
}
static uint8_t prv_server_read(lwm2m_context_t *contextP,
uint16_t instanceId,
int * numDataP,
lwm2m_data_t ** dataArrayP,
lwm2m_object_t * objectP)
{
server_instance_t * targetP;
static uint8_t prv_server_read(lwm2m_context_t *contextP, uint16_t instanceId, int *numDataP, lwm2m_data_t **dataArrayP,
lwm2m_object_t *objectP) {
server_instance_t *targetP;
uint8_t result;
/* unused parameter */
(void)contextP;
targetP = (server_instance_t *)lwm2m_list_find(objectP->instanceList, instanceId);
if (NULL == targetP) return COAP_404_NOT_FOUND;
if (NULL == targetP)
return COAP_404_NOT_FOUND;
// is the server asking for the full instance ?
if (*numDataP == 0)
{
if (*numDataP == 0) {
uint16_t resList[] = {
LWM2M_SERVER_SHORT_ID_ID, LWM2M_SERVER_LIFETIME_ID,
LWM2M_SERVER_MIN_PERIOD_ID, LWM2M_SERVER_MAX_PERIOD_ID,
@ -310,7 +273,8 @@ static uint8_t prv_server_read(lwm2m_context_t *contextP,
#endif
*dataArrayP = lwm2m_data_new(nbRes);
if (*dataArrayP == NULL) return COAP_500_INTERNAL_SERVER_ERROR;
if (*dataArrayP == NULL)
return COAP_500_INTERNAL_SERVER_ERROR;
*numDataP = nbRes;
setup_resources(dataArrayP, resList, nbRes);
}
@ -320,13 +284,9 @@ static uint8_t prv_server_read(lwm2m_context_t *contextP,
return result;
}
static uint8_t prv_server_discover(lwm2m_context_t *contextP,
uint16_t instanceId,
int * numDataP,
lwm2m_data_t ** dataArrayP,
lwm2m_object_t * objectP)
{
server_instance_t * targetP;
static uint8_t prv_server_discover(lwm2m_context_t *contextP, uint16_t instanceId, int *numDataP,
lwm2m_data_t **dataArrayP, lwm2m_object_t *objectP) {
server_instance_t *targetP;
uint8_t result;
int i;
@ -336,11 +296,11 @@ static uint8_t prv_server_discover(lwm2m_context_t *contextP,
result = COAP_205_CONTENT;
targetP = (server_instance_t *)lwm2m_list_find(objectP->instanceList, instanceId);
if (NULL == targetP) return COAP_404_NOT_FOUND;
if (NULL == targetP)
return COAP_404_NOT_FOUND;
// is the server asking for the full object ?
if (*numDataP == 0)
{
if (*numDataP == 0) {
uint16_t resList[] = {
LWM2M_SERVER_SHORT_ID_ID, LWM2M_SERVER_LIFETIME_ID,
LWM2M_SERVER_MIN_PERIOD_ID, LWM2M_SERVER_MAX_PERIOD_ID,
@ -362,16 +322,13 @@ static uint8_t prv_server_discover(lwm2m_context_t *contextP,
#endif
*dataArrayP = lwm2m_data_new(nbRes);
if (*dataArrayP == NULL) return COAP_500_INTERNAL_SERVER_ERROR;
if (*dataArrayP == NULL)
return COAP_500_INTERNAL_SERVER_ERROR;
*numDataP = nbRes;
setup_resources(dataArrayP, resList, nbRes);
}
else
{
for (i = 0; i < *numDataP && result == COAP_205_CONTENT; i++)
{
switch ((*dataArrayP)[i].id)
{
} else {
for (i = 0; i < *numDataP && result == COAP_205_CONTENT; i++) {
switch ((*dataArrayP)[i].id) {
case LWM2M_SERVER_SHORT_ID_ID:
case LWM2M_SERVER_LIFETIME_ID:
case LWM2M_SERVER_MIN_PERIOD_ID:
@ -384,57 +341,49 @@ static uint8_t prv_server_discover(lwm2m_context_t *contextP,
break;
#ifndef LWM2M_VERSION_1_0
case LWM2M_SERVER_REG_ORDER_ID:
if(targetP->registrationPriorityOrder < 0)
{
if (targetP->registrationPriorityOrder < 0) {
result = COAP_404_NOT_FOUND;
}
break;
case LWM2M_SERVER_INITIAL_REG_DELAY_ID:
if(targetP->initialRegistrationDelayTimer < 0)
{
if (targetP->initialRegistrationDelayTimer < 0) {
result = COAP_404_NOT_FOUND;
}
break;
case LWM2M_SERVER_REG_FAIL_BLOCK_ID:
if(targetP->registrationFailureBlock < 0)
{
if (targetP->registrationFailureBlock < 0) {
result = COAP_404_NOT_FOUND;
}
break;
case LWM2M_SERVER_REG_FAIL_BOOTSTRAP_ID:
if(targetP->bootstrapOnRegistrationFailure < 0)
{
if (targetP->bootstrapOnRegistrationFailure < 0) {
result = COAP_404_NOT_FOUND;
}
break;
case LWM2M_SERVER_COMM_RETRY_COUNT_ID:
if(targetP->communicationRetryCount < 0)
{
if (targetP->communicationRetryCount < 0) {
result = COAP_404_NOT_FOUND;
}
break;
case LWM2M_SERVER_COMM_RETRY_TIMER_ID:
if(targetP->communicationRetryTimer < 0)
{
if (targetP->communicationRetryTimer < 0) {
result = COAP_404_NOT_FOUND;
}
break;
case LWM2M_SERVER_SEQ_DELAY_TIMER_ID:
if(targetP->communicationSequenceDelayTimer < 0)
{
if (targetP->communicationSequenceDelayTimer < 0) {
result = COAP_404_NOT_FOUND;
}
break;
case LWM2M_SERVER_SEQ_RETRY_COUNT_ID:
if(targetP->communicationSequenceRetryCount < 0)
{
if (targetP->communicationSequenceRetryCount < 0) {
result = COAP_404_NOT_FOUND;
}
break;
@ -453,54 +402,39 @@ static uint8_t prv_server_discover(lwm2m_context_t *contextP,
return result;
}
static uint8_t prv_set_int_value(lwm2m_data_t * dataArray, uint32_t * data) {
static uint8_t prv_set_int_value(lwm2m_data_t *dataArray, uint32_t *data) {
uint8_t result;
int64_t value;
if (1 == lwm2m_data_decode_int(dataArray, &value))
{
if (value >= 0 && value <= 0xFFFFFFFF)
{
if (1 == lwm2m_data_decode_int(dataArray, &value)) {
if (value >= 0 && value <= 0xFFFFFFFF) {
*data = value;
result = COAP_204_CHANGED;
}
else
{
} else {
result = COAP_406_NOT_ACCEPTABLE;
}
}
else
{
} else {
result = COAP_400_BAD_REQUEST;
}
return result;
}
static uint8_t prv_server_write(lwm2m_context_t *contextP,
uint16_t instanceId,
int numData,
lwm2m_data_t * dataArray,
lwm2m_object_t * objectP,
lwm2m_write_type_t writeType)
{
server_instance_t * targetP;
static uint8_t prv_server_write(lwm2m_context_t *contextP, uint16_t instanceId, int numData, lwm2m_data_t *dataArray,
lwm2m_object_t *objectP, lwm2m_write_type_t writeType) {
server_instance_t *targetP;
int i;
uint8_t result;
targetP = (server_instance_t *)lwm2m_list_find(objectP->instanceList, instanceId);
if (NULL == targetP)
{
if (NULL == targetP) {
return COAP_404_NOT_FOUND;
}
if (writeType == LWM2M_WRITE_REPLACE_INSTANCE)
{
if (writeType == LWM2M_WRITE_REPLACE_INSTANCE) {
result = prv_server_delete(contextP, instanceId, objectP);
if (result == COAP_202_DELETED)
{
if (result == COAP_202_DELETED) {
result = prv_server_create(contextP, instanceId, numData, dataArray, objectP);
if (result == COAP_201_CREATED)
{
if (result == COAP_201_CREATED) {
result = COAP_204_CHANGED;
}
}
@ -508,34 +442,25 @@ static uint8_t prv_server_write(lwm2m_context_t *contextP,
}
i = 0;
do
{
do {
/* No multiple instance resources */
if (dataArray[i].type == LWM2M_TYPE_MULTIPLE_RESOURCE)
{
if (dataArray[i].type == LWM2M_TYPE_MULTIPLE_RESOURCE) {
result = COAP_404_NOT_FOUND;
continue;
}
switch (dataArray[i].id)
{
case LWM2M_SERVER_SHORT_ID_ID:
{
uint32_t value = targetP->shortServerId;
result = prv_set_int_value(dataArray + i, &value);
if (COAP_204_CHANGED == result)
{
if (0 < value && 0xFFFF >= value)
{
targetP->shortServerId = value;
}
else
{
result = COAP_406_NOT_ACCEPTABLE;
}
switch (dataArray[i].id) {
case LWM2M_SERVER_SHORT_ID_ID: {
uint32_t value = targetP->shortServerId;
result = prv_set_int_value(dataArray + i, &value);
if (COAP_204_CHANGED == result) {
if (0 < value && 0xFFFF >= value) {
targetP->shortServerId = value;
} else {
result = COAP_406_NOT_ACCEPTABLE;
}
}
break;
} break;
case LWM2M_SERVER_LIFETIME_ID:
result = prv_set_int_value(dataArray + i, (uint32_t *)&(targetP->lifetime));
@ -557,40 +482,34 @@ static uint8_t prv_server_write(lwm2m_context_t *contextP,
result = prv_set_int_value(dataArray + i, &(targetP->disableTimeout));
break;
case LWM2M_SERVER_STORING_ID:
{
case LWM2M_SERVER_STORING_ID: {
bool value;
if (1 == lwm2m_data_decode_bool(dataArray + i, &value))
{
if (1 == lwm2m_data_decode_bool(dataArray + i, &value)) {
targetP->storing = value;
result = COAP_204_CHANGED;
}
else
{
} else {
result = COAP_400_BAD_REQUEST;
}
}
break;
} break;
case LWM2M_SERVER_BINDING_ID:
if ((dataArray[i].type == LWM2M_TYPE_STRING || dataArray[i].type == LWM2M_TYPE_OPAQUE)
&& dataArray[i].value.asBuffer.length > 0 && dataArray[i].value.asBuffer.length <= 3
if ((dataArray[i].type == LWM2M_TYPE_STRING || dataArray[i].type == LWM2M_TYPE_OPAQUE) &&
dataArray[i].value.asBuffer.length > 0 && dataArray[i].value.asBuffer.length <= 3
#ifdef LWM2M_VERSION_1_0
&& (strncmp((char*)dataArray[i].value.asBuffer.buffer, "U", dataArray[i].value.asBuffer.length) == 0
|| strncmp((char*)dataArray[i].value.asBuffer.buffer, "UQ", dataArray[i].value.asBuffer.length) == 0
|| strncmp((char*)dataArray[i].value.asBuffer.buffer, "S", dataArray[i].value.asBuffer.length) == 0
|| strncmp((char*)dataArray[i].value.asBuffer.buffer, "SQ", dataArray[i].value.asBuffer.length) == 0
|| strncmp((char*)dataArray[i].value.asBuffer.buffer, "US", dataArray[i].value.asBuffer.length) == 0
|| strncmp((char*)dataArray[i].value.asBuffer.buffer, "UQS", dataArray[i].value.asBuffer.length) == 0)
&&
(strncmp((char *)dataArray[i].value.asBuffer.buffer, "U", dataArray[i].value.asBuffer.length) == 0 ||
strncmp((char *)dataArray[i].value.asBuffer.buffer, "UQ", dataArray[i].value.asBuffer.length) == 0 ||
strncmp((char *)dataArray[i].value.asBuffer.buffer, "S", dataArray[i].value.asBuffer.length) == 0 ||
strncmp((char *)dataArray[i].value.asBuffer.buffer, "SQ", dataArray[i].value.asBuffer.length) == 0 ||
strncmp((char *)dataArray[i].value.asBuffer.buffer, "US", dataArray[i].value.asBuffer.length) == 0 ||
strncmp((char *)dataArray[i].value.asBuffer.buffer, "UQS", dataArray[i].value.asBuffer.length) == 0)
#endif
)
{
strncpy(targetP->binding, (char*)dataArray[i].value.asBuffer.buffer, dataArray[i].value.asBuffer.length);
) {
strncpy(targetP->binding, (char *)dataArray[i].value.asBuffer.buffer, // NOSONAR
dataArray[i].value.asBuffer.length);
result = COAP_204_CHANGED;
}
else
{
} else {
result = COAP_400_BAD_REQUEST;
}
break;
@ -600,163 +519,113 @@ static uint8_t prv_server_write(lwm2m_context_t *contextP,
break;
#ifndef LWM2M_VERSION_1_0
case LWM2M_SERVER_REG_ORDER_ID:
{
case LWM2M_SERVER_REG_ORDER_ID: {
uint64_t value;
if (1 == lwm2m_data_decode_uint(dataArray + i, &value))
{
if (value <= INT_MAX)
{
if (1 == lwm2m_data_decode_uint(dataArray + i, &value)) {
if (value <= INT_MAX) {
targetP->registrationPriorityOrder = value;
result = COAP_204_CHANGED;
}
else
{
} else {
result = COAP_406_NOT_ACCEPTABLE;
}
}
else
{
} else {
result = COAP_400_BAD_REQUEST;
}
break;
}
case LWM2M_SERVER_INITIAL_REG_DELAY_ID:
{
case LWM2M_SERVER_INITIAL_REG_DELAY_ID: {
uint64_t value;
if (1 == lwm2m_data_decode_uint(dataArray + i, &value))
{
if (value <= INT_MAX)
{
if (1 == lwm2m_data_decode_uint(dataArray + i, &value)) {
if (value <= INT_MAX) {
targetP->initialRegistrationDelayTimer = value;
result = COAP_204_CHANGED;
}
else
{
} else {
result = COAP_406_NOT_ACCEPTABLE;
}
}
else
{
} else {
result = COAP_400_BAD_REQUEST;
}
break;
}
case LWM2M_SERVER_REG_FAIL_BLOCK_ID:
{
case LWM2M_SERVER_REG_FAIL_BLOCK_ID: {
bool value;
if (1 == lwm2m_data_decode_bool(dataArray + i, &value))
{
if (1 == lwm2m_data_decode_bool(dataArray + i, &value)) {
targetP->registrationFailureBlock = value;
result = COAP_204_CHANGED;
}
else
{
} else {
result = COAP_400_BAD_REQUEST;
}
break;
}
case LWM2M_SERVER_REG_FAIL_BOOTSTRAP_ID:
{
case LWM2M_SERVER_REG_FAIL_BOOTSTRAP_ID: {
bool value;
if (1 == lwm2m_data_decode_bool(dataArray + i, &value))
{
if (1 == lwm2m_data_decode_bool(dataArray + i, &value)) {
targetP->bootstrapOnRegistrationFailure = value;
result = COAP_204_CHANGED;
}
else
{
} else {
result = COAP_400_BAD_REQUEST;
}
break;
}
case LWM2M_SERVER_COMM_RETRY_COUNT_ID:
{
case LWM2M_SERVER_COMM_RETRY_COUNT_ID: {
uint64_t value;
if (1 == lwm2m_data_decode_uint(dataArray + i, &value))
{
if (value <= INT_MAX)
{
if (1 == lwm2m_data_decode_uint(dataArray + i, &value)) {
if (value <= INT_MAX) {
targetP->communicationRetryCount = value;
result = COAP_204_CHANGED;
}
else
{
} else {
result = COAP_406_NOT_ACCEPTABLE;
}
}
else
{
} else {
result = COAP_400_BAD_REQUEST;
}
break;
}
case LWM2M_SERVER_COMM_RETRY_TIMER_ID:
{
case LWM2M_SERVER_COMM_RETRY_TIMER_ID: {
uint64_t value;
if (1 == lwm2m_data_decode_uint(dataArray + i, &value))
{
if (value <= INT_MAX)
{
if (1 == lwm2m_data_decode_uint(dataArray + i, &value)) {
if (value <= INT_MAX) {
targetP->communicationRetryTimer = value;
result = COAP_204_CHANGED;
}
else
{
} else {
result = COAP_406_NOT_ACCEPTABLE;
}
}
else
{
} else {
result = COAP_400_BAD_REQUEST;
}
break;
}
case LWM2M_SERVER_SEQ_DELAY_TIMER_ID:
{
case LWM2M_SERVER_SEQ_DELAY_TIMER_ID: {
uint64_t value;
if (1 == lwm2m_data_decode_uint(dataArray + i, &value))
{
if (value <= INT_MAX)
{
if (1 == lwm2m_data_decode_uint(dataArray + i, &value)) {
if (value <= INT_MAX) {
targetP->communicationSequenceDelayTimer = value;
result = COAP_204_CHANGED;
}
else
{
} else {
result = COAP_406_NOT_ACCEPTABLE;
}
}
else
{
} else {
result = COAP_400_BAD_REQUEST;
}
break;
}
case LWM2M_SERVER_SEQ_RETRY_COUNT_ID:
{
case LWM2M_SERVER_SEQ_RETRY_COUNT_ID: {
uint64_t value;
if (1 == lwm2m_data_decode_uint(dataArray + i, &value))
{
if (value <= INT_MAX)
{
if (1 == lwm2m_data_decode_uint(dataArray + i, &value)) {
if (value <= INT_MAX) {
targetP->communicationSequenceRetryCount = value;
result = COAP_204_CHANGED;
}
else
{
} else {
result = COAP_406_NOT_ACCEPTABLE;
}
}
else
{
} else {
result = COAP_400_BAD_REQUEST;
}
break;
@ -783,28 +652,26 @@ static uint8_t prv_server_write(lwm2m_context_t *contextP,
return result;
}
static uint8_t prv_server_execute(lwm2m_context_t *contextP,
uint16_t instanceId,
uint16_t resourceId,
uint8_t * buffer,
int length,
lwm2m_object_t * objectP)
static uint8_t prv_server_execute(lwm2m_context_t *contextP, uint16_t instanceId, uint16_t resourceId, uint8_t *buffer,
int length, lwm2m_object_t *objectP)
{
server_instance_t * targetP;
server_instance_t *targetP;
/* unused parameter */
(void)contextP;
targetP = (server_instance_t *)lwm2m_list_find(objectP->instanceList, instanceId);
if (NULL == targetP) return COAP_404_NOT_FOUND;
if (NULL == targetP)
return COAP_404_NOT_FOUND;
switch (resourceId)
{
switch (resourceId) {
case LWM2M_SERVER_DISABLE_ID:
// executed in core, if COAP_204_CHANGED is returned
if (0 < targetP->disableTimeout) return COAP_204_CHANGED;
else return COAP_405_METHOD_NOT_ALLOWED;
if (0 < targetP->disableTimeout)
return COAP_204_CHANGED;
else
return COAP_405_METHOD_NOT_ALLOWED;
case LWM2M_SERVER_UPDATE_ID:
// executed in core, if COAP_204_CHANGED is returned
return COAP_204_CHANGED;
@ -813,34 +680,29 @@ static uint8_t prv_server_execute(lwm2m_context_t *contextP,
}
}
static uint8_t prv_server_delete(lwm2m_context_t *contextP,
uint16_t id,
lwm2m_object_t * objectP)
{
server_instance_t * serverInstance;
static uint8_t prv_server_delete(lwm2m_context_t *contextP, uint16_t id, lwm2m_object_t *objectP) {
server_instance_t *serverInstance;
/* unused parameter */
(void)contextP;
objectP->instanceList = lwm2m_list_remove(objectP->instanceList, id, (lwm2m_list_t **)&serverInstance);
if (NULL == serverInstance) return COAP_404_NOT_FOUND;
if (NULL == serverInstance)
return COAP_404_NOT_FOUND;
lwm2m_free(serverInstance);
return COAP_202_DELETED;
}
static uint8_t prv_server_create(lwm2m_context_t *contextP,
uint16_t instanceId,
int numData,
lwm2m_data_t * dataArray,
lwm2m_object_t * objectP)
{
server_instance_t * serverInstance;
static uint8_t prv_server_create(lwm2m_context_t *contextP, uint16_t instanceId, int numData, lwm2m_data_t *dataArray,
lwm2m_object_t *objectP) {
server_instance_t *serverInstance;
uint8_t result;
serverInstance = (server_instance_t *)lwm2m_malloc(sizeof(server_instance_t));
if (NULL == serverInstance) return COAP_500_INTERNAL_SERVER_ERROR;
if (NULL == serverInstance)
return COAP_500_INTERNAL_SERVER_ERROR;
memset(serverInstance, 0, sizeof(server_instance_t));
serverInstance->instanceId = instanceId;
@ -858,76 +720,64 @@ static uint8_t prv_server_create(lwm2m_context_t *contextP,
result = prv_server_write(contextP, instanceId, numData, dataArray, objectP, LWM2M_WRITE_REPLACE_RESOURCES);
if (result != COAP_204_CHANGED)
{
if (result != COAP_204_CHANGED) {
(void)prv_server_delete(contextP, instanceId, objectP);
}
else
{
} else {
result = COAP_201_CREATED;
}
return result;
}
void copy_server_object(lwm2m_object_t * objectDest, lwm2m_object_t * objectSrc)
{
void copy_server_object(lwm2m_object_t *objectDest, lwm2m_object_t *objectSrc) {
memcpy(objectDest, objectSrc, sizeof(lwm2m_object_t));
objectDest->instanceList = NULL;
objectDest->userData = NULL;
server_instance_t * instanceSrc = (server_instance_t *)objectSrc->instanceList;
server_instance_t * previousInstanceDest = NULL;
while (instanceSrc != NULL)
{
server_instance_t * instanceDest = (server_instance_t *)lwm2m_malloc(sizeof(server_instance_t));
if (NULL == instanceDest)
{
server_instance_t *instanceSrc = (server_instance_t *)objectSrc->instanceList;
server_instance_t *previousInstanceDest = NULL;
while (instanceSrc != NULL) {
server_instance_t *instanceDest = (server_instance_t *)lwm2m_malloc(sizeof(server_instance_t));
if (NULL == instanceDest) {
return;
}
memcpy(instanceDest, instanceSrc, sizeof(server_instance_t));
// not sure it's necessary:
strcpy(instanceDest->binding, instanceSrc->binding);
strcpy(instanceDest->binding, instanceSrc->binding); // NOSONAR
instanceSrc = (server_instance_t *)instanceSrc->next;
if (previousInstanceDest == NULL)
{
if (previousInstanceDest == NULL) {
objectDest->instanceList = (lwm2m_list_t *)instanceDest;
}
else
{
} else {
previousInstanceDest->next = instanceDest;
}
previousInstanceDest = instanceDest;
}
}
void display_server_object(lwm2m_object_t * object)
{
void display_server_object(lwm2m_object_t *object) {
fprintf(stdout, " /%u: Server object, instances:\r\n", object->objID);
server_instance_t * serverInstance = (server_instance_t *)object->instanceList;
while (serverInstance != NULL)
{
server_instance_t *serverInstance = (server_instance_t *)object->instanceList;
while (serverInstance != NULL) {
fprintf(stdout, " /%u/%u: instanceId: %u, shortServerId: %u, lifetime: %u, storing: %s, binding: %s",
object->objID, serverInstance->instanceId,
serverInstance->instanceId, serverInstance->shortServerId, serverInstance->lifetime,
serverInstance->storing ? "true" : "false", serverInstance->binding);
object->objID, serverInstance->instanceId, serverInstance->instanceId, serverInstance->shortServerId,
serverInstance->lifetime, serverInstance->storing ? "true" : "false", serverInstance->binding);
#ifndef LWM2M_VERSION_1_0
if(serverInstance->registrationPriorityOrder >= 0)
if (serverInstance->registrationPriorityOrder >= 0)
fprintf(stdout, ", registrationPriorityOrder: %d", serverInstance->registrationPriorityOrder);
if(serverInstance->initialRegistrationDelayTimer >= 0)
if (serverInstance->initialRegistrationDelayTimer >= 0)
fprintf(stdout, ", initialRegistrationDelayTimer: %d", serverInstance->initialRegistrationDelayTimer);
if(serverInstance->registrationFailureBlock >= 0)
if (serverInstance->registrationFailureBlock >= 0)
fprintf(stdout, ", registrationFailureBlock: %s",
serverInstance->registrationFailureBlock > 0 ? "true" : "false");
if(serverInstance->bootstrapOnRegistrationFailure >= 0)
if (serverInstance->bootstrapOnRegistrationFailure >= 0)
fprintf(stdout, ", bootstrapOnRegistrationFaulure: %s",
serverInstance->bootstrapOnRegistrationFailure > 0 ? "true" : "false");
if(serverInstance->communicationRetryCount >= 0)
if (serverInstance->communicationRetryCount >= 0)
fprintf(stdout, ", communicationRetryCount: %d", serverInstance->communicationRetryCount);
if(serverInstance->communicationRetryTimer >= 0)
if (serverInstance->communicationRetryTimer >= 0)
fprintf(stdout, ", communicationRetryTimer: %d", serverInstance->communicationRetryTimer);
if(serverInstance->communicationSequenceDelayTimer >= 0)
if (serverInstance->communicationSequenceDelayTimer >= 0)
fprintf(stdout, ", communicationSequenceDelayTimer: %d", serverInstance->communicationSequenceDelayTimer);
if(serverInstance->communicationSequenceRetryCount >= 0)
if (serverInstance->communicationSequenceRetryCount >= 0)
fprintf(stdout, ", communicationSequenceRetryCount: %d", serverInstance->communicationSequenceRetryCount);
fprintf(stdout, ", muteSend: %s", serverInstance->muteSend ? "true" : "false");
#endif
@ -936,18 +786,13 @@ void display_server_object(lwm2m_object_t * object)
}
}
lwm2m_object_t * get_server_object(int serverId,
const char* binding,
int lifetime,
bool storing)
{
lwm2m_object_t * serverObj;
lwm2m_object_t *get_server_object(int serverId, const char *binding, int lifetime, bool storing) {
lwm2m_object_t *serverObj;
serverObj = (lwm2m_object_t *)lwm2m_malloc(sizeof(lwm2m_object_t));
if (NULL != serverObj)
{
server_instance_t * serverInstance;
if (NULL != serverObj) {
server_instance_t *serverInstance;
memset(serverObj, 0, sizeof(lwm2m_object_t));
@ -960,8 +805,7 @@ lwm2m_object_t * get_server_object(int serverId,
// Manually create an hardcoded server
serverInstance = (server_instance_t *)lwm2m_malloc(sizeof(server_instance_t));
if (NULL == serverInstance)
{
if (NULL == serverInstance) {
lwm2m_free(serverObj);
return NULL;
}
@ -971,7 +815,7 @@ lwm2m_object_t * get_server_object(int serverId,
serverInstance->shortServerId = serverId;
serverInstance->lifetime = lifetime;
serverInstance->storing = storing;
memcpy (serverInstance->binding, binding, strlen(binding)+1);
memcpy(serverInstance->binding, binding, strlen(binding) + 1); // NOSONAR
#ifndef LWM2M_VERSION_1_0
serverInstance->registrationPriorityOrder = -1;
serverInstance->initialRegistrationDelayTimer = -1;
@ -996,11 +840,9 @@ lwm2m_object_t * get_server_object(int serverId,
return serverObj;
}
void clean_server_object(lwm2m_object_t * object)
{
while (object->instanceList != NULL)
{
server_instance_t * serverInstance = (server_instance_t *)object->instanceList;
void clean_server_object(lwm2m_object_t *object) {
while (object->instanceList != NULL) {
server_instance_t *serverInstance = (server_instance_t *)object->instanceList;
object->instanceList = object->instanceList->next;
lwm2m_free(serverInstance);
}

View File

@ -72,10 +72,10 @@
#include "liblwm2m.h"
#include "lwm2mclient.h"
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define PRV_TLV_BUFFER_SIZE 64
@ -84,59 +84,47 @@
* The lwm2m_object_t object structure - which represent every object of the liblwm2m as seen in the single instance
* object - contain a chained list called instanceList with the object specific structure prv_instance_t:
*/
typedef struct _prv_instance_
{
typedef struct _prv_instance_ {
/*
* The first two are mandatories and represent the pointer to the next instance and the ID of this one. The rest
* is the instance scope user data (uint8_t test in this case)
*/
struct _prv_instance_ * next; // matches lwm2m_list_t::next
uint16_t shortID; // matches lwm2m_list_t::id
uint8_t test;
double dec;
char * str;
struct _prv_instance_ *next; // matches lwm2m_list_t::next
uint16_t shortID; // matches lwm2m_list_t::id
uint8_t test;
double dec;
char *str;
#ifdef LWM2M_RAW_BLOCK1_REQUESTS
uint8_t * block_buffer;
size_t value_offset;
size_t value_len;
uint8_t *block_buffer;
size_t value_offset;
size_t value_len;
#endif
} prv_instance_t;
static uint8_t prv_delete(lwm2m_context_t *contextP,
uint16_t id,
lwm2m_object_t * objectP);
static uint8_t prv_create(lwm2m_context_t *contextP,
uint16_t instanceId,
int numData,
lwm2m_data_t * dataArray,
lwm2m_object_t * objectP);
static uint8_t prv_delete(lwm2m_context_t *contextP, uint16_t id, lwm2m_object_t *objectP);
static uint8_t prv_create(lwm2m_context_t *contextP, uint16_t instanceId, int numData, lwm2m_data_t *dataArray,
lwm2m_object_t *objectP);
static void prv_output_buffer(uint8_t * buffer,
int length)
{
static void prv_output_buffer(uint8_t *buffer, int length) {
int i;
uint8_t array[16];
i = 0;
while (i < length)
{
while (i < length) {
int j;
fprintf(stderr, " ");
memcpy(array, buffer+i, 16);
memcpy(array, buffer + i, 16);
for (j = 0 ; j < 16 && i+j < length; j++)
{
for (j = 0; j < 16 && i + j < length; j++) {
fprintf(stderr, "%02X ", array[j]);
}
while (j < 16)
{
while (j < 16) {
fprintf(stderr, " ");
j++;
}
fprintf(stderr, " ");
for (j = 0 ; j < 16 && i+j < length; j++)
{
for (j = 0; j < 16 && i + j < length; j++) {
if (isprint(array[j]))
fprintf(stderr, "%c ", array[j]);
else
@ -148,40 +136,34 @@ static void prv_output_buffer(uint8_t * buffer,
}
}
static uint8_t prv_read(lwm2m_context_t *contextP,
uint16_t instanceId,
int * numDataP,
lwm2m_data_t ** dataArrayP,
lwm2m_object_t * objectP)
{
prv_instance_t * targetP;
static uint8_t prv_read(lwm2m_context_t *contextP, uint16_t instanceId, int *numDataP, lwm2m_data_t **dataArrayP,
lwm2m_object_t *objectP) {
prv_instance_t *targetP;
int i;
/* unused parameter */
(void)contextP;
targetP = (prv_instance_t *)lwm2m_list_find(objectP->instanceList, instanceId);
if (NULL == targetP) return COAP_404_NOT_FOUND;
if (NULL == targetP)
return COAP_404_NOT_FOUND;
if (*numDataP == 0)
{
if (*numDataP == 0) {
*dataArrayP = lwm2m_data_new(3);
if (*dataArrayP == NULL) return COAP_500_INTERNAL_SERVER_ERROR;
if (*dataArrayP == NULL)
return COAP_500_INTERNAL_SERVER_ERROR;
*numDataP = 3;
(*dataArrayP)[0].id = 1;
(*dataArrayP)[1].id = 3;
(*dataArrayP)[2].id = 5;
}
for (i = 0 ; i < *numDataP ; i++)
{
if ((*dataArrayP)[i].type == LWM2M_TYPE_MULTIPLE_RESOURCE)
{
for (i = 0; i < *numDataP; i++) {
if ((*dataArrayP)[i].type == LWM2M_TYPE_MULTIPLE_RESOURCE) {
return COAP_404_NOT_FOUND;
}
switch ((*dataArrayP)[i].id)
{
switch ((*dataArrayP)[i].id) {
case 1:
lwm2m_data_encode_int(targetP->test, *dataArrayP + i);
break;
@ -201,34 +183,26 @@ static uint8_t prv_read(lwm2m_context_t *contextP,
return COAP_205_CONTENT;
}
static uint8_t prv_discover(lwm2m_context_t *contextP,
uint16_t instanceId,
int * numDataP,
lwm2m_data_t ** dataArrayP,
lwm2m_object_t * objectP)
{
static uint8_t prv_discover(lwm2m_context_t *contextP, uint16_t instanceId, int *numDataP, lwm2m_data_t **dataArrayP,
lwm2m_object_t *objectP) {
int i;
/* unused parameter */
(void)contextP;
// is the server asking for the full object ?
if (*numDataP == 0)
{
if (*numDataP == 0) {
*dataArrayP = lwm2m_data_new(4);
if (*dataArrayP == NULL) return COAP_500_INTERNAL_SERVER_ERROR;
if (*dataArrayP == NULL)
return COAP_500_INTERNAL_SERVER_ERROR;
*numDataP = 3;
(*dataArrayP)[0].id = 1;
(*dataArrayP)[1].id = 2;
(*dataArrayP)[2].id = 3;
(*dataArrayP)[3].id = 5;
}
else
{
for (i = 0; i < *numDataP; i++)
{
switch ((*dataArrayP)[i].id)
{
} else {
for (i = 0; i < *numDataP; i++) {
switch ((*dataArrayP)[i].id) {
case 1:
case 2:
case 3:
@ -243,75 +217,61 @@ static uint8_t prv_discover(lwm2m_context_t *contextP,
return COAP_205_CONTENT;
}
static uint8_t prv_write(lwm2m_context_t *contextP,
uint16_t instanceId,
int numData,
lwm2m_data_t * dataArray,
lwm2m_object_t * objectP,
lwm2m_write_type_t writeType)
{
prv_instance_t * targetP;
static uint8_t prv_write(lwm2m_context_t *contextP, uint16_t instanceId, int numData, lwm2m_data_t *dataArray,
lwm2m_object_t *objectP, lwm2m_write_type_t writeType) {
prv_instance_t *targetP;
int i;
char * tmp;
targetP = (prv_instance_t *)lwm2m_list_find(objectP->instanceList, instanceId);
if (NULL == targetP) return COAP_404_NOT_FOUND;
char *tmp;
if (writeType == LWM2M_WRITE_REPLACE_INSTANCE)
{
targetP = (prv_instance_t *)lwm2m_list_find(objectP->instanceList, instanceId);
if (NULL == targetP)
return COAP_404_NOT_FOUND;
if (writeType == LWM2M_WRITE_REPLACE_INSTANCE) {
uint8_t result = prv_delete(contextP, instanceId, objectP);
if (result == COAP_202_DELETED)
{
if (result == COAP_202_DELETED) {
result = prv_create(contextP, instanceId, numData, dataArray, objectP);
if (result == COAP_201_CREATED)
{
if (result == COAP_201_CREATED) {
result = COAP_204_CHANGED;
}
}
return result;
}
for (i = 0 ; i < numData ; i++)
{
for (i = 0; i < numData; i++) {
/* No multiple instance resources */
if (dataArray[i].type == LWM2M_TYPE_MULTIPLE_RESOURCE) return COAP_404_NOT_FOUND;
if (dataArray[i].type == LWM2M_TYPE_MULTIPLE_RESOURCE)
return COAP_404_NOT_FOUND;
switch (dataArray[i].id)
{
case 1:
{
int64_t value;
switch (dataArray[i].id) {
case 1: {
int64_t value;
if (1 != lwm2m_data_decode_int(dataArray + i, &value) || value < 0 || value > 0xFF)
{
return COAP_400_BAD_REQUEST;
}
targetP->test = (uint8_t)value;
if (1 != lwm2m_data_decode_int(dataArray + i, &value) || value < 0 || value > 0xFF) {
return COAP_400_BAD_REQUEST;
}
targetP->test = (uint8_t)value;
} break;
case 2:
return COAP_405_METHOD_NOT_ALLOWED;
case 3:
if (1 != lwm2m_data_decode_float(dataArray + i, &(targetP->dec))) {
return COAP_400_BAD_REQUEST;
}
break;
case 2:
return COAP_405_METHOD_NOT_ALLOWED;
case 3:
if (1 != lwm2m_data_decode_float(dataArray + i, &(targetP->dec)))
{
return COAP_400_BAD_REQUEST;
}
case 5:
if (dataArray[i].type == LWM2M_TYPE_STRING || dataArray[i].type == LWM2M_TYPE_OPAQUE) {
tmp = targetP->str;
targetP->str = lwm2m_malloc(dataArray[i].value.asBuffer.length + 1);
strncpy(targetP->str, (char *)dataArray[i].value.asBuffer.buffer, // NOSONAR
dataArray[i].value.asBuffer.length);
lwm2m_free(tmp);
break;
case 5:
if (dataArray[i].type == LWM2M_TYPE_STRING || dataArray[i].type == LWM2M_TYPE_OPAQUE)
{
tmp = targetP->str;
targetP->str = lwm2m_malloc(dataArray[i].value.asBuffer.length + 1);
strncpy(targetP->str, (char*)dataArray[i].value.asBuffer.buffer, dataArray[i].value.asBuffer.length);
lwm2m_free(tmp);
break;
}
else
{
return COAP_400_BAD_REQUEST;
}
default:
return COAP_404_NOT_FOUND;
} else {
return COAP_400_BAD_REQUEST;
}
default:
return COAP_404_NOT_FOUND;
}
}
@ -320,10 +280,8 @@ static uint8_t prv_write(lwm2m_context_t *contextP,
#ifdef LWM2M_RAW_BLOCK1_REQUESTS
static void prv_block_buffer_free(prv_instance_t * targetP)
{
if (targetP->block_buffer != NULL)
{
static void prv_block_buffer_free(prv_instance_t *targetP) {
if (targetP->block_buffer != NULL) {
lwm2m_free(targetP->block_buffer);
targetP->block_buffer = NULL;
targetP->value_len = 0;
@ -331,28 +289,22 @@ static void prv_block_buffer_free(prv_instance_t * targetP)
}
}
static uint8_t prv_raw_block1_write(lwm2m_context_t *contextP,
lwm2m_uri_t * uriP,
lwm2m_media_type_t format,
uint8_t * payload,
int length,
lwm2m_object_t * objectP,
uint32_t block_num,
uint8_t block_more)
{
prv_instance_t * targetP;
static uint8_t prv_raw_block1_write(lwm2m_context_t *contextP, lwm2m_uri_t *uriP, lwm2m_media_type_t format,
uint8_t *payload, int length, lwm2m_object_t *objectP, uint32_t block_num,
uint8_t block_more) {
prv_instance_t *targetP;
targetP = (prv_instance_t *)lwm2m_list_find(objectP->instanceList, uriP->instanceId);
if (NULL == targetP) return COAP_404_NOT_FOUND;
if (uriP->resourceId < 5) return COAP_400_BAD_REQUEST;
if (uriP->resourceId > 5) return COAP_404_NOT_FOUND;
if (NULL == targetP)
return COAP_404_NOT_FOUND;
if (uriP->resourceId < 5)
return COAP_400_BAD_REQUEST;
if (uriP->resourceId > 5)
return COAP_404_NOT_FOUND;
// Only accept single attribute value
if (block_num == 0
&& format == LWM2M_CONTENT_TLV
&& length > 0
&& ((payload[0] & 0xC0) == 0xC0 || (payload[0] & 0xC0) == 0x40))
{
if (block_num == 0 && format == LWM2M_CONTENT_TLV && length > 0 &&
((payload[0] & 0xC0) == 0xC0 || (payload[0] & 0xC0) == 0x40)) {
prv_block_buffer_free(targetP);
int offset; // length of id field
@ -362,65 +314,56 @@ static uint8_t prv_raw_block1_write(lwm2m_context_t *contextP,
} else {
offset = 1;
}
switch (payload[0] & 0x18)
{
case 0x00:
// no length field
targetP->value_len = payload[0] & 0x07;
break;
case 0x08:
// length field is 8 bits long
targetP->value_len = payload[offset];
offset += 1;
break;
case 0x10:
// length field is 16 bits long
targetP->value_len = (payload[offset]<<8) + payload[offset+1];
offset += 2;
break;
case 0x18:
// length field is 24 bits long
targetP->value_len = (payload[offset]<<16) + (payload[offset+1]<<8) + payload[offset+2];
offset += 3;
break;
default:
// this should never occur, so return Bad Request
return COAP_400_BAD_REQUEST;
switch (payload[0] & 0x18) {
case 0x00:
// no length field
targetP->value_len = payload[0] & 0x07;
break;
case 0x08:
// length field is 8 bits long
targetP->value_len = payload[offset];
offset += 1;
break;
case 0x10:
// length field is 16 bits long
targetP->value_len = (payload[offset] << 8) + payload[offset + 1];
offset += 2;
break;
case 0x18:
// length field is 24 bits long
targetP->value_len = (payload[offset] << 16) + (payload[offset + 1] << 8) + payload[offset + 2];
offset += 3;
break;
default:
// this should never occur, so return Bad Request
return COAP_400_BAD_REQUEST;
}
targetP->value_offset = offset;
targetP->block_buffer = lwm2m_malloc(targetP->value_offset + targetP->value_offset);
}
else if (length > 0 && (format == LWM2M_CONTENT_OPAQUE || format == LWM2M_CONTENT_TEXT))
{
} else if (length > 0 && (format == LWM2M_CONTENT_OPAQUE || format == LWM2M_CONTENT_TEXT)) {
size_t len = targetP->value_len + length;
uint8_t * tmp = (uint8_t *)lwm2m_malloc(len);
if (targetP->block_buffer != NULL)
{
uint8_t *tmp = (uint8_t *)lwm2m_malloc(len);
if (targetP->block_buffer != NULL) {
memcpy(tmp, targetP->block_buffer, targetP->value_len);
prv_block_buffer_free(targetP);
}
targetP->block_buffer = tmp;
targetP->value_len = len;
}
else
{
} else {
return COAP_400_BAD_REQUEST;
}
}
if ((block_num + 1) * length > targetP->value_offset + targetP->value_len)
{
if ((block_num + 1) * length > targetP->value_offset + targetP->value_len) {
prv_block_buffer_free(targetP);
return COAP_400_BAD_REQUEST;
}
else
{
} else {
memcpy(targetP->block_buffer + (block_num * length), payload, length);
}
if (block_more == 0){
char * old_str = targetP->str;
if (block_more == 0) {
char *old_str = targetP->str;
targetP->str = lwm2m_malloc(targetP->value_len + 1);
strncpy(targetP->str, (char*) targetP->block_buffer + targetP->value_offset, targetP->value_len);
strncpy(targetP->str, (char *)targetP->block_buffer + targetP->value_offset, targetP->value_len); // NOSONAR
targetP->str[targetP->value_len] = 0;
lwm2m_free(old_str);
prv_block_buffer_free(targetP);
@ -428,21 +371,18 @@ static uint8_t prv_raw_block1_write(lwm2m_context_t *contextP,
} else {
return COAP_231_CONTINUE;
}
}
#endif
static uint8_t prv_delete(lwm2m_context_t *contextP,
uint16_t id,
lwm2m_object_t * objectP)
{
prv_instance_t * targetP;
static uint8_t prv_delete(lwm2m_context_t *contextP, uint16_t id, lwm2m_object_t *objectP) {
prv_instance_t *targetP;
/* unused parameter */
(void)contextP;
objectP->instanceList = lwm2m_list_remove(objectP->instanceList, id, (lwm2m_list_t **)&targetP);
if (NULL == targetP) return COAP_404_NOT_FOUND;
if (NULL == targetP)
return COAP_404_NOT_FOUND;
#ifdef LWM2M_RAW_BLOCK1_REQUESTS
lwm2m_free(targetP->block_buffer);
@ -455,18 +395,14 @@ static uint8_t prv_delete(lwm2m_context_t *contextP,
return COAP_202_DELETED;
}
static uint8_t prv_create(lwm2m_context_t *contextP,
uint16_t instanceId,
int numData,
lwm2m_data_t * dataArray,
lwm2m_object_t * objectP)
{
prv_instance_t * targetP;
static uint8_t prv_create(lwm2m_context_t *contextP, uint16_t instanceId, int numData, lwm2m_data_t *dataArray,
lwm2m_object_t *objectP) {
prv_instance_t *targetP;
uint8_t result;
targetP = (prv_instance_t *)lwm2m_malloc(sizeof(prv_instance_t));
if (NULL == targetP) return COAP_500_INTERNAL_SERVER_ERROR;
if (NULL == targetP)
return COAP_500_INTERNAL_SERVER_ERROR;
memset(targetP, 0, sizeof(prv_instance_t));
targetP->shortID = instanceId;
@ -474,74 +410,62 @@ static uint8_t prv_create(lwm2m_context_t *contextP,
result = prv_write(contextP, instanceId, numData, dataArray, objectP, LWM2M_WRITE_REPLACE_RESOURCES);
if (result != COAP_204_CHANGED)
{
if (result != COAP_204_CHANGED) {
(void)prv_delete(contextP, instanceId, objectP);
}
else
{
} else {
result = COAP_201_CREATED;
}
return result;
}
static uint8_t prv_exec(lwm2m_context_t *contextP,
uint16_t instanceId,
uint16_t resourceId,
uint8_t * buffer,
int length,
lwm2m_object_t * objectP)
{
static uint8_t prv_exec(lwm2m_context_t *contextP, uint16_t instanceId, uint16_t resourceId, uint8_t *buffer,
int length, lwm2m_object_t *objectP) {
/* unused parameter */
(void)contextP;
if (NULL == lwm2m_list_find(objectP->instanceList, instanceId)) return COAP_404_NOT_FOUND;
if (NULL == lwm2m_list_find(objectP->instanceList, instanceId))
return COAP_404_NOT_FOUND;
switch (resourceId)
{
case 1:
return COAP_405_METHOD_NOT_ALLOWED;
case 2:
fprintf(stdout, "\r\n-----------------\r\n"
"Execute on %hu/%d/%d\r\n"
" Parameter (%d bytes):\r\n",
objectP->objID, instanceId, resourceId, length);
prv_output_buffer((uint8_t*)buffer, length);
fprintf(stdout, "-----------------\r\n\r\n");
return COAP_204_CHANGED;
case 3:
return COAP_405_METHOD_NOT_ALLOWED;
case 5:
return COAP_405_METHOD_NOT_ALLOWED;
default:
return COAP_404_NOT_FOUND;
switch (resourceId) {
case 1:
return COAP_405_METHOD_NOT_ALLOWED;
case 2:
fprintf(stdout,
"\r\n-----------------\r\n"
"Execute on %hu/%d/%d\r\n"
" Parameter (%d bytes):\r\n",
objectP->objID, instanceId, resourceId, length);
prv_output_buffer((uint8_t *)buffer, length);
fprintf(stdout, "-----------------\r\n\r\n");
return COAP_204_CHANGED;
case 3:
return COAP_405_METHOD_NOT_ALLOWED;
case 5:
return COAP_405_METHOD_NOT_ALLOWED;
default:
return COAP_404_NOT_FOUND;
}
}
void display_test_object(lwm2m_object_t * object)
{
void display_test_object(lwm2m_object_t *object) {
fprintf(stdout, " /%u: Test object, instances:\r\n", object->objID);
prv_instance_t * instance = (prv_instance_t *)object->instanceList;
while (instance != NULL)
{
fprintf(stdout, " /%u/%u: shortId: %u, test: %u\r\n",
object->objID, instance->shortID,
instance->shortID, instance->test);
prv_instance_t *instance = (prv_instance_t *)object->instanceList;
while (instance != NULL) {
fprintf(stdout, " /%u/%u: shortId: %u, test: %u\r\n", object->objID, instance->shortID, instance->shortID,
instance->test);
instance = (prv_instance_t *)instance->next;
}
}
lwm2m_object_t * get_test_object(void)
{
lwm2m_object_t * testObj;
lwm2m_object_t *get_test_object(void) {
lwm2m_object_t *testObj;
testObj = (lwm2m_object_t *)lwm2m_malloc(sizeof(lwm2m_object_t));
if (NULL != testObj)
{
if (NULL != testObj) {
int i;
prv_instance_t * targetP;
prv_instance_t *targetP;
memset(testObj, 0, sizeof(lwm2m_object_t));
@ -549,20 +473,20 @@ lwm2m_object_t * get_test_object(void)
// Not required, but useful for testing.
testObj->versionMajor = 1;
testObj->versionMinor = 0;
for (i=0 ; i < 3 ; i++)
{
for (i = 0; i < 3; i++) {
targetP = (prv_instance_t *)lwm2m_malloc(sizeof(prv_instance_t));
if (NULL == targetP) return NULL;
if (NULL == targetP)
return NULL;
memset(targetP, 0, sizeof(prv_instance_t));
targetP->shortID = 10 + i;
targetP->test = 20 + i;
targetP->dec = -30 + i + (double)i/100.0;
char * str = lwm2m_malloc(i + 1);
targetP->test = 20 + i;
targetP->dec = -30 + i + (double)i / 100.0;
char *str = lwm2m_malloc(i + 1);
str[0] = 0;
for (int j = 0; j < i; j++) {
strcat(str, "I");
strcat(str, "I"); // NOSONAR
}
targetP->str = str;
targetP->str = str;
#ifdef LWM2M_RAW_BLOCK1_REQUESTS
targetP->block_buffer = NULL;
targetP->value_len = 0;
@ -586,20 +510,16 @@ lwm2m_object_t * get_test_object(void)
#ifdef LWM2M_RAW_BLOCK1_REQUESTS
testObj->rawBlock1WriteFunc = prv_raw_block1_write;
#endif
}
return testObj;
}
void free_test_object(lwm2m_object_t * object)
{
prv_instance_t * targetP = (prv_instance_t *)object->instanceList;
while (targetP != NULL)
{
prv_instance_t * next = targetP->next;
if (targetP != NULL)
{
void free_test_object(lwm2m_object_t *object) {
prv_instance_t *targetP = (prv_instance_t *)object->instanceList;
while (targetP != NULL) {
prv_instance_t *next = targetP->next;
if (targetP != NULL) {
lwm2m_free(targetP->str);
#ifdef LWM2M_RAW_BLOCK1_REQUESTS
prv_block_buffer_free(targetP);
@ -608,11 +528,9 @@ void free_test_object(lwm2m_object_t * object)
targetP = next;
}
LWM2M_LIST_FREE(object->instanceList);
if (object->userData != NULL)
{
if (object->userData != NULL) {
lwm2m_free(object->userData);
object->userData = NULL;
}
lwm2m_free(object);
}

View File

@ -27,33 +27,23 @@
#include "lwm2mclient.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <string.h>
#ifdef LWM2M_EMBEDDED_MODE
static void prv_value_change(void* context,
const char* uriPath,
const char * value,
size_t valueLength)
{
static void prv_value_change(void *context, const char *uriPath, const char *value, size_t valueLength) {
lwm2m_uri_t uri;
if (lwm2m_stringToUri(uriPath, strlen(uriPath), &uri))
{
if (lwm2m_stringToUri(uriPath, strlen(uriPath), &uri)) { // NOSONAR
handle_value_changed(context, &uri, value, valueLength);
}
}
void init_value_change(lwm2m_context_t * lwm2m)
{
system_setValueChangedHandler(lwm2m, prv_value_change);
}
void init_value_change(lwm2m_context_t *lwm2m) { system_setValueChangedHandler(lwm2m, prv_value_change); }
#else
void init_value_change(lwm2m_context_t * lwm2m)
{
}
void init_value_change(lwm2m_context_t *lwm2m) {}
void system_reboot(void) { exit(1); }

View File

@ -1,111 +0,0 @@
/*******************************************************************************
*
* Copyright (c) 2014 Bosch Software Innovations GmbH, Germany.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v20.html
* The Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Bosch Software Innovations GmbH - Please refer to git log
*
*******************************************************************************/
/*
* lwm2mclient.h
*
* General functions of lwm2m test client.
*
* Created on: 22.01.2015
* Author: Achim Kraus
* Copyright (c) 2015 Bosch Software Innovations GmbH, Germany. All rights reserved.
*/
#ifndef LWM2MCLIENT_H_
#define LWM2MCLIENT_H_
#include "liblwm2m.h"
extern int g_reboot;
/*
* object_device.c
*/
lwm2m_object_t * get_object_device(void);
void free_object_device(lwm2m_object_t * objectP);
uint8_t device_change(lwm2m_data_t * dataArray, lwm2m_object_t * objectP);
void display_device_object(lwm2m_object_t * objectP);
/*
* object_firmware.c
*/
lwm2m_object_t * get_object_firmware(void);
void free_object_firmware(lwm2m_object_t * objectP);
void display_firmware_object(lwm2m_object_t * objectP);
/*
* object_location.c
*/
lwm2m_object_t * get_object_location(void);
void free_object_location(lwm2m_object_t * object);
void display_location_object(lwm2m_object_t * objectP);
/*
* object_test.c
*/
#define TEST_OBJECT_ID 31024
lwm2m_object_t * get_test_object(void);
void free_test_object(lwm2m_object_t * object);
void display_test_object(lwm2m_object_t * objectP);
/*
* object_server.c
*/
lwm2m_object_t * get_server_object(int serverId, const char* binding, int lifetime, bool storing);
void clean_server_object(lwm2m_object_t * object);
void display_server_object(lwm2m_object_t * objectP);
void copy_server_object(lwm2m_object_t * objectDest, lwm2m_object_t * objectSrc);
/*
* object_connectivity_moni.c
*/
lwm2m_object_t * get_object_conn_m(void);
void free_object_conn_m(lwm2m_object_t * objectP);
uint8_t connectivity_moni_change(lwm2m_data_t * dataArray, lwm2m_object_t * objectP);
/*
* object_connectivity_stat.c
*/
extern lwm2m_object_t * get_object_conn_s(void);
void free_object_conn_s(lwm2m_object_t * objectP);
extern void conn_s_updateTxStatistic(lwm2m_object_t * objectP, uint16_t txDataByte, bool smsBased);
extern void conn_s_updateRxStatistic(lwm2m_object_t * objectP, uint16_t rxDataByte, bool smsBased);
/*
* object_access_control.c
*/
lwm2m_object_t* acc_ctrl_create_object(void);
void acl_ctrl_free_object(lwm2m_object_t * objectP);
bool acc_ctrl_obj_add_inst (lwm2m_object_t* accCtrlObjP, uint16_t instId,
uint16_t acObjectId, uint16_t acObjInstId, uint16_t acOwner);
bool acc_ctrl_oi_add_ac_val(lwm2m_object_t* accCtrlObjP, uint16_t instId,
uint16_t aclResId, uint16_t acValue);
/*
* lwm2mclient.c
*/
void handle_value_changed(lwm2m_context_t* lwm2mH, lwm2m_uri_t* uri, const char * value, size_t valueLength);
/*
* system_api.c
*/
void init_value_change(lwm2m_context_t * lwm2m);
void system_reboot(void);
/*
* object_security.c
*/
lwm2m_object_t * get_security_object(int serverId, const char* serverUri, char * bsPskId, char * psk, uint16_t pskLen, bool isBootstrap);
void clean_security_object(lwm2m_object_t * objectP);
char * get_server_uri(lwm2m_object_t * objectP, uint16_t secObjInstID);
void display_security_object(lwm2m_object_t * objectP);
void copy_security_object(lwm2m_object_t * objectDest, lwm2m_object_t * objectSrc);
#endif /* LWM2MCLIENT_H_ */

View File

@ -1,352 +0,0 @@
/*******************************************************************************
*
* Copyright (c) 2014 Bosch Software Innovations GmbH, Germany.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v20.html
* The Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Bosch Software Innovations GmbH - Please refer to git log
* Pascal Rieux - Please refer to git log
* Scott Bertin, AMETEK, Inc. - Please refer to git log
*
******************************************************************************/
/*! \file
LWM2M object "Location" implementation
\author Joerg Hubschneider
*/
/*
* Object | | Multiple | | Description |
* Name | ID | Instances |Mand.| |
*-------------+------+-----------+-----+-------------------------------+
* Location | 6 | No | No | see TS E.7 page 101 |
*
* Resources:
* Name | ID | Oper.|Instances|Mand.| Type | Range | Units | Description |
* -------------+-----+------+---------+-----+---------+-------+-------+----------------------------------------------------------------------------------+
* Latitude | 0 | R | Single | Yes | Float | | Deg | The decimal notation of latitude e.g. - 45.5723 [Worlds Geodetic System 1984].|
* Longitude | 1 | R | Single | Yes | Float | | Deg | The decimal notation of longitude e.g. - 153.21760 [Worlds Geodetic System 1984].|
* Altitude | 2 | R | Single | No | Float | | m | The decimal notation of altitude in meters above sea level. |
* Radius | 3 | R | Single | No | Float | | m | The value in the Radius Resource indicates the size in meters of a circular area |
* | | | | | | | | around a point of geometry. |
* Velocity | 4 | R | Single | No | Opaque | | * | The velocity of the device as defined in 3GPP 23.032 GAD specification(*). |
* | | | | | | | | This set of values may not be available if the device is static. |
* | | | | | | | | opaque: see OMA_TS 6.3.2 |
* Timestamp | 5 | R | Single | Yes | Time | | s | The timestamp when the location measurement was performed. |
* Speed | 6 | R | Single | No | Float | | m/s | Speed is the time rate of change in position of a LwM2M Client without regard |
* | | | | | | | | for direction: the scalar component of velocity. |
*/
#include "liblwm2m.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#ifdef LWM2M_CLIENT_MODE
// ---- private "object location" specific defines ----
// Resource Id's:
#define RES_M_LATITUDE 0
#define RES_M_LONGITUDE 1
#define RES_O_ALTITUDE 2
#define RES_O_RADIUS 3
#define RES_O_VELOCITY 4
#define RES_M_TIMESTAMP 5
#define RES_O_SPEED 6
//----- 3GPP TS 23.032 V11.0.0(2012-09) ---------
#define HORIZONTAL_VELOCITY 0 // for Octet-1 upper half(..<<4)
#define HORIZONTAL_VELOCITY_VERTICAL 1 // set vertical direction bit!
#define HORIZONTAL_VELOCITY_WITH_UNCERTAINTY 2
#define HORIZONTAL_VELOCITY_VERTICAL_WITH_UNCERTAINTY 3
#define VELOCITY_OCTETS 7 // for HORIZONTAL_VELOCITY_VERTICAL_WITH_UNCERTAINTY
typedef struct
{
float latitude;
float longitude;
float altitude;
float radius;
uint8_t velocity [VELOCITY_OCTETS]; //3GPP notation 1st step: HORIZONTAL_VELOCITY_WITH_UNCERTAINTY
unsigned long timestamp;
float speed;
} location_data_t;
/**
implementation for all read-able resources
*/
static uint8_t prv_res2tlv(lwm2m_data_t* dataP,
location_data_t* locDataP)
{
//-------------------------------------------------------------------- JH --
uint8_t ret = COAP_205_CONTENT;
switch (dataP->id) // location resourceId
{
case RES_M_LATITUDE:
lwm2m_data_encode_float(locDataP->latitude, dataP);
break;
case RES_M_LONGITUDE:
lwm2m_data_encode_float(locDataP->longitude, dataP);
break;
case RES_O_ALTITUDE:
lwm2m_data_encode_float(locDataP->altitude, dataP);
break;
case RES_O_RADIUS:
lwm2m_data_encode_float(locDataP->radius, dataP);
break;
case RES_O_VELOCITY:
{
size_t length;
switch( locDataP->velocity[0] >> 4 )
{
case HORIZONTAL_VELOCITY:
{
length = 4;
break;
}
case HORIZONTAL_VELOCITY_VERTICAL:
{
length = 5;
break;
}
case HORIZONTAL_VELOCITY_WITH_UNCERTAINTY:
{
length = 5;
break;
}
case HORIZONTAL_VELOCITY_VERTICAL_WITH_UNCERTAINTY:
{
length = 7;
break;
}
default:
{
length = 0;
break;
}
}
lwm2m_data_encode_opaque(locDataP->velocity, length, dataP);
break;
}
case RES_M_TIMESTAMP:
lwm2m_data_encode_int(locDataP->timestamp, dataP);
break;
case RES_O_SPEED:
lwm2m_data_encode_float(locDataP->speed, dataP);
break;
default:
ret = COAP_404_NOT_FOUND;
break;
}
return ret;
}
/**
* Implementation (callback-) function of reading object resources. For whole
* object, single resources or a sequence of resources
* see 3GPP TS 23.032 V11.0.0(2012-09) page 23,24.
* implemented for: HORIZONTAL_VELOCITY_WITH_UNCERTAINT
* @param contextP in, unused pointer to LWM2M context
* @param objInstId in, instances ID of the location object to read
* @param numDataP in/out, pointer to the number of resource to read. 0 is the
* exception for all readable resource of object instance
* @param tlvArrayP in/out, TLV data sequence with initialized resource ID to read
* @param objectP in, private location data structure
*/
static uint8_t prv_location_read(lwm2m_context_t *contextP,
uint16_t objInstId,
int* numDataP,
lwm2m_data_t** tlvArrayP,
lwm2m_object_t* objectP)
{
//-------------------------------------------------------------------- JH --
int i;
uint8_t result = COAP_500_INTERNAL_SERVER_ERROR;
location_data_t* locDataP = (location_data_t*)(objectP->userData);
/* unused parameter */
(void)contextP;
// defined as single instance object!
if (objInstId != 0) return COAP_404_NOT_FOUND;
if (*numDataP == 0) // full object, readable resources!
{
uint16_t readResIds[] = {
RES_M_LATITUDE,
RES_M_LONGITUDE,
RES_O_ALTITUDE,
RES_O_RADIUS,
RES_O_VELOCITY,
RES_M_TIMESTAMP,
RES_O_SPEED
}; // readable resources!
*numDataP = sizeof(readResIds)/sizeof(uint16_t);
*tlvArrayP = lwm2m_data_new(*numDataP);
if (*tlvArrayP == NULL) return COAP_500_INTERNAL_SERVER_ERROR;
// init readable resource id's
for (i = 0 ; i < *numDataP ; i++)
{
(*tlvArrayP)[i].id = readResIds[i];
}
}
for (i = 0 ; i < *numDataP ; i++)
{
if ((*tlvArrayP)[i].type == LWM2M_TYPE_MULTIPLE_RESOURCE)
{
result = COAP_404_NOT_FOUND;
}
else
{
result = prv_res2tlv ((*tlvArrayP)+i, locDataP);
}
if (result!=COAP_205_CONTENT) break;
}
return result;
}
void display_location_object(lwm2m_object_t * object)
{
location_data_t * data = (location_data_t *)object->userData;
fprintf(stdout, " /%u: Location object:\r\n", object->objID);
if (NULL != data)
{
fprintf(stdout, " latitude: %.6f, longitude: %.6f, altitude: %.6f, radius: %.6f, timestamp: %lu, speed: %.6f\r\n",
data->latitude, data->longitude, data->altitude, data->radius, data->timestamp, data->speed);
}
}
/**
* Convenience function to set the velocity attributes.
* see 3GPP TS 23.032 V11.0.0(2012-09) page 23,24.
* implemented for: HORIZONTAL_VELOCITY_WITH_UNCERTAINTY
* @param locationObj location object reference (to be casted!)
* @param bearing [Deg] 0 - 359 resolution: 1 degree
* @param horizontalSpeed [km/h] 1 - s^16-1 resolution: 1 km/h steps
* @param speedUncertainty [km/h] 1-254 resolution: 1 km/h (255=undefined!)
*/
void location_setVelocity(lwm2m_object_t* locationObj,
uint16_t bearing,
uint16_t horizontalSpeed,
uint8_t speedUncertainty)
{
//-------------------------------------------------------------------- JH --
location_data_t* pData = locationObj->userData;
pData->velocity[0] = HORIZONTAL_VELOCITY_WITH_UNCERTAINTY << 4;
pData->velocity[0] |= (bearing & 0x100) >> 8;
pData->velocity[1] = (bearing & 0x0FF);
pData->velocity[2] = horizontalSpeed >> 8;
pData->velocity[3] = horizontalSpeed & 0xff;
pData->velocity[4] = speedUncertainty;
}
/**
* A convenience function to set the location coordinates with its timestamp.
* @see testMe()
* @param locationObj location object reference (to be casted!)
* @param latitude the second argument.
* @param longitude the second argument.
* @param altitude the second argument.
* @param timestamp the related timestamp. Seconds since 1970.
*/
void location_setLocationAtTime(lwm2m_object_t* locationObj,
float latitude,
float longitude,
float altitude,
uint64_t timestamp)
{
//-------------------------------------------------------------------- JH --
location_data_t* pData = locationObj->userData;
pData->latitude = latitude;
pData->longitude = longitude;
pData->altitude = altitude;
pData->timestamp = timestamp;
}
/**
* This function creates the LWM2M Location.
* @return gives back allocated LWM2M data object structure pointer. On error,
* NULL value is returned.
*/
lwm2m_object_t * get_object_location(void)
{
//-------------------------------------------------------------------- JH --
lwm2m_object_t * locationObj;
locationObj = (lwm2m_object_t *)lwm2m_malloc(sizeof(lwm2m_object_t));
if (NULL != locationObj)
{
memset(locationObj, 0, sizeof(lwm2m_object_t));
// It assigns its unique ID
// The 6 is the standard ID for the optional object "Location".
locationObj->objID = LWM2M_LOCATION_OBJECT_ID;
// and its unique instance
locationObj->instanceList = (lwm2m_list_t *)lwm2m_malloc(sizeof(lwm2m_list_t));
if (NULL != locationObj->instanceList)
{
memset(locationObj->instanceList, 0, sizeof(lwm2m_list_t));
}
else
{
lwm2m_free(locationObj);
return NULL;
}
// And the private function that will access the object.
// Those function will be called when a read query is made by the server.
// In fact the library don't need to know the resources of the object, only the server does.
//
locationObj->readFunc = prv_location_read;
locationObj->userData = lwm2m_malloc(sizeof(location_data_t));
// initialize private data structure containing the needed variables
if (NULL != locationObj->userData)
{
location_data_t* data = (location_data_t*)locationObj->userData;
data->latitude = 27.986065; // Mount Everest :)
data->longitude = 86.922623;
data->altitude = 8495.0000;
data->radius = 0.0;
location_setVelocity(locationObj, 0, 0, 255); // 255: speedUncertainty not supported!
data->timestamp = time(NULL);
data->speed = 0.0;
}
else
{
lwm2m_free(locationObj);
locationObj = NULL;
}
}
return locationObj;
}
void free_object_location(lwm2m_object_t * object)
{
lwm2m_list_free(object->instanceList);
lwm2m_free(object->userData);
lwm2m_free(object);
}
#endif //LWM2M_CLIENT_MODE

View File

@ -0,0 +1,33 @@
cmake_minimum_required(VERSION 3.21)
project(lwm2mclient_raw_block1 C)
set(WAKAAMA_MODE_CLIENT ON)
set(WAKAAMA_CLIENT_INITIATED_BOOTSTRAP ON)
set(WAKAAMA_DATA_SENML_JSON ON)
set(WAKAAMA_DATA_SENML_CBOR OFF)
set(WAKAAMA_COAP_RAW_BLOCK1_REQUESTS ON)
set(WAKAAMA_CLI ON)
set(WAKAAMA_TRANSPORT POSIX_UDP)
set(WAKAAMA_PLATFORM POSIX)
add_subdirectory(../../../ wakaama_lib)
add_executable(lwm2mclient_raw_block1)
target_sources(
lwm2mclient_raw_block1
PRIVATE ../common/lwm2mclient.c
../common/lwm2mclient.h
../common/object_access_control.c
../common/object_connectivity_moni.c
../common/object_connectivity_stat.c
../common/object_device.c
../common/object_firmware.c
../common/object_location.c
../common/object_security.c
../common/object_server.c
../common/object_test.c
../common/system_api.c
)
target_link_libraries(lwm2mclient_raw_block1 PRIVATE wakaama_static)

View File

@ -0,0 +1,32 @@
cmake_minimum_required(VERSION 3.21)
project(lwm2mclient_tinydtls C)
set(WAKAAMA_MODE_CLIENT ON)
set(WAKAAMA_CLIENT_INITIATED_BOOTSTRAP ON)
set(WAKAAMA_DATA_SENML_JSON ON)
set(WAKAAMA_DATA_SENML_CBOR OFF)
set(WAKAAMA_CLI ON)
set(WAKAAMA_TRANSPORT TINYDTLS)
set(WAKAAMA_PLATFORM POSIX)
add_subdirectory(../../../ wakaama_lib)
add_executable(lwm2mclient_tinydtls)
target_sources(
lwm2mclient_tinydtls
PRIVATE ../common/lwm2mclient.c
../common/lwm2mclient.h
../common/object_access_control.c
../common/object_connectivity_moni.c
../common/object_connectivity_stat.c
../common/object_device.c
../common/object_firmware.c
../common/object_location.c
../common/object_security.c
../common/object_server.c
../common/object_test.c
../common/system_api.c
)
target_link_libraries(lwm2mclient_tinydtls PRIVATE wakaama_static)

View File

@ -0,0 +1,32 @@
cmake_minimum_required(VERSION 3.21)
project(lwm2mclient C)
set(WAKAAMA_MODE_CLIENT ON)
set(WAKAAMA_CLIENT_INITIATED_BOOTSTRAP ON)
set(WAKAAMA_DATA_SENML_JSON ON)
set(WAKAAMA_DATA_SENML_CBOR OFF)
set(WAKAAMA_CLI ON)
set(WAKAAMA_TRANSPORT POSIX_UDP)
set(WAKAAMA_PLATFORM POSIX)
add_subdirectory(../../../ wakaama_lib)
add_executable(lwm2mclient)
target_sources(
lwm2mclient
PRIVATE ../common/lwm2mclient.c
../common/lwm2mclient.h
../common/object_access_control.c
../common/object_connectivity_moni.c
../common/object_connectivity_stat.c
../common/object_device.c
../common/object_firmware.c
../common/object_location.c
../common/object_security.c
../common/object_server.c
../common/object_test.c
../common/system_api.c
)
target_link_libraries(lwm2mclient PRIVATE wakaama_static)

View File

@ -88,7 +88,7 @@ class Lwm2mClient(HelperBase):
def __init__(self, arguments="", timeout=3, encoding="utf8"):
self.pexpectobj = pexpect.spawn(REPO_BASE_PATH +
"/build-presets/client/examples/client/lwm2mclient "
"/build-wakaama-client/udp/lwm2mclient "
+ arguments,
encoding=encoding,
timeout=timeout)