Azure / azure-iot-sdk-c

A C99 SDK for connecting devices to Microsoft Azure IoT services
https://azure.github.io/azure-iot-sdk-c
Other
589 stars 737 forks source link

MQTT connection settings for constrained devices without using Azure IoT SDKs #660

Closed richmondu closed 6 years ago

richmondu commented 6 years ago

I have a constrained embedded device so I don't want to use Azure's IoT SDKs. I need to connect to Azure IoT Hub using LWIP's MQTT library. I have it connected with Amazon IoT/Greengrass and Google IoT already. The Azure IoT SDK samples (Python, NodeJS) abstracts MQTT details such as username, password as well as the generated SAS token and CA. Nor do the APIs expose get functions to retrieve the actual values used and generated. It exposes "connection string" (for SAS authentication) which are NOT directly related to MQTT. There also seems no good documentation on this as well. Or probably scattered in different pages.

I understand that Azure IoT provides 3 authentication types. I actually can connect successfully to my Azure IoT Hub using the first 2 possibilities using Azure IoT Python and NodeJS SDK samples. So my Azure IoT Hub setup are correct. But I need to use LWIP's MQTT library not the Azure IoT SDKs. So I would like to know the required values for the MQTT connection and TLS certificates. For each of the 3 authentication types, can someone please verify or correct the values?

  1. Authentication using Symmetric key (SAS Token) MQTT clientid: device id MQTT username: myiothub.azure-devices.net/deviceid MQTT password: SAS TOKEN (generated with SharedAccessKey from connection string) TLS ca: BALTIMORE CA [chain of 4 certificates]? TLS cert: NULL TLS pkey: NULL CLOUD: copy the shared access key for SAS TOKEN generation DEVICE: send BALTIMORE CA for TLS connection? ( Most Python and NodeJS examples abstracts the BALTIMORE CA, It seems to retrieve the value from certificate store inside the library abstracting the user about it. But embedded devices do not have a certificate store so it must be explicitly loaded in the user code.) ( Saving the BALTIMORE CA, which is a certificate chain of 4 certificates requires 6KB of memory already. Amazon IoT provides a root CA without intermediate certificates.)

  2. Authentication with X.509 Self-Signed
    MQTT clientid: device id MQTT username: myiothub.azure-devices.net/deviceid MQTT password: NULL? (or hash of device cert?) TLS ca: NULL? (or BALTIMORE Root CA?) TLS cert: device certificate TLS pkey: device private key CLOUD: set the "Thumbprint" of device certificate (double click certificate->Details Tab->Thumbprint) DEVICE: send device certificate and private key for TLS connection? (need to send BALTIMORE Root CA as well?)

  3. Authentication with X.509 CA Signed MQTT clientid: device id MQTT username: myiothub.azure-devices.net/deviceid MQTT password: NULL TLS ca: ca TLS cert: NULL? TLS pkey: NULL? CLOUD: set CA and activate with verification code DEVICE: send CA only for TLS connection?

Hope someone could add complete documentation like this in the Azure web pages. This will help a lot for those using MQTT libraries instead of Azure IoT SDKs.

For reference, below are MQTT connection settings used to connect to Amazon IoT and Google IoT with some open-source MQTT library.

  1. Amazon IoT MQTT clientid: device id (or 'thing name' if set with a thing) MQTT username: NULL MQTT password: NULL TLS ca: CA TLS cert: device certificate TLS pkey: device private key CLOUD: set CA, certificate and private key (* Can use AWS certificate generation) DEVICE: send CA, certificate and private key for TLS connection

  2. Amazon Greengrass MQTT clientid: device id (or 'thing name' if set with a thing) MQTT username: NULL MQTT password: NULL TLS ca: Greengrass Group CA (dynamically queried, expires 7 days default configurable to 30 days max) TLS cert: device certificate TLS pkey: device private key CLOUD: set CA, certificate and private key (* Can use AWS certificate generation) DEVICE: send GG CA, certificate and private key for TLS connection

  3. Google IoT MQTT clientid: projects/PROJECT_ID/locations/LOCATION_ID/registries/REGISTRY_ID/devices/DEVICE_ID MQTT username: NULL MQTT password: JWT TOKEN (generated with device private key) TLS ca: NULL TLS cert: device certificate TLS pkey: device private key CLOUD: set device certificate DEVICE: no certificate or private key is sent during TLS connection

Any help will be appreciated. Thank you. @ewertons @zolvarga @jebrando

anhashia commented 6 years ago

@richmondu This is covered in detail under https://docs.microsoft.com/en-us/azure/iot-hub/iot-hub-mqtt-support#using-the-mqtt-protocol-directly

There are ways to authenticate the client (device) to IoT Hub 1.) SAS token (password) 2.) X.509 client certificate.

Both are mutually exclusive. You can choose either 1 or 2 The are 2 type of certs here

1.) Server side certificate for IoT Hub server authentication Root CA (public) for Global IoT Hub is located at https://github.com/Azure/azure-iot-sdk-c/blob/master/certs/ms.der for reference.

IoT Hub server will send wildcard -> Intermediate CA. Device needs to validate the chain and for that it would need Root CA only. So you will have to configure your TLS library to validate Root CA. You don't need chain on the device. Chain will be sent to you from IoT hub. You only need Root CA which has to be trusted.

2.) Client side certificate for device side authentication. This is relevant only if you are using X.509 authentication and not needed for SAS token. Here you need the certificate for which you have the private key. Password here will be none

Call will be something like this if using third party MQTT library like paho.

client.tls_set(ca_certs=”ms.crt”, certfile="new-device-full-chain.cert.pem", keyfile="new-device.key.pem", cert_reqs=ssl.CERT_REQUIRED, tls_version=ssl.PROTOCOL_TLSv1, ciphers=None)
client.username_pw_set(username=iot_hub_name+".azure-devices.net/" + device_id, password=None)
richmondu commented 6 years ago

