summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTodd Malsbary <todd.malsbary@intel.com>2017-04-11 11:42:10 -0700
committerDan Mihai <Daniel.Mihai@microsoft.com>2017-04-18 15:46:42 +0000
commit5767203911c874ab2b2b027db372996b6904e99b (patch)
tree05468bbaf88406a9e4d58d4e4e7878120620b528
parentdf218cd3941360bad0e83c8d051ae0dc716c56f3 (diff)
downloadiotivity-5767203911c874ab2b2b027db372996b6904e99b.tar.gz
iotivity-5767203911c874ab2b2b027db372996b6904e99b.tar.bz2
iotivity-5767203911c874ab2b2b027db372996b6904e99b.zip
[IOT-1942] Add support for diagnostic payloads.
Bug: https://jira.iotivity.org/browse/IOT-1942 Change-Id: Ia4d761bfc49d646b2e1514844826411df272d5a4 Signed-off-by: Todd Malsbary <todd.malsbary@intel.com> Reviewed-on: https://gerrit.iotivity.org/gerrit/18721 Tested-by: jenkins-iotivity <jenkins@iotivity.org> Reviewed-by: Dan Mihai <Daniel.Mihai@microsoft.com>
-rw-r--r--resource/csdk/include/octypes.h10
-rw-r--r--resource/csdk/stack/include/ocpayload.h4
-rw-r--r--resource/csdk/stack/src/ocpayload.c31
-rwxr-xr-xresource/csdk/stack/src/ocpayloadconvert.c20
-rwxr-xr-xresource/csdk/stack/src/ocpayloadparse.c34
-rw-r--r--resource/csdk/stack/src/ocserverrequest.c3
-rw-r--r--resource/csdk/stack/src/ocstack.c18
-rw-r--r--resource/csdk/stack/test/gtest_helper.h1
-rw-r--r--resource/csdk/stack/test/stacktests.cpp61
9 files changed, 176 insertions, 6 deletions
diff --git a/resource/csdk/include/octypes.h b/resource/csdk/include/octypes.h
index 524dad642..111e34c22 100644
--- a/resource/csdk/include/octypes.h
+++ b/resource/csdk/include/octypes.h
@@ -1418,7 +1418,9 @@ typedef enum
/** The payload is an OCSecurityPayload */
PAYLOAD_TYPE_SECURITY,
/** The payload is an OCPresencePayload */
- PAYLOAD_TYPE_PRESENCE
+ PAYLOAD_TYPE_PRESENCE,
+ /** The payload is an OCDiagnosticPayload */
+ PAYLOAD_TYPE_DIAGNOSTIC
} OCPayloadType;
/**
@@ -1578,6 +1580,12 @@ typedef struct
} OCPresencePayload;
#endif
+typedef struct
+{
+ OCPayload base;
+ char* message;
+} OCDiagnosticPayload;
+
/**
* Incoming requests handled by the server. Requests are passed in as a parameter to the
* OCEntityHandler callback API.
diff --git a/resource/csdk/stack/include/ocpayload.h b/resource/csdk/stack/include/ocpayload.h
index 66562b7a3..556571027 100644
--- a/resource/csdk/stack/include/ocpayload.h
+++ b/resource/csdk/stack/include/ocpayload.h
@@ -264,6 +264,10 @@ OCPresencePayload* OCPresencePayloadCreate(uint32_t seqNum, uint32_t maxAge,
OCPresenceTrigger trigger, const char* resourceType);
void OCPresencePayloadDestroy(OCPresencePayload* payload);
+// Diagnostic Payload
+OCDiagnosticPayload* OCDiagnosticPayloadCreate(const char *message);
+void OCDiagnosticPayloadDestroy(OCDiagnosticPayload* payload);
+
// Helper API
OCStringLL* CloneOCStringLL (OCStringLL* ll);
void OCFreeOCStringLL(OCStringLL* ll);
diff --git a/resource/csdk/stack/src/ocpayload.c b/resource/csdk/stack/src/ocpayload.c
index 957eeeff4..27c2f98f2 100644
--- a/resource/csdk/stack/src/ocpayload.c
+++ b/resource/csdk/stack/src/ocpayload.c
@@ -59,6 +59,9 @@ void OCPayloadDestroy(OCPayload* payload)
case PAYLOAD_TYPE_PRESENCE:
OCPresencePayloadDestroy((OCPresencePayload*)payload);
break;
+ case PAYLOAD_TYPE_DIAGNOSTIC:
+ OCDiagnosticPayloadDestroy((OCDiagnosticPayload*)payload);
+ break;
case PAYLOAD_TYPE_SECURITY:
OCSecurityPayloadDestroy((OCSecurityPayload*)payload);
break;
@@ -2137,6 +2140,34 @@ void OCPresencePayloadDestroy(OCPresencePayload* payload)
OICFree(payload);
}
+OCDiagnosticPayload* OCDiagnosticPayloadCreate(const char* message)
+{
+ if (!message)
+ {
+ return NULL;
+ }
+
+ OCDiagnosticPayload* payload = (OCDiagnosticPayload*)OICCalloc(1, sizeof(OCDiagnosticPayload));
+ if (!payload)
+ {
+ return NULL;
+ }
+
+ payload->base.type = PAYLOAD_TYPE_DIAGNOSTIC;
+ payload->message = OICStrdup(message);
+ return payload;
+}
+
+void OCDiagnosticPayloadDestroy(OCDiagnosticPayload* payload)
+{
+ if (!payload)
+ {
+ return;
+ }
+ OICFree(payload->message);
+ OICFree(payload);
+}
+
OCStackResult OCLinksPayloadValueCreate(const char* resourceUri, OCRepPayloadValue** linksRepPayloadValue,
OCDevAddr* devAddr)
{
diff --git a/resource/csdk/stack/src/ocpayloadconvert.c b/resource/csdk/stack/src/ocpayloadconvert.c
index 0e76b306e..5cdbf5520 100755
--- a/resource/csdk/stack/src/ocpayloadconvert.c
+++ b/resource/csdk/stack/src/ocpayloadconvert.c
@@ -54,6 +54,8 @@ static int64_t OCConvertRepPayload(OCRepPayload *payload, uint8_t *outPayload, s
static int64_t OCConvertRepMap(CborEncoder *map, const OCRepPayload *payload);
static int64_t OCConvertPresencePayload(OCPresencePayload *payload, uint8_t *outPayload,
size_t *size);
+static int64_t OCConvertDiagnosticPayload(OCDiagnosticPayload *payload, uint8_t *outPayload,
+ size_t *size);
static int64_t OCConvertSecurityPayload(OCSecurityPayload *payload, uint8_t *outPayload,
size_t *size);
static int64_t OCConvertSingleRepPayloadValue(CborEncoder *parent, const OCRepPayloadValue *value);
@@ -147,6 +149,8 @@ static int64_t OCConvertPayloadHelper(OCPayload* payload, OCPayloadFormat format
return OCConvertRepPayload((OCRepPayload*)payload, outPayload, size);
case PAYLOAD_TYPE_PRESENCE:
return OCConvertPresencePayload((OCPresencePayload*)payload, outPayload, size);
+ case PAYLOAD_TYPE_DIAGNOSTIC:
+ return OCConvertDiagnosticPayload((OCDiagnosticPayload*)payload, outPayload, size);
case PAYLOAD_TYPE_SECURITY:
return OCConvertSecurityPayload((OCSecurityPayload*)payload, outPayload, size);
default:
@@ -1011,6 +1015,22 @@ exit:
return checkError(err, &encoder, outPayload, size);
}
+static int64_t OCConvertDiagnosticPayload(OCDiagnosticPayload *payload, uint8_t *outPayload,
+ size_t *size)
+{
+ int64_t err = CborNoError;
+ CborEncoder encoder;
+
+ cbor_encoder_init(&encoder, outPayload, *size, 0);
+
+ // Message
+ err |= cbor_encode_text_string(&encoder, payload->message, strlen(payload->message));
+ VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding message");
+
+exit:
+ return checkError(err, &encoder, outPayload, size);
+}
+
static int64_t AddTextStringToMap(CborEncoder* map, const char* key, size_t keylen,
const char* value)
{
diff --git a/resource/csdk/stack/src/ocpayloadparse.c b/resource/csdk/stack/src/ocpayloadparse.c
index 2dcd6c602..68ed73bb9 100755
--- a/resource/csdk/stack/src/ocpayloadparse.c
+++ b/resource/csdk/stack/src/ocpayloadparse.c
@@ -50,6 +50,7 @@ static OCStackResult OCParseDiscoveryPayload(OCPayload **outPayload, OCPayloadFo
static CborError OCParseSingleRepPayload(OCRepPayload **outPayload, CborValue *repParent, bool isRoot);
static OCStackResult OCParseRepPayload(OCPayload **outPayload, CborValue *arrayVal);
static OCStackResult OCParsePresencePayload(OCPayload **outPayload, CborValue *arrayVal);
+static OCStackResult OCParseDiagnosticPayload(OCPayload **outPayload, CborValue *arrayVal);
static OCStackResult OCParseSecurityPayload(OCPayload **outPayload, const uint8_t *payload, size_t size);
OCStackResult OCParsePayload(OCPayload **outPayload, OCPayloadFormat payloadFormat,
@@ -81,6 +82,9 @@ OCStackResult OCParsePayload(OCPayload **outPayload, OCPayloadFormat payloadForm
case PAYLOAD_TYPE_PRESENCE:
result = OCParsePresencePayload(outPayload, &rootValue);
break;
+ case PAYLOAD_TYPE_DIAGNOSTIC:
+ result = OCParseDiagnosticPayload(outPayload, &rootValue);
+ break;
case PAYLOAD_TYPE_SECURITY:
result = OCParseSecurityPayload(outPayload, payload, payloadSize);
break;
@@ -1327,3 +1331,33 @@ exit:
OCPresencePayloadDestroy(payload);
return ret;
}
+
+static OCStackResult OCParseDiagnosticPayload(OCPayload **outPayload, CborValue *rootValue)
+{
+ OCStackResult ret = OC_STACK_INVALID_PARAM;
+ OCDiagnosticPayload *payload = NULL;
+ VERIFY_PARAM_NON_NULL(TAG, outPayload, "Invalid Parameter outPayload");
+
+ *outPayload = NULL;
+
+ payload = (OCDiagnosticPayload *)OICCalloc(1, sizeof(OCDiagnosticPayload));
+ ret = OC_STACK_NO_MEMORY;
+ VERIFY_PARAM_NON_NULL(TAG, payload, "Failed allocating diagnostic payload");
+ payload->base.type = PAYLOAD_TYPE_DIAGNOSTIC;
+ ret = OC_STACK_MALFORMED_RESPONSE;
+
+ if (cbor_value_is_text_string(rootValue))
+ {
+ size_t len = 0;
+ CborError err = cbor_value_dup_text_string(rootValue, &payload->message, &len, NULL);
+ VERIFY_CBOR_SUCCESS(TAG, err, "Failed finding message value");
+ }
+
+ *outPayload = (OCPayload *)payload;
+ return OC_STACK_OK;
+
+exit:
+ OIC_LOG(ERROR, TAG, "CBOR error Parse Diagnostic Payload");
+ OCDiagnosticPayloadDestroy(payload);
+ return ret;
+}
diff --git a/resource/csdk/stack/src/ocserverrequest.c b/resource/csdk/stack/src/ocserverrequest.c
index fddd9c1b9..4a67eb3ed 100644
--- a/resource/csdk/stack/src/ocserverrequest.c
+++ b/resource/csdk/stack/src/ocserverrequest.c
@@ -658,7 +658,8 @@ OCStackResult HandleSingleResponse(OCEntityHandlerResponse * ehResponse)
return result;
}
// Add CONTENT_FORMAT OPT if payload exist
- if (responseInfo.info.payloadSize > 0)
+ if (ehResponse->payload->type != PAYLOAD_TYPE_DIAGNOSTIC &&
+ responseInfo.info.payloadSize > 0)
{
responseInfo.info.payloadFormat = OCToCAPayloadFormat(
serverRequest->acceptFormat);
diff --git a/resource/csdk/stack/src/ocstack.c b/resource/csdk/stack/src/ocstack.c
index 4b24117f3..7361c8074 100644
--- a/resource/csdk/stack/src/ocstack.c
+++ b/resource/csdk/stack/src/ocstack.c
@@ -1692,9 +1692,18 @@ void OCHandleResponse(const CAEndpoint_t* endPoint, const CAResponseInfo_t* resp
}
if (type == PAYLOAD_TYPE_INVALID)
{
- OIC_LOG_V(INFO, TAG, "Assuming PAYLOAD_TYPE_REPRESENTATION: %d %s",
- cbNode->method, cbNode->requestUri);
- type = PAYLOAD_TYPE_REPRESENTATION;
+ if (responseInfo->info.payloadFormat == CA_FORMAT_UNDEFINED)
+ {
+ OIC_LOG_V(INFO, TAG, "Assuming PAYLOAD_TYPE_DIAGNOSTIC: %d %s",
+ cbNode->method, cbNode->requestUri);
+ type = PAYLOAD_TYPE_DIAGNOSTIC;
+ }
+ else
+ {
+ OIC_LOG_V(INFO, TAG, "Assuming PAYLOAD_TYPE_REPRESENTATION: %d %s",
+ cbNode->method, cbNode->requestUri);
+ type = PAYLOAD_TYPE_REPRESENTATION;
+ }
}
}
else
@@ -1712,7 +1721,8 @@ void OCHandleResponse(const CAEndpoint_t* endPoint, const CAResponseInfo_t* resp
}
// In case of error, still want application to receive the error message.
- if (OCResultToSuccess(response->result) || PAYLOAD_TYPE_REPRESENTATION == type)
+ if (OCResultToSuccess(response->result) || PAYLOAD_TYPE_REPRESENTATION == type ||
+ PAYLOAD_TYPE_DIAGNOSTIC == type)
{
if (OC_STACK_OK != OCParsePayload(&response->payload,
CAToOCPayloadFormat(responseInfo->info.payloadFormat),
diff --git a/resource/csdk/stack/test/gtest_helper.h b/resource/csdk/stack/test/gtest_helper.h
index a3c73cba9..b68799be6 100644
--- a/resource/csdk/stack/test/gtest_helper.h
+++ b/resource/csdk/stack/test/gtest_helper.h
@@ -168,6 +168,7 @@ namespace iotivity
break;
}
OCProcess();
+ std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
return m_called ? OC_STACK_OK : OC_STACK_TIMEOUT;
}
diff --git a/resource/csdk/stack/test/stacktests.cpp b/resource/csdk/stack/test/stacktests.cpp
index 8e4a8c9d9..b5b53eeea 100644
--- a/resource/csdk/stack/test/stacktests.cpp
+++ b/resource/csdk/stack/test/stacktests.cpp
@@ -2817,3 +2817,64 @@ TEST(LinksPayloadValue, createLinksPayloadValue)
EXPECT_EQ(OC_STACK_OK, OCStop());
}
+
+TEST(DiagnosticPayload, CreateDestroy)
+{
+ OCDiagnosticPayload *payload;
+
+ payload = NULL;
+ OCDiagnosticPayloadDestroy(payload);
+
+ payload = OCDiagnosticPayloadCreate(NULL);
+ ASSERT_TRUE(payload == NULL);
+
+ payload = OCDiagnosticPayloadCreate("message");
+ ASSERT_TRUE(payload != NULL);
+ ASSERT_STREQ("message", payload->message);
+ OCDiagnosticPayloadDestroy(payload);
+}
+
+static OCEntityHandlerResult DiagnosticPayloadRequest(OCEntityHandlerFlag flag,
+ OCEntityHandlerRequest *request, void *ctx)
+{
+ OC_UNUSED(flag);
+ OC_UNUSED(ctx);
+ OCEntityHandlerResponse response;
+ memset(&response, 0, sizeof(response));
+ response.requestHandle = request->requestHandle;
+ response.resourceHandle = request->resource;
+ response.ehResult = OC_EH_BAD_REQ;
+ response.payload = (OCPayload*) OCDiagnosticPayloadCreate("message");
+ EXPECT_TRUE(response.payload != NULL);
+ EXPECT_EQ(OC_STACK_OK, OCDoResponse(&response));
+ return OC_EH_OK;
+}
+
+static OCStackApplicationResult DiagnosticPayloadResponse(void *ctx, OCDoHandle handle,
+ OCClientResponse *response)
+{
+ OC_UNUSED(ctx);
+ OC_UNUSED(handle);
+ EXPECT_EQ(OC_STACK_INVALID_QUERY, response->result);
+ EXPECT_EQ(PAYLOAD_TYPE_DIAGNOSTIC, response->payload->type);
+ OCDiagnosticPayload *payload = (OCDiagnosticPayload*) response->payload;
+ EXPECT_STREQ("message", payload->message);
+ return OC_STACK_DELETE_TRANSACTION;
+}
+
+TEST(DiagnosticPayload, DISABLED_EndToEnd)
+{
+ EXPECT_EQ(OC_STACK_OK, OCInit("127.0.0.1", 5683, OC_CLIENT_SERVER));
+ itst::DeadmanTimer killSwitch(SHORT_TEST_TIMEOUT);
+
+ OCResourceHandle handle;
+ EXPECT_EQ(OC_STACK_OK, OCCreateResource(&handle, "core.light", "oic.if.baseline", "/a/light",
+ DiagnosticPayloadRequest, NULL, OC_DISCOVERABLE));
+
+ itst::Callback diagnosticPayloadCB(&DiagnosticPayloadResponse);
+ EXPECT_EQ(OC_STACK_OK, OCDoResource(NULL, OC_REST_GET, "127.0.0.1:5683/a/light", NULL,
+ 0, CT_DEFAULT, OC_HIGH_QOS, diagnosticPayloadCB, NULL, 0));
+ EXPECT_EQ(OC_STACK_OK, diagnosticPayloadCB.Wait(100));
+
+ OCStop();
+}