12using namespace dawn::wakaama_internal;
16constexpr uint32_t SERVER_DISABLE_TIMEOUT_DEFAULT = 86400;
17constexpr uint32_t SERVER_COMMUNICATION_RETRY_TIMER_DEFAULT = 60;
18constexpr uint32_t SERVER_COMMUNICATION_SEQUENCE_DELAY_TIMER_DEFAULT = 86400;
19constexpr uint8_t SERVER_COMMUNICATION_RETRY_COUNT_DEFAULT = 5;
20constexpr uint8_t SERVER_COMMUNICATION_SEQUENCE_RETRY_COUNT_DEFAULT = 1;
22constexpr uint16_t SECURITY_RESOURCE_IDS[] = {LWM2M_SECURITY_URI_ID,
23 LWM2M_SECURITY_BOOTSTRAP_ID,
24 LWM2M_SECURITY_SECURITY_ID,
25 LWM2M_SECURITY_PUBLIC_KEY_ID,
26 LWM2M_SECURITY_SERVER_PUBLIC_KEY_ID,
27 LWM2M_SECURITY_SECRET_KEY_ID,
28 LWM2M_SECURITY_SHORT_SERVER_ID,
29 LWM2M_SECURITY_HOLD_OFF_ID,
30 LWM2M_SECURITY_BOOTSTRAP_TIMEOUT_ID};
32constexpr uint16_t SERVER_READ_RESOURCE_IDS[] = {LWM2M_SERVER_SHORT_ID_ID,
33 LWM2M_SERVER_LIFETIME_ID,
34 LWM2M_SERVER_MIN_PERIOD_ID,
35 LWM2M_SERVER_MAX_PERIOD_ID,
36 LWM2M_SERVER_TIMEOUT_ID,
37 LWM2M_SERVER_STORING_ID,
38 LWM2M_SERVER_BINDING_ID,
39 LWM2M_SERVER_REG_ORDER_ID,
40 LWM2M_SERVER_INITIAL_REG_DELAY_ID,
41 LWM2M_SERVER_REG_FAIL_BLOCK_ID,
42 LWM2M_SERVER_REG_FAIL_BOOTSTRAP_ID,
43 LWM2M_SERVER_COMM_RETRY_COUNT_ID,
44 LWM2M_SERVER_COMM_RETRY_TIMER_ID,
45 LWM2M_SERVER_SEQ_DELAY_TIMER_ID,
46 LWM2M_SERVER_SEQ_RETRY_COUNT_ID,
47 LWM2M_SERVER_PREFERRED_TRANSPORT_ID,
48 LWM2M_SERVER_MUTE_SEND_ID};
50constexpr uint16_t SERVER_DISCOVER_RESOURCE_IDS[] = {LWM2M_SERVER_SHORT_ID_ID,
51 LWM2M_SERVER_LIFETIME_ID,
52 LWM2M_SERVER_MIN_PERIOD_ID,
53 LWM2M_SERVER_MAX_PERIOD_ID,
54 LWM2M_SERVER_DISABLE_ID,
55 LWM2M_SERVER_TIMEOUT_ID,
56 LWM2M_SERVER_STORING_ID,
57 LWM2M_SERVER_BINDING_ID,
58 LWM2M_SERVER_UPDATE_ID,
59 LWM2M_SERVER_REG_ORDER_ID,
60 LWM2M_SERVER_INITIAL_REG_DELAY_ID,
61 LWM2M_SERVER_REG_FAIL_BLOCK_ID,
62 LWM2M_SERVER_REG_FAIL_BOOTSTRAP_ID,
63 LWM2M_SERVER_COMM_RETRY_COUNT_ID,
64 LWM2M_SERVER_COMM_RETRY_TIMER_ID,
65 LWM2M_SERVER_SEQ_DELAY_TIMER_ID,
66 LWM2M_SERVER_SEQ_RETRY_COUNT_ID,
67 LWM2M_SERVER_PREFERRED_TRANSPORT_ID,
68 LWM2M_SERVER_MUTE_SEND_ID};
70constexpr uint16_t DEVICE_RESOURCE_IDS[] = {
71 CProtoWakaama::WAKAAMA_DEVICE_RESOURCE_MANUFACTURER,
72 CProtoWakaama::WAKAAMA_DEVICE_RESOURCE_MODEL_NUMBER,
73 CProtoWakaama::WAKAAMA_DEVICE_RESOURCE_SERIAL_NUMBER,
74 CProtoWakaama::WAKAAMA_DEVICE_RESOURCE_FIRMWARE_VERSION,
75 CProtoWakaama::WAKAAMA_DEVICE_RESOURCE_ERROR_CODE,
76 CProtoWakaama::WAKAAMA_DEVICE_RESOURCE_CURRENT_TIME,
77 CProtoWakaama::WAKAAMA_DEVICE_RESOURCE_BINDING_MODES,
80bool encodeString(
const char *str, lwm2m_data_t *data)
82 lwm2m_data_encode_string(str ==
nullptr ?
"" : str, data);
83 return data->type == LWM2M_TYPE_STRING;
86bool encodeOpaque(
const uint8_t *buffer,
size_t len, lwm2m_data_t *data)
88 lwm2m_data_encode_opaque(buffer, len, data);
89 return data->type == LWM2M_TYPE_OPAQUE;
92#ifdef CONFIG_WAKAAMA_BOOTSTRAP
93bool bufferValue(
const lwm2m_data_t &data,
const uint8_t **buffer,
size_t *length)
95 if (buffer ==
nullptr || length ==
nullptr)
102 case LWM2M_TYPE_STRING:
103 case LWM2M_TYPE_OPAQUE:
104 case LWM2M_TYPE_CORE_LINK:
111 *buffer = data.value.asBuffer.buffer;
112 *length = data.value.asBuffer.length;
113 return *length == 0 || *buffer !=
nullptr;
117bool allocateResourceList(
const uint16_t *ids,
int count,
int *numData, lwm2m_data_t **dataArray)
119 *dataArray = lwm2m_data_new(count);
120 if (*dataArray ==
nullptr)
126 for (
int i = 0; i < count; i++)
128 (*dataArray)[i].id = ids[i];
135bool decodeUint(lwm2m_data_t *data, T *value)
139 if (lwm2m_data_decode_int(data, &intValue) != 1 || intValue < 0 ||
140 static_cast<uint64_t
>(intValue) >
static_cast<uint64_t
>(std::numeric_limits<T>::max()))
145 *value =
static_cast<T
>(intValue);
149bool assignShortString(
char *dest,
size_t capacity,
const lwm2m_data_t &data)
151 if ((data.type != LWM2M_TYPE_STRING && data.type != LWM2M_TYPE_OPAQUE) ||
152 data.value.asBuffer.length == 0 || data.value.asBuffer.length >= capacity ||
153 data.value.asBuffer.buffer ==
nullptr)
158 std::memcpy(dest, data.value.asBuffer.buffer, data.value.asBuffer.length);
159 dest[data.value.asBuffer.length] =
'\0';
165 inst.binding[0] =
'U';
166 inst.binding[1] =
'\0';
167 inst.preferredTransport[0] =
'U';
168 inst.preferredTransport[1] =
'\0';
169 inst.disableTimeout = SERVER_DISABLE_TIMEOUT_DEFAULT;
170 inst.bootstrapOnRegistrationFailure =
true;
171 inst.communicationRetryCount = SERVER_COMMUNICATION_RETRY_COUNT_DEFAULT;
172 inst.communicationRetryTimer = SERVER_COMMUNICATION_RETRY_TIMER_DEFAULT;
173 inst.communicationSequenceDelayTimer = SERVER_COMMUNICATION_SEQUENCE_DELAY_TIMER_DEFAULT;
174 inst.communicationSequenceRetryCount = SERVER_COMMUNICATION_SEQUENCE_RETRY_COUNT_DEFAULT;
180 if (pools ==
nullptr)
185 for (
size_t i = 0; i < pools->securityCapacity; i++)
189 if (!inst->allocated)
191 std::memset(inst, 0,
sizeof(*inst));
192 inst->allocated =
true;
193 inst->uri = inst->uriBuffer;
205 std::memset(inst, 0,
sizeof(*inst));
211 if (pools ==
nullptr)
216 for (
size_t i = 0; i < pools->serverCapacity; i++)
220 if (!inst->allocated)
222 std::memset(inst, 0,
sizeof(*inst));
223 inst->allocated =
true;
224 initServerDefaults(*inst);
236 std::memset(inst, 0,
sizeof(*inst));
244 if (len > 0 && src ==
nullptr)
249 while (len > 0 && src[len - 1] ==
'\0')
254 if (len >=
sizeof(inst.uriBuffer))
261 std::memcpy(inst.uriBuffer, src, len);
264 inst.uriBuffer[len] =
'\0';
265 inst.uri = inst.uriBuffer;
269bool dawn::wakaama_internal::assignSecurityBuffer(
const uint8_t *src,
281 if (len > 0 && src ==
nullptr)
288 std::memcpy(buffer, src, len);
300uint8_t dawn::wakaama_internal::securityRead(lwm2m_context_t *ctx,
303 lwm2m_data_t **dataArray,
304 lwm2m_object_t *
object)
310 inst =
reinterpret_cast<security_instance_s *
>(lwm2m_list_find(object->instanceList, instanceId));
313 return COAP_404_NOT_FOUND;
318 if (!allocateResourceList(
319 SECURITY_RESOURCE_IDS,
320 static_cast<int>(
sizeof(SECURITY_RESOURCE_IDS) /
sizeof(SECURITY_RESOURCE_IDS[0])),
324 return COAP_500_INTERNAL_SERVER_ERROR;
328 for (
int i = 0; i < *numData; i++)
330 switch ((*dataArray)[i].id)
332 case LWM2M_SECURITY_URI_ID:
333 if (!encodeString(inst->uri, &(*dataArray)[i]))
335 return COAP_500_INTERNAL_SERVER_ERROR;
339 case LWM2M_SECURITY_BOOTSTRAP_ID:
340 lwm2m_data_encode_bool(inst->bootstrap, &(*dataArray)[i]);
343 case LWM2M_SECURITY_SECURITY_ID:
344 lwm2m_data_encode_int(inst->securityMode, &(*dataArray)[i]);
347 case LWM2M_SECURITY_PUBLIC_KEY_ID:
348 if (!encodeOpaque(inst->publicIdentity, inst->publicIdentityLen, &(*dataArray)[i]))
350 return COAP_500_INTERNAL_SERVER_ERROR;
354 case LWM2M_SECURITY_SERVER_PUBLIC_KEY_ID:
355 if (!encodeOpaque(
nullptr, 0, &(*dataArray)[i]))
357 return COAP_500_INTERNAL_SERVER_ERROR;
361 case LWM2M_SECURITY_SECRET_KEY_ID:
362 if (!encodeOpaque(inst->secretKey, inst->secretKeyLen, &(*dataArray)[i]))
364 return COAP_500_INTERNAL_SERVER_ERROR;
368 case LWM2M_SECURITY_SHORT_SERVER_ID:
369 lwm2m_data_encode_int(inst->shortServerId, &(*dataArray)[i]);
372 case LWM2M_SECURITY_HOLD_OFF_ID:
373 lwm2m_data_encode_int(inst->holdoff, &(*dataArray)[i]);
376 case LWM2M_SECURITY_BOOTSTRAP_TIMEOUT_ID:
377 lwm2m_data_encode_int(inst->bootstrapTimeout, &(*dataArray)[i]);
381 return COAP_404_NOT_FOUND;
385 return COAP_205_CONTENT;
388uint8_t dawn::wakaama_internal::securityDiscover(lwm2m_context_t *ctx,
391 lwm2m_data_t **dataArray,
392 lwm2m_object_t *
object)
398 inst =
reinterpret_cast<security_instance_s *
>(lwm2m_list_find(object->instanceList, instanceId));
401 return COAP_404_NOT_FOUND;
406 if (!allocateResourceList(
407 SECURITY_RESOURCE_IDS,
408 static_cast<int>(
sizeof(SECURITY_RESOURCE_IDS) /
sizeof(SECURITY_RESOURCE_IDS[0])),
412 return COAP_500_INTERNAL_SERVER_ERROR;
416 return COAP_205_CONTENT;
419#ifdef CONFIG_WAKAAMA_BOOTSTRAP
420uint8_t dawn::wakaama_internal::securityWrite(lwm2m_context_t *ctx,
423 lwm2m_data_t *dataArray,
424 lwm2m_object_t *
object,
425 lwm2m_write_type_t writeType)
432 inst =
reinterpret_cast<security_instance_s *
>(lwm2m_list_find(object->instanceList, instanceId));
435 return COAP_404_NOT_FOUND;
438 for (
int i = 0; i < numData; i++)
443 if (dataArray[i].type == LWM2M_TYPE_MULTIPLE_RESOURCE)
445 return COAP_404_NOT_FOUND;
448 switch (dataArray[i].
id)
450 case LWM2M_SECURITY_URI_ID:
452 const uint8_t *buffer;
455 if (!bufferValue(dataArray[i], &buffer, &length))
457 return COAP_400_BAD_REQUEST;
460 if (!assignSecurityString(*inst, buffer, length))
462 return COAP_500_INTERNAL_SERVER_ERROR;
467 case LWM2M_SECURITY_BOOTSTRAP_ID:
468 if (lwm2m_data_decode_bool(dataArray + i, &boolValue) != 1)
470 return COAP_400_BAD_REQUEST;
473 inst->bootstrap = boolValue;
476 case LWM2M_SECURITY_SECURITY_ID:
477 if (lwm2m_data_decode_int(dataArray + i, &intValue) != 1 || intValue < 0 ||
480 return COAP_400_BAD_REQUEST;
483 inst->securityMode =
static_cast<uint8_t
>(intValue);
486 case LWM2M_SECURITY_PUBLIC_KEY_ID:
488 const uint8_t *buffer;
491 if (!bufferValue(dataArray[i], &buffer, &length))
493 return COAP_400_BAD_REQUEST;
496 if (!assignSecurityBuffer(buffer,
498 inst->publicIdentityBuffer,
499 sizeof(inst->publicIdentityBuffer),
500 &inst->publicIdentity,
501 &inst->publicIdentityLen))
503 return COAP_500_INTERNAL_SERVER_ERROR;
508 case LWM2M_SECURITY_SECRET_KEY_ID:
510 const uint8_t *buffer;
513 if (!bufferValue(dataArray[i], &buffer, &length))
515 return COAP_400_BAD_REQUEST;
518 if (!assignSecurityBuffer(buffer,
520 inst->secretKeyBuffer,
521 sizeof(inst->secretKeyBuffer),
523 &inst->secretKeyLen))
525 return COAP_500_INTERNAL_SERVER_ERROR;
530 case LWM2M_SECURITY_SERVER_PUBLIC_KEY_ID:
533 case LWM2M_SECURITY_SHORT_SERVER_ID:
534 if (lwm2m_data_decode_int(dataArray + i, &intValue) != 1 || intValue < 0 ||
535 intValue > UINT16_MAX)
537 return COAP_400_BAD_REQUEST;
540 inst->shortServerId =
static_cast<uint16_t
>(intValue);
543 case LWM2M_SECURITY_HOLD_OFF_ID:
544 if (lwm2m_data_decode_int(dataArray + i, &intValue) != 1 || intValue < 0 ||
545 intValue > UINT32_MAX)
547 return COAP_400_BAD_REQUEST;
550 inst->holdoff =
static_cast<uint32_t
>(intValue);
553 case LWM2M_SECURITY_BOOTSTRAP_TIMEOUT_ID:
554 if (lwm2m_data_decode_int(dataArray + i, &intValue) != 1 || intValue < 0 ||
555 intValue > UINT32_MAX)
557 return COAP_400_BAD_REQUEST;
560 inst->bootstrapTimeout =
static_cast<uint32_t
>(intValue);
564 return COAP_400_BAD_REQUEST;
568 return COAP_204_CHANGED;
571uint8_t dawn::wakaama_internal::securityCreate(lwm2m_context_t *ctx,
574 lwm2m_data_t *dataArray,
575 lwm2m_object_t *
object)
581 if (lwm2m_list_find(object->instanceList, instanceId) !=
nullptr)
583 return COAP_400_BAD_REQUEST;
586 inst = allocateSecurityInstance(pools);
589 return COAP_500_INTERNAL_SERVER_ERROR;
592 inst->id = instanceId;
593 inst->securityMode = LWM2M_SECURITY_MODE_NONE;
595 object->instanceList = LWM2M_LIST_ADD(object->instanceList, inst);
598 securityWrite(ctx, instanceId, numData, dataArray,
object, LWM2M_WRITE_REPLACE_RESOURCES);
599 if (result != COAP_204_CHANGED)
601 lwm2m_list_t *removed;
603 object->instanceList = lwm2m_list_remove(object->instanceList, instanceId, &removed);
605 releaseSecurityInstance(inst);
609 return COAP_201_CREATED;
612uint8_t dawn::wakaama_internal::securityDelete(lwm2m_context_t *ctx,
614 lwm2m_object_t *
object)
616 lwm2m_list_t *removed;
620 object->instanceList = lwm2m_list_remove(object->instanceList, instanceId, &removed);
621 if (removed ==
nullptr)
623 return COAP_404_NOT_FOUND;
627 return COAP_202_DELETED;
631uint8_t dawn::wakaama_internal::serverRead(lwm2m_context_t *ctx,
634 lwm2m_data_t **dataArray,
635 lwm2m_object_t *
object)
641 inst =
reinterpret_cast<server_instance_s *
>(lwm2m_list_find(object->instanceList, instanceId));
644 return COAP_404_NOT_FOUND;
649 if (!allocateResourceList(SERVER_READ_RESOURCE_IDS,
650 static_cast<int>(
sizeof(SERVER_READ_RESOURCE_IDS) /
651 sizeof(SERVER_READ_RESOURCE_IDS[0])),
655 return COAP_500_INTERNAL_SERVER_ERROR;
659 for (
int i = 0; i < *numData; i++)
661 switch ((*dataArray)[i].id)
663 case LWM2M_SERVER_SHORT_ID_ID:
664 lwm2m_data_encode_int(inst->shortServerId, &(*dataArray)[i]);
667 case LWM2M_SERVER_LIFETIME_ID:
668 lwm2m_data_encode_int(inst->lifetime, &(*dataArray)[i]);
671 case LWM2M_SERVER_MIN_PERIOD_ID:
672 lwm2m_data_encode_int(inst->defaultMinPeriod, &(*dataArray)[i]);
675 case LWM2M_SERVER_MAX_PERIOD_ID:
676 lwm2m_data_encode_int(inst->defaultMaxPeriod, &(*dataArray)[i]);
679 case LWM2M_SERVER_DISABLE_ID:
680 case LWM2M_SERVER_UPDATE_ID:
681 case LWM2M_SERVER_TRIGGER_ID:
682 return COAP_405_METHOD_NOT_ALLOWED;
684 case LWM2M_SERVER_TIMEOUT_ID:
685 lwm2m_data_encode_int(inst->disableTimeout, &(*dataArray)[i]);
688 case LWM2M_SERVER_STORING_ID:
689 lwm2m_data_encode_bool(inst->storing, &(*dataArray)[i]);
692 case LWM2M_SERVER_BINDING_ID:
693 if (!encodeString(inst->binding, &(*dataArray)[i]))
695 return COAP_500_INTERNAL_SERVER_ERROR;
699 case LWM2M_SERVER_REG_ORDER_ID:
700 lwm2m_data_encode_int(inst->registrationOrder, &(*dataArray)[i]);
703 case LWM2M_SERVER_INITIAL_REG_DELAY_ID:
704 lwm2m_data_encode_int(inst->initialRegistrationDelay, &(*dataArray)[i]);
707 case LWM2M_SERVER_REG_FAIL_BLOCK_ID:
708 lwm2m_data_encode_bool(inst->registrationFailureBlock, &(*dataArray)[i]);
711 case LWM2M_SERVER_REG_FAIL_BOOTSTRAP_ID:
712 lwm2m_data_encode_bool(inst->bootstrapOnRegistrationFailure, &(*dataArray)[i]);
715 case LWM2M_SERVER_COMM_RETRY_COUNT_ID:
716 lwm2m_data_encode_int(inst->communicationRetryCount, &(*dataArray)[i]);
719 case LWM2M_SERVER_COMM_RETRY_TIMER_ID:
720 lwm2m_data_encode_int(inst->communicationRetryTimer, &(*dataArray)[i]);
723 case LWM2M_SERVER_SEQ_DELAY_TIMER_ID:
724 lwm2m_data_encode_int(inst->communicationSequenceDelayTimer, &(*dataArray)[i]);
727 case LWM2M_SERVER_SEQ_RETRY_COUNT_ID:
728 lwm2m_data_encode_int(inst->communicationSequenceRetryCount, &(*dataArray)[i]);
731 case LWM2M_SERVER_PREFERRED_TRANSPORT_ID:
732 if (!encodeString(inst->preferredTransport, &(*dataArray)[i]))
734 return COAP_500_INTERNAL_SERVER_ERROR;
738 case LWM2M_SERVER_MUTE_SEND_ID:
739 lwm2m_data_encode_bool(inst->muteSend, &(*dataArray)[i]);
743 return COAP_404_NOT_FOUND;
747 return COAP_205_CONTENT;
750uint8_t dawn::wakaama_internal::serverDiscover(lwm2m_context_t *ctx,
753 lwm2m_data_t **dataArray,
754 lwm2m_object_t *
object)
760 inst =
reinterpret_cast<server_instance_s *
>(lwm2m_list_find(object->instanceList, instanceId));
763 return COAP_404_NOT_FOUND;
768 if (!allocateResourceList(SERVER_DISCOVER_RESOURCE_IDS,
769 static_cast<int>(
sizeof(SERVER_DISCOVER_RESOURCE_IDS) /
770 sizeof(SERVER_DISCOVER_RESOURCE_IDS[0])),
774 return COAP_500_INTERNAL_SERVER_ERROR;
778 return COAP_205_CONTENT;
781uint8_t dawn::wakaama_internal::serverExecute(lwm2m_context_t *ctx,
786 lwm2m_object_t *
object)
793 inst =
reinterpret_cast<server_instance_s *
>(lwm2m_list_find(object->instanceList, instanceId));
796 return COAP_404_NOT_FOUND;
801 case LWM2M_SERVER_UPDATE_ID:
802 return lwm2m_update_registration(ctx, inst->shortServerId,
true) == COAP_NO_ERROR
804 : COAP_400_BAD_REQUEST;
806 case LWM2M_SERVER_DISABLE_ID:
807 case LWM2M_SERVER_TRIGGER_ID:
808 return COAP_405_METHOD_NOT_ALLOWED;
811 return COAP_405_METHOD_NOT_ALLOWED;
815uint8_t dawn::wakaama_internal::serverWrite(lwm2m_context_t *ctx,
818 lwm2m_data_t *dataArray,
819 lwm2m_object_t *
object,
820 lwm2m_write_type_t writeType)
827 inst =
reinterpret_cast<server_instance_s *
>(lwm2m_list_find(object->instanceList, instanceId));
830 return COAP_404_NOT_FOUND;
833 for (
int i = 0; i < numData; i++)
837 if (dataArray[i].type == LWM2M_TYPE_MULTIPLE_RESOURCE)
839 return COAP_404_NOT_FOUND;
842 switch (dataArray[i].
id)
844 case LWM2M_SERVER_SHORT_ID_ID:
845 if (!decodeUint(dataArray + i, &inst->shortServerId))
847 return COAP_400_BAD_REQUEST;
851 case LWM2M_SERVER_LIFETIME_ID:
852 if (!decodeUint(dataArray + i, &inst->lifetime))
854 return COAP_400_BAD_REQUEST;
858 case LWM2M_SERVER_MIN_PERIOD_ID:
859 if (!decodeUint(dataArray + i, &inst->defaultMinPeriod))
861 return COAP_400_BAD_REQUEST;
865 case LWM2M_SERVER_MAX_PERIOD_ID:
866 if (!decodeUint(dataArray + i, &inst->defaultMaxPeriod))
868 return COAP_400_BAD_REQUEST;
872 case LWM2M_SERVER_TIMEOUT_ID:
873 if (!decodeUint(dataArray + i, &inst->disableTimeout))
875 return COAP_400_BAD_REQUEST;
879 case LWM2M_SERVER_STORING_ID:
880 if (lwm2m_data_decode_bool(dataArray + i, &boolValue) != 1)
882 return COAP_400_BAD_REQUEST;
885 inst->storing = boolValue;
888 case LWM2M_SERVER_BINDING_ID:
889 if (!assignShortString(inst->binding,
sizeof(inst->binding), dataArray[i]))
891 return COAP_400_BAD_REQUEST;
895 case LWM2M_SERVER_UPDATE_ID:
896 case LWM2M_SERVER_DISABLE_ID:
897 case LWM2M_SERVER_TRIGGER_ID:
898 return COAP_405_METHOD_NOT_ALLOWED;
900 case LWM2M_SERVER_REG_ORDER_ID:
901 if (!decodeUint(dataArray + i, &inst->registrationOrder))
903 return COAP_400_BAD_REQUEST;
907 case LWM2M_SERVER_INITIAL_REG_DELAY_ID:
908 if (!decodeUint(dataArray + i, &inst->initialRegistrationDelay))
910 return COAP_400_BAD_REQUEST;
914 case LWM2M_SERVER_REG_FAIL_BLOCK_ID:
915 if (lwm2m_data_decode_bool(dataArray + i, &boolValue) != 1)
917 return COAP_400_BAD_REQUEST;
920 inst->registrationFailureBlock = boolValue;
923 case LWM2M_SERVER_REG_FAIL_BOOTSTRAP_ID:
924 if (lwm2m_data_decode_bool(dataArray + i, &boolValue) != 1)
926 return COAP_400_BAD_REQUEST;
929 inst->bootstrapOnRegistrationFailure = boolValue;
932 case LWM2M_SERVER_COMM_RETRY_COUNT_ID:
933 if (!decodeUint(dataArray + i, &inst->communicationRetryCount))
935 return COAP_400_BAD_REQUEST;
939 case LWM2M_SERVER_COMM_RETRY_TIMER_ID:
940 if (!decodeUint(dataArray + i, &inst->communicationRetryTimer))
942 return COAP_400_BAD_REQUEST;
946 case LWM2M_SERVER_SEQ_DELAY_TIMER_ID:
947 if (!decodeUint(dataArray + i, &inst->communicationSequenceDelayTimer))
949 return COAP_400_BAD_REQUEST;
953 case LWM2M_SERVER_SEQ_RETRY_COUNT_ID:
954 if (!decodeUint(dataArray + i, &inst->communicationSequenceRetryCount))
956 return COAP_400_BAD_REQUEST;
960 case LWM2M_SERVER_PREFERRED_TRANSPORT_ID:
961 if (!assignShortString(
962 inst->preferredTransport,
sizeof(inst->preferredTransport), dataArray[i]))
964 return COAP_400_BAD_REQUEST;
968 case LWM2M_SERVER_MUTE_SEND_ID:
969 if (lwm2m_data_decode_bool(dataArray + i, &boolValue) != 1)
971 return COAP_400_BAD_REQUEST;
974 inst->muteSend = boolValue;
978 return COAP_400_BAD_REQUEST;
982 return COAP_204_CHANGED;
985#ifdef CONFIG_WAKAAMA_BOOTSTRAP
986uint8_t dawn::wakaama_internal::serverCreate(lwm2m_context_t *ctx,
989 lwm2m_data_t *dataArray,
990 lwm2m_object_t *
object)
996 if (lwm2m_list_find(object->instanceList, instanceId) !=
nullptr)
998 return COAP_400_BAD_REQUEST;
1001 inst = allocateServerInstance(pools);
1002 if (inst ==
nullptr)
1004 return COAP_500_INTERNAL_SERVER_ERROR;
1007 inst->id = instanceId;
1008 inst->binding[0] =
'U';
1009 object->instanceList = LWM2M_LIST_ADD(object->instanceList, inst);
1011 result = serverWrite(ctx, instanceId, numData, dataArray,
object, LWM2M_WRITE_REPLACE_RESOURCES);
1012 if (result != COAP_204_CHANGED)
1014 lwm2m_list_t *removed;
1016 object->instanceList = lwm2m_list_remove(object->instanceList, instanceId, &removed);
1018 releaseServerInstance(inst);
1022 return COAP_201_CREATED;
1025uint8_t dawn::wakaama_internal::serverDelete(lwm2m_context_t *ctx,
1026 uint16_t instanceId,
1027 lwm2m_object_t *
object)
1029 lwm2m_list_t *removed;
1033 object->instanceList = lwm2m_list_remove(object->instanceList, instanceId, &removed);
1034 if (removed ==
nullptr)
1036 return COAP_404_NOT_FOUND;
1040 return COAP_202_DELETED;
1048constexpr uint16_t DEVICE_BATTERY_RESOURCE_IDS[] = {
1049 CProtoWakaama::WAKAAMA_DEVICE_RESOURCE_POWER_SOURCE_VOLTAGE,
1050 CProtoWakaama::WAKAAMA_DEVICE_RESOURCE_BATTERY_LEVEL,
1051 CProtoWakaama::WAKAAMA_DEVICE_RESOURCE_BATTERY_STATUS,
1058static int deviceResourceIds(
CProtoWakaama *proto, uint16_t *out)
1062 for (uint16_t
id : DEVICE_RESOURCE_IDS)
1067 for (uint16_t
id : DEVICE_BATTERY_RESOURCE_IDS)
1070 if (bind !=
nullptr && bind->io !=
nullptr)
1083static int deviceBatteryStatusToLwm2m(
int nuttxState)
1105static bool deviceReadBattery(
CProtoWakaama *proto, uint16_t resId, lwm2m_data_t *data)
1110 if (bind ==
nullptr || bind->io ==
nullptr || bind->data ==
nullptr)
1115 if (bind->io->
getData(*bind->data, 1) < 0)
1120 val = *
static_cast<uint32_t *
>(bind->data->
getDataPtr());
1124 case CProtoWakaama::WAKAAMA_DEVICE_RESOURCE_POWER_SOURCE_VOLTAGE:
1125 lwm2m_data_encode_int(
static_cast<int>(val), data);
1128 case CProtoWakaama::WAKAAMA_DEVICE_RESOURCE_BATTERY_LEVEL:
1129 lwm2m_data_encode_int(
static_cast<int>(val), data);
1132 case CProtoWakaama::WAKAAMA_DEVICE_RESOURCE_BATTERY_STATUS:
1133 lwm2m_data_encode_int(deviceBatteryStatusToLwm2m(
static_cast<int>(val)), data);
1143void dawn::wakaama_internal::deviceResolveBatteryBindings(
CProtoWakaama *proto)
1145 for (uint16_t
id : DEVICE_BATTERY_RESOURCE_IDS)
1149 if (bind ==
nullptr || bind->objid == 0)
1154 bind->io = proto->getIOObject(bind->objid);
1155 if (bind->io !=
nullptr)
1162uint8_t dawn::wakaama_internal::deviceRead(lwm2m_context_t *ctx,
1163 uint16_t instanceId,
1165 lwm2m_data_t **dataArray,
1166 lwm2m_object_t *
object)
1174 if (proto ==
nullptr)
1176 return COAP_500_INTERNAL_SERVER_ERROR;
1179 inst =
reinterpret_cast<device_instance_s *
>(lwm2m_list_find(object->instanceList, instanceId));
1180 if (inst ==
nullptr)
1182 return COAP_404_NOT_FOUND;
1187 uint16_t ids[(
sizeof(DEVICE_RESOURCE_IDS) /
sizeof(DEVICE_RESOURCE_IDS[0])) +
1188 (
sizeof(DEVICE_BATTERY_RESOURCE_IDS) /
sizeof(DEVICE_BATTERY_RESOURCE_IDS[0]))];
1189 int count = deviceResourceIds(proto, ids);
1191 if (!allocateResourceList(ids, count, numData, dataArray))
1193 return COAP_500_INTERNAL_SERVER_ERROR;
1197 for (
int i = 0; i < *numData; i++)
1199 switch ((*dataArray)[i].
id)
1201 case CProtoWakaama::WAKAAMA_DEVICE_RESOURCE_MANUFACTURER:
1202 if (!encodeString(proto->deviceManufacturer(), &(*dataArray)[i]))
1204 return COAP_500_INTERNAL_SERVER_ERROR;
1208 case CProtoWakaama::WAKAAMA_DEVICE_RESOURCE_MODEL_NUMBER:
1209 if (!encodeString(proto->deviceModelNumber(), &(*dataArray)[i]))
1211 return COAP_500_INTERNAL_SERVER_ERROR;
1215 case CProtoWakaama::WAKAAMA_DEVICE_RESOURCE_SERIAL_NUMBER:
1216 if (!encodeString(proto->deviceSerialNumber(), &(*dataArray)[i]))
1218 return COAP_500_INTERNAL_SERVER_ERROR;
1222 case CProtoWakaama::WAKAAMA_DEVICE_RESOURCE_FIRMWARE_VERSION:
1223 if (!encodeString(proto->deviceFirmwareVersion(), &(*dataArray)[i]))
1225 return COAP_500_INTERNAL_SERVER_ERROR;
1229 case CProtoWakaama::WAKAAMA_DEVICE_RESOURCE_ERROR_CODE:
1230 lwm2m_data_encode_int(0, &(*dataArray)[i]);
1233 case CProtoWakaama::WAKAAMA_DEVICE_RESOURCE_CURRENT_TIME:
1234 lwm2m_data_encode_int(lwm2m_gettime(), &(*dataArray)[i]);
1237 case CProtoWakaama::WAKAAMA_DEVICE_RESOURCE_BINDING_MODES:
1238 if (!encodeString(
"U", &(*dataArray)[i]))
1240 return COAP_500_INTERNAL_SERVER_ERROR;
1244 case CProtoWakaama::WAKAAMA_DEVICE_RESOURCE_POWER_SOURCE_VOLTAGE:
1245 case CProtoWakaama::WAKAAMA_DEVICE_RESOURCE_BATTERY_LEVEL:
1246 case CProtoWakaama::WAKAAMA_DEVICE_RESOURCE_BATTERY_STATUS:
1247 if (!deviceReadBattery(proto, (*dataArray)[i].
id, &(*dataArray)[i]))
1249 return COAP_404_NOT_FOUND;
1254 return COAP_404_NOT_FOUND;
1258 return COAP_205_CONTENT;
1261uint8_t dawn::wakaama_internal::deviceDiscover(lwm2m_context_t *ctx,
1262 uint16_t instanceId,
1264 lwm2m_data_t **dataArray,
1265 lwm2m_object_t *
object)
1269 if (lwm2m_list_find(object->instanceList, instanceId) ==
nullptr)
1271 return COAP_404_NOT_FOUND;
1277 reinterpret_cast<device_instance_s *
>(lwm2m_list_find(object->instanceList, instanceId));
1279 if (inst ==
nullptr)
1281 return COAP_404_NOT_FOUND;
1285 uint16_t ids[(
sizeof(DEVICE_RESOURCE_IDS) /
sizeof(DEVICE_RESOURCE_IDS[0])) +
1286 (
sizeof(DEVICE_BATTERY_RESOURCE_IDS) /
sizeof(DEVICE_BATTERY_RESOURCE_IDS[0]))];
1289 if (proto ==
nullptr)
1291 return COAP_500_INTERNAL_SERVER_ERROR;
1294 count = deviceResourceIds(proto, ids);
1296 if (!allocateResourceList(ids, count, numData, dataArray))
1298 return COAP_500_INTERNAL_SERVER_ERROR;
1302 return COAP_205_CONTENT;
int getData(IODataCmn &data, size_t len, size_t offset=0)
Get data from I/O (public interface with stats tracking).
io_ddata_t * ddata_alloc(size_t batch, size_t chunk_size=0)
Allocate data buffer for this I/O.
Wakaama LwM2M client protocol implementation.
SDeviceIoBind * deviceBatteryBind(uint16_t resourceId)
Return the battery binding for a Device resource id, or nullptr.
Out-of-tree user-extension hooks for Dawn.
Device-object resource backed by a descriptor IO.
void * getDataPtr(size_t batch=0)
Get pointer to data only (skips timestamp if present).
Fixed pools backing bootstrap-mutable Security and Server objects.
Runtime representation of the single LwM2M Device instance.
Runtime representation of one LwM2M Security object instance.
Runtime representation of one LwM2M Server object instance.