replace : iotivity -> iotivity-sec
[platform/upstream/iotivity.git] / resource / provisioning / examples / provisioningclient.cpp
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 <stdio.h>
22 #include <string.h>
23 #include <unistd.h>
24 #include <string>
25 #include <map>
26 #include <cstdlib>
27 #include <pthread.h>
28 #include <mutex>
29 #include <condition_variable>
30
31 #include "logger.h"
32 #include "oic_malloc.h"
33 #include "oic_string.h"
34 #include "OCPlatform.h"
35 #include "OCApi.h"
36 #include "OCProvisioningManager.hpp"
37 #include "oxmjustworks.h"
38 #include "oxmrandompin.h"
39 #include "aclresource.h"
40 #include "utlist.h"
41 #include "mbedtls/x509_crt.h"
42
43 #define MAX_PERMISSION_LENGTH (5)
44 #define ACL_RESRC_ARRAY_SIZE (3)
45 #define CREATE (1)
46 #define READ (2)
47 #define UPDATE (4)
48 #define DELETE (8)
49 #define NOTIFY (16)
50 #define DASH '-'
51 #define PREDEFINED_TIMEOUT (10)
52 #define MAX_OWNED_DEVICE (10)
53 #define TAG  "provisioningclient"
54
55 #define JSON_DB_PATH "./oic_svr_db_client.json"
56 #define DAT_DB_PATH "./oic_svr_db_client.dat"
57 #define DEV_STATUS_ON "DEV_STATUS_ON"
58 #define DEV_STATUS_OFF "DEV_STATUS_OFF"
59
60 #define DISCOVERY_TIMEOUT 5
61
62 static const OicSecPrm_t  SUPPORTED_PRMS[1] =
63 {
64     PRM_PRE_CONFIGURED,
65 };
66
67 using namespace OC;
68
69 DeviceList_t pUnownedDevList, pOwnedDevList, pMOTEnabledDeviceList;
70 static int transferDevIdx, ask = 1;
71 static OicSecPconf_t g_pconf;
72 static uint16_t g_credId = 0;
73
74 static FILE* client_open(const char *UNUSED_PARAM, const char *mode)
75 {
76     (void)UNUSED_PARAM;
77     return fopen(DAT_DB_PATH, mode);
78 }
79
80 void printMenu()
81 {
82     std::cout << "\nChoose an option:"<<std::endl;
83     std::cout << "   1. UnOwned Device discovery"<<std::endl;
84     std::cout << "   2. Owned Device discovery"<<std::endl;
85     std::cout << "   3. Ownership transfer"<<std::endl;
86     std::cout << "   4. Provision ACL"<<std::endl;
87     std::cout << "   5. Provision Credentials"<<std::endl;
88     std::cout << "   6. Credential & ACL provisioning b/w two devices"<<std::endl;
89     std::cout << "   7. Unlink Devices"<<std::endl;
90     std::cout << "   8. Remove Device"<<std::endl;
91     std::cout << "   9. Remove Device using UUID"<<std::endl;
92     std::cout << "  10. Get Linked Devices"<<std::endl;
93     std::cout << "  11. Get Device Status"<<std::endl;
94     std::cout << "  12. Provision Direct-Pairing Configuration"<<std::endl;
95 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
96     std::cout << "  13. Save the Trust Cert. Chain into Cred of SVR"<<std::endl;
97     std::cout << "  14. Provision the Trust Cert. Chain"<<std::endl;
98     std::cout << "  15. Read trust cert chain"<<std::endl;
99 #endif // __WITH_DTLS__ || __WITH_TLS__
100 #ifdef MULTIPLE_OWNER
101     std::cout << "  16. Change Multiple Ownership Transfer Mode"<<std::endl;
102     std::cout << "  17. Select OxM method for Multiple Ownership Transfer"<<std::endl;
103     std::cout << "  18. Multiple Ownership Transfer Enabled Devices Discovery"<<std::endl;
104     std::cout << "  19. Provision pre configure PIN for Multiple Ownership Transfer Mode"<<std::endl;
105     std::cout << "  20. Add pre configure PIN for Multiple Ownership Transfer Mode"<<std::endl;
106     std::cout << "  21. Remove Sub-Owner from Resource Server"<<std::endl;
107     std::cout << "  22. Remove All Sub-Owner from Resource Server"<<std::endl;
108 #endif
109     std::cout << "  30. Configure SVRdb as Self-OwnerShip"<<std::endl;
110     std::cout << "  99. Exit loop"<<std::endl;
111 }
112
113 void moveTransferredDevice()
114 {
115     pOwnedDevList.push_back(pUnownedDevList[transferDevIdx]);
116     pUnownedDevList.erase(pUnownedDevList.begin() + transferDevIdx);
117 }
118
119 void InputPinCB(char* pinBuf, size_t bufSize)
120 {
121     if(pinBuf)
122     {
123         std::cout <<"INPUT PIN : ";
124         std::string ptr;
125         std::cin >> ptr;
126         OICStrcpy(pinBuf, bufSize, ptr.c_str());
127         return;
128     }
129 }
130
131 void printUuid(OicUuid_t uuid)
132 {
133     for (int i = 0; i < UUID_LENGTH; i++)
134     {
135         std::cout <<std::hex << uuid.id[i] << " ";
136     }
137     std::cout<<std::endl;
138 }
139
140
141 static OCStackResult peerCertCallback(const mbedtls_x509_crt *cert, int depth)
142 {
143     OIC_LOG_V(DEBUG, TAG, "Depth : %d", depth);
144     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
145     OIC_LOG(DEBUG, TAG, "***** Serial number of peer certificate is below *****");
146     OIC_LOG_BUFFER(DEBUG, TAG, cert->serial.p, cert->serial.len);
147     OIC_LOG(DEBUG, TAG, "***** Serial number of peer certificate is above *****");
148     OIC_LOG_V(DEBUG, TAG, "OUT%s", __func__);
149
150     return OC_STACK_OK;
151 }
152
153 void ownershipTransferCB(PMResultList_t *result, int hasError)
154 {
155     if (hasError)
156     {
157         std::cout << "Error!!! in OwnershipTransfer"<<std::endl;
158     }
159     else
160     {
161         std::cout<< "\nTransferred Ownership successfuly for device : ";
162         printUuid(result->at(0).deviceId);
163         delete result;
164
165         moveTransferredDevice();
166     }
167     ask = 1;
168 }
169
170 void printStatus(int status)
171 {
172     static std::map<int, std::string> devStatus = {{1<<0, DEV_STATUS_ON}, {1<<1, DEV_STATUS_OFF}};
173
174     std::cout <<devStatus[status] <<std::endl;
175 }
176
177 void printDevices(DeviceList_t &list)
178 {
179    for (unsigned int i = 0; i < list.size(); i++ )
180    {
181       std::cout << "Device "<< i+1 <<" ID: ";
182       std::cout << list[i]->getDeviceID() << " From IP: ";
183       std::cout << list[i]->getDevAddr() << std::endl;
184    }
185 }
186
187 /**
188  * Callback function for provisioning ACL, Credentials.
189  *
190  * @param[in]    result Result list
191  * @param[in] hasError indicates if the result has error
192  */
193 void provisionCB(PMResultList_t *result, int hasError)
194 {
195    if (hasError)
196    {
197        std::cout << "Error in provisioning operation!"<<std::endl;
198    }
199    else
200    {
201        std::cout<< "\nReceived provisioning results: ";
202        for (unsigned int i = 0; i < result->size(); i++)
203        {
204            std::cout << "Result is = " << result->at(i).res <<" for device ";
205            printUuid(result->at(i).deviceId);
206        }
207
208        delete result;
209    }
210    printMenu();
211    ask = 1;
212 }
213 /**
214  *
215  * Ask user with which devices it wants to make further actions.
216  * All possible error checks included.
217  * Default behavior in case if only one options leaves are included too.
218  * Expect that user count devices from 1, f.e. 1st, 2nd, 3rd, etc
219  * Use DeviceList_t instead of devicesCount because of print devices info
220  *
221  * @param[in] list owned devices list.
222  * @param[out] out device number array.
223  * @param[in] count how many device numbers need to read.
224  * @return 0 in case of success and other value otherwise.
225  */
226 int readDeviceNumber(DeviceList_t &list, int count, int *out)
227 {
228    if (out == NULL || count <= 0)
229    {
230       std::cout << "Error! Please put valid input parameters" << std::endl;
231       return -1;
232    }
233
234    int devicesCount = list.size();
235
236    //Print current list of owned devices
237    std::cout <<"Owned devices, count = " << devicesCount << std::endl;
238    printDevices(list);
239
240    if (devicesCount < count)
241    {
242       std::cout << "You can't proceed with selected action because Owned devices count ( ";
243       std::cout << devicesCount << " ) are less then required devices ( " << count << " ).";
244       std::cout << "You may need to discover devices again" << std::endl;
245       return -2;
246    }
247
248    std::cout << "Select " << count << " device(s) for provisioning" << std::endl;
249
250    for (int curr = 0; curr < count; curr++)
251    {
252       //select last device by default if only 1 option exist
253       //from user's point of view device counting starts from 1,
254       //so 1st, 2nd, 3rd, etc devices
255       if ((curr == count - 1) && (devicesCount == count))
256       {
257          int sum = 0;
258          for (int i = 0; i < curr; i++)
259          {
260              sum += out[i];
261          }
262
263          out[curr] = (count*(count+1))/2 - sum;
264
265          std::cout << "Device " << curr + 1 << " : " << out[curr];
266          std::cout << " - selected automatically (because no other options exist)" << std::endl;
267          break;
268       }
269
270       int choice;
271       std::cout << "Device " << curr + 1 << " : ";
272       std::cin >> choice;
273
274       if (choice < 1 || choice > devicesCount)
275       {
276          std::cout << "Error! You should enter valid device number!" << std::endl;
277          return -3;
278       }
279
280       //check that user doesn't select the same device twice
281       for (int i = 0; i < curr; i++)
282       {
283          if (out[i] == choice)
284          {
285             std::cout << "Error! You cannot select the same device twice!" << std::endl;
286             return -4;
287          }
288       }
289
290       out[curr] = choice;
291    }
292
293    //Users count devices from 1, so 1st, 2nd, 3rd, etc device
294    //But deviceList array start index is 0, so need to decrease all numbers to 1
295    for (int i = 0; i < count; i++) out[i] -= 1;
296
297    return 0;
298 }
299
300 /**
301  * Perform cleanup for ACL
302  * @param[in]    ACL
303  */
304 static void deleteACL(OicSecAcl_t *acl)
305 {
306     DeleteACLList(acl);
307
308 }
309
310 /**
311  * Calculate ACL permission from string to bit
312  *
313  * @param[in] temp_psm    Input data of ACL permission string
314  * @param[in,out] pms    The pointer of ACL permission value
315  * @return  0 on success otherwise -1.
316  */
317 static int CalculateAclPermission(const char *temp_pms, uint16_t *pms)
318 {
319     int i = 0;
320
321     if (NULL == temp_pms || NULL == pms)
322     {
323         return -1;
324     }
325     *pms = 0;
326     while (temp_pms[i] != '\0')
327     {
328         switch (temp_pms[i])
329         {
330             case 'C':
331                 {
332                     *pms += CREATE;
333                     i++;
334                     break;
335                 }
336             case 'R':
337                 {
338                     *pms += READ;
339                     i++;
340                     break;
341                 }
342             case 'U':
343                 {
344                     *pms += UPDATE;
345                     i++;
346                     break;
347                 }
348             case 'D':
349                 {
350                     *pms += DELETE;
351                     i++;
352                     break;
353                 }
354             case 'N':
355                 {
356                     *pms += NOTIFY;
357                     i++;
358                     break;
359                 }
360             case '_':
361                 {
362                     i++;
363                     break;
364                 }
365             default:
366                 {
367                     return -1;
368                 }
369         }
370     }
371     return 0;
372 }
373
374 /**
375  * Get the ACL property from user
376  *
377  * @param[in]    ACL Datastructure to save user inputs
378  * @return  0 on success otherwise -1.
379  */
380 static int InputACL(OicSecAcl_t *acl)
381 {
382     int ret;
383     char *temp_id, *temp_rsc, *temp_pms;
384
385     printf("******************************************************************************\n");
386     printf("-Set ACL policy for target device\n");
387     printf("******************************************************************************\n");
388     //Set Subject.
389     printf("-URN identifying the subject\n");
390     printf("ex) 1111-1111-1111-1111 (16 Numbers except to '-')\n");
391     printf("Subject : ");
392     ret = scanf("%19ms", &temp_id);
393
394     OicSecAce_t* ace = (OicSecAce_t*)OICCalloc(1, sizeof(OicSecAce_t));
395     if(NULL == ace)
396     {
397         OIC_LOG(ERROR, TAG, "Error while memory allocation");
398         return -1;
399     }
400     LL_APPEND(acl->aces, ace);
401
402     if (1 == ret)
403     {
404         for (int i = 0, j = 0; temp_id[i] != '\0'; i++)
405         {
406             if (DASH != temp_id[i])
407                 ace->subjectuuid.id[j++] = temp_id[i];
408         }
409         OICFree(temp_id);
410     }
411     else
412     {
413         deleteACL(acl);
414         printf("Error while input\n");
415         return -1;
416     }
417
418     //Set Resource.
419     size_t resourcesLen = 0;
420     printf("Num. of Resource : ");
421     ret = scanf("%zu", &resourcesLen);
422     if ((1 != ret) || (resourcesLen <= 0 || resourcesLen > 50))
423     {
424         deleteACL(acl);
425         printf("Error while input\n");
426         return -1;
427     }
428     printf("-URI of resource\n");
429     printf("ex)/oic/sh/temp/0 (Max_URI_Length: %d Byte )\n", MAX_URI_LENGTH);
430     for(size_t i = 0; i < resourcesLen; i++)
431     {
432         OicSecRsrc_t* rsrc = (OicSecRsrc_t*)OICCalloc(1, sizeof(OicSecRsrc_t));
433         if(NULL == rsrc)
434         {
435             deleteACL(acl);
436             OIC_LOG(ERROR, TAG, "Error while memory allocation");
437             return -1;
438         }
439
440         LL_APPEND(ace->resources, rsrc);
441
442         printf("[%zu]Resource : ", i + 1);
443         ret = scanf("%64ms", &temp_rsc);
444         if (1 != ret)
445         {
446             printf("Error while input\n");
447             return -1;
448         }
449
450         rsrc->href = OICStrdup(temp_rsc);
451         OICFree(temp_rsc);
452
453         char* rsrc_in = NULL;
454         size_t arrLen = 0;
455         while(1)
456         {
457             printf("         Enter Number of resource type for [%s]: ", rsrc->href);
458             for(int ret=0; 1!=ret; )
459             {
460                 ret = scanf("%zu", &arrLen);
461                 for( ; 0x20<=getchar(); );  // for removing overflow garbages
462                                             // '0x20<=code' is character region
463             }
464             if(ACL_RESRC_ARRAY_SIZE >= arrLen)
465             {
466                 break;
467             }
468             printf("     Entered Wrong Number. Please Enter under %d Again\n", ACL_RESRC_ARRAY_SIZE);
469         }
470
471         rsrc->typeLen = arrLen;
472         rsrc->types = (char**)OICCalloc(arrLen, sizeof(char*));
473         if(!rsrc->types)
474         {
475             OIC_LOG(ERROR, TAG, "createAcl: OICCalloc error return");
476             goto error;
477         }
478
479         for(unsigned int i = 0; i < arrLen; i++)
480         {
481             printf("         Enter ResourceType[%d] Name (e.g. core.led): ", i+1);
482             for(int ret=0; 1!=ret; )
483             {
484                 ret = scanf("%64ms", &rsrc_in);  // '128' is ACL_RESRC_MAX_LEN
485                 for( ; 0x20<=getchar(); );  // for removing overflow garbages
486                                             // '0x20<=code' is character region
487             }
488             rsrc->types[i] = OICStrdup(rsrc_in);
489             OICFree(rsrc_in);
490             if(!rsrc->types[i])
491             {
492                 OIC_LOG(ERROR, TAG, "createAcl: OICStrdup error return");
493                 goto error;
494             }
495         }
496
497         while(1)
498         {
499             printf("         Enter Number of interface name for [%s]: ", rsrc->href);
500             for(int ret=0; 1!=ret; )
501             {
502                 ret = scanf("%zu", &arrLen);
503                 for( ; 0x20<=getchar(); );  // for removing overflow garbages
504                                             // '0x20<=code' is character region
505             }
506             if(ACL_RESRC_ARRAY_SIZE >= arrLen)
507             {
508                 break;
509             }
510             printf("     Entered Wrong Number. Please Enter under %d Again\n", ACL_RESRC_ARRAY_SIZE);
511         }
512
513         rsrc->interfaceLen = arrLen;
514         rsrc->interfaces = (char**)OICCalloc(arrLen, sizeof(char*));
515         if(!rsrc->interfaces)
516         {
517             OIC_LOG(ERROR, TAG, "createAcl: OICCalloc error return");
518             goto error;
519         }
520
521         for(unsigned int i = 0; i < arrLen; i++)
522         {
523             printf("         Enter interfnace[%d] Name (e.g. oic.if.baseline): ", i+1);
524             for(int ret=0; 1!=ret; )
525             {
526                 ret = scanf("%64ms", &rsrc_in);  // '128' is ACL_RESRC_MAX_LEN
527                 for( ; 0x20<=getchar(); );  // for removing overflow garbages
528                                             // '0x20<=code' is character region
529             }
530             rsrc->interfaces[i] = OICStrdup(rsrc_in);
531             OICFree(rsrc_in);
532             if(!rsrc->interfaces[i])
533             {
534                 OIC_LOG(ERROR, TAG, "createAcl: OICStrdup error return");
535                 goto error;
536             }
537         }
538
539     }
540
541     // Set Permission
542     do
543     {
544         printf("-Set the permission(C,R,U,D,N)\n");
545         printf("ex) CRUDN, CRU_N,..(5 Charaters)\n");
546         printf("Permission : ");
547         ret = scanf("%5ms", &temp_pms);
548         if (1 != ret)
549         {
550             printf("Error while input\n");
551             goto error;
552         }
553         ret = CalculateAclPermission(temp_pms, &(ace->permission));
554         OICFree(temp_pms);
555     } while (0 != ret );
556
557     // Set Rowner
558     printf("-URN identifying the rowner\n");
559     printf("ex) 1111-1111-1111-1111 (16 Numbers except to '-')\n");
560
561     printf("Rowner : ");
562     ret = scanf("%19ms", &temp_id);
563     if (1 != ret)
564     {
565         printf("Error while input\n");
566         goto error;
567     }
568
569     for (int k = 0, j = 0; temp_id[k] != '\0'; k++)
570     {
571         if (DASH != temp_id[k])
572         {
573             acl->rownerID.id[j++] = temp_id[k];
574         }
575     }
576     OICFree(temp_id);
577
578     return 0;
579
580 error:
581     DeleteACLList(acl);
582     return -1;
583 }
584
585 static int InputCredentials(Credential &cred)
586 {
587    int choice;
588
589    do
590    {
591        std::cout << "Select credential type from following values:" << std::endl;
592        std::cout << "1:  symmetric pair-wise key" << std::endl;
593        std::cout << "2:  symmetric group key" << std::endl;
594        std::cout << "4:  asymmetric key" << std::endl;
595        std::cout << "8:  signed asymmetric key (aka certificate)" << std::endl;
596        std::cout << "16: PIN /password" << std::endl;
597        std::cout << "Your choice: ";
598
599        std::cin >> choice;
600
601        switch (choice){
602            case 1:
603                cred.setCredentialType(static_cast<OicSecCredType_t>(choice));
604                choice = 0; //validation of the accepted choice.
605                break;
606            case 2:
607            case 4:
608            case 8:
609            case 16:
610                std::cout << "selected type is not supported yet" << std::endl;
611                break;
612            default:
613                std::cout << "Error! Please select valid credential type" << std::endl;
614                break;
615        }
616    } while(0 != choice);
617
618    std::cout << "Please enter key size (valid size is 128 or 256) :";
619    std::cin >> choice;
620
621    if(128 == choice)
622    {
623        cred.setCredentialKeySize(OWNER_PSK_LENGTH_128);
624    }
625    else if(256 == choice)
626    {
627         cred.setCredentialKeySize(OWNER_PSK_LENGTH_256);
628    }
629    else
630    {
631       std::cout << "Error! Please enter valid key size!" << std::endl;
632       return -2;
633    }
634
635    return 0;
636 }
637
638 static void deletePconf()
639 {
640     OICFree(g_pconf.prm);
641     //free pdacl
642     OicSecPdAcl_t* acl = g_pconf.pdacls;
643     if (acl)
644     {
645         /* Clean Resources */
646         for (unsigned int i = 0; i < (acl)->resourcesLen; i++)
647         {
648             OICFree((acl)->resources[i]);
649         }
650         OICFree((acl)->resources);
651
652         /* Clean ACL node itself */
653         /* Required only if acl was created in heap */
654         OICFree((acl));
655     }
656     memset(&g_pconf, 0, sizeof(OicSecPconf_t));
657 }
658
659 static OicSecPdAcl_t* InputPdACL()
660 {
661     int ret;
662     char *temp_rsc, *temp_pms;
663
664     printf("******************************************************************************\n");
665     printf("-Set ACL policy for target DP device\n");
666     printf("******************************************************************************\n");
667
668     OicSecPdAcl_t *acl = (OicSecPdAcl_t *)OICCalloc(1,sizeof(OicSecPdAcl_t));
669     if (NULL == acl)
670     {
671         OIC_LOG(ERROR, TAG, "Error while memory allocation");
672         return NULL;
673     }
674
675     //Set Resource.
676     printf("Num. of Resource : ");
677     ret = scanf("%zu", &acl->resourcesLen);
678     if ((1 != ret) || (acl->resourcesLen <= 0 || acl->resourcesLen > 50))
679     {
680         printf("Error while input\n");
681         OICFree(acl);
682         return NULL;
683     }
684     printf("-URI of resource\n");
685     printf("ex)/oic/sh/temp/0 (Max_URI_Length: %d Byte )\n", MAX_URI_LENGTH);
686     acl->resources = (char **)OICCalloc(acl->resourcesLen, sizeof(char *));
687     if (NULL == acl->resources)
688     {
689         OIC_LOG(ERROR, TAG, "Error while memory allocation");
690         OICFree(acl);
691         return NULL;
692     }
693     for (size_t i = 0; i < acl->resourcesLen; i++)
694     {
695         printf("[%zu]Resource : ", i + 1);
696         ret = scanf("%64ms", &temp_rsc);
697         if (1 != ret)
698         {
699             printf("Error while input\n");
700             OICFree(acl->resources);
701             OICFree(acl);
702             return NULL;
703         }
704
705         acl->resources[i] = OICStrdup(temp_rsc);
706         OICFree(temp_rsc);
707         if (NULL == acl->resources[i])
708         {
709             OIC_LOG(ERROR, TAG, "Error while memory allocation");
710             OICFree(acl->resources);
711             OICFree(acl);
712             return NULL;
713         }
714     }
715
716     // Set Permission
717     do
718     {
719         printf("-Set the permission(C,R,U,D,N)\n");
720         printf("ex) CRUDN, CRU_N,..(5 Charaters)\n");
721         printf("Permission : ");
722         ret = scanf("%5ms", &temp_pms);
723         if (1 != ret)
724         {
725             printf("Error while input\n");
726             OICFree(acl->resources);
727             OICFree(acl);
728             return NULL;
729         }
730         ret = CalculateAclPermission(temp_pms, &(acl->permission));
731         OICFree(temp_pms);
732     } while (0 != ret );
733
734     return acl;
735 }
736
737 void provisionDirectPairingCB(PMResultList_t *result, int hasError)
738 {
739     if (hasError)
740     {
741         std::cout << "Error in provisioning operation!"<<std::endl;
742     }
743     else
744     {
745         std::cout<< "\nReceived provisioning results: Direct Pairing is successful ";
746         for (unsigned int i = 0; i < result->size(); i++)
747         {
748             std::cout << "Result is = " << result->at(i).res <<" for device ";
749             printUuid(result->at(i).deviceId);
750         }
751
752         delete result;
753     }
754     deletePconf();
755     printMenu();
756     ask = 1;
757 }
758
759 static void provisionDP(int dev_num)
760 {
761     OCStackResult rst;
762     std::string pin("");
763
764     // set enable dp
765     g_pconf.edp = true;
766
767     // set default supported PRM types
768     g_pconf.prmLen = sizeof(SUPPORTED_PRMS)/sizeof(OicSecPrm_t);
769     g_pconf.prm = (OicSecPrm_t *)OICCalloc(g_pconf.prmLen, sizeof(OicSecPrm_t));
770     if(g_pconf.prm)
771     {
772         for (size_t i=0; i < g_pconf.prmLen; i++)
773         {
774             g_pconf.prm[i] = SUPPORTED_PRMS[i];
775         }
776     }
777     else
778     {
779         OIC_LOG(ERROR, TAG, "create prm error return");
780         goto PVDP_ERROR;
781     }
782
783     std::cout << "Enter PIN to be configured: ";
784     while (1)
785     {
786         std::cin >> pin;
787         if (pin.length() == DP_PIN_LENGTH)
788         {
789             break;
790         }
791         else
792         {
793             std::cout << "PIN length should be 8, Enter again: ";
794         }
795     }
796
797     memcpy(g_pconf.pin.val, pin.c_str(), DP_PIN_LENGTH);
798
799     // set default pdacl
800
801     g_pconf.pdacls = InputPdACL();
802     if(!g_pconf.pdacls)
803     {
804         OIC_LOG(ERROR, TAG, "InputPdACL error return");
805         goto PVDP_ERROR;
806     }
807
808     // call |OCProvisionDirectPairing| API actually
809     // calling this API with callback actually acts like blocking
810     // for error checking, the return value saved and printed
811     rst = pOwnedDevList[dev_num-1]->provisionDirectPairing(&g_pconf, provisionDirectPairingCB);
812     if(OC_STACK_OK != rst)
813     {
814         OIC_LOG_V(ERROR, TAG, "OCProvisionDirectPairing API error: %d", rst);
815         if (OC_STACK_UNAUTHORIZED_REQ == rst)
816         {
817             OIC_LOG(ERROR, TAG, "Target Server NOT Support Direct-Pairing !!! (DPC == false)");
818         }
819         goto PVDP_ERROR;
820     }
821     return;
822
823 PVDP_ERROR:
824     deletePconf();  // after here |acl| points nothing
825     ask = 1;
826 }
827
828 OCStackResult displayMutualVerifNumCB(uint8_t mutualVerifNum[MUTUAL_VERIF_NUM_LEN])
829 {
830     OIC_LOG(INFO, TAG, "IN displayMutualVerifNumCB");
831     OIC_LOG(INFO, TAG, "############ mutualVerifNum ############");
832     OIC_LOG_BUFFER(INFO, TAG, mutualVerifNum, MUTUAL_VERIF_NUM_LEN);
833     OIC_LOG(INFO, TAG, "############ mutualVerifNum ############");
834     OIC_LOG(INFO, TAG, "OUT displayMutualVerifNumCB");
835     return OC_STACK_OK;
836 }
837
838 OCStackResult confirmMutualVerifNumCB(void)
839 {
840     for (;;)
841     {
842         int userConfirm;
843
844         printf("   > Press 1 if the mutual verification numbers are the same\n");
845         printf("   > Press 0 if the mutual verification numbers are not the same\n");
846
847         for (int ret=0; 1!=ret; )
848         {
849             ret = scanf("%d", &userConfirm);
850             for (; 0x20<=getchar(); );  // for removing overflow garbage
851                                         // '0x20<=code' is character region
852         }
853         if (1 == userConfirm)
854         {
855             break;
856         }
857         else if (0 == userConfirm)
858         {
859             return OC_STACK_USER_DENIED_REQ;
860         }
861         printf("   Entered Wrong Number. Please Enter Again\n");
862     }
863     return OC_STACK_OK;
864 }
865
866
867
868
869 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
870 static int saveTrustCert(void)
871 {
872
873     // call |OCSaveTrustCertChainBin| API actually
874     printf("   Save Trust Cert. Chain into Cred of SVR.\n");
875
876     ByteArray trustCertChainArray = {0, 0};
877
878     FILE *fp = fopen("rootca.crt", "rb+");
879
880     if (fp)
881     {
882         int fsize;
883         if (fseeko(fp, 0, SEEK_END) == 0 && (fsize = ftello(fp)) >= 0)
884         {
885             trustCertChainArray.data = (uint8_t*)OICCalloc(1, fsize);
886             trustCertChainArray.len = fsize;
887             if (NULL == trustCertChainArray.data)
888             {
889                 OIC_LOG(ERROR,TAG,"Failed to allocate memory");
890                 fclose(fp);
891                 return -1;
892             }
893             rewind(fp);
894             fsize = fread(trustCertChainArray.data, 1, fsize, fp);
895             if(0 == fsize)
896             {
897                 OIC_LOG(ERROR,TAG,"Read error");
898             }
899         }
900         fclose(fp);
901     }
902     OIC_LOG_BUFFER(DEBUG, TAG, trustCertChainArray.data, trustCertChainArray.len);
903
904     if(OC_STACK_OK != OCSecure::saveTrustCertChain(trustCertChainArray.data, trustCertChainArray.len,
905                         OIC_ENCODING_PEM,&g_credId))
906     {
907         OIC_LOG(ERROR, TAG, "OCSaveTrustCertChainBin API error");
908         return -1;
909     }
910     printf("CredId of Saved Trust Cert. Chain into Cred of SVR : %d.\n", g_credId);
911
912     return 0;
913 }
914
915 void certChainCallBack(uint16_t credId, uint8_t *trustCertChain,size_t chainSize)
916 {
917     OIC_LOG_V(INFO, TAG, "trustCertChain Changed for credId %u", credId);
918     OC_UNUSED(trustCertChain);
919     OC_UNUSED(chainSize);
920     return;
921 }
922 #endif // __WITH_DTLS__ or __WITH_TLS__
923
924 #ifdef MULTIPLE_OWNER
925 void MOTMethodCB(PMResultList_t *result, int hasError)
926 {
927     if (hasError)
928     {
929         std::cout << "Error!!! in callback"<<std::endl;
930     }
931     else
932     {
933         std::cout<< "callback successfull"<<std::endl;
934         delete result;
935     }
936 }
937
938 void MOTRemoveSubOwnerCB(PMResultList_t *result, int hasError)
939 {
940     if (hasError)
941     {
942         std::cout << "Error!!! in callback"<<std::endl;
943     }
944     else
945     {
946         std::cout<< "callback successfull"<<std::endl;
947         delete result;
948     }
949 }
950
951 #endif // MULTIPLE_OWNER
952
953 int main(void)
954 {
955     OCStackResult result;
956     OCPersistentStorage ps {client_open, fread, fwrite, fclose, unlink, NULL, NULL};
957
958     // Create PlatformConfig object
959     PlatformConfig cfg {
960         OC::ServiceType::InProc,
961             OC::ModeType::Both,
962             "0.0.0.0",
963             0,
964             OC::QualityOfService::LowQos,
965             &ps
966     };
967
968     OCPlatform::Configure(cfg);
969
970     try
971     {
972         int choice;
973         OicSecAcl_t *acl1 = nullptr, *acl2 = nullptr;
974         if (OCSecure::provisionInit("") != OC_STACK_OK)
975         {
976             std::cout <<"PM Init failed"<< std::endl;
977             return 1;
978         }
979
980         result = OCSecure::registerDisplayNumCallback(displayMutualVerifNumCB);
981         if (result != OC_STACK_OK)
982         {
983             std::cout<< "!!Error - setDisplayVerifNumCB failed."<<std::endl;
984         }
985
986         result = OCSecure::registerUserConfirmCallback(confirmMutualVerifNumCB);
987         if (result != OC_STACK_OK)
988         {
989             std::cout<< "!!Error - setConfirmVerifNumCB failed."<<std::endl;
990         }
991
992         OCSecure::setPeerCertCallback(peerCertCallback);
993
994         for (int out = 0; !out;)
995         {
996             while (!ask)
997             {
998                 sleep(1);
999             }
1000
1001             if (acl1)
1002             {
1003                 deleteACL(acl1);
1004                 acl1 = nullptr;
1005             }
1006
1007             if (acl2)
1008             {
1009                 deleteACL(acl2);
1010                 acl2 = nullptr;
1011             }
1012
1013             printMenu();
1014             std::cin >> choice;
1015             switch(choice) {
1016                 case 1:
1017                     {
1018                         //Secure resource discovery.
1019
1020                         pUnownedDevList.clear();
1021                         std::cout << "Started discovery..." <<std::endl;
1022                         OCStackResult result = OCSecure::discoverUnownedDevices(DISCOVERY_TIMEOUT,
1023                                 pUnownedDevList);
1024                         if (result != OC_STACK_OK)
1025                         {
1026                             std::cout<< "!!Error - UnOwned Discovery failed."<<std::endl;
1027                         }
1028                         else if (pUnownedDevList.size())
1029                         {
1030                             std::cout <<"Found secure devices, count = " <<
1031                                 pUnownedDevList.size() << std::endl;
1032                             printDevices(pUnownedDevList);
1033                         }
1034                         else
1035                         {
1036                             std::cout <<"No Secure devices found"<<std::endl;
1037                         }
1038                         break;
1039                     }
1040                 case 2:
1041                     {
1042                         pOwnedDevList.clear();
1043                         std::cout << "Started discovery..." <<std::endl;
1044                         OCStackResult result = OCSecure::discoverOwnedDevices(DISCOVERY_TIMEOUT,
1045                                 pOwnedDevList);
1046                         if (result != OC_STACK_OK)
1047                         {
1048                             std::cout<< "!!Error - Owned Discovery failed."<<std::endl;
1049                         }
1050                         else if (pOwnedDevList.size())
1051                         {
1052                             std::cout <<"Found owned devices, count = " <<
1053                                 pOwnedDevList.size() << std::endl;
1054                             printDevices(pOwnedDevList);
1055                         }
1056                         else
1057                         {
1058                             std::cout <<"No Secure devices found"<<std::endl;
1059                         }
1060                         break;
1061                     }
1062                 case 3:
1063                     {
1064                         unsigned int devNum;
1065
1066                         if (!pUnownedDevList.size())
1067                         {
1068                             std::cout <<"There are no more Unowned devices"<<std::endl;
1069                             break;
1070                         }
1071
1072                         for (unsigned int i = 0; i < pUnownedDevList.size(); i++ )
1073                         {
1074                             std::cout << i+1 << ": "<< pUnownedDevList[i]->getDeviceID();
1075                             std::cout << " From IP:" << pUnownedDevList[i]->getDevAddr() <<std::endl;
1076                         }
1077
1078                         std::cout <<"Select device number: "<<std::endl;
1079                         std::cin >> devNum;
1080                         if (devNum > pUnownedDevList.size())
1081                         {
1082                             std::cout <<"Invalid device number"<<std::endl;
1083                             break;
1084                         }
1085                         transferDevIdx = devNum - 1;
1086
1087                         //register callbacks for JUST WORKS and PIN methods
1088                         std::cout <<"Registering OTM Methods: 1. JUST WORKS and 2. PIN"<<std::endl;
1089                         OCSecure::setInputPinCallback(InputPinCB);
1090
1091                         ask = 0;
1092                         std::cout << "Transfering ownership for : "<<
1093                             pUnownedDevList[devNum-1]->getDeviceID()<<std::endl;
1094                         if (pUnownedDevList[devNum-1]->doOwnershipTransfer(ownershipTransferCB)
1095                                 != OC_STACK_OK)
1096                         {
1097                             std::cout<<"OwnershipTransferCallback is failed"<<std::endl;
1098                             ask = 1;
1099                         }
1100                         break;
1101                     }
1102                 case 4: //Provision ACL
1103                     {
1104                         int index;
1105
1106                         if (0 != readDeviceNumber(pOwnedDevList, 1, &index)) break;
1107
1108                         std::cout << "Provision ACL for : "<<
1109                             pOwnedDevList[index]->getDeviceID()<< std::endl;
1110
1111                         acl1 = (OicSecAcl_t *)OICCalloc(1,sizeof(OicSecAcl_t));
1112                         if (NULL == acl1)
1113                         {
1114                             OIC_LOG(ERROR, TAG, "Error while memory allocation");
1115                             break;
1116                         }
1117
1118                         std::cout << "Please input ACL for selected device: " << std::endl;
1119                         if (0 != InputACL(acl1))
1120                         {
1121                             break;
1122                         }
1123
1124                         ask = 0;
1125
1126                         if (pOwnedDevList[index]->provisionACL(acl1, provisionCB) != OC_STACK_OK)
1127                         {
1128                             ask = 1;
1129                             std::cout <<"provisionACL is failed"<< std::endl;
1130                         }
1131                     }
1132                     break;
1133                 case 5: //Provision Credentials
1134                     {
1135                         int devices[2];
1136
1137                         if (0 != readDeviceNumber(pOwnedDevList, 2, devices)) break;
1138
1139                         int first  = devices[0];
1140                         int second = devices[1];
1141
1142                         std::cout << "Provision Credentials to devices: "<<
1143                             pOwnedDevList[first]->getDeviceID();
1144                         std::cout << " and "<< pOwnedDevList[second]->getDeviceID() << std::endl;
1145
1146                         Credential cred( NO_SECURITY_MODE ,0);
1147                         std::cout << "Please input credentials for selected devices: " << std::endl;
1148                         if (0 != InputCredentials(cred))
1149                             break;
1150
1151                         ask = 0;
1152
1153                         if (pOwnedDevList[first]->provisionCredentials(cred,
1154                                     *pOwnedDevList[second].get(), provisionCB) != OC_STACK_OK)
1155                         {
1156                             ask = 1;
1157                             std::cout <<"provisionCredentials is failed"<< std::endl;
1158                         }
1159                     }
1160                     break;
1161                 case 6: //Provision ACL & Creds b/w two devices.
1162                     {
1163                         int devices[2];
1164
1165                         if (0 != readDeviceNumber(pOwnedDevList, 2, devices)) break;
1166
1167                         int first  = devices[0];
1168                         int second = devices[1];
1169
1170                         std::cout << "Provision pairwise devices: "<<
1171                             pOwnedDevList[first]->getDeviceID();
1172                         std::cout << " and "<< pOwnedDevList[second]->getDeviceID() << std::endl;
1173
1174                         Credential cred( NO_SECURITY_MODE, 0);
1175                         std::cout << "Please input credentials for selected devices: " << std::endl;
1176                         if (0 != InputCredentials(cred))
1177                             break;
1178
1179                         acl1 = (OicSecAcl_t *)OICCalloc(1,sizeof(OicSecAcl_t));
1180                         if (NULL == acl1)
1181                         {
1182                             OIC_LOG(ERROR, TAG, "Error while memory allocation");
1183                             break;
1184                         }
1185
1186                         std::cout << "Please input ACL for selected device: " << std::endl;
1187                         if (0 != InputACL(acl1))
1188                         {
1189                             break;
1190                         }
1191
1192                         acl2 = (OicSecAcl_t *)OICCalloc(1,sizeof(OicSecAcl_t));
1193                         if (NULL == acl2)
1194                         {
1195                             OIC_LOG(ERROR, TAG, "Error while memory allocation");
1196                             break;
1197                         }
1198
1199                         std::cout << "Please input ACL for selected device: " << std::endl;
1200                         if (0 != InputACL(acl2))
1201                         {
1202                             break;
1203                         }
1204
1205                         ask = 0;
1206
1207                         if (pOwnedDevList[first]->provisionPairwiseDevices(cred, acl1,
1208                                     *pOwnedDevList[second].get(), acl2, provisionCB) != OC_STACK_OK)
1209                         {
1210                             ask = 1;
1211                             std::cout <<"provisionPairwiseDevices is failed"<< std::endl;
1212                         }
1213                     }
1214                     break;
1215                 case 7: //Unlink Devices
1216                     {
1217                         int devices[2];
1218
1219                         if (0 != readDeviceNumber(pOwnedDevList, 2, devices)) break;
1220
1221                         int first  = devices[0];
1222                         int second = devices[1];
1223
1224                         std::cout << "Unlink devices: "<< pOwnedDevList[first]->getDeviceID();
1225                         std::cout << " and "<< pOwnedDevList[second]->getDeviceID() << std::endl;
1226
1227                         ask = 0;
1228
1229                         if (pOwnedDevList[first]->unlinkDevices(*pOwnedDevList[second].get(),
1230                                     provisionCB) != OC_STACK_OK)
1231                         {
1232                             ask = 1;
1233                             std::cout <<"unlinkDevice is failed"<< std::endl;
1234                         }
1235                         break;
1236                     }
1237                 case 8: //Remove Device
1238                     {
1239                         int index;
1240
1241                         if (0 != readDeviceNumber(pOwnedDevList, 1, &index)) break;
1242
1243                         std::cout << "Remove Device: "<< pOwnedDevList[index]->getDeviceID()<< std::endl;
1244
1245                         ask = 0;
1246
1247                         if (pOwnedDevList[index]->removeDevice(DISCOVERY_TIMEOUT, provisionCB)
1248                                 != OC_STACK_OK)
1249                         {
1250                             ask = 1;
1251                             std::cout <<"removeDevice is failed"<< std::endl;
1252                         }
1253                         break;
1254                     }
1255                 case 9: //Remove Device using UUID
1256                     {
1257                         int index;
1258
1259                         if (0 != readDeviceNumber(pOwnedDevList, 1, &index)) break;
1260
1261                         std::cout << "Remove Device: "<< pOwnedDevList[index]->getDeviceID()<< std::endl;
1262
1263                         ask = 0;
1264
1265                         if (OCSecure::removeDeviceWithUuid(DISCOVERY_TIMEOUT,
1266                                                                        pOwnedDevList[index]->getDeviceID(),
1267                                                                        provisionCB)
1268                                 != OC_STACK_OK)
1269                         {
1270                             ask = 1;
1271                             std::cout <<"removeDevice is failed"<< std::endl;
1272                         }
1273                         break;
1274                     }
1275
1276                 case 10: //Get Linked devices
1277                     {
1278                         UuidList_t linkedUuid;
1279                         unsigned int devNum;
1280
1281                         if (!pOwnedDevList.size())
1282                         {
1283                             std::cout <<"There are no Owned devices yet,"
1284                                 " may need to discover"<<std::endl;
1285                             break;
1286                         }
1287
1288                         for (unsigned int i = 0; i < pOwnedDevList.size(); i++ )
1289                         {
1290                             std::cout << i+1 << ": "<< pOwnedDevList[i]->getDeviceID() <<" From IP:";
1291                             std::cout << pOwnedDevList[i]->getDevAddr() <<std::endl;
1292                         }
1293
1294                         std::cout <<"Select device number: "<<std::endl;
1295                         std::cin >> devNum;
1296                         if (devNum > pOwnedDevList.size())
1297                         {
1298                             std::cout <<"Invalid device number"<<std::endl;
1299                             break;
1300                         }
1301
1302                         if(pOwnedDevList[devNum  -1]->getLinkedDevices(linkedUuid) == OC_STACK_OK)
1303                         {
1304                             if (!linkedUuid.size())
1305                             {
1306                                 std::cout <<"No devices are linked to "<<
1307                                     pOwnedDevList[devNum  -1]->getDeviceID() << std::endl;
1308                             }
1309                             //display the Linked devices (UUIDs)
1310                             for(unsigned int i = 0; i < linkedUuid.size(); i++)
1311                             {
1312                                 printUuid(linkedUuid[i]);
1313                             }
1314                         }
1315                         else
1316                         {
1317                             std::cout <<"Error! in getLinkedDevices"<<std::endl;
1318                         }
1319                         break;
1320                     }
1321                 case 11: //Get device' status
1322                     {
1323                         DeviceList_t unownedList, ownedList;
1324
1325                         if (OCSecure::getDevInfoFromNetwork(DISCOVERY_TIMEOUT, ownedList,
1326                                     unownedList) == OC_STACK_OK)
1327                         {
1328                             std::cout <<"Owned Device' status for" <<std::endl;
1329                             for (unsigned int i = 0; i < ownedList.size(); i++ )
1330                             {
1331                                 std::cout << "Device "<<i+1 <<" ID: '";
1332                                 std::cout << ownedList[i]->getDeviceID() << "' From IP: ";
1333                                 std::cout << ownedList[i]->getDevAddr() << " Status: ";
1334                                 printStatus(ownedList[i]->getDeviceStatus());
1335                             }
1336                             std::cout <<"\nUnOwned Device' status for" <<std::endl;
1337                             for (unsigned int i = 0; i < unownedList.size(); i++ )
1338                             {
1339                                 std::cout << "Device "<<i+1 <<" ID: '";
1340                                 std::cout << unownedList[i]->getDeviceID() << "' From IP: ";
1341                                 std::cout << unownedList[i]->getDevAddr() << " Status: ";
1342                                 printStatus(unownedList[i]->getDeviceStatus());
1343                             }
1344
1345                         }
1346                         break;
1347                     }
1348
1349                 case 12:
1350                     {
1351                         unsigned int devNum;
1352
1353                         if (!pOwnedDevList.size())
1354                         {
1355                             std::cout <<"There are no Owned devices yet,"
1356                                 " may need to discover"<<std::endl;
1357                             break;
1358                         }
1359
1360                         for (unsigned int i = 0; i < pOwnedDevList.size(); i++ )
1361                         {
1362                             std::cout << i+1 << ": "<< pOwnedDevList[i]->getDeviceID() <<" From IP:";
1363                             std::cout << pOwnedDevList[i]->getDevAddr() <<std::endl;
1364                         }
1365
1366                         std::cout <<"Select device number: "<<std::endl;
1367                         std::cin >> devNum;
1368                         if (devNum > pOwnedDevList.size())
1369                         {
1370                             std::cout <<"Invalid device number"<<std::endl;
1371                             break;
1372                         }
1373
1374                         ask = 0;
1375                         provisionDP(devNum);
1376
1377                         break;
1378                     }
1379 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
1380                 case 13:
1381                     {
1382                         std::cout<< "registering cert chain change notifier"<<std::endl;
1383                         OCSecure::registerTrustCertChangeNotifier(certChainCallBack);
1384                         if(saveTrustCert())
1385                         {
1386                             std::cout<<"Error in saving cert"<<std::endl;
1387                         }
1388                         std::cout<< "Unregister notifier"<<std::endl;
1389                         OCSecure::removeTrustCertChangeNotifier();
1390                         break;
1391                     }
1392                 case 14:
1393                     {
1394                         int index;
1395
1396                         if (0 != readDeviceNumber(pOwnedDevList, 1, &index)) break;
1397
1398                         std::cout << "Provision cert for : "<<
1399                             pOwnedDevList[index]->getDeviceID()<< std::endl;
1400
1401                         ask = 0;
1402
1403                         if (pOwnedDevList[index]->provisionTrustCertChain(SIGNED_ASYMMETRIC_KEY,
1404                                                                     g_credId,provisionCB ) != OC_STACK_OK)
1405                         {
1406                             ask = 1;
1407                             std::cout <<"provision cert is failed"<< std::endl;
1408                         }
1409                         break;
1410                     }
1411                 case 15:
1412                     {
1413                         if (0==g_credId)
1414                         {
1415                             std::cout<<"please save cert using option 13.";
1416                         }
1417                         else
1418                         {
1419                             uint8_t *trustCertChain = NULL;
1420                             size_t chainSize = 0;
1421                             if (OC_STACK_OK != OCSecure::readTrustCertChain(g_credId, &trustCertChain,&chainSize))
1422                             {
1423                                 std::cout <<"issue in read trust chain"<< std::endl;
1424                             }
1425                             else
1426                             {
1427                                 std::cout<<"size of cert : "<<chainSize<<std::endl;
1428                             }
1429                         }
1430                         break;
1431                     }
1432 #endif //__WITH_DTLS__ || __WITH_TLS__
1433 #ifdef MULTIPLE_OWNER
1434                  case 16:
1435                     {
1436                         if (!pOwnedDevList.size() && !pMOTEnabledDeviceList.size())
1437                         {
1438                             std::cout <<"Owned device list and MOT device list both are empty."<<std::endl;
1439                             break;
1440                         }
1441                         unsigned int dev_count = 0;
1442                         if (pOwnedDevList.size())
1443                         {
1444                             dev_count = pOwnedDevList.size();
1445                             printDevices(pOwnedDevList);
1446                         }
1447
1448                         if (pMOTEnabledDeviceList.size())
1449                         {
1450                             dev_count += pMOTEnabledDeviceList.size();
1451                             for (unsigned int i = 0; i < pMOTEnabledDeviceList.size(); i++ )
1452                             {
1453                                 std::cout << "Device ";
1454                                 std::cout <<((dev_count - pMOTEnabledDeviceList.size())+ i + 1) ;
1455                                 std::cout <<" ID : ";
1456                                 std::cout << pMOTEnabledDeviceList[i]->getDeviceID()<<" From IP: ";
1457                                 std::cout << pMOTEnabledDeviceList[i]->getDevAddr() << std::endl;
1458                             }
1459                         }
1460
1461                         // select device
1462                         unsigned int dev_num = 0;
1463                         for( ; ; )
1464                         {
1465                             std::cout << "Enter Device Number, to change the mode: "<<std::endl;
1466                             std::cin >> dev_num;
1467                             if(0 < dev_num && dev_count >= dev_num)
1468                             {
1469                                 break;
1470                             }
1471                             std::cout << "   Entered Wrong Number. Please Enter Again"<<std::endl;
1472                         }
1473
1474                         OicSecMomType_t momType = OIC_MULTIPLE_OWNER_ENABLE;
1475                         int mom = 0;
1476                         for( ; ; )
1477                         {
1478                             std::cout <<"   0. Disable Multiple Ownership Transfer"<<std::endl;
1479                             std::cout <<"   1. Enable Multiple Ownership Transfer "<<std::endl;
1480                             std::cout <<"> Enter Mode of Multiple Ownership Transfer :"<<std::endl;
1481                             for(int ret=0; 1!=ret; )
1482                             {
1483                                 ret = scanf("%d", &mom);
1484                                 for( ; 0x20<=getchar(); );  // for removing overflow garbages
1485                                                             // '0x20<=code' is character region
1486                             }
1487                             if(mom == 0)
1488                             {
1489                                 momType = OIC_MULTIPLE_OWNER_DISABLE;
1490                                 break;
1491                             }
1492                             if(mom == 1)
1493                             {
1494                                 momType = OIC_MULTIPLE_OWNER_ENABLE;
1495                                 break;
1496                             }
1497                             std::cout <<"     Entered Wrong Number. Please Enter Again"<<std::endl;
1498                         }
1499
1500                         if (!pOwnedDevList.size())
1501                         {
1502                             if(OC_STACK_OK != pMOTEnabledDeviceList[dev_num-1]->changeMOTMode(
1503                             (const OicSecMomType_t)momType,MOTMethodCB))
1504                             {
1505                                 OIC_LOG(ERROR, TAG, "changeMOTMode API error");
1506                             }
1507                         }
1508                         else
1509                         {
1510                             if(dev_num <= pOwnedDevList.size())
1511                             {
1512                                 if(OC_STACK_OK != pOwnedDevList[dev_num-1]->changeMOTMode(momType,
1513                                 MOTMethodCB))
1514                                 {
1515                                     OIC_LOG(ERROR, TAG, "changeMOTMode API error");
1516                                 }
1517                             }
1518                             else
1519                             {
1520                                 if(OC_STACK_OK != pMOTEnabledDeviceList[(dev_num -
1521                                 pOwnedDevList.size() - 1)]->changeMOTMode(momType,
1522                                 MOTMethodCB))
1523                                 {
1524                                     OIC_LOG(ERROR, TAG, "changeMOTMode API error");
1525                                 }
1526                             }
1527                         }
1528                          break;
1529                     }
1530                 case 17:
1531                     {
1532                         if (!pMOTEnabledDeviceList.size())
1533                         {
1534                             std::cout <<"Please discover the MOT device first. Use option 18"<<std::endl;
1535                             break;
1536                         }
1537
1538                         printDevices(pMOTEnabledDeviceList);
1539                         // select device
1540                         unsigned int dev_num = 0;
1541                         for( ; ; )
1542                         {
1543                             std::cout << "Enter Device Number, for MOT Device: "<<std::endl;
1544                             std::cin >> dev_num;
1545                             if(0 < dev_num &&  pMOTEnabledDeviceList.size() >=dev_num)
1546                             {
1547                                 break;
1548                             }
1549                                               std::cout << "     Entered Wrong Number. Please Enter Again"<<std::endl;
1550                         }
1551
1552                         int oxm = 0;
1553                         OicSecOxm_t secOxm = OIC_PRECONFIG_PIN;
1554                         std::cout << "Select method for  Multiple Ownership Transfer: "<<std::endl;
1555                         for( ; ; )
1556                         {
1557                             std::cout << "  0. Random PIN OxM "<<std::endl;
1558                             std::cout << "  1. Pre-Configured PIN OxM "<<std::endl;
1559                             std::cout << "   > Enter Number of  OxM for Multiple Ownership Transfer : "<<std::endl;
1560                             std::cin >> oxm;
1561                             if(0 == oxm)
1562                             {
1563                                 secOxm = OIC_RANDOM_DEVICE_PIN;
1564                                 break;
1565                             }
1566                             if(1 == oxm)
1567                             {
1568                                 secOxm = OIC_PRECONFIG_PIN;
1569                                 break;
1570                             }
1571                             std::cout << "     Entered Wrong Number. Please Enter Again"<<std::endl;
1572                         }
1573
1574                         if(OC_STACK_OK != pMOTEnabledDeviceList[dev_num-1]->selectMOTMethod((const OicSecOxm_t)secOxm,
1575                                               MOTMethodCB))
1576                         {
1577                             OIC_LOG(ERROR, TAG, "selectMOTMethod API error");
1578                         }
1579                          break;
1580                     }
1581                 case 18:
1582                     {
1583                         pMOTEnabledDeviceList.clear();
1584                         std::cout << "Started MOT Enabled device discovery..." <<std::endl;
1585                         OCStackResult result = OCSecure::discoverMultipleOwnerEnabledDevices
1586                             (DISCOVERY_TIMEOUT, pMOTEnabledDeviceList);
1587                         if (result != OC_STACK_OK)
1588                         {
1589                             std::cout<< "!!Error - MOT Enabled dev Discovery failed."<<std::endl;
1590                         }
1591                         else if (pMOTEnabledDeviceList.size())
1592                         {
1593                             std::cout <<"Found MOT enabled devices, count = " <<
1594                                 pMOTEnabledDeviceList.size() << std::endl;
1595                             printDevices(pMOTEnabledDeviceList);
1596                         }
1597                         else
1598                         {
1599                             std::cout <<"No MOT enabled Secure devices found"<<std::endl;
1600                         }
1601                         break;
1602                     }
1603                 case 19:
1604                     {
1605                         if (!pMOTEnabledDeviceList.size())
1606                         {
1607                             std::cout <<"Please discover the MOT device first. Use option 16"<<std::endl;
1608                             break;
1609                         }
1610
1611                         printDevices(pMOTEnabledDeviceList);
1612                         // select device
1613                         unsigned int dev_num = 0;
1614                         for( ; ; )
1615                         {
1616                             std::cout << "Enter Device Number, for MOT Device: "<<std::endl;
1617                             std::cin >> dev_num;
1618                             if(0 < dev_num && pMOTEnabledDeviceList.size() >=dev_num)
1619                             {
1620                                 break;
1621                             }
1622                             std::cout << "     Entered Wrong Number. Please Enter Again"<<std::endl;
1623                         }
1624
1625                         char preconfigPin[9] = {0};
1626                         std::cout << "   > Input the 8 digit PreconfigPin (e.g. 12341234) :" <<std::endl;
1627                         for(int ret=0; 1!=ret; )
1628                         {
1629                             ret = scanf("%8s", preconfigPin);
1630                             for( ; 0x20<=getchar(); );  // for removing overflow garbages
1631                                                         // '0x20<=code' is character region
1632                         }
1633                         size_t preconfPinLength = strlen(preconfigPin);
1634                         if(OC_STACK_OK != pMOTEnabledDeviceList[dev_num-1]->provisionPreconfPin(preconfigPin,
1635                             preconfPinLength, MOTMethodCB))
1636                         {
1637                             OIC_LOG(ERROR, TAG, "provisionPreconfPin API error");
1638                         }
1639                         break;
1640                     }
1641                     case 20:
1642                     {
1643                         if (!pMOTEnabledDeviceList.size())
1644                         {
1645                             std::cout <<"Please discover the MOT device first. Use option 16"<<std::endl;
1646                             break;
1647                         }
1648
1649                         printDevices(pMOTEnabledDeviceList);
1650                         // select device
1651                         unsigned int dev_num = 0;
1652                         for( ; ; )
1653                         {
1654                             std::cout << "Enter Device Number, for MOT Device: "<<std::endl;
1655                             std::cin >> dev_num;
1656                             if(0 < dev_num && pMOTEnabledDeviceList.size() >=dev_num)
1657                             {
1658                                 break;
1659                             }
1660                             std::cout << "     Entered Wrong Number. Please Enter Again"<<std::endl;
1661                         }
1662
1663                         char preconfPIN[9] = {0};
1664                         std::cout << "   > Input the 8 digit preconfPIN (e.g. 12341234) :" <<std::endl;
1665                         for(int ret=0; 1!=ret; )
1666                         {
1667                             ret = scanf("%8s", preconfPIN);
1668                             for( ; 0x20<=getchar(); );  // for removing overflow garbages
1669                                                         // '0x20<=code' is character region
1670                         }
1671                         size_t preconfPinLength = strlen(preconfPIN);
1672                         if(OC_STACK_OK != pMOTEnabledDeviceList[dev_num-1]->addPreconfigPIN(preconfPIN,
1673                             preconfPinLength))
1674                         {
1675                             OIC_LOG(ERROR, TAG, "addPreconfigPIN API error");
1676                         }
1677                         break;
1678                     }
1679                     case 21: //Remove sub-owner
1680                     {
1681                         if (!pMOTEnabledDeviceList.size())
1682                         {
1683                             std::cout <<"Please discover the MOT device first. Use option 16"<<std::endl;
1684                             break;
1685                         }
1686
1687                         printDevices(pMOTEnabledDeviceList);
1688                         // select device
1689                         unsigned int dev_num = 0;
1690                         for( ; ; )
1691                         {
1692                             std::cout << "Enter Device Number, for MOT Device: "<<std::endl;
1693                             std::cin >> dev_num;
1694                             if(0 < dev_num && pMOTEnabledDeviceList.size() >=dev_num)
1695                             {
1696                                 break;
1697                             }
1698                             std::cout << "     Entered Wrong Number. Please Enter Again"<<std::endl;
1699                         }
1700
1701                         UuidList_t subOwenrList;
1702                         pMOTEnabledDeviceList[dev_num - 1]->getSubOwnerList(subOwenrList);
1703                         if (0 == subOwenrList.size())
1704                         {
1705                             std::cout << "SubOwner List is empty."<<std::endl;
1706                         }
1707                         else
1708                         {
1709                             //display the Linked devices (UUIDs)
1710                             for(unsigned int i = 0; i < subOwenrList.size(); i++)
1711                             {
1712                                 printUuid(subOwenrList[i]);
1713                             }
1714                         }
1715                         unsigned int so_num = 0;
1716                         for( ; ; )
1717                         {
1718                             std::cout << "Enter SubOwner Number to be Removed: "<<std::endl;
1719                             std::cin >> so_num;
1720                             if(0 < so_num && subOwenrList.size() >=so_num)
1721                             {
1722                                 pMOTEnabledDeviceList[dev_num - 1]->removeSubOwner(&subOwenrList[so_num], MOTRemoveSubOwnerCB);
1723                                 break;
1724                             }
1725                             std::cout << "     Entered Wrong Number. Please Enter Again"<<std::endl;
1726                         }
1727
1728                         break;
1729                     }
1730                     case 22: //Remove all sub-owner
1731                     {
1732                         if (!pMOTEnabledDeviceList.size())
1733                         {
1734                             std::cout <<"Please discover the MOT device first. Use option 16"<<std::endl;
1735                             break;
1736                         }
1737
1738                         printDevices(pMOTEnabledDeviceList);
1739                         // select device
1740                         unsigned int dev_num = 0;
1741                         for( ; ; )
1742                         {
1743                             std::cout << "Enter Device Number, for MOT Device: "<<std::endl;
1744                             std::cin >> dev_num;
1745                             if(0 < dev_num && pMOTEnabledDeviceList.size() >=dev_num)
1746                             {
1747                                 break;
1748                             }
1749                             std::cout << "     Entered Wrong Number. Please Enter Again"<<std::endl;
1750                         }
1751
1752                         UuidList_t subOwenrList;
1753                         pMOTEnabledDeviceList[dev_num - 1]->getSubOwnerList(subOwenrList);
1754                         if (0 == subOwenrList.size())
1755                         {
1756                             std::cout << "SubOwner List is empty."<<std::endl;
1757                         }
1758                         else
1759                         {
1760                             pMOTEnabledDeviceList[dev_num - 1]->removeAllSubOwner(MOTRemoveSubOwnerCB);
1761                         }
1762                         break;
1763                     }
1764 #endif //MULTIPLE_OWNER
1765                 case 30:
1766                     {
1767                         OCStackResult result;
1768                         result = OCSecure::configSelfOwnership();
1769                         if (OC_STACK_OK != result)
1770                         {
1771                             std::cout<<"configSelfOwnership API error. Please check SVR DB"<<std::endl;
1772                         }
1773                         else
1774                         {
1775                             std::cout<<"Success to configures SVR DB as self-ownership"<<std::endl;
1776                         }
1777                         break;
1778                     }
1779                 case 99:
1780                 default:
1781                     out = 1;
1782                     break;
1783             }
1784         }
1785     }
1786     catch(OCException& e)
1787     {
1788         oclog() << "Exception in main: "<<e.what();
1789     }
1790
1791     return 0;
1792 }