12 #define IS_PTR_VALID_AND_RES_EXISTS(resPtr) (resPtr && resPtr->instCount())
13 #define IS_RES_PTR_VALID(resPtr) (resPtr != NULL)
18 if (_context.state <= STATE_BOOTSTRAPPING)
return;
21 lwm2m_resource_value_changed(&_context, &uri);
25 std::vector<Resource *> list;
27 if (res.instCount()) list.push_back(&res);
33 std::vector<Resource *> list;
35 if (res.instCount() && filter.
isCompatible(res.getOperation())) list.push_back(&res);
41 std::vector<Resource *> list;
42 for (
auto &res :
resources()) list.push_back(&res);
62 Instance* Instance::getSecurityInst(lwm2m_server_t *server) {
63 if (!server)
return NULL;
67 bool Instance::resourceToLwm2mData(Resource &res,
ID_T instanceId, lwm2m_data_t &data) {
68 if (!res.isExist(instanceId)) {
73 switch(res.getTypeId()) {
76 lwm2m_data_encode_bool(value, &data);
81 lwm2m_data_encode_time(value, &data);
86 lwm2m_data_encode_int(value, &data);
91 lwm2m_data_encode_uint(value, &data);
96 lwm2m_data_encode_float(value, &data);
100 OBJ_LINK_T value = res.get<OBJ_LINK_T>(instanceId);
101 lwm2m_data_encode_objlink(value.objId, value.objInstId, &data);
106 lwm2m_data_encode_opaque(value.data(), value.size(), &data);
111 lwm2m_data_encode_string(value.c_str(), &data);
116 lwm2m_data_encode_corelink(value.c_str(), &data);
119 default:
return false;
125 bool Instance::lwm2mDataToResource(
const lwm2m_data_t &data, Resource &res,
ID_T instanceId) {
126 switch (res.getTypeId()) {
129 if (!lwm2m_data_decode_bool(&data, &value) || !res.set(value, instanceId))
return false;
134 if (!lwm2m_data_decode_time(&data, &value) || !res.set(value, instanceId))
return false;
139 if (!lwm2m_data_decode_int(&data, &value) || !res.set(value, instanceId))
return false;
144 if (!lwm2m_data_decode_uint(&data, &value) || !res.set(value, instanceId))
return false;
149 if (!lwm2m_data_decode_float(&data, &value) || !res.set(value, instanceId))
return false;
154 if (!lwm2m_data_decode_objlink(&data, &value.objId, &value.objInstId) || !res.set(std::move(value), instanceId))
return false;
158 if (data.type != LWM2M_TYPE_OPAQUE && data.type != LWM2M_TYPE_STRING)
return false;
160 uint8_t *buffer = NULL;
161 if (!lwm2m_data_decode_opaque(&data, &buffer, &len) || !res.set(
OPAQUE_T(buffer, buffer+len), instanceId)) {
169 if (data.type != LWM2M_TYPE_OPAQUE && data.type != LWM2M_TYPE_STRING)
return false;
170 size_t len = data.value.asBuffer.length;
171 uint8_t *buffer = data.value.asBuffer.buffer;
172 if (!res.set(
STRING_T(buffer, buffer+len), instanceId))
return false;
176 if (data.type != LWM2M_TYPE_OPAQUE && data.type != LWM2M_TYPE_STRING && data.type != LWM2M_TYPE_CORE_LINK)
return false;
177 size_t len = data.value.asBuffer.length;
178 uint8_t *buffer = data.value.asBuffer.buffer;
179 if (!res.set(
CORE_LINK_T(buffer, buffer + len), instanceId))
return false;
182 default:
return false;
188 Resource* Instance::getValidatedResForWrite(
const lwm2m_data_t &data, lwm2m_write_type_t writeType, uint8_t &errCode) {
192 errCode = COAP_404_NOT_FOUND;
196 if ((data.type == LWM2M_TYPE_MULTIPLE_RESOURCE && res->isSingle()) ||
197 (data.type != LWM2M_TYPE_MULTIPLE_RESOURCE && res->isMultiple())) {
199 errCode = COAP_400_BAD_REQUEST;
205 uint8_t Instance::resourceWrite(lwm2m_server_t *server, Resource &res,
const lwm2m_data_t &data, lwm2m_write_type_t writeType) {
206 bool isReplace = (writeType == LWM2M_WRITE_REPLACE_INSTANCE || writeType == LWM2M_WRITE_REPLACE_RESOURCES);
210 if (data.type == LWM2M_TYPE_MULTIPLE_RESOURCE && data.value.asChildren.count == 0) {
212 return COAP_400_BAD_REQUEST;
218 resBackup = std::move(res);
222 const lwm2m_data_t *data_ptr = &data;
223 if (data.type == LWM2M_TYPE_MULTIPLE_RESOURCE) {
224 count = data.value.asChildren.count;
225 data_ptr = data.value.asChildren.array;
229 for (
size_t i = 0; i < count; i++) {
232 if (!lwm2mDataToResource(data_ptr[i], res, resInstId)) {
235 if (isReplace) res = std::move(resBackup);
236 return COAP_400_BAD_REQUEST;
244 return COAP_NO_ERROR;
247 Resource* Instance::getValidatedResForRead(
const lwm2m_data_t &data, uint8_t &errCode) {
251 errCode = COAP_404_NOT_FOUND;
255 if (!res->getOperation().isRead()) {
257 errCode = COAP_400_BAD_REQUEST;
261 if (data.type == LWM2M_TYPE_MULTIPLE_RESOURCE && res->isSingle()) {
263 errCode = COAP_400_BAD_REQUEST;
267 if (data.type == LWM2M_TYPE_MULTIPLE_RESOURCE) {
268 for (
size_t i = 0; i < data.value.asChildren.count; i++) {
269 if (!res->isExist(data.value.asChildren.array[i].id)) {
271 errCode = COAP_404_NOT_FOUND;
280 uint8_t Instance::resourceRead(lwm2m_server_t *server, lwm2m_data_t &data, Resource &res) {
283 if (res.isMultiple() && data.type != LWM2M_TYPE_MULTIPLE_RESOURCE) {
284 lwm2m_data_t *subData = lwm2m_data_new(res.instCount());
285 lwm2m_data_t *dataCnt = subData;
286 for (
auto id : res.instIds()) (dataCnt++)->
id =
id;
287 lwm2m_data_encode_instances(subData, res.instCount(), &data);
291 lwm2m_data_t *data_ptr = &data;
292 if (data.type == LWM2M_TYPE_MULTIPLE_RESOURCE) {
293 count = data.value.asChildren.count;
294 data_ptr = data.value.asChildren.array;
298 for (
size_t j = 0; j < count; j++) {
301 if (!resourceToLwm2mData(res, resInstId, data_ptr[j])) {
303 return COAP_400_BAD_REQUEST;
307 return COAP_NO_ERROR;
310 Resource* Instance::getValidatedResForExecute(
ID_T resId, uint8_t &errCode) {
314 errCode = COAP_404_NOT_FOUND;
318 if (!res->getOperation().isExecute()) {
320 errCode = COAP_405_METHOD_NOT_ALLOWED;
326 uint8_t Instance::createEmptyLwm2mDataArray(std::vector<Resource*> resources, lwm2m_data_t **dataArray,
int *numData) {
327 lwm2m_data_t *arr = lwm2m_data_new(
resources.size());
328 if (!arr)
return COAP_500_INTERNAL_SERVER_ERROR;
330 lwm2m_data_t *arrCnt = arr;
335 return COAP_NO_ERROR;
338 bool Instance::isAllMandatoryResourcesPresent(
int numData, lwm2m_data_t *data){
341 std::vector<Resource *> mandatoryResources;
343 if (!res.isMandatory() || !res.getOperation().isWrite())
continue;
345 for (
int i = 0; i < numData; i++) {
346 if (data[i].
id == res.getId()) {
359 uint8_t Instance::replaceInstance(lwm2m_server_t *server,
int numData, lwm2m_data_t *dataArray) {
364 std::vector<Resource> replaceInstResources;
367 if (_context.state > STATE_BOOTSTRAPPING && !isAllMandatoryResourcesPresent(numData, dataArray))
return COAP_400_BAD_REQUEST;
369 for (
int i = 0; i < numData; i++) {
370 uint8_t errCode = COAP_NO_ERROR;
371 Resource *res = getValidatedResForWrite(dataArray[i], LWM2M_WRITE_REPLACE_INSTANCE, errCode);
375 if (errCode != COAP_404_NOT_FOUND) {
381 replaceInstResources.push_back(*res);
382 errCode = resourceWrite(server, replaceInstResources.back(), dataArray[i], LWM2M_WRITE_REPLACE_INSTANCE);
383 if (errCode != COAP_NO_ERROR) {
390 for (
auto &res : replaceInstResources) {
391 *
resource(res.getId()) = std::move(res);
395 return COAP_NO_ERROR;
398 uint8_t Instance::replaceResource(lwm2m_server_t *server,
int numData, lwm2m_data_t *dataArray, lwm2m_write_type_t writeType) {
399 for (
int i = 0; i < numData; i++) {
400 uint8_t errCode = COAP_NO_ERROR;
401 Resource *res = getValidatedResForWrite(dataArray[i], writeType, errCode);
407 if (server == NULL || errCode != COAP_404_NOT_FOUND) {
413 errCode = resourceWrite(server, *res, dataArray[i], writeType);
414 if (errCode != COAP_NO_ERROR) {
420 return COAP_NO_ERROR;
425 if (numData == NULL || dataArray == NULL)
return COAP_500_INTERNAL_SERVER_ERROR;
427 bool readAllAvailableRes = *numData == 0;
429 if (readAllAvailableRes) {
431 uint8_t errCode = createEmptyLwm2mDataArray(readResources, dataArray, numData);
432 if (errCode != COAP_NO_ERROR) {
438 uint8_t result = COAP_404_NOT_FOUND;
439 for (
int i = 0; i < *numData; i++) {
440 uint8_t errCode = COAP_NO_ERROR;
441 lwm2m_data_t *data = (*dataArray) + i;
442 Resource *res = getValidatedResForRead(*data, errCode);
448 if (server == NULL || errCode != COAP_404_NOT_FOUND) {
455 errCode = resourceRead(server, *data, *res);
456 if (errCode != COAP_NO_ERROR) {
461 result = COAP_205_CONTENT;
469 if (!numData)
return COAP_204_CHANGED;
470 if (dataArray == NULL)
return COAP_500_INTERNAL_SERVER_ERROR;
475 for (
int i = 0; i < numData; i++) {
476 auto res =
resource(dataArray[i].
id);
478 if (!res->getOperation().isWrite() && (_context.state > STATE_BOOTSTRAPPING) && server != NULL) {
480 return COAP_405_METHOD_NOT_ALLOWED;
484 uint8_t errCode = COAP_NO_ERROR;
485 if (writeType == LWM2M_WRITE_REPLACE_INSTANCE) errCode = replaceInstance(server, numData, dataArray);
486 else errCode = replaceResource(server, numData, dataArray, writeType);
488 return (errCode == COAP_NO_ERROR)? COAP_204_CHANGED : errCode;
493 uint8_t errCode = COAP_NO_ERROR;
494 Resource *res = getValidatedResForExecute(resId, errCode);
503 return COAP_404_NOT_FOUND;
510 return execute(*
this, resId,
OPAQUE_T(buffer, buffer + length))? COAP_204_CHANGED : COAP_405_METHOD_NOT_ALLOWED;
514 if (numData == NULL || dataArray == NULL)
return COAP_500_INTERNAL_SERVER_ERROR;
516 bool discoverAllAvailableRes = *numData == 0;
518 if (discoverAllAvailableRes) {
520 uint8_t errCode = createEmptyLwm2mDataArray(
resources, dataArray, numData);
521 if (errCode != COAP_NO_ERROR) {
527 for (
int i = 0; i < *numData; i++) {
528 lwm2m_data_t *data = (*dataArray) + i;
532 return COAP_404_NOT_FOUND;
537 if (res->isMultiple() && res->instCount() && data->type != LWM2M_TYPE_MULTIPLE_RESOURCE) {
538 lwm2m_data_t *subData = lwm2m_data_new(res->instCount());
539 lwm2m_data_t *dataCnt = subData;
540 for (
auto id : res->instIds()) {
541 (dataCnt++)->
id =
id;
544 lwm2m_data_encode_instances(subData, res->instCount(), data);
549 return COAP_205_CONTENT;
#define IS_PTR_VALID_AND_RES_EXISTS(resPtr)
#define IS_RES_PTR_VALID(resPtr)
#define WPP_LOGE(TAG, FMT,...)
#define WPP_LOGW(TAG, FMT,...)
#define WPP_LOGD(TAG, FMT,...)
#define SINGLE_INSTANCE_ID
Instance is interface class that implements manipulation with derived class resources....
void resourceOperationNotifier(ItemOp::TYPE type, ID_T resId, ID_T resInstId) override
Handle information about resource operation (WRITE, DELETE). Called by ResourceContainer after resour...
uint8_t readAsServer(lwm2m_server_t *server, int *numDataP, lwm2m_data_t **dataArray)
This methods is called by the core when the server wants to read, write, discover,...
OBJ_ID getObjectID() const
virtual void serverOperationNotifier(Instance *securityInst, ItemOp::TYPE type, const ResLink &resLink)=0
This method must be implemented by the derived class, and handle information about resource operation...
uint8_t discoverAsServer(lwm2m_server_t *server, int *numDataP, lwm2m_data_t **dataArray)
virtual void userOperationNotifier(ItemOp::TYPE type, const ResLink &resLink)=0
This method must be implemented by the derived class, and handle information about resource operation...
std::vector< Resource * > getInstantiatedResList()
This method return list with resources that has been instantiated. If resources does not exist then r...
WppRegistry & getRegistry()
Helpfull methods to get registry instances.
WppClient & getClient()
Helpfull methods to get client instances.
uint8_t executeAsServer(lwm2m_server_t *server, ID_T resId, uint8_t *buffer, int length)
lwm2m_context_t & getContext()
Return context that can be used by derived class.
void notifyResChanged(ID_T resId, ID_T resInstId=ID_T_MAX_VAL)
Notify server about resource value change.
ID_T getInstanceID() const
std::vector< Resource * > getResList()
This method return list with all resources that has been defined. If resources does not exist then re...
uint8_t writeAsServer(lwm2m_server_t *server, int numData, lwm2m_data_t *dataArray, lwm2m_write_type_t writeType)
Instance * instance(ID_T instanceID=ID_T_MAX_VAL)
Gets an instance of the object.
Resource * resource(ID_T resId)
This method return resource ptr if it exists. If resources does not exist then return NULL.
std::vector< Resource > & resources()
This method return list with all resources that has been defined.
The Resource class in the wpp namespace is a comprehensive and flexible class designed to handle diff...
const T & get(ID_T resInstId=SINGLE_INSTANCE_ID)
Represents a client interface for Wpp library.
The WppRegistry class represents a registry for managing LWM2M objects.
Object * object(OBJ_ID objId)
Retrieves a pointer to the Object with the given objId.
The WppConnection class represents a connection interface for the Wpp library.
std::string CORE_LINK_T
CoreLink - </3/0> or </1/0/>;ssid=101 or </5>,</4>,</55>;ver=1.9,</55/0>. Represent as string in lwm2...
bool BOOL_T
Wpp data types bindings.
std::function< bool(Instance &, ID_T, const OPAQUE_T &)> EXECUTE_T
std::vector< uint8_t > OPAQUE_T
Opaque - represent buffer or string as lwm2m_data_t.value.asBuffer.
The ItemOp struct represents the operations that can be performed on a instance/resource.
bool isCompatible(const ItemOp &operation) const
Checks if the ItemOp object is compatible with another ItemOp object.
TYPE
Enum representing the different types of operations.