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