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"
28 #include "platform_features.h"
31 #include "oic_malloc.h"
32 #include "oic_string.h"
33 #include "ocprovisioningmanager.h"
34 #include "oxmjustworks.h"
35 #include "oxmrandompin.h"
36 #include "securevirtualresourcetypes.h"
37 #include "srmutility.h"
39 #include "pmutility.h"
46 // declaration(s) for provisioning client using C-level provisioning API
47 // user input definition for main loop on provisioning client
48 #define _10_DISCOV_MOT_ENABLED_DEV_ 10
49 #define _11_DISCOV_MULTIPLE_OWNED_DEV_ 11
50 #define _20_PERFORM_MOT_ 20
51 #define _30_GET_LED_RESOURCE_ 30
52 #define _31_PUT_LED_RESOURCE_ 31
53 #define _40_PROVISION_ACL_ 40
54 #define _41_PROVISION_CRED_ 41
55 #define _99_EXIT_PRVN_CLT_ 99
57 #define ACL_RESRC_MAX_NUM 16
58 #define ACL_RESRC_ARRAY_SIZE 3 //This value is used only for sample (not OCF spec)
59 #define ACL_RESRC_MAX_LEN 128
60 #define ACL_PEMISN_CNT 5
61 #define DISCOVERY_TIMEOUT 5 // 5 sec
62 #define CALLBACK_TIMEOUT 60 // 1 min
63 #define TAG "subownerclient"
65 static const char* SVR_DB_FILE_NAME = "oic_svr_db_subowner_client.dat";
66 // '_' for separaing from the same constant variable in |srmresourcestrings.c|
67 static const char* PRVN_DB_FILE_NAME = "oic_pdm_subowner.db";
68 static const OicSecPrm_t SUPPORTED_PRMS[1] =
73 // |g_ctx| means provision manager application context and
74 // the following, includes |un/own_list|, could be variables, which |g_ctx| has,
75 // for accessing all function(s) for these, they are declared on global domain
76 static const char* g_ctx = "SubOwner Client Application Context";
77 static char* g_svr_fname;
78 static char* g_prvn_fname;
79 static OCProvisionDev_t* g_own_list;
80 static OCProvisionDev_t* g_unown_list;
81 static OCProvisionDev_t* g_motdev_list;
82 static OCProvisionDev_t* g_mowned_list;
84 static int g_unown_cnt;
85 static int g_motdev_cnt;
86 static int g_mowned_cnt;
89 // function declaration(s) for calling them before implementing
90 static OCProvisionDev_t* getDevInst(const OCProvisionDev_t*, const int);
91 static int printDevList(const OCProvisionDev_t*);
92 static size_t printUuidList(const OCUuidList_t*);
93 static int printResultList(const OCProvisionResult_t*, const int);
94 static void printUuid(const OicUuid_t*);
95 static FILE* fopen_prvnMng(const char*, const char*);
96 static int waitCallbackRet(void);
97 static int selectTwoDiffNum(int*, int*, const int, const char*);
99 // callback function(s) for provisioning client using C-level provisioning API
100 static void multipleOwnershipTransferCB(void* ctx, int nOfRes, OCProvisionResult_t* arr, bool hasError)
104 OIC_LOG_V(INFO, TAG, "Multiple Ownership Transfer SUCCEEDED - ctx: %s", (char*) ctx);
108 OIC_LOG_V(ERROR, TAG, "Multiple Ownership Transfer FAILED - ctx: %s", (char*) ctx);
109 printResultList((const OCProvisionResult_t*) arr, nOfRes);
114 // callback function(s) for provisioning client using C-level provisioning API
115 static void ownershipTransferCB(void* ctx, int nOfRes, OCProvisionResult_t* arr, bool hasError)
119 OIC_LOG_V(INFO, TAG, "Ownership Transfer SUCCEEDED - ctx: %s", (char*) ctx);
123 OIC_LOG_V(ERROR, TAG, "Ownership Transfer FAILED - ctx: %s", (char*) ctx);
124 printResultList((const OCProvisionResult_t*) arr, nOfRes);
129 static void updateDoxmForMOTCB(void* ctx, int nOfRes, OCProvisionResult_t* arr, bool hasError)
133 OIC_LOG_V(INFO, TAG, "POST 'doxm' SUCCEEDED - ctx: %s", (char*) ctx);
137 OIC_LOG_V(ERROR, TAG, "POST 'doxm' FAILED - ctx: %s", (char*) ctx);
138 printResultList((const OCProvisionResult_t*) arr, nOfRes);
143 static void provisionCredCB(void* ctx, int nOfRes, OCProvisionResult_t* arr, bool hasError)
147 OIC_LOG_V(INFO, TAG, "Provision Credential SUCCEEDED - ctx: %s", (char*) ctx);
151 OIC_LOG_V(ERROR, TAG, "Provision Credential FAILED - ctx: %s", (char*) ctx);
152 printResultList((const OCProvisionResult_t*) arr, nOfRes);
157 static void provisionAclCB(void* ctx, int nOfRes, OCProvisionResult_t* arr, bool hasError)
161 OIC_LOG_V(INFO, TAG, "Provision ACL SUCCEEDED - ctx: %s", (char*) ctx);
165 OIC_LOG_V(ERROR, TAG, "Provision ACL FAILED - ctx: %s", (char*) ctx);
166 printResultList((const OCProvisionResult_t*) arr, nOfRes);
171 // response handler for LED requests.
172 static void LedCB(void *ctx, OCDoHandle UNUSED,
173 OCClientResponse *clientResponse)
177 if(OC_STACK_OK == clientResponse->result)
179 printf("Received OC_STACK_OK from server\n");
180 if(clientResponse->payload)
182 printf("Response ===================> %s\n", clientResponse->payload);
185 else if(OC_STACK_RESOURCE_CHANGED == clientResponse->result)
187 printf("Received OC_STACK_RESOURCE_CHANGED from server\n");
191 printf("Error in response : %d\n", clientResponse->result);
196 printf("Hit the response callback but can not find response data\n");
202 static void inputPinCB(char* pin, size_t len)
204 if(!pin || OXM_RANDOM_PIN_SIZE>=len)
206 OIC_LOG(ERROR, TAG, "inputPinCB invalid parameters");
210 printf(" > INPUT PIN: ");
211 for(int ret=0; 1!=ret; )
213 ret = scanf("%8s", pin);
214 for( ; 0x20<=getchar(); ); // for removing overflow garbages
215 // '0x20<=code' is character region
219 // function(s) for provisioning client using C-level provisioning API
220 static int initProvisionClient(void)
222 // initialize persistent storage for SVR DB
223 static OCPersistentStorage ps = {fopen_prvnMng, fread, fwrite, fclose, unlink};
224 if(OC_STACK_OK != OCRegisterPersistentStorageHandler(&ps))
226 OIC_LOG(ERROR, TAG, "OCRegisterPersistentStorageHandler error");
230 // initialize OC stack and provisioning manager
231 if(OC_STACK_OK != OCInit(NULL, 0, OC_CLIENT_SERVER))
233 OIC_LOG(ERROR, TAG, "OCStack init error");
237 if (access(PRVN_DB_FILE_NAME, F_OK) != -1)
239 printf("************************************************************\n");
240 printf("************Provisioning DB file already exists.************\n");
241 printf("************************************************************\n");
245 printf("*************************************************************\n");
246 printf("************No provisioning DB file, creating new************\n");
247 printf("*************************************************************\n");
250 if(OC_STACK_OK != OCInitPM(PRVN_DB_FILE_NAME))
252 OIC_LOG(ERROR, TAG, "OC_PM init error");
256 SetInputPinCB(inputPinCB);
261 static int discoverMotSupportedDevices(void)
263 // delete un/owned device lists before updating them
266 OCDeleteDiscoveredDevices(g_motdev_list);
267 g_motdev_list = NULL;
270 // call |OCDiscoverMultipleOwnerEnabledDevices| API actually
271 printf(" Discovering Multiple Ownership Transfer enabled Devices on Network..\n");
272 if(OC_STACK_OK != OCDiscoverMultipleOwnerEnabledDevices(DISCOVERY_TIMEOUT, &g_motdev_list))
274 OIC_LOG(ERROR, TAG, "OCDiscoverMultipleOwnerEnalbedDevices API error");
278 // display the discovered device lists
279 printf(" > Discovered Multiple Ownership Transfer Enabled Devices\n");
280 g_motdev_cnt = printDevList(g_motdev_list);
285 static int discoverSubOwnerDevices()
287 // delete un/owned device lists before updating them
290 OCDeleteDiscoveredDevices(g_mowned_list);
291 g_mowned_list = NULL;
294 // call |OCDiscoverMultipleOwnedDevices| API actually
295 printf(" Discovering Multiple Owned Devices on Network..\n");
296 if(OC_STACK_OK != OCDiscoverMultipleOwnedDevices(DISCOVERY_TIMEOUT, &g_mowned_list))
298 OIC_LOG(ERROR, TAG, "OCDiscoverMultipleOwnerEnabledDevices API error");
302 // display the discovered device lists
303 printf(" > Discovered Multiple Owned Devices\n");
304 g_mowned_cnt = printDevList(g_mowned_list);
309 static int multipleOwnershipTransfer(void)
311 // check |unown_list| for registering devices
312 if(!g_motdev_list || 0 >=g_motdev_cnt)
314 printf(" > MultipleOwnershipTransfer Enabled Device List is Empty\n");
315 printf(" > Please Discover Devices first, with [10] Menu\n");
316 return 0; // normal case
319 // call |getDevInst| API actually
320 // calling this API with callback actually acts like blocking
321 // for error checking, the return value saved and printed
324 #ifdef _ENABLE_MULTIPLE_OWNER_
325 OCProvisionDev_t* dev = NULL;
326 LL_FOREACH(g_motdev_list, dev)
328 if(OIC_PRECONFIG_PIN == dev->doxm->oxmSel)
330 //Pre-Configured PIN initialization
331 if(OC_STACK_OK != OCAddPreconfigPIN(dev, "12341234", OXM_PRECONFIG_PIN_SIZE))
333 printf("\n\n\n*** %60s ***\n", "WARNNING : Failed to save the pre-configured PIN");
334 printf("*** %60s ***\n\n\n", "WARNNING : You can't use the pre-configured PIN OxM for MOT");
339 #endif //_ENABLE_MULTIPLE_OWNER_
341 if(OC_STACK_OK != OCDoMultipleOwnershipTransfer(g_ctx, g_motdev_list, multipleOwnershipTransferCB))
343 OIC_LOG(ERROR, TAG, "_20_PERFORM_MOT_: error");
347 if(waitCallbackRet()) // input |g_doneCB| flag implicitly
349 OIC_LOG(ERROR, TAG, "OCProvisionCredentials callback error");
353 // display the registered result
354 printf(" > Registered Discovered Devices\n");
359 static int sendGetLed()
362 char query[256] = {0};
363 OCCallbackData cbData;
365 cbData.context = NULL;
368 printDevList(g_mowned_list);
370 // select device for provisioning access control list
373 printf(" > Enter Device Number, for sending GET LED request: ");
374 for(int ret=0; 1!=ret; )
376 ret = scanf("%d", &selDevNum);
377 for( ; 0x20<=getchar(); ); // for removing overflow garbages
378 // '0x20<=code' is character region
380 if(0<selDevNum && g_mowned_cnt>=selDevNum)
384 printf(" Entered Wrong Number. Please Enter Again\n");
387 OCProvisionDev_t* selDev = getDevInst(g_mowned_list, selDevNum);
390 printf("Failed to getDevInst()\n");
394 if(PMGenerateQuery(true, selDev->endpoint.addr, selDev->securePort, selDev->connType,
395 query, sizeof(query), "/a/led"))
398 printf("query=%s\n", query);
399 if(OC_STACK_OK != OCDoResource(NULL, OC_REST_GET, query, NULL, NULL, selDev->connType,
400 OC_HIGH_QOS, &cbData, NULL, 0))
402 printf("********************************\n");
403 printf("Failed to send GET request to %s\n", query);
404 printf("********************************\n");
413 printf("Failed to generate GET request for /a/led\n");
420 static int sendPutLed()
423 char query[256] = {0};
424 OCCallbackData cbData;
426 cbData.context = NULL;
429 printDevList(g_mowned_list);
430 // select device for provisioning access control list
433 printf(" > Enter Device Number, for sending PUT LED request: ");
434 for(int ret=0; 1!=ret; )
436 ret = scanf("%d", &selDevNum);
437 for( ; 0x20<=getchar(); ); // for removing overflow garbages
438 // '0x20<=code' is character region
440 if(0<selDevNum && g_mowned_cnt>=selDevNum)
444 printf(" Entered Wrong Number. Please Enter Again\n");
447 OCProvisionDev_t* selDev = getDevInst(g_mowned_list, selDevNum);
450 printf("Failed to getDevInst()\n");
454 if(PMGenerateQuery(true, selDev->endpoint.addr, selDev->securePort, selDev->connType,
455 query, sizeof(query), "/a/led"))
458 printf("query=%s\n", query);
459 if(OC_STACK_OK != OCDoResource(NULL, OC_REST_PUT, query, NULL, NULL, selDev->connType,
460 OC_LOW_QOS, &cbData, NULL, 0))
462 printf("********************************\n");
463 printf("Failed to send PUT request to %s\n", query);
464 printf("********************************\n");
473 printf("Failed to generate PUT request for /a/led\n");
481 static OicSecAcl_t* createAclForLEDAccess(const OicUuid_t* subject)
485 OIC_LOG(ERROR, TAG, "createAcl: Invalid paramters");
488 // allocate memory for |acl| struct
489 OicSecAcl_t* acl = (OicSecAcl_t*) OICCalloc(1, sizeof(OicSecAcl_t));
492 OIC_LOG(ERROR, TAG, "createAcl: OICCalloc error return");
493 return NULL; // not need to 'goto' |ERROR| before allocating |acl|
495 OicSecAce_t* ace = (OicSecAce_t*) OICCalloc(1, sizeof(OicSecAce_t));
498 OIC_LOG(ERROR, TAG, "createAcl: OICCalloc error return");
499 return NULL; // not need to 'goto' |ERROR| before allocating |acl|
501 LL_APPEND(acl->aces, ace);
502 memcpy(ace->subjectuuid.id, subject->id, sizeof(subject->id));
505 char* rsrc_in = "/a/led"; // '1' for null termination
506 OicSecRsrc_t* rsrc = (OicSecRsrc_t*)OICCalloc(1, sizeof(OicSecRsrc_t));
509 OIC_LOG(ERROR, TAG, "createAcl: OICCalloc error return");
513 size_t len = strlen(rsrc_in)+1; // '1' for null termination
514 rsrc->href = (char*) OICCalloc(len, sizeof(char));
517 OIC_LOG(ERROR, TAG, "createAcl: OICCalloc error return");
520 OICStrcpy(rsrc->href, len, rsrc_in);
522 //fill the resource type (rt)
524 rsrc->types = (char**)OICCalloc(1, sizeof(char*));
527 OIC_LOG(ERROR, TAG, "createAcl: OICCalloc error return");
530 rsrc->types[0] = OICStrdup("oic.r.core");
533 OIC_LOG(ERROR, TAG, "createAcl: OICStrdup error return");
537 //fill the interface (if)
538 rsrc->interfaceLen = 1;
539 rsrc->interfaces = (char**)OICCalloc(1, sizeof(char*));
540 if(!rsrc->interfaces)
542 OIC_LOG(ERROR, TAG, "createAcl: OICCalloc error return");
545 rsrc->interfaces[0] = OICStrdup("oic.if.baseline");
546 if(!rsrc->interfaces[0])
548 OIC_LOG(ERROR, TAG, "createAcl: OICStrdup error return");
552 LL_APPEND(ace->resources, rsrc);
554 // full permission for /a/led
555 ace->permission = PERMISSION_FULL_CONTROL;
557 ace->eownerID = (OicUuid_t*)OICCalloc(1, sizeof(OicUuid_t));
558 if(NULL == ace->eownerID)
560 OIC_LOG(ERROR, TAG, "createAcl: OICCalloc error return");
564 memcpy(ace->eownerID->id, subject->id, sizeof(subject->id));
569 OCDeleteACLList(acl); // after here |acl| points nothing
573 static int provisionAclForLed()
575 OicSecAcl_t* acl = NULL;
577 // check |own_list| for provisioning access control list
578 if(!g_mowned_list || 1> g_mowned_cnt)
580 printf(" > MOT Device List is Empty\n");
581 printf(" > Please Perform MOT first, with [12|21] Menu\n");
582 return 0; // normal case
585 // display the MOT dev list
586 printf(" > MOT Devices\n");
587 g_mowned_cnt = printDevList(g_mowned_list);
589 // select device for provisioning access control list
593 printf(" > Enter Device Number, for Provisioning LED's ACL: ");
594 for(int ret=0; 1!=ret; )
596 ret = scanf("%d", &dev_num);
597 for( ; 0x20<=getchar(); ); // for removing overflow garbages
598 // '0x20<=code' is character region
600 if(0<dev_num && g_mowned_list>=dev_num)
604 printf(" Entered Wrong Number. Please Enter Again\n");
608 printf(" Provisioning Selected ACL..\n");
609 OCProvisionDev_t* dev = getDevInst((const OCProvisionDev_t*) g_mowned_list, dev_num);
612 OIC_LOG(ERROR, TAG, "provisionAcl: device instance empty");
616 acl = createAclForLEDAccess(&dev->doxm->subOwners->uuid);
619 OIC_LOG(ERROR, TAG, "provisionAcl: Failed to create ACL for LED");
623 OCStackResult rst = OCProvisionACL((void*) g_ctx, dev, acl, provisionAclCB);
624 if(OC_STACK_OK != rst)
626 OIC_LOG_V(ERROR, TAG, "OCProvisionACL API error: %d", rst);
629 if(waitCallbackRet()) // input |g_doneCB| flag implicitly
631 OIC_LOG(ERROR, TAG, "OCProvisionCredentials callback error");
634 // display the ACL-provisioned result
635 printf(" > Provisioned Selected ACL\n");
637 OCDeleteACLList(acl); // after here |acl| points nothing
641 OCDeleteACLList(acl);
645 static int provisionCred()
647 // check |unown_list| for registering devices
648 if(!g_mowned_list|| 0 >=g_mowned_cnt)
650 printf(" > Multiple Owned Device List is Empty\n");
651 printf(" > Please Discover Devices first, with [13] Menu\n");
652 return 0; // normal case
655 // display the MOT dev list
656 printf(" > Multiple Owned Devices\n");
657 g_mowned_cnt = printDevList(g_mowned_list);
662 printf(" > Enter Multiple Owned Device Number to link : ");
663 for(int ret=0; 1!=ret; )
665 ret = scanf("%d", &dev_num);
666 for( ; 0x20<=getchar(); ); // for removing overflow garbages
667 // '0x20<=code' is character region
669 if(0<dev_num && g_mowned_cnt>=dev_num)
673 printf(" Entered Wrong Number. Please Enter Again\n");
676 OCProvisionDev_t* motDev = getDevInst(g_mowned_list, dev_num);
679 OIC_LOG(ERROR, TAG, "Failed to getDevInst()");
683 // display the MOT dev list
684 printf(" > Owned Devices\n");
685 g_own_cnt = printDevList(g_own_list);
689 printf(" > Enter Owned Device Number to link : ");
690 for(int ret=0; 1!=ret; )
692 ret = scanf("%d", &dev_num);
693 for( ; 0x20<=getchar(); ); // for removing overflow garbages
694 // '0x20<=code' is character region
696 if(0<dev_num && g_own_cnt>=dev_num)
700 printf(" Entered Wrong Number. Please Enter Again\n");
703 OCProvisionDev_t* ownDev = getDevInst(g_own_list, dev_num);
706 OIC_LOG(ERROR, TAG, "Failed to getDevInst()");
710 // call |OCProvisionCredentials| API actually
711 // calling this API with callback actually acts like blocking
712 // for error checking, the return value saved and printed
714 printf(" Provisioning Selected Pairwise Devices..\n");
715 OCStackResult rst = OCProvisionCredentials((void*) g_ctx,
716 SYMMETRIC_PAIR_WISE_KEY, OWNER_PSK_LENGTH_128,
717 ownDev, motDev, provisionCredCB);
718 if(OC_STACK_OK != rst)
720 OIC_LOG_V(ERROR, TAG, "OCProvisionPairwiseDevices API error: %d", rst);
723 if(waitCallbackRet()) // input |g_doneCB| flag implicitly
725 OIC_LOG(ERROR, TAG, "OCProvisionCredentials callback error");
729 // display the pairwise-provisioned result
730 printf(" > Provisioned Selected Pairwise Devices\n");
738 static OCProvisionDev_t* getDevInst(const OCProvisionDev_t* dev_lst, const int dev_num)
740 if(!dev_lst || 0>=dev_num)
742 printf(" Device List is Empty..\n");
746 OCProvisionDev_t* lst = (OCProvisionDev_t*) dev_lst;
756 return NULL; // in here |lst| is always |NULL|
759 static int printDevList(const OCProvisionDev_t* dev_lst)
763 printf(" Device List is Empty..\n\n");
767 OCProvisionDev_t* lst = (OCProvisionDev_t*) dev_lst;
771 printf(" [%d] ", ++lst_cnt);
772 printUuid((const OicUuid_t*) &lst->doxm->deviceID);
781 static size_t printUuidList(const OCUuidList_t* uid_lst)
785 printf(" Device List is Empty..\n\n");
789 OCUuidList_t* lst = (OCUuidList_t*) uid_lst;
793 printf(" [%zu] ", ++lst_cnt);
794 printUuid((const OicUuid_t*) &lst->dev);
803 static int printResultList(const OCProvisionResult_t* rslt_lst, const int rslt_cnt)
805 if(!rslt_lst || 0>=rslt_cnt)
807 printf(" Device List is Empty..\n\n");
812 for( ; rslt_cnt>lst_cnt; ++lst_cnt)
814 printf(" [%d] ", lst_cnt+1);
815 printUuid((const OicUuid_t*) &rslt_lst[lst_cnt].deviceId);
816 printf(" - result: %d\n", rslt_lst[lst_cnt].res);
823 static void printUuid(const OicUuid_t* uid)
825 for(int i=0; i<UUID_LENGTH; )
827 printf("%02X", (*uid).id[i++]);
828 if(i==4 || i==6 || i==8 || i==10) // canonical format for UUID has '8-4-4-4-12'
835 static FILE* fopen_prvnMng(const char* path, const char* mode)
837 (void)path; // unused |path| parameter
839 // input |g_svr_db_fname| internally by force, not using |path| parameter
840 // because |OCPersistentStorage::open| is called |OCPersistentStorage| internally
841 // with its own |SVR_DB_FILE_NAME|
842 return fopen(SVR_DB_FILE_NAME, mode);
845 static int waitCallbackRet(void)
847 for(int i=0; !g_doneCB && CALLBACK_TIMEOUT>i; ++i)
850 if(OC_STACK_OK != OCProcess())
852 OIC_LOG(ERROR, TAG, "OCStack process error");
860 static int selectTwoDiffNum(int* a, int* b, const int max, const char* str)
862 if(!a || !b || 2>max || !str)
869 for(int i=0; 2>i; ++i)
874 printf(" > Enter Device[%d] Number, %s: ", i+1, str);
875 for(int ret=0; 1!=ret; )
877 ret = scanf("%d", num);
878 for( ; 0x20<=getchar(); ); // for removing overflow garbages
879 // '0x20<=code' is character region
881 if(0<*num && max>=*num)
885 printf(" Entered Wrong Number. Please Enter Again\n");
898 static void printMenu(void)
900 printf("************************************************************\n");
901 printf("****** OIC Provisioning Client with using C-level API ******\n");
902 printf("************************************************************\n\n");
904 printf("** [A] DISCOVER DEVICES ON NETWORK\n");
905 printf("** 10. Discover Multiple Ownership Transfer Enabled Devices on Network\n");
906 printf("** 11. Discover Multiple Owned Devices on Network\n\n");
908 printf("** [B] PERFORM MULTIPLE OWNERSHIP TRANSFER\n");
909 printf("** 20. Perform the Multiple Ownership Transfer for ALL discovered dievices\n\n");
911 printf("** [C] Get/Put Request for APPLICATION RESOURCE\n");
912 printf("** 30. Get LED resource\n");
913 printf("** 31. Put LED resource\n\n");
915 printf("** [D] LINK DEVICES\n");
916 printf("** 40. Provision ACL for LED Resource\n");
917 printf("** 41. Provison Credential\n\n");
919 printf("** [F] EXIT PROVISIONING CLIENT\n");
920 printf("** 99. Exit Provisionong Client\n\n");
922 printf("************************************************************\n\n");
925 // main function for provisioning client using C-level provisioning API
928 // initialize provisioning client
929 if(initProvisionClient())
931 OIC_LOG(ERROR, TAG, "ProvisionClient init error");
935 // main loop for provisioning manager
942 printf(">> Enter Menu Number: ");
943 for(int ret=0; 1!=ret; )
945 ret = scanf("%d", &mnNum);
946 for( ; 0x20<=getchar(); ); // for removing overflow garbages
947 // '0x20<=code' is character region
952 case _10_DISCOV_MOT_ENABLED_DEV_:
953 if(discoverMotSupportedDevices())
955 OIC_LOG(ERROR, TAG, "_12_MOT_DISCOV_DEV_: error");
958 case _11_DISCOV_MULTIPLE_OWNED_DEV_:
959 if(discoverSubOwnerDevices())
961 OIC_LOG(ERROR, TAG, "_13_DISCOV_MULTIPLE_OWNED_DEV_: error");
964 case _20_PERFORM_MOT_:
965 if(multipleOwnershipTransfer())
967 OIC_LOG(ERROR, TAG, "_21_PERFORM_MOT_: error");
970 case _30_GET_LED_RESOURCE_:
973 OIC_LOG(ERROR, TAG, "_30_GET_LED_RESOURCE_: error");
976 case _31_PUT_LED_RESOURCE_:
979 OIC_LOG(ERROR, TAG, "_31_PUT_LED_RESOURCE_: error");
982 case _40_PROVISION_ACL_:
983 if(provisionAclForLed())
985 OIC_LOG(ERROR, TAG, "_40_PROVISION_ACL_: error");
988 case _41_PROVISION_CRED_:
989 OIC_LOG(ERROR, TAG, "NOT SUPPORTED YET.");
994 OIC_LOG(ERROR, TAG, "_41_PROVISION_CRED_: error");
998 case _99_EXIT_PRVN_CLT_:
1001 printf(">> Entered Wrong Number. Please Enter Again\n\n");
1007 if(OC_STACK_OK != OCStop())
1009 OIC_LOG(ERROR, TAG, "OCStack stop error");
1011 OCDeleteDiscoveredDevices(g_own_list); // after here |g_own_list| points nothing
1012 OCDeleteDiscoveredDevices(g_unown_list); // after here |g_unown_list| points nothing
1013 OCDeleteDiscoveredDevices(g_motdev_list); // after here |g_motdev_list| points nothing
1017 OICFree(g_svr_fname); // after here |g_svr_fname| points nothing
1021 OICFree(g_prvn_fname); // after here |g_prvn_fname| points nothing
1023 return 0; // always return normal case
1028 #endif //__cplusplus