Exemple #1
0
void CALogPDUInfo(coap_pdu_t *pdu, const CAEndpoint_t *endpoint)
{
    VERIFY_NON_NULL_VOID(pdu, TAG, "pdu");

    OIC_LOG_V(DEBUG, TAG, "PDU Maker - payload : %s", pdu->data);

#ifdef TCP_ADAPTER
    if (CA_ADAPTER_TCP == endpoint->adapter)
    {
        OIC_LOG(DEBUG, TAG, "pdu header data :");
        OIC_LOG_BUFFER(DEBUG, TAG,  pdu->hdr, pdu->length);
    }
    else
#else
    (void) endpoint;
#endif
    {
        OIC_LOG_V(DEBUG, TAG, "PDU Maker - type : %d", pdu->hdr->coap_hdr_udp_t.type);

        OIC_LOG_V(DEBUG, TAG, "PDU Maker - code : %d", pdu->hdr->coap_hdr_udp_t.code);

        OIC_LOG(DEBUG, TAG, "PDU Maker - token :");

        OIC_LOG_BUFFER(DEBUG, TAG, pdu->hdr->coap_hdr_udp_t.token,
                       pdu->hdr->coap_hdr_udp_t.token_length);
    }
}
Exemple #2
0
static void CALogPayloadInfo(CAInfo_t *info)
{
    if(info)
    {
        if (info->options)
        {
            for (uint32_t i = 0; i < info->numOptions; i++)
            {
                OIC_LOG_V(DEBUG, TAG, "optionID: %d", info->options[i].optionID);

                OIC_LOG_V(DEBUG, TAG, "list: %s", info->options[i].optionData);
            }
        }

        if (info->payload)
        {
            OIC_LOG_V(DEBUG, TAG, "payload: %p(%zu)", info->payload,
                      info->payloadSize);
        }

        if (info->token)
        {
            OIC_LOG(DEBUG, TAG, "token:");
            OIC_LOG_BUFFER(DEBUG, TAG, (const uint8_t *) info->token,
                           info->tokenLength);
        }
        OIC_LOG_V(DEBUG, TAG, "msgID: %d", info->messageId);
    }
    else
    {
        OIC_LOG(DEBUG, TAG, "info is NULL, cannot output log data");
    }
}
OCStackResult displayNumCB(void * ctx, uint8_t mutualVerifNum[MUTUAL_VERIF_NUM_LEN])
{
    OIC_LOG(INFO, TAG, "IN displayNumCB");
    OIC_LOG(INFO, TAG, "############ mutualVerifNum ############");
    OIC_LOG_BUFFER(INFO, TAG, mutualVerifNum, MUTUAL_VERIF_NUM_LEN);
    OIC_LOG(INFO, TAG, "############ mutualVerifNum ############");
    OIC_LOG(INFO, TAG, "OUT displayNumCB");
    return OC_STACK_OK;
}
Exemple #4
0
ClientCB* GetClientCB(const CAToken_t token, uint8_t tokenLength,
                      OCDoHandle handle, const char * requestUri)
{
    ClientCB* out = NULL;

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

            if (memcmp(out->token, token, tokenLength) == 0)
            {
                return out;
            }
            CheckAndDeleteTimedOutCB(out);
        }
/**
 * Get a server request from the server request list using the specified token.
 *
 * @param token - token of server request
 * @param tokenLength - length of token
 *
 * @return
 *     OCServerRequest*
 */
