Modify to update rowner as PT's UUID when ownership transfer is done.
[platform/upstream/iotivity.git] / resource / csdk / security / provisioning / sample / provisioningclient.c
index ee44606..ab423b4 100644 (file)
@@ -46,7 +46,8 @@ extern "C"
 #define _30_PROVIS_PAIR_DEVS_   30
 #define _31_PROVIS_CRED_        31
 #define _32_PROVIS_ACL_         32
-#define _33_CHECK_LINK_STATUS_  33
+#define _33_PROVIS_DP_           33
+#define _34_CHECK_LINK_STATUS_  34
 #define _40_UNLINK_PAIR_DEVS_   40
 #define _50_REMOVE_SELEC_DEV_   50
 #define _99_EXIT_PRVN_CLT_      99
@@ -59,9 +60,14 @@ extern "C"
 #define TAG "provisioningclient"
 
 static const char* ACL_PEMISN[5] = {"CREATE", "READ", "WRITE", "DELETE", "NOTIFY"};
-static const char* SVR_DB_FILE_NAME = "oic_svr_db_client.json";
+static const char* SVR_DB_FILE_NAME = "oic_svr_db_client.dat";
         // '_' for separaing from the same constant variable in |srmresourcestrings.c|
 static const char* PRVN_DB_FILE_NAME = "oic_prvn_mng.db";
+static const OicSecPrm_t  SUPPORTED_PRMS[1] =
+{
+    PRM_PRE_CONFIGURED,
+};
+
 // |g_ctx| means provision manager application context and
 // the following, includes |un/own_list|, could be variables, which |g_ctx| has,
 // for accessing all function(s) for these, they are declared on global domain
@@ -76,6 +82,7 @@ static bool g_doneCB;
 
 // function declaration(s) for calling them before implementing
 static OicSecAcl_t* createAcl(const int);
+static OicSecPdAcl_t* createPdAcl(const int);
 static OCProvisionDev_t* getDevInst(const OCProvisionDev_t*, const int);
 static int printDevList(const OCProvisionDev_t*);
 static size_t printUuidList(const OCUuidList_t*);
@@ -142,6 +149,20 @@ static void provisionAclCB(void* ctx, int nOfRes, OCProvisionResult_t* arr, bool
     g_doneCB = true;
 }
 
+static void provisionDPCB(void* ctx, int nOfRes, OCProvisionResult_t* arr, bool hasError)
+{
+    if(!hasError)
+    {
+        OIC_LOG_V(INFO, TAG, "Provision Direct-Pairing SUCCEEDED - ctx: %s", (char*) ctx);
+    }
+    else
+    {
+        OIC_LOG_V(ERROR, TAG, "Provision Direct-Pairing FAILED - ctx: %s", (char*) ctx);
+        printResultList((const OCProvisionResult_t*) arr, nOfRes);
+    }
+    g_doneCB = true;
+}
+
 static void unlinkDevicesCB(void* ctx, int nOfRes, OCProvisionResult_t* arr, bool hasError)
 {
     if(!hasError)
@@ -245,7 +266,7 @@ static int initProvisionClient(void)
         return -1;
     }
     otmcb.loadSecretCB = InputPinCodeCallback;
-    otmcb.createSecureSessionCB = CreateSecureSessionRandomPinCallbak;
+    otmcb.createSecureSessionCB = CreateSecureSessionRandomPinCallback;
     otmcb.createSelectOxmPayloadCB = CreatePinBasedSelectOxmPayload;
     otmcb.createOwnerTransferPayloadCB = CreatePinBasedOwnerTransferPayload;
     if(OC_STACK_OK != OCSetOwnerTransferCallbackData(OIC_RANDOM_DEVICE_PIN, &otmcb))
@@ -560,10 +581,13 @@ static int provisionAcl(void)
     // for error checking, the return value saved and printed
     g_doneCB = false;
     printf("   Provisioning Selected ACL..\n");
