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