This commit is an initial commit to support lwm2m through wakaama[1].
[1] https://github.com/eclipse/wakaama
Change-Id: I615b4ef26a7baba86d492776f13a10e1be84003d
Signed-off-by: Jin-Seong Kim <jseong82.kim@samsung.com>
- LWM2M_BOOTSTRAP_SERVER_MODE to enable LWM2M Bootstrap Server interfaces.
- LWM2M_BOOTSTRAP to enable LWM2M Bootstrap support in a LWM2M Client.
- LWM2M_SUPPORT_JSON to enable JSON payload support (implicit when defining LWM2M_SERVER_MODE)
+ - LWM2M_OLD_CONTENT_FORMAT_SUPPORT to support the deprecated content format values for TLV and JSON.
Depending on your platform, you need to define LWM2M_BIG_ENDIAN or LWM2M_LITTLE_ENDIAN.
LWM2M_CLIENT_MODE and LWM2M_SERVER_MODE can be defined at the same time.
* ``make``
* ``./lwm2mclient [Options]``
-DTLS feature requires tinydtls submodule. Look at examples/client/README.md for an example of how
-to include tinydtls.
+DTLS feature requires the tinydtls submodule. To include it, on the first run,
+use the following commands to retrieve the sources:
+ * git submodule init
+ * git submodule update
+
+You need to install libtool and autoreconf to build with tinydtls.
Build with tinydtls:
* Create a build directory and change to that.
* ``cmake -DDTLS=1 [liblwm2m directory]/examples/client``
* ``make``
- * ``./lwm2mclient_dtls [Options]``
+ * ``./lwm2mclient [Options]``
The lwm2mclient features nine LWM2M objects:
- Security Object (id: 0)
--------
- Implementation Improvments
- --------------------------
+ Implementation Improvements
+ ---------------------------
- Store lwm2m_transaction_t per peer
- Utility functions to easily implements objects
The utility will just use read and write individual resources. Either statically or
- throught callbacks. See [https://github.com/01org/libdmclient]/tests/mgtobj/utils/static_mo_util.h
+ through callbacks. See [https://github.com/01org/libdmclient]/tests/mgtobj/utils/static_mo_util.h
\ No newline at end of file
ifeq ($(CONFIG_DM),y)
# Routing table support
-
-CSRCS += management.c objects.c observe.c data.c discover.c packet.c registration.c tlv_lwm2m.c transaction.c uri_lwm2m.c utils.c list.c liblwm2m.c json.c bootstrap.c
+CSRCS += block1.c
+CSRCS += management.c objects.c observe.c data.c discover.c packet.c registration.c transaction.c utils.c list.c liblwm2m.c json.c bootstrap.c
+CSRCS += tlv.c uri.c
ifeq ($(CONFIG_LWM2M_CLIENT_MODE),y)
CFLAGS+=-DLWM2M_CLIENT_MODE
ifeq ($(CONFIG_LWM2M_LITTLE_ENDIAN),y)
CFLAGS+=-DLWM2M_LITTLE_ENDIAN
+else
+CFLAGS+=-DLWM2M_BIG_ENDIAN
endif
+
+CFLAGS+=-D__TINYARA__
+
CFLAGS+=-I$(TOPDIR)/../external/wakaama/core
DEPPATH += --dep-path wakaama/core
--- /dev/null
+/*******************************************************************************
+ *
+ * Copyright (c) 2016 Intel Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * and Eclipse Distribution License v1.0 which accompany this distribution.
+ *
+ * The Eclipse Public License is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * The Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ * Simon Bernard - initial API and implementation
+ *
+ *******************************************************************************/
+/*
+ Copyright (c) 2016 Intel Corporation
+
+ Redistribution and use in source and binary forms, with or without modification,
+ are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+ * Neither the name of Intel Corporation nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ THE POSSIBILITY OF SUCH DAMAGE.
+*/
+#include "internals.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+// the maximum payload transferred by block1 we accumulate per server
+#define MAX_BLOCK1_SIZE 4096
+
+coap_status_t coap_block1_handler(lwm2m_block1_data_t ** pBlock1Data,
+ uint16_t mid,
+ uint8_t * buffer,
+ size_t length,
+ uint16_t blockSize,
+ uint32_t blockNum,
+ bool blockMore,
+ uint8_t ** outputBuffer,
+ size_t * outputLength)
+{
+ lwm2m_block1_data_t * block1Data = *pBlock1Data;;
+
+ // manage new block1 transfer
+ if (blockNum == 0)
+ {
+ // we already have block1 data for this server, clear it
+ if (block1Data != NULL)
+ {
+ lwm2m_free(block1Data->block1buffer);
+ }
+ else
+ {
+ block1Data = lwm2m_malloc(sizeof(lwm2m_block1_data_t));
+ *pBlock1Data = block1Data;
+ if (NULL == block1Data) return COAP_500_INTERNAL_SERVER_ERROR;
+ }
+
+ block1Data->block1buffer = lwm2m_malloc(length);
+ block1Data->block1bufferSize = length;
+
+ // write new block in buffer
+ memcpy(block1Data->block1buffer, buffer, length);
+ block1Data->lastmid = mid;
+ }
+ // manage already started block1 transfer
+ else
+ {
+ if (block1Data == NULL)
+ {
+ // we never receive the first block
+ // TODO should we clean block1 data for this server ?
+ return COAP_408_REQ_ENTITY_INCOMPLETE;
+ }
+
+ // If this is a retransmission, we already did that.
+ if (block1Data->lastmid != mid)
+ {
+ uint8_t * oldBuffer = block1Data->block1buffer;
+ size_t oldSize = block1Data->block1bufferSize;
+
+ if (block1Data->block1bufferSize != blockSize * blockNum)
+ {
+ // we don't receive block in right order
+ // TODO should we clean block1 data for this server ?
+ return COAP_408_REQ_ENTITY_INCOMPLETE;
+ }
+
+ // is it too large?
+ if (block1Data->block1bufferSize + length >= MAX_BLOCK1_SIZE) {
+ return COAP_413_ENTITY_TOO_LARGE;
+ }
+ // re-alloc new buffer
+ block1Data->block1bufferSize = oldSize+length;
+ block1Data->block1buffer = lwm2m_malloc(block1Data->block1bufferSize);
+ if (NULL == block1Data->block1buffer) return COAP_500_INTERNAL_SERVER_ERROR;
+ memcpy(block1Data->block1buffer, oldBuffer, oldSize);
+ lwm2m_free(oldBuffer);
+
+ // write new block in buffer
+ memcpy(block1Data->block1buffer + oldSize, buffer, length);
+ block1Data->lastmid = mid;
+ }
+ }
+
+ if (blockMore)
+ {
+ *outputLength = -1;
+ return COAP_231_CONTINUE;
+ }
+ else
+ {
+ // buffer is full, set output parameter
+ // we don't free it to be able to send retransmission
+ *outputLength = block1Data->block1bufferSize;
+ *outputBuffer = block1Data->block1buffer;
+
+ return NO_ERROR;
+ }
+}
+
+void free_block1_buffer(lwm2m_block1_data_t * block1Data)
+{
+ if (block1Data != NULL)
+ {
+ // free block1 buffer
+ lwm2m_free(block1Data->block1buffer);
+ block1Data->block1bufferSize = 0 ;
+
+ // free current element
+ lwm2m_free(block1Data);
+ }
+}
#define PRV_QUERY_BUFFER_LENGTH 200
-static void prv_bootstrapFailed(lwm2m_server_t * bootstrapServer)
-{
- LOG("Entering");
-
- bootstrapServer->status = STATE_BS_FAILED;
-}
static void prv_handleResponse(lwm2m_server_t * bootstrapServer,
coap_packet_t * message)
}
else
{
- prv_bootstrapFailed(bootstrapServer);
+ bootstrapServer->status = STATE_BS_FAILING;
}
}
}
else
{
- prv_bootstrapFailed(bootstrapServer);
+ bootstrapServer->status = STATE_BS_FAILING;
}
}
}
LOG("Entering");
- query_length = utils_stringCopy(query, PRV_QUERY_BUFFER_LENGTH, "?ep=");
+ query_length = utils_stringCopy(query, PRV_QUERY_BUFFER_LENGTH, QUERY_STARTER QUERY_NAME);
if (query_length < 0)
{
- bootstrapServer->status = STATE_BS_FAILED;
+ bootstrapServer->status = STATE_BS_FAILING;
return;
}
res = utils_stringCopy(query + query_length, PRV_QUERY_BUFFER_LENGTH - query_length, context->endpointName);
if (res < 0)
{
- bootstrapServer->status = STATE_BS_FAILED;
+ bootstrapServer->status = STATE_BS_FAILING;
return;
}
query_length += res;
LOG("Bootstrap server connection opened");
- transaction = transaction_new(COAP_TYPE_CON, COAP_POST, NULL, NULL, context->nextMID++, 4, NULL, ENDPOINT_SERVER, (void *)bootstrapServer);
+ transaction = transaction_new(bootstrapServer->sessionH, COAP_POST, NULL, NULL, context->nextMID++, 4, NULL);
if (transaction == NULL)
{
- bootstrapServer->status = STATE_BS_FAILED;
+ bootstrapServer->status = STATE_BS_FAILING;
return;
}
void bootstrap_step(lwm2m_context_t * contextP,
uint32_t currentTime,
- time_t* timeoutP)
+ time_t * timeoutP)
{
lwm2m_server_t * targetP;
// waiting
break;
- case STATE_BS_FINISHED:
+ case STATE_BS_FINISHING:
if (targetP->sessionH != NULL)
{
lwm2m_close_connection(targetP->sessionH, contextP->userData);
targetP->sessionH = NULL;
}
+ targetP->status = STATE_BS_FINISHED;
+ *timeoutP = 0;
break;
- case STATE_BS_FAILED:
+ case STATE_BS_FAILING:
if (targetP->sessionH != NULL)
{
lwm2m_close_connection(targetP->sessionH, contextP->userData);
targetP->sessionH = NULL;
}
+ targetP->status = STATE_BS_FAILED;
+ *timeoutP = 0;
break;
default:
if (bootstrapServer != NULL
&& bootstrapServer->status == STATE_BS_PENDING)
{
- LOG("Bootstrap server status changed to STATE_BS_FINISHED");
- bootstrapServer->status = STATE_BS_FINISHED;
+ LOG("Bootstrap server status changed to STATE_BS_FINISHING");
+ bootstrapServer->status = STATE_BS_FINISHING;
return COAP_204_CHANGED;
}
case STATE_BS_HOLD_OFF:
case STATE_BS_INITIATED:
case STATE_BS_PENDING:
+ case STATE_BS_FINISHING:
bs_status = STATE_BS_PENDING;
break;
break;
case STATE_BS_FINISHED:
+ case STATE_BS_FINISHING:
+ case STATE_BS_FAILING:
case STATE_BS_FAILED:
default:
LOG("Returning COAP_IGNORE");
if (message->uri_query == NULL) return COAP_400_BAD_REQUEST;
if (message->payload != NULL) return COAP_400_BAD_REQUEST;
- if (lwm2m_strncmp((char *)message->uri_query->data, QUERY_TEMPLATE, QUERY_LENGTH) != 0)
+ if (lwm2m_strncmp((char *)message->uri_query->data, QUERY_NAME, QUERY_NAME_LEN) != 0)
{
return COAP_400_BAD_REQUEST;
}
- if (message->uri_query->len == QUERY_LENGTH) return COAP_400_BAD_REQUEST;
+ if (message->uri_query->len == QUERY_NAME_LEN) return COAP_400_BAD_REQUEST;
if (message->uri_query->next != NULL) return COAP_400_BAD_REQUEST;
- name = (char *)lwm2m_malloc(message->uri_query->len - QUERY_LENGTH + 1);
+ name = (char *)lwm2m_malloc(message->uri_query->len - QUERY_NAME_LEN + 1);
if (name == NULL) return COAP_500_INTERNAL_SERVER_ERROR;
- memcpy(name, message->uri_query->data + QUERY_LENGTH, message->uri_query->len - QUERY_LENGTH);
- name[message->uri_query->len - QUERY_LENGTH] = 0;
+ memcpy(name, message->uri_query->data + QUERY_NAME_LEN, message->uri_query->len - QUERY_NAME_LEN);
+ name[message->uri_query->len - QUERY_NAME_LEN] = 0;
result = contextP->bootstrapCallback(fromSessionH, COAP_NO_ERROR, NULL, name, contextP->bootstrapUserData);
if (message == NULL)
{
- dataP->callback(transacP->peerP,
+ dataP->callback(transacP->peerH,
COAP_503_SERVICE_UNAVAILABLE,
uriP,
NULL,
{
coap_packet_t * packet = (coap_packet_t *)message;
- dataP->callback(transacP->peerP,
+ dataP->callback(transacP->peerH,
packet->code,
uriP,
NULL,
bs_data_t * dataP;
LOG_URI(uriP);
- transaction = transaction_new(COAP_TYPE_CON, COAP_DELETE, NULL, uriP, contextP->nextMID++, 4, NULL, ENDPOINT_UNKNOWN, sessionH);
+ transaction = transaction_new(sessionH, COAP_DELETE, NULL, uriP, contextP->nextMID++, 4, NULL);
if (transaction == NULL) return COAP_500_INTERNAL_SERVER_ERROR;
dataP = (bs_data_t *)lwm2m_malloc(sizeof(bs_data_t));
return COAP_400_BAD_REQUEST;
}
- transaction = transaction_new(COAP_TYPE_CON, COAP_PUT, NULL, uriP, contextP->nextMID++, 4, NULL, ENDPOINT_UNKNOWN, sessionH);
+ transaction = transaction_new(sessionH, COAP_PUT, NULL, uriP, contextP->nextMID++, 4, NULL);
if (transaction == NULL) return COAP_500_INTERNAL_SERVER_ERROR;
coap_set_header_content_type(transaction->message, format);
bs_data_t * dataP;
LOG("Entering");
- transaction = transaction_new(COAP_TYPE_CON, COAP_POST, NULL, NULL, contextP->nextMID++, 4, NULL, ENDPOINT_UNKNOWN, sessionH);
+ transaction = transaction_new(sessionH, COAP_POST, NULL, NULL, contextP->nextMID++, 4, NULL);
if (transaction == NULL) return COAP_500_INTERNAL_SERVER_ERROR;
coap_set_header_uri_path(transaction->message, "/"URI_BOOTSTRAP_SEGMENT);
#include <float.h>
// dataP array length is assumed to be 1.
-static size_t prv_textSerialize(lwm2m_data_t * dataP,
- uint8_t ** bufferP)
+static int prv_textSerialize(lwm2m_data_t * dataP,
+ uint8_t ** bufferP)
{
+ size_t res;
+
switch (dataP->type)
{
case LWM2M_TYPE_STRING:
*bufferP = (uint8_t *)lwm2m_malloc(dataP->value.asBuffer.length);
if (*bufferP == NULL) return 0;
memcpy(*bufferP, dataP->value.asBuffer.buffer, dataP->value.asBuffer.length);
- return dataP->value.asBuffer.length;
+ return (int)dataP->value.asBuffer.length;
case LWM2M_TYPE_INTEGER:
- return utils_int64ToPlainText(dataP->value.asInteger, bufferP);
+ res = utils_int64ToPlainText(dataP->value.asInteger, bufferP);
+ if (res == 0) return -1;
+ return (int)res;
case LWM2M_TYPE_FLOAT:
- return utils_float64ToPlainText(dataP->value.asFloat, bufferP);
+ res = utils_float64ToPlainText(dataP->value.asFloat, bufferP);
+ if (res == 0) return -1;
+ return (int)res;
case LWM2M_TYPE_BOOLEAN:
- return utils_boolToPlainText(dataP->value.asBoolean, bufferP);
+ res = utils_boolToPlainText(dataP->value.asBoolean, bufferP);
+ if (res == 0) return -1;
+ return (int)res;
case LWM2M_TYPE_OBJECT_LINK:
- // TODO: implement
+ {
+ char stringBuffer[20];
+ int len = snprintf(stringBuffer, 20, "%d:%d",
+ dataP->value.asObjLink.objectId,
+ dataP->value.asObjLink.objectInstanceId);
+ *bufferP = (uint8_t *)lwm2m_malloc(len);
+ if (*bufferP == NULL) return -1;
+ memcpy(*bufferP, stringBuffer, len);
+ return len;
+ }
case LWM2M_TYPE_OPAQUE:
case LWM2M_TYPE_UNDEFINED:
default:
- return 0;
+ return -1;
}
}
return result;
}
+void lwm2m_data_encode_objlink(uint16_t objectId,
+ uint16_t objectInstanceId,
+ lwm2m_data_t * dataP)
+{
+ LOG_ARG("value: %d/%d", objectId, objectInstanceId);
+ dataP->type = LWM2M_TYPE_OBJECT_LINK;
+ dataP->value.asObjLink.objectId = objectId;
+ dataP->value.asObjLink.objectInstanceId = objectInstanceId;
+}
+
void lwm2m_data_include(lwm2m_data_t * subDataP,
size_t count,
lwm2m_data_t * dataP)
(*dataP)->type = LWM2M_TYPE_OPAQUE;
return prv_setBuffer(*dataP, buffer, bufferLen);
+#ifdef LWM2M_OLD_CONTENT_FORMAT_SUPPORT
+ case LWM2M_CONTENT_TLV_OLD:
+#endif
case LWM2M_CONTENT_TLV:
return tlv_parse(buffer, bufferLen, dataP);
#ifdef LWM2M_SUPPORT_JSON
+#ifdef LWM2M_OLD_CONTENT_FORMAT_SUPPORT
+ case LWM2M_CONTENT_JSON_OLD:
+#endif
case LWM2M_CONTENT_JSON:
return json_parse(uriP, buffer, bufferLen, dataP);
#endif
}
}
-size_t lwm2m_data_serialize(lwm2m_uri_t * uriP,
- int size,
- lwm2m_data_t * dataP,
- lwm2m_media_type_t * formatP,
- uint8_t ** bufferP)
+int lwm2m_data_serialize(lwm2m_uri_t * uriP,
+ int size,
+ lwm2m_data_t * dataP,
+ lwm2m_media_type_t * formatP,
+ uint8_t ** bufferP)
{
-
LOG_URI(uriP);
LOG_ARG("size: %d, formatP: %s", size, STR_MEDIA_TYPE(*formatP));
|| *formatP == LWM2M_CONTENT_OPAQUE)
{
if (size != 1
- || !LWM2M_URI_IS_SET_RESOURCE(uriP)
+ || (uriP != NULL && !LWM2M_URI_IS_SET_RESOURCE(uriP))
|| dataP->type == LWM2M_TYPE_OBJECT
|| dataP->type == LWM2M_TYPE_OBJECT_INSTANCE
|| dataP->type == LWM2M_TYPE_MULTIPLE_RESOURCE)
case LWM2M_CONTENT_OPAQUE:
*bufferP = (uint8_t *)lwm2m_malloc(dataP->value.asBuffer.length);
- if (*bufferP == NULL) return 0;
+ if (*bufferP == NULL) return -1;
memcpy(*bufferP, dataP->value.asBuffer.buffer, dataP->value.asBuffer.length);
- return dataP->value.asBuffer.length;
+ return (int)dataP->value.asBuffer.length;
case LWM2M_CONTENT_TLV:
{
- uint8_t baseUriStr[URI_MAX_STRING_LEN];
- size_t baseUriLen;
- uri_depth_t rootLevel;
bool isResourceInstance;
- baseUriLen = uri_toString(uriP, baseUriStr, URI_MAX_STRING_LEN, &rootLevel);
- if (baseUriLen <= 0) return 0;
- if (rootLevel == URI_DEPTH_RESOURCE_INSTANCE)
+ if (uriP != NULL && LWM2M_URI_IS_SET_RESOURCE(uriP)
+ && (size != 1 || dataP->id != uriP->resourceId))
{
isResourceInstance = true;
}
#ifdef LWM2M_CLIENT_MODE
case LWM2M_CONTENT_LINK:
- return discover_serialize(NULL, uriP, size, dataP, bufferP);
+ return discover_serialize(NULL, uriP, NULL, size, dataP, bufferP);
#endif
#ifdef LWM2M_SUPPORT_JSON
case LWM2M_CONTENT_JSON:
#endif
default:
- return 0;
+ return -1;
}
}
#ifdef LWM2M_CLIENT_MODE
+
+static lwm2m_attributes_t * prv_findAttributes(lwm2m_context_t * contextP,
+ lwm2m_uri_t * uriP,
+ lwm2m_server_t * serverP)
+{
+ lwm2m_observed_t * observedP;
+ lwm2m_watcher_t * watcherP;
+ lwm2m_attributes_t * paramP;
+
+ paramP = NULL;
+
+ if (contextP == NULL) return NULL;
+ if (serverP == NULL) return NULL;
+
+ observedP = observe_findByUri(contextP, uriP);
+ if (observedP == NULL || observedP->watcherList == NULL) return NULL;
+
+ for (watcherP = observedP->watcherList; watcherP != NULL; watcherP = watcherP->next)
+ {
+ if (watcherP->server == serverP)
+ {
+ paramP = watcherP->parameters;
+ }
+ }
+
+ return paramP;
+}
+
static int prv_serializeAttributes(lwm2m_context_t * contextP,
lwm2m_uri_t * uriP,
+ lwm2m_server_t * serverP,
+ lwm2m_attributes_t * objectParamP,
uint8_t * buffer,
size_t uriLen,
size_t bufferLen)
{
- lwm2m_observed_t * observedP;
- lwm2m_watcher_t * watcherP;
int head;
int res;
+ lwm2m_attributes_t * paramP;
- if (contextP == NULL) return 0;
+ head = 0;
- observedP = observe_findByUri(contextP, uriP);
- if (observedP == NULL || observedP->watcherList == NULL) return 0;
+ paramP = prv_findAttributes(contextP, uriP, serverP);
+ if (paramP == NULL) paramP = objectParamP;
- head = 0;
- for (watcherP = observedP->watcherList; watcherP != NULL; watcherP = watcherP->next)
+ if (paramP != NULL)
{
- lwm2m_attributes_t * paramP;
-
- paramP = watcherP->parameters;
- if (paramP == NULL || paramP->toSet == 0) continue;
+ head = uriLen;
- if (observedP->watcherList->next != NULL)
+ if (paramP->toSet & LWM2M_ATTR_FLAG_MIN_PERIOD)
{
- // multiple servers
- memcpy(buffer + head, buffer, uriLen);
-
PRV_CONCAT_STR(buffer, bufferLen, head, LINK_ATTR_SEPARATOR, LINK_ATTR_SEPARATOR_SIZE);
- PRV_CONCAT_STR(buffer, bufferLen, head, ATTR_SERVER_ID_STR, ATTR_SERVER_ID_LEN);
+ PRV_CONCAT_STR(buffer, bufferLen, head, ATTR_MIN_PERIOD_STR, ATTR_MIN_PERIOD_LEN);
- res = utils_intToText(watcherP->server->shortID, buffer + head, bufferLen - head);
+ res = utils_intToText(paramP->minPeriod, buffer + head, bufferLen - head);
if (res <= 0) return -1;
head += res;
}
- else
- {
- head = uriLen;
- }
-
- if (paramP->toSet & LWM2M_ATTR_FLAG_MIN_PERIOD)
+ else if (objectParamP->toSet & LWM2M_ATTR_FLAG_MIN_PERIOD)
{
PRV_CONCAT_STR(buffer, bufferLen, head, LINK_ATTR_SEPARATOR, LINK_ATTR_SEPARATOR_SIZE);
PRV_CONCAT_STR(buffer, bufferLen, head, ATTR_MIN_PERIOD_STR, ATTR_MIN_PERIOD_LEN);
- res = utils_intToText(paramP->minPeriod, buffer + head, bufferLen - head);
+ res = utils_intToText(objectParamP->minPeriod, buffer + head, bufferLen - head);
if (res <= 0) return -1;
head += res;
}
+
if (paramP->toSet & LWM2M_ATTR_FLAG_MAX_PERIOD)
{
PRV_CONCAT_STR(buffer, bufferLen, head, LINK_ATTR_SEPARATOR, LINK_ATTR_SEPARATOR_SIZE);
if (res <= 0) return -1;
head += res;
}
+ else if (objectParamP->toSet & LWM2M_ATTR_FLAG_MAX_PERIOD)
+ {
+ PRV_CONCAT_STR(buffer, bufferLen, head, LINK_ATTR_SEPARATOR, LINK_ATTR_SEPARATOR_SIZE);
+ PRV_CONCAT_STR(buffer, bufferLen, head, ATTR_MAX_PERIOD_STR, ATTR_MAX_PERIOD_LEN);
+
+ res = utils_intToText(objectParamP->maxPeriod, buffer + head, bufferLen - head);
+ if (res <= 0) return -1;
+ head += res;
+ }
+
if (paramP->toSet & LWM2M_ATTR_FLAG_GREATER_THAN)
{
PRV_CONCAT_STR(buffer, bufferLen, head, LINK_ATTR_SEPARATOR, LINK_ATTR_SEPARATOR_SIZE);
PRV_CONCAT_STR(buffer, bufferLen, head, LINK_ITEM_ATTR_END, LINK_ITEM_ATTR_END_SIZE);
}
- if (head > 0) head -= uriLen;
+ if (head > 0) head -= uriLen + 1;
return head;
}
static int prv_serializeLinkData(lwm2m_context_t * contextP,
lwm2m_data_t * tlvP,
+ lwm2m_server_t * serverP,
+ lwm2m_attributes_t * objectParamP,
lwm2m_uri_t * parentUriP,
uint8_t * parentUriStr,
size_t parentUriLen,
head += LINK_ITEM_END_SIZE;
}
- memcpy(&uri, parentUriP, sizeof(lwm2m_uri_t));
- uri.resourceId = tlvP->id;
- uri.flag |= LWM2M_URI_FLAG_RESOURCE_ID;
- res = prv_serializeAttributes(contextP, &uri, buffer, head - 1, bufferLen);
- if (res < 0) return -1; // careful, 0 is valid
- if (res > 0) head += res - 1;
-
+ if (serverP != NULL)
+ {
+ memcpy(&uri, parentUriP, sizeof(lwm2m_uri_t));
+ uri.resourceId = tlvP->id;
+ uri.flag |= LWM2M_URI_FLAG_RESOURCE_ID;
+ res = prv_serializeAttributes(contextP, &uri, serverP, objectParamP, buffer, head - 1, bufferLen);
+ if (res < 0) return -1; // careful, 0 is valid
+ if (res > 0) head += res;
+ }
break;
case LWM2M_TYPE_OBJECT_INSTANCE:
PRV_CONCAT_STR(buffer, bufferLen, head, LINK_ITEM_START, LINK_ITEM_START_SIZE);
PRV_CONCAT_STR(buffer, bufferLen, head, uriStr, uriLen);
PRV_CONCAT_STR(buffer, bufferLen, head, LINK_ITEM_END, LINK_ITEM_END_SIZE);
- res = prv_serializeAttributes(contextP, &uri, buffer, head - 1, bufferLen);
- if (res < 0) return -1; // careful, 0 is valid
- if (res == 0) head = 0; // rewind
- else head += res - 1;
-
+ if (serverP != NULL)
+ {
+ res = prv_serializeAttributes(contextP, &uri, serverP, NULL, buffer, head - 1, bufferLen);
+ if (res < 0) return -1; // careful, 0 is valid
+ if (res == 0) head = 0; // rewind
+ else head += res;
+ }
for (index = 0; index < tlvP->value.asChildren.count; index++)
{
- res = prv_serializeLinkData(contextP, tlvP->value.asChildren.array + index, &uri, uriStr, uriLen, buffer + head, bufferLen - head);
+ res = prv_serializeLinkData(contextP, tlvP->value.asChildren.array + index, serverP, objectParamP, &uri, uriStr, uriLen, buffer + head, bufferLen - head);
if (res < 0) return -1;
head += res;
}
}
int discover_serialize(lwm2m_context_t * contextP,
- lwm2m_uri_t * uriP,
- int size,
- lwm2m_data_t * dataP,
- uint8_t ** bufferP)
+ lwm2m_uri_t * uriP,
+ lwm2m_server_t * serverP,
+ int size,
+ lwm2m_data_t * dataP,
+ uint8_t ** bufferP)
{
uint8_t bufferLink[PRV_LINK_BUFFER_SIZE];
uint8_t baseUriStr[URI_MAX_STRING_LEN];
int index;
size_t head;
int res;
- lwm2m_uri_t tempUri;
+ lwm2m_uri_t parentUri;
+ lwm2m_attributes_t * paramP;
+ lwm2m_attributes_t mergedParam;
LOG_ARG("size: %d", size);
LOG_URI(uriP);
- baseUriLen = uri_toString(uriP, baseUriStr, URI_MAX_STRING_LEN, NULL);
- if (baseUriLen < 0) return -1;
- baseUriLen -= 1;
head = 0;
- memset(&tempUri, 0, sizeof(lwm2m_uri_t));
-
- // get object level attributes
- PRV_CONCAT_STR(bufferLink, PRV_LINK_BUFFER_SIZE, head, LINK_ITEM_START, LINK_ITEM_START_SIZE);
- PRV_CONCAT_STR(bufferLink, PRV_LINK_BUFFER_SIZE, head, LINK_URI_SEPARATOR, LINK_URI_SEPARATOR_SIZE);
- res = utils_intToText(uriP->objectId, bufferLink + head, PRV_LINK_BUFFER_SIZE - head);
- if (res <= 0) return -1;
- head += res;
- PRV_CONCAT_STR(bufferLink, PRV_LINK_BUFFER_SIZE, head, LINK_ITEM_END, LINK_ITEM_END_SIZE);
- tempUri.objectId = uriP->objectId;
- res = prv_serializeAttributes(contextP, &tempUri, bufferLink, head - 1, PRV_LINK_BUFFER_SIZE);
- if (res < 0) return -1; // careful, 0 is valid
- if (res == 0) head = 0; // rewind
- else head += res - 1;
- if (LWM2M_URI_IS_SET_INSTANCE(uriP))
+ memset(&parentUri, 0, sizeof(lwm2m_uri_t));
+ parentUri.objectId = uriP->objectId;
+ parentUri.flag = LWM2M_URI_FLAG_OBJECT_ID;
+
+ if (LWM2M_URI_IS_SET_RESOURCE(uriP))
{
- size_t subHead;
+ lwm2m_uri_t tempUri;
+ lwm2m_attributes_t * objParamP;
+ lwm2m_attributes_t * instParamP;
+ memset(&parentUri, 0, sizeof(lwm2m_uri_t));
+ tempUri.objectId = uriP->objectId;
+ tempUri.flag = LWM2M_URI_FLAG_OBJECT_ID;
+
+ // get object level attributes
+ objParamP = prv_findAttributes(contextP, &tempUri, serverP);
+
// get object instance level attributes
- subHead = 0;
- PRV_CONCAT_STR(bufferLink + head, PRV_LINK_BUFFER_SIZE - head, subHead, LINK_ITEM_START, LINK_ITEM_START_SIZE);
- PRV_CONCAT_STR(bufferLink + head, PRV_LINK_BUFFER_SIZE - head, subHead, LINK_URI_SEPARATOR, LINK_URI_SEPARATOR_SIZE);
- res = utils_intToText(uriP->objectId, bufferLink + head + subHead, PRV_LINK_BUFFER_SIZE - head - subHead);
- if (res <= 0) return -1;
- subHead += res;
- PRV_CONCAT_STR(bufferLink + head, PRV_LINK_BUFFER_SIZE - head, subHead, LINK_URI_SEPARATOR, LINK_URI_SEPARATOR_SIZE);
- res = utils_intToText(uriP->instanceId, bufferLink + head + subHead, PRV_LINK_BUFFER_SIZE - head - subHead);
- if (res <= 0) return -1;
- subHead += res;
- PRV_CONCAT_STR(bufferLink + head, PRV_LINK_BUFFER_SIZE - head, subHead, LINK_ITEM_END, LINK_ITEM_END_SIZE);
tempUri.instanceId = uriP->instanceId;
tempUri.flag = LWM2M_URI_FLAG_INSTANCE_ID;
- res = prv_serializeAttributes(contextP, &tempUri, bufferLink + head, head + subHead - 1, PRV_LINK_BUFFER_SIZE);
- if (res < 0) return -1; // careful, 0 is valid
- if (res == 0) subHead = 0; // rewind
- else subHead += res - 1;
+ instParamP = prv_findAttributes(contextP, &tempUri, serverP);
+
+ if (objParamP != NULL)
+ {
+ if (instParamP != NULL)
+ {
+ memset(&mergedParam, 0, sizeof(lwm2m_attributes_t));
+ mergedParam.toSet = objParamP->toSet | instParamP->toSet;
+ if (mergedParam.toSet & LWM2M_ATTR_FLAG_MIN_PERIOD)
+ {
+ if (instParamP->toSet & LWM2M_ATTR_FLAG_MIN_PERIOD)
+ {
+ mergedParam.minPeriod = instParamP->minPeriod;
+ }
+ else
+ {
+ mergedParam.minPeriod = objParamP->minPeriod;
+ }
+ }
+ if (mergedParam.toSet & LWM2M_ATTR_FLAG_MAX_PERIOD)
+ {
+ if (instParamP->toSet & LWM2M_ATTR_FLAG_MAX_PERIOD)
+ {
+ mergedParam.maxPeriod = instParamP->maxPeriod;
+ }
+ else
+ {
+ mergedParam.maxPeriod = objParamP->maxPeriod;
+ }
+ }
+ paramP = &mergedParam;
+ }
+ else
+ {
+ paramP = objParamP;
+ }
+ }
+ else
+ {
+ paramP = instParamP;
+ }
+ uriP->flag &= ~LWM2M_URI_FLAG_RESOURCE_ID;
+ }
+ else
+ {
+ paramP = NULL;
- head += subHead;
+ if (LWM2M_URI_IS_SET_INSTANCE(uriP))
+ {
+ PRV_CONCAT_STR(bufferLink, PRV_LINK_BUFFER_SIZE, head, LINK_ITEM_START, LINK_ITEM_START_SIZE);
+ PRV_CONCAT_STR(bufferLink, PRV_LINK_BUFFER_SIZE, head, LINK_URI_SEPARATOR, LINK_URI_SEPARATOR_SIZE);
+ res = utils_intToText(uriP->objectId, bufferLink + head, PRV_LINK_BUFFER_SIZE - head);
+ if (res <= 0) return -1;
+ head += res;
+ PRV_CONCAT_STR(bufferLink, PRV_LINK_BUFFER_SIZE, head, LINK_URI_SEPARATOR, LINK_URI_SEPARATOR_SIZE);
+ res = utils_intToText(uriP->instanceId, bufferLink + head, PRV_LINK_BUFFER_SIZE - head);
+ if (res <= 0) return -1;
+ head += res;
+ PRV_CONCAT_STR(bufferLink, PRV_LINK_BUFFER_SIZE, head, LINK_ITEM_END, LINK_ITEM_END_SIZE);
+ parentUri.instanceId = uriP->instanceId;
+ parentUri.flag = LWM2M_URI_FLAG_INSTANCE_ID;
+ if (serverP != NULL)
+ {
+ res = prv_serializeAttributes(contextP, &parentUri, serverP, NULL, bufferLink, head - 1, PRV_LINK_BUFFER_SIZE);
+ if (res < 0) return -1; // careful, 0 is valid
+ }
+ else
+ {
+ res = 0;
+ }
+ head += res;
+ }
+ else
+ {
+ PRV_CONCAT_STR(bufferLink, PRV_LINK_BUFFER_SIZE, head, LINK_ITEM_START, LINK_ITEM_START_SIZE);
+ PRV_CONCAT_STR(bufferLink, PRV_LINK_BUFFER_SIZE, head, LINK_URI_SEPARATOR, LINK_URI_SEPARATOR_SIZE);
+ res = utils_intToText(uriP->objectId, bufferLink + head, PRV_LINK_BUFFER_SIZE - head);
+ if (res <= 0) return -1;
+ head += res;
+ PRV_CONCAT_STR(bufferLink, PRV_LINK_BUFFER_SIZE, head, LINK_ITEM_END, LINK_ITEM_END_SIZE);
+
+ if (serverP != NULL)
+ {
+ res = prv_serializeAttributes(contextP, &parentUri, serverP, NULL, bufferLink, head - 1, PRV_LINK_BUFFER_SIZE);
+ if (res < 0) return -1; // careful, 0 is valid
+ head += res;
+ }
+ }
}
+ baseUriLen = uri_toString(uriP, baseUriStr, URI_MAX_STRING_LEN, NULL);
+ if (baseUriLen < 0) return -1;
+ baseUriLen -= 1;
+
for (index = 0; index < size && head < PRV_LINK_BUFFER_SIZE; index++)
{
- res = prv_serializeLinkData(contextP, dataP + index, uriP, baseUriStr, baseUriLen, bufferLink + head, PRV_LINK_BUFFER_SIZE - head);
+ res = prv_serializeLinkData(contextP, dataP + index, serverP, paramP, uriP, baseUriStr, baseUriLen, bufferLink + head, PRV_LINK_BUFFER_SIZE - head);
if (res < 0) return -1;
head += res;
}
coap_set_option_header(unsigned int delta, size_t length, uint8_t *buffer)
{
size_t written = 0;
+ unsigned int *x = δ
buffer[0] = coap_option_nibble(delta)<<4 | coap_option_nibble(length);
/* avoids code duplication without function overhead */
- unsigned int *x = δ
do
{
if (*x>268)
coap_parse_message(void *packet, uint8_t *data, uint16_t data_len)
{
coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
+ uint8_t *current_option;
+ unsigned int option_number = 0;
+ unsigned int option_delta = 0;
+ size_t option_length = 0;
+ unsigned int *x;
/* Initialize packet */
memset(coap_pkt, 0, sizeof(coap_packet_t));
return BAD_REQUEST_4_00;
}
- uint8_t *current_option = data + COAP_HEADER_LEN;
+ current_option = data + COAP_HEADER_LEN;
if (coap_pkt->token_len != 0)
{
/* parse options */
current_option += coap_pkt->token_len;
- unsigned int option_number = 0;
- unsigned int option_delta = 0;
- size_t option_length = 0;
-
while (current_option < data+data_len)
{
/* Payload marker 0xFF, currently only checking for 0xF* because rest is reserved */
++current_option;
/* avoids code duplication without function overhead */
- unsigned int *x = &option_delta;
+ x = &option_delta;
do
{
if (*x==13)
if (!IS_OPTION(coap_pkt, COAP_OPTION_PROXY_URI)) return 0;
- *uri = coap_pkt->proxy_uri;
+ *uri = (const char *)coap_pkt->proxy_uri;
return coap_pkt->proxy_uri_len;
}
{
coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
- coap_pkt->proxy_uri = uri;
+ coap_pkt->proxy_uri = (uint8_t *)uri;
coap_pkt->proxy_uri_len = strlen(uri);
SET_OPTION(coap_pkt, COAP_OPTION_PROXY_URI);
if (!IS_OPTION(coap_pkt, COAP_OPTION_LOCATION_QUERY)) return 0;
- *query = coap_pkt->location_query;
+ *query = (const char*)coap_pkt->location_query;
return coap_pkt->location_query_len;
}
while (query[0]=='?') ++query;
- coap_pkt->location_query = query;
+ coap_pkt->location_query = (uint8_t *)query;
coap_pkt->location_query_len = strlen(query);
SET_OPTION(coap_pkt, COAP_OPTION_LOCATION_QUERY);
#define COAP_DEFAULT_MAX_AGE 60
#define COAP_RESPONSE_TIMEOUT 2
#define COAP_MAX_RETRANSMIT 4
+#define COAP_ACK_RANDOM_FACTOR 1.5
+
+#define COAP_MAX_TRANSMIT_WAIT ((COAP_RESPONSE_TIMEOUT * ( (1 << (COAP_MAX_RETRANSMIT + 1) ) - 1) * COAP_ACK_RANDOM_FACTOR))
#define COAP_HEADER_LEN 4 /* | version:0x03 type:0x0C tkl:0xF0 | code | mid:0x00FF | mid:0xFF00 | */
#define COAP_ETAG_LEN 8 /* The maximum number of bytes for the ETag */
#define COAP_MAX_PACKET_SIZE (COAP_MAX_HEADER_SIZE + REST_MAX_CHUNK_SIZE)
/* 0/14 48 for IPv6 (28 for IPv4) */
-// #if COAP_MAX_PACKET_SIZE > (UIP_BUFSIZE - UIP_LLH_LEN - UIP_IPUDPH_LEN)
-//#error "UIP_CONF_BUFFER_SIZE too small for REST_MAX_CHUNK_SIZE"
-// #endif
/* Bitmap for set options */
COAP_OPTION_BLOCK1 = 27, /* 1-3 B */
COAP_OPTION_SIZE = 28, /* 0-4 B */
COAP_OPTION_PROXY_URI = 35, /* 1-270 B */
+ OPTION_MAX_VALUE = 0xFFFF
} coap_option_t;
/* CoAP Content-Types */
APPLICATION_SOAP_FASTINFOSET = 49,
APPLICATION_JSON = 50,
APPLICATION_X_OBIX_BINARY = 51,
- APPLICATION_FILLER=65535,
+ CONTENT_MAX_VALUE = 0xFFFF
} coap_content_type_t;
typedef struct _multi_option_t {
#define COAP_SERIALIZE_BLOCK_OPTION(number, field, text) \
if (IS_OPTION(coap_pkt, number)) \
{ \
- PRINTF(text" [%lu%s (%u B/blk)]\n", coap_pkt->field##_num, coap_pkt->field##_more ? "+" : "", coap_pkt->field##_size); \
uint32_t block = coap_pkt->field##_num << 4; \
+ PRINTF(text" [%lu%s (%u B/blk)]\n", coap_pkt->field##_num, coap_pkt->field##_more ? "+" : "", coap_pkt->field##_size); \
if (coap_pkt->field##_more) block |= 0x8; \
block |= 0xF & coap_log_2(coap_pkt->field##_size/16); \
PRINTF(text" encoded: 0x%lX\n", block); \
((S) == STATE_REGISTERED ? "STATE_REGISTERED" : \
((S) == STATE_REG_FAILED ? "STATE_REG_FAILED" : \
((S) == STATE_REG_UPDATE_PENDING ? "STATE_REG_UPDATE_PENDING" : \
+((S) == STATE_REG_UPDATE_NEEDED ? "STATE_REG_UPDATE_NEEDED" : \
+((S) == STATE_REG_FULL_UPDATE_NEEDED ? "STATE_REG_FULL_UPDATE_NEEDED" : \
((S) == STATE_DEREG_PENDING ? "STATE_DEREG_PENDING" : \
((S) == STATE_BS_HOLD_OFF ? "STATE_BS_HOLD_OFF" : \
((S) == STATE_BS_INITIATED ? "STATE_BS_INITIATED" : \
((S) == STATE_BS_PENDING ? "STATE_BS_PENDING" : \
((S) == STATE_BS_FINISHED ? "STATE_BS_FINISHED" : \
+((S) == STATE_BS_FINISHING ? "STATE_BS_FINISHING" : \
+((S) == STATE_BS_FAILING ? "STATE_BS_FAILING" : \
((S) == STATE_BS_FAILED ? "STATE_BS_FAILED" : \
-"Unknown")))))))))))
+"Unknown")))))))))))))))
#define STR_MEDIA_TYPE(M) \
((M) == LWM2M_CONTENT_TEXT ? "LWM2M_CONTENT_TEXT" : \
((M) == LWM2M_CONTENT_LINK ? "LWM2M_CONTENT_LINK" : \
#define LWM2M_DEFAULT_LIFETIME 86400
#ifdef LWM2M_SUPPORT_JSON
-#define REG_LWM2M_RESOURCE_TYPE ">;rt=\"oma.lwm2m\";ct=1543," // Temporary value
+#define REG_LWM2M_RESOURCE_TYPE ">;rt=\"oma.lwm2m\";ct=11543,"
#define REG_LWM2M_RESOURCE_TYPE_LEN 25
#else
#define REG_LWM2M_RESOURCE_TYPE ">;rt=\"oma.lwm2m\","
#define URI_BOOTSTRAP_SEGMENT "bs"
#define URI_BOOTSTRAP_SEGMENT_LEN 2
-#define QUERY_TEMPLATE "ep="
-#define QUERY_LENGTH 3 // strlen("ep=")
+#define QUERY_STARTER "?"
+#define QUERY_NAME "ep="
+#define QUERY_NAME_LEN 3 // strlen("ep=")
#define QUERY_SMS "sms="
#define QUERY_SMS_LEN 4
#define QUERY_LIFETIME "lt="
#define QUERY_BINDING_LEN 2
#define QUERY_DELIMITER "&"
-#define QUERY_VERSION_FULL "lwm2m=1.0"
-#define QUERY_VERSION_FULL_LEN 9
+#define LWM2M_VERSION "1.0"
+#define LWM2M_VERSION_LEN 3
+
+#define QUERY_VERSION_FULL QUERY_VERSION LWM2M_VERSION
+#define QUERY_VERSION_FULL_LEN QUERY_VERSION_LEN+LWM2M_VERSION_LEN
#define REG_URI_START '<'
#define REG_URI_END '>'
#define REG_ATTR_TYPE_VALUE_LEN 11
#define REG_ATTR_CONTENT_KEY "ct"
#define REG_ATTR_CONTENT_KEY_LEN 2
-#define REG_ATTR_CONTENT_JSON "1543" // Temporary value
-#define REG_ATTR_CONTENT_JSON_LEN 4
+#define REG_ATTR_CONTENT_JSON "11543" // Temporary value
+#define REG_ATTR_CONTENT_JSON_LEN 5
#define ATTR_SERVER_ID_STR "ep="
#define ATTR_SERVER_ID_LEN 3
typedef struct
{
+ uint16_t clientID;
lwm2m_uri_t uri;
lwm2m_result_callback_t callback;
void * userData;
coap_status_t object_create(lwm2m_context_t * contextP, lwm2m_uri_t * uriP, lwm2m_media_type_t format, uint8_t * buffer, size_t length);
coap_status_t object_execute(lwm2m_context_t * contextP, lwm2m_uri_t * uriP, uint8_t * buffer, size_t length);
coap_status_t object_delete(lwm2m_context_t * contextP, lwm2m_uri_t * uriP);
-coap_status_t object_discover(lwm2m_context_t * contextP, lwm2m_uri_t * uriP, uint8_t ** bufferP, size_t * lengthP);
+coap_status_t object_discover(lwm2m_context_t * contextP, lwm2m_uri_t * uriP, lwm2m_server_t * serverP, uint8_t ** bufferP, size_t * lengthP);
uint8_t object_checkReadable(lwm2m_context_t * contextP, lwm2m_uri_t * uriP);
uint8_t object_checkNumeric(lwm2m_context_t * contextP, lwm2m_uri_t * uriP);
bool object_isInstanceNew(lwm2m_context_t * contextP, uint16_t objectId, uint16_t instanceId);
coap_status_t object_writeInstance(lwm2m_context_t * contextP, lwm2m_uri_t * uriP, lwm2m_data_t * dataP);
// defined in transaction.c
-lwm2m_transaction_t * transaction_new(coap_message_type_t type, coap_method_t method, char * altPath, lwm2m_uri_t * uriP, uint16_t mID, uint8_t token_len, uint8_t* token, lwm2m_endpoint_type_t peerType, void * peerP);
+lwm2m_transaction_t * transaction_new(void * sessionH, coap_method_t method, char * altPath, lwm2m_uri_t * uriP, uint16_t mID, uint8_t token_len, uint8_t* token);
int transaction_send(lwm2m_context_t * contextP, lwm2m_transaction_t * transacP);
void transaction_free(lwm2m_transaction_t * transacP);
void transaction_remove(lwm2m_context_t * contextP, lwm2m_transaction_t * transacP);
coap_status_t observe_setParameters(lwm2m_context_t * contextP, lwm2m_uri_t * uriP, lwm2m_server_t * serverP, lwm2m_attributes_t * attrP);
void observe_step(lwm2m_context_t * contextP, time_t currentTime, time_t * timeoutP);
bool observe_handleNotify(lwm2m_context_t * contextP, void * fromSessionH, coap_packet_t * message, coap_packet_t * response);
-void observe_remove(lwm2m_client_t * clientP, lwm2m_observation_t * observationP);
+void observe_remove(lwm2m_observation_t * observationP);
lwm2m_observed_t * observe_findByUri(lwm2m_context_t * contextP, lwm2m_uri_t * uriP);
// defined in registration.c
// defined in tlv.c
int tlv_parse(uint8_t * buffer, size_t bufferLen, lwm2m_data_t ** dataP);
-size_t tlv_serialize(bool isResourceInstance, int size, lwm2m_data_t * dataP, uint8_t ** bufferP);
+int tlv_serialize(bool isResourceInstance, int size, lwm2m_data_t * dataP, uint8_t ** bufferP);
// defined in json.c
#ifdef LWM2M_SUPPORT_JSON
int json_parse(lwm2m_uri_t * uriP, uint8_t * buffer, size_t bufferLen, lwm2m_data_t ** dataP);
-size_t json_serialize(lwm2m_uri_t * uriP, int size, lwm2m_data_t * tlvP, uint8_t ** bufferP);
+int json_serialize(lwm2m_uri_t * uriP, int size, lwm2m_data_t * tlvP, uint8_t ** bufferP);
#endif
// defined in discover.c
-int discover_serialize(lwm2m_context_t * contextP, lwm2m_uri_t * uriP, int size, lwm2m_data_t * dataP, uint8_t ** bufferP);
+int discover_serialize(lwm2m_context_t * contextP, lwm2m_uri_t * uriP, lwm2m_server_t * serverP, int size, lwm2m_data_t * dataP, uint8_t ** bufferP);
+
+// defined in block1.c
+coap_status_t coap_block1_handler(lwm2m_block1_data_t ** block1Data, uint16_t mid, uint8_t * buffer, size_t length, uint16_t blockSize, uint32_t blockNum, bool blockMore, uint8_t ** outputBuffer, size_t * outputLength);
+void free_block1_buffer(lwm2m_block1_data_t * block1Data);
// defined in utils.c
lwm2m_data_type_t utils_depthToDatatype(uri_depth_t depth);
return head;
}
-static size_t prv_findAndCheckData(lwm2m_uri_t * uriP,
- uri_depth_t level,
- size_t size,
- lwm2m_data_t * tlvP,
- lwm2m_data_t ** targetP)
+static int prv_findAndCheckData(lwm2m_uri_t * uriP,
+ uri_depth_t level,
+ size_t size,
+ lwm2m_data_t * tlvP,
+ lwm2m_data_t ** targetP)
{
size_t index;
- size_t result;
+ int result;
+
+ if (size == 0) return 0;
if (size > 1)
{
if (tlvP[index].type != tlvP[0].type)
{
*targetP = NULL;
- return 0;
+ return -1;
}
}
}
if (tlvP[index].type == LWM2M_TYPE_OBJECT || tlvP[index].type == LWM2M_TYPE_OBJECT_INSTANCE)
{
*targetP = NULL;
- return 0;
+ return -1;
}
}
}
}
*targetP = NULL;
- result = 0;
+ result = -1;
switch (level)
{
case URI_DEPTH_OBJECT:
if (tlvP[0].type == LWM2M_TYPE_OBJECT)
{
*targetP = tlvP;
- result = size;
+ result = (int)size;
}
break;
break;
case LWM2M_TYPE_OBJECT_INSTANCE:
*targetP = tlvP;
- result = size;
+ result = (int)size;
break;
default:
break;
break;
default:
*targetP = tlvP;
- result = size;
+ result = (int)size;
break;
}
break;
break;
default:
*targetP = tlvP;
- result = size;
+ result = (int)size;
break;
}
break;
return result;
}
-size_t json_serialize(lwm2m_uri_t * uriP,
- int size,
- lwm2m_data_t * tlvP,
- uint8_t ** bufferP)
+int json_serialize(lwm2m_uri_t * uriP,
+ int size,
+ lwm2m_data_t * tlvP,
+ uint8_t ** bufferP)
{
- size_t index;
+ int index;
size_t head;
uint8_t bufferJSON[PRV_JSON_BUFFER_SIZE];
uint8_t baseUriStr[URI_MAX_STRING_LEN];
int baseUriLen;
uri_depth_t rootLevel;
- size_t num;
+ int num;
lwm2m_data_t * targetP;
LOG_ARG("size: %d", size);
LOG_URI(uriP);
- if (size == 0 || tlvP == NULL) return 0;
+ if (size != 0 && tlvP == NULL) return -1;
baseUriLen = uri_toString(uriP, baseUriStr, URI_MAX_STRING_LEN, &rootLevel);
- if (baseUriLen < 0) return 0;
+ if (baseUriLen < 0) return -1;
num = prv_findAndCheckData(uriP, rootLevel, size, tlvP, &targetP);
- if (num == 0) return num;
+ if (num < 0) return -1;
while (num == 1
&& (targetP->type == LWM2M_TYPE_OBJECT
if (head + JSON_FOOTER_SIZE - 1 > PRV_JSON_BUFFER_SIZE) return 0;
- memcpy(bufferJSON + head - 1, JSON_FOOTER, JSON_FOOTER_SIZE);
- head = head - 1 + JSON_FOOTER_SIZE;
+ if (num > 0) head = head - 1;
+
+ memcpy(bufferJSON + head, JSON_FOOTER, JSON_FOOTER_SIZE);
+ head = head + JSON_FOOTER_SIZE;
*bufferP = (uint8_t *)lwm2m_malloc(head);
if (*bufferP == NULL) return 0;
{
memset(contextP, 0, sizeof(lwm2m_context_t));
contextP->userData = userData;
- srand(time(NULL));
+ srand((int)lwm2m_gettime());
contextP->nextMID = rand();
}
{
lwm2m_free(serverP->location);
}
+ free_block1_buffer(serverP->block1Data);
lwm2m_free(serverP);
}
}
}
-static void prv_deleteBootstrapServerList(lwm2m_context_t * contextP)
+static void prv_deleteBootstrapServer(lwm2m_server_t * serverP)
{
- LWM2M_LIST_FREE(contextP->bootstrapServerList);
- contextP->bootstrapServerList = NULL;
+ // TODO should we free location as in prv_deleteServer ?
+ // TODO should we parse transaction and observation to remove the ones related to this server ?
+ free_block1_buffer(serverP->block1Data);
+ lwm2m_free(serverP);
+}
+
+static void prv_deleteBootstrapServerList(lwm2m_context_t * context)
+{
+ while (NULL != context->bootstrapServerList)
+ {
+ lwm2m_server_t * server;
+ server = context->bootstrapServerList;
+ context->bootstrapServerList = server->next;
+ prv_deleteBootstrapServer(server);
+ }
}
static void prv_deleteObservedList(lwm2m_context_t * contextP)
if (!targetP->dirty)
{
// TODO: Should we revert the status to STATE_DEREGISTERED ?
- contextP->serverList = (lwm2m_server_t *)LWM2M_LIST_ADD(contextP->serverList, targetP);;
+ contextP->serverList = (lwm2m_server_t *)LWM2M_LIST_ADD(contextP->serverList, targetP);
}
else
{
int lwm2m_remove_object(lwm2m_context_t * contextP,
uint16_t id)
{
- uint16_t i;
lwm2m_object_t * targetP;
LOG_ARG("ID: %d", id);
#define COAP_202_DELETED (uint8_t)0x42
#define COAP_204_CHANGED (uint8_t)0x44
#define COAP_205_CONTENT (uint8_t)0x45
+#define COAP_231_CONTINUE (uint8_t)0x5F
#define COAP_400_BAD_REQUEST (uint8_t)0x80
#define COAP_401_UNAUTHORIZED (uint8_t)0x81
#define COAP_402_BAD_OPTION (uint8_t)0x82
#define COAP_404_NOT_FOUND (uint8_t)0x84
#define COAP_405_METHOD_NOT_ALLOWED (uint8_t)0x85
#define COAP_406_NOT_ACCEPTABLE (uint8_t)0x86
+#define COAP_408_REQ_ENTITY_INCOMPLETE (uint8_t)0x88
+#define COAP_412_PRECONDITION_FAILED (uint8_t)0x8C
+#define COAP_413_ENTITY_TOO_LARGE (uint8_t)0x8D
#define COAP_500_INTERNAL_SERVER_ERROR (uint8_t)0xA0
#define COAP_501_NOT_IMPLEMENTED (uint8_t)0xA1
#define COAP_503_SERVICE_UNAVAILABLE (uint8_t)0xA3
#define LWM2M_FIRMWARE_UPDATE_OBJECT_ID 5
#define LWM2M_LOCATION_OBJECT_ID 6
#define LWM2M_CONN_STATS_OBJECT_ID 7
-#define LWM2M_POWER_MONITOR_OBJECT_ID 8
/*
* Ressource IDs for the LWM2M Security Object
#define LWM2M_SECURITY_SMS_SERVER_NUMBER_ID 9
#define LWM2M_SECURITY_SHORT_SERVER_ID 10
#define LWM2M_SECURITY_HOLD_OFF_ID 11
+#define LWM2M_SECURITY_BOOTSTRAP_TIMEOUT_ID 12
/*
* Ressource IDs for the LWM2M Server Object
size_t count;
lwm2m_data_t * array;
} asChildren;
+ struct
+ {
+ uint16_t objectId;
+ uint16_t objectInstanceId;
+ } asObjLink;
} value;
};
LWM2M_CONTENT_TEXT = 0, // Also used as undefined
LWM2M_CONTENT_LINK = 40,
LWM2M_CONTENT_OPAQUE = 42,
- LWM2M_CONTENT_TLV = 1542, // Temporary value
- LWM2M_CONTENT_JSON = 1543 // Temporary value
+ LWM2M_CONTENT_TLV_OLD = 1542, // Keep old value for backward-compatibility
+ LWM2M_CONTENT_TLV = 11542,
+ LWM2M_CONTENT_JSON_OLD = 1543, // Keep old value for backward-compatibility
+ LWM2M_CONTENT_JSON = 11543
} lwm2m_media_type_t;
lwm2m_data_t * lwm2m_data_new(int size);
int lwm2m_data_parse(lwm2m_uri_t * uriP, uint8_t * buffer, size_t bufferLen, lwm2m_media_type_t format, lwm2m_data_t ** dataP);
-size_t lwm2m_data_serialize(lwm2m_uri_t * uriP, int size, lwm2m_data_t * dataP, lwm2m_media_type_t * formatP, uint8_t ** bufferP);
+int lwm2m_data_serialize(lwm2m_uri_t * uriP, int size, lwm2m_data_t * dataP, lwm2m_media_type_t * formatP, uint8_t ** bufferP);
void lwm2m_data_free(int size, lwm2m_data_t * dataP);
void lwm2m_data_encode_string(const char * string, lwm2m_data_t * dataP);
int lwm2m_data_decode_float(const lwm2m_data_t * dataP, double * valueP);
void lwm2m_data_encode_bool(bool value, lwm2m_data_t * dataP);
int lwm2m_data_decode_bool(const lwm2m_data_t * dataP, bool * valueP);
+void lwm2m_data_encode_objlink(uint16_t objectId, uint16_t objectInstanceId, lwm2m_data_t * dataP);
void lwm2m_data_encode_instances(lwm2m_data_t * subDataP, size_t count, lwm2m_data_t * dataP);
void lwm2m_data_include(lwm2m_data_t * subDataP, size_t count, lwm2m_data_t * dataP);
typedef enum
{
- STATE_DEREGISTERED = 0, // not registered or boostrap not started
- STATE_REG_PENDING, // registration pending
- STATE_REGISTERED, // successfully registered
- STATE_REG_FAILED, // last registration failed
- STATE_REG_UPDATE_PENDING, // registration update pending
- STATE_DEREG_PENDING, // deregistration pending
- STATE_BS_HOLD_OFF, // bootstrap hold off time
- STATE_BS_INITIATED, // bootstrap request sent
- STATE_BS_PENDING, // boostrap on going
- STATE_BS_FINISHED, // bootstrap done
- STATE_BS_FAILED, // bootstrap failed
+ STATE_DEREGISTERED = 0, // not registered or boostrap not started
+ STATE_REG_PENDING, // registration pending
+ STATE_REGISTERED, // successfully registered
+ STATE_REG_FAILED, // last registration failed
+ STATE_REG_UPDATE_PENDING, // registration update pending
+ STATE_REG_UPDATE_NEEDED, // registration update required
+ STATE_REG_FULL_UPDATE_NEEDED, // registration update with objects required
+ STATE_DEREG_PENDING, // deregistration pending
+ STATE_BS_HOLD_OFF, // bootstrap hold off time
+ STATE_BS_INITIATED, // bootstrap request sent
+ STATE_BS_PENDING, // boostrap ongoing
+ STATE_BS_FINISHING, // boostrap finish received
+ STATE_BS_FINISHED, // bootstrap done
+ STATE_BS_FAILING, // bootstrap error occurred
+ STATE_BS_FAILED, // bootstrap failed
} lwm2m_status_t;
typedef enum
BINDING_UQS // UDP queue mode plus SMS
} lwm2m_binding_t;
+/*
+ * LWM2M block1 data
+ *
+ * Temporary data needed to handle block1 request.
+ * Currently support only one block1 request by server.
+ */
+typedef struct _lwm2m_block1_data_ lwm2m_block1_data_t;
+
+struct _lwm2m_block1_data_
+{
+ uint8_t * block1buffer; // data buffer
+ size_t block1bufferSize; // buffer size
+ uint16_t lastmid; // mid of the last message received
+};
+
typedef struct _lwm2m_server_
{
- struct _lwm2m_server_ * next; // matches lwm2m_list_t::next
- uint16_t secObjInstID; // matches lwm2m_list_t::id
- uint16_t shortID; // servers short ID, may be 0 for bootstrap server
- time_t lifetime; // lifetime of the registration in sec or 0 if default value (86400 sec), also used as hold off time for bootstrap servers
- time_t registration; // date of the last registration in sec or end of client hold off time for bootstrap servers
- lwm2m_binding_t binding; // client connection mode with this server
- void * sessionH;
- lwm2m_status_t status;
- char * location;
- bool dirty;
+ struct _lwm2m_server_ * next; // matches lwm2m_list_t::next
+ uint16_t secObjInstID; // matches lwm2m_list_t::id
+ uint16_t shortID; // servers short ID, may be 0 for bootstrap server
+ time_t lifetime; // lifetime of the registration in sec or 0 if default value (86400 sec), also used as hold off time for bootstrap servers
+ time_t registration; // date of the last registration in sec or end of client hold off time for bootstrap servers
+ lwm2m_binding_t binding; // client connection mode with this server
+ void * sessionH;
+ lwm2m_status_t status;
+ char * location;
+ bool dirty;
+ lwm2m_block1_data_t * block1Data; // buffer to handle block1 data, should be replace by a list to support several block1 transfer by server.
} lwm2m_server_t;
* Adaptation of Erbium's coap_transaction_t
*/
-typedef enum
-{
- ENDPOINT_UNKNOWN = 0,
- ENDPOINT_CLIENT,
- ENDPOINT_SERVER
-} lwm2m_endpoint_type_t;
-
typedef struct _lwm2m_transaction_ lwm2m_transaction_t;
typedef void (*lwm2m_transaction_callback_t) (lwm2m_transaction_t * transacP, void * message);
{
lwm2m_transaction_t * next; // matches lwm2m_list_t::next
uint16_t mID; // matches lwm2m_list_t::id
- lwm2m_endpoint_type_t peerType;
- void * peerP;
+ void * peerH;
uint8_t ack_received; // indicates, that the ACK was received
time_t response_timeout; // timeout to wait for response, if token is used. When 0, use calculated acknowledge timeout.
uint8_t retrans_counter;
LOG_ARG("Code: %02X, server status: %s", message->code, STR_STATUS(serverP->status));
LOG_URI(uriP);
- format = utils_convertMediaType(message->content_type);
+
+ if (IS_OPTION(message, COAP_OPTION_CONTENT_TYPE))
+ {
+ format = utils_convertMediaType(message->content_type);
+ }
+ else
+ {
+ format = LWM2M_CONTENT_TLV;
+ }
if (uriP->objectId == LWM2M_SECURITY_OBJECT_ID)
{
}
if (serverP->status != STATE_REGISTERED
- && serverP->status != STATE_REG_UPDATE_PENDING)
+ && serverP->status != STATE_REG_UPDATE_NEEDED
+ && serverP->status != STATE_REG_FULL_UPDATE_NEEDED
+ && serverP->status != STATE_REG_UPDATE_PENDING)
{
return COAP_IGNORE;
}
{
uint8_t * buffer = NULL;
size_t length = 0;
+ int res;
if (IS_OPTION(message, COAP_OPTION_OBSERVE))
{
result = observe_handleRequest(contextP, uriP, serverP, size, dataP, message, response);
if (COAP_205_CONTENT == result)
{
- length = lwm2m_data_serialize(uriP, size, dataP, &format, &buffer);
- if (length == 0)
+ res = lwm2m_data_serialize(uriP, size, dataP, &format, &buffer);
+ if (res < 0)
{
result = COAP_500_INTERNAL_SERVER_ERROR;
}
else
{
+ length = (size_t)res;
LOG_ARG("Observe Request[/%d/%d/%d]: %.*s\n", uriP->objectId, uriP->instanceId, uriP->resourceId, length, buffer);
}
}
&& message->accept_num == 1
&& message->accept[0] == APPLICATION_LINK_FORMAT)
{
- format = APPLICATION_LINK_FORMAT;
- result = object_discover(contextP, uriP, &buffer, &length);
+ format = LWM2M_CONTENT_LINK;
+ result = object_discover(contextP, uriP, serverP, &buffer, &length);
}
else
{
+ if (IS_OPTION(message, COAP_OPTION_ACCEPT))
+ {
+ format = utils_convertMediaType(message->accept[0]);
+ }
+
result = object_read(contextP, uriP, &format, &buffer, &length);
}
if (COAP_205_CONTENT == result)
if (message == NULL)
{
- dataP->callback(((lwm2m_client_t*)transacP->peerP)->internalID,
+ dataP->callback(dataP->clientID,
&dataP->uri,
COAP_503_SERVICE_UNAVAILABLE,
LWM2M_CONTENT_TEXT, NULL, 0,
lwm2m_free(locationString);
}
- dataP->callback(((lwm2m_client_t*)transacP->peerP)->internalID,
+ dataP->callback(dataP->clientID,
&dataP->uri,
packet->code,
utils_convertMediaType(packet->content_type),
clientP = (lwm2m_client_t *)lwm2m_list_find((lwm2m_list_t *)contextP->clientList, clientID);
if (clientP == NULL) return COAP_404_NOT_FOUND;
- transaction = transaction_new(COAP_TYPE_CON, method, clientP->altPath, uriP, contextP->nextMID++, 4, NULL, ENDPOINT_CLIENT, (void *)clientP);
+ transaction = transaction_new(clientP->sessionH, method, clientP->altPath, uriP, contextP->nextMID++, 4, NULL);
if (transaction == NULL) return COAP_500_INTERNAL_SERVER_ERROR;
- if (buffer != NULL)
+ if (method == COAP_GET)
+ {
+ coap_set_header_accept(transaction->message, format);
+ }
+ else if (buffer != NULL)
{
coap_set_header_content_type(transaction->message, format);
// TODO: Take care of fragmentation
return COAP_500_INTERNAL_SERVER_ERROR;
}
memcpy(&dataP->uri, uriP, sizeof(lwm2m_uri_t));
+ dataP->clientID = clientP->internalID;
dataP->callback = callback;
dataP->userData = userData;
lwm2m_result_callback_t callback,
void * userData)
{
+ lwm2m_client_t * clientP;
+ lwm2m_media_type_t format;
+
LOG_ARG("clientID: %d", clientID);
LOG_URI(uriP);
+
+ clientP = (lwm2m_client_t *)lwm2m_list_find((lwm2m_list_t *)contextP->clientList, clientID);
+ if (clientP == NULL) return COAP_404_NOT_FOUND;
+
+ if (clientP->supportJSON == true)
+ {
+ format = LWM2M_CONTENT_JSON;
+ }
+ else
+ {
+ format = LWM2M_CONTENT_TLV;
+ }
+
return prv_makeOperation(contextP, clientID, uriP,
- COAP_GET,
- LWM2M_CONTENT_TEXT,
- NULL, 0,
- callback, userData);
+ COAP_GET,
+ format,
+ NULL, 0,
+ callback, userData);
}
int lwm2m_dm_write(lwm2m_context_t * contextP,
{
LOG_ARG("clientID: %d, format: %s, length: %d", clientID, STR_MEDIA_TYPE(format), length);
LOG_URI(uriP);
+
if (LWM2M_URI_IS_SET_INSTANCE(uriP)
|| length == 0)
{
clientP = (lwm2m_client_t *)lwm2m_list_find((lwm2m_list_t *)contextP->clientList, clientID);
if (clientP == NULL) return COAP_404_NOT_FOUND;
- transaction = transaction_new(COAP_TYPE_CON, COAP_PUT, clientP->altPath, uriP, contextP->nextMID++, 4, NULL, ENDPOINT_CLIENT, (void *)clientP);
+ transaction = transaction_new(clientP->sessionH, COAP_PUT, clientP->altPath, uriP, contextP->nextMID++, 4, NULL);
if (transaction == NULL) return COAP_500_INTERNAL_SERVER_ERROR;
if (callback != NULL)
return COAP_500_INTERNAL_SERVER_ERROR;
}
memcpy(&dataP->uri, uriP, sizeof(lwm2m_uri_t));
+ dataP->clientID = clientP->internalID;
dataP->callback = callback;
dataP->userData = userData;
clientP = (lwm2m_client_t *)lwm2m_list_find((lwm2m_list_t *)contextP->clientList, clientID);
if (clientP == NULL) return COAP_404_NOT_FOUND;
- transaction = transaction_new(COAP_TYPE_CON, COAP_GET, clientP->altPath, uriP, contextP->nextMID++, 4, NULL, ENDPOINT_CLIENT, (void *)clientP);
+ transaction = transaction_new(clientP->sessionH, COAP_GET, clientP->altPath, uriP, contextP->nextMID++, 4, NULL);
if (transaction == NULL) return COAP_500_INTERNAL_SERVER_ERROR;
coap_set_header_accept(transaction->message, LWM2M_CONTENT_LINK);
return COAP_500_INTERNAL_SERVER_ERROR;
}
memcpy(&dataP->uri, uriP, sizeof(lwm2m_uri_t));
+ dataP->clientID = clientP->internalID;
dataP->callback = callback;
dataP->userData = userData;
targetP = (lwm2m_object_t *)LWM2M_LIST_FIND(contextP->objectList, uriP->objectId);
if (NULL == targetP) return COAP_404_NOT_FOUND;
if (NULL == targetP->readFunc) return COAP_405_METHOD_NOT_ALLOWED;
- if (targetP->instanceList == NULL) return COAP_404_NOT_FOUND;
if (LWM2M_URI_IS_SET_INSTANCE(uriP))
{
lwm2m_list_t * instanceP;
int i;
+ result = COAP_205_CONTENT;
+
*sizeP = 0;
for (instanceP = targetP->instanceList; instanceP != NULL ; instanceP = instanceP->next)
{
(*sizeP)++;
}
- *dataP = lwm2m_data_new(*sizeP);
- if (*dataP == NULL) return COAP_500_INTERNAL_SERVER_ERROR;
-
- result = COAP_205_CONTENT;
- instanceP = targetP->instanceList;
- i = 0;
- while (instanceP != NULL && result == COAP_205_CONTENT)
+ if (*sizeP == 0)
{
- result = targetP->readFunc(instanceP->id, (int*)&((*dataP)[i].value.asChildren.count), &((*dataP)[i].value.asChildren.array), targetP);
- (*dataP)[i].type = LWM2M_TYPE_OBJECT_INSTANCE;
- (*dataP)[i].id = instanceP->id;
- i++;
- instanceP = instanceP->next;
+ *dataP = NULL;
+ }
+ else
+ {
+ *dataP = lwm2m_data_new(*sizeP);
+ if (*dataP == NULL) return COAP_500_INTERNAL_SERVER_ERROR;
+
+ instanceP = targetP->instanceList;
+ i = 0;
+ while (instanceP != NULL && result == COAP_205_CONTENT)
+ {
+ result = targetP->readFunc(instanceP->id, (int*)&((*dataP)[i].value.asChildren.count), &((*dataP)[i].value.asChildren.array), targetP);
+ (*dataP)[i].type = LWM2M_TYPE_OBJECT_INSTANCE;
+ (*dataP)[i].id = instanceP->id;
+ i++;
+ instanceP = instanceP->next;
+ }
}
}
coap_status_t result;
lwm2m_data_t * dataP = NULL;
int size = 0;
+ int res;
LOG_URI(uriP);
result = object_readData(contextP, uriP, &size, &dataP);
if (result == COAP_205_CONTENT)
{
- *lengthP = lwm2m_data_serialize(uriP, size, dataP, formatP, bufferP);
- if (*lengthP == 0)
+ res = lwm2m_data_serialize(uriP, size, dataP, formatP, bufferP);
+ if (res < 0)
{
- if (*formatP != LWM2M_CONTENT_TEXT
- || size != 1
- || dataP->type != LWM2M_TYPE_STRING
- || dataP->value.asBuffer.length != 0)
- {
- result = COAP_500_INTERNAL_SERVER_ERROR;
- }
+ result = COAP_500_INTERNAL_SERVER_ERROR;
+ }
+ else
+ {
+ *lengthP = (size_t)res;
}
}
lwm2m_data_free(size, dataP);
targetP = (lwm2m_object_t *)LWM2M_LIST_FIND(contextP->objectList, uriP->objectId);
if (NULL == targetP) return COAP_404_NOT_FOUND;
if (NULL == targetP->executeFunc) return COAP_405_METHOD_NOT_ALLOWED;
+ if (NULL == lwm2m_list_find(targetP->instanceList, uriP->instanceId)) return COAP_404_NOT_FOUND;
return targetP->executeFunc(uriP->instanceId, uriP->resourceId, buffer, length, targetP);
}
uint8_t result;
LOG_URI(uriP);
+
if (length == 0 || buffer == 0)
{
return COAP_400_BAD_REQUEST;
coap_status_t object_discover(lwm2m_context_t * contextP,
lwm2m_uri_t * uriP,
+ lwm2m_server_t * serverP,
uint8_t ** bufferP,
size_t * lengthP)
{
targetP = (lwm2m_object_t *)LWM2M_LIST_FIND(contextP->objectList, uriP->objectId);
if (NULL == targetP) return COAP_404_NOT_FOUND;
if (NULL == targetP->discoverFunc) return COAP_501_NOT_IMPLEMENTED;
- if (targetP->instanceList == NULL) return COAP_404_NOT_FOUND;
if (LWM2M_URI_IS_SET_INSTANCE(uriP))
{
if (dataP == NULL) return COAP_500_INTERNAL_SERVER_ERROR;
dataP->id = uriP->resourceId;
- uriP->flag &= ~LWM2M_URI_FLAG_RESOURCE_ID;
}
result = targetP->discoverFunc(uriP->instanceId, &size, &dataP, targetP);
lwm2m_list_t * instanceP;
int i;
+ result = COAP_205_CONTENT;
+
size = 0;
for (instanceP = targetP->instanceList; instanceP != NULL ; instanceP = instanceP->next)
{
size++;
}
- dataP = lwm2m_data_new(size);
- if (dataP == NULL) return COAP_500_INTERNAL_SERVER_ERROR;
-
- result = COAP_205_CONTENT;
- instanceP = targetP->instanceList;
- i = 0;
- while (instanceP != NULL && result == COAP_205_CONTENT)
+ if (size != 0)
{
- result = targetP->discoverFunc(instanceP->id, (int*)&(dataP[i].value.asChildren.count), &(dataP[i].value.asChildren.array), targetP);
- dataP[i].type = LWM2M_TYPE_OBJECT_INSTANCE;
- dataP[i].id = instanceP->id;
- i++;
- instanceP = instanceP->next;
+ dataP = lwm2m_data_new(size);
+ if (dataP == NULL) return COAP_500_INTERNAL_SERVER_ERROR;
+
+ instanceP = targetP->instanceList;
+ i = 0;
+ while (instanceP != NULL && result == COAP_205_CONTENT)
+ {
+ result = targetP->discoverFunc(instanceP->id, (int*)&(dataP[i].value.asChildren.count), &(dataP[i].value.asChildren.array), targetP);
+ dataP[i].type = LWM2M_TYPE_OBJECT_INSTANCE;
+ dataP[i].id = instanceP->id;
+ i++;
+ instanceP = instanceP->next;
+ }
}
}
{
int len;
- len = discover_serialize(contextP, uriP, size, dataP, bufferP);
+ len = discover_serialize(contextP, uriP, serverP, size, dataP, bufferP);
if (len <= 0) result = COAP_500_INTERNAL_SERVER_ERROR;
else *lengthP = len;
}
return -1;
}
targetP->lifetime = value;
- dataP[1].value.asBuffer.buffer = lwm2m_malloc(sizeof(uint8_t));
- *(dataP[1].value.asBuffer.buffer) = 'U';
- dataP[1].value.asBuffer.length = 1;
targetP->binding = utils_stringToBinding(dataP[1].value.asBuffer.buffer, dataP[1].value.asBuffer.length);
lwm2m_list_t * securityInstP; // instanceID of the server in the LWM2M Security Object
LOG("Entering");
+
for (objectP = contextP->objectList; objectP != NULL; objectP = objectP->next)
{
if (objectP->objID == LWM2M_SECURITY_OBJECT_ID)
{
bool notify = false;
-#ifdef LWM2M_CLIENT_SHELL_ON
if (watcherP->update == true)
-#endif
{
// value changed, should we notify the server ?
}
if (watcherP->parameters != NULL
- && (watcherP->parameters->toSet & LWM2M_ATTR_FLAG_MIN_PERIOD) != 0
- && (notify == true))
+ && (watcherP->parameters->toSet & LWM2M_ATTR_FLAG_MIN_PERIOD) != 0)
{
LOG_ARG("Checking minimal period (%d s)", watcherP->parameters->minPeriod);
if (*timeoutP > interval) *timeoutP = interval;
notify = false;
}
-/***
else
{
LOG("Notify on minimal period");
notify = true;
}
-***/
}
}
{
if (dataP != NULL)
{
- length = lwm2m_data_serialize(&targetP->uri, size, dataP, &format, &buffer);
- if (length == 0) break;
+ int res;
+
+ res = lwm2m_data_serialize(&targetP->uri, size, dataP, &format, &buffer);
+ if (res < 0)
+ {
+ break;
+ }
+ else
+ {
+ length = (size_t)res;
+ }
+
}
else
{
return targetP;
}
-void observe_remove(lwm2m_client_t * clientP,
- lwm2m_observation_t * observationP)
+void observe_remove(lwm2m_observation_t * observationP)
{
LOG("Entering");
- clientP->observationList = (lwm2m_observation_t *) LWM2M_LIST_RM(clientP->observationList, observationP->id, NULL);
+ observationP->clientP->observationList = (lwm2m_observation_t *) LWM2M_LIST_RM(observationP->clientP->observationList, observationP->id, NULL);
lwm2m_free(observationP);
}
{
case STATE_DEREG_PENDING:
// Observation was canceled by the user.
- observe_remove(((lwm2m_client_t*)transacP->peerP), observationP);
+ observe_remove(observationP);
return;
case STATE_REG_PENDING:
if (code != COAP_205_CONTENT)
{
- observationP->callback(((lwm2m_client_t*)transacP->peerP)->internalID,
+ observationP->callback(observationP->clientP->internalID,
&observationP->uri,
code,
LWM2M_CONTENT_TEXT, NULL, 0,
observationP->userData);
- observe_remove(((lwm2m_client_t*)transacP->peerP), observationP);
+ observe_remove(observationP);
}
else
{
- observationP->callback(((lwm2m_client_t*)transacP->peerP)->internalID,
+ observationP->callback(observationP->clientP->internalID,
&observationP->uri,
0,
packet->content_type, packet->payload, packet->payload_len,
if (code != COAP_205_CONTENT)
{
- cancelP->callbackP(((lwm2m_client_t*)transacP->peerP)->internalID,
+ cancelP->callbackP(cancelP->observationP->clientP->internalID,
&cancelP->observationP->uri,
code,
LWM2M_CONTENT_TEXT, NULL, 0,
}
else
{
- cancelP->callbackP(((lwm2m_client_t*)transacP->peerP)->internalID,
+ cancelP->callbackP(cancelP->observationP->clientP->internalID,
&cancelP->observationP->uri,
0,
packet->content_type, packet->payload, packet->payload_len,
cancelP->userDataP);
}
- observe_remove(((lwm2m_client_t*)transacP->peerP), cancelP->observationP);
+ observe_remove(cancelP->observationP);
lwm2m_free(cancelP);
}
token[2] = observationP->id >> 8;
token[3] = observationP->id & 0xFF;
- transactionP = transaction_new(COAP_TYPE_CON, COAP_GET, clientP->altPath, uriP, contextP->nextMID++, 4, token, ENDPOINT_CLIENT, (void *)clientP);
+ transactionP = transaction_new(clientP->sessionH, COAP_GET, clientP->altPath, uriP, contextP->nextMID++, 4, token);
if (transactionP == NULL)
{
lwm2m_free(observationP);
lwm2m_transaction_t * transactionP;
cancellation_data_t * cancelP;
- transactionP = transaction_new(COAP_TYPE_CON, COAP_GET, clientP->altPath, uriP, contextP->nextMID++, 0, NULL, ENDPOINT_CLIENT, (void *)clientP);
+ transactionP = transaction_new(clientP->sessionH, COAP_GET, clientP->altPath, uriP, contextP->nextMID++, 0, NULL);
if (transactionP == NULL)
{
return COAP_500_INTERNAL_SERVER_ERROR;
new_offset = block_offset;
}
- coap_error_code = handle_request(contextP, fromSessionH, message, response);
- if (coap_error_code==NO_ERROR)
+ /* handle block1 option */
+ if (IS_OPTION(message, COAP_OPTION_BLOCK1))
{
- /* Apply blockwise transfers. */
- if ( IS_OPTION(message, COAP_OPTION_BLOCK1) && response->code<COAP_400_BAD_REQUEST && !IS_OPTION(response, COAP_OPTION_BLOCK1) )
+#ifdef LWM2M_CLIENT_MODE
+ // get server
+ lwm2m_server_t * serverP;
+ serverP = utils_findServer(contextP, fromSessionH);
+#ifdef LWM2M_BOOTSTRAP
+ if (serverP == NULL)
+ {
+ serverP = utils_findBootstrapServer(contextP, fromSessionH);
+ }
+#endif
+ if (serverP == NULL)
{
- LOG("Block1 NOT IMPLEMENTED");
+ coap_error_code = COAP_500_INTERNAL_SERVER_ERROR;
+ }
+ else
+ {
+ uint32_t block1_num;
+ uint8_t block1_more;
+ uint16_t block1_size;
+ uint8_t * complete_buffer = NULL;
+ size_t complete_buffer_size;
+
+ // parse block1 header
+ coap_get_header_block1(message, &block1_num, &block1_more, &block1_size, NULL);
+ LOG_ARG("Blockwise: block1 request NUM %u (SZX %u/ SZX Max%u) MORE %u", block1_num, block1_size, REST_MAX_CHUNK_SIZE, block1_more);
- coap_error_code = COAP_501_NOT_IMPLEMENTED;
+ // handle block 1
+ coap_error_code = coap_block1_handler(&serverP->block1Data, message->mid, message->payload, message->payload_len, block1_size, block1_num, block1_more, &complete_buffer, &complete_buffer_size);
+
+ // if payload is complete, replace it in the coap message.
+ if (coap_error_code == NO_ERROR)
+ {
+ message->payload = complete_buffer;
+ message->payload_len = complete_buffer_size;
+ }
+ else if (coap_error_code == COAP_231_CONTINUE)
+ {
+ block1_size = MIN(block1_size, REST_MAX_CHUNK_SIZE);
+ coap_set_header_block1(response,block1_num, block1_more,block1_size);
+ }
}
- else if ( IS_OPTION(message, COAP_OPTION_BLOCK2) )
+#else
+ coap_error_code = COAP_501_NOT_IMPLEMENTED;
+#endif
+ }
+ if (coap_error_code == NO_ERROR)
+ {
+ coap_error_code = handle_request(contextP, fromSessionH, message, response);
+ }
+ if (coap_error_code==NO_ERROR)
+ {
+ if ( IS_OPTION(message, COAP_OPTION_BLOCK2) )
{
/* unchanged new_offset indicates that resource is unaware of blockwise transfer */
if (new_offset==block_offset)
int index;
int res;
- index = utils_stringCopy(buffer, length, "?ep=");
+ index = utils_stringCopy(buffer, length, QUERY_STARTER QUERY_VERSION_FULL QUERY_DELIMITER QUERY_NAME);
if (index < 0) return 0;
res = utils_stringCopy(buffer + index, length - index, contextP->endpointName);
if (res < 0) return 0;
void * message)
{
coap_packet_t * packet = (coap_packet_t *)message;
- lwm2m_server_t * targetP = (lwm2m_server_t *)(transacP->peerP);
+ lwm2m_server_t * targetP = (lwm2m_server_t *)(transacP->userData);
if (targetP->status == STATE_REG_PENDING)
{
if (NULL == server->sessionH) return COAP_503_SERVICE_UNAVAILABLE;
- transaction = transaction_new(COAP_TYPE_CON, COAP_POST, NULL, NULL, contextP->nextMID++, 4, NULL, ENDPOINT_SERVER, (void *)server);
+ transaction = transaction_new(server->sessionH, COAP_POST, NULL, NULL, contextP->nextMID++, 4, NULL);
if (transaction == NULL) return COAP_500_INTERNAL_SERVER_ERROR;
coap_set_header_uri_path(transaction->message, "/"URI_REGISTRATION_SEGMENT);
void * message)
{
coap_packet_t * packet = (coap_packet_t *)message;
- lwm2m_server_t * targetP = (lwm2m_server_t *)(transacP->peerP);
+ lwm2m_server_t * targetP = (lwm2m_server_t *)(transacP->userData);
if (targetP->status == STATE_REG_UPDATE_PENDING)
{
time_t tv_sec = lwm2m_gettime();
if (tv_sec >= 0)
{
- printf("update register\n");
targetP->registration = tv_sec;
}
if (packet != NULL && packet->code == COAP_204_CHANGED)
uint8_t payload[512];
int payload_length;
- transaction = transaction_new(COAP_TYPE_CON, COAP_POST, NULL, NULL, contextP->nextMID++, 4, NULL, ENDPOINT_SERVER, (void *)server);
+ transaction = transaction_new(server->sessionH, COAP_POST, NULL, NULL, contextP->nextMID++, 4, NULL);
if (transaction == NULL) return COAP_500_INTERNAL_SERVER_ERROR;
coap_set_header_uri_path(transaction->message, server->location);
if (targetP->shortID == shortServerID)
{
// found the server, trigger the update transaction
- if (targetP->status == STATE_REGISTERED)
+ if (targetP->status == STATE_REGISTERED
+ || targetP->status == STATE_REG_UPDATE_PENDING)
{
- return prv_updateRegistration(contextP, targetP, withObjects);
+ if (withObjects == true)
+ {
+ targetP->status = STATE_REG_FULL_UPDATE_NEEDED;
+ }
+ else
+ {
+ targetP->status = STATE_REG_UPDATE_NEEDED;
+ }
+ return COAP_NO_ERROR;
+ }
+ else if ((targetP->status == STATE_REG_FULL_UPDATE_NEEDED)
+ || (targetP->status == STATE_REG_UPDATE_NEEDED))
+ {
+ // if REG (FULL) UPDATE is already set, returns COAP_NO_ERROR
+ if (withObjects == true)
+ {
+ targetP->status = STATE_REG_FULL_UPDATE_NEEDED;
+ }
+ return COAP_NO_ERROR;
}
else
{
}
else
{
- if (targetP->status == STATE_REGISTERED)
+ if (targetP->status == STATE_REGISTERED
+ || targetP->status == STATE_REG_UPDATE_PENDING)
{
- result = prv_updateRegistration(contextP, targetP, withObjects);
+ if (withObjects == true)
+ {
+ targetP->status = STATE_REG_FULL_UPDATE_NEEDED;
+ }
+ else
+ {
+ targetP->status = STATE_REG_UPDATE_NEEDED;
+ }
}
}
targetP = targetP->next;
switch (targetP->status)
{
case STATE_REGISTERED:
+ case STATE_REG_UPDATE_NEEDED:
+ case STATE_REG_FULL_UPDATE_NEEDED:
case STATE_REG_UPDATE_PENDING:
if (reg_status == STATE_REG_FAILED)
{
{
lwm2m_server_t * targetP;
- targetP = (lwm2m_server_t *)(transacP->peerP);
+ targetP = (lwm2m_server_t *)(transacP->userData);
if (NULL != targetP)
{
if (targetP->status == STATE_DEREG_PENDING)
return;
}
- transaction = transaction_new(COAP_TYPE_CON, COAP_DELETE, NULL, NULL, contextP->nextMID++, 4, NULL, ENDPOINT_SERVER, (void *)serverP);
+ transaction = transaction_new(serverP->sessionH, COAP_DELETE, NULL, NULL, contextP->nextMID++, 4, NULL);
if (transaction == NULL) return;
coap_set_header_uri_path(transaction->message, serverP->location);
char ** nameP,
uint32_t * lifetimeP,
char ** msisdnP,
- lwm2m_binding_t * bindingP)
+ lwm2m_binding_t * bindingP,
+ char ** versionP)
{
*nameP = NULL;
*lifetimeP = 0;
*msisdnP = NULL;
*bindingP = BINDING_UNKNOWN;
+ *versionP = NULL;
while (query != NULL)
{
- if (lwm2m_strncmp((char *)query->data, QUERY_TEMPLATE, QUERY_LENGTH) == 0)
+ if (lwm2m_strncmp((char *)query->data, QUERY_NAME, QUERY_NAME_LEN) == 0)
{
if (*nameP != NULL) goto error;
- if (query->len == QUERY_LENGTH) goto error;
+ if (query->len == QUERY_NAME_LEN) goto error;
- *nameP = (char *)lwm2m_malloc(query->len - QUERY_LENGTH + 1);
+ *nameP = (char *)lwm2m_malloc(query->len - QUERY_NAME_LEN + 1);
if (*nameP != NULL)
{
- memcpy(*nameP, query->data + QUERY_LENGTH, query->len - QUERY_LENGTH);
- (*nameP)[query->len - QUERY_LENGTH] = 0;
+ memcpy(*nameP, query->data + QUERY_NAME_LEN, query->len - QUERY_NAME_LEN);
+ (*nameP)[query->len - QUERY_NAME_LEN] = 0;
}
}
else if (lwm2m_strncmp((char *)query->data, QUERY_SMS, QUERY_SMS_LEN) == 0)
}
else if (lwm2m_strncmp((char *)query->data, QUERY_VERSION, QUERY_VERSION_LEN) == 0)
{
- if ((query->len != QUERY_VERSION_FULL_LEN)
- || (lwm2m_strncmp((char *)query->data, QUERY_VERSION_FULL, QUERY_VERSION_FULL_LEN) != 0))
+ if (*versionP != NULL) goto error;
+ if (query->len == QUERY_VERSION_LEN) goto error;
+
+ *versionP = (char *)lwm2m_malloc(query->len - QUERY_VERSION_LEN + 1);
+ if (*versionP != NULL)
{
- goto error;
+ memcpy(*versionP, query->data + QUERY_VERSION_LEN, query->len - QUERY_VERSION_LEN);
+ (*versionP)[query->len - QUERY_VERSION_LEN] = 0;
}
}
else if (lwm2m_strncmp((char *)query->data, QUERY_BINDING, QUERY_BINDING_LEN) == 0)
error:
if (*nameP != NULL) lwm2m_free(*nameP);
if (*msisdnP != NULL) lwm2m_free(*msisdnP);
+ if (*versionP != NULL) lwm2m_free(*versionP);
return -1;
}
while (index < length && data[index] == ' ') index++;
if (index == length) return 0;
+ if (data[index] == REG_ATTR_SEPARATOR)
+ {
+ index++;
+ }
+ if (index == length) return 0;
+
*keyStart = index;
while (index < length && data[index] != REG_ATTR_EQUALS) index++;
uint32_t lifetime;
char * msisdn;
char * altPath;
+ char * version;
lwm2m_binding_t binding;
lwm2m_client_object_t * objects;
bool supportJSON;
lwm2m_client_t * clientP;
char location[MAX_LOCATION_LENGTH];
- if (0 != prv_getParameters(message->uri_query, &name, &lifetime, &msisdn, &binding))
+ if (0 != prv_getParameters(message->uri_query, &name, &lifetime, &msisdn, &binding, &version))
{
return COAP_400_BAD_REQUEST;
}
{
case 0:
// Register operation
-
- if (objects == NULL)
+ // Version is mandatory
+ if (version == NULL)
{
- lwm2m_free(name);
+ if (name != NULL) lwm2m_free(name);
if (msisdn != NULL) lwm2m_free(msisdn);
return COAP_400_BAD_REQUEST;
}
// Endpoint client name is mandatory
if (name == NULL)
{
+ lwm2m_free(version);
+ if (msisdn != NULL) lwm2m_free(msisdn);
+ return COAP_400_BAD_REQUEST;
+ }
+ // Object list is mandatory
+ if (objects == NULL)
+ {
+ lwm2m_free(version);
+ lwm2m_free(name);
if (msisdn != NULL) lwm2m_free(msisdn);
return COAP_400_BAD_REQUEST;
}
+ // version must be 1.0
+ if (strlen(version) != LWM2M_VERSION_LEN
+ || lwm2m_strncmp(version, LWM2M_VERSION, LWM2M_VERSION_LEN))
+ {
+ lwm2m_free(version);
+ lwm2m_free(name);
+ if (msisdn != NULL) lwm2m_free(msisdn);
+ return COAP_412_PRECONDITION_FAILED;
+ }
+
if (lifetime == 0)
{
lifetime = LWM2M_DEFAULT_LIFETIME;
COAP_202_DELETED,
LWM2M_CONTENT_TEXT, NULL, 0,
observationP->userData);
- observe_remove(clientP, observationP);
+ observe_remove(observationP);
}
else
{
COAP_202_DELETED,
LWM2M_CONTENT_TEXT, NULL, 0,
observationP->userData);
- observe_remove(clientP, observationP);
+ observe_remove(observationP);
}
}
}
time_t interval;
nextUpdate = targetP->lifetime;
- if (30 < nextUpdate)
+ if (COAP_MAX_TRANSMIT_WAIT < nextUpdate)
+ {
+ nextUpdate -= COAP_MAX_TRANSMIT_WAIT;
+ }
+ else
{
- nextUpdate -= 15; // update 15s earlier to have a chance to resend
+ nextUpdate = nextUpdate >> 1;
}
interval = targetP->registration + nextUpdate - currentTime;
if (0 >= interval)
{
LOG("Updating registration");
- printf("update regmsg\n");
prv_updateRegistration(contextP, targetP, false);
}
else if (interval < *timeoutP)
}
break;
+ case STATE_REG_UPDATE_NEEDED:
+ prv_updateRegistration(contextP, targetP, false);
+ break;
+
+ case STATE_REG_FULL_UPDATE_NEEDED:
+ prv_updateRegistration(contextP, targetP, true);
+ break;
+
case STATE_REG_FAILED:
if (targetP->sessionH != NULL)
{
}
-static size_t prv_getLength(int size,
- lwm2m_data_t * dataP)
+static int prv_getLength(int size,
+ lwm2m_data_t * dataP)
{
int length;
int i;
}
}
- if (length < 0)
- {
- return 0;
- }
- else
- {
- return (size_t)length;
- }
+ return length;
}
-size_t tlv_serialize(bool isResourceInstance,
- int size,
- lwm2m_data_t * dataP,
- uint8_t ** bufferP)
+int tlv_serialize(bool isResourceInstance,
+ int size,
+ lwm2m_data_t * dataP,
+ uint8_t ** bufferP)
{
- size_t length;
+ int length;
int index;
int i;
{
case LWM2M_TYPE_MULTIPLE_RESOURCE:
isInstance = true;
- // fall throught
+ // fall through
case LWM2M_TYPE_OBJECT_INSTANCE:
{
uint8_t * tmpBuffer;
- size_t tmpLength;
+ int res;
- tmpLength = tlv_serialize(isInstance, dataP[i].value.asChildren.count, dataP[i].value.asChildren.array, &tmpBuffer);
- if (tmpLength == 0)
+ res = tlv_serialize(isInstance, dataP[i].value.asChildren.count, dataP[i].value.asChildren.array, &tmpBuffer);
+ if (res < 0)
{
- length = 0;
+ length = -1;
}
else
{
+ size_t tmpLength;
+
+ tmpLength = (size_t)res;
headerLen = prv_createHeader(*bufferP + index, false, dataP[i].type, dataP[i].id, tmpLength);
index += headerLen;
- memcpy(*bufferP + index, tmpBuffer, tmpLength);
- index += tmpLength;
- lwm2m_free(tmpBuffer);
+ if (tmpLength > 0)
+ {
+ memcpy(*bufferP + index, tmpBuffer, tmpLength);
+ index += tmpLength;
+ lwm2m_free(tmpBuffer);
+ }
}
}
break;
- case LWM2M_TYPE_STRING:
- case LWM2M_TYPE_OPAQUE:
- headerLen = prv_createHeader(*bufferP + index, isInstance, dataP[i].type, dataP[i].id, dataP[i].value.asBuffer.length);
- if (headerLen == 0)
- {
- length = 0;
- }
- else
+ case LWM2M_TYPE_OBJECT_LINK:
{
+ int k;
+ uint8_t buf[4];
+ uint32_t v = dataP[i].value.asObjLink.objectId;
+ v <<= 16;
+ v |= dataP[i].value.asObjLink.objectInstanceId;
+ for (k = 3; k >= 0; --k) {
+ buf[k] = (uint8_t)(v & 0xFF);
+ v >>= 8;
+ }
+ // keep encoding as buffer
+ headerLen = prv_createHeader(*bufferP + index, isInstance, dataP[i].type, dataP[i].id, 4);
index += headerLen;
- memcpy(*bufferP + index, dataP[i].value.asBuffer.buffer, dataP[i].value.asBuffer.length);
- index += dataP[i].value.asBuffer.length;
+ memcpy(*bufferP + index, buf, 4);
+ index += 4;
}
break;
- case LWM2M_TYPE_OBJECT_LINK:
- // Object Link is a four-bytes integer
+ case LWM2M_TYPE_STRING:
+ case LWM2M_TYPE_OPAQUE:
+ headerLen = prv_createHeader(*bufferP + index, isInstance, dataP[i].type, dataP[i].id, dataP[i].value.asBuffer.length);
+ index += headerLen;
+ memcpy(*bufferP + index, dataP[i].value.asBuffer.buffer, dataP[i].value.asBuffer.length);
+ index += dataP[i].value.asBuffer.length;
+ break;
+
case LWM2M_TYPE_INTEGER:
{
size_t data_len;
data_len = utils_encodeInt(dataP[i].value.asInteger, data_buffer);
headerLen = prv_createHeader(*bufferP + index, isInstance, dataP[i].type, dataP[i].id, data_len);
- if (headerLen == 0)
- {
- length = 0;
- }
- else
- {
- index += headerLen;
- memcpy(*bufferP + index, data_buffer, data_len);
- index += data_len;
- }
+ index += headerLen;
+ memcpy(*bufferP + index, data_buffer, data_len);
+ index += data_len;
}
break;
data_len = utils_encodeFloat(dataP[i].value.asFloat, data_buffer);
headerLen = prv_createHeader(*bufferP + index, isInstance, dataP[i].type, dataP[i].id, data_len);
- if (headerLen == 0)
- {
- length = 0;
- }
- else
- {
- index += headerLen;
- memcpy(*bufferP + index, data_buffer, data_len);
- index += data_len;
- }
+ index += headerLen;
+ memcpy(*bufferP + index, data_buffer, data_len);
+ index += data_len;
}
break;
case LWM2M_TYPE_BOOLEAN:
headerLen = prv_createHeader(*bufferP + index, isInstance, dataP[i].type, dataP[i].id, 1);
- if (headerLen == 0)
- {
- length = 0;
- }
- else
- {
- index += headerLen;
- (*bufferP)[index] = dataP[i].value.asBoolean ? 1 : 0;
- index += 1;
- }
+ index += headerLen;
+ (*bufferP)[index] = dataP[i].value.asBoolean ? 1 : 0;
+ index += 1;
break;
default:
- length = 0;
+ length = -1;
break;
}
}
- if (length == 0)
+ if (length < 0)
{
lwm2m_free(*bufferP);
+ *bufferP = NULL;
}
LOG_ARG("returning %u", length);
return 0;
}
-lwm2m_transaction_t * transaction_new(coap_message_type_t type,
+lwm2m_transaction_t * transaction_new(void * sessionH,
coap_method_t method,
char * altPath,
lwm2m_uri_t * uriP,
uint16_t mID,
uint8_t token_len,
- uint8_t* token,
- lwm2m_endpoint_type_t peerType,
- void * peerP)
+ uint8_t* token)
{
lwm2m_transaction_t * transacP;
int result;
- LOG_ARG("type: %d, method: %d, altPath: \"%s\", mID: %d, token_len: %d",
- type, method, altPath, mID, token_len);
+ LOG_ARG("method: %d, altPath: \"%s\", mID: %d, token_len: %d",
+ method, altPath, mID, token_len);
LOG_URI(uriP);
- // no transactions for ack or rst
- if (COAP_TYPE_ACK == type || COAP_TYPE_RST == type) return NULL;
-
// no transactions without peer
- if (NULL == peerP) return NULL;
-
- if (COAP_TYPE_NON == type)
- {
- // no transactions for NON responses
- if (COAP_DELETE < method) return NULL;
- // no transactions for NON request without token
- if (0 == token_len) return NULL;
- }
+ if (NULL == sessionH) return NULL;
transacP = (lwm2m_transaction_t *)lwm2m_malloc(sizeof(lwm2m_transaction_t));
transacP->message = lwm2m_malloc(sizeof(coap_packet_t));
if (NULL == transacP->message) goto error;
- coap_init_message(transacP->message, type, method, mID);
+ coap_init_message(transacP->message, COAP_TYPE_CON, method, mID);
+
+ transacP->peerH = sessionH;
transacP->mID = mID;
- transacP->peerType = peerType;
- transacP->peerP = peerP;
if (altPath != NULL)
{
while (NULL != transacP)
{
- void * targetSessionH;
-
- targetSessionH = NULL;
- switch (transacP->peerType)
- {
-#ifdef LWM2M_BOOTSTRAP_SERVER_MODE
- case ENDPOINT_UNKNOWN:
- targetSessionH = transacP->peerP;
- break;
-#endif
-#ifdef LWM2M_SERVER_MODE
- case ENDPOINT_CLIENT:
- targetSessionH = ((lwm2m_client_t *)transacP->peerP)->sessionH;
- break;
-#endif
-
-#ifdef LWM2M_CLIENT_MODE
- case ENDPOINT_SERVER:
- if (NULL != transacP->peerP)
- {
- targetSessionH = ((lwm2m_server_t *)transacP->peerP)->sessionH;
- }
- break;
-#endif
-
- default:
- break;
- }
-
- if (lwm2m_session_is_equal(fromSessionH, targetSessionH, contextP->userData) == true)
+ if (lwm2m_session_is_equal(fromSessionH, transacP->peerH, contextP->userData) == true)
{
if (!transacP->ack_received)
{
if (COAP_MAX_RETRANSMIT + 1 >= transacP->retrans_counter)
{
- void * targetSessionH = NULL;
-
- switch (transacP->peerType)
- {
-#ifdef LWM2M_BOOTSTRAP_SERVER_MODE
- case ENDPOINT_UNKNOWN:
- targetSessionH = transacP->peerP;
- break;
-#endif
-#ifdef LWM2M_SERVER_MODE
- case ENDPOINT_CLIENT:
- targetSessionH = ((lwm2m_client_t *)transacP->peerP)->sessionH;
- break;
-#endif
-#ifdef LWM2M_CLIENT_MODE
- case ENDPOINT_SERVER:
- if (NULL != transacP->peerP)
- {
- targetSessionH = ((lwm2m_server_t *)transacP->peerP)->sessionH;
- }
- break;
-#endif
- default:
- return COAP_500_INTERNAL_SERVER_ERROR;
- }
-
- (void)lwm2m_buffer_send(targetSessionH, transacP->buffer, transacP->buffer_len, contextP->userData);
+ (void)lwm2m_buffer_send(transacP->peerH, transacP->buffer, transacP->buffer_len, contextP->userData);
transacP->retrans_time += timeout;
transacP->retrans_counter += 1;
decLength = 0;
if (decPart >= FLT_EPSILON)
{
- int i;
double noiseFloor;
if (intLength >= length - 1) return 0;
- i = 0;
noiseFloor = FLT_EPSILON;
do
{
decPart *= 10;
noiseFloor *= 10;
- i++;
} while (decPart - (int64_t)decPart > noiseFloor);
decLength = utils_intToText(decPart, string + intLength, length - intLength);
return LWM2M_CONTENT_TEXT;
case APPLICATION_OCTET_STREAM:
return LWM2M_CONTENT_OPAQUE;
+ case LWM2M_CONTENT_TLV_OLD:
+ return LWM2M_CONTENT_TLV_OLD;
case LWM2M_CONTENT_TLV:
return LWM2M_CONTENT_TLV;
+ case LWM2M_CONTENT_JSON_OLD:
+ return LWM2M_CONTENT_JSON_OLD;
case LWM2M_CONTENT_JSON:
return LWM2M_CONTENT_JSON;
case APPLICATION_LINK_FORMAT:
if (len == 0) return -1;
if (len > length + 1) return -1;
- memcpy(buffer, str + _PRV_INT32_MAX_STR_LEN - len, len);
+ memcpy(buffer, str, len);
buffer[len] = 0;
return len;
set(WAKAAMA_SOURCES
${WAKAAMA_SOURCES_DIR}/liblwm2m.c
- ${WAKAAMA_SOURCES_DIR}/uri_lwm2m.c
+ ${WAKAAMA_SOURCES_DIR}/uri.c
${WAKAAMA_SOURCES_DIR}/utils.c
${WAKAAMA_SOURCES_DIR}/objects.c
${WAKAAMA_SOURCES_DIR}/tlv.c
${WAKAAMA_SOURCES_DIR}/observe.c
${WAKAAMA_SOURCES_DIR}/json.c
${WAKAAMA_SOURCES_DIR}/discover.c
- ${CORE_HEADERS}
+ ${WAKAAMA_SOURCES_DIR}/block1.c
${EXT_SOURCES})
# This will not work for multi project cmake generators like the Visual Studio Generator
include_directories (${WAKAAMA_SOURCES_DIR} ${SHARED_INCLUDE_DIRS})
SET(SOURCES
- bootstrap_server.c
- bootstrap_info.c
- bootstrap_info.h
+ ${CMAKE_CURRENT_LIST_DIR}/bootstrap_server.c
+ ${CMAKE_CURRENT_LIST_DIR}/bootstrap_info.c
+ ${CMAKE_CURRENT_LIST_DIR}/bootstrap_info.h
)
SET(AUXILIARY_FILES
- bootstrap_server.ini)
+ ${CMAKE_CURRENT_LIST_DIR}/bootstrap_server.ini)
add_executable(${PROJECT_NAME} ${SOURCES} ${AUXILIARY_FILES} ${WAKAAMA_SOURCES} ${SHARED_SOURCES})
int size;
bs_server_tlv_t * serverP;
lwm2m_media_type_t format;
+ int res;
switch (dataP->securityMode)
{
}
format = LWM2M_CONTENT_TLV;
- serverP->securityLen = lwm2m_data_serialize(NULL, size, tlvP, &format, &(serverP->securityData));
- if (serverP->securityLen <= 0) goto error;
+ res = lwm2m_data_serialize(NULL, size, tlvP, &format, &(serverP->securityData));
+ if (res <= 0) goto error;
+ serverP->securityLen = (size_t)res;
lwm2m_data_free(size, tlvP);
if (dataP->isBootstrap == false)
tlvP[3].id = LWM2M_SERVER_BINDING_ID;
lwm2m_data_encode_string("U", tlvP + 3);
- serverP->serverLen = lwm2m_data_serialize(NULL, size, tlvP, &format, &(serverP->serverData));
- if (serverP->serverLen <= 0) goto error;
+ res = lwm2m_data_serialize(NULL, size, tlvP, &format, &(serverP->serverData));
+ if (res <= 0) goto error;
+ serverP->serverLen = res;
lwm2m_data_free(size, tlvP);
}
fclose(fd);
if (data.bsInfo == NULL)
{
- fprintf(stderr, "Reading Bootsrap Info from file %s failed.\r\n", filename);
+ fprintf(stderr, "Reading Bootstrap Info from file %s failed.\r\n", filename);
return -1;
}
include_directories (${WAKAAMA_SOURCES_DIR} ${SHARED_INCLUDE_DIRS})
SET(SOURCES
- lwm2mclient.c
- lwm2mclient.h
- system_api.c
- object_security.c
- object_server.c
- object_device.c
- object_firmware.c
- object_location.c
- object_connectivity_moni.c
- object_connectivity_stat.c
- object_access_control.c
- test_object.c
+ ${CMAKE_CURRENT_LIST_DIR}/lwm2mclient.c
+ ${CMAKE_CURRENT_LIST_DIR}/lwm2mclient.h
+ ${CMAKE_CURRENT_LIST_DIR}/system_api.c
+ ${CMAKE_CURRENT_LIST_DIR}/object_security.c
+ ${CMAKE_CURRENT_LIST_DIR}/object_server.c
+ ${CMAKE_CURRENT_LIST_DIR}/object_device.c
+ ${CMAKE_CURRENT_LIST_DIR}/object_firmware.c
+ ${CMAKE_CURRENT_LIST_DIR}/object_location.c
+ ${CMAKE_CURRENT_LIST_DIR}/object_connectivity_moni.c
+ ${CMAKE_CURRENT_LIST_DIR}/object_connectivity_stat.c
+ ${CMAKE_CURRENT_LIST_DIR}/object_access_control.c
+ ${CMAKE_CURRENT_LIST_DIR}/test_object.c
)
add_executable(${PROJECT_NAME} ${SOURCES} ${WAKAAMA_SOURCES} ${SHARED_SOURCES})
ifeq ($(CONFIG_DM),y)
-# Routing table support
+CSRCS += lwm2mclient.c
+CSRCS += object_connectivity_moni.c object_connectivity_stat.c
+CSRCS += object_device.c
+CSRCS += object_location.c
+CSRCS += object_security.c
-CSRCS += 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 system_api.c test_object.c lwm2mclient.c common_monitor_interface.c connectivity_interface.c power_monitor_interface.c object_power_moni.c
+# Interface API functions for dm frameworks
+CSRCS += connectivity_interface.c
CFLAGS+=-I$(TOPDIR)/../external/wakaama/core
CFLAGS+=-I$(TOPDIR)/../external/wakaama/examples/shared
+CFLAGS+=-D__TINYARA__
+
DEPPATH += --dep-path wakaama/examples/client
VPATH += :wakaama/examples/client
+++ /dev/null
-#include <stdio.h>
-#include <unistd.h>
-#include <dirent.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <ctype.h>
-#include <stdint.h>
-#include "common_monitor_interface.h"
-
-
-int readonce(FAR const char *filename, FAR char *buffer, uint8_t buflen)
-{
- int ret;
-
- printf("opening %s\n", filename);
- int fd = open(filename, O_RDONLY);
-
- memset(buffer, 0x00, buflen);
- if (fd < 0)
- {
- printf("error reading file %s\n", filename);
- return ERROR;
- }
- else
- {
- size_t nbytes;
-
-
- /* Read until we hit the end of the file, until we have exhausted the
- * buffer space, or until some irrecoverable error occurs
- */
-
- *buffer = '\0'; /* NUL terminate the empty buffer */
- ret = ERROR; /* Assume failure */
-
- nbytes = read(fd, buffer, buflen);
- printf("%d bytes read\n", nbytes);
- if (nbytes < 0)
- {
- /* Read error */
-
- int errcode = errno;
- DEBUGASSERT(errcode > 0);
-
- /* EINTR is not a read error. It simply means that a signal was
- * received while waiting for the read to complete.
- */
-
- if (errcode != EINTR)
- {
- /* Fatal error */
-
- printf("EINTR error\n");
- }
- }
- else if (nbytes >= 0)
- {
- *(buffer+nbytes) = '\0';
- ret = OK;
- }
-
- }
-
- /* Close the file and return. */
-
- close(fd);
- return ret;
-}
-
-int readfile(FAR const char *filename, FAR char *buffer, uint8_t buflen)
-{
- FAR char *bufptr;
- size_t remaining;
- ssize_t nread;
- ssize_t ntotal;
- int ret;
-
- printf("opening %s\n", filename);
- int fd = open(filename, O_RDONLY);
-
- if (fd < 0)
- {
- printf("error reading file %s\n", filename);
- return ERROR;
- }
- else
- {
- size_t nbytes;
-
-
- /* Read until we hit the end of the file, until we have exhausted the
- * buffer space, or until some irrecoverable error occurs
- */
-
- ntotal = 0; /* No bytes read yet */
- *buffer = '\0'; /* NUL terminate the empty buffer */
- bufptr = buffer; /* Working pointer */
- remaining = buflen - 1; /* Reserve one byte for a NUL terminator */
- ret = ERROR; /* Assume failure */
-
- do {
- nbytes = read(fd, buffer, buflen);
- printf("%d bytes read\n", nbytes);
- if (nbytes < 0)
- {
- /* Read error */
-
- int errcode = errno;
- DEBUGASSERT(errcode > 0);
-
- /* EINTR is not a read error. It simply means that a signal was
- * received while waiting for the read to complete.
- */
-
- if (errcode != EINTR)
- {
- /* Fatal error */
-
- printf("EINTR error\n");
- break;
- }
- }
- else if (nbytes == 0)
- {
- /* End of file */
-
- ret = OK;
- break;
- }
- else
- {
- /* Successful read. Make sure that the buffer is null terminated */
-
- DEBUGASSERT(nbytes <= remaining);
- ntotal += nbytes;
- buffer[ntotal] = '\0';
-
- /* Bump up the read count and continuing reading to the end of
- * file.
- */
-
- bufptr += nbytes;
- remaining -= nbytes;
- }
- } while (buflen > 0);
- }
-
- /* Close the file and return. */
-
- close(fd);
- return ret;
-}
-
-void mount_procfs(void)
-{
- int ret;
- ret = mount(NULL, PROC_MOUNTPOINT, "procfs", 0, NULL);
-}
-
+++ /dev/null
-#ifndef _COMMON_MONITOR_INTERFACE_H
-#define _COMMON_MONITOR_INTERFACE_H
-#include <stdint.h>
-#define PROC_BUFFER_LEN 128
-#define PROC_MOUNTPOINT "/proc"
-
-int readonce(FAR const char *filename, FAR char *buffer, uint8_t buflen);
-int readfile(FAR const char *filename, FAR char *buffer, uint8_t buflen);
-void mount_procfs(void);
-#endif
-
-#include <stdio.h>
-#include <unistd.h>
-#include <dirent.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <ctype.h>
-#include <stdint.h>
-#include<netinet/in.h>
-#include<arpa/inet.h>
-#include<sys/socket.h>
-//#include "../../../../net/dualmac/csma.h"
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <sys/socket.h>
#include "connectivity_interface.h"
#include <net/lwip/netif.h>
#endif
-#include "common_monitor_interface.h"
-
-
-uint8_t cm_iobuffer[PROC_BUFFER_LEN];
-
-
/*Read APIs*/
void get_interface_name(char *mac)
{
#if defined(CONFIG_WICED)
- strcpy(mac,"en1");
+ strcpy(mac,"en1");
#elif defined(CONFIG_NET_ETHERNET)
- strcpy(mac,"eth0");
+ strcpy(mac,"eth0");
#elif defined(CONFIG_NET_802154)
- strcpy(mac,"wlan0");
-#elif defined(CONFIG_ARCH_BOARD_SIDK_S5JT200)
- strcpy(mac, "wl1");
+ strcpy(mac,"wlan0");
#endif
}
void get_ip_address(char *ipAddr)
{
- int ret;
- uint8_t *filepath;
- ret = mount(NULL, PROC_MOUNTPOINT, "procfs", 0, NULL);
- printf("mount returns value %d\n", ret);
- ret = asprintf(&filepath, "%s/connectivity/ipaddr", PROC_MOUNTPOINT);
- ret = readonce(filepath, cm_iobuffer, PROC_BUFFER_LEN);
- strncpy(ipAddr, cm_iobuffer, strlen(cm_iobuffer));
- if (ret == OK)
- {
- printf("IP addr is %s\n", ipAddr);
- }
+ printf("Calling inet_ntop\n");
+ char mac[4];
+ get_interface_name(mac);
+#ifdef CONFIG_NET_IPv4
+ struct in_addr addr;
+ netlib_get_ipv4addr(mac, &addr);
+ inet_ntop(AF_INET, &addr, ipAddr, INET_ADDRSTRLEN);
+#endif
+#ifdef CONFIG_NET_IPv6
+ struct in6_addr addr;
+ netlib_get_ipv6addr(mac, &addr);
+ inet_ntop(AF_INET6, &addr, ipAddr, INET6_ADDRSTRLEN);
+#endif
+ printf("After inet_ntop\n");
}
/****************************************************************************
void get_router_ip_address(char *routerIPAddr)
{
- char mac[4];
- get_interface_name(mac);
+ char mac[4];
+ get_interface_name(mac);
#ifdef CONFIG_NET_IPv4
- struct in_addr addr;
- netlib_get_dripv4addr(mac,addr);
- inet_ntop(AF_INET, &addr, routerIPAddr, INET_ADDRSTRLEN);
+ struct in_addr addr;
+ netlib_get_dripv4addr(mac,addr);
+ inet_ntop(AF_INET, &addr, routerIPAddr, INET_ADDRSTRLEN);
#endif
#ifdef CONFIG_NET_IPv6
- struct in6_addr addr;
- netlib_get_dripv6addr(mac,addr);
- inet_ntop(AF_INET6, &addr, routerIPAddr, INET6_ADDRSTRLEN);
+ struct in6_addr addr;
+ netlib_get_dripv6addr(mac,addr);
+ inet_ntop(AF_INET6, &addr, routerIPAddr, INET6_ADDRSTRLEN);
#endif
}
*
****************************************************************************/
-void get_signal_strength(int *rssi_value)
+uint8_t get_signal_strength(void)
{
- int ret;
- uint8_t *filepath;
- ret = mount(NULL, PROC_MOUNTPOINT, "procfs", 0, NULL);
- printf("mount returns value %d\n", ret);
- ret = asprintf(&filepath, "%s/connectivity/rssi", PROC_MOUNTPOINT);
- ret = readonce(filepath, cm_iobuffer, PROC_BUFFER_LEN);
- if (ret == OK)
- {
-// *rssi_value = atoi(cm_iobuffer);
- sscanf(cm_iobuffer, "%d", rssi_value);
- printf("rssi is %d\n", *rssi_value);
- }
+#if defined(CONFIG_NET_802154)
+ return get_rssi();
+#endif
+ return -1;
}
/****************************************************************************
*
****************************************************************************/
-int get_lqi()
+int get_lqi(void)
{
#if defined(CONFIG_NET_802154)
return get_lqi_val();
*
****************************************************************************/
-int get_link_utilization()
+int get_link_utilization(void)
{
return 0;
}
int get_tx_data()
{
//TODO: Feature implementation
+ return 0;
}
/****************************************************************************
int get_rx_data()
{
///TODO: Feature implementation
+ return 0;
}
/****************************************************************************
*
*
****************************************************************************/
- int get_max_message_size()
+int get_max_message_size()
{
///TODO: Feature implementation
+ return 0;
}
-
-
-/****************************************************************************
- * Name: get_bitrate
- *
- * Description:
- * Get bitrate
- *
- * Returned Value:
- *
- *
- ****************************************************************************/
- void get_bitrate(int *bitrate)
- {
- int ret;
- uint8_t *filepath;
- ret = mount(NULL, PROC_MOUNTPOINT, "procfs", 0, NULL);
- printf("mount returns value %d\n", ret);
- ret = asprintf(&filepath, "%s/connectivity/bitrate", PROC_MOUNTPOINT);
- ret = readonce(filepath, cm_iobuffer, PROC_BUFFER_LEN);
- if (ret == OK)
- {
- *bitrate = atoi(cm_iobuffer);
- }
- }
-
-/****************************************************************************
- * Name: get_network_bearer
- *
- * Description:
- * Get Network Bearer
- *
- * Returned Value:
- *
- *
- ****************************************************************************/
-void get_network_bearer(int *nwbearer)
-{
- int ret;
- uint8_t *filepath;
- ret = mount(NULL, PROC_MOUNTPOINT, "procfs", 0, NULL);
- printf("mount returns value %d\n", ret);
- ret = asprintf(&filepath, "%s/connectivity/nwbearer", PROC_MOUNTPOINT);
- ret = readonce(filepath, cm_iobuffer, PROC_BUFFER_LEN);
- if (ret == OK)
- sscanf(cm_iobuffer, "%d", nwbearer);
-}
-
-/****************************************************************************
- * Name: get_avl_network_bearer
- *
- * Description:
- * Get Available Network Bearer
- *
- * Returned Value:
- *
- *
- ****************************************************************************/
-void get_avl_network_bearer(int *nwbearer)
-{
- int ret;
- uint8_t *filepath;
- ret = mount(NULL, PROC_MOUNTPOINT, "procfs", 0, NULL);
- printf("mount returns value %d\n", ret);
- ret = asprintf(&filepath, "%s/connectivity/available_bearer", PROC_MOUNTPOINT);
- ret = readonce(filepath, cm_iobuffer, PROC_BUFFER_LEN);
- if (ret == OK)
- sscanf(cm_iobuffer, "%d", nwbearer);
-}
-
-
-
-
-
-
/*Util Functions*/
/****************************************************************************
* Return the appropriate Callback flags
*
****************************************************************************/
-void get_signal_strength(int *rssi_value);
+uint8_t get_signal_strength(void);
/****************************************************************************
* Name: get_link_utilization
*
*
****************************************************************************/
-
int get_tx_data(void);
/****************************************************************************
*
*
****************************************************************************/
-
int get_rx_data(void);
/****************************************************************************
*
****************************************************************************/
int get_max_message_size(void);
-
-
-/****************************************************************************
- * Name: get_bitrate
- *
- * Description:
- * Get bitrate
- *
- * Returned Value:
- *
- *
- ****************************************************************************/
- void get_bitrate(int *bitrate);
-
-
-/****************************************************************************
- * Name: get_network_bearer
- *
- * Description:
- * Get Network Bearer
- *
- * Returned Value:
- *
- *
- ****************************************************************************/
-void get_network_bearer(int *nwbearer);
-
-/****************************************************************************
- * Name: get_avl_network_bearer
- *
- * Description:
- * Get Available Network Bearer
- *
- * Returned Value:
- *
- *
- ****************************************************************************/
-void get_avl_network_bearer(int *nwbearer);
Bosch Software Innovations GmbH - Please refer to git log
*/
-#include <tinyara/config.h>
-#include <time.h>
-#ifdef CONFIG_NET_LWIP
-
-//#include "object_connectivity_stat.h"
#include "lwm2mclient.h"
#include "liblwm2m.h"
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
+#include <netdb.h>
#include <sys/stat.h>
#include <errno.h>
#include <signal.h>
-#include <debug.h>
-#include <semaphore.h>
-#include <sys/ioctl.h>
-
-#include <net/if.h>
-#include <netinet/arp.h>
-
-#include <apps/netutils/netlib.h>
-#include <netdb.h>
-#include <tinyara/net/dns.h>
+#define MAX_PACKET_SIZE 1024
+#define DEFAULT_SERVER_IPV6 "[::1]"
+#define DEFAULT_SERVER_IPV4 "127.0.0.1"
/****************************************************************************
- * Definitions
+ * TINYARA
+ * - definition and global variables
+ * - APIs used for dm frameworks
****************************************************************************/
+#if defined(__TINYARA__)
-#if defined(CONFIG_NET_ETHERNET) && CONFIG_NET_ETHERNET == 1
-#if LWIP_HAVE_LOOPIF
-#define NET_DEVNAME "en1"
-#else
-#define NET_DEVNAME "en0"
+/* Definitions*/
+#ifndef FD_SETSIZE
+#define FD_SETSIZE (CONFIG_NFILE_DESCRIPTORS + CONFIG_NSOCKET_DESCRIPTORS)
#endif
-#elif defined(CONFIG_NET_802154) && CONFIG_NET_802154 == 1
-#define NET_DEVNAME "wpan0"
-#else
-#error "undefined CONFIG_NET_<type>, check your .config"
+
+#ifndef STDIN_FILENO
+#define STDIN_FILENO 0
+#endif
+#ifndef STDOUT_FILENO
+#define STDOUT_FILENO 1
+#endif
+#ifndef STDERR_FILENO
+#define STDERR_FILENO 2
#endif
-/****************************************************************************
- * Private Data
- ****************************************************************************/
+#define SET_PARAM_DM_FRAMEWORK -10
-#define MAX_PACKET_SIZE 1024
-#define DEFAULT_SERVER_IPV6 "[::1]"
-#define DEFAULT_SERVER_IPV4 "127.0.0.1"
+#define DEFAULT_CLIENT_NAME "myawesomeclient"
#define IPADDRLEN_MAX 32
#define PORTLEN_MAX 6
-#ifndef STDIN_FILENO
-# define STDIN_FILENO 0
-#endif
-
-static int cc = 0;
-int g_reboot = 0;
-static int g_quit = 0;
+/* Global variables */
static char g_serverAddr[IPADDRLEN_MAX];
static char g_serverPort[PORTLEN_MAX];
static char g_bootstrapserverAddr[IPADDRLEN_MAX];
static uint16_t g_lifetime;
bool g_bootstrapRequested;
-#define OBJ_COUNT 10
-lwm2m_object_t *objArray[OBJ_COUNT];
+#endif /* __TINYARA__ */
+
+int g_reboot = 0;
+static int g_quit = 0;
+
+lwm2m_context_t * lwm2mH;
+
+#define OBJ_COUNT 9
+lwm2m_object_t * objArray[OBJ_COUNT];
// only backup security and server objects
# define BACKUP_OBJECT_COUNT 2
-lwm2m_object_t *backupObjectArray[BACKUP_OBJECT_COUNT];
+lwm2m_object_t * backupObjectArray[BACKUP_OBJECT_COUNT];
-typedef struct {
- lwm2m_object_t *securityObjP;
- lwm2m_object_t *serverObject;
- int sock;
+typedef struct
+{
+ lwm2m_object_t * securityObjP;
+ lwm2m_object_t * serverObject;
+ int sock;
#ifdef WITH_TINYDTLS
- dtls_connection_t *connList;
- lwm2m_context_t *lwm2mH;
+ dtls_connection_t * connList;
+ lwm2m_context_t * lwm2mH;
#else
- connection_t *connList;
+ connection_t * connList;
#endif
- int addressFamily;
+ int addressFamily;
} client_data_t;
-lwm2m_context_t *lwm2mH;
-client_data_t data;
+#if defined (__TINYARA__)
+/* Private Functions */
+static void clear_client_globals(void);
+static void prv_close_sock(void);
+static void prv_update_server(client_data_t *dataP, uint16_t secObjInstID);
+static void process_udpconn(int sockfd, fd_set *readfds, client_data_t data);
+#endif /*__TINYARA__*/
-static void clear_client_globals(void)
+static void prv_quit(char * buffer,
+ void * user_data)
{
- memset(g_bootstrapserverAddr, 0x00, IPADDRLEN_MAX);
- memset(g_bootstrapserverPort, 0x00, 6);
- if (lwm2mH->state == STATE_REGISTER_REQUIRED ||
- lwm2mH->state == STATE_REGISTERING ||
- lwm2mH->state == STATE_READY) {
- printf("g_bootstrapRequested = false\n");
- g_bootstrapRequested = false;
- }
-}
-
-static void prv_update_server(client_data_t *dataP,
- uint16_t secObjInstID)
-{
- char *uri;
- char *server_host;
- char *server_port;
-
- uri = get_server_uri(dataP->securityObjP, secObjInstID);
-
- if (uri == NULL) {
- return;
- }
-
- // parse uri in the form "coaps://[server_host]:[port]"
- if (0 == strncmp(uri, "coaps://", strlen("coaps://"))) {
- server_host = uri + strlen("coaps://");
- } else if (0 == strncmp(uri, "coap://", strlen("coap://"))) {
- server_host = uri + strlen("coap://");
- } else {
- return;
- }
- server_port = strrchr(server_host, ':');
- if (server_port == NULL) {
- return;
- }
- // remove brackets
- if (server_host[0] == '[') {
- server_host++;
- if (*(server_port - 1) == ']') {
- *(server_port - 1) = 0;
- } else {
- return;
- }
- }
- // split strings
- *server_port = 0;
- server_port++;
-
- client_set_serverAddr(server_host, false);
- client_set_serverPort(server_port, false);
-}
-
-
-static void prv_quit(char *buffer,
- void *user_data)
-{
- g_quit = 1;
+ g_quit = 1;
}
void handle_sigint(int signum)
{
- g_quit = 2;
+ g_quit = 2;
}
-void handle_value_changed(lwm2m_context_t *lwm2mH,
- lwm2m_uri_t *uri,
- const char *value,
- size_t valueLength)
+void handle_value_changed(lwm2m_context_t * lwm2mP,
+ lwm2m_uri_t * uri,
+ const char * value,
+ size_t valueLength)
{
- lwm2m_object_t *object = (lwm2m_object_t *)LWM2M_LIST_FIND(lwm2mH->objectList, uri->objectId);
-
- if (NULL != object) {
- if (object->writeFunc != NULL) {
- lwm2m_data_t *dataP;
- int result;
-
- dataP = lwm2m_data_new(1);
- if (dataP == NULL) {
- fprintf(stderr, "Internal allocation failure !\n");
- return;
- }
- dataP->id = uri->resourceId;
- lwm2m_data_encode_nstring(value, valueLength, dataP);
-
- result = object->writeFunc(uri->instanceId, 1, dataP, object);
- if (COAP_405_METHOD_NOT_ALLOWED == result) {
- switch (uri->objectId) {
- case LWM2M_DEVICE_OBJECT_ID:
- result = device_change(dataP, object);
- break;
- default:
- break;
- }
- }
-
- if (COAP_204_CHANGED != result) {
- fprintf(stderr, "Failed to change value!\n");
- } else {
- fprintf(stderr, "value changed!\n");
- lwm2m_resource_value_changed(lwm2mH, uri);
- }
- lwm2m_data_free(1, dataP);
- return;
- } else {
- fprintf(stderr, "write not supported for specified resource!\n");
- }
- return;
- } else {
- fprintf(stderr, "Object not found !\n");
- }
+ lwm2m_object_t * object = (lwm2m_object_t *)LWM2M_LIST_FIND(lwm2mP->objectList, uri->objectId);
+
+ if (NULL != object)
+ {
+ if (object->writeFunc != NULL)
+ {
+ lwm2m_data_t * dataP;
+ int result;
+
+ dataP = lwm2m_data_new(1);
+ if (dataP == NULL)
+ {
+ fprintf(stderr, "Internal allocation failure !\n");
+ return;
+ }
+ dataP->id = uri->resourceId;
+ lwm2m_data_encode_nstring(value, valueLength, dataP);
+
+ result = object->writeFunc(uri->instanceId, 1, dataP, object);
+ if (COAP_405_METHOD_NOT_ALLOWED == result)
+ {
+ switch (uri->objectId)
+ {
+ case LWM2M_DEVICE_OBJECT_ID:
+ result = device_change(dataP, object);
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (COAP_204_CHANGED != result)
+ {
+ fprintf(stderr, "Failed to change value!\n");
+ }
+ else
+ {
+ fprintf(stderr, "value changed!\n");
+ lwm2m_resource_value_changed(lwm2mP, uri);
+ }
+ lwm2m_data_free(1, dataP);
+ return;
+ }
+ else
+ {
+ fprintf(stderr, "write not supported for specified resource!\n");
+ }
+ return;
+ }
+ else
+ {
+ fprintf(stderr, "Object not found !\n");
+ }
}
#ifdef WITH_TINYDTLS
-void *lwm2m_connect_server(uint16_t secObjInstID,
- void *userData)
+void * lwm2m_connect_server(uint16_t secObjInstID,
+ void * userData)
{
- client_data_t *dataP;
- lwm2m_list_t *instance;
- dtls_connection_t *newConnP = NULL;
- dataP = (client_data_t *)userData;
- lwm2m_object_t *securityObj = dataP->securityObjP;
-
- instance = LWM2M_LIST_FIND(dataP->securityObjP->instanceList, secObjInstID);
- if (instance == NULL) {
- return NULL;
- }
-
-
- newConnP = connection_create(dataP->connList, dataP->sock, securityObj, instance->id, dataP->lwm2mH, dataP->addressFamily);
- if (newConnP == NULL) {
- fprintf(stderr, "Connection creation failed.\n");
- return NULL;
- }
-
- dataP->connList = newConnP;
- return (void *)newConnP;
+ client_data_t * dataP;
+ lwm2m_list_t * instance;
+ dtls_connection_t * newConnP = NULL;
+ dataP = (client_data_t *)userData;
+ lwm2m_object_t * securityObj = dataP->securityObjP;
+
+ instance = LWM2M_LIST_FIND(dataP->securityObjP->instanceList, secObjInstID);
+ if (instance == NULL) return NULL;
+
+
+ newConnP = connection_create(dataP->connList, dataP->sock, securityObj, instance->id, dataP->lwm2mH, dataP->addressFamily);
+ if (newConnP == NULL)
+ {
+ fprintf(stderr, "Connection creation failed.\n");
+ return NULL;
+ }
+
+ dataP->connList = newConnP;
+ return (void *)newConnP;
}
#else
-void *lwm2m_connect_server(uint16_t secObjInstID,
- void *userData)
+void * lwm2m_connect_server(uint16_t secObjInstID,
+ void * userData)
{
- client_data_t *dataP;
- char *uri;
- char *host;
- char *port;
- connection_t *newConnP = NULL;
-
- dataP = (client_data_t *)userData;
-
- uri = get_server_uri(dataP->securityObjP, secObjInstID);
-
- if (uri == NULL) {
- return NULL;
- }
-
- // parse uri in the form "coaps://[host]:[port]"
- if (0 == strncmp(uri, "coaps://", strlen("coaps://"))) {
- host = uri + strlen("coaps://");
- } else if (0 == strncmp(uri, "coap://", strlen("coap://"))) {
- host = uri + strlen("coap://");
- } else {
- goto exit;
- }
- port = strrchr(host, ':');
- if (port == NULL) {
- goto exit;
- }
- // remove brackets
- if (host[0] == '[') {
- host++;
- if (*(port - 1) == ']') {
- *(port - 1) = 0;
- } else {
- goto exit;
- }
- }
- // split strings
- *port = 0;
- port++;
-
- fprintf(stderr, "Opening connection to server at %s:%s\r\n", host, port);
- newConnP = connection_create(dataP->connList, dataP->sock, host, port, dataP->addressFamily);
- if (newConnP == NULL) {
- fprintf(stderr, "Connection creation failed.\r\n");
- } else {
- dataP->connList = newConnP;
- }
-#ifdef LWM2M_CLIENT_MODE
- printf("lwm2mH->state = %d\n", lwm2mH->state);
- if (lwm2mH->state == STATE_REGISTERING ||
- lwm2mH->state == STATE_REGISTER_REQUIRED) {
- prv_update_server(dataP, secObjInstID);
- }
-
-#endif
+ client_data_t * dataP;
+ char * uri;
+ char * host;
+ char * port;
+ connection_t * newConnP = NULL;
+
+ dataP = (client_data_t *)userData;
+
+ uri = get_server_uri(dataP->securityObjP, secObjInstID);
+
+ if (uri == NULL) return NULL;
+
+ // parse uri in the form "coaps://[host]:[port]"
+ if (0==strncmp(uri, "coaps://", strlen("coaps://"))) {
+ host = uri+strlen("coaps://");
+ }
+ else if (0==strncmp(uri, "coap://", strlen("coap://"))) {
+ host = uri+strlen("coap://");
+ }
+ else {
+ goto exit;
+ }
+ port = strrchr(host, ':');
+ if (port == NULL) goto exit;
+ // remove brackets
+ if (host[0] == '[')
+ {
+ host++;
+ if (*(port - 1) == ']')
+ {
+ *(port - 1) = 0;
+ }
+ else goto exit;
+ }
+ // split strings
+ *port = 0;
+ port++;
+
+ fprintf(stderr, "Opening connection to server at %s:%s\r\n", host, port);
+ newConnP = connection_create(dataP->connList, dataP->sock, host, port, dataP->addressFamily);
+ if (newConnP == NULL) {
+ fprintf(stderr, "Connection creation failed.\r\n");
+ }
+ else {
+ dataP->connList = newConnP;
+ }
exit:
- lwm2m_free(uri);
- return (void *)newConnP;
+ lwm2m_free(uri);
+ return (void *)newConnP;
}
#endif
-void lwm2m_close_connection(void *sessionH,
- void *userData)
+void lwm2m_close_connection(void * sessionH,
+ void * userData)
{
- client_data_t *app_data;
+ client_data_t * app_data;
#ifdef WITH_TINYDTLS
- dtls_connection_t *targetP;
+ dtls_connection_t * targetP;
#else
- connection_t *targetP;
+ connection_t * targetP;
#endif
- app_data = (client_data_t *)userData;
+ app_data = (client_data_t *)userData;
#ifdef WITH_TINYDTLS
- targetP = (dtls_connection_t *)sessionH;
+ targetP = (dtls_connection_t *)sessionH;
#else
- targetP = (connection_t *)sessionH;
+ targetP = (connection_t *)sessionH;
#endif
- if (targetP == app_data->connList) {
- app_data->connList = targetP->next;
- lwm2m_free(targetP);
- } else {
+ if (targetP == app_data->connList)
+ {
+ app_data->connList = targetP->next;
+ lwm2m_free(targetP);
+ }
+ else
+ {
#ifdef WITH_TINYDTLS
- dtls_connection_t *parentP;
+ dtls_connection_t * parentP;
#else
- connection_t *parentP;
+ connection_t * parentP;
#endif
- parentP = app_data->connList;
- while (parentP != NULL && parentP->next != targetP) {
- parentP = parentP->next;
- }
- if (parentP != NULL) {
- parentP->next = targetP->next;
- lwm2m_free(targetP);
- }
- }
+ parentP = app_data->connList;
+ while (parentP != NULL && parentP->next != targetP)
+ {
+ parentP = parentP->next;
+ }
+ if (parentP != NULL)
+ {
+ parentP->next = targetP->next;
+ lwm2m_free(targetP);
+ }
+ }
}
-#endif
-static void prv_output_servers(char *buffer,
- void *user_data)
+static void prv_output_servers(char * buffer,
+ void * user_data)
{
- lwm2m_context_t *lwm2mH = (lwm2m_context_t *) user_data;
- lwm2m_server_t *targetP;
-
- targetP = lwm2mH->bootstrapServerList;
-
- if (lwm2mH->bootstrapServerList == NULL) {
- fprintf(stdout, "No Bootstrap Server.\r\n");
- } else {
- fprintf(stdout, "Bootstrap Servers:\r\n");
- for (targetP = lwm2mH->bootstrapServerList ; targetP != NULL ; targetP = targetP->next) {
- fprintf(stdout, " - Security Object ID %d", targetP->secObjInstID);
- fprintf(stdout, "\tHold Off Time: %lu s", (unsigned long)targetP->lifetime);
- fprintf(stdout, "\tstatus: ");
- switch (targetP->status) {
- case STATE_DEREGISTERED:
- fprintf(stdout, "DEREGISTERED\r\n");
- break;
- case STATE_BS_HOLD_OFF:
- fprintf(stdout, "CLIENT HOLD OFF\r\n");
- break;
- case STATE_BS_INITIATED:
- fprintf(stdout, "BOOTSTRAP INITIATED\r\n");
- break;
- case STATE_BS_PENDING:
- fprintf(stdout, "BOOTSTRAP PENDING\r\n");
- break;
- case STATE_BS_FINISHED:
- fprintf(stdout, "BOOTSTRAP FINISHED\r\n");
- break;
- case STATE_BS_FAILED:
- fprintf(stdout, "BOOTSTRAP FAILED\r\n");
- break;
- default:
- fprintf(stdout, "INVALID (%d)\r\n", (int)targetP->status);
- }
- }
- }
-
- if (lwm2mH->serverList == NULL) {
- fprintf(stdout, "No LWM2M Server.\r\n");
- } else {
- fprintf(stdout, "LWM2M Servers:\r\n");
- for (targetP = lwm2mH->serverList ; targetP != NULL ; targetP = targetP->next) {
- fprintf(stdout, " - Server ID %d", targetP->shortID);
- fprintf(stdout, "\tstatus: ");
- switch (targetP->status) {
- case STATE_DEREGISTERED:
- fprintf(stdout, "DEREGISTERED\r\n");
- break;
- case STATE_REG_PENDING:
- fprintf(stdout, "REGISTRATION PENDING\r\n");
- break;
- case STATE_REGISTERED:
- fprintf(stdout, "REGISTERED\tlocation: \"%s\"\tLifetime: %lus\r\n", targetP->location, (unsigned long)targetP->lifetime);
- break;
- case STATE_REG_UPDATE_PENDING:
- fprintf(stdout, "REGISTRATION UPDATE PENDING\r\n");
- break;
- case STATE_DEREG_PENDING:
- fprintf(stdout, "DEREGISTRATION PENDING\r\n");
- break;
- case STATE_REG_FAILED:
- fprintf(stdout, "REGISTRATION FAILED\r\n");
- break;
- default:
- fprintf(stdout, "INVALID (%d)\r\n", (int)targetP->status);
- }
- }
- }
+ lwm2mH = (lwm2m_context_t *) user_data;
+ lwm2m_server_t * targetP;
+
+ targetP = lwm2mH->bootstrapServerList;
+
+ if (lwm2mH->bootstrapServerList == NULL)
+ {
+ fprintf(stdout, "No Bootstrap Server.\r\n");
+ }
+ else
+ {
+ fprintf(stdout, "Bootstrap Servers:\r\n");
+ for (targetP = lwm2mH->bootstrapServerList ; targetP != NULL ; targetP = targetP->next)
+ {
+ fprintf(stdout, " - Security Object ID %d", targetP->secObjInstID);
+ fprintf(stdout, "\tHold Off Time: %lu s", (unsigned long)targetP->lifetime);
+ fprintf(stdout, "\tstatus: ");
+ switch(targetP->status)
+ {
+ case STATE_DEREGISTERED:
+ fprintf(stdout, "DEREGISTERED\r\n");
+ break;
+ case STATE_BS_HOLD_OFF:
+ fprintf(stdout, "CLIENT HOLD OFF\r\n");
+ break;
+ case STATE_BS_INITIATED:
+ fprintf(stdout, "BOOTSTRAP INITIATED\r\n");
+ break;
+ case STATE_BS_PENDING:
+ fprintf(stdout, "BOOTSTRAP PENDING\r\n");
+ break;
+ case STATE_BS_FINISHED:
+ fprintf(stdout, "BOOTSTRAP FINISHED\r\n");
+ break;
+ case STATE_BS_FAILED:
+ fprintf(stdout, "BOOTSTRAP FAILED\r\n");
+ break;
+ default:
+ fprintf(stdout, "INVALID (%d)\r\n", (int)targetP->status);
+ }
+ }
+ }
+
+ if (lwm2mH->serverList == NULL)
+ {
+ fprintf(stdout, "No LWM2M Server.\r\n");
+ }
+ else
+ {
+ fprintf(stdout, "LWM2M Servers:\r\n");
+ for (targetP = lwm2mH->serverList ; targetP != NULL ; targetP = targetP->next)
+ {
+ fprintf(stdout, " - Server ID %d", targetP->shortID);
+ fprintf(stdout, "\tstatus: ");
+ switch(targetP->status)
+ {
+ case STATE_DEREGISTERED:
+ fprintf(stdout, "DEREGISTERED\r\n");
+ break;
+ case STATE_REG_PENDING:
+ fprintf(stdout, "REGISTRATION PENDING\r\n");
+ break;
+ case STATE_REGISTERED:
+ fprintf(stdout, "REGISTERED\tlocation: \"%s\"\tLifetime: %lus\r\n", targetP->location, (unsigned long)targetP->lifetime);
+ break;
+ case STATE_REG_UPDATE_PENDING:
+ fprintf(stdout, "REGISTRATION UPDATE PENDING\r\n");
+ break;
+ case STATE_DEREG_PENDING:
+ fprintf(stdout, "DEREGISTRATION PENDING\r\n");
+ break;
+ case STATE_REG_FAILED:
+ fprintf(stdout, "REGISTRATION FAILED\r\n");
+ break;
+ default:
+ fprintf(stdout, "INVALID (%d)\r\n", (int)targetP->status);
+ }
+ }
+ }
}
-static void prv_change(char *buffer,
- void *user_data)
+static void prv_change(char * buffer,
+ void * user_data)
{
-
- lwm2m_uri_t uri;
- char *end = NULL;
- int result;
-
- end = get_end_of_arg(buffer);
-// if (end[0] == 0) goto syntax_error;
-
- result = lwm2m_stringToUri(buffer, end - buffer, &uri);
- if (result == 0) {
- goto syntax_error;
- }
-
- buffer = get_next_arg(end, &end);
-
- if (buffer[0] == 0) {
- fprintf(stderr, "report change!\n");
- lwm2m_resource_value_changed(lwm2mH, &uri);
- } else {
- handle_value_changed(lwm2mH, &uri, buffer, end - buffer);
- }
- return;
+ lwm2mH = (lwm2m_context_t *) user_data;
+ lwm2m_uri_t uri;
+ char * end = NULL;
+ int result;
+
+ end = get_end_of_arg(buffer);
+ if (end[0] == 0) goto syntax_error;
+
+ result = lwm2m_stringToUri(buffer, end - buffer, &uri);
+ if (result == 0) goto syntax_error;
+
+ buffer = get_next_arg(end, &end);
+
+ if (buffer[0] == 0)
+ {
+ fprintf(stderr, "report change!\n");
+ lwm2m_resource_value_changed(lwm2mH, &uri);
+ }
+ else
+ {
+ handle_value_changed(lwm2mH, &uri, buffer, end - buffer);
+ }
+ return;
syntax_error:
- fprintf(stdout, "Syntax error !\n");
+ fprintf(stdout, "Syntax error !\n");
}
-static void prv_object_list(char *buffer,
- void *user_data)
+static void prv_object_list(char * buffer,
+ void * user_data)
{
- lwm2m_context_t *lwm2mH = (lwm2m_context_t *)user_data;
- lwm2m_object_t *objectP;
-
- for (objectP = lwm2mH->objectList; objectP != NULL; objectP = objectP->next) {
- if (objectP->instanceList == NULL) {
- fprintf(stdout, "/%d ", objectP->objID);
- } else {
- lwm2m_list_t *instanceP;
-
- for (instanceP = objectP->instanceList; instanceP != NULL ; instanceP = instanceP->next) {
- fprintf(stdout, "/%d/%d ", objectP->objID, instanceP->id);
- }
- }
- fprintf(stdout, "\r\n");
- }
+ lwm2mH = (lwm2m_context_t *)user_data;
+ lwm2m_object_t * objectP;
+
+ for (objectP = lwm2mH->objectList; objectP != NULL; objectP = objectP->next)
+ {
+ if (objectP->instanceList == NULL)
+ {
+ fprintf(stdout, "/%d ", objectP->objID);
+ }
+ else
+ {
+ lwm2m_list_t * instanceP;
+
+ for (instanceP = objectP->instanceList; instanceP != NULL ; instanceP = instanceP->next)
+ {
+ fprintf(stdout, "/%d/%d ", objectP->objID, instanceP->id);
+ }
+ }
+ fprintf(stdout, "\r\n");
+ }
}
-static void prv_instance_dump(lwm2m_object_t *objectP,
- uint16_t id)
+static void prv_instance_dump(lwm2m_object_t * objectP,
+ uint16_t id)
{
- int numData;
- lwm2m_data_t *dataArray;
- uint16_t res;
-
- numData = 0;
- res = objectP->readFunc(id, &numData, &dataArray, objectP);
- if (res != COAP_205_CONTENT) {
- printf("Error ");
- print_status(stdout, res);
- printf("\r\n");
- return;
- }
-
- dump_tlv(stdout, numData, dataArray, 0);
+ int numData;
+ lwm2m_data_t * dataArray;
+ uint16_t res;
+
+ numData = 0;
+ res = objectP->readFunc(id, &numData, &dataArray, objectP);
+ if (res != COAP_205_CONTENT)
+ {
+ printf("Error ");
+ print_status(stdout, res);
+ printf("\r\n");
+ return;
+ }
+
+ dump_tlv(stdout, numData, dataArray, 0);
}
-static void prv_object_dump(char *buffer,
- void *user_data)
+static void prv_object_dump(char * buffer,
+ void * user_data)
{
- lwm2m_context_t *lwm2mH = (lwm2m_context_t *) user_data;
- lwm2m_uri_t uri;
- char *end = NULL;
- int result;
- lwm2m_object_t *objectP;
-
- end = get_end_of_arg(buffer);
- //if (end[0] == 0) goto syntax_error;
-
- result = lwm2m_stringToUri(buffer, end - buffer, &uri);
- if (result == 0) {
- goto syntax_error;
- }
- if (uri.flag & LWM2M_URI_FLAG_RESOURCE_ID) {
- goto syntax_error;
- }
-
- objectP = (lwm2m_object_t *)LWM2M_LIST_FIND(lwm2mH->objectList, uri.objectId);
- if (objectP == NULL) {
- fprintf(stdout, "Object not found.\n");
- return;
- }
-
- if (uri.flag & LWM2M_URI_FLAG_INSTANCE_ID) {
- prv_instance_dump(objectP, uri.instanceId);
- } else {
- lwm2m_list_t *instanceP;
-
- for (instanceP = objectP->instanceList; instanceP != NULL ; instanceP = instanceP->next) {
- fprintf(stdout, "Instance %d:\r\n", instanceP->id);
- prv_instance_dump(objectP, instanceP->id);
- fprintf(stdout, "\r\n");
- }
- }
-
- return;
+ lwm2mH = (lwm2m_context_t *) user_data;
+ lwm2m_uri_t uri;
+ char * end = NULL;
+ int result;
+ lwm2m_object_t * objectP;
+
+ end = get_end_of_arg(buffer);
+ if (end[0] == 0) goto syntax_error;
+
+ result = lwm2m_stringToUri(buffer, end - buffer, &uri);
+ if (result == 0) goto syntax_error;
+ if (uri.flag & LWM2M_URI_FLAG_RESOURCE_ID) goto syntax_error;
+
+ objectP = (lwm2m_object_t *)LWM2M_LIST_FIND(lwm2mH->objectList, uri.objectId);
+ if (objectP == NULL)
+ {
+ fprintf(stdout, "Object not found.\n");
+ return;
+ }
+
+ if (uri.flag & LWM2M_URI_FLAG_INSTANCE_ID)
+ {
+ prv_instance_dump(objectP, uri.instanceId);
+ }
+ else
+ {
+ lwm2m_list_t * instanceP;
+
+ for (instanceP = objectP->instanceList; instanceP != NULL ; instanceP = instanceP->next)
+ {
+ fprintf(stdout, "Instance %d:\r\n", instanceP->id);
+ prv_instance_dump(objectP, instanceP->id);
+ fprintf(stdout, "\r\n");
+ }
+ }
+
+ return;
syntax_error:
- fprintf(stdout, "Syntax error !\n");
+ fprintf(stdout, "Syntax error !\n");
}
-static void prv_update(char *buffer,
- void *user_data)
+static void prv_update(char * buffer,
+ void * user_data)
{
- lwm2m_context_t *lwm2mH = (lwm2m_context_t *)user_data;
- if (buffer[0] == 0) {
- goto syntax_error;
- }
-
- uint16_t serverId = (uint16_t) atoi(buffer);
- int res = lwm2m_update_registration(lwm2mH, serverId, false);
- if (res != 0) {
- fprintf(stdout, "Registration update error: ");
- print_status(stdout, res);
- fprintf(stdout, "\r\n");
- }
- return;
+ lwm2mH = (lwm2m_context_t *)user_data;
+ if (buffer[0] == 0) goto syntax_error;
+
+ uint16_t serverId = (uint16_t) atoi(buffer);
+ int res = lwm2m_update_registration(lwm2mH, serverId, false);
+ if (res != 0)
+ {
+ fprintf(stdout, "Registration update error: ");
+ print_status(stdout, res);
+ fprintf(stdout, "\r\n");
+ }
+ return;
syntax_error:
- fprintf(stdout, "Syntax error !\n");
+ fprintf(stdout, "Syntax error !\n");
}
-static void update_battery_level(lwm2m_context_t *context)
+static void update_battery_level(lwm2m_context_t * context)
{
- static time_t next_change_time = 0;
- time_t tv_sec;
-
- tv_sec = lwm2m_gettime();
- if (tv_sec < 0) {
- return;
- }
-
- if (next_change_time < tv_sec) {
- char value[15];
- int valueLength;
- lwm2m_uri_t uri;
- int level = rand() % 100;
-
- if (0 > level) {
- level = -level;
- }
- if (lwm2m_stringToUri("/3/0/9", 6, &uri)) {
- valueLength = sprintf(value, "%d", level);
- fprintf(stderr, "New Battery Level: %d\n", level);
- handle_value_changed(context, &uri, value, valueLength);
- }
- level = rand() % 20;
- if (0 > level) {
- level = -level;
- }
- next_change_time = tv_sec + level + 10;
- }
+ static time_t next_change_time = 0;
+ time_t tv_sec;
+
+ tv_sec = lwm2m_gettime();
+ if (tv_sec < 0) return;
+
+ if (next_change_time < tv_sec)
+ {
+ char value[15];
+ int valueLength;
+ lwm2m_uri_t uri;
+ int level = rand() % 100;
+
+ if (0 > level) level = -level;
+ if (lwm2m_stringToUri("/3/0/9", 6, &uri))
+ {
+ valueLength = sprintf(value, "%d", level);
+ fprintf(stderr, "New Battery Level: %d\n", level);
+ handle_value_changed(context, &uri, value, valueLength);
+ }
+ level = rand() % 20;
+ if (0 > level) level = -level;
+ next_change_time = tv_sec + level + 10;
+ }
}
-static void prv_add(char *buffer,
- void *user_data)
+static void prv_add(char * buffer,
+ void * user_data)
{
- lwm2m_context_t *lwm2mH = (lwm2m_context_t *)user_data;
- lwm2m_object_t *objectP;
- int res;
-
- objectP = get_test_object();
- if (objectP == NULL) {
- fprintf(stdout, "Creating object 1024 failed.\r\n");
- return;
- }
- res = lwm2m_add_object(lwm2mH, objectP);
- if (res != 0) {
- fprintf(stdout, "Adding object 1024 failed: ");
- print_status(stdout, res);
- fprintf(stdout, "\r\n");
- } else {
- fprintf(stdout, "Object 1024 added.\r\n");
- }
- return;
+ lwm2mH = (lwm2m_context_t *)user_data;
+ lwm2m_object_t * objectP;
+ int res;
+
+ objectP = get_test_object();
+ if (objectP == NULL)
+ {
+ fprintf(stdout, "Creating object 1024 failed.\r\n");
+ return;
+ }
+ res = lwm2m_add_object(lwm2mH, objectP);
+ if (res != 0)
+ {
+ fprintf(stdout, "Adding object 1024 failed: ");
+ print_status(stdout, res);
+ fprintf(stdout, "\r\n");
+ }
+ else
+ {
+ fprintf(stdout, "Object 1024 added.\r\n");
+ }
+ return;
}
-static void prv_remove(char *buffer,
- void *user_data)
+static void prv_remove(char * buffer,
+ void * user_data)
{
- lwm2m_context_t *lwm2mH = (lwm2m_context_t *)user_data;
- int res;
-
- res = lwm2m_remove_object(lwm2mH, 1024);
- if (res != 0) {
- fprintf(stdout, "Removing object 1024 failed: ");
- print_status(stdout, res);
- fprintf(stdout, "\r\n");
- } else {
- fprintf(stdout, "Object 1024 removed.\r\n");
- }
- return;
+ lwm2mH = (lwm2m_context_t *)user_data;
+ int res;
+
+ res = lwm2m_remove_object(lwm2mH, 1024);
+ if (res != 0)
+ {
+ fprintf(stdout, "Removing object 1024 failed: ");
+ print_status(stdout, res);
+ fprintf(stdout, "\r\n");
+ }
+ else
+ {
+ fprintf(stdout, "Object 1024 removed.\r\n");
+ }
+ return;
}
#ifdef LWM2M_BOOTSTRAP
-static void prv_initiate_bootstrap(char *buffer,
- void *user_data)
+static void prv_initiate_bootstrap(char * buffer,
+ void * user_data)
{
- lwm2m_context_t *lwm2mH = (lwm2m_context_t *)user_data;
- lwm2m_server_t *targetP;
-
- // HACK !!!
- lwm2mH->state = STATE_BOOTSTRAP_REQUIRED;
- targetP = lwm2mH->bootstrapServerList;
- while (targetP != NULL) {
- targetP->lifetime = 0;
- targetP = targetP->next;
- }
+ lwm2mH = (lwm2m_context_t *)user_data;
+ lwm2m_server_t * targetP;
+
+ // HACK !!!
+ lwm2mH->state = STATE_BOOTSTRAP_REQUIRED;
+ targetP = lwm2mH->bootstrapServerList;
+ while (targetP != NULL)
+ {
+ targetP->lifetime = 0;
+ targetP = targetP->next;
+ }
}
-static void prv_display_objects(char *buffer,
- void *user_data)
+static void prv_display_objects(char * buffer,
+ void * user_data)
{
- lwm2m_context_t *lwm2mH = (lwm2m_context_t *)user_data;
- lwm2m_object_t *object;
-
- for (object = lwm2mH->objectList; object != NULL; object = object->next) {
- if (NULL != object) {
- switch (object->objID) {
- case LWM2M_SECURITY_OBJECT_ID:
- display_security_object(object);
- break;
- case LWM2M_SERVER_OBJECT_ID:
- display_server_object(object);
- break;
- case LWM2M_ACL_OBJECT_ID:
- break;
- case LWM2M_DEVICE_OBJECT_ID:
- display_device_object(object);
- break;
- case LWM2M_CONN_MONITOR_OBJECT_ID:
- break;
- case LWM2M_FIRMWARE_UPDATE_OBJECT_ID:
- display_firmware_object(object);
- break;
- case LWM2M_LOCATION_OBJECT_ID:
- display_location_object(object);
- break;
- case LWM2M_CONN_STATS_OBJECT_ID:
- break;
- case TEST_OBJECT_ID:
- display_test_object(object);
- break;
- }
- }
- }
+ lwm2mH = (lwm2m_context_t *)user_data;
+ lwm2m_object_t * object;
+
+ for (object = lwm2mH->objectList; object != NULL; object = object->next){
+ if (NULL != object) {
+ switch (object->objID)
+ {
+ case LWM2M_SECURITY_OBJECT_ID:
+ display_security_object(object);
+ break;
+ case LWM2M_SERVER_OBJECT_ID:
+ display_server_object(object);
+ break;
+ case LWM2M_ACL_OBJECT_ID:
+ break;
+ case LWM2M_DEVICE_OBJECT_ID:
+ display_device_object(object);
+ break;
+ case LWM2M_CONN_MONITOR_OBJECT_ID:
+ break;
+ case LWM2M_FIRMWARE_UPDATE_OBJECT_ID:
+ display_firmware_object(object);
+ break;
+ case LWM2M_LOCATION_OBJECT_ID:
+ display_location_object(object);
+ break;
+ case LWM2M_CONN_STATS_OBJECT_ID:
+ break;
+ case TEST_OBJECT_ID:
+ display_test_object(object);
+ break;
+ }
+ }
+ }
}
-static void prv_display_backup(char *buffer,
- void *user_data)
+static void prv_display_backup(char * buffer,
+ void * user_data)
{
- if (NULL != backupObjectArray) {
- int i;
- for (i = 0 ; i < BACKUP_OBJECT_COUNT ; i++) {
- lwm2m_object_t *object = backupObjectArray[i];
- if (NULL != object) {
- switch (object->objID) {
- case LWM2M_SECURITY_OBJECT_ID:
- display_security_object(object);
- break;
- case LWM2M_SERVER_OBJECT_ID:
- display_server_object(object);
- break;
- default:
- break;
- }
- }
- }
- }
+ int i;
+ for (i = 0 ; i < BACKUP_OBJECT_COUNT ; i++) {
+ lwm2m_object_t * object = backupObjectArray[i];
+ if (NULL != object) {
+ switch (object->objID)
+ {
+ case LWM2M_SECURITY_OBJECT_ID:
+ display_security_object(object);
+ break;
+ case LWM2M_SERVER_OBJECT_ID:
+ display_server_object(object);
+ break;
+ default:
+ break;
+ }
+ }
+ }
}
-static void prv_backup_objects(lwm2m_context_t *context)
+static void prv_backup_objects(lwm2m_context_t * context)
{
- uint16_t i;
-
- for (i = 0; i < BACKUP_OBJECT_COUNT; i++) {
- if (NULL != backupObjectArray[i]) {
- switch (backupObjectArray[i]->objID) {
- case LWM2M_SECURITY_OBJECT_ID:
- clean_security_object(backupObjectArray[i]);
- lwm2m_free(backupObjectArray[i]);
- break;
- case LWM2M_SERVER_OBJECT_ID:
- clean_server_object(backupObjectArray[i]);
- lwm2m_free(backupObjectArray[i]);
- break;
- default:
- break;
- }
- }
- backupObjectArray[i] = (lwm2m_object_t *)lwm2m_malloc(sizeof(lwm2m_object_t));
- memset(backupObjectArray[i], 0, sizeof(lwm2m_object_t));
- }
-
- /*
- * Backup content of objects 0 (security) and 1 (server)
- */
- copy_security_object(backupObjectArray[0], (lwm2m_object_t *)LWM2M_LIST_FIND(context->objectList, LWM2M_SECURITY_OBJECT_ID));
- copy_server_object(backupObjectArray[1], (lwm2m_object_t *)LWM2M_LIST_FIND(context->objectList, LWM2M_SERVER_OBJECT_ID));
+ uint16_t i;
+
+ for (i = 0; i < BACKUP_OBJECT_COUNT; i++) {
+ if (NULL != backupObjectArray[i]) {
+ switch (backupObjectArray[i]->objID)
+ {
+ case LWM2M_SECURITY_OBJECT_ID:
+ clean_security_object(backupObjectArray[i]);
+ lwm2m_free(backupObjectArray[i]);
+ break;
+ case LWM2M_SERVER_OBJECT_ID:
+ clean_server_object(backupObjectArray[i]);
+ lwm2m_free(backupObjectArray[i]);
+ break;
+ default:
+ break;
+ }
+ }
+ backupObjectArray[i] = (lwm2m_object_t *)lwm2m_malloc(sizeof(lwm2m_object_t));
+ memset(backupObjectArray[i], 0, sizeof(lwm2m_object_t));
+ }
+
+ /*
+ * Backup content of objects 0 (security) and 1 (server)
+ */
+ copy_security_object(backupObjectArray[0], (lwm2m_object_t *)LWM2M_LIST_FIND(context->objectList, LWM2M_SECURITY_OBJECT_ID));
+ copy_server_object(backupObjectArray[1], (lwm2m_object_t *)LWM2M_LIST_FIND(context->objectList, LWM2M_SERVER_OBJECT_ID));
}
-static void prv_restore_objects(lwm2m_context_t *context)
+static void prv_restore_objects(lwm2m_context_t * context)
{
- lwm2m_object_t *targetP;
-
- /*
- * Restore content of objects 0 (security) and 1 (server)
- */
- targetP = (lwm2m_object_t *)LWM2M_LIST_FIND(context->objectList, LWM2M_SECURITY_OBJECT_ID);
- // first delete internal content
- clean_security_object(targetP);
- // then restore previous object
- copy_security_object(targetP, backupObjectArray[0]);
-
- targetP = (lwm2m_object_t *)LWM2M_LIST_FIND(context->objectList, LWM2M_SERVER_OBJECT_ID);
- // first delete internal content
- clean_server_object(targetP);
- // then restore previous object
- copy_server_object(targetP, backupObjectArray[1]);
-
- // restart the old servers
- fprintf(stdout, "[BOOTSTRAP] ObjectList restored\r\n");
+ lwm2m_object_t * targetP;
+
+ /*
+ * Restore content of objects 0 (security) and 1 (server)
+ */
+ targetP = (lwm2m_object_t *)LWM2M_LIST_FIND(context->objectList, LWM2M_SECURITY_OBJECT_ID);
+ // first delete internal content
+ clean_security_object(targetP);
+ // then restore previous object
+ copy_security_object(targetP, backupObjectArray[0]);
+
+ targetP = (lwm2m_object_t *)LWM2M_LIST_FIND(context->objectList, LWM2M_SERVER_OBJECT_ID);
+ // first delete internal content
+ clean_server_object(targetP);
+ // then restore previous object
+ copy_server_object(targetP, backupObjectArray[1]);
+
+ // restart the old servers
+ fprintf(stdout, "[BOOTSTRAP] ObjectList restored\r\n");
}
-static void update_bootstrap_info(lwm2m_client_state_t *previousBootstrapState,
- lwm2m_context_t *context)
+static void update_bootstrap_info(lwm2m_client_state_t * previousBootstrapState,
+ lwm2m_context_t * context)
{
- if (*previousBootstrapState != context->state) {
- *previousBootstrapState = context->state;
- switch (context->state) {
- case STATE_BOOTSTRAPPING:
+ if (*previousBootstrapState != context->state)
+ {
+ *previousBootstrapState = context->state;
+ switch(context->state)
+ {
+ case STATE_BOOTSTRAPPING:
#ifdef WITH_LOGS
- fprintf(stdout, "[BOOTSTRAP] backup security and server objects\r\n");
+ fprintf(stdout, "[BOOTSTRAP] backup security and server objects\r\n");
#endif
- prv_backup_objects(context);
- break;
- default:
- break;
- }
- }
+ prv_backup_objects(context);
+ break;
+ default:
+ break;
+ }
+ }
}
static void close_backup_object()
{
- int i;
- for (i = 0; i < BACKUP_OBJECT_COUNT; i++) {
- if (NULL != backupObjectArray[i]) {
- switch (backupObjectArray[i]->objID) {
- case LWM2M_SECURITY_OBJECT_ID:
- clean_security_object(backupObjectArray[i]);
- lwm2m_free(backupObjectArray[i]);
- break;
- case LWM2M_SERVER_OBJECT_ID:
- clean_server_object(backupObjectArray[i]);
- lwm2m_free(backupObjectArray[i]);
- break;
- default:
- break;
- }
- }
- }
+ int i;
+ for (i = 0; i < BACKUP_OBJECT_COUNT; i++) {
+ switch (backupObjectArray[i]->objID)
+ {
+ case LWM2M_SECURITY_OBJECT_ID:
+ clean_security_object(backupObjectArray[i]);
+ lwm2m_free(backupObjectArray[i]);
+ break;
+ case LWM2M_SERVER_OBJECT_ID:
+ clean_server_object(backupObjectArray[i]);
+ lwm2m_free(backupObjectArray[i]);
+ break;
+ default:
+ break;
+ }
+ }
}
-#endif
+#endif /* LWM2M_BOOTSTRAP */
+
void print_usage(void)
{
- fprintf(stdout, "Usage: lwm2mclient [OPTION]\r\n");
- fprintf(stdout, "Launch a LWM2M client.\r\n");
- fprintf(stdout, "Options:\r\n");
- fprintf(stdout, " -n NAME\tSet the endpoint name of the Client. Default: testlwm2mclient\r\n");
- fprintf(stdout, " -l PORT\tSet the local UDP port of the Client. Default: 56830\r\n");
- fprintf(stdout, " -h HOST\tSet the hostname of the LWM2M Server to connect to. Default: localhost\r\n");
- fprintf(stdout, " -p PORT\tSet the port of the LWM2M Server to connect to. Default: "LWM2M_STANDARD_PORT_STR"\r\n");
- fprintf(stdout, " -4\t\tUse IPv4 connection. Default: IPv6 connection\r\n");
- fprintf(stdout, " -t TIME\tSet the lifetime of the Client. Default: 300\r\n");
- fprintf(stdout, " -b\t\tBootstrap requested.\r\n");
- fprintf(stdout, " -c\t\tChange battery level over time.\r\n");
-#ifdef WITH_TINYDTLS
- fprintf(stdout, " -i STRING\tSet the device management or bootstrap server PSK identity. If not set use none secure mode\r\n");
- fprintf(stdout, " -s HEXSTRING\tSet the device management or bootstrap server Pre-Shared-Key. If not set use none secure mode\r\n");
+ fprintf(stdout, "Usage: lwm2mclient [OPTION]\r\n");
+ fprintf(stdout, "Launch a LWM2M client.\r\n");
+ fprintf(stdout, "Options:\r\n");
+ fprintf(stdout, " -n NAME\tSet the endpoint name of the Client. Default: testlwm2mclient\r\n");
+ fprintf(stdout, " -l PORT\tSet the local UDP port of the Client. Default: 56830\r\n");
+ fprintf(stdout, " -h HOST\tSet the hostname of the LWM2M Server to connect to. Default: localhost\r\n");
+ fprintf(stdout, " -p PORT\tSet the port of the LWM2M Server to connect to. Default: "LWM2M_STANDARD_PORT_STR"\r\n");
+ fprintf(stdout, " -4\t\tUse IPv4 connection. Default: IPv6 connection\r\n");
+ fprintf(stdout, " -t TIME\tSet the lifetime of the Client. Default: 300\r\n");
+ fprintf(stdout, " -b\t\tBootstrap requested.\r\n");
+ fprintf(stdout, " -c\t\tChange battery level over time.\r\n");
+#ifdef WITH_TINYDTLS
+ fprintf(stdout, " -i STRING\tSet the device management or bootstrap server PSK identity. If not set use none secure mode\r\n");
+ fprintf(stdout, " -s HEXSTRING\tSet the device management or bootstrap server Pre-Shared-Key. If not set use none secure mode\r\n");
#endif
- fprintf(stdout, "\r\n");
+ fprintf(stdout, "\r\n");
}
+int lwm2m_client_main(int argc, char *argv[])
+{
+ client_data_t data;
+ int result;
+ lwm2mH = NULL;
+ int i;
+ const char * localPort = "56830";
+ const char * server = NULL;
+ const char * serverPort = LWM2M_STANDARD_PORT_STR;
+ char * name = "testlwm2mclient";
+ int lifetime = 300;
+ int batterylevelchanging = 0;
+ time_t reboot_time = 0;
+ int opt;
+ bool bootstrapRequested = false;
+ bool serverPortChanged = false;
+
+#ifdef LWM2M_BOOTSTRAP
+ lwm2m_client_state_t previousState = STATE_INITIAL;
+#endif
+
+ char * pskId = NULL;
+ uint16_t pskLen = -1;
+ char * pskBuffer = NULL;
+
+ /*
+ * The function start by setting up the command line interface (which may or not be useful depending on your project)
+ *
+ * This is an array of commands describes as { name, description, long description, callback, userdata }.
+ * The firsts tree are easy to understand, the callback is the function that will be called when this command is typed
+ * and in the last one will be stored the lwm2m context (allowing access to the server settings and the objects).
+ */
+ command_desc_t commands[] =
+ {
+ {"list", "List known servers.", NULL, prv_output_servers, NULL},
+ {"change", "Change the value of resource.", " change URI [DATA]\r\n"
+ " URI: uri of the resource such as /3/0, /3/0/2\r\n"
+ " DATA: (optional) new value\r\n", prv_change, NULL},
+ {"update", "Trigger a registration update", " update SERVER\r\n"
+ " SERVER: short server id such as 123\r\n", prv_update, NULL},
+#ifdef LWM2M_BOOTSTRAP
+ {"bootstrap", "Initiate a DI bootstrap process", NULL, prv_initiate_bootstrap, NULL},
+ {"dispb", "Display current backup of objects/instances/resources\r\n"
+ "\t(only security and server objects are backupped)", NULL, prv_display_backup, NULL},
+
+ {"disp", "Display current objects/instances/resources", NULL, prv_display_objects, NULL},
+#endif
+ {"ls", "List Objects and Instances", NULL, prv_object_list, NULL},
+ {"dump", "Dump an Object", "dump URI"
+ "URI: uri of the Object or Instance such as /3/0, /1\r\n", prv_object_dump, NULL},
+ {"add", "Add support of object 1024", NULL, prv_add, NULL},
+ {"rm", "Remove support of object 1024", NULL, prv_remove, NULL},
+ {"quit", "Quit the client gracefully.", NULL, prv_quit, NULL},
+ {"^C", "Quit the client abruptly (without sending a de-register message).", NULL, NULL, NULL},
+
+ COMMAND_END_LIST
+ };
+
+ memset(&data, 0, sizeof(client_data_t));
+ data.addressFamily = AF_INET;
+
+ opt = 1;
+ while (opt < argc)
+ {
+ if (argv[opt] == NULL
+ || argv[opt][0] != '-'
+ || argv[opt][2] != 0)
+ {
+ print_usage();
+ return 0;
+ }
+ switch (argv[opt][1])
+ {
+ case 'b':
+ bootstrapRequested = true;
+ if (!serverPortChanged) serverPort = LWM2M_BSSERVER_PORT_STR;
+ break;
+ case 'c':
+ batterylevelchanging = 1;
+ break;
+ case 't':
+ opt++;
+ if (opt >= argc)
+ {
+ print_usage();
+ return 0;
+ }
+ if (1 != sscanf(argv[opt], "%d", &lifetime))
+ {
+ print_usage();
+ return 0;
+ }
+ break;
+#ifdef WITH_TINYDTLS
+ case 'i':
+ opt++;
+ if (opt >= argc)
+ {
+ print_usage();
+ return 0;
+ }
+ pskId = argv[opt];
+ break;
+ case 's':
+ opt++;
+ if (opt >= argc)
+ {
+ print_usage();
+ return 0;
+ }
+ psk = argv[opt];
+ break;
+#endif
+ case 'n':
+ opt++;
+ if (opt >= argc)
+ {
+ print_usage();
+ return 0;
+ }
+ name = argv[opt];
+ break;
+ case 'l':
+ opt++;
+ if (opt >= argc)
+ {
+ print_usage();
+ return 0;
+ }
+ localPort = argv[opt];
+ break;
+ case 'h':
+ opt++;
+ if (opt >= argc)
+ {
+ print_usage();
+ return 0;
+ }
+ server = argv[opt];
+ break;
+ case 'p':
+ opt++;
+ if (opt >= argc)
+ {
+ print_usage();
+ return 0;
+ }
+ serverPort = argv[opt];
+ serverPortChanged = true;
+ break;
+ case '4':
+ data.addressFamily = AF_INET;
+ break;
+ default:
+ print_usage();
+ return 0;
+ }
+ opt += 1;
+ }
+#if defined (__TINYARA__)
+ if (argc == SET_PARAM_DM_FRAMEWORK) {
+ /* To handling parameters set through dm frameworks */
+ name = DEFAULT_CLIENT_NAME;
+ lifetime = g_lifetime;
+
+ bootstrapRequested = g_bootstrapRequested;
+
+ if (bootstrapRequested) {
+ server = g_bootstrapserverAddr;
+ serverPort = g_bootstrapserverPort;
+ } else {
+ server = g_serverAddr;
+ serverPort = g_serverPort;
+ }
+ }
+#endif /* __TINYARA__ */
+ if (!server)
+ {
+ server = (AF_INET == data.addressFamily ? DEFAULT_SERVER_IPV4 : DEFAULT_SERVER_IPV6);
+ }
+
+ /*
+ *This call an internal function that create an IPV6 socket on the port 5683.
+ */
+ fprintf(stderr, "Trying to bind LWM2M Client to port %s\r\n", localPort);
+ data.sock = create_socket(localPort, data.addressFamily);
+ if (data.sock < 0)
+ {
+ fprintf(stderr, "Failed to open socket: %d %s\r\n", errno, strerror(errno));
+ return -1;
+ }
+
+ /*
+ * Now the main function fill an array with each object, this list will be later passed to liblwm2m.
+ * Those functions are located in their respective object file.
+ */
+#ifdef WITH_TINYDTLS
+ if (psk != NULL)
+ {
+ pskLen = strlen(psk) / 2;
+ pskBuffer = malloc(pskLen);
+
+ if (NULL == pskBuffer)
+ {
+ fprintf(stderr, "Failed to create PSK binary buffer\r\n");
+ return -1;
+ }
+ // Hex string to binary
+ char *h = psk;
+ char *b = pskBuffer;
+ char xlate[] = "0123456789ABCDEF";
+
+ for ( ; *h; h += 2, ++b)
+ {
+ char *l = strchr(xlate, toupper(*h));
+ char *r = strchr(xlate, toupper(*(h+1)));
+
+ if (!r || !l)
+ {
+ fprintf(stderr, "Failed to parse Pre-Shared-Key HEXSTRING\r\n");
+ return -1;
+ }
+
+ *b = ((l - xlate) << 4) + (r - xlate);
+ }
+ }
+#endif
+
+ char serverUri[50];
+ int serverId = 123;
+ sprintf (serverUri, "coap://%s:%s", server, serverPort);
+#ifdef LWM2M_BOOTSTRAP
+ objArray[0] = get_security_object(serverId, serverUri, pskId, pskBuffer, pskLen, bootstrapRequested);
+#else
+ objArray[0] = get_security_object(serverId, serverUri, pskId, pskBuffer, pskLen, false);
+#endif
+ if (NULL == objArray[0])
+ {
+ fprintf(stderr, "Failed to create security object\r\n");
+ return -1;
+ }
+ data.securityObjP = objArray[0];
+
+ objArray[1] = get_server_object(serverId, "U", lifetime, false);
+ if (NULL == objArray[1])
+ {
+ fprintf(stderr, "Failed to create server object\r\n");
+ return -1;
+ }
+
+ objArray[2] = get_object_device();
+ if (NULL == objArray[2])
+ {
+ fprintf(stderr, "Failed to create Device object\r\n");
+ return -1;
+ }
+
+ objArray[3] = get_object_firmware();
+ if (NULL == objArray[3])
+ {
+ fprintf(stderr, "Failed to create Firmware object\r\n");
+ return -1;
+ }
+
+ objArray[4] = get_object_location();
+ if (NULL == objArray[4])
+ {
+ fprintf(stderr, "Failed to create location object\r\n");
+ return -1;
+ }
+
+ objArray[5] = get_test_object();
+ if (NULL == objArray[5])
+ {
+ fprintf(stderr, "Failed to create test object\r\n");
+ return -1;
+ }
+
+ objArray[6] = get_object_conn_m();
+ if (NULL == objArray[6])
+ {
+ fprintf(stderr, "Failed to create connectivity monitoring object\r\n");
+ return -1;
+ }
+
+ objArray[7] = get_object_conn_s();
+ if (NULL == objArray[7])
+ {
+ fprintf(stderr, "Failed to create connectivity statistics object\r\n");
+ return -1;
+ }
+
+ int instId = 0;
+ objArray[8] = acc_ctrl_create_object();
+ if (NULL == objArray[8])
+ {
+ fprintf(stderr, "Failed to create Access Control object\r\n");
+ return -1;
+ }
+ else if (acc_ctrl_obj_add_inst(objArray[8], instId, 3, 0, serverId)==false)
+ {
+ fprintf(stderr, "Failed to create Access Control object instance\r\n");
+ return -1;
+ }
+ else if (acc_ctrl_oi_add_ac_val(objArray[8], instId, 0, 0b000000000001111)==false)
+ {
+ fprintf(stderr, "Failed to create Access Control ACL default resource\r\n");
+ return -1;
+ }
+ else if (acc_ctrl_oi_add_ac_val(objArray[8], instId, 999, 0b000000000000001)==false)
+ {
+ fprintf(stderr, "Failed to create Access Control ACL resource for serverId: 999\r\n");
+ return -1;
+ }
+ /*
+ * The liblwm2m library is now initialized with the functions that will be in
+ * charge of communication
+ */
+ lwm2mH = lwm2m_init(&data);
+ if (NULL == lwm2mH)
+ {
+ fprintf(stderr, "lwm2m_init() failed\r\n");
+ return -1;
+ }
+
+#ifdef WITH_TINYDTLS
+ data.lwm2mH = lwm2mH;
+#endif
+
+ /*
+ * We configure the liblwm2m library with the name of the client - which shall be unique for each client -
+ * the number of objects we will be passing through and the objects array
+ */
+ result = lwm2m_configure(lwm2mH, name, NULL, NULL, OBJ_COUNT, objArray);
+ if (result != 0)
+ {
+ fprintf(stderr, "lwm2m_configure() failed: 0x%X\r\n", result);
+ return -1;
+ }
+
+ //signal(SIGINT, handle_sigint);
+
+ /**
+ * Initialize value changed callback.
+ */
+ init_value_change(lwm2mH);
+
+ /*
+ * As you now have your lwm2m context complete you can pass it as an argument to all the command line functions
+ * precedently viewed (first point)
+ */
+ for (i = 0 ; commands[i].name != NULL ; i++)
+ {
+ commands[i].userData = (void *)lwm2mH;
+ }
+ fprintf(stdout, "LWM2M Client \"%s\" started on port %s\r\n", name, localPort);
+ fprintf(stdout, "> "); fflush(stdout);
+ /*
+ * We now enter in a while loop that will handle the communications from the server
+ */
+ while (0 == g_quit)
+ {
+ struct timeval tv;
+ fd_set readfds;
+
+ if (g_reboot)
+ {
+ time_t tv_sec;
+
+ tv_sec = lwm2m_gettime();
+
+ if (0 == reboot_time)
+ {
+ reboot_time = tv_sec + 5;
+ }
+ if (reboot_time < tv_sec)
+ {
+ /*
+ * Message should normally be lost with reboot ...
+ */
+ fprintf(stderr, "reboot time expired, rebooting ...");
+ system_reboot();
+ }
+ else
+ {
+ tv.tv_sec = reboot_time - tv_sec;
+ }
+ }
+ else if (batterylevelchanging)
+ {
+ update_battery_level(lwm2mH);
+ tv.tv_sec = 5;
+ }
+ else
+ {
+ tv.tv_sec = 60;
+ }
+ tv.tv_usec = 0;
+
+ FD_ZERO(&readfds);
+ FD_SET(data.sock, &readfds);
+#if defined (__TINYARA__)
+ FD_SET(STDIN_FILENO, &readfds);
+#else
+ FD_SET(stdin, &readfds);
+#endif
+
+ /*
+ * This function does two things:
+ * - first it does the work needed by liblwm2m (eg. (re)sending some packets).
+ * - Secondly it adjusts the timeout value (default 60s) depending on the state of the transaction
+ * (eg. retransmission) and the time between the next operation
+ */
+ result = lwm2m_step(lwm2mH, &(tv.tv_sec));
+ fprintf(stdout, " -> State: ");
+ switch (lwm2mH->state)
+ {
+ case STATE_INITIAL:
+ fprintf(stdout, "STATE_INITIAL\r\n");
+ break;
+ case STATE_BOOTSTRAP_REQUIRED:
+ fprintf(stdout, "STATE_BOOTSTRAP_REQUIRED\r\n");
+ break;
+ case STATE_BOOTSTRAPPING:
+ fprintf(stdout, "STATE_BOOTSTRAPPING\r\n");
+ break;
+ case STATE_REGISTER_REQUIRED:
+ fprintf(stdout, "STATE_REGISTER_REQUIRED\r\n");
+ break;
+ case STATE_REGISTERING:
+ fprintf(stdout, "STATE_REGISTERING\r\n");
+ break;
+ case STATE_READY:
+ fprintf(stdout, "STATE_READY\r\n");
+ break;
+ default:
+ fprintf(stdout, "Unknown...\r\n");
+ break;
+ }
+ if (result != 0)
+ {
+ fprintf(stderr, "lwm2m_step() failed: 0x%X\r\n", result);
+#ifdef LWM2M_BOOTSTRAP
+ if(previousState == STATE_BOOTSTRAPPING)
+ {
+#ifdef WITH_LOGS
+ fprintf(stdout, "[BOOTSTRAP] restore security and server objects\r\n");
+#endif
+ prv_restore_objects(lwm2mH);
+ lwm2mH->state = STATE_INITIAL;
+ }
+ else
+#endif /* LWM2M_BOOTSTRAP */
+ return -1;
+ }
+#ifdef LWM2M_BOOTSTRAP
+ update_bootstrap_info(&previousState, lwm2mH);
+#endif
+ /*
+ * This part will set up an interruption until an event happen on SDTIN or the socket until "tv" timed out (set
+ * with the precedent function)
+ */
+ result = select(FD_SETSIZE, &readfds, NULL, NULL, &tv);
+
+ if (result < 0)
+ {
+ if (errno != EINTR)
+ {
+ fprintf(stderr, "Error in select(): %d %s\r\n", errno, strerror(errno));
+ }
+ }
+ else if (result > 0)
+ {
+ uint8_t buffer[MAX_PACKET_SIZE];
+ int numBytes;
+
+ /*
+ * If an event happens on the socket
+ */
+ if (FD_ISSET(data.sock, &readfds))
+ {
+ struct sockaddr_storage addr;
+ socklen_t addrLen;
+
+ addrLen = sizeof(addr);
+
+ /*
+ * We retrieve the data received
+ */
+ numBytes = recvfrom(data.sock, buffer, MAX_PACKET_SIZE, 0, (struct sockaddr *)&addr, &addrLen);
+
+ if (0 > numBytes)
+ {
+ fprintf(stderr, "Error in recvfrom(): %d %s\r\n", errno, strerror(errno));
+ }
+ else if (0 < numBytes)
+ {
+ char s[INET6_ADDRSTRLEN];
+ in_port_t port;
+
+#ifdef WITH_TINYDTLS
+ dtls_connection_t * connP;
+#else
+ connection_t * connP;
+#endif
+ if (AF_INET == addr.ss_family)
+ {
+ struct sockaddr_in *saddr = (struct sockaddr_in *)&addr;
+ inet_ntop(saddr->sin_family, &saddr->sin_addr, s, INET6_ADDRSTRLEN);
+ port = saddr->sin_port;
+ }
+ else if (AF_INET6 == addr.ss_family)
+ {
+ struct sockaddr_in6 *saddr = (struct sockaddr_in6 *)&addr;
+ inet_ntop(saddr->sin6_family, &saddr->sin6_addr, s, INET6_ADDRSTRLEN);
+ port = saddr->sin6_port;
+ }
+ fprintf(stderr, "%d bytes received from [%s]:%hu\r\n", numBytes, s, ntohs(port));
+
+ /*
+ * Display it in the STDERR
+ */
+ output_buffer(stderr, buffer, numBytes, 0);
+
+ connP = connection_find(data.connList, &addr, addrLen);
+ if (connP != NULL)
+ {
+ /*
+ * Let liblwm2m respond to the query depending on the context
+ */
+#ifdef WITH_TINYDTLS
+ int result = connection_handle_packet(connP, buffer, numBytes);
+ if (0 != result)
+ {
+ printf("error handling message %d\n",result);
+ }
+#else
+ lwm2m_handle_packet(lwm2mH, buffer, numBytes, connP);
+#endif
+ conn_s_updateRxStatistic(objArray[7], numBytes, false);
+ }
+ else
+ {
+ fprintf(stderr, "received bytes ignored!\r\n");
+ }
+ }
+ }
+
+ /*
+ * If the event happened on the SDTIN
+ */
+#if defined (__TINYARA__)
+ else if (FD_ISSET(STDIN_FILENO, &readfds))
+#else
+ else if (FD_ISSET(stdin, &readfds))
+#endif
+ {
+#if defined (__TINYARA__)
+ numBytes = read(STDIN_FILENO, buffer, MAX_PACKET_SIZE - 1);
+#else
+ numBytes = read(stdin, buffer, MAX_PACKET_SIZE - 1);
+#endif
+
+ if (numBytes > 1)
+ {
+ buffer[numBytes] = 0;
+ /*
+ * We call the corresponding callback of the typed command passing it the buffer for further arguments
+ */
+ handle_command(commands, (char*)buffer);
+ }
+ if (g_quit == 0)
+ {
+ fprintf(stdout, "\r\n> ");
+ fflush(stdout);
+ }
+ else
+ {
+ fprintf(stdout, "\r\n");
+ }
+ }
+ }
+ }
+
+ /*
+ * Finally when the loop is left smoothly - asked by user in the command line interface - we unregister our client from it
+ */
+ if (g_quit == 1)
+ {
+#ifdef LWM2M_BOOTSTRAP
+ close_backup_object();
+#endif
+ lwm2m_close(lwm2mH);
+ }
+ close(data.sock);
+ connection_free(data.connList);
+
+ clean_security_object(objArray[0]);
+ lwm2m_free(objArray[0]);
+ clean_server_object(objArray[1]);
+ lwm2m_free(objArray[1]);
+ free_object_device(objArray[2]);
+ free_object_firmware(objArray[3]);
+ free_object_location(objArray[4]);
+ free_test_object(objArray[5]);
+ free_object_conn_m(objArray[6]);
+ free_object_conn_s(objArray[7]);
+ acl_ctrl_free_object(objArray[8]);
+
+#ifdef MEMORY_TRACE
+ if (g_quit == 1)
+ {
+ trace_print(0, 1);
+ }
+#endif
+
+ return 0;
+}
/****************************************************************************
- * API support
+ * TINYARA
+ * DM (Device Management) Frameworks supporting APIs
****************************************************************************/
-char *client_set_serverAddr(FAR const char *serverAddr,
- bool isbootstrap)
+
+#if defined (__TINYARA__)
+
+/* Public APIs */
+
+pthread_addr_t lwm2m_client_run(void)
+{
+
+ lwm2m_client_main(SET_PARAM_DM_FRAMEWORK, NULL);
+ return 0;
+}
+
+char *client_set_serverAddr(FAR const char *serverAddr, bool isbootstrap)
{
if (serverAddr) {
if (isbootstrap) {
return g_serverAddr;
}
-
-char *client_set_serverPort(FAR const char *serverPort,
- bool isbootstrap)
+char *client_set_serverPort(FAR const char *serverPort, bool isbootstrap)
{
if (serverPort) {
if (isbootstrap) {
}
}
-
char *client_get_serverPort(void)
{
return g_serverPort;
-
}
-
int client_set_lifetime(int lifetime)
{
g_lifetime = lifetime;
return 0;
}
-static void process_udpconn(int sockfd, fd_set *readfds)
+static void process_udpconn(int sockfd, fd_set *readfds, client_data_t data)
{
uint8_t buffer[MAX_PACKET_SIZE];
int numBytes;
}
}
+
+lwm2m_context_t *wrapper_get_context(void)
+{
+ return lwm2mH;
+}
+
+int client_object_dump(char *buffer)
+{
+ if (lwm2mH != NULL) {
+ prv_object_dump(buffer, lwm2mH);
+ return 0;
+ } else {
+ fprintf(stderr, "Error calling object dump\n");
+ }
+ return -1;
+}
+
+/* Private APIs */
+
static void prv_close_sock(void)
{
connection_t *connPtr = NULL;
}
}
-pthread_addr_t client_main(void)
+static void clear_client_globals(void)
{
- int result;
- int i;
-
- const char *localPort = "56830";
-#if 0
- const char *server = "192.168.0.4";
- const char *serverPort = LWM2M_STANDARD_PORT_STR;
- char *name = "testlwm2mclient";
- int lifetime = 300;
-#endif
- char *server = g_serverAddr;
- char *serverPort = g_serverPort;
- char *name = "myawesomeclient";
- int lifetime = g_lifetime;
- int batterylevelchanging = 0;
- time_t reboot_time = 0;
- int opt;
- bool bootstrapRequested = g_bootstrapRequested;
- bool serverPortChanged = false;
-
- if (bootstrapRequested) {
- server = g_bootstrapserverAddr;
- serverPort = g_bootstrapserverPort;
- } else {
- server = g_serverAddr;
- serverPort = g_serverPort;
- }
-
-
-#ifdef LWM2M_BOOTSTRAP
- lwm2m_client_state_t previousState = STATE_INITIAL;
-#endif
-
- char *pskId = NULL;
- char *psk = NULL;
- uint16_t pskLen = -1;
- char *pskBuffer = NULL;
-
- /*
- * The function start by setting up the command line interface (which may or not be useful depending on your project)
- *
- * This is an array of commands describes as { name, description, long description, callback, userdata }.
- * The firsts tree are easy to understand, the callback is the function that will be called when this command is typed
- * and in the last one will be stored the lwm2m context (allowing access to the server settings and the objects).
- */
- command_desc_t commands[] = {
- {"list", "List known servers.", NULL, prv_output_servers, NULL},
- {
- "change", "Change the value of resource.", " change URI [DATA]\r\n"
- " URI: uri of the resource such as /3/0, /3/0/2\r\n"
- " DATA: (optional) new value\r\n", prv_change, NULL
- },
- {
- "update", "Trigger a registration update", " update SERVER\r\n"
- " SERVER: short server id such as 123\r\n", prv_update, NULL
- },
-#ifdef LWM2M_BOOTSTRAP
- {"bootstrap", "Initiate a DI bootstrap process", NULL, prv_initiate_bootstrap, NULL},
- {
- "dispb", "Display current backup of objects/instances/resources\r\n"
- "\t(only security and server objects are backupped)", NULL, prv_display_backup, NULL
- },
-#endif
- {"ls", "List Objects and Instances", NULL, prv_object_list, NULL},
- {"disp", "Display current objects/instances/resources", NULL, prv_display_objects, NULL},
- {
- "dump", "Dump an Object", "dump URI"
- "URI: uri of the Object or Instance such as /3/0, /1\r\n", prv_object_dump, NULL
- },
- {"add", "Add support of object 1024", NULL, prv_add, NULL},
- {"rm", "Remove support of object 1024", NULL, prv_remove, NULL},
- {"quit", "Quit the client gracefully.", NULL, prv_quit, NULL},
- {"^C", "Quit the client abruptly (without sending a de-register message).", NULL, NULL, NULL},
-
- COMMAND_END_LIST
- };
-
- printf("Inside client_main check serial\n");
-
- memset(&data, 0, sizeof(client_data_t));
- data.addressFamily = AF_INET;
-#if 0
- opt = 1;
- while (opt < argc) {
- if (argv[opt] == NULL
- || argv[opt][0] != '-'
- || argv[opt][2] != 0) {
- print_usage();
- return 0;
- }
- switch (argv[opt][1]) {
- case 'b':
- bootstrapRequested = true;
- if (!serverPortChanged) {
- serverPort = LWM2M_BSSERVER_PORT_STR;
- }
- break;
- case 'c':
- batterylevelchanging = 1;
- break;
- case 't':
- opt++;
- if (opt >= argc) {
- print_usage();
- return 0;
- }
- if (1 != sscanf(argv[opt], "%d", &lifetime)) {
- print_usage();
- return 0;
- }
- break;
-#ifdef WITH_TINYDTLS
- case 'i':
- opt++;
- if (opt >= argc) {
- print_usage();
- return 0;
- }
- pskId = argv[opt];
- break;
- case 's':
- opt++;
- if (opt >= argc) {
- print_usage();
- return 0;
- }
- psk = argv[opt];
- break;
-#endif
- case 'n':
- opt++;
- if (opt >= argc) {
- print_usage();
- return 0;
- }
- name = argv[opt];
- break;
- case 'l':
- opt++;
- if (opt >= argc) {
- print_usage();
- return 0;
- }
- localPort = argv[opt];
- break;
- case 'h':
- opt++;
- if (opt >= argc) {
- print_usage();
- return 0;
- }
- server = argv[opt];
- break;
- case 'p':
- opt++;
- if (opt >= argc) {
- print_usage();
- return 0;
- }
- serverPort = argv[opt];
- serverPortChanged = true;
- break;
- case '4':
- data.addressFamily = AF_INET;
- break;
- default:
- print_usage();
- return 0;
- }
- opt += 1;
- }
-#endif
- if (!server) {
- server = (AF_INET == data.addressFamily ? DEFAULT_SERVER_IPV4 : DEFAULT_SERVER_IPV6);
- }
-
- /*
- *This call an internal function that create an IPV6 socket on the port 5683.
- */
- fprintf(stderr, "Trying to bind LWM2M Client to port %s\r\n", localPort);
- data.sock = create_socket(localPort, data.addressFamily);
- if (data.sock < 0) {
- fprintf(stderr, "Failed to open socket: %d %s\r\n", errno, strerror(errno));
- return -1;
- }
-
- /*
- * Now the main function fill an array with each object, this list will be later passed to liblwm2m.
- * Those functions are located in their respective object file.
- */
-#ifdef WITH_TINYDTLS
- if (psk != NULL) {
- pskLen = strlen(psk) / 2;
- pskBuffer = malloc(pskLen);
-
- if (NULL == pskBuffer) {
- fprintf(stderr, "Failed to create PSK binary buffer\r\n");
- return -1;
- }
- // Hex string to binary
- char *h = psk;
- char *b = pskBuffer;
- char xlate[] = "0123456789ABCDEF";
-
- for (; *h; h += 2, ++b) {
- char *l = strchr(xlate, toupper(*h));
- char *r = strchr(xlate, toupper(*(h + 1)));
-
- if (!r || !l) {
- fprintf(stderr, "Failed to parse Pre-Shared-Key HEXSTRING\r\n");
- return -1;
- }
-
- *b = ((l - xlate) << 4) + (r - xlate);
- }
- }
-#endif
-
- char serverUri[50];
- int serverId = 123;
- sprintf(serverUri, "coap://%s:%s", server, serverPort);
-#ifdef LWM2M_BOOTSTRAP
- objArray[0] = get_security_object(serverId, serverUri, pskId, pskBuffer, pskLen, bootstrapRequested);
-#else
- objArray[0] = get_security_object(serverId, serverUri, pskId, pskBuffer, pskLen, false);
-#endif
- if (NULL == objArray[0]) {
- fprintf(stderr, "Failed to create security object\r\n");
- return -1;
- }
- data.securityObjP = objArray[0];
-
- objArray[1] = get_server_object(serverId, "U", lifetime, false);
- if (NULL == objArray[1]) {
- fprintf(stderr, "Failed to create server object\r\n");
- return -1;
- }
-
- objArray[2] = get_object_device();
- if (NULL == objArray[2]) {
- fprintf(stderr, "Failed to create Device object\r\n");
- return -1;
- }
-
- objArray[3] = get_object_firmware();
- if (NULL == objArray[3]) {
- fprintf(stderr, "Failed to create Firmware object\r\n");
- return -1;
- }
-
- objArray[4] = get_object_location();
- if (NULL == objArray[4]) {
- fprintf(stderr, "Failed to create location object\r\n");
- return -1;
+ memset(g_bootstrapserverAddr, 0x00, IPADDRLEN_MAX);
+ memset(g_bootstrapserverPort, 0x00, 6);
+ if (lwm2mH->state == STATE_REGISTER_REQUIRED ||
+ lwm2mH->state == STATE_REGISTERING ||
+ lwm2mH->state == STATE_READY) {
+ printf("g_bootstrapRequested = false\n");
+ g_bootstrapRequested = false;
}
+}
- objArray[5] = get_test_object();
- if (NULL == objArray[5]) {
- fprintf(stderr, "Failed to create test object\r\n");
- return -1;
- }
+static void prv_update_server(client_data_t *dataP, uint16_t secObjInstID)
+{
+ char *uri;
+ char *server_host;
+ char *server_port;
- objArray[6] = get_object_conn_m();
- if (NULL == objArray[6]) {
- fprintf(stderr, "Failed to create connectivity monitoring object\r\n");
- return -1;
- }
+ uri = get_server_uri(dataP->securityObjP, secObjInstID);
- objArray[7] = get_object_conn_s();
- if (NULL == objArray[7]) {
- fprintf(stderr, "Failed to create connectivity statistics object\r\n");
- return -1;
+ if (uri == NULL) {
+ return;
}
- int instId = 0;
- objArray[8] = acc_ctrl_create_object();
- if (NULL == objArray[8]) {
- fprintf(stderr, "Failed to create Access Control object\r\n");
- return -1;
- } else if (acc_ctrl_obj_add_inst(objArray[8], instId, 3, 0, serverId) == false) {
- fprintf(stderr, "Failed to create Access Control object instance\r\n");
- return -1;
- } else if (acc_ctrl_oi_add_ac_val(objArray[8], instId, 0, 0b000000000001111) == false) {
- fprintf(stderr, "Failed to create Access Control ACL default resource\r\n");
- return -1;
- } else if (acc_ctrl_oi_add_ac_val(objArray[8], instId, 999, 0b000000000000001) == false) {
- fprintf(stderr, "Failed to create Access Control ACL resource for serverId: 999\r\n");
- return -1;
- }
- objArray[9] = get_power_monitor_object();
- if (NULL == objArray[9]) {
- fprintf(stderr, "Failed to create Power Monitoring object\r\n");
- return -1;
+ // parse uri in the form "coaps://[server_host]:[port]"
+ if (0 == strncmp(uri, "coaps://", strlen("coaps://"))) {
+ server_host = uri + strlen("coaps://");
+ } else if (0 == strncmp(uri, "coap://", strlen("coap://"))) {
+ server_host = uri + strlen("coap://");
} else {
- if (power_monitor_obj_add_inst(objArray[9], instId, 0) == false) {
- fprintf(stderr, "Failed to create Power Monitoring object instance\r\n");
- return -1;
- }
- if (power_monitor_obj_add_inst(objArray[9], instId + 1, 0) == false) {
- fprintf(stderr, "Failed to create Power Monitoring object instance\r\n");
- return -1;
- }
- if (power_monitor_obj_add_inst(objArray[9], instId + 2, 0) == false) {
- fprintf(stderr, "Failed to create Power Monitoring object instance\r\n");
- return -1;
- }
- }
- /*
- * The liblwm2m library is now initialized with the functions that will be in
- * charge of communication
- */
- lwm2mH = lwm2m_init(&data);
- if (NULL == lwm2mH) {
- fprintf(stderr, "lwm2m_init() failed\r\n");
- return -1;
- }
-
-#ifdef WITH_TINYDTLS
- data.lwm2mH = lwm2mH;
-#endif
-
- /*
- * We configure the liblwm2m library with the name of the client - which shall be unique for each client -
- * the number of objects we will be passing through and the objects array
- */
- result = lwm2m_configure(lwm2mH, name, NULL, NULL, OBJ_COUNT, objArray);
- if (result != 0) {
- fprintf(stderr, "lwm2m_configure() failed: 0x%X\r\n", result);
- return -1;
+ return;
}
-
- //signal(SIGINT, handle_sigint);
- printf("Instantiated objects\n");
-
- /**
- * Initialize value changed callback.
- */
- init_value_change(lwm2mH);
-
- /*
- * As you now have your lwm2m context complete you can pass it as an argument to all the command line functions
- * precedently viewed (first point)
- */
- for (i = 0 ; commands[i].name != NULL ; i++) {
- commands[i].userData = (void *)lwm2mH;
+ server_port = strrchr(server_host, ':');
+ if (server_port == NULL) {
+ return;
}
- fprintf(stdout, "LWM2M Client \"%s\" started on port %s\r\n", name, localPort);
- fprintf(stdout, "> ");
- fflush(stdout);
- /*
- * We now enter in a while loop that will handle the communications from the server
- */
- while (0 == g_quit) {
- struct timeval tv;
- fd_set readfds;
- int sockfd;
- connection_t *connPtr = NULL;
-
- struct timespec tv1;
- struct timespec tv2;
- int ret_timestamp;
-
- if (g_reboot) {
- time_t tv_sec;
-
- tv_sec = lwm2m_gettime();
-
- if (0 == reboot_time) {
- reboot_time = tv_sec + 5;
- }
- if (reboot_time < tv_sec) {
- /*
- * Message should normally be lost with reboot ...
- */
- fprintf(stderr, "reboot time expired, rebooting ...");
- system_reboot();
- } else {
- tv.tv_sec = reboot_time - tv_sec;
- }
- } else if (batterylevelchanging) {
- update_battery_level(lwm2mH);
- tv.tv_sec = 5;
+ // remove brackets
+ if (server_host[0] == '[') {
+ server_host++;
+ if (*(server_port - 1) == ']') {
+ *(server_port - 1) = 0;
} else {
- tv.tv_sec = 60;
- }
- tv.tv_usec = 0;
-
- FD_ZERO(&readfds);
- connPtr = ((client_data_t *)(lwm2mH->userData))->connList;
- while (connPtr != NULL) {
- printf("setting %d\n", connPtr->sock);
- FD_SET(connPtr->sock, &readfds);
- connPtr = connPtr->next;
- }
-
- ret_timestamp = clock_gettime(CLOCK_REALTIME, &tv1);
- printf("checking lwm2m_step\n");
- usleep(20000);
-
- /*
- * This function does two things:
- * - first it does the work needed by liblwm2m (eg. (re)sending some packets).
- * - Secondly it adjusts the timeout value (default 60s) depending on the state of the transaction
- * (eg. retransmission) and the time between the next operation
- */
- result = lwm2m_step(lwm2mH, &(tv.tv_sec));
- fprintf(stdout, " -> State: ");
- switch (lwm2mH->state) {
- case STATE_INITIAL:
- fprintf(stdout, "STATE_INITIAL\r\n");
- break;
- case STATE_BOOTSTRAP_REQUIRED:
- fprintf(stdout, "STATE_BOOTSTRAP_REQUIRED\r\n");
- break;
- case STATE_BOOTSTRAPPING:
- fprintf(stdout, "STATE_BOOTSTRAPPING\r\n");
- break;
- case STATE_REGISTER_REQUIRED:
- fprintf(stdout, "STATE_REGISTER_REQUIRED\r\n");
- break;
- case STATE_REGISTERING:
- fprintf(stdout, "STATE_REGISTERING\r\n");
- break;
- case STATE_READY:
- fprintf(stdout, "STATE_READY\r\n");
- break;
- default:
- fprintf(stdout, "Unknown...\r\n");
- break;
- }
- if (result != 0) {
- fprintf(stderr, "lwm2m_step() failed: 0x%X\r\n", result);
- if (previousState == STATE_BOOTSTRAPPING) {
-#ifdef WITH_LOGS
- fprintf(stdout, "[BOOTSTRAP] restore security and server objects\r\n");
-#endif
- prv_restore_objects(lwm2mH);
- lwm2mH->state = STATE_INITIAL;
- } else {
- return -1;
- }
- }
-#ifdef LWM2M_BOOTSTRAP
- update_bootstrap_info(&previousState, lwm2mH);
-#endif
- printf("got connection, now trying select %d:%d, %lu:%lu\n", data.sock + 1, CONFIG_NSOCKET_DESCRIPTORS,
- tv.tv_sec, tv.tv_usec);
- usleep(20000);
- /*
- * This part will set up an interruption until an event happen on SDTIN or the socket until "tv" timed out (set
- * with the precedent function)
- */
- result = select(CONFIG_NFILE_DESCRIPTORS +
- CONFIG_NSOCKET_DESCRIPTORS, &readfds,
- NULL, NULL, &tv);
- ret_timestamp = clock_gettime(CLOCK_REALTIME, &tv2);
- printf("select exits with value %d\n", result);
- usleep(20000);
- printf("time diff %lu:%lu\n", tv2.tv_sec - tv1.tv_sec,
- tv2.tv_nsec - tv1.tv_nsec);
- usleep(20000);
- if (result < 0) {
- if (errno != EINTR) {
- fprintf(stderr, "Error in select(): %d %s\r\n", errno, strerror(errno));
- }
- } else if (result > 0) {
- uint8_t buffer[MAX_PACKET_SIZE];
- int numBytes;
-
- /*
- * If an event happens on the socket
- */
- connPtr = ((client_data_t *)(lwm2mH->userData))->connList;
- while (connPtr != NULL) {
- process_udpconn(connPtr->sock, &readfds);
- connPtr = connPtr->next;
- }
- }
- }
-
- /*
- * Finally when the loop is left smoothly - asked by user in the command line interface - we unregister our client from it
- */
- if (g_quit == 1) {
-#ifdef LWM2M_BOOTSTRAP
- if (g_bootstrapRequested == true) {
- close_backup_object();
+ return;
}
-#endif
- clear_client_globals();
- lwm2m_close(lwm2mH);
}
+ // split strings
+ *server_port = 0;
+ server_port++;
- close(data.sock);
- prv_close_sock();
- connection_free(data.connList);
-
- clean_security_object(objArray[0]);
- lwm2m_free(objArray[0]);
- clean_server_object(objArray[1]);
- lwm2m_free(objArray[1]);
- free_object_device(objArray[2]);
- free_object_firmware(objArray[3]);
- free_object_location(objArray[4]);
- free_test_object(objArray[5]);
- free_object_conn_m(objArray[6]);
- free_object_conn_s(objArray[7]);
- acl_ctrl_free_object(objArray[8]);
- power_monitor_free_object(objArray[9]);
-
-#ifdef MEMORY_TRACE
- if (g_quit == 1) {
- trace_print(0, 1);
- }
-#endif
-
-
- printf("Exiting wakaama client thread\n");
- g_quit = 0;
- return 0;
-}
-
-lwm2m_context_t *wrapper_get_context(void)
-{
- return lwm2mH;
-}
-
-int client_object_dump(char *buffer)
-{
- if (lwm2mH != NULL) {
- prv_object_dump(buffer, lwm2mH);
- return 0;
- } else {
- fprintf(stderr, "Error calling object dump\n");
- }
- return -1;
+ client_set_serverAddr(server_host, false);
+ client_set_serverPort(server_port, false);
}
+#endif /* __TINYARA__ */
#ifndef LWM2MCLIENT_H_
#define LWM2MCLIENT_H_
#include <pthread.h>
+
#include "liblwm2m.h"
extern int g_reboot;
-extern char *ipaddr;
-extern char *port;
/*
* 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);
+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);
+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);
+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 1024
-lwm2m_object_t *get_test_object(void);
-void free_test_object(lwm2m_object_t *object);
-void display_test_object(lwm2m_object_t *objectP);
+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);
+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);
+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);
+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);
+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);
+void handle_value_changed(lwm2m_context_t* lwm2mH, lwm2m_uri_t* uri, const char * value, size_t valueLength);
/*
- * 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);
-pthread_addr_t client_main(void);
-
-/*
- * Server IP address, Port
+ * TINYARA
+ * DM (Device Management) Frameworks APIs
*/
+pthread_addr_t lwm2m_client_run(void);
char *client_set_serverAddr(FAR const char *serverAddr, bool isbootstrap);
char *client_get_serverAddr(void);
char *client_set_serverPort(FAR const char *serverPort, bool isbootstrap);
char *client_get_serverPort(void);
-int client_object_dump(char *buffer);
-
+int client_object_dump(char *buffer);
int client_set_lifetime(int lifetime);
+int client_change_resource(char *buffer, void *user_data);
+
void client_initiate_bootstrap(void);
void client_close(void);
-int client_change_resource(char *buffer, void *user_data);
+
+/*
+ * 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_ */
#include <string.h>
#include <ctype.h>
-#include "connectivity_interface.h"
-
// Resource Id's:
#define RES_M_NETWORK_BEARER 0
#define RES_M_AVL_NETWORK_BEARER 1
#define RES_O_CELL_ID 8
#define RES_O_SMNC 9
#define RES_O_SMCC 10
-#define RES_O_RFCHANNEL 11
-#define RES_O_TX_POWER 12
-#define RES_O_LISTEN_INTERVAL 13
-#define RES_O_NOISE 14
-#define RES_O_RATE 15
-#define RES_O_LQI 16
-#define RES_O_WIFI_VERSION 17
-
-#if 0
+
#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_LINK_UTILIZATION 666
#define VALUE_SMNC 33
#define VALUE_SMCC 44
-#endif
-
-
typedef struct
{
-#if 0
char ipAddresses[2][16]; // limited to 2!
char routerIpAddresses[2][16]; // limited to 2!
long cellId;
int signalStrength;
int linkQuality;
int linkUtilization;
- int rfChannel;
- uint8_t txPower;
- int listenInterval;
-
- int noise;
- int rate;
- int lqi;
- char version;
-#endif
- char ipAddresses[2][16]; // limited to 2!
- int signalStrength;
- int rate;
- int nwbearer;
- int available_bearer;
} conn_m_data_t;
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: fetch_network_bearer
- *
- * Description:
- * To get the underlined network bearer for lwm2m from connectivity manager
- *
- * Returned Value:
- *
- *
- ****************************************************************************/
-#if 0
-static void fetch_network_bearer(int *value)
-{
- (*value)=0;
-}
-#endif
-/****************************************************************************
- * Name: fetch_avl_network_bearer
- *
- * Description:
- * To get the available underlined network bearer for lwm2m from connectivity manager
- *
- * Returned Value:
- *
- *
- ****************************************************************************/
-#if 0
-static void fetch_avl_network_bearer(int *value)
-{
- (*value)=0;
-}
-#endif
-/****************************************************************************
- * Name: fetch_rssi
- *
- * Description:
- * Get signal strength value from connectivity manager
- *
- * Returned Value:
- *
- *
- ****************************************************************************/
-#if 0
-static void fetch_rssi(int *value)
-{
-#if defined(CONFIG_WICED) && (CONFIG_ARCH_CHIP_BCM4390X == 1)
- wwd_wifi_get_rssi(value);
- printf("address of rssi is %d\n", value);
-#else
- (*value)=get_signal_strength();
-#endif
-}
-#endif
-/****************************************************************************
- * Name: fetch_channel
- *
- * Description:
- * Get RF channel from driver
- *
- * Returned Value:
- *
- *
- ****************************************************************************/
-#if 0
-static void fetch_channel(int *value)
-{
-#if defined(CONFIG_WICED) && (CONFIG_ARCH_CHIP_BCM4390X == 1)
- wwd_wifi_get_channel(WWD_STA_INTERFACE, value);
-#else
- *value = 0;
-#endif
-
-}
-#endif
-/****************************************************************************
- * Name: fetch_lqi
- *
- * Description:
- * Get link quality index value from connectivity manager
- *
- * Returned Value:
- *
- *
- ****************************************************************************/
-#if 0
- static void fetch_lqi(int *value)
-{
-#if defined(CONFIG_WICED) && (CONFIG_ARCH_CHIP_BCM4390X == 1)
- wwd_wifi_get_rssi(value);
-#else
- (*value)=get_signal_strength();
-#endif
-}
-#endif
-
-/****************************************************************************
- * Name: fetch_tx_power
- *
- * Description:
- * Get tx power
- *
- * Returned Value:
- *
- *
- ****************************************************************************/
-#if 0
-static void fetch_tx_power(uint8_t *value)
-{
-#if defined(CONFIG_WICED) && (CONFIG_ARCH_CHIP_BCM4390X == 1)
- wwd_wifi_get_tx_power(value);
-#else
- *value = 0;
-#endif
-
-}
-#endif
-/****************************************************************************
- * Name: fetch_listen_interval
- *
- * Description:
- * Get tx power
- *
- * Returned Value:
- *
- *
- ****************************************************************************/
-#if 0
-static void fetch_listen_interval(wiced_listen_interval_t* value)
-{
-#if defined(CONFIG_WICED) && (CONFIG_ARCH_CHIP_BCM4390X == 1)
- wwd_wifi_get_listen_interval(value);
-#else
- *value = 0;
-#endif
-
-}
-#endif
-/****************************************************************************
- * Name: fetch_noise
- *
- * Description:
- * Get noise
- *
- * Returned Value:
- *
- *
- ****************************************************************************/
-#if 0
-static void fetch_noise(int *value)
-{
-#if defined(CONFIG_WICED) && (CONFIG_ARCH_CHIP_BCM4390X == 1)
- wwd_wifi_get_noise(value);
-#else
- *value = 0;
-#endif
-}
-#endif
-/****************************************************************************
- * Name: fetch_rate
- *
- * Description:
- * Get the transmision data rate for provided interface
- *
- * Returned Value:
- *
- *
- ****************************************************************************/
-#if 0
-static void fetch_rate(int *value)
-{
-#if defined(CONFIG_WICED) && (CONFIG_ARCH_CHIP_BCM4390X == 1)
- wwd_wifi_get_rate(WWD_STA_INTERFACE,value);
-#else
- *value = 0;
-#endif
-}
-#endif
-
-/****************************************************************************
- * Name: fetch_wifi_version
- *
- * Description:
- * Get the transmision data rate for provided interface
- *
- * Returned Value:
- *
- *
- ****************************************************************************/
-//static void fetch_wifi_version(char* value, uint8_t length)
-//char fetch_wifi_version (char value, uint8_t length)
-//{
-//#if defined(CONFIG_WICED) && (CONFIG_ARCH_CHIP_BCM4390X == 1)
-// wwd_wifi_get_wifi_version(value, sizeof(value));
-// printf("wifi version called is %c\n", value);
-//#else
-// *value = a;
-//#endif
-// return value;
-//}
-
-/****************************************************************************
- * Name: fetch_ip_address
- *
- * Description:
- * Get the assinged IPv4/IPv6 address from Connectivity Manager
- *
- * Returned Value:
- *
- ****************************************************************************/
-#if 0
-static void fetch_ip_address(char *value)
-{
- get_ip_address(value);
-}
-#endif
-/****************************************************************************
- * Name: fetch_router_ip_address
- *
- * Description:
- * Get the Router's IPv4/IPv6 address from Connectivity Manager
- *
- * Returned Value:
- *
- *
- ****************************************************************************/
-#if 0
-static void fetch_router_ip_address(char *value)
-{
- get_router_ip_address(value);
-}
-#endif
-/****************************************************************************
- * Name: fetch_link_utilization
- *
- * Description:
- * Get the link utilization statistics from Connectivity Manager
- *
- * Returned Value:
- *
- *
- ****************************************************************************/
-#if 0
-static void fetch_link_utilization(int *value)
-{
- (*value)=get_link_utilization();
-}
-#endif
-/****************************************************************************
- * Name: fetch_APN
- *
- * Description:
- * Get APN value from Connectivity Manager
- *
- * Returned Value:
- *
- *
- ****************************************************************************/
-#if 0
-static void fetch_APN(char *value)
-{
- strcpy(value,"\0");
-}
-#endif
-/****************************************************************************
- * Name: fetch_cell_id
- *
- * Description:
- * Get cell id value from Connectivity Manager
- *
- * Returned Value:
- *
- *
- ****************************************************************************/
-#if 0
-static void fetch_cell_id(int *value)
-{
- (*value)=0;
-}
-#endif
-/****************************************************************************
- * Name: fetch_SMNC
- *
- * Description:
- *
- *
- * Returned Value:
- *
- *
- ****************************************************************************/
-#if 0
-static void fetch_SMNC(int *value)
-{
- (*value)=0;
-}
-#endif
-/****************************************************************************
- * Name: fetch_SMCC
- *
- * Description:
- *
- *
- * Returned Value:
- *
- *
- ****************************************************************************/
-#if 0
-static void fetch_SMCC(int *value)
-{
- (*value)=0;
-}
-#endif
-/****************************************************************************
- * Name: fetch_initial_values
- *
- * Description:
- * Get initialization values from connectivity manager
- *
- * Returned Value:
- *
- *
- ****************************************************************************/
-static void fetch_initial_values(conn_m_data_t *myData)
-{
-#if 0
- fetch_cell_id(&myData->cellId);
- fetch_rssi(&myData->signalStrength);
- fetch_lqi(&myData->linkQuality);
- fetch_link_utilization(&myData->linkUtilization);
- fetch_ip_address(*(myData->ipAddresses + 0));
- fetch_router_ip_address(*(myData->routerIpAddresses + 0));
- fetch_channel(&myData->rfChannel);
- fetch_tx_power(&myData->txPower);
- fetch_listen_interval(&myData->listenInterval);
- fetch_noise(&myData->noise);
- fetch_rate(&myData->rate);
- fetch_lqi(&myData->lqi);
-#endif
- get_network_bearer(&myData->nwbearer);
- get_avl_network_bearer(&myData->available_bearer);
- get_signal_strength(&myData->signalStrength);
- get_bitrate(&myData->rate);
- get_ip_address(&myData->ipAddresses);
-}
-
-/****************************************************************************
- * Name: prv_set_value
- *
- * Description:
- *
- *
- * Returned Value:
- * Return the appropriate error code or success code value
- *
- ****************************************************************************/
-
static uint8_t prv_set_value(lwm2m_data_t * dataP,
conn_m_data_t * connDataP)
{
- int value;
- uint8_t tx_val;
- char apn[20];
switch (dataP->id)
{
case RES_M_NETWORK_BEARER:
- get_network_bearer(&value);
- connDataP->nwbearer = value;
- printf("nwbearer is %d\n", value);
- lwm2m_data_encode_int(connDataP->nwbearer, dataP);
+ lwm2m_data_encode_int(VALUE_NETWORK_BEARER_GSM, dataP);
return COAP_205_CONTENT;
case RES_M_AVL_NETWORK_BEARER:
lwm2m_data_t * subTlvP;
subTlvP = lwm2m_data_new(riCnt);
subTlvP[0].id = 0;
- get_avl_network_bearer(&value);
- connDataP->available_bearer = value;
- lwm2m_data_encode_int(connDataP->available_bearer, subTlvP);
+ lwm2m_data_encode_int(VALUE_AVL_NETWORK_BEARER_1, subTlvP);
lwm2m_data_encode_instances(subTlvP, riCnt, dataP);
return COAP_205_CONTENT ;
}
case RES_M_RADIO_SIGNAL_STRENGTH: //s-int
- get_signal_strength(&value);
- connDataP->signalStrength = value;
lwm2m_data_encode_int(connDataP->signalStrength, dataP);
return COAP_205_CONTENT;
case RES_O_LINK_QUALITY: //s-int
- /* TODO */
-#if 0
- connDataP->linkQuality=value;
lwm2m_data_encode_int(connDataP->linkQuality, dataP);
-#endif
return COAP_205_CONTENT ;
case RES_M_IP_ADDRESSES:
for (ri = 0; ri < riCnt; ri++)
{
subTlvP[ri].id = ri;
- get_ip_address(*(connDataP->ipAddresses + ri));
lwm2m_data_encode_string(connDataP->ipAddresses[ri], subTlvP + ri);
}
lwm2m_data_encode_instances(subTlvP, riCnt, dataP);
case RES_O_ROUTER_IP_ADDRESS:
{
- /* TODO */
-#if 0
int ri, riCnt = 1; // reduced to 1 instance to fit in one block size
lwm2m_data_t* subTlvP = lwm2m_data_new(riCnt);
for (ri=0; ri<riCnt; ri++)
{
subTlvP[ri].id = ri;
- /* TODO */
lwm2m_data_encode_string(connDataP->routerIpAddresses[ri], subTlvP + ri);
}
lwm2m_data_encode_instances(subTlvP, riCnt, dataP);
-#endif
return COAP_205_CONTENT ;
}
break;
case RES_O_LINK_UTILIZATION:
- /* TODO */
-#if 0
lwm2m_data_encode_int(connDataP->linkUtilization, dataP);
-#endif
return COAP_205_CONTENT;
case RES_O_APN:
lwm2m_data_t * subTlvP;
subTlvP = lwm2m_data_new(riCnt);
subTlvP[0].id = 0;
- /* Not used */
- lwm2m_data_encode_string(apn, subTlvP);
+ lwm2m_data_encode_string(VALUE_APN_1, subTlvP);
lwm2m_data_encode_instances(subTlvP, riCnt, dataP);
return COAP_205_CONTENT;
}
break;
case RES_O_CELL_ID:
- /* Not used */
+ lwm2m_data_encode_int(connDataP->cellId, dataP);
return COAP_205_CONTENT ;
case RES_O_SMNC:
- /* Not used */
- lwm2m_data_encode_int(value, dataP);
+ lwm2m_data_encode_int(VALUE_SMNC, dataP);
return COAP_205_CONTENT ;
case RES_O_SMCC:
- /* Not used */
- lwm2m_data_encode_int(value, dataP);
+ lwm2m_data_encode_int(VALUE_SMCC, dataP);
return COAP_205_CONTENT ;
- case RES_O_RFCHANNEL:
- /* TODO */
- printf("channel: %d\n", value);
- lwm2m_data_encode_int(value, dataP);
- return COAP_205_CONTENT;
-
- case RES_O_TX_POWER:
- /* TODO */
- return COAP_205_CONTENT;
-
- case RES_O_LISTEN_INTERVAL:
-{
- /* TODO */
-#if 0
- wiced_listen_interval_t interval_value;
- fetch_listen_interval(&interval_value);
-#endif
- lwm2m_data_encode_int(value, dataP);
- return COAP_205_CONTENT;
-}
-
- case RES_O_NOISE:
- /* TODO */
- printf("Noise: %d dbm\n", value);
- lwm2m_data_encode_int(value, dataP);
- return COAP_205_CONTENT;
-
- case RES_O_RATE:
- get_bitrate(&value);
- printf("Rate: %d kbps\n ", value);
- lwm2m_data_encode_int(value, dataP);
- return COAP_205_CONTENT;
-
- case RES_O_LQI:
- /* TODO */
- if (value < -100)
- value = 0;
- else{
- if (value > -50)
- value = 100;
- else{
- value = 2*(value+100);
- }
- }
- printf("LQI: %d (%)\n", value);
- lwm2m_data_encode_int(value, dataP);
- return COAP_205_CONTENT;
-
default:
return COAP_404_NOT_FOUND ;
}
if (*numDataP == 0)
{
uint16_t resList[] = {
-#if 0
RES_M_NETWORK_BEARER,
RES_M_AVL_NETWORK_BEARER,
RES_M_RADIO_SIGNAL_STRENGTH,
RES_O_APN,
RES_O_CELL_ID,
RES_O_SMNC,
- RES_O_SMCC,
- RES_O_RFCHANNEL
-#endif
- RES_M_NETWORK_BEARER,
- RES_M_AVL_NETWORK_BEARER,
- RES_M_RADIO_SIGNAL_STRENGTH,
- RES_M_IP_ADDRESSES,
- RES_O_RATE
+ RES_O_SMCC
};
int nbRes = sizeof(resList) / sizeof(uint16_t);
*/
if (NULL != connObj->userData)
{
- conn_m_data_t *myData = (conn_m_data_t*) connObj->userData;
-#if 0
+ 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;
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
- fetch_initial_values(myData);
-#endif
}
else
{
break;
case RES_O_LINK_QUALITY:
-#if 0
if (1 == lwm2m_data_decode_int(dataArray, &value))
{
data->linkQuality = value;
{
result = COAP_400_BAD_REQUEST;
}
-#endif
break;
case RES_M_IP_ADDRESSES:
break;
case RES_O_ROUTER_IP_ADDRESS:
-#if 0
if (sizeof(data->routerIpAddresses[0]) <= dataArray->value.asBuffer.length)
{
result = COAP_400_BAD_REQUEST;
data->routerIpAddresses[0][dataArray->value.asBuffer.length] = 0;
result = COAP_204_CHANGED;
}
-#endif
break;
case RES_O_CELL_ID:
-#if 0
if (1 == lwm2m_data_decode_int(dataArray, &value))
{
data->cellId = value;
{
result = COAP_400_BAD_REQUEST;
}
-#endif
break;
default:
return result;
}
+
*
* Resources:
*
- * Name | ID | Oper. | Inst. | Mand.| Type | Range | Units | Descripton |
- * SMS Tx Counter | 0 | R | Single| No | Integer | | | |
- * SMS Rx Counter | 1 | R | Single| No | Integer | | | |
- * Tx Data | 2 | R | Single| No | Integer | | kByte | |
- * Rx Data | 3 | R | Single| No | Integer | | kByte | |
- * Max Message Size | 4 | R | Single| No | Integer | | Byte | |
- * Average Message Size | 5 | R | Single| No | Integer | | Byte | |
- * StartOrReset | 6 | E | Single| Yes | Integer | | | |
+ * Name | ID | Oper. | Inst. | Mand.| Type | Range | Units | Description |
+ * SMS Tx Counter | 0 | R | Single| No | Integer | | | |
+ * SMS Rx Counter | 1 | R | Single| No | Integer | | | |
+ * Tx Data | 2 | R | Single| No | Integer | | kByte | |
+ * Rx Data | 3 | R | Single| No | Integer | | kByte | |
+ * Max Message Size | 4 | R | Single| No | Integer | | Byte | |
+ * Average Message Size | 5 | R | Single| No | Integer | | Byte | |
+ * StartOrReset | 6 | E | Single| Yes | Integer | | | |
*/
#include "liblwm2m.h"
-#include "tinyara/net/net.h"
+
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define RES_O_MAX_MESSAGE_SIZE 4
#define RES_O_AVERAGE_MESSAGE_SIZE 5
#define RES_M_START_OR_RESET 6
-#define RES_O_COLLECTION_PERIOD 7
typedef struct
{
int64_t avrMessageSize;
int64_t messageCount; // private for incremental average calc.
bool collectDataStarted;
- uint32_t collectionPeriod;
} conn_s_data_t;
-
-/****************************************************************************
- * Name: fetch_smsTx
- *
- * Description:
- * To get the smsTx statistic value for lwm2m from connectivity manager
- *
- * Returned Value:
- *
- *
- ****************************************************************************/
- void fetch_smsTx(int *value);
-
- /****************************************************************************
- * Name: fetch_smsRx
- *
- * Description:
- * To get the smsRx statistic value forlwm2m from connectivity manager
- *
- * Returned Value:
- *
- *
- ****************************************************************************/
- void fetch_smsRx(int *value);
-
-/****************************************************************************
- * Name: fetch_txDataByte
- *
- * Description:
- * To get the txDataByte value for lwm2m from connectivity manager
- *
- * Returned Value:
- *
- *
- ****************************************************************************/
- void fetch_txDataByte(int *value);
-
-/****************************************************************************
- * Name: fetch_rxDataByte
- *
- * Description:
- * To get the rxDataByte value for lwm2m from connectivity manager
- *
- * Returned Value:
- *
- *
- ****************************************************************************/
- void fetch_rxDataByte(int *value);
-
-/****************************************************************************
- * Name: fetch_maxMessageSize
- *
- * Description:
- * To get the maximum message size for lwm2m from connectivity manager
- *
- * Returned Value:
- *
- *
- ****************************************************************************/
- void fetch_maxMessageSize(int *value);
-
-/****************************************************************************
- * Name: fetch_avrMessageSize
- *
- * Description:
- * To get the avegare message size for lwm2m from connectivity manager
- *
- * Returned Value:
- *
- *
- ****************************************************************************/
- void fetch_avrMessageSize(int *value);
-
-
-
-/****************************************************************************
- * Name: fetch_smsTx
- *
- * Description:
- * To get the smsTx statistic value for lwm2m from connectivity manager
- *
- * Returned Value:
- *
- *
- ****************************************************************************/
-
- void fetch_smsTx(int *value)
-{
- (*value)=0;
-}
-
- /****************************************************************************
- * Name: fetch_smsRx
- *
- * Description:
- * To get the smsRx statistic value forlwm2m from connectivity manager
- *
- * Returned Value:
- *
- *
- ****************************************************************************/
-
-void fetch_smsRx(int *value)
-{
- (*value)=0;
-}
-
- /****************************************************************************
- * Name: fetch_txDataByte
- *
- * Description:
- * To get the txDataByte value for lwm2m from connectivity manager
- *
- * Returned Value:
- *
- *
- ****************************************************************************/
-
-void fetch_txDataByte(int *value)
-{
-#ifdef CONFIG_WL_WICED
- (*value)= wifi_tx_count/1000;
-#endif
-#ifdef CONFIG_ENC28J60
- (*value)= eth_tx_count/1000;
-#endif
-
-}
-
- /****************************************************************************
- * Name: fetch_rxDataByte
- *
- * Description:
- * To get the rxDataByte value for lwm2m from connectivity manager
- *
- * Returned Value:
- *
- *
- ****************************************************************************/
-
- void fetch_rxDataByte(int *value)
-{
-#ifdef CONFIG_WL_WICED
- (*value)=wifi_total_message_size/1000;
-#endif
-#ifdef CONFIG_ENC28J60
- (*value)=eth_total_message_size/1000;
-#endif
-}
-
- /****************************************************************************
- * Name: fetch_maxMessageSize
- *
- * Description:
- * To get the maximum message size for lwm2m from connectivity manager
- *
- * Returned Value:
- *
- *
- ****************************************************************************/
-
- void fetch_maxMessageSize(int *value)
-{
-#ifdef CONFIG_WL_WICED
- (*value)=wifi_max_message_size/1000;
-#endif
-#ifdef CONFIG_ENC28J60
- (*value)=eth_max_message_size/1000;
-#endif
-}
-
- /****************************************************************************
- * Name: fetch_avrMessageSize
- *
- * Description:
- * To get the avegare message size for lwm2m from connectivity manager
- *
- * Returned Value:
- *
- *
- ****************************************************************************/
-
- void fetch_avrMessageSize(int *value)
-{
-#ifdef CONFIG_WL_WICED
- (*value)=wifi_avg_message_size/1000;
-#endif
-#ifdef CONFIG_ENC28J60
- (*value)=eth_avg_message_size/1000;
-#endif
-
-}
-
static uint8_t prv_set_tlv(lwm2m_data_t * dataP, conn_s_data_t * connStDataP)
{
switch (dataP->id) {
case RES_O_SMS_TX_COUNTER:
- //fetch_smsTx(&connStDataP->smsTxCounter);
lwm2m_data_encode_int(connStDataP->smsTxCounter, dataP);
return COAP_205_CONTENT;
break;
case RES_O_SMS_RX_COUNTER:
- // fetch_smsRx(&connStDataP->smsRxCounter);
lwm2m_data_encode_int(connStDataP->smsRxCounter, dataP);
return COAP_205_CONTENT;
break;
case RES_O_TX_DATA:
- //fetch_txDataByte(&connStDataP->txDataByte);
lwm2m_data_encode_int(connStDataP->txDataByte/1024, dataP);
return COAP_205_CONTENT;
break;
case RES_O_RX_DATA:
- //fetch_rxDataByte(&connStDataP->rxDataByte);
lwm2m_data_encode_int(connStDataP->rxDataByte/1024, dataP);
return COAP_205_CONTENT;
break;
case RES_O_MAX_MESSAGE_SIZE:
- //fetch_maxMessageSize(&connStDataP->maxMessageSize);
lwm2m_data_encode_int(connStDataP->maxMessageSize, dataP);
return COAP_205_CONTENT;
break;
case RES_O_AVERAGE_MESSAGE_SIZE:
- //fetch_avrMessageSize(&connStDataP->avrMessageSize);
lwm2m_data_encode_int(connStDataP->avrMessageSize, dataP);
return COAP_205_CONTENT;
break;
- case RES_O_COLLECTION_PERIOD:
- //fetch_avrMessageSize(&connStDataP->collectionPeriod);
- lwm2m_data_encode_int(connStDataP->collectionPeriod, dataP);
- return COAP_205_CONTENT;
- break;
default:
return COAP_404_NOT_FOUND ;
}
RES_O_TX_DATA,
RES_O_RX_DATA,
RES_O_MAX_MESSAGE_SIZE,
- RES_O_AVERAGE_MESSAGE_SIZE,
- RES_O_COLLECTION_PERIOD,
+ RES_O_AVERAGE_MESSAGE_SIZE
};
int nbRes = sizeof(resList) / sizeof(uint16_t);
myData->maxMessageSize = 0;
myData->avrMessageSize = 0;
myData->messageCount = 0;
- myData->collectionPeriod = 0;
myData->collectDataStarted = start;
-#ifdef CONFIG_WL_WICED
- wifi_tx_count=0;
- wifi_rx_count=0;
- wifi_max_message_size=0;
- wifi_avg_message_size=0;
- wifi_total_message_size=0;
-#endif
-#ifdef CONFIG_ENC28J60
- eth_tx_count=0;
- eth_rx_count=0;
- eth_max_message_size=0;
- eth_avg_message_size=0;
- eth_total_message_size=0;
-#endif
-
}
static uint8_t prv_exec(uint16_t instanceId, uint16_t resourceId,
}
}
-#if 1
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 (smsBased) myData->smsRxCounter++;
}
}
-#endif
+
lwm2m_object_t * get_object_conn_s(void)
{
+++ /dev/null
-
-/*
- * This connectivity statistics object is optional and single instance only
- *
- * Resources:
- *
- * Name | ID | Oper. | Inst. | Mand.| Type | Range | Units | Descripton |
- * SMS Tx Counter | 0 | R | Single| No | Integer | | | |
- * SMS Rx Counter | 1 | R | Single| No | Integer | | | |
- * Tx Data | 2 | R | Single| No | Integer | | kByte | |
- * Rx Data | 3 | R | Single| No | Integer | | kByte | |
- * Max Message Size | 4 | R | Single| No | Integer | | Byte | |
- * Average Message Size | 5 | R | Single| No | Integer | | Byte | |
- * StartOrReset | 6 | E | Single| Yes | Integer | | | |
- */
-
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-
-#include "../../core/liblwm2m.h"
-#include "../../../../os/include/tinyara/net/net.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_COLLECTION_PERIOD 7
-
-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;
- uint32_t collectionPeriod;
-} conn_s_data_t;
-
-/****************************************************************************
- * Name: fetch_smsTx
- *
- * Description:
- * To get the smsTx statistic value for lwm2m from connectivity manager
- *
- * Returned Value:
- *
- *
- ****************************************************************************/
- void fetch_smsTx(int *value);
-
- /****************************************************************************
- * Name: fetch_smsRx
- *
- * Description:
- * To get the smsRx statistic value forlwm2m from connectivity manager
- *
- * Returned Value:
- *
- *
- ****************************************************************************/
- void fetch_smsRx(int *value);
-
-/****************************************************************************
- * Name: fetch_txDataByte
- *
- * Description:
- * To get the txDataByte value for lwm2m from connectivity manager
- *
- * Returned Value:
- *
- *
- ****************************************************************************/
- void fetch_txDataByte(int *value);
-
-/****************************************************************************
- * Name: fetch_rxDataByte
- *
- * Description:
- * To get the rxDataByte value for lwm2m from connectivity manager
- *
- * Returned Value:
- *
- *
- ****************************************************************************/
- void fetch_rxDataByte(int *value);
-
-/****************************************************************************
- * Name: fetch_maxMessageSize
- *
- * Description:
- * To get the maximum message size for lwm2m from connectivity manager
- *
- * Returned Value:
- *
- *
- ****************************************************************************/
- void fetch_maxMessageSize(int *value);
-
-/****************************************************************************
- * Name: fetch_avrMessageSize
- *
- * Description:
- * To get the avegare message size for lwm2m from connectivity manager
- *
- * Returned Value:
- *
- *
- ****************************************************************************/
- void fetch_avrMessageSize(int *value);
#include "liblwm2m.h"
#include "lwm2mclient.h"
-#include "power_monitor_interface.h"
+
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define RES_O_SOFTWARE_VERSION 19
#define RES_O_BATTERY_STATUS 20
#define RES_O_MEMORY_TOTAL 21
-/* Added for Tinyara */
-#define RES_O_POWER_STATES 22
-#define RES_O_POWER_CURR_STATE 23
-#define RES_O_POWER_TIME_SPENT 24
-#define RES_O_POWER_EXPECTED_LIFETIME 25
-
typedef struct
int64_t time;
uint8_t battery_level;
char time_offset[PRV_OFFSET_MAXLEN];
- char power_states[POWER_STATES_LEN];
- char battery_lifetime[BATTERY_LIFETIME_LEN];
- char battery_levels[BATTERY_LEVEL_LEN];
} device_data_t;
}
case RES_O_BATTERY_LEVEL:
- fetch_battery_level(devDataP->battery_levels);
- lwm2m_data_encode_string(devDataP->battery_levels, dataP);
- printf("power level = %s\n", devDataP->battery_levels);
+ lwm2m_data_encode_int(devDataP->battery_level, dataP);
return COAP_205_CONTENT;
case RES_O_MEMORY_FREE:
case RES_M_BINDING_MODES:
lwm2m_data_encode_string(PRV_BINDING_MODE, dataP);
return COAP_205_CONTENT;
-
- case RES_O_POWER_STATES:
- fetch_power_states(devDataP->power_states);
- lwm2m_data_encode_string(devDataP->power_states, dataP);
- printf("power states = %s\n", devDataP->power_states);
- return COAP_205_CONTENT;
-
- case RES_O_POWER_CURR_STATE:
-
- return COAP_205_CONTENT;
-
- case RES_O_POWER_TIME_SPENT:
-
- return COAP_205_CONTENT;
-
- case RES_O_POWER_EXPECTED_LIFETIME:
- fetch_battery_lifetime(devDataP->battery_lifetime);
- lwm2m_data_encode_string(devDataP->battery_lifetime, dataP);
- printf("battery lifetime = %s\n", devDataP->battery_lifetime);
- return COAP_205_CONTENT;
default:
return COAP_404_NOT_FOUND;
RES_O_CURRENT_TIME,
RES_O_UTC_OFFSET,
RES_O_TIMEZONE,
- RES_M_BINDING_MODES,
- RES_O_POWER_STATES,
- RES_O_POWER_CURR_STATE,
- RES_O_POWER_TIME_SPENT,
- RES_O_POWER_EXPECTED_LIFETIME,
+ RES_M_BINDING_MODES
};
int nbRes = sizeof(resList)/sizeof(uint16_t);
return result;
}
-static void prv_reboot(void)
-{
- g_reboot = 1;
-#ifdef CONFIG_ARCH_CHIP_S5JT200
- *(int*)0x80090400 = 1;
-#endif
-}
+
static uint8_t prv_device_execute(uint16_t instanceId,
uint16_t resourceId,
uint8_t * buffer,
{
case RES_M_REBOOT:
fprintf(stdout, "\n\t REBOOT\r\n\n");
- prv_reboot();
+ g_reboot = 1;
return COAP_204_CHANGED;
case RES_O_FACTORY_RESET:
fprintf(stdout, "\n\t FACTORY RESET\r\n\n");
}
}
- mount_procfs();
return deviceObj;
}
* Resources:
* Name | ID | Oper.|Instances|Mand.| Type | Range | Units | Description |
* -------------+-----+------+---------+-----+---------+-------+-------+----------------------------------------------------------------------------------+
- * Latitude | 0 | R | Single | Yes | String | | Deg | The decimal notation of latitude e.g. - 45.5723 [Worlds Geodetic System 1984].|
- * Longitude | 1 | R | Single | Yes | String | | Deg | The decimal notation of longitude e.g. - 153.21760 [Worlds Geodetic System 1984].|
- * Altidude | 2 | R | Single | No | String | | m | The decimal notation of altidude in meters above sea level. |
- * Uncertainty | 3 | R | Single | No | String | | m | The accuracy of the position in meters. |
+ * 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"
#define RES_M_LATITUDE 0
#define RES_M_LONGITUDE 1
#define RES_O_ALTITUDE 2
-#define RES_O_UNCERTAINTY 3
+#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 VELOCITY_OCTETS 5 // for HORITZOL_VELOCITY_WITH_UNCERTAINTY
-#define DEG_DECIMAL_PLACES 6 // configuration: degree decimals implementation
+#define VELOCITY_OCTETS 5 // for HORIZONTAL_VELOCITY_WITH_UNCERTAINTY
typedef struct
{
- char latitude [5 + DEG_DECIMAL_PLACES]; //"359.12345" frag=5, 9+1=10! degrees +\0
- char longitude [5 + DEG_DECIMAL_PLACES];
- char altitude [5 + DEG_DECIMAL_PLACES];
- char uncertainty[5 + DEG_DECIMAL_PLACES];
- uint8_t velocity [VELOCITY_OCTETS]; //3GPP notation 1st step: HORITZOL_VELOCITY_WITH_UNCERTAINTY
+ 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;
/**
switch (dataP->id) // location resourceId
{
case RES_M_LATITUDE:
- lwm2m_data_encode_string(locDataP->latitude, dataP);
+ lwm2m_data_encode_float(locDataP->latitude, dataP);
break;
case RES_M_LONGITUDE:
- lwm2m_data_encode_string(locDataP->longitude, dataP);
+ lwm2m_data_encode_float(locDataP->longitude, dataP);
break;
case RES_O_ALTITUDE:
- lwm2m_data_encode_string(locDataP->altitude, dataP);
+ lwm2m_data_encode_float(locDataP->altitude, dataP);
break;
- case RES_O_UNCERTAINTY:
- lwm2m_data_encode_string(locDataP->uncertainty, dataP);
+ case RES_O_RADIUS:
+ lwm2m_data_encode_float(locDataP->radius, dataP);
break;
case RES_O_VELOCITY:
- lwm2m_data_encode_string(locDataP->velocity, dataP);
+ lwm2m_data_encode_string((const char*)locDataP->velocity, 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;
RES_M_LATITUDE,
RES_M_LONGITUDE,
RES_O_ALTITUDE,
- RES_O_UNCERTAINTY,
+ RES_O_RADIUS,
RES_O_VELOCITY,
- RES_M_TIMESTAMP
+ RES_M_TIMESTAMP,
+ RES_O_SPEED
}; // readable resources!
*numDataP = sizeof(readResIds)/sizeof(uint16_t);
fprintf(stdout, " /%u: Location object:\r\n", object->objID);
if (NULL != data)
{
- fprintf(stdout, " latitude: %s, longitude: %s, altitude: %s, uncertainty: %s, timestamp: %lu\r\n",
- data->latitude, data->longitude, data->altitude, data->uncertainty, data->timestamp);
+ 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);
}
#endif
}
//-------------------------------------------------------------------- JH --
location_data_t* pData = locationObj->userData;
-#if defined(ARDUINO)
- dtostrf (latitude, -8, 6, pData->latitude);
- dtostrf (longitude, -8, 6, pData->longitude);
- dtostrf (altitude, -8, 4, pData->altitude);
-#else
- snprintf(pData->latitude, 5+DEG_DECIMAL_PLACES, "%-8.6f", (double)latitude);
- snprintf(pData->longitude,5+DEG_DECIMAL_PLACES, "%-8.6f", (double)longitude);
- snprintf(pData->altitude, 5+DEG_DECIMAL_PLACES, "%-8.4f", (double)altitude);
-#endif
-
+ pData->latitude = latitude;
+ pData->longitude = longitude;
+ pData->altitude = altitude;
pData->timestamp = timestamp;
}
if (NULL != locationObj->userData)
{
location_data_t* data = (location_data_t*)locationObj->userData;
- strcpy (data->latitude, "27.986065"); // Mount Everest :)
- strcpy (data->longitude, "86.922623");
- strcpy (data->altitude, "8495.0000");
- strcpy (data->uncertainty, "0.01");
+ 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
{
+++ /dev/null
-/*******************************************************************************
- *
- * 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 v1.0
- * and Eclipse Distribution License v1.0 which accompany this distribution.
- *
- * The Eclipse Public License is available at
- * http://www.eclipse.org/legal/epl-v10.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
- *
- *******************************************************************************/
-
-#include "liblwm2m.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-
-// Resource Id's:
-#define RES_M_OBJ_ID 0
-#define RES_M_OBJINST_ID 1
-#define RES_O_STATE 2
-#define RES_O_CURRENT 3
-#define RES_O_TIME 4
-
-struct power_m_data_s
-{
- char state[10];
- int current;
- int time;
- int W;
-};
-
-typedef struct power_m_data_s power_m_data_t;
-
-struct power_monitor_oi_s
-{ //linked list:
- struct power_monitor_oi_s* next; // matches lwm2m_list_t::next
- uint16_t objInstId; // matches lwm2m_list_t::id
- // resources
- power_m_data_t *power_monitor_resource;
-};
-
-typedef struct power_monitor_oi_s power_monitor_oi_t;
-
-typedef enum
-{
- STATE_NORMAL,
- STATE_IDLE,
- STATE_STANDBY,
- STATE_SLEEP,
-} dm_lwm2m_power_state_e;
-
-
-static const char *power_state_str[] = {"NORMAL", "IDLE", "STANDBY", "SLEEP"};
-
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: fetch_state
- *
- * Description:
- * To get the state (idle, normal, sleep, standby) of a device
- *
- * Returned Value:
- *
- *
-****************************************************************************/
-static void fetch_objID(int *value)
-{
- (*value) = 8;
-}
-/****************************************************************************/
-static void fetch_objInstId(int *value)
-{
- (*value) = 0;
-}
-
-/*****************************************************************************/
-static void fetch_state(int *value)
-{
- (*value) = STATE_NORMAL;
-}
-
-/****************************************************************************/
-
-static void fetch_time (int *value)
-{
- (*value) = 1000;
-}
-
-/****************************************************************************/
-static void fetch_current (int *value)
-{
- (*value) = 1;
-}
-/****************************************************************************/
-static void fetch_write (int *value)
-{
-
- (*value) = 1;
-}
-/****************************************************************************/
-
-
-static uint8_t prv_set_value(lwm2m_data_t * dataP, power_m_data_t *powerDataP)
-{
- int value;
-
- switch (dataP->id)
- {
-
- case RES_O_STATE:
- fetch_state(&value);
- printf("state is %d\n", value); usleep(20000);
- printf("Device power state is %s\n", power_state_str[value]);
- strncpy(powerDataP->state, power_state_str[value], strlen(power_state_str[value]));
- lwm2m_data_encode_string(powerDataP->state, dataP);
- return COAP_205_CONTENT;
-
- case RES_O_CURRENT :
- fetch_current(&value);
- printf("Current consumption is %d\n", value);
- powerDataP->current = value;
- lwm2m_data_encode_int(powerDataP->current, dataP);
- return COAP_205_CONTENT;
-
- case RES_O_TIME :
- fetch_time(&value);
- printf("Time spent in the state is %d\n", value);
- powerDataP->time = value;
- lwm2m_data_encode_int(powerDataP->time, dataP);
- return COAP_205_CONTENT;
- }
-}
-
-
-
-static uint8_t prv_write_resources(uint16_t instanceId, int numData,
- lwm2m_data_t* tlvArray, lwm2m_object_t* objectP, bool doCreate)
-{
- int i;
- uint8_t result;
- int64_t value;
-
- power_monitor_oi_t* powerMonitorOiP = (power_monitor_oi_t *)
- lwm2m_list_find(objectP->instanceList, instanceId);
- if (NULL == powerMonitorOiP)
- return COAP_404_NOT_FOUND ;
-
- i = 0;
- do
- {
- switch (tlvArray[i].id)
- {
- case RES_O_STATE:
- if (doCreate==false)
- {
- result = COAP_405_METHOD_NOT_ALLOWED;
- }
- else
- {
- if (1 != lwm2m_data_decode_int(&tlvArray[i], &value))
- {
- result = COAP_400_BAD_REQUEST;
- }
- else
- {
- // TODO
- }
- }
- break;
-
- case RES_O_CURRENT:
- if (doCreate==false)
- {
- result = COAP_405_METHOD_NOT_ALLOWED;
- }
- else
- {
- if (1 != lwm2m_data_decode_int(&tlvArray[i], &value))
- {
- result = COAP_400_BAD_REQUEST;
- }
- else
- {
- // TODO
- }
- }
- break;
-
- case RES_O_TIME:
- if (doCreate==false)
- {
- result = COAP_405_METHOD_NOT_ALLOWED;
- }
- else
- {
- if (1 != lwm2m_data_decode_int(&tlvArray[i], &value))
- {
- result = COAP_400_BAD_REQUEST;
- }
- else
- {
- // TODO
- }
- }
- break;
- default:
- return COAP_404_NOT_FOUND ;
- }
- i++;
- } while (i < numData && result == COAP_204_CHANGED );
-
- return result;
-}
-
-static uint8_t prv_write(uint16_t instanceId, int numData,
- lwm2m_data_t* tlvArray, lwm2m_object_t* objectP)
-{
- return prv_write_resources(instanceId, numData, tlvArray, objectP, false);
-}
-
-static uint8_t prv_delete(uint16_t id, lwm2m_object_t * objectP)
-{
- power_monitor_oi_t* targetP;
-
- 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);
-
- return COAP_202_DELETED;
-}
-
-static uint8_t prv_read(uint16_t instanceId,
- int * numDataP,
- lwm2m_data_t ** dataArrayP,
- lwm2m_object_t * objectP)
-{
- uint8_t result;
- int i;
-
- power_monitor_oi_t* powerMoniOiP =
- (power_monitor_oi_t *)lwm2m_list_find(objectP->instanceList, instanceId);
- printf("instance Id is %d\n", instanceId);
- if (powerMoniOiP == NULL)
- {
- printf("No instance found\n");
- return COAP_404_NOT_FOUND ;
- }
-
-
- if (*numDataP == 0)
- {
- uint16_t resList[] = {
-
- RES_O_STATE,
- RES_O_CURRENT,
- RES_O_TIME
- };
- int nbRes = sizeof(resList) / sizeof(uint16_t);
- *dataArrayP = lwm2m_data_new(nbRes);
- if (*dataArrayP == NULL)
- return COAP_500_INTERNAL_SERVER_ERROR ;
- *numDataP = nbRes;
- for (i = 0; i < nbRes; i++)
- {
- (*dataArrayP)[i].id = resList[i];
- }
- }
- i = 0;
- do
- {
- result = prv_set_value((*dataArrayP) + i, powerMoniOiP->power_monitor_resource);
- i++;
- } while (i < *numDataP && result == COAP_205_CONTENT);
- return result;
-}
-
-static uint8_t prv_create(uint16_t objInstId, int numData,
- lwm2m_data_t * tlvArray, lwm2m_object_t * objectP)
-{
- power_monitor_oi_t * targetP;
- uint8_t result;
-
- targetP = (power_monitor_oi_t *)lwm2m_malloc(sizeof(power_monitor_oi_t));
- if (NULL == targetP) return COAP_500_INTERNAL_SERVER_ERROR;
- memset(targetP, 0, sizeof(power_monitor_oi_t));
-
- targetP->objInstId = objInstId;
- objectP->instanceList = LWM2M_LIST_ADD(objectP->instanceList, targetP);
-
- result = prv_write_resources(objInstId, numData, tlvArray, objectP, true);
-
- if (result != COAP_204_CHANGED)
- {
- prv_delete(objInstId, objectP);
- }
- else
- {
- result = COAP_201_CREATED;
- }
- return result;
-}
-
-lwm2m_object_t * get_power_monitor_object(void)
-{
- lwm2m_object_t * powerObj;
-
- powerObj = (lwm2m_object_t *) malloc(sizeof(lwm2m_object_t));
-
- if (powerObj != NULL)
- {
- memset(powerObj, 0x00, sizeof(lwm2m_object_t));
-
- powerObj->objID = LWM2M_POWER_MONITOR_OBJECT_ID;
-
- powerObj->readFunc = prv_read;
- powerObj->writeFunc = prv_write;
- powerObj->createFunc = prv_create;
- powerObj->deleteFunc = prv_delete;
- powerObj->executeFunc = NULL;
- }
-
- return powerObj;
-}
-
-
-bool power_monitor_obj_add_inst (lwm2m_object_t* powerMonitorObjP, uint16_t instId,
- int domain_code)
-{
- bool ret = false;
-
- if (NULL == powerMonitorObjP)
- {
- return ret;
- }
- else
- {
- // create an access control object instance
- power_monitor_oi_t* powerMonitorOiP;
- powerMonitorOiP = (power_monitor_oi_t *)lwm2m_malloc(sizeof(power_monitor_oi_t));
- if (NULL == powerMonitorOiP)
- {
- return ret;
- }
- else
- {
- memset(powerMonitorOiP, 0, sizeof(power_monitor_oi_t));
- // list: key
- powerMonitorOiP->objInstId = instId;
- // object instance data:
- powerMonitorOiP->power_monitor_resource = (power_m_data_t *)
- lwm2m_malloc(sizeof(power_m_data_t));
- powerMonitorOiP->power_monitor_resource->W = domain_code;
-
- powerMonitorObjP->instanceList =
- LWM2M_LIST_ADD(powerMonitorObjP->instanceList, powerMonitorOiP);
- ret = true;
- }
- }
- return ret;
-}
-#if 0
-bool power_monitor_oi_add_ac_val (lwm2m_object_t* powerMonitorObjP, uint16_t instId,
- uint16_t pmResId, uint16_t pmValue)
-{
- bool ret = false;
-
- power_monitor_oi_t* powerMonitorOiP = (power_monitor_oi_t *)
- lwm2m_list_find(powerMonitorObjP->instanceList, instId);
- if (NULL == powerMonitorOiP)
- return ret;
-
- return prv_add_ac_val (powerMonitorOiP, pmResId, pmValue);
-}
-#endif
-
-void power_monitor_free_object(lwm2m_object_t * objectP)
-{
- power_monitor_oi_t *powermOiT;
- power_monitor_oi_t *powermOiP = (power_monitor_oi_t*)objectP->instanceList;
- while (powermOiP != NULL)
- {
- // first free acl (multiple resource!):
- powermOiT = powermOiP;
- powermOiP = powermOiP->next;
- if (powermOiT->power_monitor_resource != NULL)
- lwm2m_free(powermOiT->power_monitor_resource);
-
- lwm2m_free(powermOiT);
- }
- lwm2m_free(objectP);
-}
-/****************************************************************************/
-
-
-
return COAP_205_CONTENT;
case LWM2M_SECURITY_PUBLIC_KEY_ID:
- lwm2m_data_encode_opaque(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(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(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:
return COAP_205_CONTENT;
case LWM2M_SECURITY_SMS_KEY_PARAM_ID:
- lwm2m_data_encode_opaque(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(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:
+++ /dev/null
-#include <tinyara/config.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <dirent.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <ctype.h>
-#include <stdint.h>
-#include "power_monitor_interface.h"
-#include "common_monitor_interface.h"
-
-
-uint8_t pm_iobuffer[PROC_BUFFER_LEN];
-
-void fetch_power_states(FAR char *powerstates)
-{
- int ret;
- uint8_t *filepath;
- ret = asprintf(&filepath, "%s/power/system/states", PROC_MOUNTPOINT);
- ret = readfile(filepath, pm_iobuffer, PROC_BUFFER_LEN);
- if (ret == OK)
- {
- strncpy(powerstates, pm_iobuffer, strlen(pm_iobuffer));
- printf("powerstates %s:%s:%d\n", powerstates, pm_iobuffer, strlen(pm_iobuffer));
- }
-}
-
-void fetch_battery_lifetime(FAR char *expectedlifetime)
-{
- int ret;
- uint8_t *filepath;
- ret = mount(NULL, PROC_MOUNTPOINT, "procfs", 0, NULL);
- printf("mount returns value %d\n", ret);
- ret = asprintf(&filepath, "%s/power/battery/runtime", PROC_MOUNTPOINT);
- ret = readfile(filepath, pm_iobuffer, PROC_BUFFER_LEN);
- if (ret == OK)
- {
- strncpy(expectedlifetime, pm_iobuffer, strlen(pm_iobuffer));
- printf("expectedlifetime %s:%s:%d\n", expectedlifetime, pm_iobuffer, strlen(pm_iobuffer));
- }
-}
-
-void fetch_battery_level(FAR char * batterylevel)
-{
- int ret;
- uint8_t *filepath;
- ret = asprintf(&filepath, "%s/power/battery/life", PROC_MOUNTPOINT);
- ret = readfile(filepath, pm_iobuffer, PROC_BUFFER_LEN);
- if (ret == OK)
- {
- strncpy(batterylevel, pm_iobuffer, strlen(pm_iobuffer));
- printf("batterylevel %s:%s:%d\n", batterylevel, pm_iobuffer, strlen(pm_iobuffer));
- }
-}
\ No newline at end of file
+++ /dev/null
-#ifndef _POWER_MONITOR_INTERFACE_H
-#define _POWER_MONITOR_INTERFACE_H
-enum power_state_e {
- POWER_STATE_HIGH = 0,
- POWER_STATE_MEDIUM,
- POWER_STATE_LOW
-};
-
-#define POWER_STATES_LEN 64
-#define BATTERY_LIFETIME_LEN 32
-#define BATTERY_LEVEL_LEN 32
-void fetch_power_states(FAR char *powerstates);
-void fetch_power_curr_state(char *currstate);
-void fetch_power_time_spent(char *timespent);
-void fetch_power_battery_state(char *batterystate);
-void fetch_battery_lifetime(FAR char *expectedlifetime);
-void fetch_battery_level(FAR char * batterylevel);
-#endif
\ No newline at end of file
include_directories (${WAKAAMA_SOURCES_DIR} ${SHARED_INCLUDE_DIRS})
SET(SOURCES
- lightclient.c
- object_security.c
- object_server.c
- object_device.c
- test_object.c
+ ${CMAKE_CURRENT_LIST_DIR}/lightclient.c
+ ${CMAKE_CURRENT_LIST_DIR}/object_security.c
+ ${CMAKE_CURRENT_LIST_DIR}/object_server.c
+ ${CMAKE_CURRENT_LIST_DIR}/object_device.c
+ ${CMAKE_CURRENT_LIST_DIR}/test_object.c
)
add_executable(${PROJECT_NAME} ${SOURCES} ${WAKAAMA_SOURCES} ${SHARED_SOURCES})
case STATE_REG_UPDATE_PENDING:
fprintf(stderr, "REGISTRATION UPDATE PENDING\r\n");
break;
+ case STATE_REG_UPDATE_NEEDED:
+ fprintf(stderr, "REGISTRATION UPDATE REQUIRED\r\n");
+ break;
case STATE_DEREG_PENDING:
fprintf(stderr, "DEREGISTRATION PENDING\r\n");
break;
#define OBJ_COUNT 4
-int lightclient_main(int argc, char *argv[])
+int main(int argc, char *argv[])
{
- app_main_dhcp();
-
client_data_t data;
lwm2m_context_t * lwm2mH = NULL;
lwm2m_object_t * objArray[OBJ_COUNT];
memset(&data, 0, sizeof(client_data_t));
- data.addressFamily = AF_INET;
+ data.addressFamily = AF_INET6;
opt = 1;
while (opt < argc)
include_directories (${WAKAAMA_SOURCES_DIR} ${SHARED_INCLUDE_DIRS})
SET(SOURCES
- lwm2mserver.c
+ ${CMAKE_CURRENT_LIST_DIR}/lwm2mserver.c
)
add_executable(${PROJECT_NAME} ${SOURCES} ${WAKAAMA_SOURCES} ${SHARED_SOURCES})
if (length == 0) fprintf(stream, "\n");
+ if (buffer == NULL) return;
+
i = 0;
while (i < length)
{
tmp = buffer[length + dataIndex + dataLen];
buffer[length + dataIndex + dataLen] = 0;
- if (0 < sscanf(buffer + length + dataIndex, "%"PRId64, &intValue))
+ if (0 < sscanf((const char *)buffer + length + dataIndex, "%"PRId64, &intValue))
{
print_indent(stream, indent+2);
fprintf(stream, "data as Integer: %" PRId64 "\r\n", intValue);
}
- if (0 < sscanf(buffer + length + dataIndex, "%g", &floatValue))
+ if (0 < sscanf((const char*)buffer + length + dataIndex, "%lg", &floatValue))
{
print_indent(stream, indent+2);
fprintf(stream, "data as Float: %.16g\r\n", floatValue);
{
int i;
- if (data == NULL) return;
-
print_indent(stream, indent);
fprintf(stream, "%d bytes received of type ", dataLength);
+
switch (format)
{
case LWM2M_CONTENT_TEXT:
case LWM2M_TYPE_STRING:
fprintf(stream, "LWM2M_TYPE_STRING\r\n");
print_indent(stream, indent + 1);
- fprintf(stream, "\"%.*s\"\r\n", dataP[i].value.asBuffer.length, dataP[i].value.asBuffer.buffer);
+ fprintf(stream, "\"%.*s\"\r\n", (int)dataP[i].value.asBuffer.length, dataP[i].value.asBuffer.buffer);
break;
case LWM2M_TYPE_OPAQUE:
fprintf(stream, "LWM2M_TYPE_OPAQUE\r\n");
case LWM2M_TYPE_FLOAT:
fprintf(stream, "LWM2M_TYPE_FLOAT: ");
print_indent(stream, indent + 1);
- fprintf(stream, "%f", dataP[i].value.asInteger);
+ fprintf(stream, "%" PRId64, dataP[i].value.asInteger);
fprintf(stream, "\r\n");
break;
case LWM2M_TYPE_BOOLEAN:
memset(&hints, 0, sizeof hints);
hints.ai_family = addressFamily;
hints.ai_socktype = SOCK_DGRAM;
-// hints.ai_flags = AI_PASSIVE;
+ hints.ai_flags = AI_PASSIVE;
if (0 != getaddrinfo(NULL, portStr, &hints, &res))
{
if (s >= 0)
{
sa = p->ai_addr;
-#if CONFIG_NET_LWIP
- sa->sa_len = p->ai_addrlen;
-#endif
sl = p->ai_addrlen;
if (-1 == connect(s, p->ai_addr, p->ai_addrlen))
{
}
if (s >= 0)
{
- connP = connection_new_incoming(connList, s, sa, sl);
-// close(s);
+ connP = connection_new_incoming(connList, sock, sa, sl);
+ close(s);
}
if (NULL != servinfo) {
#ifdef CONFIG_NET_LWIP
dataP->type == LWM2M_TYPE_OPAQUE)
{
char * buff;
-
+
buff = (char*)lwm2m_malloc(dataP->value.asBuffer.length);
if (buff != 0)
{
lwm2m_data_free(size, dataP);
return buff;
- }else{
+ } else {
return NULL;
}
}
lwm2m_data_free(size, dataP);
return buff;
- }else{
+ } else {
return NULL;
}
}
struct sockaddr_in *saddr = (struct sockaddr_in *)&connP->addr;
inet_ntop(saddr->sin_family, &saddr->sin_addr, s, INET6_ADDRSTRLEN);
port = saddr->sin_port;
-}
+ }
else if (AF_INET6 == connP->addr.sin6_family)
{
struct sockaddr_in6 *saddr = (struct sockaddr_in6 *)&connP->addr;
if (nbSent == -1) return -1;
offset += nbSent;
}
+ connP->lastSend = lwm2m_gettime();
return 0;
}
/* This function is the "key store" for tinyDTLS. It is called to
* retrieve a key for the given identity within this particular
* session. */
-static int
-get_psk_info(struct dtls_context_t *ctx,
+static int get_psk_info(struct dtls_context_t *ctx,
const session_t *session,
dtls_credentials_type_t type,
const unsigned char *id, size_t id_len,
return dtls_alert_fatal_create(DTLS_ALERT_INTERNAL_ERROR);
}
-static int
-send_to_peer(struct dtls_context_t *ctx,
+static int send_to_peer(struct dtls_context_t *ctx,
session_t *session, uint8 *data, size_t len) {
// find connection
if (cnx != NULL)
{
// send data to peer
+
+ // TODO: nat expiration?
int err = send_data(cnx,data,len);
if (COAP_NO_ERROR != err)
{
return -1;
}
-static int
-read_from_peer(struct dtls_context_t *ctx,
+static int read_from_peer(struct dtls_context_t *ctx,
session_t *session, uint8 *data, size_t len) {
// find connection
// compare V4 with V4
return ((struct sockaddr_in *)x)->sin_addr.s_addr == ((struct sockaddr_in *)y)->sin_addr.s_addr;
// is V6 mapped V4?
- }
-#ifdef IPv6
- else if (IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *)y)->sin6_addr)) {
+ } else if (IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *)y)->sin6_addr)) {
struct in6_addr* addr6 = &((struct sockaddr_in6 *)y)->sin6_addr;
uint32_t y6to4 = addr6->s6_addr[15] << 24 | addr6->s6_addr[14] << 16 | addr6->s6_addr[13] << 8 | addr6->s6_addr[12];
return y6to4 == ((struct sockaddr_in *)x)->sin_addr.s_addr;
- }
-#endif
- else {
+ } else {
return 0;
}
-
} else if (x->sa_family == AF_INET6 && y->sa_family == AF_INET6) {
// IPV6 with IPV6 compare
return memcmp(((struct sockaddr_in6 *)x)->sin6_addr.s6_addr, ((struct sockaddr_in6 *)y)->sin6_addr.s6_addr, 16) == 0;
memset(&hints, 0, sizeof hints);
hints.ai_family = ai_family;
hints.ai_socktype = SOCK_DGRAM;
-// hints.ai_flags = AI_PASSIVE;
+ hints.ai_flags = AI_PASSIVE;
if (0 != getaddrinfo(NULL, portStr, &hints, &res))
{
connP->dtlsSession = (session_t *)malloc(sizeof(session_t));
connP->dtlsSession->addr.sin6 = connP->addr;
connP->dtlsSession->size = connP->addrLen;
+ connP->lastSend = lwm2m_gettime();
}
return connP;
}
if (s >= 0)
{
-
- connP = connection_new_incoming(connList, s, sa, sl);
- // close(s);
+ connP = connection_new_incoming(connList, sock, sa, sl);
+ close(s);
// do we need to start tinydtls?
if (connP != NULL)
}
}
- if (NULL != servinfo) {
- free(servinfo);
-
-
- }
+ if (NULL != servinfo) free(servinfo);
return connP;
}
}
int connection_send(dtls_connection_t *connP, uint8_t * buffer, size_t length){
-
if (connP->dtlsSession == NULL) {
// no security
-
-
if ( 0 != send_data(connP, buffer, length)) {
return -1 ;
}
} else {
+ if (DTLS_NAT_TIMEOUT > 0 && (lwm2m_gettime() - connP->lastSend) > DTLS_NAT_TIMEOUT)
+ {
+ // we need to rehandhake because our source IP/port probably changed for the server
+ if ( connection_rehandshake(connP, false) != 0 )
+ {
+ printf("can't send due to rehandshake error\n");
+ return -1;
+ }
+ }
if (-1 == dtls_write(connP->dtlsContext, connP->dtlsSession, buffer, length)) {
return -1;
}
}
+
return 0;
}
}
}
+int connection_rehandshake(dtls_connection_t *connP, bool sendCloseNotify) {
+
+ // if not a dtls connection we do nothing
+ if (connP->dtlsSession == NULL) {
+ return 0;
+ }
+
+ // reset current session
+ dtls_peer_t * peer = dtls_get_peer(connP->dtlsContext, connP->dtlsSession);
+ if (peer != NULL)
+ {
+ if (!sendCloseNotify)
+ {
+ peer->state = DTLS_STATE_CLOSED;
+ }
+ dtls_reset_peer(connP->dtlsContext, peer);
+ }
+
+ // start a fresh handshake
+ int result = dtls_connect(connP->dtlsContext, connP->dtlsSession);
+ if (result !=0) {
+ printf("error dtls reconnection %d\n",result);
+ }
+ return result;
+}
+
uint8_t lwm2m_buffer_send(void * sessionH,
uint8_t * buffer,
size_t length,
#define LWM2M_BSSERVER_PORT_STR "5685"
#define LWM2M_BSSERVER_PORT 5685
+// after 40sec of inactivity we rehandshake
+#define DTLS_NAT_TIMEOUT 40
+
typedef struct _dtls_connection_t
{
struct _dtls_connection_t * next;
int securityInstId;
lwm2m_context_t * lwm2mH;
dtls_context_t * dtlsContext;
+ time_t lastSend; // last time a data was sent to the server (used for NAT timeouts)
} dtls_connection_t;
int create_socket(const char * portStr, int ai_family);
int connection_send(dtls_connection_t *connP, uint8_t * buffer, size_t length);
int connection_handle_packet(dtls_connection_t *connP, uint8_t * buffer, size_t length);
+// rehandshake a connection, useful when your NAT timed out and your client has a new IP/PORT
+int connection_rehandshake(dtls_connection_t *connP, bool sendCloseNotify);
+
#endif
--- /dev/null
+/*******************************************************************************
+ *
+ * Copyright (c) 2015 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 v1.0
+ * and Eclipse Distribution License v1.0 which accompany this distribution.
+ *
+ * The Eclipse Public License is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * The Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ * Julien Vermillard - Please refer to git log
+ *
+ *******************************************************************************/
+
+#include "tests.h"
+#include "CUnit/Basic.h"
+#include "internals.h"
+#include "liblwm2m.h"
+
+
+static void handle_12345(lwm2m_block1_data_t ** blk1,
+ uint16_t mid) {
+ uint8_t *buffer = "12345";
+ size_t bsize;
+ uint8_t *resultBuffer = NULL;
+
+ coap_status_t st = coap_block1_handler(blk1, mid, buffer, 5, 5, 0, true, &resultBuffer, &bsize);
+ CU_ASSERT_EQUAL(st, COAP_231_CONTINUE);
+ CU_ASSERT_PTR_NULL(resultBuffer);
+}
+
+static void handle_67(lwm2m_block1_data_t ** blk1,
+ uint16_t mid) {
+ uint8_t *buffer = "67";
+ size_t bsize;
+ uint8_t *resultBuffer = NULL;
+
+ coap_status_t st = coap_block1_handler(blk1, mid, buffer, 2, 5, 1, false, &resultBuffer, &bsize);
+ CU_ASSERT_EQUAL(st, NO_ERROR);
+ CU_ASSERT_PTR_NOT_NULL(*resultBuffer);
+ CU_ASSERT_EQUAL(bsize, 7);
+ CU_ASSERT_NSTRING_EQUAL(resultBuffer, "1234567", 7);
+}
+
+
+static void test_block1_nominal(void)
+{
+ lwm2m_block1_data_t * blk1 = NULL;
+
+ handle_12345(&blk1, 123);
+ handle_67(&blk1, 346);
+
+ free_block1_buffer(blk1);
+}
+
+static void test_block1_retransmit(void)
+{
+ lwm2m_block1_data_t * blk1 = NULL;
+
+ handle_12345(&blk1, 1);
+ handle_12345(&blk1, 1);
+ handle_67(&blk1, 3);
+ handle_67(&blk1, 3);
+ handle_67(&blk1, 3);
+
+ free_block1_buffer(blk1);
+}
+
+static struct TestTable table[] = {
+ { "test of test_block1_nominal()", test_block1_nominal },
+ { "test of test_block1_retransmit()", test_block1_retransmit },
+ { NULL, NULL },
+};
+
+CU_ErrorCode create_block1_suit() {
+ CU_pSuite pSuite = NULL;
+ pSuite = CU_add_suite("Suite_block1", NULL, NULL);
+
+ if (NULL == pSuite) {
+ return CU_get_error();
+ }
+ return add_tests(pSuite, table);
+}
CU_ErrorCode create_object_read_suit();
CU_ErrorCode create_convert_numbers_suit();
CU_ErrorCode create_tlv_json_suit();
+CU_ErrorCode create_block1_suit();
#endif /* TESTS_H_ */
}
length = lwm2m_data_serialize((uriStr != NULL) ? &uri : NULL, size, tlvP, &format, &buffer);
- if (length <= 0)
+ if (length < 0)
{
printf("Serialize lwm2m_data_t %s to %s failed.\n", id, format==LWM2M_CONTENT_JSON?"JSON":"TLV");
//dump_data_t(stdout, size, tlvP, 0);
}
else
{
- //printf("\n\nSerialize lwm2m_data_t %s:\n", id);
- //output_buffer(stdout, buffer, length, 0);
+ printf("\n\nSerialize lwm2m_data_t %s:\n", id);
+ output_buffer(stdout, buffer, length, 0);
lwm2m_free(buffer);
}
}
// Serialize to the same format and compare to the input buffer
test_data_and_compare(uriStr, format, tlvP, size, id, (uint8_t*)expectBuf, expectLen);
- // Serialize to the other format respectivly.
+ // Serialize to the other format respectively.
if (format == LWM2M_CONTENT_TLV)
test_data(uriStr, LWM2M_CONTENT_JSON, tlvP, size, id);
else if (format == LWM2M_CONTENT_JSON)
}";
// We do a string comparison. Because parsing+serialization changes double value
- // precision, we expect a slighty different output than input.
+ // precision, we expect a slightly different output than input.
const char * expect = "{\"e\":[ \
{\"n\":\"0\",\"v\":1234}, \
{\"n\":\"1\",\"v\":56.78900146484375}, \
lwm2m_data_encode_bool(true, data1 + 15);
lwm2m_data_encode_bool(false, data1 + 16);
- test_data(NULL, LWM2M_CONTENT_TLV, data1, sizeof(data1)/sizeof(lwm2m_data_t), "1");
- test_data(NULL, LWM2M_CONTENT_JSON, data1, sizeof(data1)/sizeof(lwm2m_data_t), "1");
+ test_data(NULL, LWM2M_CONTENT_TLV, data1, 17, "1");
+ test_data(NULL, LWM2M_CONTENT_JSON, data1, 17, "1");
}
static struct TestTable table[] = {
if (CUE_SUCCESS != create_tlv_json_suit()) {
goto exit;
}
+ if (CUE_SUCCESS != create_block1_suit()) {
+ goto exit;
+ }
CU_basic_set_mode(CU_BRM_VERBOSE);
CU_basic_run_tests();
{
FAR char *bufptr;
size_t remaining;
- ssize_t nread;
ssize_t ntotal;
int ret;
wakaama_sparam.sched_priority = SCHED_PRIORITY_DEFAULT;
(void)pthread_attr_setschedparam(&wakaama_attr, &wakaama_sparam);
(void)pthread_attr_setstacksize(&wakaama_attr, 4096);
- ret = pthread_create(&wakaama_thread, &wakaama_attr, (pthread_startroutine_t)client_main, NULL);
+ ret = pthread_create(&wakaama_thread, &wakaama_attr, (pthread_startroutine_t)lwm2m_client_run, NULL);
pthread_detach(wakaama_thread);
/* Function return value */
if (ret != 0) {