d391770e84bbcf7233e53bb7025b8ead9b82332d
[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 #ifdef MULTIPLE_OWNER
1307 static int changeMultipleOwnershipTrnasferMode(void)
1308 {
1309     // check |own_list| for removing device
1310     if(!g_own_list || 1>g_own_cnt)
1311     {
1312         printf("   > Owned Device List is Empty\n");
1313         printf("   > Please Discover the Owned Devices, with [12] Menu\n");
1314         return 0;  // normal case
1315     }
1316
1317     // select device for removing it
1318     int dev_num = 0;
1319     for( ; ; )
1320     {
1321         printf("   > Enter Device Number, for MOT Device: ");
1322         for(int ret=0; 1!=ret; )
1323         {
1324             ret = scanf("%d", &dev_num);
1325             for( ; 0x20<=getchar(); );  // for removing overflow garbages
1326                                         // '0x20<=code' is character region
1327         }
1328         if(0<dev_num && g_own_cnt>=dev_num)
1329         {
1330             break;
1331         }
1332         printf("     Entered Wrong Number. Please Enter Again\n");
1333     }
1334
1335     int mom = 0;
1336     for( ; ; )
1337     {
1338         printf("   0. Disable Multuple Ownership Transfer\n");
1339         printf("   1. Enable Multuple Ownership Transfer\n");
1340         printf("   2. (Not Supported yet) Timely Enable Multuple Ownership Transfer\n");
1341         printf("   > Enter Mode of Multuple Ownership Transfer : ");
1342         for(int ret=0; 1!=ret; )
1343         {
1344             ret = scanf("%d", &mom);
1345             for( ; 0x20<=getchar(); );  // for removing overflow garbages
1346                                         // '0x20<=code' is character region
1347         }
1348         if(0 <= dev_num && OIC_NUMBER_OF_MOM_TYPE > dev_num)
1349         {
1350             break;
1351         }
1352         printf("     Entered Wrong Number. Please Enter Again\n");
1353     }
1354
1355     OCProvisionDev_t* motDev = getDevInst(g_own_list, dev_num);
1356     if(OC_STACK_OK == OCChangeMOTMode(NULL, motDev, (OicSecMomType_t)dev_num, updateDoxmForMOTCB))
1357     {
1358         g_doneCB = false;
1359     }
1360     else
1361     {
1362         OIC_LOG(ERROR, TAG, "OCChangeMOTMode API error");
1363         return -1;
1364     }
1365
1366     if(waitCallbackRet())  // input |g_doneCB| flag implicitly
1367     {
1368         OIC_LOG(ERROR, TAG, "waitCallbackRet callback error");
1369         return -1;
1370     }
1371
1372     return 0;
1373 }
1374
1375 static int selectMultipleOwnershipTrnasferMethod(void)
1376 {
1377     // check |own_list| for removing device
1378     if(!g_mot_enable_list || 1>g_mot_enable_cnt)
1379     {
1380         printf("   > Multiple Ownership Transfer Enabled Device List is Empty\n");
1381         printf("   > Please Discover the Multiple Ownership Transfer Enabled Devices, with [13] Menu\n");
1382         return 0;  // normal case
1383     }
1384
1385     // select device for removing it
1386     int dev_num = 0;
1387     for( ; ; )
1388     {
1389         printf("   > Enter Device Number, for MOT Device: ");
1390         for(int ret=0; 1!=ret; )
1391         {
1392             ret = scanf("%d", &dev_num);
1393             for( ; 0x20<=getchar(); );  // for removing overflow garbages
1394                                         // '0x20<=code' is character region
1395         }
1396         if(0<dev_num && g_mot_enable_cnt>=dev_num)
1397         {
1398             break;
1399         }
1400         printf("     Entered Wrong Number. Please Enter Again\n");
1401     }
1402
1403     const int preconfOxm = 4;
1404     int oxm = 0;
1405     for( ; ; )
1406     {
1407         printf("   %d. (Not Supported)\n", OIC_JUST_WORKS);
1408         printf("   %d. Random PIN OxM\n", OIC_RANDOM_DEVICE_PIN);
1409         printf("   %d. (Not Supported)\n", OIC_MANUFACTURER_CERTIFICATE);
1410         printf("   %d. (Not Supported)\n", OIC_DECENTRALIZED_PUBLIC_KEY);
1411         printf("   %d. Pre-Configured PIN OxM\n", OIC_PRECONFIG_PIN);
1412         printf("   > Enter Number of  OxM for Multiple Ownership Transfer : ");
1413         for(int ret=0; 1!=ret; )
1414         {
1415             ret = scanf("%d", &oxm);
1416             for( ; 0x20<=getchar(); );  // for removing overflow garbages
1417                                         // '0x20<=code' is character region
1418         }
1419         if(OIC_PRECONFIG_PIN == oxm || OIC_RANDOM_DEVICE_PIN == oxm)
1420         {
1421             break;
1422         }
1423         printf("     Entered Wrong Number. Please Enter Again\n");
1424     }
1425
1426     OCProvisionDev_t* motDev = getDevInst(g_mot_enable_list, dev_num);
1427     if(OC_STACK_OK ==  OCSelectMOTMethod(NULL, motDev, (OicSecOxm_t)oxm, updateDoxmForMOTCB))
1428     {
1429         g_doneCB = false;
1430     }
1431     else
1432     {
1433         OIC_LOG(ERROR, TAG, "OCSelectMOTMethod API error");
1434         return -1;
1435     }
1436
1437     if(waitCallbackRet())  // input |g_doneCB| flag implicitly
1438     {
1439         OIC_LOG(ERROR, TAG, "waitCallbackRet callback error");
1440         return -1;
1441     }
1442
1443     return 0;
1444 }
1445
1446 static int provisionPreconfigPIN()
1447 {
1448     // check |own_list| for removing device
1449     if(!g_mot_enable_list || 1>g_mot_enable_cnt)
1450     {
1451         printf("   > Multiple Ownership Transfer Enabled Device List is Empty\n");
1452         printf("   > Please Discover the Multiple Ownership Transfer Enabled Devices, with [13] Menu\n");
1453         return 0;  // normal case
1454     }
1455
1456     // select device for removing it
1457     int dev_num = 0;
1458     for( ; ; )
1459     {
1460         printf("   > Enter Device Number, for MOT Device: ");
1461         for(int ret=0; 1!=ret; )
1462         {
1463             ret = scanf("%d", &dev_num);
1464             for( ; 0x20<=getchar(); );  // for removing overflow garbages
1465                                         // '0x20<=code' is character region
1466         }
1467         if(0<dev_num && g_mot_enable_cnt>=dev_num)
1468         {
1469             break;
1470         }
1471         printf("     Entered Wrong Number. Please Enter Again\n");
1472     }
1473
1474     char preconfigPin[9] = {0};
1475     printf("   > Input the PreconfigPin (e.g. 12341234) : ");
1476     for(int ret=0; 1!=ret; )
1477     {
1478         ret = scanf("%8s", preconfigPin);
1479         for( ; 0x20<=getchar(); );  // for removing overflow garbages
1480                                     // '0x20<=code' is character region
1481     }
1482
1483     OCProvisionDev_t* motDev = getDevInst(g_mot_enable_list, dev_num);
1484     if(OC_STACK_OK == OCProvisionPreconfigPin(NULL, motDev, preconfigPin, strlen(preconfigPin), provisionCredCB))
1485     {
1486         g_doneCB = false;
1487     }
1488     else
1489     {
1490         OIC_LOG(ERROR, TAG, "OCProvisionPreconfigPin API error");
1491         return -1;
1492     }
1493
1494     if(waitCallbackRet())  // input |g_doneCB| flag implicitly
1495     {
1496         OIC_LOG(ERROR, TAG, "waitCallbackRet callback error");
1497         return -1;
1498     }
1499
1500     return 0;
1501 }
1502
1503 static int removeSubOwner(void)
1504 {
1505     // check |g_mot_enable_list| for removing sub-owner
1506     if (!g_mot_enable_list || 1 > g_mot_enable_cnt)
1507     {
1508         printf("   > Multiple Ownership Transfer Enabled Device List is Empty\n");
1509         printf("   > Please Discover the Multiple Ownership Transfer Enabled Devices, with [13] Menu\n");
1510         return 0;  // normal case
1511     }
1512
1513     // select resource server for removing sub-owner
1514     int dev_num = 0;
1515     for ( ; ; )
1516     {
1517         printf("   > Enter Device Number to remove sub-owner: ");
1518         for (int ret = 0; 1 != ret; )
1519         {
1520             ret = scanf("%d", &dev_num);
1521             for( ; 0x20 <= getchar(); );  // for removing overflow garbages
1522                                         // '0x20<=code' is character region
1523         }
1524         if (0 < dev_num && g_mot_enable_cnt >= dev_num)
1525         {
1526             break;
1527         }
1528         printf("     Entered Wrong Number. Please Enter Again\n");
1529     }
1530
1531     OCProvisionDev_t* motDev = getDevInst(g_mot_enable_list, dev_num);
1532     if (motDev && motDev->doxm && motDev->doxm->subOwners)
1533     {
1534         OicSecSubOwner_t* subOwner = motDev->doxm->subOwners;
1535         int so_cnt = 0;
1536         while(subOwner)
1537         {
1538             printf("     [%zu] ", ++so_cnt);
1539             printUuid(&subOwner->uuid);
1540             printf("\n");
1541             subOwner = subOwner->next;
1542         }
1543
1544         int so_num = 0;
1545         for ( ; ; )
1546         {
1547             printf("   > Enter SubOwner Number to be removed : ");
1548             for (int ret = 0; 1 != ret; )
1549             {
1550                 ret = scanf("%d", &so_num);
1551                 for( ; 0x20<=getchar(); );  // for removing overflow garbages
1552                                             // '0x20<=code' is character region
1553             }
1554             if (0 < so_num && so_cnt >= so_num)
1555             {
1556                 int target_num = 0;
1557                 subOwner = motDev->doxm->subOwners;
1558                 while (subOwner)
1559                 {
1560                     if(so_num == ++target_num)
1561                     {
1562                         if (OC_STACK_OK != OCRemoveSubOwner(NULL, motDev, &subOwner->uuid, deleteDoxmForMOTCB))
1563                         {
1564                             return -1;
1565                         }
1566
1567                         g_doneCB = false;
1568
1569                         if(waitCallbackRet())  // input |g_doneCB| flag implicitly
1570                         {
1571                             OIC_LOG(ERROR, TAG, "waitCallbackRet callback error");
1572                             return -1;
1573                         }
1574                         return 0;
1575                     }
1576                     subOwner = subOwner->next;
1577                 }
1578                 break;
1579             }
1580             printf("     Entered Wrong Number. Please Enter Again\n");
1581         }
1582     }
1583     else
1584     {
1585         printf("     SubOwner list is empty.\n");
1586     }
1587
1588     return 0;
1589 }
1590
1591 static int removeAllSubOwner(void)
1592 {
1593     // check |g_mot_enable_list| for removing sub-owner
1594     if (!g_mot_enable_list || 1 > g_mot_enable_cnt)
1595     {
1596         printf("   > Multiple Ownership Transfer Enabled Device List is Empty\n");
1597         printf("   > Please Discover the Multiple Ownership Transfer Enabled Devices, with [13] Menu\n");
1598         return 0;  // normal case
1599     }
1600
1601     // select resource server for removing sub-owner
1602     int dev_num = 0;
1603     for ( ; ; )
1604     {
1605         printf("   > Enter Device Number to remove sub-owner: ");
1606         for (int ret = 0; 1 != ret; )
1607         {
1608             ret = scanf("%d", &dev_num);
1609             for( ; 0x20 <= getchar(); );  // for removing overflow garbages
1610                                         // '0x20<=code' is character region
1611         }
1612         if (0 < dev_num && g_mot_enable_cnt >= dev_num)
1613         {
1614             break;
1615         }
1616         printf("     Entered Wrong Number. Please Enter Again\n");
1617     }
1618
1619     OCProvisionDev_t* motDev = getDevInst(g_mot_enable_list, dev_num);
1620     if (motDev && motDev->doxm && motDev->doxm->subOwners)
1621     {
1622         if (OC_STACK_OK != OCRemoveAllSubOwner(NULL, motDev, deleteDoxmForMOTCB))
1623         {
1624             return -1;
1625         }
1626
1627         g_doneCB = false;
1628
1629         if(waitCallbackRet())  // input |g_doneCB| flag implicitly
1630         {
1631             OIC_LOG(ERROR, TAG, "waitCallbackRet callback error");
1632             return -1;
1633         }
1634         return 0;
1635     }
1636     else
1637     {
1638         printf("     SubOwner list is empty.\n");
1639     }
1640
1641     return 0;
1642 }
1643
1644 #endif //MULTIPLE_OWNER
1645
1646 static int resetDevice(void)
1647 {
1648     // check |own_list| for removing device
1649     if (!g_own_list || 1 > g_own_cnt)
1650     {
1651         printf("   > Owned Device List, to Reset Device, is Empty\n");
1652         printf("   > Please Register Unowned Devices first, with [20] Menu\n");
1653         return 0;
1654     }
1655
1656     OCProvisionDev_t *dev = NULL;
1657
1658     for ( ; ; )
1659     {
1660             printf("************************************************************\n");
1661             printf("Reset device candidate list:\n");
1662             g_unown_cnt = printDevList(g_own_list);
1663             if(0 == g_unown_cnt)
1664             {
1665                 break;
1666             }
1667
1668             printf("Select number device from list\nor: -1 - escape\n");
1669             int c = 0;
1670
1671             if (!scanf("%d",&c))
1672             {
1673                 continue;
1674             }
1675
1676             if(0 == c && NULL != dev)
1677             {
1678                 break;
1679             }
1680
1681             if(-1 == c)
1682             {
1683                 return 0;
1684             }
1685
1686             if(c > g_own_cnt)
1687             {
1688                 continue;
1689             }
1690
1691             dev = g_own_list;
1692             for(int lst_cnt = 1; dev && lst_cnt != c; lst_cnt++, dev = dev->next);
1693             break;
1694
1695     }
1696
1697     g_doneCB = false;
1698     printf("   Resetting Selected Owned Device..\n");
1699
1700     OCStackResult rst = SRPResetDevice(dev, resetDeviceCB);
1701     if (OC_STACK_OK != rst)
1702     {
1703         OIC_LOG_V(ERROR, TAG, "OCResetDevice API error: %d", rst);
1704         return -1;
1705     }
1706
1707     if (waitCallbackRet())  // input |g_doneCB| flag implicitly
1708     {
1709         OIC_LOG_V(ERROR, TAG, "%s: callback error", __func__);
1710         return -1;
1711     }
1712
1713     // display the removed result
1714     printf("   > Reset Selected Owned Device SUCCEEDED\n");
1715     printf("   > Please Discover Owned Devices for the Registered Result, with [10|12] Menu\n");
1716
1717     return 0;
1718 }
1719
1720 static int resetSVRDB(void)
1721 {
1722     printf("   Resetting SVR DB..\n");
1723     OCStackResult rst = OCResetSVRDB();
1724     if (OC_STACK_OK != rst)
1725     {
1726         OIC_LOG_V(ERROR, TAG, "OCResetSVRDB API error: %d", rst);
1727         return -1;
1728     }
1729     return 0;
1730 }
1731
1732 static OicSecAcl_t* createAcl(const int dev_num)
1733 {
1734     if(0>=dev_num || g_own_cnt<dev_num)
1735     {
1736         OIC_LOG(ERROR, TAG, "createAcl invalid parameters");
1737         return NULL;  // not need to 'goto' |ERROR| before allocating |acl|
1738     }
1739
1740     // allocate memory for |acl| struct
1741     printf("   **** Create ACL for the Selected Device[%d]\n", dev_num);
1742     OicSecAcl_t* acl = (OicSecAcl_t*) OICCalloc(1, sizeof(OicSecAcl_t));
1743     if(!acl)
1744     {
1745         OIC_LOG(ERROR, TAG, "createAcl: OICCalloc error return");
1746         return NULL;  // not need to 'goto' |ERROR| before allocating |acl|
1747     }
1748     OicSecAce_t* ace = (OicSecAce_t*) OICCalloc(1, sizeof(OicSecAce_t));
1749     if(!ace)
1750     {
1751         OIC_LOG(ERROR, TAG, "createAcl: OICCalloc error return");
1752         return NULL;  // not need to 'goto' |ERROR| before allocating |acl|
1753     }
1754     LL_APPEND(acl->aces, ace);
1755
1756     // enter |subject| device number
1757     int num = 0;
1758     for( ; ; )
1759     {
1760         printf("   > [A] Enter Subject Device Number: ");
1761         for(int ret=0; 1!=ret; )
1762         {
1763             ret = scanf("%d", &num);
1764             for( ; 0x20<=getchar(); );  // for removing overflow garbages
1765                                         // '0x20<=code' is character region
1766         }
1767         if(0<num && g_own_cnt>=num && dev_num!=num)
1768         {
1769             break;
1770         }
1771         printf("     Entered Wrong Number. Please Enter Again\n");
1772     }
1773
1774     OCProvisionDev_t* dev = getDevInst((const OCProvisionDev_t*)g_own_list, num);
1775     if(!dev || !dev->doxm)
1776     {
1777         OIC_LOG(ERROR, TAG, "createAcl: device instance empty");
1778         goto CRACL_ERROR;
1779     }
1780     memcpy(&ace->subjectuuid, &dev->doxm->deviceID, UUID_LENGTH);
1781
1782     // enter number of |resources| in 'accessed' device
1783     for( ; ; )
1784     {
1785         printf("   > [B] Enter Number of Accessed Resources (under 16): ");
1786                 // '16' is |ACL_RESRC_MAX_NUM|
1787         for(int ret=0; 1!=ret; )
1788         {
1789             ret = scanf("%d", &num);
1790             for( ; 0x20<=getchar(); );  // for removing overflow garbages
1791                                         // '0x20<=code' is character region
1792         }
1793         if(0<num && ACL_RESRC_MAX_NUM>=num)
1794         {
1795             break;
1796         }
1797         printf("     Entered Wrong Number. Please Enter under 16 Again\n");
1798                 // '16' is |ACL_RESRC_MAX_NUM|
1799     }
1800
1801     // enter actually each 'accessed' |resources| name
1802     printf("         Enter Each Accessed Resource Name (each under 128 char)\n");
1803             // '128' is ACL_RESRC_MAX_LEN
1804
1805     char rsrc_in[ACL_RESRC_MAX_LEN+1] = {0};  // '1' for null termination
1806     for(int i = 0; num > i; ++i)
1807     {
1808         OicSecRsrc_t* rsrc = (OicSecRsrc_t*)OICCalloc(1, sizeof(OicSecRsrc_t));
1809         if(!rsrc)
1810         {
1811             OIC_LOG(ERROR, TAG, "createAcl: OICCalloc error return");
1812             goto CRACL_ERROR;
1813         }
1814
1815         printf("         Enter Accessed Resource[%d] Name: (e.g. /a/led)", i+1);
1816         for(int ret=0; 1!=ret; )
1817         {
1818             ret = scanf("%128s", rsrc_in);  // '128' is ACL_RESRC_MAX_LEN
1819             for( ; 0x20<=getchar(); );  // for removing overflow garbages
1820                                         // '0x20<=code' is character region
1821         }
1822         size_t len = strlen(rsrc_in)+1;  // '1' for null termination
1823         rsrc->href = (char*) OICCalloc(len, sizeof(char));
1824         if(!rsrc->href)
1825         {
1826             OIC_LOG(ERROR, TAG, "createAcl: OICCalloc error return");
1827             goto CRACL_ERROR;
1828         }
1829         OICStrcpy(rsrc->href, len, rsrc_in);
1830
1831         size_t arrLen = 0;
1832         while(1)
1833         {
1834             printf("         Enter Number of resource type for [%s] : ", rsrc->href);
1835             for(int ret=0; 1!=ret; )
1836             {
1837                 ret = scanf("%zu", &arrLen);
1838                 for( ; 0x20<=getchar(); );  // for removing overflow garbages
1839                                             // '0x20<=code' is character region
1840             }
1841             if(ACL_RESRC_ARRAY_SIZE >= arrLen)
1842             {
1843                 break;
1844             }
1845             printf("     Entered Wrong Number. Please Enter under %d Again\n", ACL_RESRC_ARRAY_SIZE);
1846         }
1847
1848         rsrc->typeLen = arrLen;
1849         rsrc->types = (char**)OICCalloc(arrLen, sizeof(char*));
1850         if(!rsrc->types)
1851         {
1852             OIC_LOG(ERROR, TAG, "createAcl: OICCalloc error return");
1853             goto CRACL_ERROR;
1854         }
1855
1856         for(size_t i = 0; i < arrLen; i++)
1857         {
1858             printf("         Enter ResourceType[%zu] Name (e.g. core.led): ", i+1);
1859             for(int ret=0; 1!=ret; )
1860             {
1861                 ret = scanf("%128s", rsrc_in);  // '128' is ACL_RESRC_MAX_LEN
1862                 for( ; 0x20<=getchar(); );  // for removing overflow garbages
1863                                             // '0x20<=code' is character region
1864             }
1865             rsrc->types[i] = OICStrdup(rsrc_in);
1866             if(!rsrc->types[i])
1867             {
1868                 OIC_LOG(ERROR, TAG, "createAcl: OICStrdup error return");
1869                 goto CRACL_ERROR;
1870             }
1871         }
1872
1873         while(1)
1874         {
1875             printf("         Enter Number of interface for [%s]: ", rsrc->href);
1876             for(int ret=0; 1!=ret; )
1877             {
1878                 ret = scanf("%zu", &arrLen);
1879                 for( ; 0x20<=getchar(); );  // for removing overflow garbages
1880                                             // '0x20<=code' is character region
1881             }
1882             if(ACL_RESRC_ARRAY_SIZE >= arrLen)
1883             {
1884                 break;
1885             }
1886             printf("     Entered Wrong Number. Please Enter under %d Again\n", ACL_RESRC_ARRAY_SIZE);
1887         }
1888
1889         rsrc->interfaceLen = arrLen;
1890         rsrc->interfaces = (char**)OICCalloc(arrLen, sizeof(char*));
1891         if(!rsrc->interfaces)
1892         {
1893             OIC_LOG(ERROR, TAG, "createAcl: OICCalloc error return");
1894             goto CRACL_ERROR;
1895         }
1896
1897         for(size_t i = 0; i < arrLen; i++)
1898         {
1899             printf("         Enter Interface[%zu] Name (e.g. oic.if.baseline): ", i+1);
1900             for(int ret=0; 1!=ret; )
1901             {
1902                 ret = scanf("%128s", rsrc_in);  // '128' is ACL_RESRC_MAX_LEN
1903                 for( ; 0x20<=getchar(); );  // for removing overflow garbages
1904                                             // '0x20<=code' is character region
1905             }
1906             rsrc->interfaces[i] = OICStrdup(rsrc_in);
1907             if(!rsrc->interfaces[i])
1908             {
1909                 OIC_LOG(ERROR, TAG, "createAcl: OICStrdup error return");
1910                 goto CRACL_ERROR;
1911             }
1912         }
1913
1914         LL_APPEND(ace->resources, rsrc);
1915     }
1916
1917     // enter |permission| for this access
1918     printf("   > [C] Enter Permission for This Access\n");
1919     uint16_t pmsn = PERMISSION_FULL_CONTROL;  // default full permission
1920     uint16_t pmsn_msk = PERMISSION_CREATE;  // default permission mask
1921     for(int i=0; ACL_PEMISN_CNT>i; ++i)
1922     {
1923         char ans = 0;
1924         for( ; ; )
1925         {
1926             printf("         Enter %s Permission (y/n): ", ACL_PEMISN[i]);
1927             for(int ret=0; 1!=ret; )
1928             {
1929                 ret = scanf("%c", &ans);
1930                 for( ; 0x20<=getchar(); );  // for removing overflow garbages
1931                                             // '0x20<=code' is character region
1932             }
1933             if('y'==ans || 'Y'==ans || 'n'==ans|| 'N'==ans)
1934             {
1935                 ans &= ~0x20;  // for masking lower case, 'y/n'
1936                 break;
1937             }
1938             printf("         Entered Wrong Answer. Please Enter 'y/n' Again\n");
1939         }
1940         if('N' == ans)  // masked lower case, 'n'
1941         {
1942             pmsn -= pmsn_msk;
1943         }
1944         pmsn_msk <<= 1;
1945     }
1946     ace->permission = pmsn;
1947
1948     return acl;
1949
1950 CRACL_ERROR:
1951     OCDeleteACLList(acl);  // after here |acl| points nothing
1952     return NULL;
1953 }
1954
1955 static OicSecAcl_t* createSimpleAcl(const OicUuid_t uuid)
1956 {
1957     OIC_LOG(DEBUG, TAG, "createSimpleAcl IN");
1958
1959     // allocate memory for |acl| struct
1960     OicSecAcl_t* acl = (OicSecAcl_t*) OICCalloc(1, sizeof(OicSecAcl_t));
1961     if(!acl)
1962     {
1963         OIC_LOG(DEBUG, TAG, "OICCalloc error return");
1964         return NULL;  // not need to 'goto' |ERROR| before allocating |acl|
1965     }
1966     OicSecAce_t* ace = (OicSecAce_t*) OICCalloc(1, sizeof(OicSecAce_t));
1967     if(!ace)
1968     {
1969         OIC_LOG(DEBUG, TAG,  "OICCalloc error return");
1970         return NULL;  // not need to 'goto' |ERROR| before allocating |acl|
1971     }
1972     LL_APPEND(acl->aces, ace);
1973
1974     memcpy(&ace->subjectuuid, &uuid, UUID_LENGTH);
1975
1976     OicSecRsrc_t* rsrc = (OicSecRsrc_t*)OICCalloc(1, sizeof(OicSecRsrc_t));
1977     if(!rsrc)
1978     {
1979         OIC_LOG(DEBUG, TAG, "OICCalloc error return");
1980         OCDeleteACLList(acl);
1981         return NULL;
1982     }
1983
1984     char href[] = "*";
1985     size_t len = strlen(href)+1;  // '1' for null termination
1986     rsrc->href = (char*) OICCalloc(len, sizeof(char));
1987     if(!rsrc->href)
1988     {
1989         OIC_LOG(DEBUG, TAG,  "OICCalloc error return");
1990         OCDeleteACLList(acl);
1991         return NULL;
1992     }
1993     OICStrcpy(rsrc->href, len, href);
1994
1995     size_t arrLen = 1;
1996     rsrc->typeLen = arrLen;
1997     rsrc->types = (char**)OICCalloc(arrLen, sizeof(char*));
1998     if(!rsrc->types)
1999     {
2000         OIC_LOG(DEBUG, TAG,  "OICCalloc error return");
2001         OCDeleteACLList(acl);
2002         return NULL;
2003     }
2004     rsrc->types[0] = OICStrdup("");   // ignore
2005
2006     rsrc->interfaceLen = 1;
2007     rsrc->interfaces = (char**)OICCalloc(arrLen, sizeof(char*));
2008     if(!rsrc->interfaces)
2009     {
2010         OIC_LOG(DEBUG, TAG,  "OICCalloc error return");
2011         OCDeleteACLList(acl);
2012         return NULL;
2013     }
2014     rsrc->interfaces[0] = OICStrdup("oic.if.baseline");  // ignore
2015
2016     LL_APPEND(ace->resources, rsrc);
2017
2018     ace->permission = 31;   // R/W/U/D
2019
2020     OIC_LOG(DEBUG, TAG, "createSimpleAcl OUT");
2021
2022     return acl;
2023 }
2024
2025 static OicSecPdAcl_t* createPdAcl(const int dev_num)
2026 {
2027     if(0>=dev_num || g_own_cnt<dev_num)
2028     {
2029         OIC_LOG(ERROR, TAG, "createAcl invalid parameters");
2030         return NULL;  // not need to 'goto' |ERROR| before allocating |acl|
2031     }
2032
2033     // allocate memory for |pdacl| struct
2034     printf("   **** Create PDACL for the Selected Device[%d]\n", dev_num);
2035     OicSecPdAcl_t* pdAcl = (OicSecPdAcl_t*) OICCalloc(1, sizeof(OicSecPdAcl_t));
2036     if(!pdAcl)
2037     {
2038         OIC_LOG(ERROR, TAG, "createAcl: OICCalloc error return");
2039         return NULL;  // not need to 'goto' |ERROR| before allocating |acl|
2040     }
2041
2042
2043     // number of resources
2044     char rsrc_in[][ACL_RESRC_MAX_LEN+1] = {"*", "/rsrc/*"};
2045     pdAcl->resourcesLen = 1;
2046
2047     // resource
2048     int num = pdAcl->resourcesLen;
2049     pdAcl->resources = (char**) OICCalloc(num, sizeof(char*));
2050     if(!pdAcl->resources)
2051     {
2052         OIC_LOG(ERROR, TAG, "createPdAcl: OICCalloc error return");
2053         goto CRPDACL_ERROR;
2054     }
2055     for(int i=0; num>i; ++i)
2056     {
2057         size_t len = strlen(rsrc_in[i])+1;  // '1' for null termination
2058         char* rsrc = (char*) OICCalloc(len, sizeof(char));
2059         if(!rsrc)
2060         {
2061             OIC_LOG(ERROR, TAG, "createPdAcl: OICCalloc error return");
2062             goto CRPDACL_ERROR;
2063         }
2064         OICStrcpy(rsrc, len, rsrc_in[i]);
2065         pdAcl->resources[i] = rsrc;  // after here, |rsrc| points nothing
2066     }
2067
2068     // permission
2069     pdAcl->permission = PERMISSION_FULL_CONTROL;
2070
2071     return pdAcl;
2072
2073 CRPDACL_ERROR:
2074     OCDeletePdAclList(pdAcl);
2075     return NULL;
2076 }
2077
2078 static OCProvisionDev_t* getDevInst(const OCProvisionDev_t* dev_lst, const int dev_num)
2079 {
2080     if(!dev_lst || 0>=dev_num)
2081     {
2082         printf("     Device List is Empty..\n");
2083         return NULL;
2084     }
2085
2086     OCProvisionDev_t* lst = (OCProvisionDev_t*) dev_lst;
2087     for(int i=0; lst; )
2088     {
2089         if(dev_num == ++i)
2090         {
2091             return lst;
2092         }
2093         lst = lst->next;
2094     }
2095
2096     return NULL;  // in here |lst| is always |NULL|
2097 }
2098
2099 static int printDevList(const OCProvisionDev_t* dev_lst)
2100 {
2101     if(!dev_lst)
2102     {
2103         printf("     Device List is Empty..\n\n");
2104         return 0;
2105     }
2106
2107     OCProvisionDev_t* lst = (OCProvisionDev_t*) dev_lst;
2108     int lst_cnt = 0;
2109     for( ; lst; )
2110     {
2111         printf("     [%d] ", ++lst_cnt);
2112         printUuid((const OicUuid_t*) &lst->doxm->deviceID);
2113         printf("\n");
2114         lst = lst->next;
2115     }
2116     printf("\n");
2117
2118     return lst_cnt;
2119 }
2120
2121 static size_t printUuidList(const OCUuidList_t* uid_lst)
2122 {
2123     if(!uid_lst)
2124     {
2125         printf("     Device List is Empty..\n\n");
2126         return 0;
2127     }
2128
2129     OCUuidList_t* lst = (OCUuidList_t*) uid_lst;
2130     size_t lst_cnt = 0;
2131     for( ; lst; )
2132     {
2133         printf("     [%zu] ", ++lst_cnt);
2134         printUuid((const OicUuid_t*) &lst->dev);
2135         printf("\n");
2136         lst = lst->next;
2137     }
2138     printf("\n");
2139
2140     return lst_cnt;
2141 }
2142
2143 static int printResultList(const OCProvisionResult_t* rslt_lst, const int rslt_cnt)
2144 {
2145     if(!rslt_lst || 0>=rslt_cnt)
2146     {
2147         printf("     Device List is Empty..\n\n");
2148         return 0;
2149     }
2150
2151     int lst_cnt = 0;
2152     for( ; rslt_cnt>lst_cnt; ++lst_cnt)
2153     {
2154         printf("     [%d] ", lst_cnt+1);
2155         printUuid((const OicUuid_t*) &rslt_lst[lst_cnt].deviceId);
2156         printf(" - result: %d\n", rslt_lst[lst_cnt].res);
2157     }
2158     printf("\n");
2159
2160     return lst_cnt;
2161 }
2162
2163 static void printUuid(const OicUuid_t* uid)
2164 {
2165     for(int i=0; i<UUID_LENGTH; )
2166     {
2167         printf("%02X", (*uid).id[i++]);
2168         if(i==4 || i==6 || i==8 || i==10)  // canonical format for UUID has '8-4-4-4-12'
2169         {
2170             printf("-");
2171         }
2172     }
2173 }
2174
2175 static FILE* fopen_prvnMng(const char* path, const char* mode)
2176 {
2177     (void)path;  // unused |path| parameter
2178
2179     // input |g_svr_db_fname| internally by force, not using |path| parameter
2180     // because |OCPersistentStorage::open| is called |OCPersistentStorage| internally
2181     // with its own |SVR_DB_FILE_NAME|
2182     return fopen(SVR_DB_FILE_NAME, mode);
2183 }
2184
2185 static int peerCertCallback(void *ctx, const mbedtls_x509_crt *cert, int depth)
2186 {
2187     (void)ctx;
2188
2189     OIC_LOG_V(DEBUG, TAG, "Depth : %d", depth);
2190     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
2191     OIC_LOG(DEBUG, TAG, "***** Serial number of certificate is below *****");
2192     OIC_LOG_BUFFER(DEBUG, TAG, cert->serial.p, cert->serial.len);
2193     OIC_LOG(DEBUG, TAG, "***** Serial number of certificate is above *****");
2194     OIC_LOG_V(DEBUG, TAG, "OUT%s", __func__);
2195
2196     return 0;
2197 }
2198
2199 static int waitCallbackRet(void)
2200 {
2201     for(int i=0; !g_doneCB && CALLBACK_TIMEOUT>i; ++i)
2202     {
2203         sleep(1);
2204         if(OC_STACK_OK != OCProcess())
2205         {
2206             OIC_LOG(ERROR, TAG, "OCStack process error");
2207             return -1;
2208         }
2209     }
2210
2211     if(!g_doneCB)
2212     {
2213         OCPDMCleanupForTimeout();
2214     }
2215
2216     return 0;
2217 }
2218
2219 static int selectTwoDiffNum(int* a, int* b, const int max, const char* str)
2220 {
2221     if(!a || !b || 2>max || !str)
2222     {
2223         return -1;
2224     }
2225
2226     for( ; ; )
2227     {
2228         for(int i=0; 2>i; ++i)
2229         {
2230             int* num = 0==i?a:b;
2231             for( ; ; )
2232             {
2233                 printf("   > Enter Device[%d] Number, %s: ", i+1, str);
2234                 for(int ret=0; 1!=ret; )
2235                 {
2236                     ret = scanf("%d", num);
2237                     for( ; 0x20<=getchar(); );  // for removing overflow garbages
2238                                                 // '0x20<=code' is character region
2239                 }
2240                 if(0<*num && max>=*num)
2241                 {
2242                     break;
2243                 }
2244                 printf("     Entered Wrong Number. Please Enter Again\n");
2245             }
2246         }
2247         if(*a != *b)
2248         {
2249             printf("\n");
2250             return 0;
2251         }
2252     }
2253
2254     return -1;
2255 }
2256
2257 #ifdef __WITH_TLS__
2258
2259 static void setDevProtocol(OCProvisionDev_t* lst)
2260 {
2261     if(!lst)
2262     {
2263         printf("     Device List is Empty..\n\n");
2264         return;
2265     }
2266
2267     for( ; lst; )
2268     {
2269         if(2 == secure_protocol)
2270         {
2271             lst->connType &= ~CT_ADAPTER_IP; //reset IP flag
2272             lst->connType |= CT_ADAPTER_TCP; //set TCP flag
2273             lst->endpoint.adapter = OC_ADAPTER_TCP;
2274             lst->endpoint.port = lst->tcpPort;
2275             lst->securePort = lst->tcpPort;
2276         }
2277         lst = lst->next;
2278     }
2279 }
2280
2281 static void selectSecureProtocol()
2282 {
2283     printf("   Select protocol\n");
2284     printf("   1 - DTLS(Default)\n");
2285     printf("   2 - TLS\n");
2286
2287     for(int ret=0; 1!=ret; )
2288     {
2289         ret = scanf("%d",&secure_protocol);
2290         for( ; 0x20<=getchar(); );  // for removing overflow garbages
2291         // '0x20<=code' is character region
2292     }
2293
2294     if(0 >= secure_protocol || 2 < secure_protocol)
2295     {
2296         secure_protocol = 1;
2297     }
2298
2299     setDevProtocol(g_own_list);
2300     setDevProtocol(g_unown_list);
2301 }
2302 #endif
2303
2304 static void secureStorageHwEmulation()
2305 {
2306     printf("   Enable Secure Storage HW Emulation\n");
2307
2308     printf("         Enter Own Certificate File Path[~4095]: ");
2309     char cert_filepath[4096] = {0,};
2310     for(int ret=0; 1!=ret; )
2311     {
2312         ret = scanf("%255s", cert_filepath);
2313         for( ; 0x20<=getchar(); );  // for removing overflow garbages
2314                                     // '0x20<=code' is character region
2315     }
2316
2317     printf("         Enter Private Key File Path[~4095]: ");
2318     char key_filepath[4096] = {0,};
2319     for(int ret=0; 1!=ret; )
2320     {
2321         ret = scanf("%255s", key_filepath);
2322         for( ; 0x20<=getchar(); );  // for removing overflow garbages
2323                                     // '0x20<=code' is character region
2324     }
2325
2326     printf("         Enter Password for Key Password[~31][Press (Enter) to not set]: ");
2327     char pwd[32] = {0,};
2328     for(int i=0; i < 31; i++)
2329     {
2330         pwd[i] = (char)getchar();
2331         if (0x20 <= pwd[i])
2332         {
2333             pwd[i--] = '\0';
2334             continue;
2335         }
2336         if (0x0A == pwd[i])
2337         {
2338             pwd[i] = '\0';
2339             break;
2340         }
2341     }
2342
2343     if (0 != SSemulSetCertkeyFilepath(cert_filepath, key_filepath, pwd))
2344     {
2345         printf("    Fail to set cert/key file path");
2346         return;
2347     }
2348
2349     if (0 != SetHwPkixCallbacks(HWGetKeyContext,
2350                                                   HWFreeKeyContext,
2351                                                   HWGetOwnCertificateChain,
2352                                                   HWSetupPkContext))
2353     {
2354         printf("    Fail to regist HW Pkix Callbacks");
2355         return;
2356     }
2357     printf("    Success to regist HW Pkix Callbacks");
2358 }
2359
2360 static void selectVerifMethod()
2361 {
2362     int option;
2363     printf("   Select verification method for ownership transfer\n");
2364     printf("   0 - No verification\n");
2365     printf("   1 - Display only\n");
2366     printf("   2 - Confirm only\n");
2367     printf("   3 - Both Display and Confirm\n");
2368
2369     for(int ret=0; 1!=ret; )
2370     {
2371         ret = scanf("%d",&option);
2372         for( ; 0x20<=getchar(); );  // for removing overflow garbages
2373         // '0x20<=code' is character region
2374     }
2375
2376     if(0 > option || 3 < option)
2377     {
2378         printf("Invalid option!");
2379     }
2380     SetVerifyOption((VerifyOptionBitmask_t) option);
2381     printf("Option %d chosen!", option);
2382 }
2383
2384 static void printMenu(void)
2385 {
2386     printf("************************************************************\n");
2387     printf("****** OIC Provisioning Client with using C-level API ******\n");
2388     printf("************************************************************\n\n");
2389
2390     printf("** [A] DISCOVER DEVICES ON NETWORK\n");
2391     printf("** 10. Discover All Un/Owned Devices on Network\n");
2392     printf("** 11. Discover Only Unowned Devices on Network\n");
2393 #ifdef MULTIPLE_OWNER
2394     printf("** 12. Discover Only Owned Devices on Network\n");
2395     printf("** 13. Discover Multiple Ownership Transfer Enabled Devices on Network\n\n");
2396 #else
2397     printf("** 12. Discover Only Owned Devices on Network\n\n");
2398 #endif //MULTIPLE_OWNER
2399
2400     printf("** [B] REGISTER/OWN ALL DISCOVERED UNOWNED DEVICES\n");
2401     printf("** 20. Register/Own All Discovered Unowned Devices\n\n");
2402
2403     printf("** [C] PROVISION/LINK PAIRWISE THINGS\n");
2404     printf("** 30. Provision/Link Pairwise Things\n");
2405     printf("** 31. Provision Credentials for Pairwise Things\n");
2406     printf("** 32. Provision the Selected Access Control List(ACL)\n");
2407     printf("** 33. Provision Direct-Pairing Configuration\n");
2408     printf("** 34. Check Linked Status of the Selected Device on PRVN DB\n");
2409     printf("** 35. Save the Selected Access Control List(ACL) into local SVR DB\n\n");
2410
2411     printf("** [D] UNLINK PAIRWISE THINGS\n");
2412     printf("** 40. Unlink Pairwise Things\n\n");
2413
2414     printf("** [E] REMOVE THE SELECTED DEVICE\n");
2415     printf("** 50. Remove the Selected Device\n");
2416     printf("** 51. Remove Device with UUID (UUID input is required)\n");
2417     printf("** 52. Reset the Selected Device\n");
2418     printf("** 53. Reset SVR DB\n\n");
2419
2420     printf("** [F] GET SECURITY RESOURCE FOR DEBUGGING ONLY\n");
2421     printf("** 60. Get the Credential resources of the Selected Device\n");
2422     printf("** 61. Get the ACL resources of the Selected Device\n\n");
2423
2424 #ifdef MULTIPLE_OWNER
2425     printf("** [G] UPDATE THE MULTIPLE OWNERSHIP TRANSFER RELATED VALUE\n");
2426     printf("** 70. Change the Multiple Ownership transfer MODE(update mom)\n");
2427     printf("** 71. Provision Preconfigured PIN\n");
2428     printf("** 72. Change the Multiple Ownership transfer METHOD(update oxmsel)\n");
2429     printf("** 73. Remove Sub-Owner from Resource Server\n");
2430     printf("** 74. Remove All Sub-Owner from Resource Server\n\n");
2431 #endif //MULTIPLE_OWNER
2432
2433 #ifdef __WITH_TLS__
2434     printf("** [H] SELECT SECURE PROTOCOL DTLS/TLS AND OTHERS\n");
2435     printf("** 80. Select secure protocol(default DTLS)\n");
2436     printf("** 81. Select verification method\n");
2437     printf("** 82. Enable secure storage hw emulation\n\n");
2438 #else
2439     printf("** [H] SELECT VERIFICATION OPTION\n");
2440     printf("** 81. Select verification method\n\n");
2441 #endif
2442     printf("** [I] EXIT PROVISIONING CLIENT\n");
2443
2444     printf("** 99. Exit Provisionong Client\n\n");
2445
2446     printf("************************************************************\n\n");
2447 }
2448
2449 #if 0 // Code for enabling path configuration for PDB and SVR DBf
2450 static void printUsage(void)
2451 {
2452     printf("\n");
2453     printf("OIC Provisioning Client with using C-level API\n");
2454     printf("Usage: provisioningclient [option]...\n");
2455     printf("\n");
2456     printf("  -h                           print help for this provisioning client\n");
2457     printf("  -p=[prvn_db_file_path/name]  input PRVN DB file path and name\n");
2458     printf("                               if not exists, will load default DB file\n");
2459     printf("                               (default: |oic_prvn_mng.db| on working dir)\n");
2460     printf("                               (ex. -p=oic_prvn_mng.db)\n");
2461     printf("  -s=[svr_db_file_path/name]   input SVR DB file path and name\n");
2462     printf("                               if not exists, will load default DB file\n");
2463     printf("                               (default: |oic_svr_db_client.json| on working dir)\n");
2464     printf("                               (ex. -s=oic_svr_db_client.json)\n");
2465     printf("\n");
2466 }
2467 #endif
2468
2469 /**
2470  * Sample implementation of Export key block and master secret
2471  *
2472  * @param[in] p_expkey  Context for the callback
2473  * @aram[in] ms        Pointer to master secret (fixed length: 48 bytes)
2474  * @param[in] kb        Pointer to key block, see RFC 5246 section 6.3
2475  *                  (variable length: 2 * maclen + 2 * keylen + 2 * ivlen).
2476  * @param[in] maclen    MAC length
2477  * @param[in] keylen    Key length
2478  * @param[in] ivlen     IV length
2479  */
2480 static void SslExportKeysCallback(const unsigned char* masterSecret,
2481                                   const unsigned char* keyBlock,
2482                                   size_t macLen, size_t keyLen, size_t ivLen)
2483 {
2484     OIC_LOG_V(INFO, TAG, "In %s ", __func__);
2485
2486     OIC_LOG(INFO, TAG, "[MASTER SECRET] : ");
2487     OIC_LOG_BUFFER(INFO, TAG, masterSecret, 48);
2488
2489     OIC_LOG(INFO, TAG, "[KEY BLOCK] : ");
2490     OIC_LOG_BUFFER(INFO, TAG, keyBlock, (2 * macLen) + (2 * keyLen) + (2 * ivLen));
2491
2492     OIC_LOG_V(INFO, TAG, "Mac Length = %zu, Key Length = %zu, IV Length = %zu",
2493             macLen, keyLen, ivLen);
2494
2495     OIC_LOG_V(INFO, TAG, "Out %s ", __func__);
2496 }
2497
2498 // main function for provisioning client using C-level provisioning API
2499 int main()
2500 {
2501     // initialize provisioning client
2502     if(initProvisionClient())
2503     {
2504         OIC_LOG(ERROR, TAG, "ProvisionClient init error");
2505         goto PMCLT_ERROR;
2506     }
2507
2508     if (CA_STATUS_OK !=
2509         CASetSslExportKeysCallback(SslExportKeysCallback, CA_SSL_EKCB_DTLS, CA_SSL_EKCB_CLIENT))
2510     {
2511         OIC_LOG(ERROR, TAG, "Failed to register the (D)TLS export Key Callback!");
2512         goto PMCLT_ERROR;
2513     }
2514
2515     // Client can choose a allowed/not-allowed OxM method.
2516     if(OC_STACK_OK != OCSetOxmAllowStatus(OIC_DECENTRALIZED_PUBLIC_KEY, false))
2517     {
2518         OIC_LOG(WARNING, TAG, "Failed to disable OIC_DECENTRALIZED_PUBLIC_KEY OxM");
2519     }
2520
2521     // set callbacks for verification options
2522     SetDisplayNumCB(NULL, displayNumCB);
2523     SetUserConfirmCB(NULL, confirmNumCB);
2524     SetInputStateCB(NULL, notifyInputStateCB);
2525
2526     // set callback for checking peer certificate information
2527     OCSetPeerCertCallback(NULL, peerCertCallback);
2528
2529 #ifdef MULTIPLE_OWNER
2530     SetPreconfigPin("12341234", 8);
2531 #endif //MULTIPLE_OWNER
2532
2533     // main loop for provisioning manager
2534     int mn_num = 0;
2535     for( ; ; )
2536     {
2537         printf("\n");
2538         printMenu();
2539         printf(">> Enter Menu Number: ");
2540         for(int ret=0; 1!=ret; )
2541         {
2542             ret = scanf("%d", &mn_num);
2543             for( ; 0x20<=getchar(); );  // for removing overflow garbages
2544                                         // '0x20<=code' is character region
2545         }
2546         printf("\n");
2547         switch(mn_num)
2548         {
2549         case _10_DISCOV_ALL_DEVS_:
2550             if(discoverAllDevices())
2551             {
2552                 OIC_LOG(ERROR, TAG, "_10_DISCOV_ALL_DEVS_: error");
2553             }
2554             break;
2555         case _11_DISCOV_UNOWN_DEVS_:
2556             if(discoverUnownedDevices())
2557             {
2558                 OIC_LOG(ERROR, TAG, "_11_DISCOV_UNOWN_DEVS_: error");
2559             }
2560             break;
2561         case _12_DISCOV_OWN_DEVS_:
2562             if(discoverOwnedDevices())
2563             {
2564                 OIC_LOG(ERROR, TAG, "_12_DISCOV_OWN_DEVS_: error");
2565             }
2566             break;
2567 #ifdef MULTIPLE_OWNER
2568         case _13_MOT_DISCOV_DEV_:
2569             if(discoverMOTEnabledDevices())
2570             {
2571                 OIC_LOG(ERROR, TAG, "_13_MOT_DISCOV_DEV_: error");
2572             }
2573             break;
2574 #endif //MULTIPLE_OWNER
2575         case _20_REGIST_DEVS_:
2576             if(registerDevices())
2577             {
2578                 OIC_LOG(ERROR, TAG, "_20_REGIST_DEVS_: error");
2579             }
2580             break;
2581         case _30_PROVIS_PAIR_DEVS_:
2582             if(provisionPairwise())
2583             {
2584                 OIC_LOG(ERROR, TAG, "_30_PROVIS_PAIR_DEVS_: error");
2585             }
2586             break;
2587         case _31_PROVIS_CRED_:
2588             if(provisionCred())
2589             {
2590                 OIC_LOG(ERROR, TAG, "_31_PROVIS_CRED_: error");
2591             }
2592             break;
2593         case _32_PROVIS_ACL_:
2594             if(provisionAcl())
2595             {
2596                 OIC_LOG(ERROR, TAG, "_32_PROVIS_ACL_: error");
2597             }
2598             break;
2599         case _33_PROVIS_DP_:
2600             if(provisionDirectPairing())
2601             {
2602                 OIC_LOG(ERROR, TAG, "_33_PROVIS_DP_: error");
2603             }
2604             break;
2605         case _34_CHECK_LINK_STATUS_:
2606             if(checkLinkedStatus())
2607             {
2608                 OIC_LOG(ERROR, TAG, "_34_CHECK_LINK_STATUS_: error");
2609             }
2610             break;
2611         case _35_SAVE_ACL_:
2612             if(saveAcl())
2613             {
2614                 OIC_LOG(ERROR, TAG, "_35_SAVE_ACL_: error");
2615             }
2616             break;
2617         case _40_UNLINK_PAIR_DEVS_:
2618             if(unlinkPairwise())
2619             {
2620                 OIC_LOG(ERROR, TAG, "_40_UNLINK_PAIR_DEVS_: error");
2621             }
2622             break;
2623         case _50_REMOVE_SELEC_DEV_:
2624             if(removeDevice())
2625             {
2626                 OIC_LOG(ERROR, TAG, "_50_REMOVE_SELEC_DEV_: error");
2627             }
2628             break;
2629         case _51_REMOVE_DEV_WITH_UUID_:
2630             if(removeDeviceWithUuid())
2631             {
2632                 OIC_LOG(ERROR, TAG, "_51_REMOVE_DEV_WITH_UUID_: error");
2633             }
2634             break;
2635         case _52_RESET_SELEC_DEV_:
2636             if(resetDevice())
2637             {
2638                 OIC_LOG(ERROR, TAG, "_52_RESET_SELEC_DEV_: error");
2639             }
2640             break;
2641         case _53_RESET_SVR_DB_:
2642             if(resetSVRDB())
2643             {
2644                 OIC_LOG(ERROR, TAG, "_53_RESET_SVR_DB_: error");
2645             }
2646             break;
2647         case _60_GET_CRED_:
2648             if(getCred())
2649             {
2650                 OIC_LOG(ERROR, TAG, "_60_GET_CRED_: error");
2651             }
2652             break;
2653         case _61_GET_ACL_:
2654             if(getAcl())
2655             {
2656                 OIC_LOG(ERROR, TAG, "_61_GET_ACL_: error");
2657             }
2658             break;
2659 #ifdef MULTIPLE_OWNER
2660         case _70_MOT_CHANGE_MOM_:
2661             if(changeMultipleOwnershipTrnasferMode())
2662             {
2663                 OIC_LOG(ERROR, TAG, "_70_MOT_CHANGE_MOM_: error");
2664             }
2665             break;
2666         case _71_MOT_PROV_PRECONF_PIN_:
2667             if(provisionPreconfigPIN())
2668             {
2669                 OIC_LOG(ERROR, TAG, "_71_MOT_PROV_PRECONF_PIN_: error");
2670             }
2671             break;
2672         case _72_MOT_OXM_SEL_:
2673             if(selectMultipleOwnershipTrnasferMethod())
2674             {
2675                 OIC_LOG(ERROR, TAG, "_72_MOT_OXM_SEL_: error");
2676             }
2677             break;
2678         case _73_MOT_REMOVE_SUBOWNER_:
2679             if(removeSubOwner())
2680             {
2681                 OIC_LOG(ERROR, TAG, "_73_MOT_REMOVE_SUBOWNER_ : error");
2682             }
2683             break;
2684         case _74_MOT_REMOVE_ALL_SUBOWNER_:
2685             if(removeAllSubOwner())
2686             {
2687                 OIC_LOG(ERROR, TAG, "_74_MOT_REMOVE_ALL_SUBOWNER_ : error");
2688             }
2689             break;
2690 #endif //MULTIPLE_OWNER
2691 #ifdef __WITH_TLS__
2692         case  _80_SELECT_PROTOCOL_:
2693             selectSecureProtocol();
2694             break;
2695 #endif
2696         case _81_SELECT_VERIF_METHOD_:
2697             selectVerifMethod();
2698             break;
2699         case _82_SECURE_STORAGE_HW_EMULATION_:
2700             secureStorageHwEmulation();
2701             break;
2702         case _99_EXIT_PRVN_CLT_:
2703             goto PMCLT_ERROR;
2704         default:
2705             printf(">> Entered Wrong Number. Please Enter Again\n\n");
2706             break;
2707         }
2708     }
2709
2710 PMCLT_ERROR:
2711     if(OC_STACK_OK != OCStop())
2712     {
2713         OIC_LOG(ERROR, TAG, "OCStack stop error");
2714     }
2715     OCDeleteDiscoveredDevices(g_own_list);  // after here |g_own_list| points nothing
2716     OCDeleteDiscoveredDevices(g_unown_list);  // after here |g_unown_list| points nothing
2717 #ifdef MULTIPLE_OWNER
2718     OCDeleteDiscoveredDevices(g_mot_enable_list);  // after here |g_motdev_list| points nothing
2719 #endif //MULTIPLE_OWNER
2720
2721     if(g_svr_fname)
2722     {
2723         OICFree(g_svr_fname);  // after here |g_svr_fname| points nothing
2724     }
2725     if(g_prvn_fname)
2726     {
2727         OICFree(g_prvn_fname);  // after here |g_prvn_fname| points nothing
2728     }
2729     return 0;  // always return normal case
2730 }
2731
2732 #ifdef __cplusplus
2733 }
2734 #endif //__cplusplus