Fixed some typo issues
[iotivity.git] / resource / csdk / security / provisioning / sample / provisioningclient.c
1 /******************************************************************
2  *
3  * Copyright 2015 Samsung Electronics All Rights Reserved.
4  *
5  *
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  *****************************************************************/
20
21 #include "iotivity_config.h"
22
23 #include <stdio.h>
24 #include <string.h>
25 #ifdef HAVE_UNISTD_H
26 #include <unistd.h>
27 #endif
28
29 #include "utlist.h"
30 #include "oic_malloc.h"
31 #include "oic_string.h"
32 #include "ocprovisioningmanager.h"
33 #include "oxmjustworks.h"
34 #include "oxmrandompin.h"
35 #include "srmutility.h"
36 #include "spresource.h"
37 #include "pmtypes.h"
38 #include "oxmverifycommon.h"
39 #include "mbedtls/config.h"
40 #include "mbedtls/pem.h"
41 #include "mbedtls/x509_csr.h"
42 #include "occertutility.h"
43 #include "pmutility.h"
44 #include "occloudprovisioning.h"
45 #include "auth.h"
46 #include "credresource.h"
47
48 #ifdef _MSC_VER
49 #include <io.h>
50 #define F_OK 0
51 #define access _access_s
52 #endif
53
54 /// This example is using experimental API, so there is no guarantee of support for future release,
55 /// nor any there any guarantee that breaking changes will not occur across releases.
56 #include "experimental/payload_logging.h"
57 #include "experimental/logger.h"
58
59 #ifdef __cplusplus
60 extern "C"
61 {
62 #endif //__cplusplus
63
64 // declaration(s) for provisioning client using C-level provisioning API
65 // user input definition for main loop on provisioning client
66 #define _10_DISCOV_ALL_DEVS_        10
67 #define _11_DISCOV_UNOWN_DEVS_      11
68 #define _12_DISCOV_OWN_DEVS_        12
69 #ifdef MULTIPLE_OWNER
70 #define _13_MOT_DISCOV_DEV_         13
71 #define _14_MOT_DISCOV_SINGLE_DEV_  14
72 #endif //MULTIPLE_OWNER
73 #define _20_REGIST_DEVS_            20
74 #define _21_REGIST_DEVS_            21
75 #define _30_PROVIS_PAIR_DEVS_       30
76 #define _31_PROVIS_CRED_            31
77 #define _32_PROVIS_ACL_             32
78 #define _33_CHECK_LINK_STATUS_      33
79 #define _34_SAVE_ACL_               34
80 #define _35_PROVIS_CERT_            35
81 #ifdef WITH_CLOUD
82 #define _36_PROVIS_CLOUD_CONF_      36
83 #define _37_GET_CLOUD_STAT_         37
84 #define _38_REMOVE_CLOUD_CONF_      38
85 #endif //WITH_CLOUD
86 #define _39_PROVIS_SEC_PROFILE      39
87 #define _40_UNLINK_PAIR_DEVS_       40
88 #define _50_REMOVE_SELEC_DEV_       50
89 #define _51_REMOVE_DEV_WITH_UUID_   51
90 #define _52_RESET_SELEC_DEV_        52
91 #define _53_RESET_SVR_DB_           53
92 #define _60_GET_CRED_               60
93 #define _61_GET_ACL_                61
94 #define _62_GET_CSR_                62
95 #define _63_GET_SP_                 63
96 #ifdef MULTIPLE_OWNER
97 #define _70_MOT_CHANGE_MOM_         70
98 #define _71_MOT_PROV_PRECONF_PIN_   71
99 #define _72_MOT_OXM_SEL_            72
100 #endif //MULTIPLE_OWNER
101 #define _80_SELECT_PROTOCOL_        80
102 #define _81_SELECT_VERIF_METHOD_    81
103 #define _99_EXIT_PRVN_CLT_          99
104
105 #define ACL_RESRC_MAX_NUM   16
106 #define ACL_RESRC_ARRAY_SIZE   3 //This value is used only for sample (not OCF spec)
107 #define ACL_RESRC_MAX_LEN   128
108 #define ACL_PEMISN_CNT      5
109 #define DISCOVERY_TIMEOUT   10  // 10 sec
110 #define CALLBACK_TIMEOUT    60  // 1 min
111 #define TAG "provisioningclient"
112
113 static const char* ACL_PEMISN[5] = {"CREATE", "READ", "WRITE", "DELETE", "NOTIFY"};
114 static const char* SVR_DB_FILE_NAME = "oic_svr_db_client.dat";
115         // '_' for separaing from the same constant variable in |srmresourcestrings.c|
116 static const char* PRVN_DB_FILE_NAME = "oic_prvn_mng.db";
117
118 static char* TEST_CERT_NOT_BEFORE = "20170101000000"; // Not before field for certificates, in format YYYYMMDDhhmmss
119 static char* TEST_CERT_NOT_AFTER = "20270101000000";  // + ten years
120
121 // |g_ctx| means provision manager application context and
122 // the following, includes |un/own_list|, could be variables, which |g_ctx| has,
123 // for accessing all function(s) for these, they are declared on global domain
124 static char* g_ctx = "Provision Manager Client Application Context";
125 static char* g_svr_fname;
126 static char* g_prvn_fname;
127 static OCProvisionDev_t* g_own_list;
128 static OCProvisionDev_t* g_unown_list;
129 static int g_own_cnt;
130 static int g_unown_cnt;
131 #ifdef MULTIPLE_OWNER
132 static OCProvisionDev_t* g_mot_enable_list;
133 static int g_mot_enable_cnt;
134 #endif //MULTIPLE_OWNER
135 char* g_caKeyPem;   /* Test CA private key */
136 char* g_caCertPem;  /* Test CA certificate */
137 uint16_t g_caCredId = 0;   /* ID of CA's OCF identity cert */
138 char* g_csr;    /* Certificate signing request from device */
139
140 static bool g_doneCB;    /* Set to true by the callback to indicate it completed. */
141 static bool g_successCB; /* Set to true by the callback to indicate success. */
142 #ifdef __WITH_TLS__
143 static int secure_protocol = 1;
144 static void setDevProtocol(OCProvisionDev_t* dev_lst);
145 #endif
146 // function declaration(s) for calling them before implementing
147 static OicSecAcl_t* createAcl(const int);
148 static OicSecAcl_t* createSimpleAcl(const OicUuid_t uuid);
149 static OCProvisionDev_t* getDevInst(const OCProvisionDev_t*, const int);
150 static int printDevList(const OCProvisionDev_t*);
151 static size_t printUuidList(const OCUuidList_t*);
152 static size_t printResultList(const OCProvisionResult_t*, const size_t);
153 static void printUuid(const OicUuid_t*);
154 static FILE* fopen_prvnMng(const char*, const char*);
155 static int waitCallbackRet(void);
156 static int selectTwoDiffNum(int*, int*, const int, const char*);
157
158 char * gSupportedProfilesDefault[] = { "oic.sec.sp.baseline" };
159 OicSecSp_t gSpDefault =
160 {
161     1,                          // supportedLen
162     gSupportedProfilesDefault,  // supportedProfiles[0]
163     "oic.sec.sp.baseline",      // activeProfile
164 };
165
166 char * gSupportedProfilesAll[] = { "oic.sec.sp.black", "oic.sec.sp.blue", "oic.sec.sp.purple", "oic.sec.sp.baseline",  };
167 OicSecSp_t gSpAll =
168 {
169     4,                      // supportedLen
170     gSupportedProfilesAll,  // supportedProfiles[0]
171     "oic.sec.sp.black",     // activeProfile
172 };
173 char * gSupportedProfilesInvalid[] = { "oic.sec.sp.black", "oic.sec.sp.blue", "oic.sec.sp.purple", "oic.sec.sp.baseline",  };
174 OicSecSp_t gSpInvalid =
175 {
176     4,                         // supportedLen
177     gSupportedProfilesInvalid, // supportedProfiles
178     "oic.sec.sp.invalid",      // activeProfile
179 };
180
181
182 /* At a few places in this file, warning 4028 is incorrectly produced, disable it for the whole file. */
183 #ifdef _MSC_VER
184 #pragma warning( disable : 4028)
185 #endif
186
187 // callback function(s) for provisioning client using C-level provisioning API
188 static void ownershipTransferCB(void* ctx, size_t nOfRes, OCProvisionResult_t* arr, bool hasError)
189 {
190     if(!hasError)
191     {
192         OIC_LOG_V(INFO, TAG, "Ownership Transfer SUCCEEDED - ctx: %s", (char*) ctx);
193     }
194     else
195     {
196         OIC_LOG_V(ERROR, TAG, "Ownership Transfer FAILED - ctx: %s", (char*) ctx);
197         printResultList((const OCProvisionResult_t*) arr, nOfRes);
198     }
199     g_doneCB = true;
200 }
201
202 static void provisionPairwiseCB(void* ctx, size_t nOfRes, OCProvisionResult_t* arr, bool hasError)
203 {
204     if(!hasError)
205     {
206         OIC_LOG_V(INFO, TAG, "Provision Pairwise SUCCEEDED - ctx: %s", (char*) ctx);
207     }
208     else
209     {
210         OIC_LOG_V(ERROR, TAG, "Provision Pairwise FAILED - ctx: %s", (char*) ctx);
211         printResultList((const OCProvisionResult_t*) arr, nOfRes);
212     }
213     g_doneCB = true;
214 }
215
216 static void provisionCredCB(void* ctx, size_t nOfRes, OCProvisionResult_t* arr, bool hasError)
217 {
218     if(!hasError)
219     {
220         OIC_LOG_V(INFO, TAG, "Provision Credential SUCCEEDED - ctx: %s", (char*) ctx);
221         g_successCB = true;
222     }
223     else
224     {
225         OIC_LOG_V(ERROR, TAG, "Provision Credential FAILED - ctx: %s", (char*) ctx);
226         printResultList((const OCProvisionResult_t*) arr, nOfRes);
227         g_successCB = false;
228     }
229     g_doneCB = true;
230 }
231
232 /* Function of type OCProvisionResultCB from \resource\csdk\security\provisioning\include\pmtypes.h */
233 void provisionTrustChainCB(void* ctx, int nOfRes, OCProvisionResult_t *arr, bool hasError)
234 {
235     if (!hasError)
236     {
237         OIC_LOG_V(INFO, TAG, "Provision Credential SUCCEEDED - ctx: %s", (char*)ctx);
238         g_successCB = true;
239     }
240     else
241     {
242         OIC_LOG_V(ERROR, TAG, "Provision Credential FAILED - ctx: %s", (char*)ctx);
243         printResultList((const OCProvisionResult_t*)arr, nOfRes);
244         g_successCB = false;
245     }
246     g_doneCB = true;
247 }
248
249 #ifdef WITH_CLOUD
250 static void provisionCloudConfigCB(void* ctx, size_t nOfRes, OCProvisionResult_t* arr, bool hasError)
251 {
252     if(!hasError)
253     {
254         OIC_LOG_V(INFO, TAG, "Provision cloud config SUCCEEDED - ctx: %s", (char*) ctx);
255     }
256     else
257     {
258         OIC_LOG_V(ERROR, TAG, "Provision cloud config FAILED - ctx: %s", (char*) ctx);
259         printResultList((const OCProvisionResult_t*) arr, nOfRes);
260     }
261     g_doneCB = true;
262 }
263
264 static void getCloudStatusCB(void* ctx, size_t nOfRes, OCProvisionResult_t* arr, bool hasError)
265 {
266     if(!hasError)
267     {
268         OIC_LOG_V(INFO, TAG, "Get cloud status SUCCEEDED - ctx: %s", (char*) ctx);
269     }
270     else
271     {
272         OIC_LOG_V(ERROR, TAG, "Get cloud status FAILED - ctx: %s", (char*) ctx);
273         printResultList((const OCProvisionResult_t*) arr, nOfRes);
274     }
275     g_doneCB = true;
276 }
277
278 static void removeCloudConfCB(void* ctx, size_t nOfRes, OCProvisionResult_t* arr, bool hasError)
279 {
280     if(!hasError)
281     {
282         OIC_LOG_V(INFO, TAG, "Remove cloud ACL SUCCEEDED - ctx: %s", (char*) ctx);
283     }
284     else
285     {
286         OIC_LOG_V(ERROR, TAG, "Remove cloud ACL FAILED - ctx: %s", (char*) ctx);
287         printResultList((const OCProvisionResult_t*) arr, nOfRes);
288     }
289     g_doneCB = true;
290 }
291 #endif //WITH_CLOUD
292
293 static void provisionAclCB(void* ctx, size_t nOfRes, OCProvisionResult_t* arr, bool hasError)
294 {
295     if(!hasError)
296     {
297         OIC_LOG_V(INFO, TAG, "Provision ACL SUCCEEDED - ctx: %s", (char*) ctx);
298     }
299     else
300     {
301         OIC_LOG_V(ERROR, TAG, "Provision ACL FAILED - ctx: %s", (char*) ctx);
302         printResultList((const OCProvisionResult_t*) arr, nOfRes);
303     }
304     g_doneCB = true;
305 }
306
307 static void getCredCB(void* ctx, size_t nOfRes, OCProvisionResult_t* arr, bool hasError)
308 {
309     if(!hasError)
310     {
311         OIC_LOG_V(INFO, TAG, "getCredCB SUCCEEDED - ctx: %s", (char*) ctx);
312     }
313     else
314     {
315         OIC_LOG_V(ERROR, TAG, "getCredCB FAILED - ctx: %s", (char*) ctx);
316         printResultList((const OCProvisionResult_t*) arr, nOfRes);
317     }
318     g_doneCB = true;
319 }
320
321 static void getAclCB(void* ctx, size_t nOfRes, OCProvisionResult_t* arr, bool hasError)
322 {
323     if(!hasError)
324     {
325         OIC_LOG_V(INFO, TAG, "getAclCB SUCCEEDED - ctx: %s", (char*) ctx);
326     }
327     else
328     {
329         OIC_LOG_V(ERROR, TAG, "getAclCB FAILED - ctx: %s", (char*) ctx);
330         printResultList((const OCProvisionResult_t*) arr, nOfRes);
331     }
332     g_doneCB = true;
333 }
334
335 static void getCsrCB(void* ctx, size_t nOfRes, OCPMGetCsrResult_t* arr, bool hasError)
336 {
337     if (!hasError)
338     {
339         size_t i;
340         mbedtls_x509_csr csr;
341         OIC_LOG_V(INFO, TAG, "getCsrCB SUCCEEDED - ctx: %s", (char*)ctx);
342         for (i = 0; i < nOfRes; i++)
343         {
344             char pemBuffer[2048] = { 0 };
345             char infoBuffer[2048] = { 0 };
346             size_t olen;
347             int ret;
348
349             if (arr[i].encoding == OIC_ENCODING_DER)
350             {
351                 ret = mbedtls_pem_write_buffer("-----BEGIN CERTIFICATE REQUEST-----",
352                     "-----END CERTIFICATE REQUEST-----",
353                     arr[i].csr,
354                     arr[i].csrLen,
355                     (unsigned char *)pemBuffer,
356                     sizeof(pemBuffer),
357                     &olen);
358                 if (ret < 0)
359                 {
360                     OIC_LOG_V(ERROR, TAG, "Couldn't convert CSR into PEM: %d", ret);
361                     pemBuffer[0] = '\0';
362                 }
363             }
364             else
365             {
366                 OICStrcpyPartial(pemBuffer, sizeof(pemBuffer), (const char *)arr[i].csr, arr[i].csrLen);
367             }
368
369             mbedtls_x509_csr_init(&csr);
370             ret = mbedtls_x509_csr_parse_der(&csr, arr[i].csr, arr[i].csrLen);
371             if (ret < 0)
372             {
373                 OIC_LOG_V(ERROR, TAG, "Couldn't parse CSR: %d", ret);
374                 infoBuffer[0] = '\0';
375             }
376             else
377             {
378                 ret = mbedtls_x509_csr_info(infoBuffer, sizeof(infoBuffer), "", &csr);
379                 if (ret < 0)
380                 {
381                     OIC_LOG_V(ERROR, TAG, "Couldn't get CSR info buffer: %d", ret);
382                     infoBuffer[0] = '\0';
383                 }
384             }
385             mbedtls_x509_csr_free(&csr);
386
387             OIC_LOG(INFO, TAG, "getCsrCB success");
388             // OIC_LOG_V truncates strings, and the entirety of the CSR PEM gets cut off if we use it
389             printf("getCsrCB: csr[%" PRIuPTR "]:\n%s\n", i, pemBuffer);
390             printf("getCsrCB: csr info[%" PRIuPTR "]:\n%s\n", i, infoBuffer);
391         }
392     }
393     else
394     {
395         OIC_LOG_V(ERROR, TAG, "getCsrCB FAILED - ctx: %s", (char*)ctx);
396
397         if (!arr || (0 == nOfRes))
398         {
399             printf("     Device List is Empty..\n\n");
400         }
401         else
402         {
403             size_t lst_cnt;
404             for (lst_cnt = 0; nOfRes > lst_cnt; ++lst_cnt)
405             {
406                 printf("     [%" PRIuPTR "] ", lst_cnt + 1);
407                 printUuid((const OicUuid_t*)&arr[lst_cnt].deviceId);
408                 printf(" - result: %d\n", arr[lst_cnt].res);
409             }
410             printf("\n");
411         }
412     }
413     g_doneCB = true;
414 }
415
416 static void getSpCB(void* ctx, size_t nOfRes, OCPMGetSpResult_t* arr, bool hasError)
417 {
418     if(!hasError)
419     {
420         OIC_LOG_V(INFO, TAG, "getSpCB SUCCEEDED - ctx: %s", (char*) ctx);
421         OIC_LOG(INFO, TAG, "Retrieved Security Profile(s)");
422         for (size_t i = 0; i < nOfRes; i++)
423         {
424             LogSp((arr[i]).sp, INFO, TAG, NULL);
425         }
426     }
427     else
428     {
429         OIC_LOG_V(ERROR, TAG, "getSpCB FAILED - ctx: %s", (char*) ctx);
430         printResultList((const OCProvisionResult_t*) arr, nOfRes);
431     }
432     g_doneCB = true;
433 }
434
435 static void getCsrForCertProvCB(void* ctx, size_t nOfRes, OCPMGetCsrResult_t* arr, bool hasError)
436 {
437     g_successCB = false;
438
439     if (!hasError)
440     {
441         if (nOfRes != 1)
442         {
443             OIC_LOG_V(ERROR, TAG, "getCsrForCertProvCB FAILED - ctx: %s", (char*)ctx);
444             goto exit;
445         }
446
447         if (arr[0].encoding == OIC_ENCODING_DER)
448         {
449             OCStackResult res = OCConvertDerCSRToPem((char*)arr[0].csr, arr[0].csrLen, &g_csr);
450             if (res != OC_STACK_OK)
451             {
452                 OIC_LOG_V(ERROR, TAG, "getCsrForCertProvCB FAILED (CSR re-encoding failed) - error: %d, ctx: %s", res, (char*)ctx);
453                 goto exit;
454             }
455             g_successCB = true;
456         }
457         else if(arr[0].encoding == OIC_ENCODING_PEM)
458         {
459             g_csr = (char*)OICCalloc(1, arr[0].csrLen);
460             if (g_csr == NULL)
461             {
462                 OIC_LOG_V(ERROR, TAG, "getCsrForCertProvCB FAILED (memory allocation) - ctx: %s", (char*)ctx);
463                 goto exit;
464             }
465
466             memcpy(g_csr, arr[0].csr, arr[0].csrLen);
467
468             OIC_LOG(INFO, TAG, "getCsrForCertProvCB success");
469             g_successCB = true;
470         }
471         else
472         {
473             OIC_LOG_V(ERROR, TAG, "getCsrForCertProvCB FAILED (unknown encoding) - ctx: %s", (char*)ctx);
474             goto exit;
475         }
476     }
477     else
478     {
479         OIC_LOG_V(ERROR, TAG, "getCsrForCertProvCB FAILED - ctx: %s", (char*)ctx);
480     }
481
482 exit:
483     g_doneCB = true;
484 }
485
486 static void unlinkDevicesCB(void* ctx, size_t nOfRes, OCProvisionResult_t* arr, bool hasError)
487 {
488     if(!hasError)
489     {
490         OIC_LOG_V(INFO, TAG, "Unlink Devices SUCCEEDED - ctx: %s", (char*) ctx);
491     }
492     else
493     {
494         OIC_LOG_V(ERROR, TAG, "Unlink Devices FAILED - ctx: %s", (char*) ctx);
495         printResultList((const OCProvisionResult_t*) arr, nOfRes);
496     }
497     g_doneCB = true;
498 }
499
500 static void removeDeviceCB(void* ctx, size_t nOfRes, OCProvisionResult_t* arr, bool hasError)
501 {
502     if(!hasError)
503     {
504         OIC_LOG_V(INFO, TAG, "Remove Device SUCCEEDED - ctx: %s", (char*) ctx);
505     }
506     else
507     {
508         OIC_LOG_V(ERROR, TAG, "Remove Device FAILED - ctx: %s", (char*) ctx);
509         printResultList((const OCProvisionResult_t*) arr, nOfRes);
510     }
511     g_doneCB = true;
512 }
513
514 static void syncDeviceCB(void* ctx, size_t nOfRes, OCProvisionResult_t* arr, bool hasError)
515 {
516     if(!hasError)
517     {
518         OIC_LOG_V(INFO, TAG, "Sync Device SUCCEEDED - ctx: %s", (char*) ctx);
519     }
520     else
521     {
522         OIC_LOG_V(ERROR, TAG, "Sync Device FAILED - ctx: %s", (char*) ctx);
523         printResultList((const OCProvisionResult_t*) arr, nOfRes);
524     }
525     g_doneCB = true;
526 }
527
528 #ifdef MULTIPLE_OWNER
529 static void updateDoxmForMOTCB(void* ctx, size_t nOfRes, OCProvisionResult_t* arr, bool hasError)
530 {
531     if(!hasError)
532     {
533         OIC_LOG_V(INFO, TAG, "POST 'doxm' SUCCEEDED - ctx: %s", (char*) ctx);
534     }
535     else
536     {
537         OIC_LOG_V(ERROR, TAG, "POST 'doxm'  FAILED - ctx: %s", (char*) ctx);
538         printResultList((const OCProvisionResult_t*) arr, nOfRes);
539     }
540     g_doneCB = true;
541 }
542 #endif //MULTIPLE_OWNER
543
544 static void OC_CALL inputPinCB(OicUuid_t deviceId, char *pin, size_t len, void *context)
545 {
546     OC_UNUSED(deviceId);
547     OC_UNUSED(context);
548
549     if(!pin || OXM_RANDOM_PIN_MIN_SIZE > len)
550     {
551         OIC_LOG(ERROR, TAG, "inputPinCB invalid parameters");
552         return;
553     }
554
555     printf("   > INPUT PIN: ");
556     for(int ret=0; 1!=ret; )
557     {
558         ret = scanf("%32s", pin);
559         for( ; 0x20<=getchar(); );  // for removing overflow garbages
560                                     // '0x20<=code' is character region
561     }
562 }
563
564 // function(s) for provisioning client using C-level provisioning API
565 static int initProvisionClient(void)
566 {
567     // initialize persistent storage for SVR DB
568     static OCPersistentStorage pstStr =
569     {
570         .open = fopen_prvnMng,
571         .read = fread,
572         .write = fwrite,
573         .close = fclose,
574         .unlink = remove
575     };
576     if(OC_STACK_OK != OCRegisterPersistentStorageHandler(&pstStr))
577     {
578         OIC_LOG(ERROR, TAG, "OCRegisterPersistentStorageHandler error");
579         return -1;
580     }
581
582     // initialize OC stack and provisioning manager
583     if(OC_STACK_OK != OCInit(NULL, 0, OC_CLIENT_SERVER))
584     {
585         OIC_LOG(ERROR, TAG, "OCStack init error");
586         return -1;
587     }
588
589     if (access(PRVN_DB_FILE_NAME, F_OK) == 0)
590     {
591         printf("************************************************************\n");
592         printf("************Provisioning DB file already exists.************\n");
593         printf("************************************************************\n");
594     }
595     else
596     {
597         printf("*************************************************************\n");
598         printf("************No provisioning DB file, creating new************\n");
599         printf("*************************************************************\n");
600     }
601
602     if(OC_STACK_OK != OCInitPM(PRVN_DB_FILE_NAME))
603     {
604         OIC_LOG(ERROR, TAG, "OC_PM init error");
605         return -1;
606     }
607
608     SetInputPinWithContextCB(inputPinCB, NULL);
609
610     return 0;
611 }
612
613 static int discoverAllDevices(void)
614 {
615     // delete un/owned device lists before updating them
616     if(g_own_list)
617     {
618         OCDeleteDiscoveredDevices(g_own_list);
619         g_own_list = NULL;
620     }
621     if(g_unown_list)
622     {
623         OCDeleteDiscoveredDevices(g_unown_list);
624         g_unown_list = NULL;
625     }
626
627     // call |OCGetDevInfoFromNetwork| API
628     printf("   Discovering All Un/Owned Devices on Network..\n");
629     if(OC_STACK_OK != OCGetDevInfoFromNetwork(DISCOVERY_TIMEOUT, &g_own_list, &g_unown_list))
630     {
631         OIC_LOG(ERROR, TAG, "OCGetDevInfoFromNetwork API error");
632         return -1;
633     }
634
635     // display the discovered un/owned lists
636     printf("   > Discovered Owned Devices\n");
637     g_own_cnt = printDevList(g_own_list);
638     printf("   > Discovered Unowned Devices\n");
639     g_unown_cnt = printDevList(g_unown_list);
640 #ifdef __WITH_TLS__
641     setDevProtocol(g_own_list);
642     setDevProtocol(g_unown_list);
643 #endif
644     return 0;
645 }
646
647
648 static int discoverUnownedDevices(void)
649 {
650     // delete unowned device list before updating it
651     if(g_unown_list)
652     {
653         OCDeleteDiscoveredDevices(g_unown_list);
654         g_unown_list = NULL;
655     }
656
657     // call |OCDiscoverUnownedDevices| API
658     printf("   Discovering Only Unowned Devices on Network..\n");
659     if(OC_STACK_OK != OCDiscoverUnownedDevices(DISCOVERY_TIMEOUT, &g_unown_list))
660     {
661         OIC_LOG(ERROR, TAG, "OCDiscoverUnownedDevices API error");
662         return -1;
663     }
664
665     // display the discovered unowned list
666     printf("   > Discovered Unowned Devices\n");
667     g_unown_cnt = printDevList(g_unown_list);
668 #ifdef __WITH_TLS__
669     setDevProtocol(g_unown_list);
670 #endif
671     return 0;
672 }
673
674 static int discoverOwnedDevices(void)
675 {
676     // delete owned device list before updating it
677     if(g_own_list)
678     {
679         OCDeleteDiscoveredDevices(g_own_list);
680         g_own_list = NULL;
681     }
682
683     // call |OCDiscoverOwnedDevices| API
684     printf("   Discovering Only Owned Devices on Network..\n");
685     if(OC_STACK_OK != OCDiscoverOwnedDevices(DISCOVERY_TIMEOUT, &g_own_list))
686     {
687         OIC_LOG(ERROR, TAG, "OCDiscoverOwnedDevices API error");
688         return -1;
689     }
690
691     // display the discovered owned list
692     printf("   > Discovered Owned Devices\n");
693     g_own_cnt = printDevList(g_own_list);
694 #ifdef __WITH_TLS__
695     setDevProtocol(g_own_list);
696 #endif
697     return 0;
698 }
699
700 #ifdef MULTIPLE_OWNER
701 static int discoverMOTEnabledDevices(void)
702 {
703     // delete owned device list before updating it
704     if(g_mot_enable_list)
705     {
706         OCDeleteDiscoveredDevices(g_mot_enable_list);
707         g_mot_enable_list = NULL;
708     }
709
710     // call |OCDiscoverOwnedDevices| API
711     printf("   Discovering Multiple Ownership Transfer Enabled Devices on Network..\n");
712     if(OC_STACK_OK != OCDiscoverMultipleOwnerEnabledDevices(DISCOVERY_TIMEOUT, &g_mot_enable_list))
713     {
714         OIC_LOG(ERROR, TAG, "OCDiscoverMultipleOwnerEnalbedDevices API error");
715         return -1;
716     }
717
718     // display the discovered owned list
719     printf("   > Discovered Multiple Ownership Transfer Enabled Devices\n");
720     g_mot_enable_cnt = printDevList(g_mot_enable_list);
721
722     return 0;
723 }
724
725 static int discoverSingleMOTEnabledDevice(void)
726 {
727     OicUuid_t uuid = { .id = { 0 } };
728     char strUuid[64] = { 0 };
729
730     // Delete owned device list before updating it
731     if (g_mot_enable_list)
732     {
733         OCDeleteDiscoveredDevices(g_mot_enable_list);
734         g_mot_enable_list = NULL;
735     }
736
737     // Get the device id
738     printf("   Specify the Multiple Ownership Transfer enabled device to discover on the network\n");
739     printf("   > Input the UUID : ");
740     for (int ret = 0; 1 != ret; )
741     {
742         ret = scanf("%64s", strUuid);
743         for (; 0x20 <= getchar(); );  // for removing overflow garbages
744                                       // '0x20<=code' is character region
745     }
746
747     OCStackResult rst = ConvertStrToUuid(strUuid, &uuid);
748     if (OC_STACK_OK != rst)
749     {
750         OIC_LOG_V(ERROR, TAG, "ConvertStrToUuid API error: %d", rst);
751         return -1;
752     }
753
754     // Call |OCDiscoverMultipleOwnerEnabledSingleDevice| API
755     printf("   Discovering the Multiple Ownership Transfer enabled device on the network..\n");
756     if (OC_STACK_OK != OCDiscoverMultipleOwnerEnabledSingleDevice(DISCOVERY_TIMEOUT, &uuid, &g_mot_enable_list))
757     {
758         OIC_LOG(ERROR, TAG, "OCDiscoverMultipleOwnerEnabledSingleDevice API error");
759         return -1;
760     }
761
762     // Display the discovered owned list
763     printf("   > Discovered Multiple Ownership Transfer Enabled Device\n");
764     g_mot_enable_cnt = printDevList(g_mot_enable_list);
765
766     return 0;
767 }
768 #endif //MULTIPLE_OWNER
769
770 static int registerDevices(int fSelect)
771 {
772     // check |unown_list| for registering devices
773     if(!g_unown_list || 0>=g_unown_cnt)
774     {
775         printf("   > Unowned Device List, to Register Devices, is Empty\n");
776         printf("   > Please Discover Unowned Devices first, with [10|11] Menu\n");
777         return 0;  // normal case
778     }
779
780     OCProvisionDev_t *p, *t, *devList = NULL;
781     int devListLen = 0;
782
783     if(fSelect)
784     {
785         for(;;)
786         {
787             printf("************************************************************\n");
788             printf("OTM device candidate list:\n");
789             g_unown_cnt = printDevList(g_unown_list);
790             if(0 == g_unown_cnt)
791             {
792                 break;
793             }
794
795             printf("Select number device from list\nor: 0 - start OTM -1 - escape\n");
796             int c = 0;
797
798             if (!scanf("%d",&c))
799             {
800                 continue;
801             }
802
803             if(0 == c && NULL != devList)
804             {
805                 break;
806             }
807
808             if(-1 == c)
809             {
810                 if(devListLen)
811                 {
812                     p = NULL;
813                     t = NULL;
814                     LL_FOREACH_SAFE(devList, p, t)
815                     {
816                         LL_APPEND(g_unown_list, p);
817                         LL_DELETE(devList, t);
818                     }
819                 }
820                 return 0;
821             }
822
823             if(c > g_unown_cnt)
824             {
825                 continue;
826             }
827
828             p = g_unown_list;
829             for(int lst_cnt = 1; p && lst_cnt != c; lst_cnt++, p = p->next);
830
831             if(p)
832             {
833                 LL_DELETE(g_unown_list, p);
834                 LL_APPEND(devList, p);
835             }
836
837             printf("OTM device list:\n");
838             devListLen = printDevList(devList);
839         }
840     }
841     else
842     {
843         devList = g_unown_list;
844     }
845     // call |OCDoOwnershipTransfer| API
846     // calling this API with callback actually acts like blocking
847     // for error checking, the return value saved and printed
848     g_doneCB = false;
849     printf("   Registering All Discovered Unowned Devices..\n");
850     OCStackResult rst = OCDoOwnershipTransfer((void*) g_ctx, devList, ownershipTransferCB);
851
852     if(OC_STACK_OK != rst)
853     {
854         OIC_LOG_V(ERROR, TAG, "OCDoOwnershipTransfer API error: %d", rst);
855         return -1;
856     }
857     if(waitCallbackRet())  // input |g_doneCB| flag implicitly
858     {
859         OIC_LOG(ERROR, TAG, "OCDoOwnershipTransfer callback error");
860         return -1;
861     }
862
863     // display the registered result
864     printf("   > Registered Discovered Unowned Devices\n");
865     printf("   > Please Discover Owned Devices for the Registered Result, with [10|12] Menu\n");
866
867     return 0;
868 }
869
870 static int provisionPairwise(void)
871 {
872     // check |own_list| for provisioning pairwise devices
873     if(!g_own_list || 2>g_own_cnt)
874     {
875         printf("   > Owned Device List, to Provision the Pairwise, is Empty\n");
876         printf("   > Please Register Unowned Devices first, with [20] Menu\n");
877         return 0;  // normal case
878     }
879
880     // select two devices for provisioning pairwise devices
881     int dev_num[2] = {0};
882     if(selectTwoDiffNum(&(dev_num[0]), &(dev_num[1]), g_own_cnt, "for Linking Devices"))
883     {
884         OIC_LOG(ERROR, TAG, "selectTwoDiffNum error return");
885         return -1;  // not need to 'goto' |ERROR| before allocating |acl|
886     }
887
888     // create ACL(s) for each selected device
889     OicSecAcl_t* acl[2] = {0};
890     for(int i=0; 2>i; ++i)
891     {
892         acl[i] = createAcl(dev_num[i]);
893         if(!acl[i])
894         {
895             OIC_LOG(ERROR, TAG, "createAcl error return");
896             goto PVPWS_ERROR;
897         }
898     }
899
900     // call |OCProvisionPairwiseDevices| API
901     // calling this API with callback actually acts like blocking
902     // for error checking, the return value saved and printed
903     g_doneCB = false;
904     printf("   Provisioning Selected Pairwise Devices..\n");
905     OCStackResult rst =
906             OCProvisionPairwiseDevices((void*) g_ctx,
907                     SYMMETRIC_PAIR_WISE_KEY, OWNER_PSK_LENGTH_128,
908                     getDevInst((const OCProvisionDev_t*) g_own_list, dev_num[0]), acl[0],
909                     getDevInst((const OCProvisionDev_t*) g_own_list, dev_num[1]), acl[1],
910                     provisionPairwiseCB);
911     if(OC_STACK_OK != rst)
912     {
913         OIC_LOG_V(ERROR, TAG, "OCProvisionPairwiseDevices API error: %d", rst);
914         goto PVPWS_ERROR;
915     }
916     if(waitCallbackRet())  // input |g_doneCB| flag implicitly
917     {
918         OIC_LOG(ERROR, TAG, "OCProvisionPairwiseDevices callback error");
919         goto PVPWS_ERROR;
920     }
921     OCDeleteACLList(acl[0]);
922     OCDeleteACLList(acl[1]);
923
924     // display the pairwise-provisioned result
925     printf("   > Provisioned Selected Pairwise Devices\n");
926     printf("   > Please Check Device's Status for the Linked Result, with [33] Menu\n");
927
928     return 0;
929
930 PVPWS_ERROR:
931     OCDeleteACLList(acl[0]);
932     OCDeleteACLList(acl[1]);
933     return -1;
934 }
935
936 static int provisionCred(void)
937 {
938     // check |own_list| for provisioning pairwise credentials
939     if(!g_own_list || 2>g_own_cnt)
940     {
941         printf("   > Owned Device List, to Provision Credentials, is Empty\n");
942         printf("   > Please Register Unowned Devices first, with [20] Menu\n");
943         return 0;  // normal case
944     }
945
946     // select two devices for provisioning pairwise credentials
947     int dev_num[2] = {0};
948     if(selectTwoDiffNum(&(dev_num[0]), &(dev_num[1]), g_own_cnt, "for Linking CRED(s)"))
949     {
950         OIC_LOG(ERROR, TAG, "selectTwoDiffNum error return");
951         return -1;
952     }
953
954     printf("   Select PSK length..\n");
955     printf("   1 - 128bit(Default)\n");
956     printf("   2 - 256bit\n");
957     int sizeOption = 0;
958
959     for(int ret=0; 1!=ret; )
960     {
961          ret = scanf("%d",&sizeOption);
962          for( ; 0x20<=getchar(); );  // for removing overflow garbages
963                                     // '0x20<=code' is character region
964     }
965     size_t size = 0;
966
967     switch(sizeOption)
968     {
969         case 1:
970         {
971             size = OWNER_PSK_LENGTH_128;
972             break;
973         }
974         case 2:
975         {
976             size = OWNER_PSK_LENGTH_256;
977             break;
978         }
979         default:
980         {
981             size = OWNER_PSK_LENGTH_128;
982             break;
983         }
984     }
985
986
987     // call |OCProvisionCredentials| API
988     // calling this API with callback actually acts like blocking
989     // for error checking, the return value saved and printed
990     g_doneCB = false;
991     printf("   Provisioning Selected Pairwise Credentials..\n");
992     OCStackResult rst =
993             OCProvisionCredentials((void*) g_ctx,
994                     SYMMETRIC_PAIR_WISE_KEY, size,
995                     getDevInst((const OCProvisionDev_t*) g_own_list, dev_num[0]),
996                     getDevInst((const OCProvisionDev_t*) g_own_list, dev_num[1]),
997                     provisionCredCB);
998     if(OC_STACK_OK != rst)
999     {
1000         OIC_LOG_V(ERROR, TAG, "OCProvisionCredentials API error: %d", rst);
1001         return -1;
1002     }
1003     if(waitCallbackRet())  // input |g_doneCB| flag implicitly
1004     {
1005         OIC_LOG(ERROR, TAG, "OCProvisionCredentials callback error");
1006         return -1;
1007     }
1008
1009     // display the CRED-provisioned result
1010     printf("   > Provisioned Selected Pairwise Crendentials\n");
1011     printf("   > Please Check Device's Status for the Linked Result, with [34] Menu\n");
1012
1013     return 0;
1014 }
1015
1016 /*
1017  *   Initialize the provisioning client for certificate provisioning.
1018  *   This function:
1019  *   1. Generates a root key pair for a CA.
1020  *   2. Generates a self-signed root certificate for the CA public key.
1021  *   3. Saves this root as a trust anchor locally.
1022  *   4. Generate and store an IoTivity key and cert (issued from the CA root cert).
1023  *      This is an EE cert the CA/OBT will use in DTLS.
1024  *
1025  *   The CA's key and cert are written to g_caKeyPem and g_caCertPem (resp.).
1026  */
1027 static int setupCA(void)
1028 {
1029     char* publicKey = NULL;
1030     size_t publicKeyLen = 0;
1031     size_t caKeyLen = 0;
1032     char* serial = NULL;
1033     size_t serialLen = 0;
1034     size_t caCertLen = 0;
1035     char* idPublicKey = NULL;
1036     char* idKey = NULL;
1037     char* idCert = NULL;
1038     size_t idCertLen = 0;
1039     size_t idKeyLen = 0;
1040
1041     if (g_caCredId == 0)
1042     {
1043         printf("Setting up CA for certificate provisioning\n");
1044     }
1045     else
1046     {
1047         printf("Skipping CA setup, already done\n");
1048         return 0;
1049     }
1050
1051     /* Create CA keypair, serial number */
1052     OCStackResult res = OCGenerateKeyPair(&publicKey, &publicKeyLen, &g_caKeyPem, &caKeyLen);
1053     if (res != OC_STACK_OK)
1054     {
1055         OIC_LOG_V(ERROR, TAG, "OCGenerateKeyPair failed, error: %d", res);
1056         goto exit;
1057     }
1058
1059     res = OCGenerateRandomSerialNumber(&serial, &serialLen);
1060     if (res != OC_STACK_OK)
1061     {
1062         OIC_LOG_V(ERROR, TAG, "OCGenerateRandomSerialNumber failed, error: %d", res);
1063         goto exit;
1064     }
1065
1066     /* Create a CA certificate */
1067     res = OCGenerateRootCACertificate(
1068         "C=US, O=Open Connectivity Foundation, CN=IoTivity test code CA",  // subject
1069         publicKey,
1070         NULL,               // Issuer private key is null
1071         g_caKeyPem,         // use CA's own key to create self-signed cert
1072         serial,
1073         TEST_CERT_NOT_BEFORE,
1074         TEST_CERT_NOT_AFTER,
1075         &g_caCertPem,
1076         &caCertLen);
1077     if (res != OC_STACK_OK)
1078     {
1079         OIC_LOG_V(ERROR, TAG, "OCGenerateRootCACertificate failed, error: %d", res);
1080         goto exit;
1081     }
1082
1083     /* Set our own trust anchor so that we trust certs we've issued. */
1084     res = OCSaveTrustCertChain((uint8_t*) g_caCertPem, caCertLen, OIC_ENCODING_PEM, &g_caCredId);
1085     if (OC_STACK_OK != res)
1086     {
1087         OIC_LOG_V(ERROR, TAG, "OCSaveTrustCertChain error: %d", res);
1088         goto exit;
1089     }
1090
1091     /* Create identity certificate for use by the CA. */
1092     res = OCGenerateKeyPair(&idPublicKey, &publicKeyLen, &idKey, &idKeyLen);
1093     if (res != OC_STACK_OK)
1094     {
1095         OIC_LOG_V(ERROR, TAG, "OCGenerateKeyPair failed, error: %d", res);
1096         goto exit;
1097     }
1098
1099     res = OCGenerateRandomSerialNumber(&serial, &serialLen);
1100     if (res != OC_STACK_OK)
1101     {
1102         OIC_LOG_V(ERROR, TAG, "OCGenerateRandomSerialNumber failed, error: %d", res);
1103         goto exit;
1104     }
1105
1106     OCUUIdentity deviceId = { 0 };
1107     res = OCGetDeviceId(&deviceId);
1108     if (res != OC_STACK_OK)
1109     {
1110         OIC_LOG_V(ERROR, TAG, "Failed to get own UUID, error: %d", res);
1111         goto exit;
1112     }
1113
1114     OicUuid_t uuid = { 0 };
1115     memcpy(uuid.id, deviceId.id, sizeof(uuid.id));
1116
1117     res = OCGenerateIdentityCertificate(
1118         &uuid,
1119         idPublicKey,
1120         g_caCertPem,
1121         g_caKeyPem,
1122         serial,
1123         TEST_CERT_NOT_BEFORE,
1124         TEST_CERT_NOT_AFTER,
1125         &idCert,
1126         &idCertLen);
1127     if (res != OC_STACK_OK)
1128     {
1129         OIC_LOG_V(ERROR, TAG, "Failed to create identity cert for CA, error: %d", res);
1130         goto exit;
1131     }
1132
1133     uint16_t idCertCredId = 0;
1134     res = OCSaveOwnCertChain(idCert, idKey, &idCertCredId);
1135     if (res != OC_STACK_OK)
1136     {
1137         OIC_LOG_V(ERROR, TAG, "Failed to save CA's identity cert & key, error: %d", res);
1138         goto exit;
1139     }
1140
1141 exit:
1142     OICFree(publicKey);
1143     OICFree(serial);
1144     OICFree(idPublicKey);
1145     if (idKey != NULL)
1146     {
1147         OICClearMemory(idKey, idKeyLen);
1148         OICFree(idKey);
1149     }
1150     OICFree(idCert);
1151
1152     if (res != OC_STACK_OK)
1153     {
1154         return -1;
1155     }
1156
1157     return 0;
1158 }
1159
1160 /*
1161  * Create an identity certificate for a device, based on the information in its CSR.
1162  * Assumes the csr has already been validated wtih OCVerifyCSRSignature.
1163  */
1164 static int createIdentityCertFromCSR(const char* caKeyPem, const char* caCertPem, char* csr,
1165     char** deviceCert)
1166 {
1167     char* publicKey = NULL;
1168     char* serial = NULL;
1169     size_t serialLen;
1170     OicUuid_t uuid = { 0 };
1171     OCStackResult res = OC_STACK_ERROR;
1172
1173     res = OCGetUuidFromCSR(csr, &uuid);
1174     if (res != OC_STACK_OK)
1175     {
1176         OIC_LOG_V(ERROR, TAG, "Failed to get UUID from CSR, error: %d", res);
1177         goto exit;
1178     }
1179     /* Note: a real OBT must make sure the UUID isn't already in use on the network. */
1180
1181     res = OCGetPublicKeyFromCSR(csr, &publicKey);
1182     if (res != OC_STACK_OK)
1183     {
1184         OIC_LOG_V(ERROR, TAG, "Failed to get public key from CSR, error: %d", res);
1185         goto exit;
1186     }
1187
1188     res = OCGenerateRandomSerialNumber(&serial, &serialLen);
1189     if (res != OC_STACK_OK)
1190     {
1191         OIC_LOG_V(ERROR, TAG, "OCGenerateRandomSerialNumber failed, error: %d", res);
1192         goto exit;
1193     }
1194
1195     size_t deviceCertLen;
1196     res = OCGenerateIdentityCertificate(
1197             &uuid,
1198             publicKey,
1199             caCertPem,
1200             caKeyPem,
1201             serial,
1202             TEST_CERT_NOT_BEFORE,
1203             TEST_CERT_NOT_AFTER,
1204             deviceCert,
1205             &deviceCertLen);
1206
1207     if(res != OC_STACK_OK)
1208     {
1209         OIC_LOG_V(ERROR, TAG, "OCGenerateIdentityCertificate failed, error: %d", res);
1210         goto exit;
1211     }
1212
1213 exit:
1214     OICFree(publicKey);
1215     OICFree(serial);
1216
1217     if (res != OC_STACK_OK)
1218     {
1219         return -1;
1220     }
1221
1222     return 0;
1223 }
1224
1225 static int provisionCert(void)
1226 {
1227     // make sure we own at least one device to provision
1228     if (!g_own_list || g_own_cnt == 0)
1229     {
1230         printf("   > Owned Device List, to Provision Credentials, is Empty\n");
1231         printf("   > Please Register Unowned Devices first, with [20] Menu\n");
1232         return 0;  // normal case
1233     }
1234
1235     // select device for provisioning certificate
1236     int dev_num = 0;
1237     if (g_own_cnt == 1)
1238     {
1239         dev_num = 1;
1240     }
1241     else
1242     {
1243         for (; ; )
1244         {
1245             printf("   > Enter Device Number, for certificate provisioning: ");
1246             for (int ret = 0; 1 != ret; )
1247             {
1248                 ret = scanf("%d", &dev_num);
1249                 for (; 0x20 <= getchar(); );  // for removing overflow garbages
1250                                           // '0x20<=code' is character region
1251             }
1252             if (0<dev_num && g_own_cnt >= dev_num)
1253             {
1254                 break;
1255             }
1256             printf("     Entered Wrong Number. Please Enter Again\n");
1257         }
1258     }
1259
1260     OCProvisionDev_t* targetDevice = getDevInst((const OCProvisionDev_t*)g_own_list, dev_num);
1261     if (targetDevice == NULL)
1262     {
1263         OIC_LOG(ERROR, TAG, "Error, invalid device %d");
1264         return -1;
1265     }
1266
1267     // Install the CA trust anchor
1268     if (setupCA() != 0)
1269     {
1270         printf("     Failed to setup CA\n");
1271         return -1;
1272     }
1273
1274     // Provision the CA root cert to the target device
1275     printf("   > Saving root certificate (trust anchor) to selected device..\n");
1276     g_doneCB = false;
1277     OicSecCredType_t type = SIGNED_ASYMMETRIC_KEY;
1278
1279     OCStackResult rst = OCProvisionTrustCertChain((void*)g_ctx, type, g_caCredId, targetDevice, (OCProvisionResultCB)&provisionTrustChainCB);
1280     if (OC_STACK_OK != rst)
1281     {
1282         OIC_LOG_V(ERROR, TAG, "OCProvisionTrustCertChain returned error: %d", rst);
1283         return -1;
1284     }
1285
1286     if (waitCallbackRet())  // input |g_doneCB| flag implicitly
1287     {
1288         OIC_LOG(ERROR, TAG, "OCProvisionTrustCertChain callback error");
1289         return -1;
1290     }
1291     if (!g_successCB)
1292     {
1293         return -1;
1294     }
1295
1296     // Request a CSR from the device, check the CSR signature
1297     printf("   > Getting CSR from device..\n");
1298     g_doneCB = false;
1299     rst = OCGetCSRResource((void*)g_ctx, targetDevice, getCsrForCertProvCB);
1300     if (OC_STACK_OK != rst)
1301     {
1302         OIC_LOG_V(ERROR, TAG, "OCGetCSRResource API error: %d", rst);
1303         return -1;
1304     }
1305     if (waitCallbackRet())  // input |g_doneCB| flag implicitly
1306     {
1307         OIC_LOG(ERROR, TAG, "OCGetCSRResource callback error");
1308         return -1;
1309     }
1310     if (!g_successCB)
1311     {
1312         return -1;
1313     }
1314
1315     rst = OCVerifyCSRSignature(g_csr);
1316     if (OC_STACK_OK != rst)
1317     {
1318         OIC_LOG(ERROR, TAG, "Failed to validate CSR signature");
1319         OICFreeAndSetToNull((void**)&g_csr);
1320         return -1;
1321     }
1322
1323     printf("   > Creating a certificate for the device..\n");
1324     char* deviceCert;
1325     int ret = createIdentityCertFromCSR(g_caKeyPem, g_caCertPem, g_csr, &deviceCert);
1326     OICFreeAndSetToNull((void**)&g_csr);
1327     if (ret != 0)
1328     {
1329         OIC_LOG(ERROR, TAG, "Failed to generate certificate");
1330         OICFree(deviceCert);
1331         return -1;
1332     }
1333
1334     //Provision the new cert
1335     printf("   > Provisioning certificate credential to selected device..\n");
1336     g_doneCB = false;
1337     rst = OCProvisionCertificate((void *)g_ctx, targetDevice, deviceCert, provisionCredCB);
1338     if (OC_STACK_OK != rst)
1339     {
1340         OIC_LOG_V(ERROR, TAG, "OCProvisionCertificate returned error: %d", rst);
1341         OICFree(deviceCert);
1342         return -1;
1343     }
1344     if (waitCallbackRet())  // input |g_doneCB| flag implicitly
1345     {
1346         OIC_LOG(ERROR, TAG, "OCProvisionCertificate callback error");
1347         OICFree(deviceCert);
1348         return -1;
1349     }
1350     if (!g_successCB)
1351     {
1352         OICFree(deviceCert);
1353         return -1;
1354     }
1355
1356     printf("   > Provisioned certificate crendentials\n");
1357     OICFree(deviceCert);
1358
1359     return 0;
1360 }
1361
1362 static int provisionSecurityProfileInfo(void)
1363 {
1364     // make sure we own at least one device to provision
1365     if (!g_own_list || g_own_cnt == 0)
1366     {
1367         printf("   > Owned Device List, to Provision Security Profile Info, is Empty\n");
1368         printf("   > Please Register Unowned Devices first, with [20] Menu\n");
1369         return 0;  // normal case
1370     }
1371
1372     // select device for provisioning security profile
1373     int dev_num = 0;
1374     if (g_own_cnt == 1)
1375     {
1376         dev_num = 1;
1377     }
1378     else
1379     {
1380         for (; ; )
1381         {
1382             printf("   > Enter Device Number, for security profile provisioning: ");
1383             for (int ret = 0; 1 != ret; )
1384             {
1385                 ret = scanf("%d", &dev_num);
1386                 for (; 0x20 <= getchar(); );  // for removing overflow garbages
1387                                               // '0x20<=code' is character region
1388             }
1389             if (0<dev_num && g_own_cnt >= dev_num)
1390             {
1391                 break;
1392             }
1393             printf("     Entered Wrong Number. Please Enter Again\n");
1394         }
1395     }
1396
1397     OCProvisionDev_t* targetDevice = getDevInst((const OCProvisionDev_t*)g_own_list, dev_num);
1398     if (targetDevice == NULL)
1399     {
1400         OIC_LOG(ERROR, TAG, "Error, invalid device %d");
1401         return -1;
1402     }
1403
1404     int sp_selection = 0;
1405     for (; ; )
1406     {
1407         printf("   > Enter (1) for SP defaults, (2) for SP containing all profiles, (3) for an invalid SP: ");
1408         for (int ret = 0; 1 != ret; )
1409         {
1410             ret = scanf("%d", &sp_selection);
1411             for (; 0x20 <= getchar(); );  // for removing overflow garbages
1412                                           // '0x20<=code' is character region
1413         }
1414         if ((1 <= sp_selection) && (3 >= sp_selection))
1415         {
1416             break;
1417         }
1418         printf("     Entered Wrong Number. Please Enter Again\n");
1419     }
1420
1421     printf("   > Posting new security profile info to device ...\n");
1422     g_doneCB = false;
1423
1424     OicSecSp_t *sp = NULL;
1425     switch (sp_selection) {
1426         case 2 : sp = &gSpAll; break;
1427         case 3 : sp = &gSpInvalid; break;
1428         default: sp = &gSpDefault;
1429     }
1430
1431     OCStackResult rst = OCProvisionSecurityProfileInfo(
1432         (void*)g_ctx, sp, targetDevice, (OCProvisionResultCB)&provisionTrustChainCB);
1433     if (OC_STACK_OK != rst)
1434     {
1435         OIC_LOG_V(ERROR, TAG, "provisionSecurityProfileInfo returned error: %d", rst);
1436         return -1;
1437     }
1438
1439     if (waitCallbackRet())  // input |g_doneCB| flag implicitly
1440     {
1441         OIC_LOG(ERROR, TAG, "provisionSecurityProfileInfo callback error");
1442         return -1;
1443     }
1444     if (!g_successCB)
1445     {
1446         return -1;
1447     }
1448
1449     printf("   > Provisioned security profile info\n");
1450
1451     return 0;
1452 }
1453
1454 #ifdef WITH_CLOUD
1455 static int provisionCloudConfig(void)
1456 {
1457     // make sure we own at least one device to provision
1458     if (!g_own_list || g_own_cnt == 0)
1459     {
1460         printf("   > Owned Device List, to Provision Credentials, is Empty\n");
1461         printf("   > Please Register Unowned Devices first, with [20] Menu\n");
1462         return 0;  // normal case
1463     }
1464     int ret = -1;
1465     // select device for provisioning certificate
1466     int dev_num = 0;
1467     if (g_own_cnt == 1)
1468     {
1469         dev_num = 1;
1470     }
1471     else
1472     {
1473         for (; ; )
1474         {
1475             printf("   > Enter Device Number, for certificate provisioning: ");
1476             for (int ret = 0; 1 != ret; )
1477             {
1478                 ret = scanf("%d", &dev_num);
1479                 for (; 0x20 <= getchar(); );  // for removing overflow garbages
1480                                           // '0x20<=code' is character region
1481             }
1482             if (0<dev_num && g_own_cnt >= dev_num)
1483             {
1484                 break;
1485             }
1486             printf("     Entered Wrong Number. Please Enter Again\n");
1487         }
1488     }
1489
1490     OCProvisionDev_t* targetDevice = getDevInst((const OCProvisionDev_t*)g_own_list, dev_num);
1491     if (targetDevice == NULL)
1492     {
1493         OIC_LOG(ERROR, TAG, "Error, invalid device %d");
1494         return -1;
1495     }
1496
1497     // Install the CA trust anchor
1498     FILE *F;
1499     F = fopen("rootca.crt", "rb");
1500     fseek (F , 0 , SEEK_END);
1501     int certsize = ftell (F);
1502     rewind (F);
1503     uint8_t* cert = (uint8_t*) malloc (sizeof(char)*certsize);
1504     int res = fread (cert, 1, certsize, F);
1505     /* Set our own trust anchor so that we trust certs we've issued. */
1506     res = OCSaveTrustCertChain((uint8_t*) cert, certsize, OIC_ENCODING_PEM, &g_caCredId);
1507     if (OC_STACK_OK != res)
1508     {
1509         printf("     Failed to setup CA\n");
1510         return -1;
1511     }
1512
1513     // Provision the CA root cert to the target device
1514     printf("   > Saving root certificate (trust anchor) to selected device..\n");
1515     g_doneCB = false;
1516     OicSecCredType_t type = SIGNED_ASYMMETRIC_KEY;
1517
1518     OCStackResult rst = OCProvisionTrustCertChain((void*)g_ctx, type, g_caCredId, targetDevice, (OCProvisionResultCB)&provisionTrustChainCB);
1519     if (OC_STACK_OK != rst)
1520     {
1521         OIC_LOG_V(ERROR, TAG, "OCProvisionTrustCertChain returned error: %d", rst);
1522         return -1;
1523     }
1524
1525     if (waitCallbackRet())  // input |g_doneCB| flag implicitly
1526     {
1527         OIC_LOG(ERROR, TAG, "OCProvisionTrustCertChain callback error");
1528         return -1;
1529     }
1530     if (!g_successCB)
1531     {
1532         return -1;
1533     }
1534
1535     OicCloud_t *cloud = OICCalloc(1, sizeof(OicCloud_t));
1536     if (NULL == cloud)
1537     {
1538         OIC_LOG(ERROR, TAG, "Error, invalid cloud");
1539         return -1;
1540     }
1541     cloud->apn = (char*)OICCalloc(1, 1024);
1542     if (NULL == cloud->apn)
1543     {
1544         OIC_LOG(ERROR, TAG, "Error, invalid cloud->apn");
1545         goto PCC_ERROR;
1546     }
1547     cloud->cis = (char*)OICCalloc(1, 1024);
1548     if (NULL == cloud->cis)
1549     {
1550         OIC_LOG(ERROR, TAG, "Error, invalid cloud->cis");
1551         goto PCC_ERROR;
1552     }
1553     cloud->at = (char*)OICCalloc(1, 1024);
1554     if (NULL == cloud->at)
1555     {
1556         OIC_LOG(ERROR, TAG, "Error, invalid cloud->at");
1557         goto PCC_ERROR;
1558     }
1559     cloud->sid = (char*)OICCalloc(1, 1024);
1560     if (NULL == cloud->sid)
1561     {
1562         OIC_LOG(ERROR, TAG, "Error, invalid cloud->sid");
1563         goto PCC_ERROR;
1564     }
1565
1566     snprintf(cloud->cis,13,"coaps+tcp://");
1567
1568     printf("   > cloud uri (host(ip):port): ");
1569     for(int ret=0; 1!=ret; )
1570     {
1571         ret = scanf("%32s", cloud->cis + 12);
1572         for( ; 0x20<=getchar(); );  // for removing overflow garbages
1573                                     // '0x20<=code' is character region
1574     }
1575
1576     printf("   > oauth provider: ");
1577     for(int ret=0; 1!=ret; )
1578     {
1579         ret = scanf("%32s", cloud->apn);
1580         for( ; 0x20<=getchar(); );  // for removing overflow garbages
1581                                     // '0x20<=code' is character region
1582     }
1583
1584     printf("   > access token: ");
1585     for(int ret=0; 1!=ret; )
1586     {
1587         ret = scanf("%32s", cloud->at);
1588         for( ; 0x20<=getchar(); );  // for removing overflow garbages
1589                                     // '0x20<=code' is character region
1590     }
1591
1592     printf("   > cloud id: ");
1593     for(int ret=0; 1!=ret; )
1594     {
1595         ret = scanf("%32s", cloud->sid);
1596         for( ; 0x20<=getchar(); );  // for removing overflow garbages
1597                                     // '0x20<=code' is character region
1598     }
1599
1600     //Provision the new cert
1601     printf("   > Provisioning certificate credential to selected device..\n");
1602     g_doneCB = false;
1603     rst = OCProvisionCloudConfig((void*)g_ctx, targetDevice, cloud, (OCClientResponseHandler)provisionCloudConfigCB);
1604     if (OC_STACK_OK != rst)
1605     {
1606         OIC_LOG_V(ERROR, TAG, "OCProvisionCertificate returned error: %d", rst);
1607         goto PCC_ERROR;
1608     }
1609     if (waitCallbackRet())  // input |g_doneCB| flag implicitly
1610     {
1611         OIC_LOG(ERROR, TAG, "OCProvisionCertificate callback error");
1612         goto PCC_ERROR;
1613     }
1614     if (!g_successCB)
1615     {
1616         goto PCC_ERROR;
1617     }
1618
1619     printf("   > Provisioned cloud crendentials\n");
1620
1621     ret = 0;
1622
1623 PCC_ERROR:
1624     FreeCloud(cloud);
1625     return ret;
1626 }
1627
1628 static int getCloudStatus(void)
1629 {
1630     int ret = -1;
1631     // make sure we own at least one device to provision
1632     if (!g_own_list || g_own_cnt == 0)
1633     {
1634         printf("   > Owned Device List, to Provision Credentials, is Empty\n");
1635         printf("   > Please Register Unowned Devices first, with [20] Menu\n");
1636         return 0;  // normal case
1637     }
1638
1639     // select device for cloud state request
1640     int dev_num = 0;
1641     if (g_own_cnt == 1)
1642     {
1643         dev_num = 1;
1644     }
1645     else
1646     {
1647         for (; ; )
1648         {
1649             printf("   > Enter Device Number, for cloud state request: ");
1650             for (int ret = 0; 1 != ret; )
1651             {
1652                 ret = scanf("%d", &dev_num);
1653                 for (; 0x20 <= getchar(); );  // for removing overflow garbages
1654                                           // '0x20<=code' is character region
1655             }
1656             if (0<dev_num && g_own_cnt >= dev_num)
1657             {
1658                 break;
1659             }
1660             printf("     Entered Wrong Number. Please Enter Again\n");
1661         }
1662     }
1663
1664     OCProvisionDev_t* targetDevice = getDevInst((const OCProvisionDev_t*)g_own_list, dev_num);
1665     if (targetDevice == NULL)
1666     {
1667         OIC_LOG(ERROR, TAG, "Error, invalid device %d");
1668         return -1;
1669     }
1670
1671     OicCloud_t *cloud = OICCalloc(1,sizeof(OicCloud_t));
1672     cloud->cis = OICCalloc(1,1024);
1673
1674     snprintf(cloud->cis,13,"coaps+tcp://");
1675
1676     printf("   > cloud uri (host(ip):port): ");
1677     for(int ret=0; 1!=ret; )
1678     {
1679         ret = scanf("%32s", cloud->cis + 12);
1680         for( ; 0x20<=getchar(); );  // for removing overflow garbages
1681                                     // '0x20<=code' is character region
1682     }
1683
1684     //Provision the new cert
1685     printf("   > Provisioning certificate credential to selected device..\n");
1686     g_doneCB = false;
1687     OCStackResult rst = OCGetCloudStatusRequest((void*)g_ctx, targetDevice, cloud, (OCClientResponseHandler)getCloudStatusCB);
1688     if (OC_STACK_OK != rst)
1689     {
1690         OIC_LOG_V(ERROR, TAG, "OCProvisionCertificate returned error: %d", rst);
1691         goto exit;
1692     }
1693     if (waitCallbackRet())  // input |g_doneCB| flag implicitly
1694     {
1695         OIC_LOG(ERROR, TAG, "OCProvisionCertificate callback error");
1696         goto exit;
1697     }
1698     if (!g_successCB)
1699     {
1700         ret = -1;
1701         goto exit;
1702     }
1703     ret = 0;
1704 exit:
1705     FreeCloud(cloud);
1706
1707     printf("   > Provisioned cloud crendentials\n");
1708
1709     return ret;
1710 }
1711
1712 static int removeCloudConf(void)
1713 {
1714     // make sure we own at least one device to provision
1715     if (!g_own_list || g_own_cnt == 0)
1716     {
1717         printf("   > Owned Device List, to Provision Credentials, is Empty\n");
1718         printf("   > Please Register Unowned Devices first, with [20] Menu\n");
1719         return 0;  // normal case
1720     }
1721
1722     int res = -1;
1723
1724     // select device for provisioning certificate
1725     int dev_num = 0;
1726     if (g_own_cnt == 1)
1727     {
1728         dev_num = 1;
1729     }
1730     else
1731     {
1732         for (; ; )
1733         {
1734             printf("   > Enter Device Number, for certificate provisioning: ");
1735             for (int ret = 0; 1 != ret; )
1736             {
1737                 ret = scanf("%d", &dev_num);
1738                 for (; 0x20 <= getchar(); );  // for removing overflow garbages
1739                                           // '0x20<=code' is character region
1740             }
1741             if (0<dev_num && g_own_cnt >= dev_num)
1742             {
1743                 break;
1744             }
1745             printf("     Entered Wrong Number. Please Enter Again\n");
1746         }
1747     }
1748
1749     OCProvisionDev_t* targetDevice = getDevInst((const OCProvisionDev_t*)g_own_list, dev_num);
1750     if (targetDevice == NULL)
1751     {
1752         OIC_LOG(ERROR, TAG, "Error, invalid device %d");
1753         return res;
1754     }
1755
1756     OicCloud_t *cloud = OICCalloc(1, sizeof(OicCloud_t));
1757     if (NULL == cloud)
1758     {
1759         OIC_LOG(ERROR, TAG, "Error, invalid cloud");
1760         return res;
1761     }
1762     cloud->sid = (char*)OICCalloc(1, 1024);
1763     if (NULL == cloud->sid)
1764     {
1765         OIC_LOG(ERROR, TAG, "Error, invalid cloud->sid");
1766         goto PCC_ERROR;
1767     }
1768     printf("   > cloud id: ");
1769     for(int ret=0; 1!=ret; )
1770     {
1771         ret = scanf("%64s", cloud->sid);
1772         for( ; 0x20<=getchar(); );  // for removing overflow garbages
1773                                     // '0x20<=code' is character region
1774     }
1775
1776     printf("   > Removing cloud related acl and coapcloudconf resource from the selected device..\n");
1777     g_doneCB = false;
1778     OCStackResult rst = OCRemoveCloudConfig((void*)g_ctx, targetDevice, cloud, removeCloudConfCB);
1779     if (OC_STACK_OK != rst)
1780     {
1781         OIC_LOG_V(ERROR, TAG, "OCRemoveCloudConfig returned error: %d", rst);
1782         goto PCC_ERROR;
1783     }
1784     if (waitCallbackRet())  // input |g_doneCB| flag implicitly
1785     {
1786         OIC_LOG(ERROR, TAG, "OCRemoveCloudConfig callback error");
1787         goto PCC_ERROR;
1788     }
1789     if (!g_successCB)
1790     {
1791         goto PCC_ERROR;
1792     }
1793
1794     printf("   > Removed coapcloudconf and cloud acl\n");
1795
1796     res = 0;
1797
1798 PCC_ERROR:
1799     FreeCloud(cloud);
1800     return res;
1801 }
1802 #endif //WITH_CLOUD
1803
1804 static int provisionAcl(void)
1805 {
1806     // check |own_list| for provisioning access control list
1807     if(!g_own_list || 1>g_own_cnt)
1808     {
1809         printf("   > Owned Device List, to Provision ACL, is Empty\n");
1810         printf("   > Please Register Unowned Devices first, with [20] Menu\n");
1811         return 0;  // normal case
1812     }
1813
1814     // select device for provisioning access control list
1815     int dev_num = 0;
1816     for( ; ; )
1817     {
1818         printf("   > Enter Device Number, for Provisioning ACL: ");
1819         for(int ret=0; 1!=ret; )
1820         {
1821             ret = scanf("%d", &dev_num);
1822             for( ; 0x20<=getchar(); );  // for removing overflow garbages
1823                                         // '0x20<=code' is character region
1824         }
1825         if(0<dev_num && g_own_cnt>=dev_num)
1826         {
1827             break;
1828         }
1829         printf("     Entered Wrong Number. Please Enter Again\n");
1830     }
1831
1832     // create ACL for selected device
1833     OicSecAcl_t* acl = NULL;
1834     acl = createAcl(dev_num);
1835     if(!acl)
1836     {
1837         OIC_LOG(ERROR, TAG, "createAcl error return");
1838         goto PVACL_ERROR;
1839     }
1840
1841     // call |OCProvisionACL| API
1842     // calling this API with callback actually acts like blocking
1843     // for error checking, the return value saved and printed
1844     g_doneCB = false;
1845     printf("   Provisioning Selected ACL..\n");
1846     OCProvisionDev_t* dev = getDevInst((const OCProvisionDev_t*) g_own_list, dev_num);
1847     if(!dev)
1848     {
1849         OIC_LOG(ERROR, TAG, "provisionAcl: device instance empty");
1850         goto PVACL_ERROR;
1851     }
1852     OCStackResult rst = OCProvisionACL((void*) g_ctx, dev, acl, provisionAclCB);
1853     if(OC_STACK_OK != rst)
1854     {
1855         OIC_LOG_V(ERROR, TAG, "OCProvisionACL API error: %d", rst);
1856         goto PVACL_ERROR;
1857     }
1858     if(waitCallbackRet())  // input |g_doneCB| flag implicitly
1859     {
1860         OIC_LOG(ERROR, TAG, "OCProvisionACL callback error");
1861         goto PVACL_ERROR;
1862     }
1863     OCDeleteACLList(acl);  // after here |acl| points nothing
1864
1865     // display the ACL-provisioned result
1866     printf("   > Provisioned Selected ACL\n");
1867
1868     return 0;
1869
1870 PVACL_ERROR:
1871     OCDeleteACLList(acl);  // after here |acl| points nothing
1872     return -1;
1873 }
1874
1875 static int checkLinkedStatus(void)
1876 {
1877     // check |own_list| for checking selected link status on PRVN DB
1878     if(!g_own_list || 1>g_own_cnt)
1879     {
1880         printf("   > Owned Device List, to Check Linked Status on PRVN DB, is Empty\n");
1881         printf("   > Please Register Unowned Devices first, with [20] Menu\n");
1882         return 0;  // normal case
1883     }
1884
1885     // select device for checking selected link status on PRVN DB
1886     int dev_num = 0;
1887     for( ; ; )
1888     {
1889         printf("   > Enter Device Number, for Checking Linked Status on PRVN DB: ");
1890         for(int ret=0; 1!=ret; )
1891         {
1892             ret = scanf("%d", &dev_num);
1893             for( ; 0x20<=getchar(); );  // for removing overflow garbages
1894                                         // '0x20<=code' is character region
1895         }
1896         if(0<dev_num && g_own_cnt>=dev_num)
1897         {
1898             break;
1899         }
1900         printf("     Entered Wrong Number. Please Enter Again\n");
1901     }
1902
1903     // call |OCGetLinkedStatus| API
1904     printf("   Checking Selected Link Status on PRVN DB..\n");
1905     OCUuidList_t* dvid_lst = NULL;
1906     size_t dvid_cnt = 0;
1907     OCProvisionDev_t* dev = getDevInst((const OCProvisionDev_t*)g_own_list, dev_num);
1908     if(!dev || !dev->doxm)
1909     {
1910         OIC_LOG(ERROR, TAG, "checkLinkedStatus: device instance empty");
1911         goto CKLST_ERROR;
1912     }
1913
1914     if(OC_STACK_OK !=
1915             OCGetLinkedStatus(
1916                     &dev->doxm->deviceID,
1917                     &dvid_lst, &dvid_cnt))  // allow empty list
1918     {
1919         OIC_LOG(ERROR, TAG, "OCGetLinkedStatus API error");
1920         goto CKLST_ERROR;
1921     }
1922
1923     // display the linked status result
1924     printf("   > Checked Selected Link Status on PRVN DB\n");
1925     if(!dvid_lst || !dvid_cnt)  // |size_t| is unsigned
1926     {
1927         printf("     Linked Device List is Empty..\n");
1928         return 0;  // normal case
1929     }
1930     if(dvid_cnt != printUuidList((const OCUuidList_t*) dvid_lst))
1931     {
1932         OIC_LOG(ERROR, TAG, "printUuidList error return");
1933         goto CKLST_ERROR;
1934     }
1935     OCDeleteUuidList(dvid_lst);
1936
1937     return 0;
1938
1939 CKLST_ERROR:
1940     OCDeleteUuidList(dvid_lst);
1941     return -1;
1942 }
1943
1944 static int saveAcl(void)
1945 {
1946     // create ACL to save into local SVR DB
1947     OicSecAcl_t* acl = NULL;
1948     OicUuid_t uuid =   {.id={0}};
1949     char strUuid[64] = {0};
1950
1951     printf("[1] Use a test UUID [11111111-2222-3333-4444-555555555555]\n");
1952     printf("[2] Use a user input\n");
1953     int sel_num = 0;
1954     for( ; ; )
1955     {
1956         printf("   > Select Number, for Subject UUID of new ACE: ");
1957         for(int ret=0; 1!=ret; )
1958         {
1959             ret = scanf("%d", &sel_num);
1960             for( ; 0x20<=getchar(); );  // for removing overflow garbages
1961                                         // '0x20<=code' is character region
1962         }
1963         if(1 == sel_num)
1964         {
1965             OICStrcpy(strUuid, sizeof(strUuid), "11111111-2222-3333-4444-555555555555");
1966             break;
1967         }
1968         else if(2 == sel_num)
1969         {
1970             printf("   > Input the UUID : ");
1971             for(int ret=0; 1!=ret; )
1972             {
1973                 ret = scanf("%64s", strUuid);
1974                 for( ; 0x20<=getchar(); );  // for removing overflow garbages
1975                                         // '0x20<=code' is character region
1976             }
1977             break;
1978         }
1979         printf("     Entered Wrong Number. Please Enter Again\n");
1980     }
1981
1982
1983     printf("Selected Subject UUID : %s\n", strUuid);
1984     OCStackResult rst = ConvertStrToUuid(strUuid, &uuid);
1985     if(OC_STACK_OK != rst)
1986     {
1987         OIC_LOG_V(ERROR, TAG, "ConvertStrToUuid API error: %d", rst);
1988         goto SVACL_ERROR;
1989     }
1990
1991     acl = createSimpleAcl(uuid);
1992     if(!acl)
1993     {
1994         OIC_LOG(ERROR, TAG, "createAcl error return");
1995         goto SVACL_ERROR;
1996     }
1997
1998     // call |OCSaveACL| API
1999     rst = OCSaveACL(acl);
2000     if(OC_STACK_OK != rst)
2001     {
2002         OIC_LOG_V(ERROR, TAG, "OCSaveACL API error: %d", rst);
2003         goto SVACL_ERROR;
2004     }
2005     OCDeleteACLList(acl);  // after here |acl| points nothing
2006
2007     // display the ACL-provisioned result
2008     printf("   > Saved Selected ACL\n");
2009
2010     return 0;
2011
2012 SVACL_ERROR:
2013     OCDeleteACLList(acl);  // after here |acl| points nothing
2014     return -1;
2015 }
2016
2017 static int getCred(void)
2018 {
2019     // check |own_list| for checking selected link status on PRVN DB
2020     if(!g_own_list || 1>g_own_cnt)
2021     {
2022         printf("   > Owned Device List, to Check Linked Status on PRVN DB, is Empty\n");
2023         printf("   > Please Register Unowned Devices first, with [20] Menu\n");
2024         return 0;  // normal case
2025     }
2026
2027     // select device for checking selected link status on PRVN DB
2028     int dev_num = 0;
2029     for( ; ; )
2030     {
2031         printf("   > Enter Device Number, for Checking Linked Status on PRVN DB: ");
2032         for(int ret=0; 1!=ret; )
2033         {
2034             ret = scanf("%d", &dev_num);
2035             for( ; 0x20<=getchar(); );  // for removing overflow garbages
2036                                         // '0x20<=code' is character region
2037         }
2038         if(0<dev_num && g_own_cnt>=dev_num)
2039         {
2040             break;
2041         }
2042         printf("     Entered Wrong Number. Please Enter Again\n");
2043     }
2044
2045     // call |getDevInst| API
2046     // calling this API with callback actually acts like blocking
2047     // for error checking, the return value saved and printed
2048     g_doneCB = false;
2049     OCProvisionDev_t* dev = getDevInst((const OCProvisionDev_t*) g_own_list, dev_num);
2050     if(!dev)
2051     {
2052         OIC_LOG(ERROR, TAG, "getDevInst: device instance empty");
2053         goto PVACL_ERROR;
2054     }
2055     OCStackResult rst = OCGetCredResource((void*) g_ctx, dev, getCredCB);
2056     if(OC_STACK_OK != rst)
2057     {
2058         OIC_LOG_V(ERROR, TAG, "OCGetCred API error: %d", rst);
2059         goto PVACL_ERROR;
2060     }
2061     if(waitCallbackRet())  // input |g_doneCB| flag implicitly
2062     {
2063         OIC_LOG(ERROR, TAG, "OCGetCredResource callback error");
2064         goto PVACL_ERROR;
2065     }
2066
2067     // display the result of get credential
2068     printf("   > Get Cred SUCCEEDED\n");
2069
2070     return 0;
2071
2072 PVACL_ERROR:
2073     return -1;
2074 }
2075
2076 static int getAcl(void)
2077 {
2078     // check |own_list| for checking selected link status on PRVN DB
2079     if(!g_own_list || 1>g_own_cnt)
2080     {
2081         printf("   > Owned Device List, to Check Linked Status on PRVN DB, is Empty\n");
2082         printf("   > Please Register Unowned Devices first, with [20] Menu\n");
2083         return 0;  // normal case
2084     }
2085
2086     // select device for checking selected link status on PRVN DB
2087     int dev_num = 0;
2088     for( ; ; )
2089     {
2090         printf("   > Enter Device Number, for Checking Linked Status on PRVN DB: ");
2091         for(int ret=0; 1!=ret; )
2092         {
2093             ret = scanf("%d", &dev_num);
2094             for( ; 0x20<=getchar(); );  // for removing overflow garbages
2095                                         // '0x20<=code' is character region
2096         }
2097         if(0<dev_num && g_own_cnt>=dev_num)
2098         {
2099             break;
2100         }
2101         printf("     Entered Wrong Number. Please Enter Again\n");
2102     }
2103
2104     // call |getDevInst| API
2105     // calling this API with callback actually acts like blocking
2106     // for error checking, the return value saved and printed
2107     g_doneCB = false;
2108     OCProvisionDev_t* dev = getDevInst((const OCProvisionDev_t*) g_own_list, dev_num);
2109     if(!dev)
2110     {
2111         OIC_LOG(ERROR, TAG, "getDevInst: device instance empty");
2112         goto PVACL_ERROR;
2113     }
2114     // IOT-2219 add support for OIC 1.1 /oic/sec/acl URI
2115     OCStackResult rst = OCGetACL2Resource((void*) g_ctx, dev, getAclCB);
2116     if(OC_STACK_OK != rst)
2117     {
2118         OIC_LOG_V(ERROR, TAG, "OCGetACL2Resource API error: %d", rst);
2119
2120         goto PVACL_ERROR;
2121     }
2122     if(waitCallbackRet())  // input |g_doneCB| flag implicitly
2123     {
2124         OIC_LOG(ERROR, TAG, "OCGetACL2Resource callback error");
2125         goto PVACL_ERROR;
2126     }
2127
2128     // display the result of get credential
2129     printf("   > Get ACL SUCCEEDED\n");
2130
2131     return 0;
2132
2133 PVACL_ERROR:
2134     return -1;
2135 }
2136
2137 static int getCsr(void)
2138 {
2139     // check |own_list| for retrieving CSR
2140     if(!g_own_list || 1>g_own_cnt)
2141     {
2142         printf("   > Owned Device List, to retrieve CSR, is Empty\n");
2143         printf("   > Please Register Unowned Devices first, with [20] Menu\n");
2144         return 0;  // normal case
2145     }
2146
2147     // select device for retrieving CSR
2148     int dev_num = 0;
2149     for( ; ; )
2150     {
2151         printf("   > Enter Device Number, for retrieving CSR: ");
2152         for(int ret=0; 1!=ret; )
2153         {
2154             ret = scanf("%d", &dev_num);
2155             for( ; 0x20<=getchar(); );  // for removing overflow garbages
2156                                         // '0x20<=code' is character region
2157         }
2158         if(0<dev_num && g_own_cnt>=dev_num)
2159         {
2160             break;
2161         }
2162         printf("     Entered Wrong Number. Please Enter Again\n");
2163     }
2164
2165     // call |getDevInst| API
2166     // calling this API with callback actually acts like blocking
2167     // for error checking, the return value saved and printed
2168     g_doneCB = false;
2169     OCProvisionDev_t* dev = getDevInst((const OCProvisionDev_t*) g_own_list, dev_num);
2170     if(!dev)
2171     {
2172         OIC_LOG(ERROR, TAG, "getDevInst: device instance empty");
2173         goto GETCSR_ERROR;
2174     }
2175     OCStackResult rst = OCGetCSRResource((void*) g_ctx, dev, getCsrCB);
2176     if(OC_STACK_OK != rst)
2177     {
2178         OIC_LOG_V(ERROR, TAG, "OCGetCSRResource API error: %d", rst);
2179
2180         goto GETCSR_ERROR;
2181     }
2182     if(waitCallbackRet())  // input |g_doneCB| flag implicitly
2183     {
2184         OIC_LOG(ERROR, TAG, "OCGetCSRResource callback error");
2185         goto GETCSR_ERROR;
2186     }
2187
2188     // display the result of get credential
2189     printf("   > Get CSR SUCCEEDED\n");
2190
2191     return 0;
2192
2193 GETCSR_ERROR:
2194     return -1;
2195 }
2196
2197 static int getSp(void)
2198 {
2199     // check |own_list| for retrieving SP
2200     if(!g_own_list || 1>g_own_cnt)
2201     {
2202         printf("   > Owned Device List, to retrieve SP, is Empty\n");
2203         printf("   > Please Register Unowned Devices first, with [20] Menu\n");
2204         return 0;  // normal case
2205     }
2206
2207     // select device for retrieving SP
2208     int dev_num = 0;
2209     for( ; ; )
2210     {
2211         printf("   > Enter Device Number, for retrieving SP: ");
2212         for(int ret=0; 1!=ret; )
2213         {
2214             ret = scanf("%d", &dev_num);
2215             for( ; 0x20<=getchar(); );  // for removing overflow garbages
2216                                         // '0x20<=code' is character region
2217         }
2218         if(0<dev_num && g_own_cnt>=dev_num)
2219         {
2220             break;
2221         }
2222         printf("     Entered Wrong Number. Please Enter Again\n");
2223     }
2224
2225     // call |getDevInst| API
2226     // calling this API with callback actually acts like blocking
2227     // for error checking, the return value saved and printed
2228     g_doneCB = false;
2229     OCProvisionDev_t* dev = getDevInst((const OCProvisionDev_t*) g_own_list, dev_num);
2230     if(!dev)
2231     {
2232         OIC_LOG(ERROR, TAG, "getDevInst: device instance empty");
2233         goto GETSP_ERROR;
2234     }
2235     OCStackResult rst = OCGetSpResource((void*) g_ctx, dev, getSpCB);
2236     if(OC_STACK_OK != rst)
2237     {
2238         OIC_LOG_V(ERROR, TAG, "OCGetSpResource API error: %d", rst);
2239
2240         goto GETSP_ERROR;
2241     }
2242
2243     if(waitCallbackRet())  // input |g_doneCB| flag implicitly
2244     {
2245         OIC_LOG(ERROR, TAG, "OCGetSpResource callback error");
2246         goto GETSP_ERROR;
2247     }
2248
2249     // display the result of get credential
2250     printf("   > Get SP SUCCEEDED\n");
2251
2252     return 0;
2253
2254 GETSP_ERROR:
2255     return -1;
2256 }
2257
2258 static int unlinkPairwise(void)
2259 {
2260     // check |own_list| for unlinking pairwise devices
2261     if(!g_own_list || 2>g_own_cnt)
2262     {
2263         printf("   > Owned Device List, to Unlink the Pairwise, is Empty\n");
2264         printf("   > Please Register Unowned Devices first, with [20] Menu\n");
2265         return 0;  // normal case
2266     }
2267
2268     // select two devices for unlinking pairwise devices
2269     int dev_num[2] = {0};
2270     if(selectTwoDiffNum(&(dev_num[0]), &(dev_num[1]), g_own_cnt, "for Unlinking Devices"))
2271     {
2272         OIC_LOG(ERROR, TAG, "selectTwoDiffNum error return");
2273         return -1;
2274     }
2275
2276     // call |OCUnlinkDevices| API
2277     // calling this API with callback actually acts like blocking
2278     // for error checking, the return value saved and printed
2279     g_doneCB = false;
2280     printf("   Unlinking Selected Pairwise Devices..\n");
2281     OCStackResult rst =
2282             OCUnlinkDevices((void*) g_ctx,
2283                     getDevInst((const OCProvisionDev_t*) g_own_list, dev_num[0]),
2284                     getDevInst((const OCProvisionDev_t*) g_own_list, dev_num[1]),
2285                     unlinkDevicesCB);
2286     if(OC_STACK_OK != rst)
2287     {
2288         OIC_LOG_V(ERROR, TAG, "OCUnlinkDevices API error: %d", rst);
2289         return -1;
2290     }
2291     if(waitCallbackRet())  // input |g_doneCB| flag implicitly
2292     {
2293         OIC_LOG(ERROR, TAG, "OCUnlinkDevices callback error");
2294         return -1;
2295     }
2296
2297     // display the pairwise-unlinked result
2298     printf("   > Unlinked Selected Pairwise Devices\n");
2299     printf("   > Please Check Device's Status for the Unlinked Result, with [33] Menu\n");
2300
2301     return 0;
2302 }
2303
2304 static int removeDevice(void)
2305 {
2306     // check |own_list| for removing device
2307     if(!g_own_list || 1>g_own_cnt)
2308     {
2309         printf("   > Owned Device List, to Remove Device, is Empty\n");
2310         printf("   > Please Register Unowned Devices first, with [20] Menu\n");
2311         return 0;  // normal case
2312     }
2313
2314     // select device for removing it
2315     int dev_num = 0;
2316     for( ; ; )
2317     {
2318         printf("   > Enter Device Number, for Removing Device: ");
2319         for(int ret=0; 1!=ret; )
2320         {
2321             ret = scanf("%d", &dev_num);
2322             for( ; 0x20<=getchar(); );  // for removing overflow garbages
2323                                         // '0x20<=code' is character region
2324         }
2325         if(0<dev_num && g_own_cnt>=dev_num)
2326         {
2327             break;
2328         }
2329         printf("     Entered Wrong Number. Please Enter Again\n");
2330     }
2331
2332     // call |OCRemoveDevice| API
2333     // calling this API with callback actually acts like blocking
2334     // for error checking, the return value saved and printed
2335     g_doneCB = false;
2336     printf("   Removing Selected Owned Device..\n");
2337     OCStackResult rst =
2338             OCRemoveDevice((void*) g_ctx, DISCOVERY_TIMEOUT,
2339                     getDevInst((const OCProvisionDev_t*) g_own_list, dev_num), removeDeviceCB);
2340     if(OC_STACK_OK != rst)
2341     {
2342         OIC_LOG_V(ERROR, TAG, "OCRemoveDevice API error: %d", rst);
2343         return -1;
2344     }
2345     if(waitCallbackRet())  // input |g_doneCB| flag implicitly
2346     {
2347         OIC_LOG(ERROR, TAG, "OCRemoveDevice callback error");
2348         return -1;
2349     }
2350
2351     // display the removed result
2352     printf("   > Removed Selected Owned Device\n");
2353     printf("   > Please Discover Owned Devices for the Registered Result, with [10|12] Menu\n");
2354
2355     return 0;
2356 }
2357
2358 static int removeDeviceWithUuid(void)
2359 {
2360     char strUuid[64] = {0};
2361     OicUuid_t revUuid;
2362     printf("Input the UUID : ");
2363     for(int ret=0; 1!=ret; )
2364     {
2365         ret = scanf("%63s", strUuid);
2366         for( ; 0x20<=getchar(); );  // for removing overflow garbages
2367                                     // '0x20<=code' is character region
2368     }
2369     OCStackResult rst = ConvertStrToUuid(strUuid, &revUuid);
2370     if(OC_STACK_OK != rst)
2371     {
2372         OIC_LOG_V(ERROR, TAG, "ConvertStrToUuid API error: %d", rst);
2373         return -1;
2374     }
2375
2376     g_doneCB = false;
2377     rst = OCRemoveDeviceWithUuid("RemoveDeviceWithUUID", DISCOVERY_TIMEOUT, &revUuid, removeDeviceCB);
2378     if(OC_STACK_OK != rst)
2379     {
2380         OIC_LOG_V(ERROR, TAG, "OCRemoveDeviceWithUuid API error: %d", rst);
2381         return -1;
2382     }
2383
2384     if(waitCallbackRet())  // input |g_doneCB| flag implicitly
2385     {
2386         OIC_LOG(ERROR, TAG, "OCRemoveDeviceWithUuid callback error");
2387         return -1;
2388     }
2389
2390     // display the removed result
2391     printf("   > Removed %s Device\n", strUuid);
2392     printf("   > Please Discover Owned Devices for the Registered Result, with [10|12] Menu\n");
2393
2394     return 0;
2395 }
2396
2397 OCStackResult OC_CALL displayNumCB(void * ctx, uint8_t mutualVerifNum[MUTUAL_VERIF_NUM_LEN])
2398 {
2399     OC_UNUSED(ctx);
2400
2401     OIC_LOG(INFO, TAG, "IN displayMutualVerifNumCB");
2402     if (NULL != mutualVerifNum)
2403     {
2404         OIC_LOG(INFO, TAG, "############ mutualVerifNum ############");
2405         OIC_LOG_BUFFER(INFO, TAG, mutualVerifNum, MUTUAL_VERIF_NUM_LEN);
2406         OIC_LOG(INFO, TAG, "############ mutualVerifNum ############");
2407         OIC_LOG(INFO, TAG, "OUT displayMutualVerifNumCB");
2408     }
2409     else
2410     {
2411         OIC_LOG(INFO, TAG, "############ Confirm on the Server side ############");
2412     }
2413     return OC_STACK_OK;
2414 }
2415
2416 OCStackResult OC_CALL confirmNumCB(void * ctx)
2417 {
2418     OC_UNUSED(ctx);
2419
2420     for (;;)
2421     {
2422         int userConfirm;
2423
2424         printf("   > Press 1 if the mutual verification numbers are the same\n");
2425         printf("   > Press 0 if the mutual verification numbers are not the same\n");
2426
2427         for (int ret=0; 1!=ret; )
2428         {
2429             ret = scanf("%d", &userConfirm);
2430             for (; 0x20<=getchar(); );  // for removing overflow garbage
2431                                         // '0x20<=code' is character region
2432         }
2433         if (1 == userConfirm)
2434         {
2435             break;
2436         }
2437         else if (0 == userConfirm)
2438         {
2439             return OC_STACK_USER_DENIED_REQ;
2440         }
2441         printf("   Entered Wrong Number. Please Enter Again\n");
2442     }
2443     return OC_STACK_OK;
2444 }
2445
2446 #ifdef MULTIPLE_OWNER
2447 static int changeMultipleOwnershipTrnasferMode(void)
2448 {
2449     // check |own_list| for removing device
2450     if(!g_own_list || 1>g_own_cnt)
2451     {
2452         printf("   > Owned Device List is Empty\n");
2453         printf("   > Please Discover the Owned Devices, with [12] Menu\n");
2454         return 0;  // normal case
2455     }
2456
2457     // select device for removing it
2458     int dev_num = 0;
2459     for( ; ; )
2460     {
2461         printf("   > Enter Device Number, for MOT Device: ");
2462         for(int ret=0; 1!=ret; )
2463         {
2464             ret = scanf("%d", &dev_num);
2465             for( ; 0x20<=getchar(); );  // for removing overflow garbages
2466                                         // '0x20<=code' is character region
2467         }
2468         if(0<dev_num && g_own_cnt>=dev_num)
2469         {
2470             break;
2471         }
2472         printf("     Entered Wrong Number. Please Enter Again\n");
2473     }
2474
2475     int mom = 0;
2476     for( ; ; )
2477     {
2478         printf("   0. Disable Multiple Ownership Transfer\n");
2479         printf("   1. Enable Multiple Ownership Transfer\n");
2480         printf("   2. (Not Supported yet) Timely Enable Multiple Ownership Transfer\n");
2481         printf("   > Enter Mode of Multiple Ownership Transfer : ");
2482         for(int ret=0; 1!=ret; )
2483         {
2484             ret = scanf("%d", &mom);
2485             for( ; 0x20<=getchar(); );  // for removing overflow garbages
2486                                         // '0x20<=code' is character region
2487         }
2488         if((0 <= mom) && (OIC_NUMBER_OF_MOM_TYPE > mom))
2489         {
2490             break;
2491         }
2492         printf("     Entered Wrong Number. Please Enter Again\n");
2493     }
2494
2495     OCProvisionDev_t* motDev = getDevInst(g_own_list, dev_num);
2496     if(OC_STACK_OK == OCChangeMOTMode(NULL, motDev, (OicSecMomType_t)mom, updateDoxmForMOTCB))
2497     {
2498         g_doneCB = false;
2499     }
2500     else
2501     {
2502         OIC_LOG(ERROR, TAG, "OCChangeMOTMode API error");
2503         return -1;
2504     }
2505
2506     if(waitCallbackRet())  // input |g_doneCB| flag implicitly
2507     {
2508         OIC_LOG(ERROR, TAG, "waitCallbackRet callback error");
2509         return -1;
2510     }
2511
2512     return 0;
2513 }
2514
2515 static int selectMultipleOwnershipTrnasferMethod(void)
2516 {
2517     // check |own_list| for removing device
2518     if(!g_mot_enable_list || 1>g_mot_enable_cnt)
2519     {
2520         printf("   > Multiple Ownership Transfer Enabled Device List is Empty\n");
2521         printf("   > Please Discover the Multiple Ownership Transfer Enabled Devices, with [13] Menu\n");
2522         return 0;  // normal case
2523     }
2524
2525     // select device for removing it
2526     int dev_num = 0;
2527     for( ; ; )
2528     {
2529         printf("   > Enter Device Number, for MOT Device: ");
2530         for(int ret=0; 1!=ret; )
2531         {
2532             ret = scanf("%d", &dev_num);
2533             for( ; 0x20<=getchar(); );  // for removing overflow garbages
2534                                         // '0x20<=code' is character region
2535         }
2536         if(0<dev_num && g_mot_enable_cnt>=dev_num)
2537         {
2538             break;
2539         }
2540         printf("     Entered Wrong Number. Please Enter Again\n");
2541     }
2542
2543     int oxm = 0;
2544     for( ; ; )
2545     {
2546         printf("   %d. (Not Supported)\n", OIC_JUST_WORKS);
2547         printf("   %d. Random PIN OxM\n", OIC_RANDOM_DEVICE_PIN);
2548         printf("   %d. (Not Supported)\n", OIC_MANUFACTURER_CERTIFICATE);
2549         printf("   %d. (Not Supported)\n", OIC_DECENTRALIZED_PUBLIC_KEY);
2550         printf("   %d. Pre-Configured PIN OxM\n", OIC_PRECONFIG_PIN);
2551         printf("   > Enter Number of  OxM for Multiple Ownership Transfer : ");
2552         for(int ret=0; 1!=ret; )
2553         {
2554             ret = scanf("%d", &oxm);
2555             for( ; 0x20<=getchar(); );  // for removing overflow garbages
2556                                         // '0x20<=code' is character region
2557         }
2558         if(OIC_PRECONFIG_PIN == oxm || OIC_RANDOM_DEVICE_PIN == oxm)
2559         {
2560             break;
2561         }
2562         printf("     Entered Wrong Number. Please Enter Again\n");
2563     }
2564
2565     OCProvisionDev_t* motDev = getDevInst(g_mot_enable_list, dev_num);
2566     if(OC_STACK_OK == OCSelectMOTMethod(NULL, motDev, (OicSecOxm_t)oxm, updateDoxmForMOTCB))
2567     {
2568         g_doneCB = false;
2569     }
2570     else
2571     {
2572         OIC_LOG(ERROR, TAG, "OCSelectMOTMethod API error");
2573         return -1;
2574     }
2575
2576     if(waitCallbackRet())  // input |g_doneCB| flag implicitly
2577     {
2578         OIC_LOG(ERROR, TAG, "waitCallbackRet callback error");
2579         return -1;
2580     }
2581
2582     return 0;
2583 }
2584
2585 static int provisionPreconfigPIN(void)
2586 {
2587     // check |own_list| for removing device
2588     if(!g_mot_enable_list || 1>g_mot_enable_cnt)
2589     {
2590         printf("   > Multiple Ownership Transfer Enabled Device List is Empty\n");
2591         printf("   > Please Discover the Multiple Ownership Transfer Enabled Devices, with [13] Menu\n");
2592         return 0;  // normal case
2593     }
2594
2595     // select device for removing it
2596     int dev_num = 0;
2597     for( ; ; )
2598     {
2599         printf("   > Enter Device Number, for MOT Device: ");
2600         for(int ret=0; 1!=ret; )
2601         {
2602             ret = scanf("%d", &dev_num);
2603             for( ; 0x20<=getchar(); );  // for removing overflow garbages
2604                                         // '0x20<=code' is character region
2605         }
2606         if(0<dev_num && g_mot_enable_cnt>=dev_num)
2607         {
2608             break;
2609         }
2610         printf("     Entered Wrong Number. Please Enter Again\n");
2611     }
2612
2613     char preconfigPin[9] = {0};
2614     printf("   > Input the PreconfigPin (e.g. 12341234) : ");
2615     for(int ret=0; 1!=ret; )
2616     {
2617         ret = scanf("%8s", preconfigPin);
2618         for( ; 0x20<=getchar(); );  // for removing overflow garbages
2619                                     // '0x20<=code' is character region
2620     }
2621
2622     OCProvisionDev_t* motDev = getDevInst(g_mot_enable_list, dev_num);
2623     if(OC_STACK_OK == OCProvisionPreconfigPin(NULL, motDev, preconfigPin, strlen(preconfigPin), provisionCredCB))
2624     {
2625         g_doneCB = false;
2626     }
2627     else
2628     {
2629         OIC_LOG(ERROR, TAG, "OCProvisionPreconfigPin API error");
2630         return -1;
2631     }
2632
2633     if(waitCallbackRet())  // input |g_doneCB| flag implicitly
2634     {
2635         OIC_LOG(ERROR, TAG, "waitCallbackRet callback error");
2636         return -1;
2637     }
2638
2639     return 0;
2640 }
2641 #endif //MULTIPLE_OWNER
2642
2643 static int resetDevice(void)
2644 {
2645     // check |own_list| for removing device
2646     if (!g_own_list || 1 > g_own_cnt)
2647     {
2648         printf("   > Owned Device List, to Reset Device, is Empty\n");
2649         printf("   > Please Register Unowned Devices first, with [20] Menu\n");
2650         return 0;
2651     }
2652
2653     // select device for removing it
2654     int dev_num = 0;
2655     for ( ; ; )
2656     {
2657         printf("   > Enter Device Number, for Resetting Device: ");
2658         for (int ret = 0; 1 != ret; )
2659         {
2660             ret = scanf("%d", &dev_num);
2661             for ( ; 0x20 <= getchar() ; );  // for removing overflow garbages
2662                                             // '0x20 <= code' is character region
2663         }
2664         if (0 < dev_num && g_own_cnt >= dev_num)
2665         {
2666             break;
2667         }
2668         printf("     Entered Wrong Number. Please Enter Again\n");
2669     }
2670
2671     g_doneCB = false;
2672     printf("   Resetting Selected Owned Device..\n");
2673
2674     OCStackResult rst = OCResetDevice((void *) g_ctx, DISCOVERY_TIMEOUT,
2675                     getDevInst((const OCProvisionDev_t *) g_own_list, dev_num), syncDeviceCB);
2676     if (OC_STACK_OK != rst)
2677     {
2678         OIC_LOG_V(ERROR, TAG, "OCResetDevice API error: %d", rst);
2679         return -1;
2680     }
2681
2682     if (waitCallbackRet())  // input |g_doneCB| flag implicitly
2683     {
2684         OIC_LOG(ERROR, TAG, "OCResetDevice callback error");
2685         return -1;
2686     }
2687
2688     // display the removed result
2689     printf("   > Reset Selected Owned Device SUCCEEDED\n");
2690     printf("   > Please Discover Owned Devices for the Registered Result, with [10|12] Menu\n");
2691
2692     return 0;
2693 }
2694
2695 static int resetSVRDB(void)
2696 {
2697     printf("   Resetting SVR DB..\n");
2698     OCStackResult rst = OCResetSVRDB();
2699     if (OC_STACK_OK != rst)
2700     {
2701         OIC_LOG_V(ERROR, TAG, "OCResetSVRDB API error: %d", rst);
2702         return -1;
2703     }
2704     return 0;
2705 }
2706
2707 static OicSecAcl_t* createAcl(const int dev_num)
2708 {
2709     if(0>=dev_num || g_own_cnt<dev_num)
2710     {
2711         OIC_LOG(ERROR, TAG, "createAcl invalid parameters");
2712         return NULL;  // not need to 'goto' |ERROR| before allocating |acl|
2713     }
2714
2715     // allocate memory for |acl| struct
2716     printf("   **** Create ACL for the Selected Device[%d]\n", dev_num);
2717     OicSecAcl_t* acl = (OicSecAcl_t*) OICCalloc(1, sizeof(OicSecAcl_t));
2718     if(!acl)
2719     {
2720         OIC_LOG(ERROR, TAG, "createAcl: OICCalloc error return");
2721         return NULL;  // not need to 'goto' |ERROR| before allocating |acl|
2722     }
2723     OicSecAce_t* ace = (OicSecAce_t*) OICCalloc(1, sizeof(OicSecAce_t));
2724     if(!ace)
2725     {
2726         OIC_LOG(ERROR, TAG, "createAcl: OICCalloc error return");
2727         return NULL;  // not need to 'goto' |ERROR| before allocating |acl|
2728     }
2729     LL_APPEND(acl->aces, ace);
2730
2731     // enter |subject| device number
2732     int num = 0;
2733     for( ; ; )
2734     {
2735         printf("   > [A] Enter Subject Device Number: ");
2736         for(int ret=0; 1!=ret; )
2737         {
2738             ret = scanf("%d", &num);
2739             for( ; 0x20<=getchar(); );  // for removing overflow garbages
2740                                         // '0x20<=code' is character region
2741         }
2742         if(0<num && g_own_cnt>=num && dev_num!=num)
2743         {
2744             break;
2745         }
2746         printf("     Entered Wrong Number. Please Enter Again\n");
2747     }
2748
2749     OCProvisionDev_t* dev = getDevInst((const OCProvisionDev_t*)g_own_list, num);
2750     if(!dev || !dev->doxm)
2751     {
2752         OIC_LOG(ERROR, TAG, "createAcl: device instance empty");
2753         goto CRACL_ERROR;
2754     }
2755     ace->subjectType = OicSecAceUuidSubject;
2756     memcpy(&ace->subjectuuid, &dev->doxm->deviceID, UUID_LENGTH);
2757
2758     // enter number of |resources| in 'accessed' device
2759     for( ; ; )
2760     {
2761         printf("   > [B] Enter Number of Accessed Resources (under 16): ");
2762                 // '16' is |ACL_RESRC_MAX_NUM|
2763         for(int ret=0; 1!=ret; )
2764         {
2765             ret = scanf("%d", &num);
2766             for( ; 0x20<=getchar(); );  // for removing overflow garbages
2767                                         // '0x20<=code' is character region
2768         }
2769         if(0<num && ACL_RESRC_MAX_NUM>=num)
2770         {
2771             break;
2772         }
2773         printf("     Entered Wrong Number. Please Enter under 16 Again\n");
2774                 // '16' is |ACL_RESRC_MAX_NUM|
2775     }
2776
2777     // enter actually each 'accessed' |resources| name
2778     printf("         Enter Each Accessed Resource Name (each under 128 char)\n");
2779             // '128' is ACL_RESRC_MAX_LEN
2780
2781     char rsrc_in[ACL_RESRC_MAX_LEN+1] = {0};  // '1' for null termination
2782     for(int i = 0; num > i; ++i)
2783     {
2784         OicSecRsrc_t* rsrc = (OicSecRsrc_t*)OICCalloc(1, sizeof(OicSecRsrc_t));
2785         if(!rsrc)
2786         {
2787             OIC_LOG(ERROR, TAG, "createAcl: OICCalloc error return");
2788             goto CRACL_ERROR;
2789         }
2790
2791         printf("         Enter Accessed Resource[%d] Name: (e.g. /a/led)", i+1);
2792         for(int ret=0; 1!=ret; )
2793         {
2794             ret = scanf("%128s", rsrc_in);  // '128' is ACL_RESRC_MAX_LEN
2795             for( ; 0x20<=getchar(); );  // for removing overflow garbages
2796                                         // '0x20<=code' is character region
2797         }
2798         size_t len = strlen(rsrc_in)+1;  // '1' for null termination
2799         rsrc->href = (char*) OICCalloc(len, sizeof(char));
2800         if(!rsrc->href)
2801         {
2802             OIC_LOG(ERROR, TAG, "createAcl: OICCalloc error return");
2803             goto CRACL_ERROR;
2804         }
2805         OICStrcpy(rsrc->href, len, rsrc_in);
2806
2807         size_t arrLen = 0;
2808         while(1)
2809         {
2810             printf("         Enter Number of resource type for [%s] : ", rsrc->href);
2811             for(int ret=0; 1!=ret; )
2812             {
2813                 ret = scanf("%zu", &arrLen);
2814                 for( ; 0x20<=getchar(); );  // for removing overflow garbages
2815                                             // '0x20<=code' is character region
2816             }
2817             if(ACL_RESRC_ARRAY_SIZE >= arrLen)
2818             {
2819                 break;
2820             }
2821             printf("     Entered Wrong Number. Please Enter under %d Again\n", ACL_RESRC_ARRAY_SIZE);
2822         }
2823
2824         rsrc->typeLen = arrLen;
2825         rsrc->types = (char**)OICCalloc(arrLen, sizeof(char*));
2826         if(!rsrc->types)
2827         {
2828             OIC_LOG(ERROR, TAG, "createAcl: OICCalloc error return");
2829             goto CRACL_ERROR;
2830         }
2831
2832         for(size_t j = 0; j < arrLen; j++)
2833         {
2834             printf("         Enter ResourceType[%zu] Name (e.g. core.led): ", j+1);
2835             for(int ret=0; 1!=ret; )
2836             {
2837                 ret = scanf("%128s", rsrc_in);  // '128' is ACL_RESRC_MAX_LEN
2838                 for( ; 0x20<=getchar(); );  // for removing overflow garbages
2839                                             // '0x20<=code' is character region
2840             }
2841             rsrc->types[j] = OICStrdup(rsrc_in);
2842             if(!rsrc->types[j])
2843             {
2844                 OIC_LOG(ERROR, TAG, "createAcl: OICStrdup error return");
2845                 goto CRACL_ERROR;
2846             }
2847         }
2848
2849         while(1)
2850         {
2851             printf("         Enter Number of interface for [%s]: ", rsrc->href);
2852             for(int ret=0; 1!=ret; )
2853             {
2854                 ret = scanf("%zu", &arrLen);
2855                 for( ; 0x20<=getchar(); );  // for removing overflow garbages
2856                                             // '0x20<=code' is character region
2857             }
2858             if(ACL_RESRC_ARRAY_SIZE >= arrLen)
2859             {
2860                 break;
2861             }
2862             printf("     Entered Wrong Number. Please Enter under %d Again\n", ACL_RESRC_ARRAY_SIZE);
2863         }
2864
2865         rsrc->interfaceLen = arrLen;
2866         rsrc->interfaces = (char**)OICCalloc(arrLen, sizeof(char*));
2867         if(!rsrc->interfaces)
2868         {
2869             OIC_LOG(ERROR, TAG, "createAcl: OICCalloc error return");
2870             goto CRACL_ERROR;
2871         }
2872
2873         for(size_t j = 0; j < arrLen; j++)
2874         {
2875             printf("         Enter Interface[%zu] Name (e.g. oic.if.baseline): ", j+1);
2876             for(int ret=0; 1!=ret; )
2877             {
2878                 ret = scanf("%128s", rsrc_in);  // '128' is ACL_RESRC_MAX_LEN
2879                 for( ; 0x20<=getchar(); );  // for removing overflow garbages
2880                                             // '0x20<=code' is character region
2881             }
2882             rsrc->interfaces[j] = OICStrdup(rsrc_in);
2883             if(!rsrc->interfaces[j])
2884             {
2885                 OIC_LOG(ERROR, TAG, "createAcl: OICStrdup error return");
2886                 goto CRACL_ERROR;
2887             }
2888         }
2889
2890         LL_APPEND(ace->resources, rsrc);
2891     }
2892
2893     // enter |permission| for this access
2894     printf("   > [C] Enter Permission for This Access\n");
2895     uint16_t pmsn = PERMISSION_FULL_CONTROL;  // default full permission
2896     uint16_t pmsn_msk = PERMISSION_CREATE;  // default permission mask
2897     for(int i=0; ACL_PEMISN_CNT>i; ++i)
2898     {
2899         char ans = 0;
2900         for( ; ; )
2901         {
2902             printf("         Enter %s Permission (y/n): ", ACL_PEMISN[i]);
2903             for(int ret=0; 1!=ret; )
2904             {
2905                 ret = scanf("%c", &ans);
2906                 for( ; 0x20<=getchar(); );  // for removing overflow garbages
2907                                             // '0x20<=code' is character region
2908             }
2909             if('y'==ans || 'Y'==ans || 'n'==ans|| 'N'==ans)
2910             {
2911                 ans &= ~0x20;  // for masking lower case, 'y/n'
2912                 break;
2913             }
2914             printf("         Entered Wrong Answer. Please Enter 'y/n' Again\n");
2915         }
2916         if('N' == ans)  // masked lower case, 'n'
2917         {
2918             pmsn -= pmsn_msk;
2919         }
2920         pmsn_msk <<= 1;
2921     }
2922     ace->permission = pmsn;
2923
2924     return acl;
2925
2926 CRACL_ERROR:
2927     OCDeleteACLList(acl);  // after here |acl| points nothing
2928     return NULL;
2929 }
2930
2931 static OicSecAcl_t* createSimpleAcl(const OicUuid_t uuid)
2932 {
2933     OIC_LOG(DEBUG, TAG, "createSimpleAcl IN");
2934
2935     // allocate memory for |acl| struct
2936     OicSecAcl_t* acl = (OicSecAcl_t*) OICCalloc(1, sizeof(OicSecAcl_t));
2937     if(!acl)
2938     {
2939         OIC_LOG(DEBUG, TAG, "OICCalloc error return");
2940         return NULL;  // not need to 'goto' |ERROR| before allocating |acl|
2941     }
2942     OicSecAce_t* ace = (OicSecAce_t*) OICCalloc(1, sizeof(OicSecAce_t));
2943     if(!ace)
2944     {
2945         OIC_LOG(DEBUG, TAG,  "OICCalloc error return");
2946         return NULL;  // not need to 'goto' |ERROR| before allocating |acl|
2947     }
2948     LL_APPEND(acl->aces, ace);
2949
2950     memcpy(&ace->subjectuuid, &uuid, UUID_LENGTH);
2951
2952     OicSecRsrc_t* rsrc = (OicSecRsrc_t*)OICCalloc(1, sizeof(OicSecRsrc_t));
2953     if(!rsrc)
2954     {
2955         OIC_LOG(DEBUG, TAG, "OICCalloc error return");
2956         OCDeleteACLList(acl);
2957         return NULL;
2958     }
2959
2960     char href[] = "*";
2961     size_t len = strlen(href)+1;  // '1' for null termination
2962     rsrc->href = (char*) OICCalloc(len, sizeof(char));
2963     if(!rsrc->href)
2964     {
2965         OIC_LOG(DEBUG, TAG,  "OICCalloc error return");
2966         OCDeleteACLList(acl);
2967         return NULL;
2968     }
2969     OICStrcpy(rsrc->href, len, href);
2970
2971     size_t arrLen = 1;
2972     rsrc->typeLen = arrLen;
2973     rsrc->types = (char**)OICCalloc(arrLen, sizeof(char*));
2974     if(!rsrc->types)
2975     {
2976         OIC_LOG(DEBUG, TAG,  "OICCalloc error return");
2977         OCDeleteACLList(acl);
2978         return NULL;
2979     }
2980     rsrc->types[0] = OICStrdup("");   // ignore
2981
2982     rsrc->interfaceLen = 1;
2983     rsrc->interfaces = (char**)OICCalloc(arrLen, sizeof(char*));
2984     if(!rsrc->interfaces)
2985     {
2986         OIC_LOG(DEBUG, TAG,  "OICCalloc error return");
2987         OCDeleteACLList(acl);
2988         return NULL;
2989     }
2990     rsrc->interfaces[0] = OICStrdup("oic.if.baseline");  // ignore
2991
2992     LL_APPEND(ace->resources, rsrc);
2993
2994     ace->permission = 31;   // R/W/U/D
2995
2996     OIC_LOG(DEBUG, TAG, "createSimpleAcl OUT");
2997
2998     return acl;
2999 }
3000
3001 static OCProvisionDev_t* getDevInst(const OCProvisionDev_t* dev_lst, const int dev_num)
3002 {
3003     if(!dev_lst || 0>=dev_num)
3004     {
3005         printf("     Device List is Empty..\n");
3006         return NULL;
3007     }
3008
3009     OCProvisionDev_t* lst = (OCProvisionDev_t*) dev_lst;
3010     for(int i=0; lst; )
3011     {
3012         if(dev_num == ++i)
3013         {
3014             return lst;
3015         }
3016         lst = lst->next;
3017     }
3018
3019     return NULL;  // in here |lst| is always |NULL|
3020 }
3021
3022 static int printDevList(const OCProvisionDev_t* dev_lst)
3023 {
3024     if(!dev_lst)
3025     {
3026         printf("     Device List is Empty..\n\n");
3027         return 0;
3028     }
3029
3030     OCProvisionDev_t* lst = (OCProvisionDev_t*) dev_lst;
3031     int lst_cnt = 0;
3032     for( ; lst; )
3033     {
3034         printf("     [%d] ", ++lst_cnt);
3035         printUuid((const OicUuid_t*) &lst->doxm->deviceID);
3036         printf("   %s:%d   %s", lst->endpoint.addr, lst->endpoint.port,lst->specVer);
3037         printf("\n");
3038         lst = lst->next;
3039     }
3040     printf("\n");
3041
3042     return lst_cnt;
3043 }
3044
3045 static size_t printUuidList(const OCUuidList_t* uid_lst)
3046 {
3047     if(!uid_lst)
3048     {
3049         printf("     Device List is Empty..\n\n");
3050         return 0;
3051     }
3052
3053     OCUuidList_t* lst = (OCUuidList_t*) uid_lst;
3054     size_t lst_cnt = 0;
3055     for( ; lst; )
3056     {
3057         printf("     [%" PRIuPTR "] ", ++lst_cnt);
3058         printUuid((const OicUuid_t*) &lst->dev);
3059         printf("\n");
3060         lst = lst->next;
3061     }
3062     printf("\n");
3063
3064     return lst_cnt;
3065 }
3066
3067 static size_t printResultList(const OCProvisionResult_t* rslt_lst, const size_t rslt_cnt)
3068 {
3069     if (!rslt_lst || (0 == rslt_cnt))
3070     {
3071         printf("     Device List is Empty..\n\n");
3072         return 0;
3073     }
3074
3075     size_t lst_cnt = 0;
3076     for (; rslt_cnt > lst_cnt; ++lst_cnt)
3077     {
3078         printf("     [%" PRIuPTR "] ", lst_cnt + 1);
3079         printUuid((const OicUuid_t*)&rslt_lst[lst_cnt].deviceId);
3080         printf(" - result: %d\n", rslt_lst[lst_cnt].res);
3081     }
3082     printf("\n");
3083
3084     return lst_cnt;
3085 }
3086
3087 const char* getResult(OCStackResult result)
3088 {
3089     switch (result)
3090     {
3091     case OC_STACK_OK:
3092         return "OC_STACK_OK";
3093     case OC_STACK_RESOURCE_CREATED:
3094         return "OC_STACK_RESO