Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,9 @@ This SDK only supports the **MQTT protocol**.
| Features | Status | Description |
|-----------------------------|--------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| TPM Individual Enrollment | :heavy_minus_sign: | Provisioning via [Trusted Platform Module](https://docs.microsoft.com/en-us/azure/iot-dps/concepts-security#trusted-platform-module-tpm). |
| X.509 Individual Enrollment | :heavy_check_mark: | Provisioning via [X.509 root certificate](https://docs.microsoft.com/en-us/azure/iot-dps/concepts-security#root-certificate). Please review the [samples](./azure-iot-device/samples/async-hub-scenarios/provision_x509_and_send_telemetry.py) folder and this [quickstart](https://docs.microsoft.com/en-us/azure/iot-dps/quick-create-simulated-device-x509-python) on how to create a device client. |
| X.509 Enrollment Group | :heavy_check_mark: | Provisioning via [X.509 leaf certificate](https://docs.microsoft.com/en-us/azure/iot-dps/concepts-security#leaf-certificate)). Please review the [samples](./azure-iot-device/samples/async-hub-scenarios/provision_x509_and_send_telemetry.py) folder on how to create a device client. |
| Symmetric Key Enrollment | :heavy_check_mark: | Provisioning via [Symmetric key attestation](https://docs.microsoft.com/en-us/azure/iot-dps/concepts-symmetric-key-attestation)). Please review the [samples](./azure-iot-device/samples/async-hub-scenarios/provision_symmetric_key_and_send_telemetry.py) folder on how to create a device client. |
| X.509 Individual Enrollment | :heavy_check_mark: | Provisioning via [X.509 root certificate](https://docs.microsoft.com/en-us/azure/iot-dps/concepts-security#root-certificate). Please review the [samples](azure-iot-device/samples/async-hub-scenarios/provision_x509.py) folder and this [quickstart](https://docs.microsoft.com/en-us/azure/iot-dps/quick-create-simulated-device-x509-python) on how to create a device client. |
| X.509 Enrollment Group | :heavy_check_mark: | Provisioning via [X.509 leaf certificate](https://docs.microsoft.com/en-us/azure/iot-dps/concepts-security#leaf-certificate)). Please review the [samples](azure-iot-device/samples/async-hub-scenarios/provision_x509.py) folder on how to create a device client. |
| Symmetric Key Enrollment | :heavy_check_mark: | Provisioning via [Symmetric key attestation](https://docs.microsoft.com/en-us/azure/iot-dps/concepts-symmetric-key-attestation)). Please review the [samples](azure-iot-device/samples/async-hub-scenarios/provision_symmetric_key.py) folder on how to create a device client. |

### IoTHub Service Library ([azure-iot-hub](https://github.com/Azure/azure-iot-sdk-python/blob/master/azure-iot-hub/azure/iot/hub/iothub_registry_manager.py))

Expand Down
18 changes: 9 additions & 9 deletions azure-iot-device/samples/async-hub-scenarios/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,27 +57,27 @@ In order to use these samples, you **must** set your Device Connection String in

### DPS Samples

#### Individual
#### Individual Enrollment

In order to use these samples, you **must** have the following environment variables :-

* PROVISIONING_HOST
* PROVISIONING_IDSCOPE
* PROVISIONING_REGISTRATION_ID

There are 2 ways that your device can get registered to the provisioning service differing in authentication mechanisms and another additional environment variable is needed to for the samples:-
There are 2 ways that your device can get registered to the provisioning service differing in authentication mechanisms. Depending on the mechanism used additional environment variables are needed for the samples:-

* [provision_symmetric_key.py](provision_symmetric_key.py) - Provision a device to IoTHub by registering to the Device Provisioning Service using a symmetric key. For this you must have the environment variable PROVISIONING_SYMMETRIC_KEY.
* [provision_symmetric_key_and_send_telemetry.py](provision_symmetric_key_and_send_telemetry.py) - Provision a device to IoTHub by registering to the Device Provisioning Service using a symmetric key, then send a telemetry message to IoTHub. For this you must have the environment variable PROVISIONING_SYMMETRIC_KEY.
* [provision_symmetric_key_with_payload.py](provision_symmetric_key_with_payload.py) - Provision a device to IoTHub by registering to the Device Provisioning Service using a symmetric key while supplying a custom payload. For this you must have the environment variable PROVISIONING_SYMMETRIC_KEY.
* [provision_x509.py](provision_x509.py) - Provision a device to IoTHub by registering to the Device Provisioning Service using a symmetric key. For this you must have the environment variable X509_CERT_FILE, X509_KEY_FILE, PASS_PHRASE.
* [provision_x509_and_send_telemetry.py](provision_x509_and_send_telemetry.py) - Provision a device to IoTHub by registering to the Device Provisioning Service using a symmetric key, then send a telemetry message to IoTHub. For this you must have the environment variable X509_CERT_FILE, X509_KEY_FILE, PASS_PHRASE.
* [provision_symmetric_key.py](provision_symmetric_key.py) - Provision a device to IoTHub by registering to the Device Provisioning Service using a symmetric key, then send telemetry messages to IoTHub. For this you must have the environment variable PROVISIONING_SYMMETRIC_KEY.
* [provision_symmetric_key_with_payload.py](provision_symmetric_key_with_payload.py) - Provision a device to IoTHub by registering to the Device Provisioning Service using a symmetric key while supplying a custom payload, then send telemetry messages to IoTHub. For this you must have the environment variable PROVISIONING_SYMMETRIC_KEY.
* [provision_x509.py](provision_x509.py) - Provision a device to IoTHub by registering to the Device Provisioning Service using a symmetric key, then send a telemetry message to IoTHub. For this you must have the environment variable X509_CERT_FILE, X509_KEY_FILE, PASS_PHRASE.

#### Group

#### Group Enrollment

In order to use these samples, you **must** have the following environment variables :-

* PROVISIONING_HOST
* PROVISIONING_IDSCOPE

* [provision_symmetric_key_group.py](provision_symmetric_key_group.py) - Provision multiple devices to IoTHub by registering them to the Device Provisioning Service using derived symmetric keys. For this you must have the environment variables PROVISIONING_MASTER_SYMMETRIC_KEY, PROVISIONING_DEVICE_ID_1, PROVISIONING_DEVICE_ID_2, PROVISIONING_DEVICE_ID_3.
* [provision_symmetric_key_group.py](provision_symmetric_key_group.py) - Provision multiple devices to IoTHub by registering them to the Device Provisioning Service using derived symmetric keys, then send telemetry to IoTHub from these devices. For this you must have knowledge of the group symmetric key and must have the environment variables PROVISIONING_DEVICE_ID_1, PROVISIONING_DEVICE_ID_2, PROVISIONING_DEVICE_ID_3.
* NOTE : Group symmetric key must NEVER be stored and all the device keys must be computationally derived prior to using this sample.
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,15 @@
# license information.
# --------------------------------------------------------------------------

import os
import asyncio
from azure.iot.device.aio import ProvisioningDeviceClient
import os
from azure.iot.device.aio import IoTHubDeviceClient
from azure.iot.device import Message
import uuid


messages_to_send = 10
provisioning_host = os.getenv("PROVISIONING_HOST")
id_scope = os.getenv("PROVISIONING_IDSCOPE")
registration_id = os.getenv("PROVISIONING_REGISTRATION_ID")
Expand All @@ -27,6 +32,31 @@ async def main():
print("The complete registration result is")
print(registration_result.registration_state)

if registration_result.status == "assigned":
print("Will send telemetry from the provisioned device")
device_client = IoTHubDeviceClient.create_from_symmetric_key(
symmetric_key=symmetric_key,
hostname=registration_result.registration_state.assigned_hub,
device_id=registration_result.registration_state.device_id,
)
# Connect the client.
await device_client.connect()

async def send_test_message(i):
print("sending message #" + str(i))
msg = Message("test wind speed " + str(i))
msg.message_id = uuid.uuid4()
await device_client.send_message(msg)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You don't need to set properties here (and other places), we want to make it as concise as possible

print("done sending message #" + str(i))

# send `messages_to_send` messages in parallel
await asyncio.gather(*[send_test_message(i) for i in range(1, messages_to_send + 1)])

# finally, disconnect
await device_client.disconnect()
else:
print("Can not send telemetry from the provisioned device")


if __name__ == "__main__":
asyncio.run(main())
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@
import hmac
import hashlib
from azure.iot.device.aio import ProvisioningDeviceClient
from azure.iot.device.aio import IoTHubDeviceClient
from azure.iot.device import Message
import uuid

messages_to_send = 5

provisioning_host = os.getenv("PROVISIONING_HOST")
id_scope = os.getenv("PROVISIONING_IDSCOPE")
Expand Down Expand Up @@ -47,18 +52,23 @@ def derive_device_key(device_id, group_symmetric_key):

# derived_device_key has been computed already using the helper function somewhere else
# AND NOT on this sample. Do not use the direct master key on this sample to compute device key.


derived_device_key_1 = "some_value_already_computed"
derived_device_key_2 = "some_value_already_computed"
derived_device_key_3 = "some_value_already_computed"


device_ids_to_keys[device_id_1] = derived_device_key_1
device_ids_to_keys[device_id_2] = derived_device_key_2
device_ids_to_keys[device_id_3] = derived_device_key_3


async def send_test_message(i, client):
print("sending message # {index} for client with id {id}".format(index=i, id=client.id))
msg = Message("test wind speed " + str(i))
msg.message_id = uuid.uuid4()
await client.send_message(msg)
print("done sending message # {index} for client with id {id}".format(index=i, id=client.id))


async def main():
async def register_device(registration_id):
provisioning_device_client = ProvisioningDeviceClient.create_from_symmetric_key(
Expand All @@ -73,11 +83,51 @@ async def register_device(registration_id):
results = await asyncio.gather(
register_device(device_id_1), register_device(device_id_2), register_device(device_id_3)
)
for index in range(0, len(device_ids_to_keys)):

clients_to_device_ids = {}

for index in range(0, len(results)):
registration_result = results[index]
print("The complete state of registration result is")
print(registration_result.registration_state)

if registration_result.status == "assigned":
device_id = registration_result.registration_state.device_id

print(
"Will send telemetry from the provisioned device with id {id}".format(id=device_id)
)
device_client = IoTHubDeviceClient.create_from_symmetric_key(
symmetric_key=device_ids_to_keys[device_id],
hostname=registration_result.registration_state.assigned_hub,
device_id=registration_result.registration_state.device_id,
)
# Assign the Id just for print statements
device_client.id = device_id

clients_to_device_ids[device_id] = device_client

else:
print("Can not send telemetry from the provisioned device")

# connect all the clients
await asyncio.gather(*[client.connect() for client in clients_to_device_ids.values()])

# send `messages_to_send` messages in parallel.
await asyncio.gather(
*[
send_test_message(i, client)
for i, client in [
(i, client)
for i in range(1, messages_to_send + 1)
for client in clients_to_device_ids.values()
]
]
)

# disconnect all the clients
await asyncio.gather(*[client.disconnect() for client in clients_to_device_ids.values()])


if __name__ == "__main__":
asyncio.run(main())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,17 @@
import os
import asyncio
from azure.iot.device.aio import ProvisioningDeviceClient
from azure.iot.device.aio import IoTHubDeviceClient
from azure.iot.device import Message
import uuid

provisioning_host = os.getenv("PROVISIONING_HOST")
id_scope = os.getenv("PROVISIONING_IDSCOPE")
registration_id = os.getenv("PROVISIONING_REGISTRATION_ID_PAYLOAD")
symmetric_key = os.getenv("PROVISIONING_SYMMETRIC_KEY_PAYLOAD")

messages_to_send = 10


class Wizard(object):
def __init__(self, first_name, last_name, dict_of_stuff):
Expand All @@ -37,6 +42,31 @@ async def main():
print("The complete registration result is")
print(registration_result.registration_state)

if registration_result.status == "assigned":
print("Will send telemetry from the provisioned device")
device_client = IoTHubDeviceClient.create_from_symmetric_key(
symmetric_key=symmetric_key,
hostname=registration_result.registration_state.assigned_hub,
device_id=registration_result.registration_state.device_id,
)
# Connect the client.
await device_client.connect()

async def send_test_message(i):
print("sending message #" + str(i))
msg = Message("test wind speed " + str(i))
msg.message_id = uuid.uuid4()
await device_client.send_message(msg)
print("done sending message #" + str(i))

# send `messages_to_send` messages in parallel
await asyncio.gather(*[send_test_message(i) for i in range(1, messages_to_send + 1)])

# finally, disconnect
await device_client.disconnect()
else:
print("Can not send telemetry from the provisioned device")


if __name__ == "__main__":
asyncio.run(main())
Expand Down
32 changes: 32 additions & 0 deletions azure-iot-device/samples/async-hub-scenarios/provision_x509.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,15 @@
import asyncio
from azure.iot.device import X509
from azure.iot.device.aio import ProvisioningDeviceClient
from azure.iot.device.aio import IoTHubDeviceClient
from azure.iot.device import Message
import uuid


provisioning_host = os.getenv("PROVISIONING_HOST")
id_scope = os.getenv("PROVISIONING_IDSCOPE")
registration_id = os.getenv("DPS_X509_REGISTRATION_ID")
messages_to_send = 10


async def main():
Expand All @@ -19,6 +24,7 @@ async def main():
key_file=os.getenv("X509_KEY_FILE"),
pass_phrase=os.getenv("PASS_PHRASE"),
)

provisioning_device_client = ProvisioningDeviceClient.create_from_x509_certificate(
provisioning_host=provisioning_host,
registration_id=registration_id,
Expand All @@ -31,6 +37,32 @@ async def main():
print("The complete registration result is")
print(registration_result.registration_state)

if registration_result.status == "assigned":
print("Will send telemetry from the provisioned device")
device_client = IoTHubDeviceClient.create_from_x509_certificate(
x509=x509,
hostname=registration_result.registration_state.assigned_hub,
device_id=registration_result.registration_state.device_id,
)

# Connect the client.
await device_client.connect()

async def send_test_message(i):
print("sending message #" + str(i))
msg = Message("test wind speed " + str(i))
msg.message_id = uuid.uuid4()
await device_client.send_message(msg)
print("done sending message #" + str(i))

# send `messages_to_send` messages in parallel
await asyncio.gather(*[send_test_message(i) for i in range(1, messages_to_send + 1)])

# finally, disconnect
await device_client.disconnect()
else:
print("Can not send telemetry from the provisioned device")


if __name__ == "__main__":
asyncio.run(main())
Expand Down
Loading