[CA-Integration] Fix Get working
[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, sizeof(serverRequest->token) - 1);
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
367     // Copy the info
368     switch (ehResponse->ehResult)
369     {
370         case OC_EH_OK:
371             responseInfo.result = CA_SUCCESS;
372             break;
373         case OC_EH_ERROR:
374             responseInfo.result = CA_BAD_REQ;
375             break;
376         case OC_EH_RESOURCE_CREATED:
377             responseInfo.result = CA_CREATED;
378             break;
379         case OC_EH_RESOURCE_DELETED:
380             responseInfo.result = CA_DELETED;
381             break;
382         case OC_EH_SLOW:
383             responseInfo.result = CA_SUCCESS;
384             break;
385         case OC_EH_FORBIDDEN:
386             responseInfo.result = CA_BAD_REQ;
387             break;
388         default:
389             responseInfo.result = CA_BAD_REQ;
390             break;
391     }
392
393     // TODO-CA: Need to do something with a slow response if a confirmed request was sent
394     // from client
395
396     // TODO-CA:  Need to handle CA_MSG_RESET and CA_MSG_ACKNOWLEDGE
397     switch (serverRequest->qos)
398     {
399         case OC_LOW_QOS:
400             responseInfo.info.type = CA_MSG_NONCONFIRM;
401             break;
402         case OC_MEDIUM_QOS:
403             responseInfo.info.type = CA_MSG_NONCONFIRM;
404             break;
405         case OC_HIGH_QOS:
406             responseInfo.info.type = CA_MSG_CONFIRM;
407             break;
408         case OC_NA_QOS:
409             responseInfo.info.type = CA_MSG_NONCONFIRM;
410             break;
411         default:
412             responseInfo.info.type = CA_MSG_NONCONFIRM;
413             break;
414     }
415
416     responseInfo.info.token = serverRequest->token;
417
418     if(serverRequest->observeResult == OC_STACK_OK)
419     {
420         responseInfo.info.numOptions = ehResponse->numSendVendorSpecificHeaderOptions + 1;
421     }
422     else
423     {
424         responseInfo.info.numOptions = ehResponse->numSendVendorSpecificHeaderOptions;
425     }
426
427     responseInfo.info.options = (CAHeaderOption_t *)
428                                     malloc(sizeof(CAHeaderOption_t) * responseInfo.info.numOptions);
429
430     optionsPointer = responseInfo.info.options;
431
432     if(serverRequest->observeResult == OC_STACK_OK)
433     {
434         responseInfo.info.numOptions = ehResponse->numSendVendorSpecificHeaderOptions + 1;
435     }
436
437     // TODO-CA Revisit this logic
438     if(serverRequest->observeResult == OC_STACK_OK)
439     {
440         responseInfo.info.options[0].protocolID = CA_COAP_ID;
441         responseInfo.info.options[0].optionID = COAP_OPTION_OBSERVE;
442         // TODO-CA Remove the magic number 4
443         responseInfo.info.options[0].optionLength = 4;
444         memcpy(responseInfo.info.options[0].optionData, &(serverRequest->observationOption), 4);
445
446         // Point to the next header option before copying vender specific header options
447         optionsPointer += 1;
448     }
449
450     if (ehResponse->numSendVendorSpecificHeaderOptions)
451     {
452         memcpy(optionsPointer, ehResponse->sendVendorSpecificHeaderOptions,
453                         sizeof(OCHeaderOption) * ehResponse->numSendVendorSpecificHeaderOptions);
454     }
455
456     // Allocate memory for the payload.
457     char *payload = (char *)OCMalloc(MAX_RESPONSE_LENGTH);
458     if(!payload)
459     {
460         return OC_STACK_NO_MEMORY;
461     }
462     memset(payload, 0, MAX_RESPONSE_LENGTH);
463     // Put the JSON prefix and suffix around the payload
464     strcpy(payload, (const char *)OC_JSON_PREFIX);
465     strcat(payload, (const char *)ehResponse->payload);
466     strcat(payload, (const char *)OC_JSON_SUFFIX);
467     responseInfo.info.payload = (CAPayload_t)payload;
468
469     CAResult_t caResult = CASendResponse(&responseEndpoint, &responseInfo);
470     if(caResult != CA_STATUS_OK)
471     {
472         OC_LOG(ERROR, TAG, PCF("CASendResponse error"));
473     }
474     else
475     {
476         result = OC_STACK_OK;
477     }
478
479     OCFree(payload);
480     //Delete the request
481     FindAndDeleteServerRequest(serverRequest);
482     return result;
483 #else
484     OCStackResult result = OC_STACK_ERROR;
485     OCServerProtocolResponse protocolResponse;
486     memset(&protocolResponse, 0, sizeof(OCServerProtocolResponse));
487
488     OC_LOG_V(INFO, TAG, "Inside HandleSingleResponse: %s", ehResponse->payload);
489
490     OCServerRequest *serverRequest = (OCServerRequest *)ehResponse->requestHandle;
491     // Format protocol response structure with data needed for
492     // sending the response
493     protocolResponse.qos = serverRequest->qos;
494
495     if((OCResource *)ehResponse->resourceHandle &&
496             ((OCResource *)ehResponse->resourceHandle)->resourceProperties == (OCResourceProperty) 0)
497     {
498         ehResponse->ehResult = OC_EH_RESOURCE_DELETED;
499     }
500     protocolResponse.result = EntityHandlerCodeToOCStackCode(ehResponse->ehResult);
501     protocolResponse.requesterAddr = &serverRequest->requesterAddr;
502     protocolResponse.requestToken = &serverRequest->requestToken;
503     protocolResponse.numSendVendorSpecificHeaderOptions = ehResponse->numSendVendorSpecificHeaderOptions;
504     protocolResponse.sendVendorSpecificHeaderOptions = ehResponse->sendVendorSpecificHeaderOptions;
505     protocolResponse.resourceUri = ehResponse->resourceUri;
506     protocolResponse.delayedResNeeded = serverRequest->delayedResNeeded;
507     protocolResponse.secured = serverRequest->secured;
508     protocolResponse.slowFlag = serverRequest->slowFlag;
509     protocolResponse.notificationFlag = serverRequest->notificationFlag;
510
511     //should we put the prefix and suffix here?
512     protocolResponse.payload = (unsigned char *) OCMalloc(MAX_RESPONSE_LENGTH);
513     if(!protocolResponse.payload)
514     {
515         return OC_STACK_NO_MEMORY;
516     }
517     strcpy((char *)protocolResponse.payload, (const char *)OC_JSON_PREFIX);
518     strcat((char *)protocolResponse.payload, (const char *)ehResponse->payload);
519     strcat((char *)protocolResponse.payload, (const char *)OC_JSON_SUFFIX);
520     protocolResponse.payloadSize = strlen((const char *)protocolResponse.payload) + 1;
521     protocolResponse.resourceUri = ehResponse->resourceUri;
522
523     //revise the following
524     protocolResponse.coapID = serverRequest->coapID;
525     if(serverRequest->observeResult == OC_STACK_OK)
526     {
527         protocolResponse.observationOption = serverRequest->observationOption;
528     }
529     else
530     {
531         protocolResponse.observationOption = OC_OBSERVE_NO_OPTION;
532     }
533     // Make call to OCCoAP layer
534     result = OCDoCoAPResponse(&protocolResponse);
535
536     OCFree(protocolResponse.payload);
537     //Delete the request
538     FindAndDeleteServerRequest(serverRequest);
539     return result;
540 #endif
541 }
542
543 OCStackResult HandleAggregateResponse(OCEntityHandlerResponse * ehResponse)
544 {
545     OCStackResult stackRet = OC_STACK_ERROR;
546     OCServerRequest * serverRequest = NULL;
547     OCServerResponse * serverResponse = NULL;
548
549     OC_LOG_V(INFO, TAG, "Inside HandleAggregateResponse: %s", ehResponse->payload);
550
551     serverRequest = GetServerRequestUsingHandle((OCServerRequest *)ehResponse->requestHandle);
552     serverResponse = GetServerResponseUsingHandle((OCServerRequest *)ehResponse->requestHandle);
553
554     if(serverRequest)
555     {
556         if(!serverResponse)
557         {
558             OC_LOG(INFO, TAG, PCF("This is the first response fragment"));
559             stackRet = AddServerResponse(&serverResponse, ehResponse->requestHandle);
560             if (OC_STACK_OK != stackRet)
561             {
562                 OC_LOG(ERROR, TAG, PCF("Error adding server response"));
563                 return stackRet;
564             }
565             VERIFY_NON_NULL(serverResponse);
566             VERIFY_NON_NULL(serverResponse->payload);
567         }
568
569         if((serverResponse->remainingPayloadSize >= ehResponse->payloadSize + 1 &&
570                 serverRequest->numResponses == 1) ||
571                 (serverResponse->remainingPayloadSize >= ehResponse->payloadSize + 2 &&
572                         serverRequest->numResponses > 1))
573         {
574             OC_LOG(INFO, TAG, PCF("There is room in response buffer"));
575             // append
576             sprintf((char *)serverResponse->payload, "%s%s", (char *)serverResponse->payload, (char *)ehResponse->payload);
577             OC_LOG_V(INFO, TAG, "Current aggregated response  ...%s", serverResponse->payload);
578             serverResponse->remainingPayloadSize -= ehResponse->payloadSize;
579             (serverRequest->numResponses)--;
580             if(serverRequest->numResponses == 0)
581             {
582                 OC_LOG(INFO, TAG, PCF("This is the last response fragment"));
583                 ehResponse->payload = serverResponse->payload;
584                 ehResponse->payloadSize = strlen((char *) serverResponse->payload) + 1;
585                 stackRet = HandleSingleResponse(ehResponse);
586                 //Delete the request and response
587                 FindAndDeleteServerRequest(serverRequest);
588                 FindAndDeleteServerResponse(serverResponse);
589             }
590             else
591             {
592                 OC_LOG(INFO, TAG, PCF("More response fragment to come"));
593                 // TODO: we should consider using strcat rather than setting a char by char here!
594                 sprintf((char *)serverResponse->payload, "%s%c", (char *)serverResponse->payload,OC_JSON_SEPARATOR);
595                 OC_LOG_V(INFO, TAG, "Current aggregated response  ...%s", serverResponse->payload);
596                 (serverResponse->remainingPayloadSize)--;
597                 stackRet = OC_STACK_OK;
598             }
599         }
600         else
601         {
602             OC_LOG(INFO, TAG, PCF("No room in response buffer"));
603             //Delete the request and response
604             FindAndDeleteServerRequest(serverRequest);
605             FindAndDeleteServerResponse(serverResponse);
606             stackRet = OC_STACK_NO_MEMORY;
607         }
608     }
609 exit:
610     return stackRet;
611 }