#include "oic_string.h"
#include "oic_time.h"
#include "logger.h"
+#if defined (__TIZENRT__)
+#include <apps/netutils/cJSON.h>
+#else
#include "cJSON.h"
+#endif
#include "utlist.h"
#include "ocpayload.h"
#include "srmutility.h"
-#define TAG ("PM-UTILITY")
+#define TAG ("OIC_PM_UTILITY")
typedef struct _DiscoveryInfo{
OCProvisionDev_t **ppDevicesList;
static OCStackResult SecurePortDiscovery(DiscoveryInfo* discoveryInfo,
const OCClientResponse *clientResponse);
-/*
- * Function to discover security version information through unicast
- *
- * @param[in] discoveryInfo The pointer of discovery information to matain result of discovery
- * @param[in] clientResponse Response information(It will contain payload)
- *
- * @return OC_STACK_OK on success otherwise error.
- */
-static OCStackResult SecurityVersionDiscovery(DiscoveryInfo* discoveryInfo,
- const OCClientResponse *clientResponse);
-
/**
* Callback handler for PMDeviceDiscovery API.
*
static OCStackApplicationResult DeviceDiscoveryHandler(void *ctx, OCDoHandle UNUSED,
OCClientResponse *clientResponse);
+/*
+ * Since security version discovery does not used anymore, disable security version discovery.
+ * Need to discussion to removing all version discovery related codes.
+ */
+#if 0
+/*
+ * Function to discover security version information through unicast
+ *
+ * @param[in] discoveryInfo The pointer of discovery information to matain result of discovery
+ * @param[in] clientResponse Response information(It will contain payload)
+ *
+ * @return OC_STACK_OK on success otherwise error.
+ */
+static OCStackResult SecurityVersionDiscovery(DiscoveryInfo* discoveryInfo,
+ const OCClientResponse *clientResponse);
+
/**
* Callback handler for getting secure port information using /oic/res discovery.
*
*/
static OCStackApplicationResult SecurePortDiscoveryHandler(void *ctx, OCDoHandle UNUSED,
OCClientResponse *clientResponse);
+#endif
+/*
+ * Since security version discovery does not used anymore, disable security version discovery.
+ * Need to discussion to removing all version discovery related codes.
+ */
+#if 0
/**
* Callback handler for security version discovery.
*
*/
static OCStackApplicationResult SecVersionDiscoveryHandler(void *ctx, OCDoHandle UNUSED,
OCClientResponse *clientResponse);
+#endif
/**
* Function to search node in linked list that matches given IP and port.
OCProvisionDev_t *ptr = NULL;
LL_FOREACH(*ppDevicesList, ptr)
{
- if( strcmp(ptr->endpoint.addr, addr) == 0 && port == ptr->endpoint.port)
+ if( (ptr && ptr->endpoint.addr) && strncmp(ptr->endpoint.addr, addr, MAX_ADDR_STR_SIZE) == 0 && port == ptr->endpoint.port)
{
return ptr;
}
ptr->endpoint = *endpoint;
ptr->doxm = doxm;
- ptr->securePort = DEFAULT_SECURE_PORT;
+ ptr->securePort = (CT_ADAPTER_GATT_BTLE == connType) ?
+ endpoint->port : DEFAULT_SECURE_PORT;
ptr->next = NULL;
ptr->connType = connType;
ptr->devStatus = DEV_STATUS_ON; //AddDevice is called when discovery(=alive)
- OICStrcpy(ptr->secVer, MAX_VERSION_LEN, DEFAULT_SEC_VERSION); // version initialization
+ OICStrcpy(ptr->secVer, OIC_SEC_MAX_VER_LEN, DEFAULT_SEC_VERSION); // version initialization
ptr->handle = NULL;
LL_PREPEND(*ppDevicesList, ptr);
return OC_STACK_ERROR;
}
- ptr->securePort = securePort;
+ ptr->securePort = (OC_ADAPTER_GATT_BTLE == ptr->endpoint.adapter) ?
+ ptr->endpoint.port : securePort;
#ifdef __WITH_TLS__
ptr->tcpPort = tcpPort;
return OC_STACK_ERROR;
}
- OICStrcpy(ptr->secVer, MAX_VERSION_LEN, secVer);
+ OICStrcpy(ptr->secVer, OIC_SEC_MAX_VER_LEN, secVer);
return OC_STACK_OK;
}
if (0 == strlen(src->secVer))
{
- OICStrcpy(newDev->secVer, MAX_VERSION_LEN, DEFAULT_SEC_VERSION);
+ OICStrcpy(newDev->secVer, OIC_SEC_MAX_VER_LEN, DEFAULT_SEC_VERSION);
}
else
{
- OICStrcpy(newDev->secVer, MAX_VERSION_LEN, src->secVer);
+ OICStrcpy(newDev->secVer, OIC_SEC_MAX_VER_LEN, src->secVer);
}
newDev->securePort = src->securePort;
switch(connType & CT_MASK_FLAGS & ~CT_FLAG_SECURE)
{
case CT_IP_USE_V4:
- snRet = snprintf(buffer, bufferSize, "%s%s:%d%s",
- prefix, address, port, uri);
+ snRet = snprintf(buffer, bufferSize, "%s%s:%d%s",
+ prefix, address, port, uri);
break;
case CT_IP_USE_V6:
- snRet = snprintf(buffer, bufferSize, "%s[%s]:%d%s",
- prefix, address, port, uri);
+ {
+ char addressEncoded[128] = {0};
+
+ OCStackResult result = OCEncodeAddressForRFC6874(addressEncoded,
+ sizeof(addressEncoded),
+ address);
+ if (OC_STACK_OK != result)
+ {
+ OIC_LOG_V(ERROR, TAG, "PMGenerateQuery : encoding error %d\n", result);
+ return false;
+ }
+
+ snRet = snprintf(buffer, bufferSize, "%s[%s]:%d%s",
+ prefix, addressEncoded, port, uri);
break;
+ }
default:
OIC_LOG(ERROR, TAG, "Unknown address format.");
return false;
}
break;
- // TODO: We need to verify tinyDTLS in below cases
case CT_ADAPTER_GATT_BTLE:
+ snRet = snprintf(buffer, bufferSize, "%s%s%s",
+ prefix, address, uri);
+ // snprintf return value check
+ if (snRet < 0)
+ {
+ OIC_LOG_V(ERROR, TAG, "PMGenerateQuery : Error (snprintf) %d\n", snRet);
+ return false;
+ }
+ else if ((size_t)snRet >= bufferSize)
+ {
+ OIC_LOG_V(ERROR, TAG, "PMGenerateQuery : Truncated (snprintf) %d\n", snRet);
+ return false;
+ }
+
+ break;
+ // TODO: We need to verify tinyDTLS in below cases
case CT_ADAPTER_RFCOMM_BTEDR:
OIC_LOG(ERROR, TAG, "Not supported connectivity adapter.");
return false;
return true;
}
+/*
+ * Since security version discovery does not used anymore, disable security version discovery.
+ * Need to discussion to removing all version discovery related codes.
+ */
+#if 0
static OCStackApplicationResult SecurityVersionDiscoveryHandler(void *ctx, OCDoHandle UNUSED,
OCClientResponse *clientResponse)
{
return OC_STACK_DELETE_TRANSACTION;
}
+#endif
static OCStackApplicationResult SecurePortDiscoveryHandler(void *ctx, OCDoHandle UNUSED,
OCClientResponse *clientResponse)
OIC_LOG_V(DEBUG, TAG, "%s: TCP port from discovery = %d", __func__, resPayload->tcpPort);
#endif
DiscoveryInfo* pDInfo = (DiscoveryInfo*)ctx;
+
+ if(pDInfo->isSingleDiscovery && pDInfo->isFound)
+ {
+ OIC_LOG(INFO, TAG, "Device is already founded at Single mode.");
+ return OC_STACK_DELETE_TRANSACTION;
+ }
+
OCProvisionDev_t *ptr = GetDevice(&pDInfo->pCandidateList,
clientResponse->devAddr.addr,
clientResponse->devAddr.port);
return OC_STACK_DELETE_TRANSACTION;
}
#endif
-
OIC_LOG(INFO, TAG, "Exiting SecurePortDiscoveryHandler.");
}
// Get my device ID from doxm resource
OicUuid_t myId;
memset(&myId, 0, sizeof(myId));
- OCStackResult res = GetDoxmDevOwnerId(&myId);
+ OCStackResult res = GetDoxmDeviceID(&myId);
if(OC_STACK_OK != res)
{
OIC_LOG(ERROR, TAG, "Error while getting my device ID.");
return OC_STACK_KEEP_TRANSACTION;
}
- res = GetDoxmDeviceID(&myId);
- if(OC_STACK_OK != res)
- {
- OIC_LOG(ERROR, TAG, "Error while getting my UUID.");
- DeleteDoxmBinData(ptrDoxm);
- return OC_STACK_KEEP_TRANSACTION;
- }
//if targetId and discovered deviceID are different, discard it
if ((pDInfo->isSingleDiscovery) &&
(0 != memcmp(&ptrDoxm->deviceID.id, &pDInfo->targetId->id, sizeof(pDInfo->targetId->id))) )
DeleteDoxmBinData(ptrDoxm);
return OC_STACK_KEEP_TRANSACTION;
}
- //if this is owned discovery and this is PT's reply, discard it
- if (((pDInfo->isSingleDiscovery) || (pDInfo->isOwnedDiscovery)) &&
- (0 == memcmp(&ptrDoxm->deviceID.id, &myId.id, sizeof(myId.id))) )
+ //If self reply, discard it
+ if (0 == memcmp(&ptrDoxm->deviceID.id, &myId.id, sizeof(myId.id)))
{
OIC_LOG(DEBUG, TAG, "discarding provision tool's reply");
DeleteDoxmBinData(ptrDoxm);
DeleteDoxmBinData(ptrDoxm);
return OC_STACK_KEEP_TRANSACTION;
}
-
res = SecurePortDiscovery(pDInfo, clientResponse);
if(OC_STACK_OK != res)
{
OIC_LOG(INFO, TAG, "Exiting ProvisionDiscoveryHandler.");
}
-
return OC_STACK_KEEP_TRANSACTION;
}
}
{
OIC_LOG_V(DEBUG, TAG, "OCCancel - %s : %d",
pDev->endpoint.addr, pDev->endpoint.port);
- OCCancel(pDev->handle,OC_HIGH_QOS,NULL,0);
+ if(OC_STACK_OK != OCCancel(pDev->handle,OC_HIGH_QOS,NULL,0))
+ {
+ OIC_LOG(ERROR, TAG, "Failed to remove registered callback");
+ }
}
PMDeleteDeviceList(pDInfo->pCandidateList);
}
OICFree(pDInfo);
return res;
}
- OIC_LOG(DEBUG, TAG, "OUT PMSingleDeviceDiscovery");
+ if (!pDInfo->isFound)
+ {
+ res = OC_STACK_TIMEOUT;
+ }
OICFree(pDInfo);
+ OIC_LOG(DEBUG, TAG, "OUT PMSingleDeviceDiscovery");
return res;
}
-
/**
* Discover owned/unowned devices in the same IP subnet. .
*
{
OIC_LOG(ERROR, TAG, "OCStack resource error");
OICFree(pDInfo);
+ pDInfo = NULL;
return res;
}
{
OIC_LOG(ERROR, TAG, "Failed to wait response for secure discovery.");
OICFree(pDInfo);
+ pDInfo = NULL;
OCStackResult resCancel = OCCancel(handle, OC_HIGH_QOS, NULL, 0);
if(OC_STACK_OK != resCancel)
{
{
OIC_LOG(ERROR, TAG, "Failed to remove registered callback");
OICFree(pDInfo);
+ pDInfo = NULL;
return res;
}
OIC_LOG(DEBUG, TAG, "OUT PMDeviceDiscovery");
OICFree(pDInfo);
+ pDInfo = NULL;
+ return res;
+}
+
+OCStackResult PMSingleDeviceDiscoveryInUnicast(unsigned short waittime, const OicUuid_t* deviceID,
+ const char* hostAddress, OCConnectivityType connType,
+ OCProvisionDev_t **ppFoundDevice)
+{
+ OIC_LOG(DEBUG, TAG, "IN PMSingleDeviceDiscoveryInUnicast");
+
+ if (NULL != *ppFoundDevice)
+ {
+ OIC_LOG(ERROR, TAG, "List is not null can cause memory leak");
+ return OC_STACK_INVALID_PARAM;
+ }
+
+ if (NULL == deviceID)
+ {
+ OIC_LOG(ERROR, TAG, "Invalid device ID");
+ return OC_STACK_INVALID_PARAM;
+ }
+
+ DiscoveryInfo *pDInfo = (DiscoveryInfo*)OICCalloc(1, sizeof(DiscoveryInfo));
+ if (NULL == pDInfo)
+ {
+ OIC_LOG(ERROR, TAG, "PMSingleDeviceDiscoveryInUnicast : Memory allocation failed.");
+ return OC_STACK_NO_MEMORY;
+ }
+
+ pDInfo->ppDevicesList = ppFoundDevice;
+ pDInfo->pCandidateList = NULL;
+ pDInfo->isOwnedDiscovery = false;
+ pDInfo->isSingleDiscovery = true;
+ pDInfo->isFound = false;
+ pDInfo->targetId = deviceID;
+
+ OCCallbackData cbData;
+ cbData.cb = &DeviceDiscoveryHandler;
+ cbData.context = (void *)pDInfo;
+ cbData.cd = &DeviceDiscoveryDeleteHandler;
+
+ OCStackResult res = OC_STACK_ERROR;
+
+ char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH + 1] = { '\0' };
+ if (hostAddress == NULL)
+ {
+ hostAddress = "";
+ }
+ snprintf(query, MAX_URI_LENGTH + MAX_QUERY_LENGTH + 1, "%s/oic/sec/doxm", hostAddress);
+ connType = connType & CT_MASK_ADAPTER;
+
+ OCDoHandle handle = NULL;
+ res = OCDoResource(&handle, OC_REST_DISCOVER, query, 0, 0,
+ connType, OC_HIGH_QOS, &cbData, NULL, 0);
+
+ if (res != OC_STACK_OK)
+ {
+ OIC_LOG(ERROR, TAG, "OCStack resource error");
+ OICFree(pDInfo);
+ pDInfo = NULL;
+ return res;
+ }
+
+ res = OC_STACK_OK;
+ uint64_t startTime = OICGetCurrentTime(TIME_IN_MS);
+ while (OC_STACK_OK == res && !pDInfo->isFound)
+ {
+ uint64_t currTime = OICGetCurrentTime(TIME_IN_MS);
+
+ long elapsed = (long)((currTime - startTime) / MS_PER_SEC);
+ if (elapsed > waittime)
+ {
+ break;
+ }
+ res = OCProcess();
+ }
+
+ if (OC_STACK_OK != res)
+ {
+ OIC_LOG (ERROR, TAG, "Failed to wait response for secure discovery.");
+ OICFree(pDInfo);
+ pDInfo = NULL;
+ OCStackResult resCancel = OCCancel(handle, OC_HIGH_QOS, NULL, 0);
+ if (OC_STACK_OK != resCancel)
+ {
+ OIC_LOG(ERROR, TAG, "Failed to remove registered callback");
+ }
+ return res;
+ }
+
+ res = OCCancel(handle, OC_HIGH_QOS, NULL, 0);
+ if (OC_STACK_OK != res)
+ {
+ OIC_LOG(ERROR, TAG, "Failed to remove registered callback");
+ OICFree(pDInfo);
+ pDInfo = NULL;
+ return res;
+ }
+ OIC_LOG(DEBUG, TAG, "OUT PMSingleDeviceDiscoveryInUnicast");
+
+ if (!pDInfo->isFound)
+ {
+ res = OC_STACK_TIMEOUT;
+ }
+
+ OICFree(pDInfo);
+ pDInfo = NULL;
return res;
}
-#ifdef _ENABLE_MULTIPLE_OWNER_
+#ifdef MULTIPLE_OWNER
static OCStackApplicationResult MOTDeviceDiscoveryHandler(void *ctx, OCDoHandle UNUSED,
OCClientResponse *clientResponse)
{
return OC_STACK_INVALID_PARAM;
}
- const char *DOXM_MOM_ENABLE_MULTICAST_QUERY = "/oic/sec/doxm?mom!=0&owned=TRUE";
- const char *DOXM_MULTIPLE_OWNED_MULTICAST_QUERY = "/oic/sec/doxm?owned=TRUE";
+ char DOXM_MOM_ENABLE_MULTICAST_QUERY[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
+ char DOXM_MULTIPLE_OWNED_MULTICAST_QUERY[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
+ snprintf(DOXM_MOM_ENABLE_MULTICAST_QUERY, sizeof(DOXM_MOM_ENABLE_MULTICAST_QUERY),
+ "%s?%s=%d&%s=TRUE",
+ OIC_RSRC_DOXM_URI, OIC_JSON_MOM_NAME, OIC_MULTIPLE_OWNER_DISABLE,
+ OIC_JSON_OWNED_NAME);
+ snprintf(DOXM_MULTIPLE_OWNED_MULTICAST_QUERY, sizeof(DOXM_MOM_ENABLE_MULTICAST_QUERY),
+ "%s?%s=TRUE",
+ OIC_RSRC_DOXM_URI, OIC_JSON_OWNED_NAME);
DiscoveryInfo *pDInfo = OICCalloc(1, sizeof(DiscoveryInfo));
if(NULL == pDInfo)
return res;
}
-#endif //_ENABLE_MULTIPLE_OWNER_
+#endif //MULTIPLE_OWNER
static OCStackResult SecurePortDiscovery(DiscoveryInfo* discoveryInfo,
const OCClientResponse *clientResponse)
}
OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
+ // Set filter query with rt=oic.r.doxm
+ const char RES_DOXM_QUERY_FMT[] = "%s?%s=%s";
+ char uri[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
+ snprintf(uri, sizeof(uri), RES_DOXM_QUERY_FMT, query,
+ OC_RSRVD_RESOURCE_TYPE, OIC_RSRC_TYPE_SEC_DOXM);
+
+ OIC_LOG_V(DEBUG, TAG, "URI=%s", uri);
+
OCCallbackData cbData;
cbData.cb = &SecurePortDiscoveryHandler;
cbData.context = (void*)discoveryInfo;
cbData.cd = NULL;
- OCStackResult ret = OCDoResource(&pDev->handle, OC_REST_DISCOVER, query, 0, 0,
+ OCStackResult ret = OCDoResource(&pDev->handle, OC_REST_DISCOVER, uri, 0, 0,
pDev->connType, OC_HIGH_QOS, &cbData, NULL, 0);
if(OC_STACK_OK != ret)
{
return ret;
}
+/*
+ * Since security version discovery does not used anymore, disable security version discovery.
+ * Need to discussion to removing all version discovery related codes.
+ */
+#if 0
static OCStackResult SecurityVersionDiscovery(DiscoveryInfo* discoveryInfo,
const OCClientResponse *clientResponse)
{
return ret;
}
+#endif
/**
* Function to print OCProvisionDev_t for debug purpose.