Thank you for the response. However, I tried connecting to my Azure IoT Hub using MQTT.FX (https://mqttfx.jensd.de) using the provided details but still could not connect. (Note I can connect to IoT Hub using Azure IoT SDKs samples.)

Some clarifications:

  1. The link says Username should have "api-version=2016-11-14": {iothubhostname}/{device_id}/api-version=2016-11-14 Is this valid? Only applies to the Azure IoT SDKs?
  2. For X.509 client certificate authentication, a. "ms.crt" as CA is still needed? b. "new-device-full-chain.cert.pem", Do you mean this has to be CA+cert? For AWS, the certificate is signed by CA so its TLS(ca, cert, pkey). For Azure, its TLS(ms.crt, ca+cert, pkey)?
  3. "TLSv1". I should use TLSv1 only? cannot use TLSv1.2?

Below is the summary based on the details provided:
Authentication using Symmetric key (SAS Token)

  1. MQTT broker: myiothub.azure-devices.net
  2. MQTT port: 8883
  3. MQTT clientid: deviceid
  4. MQTT username: myiothub.azure-devices.net/deviceid
  5. MQTT password: SAS TOKEN (generated with SharedAccessKey of deviceid from connection string)
  6. TLS ca: https://github.com/Azure/azure-iot-sdk-c/blob/release_2018_06_08/certs/ms.der <- convert to 'ms.crt' using openssl
  7. TLS cert: NULL
  8. TLS pkey: NULL
  9. CLOUD: copy the shared access key of deviceid for SAS TOKEN generation
  10. DEVICE: set ms.der for TLS connection

Authentication with X.509 Self-Signed

  1. MQTT broker: myiothub.azure-devices.net
  2. MQTT port: 8883
  3. MQTT clientid: deviceid
  4. MQTT username: myiothub.azure-devices.net/deviceid
  5. MQTT password: NULL
  6. TLS ca: https://github.com/Azure/azure-iot-sdk-c/blob/release_2018_06_08/certs/ms.der <- convert to ms.crt using openssl
  7. TLS cert: device certificate
  8. TLS pkey: device private key
  9. CLOUD: set the "Thumbprint" of device certificate (double click certificate->Details Tab->Thumbprint)
  10. DEVICE: set ms.der, device certificate and private key for TLS connection
anhashia commented 6 years ago

@richmondu For SAS token based authentication Example

Broker address: myhub.azure-devices.net Port: 8883 Client id : device1 user name : myhub.azure-devices.net/device1/api-version=2016-11-14 // yes you need API version in user name. password : SAS Token derived from primary key of the device. https://docs.microsoft.com/en-us/azure/iot-hub/iot-hub-devguide-security#security-tokens

SSL/TLS : Protocol TLS 1.0 and above. Select TLS 1.2

Select CA signed server certificate if underlying TLS library can directly read from OS cert store. If not the you can specify CA certificate file and point it to ms.der.

For X.509 based authentication You still need to specify Root CA of server (ms.der). This is server side certificate . So these steps are same as SAS token authetication steps mentioned above,

Only difference here is that you need to specify client side certificate versus SAS token (password) for client (device) side authentication. For client certificate, you need to have private key. Thumbprint of this client side certificate should be registered with IoT hub.

Difference is only in step 4 of TLS handshake https://docs.microsoft.com/en-us/windows/desktop/secauthn/tls-handshake-protocol For SAS based authentication : Device will not send any client side certificate. It will authenticate via MQTT user name and password once TLS channel is established.

For X.509 based authentication. device will send client certificate along with its public key in step 4. IoT Hub will calculate its thumbprint and will match it with the registered thumbprint. If it matches the authentication will succeed otherwise it will fail.

richmondu commented 6 years ago

Thanks for the clarification, I verified that the settings for both authentication types are indeed working using MQTT.FX. Case closed. Thank you @anhashia !

Authentication using Symmetric key (SAS Token) MQTT broker: myiothub.azure-devices.net MQTT port: 8883 MQTT clientid: deviceid MQTT username: myiothub.azure-devices.net/deviceid/api-version=2016-11-14 MQTT password: SAS TOKEN (generated with SharedAccessKey of deviceid from connection string) TLS ca: https://github.com/Azure/azure-iot-sdk-c/blob/release_2018_06_08/certs/ms.der <- convert to 'ms.crt' using openssl TLS cert: NULL TLS pkey: NULL CLOUD: copy the shared access key of deviceid for SAS TOKEN generation DEVICE: set ms.der for TLS connection

Authentication with X.509 Self-Signed MQTT broker: myiothub.azure-devices.net MQTT port: 8883 MQTT clientid: deviceid MQTT username: myiothub.azure-devices.net/deviceid/api-version=2016-11-14 MQTT password: NULL TLS ca: https://github.com/Azure/azure-iot-sdk-c/blob/release_2018_06_08/certs/ms.der <- convert to ms.crt using openssl TLS cert: device certificate TLS pkey: device private key CLOUD: set the "Thumbprint" of device certificate (double click certificate->Details Tab->Thumbprint) DEVICE: set ms.der, device certificate and private key for TLS connection

richmondu commented 6 years ago

I have successfully connected our microcontroller to Azure IoT Hub.

Connecting to Azure IoT Hub requires the following minimum values for mbedTLS settings:

define MBEDTLS_SSL_MAX_CONTENT_LEN (3072+512) // Increase from 3072 to support Azure IoT

define MBEDTLS_MPI_MAX_SIZE 512 // Increased from 256 to support Azure IoT

This is due to the longer CA chain of certificates sent by Azure IoT to be validated by the device during the TLS handshake.

az-iot-builder-01 commented 6 years ago

@richmondu, thank you for your contribution to our open-sourced project! Please help us improve by filling out this 2-minute customer satisfaction survey

baluzealster commented 6 years ago

Thanks for the clarification, I verified that the settings for both authentication types are indeed working using MQTT.FX. Case closed. Thank you @anhashia !

Authentication using Symmetric key (SAS Token) MQTT broker: myiothub.azure-devices.net MQTT port: 8883 MQTT clientid: deviceid MQTT username: myiothub.azure-devices.net/deviceid/api-version=2016-11-14 MQTT password: SAS TOKEN (generated with SharedAccessKey of deviceid from connection string) TLS ca: https://github.com/Azure/azure-iot-sdk-c/blob/master/certs/ms.der <- convert to 'ms.crt' using openssl TLS cert: NULL TLS pkey: NULL CLOUD: copy the shared access key of deviceid for SAS TOKEN generation DEVICE: set ms.der for TLS connection

Authentication with X.509 Self-Signed MQTT broker: myiothub.azure-devices.net MQTT port: 8883 MQTT clientid: deviceid MQTT username: myiothub.azure-devices.net/deviceid/api-version=2016-11-14 MQTT password: NULL TLS ca: https://github.com/Azure/azure-iot-sdk-c/blob/master/certs/ms.der <- convert to ms.crt using openssl TLS cert: device certificate TLS pkey: device private key CLOUD: set the "Thumbprint" of device certificate (double click certificate->Details Tab->Thumbprint) DEVICE: set ms.der, device certificate and private key for TLS connection

@richmondu thanks for giving me solution to connect azure iot hub through iot hub. But i am getting confused while connecting my client to hub using sas token method. In SAS token method only one root certificate(ms.crt) is enough or device certificate(ms.der) also needed. If device certificate is needed,it needs private key. Where can i generate private key for device certficate without having root certificate key to make a valid certifiacte. Please help me to get connected!
i am using C&python mqtt client

anhashia commented 6 years ago

https://github.com/Azure/azure-iot-sdk-c/blob/master/certs/ms.der is IoT Hub service side Root CA which device needs to have trusted for TLS handshake to proceed. This is for Server side authentication.

If using SAS token for authentication, client (device) doesn't need X.509 certificate. You can either use SAS token or X.509 certificate for device side authentication. There are mutually exclusive. This is for client side authentication.

baluzealster commented 6 years ago

https://github.com/Azure/azure-iot-sdk-c/blob/master/certs/ms.der is IoT Hub service side Root CA which device needs to have trusted for TLS handshake to proceed. This is for Server side authentication.

If using SAS token for authentication, client (device) doesn't need X.509 certificate. You can either use SAS token or X.509 certificate for device side authentication. There are mutually exclusive. This is for client side authentication.

awesome !!!!! SAS token Method: azure is connected now with my client device. It needs only ca certificate which is mentioned above. Thank u so much sir for giving me the solution

baluzealster commented 6 years ago

Thanks for the clarification, I verified that the settings for both authentication types are indeed working using MQTT.FX. Case closed. Thank you @anhashia !

Authentication using Symmetric key (SAS Token) MQTT broker: myiothub.azure-devices.net MQTT port: 8883 MQTT clientid: deviceid MQTT username: myiothub.azure-devices.net/deviceid/api-version=2016-11-14 MQTT password: SAS TOKEN (generated with SharedAccessKey of deviceid from connection string) TLS ca: https://github.com/Azure/azure-iot-sdk-c/blob/master/certs/ms.der <- convert to 'ms.crt' using openssl TLS cert: NULL TLS pkey: NULL CLOUD: copy the shared access key of deviceid for SAS TOKEN generation DEVICE: set ms.der for TLS connection

Authentication with X.509 Self-Signed MQTT broker: myiothub.azure-devices.net MQTT port: 8883 MQTT clientid: deviceid MQTT username: myiothub.azure-devices.net/deviceid/api-version=2016-11-14 MQTT password: NULL TLS ca: https://github.com/Azure/azure-iot-sdk-c/blob/master/certs/ms.der <- convert to ms.crt using openssl TLS cert: device certificate TLS pkey: device private key CLOUD: set the "Thumbprint" of device certificate (double click certificate->Details Tab->Thumbprint) DEVICE: set ms.der, device certificate and private key for TLS connection

i connected my device to azure iot using both SAS token & Self_signed but i am not able to connect my device using CA certificate .Can u tell me what are the certificates, username and password to connect?

anhashia commented 6 years ago

There is really no big difference between X.509 self-signed (thumbprint) scenario and X.509 CA signed scenario. Password should be set to none in both cases.

In x.509 CA signed scenario, you need to POP on Root CA on IoT Hub side From device (client), side you have to present the chain. This is covered in some detail here https://github.com/Azure/azure-iot-sdk-c/blob/master/tools/CACertificates/CACertificateOverview.md

If using third party MQTT paho library, the call would be something like this (as an example) for X.509 CA signed scenario.

client.tls_set(ca_certs=”ms.crt”, certfile="new-device-full-chain.cert.pem", keyfile="new-device.key.pem", cert_reqs=ssl.CERT_REQUIRED, tls_version=ssl.PROTOCOL_TLSv1, ciphers=None)
client.username_pw_set(username=iot_hub_name+".azure-devices.net/" + device_id, password=None
baluzealster commented 6 years ago

There is really no big difference between X.509 self-signed (thumbprint) scenario and X.509 CA signed scenario. Password should be set to none in both cases.

In x.509 CA signed scenario, you need to POP on Root CA on IoT Hub side From device (client), side you have to present the chain. This is covered in some detail here https://github.com/Azure/azure-iot-sdk-c/blob/master/tools/CACertificates/CACertificateOverview.md

If using third party MQTT paho library, the call would be something like this (as an example) for X.509 CA signed scenario.

client.tls_set(ca_certs=”ms.crt”, certfile="new-device-full-chain.cert.pem", keyfile="new-device.key.pem", cert_reqs=ssl.CERT_REQUIRED, tls_version=ssl.PROTOCOL_TLSv1, ciphers=None)
client.username_pw_set(username=iot_hub_name+".azure-devices.net/" + device_id, password=None

@anhashia its working for paho library but it is not working for my c library it,s askig password for connecting can u please clarify me root CA doesn't need any password? if it needs what will be it ?sorry for raising it again.

anhashia commented 6 years ago

@baluzealster : You don't need to set password if you are using x509 certificate for client authentication. You would need to set the user name though. Password is only relevant if you are using SAS token for client (device) side authentication.

baluzealster commented 6 years ago

@baluzealster : You don't need to set password if you are using x509 certificate for client authentication. You would need to set the user name though. Password is only relevant if you are using SAS token for client (device) side authentication.

is there any restrictions in CA signed method for creating device certificates like certificate common name ,password and etc. 10 days passed but i am not getting where the issue is, certificates are properly given software is also good (c client). I am able to make connection using first two methods except last one give any suggestions to connect. i am getting error from server as CONNACK return code 5.

anhashia commented 6 years ago

You can try with sample certs https://github.com/Azure/azure-iot-sdk-c/blob/master/tools/CACertificates/CACertificateOverview.md

This should work. You can then compare success case with failure case. It can provide a clue.

Dan-cws commented 5 years ago

This link is broken https://github.com/Azure/azure-iot-sdk-c/blob/master/certs/ms.der. Where can I find the certicate?

anhashia commented 5 years ago

Hi @Dan-cws It looks like it is removed now. Root CA's are in certs.c in array format. These are publicly available third party Root CAs.

You can go to older release version and get the der file. https://github.com/Azure/azure-iot-sdk-c/blob/release_2018_06_08/certs/ms.der

cc @massand

GauravChoube commented 5 years ago

Hi, I am facing some issue while connecting through MQTTfx. I am not understanding where am i doing wrong Mqttfx creadential:

Authentication using Symmetric key (SAS Token) MQTT broker: myiothub.azure-devices.net MQTT port: 8883 MQTT clientid: testDevice MQTT username: iBotHub01.azure-devices.net/testDevice/api-version=2019-03-18 MQTT password: SharedAccessSignature sr=iBotHub01.azure-devices.net(Other information) TLS : TLS 1.0

CA certificate:(Iothub.txt) -----BEGIN CERTIFICATE----- MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJ RTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYD VQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoX DTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMCSUUxEjAQBgNVBAoTCUJhbHRpbW9y ZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFsdGltb3JlIEN5YmVy VHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKMEuyKr mD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjr IZ3AQSsBUnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeK mpYcqWe4PwzV9/lSEy/CG9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSu XmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9XbIGevOF6uvUA65ehD5f/xXtabz5OTZy dc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjprl3RjM71oGDHweI12v/ye jl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoIVDaGezq1 BE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3 DQEBBQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT92 9hkTI7gQCvlYpNRhcL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3Wgx jkzSswF07r51XgdIGn9w/xZchMB5hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0 Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsaY71k5h+3zvDyny67G7fyUIhz ksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9HRCwBXbsdtTLS R9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp -----END CERTIFICATE-----

While i am connecting,i am getting error like connection lost in MQTTfx. What is wrong above?

Any help will be appreciable.

Dan-cws commented 5 years ago

Where did you get the api version? Following the official documentation https://docs.microsoft.com/en-us/azure/iot-hub/iot-hub-mqtt-support#using-the-mqtt-protocol-directly is 2018-06-30.

Hope this helps

GauravChoube commented 5 years ago

Hi Dan, I think That is SDK version so i take it from git-hub. Its working now. Problem was in SAS token where i am not adding TTL and kept the 0. Now Change to 7 days.

nageswarysv commented 5 years ago

@richmondu This is covered in detail under https://docs.microsoft.com/en-us/azure/iot-hub/iot-hub-mqtt-support#using-the-mqtt-protocol-directly

There are ways to authenticate the client (device) to IoT Hub 1.) SAS token (password) 2.) X.509 client certificate.

Both are mutually exclusive. You can choose either 1 or 2 The are 2 type of certs here

1.) Server side certificate for IoT Hub server authentication Root CA (public) for Global IoT Hub is located at https://github.com/Azure/azure-iot-sdk-c/blob/master/certs/ms.der for reference.

