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); } }
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; }
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); }
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; }
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; }
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; }
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; }
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); }