This commit is contained in:
Dane Walton 2022-11-07 18:02:28 -05:00 коммит произвёл GitHub
Родитель 0e3a968d01
Коммит f7f5ca8b15
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
11 изменённых файлов: 308 добавлений и 157 удалений

Просмотреть файл

@ -64,8 +64,6 @@
#define ADU_DEVICE_SHA_SIZE 32
#define ADU_SHA_PARTITION_READ_BUFFER_SIZE 32
#define HTTP_DOWNLOAD_CHUNK 4096
#define ADU_PNP_ACCEPT_CODE 200
#define ADU_PNP_REJECT_CODE 406
// ADU Feature Values
static az_iot_adu_client adu_client;
@ -73,6 +71,7 @@ static az_iot_adu_client_update_request adu_update_request;
static az_iot_adu_client_update_manifest adu_update_manifest;
static char adu_new_version[16];
static bool process_update_request = false;
static bool send_init_state = true;
static bool did_update = false;
static char adu_scratch_buffer[10000];
static char adu_manifest_unescape_buffer[2000];
@ -83,12 +82,7 @@ static char partition_read_buffer[ADU_SHA_PARTITION_READ_BUFFER_SIZE];
static int chunked_data_index;
static az_span pnp_components[] = { AZ_SPAN_FROM_STR(AZ_IOT_ADU_CLIENT_PROPERTIES_COMPONENT_NAME) };
az_iot_adu_client_device_properties adu_device_information
= { .manufacturer = AZ_SPAN_LITERAL_FROM_STR(ADU_DEVICE_MANUFACTURER),
.model = AZ_SPAN_LITERAL_FROM_STR(ADU_DEVICE_MODEL),
.adu_version = AZ_SPAN_LITERAL_FROM_STR(AZ_IOT_ADU_CLIENT_AGENT_VERSION),
.delivery_optimization_agent_version = AZ_SPAN_EMPTY,
.update_id = AZ_SPAN_LITERAL_FROM_STR(ADU_UPDATE_ID) };
static az_iot_adu_client_device_properties adu_device_information;
// Utility macros and defines
#define sizeofarray(a) (sizeof(a) / sizeof(a[0]))
@ -142,6 +136,90 @@ static AzIoTSasToken sasToken(
AZ_SPAN_FROM_BUFFER(mqtt_password));
#endif // IOT_CONFIG_USE_X509_CERT
/* Azure Device Update root keys used to verify the signed deployment */
/* ADU.200702.R */
static uint8_t ucAzureIoTADURootKeyId200702[ 13 ] = "ADU.200702.R";
static uint8_t ucAzureIoTADURootKeyN200702[ 385 ]
=
{
0x00, 0xd5, 0x42, 0x2e, 0xaf, 0x11, 0x54, 0xa3, 0x50, 0x65, 0x87, 0xa2, 0x4d, 0x5b, 0xba,
0x1a, 0xfb, 0xa9, 0x32, 0xdf, 0xe9, 0x99, 0x5f, 0x05, 0x45, 0xc8, 0xaf, 0xbd, 0x35, 0x1d,
0x89, 0xe8, 0x27, 0x27, 0x58, 0xa3, 0xa8, 0xee, 0xc5, 0xc5, 0x1e, 0x4f, 0xf7, 0x92, 0xa6,
0x12, 0x06, 0x7d, 0x3d, 0x7d, 0xb0, 0x07, 0xf6, 0x2c, 0x7f, 0xde, 0x6d, 0x2a, 0xf5, 0xbc,
0x49, 0xbc, 0x15, 0xef, 0xf0, 0x81, 0xcb, 0x3f, 0x88, 0x4f, 0x27, 0x1d, 0x88, 0x71, 0x28,
0x60, 0x08, 0xb6, 0x19, 0xd2, 0xd2, 0x39, 0xd0, 0x05, 0x1f, 0x3c, 0x76, 0x86, 0x71, 0xbb,
0x59, 0x58, 0xbc, 0xb1, 0x88, 0x7b, 0xab, 0x56, 0x28, 0xbf, 0x31, 0x73, 0x44, 0x32, 0x10,
0xfd, 0x3d, 0xd3, 0x96, 0x5c, 0xff, 0x4e, 0x5c, 0xb3, 0x6b, 0xff, 0x8b, 0x84, 0x9b, 0x8b,
0x80, 0xb8, 0x49, 0xd0, 0x7d, 0xfa, 0xd6, 0x40, 0x58, 0x76, 0x4d, 0xc0, 0x72, 0x27, 0x75,
0xcb, 0x9a, 0x2f, 0x9b, 0xb4, 0x9f, 0x0f, 0x25, 0xf1, 0x1c, 0xc5, 0x1b, 0x0b, 0x5a, 0x30,
0x7d, 0x2f, 0xb8, 0xef, 0xa7, 0x26, 0x58, 0x53, 0xaf, 0xd5, 0x1d, 0x55, 0x01, 0x51, 0x0d,
0xe9, 0x1b, 0xa2, 0x0f, 0x3f, 0xd7, 0xe9, 0x1d, 0x20, 0x41, 0xa6, 0xe6, 0x14, 0x0a, 0xae,
0xfe, 0xf2, 0x1c, 0x2a, 0xd6, 0xe4, 0x04, 0x7b, 0xf6, 0x14, 0x7e, 0xec, 0x0f, 0x97, 0x83,
0xfa, 0x58, 0xfa, 0x81, 0x36, 0x21, 0xb9, 0xa3, 0x2b, 0xfa, 0xd9, 0x61, 0x0b, 0x1a, 0x94,
0xf7, 0xc1, 0xbe, 0x7f, 0x40, 0x14, 0x4a, 0xc9, 0xfa, 0x35, 0x7f, 0xef, 0x66, 0x70, 0x00,
0xb1, 0xfd, 0xdb, 0xd7, 0x61, 0x0d, 0x3b, 0x58, 0x74, 0x67, 0x94, 0x89, 0x75, 0x76, 0x96,
0x7c, 0x91, 0x87, 0xd2, 0x8e, 0x11, 0x97, 0xee, 0x7b, 0x87, 0x6c, 0x9a, 0x2f, 0x45, 0xd8,
0x65, 0x3f, 0x52, 0x70, 0x98, 0x2a, 0xcb, 0xc8, 0x04, 0x63, 0xf5, 0xc9, 0x47, 0xcf, 0x70,
0xf4, 0xed, 0x64, 0xa7, 0x74, 0xa5, 0x23, 0x8f, 0xb6, 0xed, 0xf7, 0x1c, 0xd3, 0xb0, 0x1c,
0x64, 0x57, 0x12, 0x5a, 0xa9, 0x81, 0x84, 0x1f, 0xa0, 0xe7, 0x50, 0x19, 0x96, 0xb4, 0x82,
0xb1, 0xac, 0x48, 0xe3, 0xe1, 0x32, 0x82, 0xcb, 0x40, 0x1f, 0xac, 0xc4, 0x59, 0xbc, 0x10,
0x34, 0x51, 0x82, 0xf9, 0x28, 0x8d, 0xa8, 0x1e, 0x9b, 0xf5, 0x79, 0x45, 0x75, 0xb2, 0xdc,
0x9a, 0x11, 0x43, 0x08, 0xbe, 0x61, 0xcc, 0x9a, 0xc4, 0xcb, 0x77, 0x36, 0xff, 0x83, 0xdd,
0xa8, 0x71, 0x4f, 0x51, 0x8e, 0x0e, 0x7b, 0x4d, 0xfa, 0x79, 0x98, 0x8d, 0xbe, 0xfc, 0x82,
0x7e, 0x40, 0x48, 0xa9, 0x12, 0x01, 0xa8, 0xd9, 0x7e, 0xf3, 0xa5, 0x1b, 0xf1, 0xfb, 0x90,
0x77, 0x3e, 0x40, 0x87, 0x18, 0xc9, 0xab, 0xd9, 0xf7, 0x79
};
static uint8_t ucAzureIoTADURootKeyE200702[ 3 ] = { 0x01, 0x00, 0x01 };
/* ADU.200703.R */
static uint8_t ucAzureIoTADURootKeyId200703[ 13 ] = "ADU.200703.R";
static uint8_t ucAzureIoTADURootKeyN200703[ 385 ] =
{
0x00, 0xb2, 0xa3, 0xb2, 0x74, 0x16, 0xfa, 0xbb, 0x20, 0xf9, 0x52, 0x76, 0xe6, 0x27, 0x3e,
0x80, 0x41, 0xc6, 0xfe, 0xcf, 0x30, 0xf9, 0xc8, 0x96, 0xf5, 0x59, 0x0a, 0xaa, 0x81, 0xe7,
0x51, 0x83, 0x8a, 0xc4, 0xf5, 0x17, 0x3a, 0x2f, 0x2a, 0xe6, 0x57, 0xd4, 0x71, 0xce, 0x8a,
0x3d, 0xef, 0x9a, 0x55, 0x76, 0x3e, 0x99, 0xe2, 0xc2, 0xae, 0x4c, 0xee, 0x2d, 0xb8, 0x78,
0xf5, 0xa2, 0x4e, 0x28, 0xf2, 0x9c, 0x4e, 0x39, 0x65, 0xbc, 0xec, 0xe4, 0x0d, 0xe5, 0xe3,
0x38, 0xa8, 0x59, 0xab, 0x08, 0xa4, 0x1b, 0xb4, 0xf4, 0xa0, 0x52, 0xa3, 0x38, 0xb3, 0x46,
0x21, 0x13, 0xcc, 0x3c, 0x68, 0x06, 0xde, 0xfe, 0x00, 0xa6, 0x92, 0x6e, 0xde, 0x4c, 0x47,
0x10, 0xd6, 0x1c, 0x9c, 0x24, 0xf5, 0xcd, 0x70, 0xe1, 0xf5, 0x6a, 0x7c, 0x68, 0x13, 0x1d,
0xe1, 0xc5, 0xf6, 0xa8, 0x4f, 0x21, 0x9f, 0x86, 0x7c, 0x44, 0xc5, 0x8a, 0x99, 0x1c, 0xc5,
0xd3, 0x06, 0x9b, 0x5a, 0x71, 0x9d, 0x09, 0x1c, 0xc3, 0x64, 0x31, 0x6a, 0xc5, 0x17, 0x95,
0x1d, 0x5d, 0x2a, 0xf1, 0x55, 0xc7, 0x66, 0xd4, 0xe8, 0xf5, 0xd9, 0xa9, 0x5b, 0x8c, 0xa2,
0x6c, 0x62, 0x60, 0x05, 0x37, 0xd7, 0x32, 0xb0, 0x73, 0xcb, 0xf7, 0x4b, 0x36, 0x27, 0x24,
0x21, 0x8c, 0x38, 0x0a, 0xb8, 0x18, 0xfe, 0xf5, 0x15, 0x60, 0x35, 0x8b, 0x35, 0xef, 0x1e,
0x0f, 0x88, 0xa6, 0x13, 0x8d, 0x7b, 0x7d, 0xef, 0xb3, 0xe7, 0xb0, 0xc9, 0xa6, 0x1c, 0x70,
0x7b, 0xcc, 0xf2, 0x29, 0x8b, 0x87, 0xf7, 0xbd, 0x9d, 0xb6, 0x88, 0x6f, 0xac, 0x73, 0xff,
0x72, 0xf2, 0xef, 0x48, 0x27, 0x96, 0x72, 0x86, 0x06, 0xa2, 0x5c, 0xe3, 0x7d, 0xce, 0xb0,
0x9e, 0xe5, 0xc2, 0xd9, 0x4e, 0xc4, 0xf3, 0x7f, 0x78, 0x07, 0x4b, 0x65, 0x88, 0x45, 0x0c,
0x11, 0xe5, 0x96, 0x56, 0x34, 0x88, 0x2d, 0x16, 0x0e, 0x59, 0x42, 0xd2, 0xf7, 0xd9, 0xed,
0x1d, 0xed, 0xc9, 0x37, 0x77, 0x44, 0x7e, 0xe3, 0x84, 0x36, 0x9f, 0x58, 0x13, 0xef, 0x6f,
0xe4, 0xc3, 0x44, 0xd4, 0x77, 0x06, 0x8a, 0xcf, 0x5b, 0xc8, 0x80, 0x1c, 0xa2, 0x98, 0x65,
0x0b, 0x35, 0xdc, 0x73, 0xc8, 0x69, 0xd0, 0x5e, 0xe8, 0x25, 0x43, 0x9e, 0xf6, 0xd8, 0xab,
0x05, 0xaf, 0x51, 0x29, 0x23, 0x55, 0x40, 0x58, 0x10, 0xea, 0xb8, 0xe2, 0xcd, 0x5d, 0x79,
0xcc, 0xec, 0xdf, 0xb4, 0x5b, 0x98, 0xc7, 0xfa, 0xe3, 0xd2, 0x6c, 0x26, 0xce, 0x2e, 0x2c,
0x56, 0xe0, 0xcf, 0x8d, 0xee, 0xfd, 0x93, 0x12, 0x2f, 0x00, 0x49, 0x8d, 0x1c, 0x82, 0x38,
0x56, 0xa6, 0x5d, 0x79, 0x44, 0x4a, 0x1a, 0xf3, 0xdc, 0x16, 0x10, 0xb3, 0xc1, 0x2d, 0x27,
0x11, 0xfe, 0x1b, 0x98, 0x05, 0xe4, 0xa3, 0x60, 0x31, 0x99
};
static uint8_t ucAzureIoTADURootKeyE200703[ 3 ] = { 0x01, 0x00, 0x01 };
static SampleJWS::RootKey xADURootKeys[] =
{
{
// Minus one on id to not count NULL
.root_key_id = az_span_create(ucAzureIoTADURootKeyId200703, sizeof(ucAzureIoTADURootKeyId200703) - 1),
.root_key_n = AZ_SPAN_FROM_BUFFER(ucAzureIoTADURootKeyN200703),
.root_key_exponent = AZ_SPAN_FROM_BUFFER(ucAzureIoTADURootKeyE200703)
},
{
// Minus one on id to not count NULL
.root_key_id = az_span_create(ucAzureIoTADURootKeyId200702, sizeof(ucAzureIoTADURootKeyId200702) - 1),
.root_key_n = AZ_SPAN_FROM_BUFFER(ucAzureIoTADURootKeyN200702),
.root_key_exponent = AZ_SPAN_FROM_BUFFER(ucAzureIoTADURootKeyE200702)
}
};
static void connect_to_wifi()
{
Logger.Info("Connecting to WIFI SSID " + String(ssid));
@ -360,7 +438,7 @@ static void request_all_properties(void)
// send_adu_device_reported_property writes a property payload reporting device
// state and then sends it to Azure IoT Hub.
static void send_adu_device_information_property(int32_t agent_state, az_iot_adu_client_workflow * workflow)
static void send_adu_device_information_property(az_iot_adu_client_agent_state agent_state, az_iot_adu_client_workflow * workflow)
{
az_result rc;
@ -423,7 +501,7 @@ static void send_adu_device_information_property(int32_t agent_state, az_iot_adu
}
static void send_adu_accept_manifest_property(int32_t version_number,
int32_t response_code)
az_iot_adu_client_request_decision response_code)
{
az_result rc;
@ -546,7 +624,7 @@ static void process_device_property_message(
}
else
{
if(adu_update_request.workflow.action != AZ_IOT_ADU_CLIENT_SERVICE_ACTION_CANCEL)
if(adu_update_request.workflow.action == AZ_IOT_ADU_CLIENT_SERVICE_ACTION_APPLY_DEPLOYMENT)
{
rc = az_json_string_unescape(adu_update_request.update_manifest, (char*)adu_manifest_unescape_buffer, sizeof(adu_manifest_unescape_buffer), &out_manifest_size);
@ -580,6 +658,7 @@ static void process_device_property_message(
rc = SampleJWS::ManifestAuthenticate(
manifest_unescaped,
adu_update_request.update_manifest_signature,
&xADURootKeys[0], sizeof(xADURootKeys) / sizeof(xADURootKeys[0]),
AZ_SPAN_FROM_BUFFER(adu_verification_buffer));
if (az_result_failed(rc))
{
@ -593,20 +672,30 @@ static void process_device_property_message(
if (is_update_already_applied())
{
Logger.Info("Update already applied");
send_adu_accept_manifest_property(version_number, ADU_PNP_REJECT_CODE);
send_adu_accept_manifest_property(version_number, AZ_IOT_ADU_CLIENT_REQUEST_DECISION_REJECT);
process_update_request = false;
}
else
{
Logger.Info("Sending manifest property accept");
send_adu_accept_manifest_property(version_number, ADU_PNP_ACCEPT_CODE);
send_adu_accept_manifest_property(version_number, AZ_IOT_ADU_CLIENT_REQUEST_DECISION_ACCEPT);
process_update_request = true;
}
}
else
else if (adu_update_request.workflow.action == AZ_IOT_ADU_CLIENT_SERVICE_ACTION_CANCEL)
{
Logger.Info("ADU action received: cancelled deployment");
send_adu_device_information_property(AZ_IOT_ADU_CLIENT_AGENT_STATE_IDLE, NULL);
process_update_request = false;
}
else
{
Logger.Error("Unknown workflow action received: " + String(adu_update_request.workflow.action));
send_adu_device_information_property(AZ_IOT_ADU_CLIENT_AGENT_STATE_FAILED, &adu_update_request.workflow);
process_update_request = false;
}
}
}
@ -985,9 +1074,16 @@ static void send_telemetry()
// Arduino setup and loop main functions.
void setup() { establish_connection(); }
void setup() {
adu_device_information = az_iot_adu_client_device_properties_default();
adu_device_information.manufacturer = AZ_SPAN_FROM_STR(ADU_DEVICE_MANUFACTURER);
adu_device_information.model = AZ_SPAN_FROM_STR(ADU_DEVICE_MODEL);
adu_device_information.adu_version = AZ_SPAN_FROM_STR(AZ_IOT_ADU_CLIENT_AGENT_VERSION);
adu_device_information.delivery_optimization_agent_version = AZ_SPAN_EMPTY;
adu_device_information.update_id = AZ_SPAN_FROM_STR(ADU_UPDATE_ID);
bool send_init_state = true;
establish_connection();
}
void loop()
{
@ -1034,9 +1130,10 @@ void loop()
{
Logger.Info("Cancellation request was received during download. "
"Aborting update.");
send_adu_device_information_property(AZ_IOT_ADU_CLIENT_AGENT_STATE_IDLE, NULL);
process_update_request = false;
}
else
else if (adu_update_request.workflow.action == AZ_IOT_ADU_CLIENT_SERVICE_ACTION_APPLY_DEPLOYMENT)
{
result = verify_image(
adu_update_manifest.files[0].hashes->hash_value,
@ -1052,6 +1149,14 @@ void loop()
esp_restart();
}
}
else
{
Logger.Error("Unknown workflow action received: " + String(adu_update_request.workflow.action));
send_adu_device_information_property(AZ_IOT_ADU_CLIENT_AGENT_STATE_FAILED, &adu_update_request.workflow);
process_update_request = false;
}
}
}
}

Просмотреть файл

@ -637,7 +637,10 @@ static az_result base64_decode_jws_header_and_payload(jws_validation_context* ma
return AZ_OK;
}
static az_result validate_root_key(jws_validation_context* manifest_context)
static az_result validate_root_key(jws_validation_context* manifest_context,
SampleJWS::RootKey * root_keys,
uint32_t root_keys_length,
int32_t * adu_root_key_index)
{
az_result result;
az_json_reader json_reader;
@ -656,16 +659,16 @@ static az_result validate_root_key(jws_validation_context* manifest_context)
return AZ_ERROR_ITEM_NOT_FOUND;
}
if (!az_span_is_content_equal(
az_span_create(
(uint8_t*)azure_iot_adu_root_key_id, sizeof(azure_iot_adu_root_key_id) - 1),
manifest_context->kid_span))
for( int i = 0; i < root_keys_length; i++ )
{
Logger.Error("[JWS] Using the wrong root key");
return AZ_ERROR_NOT_SUPPORTED;
if( az_span_is_content_equal( root_keys[ i ].root_key_id, manifest_context->kid_span ) )
{
*adu_root_key_index = i;
return AZ_OK;
}
}
return AZ_OK;
return AZ_ERROR_NOT_SUPPORTED;
}
static az_result verify_sha_match(jws_validation_context* manifest_context, az_span manifest_span)
@ -748,11 +751,14 @@ static az_result verify_sha_match(jws_validation_context* manifest_context, az_s
az_result SampleJWS::ManifestAuthenticate(
az_span manifest_span,
az_span jws_span,
SampleJWS::RootKey * root_keys,
uint32_t root_keys_length,
az_span scratch_buffer_span)
{
az_result result;
az_json_reader json_reader;
jws_validation_context manifest_context = { 0 };
int32_t root_key_index;
/* Break up scratch buffer for reusable and persistent sections */
uint8_t* persistent_scratch_space_head = az_span_ptr(scratch_buffer_span);
@ -850,7 +856,12 @@ az_result SampleJWS::ManifestAuthenticate(
/*------------------- Parse root key id ------------------------*/
validate_root_key(&manifest_context);
result = validate_root_key(&manifest_context, root_keys, root_keys_length, &root_key_index );
if (az_result_failed(result))
{
Logger.Error("[JWS] validate_root_key failed: result " + String(result, HEX));
return result;
}
/*------------------- Parse necessary pieces for signing key
* ------------------------*/
@ -884,8 +895,8 @@ az_result SampleJWS::ManifestAuthenticate(
az_span_size(manifest_context.jwk_base64_encoded_header)
+ az_span_size(manifest_context.jwk_base64_encoded_payload) + 1),
manifest_context.jwk_signature,
az_span_create((uint8_t*)azure_iot_adu_root_key_n, sizeof(azure_iot_adu_root_key_n)),
az_span_create((uint8_t*)azure_iot_adu_root_key_e, sizeof(azure_iot_adu_root_key_e)),
root_keys[root_key_index].root_key_n,
root_keys[root_key_index].root_key_exponent,
manifest_context.scratch_calculation_buffer);
if (result != AZ_OK)

Просмотреть файл

@ -37,11 +37,24 @@
namespace SampleJWS
{
/**
* @brief Holds the values of the root key used to verify the JWS signature.
*/
typedef struct RootKey
{
az_span root_key_id;
az_span root_key_n;
az_span root_key_exponent;
} RootKey;
/**
* @brief Authenticate the manifest from ADU.
*
* @param[in] manifest_span The escaped manifest from the ADU twin property.
* @param[in] jws_span The JWS used to authenticate \p manifest_span.
* @param[in] root_keys An array of root keys that may be used to verify the payload.
* @param[in] root_keys_length The number of root keys in \p root_keys.
* @param[in] scratch_buffer_span Scratch buffer space for calculations. It
* should be `jwsSCRATCH_BUFFER_SIZE` in length.
* @return az_result The return value of this function.
@ -51,6 +64,8 @@ namespace SampleJWS
az_result ManifestAuthenticate(
az_span manifest_span,
az_span jws_span,
RootKey * root_keys,
uint32_t root_keys_length,
az_span scratch_buffer_span);
}; // namespace SampleJWS

Просмотреть файл

@ -1,9 +1,9 @@
name=Azure SDK for C
version=1.1.0-beta.1
version=1.1.0-beta.2
author=Microsoft Corporation
maintainer=Microsoft Corporation <aziotarduino@microsoft.com>
sentence=Azure SDK for C library for Arduino.
paragraph=This is an Arduino port of the Azure SDK for C (1.4.0-beta.1). It allows you to use your Arduino device with Azure services like Azure IoT Hub and Azure Device Provisioning Service. See README.md for more details. Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information.
paragraph=This is an Arduino port of the Azure SDK for C (1.4.0-beta.2). It allows you to use your Arduino device with Azure services like Azure IoT Hub and Azure Device Provisioning Service. See README.md for more details. Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information.
category=Communication
url=https://github.com/Azure/azure-sdk-for-c-arduino/releases
architectures=*

Просмотреть файл

@ -70,7 +70,7 @@ static az_result _az_http_policy_logging_append_http_request_msg(
}
else
{
required_length = az_span_size(request->_internal.method) + request->_internal.url_length + 1;
required_length += az_span_size(request->_internal.method) + request->_internal.url_length + 1;
}
_az_RETURN_IF_NOT_ENOUGH_SIZE(*ref_log_msg, required_length);

Просмотреть файл

@ -92,36 +92,6 @@
return AZ_ERROR_JSON_INVALID_STATE; \
}
const uint8_t azure_iot_adu_root_key_id[13] = "ADU.200702.R";
const uint8_t azure_iot_adu_root_key_n[385]
= { 0x00, 0xd5, 0x42, 0x2e, 0xaf, 0x11, 0x54, 0xa3, 0x50, 0x65, 0x87, 0xa2, 0x4d, 0x5b, 0xba,
0x1a, 0xfb, 0xa9, 0x32, 0xdf, 0xe9, 0x99, 0x5f, 0x05, 0x45, 0xc8, 0xaf, 0xbd, 0x35, 0x1d,
0x89, 0xe8, 0x27, 0x27, 0x58, 0xa3, 0xa8, 0xee, 0xc5, 0xc5, 0x1e, 0x4f, 0xf7, 0x92, 0xa6,
0x12, 0x06, 0x7d, 0x3d, 0x7d, 0xb0, 0x07, 0xf6, 0x2c, 0x7f, 0xde, 0x6d, 0x2a, 0xf5, 0xbc,
0x49, 0xbc, 0x15, 0xef, 0xf0, 0x81, 0xcb, 0x3f, 0x88, 0x4f, 0x27, 0x1d, 0x88, 0x71, 0x28,
0x60, 0x08, 0xb6, 0x19, 0xd2, 0xd2, 0x39, 0xd0, 0x05, 0x1f, 0x3c, 0x76, 0x86, 0x71, 0xbb,
0x59, 0x58, 0xbc, 0xb1, 0x88, 0x7b, 0xab, 0x56, 0x28, 0xbf, 0x31, 0x73, 0x44, 0x32, 0x10,
0xfd, 0x3d, 0xd3, 0x96, 0x5c, 0xff, 0x4e, 0x5c, 0xb3, 0x6b, 0xff, 0x8b, 0x84, 0x9b, 0x8b,
0x80, 0xb8, 0x49, 0xd0, 0x7d, 0xfa, 0xd6, 0x40, 0x58, 0x76, 0x4d, 0xc0, 0x72, 0x27, 0x75,
0xcb, 0x9a, 0x2f, 0x9b, 0xb4, 0x9f, 0x0f, 0x25, 0xf1, 0x1c, 0xc5, 0x1b, 0x0b, 0x5a, 0x30,
0x7d, 0x2f, 0xb8, 0xef, 0xa7, 0x26, 0x58, 0x53, 0xaf, 0xd5, 0x1d, 0x55, 0x01, 0x51, 0x0d,
0xe9, 0x1b, 0xa2, 0x0f, 0x3f, 0xd7, 0xe9, 0x1d, 0x20, 0x41, 0xa6, 0xe6, 0x14, 0x0a, 0xae,
0xfe, 0xf2, 0x1c, 0x2a, 0xd6, 0xe4, 0x04, 0x7b, 0xf6, 0x14, 0x7e, 0xec, 0x0f, 0x97, 0x83,
0xfa, 0x58, 0xfa, 0x81, 0x36, 0x21, 0xb9, 0xa3, 0x2b, 0xfa, 0xd9, 0x61, 0x0b, 0x1a, 0x94,
0xf7, 0xc1, 0xbe, 0x7f, 0x40, 0x14, 0x4a, 0xc9, 0xfa, 0x35, 0x7f, 0xef, 0x66, 0x70, 0x00,
0xb1, 0xfd, 0xdb, 0xd7, 0x61, 0x0d, 0x3b, 0x58, 0x74, 0x67, 0x94, 0x89, 0x75, 0x76, 0x96,
0x7c, 0x91, 0x87, 0xd2, 0x8e, 0x11, 0x97, 0xee, 0x7b, 0x87, 0x6c, 0x9a, 0x2f, 0x45, 0xd8,
0x65, 0x3f, 0x52, 0x70, 0x98, 0x2a, 0xcb, 0xc8, 0x04, 0x63, 0xf5, 0xc9, 0x47, 0xcf, 0x70,
0xf4, 0xed, 0x64, 0xa7, 0x74, 0xa5, 0x23, 0x8f, 0xb6, 0xed, 0xf7, 0x1c, 0xd3, 0xb0, 0x1c,
0x64, 0x57, 0x12, 0x5a, 0xa9, 0x81, 0x84, 0x1f, 0xa0, 0xe7, 0x50, 0x19, 0x96, 0xb4, 0x82,
0xb1, 0xac, 0x48, 0xe3, 0xe1, 0x32, 0x82, 0xcb, 0x40, 0x1f, 0xac, 0xc4, 0x59, 0xbc, 0x10,
0x34, 0x51, 0x82, 0xf9, 0x28, 0x8d, 0xa8, 0x1e, 0x9b, 0xf5, 0x79, 0x45, 0x75, 0xb2, 0xdc,
0x9a, 0x11, 0x43, 0x08, 0xbe, 0x61, 0xcc, 0x9a, 0xc4, 0xcb, 0x77, 0x36, 0xff, 0x83, 0xdd,
0xa8, 0x71, 0x4f, 0x51, 0x8e, 0x0e, 0x7b, 0x4d, 0xfa, 0x79, 0x98, 0x8d, 0xbe, 0xfc, 0x82,
0x7e, 0x40, 0x48, 0xa9, 0x12, 0x01, 0xa8, 0xd9, 0x7e, 0xf3, 0xa5, 0x1b, 0xf1, 0xfb, 0x90,
0x77, 0x3e, 0x40, 0x87, 0x18, 0xc9, 0xab, 0xd9, 0xf7, 0x79 };
const uint8_t azure_iot_adu_root_key_e[3] = { 0x01, 0x00, 0x01 };
const az_span default_compatibility_properties
= AZ_SPAN_LITERAL_FROM_STR(AZ_IOT_ADU_CLIENT_AGENT_DEFAULT_COMPATIBILITY_PROPERTIES);
@ -131,6 +101,17 @@ AZ_NODISCARD az_iot_adu_client_options az_iot_adu_client_options_default()
= default_compatibility_properties };
}
AZ_NODISCARD az_iot_adu_client_device_properties az_iot_adu_client_device_properties_default()
{
return (az_iot_adu_client_device_properties){ .manufacturer = AZ_SPAN_LITERAL_EMPTY,
.model = AZ_SPAN_LITERAL_EMPTY,
.custom_properties = NULL,
.adu_version = AZ_SPAN_LITERAL_EMPTY,
.delivery_optimization_agent_version
= AZ_SPAN_LITERAL_EMPTY,
.update_id = AZ_SPAN_LITERAL_EMPTY };
}
AZ_NODISCARD az_result
az_iot_adu_client_init(az_iot_adu_client* client, az_iot_adu_client_options* options)
{
@ -153,7 +134,7 @@ AZ_NODISCARD bool az_iot_adu_client_is_component_device_update(
AZ_SPAN_FROM_STR(AZ_IOT_ADU_CLIENT_AGENT_COMPONENT_NAME), component_name);
}
static az_result generate_step_id(az_span buffer, uint32_t step_index, az_span* step_id)
static az_result _generate_step_id(az_span buffer, uint32_t step_index, az_span* step_id)
{
az_result result;
*step_id = buffer;
@ -170,7 +151,7 @@ static az_result generate_step_id(az_span buffer, uint32_t step_index, az_span*
AZ_NODISCARD az_result az_iot_adu_client_get_agent_state_payload(
az_iot_adu_client* client,
az_iot_adu_client_device_properties* device_properties,
int32_t agent_state,
az_iot_adu_client_agent_state agent_state,
az_iot_adu_client_workflow* workflow,
az_iot_adu_client_install_result* last_install_result,
az_json_writer* ref_json_writer)
@ -282,7 +263,7 @@ AZ_NODISCARD az_result az_iot_adu_client_get_agent_state_payload(
for (int32_t i = 0; i < last_install_result->step_results_count; i++)
{
az_span step_id = AZ_SPAN_FROM_BUFFER(step_id_scratch_buffer);
_az_RETURN_IF_FAILED(generate_step_id(step_id, (uint32_t)i, &step_id));
_az_RETURN_IF_FAILED(_generate_step_id(step_id, (uint32_t)i, &step_id));
_az_RETURN_IF_FAILED(az_json_writer_append_property_name(ref_json_writer, step_id));
_az_RETURN_IF_FAILED(az_json_writer_append_begin_object(ref_json_writer));
@ -317,7 +298,7 @@ AZ_NODISCARD az_result az_iot_adu_client_get_agent_state_payload(
/* Fill the agent state. */
_az_RETURN_IF_FAILED(az_json_writer_append_property_name(
ref_json_writer, AZ_SPAN_FROM_STR(AZ_IOT_ADU_CLIENT_AGENT_PROPERTY_NAME_STATE)));
_az_RETURN_IF_FAILED(az_json_writer_append_int32(ref_json_writer, agent_state));
_az_RETURN_IF_FAILED(az_json_writer_append_int32(ref_json_writer, (int32_t)agent_state));
/* Fill the workflow. */
if (workflow != NULL && (az_span_ptr(workflow->id) != NULL && az_span_size(workflow->id) > 0))
@ -328,7 +309,7 @@ AZ_NODISCARD az_result az_iot_adu_client_get_agent_state_payload(
_az_RETURN_IF_FAILED(az_json_writer_append_property_name(
ref_json_writer, AZ_SPAN_FROM_STR(AZ_IOT_ADU_CLIENT_AGENT_PROPERTY_NAME_ACTION)));
_az_RETURN_IF_FAILED(az_json_writer_append_int32(ref_json_writer, workflow->action));
_az_RETURN_IF_FAILED(az_json_writer_append_int32(ref_json_writer, (int32_t)workflow->action));
_az_RETURN_IF_FAILED(az_json_writer_append_property_name(
ref_json_writer, AZ_SPAN_FROM_STR(AZ_IOT_ADU_CLIENT_AGENT_PROPERTY_NAME_ID)));
@ -406,8 +387,8 @@ AZ_NODISCARD az_result az_iot_adu_client_parse_service_properties(
AZ_SPAN_FROM_STR(AZ_IOT_ADU_CLIENT_AGENT_PROPERTY_NAME_ACTION)))
{
_az_RETURN_IF_FAILED(az_json_reader_next_token(ref_json_reader));
_az_RETURN_IF_FAILED(
az_json_token_get_int32(&ref_json_reader->token, &update_request->workflow.action));
_az_RETURN_IF_FAILED(az_json_token_get_int32(
&ref_json_reader->token, (int32_t*)&update_request->workflow.action));
}
else if (az_json_token_is_text_equal(
&ref_json_reader->token,
@ -472,6 +453,12 @@ AZ_NODISCARD az_result az_iot_adu_client_parse_service_properties(
{
RETURN_IF_JSON_TOKEN_NOT_TYPE(ref_json_reader, AZ_JSON_TOKEN_PROPERTY_NAME);
// If object isn't ended and we have reached max files allowed, next would overflow.
if (update_request->file_urls_count == _AZ_IOT_ADU_CLIENT_MAX_TOTAL_FILE_COUNT)
{
return AZ_ERROR_NOT_ENOUGH_SPACE;
}
update_request->file_urls[update_request->file_urls_count].id
= ref_json_reader->token.slice;
@ -498,7 +485,7 @@ AZ_NODISCARD az_result az_iot_adu_client_parse_service_properties(
AZ_NODISCARD az_result az_iot_adu_client_get_service_properties_response(
az_iot_adu_client* client,
int32_t version,
int32_t status,
az_iot_adu_client_request_decision status,
az_json_writer* ref_json_writer)
{
_az_PRECONDITION_NOT_NULL(client);
@ -514,7 +501,7 @@ AZ_NODISCARD az_result az_iot_adu_client_get_service_properties_response(
NULL,
ref_json_writer,
AZ_SPAN_FROM_STR(AZ_IOT_ADU_CLIENT_AGENT_PROPERTY_NAME_SERVICE),
status,
(int32_t)status,
version,
AZ_SPAN_EMPTY));
@ -621,6 +608,12 @@ AZ_NODISCARD az_result az_iot_adu_client_parse_update_manifest(
while (ref_json_reader->token.kind != AZ_JSON_TOKEN_END_ARRAY)
{
// If array isn't ended and we have reached max files allowed, next would overflow.
if (update_manifest->instructions.steps[step_index].files_count
== _AZ_IOT_ADU_CLIENT_MAX_FILE_COUNT_PER_STEP)
{
return AZ_ERROR_NOT_ENOUGH_SPACE;
}
uint32_t file_index = update_manifest->instructions.steps[step_index].files_count;
RETURN_IF_JSON_TOKEN_NOT_TYPE((ref_json_reader), AZ_JSON_TOKEN_STRING);
@ -756,6 +749,12 @@ AZ_NODISCARD az_result az_iot_adu_client_parse_update_manifest(
RETURN_IF_JSON_TOKEN_NOT_TYPE((ref_json_reader), AZ_JSON_TOKEN_PROPERTY_NAME);
// If object isn't ended and we have reached max files allowed, next would overflow.
if (files_index == _AZ_IOT_ADU_CLIENT_MAX_TOTAL_FILE_COUNT)
{
return AZ_ERROR_NOT_ENOUGH_SPACE;
}
update_manifest->files[files_index].id = ref_json_reader->token.slice;
_az_RETURN_IF_FAILED(az_json_reader_next_token(ref_json_reader));
@ -781,7 +780,7 @@ AZ_NODISCARD az_result az_iot_adu_client_parse_update_manifest(
_az_RETURN_IF_FAILED(az_json_reader_next_token(ref_json_reader));
RETURN_IF_JSON_TOKEN_NOT_TYPE((ref_json_reader), AZ_JSON_TOKEN_NUMBER);
_az_RETURN_IF_FAILED(az_json_token_get_uint32(
_az_RETURN_IF_FAILED(az_json_token_get_int64(
&ref_json_reader->token, &update_manifest->files[files_index].size_in_bytes));
}
else if (az_json_token_is_text_equal(

Просмотреть файл

@ -23,6 +23,7 @@
#include <az_result.h>
#include <az_span.h>
#include <az_iot_hub_client.h>
#include <az_iot_adu_internal.h>
#include <stdbool.h>
#include <stdint.h>
@ -37,7 +38,7 @@
/**
* @brief ADU Agent Version
*/
#define AZ_IOT_ADU_CLIENT_AGENT_VERSION "DU;agent/0.8.0-rc1-public-preview"
#define AZ_IOT_ADU_CLIENT_AGENT_VERSION "DU;agent/1.0.0"
/**
* @brief ADU PnP Component Name
@ -45,84 +46,45 @@
#define AZ_IOT_ADU_CLIENT_PROPERTIES_COMPONENT_NAME "deviceUpdate"
/**
* @brief ADU Service Response (Accepted)
* @brief Decision codes to accept or reject a received update deployment.
*/
#define AZ_IOT_ADU_CLIENT_REQUEST_ACCEPTED 200
typedef enum
{
/// ADU Service Response (Accept)
AZ_IOT_ADU_CLIENT_REQUEST_DECISION_ACCEPT = 200,
/// ADU Service Response (Reject)
AZ_IOT_ADU_CLIENT_REQUEST_DECISION_REJECT = 406
} az_iot_adu_client_request_decision;
/**
* @brief ADU Service Response (Rejected)
* @brief Agent states used to notify the ADU service of current state.
*/
#define AZ_IOT_ADU_CLIENT_REQUEST_REJECTED 406
typedef enum
{
/// ADU Agent State (Idle)
AZ_IOT_ADU_CLIENT_AGENT_STATE_IDLE = 0,
/// ADU Agent State (In Progress)
AZ_IOT_ADU_CLIENT_AGENT_STATE_DEPLOYMENT_IN_PROGRESS = 6,
/// ADU Agent State (Failed)
AZ_IOT_ADU_CLIENT_AGENT_STATE_FAILED = 255
} az_iot_adu_client_agent_state;
/**
* @brief ADU Service Action (Apply)
* @brief Actions specified by the service for the agent to process.
*/
#define AZ_IOT_ADU_CLIENT_SERVICE_ACTION_APPLY_DEPLOYMENT 3
/**
* @brief ADU Service Action (Cancel)
*/
#define AZ_IOT_ADU_CLIENT_SERVICE_ACTION_CANCEL 255
/**
* @brief ADU Agent State (Idle)
*/
#define AZ_IOT_ADU_CLIENT_AGENT_STATE_IDLE 0
/**
* @brief ADU Agent State (In Progress)
*/
#define AZ_IOT_ADU_CLIENT_AGENT_STATE_DEPLOYMENT_IN_PROGRESS 6
/**
* @brief ADU Agent State (Failed)
*/
#define AZ_IOT_ADU_CLIENT_AGENT_STATE_FAILED 255
/**
* @brief Maximum Number of Files Handled by this ADU Agent (Number of URLs)
*/
#define AZ_IOT_ADU_CLIENT_MAX_FILE_URL_COUNT 10
/**
* @brief Maximum Number of Files Handled by this ADU Agent (Steps)
*/
#define AZ_IOT_ADU_CLIENT_MAX_INSTRUCTIONS_STEPS 10
/**
* @brief Maximum Number of Files Handled by this ADU Agent (File Hashes)
*/
#define AZ_IOT_ADU_CLIENT_MAX_FILE_HASH_COUNT 2
/**
* @brief Maximum Number of Custom Device Properties
*/
#define AZ_IOT_ADU_CLIENT_MAX_DEVICE_CUSTOM_PROPERTIES 5
typedef enum
{
/// ADU Service Action (Apply)
AZ_IOT_ADU_CLIENT_SERVICE_ACTION_APPLY_DEPLOYMENT = 3,
/// ADU Service Action (Cancel)
AZ_IOT_ADU_CLIENT_SERVICE_ACTION_CANCEL = 255
} az_iot_adu_client_service_action;
/**
* @brief Default Agent Compatibility Properties
*/
#define AZ_IOT_ADU_CLIENT_AGENT_DEFAULT_COMPATIBILITY_PROPERTIES "manufacturer,model"
/* The following key is used to validate the Azure Device Update update manifest signature */
/* For more details, please see
* https://docs.microsoft.com/azure/iot-hub-device-update/device-update-security */
/**
* @brief The root key id used to identify the key.
*/
extern const uint8_t azure_iot_adu_root_key_id[13];
/**
* @brief The root key n (modulus) used to verify the manifest.
*/
extern const uint8_t azure_iot_adu_root_key_n[385];
/**
* @brief The root key e (exponent) used to verify the manifest.
*/
extern const uint8_t azure_iot_adu_root_key_e[3];
/**
* @brief Identity of the update request.
* @remark This version refers to the update request itself.
@ -155,11 +117,11 @@ typedef struct
/**
* An array holding the custom names for the device properties.
*/
az_span names[AZ_IOT_ADU_CLIENT_MAX_DEVICE_CUSTOM_PROPERTIES];
az_span names[_AZ_IOT_ADU_CLIENT_MAX_DEVICE_CUSTOM_PROPERTIES];
/**
* An array holding the custom values for the device properties.
*/
az_span values[AZ_IOT_ADU_CLIENT_MAX_DEVICE_CUSTOM_PROPERTIES];
az_span values[_AZ_IOT_ADU_CLIENT_MAX_DEVICE_CUSTOM_PROPERTIES];
/**
* The number of custom names and values.
*/
@ -168,6 +130,10 @@ typedef struct
/**
* @brief Holds the ADU agent device properties.
*
* az_iot_adu_client_device_properties_default() must be called to first initialize the
* device properties.
*
* @remarks These properties are used by the ADU service for matching
* update groups and verifying the current update deployed.
* https://docs.microsoft.com/azure/iot-hub-device-update/device-update-plug-and-play
@ -260,7 +226,7 @@ typedef struct
* The number of steps MUST match the number of steps in the
* update manifest for the resulting state to be property generated.
*/
az_iot_adu_client_step_result step_results[AZ_IOT_ADU_CLIENT_MAX_INSTRUCTIONS_STEPS];
az_iot_adu_client_step_result step_results[_AZ_IOT_ADU_CLIENT_MAX_INSTRUCTIONS_STEPS];
} az_iot_adu_client_install_result;
/**
@ -271,11 +237,9 @@ typedef struct
{
/**
* An integer that corresponds to an action the agent should perform.
* @remark Refer to the following defines for the expected values:
* AZ_IOT_ADU_CLIENT_SERVICE_ACTION_APPLY_DEPLOYMENT
* AZ_IOT_ADU_CLIENT_SERVICE_ACTION_CANCEL
* @remark Refer to the #az_iot_adu_client_service_action for possible values
*/
int32_t action;
az_iot_adu_client_service_action action;
/**
* ID of current deployment.
*/
@ -327,7 +291,7 @@ typedef struct
* Tells the agent which files to download and the hash to use to verify that the files
* were downloaded correctly.
*/
az_iot_adu_client_file_url file_urls[AZ_IOT_ADU_CLIENT_MAX_FILE_URL_COUNT];
az_iot_adu_client_file_url file_urls[_AZ_IOT_ADU_CLIENT_MAX_TOTAL_FILE_COUNT];
/**
* Number of items in \p file_urls.
*/
@ -359,7 +323,7 @@ typedef struct
/**
* Files related to this update step.
*/
az_span files[AZ_IOT_ADU_CLIENT_MAX_FILE_URL_COUNT];
az_span files[_AZ_IOT_ADU_CLIENT_MAX_FILE_COUNT_PER_STEP];
/**
* Number of items in \p files.
*/
@ -379,7 +343,7 @@ typedef struct
* Steps of the instructions in an update request.
*/
az_iot_adu_client_update_manifest_instructions_step
steps[AZ_IOT_ADU_CLIENT_MAX_INSTRUCTIONS_STEPS];
steps[_AZ_IOT_ADU_CLIENT_MAX_INSTRUCTIONS_STEPS];
/**
* Number of items in \p steps.
*/
@ -419,11 +383,11 @@ typedef struct
/**
* Size of a file, in bytes.
*/
uint32_t size_in_bytes;
int64_t size_in_bytes;
/**
* Hashes provided for a given file in the update request.
*/
az_iot_adu_client_update_manifest_file_hash hashes[AZ_IOT_ADU_CLIENT_MAX_FILE_HASH_COUNT];
az_iot_adu_client_update_manifest_file_hash hashes[_AZ_IOT_ADU_CLIENT_MAX_FILE_HASH_COUNT];
/**
* Number of items in \p hashes.
*/
@ -451,7 +415,7 @@ typedef struct
/**
* Download urls for the files referenced in the update manifest instructions.
*/
az_iot_adu_client_update_manifest_file files[AZ_IOT_ADU_CLIENT_MAX_FILE_URL_COUNT];
az_iot_adu_client_update_manifest_file files[_AZ_IOT_ADU_CLIENT_MAX_TOTAL_FILE_COUNT];
/**
* Number of items in \p files.
*/
@ -495,6 +459,15 @@ typedef struct
*/
AZ_NODISCARD az_iot_adu_client_options az_iot_adu_client_options_default();
/**
* @brief Gets the default #az_iot_adu_client_device_properties.
* @details Call this to obtain an initialized #az_iot_adu_client_device_properties structure that
* can be afterwards modified and passed to necessary APIs.
*
* @return #az_iot_adu_client_device_properties.
*/
AZ_NODISCARD az_iot_adu_client_device_properties az_iot_adu_client_device_properties_default();
/**
* @brief Initializes an Azure IoT ADU Client.
*
@ -532,7 +505,7 @@ AZ_NODISCARD bool az_iot_adu_client_is_component_device_update(
* as required by the ADU service.
* @param[in] agent_state An integer value indicating the current state of
* the ADU agent. Use the values defined by the
* AZ_IOT_ADU_CLIENT_AGENT_STATE macros in this header.
* #az_iot_adu_client_agent_state.
* Please see the ADU online documentation for more
* details.
* @param[in] workflow A pointer to a #az_iot_adu_client_workflow instance
@ -550,7 +523,7 @@ AZ_NODISCARD bool az_iot_adu_client_is_component_device_update(
AZ_NODISCARD az_result az_iot_adu_client_get_agent_state_payload(
az_iot_adu_client* client,
az_iot_adu_client_device_properties* device_properties,
int32_t agent_state,
az_iot_adu_client_agent_state agent_state,
az_iot_adu_client_workflow* workflow,
az_iot_adu_client_install_result* last_install_result,
az_json_writer* ref_json_writer);
@ -592,7 +565,7 @@ AZ_NODISCARD az_result az_iot_adu_client_parse_service_properties(
AZ_NODISCARD az_result az_iot_adu_client_get_service_properties_response(
az_iot_adu_client* client,
int32_t version,
int32_t status,
az_iot_adu_client_request_decision status,
az_json_writer* ref_json_writer);
/**

35
src/az_iot_adu_internal.h Normal file
Просмотреть файл

@ -0,0 +1,35 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// SPDX-License-Identifier: MIT
/*
* @note You MUST NOT use any symbols (macros, functions, structures, enums, etc.)
* prefixed with an underscore ('_') directly in your application code. These symbols
* are part of Azure SDK's internal implementation; we do not document these symbols
* and they are subject to change in future versions of the SDK which would break your code.
*/
// Maximum Number of Files Handled by this ADU Agent (per step)
// This must be no larger than #_AZ_IOT_ADU_CLIENT_MAX_TOTAL_FILE_COUNT.
#ifndef _AZ_IOT_ADU_CLIENT_MAX_FILE_COUNT_PER_STEP
#define _AZ_IOT_ADU_CLIENT_MAX_FILE_COUNT_PER_STEP 2
#endif // _AZ_IOT_ADU_CLIENT_MAX_FILE_COUNT_PER_STEP
// Maximum Number of Files Handled by this ADU Agent (total files for this deployment)
#ifndef _AZ_IOT_ADU_CLIENT_MAX_TOTAL_FILE_COUNT
#define _AZ_IOT_ADU_CLIENT_MAX_TOTAL_FILE_COUNT 2
#endif // _AZ_IOT_ADU_CLIENT_MAX_TOTAL_FILE_COUNT
// Maximum Number of Steps Handled by this ADU Agent
#ifndef _AZ_IOT_ADU_CLIENT_MAX_INSTRUCTIONS_STEPS
#define _AZ_IOT_ADU_CLIENT_MAX_INSTRUCTIONS_STEPS 2
#endif // _AZ_IOT_ADU_CLIENT_MAX_INSTRUCTIONS_STEPS
// Maximum Number of File Hashes Handled by this ADU Agent
#ifndef _AZ_IOT_ADU_CLIENT_MAX_FILE_HASH_COUNT
#define _AZ_IOT_ADU_CLIENT_MAX_FILE_HASH_COUNT 2
#endif // _AZ_IOT_ADU_CLIENT_MAX_FILE_HASH_COUNT
// Maximum Number of Custom Device Properties
#ifndef _AZ_IOT_ADU_CLIENT_MAX_DEVICE_CUSTOM_PROPERTIES
#define _AZ_IOT_ADU_CLIENT_MAX_DEVICE_CUSTOM_PROPERTIES 5
#endif // _AZ_IOT_ADU_CLIENT_MAX_DEVICE_CUSTOM_PROPERTIES

Просмотреть файл

@ -84,6 +84,7 @@ AZ_NODISCARD az_iot_provisioning_client_options az_iot_provisioning_client_optio
* @pre \p id_scope must be a valid span of size greater than 0.
* @pre \p registration_id must be a valid span of size greater than 0.
* @return An #az_result value indicating the result of the operation.
* @retval #AZ_OK The client was initialized successfully.
*/
AZ_NODISCARD az_result az_iot_provisioning_client_init(
az_iot_provisioning_client* client,
@ -106,6 +107,8 @@ AZ_NODISCARD az_result az_iot_provisioning_client_init(
* @pre \p mqtt_user_name must not be `NULL`.
* @pre \p mqtt_user_name_size must be greater than 0.
* @return An #az_result value indicating the result of the operation.
* @retval #AZ_OK The user name was created successfully.
* @retval #AZ_ERROR_NOT_ENOUGH_SPACE The buffer is too small.
*/
AZ_NODISCARD az_result az_iot_provisioning_client_get_user_name(
az_iot_provisioning_client const* client,
@ -127,6 +130,8 @@ AZ_NODISCARD az_result az_iot_provisioning_client_get_user_name(
* @pre \p mqtt_client_id must not be `NULL`.
* @pre \p mqtt_client_id_size must be greater than 0.
* @return An #az_result value indicating the result of the operation.
* @retval #AZ_OK The client id was created successfully.
* @retval #AZ_ERROR_NOT_ENOUGH_SPACE The buffer is too small.
*/
AZ_NODISCARD az_result az_iot_provisioning_client_get_client_id(
az_iot_provisioning_client const* client,
@ -164,6 +169,8 @@ AZ_NODISCARD az_result az_iot_provisioning_client_get_client_id(
* @pre \p signature must be a valid span of size greater than 0.
* @pre \p out_signature must not be `NULL`.
* @return An #az_result value indicating the result of the operation.
* @retval #AZ_OK The signature was created successfully.
* @retval #AZ_ERROR_NOT_ENOUGH_SPACE The buffer is too small.
*/
AZ_NODISCARD az_result az_iot_provisioning_client_sas_get_signature(
az_iot_provisioning_client const* client,
@ -194,7 +201,9 @@ AZ_NODISCARD az_result az_iot_provisioning_client_sas_get_signature(
* @pre \p token_expiration_epoch_time must be greater than 0.
* @pre \p mqtt_password must not be `NULL`.
* @pre \p mqtt_password_size must be greater than 0.
* @return An #az_result value indicating the result of the operation..
* @return An #az_result value indicating the result of the operation.
* @retval #AZ_OK The password was created successfully.
* @retval #AZ_ERROR_NOT_ENOUGH_SPACE The buffer is too small.
*/
AZ_NODISCARD az_result az_iot_provisioning_client_sas_get_password(
az_iot_provisioning_client const* client,
@ -347,6 +356,7 @@ typedef struct
* @pre \p received_payload must be a valid span of size greater than or equal to 0.
* @pre \p out_response must not be `NULL`.
* @return An #az_result value indicating the result of the operation.
* @retval #AZ_OK The topic and payload were parsed successfully.
* @retval #AZ_ERROR_IOT_TOPIC_NO_MATCH If the topic is not matching the expected format.
*/
AZ_NODISCARD az_result az_iot_provisioning_client_parse_received_topic_and_payload(
@ -391,6 +401,8 @@ AZ_INLINE bool az_iot_provisioning_client_operation_complete(
* @pre \p mqtt_topic must not be `NULL`.
* @pre \p mqtt_topic_size must be greater than 0.
* @return An #az_result value indicating the result of the operation.
* @retval #AZ_OK The topic was created successfully.
* @retval #AZ_ERROR_NOT_ENOUGH_SPACE The buffer is too small.
*/
AZ_NODISCARD az_result az_iot_provisioning_client_register_get_publish_topic(
az_iot_provisioning_client const* client,
@ -416,6 +428,8 @@ AZ_NODISCARD az_result az_iot_provisioning_client_register_get_publish_topic(
* @pre \p mqtt_topic must not be `NULL`.
* @pre \p mqtt_topic_size must be greater than 0.
* @return An #az_result value indicating the result of the operation.
* @retval #AZ_OK The topic was created successfully.
* @retval #AZ_ERROR_NOT_ENOUGH_SPACE The buffer is too small.
*/
AZ_NODISCARD az_result az_iot_provisioning_client_query_status_get_publish_topic(
az_iot_provisioning_client const* client,

Просмотреть файл

@ -17,7 +17,7 @@
/// The version in string format used for telemetry following the `semver.org` standard
/// (https://semver.org).
#define AZ_SDK_VERSION_STRING "1.4.0-beta.1"
#define AZ_SDK_VERSION_STRING "1.4.0-beta.2"
/// Major numeric identifier.
#define AZ_SDK_VERSION_MAJOR 1
@ -29,6 +29,6 @@
#define AZ_SDK_VERSION_PATCH 0
/// Optional pre-release identifier. SDK is in a pre-release state when present.
#define AZ_SDK_VERSION_PRERELEASE "beta.1"
#define AZ_SDK_VERSION_PRERELEASE "beta.2"
#endif //_az_VERSION_H

Просмотреть файл

@ -38,6 +38,5 @@ Write-Host "Updating versions."
# Update Arduino library version with SDK version.
$(gc -Raw $LibConfigFile) -replace "version=[0-9]\.[0-9]\.[0-9][a-zA-Z0-9.-]*", "version=$NewLibraryVersion" | out-file -Encoding ascii -Force -NoNewline $LibConfigFile
$(gc -Raw $LibConfigFile) -replace "\([0-9]\.[0-9]\.[0-9][^\)]*\)", "($SdkVersion)" | out-file -Encoding ascii -Force -NoNewline $LibConfigFile
$(gc -raw $LibConfigFile) -replace "url=[a-zA-Z0-9\/:.-]+", "url=https://github.com/Azure/azure-sdk-for-c/tree/$SdkVersion" | out-file -Encoding ascii -Force -NoNewline $LibConfigFile
Write-Host "You must manually update the library.properties with any new includes such as az_core.h, az_iot.h"