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 * *****************************************************************/
23 #include "ocprovisioningmanager.h"
24 #include "pmutility.h"
25 #include "ownershiptransfermanager.h"
26 #include "oic_malloc.h"
28 #include "secureresourceprovider.h"
32 typedef struct Linkdata Linkdata_t;
36 const OCProvisionDev_t *pDev1;
37 OicSecAcl_t *pDev1Acl;
38 const OCProvisionDev_t *pDev2;
39 OicSecAcl_t *pDev2Acl;
40 OCProvisionResult_t *resArr;
42 int currentCountResults;
43 OCProvisionResultCB resultCallback;
48 * The function is responsible for discovery of device is current subnet. It will list
49 * all the device in subnet which are not yet owned. Please call OCInit with OC_CLIENT_SERVER as
52 * @param[in] timeout Timeout in seconds, value till which function will listen to responses from
53 * client before returning the list of devices.
54 * @param[out] ppList List of candidate devices to be provisioned
55 * @return OTM_SUCCESS in case of success and other value otherwise.
57 OCStackResult OCDiscoverUnownedDevices(unsigned short timeout, OCProvisionDev_t **ppList)
59 if( ppList == NULL || *ppList != NULL)
61 return OC_STACK_INVALID_PARAM;
64 return PMDeviceDiscovery(timeout, false, ppList);
68 * The function is responsible for discovery of owned device is current subnet. It will list
69 * all the device in subnet which are owned by calling provisioning client.
71 * @param[in] timeout Timeout in seconds, value till which function will listen to responses from
72 * client before returning the list of devices.
73 * @param[out] ppList List of device owned by provisioning tool.
74 * @return OTM_SUCCESS in case of success and other value otherwise.
76 OCStackResult OCDiscoverOwnedDevices(unsigned short timeout, OCProvisionDev_t **ppList)
78 if( ppList == NULL || *ppList != NULL)
80 return OC_STACK_INVALID_PARAM;
83 return PMDeviceDiscovery(timeout, true, ppList);
87 * API to register for particular OxM.
89 * @param[in] Ownership transfer method.
90 * @param[in] Implementation of callback functions for owership transfer.
91 * @return OC_STACK_OK in case of success and other value otherwise.
93 OCStackResult OCSetOwnerTransferCallbackData(OicSecOxm_t oxm, OTMCallbackData_t* callbackData)
95 if(NULL == callbackData)
97 return OC_STACK_INVALID_PARAM;
100 return OTMSetOwnershipTransferCallbackData(oxm, callbackData);
103 OCStackResult OCDoOwnershipTransfer(void* ctx,
104 OCProvisionDev_t *targetDevices,
105 OCProvisionResultCB resultCallback)
107 if( NULL == targetDevices )
109 return OC_STACK_INVALID_PARAM;
112 return OTMDoOwnershipTransfer(ctx, targetDevices, resultCallback);
116 * This function deletes memory allocated to linked list created by OCDiscover_XXX_Devices API.
118 * @param[in] pList Pointer to OCProvisionDev_t which should be deleted.
120 void OCDeleteDiscoveredDevices(OCProvisionDev_t **ppList)
122 DeleteDeviceList(ppList);
126 * this function sends ACL information to resource.
128 * @param[in] ctx Application context would be returned in result callback.
129 * @param[in] selectedDeviceInfo Selected target device.
130 * @param[in] acl ACL to provision.
131 * @param[in] resultCallback callback provided by API user, callback will be called when provisioning
132 request recieves a response from resource server.
133 * @return OC_STACK_OK in case of success and other value otherwise.
135 OCStackResult OCProvisionACL(void* ctx, const OCProvisionDev_t *selectedDeviceInfo, OicSecAcl_t *acl,
136 OCProvisionResultCB resultCallback)
138 return SRPProvisionACL(ctx, selectedDeviceInfo, acl, resultCallback);
142 * function to provision credential to devices.
144 * @param[in] ctx Application context would be returned in result callback.
145 * @param[in] type Type of credentials to be provisioned to the device.
146 * @param[in] pDev1 Pointer to OCProvisionDev_t instance,respresenting resource to be provsioned.
147 @param[in] pDev2 Pointer to OCProvisionDev_t instance,respresenting resource to be provsioned.
148 * @param[in] resultCallback callback provided by API user, callback will be called when
149 * provisioning request recieves a response from first resource server.
150 * @return OC_STACK_OK in case of success and other value otherwise.
152 OCStackResult OCProvisionCredentials(void *ctx, OicSecCredType_t type, size_t keySize,
153 const OCProvisionDev_t *pDev1,
154 const OCProvisionDev_t *pDev2,
155 OCProvisionResultCB resultCallback)
157 return SRPProvisionCredentials(ctx, type, keySize,
158 pDev1, pDev2, resultCallback);
163 * Internal Function to update result in link result array.
165 static void UpdateLinkResults(Linkdata_t *link, int device, OCStackResult stackresult)
168 OC_LOG_V(INFO,TAG,"value of link->currentCountResults is %d",link->currentCountResults);
171 memcpy(link->resArr[(link->currentCountResults)].deviceId.id, link->pDev1->doxm->deviceID.id,UUID_LENGTH);
175 memcpy(link->resArr[(link->currentCountResults)].deviceId.id, link->pDev2->doxm->deviceID.id,UUID_LENGTH);
177 link->resArr[(link->currentCountResults)].res = stackresult;
178 ++(link->currentCountResults);
183 * Callback to handle ACL provisioning for device 2.
185 static void AclProv2CB(void* ctx, int nOfRes, OCProvisionResult_t *arr, bool hasError)
190 OC_LOG(ERROR,TAG,"Context is Null in ACLProv 2");
194 Linkdata_t *link = (Linkdata_t*)ctx;
195 OCProvisionResultCB resultCallback = link->resultCallback;
200 UpdateLinkResults(link, 2,arr[0].res);
201 OC_LOG(ERROR,TAG,"Error occured while ACL provisioning device 1");
202 ((OCProvisionResultCB)(resultCallback))(link->ctx, link->currentCountResults,
205 OICFree(link->resArr);
209 UpdateLinkResults(link, 2, arr[0].res);
210 ((OCProvisionResultCB)(resultCallback))(link->ctx, link->currentCountResults,
213 OICFree(link->resArr);
219 * Callback to handle ACL provisioning for device 1
221 static void AclProv1CB(void* ctx, int nOfRes, OCProvisionResult_t *arr, bool hasError)
226 OC_LOG(ERROR,TAG,"Context is Null in ACLProv1");
230 Linkdata_t *link = (Linkdata_t*)ctx;
231 OCProvisionResultCB resultCallback = link->resultCallback;
235 OC_LOG(ERROR,TAG,"Error occured while ACL provisioning device 1");
236 UpdateLinkResults(link, 1, arr[0].res);
237 ((OCProvisionResultCB)(resultCallback))(link->ctx, link->currentCountResults,
240 OICFree(link->resArr);
244 UpdateLinkResults(link, 1, arr[0].res);
245 if (NULL != link->pDev2Acl)
247 OCStackResult res = SRPProvisionACL(ctx, link->pDev2, link->pDev2Acl, &AclProv2CB);
248 if (OC_STACK_OK!=res)
250 UpdateLinkResults(link, 2, res);
251 ((OCProvisionResultCB)(resultCallback))(link->ctx, link->currentCountResults,
259 ((OCProvisionResultCB)(resultCallback))(link->ctx, link->currentCountResults,
262 OICFree(link->resArr);
270 * Callback to handle credential provisioning.
272 static void ProvisionCredsCB(void* ctx, int nOfRes, OCProvisionResult_t *arr, bool hasError)
276 OC_LOG(ERROR,TAG,"Error occured while credential provisioning");
279 Linkdata_t *link = (Linkdata_t*)ctx;
280 OCProvisionResultCB resultCallback = link->resultCallback;
281 OC_LOG_V(INFO, TAG, "has error returned %d",hasError);
282 UpdateLinkResults(link, 1, arr[0].res);
283 UpdateLinkResults(link, 2, arr[1].res);
286 OC_LOG(ERROR,TAG,"Error occured while credential provisioning");
287 ((OCProvisionResultCB)(resultCallback))(link->ctx, nOfRes,
290 OICFree(link->resArr);
294 if (NULL != link->pDev1Acl)
297 OCStackResult res = SRPProvisionACL(ctx, link->pDev1, link->pDev1Acl, &AclProv1CB);
298 if (OC_STACK_OK!=res)
300 OC_LOG(ERROR, TAG, "Error while provisioning ACL for device 1");
301 UpdateLinkResults(link, 1, res);
302 ((OCProvisionResultCB)(resultCallback))(link->ctx, link->currentCountResults,
305 OICFree(link->resArr);
309 else if (NULL!=link->pDev2Acl)
311 OC_LOG(ERROR, TAG, "ACL for device 1 is NULL");
312 OCStackResult res = SRPProvisionACL(ctx, link->pDev2, link->pDev2Acl, &AclProv2CB);
313 if (OC_STACK_OK!=res)
315 OC_LOG(ERROR, TAG, "Error while provisioning ACL for device 2");
316 UpdateLinkResults(link, 2, res);
317 ((OCProvisionResultCB)(resultCallback))(link->ctx, link->currentCountResults,
320 OICFree(link->resArr);
327 OC_LOG(INFO, TAG, "ACLs of both devices are NULL");
328 ((OCProvisionResultCB)(resultCallback))(link->ctx, link->currentCountResults,
331 OICFree(link->resArr);
337 * function to provision credentials between two devices and ACLs for the devices who act as a server.
339 * @param[in] ctx Application context would be returned in result callback.
340 * @param[in] type Type of credentials to be provisioned to the device.
341 * @param[in] pDev1 Pointer to OCProvisionDev_t instance,respresenting resource to be provsioned.
342 * @param[in] acl ACL for device 1. If this is not required set NULL.
343 * @param[in] pDev2 Pointer to OCProvisionDev_t instance,respresenting resource to be provsioned.
344 * @param[in] acl ACL for device 2. If this is not required set NULL.
345 * @param[in] resultCallback callback provided by API user, callback will be called when
346 * provisioning request recieves a response from first resource server.
347 * @return OC_STACK_OK in case of success and other value otherwise.
349 OCStackResult OCProvisionPairwiseDevices(void* ctx, OicSecCredType_t type, size_t keySize,
350 const OCProvisionDev_t *pDev1, OicSecAcl_t *pDev1Acl,
351 const OCProvisionDev_t *pDev2, OicSecAcl_t *pDev2Acl,
352 OCProvisionResultCB resultCallback)
355 if(!pDev1 || !pDev2 || !resultCallback)
357 OC_LOG(ERROR, TAG, "OCProvisionPairwiseDevices : Invalid parameters");
358 return OC_STACK_INVALID_PARAM;
360 if (!(keySize == OWNER_PSK_LENGTH_128 || keySize == OWNER_PSK_LENGTH_256))
362 OC_LOG(INFO, TAG, "OCProvisionPairwiseDevices : Invalid key size");
363 return OC_STACK_INVALID_PARAM;
365 int noOfResults = 2; // Initial Value
374 Linkdata_t *link = (Linkdata_t*) OICMalloc(sizeof(Linkdata_t));
377 OC_LOG(ERROR, TAG, "Failed to memory allocation");
378 return OC_STACK_NO_MEMORY;
380 OC_LOG_V(INFO,TAG, "Maximum no od results %d",noOfResults);
383 link->pDev1Acl = pDev1Acl;
385 link->pDev2Acl = pDev2Acl;
387 // 1 call for each device for credential provisioning. implict call by SRPProvisioning credential
388 // 1 call for ACL provisioning for device 1 and 1 call for ACL provisioning for device 2.
389 link->numOfResults = noOfResults;
390 link->resultCallback = resultCallback;
391 link->currentCountResults = 0;
392 link->resArr = (OCProvisionResult_t*) OICMalloc(sizeof(OCProvisionResult_t)*noOfResults);
393 OCStackResult res = SRPProvisionCredentials(link, type, keySize,
394 pDev1, pDev2, &ProvisionCredsCB);
395 if (res != OC_STACK_OK)
397 OICFree(link->resArr);