-    OCStackResult rst =
-            OCProvisionACL((void*) g_ctx,
-                    getDevInst((const OCProvisionDev_t*) g_own_list, dev_num),
-                    acl, provisionAclCB);
+    OCProvisionDev_t* dev = getDevInst((const OCProvisionDev_t*) g_own_list, dev_num);
+    if(!dev)
+    {
+        OIC_LOG(ERROR, TAG, "provisionAcl: device instance empty");
+        goto PVACL_ERROR;
+    }
+    OCStackResult rst = OCProvisionACL((void*) g_ctx, dev, acl, provisionAclCB);
     if(OC_STACK_OK != rst)
     {
         OIC_LOG_V(ERROR, TAG, "OCProvisionACL API error: %d", rst);
@@ -586,6 +610,104 @@ PVACL_ERROR:
     return -1;
 }
 
+static int provisionDirectPairing(void)
+{
+    // check |own_list| for provisioning direct-pairing
+    if(!g_own_list || 1>g_own_cnt)
+    {
+        printf("   > Owned Device List, to Provision ACL, is Empty\n");
+        printf("   > Please Register Unowned Devices first, with [20] Menu\n");
+        return 0;  // normal case
+    }
+
+    // select device for provisioning direct-pairing
+    int dev_num = 0;
+    for( ; ; )
+    {
+        printf("   > Enter Device Number, for Provisioning Direct-Pairing: ");
+        for(int ret=0; 1!=ret; )
+        {
+            ret = scanf("%d", &dev_num);
+            for( ; 0x20<=getchar(); );  // for removing overflow garbages
+                                        // '0x20<=code' is character region
+        }
+        if(0<dev_num && g_own_cnt>=dev_num)
+        {
+            break;
+        }
+        printf("     Entered Wrong Number. Please Enter Again\n");
+    }
+
+    // create Direct-Pairing Configuration(PIN, PDACL) for selected device
+    // TODO: default acl -> input from user !
+    OicSecPconf_t pconf;
+    memset(&pconf, 0, sizeof(OicSecPconf_t));
+
+    // set enable dp
+    pconf.edp = true;
+
+    // set default supported PRM types
+    pconf.prmLen = sizeof(SUPPORTED_PRMS)/sizeof(OicSecPrm_t);
+    pconf.prm = (OicSecPrm_t *)OICCalloc(pconf.prmLen, sizeof(OicSecPrm_t));
+    if(pconf.prm)
+    {
+        for (size_t i=0; i<pconf.prmLen; i++)
+        {
+            pconf.prm[i] = SUPPORTED_PRMS[i];
+        }
+    }
+    else
+    {
+        OIC_LOG(ERROR, TAG, "create prm error return");
+        goto PVDP_ERROR;
+    }
+
+    // set default pin
+    const char DP_DEFAULT_PIN[] = "00000000";
+    memcpy(pconf.pin.val, DP_DEFAULT_PIN, DP_PIN_LENGTH);
+
+    // set default pdacl
+    pconf.pdacls = createPdAcl(dev_num);
+    if(!pconf.pdacls)
+    {
+        OIC_LOG(ERROR, TAG, "createPdAcl error return");
+        goto PVDP_ERROR;
+    }
+
+    // call |OCProvisionDirectPairing| API actually
+    // calling this API with callback actually acts like blocking
+    // for error checking, the return value saved and printed
+    g_doneCB = false;
+    printf("   Atempt Direct-Pairing Provisioning (PIN : [%s])..\n", (char*)pconf.pin.val);
+    OCStackResult rst = OCProvisionDirectPairing((void*) g_ctx,
+                                       getDevInst((const OCProvisionDev_t*) g_own_list, dev_num),
+                                       &pconf, provisionDPCB);
+    if(OC_STACK_OK != rst)
+    {
+        OIC_LOG_V(ERROR, TAG, "OCProvisionDirectPairing API error: %d", rst);
+        if (OC_STACK_UNAUTHORIZED_REQ == rst)
+        {
+            OIC_LOG(ERROR, TAG, "Target Server NOT Support Direct-Pairing !!! (DPC == false)");
+        }
+        goto PVDP_ERROR;
+    }
+    if(waitCallbackRet())  // input |g_doneCB| flag implicitly
+    {
+        OIC_LOG(ERROR, TAG, "OCProvisionCredentials callback error");
+        goto PVDP_ERROR;
+    }
+    OCDeletePdAclList(pconf.pdacls);
+
+    // display the PCONF-provisioned result
+    printf("   > SUCCESS to provision Direct-Pairing !!\n");
+
+    return 0;
+
+PVDP_ERROR:
+    OCDeletePdAclList(pconf.pdacls);  // after here |acl| points nothing
+    return -1;
+}
+
 static int checkLinkedStatus(void)
 {
     // check |own_list| for checking selected link status on PRVN DB
@@ -783,7 +905,7 @@ static OicSecAcl_t* createAcl(const int dev_num)
             for( ; 0x20<=getchar(); );  // for removing overflow garbages
                                         // '0x20<=code' is character region
         }