IoT Hub server will send wildcard -> Intermediate CA. Device needs to validate the chain and for that it would need Root CA only. So you will have to configure your TLS library to validate Root CA. You don't need chain on the device. Chain will be sent to you from IoT hub. You only need Root CA which has to be trusted.

2.) Client side certificate for device side authentication. This is relevant only if you are using X.509 authentication and not needed for SAS token. Here you need the certificate for which you have the private key. Password here will be none

Call will be something like this if using third party MQTT library like paho.

client.tls_set(ca_certs=”ms.crt”, certfile="new-device-full-chain.cert.pem", keyfile="new-device.key.pem", cert_reqs=ssl.CERT_REQUIRED, tls_version=ssl.PROTOCOL_TLSv1, ciphers=None)
client.username_pw_set(username=iot_hub_name+".azure-devices.net/" + device_id, password=None)

The above solution has enhanced by understanding on authentication using SAS. I am trying to connect to Azure IoT from Python using MQTT. Authentication is by using Symmetric key (SAS Token). System gives RC error 5 (Connection refused – not authorised). I am not sure which of the values below are incorrectly provided.

Root Certificate: (ca_root_cert.txt containing the following text) -----BEGIN CERTIFICATE----- MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJ RTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYD VQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoX DTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMCSUUxEjAQBgNVBAoTCUJhbHRpbW9y ZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFsdGltb3JlIEN5YmVy VHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKMEuyKr mD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjr IZ3AQSsBUnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeK mpYcqWe4PwzV9/lSEy/CG9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSu XmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9XbIGevOF6uvUA65ehD5f/xXtabz5OTZy dc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjprl3RjM71oGDHweI12v/ye jl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoIVDaGezq1 BE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3 DQEBBQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT92 9hkTI7gQCvlYpNRhcL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3Wgx jkzSswF07r51XgdIGn9w/xZchMB5hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0 Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsaY71k5h+3zvDyny67G7fyUIhz ksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9HRCwBXbsdtTLS R9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp -----END CERTIFICATE-----

