Reputation: 3955
I have cloned and built the azure-iot-sdk-c on Debian (on a Virtual Box virtual machine). I am having issues adapting the prov_dev_client_sample and getting it to work. I just can't get my Debian device provisioned on the my IoT Hub through my enrolment group.
I have completed all the steps in detail to create an IoT Hub, DPS, link them, then create and symmetric key enrolment for the enrolment group for the DPS. The id_scope is correct. The Primary Key in Symmetric Key settings is used in the prov_dev_set_symmetric_key_info. I also tried the Secondary key.
Here is my prov_dev_client_sample code :
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
// CAVEAT: This sample is to demonstrate azure IoT client concepts only and is not a guide design principles or style
// Checking of return codes and error values shall be omitted for brevity. Please practice sound engineering practices
// when writing production code.
#include <stdio.h>
#include <stdlib.h>
#include "iothub.h"
#include "azure_c_shared_utility/shared_util_options.h"
#include "azure_c_shared_utility/http_proxy_io.h"
#include "azure_c_shared_utility/threadapi.h"
#include "azure_prov_client/prov_device_client.h"
#include "azure_prov_client/prov_security_factory.h"
#ifdef SET_TRUSTED_CERT_IN_SAMPLES
#include "certs.h"
#endif // SET_TRUSTED_CERT_IN_SAMPLES
//
// The protocol you wish to use should be uncommented
//
#define SAMPLE_MQTT
//#define SAMPLE_MQTT_OVER_WEBSOCKETS
//#define SAMPLE_AMQP
//#define SAMPLE_AMQP_OVER_WEBSOCKETS
//#define SAMPLE_HTTP
#ifdef SAMPLE_MQTT
#include "iothubtransportmqtt.h"
#include "azure_prov_client/prov_transport_mqtt_client.h"
#endif // SAMPLE_MQTT
#ifdef SAMPLE_MQTT_OVER_WEBSOCKETS
#include "iothubtransportmqtt_websockets.h"
#include "azure_prov_client/prov_transport_mqtt_ws_client.h"
#endif // SAMPLE_MQTT_OVER_WEBSOCKETS
#ifdef SAMPLE_AMQP
#include "iothubtransportamqp.h"
#include "azure_prov_client/prov_transport_amqp_client.h"
#endif // SAMPLE_AMQP
#ifdef SAMPLE_AMQP_OVER_WEBSOCKETS
#include "iothubtransportamqp_websockets.h"
#include "azure_prov_client/prov_transport_amqp_ws_client.h"
#endif // SAMPLE_AMQP_OVER_WEBSOCKETS
#ifdef SAMPLE_HTTP
#include "iothubtransporthttp.h"
#include "azure_prov_client/prov_transport_http_client.h"
#endif // SAMPLE_HTTP
#ifdef SET_TRUSTED_CERT_IN_SAMPLES
#include "certs.h"
#endif // SET_TRUSTED_CERT_IN_SAMPLES
// This sample is to demostrate iothub reconnection with provisioning and should not
// be confused as production code
MU_DEFINE_ENUM_STRINGS_WITHOUT_INVALID(PROV_DEVICE_RESULT, PROV_DEVICE_RESULT_VALUE);
MU_DEFINE_ENUM_STRINGS_WITHOUT_INVALID(PROV_DEVICE_REG_STATUS, PROV_DEVICE_REG_STATUS_VALUES);
static const char* global_prov_uri = "global.azure-devices-provisioning.net";
static const char* id_scope = "0ne00C8369A";
volatile static bool g_registration_complete = false;
static bool g_use_proxy = false;
static const char* PROXY_ADDRESS = "127.0.0.1";
#define PROXY_PORT 8888
#define MESSAGES_TO_SEND 2
#define TIME_BETWEEN_MESSAGES 2
static void registration_status_callback(PROV_DEVICE_REG_STATUS reg_status, void* user_context)
{
(void)user_context;
(void)printf("Provisioning Status: %s\r\n", MU_ENUM_TO_STRING(PROV_DEVICE_REG_STATUS, reg_status));
}
static void register_device_callback(PROV_DEVICE_RESULT register_result, const char* iothub_uri, const char* device_id, void* user_context)
{
(void)user_context;
if (register_result == PROV_DEVICE_RESULT_OK)
{
(void)printf("\r\nRegistration Information received from service: %s, deviceId: %s\r\n", iothub_uri, device_id);
}
else
{
(void)printf("\r\nFailure registering device: %s\r\n", MU_ENUM_TO_STRING(PROV_DEVICE_RESULT, register_result));
}
g_registration_complete = true;
}
int main(void)
{
SECURE_DEVICE_TYPE hsm_type;
//hsm_type = SECURE_DEVICE_TYPE_TPM;
//hsm_type = SECURE_DEVICE_TYPE_X509;
hsm_type = SECURE_DEVICE_TYPE_SYMMETRIC_KEY;
// Used to initialize IoTHub SDK subsystem
(void)IoTHub_Init();
(void)prov_dev_security_init(hsm_type);
// Set the symmetric key if using they auth type
// If using DPS with an enrollment group, this must the the derived device key from the DPS Primary Key
// https://docs.microsoft.com/azure/iot-dps/concepts-symmetric-key-attestation?tabs=azure-cli#group-enrollments
prov_dev_set_symmetric_key_info("test-device-Debian", "f/+oXlAlz3ejgOduLND7FbBBepEkiT8X184qzNe7pXYNoI2cJ6AOb1wsAVgxwr4SHHnX57pV6vyL4TaZgbabvA==");
HTTP_PROXY_OPTIONS http_proxy;
PROV_DEVICE_TRANSPORT_PROVIDER_FUNCTION prov_transport;
memset(&http_proxy, 0, sizeof(HTTP_PROXY_OPTIONS));
// Protocol to USE - HTTP, AMQP, AMQP_WS, MQTT, MQTT_WS
#ifdef SAMPLE_MQTT
prov_transport = Prov_Device_MQTT_Protocol;
#endif // SAMPLE_MQTT
#ifdef SAMPLE_MQTT_OVER_WEBSOCKETS
prov_transport = Prov_Device_MQTT_WS_Protocol;
#endif // SAMPLE_MQTT_OVER_WEBSOCKETS
#ifdef SAMPLE_AMQP
prov_transport = Prov_Device_AMQP_Protocol;
#endif // SAMPLE_AMQP
#ifdef SAMPLE_AMQP_OVER_WEBSOCKETS
prov_transport = Prov_Device_AMQP_WS_Protocol;
#endif // SAMPLE_AMQP_OVER_WEBSOCKETS
#ifdef SAMPLE_HTTP
prov_transport = Prov_Device_HTTP_Protocol;
#endif // SAMPLE_HTTP
printf("Provisioning API Version: %s\r\n", Prov_Device_GetVersionString());
if (g_use_proxy)
{
http_proxy.host_address = PROXY_ADDRESS;
http_proxy.port = PROXY_PORT;
}
PROV_DEVICE_RESULT prov_device_result = PROV_DEVICE_RESULT_ERROR;
PROV_DEVICE_HANDLE prov_device_handle;
if ((prov_device_handle = Prov_Device_Create(global_prov_uri, id_scope, prov_transport)) == NULL)
{
(void)printf("failed calling Prov_Device_Create\r\n");
}
else
{
if (http_proxy.host_address != NULL)
{
Prov_Device_SetOption(prov_device_handle, OPTION_HTTP_PROXY, &http_proxy);
}
//bool traceOn = true;
//Prov_Device_SetOption(prov_device_handle, PROV_OPTION_LOG_TRACE, &traceOn);
#ifdef SET_TRUSTED_CERT_IN_SAMPLES
// Setting the Trusted Certificate. This is only necessary on systems without
// built in certificate stores.
Prov_Device_SetOption(prov_device_handle, OPTION_TRUSTED_CERT, certificates);
#endif // SET_TRUSTED_CERT_IN_SAMPLES
// This option sets the registration ID it overrides the registration ID that is
// set within the HSM so be cautious if setting this value
//Prov_Device_SetOption(prov_device_handle, PROV_REGISTRATION_ID, "[REGISTRATION ID]");
prov_device_result = Prov_Device_Register_Device(prov_device_handle, register_device_callback, NULL, registration_status_callback, NULL);
if (prov_device_result == PROV_DEVICE_RESULT_OK)
{
(void)printf("\r\nRegistering Device\r\n\r\n");
do
{
ThreadAPI_Sleep(1000);
} while (!g_registration_complete);
}
else
{
(void)printf("\r\nRegistering failed with error: %d\r\n\r\n", prov_device_result);
}
Prov_Device_Destroy(prov_device_handle);
}
prov_dev_security_deinit();
// Free all the sdk subsystem
IoTHub_Deinit();
(void)printf("Press enter key to exit:\r\n");
(void)getchar();
return 0;
}
No matter what, I get the below Unauthorized error.
I have tried re-creating the IoT hub and DPS etc. over and over again. What could be the issue here? Thanks
Provisioning API Version: 1.13.0
Registering Device
Provisioning Status: PROV_DEVICE_REG_STATUS_CONNECTED
Error: Time:Sat Apr 13 18:35:28 2024 File:/home/paul/azure-iot-sdk-c/provisioning_client/src/prov_device_ll_client.c Func:prov_transport_process_json_reply Line:668 Unsuccessful json encountered: {"errorCode":401000,"trackingId":"99be0a9d-4f0a-417a-bd87-d35fc757a0ca","message":"Unauthorized","timestampUtc":"2024-04-13T16:35:29.4923688Z"}
Error: Time:Sat Apr 13 18:35:28 2024 File:/home/paul/azure-iot-sdk-c/provisioning_client/src/prov_transport_mqtt_common.c Func:prov_transport_common_mqtt_dowork Line:979 Unable to process registration reply.
Error: Time:Sat Apr 13 18:35:28 2024 File:/home/paul/azure-iot-sdk-c/provisioning_client/src/prov_device_ll_client.c Func:on_transport_registration_data Line:762 Failure retrieving data from the provisioning service
Failure registering device: PROV_DEVICE_RESULT_DEV_AUTH_ERROR
Press enter key to exit:
Upvotes: 1
Views: 284
Reputation: 3669
Make sure you give you details of Registration ID, Primary key, ID Scope and make sure Shared access policies has this Permissions to avoid "Unauthorized" error.
By following the guidelines in the provided document, I successfully connected a device to Azure IoT Hub using the Azure Device Provisioning Service (DPS) with symmetric key attestation in C. Remember to link the IoT hub, include Target IoT hubs during enrollment creation, and add an exception as required.
Select the "Manage enrollments" option and choose "Individual enrollments."
Attestation mechanism: Choose "Symmetric key."
Symmetric key settings: You can generate keys automatically or provide your own.
Registration ID: Provide a unique ID for the device.
Other details: Set provisioning status, reprovision policy, and other options as per your requirements.
Add target IoT hubs.
code is taken from git
prov_device_result = Prov_Device_Register_Device(prov_device_handle, register_device_callback, NULL, registration_status_callback, NULL);
if (prov_device_result == PROV_DEVICE_RESULT_OK)
{
(void)printf("\r\nRegistering Device\r\n\r\n");
do
{
ThreadAPI_Sleep(1000);
} while (!g_registration_complete);
}
else
{
(void)printf("\r\nRegistering failed with error: %d\r\n\r\n", prov_device_result);
}
Prov_Device_Destroy(prov_device_handle);
}
prov_dev_security_deinit();
// Free all the sdk subsystem
IoTHub_Deinit();
(void)printf("Press enter key to exit:\r\n");
(void)getchar();
return 0;
}
Output:
Upvotes: 0