+
+#ifdef WITH_CHPROXY
+OCStackResult OCSetProxyURI(const char *uri)
+{
+ return CAResultToOCResult(CASetProxyUri(uri));
+}
+#endif
+
+#if defined(RD_CLIENT) || defined(RD_SERVER)
+OCStackResult OCBindResourceInsToResource(OCResourceHandle handle, int64_t ins)
+{
+ VERIFY_NON_NULL(handle, ERROR, OC_STACK_INVALID_PARAM);
+
+ OCResource *resource = NULL;
+
+ resource = findResource((OCResource *) handle);
+ if (!resource)
+ {
+ OIC_LOG(ERROR, TAG, "Resource not found");
+ return OC_STACK_ERROR;
+ }
+
+ resource->ins = ins;
+
+ return OC_STACK_OK;
+}
+
+
+OCStackResult OCUpdateResourceInsWithResponse(const char *requestUri,
+ const OCClientResponse *response)
+{
+ // Validate input parameters
+ VERIFY_NON_NULL(requestUri, ERROR, OC_STACK_INVALID_PARAM);
+ VERIFY_NON_NULL(response, ERROR, OC_STACK_INVALID_PARAM);
+
+ char *targetUri = (char *) OICMalloc(strlen(requestUri) + 1);
+ if (!targetUri)
+ {
+ return OC_STACK_NO_MEMORY;
+ }
+ strncpy(targetUri, requestUri, strlen(requestUri) + 1);
+
+ if (response->result == OC_STACK_RESOURCE_CHANGED) // publish message
+ {
+ OIC_LOG(DEBUG, TAG, "update the ins of published resource");
+
+ char rdPubUri[MAX_URI_LENGTH] = { 0 };
+ snprintf(rdPubUri, MAX_URI_LENGTH, "%s?rt=%s", OC_RSRVD_RD_URI,
+ OC_RSRVD_RESOURCE_TYPE_RDPUBLISH);
+
+ if (strcmp(rdPubUri, targetUri) == 0)
+ {
+ // Update resource unique id in stack.
+ if (response)
+ {
+ if (response->payload)
+ {
+ OCRepPayload *rdPayload = (OCRepPayload *) response->payload;
+ OCRepPayload **links = NULL;
+ size_t dimensions[MAX_REP_ARRAY_DEPTH] = { 0 };
+ if (OCRepPayloadGetPropObjectArray(rdPayload, OC_RSRVD_LINKS,
+ &links, dimensions))
+ {
+ size_t i = 0;
+ for (; i < dimensions[0]; i++)
+ {
+ char *uri = NULL;
+ if (OCRepPayloadGetPropString(links[i], OC_RSRVD_HREF, &uri))
+ {
+ OCResourceHandle handle = OCGetResourceHandleAtUri(uri);
+ int64_t ins = 0;
+ if (OCRepPayloadGetPropInt(links[i], OC_RSRVD_INS, &ins))
+ {
+ OCBindResourceInsToResource(handle, ins);
+ }
+
+ OICFree(uri);
+ uri = NULL;
+ }
+ }
+
+ // Free links
+ size_t count = calcDimTotal(dimensions);
+ for (size_t k = 0; k < count; k++)
+ {
+ OCRepPayloadDestroy(links[k]);
+ }
+ OICFree(links);
+ }
+ }
+ }
+ }
+ }
+ else if (response->result == OC_STACK_RESOURCE_DELETED) // delete message
+ {
+ OIC_LOG(DEBUG, TAG, "update the ins of deleted resource with 0");
+
+ uint8_t numResources = 0;
+ OCGetNumberOfResources(&numResources);
+
+ char *ins = strstr(targetUri, OC_RSRVD_INS);
+ if (!ins)
+ {
+ for (uint8_t i = 0; i < numResources; i++)
+ {
+ OCResourceHandle resHandle = OCGetResourceHandle(i);
+ if (resHandle)
+ {
+ OCBindResourceInsToResource(resHandle, 0);
+ }
+ }
+ }
+ else
+ {
+ const char *token = "&";
+ char *iterTokenPtr = NULL;
+ char *start = strtok_r(targetUri, token, &iterTokenPtr);
+
+ while (start != NULL)
+ {
+ char *query = start;
+ query = strstr(query, OC_RSRVD_INS);
+ if (query)
+ {
+ int64_t queryIns = atoi(query + 4);
+ for (uint8_t i = 0; i < numResources; i++)
+ {
+ OCResourceHandle resHandle = OCGetResourceHandle(i);
+ if (resHandle)
+ {
+ int64_t resIns = 0;
+ OCGetResourceIns(resHandle, &resIns);
+ if (queryIns && queryIns == resIns)
+ {
+ OCBindResourceInsToResource(resHandle, 0);
+ break;
+ }
+ }
+ }
+ }
+ start = strtok_r(NULL, token, &iterTokenPtr);
+ }
+ }
+ }
+
+ OICFree(targetUri);
+ return OC_STACK_OK;
+}
+
+OCResourceHandle OCGetResourceHandleAtUri(const char *uri)
+{
+ if (!uri)
+ {
+ OIC_LOG(ERROR, TAG, "Resource uri is NULL");
+ return NULL;
+ }
+
+ OCResource *pointer = headResource;
+
+ while (pointer)
+ {
+ if (strncmp(uri, pointer->uri, MAX_URI_LENGTH) == 0)
+ {
+ OIC_LOG_V(DEBUG, TAG, "Found Resource %s", uri);
+ return pointer;
+ }
+ pointer = pointer->next;
+ }
+ return NULL;
+}
+
+OCStackResult OCGetResourceIns(OCResourceHandle handle, int64_t *ins)
+{
+ OCResource *resource = NULL;
+
+ VERIFY_NON_NULL(handle, ERROR, OC_STACK_INVALID_PARAM);
+ VERIFY_NON_NULL(ins, ERROR, OC_STACK_INVALID_PARAM);
+
+ resource = findResource((OCResource *) handle);
+ if (resource)
+ {
+ *ins = resource->ins;
+ return OC_STACK_OK;
+ }
+ return OC_STACK_ERROR;
+}
+#endif
+
+OCStackResult OCSetHeaderOption(OCHeaderOption* ocHdrOpt, size_t* numOptions, uint16_t optionID,
+ const void* optionData, size_t optionDataLength)
+{
+ if (!ocHdrOpt)
+ {
+ OIC_LOG (INFO, TAG, "Header options are NULL");
+ return OC_STACK_INVALID_PARAM;
+ }
+
+ if (!optionData)
+ {
+ OIC_LOG (INFO, TAG, "optionData are NULL");
+ return OC_STACK_INVALID_PARAM;
+ }
+
+ if (!numOptions)
+ {
+ OIC_LOG (INFO, TAG, "numOptions is NULL");
+ return OC_STACK_INVALID_PARAM;
+ }
+
+ if (*numOptions >= MAX_HEADER_OPTIONS)
+ {
+ OIC_LOG (INFO, TAG, "Exceeding MAX_HEADER_OPTIONS");
+ return OC_STACK_NO_MEMORY;
+ }
+
+ ocHdrOpt += *numOptions;
+ ocHdrOpt->protocolID = OC_COAP_ID;
+ ocHdrOpt->optionID = optionID;
+ ocHdrOpt->optionLength =
+ optionDataLength < MAX_HEADER_OPTION_DATA_LENGTH ?
+ optionDataLength : MAX_HEADER_OPTION_DATA_LENGTH;
+ memcpy(ocHdrOpt->optionData, (const void*) optionData, ocHdrOpt->optionLength);
+ *numOptions += 1;
+
+ return OC_STACK_OK;
+}
+
+OCStackResult OCGetHeaderOption(OCHeaderOption* ocHdrOpt, size_t numOptions, uint16_t optionID,
+ void* optionData, size_t optionDataLength, uint16_t* receivedDataLength)
+{
+ if (!ocHdrOpt || !numOptions)
+ {
+ OIC_LOG (INFO, TAG, "No options present");
+ return OC_STACK_OK;
+ }
+
+ if (!optionData)
+ {
+ OIC_LOG (INFO, TAG, "optionData are NULL");
+ return OC_STACK_INVALID_PARAM;
+ }
+
+ if (!receivedDataLength)
+ {
+ OIC_LOG (INFO, TAG, "receivedDataLength is NULL");
+ return OC_STACK_INVALID_PARAM;
+ }
+
+ for (uint8_t i = 0; i < numOptions; i++)
+ {
+ if (ocHdrOpt[i].optionID == optionID)
+ {
+ if (optionDataLength >= ocHdrOpt->optionLength)
+ {
+ memcpy(optionData, ocHdrOpt->optionData, ocHdrOpt->optionLength);
+ *receivedDataLength = ocHdrOpt->optionLength;
+ return OC_STACK_OK;
+ }
+ else
+ {
+ OIC_LOG (ERROR, TAG, "optionDataLength is less than the length of received data");
+ return OC_STACK_ERROR;
+ }
+ }
+ }
+ return OC_STACK_OK;
+}
+
+void OCDefaultAdapterStateChangedHandler(CATransportAdapter_t adapter, bool enabled)
+{
+ OIC_LOG(DEBUG, TAG, "OCDefaultAdapterStateChangedHandler");
+ if (g_adapterHandler)
+ {
+ g_adapterHandler(adapter, enabled);
+ }
+}
+
+void OCDefaultConnectionStateChangedHandler(const CAEndpoint_t *info, bool isConnected)
+{
+ OIC_LOG(DEBUG, TAG, "OCDefaultConnectionStateChangedHandler");
+ if (g_connectionHandler)
+ {
+ g_connectionHandler(info, isConnected);
+ }
+
+ /*
+ * If the client observes one or more resources over a reliable connection,
+ * then the CoAP server (or intermediary in the role of the CoAP server)
+ * MUST remove all entries associated with the client endpoint from the lists
+ * of observers when the connection is either closed or times out.
+ */
+ if (!isConnected)
+ {
+ OCDevAddr devAddr = { OC_DEFAULT_ADAPTER };
+ CopyEndpointToDevAddr(info, &devAddr);
+
+ // remove observer list with remote device address.
+ DeleteObserverUsingDevAddr(&devAddr);
+ }
+}
+
+OCStackResult OCGetDeviceId(OCUUIdentity *deviceId)
+{
+ OicUuid_t oicUuid;
+ OCStackResult ret = OC_STACK_ERROR;
+
+ ret = GetDoxmDeviceID(&oicUuid);
+ if (OC_STACK_OK == ret)
+ {
+ memcpy(deviceId, &oicUuid, UUID_IDENTITY_SIZE);
+ }
+ else
+ {
+ OIC_LOG(ERROR, TAG, "Device ID Get error");
+ }
+ return ret;
+}
+
+OCStackResult OCSetDeviceId(const OCUUIdentity *deviceId)
+{
+ OicUuid_t oicUuid;
+ OCStackResult ret = OC_STACK_ERROR;
+
+ memcpy(&oicUuid, deviceId, UUID_LENGTH);
+ for (int i = 0; i < UUID_LENGTH; i++)
+ {
+ OIC_LOG_V(INFO, TAG, "Set Device Id %x", oicUuid.id[i]);
+ }
+ ret = SetDoxmDeviceID(&oicUuid);
+ return ret;
+}
+
+OCStackResult OCGetDeviceOwnedState(bool *isOwned)
+{
+ bool isDeviceOwned = true;
+ OCStackResult ret = OC_STACK_ERROR;
+
+ ret = GetDoxmIsOwned(&isDeviceOwned);
+ if (OC_STACK_OK == ret)
+ {
+ *isOwned = isDeviceOwned;
+ }
+ else
+ {
+ OIC_LOG(ERROR, TAG, "Device Owned State Get error");
+ }
+ return ret;
+}
+
+void OCClearCallBackList()
+{
+ DeleteClientCBList();
+}
+
+void OCClearObserverlist()
+{
+ DeleteObserverList();
+}
+
+int OCEncrypt(const unsigned char *pt, size_t pt_len,
+ unsigned char **ct, size_t *ct_len)
+{
+#ifndef __SECURE_PSI__
+ OIC_LOG_V(DEBUG, TAG, "Not Supported : %s", __func__);
+ return 0;
+#else
+ OIC_LOG_V(DEBUG, TAG, "%s", __func__);
+
+ return psiEncrypt(pt, pt_len, ct, ct_len);
+#endif // __SECURE_PSI__
+}
+
+int OCDecrypt(const unsigned char *ct, size_t ct_len,
+ unsigned char **pt, size_t *pt_len)
+{
+#ifndef __SECURE_PSI__
+ OIC_LOG_V(DEBUG, TAG, "Not Supported : %s", __func__);
+ return 0;
+#else
+ OIC_LOG_V(DEBUG, TAG, "%s", __func__);
+
+ return psiDecrypt(ct, ct_len, pt, pt_len);
+#endif // __SECURE_PSI__
+}
+
+OCStackResult OCSetKey(const unsigned char* key)
+{
+#ifndef __SECURE_PSI__
+ OIC_LOG_V(DEBUG, TAG, "Not Supported : %s", __func__);
+ return OC_STACK_OK;
+#else
+ OIC_LOG_V(DEBUG, TAG, "%s", __func__);
+
+ return psiSetKey(key);
+#endif // __SECURE_PSI__
+}
+
+OCStackResult OCGetKey(unsigned char* key)
+{
+#ifndef __SECURE_PSI__
+ OIC_LOG_V(DEBUG, TAG, "Not Supported : %s", __func__);
+ return OC_STACK_OK;
+#else
+ OIC_LOG_V(DEBUG, TAG, "%s", __func__);
+
+ return psiGetKey(key);
+#endif // __SECURE_PSI__
+}
+
+OCStackResult OCSetSecurePSI(const unsigned char *key, const OCPersistentStorage *psPlain,
+ const OCPersistentStorage *psEnc, const OCPersistentStorage *psRescue)
+{
+#ifndef __SECURE_PSI__
+ OIC_LOG_V(DEBUG, TAG, "Not Supported : %s", __func__);
+ return OC_STACK_OK;
+#else
+ OIC_LOG_V(DEBUG, TAG, "%s", __func__);
+
+ return setSecurePSI(key, psPlain, psEnc, psRescue);
+#endif // __SECURE_PSI__
+}
+
+#if defined(__WITH_DTLS__) || defined (__WITH_TLS__)
+static void OtmEventHandler(const char *addr, uint16_t port, const char *uuid, int event)
+{
+ if (g_otmEventHandler.cb)
+ {
+ g_otmEventHandler.cb(g_otmEventHandler.ctx, addr, port, uuid, event);
+ }
+}
+
+/* TODO Work-around
+ * It is already declared in srmutility.h.
+ * We can't include the header file, because of "redefined VERIFY_NON_NULL"
+ */
+typedef void (*OicSecOtmEventHandler_t)(const char* addr, uint16_t port,
+ const char* uuid, int event);
+void SetOtmEventHandler(OicSecOtmEventHandler_t otmEventHandler);
+#endif
+
+OCStackResult OCSetOtmEventHandler(void *ctx, OCOtmEventHandler cb)
+{
+#if defined(__WITH_DTLS__) || defined (__WITH_TLS__)
+ OIC_LOG_V(DEBUG, TAG, "%s", __func__);
+
+ g_otmEventHandler.cb = cb;
+ g_otmEventHandler.ctx = ctx;
+
+ if (g_otmEventHandler.cb)
+ {
+ OIC_LOG(DEBUG, TAG, "SET OCOtmEventHandler");
+ SetOtmEventHandler(OtmEventHandler);
+ }
+ else
+ {
+ OIC_LOG(DEBUG, TAG, "UNSET OCOtmEventHandler");
+ SetOtmEventHandler(NULL);
+ }
+#else
+ OIC_LOG_V(DEBUG, TAG, "Not Supported : %s", __func__);
+ OC_UNUSED(ctx);
+ OC_UNUSED(cb);
+#endif
+ return OC_STACK_OK;
+}