The Cayenne MQTT mbed Library provides functions to easily connect to the Cayenne IoT project builder.
Fork of Cayenne-MQTT-mbed by
Diff: src/CayenneUtils/CayenneUtils.c
- Branch:
- feature/multivalue
- Revision:
- 22:0dbabcc6e7b2
- Parent:
- 16:085bcf2e9a18
diff -r e46b1f93c011 -r 0dbabcc6e7b2 src/CayenneUtils/CayenneUtils.c --- a/src/CayenneUtils/CayenneUtils.c Tue Nov 08 18:48:37 2016 -0700 +++ b/src/CayenneUtils/CayenneUtils.c Wed Jan 25 10:34:16 2017 -0700 @@ -162,7 +162,7 @@ * @param[in] topicNameLen CayenneTopic name length * return true if topic matches, false otherwise */ -int topicMatches(char* filter, char* topicName, unsigned int topicNameLen) +int topicMatches(char* filter, char* topicName, size_t topicNameLen) { char* curf = filter; char* curn = topicName; @@ -190,116 +190,37 @@ } /** -* Get the count of values in a message. -* @param[out] count Returned number of values found in message -* @param[in] payload Payload string, must be null terminated -* @param[in] token Character token for splitting "unit=value" payloads, 0 to just parse first comma delimited value -* @return CAYENNE_SUCCESS if value count succeeded, error code otherwise -*/ -int getValueCount(size_t* count, char* payload, char token) { - char* index = payload; - size_t unitCount = 0; - size_t valueCount = 0; - int countingValues = 0; - - if (token == 0) { - //Currently there can only be one value in payload if this isn't a "unit=value" payload. - *count = 1; - return CAYENNE_SUCCESS; - } - - *count = 0; - while (*index && index != '\0') { - if ((*index == ',') || (*index == token)) { - if (*index == ',') { - if (countingValues) { - valueCount++; - } - else { - unitCount++; - } - } - else if (*index == token) { - countingValues = 1; - valueCount++; - } - } - index++; - } - - if (countingValues) { - if ((valueCount != unitCount) && !(unitCount == 0 && valueCount == 1)) { - return CAYENNE_FAILURE; - } - } - else { - valueCount = 1; - } - *count = valueCount; - return CAYENNE_SUCCESS; -} - -/** * Parse a null terminated payload string in place. This may modify the payload string. -* @param[out] values Returned payload data unit & value array -* @param[in,out] valuesSize Size of values array, returns the count of values in the array * @param[out] type Returned type, NULL if there is none +* @param[out] unit Returned unit, NULL if there is none +* @param[out] value Returned value, NULL if there is none * @param[in] payload Payload string, must be null terminated * @param[in] token Character token for splitting "unit=value" payloads, 0 to just parse first comma delimited value * @return CAYENNE_SUCCESS if value and id were parsed, error code otherwise */ -int parsePayload(CayenneValuePair* values, size_t* valuesSize, const char** type, char* payload, char token) { +int parsePayload(const char** type, const char** unit, const char** value, char* payload, char token) { char* index = payload; - size_t count = 0; - int parsingValues = 0; - size_t valueIndex = 0; -#ifdef PARSE_INFO_PAYLOADS - int result = getValueCount(&count, payload, token); - if (result != CAYENNE_SUCCESS) { - *valuesSize = 0; - return result; - } -#else - count = 1; -#endif - - if(token == 0) - parsingValues = 1; //Don't need to parse units if there is no unit/value separator - - values[0].value = NULL; - values[0].unit = NULL; *type = NULL; + *unit = NULL; + *value = NULL; while (*index && index != '\0') { if ((*index == ',') || (*index == token)) { if (*index == ',') { *type = payload; - if (valueIndex < *valuesSize) { - if (parsingValues) { - values[valueIndex].value = index + 1; - } - else { - values[valueIndex].unit = index + 1; - } - } + *unit = index + 1; *index = '\0'; - valueIndex++; if (token == 0) break; } - else if (*index == token && !parsingValues) { - parsingValues = 1; - valueIndex = 0; + else if (*index == token) { *type = payload; - values[valueIndex].value = index + 1; + *value = index + 1; *index = '\0'; - valueIndex++; - if (count == valueIndex) - break; + break; } } index++; }; - *valuesSize = count; return CAYENNE_SUCCESS; } @@ -326,23 +247,20 @@ * @param[out] payload Returned payload * @param[in,out] length Payload buffer length * @param[in] type Optional type to use for type,unit=value payload, can be NULL -* @param[in] values Unit/value array -* @param[in] valueCount Number of values +* @param[in] unit Payload unit +* @param[in] value Payload value * @return CAYENNE_SUCCESS if topic string was created, error code otherwise */ -int CayenneBuildDataPayload(char* payload, size_t* length, const char* type, const CayenneValuePair* values, size_t valueCount) { - int i; +int CayenneBuildDataPayload(char* payload, size_t* length, const char* type, const char* unit, const char* value) { size_t payloadLength = 0; - for (i = 0; i < valueCount; ++i) { - if (values[i].unit) { - payloadLength += strlen(values[i].unit) + 1; - } - else if (type) { - // If type exists but unit does not, use UNIT_UNDEFINED for the unit. - payloadLength += strlen(UNIT_UNDEFINED) + 1; - } - payloadLength += values[i].value ? strlen(values[i].value) + 1 : 0; + if (unit) { + payloadLength += strlen(unit) + 1; } + else if (type) { + // If type exists but unit does not, use UNIT_UNDEFINED for the unit. + payloadLength += strlen(UNIT_UNDEFINED) + 1; + } + payloadLength += value ? strlen(value) + 1 : 0; payloadLength += type ? strlen(type) + 1 : 0; //If payload can't fit the payload plus a terminating null byte return. if (payloadLength > *length) { @@ -353,21 +271,16 @@ if (type) { strcat(payload, type); } - for (i = 0; i < valueCount; ++i) { - if (payload[0] != '\0') - strcat(payload, ","); - if (values[i].unit) - strcat(payload, values[i].unit); - else if (type) - strcat(payload, UNIT_UNDEFINED); - } - if (payload[0] != '\0' && valueCount > 0 && values[0].value) + if (payload[0] != '\0') + strcat(payload, ","); + if (unit) + strcat(payload, unit); + else if (type) + strcat(payload, UNIT_UNDEFINED); + if (payload[0] != '\0' && value) strcat(payload, "="); - for (i = 0; i < valueCount && values[i].value; ++i) { - strcat(payload, values[i].value); - if (i + 1 < valueCount) - strcat(payload, ","); - } + if (value) + strcat(payload, value); *length = --payloadLength; //Subtract terminating null return CAYENNE_SUCCESS; } @@ -381,13 +294,10 @@ * @return CAYENNE_SUCCESS if payload string was created, error code otherwise */ int CayenneBuildResponsePayload(char* payload, size_t* length, const char* id, const char* error) { - CayenneValuePair values[1]; - values[0].unit = id; - values[0].value = error; if (error) { - return CayenneBuildDataPayload(payload, length, "error", values, 1); + return CayenneBuildDataPayload(payload, length, "error", id, error); } - return CayenneBuildDataPayload(payload, length, "ok", values, 1); + return CayenneBuildDataPayload(payload, length, "ok", id, error); } /** @@ -400,7 +310,7 @@ * @param[in] length Topic name string length * @return CAYENNE_SUCCESS if topic was parsed, error code otherwise */ -int CayenneParseTopic(CayenneTopic* topic, unsigned int* channel, const char** clientID, const char* username, char* topicName, unsigned int length) { +int CayenneParseTopic(CayenneTopic* topic, unsigned int* channel, const char** clientID, const char* username, char* topicName, size_t length) { char* index = NULL; int i = 0; TopicChannel parseTopics[PARSE_TOPICS_COUNT] = { { COMMAND_TOPIC, CAYENNE_ALL_CHANNELS },{ CONFIG_TOPIC, CAYENNE_ALL_CHANNELS }, @@ -478,42 +388,37 @@ /** * Parse a null terminated payload in place. This may modify the payload string. -* @param[out] values Returned payload data unit & value array -* @param[in,out] valuesSize Size of values array, returns the count of values in the array * @param[out] type Returned type, NULL if there is none +* @param[out] unit Returned unit, NULL if there is none +* @param[out] value Returned value, NULL if there is none * @param[out] id Returned message id, empty string if there is none * @param[in] topic Cayenne topic * @param[in] payload Payload string, must be null terminated. * @return CAYENNE_SUCCESS if topic string was created, error code otherwise */ -int CayenneParsePayload(CayenneValuePair* values, size_t* valuesSize, const char** type, const char** id, CayenneTopic topic, char* payload) { - int i; - if (!payload || !valuesSize || *valuesSize == 0) +int CayenneParsePayload(const char** type, const char** unit, const char** value, const char** id, CayenneTopic topic, char* payload) { + if (!payload) return CAYENNE_FAILURE; *type = NULL; + *unit = NULL; + *value = NULL; *id = NULL; - for(i = 0; i < *valuesSize; i++) { - values[i].unit = NULL; - values[i].value = NULL; - } switch (topic) { #ifdef PARSE_INFO_PAYLOADS case DATA_TOPIC: - parsePayload(values, valuesSize, type, payload, '='); - if (!values[0].value) + parsePayload(type, unit, value, payload, '='); + if (!*value) return CAYENNE_FAILURE; break; #endif #ifdef DIGITAL_AND_ANALOG_SUPPORT #ifdef PARSE_INFO_PAYLOADS case ANALOG_TOPIC: - parsePayload(values, valuesSize, type, payload, 0); - values[0].unit = values[0].value; //Use unit to store resolution - values[0].value = *type; - *type = NULL; - if (!values[0].value) + //Use unit to store resolution + parsePayload(value, unit, unit, payload, 0); + if (!*value) return CAYENNE_FAILURE; break; #endif @@ -521,22 +426,19 @@ case ANALOG_COMMAND_TOPIC: #endif case COMMAND_TOPIC: - parsePayload(values, valuesSize, type, payload, 0); - *id = *type; - *type = NULL; - if (!values[0].value) + parsePayload(id, value, unit, payload, 0); + if (!*value) return CAYENNE_FAILURE; break; default: break; } - if (!values[0].value) { - values[0].value = payload; - values[0].unit = NULL; + if (!*value) { + *value = payload; + *unit = NULL; *type = NULL; *id = NULL; - *valuesSize = 1; } return CAYENNE_SUCCESS;