README.md
1# Sample Guide
2
3This sample showcases the usability of AZRTOS API to connect to Azure IoT and start interacting with Azure IoT services like IoTHub and Device Provisioning Service. All the output of sample is redirect to stdout. To start the sample, the user needs to provide user configuration in sample_config.h. Following are the configuration example to setup the sample.
4
5## Prerequisites
6To run this sample, user should create an IoTHub instance in Azure ([Doc](https://docs.microsoft.com/en-us/azure/iot-hub/iot-hub-create-through-portal#create-an-iot-hub)). If sample is configured to use Device Provisioning service, use [doc](https://docs.microsoft.com/en-us/azure/iot-dps/quick-setup-auto-provision#create-a-new-iot-hub-device-provisioning-service) to create Device Provisioning instance in Azure and link it to the IoTHub ([Link](https://docs.microsoft.com/en-us/azure/iot-dps/quick-setup-auto-provision#link-the-iot-hub-and-your-device-provisioning-service)).
7
8## IoTHub connect using Symmetric key
9
10Sample connects to the device in the IoTHub using Symmetric key. To register new device in IoTHub use the [doc](https://docs.microsoft.com/en-us/azure/iot-hub/iot-hub-create-through-portal#register-a-new-device-in-the-iot-hub) to create device with Symmetric key authentication. After device's registration is complete, copy the connection string for the device with following format **HostName=<>;DeviceId=<>;SharedAccessKey=<>**. Add following macros to your compiler option.
11
12```
13#define HOST_NAME "<Hostname from connection string>"
14#define DEVICE_ID "<DeviceId from connection string>"
15#define DEVICE_SYMMETRIC_KEY "<SharedAccessKey from connection string>"
16```
17Above configuration by default enables all the features like: Telemetry, Cloud to device message and Direct Methods. To disable anyone, add following macro corresponding to the feature.
18
19```
20/* Defined, telemetry is disabled. */
21#define DISABLE_TELEMETRY_SAMPLE
22
23/* Defined, C2D is disabled. */
24#define DISABLE_C2D_SAMPLE
25
26/* Defined, Direct methods is disabled. */
27#define DISABLE_DIRECT_METHOD_SAMPLE
28
29```
30
31## IoTHub connect using X509 cert
32
33Sample connects to the device in the IoTHub using X509 cert. To generate self signed cert use the same steps mention in [IoTHub connect using X509 cert](#iothub-connect-using-x509-cert) section. Once certificate is generated, register new device in IoTHub with this cert using the x509 getting started [document](https://docs.microsoft.com/en-us/azure/iot-hub/iot-hub-security-x509-get-started). After device registration is complete, copy the connection string for the device with following format **HostName=<>;DeviceId=<>;x509=true**. Add following macros to your compiler option.
34
35```
36#define HOST_NAME "<Hostname from connection string>"
37#define DEVICE_ID "<DeviceId from connection string>"
38#define USE_DEVICE_CERTIFICATE 1
39#define DEVICE_KEY_TYPE NX_SECURE_X509_KEY_TYPE_RSA_PKCS1_DER /* NX_SECURE_X509_KEY_TYPE_RSA_PKCS1_DER for RSA, NX_SECURE_X509_KEY_TYPE_EC_DER for ECC */
40```
41
42### Steps to create self-signed certs using openssl:
43
44Set x509 configuration file for common name in cert.
45```
46cat > x509_config.cfg <<EOT
47[req]
48req_extensions = client_auth
49distinguished_name = req_distinguished_name
50
51[req_distinguished_name]
52
53[ client_auth ]
54basicConstraints = CA:FALSE
55keyUsage = digitalSignature, keyEncipherment
56extendedKeyUsage = clientAuth
57EOT
58```
59
60Create RSA self-signed certs
61```
62# Generate private key and certificate (public key).
63openssl genrsa -out privkey.pem 2048
64openssl req -new -days 365 -nodes -x509 -key privkey.pem -out cert.pem -config x509_config.cfg -subj "/CN=<Same as device Id>"
65
66# Convert format from key to der.
67openssl rsa -outform der -in privkey.pem -out privkey.der
68
69# Convert format from cert pem to der.
70openssl x509 -outform der -in cert.pem -out cert.der
71```
72
73Or create EC self-signed certs
74```
75# Generate private key and certificate (public key). Note: The comman name must be device id.
76openssl req -new -x509 -nodes -days 365 -newkey ec:<(openssl ecparam -name secp384r1) -keyout privkey.pem -out cert.pem -config x509_config.cfg -subj "/CN=<Same as device Id>"
77
78# Convert format from key to der.
79openssl ec -outform der -in privkey.pem -out privkey.der
80
81# Convert format from cert pem to der.
82openssl x509 -outform der -in cert.pem -out cert.der
83```
84
85Convert der to hex array (ubuntu) and set them in sample_device_identity.c.
86```
87echo "#include \"nx_api.h\"
88/**
89device cert (`openssl x509 -in cert.pem -fingerprint -noout | sed 's/://g' `) :
90`cat cert.pem`
91
92device private key :
93`cat privkey.pem`
94*/
95" > sample_device_identity.c
96
97xxd -i cert.der | sed -E "s/(unsigned char) (\w+)/\1 sample_device_cert_ptr/g; s/(unsigned int) (\w+)_len/\1 sample_device_cert_len/g" >> sample_device_identity.c
98xxd -i privkey.der | sed -E "s/(unsigned char) (\w+)/\1 sample_device_private_key_ptr/g; s/(unsigned int) (\w+)_len/\1 sample_device_private_key_len/g" >> sample_device_identity.c
99```
100
101
102## Use Device Provisioning Service with Symmetric key
103
104Sample uses Device Provisioning service to get IoTHub device details and then connects to assigned IoTHub device. To start, user creates individual enrollment using [doc](https://docs.microsoft.com/en-us/azure/iot-dps/quick-create-simulated-device-symm-key#create-a-device-enrollment-entry-in-the-portal) with Symmetric key. After completion, update following macros to your compiler option.
105
106Note: To get the values, use the [doc](https://docs.microsoft.com/en-us/azure/iot-dps/concepts-device) to understand the concepts of Device provisioning service.
107
108```
109#define ENDPOINT "<Service Endpoint or Global device endpoint from Provisioning service overview page>"
110#define ID_SCOPE "<ID Scope value from Provisioning service overview page>"
111#define REGISTRATION_ID "<RegistrationId provide when doing Individual registration>"
112#define DEVICE_SYMMETRIC_KEY "<Symmetric key from Individual registration detail page>"
113
114/* Enable DPS */
115#define ENABLE_DPS_SAMPLE
116```
117
118## Use Device Provisioning Service with X509
119
120Sample uses Device Provisioning service to get IoTHub details and then connects to assigned IoTHub device. To start, user creates individual enrollment using [doc](https://docs.microsoft.com/en-us/azure/iot-dps/quick-create-simulated-device-x509#create-a-device-enrollment-entry-in-the-portal) with X509 cert. After completion, update following macros to your compiler option.
121
122Note: To get the values, use the [doc](https://docs.microsoft.com/en-us/azure/iot-dps/concepts-device) to understand the concepts of Device provisioning service.
123
124```
125#define ENDPOINT "<Service Endpoint or Global device endpoint from Provisioning service overview page>"
126#define ID_SCOPE "<ID Scope value from Provisioning service overview page>"
127#define REGISTRATION_ID "<RegistrationId provide when doing Individual registration>"
128#define USE_DEVICE_CERTIFICATE 1
129#define DEVICE_KEY_TYPE NX_SECURE_X509_KEY_TYPE_RSA_PKCS1_DER /* Right now only RSA certs are supported*/
130
131/* Enable DPS */
132#define ENABLE_DPS_SAMPLE
133```
134To generate self signed cert use the same steps mention in [IoTHub connect using X509 cert](#iothub-connect-using-x509-cert) section.
135
136### [IoT Plug and Play (Certificates)][pnp_sample]
137Connect a IoT Plug and Play enabled device with the Digital Twin Model ID (DTMI) detailed [here](https://github.com/Azure/opendigitaltwins-dtdl/blob/master/DTDL/v2/samples/Thermostat.json).
138In short, the capabilities are listed here:
139- **Methods**: Invoke a IoT Plug and Play command called `getMaxMinReport` with JSON payload value `"since"` with an [ISO8601](https://en.wikipedia.org/wiki/ISO_8601) value for start time for the report. The method sends a response containing the following JSON payload:
140```json
141{
142 "maxTemp": 20,
143 "minTemp": 20,
144 "avgTemp": 20,
145 "startTime": "<ISO8601 time>",
146 "endTime": "<ISO8601 time>"
147}
148```
149with correct values substituted for each field.
150- **Telemetry**: Device sends a JSON message with the field name `temperature` and the `double` value of the temperature.
151- **Twin**: Desired property with the field name `targetTemperature` and the `double` value for the desired temperature. Reported property with the field name `maxTempSinceLastReboot` and the `double` value for the highest temperature.Note that part of the IoT Plug and Play spec is a response to a desired property update from the service. The device will send back a reported property with a similarly named property and a set of "ack" values: `ac` for the HTTP-like ack code, `av` for ack version of the property, and an optional `ad` for an ack description.