From e8971dd4914c9d42938c4c885b4ac6d784d7e0ff Mon Sep 17 00:00:00 2001
|
|
From: Hauke Mehrtens <hauke@hauke-m.de>
|
|
Date: Mon, 3 Oct 2016 23:22:36 +0200
|
|
Subject: [PATCH 2/3] csdk: move OCClientResponse from stack to heap
|
|
|
|
OCClientResponse is about 50KByte and should not be stored on the
|
|
stack. On LEDE with MIPS, musl libc this causes a segmentation fault.
|
|
Moving this structure to the heap is the simple solution for this
|
|
problem, but this structure should be shrined.
|
|
|
|
There are probably more places were this is stored on the stack and
|
|
will cause problems. This fixes the other issue I saw in
|
|
https://jira.iotivity.org/browse/IOT-1374
|
|
|
|
Change-Id: I45d8aee4a8151fea51d3318acb1eea61ce579060
|
|
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
|
|
---
|
|
resource/csdk/stack/src/ocstack.c | 163 ++++++++++++++++++++++++--------------
|
|
1 file changed, 102 insertions(+), 61 deletions(-)
|
|
|
|
--- a/resource/csdk/stack/src/ocstack.c
|
|
+++ b/resource/csdk/stack/src/ocstack.c
|
|
@@ -1042,7 +1042,7 @@ OCStackResult HandlePresenceResponse(con
|
|
OCStackApplicationResult cbResult = OC_STACK_DELETE_TRANSACTION;
|
|
ClientCB * cbNode = NULL;
|
|
char *resourceTypeName = NULL;
|
|
- OCClientResponse response = {.devAddr = {.adapter = OC_DEFAULT_ADAPTER}};
|
|
+ OCClientResponse *response = NULL;
|
|
OCStackResult result = OC_STACK_ERROR;
|
|
uint32_t maxAge = 0;
|
|
int uriLen;
|
|
@@ -1057,15 +1057,23 @@ OCStackResult HandlePresenceResponse(con
|
|
return OC_STACK_ERROR;
|
|
}
|
|
|
|
- response.payload = NULL;
|
|
- response.result = OC_STACK_OK;
|
|
+ response = (OCClientResponse *)OICCalloc(1, sizeof(*response));
|
|
+ if (!response)
|
|
+ {
|
|
+ OIC_LOG(ERROR, TAG, "Allocating memory for response failed");
|
|
+ return OC_STACK_ERROR;
|
|
+ }
|
|
+ response->devAddr.adapter = OC_DEFAULT_ADAPTER;
|
|
|
|
- CopyEndpointToDevAddr(endpoint, &response.devAddr);
|
|
- FixUpClientResponse(&response);
|
|
+ response->payload = NULL;
|
|
+ response->result = OC_STACK_OK;
|
|
+
|
|
+ CopyEndpointToDevAddr(endpoint, &response->devAddr);
|
|
+ FixUpClientResponse(response);
|
|
|
|
if (responseInfo->info.payload)
|
|
{
|
|
- result = OCParsePayload(&response.payload,
|
|
+ result = OCParsePayload(&response->payload,
|
|
PAYLOAD_TYPE_PRESENCE,
|
|
responseInfo->info.payload,
|
|
responseInfo->info.payloadSize);
|
|
@@ -1075,15 +1083,15 @@ OCStackResult HandlePresenceResponse(con
|
|
OIC_LOG(ERROR, TAG, "Presence parse failed");
|
|
goto exit;
|
|
}
|
|
- if(!response.payload || response.payload->type != PAYLOAD_TYPE_PRESENCE)
|
|
+ if(!response->payload || response->payload->type != PAYLOAD_TYPE_PRESENCE)
|
|
{
|
|
OIC_LOG(ERROR, TAG, "Presence payload was wrong type");
|
|
result = OC_STACK_ERROR;
|
|
goto exit;
|
|
}
|
|
- response.sequenceNumber = ((OCPresencePayload*)response.payload)->sequenceNumber;
|
|
- resourceTypeName = ((OCPresencePayload*)response.payload)->resourceType;
|
|
- maxAge = ((OCPresencePayload*)response.payload)->maxAge;
|
|
+ response->sequenceNumber = ((OCPresencePayload*)response->payload)->sequenceNumber;
|
|
+ resourceTypeName = ((OCPresencePayload*)response->payload)->resourceType;
|
|
+ maxAge = ((OCPresencePayload*)response->payload)->maxAge;
|
|
}
|
|
|
|
// check for unicast presence
|
|
@@ -1091,6 +1099,7 @@ OCStackResult HandlePresenceResponse(con
|
|
responseInfo->isMulticast);
|
|
if (uriLen < 0 || (size_t)uriLen >= sizeof (presenceUri))
|
|
{
|
|
+ OICFree(response);
|
|
return OC_STACK_INVALID_URI;
|
|
}
|
|
OIC_LOG(ERROR, TAG, "check for unicast presence");
|
|
@@ -1118,7 +1127,7 @@ OCStackResult HandlePresenceResponse(con
|
|
|
|
if (presenceSubscribe)
|
|
{
|
|
- if(cbNode->sequenceNumber == response.sequenceNumber)
|
|
+ if(cbNode->sequenceNumber == response->sequenceNumber)
|
|
{
|
|
OIC_LOG(INFO, TAG, "No presence change");
|
|
ResetPresenceTTL(cbNode, maxAge);
|
|
@@ -1129,7 +1138,7 @@ OCStackResult HandlePresenceResponse(con
|
|
if(maxAge == 0)
|
|
{
|
|
OIC_LOG(INFO, TAG, "Stopping presence");
|
|
- response.result = OC_STACK_PRESENCE_STOPPED;
|
|
+ response->result = OC_STACK_PRESENCE_STOPPED;
|
|
if(cbNode->presence)
|
|
{
|
|
OICFree(cbNode->presence->timeOut);
|
|
@@ -1165,7 +1174,7 @@ OCStackResult HandlePresenceResponse(con
|
|
|
|
ResetPresenceTTL(cbNode, maxAge);
|
|
|
|
- cbNode->sequenceNumber = response.sequenceNumber;
|
|
+ cbNode->sequenceNumber = response->sequenceNumber;
|
|
}
|
|
}
|
|
else
|
|
@@ -1175,7 +1184,7 @@ OCStackResult HandlePresenceResponse(con
|
|
if (0 == maxAge)
|
|
{
|
|
OIC_LOG(INFO, TAG, "Stopping presence");
|
|
- response.result = OC_STACK_PRESENCE_STOPPED;
|
|
+ response->result = OC_STACK_PRESENCE_STOPPED;
|
|
}
|
|
}
|
|
|
|
@@ -1191,7 +1200,7 @@ OCStackResult HandlePresenceResponse(con
|
|
|
|
OIC_LOG(INFO, TAG, "Callback for presence");
|
|
|
|
- cbResult = cbNode->callBack(cbNode->context, cbNode->handle, &response);
|
|
+ cbResult = cbNode->callBack(cbNode->context, cbNode->handle, response);
|
|
|
|
if (cbResult == OC_STACK_DELETE_TRANSACTION)
|
|
{
|
|
@@ -1199,7 +1208,8 @@ OCStackResult HandlePresenceResponse(con
|
|
}
|
|
|
|
exit:
|
|
- OCPayloadDestroy(response.payload);
|
|
+ OCPayloadDestroy(response->payload);
|
|
+ OICFree(response);
|
|
return result;
|
|
}
|
|
|
|
@@ -1240,36 +1250,53 @@ void OCHandleResponse(const CAEndpoint_t
|
|
OIC_LOG(INFO, TAG, "Receiving A Timeout for this token");
|
|
OIC_LOG(INFO, TAG, "Calling into application address space");
|
|
|
|
- OCClientResponse response =
|
|
- {.devAddr = {.adapter = OC_DEFAULT_ADAPTER}};
|
|
- CopyEndpointToDevAddr(endPoint, &response.devAddr);
|
|
- FixUpClientResponse(&response);
|
|
- response.resourceUri = responseInfo->info.resourceUri;
|
|
- memcpy(response.identity.id, responseInfo->info.identity.id,
|
|
- sizeof (response.identity.id));
|
|
- response.identity.id_length = responseInfo->info.identity.id_length;
|
|
+ OCClientResponse *response = NULL;
|
|
+
|
|
+ response = (OCClientResponse *)OICCalloc(1, sizeof(*response));
|
|
+ if (!response)
|
|
+ {
|
|
+ OIC_LOG(ERROR, TAG, "Allocating memory for response failed");
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ response->devAddr.adapter = OC_DEFAULT_ADAPTER;
|
|
+ CopyEndpointToDevAddr(endPoint, &response->devAddr);
|
|
+ FixUpClientResponse(response);
|
|
+ response->resourceUri = responseInfo->info.resourceUri;
|
|
+ memcpy(response->identity.id, responseInfo->info.identity.id,
|
|
+ sizeof (response->identity.id));
|
|
+ response->identity.id_length = responseInfo->info.identity.id_length;
|
|
|
|
- response.result = CAResponseToOCStackResult(responseInfo->result);
|
|
+ response->result = CAResponseToOCStackResult(responseInfo->result);
|
|
cbNode->callBack(cbNode->context,
|
|
- cbNode->handle, &response);
|
|
+ cbNode->handle, response);
|
|
FindAndDeleteClientCB(cbNode);
|
|
+ OICFree(response);
|
|
}
|
|
else
|
|
{
|
|
OIC_LOG(INFO, TAG, "This is a regular response, A client call back is found");
|
|
OIC_LOG(INFO, TAG, "Calling into application address space");
|
|
|
|
- OCClientResponse response =
|
|
- {.devAddr = {.adapter = OC_DEFAULT_ADAPTER}};
|
|
- response.sequenceNumber = MAX_SEQUENCE_NUMBER + 1;
|
|
- CopyEndpointToDevAddr(endPoint, &response.devAddr);
|
|
- FixUpClientResponse(&response);
|
|
- response.resourceUri = responseInfo->info.resourceUri;
|
|
- memcpy(response.identity.id, responseInfo->info.identity.id,
|
|
- sizeof (response.identity.id));
|
|
- response.identity.id_length = responseInfo->info.identity.id_length;
|
|
+ OCClientResponse *response = NULL;
|
|
|
|
- response.result = CAResponseToOCStackResult(responseInfo->result);
|
|
+ response = (OCClientResponse *)OICCalloc(1, sizeof(*response));
|
|
+ if (!response)
|
|
+ {
|
|
+ OIC_LOG(ERROR, TAG, "Allocating memory for response failed");
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ response->devAddr.adapter = OC_DEFAULT_ADAPTER;
|
|
+ response->sequenceNumber = MAX_SEQUENCE_NUMBER + 1;
|
|
+ CopyEndpointToDevAddr(endPoint, &response->devAddr);
|
|
+ FixUpClientResponse(response);
|
|
+ response->resourceUri = responseInfo->info.resourceUri;
|
|
+ memcpy(response->identity.id, responseInfo->info.identity.id,
|
|
+ sizeof (response->identity.id));
|
|
+ response->identity.id_length = responseInfo->info.identity.id_length;
|
|
+
|
|
+ response->result = CAResponseToOCStackResult(responseInfo->result);
|
|
|
|
if(responseInfo->info.payload &&
|
|
responseInfo->info.payloadSize)
|
|
@@ -1359,21 +1386,23 @@ void OCHandleResponse(const CAEndpoint_t
|
|
{
|
|
OIC_LOG_V(ERROR, TAG, "Unknown Payload type: %d %s",
|
|
cbNode->method, cbNode->requestUri);
|
|
+ OICFree(response);
|
|
return;
|
|
}
|
|
|
|
- if(OC_STACK_OK != OCParsePayload(&response.payload,
|
|
+ if(OC_STACK_OK != OCParsePayload(&response->payload,
|
|
type,
|
|
responseInfo->info.payload,
|
|
responseInfo->info.payloadSize))
|
|
{
|
|
OIC_LOG(ERROR, TAG, "Error converting payload");
|
|
- OCPayloadDestroy(response.payload);
|
|
+ OCPayloadDestroy(response->payload);
|
|
+ OICFree(response);
|
|
return;
|
|
}
|
|
}
|
|
|
|
- response.numRcvdVendorSpecificHeaderOptions = 0;
|
|
+ response->numRcvdVendorSpecificHeaderOptions = 0;
|
|
if(responseInfo->info.numOptions > 0)
|
|
{
|
|
int start = 0;
|
|
@@ -1391,19 +1420,20 @@ void OCHandleResponse(const CAEndpoint_t
|
|
observationOption =
|
|
(observationOption << 8) | optionData[i];
|
|
}
|
|
- response.sequenceNumber = observationOption;
|
|
- response.numRcvdVendorSpecificHeaderOptions = responseInfo->info.numOptions - 1;
|
|
+ response->sequenceNumber = observationOption;
|
|
+ response->numRcvdVendorSpecificHeaderOptions = responseInfo->info.numOptions - 1;
|
|
start = 1;
|
|
}
|
|
else
|
|
{
|
|
- response.numRcvdVendorSpecificHeaderOptions = responseInfo->info.numOptions;
|
|
+ response->numRcvdVendorSpecificHeaderOptions = responseInfo->info.numOptions;
|
|
}
|
|
|
|
- if(response.numRcvdVendorSpecificHeaderOptions > MAX_HEADER_OPTIONS)
|
|
+ if(response->numRcvdVendorSpecificHeaderOptions > MAX_HEADER_OPTIONS)
|
|
{
|
|
OIC_LOG(ERROR, TAG, "#header options are more than MAX_HEADER_OPTIONS");
|
|
- OCPayloadDestroy(response.payload);
|
|
+ OCPayloadDestroy(response->payload);
|
|
+ OICFree(response);
|
|
return;
|
|
}
|
|
|
|
@@ -1411,19 +1441,19 @@ void OCHandleResponse(const CAEndpoint_t
|
|
{
|
|
if(&(responseInfo->info.options[i]))
|
|
{
|
|
- memcpy (&(response.rcvdVendorSpecificHeaderOptions[i-start]),
|
|
+ memcpy (&(response->rcvdVendorSpecificHeaderOptions[i-start]),
|
|
&(responseInfo->info.options[i]), sizeof(OCHeaderOption));
|
|
}
|
|
}
|
|
}
|
|
|
|
if (cbNode->method == OC_REST_OBSERVE &&
|
|
- response.sequenceNumber > OC_OFFSET_SEQUENCE_NUMBER &&
|
|
+ response->sequenceNumber > OC_OFFSET_SEQUENCE_NUMBER &&
|
|
cbNode->sequenceNumber <= MAX_SEQUENCE_NUMBER &&
|
|
- response.sequenceNumber <= cbNode->sequenceNumber)
|
|
+ response->sequenceNumber <= cbNode->sequenceNumber)
|
|
{
|
|
OIC_LOG_V(INFO, TAG, "Received stale notification. Number :%d",
|
|
- response.sequenceNumber);
|
|
+ response->sequenceNumber);
|
|
}
|
|
else
|
|
{
|
|
@@ -1432,13 +1462,13 @@ void OCHandleResponse(const CAEndpoint_t
|
|
char *targetUri = strstr(cbNode->requestUri, OC_RSRVD_RD_URI);
|
|
if (targetUri)
|
|
{
|
|
- OCUpdateResourceInsWithResponse(cbNode->requestUri, &response);
|
|
+ OCUpdateResourceInsWithResponse(cbNode->requestUri, response);
|
|
}
|
|
#endif
|
|
OCStackApplicationResult appFeedback = cbNode->callBack(cbNode->context,
|
|
cbNode->handle,
|
|
- &response);
|
|
- cbNode->sequenceNumber = response.sequenceNumber;
|
|
+ response);
|
|
+ cbNode->sequenceNumber = response->sequenceNumber;
|
|
|
|
if (appFeedback == OC_STACK_DELETE_TRANSACTION)
|
|
{
|
|
@@ -1459,7 +1489,8 @@ void OCHandleResponse(const CAEndpoint_t
|
|
CA_MSG_ACKNOWLEDGE, 0, NULL, NULL, 0, NULL, CA_RESPONSE_FOR_RES);
|
|
}
|
|
|
|
- OCPayloadDestroy(response.payload);
|
|
+ OCPayloadDestroy(response->payload);
|
|
+ OICFree(response);
|
|
}
|
|
return;
|
|
}
|
|
@@ -1585,16 +1616,26 @@ void HandleCAErrorResponse(const CAEndpo
|
|
errorInfo->info.tokenLength, NULL, NULL);
|
|
if (cbNode)
|
|
{
|
|
- OCClientResponse response = { .devAddr = { .adapter = OC_DEFAULT_ADAPTER } };
|
|
- CopyEndpointToDevAddr(endPoint, &response.devAddr);
|
|
- FixUpClientResponse(&response);
|
|
- response.resourceUri = errorInfo->info.resourceUri;
|
|
- memcpy(response.identity.id, errorInfo->info.identity.id,
|
|
- sizeof (response.identity.id));
|
|
- response.identity.id_length = errorInfo->info.identity.id_length;
|
|
- response.result = CAResultToOCResult(errorInfo->result);
|
|
+ OCClientResponse *response = NULL;
|
|
+
|
|
+ response = (OCClientResponse *)OICCalloc(1, sizeof(*response));
|
|
+ if (!response)
|
|
+ {
|
|
+ OIC_LOG(ERROR, TAG, "Allocating memory for response failed");
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ response->devAddr.adapter = OC_DEFAULT_ADAPTER;
|
|
+ CopyEndpointToDevAddr(endPoint, &response->devAddr);
|
|
+ FixUpClientResponse(response);
|
|
+ response->resourceUri = errorInfo->info.resourceUri;
|
|
+ memcpy(response->identity.id, errorInfo->info.identity.id,
|
|
+ sizeof (response->identity.id));
|
|
+ response->identity.id_length = errorInfo->info.identity.id_length;
|
|
+ response->result = CAResultToOCResult(errorInfo->result);
|
|
|
|
- cbNode->callBack(cbNode->context, cbNode->handle, &response);
|
|
+ cbNode->callBack(cbNode->context, cbNode->handle, response);
|
|
+ OICFree(response);
|
|
}
|
|
|
|
ResourceObserver *observer = GetObserverUsingToken(errorInfo->info.token,
|