1 /******************************************************************
3 * Copyright 2015 Samsung Electronics All Rights Reserved.
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
19 *****************************************************************/
21 #include "iotivity_config.h"
31 #include "oic_malloc.h"
32 #include "oic_string.h"
33 #include "ocprovisioningmanager.h"
34 #include "oxmjustworks.h"
35 #include "oxmrandompin.h"
36 #include "securevirtualresourcetypes.h"
37 #include "srmutility.h"
39 #include "oxmverifycommon.h"
40 #include "pkix_interface.h"
41 #include "hw_emul/hw_interface.h"
42 #include "mbedtls/x509_crt.h"
49 // declaration(s) for provisioning client using C-level provisioning API
50 // user input definition for main loop on provisioning client
51 #define _10_DISCOV_ALL_DEVS_ 10
52 #define _11_DISCOV_UNOWN_DEVS_ 11
53 #define _12_DISCOV_OWN_DEVS_ 12
55 #define _13_MOT_DISCOV_DEV_ 13
56 #endif //MULTIPLE_OWNER
57 #define _20_REGIST_DEVS_ 20
58 #define _30_PROVIS_PAIR_DEVS_ 30
59 #define _31_PROVIS_CRED_ 31
60 #define _32_PROVIS_ACL_ 32
61 #define _33_PROVIS_DP_ 33
62 #define _34_CHECK_LINK_STATUS_ 34
63 #define _35_SAVE_ACL_ 35
64 #define _40_UNLINK_PAIR_DEVS_ 40
65 #define _50_REMOVE_SELEC_DEV_ 50
66 #define _51_REMOVE_DEV_WITH_UUID_ 51
67 #define _52_RESET_SELEC_DEV_ 52
68 #define _53_RESET_SVR_DB_ 53
69 #define _60_GET_CRED_ 60
70 #define _61_GET_ACL_ 61
72 #define _70_MOT_CHANGE_MOM_ 70
73 #define _71_MOT_PROV_PRECONF_PIN_ 71
74 #define _72_MOT_OXM_SEL_ 72
75 #define _73_MOT_REMOVE_SUBOWNER_ 73
76 #define _74_MOT_REMOVE_ALL_SUBOWNER_ 74
77 #endif //MULTIPLE_OWNER
78 #define _80_SELECT_PROTOCOL_ 80
79 #define _81_SELECT_VERIF_METHOD_ 81
80 #define _82_SECURE_STORAGE_HW_EMULATION_ 82
81 #define _99_EXIT_PRVN_CLT_ 99
83 #define ACL_RESRC_MAX_NUM 16
84 #define ACL_RESRC_ARRAY_SIZE 3 //This value is used only for sample (not OCF spec)
85 #define ACL_RESRC_MAX_LEN 128
86 #define ACL_PEMISN_CNT 5
87 #define DISCOVERY_TIMEOUT 10 // 10 sec
88 #define CALLBACK_TIMEOUT 60 // 1 min
89 #define TAG "provisioningclient"
91 static const char* ACL_PEMISN[5] = {"CREATE", "READ", "WRITE", "DELETE", "NOTIFY"};
92 static const char* SVR_DB_FILE_NAME = "oic_svr_db_client.dat";
93 // '_' for separaing from the same constant variable in |srmresourcestrings.c|
94 static const char* PRVN_DB_FILE_NAME = "oic_prvn_mng.db";
95 static const OicSecPrm_t SUPPORTED_PRMS[1] =
100 // |g_ctx| means provision manager application context and
101 // the following, includes |un/own_list|, could be variables, which |g_ctx| has,
102 // for accessing all function(s) for these, they are declared on global domain
103 static const char* g_ctx = "Provision Manager Client Application Context";
104 static char* g_svr_fname;
105 static char* g_prvn_fname;
106 static OCProvisionDev_t* g_own_list;
107 static OCProvisionDev_t* g_unown_list;
108 static int g_own_cnt;
109 static int g_unown_cnt;
110 #ifdef MULTIPLE_OWNER
111 static OCProvisionDev_t* g_mot_enable_list;
112 static int g_mot_enable_cnt;
113 #endif //MULTIPLE_OWNER
115 static bool g_doneCB;
117 static int secure_protocol = 1;
118 static void setDevProtocol(OCProvisionDev_t* dev_lst);
120 // function declaration(s) for calling them before implementing
121 static OicSecAcl_t* createAcl(const int);
122 static OicSecAcl_t* createSimpleAcl(const OicUuid_t uuid);
123 static OicSecPdAcl_t* createPdAcl(const int);
124 static OCProvisionDev_t* getDevInst(const OCProvisionDev_t*, const int);
125 static int printDevList(const OCProvisionDev_t*);
126 static size_t printUuidList(const OCUuidList_t*);
127 static int printResultList(const OCProvisionResult_t*, const int);
128 static void printUuid(const OicUuid_t*);
129 static FILE* fopen_prvnMng(const char*, const char*);
130 static int waitCallbackRet(void);
131 static int selectTwoDiffNum(int*, int*, const int, const char*);
133 // callback function(s) for provisioning client using C-level provisioning API
134 static void ownershipTransferCB(void* ctx, int nOfRes, OCProvisionResult_t* arr, bool hasError)
138 OIC_LOG_V(INFO, TAG, "Ownership Transfer SUCCEEDED - ctx: %s", (char*) ctx);
142 OIC_LOG_V(ERROR, TAG, "Ownership Transfer FAILED - ctx: %s", (char*) ctx);
143 printResultList((const OCProvisionResult_t*) arr, nOfRes);
148 static void provisionPairwiseCB(void* ctx, int nOfRes, OCProvisionResult_t* arr, bool hasError)
152 OIC_LOG_V(INFO, TAG, "Provision Pairwise SUCCEEDED - ctx: %s", (char*) ctx);
156 OIC_LOG_V(ERROR, TAG, "Provision Pairwise FAILED - ctx: %s", (char*) ctx);
157 printResultList((const OCProvisionResult_t*) arr, nOfRes);
162 static void provisionCredCB(void* ctx, int nOfRes, OCProvisionResult_t* arr, bool hasError)
166 OIC_LOG_V(INFO, TAG, "Provision Credential SUCCEEDED - ctx: %s", (char*) ctx);
170 OIC_LOG_V(ERROR, TAG, "Provision Credential FAILED - ctx: %s", (char*) ctx);
171 printResultList((const OCProvisionResult_t*) arr, nOfRes);
176 static void provisionAclCB(void* ctx, int nOfRes, OCProvisionResult_t* arr, bool hasError)
180 OIC_LOG_V(INFO, TAG, "Provision ACL SUCCEEDED - ctx: %s", (char*) ctx);
184 OIC_LOG_V(ERROR, TAG, "Provision ACL FAILED - ctx: %s", (char*) ctx);
185 printResultList((const OCProvisionResult_t*) arr, nOfRes);
190 static void getCredCB(void* ctx, int nOfRes, OCProvisionResult_t* arr, bool hasError)
194 OIC_LOG_V(INFO, TAG, "getCredCB SUCCEEDED - ctx: %s", (char*) ctx);
198 OIC_LOG_V(ERROR, TAG, "getCredCB FAILED - ctx: %s", (char*) ctx);
199 printResultList((const OCProvisionResult_t*) arr, nOfRes);
204 static void getAclCB(void* ctx, int nOfRes, OCProvisionResult_t* arr, bool hasError)
208 OIC_LOG_V(INFO, TAG, "getAclCB SUCCEEDED - ctx: %s", (char*) ctx);
212 OIC_LOG_V(ERROR, TAG, "getAclCB FAILED - ctx: %s", (char*) ctx);
213 printResultList((const OCProvisionResult_t*) arr, nOfRes);
218 static void provisionDPCB(void* ctx, int nOfRes, OCProvisionResult_t* arr, bool hasError)
222 OIC_LOG_V(INFO, TAG, "Provision Direct-Pairing SUCCEEDED - ctx: %s", (char*) ctx);
226 OIC_LOG_V(ERROR, TAG, "Provision Direct-Pairing FAILED - ctx: %s", (char*) ctx);
227 printResultList((const OCProvisionResult_t*) arr, nOfRes);
232 static void unlinkDevicesCB(void* ctx, int nOfRes, OCProvisionResult_t* arr, bool hasError)
236 OIC_LOG_V(INFO, TAG, "Unlink Devices SUCCEEDED - ctx: %s", (char*) ctx);
240 OIC_LOG_V(ERROR, TAG, "Unlink Devices FAILED - ctx: %s", (char*) ctx);
241 printResultList((const OCProvisionResult_t*) arr, nOfRes);
246 static void removeDeviceCB(void* ctx, int nOfRes, OCProvisionResult_t* arr, bool hasError)
250 OIC_LOG_V(INFO, TAG, "Remove Device SUCCEEDED - ctx: %s", (char*) ctx);
254 OIC_LOG_V(ERROR, TAG, "Remove Device FAILED - ctx: %s", (char*) ctx);
255 printResultList((const OCProvisionResult_t*) arr, nOfRes);
260 static void syncDeviceCB(void* ctx, int nOfRes, OCProvisionResult_t* arr, bool hasError)
264 OIC_LOG_V(INFO, TAG, "Sync Device SUCCEEDED - ctx: %s", (char*) ctx);
268 OIC_LOG_V(ERROR, TAG, "Sync Device FAILED - ctx: %s", (char*) ctx);
269 printResultList((const OCProvisionResult_t*) arr, nOfRes);
274 #ifdef MULTIPLE_OWNER
275 static void updateDoxmForMOTCB(void* ctx, int nOfRes, OCProvisionResult_t* arr, bool hasError)
279 OIC_LOG_V(INFO, TAG, "POST 'doxm' SUCCEEDED - ctx: %s", (char*) ctx);
283 OIC_LOG_V(ERROR, TAG, "POST 'doxm' FAILED - ctx: %s", (char*) ctx);
284 printResultList((const OCProvisionResult_t*) arr, nOfRes);
289 static void deleteDoxmForMOTCB(void* ctx, int nOfRes, OCProvisionResult_t* arr, bool hasError)
293 OIC_LOG_V(INFO, TAG, "DELETE 'doxm' SUCCEEDED - ctx: %s", (char*) ctx);
297 OIC_LOG_V(ERROR, TAG, "DELETE 'doxm' FAILED - ctx: %s", (char*) ctx);
298 printResultList((const OCProvisionResult_t*) arr, nOfRes);
303 #endif //MULTIPLE_OWNER
305 static void inputPinCB(char* pin, size_t len)
307 if(!pin || OXM_RANDOM_PIN_MIN_SIZE > len)
309 OIC_LOG(ERROR, TAG, "inputPinCB invalid parameters");
313 printf(" > INPUT PIN: ");
314 for(int ret=0; 1!=ret; )
316 ret = scanf("%32s", pin);
317 for( ; 0x20<=getchar(); ); // for removing overflow garbages
318 // '0x20<=code' is character region
322 // function(s) for provisioning client using C-level provisioning API
323 static int initProvisionClient(void)
325 // initialize persistent storage for SVR DB
326 static OCPersistentStorage pstStr =
328 .open = fopen_prvnMng,
334 if(OC_STACK_OK != OCRegisterPersistentStorageHandler(&pstStr))
336 OIC_LOG(ERROR, TAG, "OCRegisterPersistentStorageHandler error");
340 // initialize OC stack and provisioning manager
341 if(OC_STACK_OK != OCInit(NULL, 0, OC_CLIENT_SERVER))
343 OIC_LOG(ERROR, TAG, "OCStack init error");
347 if (access(PRVN_DB_FILE_NAME, F_OK) != -1)
349 printf("************************************************************\n");
350 printf("************Provisioning DB file already exists.************\n");
351 printf("************************************************************\n");
355 printf("*************************************************************\n");
356 printf("************No provisioning DB file, creating new************\n");
357 printf("*************************************************************\n");
360 if(OC_STACK_OK != OCInitPM(PRVN_DB_FILE_NAME))
362 OIC_LOG(ERROR, TAG, "OC_PM init error");
366 SetInputPinCB(inputPinCB);
371 static int discoverAllDevices(void)
373 // delete un/owned device lists before updating them
376 OCDeleteDiscoveredDevices(g_own_list);
381 OCDeleteDiscoveredDevices(g_unown_list);
385 // call |OCGetDevInfoFromNetwork| API actually
386 printf(" Discovering All Un/Owned Devices on Network..\n");
387 if(OC_STACK_OK != OCGetDevInfoFromNetwork(DISCOVERY_TIMEOUT, &g_own_list, &g_unown_list))
389 OIC_LOG(ERROR, TAG, "OCGetDevInfoFromNetwork API error");
393 // display the discovered un/owned lists
394 printf(" > Discovered Owned Devices\n");
395 g_own_cnt = printDevList(g_own_list);
396 printf(" > Discovered Unowned Devices\n");
397 g_unown_cnt = printDevList(g_unown_list);
399 setDevProtocol(g_own_list);
400 setDevProtocol(g_unown_list);
406 static int discoverUnownedDevices(void)
408 // delete unowned device list before updating it
411 OCDeleteDiscoveredDevices(g_unown_list);
415 // call |OCDiscoverUnownedDevices| API actually
416 printf(" Discovering Only Unowned Devices on Network..\n");
417 if(OC_STACK_OK != OCDiscoverUnownedDevices(DISCOVERY_TIMEOUT, &g_unown_list))
419 OIC_LOG(ERROR, TAG, "OCDiscoverUnownedDevices API error");
423 // display the discovered unowned list
424 printf(" > Discovered Unowned Devices\n");
425 g_unown_cnt = printDevList(g_unown_list);
427 setDevProtocol(g_unown_list);
432 static int discoverOwnedDevices(void)
434 // delete owned device list before updating it
437 OCDeleteDiscoveredDevices(g_own_list);
441 // call |OCDiscoverOwnedDevices| API actually
442 printf(" Discovering Only Owned Devices on Network..\n");
443 if(OC_STACK_OK != OCDiscoverOwnedDevices(DISCOVERY_TIMEOUT, &g_own_list))
445 OIC_LOG(ERROR, TAG, "OCDiscoverOwnedDevices API error");
449 // display the discovered owned list
450 printf(" > Discovered Owned Devices\n");
451 g_own_cnt = printDevList(g_own_list);
453 setDevProtocol(g_own_list);
458 #ifdef MULTIPLE_OWNER
459 static int discoverMOTEnabledDevices(void)
461 // delete owned device list before updating it
462 if(g_mot_enable_list)
464 OCDeleteDiscoveredDevices(g_mot_enable_list);
465 g_mot_enable_list = NULL;
468 // call |OCDiscoverOwnedDevices| API actually
469 printf(" Discovering Multiple Ownership Transfer Enabled Devices on Network..\n");
470 if(OC_STACK_OK != OCDiscoverMultipleOwnerEnabledDevices(DISCOVERY_TIMEOUT, &g_mot_enable_list))
472 OIC_LOG(ERROR, TAG, "OCDiscoverMultipleOwnerEnalbedDevices API error");
476 // display the discovered owned list
477 printf(" > Discovered Multiple Ownership Transfer Enabled Devices\n");
478 g_mot_enable_cnt = printDevList(g_mot_enable_list);
482 #endif //MULTIPLE_OWNER
484 static int registerDevices(void)
486 // check |unown_list| for registering devices
487 if(!g_unown_list || 0>=g_unown_cnt)
489 printf(" > Unowned Device List, to Register Devices, is Empty\n");
490 printf(" > Please Discover Unowned Devices first, with [10|11] Menu\n");
491 return 0; // normal case
494 // call |OCDoOwnershipTransfer| API actually
495 // calling this API with callback actually acts like blocking
496 // for error checking, the return value saved and printed
498 printf(" Registering All Discovered Unowned Devices..\n");
499 OCStackResult rst = OCDoOwnershipTransfer((void*) g_ctx, g_unown_list, ownershipTransferCB);
500 if(OC_STACK_OK != rst)
502 OIC_LOG_V(ERROR, TAG, "OCDoOwnershipTransfer API error: %d", rst);
505 if(waitCallbackRet()) // input |g_doneCB| flag implicitly
507 OIC_LOG(ERROR, TAG, "OCProvisionCredentials callback error");
511 // display the registered result
512 printf(" > Registered Discovered Unowned Devices\n");
513 printf(" > Please Discover Owned Devices for the Registered Result, with [10|12] Menu\n");
518 static int provisionPairwise(void)
520 // check |own_list| for provisioning pairwise devices
521 if(!g_own_list || 2>g_own_cnt)
523 printf(" > Owned Device List, to Provision the Pairwise, is Empty\n");
524 printf(" > Please Register Unowned Devices first, with [20] Menu\n");
525 return 0; // normal case
528 // select two devices for provisioning pairwise devices
529 int dev_num[2] = {0};
530 if(selectTwoDiffNum(&(dev_num[0]), &(dev_num[1]), g_own_cnt, "for Linking Devices"))
532 OIC_LOG(ERROR, TAG, "selectTwoDiffNum error return");
533 return -1; // not need to 'goto' |ERROR| before allocating |acl|
536 // create ACL(s) for each selected device
537 OicSecAcl_t* acl[2] = {0};
538 for(int i=0; 2>i; ++i)
540 acl[i] = createAcl(dev_num[i]);
543 OIC_LOG(ERROR, TAG, "createAcl error return");
548 // call |OCProvisionPairwiseDevices| API actually
549 // calling this API with callback actually acts like blocking
550 // for error checking, the return value saved and printed
552 printf(" Provisioning Selected Pairwise Devices..\n");
554 OCProvisionPairwiseDevices((void*) g_ctx,
555 SYMMETRIC_PAIR_WISE_KEY, OWNER_PSK_LENGTH_128,
556 getDevInst((const OCProvisionDev_t*) g_own_list, dev_num[0]), acl[0],
557 getDevInst((const OCProvisionDev_t*) g_own_list, dev_num[1]), acl[1],
558 provisionPairwiseCB);
559 if(OC_STACK_OK != rst)
561 OIC_LOG_V(ERROR, TAG, "OCProvisionPairwiseDevices API error: %d", rst);
564 if(waitCallbackRet()) // input |g_doneCB| flag implicitly
566 OIC_LOG(ERROR, TAG, "OCProvisionCredentials callback error");
569 OCDeleteACLList(acl[0]);
570 OCDeleteACLList(acl[1]);
572 // display the pairwise-provisioned result
573 printf(" > Provisioned Selected Pairwise Devices\n");
574 printf(" > Please Check Device's Status for the Linked Result, with [33] Menu\n");
579 OCDeleteACLList(acl[0]);
580 OCDeleteACLList(acl[1]);
584 static int provisionCred(void)
586 // check |own_list| for provisioning pairwise credentials
587 if(!g_own_list || 2>g_own_cnt)
589 printf(" > Owned Device List, to Provision Credentials, is Empty\n");
590 printf(" > Please Register Unowned Devices first, with [20] Menu\n");
591 return 0; // normal case
594 // select two devices for provisioning pairwise credentials
595 int dev_num[2] = {0};
596 if(selectTwoDiffNum(&(dev_num[0]), &(dev_num[1]), g_own_cnt, "for Linking CRED(s)"))
598 OIC_LOG(ERROR, TAG, "selectTwoDiffNum error return");
602 printf(" Select PSK length..\n");
603 printf(" 1 - 128bit(Default)\n");
604 printf(" 2 - 256bit\n");
607 for(int ret=0; 1!=ret; )
609 ret = scanf("%d",&sizeOption);
610 for( ; 0x20<=getchar(); ); // for removing overflow garbages
611 // '0x20<=code' is character region
619 size = OWNER_PSK_LENGTH_128;
624 size = OWNER_PSK_LENGTH_256;
629 size = OWNER_PSK_LENGTH_128;
635 // call |OCProvisionCredentials| API actually
636 // calling this API with callback actually acts like blocking
637 // for error checking, the return value saved and printed
639 printf(" Provisioning Selected Pairwise Credentials..\n");
641 OCProvisionCredentials((void*) g_ctx,
642 SYMMETRIC_PAIR_WISE_KEY, size,
643 getDevInst((const OCProvisionDev_t*) g_own_list, dev_num[0]),
644 getDevInst((const OCProvisionDev_t*) g_own_list, dev_num[1]),
646 if(OC_STACK_OK != rst)
648 OIC_LOG_V(ERROR, TAG, "OCProvisionCredentials API error: %d", rst);
651 if(waitCallbackRet()) // input |g_doneCB| flag implicitly
653 OIC_LOG(ERROR, TAG, "OCProvisionCredentials callback error");
657 // display the CRED-provisioned result
658 printf(" > Provisioned Selected Pairwise Crendentials\n");
659 printf(" > Please Check Device's Status for the Linked Result, with [34] Menu\n");
664 static int provisionAcl(void)
666 // check |own_list| for provisioning access control list
667 if(!g_own_list || 1>g_own_cnt)
669 printf(" > Owned Device List, to Provision ACL, is Empty\n");
670 printf(" > Please Register Unowned Devices first, with [20] Menu\n");
671 return 0; // normal case
674 // select device for provisioning access control list
678 printf(" > Enter Device Number, for Provisioning ACL: ");
679 for(int ret=0; 1!=ret; )
681 ret = scanf("%d", &dev_num);
682 for( ; 0x20<=getchar(); ); // for removing overflow garbages
683 // '0x20<=code' is character region
685 if(0<dev_num && g_own_cnt>=dev_num)
689 printf(" Entered Wrong Number. Please Enter Again\n");
692 // create ACL for selected device
693 OicSecAcl_t* acl = NULL;
694 acl = createAcl(dev_num);
697 OIC_LOG(ERROR, TAG, "createAcl error return");
701 // call |OCProvisionACL| API actually
702 // calling this API with callback actually acts like blocking
703 // for error checking, the return value saved and printed
705 printf(" Provisioning Selected ACL..\n");
706 OCProvisionDev_t* dev = getDevInst((const OCProvisionDev_t*) g_own_list, dev_num);
709 OIC_LOG(ERROR, TAG, "provisionAcl: device instance empty");
712 OCStackResult rst = OCProvisionACL((void*) g_ctx, dev, acl, provisionAclCB);
713 if(OC_STACK_OK != rst)
715 OIC_LOG_V(ERROR, TAG, "OCProvisionACL API error: %d", rst);
718 if(waitCallbackRet()) // input |g_doneCB| flag implicitly
720 OIC_LOG(ERROR, TAG, "OCProvisionCredentials callback error");
723 OCDeleteACLList(acl); // after here |acl| points nothing
725 // display the ACL-provisioned result
726 printf(" > Provisioned Selected ACL\n");
731 OCDeleteACLList(acl); // after here |acl| points nothing
735 static int provisionDirectPairing(void)
737 // check |own_list| for provisioning direct-pairing
738 if(!g_own_list || 1>g_own_cnt)
740 printf(" > Owned Device List, to Provision ACL, is Empty\n");
741 printf(" > Please Register Unowned Devices first, with [20] Menu\n");
742 return 0; // normal case
745 // select device for provisioning direct-pairing
749 printf(" > Enter Device Number, for Provisioning Direct-Pairing: ");
750 for(int ret=0; 1!=ret; )
752 ret = scanf("%d", &dev_num);
753 for( ; 0x20<=getchar(); ); // for removing overflow garbages
754 // '0x20<=code' is character region
756 if(0<dev_num && g_own_cnt>=dev_num)
760 printf(" Entered Wrong Number. Please Enter Again\n");
763 // create Direct-Pairing Configuration(PIN, PDACL) for selected device
764 // TODO: default acl -> input from user !
766 memset(&pconf, 0, sizeof(OicSecPconf_t));
771 // set default supported PRM types
772 pconf.prmLen = sizeof(SUPPORTED_PRMS)/sizeof(OicSecPrm_t);
773 pconf.prm = (OicSecPrm_t *)OICCalloc(pconf.prmLen, sizeof(OicSecPrm_t));
776 for (size_t i=0; i<pconf.prmLen; i++)
778 pconf.prm[i] = SUPPORTED_PRMS[i];
783 OIC_LOG(ERROR, TAG, "create prm error return");
788 const char DP_DEFAULT_PIN[] = "00000000";
789 memcpy(pconf.pin.val, DP_DEFAULT_PIN, DP_PIN_LENGTH);
792 pconf.pdacls = createPdAcl(dev_num);
795 OIC_LOG(ERROR, TAG, "createPdAcl error return");
799 // call |OCProvisionDirectPairing| API actually
800 // calling this API with callback actually acts like blocking
801 // for error checking, the return value saved and printed
803 printf(" Atempt Direct-Pairing Provisioning (PIN : [%s])..\n", (char*)pconf.pin.val);
804 OCStackResult rst = OCProvisionDirectPairing((void*) g_ctx,
805 getDevInst((const OCProvisionDev_t*) g_own_list, dev_num),
806 &pconf, provisionDPCB);
807 if(OC_STACK_OK != rst)
809 OIC_LOG_V(ERROR, TAG, "OCProvisionDirectPairing API error: %d", rst);
810 if (OC_STACK_UNAUTHORIZED_REQ == rst)
812 OIC_LOG(ERROR, TAG, "Target Server NOT Support Direct-Pairing !!! (DPC == false)");
816 if(waitCallbackRet()) // input |g_doneCB| flag implicitly
818 OIC_LOG(ERROR, TAG, "OCProvisionCredentials callback error");
821 OCDeletePdAclList(pconf.pdacls);
823 // display the PCONF-provisioned result
824 printf(" > SUCCESS to provision Direct-Pairing !!\n");
829 OCDeletePdAclList(pconf.pdacls); // after here |acl| points nothing
833 static int checkLinkedStatus(void)
835 // check |own_list| for checking selected link status on PRVN DB
836 if(!g_own_list || 1>g_own_cnt)
838 printf(" > Owned Device List, to Check Linked Status on PRVN DB, is Empty\n");
839 printf(" > Please Register Unowned Devices first, with [20] Menu\n");
840 return 0; // normal case
843 // select device for checking selected link status on PRVN DB
847 printf(" > Enter Device Number, for Checking Linked Status on PRVN DB: ");
848 for(int ret=0; 1!=ret; )
850 ret = scanf("%d", &dev_num);
851 for( ; 0x20<=getchar(); ); // for removing overflow garbages
852 // '0x20<=code' is character region
854 if(0<dev_num && g_own_cnt>=dev_num)
858 printf(" Entered Wrong Number. Please Enter Again\n");
861 // call |OCGetLinkedStatus| API actually
862 printf(" Checking Selected Link Status on PRVN DB..\n");
863 OCUuidList_t* dvid_lst = NULL;
865 OCProvisionDev_t* dev = getDevInst((const OCProvisionDev_t*)g_own_list, dev_num);
866 if(!dev || !dev->doxm)
868 OIC_LOG(ERROR, TAG, "checkLinkedStatus: device instance empty");
874 &dev->doxm->deviceID,
875 &dvid_lst, &dvid_cnt)) // allow empty list
877 OIC_LOG(ERROR, TAG, "OCGetLinkedStatus API error");
881 // display the linked status result
882 printf(" > Checked Selected Link Status on PRVN DB\n");
883 if(!dvid_lst || !dvid_cnt) // |size_t| is unsigned
885 printf(" Linked Device List is Empty..\n");
886 return 0; // normal case
888 if(dvid_cnt != printUuidList((const OCUuidList_t*) dvid_lst))
890 OIC_LOG(ERROR, TAG, "printUuidList error return");
893 OCDeleteUuidList(dvid_lst);
898 OCDeleteUuidList(dvid_lst);
902 static int saveAcl(void)
904 // create ACL to save into local SVR DB
905 OicSecAcl_t* acl = NULL;
906 OicUuid_t uuid = {.id={0}};
907 char strUuid[64] = {0};
909 printf("[1] Use a test UUID [11111111-2222-3333-4444-555555555555]\n");
910 printf("[2] Use a user input\n");
914 printf(" > Select Number, for Subject UUID of new ACE: ");
915 for(int ret=0; 1!=ret; )
917 ret = scanf("%d", &sel_num);
918 for( ; 0x20<=getchar(); ); // for removing overflow garbages
919 // '0x20<=code' is character region
923 OICStrcpy(strUuid, sizeof(strUuid), "11111111-2222-3333-4444-555555555555");
926 else if(2 == sel_num)
928 printf(" > Input the UUID : ");
929 for(int ret=0; 1!=ret; )
931 ret = scanf("%64s", strUuid);
932 for( ; 0x20<=getchar(); ); // for removing overflow garbages
933 // '0x20<=code' is character region
937 printf(" Entered Wrong Number. Please Enter Again\n");
941 printf("Selected Subject UUID : %s\n", strUuid);
942 OCStackResult rst = ConvertStrToUuid(strUuid, &uuid);
943 if(OC_STACK_OK != rst)
945 OIC_LOG_V(ERROR, TAG, "ConvertStrToUuid API error: %d", rst);
949 acl = createSimpleAcl(uuid);
952 OIC_LOG(ERROR, TAG, "createAcl error return");
956 // call |OCSaveACL| API actually
957 rst = OCSaveACL(acl);
958 if(OC_STACK_OK != rst)
960 OIC_LOG_V(ERROR, TAG, "OCSaveACL API error: %d", rst);
963 OCDeleteACLList(acl); // after here |acl| points nothing
965 // display the ACL-provisioned result
966 printf(" > Saved Selected ACL\n");
971 OCDeleteACLList(acl); // after here |acl| points nothing
975 static int getCred(void)
977 // check |own_list| for checking selected link status on PRVN DB
978 if(!g_own_list || 1>g_own_cnt)
980 printf(" > Owned Device List, to Check Linked Status on PRVN DB, is Empty\n");
981 printf(" > Please Register Unowned Devices first, with [20] Menu\n");
982 return 0; // normal case
985 // select device for checking selected link status on PRVN DB
989 printf(" > Enter Device Number, for Checking Linked Status on PRVN DB: ");
990 for(int ret=0; 1!=ret; )
992 ret = scanf("%d", &dev_num);
993 for( ; 0x20<=getchar(); ); // for removing overflow garbages
994 // '0x20<=code' is character region
996 if(0<dev_num && g_own_cnt>=dev_num)
1000 printf(" Entered Wrong Number. Please Enter Again\n");
1003 // call |getDevInst| API actually
1004 // calling this API with callback actually acts like blocking
1005 // for error checking, the return value saved and printed
1007 OCProvisionDev_t* dev = getDevInst((const OCProvisionDev_t*) g_own_list, dev_num);
1010 OIC_LOG(ERROR, TAG, "getDevInst: device instance empty");
1013 OCStackResult rst = OCGetCredResource((void*) g_ctx, dev, getCredCB);
1014 if(OC_STACK_OK != rst)
1016 OIC_LOG_V(ERROR, TAG, "OCGetCred API error: %d", rst);
1019 if(waitCallbackRet()) // input |g_doneCB| flag implicitly
1021 OIC_LOG(ERROR, TAG, "OCGetCredResource callback error");
1025 // display the result of get credential
1026 printf(" > Get Cred SUCCEEDED\n");
1034 static int getAcl(void)
1036 // check |own_list| for checking selected link status on PRVN DB
1037 if(!g_own_list || 1>g_own_cnt)
1039 printf(" > Owned Device List, to Check Linked Status on PRVN DB, is Empty\n");
1040 printf(" > Please Register Unowned Devices first, with [20] Menu\n");
1041 return 0; // normal case
1044 // select device for checking selected link status on PRVN DB
1048 printf(" > Enter Device Number, for Checking Linked Status on PRVN DB: ");
1049 for(int ret=0; 1!=ret; )
1051 ret = scanf("%d", &dev_num);
1052 for( ; 0x20<=getchar(); ); // for removing overflow garbages
1053 // '0x20<=code' is character region
1055 if(0<dev_num && g_own_cnt>=dev_num)
1059 printf(" Entered Wrong Number. Please Enter Again\n");
1062 // call |getDevInst| API actually
1063 // calling this API with callback actually acts like blocking
1064 // for error checking, the return value saved and printed
1066 OCProvisionDev_t* dev = getDevInst((const OCProvisionDev_t*) g_own_list, dev_num);
1069 OIC_LOG(ERROR, TAG, "getDevInst: device instance empty");
1072 OCStackResult rst = OCGetACLResource((void*) g_ctx, dev, getAclCB);
1073 if(OC_STACK_OK != rst)
1075 OIC_LOG_V(ERROR, TAG, "OCGetACLResource API error: %d", rst);
1079 if(waitCallbackRet()) // input |g_doneCB| flag implicitly
1081 OIC_LOG(ERROR, TAG, "OCGetACLResource callback error");
1085 // display the result of get credential
1086 printf(" > Get ACL SUCCEEDED\n");
1094 static int unlinkPairwise(void)
1096 // check |own_list| for unlinking pairwise devices
1097 if(!g_own_list || 2>g_own_cnt)
1099 printf(" > Owned Device List, to Unlink the Pairwise, is Empty\n");
1100 printf(" > Please Register Unowned Devices first, with [20] Menu\n");
1101 return 0; // normal case
1104 // select two devices for unlinking pairwise devices
1105 int dev_num[2] = {0};
1106 if(selectTwoDiffNum(&(dev_num[0]), &(dev_num[1]), g_own_cnt, "for Unlinking Devices"))
1108 OIC_LOG(ERROR, TAG, "selectTwoDiffNum error return");
1112 // call |OCUnlinkDevices| API actually
1113 // calling this API with callback actually acts like blocking
1114 // for error checking, the return value saved and printed
1116 printf(" Unlinking Selected Pairwise Devices..\n");
1118 OCUnlinkDevices((void*) g_ctx,
1119 getDevInst((const OCProvisionDev_t*) g_own_list, dev_num[0]),
1120 getDevInst((const OCProvisionDev_t*) g_own_list, dev_num[1]),
1122 if(OC_STACK_OK != rst)
1124 OIC_LOG_V(ERROR, TAG, "OCUnlinkDevices API error: %d", rst);
1127 if(waitCallbackRet()) // input |g_doneCB| flag implicitly
1129 OIC_LOG(ERROR, TAG, "OCProvisionCredentials callback error");
1133 // display the pairwise-unlinked result
1134 printf(" > Unlinked Selected Pairwise Devices\n");
1135 printf(" > Please Check Device's Status for the Unlinked Result, with [33] Menu\n");
1140 static int removeDevice(void)
1142 // check |own_list| for removing device
1143 if(!g_own_list || 1>g_own_cnt)
1145 printf(" > Owned Device List, to Remove Device, is Empty\n");
1146 printf(" > Please Register Unowned Devices first, with [20] Menu\n");
1147 return 0; // normal case
1150 // select device for removing it
1154 printf(" > Enter Device Number, for Removing Device: ");
1155 for(int ret=0; 1!=ret; )
1157 ret = scanf("%d", &dev_num);
1158 for( ; 0x20<=getchar(); ); // for removing overflow garbages
1159 // '0x20<=code' is character region
1161 if(0<dev_num && g_own_cnt>=dev_num)
1165 printf(" Entered Wrong Number. Please Enter Again\n");
1168 // call |OCRemoveDevice| API actually
1169 // calling this API with callback actually acts like blocking
1170 // for error checking, the return value saved and printed
1172 printf(" Removing Selected Owned Device..\n");
1174 OCRemoveDevice((void*) g_ctx, DISCOVERY_TIMEOUT,
1175 getDevInst((const OCProvisionDev_t*) g_own_list, dev_num), removeDeviceCB);
1176 if(OC_STACK_OK != rst)
1178 OIC_LOG_V(ERROR, TAG, "OCRemoveDevice API error: %d", rst);
1181 if(waitCallbackRet()) // input |g_doneCB| flag implicitly
1183 OIC_LOG(ERROR, TAG, "OCProvisionCredentials callback error");
1187 // display the removed result
1188 printf(" > Removed Selected Owned Device\n");
1189 printf(" > Please Discover Owned Devices for the Registered Result, with [10|12] Menu\n");
1194 static int removeDeviceWithUuid(void)
1196 char strUuid[64] = {0};
1198 printf("Input the UUID : ");
1199 for(int ret=0; 1!=ret; )
1201 ret = scanf("%63s", strUuid);
1202 for( ; 0x20<=getchar(); ); // for removing overflow garbages
1203 // '0x20<=code' is character region
1205 OCStackResult rst = ConvertStrToUuid(strUuid, &revUuid);
1206 if(OC_STACK_OK != rst)
1208 OIC_LOG_V(ERROR, TAG, "ConvertStrToUuid API error: %d", rst);
1213 rst = OCRemoveDeviceWithUuid("RemoveDeviceWithUUID", DISCOVERY_TIMEOUT, &revUuid, removeDeviceCB);
1214 if(OC_STACK_OK != rst)
1216 OIC_LOG_V(ERROR, TAG, "OCRemoveDeviceWithUuid API error: %d", rst);
1220 if(waitCallbackRet()) // input |g_doneCB| flag implicitly
1222 OIC_LOG(ERROR, TAG, "OCRemoveDeviceWithUuid callback error");
1226 // display the removed result
1227 printf(" > Removed %s Device\n", strUuid);
1228 printf(" > Please Discover Owned Devices for the Registered Result, with [10|12] Menu\n");
1233 OCStackResult displayNumCB(void * ctx, uint8_t mutualVerifNum[MUTUAL_VERIF_NUM_LEN])
1235 OIC_LOG(INFO, TAG, "IN displayMutualVerifNumCB");
1237 if (NULL != mutualVerifNum)
1239 OIC_LOG(INFO, TAG, "############ mutualVerifNum ############");
1240 OIC_LOG_BUFFER(INFO, TAG, mutualVerifNum, MUTUAL_VERIF_NUM_LEN);
1241 OIC_LOG(INFO, TAG, "############ mutualVerifNum ############");
1242 OIC_LOG(INFO, TAG, "OUT displayMutualVerifNumCB");
1246 OIC_LOG(INFO, TAG, "############ Confirm on the Server side ############");
1251 OCStackResult confirmNumCB(void * ctx)
1258 printf(" > Press 1 if the mutual verification numbers are the same\n");
1259 printf(" > Press 0 if the mutual verification numbers are not the same\n");
1261 for (int ret=0; 1!=ret; )
1263 ret = scanf("%d", &userConfirm);
1264 for (; 0x20<=getchar(); ); // for removing overflow garbage
1265 // '0x20<=code' is character region
1267 if (1 == userConfirm)
1271 else if (0 == userConfirm)
1273 return OC_STACK_USER_DENIED_REQ;
1275 printf(" Entered Wrong Number. Please Enter Again\n");
1280 OCStackResult notifyInputStateCB(void * ctx)
1284 OIC_LOG(DEBUG, TAG, "IN notifyInputStateCB");
1285 OIC_LOG(DEBUG, TAG, "User input Callback in progress");
1286 OIC_LOG(DEBUG, TAG, "OUT notifyInputStateCB");
1291 #ifdef MULTIPLE_OWNER
1292 static int changeMultipleOwnershipTrnasferMode(void)
1294 // check |own_list| for removing device
1295 if(!g_own_list || 1>g_own_cnt)
1297 printf(" > Owned Device List is Empty\n");
1298 printf(" > Please Discover the Owned Devices, with [12] Menu\n");
1299 return 0; // normal case
1302 // select device for removing it
1306 printf(" > Enter Device Number, for MOT Device: ");
1307 for(int ret=0; 1!=ret; )
1309 ret = scanf("%d", &dev_num);
1310 for( ; 0x20<=getchar(); ); // for removing overflow garbages
1311 // '0x20<=code' is character region
1313 if(0<dev_num && g_own_cnt>=dev_num)
1317 printf(" Entered Wrong Number. Please Enter Again\n");
1323 printf(" 0. Disable Multuple Ownership Transfer\n");
1324 printf(" 1. Enable Multuple Ownership Transfer\n");
1325 printf(" 2. (Not Supported yet) Timely Enable Multuple Ownership Transfer\n");
1326 printf(" > Enter Mode of Multuple Ownership Transfer : ");
1327 for(int ret=0; 1!=ret; )
1329 ret = scanf("%d", &mom);
1330 for( ; 0x20<=getchar(); ); // for removing overflow garbages
1331 // '0x20<=code' is character region
1333 if(0 <= dev_num && OIC_NUMBER_OF_MOM_TYPE > dev_num)
1337 printf(" Entered Wrong Number. Please Enter Again\n");
1340 OCProvisionDev_t* motDev = getDevInst(g_own_list, dev_num);
1341 if(OC_STACK_OK == OCChangeMOTMode(NULL, motDev, (OicSecMomType_t)dev_num, updateDoxmForMOTCB))
1347 OIC_LOG(ERROR, TAG, "OCChangeMOTMode API error");
1351 if(waitCallbackRet()) // input |g_doneCB| flag implicitly
1353 OIC_LOG(ERROR, TAG, "waitCallbackRet callback error");
1360 static int selectMultipleOwnershipTrnasferMethod(void)
1362 // check |own_list| for removing device
1363 if(!g_mot_enable_list || 1>g_mot_enable_cnt)
1365 printf(" > Multiple Ownership Transfer Enabled Device List is Empty\n");
1366 printf(" > Please Discover the Multiple Ownership Transfer Enabled Devices, with [13] Menu\n");
1367 return 0; // normal case
1370 // select device for removing it
1374 printf(" > Enter Device Number, for MOT Device: ");
1375 for(int ret=0; 1!=ret; )
1377 ret = scanf("%d", &dev_num);
1378 for( ; 0x20<=getchar(); ); // for removing overflow garbages
1379 // '0x20<=code' is character region
1381 if(0<dev_num && g_mot_enable_cnt>=dev_num)
1385 printf(" Entered Wrong Number. Please Enter Again\n");
1388 const int preconfOxm = 4;
1392 printf(" %d. (Not Supported)\n", OIC_JUST_WORKS);
1393 printf(" %d. Random PIN OxM\n", OIC_RANDOM_DEVICE_PIN);
1394 printf(" %d. (Not Supported)\n", OIC_MANUFACTURER_CERTIFICATE);
1395 printf(" %d. (Not Supported)\n", OIC_DECENTRALIZED_PUBLIC_KEY);
1396 printf(" %d. Pre-Configured PIN OxM\n", OIC_PRECONFIG_PIN);
1397 printf(" > Enter Number of OxM for Multiple Ownership Transfer : ");
1398 for(int ret=0; 1!=ret; )
1400 ret = scanf("%d", &oxm);
1401 for( ; 0x20<=getchar(); ); // for removing overflow garbages
1402 // '0x20<=code' is character region
1404 if(OIC_PRECONFIG_PIN == oxm || OIC_RANDOM_DEVICE_PIN == oxm)
1408 printf(" Entered Wrong Number. Please Enter Again\n");
1411 OCProvisionDev_t* motDev = getDevInst(g_mot_enable_list, dev_num);
1412 if(OC_STACK_OK == OCSelectMOTMethod(NULL, motDev, (OicSecOxm_t)oxm, updateDoxmForMOTCB))
1418 OIC_LOG(ERROR, TAG, "OCSelectMOTMethod API error");
1422 if(waitCallbackRet()) // input |g_doneCB| flag implicitly
1424 OIC_LOG(ERROR, TAG, "waitCallbackRet callback error");
1431 static int provisionPreconfigPIN()
1433 // check |own_list| for removing device
1434 if(!g_mot_enable_list || 1>g_mot_enable_cnt)
1436 printf(" > Multiple Ownership Transfer Enabled Device List is Empty\n");
1437 printf(" > Please Discover the Multiple Ownership Transfer Enabled Devices, with [13] Menu\n");
1438 return 0; // normal case
1441 // select device for removing it
1445 printf(" > Enter Device Number, for MOT Device: ");
1446 for(int ret=0; 1!=ret; )
1448 ret = scanf("%d", &dev_num);
1449 for( ; 0x20<=getchar(); ); // for removing overflow garbages
1450 // '0x20<=code' is character region
1452 if(0<dev_num && g_mot_enable_cnt>=dev_num)
1456 printf(" Entered Wrong Number. Please Enter Again\n");
1459 char preconfigPin[9] = {0};
1460 printf(" > Input the PreconfigPin (e.g. 12341234) : ");
1461 for(int ret=0; 1!=ret; )
1463 ret = scanf("%8s", preconfigPin);
1464 for( ; 0x20<=getchar(); ); // for removing overflow garbages
1465 // '0x20<=code' is character region
1468 OCProvisionDev_t* motDev = getDevInst(g_mot_enable_list, dev_num);
1469 if(OC_STACK_OK == OCProvisionPreconfigPin(NULL, motDev, preconfigPin, strlen(preconfigPin), provisionCredCB))
1475 OIC_LOG(ERROR, TAG, "OCProvisionPreconfigPin API error");
1479 if(waitCallbackRet()) // input |g_doneCB| flag implicitly
1481 OIC_LOG(ERROR, TAG, "waitCallbackRet callback error");
1488 static int removeSubOwner(void)
1490 // check |g_mot_enable_list| for removing sub-owner
1491 if (!g_mot_enable_list || 1 > g_mot_enable_cnt)
1493 printf(" > Multiple Ownership Transfer Enabled Device List is Empty\n");
1494 printf(" > Please Discover the Multiple Ownership Transfer Enabled Devices, with [13] Menu\n");
1495 return 0; // normal case
1498 // select resource server for removing sub-owner
1502 printf(" > Enter Device Number to remove sub-owner: ");
1503 for (int ret = 0; 1 != ret; )
1505 ret = scanf("%d", &dev_num);
1506 for( ; 0x20 <= getchar(); ); // for removing overflow garbages
1507 // '0x20<=code' is character region
1509 if (0 < dev_num && g_mot_enable_cnt >= dev_num)
1513 printf(" Entered Wrong Number. Please Enter Again\n");
1516 OCProvisionDev_t* motDev = getDevInst(g_mot_enable_list, dev_num);
1517 if (motDev && motDev->doxm && motDev->doxm->subOwners)
1519 OicSecSubOwner_t* subOwner = motDev->doxm->subOwners;
1523 printf(" [%zu] ", ++so_cnt);
1524 printUuid(&subOwner->uuid);
1526 subOwner = subOwner->next;
1532 printf(" > Enter SubOwner Number to be removed : ");
1533 for (int ret = 0; 1 != ret; )
1535 ret = scanf("%d", &so_num);
1536 for( ; 0x20<=getchar(); ); // for removing overflow garbages
1537 // '0x20<=code' is character region
1539 if (0 < so_num && so_cnt >= so_num)
1542 subOwner = motDev->doxm->subOwners;
1545 if(so_num == ++target_num)
1547 if (OC_STACK_OK != OCRemoveSubOwner(NULL, motDev, &subOwner->uuid, deleteDoxmForMOTCB))
1554 if(waitCallbackRet()) // input |g_doneCB| flag implicitly
1556 OIC_LOG(ERROR, TAG, "waitCallbackRet callback error");
1561 subOwner = subOwner->next;
1565 printf(" Entered Wrong Number. Please Enter Again\n");
1570 printf(" SubOwner list is empty.\n");
1576 static int removeAllSubOwner(void)
1578 // check |g_mot_enable_list| for removing sub-owner
1579 if (!g_mot_enable_list || 1 > g_mot_enable_cnt)
1581 printf(" > Multiple Ownership Transfer Enabled Device List is Empty\n");
1582 printf(" > Please Discover the Multiple Ownership Transfer Enabled Devices, with [13] Menu\n");
1583 return 0; // normal case
1586 // select resource server for removing sub-owner
1590 printf(" > Enter Device Number to remove sub-owner: ");
1591 for (int ret = 0; 1 != ret; )
1593 ret = scanf("%d", &dev_num);
1594 for( ; 0x20 <= getchar(); ); // for removing overflow garbages
1595 // '0x20<=code' is character region
1597 if (0 < dev_num && g_mot_enable_cnt >= dev_num)
1601 printf(" Entered Wrong Number. Please Enter Again\n");
1604 OCProvisionDev_t* motDev = getDevInst(g_mot_enable_list, dev_num);
1605 if (motDev && motDev->doxm && motDev->doxm->subOwners)
1607 if (OC_STACK_OK != OCRemoveAllSubOwner(NULL, motDev, deleteDoxmForMOTCB))
1614 if(waitCallbackRet()) // input |g_doneCB| flag implicitly
1616 OIC_LOG(ERROR, TAG, "waitCallbackRet callback error");
1623 printf(" SubOwner list is empty.\n");
1629 #endif //MULTIPLE_OWNER
1631 static int resetDevice(void)
1633 // check |own_list| for removing device
1634 if (!g_own_list || 1 > g_own_cnt)
1636 printf(" > Owned Device List, to Reset Device, is Empty\n");
1637 printf(" > Please Register Unowned Devices first, with [20] Menu\n");
1641 // select device for removing it
1645 printf(" > Enter Device Number, for Resetting Device: ");
1646 for (int ret = 0; 1 != ret; )
1648 ret = scanf("%d", &dev_num);
1649 for ( ; 0x20 <= getchar() ; ); // for removing overflow garbages
1650 // '0x20 <= code' is character region
1652 if (0 < dev_num && g_own_cnt >= dev_num)
1656 printf(" Entered Wrong Number. Please Enter Again\n");
1660 printf(" Resetting Selected Owned Device..\n");
1662 OCStackResult rst = OCResetDevice((void *) g_ctx, DISCOVERY_TIMEOUT,
1663 getDevInst((const OCProvisionDev_t *) g_own_list, dev_num), syncDeviceCB);
1664 if (OC_STACK_OK != rst)
1666 OIC_LOG_V(ERROR, TAG, "OCResetDevice API error: %d", rst);
1670 if (waitCallbackRet()) // input |g_doneCB| flag implicitly
1672 OIC_LOG(ERROR, TAG, "OCProvisionCredentials callback error");
1676 // display the removed result
1677 printf(" > Reset Selected Owned Device SUCCEEDED\n");
1678 printf(" > Please Discover Owned Devices for the Registered Result, with [10|12] Menu\n");
1683 static int resetSVRDB(void)
1685 printf(" Resetting SVR DB..\n");
1686 OCStackResult rst = OCResetSVRDB();
1687 if (OC_STACK_OK != rst)
1689 OIC_LOG_V(ERROR, TAG, "OCResetSVRDB API error: %d", rst);
1695 static OicSecAcl_t* createAcl(const int dev_num)
1697 if(0>=dev_num || g_own_cnt<dev_num)
1699 OIC_LOG(ERROR, TAG, "createAcl invalid parameters");
1700 return NULL; // not need to 'goto' |ERROR| before allocating |acl|
1703 // allocate memory for |acl| struct
1704 printf(" **** Create ACL for the Selected Device[%d]\n", dev_num);
1705 OicSecAcl_t* acl = (OicSecAcl_t*) OICCalloc(1, sizeof(OicSecAcl_t));
1708 OIC_LOG(ERROR, TAG, "createAcl: OICCalloc error return");
1709 return NULL; // not need to 'goto' |ERROR| before allocating |acl|
1711 OicSecAce_t* ace = (OicSecAce_t*) OICCalloc(1, sizeof(OicSecAce_t));
1714 OIC_LOG(ERROR, TAG, "createAcl: OICCalloc error return");
1715 return NULL; // not need to 'goto' |ERROR| before allocating |acl|
1717 LL_APPEND(acl->aces, ace);
1719 // enter |subject| device number
1723 printf(" > [A] Enter Subject Device Number: ");
1724 for(int ret=0; 1!=ret; )
1726 ret = scanf("%d", &num);
1727 for( ; 0x20<=getchar(); ); // for removing overflow garbages
1728 // '0x20<=code' is character region
1730 if(0<num && g_own_cnt>=num && dev_num!=num)
1734 printf(" Entered Wrong Number. Please Enter Again\n");
1737 OCProvisionDev_t* dev = getDevInst((const OCProvisionDev_t*)g_own_list, num);
1738 if(!dev || !dev->doxm)
1740 OIC_LOG(ERROR, TAG, "createAcl: device instance empty");
1743 memcpy(&ace->subjectuuid, &dev->doxm->deviceID, UUID_LENGTH);
1745 // enter number of |resources| in 'accessed' device
1748 printf(" > [B] Enter Number of Accessed Resources (under 16): ");
1749 // '16' is |ACL_RESRC_MAX_NUM|
1750 for(int ret=0; 1!=ret; )
1752 ret = scanf("%d", &num);
1753 for( ; 0x20<=getchar(); ); // for removing overflow garbages
1754 // '0x20<=code' is character region
1756 if(0<num && ACL_RESRC_MAX_NUM>=num)
1760 printf(" Entered Wrong Number. Please Enter under 16 Again\n");
1761 // '16' is |ACL_RESRC_MAX_NUM|
1764 // enter actually each 'accessed' |resources| name
1765 printf(" Enter Each Accessed Resource Name (each under 128 char)\n");
1766 // '128' is ACL_RESRC_MAX_LEN
1768 char rsrc_in[ACL_RESRC_MAX_LEN+1] = {0}; // '1' for null termination
1769 for(int i = 0; num > i; ++i)
1771 OicSecRsrc_t* rsrc = (OicSecRsrc_t*)OICCalloc(1, sizeof(OicSecRsrc_t));
1774 OIC_LOG(ERROR, TAG, "createAcl: OICCalloc error return");
1778 printf(" Enter Accessed Resource[%d] Name: (e.g. /a/led)", i+1);
1779 for(int ret=0; 1!=ret; )
1781 ret = scanf("%128s", rsrc_in); // '128' is ACL_RESRC_MAX_LEN
1782 for( ; 0x20<=getchar(); ); // for removing overflow garbages
1783 // '0x20<=code' is character region
1785 size_t len = strlen(rsrc_in)+1; // '1' for null termination
1786 rsrc->href = (char*) OICCalloc(len, sizeof(char));
1789 OIC_LOG(ERROR, TAG, "createAcl: OICCalloc error return");
1792 OICStrcpy(rsrc->href, len, rsrc_in);
1797 printf(" Enter Number of resource type for [%s] : ", rsrc->href);
1798 for(int ret=0; 1!=ret; )
1800 ret = scanf("%zu", &arrLen);
1801 for( ; 0x20<=getchar(); ); // for removing overflow garbages
1802 // '0x20<=code' is character region
1804 if(ACL_RESRC_ARRAY_SIZE >= arrLen)
1808 printf(" Entered Wrong Number. Please Enter under %d Again\n", ACL_RESRC_ARRAY_SIZE);
1811 rsrc->typeLen = arrLen;
1812 rsrc->types = (char**)OICCalloc(arrLen, sizeof(char*));
1815 OIC_LOG(ERROR, TAG, "createAcl: OICCalloc error return");
1819 for(size_t i = 0; i < arrLen; i++)
1821 printf(" Enter ResourceType[%zu] Name (e.g. core.led): ", i+1);
1822 for(int ret=0; 1!=ret; )
1824 ret = scanf("%128s", rsrc_in); // '128' is ACL_RESRC_MAX_LEN
1825 for( ; 0x20<=getchar(); ); // for removing overflow garbages
1826 // '0x20<=code' is character region
1828 rsrc->types[i] = OICStrdup(rsrc_in);
1831 OIC_LOG(ERROR, TAG, "createAcl: OICStrdup error return");
1838 printf(" Enter Number of interface for [%s]: ", rsrc->href);
1839 for(int ret=0; 1!=ret; )
1841 ret = scanf("%zu", &arrLen);
1842 for( ; 0x20<=getchar(); ); // for removing overflow garbages
1843 // '0x20<=code' is character region
1845 if(ACL_RESRC_ARRAY_SIZE >= arrLen)
1849 printf(" Entered Wrong Number. Please Enter under %d Again\n", ACL_RESRC_ARRAY_SIZE);
1852 rsrc->interfaceLen = arrLen;
1853 rsrc->interfaces = (char**)OICCalloc(arrLen, sizeof(char*));
1854 if(!rsrc->interfaces)
1856 OIC_LOG(ERROR, TAG, "createAcl: OICCalloc error return");
1860 for(size_t i = 0; i < arrLen; i++)
1862 printf(" Enter Interface[%zu] Name (e.g. oic.if.baseline): ", i+1);
1863 for(int ret=0; 1!=ret; )
1865 ret = scanf("%128s", rsrc_in); // '128' is ACL_RESRC_MAX_LEN
1866 for( ; 0x20<=getchar(); ); // for removing overflow garbages
1867 // '0x20<=code' is character region
1869 rsrc->interfaces[i] = OICStrdup(rsrc_in);
1870 if(!rsrc->interfaces[i])
1872 OIC_LOG(ERROR, TAG, "createAcl: OICStrdup error return");
1877 LL_APPEND(ace->resources, rsrc);
1880 // enter |permission| for this access
1881 printf(" > [C] Enter Permission for This Access\n");
1882 uint16_t pmsn = PERMISSION_FULL_CONTROL; // default full permission
1883 uint16_t pmsn_msk = PERMISSION_CREATE; // default permission mask
1884 for(int i=0; ACL_PEMISN_CNT>i; ++i)
1889 printf(" Enter %s Permission (y/n): ", ACL_PEMISN[i]);
1890 for(int ret=0; 1!=ret; )
1892 ret = scanf("%c", &ans);
1893 for( ; 0x20<=getchar(); ); // for removing overflow garbages
1894 // '0x20<=code' is character region
1896 if('y'==ans || 'Y'==ans || 'n'==ans|| 'N'==ans)
1898 ans &= ~0x20; // for masking lower case, 'y/n'
1901 printf(" Entered Wrong Answer. Please Enter 'y/n' Again\n");
1903 if('N' == ans) // masked lower case, 'n'
1909 ace->permission = pmsn;
1914 OCDeleteACLList(acl); // after here |acl| points nothing
1918 static OicSecAcl_t* createSimpleAcl(const OicUuid_t uuid)
1920 OIC_LOG(DEBUG, TAG, "createSimpleAcl IN");
1922 // allocate memory for |acl| struct
1923 OicSecAcl_t* acl = (OicSecAcl_t*) OICCalloc(1, sizeof(OicSecAcl_t));
1926 OIC_LOG(DEBUG, TAG, "OICCalloc error return");
1927 return NULL; // not need to 'goto' |ERROR| before allocating |acl|
1929 OicSecAce_t* ace = (OicSecAce_t*) OICCalloc(1, sizeof(OicSecAce_t));
1932 OIC_LOG(DEBUG, TAG, "OICCalloc error return");
1933 return NULL; // not need to 'goto' |ERROR| before allocating |acl|
1935 LL_APPEND(acl->aces, ace);
1937 memcpy(&ace->subjectuuid, &uuid, UUID_LENGTH);
1939 OicSecRsrc_t* rsrc = (OicSecRsrc_t*)OICCalloc(1, sizeof(OicSecRsrc_t));
1942 OIC_LOG(DEBUG, TAG, "OICCalloc error return");
1943 OCDeleteACLList(acl);
1948 size_t len = strlen(href)+1; // '1' for null termination
1949 rsrc->href = (char*) OICCalloc(len, sizeof(char));
1952 OIC_LOG(DEBUG, TAG, "OICCalloc error return");
1953 OCDeleteACLList(acl);
1956 OICStrcpy(rsrc->href, len, href);
1959 rsrc->typeLen = arrLen;
1960 rsrc->types = (char**)OICCalloc(arrLen, sizeof(char*));
1963 OIC_LOG(DEBUG, TAG, "OICCalloc error return");
1964 OCDeleteACLList(acl);
1967 rsrc->types[0] = OICStrdup(""); // ignore
1969 rsrc->interfaceLen = 1;
1970 rsrc->interfaces = (char**)OICCalloc(arrLen, sizeof(char*));
1971 if(!rsrc->interfaces)
1973 OIC_LOG(DEBUG, TAG, "OICCalloc error return");
1974 OCDeleteACLList(acl);
1977 rsrc->interfaces[0] = OICStrdup("oic.if.baseline"); // ignore
1979 LL_APPEND(ace->resources, rsrc);
1981 ace->permission = 31; // R/W/U/D
1983 OIC_LOG(DEBUG, TAG, "createSimpleAcl OUT");
1988 static OicSecPdAcl_t* createPdAcl(const int dev_num)
1990 if(0>=dev_num || g_own_cnt<dev_num)
1992 OIC_LOG(ERROR, TAG, "createAcl invalid parameters");
1993 return NULL; // not need to 'goto' |ERROR| before allocating |acl|
1996 // allocate memory for |pdacl| struct
1997 printf(" **** Create PDACL for the Selected Device[%d]\n", dev_num);
1998 OicSecPdAcl_t* pdAcl = (OicSecPdAcl_t*) OICCalloc(1, sizeof(OicSecPdAcl_t));
2001 OIC_LOG(ERROR, TAG, "createAcl: OICCalloc error return");
2002 return NULL; // not need to 'goto' |ERROR| before allocating |acl|
2006 // number of resources
2007 char rsrc_in[][ACL_RESRC_MAX_LEN+1] = {"*", "/rsrc/*"};
2008 pdAcl->resourcesLen = 1;
2011 int num = pdAcl->resourcesLen;
2012 pdAcl->resources = (char**) OICCalloc(num, sizeof(char*));
2013 if(!pdAcl->resources)
2015 OIC_LOG(ERROR, TAG, "createPdAcl: OICCalloc error return");
2018 for(int i=0; num>i; ++i)
2020 size_t len = strlen(rsrc_in[i])+1; // '1' for null termination
2021 char* rsrc = (char*) OICCalloc(len, sizeof(char));
2024 OIC_LOG(ERROR, TAG, "createPdAcl: OICCalloc error return");
2027 OICStrcpy(rsrc, len, rsrc_in[i]);
2028 pdAcl->resources[i] = rsrc; // after here, |rsrc| points nothing
2032 pdAcl->permission = PERMISSION_FULL_CONTROL;
2037 OCDeletePdAclList(pdAcl);
2041 static OCProvisionDev_t* getDevInst(const OCProvisionDev_t* dev_lst, const int dev_num)
2043 if(!dev_lst || 0>=dev_num)
2045 printf(" Device List is Empty..\n");
2049 OCProvisionDev_t* lst = (OCProvisionDev_t*) dev_lst;
2059 return NULL; // in here |lst| is always |NULL|
2062 static int printDevList(const OCProvisionDev_t* dev_lst)
2066 printf(" Device List is Empty..\n\n");
2070 OCProvisionDev_t* lst = (OCProvisionDev_t*) dev_lst;
2074 printf(" [%d] ", ++lst_cnt);
2075 printUuid((const OicUuid_t*) &lst->doxm->deviceID);
2084 static size_t printUuidList(const OCUuidList_t* uid_lst)
2088 printf(" Device List is Empty..\n\n");
2092 OCUuidList_t* lst = (OCUuidList_t*) uid_lst;
2096 printf(" [%zu] ", ++lst_cnt);
2097 printUuid((const OicUuid_t*) &lst->dev);
2106 static int printResultList(const OCProvisionResult_t* rslt_lst, const int rslt_cnt)
2108 if(!rslt_lst || 0>=rslt_cnt)
2110 printf(" Device List is Empty..\n\n");
2115 for( ; rslt_cnt>lst_cnt; ++lst_cnt)
2117 printf(" [%d] ", lst_cnt+1);
2118 printUuid((const OicUuid_t*) &rslt_lst[lst_cnt].deviceId);
2119 printf(" - result: %d\n", rslt_lst[lst_cnt].res);
2126 static void printUuid(const OicUuid_t* uid)
2128 for(int i=0; i<UUID_LENGTH; )
2130 printf("%02X", (*uid).id[i++]);
2131 if(i==4 || i==6 || i==8 || i==10) // canonical format for UUID has '8-4-4-4-12'
2138 static FILE* fopen_prvnMng(const char* path, const char* mode)
2140 (void)path; // unused |path| parameter
2142 // input |g_svr_db_fname| internally by force, not using |path| parameter
2143 // because |OCPersistentStorage::open| is called |OCPersistentStorage| internally
2144 // with its own |SVR_DB_FILE_NAME|
2145 return fopen(SVR_DB_FILE_NAME, mode);
2148 static int peerCertCallback(void *ctx, const mbedtls_x509_crt *cert, int depth)
2152 OIC_LOG_V(DEBUG, TAG, "Depth : %d", depth);
2153 OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
2154 OIC_LOG(DEBUG, TAG, "***** Serial number of certificate is below *****");
2155 OIC_LOG_BUFFER(DEBUG, TAG, cert->serial.p, cert->serial.len);
2156 OIC_LOG(DEBUG, TAG, "***** Serial number of certificate is above *****");
2157 OIC_LOG_V(DEBUG, TAG, "OUT%s", __func__);
2162 static int waitCallbackRet(void)
2164 for(int i=0; !g_doneCB && CALLBACK_TIMEOUT>i; ++i)
2167 if(OC_STACK_OK != OCProcess())
2169 OIC_LOG(ERROR, TAG, "OCStack process error");
2176 OCPDMCleanupForTimeout();
2182 static int selectTwoDiffNum(int* a, int* b, const int max, const char* str)
2184 if(!a || !b || 2>max || !str)
2191 for(int i=0; 2>i; ++i)
2193 int* num = 0==i?a:b;
2196 printf(" > Enter Device[%d] Number, %s: ", i+1, str);
2197 for(int ret=0; 1!=ret; )
2199 ret = scanf("%d", num);
2200 for( ; 0x20<=getchar(); ); // for removing overflow garbages
2201 // '0x20<=code' is character region
2203 if(0<*num && max>=*num)
2207 printf(" Entered Wrong Number. Please Enter Again\n");
2222 static void setDevProtocol(OCProvisionDev_t* lst)
2226 printf(" Device List is Empty..\n\n");
2232 if(2 == secure_protocol)
2234 lst->connType &= ~CT_ADAPTER_IP; //reset IP flag
2235 lst->connType |= CT_ADAPTER_TCP; //set TCP flag
2236 lst->endpoint.adapter = OC_ADAPTER_TCP;
2237 lst->endpoint.port = lst->tcpPort;
2238 lst->securePort = lst->tcpPort;
2244 static void selectSecureProtocol()
2246 printf(" Select protocol\n");
2247 printf(" 1 - DTLS(Default)\n");
2248 printf(" 2 - TLS\n");
2250 for(int ret=0; 1!=ret; )
2252 ret = scanf("%d",&secure_protocol);
2253 for( ; 0x20<=getchar(); ); // for removing overflow garbages
2254 // '0x20<=code' is character region
2257 if(0 >= secure_protocol || 2 < secure_protocol)
2259 secure_protocol = 1;
2262 setDevProtocol(g_own_list);
2263 setDevProtocol(g_unown_list);
2267 static void secureStorageHwEmulation()
2269 printf(" Enable Secure Storage HW Emulation\n");
2271 printf(" Enter Own Certificate File Path[~4095]: ");
2272 char cert_filepath[4096] = {0,};
2273 for(int ret=0; 1!=ret; )
2275 ret = scanf("%255s", cert_filepath);
2276 for( ; 0x20<=getchar(); ); // for removing overflow garbages
2277 // '0x20<=code' is character region
2280 printf(" Enter Private Key File Path[~4095]: ");
2281 char key_filepath[4096] = {0,};
2282 for(int ret=0; 1!=ret; )
2284 ret = scanf("%255s", key_filepath);
2285 for( ; 0x20<=getchar(); ); // for removing overflow garbages
2286 // '0x20<=code' is character region
2289 printf(" Enter Password for Key Password[~31][Press (Enter) to not set]: ");
2290 char pwd[32] = {0,};
2291 for(int i=0; i < 31; i++)
2293 pwd[i] = (char)getchar();
2306 if (0 != SSemulSetCertkeyFilepath(cert_filepath, key_filepath, pwd))
2308 printf(" Fail to set cert/key file path");
2312 if (0 != SetHwPkixCallbacks(HWGetKeyContext,
2314 HWGetOwnCertificateChain,
2317 printf(" Fail to regist HW Pkix Callbacks");
2320 printf(" Success to regist HW Pkix Callbacks");
2323 static void selectVerifMethod()
2326 printf(" Select verification method for ownership transfer\n");
2327 printf(" 0 - No verification\n");
2328 printf(" 1 - Display only\n");
2329 printf(" 2 - Confirm only\n");
2330 printf(" 3 - Both Display and Confirm\n");
2332 for(int ret=0; 1!=ret; )
2334 ret = scanf("%d",&option);
2335 for( ; 0x20<=getchar(); ); // for removing overflow garbages
2336 // '0x20<=code' is character region
2339 if(0 > option || 3 < option)
2341 printf("Invalid option!");
2343 SetVerifyOption((VerifyOptionBitmask_t) option);
2344 printf("Option %d chosen!", option);
2347 static void printMenu(void)
2349 printf("************************************************************\n");
2350 printf("****** OIC Provisioning Client with using C-level API ******\n");
2351 printf("************************************************************\n\n");
2353 printf("** [A] DISCOVER DEVICES ON NETWORK\n");
2354 printf("** 10. Discover All Un/Owned Devices on Network\n");
2355 printf("** 11. Discover Only Unowned Devices on Network\n");
2356 #ifdef MULTIPLE_OWNER
2357 printf("** 12. Discover Only Owned Devices on Network\n");
2358 printf("** 13. Discover Multiple Ownership Transfer Enabled Devices on Network\n\n");
2360 printf("** 12. Discover Only Owned Devices on Network\n\n");
2361 #endif //MULTIPLE_OWNER
2363 printf("** [B] REGISTER/OWN ALL DISCOVERED UNOWNED DEVICES\n");
2364 printf("** 20. Register/Own All Discovered Unowned Devices\n\n");
2366 printf("** [C] PROVISION/LINK PAIRWISE THINGS\n");
2367 printf("** 30. Provision/Link Pairwise Things\n");
2368 printf("** 31. Provision Credentials for Pairwise Things\n");
2369 printf("** 32. Provision the Selected Access Control List(ACL)\n");
2370 printf("** 33. Provision Direct-Pairing Configuration\n");
2371 printf("** 34. Check Linked Status of the Selected Device on PRVN DB\n");
2372 printf("** 35. Save the Selected Access Control List(ACL) into local SVR DB\n\n");
2374 printf("** [D] UNLINK PAIRWISE THINGS\n");
2375 printf("** 40. Unlink Pairwise Things\n\n");
2377 printf("** [E] REMOVE THE SELECTED DEVICE\n");
2378 printf("** 50. Remove the Selected Device\n");
2379 printf("** 51. Remove Device with UUID (UUID input is required)\n");
2380 printf("** 52. Reset the Selected Device\n");
2381 printf("** 53. Reset SVR DB\n\n");
2383 printf("** [F] GET SECURITY RESOURCE FOR DEBUGGING ONLY\n");
2384 printf("** 60. Get the Credential resources of the Selected Device\n");
2385 printf("** 61. Get the ACL resources of the Selected Device\n\n");
2387 #ifdef MULTIPLE_OWNER
2388 printf("** [G] UPDATE THE MULTIPLE OWNERSHIP TRANSFER RELATED VALUE\n");
2389 printf("** 70. Change the Multiple Ownership transfer MODE(update mom)\n");
2390 printf("** 71. Provision Preconfigured PIN\n");
2391 printf("** 72. Change the Multiple Ownership transfer METHOD(update oxmsel)\n");
2392 printf("** 73. Remove Sub-Owner from Resource Server\n");
2393 printf("** 74. Remove All Sub-Owner from Resource Server\n\n");
2394 #endif //MULTIPLE_OWNER
2397 printf("** [H] SELECT SECURE PROTOCOL DTLS/TLS AND OTHERS\n");
2398 printf("** 80. Select secure protocol(default DTLS)\n");
2399 printf("** 81. Select verification method\n");
2400 printf("** 82. Enable secure storage hw emulation\n\n");
2402 printf("** [H] SELECT VERIFICATION OPTION\n");
2403 printf("** 81. Select verification method\n\n");
2405 printf("** [I] EXIT PROVISIONING CLIENT\n");
2407 printf("** 99. Exit Provisionong Client\n\n");
2409 printf("************************************************************\n\n");
2412 #if 0 // Code for enabling path configuration for PDB and SVR DBf
2413 static void printUsage(void)
2416 printf("OIC Provisioning Client with using C-level API\n");
2417 printf("Usage: provisioningclient [option]...\n");
2419 printf(" -h print help for this provisioning client\n");
2420 printf(" -p=[prvn_db_file_path/name] input PRVN DB file path and name\n");
2421 printf(" if not exists, will load default DB file\n");
2422 printf(" (default: |oic_prvn_mng.db| on working dir)\n");
2423 printf(" (ex. -p=oic_prvn_mng.db)\n");
2424 printf(" -s=[svr_db_file_path/name] input SVR DB file path and name\n");
2425 printf(" if not exists, will load default DB file\n");
2426 printf(" (default: |oic_svr_db_client.json| on working dir)\n");
2427 printf(" (ex. -s=oic_svr_db_client.json)\n");
2433 * Sample implementation of Export key block and master secret
2435 * @param[in] p_expkey Context for the callback
2436 * @aram[in] ms Pointer to master secret (fixed length: 48 bytes)
2437 * @param[in] kb Pointer to key block, see RFC 5246 section 6.3
2438 * (variable length: 2 * maclen + 2 * keylen + 2 * ivlen).
2439 * @param[in] maclen MAC length
2440 * @param[in] keylen Key length
2441 * @param[in] ivlen IV length
2443 static void SslExportKeysCallback(const unsigned char* masterSecret,
2444 const unsigned char* keyBlock,
2445 size_t macLen, size_t keyLen, size_t ivLen)
2447 OIC_LOG_V(INFO, TAG, "In %s ", __func__);
2449 OIC_LOG(INFO, TAG, "[MASTER SECRET] : ");
2450 OIC_LOG_BUFFER(INFO, TAG, masterSecret, 48);
2452 OIC_LOG(INFO, TAG, "[KEY BLOCK] : ");
2453 OIC_LOG_BUFFER(INFO, TAG, keyBlock, (2 * macLen) + (2 * keyLen) + (2 * ivLen));
2455 OIC_LOG_V(INFO, TAG, "Mac Length = %zu, Key Length = %zu, IV Length = %zu",
2456 macLen, keyLen, ivLen);
2458 OIC_LOG_V(INFO, TAG, "Out %s ", __func__);
2461 // main function for provisioning client using C-level provisioning API
2464 // initialize provisioning client
2465 if(initProvisionClient())
2467 OIC_LOG(ERROR, TAG, "ProvisionClient init error");
2472 CASetSslExportKeysCallback(SslExportKeysCallback, CA_SSL_EKCB_DTLS, CA_SSL_EKCB_CLIENT))
2474 OIC_LOG(ERROR, TAG, "Failed to register the (D)TLS export Key Callback!");
2478 // Client can choose a allowed/not-allowed OxM method.
2479 if(OC_STACK_OK != OCSetOxmAllowStatus(OIC_DECENTRALIZED_PUBLIC_KEY, false))
2481 OIC_LOG(WARNING, TAG, "Failed to disable OIC_DECENTRALIZED_PUBLIC_KEY OxM");
2484 // set callbacks for verification options
2485 SetDisplayNumCB(NULL, displayNumCB);
2486 SetUserConfirmCB(NULL, confirmNumCB);
2487 SetInputStateCB(NULL, notifyInputStateCB);
2489 // set callback for checking peer certificate information
2490 OCSetPeerCertCallback(NULL, peerCertCallback);
2492 #ifdef MULTIPLE_OWNER
2493 SetPreconfigPin("12341234", 8);
2494 #endif //MULTIPLE_OWNER
2496 // main loop for provisioning manager
2502 printf(">> Enter Menu Number: ");
2503 for(int ret=0; 1!=ret; )
2505 ret = scanf("%d", &mn_num);
2506 for( ; 0x20<=getchar(); ); // for removing overflow garbages
2507 // '0x20<=code' is character region
2512 case _10_DISCOV_ALL_DEVS_:
2513 if(discoverAllDevices())
2515 OIC_LOG(ERROR, TAG, "_10_DISCOV_ALL_DEVS_: error");
2518 case _11_DISCOV_UNOWN_DEVS_:
2519 if(discoverUnownedDevices())
2521 OIC_LOG(ERROR, TAG, "_11_DISCOV_UNOWN_DEVS_: error");
2524 case _12_DISCOV_OWN_DEVS_:
2525 if(discoverOwnedDevices())
2527 OIC_LOG(ERROR, TAG, "_12_DISCOV_OWN_DEVS_: error");
2530 #ifdef MULTIPLE_OWNER
2531 case _13_MOT_DISCOV_DEV_:
2532 if(discoverMOTEnabledDevices())
2534 OIC_LOG(ERROR, TAG, "_13_MOT_DISCOV_DEV_: error");
2537 #endif //MULTIPLE_OWNER
2538 case _20_REGIST_DEVS_:
2539 if(registerDevices())
2541 OIC_LOG(ERROR, TAG, "_20_REGIST_DEVS_: error");
2544 case _30_PROVIS_PAIR_DEVS_:
2545 if(provisionPairwise())
2547 OIC_LOG(ERROR, TAG, "_30_PROVIS_PAIR_DEVS_: error");
2550 case _31_PROVIS_CRED_:
2553 OIC_LOG(ERROR, TAG, "_31_PROVIS_CRED_: error");
2556 case _32_PROVIS_ACL_:
2559 OIC_LOG(ERROR, TAG, "_32_PROVIS_ACL_: error");
2562 case _33_PROVIS_DP_:
2563 if(provisionDirectPairing())
2565 OIC_LOG(ERROR, TAG, "_33_PROVIS_DP_: error");
2568 case _34_CHECK_LINK_STATUS_:
2569 if(checkLinkedStatus())
2571 OIC_LOG(ERROR, TAG, "_34_CHECK_LINK_STATUS_: error");
2577 OIC_LOG(ERROR, TAG, "_35_SAVE_ACL_: error");
2580 case _40_UNLINK_PAIR_DEVS_:
2581 if(unlinkPairwise())
2583 OIC_LOG(ERROR, TAG, "_40_UNLINK_PAIR_DEVS_: error");
2586 case _50_REMOVE_SELEC_DEV_:
2589 OIC_LOG(ERROR, TAG, "_50_REMOVE_SELEC_DEV_: error");
2592 case _51_REMOVE_DEV_WITH_UUID_:
2593 if(removeDeviceWithUuid())
2595 OIC_LOG(ERROR, TAG, "_51_REMOVE_DEV_WITH_UUID_: error");
2598 case _52_RESET_SELEC_DEV_:
2601 OIC_LOG(ERROR, TAG, "_52_RESET_SELEC_DEV_: error");
2604 case _53_RESET_SVR_DB_:
2607 OIC_LOG(ERROR, TAG, "_53_RESET_SVR_DB_: error");
2613 OIC_LOG(ERROR, TAG, "_60_GET_CRED_: error");
2619 OIC_LOG(ERROR, TAG, "_61_GET_ACL_: error");
2622 #ifdef MULTIPLE_OWNER
2623 case _70_MOT_CHANGE_MOM_:
2624 if(changeMultipleOwnershipTrnasferMode())
2626 OIC_LOG(ERROR, TAG, "_70_MOT_CHANGE_MOM_: error");
2629 case _71_MOT_PROV_PRECONF_PIN_:
2630 if(provisionPreconfigPIN())
2632 OIC_LOG(ERROR, TAG, "_71_MOT_PROV_PRECONF_PIN_: error");
2635 case _72_MOT_OXM_SEL_:
2636 if(selectMultipleOwnershipTrnasferMethod())
2638 OIC_LOG(ERROR, TAG, "_72_MOT_OXM_SEL_: error");
2641 case _73_MOT_REMOVE_SUBOWNER_:
2642 if(removeSubOwner())
2644 OIC_LOG(ERROR, TAG, "_73_MOT_REMOVE_SUBOWNER_ : error");
2647 case _74_MOT_REMOVE_ALL_SUBOWNER_:
2648 if(removeAllSubOwner())
2650 OIC_LOG(ERROR, TAG, "_74_MOT_REMOVE_ALL_SUBOWNER_ : error");
2653 #endif //MULTIPLE_OWNER
2655 case _80_SELECT_PROTOCOL_:
2656 selectSecureProtocol();
2659 case _81_SELECT_VERIF_METHOD_:
2660 selectVerifMethod();
2662 case _82_SECURE_STORAGE_HW_EMULATION_:
2663 secureStorageHwEmulation();
2665 case _99_EXIT_PRVN_CLT_:
2668 printf(">> Entered Wrong Number. Please Enter Again\n\n");
2674 if(OC_STACK_OK != OCStop())
2676 OIC_LOG(ERROR, TAG, "OCStack stop error");
2678 OCDeleteDiscoveredDevices(g_own_list); // after here |g_own_list| points nothing
2679 OCDeleteDiscoveredDevices(g_unown_list); // after here |g_unown_list| points nothing
2680 #ifdef MULTIPLE_OWNER
2681 OCDeleteDiscoveredDevices(g_mot_enable_list); // after here |g_motdev_list| points nothing
2682 #endif //MULTIPLE_OWNER
2686 OICFree(g_svr_fname); // after here |g_svr_fname| points nothing
2690 OICFree(g_prvn_fname); // after here |g_prvn_fname| points nothing
2692 return 0; // always return normal case
2697 #endif //__cplusplus