diff --git a/src/device_manager.h b/src/device_manager.h index 907e831..52838d5 100644 --- a/src/device_manager.h +++ b/src/device_manager.h @@ -42,6 +42,7 @@ //! \{ #define MAX_STR_SIZE (64) +#define DEFAULT_PROVSIONING_TIMEOUT (30) //! \} /** @@ -129,7 +130,7 @@ void GetClientList(json_object *respObj); 2 for ALREADY_PROVISIONED */ ProvisionStatus ProvisionConstrainedDevice(const char *clientID, const char *fcap, - const char *deviceType, int licenseeID, const char *parentID); + const char *deviceType, int licenseeID, const char *parentID, int timeout); /** * @brief Check if constrained device is provisioned or not diff --git a/src/device_manager_ubus.c b/src/device_manager_ubus.c index 9a65b36..45e4836 100644 --- a/src/device_manager_ubus.c +++ b/src/device_manager_ubus.c @@ -67,6 +67,7 @@ enum { ARG_CONSTRAINED_LICENSEE_ID, ARG_CONSTRAINED_FCAP, ARG_CONSTRAINED_PARENT_ID, + ARG_CONSTRAINED_TIMEOUT, PROVISION_CONSTRAINED_DEVICE_MAX }; @@ -112,7 +113,8 @@ static const struct blobmsg_policy [ARG_CONSTRAINED_DEVICE_TYPE] = {.name = "device_type", .type = BLOBMSG_TYPE_STRING}, [ARG_CONSTRAINED_LICENSEE_ID] = {.name = "licensee_id", .type = BLOBMSG_TYPE_INT32}, [ARG_CONSTRAINED_FCAP] = {.name = "fcap", .type = BLOBMSG_TYPE_STRING}, - [ARG_CONSTRAINED_PARENT_ID] = {.name = "parent_id", .type = BLOBMSG_TYPE_STRING} + [ARG_CONSTRAINED_PARENT_ID] = {.name = "parent_id", .type = BLOBMSG_TYPE_STRING}, + [ARG_CONSTRAINED_TIMEOUT] = {.name = "timeout", .type = BLOBMSG_TYPE_INT32} }; /** IsConstrainedDeviceProvisioned arguments and their type. */ @@ -245,6 +247,7 @@ static int ProvisionConstrainedDeviceHandler(struct ubus_context *ctx, struct ub { struct blob_attr *args[PROVISION_CONSTRAINED_DEVICE_MAX]; struct blob_buf b = {0}; + int timeout; blobmsg_parse(provisionConstrainedDevicePolicy, PROVISION_CONSTRAINED_DEVICE_MAX, args, blob_data(msg), blob_len(msg)); if (!args[ARG_CONSTRAINED_DEVICE_TYPE] || !args[ARG_CONSTRAINED_LICENSEE_ID] || @@ -258,10 +261,15 @@ static int ProvisionConstrainedDeviceHandler(struct ubus_context *ctx, struct ub char *fcap = blobmsg_get_string(args[ARG_CONSTRAINED_FCAP]); char *parentID = blobmsg_get_string(args[ARG_CONSTRAINED_PARENT_ID]); + if (!args[ARG_CONSTRAINED_TIMEOUT]) + timeout = DEFAULT_PROVSIONING_TIMEOUT; + else + timeout = blobmsg_get_u32(args[ARG_CONSTRAINED_TIMEOUT]); + if (!deviceType || !clientID || !fcap || !parentID) return UBUS_STATUS_UNKNOWN_ERROR; - ProvisionStatus status = ProvisionConstrainedDevice(clientID, fcap, deviceType, licenseeID, parentID); + ProvisionStatus status = ProvisionConstrainedDevice(clientID, fcap, deviceType, licenseeID, parentID, timeout); blob_buf_init(&b, 0); blobmsg_add_u32(&b, "status", status); diff --git a/src/fdm_provision_constrained.c b/src/fdm_provision_constrained.c index aa1539a..f174991 100644 --- a/src/fdm_provision_constrained.c +++ b/src/fdm_provision_constrained.c @@ -61,8 +61,6 @@ #define COAP_TIMEOUT 10000 -#define POLLING_TIMEOUT_SECONDS 30 - #define POLLING_SLEEP_SECONDS 2 /*************************************************************************************************** @@ -512,15 +510,12 @@ static bool RemoveDeviceObservations(const char *clientID, return result; } -static bool WriteProvisioningInformationToDevice (const AwaServerSession *session, - const char *clientID, const char *fcapCode, const char *deviceType, int licenseeID, - const char *parentID) +static bool WriteParentID (const AwaServerSession *session, const char *clientID, const char *parentID) { - bool result = false; - AwaError error = AwaError_Success; unsigned char i, gatewayDeviceID[DEVICE_ID_SIZE]; AwaOpaque parentIDOpaque; - + AwaError error = AwaError_Success; + bool result = false; // 3 because two is for hex letters and one for space if (strlen(parentID)/3 != DEVICE_ID_SIZE) { @@ -528,6 +523,39 @@ static bool WriteProvisioningInformationToDevice (const AwaServerSession *sessio return false; } + AwaServerWriteOperation *writeOp = AwaServerWriteOperation_New(session, AwaWriteMode_Update); + if (writeOp != NULL) + { + for (i = 0; i < DEVICE_ID_SIZE; i++) + { + // 3 because two is for hex letters and one for space + sscanf(&parentID[i*3], "%02hhX", &gatewayDeviceID[i]); + } + parentIDOpaque.Data = gatewayDeviceID; + parentIDOpaque.Size = sizeof(gatewayDeviceID); + error = AwaServerWriteOperation_AddValueAsOpaque(writeOp, pathStore.parentIDPath, parentIDOpaque); + if (error == AwaError_Success) + { + error = AwaServerWriteOperation_Perform(writeOp, clientID, COAP_TIMEOUT); + if (error == AwaError_Success) + { + result = true; + } + else + { + LOG(LOG_ERR, "Failed to write parentID\nerror: %s", AwaError_ToString(error)); + } + } + AwaServerWriteOperation_Free(&writeOp); + } + return result; +} + +static bool WriteProvisioningInformationToDevice (const AwaServerSession *session, + const char *clientID, const char *fcapCode, const char *deviceType, int licenseeID) +{ + bool result = false; + AwaError error = AwaError_Success; AwaServerWriteOperation *writeOp = AwaServerWriteOperation_New(session, AwaWriteMode_Update); if (writeOp != NULL) { @@ -546,38 +574,28 @@ static bool WriteProvisioningInformationToDevice (const AwaServerSession *sessio error = AwaServerWriteOperation_AddValueAsInteger(writeOp, pathStore.licenseeIDPath, licenseeID); } if (error == AwaError_Success) - { - for (i = 0; i < DEVICE_ID_SIZE; i++) - { - // 3 because two is for hex letters and one for space - sscanf(&parentID[i*3], "%02hhX", &gatewayDeviceID[i]); - } - parentIDOpaque.Data = gatewayDeviceID; - parentIDOpaque.Size = sizeof(gatewayDeviceID); - error = AwaServerWriteOperation_AddValueAsOpaque(writeOp, pathStore.parentIDPath, parentIDOpaque); - } - if (error == AwaError_Success) { error = AwaServerWriteOperation_Perform(writeOp, clientID, COAP_TIMEOUT); if (error == AwaError_Success) { result = true; } + else + { + LOG(LOG_ERR, "Failed to perform write operation\nerror: %s", AwaError_ToString(error)); + } } else { - LOG(LOG_ERR, "Failed to create write request\nerror: %s", - AwaError_ToString(error)); + LOG(LOG_ERR, "Failed to create write request\nerror: %s", AwaError_ToString(error)); } - AwaServerWriteOperation_Free(&writeOp); } return result; } -static bool WaitForNotification(AwaServerSession *session) +static bool WaitForNotification(AwaServerSession *session, int timeout) { - int timeout = POLLING_TIMEOUT_SECONDS; while (timeout-- != 0) { AwaServerSession_Process(session, COAP_TIMEOUT); @@ -613,13 +631,12 @@ bool IsConstrainedDeviceProvisioned(const char *clientID) { status = IsDeviceProvisioned(serverSession, clientID); } - Server_ReleaseSession(&serverSession); return status; } ProvisionStatus ProvisionConstrainedDevice(const char *clientID, const char*fcap, - const char *deviceType, int licenseeID, const char *parentID) + const char *deviceType, int licenseeID, const char *parentID, int timeout) { ProvisionStatus result = PROVISION_FAIL; OBJECT_T flowObjects[] = {flowObject, flowAccessObject}; @@ -659,11 +676,12 @@ ProvisionStatus ProvisionConstrainedDevice(const char *clientID, const char*fcap if (ObserveDeviceFlowAccessObject(serverSession, clientID, &flowAccessObjectChange, &flowAccessObjectChangeObservation)) { - if (!WriteProvisioningInformationToDevice(serverSession, clientID, fcap, deviceType, licenseeID, parentID)) + if (!WriteProvisioningInformationToDevice(serverSession, clientID, fcap, deviceType, licenseeID) || + !WriteParentID(serverSession, clientID, parentID)) { LOG(LOG_ERR, "Writing of device provisioning information failed"); } - else if (WaitForNotification(serverSession)) + else if (WaitForNotification(serverSession, timeout)) { result = PROVISION_OK; } diff --git a/src/fdm_provision_constrained.h b/src/fdm_provision_constrained.h index 5f9b105..ee9e793 100644 --- a/src/fdm_provision_constrained.h +++ b/src/fdm_provision_constrained.h @@ -41,12 +41,13 @@ * @param[in] deviceType registered device type * @param[in] licenseeID Licensee ID. * @param[in] parentID Device ID of Gateway device. + * @param[in] timeout time to wait for notification to arrive. * @return 0 for PROVISION_OK 1 for PROVISION_FAIL 2 for ALREADY_PROVISIONED */ ProvisionStatus ProvisionConstrainedDevice(const char *clientID, const char *fcap, - const char *deviceType, int licenseeID, const char *parentID); + const char *deviceType, int licenseeID, const char *parentID, int timeout); /** * @brief Poll the contents of the FlowAccessObject of the constrained device.