OCServerRequest * GetServerRequestUsingToken (const OCCoAPToken token)
{
    OCServerRequest * out = NULL;
    LL_FOREACH (serverRequestList, out)
    {
        OC_LOG(INFO, TAG,PCF("comparing tokens"));
        OC_LOG_BUFFER(INFO, TAG, token.token, token.tokenLength);
        OC_LOG_BUFFER(INFO, TAG, out->requestToken.token, out->requestToken.tokenLength);
        if((out->requestToken.tokenLength == token.tokenLength) &&
                (memcmp(out->requestToken.token, token.token, token.tokenLength) == 0))
        {
            return out;
        }
    }
//This function is called back by libcoap when ack or rst are received
static void HandleCoAPAckRst(struct coap_context_t * ctx, uint8_t msgType,
        const coap_queue_t * sentQueue){

    // silence warnings
    (void) ctx;
    coap_pdu_t * sentPdu = sentQueue->pdu;
    OCStackResult result = OC_STACK_ERROR;
    uint32_t observationOption = OC_OBSERVE_NO_OPTION;
    // {{0}} to eliminate warning for known compiler bug 53119
    // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53119
    OCCoAPToken sentToken = {{0}};

    result = ParseCoAPPdu(sentPdu, NULL, NULL, &observationOption, NULL, NULL, NULL,
            NULL, NULL, NULL, NULL, NULL);
    VERIFY_SUCCESS(result, OC_STACK_OK);

    // fill OCCoAPToken structure
    RetrieveOCCoAPToken(sentPdu, &sentToken);

    if(msgType == COAP_MESSAGE_RST)
    {
        if(myStackMode != OC_CLIENT)
        {
            result = OCStackFeedBack(&sentToken, OC_OBSERVER_NOT_INTERESTED);
            if(result == OC_STACK_OK)
            {
                OC_LOG_V(DEBUG, TAG,
                        "Received RST, removing all queues associated with Token %d bytes",
                        sentToken.tokenLength);
                OC_LOG_BUFFER(INFO, TAG, sentToken.token, sentToken.tokenLength);
                coap_cancel_all_messages(ctx, &sentQueue->remote, sentToken.token,
                        sentToken.tokenLength);
            }
        }
    }
    else if(observationOption != OC_OBSERVE_NO_OPTION && msgType == COAP_MESSAGE_ACK)
    {
        OC_LOG_V(DEBUG, TAG, "Received ACK, for Token %d bytes",sentToken.tokenLength);
        OC_LOG_BUFFER(INFO, TAG, sentToken.token, sentToken.tokenLength);
        // now the observer is still interested
        if(myStackMode != OC_CLIENT)
        {
            OCStackFeedBack(&sentToken, OC_OBSERVER_STILL_INTERESTED);
        }
    }
exit:
    return;
}
Exemple #3
0
void ocInitialize () {
    char ipAddr[16] = "";
    OCGetInterfaceAddress (NULL, 0, AF_INET, (uint8_t *)ipAddr, 16);
    OC_LOG(DEBUG, TAG, PCF("IP addr is:"));
    OC_LOG_BUFFER(INFO, TAG, (uint8_t*)ipAddr, sizeof(ipAddr));
    delay(2000);
    OCInit (ipAddr, 8001, OC_SERVER);
}
Exemple #4
0
ResourceObserver* GetObserverUsingToken (const OCCoAPToken * token)
{
    ResourceObserver *out = NULL;

    if(token)
    {
        LL_FOREACH (serverObsList, out)
        {
            OC_LOG(INFO, TAG,PCF("comparing tokens"));
            OC_LOG_BUFFER(INFO, TAG, token->token, token->tokenLength);
            OC_LOG_BUFFER(INFO, TAG, out->token.token, out->token.tokenLength);
            if((out->token.tokenLength == token->tokenLength) &&
               (memcmp(out->token.token, token->token, token->tokenLength) == 0))
            {
                return out;
            }
        }
    }
ResourceObserver* GetObserverUsingToken (const CAToken_t token, uint8_t tokenLength)
{
    ResourceObserver *out = NULL;

    if(token && *token)
    {
        OC_LOG(INFO, TAG, "Looking for token");
        OC_LOG_BUFFER(INFO, TAG, (const uint8_t *)token, tokenLength);
        OC_LOG(INFO, TAG, "\tFound token:");

        LL_FOREACH (serverObsList, out)
        {
            OC_LOG_BUFFER(INFO, TAG, (const uint8_t *)out->token, tokenLength);
            if((memcmp(out->token, token, tokenLength) == 0))
            {
                return out;
            }
        }
ClientCB* GetClientCB(const CAToken_t token, uint8_t tokenLength,
        OCDoHandle handle, const char * requestUri)
{

    ClientCB* out = NULL;

    if(token && *token && tokenLength <= CA_MAX_TOKEN_LEN && tokenLength > 0)
    {
        OC_LOG (INFO, TAG,  "Looking for token");
        OC_LOG_BUFFER(INFO, TAG, (const uint8_t *)token, tokenLength);
        OC_LOG(INFO, TAG, "\tFound in callback list");
        LL_FOREACH(cbList, out)
        {
            OC_LOG_BUFFER(INFO, TAG, (const uint8_t *)out->token, tokenLength);

            if(memcmp(out->token, token, tokenLength) == 0)
            {
                return out;
            }
            CheckAndDeleteTimedOutCB(out);
        }
OCStackApplicationResult getReqCB(void* ctx, OCDoHandle handle,
                           OCClientResponse * clientResponse)
{
    uint8_t remoteIpAddr[4];
    uint16_t remotePortNu;

    if (ctx == (void*) DEFAULT_CONTEXT_VALUE)
    {
        OC_LOG(INFO, TAG, "<====Callback Context for GET received successfully====>");
    }
    else
    {
        OC_LOG(ERROR, TAG, "<====Callback Context for GET fail====>");
    }

    if (clientResponse)
    {
        OCDevAddrToIPv4Addr((OCDevAddr *) clientResponse->addr, remoteIpAddr, remoteIpAddr + 1,
                remoteIpAddr + 2, remoteIpAddr + 3);
        OCDevAddrToPort((OCDevAddr *) clientResponse->addr, &remotePortNu);

        OC_LOG_V(INFO, TAG,"Get Response: %s \nFrom %d.%d.%d.%d:%d\n",
                clientResponse->resJSONPayload, remoteIpAddr[0], remoteIpAddr[1],
                remoteIpAddr[2], remoteIpAddr[3], remotePortNu);

        if (clientResponse->rcvdVendorSpecificHeaderOptions
                && clientResponse->numRcvdVendorSpecificHeaderOptions)
        {
            OC_LOG (INFO, TAG, "Received vendor specific options");
            uint8_t i = 0;
            OCHeaderOption * rcvdOptions = clientResponse->rcvdVendorSpecificHeaderOptions;
            for (i = 0; i < clientResponse->numRcvdVendorSpecificHeaderOptions; i++)
            {
                if (((OCHeaderOption) rcvdOptions[i]).protocolID == OC_COAP_ID)
                {
                    OC_LOG_V(INFO, TAG, "Received option with OC_COAP_ID and ID %u with",
                            ((OCHeaderOption)rcvdOptions[i]).optionID );

                    OC_LOG_BUFFER(INFO, TAG, ((OCHeaderOption)rcvdOptions[i]).optionData,
                        MAX_HEADER_OPTION_DATA_LENGTH);
                }
            }
        }
    }
    else
    {
        OC_LOG(ERROR, TAG, "<====GET Callback fail to receive clientResponse====>\n");
    }
    return OC_STACK_DELETE_TRANSACTION;
}
OCStackApplicationResult getReqCB(void* ctx, OCDoHandle /*handle*/,
                                  OCClientResponse * clientResponse)
{
    if (ctx == (void*) DEFAULT_CONTEXT_VALUE)
    {
        OC_LOG(INFO, TAG, "<====Callback Context for GET received successfully====>");
    }
    else
    {
        OC_LOG(ERROR, TAG, "<====Callback Context for GET fail====>");
    }

    if (clientResponse)
    {
        OC_LOG_V(INFO, TAG, "StackResult: %s",  getResult(clientResponse->result));
        OC_LOG_V(INFO, TAG, "SEQUENCE NUMBER: %d", clientResponse->sequenceNumber);
        OC_LOG_PAYLOAD(INFO, clientResponse->payload);
        OC_LOG(INFO, TAG, ("=============> Get Response"));

        if (clientResponse->numRcvdVendorSpecificHeaderOptions > 0 )
        {
            OC_LOG (INFO, TAG, "Received vendor specific options");
            uint8_t i = 0;
            OCHeaderOption * rcvdOptions = clientResponse->rcvdVendorSpecificHeaderOptions;
            for (i = 0; i < clientResponse->numRcvdVendorSpecificHeaderOptions; i++)
            {
                if (((OCHeaderOption) rcvdOptions[i]).protocolID == OC_COAP_ID)
                {
                    OC_LOG_V(INFO, TAG, "Received option with OC_COAP_ID and ID %u with",
                            ((OCHeaderOption)rcvdOptions[i]).optionID );

                    OC_LOG_BUFFER(INFO, TAG, ((OCHeaderOption)rcvdOptions[i]).optionData,
                        MAX_HEADER_OPTION_DATA_LENGTH);
                }
            }
        }
    }
    else
    {
        OC_LOG(ERROR, TAG, "<====GET Callback fail to receive clientResponse====>\n");
    }
    return OC_STACK_DELETE_TRANSACTION;
}
void DeleteClientCB(ClientCB * cbNode)
{
    if(cbNode)
    {
        LL_DELETE(cbList, cbNode);
        OC_LOG (INFO, TAG, "Deleting token");
        OC_LOG_BUFFER(INFO, TAG, (const uint8_t *)cbNode->token, cbNode->tokenLength);
        CADestroyToken (cbNode->token);
        OICFree(cbNode->devAddr);
        OICFree(cbNode->handle);
        OC_LOG_V (INFO, TAG, "Deleting callback with uri %s", cbNode->requestUri);
        OICFree(cbNode->requestUri);
        if(cbNode->deleteCallback)
        {
            cbNode->deleteCallback(cbNode->context);
        }

        #ifdef WITH_PRESENCE
        if(cbNode->presence)
        {
            OICFree(cbNode->presence->timeOut);
            OICFree(cbNode->presence);
        }
        if(cbNode->method == OC_REST_PRESENCE)
        {
            OCResourceType * pointer = cbNode->filterResourceType;
            OCResourceType * next = NULL;
            while(pointer)
            {
                next = pointer->next;
                OICFree(pointer->resourcetypename);
                OICFree(pointer);
                pointer = next;
            }
        }
        #endif // WITH_PRESENCE
        OICFree(cbNode);
        cbNode = NULL;
    }
}
Exemple #10
0
OCStackApplicationResult getReqCB(void* ctx, OCDoHandle handle, OCClientResponse * clientResponse)
{
    if(clientResponse == NULL)
    {
        OC_LOG(INFO, TAG, "getReqCB received NULL clientResponse");
        return   OC_STACK_DELETE_TRANSACTION;
    }

    if(ctx == (void*)DEFAULT_CONTEXT_VALUE)
    {
        OC_LOG(INFO, TAG, "Callback Context for GET query recvd successfully");
    }

    OC_LOG_V(INFO, TAG, "StackResult: %s",  getResult(clientResponse->result));
    OC_LOG_V(INFO, TAG, "SEQUENCE NUMBER: %d", clientResponse->sequenceNumber);
    OC_LOG_V(INFO, TAG, "JSON = %s =============> Get Response", clientResponse->resJSONPayload);

    if(clientResponse->rcvdVendorSpecificHeaderOptions &&
            clientResponse->numRcvdVendorSpecificHeaderOptions)
    {
        OC_LOG (INFO, TAG, "Received vendor specific options");
        uint8_t i = 0;
        OCHeaderOption * rcvdOptions = clientResponse->rcvdVendorSpecificHeaderOptions;
        for( i = 0; i < clientResponse->numRcvdVendorSpecificHeaderOptions; i++)
        {
            if(((OCHeaderOption)rcvdOptions[i]).protocolID == OC_COAP_ID)
            {
                OC_LOG_V(INFO, TAG, "Received option with OC_COAP_ID and ID %u with",
                        ((OCHeaderOption)rcvdOptions[i]).optionID );

                OC_LOG_BUFFER(INFO, TAG, ((OCHeaderOption)rcvdOptions[i]).optionData,
                    MAX_HEADER_OPTION_DATA_LENGTH);
            }
        }
    }
    return OC_STACK_DELETE_TRANSACTION;
}
/**
 * Function to save ownerPSK at provisioning tool end.
 *
 * @param[in] selectedDeviceInfo   selected device information to performing provisioning.
 * @return  OC_STACK_OK on success
 */
static OCStackResult SaveOwnerPSK(OCProvisionDev_t *selectedDeviceInfo)
{
    OC_LOG(DEBUG, TAG, "IN SaveOwnerPSK");

    OCStackResult res = OC_STACK_ERROR;

    CAEndpoint_t endpoint;
    memset(&endpoint, 0x00, sizeof(CAEndpoint_t));
    OICStrcpy(endpoint.addr, MAX_ADDR_STR_SIZE_CA, selectedDeviceInfo->endpoint.addr);
    endpoint.addr[MAX_ADDR_STR_SIZE_CA - 1] = '\0';
    endpoint.port = selectedDeviceInfo->securePort;

    OicUuid_t ptDeviceID = {.id={0}};
    if (OC_STACK_OK != GetDoxmDeviceID(&ptDeviceID))
    {
        OC_LOG(ERROR, TAG, "Error while retrieving provisioning tool's device ID");
        return res;
    }

    uint8_t ownerPSK[OWNER_PSK_LENGTH_128] = {0};

    //Generating OwnerPSK
    CAResult_t pskRet = CAGenerateOwnerPSK(&endpoint,
            (uint8_t *)GetOxmString(selectedDeviceInfo->doxm->oxmSel),
            strlen(GetOxmString(selectedDeviceInfo->doxm->oxmSel)), ptDeviceID.id,
            sizeof(ptDeviceID.id), selectedDeviceInfo->doxm->deviceID.id,
            sizeof(selectedDeviceInfo->doxm->deviceID.id), ownerPSK,
            OWNER_PSK_LENGTH_128);

    if (CA_STATUS_OK == pskRet)
    {
        OC_LOG(INFO, TAG,"ownerPSK dump:\n");
        OC_LOG_BUFFER(INFO, TAG,ownerPSK, OWNER_PSK_LENGTH_128);
        //Generating new credential for provisioning tool
        size_t ownLen = 1;
        uint32_t outLen = 0;

        char base64Buff[B64ENCODE_OUT_SAFESIZE(sizeof(ownerPSK)) + 1] = {};
        B64Result b64Ret = b64Encode(ownerPSK, sizeof(ownerPSK), base64Buff, sizeof(base64Buff),
                &outLen);
        VERIFY_SUCCESS(TAG, B64_OK == b64Ret, ERROR);

        OicSecCred_t *cred = GenerateCredential(&selectedDeviceInfo->doxm->deviceID,
                SYMMETRIC_PAIR_WISE_KEY, NULL,
                base64Buff, ownLen, &ptDeviceID);
        VERIFY_NON_NULL(TAG, cred, ERROR);

        res = AddCredential(cred);
        if(res != OC_STACK_OK)
        {
            DeleteCredList(cred);
            return res;
        }
    }
    else
    {
        OC_LOG(ERROR, TAG, "CAGenerateOwnerPSK failed");
    }

    OC_LOG(DEBUG, TAG, "OUT SaveOwnerPSK");
exit:
    return res;
}
Exemple #12
0
OCStackResult
AddClientCB (ClientCB** clientCB, OCCallbackData* cbData,
             CAToken_t token, uint8_t tokenLength,
             OCDoHandle *handle, OCMethod method,
             OCDevAddr *devAddr, char * requestUri,
             char * resourceTypeName, uint32_t ttl)
{
    if(!clientCB || !cbData || !handle || !requestUri || tokenLength > CA_MAX_TOKEN_LEN)
    {
        return OC_STACK_INVALID_PARAM;
    }

    ClientCB *cbNode = NULL;

    #ifdef WITH_PRESENCE
    if(method == OC_REST_PRESENCE)
    {   // Retrieve the presence callback structure for this specific requestUri.
        cbNode = GetClientCB(NULL, 0, NULL, requestUri);
    }
    #endif // WITH_PRESENCE

    if(!cbNode)// If it does not already exist, create new node.
    {
        cbNode = (ClientCB*) OICMalloc(sizeof(ClientCB));
        if(!cbNode)
        {
            *clientCB = NULL;
            goto exit;
        }
        else
        {
            OC_LOG(INFO, TAG, "Adding client callback with token");
            OC_LOG_BUFFER(INFO, TAG, (const uint8_t *)token, tokenLength);
            cbNode->callBack = cbData->cb;
            cbNode->context = cbData->context;
            cbNode->deleteCallback = cbData->cd;
            //Note: token memory is allocated in the caller OCDoResource
            //but freed in DeleteClientCB
            cbNode->token = token;
            cbNode->tokenLength = tokenLength;
            cbNode->handle = *handle;
            cbNode->method = method;
            cbNode->sequenceNumber = 0;
            #ifdef WITH_PRESENCE
            cbNode->presence = NULL;
            cbNode->filterResourceType = NULL;
            #endif // WITH_PRESENCE

            if (method == OC_REST_PRESENCE ||
                method == OC_REST_OBSERVE  ||
                method == OC_REST_OBSERVE_ALL)
            {
                cbNode->TTL = 0;
            }
            else
            {
                cbNode->TTL = ttl;
            }
            cbNode->requestUri = requestUri;    // I own it now
            cbNode->devAddr = devAddr;          // I own it now
            OC_LOG_V(INFO, TAG, "Added Callback for uri : %s", requestUri);
            LL_APPEND(cbList, cbNode);
            *clientCB = cbNode;
        }
    }
    else
    {
        // Ensure that the handle the SDK hands back up to the application layer for the
        // OCDoResource call matches the found ClientCB Node.
        *clientCB = cbNode;

        if (cbData->cd)
        {
            cbData->cd(cbData->context);
        }

        OICFree(token);
        OICFree(*handle);
        OICFree(requestUri);
        OICFree(devAddr);
        *handle = cbNode->handle;
    }

    #ifdef WITH_PRESENCE
    if(method == OC_REST_PRESENCE && resourceTypeName)
    {
        // Amend the found or created node by adding a new resourceType to it.
        return InsertResourceTypeFilter(cbNode,(char *)resourceTypeName);
        // I own resourceTypName now.
    }
    else
    {
        OICFree(resourceTypeName);
    }
    #else
    OICFree(resourceTypeName);
    #endif

    return OC_STACK_OK;

    exit:
        return OC_STACK_NO_MEMORY;
}
Exemple #13
0
OCEntityHandlerResult
OCEntityHandlerCb (OCEntityHandlerFlag flag,
        OCEntityHandlerRequest *entityHandlerRequest)
{
    OC_LOG_V (INFO, TAG, "Inside entity handler - flags: 0x%x", flag);

    OCEntityHandlerResult ehResult = OC_EH_OK;
    OCEntityHandlerResponse response;
    char payload[MAX_RESPONSE_LENGTH] = {0};

    // Validate pointer
    if (!entityHandlerRequest)
    {
        OC_LOG (ERROR, TAG, "Invalid request pointer");
        return OC_EH_ERROR;
    }

    // Initialize certain response fields
    response.numSendVendorSpecificHeaderOptions = 0;
    memset(response.sendVendorSpecificHeaderOptions, 0, sizeof response.sendVendorSpecificHeaderOptions);
    memset(response.resourceUri, 0, sizeof response.resourceUri);

    if (flag & OC_INIT_FLAG)
    {
        OC_LOG (INFO, TAG, "Flag includes OC_INIT_FLAG");
    }
    if (flag & OC_REQUEST_FLAG)
    {
        OC_LOG (INFO, TAG, "Flag includes OC_REQUEST_FLAG");
        if (OC_REST_GET == entityHandlerRequest->method)
        {
            OC_LOG (INFO, TAG, "Received OC_REST_GET from client");
            ehResult = ProcessGetRequest (entityHandlerRequest, payload, sizeof(payload) - 1);
        }
        else if (OC_REST_PUT == entityHandlerRequest->method)
        {
            OC_LOG (INFO, TAG, "Received OC_REST_PUT from client");
            ehResult = ProcessPutRequest (entityHandlerRequest, payload, sizeof(payload) - 1);
        }
        else if (OC_REST_POST == entityHandlerRequest->method)
        {
            OC_LOG (INFO, TAG, "Received OC_REST_POST from client");
            ehResult = ProcessPostRequest (entityHandlerRequest, &response, payload, sizeof(payload) - 1);
        }
        else if (OC_REST_DELETE == entityHandlerRequest->method)
        {
            OC_LOG (INFO, TAG, "Received OC_REST_DELETE from client");
            ehResult = ProcessDeleteRequest (entityHandlerRequest, payload, sizeof(payload) - 1);
        }
        else
        {
            OC_LOG_V (INFO, TAG, "Received unsupported method %d from client",
                    entityHandlerRequest->method);
        }

        // If the result isn't an error or forbidden, send response
        if (!((ehResult == OC_EH_ERROR) || (ehResult == OC_EH_FORBIDDEN)))
        {
            // Format the response.  Note this requires some info about the request
            response.requestHandle = entityHandlerRequest->requestHandle;
            response.resourceHandle = entityHandlerRequest->resource;
            response.ehResult = ehResult;
            response.payload = (unsigned char *)payload;
            response.payloadSize = strlen(payload);
            // Indicate that response is NOT in a persistent buffer
            response.persistentBufferFlag = 0;

            // Handle vendor specific options
            if(entityHandlerRequest->rcvdVendorSpecificHeaderOptions &&
                    entityHandlerRequest->numRcvdVendorSpecificHeaderOptions)
            {
                OC_LOG (INFO, TAG, "Received vendor specific options");
                uint8_t i = 0;
                OCHeaderOption * rcvdOptions = entityHandlerRequest->rcvdVendorSpecificHeaderOptions;
                for( i = 0; i < entityHandlerRequest->numRcvdVendorSpecificHeaderOptions; i++)
                {
                    if(((OCHeaderOption)rcvdOptions[i]).protocolID == OC_COAP_ID)
                    {
                        OC_LOG_V(INFO, TAG, "Received option with OC_COAP_ID and ID %u with",
                                ((OCHeaderOption)rcvdOptions[i]).optionID );
                        OC_LOG_BUFFER(INFO, TAG, ((OCHeaderOption)rcvdOptions[i]).optionData,
                                ((OCHeaderOption)rcvdOptions[i]).optionLength);
                    }
                }
                OCHeaderOption * sendOptions = response.sendVendorSpecificHeaderOptions;
                uint8_t option2[] = {21,22,23,24,25,26,27,28,29,30};
                uint8_t option3[] = {31,32,33,34,35,36,37,38,39,40};
                sendOptions[0].protocolID = OC_COAP_ID;
                sendOptions[0].optionID = 2248;
                memcpy(sendOptions[0].optionData, option2, sizeof(option2));
                sendOptions[0].optionLength = 10;
                sendOptions[1].protocolID = OC_COAP_ID;
                sendOptions[1].optionID = 2600;
                memcpy(sendOptions[1].optionData, option3, sizeof(option3));
                sendOptions[1].optionLength = 10;
                response.numSendVendorSpecificHeaderOptions = 2;
            }

            // Send the response
            if (OCDoResponse(&response) != OC_STACK_OK)
            {
                OC_LOG(ERROR, TAG, "Error sending response");
                ehResult = OC_EH_ERROR;
            }
        }
    }
    if (flag & OC_OBSERVE_FLAG)
    {
        OC_LOG(INFO, TAG, "Flag includes OC_OBSERVE_FLAG");

        if (OC_OBSERVE_REGISTER == entityHandlerRequest->obsInfo.action)
        {
            OC_LOG (INFO, TAG, "Received OC_OBSERVE_REGISTER from client");
            ProcessObserveRegister (entityHandlerRequest);
        }
        else if (OC_OBSERVE_DEREGISTER == entityHandlerRequest->obsInfo.action)
        {
            OC_LOG (INFO, TAG, "Received OC_OBSERVE_DEREGISTER from client");
            ProcessObserveDeregister (entityHandlerRequest);
        }
    }

    return ehResult;
}
//This function is called back by libcoap when a response is received
static void HandleCoAPResponses(struct coap_context_t *ctx,
        const coap_queue_t * rcvdResponse) {
    OCResponse * response = NULL;
    OCCoAPToken rcvdToken;
    OCClientResponse clientResponse = {0};
    ClientCB * cbNode = NULL;
    unsigned char bufRes[MAX_RESPONSE_LENGTH] = {0};
    uint32_t sequenceNumber = OC_OBSERVE_NO_OPTION;
    uint32_t maxAge = 0;
    OCStackResult result = OC_STACK_ERROR;
    coap_pdu_t * sendPdu = NULL;
    coap_pdu_t * recvPdu = NULL;
    unsigned char rcvdUri[MAX_URI_LENGTH] = { 0 };
    uint8_t isObserveNotification = 0;
    #ifdef WITH_PRESENCE
    char * resourceTypeName = NULL;
    uint8_t remoteIpAddr[4];
    uint16_t remotePortNu;
    unsigned char fullUri[MAX_URI_LENGTH] = { 0 };
    uint8_t isPresenceNotification = 0;
    uint8_t isMulticastPresence = 0;
    uint32_t lowerBound;
    uint32_t higherBound;
    char * tok = NULL;
    #endif
    coap_block_t rcvdBlock1 = {COAP_BLOCK_FILL_VALUE};
    coap_block_t rcvdBlock2 = {COAP_BLOCK_FILL_VALUE};
    uint16_t rcvdSize2 = 0;

    VERIFY_NON_NULL(ctx);
    VERIFY_NON_NULL(rcvdResponse);
    recvPdu = rcvdResponse->pdu;

    result = ParseCoAPPdu(recvPdu, rcvdUri, NULL, &sequenceNumber, &maxAge,
            &clientResponse.numRcvdVendorSpecificHeaderOptions,
            clientResponse.rcvdVendorSpecificHeaderOptions,
            &rcvdBlock1, &rcvdBlock2, NULL, &rcvdSize2, bufRes);

    VERIFY_SUCCESS(result, OC_STACK_OK);

    OC_LOG_V(DEBUG, TAG, "The sequenceNumber/NONCE of this response %u", sequenceNumber);
    OC_LOG_V(DEBUG, TAG, "The maxAge/TTL of this response %u", maxAge);
    OC_LOG_V(DEBUG, TAG, "The response received is %s", bufRes);

    if(sequenceNumber >= OC_OFFSET_SEQUENCE_NUMBER)
    {
        isObserveNotification = 1;
        OC_LOG(INFO, TAG, PCF("Received an observe notification"));
    }

    #ifdef WITH_PRESENCE
    if(!strcmp((char *)rcvdUri, (char *)OC_PRESENCE_URI)){
        char* tokSavePtr;

        isPresenceNotification = 1;
        OC_LOG(INFO, TAG, PCF("Received a presence notification"));
        tok = strtok_r((char *)bufRes, "[:]}", &tokSavePtr);
        bufRes[strlen((char *)bufRes)] = ':';
        tok = strtok_r(NULL, "[:]}", &tokSavePtr);
        bufRes[strlen((char *)bufRes)] = ':';
        VERIFY_NON_NULL(tok);
        sequenceNumber = (uint32_t )atol(tok);
        OC_LOG_V(DEBUG, TAG, "The received NONCE is %u", sequenceNumber);
        tok = strtok_r(NULL, "[:]}", &tokSavePtr);
        VERIFY_NON_NULL(tok);
        maxAge = (uint32_t )atol(tok);
        OC_LOG_V(DEBUG, TAG, "The received TTL is %u", maxAge);
        tok = strtok_r(NULL, "[:]}", &tokSavePtr);
        if(tok) {
            bufRes[strlen((char *)bufRes)] = ':';
            resourceTypeName = (char *)OCMalloc(strlen(tok));
            if(!resourceTypeName)
            {
                goto exit;
            }
            strcpy(resourceTypeName, tok);
            OC_LOG_V(DEBUG, TAG, "----------------resourceTypeName %s",
                    resourceTypeName);
        }
        bufRes[strlen((char *)bufRes)] = ']';
    }
    #endif

    // fill OCCoAPToken structure
    RetrieveOCCoAPToken(recvPdu, &rcvdToken);
    OC_LOG_V(INFO, TAG,"Received a pdu with Token", rcvdToken.tokenLength);
    OC_LOG_BUFFER(INFO, TAG, rcvdToken.token, rcvdToken.tokenLength);

    // fill OCClientResponse structure
    result = FormOCClientResponse(&clientResponse, CoAPToOCResponseCode(recvPdu->hdr->code),
            (OCDevAddr *) &(rcvdResponse->remote), sequenceNumber, bufRes);
    VERIFY_SUCCESS(result, OC_STACK_OK);

    cbNode = GetClientCB(&rcvdToken, NULL, NULL);

    #ifdef WITH_PRESENCE
    // Check if the application subscribed for presence
    if(!cbNode)
    {
        // get the address of the remote
        OCDevAddrToIPv4Addr((OCDevAddr *) &(rcvdResponse->remote), remoteIpAddr,
                remoteIpAddr + 1, remoteIpAddr + 2, remoteIpAddr + 3);
        OCDevAddrToPort((OCDevAddr *) &(rcvdResponse->remote), &remotePortNu);
        snprintf((char *)fullUri, sizeof(fullUri), "coap://%d.%d.%d.%d:%d%s",
                remoteIpAddr[0],remoteIpAddr[1],remoteIpAddr[2],remoteIpAddr[3],
                remotePortNu,rcvdUri);
        cbNode = GetClientCB(NULL, NULL, fullUri);
    }

    // Check if application subscribed for multicast presence
    if(!cbNode)
    {
        snprintf((char *)fullUri, sizeof(fullUri), "%s%s", OC_MULTICAST_IP, rcvdUri);
        cbNode = GetClientCB(NULL, NULL, fullUri);
        isMulticastPresence = 1;
        isPresenceNotification = 0;
    }
    #endif

    // fill OCResponse structure
    result = FormOCResponse(&response, cbNode, maxAge, &clientResponse);
    VERIFY_SUCCESS(result, OC_STACK_OK);

    if(cbNode)
    {
        if(!isObserveNotification)
        {
            #ifdef WITH_PRESENCE
            if(!isPresenceNotification)
            {
            #endif
                OC_LOG(INFO, TAG, PCF("Received a regular response"));
                if(recvPdu->hdr->type == COAP_MESSAGE_CON)
                {
                    sendPdu = GenerateCoAPPdu(COAP_MESSAGE_ACK, 0,
                            recvPdu->hdr->id, NULL, NULL, NULL);
                    VERIFY_NON_NULL(sendPdu);
                    result = SendCoAPPdu(gCoAPCtx, (coap_address_t*) &rcvdResponse->remote,
                            sendPdu,
                            (coap_send_flags_t)(rcvdResponse->secure ? SEND_SECURE_PORT : 0));
                }
            #ifdef WITH_PRESENCE
            }
            #endif
        }
        if(isObserveNotification)
        {
            OC_LOG(INFO, TAG, PCF("Received an observe notification"));
            if(recvPdu->hdr->type == COAP_MESSAGE_CON)
            {
                sendPdu = GenerateCoAPPdu(COAP_MESSAGE_ACK, 0,
                        recvPdu->hdr->id, NULL, NULL, NULL);
                VERIFY_NON_NULL(sendPdu);
                result = SendCoAPPdu(gCoAPCtx, (coap_address_t*) &rcvdResponse->remote,
                        sendPdu,
                        (coap_send_flags_t)(rcvdResponse->secure ? SEND_SECURE_PORT : 0));
            }
            //TODO: check the standard for methods to detect wrap around condition
            if(cbNode->method == OC_REST_OBSERVE &&
                    (clientResponse.sequenceNumber <= cbNode->sequenceNumber ||
                            (clientResponse.sequenceNumber > cbNode->sequenceNumber &&
                                    clientResponse.sequenceNumber == (MAX_SEQUENCE_NUMBER))))
            {
                OC_LOG_V(DEBUG, TAG, "Observe notification came out of order. \
                        Ignoring Incoming:%d  Against Current:%d.",
                        clientResponse.sequenceNumber, cbNode->sequenceNumber);
                goto exit;
            }
            if(clientResponse.sequenceNumber > cbNode->sequenceNumber){
                cbNode->sequenceNumber = clientResponse.sequenceNumber;
            }
        }
        else
        {
            #ifdef WITH_PRESENCE
            if(isPresenceNotification)
//This function is called back by libcoap when a request is received
static void HandleCoAPRequests(struct coap_context_t *ctx,
        const coap_queue_t * rcvdRequest)
{
    // silence warnings
    (void) ctx;
    OCServerProtocolRequest protocolRequest = {(OCMethod)0};
    coap_block_t rcvdBlock1;
    coap_block_t rcvdBlock2;
    memset(&rcvdBlock1, COAP_BLOCK_FILL_VALUE, sizeof(coap_block_t));
    memset(&rcvdBlock2, COAP_BLOCK_FILL_VALUE, sizeof(coap_block_t));
    uint16_t rcvdSize1 = 0;
    coap_pdu_t * rcvdPdu = rcvdRequest->pdu;
    coap_pdu_t * sendPdu = NULL;
    coap_send_flags_t sendFlag;
    OCStackResult result = OC_STACK_ERROR;
    OCStackResult requestResult = OC_STACK_ERROR;

    if(myStackMode == OC_CLIENT)
    {
        //TODO: should the client be responding to requests?
        return;
    }

    protocolRequest.observationOption = OC_OBSERVE_NO_OPTION;
    protocolRequest.qos = (rcvdPdu->hdr->type == COAP_MESSAGE_CON) ?
            OC_HIGH_QOS : OC_LOW_QOS;
    protocolRequest.coapID = rcvdPdu->hdr->id;
    protocolRequest.delayedResNeeded = rcvdRequest->delayedResNeeded;
    protocolRequest.secured = rcvdRequest->secure;

    // fill OCCoAPToken structure
    RetrieveOCCoAPToken(rcvdPdu, &protocolRequest.requestToken);
    OC_LOG_V(INFO, TAG, " Token received %d bytes",
            protocolRequest.requestToken.tokenLength);
    OC_LOG_BUFFER(INFO, TAG, protocolRequest.requestToken.token,
            protocolRequest.requestToken.tokenLength);

    // fill OCDevAddr
    memcpy(&protocolRequest.requesterAddr, (OCDevAddr *) &rcvdRequest->remote,
            sizeof(OCDevAddr));

    // Retrieve Uri and Query from received coap pdu
    result =  ParseCoAPPdu(rcvdPdu, protocolRequest.resourceUrl,
            protocolRequest.query,
            &(protocolRequest.observationOption), NULL,
            &(protocolRequest.numRcvdVendorSpecificHeaderOptions),
            protocolRequest.rcvdVendorSpecificHeaderOptions,
            &rcvdBlock1, &rcvdBlock2, &rcvdSize1, NULL,
            protocolRequest.reqJSONPayload);
    VERIFY_SUCCESS(result, OC_STACK_OK);

    switch (rcvdPdu->hdr->code)
    {
        case COAP_REQUEST_GET:
        {
            protocolRequest.method = OC_REST_GET;
            break;
        }
        case COAP_REQUEST_POST:
        {
            protocolRequest.method = OC_REST_POST;
            break;
        }
        case COAP_REQUEST_DELETE:
        {
            protocolRequest.method = OC_REST_DELETE;
            break;
        }
        case COAP_REQUEST_PUT:
        {
            protocolRequest.method = OC_REST_PUT;
            break;
        }
        default:
        {
            OC_LOG_V(ERROR, TAG, "Received CoAP method %d not supported",
                    rcvdPdu->hdr->code);
            goto exit;
        }
    }

    if(rcvdBlock1.szx != 7)
    {
        protocolRequest.reqPacketSize = 1 << (rcvdBlock1.szx + 4);
        protocolRequest.reqMorePacket = rcvdBlock1.m;
        protocolRequest.reqPacketNum  = rcvdBlock1.num;
    }
    else
    {
        // No block1 received
        rcvdSize1 = strlen((const char *)protocolRequest.reqJSONPayload)+1;
        protocolRequest.reqTotalSize = rcvdSize1;
    }

    if(rcvdBlock2.szx != 7)
    {
        protocolRequest.resPacketSize = 1 << (rcvdBlock2.szx + 4);
        protocolRequest.resPacketNum  = rcvdBlock2.num;
    }

    requestResult = HandleStackRequests(&protocolRequest);

    if(requestResult == OC_STACK_VIRTUAL_DO_NOT_HANDLE ||
            requestResult == OC_STACK_OK ||
            requestResult == OC_STACK_RESOURCE_CREATED ||
            requestResult == OC_STACK_RESOURCE_DELETED ||
            requestResult == OC_STACK_INVALID_DEVICE_INFO)
    {
        goto exit;
    }
    else if(requestResult == OC_STACK_NO_MEMORY ||
            requestResult == OC_STACK_ERROR ||
            requestResult == OC_STACK_NOTIMPL ||
            requestResult == OC_STACK_NO_RESOURCE ||
            requestResult == OC_STACK_RESOURCE_ERROR)
    {
        // TODO: should we send an error also when we receive a non-secured request to a secure resource?
        // TODO: should we consider some sort of error response
        OC_LOG(DEBUG, TAG, PCF("We should send some sort of error message"));
        // generate the pdu, if the request was CON, then the response is ACK, otherwire NON
        sendPdu = GenerateCoAPPdu((rcvdPdu->hdr->type == COAP_MESSAGE_CON)? COAP_MESSAGE_ACK : COAP_MESSAGE_NON,
                OCToCoAPResponseCode(requestResult), rcvdPdu->hdr->id,
                &protocolRequest.requestToken, NULL, NULL);
        VERIFY_NON_NULL(sendPdu);
        coap_show_pdu(sendPdu);
        sendFlag = (coap_send_flags_t)(rcvdRequest->secure ? SEND_SECURE_PORT : 0);
        if(SendCoAPPdu(gCoAPCtx, (coap_address_t*) &(rcvdRequest->remote), sendPdu,
                sendFlag)
                != OC_STACK_OK){
            OC_LOG(DEBUG, TAG, PCF("A problem occurred in sending a pdu"));
        }
        goto exit;
    }
    else if(requestResult == OC_STACK_SLOW_RESOURCE)
    {
        if(rcvdPdu->hdr->type == COAP_MESSAGE_CON)
        {
            // generate the pdu, if the request was CON, then the response is ACK, otherwire NON
            sendPdu = GenerateCoAPPdu(COAP_MESSAGE_ACK, 0, rcvdPdu->hdr->id,
                    NULL, NULL, NULL);
            VERIFY_NON_NULL(sendPdu);
            coap_show_pdu(sendPdu);

            sendFlag = (coap_send_flags_t)(rcvdRequest->secure ? SEND_SECURE_PORT : 0);
            if(SendCoAPPdu(gCoAPCtx, (coap_address_t*) &(rcvdRequest->remote), sendPdu,
                    sendFlag)
                    != OC_STACK_OK){
                OC_LOG(DEBUG, TAG, PCF("A problem occurred in sending a pdu"));
            }
        }
        else
        {
            goto exit;
        }
    }
exit:
    return;
}
//Start sample app 'sendrecv' on different Linux box.
void SendReceiveTest()
{
    Serial.println("entering SendReceiveTest...");
    OCDevAddr ipAddr, peerAddr, recvAddr;
    int32_t sfd;
    int32_t recvLen;
    uint8_t buf[MAX_BUF_SIZE];
    uint16_t recvPort;

    VERIFY_SUCCESS(OCBuildIPv4Address( 0, 0, 0, 0, TEST_PORT_NUM, &ipAddr), ERR_SUCCESS);
    VERIFY_SUCCESS(OCBuildIPv4Address(PEER_IP_ADDR[0], PEER_IP_ADDR[1],
                PEER_IP_ADDR[2], PEER_IP_ADDR[3], TEST_PORT_NUM, &peerAddr), ERR_SUCCESS);
    VERIFY_SUCCESS(OCInitUDP( &ipAddr, &sfd), ERR_SUCCESS);
    OC_LOG(DEBUG, MOD_NAME, PCF("Peer Addr :"));
    OC_LOG_BUFFER(INFO, MOD_NAME, peerAddr.addr, peerAddr.size);
    for (int i = 0; i < 300; i++)
    {

        OC_LOG_V(DEBUG, MOD_NAME, "--------------------- i --------------- %d", i);
        VERIFY_SUCCESS(OCSendTo(sfd, TEST_BUF, i + 10, 0, &peerAddr), i+10);

        delay(2000);
        recvLen = OCRecvFrom(sfd, buf, MAX_BUF_SIZE, 0, &recvAddr);
        if (recvLen > 0)
        {
            OC_LOG(DEBUG, MOD_NAME, PCF("Rcvd data from :"));
            OC_LOG_BUFFER(INFO, MOD_NAME, recvAddr.addr, recvAddr.size);
            OCDevAddrToPort(&recvAddr, &recvPort);
            OC_LOG_V(DEBUG, MOD_NAME, "Recv Data from Port %hu", recvPort);
            OC_LOG(DEBUG, MOD_NAME, PCF("Data Length :"));
            OC_LOG_BUFFER(INFO, MOD_NAME, (uint8_t*)&recvLen, sizeof(recvLen));
            OC_LOG(DEBUG, MOD_NAME, PCF("Data :"));
            if (recvLen < 255)
            {
                OC_LOG_BUFFER(INFO, MOD_NAME, buf, recvLen);
            }
            else
            {
                int idx = 0;
                int rem = recvLen;
                do {
                    if (rem > 255)
                    {
                        OC_LOG_BUFFER(INFO, MOD_NAME, buf + idx, 255);
                        rem = rem - 255;
                    }
                    else
                    {
                        OC_LOG_BUFFER(INFO, MOD_NAME, buf + idx, rem);
                        rem = 0;
                    }
                    idx = idx + 255;
                }while(rem > 0);
            }

        }
    }
    VERIFY_SUCCESS(OCClose( sfd), ERR_SUCCESS);
    OC_LOG(DEBUG, MOD_NAME, PCF("WifiTest - Completed"));

}