Azure / azure-iot-middleware-freertos

Azure IoT Middleware for FreeRTOS
https://azure.github.io/azure-iot-middleware-freertos/
MIT License
82 stars 24 forks source link

DPS and multiple Devices #230

Closed aardrasystems closed 2 years ago

aardrasystems commented 2 years ago

Hi

I have been advised by the Azure Support team to ask questions about the azure-IoT-middleware-freertos directly on here.

I aim to use this SDK with ESP32.

How can I set it up with DPS so that I have one global bin firmware, that automatically downloads each device's key within in the device itself? I aim to have about 3K devices.

Each device will know its own ID(mac or serial), I could write a small AzureFunction API that each device call for it key, and then could use that key to connect to the iot hub. This would mean, DPS would not be needed.

danewalton commented 2 years ago

Hi @aardrasystems From a security perspective, it doesn't seem that the devices would have a way to authenticate with the AzureFunction that they are who they say they are, since the only thing they have is some ID that anyone could spoof.

That being said, there is technically nothing preventing you from creating an HTTP endpoint and sending the ID in a query with the key as a response. However, that would NOT be recommended as it is very insecure.

Do any of your devices have a hardware secure element?

aardrasystems commented 2 years ago

Hi Dane

Thanks for your reply.

Can you specify what you mean by hardware secure element? We are going to be using the ESP32,

The issue arises, as we are going to deploy 3K sensors. When we compile the project, we are generating a bin file, which we want to keep global, so that our updates are much simpler to manage. Therefore if we were to program a key into each device, then when we perform firmware updates, these could be overwritten.

Is there a specific method we could use to overcome this issue?

I can check with ESP32 team, if when we are programming the devices for the first time if we can also download a key, which could be stored in a location that can never be overwritten during firmware updates . Then we could change the SDK to read the key from that location instead of hardcoded string.

danewalton commented 2 years ago

A hardware secure element is a secure way to persist storage of hardware keys (among other features like offloaded crypto operations). Similar to what you're talking about where the keys would stay stored even if you flash a new image. The newer ESP32SE chips have an ATEC608A which has that capability.

Fundamentally, you have the right idea that the keys shouldn't be stored in the image itself. They should be stored in a way that they can be fetched during the boot up process from somewhere other than the binary.

aardrasystems commented 2 years ago

Hi Dan

Have you managed or got an example of how the API can be called and saved onto ESP32? For example when we flash a ESP32 using UART, are there commands that can write to specific point in flash?

danewalton commented 2 years ago

I don't personally but I can share some docs here which might help guide you.

aardrasystems commented 2 years ago

Hi

I think what would be the best option is to develop two Firmware

Firmware A is the actual Middleware RTOS SDK, that looks at a particular location in flash memory for the Azure DPS registration ID.

Firmware B is installed on the device during production. This firmware calls an API, which would check a list of approved devices and then pass the registration ID for that Device. The device would then perform a firmware update, and download Firmware A.

Is it possible to create an Azure Function, that will generate registration ID for any device ID? Is there any example

aardrasystems commented 2 years ago

Hi @danewalton

Is there a reason why you can not do DPS group enrollment with this SDK?

danewalton commented 2 years ago

Are you talking about group enrollment where all devices have the same SAS key? We do support this scenario with group enrollment using x509 certs.

aardrasystems commented 2 years ago

Hi @danewalton

My preference would be no use to x509 so that maintenance on the device is reduced. That is the primary reason for using SAS.

What I was referring to is that each device has it own SAS, but in the DPS portal we can group similar device under the group instead of see every device under individual devices.

Can this be possible?

Am I correct un understanding that using this SDK with DPS all I need to do is specify the following only?

Enable Device Provisioning Sample Azure Device Provisioning Service ID Scope Azure Device Provisioning Service Registration ID

Do I need to specify the following as well?

Azure IoT Device ID Azure IoT Device Symmetric Key

Which normally used when DPS is not used?

danewalton commented 2 years ago

