- Add APIs to do MOT discovery of a specific device.
- Add APIs to check to see if the caller is a subowner.
- Add context to display and input pin callbacks.
- Add device information to input pin callback.
- Enable C++ security APIs to be built for Windows.
- Update ProvisioningClient and Sampleserver_RandomPin
to use the new APIs.
- Enable MOT to always build on Windows.
Change-Id: I27af9d3c2c7065b8643f77be3ac4c9b2dc5ffe80
Signed-off-by: Alex Kelley <alexke@microsoft.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/16403
Tested-by: jenkins-iotivity <jenkins@iotivity.org>
Reviewed-by: Mike Fenelon <mike.fenelon@microsoft.com>
Reviewed-by: Kevin Kane <kkane@microsoft.com>
#include "gtest/gtest.h"
#include "time.h"
+// Test function hooks
#define CAcloseSslConnection CAcloseSslConnectionTest
#define CAdecryptSsl CAdecryptSslTest
#define CAdeinitSslAdapter CAdeinitSslAdapterTest
#define CAsetTlsCipherSuite CAsetTlsCipherSuiteTest
#define CAsslGenerateOwnerPsk CAsslGenerateOwnerPskTest
#define CAcloseSslConnectionAll CAcloseSslConnectionAllTest
+#ifdef MULTIPLE_OWNER
+#define GetCASecureEndpointData GetCASecureEndpointDataTest
+#endif
#include "../src/adapter_util/ca_adapter_net_ssl.c"
; Windows octbstack.dll exports that are required for both products and tests,
; but only when building with SECURED=1.
+ConvertUuidToStr
+
CreateJustWorksOwnerTransferPayload
CreateJustWorksSelectOxmPayload
CreateMVJustWorksSelectOxmPayload
OCDeletePdAclList
OCDeleteUuidList
OCDiscoverOwnedDevices
+OCDiscoverSingleDevice
OCDiscoverUnownedDevices
OCDoOwnershipTransfer
OCGetACLResource
OCProvisionCredentials
OCProvisionDirectPairing
OCProvisionPairwiseDevices
+OCProvisionTrustCertChain
+OCReadTrustCertChain
+OCRegisterTrustCertChainNotifier
OCRemoveDevice
OCRemoveDeviceWithUuid
+OCRemoveTrustCertChainNotifier
OCResetDevice
OCResetSVRDB
+OCSaveTrustCertChain
OCSetOwnerTransferCallbackData
OCUnlinkDevices
OCSetOxmAllowStatus
+SetDisplayPinWithContextCB
+UnsetDisplayPinWithContextCB
SetGeneratePinCB
+UnsetGeneratePinCB
SetInputPinCB
+SetInputPinWithContextCB
+UnsetInputPinCB
+UnsetInputPinWithContextCB
SetRandomPinPolicy
SetDisplayNumCB
UnsetDisplayNumCB
OCChangeMOTMode
OCDiscoverMultipleOwnedDevices
OCDiscoverMultipleOwnerEnabledDevices
+OCDiscoverMultipleOwnerEnabledSingleDevice
OCDoMultipleOwnershipTransfer
+OCIsSubownerOfDevice
OCProvisionPreconfigPin
OCSelectMOTMethod
}OicSecPinType_t;
/**
- * Function pointer to print pin code.
+ * Function pointer to display pin code.
*/
typedef void (*GeneratePinCallback)(char* pinData, size_t pinSize);
/**
+ * Function pointer to display pin code, with context.
+ */
+typedef void(*DisplayPinCallbackWithContext)(char* pinData, size_t pinSize, void* context);
+
+/**
* Function pointer to input pin code.
*/
typedef void (*InputPinCallback)(char* pinBuf, size_t bufSize);
/**
- * Function to setting generate PIN callback from user.
+ * Function pointer to input pin code, with context and device information.
+ */
+typedef void(*InputPinCallbackWithContext)(OicUuid_t deviceId, char* pinBuffer, size_t pinBufferSize, void* context);
+
+/**
+ * Function to set the display PIN callback from the user.
+ *
+ * @deprecated Use SetDisplayPinWithContextCB instead.
*
* @param pinCB implementation of generate PIN callback.
*/
void SetGeneratePinCB(GeneratePinCallback pinCB);
/**
- * Function to setting input PIN callback from user.
+ * Function to set the display PIN callback from the user with context.
+ *
+ * @param displayPinCB implementation of display PIN callback.
+ * @param context context to return in the callback.
+ *
+ * @return OC_STACK_OK in case of success or other value in case of error.
+ * OC_STACK_INVALID_PARAM if pinCB is invalid.
+ * OC_STACK_DUPLICATE_REQUEST if a display pin callback has already been set.
+ */
+OCStackResult SetDisplayPinWithContextCB(DisplayPinCallbackWithContext displayPinCB, void* context);
+
+/**
+ * Function to set the input PIN callback from the user.
+ *
+ * @deprecated Use SetInputPinWithContextCB instead.
*
* @param pinCB implementation of input PIN callback.
*/
void SetInputPinCB(InputPinCallback pinCB);
/**
+ * Function to set the input PIN callback from the user with context.
+ *
+ * @param inputPinCB implementation of input PIN callback.
+ * @param context context to return in the callback.
+ *
+ * @return OC_STACK_OK in case of success or other value in case of error.
+ * OC_STACK_INVALID_PARAM if pinCB is invalid.
+ * OC_STACK_DUPLICATE_REQUEST if an input pin callback has already been set.
+ */
+OCStackResult SetInputPinWithContextCB(InputPinCallbackWithContext inputPinCB, void* context);
+
+/**
* Function to unset the input PIN callback.
- * NOTE : Do not call this function while PIN based ownership transfer.
+ * NOTE : Do not call this function while PIN based ownership transfer is in progress.
+ *
+ * @deprecated Use UnsetInputPinWithContextCB instead.
+ *
*/
void UnsetInputPinCB();
/**
+ * Function to unset the input PIN callback.
+ * NOTE : Do not call this function while PIN based ownership transfer is in progress.
+ */
+void UnsetInputPinWithContextCB();
+
+/**
* Function to unset the PIN generation callback.
- * NOTE : Do not call this function while PIN based ownership transfer.
+ * NOTE : Do not call this function while PIN based ownership transfer is in progress.
+ *
+ * @deprecated Use UnsetDisplayPinWithContextCB instead.
+ *
*/
void UnsetGeneratePinCB();
/**
- * Function to generate random PIN.
- * This function will send generated PIN to user via callback.
+ * Function to unset the PIN display callback.
+ * NOTE : Do not call this function while PIN based ownership transfer is in progress.
+ */
+void UnsetDisplayPinWithContextCB();
+
+/**
+ * Function to generate a random PIN.
+ * This function will send a generated PIN to the user via the callback that was set in
+ * SetGeneratePinCB or SetGeneratePinWithContextCB.
*
* @param pinBuffer is the reference to the buffer to store the generated PIN data.
* @param bufferSize is the size of buffer.
OCStackResult GeneratePin(char* pinBuffer, size_t bufferSize);
/**
- * Function to input PIN callback via input callback.
+ * Function to get a pin for a device.
+ * This function will acquire a pin from the user via the callback that was set in
+ * SetInputPinCB or SetInputPinWithContextCB.
*
+ * @param[in] deviceId is the device that is requesting a pin
* @param[in,out] pinBuffer is the reference to the buffer to store the inputed PIN data.
* @param[in] bufferSize is the size of buffer.
*
* @return ::OC_STACK_OK in case of success or other value in ccase of error.
*/
-OCStackResult InputPin(char* pinBuffer, size_t bufferSize);
+OCStackResult InputPin(OicUuid_t deviceId, char* pinBuffer, size_t bufferSize);
#ifdef MULTIPLE_OWNER
/**
#endif
/**
- * Function to setting the policy for random PIN generation
+ * Function to set the policy for random PIN generation
*
* @param[in] pinSize Byte length of random PIN
* @param[in] pinType Type of random PIN (ref OicSecPinType)
*/\r
OCStackResult OCDiscoverSingleDevice(unsigned short timeout, const OicUuid_t* deviceID,\r
OCProvisionDev_t **ppFoundDevice);\r
-
-/**
- * The function is responsible for discovery of owned/unowned device is specified endpoint/MAC
- * address.
- * It will return the found device even though timeout is not exceeded.
- *
- * @param[in] timeout Timeout in seconds, value till which function will listen to responses from
- * server before returning the device.
- * @param[in] deviceID deviceID of target device.
- * @param[in] hostAddress MAC address of target device.
- * @param[in] connType ConnectivityType for discovery.
- * @param[out] ppFoundDevice OCProvisionDev_t of found device.
- * @return OTM_SUCCESS in case of success and other value otherwise.
- */
-OCStackResult OCDiscoverSingleDeviceInUnicast(unsigned short timeout, const OicUuid_t* deviceID,
- const char* hostAddress, OCConnectivityType connType,
- OCProvisionDev_t **ppFoundDevice);
+\r
+/**\r
+ * The function is responsible for discovery of owned/unowned device is specified endpoint/MAC\r
+ * address.\r
+ * It will return the found device even though timeout is not exceeded.\r
+ *\r
+ * @param[in] timeout Timeout in seconds, value till which function will listen to responses from\r
+ * server before returning the device.\r
+ * @param[in] deviceID deviceID of target device.\r
+ * @param[in] hostAddress MAC address of target device.\r
+ * @param[in] connType ConnectivityType for discovery.\r
+ * @param[out] ppFoundDevice OCProvisionDev_t of found device.\r
+ * @return OTM_SUCCESS in case of success and other value otherwise.\r
+ */\r
+OCStackResult OCDiscoverSingleDeviceInUnicast(unsigned short timeout, const OicUuid_t* deviceID,\r
+ const char* hostAddress, OCConnectivityType connType,\r
+ OCProvisionDev_t **ppFoundDevice);\r
\r
/**\r
* The function is responsible for discovery of device is current subnet. It will list\r
\r
#ifdef MULTIPLE_OWNER\r
/**\r
+ * The function is responsible for the discovery of an MOT-enabled device with the specified deviceID.\r
+ * The function will return when security information for device with deviceID has been obtained or the \r
+ * timeout has been exceeded.\r
+ *\r
+ * @param[in] timeoutSeconds Maximum time, in seconds, this function will listen for responses from \r
+ * servers before returning.\r
+ * @param[in] deviceID deviceID of target device.\r
+ * @param[out] ppFoundDevice OCProvisionDev_t of discovered device. Caller should use\r
+ * OCDeleteDiscoveredDevices to delete the device.\r
+ * @return OC_STACK_OK in case of success and other values otherwise.\r
+ */\r
+OCStackResult OCDiscoverMultipleOwnerEnabledSingleDevice(unsigned short timeoutSeconds,\r
+ const OicUuid_t *deviceID, \r
+ OCProvisionDev_t **ppFoundDevice);\r
+\r
+/**\r
* The function is responsible for discovery of MOT enabled device is current subnet.\r
*\r
* @param[in] timeout Timeout in seconds, value till which function will listen to responses from\r
* @return OC_STACK_OK in case of success and other value otherwise.\r
*/\r
OCStackResult OCDiscoverMultipleOwnedDevices(unsigned short timeout, OCProvisionDev_t **ppList);\r
+\r
+/**\r
+ * The function is responsible for determining if the caller is a subowner of the specified device.\r
+ *\r
+ * @param[in] device MOT enabled device that contains a list of subowners.\r
+ * @param[out] isSubowner Bool indicating whether the caller is a subowner of device.\r
+ * @return OC_STACK_OK in case of success and other value otherwise.\r
+ */\r
+OCStackResult OCIsSubownerOfDevice(OCProvisionDev_t *device, bool *isSubowner);\r
#endif //MULTIPLE_OWNER\r
\r
/**\r
#ifdef MULTIPLE_OWNER
/**
+ * The function is responsible for the discovery of an MOT-enabled device with the specified deviceID.
+ * The function will return when security information for device with deviceID has been obtained or the
+ * timeout has been exceeded.
+ *
+ * @param[in] timeoutSeconds Maximum time, in seconds, this function will listen for responses from
+ * servers before returning.
+ * @param[in] deviceID deviceID of target device.
+ * @param[out] ppFoundDevice OCProvisionDev_t of found device. Caller should use PMDeleteDeviceList
+ * to delete the device.
+ *
+ * @return OC_STACK_OK on success otherwise error.
+ * OC_STACK_INVALID_PARAM when deviceID is NULL or ppFoundDevice is not initailized.
+ */
+OCStackResult PMMultipleOwnerSingleDeviceDiscovery(unsigned short timeoutSeconds,
+ const OicUuid_t *deviceID,
+ OCProvisionDev_t **ppFoundDevice);
+
+/**
* Discover multiple OTM enabled devices in the same IP subnet.
*
* @param[in] waittime Timeout in seconds.
* @return OC_STACK_OK on success otherwise error.
*/
OCStackResult PMMultipleOwnerDeviceDiscovery(unsigned short waittime, bool isMultipleOwned, OCProvisionDev_t **ppDevicesList);
+
+/**
+ * The function is responsible for determining if the caller is a subowner of the specified device.
+ *
+ * @param[in] device MOT enabled device that contains a list of subowners
+ * @param[out] isSubowner Bool indicating whether the caller is a subowner of device
+ *
+ * @return OC_STACK_OK in case of success and other value otherwise.
+ */
+OCStackResult PMIsSubownerOfDevice(OCProvisionDev_t *device, bool *isSubowner);
#endif //MULTIPLE_OWNER
/**
#define _12_DISCOV_OWN_DEVS_ 12
#ifdef MULTIPLE_OWNER
#define _13_MOT_DISCOV_DEV_ 13
+#define _14_MOT_DISCOV_SINGLE_DEV_ 14
#endif //MULTIPLE_OWNER
#define _20_REGIST_DEVS_ 20
#define _30_PROVIS_PAIR_DEVS_ 30
}
#endif //MULTIPLE_OWNER
-static void inputPinCB(char* pin, size_t len)
+static void inputPinCB(OicUuid_t deviceId, char *pin, size_t len, void *context)
{
if(!pin || OXM_RANDOM_PIN_MIN_SIZE > len)
{
return -1;
}
- SetInputPinCB(inputPinCB);
+ SetInputPinWithContextCB(inputPinCB, NULL);
return 0;
}
g_unown_list = NULL;
}
- // call |OCGetDevInfoFromNetwork| API actually
+ // call |OCGetDevInfoFromNetwork| API
printf(" Discovering All Un/Owned Devices on Network..\n");
if(OC_STACK_OK != OCGetDevInfoFromNetwork(DISCOVERY_TIMEOUT, &g_own_list, &g_unown_list))
{
g_unown_list = NULL;
}
- // call |OCDiscoverUnownedDevices| API actually
+ // call |OCDiscoverUnownedDevices| API
printf(" Discovering Only Unowned Devices on Network..\n");
if(OC_STACK_OK != OCDiscoverUnownedDevices(DISCOVERY_TIMEOUT, &g_unown_list))
{
g_own_list = NULL;
}
- // call |OCDiscoverOwnedDevices| API actually
+ // call |OCDiscoverOwnedDevices| API
printf(" Discovering Only Owned Devices on Network..\n");
if(OC_STACK_OK != OCDiscoverOwnedDevices(DISCOVERY_TIMEOUT, &g_own_list))
{
g_mot_enable_list = NULL;
}
- // call |OCDiscoverOwnedDevices| API actually
+ // call |OCDiscoverOwnedDevices| API
printf(" Discovering Multiple Ownership Transfer Enabled Devices on Network..\n");
if(OC_STACK_OK != OCDiscoverMultipleOwnerEnabledDevices(DISCOVERY_TIMEOUT, &g_mot_enable_list))
{
return 0;
}
+
+static int discoverSingleMOTEnabledDevice(void)
+{
+ OicUuid_t uuid = { .id = { 0 } };
+ char strUuid[64] = { 0 };
+
+ // Delete owned device list before updating it
+ if (g_mot_enable_list)
+ {
+ OCDeleteDiscoveredDevices(g_mot_enable_list);
+ g_mot_enable_list = NULL;
+ }
+
+ // Get the device id
+ printf(" Specify the Multiple Ownership Transfer enabled device to discover on the network\n");
+ printf(" > Input the UUID : ");
+ for (int ret = 0; 1 != ret; )
+ {
+ ret = scanf("%64s", strUuid);
+ for (; 0x20 <= getchar(); ); // for removing overflow garbages
+ // '0x20<=code' is character region
+ }
+
+ OCStackResult rst = ConvertStrToUuid(strUuid, &uuid);
+ if (OC_STACK_OK != rst)
+ {
+ OIC_LOG_V(ERROR, TAG, "ConvertStrToUuid API error: %d", rst);
+ return -1;
+ }
+
+ // Call |OCDiscoverMultipleOwnerEnabledSingleDevice| API
+ printf(" Discovering the Multiple Ownership Transfer enabled device on the network..\n");
+ if (OC_STACK_OK != OCDiscoverMultipleOwnerEnabledSingleDevice(DISCOVERY_TIMEOUT, &uuid, &g_mot_enable_list))
+ {
+ OIC_LOG(ERROR, TAG, "OCDiscoverMultipleOwnerEnabledSingleDevice API error");
+ return -1;
+ }
+
+ // Display the discovered owned list
+ printf(" > Discovered Multiple Ownership Transfer Enabled Device\n");
+ g_mot_enable_cnt = printDevList(g_mot_enable_list);
+
+ return 0;
+}
#endif //MULTIPLE_OWNER
static int registerDevices(void)
return 0; // normal case
}
- // call |OCDoOwnershipTransfer| API actually
+ // call |OCDoOwnershipTransfer| API
// calling this API with callback actually acts like blocking
// for error checking, the return value saved and printed
g_doneCB = false;
}
}
- // call |OCProvisionPairwiseDevices| API actually
+ // call |OCProvisionPairwiseDevices| API
// calling this API with callback actually acts like blocking
// for error checking, the return value saved and printed
g_doneCB = false;
}
- // call |OCProvisionCredentials| API actually
+ // call |OCProvisionCredentials| API
// calling this API with callback actually acts like blocking
// for error checking, the return value saved and printed
g_doneCB = false;
goto PVACL_ERROR;
}
- // call |OCProvisionACL| API actually
+ // call |OCProvisionACL| API
// calling this API with callback actually acts like blocking
// for error checking, the return value saved and printed
g_doneCB = false;
goto PVDP_ERROR;
}
- // call |OCProvisionDirectPairing| API actually
+ // call |OCProvisionDirectPairing| API
// calling this API with callback actually acts like blocking
// for error checking, the return value saved and printed
g_doneCB = false;
printf(" Entered Wrong Number. Please Enter Again\n");
}
- // call |OCGetLinkedStatus| API actually
+ // call |OCGetLinkedStatus| API
printf(" Checking Selected Link Status on PRVN DB..\n");
OCUuidList_t* dvid_lst = NULL;
size_t dvid_cnt = 0;
goto SVACL_ERROR;
}
- // call |OCSaveACL| API actually
+ // call |OCSaveACL| API
rst = OCSaveACL(acl);
if(OC_STACK_OK != rst)
{
printf(" Entered Wrong Number. Please Enter Again\n");
}
- // call |getDevInst| API actually
+ // call |getDevInst| API
// calling this API with callback actually acts like blocking
// for error checking, the return value saved and printed
g_doneCB = false;
printf(" Entered Wrong Number. Please Enter Again\n");
}
- // call |getDevInst| API actually
+ // call |getDevInst| API
// calling this API with callback actually acts like blocking
// for error checking, the return value saved and printed
g_doneCB = false;
return -1;
}
- // call |OCUnlinkDevices| API actually
+ // call |OCUnlinkDevices| API
// calling this API with callback actually acts like blocking
// for error checking, the return value saved and printed
g_doneCB = false;
printf(" Entered Wrong Number. Please Enter Again\n");
}
- // call |OCRemoveDevice| API actually
+ // call |OCRemoveDevice| API
// calling this API with callback actually acts like blocking
// for error checking, the return value saved and printed
g_doneCB = false;
printf("** 11. Discover Only Unowned Devices on Network\n");
#ifdef MULTIPLE_OWNER
printf("** 12. Discover Only Owned Devices on Network\n");
- printf("** 13. Discover Multiple Ownership Transfer Enabled Devices on Network\n\n");
+ printf("** 13. Discover Multiple Ownership Transfer Enabled Devices on Network\n");
+ printf("** 14. Discover Specific Multiple Ownership Transfer Enabled Device on Network\n\n");
#else
printf("** 12. Discover Only Owned Devices on Network\n\n");
#endif //MULTIPLE_OWNER
OIC_LOG(ERROR, TAG, "_13_MOT_DISCOV_DEV_: error");
}
break;
+ case _14_MOT_DISCOV_SINGLE_DEV_:
+ if (discoverSingleMOTEnabledDevice())
+ {
+ OIC_LOG(ERROR, TAG, "_14_MOT_DISCOV_SINGLE_DEV_: error");
+ }
+ break;
#endif //MULTIPLE_OWNER
case _20_REGIST_DEVS_:
if(registerDevices())
return fopen(CRED_FILE, mode);
}
-void GeneratePinCB(char* pin, size_t pinSize)
+void DisplayPinCB(char *pin, size_t pinSize, void *context)
{
if(NULL == pin || pinSize <= 0)
{
}
/**
- * If server supported random pin based ownership transfer,
- * callback of print PIN should be registered before runing server.
+ * If the server supports random pin based ownership transfer, the callback
+ * to display a PIN should be registered before running the server.
*/
- SetGeneratePinCB(GeneratePinCB);
+ SetDisplayPinWithContextCB(DisplayPinCB, NULL);
/**
* Random PIN generation policy can be changed through SetRandomPinPolicy() API.
#ifdef MULTIPLE_OWNER
/**
+ * The function is responsible for the discovery of an MOT-enabled device with the specified deviceID.
+ * The function will return when security information for device with deviceID has been obtained or the
+ * timeout has been exceeded.
+ *
+ * @param[in] timeoutSeconds Maximum time, in seconds, this function will listen for responses from
+ * servers before returning.
+ * @param[in] deviceID deviceID of target device.
+ * @param[out] ppFoundDevice OCProvisionDev_t of discovered device. Caller should use
+ * OCDeleteDiscoveredDevices to delete the device.
+ * @return OC_STACK_OK in case of success and other values otherwise.
+ */
+OCStackResult OCDiscoverMultipleOwnerEnabledSingleDevice(unsigned short timeoutSeconds,
+ const OicUuid_t* deviceID,
+ OCProvisionDev_t **ppFoundDevice)
+{
+ if ((NULL == ppFoundDevice) || (NULL != *ppFoundDevice) || (0 == timeoutSeconds) || (NULL == deviceID))
+ {
+ return OC_STACK_INVALID_PARAM;
+ }
+
+ return PMMultipleOwnerSingleDeviceDiscovery(timeoutSeconds, deviceID, ppFoundDevice);
+}
+
+/**
* The function is responsible for discovery of MOT enabled device is current subnet.
*
* @param[in] timeout Timeout in seconds, value till which function will listen to responses from
* @param[in] targetDeviceInfo Selected target device.
* @param[in] preconfigPin Preconfig PIN which is used while multiple owner authentication
* @param[in] preconfigPinLen Byte length of preconfigPin
- *
* @return OC_STACK_OK in case of success and other value otherwise.
*/
OCStackResult OCAddPreconfigPin(const OCProvisionDev_t *targetDeviceInfo,
return MOTDoOwnershipTransfer(ctx, targetDevices, resultCallback);
}
+/**
+ * The function is responsible for determining if the caller is a subowner of the specified device.
+ *
+ * @param[in] device MOT enabled device that contains a list of subowners
+ * @param[out] isSubowner Bool indicating whether the caller is a subowner of device
+ * @return OC_STACK_OK in case of success and other value otherwise.
+ */
+OCStackResult OCIsSubownerOfDevice(OCProvisionDev_t *device, bool *isSubowner)
+{
+ if ((NULL == device) || (NULL == isSubowner))
+ {
+ return OC_STACK_INVALID_PARAM;
+ }
+
+ return PMIsSubownerOfDevice(device, isSubowner);
+}
#endif //MULTIPLE_OWNER
/**
uint8_t pinData[OXM_RANDOM_PIN_MAX_SIZE + 1] = {0};
- OCStackResult res = InputPin((char*)pinData, sizeof(pinData));
+ OCStackResult res = InputPin(otmCtx->selectedDeviceInfo->doxm->deviceID, (char*)pinData, sizeof(pinData));
if (OC_STACK_OK != res)
{
OIC_LOG(ERROR, TAG, "Failed to input PIN");
#include "srmutility.h"
+static const uint64_t USECS_PER_MSEC = 1000;
+
#define TAG ("OIC_PM_UTILITY")
typedef struct _DiscoveryInfo{
// Get my device ID from doxm resource
OicUuid_t myId;
memset(&myId, 0, sizeof(myId));
- OCStackResult res = GetDoxmDevOwnerId(&myId);
+
+ res = GetDoxmDeviceID(&myId);
if(OC_STACK_OK != res)
{
OIC_LOG(ERROR, TAG, "Error while getting my device ID.");
return OC_STACK_KEEP_TRANSACTION;
}
- res = GetDoxmDeviceID(&myId);
- if(OC_STACK_OK != res)
+ //if targetId and discovered deviceID are different, discard it
+ if ((pDInfo->isSingleDiscovery) &&
+ (0 != memcmp(&ptrDoxm->deviceID.id, &pDInfo->targetId->id, sizeof(pDInfo->targetId->id))))
{
- OIC_LOG(ERROR, TAG, "Error while getting my UUID.");
+ OIC_LOG(DEBUG, TAG, "Discovered device is not target device");
DeleteDoxmBinData(ptrDoxm);
return OC_STACK_KEEP_TRANSACTION;
}
+
//if this is owned discovery and this is PT's reply, discard it
- if((pDInfo->isOwnedDiscovery) &&
- (0 == memcmp(&ptrDoxm->deviceID.id, &myId.id, sizeof(myId.id))) )
+ if (((pDInfo->isSingleDiscovery) || (pDInfo->isOwnedDiscovery)) &&
+ (0 == memcmp(&ptrDoxm->deviceID.id, &myId.id, sizeof(myId.id))))
{
OIC_LOG(DEBUG, TAG, "discarding provision tool's reply");
DeleteDoxmBinData(ptrDoxm);
return OC_STACK_DELETE_TRANSACTION;
}
+/**
+ * The function is responsible for the discovery of an MOT-enabled device with the specified deviceID.
+ * The function will return when security information for device with deviceID has been obtained or the
+ * timeout has been exceeded.
+ *
+ * @param[in] timeoutSeconds Maximum time, in seconds, this function will listen for responses from
+ * servers before returning.
+ * @param[in] deviceID deviceID of target device.
+ * @param[out] ppFoundDevice OCProvisionDev_t of found device. Caller should use PMDeleteDeviceList
+ * to delete the device.
+ *
+ * @return OC_STACK_OK on success otherwise error.
+ * OC_STACK_INVALID_PARAM when deviceID is NULL or ppFoundDevice is not initailized.
+ */
+OCStackResult PMMultipleOwnerSingleDeviceDiscovery(unsigned short timeoutSeconds,
+ const OicUuid_t* deviceID,
+ OCProvisionDev_t **ppFoundDevice)
+{
+ OIC_LOG(DEBUG, TAG, "IN PMMultipleOwnerSingleDeviceDiscovery");
+
+ if ((NULL == ppFoundDevice) || (NULL == deviceID))
+ {
+ return OC_STACK_INVALID_PARAM;
+ }
+
+ DiscoveryInfo discoveryInfo;
+ discoveryInfo.ppDevicesList = ppFoundDevice;
+ discoveryInfo.pCandidateList = NULL;
+ discoveryInfo.isOwnedDiscovery = false;
+ discoveryInfo.isSingleDiscovery = true;
+ discoveryInfo.isFound = false;
+ discoveryInfo.targetId = deviceID;
+
+ OCCallbackData cbData;
+ cbData.cb = &MOTDeviceDiscoveryHandler;
+ cbData.context = (void *)&discoveryInfo;
+ cbData.cd = NULL;
+
+ OCStackResult res = OC_STACK_ERROR;
+ const char query[] = "/oic/sec/doxm?mom!=0&owned=TRUE";
+
+ OCDoHandle handle = NULL;
+ res = OCDoResource(&handle, OC_REST_DISCOVER, query, 0, 0, CT_DEFAULT, OC_HIGH_QOS, &cbData, NULL, 0);
+ if (res != OC_STACK_OK)
+ {
+ OIC_LOG(ERROR, TAG, "OCStack resource error");
+ return res;
+ }
+
+ //Waiting for each response.
+ uint64_t startTime = OICGetCurrentTime(TIME_IN_MS);
+ while ((OC_STACK_OK == res) && !discoveryInfo.isFound)
+ {
+ uint64_t currTime = OICGetCurrentTime(TIME_IN_MS);
+ if (currTime >= startTime)
+ {
+ long elapsed = (long)((currTime - startTime) / MS_PER_SEC);
+ if (elapsed > timeoutSeconds)
+ {
+ break;
+ }
+
+ // Sleep for 100 ms to free up the CPU
+ usleep(100 * USECS_PER_MSEC);
+
+ res = OCProcess();
+ }
+ else
+ {
+ // System time has changed so we cannot reliably continue processing.
+ // Function returns with no device discovered.
+ break;
+ }
+ }
+
+ if (OC_STACK_OK != res)
+ {
+ OIC_LOG(ERROR, TAG, "Failed while waiting for a secure discovery response.");
+ OCStackResult resCancel = OCCancel(handle, OC_HIGH_QOS, NULL, 0);
+ if (OC_STACK_OK != resCancel)
+ {
+ OIC_LOG(ERROR, TAG, "Failed to remove registered callback");
+ }
+ return res;
+ }
+
+ res = OCCancel(handle, OC_HIGH_QOS, NULL, 0);
+ if (OC_STACK_OK != res)
+ {
+ OIC_LOG(ERROR, TAG, "Failed to remove the registered callback");
+ return res;
+ }
+ OIC_LOG(DEBUG, TAG, "OUT PMMultipleOwnerSingleDeviceDiscovery");
+ return res;
+}
/**
* Discover multiple OTM enabled devices in the same IP subnet.
return res;
}
+/**
+ * The function is responsible for determining if the caller is a subowner of the specified device.
+ *
+ * @param[in] device MOT enabled device that contains a list of subowners
+ * @param[out] isSubowner Bool indicating whether the caller is a subowner of device
+ *
+ * @return OC_STACK_OK in case of success and other value otherwise.
+ */
+OCStackResult PMIsSubownerOfDevice(OCProvisionDev_t *device, bool *isSubowner)
+{
+ if ((NULL == device) || (NULL == isSubowner))
+ {
+ return OC_STACK_INVALID_PARAM;
+ }
+
+ OicUuid_t myId;
+ memset(&myId, 0, sizeof(myId));
+ OicSecSubOwner_t* subOwner = NULL;
+
+ *isSubowner = false;
+
+ OCStackResult result = GetDoxmDeviceID(&myId);
+ if (OC_STACK_OK == result)
+ {
+ LL_FOREACH(device->doxm->subOwners, subOwner)
+ {
+ if (memcmp(myId.id, subOwner->uuid.id, sizeof(myId.id)) == 0)
+ {
+ *isSubowner = true;
+ break;
+ }
+ }
+ }
+ else
+ {
+ OIC_LOG(ERROR, TAG, "Error while getting my UUID.");
+ }
+
+ return result;
+}
#endif //MULTIPLE_OWNER
static OCStackResult SecurePortDiscovery(DiscoveryInfo* discoveryInfo,
#define NUMBER_OF_PINNUM (10)
#define NUMBER_OF_ALPHABET (26)
-static GeneratePinCallback gGenPinCallback = NULL;
-static InputPinCallback gInputPinCallback = NULL;
+/**
+ * Callbacks for displaying a pin.
+ */
+typedef struct DisplayPinCallbacks
+{
+ GeneratePinCallback callback;
+ DisplayPinCallbackWithContext contextCallback;
+ void* context;
+} DisplayPinCallbacks_t;
+
+/**
+ * Callbacks for pin input.
+ */
+typedef struct InputPinCallbacks
+{
+ InputPinCallback callback;
+ InputPinCallbackWithContext contextCallback;
+ void* context;
+} InputPinCallbacks_t;
+
+static DisplayPinCallbacks_t g_displayPinCallbacks = { .callback = NULL, .contextCallback = NULL, .context = NULL };
+static InputPinCallbacks_t g_inputPinCallbacks = { .callback = NULL, .contextCallback = NULL, .context = NULL };
typedef struct PinOxmData {
uint8_t pinData[OXM_RANDOM_PIN_MAX_SIZE + 1];
OIC_LOG(ERROR, TAG, "Failed to set callback for input pin.");
return;
}
+
+ if ((NULL != g_inputPinCallbacks.callback) || (NULL != g_inputPinCallbacks.contextCallback))
+ {
+ OIC_LOG(ERROR, TAG, "Callback for input pin is already set.");
+ return;
+ }
- gInputPinCallback = pinCB;
+ g_inputPinCallbacks.callback = pinCB;
+}
+
+OCStackResult SetInputPinWithContextCB(InputPinCallbackWithContext inputPinCB, void* context)
+{
+ if (NULL == inputPinCB)
+ {
+ OIC_LOG(ERROR, TAG, "Failed to set callback for input pin.");
+ return OC_STACK_INVALID_PARAM;
+ }
+
+ if ((NULL != g_inputPinCallbacks.callback) || (NULL != g_inputPinCallbacks.contextCallback))
+ {
+ OIC_LOG(ERROR, TAG, "Callback for input pin is already set.");
+ return OC_STACK_DUPLICATE_REQUEST;
+ }
+
+ g_inputPinCallbacks.contextCallback = inputPinCB;
+ g_inputPinCallbacks.context = context;
+
+ return OC_STACK_OK;
}
void SetGeneratePinCB(GeneratePinCallback pinCB)
return;
}
- gGenPinCallback = pinCB;
+ if ((NULL != g_displayPinCallbacks.callback) || (NULL != g_displayPinCallbacks.contextCallback))
+ {
+ OIC_LOG(ERROR, TAG, "Callback for generate pin is already set.");
+ return;
+ }
+
+ g_displayPinCallbacks.callback = pinCB;
+}
+
+OCStackResult SetDisplayPinWithContextCB(DisplayPinCallbackWithContext displayPinCB, void* context)
+{
+ if (NULL == displayPinCB)
+ {
+ OIC_LOG(ERROR, TAG, "Failed to set a callback for displaying a pin.");
+ return OC_STACK_INVALID_PARAM;
+ }
+
+ if ((NULL != g_displayPinCallbacks.callback) || (NULL != g_displayPinCallbacks.contextCallback))
+ {
+ OIC_LOG(ERROR, TAG, "Callback for displaying a pin is already set.");
+ return OC_STACK_DUPLICATE_REQUEST;
+ }
+
+ g_displayPinCallbacks.contextCallback = displayPinCB;
+ g_displayPinCallbacks.context = context;
+
+ return OC_STACK_OK;
}
void UnsetInputPinCB()
{
- gInputPinCallback = NULL;
+ UnsetInputPinWithContextCB();
+}
+
+void UnsetInputPinWithContextCB()
+{
+ g_inputPinCallbacks.callback = NULL;
+ g_inputPinCallbacks.contextCallback = NULL;
+ g_inputPinCallbacks.context = NULL;
+}
+
+void UnsetGeneratePinCB()
+{
+ UnsetDisplayPinWithContextCB();
+}
+
+void UnsetDisplayPinWithContextCB()
+{
+ g_displayPinCallbacks.callback = NULL;
+ g_displayPinCallbacks.contextCallback = NULL;
+ g_displayPinCallbacks.context = NULL;
}
/**
pinBuffer[g_PinOxmData.pinSize] = '\0';
g_PinOxmData.pinData[g_PinOxmData.pinSize] = '\0';
- if(gGenPinCallback)
+ if(g_displayPinCallbacks.callback)
{
- gGenPinCallback(pinBuffer, g_PinOxmData.pinSize);
+ g_displayPinCallbacks.callback(pinBuffer, g_PinOxmData.pinSize);
+ }
+ else if (g_displayPinCallbacks.contextCallback)
+ {
+ g_displayPinCallbacks.contextCallback(pinBuffer, g_PinOxmData.pinSize, g_displayPinCallbacks.context);
}
else
{
return OC_STACK_OK;
}
-OCStackResult InputPin(char* pinBuffer, size_t bufferSize)
+OCStackResult InputPin(OicUuid_t deviceId, char* pinBuffer, size_t bufferSize)
{
if(!pinBuffer)
{
return OC_STACK_INVALID_PARAM;
}
- if(gInputPinCallback)
+ if(g_inputPinCallbacks.callback)
+ {
+ g_inputPinCallbacks.callback(pinBuffer, bufferSize);
+ OICStrcpy((char*)(g_PinOxmData.pinData), OXM_RANDOM_PIN_MAX_SIZE + 1, pinBuffer);
+ g_PinOxmData.pinSize = strlen((char*)(g_PinOxmData.pinData));
+ }
+ else if (g_inputPinCallbacks.contextCallback)
{
- gInputPinCallback(pinBuffer, bufferSize);
+ g_inputPinCallbacks.contextCallback(deviceId, pinBuffer, bufferSize, g_inputPinCallbacks.context);
OICStrcpy((char*)(g_PinOxmData.pinData), OXM_RANDOM_PIN_MAX_SIZE + 1, pinBuffer);
g_PinOxmData.pinSize = strlen((char*)(g_PinOxmData.pinData));
}
size_t chainSize)>CertChainCallBack;
typedef std::function<OCStackResult(uint8_t verifNum[])> DisplayNumCB;
typedef std::function<OCStackResult()> UserConfirmNumCB;
+ typedef std::function<void(char* pinData, size_t pinSize)> DisplayPinCB;
+ typedef std::function<void(OicUuid_t deviceId, char* pinBuffer, size_t pinBufferSize)> InputPinCB;
struct ProvisionContext
{
TrustCertChainContext(CertChainCallBack cb) : callback(cb){}
};
+ struct DisplayPinContext
+ {
+ DisplayPinCB callback;
+ DisplayPinContext(DisplayPinCB cb) : callback(cb) {}
+ };
+
+ struct InputPinContext
+ {
+ InputPinCB callback;
+ InputPinContext(InputPinCB cb) : callback(cb) {}
+ };
+
struct DisplayNumContext
{
DisplayNumCB callback;
UserConfirmNumContext(UserConfirmNumCB cb) : callback(cb){}
};
+ typedef InputPinContext* InputPinCallbackHandle;
+ typedef DisplayPinContext* DisplayPinCallbackHandle;
+
/**
* This class is for credential's to be set to devices.
* The types supported are
static OCStackResult discoverMultipleOwnedDevices(unsigned short timeout,
DeviceList_t &list);
+ /**
+ * API is responsible for discovery of a MOT enabled device with a specified deviceID.
+ * The function will return when security information for device with deviceID has been
+ * obtained or the timeout has been exceeded.
+ *
+ * @param timeout Maximum time, in seconds, this function will listen for responses
+ * from servers before returning.
+ * @param deviceID deviceID of target device
+ * @param foundDevice OCSecureResource object of found device.
+ * @return ::OC_STACK_OK in case of success and other value otherwise.
+ * ::OC_STACK_INVALID_PARAM when deviceID is NULL or ppFoundDevice is not
+ * initailized.
+ */
+ static OCStackResult discoverMultipleOwnerEnabledDevice(unsigned short timeout,
+ const OicUuid_t* deviceID,
+ std::shared_ptr<OCSecureResource> &foundDevice);
+
#endif
/**
- * API for registering Pin Callback.
+ * API for registering a pin input callback. Only one input pin callback is allowed
+ * to be registered at a time by setInputPinCallback and registerInputPinCallback.
+ * Use unsetInputPinCallback to unregister a callback set by setInputPinCallback.
*
- * @param InputPinCallback inputPin caaback function.
- * @return ::OC_STACK_OK in case of success and other value otherwise.
+ * @deprecated Use registerInputPinCallback instead.
+ *
+ * @param InputPinCallback inputPin callback function.
+ * @return OC_STACK_OK in case of success and other value otherwise.
+ * OC_STACK_INVALID_CALLBACK if inputPin is invalid.
+ * OC_STACK_DUPLICATE_REQUEST if an input pin callback has already been set.
*/
static OCStackResult setInputPinCallback(InputPinCallback inputPin);
/**
- * API for de-registering Pin Callback.
+ * API for de-registering a pin callback.
+ *
+ * @deprecated Use deregisterInputPinCallback instead.
*
* @return ::OC_STACK_OK in case of success and other value otherwise.
*/
static OCStackResult unsetInputPinCallback();
/**
+ * API to register for a callback to input a pin. Only one input pin callback is allowed
+ * to be registered at a time by setInputPinCallback and registerInputPinCallback. Use
+ * deregisterInputPinCallback to unregister a callback set by registerInputPinCallback.
+ *
+ * @param inputPinCB Callback which is to be registered.
+ * @param inputPinCallbackHandle Pointer to a handle that can be used to deregister the callback.
+ * @return OC_STACK_OK in case of success and other values otherwise.
+ * OC_STACK_INVALID_CALLBACK if inputPinCB is invalid.
+ * OC_STACK_INVALID_PARAM if inputPinCallbackHandle is invalid.
+ * OC_STACK_DUPLICATE_REQUEST if an input pin callback has already been set.
+ */
+ static OCStackResult registerInputPinCallback(InputPinCB inputPinCB, InputPinCallbackHandle* inputPinCallbackHandle);
+
+ /**
+ * API to de-register the callback to input a pin.
+ *
+ * @param inputPinCallbackHandle Handle specifying which callback to deregister.
+ * @return OC_STACK_OK in case of success and other value otherwise.
+ */
+ static OCStackResult deregisterInputPinCallback(InputPinCallbackHandle inputPinCallbackHandle);
+
+ /**
+ * API to register a callback to display the stack generated PIN. Only one display pin callback
+ * is allowed to be registered at a time by setDisplayPinCB and registerDisplayPinCallback.
+ * Use unsetDisplayPinCB to unregister a callback set by setDisplayPinCB.
+ *
+ * @deprecated Use registerDisplayPinCallback instead.
+ *
+ * @param displayPin Callback method to display a generated pin.
+ * @return OC_STACK_OK in case of success and other value otherwise.
+ * OC_STACK_INVALID_CALLBACK if displayPin is invalid.
+ * OC_STACK_DUPLICATE_REQUEST if a display pin callback has already been set.
+ */
+ static OCStackResult setDisplayPinCB(GeneratePinCallback displayPin);
+
+ /**
+ * API for de-registering the display pin callback.
+ *
+ * @deprecated Use deregisterDisplayPinCallback instead.
+ *
+ * @return ::OC_STACK_OK in case of success and other value otherwise.
+ */
+ static OCStackResult unsetDisplayPinCB();
+
+ /**
+ * API to register for a callback to display a pin. Only one display pin callback is
+ * allowed to be registered at a time by setDisplayPinCB and registerDisplayPinCallback.
+ * Use deregisterDisplayPinCallback to unregister a callback set by registerDisplayPinCallback.
+ *
+ * @param displayPinCB Callback which is to be registered.
+ * @param displayPinCallbackHandle Pointer to a handle that can be used to deregister the callback.
+ * @return OC_STACK_OK in case of success and other value otherwise.
+ * OC_STACK_INVALID_CALLBACK if displayPinCB is invalid.
+ * OC_STACK_INVALID_PARAM if displayPinCallbackHandle is invalid.
+ * OC_STACK_DUPLICATE_REQUEST if a display pin callback has already been set.
+ */
+ static OCStackResult registerDisplayPinCallback(DisplayPinCB displayPinCB, DisplayPinCallbackHandle* displayPinCallbackHandle);
+
+ /**
+ * API to de-register the callback to display a pin.
+ *
+ * @param displayPinCallbackHandle Handle used to deregister the callback.
+ * @return OC_STACK_OK in case of success and other value otherwise.
+ */
+ static OCStackResult deregisterDisplayPinCallback(DisplayPinCallbackHandle displayPinCallbackHandle);
+
+ /**
* API to get status of all the devices in current subnet. The status include endpoint
* information and doxm information which can be extracted during owned and unowned
* discovery. Along with this information, API will provide information about
static OCStackResult getDevInfoFromNetwork(unsigned short timeout,
DeviceList_t &ownedDevList,
DeviceList_t &unownedDevList);
- /**
- * Server API to register callback to display stack generated PIN.
- *
- * @param displayPin Callback Method to Display generated PIN.
- * @return ::OC_STACK_OK in case of success and other value otherwise.
- */
- static OCStackResult setDisplayPinCB(GeneratePinCallback displayPin);
/**
* API to remove device credential and ACL from all devices in subnet.
bool getOwnedStatus();
/**
+ * This function provides the selected ownership transfer method of the device.
+ * @return Selected ownership transfer method.
+ */
+ OicSecOxm_t getSelectedOwnershipTransferMethod();
+
+ /**
* API to get the proper OxM for OT.
*
* @param oxm Address to save the selected OxM.
OCStackResult doMultipleOwnershipTransfer(ResultCallBack resultCallback);
/**
+ * API to check if the caller is a subowner of the MOT device.
+ *
+ * @param subowner Bool indicating if the caller is a subowner.
+ *
+ * @return ::OC_STACK_OK in case of success and other values otherwise.
+ */
+ OCStackResult isSubownerOfDevice(bool* subowner);
+
+ /**
* API to get the proper OxM for MOT.
*
* @param oxm Address to save the selected OxM.
*/
bool isMOTEnabled();
-
#endif // MULTIPLE_OWNER
private:
Import('env')
-ocprovision_env = env.Clone()
+lib_env = env.Clone()
+SConscript(lib_env.get('SRC_DIR') + '/resource/third_party_libs.scons', 'lib_env')
+
+ocprovision_env = lib_env.Clone()
######################################################################
# Build flags
ocprovision_env.AppendUnique(LIBPATH = [ocprovision_env.get('BUILD_DIR')])
ocprovision_env.AppendUnique(LIBS = ['octbstack', 'oc_logger'])
+if target_os in ['windows']:
+ ocprovision_env.PrependUnique(LIBS = [
+ 'oc',
+ 'octbstack',
+ 'oc_logger',
+ ])
+
######################################################################
# Source files and Targets
######################################################################
]
ocprovision_env.UserInstallTargetHeader('../include/OCCloudProvisioning.hpp', 'resource', 'OCCloudProvisioning.hpp')
-ocprovision = ocprovision_env.SharedLibrary('ocprovision', ocprovision_src)
+if target_os not in ['windows']:
+ ocprovision = ocprovision_env.SharedLibrary('ocprovision', ocprovision_src)
+else:
+ ocprovision = ocprovision_env.StaticLibrary('ocprovision', ocprovision_src)
ocprovision_env.InstallTarget(ocprovision, 'libocprovision')
ocprovision_env.UserInstallTargetLib(ocprovision, 'libocprovision')
ocprovision_env.UserInstallTargetHeader('../include/OCProvisioningManager.hpp', 'resource', 'OCProvisioningManager.hpp')
pUnownedDevList.erase(pUnownedDevList.begin() + transferDevIdx);
}
-void InputPinCB(char* pinBuf, size_t bufSize)
+void OnInputPinCB(OicUuid_t deviceId, char* pinBuf, size_t bufSize)
{
if(pinBuf)
{
#if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
static int saveTrustCert(void)
{
-
// call |OCSaveTrustCertChainBin| API actually
printf(" Save Trust Cert. Chain into Cred of SVR.\n");
try
{
+ InputPinCallbackHandle callbackHandle = nullptr;
int choice;
OicSecAcl_t *acl1 = nullptr, *acl2 = nullptr;
if (OCSecure::provisionInit("") != OC_STACK_OK)
return 1;
}
+ result = OCSecure::registerInputPinCallback(OnInputPinCB, &callbackHandle);
+ if (result != OC_STACK_OK)
+ {
+ std::cout << "!!Error - registerInputPinCallback failed." << std::endl;
+ }
+
result = OCSecure::registerDisplayNumCallback(displayMutualVerifNumCB);
if (result != OC_STACK_OK)
{
break;
}
transferDevIdx = devNum - 1;
-
- //register callbacks for JUST WORKS and PIN methods
- std::cout <<"Registering OTM Methods: 1. JUST WORKS and 2. PIN"<<std::endl;
- OCSecure::setInputPinCallback(InputPinCB);
-
+
ask = 0;
std::cout << "Transfering ownership for : "<<
pUnownedDevList[devNum-1]->getDeviceID()<<std::endl;
break;
}
}
+
+ // Unregister the input pin callback
+ OCSecure::deregisterInputPinCallback(callbackHandle);
}
catch(OCException& e)
{
pMOTEnabledDeviceList.erase(pMOTEnabledDeviceList.begin() + transferDevIdx);
}
-void InputPinCB(char* pinBuf, size_t bufSize)
+void OnInputPinCB(OicUuid_t deviceId, char* pinBuf, size_t bufSize)
{
if(pinBuf)
{
int main(void)
{
+ InputPinCallbackHandle callbackHandle = nullptr;
+
OCPersistentStorage ps {client_open, fread, fwrite, fclose, unlink };
// Create PlatformConfig object
OCPlatform::Configure(cfg);
- //set Input Pin callback
- OCSecure::setInputPinCallback(InputPinCB);
+ // Set Input Pin callback
+ if (OC_STACK_OK != OCSecure::registerInputPinCallback(OnInputPinCB, &callbackHandle))
+ {
+ std::cout << "!!Error - registerInputPinCallback failed." << std::endl;
+ }
try
{
oclog() << "Exception in main: "<<e.what();
}
+ // Unregister input pin callback
+ OCSecure::deregisterInputPinCallback(callbackHandle);
+
return 0;
}
namespace OC
{
+ /**
+ * Prevent multiple registrations of the input pin callback since the
+ * underlying IoTivity stack can only handle having one callback set
+ * at a time.
+ */
+ bool g_inputPinCallbackRegistered = false;
+
+ /**
+ * Prevent multiple registrations of the display pin callback since the
+ * underlying IoTivity stack can only handle having one callback set
+ * at a time.
+ */
+ bool g_displayPinCallbackRegistered = false;
+
OCStackResult OCSecure::provisionInit(const std::string& dbPath)
{
OCStackResult result;
return result;
}
+ OCStackResult OCSecure::discoverMultipleOwnerEnabledDevice(unsigned short timeout, const OicUuid_t* deviceID, std::shared_ptr<OCSecureResource> &foundDevice)
+ {
+ OCStackResult result;
+ OCProvisionDev_t *pDev = nullptr;
+ auto csdkLock = OCPlatform_impl::Instance().csdkLock();
+ auto cLock = csdkLock.lock();
+
+ if (cLock)
+ {
+ std::lock_guard<std::recursive_mutex> lock(*cLock);
+ result = OCDiscoverMultipleOwnerEnabledSingleDevice(timeout, deviceID, &pDev);
+ if (result == OC_STACK_OK)
+ {
+ if (pDev)
+ {
+ foundDevice.reset(new OCSecureResource(csdkLock, pDev));
+ }
+ else
+ {
+ oclog() << "Not found Secure resource!";
+ foundDevice.reset();
+ }
+ }
+ else
+ {
+ oclog() << "Secure resource discovery failed!";
+ }
+ }
+ else
+ {
+ oclog() << "Mutex not found";
+ result = OC_STACK_ERROR;
+ }
+
+ return result;
+ }
+
#endif
OCStackResult OCSecure::setInputPinCallback(InputPinCallback inputPin)
{
- OCStackResult result;
+ if (!inputPin)
+ {
+ oclog() << "inputPin can't be null";
+ return OC_STACK_INVALID_PARAM;
+ }
+ else if (g_inputPinCallbackRegistered)
+ {
+ oclog() << "Callback for pin input already registered.";
+ return OC_STACK_DUPLICATE_REQUEST;
+ }
+
+ OCStackResult result = OC_STACK_OK;
auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
if (cLock)
{
std::lock_guard<std::recursive_mutex> lock(*cLock);
SetInputPinCB(inputPin);
- result = OC_STACK_OK;
+ g_inputPinCallbackRegistered = true;
}
else
{
OCStackResult OCSecure::unsetInputPinCallback()
{
- OCStackResult result;
+ OCStackResult result = OC_STACK_OK;
auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
if (cLock)
{
std::lock_guard<std::recursive_mutex> lock(*cLock);
UnsetInputPinCB();
- result = OC_STACK_OK;
+ g_inputPinCallbackRegistered = false;
}
else
{
- oclog() <<"Mutex not found";
+ oclog() << "Mutex not found";
+ result = OC_STACK_ERROR;
+ }
+
+ return result;
+ }
+
+ static void inputPinCallbackWrapper(OicUuid_t deviceId, char* pinBuffer, size_t pinBufferSize, void* context)
+ {
+ (static_cast<InputPinContext*>(context))->callback(deviceId, pinBuffer, pinBufferSize);
+ }
+
+ OCStackResult OCSecure::registerInputPinCallback(InputPinCB inputPinCB, InputPinCallbackHandle* inputPinCallbackHandle)
+ {
+ OCStackResult result = OC_STACK_ERROR;
+
+ if (!inputPinCB)
+ {
+ oclog() << "Failed to register callback for pin input.";
+ return OC_STACK_INVALID_CALLBACK;
+ }
+ else if (!inputPinCallbackHandle)
+ {
+ return OC_STACK_INVALID_PARAM;
+ }
+ else if (g_inputPinCallbackRegistered)
+ {
+ oclog() << "Callback for pin input already registered.";
+ return OC_STACK_DUPLICATE_REQUEST;
+ }
+
+ *inputPinCallbackHandle = nullptr;
+
+ auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
+
+ if (cLock)
+ {
+ InputPinContext* inputPinContext = new InputPinContext(inputPinCB);
+ if (nullptr != inputPinContext)
+ {
+ std::lock_guard<std::recursive_mutex> lock(*cLock);
+ result = SetInputPinWithContextCB(&inputPinCallbackWrapper, static_cast<void*>(inputPinContext));
+ if (OC_STACK_OK == result)
+ {
+ g_inputPinCallbackRegistered = true;
+ *inputPinCallbackHandle = inputPinContext;
+ }
+ else
+ {
+ if (nullptr != inputPinContext)
+ {
+ delete inputPinContext;
+ }
+ }
+ }
+ else
+ {
+ result = OC_STACK_NO_MEMORY;
+ }
+ }
+ else
+ {
+ oclog() << "Mutex not found";
+ }
+
+ return result;
+ }
+
+ OCStackResult OCSecure::deregisterInputPinCallback(InputPinCallbackHandle inputPinCallbackHandle)
+ {
+ OCStackResult result = OC_STACK_OK;
+
+ auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
+
+ if (cLock)
+ {
+ std::lock_guard<std::recursive_mutex> lock(*cLock);
+ UnsetInputPinWithContextCB();
+ if (nullptr != inputPinCallbackHandle)
+ {
+ delete inputPinCallbackHandle;
+ }
+ g_inputPinCallbackRegistered = false;
+ }
+ else
+ {
+ oclog() << "Mutex not found";
result = OC_STACK_ERROR;
}
oclog() <<"displayPin can't be null";
return OC_STACK_INVALID_PARAM;
}
+ else if (g_displayPinCallbackRegistered)
+ {
+ oclog() << "Callback for pin display already registered.";
+ return OC_STACK_DUPLICATE_REQUEST;
+ }
OCStackResult result = OC_STACK_OK;
auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
{
std::lock_guard<std::recursive_mutex> lock(*cLock);
SetGeneratePinCB(displayPin);
+ g_displayPinCallbackRegistered = true;
}
else
{
return result;
}
+ OCStackResult OCSecure::unsetDisplayPinCB()
+ {
+ OCStackResult result = OC_STACK_OK;
+ auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
+
+ if (cLock)
+ {
+ std::lock_guard<std::recursive_mutex> lock(*cLock);
+ UnsetGeneratePinCB();
+ g_displayPinCallbackRegistered = false;
+ }
+ else
+ {
+ oclog() << "Mutex not found";
+ result = OC_STACK_ERROR;
+ }
+
+ return result;
+ }
+
+ static void displayPinCallbackWrapper(char* pinData, size_t pinDataSize, void* context)
+ {
+ (static_cast<DisplayPinContext*>(context))->callback(pinData, pinDataSize);
+ }
+
+ OCStackResult OCSecure::registerDisplayPinCallback(DisplayPinCB displayPinCB, DisplayPinCallbackHandle* displayPinCallbackHandle)
+ {
+ OCStackResult result = OC_STACK_ERROR;
+
+ if (!displayPinCB)
+ {
+ oclog() << "Failed to register callback for pin display.";
+ return OC_STACK_INVALID_CALLBACK;
+ }
+ else if (!displayPinCallbackHandle)
+ {
+ return OC_STACK_INVALID_PARAM;
+ }
+ else if (g_displayPinCallbackRegistered)
+ {
+ oclog() << "Callback for pin display already registered.";
+ return OC_STACK_DUPLICATE_REQUEST;
+ }
+
+ *displayPinCallbackHandle = nullptr;
+
+ auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
+
+ if (cLock)
+ {
+ DisplayPinContext* displayPinContext = new DisplayPinContext(displayPinCB);
+ if (nullptr != displayPinContext)
+ {
+ std::lock_guard<std::recursive_mutex> lock(*cLock);
+ result = SetDisplayPinWithContextCB(&displayPinCallbackWrapper, static_cast<void*>(displayPinContext));
+ if (OC_STACK_OK == result)
+ {
+ *displayPinCallbackHandle = displayPinContext;
+ g_displayPinCallbackRegistered = true;
+ }
+ else
+ {
+ if (nullptr != displayPinContext)
+ {
+ delete displayPinContext;
+ }
+ }
+ }
+ else
+ {
+ result = OC_STACK_NO_MEMORY;
+ }
+ }
+ else
+ {
+ oclog() << "Mutex not found";
+ }
+
+ return result;
+ }
+
+ OCStackResult OCSecure::deregisterDisplayPinCallback(DisplayPinCallbackHandle displayPinCallbackHandle)
+ {
+ OCStackResult result = OC_STACK_OK;
+
+ auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
+ if (cLock)
+ {
+ std::lock_guard<std::recursive_mutex> lock(*cLock);
+ UnsetDisplayPinWithContextCB();
+ if (nullptr != displayPinCallbackHandle)
+ {
+ delete displayPinCallbackHandle;
+ }
+ g_displayPinCallbackRegistered = false;
+ }
+ else
+ {
+ oclog() << "Mutex not found";
+ result = OC_STACK_ERROR;
+ }
+
+ return result;
+ }
+
OCStackResult OCSecure::removeDeviceWithUuid(unsigned short waitTimeForOwnedDeviceDiscovery,
std::string uuid,
ResultCallBack resultCallback)
return result;
}
+ OCStackResult OCSecureResource::isSubownerOfDevice(bool* subowner)
+ {
+ if (!subowner)
+ {
+ oclog() << "Subowner cannot be null";
+ return OC_STACK_INVALID_CALLBACK;
+ }
+
+ OCStackResult result;
+ auto cLock = m_csdkLock.lock();
+
+ if (cLock)
+ {
+ std::lock_guard<std::recursive_mutex> lock(*cLock);
+ result = OCIsSubownerOfDevice(devPtr, subowner);
+ }
+ else
+ {
+ oclog() << "Mutex not found";
+ result = OC_STACK_ERROR;
+ }
+ return result;
+ }
+
#endif
OCStackResult OCSecureResource::provisionACL( const OicSecAcl_t* acl,
ResultCallBack resultCallback)
return devPtr->doxm->owned;
}
+ OicSecOxm_t OCSecureResource::getSelectedOwnershipTransferMethod()
+ {
+ validateSecureResource();
+ return devPtr->doxm->oxmSel;
+ }
+
void OCSecureResource::validateSecureResource()
{
if (!devPtr)
oclib_env.UserInstallTargetHeader(header_dir + 'OCAccountManager.h', 'resource', 'OCAccountManager.h')
# Add Provisioning library
-if target_os in ['linux', 'android', 'tizen'] and secured == '1':
+if target_os in ['linux', 'android', 'tizen', 'windows'] and secured == '1':
SConscript('../provisioning/SConscript')
set WITH_TCP=1
set WITH_UPSTREAM_LIBCOAP=1
set BINDIR=debug
+set MULTIPLE_OWNER=1
set RUN_ARG=%1
SHIFT
set PATH=!PATH!;!BUILD_DIR!;C:\msys64\mingw64\bin
)
-set BUILD_OPTIONS= TARGET_OS=%TARGET_OS% TARGET_ARCH=%TARGET_ARCH% RELEASE=%RELEASE% WITH_RA=0 TARGET_TRANSPORT=IP SECURED=%SECURED% WITH_TCP=%WITH_TCP% BUILD_SAMPLE=ON LOGGING=%LOGGING% TEST=%TEST% RD_MODE=CLIENT ROUTING=%ROUTING% WITH_UPSTREAM_LIBCOAP=%WITH_UPSTREAM_LIBCOAP%
+set BUILD_OPTIONS= TARGET_OS=%TARGET_OS% TARGET_ARCH=%TARGET_ARCH% RELEASE=%RELEASE% WITH_RA=0 TARGET_TRANSPORT=IP SECURED=%SECURED% WITH_TCP=%WITH_TCP% BUILD_SAMPLE=ON LOGGING=%LOGGING% TEST=%TEST% RD_MODE=CLIENT ROUTING=%ROUTING% WITH_UPSTREAM_LIBCOAP=%WITH_UPSTREAM_LIBCOAP% MULTIPLE_OWNER=%MULTIPLE_OWNER%
REM Use MSVC_VERSION=12.0 for VS2013, or MSVC_VERSION=14.0 for VS2015.
REM If MSVC_VERSION has not been defined here, SCons chooses automatically a VS version.
echo ROUTING=%ROUTING%
echo WITH_TCP=%WITH_TCP%
echo WITH_UPSTREAM_LIBCOAP=%WITH_UPSTREAM_LIBCOAP%
+ echo MULTIPLE_OWNER=%MULTIPLE_OWNER%
echo MSVC_VERSION=%MSVC_VERSION%
echo.scons VERBOSE=1 %BUILD_OPTIONS%
scons VERBOSE=1 %BUILD_OPTIONS%