MQTT broker: .azure-devices.net MQTT port: 8883 MQTT clientid: deviceid MQTT username: .azure-devices.net/[deviceid]/api-version=2018-06-30 MQTT password: I am using share access key from connection string of the device from Azure portal. But this is not matching with the security token structure provided on Azure documentation. SharedAccessSignature sig={signature-string}&se={expiry}&skn={policyName}&sr={URL-encoded-resourceURI} TLS : TLSv1

Any help will be appreciable.

Ashutosh-017 commented 1 year ago

I am facing same problem I don't want to use Azure SDK I want to develop a code on ESP IDF to connect with azure IoT hub using MQTT with SAS method. Please help me This is my function to start MQTT

esp_mqtt_client_handle_t client = NULL;

static void mqtt_app_start(void) { ESP_LOGI(TAG, "STARTING MQTT"); esp_mqtt_client_config_t mqttConfig = { .uri = "mqtts://"MQTT_HOST, .port = MQTT_SERVER_PORT, .username = MQTT_USERNAME, .password = MQTT_PASSWORD, .client_id = client_id, .client_cert_pem = NULL, .client_key_pem = NULL, };

client = esp_mqtt_client_init(&mqttConfig);
esp_mqtt_client_register_event(client, ESP_EVENT_ANY_ID, mqtt_event_handler, client);
esp_mqtt_client_start(client);    

}