OCServerRequest * GetServerRequestUsingToken (const CAToken_t token, uint8_t tokenLength)
{
    if(!token)
    {
        OIC_LOG(ERROR, TAG, "Invalid Parameter Token");
        return NULL;
    }

    OCServerRequest * out = NULL;
    OIC_LOG(INFO, TAG,"Get server request with token");
    OIC_LOG_BUFFER(INFO, TAG, (const uint8_t *)token, tokenLength);

    OIC_LOG(INFO, TAG,"Found token");
    LL_FOREACH (serverRequestList, out)
    {
        OIC_LOG_BUFFER(INFO, TAG, (const uint8_t *)out->requestToken, tokenLength);
        if(memcmp(out->requestToken, token, tokenLength) == 0)
        {
            return out;
        }
    }
void CALogPDUInfo(coap_pdu_t *pdu)
{
    VERIFY_NON_NULL_VOID(pdu, TAG, "pdu");

    OIC_LOG_V(DEBUG, TAG, "PDU Maker - payload : %s", pdu->data);

    OIC_LOG_V(DEBUG, TAG, "PDU Maker - type : %d", pdu->hdr->type);

    OIC_LOG_V(DEBUG, TAG, "PDU Maker - code : %d", pdu->hdr->code);

    OIC_LOG(DEBUG, TAG, "PDU Maker - token :");

    OIC_LOG_BUFFER(DEBUG, TAG, pdu->hdr->token, pdu->hdr->token_length);
}
Exemple #7
0
void DeleteClientCB(ClientCB * cbNode)
{
    if (cbNode)
    {
        LL_DELETE(cbList, cbNode);
        OIC_LOG (INFO, TAG, "Deleting token");
        OIC_LOG_BUFFER(INFO, TAG, (const uint8_t *)cbNode->token, cbNode->tokenLength);
        CADestroyToken (cbNode->token);
        OICFree(cbNode->devAddr);
        OICFree(cbNode->handle);
        OIC_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;
    }
}
OCStackApplicationResult getReqCB(void* ctx, OCDoHandle /*handle*/,
                                  OCClientResponse * clientResponse)
{
    if (clientResponse == NULL)
    {
        OIC_LOG(INFO, TAG, "getReqCB received NULL clientResponse");
        return   OC_STACK_DELETE_TRANSACTION;
    }

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

    OIC_LOG_V(INFO, TAG, "StackResult: %s",  getResult(clientResponse->result));
    OIC_LOG_V(INFO, TAG, "SEQUENCE NUMBER: %d", clientResponse->sequenceNumber);
    OIC_LOG_PAYLOAD(INFO, clientResponse->payload);
    OIC_LOG(INFO, TAG, ("=============> Get Response"));

    if (clientResponse->numRcvdVendorSpecificHeaderOptions > 0)
    {
        OIC_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)
            {
                OIC_LOG_V(INFO, TAG, "Received option with OC_COAP_ID and ID %u with",
                        ((OCHeaderOption)rcvdOptions[i]).optionID );

                OIC_LOG_BUFFER(INFO, TAG, ((OCHeaderOption)rcvdOptions[i]).optionData,
                    MAX_HEADER_OPTION_DATA_LENGTH);
            }
        }
    }
    return OC_STACK_DELETE_TRANSACTION;
}
OCStackResult OCConvertPayload(OCPayload* payload, uint8_t** outPayload, size_t* size)
{
    // TinyCbor Version 47a78569c0 or better on master is required for the re-allocation
    // strategy to work.  If you receive the following assertion error, please do a git-pull
    // from the extlibs/tinycbor/tinycbor directory
    #define CborNeedsUpdating  (CborErrorOutOfMemory < CborErrorDataTooLarge)
    OC_STATIC_ASSERT(!CborNeedsUpdating, "tinycbor needs to be updated to at least 47a78569c0");
    #undef CborNeedsUpdating

    OCStackResult ret = OC_STACK_INVALID_PARAM;
    int64_t err;
    uint8_t *out = NULL;
    size_t curSize = INIT_SIZE;

    VERIFY_PARAM_NON_NULL(TAG, payload, "Input param, payload is NULL");
    VERIFY_PARAM_NON_NULL(TAG, outPayload, "OutPayload parameter is NULL");
    VERIFY_PARAM_NON_NULL(TAG, size, "size parameter is NULL");

    OIC_LOG_V(INFO, TAG, "Converting payload of type %d", payload->type);
    if (PAYLOAD_TYPE_SECURITY == payload->type)
    {
        size_t securityPayloadSize = ((OCSecurityPayload *)payload)->payloadSize;
        if (securityPayloadSize > 0)
        {
            out = (uint8_t *)OICCalloc(1, ((OCSecurityPayload *)payload)->payloadSize);
            VERIFY_PARAM_NON_NULL(TAG, out, "Failed to allocate security payload");
        }
    }
    if (out == NULL)
    {
        out = (uint8_t *)OICCalloc(1, curSize);
        VERIFY_PARAM_NON_NULL(TAG, out, "Failed to allocate payload");
    }
    err = OCConvertPayloadHelper(payload, out, &curSize);
    ret = OC_STACK_NO_MEMORY;

    if (err == CborErrorOutOfMemory)
    {
        // reallocate "out" and try again!
        uint8_t *out2 = (uint8_t *)OICRealloc(out, curSize);
        VERIFY_PARAM_NON_NULL(TAG, out2, "Failed to increase payload size");
        out = out2;
        err = OCConvertPayloadHelper(payload, out, &curSize);
        while (err == CborErrorOutOfMemory)
        {
            uint8_t *out2 = (uint8_t *)OICRealloc(out, curSize);
            VERIFY_PARAM_NON_NULL(TAG, out2, "Failed to increase payload size");
            out = out2;
            err = OCConvertPayloadHelper(payload, out, &curSize);
        }
    }

    if (err == CborNoError)
    {
        if (curSize < INIT_SIZE && PAYLOAD_TYPE_SECURITY != payload->type)
        {
            uint8_t *out2 = (uint8_t *)OICRealloc(out, curSize);
            VERIFY_PARAM_NON_NULL(TAG, out2, "Failed to increase payload size");
            out = out2;
        }

        *size = curSize;
        *outPayload = out;
        OIC_LOG_V(DEBUG, TAG, "Payload Size: %zd Payload : ", *size);
        OIC_LOG_BUFFER(DEBUG, TAG, *outPayload, *size);
        return OC_STACK_OK;
    }

    //TODO: Proper conversion from CborError to OCStackResult.
    ret = (OCStackResult)-err;

exit:
    OICFree(out);
    return ret;
}
static void CAReceivedPacketCallback(CAEndpoint_t *endpoint, void *data, uint32_t dataLen)
{
    OIC_LOG(DEBUG, TAG, "IN");
    VERIFY_NON_NULL_VOID(data, TAG, "data");

    uint32_t code = CA_NOT_FOUND;
    coap_pdu_t *pdu = (coap_pdu_t *) CAParsePDU((const char *) data, dataLen, &code);
    OICFree(data);
    if (NULL == pdu)
    {
        OIC_LOG(ERROR, TAG, "Parse PDU failed");
        return;
    }

    char uri[CA_MAX_URI_LENGTH] = { };

    if (CA_GET == code || CA_POST == code || CA_PUT == code || CA_DELETE == code)
    {
        CARequestInfo_t *ReqInfo = (CARequestInfo_t *) OICCalloc(1, sizeof(CARequestInfo_t));
        if (NULL == ReqInfo)
        {
            OIC_LOG(ERROR, TAG, "CAReceivedPacketCallback, Memory allocation failed!");
            coap_delete_pdu(pdu);
            return;
        }

        CAResult_t res = CAGetRequestInfoFromPDU(pdu, ReqInfo);
        if (CA_STATUS_OK != res)
        {
            OIC_LOG_V(ERROR, TAG, "CAGetRequestInfoFromPDU failed : %d", res);
            OICFree(ReqInfo);
            coap_delete_pdu(pdu);
            return;
        }

        if (NULL != ReqInfo->info.options)
        {
            for (uint32_t i = 0; i < ReqInfo->info.numOptions; i++)
            {
                OIC_LOG_V(DEBUG, TAG, "optionID: %d", ReqInfo->info.options[i].optionID);

                OIC_LOG_V(DEBUG, TAG, "list: %s", ReqInfo->info.options[i].optionData);
            }
        }

        if (NULL != ReqInfo->info.payload)
        {
            OIC_LOG_V(DEBUG, TAG, "Request- payload: %s", ReqInfo->info.payload);
        }

        OIC_LOG_V(DEBUG, TAG, "code: %d", ReqInfo->method);
        OIC_LOG(DEBUG, TAG, "token:");
        OIC_LOG_BUFFER(DEBUG, TAG, (const uint8_t *) ReqInfo->info.token, CA_MAX_TOKEN_LEN);

        if (g_requestHandler)
        {
            g_requestHandler(endpoint, ReqInfo);
        }

        CADestroyRequestInfoInternal(ReqInfo);
    }
    else
    {
        CAResponseInfo_t *ResInfo = (CAResponseInfo_t *) OICCalloc(1, sizeof(CAResponseInfo_t));
        if (NULL == ResInfo)
        {
            OIC_LOG(ERROR, TAG, "CAReceivedPacketCallback, Memory allocation failed!");
            coap_delete_pdu(pdu);
            return;
        }

        CAResult_t res = CAGetResponseInfoFromPDU(pdu, ResInfo);
        if (CA_STATUS_OK != res)
        {
            OIC_LOG_V(ERROR, TAG, "CAGetResponseInfoFromPDU failed : %d", res);
            OICFree(ResInfo);
            coap_delete_pdu(pdu);
            return;
        }

        if (NULL != ResInfo->info.options)
        {
            for (uint32_t i = 0; i < ResInfo->info.numOptions; i++)
            {
                OIC_LOG_V(DEBUG, TAG, "optionID: %d", ResInfo->info.options[i].optionID);

                OIC_LOG_V(DEBUG, TAG, "list: %s", ResInfo->info.options[i].optionData);
            }
        }

        if (NULL != ResInfo->info.payload)
        {
            OIC_LOG_V(DEBUG, TAG, "payload: %s", ResInfo->info.payload);
        }
        OIC_LOG_V(DEBUG, TAG, "code: %d", ResInfo->result);

        // for retransmission
        void *retransmissionPdu = NULL;
        CARetransmissionReceivedData(&g_retransmissionContext, endpoint, pdu->hdr, pdu->length,
                                     &retransmissionPdu);

        // get token from saved data in retransmission list
        if (retransmissionPdu && CA_EMPTY == code)
        {
            CAResult_t res = CAGetTokenFromPDU((const coap_hdr_t *)retransmissionPdu,
                                               &(ResInfo->info));
            if(CA_STATUS_OK != res)
            {
                OIC_LOG(ERROR, TAG, "fail to get Token from retransmission list");
                OICFree(ResInfo->info.token);
            }
        }
        OICFree(retransmissionPdu);

        if (NULL != ResInfo)
        {
            if (g_responseHandler)
            {
                g_responseHandler(endpoint, ResInfo);
            }
            CADestroyResponseInfoInternal(ResInfo);
        }
    }

    if (pdu)
    {
        coap_delete_pdu(pdu);
    }
    OIC_LOG(DEBUG, TAG, "OUT");
}
CAResult_t CAGenerateTokenInternal(CAToken_t *token, uint8_t tokenLength)
{
    OIC_LOG(DEBUG, TAG, "IN");

    if (!token)
    {
        OIC_LOG(ERROR, TAG, "invalid token pointer");
        return CA_STATUS_INVALID_PARAM;
    }

    if ((tokenLength > CA_MAX_TOKEN_LEN) || (0 == tokenLength))
    {
        OIC_LOG(ERROR, TAG, "invalid token length");
        return CA_STATUS_INVALID_PARAM;
    }

    if (SEED == 0)
    {
#ifdef ARDUINO
        SEED = now();
#else
        SEED = time(NULL);
#endif
        if (SEED == (unsigned int)((time_t)-1))
        {
            OIC_LOG(ERROR, TAG, "seed is not made");
            SEED = 0;
            return CA_STATUS_FAILED;
        }
#if HAVE_SRANDOM
        srandom(SEED);
#else
        srand(SEED);
#endif
    }

    // memory allocation
    char *temp = (char *) OICCalloc(tokenLength, sizeof(char));
    if (NULL == temp)
    {
        OIC_LOG(ERROR, TAG, "Out of memory");
        return CA_MEMORY_ALLOC_FAILED;
    }

    // set random byte
    for (uint8_t index = 0; index < tokenLength; index++)
    {
        // use valid characters
#ifdef ARDUINO
        temp[index] = rand() & 0x00FF;
#else
        temp[index] = random() & 0x00FF;
#endif
    }

    // save token
    *token = temp;

    OIC_LOG_V(DEBUG, TAG, "token len:%d, token:", tokenLength);
    OIC_LOG_BUFFER(DEBUG, TAG, (const uint8_t *)(*token), tokenLength);

    OIC_LOG(DEBUG, TAG, "OUT");
    return CA_STATUS_OK;
}
coap_pdu_t *CAGeneratePDUImpl(code_t code, coap_list_t *options, const CAInfo_t *info,
                              const CAEndpoint_t *endpoint)
{
    OIC_LOG(DEBUG, TAG, "IN");
    VERIFY_NON_NULL_RET(info, TAG, "info", NULL);
    VERIFY_NON_NULL_RET(endpoint, TAG, "endpoint", NULL);

    coap_pdu_t *pdu = coap_new_pdu();

    if (NULL == pdu)
    {
        OIC_LOG(ERROR, TAG, "malloc failed");
        return NULL;
    }

    OIC_LOG_V(DEBUG, TAG, "msgID is %d", info->messageId);
    uint16_t message_id;
    if (0 == info->messageId)
    {
        /* initialize message id */
        prng((uint8_t * ) &message_id, sizeof(message_id));

        OIC_LOG_V(DEBUG, TAG, "gen msg id=%d", message_id);
    }
    else
    {
        /* use saved message id */
        message_id = info->messageId;
    }
    pdu->hdr->id = message_id;
    OIC_LOG_V(DEBUG, TAG, "messageId in pdu is %d, %d", message_id, pdu->hdr->id);

    pdu->hdr->type = info->type;
    pdu->hdr->code = COAP_RESPONSE_CODE(code);

    if (info->token && CA_EMPTY != code)
    {
        uint32_t tokenLength = info->tokenLength;
        OIC_LOG_V(DEBUG, TAG, "token info token length: %d, token :", tokenLength);
        OIC_LOG_BUFFER(DEBUG, TAG, (const uint8_t *)info->token, tokenLength);

        int32_t ret = coap_add_token(pdu, tokenLength, (unsigned char *)info->token);
        if (0 == ret)
        {
            OIC_LOG(ERROR, TAG, "can't add token");
        }
    }

    if (options)
    {
        for (coap_list_t *opt = options; opt; opt = opt->next)
        {
            OIC_LOG_V(DEBUG, TAG, "[%s] opt will be added.",
                      COAP_OPTION_DATA(*(coap_option *) opt->data));
            coap_add_option(pdu, COAP_OPTION_KEY(*(coap_option *) opt->data),
                            COAP_OPTION_LENGTH(*(coap_option *) opt->data),
                            COAP_OPTION_DATA(*(coap_option *) opt->data));
        }
    }

    bool enabledPayload = false;
#ifndef WITH_BWT
    enabledPayload = true;
#endif

    if (enabledPayload || CA_ADAPTER_GATT_BTLE == endpoint->adapter)
    {
        if (NULL != info->payload && 0 < info->payloadSize)
        {
            OIC_LOG(DEBUG, TAG, "payload is added");
            coap_add_data(pdu, info->payloadSize, (const unsigned char *) info->payload);
        }
    }

    OIC_LOG(DEBUG, TAG, "OUT");
    return pdu;
}
Exemple #13
0
int32_t GetDtlsPskForRandomPinOxm( CADtlsPskCredType_t type,
              const unsigned char *UNUSED1, size_t UNUSED2,
              unsigned char *result, size_t result_length)
{
    int32_t ret = -1;

    (void)UNUSED1;
    (void)UNUSED2;

    if (NULL == result || result_length < OWNER_PSK_LENGTH_128)
    {
        return ret;
    }

    switch (type)
    {
        case CA_DTLS_PSK_HINT:
        case CA_DTLS_PSK_IDENTITY:
            /**
             * The server will provide PSK hint to identify PSK according to RFC 4589 and RFC 4279.
             *
             * At this point, The server generate random hint and
             * provide it to client through server key exchange message.
             */
            OCFillRandomMem(result, result_length);
            ret = result_length;

            OIC_LOG(DEBUG, TAG, "PSK HINT : ");
            OIC_LOG_BUFFER(DEBUG, TAG, result, result_length);
            break;

        case CA_DTLS_PSK_KEY:
            {
                int dtlsRes = DeriveCryptoKeyFromPassword(
                                                          (const unsigned char *)g_PinOxmData.pinData,
                                                          OXM_RANDOM_PIN_SIZE,
                                                          g_PinOxmData.newDevice.id,
                                                          UUID_LENGTH, PBKDF_ITERATIONS,
                                                          OWNER_PSK_LENGTH_128, (uint8_t*)result);

                OIC_LOG_V(DEBUG, TAG, "DeriveCryptoKeyFromPassword Completed (%d)", dtlsRes);
                OIC_LOG_V(DEBUG, TAG, "PIN : %s", g_PinOxmData.pinData);
                OIC_LOG(DEBUG, TAG, "UUID : ");
                OIC_LOG_BUFFER(DEBUG, TAG, g_PinOxmData.newDevice.id, UUID_LENGTH);

                if(0 == dtlsRes)
                {
                    ret = OWNER_PSK_LENGTH_128;
                }
                else
                {
                    OIC_LOG_V(ERROR, TAG, "Failed to derive crypto key from PIN : result=%d", dtlsRes);
                    ret = -1;
                }
            }
            break;

        default:
            {
                OIC_LOG (ERROR, TAG, "Wrong value passed for CADtlsPskCredType_t.");
                ret = -1;
            }
            break;
    }

    return ret;
}
Exemple #14
0
static CAResult_t CAProcessSendData(const CAData_t *data)
{
    VERIFY_NON_NULL(data, TAG, "data");
    VERIFY_NON_NULL(data->remoteEndpoint, TAG, "remoteEndpoint");

    CAResult_t res = CA_STATUS_FAILED;

    CASendDataType_t type = data->type;

    coap_pdu_t *pdu = NULL;
    CAInfo_t *info = NULL;
    coap_list_t *options = NULL;
    coap_transport_type transport;

    if (SEND_TYPE_UNICAST == type)
    {
        OIC_LOG(DEBUG,TAG,"Unicast message");
#ifdef ROUTING_GATEWAY
        /*
         * When forwarding a packet, do not attempt retransmission as its the responsibility of
         * packet originator node
         */
        bool skipRetransmission = false;
#endif

        if (NULL != data->requestInfo)
        {
            OIC_LOG(DEBUG, TAG, "requestInfo is available..");

            info = &data->requestInfo->info;
#ifdef ROUTING_GATEWAY
            skipRetransmission = data->requestInfo->info.skipRetransmission;
#endif
            pdu = CAGeneratePDU(data->requestInfo->method, info, data->remoteEndpoint,
                                &options, &transport);
        }
        else if (NULL != data->responseInfo)
        {
            OIC_LOG(DEBUG, TAG, "responseInfo is available..");

            info = &data->responseInfo->info;
#ifdef ROUTING_GATEWAY
            skipRetransmission = data->responseInfo->info.skipRetransmission;
#endif
            pdu = CAGeneratePDU(data->responseInfo->result, info, data->remoteEndpoint,
                                &options, &transport);
        }
        else
        {
            OIC_LOG(DEBUG, TAG, "request info, response info is empty");
            return CA_STATUS_INVALID_PARAM;
        }

        // interface controller function call.
        if (NULL != pdu)
        {
#ifdef WITH_BWT
            if (CA_ADAPTER_GATT_BTLE != data->remoteEndpoint->adapter
#ifdef TCP_ADAPTER
                    && CA_ADAPTER_TCP != data->remoteEndpoint->adapter
#endif
                    )
            {
                // Blockwise transfer
                if (NULL != info)
                {
                    CAResult_t res = CAAddBlockOption(&pdu, info,
                                                      data->remoteEndpoint,
                                                      &options);
                    if (CA_STATUS_OK != res)
                    {
                        OIC_LOG(INFO, TAG, "to write block option has failed");
                        CAErrorHandler(data->remoteEndpoint, pdu->hdr, pdu->length, res);
                        coap_delete_list(options);
                        coap_delete_pdu(pdu);
                        return res;
                    }
                }
            }
#endif
            CALogPDUInfo(pdu, data->remoteEndpoint);

            res = CASendUnicastData(data->remoteEndpoint, pdu->hdr, pdu->length);
            if (CA_STATUS_OK != res)
            {
                OIC_LOG_V(ERROR, TAG, "send failed:%d", res);
                CAErrorHandler(data->remoteEndpoint, pdu->hdr, pdu->length, res);
                coap_delete_list(options);
                coap_delete_pdu(pdu);
                return res;
            }

#ifdef TCP_ADAPTER
            if (CA_ADAPTER_TCP == data->remoteEndpoint->adapter)
            {
                OIC_LOG(INFO, TAG, "retransmission will be not worked");
            }
            else
#endif
#ifdef ROUTING_GATEWAY
            if(!skipRetransmission)
#endif
            {
                // for retransmission
                res = CARetransmissionSentData(&g_retransmissionContext, data->remoteEndpoint,
                                               pdu->hdr, pdu->length);
                if ((CA_STATUS_OK != res) && (CA_NOT_SUPPORTED != res))
                {
                    //when retransmission not supported this will return CA_NOT_SUPPORTED, ignore
                    OIC_LOG_V(INFO, TAG, "retransmission is not enabled due to error, res : %d", res);
                    coap_delete_list(options);
                    coap_delete_pdu(pdu);
                    return res;
                }
            }

            coap_delete_list(options);
            coap_delete_pdu(pdu);
        }
        else
        {
            OIC_LOG(ERROR,TAG,"Failed to generate unicast PDU");
            CASendErrorInfo(data->remoteEndpoint, info, CA_SEND_FAILED);
            return CA_SEND_FAILED;
        }
    }
    else if (SEND_TYPE_MULTICAST == type)
    {
        OIC_LOG(DEBUG,TAG,"Multicast message");
        if (NULL != data->requestInfo)
        {
            OIC_LOG(DEBUG, TAG, "requestInfo is available..");

            info = &data->requestInfo->info;
            pdu = CAGeneratePDU(CA_GET, info, data->remoteEndpoint, &options, &transport);

            if (NULL != pdu)
            {
#ifdef WITH_BWT
                if (CA_ADAPTER_GATT_BTLE != data->remoteEndpoint->adapter
#ifdef TCP_ADAPTER
                        && CA_ADAPTER_TCP != data->remoteEndpoint->adapter
#endif
                        )
                {
                    // Blockwise transfer
                    CAResult_t res = CAAddBlockOption(&pdu, &data->requestInfo->info,
                                                      data->remoteEndpoint,
                                                      &options);
                    if (CA_STATUS_OK != res)
                    {
                        OIC_LOG(DEBUG, TAG, "CAAddBlockOption has failed");
                        CAErrorHandler(data->remoteEndpoint, pdu->hdr, pdu->length, res);
                        coap_delete_list(options);
                        coap_delete_pdu(pdu);
                        return res;
                    }
                }
#endif
            }
            else
            {
                OIC_LOG(ERROR,TAG,"Failed to generate multicast PDU");
                CASendErrorInfo(data->remoteEndpoint, info, CA_SEND_FAILED);
                return CA_SEND_FAILED;
            }
        }
        else if (NULL != data->responseInfo)
        {
            OIC_LOG(DEBUG, TAG, "responseInfo is available..");

            info = &data->responseInfo->info;
            pdu = CAGeneratePDU(data->responseInfo->result, info, data->remoteEndpoint,
                                &options, &transport);

            if (NULL != pdu)
            {
#ifdef WITH_BWT
                if (CA_ADAPTER_GATT_BTLE != data->remoteEndpoint->adapter
#ifdef TCP_ADAPTER
                        && CA_ADAPTER_TCP != data->remoteEndpoint->adapter
#endif
                        )
                {
                    // Blockwise transfer
                    if (NULL != info)
                    {
                        CAResult_t res = CAAddBlockOption(&pdu, info,
                                                          data->remoteEndpoint,
                                                          &options);
                        if (CA_STATUS_OK != res)
                        {
                            OIC_LOG(INFO, TAG, "to write block option has failed");
                            CAErrorHandler(data->remoteEndpoint, pdu->hdr, pdu->length, res);
                            coap_delete_list(options);
                            coap_delete_pdu(pdu);
                            return res;
                        }
                    }
                }
#endif
            }
            else
            {
                OIC_LOG(ERROR,TAG,"Failed to generate multicast PDU");
                CASendErrorInfo(data->remoteEndpoint, info, CA_SEND_FAILED);
                return CA_SEND_FAILED;
            }
        }
        else
        {
            OIC_LOG(ERROR, TAG, "request or response info is empty");
            return CA_SEND_FAILED;
        }

        CALogPDUInfo(pdu, data->remoteEndpoint);

        OIC_LOG(DEBUG, TAG, "pdu to send :");
        OIC_LOG_BUFFER(DEBUG, TAG,  (uint8_t*)pdu->hdr, pdu->length);

        res = CASendMulticastData(data->remoteEndpoint, pdu->hdr, pdu->length);
        if (CA_STATUS_OK != res)
        {
            OIC_LOG_V(ERROR, TAG, "send failed:%d", res);
            CAErrorHandler(data->remoteEndpoint, pdu->hdr, pdu->length, res);
            coap_delete_list(options);
            coap_delete_pdu(pdu);
            return res;
        }

        coap_delete_list(options);
        coap_delete_pdu(pdu);
    }

    return CA_STATUS_OK;
}
Exemple #15
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);
    }

    if (!cbNode)// If it does not already exist, create new node.
