// Copyright (c) Microsoft. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. #include #include #include "azure_c_shared_utility/xlogging.h" #include "azure_c_shared_utility/platform.h" #include "azure_c_shared_utility/threadapi.h" #include "azure_c_shared_utility/crt_abstractions.h" #include "azure_c_shared_utility/shared_util_options.h" #include "iothub_device_client.h" #include "iothub_client_options.h" #include "iothub_message.h" #include "iothub_registrymanager.h" #include "iothubtransportamqp.h" #include "iothub_account.h" #include "iothubtest.h" #include "parson.h" #include "../common_longhaul/iothub_client_common_longhaul.h" #ifdef SET_TRUSTED_CERT_IN_SAMPLES #include "certs.h" #endif // SET_TRUSTED_CERT_IN_SAMPLES const int FIVE_DAYS = (60 * 60 * 24) * 5; const int YEAR_2020 = 1577865600; static const char SAS_DEVICE_PREFIX_FMT[] = "csdk_e2eDevice_sas_j_please_delete_"; static const char X509_DEVICE_PREFIX_FMT[] = "csdk_e2eDevice_x509_j_please_delete_"; static const char HSM_DEVICE_PREFIX_FMT[] = "hsm-dev-"; typedef struct ENUM_CONTEXT_TAG { IOTHUB_REGISTRYMANAGER_HANDLE registryManagerHandle; IOTHUB_SERVICE_CLIENT_DEVICE_TWIN_HANDLE deviceTwinHandle; } ENUM_CONTEXT; void deviceItemEnum(const void* item, const void* action_context, bool* continue_processing) { const ENUM_CONTEXT* context = (const ENUM_CONTEXT*) action_context; const IOTHUB_MODULE* module = (const IOTHUB_MODULE*) item; if (strncmp(module->deviceId, SAS_DEVICE_PREFIX_FMT, sizeof(SAS_DEVICE_PREFIX_FMT) - 1) == 0 || strncmp(module->deviceId, X509_DEVICE_PREFIX_FMT, sizeof(X509_DEVICE_PREFIX_FMT) - 1) == 0 || strncmp(module->deviceId, HSM_DEVICE_PREFIX_FMT, sizeof(HSM_DEVICE_PREFIX_FMT) - 1) == 0) { char* twin = IoTHubDeviceTwin_GetTwin(context->deviceTwinHandle, module->deviceId); if (twin) { JSON_Object* root_object = NULL; JSON_Value* root_value = NULL; JSON_Object* properties = NULL; JSON_Object* desired = NULL; JSON_Object* metadata = NULL; const char* lastUpdated = NULL; if ((root_value = json_parse_string(twin)) == NULL) { LogError("json_parse_string failed"); } else if ((root_object = json_value_get_object(root_value)) == NULL) { LogError("json_value_get_object root object failed"); } else if ((properties = json_object_get_object(root_object, "properties")) == NULL) { LogError("json_object_get_object properties object failed"); } else if ((desired = json_object_get_object(properties, "desired")) == NULL) { LogError("json_object_get_object desired object failed"); } else if ((metadata = json_object_get_object(desired, "$metadata")) == NULL) { LogError("json_object_get_object metadata object failed"); } else if ((lastUpdated = json_object_get_string(metadata, "$lastUpdated")) == NULL) { LogError("json_object_get_object lastUpdated time failed"); } else { struct tm tm = { 0 }; tm.tm_year = atoi(lastUpdated) - 1900; tm.tm_mon = atoi(&lastUpdated[5]) - 1; tm.tm_mday = atoi(&lastUpdated[8]); time_t deviceTime = mktime(&tm); time_t now = time(0); if (deviceTime > YEAR_2020 && (now - deviceTime > FIVE_DAYS)) { LogInfo("Deleting device %s, %d days old", module->deviceId, (int)(now - deviceTime) / (60 * 60 * 24)); IOTHUB_REGISTRYMANAGER_RESULT result = IoTHubRegistryManager_DeleteDevice(context->registryManagerHandle, module->deviceId); if (result != IOTHUB_REGISTRYMANAGER_OK) { LogError("failed to delete device %s", module->deviceId); } } } json_value_free(root_value); free(twin); } } IoTHubRegistryManager_FreeModuleMembers((IOTHUB_MODULE*)module); free((void*)module); *continue_processing = true; } int main(void) { int result = 0; const char* connection_string; IOTHUB_LONGHAUL_RESOURCES_HANDLE iotHubLonghaulRsrcsHandle = NULL; IOTHUB_SERVICE_CLIENT_AUTH_HANDLE serviceClientAuth = NULL; IOTHUB_SERVICE_CLIENT_DEVICE_TWIN_HANDLE deviceTwin = NULL; IOTHUB_ACCOUNT_INFO_HANDLE account_info = NULL; IOTHUB_REGISTRYMANAGER_HANDLE registryManager = NULL; SINGLYLINKEDLIST_HANDLE deviceList = NULL; if ((iotHubLonghaulRsrcsHandle = longhaul_tests_init()) == NULL) { LogError("Test failed"); result = MU_FAILURE; } else if ((account_info = longhaul_get_account_info(iotHubLonghaulRsrcsHandle)) == NULL) { LogError("Failed retrieving account info"); result = MU_FAILURE; } else if ((connection_string = IoTHubAccount_GetIoTHubConnString(account_info)) == NULL) { LogError("Failed retrieving the IoT hub connection string"); result = MU_FAILURE; } else if ((serviceClientAuth = IoTHubServiceClientAuth_CreateFromConnectionString(connection_string)) == NULL) { LogError("Failed to initialize IoT hub service client"); result = MU_FAILURE; } else if ((deviceTwin = IoTHubDeviceTwin_Create(serviceClientAuth)) == NULL) { LogError("Failed to initialize IoT hub service device twin client"); result = MU_FAILURE; } else if ((registryManager = IoTHubRegistryManager_Create(serviceClientAuth)) == NULL) { LogError("Failed to initialize IoT hub service registry manager"); result = MU_FAILURE; } else if ((deviceList = singlylinkedlist_create()) == NULL) { LogError("Failed to create singly linked list"); result = MU_FAILURE; } else if (IoTHubRegistryManager_GetModuleList(registryManager, NULL, deviceList, IOTHUB_REGISTRY_DEVICE_UPDATE_EX_VERSION_1) != IOTHUB_REGISTRYMANAGER_OK) { LogError("Failed to get hub devices"); result = MU_FAILURE; } if (deviceList) { ENUM_CONTEXT context; context.deviceTwinHandle = deviceTwin; context.registryManagerHandle = registryManager; singlylinkedlist_foreach(deviceList, deviceItemEnum, &context); singlylinkedlist_destroy(deviceList); } if (registryManager) { IoTHubRegistryManager_Destroy(registryManager); } if (deviceTwin) { IoTHubDeviceTwin_Destroy(deviceTwin); } if (serviceClientAuth) { IoTHubServiceClientAuth_Destroy(serviceClientAuth); } if (iotHubLonghaulRsrcsHandle) { longhaul_tests_deinit(iotHubLonghaulRsrcsHandle); } return result; }