replace : iotivity -> iotivity-sec
[platform/upstream/iotivity.git] / resource / csdk / security / provisioning / src / pmutility.c
index bdf08c5..0efb109 100644 (file)
 #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"
 
@@ -71,17 +75,6 @@ typedef struct _DiscoveryInfo{
 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.
  *
@@ -94,6 +87,22 @@ static OCStackResult SecurityVersionDiscovery(DiscoveryInfo* discoveryInfo,
 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.
  *
@@ -106,7 +115,13 @@ static OCStackApplicationResult DeviceDiscoveryHandler(void *ctx, OCDoHandle UNU
  */
 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.
  *
@@ -118,6 +133,7 @@ static OCStackApplicationResult SecurePortDiscoveryHandler(void *ctx, OCDoHandle
  */
 static OCStackApplicationResult SecVersionDiscoveryHandler(void *ctx, OCDoHandle UNUSED,
                                 OCClientResponse *clientResponse);
+#endif
 
 /**
  * Function to search node in linked list that matches given IP and port.
@@ -139,7 +155,7 @@ OCProvisionDev_t* GetDevice(OCProvisionDev_t **ppDevicesList, const char* addr,
     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;
         }
@@ -179,11 +195,12 @@ OCStackResult AddDevice(OCProvisionDev_t **ppDevicesList, OCDevAddr* endpoint,
 
         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);
@@ -246,7 +263,8 @@ static OCStackResult UpdateSecurePortOfDevice(OCProvisionDev_t **ppDevicesList,
         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;
@@ -281,7 +299,7 @@ OCStackResult UpdateSecVersionOfDevice(OCProvisionDev_t **ppDevicesList, const c
         return OC_STACK_ERROR;
     }
 
-    OICStrcpy(ptr->secVer, MAX_VERSION_LEN, secVer);
+    OICStrcpy(ptr->secVer, OIC_SEC_MAX_VER_LEN, secVer);
 
     return OC_STACK_OK;
 }
@@ -346,11 +364,11 @@ OCProvisionDev_t* PMCloneOCProvisionDev(const OCProvisionDev_t* src)
 
     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;
@@ -511,8 +529,23 @@ bool PMGenerateQuery(bool isSecure,
             }
 
             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;
@@ -525,6 +558,11 @@ bool PMGenerateQuery(bool isSecure,
     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)
 {
@@ -597,6 +635,7 @@ static OCStackApplicationResult SecurityVersionDiscoveryHandler(void *ctx, OCDoH
 
     return  OC_STACK_DELETE_TRANSACTION;
 }
+#endif
 
 static OCStackApplicationResult SecurePortDiscoveryHandler(void *ctx, OCDoHandle UNUSED,
                                  OCClientResponse *clientResponse)
@@ -703,7 +742,6 @@ static OCStackApplicationResult SecurePortDiscoveryHandler(void *ctx, OCDoHandle
                 return OC_STACK_DELETE_TRANSACTION;
             }
 #endif
-
             OIC_LOG(INFO, TAG, "Exiting SecurePortDiscoveryHandler.");
         }
 
@@ -767,7 +805,7 @@ static OCStackApplicationResult DeviceDiscoveryHandler(void *ctx, OCDoHandle UNU
                 // 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.");
@@ -784,13 +822,6 @@ static OCStackApplicationResult DeviceDiscoveryHandler(void *ctx, OCDoHandle UNU
                     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))) )
@@ -799,9 +830,8 @@ static OCStackApplicationResult DeviceDiscoveryHandler(void *ctx, OCDoHandle UNU
                     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);
@@ -816,7 +846,6 @@ static OCStackApplicationResult DeviceDiscoveryHandler(void *ctx, OCDoHandle UNU
                     DeleteDoxmBinData(ptrDoxm);
                     return OC_STACK_KEEP_TRANSACTION;
                 }
-
                 res = SecurePortDiscovery(pDInfo, clientResponse);
                 if(OC_STACK_OK != res)
                 {
@@ -827,7 +856,6 @@ static OCStackApplicationResult DeviceDiscoveryHandler(void *ctx, OCDoHandle UNU
 
                 OIC_LOG(INFO, TAG, "Exiting ProvisionDiscoveryHandler.");
             }
-
             return  OC_STACK_KEEP_TRANSACTION;
         }
     }
@@ -964,12 +992,15 @@ OCStackResult PMSingleDeviceDiscovery(unsigned short waittime, const OicUuid_t*
         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. .
  *
@@ -1049,7 +1080,113 @@ OCStackResult PMDeviceDiscovery(unsigned short waittime, bool isOwned, OCProvisi
     return res;
 }
 
-#ifdef _ENABLE_MULTIPLE_OWNER_
+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 MULTIPLE_OWNER
 static OCStackApplicationResult MOTDeviceDiscoveryHandler(void *ctx, OCDoHandle UNUSED,
                                 OCClientResponse *clientResponse)
 {
@@ -1224,8 +1361,15 @@ OCStackResult PMMultipleOwnerDeviceDiscovery(unsigned short waittime, bool isMul
         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)
@@ -1282,7 +1426,7 @@ OCStackResult PMMultipleOwnerDeviceDiscovery(unsigned short waittime, bool isMul
     return res;
 }
 
-#endif //_ENABLE_MULTIPLE_OWNER_
+#endif //MULTIPLE_OWNER
 
 static OCStackResult SecurePortDiscovery(DiscoveryInfo* discoveryInfo,
                                          const OCClientResponse *clientResponse)
@@ -1343,6 +1487,11 @@ static OCStackResult SecurePortDiscovery(DiscoveryInfo* discoveryInfo,
     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)
 {
@@ -1385,6 +1534,7 @@ static OCStackResult SecurityVersionDiscovery(DiscoveryInfo* discoveryInfo,
 
     return ret;
 }
+#endif
 
 /**
  * Function to print OCProvisionDev_t for debug purpose.