1 /******************************************************************
3 * Copyright 2016 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 *****************************************************************/
20 #include "iotivity_config.h"
29 #include "platform_features.h"
32 #include "oic_malloc.h"
33 #include "oic_string.h"
34 #include "ocprovisioningmanager.h"
35 #include "oxmjustworks.h"
36 #include "oxmrandompin.h"
37 #include "securevirtualresourcetypes.h"
38 #include "srmutility.h"
40 #include "pmutility.h"
46 #define access _access_s
54 // declaration(s) for provisioning client using C-level provisioning API
55 // user input definition for main loop on provisioning client
56 #define _10_DISCOV_MOT_ENABLED_DEV_ 10
57 #define _11_DISCOV_MULTIPLE_OWNED_DEV_ 11
58 #define _20_PERFORM_MOT_ 20
59 #define _30_GET_LED_RESOURCE_ 30
60 #define _31_PUT_LED_RESOURCE_ 31
61 #define _40_PROVISION_ACL_ 40
62 #define _41_PROVISION_CRED_ 41
63 #define _99_EXIT_PRVN_CLT_ 99
65 #define ACL_RESRC_MAX_NUM 16
66 #define ACL_RESRC_ARRAY_SIZE 3 //This value is used only for sample (not OCF spec)
67 #define ACL_RESRC_MAX_LEN 128
68 #define ACL_PEMISN_CNT 5
69 #define DISCOVERY_TIMEOUT 5 // 5 sec
70 #define CALLBACK_TIMEOUT 60 // 1 min
71 #define TAG "subownerclient"
73 static const char* SVR_DB_FILE_NAME = "oic_svr_db_subowner_client.dat";
74 // '_' for separaing from the same constant variable in |srmresourcestrings.c|
75 static const char* PRVN_DB_FILE_NAME = "oic_pdm_subowner.db";
76 static const OicSecPrm_t SUPPORTED_PRMS[1] =
81 // |g_ctx| means provision manager application context and
82 // the following, includes |un/own_list|, could be variables, which |g_ctx| has,
83 // for accessing all function(s) for these, they are declared on global domain
84 static char* g_ctx = "SubOwner Client Application Context";
85 static char* g_svr_fname;
86 static char* g_prvn_fname;
87 static OCProvisionDev_t* g_own_list;
88 static OCProvisionDev_t* g_unown_list;
89 static OCProvisionDev_t* g_motdev_list;
90 static OCProvisionDev_t* g_mowned_list;
92 static int g_unown_cnt;
93 static int g_motdev_cnt;
94 static int g_mowned_cnt;
97 // function declaration(s) for calling them before implementing
98 static OCProvisionDev_t* getDevInst(const OCProvisionDev_t*, const int);
99 static int printDevList(const OCProvisionDev_t*);
100 static size_t printUuidList(const OCUuidList_t*);
101 static size_t printResultList(const OCProvisionResult_t*, const size_t);
102 static void printUuid(const OicUuid_t*);
103 static FILE* fopen_prvnMng(const char*, const char*);
104 static int waitCallbackRet(void);
105 static int selectTwoDiffNum(int*, int*, const int, const char*);
107 // callback function(s) for provisioning client using C-level provisioning API
108 static void multipleOwnershipTransferCB(void* ctx, size_t nOfRes, OCProvisionResult_t* arr, bool hasError)
112 OIC_LOG_V(INFO, TAG, "Multiple Ownership Transfer SUCCEEDED - ctx: %s", (char*) ctx);
116 OIC_LOG_V(ERROR, TAG, "Multiple Ownership Transfer FAILED - ctx: %s", (char*) ctx);
117 printResultList((const OCProvisionResult_t*) arr, nOfRes);
122 // callback function(s) for provisioning client using C-level provisioning API
123 static void ownershipTransferCB(void* ctx, size_t nOfRes, OCProvisionResult_t* arr, bool hasError)
127 OIC_LOG_V(INFO, TAG, "Ownership Transfer SUCCEEDED - ctx: %s", (char*) ctx);
131 OIC_LOG_V(ERROR, TAG, "Ownership Transfer FAILED - ctx: %s", (char*) ctx);
132 printResultList((const OCProvisionResult_t*) arr, nOfRes);
137 static void updateDoxmForMOTCB(void* ctx, size_t nOfRes, OCProvisionResult_t* arr, bool hasError)
141 OIC_LOG_V(INFO, TAG, "POST 'doxm' SUCCEEDED - ctx: %s", (char*) ctx);
145 OIC_LOG_V(ERROR, TAG, "POST 'doxm' FAILED - ctx: %s", (char*) ctx);
146 printResultList((const OCProvisionResult_t*) arr, nOfRes);
151 static void provisionCredCB(void* ctx, size_t nOfRes, OCProvisionResult_t* arr, bool hasError)
155 OIC_LOG_V(INFO, TAG, "Provision Credential SUCCEEDED - ctx: %s", (char*) ctx);
159 OIC_LOG_V(ERROR, TAG, "Provision Credential FAILED - ctx: %s", (char*) ctx);
160 printResultList((const OCProvisionResult_t*) arr, nOfRes);
165 static void provisionAclCB(void* ctx, size_t nOfRes, OCProvisionResult_t* arr, bool hasError)
169 OIC_LOG_V(INFO, TAG, "Provision ACL SUCCEEDED - ctx: %s", (char*) ctx);
173 OIC_LOG_V(ERROR, TAG, "Provision ACL FAILED - ctx: %s", (char*) ctx);
174 printResultList((const OCProvisionResult_t*) arr, nOfRes);
179 // response handler for LED requests.
180 static OCStackApplicationResult LedCB(void *ctx, OCDoHandle UNUSED, OCClientResponse *clientResponse)
184 if(OC_STACK_OK == clientResponse->result)
186 printf("Received OC_STACK_OK from server\n");
187 if(clientResponse->payload)
189 printf("Response ===================> %s\n", (char*)clientResponse->payload);
192 else if(OC_STACK_RESOURCE_CHANGED == clientResponse->result)
194 printf("Received OC_STACK_RESOURCE_CHANGED from server\n");
198 printf("Error in response : %d\n", clientResponse->result);
203 printf("Hit the response callback but can not find response data\n");
210 static void inputPinCB(char* pin, size_t len)
212 if(!pin || OXM_RANDOM_PIN_MAX_SIZE>=len)
214 OIC_LOG(ERROR, TAG, "inputPinCB invalid parameters");
218 printf(" > INPUT PIN: ");
219 for(int ret=0; 1!=ret; )
221 ret = scanf("%32s", pin);
222 for( ; 0x20<=getchar(); ); // for removing overflow garbages
223 // '0x20<=code' is character region
227 // function(s) for provisioning client using C-level provisioning API
228 static int initProvisionClient(void)
230 // initialize persistent storage for SVR DB
231 static OCPersistentStorage ps = {fopen_prvnMng, fread, fwrite, fclose, unlink};
232 if(OC_STACK_OK != OCRegisterPersistentStorageHandler(&ps))
234 OIC_LOG(ERROR, TAG, "OCRegisterPersistentStorageHandler error");
238 // initialize OC stack and provisioning manager
239 if(OC_STACK_OK != OCInit(NULL, 0, OC_CLIENT_SERVER))
241 OIC_LOG(ERROR, TAG, "OCStack init error");
245 if (access(PRVN_DB_FILE_NAME, F_OK) != -1)
247 printf("************************************************************\n");
248 printf("************Provisioning DB file already exists.************\n");
249 printf("************************************************************\n");
253 printf("*************************************************************\n");
254 printf("************No provisioning DB file, creating new************\n");
255 printf("*************************************************************\n");
258 if(OC_STACK_OK != OCInitPM(PRVN_DB_FILE_NAME))
260 OIC_LOG(ERROR, TAG, "OC_PM init error");
264 SetInputPinCB(inputPinCB);
269 static int discoverMotSupportedDevices(void)
271 // delete un/owned device lists before updating them
274 OCDeleteDiscoveredDevices(g_motdev_list);
275 g_motdev_list = NULL;
278 // call |OCDiscoverMultipleOwnerEnabledDevices| API actually
279 printf(" Discovering Multiple Ownership Transfer enabled Devices on Network..\n");
280 if(OC_STACK_OK != OCDiscoverMultipleOwnerEnabledDevices(DISCOVERY_TIMEOUT, &g_motdev_list))
282 OIC_LOG(ERROR, TAG, "OCDiscoverMultipleOwnerEnalbedDevices API error");
286 // display the discovered device lists
287 printf(" > Discovered Multiple Ownership Transfer Enabled Devices\n");
288 g_motdev_cnt = printDevList(g_motdev_list);
293 static int discoverSubOwnerDevices()
295 // delete un/owned device lists before updating them
298 OCDeleteDiscoveredDevices(g_mowned_list);
299 g_mowned_list = NULL;
302 // call |OCDiscoverMultipleOwnedDevices| API actually
303 printf(" Discovering Multiple Owned Devices on Network..\n");
304 if(OC_STACK_OK != OCDiscoverMultipleOwnedDevices(DISCOVERY_TIMEOUT, &g_mowned_list))
306 OIC_LOG(ERROR, TAG, "OCDiscoverMultipleOwnerEnabledDevices API error");
310 // display the discovered device lists
311 printf(" > Discovered Multiple Owned Devices\n");
312 g_mowned_cnt = printDevList(g_mowned_list);
317 static int multipleOwnershipTransfer(void)
319 // check |unown_list| for registering devices
320 if(!g_motdev_list || 0 >=g_motdev_cnt)
322 printf(" > MultipleOwnershipTransfer Enabled Device List is Empty\n");
323 printf(" > Please Discover Devices first, with [10] Menu\n");
324 return 0; // normal case
327 // call |getDevInst| API actually
328 // calling this API with callback actually acts like blocking
329 // for error checking, the return value saved and printed
332 #ifdef MULTIPLE_OWNER
333 OCProvisionDev_t* dev = NULL;
334 LL_FOREACH(g_motdev_list, dev)
336 if(OIC_PRECONFIG_PIN == dev->doxm->oxmSel)
338 //Pre-Configured PIN initialization
339 const char* testPreconfigPin = "12341234";
340 if(OC_STACK_OK != OCAddPreconfigPin(dev, testPreconfigPin, strlen(testPreconfigPin)))
342 printf("\n\n\n*** %60s ***\n", "WARNNING : Failed to save the pre-configured PIN");
343 printf("*** %60s ***\n\n\n", "WARNNING : You can't use the pre-configured PIN OxM for MOT");
348 #endif //MULTIPLE_OWNER
350 if(OC_STACK_OK != OCDoMultipleOwnershipTransfer(g_ctx, g_motdev_list, multipleOwnershipTransferCB))
352 OIC_LOG(ERROR, TAG, "_20_PERFORM_MOT_: error");
356 if(waitCallbackRet()) // input |g_doneCB| flag implicitly
358 OIC_LOG(ERROR, TAG, "OCProvisionCredentials callback error");
362 // display the registered result
363 printf(" > Registered Discovered Devices\n");
368 static int sendGetLed()
371 char query[256] = {0};
372 OCCallbackData cbData;
374 cbData.context = NULL;
377 printDevList(g_mowned_list);
379 // select device for provisioning access control list
382 printf(" > Enter Device Number, for sending GET LED request: ");
383 for(int ret=0; 1!=ret; )
385 ret = scanf("%d", &selDevNum);
386 for( ; 0x20<=getchar(); ); // for removing overflow garbages
387 // '0x20<=code' is character region
389 if(0<selDevNum && g_mowned_cnt>=selDevNum)
393 printf(" Entered Wrong Number. Please Enter Again\n");
396 OCProvisionDev_t* selDev = getDevInst(g_mowned_list, selDevNum);
399 printf("Failed to getDevInst()\n");
403 if(PMGenerateQuery(true, selDev->endpoint.addr, selDev->securePort, selDev->connType, query, sizeof(query), "/a/led"))
406 printf("query=%s\n", query);
407 if(OC_STACK_OK != OCDoResource(NULL, OC_REST_GET, query, NULL, NULL, selDev->connType, OC_HIGH_QOS, &cbData, NULL, 0))
409 printf("********************************\n");
410 printf("Failed to send GET request to %s\n", query);
411 printf("********************************\n");
420 printf("Failed to generate GET request for /a/led\n");
427 static int sendPutLed()
430 char query[256] = {0};
431 OCCallbackData cbData;
433 cbData.context = NULL;
436 printDevList(g_mowned_list);
437 // select device for provisioning access control list
440 printf(" > Enter Device Number, for sending PUT LED request: ");
441 for(int ret=0; 1!=ret; )
443 ret = scanf("%d", &selDevNum);
444 for( ; 0x20<=getchar(); ); // for removing overflow garbages
445 // '0x20<=code' is character region
447 if(0<selDevNum && g_mowned_cnt>=selDevNum)
451 printf(" Entered Wrong Number. Please Enter Again\n");
454 OCProvisionDev_t* selDev = getDevInst(g_mowned_list, selDevNum);
457 printf("Failed to getDevInst()\n");
461 if(PMGenerateQuery(true, selDev->endpoint.addr, selDev->securePort, selDev->connType, query, sizeof(query), "/a/led"))
464 printf("query=%s\n", query);
465 if(OC_STACK_OK != OCDoResource(NULL, OC_REST_PUT, query, NULL, NULL, selDev->connType, OC_LOW_QOS, &cbData, NULL, 0))
467 printf("********************************\n");
468 printf("Failed to send PUT request to %s\n", query);
469 printf("********************************\n");
478 printf("Failed to generate PUT request for /a/led\n");
486 static OicSecAcl_t* createAclForLEDAccess(const OicUuid_t* subject)
490 OIC_LOG(ERROR, TAG, "createAcl: Invalid paramters");
493 // allocate memory for |acl| struct
494 OicSecAcl_t* acl = (OicSecAcl_t*) OICCalloc(1, sizeof(OicSecAcl_t));
497 OIC_LOG(ERROR, TAG, "createAcl: OICCalloc error return");
498 return NULL; // not need to 'goto' |ERROR| before allocating |acl|
500 OicSecAce_t* ace = (OicSecAce_t*) OICCalloc(1, sizeof(OicSecAce_t));
503 OIC_LOG(ERROR, TAG, "createAcl: OICCalloc error return");
504 return NULL; // not need to 'goto' |ERROR| before allocating |acl|
506 LL_APPEND(acl->aces, ace);
507 memcpy(ace->subjectuuid.id, subject->id, sizeof(subject->id));
510 char* rsrc_in = "/a/led"; // '1' for null termination
511 OicSecRsrc_t* rsrc = (OicSecRsrc_t*)OICCalloc(1, sizeof(OicSecRsrc_t));
514 OIC_LOG(ERROR, TAG, "createAcl: OICCalloc error return");
518 size_t len = strlen(rsrc_in)+1; // '1' for null termination
519 rsrc->href = (char*) OICCalloc(len, sizeof(char));
522 OIC_LOG(ERROR, TAG, "createAcl: OICCalloc error return");
525 OICStrcpy(rsrc->href, len, rsrc_in);
527 //fill the resource type (rt)
529 rsrc->types = (char**)OICCalloc(1, sizeof(char*));
532 OIC_LOG(ERROR, TAG, "createAcl: OICCalloc error return");
535 rsrc->types[0] = OICStrdup("oic.r.core");
538 OIC_LOG(ERROR, TAG, "createAcl: OICStrdup error return");
542 //fill the interface (if)
543 rsrc->interfaceLen = 1;
544 rsrc->interfaces = (char**)OICCalloc(1, sizeof(char*));
545 if(!rsrc->interfaces)
547 OIC_LOG(ERROR, TAG, "createAcl: OICCalloc error return");
550 rsrc->interfaces[0] = OICStrdup("oic.if.baseline");
551 if(!rsrc->interfaces[0])
553 OIC_LOG(ERROR, TAG, "createAcl: OICStrdup error return");
557 LL_APPEND(ace->resources, rsrc);
559 // full permission for /a/led
560 ace->permission = PERMISSION_FULL_CONTROL;
562 ace->eownerID = (OicUuid_t*)OICCalloc(1, sizeof(OicUuid_t));
563 if(NULL == ace->eownerID)
565 OIC_LOG(ERROR, TAG, "createAcl: OICCalloc error return");
569 memcpy(ace->eownerID->id, subject->id, sizeof(subject->id));
574 OCDeleteACLList(acl); // after here |acl| points nothing
578 static int provisionAclForLed()
580 OicSecAcl_t* acl = NULL;
582 // check |own_list| for provisioning access control list
583 if(!g_mowned_list || 1> g_mowned_cnt)
585 printf(" > MOT Device List is Empty\n");
586 printf(" > Please Perform MOT first, with [12|21] Menu\n");
587 return 0; // normal case
590 // display the MOT dev list
591 printf(" > MOT Devices\n");
592 g_mowned_cnt = printDevList(g_mowned_list);
594 // select device for provisioning access control list
598 printf(" > Enter Device Number, for Provisioning LED's ACL: ");
599 for(int ret=0; 1!=ret; )
601 ret = scanf("%d", &dev_num);
602 for( ; 0x20<=getchar(); ); // for removing overflow garbages
603 // '0x20<=code' is character region
605 if (0 < dev_num && g_mowned_cnt >= dev_num)
609 printf(" Entered Wrong Number. Please Enter Again\n");
613 printf(" Provisioning Selected ACL..\n");
614 OCProvisionDev_t* dev = getDevInst((const OCProvisionDev_t*) g_mowned_list, dev_num);
617 OIC_LOG(ERROR, TAG, "provisionAcl: device instance empty");
621 acl = createAclForLEDAccess(&dev->doxm->subOwners->uuid);
624 OIC_LOG(ERROR, TAG, "provisionAcl: Failed to create ACL for LED");
628 OCStackResult rst = OCProvisionACL((void*) g_ctx, dev, acl, provisionAclCB);
629 if(OC_STACK_OK != rst)
631 OIC_LOG_V(ERROR, TAG, "OCProvisionACL API error: %d", rst);
634 if(waitCallbackRet()) // input |g_doneCB| flag implicitly
636 OIC_LOG(ERROR, TAG, "OCProvisionCredentials callback error");
639 // display the ACL-provisioned result
640 printf(" > Provisioned Selected ACL\n");
642 OCDeleteACLList(acl); // after here |acl| points nothing
646 OCDeleteACLList(acl);
650 static int provisionCred()
652 // check |unown_list| for registering devices
653 if(!g_mowned_list|| 0 >=g_mowned_cnt)
655 printf(" > Multiple Owned Device List is Empty\n");
656 printf(" > Please Discover Devices first, with [13] Menu\n");
657 return 0; // normal case
660 // display the MOT dev list
661 printf(" > Multiple Owned Devices\n");
662 g_mowned_cnt = printDevList(g_mowned_list);
667 printf(" > Enter Multiple Owned Device Number to link : ");
668 for(int ret=0; 1!=ret; )
670 ret = scanf("%d", &dev_num);
671 for( ; 0x20<=getchar(); ); // for removing overflow garbages
672 // '0x20<=code' is character region
674 if(0<dev_num && g_mowned_cnt>=dev_num)
678 printf(" Entered Wrong Number. Please Enter Again\n");
681 OCProvisionDev_t* motDev = getDevInst(g_mowned_list, dev_num);
684 OIC_LOG(ERROR, TAG, "Failed to getDevInst()");
688 // display the MOT dev list
689 printf(" > Owned Devices\n");
690 g_own_cnt = printDevList(g_own_list);
694 printf(" > Enter Owned Device Number to link : ");
695 for(int ret=0; 1!=ret; )
697 ret = scanf("%d", &dev_num);
698 for( ; 0x20<=getchar(); ); // for removing overflow garbages
699 // '0x20<=code' is character region
701 if(0<dev_num && g_own_cnt>=dev_num)
705 printf(" Entered Wrong Number. Please Enter Again\n");
708 OCProvisionDev_t* ownDev = getDevInst(g_own_list, dev_num);
711 OIC_LOG(ERROR, TAG, "Failed to getDevInst()");
715 // call |OCProvisionCredentials| API actually
716 // calling this API with callback actually acts like blocking
717 // for error checking, the return value saved and printed
719 printf(" Provisioning Selected Pairwise Devices..\n");
720 OCStackResult rst = OCProvisionCredentials((void*) g_ctx,
721 SYMMETRIC_PAIR_WISE_KEY, OWNER_PSK_LENGTH_128,
722 ownDev, motDev, provisionCredCB);
723 if(OC_STACK_OK != rst)
725 OIC_LOG_V(ERROR, TAG, "OCProvisionPairwiseDevices API error: %d", rst);
728 if(waitCallbackRet()) // input |g_doneCB| flag implicitly
730 OIC_LOG(ERROR, TAG, "OCProvisionCredentials callback error");
734 // display the pairwise-provisioned result
735 printf(" > Provisioned Selected Pairwise Devices\n");
743 static OCProvisionDev_t* getDevInst(const OCProvisionDev_t* dev_lst, const int dev_num)
745 if(!dev_lst || 0>=dev_num)
747 printf(" Device List is Empty..\n");
751 OCProvisionDev_t* lst = (OCProvisionDev_t*) dev_lst;
761 return NULL; // in here |lst| is always |NULL|
764 static int printDevList(const OCProvisionDev_t* dev_lst)
768 printf(" Device List is Empty..\n\n");
772 OCProvisionDev_t* lst = (OCProvisionDev_t*) dev_lst;
776 printf(" [%d] ", ++lst_cnt);
777 printUuid((const OicUuid_t*) &lst->doxm->deviceID);
786 static size_t printUuidList(const OCUuidList_t* uid_lst)
790 printf(" Device List is Empty..\n\n");
794 OCUuidList_t* lst = (OCUuidList_t*) uid_lst;
798 printf(" [%" PRIuPTR "] ", ++lst_cnt);
799 printUuid((const OicUuid_t*) &lst->dev);
808 static size_t printResultList(const OCProvisionResult_t* rslt_lst, const size_t rslt_cnt)
810 if (!rslt_lst || (0 == rslt_cnt))
812 printf(" Device List is Empty..\n\n");
819 printf(" [%" PRIuPTR "] ", lst_cnt + 1);
820 printUuid((const OicUuid_t*)&rslt_lst[lst_cnt].deviceId);
821 printf(" - result: %d\n", rslt_lst[lst_cnt].res);
822 } while (++lst_cnt < rslt_cnt);
828 static void printUuid(const OicUuid_t* uid)
830 for(int i=0; i<UUID_LENGTH; )
832 printf("%02X", (*uid).id[i++]);
833 if(i==4 || i==6 || i==8 || i==10) // canonical format for UUID has '8-4-4-4-12'
840 static FILE* fopen_prvnMng(const char* path, const char* mode)
842 if (0 == strcmp(path, OC_SECURITY_DB_DAT_FILE_NAME))
844 // input |g_svr_db_fname| internally by force, not using |path| parameter
845 // because |OCPersistentStorage::open| is called |OCPersistentStorage| internally
846 // with its own |SVR_DB_FILE_NAME|
847 return fopen(SVR_DB_FILE_NAME, mode);
851 return fopen(path, mode);
855 static int waitCallbackRet(void)
857 for(int i=0; !g_doneCB && CALLBACK_TIMEOUT>i; ++i)
860 if(OC_STACK_OK != OCProcess())
862 OIC_LOG(ERROR, TAG, "OCStack process error");
870 static int selectTwoDiffNum(int* a, int* b, const int max, const char* str)
872 if(!a || !b || 2>max || !str)
879 for(int i=0; 2>i; ++i)
884 printf(" > Enter Device[%d] Number, %s: ", i+1, str);
885 for(int ret=0; 1!=ret; )
887 ret = scanf("%d", num);
888 for( ; 0x20<=getchar(); ); // for removing overflow garbages
889 // '0x20<=code' is character region
891 if(0<*num && max>=*num)
895 printf(" Entered Wrong Number. Please Enter Again\n");
908 static void printMenu(void)
910 printf("************************************************************\n");
911 printf("****** OIC Provisioning Client with using C-level API ******\n");
912 printf("************************************************************\n\n");
914 printf("** [A] DISCOVER DEVICES ON NETWORK\n");
915 printf("** 10. Discover Multiple Ownership Transfer Enabled Devices on Network\n");
916 printf("** 11. Discover Multiple Owned Devices on Network\n\n");
918 printf("** [B] PERFORM MULTIPLE OWNERSHIP TRANSFER\n");
919 printf("** 20. Perform the Multiple Ownership Transfer for ALL discovered dievices\n\n");
921 printf("** [C] Get/Put Request for APPLICATION RESOURCE\n");
922 printf("** 30. Get LED resource\n");
923 printf("** 31. Put LED resource\n\n");
925 printf("** [D] LINK DEVICES\n");
926 printf("** 40. Provision ACL for LED Resource\n");
927 printf("** 41. Provison Credential\n\n");
929 printf("** [F] EXIT PROVISIONING CLIENT\n");
930 printf("** 99. Exit Provisionong Client\n\n");
932 printf("************************************************************\n\n");
935 // main function for provisioning client using C-level provisioning API
938 // initialize provisioning client
939 if(initProvisionClient())
941 OIC_LOG(ERROR, TAG, "ProvisionClient init error");
945 // main loop for provisioning manager
952 printf(">> Enter Menu Number: ");
953 for(int ret=0; 1!=ret; )
955 ret = scanf("%d", &mnNum);
956 for( ; 0x20<=getchar(); ); // for removing overflow garbages
957 // '0x20<=code' is character region
962 case _10_DISCOV_MOT_ENABLED_DEV_:
963 if(discoverMotSupportedDevices())
965 OIC_LOG(ERROR, TAG, "_12_MOT_DISCOV_DEV_: error");
968 case _11_DISCOV_MULTIPLE_OWNED_DEV_:
969 if(discoverSubOwnerDevices())
971 OIC_LOG(ERROR, TAG, "_13_DISCOV_MULTIPLE_OWNED_DEV_: error");
974 case _20_PERFORM_MOT_:
975 if(multipleOwnershipTransfer())
977 OIC_LOG(ERROR, TAG, "_21_PERFORM_MOT_: error");
980 case _30_GET_LED_RESOURCE_:
983 OIC_LOG(ERROR, TAG, "_30_GET_LED_RESOURCE_: error");
986 case _31_PUT_LED_RESOURCE_:
989 OIC_LOG(ERROR, TAG, "_31_PUT_LED_RESOURCE_: error");
992 case _40_PROVISION_ACL_:
993 if(provisionAclForLed())
995 OIC_LOG(ERROR, TAG, "_40_PROVISION_ACL_: error");
998 case _41_PROVISION_CRED_:
999 OIC_LOG(ERROR, TAG, "NOT SUPPORTED YET.");
1004 OIC_LOG(ERROR, TAG, "_41_PROVISION_CRED_: error");
1008 case _99_EXIT_PRVN_CLT_:
1011 printf(">> Entered Wrong Number. Please Enter Again\n\n");
1017 if(OC_STACK_OK != OCStop())
1019 OIC_LOG(ERROR, TAG, "OCStack stop error");
1021 OCDeleteDiscoveredDevices(g_own_list); // after here |g_own_list| points nothing
1022 OCDeleteDiscoveredDevices(g_unown_list); // after here |g_unown_list| points nothing
1023 OCDeleteDiscoveredDevices(g_motdev_list); // after here |g_motdev_list| points nothing
1027 OICFree(g_svr_fname); // after here |g_svr_fname| points nothing
1031 OICFree(g_prvn_fname); // after here |g_prvn_fname| points nothing
1033 return 0; // always return normal case
1038 #endif //__cplusplus