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 ******************************************************************/
26 #include "oic_malloc.h"
28 #include "ocprovisioningmanager.h"
29 #include "secureresourceprovider.h"
30 #include "oxmjustworks.h"
31 #include "oxmrandompin.h"
32 #include "pinoxmcommon.h"
33 #include "oic_string.h"
35 #define MAX_URI_LENGTH (64)
36 #define MAX_PERMISSION_LENGTH (5)
43 #define PREDEFINED_TIMEOUT (10)
44 #define MAX_OWNED_DEVICE (10)
45 #define TAG "provisioningclient"
47 static char CRED_FILE[] = "oic_svr_db_client.json";
48 static OicSecAcl_t *gAcl1 = NULL;
49 static OicSecAcl_t *gAcl2 = NULL;
50 static int gOwnershipState = 0;
54 ownershipDone = 1 << 1,
55 finalizeDone = 1 << 2,
56 provisionCredDone = 1 << 3,
57 provisionAclDone = 1 << 4
62 * Perform cleanup for ACL
65 static void deleteACL(OicSecAcl_t *acl)
70 for (size_t i = 0; i < (acl)->resourcesLen; i++)
72 OICFree((acl)->resources[i]);
74 OICFree((acl)->resources);
77 OICFree((acl)->owners);
79 /* Clean ACL node itself */
87 * Calculate ACL permission from string to bit
89 * @param[in] temp_psm Input data of ACL permission string
90 * @param[in,out] pms The pointer of ACL permission value
91 * @return 0 on success otherwise -1.
93 static int CalculateAclPermission(const char *temp_pms, uint16_t *pms)
97 if (NULL == temp_pms || NULL == pms)
102 while (temp_pms[i] != '\0')
151 * Get the ACL property from user
153 * @param[in] ACL Datastructure to save user inputs
154 * @return 0 on success otherwise -1.
156 static int InputACL(OicSecAcl_t *acl)
158 int unused __attribute__((unused));
159 char temp_id [UUID_LENGTH + 4] = {0,};
160 char temp_rsc[MAX_URI_LENGTH + 1] = {0,};
161 char temp_pms[MAX_PERMISSION_LENGTH + 1] = {0,};
162 printf("******************************************************************************\n");
163 printf("-Set ACL policy for target device\n");
164 printf("******************************************************************************\n");
166 printf("-URN identifying the subject\n");
167 printf("ex) 1111-1111-1111-1111 (16 Numbers except to '-')\n");
168 printf("Subject : ");
169 unused = scanf("%19s", temp_id);
171 for (int i = 0; temp_id[i] != '\0'; i++)
173 if (DASH != temp_id[i])
174 acl->subject.id[j++] = temp_id[i];
178 printf("Num. of Resource : ");
179 unused = scanf("%zu", &acl->resourcesLen);
180 printf("-URI of resource\n");
181 printf("ex)/oic/sh/temp/0 (Max_URI_Length: 64 Byte )\n");
182 acl->resources = (char **)OICMalloc(acl->resourcesLen * sizeof(char *));
183 if (NULL == acl->resources)
185 OC_LOG(ERROR, TAG, "Error while memory allocation");
188 for (size_t i = 0; i < acl->resourcesLen; i++)
190 printf("[%zu]Resource : ", i + 1);
191 unused = scanf("%64s", temp_rsc);
192 acl->resources[i] = OICStrdup(temp_rsc);
194 if (NULL == acl->resources[i])
196 OC_LOG(ERROR, TAG, "Error while memory allocation");
199 strncpy(acl->resources[i], temp_rsc, strlen(temp_rsc));
200 acl->resources[i][strlen(temp_rsc)] = '\0';
205 printf("-Set the permission(C,R,U,D,N)\n");
206 printf("ex) CRUDN, CRU_N,..(5 Charaters)\n");
207 printf("Permission : ");
208 unused = scanf("%5s", temp_pms);
210 while (0 != CalculateAclPermission(temp_pms, &(acl->permission)) );
212 printf("Num. of Rowner : ");
213 unused = scanf("%zu", &acl->ownersLen);
214 printf("-URN identifying the rowner\n");
215 printf("ex) 1111-1111-1111-1111 (16 Numbers except to '-')\n");
216 acl->owners = (OicUuid_t *)OICCalloc(acl->ownersLen, sizeof(OicUuid_t));
217 if (NULL == acl->owners)
219 OC_LOG(ERROR, TAG, "Error while memory allocation");
222 for (size_t i = 0; i < acl->ownersLen; i++)
224 printf("[%zu]Rowner : ", i + 1);
225 unused = scanf("%19s", temp_id);
227 for (int k = 0; temp_id[k] != '\0'; k++)
229 if (DASH != temp_id[k])
231 acl->owners[i].id[j++] = temp_id[k];
239 //FILE *client_fopen(const char *path, const char *mode)
240 FILE *client_fopen(const char *UNUSED_PARAM, const char *mode)
242 return fopen(CRED_FILE, mode);
245 void PrintfResult(const char* procName, void* ctx, int nOfRes, OCProvisionResult_t *arr, bool hasError)
247 printf("-----------------------------------------------------------\n");
250 printf("%s was successfully done.\n", procName);
254 for(int i = 0; i < nOfRes; i++)
257 for(int j = 0; j < UUID_LENGTH; i++)
259 printf("%c", arr[i].deviceId.id[j]);
262 printf("Result=%d\n", arr[i].res);
268 printf("Context is %s\n", (char*)ctx);
270 printf("-----------------------------------------------------------\n");
273 void ProvisionCredCB(void* ctx, int nOfRes, OCProvisionResult_t *arr, bool hasError)
278 PrintfResult("Provision Credential", ctx, nOfRes, arr, hasError);
282 void ProvisionAclCB(void* ctx, int nOfRes, OCProvisionResult_t *arr, bool hasError)
287 PrintfResult("Provision ACL", ctx, nOfRes, arr, hasError);
291 void ProvisionPairwiseCB(void* ctx, int nOfRes, OCProvisionResult_t *arr, bool hasError)
296 PrintfResult("Provision Pairwise Credential", ctx, nOfRes, arr, hasError);
300 void OwnershipTransferCB(void* ctx, int nOfRes, OCProvisionResult_t *arr, bool hasError)
305 PrintfResult("Ownership transfer", ctx, nOfRes, arr, hasError);
309 void InputPinCB(char* pinBuf, size_t bufSize)
313 printf("INPUT PIN : ");
314 int unused = scanf("%s", pinBuf);
315 pinBuf[bufSize - 1] = '\0';
320 * Provisioning client sample using ProvisioningAPI
322 int main(int argc, char **argv)
324 OCStackResult res = OC_STACK_OK;
325 int unused __attribute__((unused));
327 gAcl1 = (OicSecAcl_t *)OICMalloc(sizeof(OicSecAcl_t));
330 OC_LOG(ERROR, TAG, "Error while memory allocation");
334 // Initialize Persistent Storage for SVR database
335 OCPersistentStorage ps = { .open = NULL,
340 ps.open = client_fopen;
345 OCRegisterPersistentStorageHandler(&ps);
347 if (OC_STACK_OK != OCInit(NULL, 0, OC_CLIENT_SERVER))
349 OC_LOG(ERROR, TAG, "OCStack init error");
353 OCProvisionDev_t* pDeviceList = NULL;
354 res = OCDiscoverUnownedDevices(PREDEFINED_TIMEOUT, &pDeviceList);
355 if(OC_STACK_OK != res)
357 OC_LOG_V(ERROR, TAG, "Failed to PMDeviceDiscovery : %d", res);
361 OCProvisionDev_t* pCurDev = pDeviceList;
363 while(pCurDev !=NULL)
365 for(i = 0; i < UUID_LENGTH; i++)
366 printf("%c", pCurDev->doxm->deviceID.id[i]);
368 pCurDev = pCurDev->next;
371 //Register callback function to each OxM
372 OTMCallbackData_t justWorksCBData = {.loadSecretCB=NULL,
373 .createSecureSessionCB=NULL,
374 .createSelectOxmPayloadCB=NULL,
375 .createOwnerTransferPayloadCB=NULL};
376 justWorksCBData.loadSecretCB = LoadSecretJustWorksCallback;
377 justWorksCBData.createSecureSessionCB = CreateSecureSessionJustWorksCallback;
378 justWorksCBData.createSelectOxmPayloadCB = CreateJustWorksSelectOxmPayload;
379 justWorksCBData.createOwnerTransferPayloadCB = CreateJustWorksOwnerTransferPayload;
380 OTMSetOwnershipTransferCallbackData(OIC_JUST_WORKS, &justWorksCBData);
382 OTMCallbackData_t pinBasedCBData = {.loadSecretCB=NULL,
383 .createSecureSessionCB=NULL,
384 .createSelectOxmPayloadCB=NULL,
385 .createOwnerTransferPayloadCB=NULL};
386 pinBasedCBData.loadSecretCB = InputPinCodeCallback;
387 pinBasedCBData.createSecureSessionCB = CreateSecureSessionRandomPinCallbak;
388 pinBasedCBData.createSelectOxmPayloadCB = CreatePinBasedSelectOxmPayload;
389 pinBasedCBData.createOwnerTransferPayloadCB = CreatePinBasedOwnerTransferPayload;
390 OTMSetOwnershipTransferCallbackData(OIC_RANDOM_DEVICE_PIN, &pinBasedCBData);
392 SetInputPinCB(&InputPinCB);
394 char* myContext = "OTM Context";
395 //Perform ownership transfer
396 res = OCDoOwnershipTransfer((void*)myContext, pDeviceList, OwnershipTransferCB);
397 if(OC_STACK_OK == res)
399 OC_LOG(INFO, TAG, "Request for ownership transfer is sent successfully.");
403 OC_LOG_V(ERROR, TAG, "Failed to OCDoOwnershipTransfer : %d", res);
407 while ( gOwnershipState == 0 )
409 if (OCProcess() != OC_STACK_OK)
411 OC_LOG(ERROR, TAG, "OCStack process error");
417 // Credential & ACL provisioning between two devices.
419 OCProvisionDev_t *pOwnedList = NULL;
420 OCProvisionDev_t *pOwnedDevices [MAX_OWNED_DEVICE] = {0,};
421 int nOwnedDevice = 0;
423 res = OCDiscoverOwnedDevices(PREDEFINED_TIMEOUT, &pOwnedList);
424 if (OC_STACK_OK == res)
426 printf("################## Owned Device List #######################\n");
427 while (pOwnedList != NULL)
430 printf(" %d : ", nOwnedDevice);
431 for (int i = 0; i < UUID_LENGTH; i++)
433 printf("%c", pOwnedList->doxm->deviceID.id[i]);
436 pOwnedDevices[nOwnedDevice] = pOwnedList;
437 pOwnedList = pOwnedList->next;
442 OC_LOG(ERROR, TAG, "Error while Owned Device Discovery");
448 printf("Select 2 devices for Credential & ACL provisioning\n");
449 printf("Device 1: ");
450 unused = scanf("%d", &Device1);
451 printf("Device 2: ");
452 unused = scanf("%d", &Device2);
455 gAcl1 = (OicSecAcl_t *)OICMalloc(sizeof(OicSecAcl_t));
458 OC_LOG(ERROR, TAG, "Error while memory allocation");
461 memset(gAcl1, 0x00, sizeof(OicSecAcl_t));
463 gAcl2 = (OicSecAcl_t *)OICMalloc(sizeof(OicSecAcl_t));
466 OC_LOG(ERROR, TAG, "Error while memory allocation");
469 memset(gAcl2, 0x00, sizeof(OicSecAcl_t));
471 printf("Input ACL for Device1\n");
472 if ( 0 == InputACL(gAcl1))
474 printf("Success Input ACL\n");
478 OC_LOG(ERROR, TAG, "InputACL error");
482 printf("Input ACL for Device2\n");
483 if (0 == InputACL(gAcl2))
485 printf("Success Input ACL\n");
489 OC_LOG(ERROR, TAG, "InputACL error");
493 OCProvisionPairwiseDevices(ctx,SYMMETRIC_PAIR_WISE_KEY, OWNER_PSK_LENGTH_128, pOwnedDevices[Device1],
494 gAcl1, pOwnedDevices[Device2], gAcl2, ProvisionPairwiseCB);
497 while ( gOwnershipState == 0 )
499 if (OCProcess() != OC_STACK_OK)
501 OC_LOG(ERROR, TAG, "OCStack process error");
507 if (OCStop() != OC_STACK_OK)
509 OC_LOG(ERROR, TAG, "OCStack process error");
516 OCDeleteDiscoveredDevices(&pDeviceList);
517 OCDeleteDiscoveredDevices(&pOwnedList);