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 OicSecOxm_t selectOTMcb(const OicSecOxm_t* otmList, const uint32_t len)
1308 return otmList[len-1];
1311 #ifdef MULTIPLE_OWNER
1312 static int changeMultipleOwnershipTrnasferMode(void)
1314 // check |own_list| for removing device
1315 if(!g_own_list || 1>g_own_cnt)
1317 printf(" > Owned Device List is Empty\n");
1318 printf(" > Please Discover the Owned Devices, with [12] Menu\n");
1319 return 0; // normal case
1322 // select device for removing it
1326 printf(" > Enter Device Number, for MOT Device: ");
1327 for(int ret=0; 1!=ret; )
1329 ret = scanf("%d", &dev_num);
1330 for( ; 0x20<=getchar(); ); // for removing overflow garbages
1331 // '0x20<=code' is character region
1333 if(0<dev_num && g_own_cnt>=dev_num)
1337 printf(" Entered Wrong Number. Please Enter Again\n");
1343 printf(" 0. Disable Multuple Ownership Transfer\n");
1344 printf(" 1. Enable Multuple Ownership Transfer\n");
1345 printf(" 2. (Not Supported yet) Timely Enable Multuple Ownership Transfer\n");
1346 printf(" > Enter Mode of Multuple Ownership Transfer : ");
1347 for(int ret=0; 1!=ret; )
1349 ret = scanf("%d", &mom);
1350 for( ; 0x20<=getchar(); ); // for removing overflow garbages
1351 // '0x20<=code' is character region
1353 if(0 <= dev_num && OIC_NUMBER_OF_MOM_TYPE > dev_num)
1357 printf(" Entered Wrong Number. Please Enter Again\n");
1360 OCProvisionDev_t* motDev = getDevInst(g_own_list, dev_num);
1361 if(OC_STACK_OK == OCChangeMOTMode(NULL, motDev, (OicSecMomType_t)dev_num, updateDoxmForMOTCB))
1367 OIC_LOG(ERROR, TAG, "OCChangeMOTMode API error");
1371 if(waitCallbackRet()) // input |g_doneCB| flag implicitly
1373 OIC_LOG(ERROR, TAG, "waitCallbackRet callback error");
1380 static int selectMultipleOwnershipTrnasferMethod(void)
1382 // check |own_list| for removing device
1383 if(!g_mot_enable_list || 1>g_mot_enable_cnt)
1385 printf(" > Multiple Ownership Transfer Enabled Device List is Empty\n");
1386 printf(" > Please Discover the Multiple Ownership Transfer Enabled Devices, with [13] Menu\n");
1387 return 0; // normal case
1390 // select device for removing it
1394 printf(" > Enter Device Number, for MOT Device: ");
1395 for(int ret=0; 1!=ret; )
1397 ret = scanf("%d", &dev_num);
1398 for( ; 0x20<=getchar(); ); // for removing overflow garbages
1399 // '0x20<=code' is character region
1401 if(0<dev_num && g_mot_enable_cnt>=dev_num)
1405 printf(" Entered Wrong Number. Please Enter Again\n");
1408 const int preconfOxm = 4;
1412 printf(" %d. (Not Supported)\n", OIC_JUST_WORKS);
1413 printf(" %d. Random PIN OxM\n", OIC_RANDOM_DEVICE_PIN);
1414 printf(" %d. (Not Supported)\n", OIC_MANUFACTURER_CERTIFICATE);
1415 printf(" %d. (Not Supported)\n", OIC_DECENTRALIZED_PUBLIC_KEY);
1416 printf(" %d. Pre-Configured PIN OxM\n", OIC_PRECONFIG_PIN);
1417 printf(" > Enter Number of OxM for Multiple Ownership Transfer : ");
1418 for(int ret=0; 1!=ret; )
1420 ret = scanf("%d", &oxm);
1421 for( ; 0x20<=getchar(); ); // for removing overflow garbages
1422 // '0x20<=code' is character region
1424 if(OIC_PRECONFIG_PIN == oxm || OIC_RANDOM_DEVICE_PIN == oxm)
1428 printf(" Entered Wrong Number. Please Enter Again\n");
1431 OCProvisionDev_t* motDev = getDevInst(g_mot_enable_list, dev_num);
1432 if(OC_STACK_OK == OCSelectMOTMethod(NULL, motDev, (OicSecOxm_t)oxm, updateDoxmForMOTCB))
1438 OIC_LOG(ERROR, TAG, "OCSelectMOTMethod API error");
1442 if(waitCallbackRet()) // input |g_doneCB| flag implicitly
1444 OIC_LOG(ERROR, TAG, "waitCallbackRet callback error");
1451 static int provisionPreconfigPIN()
1453 // check |own_list| for removing device
1454 if(!g_mot_enable_list || 1>g_mot_enable_cnt)
1456 printf(" > Multiple Ownership Transfer Enabled Device List is Empty\n");
1457 printf(" > Please Discover the Multiple Ownership Transfer Enabled Devices, with [13] Menu\n");
1458 return 0; // normal case
1461 // select device for removing it
1465 printf(" > Enter Device Number, for MOT Device: ");
1466 for(int ret=0; 1!=ret; )
1468 ret = scanf("%d", &dev_num);
1469 for( ; 0x20<=getchar(); ); // for removing overflow garbages
1470 // '0x20<=code' is character region
1472 if(0<dev_num && g_mot_enable_cnt>=dev_num)
1476 printf(" Entered Wrong Number. Please Enter Again\n");
1479 char preconfigPin[9] = {0};
1480 printf(" > Input the PreconfigPin (e.g. 12341234) : ");
1481 for(int ret=0; 1!=ret; )
1483 ret = scanf("%8s", preconfigPin);
1484 for( ; 0x20<=getchar(); ); // for removing overflow garbages
1485 // '0x20<=code' is character region
1488 OCProvisionDev_t* motDev = getDevInst(g_mot_enable_list, dev_num);
1489 if(OC_STACK_OK == OCProvisionPreconfigPin(NULL, motDev, preconfigPin, strlen(preconfigPin), provisionCredCB))
1495 OIC_LOG(ERROR, TAG, "OCProvisionPreconfigPin API error");
1499 if(waitCallbackRet()) // input |g_doneCB| flag implicitly
1501 OIC_LOG(ERROR, TAG, "waitCallbackRet callback error");
1508 static int removeSubOwner(void)
1510 // check |g_mot_enable_list| for removing sub-owner
1511 if (!g_mot_enable_list || 1 > g_mot_enable_cnt)
1513 printf(" > Multiple Ownership Transfer Enabled Device List is Empty\n");
1514 printf(" > Please Discover the Multiple Ownership Transfer Enabled Devices, with [13] Menu\n");
1515 return 0; // normal case
1518 // select resource server for removing sub-owner
1522 printf(" > Enter Device Number to remove sub-owner: ");
1523 for (int ret = 0; 1 != ret; )
1525 ret = scanf("%d", &dev_num);
1526 for( ; 0x20 <= getchar(); ); // for removing overflow garbages
1527 // '0x20<=code' is character region
1529 if (0 < dev_num && g_mot_enable_cnt >= dev_num)
1533 printf(" Entered Wrong Number. Please Enter Again\n");
1536 OCProvisionDev_t* motDev = getDevInst(g_mot_enable_list, dev_num);
1537 if (motDev && motDev->doxm && motDev->doxm->subOwners)
1539 OicSecSubOwner_t* subOwner = motDev->doxm->subOwners;
1543 printf(" [%zu] ", ++so_cnt);
1544 printUuid(&subOwner->uuid);
1546 subOwner = subOwner->next;
1552 printf(" > Enter SubOwner Number to be removed : ");
1553 for (int ret = 0; 1 != ret; )
1555 ret = scanf("%d", &so_num);
1556 for( ; 0x20<=getchar(); ); // for removing overflow garbages
1557 // '0x20<=code' is character region
1559 if (0 < so_num && so_cnt >= so_num)
1562 subOwner = motDev->doxm->subOwners;
1565 if(so_num == ++target_num)
1567 if (OC_STACK_OK != OCRemoveSubOwner(NULL, motDev, &subOwner->uuid, deleteDoxmForMOTCB))
1574 if(waitCallbackRet()) // input |g_doneCB| flag implicitly
1576 OIC_LOG(ERROR, TAG, "waitCallbackRet callback error");
1581 subOwner = subOwner->next;
1585 printf(" Entered Wrong Number. Please Enter Again\n");
1590 printf(" SubOwner list is empty.\n");
1596 static int removeAllSubOwner(void)
1598 // check |g_mot_enable_list| for removing sub-owner
1599 if (!g_mot_enable_list || 1 > g_mot_enable_cnt)
1601 printf(" > Multiple Ownership Transfer Enabled Device List is Empty\n");
1602 printf(" > Please Discover the Multiple Ownership Transfer Enabled Devices, with [13] Menu\n");
1603 return 0; // normal case
1606 // select resource server for removing sub-owner
1610 printf(" > Enter Device Number to remove sub-owner: ");
1611 for (int ret = 0; 1 != ret; )
1613 ret = scanf("%d", &dev_num);
1614 for( ; 0x20 <= getchar(); ); // for removing overflow garbages
1615 // '0x20<=code' is character region
1617 if (0 < dev_num && g_mot_enable_cnt >= dev_num)
1621 printf(" Entered Wrong Number. Please Enter Again\n");
1624 OCProvisionDev_t* motDev = getDevInst(g_mot_enable_list, dev_num);
1625 if (motDev && motDev->doxm && motDev->doxm->subOwners)
1627 if (OC_STACK_OK != OCRemoveAllSubOwner(NULL, motDev, deleteDoxmForMOTCB))
1634 if(waitCallbackRet()) // input |g_doneCB| flag implicitly
1636 OIC_LOG(ERROR, TAG, "waitCallbackRet callback error");
1643 printf(" SubOwner list is empty.\n");
1649 #endif //MULTIPLE_OWNER
1651 static int resetDevice(void)
1653 // check |own_list| for removing device
1654 if (!g_own_list || 1 > g_own_cnt)
1656 printf(" > Owned Device List, to Reset Device, is Empty\n");
1657 printf(" > Please Register Unowned Devices first, with [20] Menu\n");
1661 OCProvisionDev_t *dev = NULL;
1665 printf("************************************************************\n");
1666 printf("Reset device candidate list:\n");
1667 g_unown_cnt = printDevList(g_own_list);
1668 if(0 == g_unown_cnt)
1673 printf("Select number device from list\nor: -1 - escape\n");
1676 if (!scanf("%d",&c))
1681 if(0 == c && NULL != dev)
1697 for(int lst_cnt = 1; dev && lst_cnt != c; lst_cnt++, dev = dev->next);
1703 printf(" Resetting Selected Owned Device..\n");
1705 OCStackResult rst = SRPResetDevice(dev, resetDeviceCB);
1706 if (OC_STACK_OK != rst)
1708 OIC_LOG_V(ERROR, TAG, "OCResetDevice API error: %d", rst);
1712 if (waitCallbackRet()) // input |g_doneCB| flag implicitly
1714 OIC_LOG_V(ERROR, TAG, "%s: callback error", __func__);
1718 // display the removed result
1719 printf(" > Reset Selected Owned Device SUCCEEDED\n");
1720 printf(" > Please Discover Owned Devices for the Registered Result, with [10|12] Menu\n");
1725 static int resetSVRDB(void)
1727 printf(" Resetting SVR DB..\n");
1728 OCStackResult rst = OCResetSVRDB();
1729 if (OC_STACK_OK != rst)
1731 OIC_LOG_V(ERROR, TAG, "OCResetSVRDB API error: %d", rst);
1737 static OicSecAcl_t* createAcl(const int dev_num)
1739 if(0>=dev_num || g_own_cnt<dev_num)
1741 OIC_LOG(ERROR, TAG, "createAcl invalid parameters");
1742 return NULL; // not need to 'goto' |ERROR| before allocating |acl|
1745 // allocate memory for |acl| struct
1746 printf(" **** Create ACL for the Selected Device[%d]\n", dev_num);
1747 OicSecAcl_t* acl = (OicSecAcl_t*) OICCalloc(1, sizeof(OicSecAcl_t));
1750 OIC_LOG(ERROR, TAG, "createAcl: OICCalloc error return");
1751 return NULL; // not need to 'goto' |ERROR| before allocating |acl|
1753 OicSecAce_t* ace = (OicSecAce_t*) OICCalloc(1, sizeof(OicSecAce_t));
1756 OIC_LOG(ERROR, TAG, "createAcl: OICCalloc error return");
1757 return NULL; // not need to 'goto' |ERROR| before allocating |acl|
1759 LL_APPEND(acl->aces, ace);
1761 // enter |subject| device number
1765 printf(" > [A] Enter Subject Device Number: ");
1766 for(int ret=0; 1!=ret; )
1768 ret = scanf("%d", &num);
1769 for( ; 0x20<=getchar(); ); // for removing overflow garbages
1770 // '0x20<=code' is character region
1772 if(0<num && g_own_cnt>=num && dev_num!=num)
1776 printf(" Entered Wrong Number. Please Enter Again\n");
1779 OCProvisionDev_t* dev = getDevInst((const OCProvisionDev_t*)g_own_list, num);
1780 if(!dev || !dev->doxm)
1782 OIC_LOG(ERROR, TAG, "createAcl: device instance empty");
1785 memcpy(&ace->subjectuuid, &dev->doxm->deviceID, UUID_LENGTH);
1787 // enter number of |resources| in 'accessed' device
1790 printf(" > [B] Enter Number of Accessed Resources (under 16): ");
1791 // '16' is |ACL_RESRC_MAX_NUM|
1792 for(int ret=0; 1!=ret; )
1794 ret = scanf("%d", &num);
1795 for( ; 0x20<=getchar(); ); // for removing overflow garbages
1796 // '0x20<=code' is character region
1798 if(0<num && ACL_RESRC_MAX_NUM>=num)
1802 printf(" Entered Wrong Number. Please Enter under 16 Again\n");
1803 // '16' is |ACL_RESRC_MAX_NUM|
1806 // enter actually each 'accessed' |resources| name
1807 printf(" Enter Each Accessed Resource Name (each under 128 char)\n");
1808 // '128' is ACL_RESRC_MAX_LEN
1810 char rsrc_in[ACL_RESRC_MAX_LEN+1] = {0}; // '1' for null termination
1811 for(int i = 0; num > i; ++i)
1813 OicSecRsrc_t* rsrc = (OicSecRsrc_t*)OICCalloc(1, sizeof(OicSecRsrc_t));
1816 OIC_LOG(ERROR, TAG, "createAcl: OICCalloc error return");
1820 printf(" Enter Accessed Resource[%d] Name: (e.g. /a/led)", i+1);
1821 for(int ret=0; 1!=ret; )
1823 ret = scanf("%128s", rsrc_in); // '128' is ACL_RESRC_MAX_LEN
1824 for( ; 0x20<=getchar(); ); // for removing overflow garbages
1825 // '0x20<=code' is character region
1827 size_t len = strlen(rsrc_in)+1; // '1' for null termination
1828 rsrc->href = (char*) OICCalloc(len, sizeof(char));
1831 OIC_LOG(ERROR, TAG, "createAcl: OICCalloc error return");
1834 OICStrcpy(rsrc->href, len, rsrc_in);
1839 printf(" Enter Number of resource type for [%s] : ", rsrc->href);
1840 for(int ret=0; 1!=ret; )
1842 ret = scanf("%zu", &arrLen);
1843 for( ; 0x20<=getchar(); ); // for removing overflow garbages
1844 // '0x20<=code' is character region
1846 if(ACL_RESRC_ARRAY_SIZE >= arrLen)
1850 printf(" Entered Wrong Number. Please Enter under %d Again\n", ACL_RESRC_ARRAY_SIZE);
1853 rsrc->typeLen = arrLen;
1854 rsrc->types = (char**)OICCalloc(arrLen, sizeof(char*));
1857 OIC_LOG(ERROR, TAG, "createAcl: OICCalloc error return");
1861 for(size_t i = 0; i < arrLen; i++)
1863 printf(" Enter ResourceType[%zu] Name (e.g. core.led): ", i+1);
1864 for(int ret=0; 1!=ret; )
1866 ret = scanf("%128s", rsrc_in); // '128' is ACL_RESRC_MAX_LEN
1867 for( ; 0x20<=getchar(); ); // for removing overflow garbages
1868 // '0x20<=code' is character region
1870 rsrc->types[i] = OICStrdup(rsrc_in);
1873 OIC_LOG(ERROR, TAG, "createAcl: OICStrdup error return");
1880 printf(" Enter Number of interface for [%s]: ", rsrc->href);
1881 for(int ret=0; 1!=ret; )
1883 ret = scanf("%zu", &arrLen);
1884 for( ; 0x20<=getchar(); ); // for removing overflow garbages
1885 // '0x20<=code' is character region
1887 if(ACL_RESRC_ARRAY_SIZE >= arrLen)
1891 printf(" Entered Wrong Number. Please Enter under %d Again\n", ACL_RESRC_ARRAY_SIZE);
1894 rsrc->interfaceLen = arrLen;
1895 rsrc->interfaces = (char**)OICCalloc(arrLen, sizeof(char*));
1896 if(!rsrc->interfaces)
1898 OIC_LOG(ERROR, TAG, "createAcl: OICCalloc error return");
1902 for(size_t i = 0; i < arrLen; i++)
1904 printf(" Enter Interface[%zu] Name (e.g. oic.if.baseline): ", i+1);
1905 for(int ret=0; 1!=ret; )
1907 ret = scanf("%128s", rsrc_in); // '128' is ACL_RESRC_MAX_LEN
1908 for( ; 0x20<=getchar(); ); // for removing overflow garbages
1909 // '0x20<=code' is character region
1911 rsrc->interfaces[i] = OICStrdup(rsrc_in);
1912 if(!rsrc->interfaces[i])
1914 OIC_LOG(ERROR, TAG, "createAcl: OICStrdup error return");
1919 LL_APPEND(ace->resources, rsrc);
1922 // enter |permission| for this access
1923 printf(" > [C] Enter Permission for This Access\n");
1924 uint16_t pmsn = PERMISSION_FULL_CONTROL; // default full permission
1925 uint16_t pmsn_msk = PERMISSION_CREATE; // default permission mask
1926 for(int i=0; ACL_PEMISN_CNT>i; ++i)
1931 printf(" Enter %s Permission (y/n): ", ACL_PEMISN[i]);
1932 for(int ret=0; 1!=ret; )
1934 ret = scanf("%c", &ans);
1935 for( ; 0x20<=getchar(); ); // for removing overflow garbages
1936 // '0x20<=code' is character region
1938 if('y'==ans || 'Y'==ans || 'n'==ans|| 'N'==ans)
1940 ans &= ~0x20; // for masking lower case, 'y/n'
1943 printf(" Entered Wrong Answer. Please Enter 'y/n' Again\n");
1945 if('N' == ans) // masked lower case, 'n'
1951 ace->permission = pmsn;
1956 OCDeleteACLList(acl); // after here |acl| points nothing
1960 static OicSecAcl_t* createSimpleAcl(const OicUuid_t uuid)
1962 OIC_LOG(DEBUG, TAG, "createSimpleAcl IN");
1964 // allocate memory for |acl| struct
1965 OicSecAcl_t* acl = (OicSecAcl_t*) OICCalloc(1, sizeof(OicSecAcl_t));
1968 OIC_LOG(DEBUG, TAG, "OICCalloc error return");
1969 return NULL; // not need to 'goto' |ERROR| before allocating |acl|
1971 OicSecAce_t* ace = (OicSecAce_t*) OICCalloc(1, sizeof(OicSecAce_t));
1974 OIC_LOG(DEBUG, TAG, "OICCalloc error return");
1975 return NULL; // not need to 'goto' |ERROR| before allocating |acl|
1977 LL_APPEND(acl->aces, ace);
1979 memcpy(&ace->subjectuuid, &uuid, UUID_LENGTH);
1981 OicSecRsrc_t* rsrc = (OicSecRsrc_t*)OICCalloc(1, sizeof(OicSecRsrc_t));
1984 OIC_LOG(DEBUG, TAG, "OICCalloc error return");
1985 OCDeleteACLList(acl);
1990 size_t len = strlen(href)+1; // '1' for null termination
1991 rsrc->href = (char*) OICCalloc(len, sizeof(char));
1994 OIC_LOG(DEBUG, TAG, "OICCalloc error return");
1995 OCDeleteACLList(acl);
1998 OICStrcpy(rsrc->href, len, href);
2001 rsrc->typeLen = arrLen;
2002 rsrc->types = (char**)OICCalloc(arrLen, sizeof(char*));
2005 OIC_LOG(DEBUG, TAG, "OICCalloc error return");
2006 OCDeleteACLList(acl);
2009 rsrc->types[0] = OICStrdup(""); // ignore
2011 rsrc->interfaceLen = 1;
2012 rsrc->interfaces = (char**)OICCalloc(arrLen, sizeof(char*));
2013 if(!rsrc->interfaces)
2015 OIC_LOG(DEBUG, TAG, "OICCalloc error return");
2016 OCDeleteACLList(acl);
2019 rsrc->interfaces[0] = OICStrdup("oic.if.baseline"); // ignore
2021 LL_APPEND(ace->resources, rsrc);
2023 ace->permission = 31; // R/W/U/D
2025 OIC_LOG(DEBUG, TAG, "createSimpleAcl OUT");
2030 static OicSecPdAcl_t* createPdAcl(const int dev_num)
2032 if(0>=dev_num || g_own_cnt<dev_num)
2034 OIC_LOG(ERROR, TAG, "createAcl invalid parameters");
2035 return NULL; // not need to 'goto' |ERROR| before allocating |acl|
2038 // allocate memory for |pdacl| struct
2039 printf(" **** Create PDACL for the Selected Device[%d]\n", dev_num);
2040 OicSecPdAcl_t* pdAcl = (OicSecPdAcl_t*) OICCalloc(1, sizeof(OicSecPdAcl_t));
2043 OIC_LOG(ERROR, TAG, "createAcl: OICCalloc error return");
2044 return NULL; // not need to 'goto' |ERROR| before allocating |acl|
2048 // number of resources
2049 char rsrc_in[][ACL_RESRC_MAX_LEN+1] = {"*", "/rsrc/*"};
2050 pdAcl->resourcesLen = 1;
2053 int num = pdAcl->resourcesLen;
2054 pdAcl->resources = (char**) OICCalloc(num, sizeof(char*));
2055 if(!pdAcl->resources)
2057 OIC_LOG(ERROR, TAG, "createPdAcl: OICCalloc error return");
2060 for(int i=0; num>i; ++i)
2062 size_t len = strlen(rsrc_in[i])+1; // '1' for null termination
2063 char* rsrc = (char*) OICCalloc(len, sizeof(char));
2066 OIC_LOG(ERROR, TAG, "createPdAcl: OICCalloc error return");
2069 OICStrcpy(rsrc, len, rsrc_in[i]);
2070 pdAcl->resources[i] = rsrc; // after here, |rsrc| points nothing
2074 pdAcl->permission = PERMISSION_FULL_CONTROL;
2079 OCDeletePdAclList(pdAcl);
2083 static OCProvisionDev_t* getDevInst(const OCProvisionDev_t* dev_lst, const int dev_num)
2085 if(!dev_lst || 0>=dev_num)
2087 printf(" Device List is Empty..\n");
2091 OCProvisionDev_t* lst = (OCProvisionDev_t*) dev_lst;
2101 return NULL; // in here |lst| is always |NULL|
2104 static int printDevList(const OCProvisionDev_t* dev_lst)
2108 printf(" Device List is Empty..\n\n");
2112 OCProvisionDev_t* lst = (OCProvisionDev_t*) dev_lst;
2116 printf(" [%d] ", ++lst_cnt);
2117 printUuid((const OicUuid_t*) &lst->doxm->deviceID);
2126 static size_t printUuidList(const OCUuidList_t* uid_lst)
2130 printf(" Device List is Empty..\n\n");
2134 OCUuidList_t* lst = (OCUuidList_t*) uid_lst;
2138 printf(" [%zu] ", ++lst_cnt);
2139 printUuid((const OicUuid_t*) &lst->dev);
2148 static int printResultList(const OCProvisionResult_t* rslt_lst, const int rslt_cnt)
2150 if(!rslt_lst || 0>=rslt_cnt)
2152 printf(" Device List is Empty..\n\n");
2157 for( ; rslt_cnt>lst_cnt; ++lst_cnt)
2159 printf(" [%d] ", lst_cnt+1);
2160 printUuid((const OicUuid_t*) &rslt_lst[lst_cnt].deviceId);
2161 printf(" - result: %d\n", rslt_lst[lst_cnt].res);
2168 static void printUuid(const OicUuid_t* uid)
2170 for(int i=0; i<UUID_LENGTH; )
2172 printf("%02X", (*uid).id[i++]);
2173 if(i==4 || i==6 || i==8 || i==10) // canonical format for UUID has '8-4-4-4-12'
2180 static FILE* fopen_prvnMng(const char* path, const char* mode)
2182 (void)path; // unused |path| parameter
2184 // input |g_svr_db_fname| internally by force, not using |path| parameter
2185 // because |OCPersistentStorage::open| is called |OCPersistentStorage| internally
2186 // with its own |SVR_DB_FILE_NAME|
2187 return fopen(SVR_DB_FILE_NAME, mode);
2190 static int peerCertCallback(void *ctx, const mbedtls_x509_crt *cert, int depth)
2194 OIC_LOG_V(DEBUG, TAG, "Depth : %d", depth);
2195 OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
2196 OIC_LOG(DEBUG, TAG, "***** Serial number of certificate is below *****");
2197 OIC_LOG_BUFFER(DEBUG, TAG, cert->serial.p, cert->serial.len);
2198 OIC_LOG(DEBUG, TAG, "***** Serial number of certificate is above *****");
2199 OIC_LOG_V(DEBUG, TAG, "OUT%s", __func__);
2204 static int waitCallbackRet(void)
2206 for(int i=0; !g_doneCB && CALLBACK_TIMEOUT>i; ++i)
2209 if(OC_STACK_OK != OCProcess())
2211 OIC_LOG(ERROR, TAG, "OCStack process error");
2218 OCPDMCleanupForTimeout();
2224 static int selectTwoDiffNum(int* a, int* b, const int max, const char* str)
2226 if(!a || !b || 2>max || !str)
2233 for(int i=0; 2>i; ++i)
2235 int* num = 0==i?a:b;
2238 printf(" > Enter Device[%d] Number, %s: ", i+1, str);
2239 for(int ret=0; 1!=ret; )
2241 ret = scanf("%d", num);
2242 for( ; 0x20<=getchar(); ); // for removing overflow garbages
2243 // '0x20<=code' is character region
2245 if(0<*num && max>=*num)
2249 printf(" Entered Wrong Number. Please Enter Again\n");
2264 static void setDevProtocol(OCProvisionDev_t* lst)
2268 printf(" Device List is Empty..\n\n");
2274 if(2 == secure_protocol)
2276 lst->connType &= ~CT_ADAPTER_IP; //reset IP flag
2277 lst->connType |= CT_ADAPTER_TCP; //set TCP flag
2278 lst->endpoint.adapter = OC_ADAPTER_TCP;
2279 lst->endpoint.port = lst->tcpPort;
2280 lst->securePort = lst->tcpPort;
2286 static void selectSecureProtocol()
2288 printf(" Select protocol\n");
2289 printf(" 1 - DTLS(Default)\n");
2290 printf(" 2 - TLS\n");
2292 for(int ret=0; 1!=ret; )
2294 ret = scanf("%d",&secure_protocol);
2295 for( ; 0x20<=getchar(); ); // for removing overflow garbages
2296 // '0x20<=code' is character region
2299 if(0 >= secure_protocol || 2 < secure_protocol)
2301 secure_protocol = 1;
2304 setDevProtocol(g_own_list);
2305 setDevProtocol(g_unown_list);
2309 static void secureStorageHwEmulation()
2311 printf(" Enable Secure Storage HW Emulation\n");
2313 printf(" Enter Own Certificate File Path[~4095]: ");
2314 char cert_filepath[4096] = {0,};
2315 for(int ret=0; 1!=ret; )
2317 ret = scanf("%255s", cert_filepath);
2318 for( ; 0x20<=getchar(); ); // for removing overflow garbages
2319 // '0x20<=code' is character region
2322 printf(" Enter Private Key File Path[~4095]: ");
2323 char key_filepath[4096] = {0,};
2324 for(int ret=0; 1!=ret; )
2326 ret = scanf("%255s", key_filepath);
2327 for( ; 0x20<=getchar(); ); // for removing overflow garbages
2328 // '0x20<=code' is character region
2331 printf(" Enter Password for Key Password[~31][Press (Enter) to not set]: ");
2332 char pwd[32] = {0,};
2333 for(int i=0; i < 31; i++)
2335 pwd[i] = (char)getchar();
2348 if (0 != SSemulSetCertkeyFilepath(cert_filepath, key_filepath, pwd))
2350 printf(" Fail to set cert/key file path");
2354 if (0 != SetHwPkixCallbacks(HWGetKeyContext,
2356 HWGetOwnCertificateChain,
2359 printf(" Fail to regist HW Pkix Callbacks");
2362 printf(" Success to regist HW Pkix Callbacks");
2365 static void selectVerifMethod()
2368 printf(" Select verification method for ownership transfer\n");
2369 printf(" 0 - No verification\n");
2370 printf(" 1 - Display only\n");
2371 printf(" 2 - Confirm only\n");
2372 printf(" 3 - Both Display and Confirm\n");
2374 for(int ret=0; 1!=ret; )
2376 ret = scanf("%d",&option);
2377 for( ; 0x20<=getchar(); ); // for removing overflow garbages
2378 // '0x20<=code' is character region
2381 if(0 > option || 3 < option)
2383 printf("Invalid option!");
2385 SetVerifyOption((VerifyOptionBitmask_t) option);
2386 printf("Option %d chosen!", option);
2389 static void printMenu(void)
2391 printf("************************************************************\n");
2392 printf("****** OIC Provisioning Client with using C-level API ******\n");
2393 printf("************************************************************\n\n");
2395 printf("** [A] DISCOVER DEVICES ON NETWORK\n");
2396 printf("** 10. Discover All Un/Owned Devices on Network\n");
2397 printf("** 11. Discover Only Unowned Devices on Network\n");
2398 #ifdef MULTIPLE_OWNER
2399 printf("** 12. Discover Only Owned Devices on Network\n");
2400 printf("** 13. Discover Multiple Ownership Transfer Enabled Devices on Network\n\n");
2402 printf("** 12. Discover Only Owned Devices on Network\n\n");
2403 #endif //MULTIPLE_OWNER
2405 printf("** [B] REGISTER/OWN ALL DISCOVERED UNOWNED DEVICES\n");
2406 printf("** 20. Register/Own All Discovered Unowned Devices\n\n");
2408 printf("** [C] PROVISION/LINK PAIRWISE THINGS\n");
2409 printf("** 30. Provision/Link Pairwise Things\n");
2410 printf("** 31. Provision Credentials for Pairwise Things\n");
2411 printf("** 32. Provision the Selected Access Control List(ACL)\n");
2412 printf("** 33. Provision Direct-Pairing Configuration\n");
2413 printf("** 34. Check Linked Status of the Selected Device on PRVN DB\n");
2414 printf("** 35. Save the Selected Access Control List(ACL) into local SVR DB\n\n");
2416 printf("** [D] UNLINK PAIRWISE THINGS\n");
2417 printf("** 40. Unlink Pairwise Things\n\n");
2419 printf("** [E] REMOVE THE SELECTED DEVICE\n");
2420 printf("** 50. Remove the Selected Device\n");
2421 printf("** 51. Remove Device with UUID (UUID input is required)\n");
2422 printf("** 52. Reset the Selected Device\n");
2423 printf("** 53. Reset SVR DB\n\n");
2425 printf("** [F] GET SECURITY RESOURCE FOR DEBUGGING ONLY\n");
2426 printf("** 60. Get the Credential resources of the Selected Device\n");
2427 printf("** 61. Get the ACL resources of the Selected Device\n\n");
2429 #ifdef MULTIPLE_OWNER
2430 printf("** [G] UPDATE THE MULTIPLE OWNERSHIP TRANSFER RELATED VALUE\n");
2431 printf("** 70. Change the Multiple Ownership transfer MODE(update mom)\n");
2432 printf("** 71. Provision Preconfigured PIN\n");
2433 printf("** 72. Change the Multiple Ownership transfer METHOD(update oxmsel)\n");
2434 printf("** 73. Remove Sub-Owner from Resource Server\n");
2435 printf("** 74. Remove All Sub-Owner from Resource Server\n\n");
2436 #endif //MULTIPLE_OWNER
2439 printf("** [H] SELECT SECURE PROTOCOL DTLS/TLS AND OTHERS\n");
2440 printf("** 80. Select secure protocol(default DTLS)\n");
2441 printf("** 81. Select verification method\n");
2442 printf("** 82. Enable secure storage hw emulation\n\n");
2444 printf("** [H] SELECT VERIFICATION OPTION\n");
2445 printf("** 81. Select verification method\n\n");
2447 printf("** [I] EXIT PROVISIONING CLIENT\n");
2449 printf("** 99. Exit Provisionong Client\n\n");
2451 printf("************************************************************\n\n");
2454 #if 0 // Code for enabling path configuration for PDB and SVR DBf
2455 static void printUsage(void)
2458 printf("OIC Provisioning Client with using C-level API\n");
2459 printf("Usage: provisioningclient [option]...\n");
2461 printf(" -h print help for this provisioning client\n");
2462 printf(" -p=[prvn_db_file_path/name] input PRVN DB file path and name\n");
2463 printf(" if not exists, will load default DB file\n");
2464 printf(" (default: |oic_prvn_mng.db| on working dir)\n");
2465 printf(" (ex. -p=oic_prvn_mng.db)\n");
2466 printf(" -s=[svr_db_file_path/name] input SVR DB file path and name\n");
2467 printf(" if not exists, will load default DB file\n");
2468 printf(" (default: |oic_svr_db_client.json| on working dir)\n");
2469 printf(" (ex. -s=oic_svr_db_client.json)\n");
2475 * Sample implementation of Export key block and master secret
2477 * @param[in] p_expkey Context for the callback
2478 * @aram[in] ms Pointer to master secret (fixed length: 48 bytes)
2479 * @param[in] kb Pointer to key block, see RFC 5246 section 6.3
2480 * (variable length: 2 * maclen + 2 * keylen + 2 * ivlen).
2481 * @param[in] maclen MAC length
2482 * @param[in] keylen Key length
2483 * @param[in] ivlen IV length
2485 static void SslExportKeysCallback(const unsigned char* masterSecret,
2486 const unsigned char* keyBlock,
2487 size_t macLen, size_t keyLen, size_t ivLen)
2489 OIC_LOG_V(INFO, TAG, "In %s ", __func__);
2491 OIC_LOG(INFO, TAG, "[MASTER SECRET] : ");
2492 OIC_LOG_BUFFER(INFO, TAG, masterSecret, 48);
2494 OIC_LOG(INFO, TAG, "[KEY BLOCK] : ");
2495 OIC_LOG_BUFFER(INFO, TAG, keyBlock, (2 * macLen) + (2 * keyLen) + (2 * ivLen));
2497 OIC_LOG_V(INFO, TAG, "Mac Length = %zu, Key Length = %zu, IV Length = %zu",
2498 macLen, keyLen, ivLen);
2500 OIC_LOG_V(INFO, TAG, "Out %s ", __func__);
2503 // main function for provisioning client using C-level provisioning API
2506 // initialize provisioning client
2507 if(initProvisionClient())
2509 OIC_LOG(ERROR, TAG, "ProvisionClient init error");
2514 CASetSslExportKeysCallback(SslExportKeysCallback, CA_SSL_EKCB_DTLS, CA_SSL_EKCB_CLIENT))
2516 OIC_LOG(ERROR, TAG, "Failed to register the (D)TLS export Key Callback!");
2520 // Client can choose a allowed/not-allowed OxM method.
2521 if(OC_STACK_OK != OCSetOxmAllowStatus(OIC_DECENTRALIZED_PUBLIC_KEY, false))
2523 OIC_LOG(WARNING, TAG, "Failed to disable OIC_DECENTRALIZED_PUBLIC_KEY OxM");
2526 // set callbacks for verification options
2527 SetDisplayNumCB(NULL, displayNumCB);
2528 SetUserConfirmCB(NULL, confirmNumCB);
2529 SetInputStateCB(NULL, notifyInputStateCB);
2530 SetSelectOTMCB(selectOTMcb);
2532 // set callback for checking peer certificate information
2533 OCSetPeerCertCallback(NULL, peerCertCallback);
2535 #ifdef MULTIPLE_OWNER
2536 SetPreconfigPin("12341234", 8);
2537 #endif //MULTIPLE_OWNER
2539 // main loop for provisioning manager
2545 printf(">> Enter Menu Number: ");
2546 for(int ret=0; 1!=ret; )
2548 ret = scanf("%d", &mn_num);
2549 for( ; 0x20<=getchar(); ); // for removing overflow garbages
2550 // '0x20<=code' is character region
2555 case _10_DISCOV_ALL_DEVS_:
2556 if(discoverAllDevices())
2558 OIC_LOG(ERROR, TAG, "_10_DISCOV_ALL_DEVS_: error");
2561 case _11_DISCOV_UNOWN_DEVS_:
2562 if(discoverUnownedDevices())
2564 OIC_LOG(ERROR, TAG, "_11_DISCOV_UNOWN_DEVS_: error");
2567 case _12_DISCOV_OWN_DEVS_:
2568 if(discoverOwnedDevices())
2570 OIC_LOG(ERROR, TAG, "_12_DISCOV_OWN_DEVS_: error");
2573 #ifdef MULTIPLE_OWNER
2574 case _13_MOT_DISCOV_DEV_:
2575 if(discoverMOTEnabledDevices())
2577 OIC_LOG(ERROR, TAG, "_13_MOT_DISCOV_DEV_: error");
2580 #endif //MULTIPLE_OWNER
2581 case _20_REGIST_DEVS_:
2582 if(registerDevices())
2584 OIC_LOG(ERROR, TAG, "_20_REGIST_DEVS_: error");
2587 case _30_PROVIS_PAIR_DEVS_:
2588 if(provisionPairwise())
2590 OIC_LOG(ERROR, TAG, "_30_PROVIS_PAIR_DEVS_: error");
2593 case _31_PROVIS_CRED_:
2596 OIC_LOG(ERROR, TAG, "_31_PROVIS_CRED_: error");
2599 case _32_PROVIS_ACL_:
2602 OIC_LOG(ERROR, TAG, "_32_PROVIS_ACL_: error");
2605 case _33_PROVIS_DP_:
2606 if(provisionDirectPairing())
2608 OIC_LOG(ERROR, TAG, "_33_PROVIS_DP_: error");
2611 case _34_CHECK_LINK_STATUS_:
2612 if(checkLinkedStatus())
2614 OIC_LOG(ERROR, TAG, "_34_CHECK_LINK_STATUS_: error");
2620 OIC_LOG(ERROR, TAG, "_35_SAVE_ACL_: error");
2623 case _40_UNLINK_PAIR_DEVS_:
2624 if(unlinkPairwise())
2626 OIC_LOG(ERROR, TAG, "_40_UNLINK_PAIR_DEVS_: error");
2629 case _50_REMOVE_SELEC_DEV_:
2632 OIC_LOG(ERROR, TAG, "_50_REMOVE_SELEC_DEV_: error");
2635 case _51_REMOVE_DEV_WITH_UUID_:
2636 if(removeDeviceWithUuid())
2638 OIC_LOG(ERROR, TAG, "_51_REMOVE_DEV_WITH_UUID_: error");
2641 case _52_RESET_SELEC_DEV_:
2644 OIC_LOG(ERROR, TAG, "_52_RESET_SELEC_DEV_: error");
2647 case _53_RESET_SVR_DB_:
2650 OIC_LOG(ERROR, TAG, "_53_RESET_SVR_DB_: error");
2656 OIC_LOG(ERROR, TAG, "_60_GET_CRED_: error");
2662 OIC_LOG(ERROR, TAG, "_61_GET_ACL_: error");
2665 #ifdef MULTIPLE_OWNER
2666 case _70_MOT_CHANGE_MOM_:
2667 if(changeMultipleOwnershipTrnasferMode())
2669 OIC_LOG(ERROR, TAG, "_70_MOT_CHANGE_MOM_: error");
2672 case _71_MOT_PROV_PRECONF_PIN_:
2673 if(provisionPreconfigPIN())
2675 OIC_LOG(ERROR, TAG, "_71_MOT_PROV_PRECONF_PIN_: error");
2678 case _72_MOT_OXM_SEL_:
2679 if(selectMultipleOwnershipTrnasferMethod())
2681 OIC_LOG(ERROR, TAG, "_72_MOT_OXM_SEL_: error");
2684 case _73_MOT_REMOVE_SUBOWNER_:
2685 if(removeSubOwner())
2687 OIC_LOG(ERROR, TAG, "_73_MOT_REMOVE_SUBOWNER_ : error");
2690 case _74_MOT_REMOVE_ALL_SUBOWNER_:
2691 if(removeAllSubOwner())
2693 OIC_LOG(ERROR, TAG, "_74_MOT_REMOVE_ALL_SUBOWNER_ : error");
2696 #endif //MULTIPLE_OWNER
2698 case _80_SELECT_PROTOCOL_:
2699 selectSecureProtocol();
2702 case _81_SELECT_VERIF_METHOD_:
2703 selectVerifMethod();
2705 case _82_SECURE_STORAGE_HW_EMULATION_:
2706 secureStorageHwEmulation();
2708 case _99_EXIT_PRVN_CLT_:
2711 printf(">> Entered Wrong Number. Please Enter Again\n\n");
2717 if(OC_STACK_OK != OCStop())
2719 OIC_LOG(ERROR, TAG, "OCStack stop error");
2721 OCDeleteDiscoveredDevices(g_own_list); // after here |g_own_list| points nothing
2722 OCDeleteDiscoveredDevices(g_unown_list); // after here |g_unown_list| points nothing
2723 #ifdef MULTIPLE_OWNER
2724 OCDeleteDiscoveredDevices(g_mot_enable_list); // after here |g_motdev_list| points nothing
2725 #endif //MULTIPLE_OWNER
2729 OICFree(g_svr_fname); // after here |g_svr_fname| points nothing
2733 OICFree(g_prvn_fname); // after here |g_prvn_fname| points nothing
2735 return 0; // always return normal case
2740 #endif //__cplusplus