-        if(num && g_own_cnt>=num && dev_num!=num)
+        if(0<num && g_own_cnt>=num && dev_num!=num)
         {
             break;
         }
@@ -805,12 +927,11 @@ static OicSecAcl_t* createAcl(const int dev_num)
                 // '16' is |ACL_RESRC_MAX_NUM|
         for(int ret=0; 1!=ret; )
         {
-            ret = scanf("%zu", &acl->resourcesLen);
+            ret = scanf("%d", &num);
             for( ; 0x20<=getchar(); );  // for removing overflow garbages
                                         // '0x20<=code' is character region
         }
-        if(acl->resourcesLen && ACL_RESRC_MAX_NUM>=acl->resourcesLen)
-                // |acl->resourcesLen| is unsigned
+        if(0<num && ACL_RESRC_MAX_NUM>=num)
         {
             break;
         }
@@ -821,15 +942,15 @@ static OicSecAcl_t* createAcl(const int dev_num)
     // enter actually each 'accessed' |resources| name
     printf("         Enter Each Accessed Resource Name (each under 128 char)\n");
             // '128' is ACL_RESRC_MAX_LEN
-    num = acl->resourcesLen;
-    acl->resources = (char**) OICCalloc(num, sizeof(char*));
+    acl->resourcesLen = (unsigned) num;
+    acl->resources = (char**) OICCalloc(acl->resourcesLen, sizeof(char*));
     if(!acl->resources)
     {
         OIC_LOG(ERROR, TAG, "createAcl: OICCalloc error return");
         goto CRACL_ERROR;
     }
     char rsrc_in[ACL_RESRC_MAX_LEN+1] = {0};  // '1' for null termination
-    for(int i=0; num>i; ++i)
+    for(int i=0; acl->resourcesLen>(unsigned)i; ++i)
     {
         printf("         Enter Accessed Resource[%d] Name: ", i+1);
         for(int ret=0; 1!=ret; )
@@ -881,36 +1002,30 @@ static OicSecAcl_t* createAcl(const int dev_num)
     acl->permission = pmsn;
 
     // enter |owner| device number
+    int own_num = 0;
     for( ; ; )
     {
         printf("   > [D] Enter Owner Device Number: ");
         for(int ret=0; 1!=ret; )
         {
-            ret = scanf("%d", &num);
+            ret = scanf("%d", &own_num);
             for( ; 0x20<=getchar(); );  // for removing overflow garbages
                                         // '0x20<=code' is character region
         }
-        if(num && g_own_cnt>=num)
+        if(0<own_num && g_own_cnt>=own_num)
         {
             break;
         }
         printf("         Entered Wrong Number. Please Enter Again\n");
     }
-    acl->ownersLen = 1;
-    acl->owners = (OicUuid_t*) OICCalloc(1, sizeof(OicUuid_t));
-    if(!acl->owners)
-    {
-        OIC_LOG(ERROR, TAG, "createAcl: OICCalloc error return");
-        goto CRACL_ERROR;
-    }
 
-    dev = getDevInst((const OCProvisionDev_t*)g_own_list, num);
+    dev = getDevInst((const OCProvisionDev_t*)g_own_list, own_num);
     if(!dev || !dev->doxm)
     {
         OIC_LOG(ERROR, TAG, "createAcl: device instance empty");
         goto CRACL_ERROR;
     }
-    memcpy(acl->owners, &dev->doxm->deviceID, UUID_LENGTH);
+    memcpy(&acl->rownerID, &dev->doxm->deviceID, sizeof(OicUuid_t));
     printf("\n");
 
     return acl;
@@ -920,6 +1035,59 @@ CRACL_ERROR:
     return NULL;
 }
 
