1 //******************************************************************
3 // Copyright 2014 Intel Mobile Communications GmbH All Rights Reserved.
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
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 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
22 //=============================================================================
24 //=============================================================================
26 #include "ocstackconfig.h"
27 #include "occlientcb.h"
28 #include "ocobserve.h"
39 //=============================================================================
41 //=============================================================================
42 #define TAG PCF("OCCoAP")
43 #define VERIFY_SUCCESS(op, successCode) { if (op != successCode) \
44 {OC_LOG_V(FATAL, TAG, "%s failed!!", #op); goto exit;} }
45 #define VERIFY_NON_NULL(arg) { if (!arg) {OC_LOG_V(FATAL, TAG, "%s is NULL", #arg); goto exit;} }
47 //=============================================================================
49 //=============================================================================
50 #define COAP_BLOCK_FILL_VALUE (0xFF)
52 //=============================================================================
54 //=============================================================================
56 static uint8_t coapWKIpAddr[] = { 224, 0, 1, 187 };
57 static coap_context_t *gCoAPCtx = NULL;
59 //=============================================================================
61 //=============================================================================
63 //generate a coap token
64 void OCGenerateCoAPToken(OCCoAPToken * token)
68 token->tokenLength = MAX_TOKEN_LENGTH;
69 OCFillRandomMem((uint8_t*)token->token, token->tokenLength);
73 //This function is called back by libcoap when ack or rst are received
74 static void HandleCoAPAckRst(struct coap_context_t * ctx, uint8_t msgType,
75 const coap_queue_t * sentQueue){
79 coap_pdu_t * sentPdu = sentQueue->pdu;
80 OCStackResult result = OC_STACK_ERROR;
81 uint32_t observationOption = OC_OBSERVE_NO_OPTION;
82 // {{0}} to eliminate warning for known compiler bug 53119
83 // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53119
84 OCCoAPToken sentToken = {{0}};
86 result = ParseCoAPPdu(sentPdu, NULL, NULL, &observationOption, NULL, NULL, NULL,
87 NULL, NULL, NULL, NULL, NULL);
88 VERIFY_SUCCESS(result, OC_STACK_OK);
90 // fill OCCoAPToken structure
91 RetrieveOCCoAPToken(sentPdu, &sentToken);
93 if(msgType == COAP_MESSAGE_RST)
95 if(myStackMode != OC_CLIENT)
97 result = OCStackFeedBack(&sentToken, OC_OBSERVER_NOT_INTERESTED);
98 if(result == OC_STACK_OK)
101 "Received RST, removing all queues associated with Token %d bytes",
102 sentToken.tokenLength);
103 OC_LOG_BUFFER(INFO, TAG, sentToken.token, sentToken.tokenLength);
104 coap_cancel_all_messages(ctx, &sentQueue->remote, sentToken.token,
105 sentToken.tokenLength);
109 else if(observationOption != OC_OBSERVE_NO_OPTION && msgType == COAP_MESSAGE_ACK)
111 OC_LOG_V(DEBUG, TAG, "Received ACK, for Token %d bytes",sentToken.tokenLength);
112 OC_LOG_BUFFER(INFO, TAG, sentToken.token, sentToken.tokenLength);
113 // now the observer is still interested
114 if(myStackMode != OC_CLIENT)
116 OCStackFeedBack(&sentToken, OC_OBSERVER_STILL_INTERESTED);
123 //This function is called back by libcoap when a request is received
124 static void HandleCoAPRequests(struct coap_context_t *ctx,
125 const coap_queue_t * rcvdRequest)
129 OCServerProtocolRequest protocolRequest = {(OCMethod)0};
130 coap_block_t rcvdBlock1;
131 coap_block_t rcvdBlock2;
132 memset(&rcvdBlock1, COAP_BLOCK_FILL_VALUE, sizeof(coap_block_t));
133 memset(&rcvdBlock2, COAP_BLOCK_FILL_VALUE, sizeof(coap_block_t));
134 uint16_t rcvdSize1 = 0;
135 coap_pdu_t * rcvdPdu = rcvdRequest->pdu;
136 coap_pdu_t * sendPdu = NULL;
137 coap_send_flags_t sendFlag;
138 OCStackResult result = OC_STACK_ERROR;
139 OCStackResult requestResult = OC_STACK_ERROR;
141 if(myStackMode == OC_CLIENT)
143 //TODO: should the client be responding to requests?
147 protocolRequest.observationOption = OC_OBSERVE_NO_OPTION;
148 protocolRequest.qos = (rcvdPdu->hdr->type == COAP_MESSAGE_CON) ?
149 OC_HIGH_QOS : OC_LOW_QOS;
150 protocolRequest.coapID = rcvdPdu->hdr->id;
151 protocolRequest.delayedResNeeded = rcvdRequest->delayedResNeeded;
152 protocolRequest.secured = rcvdRequest->secure;
154 // fill OCCoAPToken structure
155 RetrieveOCCoAPToken(rcvdPdu, &protocolRequest.requestToken);
156 OC_LOG_V(INFO, TAG, " Token received %d bytes",
157 protocolRequest.requestToken.tokenLength);
158 OC_LOG_BUFFER(INFO, TAG, protocolRequest.requestToken.token,
159 protocolRequest.requestToken.tokenLength);
162 memcpy(&protocolRequest.requesterAddr, (OCDevAddr *) &rcvdRequest->remote,
165 // Retrieve Uri and Query from received coap pdu
166 result = ParseCoAPPdu(rcvdPdu, protocolRequest.resourceUrl,
167 protocolRequest.query,
168 &(protocolRequest.observationOption), NULL,
169 &(protocolRequest.numRcvdVendorSpecificHeaderOptions),
170 protocolRequest.rcvdVendorSpecificHeaderOptions,
171 &rcvdBlock1, &rcvdBlock2, &rcvdSize1, NULL,
172 protocolRequest.reqJSONPayload);
173 VERIFY_SUCCESS(result, OC_STACK_OK);
175 switch (rcvdPdu->hdr->code)
177 case COAP_REQUEST_GET:
179 protocolRequest.method = OC_REST_GET;
182 case COAP_REQUEST_POST:
184 protocolRequest.method = OC_REST_POST;
187 case COAP_REQUEST_DELETE:
189 protocolRequest.method = OC_REST_DELETE;
192 case COAP_REQUEST_PUT:
194 protocolRequest.method = OC_REST_PUT;
199 OC_LOG_V(ERROR, TAG, "Received CoAP method %d not supported",
205 if(rcvdBlock1.szx != 7)
207 protocolRequest.reqPacketSize = 1 << (rcvdBlock1.szx + 4);
208 protocolRequest.reqMorePacket = rcvdBlock1.m;
209 protocolRequest.reqPacketNum = rcvdBlock1.num;
213 // No block1 received
214 rcvdSize1= strlen((const char*)protocolRequest.reqJSONPayload)+1;
215 protocolRequest.reqTotalSize = rcvdSize1;
218 if(rcvdBlock2.szx != 7)
220 protocolRequest.resPacketSize = 1 << (rcvdBlock2.szx + 4);
221 protocolRequest.resPacketNum = rcvdBlock2.num;
224 requestResult = HandleStackRequests(&protocolRequest);
226 if(requestResult == OC_STACK_VIRTUAL_DO_NOT_HANDLE ||
227 requestResult == OC_STACK_OK ||
228 requestResult == OC_STACK_RESOURCE_CREATED ||
229 requestResult == OC_STACK_RESOURCE_DELETED)
233 else if(requestResult == OC_STACK_NO_MEMORY ||
234 requestResult == OC_STACK_ERROR ||
235 requestResult == OC_STACK_NOTIMPL ||
236 requestResult == OC_STACK_NO_RESOURCE ||
237 requestResult == OC_STACK_RESOURCE_ERROR)
239 // TODO: should we send an error also when we receive a non-secured request to a secure resource?
240 // TODO: should we consider some sort of error response
241 OC_LOG(DEBUG, TAG, PCF("We should send some sort of error message"));
242 // generate the pdu, if the request was CON, then the response is ACK, otherwire NON
243 sendPdu = GenerateCoAPPdu((rcvdPdu->hdr->type == COAP_MESSAGE_CON)? COAP_MESSAGE_ACK : COAP_MESSAGE_NON,
244 OCToCoAPResponseCode(requestResult), rcvdPdu->hdr->id,
245 &protocolRequest.requestToken, NULL, NULL);
246 VERIFY_NON_NULL(sendPdu);
247 coap_show_pdu(sendPdu);
248 sendFlag = (coap_send_flags_t)(rcvdRequest->secure ? SEND_SECURE_PORT : 0);
249 if(SendCoAPPdu(gCoAPCtx, (coap_address_t*) &(rcvdRequest->remote), sendPdu,
252 OC_LOG(DEBUG, TAG, PCF("A problem occurred in sending a pdu"));
256 else if(requestResult == OC_STACK_SLOW_RESOURCE)
258 if(rcvdPdu->hdr->type == COAP_MESSAGE_CON)
260 // generate the pdu, if the request was CON, then the response is ACK, otherwire NON
261 sendPdu = GenerateCoAPPdu(COAP_MESSAGE_ACK, 0, rcvdPdu->hdr->id,
263 VERIFY_NON_NULL(sendPdu);
264 coap_show_pdu(sendPdu);
266 sendFlag = (coap_send_flags_t)(rcvdRequest->secure ? SEND_SECURE_PORT : 0);
267 if(SendCoAPPdu(gCoAPCtx, (coap_address_t*) &(rcvdRequest->remote), sendPdu,
270 OC_LOG(DEBUG, TAG, PCF("A problem occurred in sending a pdu"));
282 uint32_t GetTime(float afterSeconds)
286 return now + (uint32_t)(afterSeconds * COAP_TICKS_PER_SECOND);
289 //This function is called back by libcoap when a response is received
290 static void HandleCoAPResponses(struct coap_context_t *ctx,
291 const coap_queue_t * rcvdResponse) {
292 OCStackResult result = OC_STACK_OK;
293 OCCoAPToken rcvdToken = {{0}};
294 OCResponse * response = NULL;
295 OCClientResponse * clientResponse = NULL;
296 unsigned char bufRes[MAX_RESPONSE_LENGTH] = {0};
297 coap_pdu_t * sendPdu = NULL;
298 coap_pdu_t * recvPdu = NULL;
299 uint8_t remoteIpAddr[4] = {0};
300 uint16_t remotePortNu = 0;
301 uint32_t sequenceNumber = OC_OBSERVE_NO_OPTION;
303 unsigned char fullUri[MAX_URI_LENGTH] = { 0 };
304 unsigned char rcvdUri[MAX_URI_LENGTH] = { 0 };
305 coap_block_t rcvdBlock1 = {COAP_BLOCK_FILL_VALUE};
306 coap_block_t rcvdBlock2 = {COAP_BLOCK_FILL_VALUE};
307 uint16_t rcvdSize2 = 0;
309 VERIFY_NON_NULL(ctx);
310 VERIFY_NON_NULL(rcvdResponse);
311 recvPdu = rcvdResponse->pdu;
313 clientResponse = (OCClientResponse *) OCCalloc(1, sizeof(OCClientResponse));
315 result = ParseCoAPPdu(recvPdu, rcvdUri, NULL, &sequenceNumber, &maxAge,
316 &(clientResponse->numRcvdVendorSpecificHeaderOptions),
317 clientResponse->rcvdVendorSpecificHeaderOptions,
318 &rcvdBlock1, &rcvdBlock2, NULL, &rcvdSize2, bufRes);
319 VERIFY_SUCCESS(result, OC_STACK_OK);
321 // get the address of the remote
322 OCDevAddrToIPv4Addr((OCDevAddr *) &(rcvdResponse->remote), remoteIpAddr,
323 remoteIpAddr + 1, remoteIpAddr + 2, remoteIpAddr + 3);
324 OCDevAddrToPort((OCDevAddr *) &(rcvdResponse->remote), &remotePortNu);
325 snprintf((char *)fullUri, MAX_URI_LENGTH, "coap://%d.%d.%d.%d:%d%s",
326 remoteIpAddr[0],remoteIpAddr[1],remoteIpAddr[2],remoteIpAddr[3],
327 remotePortNu,rcvdUri);
329 // fill OCCoAPToken structure
330 RetrieveOCCoAPToken(recvPdu, &rcvdToken);
331 OC_LOG_V(INFO, TAG,"Received a pdu with Token", rcvdToken.tokenLength);
332 OC_LOG_BUFFER(INFO, TAG, rcvdToken.token, rcvdToken.tokenLength);
334 // fill OCClientResponse structure
335 result = FormOCClientResponse(clientResponse, CoAPToOCResponseCode(recvPdu->hdr->code),
336 (OCDevAddr *) &(rcvdResponse->remote), sequenceNumber, NULL);
337 VERIFY_SUCCESS(result, OC_STACK_OK);
339 result = FormOCResponse(&response, NULL, maxAge, fullUri, rcvdUri,
340 &rcvdToken, clientResponse, bufRes);
341 VERIFY_SUCCESS(result, OC_STACK_OK);
343 result = HandleStackResponses(response);
345 if(result == OC_STACK_ERROR)
347 OC_LOG(INFO, TAG, PCF("Received a notification or response that is malformed or incorrect \
348 ------------ sending RESET"));
349 sendPdu = GenerateCoAPPdu(COAP_MESSAGE_RST, 0,
350 recvPdu->hdr->id, NULL, NULL, NULL);
351 VERIFY_NON_NULL(sendPdu);
352 result = SendCoAPPdu(gCoAPCtx, (coap_address_t*) &rcvdResponse->remote, sendPdu,
353 (coap_send_flags_t)(rcvdResponse->secure ? SEND_SECURE_PORT : 0));
354 VERIFY_SUCCESS(result, OC_STACK_OK);
356 else if(result == OC_STACK_NO_MEMORY)
358 OC_LOG(ERROR, TAG, PCF("Received a notification or response. While processing, local " \
359 "platform or memory pool ran out memory."));
362 if(recvPdu->hdr->type == COAP_MESSAGE_CON)
364 sendPdu = GenerateCoAPPdu(COAP_MESSAGE_ACK, 0,
365 recvPdu->hdr->id, NULL, NULL, NULL);
366 VERIFY_NON_NULL(sendPdu);
367 result = SendCoAPPdu(gCoAPCtx, (coap_address_t*) &rcvdResponse->remote,
369 (coap_send_flags_t)(rcvdResponse->secure ? SEND_SECURE_PORT : 0));
370 VERIFY_SUCCESS(result, OC_STACK_OK);
375 OCFree(clientResponse);
378 //=============================================================================
380 //=============================================================================
383 * Initialize the CoAP client or server with its IPv4 address and CoAP port
386 * IP Address of host device
388 * Port of host device
390 * Host device is client, server, or client-server
396 OCStackResult OCInitCoAP(const char *address, uint16_t port, OCMode mode) {
398 OCStackResult ret = OC_STACK_ERROR;
400 TODO ("Below should go away and be replaced by OC_LOG");
401 coap_log_t log_level = (coap_log_t)(LOG_DEBUG + 1);
403 uint8_t ipAddr[4] = { 0 };
404 uint16_t parsedPort = 0;
406 OC_LOG(INFO, TAG, PCF("Entering OCInitCoAP"));
408 coap_set_log_level(log_level);
412 if (!ParseIPv4Address((unsigned char *) address, ipAddr, &parsedPort))
414 ret = OC_STACK_ERROR;
418 OC_LOG_V(INFO, TAG, "Parsed IP Address %d.%d.%d.%d",
419 ipAddr[0],ipAddr[1],ipAddr[2],ipAddr[3]);
422 gCoAPCtx = coap_new_context(ipAddr, port);
423 VERIFY_NON_NULL(gCoAPCtx);
425 // To allow presence notification work we need to init socket gCoAPCtx->sockfd_wellknown
426 // for servers as well as clients
427 OCBuildIPv4Address(coapWKIpAddr[0], coapWKIpAddr[1], coapWKIpAddr[2],
428 coapWKIpAddr[3], COAP_DEFAULT_PORT, &mcastAddr);
430 coap_join_wellknown_group(gCoAPCtx,
431 (coap_address_t* )&mcastAddr), 0);
433 coap_register_request_handler(gCoAPCtx, HandleCoAPRequests);
434 coap_register_response_handler(gCoAPCtx, HandleCoAPResponses);
435 coap_register_ack_rst_handler(gCoAPCtx, HandleCoAPAckRst);
440 if (ret != OC_STACK_OK)
448 * Discover OC resources
450 * @param method - method to perform on the resource
451 * @param qos - Quality of Service the request will be sent on
452 * @param token - token which will added to the request
453 * @param Uri - URI of the resource to interact with
454 * @param payload - the request payload to be added to the request before sending
455 * by the stack when discovery or resource interaction is complete
456 * @param options - The address of an array containing the vendor specific
457 * header options to be sent with the request
462 OCStackResult OCDoCoAPResource(OCMethod method, OCQualityOfService qos, OCCoAPToken * token,
463 const char *Uri, const char *payload, OCHeaderOption * options, uint8_t numOptions)
466 OCStackResult ret = OC_STACK_ERROR;
467 coap_pdu_t *pdu = NULL;
470 uint8_t ipAddr[4] = { 0 };
472 coap_list_t *optList = NULL;
475 uint32_t observeOption;
476 coap_send_flags_t flag = (coap_send_flags_t)0;
478 OC_LOG(INFO, TAG, PCF("Entering OCDoCoAPResource"));
481 OC_LOG_V(INFO, TAG, "URI = %s", Uri);
482 VERIFY_SUCCESS(coap_split_uri((unsigned char * )Uri, strlen(Uri), &uri), OC_STACK_OK);
484 // Generate the destination address
485 if (uri.host.length && ParseIPv4Address(uri.host.s, ipAddr, &port)) {
486 OCBuildIPv4Address(ipAddr[0], ipAddr[1], ipAddr[2], ipAddr[3], uri.port,
492 VERIFY_SUCCESS(FormOptionList(&optList, NULL, NULL, NULL,
493 (uint16_t*)&uri.port, uri.path.length, uri.path.s, uri.query.length,
494 uri.query.s, options, numOptions), OC_STACK_OK);
496 //TODO : Investigate the scenario where there will be no uri for OCDoCoAPResource
497 flag = (coap_send_flags_t) (uri.secure ? SEND_SECURE_PORT : 0);
498 OC_LOG_V(DEBUG, TAG, "uri.host.s %s", uri.host.s);
499 OC_LOG_V(DEBUG, TAG, "uri.path.s %s", uri.path.s);
500 OC_LOG_V(DEBUG, TAG, "uri.port %d", uri.port);
501 OC_LOG_V(DEBUG, TAG, "uri.query.s %s", uri.query.s);
502 OC_LOG_V(DEBUG, TAG, "secure uri %d", uri.secure);
505 coapMsgType = OCToCoAPQoS(qos);
507 // Decide method type
510 coapMethod = COAP_REQUEST_GET;
513 coapMethod = COAP_REQUEST_PUT;
516 coapMethod = COAP_REQUEST_POST;
519 coapMethod = COAP_REQUEST_DELETE;
521 case OC_REST_OBSERVE_ALL:
522 case OC_REST_OBSERVE:
523 case OC_REST_CANCEL_OBSERVE:
524 coapMethod = COAP_REQUEST_GET;
525 observeOption = (method == OC_REST_CANCEL_OBSERVE)?
526 OC_OBSERVE_DEREGISTER:OC_OBSERVE_REGISTER;
527 coap_insert(&optList, CreateNewOptionNode(COAP_OPTION_OBSERVE,
528 sizeof(observeOption), (uint8_t *)&observeOption), OrderOptions);
531 coapMethod = OC_REST_NOMETHOD;
532 OC_LOG(FATAL, TAG, PCF("OCDoCoAPResource only supports GET, PUT, & OBSERVE methods"));
536 VERIFY_NON_NULL(gCoAPCtx);
537 pdu = GenerateCoAPPdu(coapMsgType, coapMethod,
538 coap_new_message_id(gCoAPCtx), token,
539 (unsigned char*) payload, optList);
540 VERIFY_NON_NULL(pdu);
542 ret = SendCoAPPdu(gCoAPCtx, (coap_address_t*) &dst, pdu, flag);
545 if (ret!= OC_STACK_OK)
547 OC_LOG(DEBUG, TAG, PCF("A problem occurred in sending a pdu"));
552 OCStackResult OCDoCoAPResponse(OCServerProtocolResponse *response)
554 OCStackResult result = OC_STACK_ERROR;
555 coap_pdu_t * sendPdu = NULL;
556 coap_list_t *optList = NULL;
557 uint8_t msgType = COAP_MESSAGE_NON;
558 uint8_t mediaType = COAP_MEDIATYPE_APPLICATION_JSON;
559 uint32_t maxAge = 0x2ffff;
560 coap_send_flags_t sendFlag = (coap_send_flags_t)0;
562 //uint32_t observeOption = OC_OBSERVE_NO_OPTION;
563 //OCStackResult responseResult;
565 OC_LOG(INFO, TAG, PCF("Entering OCDoCoAPResponse"));
567 if(response->notificationFlag && response->qos == OC_HIGH_QOS)
569 msgType = COAP_MESSAGE_CON;
571 else if(response->notificationFlag && response->qos != OC_HIGH_QOS)
573 msgType = COAP_MESSAGE_NON;
575 else if(!response->notificationFlag && !response->slowFlag && response->qos == OC_HIGH_QOS)
577 msgType = COAP_MESSAGE_ACK;
579 else if(!response->notificationFlag && response->slowFlag && response->qos == OC_HIGH_QOS)
581 msgType = COAP_MESSAGE_CON;
583 else if(!response->notificationFlag)
585 msgType = COAP_MESSAGE_NON;
588 if(response->coapID == 0)
590 response->coapID = coap_new_message_id(gCoAPCtx);
593 if (response->observationOption != OC_OBSERVE_NO_OPTION)
595 result = FormOptionList(&optList, &mediaType, &maxAge,
596 &response->observationOption, NULL,
597 strlen((char *)response->resourceUri), response->resourceUri,
599 response->sendVendorSpecificHeaderOptions,
600 response->numSendVendorSpecificHeaderOptions);
604 result = FormOptionList(&optList, &mediaType, &maxAge,
606 strlen((char *)response->resourceUri), response->resourceUri,
608 response->sendVendorSpecificHeaderOptions,
609 response->numSendVendorSpecificHeaderOptions);
611 VERIFY_SUCCESS(result, OC_STACK_OK);
613 sendPdu = GenerateCoAPPdu(msgType, OCToCoAPResponseCode(response->result),
614 response->coapID, response->requestToken, (unsigned char *)response->payload,
617 VERIFY_NON_NULL(sendPdu);
618 coap_show_pdu(sendPdu);
620 sendFlag = (coap_send_flags_t)(response->delayedResNeeded ? SEND_DELAYED : 0);
621 sendFlag = (coap_send_flags_t)( sendFlag | (response->secured ? SEND_SECURE_PORT : 0));
623 if (SendCoAPPdu(gCoAPCtx, (coap_address_t *) (response->requesterAddr), sendPdu, sendFlag)
626 OC_LOG(ERROR, TAG, PCF("A problem occurred in sending a pdu"));
627 return OC_STACK_ERROR;
631 OC_LOG(ERROR, TAG, PCF("Error formatting server response"));
632 return OC_STACK_ERROR;
636 * Stop the CoAP client or server processing
638 * @return 0 - success, else - TBD error
640 OCStackResult OCStopCoAP() {
641 OC_LOG(INFO, TAG, PCF("Entering OCStopCoAP"));
642 coap_free_context(gCoAPCtx);
648 * Called in main loop of CoAP client or server. Allows low-level CoAP processing of
649 * send, receive, timeout, discovery, callbacks, etc.
651 * @return 0 - success, else - TBD error
653 OCStackResult OCProcessCoAP() {
655 OC_LOG(INFO, TAG, PCF("Entering OCProcessCoAP"));
657 read = coap_read(gCoAPCtx, gCoAPCtx->sockfd);
659 OC_LOG(INFO, TAG, PCF("This is a Unicast<============"));
661 if (-1 != gCoAPCtx->sockfd_wellknown) {
662 read = coap_read(gCoAPCtx, gCoAPCtx->sockfd_wellknown);
665 OC_LOG(INFO, TAG, PCF("This is a Multicast<==========="));
668 if (-1 != gCoAPCtx->sockfd_dtls) {
669 read = coap_read(gCoAPCtx, gCoAPCtx->sockfd_dtls);
672 OC_LOG(INFO, TAG, PCF("This is a Secure packet<==========="));
675 coap_dispatch(gCoAPCtx);
677 HandleSendQueue(gCoAPCtx);
684 * Retrieve the info about the end-point where resource is being hosted.
685 * Currently, this method only provides the IP port with which the socket
688 * @return 0 - success, else - TBD error
690 OCStackResult OCGetResourceEndPointInfo (OCResource *resPtr, void *info) {
692 OCStackResult result = OC_STACK_ERROR;
694 OC_LOG(INFO, TAG, PCF("Entering OCGetResourceEndPointInfo"));
695 VERIFY_NON_NULL(resPtr);
696 VERIFY_NON_NULL(info);
698 sfd = (resPtr->resourceProperties & OC_SECURE) ? gCoAPCtx->sockfd_dtls :
701 if (OCGetSocketInfo(sfd, (uint16_t*)info) == ERR_SUCCESS)
702 result = OC_STACK_OK;