Update snapshot(2018-02-14)
[platform/upstream/iotivity.git] / resource / csdk / security / provisioning / sample / provisioningclient.c
1 /******************************************************************
2  *
3  * Copyright 2015 Samsung Electronics All Rights Reserved.
4  *
5  *
6  *
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
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
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.
18  *
19  *****************************************************************/
20
21 #include "iotivity_config.h"
22
23 #include <stdio.h>
24 #include <string.h>
25 #ifdef HAVE_UNISTD_H
26 #include <unistd.h>
27 #endif
28
29 #include "utlist.h"
30 #include "logger.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"
38 #include "pmtypes.h"
39 #include "oxmverifycommon.h"
40 #include "pkix_interface.h"
41 #include "hw_emul/hw_interface.h"
42 #include "mbedtls/x509_crt.h"
43 #include "secureresourceprovider.h"
44
45 #ifdef __cplusplus
46 extern "C"
47 {
48 #endif //__cplusplus
49
50 // declaration(s) for provisioning client using C-level provisioning API
51 // user input definition for main loop on provisioning client
52 #define _10_DISCOV_ALL_DEVS_            10
53 #define _11_DISCOV_UNOWN_DEVS_          11
54 #define _12_DISCOV_OWN_DEVS_            12
55 #ifdef MULTIPLE_OWNER
56 #define _13_MOT_DISCOV_DEV_             13
57 #endif //MULTIPLE_OWNER
58 #define _20_REGIST_DEVS_                20
59 #define _30_PROVIS_PAIR_DEVS_           30
60 #define _31_PROVIS_CRED_                31
61 #define _32_PROVIS_ACL_                 32
62 #define _33_PROVIS_DP_                  33
63 #define _34_CHECK_LINK_STATUS_          34
64 #define _35_SAVE_ACL_                   35
65 #define _40_UNLINK_PAIR_DEVS_           40
66 #define _50_REMOVE_SELEC_DEV_           50
67 #define _51_REMOVE_DEV_WITH_UUID_       51
68 #define _52_RESET_SELEC_DEV_            52
69 #define _53_RESET_SVR_DB_               53
70 #define _60_GET_CRED_                   60
71 #define _61_GET_ACL_                    61
72 #ifdef MULTIPLE_OWNER
73 #define _70_MOT_CHANGE_MOM_             70
74 #define _71_MOT_PROV_PRECONF_PIN_       71
75 #define _72_MOT_OXM_SEL_                72
76 #define _73_MOT_REMOVE_SUBOWNER_        73
77 #define _74_MOT_REMOVE_ALL_SUBOWNER_        74
78 #endif //MULTIPLE_OWNER
79 #define _80_SELECT_PROTOCOL_            80
80 #define _81_SELECT_VERIF_METHOD_        81
81 #define _82_SECURE_STORAGE_HW_EMULATION_    82
82 #define _99_EXIT_PRVN_CLT_              99
83
84 #define ACL_RESRC_MAX_NUM   16
85 #define ACL_RESRC_ARRAY_SIZE   3 //This value is used only for sample (not OCF spec)
86 #define ACL_RESRC_MAX_LEN   128
87 #define ACL_PEMISN_CNT      5
88 #define DISCOVERY_TIMEOUT   10  // 10 sec
89 #define CALLBACK_TIMEOUT    60  // 1 min
90 #define TAG "provisioningclient"
91
92 static const char* ACL_PEMISN[5] = {"CREATE", "READ", "WRITE", "DELETE", "NOTIFY"};
93 static const char* SVR_DB_FILE_NAME = "oic_svr_db_client.dat";
94         // '_' for separaing from the same constant variable in |srmresourcestrings.c|
95 static const char* PRVN_DB_FILE_NAME = "oic_prvn_mng.db";
96 static const OicSecPrm_t  SUPPORTED_PRMS[1] =
97 {
98     PRM_PRE_CONFIGURED,
99 };
100
101 // |g_ctx| means provision manager application context and
102 // the following, includes |un/own_list|, could be variables, which |g_ctx| has,
103 // for accessing all function(s) for these, they are declared on global domain
104 static const char* g_ctx = "Provision Manager Client Application Context";
105 static char* g_svr_fname;
106 static char* g_prvn_fname;
107 static OCProvisionDev_t* g_own_list;
108 static OCProvisionDev_t* g_unown_list;
109 static int g_own_cnt;
110 static int g_unown_cnt;
111 #ifdef MULTIPLE_OWNER
112 static OCProvisionDev_t* g_mot_enable_list;
113 static int g_mot_enable_cnt;
114 #endif //MULTIPLE_OWNER
115
116 static bool g_doneCB;
117 #ifdef __WITH_TLS__
118 static int secure_protocol = 1;
119 static void setDevProtocol(OCProvisionDev_t* dev_lst);
120 #endif
121 // function declaration(s) for calling them before implementing
122 static OicSecAcl_t* createAcl(const int);
123 static OicSecAcl_t* createSimpleAcl(const OicUuid_t uuid);
124 static OicSecPdAcl_t* createPdAcl(const int);
125 static OCProvisionDev_t* getDevInst(const OCProvisionDev_t*, const int);
126 static int printDevList(const OCProvisionDev_t*);
127 static size_t printUuidList(const OCUuidList_t*);
128 static int printResultList(const OCProvisionResult_t*, const int);
129 static void printUuid(const OicUuid_t*);
130 static FILE* fopen_prvnMng(const char*, const char*);
131 static int waitCallbackRet(void);
132 static int selectTwoDiffNum(int*, int*, const int, const char*);
133
134 // callback function(s) for provisioning client using C-level provisioning API
135 static void ownershipTransferCB(void* ctx, int nOfRes, OCProvisionResult_t* arr, bool hasError)
136 {
137     if(!hasError)
138     {
139         OIC_LOG_V(INFO, TAG, "Ownership Transfer SUCCEEDED - ctx: %s", (char*) ctx);
140     }
141     else
142     {
143         OIC_LOG_V(ERROR, TAG, "Ownership Transfer FAILED - ctx: %s", (char*) ctx);
144         printResultList((const OCProvisionResult_t*) arr, nOfRes);
145     }
146     g_doneCB = true;
147 }
148
149 static void provisionPairwiseCB(void* ctx, int nOfRes, OCProvisionResult_t* arr, bool hasError)
150 {
151     if(!hasError)
152     {
153         OIC_LOG_V(INFO, TAG, "Provision Pairwise SUCCEEDED - ctx: %s", (char*) ctx);
154     }
155     else
156     {
157         OIC_LOG_V(ERROR, TAG, "Provision Pairwise FAILED - ctx: %s", (char*) ctx);
158         printResultList((const OCProvisionResult_t*) arr, nOfRes);
159     }
160     g_doneCB = true;
161 }
162
163 static void provisionCredCB(void* ctx, int nOfRes, OCProvisionResult_t* arr, bool hasError)
164 {
165     if(!hasError)
166     {
167         OIC_LOG_V(INFO, TAG, "Provision Credential SUCCEEDED - ctx: %s", (char*) ctx);
168     }
169     else
170     {
171         OIC_LOG_V(ERROR, TAG, "Provision Credential FAILED - ctx: %s", (char*) ctx);
172         printResultList((const OCProvisionResult_t*) arr, nOfRes);
173     }
174     g_doneCB = true;
175 }
176
177 static void provisionAclCB(void* ctx, int nOfRes, OCProvisionResult_t* arr, bool hasError)
178 {
179     if(!hasError)
180     {
181         OIC_LOG_V(INFO, TAG, "Provision ACL SUCCEEDED - ctx: %s", (char*) ctx);
182     }
183     else
184     {
185         OIC_LOG_V(ERROR, TAG, "Provision ACL FAILED - ctx: %s", (char*) ctx);
186         printResultList((const OCProvisionResult_t*) arr, nOfRes);
187     }
188     g_doneCB = true;
189 }
190
191 static void getCredCB(void* ctx, int nOfRes, OCProvisionResult_t* arr, bool hasError)
192 {
193     if(!hasError)
194     {
195         OIC_LOG_V(INFO, TAG, "getCredCB SUCCEEDED - ctx: %s", (char*) ctx);
196     }
197     else
198     {
199         OIC_LOG_V(ERROR, TAG, "getCredCB FAILED - ctx: %s", (char*) ctx);
200         printResultList((const OCProvisionResult_t*) arr, nOfRes);
201     }
202     g_doneCB = true;
203 }
204
205 static void getAclCB(void* ctx, int nOfRes, OCProvisionResult_t* arr, bool hasError)
206 {
207     if(!hasError)
208     {
209         OIC_LOG_V(INFO, TAG, "getAclCB SUCCEEDED - ctx: %s", (char*) ctx);
210     }
211     else
212     {
213         OIC_LOG_V(ERROR, TAG, "getAclCB FAILED - ctx: %s", (char*) ctx);
214         printResultList((const OCProvisionResult_t*) arr, nOfRes);
215     }
216     g_doneCB = true;
217 }
218
219 static void provisionDPCB(void* ctx, int nOfRes, OCProvisionResult_t* arr, bool hasError)
220 {
221     if(!hasError)
222     {
223         OIC_LOG_V(INFO, TAG, "Provision Direct-Pairing SUCCEEDED - ctx: %s", (char*) ctx);
224     }
225     else
226     {
227         OIC_LOG_V(ERROR, TAG, "Provision Direct-Pairing FAILED - ctx: %s", (char*) ctx);
228         printResultList((const OCProvisionResult_t*) arr, nOfRes);
229     }
230     g_doneCB = true;
231 }
232
233 static void unlinkDevicesCB(void* ctx, int nOfRes, OCProvisionResult_t* arr, bool hasError)
234 {
235     if(!hasError)
236     {
237         OIC_LOG_V(INFO, TAG, "Unlink Devices SUCCEEDED - ctx: %s", (char*) ctx);
238     }
239     else
240     {
241         OIC_LOG_V(ERROR, TAG, "Unlink Devices FAILED - ctx: %s", (char*) ctx);
242         printResultList((const OCProvisionResult_t*) arr, nOfRes);
243     }
244     g_doneCB = true;
245 }
246
247 static void removeDeviceCB(void* ctx, int nOfRes, OCProvisionResult_t* arr, bool hasError)
248 {
249     if(!hasError)
250     {
251         OIC_LOG_V(INFO, TAG, "Remove Device SUCCEEDED - ctx: %s", (char*) ctx);
252     }
253     else
254     {
255         OIC_LOG_V(ERROR, TAG, "Remove Device FAILED - ctx: %s", (char*) ctx);
256         printResultList((const OCProvisionResult_t*) arr, nOfRes);
257     }
258     g_doneCB = true;
259 }
260
261 static void resetDeviceCB(void* ctx)
262 {
263     OC_UNUSED(ctx);
264     OIC_LOG_V(INFO, TAG, "Reset Device SUCCEEDED");
265     g_doneCB = true;
266 }
267
268 #ifdef MULTIPLE_OWNER
269 static void updateDoxmForMOTCB(void* ctx, int nOfRes, OCProvisionResult_t* arr, bool hasError)
270 {
271     if(!hasError)
272     {
273         OIC_LOG_V(INFO, TAG, "POST 'doxm' SUCCEEDED - ctx: %s", (char*) ctx);
274     }
275     else
276     {
277         OIC_LOG_V(ERROR, TAG, "POST 'doxm'  FAILED - ctx: %s", (char*) ctx);
278         printResultList((const OCProvisionResult_t*) arr, nOfRes);
279     }
280     g_doneCB = true;
281 }
282
283 static void deleteDoxmForMOTCB(void* ctx, int nOfRes, OCProvisionResult_t* arr, bool hasError)
284 {
285     if(!hasError)
286     {
287         OIC_LOG_V(INFO, TAG, "DELETE 'doxm' SUCCEEDED - ctx: %s", (char*) ctx);
288     }
289     else
290     {
291         OIC_LOG_V(ERROR, TAG, "DELETE 'doxm'  FAILED - ctx: %s", (char*) ctx);
292         printResultList((const OCProvisionResult_t*) arr, nOfRes);
293     }
294     g_doneCB = true;
295 }
296
297 #endif //MULTIPLE_OWNER
298
299 static void inputPinCB(char* pin, size_t len)
300 {
301     if(!pin || OXM_RANDOM_PIN_MIN_SIZE > len)
302     {
303         OIC_LOG(ERROR, TAG, "inputPinCB invalid parameters");
304         return;
305     }
306
307     printf("   > INPUT PIN: ");
308     for(int ret=0; 1!=ret; )
309     {
310         ret = scanf("%32s", pin);
311         for( ; 0x20<=getchar(); );  // for removing overflow garbages
312                                     // '0x20<=code' is character region
313     }
314 }
315
316 // function(s) for provisioning client using C-level provisioning API
317 static int initProvisionClient(void)
318 {
319     // initialize persistent storage for SVR DB
320     static OCPersistentStorage pstStr =
321     {
322         .open = fopen_prvnMng,
323         .read = fread,
324         .write = fwrite,
325         .close = fclose,
326         .unlink = unlink
327     };
328     if(OC_STACK_OK != OCRegisterPersistentStorageHandler(&pstStr))
329     {
330         OIC_LOG(ERROR, TAG, "OCRegisterPersistentStorageHandler error");
331         return -1;
332     }
333
334     // initialize OC stack and provisioning manager
335     if(OC_STACK_OK != OCInit(NULL, 0, OC_CLIENT_SERVER))
336     {
337         OIC_LOG(ERROR, TAG, "OCStack init error");
338         return -1;
339     }
340
341     if (access(PRVN_DB_FILE_NAME, F_OK) != -1)
342     {
343         printf("************************************************************\n");
344         printf("************Provisioning DB file already exists.************\n");
345         printf("************************************************************\n");
346     }
347     else
348     {
349         printf("*************************************************************\n");
350         printf("************No provisioning DB file, creating new************\n");
351         printf("*************************************************************\n");
352     }
353
354     if(OC_STACK_OK != OCInitPM(PRVN_DB_FILE_NAME))
355     {
356         OIC_LOG(ERROR, TAG, "OC_PM init error");
357         return -1;
358     }
359
360     SetInputPinCB(inputPinCB);
361
362     return 0;
363 }
364
365 static int discoverAllDevices(void)
366 {
367     // delete un/owned device lists before updating them
368     if(g_own_list)
369     {
370         OCDeleteDiscoveredDevices(g_own_list);
371         g_own_list = NULL;
372     }
373     if(g_unown_list)
374     {
375         OCDeleteDiscoveredDevices(g_unown_list);
376         g_unown_list = NULL;
377     }
378
379     // call |OCGetDevInfoFromNetwork| API actually
380     printf("   Discovering All Un/Owned Devices on Network..\n");
381     if(OC_STACK_OK != OCGetDevInfoFromNetwork(DISCOVERY_TIMEOUT, &g_own_list, &g_unown_list))
382     {
383         OIC_LOG(ERROR, TAG, "OCGetDevInfoFromNetwork API error");
384         return -1;
385     }
386
387     // display the discovered un/owned lists
388     printf("   > Discovered Owned Devices\n");
389     g_own_cnt = printDevList(g_own_list);
390     printf("   > Discovered Unowned Devices\n");
391     g_unown_cnt = printDevList(g_unown_list);
392 #ifdef __WITH_TLS__
393     setDevProtocol(g_own_list);
394     setDevProtocol(g_unown_list);
395 #endif
396     return 0;
397 }
398
399
400 static int discoverUnownedDevices(void)
401 {
402     // delete unowned device list before updating it
403     if(g_unown_list)
404     {
405         OCDeleteDiscoveredDevices(g_unown_list);
406         g_unown_list = NULL;
407     }
408
409     // call |OCDiscoverUnownedDevices| API actually
410     printf("   Discovering Only Unowned Devices on Network..\n");
411     if(OC_STACK_OK != OCDiscoverUnownedDevices(DISCOVERY_TIMEOUT, &g_unown_list))
412     {
413         OIC_LOG(ERROR, TAG, "OCDiscoverUnownedDevices API error");
414         return -1;
415     }
416
417     // display the discovered unowned list
418     printf("   > Discovered Unowned Devices\n");
419     g_unown_cnt = printDevList(g_unown_list);
420 #ifdef __WITH_TLS__
421     setDevProtocol(g_unown_list);
422 #endif
423     return 0;
424 }
425
426 static int discoverOwnedDevices(void)
427 {
428     // delete owned device list before updating it
429     if(g_own_list)
430     {
431         OCDeleteDiscoveredDevices(g_own_list);
432         g_own_list = NULL;
433     }
434
435     // call |OCDiscoverOwnedDevices| API actually
436     printf("   Discovering Only Owned Devices on Network..\n");
437     if(OC_STACK_OK != OCDiscoverOwnedDevices(DISCOVERY_TIMEOUT, &g_own_list))
438     {
439         OIC_LOG(ERROR, TAG, "OCDiscoverOwnedDevices API error");
440         return -1;
441     }
442
443     // display the discovered owned list
444     printf("   > Discovered Owned Devices\n");
445     g_own_cnt = printDevList(g_own_list);
446 #ifdef __WITH_TLS__
447     setDevProtocol(g_own_list);
448 #endif
449     return 0;
450 }
451
452 #ifdef MULTIPLE_OWNER
453 static int discoverMOTEnabledDevices(void)
454 {
455     // delete owned device list before updating it
456     if(g_mot_enable_list)
457     {
458         OCDeleteDiscoveredDevices(g_mot_enable_list);
459         g_mot_enable_list = NULL;
460     }
461
462     // call |OCDiscoverOwnedDevices| API actually
463     printf("   Discovering Multiple Ownership Transfer Enabled Devices on Network..\n");
464     if(OC_STACK_OK != OCDiscoverMultipleOwnerEnabledDevices(DISCOVERY_TIMEOUT, &g_mot_enable_list))
465     {
466         OIC_LOG(ERROR, TAG, "OCDiscoverMultipleOwnerEnalbedDevices API error");
467         return -1;
468     }
469
470     // display the discovered owned list
471     printf("   > Discovered Multiple Ownership Transfer Enabled Devices\n");
472     g_mot_enable_cnt = printDevList(g_mot_enable_list);
473
474     return 0;
475 }
476 #endif //MULTIPLE_OWNER
477
478 static int registerDevices(void)
479 {
480     // check |unown_list| for registering devices
481     if(!g_unown_list || 0>=g_unown_cnt)
482     {
483         printf("   > Unowned Device List, to Register Devices, is Empty\n");
484         printf("   > Please Discover Unowned Devices first, with [10|11] Menu\n");
485         return 0;  // normal case
486     }
487
488     // call |OCDoOwnershipTransfer| API actually
489     // calling this API with callback actually acts like blocking
490     // for error checking, the return value saved and printed
491     g_doneCB = false;
492     printf("   Registering All Discovered Unowned Devices..\n");
493     OCStackResult rst = OCDoOwnershipTransfer((void*) g_ctx, g_unown_list, ownershipTransferCB);
494     if(OC_STACK_OK != rst)
495     {
496         OIC_LOG_V(ERROR, TAG, "OCDoOwnershipTransfer API error: %d", rst);
497         return -1;
498     }
499     if(waitCallbackRet())  // input |g_doneCB| flag implicitly
500     {
501         OIC_LOG(ERROR, TAG, "OCProvisionCredentials callback error");
502         return -1;
503     }
504
505     // display the registered result
506     printf("   > Registered Discovered Unowned Devices\n");
507     printf("   > Please Discover Owned Devices for the Registered Result, with [10|12] Menu\n");
508
509     return 0;
510 }
511
512 static int provisionPairwise(void)
513 {
514     // check |own_list| for provisioning pairwise devices
515     if(!g_own_list || 2>g_own_cnt)
516     {
517         printf("   > Owned Device List, to Provision the Pairwise, is Empty\n");
518         printf("   > Please Register Unowned Devices first, with [20] Menu\n");
519         return 0;  // normal case
520     }
521
522     // select two devices for provisioning pairwise devices
523     int dev_num[2] = {0};
524     if(selectTwoDiffNum(&(dev_num[0]), &(dev_num[1]), g_own_cnt, "for Linking Devices"))
525     {
526         OIC_LOG(ERROR, TAG, "selectTwoDiffNum error return");
527         return -1;  // not need to 'goto' |ERROR| before allocating |acl|
528     }
529
530     // create ACL(s) for each selected device
531     OicSecAcl_t* acl[2] = {0};
532     for(int i=0; 2>i; ++i)
533     {
534         acl[i] = createAcl(dev_num[i]);
535         if(!acl[i])
536         {
537             OIC_LOG(ERROR, TAG, "createAcl error return");
538             goto PVPWS_ERROR;
539         }
540     }
541
542     // call |OCProvisionPairwiseDevices| API actually
543     // calling this API with callback actually acts like blocking
544     // for error checking, the return value saved and printed
545     g_doneCB = false;
546     printf("   Provisioning Selected Pairwise Devices..\n");
547     OCStackResult rst =
548             OCProvisionPairwiseDevices((void*) g_ctx,
549                     SYMMETRIC_PAIR_WISE_KEY, OWNER_PSK_LENGTH_128,
550                     getDevInst((const OCProvisionDev_t*) g_own_list, dev_num[0]), acl[0],
551                     getDevInst((const OCProvisionDev_t*) g_own_list, dev_num[1]), acl[1],
552                     provisionPairwiseCB);
553     if(OC_STACK_OK != rst)
554     {
555         OIC_LOG_V(ERROR, TAG, "OCProvisionPairwiseDevices API error: %d", rst);
556         goto PVPWS_ERROR;
557     }
558     if(waitCallbackRet())  // input |g_doneCB| flag implicitly
559     {
560         OIC_LOG(ERROR, TAG, "OCProvisionCredentials callback error");
561         goto PVPWS_ERROR;
562     }
563     OCDeleteACLList(acl[0]);
564     OCDeleteACLList(acl[1]);
565
566     // display the pairwise-provisioned result
567     printf("   > Provisioned Selected Pairwise Devices\n");
568     printf("   > Please Check Device's Status for the Linked Result, with [33] Menu\n");
569
570     return 0;
571
572 PVPWS_ERROR:
573     OCDeleteACLList(acl[0]);
574     OCDeleteACLList(acl[1]);
575     return -1;
576 }
577
578 static int provisionCred(void)
579 {
580     // check |own_list| for provisioning pairwise credentials
581     if(!g_own_list || 2>g_own_cnt)
582     {
583         printf("   > Owned Device List, to Provision Credentials, is Empty\n");
584         printf("   > Please Register Unowned Devices first, with [20] Menu\n");
585         return 0;  // normal case
586     }
587
588     // select two devices for provisioning pairwise credentials
589     int dev_num[2] = {0};
590     if(selectTwoDiffNum(&(dev_num[0]), &(dev_num[1]), g_own_cnt, "for Linking CRED(s)"))
591     {
592         OIC_LOG(ERROR, TAG, "selectTwoDiffNum error return");
593         return -1;
594     }
595
596     printf("   Select PSK length..\n");
597     printf("   1 - 128bit(Default)\n");
598     printf("   2 - 256bit\n");
599     int sizeOption = 0;
600
601     for(int ret=0; 1!=ret; )
602     {
603          ret = scanf("%d",&sizeOption);
604          for( ; 0x20<=getchar(); );  // for removing overflow garbages
605                                     // '0x20<=code' is character region
606     }
607     size_t size = 0;
608
609     switch(sizeOption)
610     {
611         case 1:
612         {
613             size = OWNER_PSK_LENGTH_128;
614             break;
615         }
616         case 2:
617         {
618             size = OWNER_PSK_LENGTH_256;
619             break;
620         }
621         default:
622         {
623             size = OWNER_PSK_LENGTH_128;
624             break;
625         }
626     }
627
628
629     // call |OCProvisionCredentials| API actually
630     // calling this API with callback actually acts like blocking
631     // for error checking, the return value saved and printed
632     g_doneCB = false;
633     printf("   Provisioning Selected Pairwise Credentials..\n");
634     OCStackResult rst =
635             OCProvisionCredentials((void*) g_ctx,
636                     SYMMETRIC_PAIR_WISE_KEY, size,
637                     getDevInst((const OCProvisionDev_t*) g_own_list, dev_num[0]),
638                     getDevInst((const OCProvisionDev_t*) g_own_list, dev_num[1]),
639                     provisionCredCB);
640     if(OC_STACK_OK != rst)
641     {
642         OIC_LOG_V(ERROR, TAG, "OCProvisionCredentials API error: %d", rst);
643         return -1;
644     }
645     if(waitCallbackRet())  // input |g_doneCB| flag implicitly
646     {
647         OIC_LOG(ERROR, TAG, "OCProvisionCredentials callback error");
648         return -1;
649     }
650
651     // display the CRED-provisioned result
652     printf("   > Provisioned Selected Pairwise Crendentials\n");
653     printf("   > Please Check Device's Status for the Linked Result, with [34] Menu\n");
654
655     return 0;
656 }
657
658 static int provisionAcl(void)
659 {
660     // check |own_list| for provisioning access control list
661     if(!g_own_list || 1>g_own_cnt)
662     {
663         printf("   > Owned Device List, to Provision ACL, is Empty\n");
664         printf("   > Please Register Unowned Devices first, with [20] Menu\n");
665         return 0;  // normal case
666     }
667
668     // select device for provisioning access control list
669     int dev_num = 0;
670     for( ; ; )
671     {
672         printf("   > Enter Device Number, for Provisioning ACL: ");
673         for(int ret=0; 1!=ret; )
674         {
675             ret = scanf("%d", &dev_num);
676             for( ; 0x20<=getchar(); );  // for removing overflow garbages
677                                         // '0x20<=code' is character region
678         }
679         if(0<dev_num && g_own_cnt>=dev_num)
680         {
681             break;
682         }
683         printf("     Entered Wrong Number. Please Enter Again\n");
684     }
685
686     // create ACL for selected device
687     OicSecAcl_t* acl = NULL;
688     acl = createAcl(dev_num);
689     if(!acl)
690     {
691         OIC_LOG(ERROR, TAG, "createAcl error return");
692         goto PVACL_ERROR;
693     }
694
695     // call |OCProvisionACL| API actually
696     // calling this API with callback actually acts like blocking
697     // for error checking, the return value saved and printed
698     g_doneCB = false;
699     printf("   Provisioning Selected ACL..\n");
700     OCProvisionDev_t* dev = getDevInst((const OCProvisionDev_t*) g_own_list, dev_num);
701     if(!dev)
702     {
703         OIC_LOG(ERROR, TAG, "provisionAcl: device instance empty");
704         goto PVACL_ERROR;
705     }
706     OCStackResult rst = OCProvisionACL((void*) g_ctx, dev, acl, provisionAclCB);
707     if(OC_STACK_OK != rst)
708     {
709         OIC_LOG_V(ERROR, TAG, "OCProvisionACL API error: %d", rst);
710         goto PVACL_ERROR;
711     }
712     if(waitCallbackRet())  // input |g_doneCB| flag implicitly
713     {
714         OIC_LOG(ERROR, TAG, "OCProvisionCredentials callback error");
715         goto PVACL_ERROR;
716     }
717     OCDeleteACLList(acl);  // after here |acl| points nothing
718
719     // display the ACL-provisioned result
720     printf("   > Provisioned Selected ACL\n");
721
722     return 0;
723
724 PVACL_ERROR:
725     OCDeleteACLList(acl);  // after here |acl| points nothing
726     return -1;
727 }
728
729 static int provisionDirectPairing(void)
730 {
731     // check |own_list| for provisioning direct-pairing
732     if(!g_own_list || 1>g_own_cnt)
733     {
734         printf("   > Owned Device List, to Provision ACL, is Empty\n");
735         printf("   > Please Register Unowned Devices first, with [20] Menu\n");
736         return 0;  // normal case
737     }
738
739     // select device for provisioning direct-pairing
740     int dev_num = 0;
741     for( ; ; )
742     {
743         printf("   > Enter Device Number, for Provisioning Direct-Pairing: ");
744         for(int ret=0; 1!=ret; )
745         {
746             ret = scanf("%d", &dev_num);
747             for( ; 0x20<=getchar(); );  // for removing overflow garbages
748                                         // '0x20<=code' is character region
749         }
750         if(0<dev_num && g_own_cnt>=dev_num)
751         {
752             break;
753         }
754         printf("     Entered Wrong Number. Please Enter Again\n");
755     }
756
757     // create Direct-Pairing Configuration(PIN, PDACL) for selected device
758     // TODO: default acl -> input from user !
759     OicSecPconf_t pconf;
760     memset(&pconf, 0, sizeof(OicSecPconf_t));
761
762     // set enable dp
763     pconf.edp = true;
764
765     // set default supported PRM types
766     pconf.prmLen = sizeof(SUPPORTED_PRMS)/sizeof(OicSecPrm_t);
767     pconf.prm = (OicSecPrm_t *)OICCalloc(pconf.prmLen, sizeof(OicSecPrm_t));
768     if(pconf.prm)
769     {
770         for (size_t i=0; i<pconf.prmLen; i++)
771         {
772             pconf.prm[i] = SUPPORTED_PRMS[i];
773         }
774     }
775     else
776     {
777         OIC_LOG(ERROR, TAG, "create prm error return");
778         goto PVDP_ERROR;
779     }
780
781     // set default pin
782     const char DP_DEFAULT_PIN[] = "00000000";
783     memcpy(pconf.pin.val, DP_DEFAULT_PIN, DP_PIN_LENGTH);
784
785     // set default pdacl
786     pconf.pdacls = createPdAcl(dev_num);
787     if(!pconf.pdacls)
788     {
789         OIC_LOG(ERROR, TAG, "createPdAcl error return");
790         goto PVDP_ERROR;
791     }
792
793     // call |OCProvisionDirectPairing| API actually
794     // calling this API with callback actually acts like blocking
795     // for error checking, the return value saved and printed
796     g_doneCB = false;
797     printf("   Atempt Direct-Pairing Provisioning (PIN : [%s])..\n", (char*)pconf.pin.val);
798     OCStackResult rst = OCProvisionDirectPairing((void*) g_ctx,
799                                        getDevInst((const OCProvisionDev_t*) g_own_list, dev_num),
800                                        &pconf, provisionDPCB);
801     if(OC_STACK_OK != rst)
802     {
803         OIC_LOG_V(ERROR, TAG, "OCProvisionDirectPairing API error: %d", rst);
804         if (OC_STACK_UNAUTHORIZED_REQ == rst)
805         {
806             OIC_LOG(ERROR, TAG, "Target Server NOT Support Direct-Pairing !!! (DPC == false)");
807         }
808         goto PVDP_ERROR;
809     }
810     if(waitCallbackRet())  // input |g_doneCB| flag implicitly
811     {
812         OIC_LOG(ERROR, TAG, "OCProvisionCredentials callback error");
813         goto PVDP_ERROR;
814     }
815     OCDeletePdAclList(pconf.pdacls);
816
817     // display the PCONF-provisioned result
818     printf("   > SUCCESS to provision Direct-Pairing !!\n");
819
820     return 0;
821
822 PVDP_ERROR:
823     OCDeletePdAclList(pconf.pdacls);  // after here |acl| points nothing
824     return -1;
825 }
826
827 static int checkLinkedStatus(void)
828 {
829     // check |own_list| for checking selected link status on PRVN DB
830     if(!g_own_list || 1>g_own_cnt)
831     {
832         printf("   > Owned Device List, to Check Linked Status on PRVN DB, is Empty\n");
833         printf("   > Please Register Unowned Devices first, with [20] Menu\n");
834         return 0;  // normal case
835     }
836
837     // select device for checking selected link status on PRVN DB
838     int dev_num = 0;
839     for( ; ; )
840     {
841         printf("   > Enter Device Number, for Checking Linked Status on PRVN DB: ");
842         for(int ret=0; 1!=ret; )
843         {
844             ret = scanf("%d", &dev_num);
845             for( ; 0x20<=getchar(); );  // for removing overflow garbages
846                                         // '0x20<=code' is character region
847         }
848         if(0<dev_num && g_own_cnt>=dev_num)
849         {
850             break;
851         }
852         printf("     Entered Wrong Number. Please Enter Again\n");
853     }
854
855     // call |OCGetLinkedStatus| API actually
856     printf("   Checking Selected Link Status on PRVN DB..\n");
857     OCUuidList_t* dvid_lst = NULL;
858     size_t dvid_cnt = 0;
859     OCProvisionDev_t* dev = getDevInst((const OCProvisionDev_t*)g_own_list, dev_num);
860     if(!dev || !dev->doxm)
861     {
862         OIC_LOG(ERROR, TAG, "checkLinkedStatus: device instance empty");
863         goto CKLST_ERROR;
864     }
865
866     if(OC_STACK_OK !=
867             OCGetLinkedStatus(
868                     &dev->doxm->deviceID,
869                     &dvid_lst, &dvid_cnt))  // allow empty list
870     {
871         OIC_LOG(ERROR, TAG, "OCGetLinkedStatus API error");
872         goto CKLST_ERROR;
873     }
874
875     // display the linked status result
876     printf("   > Checked Selected Link Status on PRVN DB\n");
877     if(!dvid_lst || !dvid_cnt)  // |size_t| is unsigned
878     {
879         printf("     Linked Device List is Empty..\n");
880         return 0;  // normal case
881     }
882     if(dvid_cnt != printUuidList((const OCUuidList_t*) dvid_lst))
883     {
884         OIC_LOG(ERROR, TAG, "printUuidList error return");
885         goto CKLST_ERROR;
886     }
887     OCDeleteUuidList(dvid_lst);
888
889     return 0;
890
891 CKLST_ERROR:
892     OCDeleteUuidList(dvid_lst);
893     return -1;
894 }
895
896 static int saveAcl(void)
897 {
898     // create ACL to save into local SVR DB
899     OicSecAcl_t* acl = NULL;
900     OicUuid_t uuid =   {.id={0}};
901     char strUuid[64] = {0};
902
903     printf("[1] Use a test UUID [11111111-2222-3333-4444-555555555555]\n");
904     printf("[2] Use a user input\n");
905     int sel_num = 0;
906     for( ; ; )
907     {
908         printf("   > Select Number, for Subject UUID of new ACE: ");
909         for(int ret=0; 1!=ret; )
910         {
911             ret = scanf("%d", &sel_num);
912             for( ; 0x20<=getchar(); );  // for removing overflow garbages
913                                         // '0x20<=code' is character region
914         }
915         if(1 == sel_num)
916         {
917             OICStrcpy(strUuid, sizeof(strUuid), "11111111-2222-3333-4444-555555555555");
918             break;
919         }
920         else if(2 == sel_num)
921         {
922             printf("   > Input the UUID : ");
923             for(int ret=0; 1!=ret; )
924             {
925                 ret = scanf("%64s", strUuid);
926                 for( ; 0x20<=getchar(); );  // for removing overflow garbages
927                                         // '0x20<=code' is character region
928             }
929             break;
930         }
931         printf("     Entered Wrong Number. Please Enter Again\n");
932     }
933
934
935     printf("Selected Subject UUID : %s\n", strUuid);
936     OCStackResult rst = ConvertStrToUuid(strUuid, &uuid);
937     if(OC_STACK_OK != rst)
938     {
939         OIC_LOG_V(ERROR, TAG, "ConvertStrToUuid API error: %d", rst);
940         goto SVACL_ERROR;
941     }
942
943     acl = createSimpleAcl(uuid);
944     if(!acl)
945     {
946         OIC_LOG(ERROR, TAG, "createAcl error return");
947         goto SVACL_ERROR;
948     }
949
950     // call |OCSaveACL| API actually
951     rst = OCSaveACL(acl);
952     if(OC_STACK_OK != rst)
953     {
954         OIC_LOG_V(ERROR, TAG, "OCSaveACL API error: %d", rst);
955         goto SVACL_ERROR;
956     }
957     OCDeleteACLList(acl);  // after here |acl| points nothing
958
959     // display the ACL-provisioned result
960     printf("   > Saved Selected ACL\n");
961
962     return 0;
963
964 SVACL_ERROR:
965     OCDeleteACLList(acl);  // after here |acl| points nothing
966     return -1;
967 }
968
969 static int getCred(void)
970 {
971     // check |own_list| for checking selected link status on PRVN DB
972     if(!g_own_list || 1>g_own_cnt)
973     {
974         printf("   > Owned Device List, to Check Linked Status on PRVN DB, is Empty\n");
975         printf("   > Please Register Unowned Devices first, with [20] Menu\n");
976         return 0;  // normal case
977     }
978
979     // select device for checking selected link status on PRVN DB
980     int dev_num = 0;
981     for( ; ; )
982     {
983         printf("   > Enter Device Number, for Checking Linked Status on PRVN DB: ");
984         for(int ret=0; 1!=ret; )
985         {
986             ret = scanf("%d", &dev_num);
987             for( ; 0x20<=getchar(); );  // for removing overflow garbages
988                                         // '0x20<=code' is character region
989         }
990         if(0<dev_num && g_own_cnt>=dev_num)
991         {
992             break;
993         }
994         printf("     Entered Wrong Number. Please Enter Again\n");
995     }
996
997     // call |getDevInst| API actually
998     // calling this API with callback actually acts like blocking
999     // for error checking, the return value saved and printed
1000     g_doneCB = false;
1001     OCProvisionDev_t* dev = getDevInst((const OCProvisionDev_t*) g_own_list, dev_num);
1002     if(!dev)
1003     {
1004         OIC_LOG(ERROR, TAG, "getDevInst: device instance empty");
1005         goto PVACL_ERROR;
1006     }
1007     OCStackResult rst = OCGetCredResource((void*) g_ctx, dev, getCredCB);
1008     if(OC_STACK_OK != rst)
1009     {
1010         OIC_LOG_V(ERROR, TAG, "OCGetCred API error: %d", rst);
1011         goto PVACL_ERROR;
1012     }
1013     if(waitCallbackRet())  // input |g_doneCB| flag implicitly
1014     {
1015         OIC_LOG(ERROR, TAG, "OCGetCredResource callback error");
1016         goto PVACL_ERROR;
1017     }
1018
1019     // display the result of get credential
1020     printf("   > Get Cred SUCCEEDED\n");
1021
1022     return 0;
1023
1024 PVACL_ERROR:
1025     return -1;
1026 }
1027
1028 static int getAcl(void)
1029 {
1030     // check |own_list| for checking selected link status on PRVN DB
1031     if(!g_own_list || 1>g_own_cnt)
1032     {
1033         printf("   > Owned Device List, to Check Linked Status on PRVN DB, is Empty\n");
1034         printf("   > Please Register Unowned Devices first, with [20] Menu\n");
1035         return 0;  // normal case
1036     }
1037
1038     // select device for checking selected link status on PRVN DB
1039     int dev_num = 0;
1040     for( ; ; )
1041     {
1042         printf("   > Enter Device Number, for Checking Linked Status on PRVN DB: ");
1043         for(int ret=0; 1!=ret; )
1044         {
1045             ret = scanf("%d", &dev_num);
1046             for( ; 0x20<=getchar(); );  // for removing overflow garbages
1047                                         // '0x20<=code' is character region
1048         }
1049         if(0<dev_num && g_own_cnt>=dev_num)
1050         {
1051             break;
1052         }
1053         printf("     Entered Wrong Number. Please Enter Again\n");
1054     }
1055
1056     // call |getDevInst| API actually
1057     // calling this API with callback actually acts like blocking
1058     // for error checking, the return value saved and printed
1059     g_doneCB = false;
1060     OCProvisionDev_t* dev = getDevInst((const OCProvisionDev_t*) g_own_list, dev_num);
1061     if(!dev)
1062     {
1063         OIC_LOG(ERROR, TAG, "getDevInst: device instance empty");
1064         goto PVACL_ERROR;
1065     }
1066     OCStackResult rst = OCGetACLResource((void*) g_ctx, dev, getAclCB);
1067     if(OC_STACK_OK != rst)
1068     {
1069         OIC_LOG_V(ERROR, TAG, "OCGetACLResource API error: %d", rst);
1070
1071         goto PVACL_ERROR;
1072     }
1073     if(waitCallbackRet())  // input |g_doneCB| flag implicitly
1074     {
1075         OIC_LOG(ERROR, TAG, "OCGetACLResource callback error");
1076         goto PVACL_ERROR;
1077     }
1078
1079     // display the result of get credential
1080     printf("   > Get ACL SUCCEEDED\n");
1081
1082     return 0;
1083
1084 PVACL_ERROR:
1085     return -1;
1086 }
1087
1088 static int unlinkPairwise(void)
1089 {
1090     // check |own_list| for unlinking pairwise devices
1091     if(!g_own_list || 2>g_own_cnt)
1092     {
1093         printf("   > Owned Device List, to Unlink the Pairwise, is Empty\n");
1094         printf("   > Please Register Unowned Devices first, with [20] Menu\n");
1095         return 0;  // normal case
1096     }
1097
1098     // select two devices for unlinking pairwise devices
1099     int dev_num[2] = {0};
1100     if(selectTwoDiffNum(&(dev_num[0]), &(dev_num[1]), g_own_cnt, "for Unlinking Devices"))
1101     {
1102         OIC_LOG(ERROR, TAG, "selectTwoDiffNum error return");
1103         return -1;
1104     }
1105
1106     // call |OCUnlinkDevices| API actually
1107     // calling this API with callback actually acts like blocking
1108     // for error checking, the return value saved and printed
1109     g_doneCB = false;
1110     printf("   Unlinking Selected Pairwise Devices..\n");
1111     OCStackResult rst =
1112             OCUnlinkDevices((void*) g_ctx,
1113                     getDevInst((const OCProvisionDev_t*) g_own_list, dev_num[0]),
1114                     getDevInst((const OCProvisionDev_t*) g_own_list, dev_num[1]),
1115                     unlinkDevicesCB);
1116     if(OC_STACK_OK != rst)
1117     {
1118         OIC_LOG_V(ERROR, TAG, "OCUnlinkDevices API error: %d", rst);
1119         return -1;
1120     }
1121     if(waitCallbackRet())  // input |g_doneCB| flag implicitly
1122     {
1123         OIC_LOG(ERROR, TAG, "OCProvisionCredentials callback error");
1124         return -1;
1125     }
1126
1127     // display the pairwise-unlinked result
1128     printf("   > Unlinked Selected Pairwise Devices\n");
1129     printf("   > Please Check Device's Status for the Unlinked Result, with [33] Menu\n");
1130
1131     return 0;
1132 }
1133
1134 static int removeDevice(void)
1135 {
1136     // check |own_list| for removing device
1137     if(!g_own_list || 1>g_own_cnt)
1138     {
1139         printf("   > Owned Device List, to Remove Device, is Empty\n");
1140         printf("   > Please Register Unowned Devices first, with [20] Menu\n");
1141         return 0;  // normal case
1142     }
1143
1144     // select device for removing it
1145     int dev_num = 0;
1146     for( ; ; )
1147     {
1148         printf("   > Enter Device Number, for Removing Device: ");
1149         for(int ret=0; 1!=ret; )
1150         {
1151             ret = scanf("%d", &dev_num);
1152             for( ; 0x20<=getchar(); );  // for removing overflow garbages
1153                                         // '0x20<=code' is character region
1154         }
1155         if(0<dev_num && g_own_cnt>=dev_num)
1156         {
1157             break;
1158         }
1159         printf("     Entered Wrong Number. Please Enter Again\n");
1160     }
1161
1162     // call |OCRemoveDevice| API actually
1163     // calling this API with callback actually acts like blocking
1164     // for error checking, the return value saved and printed
1165     g_doneCB = false;
1166     printf("   Removing Selected Owned Device..\n");
1167     OCStackResult rst =
1168             OCRemoveDevice((void*) g_ctx, DISCOVERY_TIMEOUT,
1169                     getDevInst((const OCProvisionDev_t*) g_own_list, dev_num), removeDeviceCB);
1170     if(OC_STACK_OK != rst)
1171     {
1172         OIC_LOG_V(ERROR, TAG, "OCRemoveDevice API error: %d", rst);
1173         return -1;
1174     }
1175     if(waitCallbackRet())  // input |g_doneCB| flag implicitly
1176     {
1177         OIC_LOG(ERROR, TAG, "OCProvisionCredentials callback error");
1178         return -1;
1179     }
1180
1181     // display the removed result
1182     printf("   > Removed Selected Owned Device\n");
1183     printf("   > Please Discover Owned Devices for the Registered Result, with [10|12] Menu\n");
1184
1185     return 0;
1186 }
1187
1188 static int removeDeviceWithUuid(void)
1189 {
1190     char strUuid[64] = {0};
1191     OicUuid_t revUuid;
1192     printf("Input the UUID : ");
1193     for(int ret=0; 1!=ret; )
1194     {
1195         ret = scanf("%63s", strUuid);
1196         for( ; 0x20<=getchar(); );  // for removing overflow garbages
1197                                     // '0x20<=code' is character region
1198     }
1199     OCStackResult rst = ConvertStrToUuid(strUuid, &revUuid);
1200     if(OC_STACK_OK != rst)
1201     {
1202         OIC_LOG_V(ERROR, TAG, "ConvertStrToUuid API error: %d", rst);
1203         return -1;
1204     }
1205
1206     g_doneCB = false;
1207     rst = OCRemoveDeviceWithUuid("RemoveDeviceWithUUID", DISCOVERY_TIMEOUT, &revUuid, removeDeviceCB);
1208     if(OC_STACK_OK != rst)
1209     {
1210         OIC_LOG_V(ERROR, TAG, "OCRemoveDeviceWithUuid API error: %d", rst);
1211         return -1;
1212     }
1213
1214     if(waitCallbackRet())  // input |g_doneCB| flag implicitly
1215     {
1216         OIC_LOG(ERROR, TAG, "OCRemoveDeviceWithUuid callback error");
1217         return -1;
1218     }
1219
1220     // display the removed result
1221     printf("   > Removed %s Device\n", strUuid);
1222     printf("   > Please Discover Owned Devices for the Registered Result, with [10|12] Menu\n");
1223
1224     return 0;
1225 }
1226
1227 OCStackResult displayNumCB(void * ctx, uint8_t mutualVerifNum[MUTUAL_VERIF_NUM_LEN])
1228 {
1229     OIC_LOG(INFO, TAG, "IN displayMutualVerifNumCB");
1230     OC_UNUSED(ctx);
1231     if (NULL != mutualVerifNum)
1232     {
1233         OIC_LOG(INFO, TAG, "############ mutualVerifNum ############");
1234         OIC_LOG_BUFFER(INFO, TAG, mutualVerifNum, MUTUAL_VERIF_NUM_LEN);
1235         OIC_LOG(INFO, TAG, "############ mutualVerifNum ############");
1236         OIC_LOG(INFO, TAG, "OUT displayMutualVerifNumCB");
1237     }
1238     else
1239     {
1240         OIC_LOG(INFO, TAG, "############ Confirm on the Server side ############");
1241     }
1242     return OC_STACK_OK;
1243 }
1244
1245 OCStackResult confirmNumCB(void * ctx)
1246 {
1247     OC_UNUSED(ctx);
1248     for (;;)
1249     {
1250         int userConfirm;
1251
1252         printf("   > Press 1 if the mutual verification numbers are the same\n");
1253         printf("   > Press 0 if the mutual verification numbers are not the same\n");
1254
1255         for (int ret=0; 1!=ret; )
1256         {
1257             ret = scanf("%d", &userConfirm);
1258             for (; 0x20<=getchar(); );  // for removing overflow garbage
1259                                         // '0x20<=code' is character region
1260         }
1261         if (1 == userConfirm)
1262         {
1263             break;
1264         }
1265         else if (0 == userConfirm)
1266         {
1267             return OC_STACK_USER_DENIED_REQ;
1268         }
1269         printf("   Entered Wrong Number. Please Enter Again\n");
1270     }
1271     return OC_STACK_OK;
1272 }
1273
1274 OCStackResult notifyInputStateCB(void * ctx)
1275 {
1276     OC_UNUSED(ctx);
1277
1278     OIC_LOG(DEBUG, TAG, "IN notifyInputStateCB");
1279     OIC_LOG(DEBUG, TAG, "User input Callback in progress");
1280     OIC_LOG(DEBUG, TAG, "OUT notifyInputStateCB");
1281
1282     return OC_STACK_OK;
1283 }
1284
1285 #ifdef MULTIPLE_OWNER
1286 static int changeMultipleOwnershipTrnasferMode(void)
1287 {
1288     // check |own_list| for removing device
1289     if(!g_own_list || 1>g_own_cnt)
1290     {
1291         printf("   > Owned Device List is Empty\n");
1292         printf("   > Please Discover the Owned Devices, with [12] Menu\n");
1293         return 0;  // normal case
1294     }
1295
1296     // select device for removing it
1297     int dev_num = 0;
1298     for( ; ; )
1299     {
1300         printf("   > Enter Device Number, for MOT Device: ");
1301         for(int ret=0; 1!=ret; )
1302         {
1303             ret = scanf("%d", &dev_num);
1304             for( ; 0x20<=getchar(); );  // for removing overflow garbages
1305                                         // '0x20<=code' is character region
1306         }
1307         if(0<dev_num && g_own_cnt>=dev_num)
1308         {
1309             break;
1310         }
1311         printf("     Entered Wrong Number. Please Enter Again\n");
1312     }
1313
1314     int mom = 0;
1315     for( ; ; )
1316     {
1317         printf("   0. Disable Multuple Ownership Transfer\n");
1318         printf("   1. Enable Multuple Ownership Transfer\n");
1319         printf("   2. (Not Supported yet) Timely Enable Multuple Ownership Transfer\n");
1320         printf("   > Enter Mode of Multuple Ownership Transfer : ");
1321         for(int ret=0; 1!=ret; )
1322         {
1323             ret = scanf("%d", &mom);
1324             for( ; 0x20<=getchar(); );  // for removing overflow garbages
1325                                         // '0x20<=code' is character region
1326         }
1327         if(0 <= dev_num && OIC_NUMBER_OF_MOM_TYPE > dev_num)
1328         {
1329             break;
1330         }
1331         printf("     Entered Wrong Number. Please Enter Again\n");
1332     }
1333
1334     OCProvisionDev_t* motDev = getDevInst(g_own_list, dev_num);
1335     if(OC_STACK_OK == OCChangeMOTMode(NULL, motDev, (OicSecMomType_t)dev_num, updateDoxmForMOTCB))
1336     {
1337         g_doneCB = false;
1338     }
1339     else
1340     {
1341         OIC_LOG(ERROR, TAG, "OCChangeMOTMode API error");
1342         return -1;
1343     }
1344
1345     if(waitCallbackRet())  // input |g_doneCB| flag implicitly
1346     {
1347         OIC_LOG(ERROR, TAG, "waitCallbackRet callback error");
1348         return -1;
1349     }
1350
1351     return 0;
1352 }
1353
1354 static int selectMultipleOwnershipTrnasferMethod(void)
1355 {
1356     // check |own_list| for removing device
1357     if(!g_mot_enable_list || 1>g_mot_enable_cnt)
1358     {
1359         printf("   > Multiple Ownership Transfer Enabled Device List is Empty\n");
1360         printf("   > Please Discover the Multiple Ownership Transfer Enabled Devices, with [13] Menu\n");
1361         return 0;  // normal case
1362     }
1363
1364     // select device for removing it
1365     int dev_num = 0;
1366     for( ; ; )
1367     {
1368         printf("   > Enter Device Number, for MOT Device: ");
1369         for(int ret=0; 1!=ret; )
1370         {
1371             ret = scanf("%d", &dev_num);
1372             for( ; 0x20<=getchar(); );  // for removing overflow garbages
1373                                         // '0x20<=code' is character region
1374         }
1375         if(0<dev_num && g_mot_enable_cnt>=dev_num)
1376         {
1377             break;
1378         }
1379         printf("     Entered Wrong Number. Please Enter Again\n");
1380     }
1381
1382     const int preconfOxm = 4;
1383     int oxm = 0;
1384     for( ; ; )
1385     {
1386         printf("   %d. (Not Supported)\n", OIC_JUST_WORKS);
1387         printf("   %d. Random PIN OxM\n", OIC_RANDOM_DEVICE_PIN);
1388         printf("   %d. (Not Supported)\n", OIC_MANUFACTURER_CERTIFICATE);
1389         printf("   %d. (Not Supported)\n", OIC_DECENTRALIZED_PUBLIC_KEY);
1390         printf("   %d. Pre-Configured PIN OxM\n", OIC_PRECONFIG_PIN);
1391         printf("   > Enter Number of  OxM for Multiple Ownership Transfer : ");
1392         for(int ret=0; 1!=ret; )
1393         {
1394             ret = scanf("%d", &oxm);
1395             for( ; 0x20<=getchar(); );  // for removing overflow garbages
1396                                         // '0x20<=code' is character region
1397         }
1398         if(OIC_PRECONFIG_PIN == oxm || OIC_RANDOM_DEVICE_PIN == oxm)
1399         {
1400             break;
1401         }
1402         printf("     Entered Wrong Number. Please Enter Again\n");
1403     }
1404
1405     OCProvisionDev_t* motDev = getDevInst(g_mot_enable_list, dev_num);
1406     if(OC_STACK_OK ==  OCSelectMOTMethod(NULL, motDev, (OicSecOxm_t)oxm, updateDoxmForMOTCB))
1407     {
1408         g_doneCB = false;
1409     }
1410     else
1411     {
1412         OIC_LOG(ERROR, TAG, "OCSelectMOTMethod API error");
1413         return -1;
1414     }
1415
1416     if(waitCallbackRet())  // input |g_doneCB| flag implicitly
1417     {
1418         OIC_LOG(ERROR, TAG, "waitCallbackRet callback error");
1419         return -1;
1420     }
1421
1422     return 0;
1423 }
1424
1425 static int provisionPreconfigPIN()
1426 {
1427     // check |own_list| for removing device
1428     if(!g_mot_enable_list || 1>g_mot_enable_cnt)
1429     {
1430         printf("   > Multiple Ownership Transfer Enabled Device List is Empty\n");
1431         printf("   > Please Discover the Multiple Ownership Transfer Enabled Devices, with [13] Menu\n");
1432         return 0;  // normal case
1433     }
1434
1435     // select device for removing it
1436     int dev_num = 0;
1437     for( ; ; )
1438     {
1439         printf("   > Enter Device Number, for MOT Device: ");
1440         for(int ret=0; 1!=ret; )
1441         {
1442             ret = scanf("%d", &dev_num);
1443             for( ; 0x20<=getchar(); );  // for removing overflow garbages
1444                                         // '0x20<=code' is character region
1445         }
1446         if(0<dev_num && g_mot_enable_cnt>=dev_num)
1447         {
1448             break;
1449         }
1450         printf("     Entered Wrong Number. Please Enter Again\n");
1451     }
1452
1453     char preconfigPin[9] = {0};
1454     printf("   > Input the PreconfigPin (e.g. 12341234) : ");
1455     for(int ret=0; 1!=ret; )
1456     {
1457         ret = scanf("%8s", preconfigPin);
1458         for( ; 0x20<=getchar(); );  // for removing overflow garbages
1459                                     // '0x20<=code' is character region
1460     }
1461
1462     OCProvisionDev_t* motDev = getDevInst(g_mot_enable_list, dev_num);
1463     if(OC_STACK_OK == OCProvisionPreconfigPin(NULL, motDev, preconfigPin, strlen(preconfigPin), provisionCredCB))
1464     {
1465         g_doneCB = false;
1466     }
1467     else
1468     {
1469         OIC_LOG(ERROR, TAG, "OCProvisionPreconfigPin API error");
1470         return -1;
1471     }
1472
1473     if(waitCallbackRet())  // input |g_doneCB| flag implicitly
1474     {
1475         OIC_LOG(ERROR, TAG, "waitCallbackRet callback error");
1476         return -1;
1477     }
1478
1479     return 0;
1480 }
1481
1482 static int removeSubOwner(void)
1483 {
1484     // check |g_mot_enable_list| for removing sub-owner
1485     if (!g_mot_enable_list || 1 > g_mot_enable_cnt)
1486     {
1487         printf("   > Multiple Ownership Transfer Enabled Device List is Empty\n");
1488         printf("   > Please Discover the Multiple Ownership Transfer Enabled Devices, with [13] Menu\n");
1489         return 0;  // normal case
1490     }
1491
1492     // select resource server for removing sub-owner
1493     int dev_num = 0;
1494     for ( ; ; )
1495     {
1496         printf("   > Enter Device Number to remove sub-owner: ");
1497         for (int ret = 0; 1 != ret; )
1498         {
1499             ret = scanf("%d", &dev_num);
1500             for( ; 0x20 <= getchar(); );  // for removing overflow garbages
1501                                         // '0x20<=code' is character region
1502         }
1503         if (0 < dev_num && g_mot_enable_cnt >= dev_num)
1504         {
1505             break;
1506         }
1507         printf("     Entered Wrong Number. Please Enter Again\n");
1508     }
1509
1510     OCProvisionDev_t* motDev = getDevInst(g_mot_enable_list, dev_num);
1511     if (motDev && motDev->doxm && motDev->doxm->subOwners)
1512     {
1513         OicSecSubOwner_t* subOwner = motDev->doxm->subOwners;
1514         int so_cnt = 0;
1515         while(subOwner)
1516         {
1517             printf("     [%zu] ", ++so_cnt);
1518             printUuid(&subOwner->uuid);
1519             printf("\n");
1520             subOwner = subOwner->next;
1521         }
1522
1523         int so_num = 0;
1524         for ( ; ; )
1525         {
1526             printf("   > Enter SubOwner Number to be removed : ");
1527             for (int ret = 0; 1 != ret; )
1528             {
1529                 ret = scanf("%d", &so_num);
1530                 for( ; 0x20<=getchar(); );  // for removing overflow garbages
1531                                             // '0x20<=code' is character region
1532             }
1533             if (0 < so_num && so_cnt >= so_num)
1534             {
1535                 int target_num = 0;
1536                 subOwner = motDev->doxm->subOwners;
1537                 while (subOwner)
1538                 {
1539                     if(so_num == ++target_num)
1540                     {
1541                         if (OC_STACK_OK != OCRemoveSubOwner(NULL, motDev, &subOwner->uuid, deleteDoxmForMOTCB))
1542                         {
1543                             return -1;
1544                         }
1545
1546                         g_doneCB = false;
1547
1548                         if(waitCallbackRet())  // input |g_doneCB| flag implicitly
1549                         {
1550                             OIC_LOG(ERROR, TAG, "waitCallbackRet callback error");
1551                             return -1;
1552                         }
1553                         return 0;
1554                     }
1555                     subOwner = subOwner->next;
1556                 }
1557                 break;
1558             }
1559             printf("     Entered Wrong Number. Please Enter Again\n");
1560         }
1561     }
1562     else
1563     {
1564         printf("     SubOwner list is empty.\n");
1565     }
1566
1567     return 0;
1568 }
1569
1570 static int removeAllSubOwner(void)
1571 {
1572     // check |g_mot_enable_list| for removing sub-owner
1573     if (!g_mot_enable_list || 1 > g_mot_enable_cnt)
1574     {
1575         printf("   > Multiple Ownership Transfer Enabled Device List is Empty\n");
1576         printf("   > Please Discover the Multiple Ownership Transfer Enabled Devices, with [13] Menu\n");
1577         return 0;  // normal case
1578     }
1579
1580     // select resource server for removing sub-owner
1581     int dev_num = 0;
1582     for ( ; ; )
1583     {
1584         printf("   > Enter Device Number to remove sub-owner: ");
1585         for (int ret = 0; 1 != ret; )
1586         {
1587             ret = scanf("%d", &dev_num);
1588             for( ; 0x20 <= getchar(); );  // for removing overflow garbages
1589                                         // '0x20<=code' is character region
1590         }
1591         if (0 < dev_num && g_mot_enable_cnt >= dev_num)
1592         {
1593             break;
1594         }
1595         printf("     Entered Wrong Number. Please Enter Again\n");
1596     }
1597
1598     OCProvisionDev_t* motDev = getDevInst(g_mot_enable_list, dev_num);
1599     if (motDev && motDev->doxm && motDev->doxm->subOwners)
1600     {
1601         if (OC_STACK_OK != OCRemoveAllSubOwner(NULL, motDev, deleteDoxmForMOTCB))
1602         {
1603             return -1;
1604         }
1605
1606         g_doneCB = false;
1607
1608         if(waitCallbackRet())  // input |g_doneCB| flag implicitly
1609         {
1610             OIC_LOG(ERROR, TAG, "waitCallbackRet callback error");
1611             return -1;
1612         }
1613         return 0;
1614     }
1615     else
1616     {
1617         printf("     SubOwner list is empty.\n");
1618     }
1619
1620     return 0;
1621 }
1622
1623 #endif //MULTIPLE_OWNER
1624
1625 static int resetDevice(void)
1626 {
1627     // check |own_list| for removing device
1628     if (!g_own_list || 1 > g_own_cnt)
1629     {
1630         printf("   > Owned Device List, to Reset Device, is Empty\n");
1631         printf("   > Please Register Unowned Devices first, with [20] Menu\n");
1632         return 0;
1633     }
1634
1635     OCProvisionDev_t *dev = NULL;
1636
1637     for ( ; ; )
1638     {
1639             printf("************************************************************\n");
1640             printf("Reset device candidate list:\n");
1641             g_unown_cnt = printDevList(g_own_list);
1642             if(0 == g_unown_cnt)
1643             {
1644                 break;
1645             }
1646
1647             printf("Select number device from list\nor: -1 - escape\n");
1648             int c = 0;
1649
1650             if (!scanf("%d",&c))
1651             {
1652                 continue;
1653             }
1654
1655             if(0 == c && NULL != dev)
1656             {
1657                 break;
1658             }
1659
1660             if(-1 == c)
1661             {
1662                 return 0;
1663             }
1664
1665             if(c > g_own_cnt)
1666             {
1667                 continue;
1668             }
1669
1670             dev = g_own_list;
1671             for(int lst_cnt = 1; dev && lst_cnt != c; lst_cnt++, dev = dev->next);
1672             break;
1673
1674     }
1675
1676     g_doneCB = false;
1677     printf("   Resetting Selected Owned Device..\n");
1678
1679     OCStackResult rst = SRPResetDevice(dev, resetDeviceCB);
1680     if (OC_STACK_OK != rst)
1681     {
1682         OIC_LOG_V(ERROR, TAG, "OCResetDevice API error: %d", rst);
1683         return -1;
1684     }
1685
1686     if (waitCallbackRet())  // input |g_doneCB| flag implicitly
1687     {
1688         OIC_LOG_V(ERROR, TAG, "%s: callback error", __func__);
1689         return -1;
1690     }
1691
1692     // display the removed result
1693     printf("   > Reset Selected Owned Device SUCCEEDED\n");
1694     printf("   > Please Discover Owned Devices for the Registered Result, with [10|12] Menu\n");
1695
1696     return 0;
1697 }
1698
1699 static int resetSVRDB(void)
1700 {
1701     printf("   Resetting SVR DB..\n");
1702     OCStackResult rst = OCResetSVRDB();
1703     if (OC_STACK_OK != rst)
1704     {
1705         OIC_LOG_V(ERROR, TAG, "OCResetSVRDB API error: %d", rst);
1706         return -1;
1707     }
1708     return 0;
1709 }
1710
1711 static OicSecAcl_t* createAcl(const int dev_num)
1712 {
1713     if(0>=dev_num || g_own_cnt<dev_num)
1714     {
1715         OIC_LOG(ERROR, TAG, "createAcl invalid parameters");
1716         return NULL;  // not need to 'goto' |ERROR| before allocating |acl|
1717     }
1718
1719     // allocate memory for |acl| struct
1720     printf("   **** Create ACL for the Selected Device[%d]\n", dev_num);
1721     OicSecAcl_t* acl = (OicSecAcl_t*) OICCalloc(1, sizeof(OicSecAcl_t));
1722     if(!acl)
1723     {
1724         OIC_LOG(ERROR, TAG, "createAcl: OICCalloc error return");
1725         return NULL;  // not need to 'goto' |ERROR| before allocating |acl|
1726     }
1727     OicSecAce_t* ace = (OicSecAce_t*) OICCalloc(1, sizeof(OicSecAce_t));
1728     if(!ace)
1729     {
1730         OIC_LOG(ERROR, TAG, "createAcl: OICCalloc error return");
1731         return NULL;  // not need to 'goto' |ERROR| before allocating |acl|
1732     }
1733     LL_APPEND(acl->aces, ace);
1734
1735     // enter |subject| device number
1736     int num = 0;
1737     for( ; ; )
1738     {
1739         printf("   > [A] Enter Subject Device Number: ");
1740         for(int ret=0; 1!=ret; )
1741         {
1742             ret = scanf("%d", &num);
1743             for( ; 0x20<=getchar(); );  // for removing overflow garbages
1744                                         // '0x20<=code' is character region
1745         }
1746         if(0<num && g_own_cnt>=num && dev_num!=num)
1747         {
1748             break;
1749         }
1750         printf("     Entered Wrong Number. Please Enter Again\n");
1751     }
1752
1753     OCProvisionDev_t* dev = getDevInst((const OCProvisionDev_t*)g_own_list, num);
1754     if(!dev || !dev->doxm)
1755     {
1756         OIC_LOG(ERROR, TAG, "createAcl: device instance empty");
1757         goto CRACL_ERROR;
1758     }
1759     memcpy(&ace->subjectuuid, &dev->doxm->deviceID, UUID_LENGTH);
1760
1761     // enter number of |resources| in 'accessed' device
1762     for( ; ; )
1763     {
1764         printf("   > [B] Enter Number of Accessed Resources (under 16): ");
1765                 // '16' is |ACL_RESRC_MAX_NUM|
1766         for(int ret=0; 1!=ret; )
1767         {
1768             ret = scanf("%d", &num);
1769             for( ; 0x20<=getchar(); );  // for removing overflow garbages
1770                                         // '0x20<=code' is character region
1771         }
1772         if(0<num && ACL_RESRC_MAX_NUM>=num)
1773         {
1774             break;
1775         }
1776         printf("     Entered Wrong Number. Please Enter under 16 Again\n");
1777                 // '16' is |ACL_RESRC_MAX_NUM|
1778     }
1779
1780     // enter actually each 'accessed' |resources| name
1781     printf("         Enter Each Accessed Resource Name (each under 128 char)\n");
1782             // '128' is ACL_RESRC_MAX_LEN
1783
1784     char rsrc_in[ACL_RESRC_MAX_LEN+1] = {0};  // '1' for null termination
1785     for(int i = 0; num > i; ++i)
1786     {
1787         OicSecRsrc_t* rsrc = (OicSecRsrc_t*)OICCalloc(1, sizeof(OicSecRsrc_t));
1788         if(!rsrc)
1789         {
1790             OIC_LOG(ERROR, TAG, "createAcl: OICCalloc error return");
1791             goto CRACL_ERROR;
1792         }
1793
1794         printf("         Enter Accessed Resource[%d] Name: (e.g. /a/led)", i+1);
1795         for(int ret=0; 1!=ret; )
1796         {
1797             ret = scanf("%128s", rsrc_in);  // '128' is ACL_RESRC_MAX_LEN
1798             for( ; 0x20<=getchar(); );  // for removing overflow garbages
1799                                         // '0x20<=code' is character region
1800         }
1801         size_t len = strlen(rsrc_in)+1;  // '1' for null termination
1802         rsrc->href = (char*) OICCalloc(len, sizeof(char));
1803         if(!rsrc->href)
1804         {
1805             OIC_LOG(ERROR, TAG, "createAcl: OICCalloc error return");
1806             goto CRACL_ERROR;
1807         }
1808         OICStrcpy(rsrc->href, len, rsrc_in);
1809
1810         size_t arrLen = 0;
1811         while(1)
1812         {
1813             printf("         Enter Number of resource type for [%s] : ", rsrc->href);
1814             for(int ret=0; 1!=ret; )
1815             {
1816                 ret = scanf("%zu", &arrLen);
1817                 for( ; 0x20<=getchar(); );  // for removing overflow garbages
1818                                             // '0x20<=code' is character region
1819             }
1820             if(ACL_RESRC_ARRAY_SIZE >= arrLen)
1821             {
1822                 break;
1823             }
1824             printf("     Entered Wrong Number. Please Enter under %d Again\n", ACL_RESRC_ARRAY_SIZE);
1825         }
1826
1827         rsrc->typeLen = arrLen;
1828         rsrc->types = (char**)OICCalloc(arrLen, sizeof(char*));
1829         if(!rsrc->types)
1830         {
1831             OIC_LOG(ERROR, TAG, "createAcl: OICCalloc error return");
1832             goto CRACL_ERROR;
1833         }
1834
1835         for(size_t i = 0; i < arrLen; i++)
1836         {
1837             printf("         Enter ResourceType[%zu] Name (e.g. core.led): ", i+1);
1838             for(int ret=0; 1!=ret; )
1839             {
1840                 ret = scanf("%128s", rsrc_in);  // '128' is ACL_RESRC_MAX_LEN
1841                 for( ; 0x20<=getchar(); );  // for removing overflow garbages
1842                                             // '0x20<=code' is character region
1843             }
1844             rsrc->types[i] = OICStrdup(rsrc_in);
1845             if(!rsrc->types[i])
1846             {
1847                 OIC_LOG(ERROR, TAG, "createAcl: OICStrdup error return");
1848                 goto CRACL_ERROR;
1849             }
1850         }
1851
1852         while(1)
1853         {
1854             printf("         Enter Number of interface for [%s]: ", rsrc->href);
1855             for(int ret=0; 1!=ret; )
1856             {
1857                 ret = scanf("%zu", &arrLen);
1858                 for( ; 0x20<=getchar(); );  // for removing overflow garbages
1859                                             // '0x20<=code' is character region
1860             }
1861             if(ACL_RESRC_ARRAY_SIZE >= arrLen)
1862             {
1863                 break;
1864             }
1865             printf("     Entered Wrong Number. Please Enter under %d Again\n", ACL_RESRC_ARRAY_SIZE);
1866         }
1867
1868         rsrc->interfaceLen = arrLen;
1869         rsrc->interfaces = (char**)OICCalloc(arrLen, sizeof(char*));
1870         if(!rsrc->interfaces)
1871         {
1872             OIC_LOG(ERROR, TAG, "createAcl: OICCalloc error return");
1873             goto CRACL_ERROR;
1874         }
1875
1876         for(size_t i = 0; i < arrLen; i++)
1877         {
1878             printf("         Enter Interface[%zu] Name (e.g. oic.if.baseline): ", i+1);
1879             for(int ret=0; 1!=ret; )
1880             {
1881                 ret = scanf("%128s", rsrc_in);  // '128' is ACL_RESRC_MAX_LEN
1882                 for( ; 0x20<=getchar(); );  // for removing overflow garbages
1883                                             // '0x20<=code' is character region
1884             }
1885             rsrc->interfaces[i] = OICStrdup(rsrc_in);
1886             if(!rsrc->interfaces[i])
1887             {
1888                 OIC_LOG(ERROR, TAG, "createAcl: OICStrdup error return");
1889                 goto CRACL_ERROR;
1890             }
1891         }
1892
1893         LL_APPEND(ace->resources, rsrc);
1894     }
1895
1896     // enter |permission| for this access
1897     printf("   > [C] Enter Permission for This Access\n");
1898     uint16_t pmsn = PERMISSION_FULL_CONTROL;  // default full permission
1899     uint16_t pmsn_msk = PERMISSION_CREATE;  // default permission mask
1900     for(int i=0; ACL_PEMISN_CNT>i; ++i)
1901     {
1902         char ans = 0;
1903         for( ; ; )
1904         {
1905             printf("         Enter %s Permission (y/n): ", ACL_PEMISN[i]);
1906             for(int ret=0; 1!=ret; )
1907             {
1908                 ret = scanf("%c", &ans);
1909                 for( ; 0x20<=getchar(); );  // for removing overflow garbages
1910                                             // '0x20<=code' is character region
1911             }
1912             if('y'==ans || 'Y'==ans || 'n'==ans|| 'N'==ans)
1913             {
1914                 ans &= ~0x20;  // for masking lower case, 'y/n'
1915                 break;
1916             }
1917             printf("         Entered Wrong Answer. Please Enter 'y/n' Again\n");
1918         }
1919         if('N' == ans)  // masked lower case, 'n'
1920         {
1921             pmsn -= pmsn_msk;
1922         }
1923         pmsn_msk <<= 1;
1924     }
1925     ace->permission = pmsn;
1926
1927     return acl;
1928
1929 CRACL_ERROR:
1930     OCDeleteACLList(acl);  // after here |acl| points nothing
1931     return NULL;
1932 }
1933
1934 static OicSecAcl_t* createSimpleAcl(const OicUuid_t uuid)
1935 {
1936     OIC_LOG(DEBUG, TAG, "createSimpleAcl IN");
1937
1938     // allocate memory for |acl| struct
1939     OicSecAcl_t* acl = (OicSecAcl_t*) OICCalloc(1, sizeof(OicSecAcl_t));
1940     if(!acl)
1941     {
1942         OIC_LOG(DEBUG, TAG, "OICCalloc error return");
1943         return NULL;  // not need to 'goto' |ERROR| before allocating |acl|
1944     }
1945     OicSecAce_t* ace = (OicSecAce_t*) OICCalloc(1, sizeof(OicSecAce_t));
1946     if(!ace)
1947     {
1948         OIC_LOG(DEBUG, TAG,  "OICCalloc error return");
1949         return NULL;  // not need to 'goto' |ERROR| before allocating |acl|
1950     }
1951     LL_APPEND(acl->aces, ace);
1952
1953     memcpy(&ace->subjectuuid, &uuid, UUID_LENGTH);
1954
1955     OicSecRsrc_t* rsrc = (OicSecRsrc_t*)OICCalloc(1, sizeof(OicSecRsrc_t));
1956     if(!rsrc)
1957     {
1958         OIC_LOG(DEBUG, TAG, "OICCalloc error return");
1959         OCDeleteACLList(acl);
1960         return NULL;
1961     }
1962
1963     char href[] = "*";
1964     size_t len = strlen(href)+1;  // '1' for null termination
1965     rsrc->href = (char*) OICCalloc(len, sizeof(char));
1966     if(!rsrc->href)
1967     {
1968         OIC_LOG(DEBUG, TAG,  "OICCalloc error return");
1969         OCDeleteACLList(acl);
1970         return NULL;
1971     }
1972     OICStrcpy(rsrc->href, len, href);
1973
1974     size_t arrLen = 1;
1975     rsrc->typeLen = arrLen;
1976     rsrc->types = (char**)OICCalloc(arrLen, sizeof(char*));
1977     if(!rsrc->types)
1978     {
1979         OIC_LOG(DEBUG, TAG,  "OICCalloc error return");
1980         OCDeleteACLList(acl);
1981         return NULL;
1982     }
1983     rsrc->types[0] = OICStrdup("");   // ignore
1984
1985     rsrc->interfaceLen = 1;
1986     rsrc->interfaces = (char**)OICCalloc(arrLen, sizeof(char*));
1987     if(!rsrc->interfaces)
1988     {
1989         OIC_LOG(DEBUG, TAG,  "OICCalloc error return");
1990         OCDeleteACLList(acl);
1991         return NULL;
1992     }
1993     rsrc->interfaces[0] = OICStrdup("oic.if.baseline");  // ignore
1994
1995     LL_APPEND(ace->resources, rsrc);
1996
1997     ace->permission = 31;   // R/W/U/D
1998
1999     OIC_LOG(DEBUG, TAG, "createSimpleAcl OUT");
2000
2001     return acl;
2002 }
2003
2004 static OicSecPdAcl_t* createPdAcl(const int dev_num)
2005 {
2006     if(0>=dev_num || g_own_cnt<dev_num)
2007     {
2008         OIC_LOG(ERROR, TAG, "createAcl invalid parameters");
2009         return NULL;  // not need to 'goto' |ERROR| before allocating |acl|
2010     }
2011
2012     // allocate memory for |pdacl| struct
2013     printf("   **** Create PDACL for the Selected Device[%d]\n", dev_num);
2014     OicSecPdAcl_t* pdAcl = (OicSecPdAcl_t*) OICCalloc(1, sizeof(OicSecPdAcl_t));
2015     if(!pdAcl)
2016     {
2017         OIC_LOG(ERROR, TAG, "createAcl: OICCalloc error return");
2018         return NULL;  // not need to 'goto' |ERROR| before allocating |acl|
2019     }
2020
2021
2022     // number of resources
2023     char rsrc_in[][ACL_RESRC_MAX_LEN+1] = {"*", "/rsrc/*"};
2024     pdAcl->resourcesLen = 1;
2025
2026     // resource
2027     int num = pdAcl->resourcesLen;
2028     pdAcl->resources = (char**) OICCalloc(num, sizeof(char*));
2029     if(!pdAcl->resources)
2030     {
2031         OIC_LOG(ERROR, TAG, "createPdAcl: OICCalloc error return");
2032         goto CRPDACL_ERROR;
2033     }
2034     for(int i=0; num>i; ++i)
2035     {
2036         size_t len = strlen(rsrc_in[i])+1;  // '1' for null termination
2037         char* rsrc = (char*) OICCalloc(len, sizeof(char));
2038         if(!rsrc)
2039         {
2040             OIC_LOG(ERROR, TAG, "createPdAcl: OICCalloc error return");
2041             goto CRPDACL_ERROR;
2042         }
2043         OICStrcpy(rsrc, len, rsrc_in[i]);
2044         pdAcl->resources[i] = rsrc;  // after here, |rsrc| points nothing
2045     }
2046
2047     // permission
2048     pdAcl->permission = PERMISSION_FULL_CONTROL;
2049
2050     return pdAcl;
2051
2052 CRPDACL_ERROR:
2053     OCDeletePdAclList(pdAcl);
2054     return NULL;
2055 }
2056
2057 static OCProvisionDev_t* getDevInst(const OCProvisionDev_t* dev_lst, const int dev_num)
2058 {
2059     if(!dev_lst || 0>=dev_num)
2060     {
2061         printf("     Device List is Empty..\n");
2062         return NULL;
2063     }
2064
2065     OCProvisionDev_t* lst = (OCProvisionDev_t*) dev_lst;
2066     for(int i=0; lst; )
2067     {
2068         if(dev_num == ++i)
2069         {
2070             return lst;
2071         }
2072         lst = lst->next;
2073     }
2074
2075     return NULL;  // in here |lst| is always |NULL|
2076 }
2077
2078 static int printDevList(const OCProvisionDev_t* dev_lst)
2079 {
2080     if(!dev_lst)
2081     {
2082         printf("     Device List is Empty..\n\n");
2083         return 0;
2084     }
2085
2086     OCProvisionDev_t* lst = (OCProvisionDev_t*) dev_lst;
2087     int lst_cnt = 0;
2088     for( ; lst; )
2089     {
2090         printf("     [%d] ", ++lst_cnt);
2091         printUuid((const OicUuid_t*) &lst->doxm->deviceID);
2092         printf("\n");
2093         lst = lst->next;
2094     }
2095     printf("\n");
2096
2097     return lst_cnt;
2098 }
2099
2100 static size_t printUuidList(const OCUuidList_t* uid_lst)
2101 {
2102     if(!uid_lst)
2103     {
2104         printf("     Device List is Empty..\n\n");
2105         return 0;
2106     }
2107
2108     OCUuidList_t* lst = (OCUuidList_t*) uid_lst;
2109     size_t lst_cnt = 0;
2110     for( ; lst; )
2111     {
2112         printf("     [%zu] ", ++lst_cnt);
2113         printUuid((const OicUuid_t*) &lst->dev);
2114         printf("\n");
2115         lst = lst->next;
2116     }
2117     printf("\n");
2118
2119     return lst_cnt;
2120 }
2121
2122 static int printResultList(const OCProvisionResult_t* rslt_lst, const int rslt_cnt)
2123 {
2124     if(!rslt_lst || 0>=rslt_cnt)
2125     {
2126         printf("     Device List is Empty..\n\n");
2127         return 0;
2128     }
2129
2130     int lst_cnt = 0;
2131     for( ; rslt_cnt>lst_cnt; ++lst_cnt)
2132     {
2133         printf("     [%d] ", lst_cnt+1);
2134         printUuid((const OicUuid_t*) &rslt_lst[lst_cnt].deviceId);
2135         printf(" - result: %d\n", rslt_lst[lst_cnt].res);
2136     }
2137     printf("\n");
2138
2139     return lst_cnt;
2140 }
2141
2142 static void printUuid(const OicUuid_t* uid)
2143 {
2144     for(int i=0; i<UUID_LENGTH; )
2145     {
2146         printf("%02X", (*uid).id[i++]);
2147         if(i==4 || i==6 || i==8 || i==10)  // canonical format for UUID has '8-4-4-4-12'
2148         {
2149             printf("-");
2150         }
2151     }
2152 }
2153
2154 static FILE* fopen_prvnMng(const char* path, const char* mode)
2155 {
2156     (void)path;  // unused |path| parameter
2157
2158     // input |g_svr_db_fname| internally by force, not using |path| parameter
2159     // because |OCPersistentStorage::open| is called |OCPersistentStorage| internally
2160     // with its own |SVR_DB_FILE_NAME|
2161     return fopen(SVR_DB_FILE_NAME, mode);
2162 }
2163
2164 static int peerCertCallback(void *ctx, const mbedtls_x509_crt *cert, int depth)
2165 {
2166     (void)ctx;
2167
2168     OIC_LOG_V(DEBUG, TAG, "Depth : %d", depth);
2169     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
2170     OIC_LOG(DEBUG, TAG, "***** Serial number of certificate is below *****");
2171     OIC_LOG_BUFFER(DEBUG, TAG, cert->serial.p, cert->serial.len);
2172     OIC_LOG(DEBUG, TAG, "***** Serial number of certificate is above *****");
2173     OIC_LOG_V(DEBUG, TAG, "OUT%s", __func__);
2174
2175     return 0;
2176 }
2177
2178 static int waitCallbackRet(void)
2179 {
2180     for(int i=0; !g_doneCB && CALLBACK_TIMEOUT>i; ++i)
2181     {
2182         sleep(1);
2183         if(OC_STACK_OK != OCProcess())
2184         {
2185             OIC_LOG(ERROR, TAG, "OCStack process error");
2186             return -1;
2187         }
2188     }
2189
2190     if(!g_doneCB)
2191     {
2192         OCPDMCleanupForTimeout();
2193     }
2194
2195     return 0;
2196 }
2197
2198 static int selectTwoDiffNum(int* a, int* b, const int max, const char* str)
2199 {
2200     if(!a || !b || 2>max || !str)
2201     {
2202         return -1;
2203     }
2204
2205     for( ; ; )
2206     {
2207         for(int i=0; 2>i; ++i)
2208         {
2209             int* num = 0==i?a:b;
2210             for( ; ; )
2211             {
2212                 printf("   > Enter Device[%d] Number, %s: ", i+1, str);
2213                 for(int ret=0; 1!=ret; )
2214                 {
2215                     ret = scanf("%d", num);
2216                     for( ; 0x20<=getchar(); );  // for removing overflow garbages
2217                                                 // '0x20<=code' is character region
2218                 }
2219                 if(0<*num && max>=*num)
2220                 {
2221                     break;
2222                 }
2223                 printf("     Entered Wrong Number. Please Enter Again\n");
2224             }
2225         }
2226         if(*a != *b)
2227         {
2228             printf("\n");
2229             return 0;
2230         }
2231     }
2232
2233     return -1;
2234 }
2235
2236 #ifdef __WITH_TLS__
2237
2238 static void setDevProtocol(OCProvisionDev_t* lst)
2239 {
2240     if(!lst)
2241     {
2242         printf("     Device List is Empty..\n\n");
2243         return;
2244     }
2245
2246     for( ; lst; )
2247     {
2248         if(2 == secure_protocol)
2249         {
2250             lst->connType &= ~CT_ADAPTER_IP; //reset IP flag
2251             lst->connType |= CT_ADAPTER_TCP; //set TCP flag
2252             lst->endpoint.adapter = OC_ADAPTER_TCP;
2253             lst->endpoint.port = lst->tcpPort;
2254             lst->securePort = lst->tcpPort;
2255         }
2256         lst = lst->next;
2257     }
2258 }
2259
2260 static void selectSecureProtocol()
2261 {
2262     printf("   Select protocol\n");
2263     printf("   1 - DTLS(Default)\n");
2264     printf("   2 - TLS\n");
2265
2266     for(int ret=0; 1!=ret; )
2267     {
2268         ret = scanf("%d",&secure_protocol);
2269         for( ; 0x20<=getchar(); );  // for removing overflow garbages
2270         // '0x20<=code' is character region
2271     }
2272
2273     if(0 >= secure_protocol || 2 < secure_protocol)
2274     {
2275         secure_protocol = 1;
2276     }
2277
2278     setDevProtocol(g_own_list);
2279     setDevProtocol(g_unown_list);
2280 }
2281 #endif
2282
2283 static void secureStorageHwEmulation()
2284 {
2285     printf("   Enable Secure Storage HW Emulation\n");
2286
2287     printf("         Enter Own Certificate File Path[~4095]: ");
2288     char cert_filepath[4096] = {0,};
2289     for(int ret=0; 1!=ret; )
2290     {
2291         ret = scanf("%255s", cert_filepath);
2292         for( ; 0x20<=getchar(); );  // for removing overflow garbages
2293                                     // '0x20<=code' is character region
2294     }
2295
2296     printf("         Enter Private Key File Path[~4095]: ");
2297     char key_filepath[4096] = {0,};
2298     for(int ret=0; 1!=ret; )
2299     {
2300         ret = scanf("%255s", key_filepath);
2301         for( ; 0x20<=getchar(); );  // for removing overflow garbages
2302                                     // '0x20<=code' is character region
2303     }
2304
2305     printf("         Enter Password for Key Password[~31][Press (Enter) to not set]: ");
2306     char pwd[32] = {0,};
2307     for(int i=0; i < 31; i++)
2308     {
2309         pwd[i] = (char)getchar();
2310         if (0x20 <= pwd[i])
2311         {
2312             pwd[i--] = '\0';
2313             continue;
2314         }
2315         if (0x0A == pwd[i])
2316         {
2317             pwd[i] = '\0';
2318             break;
2319         }
2320     }
2321
2322     if (0 != SSemulSetCertkeyFilepath(cert_filepath, key_filepath, pwd))
2323     {
2324         printf("    Fail to set cert/key file path");
2325         return;
2326     }
2327
2328     if (0 != SetHwPkixCallbacks(HWGetKeyContext,
2329                                                   HWFreeKeyContext,
2330                                                   HWGetOwnCertificateChain,
2331                                                   HWSetupPkContext))
2332     {
2333         printf("    Fail to regist HW Pkix Callbacks");
2334         return;
2335     }
2336     printf("    Success to regist HW Pkix Callbacks");
2337 }
2338
2339 static void selectVerifMethod()
2340 {
2341     int option;
2342     printf("   Select verification method for ownership transfer\n");
2343     printf("   0 - No verification\n");
2344     printf("   1 - Display only\n");
2345     printf("   2 - Confirm only\n");
2346     printf("   3 - Both Display and Confirm\n");
2347
2348     for(int ret=0; 1!=ret; )
2349     {
2350         ret = scanf("%d",&option);
2351         for( ; 0x20<=getchar(); );  // for removing overflow garbages
2352         // '0x20<=code' is character region
2353     }
2354
2355     if(0 > option || 3 < option)
2356     {
2357         printf("Invalid option!");
2358     }
2359     SetVerifyOption((VerifyOptionBitmask_t) option);
2360     printf("Option %d chosen!", option);
2361 }
2362
2363 static void printMenu(void)
2364 {
2365     printf("************************************************************\n");
2366     printf("****** OIC Provisioning Client with using C-level API ******\n");
2367     printf("************************************************************\n\n");
2368
2369     printf("** [A] DISCOVER DEVICES ON NETWORK\n");
2370     printf("** 10. Discover All Un/Owned Devices on Network\n");
2371     printf("** 11. Discover Only Unowned Devices on Network\n");
2372 #ifdef MULTIPLE_OWNER
2373     printf("** 12. Discover Only Owned Devices on Network\n");
2374     printf("** 13. Discover Multiple Ownership Transfer Enabled Devices on Network\n\n");
2375 #else
2376     printf("** 12. Discover Only Owned Devices on Network\n\n");
2377 #endif //MULTIPLE_OWNER
2378
2379     printf("** [B] REGISTER/OWN ALL DISCOVERED UNOWNED DEVICES\n");
2380     printf("** 20. Register/Own All Discovered Unowned Devices\n\n");
2381
2382     printf("** [C] PROVISION/LINK PAIRWISE THINGS\n");
2383     printf("** 30. Provision/Link Pairwise Things\n");
2384     printf("** 31. Provision Credentials for Pairwise Things\n");
2385     printf("** 32. Provision the Selected Access Control List(ACL)\n");
2386     printf("** 33. Provision Direct-Pairing Configuration\n");
2387     printf("** 34. Check Linked Status of the Selected Device on PRVN DB\n");
2388     printf("** 35. Save the Selected Access Control List(ACL) into local SVR DB\n\n");
2389
2390     printf("** [D] UNLINK PAIRWISE THINGS\n");
2391     printf("** 40. Unlink Pairwise Things\n\n");
2392
2393     printf("** [E] REMOVE THE SELECTED DEVICE\n");
2394     printf("** 50. Remove the Selected Device\n");
2395     printf("** 51. Remove Device with UUID (UUID input is required)\n");
2396     printf("** 52. Reset the Selected Device\n");
2397     printf("** 53. Reset SVR DB\n\n");
2398
2399     printf("** [F] GET SECURITY RESOURCE FOR DEBUGGING ONLY\n");
2400     printf("** 60. Get the Credential resources of the Selected Device\n");
2401     printf("** 61. Get the ACL resources of the Selected Device\n\n");
2402
2403 #ifdef MULTIPLE_OWNER
2404     printf("** [G] UPDATE THE MULTIPLE OWNERSHIP TRANSFER RELATED VALUE\n");
2405     printf("** 70. Change the Multiple Ownership transfer MODE(update mom)\n");
2406     printf("** 71. Provision Preconfigured PIN\n");
2407     printf("** 72. Change the Multiple Ownership transfer METHOD(update oxmsel)\n");
2408     printf("** 73. Remove Sub-Owner from Resource Server\n");
2409     printf("** 74. Remove All Sub-Owner from Resource Server\n\n");
2410 #endif //MULTIPLE_OWNER
2411
2412 #ifdef __WITH_TLS__
2413     printf("** [H] SELECT SECURE PROTOCOL DTLS/TLS AND OTHERS\n");
2414     printf("** 80. Select secure protocol(default DTLS)\n");
2415     printf("** 81. Select verification method\n");
2416     printf("** 82. Enable secure storage hw emulation\n\n");
2417 #else
2418     printf("** [H] SELECT VERIFICATION OPTION\n");
2419     printf("** 81. Select verification method\n\n");
2420 #endif
2421     printf("** [I] EXIT PROVISIONING CLIENT\n");
2422
2423     printf("** 99. Exit Provisionong Client\n\n");
2424
2425     printf("************************************************************\n\n");
2426 }
2427
2428 #if 0 // Code for enabling path configuration for PDB and SVR DBf
2429 static void printUsage(void)
2430 {
2431     printf("\n");
2432     printf("OIC Provisioning Client with using C-level API\n");
2433     printf("Usage: provisioningclient [option]...\n");
2434     printf("\n");
2435     printf("  -h                           print help for this provisioning client\n");
2436     printf("  -p=[prvn_db_file_path/name]  input PRVN DB file path and name\n");
2437     printf("                               if not exists, will load default DB file\n");
2438     printf("                               (default: |oic_prvn_mng.db| on working dir)\n");
2439     printf("                               (ex. -p=oic_prvn_mng.db)\n");
2440     printf("  -s=[svr_db_file_path/name]   input SVR DB file path and name\n");
2441     printf("                               if not exists, will load default DB file\n");
2442     printf("                               (default: |oic_svr_db_client.json| on working dir)\n");
2443     printf("                               (ex. -s=oic_svr_db_client.json)\n");
2444     printf("\n");
2445 }
2446 #endif
2447
2448 /**
2449  * Sample implementation of Export key block and master secret
2450  *
2451  * @param[in] p_expkey  Context for the callback
2452  * @aram[in] ms        Pointer to master secret (fixed length: 48 bytes)
2453  * @param[in] kb        Pointer to key block, see RFC 5246 section 6.3
2454  *                  (variable length: 2 * maclen + 2 * keylen + 2 * ivlen).
2455  * @param[in] maclen    MAC length
2456  * @param[in] keylen    Key length
2457  * @param[in] ivlen     IV length
2458  */
2459 static void SslExportKeysCallback(const unsigned char* masterSecret,
2460                                   const unsigned char* keyBlock,
2461                                   size_t macLen, size_t keyLen, size_t ivLen)
2462 {
2463     OIC_LOG_V(INFO, TAG, "In %s ", __func__);
2464
2465     OIC_LOG(INFO, TAG, "[MASTER SECRET] : ");
2466     OIC_LOG_BUFFER(INFO, TAG, masterSecret, 48);
2467
2468     OIC_LOG(INFO, TAG, "[KEY BLOCK] : ");
2469     OIC_LOG_BUFFER(INFO, TAG, keyBlock, (2 * macLen) + (2 * keyLen) + (2 * ivLen));
2470
2471     OIC_LOG_V(INFO, TAG, "Mac Length = %zu, Key Length = %zu, IV Length = %zu",
2472             macLen, keyLen, ivLen);
2473
2474     OIC_LOG_V(INFO, TAG, "Out %s ", __func__);
2475 }
2476
2477 // main function for provisioning client using C-level provisioning API
2478 int main()
2479 {
2480     // initialize provisioning client
2481     if(initProvisionClient())
2482     {
2483         OIC_LOG(ERROR, TAG, "ProvisionClient init error");
2484         goto PMCLT_ERROR;
2485     }
2486
2487     if (CA_STATUS_OK !=
2488         CASetSslExportKeysCallback(SslExportKeysCallback, CA_SSL_EKCB_DTLS, CA_SSL_EKCB_CLIENT))
2489     {
2490         OIC_LOG(ERROR, TAG, "Failed to register the (D)TLS export Key Callback!");
2491         goto PMCLT_ERROR;
2492     }
2493
2494     // Client can choose a allowed/not-allowed OxM method.
2495     if(OC_STACK_OK != OCSetOxmAllowStatus(OIC_DECENTRALIZED_PUBLIC_KEY, false))
2496     {
2497         OIC_LOG(WARNING, TAG, "Failed to disable OIC_DECENTRALIZED_PUBLIC_KEY OxM");
2498     }
2499
2500     // set callbacks for verification options
2501     SetDisplayNumCB(NULL, displayNumCB);
2502     SetUserConfirmCB(NULL, confirmNumCB);
2503     SetInputStateCB(NULL, notifyInputStateCB);
2504
2505     // set callback for checking peer certificate information
2506     OCSetPeerCertCallback(NULL, peerCertCallback);
2507
2508 #ifdef MULTIPLE_OWNER
2509     SetPreconfigPin("12341234", 8);
2510 #endif //MULTIPLE_OWNER
2511
2512     // main loop for provisioning manager
2513     int mn_num = 0;
2514     for( ; ; )
2515     {
2516         printf("\n");
2517         printMenu();
2518         printf(">> Enter Menu Number: ");
2519         for(int ret=0; 1!=ret; )
2520         {
2521             ret = scanf("%d", &mn_num);
2522             for( ; 0x20<=getchar(); );  // for removing overflow garbages
2523                                         // '0x20<=code' is character region
2524         }
2525         printf("\n");
2526         switch(mn_num)
2527         {
2528         case _10_DISCOV_ALL_DEVS_:
2529             if(discoverAllDevices())
2530             {
2531                 OIC_LOG(ERROR, TAG, "_10_DISCOV_ALL_DEVS_: error");
2532             }
2533             break;
2534         case _11_DISCOV_UNOWN_DEVS_:
2535             if(discoverUnownedDevices())
2536             {
2537                 OIC_LOG(ERROR, TAG, "_11_DISCOV_UNOWN_DEVS_: error");
2538             }
2539             break;
2540         case _12_DISCOV_OWN_DEVS_:
2541             if(discoverOwnedDevices())
2542             {
2543                 OIC_LOG(ERROR, TAG, "_12_DISCOV_OWN_DEVS_: error");
2544             }
2545             break;
2546 #ifdef MULTIPLE_OWNER
2547         case _13_MOT_DISCOV_DEV_:
2548             if(discoverMOTEnabledDevices())
2549             {
2550                 OIC_LOG(ERROR, TAG, "_13_MOT_DISCOV_DEV_: error");
2551             }
2552             break;
2553 #endif //MULTIPLE_OWNER
2554         case _20_REGIST_DEVS_:
2555             if(registerDevices())
2556             {
2557                 OIC_LOG(ERROR, TAG, "_20_REGIST_DEVS_: error");
2558             }
2559             break;
2560         case _30_PROVIS_PAIR_DEVS_:
2561             if(provisionPairwise())
2562             {
2563                 OIC_LOG(ERROR, TAG, "_30_PROVIS_PAIR_DEVS_: error");
2564             }
2565             break;
2566         case _31_PROVIS_CRED_:
2567             if(provisionCred())
2568             {
2569                 OIC_LOG(ERROR, TAG, "_31_PROVIS_CRED_: error");
2570             }
2571             break;
2572         case _32_PROVIS_ACL_:
2573             if(provisionAcl())
2574             {
2575                 OIC_LOG(ERROR, TAG, "_32_PROVIS_ACL_: error");
2576             }
2577             break;
2578         case _33_PROVIS_DP_:
2579             if(provisionDirectPairing())
2580             {
2581                 OIC_LOG(ERROR, TAG, "_33_PROVIS_DP_: error");
2582             }
2583             break;
2584         case _34_CHECK_LINK_STATUS_:
2585             if(checkLinkedStatus())
2586             {
2587                 OIC_LOG(ERROR, TAG, "_34_CHECK_LINK_STATUS_: error");
2588             }
2589             break;
2590         case _35_SAVE_ACL_:
2591             if(saveAcl())
2592             {
2593                 OIC_LOG(ERROR, TAG, "_35_SAVE_ACL_: error");
2594             }
2595             break;
2596         case _40_UNLINK_PAIR_DEVS_:
2597             if(unlinkPairwise())
2598             {
2599                 OIC_LOG(ERROR, TAG, "_40_UNLINK_PAIR_DEVS_: error");
2600             }
2601             break;
2602         case _50_REMOVE_SELEC_DEV_:
2603             if(removeDevice())
2604             {
2605                 OIC_LOG(ERROR, TAG, "_50_REMOVE_SELEC_DEV_: error");
2606             }
2607             break;
2608         case _51_REMOVE_DEV_WITH_UUID_:
2609             if(removeDeviceWithUuid())
2610             {
2611                 OIC_LOG(ERROR, TAG, "_51_REMOVE_DEV_WITH_UUID_: error");
2612             }
2613             break;
2614         case _52_RESET_SELEC_DEV_:
2615             if(resetDevice())
2616             {
2617                 OIC_LOG(ERROR, TAG, "_52_RESET_SELEC_DEV_: error");
2618             }
2619             break;
2620         case _53_RESET_SVR_DB_:
2621             if(resetSVRDB())
2622             {
2623                 OIC_LOG(ERROR, TAG, "_53_RESET_SVR_DB_: error");
2624             }
2625             break;
2626         case _60_GET_CRED_:
2627             if(getCred())
2628             {
2629                 OIC_LOG(ERROR, TAG, "_60_GET_CRED_: error");
2630             }
2631             break;
2632         case _61_GET_ACL_:
2633             if(getAcl())
2634             {
2635                 OIC_LOG(ERROR, TAG, "_61_GET_ACL_: error");
2636             }
2637             break;
2638 #ifdef MULTIPLE_OWNER
2639         case _70_MOT_CHANGE_MOM_:
2640             if(changeMultipleOwnershipTrnasferMode())
2641             {
2642                 OIC_LOG(ERROR, TAG, "_70_MOT_CHANGE_MOM_: error");
2643             }
2644             break;
2645         case _71_MOT_PROV_PRECONF_PIN_:
2646             if(provisionPreconfigPIN())
2647             {
2648                 OIC_LOG(ERROR, TAG, "_71_MOT_PROV_PRECONF_PIN_: error");
2649             }
2650             break;
2651         case _72_MOT_OXM_SEL_:
2652             if(selectMultipleOwnershipTrnasferMethod())
2653             {
2654                 OIC_LOG(ERROR, TAG, "_72_MOT_OXM_SEL_: error");
2655             }
2656             break;
2657         case _73_MOT_REMOVE_SUBOWNER_:
2658             if(removeSubOwner())
2659             {
2660                 OIC_LOG(ERROR, TAG, "_73_MOT_REMOVE_SUBOWNER_ : error");
2661             }
2662             break;
2663         case _74_MOT_REMOVE_ALL_SUBOWNER_:
2664             if(removeAllSubOwner())
2665             {
2666                 OIC_LOG(ERROR, TAG, "_74_MOT_REMOVE_ALL_SUBOWNER_ : error");
2667             }
2668             break;
2669 #endif //MULTIPLE_OWNER
2670 #ifdef __WITH_TLS__
2671         case  _80_SELECT_PROTOCOL_:
2672             selectSecureProtocol();
2673             break;
2674 #endif
2675         case _81_SELECT_VERIF_METHOD_:
2676             selectVerifMethod();
2677             break;
2678         case _82_SECURE_STORAGE_HW_EMULATION_:
2679             secureStorageHwEmulation();
2680             break;
2681         case _99_EXIT_PRVN_CLT_:
2682             goto PMCLT_ERROR;
2683         default:
2684             printf(">> Entered Wrong Number. Please Enter Again\n\n");
2685             break;
2686         }
2687     }
2688
2689 PMCLT_ERROR:
2690     if(OC_STACK_OK != OCStop())
2691     {
2692         OIC_LOG(ERROR, TAG, "OCStack stop error");
2693     }
2694     OCDeleteDiscoveredDevices(g_own_list);  // after here |g_own_list| points nothing
2695     OCDeleteDiscoveredDevices(g_unown_list);  // after here |g_unown_list| points nothing
2696 #ifdef MULTIPLE_OWNER
2697     OCDeleteDiscoveredDevices(g_mot_enable_list);  // after here |g_motdev_list| points nothing
2698 #endif //MULTIPLE_OWNER
2699
2700     if(g_svr_fname)
2701     {
2702         OICFree(g_svr_fname);  // after here |g_svr_fname| points nothing
2703     }
2704     if(g_prvn_fname)
2705     {
2706         OICFree(g_prvn_fname);  // after here |g_prvn_fname| points nothing
2707     }
2708     return 0;  // always return normal case
2709 }
2710
2711 #ifdef __cplusplus
2712 }
2713 #endif //__cplusplus