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 "oxmrawpublickey.h"
41 #include "pkix_interface.h"
42 #include "hw_emul/hw_interface.h"
43 #include "mbedtls/x509_crt.h"
44 #include "secureresourceprovider.h"
51 // declaration(s) for provisioning client using C-level provisioning API
52 // user input definition for main loop on provisioning client
53 #define _10_DISCOV_ALL_DEVS_ 10
54 #define _11_DISCOV_UNOWN_DEVS_ 11
55 #define _12_DISCOV_OWN_DEVS_ 12
57 #define _13_MOT_DISCOV_DEV_ 13
58 #endif //MULTIPLE_OWNER
59 #define _20_REGIST_DEVS_ 20
60 #define _30_PROVIS_PAIR_DEVS_ 30
61 #define _31_PROVIS_CRED_ 31
62 #define _32_PROVIS_ACL_ 32
63 #define _33_PROVIS_DP_ 33
64 #define _34_CHECK_LINK_STATUS_ 34
65 #define _35_SAVE_ACL_ 35
66 #define _40_UNLINK_PAIR_DEVS_ 40
67 #define _50_REMOVE_SELEC_DEV_ 50
68 #define _51_REMOVE_DEV_WITH_UUID_ 51
69 #define _52_RESET_SELEC_DEV_ 52
70 #define _53_RESET_SVR_DB_ 53
71 #define _60_GET_CRED_ 60
72 #define _61_GET_ACL_ 61
74 #define _70_MOT_CHANGE_MOM_ 70
75 #define _71_MOT_PROV_PRECONF_PIN_ 71
76 #define _72_MOT_OXM_SEL_ 72
77 #define _73_MOT_REMOVE_SUBOWNER_ 73
78 #define _74_MOT_REMOVE_ALL_SUBOWNER_ 74
79 #endif //MULTIPLE_OWNER
80 #define _80_SELECT_PROTOCOL_ 80
81 #define _81_SELECT_VERIF_METHOD_ 81
82 #define _82_SECURE_STORAGE_HW_EMULATION_ 82
83 #define _99_EXIT_PRVN_CLT_ 99
85 #define ACL_RESRC_MAX_NUM 16
86 #define ACL_RESRC_ARRAY_SIZE 3 //This value is used only for sample (not OCF spec)
87 #define ACL_RESRC_MAX_LEN 128
88 #define ACL_PEMISN_CNT 5
89 #define DISCOVERY_TIMEOUT 10 // 10 sec
90 #define CALLBACK_TIMEOUT 60 // 1 min
91 #define TAG "provisioningclient"
93 static const char* ACL_PEMISN[5] = {"CREATE", "READ", "WRITE", "DELETE", "NOTIFY"};
94 static const char* SVR_DB_FILE_NAME = "oic_svr_db_client.dat";
95 // '_' for separaing from the same constant variable in |srmresourcestrings.c|
96 static const char* PRVN_DB_FILE_NAME = "oic_prvn_mng.db";
97 static const OicSecPrm_t SUPPORTED_PRMS[1] =
102 // |g_ctx| means provision manager application context and
103 // the following, includes |un/own_list|, could be variables, which |g_ctx| has,
104 // for accessing all function(s) for these, they are declared on global domain
105 static const char* g_ctx = "Provision Manager Client Application Context";
106 static char* g_svr_fname;
107 static char* g_prvn_fname;
108 static OCProvisionDev_t* g_own_list;
109 static OCProvisionDev_t* g_unown_list;
110 static int g_own_cnt;
111 static int g_unown_cnt;
112 #ifdef MULTIPLE_OWNER
113 static OCProvisionDev_t* g_mot_enable_list;
114 static int g_mot_enable_cnt;
115 #endif //MULTIPLE_OWNER
117 static bool g_doneCB;
119 static int secure_protocol = 1;
120 static void setDevProtocol(OCProvisionDev_t* dev_lst);
122 // function declaration(s) for calling them before implementing
123 static OicSecAcl_t* createAcl(const int);
124 static OicSecAcl_t* createSimpleAcl(const OicUuid_t uuid);
125 static OicSecPdAcl_t* createPdAcl(const int);
126 static OCProvisionDev_t* getDevInst(const OCProvisionDev_t*, const int);
127 static int printDevList(const OCProvisionDev_t*);
128 static size_t printUuidList(const OCUuidList_t*);
129 static int printResultList(const OCProvisionResult_t*, const int);
130 static void printUuid(const OicUuid_t*);
131 static FILE* fopen_prvnMng(const char*, const char*);
132 static int waitCallbackRet(void);
133 static int selectTwoDiffNum(int*, int*, const int, const char*);
135 // callback function(s) for provisioning client using C-level provisioning API
136 static void ownershipTransferCB(void* ctx, int nOfRes, OCProvisionResult_t* arr, bool hasError)
140 OIC_LOG_V(INFO, TAG, "Ownership Transfer SUCCEEDED - ctx: %s", (char*) ctx);
144 OIC_LOG_V(ERROR, TAG, "Ownership Transfer FAILED - ctx: %s", (char*) ctx);
145 printResultList((const OCProvisionResult_t*) arr, nOfRes);
150 static void provisionPairwiseCB(void* ctx, int nOfRes, OCProvisionResult_t* arr, bool hasError)
154 OIC_LOG_V(INFO, TAG, "Provision Pairwise SUCCEEDED - ctx: %s", (char*) ctx);
158 OIC_LOG_V(ERROR, TAG, "Provision Pairwise FAILED - ctx: %s", (char*) ctx);
159 printResultList((const OCProvisionResult_t*) arr, nOfRes);
164 static void provisionCredCB(void* ctx, int nOfRes, OCProvisionResult_t* arr, bool hasError)
168 OIC_LOG_V(INFO, TAG, "Provision Credential SUCCEEDED - ctx: %s", (char*) ctx);
172 OIC_LOG_V(ERROR, TAG, "Provision Credential FAILED - ctx: %s", (char*) ctx);
173 printResultList((const OCProvisionResult_t*) arr, nOfRes);
178 static void provisionAclCB(void* ctx, int nOfRes, OCProvisionResult_t* arr, bool hasError)
182 OIC_LOG_V(INFO, TAG, "Provision ACL SUCCEEDED - ctx: %s", (char*) ctx);
186 OIC_LOG_V(ERROR, TAG, "Provision ACL FAILED - ctx: %s", (char*) ctx);
187 printResultList((const OCProvisionResult_t*) arr, nOfRes);
192 static void getCredCB(void* ctx, int nOfRes, OCProvisionResult_t* arr, bool hasError)
196 OIC_LOG_V(INFO, TAG, "getCredCB SUCCEEDED - ctx: %s", (char*) ctx);
200 OIC_LOG_V(ERROR, TAG, "getCredCB FAILED - ctx: %s", (char*) ctx);
201 printResultList((const OCProvisionResult_t*) arr, nOfRes);
206 static void getAclCB(void* ctx, int nOfRes, OCProvisionResult_t* arr, bool hasError)
210 OIC_LOG_V(INFO, TAG, "getAclCB SUCCEEDED - ctx: %s", (char*) ctx);
214 OIC_LOG_V(ERROR, TAG, "getAclCB FAILED - ctx: %s", (char*) ctx);
215 printResultList((const OCProvisionResult_t*) arr, nOfRes);
220 static void provisionDPCB(void* ctx, int nOfRes, OCProvisionResult_t* arr, bool hasError)
224 OIC_LOG_V(INFO, TAG, "Provision Direct-Pairing SUCCEEDED - ctx: %s", (char*) ctx);
228 OIC_LOG_V(ERROR, TAG, "Provision Direct-Pairing FAILED - ctx: %s", (char*) ctx);
229 printResultList((const OCProvisionResult_t*) arr, nOfRes);
234 static void unlinkDevicesCB(void* ctx, int nOfRes, OCProvisionResult_t* arr, bool hasError)
238 OIC_LOG_V(INFO, TAG, "Unlink Devices SUCCEEDED - ctx: %s", (char*) ctx);
242 OIC_LOG_V(ERROR, TAG, "Unlink Devices FAILED - ctx: %s", (char*) ctx);
243 printResultList((const OCProvisionResult_t*) arr, nOfRes);
248 static void removeDeviceCB(void* ctx, int nOfRes, OCProvisionResult_t* arr, bool hasError)
252 OIC_LOG_V(INFO, TAG, "Remove Device SUCCEEDED - ctx: %s", (char*) ctx);
256 OIC_LOG_V(ERROR, TAG, "Remove Device FAILED - ctx: %s", (char*) ctx);
257 printResultList((const OCProvisionResult_t*) arr, nOfRes);
262 static void resetDeviceCB(void* ctx)
265 OIC_LOG_V(INFO, TAG, "Reset Device SUCCEEDED");
269 #ifdef MULTIPLE_OWNER
270 static void updateDoxmForMOTCB(void* ctx, int nOfRes, OCProvisionResult_t* arr, bool hasError)
274 OIC_LOG_V(INFO, TAG, "POST 'doxm' SUCCEEDED - ctx: %s", (char*) ctx);
278 OIC_LOG_V(ERROR, TAG, "POST 'doxm' FAILED - ctx: %s", (char*) ctx);
279 printResultList((const OCProvisionResult_t*) arr, nOfRes);
284 static void deleteDoxmForMOTCB(void* ctx, int nOfRes, OCProvisionResult_t* arr, bool hasError)
288 OIC_LOG_V(INFO, TAG, "DELETE 'doxm' SUCCEEDED - ctx: %s", (char*) ctx);
292 OIC_LOG_V(ERROR, TAG, "DELETE 'doxm' FAILED - ctx: %s", (char*) ctx);
293 printResultList((const OCProvisionResult_t*) arr, nOfRes);
298 #endif //MULTIPLE_OWNER
300 static void inputPinCB(char* pin, size_t len)
302 if(!pin || OXM_RANDOM_PIN_MIN_SIZE > len)
304 OIC_LOG(ERROR, TAG, "inputPinCB invalid parameters");
308 printf(" > INPUT PIN: ");
309 for(int ret=0; 1!=ret; )
311 ret = scanf("%32s", pin);
312 for( ; 0x20<=getchar(); ); // for removing overflow garbages
313 // '0x20<=code' is character region
317 static char rpk[32] = {
318 0xB2, 0xA2, 0x0D, 0xC0, 0xCB, 0x3C, 0xA0, 0x27,
319 0x45, 0x00, 0x73, 0xBD, 0x02, 0xF5, 0x84, 0x4B,
320 0x0C, 0x1C, 0xD6, 0x6A, 0xD3, 0x9E, 0x3F, 0x64,
321 0x95, 0x6B, 0xB8, 0xCA, 0x58, 0xBC, 0xBE, 0xBE
324 static void InputRPKMasterKeyCB(char **rpkMasterKey, size_t *rpkMasterKeyLen)
326 if(!rpkMasterKey || !rpkMasterKeyLen)
328 OIC_LOG(ERROR, TAG, "InputRPKMasterKeyCB invalid parameters");
333 *rpkMasterKeyLen = 32;
336 // function(s) for provisioning client using C-level provisioning API
337 static int initProvisionClient(void)
339 // initialize persistent storage for SVR DB
340 static OCPersistentStorage pstStr =
342 .open = fopen_prvnMng,
348 if(OC_STACK_OK != OCRegisterPersistentStorageHandler(&pstStr))
350 OIC_LOG(ERROR, TAG, "OCRegisterPersistentStorageHandler error");
354 // initialize OC stack and provisioning manager
355 if(OC_STACK_OK != OCInit(NULL, 0, OC_CLIENT_SERVER))
357 OIC_LOG(ERROR, TAG, "OCStack init error");
361 if (access(PRVN_DB_FILE_NAME, F_OK) != -1)
363 printf("************************************************************\n");
364 printf("************Provisioning DB file already exists.************\n");
365 printf("************************************************************\n");
369 printf("*************************************************************\n");
370 printf("************No provisioning DB file, creating new************\n");
371 printf("*************************************************************\n");
374 if(OC_STACK_OK != OCInitPM(PRVN_DB_FILE_NAME))
376 OIC_LOG(ERROR, TAG, "OC_PM init error");
380 SetInputPinCB(inputPinCB);
381 SetRPKMasterKeyCB(InputRPKMasterKeyCB);
386 static int discoverAllDevices(void)
388 // delete un/owned device lists before updating them
391 OCDeleteDiscoveredDevices(g_own_list);
396 OCDeleteDiscoveredDevices(g_unown_list);
400 // call |OCGetDevInfoFromNetwork| API actually
401 printf(" Discovering All Un/Owned Devices on Network..\n");
402 if(OC_STACK_OK != OCGetDevInfoFromNetwork(DISCOVERY_TIMEOUT, &g_own_list, &g_unown_list))
404 OIC_LOG(ERROR, TAG, "OCGetDevInfoFromNetwork API error");
408 // display the discovered un/owned lists
409 printf(" > Discovered Owned Devices\n");
410 g_own_cnt = printDevList(g_own_list);
411 printf(" > Discovered Unowned Devices\n");
412 g_unown_cnt = printDevList(g_unown_list);
414 setDevProtocol(g_own_list);
415 setDevProtocol(g_unown_list);
421 static int discoverUnownedDevices(void)
423 // delete unowned device list before updating it
426 OCDeleteDiscoveredDevices(g_unown_list);
430 // call |OCDiscoverUnownedDevices| API actually
431 printf(" Discovering Only Unowned Devices on Network..\n");
432 if(OC_STACK_OK != OCDiscoverUnownedDevices(DISCOVERY_TIMEOUT, &g_unown_list))
434 OIC_LOG(ERROR, TAG, "OCDiscoverUnownedDevices API error");
438 // display the discovered unowned list
439 printf(" > Discovered Unowned Devices\n");
440 g_unown_cnt = printDevList(g_unown_list);
442 setDevProtocol(g_unown_list);
447 static int discoverOwnedDevices(void)
449 // delete owned device list before updating it
452 OCDeleteDiscoveredDevices(g_own_list);
456 // call |OCDiscoverOwnedDevices| API actually
457 printf(" Discovering Only Owned Devices on Network..\n");
458 if(OC_STACK_OK != OCDiscoverOwnedDevices(DISCOVERY_TIMEOUT, &g_own_list))
460 OIC_LOG(ERROR, TAG, "OCDiscoverOwnedDevices API error");
464 // display the discovered owned list
465 printf(" > Discovered Owned Devices\n");
466 g_own_cnt = printDevList(g_own_list);
468 setDevProtocol(g_own_list);
473 #ifdef MULTIPLE_OWNER
474 static int discoverMOTEnabledDevices(void)
476 // delete owned device list before updating it
477 if(g_mot_enable_list)
479 OCDeleteDiscoveredDevices(g_mot_enable_list);
480 g_mot_enable_list = NULL;
483 // call |OCDiscoverOwnedDevices| API actually
484 printf(" Discovering Multiple Ownership Transfer Enabled Devices on Network..\n");
485 if(OC_STACK_OK != OCDiscoverMultipleOwnerEnabledDevices(DISCOVERY_TIMEOUT, &g_mot_enable_list))
487 OIC_LOG(ERROR, TAG, "OCDiscoverMultipleOwnerEnalbedDevices API error");
491 // display the discovered owned list
492 printf(" > Discovered Multiple Ownership Transfer Enabled Devices\n");
493 g_mot_enable_cnt = printDevList(g_mot_enable_list);
497 #endif //MULTIPLE_OWNER
499 static int registerDevices(void)
501 // check |unown_list| for registering devices
502 if(!g_unown_list || 0>=g_unown_cnt)
504 printf(" > Unowned Device List, to Register Devices, is Empty\n");
505 printf(" > Please Discover Unowned Devices first, with [10|11] Menu\n");
506 return 0; // normal case
509 // call |OCDoOwnershipTransfer| API actually
510 // calling this API with callback actually acts like blocking
511 // for error checking, the return value saved and printed
513 printf(" Registering All Discovered Unowned Devices..\n");
514 OCStackResult rst = OCDoOwnershipTransfer((void*) g_ctx, g_unown_list, ownershipTransferCB);
515 if(OC_STACK_OK != rst)
517 OIC_LOG_V(ERROR, TAG, "OCDoOwnershipTransfer API error: %d", rst);
520 if(waitCallbackRet()) // input |g_doneCB| flag implicitly
522 OIC_LOG(ERROR, TAG, "OCProvisionCredentials callback error");
526 // display the registered result
527 printf(" > Registered Discovered Unowned Devices\n");
528 printf(" > Please Discover Owned Devices for the Registered Result, with [10|12] Menu\n");
533 static int provisionPairwise(void)
535 // check |own_list| for provisioning pairwise devices
536 if(!g_own_list || 2>g_own_cnt)
538 printf(" > Owned Device List, to Provision the Pairwise, is Empty\n");
539 printf(" > Please Register Unowned Devices first, with [20] Menu\n");
540 return 0; // normal case
543 // select two devices for provisioning pairwise devices
544 int dev_num[2] = {0};
545 if(selectTwoDiffNum(&(dev_num[0]), &(dev_num[1]), g_own_cnt, "for Linking Devices"))
547 OIC_LOG(ERROR, TAG, "selectTwoDiffNum error return");
548 return -1; // not need to 'goto' |ERROR| before allocating |acl|
551 // create ACL(s) for each selected device
552 OicSecAcl_t* acl[2] = {0};
553 for(int i=0; 2>i; ++i)
555 acl[i] = createAcl(dev_num[i]);
558 OIC_LOG(ERROR, TAG, "createAcl error return");
563 // call |OCProvisionPairwiseDevices| API actually
564 // calling this API with callback actually acts like blocking
565 // for error checking, the return value saved and printed
567 printf(" Provisioning Selected Pairwise Devices..\n");
569 OCProvisionPairwiseDevices((void*) g_ctx,
570 SYMMETRIC_PAIR_WISE_KEY, OWNER_PSK_LENGTH_128,
571 getDevInst((const OCProvisionDev_t*) g_own_list, dev_num[0]), acl[0],
572 getDevInst((const OCProvisionDev_t*) g_own_list, dev_num[1]), acl[1],
573 provisionPairwiseCB);
574 if(OC_STACK_OK != rst)
576 OIC_LOG_V(ERROR, TAG, "OCProvisionPairwiseDevices API error: %d", rst);
579 if(waitCallbackRet()) // input |g_doneCB| flag implicitly
581 OIC_LOG(ERROR, TAG, "OCProvisionCredentials callback error");
584 OCDeleteACLList(acl[0]);
585 OCDeleteACLList(acl[1]);
587 // display the pairwise-provisioned result
588 printf(" > Provisioned Selected Pairwise Devices\n");
589 printf(" > Please Check Device's Status for the Linked Result, with [33] Menu\n");
594 OCDeleteACLList(acl[0]);
595 OCDeleteACLList(acl[1]);
599 static int provisionCred(void)
601 // check |own_list| for provisioning pairwise credentials
602 if(!g_own_list || 2>g_own_cnt)
604 printf(" > Owned Device List, to Provision Credentials, is Empty\n");
605 printf(" > Please Register Unowned Devices first, with [20] Menu\n");
606 return 0; // normal case
609 // select two devices for provisioning pairwise credentials
610 int dev_num[2] = {0};
611 if(selectTwoDiffNum(&(dev_num[0]), &(dev_num[1]), g_own_cnt, "for Linking CRED(s)"))
613 OIC_LOG(ERROR, TAG, "selectTwoDiffNum error return");
617 printf(" Select PSK length..\n");
618 printf(" 1 - 128bit(Default)\n");
619 printf(" 2 - 256bit\n");
622 for(int ret=0; 1!=ret; )
624 ret = scanf("%d",&sizeOption);
625 for( ; 0x20<=getchar(); ); // for removing overflow garbages
626 // '0x20<=code' is character region
634 size = OWNER_PSK_LENGTH_128;
639 size = OWNER_PSK_LENGTH_256;
644 size = OWNER_PSK_LENGTH_128;
650 // call |OCProvisionCredentials| API actually
651 // calling this API with callback actually acts like blocking
652 // for error checking, the return value saved and printed
654 printf(" Provisioning Selected Pairwise Credentials..\n");
656 OCProvisionCredentials((void*) g_ctx,
657 SYMMETRIC_PAIR_WISE_KEY, size,
658 getDevInst((const OCProvisionDev_t*) g_own_list, dev_num[0]),
659 getDevInst((const OCProvisionDev_t*) g_own_list, dev_num[1]),
661 if(OC_STACK_OK != rst)
663 OIC_LOG_V(ERROR, TAG, "OCProvisionCredentials API error: %d", rst);
666 if(waitCallbackRet()) // input |g_doneCB| flag implicitly
668 OIC_LOG(ERROR, TAG, "OCProvisionCredentials callback error");
672 // display the CRED-provisioned result
673 printf(" > Provisioned Selected Pairwise Crendentials\n");
674 printf(" > Please Check Device's Status for the Linked Result, with [34] Menu\n");
679 static int provisionAcl(void)
681 // check |own_list| for provisioning access control list
682 if(!g_own_list || 1>g_own_cnt)
684 printf(" > Owned Device List, to Provision ACL, is Empty\n");
685 printf(" > Please Register Unowned Devices first, with [20] Menu\n");
686 return 0; // normal case
689 // select device for provisioning access control list
693 printf(" > Enter Device Number, for Provisioning ACL: ");
694 for(int ret=0; 1!=ret; )
696 ret = scanf("%d", &dev_num);
697 for( ; 0x20<=getchar(); ); // for removing overflow garbages
698 // '0x20<=code' is character region
700 if(0<dev_num && g_own_cnt>=dev_num)
704 printf(" Entered Wrong Number. Please Enter Again\n");
707 // create ACL for selected device
708 OicSecAcl_t* acl = NULL;
709 acl = createAcl(dev_num);
712 OIC_LOG(ERROR, TAG, "createAcl error return");
716 // call |OCProvisionACL| API actually
717 // calling this API with callback actually acts like blocking
718 // for error checking, the return value saved and printed
720 printf(" Provisioning Selected ACL..\n");
721 OCProvisionDev_t* dev = getDevInst((const OCProvisionDev_t*) g_own_list, dev_num);
724 OIC_LOG(ERROR, TAG, "provisionAcl: device instance empty");
727 OCStackResult rst = OCProvisionACL((void*) g_ctx, dev, acl, provisionAclCB);
728 if(OC_STACK_OK != rst)
730 OIC_LOG_V(ERROR, TAG, "OCProvisionACL API error: %d", rst);
733 if(waitCallbackRet()) // input |g_doneCB| flag implicitly
735 OIC_LOG(ERROR, TAG, "OCProvisionCredentials callback error");
738 OCDeleteACLList(acl); // after here |acl| points nothing
740 // display the ACL-provisioned result
741 printf(" > Provisioned Selected ACL\n");
746 OCDeleteACLList(acl); // after here |acl| points nothing
750 static int provisionDirectPairing(void)
752 // check |own_list| for provisioning direct-pairing
753 if(!g_own_list || 1>g_own_cnt)
755 printf(" > Owned Device List, to Provision ACL, is Empty\n");
756 printf(" > Please Register Unowned Devices first, with [20] Menu\n");
757 return 0; // normal case
760 // select device for provisioning direct-pairing
764 printf(" > Enter Device Number, for Provisioning Direct-Pairing: ");
765 for(int ret=0; 1!=ret; )
767 ret = scanf("%d", &dev_num);
768 for( ; 0x20<=getchar(); ); // for removing overflow garbages
769 // '0x20<=code' is character region
771 if(0<dev_num && g_own_cnt>=dev_num)
775 printf(" Entered Wrong Number. Please Enter Again\n");
778 // create Direct-Pairing Configuration(PIN, PDACL) for selected device
779 // TODO: default acl -> input from user !
781 memset(&pconf, 0, sizeof(OicSecPconf_t));
786 // set default supported PRM types
787 pconf.prmLen = sizeof(SUPPORTED_PRMS)/sizeof(OicSecPrm_t);
788 pconf.prm = (OicSecPrm_t *)OICCalloc(pconf.prmLen, sizeof(OicSecPrm_t));
791 for (size_t i=0; i<pconf.prmLen; i++)
793 pconf.prm[i] = SUPPORTED_PRMS[i];
798 OIC_LOG(ERROR, TAG, "create prm error return");
803 const char DP_DEFAULT_PIN[] = "00000000";
804 memcpy(pconf.pin.val, DP_DEFAULT_PIN, DP_PIN_LENGTH);
807 pconf.pdacls = createPdAcl(dev_num);
810 OIC_LOG(ERROR, TAG, "createPdAcl error return");
814 // call |OCProvisionDirectPairing| API actually
815 // calling this API with callback actually acts like blocking
816 // for error checking, the return value saved and printed
818 printf(" Atempt Direct-Pairing Provisioning (PIN : [%s])..\n", (char*)pconf.pin.val);
819 OCStackResult rst = OCProvisionDirectPairing((void*) g_ctx,
820 getDevInst((const OCProvisionDev_t*) g_own_list, dev_num),
821 &pconf, provisionDPCB);
822 if(OC_STACK_OK != rst)
824 OIC_LOG_V(ERROR, TAG, "OCProvisionDirectPairing API error: %d", rst);
825 if (OC_STACK_UNAUTHORIZED_REQ == rst)
827 OIC_LOG(ERROR, TAG, "Target Server NOT Support Direct-Pairing !!! (DPC == false)");
831 if(waitCallbackRet()) // input |g_doneCB| flag implicitly
833 OIC_LOG(ERROR, TAG, "OCProvisionCredentials callback error");
836 OCDeletePdAclList(pconf.pdacls);
838 // display the PCONF-provisioned result
839 printf(" > SUCCESS to provision Direct-Pairing !!\n");
844 OCDeletePdAclList(pconf.pdacls); // after here |acl| points nothing
848 static int checkLinkedStatus(void)
850 // check |own_list| for checking selected link status on PRVN DB
851 if(!g_own_list || 1>g_own_cnt)
853 printf(" > Owned Device List, to Check Linked Status on PRVN DB, is Empty\n");
854 printf(" > Please Register Unowned Devices first, with [20] Menu\n");
855 return 0; // normal case
858 // select device for checking selected link status on PRVN DB
862 printf(" > Enter Device Number, for Checking Linked Status on PRVN DB: ");
863 for(int ret=0; 1!=ret; )
865 ret = scanf("%d", &dev_num);
866 for( ; 0x20<=getchar(); ); // for removing overflow garbages
867 // '0x20<=code' is character region
869 if(0<dev_num && g_own_cnt>=dev_num)
873 printf(" Entered Wrong Number. Please Enter Again\n");
876 // call |OCGetLinkedStatus| API actually
877 printf(" Checking Selected Link Status on PRVN DB..\n");
878 OCUuidList_t* dvid_lst = NULL;
880 OCProvisionDev_t* dev = getDevInst((const OCProvisionDev_t*)g_own_list, dev_num);
881 if(!dev || !dev->doxm)
883 OIC_LOG(ERROR, TAG, "checkLinkedStatus: device instance empty");
889 &dev->doxm->deviceID,
890 &dvid_lst, &dvid_cnt)) // allow empty list
892 OIC_LOG(ERROR, TAG, "OCGetLinkedStatus API error");
896 // display the linked status result
897 printf(" > Checked Selected Link Status on PRVN DB\n");
898 if(!dvid_lst || !dvid_cnt) // |size_t| is unsigned
900 printf(" Linked Device List is Empty..\n");
901 return 0; // normal case
903 if(dvid_cnt != printUuidList((const OCUuidList_t*) dvid_lst))
905 OIC_LOG(ERROR, TAG, "printUuidList error return");
908 OCDeleteUuidList(dvid_lst);
913 OCDeleteUuidList(dvid_lst);
917 static int saveAcl(void)
919 // create ACL to save into local SVR DB
920 OicSecAcl_t* acl = NULL;
921 OicUuid_t uuid = {.id={0}};
922 char strUuid[64] = {0};
924 printf("[1] Use a test UUID [11111111-2222-3333-4444-555555555555]\n");
925 printf("[2] Use a user input\n");
929 printf(" > Select Number, for Subject UUID of new ACE: ");
930 for(int ret=0; 1!=ret; )
932 ret = scanf("%d", &sel_num);
933 for( ; 0x20<=getchar(); ); // for removing overflow garbages
934 // '0x20<=code' is character region
938 OICStrcpy(strUuid, sizeof(strUuid), "11111111-2222-3333-4444-555555555555");
941 else if(2 == sel_num)
943 printf(" > Input the UUID : ");
944 for(int ret=0; 1!=ret; )
946 ret = scanf("%64s", strUuid);
947 for( ; 0x20<=getchar(); ); // for removing overflow garbages
948 // '0x20<=code' is character region
952 printf(" Entered Wrong Number. Please Enter Again\n");
956 printf("Selected Subject UUID : %s\n", strUuid);
957 OCStackResult rst = ConvertStrToUuid(strUuid, &uuid);
958 if(OC_STACK_OK != rst)
960 OIC_LOG_V(ERROR, TAG, "ConvertStrToUuid API error: %d", rst);
964 acl = createSimpleAcl(uuid);
967 OIC_LOG(ERROR, TAG, "createAcl error return");
971 // call |OCSaveACL| API actually
972 rst = OCSaveACL(acl);
973 if(OC_STACK_OK != rst)
975 OIC_LOG_V(ERROR, TAG, "OCSaveACL API error: %d", rst);
978 OCDeleteACLList(acl); // after here |acl| points nothing
980 // display the ACL-provisioned result
981 printf(" > Saved Selected ACL\n");
986 OCDeleteACLList(acl); // after here |acl| points nothing
990 static int getCred(void)
992 // check |own_list| for checking selected link status on PRVN DB
993 if(!g_own_list || 1>g_own_cnt)
995 printf(" > Owned Device List, to Check Linked Status on PRVN DB, is Empty\n");
996 printf(" > Please Register Unowned Devices first, with [20] Menu\n");
997 return 0; // normal case
1000 // select device for checking selected link status on PRVN DB
1004 printf(" > Enter Device Number, for Checking Linked Status on PRVN DB: ");
1005 for(int ret=0; 1!=ret; )
1007 ret = scanf("%d", &dev_num);
1008 for( ; 0x20<=getchar(); ); // for removing overflow garbages
1009 // '0x20<=code' is character region
1011 if(0<dev_num && g_own_cnt>=dev_num)
1015 printf(" Entered Wrong Number. Please Enter Again\n");
1018 // call |getDevInst| API actually
1019 // calling this API with callback actually acts like blocking
1020 // for error checking, the return value saved and printed
1022 OCProvisionDev_t* dev = getDevInst((const OCProvisionDev_t*) g_own_list, dev_num);
1025 OIC_LOG(ERROR, TAG, "getDevInst: device instance empty");
1028 OCStackResult rst = OCGetCredResource((void*) g_ctx, dev, getCredCB);
1029 if(OC_STACK_OK != rst)
1031 OIC_LOG_V(ERROR, TAG, "OCGetCred API error: %d", rst);
1034 if(waitCallbackRet()) // input |g_doneCB| flag implicitly
1036 OIC_LOG(ERROR, TAG, "OCGetCredResource callback error");
1040 // display the result of get credential
1041 printf(" > Get Cred SUCCEEDED\n");
1049 static int getAcl(void)
1051 // check |own_list| for checking selected link status on PRVN DB
1052 if(!g_own_list || 1>g_own_cnt)
1054 printf(" > Owned Device List, to Check Linked Status on PRVN DB, is Empty\n");
1055 printf(" > Please Register Unowned Devices first, with [20] Menu\n");
1056 return 0; // normal case
1059 // select device for checking selected link status on PRVN DB
1063 printf(" > Enter Device Number, for Checking Linked Status on PRVN DB: ");
1064 for(int ret=0; 1!=ret; )
1066 ret = scanf("%d", &dev_num);
1067 for( ; 0x20<=getchar(); ); // for removing overflow garbages
1068 // '0x20<=code' is character region
1070 if(0<dev_num && g_own_cnt>=dev_num)
1074 printf(" Entered Wrong Number. Please Enter Again\n");
1077 // call |getDevInst| API actually
1078 // calling this API with callback actually acts like blocking
1079 // for error checking, the return value saved and printed
1081 OCProvisionDev_t* dev = getDevInst((const OCProvisionDev_t*) g_own_list, dev_num);
1084 OIC_LOG(ERROR, TAG, "getDevInst: device instance empty");
1087 OCStackResult rst = OCGetACLResource((void*) g_ctx, dev, getAclCB);
1088 if(OC_STACK_OK != rst)
1090 OIC_LOG_V(ERROR, TAG, "OCGetACLResource API error: %d", rst);
1094 if(waitCallbackRet()) // input |g_doneCB| flag implicitly
1096 OIC_LOG(ERROR, TAG, "OCGetACLResource callback error");
1100 // display the result of get credential
1101 printf(" > Get ACL SUCCEEDED\n");
1109 static int unlinkPairwise(void)
1111 // check |own_list| for unlinking pairwise devices
1112 if(!g_own_list || 2>g_own_cnt)
1114 printf(" > Owned Device List, to Unlink the Pairwise, is Empty\n");
1115 printf(" > Please Register Unowned Devices first, with [20] Menu\n");
1116 return 0; // normal case
1119 // select two devices for unlinking pairwise devices
1120 int dev_num[2] = {0};
1121 if(selectTwoDiffNum(&(dev_num[0]), &(dev_num[1]), g_own_cnt, "for Unlinking Devices"))
1123 OIC_LOG(ERROR, TAG, "selectTwoDiffNum error return");
1127 // call |OCUnlinkDevices| API actually
1128 // calling this API with callback actually acts like blocking
1129 // for error checking, the return value saved and printed
1131 printf(" Unlinking Selected Pairwise Devices..\n");
1133 OCUnlinkDevices((void*) g_ctx,
1134 getDevInst((const OCProvisionDev_t*) g_own_list, dev_num[0]),
1135 getDevInst((const OCProvisionDev_t*) g_own_list, dev_num[1]),
1137 if(OC_STACK_OK != rst)
1139 OIC_LOG_V(ERROR, TAG, "OCUnlinkDevices API error: %d", rst);
1142 if(waitCallbackRet()) // input |g_doneCB| flag implicitly
1144 OIC_LOG(ERROR, TAG, "OCProvisionCredentials callback error");
1148 // display the pairwise-unlinked result
1149 printf(" > Unlinked Selected Pairwise Devices\n");
1150 printf(" > Please Check Device's Status for the Unlinked Result, with [33] Menu\n");
1155 static int removeDevice(void)
1157 // check |own_list| for removing device
1158 if(!g_own_list || 1>g_own_cnt)
1160 printf(" > Owned Device List, to Remove Device, is Empty\n");
1161 printf(" > Please Register Unowned Devices first, with [20] Menu\n");
1162 return 0; // normal case
1165 // select device for removing it
1169 printf(" > Enter Device Number, for Removing Device: ");
1170 for(int ret=0; 1!=ret; )
1172 ret = scanf("%d", &dev_num);
1173 for( ; 0x20<=getchar(); ); // for removing overflow garbages
1174 // '0x20<=code' is character region
1176 if(0<dev_num && g_own_cnt>=dev_num)
1180 printf(" Entered Wrong Number. Please Enter Again\n");
1183 // call |OCRemoveDevice| API actually
1184 // calling this API with callback actually acts like blocking
1185 // for error checking, the return value saved and printed
1187 printf(" Removing Selected Owned Device..\n");
1189 OCRemoveDevice((void*) g_ctx, DISCOVERY_TIMEOUT,
1190 getDevInst((const OCProvisionDev_t*) g_own_list, dev_num), removeDeviceCB);
1191 if(OC_STACK_OK != rst)
1193 OIC_LOG_V(ERROR, TAG, "OCRemoveDevice API error: %d", rst);
1196 if(waitCallbackRet()) // input |g_doneCB| flag implicitly
1198 OIC_LOG(ERROR, TAG, "OCProvisionCredentials callback error");
1202 // display the removed result
1203 printf(" > Removed Selected Owned Device\n");
1204 printf(" > Please Discover Owned Devices for the Registered Result, with [10|12] Menu\n");
1209 static int removeDeviceWithUuid(void)
1211 char strUuid[64] = {0};
1213 printf("Input the UUID : ");
1214 for(int ret=0; 1!=ret; )
1216 ret = scanf("%63s", strUuid);
1217 for( ; 0x20<=getchar(); ); // for removing overflow garbages
1218 // '0x20<=code' is character region
1220 OCStackResult rst = ConvertStrToUuid(strUuid, &revUuid);
1221 if(OC_STACK_OK != rst)
1223 OIC_LOG_V(ERROR, TAG, "ConvertStrToUuid API error: %d", rst);
1228 rst = OCRemoveDeviceWithUuid("RemoveDeviceWithUUID", DISCOVERY_TIMEOUT, &revUuid, removeDeviceCB);
1229 if(OC_STACK_OK != rst)
1231 OIC_LOG_V(ERROR, TAG, "OCRemoveDeviceWithUuid API error: %d", rst);
1235 if(waitCallbackRet()) // input |g_doneCB| flag implicitly
1237 OIC_LOG(ERROR, TAG, "OCRemoveDeviceWithUuid callback error");
1241 // display the removed result
1242 printf(" > Removed %s Device\n", strUuid);
1243 printf(" > Please Discover Owned Devices for the Registered Result, with [10|12] Menu\n");
1248 OCStackResult displayNumCB(void * ctx, uint8_t mutualVerifNum[MUTUAL_VERIF_NUM_LEN])
1250 OIC_LOG(INFO, TAG, "IN displayMutualVerifNumCB");
1252 if (NULL != mutualVerifNum)
1254 OIC_LOG(INFO, TAG, "############ mutualVerifNum ############");
1255 OIC_LOG_BUFFER(INFO, TAG, mutualVerifNum, MUTUAL_VERIF_NUM_LEN);
1256 OIC_LOG(INFO, TAG, "############ mutualVerifNum ############");
1257 OIC_LOG(INFO, TAG, "OUT displayMutualVerifNumCB");
1261 OIC_LOG(INFO, TAG, "############ Confirm on the Server side ############");
1266 OCStackResult confirmNumCB(void * ctx)
1273 printf(" > Press 1 if the mutual verification numbers are the same\n");
1274 printf(" > Press 0 if the mutual verification numbers are not the same\n");
1276 for (int ret=0; 1!=ret; )
1278 ret = scanf("%d", &userConfirm);
1279 for (; 0x20<=getchar(); ); // for removing overflow garbage
1280 // '0x20<=code' is character region
1282 if (1 == userConfirm)
1286 else if (0 == userConfirm)
1288 return OC_STACK_USER_DENIED_REQ;
1290 printf(" Entered Wrong Number. Please Enter Again\n");
1295 OCStackResult notifyInputStateCB(void * ctx)
1299 OIC_LOG(DEBUG, TAG, "IN notifyInputStateCB");
1300 OIC_LOG(DEBUG, TAG, "User input Callback in progress");
1301 OIC_LOG(DEBUG, TAG, "OUT notifyInputStateCB");
1306 #ifdef MULTIPLE_OWNER
1307 static int changeMultipleOwnershipTrnasferMode(void)
1309 // check |own_list| for removing device
1310 if(!g_own_list || 1>g_own_cnt)
1312 printf(" > Owned Device List is Empty\n");
1313 printf(" > Please Discover the Owned Devices, with [12] Menu\n");
1314 return 0; // normal case
1317 // select device for removing it
1321 printf(" > Enter Device Number, for MOT Device: ");
1322 for(int ret=0; 1!=ret; )
1324 ret = scanf("%d", &dev_num);
1325 for( ; 0x20<=getchar(); ); // for removing overflow garbages
1326 // '0x20<=code' is character region
1328 if(0<dev_num && g_own_cnt>=dev_num)
1332 printf(" Entered Wrong Number. Please Enter Again\n");
1338 printf(" 0. Disable Multuple Ownership Transfer\n");
1339 printf(" 1. Enable Multuple Ownership Transfer\n");
1340 printf(" 2. (Not Supported yet) Timely Enable Multuple Ownership Transfer\n");
1341 printf(" > Enter Mode of Multuple Ownership Transfer : ");
1342 for(int ret=0; 1!=ret; )
1344 ret = scanf("%d", &mom);
1345 for( ; 0x20<=getchar(); ); // for removing overflow garbages
1346 // '0x20<=code' is character region
1348 if(0 <= dev_num && OIC_NUMBER_OF_MOM_TYPE > dev_num)
1352 printf(" Entered Wrong Number. Please Enter Again\n");
1355 OCProvisionDev_t* motDev = getDevInst(g_own_list, dev_num);
1356 if(OC_STACK_OK == OCChangeMOTMode(NULL, motDev, (OicSecMomType_t)dev_num, updateDoxmForMOTCB))
1362 OIC_LOG(ERROR, TAG, "OCChangeMOTMode API error");
1366 if(waitCallbackRet()) // input |g_doneCB| flag implicitly
1368 OIC_LOG(ERROR, TAG, "waitCallbackRet callback error");
1375 static int selectMultipleOwnershipTrnasferMethod(void)
1377 // check |own_list| for removing device
1378 if(!g_mot_enable_list || 1>g_mot_enable_cnt)
1380 printf(" > Multiple Ownership Transfer Enabled Device List is Empty\n");
1381 printf(" > Please Discover the Multiple Ownership Transfer Enabled Devices, with [13] Menu\n");
1382 return 0; // normal case
1385 // select device for removing it
1389 printf(" > Enter Device Number, for MOT Device: ");
1390 for(int ret=0; 1!=ret; )
1392 ret = scanf("%d", &dev_num);
1393 for( ; 0x20<=getchar(); ); // for removing overflow garbages
1394 // '0x20<=code' is character region
1396 if(0<dev_num && g_mot_enable_cnt>=dev_num)
1400 printf(" Entered Wrong Number. Please Enter Again\n");
1403 const int preconfOxm = 4;
1407 printf(" %d. (Not Supported)\n", OIC_JUST_WORKS);
1408 printf(" %d. Random PIN OxM\n", OIC_RANDOM_DEVICE_PIN);
1409 printf(" %d. (Not Supported)\n", OIC_MANUFACTURER_CERTIFICATE);
1410 printf(" %d. (Not Supported)\n", OIC_DECENTRALIZED_PUBLIC_KEY);
1411 printf(" %d. Pre-Configured PIN OxM\n", OIC_PRECONFIG_PIN);
1412 printf(" > Enter Number of OxM for Multiple Ownership Transfer : ");
1413 for(int ret=0; 1!=ret; )
1415 ret = scanf("%d", &oxm);
1416 for( ; 0x20<=getchar(); ); // for removing overflow garbages
1417 // '0x20<=code' is character region
1419 if(OIC_PRECONFIG_PIN == oxm || OIC_RANDOM_DEVICE_PIN == oxm)
1423 printf(" Entered Wrong Number. Please Enter Again\n");
1426 OCProvisionDev_t* motDev = getDevInst(g_mot_enable_list, dev_num);
1427 if(OC_STACK_OK == OCSelectMOTMethod(NULL, motDev, (OicSecOxm_t)oxm, updateDoxmForMOTCB))
1433 OIC_LOG(ERROR, TAG, "OCSelectMOTMethod API error");
1437 if(waitCallbackRet()) // input |g_doneCB| flag implicitly
1439 OIC_LOG(ERROR, TAG, "waitCallbackRet callback error");
1446 static int provisionPreconfigPIN()
1448 // check |own_list| for removing device
1449 if(!g_mot_enable_list || 1>g_mot_enable_cnt)
1451 printf(" > Multiple Ownership Transfer Enabled Device List is Empty\n");
1452 printf(" > Please Discover the Multiple Ownership Transfer Enabled Devices, with [13] Menu\n");
1453 return 0; // normal case
1456 // select device for removing it
1460 printf(" > Enter Device Number, for MOT Device: ");
1461 for(int ret=0; 1!=ret; )
1463 ret = scanf("%d", &dev_num);
1464 for( ; 0x20<=getchar(); ); // for removing overflow garbages
1465 // '0x20<=code' is character region
1467 if(0<dev_num && g_mot_enable_cnt>=dev_num)
1471 printf(" Entered Wrong Number. Please Enter Again\n");
1474 char preconfigPin[9] = {0};
1475 printf(" > Input the PreconfigPin (e.g. 12341234) : ");
1476 for(int ret=0; 1!=ret; )
1478 ret = scanf("%8s", preconfigPin);
1479 for( ; 0x20<=getchar(); ); // for removing overflow garbages
1480 // '0x20<=code' is character region
1483 OCProvisionDev_t* motDev = getDevInst(g_mot_enable_list, dev_num);
1484 if(OC_STACK_OK == OCProvisionPreconfigPin(NULL, motDev, preconfigPin, strlen(preconfigPin), provisionCredCB))
1490 OIC_LOG(ERROR, TAG, "OCProvisionPreconfigPin API error");
1494 if(waitCallbackRet()) // input |g_doneCB| flag implicitly
1496 OIC_LOG(ERROR, TAG, "waitCallbackRet callback error");
1503 static int removeSubOwner(void)
1505 // check |g_mot_enable_list| for removing sub-owner
1506 if (!g_mot_enable_list || 1 > g_mot_enable_cnt)
1508 printf(" > Multiple Ownership Transfer Enabled Device List is Empty\n");
1509 printf(" > Please Discover the Multiple Ownership Transfer Enabled Devices, with [13] Menu\n");
1510 return 0; // normal case
1513 // select resource server for removing sub-owner
1517 printf(" > Enter Device Number to remove sub-owner: ");
1518 for (int ret = 0; 1 != ret; )
1520 ret = scanf("%d", &dev_num);
1521 for( ; 0x20 <= getchar(); ); // for removing overflow garbages
1522 // '0x20<=code' is character region
1524 if (0 < dev_num && g_mot_enable_cnt >= dev_num)
1528 printf(" Entered Wrong Number. Please Enter Again\n");
1531 OCProvisionDev_t* motDev = getDevInst(g_mot_enable_list, dev_num);
1532 if (motDev && motDev->doxm && motDev->doxm->subOwners)
1534 OicSecSubOwner_t* subOwner = motDev->doxm->subOwners;
1538 printf(" [%zu] ", ++so_cnt);
1539 printUuid(&subOwner->uuid);
1541 subOwner = subOwner->next;
1547 printf(" > Enter SubOwner Number to be removed : ");
1548 for (int ret = 0; 1 != ret; )
1550 ret = scanf("%d", &so_num);
1551 for( ; 0x20<=getchar(); ); // for removing overflow garbages
1552 // '0x20<=code' is character region
1554 if (0 < so_num && so_cnt >= so_num)
1557 subOwner = motDev->doxm->subOwners;
1560 if(so_num == ++target_num)
1562 if (OC_STACK_OK != OCRemoveSubOwner(NULL, motDev, &subOwner->uuid, deleteDoxmForMOTCB))
1569 if(waitCallbackRet()) // input |g_doneCB| flag implicitly
1571 OIC_LOG(ERROR, TAG, "waitCallbackRet callback error");
1576 subOwner = subOwner->next;
1580 printf(" Entered Wrong Number. Please Enter Again\n");
1585 printf(" SubOwner list is empty.\n");
1591 static int removeAllSubOwner(void)
1593 // check |g_mot_enable_list| for removing sub-owner
1594 if (!g_mot_enable_list || 1 > g_mot_enable_cnt)
1596 printf(" > Multiple Ownership Transfer Enabled Device List is Empty\n");
1597 printf(" > Please Discover the Multiple Ownership Transfer Enabled Devices, with [13] Menu\n");
1598 return 0; // normal case
1601 // select resource server for removing sub-owner
1605 printf(" > Enter Device Number to remove sub-owner: ");
1606 for (int ret = 0; 1 != ret; )
1608 ret = scanf("%d", &dev_num);
1609 for( ; 0x20 <= getchar(); ); // for removing overflow garbages
1610 // '0x20<=code' is character region
1612 if (0 < dev_num && g_mot_enable_cnt >= dev_num)
1616 printf(" Entered Wrong Number. Please Enter Again\n");
1619 OCProvisionDev_t* motDev = getDevInst(g_mot_enable_list, dev_num);
1620 if (motDev && motDev->doxm && motDev->doxm->subOwners)
1622 if (OC_STACK_OK != OCRemoveAllSubOwner(NULL, motDev, deleteDoxmForMOTCB))
1629 if(waitCallbackRet()) // input |g_doneCB| flag implicitly
1631 OIC_LOG(ERROR, TAG, "waitCallbackRet callback error");
1638 printf(" SubOwner list is empty.\n");
1644 #endif //MULTIPLE_OWNER
1646 static int resetDevice(void)
1648 // check |own_list| for removing device
1649 if (!g_own_list || 1 > g_own_cnt)
1651 printf(" > Owned Device List, to Reset Device, is Empty\n");
1652 printf(" > Please Register Unowned Devices first, with [20] Menu\n");
1656 OCProvisionDev_t *dev = NULL;
1660 printf("************************************************************\n");
1661 printf("Reset device candidate list:\n");
1662 g_unown_cnt = printDevList(g_own_list);
1663 if(0 == g_unown_cnt)
1668 printf("Select number device from list\nor: -1 - escape\n");
1671 if (!scanf("%d",&c))
1676 if(0 == c && NULL != dev)
1692 for(int lst_cnt = 1; dev && lst_cnt != c; lst_cnt++, dev = dev->next);
1698 printf(" Resetting Selected Owned Device..\n");
1700 OCStackResult rst = SRPResetDevice(dev, resetDeviceCB);
1701 if (OC_STACK_OK != rst)
1703 OIC_LOG_V(ERROR, TAG, "OCResetDevice API error: %d", rst);
1707 if (waitCallbackRet()) // input |g_doneCB| flag implicitly
1709 OIC_LOG_V(ERROR, TAG, "%s: callback error", __func__);
1713 // display the removed result
1714 printf(" > Reset Selected Owned Device SUCCEEDED\n");
1715 printf(" > Please Discover Owned Devices for the Registered Result, with [10|12] Menu\n");
1720 static int resetSVRDB(void)
1722 printf(" Resetting SVR DB..\n");
1723 OCStackResult rst = OCResetSVRDB();
1724 if (OC_STACK_OK != rst)
1726 OIC_LOG_V(ERROR, TAG, "OCResetSVRDB API error: %d", rst);
1732 static OicSecAcl_t* createAcl(const int dev_num)
1734 if(0>=dev_num || g_own_cnt<dev_num)
1736 OIC_LOG(ERROR, TAG, "createAcl invalid parameters");
1737 return NULL; // not need to 'goto' |ERROR| before allocating |acl|
1740 // allocate memory for |acl| struct
1741 printf(" **** Create ACL for the Selected Device[%d]\n", dev_num);
1742 OicSecAcl_t* acl = (OicSecAcl_t*) OICCalloc(1, sizeof(OicSecAcl_t));
1745 OIC_LOG(ERROR, TAG, "createAcl: OICCalloc error return");
1746 return NULL; // not need to 'goto' |ERROR| before allocating |acl|
1748 OicSecAce_t* ace = (OicSecAce_t*) OICCalloc(1, sizeof(OicSecAce_t));
1751 OIC_LOG(ERROR, TAG, "createAcl: OICCalloc error return");
1752 return NULL; // not need to 'goto' |ERROR| before allocating |acl|
1754 LL_APPEND(acl->aces, ace);
1756 // enter |subject| device number
1760 printf(" > [A] Enter Subject Device Number: ");
1761 for(int ret=0; 1!=ret; )
1763 ret = scanf("%d", &num);
1764 for( ; 0x20<=getchar(); ); // for removing overflow garbages
1765 // '0x20<=code' is character region
1767 if(0<num && g_own_cnt>=num && dev_num!=num)
1771 printf(" Entered Wrong Number. Please Enter Again\n");
1774 OCProvisionDev_t* dev = getDevInst((const OCProvisionDev_t*)g_own_list, num);
1775 if(!dev || !dev->doxm)
1777 OIC_LOG(ERROR, TAG, "createAcl: device instance empty");
1780 memcpy(&ace->subjectuuid, &dev->doxm->deviceID, UUID_LENGTH);
1782 // enter number of |resources| in 'accessed' device
1785 printf(" > [B] Enter Number of Accessed Resources (under 16): ");
1786 // '16' is |ACL_RESRC_MAX_NUM|
1787 for(int ret=0; 1!=ret; )
1789 ret = scanf("%d", &num);
1790 for( ; 0x20<=getchar(); ); // for removing overflow garbages
1791 // '0x20<=code' is character region
1793 if(0<num && ACL_RESRC_MAX_NUM>=num)
1797 printf(" Entered Wrong Number. Please Enter under 16 Again\n");
1798 // '16' is |ACL_RESRC_MAX_NUM|
1801 // enter actually each 'accessed' |resources| name
1802 printf(" Enter Each Accessed Resource Name (each under 128 char)\n");
1803 // '128' is ACL_RESRC_MAX_LEN
1805 char rsrc_in[ACL_RESRC_MAX_LEN+1] = {0}; // '1' for null termination
1806 for(int i = 0; num > i; ++i)
1808 OicSecRsrc_t* rsrc = (OicSecRsrc_t*)OICCalloc(1, sizeof(OicSecRsrc_t));
1811 OIC_LOG(ERROR, TAG, "createAcl: OICCalloc error return");
1815 printf(" Enter Accessed Resource[%d] Name: (e.g. /a/led)", i+1);
1816 for(int ret=0; 1!=ret; )
1818 ret = scanf("%128s", rsrc_in); // '128' is ACL_RESRC_MAX_LEN
1819 for( ; 0x20<=getchar(); ); // for removing overflow garbages
1820 // '0x20<=code' is character region
1822 size_t len = strlen(rsrc_in)+1; // '1' for null termination
1823 rsrc->href = (char*) OICCalloc(len, sizeof(char));
1826 OIC_LOG(ERROR, TAG, "createAcl: OICCalloc error return");
1829 OICStrcpy(rsrc->href, len, rsrc_in);
1834 printf(" Enter Number of resource type for [%s] : ", rsrc->href);
1835 for(int ret=0; 1!=ret; )
1837 ret = scanf("%zu", &arrLen);
1838 for( ; 0x20<=getchar(); ); // for removing overflow garbages
1839 // '0x20<=code' is character region
1841 if(ACL_RESRC_ARRAY_SIZE >= arrLen)
1845 printf(" Entered Wrong Number. Please Enter under %d Again\n", ACL_RESRC_ARRAY_SIZE);
1848 rsrc->typeLen = arrLen;
1849 rsrc->types = (char**)OICCalloc(arrLen, sizeof(char*));
1852 OIC_LOG(ERROR, TAG, "createAcl: OICCalloc error return");
1856 for(size_t i = 0; i < arrLen; i++)
1858 printf(" Enter ResourceType[%zu] Name (e.g. core.led): ", i+1);
1859 for(int ret=0; 1!=ret; )
1861 ret = scanf("%128s", rsrc_in); // '128' is ACL_RESRC_MAX_LEN
1862 for( ; 0x20<=getchar(); ); // for removing overflow garbages
1863 // '0x20<=code' is character region
1865 rsrc->types[i] = OICStrdup(rsrc_in);
1868 OIC_LOG(ERROR, TAG, "createAcl: OICStrdup error return");
1875 printf(" Enter Number of interface for [%s]: ", rsrc->href);
1876 for(int ret=0; 1!=ret; )
1878 ret = scanf("%zu", &arrLen);
1879 for( ; 0x20<=getchar(); ); // for removing overflow garbages
1880 // '0x20<=code' is character region
1882 if(ACL_RESRC_ARRAY_SIZE >= arrLen)
1886 printf(" Entered Wrong Number. Please Enter under %d Again\n", ACL_RESRC_ARRAY_SIZE);
1889 rsrc->interfaceLen = arrLen;
1890 rsrc->interfaces = (char**)OICCalloc(arrLen, sizeof(char*));
1891 if(!rsrc->interfaces)
1893 OIC_LOG(ERROR, TAG, "createAcl: OICCalloc error return");
1897 for(size_t i = 0; i < arrLen; i++)
1899 printf(" Enter Interface[%zu] Name (e.g. oic.if.baseline): ", i+1);
1900 for(int ret=0; 1!=ret; )
1902 ret = scanf("%128s", rsrc_in); // '128' is ACL_RESRC_MAX_LEN
1903 for( ; 0x20<=getchar(); ); // for removing overflow garbages
1904 // '0x20<=code' is character region
1906 rsrc->interfaces[i] = OICStrdup(rsrc_in);
1907 if(!rsrc->interfaces[i])
1909 OIC_LOG(ERROR, TAG, "createAcl: OICStrdup error return");
1914 LL_APPEND(ace->resources, rsrc);
1917 // enter |permission| for this access
1918 printf(" > [C] Enter Permission for This Access\n");
1919 uint16_t pmsn = PERMISSION_FULL_CONTROL; // default full permission
1920 uint16_t pmsn_msk = PERMISSION_CREATE; // default permission mask
1921 for(int i=0; ACL_PEMISN_CNT>i; ++i)
1926 printf(" Enter %s Permission (y/n): ", ACL_PEMISN[i]);
1927 for(int ret=0; 1!=ret; )
1929 ret = scanf("%c", &ans);
1930 for( ; 0x20<=getchar(); ); // for removing overflow garbages
1931 // '0x20<=code' is character region
1933 if('y'==ans || 'Y'==ans || 'n'==ans|| 'N'==ans)
1935 ans &= ~0x20; // for masking lower case, 'y/n'
1938 printf(" Entered Wrong Answer. Please Enter 'y/n' Again\n");
1940 if('N' == ans) // masked lower case, 'n'
1946 ace->permission = pmsn;
1951 OCDeleteACLList(acl); // after here |acl| points nothing
1955 static OicSecAcl_t* createSimpleAcl(const OicUuid_t uuid)
1957 OIC_LOG(DEBUG, TAG, "createSimpleAcl IN");
1959 // allocate memory for |acl| struct
1960 OicSecAcl_t* acl = (OicSecAcl_t*) OICCalloc(1, sizeof(OicSecAcl_t));
1963 OIC_LOG(DEBUG, TAG, "OICCalloc error return");
1964 return NULL; // not need to 'goto' |ERROR| before allocating |acl|
1966 OicSecAce_t* ace = (OicSecAce_t*) OICCalloc(1, sizeof(OicSecAce_t));
1969 OIC_LOG(DEBUG, TAG, "OICCalloc error return");
1970 return NULL; // not need to 'goto' |ERROR| before allocating |acl|
1972 LL_APPEND(acl->aces, ace);
1974 memcpy(&ace->subjectuuid, &uuid, UUID_LENGTH);
1976 OicSecRsrc_t* rsrc = (OicSecRsrc_t*)OICCalloc(1, sizeof(OicSecRsrc_t));
1979 OIC_LOG(DEBUG, TAG, "OICCalloc error return");
1980 OCDeleteACLList(acl);
1985 size_t len = strlen(href)+1; // '1' for null termination
1986 rsrc->href = (char*) OICCalloc(len, sizeof(char));
1989 OIC_LOG(DEBUG, TAG, "OICCalloc error return");
1990 OCDeleteACLList(acl);
1993 OICStrcpy(rsrc->href, len, href);
1996 rsrc->typeLen = arrLen;
1997 rsrc->types = (char**)OICCalloc(arrLen, sizeof(char*));
2000 OIC_LOG(DEBUG, TAG, "OICCalloc error return");
2001 OCDeleteACLList(acl);
2004 rsrc->types[0] = OICStrdup(""); // ignore
2006 rsrc->interfaceLen = 1;
2007 rsrc->interfaces = (char**)OICCalloc(arrLen, sizeof(char*));
2008 if(!rsrc->interfaces)
2010 OIC_LOG(DEBUG, TAG, "OICCalloc error return");
2011 OCDeleteACLList(acl);
2014 rsrc->interfaces[0] = OICStrdup("oic.if.baseline"); // ignore
2016 LL_APPEND(ace->resources, rsrc);
2018 ace->permission = 31; // R/W/U/D
2020 OIC_LOG(DEBUG, TAG, "createSimpleAcl OUT");
2025 static OicSecPdAcl_t* createPdAcl(const int dev_num)
2027 if(0>=dev_num || g_own_cnt<dev_num)
2029 OIC_LOG(ERROR, TAG, "createAcl invalid parameters");
2030 return NULL; // not need to 'goto' |ERROR| before allocating |acl|
2033 // allocate memory for |pdacl| struct
2034 printf(" **** Create PDACL for the Selected Device[%d]\n", dev_num);
2035 OicSecPdAcl_t* pdAcl = (OicSecPdAcl_t*) OICCalloc(1, sizeof(OicSecPdAcl_t));
2038 OIC_LOG(ERROR, TAG, "createAcl: OICCalloc error return");
2039 return NULL; // not need to 'goto' |ERROR| before allocating |acl|
2043 // number of resources
2044 char rsrc_in[][ACL_RESRC_MAX_LEN+1] = {"*", "/rsrc/*"};
2045 pdAcl->resourcesLen = 1;
2048 int num = pdAcl->resourcesLen;
2049 pdAcl->resources = (char**) OICCalloc(num, sizeof(char*));
2050 if(!pdAcl->resources)
2052 OIC_LOG(ERROR, TAG, "createPdAcl: OICCalloc error return");
2055 for(int i=0; num>i; ++i)
2057 size_t len = strlen(rsrc_in[i])+1; // '1' for null termination
2058 char* rsrc = (char*) OICCalloc(len, sizeof(char));
2061 OIC_LOG(ERROR, TAG, "createPdAcl: OICCalloc error return");
2064 OICStrcpy(rsrc, len, rsrc_in[i]);
2065 pdAcl->resources[i] = rsrc; // after here, |rsrc| points nothing
2069 pdAcl->permission = PERMISSION_FULL_CONTROL;
2074 OCDeletePdAclList(pdAcl);
2078 static OCProvisionDev_t* getDevInst(const OCProvisionDev_t* dev_lst, const int dev_num)
2080 if(!dev_lst || 0>=dev_num)
2082 printf(" Device List is Empty..\n");
2086 OCProvisionDev_t* lst = (OCProvisionDev_t*) dev_lst;
2096 return NULL; // in here |lst| is always |NULL|
2099 static int printDevList(const OCProvisionDev_t* dev_lst)
2103 printf(" Device List is Empty..\n\n");
2107 OCProvisionDev_t* lst = (OCProvisionDev_t*) dev_lst;
2111 printf(" [%d] ", ++lst_cnt);
2112 printUuid((const OicUuid_t*) &lst->doxm->deviceID);
2121 static size_t printUuidList(const OCUuidList_t* uid_lst)
2125 printf(" Device List is Empty..\n\n");
2129 OCUuidList_t* lst = (OCUuidList_t*) uid_lst;
2133 printf(" [%zu] ", ++lst_cnt);
2134 printUuid((const OicUuid_t*) &lst->dev);
2143 static int printResultList(const OCProvisionResult_t* rslt_lst, const int rslt_cnt)
2145 if(!rslt_lst || 0>=rslt_cnt)
2147 printf(" Device List is Empty..\n\n");
2152 for( ; rslt_cnt>lst_cnt; ++lst_cnt)
2154 printf(" [%d] ", lst_cnt+1);
2155 printUuid((const OicUuid_t*) &rslt_lst[lst_cnt].deviceId);
2156 printf(" - result: %d\n", rslt_lst[lst_cnt].res);
2163 static void printUuid(const OicUuid_t* uid)
2165 for(int i=0; i<UUID_LENGTH; )
2167 printf("%02X", (*uid).id[i++]);
2168 if(i==4 || i==6 || i==8 || i==10) // canonical format for UUID has '8-4-4-4-12'
2175 static FILE* fopen_prvnMng(const char* path, const char* mode)
2177 (void)path; // unused |path| parameter
2179 // input |g_svr_db_fname| internally by force, not using |path| parameter
2180 // because |OCPersistentStorage::open| is called |OCPersistentStorage| internally
2181 // with its own |SVR_DB_FILE_NAME|
2182 return fopen(SVR_DB_FILE_NAME, mode);
2185 static int peerCertCallback(void *ctx, const mbedtls_x509_crt *cert, int depth)
2189 OIC_LOG_V(DEBUG, TAG, "Depth : %d", depth);
2190 OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
2191 OIC_LOG(DEBUG, TAG, "***** Serial number of certificate is below *****");
2192 OIC_LOG_BUFFER(DEBUG, TAG, cert->serial.p, cert->serial.len);
2193 OIC_LOG(DEBUG, TAG, "***** Serial number of certificate is above *****");
2194 OIC_LOG_V(DEBUG, TAG, "OUT%s", __func__);
2199 static int waitCallbackRet(void)
2201 for(int i=0; !g_doneCB && CALLBACK_TIMEOUT>i; ++i)
2204 if(OC_STACK_OK != OCProcess())
2206 OIC_LOG(ERROR, TAG, "OCStack process error");
2213 OCPDMCleanupForTimeout();
2219 static int selectTwoDiffNum(int* a, int* b, const int max, const char* str)
2221 if(!a || !b || 2>max || !str)
2228 for(int i=0; 2>i; ++i)
2230 int* num = 0==i?a:b;
2233 printf(" > Enter Device[%d] Number, %s: ", i+1, str);
2234 for(int ret=0; 1!=ret; )
2236 ret = scanf("%d", num);
2237 for( ; 0x20<=getchar(); ); // for removing overflow garbages
2238 // '0x20<=code' is character region
2240 if(0<*num && max>=*num)
2244 printf(" Entered Wrong Number. Please Enter Again\n");
2259 static void setDevProtocol(OCProvisionDev_t* lst)
2263 printf(" Device List is Empty..\n\n");
2269 if(2 == secure_protocol)
2271 lst->connType &= ~CT_ADAPTER_IP; //reset IP flag
2272 lst->connType |= CT_ADAPTER_TCP; //set TCP flag
2273 lst->endpoint.adapter = OC_ADAPTER_TCP;
2274 lst->endpoint.port = lst->tcpPort;
2275 lst->securePort = lst->tcpPort;
2281 static void selectSecureProtocol()
2283 printf(" Select protocol\n");
2284 printf(" 1 - DTLS(Default)\n");
2285 printf(" 2 - TLS\n");
2287 for(int ret=0; 1!=ret; )
2289 ret = scanf("%d",&secure_protocol);
2290 for( ; 0x20<=getchar(); ); // for removing overflow garbages
2291 // '0x20<=code' is character region
2294 if(0 >= secure_protocol || 2 < secure_protocol)
2296 secure_protocol = 1;
2299 setDevProtocol(g_own_list);
2300 setDevProtocol(g_unown_list);
2304 static void secureStorageHwEmulation()
2306 printf(" Enable Secure Storage HW Emulation\n");
2308 printf(" Enter Own Certificate File Path[~4095]: ");
2309 char cert_filepath[4096] = {0,};
2310 for(int ret=0; 1!=ret; )
2312 ret = scanf("%255s", cert_filepath);
2313 for( ; 0x20<=getchar(); ); // for removing overflow garbages
2314 // '0x20<=code' is character region
2317 printf(" Enter Private Key File Path[~4095]: ");
2318 char key_filepath[4096] = {0,};
2319 for(int ret=0; 1!=ret; )
2321 ret = scanf("%255s", key_filepath);
2322 for( ; 0x20<=getchar(); ); // for removing overflow garbages
2323 // '0x20<=code' is character region
2326 printf(" Enter Password for Key Password[~31][Press (Enter) to not set]: ");
2327 char pwd[32] = {0,};
2328 for(int i=0; i < 31; i++)
2330 pwd[i] = (char)getchar();
2343 if (0 != SSemulSetCertkeyFilepath(cert_filepath, key_filepath, pwd))
2345 printf(" Fail to set cert/key file path");
2349 if (0 != SetHwPkixCallbacks(HWGetKeyContext,
2351 HWGetOwnCertificateChain,
2354 printf(" Fail to regist HW Pkix Callbacks");
2357 printf(" Success to regist HW Pkix Callbacks");
2360 static void selectVerifMethod()
2363 printf(" Select verification method for ownership transfer\n");
2364 printf(" 0 - No verification\n");
2365 printf(" 1 - Display only\n");
2366 printf(" 2 - Confirm only\n");
2367 printf(" 3 - Both Display and Confirm\n");
2369 for(int ret=0; 1!=ret; )
2371 ret = scanf("%d",&option);
2372 for( ; 0x20<=getchar(); ); // for removing overflow garbages
2373 // '0x20<=code' is character region
2376 if(0 > option || 3 < option)
2378 printf("Invalid option!");
2380 SetVerifyOption((VerifyOptionBitmask_t) option);
2381 printf("Option %d chosen!", option);
2384 static void printMenu(void)
2386 printf("************************************************************\n");
2387 printf("****** OIC Provisioning Client with using C-level API ******\n");
2388 printf("************************************************************\n\n");
2390 printf("** [A] DISCOVER DEVICES ON NETWORK\n");
2391 printf("** 10. Discover All Un/Owned Devices on Network\n");
2392 printf("** 11. Discover Only Unowned Devices on Network\n");
2393 #ifdef MULTIPLE_OWNER
2394 printf("** 12. Discover Only Owned Devices on Network\n");
2395 printf("** 13. Discover Multiple Ownership Transfer Enabled Devices on Network\n\n");
2397 printf("** 12. Discover Only Owned Devices on Network\n\n");
2398 #endif //MULTIPLE_OWNER
2400 printf("** [B] REGISTER/OWN ALL DISCOVERED UNOWNED DEVICES\n");
2401 printf("** 20. Register/Own All Discovered Unowned Devices\n\n");
2403 printf("** [C] PROVISION/LINK PAIRWISE THINGS\n");
2404 printf("** 30. Provision/Link Pairwise Things\n");
2405 printf("** 31. Provision Credentials for Pairwise Things\n");
2406 printf("** 32. Provision the Selected Access Control List(ACL)\n");
2407 printf("** 33. Provision Direct-Pairing Configuration\n");
2408 printf("** 34. Check Linked Status of the Selected Device on PRVN DB\n");
2409 printf("** 35. Save the Selected Access Control List(ACL) into local SVR DB\n\n");
2411 printf("** [D] UNLINK PAIRWISE THINGS\n");
2412 printf("** 40. Unlink Pairwise Things\n\n");
2414 printf("** [E] REMOVE THE SELECTED DEVICE\n");
2415 printf("** 50. Remove the Selected Device\n");
2416 printf("** 51. Remove Device with UUID (UUID input is required)\n");
2417 printf("** 52. Reset the Selected Device\n");
2418 printf("** 53. Reset SVR DB\n\n");
2420 printf("** [F] GET SECURITY RESOURCE FOR DEBUGGING ONLY\n");
2421 printf("** 60. Get the Credential resources of the Selected Device\n");
2422 printf("** 61. Get the ACL resources of the Selected Device\n\n");
2424 #ifdef MULTIPLE_OWNER
2425 printf("** [G] UPDATE THE MULTIPLE OWNERSHIP TRANSFER RELATED VALUE\n");
2426 printf("** 70. Change the Multiple Ownership transfer MODE(update mom)\n");
2427 printf("** 71. Provision Preconfigured PIN\n");
2428 printf("** 72. Change the Multiple Ownership transfer METHOD(update oxmsel)\n");
2429 printf("** 73. Remove Sub-Owner from Resource Server\n");
2430 printf("** 74. Remove All Sub-Owner from Resource Server\n\n");
2431 #endif //MULTIPLE_OWNER
2434 printf("** [H] SELECT SECURE PROTOCOL DTLS/TLS AND OTHERS\n");
2435 printf("** 80. Select secure protocol(default DTLS)\n");
2436 printf("** 81. Select verification method\n");
2437 printf("** 82. Enable secure storage hw emulation\n\n");
2439 printf("** [H] SELECT VERIFICATION OPTION\n");
2440 printf("** 81. Select verification method\n\n");
2442 printf("** [I] EXIT PROVISIONING CLIENT\n");
2444 printf("** 99. Exit Provisionong Client\n\n");
2446 printf("************************************************************\n\n");
2449 #if 0 // Code for enabling path configuration for PDB and SVR DBf
2450 static void printUsage(void)
2453 printf("OIC Provisioning Client with using C-level API\n");
2454 printf("Usage: provisioningclient [option]...\n");
2456 printf(" -h print help for this provisioning client\n");
2457 printf(" -p=[prvn_db_file_path/name] input PRVN DB file path and name\n");
2458 printf(" if not exists, will load default DB file\n");
2459 printf(" (default: |oic_prvn_mng.db| on working dir)\n");
2460 printf(" (ex. -p=oic_prvn_mng.db)\n");
2461 printf(" -s=[svr_db_file_path/name] input SVR DB file path and name\n");
2462 printf(" if not exists, will load default DB file\n");
2463 printf(" (default: |oic_svr_db_client.json| on working dir)\n");
2464 printf(" (ex. -s=oic_svr_db_client.json)\n");
2470 * Sample implementation of Export key block and master secret
2472 * @param[in] p_expkey Context for the callback
2473 * @aram[in] ms Pointer to master secret (fixed length: 48 bytes)
2474 * @param[in] kb Pointer to key block, see RFC 5246 section 6.3
2475 * (variable length: 2 * maclen + 2 * keylen + 2 * ivlen).
2476 * @param[in] maclen MAC length
2477 * @param[in] keylen Key length
2478 * @param[in] ivlen IV length
2480 static void SslExportKeysCallback(const unsigned char* masterSecret,
2481 const unsigned char* keyBlock,
2482 size_t macLen, size_t keyLen, size_t ivLen)
2484 OIC_LOG_V(INFO, TAG, "In %s ", __func__);
2486 OIC_LOG(INFO, TAG, "[MASTER SECRET] : ");
2487 OIC_LOG_BUFFER(INFO, TAG, masterSecret, 48);
2489 OIC_LOG(INFO, TAG, "[KEY BLOCK] : ");
2490 OIC_LOG_BUFFER(INFO, TAG, keyBlock, (2 * macLen) + (2 * keyLen) + (2 * ivLen));
2492 OIC_LOG_V(INFO, TAG, "Mac Length = %zu, Key Length = %zu, IV Length = %zu",
2493 macLen, keyLen, ivLen);
2495 OIC_LOG_V(INFO, TAG, "Out %s ", __func__);
2498 // main function for provisioning client using C-level provisioning API
2501 // initialize provisioning client
2502 if(initProvisionClient())
2504 OIC_LOG(ERROR, TAG, "ProvisionClient init error");
2509 CASetSslExportKeysCallback(SslExportKeysCallback, CA_SSL_EKCB_DTLS, CA_SSL_EKCB_CLIENT))
2511 OIC_LOG(ERROR, TAG, "Failed to register the (D)TLS export Key Callback!");
2515 // Client can choose a allowed/not-allowed OxM method.
2516 if(OC_STACK_OK != OCSetOxmAllowStatus(OIC_DECENTRALIZED_PUBLIC_KEY, false))
2518 OIC_LOG(WARNING, TAG, "Failed to disable OIC_DECENTRALIZED_PUBLIC_KEY OxM");
2521 // set callbacks for verification options
2522 SetDisplayNumCB(NULL, displayNumCB);
2523 SetUserConfirmCB(NULL, confirmNumCB);
2524 SetInputStateCB(NULL, notifyInputStateCB);
2526 // set callback for checking peer certificate information
2527 OCSetPeerCertCallback(NULL, peerCertCallback);
2529 #ifdef MULTIPLE_OWNER
2530 SetPreconfigPin("12341234", 8);
2531 #endif //MULTIPLE_OWNER
2533 // main loop for provisioning manager
2539 printf(">> Enter Menu Number: ");
2540 for(int ret=0; 1!=ret; )
2542 ret = scanf("%d", &mn_num);
2543 for( ; 0x20<=getchar(); ); // for removing overflow garbages
2544 // '0x20<=code' is character region
2549 case _10_DISCOV_ALL_DEVS_:
2550 if(discoverAllDevices())
2552 OIC_LOG(ERROR, TAG, "_10_DISCOV_ALL_DEVS_: error");
2555 case _11_DISCOV_UNOWN_DEVS_:
2556 if(discoverUnownedDevices())
2558 OIC_LOG(ERROR, TAG, "_11_DISCOV_UNOWN_DEVS_: error");
2561 case _12_DISCOV_OWN_DEVS_:
2562 if(discoverOwnedDevices())
2564 OIC_LOG(ERROR, TAG, "_12_DISCOV_OWN_DEVS_: error");
2567 #ifdef MULTIPLE_OWNER
2568 case _13_MOT_DISCOV_DEV_:
2569 if(discoverMOTEnabledDevices())
2571 OIC_LOG(ERROR, TAG, "_13_MOT_DISCOV_DEV_: error");
2574 #endif //MULTIPLE_OWNER
2575 case _20_REGIST_DEVS_:
2576 if(registerDevices())
2578 OIC_LOG(ERROR, TAG, "_20_REGIST_DEVS_: error");
2581 case _30_PROVIS_PAIR_DEVS_:
2582 if(provisionPairwise())
2584 OIC_LOG(ERROR, TAG, "_30_PROVIS_PAIR_DEVS_: error");
2587 case _31_PROVIS_CRED_:
2590 OIC_LOG(ERROR, TAG, "_31_PROVIS_CRED_: error");
2593 case _32_PROVIS_ACL_:
2596 OIC_LOG(ERROR, TAG, "_32_PROVIS_ACL_: error");
2599 case _33_PROVIS_DP_:
2600 if(provisionDirectPairing())
2602 OIC_LOG(ERROR, TAG, "_33_PROVIS_DP_: error");
2605 case _34_CHECK_LINK_STATUS_:
2606 if(checkLinkedStatus())
2608 OIC_LOG(ERROR, TAG, "_34_CHECK_LINK_STATUS_: error");
2614 OIC_LOG(ERROR, TAG, "_35_SAVE_ACL_: error");
2617 case _40_UNLINK_PAIR_DEVS_:
2618 if(unlinkPairwise())
2620 OIC_LOG(ERROR, TAG, "_40_UNLINK_PAIR_DEVS_: error");
2623 case _50_REMOVE_SELEC_DEV_:
2626 OIC_LOG(ERROR, TAG, "_50_REMOVE_SELEC_DEV_: error");
2629 case _51_REMOVE_DEV_WITH_UUID_:
2630 if(removeDeviceWithUuid())
2632 OIC_LOG(ERROR, TAG, "_51_REMOVE_DEV_WITH_UUID_: error");
2635 case _52_RESET_SELEC_DEV_:
2638 OIC_LOG(ERROR, TAG, "_52_RESET_SELEC_DEV_: error");
2641 case _53_RESET_SVR_DB_:
2644 OIC_LOG(ERROR, TAG, "_53_RESET_SVR_DB_: error");
2650 OIC_LOG(ERROR, TAG, "_60_GET_CRED_: error");
2656 OIC_LOG(ERROR, TAG, "_61_GET_ACL_: error");
2659 #ifdef MULTIPLE_OWNER
2660 case _70_MOT_CHANGE_MOM_:
2661 if(changeMultipleOwnershipTrnasferMode())
2663 OIC_LOG(ERROR, TAG, "_70_MOT_CHANGE_MOM_: error");
2666 case _71_MOT_PROV_PRECONF_PIN_:
2667 if(provisionPreconfigPIN())
2669 OIC_LOG(ERROR, TAG, "_71_MOT_PROV_PRECONF_PIN_: error");
2672 case _72_MOT_OXM_SEL_:
2673 if(selectMultipleOwnershipTrnasferMethod())
2675 OIC_LOG(ERROR, TAG, "_72_MOT_OXM_SEL_: error");
2678 case _73_MOT_REMOVE_SUBOWNER_:
2679 if(removeSubOwner())
2681 OIC_LOG(ERROR, TAG, "_73_MOT_REMOVE_SUBOWNER_ : error");
2684 case _74_MOT_REMOVE_ALL_SUBOWNER_:
2685 if(removeAllSubOwner())
2687 OIC_LOG(ERROR, TAG, "_74_MOT_REMOVE_ALL_SUBOWNER_ : error");
2690 #endif //MULTIPLE_OWNER
2692 case _80_SELECT_PROTOCOL_:
2693 selectSecureProtocol();
2696 case _81_SELECT_VERIF_METHOD_:
2697 selectVerifMethod();
2699 case _82_SECURE_STORAGE_HW_EMULATION_:
2700 secureStorageHwEmulation();
2702 case _99_EXIT_PRVN_CLT_:
2705 printf(">> Entered Wrong Number. Please Enter Again\n\n");
2711 if(OC_STACK_OK != OCStop())
2713 OIC_LOG(ERROR, TAG, "OCStack stop error");
2715 OCDeleteDiscoveredDevices(g_own_list); // after here |g_own_list| points nothing
2716 OCDeleteDiscoveredDevices(g_unown_list); // after here |g_unown_list| points nothing
2717 #ifdef MULTIPLE_OWNER
2718 OCDeleteDiscoveredDevices(g_mot_enable_list); // after here |g_motdev_list| points nothing
2719 #endif //MULTIPLE_OWNER
2723 OICFree(g_svr_fname); // after here |g_svr_fname| points nothing
2727 OICFree(g_prvn_fname); // after here |g_prvn_fname| points nothing
2729 return 0; // always return normal case
2734 #endif //__cplusplus