#endif // WITH_PRESENCE
    {
        cbNode = (ClientCB*) OICMalloc(sizeof(ClientCB));
        if (!cbNode)
        {
            *clientCB = NULL;
            goto exit;
        }
        else
        {
            OIC_LOG(INFO, TAG, "Adding client callback with token");
            OIC_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
            OIC_LOG_V(INFO, TAG, "Added Callback for uri : %s", requestUri);
            LL_APPEND(cbList, cbNode);
            *clientCB = cbNode;
        }
    }
#ifdef WITH_PRESENCE
    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;
    }

    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;
}
OCEntityHandlerResult
OCEntityHandlerCb (OCEntityHandlerFlag flag,
        OCEntityHandlerRequest *entityHandlerRequest, void* /*callback*/)
{
    OIC_LOG_V (INFO, TAG, "Inside entity handler - flags: 0x%x", flag);

    OCEntityHandlerResult ehResult = OC_EH_OK;
    OCEntityHandlerResponse response = { 0, 0, OC_EH_ERROR, 0, 0, { },{ 0 }, false };

    // Validate pointer
    if (!entityHandlerRequest)
    {
        OIC_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);
    OCRepPayload* payload = nullptr;

    if (flag & OC_REQUEST_FLAG)
    {
        OIC_LOG (INFO, TAG, "Flag includes OC_REQUEST_FLAG");

        if (OC_REST_GET == entityHandlerRequest->method)
        {
            OIC_LOG (INFO, TAG, "Received OC_REST_GET from client");
            ehResult = ProcessGetRequest (entityHandlerRequest, &payload);
        }
        else if (OC_REST_PUT == entityHandlerRequest->method)
        {
            OIC_LOG (INFO, TAG, "Received OC_REST_PUT from client");
            ehResult = ProcessPutRequest (entityHandlerRequest, &payload);
        }
        else if (OC_REST_POST == entityHandlerRequest->method)
        {
            OIC_LOG (INFO, TAG, "Received OC_REST_POST from client");
            ehResult = ProcessPostRequest (entityHandlerRequest, &response, &payload);
        }
        else if (OC_REST_DELETE == entityHandlerRequest->method)
        {
            OIC_LOG (INFO, TAG, "Received OC_REST_DELETE from client");
            ehResult = ProcessDeleteRequest (entityHandlerRequest);
        }
        else
        {
            OIC_LOG_V (INFO, TAG, "Received unsupported method %d from client",
                      entityHandlerRequest->method);
            ehResult = OC_EH_ERROR;
        }
        // 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 = reinterpret_cast<OCPayload*>(payload);
            // Indicate that response is NOT in a persistent buffer
            response.persistentBufferFlag = 0;

            // Handle vendor specific options
            if(entityHandlerRequest->rcvdVendorSpecificHeaderOptions &&
                    entityHandlerRequest->numRcvdVendorSpecificHeaderOptions)
            {
                OIC_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)
                    {
                        OIC_LOG_V(INFO, TAG, "Received option with OC_COAP_ID and ID %u with",
                                ((OCHeaderOption)rcvdOptions[i]).optionID );

                        OIC_LOG_BUFFER(INFO, TAG, ((OCHeaderOption)rcvdOptions[i]).optionData,
                            MAX_HEADER_OPTION_DATA_LENGTH);
                    }
                }
                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)
            {
                OIC_LOG(ERROR, TAG, "Error sending response");
                ehResult = OC_EH_ERROR;
            }
        }
    }
    if (flag & OC_OBSERVE_FLAG)
    {
        OIC_LOG(INFO, TAG, "Flag includes OC_OBSERVE_FLAG");

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

    OCPayloadDestroy(response.payload);
    return ehResult;
}
Exemple #17
0
static void CAReceivedPacketCallback(const CASecureEndpoint_t *sep,
                                     const void *data, uint32_t dataLen)
{
    VERIFY_NON_NULL_VOID(sep, TAG, "remoteEndpoint");
    VERIFY_NON_NULL_VOID(data, TAG, "data");

    OIC_LOG(DEBUG, TAG, "received pdu data :");
    OIC_LOG_BUFFER(DEBUG, TAG,  data, dataLen);

    uint32_t code = CA_NOT_FOUND;
    CAData_t *cadata = NULL;

    coap_pdu_t *pdu = (coap_pdu_t *) CAParsePDU((const char *) data, dataLen, &code,
                                                &(sep->endpoint));
    if (NULL == pdu)
    {
        OIC_LOG(ERROR, TAG, "Parse PDU failed");
        return;
    }

    OIC_LOG_V(DEBUG, TAG, "code = %d", code);
    if (CA_GET == code || CA_POST == code || CA_PUT == code || CA_DELETE == code)
    {
        cadata = CAGenerateHandlerData(&(sep->endpoint), &(sep->identity), pdu, CA_REQUEST_DATA);
        if (!cadata)
        {
            OIC_LOG(ERROR, TAG, "CAReceivedPacketCallback, CAGenerateHandlerData failed!");
            coap_delete_pdu(pdu);
            return;
        }
    }
    else
    {
        cadata = CAGenerateHandlerData(&(sep->endpoint), &(sep->identity), pdu, CA_RESPONSE_DATA);
        if (!cadata)
        {
            OIC_LOG(ERROR, TAG, "CAReceivedPacketCallback, CAGenerateHandlerData failed!");
            coap_delete_pdu(pdu);
            return;
        }

#ifdef TCP_ADAPTER
        if (CA_ADAPTER_TCP == sep->endpoint.adapter)
        {
            OIC_LOG(INFO, TAG, "retransmission is not supported");
        }
        else
#endif
        {
            // for retransmission
            void *retransmissionPdu = NULL;
            CARetransmissionReceivedData(&g_retransmissionContext, cadata->remoteEndpoint, pdu->hdr,
                                         pdu->length, &retransmissionPdu);

            // get token from saved data in retransmission list
            if (retransmissionPdu && CA_EMPTY == code)
            {
                if (cadata->responseInfo)
                {
                    CAInfo_t *info = &cadata->responseInfo->info;
                    CAResult_t res = CAGetTokenFromPDU((const coap_hdr_t *)retransmissionPdu,
                                                       info, &(sep->endpoint));
                    if (CA_STATUS_OK != res)
                    {
                        OIC_LOG(ERROR, TAG, "fail to get Token from retransmission list");
                        OICFree(info->token);
                        info->tokenLength = 0;
                    }
                }
            }
            OICFree(retransmissionPdu);
        }
    }

    cadata->type = SEND_TYPE_UNICAST;

#ifdef SINGLE_THREAD
    CAProcessReceivedData(cadata);
#else
#ifdef WITH_BWT
    if (CA_ADAPTER_GATT_BTLE != sep->endpoint.adapter
#ifdef TCP_ADAPTER
            && CA_ADAPTER_TCP != sep->endpoint.adapter
#endif
            )
    {
        CAResult_t res = CAReceiveBlockWiseData(pdu, &(sep->endpoint), cadata, dataLen);
        if (CA_NOT_SUPPORTED == res || CA_REQUEST_TIMEOUT == res)
        {
            OIC_LOG(ERROR, TAG, "this message does not have block option");
            CAQueueingThreadAddData(&g_receiveThread, cadata, sizeof(CAData_t));
        }
        else
        {
            CADestroyData(cadata, sizeof(CAData_t));
        }
    }
    else
#endif
    {
        CAQueueingThreadAddData(&g_receiveThread, cadata, sizeof(CAData_t));
    }
#endif

    coap_delete_pdu(pdu);
}