+static OicSecPdAcl_t* createPdAcl(const int dev_num)
+{
+    if(0>=dev_num || g_own_cnt<dev_num)
+    {
+        OIC_LOG(ERROR, TAG, "createAcl invalid parameters");
+        return NULL;  // not need to 'goto' |ERROR| before allocating |acl|
+    }
+
+    // allocate memory for |pdacl| struct
+    printf("   **** Create PDACL for the Selected Device[%d]\n", dev_num);
+    OicSecPdAcl_t* pdAcl = (OicSecPdAcl_t*) OICCalloc(1, sizeof(OicSecPdAcl_t));
+    if(!pdAcl)
+    {
+        OIC_LOG(ERROR, TAG, "createAcl: OICCalloc error return");
+        return NULL;  // not need to 'goto' |ERROR| before allocating |acl|
+    }
+
+
+    // number of resources
+    char rsrc_in[][ACL_RESRC_MAX_LEN+1] = {"*", "/rsrc/*"};
+    pdAcl->resourcesLen = 1;
+
+    // resource
+    int num = pdAcl->resourcesLen;
+    pdAcl->resources = (char**) OICCalloc(num, sizeof(char*));
+    if(!pdAcl->resources)
+    {
+        OIC_LOG(ERROR, TAG, "createPdAcl: OICCalloc error return");
+        goto CRPDACL_ERROR;
+    }
+    for(int i=0; num>i; ++i)
+    {
+        size_t len = strlen(rsrc_in[i])+1;  // '1' for null termination
+        char* rsrc = (char*) OICCalloc(len, sizeof(char));
+        if(!rsrc)
+        {
+            OIC_LOG(ERROR, TAG, "createPdAcl: OICCalloc error return");
+            goto CRPDACL_ERROR;
+        }
+        OICStrcpy(rsrc, len, rsrc_in[i]);
+        pdAcl->resources[i] = rsrc;  // after here, |rsrc| points nothing
+    }
+
+    // permission
+    pdAcl->permission = PERMISSION_FULL_CONTROL;
+
+    return pdAcl;
+
+CRPDACL_ERROR:
+    OCDeletePdAclList(pdAcl);
+    return NULL;
+}
+
 static OCProvisionDev_t* getDevInst(const OCProvisionDev_t* dev_lst, const int dev_num)
 {
     if(!dev_lst || 0>=dev_num)
@@ -1098,7 +1266,8 @@ static void printMenu(void)
     printf("** 30. Provision/Link Pairwise Things\n");
     printf("** 31. Provision Credentials for Pairwise Things\n");
     printf("** 32. Provision the Selected Access Control List(ACL)\n");
-    printf("** 33. Check Linked Status of the Selected Device on PRVN DB\n\n");
+    printf("** 33. Provision Direct-Pairing Configuration\n");
+    printf("** 34. Check Linked Status of the Selected Device on PRVN DB\n\n");
 
     printf("** [D] UNLINK PAIRWISE THINGS\n");
     printf("** 40. Unlink Pairwise Things\n\n");
@@ -1200,10 +1369,16 @@ int main()
                 OIC_LOG(ERROR, TAG, "_32_PROVIS_ACL_: error");
             }
             break;
-        case _33_CHECK_LINK_STATUS_:
+        case _33_PROVIS_DP_:
+            if(provisionDirectPairing())
+            {
+                OIC_LOG(ERROR, TAG, "_33_PROVIS_DP_: error");
+            }
+            break;
+        case _34_CHECK_LINK_STATUS_:
             if(checkLinkedStatus())
             {
-                OIC_LOG(ERROR, TAG, "_33_CHECK_LINK_STATUS_: error");
+                OIC_LOG(ERROR, TAG, "_34_CHECK_LINK_STATUS_: error");
             }
             break;
         case _40_UNLINK_PAIR_DEVS_: