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"
45 // declaration(s) for provisioning client using C-level provisioning API
46 // user input definition for main loop on provisioning client
47 #define _10_DISCOV_ALL_DEVS_ 10
48 #define _11_DISCOV_UNOWN_DEVS_ 11
49 #define _12_DISCOV_OWN_DEVS_ 12
50 #ifdef _ENABLE_MULTIPLE_OWNER_
51 #define _13_MOT_DISCOV_DEV_ 13
52 #endif //_ENABLE_MULTIPLE_OWNER_
53 #define _20_REGIST_DEVS_ 20
54 #define _30_PROVIS_PAIR_DEVS_ 30
55 #define _31_PROVIS_CRED_ 31
56 #define _32_PROVIS_ACL_ 32
57 #define _33_PROVIS_DP_ 33
58 #define _34_CHECK_LINK_STATUS_ 34
59 #define _35_SAVE_ACL_ 35
60 #define _40_UNLINK_PAIR_DEVS_ 40
61 #define _50_REMOVE_SELEC_DEV_ 50
62 #define _51_REMOVE_DEV_WITH_UUID_ 51
63 #define _52_RESET_SELEC_DEV_ 52
64 #define _60_GET_CRED_ 60
65 #define _61_GET_ACL_ 61
66 #ifdef _ENABLE_MULTIPLE_OWNER_
67 #define _70_MOT_CHANGE_MOM_ 70
68 #define _71_MOT_PROV_PRECONF_PIN_ 71
69 #define _72_MOT_OXM_SEL_ 72
70 #endif //_ENABLE_MULTIPLE_OWNER_
71 #define _80_SELECT_PROTOCOL_ 80
72 #define _99_EXIT_PRVN_CLT_ 99
74 #define ACL_RESRC_MAX_NUM 16
75 #define ACL_RESRC_ARRAY_SIZE 3 //This value is used only for sample (not OCF spec)
76 #define ACL_RESRC_MAX_LEN 128
77 #define ACL_PEMISN_CNT 5
78 #define DISCOVERY_TIMEOUT 10 // 10 sec
79 #define CALLBACK_TIMEOUT 60 // 1 min
80 #define TAG "provisioningclient"
82 static const char* ACL_PEMISN[5] = {"CREATE", "READ", "WRITE", "DELETE", "NOTIFY"};
83 static const char* SVR_DB_FILE_NAME = "oic_svr_db_client.dat";
84 // '_' for separaing from the same constant variable in |srmresourcestrings.c|
85 static const char* PRVN_DB_FILE_NAME = "oic_prvn_mng.db";
86 static const OicSecPrm_t SUPPORTED_PRMS[1] =
91 // |g_ctx| means provision manager application context and
92 // the following, includes |un/own_list|, could be variables, which |g_ctx| has,
93 // for accessing all function(s) for these, they are declared on global domain
94 static const char* g_ctx = "Provision Manager Client Application Context";
95 static char* g_svr_fname;
96 static char* g_prvn_fname;
97 static OCProvisionDev_t* g_own_list;
98 static OCProvisionDev_t* g_unown_list;
100 static int g_unown_cnt;
101 #ifdef _ENABLE_MULTIPLE_OWNER_
102 static OCProvisionDev_t* g_mot_enable_list;
103 static int g_mot_enable_cnt;
104 #endif //_ENABLE_MULTIPLE_OWNER_
106 static bool g_doneCB;
108 static int secure_protocol = 1;
109 static void setDevProtocol(OCProvisionDev_t* dev_lst);
111 // function declaration(s) for calling them before implementing
112 static OicSecAcl_t* createAcl(const int);
113 static OicSecAcl_t* createSimpleAcl(const OicUuid_t uuid);
114 static OicSecPdAcl_t* createPdAcl(const int);
115 static OCProvisionDev_t* getDevInst(const OCProvisionDev_t*, const int);
116 static int printDevList(const OCProvisionDev_t*);
117 static size_t printUuidList(const OCUuidList_t*);
118 static int printResultList(const OCProvisionResult_t*, const int);
119 static void printUuid(const OicUuid_t*);
120 static FILE* fopen_prvnMng(const char*, const char*);
121 static int waitCallbackRet(void);
122 static int selectTwoDiffNum(int*, int*, const int, const char*);
124 // callback function(s) for provisioning client using C-level provisioning API
125 static void ownershipTransferCB(void* ctx, int nOfRes, OCProvisionResult_t* arr, bool hasError)
129 OIC_LOG_V(INFO, TAG, "Ownership Transfer SUCCEEDED - ctx: %s", (char*) ctx);
133 OIC_LOG_V(ERROR, TAG, "Ownership Transfer FAILED - ctx: %s", (char*) ctx);
134 printResultList((const OCProvisionResult_t*) arr, nOfRes);
139 static void provisionPairwiseCB(void* ctx, int nOfRes, OCProvisionResult_t* arr, bool hasError)
143 OIC_LOG_V(INFO, TAG, "Provision Pairwise SUCCEEDED - ctx: %s", (char*) ctx);
147 OIC_LOG_V(ERROR, TAG, "Provision Pairwise FAILED - ctx: %s", (char*) ctx);
148 printResultList((const OCProvisionResult_t*) arr, nOfRes);
153 static void provisionCredCB(void* ctx, int nOfRes, OCProvisionResult_t* arr, bool hasError)
157 OIC_LOG_V(INFO, TAG, "Provision Credential SUCCEEDED - ctx: %s", (char*) ctx);
161 OIC_LOG_V(ERROR, TAG, "Provision Credential FAILED - ctx: %s", (char*) ctx);
162 printResultList((const OCProvisionResult_t*) arr, nOfRes);
167 static void provisionAclCB(void* ctx, int nOfRes, OCProvisionResult_t* arr, bool hasError)
171 OIC_LOG_V(INFO, TAG, "Provision ACL SUCCEEDED - ctx: %s", (char*) ctx);
175 OIC_LOG_V(ERROR, TAG, "Provision ACL FAILED - ctx: %s", (char*) ctx);
176 printResultList((const OCProvisionResult_t*) arr, nOfRes);
181 static void getCredCB(void* ctx, int nOfRes, OCProvisionResult_t* arr, bool hasError)
185 OIC_LOG_V(INFO, TAG, "getCredCB SUCCEEDED - ctx: %s", (char*) ctx);
189 OIC_LOG_V(ERROR, TAG, "getCredCB FAILED - ctx: %s", (char*) ctx);
190 printResultList((const OCProvisionResult_t*) arr, nOfRes);
195 static void getAclCB(void* ctx, int nOfRes, OCProvisionResult_t* arr, bool hasError)
199 OIC_LOG_V(INFO, TAG, "getAclCB SUCCEEDED - ctx: %s", (char*) ctx);
203 OIC_LOG_V(ERROR, TAG, "getAclCB FAILED - ctx: %s", (char*) ctx);
204 printResultList((const OCProvisionResult_t*) arr, nOfRes);
209 static void provisionDPCB(void* ctx, int nOfRes, OCProvisionResult_t* arr, bool hasError)
213 OIC_LOG_V(INFO, TAG, "Provision Direct-Pairing SUCCEEDED - ctx: %s", (char*) ctx);
217 OIC_LOG_V(ERROR, TAG, "Provision Direct-Pairing FAILED - ctx: %s", (char*) ctx);
218 printResultList((const OCProvisionResult_t*) arr, nOfRes);
223 static void unlinkDevicesCB(void* ctx, int nOfRes, OCProvisionResult_t* arr, bool hasError)
227 OIC_LOG_V(INFO, TAG, "Unlink Devices SUCCEEDED - ctx: %s", (char*) ctx);
231 OIC_LOG_V(ERROR, TAG, "Unlink Devices FAILED - ctx: %s", (char*) ctx);
232 printResultList((const OCProvisionResult_t*) arr, nOfRes);
237 static void removeDeviceCB(void* ctx, int nOfRes, OCProvisionResult_t* arr, bool hasError)
241 OIC_LOG_V(INFO, TAG, "Remove Device SUCCEEDED - ctx: %s", (char*) ctx);
245 OIC_LOG_V(ERROR, TAG, "Remove Device FAILED - ctx: %s", (char*) ctx);
246 printResultList((const OCProvisionResult_t*) arr, nOfRes);
251 static void syncDeviceCB(void* ctx, int nOfRes, OCProvisionResult_t* arr, bool hasError)
255 OIC_LOG_V(INFO, TAG, "Sync Device SUCCEEDED - ctx: %s", (char*) ctx);
259 OIC_LOG_V(ERROR, TAG, "Sync Device FAILED - ctx: %s", (char*) ctx);
260 printResultList((const OCProvisionResult_t*) arr, nOfRes);
265 #ifdef _ENABLE_MULTIPLE_OWNER_
266 static void updateDoxmForMOTCB(void* ctx, int nOfRes, OCProvisionResult_t* arr, bool hasError)
270 OIC_LOG_V(INFO, TAG, "POST 'doxm' SUCCEEDED - ctx: %s", (char*) ctx);
274 OIC_LOG_V(ERROR, TAG, "POST 'doxm' FAILED - ctx: %s", (char*) ctx);
275 printResultList((const OCProvisionResult_t*) arr, nOfRes);
279 #endif //_ENABLE_MULTIPLE_OWNER_
281 static void inputPinCB(char* pin, size_t len)
283 if(!pin || OXM_RANDOM_PIN_MIN_SIZE > len)
285 OIC_LOG(ERROR, TAG, "inputPinCB invalid parameters");
289 printf(" > INPUT PIN: ");
290 for(int ret=0; 1!=ret; )
292 ret = scanf("%32s", pin);
293 for( ; 0x20<=getchar(); ); // for removing overflow garbages
294 // '0x20<=code' is character region
298 // function(s) for provisioning client using C-level provisioning API
299 static int initProvisionClient(void)
301 // initialize persistent storage for SVR DB
302 static OCPersistentStorage pstStr =
304 .open = fopen_prvnMng,
310 if(OC_STACK_OK != OCRegisterPersistentStorageHandler(&pstStr))
312 OIC_LOG(ERROR, TAG, "OCRegisterPersistentStorageHandler error");
316 // initialize OC stack and provisioning manager
317 if(OC_STACK_OK != OCInit(NULL, 0, OC_CLIENT_SERVER))
319 OIC_LOG(ERROR, TAG, "OCStack init error");
323 if (access(PRVN_DB_FILE_NAME, F_OK) != -1)
325 printf("************************************************************\n");
326 printf("************Provisioning DB file already exists.************\n");
327 printf("************************************************************\n");
331 printf("*************************************************************\n");
332 printf("************No provisioning DB file, creating new************\n");
333 printf("*************************************************************\n");
336 if(OC_STACK_OK != OCInitPM(PRVN_DB_FILE_NAME))
338 OIC_LOG(ERROR, TAG, "OC_PM init error");
342 SetInputPinCB(inputPinCB);
347 static int discoverAllDevices(void)
349 // delete un/owned device lists before updating them
352 OCDeleteDiscoveredDevices(g_own_list);
357 OCDeleteDiscoveredDevices(g_unown_list);
361 // call |OCGetDevInfoFromNetwork| API actually
362 printf(" Discovering All Un/Owned Devices on Network..\n");
363 if(OC_STACK_OK != OCGetDevInfoFromNetwork(DISCOVERY_TIMEOUT, &g_own_list, &g_unown_list))
365 OIC_LOG(ERROR, TAG, "OCGetDevInfoFromNetwork API error");
369 // display the discovered un/owned lists
370 printf(" > Discovered Owned Devices\n");
371 g_own_cnt = printDevList(g_own_list);
372 printf(" > Discovered Unowned Devices\n");
373 g_unown_cnt = printDevList(g_unown_list);
375 setDevProtocol(g_own_list);
376 setDevProtocol(g_unown_list);
382 static int discoverUnownedDevices(void)
384 // delete unowned device list before updating it
387 OCDeleteDiscoveredDevices(g_unown_list);
391 // call |OCDiscoverUnownedDevices| API actually
392 printf(" Discovering Only Unowned Devices on Network..\n");
393 if(OC_STACK_OK != OCDiscoverUnownedDevices(DISCOVERY_TIMEOUT, &g_unown_list))
395 OIC_LOG(ERROR, TAG, "OCDiscoverUnownedDevices API error");
399 // display the discovered unowned list
400 printf(" > Discovered Unowned Devices\n");
401 g_unown_cnt = printDevList(g_unown_list);
403 setDevProtocol(g_unown_list);
408 static int discoverOwnedDevices(void)
410 // delete owned device list before updating it
413 OCDeleteDiscoveredDevices(g_own_list);
417 // call |OCDiscoverOwnedDevices| API actually
418 printf(" Discovering Only Owned Devices on Network..\n");
419 if(OC_STACK_OK != OCDiscoverOwnedDevices(DISCOVERY_TIMEOUT, &g_own_list))
421 OIC_LOG(ERROR, TAG, "OCDiscoverOwnedDevices API error");
425 // display the discovered owned list
426 printf(" > Discovered Owned Devices\n");
427 g_own_cnt = printDevList(g_own_list);
429 setDevProtocol(g_own_list);
434 #ifdef _ENABLE_MULTIPLE_OWNER_
435 static int discoverMOTEnabledDevices(void)
437 // delete owned device list before updating it
438 if(g_mot_enable_list)
440 OCDeleteDiscoveredDevices(g_mot_enable_list);
441 g_mot_enable_list = NULL;
444 // call |OCDiscoverOwnedDevices| API actually
445 printf(" Discovering Multiple Ownership Transfer Enabled Devices on Network..\n");
446 if(OC_STACK_OK != OCDiscoverMultipleOwnerEnabledDevices(DISCOVERY_TIMEOUT, &g_mot_enable_list))
448 OIC_LOG(ERROR, TAG, "OCDiscoverMultipleOwnerEnalbedDevices API error");
452 // display the discovered owned list
453 printf(" > Discovered Multiple Ownership Transfer Enabled Devices\n");
454 g_mot_enable_cnt = printDevList(g_mot_enable_list);
458 #endif //_ENABLE_MULTIPLE_OWNER_
460 static int registerDevices(void)
462 // check |unown_list| for registering devices
463 if(!g_unown_list || 0>=g_unown_cnt)
465 printf(" > Unowned Device List, to Register Devices, is Empty\n");
466 printf(" > Please Discover Unowned Devices first, with [10|11] Menu\n");
467 return 0; // normal case
470 // call |OCDoOwnershipTransfer| API actually
471 // calling this API with callback actually acts like blocking
472 // for error checking, the return value saved and printed
474 printf(" Registering All Discovered Unowned Devices..\n");
475 OCStackResult rst = OCDoOwnershipTransfer((void*) g_ctx, g_unown_list, ownershipTransferCB);
476 if(OC_STACK_OK != rst)
478 OIC_LOG_V(ERROR, TAG, "OCDoOwnershipTransfer API error: %d", rst);
481 if(waitCallbackRet()) // input |g_doneCB| flag implicitly
483 OIC_LOG(ERROR, TAG, "OCProvisionCredentials callback error");
487 // display the registered result
488 printf(" > Registered Discovered Unowned Devices\n");
489 printf(" > Please Discover Owned Devices for the Registered Result, with [10|12] Menu\n");
494 static int provisionPairwise(void)
496 // check |own_list| for provisioning pairwise devices
497 if(!g_own_list || 2>g_own_cnt)
499 printf(" > Owned Device List, to Provision the Pairwise, is Empty\n");
500 printf(" > Please Register Unowned Devices first, with [20] Menu\n");
501 return 0; // normal case
504 // select two devices for provisioning pairwise devices
505 int dev_num[2] = {0};
506 if(selectTwoDiffNum(&(dev_num[0]), &(dev_num[1]), g_own_cnt, "for Linking Devices"))
508 OIC_LOG(ERROR, TAG, "selectTwoDiffNum error return");
509 return -1; // not need to 'goto' |ERROR| before allocating |acl|
512 // create ACL(s) for each selected device
513 OicSecAcl_t* acl[2] = {0};
514 for(int i=0; 2>i; ++i)
516 acl[i] = createAcl(dev_num[i]);
519 OIC_LOG(ERROR, TAG, "createAcl error return");
524 // call |OCProvisionPairwiseDevices| API actually
525 // calling this API with callback actually acts like blocking
526 // for error checking, the return value saved and printed
528 printf(" Provisioning Selected Pairwise Devices..\n");
530 OCProvisionPairwiseDevices((void*) g_ctx,
531 SYMMETRIC_PAIR_WISE_KEY, OWNER_PSK_LENGTH_128,
532 getDevInst((const OCProvisionDev_t*) g_own_list, dev_num[0]), acl[0],
533 getDevInst((const OCProvisionDev_t*) g_own_list, dev_num[1]), acl[1],
534 provisionPairwiseCB);
535 if(OC_STACK_OK != rst)
537 OIC_LOG_V(ERROR, TAG, "OCProvisionPairwiseDevices API error: %d", rst);
540 if(waitCallbackRet()) // input |g_doneCB| flag implicitly
542 OIC_LOG(ERROR, TAG, "OCProvisionCredentials callback error");
545 OCDeleteACLList(acl[0]);
546 OCDeleteACLList(acl[1]);
548 // display the pairwise-provisioned result
549 printf(" > Provisioned Selected Pairwise Devices\n");
550 printf(" > Please Check Device's Status for the Linked Result, with [33] Menu\n");
555 OCDeleteACLList(acl[0]);
556 OCDeleteACLList(acl[1]);
560 static int provisionCred(void)
562 // check |own_list| for provisioning pairwise credentials
563 if(!g_own_list || 2>g_own_cnt)
565 printf(" > Owned Device List, to Provision Credentials, is Empty\n");
566 printf(" > Please Register Unowned Devices first, with [20] Menu\n");
567 return 0; // normal case
570 // select two devices for provisioning pairwise credentials
571 int dev_num[2] = {0};
572 if(selectTwoDiffNum(&(dev_num[0]), &(dev_num[1]), g_own_cnt, "for Linking CRED(s)"))
574 OIC_LOG(ERROR, TAG, "selectTwoDiffNum error return");
578 printf(" Select PSK length..\n");
579 printf(" 1 - 128bit(Default)\n");
580 printf(" 2 - 256bit\n");
583 for(int ret=0; 1!=ret; )
585 ret = scanf("%d",&sizeOption);
586 for( ; 0x20<=getchar(); ); // for removing overflow garbages
587 // '0x20<=code' is character region
595 size = OWNER_PSK_LENGTH_128;
600 size = OWNER_PSK_LENGTH_256;
605 size = OWNER_PSK_LENGTH_128;
611 // call |OCProvisionCredentials| API actually
612 // calling this API with callback actually acts like blocking
613 // for error checking, the return value saved and printed
615 printf(" Provisioning Selected Pairwise Credentials..\n");
617 OCProvisionCredentials((void*) g_ctx,
618 SYMMETRIC_PAIR_WISE_KEY, size,
619 getDevInst((const OCProvisionDev_t*) g_own_list, dev_num[0]),
620 getDevInst((const OCProvisionDev_t*) g_own_list, dev_num[1]),
622 if(OC_STACK_OK != rst)
624 OIC_LOG_V(ERROR, TAG, "OCProvisionCredentials API error: %d", rst);
627 if(waitCallbackRet()) // input |g_doneCB| flag implicitly
629 OIC_LOG(ERROR, TAG, "OCProvisionCredentials callback error");
633 // display the CRED-provisioned result
634 printf(" > Provisioned Selected Pairwise Crendentials\n");
635 printf(" > Please Check Device's Status for the Linked Result, with [34] Menu\n");
640 static int provisionAcl(void)
642 // check |own_list| for provisioning access control list
643 if(!g_own_list || 1>g_own_cnt)
645 printf(" > Owned Device List, to Provision ACL, is Empty\n");
646 printf(" > Please Register Unowned Devices first, with [20] Menu\n");
647 return 0; // normal case
650 // select device for provisioning access control list
654 printf(" > Enter Device Number, for Provisioning ACL: ");
655 for(int ret=0; 1!=ret; )
657 ret = scanf("%d", &dev_num);
658 for( ; 0x20<=getchar(); ); // for removing overflow garbages
659 // '0x20<=code' is character region
661 if(0<dev_num && g_own_cnt>=dev_num)
665 printf(" Entered Wrong Number. Please Enter Again\n");
668 // create ACL for selected device
669 OicSecAcl_t* acl = NULL;
670 acl = createAcl(dev_num);
673 OIC_LOG(ERROR, TAG, "createAcl error return");
677 // call |OCProvisionACL| API actually
678 // calling this API with callback actually acts like blocking
679 // for error checking, the return value saved and printed
681 printf(" Provisioning Selected ACL..\n");
682 OCProvisionDev_t* dev = getDevInst((const OCProvisionDev_t*) g_own_list, dev_num);
685 OIC_LOG(ERROR, TAG, "provisionAcl: device instance empty");
688 OCStackResult rst = OCProvisionACL((void*) g_ctx, dev, acl, provisionAclCB);
689 if(OC_STACK_OK != rst)
691 OIC_LOG_V(ERROR, TAG, "OCProvisionACL API error: %d", rst);
694 if(waitCallbackRet()) // input |g_doneCB| flag implicitly
696 OIC_LOG(ERROR, TAG, "OCProvisionCredentials callback error");
699 OCDeleteACLList(acl); // after here |acl| points nothing
701 // display the ACL-provisioned result
702 printf(" > Provisioned Selected ACL\n");
707 OCDeleteACLList(acl); // after here |acl| points nothing
711 static int provisionDirectPairing(void)
713 // check |own_list| for provisioning direct-pairing
714 if(!g_own_list || 1>g_own_cnt)
716 printf(" > Owned Device List, to Provision ACL, is Empty\n");
717 printf(" > Please Register Unowned Devices first, with [20] Menu\n");
718 return 0; // normal case
721 // select device for provisioning direct-pairing
725 printf(" > Enter Device Number, for Provisioning Direct-Pairing: ");
726 for(int ret=0; 1!=ret; )
728 ret = scanf("%d", &dev_num);
729 for( ; 0x20<=getchar(); ); // for removing overflow garbages
730 // '0x20<=code' is character region
732 if(0<dev_num && g_own_cnt>=dev_num)
736 printf(" Entered Wrong Number. Please Enter Again\n");
739 // create Direct-Pairing Configuration(PIN, PDACL) for selected device
740 // TODO: default acl -> input from user !
742 memset(&pconf, 0, sizeof(OicSecPconf_t));
747 // set default supported PRM types
748 pconf.prmLen = sizeof(SUPPORTED_PRMS)/sizeof(OicSecPrm_t);
749 pconf.prm = (OicSecPrm_t *)OICCalloc(pconf.prmLen, sizeof(OicSecPrm_t));
752 for (size_t i=0; i<pconf.prmLen; i++)
754 pconf.prm[i] = SUPPORTED_PRMS[i];
759 OIC_LOG(ERROR, TAG, "create prm error return");
764 const char DP_DEFAULT_PIN[] = "00000000";
765 memcpy(pconf.pin.val, DP_DEFAULT_PIN, DP_PIN_LENGTH);
768 pconf.pdacls = createPdAcl(dev_num);
771 OIC_LOG(ERROR, TAG, "createPdAcl error return");
775 // call |OCProvisionDirectPairing| API actually
776 // calling this API with callback actually acts like blocking
777 // for error checking, the return value saved and printed
779 printf(" Atempt Direct-Pairing Provisioning (PIN : [%s])..\n", (char*)pconf.pin.val);
780 OCStackResult rst = OCProvisionDirectPairing((void*) g_ctx,
781 getDevInst((const OCProvisionDev_t*) g_own_list, dev_num),
782 &pconf, provisionDPCB);
783 if(OC_STACK_OK != rst)
785 OIC_LOG_V(ERROR, TAG, "OCProvisionDirectPairing API error: %d", rst);
786 if (OC_STACK_UNAUTHORIZED_REQ == rst)
788 OIC_LOG(ERROR, TAG, "Target Server NOT Support Direct-Pairing !!! (DPC == false)");
792 if(waitCallbackRet()) // input |g_doneCB| flag implicitly
794 OIC_LOG(ERROR, TAG, "OCProvisionCredentials callback error");
797 OCDeletePdAclList(pconf.pdacls);
799 // display the PCONF-provisioned result
800 printf(" > SUCCESS to provision Direct-Pairing !!\n");
805 OCDeletePdAclList(pconf.pdacls); // after here |acl| points nothing
809 static int checkLinkedStatus(void)
811 // check |own_list| for checking selected link status on PRVN DB
812 if(!g_own_list || 1>g_own_cnt)
814 printf(" > Owned Device List, to Check Linked Status on PRVN DB, is Empty\n");
815 printf(" > Please Register Unowned Devices first, with [20] Menu\n");
816 return 0; // normal case
819 // select device for checking selected link status on PRVN DB
823 printf(" > Enter Device Number, for Checking Linked Status on PRVN DB: ");
824 for(int ret=0; 1!=ret; )
826 ret = scanf("%d", &dev_num);
827 for( ; 0x20<=getchar(); ); // for removing overflow garbages
828 // '0x20<=code' is character region
830 if(0<dev_num && g_own_cnt>=dev_num)
834 printf(" Entered Wrong Number. Please Enter Again\n");
837 // call |OCGetLinkedStatus| API actually
838 printf(" Checking Selected Link Status on PRVN DB..\n");
839 OCUuidList_t* dvid_lst = NULL;
841 OCProvisionDev_t* dev = getDevInst((const OCProvisionDev_t*)g_own_list, dev_num);
842 if(!dev || !dev->doxm)
844 OIC_LOG(ERROR, TAG, "checkLinkedStatus: device instance empty");
850 &dev->doxm->deviceID,
851 &dvid_lst, &dvid_cnt)) // allow empty list
853 OIC_LOG(ERROR, TAG, "OCGetLinkedStatus API error");
857 // display the linked status result
858 printf(" > Checked Selected Link Status on PRVN DB\n");
859 if(!dvid_lst || !dvid_cnt) // |size_t| is unsigned
861 printf(" Linked Device List is Empty..\n");
862 return 0; // normal case
864 if(dvid_cnt != printUuidList((const OCUuidList_t*) dvid_lst))
866 OIC_LOG(ERROR, TAG, "printUuidList error return");
869 OCDeleteUuidList(dvid_lst);
874 OCDeleteUuidList(dvid_lst);
878 static int saveAcl(void)
880 // create ACL to save into local SVR DB
881 OicSecAcl_t* acl = NULL;
882 OicUuid_t uuid = {.id={0}};
883 char strUuid[64] = {0};
885 printf("[1] Use a test UUID [11111111-2222-3333-4444-555555555555]\n");
886 printf("[2] Use a user input\n");
890 printf(" > Select Number, for Subject UUID of new ACE: ");
891 for(int ret=0; 1!=ret; )
893 ret = scanf("%d", &sel_num);
894 for( ; 0x20<=getchar(); ); // for removing overflow garbages
895 // '0x20<=code' is character region
899 OICStrcpy(strUuid, sizeof(strUuid), "11111111-2222-3333-4444-555555555555");
902 else if(2 == sel_num)
904 printf(" > Input the UUID : ");
905 for(int ret=0; 1!=ret; )
907 ret = scanf("%64s", strUuid);
908 for( ; 0x20<=getchar(); ); // for removing overflow garbages
909 // '0x20<=code' is character region
913 printf(" Entered Wrong Number. Please Enter Again\n");
917 printf("Selected Subject UUID : %s\n", strUuid);
918 OCStackResult rst = ConvertStrToUuid(strUuid, &uuid);
919 if(OC_STACK_OK != rst)
921 OIC_LOG_V(ERROR, TAG, "ConvertStrToUuid API error: %d", rst);
925 acl = createSimpleAcl(uuid);
928 OIC_LOG(ERROR, TAG, "createAcl error return");
932 // call |OCSaveACL| API actually
933 rst = OCSaveACL(acl);
934 if(OC_STACK_OK != rst)
936 OIC_LOG_V(ERROR, TAG, "OCSaveACL API error: %d", rst);
939 OCDeleteACLList(acl); // after here |acl| points nothing
941 // display the ACL-provisioned result
942 printf(" > Saved Selected ACL\n");
947 OCDeleteACLList(acl); // after here |acl| points nothing
951 static int getCred(void)
953 // check |own_list| for checking selected link status on PRVN DB
954 if(!g_own_list || 1>g_own_cnt)
956 printf(" > Owned Device List, to Check Linked Status on PRVN DB, is Empty\n");
957 printf(" > Please Register Unowned Devices first, with [20] Menu\n");
958 return 0; // normal case
961 // select device for checking selected link status on PRVN DB
965 printf(" > Enter Device Number, for Checking Linked Status on PRVN DB: ");
966 for(int ret=0; 1!=ret; )
968 ret = scanf("%d", &dev_num);
969 for( ; 0x20<=getchar(); ); // for removing overflow garbages
970 // '0x20<=code' is character region
972 if(0<dev_num && g_own_cnt>=dev_num)
976 printf(" Entered Wrong Number. Please Enter Again\n");
979 // call |getDevInst| API actually
980 // calling this API with callback actually acts like blocking
981 // for error checking, the return value saved and printed
983 OCProvisionDev_t* dev = getDevInst((const OCProvisionDev_t*) g_own_list, dev_num);
986 OIC_LOG(ERROR, TAG, "getDevInst: device instance empty");
989 OCStackResult rst = OCGetCredResource((void*) g_ctx, dev, getCredCB);
990 if(OC_STACK_OK != rst)
992 OIC_LOG_V(ERROR, TAG, "OCGetCred API error: %d", rst);
995 if(waitCallbackRet()) // input |g_doneCB| flag implicitly
997 OIC_LOG(ERROR, TAG, "OCGetCredResource callback error");
1001 // display the result of get credential
1002 printf(" > Get Cred SUCCEEDED\n");
1010 static int getAcl(void)
1012 // check |own_list| for checking selected link status on PRVN DB
1013 if(!g_own_list || 1>g_own_cnt)
1015 printf(" > Owned Device List, to Check Linked Status on PRVN DB, is Empty\n");
1016 printf(" > Please Register Unowned Devices first, with [20] Menu\n");
1017 return 0; // normal case
1020 // select device for checking selected link status on PRVN DB
1024 printf(" > Enter Device Number, for Checking Linked Status on PRVN DB: ");
1025 for(int ret=0; 1!=ret; )
1027 ret = scanf("%d", &dev_num);
1028 for( ; 0x20<=getchar(); ); // for removing overflow garbages
1029 // '0x20<=code' is character region
1031 if(0<dev_num && g_own_cnt>=dev_num)
1035 printf(" Entered Wrong Number. Please Enter Again\n");
1038 // call |getDevInst| API actually
1039 // calling this API with callback actually acts like blocking
1040 // for error checking, the return value saved and printed
1042 OCProvisionDev_t* dev = getDevInst((const OCProvisionDev_t*) g_own_list, dev_num);
1045 OIC_LOG(ERROR, TAG, "getDevInst: device instance empty");
1048 OCStackResult rst = OCGetACLResource((void*) g_ctx, dev, getAclCB);
1049 if(OC_STACK_OK != rst)
1051 OIC_LOG_V(ERROR, TAG, "OCGetACLResource API error: %d", rst);
1055 if(waitCallbackRet()) // input |g_doneCB| flag implicitly
1057 OIC_LOG(ERROR, TAG, "OCGetACLResource callback error");
1061 // display the result of get credential
1062 printf(" > Get ACL SUCCEEDED\n");
1070 static int unlinkPairwise(void)
1072 // check |own_list| for unlinking pairwise devices
1073 if(!g_own_list || 2>g_own_cnt)
1075 printf(" > Owned Device List, to Unlink the Pairwise, is Empty\n");
1076 printf(" > Please Register Unowned Devices first, with [20] Menu\n");
1077 return 0; // normal case
1080 // select two devices for unlinking pairwise devices
1081 int dev_num[2] = {0};
1082 if(selectTwoDiffNum(&(dev_num[0]), &(dev_num[1]), g_own_cnt, "for Unlinking Devices"))
1084 OIC_LOG(ERROR, TAG, "selectTwoDiffNum error return");
1088 // call |OCUnlinkDevices| API actually
1089 // calling this API with callback actually acts like blocking
1090 // for error checking, the return value saved and printed
1092 printf(" Unlinking Selected Pairwise Devices..\n");
1094 OCUnlinkDevices((void*) g_ctx,
1095 getDevInst((const OCProvisionDev_t*) g_own_list, dev_num[0]),
1096 getDevInst((const OCProvisionDev_t*) g_own_list, dev_num[1]),
1098 if(OC_STACK_OK != rst)
1100 OIC_LOG_V(ERROR, TAG, "OCUnlinkDevices API error: %d", rst);
1103 if(waitCallbackRet()) // input |g_doneCB| flag implicitly
1105 OIC_LOG(ERROR, TAG, "OCProvisionCredentials callback error");
1109 // display the pairwise-unlinked result
1110 printf(" > Unlinked Selected Pairwise Devices\n");
1111 printf(" > Please Check Device's Status for the Unlinked Result, with [33] Menu\n");
1116 static int removeDevice(void)
1118 // check |own_list| for removing device
1119 if(!g_own_list || 1>g_own_cnt)
1121 printf(" > Owned Device List, to Remove Device, is Empty\n");
1122 printf(" > Please Register Unowned Devices first, with [20] Menu\n");
1123 return 0; // normal case
1126 // select device for removing it
1130 printf(" > Enter Device Number, for Removing Device: ");
1131 for(int ret=0; 1!=ret; )
1133 ret = scanf("%d", &dev_num);
1134 for( ; 0x20<=getchar(); ); // for removing overflow garbages
1135 // '0x20<=code' is character region
1137 if(0<dev_num && g_own_cnt>=dev_num)
1141 printf(" Entered Wrong Number. Please Enter Again\n");
1144 // call |OCRemoveDevice| API actually
1145 // calling this API with callback actually acts like blocking
1146 // for error checking, the return value saved and printed
1148 printf(" Removing Selected Owned Device..\n");
1150 OCRemoveDevice((void*) g_ctx, DISCOVERY_TIMEOUT,
1151 getDevInst((const OCProvisionDev_t*) g_own_list, dev_num), removeDeviceCB);
1152 if(OC_STACK_OK != rst)
1154 OIC_LOG_V(ERROR, TAG, "OCRemoveDevice API error: %d", rst);
1157 if(waitCallbackRet()) // input |g_doneCB| flag implicitly
1159 OIC_LOG(ERROR, TAG, "OCProvisionCredentials callback error");
1163 // display the removed result
1164 printf(" > Removed Selected Owned Device\n");
1165 printf(" > Please Discover Owned Devices for the Registered Result, with [10|12] Menu\n");
1170 static int removeDeviceWithUuid(void)
1172 char strUuid[64] = {0};
1174 printf("Input the UUID : ");
1175 for(int ret=0; 1!=ret; )
1177 ret = scanf("%63s", strUuid);
1178 for( ; 0x20<=getchar(); ); // for removing overflow garbages
1179 // '0x20<=code' is character region
1181 OCStackResult rst = ConvertStrToUuid(strUuid, &revUuid);
1182 if(OC_STACK_OK != rst)
1184 OIC_LOG_V(ERROR, TAG, "ConvertStrToUuid API error: %d", rst);
1189 rst = OCRemoveDeviceWithUuid("RemoveDeviceWithUUID", DISCOVERY_TIMEOUT, &revUuid, removeDeviceCB);
1190 if(OC_STACK_OK != rst)
1192 OIC_LOG_V(ERROR, TAG, "OCRemoveDeviceWithUuid API error: %d", rst);
1196 if(waitCallbackRet()) // input |g_doneCB| flag implicitly
1198 OIC_LOG(ERROR, TAG, "OCRemoveDeviceWithUuid callback error");
1202 // display the removed result
1203 printf(" > Removed %s Device\n", strUuid);
1204 printf(" > Please Discover Owned Devices for the Registered Result, with [10|12] Menu\n");
1209 #ifdef _ENABLE_MULTIPLE_OWNER_
1210 static int changeMultipleOwnershipTrnasferMode(void)
1212 // check |own_list| for removing device
1213 if(!g_own_list || 1>g_own_cnt)
1215 printf(" > Owned Device List is Empty\n");
1216 printf(" > Please Discover the Owned Devices, with [12] Menu\n");
1217 return 0; // normal case
1220 // select device for removing it
1224 printf(" > Enter Device Number, for MOT Device: ");
1225 for(int ret=0; 1!=ret; )
1227 ret = scanf("%d", &dev_num);
1228 for( ; 0x20<=getchar(); ); // for removing overflow garbages
1229 // '0x20<=code' is character region
1231 if(0<dev_num && g_own_cnt>=dev_num)
1235 printf(" Entered Wrong Number. Please Enter Again\n");
1241 printf(" 0. Disable Multuple Ownership Transfer\n");
1242 printf(" 1. Enable Multuple Ownership Transfer\n");
1243 printf(" 2. (Not Supported yet) Timely Enable Multuple Ownership Transfer\n");
1244 printf(" > Enter Mode of Multuple Ownership Transfer : ");
1245 for(int ret=0; 1!=ret; )
1247 ret = scanf("%d", &mom);
1248 for( ; 0x20<=getchar(); ); // for removing overflow garbages
1249 // '0x20<=code' is character region
1251 if(0 <= dev_num && OIC_NUMBER_OF_MOM_TYPE > dev_num)
1255 printf(" Entered Wrong Number. Please Enter Again\n");
1258 OCProvisionDev_t* motDev = getDevInst(g_own_list, dev_num);
1259 if(OC_STACK_OK == OCChangeMOTMode(NULL, motDev, (OicSecMomType_t)dev_num, updateDoxmForMOTCB))
1265 OIC_LOG(ERROR, TAG, "OCChangeMOTMode API error");
1269 if(waitCallbackRet()) // input |g_doneCB| flag implicitly
1271 OIC_LOG(ERROR, TAG, "waitCallbackRet callback error");
1278 static int selectMultipleOwnershipTrnasferMethod(void)
1280 // check |own_list| for removing device
1281 if(!g_mot_enable_list || 1>g_mot_enable_cnt)
1283 printf(" > Multiple Ownership Transfer Enabled Device List is Empty\n");
1284 printf(" > Please Discover the Multiple Ownership Transfer Enabled Devices, with [13] Menu\n");
1285 return 0; // normal case
1288 // select device for removing it
1292 printf(" > Enter Device Number, for MOT Device: ");
1293 for(int ret=0; 1!=ret; )
1295 ret = scanf("%d", &dev_num);
1296 for( ; 0x20<=getchar(); ); // for removing overflow garbages
1297 // '0x20<=code' is character region
1299 if(0<dev_num && g_mot_enable_cnt>=dev_num)
1303 printf(" Entered Wrong Number. Please Enter Again\n");
1306 const int preconfOxm = 4;
1310 printf(" %d. (Not Supported)\n", OIC_JUST_WORKS);
1311 printf(" %d. Random PIN OxM\n", OIC_RANDOM_DEVICE_PIN);
1312 printf(" %d. (Not Supported)\n", OIC_MANUFACTURER_CERTIFICATE);
1313 printf(" %d. (Not Supported)\n", OIC_DECENTRALIZED_PUBLIC_KEY);
1314 printf(" %d. Pre-Configured PIN OxM\n", OIC_PRECONFIG_PIN);
1315 printf(" > Enter Number of OxM for Multiple Ownership Transfer : ");
1316 for(int ret=0; 1!=ret; )
1318 ret = scanf("%d", &oxm);
1319 for( ; 0x20<=getchar(); ); // for removing overflow garbages
1320 // '0x20<=code' is character region
1322 if(OIC_PRECONFIG_PIN == oxm || OIC_RANDOM_DEVICE_PIN == oxm)
1326 printf(" Entered Wrong Number. Please Enter Again\n");
1329 OCProvisionDev_t* motDev = getDevInst(g_mot_enable_list, dev_num);
1330 if(OC_STACK_OK == OCSelectMOTMethod(NULL, motDev, (OicSecOxm_t)oxm, updateDoxmForMOTCB))
1336 OIC_LOG(ERROR, TAG, "OCSelectMOTMethod API error");
1340 if(waitCallbackRet()) // input |g_doneCB| flag implicitly
1342 OIC_LOG(ERROR, TAG, "waitCallbackRet callback error");
1349 static int provisionPreconfigPIN()
1351 // check |own_list| for removing device
1352 if(!g_mot_enable_list || 1>g_mot_enable_cnt)
1354 printf(" > Multiple Ownership Transfer Enabled Device List is Empty\n");
1355 printf(" > Please Discover the Multiple Ownership Transfer Enabled Devices, with [13] Menu\n");
1356 return 0; // normal case
1359 // select device for removing it
1363 printf(" > Enter Device Number, for MOT Device: ");
1364 for(int ret=0; 1!=ret; )
1366 ret = scanf("%d", &dev_num);
1367 for( ; 0x20<=getchar(); ); // for removing overflow garbages
1368 // '0x20<=code' is character region
1370 if(0<dev_num && g_mot_enable_cnt>=dev_num)
1374 printf(" Entered Wrong Number. Please Enter Again\n");
1377 char preconfigPin[9] = {0};
1378 printf(" > Input the PreconfigPin (e.g. 12341234) : ");
1379 for(int ret=0; 1!=ret; )
1381 ret = scanf("%8s", preconfigPin);
1382 for( ; 0x20<=getchar(); ); // for removing overflow garbages
1383 // '0x20<=code' is character region
1386 OCProvisionDev_t* motDev = getDevInst(g_mot_enable_list, dev_num);
1387 if(OC_STACK_OK == OCProvisionPreconfigPin(NULL, motDev, preconfigPin, strlen(preconfigPin), provisionCredCB))
1393 OIC_LOG(ERROR, TAG, "OCProvisionPreconfigPin API error");
1397 if(waitCallbackRet()) // input |g_doneCB| flag implicitly
1399 OIC_LOG(ERROR, TAG, "waitCallbackRet callback error");
1405 #endif //_ENABLE_MULTIPLE_OWNER_
1407 static int resetDevice(void)
1409 // check |own_list| for removing device
1410 if (!g_own_list || 1 > g_own_cnt)
1412 printf(" > Owned Device List, to Reset Device, is Empty\n");
1413 printf(" > Please Register Unowned Devices first, with [20] Menu\n");
1417 // select device for removing it
1421 printf(" > Enter Device Number, for Resetting Device: ");
1422 for (int ret = 0; 1 != ret; )
1424 ret = scanf("%d", &dev_num);
1425 for ( ; 0x20 <= getchar() ; ); // for removing overflow garbages
1426 // '0x20 <= code' is character region
1428 if (0 < dev_num && g_own_cnt >= dev_num)
1432 printf(" Entered Wrong Number. Please Enter Again\n");
1436 printf(" Resetting Selected Owned Device..\n");
1438 OCStackResult rst = OCResetDevice((void *) g_ctx, DISCOVERY_TIMEOUT,
1439 getDevInst((const OCProvisionDev_t *) g_own_list, dev_num), syncDeviceCB);
1440 if (OC_STACK_OK != rst)
1442 OIC_LOG_V(ERROR, TAG, "OCResetDevice API error: %d", rst);
1446 if (waitCallbackRet()) // input |g_doneCB| flag implicitly
1448 OIC_LOG(ERROR, TAG, "OCProvisionCredentials callback error");
1452 // display the removed result
1453 printf(" > Reset Selected Owned Device SUCCEEDED\n");
1454 printf(" > Please Discover Owned Devices for the Registered Result, with [10|12] Menu\n");
1459 static OicSecAcl_t* createAcl(const int dev_num)
1461 if(0>=dev_num || g_own_cnt<dev_num)
1463 OIC_LOG(ERROR, TAG, "createAcl invalid parameters");
1464 return NULL; // not need to 'goto' |ERROR| before allocating |acl|
1467 // allocate memory for |acl| struct
1468 printf(" **** Create ACL for the Selected Device[%d]\n", dev_num);
1469 OicSecAcl_t* acl = (OicSecAcl_t*) OICCalloc(1, sizeof(OicSecAcl_t));
1472 OIC_LOG(ERROR, TAG, "createAcl: OICCalloc error return");
1473 return NULL; // not need to 'goto' |ERROR| before allocating |acl|
1475 OicSecAce_t* ace = (OicSecAce_t*) OICCalloc(1, sizeof(OicSecAce_t));
1478 OIC_LOG(ERROR, TAG, "createAcl: OICCalloc error return");
1479 return NULL; // not need to 'goto' |ERROR| before allocating |acl|
1481 LL_APPEND(acl->aces, ace);
1483 // enter |subject| device number
1487 printf(" > [A] Enter Subject Device Number: ");
1488 for(int ret=0; 1!=ret; )
1490 ret = scanf("%d", &num);
1491 for( ; 0x20<=getchar(); ); // for removing overflow garbages
1492 // '0x20<=code' is character region
1494 if(0<num && g_own_cnt>=num && dev_num!=num)
1498 printf(" Entered Wrong Number. Please Enter Again\n");
1501 OCProvisionDev_t* dev = getDevInst((const OCProvisionDev_t*)g_own_list, num);
1502 if(!dev || !dev->doxm)
1504 OIC_LOG(ERROR, TAG, "createAcl: device instance empty");
1507 memcpy(&ace->subjectuuid, &dev->doxm->deviceID, UUID_LENGTH);
1509 // enter number of |resources| in 'accessed' device
1512 printf(" > [B] Enter Number of Accessed Resources (under 16): ");
1513 // '16' is |ACL_RESRC_MAX_NUM|
1514 for(int ret=0; 1!=ret; )
1516 ret = scanf("%d", &num);
1517 for( ; 0x20<=getchar(); ); // for removing overflow garbages
1518 // '0x20<=code' is character region
1520 if(0<num && ACL_RESRC_MAX_NUM>=num)
1524 printf(" Entered Wrong Number. Please Enter under 16 Again\n");
1525 // '16' is |ACL_RESRC_MAX_NUM|
1528 // enter actually each 'accessed' |resources| name
1529 printf(" Enter Each Accessed Resource Name (each under 128 char)\n");
1530 // '128' is ACL_RESRC_MAX_LEN
1532 char rsrc_in[ACL_RESRC_MAX_LEN+1] = {0}; // '1' for null termination
1533 for(int i = 0; num > i; ++i)
1535 OicSecRsrc_t* rsrc = (OicSecRsrc_t*)OICCalloc(1, sizeof(OicSecRsrc_t));
1538 OIC_LOG(ERROR, TAG, "createAcl: OICCalloc error return");
1542 printf(" Enter Accessed Resource[%d] Name: (e.g. /a/led)", i+1);
1543 for(int ret=0; 1!=ret; )
1545 ret = scanf("%128s", rsrc_in); // '128' is ACL_RESRC_MAX_LEN
1546 for( ; 0x20<=getchar(); ); // for removing overflow garbages
1547 // '0x20<=code' is character region
1549 size_t len = strlen(rsrc_in)+1; // '1' for null termination
1550 rsrc->href = (char*) OICCalloc(len, sizeof(char));
1553 OIC_LOG(ERROR, TAG, "createAcl: OICCalloc error return");
1556 OICStrcpy(rsrc->href, len, rsrc_in);
1561 printf(" Enter Number of resource type for [%s] : ", rsrc->href);
1562 for(int ret=0; 1!=ret; )
1564 ret = scanf("%d", &arrLen);
1565 for( ; 0x20<=getchar(); ); // for removing overflow garbages
1566 // '0x20<=code' is character region
1568 if(ACL_RESRC_ARRAY_SIZE >= arrLen)
1572 printf(" Entered Wrong Number. Please Enter under %d Again\n", ACL_RESRC_ARRAY_SIZE);
1575 rsrc->typeLen = arrLen;
1576 rsrc->types = (char**)OICCalloc(arrLen, sizeof(char*));
1579 OIC_LOG(ERROR, TAG, "createAcl: OICCalloc error return");
1583 for(int i = 0; i < arrLen; i++)
1585 printf(" Enter ResourceType[%d] Name (e.g. core.led): ", i+1);
1586 for(int ret=0; 1!=ret; )
1588 ret = scanf("%128s", rsrc_in); // '128' is ACL_RESRC_MAX_LEN
1589 for( ; 0x20<=getchar(); ); // for removing overflow garbages
1590 // '0x20<=code' is character region
1592 rsrc->types[i] = OICStrdup(rsrc_in);
1595 OIC_LOG(ERROR, TAG, "createAcl: OICStrdup error return");
1602 printf(" Enter Number of interface for [%s]: ", rsrc->href);
1603 for(int ret=0; 1!=ret; )
1605 ret = scanf("%d", &arrLen);
1606 for( ; 0x20<=getchar(); ); // for removing overflow garbages
1607 // '0x20<=code' is character region
1609 if(ACL_RESRC_ARRAY_SIZE >= arrLen)
1613 printf(" Entered Wrong Number. Please Enter under %d Again\n", ACL_RESRC_ARRAY_SIZE);
1616 rsrc->interfaceLen = arrLen;
1617 rsrc->interfaces = (char**)OICCalloc(arrLen, sizeof(char*));
1618 if(!rsrc->interfaces)
1620 OIC_LOG(ERROR, TAG, "createAcl: OICCalloc error return");
1624 for(int i = 0; i < arrLen; i++)
1626 printf(" Enter Interface[%d] Name (e.g. oic.if.baseline): ", i+1);
1627 for(int ret=0; 1!=ret; )
1629 ret = scanf("%128s", rsrc_in); // '128' is ACL_RESRC_MAX_LEN
1630 for( ; 0x20<=getchar(); ); // for removing overflow garbages
1631 // '0x20<=code' is character region
1633 rsrc->interfaces[i] = OICStrdup(rsrc_in);
1634 if(!rsrc->interfaces[i])
1636 OIC_LOG(ERROR, TAG, "createAcl: OICStrdup error return");
1641 LL_APPEND(ace->resources, rsrc);
1644 // enter |permission| for this access
1645 printf(" > [C] Enter Permission for This Access\n");
1646 uint16_t pmsn = PERMISSION_FULL_CONTROL; // default full permission
1647 uint16_t pmsn_msk = PERMISSION_CREATE; // default permission mask
1648 for(int i=0; ACL_PEMISN_CNT>i; ++i)
1653 printf(" Enter %s Permission (y/n): ", ACL_PEMISN[i]);
1654 for(int ret=0; 1!=ret; )
1656 ret = scanf("%c", &ans);
1657 for( ; 0x20<=getchar(); ); // for removing overflow garbages
1658 // '0x20<=code' is character region
1660 if('y'==ans || 'Y'==ans || 'n'==ans|| 'N'==ans)
1662 ans &= ~0x20; // for masking lower case, 'y/n'
1665 printf(" Entered Wrong Answer. Please Enter 'y/n' Again\n");
1667 if('N' == ans) // masked lower case, 'n'
1673 ace->permission = pmsn;
1678 OCDeleteACLList(acl); // after here |acl| points nothing
1682 static OicSecAcl_t* createSimpleAcl(const OicUuid_t uuid)
1684 OIC_LOG(DEBUG, TAG, "createSimpleAcl IN");
1686 // allocate memory for |acl| struct
1687 OicSecAcl_t* acl = (OicSecAcl_t*) OICCalloc(1, sizeof(OicSecAcl_t));
1690 OIC_LOG(DEBUG, TAG, "OICCalloc error return");
1691 return NULL; // not need to 'goto' |ERROR| before allocating |acl|
1693 OicSecAce_t* ace = (OicSecAce_t*) OICCalloc(1, sizeof(OicSecAce_t));
1696 OIC_LOG(DEBUG, TAG, "OICCalloc error return");
1697 return NULL; // not need to 'goto' |ERROR| before allocating |acl|
1699 LL_APPEND(acl->aces, ace);
1701 memcpy(&ace->subjectuuid, &uuid, UUID_LENGTH);
1703 OicSecRsrc_t* rsrc = (OicSecRsrc_t*)OICCalloc(1, sizeof(OicSecRsrc_t));
1706 OIC_LOG(DEBUG, TAG, "OICCalloc error return");
1707 OCDeleteACLList(acl);
1712 size_t len = strlen(href)+1; // '1' for null termination
1713 rsrc->href = (char*) OICCalloc(len, sizeof(char));
1716 OIC_LOG(DEBUG, TAG, "OICCalloc error return");
1717 OCDeleteACLList(acl);
1720 OICStrcpy(rsrc->href, len, href);
1723 rsrc->typeLen = arrLen;
1724 rsrc->types = (char**)OICCalloc(arrLen, sizeof(char*));
1727 OIC_LOG(DEBUG, TAG, "OICCalloc error return");
1728 OCDeleteACLList(acl);
1731 rsrc->types[0] = OICStrdup(""); // ignore
1733 rsrc->interfaceLen = 1;
1734 rsrc->interfaces = (char**)OICCalloc(arrLen, sizeof(char*));
1735 if(!rsrc->interfaces)
1737 OIC_LOG(DEBUG, TAG, "OICCalloc error return");
1738 OCDeleteACLList(acl);
1741 rsrc->interfaces[0] = OICStrdup("oic.if.baseline"); // ignore
1743 LL_APPEND(ace->resources, rsrc);
1745 ace->permission = 31; // R/W/U/D
1747 OIC_LOG(DEBUG, TAG, "createSimpleAcl OUT");
1752 static OicSecPdAcl_t* createPdAcl(const int dev_num)
1754 if(0>=dev_num || g_own_cnt<dev_num)
1756 OIC_LOG(ERROR, TAG, "createAcl invalid parameters");
1757 return NULL; // not need to 'goto' |ERROR| before allocating |acl|
1760 // allocate memory for |pdacl| struct
1761 printf(" **** Create PDACL for the Selected Device[%d]\n", dev_num);
1762 OicSecPdAcl_t* pdAcl = (OicSecPdAcl_t*) OICCalloc(1, sizeof(OicSecPdAcl_t));
1765 OIC_LOG(ERROR, TAG, "createAcl: OICCalloc error return");
1766 return NULL; // not need to 'goto' |ERROR| before allocating |acl|
1770 // number of resources
1771 char rsrc_in[][ACL_RESRC_MAX_LEN+1] = {"*", "/rsrc/*"};
1772 pdAcl->resourcesLen = 1;
1775 int num = pdAcl->resourcesLen;
1776 pdAcl->resources = (char**) OICCalloc(num, sizeof(char*));
1777 if(!pdAcl->resources)
1779 OIC_LOG(ERROR, TAG, "createPdAcl: OICCalloc error return");
1782 for(int i=0; num>i; ++i)
1784 size_t len = strlen(rsrc_in[i])+1; // '1' for null termination
1785 char* rsrc = (char*) OICCalloc(len, sizeof(char));
1788 OIC_LOG(ERROR, TAG, "createPdAcl: OICCalloc error return");
1791 OICStrcpy(rsrc, len, rsrc_in[i]);
1792 pdAcl->resources[i] = rsrc; // after here, |rsrc| points nothing
1796 pdAcl->permission = PERMISSION_FULL_CONTROL;
1801 OCDeletePdAclList(pdAcl);
1805 static OCProvisionDev_t* getDevInst(const OCProvisionDev_t* dev_lst, const int dev_num)
1807 if(!dev_lst || 0>=dev_num)
1809 printf(" Device List is Empty..\n");
1813 OCProvisionDev_t* lst = (OCProvisionDev_t*) dev_lst;
1823 return NULL; // in here |lst| is always |NULL|
1826 static int printDevList(const OCProvisionDev_t* dev_lst)
1830 printf(" Device List is Empty..\n\n");
1834 OCProvisionDev_t* lst = (OCProvisionDev_t*) dev_lst;
1838 printf(" [%d] ", ++lst_cnt);
1839 printUuid((const OicUuid_t*) &lst->doxm->deviceID);
1848 static size_t printUuidList(const OCUuidList_t* uid_lst)
1852 printf(" Device List is Empty..\n\n");
1856 OCUuidList_t* lst = (OCUuidList_t*) uid_lst;
1860 printf(" [%zu] ", ++lst_cnt);
1861 printUuid((const OicUuid_t*) &lst->dev);
1870 static int printResultList(const OCProvisionResult_t* rslt_lst, const int rslt_cnt)
1872 if(!rslt_lst || 0>=rslt_cnt)
1874 printf(" Device List is Empty..\n\n");
1879 for( ; rslt_cnt>lst_cnt; ++lst_cnt)
1881 printf(" [%d] ", lst_cnt+1);
1882 printUuid((const OicUuid_t*) &rslt_lst[lst_cnt].deviceId);
1883 printf(" - result: %d\n", rslt_lst[lst_cnt].res);
1890 static void printUuid(const OicUuid_t* uid)
1892 for(int i=0; i<UUID_LENGTH; )
1894 printf("%02X", (*uid).id[i++]);
1895 if(i==4 || i==6 || i==8 || i==10) // canonical format for UUID has '8-4-4-4-12'
1902 static FILE* fopen_prvnMng(const char* path, const char* mode)
1904 (void)path; // unused |path| parameter
1906 // input |g_svr_db_fname| internally by force, not using |path| parameter
1907 // because |OCPersistentStorage::open| is called |OCPersistentStorage| internally
1908 // with its own |SVR_DB_FILE_NAME|
1909 return fopen(SVR_DB_FILE_NAME, mode);
1912 static int waitCallbackRet(void)
1914 for(int i=0; !g_doneCB && CALLBACK_TIMEOUT>i; ++i)
1917 if(OC_STACK_OK != OCProcess())
1919 OIC_LOG(ERROR, TAG, "OCStack process error");
1927 static int selectTwoDiffNum(int* a, int* b, const int max, const char* str)
1929 if(!a || !b || 2>max || !str)
1936 for(int i=0; 2>i; ++i)
1938 int* num = 0==i?a:b;
1941 printf(" > Enter Device[%d] Number, %s: ", i+1, str);
1942 for(int ret=0; 1!=ret; )
1944 ret = scanf("%d", num);
1945 for( ; 0x20<=getchar(); ); // for removing overflow garbages
1946 // '0x20<=code' is character region
1948 if(0<*num && max>=*num)
1952 printf(" Entered Wrong Number. Please Enter Again\n");
1967 static void setDevProtocol(OCProvisionDev_t* lst)
1971 printf(" Device List is Empty..\n\n");
1977 if(2 == secure_protocol)
1979 lst->connType &= ~CT_ADAPTER_IP; //reset IP flag
1980 lst->connType |= CT_ADAPTER_TCP; //set TCP flag
1981 lst->endpoint.adapter = OC_ADAPTER_TCP;
1982 lst->endpoint.port = lst->tcpPort;
1983 lst->securePort = lst->tcpPort;
1989 static void selectSecureProtocol()
1991 printf(" Select protocol\n");
1992 printf(" 1 - DTLS(Default)\n");
1993 printf(" 2 - TLS\n");
1995 for(int ret=0; 1!=ret; )
1997 ret = scanf("%d",&secure_protocol);
1998 for( ; 0x20<=getchar(); ); // for removing overflow garbages
1999 // '0x20<=code' is character region
2002 if(0 >= secure_protocol || 2 < secure_protocol)
2004 secure_protocol = 1;
2007 setDevProtocol(g_own_list);
2008 setDevProtocol(g_unown_list);
2012 static void printMenu(void)
2014 printf("************************************************************\n");
2015 printf("****** OIC Provisioning Client with using C-level API ******\n");
2016 printf("************************************************************\n\n");
2018 printf("** [A] DISCOVER DEVICES ON NETWORK\n");
2019 printf("** 10. Discover All Un/Owned Devices on Network\n");
2020 printf("** 11. Discover Only Unowned Devices on Network\n");
2021 #ifdef _ENABLE_MULTIPLE_OWNER_
2022 printf("** 12. Discover Only Owned Devices on Network\n");
2023 printf("** 13. Discover Multiple Ownership Transfer Enabled Devices on Network\n\n");
2025 printf("** 12. Discover Only Owned Devices on Network\n\n");
2026 #endif //_ENABLE_MULTIPLE_OWNER_
2028 printf("** [B] REGISTER/OWN ALL DISCOVERED UNOWNED DEVICES\n");
2029 printf("** 20. Register/Own All Discovered Unowned Devices\n\n");
2031 printf("** [C] PROVISION/LINK PAIRWISE THINGS\n");
2032 printf("** 30. Provision/Link Pairwise Things\n");
2033 printf("** 31. Provision Credentials for Pairwise Things\n");
2034 printf("** 32. Provision the Selected Access Control List(ACL)\n");
2035 printf("** 33. Provision Direct-Pairing Configuration\n");
2036 printf("** 34. Check Linked Status of the Selected Device on PRVN DB\n");
2037 printf("** 35. Save the Selected Access Control List(ACL) into local SVR DB\n\n");
2039 printf("** [D] UNLINK PAIRWISE THINGS\n");
2040 printf("** 40. Unlink Pairwise Things\n\n");
2042 printf("** [E] REMOVE THE SELECTED DEVICE\n");
2043 printf("** 50. Remove the Selected Device\n");
2044 printf("** 51. Remove Device with UUID (UUID input is required)\n");
2045 printf("** 52. Reset the Selected Device\n\n");
2047 printf("** [F] GET SECURITY RESOURCE FOR DEBUGGING ONLY\n");
2048 printf("** 60. Get the Credential resources of the Selected Device\n");
2049 printf("** 61. Get the ACL resources of the Selected Device\n\n");
2051 #ifdef _ENABLE_MULTIPLE_OWNER_
2052 printf("** [G] UPDATE THE MULTIPLE OWNERSHIP TRANSFER RELATED VALUE\n");
2053 printf("** 70. Change the Multiple Ownership transfer MODE(update mom)\n");
2054 printf("** 71. Provision Preconfigured PIN\n");
2055 printf("** 72. Change the Multiple Ownership transfer METHOD(update oxmsel)\n\n");
2056 #endif //_ENABLE_MULTIPLE_OWNER_
2059 printf("** [H] SELECT SECURE PROTOCOL DTLS/TLS\n");
2060 printf("** 80. Select secure protocol(default DTLS)\n\n");
2062 printf("** [I] EXIT PROVISIONING CLIENT\n");
2064 printf("** [H] EXIT PROVISIONING CLIENT\n");
2067 printf("** 99. Exit Provisionong Client\n\n");
2069 printf("************************************************************\n\n");
2072 #if 0 // Code for enabling path configuration for PDB and SVR DBf
2073 static void printUsage(void)
2076 printf("OIC Provisioning Client with using C-level API\n");
2077 printf("Usage: provisioningclient [option]...\n");
2079 printf(" -h print help for this provisioning client\n");
2080 printf(" -p=[prvn_db_file_path/name] input PRVN DB file path and name\n");
2081 printf(" if not exists, will load default DB file\n");
2082 printf(" (default: |oic_prvn_mng.db| on working dir)\n");
2083 printf(" (ex. -p=oic_prvn_mng.db)\n");
2084 printf(" -s=[svr_db_file_path/name] input SVR DB file path and name\n");
2085 printf(" if not exists, will load default DB file\n");
2086 printf(" (default: |oic_svr_db_client.json| on working dir)\n");
2087 printf(" (ex. -s=oic_svr_db_client.json)\n");
2092 // main function for provisioning client using C-level provisioning API
2095 // initialize provisioning client
2096 if(initProvisionClient())
2098 OIC_LOG(ERROR, TAG, "ProvisionClient init error");
2102 #ifdef _ENABLE_MULTIPLE_OWNER_
2103 SetPreconfigPin("12341234", 8);
2104 #endif //_ENABLE_MULTIPLE_OWNER_
2106 // main loop for provisioning manager
2112 printf(">> Enter Menu Number: ");
2113 for(int ret=0; 1!=ret; )
2115 ret = scanf("%d", &mn_num);
2116 for( ; 0x20<=getchar(); ); // for removing overflow garbages
2117 // '0x20<=code' is character region
2122 case _10_DISCOV_ALL_DEVS_:
2123 if(discoverAllDevices())
2125 OIC_LOG(ERROR, TAG, "_10_DISCOV_ALL_DEVS_: error");
2128 case _11_DISCOV_UNOWN_DEVS_:
2129 if(discoverUnownedDevices())
2131 OIC_LOG(ERROR, TAG, "_11_DISCOV_UNOWN_DEVS_: error");
2134 case _12_DISCOV_OWN_DEVS_:
2135 if(discoverOwnedDevices())
2137 OIC_LOG(ERROR, TAG, "_12_DISCOV_OWN_DEVS_: error");
2140 #ifdef _ENABLE_MULTIPLE_OWNER_
2141 case _13_MOT_DISCOV_DEV_:
2142 if(discoverMOTEnabledDevices())
2144 OIC_LOG(ERROR, TAG, "_13_MOT_DISCOV_DEV_: error");
2147 #endif //_ENABLE_MULTIPLE_OWNER_
2148 case _20_REGIST_DEVS_:
2149 if(registerDevices())
2151 OIC_LOG(ERROR, TAG, "_20_REGIST_DEVS_: error");
2154 case _30_PROVIS_PAIR_DEVS_:
2155 if(provisionPairwise())
2157 OIC_LOG(ERROR, TAG, "_30_PROVIS_PAIR_DEVS_: error");
2160 case _31_PROVIS_CRED_:
2163 OIC_LOG(ERROR, TAG, "_31_PROVIS_CRED_: error");
2166 case _32_PROVIS_ACL_:
2169 OIC_LOG(ERROR, TAG, "_32_PROVIS_ACL_: error");
2172 case _33_PROVIS_DP_:
2173 if(provisionDirectPairing())
2175 OIC_LOG(ERROR, TAG, "_33_PROVIS_DP_: error");
2178 case _34_CHECK_LINK_STATUS_:
2179 if(checkLinkedStatus())
2181 OIC_LOG(ERROR, TAG, "_34_CHECK_LINK_STATUS_: error");
2187 OIC_LOG(ERROR, TAG, "_35_SAVE_ACL_: error");
2190 case _40_UNLINK_PAIR_DEVS_:
2191 if(unlinkPairwise())
2193 OIC_LOG(ERROR, TAG, "_40_UNLINK_PAIR_DEVS_: error");
2196 case _50_REMOVE_SELEC_DEV_:
2199 OIC_LOG(ERROR, TAG, "_50_REMOVE_SELEC_DEV_: error");
2202 case _51_REMOVE_DEV_WITH_UUID_:
2203 if(removeDeviceWithUuid())
2205 OIC_LOG(ERROR, TAG, "_51_REMOVE_DEV_WITH_UUID_: error");
2208 case _52_RESET_SELEC_DEV_:
2211 OIC_LOG(ERROR, TAG, "_52_RESET_SELEC_DEV_: error");
2217 OIC_LOG(ERROR, TAG, "_60_GET_CRED_: error");
2223 OIC_LOG(ERROR, TAG, "_61_GET_ACL_: error");
2226 #ifdef _ENABLE_MULTIPLE_OWNER_
2227 case _70_MOT_CHANGE_MOM_:
2228 if(changeMultipleOwnershipTrnasferMode())
2230 OIC_LOG(ERROR, TAG, "_70_MOT_CHANGE_MOM_: error");
2233 case _71_MOT_PROV_PRECONF_PIN_:
2234 if(provisionPreconfigPIN())
2236 OIC_LOG(ERROR, TAG, "_71_MOT_PROV_PRECONF_PIN_: error");
2239 case _72_MOT_OXM_SEL_:
2240 if(selectMultipleOwnershipTrnasferMethod())
2242 OIC_LOG(ERROR, TAG, "_72_MOT_OXM_SEL_: error");
2245 #endif //_ENABLE_MULTIPLE_OWNER_
2247 case _80_SELECT_PROTOCOL_:
2248 selectSecureProtocol();
2251 case _99_EXIT_PRVN_CLT_:
2254 printf(">> Entered Wrong Number. Please Enter Again\n\n");
2260 if(OC_STACK_OK != OCStop())
2262 OIC_LOG(ERROR, TAG, "OCStack stop error");
2264 OCDeleteDiscoveredDevices(g_own_list); // after here |g_own_list| points nothing
2265 OCDeleteDiscoveredDevices(g_unown_list); // after here |g_unown_list| points nothing
2266 #ifdef _ENABLE_MULTIPLE_OWNER_
2267 OCDeleteDiscoveredDevices(g_mot_enable_list); // after here |g_motdev_list| points nothing
2268 #endif //_ENABLE_MULTIPLE_OWNER_
2272 OICFree(g_svr_fname); // after here |g_svr_fname| points nothing
2276 OICFree(g_prvn_fname); // after here |g_prvn_fname| points nothing
2278 return 0; // always return normal case
2283 #endif //__cplusplus