ericwolz commented 1 year ago

There is a sample on esp mqtt connect. It uses the embedded C SDK, but you should be able to run the sample to compare the connection setting as the logic is the same.

https://github.com/Azure/azure-sdk-for-c-arduino/blob/c70fce8da6704906b8298300f88fc973cac680d3/examples/Azure_IoT_Hub_ESP32/Azure_IoT_Hub_ESP32.ino#L250

Ashutosh-017 commented 1 year ago

There is a sample on esp mqtt connect. It uses the embedded C SDK, but you should be able to run the sample to compare the connection setting as the logic is the same.

https://github.com/Azure/azure-sdk-for-c-arduino/blob/c70fce8da6704906b8298300f88fc973cac680d3/examples/Azure_IoT_Hub_ESP32/Azure_IoT_Hub_ESP32.ino#L250

Thank you for your response

Ashutosh-017 commented 1 year ago

Hello Guys I have set these parameters in my code to connect with azure IoT hub using SAS method please tell me I have felt something or these parameters are enough.

(1) host = "ssl://"MQTT_HOST, (2) port = MQTT_SERVER_PORT, (3) username = MQTT_USERNAME, (4) password = MQTT_PASSWORD, ( Generated by using Primary connection string ) (5) client_id = DeviceID, (6) keepalive = 60,

Please help me guys

ericwolz commented 1 year ago

Does it connect? What is the MQTT CONNECT packet status?

Ashutosh-017 commented 1 year ago

Does it connect? What is the MQTT CONNECT packet status? I have not test this code yet. I will do it Today will update you soon. Thank you

Ashutosh-017 commented 1 year ago

There is a sample on esp mqtt connect. It uses the embedded C SDK, but you should be able to run the sample to compare the connection setting as the logic is the same.

https://github.com/Azure/azure-sdk-for-c-arduino/blob/c70fce8da6704906b8298300f88fc973cac680d3/examples/Azure_IoT_Hub_ESP32/Azure_IoT_Hub_ESP32.ino#L250

bro In this code we only need to provide primary connection string from azure IoT hub this code will automatically convert this string into SAS token by using same libraries of Azure SDK for Arduino. I cant you this libraries in ESP IDF

ericwolz commented 1 year ago

I'm having a hard time understanding your response above. That ask is to compare the MQTT connections parameters generated from our SDK to what you are using to debug what your configuration error are in your implementation of the MQTT connection parameters.

Ashutosh-017 commented 1 year ago

I'm having a hard time understanding your response above. That ask is to compare the MQTT connections parameters generated from our SDK to what you are using to debug what your configuration error are in your implementation of the MQTT connection parameters.

.host = MQTT_HOST, .port = MQTT_SERVER_PORT, .username = MQTT_USERNAME, .password = MQTT_PASSWORD, .client_id = DeviceID,

After providing these information I got these error

