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"
29 #include "provisioningdatabasemanager.h"
33 typedef struct Linkdata Linkdata_t;
37 const OCProvisionDev_t *pDev1;
38 OicSecAcl_t *pDev1Acl;
39 const OCProvisionDev_t *pDev2;
40 OicSecAcl_t *pDev2Acl;
41 OCProvisionResult_t *resArr;
43 int currentCountResults;
44 OCProvisionResultCB resultCallback;
49 * The function is responsible for initializaton of the provisioning manager. It will load
50 * provisioning database which have owned device's list and their linked status.
51 * TODO: In addition, if there is a device(s) which has not up-to-date credentials, this function will
52 * automatically try to update the deivce(s).
54 * @param[in] dbPath file path of the sqlite3 db
56 * @return OC_STACK_OK in case of success and other value otherwise.
58 OCStackResult OCInitPM(const char* dbPath)
60 return PDMInit(dbPath);
64 * The function is responsible for discovery of device is current subnet. It will list
65 * all the device in subnet which are not yet owned. Please call OCInit with OC_CLIENT_SERVER as
68 * @param[in] timeout Timeout in seconds, value till which function will listen to responses from
69 * client before returning the list of devices.
70 * @param[out] ppList List of candidate devices to be provisioned
71 * @return OTM_SUCCESS in case of success and other value otherwise.
73 OCStackResult OCDiscoverUnownedDevices(unsigned short timeout, OCProvisionDev_t **ppList)
75 if( ppList == NULL || *ppList != NULL)
77 return OC_STACK_INVALID_PARAM;
80 return PMDeviceDiscovery(timeout, false, ppList);
84 * The function is responsible for discovery of owned device is current subnet. It will list
85 * all the device in subnet which are owned by calling provisioning client.
87 * @param[in] timeout Timeout in seconds, value till which function will listen to responses from
88 * client before returning the list of devices.
89 * @param[out] ppList List of device owned by provisioning tool.
90 * @return OTM_SUCCESS in case of success and other value otherwise.
92 OCStackResult OCDiscoverOwnedDevices(unsigned short timeout, OCProvisionDev_t **ppList)
94 if( ppList == NULL || *ppList != NULL)
96 return OC_STACK_INVALID_PARAM;
99 return PMDeviceDiscovery(timeout, true, ppList);
103 * API to register for particular OxM.
105 * @param[in] Ownership transfer method.
106 * @param[in] Implementation of callback functions for owership transfer.
107 * @return OC_STACK_OK in case of success and other value otherwise.
109 OCStackResult OCSetOwnerTransferCallbackData(OicSecOxm_t oxm, OTMCallbackData_t* callbackData)
111 if(NULL == callbackData)
113 return OC_STACK_INVALID_PARAM;
116 return OTMSetOwnershipTransferCallbackData(oxm, callbackData);
119 OCStackResult OCDoOwnershipTransfer(void* ctx,
120 OCProvisionDev_t *targetDevices,
121 OCProvisionResultCB resultCallback)
123 if( NULL == targetDevices )
125 return OC_STACK_INVALID_PARAM;
128 return OTMDoOwnershipTransfer(ctx, targetDevices, resultCallback);
132 * This function deletes memory allocated to linked list created by OCDiscover_XXX_Devices API.
134 * @param[in] pList Pointer to OCProvisionDev_t which should be deleted.
136 void OCDeleteDiscoveredDevices(OCProvisionDev_t *pList)
138 PMDeleteDeviceList(pList);
142 * this function sends ACL information to resource.
144 * @param[in] ctx Application context would be returned in result callback.
145 * @param[in] selectedDeviceInfo Selected target device.
146 * @param[in] acl ACL to provision.
147 * @param[in] resultCallback callback provided by API user, callback will be called when provisioning
148 request recieves a response from resource server.
149 * @return OC_STACK_OK in case of success and other value otherwise.
151 OCStackResult OCProvisionACL(void* ctx, const OCProvisionDev_t *selectedDeviceInfo, OicSecAcl_t *acl,
152 OCProvisionResultCB resultCallback)
154 return SRPProvisionACL(ctx, selectedDeviceInfo, acl, resultCallback);
158 * function to provision credential to devices.
160 * @param[in] ctx Application context would be returned in result callback.
161 * @param[in] type Type of credentials to be provisioned to the device.
162 * @param[in] pDev1 Pointer to OCProvisionDev_t instance,respresenting resource to be provsioned.
163 @param[in] pDev2 Pointer to OCProvisionDev_t instance,respresenting resource to be provsioned.
164 * @param[in] resultCallback callback provided by API user, callback will be called when
165 * provisioning request recieves a response from first resource server.
166 * @return OC_STACK_OK in case of success and other value otherwise.
168 OCStackResult OCProvisionCredentials(void *ctx, OicSecCredType_t type, size_t keySize,
169 const OCProvisionDev_t *pDev1,
170 const OCProvisionDev_t *pDev2,
171 OCProvisionResultCB resultCallback)
173 return SRPProvisionCredentials(ctx, type, keySize,
174 pDev1, pDev2, resultCallback);
179 * Internal Function to update result in link result array.
181 static void UpdateLinkResults(Linkdata_t *link, int device, OCStackResult stackresult)
184 OC_LOG_V(INFO,TAG,"value of link->currentCountResults is %d",link->currentCountResults);
187 memcpy(link->resArr[(link->currentCountResults)].deviceId.id, link->pDev1->doxm->deviceID.id,UUID_LENGTH);
191 memcpy(link->resArr[(link->currentCountResults)].deviceId.id, link->pDev2->doxm->deviceID.id,UUID_LENGTH);
193 link->resArr[(link->currentCountResults)].res = stackresult;
194 ++(link->currentCountResults);
199 * Callback to handle ACL provisioning for device 2.
201 static void AclProv2CB(void* ctx, int nOfRes, OCProvisionResult_t *arr, bool hasError)
206 OC_LOG(ERROR,TAG,"Context is Null in ACLProv 2");
210 Linkdata_t *link = (Linkdata_t*)ctx;
211 OCProvisionResultCB resultCallback = link->resultCallback;
216 UpdateLinkResults(link, 2,arr[0].res);
217 OC_LOG(ERROR,TAG,"Error occured while ACL provisioning device 1");
218 ((OCProvisionResultCB)(resultCallback))(link->ctx, link->currentCountResults,
221 OICFree(link->resArr);
225 UpdateLinkResults(link, 2, arr[0].res);
226 ((OCProvisionResultCB)(resultCallback))(link->ctx, link->currentCountResults,
229 OICFree(link->resArr);
235 * Callback to handle ACL provisioning for device 1
237 static void AclProv1CB(void* ctx, int nOfRes, OCProvisionResult_t *arr, bool hasError)
242 OC_LOG(ERROR,TAG,"Context is Null in ACLProv1");
246 Linkdata_t *link = (Linkdata_t*)ctx;
247 OCProvisionResultCB resultCallback = link->resultCallback;
251 OC_LOG(ERROR,TAG,"Error occured while ACL provisioning device 1");
252 UpdateLinkResults(link, 1, arr[0].res);
253 ((OCProvisionResultCB)(resultCallback))(link->ctx, link->currentCountResults,
256 OICFree(link->resArr);
260 UpdateLinkResults(link, 1, arr[0].res);
261 if (NULL != link->pDev2Acl)
263 OCStackResult res = SRPProvisionACL(ctx, link->pDev2, link->pDev2Acl, &AclProv2CB);
264 if (OC_STACK_OK!=res)
266 UpdateLinkResults(link, 2, res);
267 ((OCProvisionResultCB)(resultCallback))(link->ctx, link->currentCountResults,
275 ((OCProvisionResultCB)(resultCallback))(link->ctx, link->currentCountResults,
278 OICFree(link->resArr);
286 * Callback to handle credential provisioning.
288 static void ProvisionCredsCB(void* ctx, int nOfRes, OCProvisionResult_t *arr, bool hasError)
292 OC_LOG(ERROR,TAG,"Error occured while credential provisioning");
295 Linkdata_t *link = (Linkdata_t*)ctx;
296 OCProvisionResultCB resultCallback = link->resultCallback;
297 OC_LOG_V(INFO, TAG, "has error returned %d",hasError);
298 UpdateLinkResults(link, 1, arr[0].res);
299 UpdateLinkResults(link, 2, arr[1].res);
302 OC_LOG(ERROR,TAG,"Error occured while credential provisioning");
303 ((OCProvisionResultCB)(resultCallback))(link->ctx, nOfRes,
306 OICFree(link->resArr);
310 if (NULL != link->pDev1Acl)
313 OCStackResult res = SRPProvisionACL(ctx, link->pDev1, link->pDev1Acl, &AclProv1CB);
314 if (OC_STACK_OK!=res)
316 OC_LOG(ERROR, TAG, "Error while provisioning ACL for device 1");
317 UpdateLinkResults(link, 1, res);
318 ((OCProvisionResultCB)(resultCallback))(link->ctx, link->currentCountResults,
321 OICFree(link->resArr);
325 else if (NULL!=link->pDev2Acl)
327 OC_LOG(ERROR, TAG, "ACL for device 1 is NULL");
328 OCStackResult res = SRPProvisionACL(ctx, link->pDev2, link->pDev2Acl, &AclProv2CB);
329 if (OC_STACK_OK!=res)
331 OC_LOG(ERROR, TAG, "Error while provisioning ACL for device 2");
332 UpdateLinkResults(link, 2, res);
333 ((OCProvisionResultCB)(resultCallback))(link->ctx, link->currentCountResults,
336 OICFree(link->resArr);
343 OC_LOG(INFO, TAG, "ACLs of both devices are NULL");
344 ((OCProvisionResultCB)(resultCallback))(link->ctx, link->currentCountResults,
347 OICFree(link->resArr);
353 * function to provision credentials between two devices and ACLs for the devices who act as a server.
355 * @param[in] ctx Application context would be returned in result callback.
356 * @param[in] type Type of credentials to be provisioned to the device.
357 * @param[in] pDev1 Pointer to OCProvisionDev_t instance,respresenting resource to be provsioned.
358 * @param[in] acl ACL for device 1. If this is not required set NULL.
359 * @param[in] pDev2 Pointer to OCProvisionDev_t instance,respresenting resource to be provsioned.
360 * @param[in] acl ACL for device 2. If this is not required set NULL.
361 * @param[in] resultCallback callback provided by API user, callback will be called when
362 * provisioning request recieves a response from first resource server.
363 * @return OC_STACK_OK in case of success and other value otherwise.
365 OCStackResult OCProvisionPairwiseDevices(void* ctx, OicSecCredType_t type, size_t keySize,
366 const OCProvisionDev_t *pDev1, OicSecAcl_t *pDev1Acl,
367 const OCProvisionDev_t *pDev2, OicSecAcl_t *pDev2Acl,
368 OCProvisionResultCB resultCallback)
371 if(!pDev1 || !pDev2 || !resultCallback)
373 OC_LOG(ERROR, TAG, "OCProvisionPairwiseDevices : Invalid parameters");
374 return OC_STACK_INVALID_PARAM;
376 if (!(keySize == OWNER_PSK_LENGTH_128 || keySize == OWNER_PSK_LENGTH_256))
378 OC_LOG(INFO, TAG, "OCProvisionPairwiseDevices : Invalid key size");
379 return OC_STACK_INVALID_PARAM;
381 int noOfResults = 2; // Initial Value
390 Linkdata_t *link = (Linkdata_t*) OICMalloc(sizeof(Linkdata_t));
393 OC_LOG(ERROR, TAG, "Failed to memory allocation");
394 return OC_STACK_NO_MEMORY;
396 OC_LOG_V(INFO,TAG, "Maximum no od results %d",noOfResults);
399 link->pDev1Acl = pDev1Acl;
401 link->pDev2Acl = pDev2Acl;
403 // 1 call for each device for credential provisioning. implict call by SRPProvisioning credential
404 // 1 call for ACL provisioning for device 1 and 1 call for ACL provisioning for device 2.
405 link->numOfResults = noOfResults;
406 link->resultCallback = resultCallback;
407 link->currentCountResults = 0;
408 link->resArr = (OCProvisionResult_t*) OICMalloc(sizeof(OCProvisionResult_t)*noOfResults);
409 OCStackResult res = SRPProvisionCredentials(link, type, keySize,
410 pDev1, pDev2, &ProvisionCredsCB);
411 if (res != OC_STACK_OK)
413 OICFree(link->resArr);