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