mirror of
https://github.com/eclipse/wakaama.git
synced 2025-05-08 23:31:37 +08:00
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:
parent
1f57c8ea54
commit
9ee63a22ca
2
.github/workflows/build.yaml
vendored
2
.github/workflows/build.yaml
vendored
@ -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
|
||||
|
2
.github/workflows/build_and_test.yaml
vendored
2
.github/workflows/build_and_test.yaml
vendored
@ -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 \
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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()
|
File diff suppressed because it is too large
Load Diff
111
examples/client/common/lwm2mclient.h
Normal file
111
examples/client/common/lwm2mclient.h
Normal 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_ */
|
@ -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);
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
@ -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;
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
313
examples/client/common/object_location.c
Normal file
313
examples/client/common/object_location.c
Normal 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
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
@ -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); }
|
||||
|
@ -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_ */
|
@ -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
|
33
examples/client/raw_block1/CMakeLists.txt
Normal file
33
examples/client/raw_block1/CMakeLists.txt
Normal 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)
|
32
examples/client/tinydtls/CMakeLists.txt
Normal file
32
examples/client/tinydtls/CMakeLists.txt
Normal 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)
|
32
examples/client/udp/CMakeLists.txt
Normal file
32
examples/client/udp/CMakeLists.txt
Normal 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)
|
@ -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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user