1 /* ****************************************************************
3 * Copyright 2015 Samsung Electronics All Rights Reserved.
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 ******************************************************************/
21 #include "oickeepalive.h"
25 #include "oic_malloc.h"
26 #include "oic_string.h"
29 #include "uarraylist.h"
30 #include "ocstackinternal.h"
31 #include "ocpayloadcbor.h"
32 #include "ocpayload.h"
33 #include "ocresourcehandler.h"
37 * Logging tag for module name.
39 #define TAG "OIC_RI_KEEPALIVE"
41 static const uint64_t USECS_PER_SEC = 1000000;
43 //-----------------------------------------------------------------------------
45 //-----------------------------------------------------------------------------
46 #define VERIFY_SUCCESS(op, successCode) { if ((op) != (successCode)) \
47 {OIC_LOG_V(FATAL, TAG, "%s failed!!", #op); goto exit;} }
49 #define VERIFY_NON_NULL(arg, logLevel, retVal) { if (!(arg)) { OIC_LOG((logLevel), \
50 TAG, #arg " is NULL"); return (retVal); } }
52 #define VERIFY_NON_NULL_NR(arg, logLevel) { if (!(arg)) { OIC_LOG((logLevel), \
53 TAG, #arg " is NULL"); return; } }
55 #define VERIFY_NON_NULL_V(arg) { if (!arg) {OIC_LOG_V(FATAL, TAG, "%s is NULL", #arg);\
59 * The KeepAlive table entries are removed
60 * if it can't receive response message within 60 seconds.
62 #define KEEPALIVE_RESPONSE_TIMEOUT_SEC 60
65 * The Min time interval value. (2 minutes)
66 * start from 2 minutes and increases in multiples of 2 up to a maximum of 64minutes.
68 #define KEEPALIVE_MIN_INTERVAL 2
71 * The Max time interval value. (64 minutes)
73 #define KEEPALIVE_MAX_INTERVAL 64
76 * Default counts of interval value.
78 #define DEFAULT_INTERVAL_COUNT 6
81 * KeepAlive key to parser Payload Table.
83 static const char INTERVAL[] = "in";
86 * KeepAlive key to get interval values from Payload Table.
88 static const char INTERVAL_ARRAY[] = "inarray";
91 * To check if KeepAlive is initialized.
93 static bool g_isKeepAliveInitialized = false;
96 * Pointer to handle of the newly created KeepAlive resource.
98 static OCResourceHandle g_keepAliveHandle = NULL;
101 * KeepAlive table which holds connection interval.
103 static u_arraylist_t *g_keepAliveConnectionTable = NULL;
106 * KeepAlive table entries.
110 OCMode mode; /**< host Mode of Operation. */
111 CAEndpoint_t remoteAddr; /**< destination Address. */
112 uint32_t interval; /**< time interval for KeepAlive. in seconds.*/
113 int32_t currIndex; /**< current interval value index. */
114 size_t intervalSize; /**< total interval counts. */
115 int64_t *intervalInfo; /**< interval values for KeepAlive. */
116 bool sentPingMsg; /**< if oic client already sent ping message. */
117 uint64_t timeStamp; /**< last sent or received ping message. in microseconds. */
121 * Send disconnect message to remove connection.
123 static OCStackResult SendDisconnectMessage(const KeepAliveEntry_t *entry);
126 * Send ping message to remote endpoint.
128 static OCStackResult SendPingMessage(KeepAliveEntry_t *entry);
131 * Increase interval value to send next ping message.
133 static void IncreaseInterval(KeepAliveEntry_t *entry);
136 * Ping Message callback registered with RI for KeepAlive Request.
138 static OCStackApplicationResult PingRequestCallback(void* ctx, OCDoHandle handle,
139 OCClientResponse * clientResponse);
142 * This function creates KeepAlive resource.
143 * @return ::OC_STACK_OK or Appropriate error code.
145 static OCStackResult CreateKeepAliveResource();
148 * This function deletes KeepAlive resource.
149 * @return ::OC_STACK_OK or Appropriate error code.
151 static OCStackResult DeleteKeepAliveResource();
154 * API to handle the GET request received for a KeepAlive resource.
155 * @param[in] endPoint RemoteEndpoint which sent the packet.
156 * @param[in] requestInfo Received coap packet.
157 * @return ::OC_STACK_OK or Appropriate error code.
159 static OCStackResult HandleKeepAliveGETRequest(const CAEndpoint_t* endPoint,
160 const CARequestInfo_t* requestInfo);
163 * API to handle the PUT request received for a KeepAlive resource.
164 * @param[in] endPoint RemoteEndpoint which sent the packet.
165 * @param[in] requestInfo Received coap packet.
166 * @return ::OC_STACK_OK or Appropriate error code.
168 static OCStackResult HandleKeepAlivePUTRequest(const CAEndpoint_t* endPoint,
169 const CARequestInfo_t* requestInfo);
172 * API to handle the Response payload.
173 * @param[in] endpoint RemoteEndpoint which sent the packet.
174 * @param[in] responseCode Received reseponse code.
175 * @param[in] respPayload Response payload.
176 * @return ::OC_STACK_OK or Appropriate error code.
178 OCStackResult HandleKeepAliveResponse(const CAEndpoint_t *endPoint,
179 OCStackResult responseCode,
180 const OCRepPayload *respPayload);
182 * Gets keepalive entry.
183 * @param[in] endpoint Remote Endpoint information (like ipaddress,
184 * port, reference uri and transport type) to
185 * which the ping message has to be sent.
186 * @param[out] index index of array list.
187 * @return KeepAlive entry to send ping message.
189 static KeepAliveEntry_t *GetEntryFromEndpoint(const CAEndpoint_t *endpoint, uint32_t *index);
192 * Add keepalive entry.
193 * @param[in] endpoint Remote Endpoint information (like ipaddress,
194 * port, reference uri and transport type).
195 * @param[in] mode Whether it is OIC Server or OIC Client.
196 * @param[in] intervalArray Received interval values from cloud server.
197 * @return The KeepAlive entry added in KeepAlive Table.
199 KeepAliveEntry_t *AddKeepAliveEntry(const CAEndpoint_t *endpoint, OCMode mode,
200 int64_t *intervalArray);
203 * Remove keepalive entry.
204 * @param[in] endpoint Remote Endpoint information (like ipaddress,
205 * port, reference uri and transport type).
206 * @return The KeepAlive entry removed in KeepAlive Table.
208 static OCStackResult RemoveKeepAliveEntry(const CAEndpoint_t *endpoint);
210 OCStackResult InitializeKeepAlive(OCMode mode)
212 OIC_LOG(DEBUG, TAG, "InitializeKeepAlive IN");
213 if (g_isKeepAliveInitialized)
215 OIC_LOG(DEBUG, TAG, "KeepAlive already initialized");
219 if (OC_CLIENT != mode)
221 // Create the KeepAlive Resource[/oic/ping].
222 OCStackResult result = CreateKeepAliveResource();
223 if (OC_STACK_OK != result)
225 OIC_LOG_V(ERROR, TAG, "CreateKeepAliveResource failed[%d]", result);
230 if (!g_keepAliveConnectionTable)
232 g_keepAliveConnectionTable = u_arraylist_create();
233 if (NULL == g_keepAliveConnectionTable)
235 OIC_LOG(ERROR, TAG, "Creating KeepAlive Table failed");
236 TerminateKeepAlive(mode);
237 return OC_STACK_ERROR;
241 g_isKeepAliveInitialized = true;
243 OIC_LOG(DEBUG, TAG, "InitializeKeepAlive OUT");
247 OCStackResult TerminateKeepAlive(OCMode mode)
249 OIC_LOG(DEBUG, TAG, "TerminateKeepAlive IN");
250 if (!g_isKeepAliveInitialized)
252 OIC_LOG(ERROR, TAG, "KeepAlive not initialized");
253 return OC_STACK_ERROR;
256 if (OC_CLIENT != mode)
258 // Delete the KeepAlive Resource[/oic/ping].
259 OCStackResult result = DeleteKeepAliveResource();
260 if (OC_STACK_OK != result)
262 OIC_LOG_V(ERROR, TAG, "DeleteKeepAliveResource failed[%d]", result);
267 if (NULL != g_keepAliveConnectionTable)
269 u_arraylist_destroy(g_keepAliveConnectionTable);
270 g_keepAliveConnectionTable = NULL;
273 g_isKeepAliveInitialized = false;
275 OIC_LOG(DEBUG, TAG, "TerminateKeepAlive OUT");
279 OCStackResult CreateKeepAliveResource()
281 OIC_LOG(DEBUG, TAG, "InitKeepAliveResource IN");
283 // Create a KeepAlive resource
284 OCStackResult result = OCCreateResource(&g_keepAliveHandle,
285 KEEPALIVE_RESOURCE_TYPE_NAME,
286 KEEPALIVE_RESOURCE_INTF_NAME,
287 KEEPALIVE_RESOURCE_URI,
292 if (OC_STACK_OK != result)
294 OIC_LOG_V(ERROR, TAG, "Create resource for KeepAlive failed[%d]", result);
297 OIC_LOG(DEBUG, TAG, "InitKeepAliveResource OUT");
301 OCStackResult DeleteKeepAliveResource()
303 OIC_LOG(DEBUG, TAG, "DeleteKeepAliveResource IN");
305 // Create a KeepAlive resource
306 OCStackResult result = OCDeleteResource(g_keepAliveHandle);
308 if (OC_STACK_OK != result)
310 OIC_LOG_V(ERROR, TAG, "Delete resource for KeepAlive failed[%d]", result);
313 OIC_LOG(DEBUG, TAG, "DeleteKeepAliveResource OUT");
317 OCStackResult HandleKeepAliveRequest(const CAEndpoint_t* endPoint,
318 const CARequestInfo_t* requestInfo)
320 VERIFY_NON_NULL(endPoint, FATAL, OC_STACK_INVALID_PARAM);
321 VERIFY_NON_NULL(requestInfo, FATAL, OC_STACK_INVALID_PARAM);
323 OIC_LOG(DEBUG, TAG, "HandleKeepAliveRequest IN");
325 OCStackResult result = OC_STACK_OK;
326 if (CA_PUT == requestInfo->method)
328 result = HandleKeepAlivePUTRequest(endPoint, requestInfo);
330 else if (CA_GET == requestInfo->method)
332 result = HandleKeepAliveGETRequest(endPoint, requestInfo);
335 OIC_LOG(DEBUG, TAG, "HandleKeepAliveRequest OUT");
339 OCStackResult HandleKeepAliveGETRequest(const CAEndpoint_t* endPoint,
340 const CARequestInfo_t* requestInfo)
342 VERIFY_NON_NULL(endPoint, FATAL, OC_STACK_INVALID_PARAM);
343 VERIFY_NON_NULL(requestInfo, FATAL, OC_STACK_INVALID_PARAM);
345 OIC_LOG_V(DEBUG, TAG, "Find Ping resource [%s]", requestInfo->info.resourceUri);
347 CAResponseResult_t result = CA_CONTENT;
348 OCResource *resourcePtr = FindResourceByUri(requestInfo->info.resourceUri);
351 // Resource URL not specified
352 OIC_LOG_V(DEBUG, TAG, "There is no Ping resource [%s]", requestInfo->info.resourceUri);
353 result = CA_NOT_FOUND;
356 SendDirectStackResponse(endPoint, requestInfo->info.messageId, result, requestInfo->info.type,
357 requestInfo->info.numOptions, requestInfo->info.options,
358 requestInfo->info.token, requestInfo->info.tokenLength,
359 requestInfo->info.resourceUri, CA_RESPONSE_DATA);
364 OCStackResult HandleKeepAlivePUTRequest(const CAEndpoint_t* endPoint,
365 const CARequestInfo_t* requestInfo)
367 VERIFY_NON_NULL(endPoint, FATAL, OC_STACK_INVALID_PARAM);
368 VERIFY_NON_NULL(requestInfo, FATAL, OC_STACK_INVALID_PARAM);
370 // Get entry from KeepAlive table.
372 KeepAliveEntry_t *entry = GetEntryFromEndpoint(endPoint, &index);
375 OIC_LOG(ERROR, TAG, "Received the first keepalive message from client");
376 entry = AddKeepAliveEntry(endPoint, OC_SERVER, NULL);
379 OIC_LOG(ERROR, TAG, "Failed to add new keepalive entry");
380 return OC_STACK_ERROR;
384 OCPayload *ocPayload = NULL;
385 OCParsePayload(&ocPayload, PAYLOAD_TYPE_REPRESENTATION,
386 requestInfo->info.payload, requestInfo->info.payloadSize);
387 OCRepPayload *repPayload = (OCRepPayload *)ocPayload;
389 int64_t interval = 0;
390 OCRepPayloadGetPropInt(repPayload, INTERVAL, &interval);
391 entry->interval = interval;
392 OIC_LOG_V(DEBUG, TAG, "Received interval is [%d]", entry->interval);
393 entry->timeStamp = OICGetCurrentTime(TIME_IN_US);
395 OCPayloadDestroy(ocPayload);
397 // Send response message.
398 return SendDirectStackResponse(endPoint, requestInfo->info.messageId, CA_CHANGED,
399 requestInfo->info.type, requestInfo->info.numOptions,
400 requestInfo->info.options, requestInfo->info.token,
401 requestInfo->info.tokenLength, requestInfo->info.resourceUri,
405 OCStackResult HandleKeepAliveResponse(const CAEndpoint_t *endPoint,
406 OCStackResult responseCode,
407 const OCRepPayload *respPayload)
409 VERIFY_NON_NULL(endPoint, FATAL, OC_STACK_INVALID_PARAM);
411 OIC_LOG(DEBUG, TAG, "HandleKeepAliveResponse IN");
413 // Get entry from KeepAlive table.
415 KeepAliveEntry_t *entry = GetEntryFromEndpoint(endPoint, &index);
418 // Receive response message about find /oic/ping request.
419 OIC_LOG(ERROR, TAG, "There is no connection info in KeepAlive table");
421 if (OC_STACK_NO_RESOURCE == responseCode)
423 OIC_LOG(ERROR, TAG, "Server doesn't have a ping resource");
424 return OC_STACK_ERROR;
426 else if (OC_STACK_OK == responseCode)
428 int64_t *recvInterval = NULL;
429 size_t dimensions[MAX_REP_ARRAY_DEPTH] = { 0 };
430 OCRepPayloadGetIntArray(respPayload, INTERVAL_ARRAY, &recvInterval, dimensions);
431 size_t serverIntervalSize = calcDimTotal(dimensions);
433 entry = AddKeepAliveEntry(endPoint, OC_CLIENT, recvInterval);
436 OIC_LOG(ERROR, TAG, "Failed to add new KeepAlive entry");
437 return OC_STACK_ERROR;
440 if (serverIntervalSize)
442 // update interval size with received size of server.
443 entry->intervalSize = serverIntervalSize;
446 // Send first ping message
447 return SendPingMessage(entry);
452 // Set sentPingMsg values with false.
453 entry->sentPingMsg = false;
456 OIC_LOG(DEBUG, TAG, "HandleKeepAliveResponse OUT");
460 void ProcessKeepAlive()
462 if (!g_isKeepAliveInitialized)
464 OIC_LOG(ERROR, TAG, "KeepAlive not initialized");
468 uint32_t len = u_arraylist_length(g_keepAliveConnectionTable);
470 for (uint32_t i = 0; i < len; i++)
472 KeepAliveEntry_t *entry = (KeepAliveEntry_t *)u_arraylist_get(g_keepAliveConnectionTable,
479 uint64_t currentTime = OICGetCurrentTime(TIME_IN_US);
480 if (OC_CLIENT == entry->mode)
482 if (entry->sentPingMsg)
485 * If an OIC Client does not receive the response within 1 minutes,
486 * terminate the connection.
487 * In this case the timeStamp means last time sent ping message.
489 if ((KEEPALIVE_RESPONSE_TIMEOUT_SEC * USECS_PER_SEC) <= currentTime - entry->timeStamp)
491 OIC_LOG(DEBUG, TAG, "Client does not receive the response within 1 minutes.");
493 // Send message to disconnect session.
494 SendDisconnectMessage(entry);
499 if ((entry->interval * KEEPALIVE_RESPONSE_TIMEOUT_SEC * USECS_PER_SEC)
500 <= currentTime - entry->timeStamp)
502 // Increase interval value.
503 IncreaseInterval(entry);
505 OCStackResult result = SendPingMessage(entry);
506 if (OC_STACK_OK != result)
508 OIC_LOG(ERROR, TAG, "Failed to send ping request");
514 else if (OC_SERVER == entry->mode)
517 * If an OIC Server does not receive a PUT request to ping resource
518 * within the specified interval time, terminate the connection.
519 * In this case the timeStamp means last time received ping message.
521 if ((entry->interval * KEEPALIVE_RESPONSE_TIMEOUT_SEC * USECS_PER_SEC)
522 <= currentTime - entry->timeStamp)
524 OIC_LOG(DEBUG, TAG, "Server does not receive a PUT request.");
525 SendDisconnectMessage(entry);
531 void IncreaseInterval(KeepAliveEntry_t *entry)
533 VERIFY_NON_NULL_NR(entry, FATAL);
535 OIC_LOG_V(DEBUG, TAG, "Total interval counts: %zu", entry->intervalSize);
536 if (entry->intervalSize > (size_t)entry->currIndex + 1)
539 entry->interval = entry->intervalInfo[entry->currIndex];
540 OIC_LOG_V(DEBUG, TAG, "increase interval value [%d]", entry->interval);
544 OCStackResult SendDisconnectMessage(const KeepAliveEntry_t *entry)
546 VERIFY_NON_NULL(entry, FATAL, OC_STACK_INVALID_PARAM);
549 * Send empty message to disconnect a connection.
550 * If CA get the empty message from RI, CA will disconnect a connection.
553 OCStackResult result = RemoveKeepAliveEntry(&entry->remoteAddr);
554 if (result != OC_STACK_OK)
559 CARequestInfo_t requestInfo = { .method = CA_PUT };
560 result = CASendRequest(&entry->remoteAddr, &requestInfo);
561 return CAResultToOCResult(result);
564 OCStackResult SendPingMessage(KeepAliveEntry_t *entry)
566 VERIFY_NON_NULL(entry, FATAL, OC_STACK_INVALID_PARAM);
568 // Send ping message.
569 OCCallbackData pingData = { .context = NULL, .cb = PingRequestCallback };
570 OCDevAddr devAddr = { .adapter = OC_ADAPTER_TCP };
571 CopyEndpointToDevAddr(&(entry->remoteAddr), &devAddr);
573 OCRepPayload *payload = OCRepPayloadCreate();
576 OIC_LOG(ERROR, TAG, "Failed to allocate Payload");
577 return OC_STACK_ERROR;
579 payload->base.type = PAYLOAD_TYPE_REPRESENTATION;
580 OCRepPayloadSetPropInt(payload, INTERVAL, entry->interval);
582 OCStackResult result = OCDoResource(NULL, OC_REST_PUT, KEEPALIVE_RESOURCE_URI, &devAddr,
583 (OCPayload *) payload, CT_ADAPTER_TCP, OC_LOW_QOS,
585 if (OC_STACK_OK != result)
587 OIC_LOG(ERROR, TAG, "OCDoResource has failed");
591 // Update timeStamp with time sent ping message for next ping message.
592 entry->timeStamp = OICGetCurrentTime(TIME_IN_US);
593 entry->sentPingMsg = true;
595 OIC_LOG_V(DEBUG, TAG, "Client sent ping message, interval [%d]", entry->interval);
600 OCStackApplicationResult PingRequestCallback(void* ctx, OCDoHandle handle,
601 OCClientResponse *clientResponse)
603 OIC_LOG(DEBUG, TAG, "PingRequestCallback IN");
606 if (NULL == clientResponse)
608 OIC_LOG(ERROR, TAG, "clientResponse is NULL");
609 return OC_STACK_KEEP_TRANSACTION;
612 CAEndpoint_t endpoint = { .adapter = CA_ADAPTER_TCP };
613 CopyDevAddrToEndpoint(&(clientResponse->devAddr), &endpoint);
615 HandleKeepAliveResponse(&endpoint, clientResponse->result,
616 (OCRepPayload *)clientResponse->payload);
618 OIC_LOG(DEBUG, TAG, "PingRequestCallback OUT");
619 return OC_STACK_KEEP_TRANSACTION;
622 KeepAliveEntry_t *GetEntryFromEndpoint(const CAEndpoint_t *endpoint, uint32_t *index)
624 if (!g_keepAliveConnectionTable)
626 OIC_LOG(ERROR, TAG, "KeepAlive Table was not Created.");
630 uint32_t len = u_arraylist_length(g_keepAliveConnectionTable);
632 for (uint32_t i = 0; i < len; i++)
634 KeepAliveEntry_t *entry = (KeepAliveEntry_t *)u_arraylist_get(g_keepAliveConnectionTable,
641 if (!strncmp(entry->remoteAddr.addr, endpoint->addr, sizeof(entry->remoteAddr.addr))
642 && (entry->remoteAddr.port == endpoint->port))
644 OIC_LOG(DEBUG, TAG, "Connection Info found in KeepAlive table");
653 KeepAliveEntry_t *AddKeepAliveEntry(const CAEndpoint_t *endpoint, OCMode mode,
654 int64_t *intervalInfo)
658 OIC_LOG(ERROR, TAG, "endpoint is NULL");
662 if (!g_keepAliveConnectionTable)
664 OIC_LOG(ERROR, TAG, "KeepAlive Table was not Created.");
668 KeepAliveEntry_t *entry = (KeepAliveEntry_t *) OICCalloc(1, sizeof(KeepAliveEntry_t));
671 OIC_LOG(ERROR, TAG, "Failed to Calloc KeepAlive Entry");
676 entry->timeStamp = OICGetCurrentTime(TIME_IN_US);
677 entry->remoteAddr.adapter = endpoint->adapter;
678 entry->remoteAddr.flags = endpoint->flags;
679 entry->remoteAddr.ifindex = endpoint->ifindex;
680 entry->remoteAddr.port = endpoint->port;
681 strncpy(entry->remoteAddr.addr, endpoint->addr, sizeof(entry->remoteAddr.addr));
683 entry->intervalSize = DEFAULT_INTERVAL_COUNT;
684 entry->intervalInfo = intervalInfo;
685 if (!entry->intervalInfo)
687 entry->intervalInfo = (int64_t*) OICMalloc(entry->intervalSize * sizeof(int64_t));
688 for (size_t i = 0; i < entry->intervalSize; i++)
690 entry->intervalInfo[i] = KEEPALIVE_MIN_INTERVAL << i;
693 entry->interval = entry->intervalInfo[0];
695 bool result = u_arraylist_add(g_keepAliveConnectionTable, (void *)entry);
698 OIC_LOG(ERROR, TAG, "Adding node to head failed");
699 OICFree(entry->intervalInfo);
707 OCStackResult RemoveKeepAliveEntry(const CAEndpoint_t *endpoint)
709 VERIFY_NON_NULL(endpoint, FATAL, OC_STACK_INVALID_PARAM);
712 KeepAliveEntry_t *entry = GetEntryFromEndpoint(endpoint, &index);
715 OIC_LOG(ERROR, TAG, "There is no entry in keepalive table.");
716 return OC_STACK_ERROR;
719 KeepAliveEntry_t *removedEntry = (KeepAliveEntry_t *)
720 u_arraylist_remove(g_keepAliveConnectionTable, index);
721 if (NULL == removedEntry)
723 OIC_LOG(ERROR, TAG, "Removed Entry is NULL");
724 return OC_STACK_ERROR;
727 OIC_LOG_V(DEBUG, TAG, "Remove Connection Info from KeepAlive table, "
728 "remote addr=%s port:%d", removedEntry->remoteAddr.addr,
729 removedEntry->remoteAddr.port);
731 OICFree(entry->intervalInfo);
732 OICFree(removedEntry);
737 void HandleKeepAliveConnCB(const CAEndpoint_t *endpoint, bool isConnected)
739 VERIFY_NON_NULL_NR(endpoint, FATAL);
743 OIC_LOG(DEBUG, TAG, "Received the connected device information from CA");
745 // Send discover message to find ping resource
746 OCCallbackData pingData = {.context = NULL, .cb = PingRequestCallback };
747 OCDevAddr devAddr = { .adapter = OC_ADAPTER_TCP };
748 CopyEndpointToDevAddr(endpoint, &devAddr);
750 OCStackResult result = OCDoResource(NULL, OC_REST_DISCOVER, KEEPALIVE_RESOURCE_URI,
751 &devAddr, NULL, CT_ADAPTER_TCP, OC_HIGH_QOS,
753 if (OC_STACK_OK != result)
755 OIC_LOG(ERROR, TAG, "OCDoResource has failed");
761 OIC_LOG(DEBUG, TAG, "Received the disconnected device information from CA");
763 OCStackResult result = RemoveKeepAliveEntry(endpoint);
764 if(result != OC_STACK_OK)