If you want to use symmetric keys, you have to specify the symmetric key as well. That can be derived from the group enrollment key which was allocated to your enrollment group. Device ID is not needed.

Devices in a symmetric key enrollment group present SAS tokens derived from the group symmetric key.

https://docs.microsoft.com/en-us/azure/iot-dps/concepts-service#enrollment-group

aardrasystems commented 2 years ago

Hi @danewalton Thanks for your reply.

Can you send examples of generating the "Azure Device Provisioning Service Registration ID" and "Azure IoT Device Symmetric Key" using C#? Am I correct in saying that these will be different for each device I create in my network

danewalton commented 2 years ago

Yes each should be different for each device. You should be able to find some helpful code snippets here:

https://docs.microsoft.com/en-us/azure/iot-dps/concepts-symmetric-key-attestation?tabs=csharp#group-enrollments

aardrasystems commented 2 years ago

Hi @danewalton

Thanks

Is there a link where I can use C# to derive the Azure Device Provisioning Service Registration ID?

The Symmetric seems to be working well.

Both will require an input which is the device ID. What device id does ESP32 or the stack use? Is it simply the mac address or serial number?

At moment I am calling my device "testdevice", which worked when using the ESP32 as a single device, but with DPS I feel there could be a chance that its internally using mac address, and therefore I need to use that same device id for Symmetric keys.

The aim is to first generate all the keys manually using c# and then automate the process

