Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add SenML JSON support #428

Merged
merged 2 commits into from
Feb 21, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ Several compilation switches are used:
- 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_SUPPORT_SENML_JSON to enable SenML JSON payload support (implicit for LWM2M 1.1 or greater when defining LWM2M_SERVER_MODE or LWM2M_BOOTSTRAP_SERVER_MODE)
- LWM2M_OLD_CONTENT_FORMAT_SUPPORT to support the deprecated content format values for TLV and JSON.
- LWM2M_VERSION to specify which version of the LWM2M spec to support.
Clients will support only that version. Servers will support that version and below.
Expand Down
20 changes: 16 additions & 4 deletions core/data.c
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ static int prv_textSerialize(lwm2m_data_t * dataP,
}

static int prv_setBuffer(lwm2m_data_t * dataP,
uint8_t * buffer,
const uint8_t * buffer,
size_t bufferLen)
{
dataP->value.asBuffer.buffer = (uint8_t *)lwm2m_malloc(bufferLen);
Expand Down Expand Up @@ -242,7 +242,7 @@ void lwm2m_data_encode_string(const char * string,
}
}

void lwm2m_data_encode_opaque(uint8_t * buffer,
void lwm2m_data_encode_opaque(const uint8_t * buffer,
size_t length,
lwm2m_data_t * dataP)
{
Expand Down Expand Up @@ -642,7 +642,7 @@ void lwm2m_data_encode_instances(lwm2m_data_t * subDataP,
}

int lwm2m_data_parse(lwm2m_uri_t * uriP,
uint8_t * buffer,
const uint8_t * buffer,
size_t bufferLen,
lwm2m_media_type_t format,
lwm2m_data_t ** dataP)
Expand Down Expand Up @@ -703,6 +703,11 @@ int lwm2m_data_parse(lwm2m_uri_t * uriP,
return json_parse(uriP, buffer, bufferLen, dataP);
#endif

#ifdef LWM2M_SUPPORT_SENML_JSON
case LWM2M_CONTENT_SENML_JSON:
return senml_json_parse(uriP, buffer, bufferLen, dataP);
#endif

default:
return 0;
}
Expand All @@ -727,7 +732,9 @@ int lwm2m_data_serialize(lwm2m_uri_t * uriP,
|| dataP->type == LWM2M_TYPE_OBJECT_INSTANCE
|| dataP->type == LWM2M_TYPE_MULTIPLE_RESOURCE)
{
#ifdef LWM2M_SUPPORT_JSON
#ifdef LWM2M_SUPPORT_SENML_JSON
*formatP = LWM2M_CONTENT_SENML_JSON;
#elif defined(LWM2M_SUPPORT_JSON)
*formatP = LWM2M_CONTENT_JSON;
#else
*formatP = LWM2M_CONTENT_TLV;
Expand Down Expand Up @@ -794,6 +801,11 @@ int lwm2m_data_serialize(lwm2m_uri_t * uriP,
return json_serialize(uriP, size, dataP, bufferP);
#endif

#ifdef LWM2M_SUPPORT_SENML_JSON
case LWM2M_CONTENT_SENML_JSON:
return senml_json_serialize(uriP, size, dataP, bufferP);
#endif

default:
return -1;
}
Expand Down
93 changes: 67 additions & 26 deletions core/internals.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,13 +106,14 @@
((S) == STATE_BS_FAILING ? "STATE_BS_FAILING" : \
((S) == STATE_BS_FAILED ? "STATE_BS_FAILED" : \
"Unknown"))))))))))))))))
#define STR_MEDIA_TYPE(M) \
((M) == LWM2M_CONTENT_TEXT ? "LWM2M_CONTENT_TEXT" : \
((M) == LWM2M_CONTENT_LINK ? "LWM2M_CONTENT_LINK" : \
((M) == LWM2M_CONTENT_OPAQUE ? "LWM2M_CONTENT_OPAQUE" : \
((M) == LWM2M_CONTENT_TLV ? "LWM2M_CONTENT_TLV" : \
((M) == LWM2M_CONTENT_JSON ? "LWM2M_CONTENT_JSON" : \
"Unknown")))))
#define STR_MEDIA_TYPE(M) \
((M) == LWM2M_CONTENT_TEXT ? "LWM2M_CONTENT_TEXT" : \
((M) == LWM2M_CONTENT_LINK ? "LWM2M_CONTENT_LINK" : \
((M) == LWM2M_CONTENT_OPAQUE ? "LWM2M_CONTENT_OPAQUE" : \
((M) == LWM2M_CONTENT_TLV ? "LWM2M_CONTENT_TLV" : \
((M) == LWM2M_CONTENT_JSON ? "LWM2M_CONTENT_JSON" : \
((M) == LWM2M_CONTENT_SENML_JSON ? "LWM2M_CONTENT_SENML_JSON" : \
"Unknown"))))))
#define STR_STATE(S) \
((S) == STATE_INITIAL ? "STATE_INITIAL" : \
((S) == STATE_BOOTSTRAP_REQUIRED ? "STATE_BOOTSTRAP_REQUIRED" : \
Expand All @@ -129,7 +130,10 @@

#define LWM2M_DEFAULT_LIFETIME 86400

#ifdef LWM2M_SUPPORT_JSON
#ifdef LWM2M_SUPPORT_SENML_JSON
#define REG_LWM2M_RESOURCE_TYPE ">;rt=\"oma.lwm2m\";ct=110,"
#define REG_LWM2M_RESOURCE_TYPE_LEN 23
#elif defined(LWM2M_SUPPORT_JSON)
#define REG_LWM2M_RESOURCE_TYPE ">;rt=\"oma.lwm2m\";ct=11543,"
#define REG_LWM2M_RESOURCE_TYPE_LEN 25
#else
Expand Down Expand Up @@ -178,19 +182,23 @@
#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_DELIMITER ','
#define REG_ATTR_SEPARATOR ';'
#define REG_ATTR_EQUALS '='
#define REG_ATTR_TYPE_KEY "rt"
#define REG_ATTR_TYPE_KEY_LEN 2
#define REG_ATTR_TYPE_VALUE "\"oma.lwm2m\""
#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 "11543" // Temporary value
#define REG_ATTR_CONTENT_JSON_LEN 5
#define REG_URI_START '<'
#define REG_URI_END '>'
#define REG_DELIMITER ','
#define REG_ATTR_SEPARATOR ';'
#define REG_ATTR_EQUALS '='
#define REG_ATTR_TYPE_KEY "rt"
#define REG_ATTR_TYPE_KEY_LEN 2
#define REG_ATTR_TYPE_VALUE "\"oma.lwm2m\""
#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 "11543"
#define REG_ATTR_CONTENT_JSON_LEN 5
#define REG_ATTR_CONTENT_JSON_OLD "1543"
#define REG_ATTR_CONTENT_JSON_OLD_LEN 4
#define REG_ATTR_CONTENT_SENML_JSON "110"
#define REG_ATTR_CONTENT_SENML_JSON_LEN 3

#define ATTR_SERVER_ID_STR "ep="
#define ATTR_SERVER_ID_LEN 3
Expand Down Expand Up @@ -327,15 +335,38 @@ void bootstrap_start(lwm2m_context_t * contextP);
lwm2m_status_t bootstrap_getStatus(lwm2m_context_t * contextP);

// defined in tlv.c
int tlv_parse(uint8_t * buffer, size_t bufferLen, lwm2m_data_t ** dataP);
int tlv_parse(const uint8_t * buffer, size_t bufferLen, lwm2m_data_t ** dataP);
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);
int json_parse(lwm2m_uri_t * uriP, const uint8_t * buffer, size_t bufferLen, lwm2m_data_t ** dataP);
int json_serialize(lwm2m_uri_t * uriP, int size, lwm2m_data_t * tlvP, uint8_t ** bufferP);
#endif

// defined in senml_json.c
#ifdef LWM2M_SUPPORT_SENML_JSON
int senml_json_parse(const lwm2m_uri_t * uriP, const uint8_t * buffer, size_t bufferLen, lwm2m_data_t ** dataP);
int senml_json_serialize(const lwm2m_uri_t * uriP, int size, const lwm2m_data_t * tlvP, uint8_t ** bufferP);
#endif

// defined in json_common.c
#if defined(LWM2M_SUPPORT_JSON) || defined(LWM2M_SUPPORT_SENML_JSON)
size_t json_skipSpace(const uint8_t * buffer,size_t bufferLen);
int json_split(const uint8_t * buffer, size_t bufferLen, size_t * tokenStartP, size_t * tokenLenP, size_t * valueStartP, size_t * valueLenP);
int json_itemLength(const uint8_t * buffer, size_t bufferLen);
int json_countItems(const uint8_t * buffer, size_t bufferLen);
int json_convertNumeric(const uint8_t *value, size_t valueLen, lwm2m_data_t *targetP);
int json_convertTime(const uint8_t *valueStart, size_t valueLen, time_t *t);
size_t json_unescapeString(uint8_t *dst, const uint8_t *src, size_t len);
size_t json_escapeString(uint8_t *dst, size_t dstLen, const uint8_t *src, size_t srcLen);
lwm2m_data_t * json_extendData(lwm2m_data_t * parentP);
int json_dataStrip(int size, lwm2m_data_t * dataP, lwm2m_data_t ** resultP);
lwm2m_data_t * json_findDataItem(lwm2m_data_t * listP, size_t count, uint16_t id);
uri_depth_t json_decreaseLevel(uri_depth_t level);
int json_findAndCheckData(const lwm2m_uri_t * uriP, uri_depth_t level, size_t size, const lwm2m_data_t * tlvP, lwm2m_data_t ** targetP);
#endif

// defined in discover.c
int discover_serialize(lwm2m_context_t * contextP, lwm2m_uri_t * uriP, lwm2m_server_t * serverP, int size, lwm2m_data_t * dataP, uint8_t ** bufferP);

Expand All @@ -353,12 +384,22 @@ int utils_stringCopy(char * buffer, size_t length, const char * str);
size_t utils_intToText(int64_t data, uint8_t * string, size_t length);
size_t utils_uintToText(uint64_t data, uint8_t * string, size_t length);
size_t utils_floatToText(double data, uint8_t * string, size_t length);
int utils_textToInt(uint8_t * buffer, int length, int64_t * dataP);
size_t utils_objLinkToText(uint16_t objectId,
uint16_t objectInstanceId,
uint8_t * string,
size_t length);
int utils_textToInt(const uint8_t * buffer, int length, int64_t * dataP);
int utils_textToUInt(const uint8_t * buffer, int length, uint64_t * dataP);
int utils_textToFloat(uint8_t * buffer, int length, double * dataP);
int utils_textToFloat(const uint8_t * buffer, int length, double * dataP);
int utils_textToObjLink(const uint8_t * buffer,
int length,
uint16_t * objectId,
uint16_t * objectInstanceId);
void utils_copyValue(void * dst, const void * src, size_t len);
size_t utils_base64GetSize(size_t dataLen);
size_t utils_base64Encode(uint8_t * dataP, size_t dataLen, uint8_t * bufferP, size_t bufferLen);
size_t utils_base64Encode(const uint8_t * dataP, size_t dataLen, uint8_t * bufferP, size_t bufferLen);
size_t utils_base64GetDecodedSize(const char * dataP, size_t dataLen);
size_t utils_base64Decode(const char * dataP, size_t dataLen, uint8_t * bufferP, size_t bufferLen);
#ifdef LWM2M_CLIENT_MODE
lwm2m_server_t * utils_findServer(lwm2m_context_t * contextP, void * fromSessionH);
lwm2m_server_t * utils_findBootstrapServer(lwm2m_context_t * contextP, void * fromSessionH);
Expand Down