1 /* *****************************************************************
3 * Copyright 2015 Samsung Electronics All Rights Reserved.
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 * *****************************************************************/
29 #include <condition_variable>
32 #include "oic_malloc.h"
33 #include "oic_string.h"
34 #include "OCPlatform.h"
36 #include "OCProvisioningManager.hpp"
37 #include "oxmjustworks.h"
38 #include "oxmrandompin.h"
39 #include "aclresource.h"
41 #include "mbedtls/x509_crt.h"
43 #define MAX_PERMISSION_LENGTH (5)
44 #define ACL_RESRC_ARRAY_SIZE (3)
51 #define PREDEFINED_TIMEOUT (10)
52 #define MAX_OWNED_DEVICE (10)
53 #define TAG "provisioningclient"
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"
60 #define DISCOVERY_TIMEOUT 5
62 static const OicSecPrm_t SUPPORTED_PRMS[1] =
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;
74 static FILE* client_open(const char *UNUSED_PARAM, const char *mode)
77 return fopen(DAT_DB_PATH, mode);
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;
109 std::cout << " 30. Configure SVRdb as Self-OwnerShip"<<std::endl;
110 std::cout << " 99. Exit loop"<<std::endl;
113 void moveTransferredDevice()
115 pOwnedDevList.push_back(pUnownedDevList[transferDevIdx]);
116 pUnownedDevList.erase(pUnownedDevList.begin() + transferDevIdx);
119 void InputPinCB(char* pinBuf, size_t bufSize)
123 std::cout <<"INPUT PIN : ";
126 OICStrcpy(pinBuf, bufSize, ptr.c_str());
131 void printUuid(OicUuid_t uuid)
133 for (int i = 0; i < UUID_LENGTH; i++)
135 std::cout <<std::hex << uuid.id[i] << " ";
137 std::cout<<std::endl;
141 static OCStackResult peerCertCallback(const mbedtls_x509_crt *cert, int depth)
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__);
153 void ownershipTransferCB(PMResultList_t *result, int hasError)
157 std::cout << "Error!!! in OwnershipTransfer"<<std::endl;
161 std::cout<< "\nTransferred Ownership successfuly for device : ";
162 printUuid(result->at(0).deviceId);
165 moveTransferredDevice();
170 void printStatus(int status)
172 static std::map<int, std::string> devStatus = {{1<<0, DEV_STATUS_ON}, {1<<1, DEV_STATUS_OFF}};
174 std::cout <<devStatus[status] <<std::endl;
177 void printDevices(DeviceList_t &list)
179 for (unsigned int i = 0; i < list.size(); i++ )
181 std::cout << "Device "<< i+1 <<" ID: ";
182 std::cout << list[i]->getDeviceID() << " From IP: ";
183 std::cout << list[i]->getDevAddr() << std::endl;
188 * Callback function for provisioning ACL, Credentials.
190 * @param[in] result Result list
191 * @param[in] hasError indicates if the result has error
193 void provisionCB(PMResultList_t *result, int hasError)
197 std::cout << "Error in provisioning operation!"<<std::endl;
201 std::cout<< "\nReceived provisioning results: ";
202 for (unsigned int i = 0; i < result->size(); i++)
204 std::cout << "Result is = " << result->at(i).res <<" for device ";
205 printUuid(result->at(i).deviceId);
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
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.
226 int readDeviceNumber(DeviceList_t &list, int count, int *out)
228 if (out == NULL || count <= 0)
230 std::cout << "Error! Please put valid input parameters" << std::endl;
234 int devicesCount = list.size();
236 //Print current list of owned devices
237 std::cout <<"Owned devices, count = " << devicesCount << std::endl;
240 if (devicesCount < count)
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;
248 std::cout << "Select " << count << " device(s) for provisioning" << std::endl;
250 for (int curr = 0; curr < count; curr++)
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))
258 for (int i = 0; i < curr; i++)
263 out[curr] = (count*(count+1))/2 - sum;
265 std::cout << "Device " << curr + 1 << " : " << out[curr];
266 std::cout << " - selected automatically (because no other options exist)" << std::endl;
271 std::cout << "Device " << curr + 1 << " : ";
274 if (choice < 1 || choice > devicesCount)
276 std::cout << "Error! You should enter valid device number!" << std::endl;
280 //check that user doesn't select the same device twice
281 for (int i = 0; i < curr; i++)
283 if (out[i] == choice)
285 std::cout << "Error! You cannot select the same device twice!" << std::endl;
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;
301 * Perform cleanup for ACL
304 static void deleteACL(OicSecAcl_t *acl)
311 * Calculate ACL permission from string to bit
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.
317 static int CalculateAclPermission(const char *temp_pms, uint16_t *pms)
321 if (NULL == temp_pms || NULL == pms)
326 while (temp_pms[i] != '\0')
375 * Get the ACL property from user
377 * @param[in] ACL Datastructure to save user inputs
378 * @return 0 on success otherwise -1.
380 static int InputACL(OicSecAcl_t *acl)
383 char *temp_id, *temp_rsc, *temp_pms;
385 printf("******************************************************************************\n");
386 printf("-Set ACL policy for target device\n");
387 printf("******************************************************************************\n");
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);
394 OicSecAce_t* ace = (OicSecAce_t*)OICCalloc(1, sizeof(OicSecAce_t));
397 OIC_LOG(ERROR, TAG, "Error while memory allocation");
400 LL_APPEND(acl->aces, ace);
404 for (int i = 0, j = 0; temp_id[i] != '\0'; i++)
406 if (DASH != temp_id[i])
407 ace->subjectuuid.id[j++] = temp_id[i];
414 printf("Error while input\n");
419 size_t resourcesLen = 0;
420 printf("Num. of Resource : ");
421 ret = scanf("%zu", &resourcesLen);
422 if ((1 != ret) || (resourcesLen <= 0 || resourcesLen > 50))
425 printf("Error while input\n");
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++)
432 OicSecRsrc_t* rsrc = (OicSecRsrc_t*)OICCalloc(1, sizeof(OicSecRsrc_t));
436 OIC_LOG(ERROR, TAG, "Error while memory allocation");
440 LL_APPEND(ace->resources, rsrc);
442 printf("[%zu]Resource : ", i + 1);
443 ret = scanf("%64ms", &temp_rsc);
446 printf("Error while input\n");
450 rsrc->href = OICStrdup(temp_rsc);
453 char* rsrc_in = NULL;
457 printf(" Enter Number of resource type for [%s]: ", rsrc->href);
458 for(int ret=0; 1!=ret; )
460 ret = scanf("%zu", &arrLen);
461 for( ; 0x20<=getchar(); ); // for removing overflow garbages
462 // '0x20<=code' is character region
464 if(ACL_RESRC_ARRAY_SIZE >= arrLen)
468 printf(" Entered Wrong Number. Please Enter under %d Again\n", ACL_RESRC_ARRAY_SIZE);
471 rsrc->typeLen = arrLen;
472 rsrc->types = (char**)OICCalloc(arrLen, sizeof(char*));
475 OIC_LOG(ERROR, TAG, "createAcl: OICCalloc error return");
479 for(unsigned int i = 0; i < arrLen; i++)
481 printf(" Enter ResourceType[%d] Name (e.g. core.led): ", i+1);
482 for(int ret=0; 1!=ret; )
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
488 rsrc->types[i] = OICStrdup(rsrc_in);
492 OIC_LOG(ERROR, TAG, "createAcl: OICStrdup error return");
499 printf(" Enter Number of interface name for [%s]: ", rsrc->href);
500 for(int ret=0; 1!=ret; )
502 ret = scanf("%zu", &arrLen);
503 for( ; 0x20<=getchar(); ); // for removing overflow garbages
504 // '0x20<=code' is character region
506 if(ACL_RESRC_ARRAY_SIZE >= arrLen)
510 printf(" Entered Wrong Number. Please Enter under %d Again\n", ACL_RESRC_ARRAY_SIZE);
513 rsrc->interfaceLen = arrLen;
514 rsrc->interfaces = (char**)OICCalloc(arrLen, sizeof(char*));
515 if(!rsrc->interfaces)
517 OIC_LOG(ERROR, TAG, "createAcl: OICCalloc error return");
521 for(unsigned int i = 0; i < arrLen; i++)
523 printf(" Enter interfnace[%d] Name (e.g. oic.if.baseline): ", i+1);
524 for(int ret=0; 1!=ret; )
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
530 rsrc->interfaces[i] = OICStrdup(rsrc_in);
532 if(!rsrc->interfaces[i])
534 OIC_LOG(ERROR, TAG, "createAcl: OICStrdup error return");
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);
550 printf("Error while input\n");
553 ret = CalculateAclPermission(temp_pms, &(ace->permission));
558 printf("-URN identifying the rowner\n");
559 printf("ex) 1111-1111-1111-1111 (16 Numbers except to '-')\n");
562 ret = scanf("%19ms", &temp_id);
565 printf("Error while input\n");
569 for (int k = 0, j = 0; temp_id[k] != '\0'; k++)
571 if (DASH != temp_id[k])
573 acl->rownerID.id[j++] = temp_id[k];
585 static int InputCredentials(Credential &cred)
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: ";
603 cred.setCredentialType(static_cast<OicSecCredType_t>(choice));
604 choice = 0; //validation of the accepted choice.
610 std::cout << "selected type is not supported yet" << std::endl;
613 std::cout << "Error! Please select valid credential type" << std::endl;
616 } while(0 != choice);
618 std::cout << "Please enter key size (valid size is 128 or 256) :";
623 cred.setCredentialKeySize(OWNER_PSK_LENGTH_128);
625 else if(256 == choice)
627 cred.setCredentialKeySize(OWNER_PSK_LENGTH_256);
631 std::cout << "Error! Please enter valid key size!" << std::endl;
638 static void deletePconf()
640 OICFree(g_pconf.prm);
642 OicSecPdAcl_t* acl = g_pconf.pdacls;
645 /* Clean Resources */
646 for (unsigned int i = 0; i < (acl)->resourcesLen; i++)
648 OICFree((acl)->resources[i]);
650 OICFree((acl)->resources);
652 /* Clean ACL node itself */
653 /* Required only if acl was created in heap */
656 memset(&g_pconf, 0, sizeof(OicSecPconf_t));
659 static OicSecPdAcl_t* InputPdACL()
662 char *temp_rsc, *temp_pms;
664 printf("******************************************************************************\n");
665 printf("-Set ACL policy for target DP device\n");
666 printf("******************************************************************************\n");
668 OicSecPdAcl_t *acl = (OicSecPdAcl_t *)OICCalloc(1,sizeof(OicSecPdAcl_t));
671 OIC_LOG(ERROR, TAG, "Error while memory allocation");
676 printf("Num. of Resource : ");
677 ret = scanf("%zu", &acl->resourcesLen);
678 if ((1 != ret) || (acl->resourcesLen <= 0 || acl->resourcesLen > 50))
680 printf("Error while input\n");
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)
689 OIC_LOG(ERROR, TAG, "Error while memory allocation");
693 for (size_t i = 0; i < acl->resourcesLen; i++)
695 printf("[%zu]Resource : ", i + 1);
696 ret = scanf("%64ms", &temp_rsc);
699 printf("Error while input\n");
700 OICFree(acl->resources);
705 acl->resources[i] = OICStrdup(temp_rsc);
707 if (NULL == acl->resources[i])
709 OIC_LOG(ERROR, TAG, "Error while memory allocation");
710 OICFree(acl->resources);
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);
725 printf("Error while input\n");
726 OICFree(acl->resources);
730 ret = CalculateAclPermission(temp_pms, &(acl->permission));
737 void provisionDirectPairingCB(PMResultList_t *result, int hasError)
741 std::cout << "Error in provisioning operation!"<<std::endl;
745 std::cout<< "\nReceived provisioning results: Direct Pairing is successful ";
746 for (unsigned int i = 0; i < result->size(); i++)
748 std::cout << "Result is = " << result->at(i).res <<" for device ";
749 printUuid(result->at(i).deviceId);
759 static void provisionDP(int dev_num)
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));
772 for (size_t i=0; i < g_pconf.prmLen; i++)
774 g_pconf.prm[i] = SUPPORTED_PRMS[i];
779 OIC_LOG(ERROR, TAG, "create prm error return");
783 std::cout << "Enter PIN to be configured: ";
787 if (pin.length() == DP_PIN_LENGTH)
793 std::cout << "PIN length should be 8, Enter again: ";
797 memcpy(g_pconf.pin.val, pin.c_str(), DP_PIN_LENGTH);
801 g_pconf.pdacls = InputPdACL();
804 OIC_LOG(ERROR, TAG, "InputPdACL error return");
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)
814 OIC_LOG_V(ERROR, TAG, "OCProvisionDirectPairing API error: %d", rst);
815 if (OC_STACK_UNAUTHORIZED_REQ == rst)
817 OIC_LOG(ERROR, TAG, "Target Server NOT Support Direct-Pairing !!! (DPC == false)");
824 deletePconf(); // after here |acl| points nothing
828 OCStackResult displayMutualVerifNumCB(uint8_t mutualVerifNum[MUTUAL_VERIF_NUM_LEN])
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");
838 OCStackResult confirmMutualVerifNumCB(void)
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");
847 for (int ret=0; 1!=ret; )
849 ret = scanf("%d", &userConfirm);
850 for (; 0x20<=getchar(); ); // for removing overflow garbage
851 // '0x20<=code' is character region
853 if (1 == userConfirm)
857 else if (0 == userConfirm)
859 return OC_STACK_USER_DENIED_REQ;
861 printf(" Entered Wrong Number. Please Enter Again\n");
869 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
870 static int saveTrustCert(void)
873 // call |OCSaveTrustCertChainBin| API actually
874 printf(" Save Trust Cert. Chain into Cred of SVR.\n");
876 ByteArray trustCertChainArray = {0, 0};
878 FILE *fp = fopen("rootca.crt", "rb+");
883 if (fseeko(fp, 0, SEEK_END) == 0 && (fsize = ftello(fp)) >= 0)
885 trustCertChainArray.data = (uint8_t*)OICCalloc(1, fsize);
886 trustCertChainArray.len = fsize;
887 if (NULL == trustCertChainArray.data)
889 OIC_LOG(ERROR,TAG,"Failed to allocate memory");
894 fsize = fread(trustCertChainArray.data, 1, fsize, fp);
897 OIC_LOG(ERROR,TAG,"Read error");
902 OIC_LOG_BUFFER(DEBUG, TAG, trustCertChainArray.data, trustCertChainArray.len);
904 if(OC_STACK_OK != OCSecure::saveTrustCertChain(trustCertChainArray.data, trustCertChainArray.len,
905 OIC_ENCODING_PEM,&g_credId))
907 OIC_LOG(ERROR, TAG, "OCSaveTrustCertChainBin API error");
910 printf("CredId of Saved Trust Cert. Chain into Cred of SVR : %d.\n", g_credId);
915 void certChainCallBack(uint16_t credId, uint8_t *trustCertChain,size_t chainSize)
917 OIC_LOG_V(INFO, TAG, "trustCertChain Changed for credId %u", credId);
918 OC_UNUSED(trustCertChain);
919 OC_UNUSED(chainSize);
922 #endif // __WITH_DTLS__ or __WITH_TLS__
924 #ifdef MULTIPLE_OWNER
925 void MOTMethodCB(PMResultList_t *result, int hasError)
929 std::cout << "Error!!! in callback"<<std::endl;
933 std::cout<< "callback successfull"<<std::endl;
938 void MOTRemoveSubOwnerCB(PMResultList_t *result, int hasError)
942 std::cout << "Error!!! in callback"<<std::endl;
946 std::cout<< "callback successfull"<<std::endl;
951 #endif // MULTIPLE_OWNER
955 OCStackResult result;
956 OCPersistentStorage ps {client_open, fread, fwrite, fclose, unlink, NULL, NULL};
958 // Create PlatformConfig object
960 OC::ServiceType::InProc,
964 OC::QualityOfService::LowQos,
968 OCPlatform::Configure(cfg);
973 OicSecAcl_t *acl1 = nullptr, *acl2 = nullptr;
974 if (OCSecure::provisionInit("") != OC_STACK_OK)
976 std::cout <<"PM Init failed"<< std::endl;
980 result = OCSecure::registerDisplayNumCallback(displayMutualVerifNumCB);
981 if (result != OC_STACK_OK)
983 std::cout<< "!!Error - setDisplayVerifNumCB failed."<<std::endl;
986 result = OCSecure::registerUserConfirmCallback(confirmMutualVerifNumCB);
987 if (result != OC_STACK_OK)
989 std::cout<< "!!Error - setConfirmVerifNumCB failed."<<std::endl;
992 OCSecure::setPeerCertCallback(peerCertCallback);
994 for (int out = 0; !out;)
1018 //Secure resource discovery.
1020 pUnownedDevList.clear();
1021 std::cout << "Started discovery..." <<std::endl;
1022 OCStackResult result = OCSecure::discoverUnownedDevices(DISCOVERY_TIMEOUT,
1024 if (result != OC_STACK_OK)
1026 std::cout<< "!!Error - UnOwned Discovery failed."<<std::endl;
1028 else if (pUnownedDevList.size())
1030 std::cout <<"Found secure devices, count = " <<
1031 pUnownedDevList.size() << std::endl;
1032 printDevices(pUnownedDevList);
1036 std::cout <<"No Secure devices found"<<std::endl;
1042 pOwnedDevList.clear();
1043 std::cout << "Started discovery..." <<std::endl;
1044 OCStackResult result = OCSecure::discoverOwnedDevices(DISCOVERY_TIMEOUT,
1046 if (result != OC_STACK_OK)
1048 std::cout<< "!!Error - Owned Discovery failed."<<std::endl;
1050 else if (pOwnedDevList.size())
1052 std::cout <<"Found owned devices, count = " <<
1053 pOwnedDevList.size() << std::endl;
1054 printDevices(pOwnedDevList);
1058 std::cout <<"No Secure devices found"<<std::endl;
1064 unsigned int devNum;
1066 if (!pUnownedDevList.size())
1068 std::cout <<"There are no more Unowned devices"<<std::endl;
1072 for (unsigned int i = 0; i < pUnownedDevList.size(); i++ )
1074 std::cout << i+1 << ": "<< pUnownedDevList[i]->getDeviceID();
1075 std::cout << " From IP:" << pUnownedDevList[i]->getDevAddr() <<std::endl;
1078 std::cout <<"Select device number: "<<std::endl;
1080 if (devNum > pUnownedDevList.size())
1082 std::cout <<"Invalid device number"<<std::endl;
1085 transferDevIdx = devNum - 1;
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);
1092 std::cout << "Transfering ownership for : "<<
1093 pUnownedDevList[devNum-1]->getDeviceID()<<std::endl;
1094 if (pUnownedDevList[devNum-1]->doOwnershipTransfer(ownershipTransferCB)
1097 std::cout<<"OwnershipTransferCallback is failed"<<std::endl;
1102 case 4: //Provision ACL
1106 if (0 != readDeviceNumber(pOwnedDevList, 1, &index)) break;
1108 std::cout << "Provision ACL for : "<<
1109 pOwnedDevList[index]->getDeviceID()<< std::endl;
1111 acl1 = (OicSecAcl_t *)OICCalloc(1,sizeof(OicSecAcl_t));
1114 OIC_LOG(ERROR, TAG, "Error while memory allocation");
1118 std::cout << "Please input ACL for selected device: " << std::endl;
1119 if (0 != InputACL(acl1))
1126 if (pOwnedDevList[index]->provisionACL(acl1, provisionCB) != OC_STACK_OK)
1129 std::cout <<"provisionACL is failed"<< std::endl;
1133 case 5: //Provision Credentials
1137 if (0 != readDeviceNumber(pOwnedDevList, 2, devices)) break;
1139 int first = devices[0];
1140 int second = devices[1];
1142 std::cout << "Provision Credentials to devices: "<<
1143 pOwnedDevList[first]->getDeviceID();
1144 std::cout << " and "<< pOwnedDevList[second]->getDeviceID() << std::endl;
1146 Credential cred( NO_SECURITY_MODE ,0);
1147 std::cout << "Please input credentials for selected devices: " << std::endl;
1148 if (0 != InputCredentials(cred))
1153 if (pOwnedDevList[first]->provisionCredentials(cred,
1154 *pOwnedDevList[second].get(), provisionCB) != OC_STACK_OK)
1157 std::cout <<"provisionCredentials is failed"<< std::endl;
1161 case 6: //Provision ACL & Creds b/w two devices.
1165 if (0 != readDeviceNumber(pOwnedDevList, 2, devices)) break;
1167 int first = devices[0];
1168 int second = devices[1];
1170 std::cout << "Provision pairwise devices: "<<
1171 pOwnedDevList[first]->getDeviceID();
1172 std::cout << " and "<< pOwnedDevList[second]->getDeviceID() << std::endl;
1174 Credential cred( NO_SECURITY_MODE, 0);
1175 std::cout << "Please input credentials for selected devices: " << std::endl;
1176 if (0 != InputCredentials(cred))
1179 acl1 = (OicSecAcl_t *)OICCalloc(1,sizeof(OicSecAcl_t));
1182 OIC_LOG(ERROR, TAG, "Error while memory allocation");
1186 std::cout << "Please input ACL for selected device: " << std::endl;
1187 if (0 != InputACL(acl1))
1192 acl2 = (OicSecAcl_t *)OICCalloc(1,sizeof(OicSecAcl_t));
1195 OIC_LOG(ERROR, TAG, "Error while memory allocation");
1199 std::cout << "Please input ACL for selected device: " << std::endl;
1200 if (0 != InputACL(acl2))
1207 if (pOwnedDevList[first]->provisionPairwiseDevices(cred, acl1,
1208 *pOwnedDevList[second].get(), acl2, provisionCB) != OC_STACK_OK)
1211 std::cout <<"provisionPairwiseDevices is failed"<< std::endl;
1215 case 7: //Unlink Devices
1219 if (0 != readDeviceNumber(pOwnedDevList, 2, devices)) break;
1221 int first = devices[0];
1222 int second = devices[1];
1224 std::cout << "Unlink devices: "<< pOwnedDevList[first]->getDeviceID();
1225 std::cout << " and "<< pOwnedDevList[second]->getDeviceID() << std::endl;
1229 if (pOwnedDevList[first]->unlinkDevices(*pOwnedDevList[second].get(),
1230 provisionCB) != OC_STACK_OK)
1233 std::cout <<"unlinkDevice is failed"<< std::endl;
1237 case 8: //Remove Device
1241 if (0 != readDeviceNumber(pOwnedDevList, 1, &index)) break;
1243 std::cout << "Remove Device: "<< pOwnedDevList[index]->getDeviceID()<< std::endl;
1247 if (pOwnedDevList[index]->removeDevice(DISCOVERY_TIMEOUT, provisionCB)
1251 std::cout <<"removeDevice is failed"<< std::endl;
1255 case 9: //Remove Device using UUID
1259 if (0 != readDeviceNumber(pOwnedDevList, 1, &index)) break;
1261 std::cout << "Remove Device: "<< pOwnedDevList[index]->getDeviceID()<< std::endl;
1265 if (OCSecure::removeDeviceWithUuid(DISCOVERY_TIMEOUT,
1266 pOwnedDevList[index]->getDeviceID(),
1271 std::cout <<"removeDevice is failed"<< std::endl;
1276 case 10: //Get Linked devices
1278 UuidList_t linkedUuid;
1279 unsigned int devNum;
1281 if (!pOwnedDevList.size())
1283 std::cout <<"There are no Owned devices yet,"
1284 " may need to discover"<<std::endl;
1288 for (unsigned int i = 0; i < pOwnedDevList.size(); i++ )
1290 std::cout << i+1 << ": "<< pOwnedDevList[i]->getDeviceID() <<" From IP:";
1291 std::cout << pOwnedDevList[i]->getDevAddr() <<std::endl;
1294 std::cout <<"Select device number: "<<std::endl;
1296 if (devNum > pOwnedDevList.size())
1298 std::cout <<"Invalid device number"<<std::endl;
1302 if(pOwnedDevList[devNum -1]->getLinkedDevices(linkedUuid) == OC_STACK_OK)
1304 if (!linkedUuid.size())
1306 std::cout <<"No devices are linked to "<<
1307 pOwnedDevList[devNum -1]->getDeviceID() << std::endl;
1309 //display the Linked devices (UUIDs)
1310 for(unsigned int i = 0; i < linkedUuid.size(); i++)
1312 printUuid(linkedUuid[i]);
1317 std::cout <<"Error! in getLinkedDevices"<<std::endl;
1321 case 11: //Get device' status
1323 DeviceList_t unownedList, ownedList;
1325 if (OCSecure::getDevInfoFromNetwork(DISCOVERY_TIMEOUT, ownedList,
1326 unownedList) == OC_STACK_OK)
1328 std::cout <<"Owned Device' status for" <<std::endl;
1329 for (unsigned int i = 0; i < ownedList.size(); i++ )
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());
1336 std::cout <<"\nUnOwned Device' status for" <<std::endl;
1337 for (unsigned int i = 0; i < unownedList.size(); i++ )
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());
1351 unsigned int devNum;
1353 if (!pOwnedDevList.size())
1355 std::cout <<"There are no Owned devices yet,"
1356 " may need to discover"<<std::endl;
1360 for (unsigned int i = 0; i < pOwnedDevList.size(); i++ )
1362 std::cout << i+1 << ": "<< pOwnedDevList[i]->getDeviceID() <<" From IP:";
1363 std::cout << pOwnedDevList[i]->getDevAddr() <<std::endl;
1366 std::cout <<"Select device number: "<<std::endl;
1368 if (devNum > pOwnedDevList.size())
1370 std::cout <<"Invalid device number"<<std::endl;
1375 provisionDP(devNum);
1379 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
1382 std::cout<< "registering cert chain change notifier"<<std::endl;
1383 OCSecure::registerTrustCertChangeNotifier(certChainCallBack);
1386 std::cout<<"Error in saving cert"<<std::endl;
1388 std::cout<< "Unregister notifier"<<std::endl;
1389 OCSecure::removeTrustCertChangeNotifier();
1396 if (0 != readDeviceNumber(pOwnedDevList, 1, &index)) break;
1398 std::cout << "Provision cert for : "<<
1399 pOwnedDevList[index]->getDeviceID()<< std::endl;
1403 if (pOwnedDevList[index]->provisionTrustCertChain(SIGNED_ASYMMETRIC_KEY,
1404 g_credId,provisionCB ) != OC_STACK_OK)
1407 std::cout <<"provision cert is failed"<< std::endl;
1415 std::cout<<"please save cert using option 13.";
1419 uint8_t *trustCertChain = NULL;
1420 size_t chainSize = 0;
1421 if (OC_STACK_OK != OCSecure::readTrustCertChain(g_credId, &trustCertChain,&chainSize))
1423 std::cout <<"issue in read trust chain"<< std::endl;
1427 std::cout<<"size of cert : "<<chainSize<<std::endl;
1432 #endif //__WITH_DTLS__ || __WITH_TLS__
1433 #ifdef MULTIPLE_OWNER
1436 if (!pOwnedDevList.size() && !pMOTEnabledDeviceList.size())
1438 std::cout <<"Owned device list and MOT device list both are empty."<<std::endl;
1441 unsigned int dev_count = 0;
1442 if (pOwnedDevList.size())
1444 dev_count = pOwnedDevList.size();
1445 printDevices(pOwnedDevList);
1448 if (pMOTEnabledDeviceList.size())
1450 dev_count += pMOTEnabledDeviceList.size();
1451 for (unsigned int i = 0; i < pMOTEnabledDeviceList.size(); i++ )
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;
1462 unsigned int dev_num = 0;
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)
1471 std::cout << " Entered Wrong Number. Please Enter Again"<<std::endl;
1474 OicSecMomType_t momType = OIC_MULTIPLE_OWNER_ENABLE;
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; )
1483 ret = scanf("%d", &mom);
1484 for( ; 0x20<=getchar(); ); // for removing overflow garbages
1485 // '0x20<=code' is character region
1489 momType = OIC_MULTIPLE_OWNER_DISABLE;
1494 momType = OIC_MULTIPLE_OWNER_ENABLE;
1497 std::cout <<" Entered Wrong Number. Please Enter Again"<<std::endl;
1500 if (!pOwnedDevList.size())
1502 if(OC_STACK_OK != pMOTEnabledDeviceList[dev_num-1]->changeMOTMode(
1503 (const OicSecMomType_t)momType,MOTMethodCB))
1505 OIC_LOG(ERROR, TAG, "changeMOTMode API error");
1510 if(dev_num <= pOwnedDevList.size())
1512 if(OC_STACK_OK != pOwnedDevList[dev_num-1]->changeMOTMode(momType,
1515 OIC_LOG(ERROR, TAG, "changeMOTMode API error");
1520 if(OC_STACK_OK != pMOTEnabledDeviceList[(dev_num -
1521 pOwnedDevList.size() - 1)]->changeMOTMode(momType,
1524 OIC_LOG(ERROR, TAG, "changeMOTMode API error");
1532 if (!pMOTEnabledDeviceList.size())
1534 std::cout <<"Please discover the MOT device first. Use option 18"<<std::endl;
1538 printDevices(pMOTEnabledDeviceList);
1540 unsigned int dev_num = 0;
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)
1549 std::cout << " Entered Wrong Number. Please Enter Again"<<std::endl;
1553 OicSecOxm_t secOxm = OIC_PRECONFIG_PIN;
1554 std::cout << "Select method for Multiple Ownership Transfer: "<<std::endl;
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;
1563 secOxm = OIC_RANDOM_DEVICE_PIN;
1568 secOxm = OIC_PRECONFIG_PIN;
1571 std::cout << " Entered Wrong Number. Please Enter Again"<<std::endl;
1574 if(OC_STACK_OK != pMOTEnabledDeviceList[dev_num-1]->selectMOTMethod((const OicSecOxm_t)secOxm,
1577 OIC_LOG(ERROR, TAG, "selectMOTMethod API error");
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)
1589 std::cout<< "!!Error - MOT Enabled dev Discovery failed."<<std::endl;
1591 else if (pMOTEnabledDeviceList.size())
1593 std::cout <<"Found MOT enabled devices, count = " <<
1594 pMOTEnabledDeviceList.size() << std::endl;
1595 printDevices(pMOTEnabledDeviceList);
1599 std::cout <<"No MOT enabled Secure devices found"<<std::endl;
1605 if (!pMOTEnabledDeviceList.size())
1607 std::cout <<"Please discover the MOT device first. Use option 16"<<std::endl;
1611 printDevices(pMOTEnabledDeviceList);
1613 unsigned int dev_num = 0;
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)
1622 std::cout << " Entered Wrong Number. Please Enter Again"<<std::endl;
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; )
1629 ret = scanf("%8s", preconfigPin);
1630 for( ; 0x20<=getchar(); ); // for removing overflow garbages
1631 // '0x20<=code' is character region
1633 size_t preconfPinLength = strlen(preconfigPin);
1634 if(OC_STACK_OK != pMOTEnabledDeviceList[dev_num-1]->provisionPreconfPin(preconfigPin,
1635 preconfPinLength, MOTMethodCB))
1637 OIC_LOG(ERROR, TAG, "provisionPreconfPin API error");
1643 if (!pMOTEnabledDeviceList.size())
1645 std::cout <<"Please discover the MOT device first. Use option 16"<<std::endl;
1649 printDevices(pMOTEnabledDeviceList);
1651 unsigned int dev_num = 0;
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)
1660 std::cout << " Entered Wrong Number. Please Enter Again"<<std::endl;
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; )
1667 ret = scanf("%8s", preconfPIN);
1668 for( ; 0x20<=getchar(); ); // for removing overflow garbages
1669 // '0x20<=code' is character region
1671 size_t preconfPinLength = strlen(preconfPIN);
1672 if(OC_STACK_OK != pMOTEnabledDeviceList[dev_num-1]->addPreconfigPIN(preconfPIN,
1675 OIC_LOG(ERROR, TAG, "addPreconfigPIN API error");
1679 case 21: //Remove sub-owner
1681 if (!pMOTEnabledDeviceList.size())
1683 std::cout <<"Please discover the MOT device first. Use option 16"<<std::endl;
1687 printDevices(pMOTEnabledDeviceList);
1689 unsigned int dev_num = 0;
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)
1698 std::cout << " Entered Wrong Number. Please Enter Again"<<std::endl;
1701 UuidList_t subOwenrList;
1702 pMOTEnabledDeviceList[dev_num - 1]->getSubOwnerList(subOwenrList);
1703 if (0 == subOwenrList.size())
1705 std::cout << "SubOwner List is empty."<<std::endl;
1709 //display the Linked devices (UUIDs)
1710 for(unsigned int i = 0; i < subOwenrList.size(); i++)
1712 printUuid(subOwenrList[i]);
1715 unsigned int so_num = 0;
1718 std::cout << "Enter SubOwner Number to be Removed: "<<std::endl;
1720 if(0 < so_num && subOwenrList.size() >=so_num)
1722 pMOTEnabledDeviceList[dev_num - 1]->removeSubOwner(&subOwenrList[so_num], MOTRemoveSubOwnerCB);
1725 std::cout << " Entered Wrong Number. Please Enter Again"<<std::endl;
1730 case 22: //Remove all sub-owner
1732 if (!pMOTEnabledDeviceList.size())
1734 std::cout <<"Please discover the MOT device first. Use option 16"<<std::endl;
1738 printDevices(pMOTEnabledDeviceList);
1740 unsigned int dev_num = 0;
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)
1749 std::cout << " Entered Wrong Number. Please Enter Again"<<std::endl;
1752 UuidList_t subOwenrList;
1753 pMOTEnabledDeviceList[dev_num - 1]->getSubOwnerList(subOwenrList);
1754 if (0 == subOwenrList.size())
1756 std::cout << "SubOwner List is empty."<<std::endl;
1760 pMOTEnabledDeviceList[dev_num - 1]->removeAllSubOwner(MOTRemoveSubOwnerCB);
1764 #endif //MULTIPLE_OWNER
1767 OCStackResult result;
1768 result = OCSecure::configSelfOwnership();
1769 if (OC_STACK_OK != result)
1771 std::cout<<"configSelfOwnership API error. Please check SVR DB"<<std::endl;
1775 std::cout<<"Success to configures SVR DB as self-ownership"<<std::endl;
1786 catch(OCException& e)
1788 oclog() << "Exception in main: "<<e.what();