Update snapshot(2018-01-10)
[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
44 #ifdef __cplusplus
45 extern "C"
46 {
47 #endif //__cplusplus
48
49 // declaration(s) for provisioning client using C-level provisioning API
50 // user input definition for main loop on provisioning client
51 #define _10_DISCOV_ALL_DEVS_            10
52 #define _11_DISCOV_UNOWN_DEVS_          11
53 #define _12_DISCOV_OWN_DEVS_            12
54 #ifdef MULTIPLE_OWNER
55 #define _13_MOT_DISCOV_DEV_             13
56 #endif //MULTIPLE_OWNER
57 #define _20_REGIST_DEVS_                20
58 #define _30_PROVIS_PAIR_DEVS_           30
59 #define _31_PROVIS_CRED_                31
60 #define _32_PROVIS_ACL_                 32
61 #define _33_PROVIS_DP_                  33
62 #define _34_CHECK_LINK_STATUS_          34
63 #define _35_SAVE_ACL_                   35
64 #define _40_UNLINK_PAIR_DEVS_           40
65 #define _50_REMOVE_SELEC_DEV_           50
66 #define _51_REMOVE_DEV_WITH_UUID_       51
67 #define _52_RESET_SELEC_DEV_            52
68 #define _53_RESET_SVR_DB_               53
69 #define _60_GET_CRED_                   60
70 #define _61_GET_ACL_                    61
71 #ifdef MULTIPLE_OWNER
72 #define _70_MOT_CHANGE_MOM_             70
73 #define _71_MOT_PROV_PRECONF_PIN_       71
74 #define _72_MOT_OXM_SEL_                72
75 #define _73_MOT_REMOVE_SUBOWNER_        73
76 #define _74_MOT_REMOVE_ALL_SUBOWNER_        74
77 #endif //MULTIPLE_OWNER
78 #define _80_SELECT_PROTOCOL_            80
79 #define _81_SELECT_VERIF_METHOD_        81
80 #define _82_SECURE_STORAGE_HW_EMULATION_    82
81 #define _99_EXIT_PRVN_CLT_              99
82
83 #define ACL_RESRC_MAX_NUM   16
84 #define ACL_RESRC_ARRAY_SIZE   3 //This value is used only for sample (not OCF spec)
85 #define ACL_RESRC_MAX_LEN   128
86 #define ACL_PEMISN_CNT      5
87 #define DISCOVERY_TIMEOUT   10  // 10 sec
88 #define CALLBACK_TIMEOUT    60  // 1 min
89 #define TAG "provisioningclient"
90
91 static const char* ACL_PEMISN[5] = {"CREATE", "READ", "WRITE", "DELETE", "NOTIFY"};
92 static const char* SVR_DB_FILE_NAME = "oic_svr_db_client.dat";
93         // '_' for separaing from the same constant variable in |srmresourcestrings.c|
94 static const char* PRVN_DB_FILE_NAME = "oic_prvn_mng.db";
95 static const OicSecPrm_t  SUPPORTED_PRMS[1] =
96 {
97     PRM_PRE_CONFIGURED,
98 };
99
100 // |g_ctx| means provision manager application context and
101 // the following, includes |un/own_list|, could be variables, which |g_ctx| has,
102 // for accessing all function(s) for these, they are declared on global domain
103 static const char* g_ctx = "Provision Manager Client Application Context";
104 static char* g_svr_fname;
105 static char* g_prvn_fname;
106 static OCProvisionDev_t* g_own_list;
107 static OCProvisionDev_t* g_unown_list;
108 static int g_own_cnt;
109 static int g_unown_cnt;
110 #ifdef MULTIPLE_OWNER
111 static OCProvisionDev_t* g_mot_enable_list;
112 static int g_mot_enable_cnt;
113 #endif //MULTIPLE_OWNER
114
115 static bool g_doneCB;
116 #ifdef __WITH_TLS__
117 static int secure_protocol = 1;
118 static void setDevProtocol(OCProvisionDev_t* dev_lst);
119 #endif
120 // function declaration(s) for calling them before implementing
121 static OicSecAcl_t* createAcl(const int);
122 static OicSecAcl_t* createSimpleAcl(const OicUuid_t uuid);
123 static OicSecPdAcl_t* createPdAcl(const int);
124 static OCProvisionDev_t* getDevInst(const OCProvisionDev_t*, const int);
125 static int printDevList(const OCProvisionDev_t*);
126 static size_t printUuidList(const OCUuidList_t*);
127 static int printResultList(const OCProvisionResult_t*, const int);
128 static void printUuid(const OicUuid_t*);
129 static FILE* fopen_prvnMng(const char*, const char*);
130 static int waitCallbackRet(void);
131 static int selectTwoDiffNum(int*, int*, const int, const char*);
132
133 // callback function(s) for provisioning client using C-level provisioning API
134 static void ownershipTransferCB(void* ctx, int nOfRes, OCProvisionResult_t* arr, bool hasError)
135 {
136     if(!hasError)
137     {
138         OIC_LOG_V(INFO, TAG, "Ownership Transfer SUCCEEDED - ctx: %s", (char*) ctx);
139     }
140     else
141     {
142         OIC_LOG_V(ERROR, TAG, "Ownership Transfer FAILED - ctx: %s", (char*) ctx);
143         printResultList((const OCProvisionResult_t*) arr, nOfRes);
144     }
145     g_doneCB = true;
146 }
147
148 static void provisionPairwiseCB(void* ctx, int nOfRes, OCProvisionResult_t* arr, bool hasError)
149 {
150     if(!hasError)
151     {
152         OIC_LOG_V(INFO, TAG, "Provision Pairwise SUCCEEDED - ctx: %s", (char*) ctx);
153     }
154     else
155     {
156         OIC_LOG_V(ERROR, TAG, "Provision Pairwise FAILED - ctx: %s", (char*) ctx);
157         printResultList((const OCProvisionResult_t*) arr, nOfRes);
158     }
159     g_doneCB = true;
160 }
161
162 static void provisionCredCB(void* ctx, int nOfRes, OCProvisionResult_t* arr, bool hasError)
163 {
164     if(!hasError)
165     {
166         OIC_LOG_V(INFO, TAG, "Provision Credential SUCCEEDED - ctx: %s", (char*) ctx);
167     }
168     else
169     {
170         OIC_LOG_V(ERROR, TAG, "Provision Credential FAILED - ctx: %s", (char*) ctx);
171         printResultList((const OCProvisionResult_t*) arr, nOfRes);
172     }
173     g_doneCB = true;
174 }
175
176 static void provisionAclCB(void* ctx, int nOfRes, OCProvisionResult_t* arr, bool hasError)
177 {
178     if(!hasError)
179     {
180         OIC_LOG_V(INFO, TAG, "Provision ACL SUCCEEDED - ctx: %s", (char*) ctx);
181     }
182     else
183     {
184         OIC_LOG_V(ERROR, TAG, "Provision ACL FAILED - ctx: %s", (char*) ctx);
185         printResultList((const OCProvisionResult_t*) arr, nOfRes);
186     }
187     g_doneCB = true;
188 }
189
190 static void getCredCB(void* ctx, int nOfRes, OCProvisionResult_t* arr, bool hasError)
191 {
192     if(!hasError)
193     {
194         OIC_LOG_V(INFO, TAG, "getCredCB SUCCEEDED - ctx: %s", (char*) ctx);
195     }
196     else
197     {
198         OIC_LOG_V(ERROR, TAG, "getCredCB FAILED - ctx: %s", (char*) ctx);
199         printResultList((const OCProvisionResult_t*) arr, nOfRes);
200     }
201     g_doneCB = true;
202 }
203
204 static void getAclCB(void* ctx, int nOfRes, OCProvisionResult_t* arr, bool hasError)
205 {
206     if(!hasError)
207     {
208         OIC_LOG_V(INFO, TAG, "getAclCB SUCCEEDED - ctx: %s", (char*) ctx);
209     }
210     else
211     {
212         OIC_LOG_V(ERROR, TAG, "getAclCB FAILED - ctx: %s", (char*) ctx);
213         printResultList((const OCProvisionResult_t*) arr, nOfRes);
214     }
215     g_doneCB = true;
216 }
217
218 static void provisionDPCB(void* ctx, int nOfRes, OCProvisionResult_t* arr, bool hasError)
219 {
220     if(!hasError)
221     {
222         OIC_LOG_V(INFO, TAG, "Provision Direct-Pairing SUCCEEDED - ctx: %s", (char*) ctx);
223     }
224     else
225     {
226         OIC_LOG_V(ERROR, TAG, "Provision Direct-Pairing FAILED - ctx: %s", (char*) ctx);
227         printResultList((const OCProvisionResult_t*) arr, nOfRes);
228     }
229     g_doneCB = true;
230 }
231
232 static void unlinkDevicesCB(void* ctx, int nOfRes, OCProvisionResult_t* arr, bool hasError)
233 {
234     if(!hasError)
235     {
236         OIC_LOG_V(INFO, TAG, "Unlink Devices SUCCEEDED - ctx: %s", (char*) ctx);
237     }
238     else
239     {
240         OIC_LOG_V(ERROR, TAG, "Unlink Devices FAILED - ctx: %s", (char*) ctx);
241         printResultList((const OCProvisionResult_t*) arr, nOfRes);
242     }
243     g_doneCB = true;
244 }
245
246 static void removeDeviceCB(void* ctx, int nOfRes, OCProvisionResult_t* arr, bool hasError)
247 {
248     if(!hasError)
249     {
250         OIC_LOG_V(INFO, TAG, "Remove Device SUCCEEDED - ctx: %s", (char*) ctx);
251     }
252     else
253     {
254         OIC_LOG_V(ERROR, TAG, "Remove Device FAILED - ctx: %s", (char*) ctx);
255         printResultList((const OCProvisionResult_t*) arr, nOfRes);
256     }
257     g_doneCB = true;
258 }
259
260 static void resetDeviceCB(void* ctx, int nOfRes, OCProvisionResult_t* arr, bool hasError)
261 {
262     OC_UNUSED(ctx);
263     OIC_LOG_V(INFO, TAG, "Reset Device SUCCEEDED");
264     g_doneCB = true;
265 }
266
267 #ifdef MULTIPLE_OWNER
268 static void updateDoxmForMOTCB(void* ctx, int nOfRes, OCProvisionResult_t* arr, bool hasError)
269 {
270     if(!hasError)
271     {
272         OIC_LOG_V(INFO, TAG, "POST 'doxm' SUCCEEDED - ctx: %s", (char*) ctx);
273     }
274     else
275     {
276         OIC_LOG_V(ERROR, TAG, "POST 'doxm'  FAILED - ctx: %s", (char*) ctx);
277         printResultList((const OCProvisionResult_t*) arr, nOfRes);
278     }
279     g_doneCB = true;
280 }
281
282 static void deleteDoxmForMOTCB(void* ctx, int nOfRes, OCProvisionResult_t* arr, bool hasError)
283 {
284     if(!hasError)
285     {
286         OIC_LOG_V(INFO, TAG, "DELETE 'doxm' SUCCEEDED - ctx: %s", (char*) ctx);
287     }
288     else
289     {
290         OIC_LOG_V(ERROR, TAG, "DELETE 'doxm'  FAILED - ctx: %s", (char*) ctx);
291         printResultList((const OCProvisionResult_t*) arr, nOfRes);
292     }
293     g_doneCB = true;
294 }
295
296 #endif //MULTIPLE_OWNER
297
298 static void inputPinCB(char* pin, size_t len)
299 {
300     if(!pin || OXM_RANDOM_PIN_MIN_SIZE > len)
301     {
302         OIC_LOG(ERROR, TAG, "inputPinCB invalid parameters");
303         return;
304     }
305
306     printf("   > INPUT PIN: ");
307     for(int ret=0; 1!=ret; )
308     {
309         ret = scanf("%32s", pin);
310         for( ; 0x20<=getchar(); );  // for removing overflow garbages
311                                     // '0x20<=code' is character region
312     }
313 }
314
315 // function(s) for provisioning client using C-level provisioning API
316 static int initProvisionClient(void)
317 {
318     // initialize persistent storage for SVR DB
319     static OCPersistentStorage pstStr =
320     {
321         .open = fopen_prvnMng,
322         .read = fread,
323         .write = fwrite,
324         .close = fclose,
325         .unlink = unlink
326     };
327     if(OC_STACK_OK != OCRegisterPersistentStorageHandler(&pstStr))
328     {
329         OIC_LOG(ERROR, TAG, "OCRegisterPersistentStorageHandler error");
330         return -1;
331     }
332
333     // initialize OC stack and provisioning manager
334     if(OC_STACK_OK != OCInit(NULL, 0, OC_CLIENT_SERVER))
335     {
336         OIC_LOG(ERROR, TAG, "OCStack init error");
337         return -1;
338     }
339
340     if (access(PRVN_DB_FILE_NAME, F_OK) != -1)
341     {
342         printf("************************************************************\n");
343         printf("************Provisioning DB file already exists.************\n");
344         printf("************************************************************\n");
345     }
346     else
347     {
348         printf("*************************************************************\n");
349         printf("************No provisioning DB file, creating new************\n");
350         printf("*************************************************************\n");
351     }
352
353     if(OC_STACK_OK != OCInitPM(PRVN_DB_FILE_NAME))
354     {
355         OIC_LOG(ERROR, TAG, "OC_PM init error");
356         return -1;
357     }
358
359     SetInputPinCB(inputPinCB);
360
361     return 0;
362 }
363
364 static int discoverAllDevices(void)
365 {
366     // delete un/owned device lists before updating them
367     if(g_own_list)
368     {
369         OCDeleteDiscoveredDevices(g_own_list);
370         g_own_list = NULL;
371     }
372     if(g_unown_list)
373     {
374         OCDeleteDiscoveredDevices(g_unown_list);
375         g_unown_list = NULL;
376     }
377
378     // call |OCGetDevInfoFromNetwork| API actually
379     printf("   Discovering All Un/Owned Devices on Network..\n");
380     if(OC_STACK_OK != OCGetDevInfoFromNetwork(DISCOVERY_TIMEOUT, &g_own_list, &g_unown_list))
381     {
382         OIC_LOG(ERROR, TAG, "OCGetDevInfoFromNetwork API error");
383         return -1;
384     }
385
386     // display the discovered un/owned lists
387     printf("   > Discovered Owned Devices\n");
388     g_own_cnt = printDevList(g_own_list);
389     printf("   > Discovered Unowned Devices\n");
390     g_unown_cnt = printDevList(g_unown_list);
391 #ifdef __WITH_TLS__
392     setDevProtocol(g_own_list);
393     setDevProtocol(g_unown_list);
394 #endif
395     return 0;
396 }
397
398
399 static int discoverUnownedDevices(void)
400 {
401     // delete unowned device list before updating it
402     if(g_unown_list)
403     {
404         OCDeleteDiscoveredDevices(g_unown_list);
405         g_unown_list = NULL;
406     }
407
408     // call |OCDiscoverUnownedDevices| API actually
409     printf("   Discovering Only Unowned Devices on Network..\n");
410     if(OC_STACK_OK != OCDiscoverUnownedDevices(DISCOVERY_TIMEOUT, &g_unown_list))
411     {
412         OIC_LOG(ERROR, TAG, "OCDiscoverUnownedDevices API error");
413         return -1;
414     }
415
416     // display the discovered unowned list
417     printf("   > Discovered Unowned Devices\n");
418     g_unown_cnt = printDevList(g_unown_list);
419 #ifdef __WITH_TLS__
420     setDevProtocol(g_unown_list);
421 #endif
422     return 0;
423 }
424
425 static int discoverOwnedDevices(void)
426 {
427     // delete owned device list before updating it
428     if(g_own_list)
429     {
430         OCDeleteDiscoveredDevices(g_own_list);
431         g_own_list = NULL;
432     }
433
434     // call |OCDiscoverOwnedDevices| API actually
435     printf("   Discovering Only Owned Devices on Network..\n");
436     if(OC_STACK_OK != OCDiscoverOwnedDevices(DISCOVERY_TIMEOUT, &g_own_list))
437     {
438         OIC_LOG(ERROR, TAG, "OCDiscoverOwnedDevices API error");
439         return -1;
440     }
441
442     // display the discovered owned list
443     printf("   > Discovered Owned Devices\n");
444     g_own_cnt = printDevList(g_own_list);
445 #ifdef __WITH_TLS__
446     setDevProtocol(g_own_list);
447 #endif
448     return 0;
449 }
450
451 #ifdef MULTIPLE_OWNER
452 static int discoverMOTEnabledDevices(void)
453 {
454     // delete owned device list before updating it
455     if(g_mot_enable_list)
456     {
457         OCDeleteDiscoveredDevices(g_mot_enable_list);
458         g_mot_enable_list = NULL;
459     }
460
461     // call |OCDiscoverOwnedDevices| API actually
462     printf("   Discovering Multiple Ownership Transfer Enabled Devices on Network..\n");
463     if(OC_STACK_OK != OCDiscoverMultipleOwnerEnabledDevices(DISCOVERY_TIMEOUT, &g_mot_enable_list))
464     {
465         OIC_LOG(ERROR, TAG, "OCDiscoverMultipleOwnerEnalbedDevices API error");
466         return -1;
467     }
468
469     // display the discovered owned list
470     printf("   > Discovered Multiple Ownership Transfer Enabled Devices\n");
471     g_mot_enable_cnt = printDevList(g_mot_enable_list);
472
473     return 0;
474 }
475 #endif //MULTIPLE_OWNER
476
477 static int registerDevices(void)
478 {
479     // check |unown_list| for registering devices
480     if(!g_unown_list || 0>=g_unown_cnt)
481     {
482         printf("   > Unowned Device List, to Register Devices, is Empty\n");
483         printf("   > Please Discover Unowned Devices first, with [10|11] Menu\n");
484         return 0;  // normal case
485     }
486
487     // call |OCDoOwnershipTransfer| API actually
488     // calling this API with callback actually acts like blocking
489     // for error checking, the return value saved and printed
490     g_doneCB = false;
491     printf("   Registering All Discovered Unowned Devices..\n");
492     OCStackResult rst = OCDoOwnershipTransfer((void*) g_ctx, g_unown_list, ownershipTransferCB);
493     if(OC_STACK_OK != rst)
494     {
495         OIC_LOG_V(ERROR, TAG, "OCDoOwnershipTransfer API error: %d", rst);
496         return -1;
497     }
498     if(waitCallbackRet())  // input |g_doneCB| flag implicitly
499     {
500         OIC_LOG(ERROR, TAG, "OCProvisionCredentials callback error");
501         return -1;
502     }
503
504     // display the registered result
505     printf("   > Registered Discovered Unowned Devices\n");
506     printf("   > Please Discover Owned Devices for the Registered Result, with [10|12] Menu\n");
507
508     return 0;
509 }
510
511 static int provisionPairwise(void)
512 {
513     // check |own_list| for provisioning pairwise devices
514     if(!g_own_list || 2>g_own_cnt)
515     {
516         printf("   > Owned Device List, to Provision the Pairwise, is Empty\n");
517         printf("   > Please Register Unowned Devices first, with [20] Menu\n");
518         return 0;  // normal case
519     }
520
521     // select two devices for provisioning pairwise devices
522     int dev_num[2] = {0};
523     if(selectTwoDiffNum(&(dev_num[0]), &(dev_num[1]), g_own_cnt, "for Linking Devices"))
524     {
525         OIC_LOG(ERROR, TAG, "selectTwoDiffNum error return");
526         return -1;  // not need to 'goto' |ERROR| before allocating |acl|
527     }
528
529     // create ACL(s) for each selected device
530     OicSecAcl_t* acl[2] = {0};
531     for(int i=0; 2>i; ++i)
532     {
533         acl[i] = createAcl(dev_num[i]);
534         if(!acl[i])
535         {
536             OIC_LOG(ERROR, TAG, "createAcl error return");
537             goto PVPWS_ERROR;
538         }
539     }
540
541     // call |OCProvisionPairwiseDevices| API actually
542     // calling this API with callback actually acts like blocking
543     // for error checking, the return value saved and printed
544     g_doneCB = false;
545     printf("   Provisioning Selected Pairwise Devices..\n");
546     OCStackResult rst =
547             OCProvisionPairwiseDevices((void*) g_ctx,
548                     SYMMETRIC_PAIR_WISE_KEY, OWNER_PSK_LENGTH_128,
549                     getDevInst((const OCProvisionDev_t*) g_own_list, dev_num[0]), acl[0],
550                     getDevInst((const OCProvisionDev_t*) g_own_list, dev_num[1]), acl[1],
551                     provisionPairwiseCB);
552     if(OC_STACK_OK != rst)
553     {
554         OIC_LOG_V(ERROR, TAG, "OCProvisionPairwiseDevices API error: %d", rst);
555         goto PVPWS_ERROR;
556     }
557     if(waitCallbackRet())  // input |g_doneCB| flag implicitly
558     {
559         OIC_LOG(ERROR, TAG, "OCProvisionCredentials callback error");
560         goto PVPWS_ERROR;
561     }
562     OCDeleteACLList(acl[0]);
563     OCDeleteACLList(acl[1]);
564
565     // display the pairwise-provisioned result
566     printf("   > Provisioned Selected Pairwise Devices\n");
567     printf("   > Please Check Device's Status for the Linked Result, with [33] Menu\n");
568
569     return 0;
570
571 PVPWS_ERROR:
572     OCDeleteACLList(acl[0]);
573     OCDeleteACLList(acl[1]);
574     return -1;
575 }
576
577 static int provisionCred(void)
578 {
579     // check |own_list| for provisioning pairwise credentials
580     if(!g_own_list || 2>g_own_cnt)
581     {
582         printf("   > Owned Device List, to Provision Credentials, is Empty\n");
583         printf("   > Please Register Unowned Devices first, with [20] Menu\n");
584         return 0;  // normal case
585     }
586
587     // select two devices for provisioning pairwise credentials
588     int dev_num[2] = {0};
589     if(selectTwoDiffNum(&(dev_num[0]), &(dev_num[1]), g_own_cnt, "for Linking CRED(s)"))
590     {
591         OIC_LOG(ERROR, TAG, "selectTwoDiffNum error return");
592         return -1;
593     }
594
595     printf("   Select PSK length..\n");
596     printf("   1 - 128bit(Default)\n");
597     printf("   2 - 256bit\n");
598     int sizeOption = 0;
599
600     for(int ret=0; 1!=ret; )
601     {
602          ret = scanf("%d",&sizeOption);
603          for( ; 0x20<=getchar(); );  // for removing overflow garbages
604                                     // '0x20<=code' is character region
605     }
606     size_t size = 0;
607
608     switch(sizeOption)
609     {
610         case 1:
611         {
612             size = OWNER_PSK_LENGTH_128;
613             break;
614         }
615         case 2:
616         {
617             size = OWNER_PSK_LENGTH_256;
618             break;
619         }
620         default:
621         {
622             size = OWNER_PSK_LENGTH_128;
623             break;
624         }
625     }
626
627
628     // call |OCProvisionCredentials| API actually
629     // calling this API with callback actually acts like blocking
630     // for error checking, the return value saved and printed
631     g_doneCB = false;
632     printf("   Provisioning Selected Pairwise Credentials..\n");
633     OCStackResult rst =
634             OCProvisionCredentials((void*) g_ctx,
635                     SYMMETRIC_PAIR_WISE_KEY, size,
636                     getDevInst((const OCProvisionDev_t*) g_own_list, dev_num[0]),
637                     getDevInst((const OCProvisionDev_t*) g_own_list, dev_num[1]),
638                     provisionCredCB);
639     if(OC_STACK_OK != rst)
640     {
641         OIC_LOG_V(ERROR, TAG, "OCProvisionCredentials API error: %d", rst);
642         return -1;
643     }
644     if(waitCallbackRet())  // input |g_doneCB| flag implicitly
645     {
646         OIC_LOG(ERROR, TAG, "OCProvisionCredentials callback error");
647         return -1;
648     }
649
650     // display the CRED-provisioned result
651     printf("   > Provisioned Selected Pairwise Crendentials\n");
652     printf("   > Please Check Device's Status for the Linked Result, with [34] Menu\n");
653
654     return 0;
655 }
656
657 static int provisionAcl(void)
658 {
659     // check |own_list| for provisioning access control list
660     if(!g_own_list || 1>g_own_cnt)
661     {
662         printf("   > Owned Device List, to Provision ACL, is Empty\n");
663         printf("   > Please Register Unowned Devices first, with [20] Menu\n");
664         return 0;  // normal case
665     }
666
667     // select device for provisioning access control list
668     int dev_num = 0;
669     for( ; ; )
670     {
671         printf("   > Enter Device Number, for Provisioning ACL: ");
672         for(int ret=0; 1!=ret; )
673         {
674             ret = scanf("%d", &dev_num);
675             for( ; 0x20<=getchar(); );  // for removing overflow garbages
676                                         // '0x20<=code' is character region
677         }
678         if(0<dev_num && g_own_cnt>=dev_num)
679         {
680             break;
681         }
682         printf("     Entered Wrong Number. Please Enter Again\n");
683     }
684
685     // create ACL for selected device
686     OicSecAcl_t* acl = NULL;
687     acl = createAcl(dev_num);
688     if(!acl)
689     {
690         OIC_LOG(ERROR, TAG, "createAcl error return");
691         goto PVACL_ERROR;
692     }
693
694     // call |OCProvisionACL| API actually
695     // calling this API with callback actually acts like blocking
696     // for error checking, the return value saved and printed
697     g_doneCB = false;
698     printf("   Provisioning Selected ACL..\n");
699     OCProvisionDev_t* dev = getDevInst((const OCProvisionDev_t*) g_own_list, dev_num);
700     if(!dev)
701     {
702         OIC_LOG(ERROR, TAG, "provisionAcl: device instance empty");
703         goto PVACL_ERROR;
704     }
705     OCStackResult rst = OCProvisionACL((void*) g_ctx, dev, acl, provisionAclCB);
706     if(OC_STACK_OK != rst)
707     {
708         OIC_LOG_V(ERROR, TAG, "OCProvisionACL API error: %d", rst);
709         goto PVACL_ERROR;
710     }
711     if(waitCallbackRet())  // input |g_doneCB| flag implicitly
712     {
713         OIC_LOG(ERROR, TAG, "OCProvisionCredentials callback error");
714         goto PVACL_ERROR;
715     }
716     OCDeleteACLList(acl);  // after here |acl| points nothing
717
718     // display the ACL-provisioned result
719     printf("   > Provisioned Selected ACL\n");
720
721     return 0;
722
723 PVACL_ERROR:
724     OCDeleteACLList(acl);  // after here |acl| points nothing
725     return -1;
726 }
727
728 static int provisionDirectPairing(void)
729 {
730     // check |own_list| for provisioning direct-pairing
731     if(!g_own_list || 1>g_own_cnt)
732     {
733         printf("   > Owned Device List, to Provision ACL, is Empty\n");
734         printf("   > Please Register Unowned Devices first, with [20] Menu\n");
735         return 0;  // normal case
736     }
737
738     // select device for provisioning direct-pairing
739     int dev_num = 0;
740     for( ; ; )
741     {
742         printf("   > Enter Device Number, for Provisioning Direct-Pairing: ");
743         for(int ret=0; 1!=ret; )
744         {
745             ret = scanf("%d", &dev_num);
746             for( ; 0x20<=getchar(); );  // for removing overflow garbages
747                                         // '0x20<=code' is character region
748         }
749         if(0<dev_num && g_own_cnt>=dev_num)
750         {
751             break;
752         }
753         printf("     Entered Wrong Number. Please Enter Again\n");
754     }
755
756     // create Direct-Pairing Configuration(PIN, PDACL) for selected device
757     // TODO: default acl -> input from user !
758     OicSecPconf_t pconf;
759     memset(&pconf, 0, sizeof(OicSecPconf_t));
760
761     // set enable dp
762     pconf.edp = true;
763
764     // set default supported PRM types
765     pconf.prmLen = sizeof(SUPPORTED_PRMS)/sizeof(OicSecPrm_t);
766     pconf.prm = (OicSecPrm_t *)OICCalloc(pconf.prmLen, sizeof(OicSecPrm_t));
767     if(pconf.prm)
768     {
769         for (size_t i=0; i<pconf.prmLen; i++)
770         {
771             pconf.prm[i] = SUPPORTED_PRMS[i];
772         }
773     }
774     else
775     {
776         OIC_LOG(ERROR, TAG, "create prm error return");
777         goto PVDP_ERROR;
778     }
779
780     // set default pin
781     const char DP_DEFAULT_PIN[] = "00000000";
782     memcpy(pconf.pin.val, DP_DEFAULT_PIN, DP_PIN_LENGTH);
783
784     // set default pdacl
785     pconf.pdacls = createPdAcl(dev_num);
786     if(!pconf.pdacls)
787     {
788         OIC_LOG(ERROR, TAG, "createPdAcl error return");
789         goto PVDP_ERROR;
790     }
791
792     // call |OCProvisionDirectPairing| API actually
793     // calling this API with callback actually acts like blocking
794     // for error checking, the return value saved and printed
795     g_doneCB = false;
796     printf("   Atempt Direct-Pairing Provisioning (PIN : [%s])..\n", (char*)pconf.pin.val);
797     OCStackResult rst = OCProvisionDirectPairing((void*) g_ctx,
798                                        getDevInst((const OCProvisionDev_t*) g_own_list, dev_num),
799                                        &pconf, provisionDPCB);
800     if(OC_STACK_OK != rst)
801     {
802         OIC_LOG_V(ERROR, TAG, "OCProvisionDirectPairing API error: %d", rst);
803         if (OC_STACK_UNAUTHORIZED_REQ == rst)
804         {
805             OIC_LOG(ERROR, TAG, "Target Server NOT Support Direct-Pairing !!! (DPC == false)");
806         }
807         goto PVDP_ERROR;
808     }
809     if(waitCallbackRet())  // input |g_doneCB| flag implicitly
810     {
811         OIC_LOG(ERROR, TAG, "OCProvisionCredentials callback error");
812         goto PVDP_ERROR;
813     }
814     OCDeletePdAclList(pconf.pdacls);
815
816     // display the PCONF-provisioned result
817     printf("   > SUCCESS to provision Direct-Pairing !!\n");
818
819     return 0;
820
821 PVDP_ERROR:
822     OCDeletePdAclList(pconf.pdacls);  // after here |acl| points nothing
823     return -1;
824 }
825
826 static int checkLinkedStatus(void)
827 {
828     // check |own_list| for checking selected link status on PRVN DB
829     if(!g_own_list || 1>g_own_cnt)
830     {
831         printf("   > Owned Device List, to Check Linked Status on PRVN DB, is Empty\n");
832         printf("   > Please Register Unowned Devices first, with [20] Menu\n");
833         return 0;  // normal case
834     }
835
836     // select device for checking selected link status on PRVN DB
837     int dev_num = 0;
838     for( ; ; )
839     {
840         printf("   > Enter Device Number, for Checking Linked Status on PRVN DB: ");
841         for(int ret=0; 1!=ret; )
842         {
843             ret = scanf("%d", &dev_num);
844             for( ; 0x20<=getchar(); );  // for removing overflow garbages
845                                         // '0x20<=code' is character region
846         }
847         if(0<dev_num && g_own_cnt>=dev_num)
848         {
849             break;
850         }
851         printf("     Entered Wrong Number. Please Enter Again\n");
852     }
853
854     // call |OCGetLinkedStatus| API actually
855     printf("   Checking Selected Link Status on PRVN DB..\n");
856     OCUuidList_t* dvid_lst = NULL;
857     size_t dvid_cnt = 0;
858     OCProvisionDev_t* dev = getDevInst((const OCProvisionDev_t*)g_own_list, dev_num);
859     if(!dev || !dev->doxm)
860     {
861         OIC_LOG(ERROR, TAG, "checkLinkedStatus: device instance empty");
862         goto CKLST_ERROR;
863     }
864
865     if(OC_STACK_OK !=
866             OCGetLinkedStatus(
867                     &dev->doxm->deviceID,
868                     &dvid_lst, &dvid_cnt))  // allow empty list
869     {
870         OIC_LOG(ERROR, TAG, "OCGetLinkedStatus API error");
871         goto CKLST_ERROR;
872     }
873
874     // display the linked status result
875     printf("   > Checked Selected Link Status on PRVN DB\n");
876     if(!dvid_lst || !dvid_cnt)  // |size_t| is unsigned
877     {
878         printf("     Linked Device List is Empty..\n");
879         return 0;  // normal case
880     }
881     if(dvid_cnt != printUuidList((const OCUuidList_t*) dvid_lst))
882     {
883         OIC_LOG(ERROR, TAG, "printUuidList error return");
884         goto CKLST_ERROR;
885     }
886     OCDeleteUuidList(dvid_lst);
887
888     return 0;
889
890 CKLST_ERROR:
891     OCDeleteUuidList(dvid_lst);
892     return -1;
893 }
894
895 static int saveAcl(void)
896 {
897     // create ACL to save into local SVR DB
898     OicSecAcl_t* acl = NULL;
899     OicUuid_t uuid =   {.id={0}};
900     char strUuid[64] = {0};
901
902     printf("[1] Use a test UUID [11111111-2222-3333-4444-555555555555]\n");
903     printf("[2] Use a user input\n");
904     int sel_num = 0;
905     for( ; ; )
906     {
907         printf("   > Select Number, for Subject UUID of new ACE: ");
908         for(int ret=0; 1!=ret; )
909         {
910             ret = scanf("%d", &sel_num);
911             for( ; 0x20<=getchar(); );  // for removing overflow garbages
912                                         // '0x20<=code' is character region
913         }
914         if(1 == sel_num)
915         {
916             OICStrcpy(strUuid, sizeof(strUuid), "11111111-2222-3333-4444-555555555555");
917             break;
918         }
919         else if(2 == sel_num)
920         {
921             printf("   > Input the UUID : ");
922             for(int ret=0; 1!=ret; )
923             {
924                 ret = scanf("%64s", strUuid);
925                 for( ; 0x20<=getchar(); );  // for removing overflow garbages
926                                         // '0x20<=code' is character region
927             }
928             break;
929         }
930         printf("     Entered Wrong Number. Please Enter Again\n");
931     }
932
933
934     printf("Selected Subject UUID : %s\n", strUuid);
935     OCStackResult rst = ConvertStrToUuid(strUuid, &uuid);
936     if(OC_STACK_OK != rst)
937     {
938         OIC_LOG_V(ERROR, TAG, "ConvertStrToUuid API error: %d", rst);
939         goto SVACL_ERROR;
940     }
941
942     acl = createSimpleAcl(uuid);
943     if(!acl)
944     {
945         OIC_LOG(ERROR, TAG, "createAcl error return");
946         goto SVACL_ERROR;
947     }
948
949     // call |OCSaveACL| API actually
950     rst = OCSaveACL(acl);
951     if(OC_STACK_OK != rst)
952     {
953         OIC_LOG_V(ERROR, TAG, "OCSaveACL API error: %d", rst);
954         goto SVACL_ERROR;
955     }
956     OCDeleteACLList(acl);  // after here |acl| points nothing
957
958     // display the ACL-provisioned result
959     printf("   > Saved Selected ACL\n");
960
961     return 0;
962
963 SVACL_ERROR:
964     OCDeleteACLList(acl);  // after here |acl| points nothing
965     return -1;
966 }
967
968 static int getCred(void)
969 {
970     // check |own_list| for checking selected link status on PRVN DB
971     if(!g_own_list || 1>g_own_cnt)
972     {
973         printf("   > Owned Device List, to Check Linked Status on PRVN DB, is Empty\n");
974         printf("   > Please Register Unowned Devices first, with [20] Menu\n");
975         return 0;  // normal case
976     }
977
978     // select device for checking selected link status on PRVN DB
979     int dev_num = 0;
980     for( ; ; )
981     {
982         printf("   > Enter Device Number, for Checking Linked Status on PRVN DB: ");
983         for(int ret=0; 1!=ret; )
984         {
985             ret = scanf("%d", &dev_num);
986             for( ; 0x20<=getchar(); );  // for removing overflow garbages
987                                         // '0x20<=code' is character region
988         }
989         if(0<dev_num && g_own_cnt>=dev_num)
990         {
991             break;
992         }
993         printf("     Entered Wrong Number. Please Enter Again\n");
994     }
995
996     // call |getDevInst| API actually
997     // calling this API with callback actually acts like blocking
998     // for error checking, the return value saved and printed
999     g_doneCB = false;
1000     OCProvisionDev_t* dev = getDevInst((const OCProvisionDev_t*) g_own_list, dev_num);
1001     if(!dev)
1002     {
1003         OIC_LOG(ERROR, TAG, "getDevInst: device instance empty");
1004         goto PVACL_ERROR;
1005     }
1006     OCStackResult rst = OCGetCredResource((void*) g_ctx, dev, getCredCB);
1007     if(OC_STACK_OK != rst)
1008     {
1009         OIC_LOG_V(ERROR, TAG, "OCGetCred API error: %d", rst);
1010         goto PVACL_ERROR;
1011     }
1012     if(waitCallbackRet())  // input |g_doneCB| flag implicitly
1013     {
1014         OIC_LOG(ERROR, TAG, "OCGetCredResource callback error");
1015         goto PVACL_ERROR;
1016     }
1017
1018     // display the result of get credential
1019     printf("   > Get Cred SUCCEEDED\n");
1020
1021     return 0;
1022
1023 PVACL_ERROR:
1024     return -1;
1025 }
1026
1027 static int getAcl(void)
1028 {
1029     // check |own_list| for checking selected link status on PRVN DB
1030     if(!g_own_list || 1>g_own_cnt)
1031     {
1032         printf("   > Owned Device List, to Check Linked Status on PRVN DB, is Empty\n");
1033         printf("   > Please Register Unowned Devices first, with [20] Menu\n");
1034         return 0;  // normal case
1035     }
1036
1037     // select device for checking selected link status on PRVN DB
1038     int dev_num = 0;
1039     for( ; ; )
1040     {
1041         printf("   > Enter Device Number, for Checking Linked Status on PRVN DB: ");
1042         for(int ret=0; 1!=ret; )
1043         {
1044             ret = scanf("%d", &dev_num);
1045             for( ; 0x20<=getchar(); );  // for removing overflow garbages
1046                                         // '0x20<=code' is character region
1047         }
1048         if(0<dev_num && g_own_cnt>=dev_num)
1049         {
1050             break;
1051         }
1052         printf("     Entered Wrong Number. Please Enter Again\n");
1053     }
1054
1055     // call |getDevInst| API actually
1056     // calling this API with callback actually acts like blocking
1057     // for error checking, the return value saved and printed
1058     g_doneCB = false;
1059     OCProvisionDev_t* dev = getDevInst((const OCProvisionDev_t*) g_own_list, dev_num);
1060     if(!dev)
1061     {
1062         OIC_LOG(ERROR, TAG, "getDevInst: device instance empty");
1063         goto PVACL_ERROR;
1064     }
1065     OCStackResult rst = OCGetACLResource((void*) g_ctx, dev, getAclCB);
1066     if(OC_STACK_OK != rst)
1067     {
1068         OIC_LOG_V(ERROR, TAG, "OCGetACLResource API error: %d", rst);
1069
1070         goto PVACL_ERROR;
1071     }
1072     if(waitCallbackRet())  // input |g_doneCB| flag implicitly
1073     {
1074         OIC_LOG(ERROR, TAG, "OCGetACLResource callback error");
1075         goto PVACL_ERROR;
1076     }
1077
1078     // display the result of get credential
1079     printf("   > Get ACL SUCCEEDED\n");
1080
1081     return 0;
1082
1083 PVACL_ERROR:
1084     return -1;
1085 }
1086
1087 static int unlinkPairwise(void)
1088 {
1089     // check |own_list| for unlinking pairwise devices
1090     if(!g_own_list || 2>g_own_cnt)
1091     {
1092         printf("   > Owned Device List, to Unlink the Pairwise, is Empty\n");
1093         printf("   > Please Register Unowned Devices first, with [20] Menu\n");
1094         return 0;  // normal case
1095     }
1096
1097     // select two devices for unlinking pairwise devices
1098     int dev_num[2] = {0};
1099     if(selectTwoDiffNum(&(dev_num[0]), &(dev_num[1]), g_own_cnt, "for Unlinking Devices"))
1100     {
1101         OIC_LOG(ERROR, TAG, "selectTwoDiffNum error return");
1102         return -1;
1103     }
1104
1105     // call |OCUnlinkDevices| API actually
1106     // calling this API with callback actually acts like blocking
1107     // for error checking, the return value saved and printed
1108     g_doneCB = false;
1109     printf("   Unlinking Selected Pairwise Devices..\n");
1110     OCStackResult rst =
1111             OCUnlinkDevices((void*) g_ctx,
1112                     getDevInst((const OCProvisionDev_t*) g_own_list, dev_num[0]),
1113                     getDevInst((const OCProvisionDev_t*) g_own_list, dev_num[1]),
1114                     unlinkDevicesCB);
1115     if(OC_STACK_OK != rst)
1116     {
1117         OIC_LOG_V(ERROR, TAG, "OCUnlinkDevices API error: %d", rst);
1118         return -1;
1119     }
1120     if(waitCallbackRet())  // input |g_doneCB| flag implicitly
1121     {
1122         OIC_LOG(ERROR, TAG, "OCProvisionCredentials callback error");
1123         return -1;
1124     }
1125
1126     // display the pairwise-unlinked result
1127     printf("   > Unlinked Selected Pairwise Devices\n");
1128     printf("   > Please Check Device's Status for the Unlinked Result, with [33] Menu\n");
1129
1130     return 0;
1131 }
1132
1133 static int removeDevice(void)
1134 {
1135     // check |own_list| for removing device
1136     if(!g_own_list || 1>g_own_cnt)
1137     {
1138         printf("   > Owned Device List, to Remove Device, is Empty\n");
1139         printf("   > Please Register Unowned Devices first, with [20] Menu\n");
1140         return 0;  // normal case
1141     }
1142
1143     // select device for removing it
1144     int dev_num = 0;
1145     for( ; ; )
1146     {
1147         printf("   > Enter Device Number, for Removing Device: ");
1148         for(int ret=0; 1!=ret; )
1149         {
1150             ret = scanf("%d", &dev_num);
1151             for( ; 0x20<=getchar(); );  // for removing overflow garbages
1152                                         // '0x20<=code' is character region
1153         }
1154         if(0<dev_num && g_own_cnt>=dev_num)
1155         {
1156             break;
1157         }
1158         printf("     Entered Wrong Number. Please Enter Again\n");
1159     }
1160
1161     // call |OCRemoveDevice| API actually
1162     // calling this API with callback actually acts like blocking
1163     // for error checking, the return value saved and printed
1164     g_doneCB = false;
1165     printf("   Removing Selected Owned Device..\n");
1166     OCStackResult rst =
1167             OCRemoveDevice((void*) g_ctx, DISCOVERY_TIMEOUT,
1168                     getDevInst((const OCProvisionDev_t*) g_own_list, dev_num), removeDeviceCB);
1169     if(OC_STACK_OK != rst)
1170     {
1171         OIC_LOG_V(ERROR, TAG, "OCRemoveDevice API error: %d", rst);
1172         return -1;
1173     }
1174     if(waitCallbackRet())  // input |g_doneCB| flag implicitly
1175     {
1176         OIC_LOG(ERROR, TAG, "OCProvisionCredentials callback error");
1177         return -1;
1178     }
1179
1180     // display the removed result
1181     printf("   > Removed Selected Owned Device\n");
1182     printf("   > Please Discover Owned Devices for the Registered Result, with [10|12] Menu\n");
1183
1184     return 0;
1185 }
1186
1187 static int removeDeviceWithUuid(void)
1188 {
1189     char strUuid[64] = {0};
1190     OicUuid_t revUuid;
1191     printf("Input the UUID : ");
1192     for(int ret=0; 1!=ret; )
1193     {
1194         ret = scanf("%63s", strUuid);
1195         for( ; 0x20<=getchar(); );  // for removing overflow garbages
1196                                     // '0x20<=code' is character region
1197     }
1198     OCStackResult rst = ConvertStrToUuid(strUuid, &revUuid);
1199     if(OC_STACK_OK != rst)
1200     {
1201         OIC_LOG_V(ERROR, TAG, "ConvertStrToUuid API error: %d", rst);
1202         return -1;
1203     }
1204
1205     g_doneCB = false;
1206     rst = OCRemoveDeviceWithUuid("RemoveDeviceWithUUID", DISCOVERY_TIMEOUT, &revUuid, removeDeviceCB);
1207     if(OC_STACK_OK != rst)
1208     {
1209         OIC_LOG_V(ERROR, TAG, "OCRemoveDeviceWithUuid API error: %d", rst);
1210         return -1;
1211     }
1212
1213     if(waitCallbackRet())  // input |g_doneCB| flag implicitly
1214     {
1215         OIC_LOG(ERROR, TAG, "OCRemoveDeviceWithUuid callback error");
1216         return -1;
1217     }
1218
1219     // display the removed result
1220     printf("   > Removed %s Device\n", strUuid);
1221     printf("   > Please Discover Owned Devices for the Registered Result, with [10|12] Menu\n");
1222
1223     return 0;
1224 }
1225
1226 OCStackResult displayNumCB(void * ctx, uint8_t mutualVerifNum[MUTUAL_VERIF_NUM_LEN])
1227 {
1228     OIC_LOG(INFO, TAG, "IN displayMutualVerifNumCB");
1229     OC_UNUSED(ctx);
1230     if (NULL != mutualVerifNum)
1231     {
1232         OIC_LOG(INFO, TAG, "############ mutualVerifNum ############");
1233         OIC_LOG_BUFFER(INFO, TAG, mutualVerifNum, MUTUAL_VERIF_NUM_LEN);
1234         OIC_LOG(INFO, TAG, "############ mutualVerifNum ############");
1235         OIC_LOG(INFO, TAG, "OUT displayMutualVerifNumCB");
1236     }
1237     else
1238     {
1239         OIC_LOG(INFO, TAG, "############ Confirm on the Server side ############");
1240     }
1241     return OC_STACK_OK;
1242 }
1243
1244 OCStackResult confirmNumCB(void * ctx)
1245 {
1246     OC_UNUSED(ctx);
1247     for (;;)
1248     {
1249         int userConfirm;
1250
1251         printf("   > Press 1 if the mutual verification numbers are the same\n");
1252         printf("   > Press 0 if the mutual verification numbers are not the same\n");
1253
1254         for (int ret=0; 1!=ret; )
1255         {
1256             ret = scanf("%d", &userConfirm);
1257             for (; 0x20<=getchar(); );  // for removing overflow garbage
1258                                         // '0x20<=code' is character region
1259         }
1260         if (1 == userConfirm)
1261         {
1262             break;
1263         }
1264         else if (0 == userConfirm)
1265         {
1266             return OC_STACK_USER_DENIED_REQ;
1267         }
1268         printf("   Entered Wrong Number. Please Enter Again\n");
1269     }
1270     return OC_STACK_OK;
1271 }
1272
1273 OCStackResult notifyInputStateCB(void * ctx)
1274 {
1275     OC_UNUSED(ctx);
1276
1277     OIC_LOG(DEBUG, TAG, "IN notifyInputStateCB");
1278     OIC_LOG(DEBUG, TAG, "User input Callback in progress");
1279     OIC_LOG(DEBUG, TAG, "OUT notifyInputStateCB");
1280
1281     return OC_STACK_OK;
1282 }
1283
1284 #ifdef MULTIPLE_OWNER
1285 static int changeMultipleOwnershipTrnasferMode(void)
1286 {
1287     // check |own_list| for removing device
1288     if(!g_own_list || 1>g_own_cnt)
1289     {
1290         printf("   > Owned Device List is Empty\n");
1291         printf("   > Please Discover the Owned Devices, with [12] Menu\n");
1292         return 0;  // normal case
1293     }
1294
1295     // select device for removing it
1296     int dev_num = 0;
1297     for( ; ; )
1298     {
1299         printf("   > Enter Device Number, for MOT Device: ");
1300         for(int ret=0; 1!=ret; )
1301         {
1302             ret = scanf("%d", &dev_num);
1303             for( ; 0x20<=getchar(); );  // for removing overflow garbages
1304                                         // '0x20<=code' is character region
1305         }
1306         if(0<dev_num && g_own_cnt>=dev_num)
1307         {
1308             break;
1309         }
1310         printf("     Entered Wrong Number. Please Enter Again\n");
1311     }
1312
1313     int mom = 0;
1314     for( ; ; )
1315     {
1316         printf("   0. Disable Multuple Ownership Transfer\n");
1317         printf("   1. Enable Multuple Ownership Transfer\n");
1318         printf("   2. (Not Supported yet) Timely Enable Multuple Ownership Transfer\n");
1319         printf("   > Enter Mode of Multuple Ownership Transfer : ");
1320         for(int ret=0; 1!=ret; )
1321         {
1322             ret = scanf("%d", &mom);
1323             for( ; 0x20<=getchar(); );  // for removing overflow garbages
1324                                         // '0x20<=code' is character region
1325         }
1326         if(0 <= dev_num && OIC_NUMBER_OF_MOM_TYPE > dev_num)
1327         {
1328             break;
1329         }
1330         printf("     Entered Wrong Number. Please Enter Again\n");
1331     }
1332
1333     OCProvisionDev_t* motDev = getDevInst(g_own_list, dev_num);
1334     if(OC_STACK_OK == OCChangeMOTMode(NULL, motDev, (OicSecMomType_t)dev_num, updateDoxmForMOTCB))
1335     {
1336         g_doneCB = false;
1337     }
1338     else
1339     {
1340         OIC_LOG(ERROR, TAG, "OCChangeMOTMode API error");
1341         return -1;
1342     }
1343
1344     if(waitCallbackRet())  // input |g_doneCB| flag implicitly
1345     {
1346         OIC_LOG(ERROR, TAG, "waitCallbackRet callback error");
1347         return -1;
1348     }
1349
1350     return 0;
1351 }
1352
1353 static int selectMultipleOwnershipTrnasferMethod(void)
1354 {
1355     // check |own_list| for removing device
1356     if(!g_mot_enable_list || 1>g_mot_enable_cnt)
1357     {
1358         printf("   > Multiple Ownership Transfer Enabled Device List is Empty\n");
1359         printf("   > Please Discover the Multiple Ownership Transfer Enabled Devices, with [13] Menu\n");
1360         return 0;  // normal case
1361     }
1362
1363     // select device for removing it
1364     int dev_num = 0;
1365     for( ; ; )
1366     {
1367         printf("   > Enter Device Number, for MOT Device: ");
1368         for(int ret=0; 1!=ret; )
1369         {
1370             ret = scanf("%d", &dev_num);
1371             for( ; 0x20<=getchar(); );  // for removing overflow garbages
1372                                         // '0x20<=code' is character region
1373         }
1374         if(0<dev_num && g_mot_enable_cnt>=dev_num)
1375         {
1376             break;
1377         }
1378         printf("     Entered Wrong Number. Please Enter Again\n");
1379     }
1380
1381     const int preconfOxm = 4;
1382     int oxm = 0;
1383     for( ; ; )
1384     {
1385         printf("   %d. (Not Supported)\n", OIC_JUST_WORKS);
1386         printf("   %d. Random PIN OxM\n", OIC_RANDOM_DEVICE_PIN);
1387         printf("   %d. (Not Supported)\n", OIC_MANUFACTURER_CERTIFICATE);
1388         printf("   %d. (Not Supported)\n", OIC_DECENTRALIZED_PUBLIC_KEY);
1389         printf("   %d. Pre-Configured PIN OxM\n", OIC_PRECONFIG_PIN);
1390         printf("   > Enter Number of  OxM for Multiple Ownership Transfer : ");
1391         for(int ret=0; 1!=ret; )
1392         {
1393             ret = scanf("%d", &oxm);
1394             for( ; 0x20<=getchar(); );  // for removing overflow garbages
1395                                         // '0x20<=code' is character region
1396         }
1397         if(OIC_PRECONFIG_PIN == oxm || OIC_RANDOM_DEVICE_PIN == oxm)
1398         {
1399             break;
1400         }
1401         printf("     Entered Wrong Number. Please Enter Again\n");
1402     }
1403
1404     OCProvisionDev_t* motDev = getDevInst(g_mot_enable_list, dev_num);
1405     if(OC_STACK_OK ==  OCSelectMOTMethod(NULL, motDev, (OicSecOxm_t)oxm, updateDoxmForMOTCB))
1406     {
1407         g_doneCB = false;
1408     }
1409     else
1410     {
1411         OIC_LOG(ERROR, TAG, "OCSelectMOTMethod API error");
1412         return -1;
1413     }
1414
1415     if(waitCallbackRet())  // input |g_doneCB| flag implicitly
1416     {
1417         OIC_LOG(ERROR, TAG, "waitCallbackRet callback error");
1418         return -1;
1419     }
1420
1421     return 0;
1422 }
1423
1424 static int provisionPreconfigPIN()
1425 {
1426     // check |own_list| for removing device
1427     if(!g_mot_enable_list || 1>g_mot_enable_cnt)
1428     {
1429         printf("   > Multiple Ownership Transfer Enabled Device List is Empty\n");
1430         printf("   > Please Discover the Multiple Ownership Transfer Enabled Devices, with [13] Menu\n");
1431         return 0;  // normal case
1432     }
1433
1434     // select device for removing it
1435     int dev_num = 0;
1436     for( ; ; )
1437     {
1438         printf("   > Enter Device Number, for MOT Device: ");
1439         for(int ret=0; 1!=ret; )
1440         {
1441             ret = scanf("%d", &dev_num);
1442             for( ; 0x20<=getchar(); );  // for removing overflow garbages
1443                                         // '0x20<=code' is character region
1444         }
1445         if(0<dev_num && g_mot_enable_cnt>=dev_num)
1446         {
1447             break;
1448         }
1449         printf("     Entered Wrong Number. Please Enter Again\n");
1450     }
1451
1452     char preconfigPin[9] = {0};
1453     printf("   > Input the PreconfigPin (e.g. 12341234) : ");
1454     for(int ret=0; 1!=ret; )
1455     {
1456         ret = scanf("%8s", preconfigPin);
1457         for( ; 0x20<=getchar(); );  // for removing overflow garbages
1458                                     // '0x20<=code' is character region
1459     }
1460
1461     OCProvisionDev_t* motDev = getDevInst(g_mot_enable_list, dev_num);
1462     if(OC_STACK_OK == OCProvisionPreconfigPin(NULL, motDev, preconfigPin, strlen(preconfigPin), provisionCredCB))
1463     {
1464         g_doneCB = false;
1465     }
1466     else
1467     {
1468         OIC_LOG(ERROR, TAG, "OCProvisionPreconfigPin API error");
1469         return -1;
1470     }
1471
1472     if(waitCallbackRet())  // input |g_doneCB| flag implicitly
1473     {
1474         OIC_LOG(ERROR, TAG, "waitCallbackRet callback error");
1475         return -1;
1476     }
1477
1478     return 0;
1479 }
1480
1481 static int removeSubOwner(void)
1482 {
1483     // check |g_mot_enable_list| for removing sub-owner
1484     if (!g_mot_enable_list || 1 > g_mot_enable_cnt)
1485     {
1486         printf("   > Multiple Ownership Transfer Enabled Device List is Empty\n");
1487         printf("   > Please Discover the Multiple Ownership Transfer Enabled Devices, with [13] Menu\n");
1488         return 0;  // normal case
1489     }
1490
1491     // select resource server for removing sub-owner
1492     int dev_num = 0;
1493     for ( ; ; )
1494     {
1495         printf("   > Enter Device Number to remove sub-owner: ");
1496         for (int ret = 0; 1 != ret; )
1497         {
1498             ret = scanf("%d", &dev_num);
1499             for( ; 0x20 <= getchar(); );  // for removing overflow garbages
1500                                         // '0x20<=code' is character region
1501         }
1502         if (0 < dev_num && g_mot_enable_cnt >= dev_num)
1503         {
1504             break;
1505         }
1506         printf("     Entered Wrong Number. Please Enter Again\n");
1507     }
1508
1509     OCProvisionDev_t* motDev = getDevInst(g_mot_enable_list, dev_num);
1510     if (motDev && motDev->doxm && motDev->doxm->subOwners)
1511     {
1512         OicSecSubOwner_t* subOwner = motDev->doxm->subOwners;
1513         int so_cnt = 0;
1514         while(subOwner)
1515         {
1516             printf("     [%zu] ", ++so_cnt);
1517             printUuid(&subOwner->uuid);
1518             printf("\n");
1519             subOwner = subOwner->next;
1520         }
1521
1522         int so_num = 0;
1523         for ( ; ; )
1524         {
1525             printf("   > Enter SubOwner Number to be removed : ");
1526             for (int ret = 0; 1 != ret; )
1527             {
1528                 ret = scanf("%d", &so_num);
1529                 for( ; 0x20<=getchar(); );  // for removing overflow garbages
1530                                             // '0x20<=code' is character region
1531             }
1532             if (0 < so_num && so_cnt >= so_num)
1533             {
1534                 int target_num = 0;
1535                 subOwner = motDev->doxm->subOwners;
1536                 while (subOwner)
1537                 {
1538                     if(so_num == ++target_num)
1539                     {
1540                         if (OC_STACK_OK != OCRemoveSubOwner(NULL, motDev, &subOwner->uuid, deleteDoxmForMOTCB))
1541                         {
1542                             return -1;
1543                         }
1544
1545                         g_doneCB = false;
1546
1547                         if(waitCallbackRet())  // input |g_doneCB| flag implicitly
1548                         {
1549                             OIC_LOG(ERROR, TAG, "waitCallbackRet callback error");
1550                             return -1;
1551                         }
1552                         return 0;
1553                     }
1554                     subOwner = subOwner->next;
1555                 }
1556                 break;
1557             }
1558             printf("     Entered Wrong Number. Please Enter Again\n");
1559         }
1560     }
1561     else
1562     {
1563         printf("     SubOwner list is empty.\n");
1564     }
1565
1566     return 0;
1567 }
1568
1569 static int removeAllSubOwner(void)
1570 {
1571     // check |g_mot_enable_list| for removing sub-owner
1572     if (!g_mot_enable_list || 1 > g_mot_enable_cnt)
1573     {
1574         printf("   > Multiple Ownership Transfer Enabled Device List is Empty\n");
1575         printf("   > Please Discover the Multiple Ownership Transfer Enabled Devices, with [13] Menu\n");
1576         return 0;  // normal case
1577     }
1578
1579     // select resource server for removing sub-owner
1580     int dev_num = 0;
1581     for ( ; ; )
1582     {
1583         printf("   > Enter Device Number to remove sub-owner: ");
1584         for (int ret = 0; 1 != ret; )
1585         {
1586             ret = scanf("%d", &dev_num);
1587             for( ; 0x20 <= getchar(); );  // for removing overflow garbages
1588                                         // '0x20<=code' is character region
1589         }
1590         if (0 < dev_num && g_mot_enable_cnt >= dev_num)
1591         {
1592             break;
1593         }
1594         printf("     Entered Wrong Number. Please Enter Again\n");
1595     }
1596
1597     OCProvisionDev_t* motDev = getDevInst(g_mot_enable_list, dev_num);
1598     if (motDev && motDev->doxm && motDev->doxm->subOwners)
1599     {
1600         if (OC_STACK_OK != OCRemoveAllSubOwner(NULL, motDev, deleteDoxmForMOTCB))
1601         {
1602             return -1;
1603         }
1604
1605         g_doneCB = false;
1606
1607         if(waitCallbackRet())  // input |g_doneCB| flag implicitly
1608         {
1609             OIC_LOG(ERROR, TAG, "waitCallbackRet callback error");
1610             return -1;
1611         }
1612         return 0;
1613     }
1614     else
1615     {
1616         printf("     SubOwner list is empty.\n");
1617     }
1618
1619     return 0;
1620 }
1621
1622 #endif //MULTIPLE_OWNER
1623
1624 static int resetDevice(void)
1625 {
1626     // check |own_list| for removing device
1627     if (!g_own_list || 1 > g_own_cnt)
1628     {
1629         printf("   > Owned Device List, to Reset Device, is Empty\n");
1630         printf("   > Please Register Unowned Devices first, with [20] Menu\n");
1631         return 0;
1632     }
1633
1634     OCProvisionDev_t *dev = NULL;
1635
1636     for ( ; ; )
1637     {
1638             printf("************************************************************\n");
1639             printf("Reset device candidate list:\n");
1640             g_unown_cnt = printDevList(g_own_list);
1641             if(0 == g_unown_cnt)
1642             {
1643                 break;
1644             }
1645
1646             printf("Select number device from list\nor: -1 - escape\n");
1647             int c = 0;
1648
1649             if (!scanf("%d",&c))
1650             {
1651                 continue;
1652             }
1653
1654             if(0 == c && NULL != dev)
1655             {
1656                 break;
1657             }
1658
1659             if(-1 == c)
1660             {
1661                 return 0;
1662             }
1663
1664             if(c > g_own_cnt)
1665             {
1666                 continue;
1667             }
1668
1669             dev = g_own_list;
1670             for(int lst_cnt = 1; dev && lst_cnt != c; lst_cnt++, dev = dev->next);
1671             break;
1672
1673     }
1674
1675     g_doneCB = false;
1676     printf("   Resetting Selected Owned Device..\n");
1677
1678     OCStackResult rst = SRPResetDevice(dev, resetDeviceCB);
1679
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