(12:53:04.694) I (521) wifi:mode : sta (a0:76:4e:5a:77:48) (12:53:04.694) I (521) wifi:enable tsf (12:53:04.709) [0;32mI (521) Azure_IoT: Trying to connect with Wi-Fi (12:53:04.709) [0m (12:53:04.709) I (521) wifi:new:<6,0>, old:<1,0>, ap:<255,255>, sta:<6,0>, prof:1 (12:53:04.725) I (531) wifi:state: init -> auth (b0) (12:53:04.725) I (531) wifi:state: auth -> assoc (0) (12:53:04.725) I (541) wifi:state: assoc -> run (10) (12:53:04.742) I (551) wifi:idx:0 (ifx:0, 34:3a:20:a4:4f:c2), tid:0, ssn:0, winSize:64 (12:53:04.742) I (551) wifi:connected with Napino, aid = 4, channel 6, BW20, bssid = 34:3a:20:a4:4f:c2 (12:53:04.742) I (561) wifi:security: WPA2-PSK, phy: bgn, rssi: -32 (12:53:04.775) I (561) wifi:pm start, type: 1 (12:53:04.775) (12:53:04.775) I (561) wifi:set rx beacon pti, rx_bcn_pti: 0, bcn_timeout: 0, mt_pti: 25000, mt_time: 10000 (12:53:04.775) [0;32mI (571) Azure_IoT: Wi-Fi connected (12:53:04.775) [0m (12:53:04.788) I (601) wifi:AP's beacon interval = 102400 us, DTIM period = 1 (12:53:06.691) [0;32mI (2521) Azure_IoT: STARTING MQTT (12:53:06.691) [0m (12:53:06.691) [0;32mI (2521) Azure_IoT: Other event id:7[0m (12:53:06.755) [0;32mI (2571) esp_netif_handlers: sta ip: 172.16.43.247, mask: 255.255.255.0, gw: 172.16.43.1[0m (12:53:06.755) [0;32mI (2571) Azure_IoT: got ip: starting MQTT Client (12:53:06.755) [0m (12:53:06.755) [0;32mI (2571) Azure_IoT: STARTING MQTT (12:53:06.772) [0m (12:53:06.772) [0;32mI (2571) Azure_IoT: Other event id:7[0m (12:53:07.863) I (3681) wifi:idx:1 (ifx:0, 34:3a:20:a4:4f:c2), tid:5, ssn:2, winSize:64 (12:53:17.876) [0;31mE (13691) esp-tls: [sock=54] select() timeout[0m (12:53:17.876) [0;31mE (13691) esp-tls: [sock=55] select() timeout[0m (12:53:17.890) [0;31mE (13691) TRANSPORT_BASE: Failed to open a new connection: 32774[0m (12:53:17.890) [0;31mE (13691) MQTT_CLIENT: Error transport connect[0m (12:53:17.890) [0;32mI (13701) Azure_IoT: MQTT_EVENT_ERROR (12:53:17.909) [0m (12:53:17.909) [0;32mI (13701) Azure_IoT: MQTT_EVENT_DISCONNECTED (12:53:17.909) [0m (12:53:17.909) [0;31mE (13701) TRANSPORT_BASE: Failed to open a new connection: 32774[0m (12:53:17.909) [0;31mE (13711) MQTT_CLIENT: Error transport connect[0m (12:53:17.922) [0;32mI (13721) Azure_IoT: MQTT_EVENT_ERROR (12:53:17.922) [0m (12:53:17.922) [0;32mI (13721) Azure_IoT: MQTT_EVENT_DISCONNECTED

Ashutosh-017 commented 1 year ago

(14:42:20.717) [0;32mI (2081) Azure_IoT: STARTING MQTT (14:42:20.717) [0m (14:42:20.717) [0;32mI (2081) Azure_IoT: Other event id:7[0m (14:42:20.843) [0;31mE (2221) MQTT_CLIENT: mqtt_message_receive: transport_read() error: errno=128[0m (14:42:20.875) [0;32mI (2221) Azure_IoT: MQTT_EVENT_ERROR (14:42:20.875) [0m (14:42:20.875) [0;31mE (2231) MQTT_CLIENT: esp_mqtt_connect: mqtt_message_receive() returned -1[0m (14:42:20.875) [0;31mE (2231) MQTT_CLIENT: MQTT connect failed[0m (14:42:20.875) [0;32mI (2241) Azure_IoT: MQTT_EVENT_DISCONNECTED

ericwolz commented 1 year ago

You are having connections issues. You can use wireshark to debug your network packets. I can't really help here because I don't have any access to your project.

Help me understand why you don't want to use the SDK? You are having issues that already have been solved by the SDK.

--Eric

Ashutosh-017 commented 1 year ago

You are having connections issues. You can use wireshark to debug your network packets. I can't really help here because I don't have any access to your project.

Help me understand why you don't want to use the SDK? You are having issues that already have been solved by the SDK.

--Eric

include

include

include

include

include "esp_wifi.h"

include "esp_system.h"

include "nvs_flash.h"

include "esp_event.h"

include "esp_netif.h"

include "lwip/sockets.h"

include "lwip/dns.h"

include "lwip/netdb.h"

include "esp_log.h"

include "mqtt_client.h"

static const char *TAG = "Azure_IoT";

// WIFI connection parameters

define EXAMPLE_ESP_WIFI_SSID "Napino"

define EXAMPLE_ESP_WIFI_PASS "Napino#321"

// Azure IoT Hub connection parameters

define MQTT_SERVER_PORT 8883

define MQTT_HOST "iot-hub-0098.azure-devices.net"

define MQTT_USERNAME "iot-hub-0098.azure-devices.net/Demo2/?api-version=2020-09-30&DeviceClientType=c%2F1.5.0-beta.1(ard;esp32)"

define MQTT_PASSWORD "SharedAccessSignature sr=iot-hub-0098.azure-devices.net%2Fdevices%2FDemo2&sig=a7kXMK7wTR2PFILLAJEaZtQ5PySQ%2B70Fs2c6TgKYKRM%3D&se=1717585296"

define DeviceID "Demo2"

uint32_t MQTT_CONNEECTED = 0;

static void mqtt_app_start(void);

static esp_err_t event_handler(void ctx, system_event_t event) { switch (event->event_id) { case SYSTEM_EVENT_STA_START: esp_wifi_connect(); ESP_LOGI(TAG, "Trying to connect with Wi-Fi\n"); break;

case SYSTEM_EVENT_STA_CONNECTED:
    ESP_LOGI(TAG, "Wi-Fi connected\n");
    break;

case SYSTEM_EVENT_STA_GOT_IP:
    ESP_LOGI(TAG, "got ip: starting MQTT Client\n");
    mqtt_app_start();
    break;

case SYSTEM_EVENT_STA_DISCONNECTED:
    ESP_LOGI(TAG, "disconnected: Retrying to connect Wi-Fi\n");
    esp_wifi_connect();
    break;

default:
    break;
}
return ESP_OK;

}

void wifi_init(void) { ESP_ERROR_CHECK(esp_netif_init());

ESP_ERROR_CHECK(esp_event_loop_create_default());
esp_netif_create_default_wifi_sta();

wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK(esp_wifi_init(&cfg));

ESP_ERROR_CHECK(esp_event_loop_init(event_handler, NULL));

wifi_config_t wifi_config = {
    .sta = {
        .ssid = EXAMPLE_ESP_WIFI_SSID,
        .password = EXAMPLE_ESP_WIFI_PASS,
     .threshold.authmode = WIFI_AUTH_WPA2_PSK,
    },
};
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA) );
ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config) );
ESP_ERROR_CHECK(esp_wifi_start());

}

static void mqtt_event_handler(void handler_args, esp_event_base_t base, int32_t event_id, void event_data) { ESP_LOGD(TAG, "Event dispatched from event loop base=%s, event_id=%d", base, event_id); esp_mqtt_event_handle_t event = event_data; esp_mqtt_client_handle_t client = event->client; int msg_id; switch ((esp_mqtt_event_id_t)event_id) { case MQTT_EVENT_CONNECTED: ESP_LOGI(TAG, "MQTT_EVENT_CONNECTED\n"); MQTT_CONNEECTED=1;

    msg_id = esp_mqtt_client_subscribe(client, "/devices/deviceID", 0);
    ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id);
    msg_id = esp_mqtt_client_publish(client, "devices/deviceID", "Ashutosh Goswami", 0, 0, 0);

    break;
case MQTT_EVENT_DISCONNECTED:
    ESP_LOGI(TAG, "MQTT_EVENT_DISCONNECTED\n");
    MQTT_CONNEECTED=0;
    break;

case MQTT_EVENT_SUBSCRIBED:
    ESP_LOGI(TAG, "MQTT_EVENT_SUBSCRIBED, msg_id=%d", event->msg_id);
    break;
case MQTT_EVENT_UNSUBSCRIBED:
    ESP_LOGI(TAG, "MQTT_EVENT_UNSUBSCRIBED, msg_id=%d", event->msg_id);
    break;
case MQTT_EVENT_PUBLISHED:
    ESP_LOGI(TAG, "MQTT_EVENT_PUBLISHED, msg_id=%d", event->msg_id);
    break;
case MQTT_EVENT_DATA:
    ESP_LOGI(TAG, "MQTT_EVENT_DATA\n");
    printf("TOPIC=%.*s\r\n", event->topic_len, event->topic);
    printf("DATA=%.*s\r\n", event->data_len, event->data);
    break;
case MQTT_EVENT_ERROR:
    ESP_LOGI(TAG, "MQTT_EVENT_ERROR\n");
    break;
default:
    ESP_LOGI(TAG, "Other event id:%d", event->event_id);
    break;
}

}

esp_mqtt_client_handle_t client = NULL;

static void mqtt_app_start(void) { ESP_LOGI(TAG, "STARTING MQTT\n"); const esp_mqtt_client_config_t mqttConfig = { .host = MQTT_HOST, .port = MQTT_SERVER_PORT, .username = MQTT_USERNAME, .password = MQTT_PASSWORD, .client_id = DeviceID, .keepalive = 60, .client_cert_pem = NULL, .client_key_pem = NULL, };

client = esp_mqtt_client_init(&mqttConfig);
esp_mqtt_client_register_event(client, ESP_EVENT_ANY_ID, mqtt_event_handler, NULL);
esp_mqtt_client_start(client);    

}

void app_main(void) { esp_err_t ret = nvs_flash_init(); if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) { ESP_ERROR_CHECK(nvs_flash_erase()); ret = nvs_flash_init(); } ESP_ERROR_CHECK(ret);

wifi_init();

vTaskDelay(2000 / portTICK_PERIOD_MS);

mqtt_app_start();

} This is my code you can check mistake

ericwolz commented 1 year ago

Here is your sample that works


#include <stdio.h>
#include <stdint.h>
#include <stddef.h>
#include <string.h>
#include "esp_wifi.h"
#include "esp_system.h"
#include "nvs_flash.h"
#include `"esp_event.h"`
#include "esp_netif.h"

#include "lwip/sockets.h"
#include "lwip/dns.h"
#include "lwip/netdb.h"

#include "esp_log.h"
#include "mqtt_client.h"

static const char *TAG = "Azure_IoT";

// WIFI connection parameters
#define EXAMPLE_ESP_WIFI_SSID "MY_SSID"
#define EXAMPLE_ESP_WIFI_PASS "MY_PASSWORD"

// Azure IoT Hub connection parameters
#define MQTT_HOST "mqtts://my-hub.azure-devices.net:8883"
#define MQTT_USERNAME "my-hub.azure-devices.net/snoopy/?api-version=2021-04-12&DeviceClientType=c%2F1.5.0-beta.1(ard;esp32)"
#define MQTT_PASSWORD "SharedAccessSignature sr=my-hub.azure-devices.net%2Fdevices%2Fsnoopy&sig=6dM2iVmz8UDMMzC9XXm2thJb7uNaXXXRekpQYLA%3D&se=1586381871"
#define DeviceID "snoopy"

uint32_t MQTT_CONNEECTED = 0;

static void mqtt_app_start(void);

static void event_handler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data)
{
    switch (event_id)
    {
        case WIFI_EVENT_STA_START:
            esp_wifi_connect();
            ESP_LOGI(TAG, "Trying to connect with Wi-Fi\n");
        break;

        case WIFI_EVENT_STA_CONNECTED:
            ESP_LOGI(TAG, "Wi-Fi connected\n");
            break;

        case IP_EVENT_STA_GOT_IP:
            ESP_LOGI(TAG, "got ip: starting MQTT Client\n");
            //mqtt_app_start();
            break;

        case WIFI_EVENT_STA_DISCONNECTED:
            ESP_LOGI(TAG, "disconnected: Retrying to connect Wi-Fi\n");
            esp_wifi_connect();
            break;

        default:
            break;
    }

    return;
}

void wifi_init(void)
{
    ESP_ERROR_CHECK(esp_netif_init());

    ESP_ERROR_CHECK(esp_event_loop_create_default());
    esp_netif_create_default_wifi_sta();

    wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
    ESP_ERROR_CHECK(esp_wifi_init(&cfg));

    ESP_ERROR_CHECK(esp_event_handler_register(ESP_EVENT_ANY_BASE, ESP_EVENT_ANY_ID, event_handler, NULL));

    wifi_config_t wifi_config = {
        .sta = {
            .ssid = EXAMPLE_ESP_WIFI_SSID,
            .password = EXAMPLE_ESP_WIFI_PASS,
         .threshold.authmode = WIFI_AUTH_WPA2_PSK,
        },
    };
    ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA) );
    ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config) );
    ESP_ERROR_CHECK(esp_wifi_start());
}

static void mqtt_event_handler(void *handler_args, esp_event_base_t base, int32_t event_id, void *event_data)
{
    ESP_LOGD(TAG, "Event dispatched from event loop base=%s, event_id=%d", base, (int)event_id);
    esp_mqtt_event_handle_t event = event_data;
    esp_mqtt_client_handle_t client = event->client;
    int msg_id;

    switch ((esp_mqtt_event_id_t)event_id)
    {
        case MQTT_EVENT_CONNECTED:
            ESP_LOGI(TAG, "MQTT_EVENT_CONNECTED\n");
            MQTT_CONNEECTED=1;
            msg_id = esp_mqtt_client_subscribe(client, "devices/" DeviceID "/messages/devicebound/#", 0);
            ESP_LOGI(TAG, "sent subscribe, msg_id=%d", msg_id);
            ESP_LOGI(TAG, "devices/" DeviceID "/messages/events/");
            break;
        case MQTT_EVENT_DISCONNECTED:
            ESP_LOGI(TAG, "MQTT_EVENT_DISCONNECTED\n");
            MQTT_CONNEECTED=0;
            break;
        case MQTT_EVENT_SUBSCRIBED:
            ESP_LOGI(TAG, "MQTT_EVENT_SUBSCRIBED, msg_id=%d", event->msg_id);
            break;
        case MQTT_EVENT_UNSUBSCRIBED:
            ESP_LOGI(TAG, "MQTT_EVENT_UNSUBSCRIBED, msg_id=%d", event->msg_id);
            break;
        case MQTT_EVENT_PUBLISHED:
            ESP_LOGI(TAG, "MQTT_EVENT_PUBLISHED, msg_id=%d", event->msg_id);
            break;
        case MQTT_EVENT_DATA:
            ESP_LOGI(TAG, "MQTT_EVENT_DATA\n");
            printf("TOPIC=%.*s\r\n", event->topic_len, event->topic);
            printf("DATA=%.*s\r\n", event->data_len, event->data);
            break;
        case MQTT_EVENT_BEFORE_CONNECT:
            ESP_LOGI(TAG, "MQTT_EVENT_BEFORE_CONNECT\n");
            break;
        case MQTT_EVENT_ERROR:
            ESP_LOGI(TAG, "MQTT_EVENT_ERROR\n");
            break;
        default:
            ESP_LOGI(TAG, "Other event id:%d", event->event_id);
            break;
    }
}

esp_mqtt_client_handle_t client = NULL;

static void mqtt_app_start(void)
{
    ESP_LOGI(TAG, "STARTING MQTT\n");

    esp_mqtt_client_config_t mqtt_cfg = { 0 };
    mqtt_cfg.broker.address.uri = MQTT_HOST;
    mqtt_cfg.credentials.client_id = DeviceID;
    mqtt_cfg.credentials.username = MQTT_USERNAME;
    mqtt_cfg.credentials.authentication.password = MQTT_PASSWORD;
    mqtt_cfg.broker.verification.certificate =
            /* Baltimore CyberTrust Root */
            "-----BEGIN CERTIFICATE-----\r\n"
            "MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJ\r\n"
            "RTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYD\r\n"
            "VQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoX\r\n"
            "DTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMCSUUxEjAQBgNVBAoTCUJhbHRpbW9y\r\n"
            "ZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFsdGltb3JlIEN5YmVy\r\n"
            "VHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKMEuyKr\r\n"
            "mD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjr\r\n"
            "IZ3AQSsBUnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeK\r\n"
            "mpYcqWe4PwzV9/lSEy/CG9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSu\r\n"
            "XmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9XbIGevOF6uvUA65ehD5f/xXtabz5OTZy\r\n"
            "dc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjprl3RjM71oGDHweI12v/ye\r\n"
            "jl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoIVDaGezq1\r\n"
            "BE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3\r\n"
            "DQEBBQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT92\r\n"
            "9hkTI7gQCvlYpNRhcL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3Wgx\r\n"
            "jkzSswF07r51XgdIGn9w/xZchMB5hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0\r\n"
            "Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsaY71k5h+3zvDyny67G7fyUIhz\r\n"
            "ksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9HRCwBXbsdtTLS\r\n"
            "R9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp\r\n"
            "-----END CERTIFICATE-----\r\n"

            /* DigiCert Global Root G2 */
            "-----BEGIN CERTIFICATE-----\r\n"
            "MIIDjjCCAnagAwIBAgIQAzrx5qcRqaC7KGSxHQn65TANBgkqhkiG9w0BAQsFADBh\r\n"
            "MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3\r\n"
            "d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBH\r\n"
            "MjAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVT\r\n"
            "MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j\r\n"
            "b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEcyMIIBIjANBgkqhkiG\r\n"
            "9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzfNNNx7a8myaJCtSnX/RrohCgiN9RlUyfuI\r\n"
            "2/Ou8jqJkTx65qsGGmvPrC3oXgkkRLpimn7Wo6h+4FR1IAWsULecYxpsMNzaHxmx\r\n"
            "1x7e/dfgy5SDN67sH0NO3Xss0r0upS/kqbitOtSZpLYl6ZtrAGCSYP9PIUkY92eQ\r\n"
            "q2EGnI/yuum06ZIya7XzV+hdG82MHauVBJVJ8zUtluNJbd134/tJS7SsVQepj5Wz\r\n"
            "tCO7TG1F8PapspUwtP1MVYwnSlcUfIKdzXOS0xZKBgyMUNGPHgm+F6HmIcr9g+UQ\r\n"
            "vIOlCsRnKPZzFBQ9RnbDhxSJITRNrw9FDKZJobq7nMWxM4MphQIDAQABo0IwQDAP\r\n"
            "BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUTiJUIBiV\r\n"
            "5uNu5g/6+rkS7QYXjzkwDQYJKoZIhvcNAQELBQADggEBAGBnKJRvDkhj6zHd6mcY\r\n"
            "1Yl9PMWLSn/pvtsrF9+wX3N3KjITOYFnQoQj8kVnNeyIv/iPsGEMNKSuIEyExtv4\r\n"
            "NeF22d+mQrvHRAiGfzZ0JFrabA0UWTW98kndth/Jsw1HKj2ZL7tcu7XUIOGZX1NG\r\n"
            "Fdtom/DzMNU+MeKNhJ7jitralj41E6Vf8PlwUHBHQRFXGU7Aj64GxJUTFy8bJZ91\r\n"
            "8rGOmaFvE7FBcf6IKshPECBV1/MUReXgRPTqh5Uykw7+U0b6LJ3/iyK5S9kJRaTe\r\n"
            "pLiaWN0bfVKfjllDiIGknibVb63dDcY3fe0Dkhvld1927jyNxF1WW6LZZm6zNTfl\r\n"
            "MrY=\r\n"
            "-----END CERTIFICATE-----\r\n";

    client = esp_mqtt_client_init(&mqtt_cfg);
    esp_mqtt_client_register_event(client, ESP_EVENT_ANY_ID, mqtt_event_handler, NULL);
    esp_mqtt_client_start(client);

    while (1)
    {
        // do stuff
        vTaskDelay(1000 / portTICK_PERIOD_MS);

        ESP_LOGI(TAG, "do stuff\n");
        int msg_id = esp_mqtt_client_publish(client, "devices/" DeviceID "/messages/events/", "Ashutosh Goswami", 0, 0, 0);
        ESP_LOGI(TAG, "sent MQTT publish, msg_id=%d", msg_id);
    }

}

void app_main(void)
{
    esp_log_level_set("*", ESP_LOG_INFO);        // set all components to ERROR level

    ESP_LOGI(TAG, "app_main");
    esp_err_t ret = nvs_flash_init();
    if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
        ESP_ERROR_CHECK(nvs_flash_erase());
        ret = nvs_flash_init();
    }
    ESP_ERROR_CHECK(ret);

    wifi_init();

    vTaskDelay(2000 / portTICK_PERIOD_MS);

    mqtt_app_start();

    ESP_LOGI(TAG, "app_main exit\n");
}