CA Integration: Adding observe cancellation support
[platform/upstream/iotivity.git] / resource / csdk / stack / src / ocserverrequest.c
1 //******************************************************************
2 //
3 // Copyright 2014 Intel Mobile Communications GmbH All Rights Reserved.
4 //
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
6 //
7 // Licensed under the Apache License, Version 2.0 (the "License");
8 // you may not use this file except in compliance with the License.
9 // You may obtain a copy of the License at
10 //
11 //      http://www.apache.org/licenses/LICENSE-2.0
12 //
13 // Unless required by applicable law or agreed to in writing, software
14 // distributed under the License is distributed on an "AS IS" BASIS,
15 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 // See the License for the specific language governing permissions and
17 // limitations under the License.
18 //
19 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
20
21 #include "ocstack.h"
22 #include "ocserverrequest.h"
23 #include "ocresourcehandler.h"
24
25
26 #ifdef CA_INT
27     #include "cacommon.h"
28     #include "cainterface.h"
29 #endif
30
31 // Module Name
32 #define VERIFY_NON_NULL(arg) { if (!arg) {OC_LOG(FATAL, TAG, #arg " is NULL"); goto exit;} }
33
34 #define TAG  PCF("ocserverrequest")
35
36 static struct OCServerRequest * serverRequestList = NULL;
37 static struct OCServerResponse * serverResponseList = NULL;
38
39 OCServerRequest * GetServerRequestUsingToken (const OCCoAPToken token)
40 {
41     OCServerRequest * out = NULL;
42     LL_FOREACH (serverRequestList, out)
43     {
44         OC_LOG(INFO, TAG,PCF("comparing tokens"));
45         OC_LOG_BUFFER(INFO, TAG, token.token, token.tokenLength);
46         OC_LOG_BUFFER(INFO, TAG, out->requestToken.token, out->requestToken.tokenLength);
47         if((out->requestToken.tokenLength == token.tokenLength) &&
48                 (memcmp(out->requestToken.token, token.token, token.tokenLength) == 0))
49         {
50             return out;
51         }
52     }
53     OC_LOG(INFO, TAG, PCF("Server Request not found!!"));
54     return NULL;
55 }
56
57 OCServerRequest * GetServerRequestUsingHandle (const OCServerRequest * handle)
58 {
59     OCServerRequest * out = NULL;
60     LL_FOREACH (serverRequestList, out)
61     {
62         if(out == handle)
63         {
64             return out;
65         }
66     }
67     OC_LOG(INFO, TAG, PCF("Server Request not found!!"));
68     return NULL;
69 }
70
71 OCServerResponse * GetServerResponseUsingHandle (const OCServerRequest * handle)
72 {
73     OCServerResponse * out = NULL;
74     LL_FOREACH (serverResponseList, out)
75     {
76         if(out->requestHandle == handle)
77         {
78             return out;
79         }
80     }
81     OC_LOG(INFO, TAG, PCF("Server Response not found!!"));
82     return NULL;
83 }
84
85 OCStackResult AddServerRequest (OCServerRequest ** request, uint16_t coapID,
86         uint8_t delayedResNeeded, uint8_t secured, uint8_t notificationFlag, OCMethod method,
87         uint8_t numRcvdVendorSpecificHeaderOptions, uint32_t observationOption,
88         OCQualityOfService qos, unsigned char * query,
89         OCHeaderOption * rcvdVendorSpecificHeaderOptions,
90         unsigned char * reqJSONPayload, OCCoAPToken * requestToken,
91         OCDevAddr * requesterAddr, unsigned char * resourceUrl, size_t reqTotalSize)
92 {
93     OCServerRequest * serverRequest = NULL;
94
95     //Note: OCServerRequest includes 1 byte for the JSON Payload.  payloadSize is calculated
96     //as the required length of the string, so this will result in enough room for the
97     //null terminator as well.
98     serverRequest = (OCServerRequest *) OCCalloc(1, sizeof(OCServerRequest) + reqTotalSize - 1);
99     VERIFY_NON_NULL(serverRequest);
100
101     serverRequest->coapID = coapID;
102     serverRequest->delayedResNeeded = delayedResNeeded;
103     serverRequest->secured = secured;
104     serverRequest->notificationFlag = notificationFlag;
105
106     serverRequest->method = method;
107     serverRequest->numRcvdVendorSpecificHeaderOptions = numRcvdVendorSpecificHeaderOptions;
108     serverRequest->observationOption = observationOption;
109     serverRequest->observeResult = OC_STACK_ERROR;
110     serverRequest->qos = qos;
111     serverRequest->ehResponseHandler = HandleSingleResponse;
112     serverRequest->numResponses = 1;
113     if(query)
114     {
115         memcpy(serverRequest->query, query, strlen((const char *)query) + 1);
116     }
117     if(rcvdVendorSpecificHeaderOptions)
118     {
119         memcpy(serverRequest->rcvdVendorSpecificHeaderOptions, rcvdVendorSpecificHeaderOptions,
120             MAX_HEADER_OPTIONS * sizeof(OCHeaderOption));
121     }
122     if(reqJSONPayload)
123     {
124         // destination is at least 1 greater than the source, so a NULL always exists in the
125         // last character
126         strncpy((char*)serverRequest->reqJSONPayload,
127                 (const char*)reqJSONPayload, reqTotalSize - 1);
128     }
129     serverRequest->requestComplete = 0;
130     if(requestToken)
131     {
132         memcpy(&serverRequest->requestToken, requestToken, sizeof(OCCoAPToken));
133     }
134     if(requesterAddr)
135     {
136         memcpy(&serverRequest->requesterAddr, requesterAddr, sizeof(OCDevAddr));
137     }
138     if(resourceUrl)
139     {
140         memcpy(serverRequest->resourceUrl, resourceUrl, strlen((const char *)resourceUrl) + 1);
141     }
142
143     *request = serverRequest;
144     OC_LOG(INFO, TAG, PCF("Server Request Added!!"));
145     LL_APPEND (serverRequestList, serverRequest);
146     return OC_STACK_OK;
147
148 exit:
149     if (serverRequest)
150     {
151         OCFree(serverRequest);
152         serverRequest = NULL;
153     }
154     *request = NULL;
155     return OC_STACK_NO_MEMORY;
156 }
157
158 #ifdef CA_INT
159 OCStackResult AddServerCARequest (OCServerRequest ** request, uint16_t coapID,
160         uint8_t delayedResNeeded, uint8_t secured, uint8_t notificationFlag, OCMethod method,
161         uint8_t numRcvdVendorSpecificHeaderOptions, uint32_t observationOption,
162         OCQualityOfService qos, unsigned char * query,
163         OCHeaderOption * rcvdVendorSpecificHeaderOptions,
164         unsigned char * reqJSONPayload, OCCoAPToken * requestToken,
165         OCDevAddr * requesterAddr, unsigned char * resourceUrl, size_t reqTotalSize,
166         CAAddress_t *addressInfo, CAConnectivityType_t connectivityType, char *token)
167 {
168     OCServerRequest * serverRequest = NULL;
169
170     //Note: OCServerRequest includes 1 byte for the JSON Payload.  payloadSize is calculated
171     //as the required length of the string, so this will result in enough room for the
172     //null terminator as well.
173     serverRequest = (OCServerRequest *) OCCalloc(1, sizeof(OCServerRequest) + reqTotalSize - 1);
174     VERIFY_NON_NULL(serverRequest);
175
176     serverRequest->coapID = coapID;
177     serverRequest->delayedResNeeded = delayedResNeeded;
178     serverRequest->secured = secured;
179     serverRequest->notificationFlag = notificationFlag;
180
181     serverRequest->method = method;
182     serverRequest->numRcvdVendorSpecificHeaderOptions = numRcvdVendorSpecificHeaderOptions;
183     serverRequest->observationOption = observationOption;
184     serverRequest->observeResult = OC_STACK_ERROR;
185     serverRequest->qos = qos;
186     serverRequest->ehResponseHandler = HandleSingleResponse;
187     serverRequest->numResponses = 1;
188     if(query)
189     {
190         memcpy(serverRequest->query, query, strlen((const char *)query) + 1);
191     }
192     if(rcvdVendorSpecificHeaderOptions)
193     {
194         memcpy(serverRequest->rcvdVendorSpecificHeaderOptions, rcvdVendorSpecificHeaderOptions,
195             MAX_HEADER_OPTIONS * sizeof(OCHeaderOption));
196     }
197     if(reqJSONPayload)
198     {
199         // destination is at least 1 greater than the source, so a NULL always exists in the
200         // last character
201         strncpy((char*)serverRequest->reqJSONPayload,
202                 (const char*)reqJSONPayload, reqTotalSize - 1);
203     }
204     serverRequest->requestComplete = 0;
205     if(requestToken)
206     {
207         memcpy(&serverRequest->requestToken, requestToken, sizeof(OCCoAPToken));
208     }
209     if(requesterAddr)
210     {
211         memcpy(&serverRequest->requesterAddr, requesterAddr, sizeof(OCDevAddr));
212     }
213     if(resourceUrl)
214     {
215         memcpy(serverRequest->resourceUrl, resourceUrl, strlen((const char *)resourceUrl) + 1);
216     }
217
218     if (addressInfo)
219     {
220         serverRequest->addressInfo = *addressInfo;
221     }
222     serverRequest->connectivityType = connectivityType;
223     if (token)
224     {
225         strncpy(serverRequest->token, token, CA_MAX_TOKEN_LEN);
226     }
227
228     *request = serverRequest;
229     OC_LOG(INFO, TAG, PCF("Server Request Added!!"));
230     LL_APPEND (serverRequestList, serverRequest);
231     return OC_STACK_OK;
232
233 exit:
234     if (serverRequest)
235     {
236         OCFree(serverRequest);
237         serverRequest = NULL;
238     }
239     *request = NULL;
240     return OC_STACK_NO_MEMORY;
241 }
242 #endif
243
244 OCStackResult AddServerResponse (OCServerResponse ** response, OCRequestHandle requestHandle)
245 {
246     OCServerResponse * serverResponse = NULL;
247
248     serverResponse = (OCServerResponse *) OCCalloc(1, sizeof(OCServerResponse));
249     VERIFY_NON_NULL(serverResponse);
250
251     serverResponse->payload = (unsigned char *) OCMalloc(MAX_RESPONSE_LENGTH);
252     VERIFY_NON_NULL(serverResponse->payload);
253     memset(serverResponse->payload, 0, sizeof(MAX_RESPONSE_LENGTH));
254
255     serverResponse->remainingPayloadSize = MAX_RESPONSE_LENGTH;
256     serverResponse->requestHandle = requestHandle;
257
258     *response = serverResponse;
259     OC_LOG(INFO, TAG, PCF("Server Response Added!!"));
260     LL_APPEND (serverResponseList, serverResponse);
261     return OC_STACK_OK;
262
263 exit:
264     if (serverResponse)
265     {
266         OCFree(serverResponse);
267         serverResponse = NULL;
268     }
269     *response = NULL;
270     return OC_STACK_NO_MEMORY;
271 }
272
273 // Form the OCEntityHandlerRequest struct
274 OCStackResult FormOCEntityHandlerRequest(OCEntityHandlerRequest * entityHandlerRequest, OCRequestHandle request,
275         OCMethod method, OCResourceHandle resource, unsigned char * queryBuf, unsigned char * bufReqPayload,
276         uint8_t numVendorOptions, OCHeaderOption * vendorOptions, OCObserveAction observeAction,
277         OCObservationId observeID)
278 {
279     if (entityHandlerRequest)
280     {
281         memset(entityHandlerRequest, 0, sizeof(OCEntityHandlerRequest));
282         entityHandlerRequest->requestHandle = request;
283         entityHandlerRequest->method = method;
284         entityHandlerRequest->resource = (OCResourceHandle) resource;
285         entityHandlerRequest->query = queryBuf;
286         entityHandlerRequest->reqJSONPayload = bufReqPayload;
287         entityHandlerRequest->numRcvdVendorSpecificHeaderOptions = numVendorOptions;
288         entityHandlerRequest->rcvdVendorSpecificHeaderOptions = vendorOptions;
289
290         entityHandlerRequest->obsInfo.action = observeAction;
291         entityHandlerRequest->obsInfo.obsId = observeID;
292         return OC_STACK_OK;
293     }
294
295     return OC_STACK_INVALID_PARAM;
296 }
297
298 void FindAndDeleteServerResponse(OCServerResponse * serverResponse)
299 {
300     OCServerResponse* tmp;
301     if(serverResponse)
302     {
303         LL_FOREACH(serverResponseList, tmp)
304         {
305             if (serverResponse == tmp)
306             {
307                 DeleteServerResponse(tmp);
308                 return;
309             }
310         }
311     }
312 }
313
314 void DeleteServerResponse(OCServerResponse * serverResponse)
315 {
316     if(serverResponse) {
317         LL_DELETE(serverResponseList, serverResponse);
318         OCFree(serverResponse->payload);
319         OCFree(serverResponse);
320         OC_LOG(INFO, TAG, PCF("Server Response Removed!!"));
321     }
322 }
323
324 void FindAndDeleteServerRequest(OCServerRequest * serverRequest)
325 {
326     OCServerRequest* tmp;
327     if(serverRequest)
328     {
329         LL_FOREACH(serverRequestList, tmp)
330         {
331             if (serverRequest == tmp)
332             {
333                 DeleteServerRequest(tmp);
334                 return;
335             }
336         }
337     }
338 }
339
340 void DeleteServerRequest(OCServerRequest * serverRequest)
341 {
342     if(serverRequest) {
343         LL_DELETE(serverRequestList, serverRequest);
344         OCFree(serverRequest);
345         serverRequest = NULL;
346         OC_LOG(INFO, TAG, PCF("Server Request Removed!!"));
347     }
348 }
349
350 OCStackResult HandleSingleResponse(OCEntityHandlerResponse * ehResponse)
351 {
352 #ifdef CA_INT
353     OCStackResult result = OC_STACK_ERROR;
354     CARemoteEndpoint_t responseEndpoint;
355     CAResponseInfo_t responseInfo;
356     CAHeaderOption_t* optionsPointer;
357
358     OC_LOG_V(INFO, TAG, "Inside HandleSingleResponse: %s", ehResponse->payload);
359
360     OCServerRequest *serverRequest = (OCServerRequest *)ehResponse->requestHandle;
361
362     // Copy the address
363     responseEndpoint.resourceUri      = serverRequest->resourceUrl;
364     responseEndpoint.addressInfo      = serverRequest->addressInfo;
365     responseEndpoint.connectivityType = serverRequest->connectivityType;
366     responseEndpoint.isSecured        = serverRequest->secured;
367
368     // Copy the info
369     switch (ehResponse->ehResult)
370     {
371         case OC_EH_OK:
372             responseInfo.result = CA_SUCCESS;
373             break;
374         case OC_EH_ERROR:
375             responseInfo.result = CA_BAD_REQ;
376             break;
377         case OC_EH_RESOURCE_CREATED:
378             responseInfo.result = CA_CREATED;
379             break;
380         case OC_EH_RESOURCE_DELETED:
381             responseInfo.result = CA_DELETED;
382             break;
383         case OC_EH_SLOW:
384             responseInfo.result = CA_SUCCESS;
385             break;
386         case OC_EH_FORBIDDEN:
387             responseInfo.result = CA_BAD_REQ;
388             break;
389         default:
390             responseInfo.result = CA_BAD_REQ;
391             break;
392     }
393
394     // TODO-CA: Need to do something with a slow response if a confirmed request was sent
395     // from client
396
397     // TODO-CA:  Need to handle CA_MSG_RESET and CA_MSG_ACKNOWLEDGE
398     switch (serverRequest->qos)
399     {
400         case OC_LOW_QOS:
401             responseInfo.info.type = CA_MSG_NONCONFIRM;
402             break;
403         case OC_MEDIUM_QOS:
404             responseInfo.info.type = CA_MSG_NONCONFIRM;
405             break;
406         case OC_HIGH_QOS:
407             responseInfo.info.type = CA_MSG_CONFIRM;
408             break;
409         case OC_NA_QOS:
410             responseInfo.info.type = CA_MSG_NONCONFIRM;
411             break;
412         default:
413             responseInfo.info.type = CA_MSG_NONCONFIRM;
414             break;
415     }
416
417     responseInfo.info.token = serverRequest->token;
418
419     if(serverRequest->observeResult == OC_STACK_OK)
420     {
421         responseInfo.info.numOptions = ehResponse->numSendVendorSpecificHeaderOptions + 1;
422     }
423     else
424     {
425         responseInfo.info.numOptions = ehResponse->numSendVendorSpecificHeaderOptions;
426     }
427
428     responseInfo.info.options = (CAHeaderOption_t *)
429                                     malloc(sizeof(CAHeaderOption_t) * responseInfo.info.numOptions);
430
431     optionsPointer = responseInfo.info.options;
432
433     if(serverRequest->observeResult == OC_STACK_OK)
434     {
435         responseInfo.info.numOptions = ehResponse->numSendVendorSpecificHeaderOptions + 1;
436     }
437
438     // TODO-CA Revisit this logic
439     if(serverRequest->observeResult == OC_STACK_OK)
440     {
441         responseInfo.info.options[0].protocolID = CA_COAP_ID;
442         responseInfo.info.options[0].optionID = COAP_OPTION_OBSERVE;
443         // TODO-CA Remove the magic number 4
444         responseInfo.info.options[0].optionLength = 4;
445         memcpy(responseInfo.info.options[0].optionData, &(serverRequest->observationOption), 4);
446
447         // Point to the next header option before copying vender specific header options
448         optionsPointer += 1;
449     }
450
451     if (ehResponse->numSendVendorSpecificHeaderOptions)
452     {
453         memcpy(optionsPointer, ehResponse->sendVendorSpecificHeaderOptions,
454                         sizeof(OCHeaderOption) * ehResponse->numSendVendorSpecificHeaderOptions);
455     }
456
457     // Allocate memory for the payload.
458     char *payload = (char *)OCMalloc(MAX_RESPONSE_LENGTH);
459     if(!payload)
460     {
461         return OC_STACK_NO_MEMORY;
462     }
463     memset(payload, 0, MAX_RESPONSE_LENGTH);
464     // Put the JSON prefix and suffix around the payload
465     strcpy(payload, (const char *)OC_JSON_PREFIX);
466     strcat(payload, (const char *)ehResponse->payload);
467     strcat(payload, (const char *)OC_JSON_SUFFIX);
468     responseInfo.info.payload = (CAPayload_t)payload;
469
470     CAResult_t caResult = CASendResponse(&responseEndpoint, &responseInfo);
471     if(caResult != CA_STATUS_OK)
472     {
473         OC_LOG(ERROR, TAG, PCF("CASendResponse error"));
474     }
475     else
476     {
477         result = OC_STACK_OK;
478     }
479
480     OCFree(payload);
481     //Delete the request
482     FindAndDeleteServerRequest(serverRequest);
483     return result;
484 #else
485     OCStackResult result = OC_STACK_ERROR;
486     OCServerProtocolResponse protocolResponse;
487     memset(&protocolResponse, 0, sizeof(OCServerProtocolResponse));
488
489     OC_LOG_V(INFO, TAG, "Inside HandleSingleResponse: %s", ehResponse->payload);
490
491     OCServerRequest *serverRequest = (OCServerRequest *)ehResponse->requestHandle;
492     // Format protocol response structure with data needed for
493     // sending the response
494     protocolResponse.qos = serverRequest->qos;
495
496     if((OCResource *)ehResponse->resourceHandle &&
497             ((OCResource *)ehResponse->resourceHandle)->resourceProperties == (OCResourceProperty) 0)
498     {
499         ehResponse->ehResult = OC_EH_RESOURCE_DELETED;
500     }
501     protocolResponse.result = EntityHandlerCodeToOCStackCode(ehResponse->ehResult);
502     protocolResponse.requesterAddr = &serverRequest->requesterAddr;
503     protocolResponse.requestToken = &serverRequest->requestToken;
504     protocolResponse.numSendVendorSpecificHeaderOptions = ehResponse->numSendVendorSpecificHeaderOptions;
505     protocolResponse.sendVendorSpecificHeaderOptions = ehResponse->sendVendorSpecificHeaderOptions;
506     protocolResponse.resourceUri = ehResponse->resourceUri;
507     protocolResponse.delayedResNeeded = serverRequest->delayedResNeeded;
508     protocolResponse.secured = serverRequest->secured;
509     protocolResponse.slowFlag = serverRequest->slowFlag;
510     protocolResponse.notificationFlag = serverRequest->notificationFlag;
511
512     //should we put the prefix and suffix here?
513     protocolResponse.payload = (unsigned char *) OCMalloc(MAX_RESPONSE_LENGTH);
514     if(!protocolResponse.payload)
515     {
516         return OC_STACK_NO_MEMORY;
517     }
518     strcpy((char *)protocolResponse.payload, (const char *)OC_JSON_PREFIX);
519     strcat((char *)protocolResponse.payload, (const char *)ehResponse->payload);
520     strcat((char *)protocolResponse.payload, (const char *)OC_JSON_SUFFIX);
521     protocolResponse.payloadSize = strlen((const char *)protocolResponse.payload) + 1;
522     protocolResponse.resourceUri = ehResponse->resourceUri;
523
524     //revise the following
525     protocolResponse.coapID = serverRequest->coapID;
526     if(serverRequest->observeResult == OC_STACK_OK)
527     {
528         protocolResponse.observationOption = serverRequest->observationOption;
529     }
530     else
531     {
532         protocolResponse.observationOption = OC_OBSERVE_NO_OPTION;
533     }
534     // Make call to OCCoAP layer
535     result = OCDoCoAPResponse(&protocolResponse);
536
537     OCFree(protocolResponse.payload);
538     //Delete the request
539     FindAndDeleteServerRequest(serverRequest);
540     return result;
541 #endif
542 }
543
544 OCStackResult HandleAggregateResponse(OCEntityHandlerResponse * ehResponse)
545 {
546     OCStackResult stackRet = OC_STACK_ERROR;
547     OCServerRequest * serverRequest = NULL;
548     OCServerResponse * serverResponse = NULL;
549
550     OC_LOG_V(INFO, TAG, "Inside HandleAggregateResponse: %s", ehResponse->payload);
551
552     serverRequest = GetServerRequestUsingHandle((OCServerRequest *)ehResponse->requestHandle);
553     serverResponse = GetServerResponseUsingHandle((OCServerRequest *)ehResponse->requestHandle);
554
555     if(serverRequest)
556     {
557         if(!serverResponse)
558         {
559             OC_LOG(INFO, TAG, PCF("This is the first response fragment"));
560             stackRet = AddServerResponse(&serverResponse, ehResponse->requestHandle);
561             if (OC_STACK_OK != stackRet)
562             {
563                 OC_LOG(ERROR, TAG, PCF("Error adding server response"));
564                 return stackRet;
565             }
566             VERIFY_NON_NULL(serverResponse);
567             VERIFY_NON_NULL(serverResponse->payload);
568         }
569
570         if((serverResponse->remainingPayloadSize >= ehResponse->payloadSize + 1 &&
571                 serverRequest->numResponses == 1) ||
572                 (serverResponse->remainingPayloadSize >= ehResponse->payloadSize + 2 &&
573                         serverRequest->numResponses > 1))
574         {
575             OC_LOG(INFO, TAG, PCF("There is room in response buffer"));
576             // append
577             sprintf((char *)serverResponse->payload, "%s%s", (char *)serverResponse->payload, (char *)ehResponse->payload);
578             OC_LOG_V(INFO, TAG, "Current aggregated response  ...%s", serverResponse->payload);
579             serverResponse->remainingPayloadSize -= ehResponse->payloadSize;
580             (serverRequest->numResponses)--;
581             if(serverRequest->numResponses == 0)
582             {
583                 OC_LOG(INFO, TAG, PCF("This is the last response fragment"));
584                 ehResponse->payload = serverResponse->payload;
585                 ehResponse->payloadSize = strlen((char *) serverResponse->payload) + 1;
586                 stackRet = HandleSingleResponse(ehResponse);
587                 //Delete the request and response
588                 FindAndDeleteServerRequest(serverRequest);
589                 FindAndDeleteServerResponse(serverResponse);
590             }
591             else
592             {
593                 OC_LOG(INFO, TAG, PCF("More response fragment to come"));
594                 // TODO: we should consider using strcat rather than setting a char by char here!
595                 sprintf((char *)serverResponse->payload, "%s%c", (char *)serverResponse->payload,OC_JSON_SEPARATOR);
596                 OC_LOG_V(INFO, TAG, "Current aggregated response  ...%s", serverResponse->payload);
597                 (serverResponse->remainingPayloadSize)--;
598                 stackRet = OC_STACK_OK;
599             }
600         }
601         else
602         {
603             OC_LOG(INFO, TAG, PCF("No room in response buffer"));
604             //Delete the request and response
605             FindAndDeleteServerRequest(serverRequest);
606             FindAndDeleteServerResponse(serverResponse);
607             stackRet = OC_STACK_NO_MEMORY;
608         }
609     }
610 exit:
611     return stackRet;
612 }