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