Azure IoT Central Connect Real Device. (Connection String problems) - azure

I am following the next tutorial to add new real device on Azure IoT Central.
https://learn.microsoft.com/en-us/azure/iot-central/tutorial-add-device
I want to use a node red flow to upload data, using the Azure IoT Hub flow, but in the tutorial is not very clear how generate the connection string. I can not find the dps_cstr tool for Windows...
Do you know how I can generate the connection string to upload data from Node-Red to Azure IoT Central?
Thanks

The tutorial has a mistake.
With the dps-keygen we can generate the connection String. I use, -di,-dk,-si
dps-keygen <args>
args:
-di:<deviceId> : device id
-dk:<deviceKey> : device primary or secondary key
-mk:<masterKey> : admin primary or secondary key
-si:<scopeId> : scope id
-mr:<uri> : model repository uri
-mc:<uri> : model capability uri. Leave blank if its value is similar to model rep. uri.
-mi:<modelId> : model id

Related

Registering a device on Azure IoT-hub programatically using mqtt

Is there anyway to register the new device onto the azure iot-hub programmatically using the self/CA created certificates?
For example say, I want to register my raspberry pi on to my newly created IOT-HUB from the same rasp pi. I know we can do it using the AZ Cli. What I am looking for is there a way to do it programmatically, using MQTT/REST?.
Thanks in advance.
Regards,
Pradeep
You can make use of the device provisioning service - DPS. The DPS is another service whose purpose is to identify your device, and in case that the device identification is recognized by the DPS, the DPS will create an identity in your IoT Hub.
You set the DPS in a way that you create either individual enrollment(for individual device onboarding) or a group enrollment(for a group of the devices, typically if you use certificates or shared access key authentication type).
Enrollments typically contain an identification type that the device should present, and IoT Hub to which the device with the presented identification should be assigned.
The typical flow is that the device reaches out to the DPS with some public identification(certificate chain, TPM registration id, or SAS key). Then internally, the DPS can challenge the device(proof-of-possesion in case of CA certificates), and if the device successfully solves the challenge, that means that the device contains a specific secret(private key in case of CA certs) that identifies that device, so the DPS will create the device identity to the assigned hub in that specific enrollment. This process is called attestation.
As a result, on the device side, you receive at least the IoT Hub endpoint, and the device Id which you use to communicate with the IoT Hub.
Below are the code snippets of how you can do this with CA certificates and C#:
var certificate = new X509Certificate2(leafCertificatePath, leafCertificatePassword);
using (var security = new SecurityProviderX509Certificate(certificate))
using (var transport = new ProvisioningTransportHandlerMqtt(TransportFallbackType.TcpOnly))
{
ProvisioningDeviceClient provClient =
ProvisioningDeviceClient.Create(GlobalDeviceEndpoint, dpsScope, security, transport);
var deviceAuthentication = await GetDeviceRegistrationResultAsync(provClient, security);
var auth = new DeviceAuthenticationWithX509Certificate(deviceAuthentication.DeviceId, security.GetAuthenticationCertificate());
var deviceClient = DeviceClient.Create(hostname: deviceAuthentication.AssignedHub,
authenticationMethod: auth,
transportType: TransportType.Mqtt);
if (deviceClient == null)
{
Console.WriteLine("Failed to create DeviceClient!");
}
else
{
SendEvents(deviceClient, MESSAGE_COUNT).Wait();
}
}
Method for getting the device registration result from the DPS:
static async Task<DeviceRegistrationResult> GetDeviceRegistrationResultAsync(ProvisioningDeviceClient provClient, SecurityProviderX509 security)
{
DeviceRegistrationResult result = await provClient.RegisterAsync().ConfigureAwait(false);
if (result.Status != ProvisioningRegistrationStatusType.Assigned)
{
throw new Exception("Device not assigned");
}
return result;
}
Official example from MSFT you can find here
Here is how you can create and verify certificates with IoT Hub and DPS.
Just to clarify, 'registering' a device in IoTHub/DPS is kind of an overloaded term, and may mean different things to different people. If you are using self-signed certs, it's a two step process.
First, you need to enroll the device in DPS, which lets DPS know that sometime in the future, a device may show up with that name and that certificate. That is generally a backend process typically NOT done from the device itself. Technically, there's nothing stopping you from calling the REST APIs to do so from the device, but since you need some pretty powerful credentials to do so, it's not recommended to have them on your device. This cannot be done over MQTT. You can avoid having to enroll every individual device by uploading, verifying, and using a CA-signed cert, though.
Once that's done, the device can now/later register itself, which is the act of actually having DPS create the device registration record in IoT Hub. The device "phones home" to DPS, authenticates itself using the cert you provided in the enrollment, and registers itself, getting the IoT Hub connection information it needs back from DPS. That process can be done over MQTT and you can find step by step the process on my blog -> http://busbyland.com/azure-device-provisioning-server-over-mqtt-using-x509-certificates
Provisioning a device in IoTHub from the device itself is not recommended, as it will then require IoTHub registry write permission and use of service SDK.
The recommended approach is to use Device Provisioning Service, you can create individual or group enrollment with X509 and it will automatically provision the device in target IoTHub.
The device just needs
mechanism to attest its identity
DPS global endpoint
ID Scope to identify your instance of DPS.
Check this - https://learn.microsoft.com/en-us/azure/iot-dps/concepts-x509-attestation

