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