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 //=============================================================================
25 #define _POSIX_C_SOURCE 200112L
28 #include "ocstackconfig.h"
29 #include "occlientcb.h"
30 #include "ocobserve.h"
41 //=============================================================================
43 //=============================================================================
44 #define TAG PCF("OCCoAP")
45 #define VERIFY_SUCCESS(op, successCode) { if (op != successCode) \
46 {OC_LOG_V(FATAL, TAG, "%s failed!!", #op); goto exit;} }
47 #define VERIFY_NON_NULL(arg) { if (!arg) {OC_LOG_V(FATAL, TAG, "%s is NULL", #arg); goto exit;} }
49 //=============================================================================
51 //=============================================================================
52 #define COAP_BLOCK_FILL_VALUE (0xFF)
54 //=============================================================================
56 //=============================================================================
58 static coap_context_t *gCoAPCtx = NULL;
60 //=============================================================================
62 //=============================================================================
64 //generate a coap token
65 void OCGenerateCoAPToken(OCCoAPToken * token)
69 token->tokenLength = MAX_TOKEN_LENGTH;
70 OCFillRandomMem((uint8_t*)token->token, token->tokenLength);
74 //This function is called back by libcoap when ack or rst are received
75 static void HandleCoAPAckRst(struct coap_context_t * ctx, uint8_t msgType,
76 const coap_queue_t * sentQueue){
80 coap_pdu_t * sentPdu = sentQueue->pdu;
81 OCStackResult result = OC_STACK_ERROR;
82 uint32_t observationOption = OC_OBSERVE_NO_OPTION;
83 // {{0}} to eliminate warning for known compiler bug 53119
84 // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53119
87 CAToken_t sentToken = NULL;
89 OCCoAPToken sentToken = {{0}};
92 result = ParseCoAPPdu(sentPdu, NULL, NULL, &observationOption, NULL, NULL, NULL,
93 NULL, NULL, NULL, NULL, NULL);
94 VERIFY_SUCCESS(result, OC_STACK_OK);
96 // fill OCCoAPToken structure
97 RetrieveOCCoAPToken(sentPdu, &sentToken);
99 if(msgType == COAP_MESSAGE_RST)
101 if(myStackMode != OC_CLIENT)
103 result = OCStackFeedBack(&sentToken, OC_OBSERVER_NOT_INTERESTED);
104 if(result == OC_STACK_OK)
108 "Received RST, removing all queues associated with Token %d bytes",
110 OC_LOG_BUFFER(INFO, TAG, sentToken, CA_MAX_TOKEN_LEN);
111 coap_cancel_all_messages(ctx, &sentQueue->remote, (unsigned char *)sentToken,
115 "Received RST, removing all queues associated with Token %d bytes",
116 sentToken.tokenLength);
117 OC_LOG_BUFFER(INFO, TAG, sentToken.token, sentToken.tokenLength);
118 coap_cancel_all_messages(ctx, &sentQueue->remote, sentToken.token,
119 sentToken.tokenLength);
124 else if(observationOption != OC_OBSERVE_NO_OPTION && msgType == COAP_MESSAGE_ACK)
128 OC_LOG_V(DEBUG, TAG, "Received ACK, for Token %d bytes",sentToken.tokenLength);
129 OC_LOG_BUFFER(INFO, TAG, sentToken.token, sentToken.tokenLength);
131 // now the observer is still interested
132 if(myStackMode != OC_CLIENT)
134 OCStackFeedBack(&sentToken, OC_OBSERVER_STILL_INTERESTED);
141 //This function is called back by libcoap when a request is received
142 static void HandleCoAPRequests(struct coap_context_t *ctx,
143 const coap_queue_t * rcvdRequest)
147 OCServerProtocolRequest protocolRequest = {(OCMethod)0};
148 coap_block_t rcvdBlock1;
149 coap_block_t rcvdBlock2;
150 memset(&rcvdBlock1, COAP_BLOCK_FILL_VALUE, sizeof(coap_block_t));
151 memset(&rcvdBlock2, COAP_BLOCK_FILL_VALUE, sizeof(coap_block_t));
152 uint16_t rcvdSize1 = 0;
153 coap_pdu_t * rcvdPdu = rcvdRequest->pdu;
154 coap_pdu_t * sendPdu = NULL;
155 coap_send_flags_t sendFlag;
156 OCStackResult result = OC_STACK_ERROR;
157 OCStackResult requestResult = OC_STACK_ERROR;
159 if(myStackMode == OC_CLIENT)
161 //TODO: should the client be responding to requests?
165 protocolRequest.observationOption = OC_OBSERVE_NO_OPTION;
166 protocolRequest.qos = (rcvdPdu->hdr->type == COAP_MESSAGE_CON) ?
167 OC_HIGH_QOS : OC_LOW_QOS;
168 protocolRequest.coapID = rcvdPdu->hdr->id;
169 protocolRequest.delayedResNeeded = rcvdRequest->delayedResNeeded;
170 protocolRequest.secured = rcvdRequest->secure;
172 // fill OCCoAPToken structure
173 RetrieveOCCoAPToken(rcvdPdu, &protocolRequest.requestToken);
176 OC_LOG_V(INFO, TAG, " Token received %d bytes",
177 protocolRequest.requestToken.tokenLength);
178 OC_LOG_BUFFER(INFO, TAG, protocolRequest.requestToken.token,
179 protocolRequest.requestToken.tokenLength);
183 memcpy(&protocolRequest.requesterAddr, (OCDevAddr *) &rcvdRequest->remote,
186 // Retrieve Uri and Query from received coap pdu
187 result = ParseCoAPPdu(rcvdPdu, protocolRequest.resourceUrl,
188 protocolRequest.query,
189 &(protocolRequest.observationOption), NULL,
190 &(protocolRequest.numRcvdVendorSpecificHeaderOptions),
191 protocolRequest.rcvdVendorSpecificHeaderOptions,
192 &rcvdBlock1, &rcvdBlock2, &rcvdSize1, NULL,
193 protocolRequest.reqJSONPayload);
194 VERIFY_SUCCESS(result, OC_STACK_OK);
196 switch (rcvdPdu->hdr->code)
198 case COAP_REQUEST_GET:
200 protocolRequest.method = OC_REST_GET;
203 case COAP_REQUEST_POST:
205 protocolRequest.method = OC_REST_POST;
208 case COAP_REQUEST_DELETE:
210 protocolRequest.method = OC_REST_DELETE;
213 case COAP_REQUEST_PUT:
215 protocolRequest.method = OC_REST_PUT;
220 OC_LOG_V(ERROR, TAG, "Received CoAP method %d not supported",
226 if(rcvdBlock1.szx != 7)
228 protocolRequest.reqPacketSize = 1 << (rcvdBlock1.szx + 4);
229 protocolRequest.reqMorePacket = rcvdBlock1.m;
230 protocolRequest.reqPacketNum = rcvdBlock1.num;
234 // No block1 received
235 rcvdSize1= strlen((const char*)protocolRequest.reqJSONPayload)+1;
236 protocolRequest.reqTotalSize = rcvdSize1;
239 if(rcvdBlock2.szx != 7)
241 protocolRequest.resPacketSize = 1 << (rcvdBlock2.szx + 4);
242 protocolRequest.resPacketNum = rcvdBlock2.num;
245 requestResult = HandleStackRequests(&protocolRequest);
247 if(requestResult == OC_STACK_VIRTUAL_DO_NOT_HANDLE ||
248 requestResult == OC_STACK_OK ||
249 requestResult == OC_STACK_RESOURCE_CREATED ||
250 requestResult == OC_STACK_RESOURCE_DELETED ||
251 requestResult == OC_STACK_INVALID_DEVICE_INFO)
255 else if(requestResult == OC_STACK_NO_MEMORY ||
256 requestResult == OC_STACK_ERROR ||
257 requestResult == OC_STACK_NOTIMPL ||
258 requestResult == OC_STACK_NO_RESOURCE ||
259 requestResult == OC_STACK_RESOURCE_ERROR)
261 // TODO: should we send an error also when we receive a non-secured request to a secure resource?
262 // TODO: should we consider some sort of error response
263 OC_LOG(DEBUG, TAG, PCF("We should send some sort of error message"));
264 // generate the pdu, if the request was CON, then the response is ACK, otherwire NON
265 sendPdu = GenerateCoAPPdu((rcvdPdu->hdr->type == COAP_MESSAGE_CON)? COAP_MESSAGE_ACK : COAP_MESSAGE_NON,
266 OCToCoAPResponseCode(requestResult), rcvdPdu->hdr->id,
267 &protocolRequest.requestToken, NULL, NULL);
268 VERIFY_NON_NULL(sendPdu);
269 coap_show_pdu(sendPdu);
270 sendFlag = (coap_send_flags_t)(rcvdRequest->secure ? SEND_SECURE_PORT : 0);
271 if(SendCoAPPdu(gCoAPCtx, (coap_address_t*) &(rcvdRequest->remote), sendPdu,
274 OC_LOG(DEBUG, TAG, PCF("A problem occurred in sending a pdu"));
278 else if(requestResult == OC_STACK_SLOW_RESOURCE)
280 if(rcvdPdu->hdr->type == COAP_MESSAGE_CON)
282 // generate the pdu, if the request was CON, then the response is ACK, otherwire NON
283 sendPdu = GenerateCoAPPdu(COAP_MESSAGE_ACK, 0, rcvdPdu->hdr->id,
285 VERIFY_NON_NULL(sendPdu);
286 coap_show_pdu(sendPdu);
288 sendFlag = (coap_send_flags_t)(rcvdRequest->secure ? SEND_SECURE_PORT : 0);
289 if(SendCoAPPdu(gCoAPCtx, (coap_address_t*) &(rcvdRequest->remote), sendPdu,
292 OC_LOG(DEBUG, TAG, PCF("A problem occurred in sending a pdu"));
304 uint32_t GetTime(float afterSeconds)
308 return now + (uint32_t)(afterSeconds * COAP_TICKS_PER_SECOND);
311 //This function is called back by libcoap when a response is received
312 static void HandleCoAPResponses(struct coap_context_t *ctx,
313 const coap_queue_t * rcvdResponse) {
314 OCStackResult result = OC_STACK_OK;
316 CAToken_t rcvdToken = NULL;
318 OCCoAPToken rcvdToken = {{0}};
320 OCResponse * response = NULL;
321 OCClientResponse * clientResponse = NULL;
322 unsigned char bufRes[MAX_RESPONSE_LENGTH] = {0};
323 coap_pdu_t * sendPdu = NULL;
324 coap_pdu_t * recvPdu = NULL;
325 uint8_t remoteIpAddr[4] = {0};
326 uint16_t remotePortNu = 0;
327 uint32_t sequenceNumber = OC_OBSERVE_NO_OPTION;
329 unsigned char fullUri[MAX_URI_LENGTH] = { 0 };
330 unsigned char rcvdUri[MAX_URI_LENGTH] = { 0 };
331 coap_block_t rcvdBlock1 = {COAP_BLOCK_FILL_VALUE};
332 coap_block_t rcvdBlock2 = {COAP_BLOCK_FILL_VALUE};
333 uint16_t rcvdSize2 = 0;
335 VERIFY_NON_NULL(ctx);
336 VERIFY_NON_NULL(rcvdResponse);
337 recvPdu = rcvdResponse->pdu;
339 clientResponse = (OCClientResponse *) OCCalloc(1, sizeof(OCClientResponse));
341 result = ParseCoAPPdu(recvPdu, rcvdUri, NULL, &sequenceNumber, &maxAge,
342 &(clientResponse->numRcvdVendorSpecificHeaderOptions),
343 clientResponse->rcvdVendorSpecificHeaderOptions,
344 &rcvdBlock1, &rcvdBlock2, NULL, &rcvdSize2, bufRes);
345 VERIFY_SUCCESS(result, OC_STACK_OK);
347 // get the address of the remote
348 OCDevAddrToIPv4Addr((OCDevAddr *) &(rcvdResponse->remote), remoteIpAddr,
349 remoteIpAddr + 1, remoteIpAddr + 2, remoteIpAddr + 3);
350 OCDevAddrToPort((OCDevAddr *) &(rcvdResponse->remote), &remotePortNu);
351 snprintf((char *)fullUri, MAX_URI_LENGTH, "coap://%d.%d.%d.%d:%d%s",
352 remoteIpAddr[0],remoteIpAddr[1],remoteIpAddr[2],remoteIpAddr[3],
353 remotePortNu,rcvdUri);
355 // fill OCCoAPToken structure
356 RetrieveOCCoAPToken(recvPdu, &rcvdToken);
359 OC_LOG_V(INFO, TAG,"Received a pdu with Token", rcvdToken.tokenLength);
360 OC_LOG_BUFFER(INFO, TAG, rcvdToken.token, rcvdToken.tokenLength);
363 // fill OCClientResponse structure
364 result = FormOCClientResponse(clientResponse, CoAPToOCResponseCode(recvPdu->hdr->code),
365 (OCDevAddr *) &(rcvdResponse->remote), sequenceNumber, NULL);
366 VERIFY_SUCCESS(result, OC_STACK_OK);
369 result = FormOCResponse(&response, NULL, maxAge, fullUri, rcvdUri,
370 &rcvdToken, clientResponse, bufRes);
371 VERIFY_SUCCESS(result, OC_STACK_OK);
373 result = HandleStackResponses(response);
375 if(result == OC_STACK_ERROR)
377 OC_LOG(INFO, TAG, PCF("Received a notification or response that is malformed or incorrect \
378 ------------ sending RESET"));
379 sendPdu = GenerateCoAPPdu(COAP_MESSAGE_RST, 0,
380 recvPdu->hdr->id, NULL, NULL, NULL);
381 VERIFY_NON_NULL(sendPdu);
382 result = SendCoAPPdu(gCoAPCtx, (coap_address_t*) &rcvdResponse->remote, sendPdu,
383 (coap_send_flags_t)(rcvdResponse->secure ? SEND_SECURE_PORT : 0));
384 VERIFY_SUCCESS(result, OC_STACK_OK);
386 else if(result == OC_STACK_NO_MEMORY)
388 OC_LOG(ERROR, TAG, PCF("Received a notification or response. While processing, local " \
389 "platform or memory pool ran out memory."));
392 if(recvPdu->hdr->type == COAP_MESSAGE_CON)
394 sendPdu = GenerateCoAPPdu(COAP_MESSAGE_ACK, 0,
395 recvPdu->hdr->id, NULL, NULL, NULL);
396 VERIFY_NON_NULL(sendPdu);
397 result = SendCoAPPdu(gCoAPCtx, (coap_address_t*) &rcvdResponse->remote,
399 (coap_send_flags_t)(rcvdResponse->secure ? SEND_SECURE_PORT : 0));
400 VERIFY_SUCCESS(result, OC_STACK_OK);
405 OCFree(clientResponse);
408 //=============================================================================
410 //=============================================================================
413 * Initialize the CoAP client or server with its IPv4 address and CoAP port
416 * IP Address of host device
418 * Port of host device
420 * Host device is client, server, or client-server
426 OCStackResult OCInitCoAP(const char *address, uint16_t port, OCMode mode) {
428 OCStackResult ret = OC_STACK_ERROR;
430 TODO ("Below should go away and be replaced by OC_LOG");
431 coap_log_t log_level = (coap_log_t)(LOG_DEBUG + 1);
433 uint8_t ipAddr[4] = { 0 };
434 uint16_t parsedPort = 0;
436 OC_LOG(INFO, TAG, PCF("Entering OCInitCoAP"));
438 coap_set_log_level(log_level);
442 if (!ParseIPv4Address((unsigned char *) address, ipAddr, &parsedPort))
444 ret = OC_STACK_ERROR;
448 OC_LOG_V(INFO, TAG, "Parsed IP Address %d.%d.%d.%d",
449 ipAddr[0],ipAddr[1],ipAddr[2],ipAddr[3]);
452 gCoAPCtx = coap_new_context(ipAddr, port);
453 VERIFY_NON_NULL(gCoAPCtx);
455 // To allow presence notification work we need to init socket gCoAPCtx->sockfd_wellknown
456 // for servers as well as clients
457 OCBuildIPv4Address(COAP_WK_IPAddr_0, COAP_WK_IPAddr_1, COAP_WK_IPAddr_2,
458 COAP_WK_IPAddr_3, COAP_DEFAULT_PORT, &mcastAddr);
460 coap_join_wellknown_group(gCoAPCtx,
461 (coap_address_t* )&mcastAddr), 0);
463 coap_register_request_handler(gCoAPCtx, HandleCoAPRequests);
464 coap_register_response_handler(gCoAPCtx, HandleCoAPResponses);
465 coap_register_ack_rst_handler(gCoAPCtx, HandleCoAPAckRst);
470 if (ret != OC_STACK_OK)
478 * Discover OC resources
480 * @param method - method to perform on the resource
481 * @param qos - Quality of Service the request will be sent on
482 * @param token - token which will added to the request
483 * @param Uri - URI of the resource to interact with
484 * @param payload - the request payload to be added to the request before sending
485 * by the stack when discovery or resource interaction is complete
486 * @param options - The address of an array containing the vendor specific
487 * header options to be sent with the request
493 OCStackResult OCDoCoAPResource(OCMethod method, OCQualityOfService qos, CAToken_t * token,
494 const char *Uri, const char *payload, OCHeaderOption * options, uint8_t numOptions)
496 OCStackResult OCDoCoAPResource(OCMethod method, OCQualityOfService qos, OCCoAPToken * token,
497 const char *Uri, const char *payload, OCHeaderOption * options, uint8_t numOptions)
501 OCStackResult ret = OC_STACK_ERROR;
502 coap_pdu_t *pdu = NULL;
505 uint8_t ipAddr[4] = { 0 };
507 coap_list_t *optList = NULL;
510 uint32_t observeOption;
511 coap_send_flags_t flag = (coap_send_flags_t)0;
513 OC_LOG(INFO, TAG, PCF("Entering OCDoCoAPResource"));
516 OC_LOG_V(INFO, TAG, "URI = %s", Uri);
517 VERIFY_SUCCESS(coap_split_uri((unsigned char * )Uri, strlen(Uri), &uri), OC_STACK_OK);
519 // Generate the destination address
520 if (uri.host.length && ParseIPv4Address(uri.host.s, ipAddr, &port)) {
521 OCBuildIPv4Address(ipAddr[0], ipAddr[1], ipAddr[2], ipAddr[3], uri.port,
527 VERIFY_SUCCESS(FormOptionList(&optList, NULL, NULL, NULL,
528 (uint16_t*)&uri.port, uri.path.length, uri.path.s, uri.query.length,
529 uri.query.s, options, numOptions), OC_STACK_OK);
531 //TODO : Investigate the scenario where there will be no uri for OCDoCoAPResource
532 flag = (coap_send_flags_t) (uri.secure ? SEND_SECURE_PORT : 0);
533 OC_LOG_V(DEBUG, TAG, "uri.host.s %s", uri.host.s);
534 OC_LOG_V(DEBUG, TAG, "uri.path.s %s", uri.path.s);
535 OC_LOG_V(DEBUG, TAG, "uri.port %d", uri.port);
536 OC_LOG_V(DEBUG, TAG, "uri.query.s %s", uri.query.s);
537 OC_LOG_V(DEBUG, TAG, "secure uri %d", uri.secure);
540 coapMsgType = OCToCoAPQoS(qos, ipAddr);
542 // Decide method type
545 coapMethod = COAP_REQUEST_GET;
548 coapMethod = COAP_REQUEST_PUT;
551 coapMethod = COAP_REQUEST_POST;
554 coapMethod = COAP_REQUEST_DELETE;
556 case OC_REST_OBSERVE_ALL:
557 case OC_REST_OBSERVE:
558 case OC_REST_CANCEL_OBSERVE:
559 coapMethod = COAP_REQUEST_GET;
560 observeOption = (method == OC_REST_CANCEL_OBSERVE)?
561 OC_OBSERVE_DEREGISTER:OC_OBSERVE_REGISTER;
562 coap_insert(&optList, CreateNewOptionNode(COAP_OPTION_OBSERVE,
563 sizeof(observeOption), (uint8_t *)&observeOption), OrderOptions);
566 coapMethod = OC_REST_NOMETHOD;
567 OC_LOG(FATAL, TAG, PCF("OCDoCoAPResource only supports GET, PUT, & OBSERVE methods"));
571 VERIFY_NON_NULL(gCoAPCtx);
572 pdu = GenerateCoAPPdu(coapMsgType, coapMethod,
573 coap_new_message_id(gCoAPCtx), token,
574 (unsigned char*) payload, optList);
575 VERIFY_NON_NULL(pdu);
577 ret = SendCoAPPdu(gCoAPCtx, (coap_address_t*) &dst, pdu, flag);
580 if (ret!= OC_STACK_OK)
582 OC_LOG(DEBUG, TAG, PCF("A problem occurred in sending a pdu"));
587 OCStackResult OCDoCoAPResponse(OCServerProtocolResponse *response)
589 OCStackResult result = OC_STACK_ERROR;
590 coap_pdu_t * sendPdu = NULL;
591 coap_list_t *optList = NULL;
592 uint8_t msgType = COAP_MESSAGE_NON;
593 uint8_t mediaType = COAP_MEDIATYPE_APPLICATION_JSON;
594 uint32_t maxAge = 0x2ffff;
595 coap_send_flags_t sendFlag = (coap_send_flags_t)0;
597 //uint32_t observeOption = OC_OBSERVE_NO_OPTION;
598 //OCStackResult responseResult;
600 OC_LOG(INFO, TAG, PCF("Entering OCDoCoAPResponse"));
602 if(response->notificationFlag && response->qos == OC_HIGH_QOS)
604 msgType = COAP_MESSAGE_CON;
606 else if(response->notificationFlag && response->qos != OC_HIGH_QOS)
608 msgType = COAP_MESSAGE_NON;
610 else if(!response->notificationFlag && !response->slowFlag && response->qos == OC_HIGH_QOS)
612 msgType = COAP_MESSAGE_ACK;
614 else if(!response->notificationFlag && response->slowFlag && response->qos == OC_HIGH_QOS)
616 msgType = COAP_MESSAGE_CON;
618 else if(!response->notificationFlag)
620 msgType = COAP_MESSAGE_NON;
623 if(response->coapID == 0)
625 response->coapID = coap_new_message_id(gCoAPCtx);
628 if (response->observationOption != OC_OBSERVE_NO_OPTION)
630 result = FormOptionList(&optList, &mediaType, &maxAge,
631 &response->observationOption, NULL,
632 strlen((char *)response->resourceUri), response->resourceUri,
634 response->sendVendorSpecificHeaderOptions,
635 response->numSendVendorSpecificHeaderOptions);
639 result = FormOptionList(&optList, &mediaType, &maxAge,
641 strlen((char *)response->resourceUri), response->resourceUri,
643 response->sendVendorSpecificHeaderOptions,
644 response->numSendVendorSpecificHeaderOptions);
646 VERIFY_SUCCESS(result, OC_STACK_OK);
648 sendPdu = GenerateCoAPPdu(msgType, OCToCoAPResponseCode(response->result),
649 response->coapID, response->requestToken, (unsigned char *)response->payload,
652 VERIFY_NON_NULL(sendPdu);
653 coap_show_pdu(sendPdu);
655 sendFlag = (coap_send_flags_t)(response->delayedResNeeded ? SEND_DELAYED : 0);
656 sendFlag = (coap_send_flags_t)( sendFlag | (response->secured ? SEND_SECURE_PORT : 0));
658 if (SendCoAPPdu(gCoAPCtx, (coap_address_t *) (response->requesterAddr), sendPdu, sendFlag)
661 OC_LOG(ERROR, TAG, PCF("A problem occurred in sending a pdu"));
662 return OC_STACK_ERROR;
666 OC_LOG(ERROR, TAG, PCF("Error formatting server response"));
667 return OC_STACK_ERROR;
671 * Stop the CoAP client or server processing
673 * @return 0 - success, else - TBD error
675 OCStackResult OCStopCoAP() {
676 OC_LOG(INFO, TAG, PCF("Entering OCStopCoAP"));
677 coap_free_context(gCoAPCtx);
683 * Called in main loop of CoAP client or server. Allows low-level CoAP processing of
684 * send, receive, timeout, discovery, callbacks, etc.
686 * @return 0 - success, else - TBD error
688 OCStackResult OCProcessCoAP() {
690 read = coap_read(gCoAPCtx, gCoAPCtx->sockfd);
692 OC_LOG(INFO, TAG, PCF("This is a Unicast<============"));
694 if (-1 != gCoAPCtx->sockfd_wellknown) {
695 read = coap_read(gCoAPCtx, gCoAPCtx->sockfd_wellknown);
698 OC_LOG(INFO, TAG, PCF("This is a Multicast<==========="));
701 if (-1 != gCoAPCtx->sockfd_dtls) {
702 read = coap_read(gCoAPCtx, gCoAPCtx->sockfd_dtls);
705 OC_LOG(INFO, TAG, PCF("This is a Secure packet<==========="));
708 coap_dispatch(gCoAPCtx);
710 HandleSendQueue(gCoAPCtx);
717 * Retrieve the info about the end-point where resource is being hosted.
718 * Currently, this method only provides the IP port with which the socket
721 * @return 0 - success, else - TBD error
723 OCStackResult OCGetResourceEndPointInfo (OCResource *resPtr, void *info) {
725 OCStackResult result = OC_STACK_ERROR;
727 OC_LOG(INFO, TAG, PCF("Entering OCGetResourceEndPointInfo"));
728 VERIFY_NON_NULL(resPtr);
729 VERIFY_NON_NULL(info);
731 sfd = (resPtr->resourceProperties & OC_SECURE) ? gCoAPCtx->sockfd_dtls :
734 if (OCGetSocketInfo(sfd, (uint16_t*)info) == ERR_SUCCESS)
735 result = OC_STACK_OK;