How to move IoT Central application from one subscription to another

I created one IoT Central app form https://apps.azureiotcentral.com/ in my own subscription for a PoC. Now my customer wants me to move it to their own subscription. Question, is it possible to move the whole app? Or do I need to create a new app and then export/import templates, devices and data?
Try the following Copy feature:
EDIT:
For creating a device instance assigned to the compability model can be used, for instance, the REST API.
The following is an example of the device provisioning using the REST API request for myScopeId, mydevice, deviceKey and CapabilityModelId:
PUT:
https://global.azure-devices-provisioning.net/myScopeId/registrations/mydevice/register?api-version=2019-03-31
headers:
Authorization: sas-token
payload:
{
"registrationId":"mydevice",
"payload":{
"__iot:interfaces":{
"CapabilityModelId":"urn:rigado:Cascade_500:1"
}
}
}
where the sas-token can be generated like is described here:
generateSasToken(string resourceUri, string key, string policyName, int expiryInSeconds = 3600)
where:
resourceUri = "myScopeId/registrations/mydevice"
key = deviceKey
policyName = "registration"
You can migrate your application without having to re-create it by visiting the Azure Portal (portal.azure.com) > search for "IoT Central Application" > Find your application and click on it. Inside your application you'll see the subscription it's currently using, and an option to change it. Follow the steps to migrate your subscription.
Ibiza portal screenshot highlighting where the "change" button is.
Keep in mind that moving your application from one subscription to another will not change where your application or device data is stored. For example, if you picked United States as the location for your application, the data will continue to be in the United States, even if your subscription/resource group is in a different region.

How do I connect Minew BLE Gateway with Azure Iot Central?