These is the errors I am getting from the Esp32 device. Does it give any indication on what I could be doing wrong?

}<ESC>_[0m<CR><LF>
<ESC>_[0;32mI (4655) sample_azureiot: Waiting for time synchronization with SNTP server<ESC>_[0m<CR><LF>

31/05/2022 10:38:57.913 [RX] - W (6315) wifi:<ba-add>idx:1 (ifx:0, 0c:8e:29:a0:ec:2a), tid:0, ssn:2, winSize:64<CR><LF>
<ESC>_[0;32mI (6325) sample_azureiot: @@@@@Notification of a time synchronization event<ESC>_[0m<CR><LF>
<ESC>_[0;32mI (6675) AZ IOT: Creating a TLS connection to global.azure-devices-provisioning.net:8883.<CR>
<CR><LF>
<ESC>_[0m<CR><LF>

31/05/2022 10:38:59.963 [RX] - <ESC>_[0;32mI (8365) tls_freertos: (Network connection 0x3ffc9ba0) Connection to global.azure-devices-provisioning.net established.<ESC>_[0m<CR><LF>
<ESC>_[0;32mI (8365) AZ IOT: 0ne00516172%2fregistrations%2fPSWAqk%2FZ3CmRLf9fH7MV18Gml74c80X%2BE8g2zls8%2BNM%3D<CR><LF>
1653993539<ESC>_[0m<CR><LF>
<ESC>_[0;32mI (8435) MQTT: Packet received. ReceivedBytes=2.<ESC>_[0m<CR><LF>
<ESC>_[0;32mI (8435) MQTT: CONNACK session present bit not set.<ESC>_[0m<CR><LF>
<ESC>_[0;31mE (8435) MQTT: Connection refused: not authorized.<ESC>_[0m<CR><LF>
<ESC>_[0;31mE (8435) MQTT: CONNACK recv failed with status = MQTTServerRefused.<ESC>_[0m<CR><LF>
<ESC>_[0;31mE (8445) MQTT: MQTT connection failed with status = MQTTServerRefused.<ESC>_[0m<CR><LF>
<ESC>_[0;31mE (8455) AZ IOT: AzureIoTProvisioning failed to establish MQTT connection: Server=global.azure-devices-provisioning.net, MQTT error=0x00000006<ESC>_[0m<CR><LF>
<ESC>_[0;32mI (8475) AZ IOT: Error geting IoT Hub name and Device ID: 0x0000000b<ESC>_[0m<CR><LF>
<CR><LF>
assert failed: prvIoTHubInfoGet sample_azure_iot_pnp.c:582 (xResult == eAzureIoTSuccess)<CR><LF>
<CR><LF>
<CR><LF>
Backtrace:0x40081a7e:0x3ffc9a200x400884d1:0x3ffc9a40 0x4008f5f9:0x3ffc9a60 0x400d8952:0x3ffc9b80 0x400d8a23:0x3ffc9be0 0x4008bbcd:0x3ffc9c90 <CR><LF>
<CR><LF>
<CR><LF>
<CR><LF>
<CR><LF>
ELF file SHA256: 922579b1a721d35a<CR><LF>
<CR><LF>
Rebooting...<CR><LF>
danewalton commented 2 years ago

You have to configure the Registration ID yourself. In our ESP32 samples, that can be found here:

image

In the source code, that is then done here: https://github.com/Azure-Samples/iot-middleware-freertos-samples/blob/154ba9fbd280b855c6e49e6e9c9ee34c35705c0f/demos/sample_azure_iot/sample_azure_iot.c#L506-L515

We don't have C# code to derive a registration ID for your devices. If you want to use a MAC address, you can try something like this

Otherwise, you can do something like getting a GUID from C# and using that as your registration ID.

aardrasystems commented 2 years ago

Hi @danewalton

Thanks for clarifying that. For this test, my device will be called the "test device", once I see it working I can introduce a scheme to use the MAC address. I am having the same issue as previously where the device does not connect but keeps rebooting.

Let me show all the steps I have taken.

These are my settings as shown. has my actual IoT hub name.

screenshot_esp32

The symmetrtic key is derived using the following C# function

     public static string ComputeDerivedSymmetricKey(byte[] masterKey, string registrationId)
        {
            using (var hmac = new HMACSHA256(masterKey))
            {
                return Convert.ToBase64String(hmac.ComputeHash(Encoding.UTF8.GetBytes(registrationId)));
            }
        }

registrationId Is set to "testdevice" in this case.

masterKey is the primary key from the group enrolment image

Below is the output I am getting from the ESP32 device, it keeps rebooting. It seems that its having issues getting IoT Hub name and Device ID.

Have I missed a step in my configuration or doing something wrong?

st:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)<CR><LF>
configsip: 0, SPIWP:0xee<CR><LF>
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00<CR><LF>
mode:DIO, clock div:2<CR><LF>
load:0x3fff0030,len:6616<CR><LF>
load:0x40078000,len:14780<CR><LF>
ho 0 tail 12 room 4<CR><LF>
load:0x40080400,len:3792<CR><LF>
entry 0x40080694<CR><LF>
<ESC>_[0;32mI (28) boot: ESP-IDF v4.4-rc1-dirty 2nd stage bootloader<ESC>_[0m<CR><LF>
<ESC>_[0;32mI (28) boot: compile time 21:33:58<ESC>_[0m<CR><LF>
<ESC>_[0;32mI (29) boot: chip revision: 1<ESC>_[0m<CR><LF>
<ESC>_[0;32mI (32) boot_comm: chip revision: 1, min. bootloader chip revision: 0<ESC>_[0m<CR><LF>
<ESC>_[0;32mI (39) boot.esp32: SPI Speed      : 40MHz<ESC>_[0m<CR><LF>
<ESC>_[0;32mI (44) boot.esp32: SPI Mode       : DIO<ESC>_[0m<CR><LF>
<ESC>_[0;32mI (48) boot.esp32: SPI Flash Size : 4MB<ESC>_[0m<CR><LF>
<ESC>_[0;32mI (53) boot: Enabling RNG early entropy source...<ESC>_[0m<CR><LF>
<ESC>_[0;32mI (58) boot: Partition Table:<ESC>_[0m<CR><LF>
<ESC>_[0;32mI (62) boot: ## Label            Usage          Type ST Offset   Length<ESC>_[0m<CR><LF>
<ESC>_[0;32mI (69) boot:  0 nvs              WiFi data        01 02 00009000 00004000<ESC>_[0m<CR><LF>
<ESC>_[0;32mI (76) boot:  1 otadata          OTA data         01 00 0000d000 00002000<ESC>_[0m<CR><LF>
<ESC>_[0;32mI (84) boot:  2 phy_init         RF data          01 01 0000f000 00001000<ESC>_[0m<CR><LF>
<ESC>_[0;32mI (91) boot:  3 factory          factory app      00 00 00010000 00100000<ESC>_[0m<CR><LF>
<ESC>_[0;32mI (99) boot:  4 ota_0            OTA app          00 10 00110000 00100000<ESC>_[0m<CR><LF>
<ESC>_[0;32mI (106) boot:  5 ota_1            OTA app          00 11 00210000 00100000<ESC>_[0m<CR><LF>
<ESC>_[0;32mI (114) boot: End of partition table<ESC>_[0m<CR><LF>
<ESC>_[0;32mI (118) boot: Defaulting to factory image<ESC>_[0m<CR><LF>
<ESC>_[0;32mI (123) boot_comm: chip revision: 1, min. application chip revision: 0<ESC>_[0m<CR><LF>
<ESC>_[0;32mI (130) esp_image: segment 0: paddr=00010020 vaddr=3f400020 size=23c8ch (146572) map<ESC>_[0m<CR><LF>
<ESC>_[0;32mI (192) esp_image: segment 1: paddr=00033cb4 vaddr=3ffb0000 size=03894h ( 14484) load<ESC>_[0m<CR><LF>
<ESC>_[0;32mI (198) esp_image: segment 2: paddr=00037550 vaddr=40080000 size=08ac8h ( 35528) load<ESC>_[0m<CR><LF>
<ESC>_[0;32mI (212) esp_image: segment 3: paddr=00040020 vaddr=400d0020 size=a17bch (661436) map<ESC>_[0m<CR><LF>
<ESC>_[0;32mI (452) esp_image: segment 4: paddr=000e17e4 vaddr=40088ac8 size=0bf30h ( 48944) load<ESC>_[0m<CR><LF>
<ESC>_[0;32mI (472) esp_image: segment 5: paddr=000ed71c vaddr=50000000 size=00010h (    16) load<ESC>_[0m<CR><LF>
<ESC>_[0;32mI (483) boot: Loaded app from partition at offset 0x10000<ESC>_[0m<CR><LF>
<ESC>_[0;32mI (483) boot: Disabling RNG early entropy source...<ESC>_[0m<CR><LF>
<ESC>_[0;32mI (495) cpu_start: Pro cpu up.<ESC>_[0m<CR><LF>
<ESC>_[0;32mI (495) cpu_start: Starting app cpu, entry point is 0x400811e8<ESC>_[0m<CR><LF>
<ESC>_[0;32mI (0) cpu_start: App cpu up.<ESC>_[0m<CR><LF>
<ESC>_[0;32mI (511) cpu_start: Pro cpu start user code<ESC>_[0m<CR><LF>
<ESC>_[0;32mI (511) cpu_start: cpu freq: 160000000<ESC>_[0m<CR><LF>
<ESC>_[0;32mI (511) cpu_start: Application information:<ESC>_[0m<CR><LF>
<ESC>_[0;32mI (516) cpu_start: Project name:     azure_iot_freertos_esp32<ESC>_[0m<CR><LF>
<ESC>_[0;32mI (522) cpu_start: App version:      3e01d9e-dirty<ESC>_[0m<CR><LF>
<ESC>_[0;32mI (528) cpu_start: Compile time:     Jun  1 2022 12:53:03<ESC>_[0m<CR><LF>
<ESC>_[0;32mI (534) cpu_start: ELF file SHA256:  175f85b2c2df2ad8...<ESC>_[0m<CR><LF>
<ESC>_[0;32mI (540) cpu_start: ESP-IDF:          v4.4-rc1-dirty<ESC>_[0m<CR><LF>
<ESC>_[0;32mI (546) heap_init: Initializing. RAM available for dynamic allocation:<ESC>_[0m<CR><LF>
<ESC>_[0;32mI (553) heap_init: At 3FFAE6E0 len 00001920 (6 KiB): DRAM<ESC>_[0m<CR><LF>
<ESC>_[0;32mI (559) heap_init: At 3FFB9758 len 000268A8 (154 KiB): DRAM<ESC>_[0m<CR><LF>
<ESC>_[0;32mI (565) heap_init: At 3FFE0440 len 00003AE0 (14 KiB): D/IRAM<ESC>_[0m<CR><LF>
<ESC>_[0;32mI (571) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM<ESC>_[0m<CR><LF>
<ESC>_[0;32mI (578) heap_init: At 400949F8 len 0000B608 (45 KiB): IRAM<ESC>_[0m<CR><LF>
<ESC>_[0;32mI (585) spi_flash: detected chip: generic<ESC>_[0m<CR><LF>
<ESC>_[0;32mI (589) spi_flash: flash io: dio<ESC>_[0m<CR><LF>
<ESC>_[0;32mI (594) cpu_start: Starting scheduler on PRO CPU.<ESC>_[0m<CR><LF>
<ESC>_[0;32mI (0) cpu_start: Starting scheduler on APP CPU.<ESC>_[0m<CR><LF>
I (734) wifi:wifi driver task: 3ffaf6c8, prio:23, stack:6656, core=0<CR><LF>
<ESC>_[0;32mI (734) system_api: Base MAC address is not set<ESC>_[0m<CR><LF>
<ESC>_[0;32mI (734) system_api: read default base MAC address from EFUSE<ESC>_[0m<CR><LF>
I (744) wifi:wifi firmware version: 7679c42<CR><LF>
I (744) wifi:wifi certification version: v7.0<CR><LF>
I (744) wifi:config NVS flash: enabled<CR><LF>
I (744) wifi:config nano formating: disabled<CR><LF>
I (754) wifi:Init data frame dynamic rx buffer num: 32<CR><LF>
I (754) wifi:Init management frame dynamic rx buffer num: 32<CR><LF>
I (764) wifi:Init management short buffer num: 32<CR><LF>
I (764) wifi:Init dynamic tx buffer num: 32<CR><LF>
I (774) wifi:Init static rx buffer size: 1600<CR><LF>
I (774) wifi:Init static rx buffer num: 10<CR><LF>
I (774) wifi:Init dynamic rx buffer num: 32<CR><LF>
<ESC>_[0;32mI (784) wifi_init: rx ba win: 6<ESC>_[0m<CR><LF>
<ESC>_[0;32mI (784) wifi_init: tcpip mbox: 32<ESC>_[0m<CR><LF>
<ESC>_[0;32mI (794) wifi_init: udp mbox: 6<ESC>_[0m<CR><LF>
<ESC>_[0;32mI (794) wifi_init: tcp mbox: 6<ESC>_[0m<CR><LF>
<ESC>_[0;32mI (794) wifi_init: tcp tx win: 5744<ESC>_[0m<CR><LF>
<ESC>_[0;32mI (804) wifi_init: tcp rx win: 5744<ESC>_[0m<CR><LF>
<ESC>_[0;32mI (804) wifi_init: tcp mss: 1440<ESC>_[0m<CR><LF>
<ESC>_[0;32mI (814) wifi_init: WiFi IRAM OP enabled<ESC>_[0m<CR><LF>
<ESC>_[0;32mI (814) wifi_init: WiFi RX IRAM OP enabled<ESC>_[0m<CR><LF>
<ESC>_[0;32mI (824) sample_azureiot: Connecting to Peepal...<ESC>_[0m<CR><LF>
<ESC>_[0;32mI (824) phy_init: phy_version 4670,719f9f6,Feb 18 2021,17:07:07<ESC>_[0m<CR><LF>
I (934) wifi:mode : sta (58:bf:25:93:09:08)<CR><LF>
I (934) wifi:enable tsf<CR><LF>
<ESC>_[0;32mI (944) sample_azureiot: Waiting for IP(s)<ESC>_[0m<CR><LF>

01/06/2022 12:56:33.772 [RX] - I (2984) wifi:new:<11,0>, old:<1,0>, ap:<255,255>, sta:<11,0>, prof:1<CR><LF>
I (3744) wifi:state: init -> auth (b0)<CR><LF>
I (3744) wifi:state: auth -> assoc (0)<CR><LF>
I (3754) wifi:state: assoc -> run (10)<CR><LF>
I (3774) wifi:connected with Peepal, aid = 4, channel 11, BW20, bssid = 0c:8e:29:a0:ec:2a<CR><LF>
I (3774) wifi:security: WPA2-PSK, phy: bgn, rssi: -45<CR><LF>
I (3774) wifi:pm start, type: 1<CR><LF>
<CR><LF>
W (3794) wifi:<ba-add>idx:0 (ifx:0, 0c:8e:29:a0:ec:2a), tid:6, ssn:0, winSize:64<CR><LF>
W (3794) wifi:<ba-add>idx:1 (ifx:0, 0c:8e:29:a0:ec:2a), tid:0, ssn:2, winSize:64<CR><LF>
I (3804) wifi:AP's beacon interval = 102400 us, DTIM period = 3<CR><LF>

01/06/2022 12:56:35.406 [RX] - <ESC>_[0;32mI (4624) esp_netif_handlers: sample_azureiot: sta ip: 192.168.1.88, mask: 255.255.255.0, gw: 192.168.1.254<ESC>_[0m<CR><LF>
<ESC>_[0;32mI (4624) sample_azureiot: Got IPv4 event: Interface "sample_azureiot: sta" address: 192.168.1.88<ESC>_[0m<CR><LF>
<ESC>_[0;32mI (4634) sample_azureiot: Connected to sample_azureiot: sta<ESC>_[0m<CR><LF>
<ESC>_[0;32mI (4634) sample_azureiot: - IPv4 address: 192.168.1.88<ESC>_[0m<CR><LF>
<ESC>_[0;32mI (4644) sample_azureiot: my_json_string<CR><LF>
{<CR><LF>
<HT>    "A":<HT>    "testaccount",<CR><LF>
<HT>    "B":<HT>    "1",<CR><LF>
<HT>    "C":<HT>    "176.49.64.63",<CR><LF>
<HT>    "G":<HT>    "1.70",<CR><LF>
<HT>    "Irrigation":<HT>   true,<CR><LF>
<HT>    "Air":<HT>  false<CR><LF>
}<ESC>_[0m<CR><LF>
<ESC>_[0;32mI (4654) sample_azureiot: Waiting for time synchronization with SNTP server<ESC>_[0m<CR><LF>

01/06/2022 12:56:37.400 [RX] - <ESC>_[0;32mI (6614) sample_azureiot: @@@@@Notification of a time synchronization event<ESC>_[0m<CR><LF>
<ESC>_[0;32mI (6664) AZ IOT: Creating a TLS connection to global.azure-devices-provisioning.net:8883.<CR>
<CR><LF>
<ESC>_[0m<CR><LF>

01/06/2022 12:56:39.174 [RX] - <ESC>_[0;32mI (8394) tls_freertos: (Network connection 0x3ffca470) Connection to global.azure-devices-provisioning.net established.<ESC>_[0m<CR><LF>
<ESC>_[0;32mI (8394) AZ IOT: 0ne00516172%2fregistrations%2ftestdevice<CR><LF>
1654088198<ESC>_[0m<CR><LF>
<ESC>_[0;32mI (8444) MQTT: Packet received. ReceivedBytes=2.<ESC>_[0m<CR><LF>
<ESC>_[0;32mI (8444) MQTT: CONNACK session present bit not set.<ESC>_[0m<CR><LF>
<ESC>_[0;32mI (8444) MQTT: Connection accepted.<ESC>_[0m<CR><LF>
<ESC>_[0;32mI (8454) MQTT: Received MQTT CONNACK successfully from broker.<ESC>_[0m<CR><LF>
<ESC>_[0;32mI (8454) MQTT: MQTT connection established with the broker.<ESC>_[0m<CR><LF>
<ESC>_[0;32mI (8464) AZ IOT: AzureIoTProvisioning established an MQTT connection with global.azure-devices-provisioning.net<ESC>_[0m<CR><LF>

01/06/2022 12:56:41.263 [RX] - <ESC>_[0;32mI (10484) AZ IOT: AzureIoTProvisioning attempting to subscribe to the MQTT topic: devices/+/messages/devicebound/#<ESC>_[0m<CR><LF>
<ESC>_[0;32mI (10514) MQTT: Packet received. ReceivedBytes=3.<ESC>_[0m<CR><LF>

01/06/2022 12:56:43.634 [RX] - <ESC>_[0;32mI (12854) MQTT: Packet received. ReceivedBytes=179.<ESC>_[0m<CR><LF>
<ESC>_[0;32mI (12854) MQTT: De-serialized incoming PUBLISH packet: DeserializerResult=MQTTSuccess.<ESC>_[0m<CR><LF>
<ESC>_[0;32mI (12854) MQTT: State record updated. New state=MQTTPublishDone.<ESC>_[0m<CR><LF>

01/06/2022 12:56:45.653 [RX] - <ESC>_[0;32mI (14874) AZ IOT: $dps/registrations/res/401/?$rid=1<ESC>_[0m<CR><LF>
<ESC>_[0;32mI (14874) AZ IOT: {"errorCode":401000,"trackingId":"13e1e1cf-eda2-4093-be3a-ff854fc666e6","message":"Unauthorized","timestampUtc":"2022-06-01T11:56:42.8695743Z"}<ESC>_[0m<CR><LF>
<ESC>_[0;31mE (14884) AZ IOT: AzureIoTProvisioning client registration failed with error 401000: TrackingID: [13e1e1cf-eda2-4093-be3a-ff854fc666e6] "Unauthorized"<ESC>_[0m<CR><LF>
<ESC>_[0;32mI (14894) AZ IOT: Error geting IoT Hub name and Device ID: 0x0000000b<ESC>_[0m<CR><LF>
<CR><LF>
assert failed: prvIoTHubInfoGet sample_azure_iot_pnp.c:582 (xResult == eAzureIoTSuccess)<CR><LF>
<CR><LF>
<CR><LF>
Backtrace:0x40081a7e:0x3ffca2f00x400884d1:0x3ffca310 0x4008f5f9:0x3ffca330 0x400d8952:0x3ffca450 0x400d8a23:0x3ffca4b0 0x4008bbcd:0x3ffca560 <CR><LF>
<CR><LF>
<CR><LF>
<CR><LF>
<CR><LF>
ELF file SHA256: 175f85b2c2df2ad8<CR><LF>
<CR><LF>
danewalton commented 2 years ago

When computing the key, you used this snippet correct?

String deviceKey = Utils.ComputeDerivedSymmetricKey(Convert.FromBase64String(masterKey), registrationId);

I see "unauthorized" so somehow the credentials/connection info is not valid.

aardrasystems commented 2 years ago

Hi @danewalton

Sorry for the delay. using Convert.FromBase64String(masterKey), seems to have got it working now.

How can I change the frequency of the expiring of the SAS token >

Is it possible to disable the server root certificate? I believe this was previously Baltimore which is now G2? Is this required if my device is only connecting to my known IoT hub? The reason why I ask this is that we have some devices, which is very low maintenance and when the recent root certificates changed from Balitmore to G2, this caused a lot of issues for those devices. We would like to avoid this issue, even if the root certs are likely to change in the future.

danewalton commented 2 years ago

How can I change the frequency of the expiring of the SAS token >

The expiration time of the SAS token can be changed by modifying this config value: https://github.com/Azure/azure-iot-middleware-freertos/blob/ccfda9716f39a70c6772b6fa22f8bf7fecacee90/source/include/azure_iot_config_defaults.h#L12

As for the root cert, while possible, we cannot recommend to anyone to ignore the server root certificate in the TLS handshake for the security implications that poses. The recommended way to do that might be to have some over the air update procedure to update the certificate. We should have an OTA offering on the near horizon for this repository which would help with that scenario.

aardrasystems commented 2 years ago

Hi @danewalton

Thanks

That will be good to have OTA option to update the root cert.

I need to also add a BLE provisioning option so that I can change the SSID and password via my app.

Am I correct in understanding, at moment the wifi connection at moment is set in example_connect(void)?

danewalton commented 2 years ago

The wifi connection is initialized and started in the static esp_netif_t *wifi_start(void) section of our ESP32 sample.

aardrasystems commented 2 years ago

Hi @danewalton

I got the wifi working, as I can now set up the ssid and password using BLE and not hard code it.

Throughout the day, I get Connection and Disconnection Alerts "Microsoft.Devices.DeviceDisconnected" from the IoT Hub.

If I am correct disconnection alerts are caused by the SAS token getting refreshed, therefore I have increased my MQTT Keep-Alive to about 5 mins azureiotconfigKEEP_ALIVE_TIMEOUT_SECONDS ( 300U )

But does not seems to improve it. Does this seem correct?

My device is sending a message to the IoT Hub at moment every 3 min, but this could be extended to 1 hour. How can i avoid all these false disconnection alerts?

This is my main process for your reference.

    /* Publish messages with QoS1, send and process Keep alive messages. */
    for( ; ; )
    {
        /* Hook for sending Telemetry */
     if ((message_tx_cycle_delay >= message_tx_cycle_delay_count) || (message_force_tx()==true))
        {

            rst_message_force_tx();

            message_tx_cycle_delay = 0;
            if( ( ulCreateTelemetry( ucScratchBuffer, sizeof( ucScratchBuffer ), &ulScratchBufferLength ) == 0 ) &&
                ( ulScratchBufferLength > 0 ) )
            {

                xResult = AzureIoTHubClient_SendTelemetry( &xAzureIoTHubClient,
                                                        ucScratchBuffer, ulScratchBufferLength,
                                                        NULL, eAzureIoTHubMessageQoS1, NULL );
                configASSERT( xResult == eAzureIoTSuccess );
            }

            /* Hook for sending update to reported properties */
            ulReportedPropertiesUpdateLength = ulCreateReportedPropertiesUpdate( ucReportedPropertiesUpdate, sizeof( ucReportedPropertiesUpdate ) );

            if( ulReportedPropertiesUpdateLength > 0 )
            {
                xResult = AzureIoTHubClient_SendPropertiesReported( &xAzureIoTHubClient, ucReportedPropertiesUpdate, ulReportedPropertiesUpdateLength, NULL );
                configASSERT( xResult == eAzureIoTSuccess );
            }
        }
        else
        {
            message_tx_cycle_delay++;
        }
      //  LogInfo( ( "Attempt to receive publish message from IoT Hub.\r\n" ) );
        xResult = AzureIoTHubClient_ProcessLoop( &xAzureIoTHubClient,
                                                 sampleazureiotPROCESS_LOOP_TIMEOUT_MS );
        configASSERT( xResult == eAzureIoTSuccess );

        /* Leave Connection Idle for some time. */
        //LogInfo( ( "Keeping Connection Idle...\r\n\r\n" ) );
        LogInfo(( "***")); 
        vTaskDelay( sampleazureiotDELAY_BETWEEN_PUBLISHES_TICKS );
        LogInfo(( "@@@")); 
    }`

`

danewalton commented 2 years ago

The keep alive will not affect the SAS token refreshing. You can modify how long it takes for the SAS token to expire, but as per the MQTT spec, the connection will have to be disconnected for the token refresh.

danewalton commented 2 years ago

@aardrasystems any updates here?

aardrasystems commented 2 years ago

@danewalton

Sorry for my reply. The issue I am having is that my IoT Hub and Azure Function are reporting a disconnection when the device is still connected. So I will create a scheme that will check the device timestamp after 5 mins before sending a disconneciton alert message.

danewalton commented 2 years ago

Seems like I can close this for now then. Please let us know if you need further help or open another issue if you have additional problems.

aardrasystems commented 2 years ago

Hi @danewalton

Thanks. I will create a new post for my addditonal questions.