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");
193 Linkdata_t *link = (Linkdata_t*)ctx;
194 OCProvisionResultCB resultCallback = link->resultCallback;
199 UpdateLinkResults(link, 2,arr[0].res);
200 OC_LOG(ERROR,TAG,"Error occured while ACL provisioning device 1");
201 ((OCProvisionResultCB)(resultCallback))(link->ctx, link->currentCountResults,
204 OICFree(link->resArr);
208 UpdateLinkResults(link, 2, arr[0].res);
209 ((OCProvisionResultCB)(resultCallback))(link->ctx, link->currentCountResults,
212 OICFree(link->resArr);
218 * Callback to handle ACL provisioning for device 1
220 static void AclProv1CB(void* ctx, int nOfRes, OCProvisionResult_t *arr, bool hasError)
225 OC_LOG(ERROR,TAG,"Context is Null in ACLProv1");
228 Linkdata_t *link = (Linkdata_t*)ctx;
229 OCProvisionResultCB resultCallback = link->resultCallback;
233 OC_LOG(ERROR,TAG,"Error occured while ACL provisioning device 1");
234 UpdateLinkResults(link, 1, arr[0].res);
235 ((OCProvisionResultCB)(resultCallback))(link->ctx, link->currentCountResults,
238 OICFree(link->resArr);
242 UpdateLinkResults(link, 1, arr[0].res);
243 if (NULL != link->pDev2Acl)
245 OCStackResult res = SRPProvisionACL(ctx, link->pDev2, link->pDev2Acl, &AclProv2CB);
246 if (OC_STACK_OK!=res)
248 UpdateLinkResults(link, 2, res);
249 ((OCProvisionResultCB)(resultCallback))(link->ctx, link->currentCountResults,
257 ((OCProvisionResultCB)(resultCallback))(link->ctx, link->currentCountResults,
260 OICFree(link->resArr);
268 * Callback to handle credential provisioning.
270 static void ProvisionCredsCB(void* ctx, int nOfRes, OCProvisionResult_t *arr, bool hasError)
274 OC_LOG(ERROR,TAG,"Error occured while credential provisioning");
277 Linkdata_t *link = (Linkdata_t*)ctx;
278 OCProvisionResultCB resultCallback = link->resultCallback;
279 OC_LOG_V(INFO, TAG, "has error returned %d",hasError);
280 UpdateLinkResults(link, 1, arr[0].res);
281 UpdateLinkResults(link, 2, arr[1].res);
284 OC_LOG(ERROR,TAG,"Error occured while credential provisioning");
285 ((OCProvisionResultCB)(resultCallback))(link->ctx, nOfRes,
288 OICFree(link->resArr);
292 if (NULL != link->pDev1Acl)
295 OCStackResult res = SRPProvisionACL(ctx, link->pDev1, link->pDev1Acl, &AclProv1CB);
296 if (OC_STACK_OK!=res)
298 OC_LOG(ERROR, TAG, "Error while provisioning ACL for device 1");
299 UpdateLinkResults(link, 1, res);
300 ((OCProvisionResultCB)(resultCallback))(link->ctx, link->currentCountResults,
303 OICFree(link->resArr);
307 else if (NULL!=link->pDev2Acl)
309 OC_LOG(ERROR, TAG, "ACL for device 1 is NULL");
310 OCStackResult res = SRPProvisionACL(ctx, link->pDev2, link->pDev2Acl, &AclProv2CB);
311 if (OC_STACK_OK!=res)
313 OC_LOG(ERROR, TAG, "Error while provisioning ACL for device 2");
314 UpdateLinkResults(link, 2, res);
315 ((OCProvisionResultCB)(resultCallback))(link->ctx, link->currentCountResults,
318 OICFree(link->resArr);
325 OC_LOG(INFO, TAG, "ACLs of both devices are NULL");
326 ((OCProvisionResultCB)(resultCallback))(link->ctx, link->currentCountResults,
329 OICFree(link->resArr);
335 * function to provision credentials between two devices and ACLs for the devices who act as a server.
337 * @param[in] ctx Application context would be returned in result callback.
338 * @param[in] type Type of credentials to be provisioned to the device.
339 * @param[in] pDev1 Pointer to OCProvisionDev_t instance,respresenting resource to be provsioned.
340 * @param[in] acl ACL for device 1. If this is not required set NULL.
341 * @param[in] pDev2 Pointer to OCProvisionDev_t instance,respresenting resource to be provsioned.
342 * @param[in] acl ACL for device 2. If this is not required set NULL.
343 * @param[in] resultCallback callback provided by API user, callback will be called when
344 * provisioning request recieves a response from first resource server.
345 * @return OC_STACK_OK in case of success and other value otherwise.
347 OCStackResult OCProvisionPairwiseDevices(void* ctx, OicSecCredType_t type, size_t keySize,
348 const OCProvisionDev_t *pDev1, OicSecAcl_t *pDev1Acl,
349 const OCProvisionDev_t *pDev2, OicSecAcl_t *pDev2Acl,
350 OCProvisionResultCB resultCallback)
353 if(!pDev1 || !pDev2 || !resultCallback)
355 OC_LOG(ERROR, TAG, "OCProvisionPairwiseDevices : Invalid parameters");
356 return OC_STACK_INVALID_PARAM;
358 if (!(keySize == OWNER_PSK_LENGTH_128 || keySize == OWNER_PSK_LENGTH_256))
360 OC_LOG(INFO, TAG, "OCProvisionPairwiseDevices : Invalid key size");
361 return OC_STACK_INVALID_PARAM;
363 int noOfResults = 2; // Initial Value
372 Linkdata_t *link = (Linkdata_t*) OICMalloc(sizeof(Linkdata_t));
375 OC_LOG(ERROR, TAG, "Failed to memory allocation");
376 return OC_STACK_NO_MEMORY;
378 OC_LOG_V(INFO,TAG, "Maximum no od results %d",noOfResults);
381 link->pDev1Acl = pDev1Acl;
383 link->pDev2Acl = pDev2Acl;
385 // 1 call for each device for credential provisioning. implict call by SRPProvisioning credential
386 // 1 call for ACL provisioning for device 1 and 1 call for ACL provisioning for device 2.
387 link->numOfResults = noOfResults;
388 link->resultCallback = resultCallback;
389 link->currentCountResults = 0;
390 link->resArr = (OCProvisionResult_t*) OICMalloc(sizeof(OCProvisionResult_t)*noOfResults);
391 OCStackResult res = SRPProvisionCredentials(link, type, keySize,
392 pDev1, pDev2, &ProvisionCredsCB);
393 if (res != OC_STACK_OK)
395 OICFree(link->resArr);