I am trying to connect a Minew BLE Gateway Device (https://en.minewtech.com/gateway.html) to azure IOT Central. The device template has a prebuilt for this device named as FM 201 BLE and I just went along with it. The gateway requires you connect it thru the X509(ECC) certificates and so I created some selfsigned certificates and uploaded them to the gateway device and uploaded it from it's dashboard
I grabbed the URL from here
Is there anything I'm doing wrong? I'm expecting something in the analtyics of my iotcentral application or atleast a log file from BLE Gateway somewhere if the authentication with certificates failed. Any lead will be highly appreciated. Ive spent hours on the web trying to get this working
I do recommend the following steps before connecting the real device to the IoT Central:
Create 3 devices (e.g. device1, device2 and device3) each with the different authentication type such as sas, selfSigned and certificateAuthority on the IoT Hub (you can used also the Free tier)
Create the simulated device (console program) for each authentication type, connect them to the IoT Hub and send couple messages.
I believe that all devices will work properly (like in my test), so the authentication through a CA certificate (and the leaf certificate) and self signed certificate are OK.
Note, that the above steps passed in my test using a C# simulated devices (.Net SDK) and also with a MQTT direct protocol with my Azure IoT Hub Tester.
Once your simulated devices are working, this step is to replace them (except the sas device) with your real device. This is a critical step, which will prove it that your real device can be connected to the Azure IoT Hub.
In this step, we are going to replace the IoT Hub by IoT Central Application. You can create a free preview application. You can upload the device template such as FM-201 IoT Gateway and create the 3 devices like in the step1 from this template. Note, use the same device ids like in the step1, we can use the same device leaf certificate.
Using the tool dps_cstr we can get the device connection string for underlying IoT Hub of the IoTC App.
Replace the hostname in your simulated devices and also you need to create the sas token from this connection string for the device authenticate with the sas token.
Run the simulated devices connected to the IoTC App.
Based on my recently test, you will see, that only sas device is working, the others such as certificate devices are failed for authentication error.
This step is for troubleshooting why the X509 simulated devices switching to the IoTC App doesn't authenticate with the same certificates. There is no properly document for this case and I hope that some one from the IoT Central team will answer it if we can switch the X509 device between the IoT Hub and IoTC App like we can do it for sas device.
Update:
Based on the Provisioning Device Client Sample - Microsoft Azure IoT SDK for .NET the steps 6 and 7 are fine for sas device, where the utility dps_cstr will registered a device for a SecurityProviderSymmetricKey. Once the device has been registered and provisioned with this security provider, the real device(s) must be connected using this way, only. That's the reason why we getting an error for simulated x509 devices. So, the following step is an example of the provisioning a X509 device with a leaf certificate (device3.pfx). Note, that the CA certificate must be uploaded to the IoTC Application.
6a. Registering the device3 (from the step1) to the IoTC App
string GlobalDeviceEndpoint = "global.azure-devices-provisioning.net";
string idScope = "<idScope_IoTCapp>";
string certificateFileName = #"<your path>\device3.pfx";
//
var cert = new X509Certificate2(certificateFileName, "1234");
var securityProvider = new SecurityProviderX509Certificate(cert);
var transport = new ProvisioningTransportHandlerMqtt(TransportFallbackType.TcpOnly);
var provClient = ProvisioningDeviceClient.Create(GlobalDeviceEndpoint, idScope, securityProvider, transport);
var result = provClient.RegisterAsync().Result;
string hostname = result.AssignedHub;
string deviceId = result.DeviceId;
In this point, the device status in the IoTC App is Provisioned and the simulated or real device can be connected.
6b. You can use for a device provisioning to the IoT Central App also the REST APIs. The following screen snippets show provisioning the X509 device3 authenticated by its leaf certificate using the Postman:
In prior of using the REST calls, we have to add the device3 leaf certificate to the Postman:
Now, we can call a provisioning service:
PUT https://global.azure-devices-provisioning.net/0ne000AA0F5/registrations/device3/register?api-version=2019-03-31
To get the registrationState object:
GET https://global.azure-devices-provisioning.net/0ne000AA0F5/registrations/device3/operations/{operationId}?api-version=2019-03-31
As you can see the above picture, the IoTC application is ready for connection with a real X509 device.
"registrationState": {
"x509": {
"enrollmentGroupId": "fa472b95-b5f6-47af-a4ef-9490f45c3961"
},
"registrationId": "device3",
"createdDateTimeUtc": "2020-01-04T17:09:15.5147034Z",
"assignedHub": "iotc-bceedf66-9792-4f32-b49f-7674a6aa09ff.azure-devices.net",
"deviceId": "device3",
"status": "assigned",
"substatus": "initialAssignment",
"lastUpdatedDateTimeUtc": "2020-01-04T17:09:15.6947214Z",
"etag": "IjBmMDA3YTgzLTAwMDAtMGMwMC0wMDAwLTVlMTBjNmJiMDAwMCI="
}
Note, that in the case of provisioning a sas device (such as a device1 in this test) using the REST calls, the Authorization header must be configured with a sas token:
string sas = generateSASToken($"{scopeId}/registrations/{deviceId}", deviceKey, "registration");
7a. The following code snippet is an example of the sending a telemetry data from the X509 device with its leaf certificate (device3.pfx):
using (var dc = DeviceClient.Create(hostname, new DeviceAuthenticationWithX509Certificate(deviceId, cert), Microsoft.Azure.Devices.Client.TransportType.Mqtt))
{
var telemetryDataPoint = new { bleCnt = 50, telemetryLocation = new { lat = 49.85, lon = 20.99, alt = 29.41 } };
dc.OpenAsync().ConfigureAwait(false);
dc.SendEventAsync(new Message(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(telemetryDataPoint)))).ConfigureAwait(false);
dc.CloseAsync().ConfigureAwait(false);
}
Also, using my Azure IoT Hub Tester which is based on the M2Mqtt library the device3 with a leaf certificate device3.pfx has been successful connected to the IoTC app.
Based on the above update, I would like to correct the step 10. It looks like, the devices (such as the sas and X509) can be switched between the Azure IoT Hub and IoT Central Application once the devices have been provisioned on the IoTC App. In other words, the hostname (e.g. from my test IoTC App preview iotc-bceedf66-9792-4f32-b49f-7674a6aa09ff.azure-devices.net) from the provisioning process is a valid device facing endpoint.
Also my test shown that the device with MQTT direct protocol using a leaf certificate (device3.pfx) for connection to the IoTC app is working very well both directions included a PnP model.
The following screen snippets show the device side and IoTC application:
publishing some telemetry data:
showing telemetry data on the dashboard:
and the root CA certificate on the IoTC app:

How do I map IoTHub in Device Provisioning Service enrollment list? - Enrollment status "unassigned"

I have a Azure device provisioning service setup entitled "myDPS" and below IoT hubs are linked.
IoTHub-Dev-Asia
IoTHub-Prod-Europe
Currently there are no enrollment list. The below c# code I am using to enroll the device
private const string RegistrationId = "TestRegID";
private const string OptionalDeviceId = "Device1";
private const ProvisioningStatus OptionalProvisioningStatus = ProvisioningStatus.Enabled;
private const string SampleTpmEndorsementKey = "***"// Key generated using TPM Simulator
static async Task SetRegistrationDataAsync()
{
Console.WriteLine("Starting SetRegistrationData");
Attestation attestation = new TpmAttestation(SampleTpmEndorsementKey);
IndividualEnrollment individualEnrollment = new
IndividualEnrollment(RegistrationId, attestation);
individualEnrollment.DeviceId = OptionalDeviceId;
individualEnrollment.ProvisioningStatus = OptionalProvisioningStatus;
Console.WriteLine("\nAdding new individualEnrollment...");
var serviceClient = ProvisioningServiceClient.CreateFromConnectionString(ServiceConnectionString);
IndividualEnrollment individualEnrollmentResult =
await serviceClient.CreateOrUpdateIndividualEnrollmentAsync(individualEnrollment).ConfigureAwait(false);
Console.WriteLine("\nIndividualEnrollment created with success.");
Console.WriteLine(individualEnrollmentResult);
}
The above code successfully enrolls the device to the DPS but status shows as unassigned
Issue#1 - Enrollment status unassigned, sometimes shows FAILED
Status: failed
Error code: 404201
Issue#2
Once above issue resolved, then I would like to have some configuration where I can specify which device should map to which IoT, so that device can automatically decide it's target IoT hubs.
Example:
Device1->IoTHub-Dev-Asia
Device2->IoTHub-Dev-Asia
Device3->IoTHub-Dev-Europe
I assume Static configuration via the enrollment list can help but not sure how to use it?
The three supported allocation policies determine how devices are assigned to an IoT hub:
Lowest latency: Devices are provisioned to an IoT hub based on the hub with the lowest latency to the device.
Evenly weighted distribution (default): Linked IoT hubs are equally likely to have devices provisioned to them. This is the default setting. If you are provisioning devices to only one IoT hub, you can keep this setting.
Static configuration via the enrollment list: Specification of the desired IoT hub in the enrollment list takes priority over the DPS-level allocation policy.
If you need to assign the device ,you should use a single call to the ProvisioningDeviceClient.RegisterAsync() API. You can refer to the sample.In the sample, you need to replace the RegistrationId with that your created before.

Column Encryption Setting=enabled not working in Linked Service (Azure Data Factory)

I'm trying to implement a Custom Dot Net Activity which performs a stored procedure activity.
I've known that ADF already having a build in StoredProcActivity. But I want to insert into a table which has been already encrypted (using Always Encryption provider as the Azure Key Vault)
To workaround with always, Encryption using Azure Key vault requires the connection string to be like here
The thing I struct is the simple one While creating a AzureSqlLinkedService. I've added to my connection string with the Column Encryption Setting=enabled aalue. Actually, my connection string would be like:
Data Source=tcp:<ServerNAme>.database.windows.net,1433;Initial Catalog=<DBName>;User ID=<UserName>#<ServerNAme>;Password=<Password>;Integrated Security=False;Encrypt=True;Connect Timeout=30;Column Encryption Setting=enabled;
But, I got an error
Entity provisioning failed: Failed to connect to Linked service. Specified connection string is not valid.

Resources