Changeset 464 for azure_iot_hub_f767zi/trunk/azure_iot_sdk
- Timestamp:
- Jun 22, 2021, 9:00:19 PM (3 years ago)
- Location:
- azure_iot_hub_f767zi/trunk/azure_iot_sdk
- Files:
-
- 42 edited
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
azure_iot_hub_f767zi/trunk/azure_iot_sdk/.vscode/c_cpp_properties.json
r457 r464 20 20 "${workspaceFolder}/../azure_iot_sdk/deps/parson", 21 21 "${workspaceFolder}/../azure_iot_sdk/umqtt/inc", 22 "${workspaceFolder}/../wolfssl-4. 4.0/wolfssl",23 "${workspaceFolder}/../wolfssl-4. 4.0/wolfssl/wolfcrypt",24 "${workspaceFolder}/../wolfssl-4. 4.0",22 "${workspaceFolder}/../wolfssl-4.7.0/wolfssl", 23 "${workspaceFolder}/../wolfssl-4.7.0/wolfssl/wolfcrypt", 24 "${workspaceFolder}/../wolfssl-4.7.0", 25 25 "${workspaceFolder}/../zlib-1.2.11/src" 26 26 ], -
azure_iot_hub_f767zi/trunk/azure_iot_sdk/Makefile
r457 r464 99 99 OBJECTS += certs/certs.o 100 100 OBJECTS += deps/parson/parson.o 101 OBJECTS += deps/uhttp/src/uhttp.o 101 102 OBJECTS += iothub_client/src/blob.o 102 103 OBJECTS += iothub_client/src/iothub.o … … 144 145 OBJECTS += serializer/src/codefirst.o 145 146 OBJECTS += serializer/src/commanddecoder.o 146 OBJECTS += uhttp/src/uhttp.o147 147 OBJECTS += umqtt/src/mqtt_client.o 148 148 OBJECTS += umqtt/src/mqtt_codec.o … … 171 171 INCLUDE_PATHS += -I../../azure_iot_sdk/deps/parson 172 172 INCLUDE_PATHS += -I../../azure_iot_sdk/deps/azure-macro-utils-c/inc 173 INCLUDE_PATHS += -I../../azure_iot_sdk/deps/uhttp/inc 173 174 INCLUDE_PATHS += -I../../azure_iot_sdk/deps/umock-c/inc 174 175 INCLUDE_PATHS += -I../../azure_iot_sdk/serializer/inc 175 INCLUDE_PATHS += -I../../azure_iot_sdk/uhttp/inc176 176 INCLUDE_PATHS += -I../../azure_iot_sdk/umqtt/inc 177 INCLUDE_PATHS += -I../../wolfssl-4. 4.0/wolfssl178 INCLUDE_PATHS += -I../../wolfssl-4. 4.0/wolfssl/wolfcrypt179 INCLUDE_PATHS += -I../../wolfssl-4. 4.0177 INCLUDE_PATHS += -I../../wolfssl-4.7.0/wolfssl 178 INCLUDE_PATHS += -I../../wolfssl-4.7.0/wolfssl/wolfcrypt 179 INCLUDE_PATHS += -I../../wolfssl-4.7.0 180 180 INCLUDE_PATHS += -I../../zlib-1.2.11/src 181 181 -
azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/adapters/httpapi_compact.c
r457 r464 51 51 char* x509ClientCertificate; 52 52 char* x509ClientPrivateKey; 53 const char* proxy_host;54 int proxy_port;55 const char* proxy_username;56 const char* proxy_password;57 53 XIO_HANDLE xio_handle; 58 54 size_t received_bytes_count; … … 205 201 { 206 202 HTTP_HANDLE_DATA* http_instance; 203 TLSIO_CONFIG tlsio_config; 207 204 208 205 if (hostName == NULL) … … 226 223 LogError("There is no memory to control the http connection"); 227 224 } 228 else if (mallocAndStrcpy_s((char**)&(http_instance->hostName), hostName) != 0)229 { 230 LogError(" failure allocate hostname");225 else if (mallocAndStrcpy_s(&http_instance->hostName, hostName) != 0) 226 { 227 LogError("Failed copying hostname"); 231 228 free(http_instance); 232 229 http_instance = NULL; … … 234 231 else 235 232 { 236 http_instance->xio_handle = NULL; 237 http_instance->is_connected = 0; 238 http_instance->is_io_error = 0; 239 http_instance->received_bytes_count = 0; 240 http_instance->received_bytes = NULL; 241 http_instance->certificate = NULL; 242 http_instance->x509ClientCertificate = NULL; 243 http_instance->x509ClientPrivateKey = NULL; 244 http_instance->proxy_host = NULL; 245 http_instance->proxy_port = 0; 246 http_instance->proxy_username = NULL; 247 http_instance->proxy_password = NULL; 233 tlsio_config.hostname = http_instance->hostName; 234 tlsio_config.port = 443; 235 tlsio_config.underlying_io_interface = NULL; 236 tlsio_config.underlying_io_parameters = NULL; 237 238 http_instance->xio_handle = xio_create(platform_get_default_tlsio(), (void*)&tlsio_config); 239 240 /*Codes_SRS_HTTPAPI_COMPACT_21_016: [ If the HTTPAPI_CreateConnection failed to create the connection, it shall return NULL as the handle. ]*/ 241 if (http_instance->xio_handle == NULL) 242 { 243 LogError("Create connection failed"); 244 free(http_instance->hostName); 245 free(http_instance); 246 http_instance = NULL; 247 } 248 else 249 { 250 http_instance->is_connected = 0; 251 http_instance->is_io_error = 0; 252 http_instance->received_bytes_count = 0; 253 http_instance->received_bytes = NULL; 254 http_instance->certificate = NULL; 255 http_instance->x509ClientCertificate = NULL; 256 http_instance->x509ClientPrivateKey = NULL; 257 } 248 258 } 249 259 } … … 311 321 } 312 322 313 if (http_instance->hostName != NULL)314 {315 free((void*)http_instance->hostName);316 }317 318 323 #ifndef DO_NOT_COPY_TRUSTED_CERTS_STRING 319 324 /*Codes_SRS_HTTPAPI_COMPACT_21_018: [ If there is a certificate associated to this connection, the HTTPAPI_CloseConnection shall free all allocated memory for the certificate. ]*/ … … 336 341 } 337 342 338 if (http_instance->proxy_host != NULL) 339 { 340 free((void*)http_instance->proxy_host); 341 } 342 if (http_instance->proxy_username != NULL) 343 { 344 free((void*)http_instance->proxy_username); 345 } 346 if (http_instance->proxy_password != NULL) 347 { 348 free((void*)http_instance->proxy_password); 343 if (http_instance->hostName) 344 { 345 free(http_instance->hostName); 349 346 } 350 347 … … 714 711 { 715 712 HTTPAPI_RESULT result; 716 TLSIO_CONFIG tlsio_config;717 HTTP_PROXY_IO_CONFIG http_proxy_io_config;718 713 719 714 if (http_instance->is_connected != 0) … … 725 720 { 726 721 http_instance->is_io_error = 0; 727 tlsio_config.hostname = http_instance->hostName; 728 tlsio_config.port = 443; 729 730 if (http_instance->proxy_host != NULL) { 731 tlsio_config.underlying_io_interface = http_proxy_io_get_interface_description(); 732 } 733 else { 734 tlsio_config.underlying_io_interface = NULL; 735 } 736 737 if (tlsio_config.underlying_io_interface != NULL) { 738 tlsio_config.underlying_io_parameters = (void*)&http_proxy_io_config; 739 740 http_proxy_io_config.proxy_hostname = http_instance->proxy_host; 741 http_proxy_io_config.proxy_port = http_instance->proxy_port; 742 http_proxy_io_config.username = http_instance->proxy_username; 743 http_proxy_io_config.password = http_instance->proxy_password; 744 http_proxy_io_config.hostname = http_instance->hostName; 745 http_proxy_io_config.port = 443; 746 } 747 else { 748 tlsio_config.underlying_io_parameters = NULL; 749 } 750 751 http_instance->xio_handle = xio_create(platform_get_default_tlsio(), (void*)&tlsio_config); 752 753 if (http_instance->xio_handle == NULL) 754 { 755 LogError("Create connection failed"); 756 free(http_instance); 757 http_instance = NULL; 758 result = HTTPAPI_ERROR; 759 } 722 760 723 /*Codes_SRS_HTTPAPI_COMPACT_21_022: [ If a Certificate was provided, the HTTPAPI_ExecuteRequest shall set this option on the transport layer. ]*/ 761 elseif ((http_instance->certificate != NULL) &&724 if ((http_instance->certificate != NULL) && 762 725 (xio_setoption(http_instance->xio_handle, OPTION_TRUSTED_CERT, http_instance->certificate) != 0)) 763 726 { … … 777 740 (xio_setoption(http_instance->xio_handle, SU_OPTION_X509_PRIVATE_KEY, http_instance->x509ClientPrivateKey) != 0)) 778 741 { 742 779 743 /*Codes_SRS_HTTPAPI_COMPACT_06_006: [ If the transport failed setting the client certificate private key, the HTTPAPI_ExecuteRequest shall not send any request and return HTTPAPI_SET_OPTION_FAILED. ] */ 780 744 result = HTTPAPI_SET_OPTION_FAILED; … … 800 764 { 801 765 xio_dowork(http_instance->xio_handle); 802 //LogInfo("Waiting for TLS connection");766 LogInfo("Waiting for TLS connection"); 803 767 if ((countRetry--) < 0) 804 768 { … … 1347 1311 #endif // DO_NOT_COPY_TRUSTED_CERTS_STRING 1348 1312 } 1349 else if (strcmp(SU_OPTION_X509_CERT, optionName) == 0 )1313 else if (strcmp(SU_OPTION_X509_CERT, optionName) == 0 || strcmp(OPTION_X509_ECC_CERT, optionName) == 0) 1350 1314 { 1351 1315 int len; … … 1370 1334 } 1371 1335 } 1372 else if (strcmp(SU_OPTION_X509_PRIVATE_KEY, optionName) == 0 )1336 else if (strcmp(SU_OPTION_X509_PRIVATE_KEY, optionName) == 0 || strcmp(OPTION_X509_ECC_KEY, optionName) == 0) 1373 1337 { 1374 1338 int len; … … 1395 1359 else if (strcmp(OPTION_HTTP_PROXY, optionName) == 0) 1396 1360 { 1397 HTTP_PROXY_OPTIONS* proxy_data = (HTTP_PROXY_OPTIONS*)value; 1398 if (proxy_data->host_address == NULL || proxy_data->port <= 0) 1399 { 1400 LogError("invalid proxy_data values ( host_address = %p, port = %d)", proxy_data->host_address, proxy_data->port); 1361 TLSIO_CONFIG tlsio_config; 1362 HTTP_PROXY_IO_CONFIG proxy_config; 1363 HTTP_PROXY_OPTIONS* proxy_options = (HTTP_PROXY_OPTIONS*)value; 1364 1365 if (proxy_options->host_address == NULL) 1366 { 1367 LogError("NULL host_address in proxy options"); 1401 1368 result = HTTPAPI_ERROR; 1402 1369 } 1370 else if (((proxy_options->username == NULL) || (proxy_options->password == NULL)) && 1371 (proxy_options->username != proxy_options->password)) 1372 { 1373 LogError("Only one of username and password for proxy settings was NULL"); 1374 result = HTTPAPI_ERROR; 1375 } 1403 1376 else 1404 1377 { 1405 if(http_instance->proxy_host != NULL) 1406 {1407 free((void*)http_instance->proxy_host);1408 http_instance->proxy_host = NULL;1409 }1410 if (mallocAndStrcpy_s((char**)&(http_instance->proxy_host), (const char*)proxy_data->host_address) != 0)1411 { 1412 LogError("fail ure allocate proxy host");1378 1379 /* Workaround: xio interface is already created when HTTPAPI_CreateConnection is call without proxy support 1380 * need to destroy the interface and create a new one with proxy information 1381 */ 1382 OPTIONHANDLER_HANDLE xio_options; 1383 if ((xio_options = xio_retrieveoptions(http_instance->xio_handle)) == NULL) 1384 { 1385 LogError("failed saving underlying I/O transport options"); 1413 1386 result = HTTPAPI_ERROR; 1414 1387 } 1415 1388 else 1416 1389 { 1417 http_instance->proxy_port = proxy_data->port; 1418 1419 if (proxy_data->username != NULL && proxy_data->password != NULL) 1420 { 1421 if(http_instance->proxy_username != NULL) 1390 xio_destroy(http_instance->xio_handle); 1391 1392 proxy_config.hostname = http_instance->hostName; 1393 proxy_config.proxy_hostname = proxy_options->host_address; 1394 proxy_config.password = proxy_options->password; 1395 proxy_config.username = proxy_options->username; 1396 proxy_config.proxy_port = proxy_options->port; 1397 proxy_config.port = 443; 1398 1399 tlsio_config.hostname = http_instance->hostName; 1400 tlsio_config.port = 443; 1401 tlsio_config.underlying_io_interface = http_proxy_io_get_interface_description(); 1402 tlsio_config.underlying_io_parameters = &proxy_config; 1403 1404 http_instance->xio_handle = xio_create(platform_get_default_tlsio(), (void*)&tlsio_config); 1405 1406 if (http_instance->xio_handle == NULL) 1407 { 1408 LogError("Failed to create xio handle with proxy configuration"); 1409 result = HTTPAPI_ERROR; 1410 } 1411 else 1412 { 1413 if (OptionHandler_FeedOptions(xio_options, http_instance->xio_handle) != OPTIONHANDLER_OK) 1422 1414 { 1423 free((void*)http_instance->proxy_username); 1424 http_instance->proxy_username = NULL; 1425 } 1426 if(mallocAndStrcpy_s((char**)&(http_instance->proxy_username), (const char*)proxy_data->username) != 0) 1427 { 1428 LogError("failure allocate proxy username"); 1429 free((void*)http_instance->proxy_host); 1430 http_instance->proxy_host = NULL; 1415 LogError("Failed feeding existing options to new xio instance."); 1431 1416 result = HTTPAPI_ERROR; 1432 1417 } 1433 1418 else 1434 1419 { 1435 if(http_instance->proxy_password != NULL) 1436 { 1437 free((void*)http_instance->proxy_password); 1438 http_instance->proxy_password = NULL; 1439 } 1440 if(mallocAndStrcpy_s((char**)&(http_instance->proxy_password), (const char*)proxy_data->password) != 0) 1441 { 1442 LogError("failure allocate proxy password"); 1443 free((void*)http_instance->proxy_host); 1444 http_instance->proxy_host = NULL; 1445 free((void*)http_instance->proxy_username); 1446 http_instance->proxy_username = NULL; 1447 result = HTTPAPI_ERROR; 1448 } 1449 else 1450 { 1451 result = HTTPAPI_OK; 1452 } 1420 result = HTTPAPI_OK; 1453 1421 } 1454 1422 } 1455 else 1456 { 1457 result = HTTPAPI_OK; 1458 } 1423 1424 OptionHandler_Destroy(xio_options); 1459 1425 } 1460 1426 } … … 1466 1432 LogInfo("unknown option %s", optionName); 1467 1433 } 1434 1468 1435 return result; 1469 1436 } … … 1510 1477 #endif // DO_NOT_COPY_TRUSTED_CERTS_STRING 1511 1478 } 1512 else if (strcmp(SU_OPTION_X509_CERT, optionName) == 0 )1479 else if (strcmp(SU_OPTION_X509_CERT, optionName) == 0 || strcmp(OPTION_X509_ECC_CERT, optionName) == 0) 1513 1480 { 1514 1481 certLen = strlen((const char*)value); … … 1527 1494 } 1528 1495 } 1529 else if (strcmp(SU_OPTION_X509_PRIVATE_KEY, optionName) == 0 )1496 else if (strcmp(SU_OPTION_X509_PRIVATE_KEY, optionName) == 0 || strcmp(OPTION_X509_ECC_KEY, optionName) == 0) 1530 1497 { 1531 1498 certLen = strlen((const char*)value); -
azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/adapters/platform_toppers.c
r457 r464 52 52 const IO_INTERFACE_DESCRIPTION* platform_get_default_tlsio(void) 53 53 { 54 //return tlsio_esp_at_get_interface_description();55 return tlsio_wolfssl_get_interface_description();54 return tlsio_esp_at_get_interface_description(); 55 //return tlsio_wolfssl_get_interface_description(); 56 56 } 57 57 -
azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/adapters/tlsio_wolfssl.c
r457 r464 19 19 #include "azure_c_shared_utility/xlogging.h" 20 20 #include "azure_c_shared_utility/shared_util_options.h" 21 #include "azure_c_shared_utility/threadapi.h"22 21 23 22 typedef enum TLSIO_STATE_ENUM_TAG … … 53 52 char* x509privatekey; 54 53 int wolfssl_device_id; 55 size_t socket_reads; 54 char* hostname; 55 bool ignore_host_name_check; 56 56 } TLS_IO_INSTANCE; 57 57 58 58 STATIC_VAR_UNUSED const char* const OPTION_WOLFSSL_SET_DEVICE_ID = "SetDeviceId"; 59 static const size_t SOCKET_READ_LIMIT = 10000; // 10,000 ms ?59 static const size_t SOCKET_READ_LIMIT = 5; 60 60 61 61 /*this function will clone an option given by name and value*/ … … 106 106 } 107 107 } 108 #ifdef INVALID_DEVID 109 else if(strcmp(name, OPTION_WOLFSSL_SET_DEVICE_ID) == 0 ) 110 { 111 int* value_clone; 112 113 if ((value_clone = malloc(sizeof(int))) == NULL) 114 { 115 LogError("unable to clone device id option"); 116 } 117 else 118 { 119 *value_clone = *(int*)value; 120 } 121 122 result = value_clone; 123 } 124 #endif 108 125 else 109 126 { … … 127 144 if ((strcmp(name, OPTION_TRUSTED_CERT) == 0) || 128 145 (strcmp(name, SU_OPTION_X509_CERT) == 0) || 129 (strcmp(name, SU_OPTION_X509_PRIVATE_KEY) == 0)) 146 (strcmp(name, SU_OPTION_X509_PRIVATE_KEY) == 0) || 147 (strcmp(name, OPTION_WOLFSSL_SET_DEVICE_ID) == 0)) 130 148 { 131 149 free((void*)value); … … 185 203 result = NULL; 186 204 } 205 #ifdef INVALID_DEVID 206 else if ( 207 (tls_io_instance->wolfssl_device_id != INVALID_DEVID) && 208 (OptionHandler_AddOption(result, OPTION_WOLFSSL_SET_DEVICE_ID, &tls_io_instance->wolfssl_device_id) != OPTIONHANDLER_OK) 209 ) 210 { 211 LogError("unable to save deviceid option"); 212 OptionHandler_Destroy(result); 213 result = NULL; 214 } 215 #endif 187 216 else 188 217 { … … 258 287 int res; 259 288 tls_io_instance->tlsio_state = TLSIO_STATE_IN_HANDSHAKE; 260 tls_io_instance->socket_reads = 0;261 289 262 290 res = wolfSSL_connect(tls_io_instance->ssl); 263 291 if (res != SSL_SUCCESS) 264 292 { 265 LogError("WolfSSL connect failed"); 293 // Error codes explained in https://www.wolfssl.com/docs/wolfssl-manual/appendix-c/ 294 LogError("WolfSSL connect failed (%d)", wolfSSL_get_error(tls_io_instance->ssl, res)); 266 295 indicate_open_complete(tls_io_instance, IO_OPEN_ERROR); 267 296 tls_io_instance->tlsio_state = TLSIO_STATE_ERROR; … … 355 384 TLS_IO_INSTANCE* tls_io_instance = (TLS_IO_INSTANCE*)context; 356 385 unsigned char* new_socket_io_read_bytes; 386 size_t socket_reads = 0; 357 387 358 388 AZURE_UNREFERENCED_PARAMETER(ssl); 359 if (tls_io_instance->socket_io_read_byte_count == 0) 360 { 361 if (tls_io_instance->socket_reads >= SOCKET_READ_LIMIT) { 362 return WOLFSSL_CBIO_ERR_TIMEOUT; 363 } 389 while (tls_io_instance->socket_io_read_byte_count == 0 && socket_reads < SOCKET_READ_LIMIT) 390 { 364 391 xio_dowork(tls_io_instance->socket_io); 365 if (tls_io_instance->tlsio_state == TLSIO_STATE_IN_HANDSHAKE) 366 { 367 tls_io_instance->socket_reads++; 368 ThreadAPI_Sleep(1); 369 return 0; 370 } 392 if (tls_io_instance->tlsio_state != TLSIO_STATE_IN_HANDSHAKE) 393 { 394 break; 395 } 396 socket_reads++; 371 397 } 372 398 … … 417 443 } 418 444 419 static void on_send_complete(void* context, IO_SEND_RESULT send_result)420 {421 TLS_IO_INSTANCE* tls_io_instance = (TLS_IO_INSTANCE*)context;422 if ((tls_io_instance == NULL) || (tls_io_instance->on_send_complete == NULL))423 return;424 425 tls_io_instance->on_send_complete(tls_io_instance->on_send_complete_callback_context, send_result);426 427 tls_io_instance->on_send_complete = NULL;428 tls_io_instance->on_send_complete_callback_context = NULL;429 }430 431 445 static int on_io_send(WOLFSSL *ssl, char *buf, int sz, void *context) 432 446 { 433 int result , ret;447 int result; 434 448 AZURE_UNREFERENCED_PARAMETER(ssl); 435 449 436 450 TLS_IO_INSTANCE* tls_io_instance = (TLS_IO_INSTANCE*)context; 437 451 438 if ( (ret = xio_send(tls_io_instance->socket_io, buf, sz, on_send_complete, tls_io_instance)) != 0)439 { 440 LogError("Failed sending bytes through underlying IO %d", ret);452 if (xio_send(tls_io_instance->socket_io, buf, sz, tls_io_instance->on_send_complete, tls_io_instance->on_send_complete_callback_context) != 0) 453 { 454 LogError("Failed sending bytes through underlying IO"); 441 455 tls_io_instance->tlsio_state = TLSIO_STATE_ERROR; 442 456 indicate_error(tls_io_instance); 443 result = 0;457 result = WOLFSSL_CBIO_ERR_GENERAL; 444 458 } 445 459 else … … 455 469 AZURE_UNREFERENCED_PARAMETER(ssl); 456 470 TLS_IO_INSTANCE* tls_io_instance = (TLS_IO_INSTANCE*)context; 457 if (tls_io_instance->tlsio_state == TLSIO_STATE_OPEN) { 458 LogInfo("on_handshake_done called in TLSIO_STATE_OPEN state"); 459 } 460 else if (tls_io_instance->tlsio_state != TLSIO_STATE_IN_HANDSHAKE) 471 if (tls_io_instance->tlsio_state != TLSIO_STATE_IN_HANDSHAKE) 461 472 { 462 473 LogInfo("on_handshake_done called when not in IN_HANDSHAKE state"); … … 558 569 } 559 570 571 static int enable_domain_check(TLS_IO_INSTANCE* tls_io_instance) 572 { 573 int result = 0; 574 575 if (!tls_io_instance->ignore_host_name_check) 576 { 577 if (wolfSSL_check_domain_name(tls_io_instance->ssl, tls_io_instance->hostname) != WOLFSSL_SUCCESS) 578 { 579 result = MU_FAILURE; 580 } 581 } 582 583 return result; 584 } 585 560 586 static int prepare_wolfssl_open(TLS_IO_INSTANCE* tls_io_instance) 561 587 { 562 588 int result; 563 if (add_certificate_to_store(tls_io_instance) != 0) 589 590 if (enable_domain_check(tls_io_instance)) 591 { 592 LogError("Failed to configure domain name verification"); 593 result = MU_FAILURE; 594 } 595 else if (add_certificate_to_store(tls_io_instance) != 0) 564 596 { 565 597 LogError("Failed to add certificates to store"); … … 575 607 result = MU_FAILURE; 576 608 } 577 #ifdef INVALID_DEVID578 else if (tls_io_instance->wolfssl_device_id != INVALID_DEVID && wolfSSL_SetDevId(tls_io_instance->ssl, tls_io_instance->wolfssl_device_id) != WOLFSSL_SUCCESS)579 {580 LogError("Failure setting device id");581 result = MU_FAILURE;582 }583 #endif584 609 else 585 610 { … … 628 653 { 629 654 LogError("Cannot create the wolfSSL context"); 655 free(result); 656 result = NULL; 657 } 658 else if (mallocAndStrcpy_s(&result->hostname, tls_io_config->hostname) != 0) 659 { 660 LogError("Failed copying the target hostname."); 630 661 free(result); 631 662 result = NULL; … … 660 691 LogError("Failed getting socket IO interface description."); 661 692 wolfSSL_CTX_free(result->ssl_context); 693 free(result->hostname); 662 694 free(result); 663 695 result = NULL; … … 670 702 LogError("Failure connecting to underlying socket_io"); 671 703 wolfSSL_CTX_free(result->ssl_context); 704 free(result->hostname); 672 705 free(result); 673 706 result = NULL; … … 677 710 LogError("Failure connecting to underlying socket_io"); 678 711 wolfSSL_CTX_free(result->ssl_context); 712 free(result->hostname); 679 713 free(result); 680 714 result = NULL; … … 719 753 720 754 xio_destroy(tls_io_instance->socket_io); 755 free(tls_io_instance->hostname); 721 756 free(tls_io); 722 757 } … … 843 878 result = MU_FAILURE; 844 879 } 845 if (tls_io_instance->on_send_complete != NULL)846 {847 LogError("Error writing data");848 result = MU_FAILURE;849 }850 880 else 851 881 { … … 882 912 (tls_io_instance->tlsio_state != TLSIO_STATE_ERROR)) 883 913 { 884 if (tls_io_instance->tlsio_state != TLSIO_STATE_OPENING_UNDERLYING_IO) 885 decode_ssl_received_bytes(tls_io_instance); 914 decode_ssl_received_bytes(tls_io_instance); 886 915 xio_dowork(tls_io_instance->socket_io); 887 916 } … … 892 921 static int process_option(char** destination, const char* name, const char* value) 893 922 { 923 924 (void) name; 925 894 926 int result; 895 927 if (*destination != NULL) … … 944 976 { 945 977 int device_id = *((int *)value); 946 if (tls_io_instance->ssl != NULL) 947 { 948 if (tls_io_instance->ssl != NULL && wolfSSL_SetDevId(tls_io_instance->ssl, device_id) != WOLFSSL_SUCCESS) 949 { 950 LogError("Failure setting device id on ssl"); 951 result = MU_FAILURE; 952 } 953 else 954 { 955 result = 0; 956 } 978 if (tls_io_instance->ssl != NULL && wolfSSL_SetDevId(tls_io_instance->ssl, device_id) != WOLFSSL_SUCCESS) 979 { 980 LogError("Failure setting device id on ssl"); 981 result = MU_FAILURE; 957 982 } 958 983 else 959 984 { 960 // Save the id till we create the ssl object985 // Save the device Id even if ssl object not yet created. 961 986 tls_io_instance->wolfssl_device_id = device_id; 962 987 result = 0; … … 964 989 } 965 990 #endif 991 else if (strcmp("ignore_host_name_check", optionName) == 0) 992 { 993 bool* server_name_check = (bool*)value; 994 tls_io_instance->ignore_host_name_check = *server_name_check; 995 result = 0; 996 } 966 997 else 967 998 { -
azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/crt_abstractions.h
r457 r464 6 6 7 7 #ifdef __cplusplus 8 #include <cstdint> 8 9 #include <cstdio> 9 10 #include <cstring> … … 11 12 #include <cmath> 12 13 #else // __cplusplus 14 #include <stdint.h> 13 15 #include <stdio.h> 14 16 #include <string.h> … … 96 98 MOCKABLE_FUNCTION(, int, unsignedIntToString, char*, destination, size_t, destinationSize, unsigned int, value); 97 99 MOCKABLE_FUNCTION(, int, size_tToString, char*, destination, size_t, destinationSize, size_t, value); 100 MOCKABLE_FUNCTION(, int, uint64_tToString, char*, destination, size_t, destinationSize, uint64_t, value); 98 101 99 102 /*following logic shall define the TOUPPER and ISDIGIT, we do that because the SDK is not happy with some Arduino implementation of it.*/ -
azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/sastoken.h
r457 r464 4 4 #ifndef SASTOKEN_H 5 5 #define SASTOKEN_H 6 7 #include <stdint.h> 6 8 7 9 #ifdef __cplusplus … … 18 20 19 21 MOCKABLE_FUNCTION(, bool, SASToken_Validate, STRING_HANDLE, sasToken); 20 MOCKABLE_FUNCTION(, STRING_HANDLE, SASToken_Create, STRING_HANDLE, key, STRING_HANDLE, scope, STRING_HANDLE, keyName, size_t, expiry);21 MOCKABLE_FUNCTION(, STRING_HANDLE, SASToken_CreateString, const char*, key, const char*, scope, const char*, keyName, size_t, expiry);22 MOCKABLE_FUNCTION(, STRING_HANDLE, SASToken_Create, STRING_HANDLE, key, STRING_HANDLE, scope, STRING_HANDLE, keyName, uint64_t, expiry); 23 MOCKABLE_FUNCTION(, STRING_HANDLE, SASToken_CreateString, const char*, key, const char*, scope, const char*, keyName, uint64_t, expiry); 22 24 23 25 #ifdef __cplusplus -
azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/shared_util_options.h
r457 r464 29 29 static STATIC_VAR_UNUSED const char* const OPTION_OPENSSL_CIPHER_SUITE = "CipherSuite"; 30 30 31 static STATIC_VAR_UNUSED const char* const OPTION_OPENSSL_ENGINE = "Engine"; 32 static STATIC_VAR_UNUSED const char* const OPTION_OPENSSL_PRIVATE_KEY_TYPE = "x509PrivatekeyType"; 33 34 typedef enum OPTION_OPENSSL_KEY_TYPE_TAG 35 { 36 KEY_TYPE_DEFAULT, 37 KEY_TYPE_ENGINE 38 } OPTION_OPENSSL_KEY_TYPE; 39 31 40 static STATIC_VAR_UNUSED const char* const SU_OPTION_X509_CERT = "x509certificate"; 32 41 static STATIC_VAR_UNUSED const char* const SU_OPTION_X509_PRIVATE_KEY = "x509privatekey"; … … 45 54 static STATIC_VAR_UNUSED const char* const OPTION_SET_TLS_RENEGOTIATION = "tls_renegotiation"; 46 55 47 // DEPRECATED: The underlying security library for your platform will use a secure TLS version 56 // DEPRECATED: The underlying security library for your platform will use a secure TLS version 48 57 // that in general should not be overridden with OPTION_TLS_VERSION. 49 58 static STATIC_VAR_UNUSED const char* const OPTION_TLS_VERSION = "tls_version"; -
azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/inc/azure_c_shared_utility/tickcounter.h
r457 r464 18 18 #endif /* __cplusplus */ 19 19 20 #if defined(_WIN32) || defined(__MBED__) || defined(__APPLE__)21 20 typedef uint_fast64_t tickcounter_ms_t; // Use 64-bit because of 32-bit is going to roll over back to zero after roughly 49.7 days that is not good for IoT devices which need keep running for months 22 #else23 typedef uint_fast32_t tickcounter_ms_t;24 #endif25 21 typedef struct TICK_COUNTER_INSTANCE_TAG *TICK_COUNTER_HANDLE; 26 22 -
azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/buffer.c
r457 r464 541 541 { 542 542 //put b2 ahead of b1: [b2][b1], return b1 543 if (b2->size == 0)543 if (b2->size == 0) 544 544 { 545 545 // do nothing 546 546 result = 0; 547 } 548 else if (b1->size + b2->size < b2->size) 549 { 550 LogError("Failure: size_t overflow."); 551 result = MU_FAILURE; 547 552 } 548 553 else -
azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/crt_abstractions.c
r457 r464 6 6 #include <stdlib.h> 7 7 #include <stdarg.h> 8 #include <stdint.h> 8 9 #include <string.h> 9 10 #include <limits.h> … … 598 599 case FST_NUMBER: 599 600 val = fraction * pow(10.0, (double)exponential) * (double)signal; 600 if ((val >= ( FLT_MAX * (-1.0f))) && (val <=FLT_MAX))601 if ((val >= ((double)FLT_MAX * (-1.0))) && (val <= (double)FLT_MAX)) 601 602 { 602 603 /*Codes_SRS_CRT_ABSTRACTIONS_21_016: [The strtof_s must return the float that represents the value in the initial part of the string. If any.]*/ … … 836 837 return result; 837 838 } 839 840 /*takes "value" and transforms it into a decimal string*/ 841 /*10 => "10"*/ 842 /*return 0 when everything went ok*/ 843 int uint64_tToString(char* destination, size_t destinationSize, uint64_t value) 844 { 845 int result; 846 size_t pos; 847 /*the below loop gets the number in reverse order*/ 848 if ( 849 (destination == NULL) || 850 (destinationSize < 2) /*because the smallest number is '0\0' which requires 2 characters*/ 851 ) 852 { 853 result = MU_FAILURE; 854 } 855 else 856 { 857 pos = 0; 858 do 859 { 860 destination[pos++] = '0' + (value % 10); 861 value /= 10; 862 } while ((value > 0) && (pos < (destinationSize - 1))); 863 864 if (value == 0) 865 { 866 size_t w; 867 destination[pos] = '\0'; 868 /*all converted and they fit*/ 869 for (w = 0; w <= (pos - 1) >> 1; w++) 870 { 871 char temp; 872 temp = destination[w]; 873 destination[w] = destination[pos - 1 - w]; 874 destination[pos - 1 - w] = temp; 875 } 876 result = 0; 877 } 878 else 879 { 880 result = MU_FAILURE; 881 } 882 } 883 return result; 884 } -
azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/httpapiexsas.c
r457 r464 107 107 { 108 108 /*Codes_SRS_HTTPAPIEXSAS_06_005: [If the parameter handle is NULL then HTTAPIEX_SAS_Destroy shall do nothing and return.]*/ 109 if (handle) 109 HTTPAPIEX_SAS_STATE* state = (HTTPAPIEX_SAS_STATE*)handle; 110 if (state) 110 111 { 111 HTTPAPIEX_SAS_STATE* state = (HTTPAPIEX_SAS_STATE*)handle;112 112 /*Codes_SRS_HTTPAPIEXSAS_06_006: [HTTAPIEX_SAS_Destroy shall deallocate any structures denoted by the parameter handle.]*/ 113 113 if (state->key) … … 159 159 /*Codes_SRS_HTTPAPIEXSAS_06_011: [SASToken_Create shall be invoked.]*/ 160 160 /*Codes_SRS_HTTPAPIEXSAS_06_012: [If the return result of SASToken_Create is NULL then fallthrough.]*/ 161 size_t expiry = (size_t)(difftime(currentTime, 0) + 3600);161 uint64_t expiry = (uint64_t)(difftime(currentTime, 0) + 3600); 162 162 newSASToken = SASToken_CreateString(state->key, state->uriResource, state->keyName, expiry); 163 163 } -
azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/sastoken.c
r457 r464 24 24 if (expiryASCII[i] >= '0' && expiryASCII[i] <= '9') 25 25 { 26 value = value * 10 + ( double)(expiryASCII[i] -'0');26 value = value * 10 + ((double)expiryASCII[i] - (double)'0'); 27 27 } 28 28 else … … 203 203 } 204 204 205 static STRING_HANDLE construct_sas_token(const char* key, const char* scope, const char* keyname, size_t expiry)205 static STRING_HANDLE construct_sas_token(const char* key, const char* scope, const char* keyname, uint64_t expiry) 206 206 { 207 207 STRING_HANDLE result; … … 221 221 { 222 222 /*Codes_SRS_SASTOKEN_06_026: [If the conversion to string form fails for any reason then SASToken_Create shall return NULL.]*/ 223 if ( size_tToString(tokenExpirationTime, sizeof(tokenExpirationTime), expiry) != 0)223 if (uint64_tToString(tokenExpirationTime, sizeof(tokenExpirationTime), expiry) != 0) 224 224 { 225 225 LogError("For some reason converting seconds to a string failed. No SAS can be generated."); … … 303 303 } 304 304 305 STRING_HANDLE SASToken_Create(STRING_HANDLE key, STRING_HANDLE scope, STRING_HANDLE keyName, size_t expiry)305 STRING_HANDLE SASToken_Create(STRING_HANDLE key, STRING_HANDLE scope, STRING_HANDLE keyName, uint64_t expiry) 306 306 { 307 307 STRING_HANDLE result; … … 326 326 } 327 327 328 STRING_HANDLE SASToken_CreateString(const char* key, const char* scope, const char* keyName, size_t expiry)328 STRING_HANDLE SASToken_CreateString(const char* key, const char* scope, const char* keyName, uint64_t expiry) 329 329 { 330 330 STRING_HANDLE result; -
azure_iot_hub_f767zi/trunk/azure_iot_sdk/c-utility/src/sha384-512.c
r457 r464 469 469 if (!length) 470 470 return shaSuccess; 471 472 if (length > (sizeof(context->Message_Block) / sizeof(context->Message_Block[0]))) 473 return shaBadParam; 471 474 472 475 if (!context || !message_array) -
azure_iot_hub_f767zi/trunk/azure_iot_sdk/deps/uhttp/src/uhttp.c
r457 r464 136 136 int spaceFound = 0; 137 137 const char* initSpace = NULL; 138 char status_code[4] ;138 char status_code[4] = { 0 }; 139 139 140 140 for (index = 0; index < len; index++) … … 186 186 { 187 187 colonEncountered = true; 188 size_t keyLen = (&buffer[index])-targetPos; 189 190 if (headerKey != NULL) 191 { 192 free(headerKey); 193 headerKey = NULL; 194 } 195 headerKey = (char*)malloc(keyLen+1); 196 if (headerKey == NULL) 197 { 188 size_t keyLen = (&buffer[index]) - targetPos; 189 190 if (keyLen == 0) 191 { 192 LogError("Invalid header name with zero length."); 198 193 result = MU_FAILURE; 199 194 continueProcessing = false; … … 201 196 else 202 197 { 203 memcpy(headerKey, targetPos, keyLen); 204 headerKey[keyLen] = '\0'; 205 206 // Convert to lower case 207 for (size_t inner = 0; inner < keyLen; inner++) 208 { 209 headerKey[inner] = (char)tolower(headerKey[inner]); 210 } 211 212 targetPos = buffer+index+1; 213 crlfEncounted = false; 198 if (headerKey != NULL) 199 { 200 free(headerKey); 201 headerKey = NULL; 202 } 203 headerKey = (char*)malloc(keyLen + 1); 204 if (headerKey == NULL) 205 { 206 result = MU_FAILURE; 207 continueProcessing = false; 208 } 209 else 210 { 211 memcpy(headerKey, targetPos, keyLen); 212 headerKey[keyLen] = '\0'; 213 214 // Convert to lower case 215 for (size_t inner = 0; inner < keyLen; inner++) 216 { 217 headerKey[inner] = (char)tolower(headerKey[inner]); 218 } 219 220 targetPos = buffer+index+1; 221 crlfEncounted = false; 222 } 214 223 } 215 224 } -
azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/inc/internal/iothub_client_authorization.h
r457 r464 42 42 MOCKABLE_FUNCTION(, IOTHUB_CREDENTIAL_TYPE, IoTHubClient_Auth_Set_x509_Type, IOTHUB_AUTHORIZATION_HANDLE, handle, bool, enable_x509); 43 43 MOCKABLE_FUNCTION(, IOTHUB_CREDENTIAL_TYPE, IoTHubClient_Auth_Get_Credential_Type, IOTHUB_AUTHORIZATION_HANDLE, handle); 44 MOCKABLE_FUNCTION(, char*, IoTHubClient_Auth_Get_SasToken, IOTHUB_AUTHORIZATION_HANDLE, handle, const char*, scope, size_t, expiry_time_relative_seconds, const char*, key_name);44 MOCKABLE_FUNCTION(, char*, IoTHubClient_Auth_Get_SasToken, IOTHUB_AUTHORIZATION_HANDLE, handle, const char*, scope, uint64_t, expiry_time_relative_seconds, const char*, key_name); 45 45 MOCKABLE_FUNCTION(, int, IoTHubClient_Auth_Set_xio_Certificate, IOTHUB_AUTHORIZATION_HANDLE, handle, XIO_HANDLE, xio); 46 46 MOCKABLE_FUNCTION(, const char*, IoTHubClient_Auth_Get_DeviceId, IOTHUB_AUTHORIZATION_HANDLE, handle); … … 49 49 MOCKABLE_FUNCTION(, SAS_TOKEN_STATUS, IoTHubClient_Auth_Is_SasToken_Valid, IOTHUB_AUTHORIZATION_HANDLE, handle); 50 50 MOCKABLE_FUNCTION(, int, IoTHubClient_Auth_Get_x509_info, IOTHUB_AUTHORIZATION_HANDLE, handle, char**, x509_cert, char**, x509_key); 51 MOCKABLE_FUNCTION(, int, IoTHubClient_Auth_Set_SasToken_Expiry, IOTHUB_AUTHORIZATION_HANDLE, handle, size_t, expiry_time_seconds);52 MOCKABLE_FUNCTION(, size_t, IoTHubClient_Auth_Get_SasToken_Expiry, IOTHUB_AUTHORIZATION_HANDLE, handle);51 MOCKABLE_FUNCTION(, int, IoTHubClient_Auth_Set_SasToken_Expiry, IOTHUB_AUTHORIZATION_HANDLE, handle, uint64_t, expiry_time_seconds); 52 MOCKABLE_FUNCTION(, uint64_t, IoTHubClient_Auth_Get_SasToken_Expiry, IOTHUB_AUTHORIZATION_HANDLE, handle); 53 53 54 54 -
azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/inc/internal/iothub_internal_consts.h
r457 r464 10 10 #endif 11 11 12 static const char* IOTHUB_API_VERSION = "2019-10-01"; 13 // TODO: https://github.com/Azure/azure-iot-sdk-c/issues/1547 tracks removing this preview 14 // variable once the underlying logic is enabled on all IoTHubs. 15 static const char* IOTHUB_API_PREVIEW_VERSION = "2020-05-31-preview"; 16 12 static const char* IOTHUB_API_VERSION = "2020-09-30"; 17 13 static const char* SECURITY_INTERFACE_INTERNAL_ID = "iothub-interface-internal-id"; 18 14 static const char* SECURITY_INTERFACE_INTERNAL_ID_VALUE = "security*azureiot*com^SecurityAgent^1*0*0"; -
azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/inc/iothub_client.h
r457 r464 2 2 // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 3 4 //********************************************************************** 5 // NOTE: THIS HEADER IS DEPRECATED 6 // 7 // Functions in this header will be maintained for backward compatability. 8 // New applications should use iothub_device_client.h. 9 // 10 //********************************************************************** 11 4 12 /** @file iothub_client.h 5 * @brief Extends the IoTHubC Lient_LL modulewith additional features.13 * @brief Extends the IoTHubClient_LL with additional features. 6 14 * 7 15 * @note DEPRECATED. New users use iothub_device_client.h for IoTHubClient APIs. … … 38 46 39 47 /** 40 * @brief Creates a IoT Hub client for communication with an existing 41 * IoT Hub using the specified connection string parameter. 42 * 43 * @param connectionString Pointer to a character string 44 * @param protocol Function pointer for protocol implementation 45 * 46 * Sample connection string: 47 * <blockquote> 48 * <pre>HostName=[IoT Hub name goes here].[IoT Hub suffix goes here, e.g., private.azure-devices-int.net];DeviceId=[Device ID goes here];SharedAccessKey=[Device key goes here];</pre> 49 * <pre>HostName=[IoT Hub name goes here].[IoT Hub suffix goes here, e.g., private.azure-devices-int.net];DeviceId=[Device ID goes here];SharedAccessSignature=SharedAccessSignature sr=[IoT Hub name goes here].[IoT Hub suffix goes here, e.g., private.azure-devices-int.net]/devices/[Device ID goes here]&sig=[SAS Token goes here]&se=[Expiry Time goes here];</pre> 50 * </blockquote> 51 * 52 * @return A non-NULL @c IOTHUB_CLIENT_HANDLE value that is used when 53 * invoking other functions for IoT Hub client and @c NULL on failure. 48 * @deprecated IoTHubClient_CreateFromConnectionString is deprecated. Use IoTHubDeviceClient_CreateFromConnectionString instead. 54 49 */ 55 50 MOCKABLE_FUNCTION(, IOTHUB_CLIENT_HANDLE, IoTHubClient_CreateFromConnectionString, const char*, connectionString, IOTHUB_CLIENT_TRANSPORT_PROVIDER, protocol); 56 51 57 52 /** 58 * @brief Creates a IoT Hub client for communication with an existing IoT 59 * Hub using the specified parameters. 60 * 61 * @param config Pointer to an @c IOTHUB_CLIENT_CONFIG structure 62 * 63 * The API does not allow sharing of a connection across multiple 64 * devices. This is a blocking call. 65 * 66 * @return A non-NULL @c IOTHUB_CLIENT_HANDLE value that is used when 67 * invoking other functions for IoT Hub client and @c NULL on failure. 53 * @deprecated IoTHubClient_Create is deprecated. Use IoTHubDeviceClient_Create instead. 68 54 */ 69 55 MOCKABLE_FUNCTION(, IOTHUB_CLIENT_HANDLE, IoTHubClient_Create, const IOTHUB_CLIENT_CONFIG*, config); 70 56 71 57 /** 72 * @brief Creates a IoT Hub client for communication with an existing IoT 73 * Hub using the specified parameters. 74 * 75 * @param transportHandle TRANSPORT_HANDLE which represents a connection. 76 * @param config Pointer to an @c IOTHUB_CLIENT_CONFIG structure 77 * 78 * The API allows sharing of a connection across multiple 79 * devices. This is a blocking call. 80 * 81 * @return A non-NULL @c IOTHUB_CLIENT_HANDLE value that is used when 82 * invoking other functions for IoT Hub client and @c NULL on failure. 58 * @deprecated IoTHubClient_CreateWithTransport is deprecated. Use IoTHubDeviceClient_CreateWithTransport instead. 83 59 */ 84 60 MOCKABLE_FUNCTION(, IOTHUB_CLIENT_HANDLE, IoTHubClient_CreateWithTransport, TRANSPORT_HANDLE, transportHandle, const IOTHUB_CLIENT_CONFIG*, config); 85 61 86 62 /** 87 * @brief Creates a IoT Hub client for communication with an existing IoT 88 * Hub using the device auth module. 89 * 90 * @param iothub_uri Pointer to an ioThub hostname received in the registration process 91 * @param device_id Pointer to the device Id of the device 92 * @param protocol Function pointer for protocol implementation 93 * 94 * @return A non-NULL @c IOTHUB_CLIENT_LL_HANDLE value that is used when 95 * invoking other functions for IoT Hub client and @c NULL on failure. 63 * @deprecated IoTHubClient_CreateFromDeviceAuth is deprecated. Use IoTHubDeviceClient_CreateFromDeviceAuth instead. 96 64 */ 97 65 MOCKABLE_FUNCTION(, IOTHUB_CLIENT_HANDLE, IoTHubClient_CreateFromDeviceAuth, const char*, iothub_uri, const char*, device_id, IOTHUB_CLIENT_TRANSPORT_PROVIDER, protocol); 98 66 99 67 /** 100 * @brief Disposes of resources allocated by the IoT Hub client. This is a 101 * blocking call. 102 * 103 * @param iotHubClientHandle The handle created by a call to the create function. 68 * @deprecated IoTHubClient_Destroy is deprecated. Use IoTHubDeviceClient_Destroy instead. 104 69 */ 105 70 MOCKABLE_FUNCTION(, void, IoTHubClient_Destroy, IOTHUB_CLIENT_HANDLE, iotHubClientHandle); 106 71 107 72 /** 108 * @brief Asynchronous call to send the message specified by @p eventMessageHandle. 109 * 110 * @param iotHubClientHandle The handle created by a call to the create function. 111 * @param eventMessageHandle The handle to an IoT Hub message. 112 * @param eventConfirmationCallback The callback specified by the device for receiving 113 * confirmation of the delivery of the IoT Hub message. 114 * This callback can be expected to invoke the 115 * ::IoTHubClient_SendEventAsync function for the 116 * same message in an attempt to retry sending a failing 117 * message. The user can specify a @c NULL value here to 118 * indicate that no callback is required. 119 * @param userContextCallback User specified context that will be provided to the 120 * callback. This can be @c NULL. 121 * 122 * @b NOTE: The application behavior is undefined if the user calls 123 * the ::IoTHubClient_Destroy function from within any callback. 124 * @remarks 125 * The IOTHUB_MESSAGE_HANDLE instance provided as argument is copied by the function, 126 * so this argument can be destroyed by the calling application right after IoTHubClient_SendEventAsync returns. 127 * The copy of @c eventMessageHandle is later destroyed by the iothub client when the message is effectively sent, if a failure sending it occurs, or if the client is destroyed. 128 * @return IOTHUB_CLIENT_OK upon success or an error code upon failure. 73 * @deprecated IoTHubClient_SendEventAsync is deprecated. Use IoTHubDeviceClient_SendEventAsync instead. 129 74 */ 130 75 MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClient_SendEventAsync, IOTHUB_CLIENT_HANDLE, iotHubClientHandle, IOTHUB_MESSAGE_HANDLE, eventMessageHandle, IOTHUB_CLIENT_EVENT_CONFIRMATION_CALLBACK, eventConfirmationCallback, void*, userContextCallback); 131 76 132 77 /** 133 * @brief This function returns the current sending status for IoTHubClient. 134 * 135 * @param iotHubClientHandle The handle created by a call to the create function. 136 * @param iotHubClientStatus The sending state is populated at the address pointed 137 * at by this parameter. The value will be set to 138 * @c IOTHUBCLIENT_SENDSTATUS_IDLE if there is currently 139 * no item to be sent and @c IOTHUBCLIENT_SENDSTATUS_BUSY 140 * if there are. 141 * 142 * @return IOTHUB_CLIENT_OK upon success or an error code upon failure. 78 * @deprecated IoTHubClient_GetSendStatus is deprecated. Use IoTHubDeviceClient_GetSendStatus instead. 143 79 */ 144 80 MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClient_GetSendStatus, IOTHUB_CLIENT_HANDLE, iotHubClientHandle, IOTHUB_CLIENT_STATUS*, iotHubClientStatus); 145 81 146 82 /** 147 * @brief Sets up the message callback to be invoked when IoT Hub issues a 148 * message to the device. This is a blocking call. 149 * 150 * @param iotHubClientHandle The handle created by a call to the create function. 151 * @param messageCallback The callback specified by the device for receiving 152 * messages from IoT Hub. 153 * @param userContextCallback User specified context that will be provided to the 154 * callback. This can be @c NULL. 155 * 156 * @b NOTE: The application behavior is undefined if the user calls 157 * the ::IoTHubClient_Destroy function from within any callback. 158 * 159 * @return IOTHUB_CLIENT_OK upon success or an error code upon failure. 83 * @deprecated IoTHubClient_SetMessageCallback is deprecated. Use IoTHubDeviceClient_SetMessageCallback instead. 160 84 */ 161 85 MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClient_SetMessageCallback, IOTHUB_CLIENT_HANDLE, iotHubClientHandle, IOTHUB_CLIENT_MESSAGE_CALLBACK_ASYNC, messageCallback, void*, userContextCallback); 162 86 163 87 /** 164 * @brief Sets up the connection status callback to be invoked representing the status of 165 * the connection to IOT Hub. This is a blocking call. 166 * 167 * @param iotHubClientHandle The handle created by a call to the create function. 168 * @param connectionStatusCallback The callback specified by the device for receiving 169 * updates about the status of the connection to IoT Hub. 170 * @param userContextCallback User specified context that will be provided to the 171 * callback. This can be @c NULL. 172 * 173 * @b NOTE: The application behavior is undefined if the user calls 174 * the ::IoTHubClient_LL_Destroy function from within any callback. 175 * 176 * @return IOTHUB_CLIENT_OK upon success or an error code upon failure. 88 * @deprecated IoTHubClient_SetConnectionStatusCallback is deprecated. Use IoTHubDeviceClient_SetConnectionStatusCallback instead. 177 89 */ 178 90 MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClient_SetConnectionStatusCallback, IOTHUB_CLIENT_HANDLE, iotHubClientHandle, IOTHUB_CLIENT_CONNECTION_STATUS_CALLBACK, connectionStatusCallback, void*, userContextCallback); 179 91 180 92 /** 181 * @brief Sets up the connection status callback to be invoked representing the status of 182 * the connection to IOT Hub. This is a blocking call. 183 * 184 * @param iotHubClientHandle The handle created by a call to the create function. 185 * @param retryPolicy The policy to use to reconnect to IoT Hub when a 186 * connection drops. 187 * @param retryTimeoutLimitInSeconds Maximum amount of time(seconds) to attempt reconnection when a 188 * connection drops to IOT Hub. 189 * 190 * @b NOTE: The application behavior is undefined if the user calls 191 * the ::IoTHubClient_LL_Destroy function from within any callback. 192 * 193 * @return IOTHUB_CLIENT_OK upon success or an error code upon failure. 93 * @deprecated IoTHubClient_SetRetryPolicy is deprecated. Use IoTHubDeviceClient_SetRetryPolicy instead. 194 94 */ 195 95 MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClient_SetRetryPolicy, IOTHUB_CLIENT_HANDLE, iotHubClientHandle, IOTHUB_CLIENT_RETRY_POLICY, retryPolicy, size_t, retryTimeoutLimitInSeconds); 196 96 197 97 /** 198 * @brief Sets up the connection status callback to be invoked representing the status of 199 * the connection to IOT Hub. This is a blocking call. 200 * 201 * @param iotHubClientHandle The handle created by a call to the create function. 202 * @param retryPolicy Out parameter containing the policy to use to reconnect to IoT Hub. 203 * @param retryTimeoutLimitInSeconds Out parameter containing maximum amount of time in seconds to attempt reconnection 204 to IOT Hub. 205 * 206 * @b NOTE: The application behavior is undefined if the user calls 207 * the ::IoTHubClient_LL_Destroy function from within any callback. 208 * 209 * @return IOTHUB_CLIENT_OK upon success or an error code upon failure. 98 * @deprecated IoTHubClient_GetRetryPolicy is deprecated. Use IoTHubDeviceClient_GetRetryPolicy instead. 210 99 */ 211 100 MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClient_GetRetryPolicy, IOTHUB_CLIENT_HANDLE, iotHubClientHandle, IOTHUB_CLIENT_RETRY_POLICY*, retryPolicy, size_t*, retryTimeoutLimitInSeconds); 212 101 213 102 /** 214 * @brief This function returns in the out parameter @p lastMessageReceiveTime 215 * what was the value of the @c time function when the last message was 216 * received at the client. 217 * 218 * @param iotHubClientHandle The handle created by a call to the create function. 219 * @param lastMessageReceiveTime Out parameter containing the value of @c time function 220 * when the last message was received. 221 * 222 * @return IOTHUB_CLIENT_OK upon success or an error code upon failure. 103 * @deprecated IoTHubClient_GetLastMessageReceiveTime is deprecated. Use IoTHubDeviceClient_GetLastMessageReceiveTime instead. 223 104 */ 224 105 MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClient_GetLastMessageReceiveTime, IOTHUB_CLIENT_HANDLE, iotHubClientHandle, time_t*, lastMessageReceiveTime); 225 106 226 107 /** 227 * @brief This API sets a runtime option identified by parameter @p optionName 228 * to a value pointed to by @p value. @p optionName and the data type 229 * @p value is pointing to are specific for every option. 230 * 231 * @param iotHubClientHandle The handle created by a call to the create function. 232 * @param optionName Name of the option. 233 * @param value The value. 234 * 235 * The options that can be set via this API are: 236 * - @b timeout - the maximum time in milliseconds a communication is 237 * allowed to use. @p value is a pointer to an @c unsigned @c int with 238 * the timeout value in milliseconds. This is only supported for the HTTP 239 * protocol as of now. When the HTTP protocol uses CURL, the meaning of 240 * the parameter is <em>total request time</em>. When the HTTP protocol uses 241 * winhttp, the meaning is the same as the @c dwSendTimeout and 242 * @c dwReceiveTimeout parameters of the 243 * <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/aa384116(v=vs.85).aspx"> 244 * WinHttpSetTimeouts</a> API. 245 * - @b CURLOPT_LOW_SPEED_LIMIT - only available for HTTP protocol and only 246 * when CURL is used. It has the same meaning as CURL's option with the same 247 * name. @p value is pointer to a long. 248 * - @b CURLOPT_LOW_SPEED_TIME - only available for HTTP protocol and only 249 * when CURL is used. It has the same meaning as CURL's option with the same 250 * name. @p value is pointer to a long. 251 * - @b CURLOPT_FORBID_REUSE - only available for HTTP protocol and only 252 * when CURL is used. It has the same meaning as CURL's option with the same 253 * name. @p value is pointer to a long. 254 * - @b CURLOPT_FRESH_CONNECT - only available for HTTP protocol and only 255 * when CURL is used. It has the same meaning as CURL's option with the same 256 * name. @p value is pointer to a long. 257 * - @b CURLOPT_VERBOSE - only available for HTTP protocol and only 258 * when CURL is used. It has the same meaning as CURL's option with the same 259 * name. @p value is pointer to a long. 260 * - @b messageTimeout - the maximum time in milliseconds until a message 261 * is timeouted. The time starts at IoTHubClient_SendEventAsync. By default, 262 * messages do not expire. @p is a pointer to a uint64_t 263 * - @b svc2cl_keep_alive_timeout_secs - the AMQP service side keep alive interval in seconds. 264 * After the connection established the client requests the server to set the 265 * keep alive interval for given time. 266 * If it is not set then the default 240 sec applies. 267 * If it is set to zero the server will not send keep alive messages to the client. 268 * - @b cl2svc_keep_alive_send_ratio - the AMQP client side keep alive interval in seconds. 269 * After the connection established the server requests the client to set the 270 * keep alive interval for given time. 271 * If it is not set then the default ratio of 1/2 is applied. 272 * The ratio has to be greater than 0.0 and equal to or less than 0.9 273 274 * @return IOTHUB_CLIENT_OK upon success or an error code upon failure. 275 */ 108 * @deprecated IoTHubClient_SetOption is deprecated. Use IoTHubDeviceClient_SetOption instead. 109 */ 276 110 MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClient_SetOption, IOTHUB_CLIENT_HANDLE, iotHubClientHandle, const char*, optionName, const void*, value); 277 111 278 112 /** 279 * @brief This API specifies a call back to be used when the device receives a state update. 280 * 281 * @param iotHubClientHandle The handle created by a call to the create function. 282 * @param deviceTwinCallback The callback specified by the device client to be used for updating 283 * the desired state. The callback will be called in response to a 284 * request send by the IoTHub services. The payload will be passed to the 285 * callback, along with two version numbers: 286 * - Desired: 287 * - LastSeenReported: 288 * @param userContextCallback User specified context that will be provided to the 289 * callback. This can be @c NULL. 290 * 291 * @b NOTE: The application behavior is undefined if the user calls 292 * the ::IoTHubClient_Destroy function from within any callback. 293 * 294 * @return IOTHUB_CLIENT_OK upon success or an error code upon failure. 113 * @deprecated IoTHubClient_SetDeviceTwinCallback is deprecated. Use IoTHubDeviceClient_SetDeviceTwinCallback instead. 295 114 */ 296 115 MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClient_SetDeviceTwinCallback, IOTHUB_CLIENT_HANDLE, iotHubClientHandle, IOTHUB_CLIENT_DEVICE_TWIN_CALLBACK, deviceTwinCallback, void*, userContextCallback); 297 116 298 117 /** 299 * @brief This API sends a report of the device's properties and their current values. 300 * 301 * @param iotHubClientHandle The handle created by a call to the create function. 302 * @param reportedState The current device property values to be 'reported' to the IoTHub. 303 * @param reportedStateCallback The callback specified by the device client to be called with the 304 * result of the transaction. 305 * @param userContextCallback User specified context that will be provided to the 306 * callback. This can be @c NULL. 307 * 308 * @b NOTE: The application behavior is undefined if the user calls 309 * the ::IoTHubClient_Destroy function from within any callback. 310 * 311 * @return IOTHUB_CLIENT_OK upon success or an error code upon failure. 118 * @deprecated IoTHubClient_SendReportedState is deprecated. Use IoTHubDeviceClient_SendReportedState instead. 312 119 */ 313 120 MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClient_SendReportedState, IOTHUB_CLIENT_HANDLE, iotHubClientHandle, const unsigned char*, reportedState, size_t, size, IOTHUB_CLIENT_REPORTED_STATE_CALLBACK, reportedStateCallback, void*, userContextCallback); 314 121 315 122 /** 316 * @brief This API sets callback for cloud to device method call. 317 * 318 * @param iotHubClientHandle The handle created by a call to the create function. 319 * @param deviceMethodCallback The callback which will be called by IoTHub. 320 * @param userContextCallback User specified context that will be provided to the 321 * callback. This can be @c NULL. 322 * 323 * @return IOTHUB_CLIENT_OK upon success or an error code upon failure. 123 * @deprecated IoTHubClient_SetDeviceMethodCallback is deprecated. Use IoTHubDeviceClient_SetDeviceMethodCallback instead. 324 124 */ 325 125 MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClient_SetDeviceMethodCallback, IOTHUB_CLIENT_HANDLE, iotHubClientHandle, IOTHUB_CLIENT_DEVICE_METHOD_CALLBACK_ASYNC, deviceMethodCallback, void*, userContextCallback); 326 126 327 127 /** 328 * @brief This API sets callback for async cloud to device method call. 329 * 330 * @param iotHubClientHandle The handle created by a call to the create function. 331 * @param inboundDeviceMethodCallback The callback which will be called by IoTHub. 332 * @param userContextCallback User specified context that will be provided to the 333 * callback. This can be @c NULL. 334 * 335 * @return IOTHUB_CLIENT_OK upon success or an error code upon failure. 128 * @deprecated IoTHubClient_SetDeviceMethodCallback_Ex is deprecated. Use IoTHubDeviceClient_SetDeviceMethodCallback instead. 336 129 */ 337 130 MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClient_SetDeviceMethodCallback_Ex, IOTHUB_CLIENT_HANDLE, iotHubClientHandle, IOTHUB_CLIENT_INBOUND_DEVICE_METHOD_CALLBACK, inboundDeviceMethodCallback, void*, userContextCallback); 338 131 339 132 /** 340 * @brief This API responses to a asnyc method callback identified the methodId. 341 * 342 * @param iotHubClientHandle The handle created by a call to the create function. 343 * @param methodId The methodId of the Device Method callback. 344 * @param response The response data for the method callback. 345 * @param response_size The size of the response data buffer. 346 * @param status_response The status response of the method callback. 347 * 348 * @return IOTHUB_CLIENT_OK upon success or an error code upon failure. 133 * @deprecated IoTHubClient_DeviceMethodResponse is deprecated. Use IoTHubDeviceClient_SetDeviceMethodCallback instead. 349 134 */ 350 135 MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClient_DeviceMethodResponse, IOTHUB_CLIENT_HANDLE, iotHubClientHandle, METHOD_HANDLE, methodId, const unsigned char*, response, size_t, response_size, int, statusCode); … … 352 137 #ifndef DONT_USE_UPLOADTOBLOB 353 138 /** 354 * @brief IoTHubClient_UploadToBlobAsync uploads data from memory to a file in Azure Blob Storage. 355 * 356 * @param iotHubClientHandle The handle created by a call to the IoTHubClient_Create function. 357 * @param destinationFileName The name of the file to be created in Azure Blob Storage. 358 * @param source The source of data. 359 * @param size The size of data. 360 * @param iotHubClientFileUploadCallback A callback to be invoked when the file upload operation has finished. 361 * @param context A user-provided context to be passed to the file upload callback. 362 * 363 * @return IOTHUB_CLIENT_OK upon success or an error code upon failure. 139 * @deprecated IoTHubClient_UploadToBlobAsync is deprecated. Use IoTHubDeviceClient_UploadToBlobAsync instead. 364 140 */ 365 141 MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClient_UploadToBlobAsync, IOTHUB_CLIENT_HANDLE, iotHubClientHandle, const char*, destinationFileName, const unsigned char*, source, size_t, size, IOTHUB_CLIENT_FILE_UPLOAD_CALLBACK, iotHubClientFileUploadCallback, void*, context); 366 142 367 143 /** 368 ** DEPRECATED: Use IoTHubClient_UploadMultipleBlocksToBlobAsyncEx instead ** 369 * @brief Uploads a file to a Blob storage in chunks, fed through the callback function provided by the user. 370 * @remarks This function allows users to upload large files in chunks, not requiring the whole file content to be passed in memory. 371 * @param iotHubClientHandle The handle created by a call to the IoTHubClient_Create function. 372 * @param destinationFileName The name of the file to be created in Azure Blob Storage. 373 * @param getDataCallback A callback to be invoked to acquire the file chunks to be uploaded, as well as to indicate the status of the upload of the previous block. 374 * @param context Any data provided by the user to serve as context on getDataCallback. 375 * @returns An IOTHUB_CLIENT_RESULT value indicating the success or failure of the API call. 376 ** DEPRECATED: Use IoTHubClient_UploadMultipleBlocksToBlobAsyncEx instead ** 144 * @deprecated IoTHubClient_UploadMultipleBlocksToBlobAsync is deprecated. Use IoTHubDeviceClient_UploadMultipleBlocksToBlobAsync instead. 377 145 */ 378 146 MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClient_UploadMultipleBlocksToBlobAsync, IOTHUB_CLIENT_HANDLE, iotHubClientHandle, const char*, destinationFileName, IOTHUB_CLIENT_FILE_UPLOAD_GET_DATA_CALLBACK, getDataCallback, void*, context); 379 147 380 148 /** 381 * @brief Uploads a file to a Blob storage in chunks, fed through the callback function provided by the user. 382 * @remarks This function allows users to upload large files in chunks, not requiring the whole file content to be passed in memory. 383 * @param iotHubClientHandle The handle created by a call to the IoTHubClient_Create function. 384 * @param destinationFileName The name of the file to be created in Azure Blob Storage. 385 * @param getDataCallbackEx A callback to be invoked to acquire the file chunks to be uploaded, as well as to indicate the status of the upload of the previous block. 386 * @param context Any data provided by the user to serve as context on getDataCallback. 387 * @returns An IOTHUB_CLIENT_RESULT value indicating the success or failure of the API call.*/ 149 * @deprecated IoTHubClient_UploadMultipleBlocksToBlobAsyncEx is deprecated. Use IoTHubDeviceClient_UploadMultipleBlocksToBlobAsync instead. 150 */ 388 151 MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClient_UploadMultipleBlocksToBlobAsyncEx, IOTHUB_CLIENT_HANDLE, iotHubClientHandle, const char*, destinationFileName, IOTHUB_CLIENT_FILE_UPLOAD_GET_DATA_CALLBACK_EX, getDataCallbackEx, void*, context); 389 152 -
azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/inc/iothub_client_core.h
r457 r464 2 2 // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 3 4 /** @file iothub_client_core.h 5 * @brief Extends the IoTHubClientCore_LL module with additional features. 6 * 7 * @details IoTHubClientCore is a module that extends the IoTHubClientCore_LL 8 * module with 2 features: 9 * - scheduling the work for the IoTHubCLient from a 10 * thread, so that the user does not need to create their 11 * own thread 12 * - thread-safe APIs 13 */ 4 //********************************************************************** 5 // NOTE: THIS HEADER IS FOR INTERNAL USE ONLY 6 // 7 // Applications should use iothub_device_client.h or iothub_module_client.h 8 // instead for the official API. 9 // 10 //********************************************************************** 14 11 15 12 #ifndef IOTHUB_CLIENT_CORE_H -
azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/inc/iothub_client_core_ll.h
r457 r464 2 2 // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 3 4 /** @file iothub_client_core_ll.h 5 * @brief APIs that allow a user (usually a device) to communicate 6 * with an Azure IoTHub. 7 * 8 * @details IoTHubClientCore_LL is a module that allows a user (usually a 9 * device) to communicate with an Azure IoTHub. It can send events 10 * and receive messages. At any given moment in time there can only 11 * be at most 1 message callback function. 12 * 13 * This API surface contains a set of APIs that allows the user to 14 * interact with the lower layer portion of the IoTHubClient. These APIs 15 * contain @c _LL_ in their name, but retain the same functionality like the 16 * @c IoTHubClient_... APIs, with one difference. If the @c _LL_ APIs are 17 * used then the user is responsible for scheduling when the actual work done 18 * by the IoTHubClient happens (when the data is sent/received on/from the wire). 19 * This is useful for constrained devices where spinning a separate thread is 20 * often not desired. 21 */ 4 //********************************************************************** 5 // NOTE: THIS HEADER IS FOR INTERNAL USE ONLY 6 // 7 // Applications should use iothub_device_client_ll.h or iothub_module_client_ll.h 8 // instead for the official API. 9 // 10 //********************************************************************** 22 11 23 12 #ifndef IOTHUB_CLIENT_CORE_LL_H -
azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/inc/iothub_client_ll.h
r457 r464 1 1 // Copyright (c) Microsoft. All rights reserved. 2 2 // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 4 //********************************************************************** 5 // NOTE: THIS HEADER IS DEPRECATED 6 // 7 // Functions in this header will be maintained for backward compatability. 8 // New applications should use iothub_device_client_ll.h. 9 // 10 //********************************************************************** 11 3 12 4 13 /** @file iothub_client_ll.h … … 6 15 * with an Azure IoTHub. 7 16 * 8 * @details IoTHubClient_LL is a module thatallows a user (usually a17 * @details IoTHubClient_LL allows a user (usually a 9 18 * device) to communicate with an Azure IoTHub. It can send events 10 19 * and receive messages. At any given moment in time there can only … … 38 47 typedef struct IOTHUB_CLIENT_CORE_LL_HANDLE_DATA_TAG* IOTHUB_CLIENT_LL_HANDLE; 39 48 49 /** 50 * @deprecated IoTHubClient_LL_CreateFromConnectionString is deprecated. Use IoTHubDeviceClient_LL_CreateFromConnectionString instead. 51 */ 52 MOCKABLE_FUNCTION(, IOTHUB_CLIENT_LL_HANDLE, IoTHubClient_LL_CreateFromConnectionString, const char*, connectionString, IOTHUB_CLIENT_TRANSPORT_PROVIDER, protocol); 40 53 41 54 /** 42 * @brief Creates a IoT Hub client for communication with an existing 43 * IoT Hub using the specified connection string parameter. 44 * 45 * @param connectionString Pointer to a character string 46 * @param protocol Function pointer for protocol implementation 47 * 48 * Sample connection string: 49 * <blockquote> 50 * <pre>HostName=[IoT Hub name goes here].[IoT Hub suffix goes here, e.g., private.azure-devices-int.net];DeviceId=[Device ID goes here];SharedAccessKey=[Device key goes here];</pre> 51 * </blockquote> 52 * 53 * @return A non-NULL @c IOTHUB_CLIENT_LL_HANDLE value that is used when 54 * invoking other functions for IoT Hub client and @c NULL on failure. 55 * @deprecated IoTHubClient_LL_Create is deprecated. Use IoTHubDeviceClient_LL_Create instead. 55 56 */ 56 MOCKABLE_FUNCTION(, IOTHUB_CLIENT_LL_HANDLE, IoTHubClient_LL_CreateFromConnectionString, const char*, connectionString, IOTHUB_CLIENT_TRANSPORT_PROVIDER, protocol);57 MOCKABLE_FUNCTION(, IOTHUB_CLIENT_LL_HANDLE, IoTHubClient_LL_Create, const IOTHUB_CLIENT_CONFIG*, config); 57 58 58 59 /** 59 * @brief Creates a IoT Hub client for communication with an existing IoT 60 * Hub using the specified parameters. 61 * 62 * @param config Pointer to an @c IOTHUB_CLIENT_CONFIG structure 63 * 64 * The API does not allow sharing of a connection across multiple 65 * devices. This is a blocking call. 66 * 67 * @return A non-NULL @c IOTHUB_CLIENT_LL_HANDLE value that is used when 68 * invoking other functions for IoT Hub client and @c NULL on failure. 60 * @deprecated IoTHubClient_LL_CreateWithTransport is deprecated. Use IoTHubDeviceClient_LL_CreateWithTransport instead. 69 61 */ 70 MOCKABLE_FUNCTION(, IOTHUB_CLIENT_LL_HANDLE, IoTHubClient_LL_Create, const IOTHUB_CLIENT_CONFIG*, config);62 MOCKABLE_FUNCTION(, IOTHUB_CLIENT_LL_HANDLE, IoTHubClient_LL_CreateWithTransport, const IOTHUB_CLIENT_DEVICE_CONFIG*, config); 71 63 72 64 /** 73 * @brief Creates a IoT Hub client for communication with an existing IoT 74 * Hub using an existing transport. 75 * 76 * @param config Pointer to an @c IOTHUB_CLIENT_DEVICE_CONFIG structure 77 * 78 * The API *allows* sharing of a connection across multiple 79 * devices. This is a blocking call. 80 * 81 * @return A non-NULL @c IOTHUB_CLIENT_LL_HANDLE value that is used when 82 * invoking other functions for IoT Hub client and @c NULL on failure. 65 * @deprecated IoTHubClient_LL_CreateFromDeviceAuth is deprecated. Use IoTHubDeviceClient_LL_CreateFromDeviceAuth instead. 83 66 */ 84 MOCKABLE_FUNCTION(, IOTHUB_CLIENT_LL_HANDLE, IoTHubClient_LL_CreateWithTransport, const IOTHUB_CLIENT_DEVICE_CONFIG*, config); 85 86 /** 87 * @brief Creates a IoT Hub client for communication with an existing IoT 88 * Hub using the device auth module. 89 * 90 * @param iothub_uri Pointer to an ioThub hostname received in the registration process 91 * @param device_id Pointer to the device Id of the device 92 * @param device_auth_handle a device auth handle used to generate the connection string 93 * @param protocol Function pointer for protocol implementation 94 * 95 * @return A non-NULL @c IOTHUB_CLIENT_LL_HANDLE value that is used when 96 * invoking other functions for IoT Hub client and @c NULL on failure. 97 */ 98 MOCKABLE_FUNCTION(, IOTHUB_CLIENT_LL_HANDLE, IoTHubClient_LL_CreateFromDeviceAuth, const char*, iothub_uri, const char*, device_id, IOTHUB_CLIENT_TRANSPORT_PROVIDER, protocol); 67 MOCKABLE_FUNCTION(, IOTHUB_CLIENT_LL_HANDLE, IoTHubClient_LL_CreateFromDeviceAuth, const char*, iothub_uri, const char*, device_id, IOTHUB_CLIENT_TRANSPORT_PROVIDER, protocol); 99 68 100 69 /** 101 * @brief Disposes of resources allocated by the IoT Hub client. This is a 102 * blocking call. 103 * 104 * @param iotHubClientHandle The handle created by a call to the create function. 70 * @deprecated IoTHubClient_LL_Destroy is deprecatedDevice. Use IoTHubClient_LL_Destroy instead. 105 71 */ 106 72 MOCKABLE_FUNCTION(, void, IoTHubClient_LL_Destroy, IOTHUB_CLIENT_LL_HANDLE, iotHubClientHandle); 107 73 108 74 /** 109 * @brief Asynchronous call to send the message specified by @p eventMessageHandle. 110 * 111 * @param iotHubClientHandle The handle created by a call to the create function. 112 * @param eventMessageHandle The handle to an IoT Hub message. 113 * @param eventConfirmationCallback The callback specified by the device for receiving 114 * confirmation of the delivery of the IoT Hub message. 115 * This callback can be expected to invoke the 116 * ::IoTHubClient_LL_SendEventAsync function for the 117 * same message in an attempt to retry sending a failing 118 * message. The user can specify a @c NULL value here to 119 * indicate that no callback is required. 120 * @param userContextCallback User specified context that will be provided to the 121 * callback. This can be @c NULL. 122 * 123 * @b NOTE: The application behavior is undefined if the user calls 124 * the ::IoTHubClient_LL_Destroy function from within any callback. 125 * @remarks 126 * The IOTHUB_MESSAGE_HANDLE instance provided as argument is copied by the function, 127 * so this argument can be destroyed by the calling application right after IoTHubClient_LL_SendEventAsync returns. 128 * The copy of @c eventMessageHandle is later destroyed by the iothub client when the message is effectively sent, if a failure sending it occurs, or if the client is destroyed. 129 * @return IOTHUB_CLIENT_OK upon success or an error code upon failure. 75 * @deprecated IoTHubClient_LL_SendEventAsync is deprecated. Use IoTHubDeviceClient_LL_SendEventAsync instead. 130 76 */ 131 77 MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClient_LL_SendEventAsync, IOTHUB_CLIENT_LL_HANDLE, iotHubClientHandle, IOTHUB_MESSAGE_HANDLE, eventMessageHandle, IOTHUB_CLIENT_EVENT_CONFIRMATION_CALLBACK, eventConfirmationCallback, void*, userContextCallback); 132 78 133 79 /** 134 * @brief This function returns the current sending status for IoTHubClient. 135 * 136 * @param iotHubClientHandle The handle created by a call to the create function. 137 * @param iotHubClientStatus The sending state is populated at the address pointed 138 * at by this parameter. The value will be set to 139 * @c IOTHUBCLIENT_SENDSTATUS_IDLE if there is currently 140 * no item to be sent and @c IOTHUBCLIENT_SENDSTATUS_BUSY 141 * if there are. 142 * 143 * @return IOTHUB_CLIENT_OK upon success or an error code upon failure. 80 * @deprecated IoTHubClient_LL_GetSendStatus is deprecated. UseDevice IoTHubClient_LL_GetSendStatus instead. 144 81 */ 145 82 MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClient_LL_GetSendStatus, IOTHUB_CLIENT_LL_HANDLE, iotHubClientHandle, IOTHUB_CLIENT_STATUS*, iotHubClientStatus); 146 83 147 84 /** 148 * @brief Sets up the message callback to be invoked when IoT Hub issues a 149 * message to the device. This is a blocking call. 150 * 151 * @param iotHubClientHandle The handle created by a call to the create function. 152 * @param messageCallback The callback specified by the device for receiving 153 * messages from IoT Hub. 154 * @param userContextCallback User specified context that will be provided to the 155 * callback. This can be @c NULL. 156 * 157 * @b NOTE: The application behavior is undefined if the user calls 158 * the ::IoTHubClient_LL_Destroy function from within any callback. 159 * 160 * @return IOTHUB_CLIENT_OK upon success or an error code upon failure. 85 * @deprecated IoTHubClient_LL_SetMessageCallback is deprecated. Use IoTHubDeviceClient_LL_SetMessageCallback instead. 161 86 */ 162 87 MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClient_LL_SetMessageCallback, IOTHUB_CLIENT_LL_HANDLE, iotHubClientHandle, IOTHUB_CLIENT_MESSAGE_CALLBACK_ASYNC, messageCallback, void*, userContextCallback); 163 88 164 89 /** 165 * @brief Sets up the connection status callback to be invoked representing the status of 166 * the connection to IOT Hub. This is a blocking call. 167 * 168 * @param iotHubClientHandle The handle created by a call to the create function. 169 * @param connectionStatusCallback The callback specified by the device for receiving 170 * updates about the status of the connection to IoT Hub. 171 * @param userContextCallback User specified context that will be provided to the 172 * callback. This can be @c NULL. 173 * 174 * @b NOTE: The application behavior is undefined if the user calls 175 * the ::IoTHubClient_LL_Destroy function from within any callback. 176 * 177 * @return IOTHUB_CLIENT_OK upon success or an error code upon failure. 90 * @deprecated IoTHubClient_LL_SetConnectionStatusCallback is deprecated. Use IoTHubDeviceClient_LL_SetConnectionStatusCallback instead. 178 91 */ 179 92 MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClient_LL_SetConnectionStatusCallback, IOTHUB_CLIENT_LL_HANDLE, iotHubClientHandle, IOTHUB_CLIENT_CONNECTION_STATUS_CALLBACK, connectionStatusCallback, void*, userContextCallback); 180 93 181 94 /** 182 * @brief Sets up the connection status callback to be invoked representing the status of 183 * the connection to IOT Hub. This is a blocking call. 184 * 185 * @param iotHubClientHandle The handle created by a call to the create function. 186 * @param retryPolicy The policy to use to reconnect to IoT Hub when a 187 * connection drops. 188 * @param retryTimeoutLimitInSeconds Maximum amount of time(seconds) to attempt reconnection when a 189 * connection drops to IOT Hub. 190 * 191 * @b NOTE: The application behavior is undefined if the user calls 192 * the ::IoTHubClient_LL_Destroy function from within any callback. 193 * 194 * @return IOTHUB_CLIENT_OK upon success or an error code upon failure. 95 * @deprecated IoTHubClient_LL_SetRetryPolicy is deprecated. Use IoTHubDeviceClient_LL_SetRetryPolicy instead. 195 96 */ 196 MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClient_LL_SetRetryPolicy, IOTHUB_CLIENT_LL_HANDLE, iotHubClientHandle, IOTHUB_CLIENT_RETRY_POLICY, retryPolicy, size_t, retryTimeoutLimitInSeconds); 197 97 MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClient_LL_SetRetryPolicy, IOTHUB_CLIENT_LL_HANDLE, iotHubClientHandle, IOTHUB_CLIENT_RETRY_POLICY, retryPolicy, size_t, retryTimeoutLimitInSeconds); 198 98 199 99 /** 200 * @brief Sets up the connection status callback to be invoked representing the status of 201 * the connection to IOT Hub. This is a blocking call. 202 * 203 * @param iotHubClientHandle The handle created by a call to the create function. 204 * @param retryPolicy Out parameter containing the policy to use to reconnect to IoT Hub. 205 * @param retryTimeoutLimitInSeconds Out parameter containing maximum amount of time in seconds to attempt reconnection 206 to IOT Hub. 207 * 208 * @b NOTE: The application behavior is undefined if the user calls 209 * the ::IoTHubClient_LL_Destroy function from within any callback. 210 * 211 * @return IOTHUB_CLIENT_OK upon success or an error code upon failure. 100 * @deprecated IoTHubClient_LL_GetRetryPolicy is deprecated. Use IoTHubDeviceClient_LL_GetRetryPolicy instead. 212 101 */ 213 102 MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClient_LL_GetRetryPolicy, IOTHUB_CLIENT_LL_HANDLE, iotHubClientHandle, IOTHUB_CLIENT_RETRY_POLICY*, retryPolicy, size_t*, retryTimeoutLimitInSeconds); 214 103 215 104 /** 216 * @brief This function returns in the out parameter @p lastMessageReceiveTime 217 * what was the value of the @c time function when the last message was 218 * received at the client. 219 * 220 * @param iotHubClientHandle The handle created by a call to the create function. 221 * @param lastMessageReceiveTime Out parameter containing the value of @c time function 222 * when the last message was received. 223 * 224 * @return IOTHUB_CLIENT_OK upon success or an error code upon failure. 105 * @deprecated IoTHubClient_LL_GetLastMessageReceiveTime is deprecated. Use IoTHubDeviceClient_LL_GetLastMessageReceiveTime instead. 225 106 */ 226 107 MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClient_LL_GetLastMessageReceiveTime, IOTHUB_CLIENT_LL_HANDLE, iotHubClientHandle, time_t*, lastMessageReceiveTime); 227 108 228 109 /** 229 * @brief This function is meant to be called by the user when work 230 * (sending/receiving) can be done by the IoTHubClient. 231 * 232 * @param iotHubClientHandle The handle created by a call to the create function. 233 * 234 * All IoTHubClient interactions (in regards to network traffic 235 * and/or user level callbacks) are the effect of calling this 236 * function and they take place synchronously inside _DoWork. 110 * @deprecated IoTHubClient_LL_DoWork is deprecateDeviced. Use IoTHubDeviceClient_LL_DoWork instead. 237 111 */ 238 112 MOCKABLE_FUNCTION(, void, IoTHubClient_LL_DoWork, IOTHUB_CLIENT_LL_HANDLE, iotHubClientHandle); 239 113 240 114 /** 241 * @brief This API sets a runtime option identified by parameter @p optionName 242 * to a value pointed to by @p value. @p optionName and the data type 243 * @p value is pointing to are specific for every option. 244 * 245 * @param iotHubClientHandle The handle created by a call to the create function. 246 * @param optionName Name of the option. 247 * @param value The value. 248 * 249 * The options that can be set via this API are: 250 * - @b timeout - the maximum time in milliseconds a communication is 251 * allowed to use. @p value is a pointer to an @c unsigned @c int with 252 * the timeout value in milliseconds. This is only supported for the HTTP 253 * protocol as of now. When the HTTP protocol uses CURL, the meaning of 254 * the parameter is <em>total request time</em>. When the HTTP protocol uses 255 * winhttp, the meaning is the same as the @c dwSendTimeout and 256 * @c dwReceiveTimeout parameters of the 257 * <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/aa384116(v=vs.85).aspx"> 258 * WinHttpSetTimeouts</a> API. 259 * - @b CURLOPT_LOW_SPEED_LIMIT - only available for HTTP protocol and only 260 * when CURL is used. It has the same meaning as CURL's option with the same 261 * name. @p value is pointer to a long. 262 * - @b CURLOPT_LOW_SPEED_TIME - only available for HTTP protocol and only 263 * when CURL is used. It has the same meaning as CURL's option with the same 264 * name. @p value is pointer to a long. 265 * - @b CURLOPT_FORBID_REUSE - only available for HTTP protocol and only 266 * when CURL is used. It has the same meaning as CURL's option with the same 267 * name. @p value is pointer to a long. 268 * - @b CURLOPT_FRESH_CONNECT - only available for HTTP protocol and only 269 * when CURL is used. It has the same meaning as CURL's option with the same 270 * name. @p value is pointer to a long. 271 * - @b CURLOPT_VERBOSE - only available for HTTP protocol and only 272 * when CURL is used. It has the same meaning as CURL's option with the same 273 * name. @p value is pointer to a long. 274 * - @b keepalive - available for MQTT protocol. Integer value that sets the 275 * interval in seconds when pings are sent to the server. 276 * - @b logtrace - available for MQTT protocol. Boolean value that turns on and 277 * off the diagnostic logging. 278 * - @b sas_token_lifetime - available for MQTT & AMQP protocol. size_t value that that determines the 279 * sas token timeout length. 280 * 281 * @return IOTHUB_CLIENT_OK upon success or an error code upon failure. 115 * @deprecated IoTHubClient_LL_SetOption is deprecated. Device Use IoTHubDeviceClient_LL_SetOption instead. 282 116 */ 283 117 MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClient_LL_SetOption, IOTHUB_CLIENT_LL_HANDLE, iotHubClientHandle, const char*, optionName, const void*, value); 284 118 285 119 /** 286 * @brief This API specifies a call back to be used when the device receives a desired state update. 287 * 288 * @param iotHubClientHandle The handle created by a call to the create function. 289 * @param deviceTwinCallback The callback specified by the device client to be used for updating 290 * the desired state. The callback will be called in response to patch 291 * request send by the IoTHub services. The payload will be passed to the 292 * callback, along with two version numbers: 293 * - Desired: 294 * - LastSeenReported: 295 * @param userContextCallback User specified context that will be provided to the 296 * callback. This can be @c NULL. 297 * 298 * @b NOTE: The application behavior is undefined if the user calls 299 * the ::IoTHubClient_LL_Destroy function from within any callback. 300 * 301 * @return IOTHUB_CLIENT_OK upon success or an error code upon failure. 120 * @deprecated IoTHubClient_LL_SetDeviceTwinCallback is deprecated. Use IoTHubDeviceClient_LL_SetDeviceTwinCallback instead. 302 121 */ 303 122 MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClient_LL_SetDeviceTwinCallback, IOTHUB_CLIENT_LL_HANDLE, iotHubClientHandle, IOTHUB_CLIENT_DEVICE_TWIN_CALLBACK, deviceTwinCallback, void*, userContextCallback); 304 123 305 124 /** 306 * @brief This API sneds a report of the device's properties and their current values. 307 * 308 * @param iotHubClientHandle The handle created by a call to the create function. 309 * @param reportedState The current device property values to be 'reported' to the IoTHub. 310 * @param reportedStateCallback The callback specified by the device client to be called with the 311 * result of the transaction. 312 * @param userContextCallback User specified context that will be provided to the 313 * callback. This can be @c NULL. 314 * 315 * @b NOTE: The application behavior is undefined if the user calls 316 * the ::IoTHubClient_LL_Destroy function from within any callback. 317 * 318 * @return IOTHUB_CLIENT_OK upon success or an error code upon failure. 125 * @deprecated IoTHubClient_LL_SendReportedState is deprecated. Use IoTHubDeviceClient_LL_SendReportedState instead. 319 126 */ 320 127 MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClient_LL_SendReportedState, IOTHUB_CLIENT_LL_HANDLE, iotHubClientHandle, const unsigned char*, reportedState, size_t, size, IOTHUB_CLIENT_REPORTED_STATE_CALLBACK, reportedStateCallback, void*, userContextCallback); 321 128 322 /** 323 * @brief This API sets callback for cloud to device method call. 324 * 325 * @param iotHubClientHandle The handle created by a call to the create function. 326 * @param deviceMethodCallback The callback which will be called by IoTHub. 327 * @param userContextCallback User specified context that will be provided to the 328 * callback. This can be @c NULL. 329 * 330 * @return IOTHUB_CLIENT_OK upon success or an error code upon failure. 331 */ 332 MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClient_LL_SetDeviceMethodCallback, IOTHUB_CLIENT_LL_HANDLE, iotHubClientHandle, IOTHUB_CLIENT_DEVICE_METHOD_CALLBACK_ASYNC, deviceMethodCallback, void*, userContextCallback); 129 /** 130 * @deprecated IoTHubClient_LL_SetDeviceMethodCallback is deprecated. Use IoTHubDeviceClient_LL_SetDeviceMethodCallback instead. 131 */ 132 MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClient_LL_SetDeviceMethodCallback, IOTHUB_CLIENT_LL_HANDLE, iotHubClientHandle, IOTHUB_CLIENT_DEVICE_METHOD_CALLBACK_ASYNC, deviceMethodCallback, void*, userContextCallback); 333 133 334 /** 335 * @brief This API sets callback for async cloud to device method call. 336 * 337 * @param iotHubClientHandle The handle created by a call to the create function. 338 * @param inboundDeviceMethodCallback The callback which will be called by IoTHub. 339 * @param userContextCallback User specified context that will be provided to the 340 * callback. This can be @c NULL. 341 * 342 * @return IOTHUB_CLIENT_OK upon success or an error code upon failure. 343 */ 344 MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClient_LL_SetDeviceMethodCallback_Ex, IOTHUB_CLIENT_LL_HANDLE, iotHubClientHandle, IOTHUB_CLIENT_INBOUND_DEVICE_METHOD_CALLBACK, inboundDeviceMethodCallback, void*, userContextCallback); 134 /** 135 * @deprecated IoTHubClient_LL_SetDeviceMethodCallback_Ex is deprecated. Use IoTHubDeviceClient_LL_SetDeviceMethodCallback instead. 136 */ 137 MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClient_LL_SetDeviceMethodCallback_Ex, IOTHUB_CLIENT_LL_HANDLE, iotHubClientHandle, IOTHUB_CLIENT_INBOUND_DEVICE_METHOD_CALLBACK, inboundDeviceMethodCallback, void*, userContextCallback); 345 138 346 /** 347 * @brief This API responses to a asnyc method callback identified the methodId. 348 * 349 * @param iotHubClientHandle The handle created by a call to the create function. 350 * @param methodId The methodId of the Device Method callback. 351 * @param response The response data for the method callback. 352 * @param response_size The size of the response data buffer. 353 * @param status_response The status response of the method callback. 354 * 355 * @return IOTHUB_CLIENT_OK upon success or an error code upon failure. 356 */ 357 MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClient_LL_DeviceMethodResponse, IOTHUB_CLIENT_LL_HANDLE, iotHubClientHandle, METHOD_HANDLE, methodId, const unsigned char*, response, size_t, respSize, int, statusCode); 139 /** 140 * @deprecated IoTHubClient_LL_DeviceMethodResponse is deprecated. Use IoTHubDeviceClient_LL_SetDeviceMethodCallback instead. 141 */ 142 MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClient_LL_DeviceMethodResponse, IOTHUB_CLIENT_LL_HANDLE, iotHubClientHandle, METHOD_HANDLE, methodId, const unsigned char*, response, size_t, respSize, int, statusCode); 358 143 359 144 #ifndef DONT_USE_UPLOADTOBLOB 360 145 /** 361 * @brief This API uploads to Azure Storage the content pointed to by @p source having the size @p size 362 * under the blob name devicename/@pdestinationFileName 363 * 364 * @param iotHubClientHandle The handle created by a call to the create function. 365 * @param destinationFileName name of the file. 366 * @param source pointer to the source for file content (can be NULL) 367 * @param size the size of the source in memory (if @p source is NULL then size needs to be 0). 368 * 369 * @return IOTHUB_CLIENT_OK upon success or an error code upon failure. 146 * @deprecated IoTHubClient_LL_UploadToBlob is deprecated. UsDevicee IoTHubDeviceClient_LL_UploadToBlob instead. 370 147 */ 371 148 MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClient_LL_UploadToBlob, IOTHUB_CLIENT_LL_HANDLE, iotHubClientHandle, const char*, destinationFileName, const unsigned char*, source, size_t, size); 372 149 373 /** 374 ** DEPRECATED: Use IoTHubClient_LL_UploadMultipleBlocksToBlobAsyncEx instead ** 375 * @brief This API uploads to Azure Storage the content provided block by block by @p getDataCallback 376 * under the blob name devicename/@pdestinationFileName 377 * 378 * @param iotHubClientHandle The handle created by a call to the create function. 379 * @param destinationFileName name of the file. 380 * @param getDataCallback A callback to be invoked to acquire the file chunks to be uploaded, as well as to indicate the status of the upload of the previous block. 381 * @param context Any data provided by the user to serve as context on getDataCallback. 382 * 383 * @return IOTHUB_CLIENT_OK upon success or an error code upon failure. 384 ** DEPRECATED: Use IoTHubClient_LL_UploadMultipleBlocksToBlobAsyncEx instead ** 385 */ 386 MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClient_LL_UploadMultipleBlocksToBlob, IOTHUB_CLIENT_LL_HANDLE, iotHubClientHandle, const char*, destinationFileName, IOTHUB_CLIENT_FILE_UPLOAD_GET_DATA_CALLBACK, getDataCallback, void*, context); 150 /** 151 * @deprecated IoTHubClient_LL_UploadMultipleBlocksToBlob is deprecated. Use IoTHubDeviceClient_LL_UploadMultipleBlocksToBlob instead. 152 */ 153 MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClient_LL_UploadMultipleBlocksToBlob, IOTHUB_CLIENT_LL_HANDLE, iotHubClientHandle, const char*, destinationFileName, IOTHUB_CLIENT_FILE_UPLOAD_GET_DATA_CALLBACK, getDataCallback, void*, context); 387 154 388 /** 389 * @brief This API uploads to Azure Storage the content provided block by block by @p getDataCallback 390 * under the blob name devicename/@pdestinationFileName 391 * 392 * @param iotHubClientHandle The handle created by a call to the create function. 393 * @param destinationFileName name of the file. 394 * @param getDataCallbackEx A callback to be invoked to acquire the file chunks to be uploaded, as well as to indicate the status of the upload of the previous block. 395 * @param context Any data provided by the user to serve as context on getDataCallback. 396 * 397 * @return IOTHUB_CLIENT_OK upon success or an error code upon failure. 398 */ 399 MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClient_LL_UploadMultipleBlocksToBlobEx, IOTHUB_CLIENT_LL_HANDLE, iotHubClientHandle, const char*, destinationFileName, IOTHUB_CLIENT_FILE_UPLOAD_GET_DATA_CALLBACK_EX, getDataCallbackEx, void*, context); 155 /** 156 * @deprecated IoTHubClient_LL_UploadMultipleBlocksToBlobEx is deprecated. Use IoTHubDeviceClient_LL_UploadMultipleBlocksToBlob instead. 157 */ 158 MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClient_LL_UploadMultipleBlocksToBlobEx, IOTHUB_CLIENT_LL_HANDLE, iotHubClientHandle, const char*, destinationFileName, IOTHUB_CLIENT_FILE_UPLOAD_GET_DATA_CALLBACK_EX, getDataCallbackEx, void*, context); 400 159 401 160 #endif /*DONT_USE_UPLOADTOBLOB*/ -
azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/inc/iothub_client_options.h
r457 r464 28 28 static STATIC_VAR_UNUSED const char* OPTION_CONNECTION_TIMEOUT = "connect_timeout"; 29 29 30 /* None of the OPTION_PROXY_* options below are implemented. Use OPTION_HTTP_PROXY 31 from shared_util_options.h in https://github.com/Azure/azure-c-shared-utility/ repo instead */ 30 32 static STATIC_VAR_UNUSED const char* OPTION_PROXY_HOST = "proxy_address"; 31 33 static STATIC_VAR_UNUSED const char* OPTION_PROXY_USERNAME = "proxy_username"; … … 87 89 static STATIC_VAR_UNUSED const char* OPTION_DO_WORK_FREQUENCY_IN_MS = "do_work_freq_ms"; 88 90 91 // Minimum percentage (in the 0 to 1 range) of multiplexed registered devices that must be failing for a transport-wide reconnection to be triggered. 92 // A value of zero results in a single registered device to be able to cause a general transport reconnection 93 // (thus causing all other multiplexed registered devices to be also reconnected, meaning an agressive reconnection strategy). 94 // Setting this parameter to one indicates that 100% of the multiplexed registered devices must be failing in parallel for a 95 // transport-wide reconnection to be triggered (resulting in a very lenient reconnection strategy). 96 #define DEVICE_MULTIPLEXING_FAULTY_DEVICE_RATIO_RECONNECTION_THRESHOLD 0 97 98 // Minimum number of consecutive failures an individual registered device must have to be considered a faulty device. 99 // This is used along with DEVICE_MULTIPLEXING_FAULTY_DEVICE_RATIO_RECONNECTION_THRESHOLD to trigger transport-wide reconnections. 100 // The device may fail to authenticate, timeout establishing the connection, get disconnected by the service for some reason or fail sending messages. 101 // In all these cases the failures are cummulatively counted; if the count is equal to or greater than DEVICE_FAILURE_COUNT_RECONNECTION_THRESHOLD 102 // the device is considered to be in a faulty state. 103 #define DEVICE_FAILURE_COUNT_RECONNECTION_THRESHOLD 5 104 89 105 #ifdef __cplusplus 90 106 } -
azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/inc/iothub_client_version.h
r457 r464 9 9 #define IOTHUB_CLIENT_VERSION_H 10 10 11 #define IOTHUB_SDK_VERSION "1. 3.8"11 #define IOTHUB_SDK_VERSION "1.6.0" 12 12 13 13 #include "umock_c/umock_c_prod.h" -
azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/inc/iothub_device_client_ll.h
r457 r464 6 6 * with an Azure IoTHub. 7 7 * 8 * @details IoTHubDeviceClient_LL is a module thatallows a user (usually a8 * @details IoTHubDeviceClient_LL allows a user (usually a 9 9 * device) to communicate with an Azure IoTHub. It can send events 10 10 * and receive messages. At any given moment in time there can only … … 16 16 * @c IoTHubDeviceClient_... APIs, with one difference. If the @c _LL_ APIs are 17 17 * used then the user is responsible for scheduling when the actual work done 18 * by the IoTHubClient happens (when the data is sent/received on/from the wire).18 * by the IoTHubClient happens (when the data is sent/received on/from the network). 19 19 * This is useful for constrained devices where spinning a separate thread is 20 20 * often not desired. … … 88 88 /** 89 89 * @brief Creates a IoT Hub client for communication with an existing IoT 90 * Hub using the device auth module.90 * Hub using the device auth. 91 91 * 92 92 * @param iothub_uri Pointer to an ioThub hostname received in the registration process … … 116 116 * confirmation of the delivery of the IoT Hub message. 117 117 * This callback can be expected to invoke the 118 * ::IoTHubDeviceClient_LL_SendEventAsync function for the118 * IoTHubDeviceClient_LL_SendEventAsync function for the 119 119 * same message in an attempt to retry sending a failing 120 120 * message. The user can specify a @c NULL value here to … … 124 124 * 125 125 * @b NOTE: The application behavior is undefined if the user calls 126 * the ::IoTHubDeviceClient_LL_Destroy function from within any callback.126 * the IoTHubDeviceClient_LL_Destroy function from within any callback. 127 127 * @remarks 128 128 * The IOTHUB_MESSAGE_HANDLE instance provided as argument is copied by the function, … … 139 139 * @param iotHubClientStatus The sending state is populated at the address pointed 140 140 * at by this parameter. The value will be set to 141 * @c IOTHUB CLIENT_SENDSTATUS_IDLE if there is currently142 * no item to be sent and @c IOTHUB CLIENT_SENDSTATUS_BUSY141 * @c IOTHUB_CLIENT_SEND_STATUS_IDLE if there is currently 142 * no item to be sent and @c IOTHUB_CLIENT_SEND_STATUS_BUSY 143 143 * if there are. 144 * 145 * @remark Does not return information related to uploads initiated by IoTHubDeviceClient_LL_UploadToBlob or IoTHubDeviceClient_LL_UploadMultipleBlocksToBlob. 144 146 * 145 147 * @return IOTHUB_CLIENT_OK upon success or an error code upon failure. … … 158 160 * 159 161 * @b NOTE: The application behavior is undefined if the user calls 160 * the ::IoTHubDeviceClient_LL_Destroy function from within any callback.162 * the IoTHubDeviceClient_LL_Destroy function from within any callback. 161 163 * 162 164 * @return IOTHUB_CLIENT_OK upon success or an error code upon failure. … … 175 177 * 176 178 * @b NOTE: The application behavior is undefined if the user calls 177 * the ::IoTHubDeviceClient_LL_Destroy function from within any callback. 179 * the IoTHubDeviceClient_LL_Destroy function from within any callback. 180 * 181 * @remark Callback specified will not receive connection status change notifications for upload connections created with IoTHubDeviceClient_LL_UploadToBlob or IoTHubDeviceClient_LL_UploadMultipleBlocksToBlob. 178 182 * 179 183 * @return IOTHUB_CLIENT_OK upon success or an error code upon failure. … … 192 196 * 193 197 * @b NOTE: The application behavior is undefined if the user calls 194 * the ::IoTHubDeviceClient_LL_Destroy function from within any callback. 198 * the IoTHubDeviceClient_LL_Destroy function from within any callback. 199 * 200 * @remark Uploads initiated by IoTHubDeviceClient_LL_UploadToBlob or IoTHubDeviceClient_LL_UploadMultipleBlocksToBlob do not have automatic retries and do not honor the retryPolicy settings. 195 201 * 196 202 * @return IOTHUB_CLIENT_OK upon success or an error code upon failure. … … 209 215 * 210 216 * @b NOTE: The application behavior is undefined if the user calls 211 * the ::IoTHubDeviceClient_LL_Destroy function from within any callback.217 * the IoTHubDeviceClient_LL_Destroy function from within any callback. 212 218 * 213 219 * @return IOTHUB_CLIENT_OK upon success or an error code upon failure. … … 229 235 230 236 /** 231 * @brief This function MUST be called by the user so work (sending/receiving data on the wire,237 * @brief This function MUST be called by the user so work (sending/receiving data on the network, 232 238 * computing and enforcing timeout controls, managing the connection to the IoT Hub) can 233 239 * be done by the IoTHubClient. … … 251 257 * @param value The value. 252 258 * 253 * The options that can be set via this API are: 254 * - @b timeout - the maximum time in milliseconds a communication is 255 * allowed to use. @p value is a pointer to an @c unsigned @c int with 256 * the timeout value in milliseconds. This is only supported for the HTTP 257 * protocol as of now. When the HTTP protocol uses CURL, the meaning of 258 * the parameter is <em>total request time</em>. When the HTTP protocol uses 259 * winhttp, the meaning is the same as the @c dwSendTimeout and 260 * @c dwReceiveTimeout parameters of the 261 * <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/aa384116(v=vs.85).aspx"> 262 * WinHttpSetTimeouts</a> API. 263 * - @b CURLOPT_LOW_SPEED_LIMIT - only available for HTTP protocol and only 264 * when CURL is used. It has the same meaning as CURL's option with the same 265 * name. @p value is pointer to a long. 266 * - @b CURLOPT_LOW_SPEED_TIME - only available for HTTP protocol and only 267 * when CURL is used. It has the same meaning as CURL's option with the same 268 * name. @p value is pointer to a long. 269 * - @b CURLOPT_FORBID_REUSE - only available for HTTP protocol and only 270 * when CURL is used. It has the same meaning as CURL's option with the same 271 * name. @p value is pointer to a long. 272 * - @b CURLOPT_FRESH_CONNECT - only available for HTTP protocol and only 273 * when CURL is used. It has the same meaning as CURL's option with the same 274 * name. @p value is pointer to a long. 275 * - @b CURLOPT_VERBOSE - only available for HTTP protocol and only 276 * when CURL is used. It has the same meaning as CURL's option with the same 277 * name. @p value is pointer to a long. 278 * - @b keepalive - available for MQTT protocol. Integer value that sets the 279 * interval in seconds when pings are sent to the server. 280 * - @b logtrace - available for MQTT protocol. Boolean value that turns on and 281 * off the diagnostic logging. 282 * - @b sas_token_lifetime - available for MQTT & AMQP protocol. size_t value that that determines the 283 * sas token timeout length. 284 * - @b OPTION_TRUSTED_CERT - Azure Server certificate used to validate TLS connection to iothub. 259 * @remarks Documentation for configuration options is available at https://github.com/Azure/azure-iot-sdk-c/blob/master/doc/Iothub_sdk_options.md. 285 260 * 286 261 * @return IOTHUB_CLIENT_OK upon success or an error code upon failure. … … 302 277 * 303 278 * @b NOTE: The application behavior is undefined if the user calls 304 * the ::IoTHubDeviceClient_LL_Destroy function from within any callback.279 * the IoTHubDeviceClient_LL_Destroy function from within any callback. 305 280 * 306 281 * @return IOTHUB_CLIENT_OK upon success or an error code upon failure. … … 319 294 * 320 295 * @b NOTE: The application behavior is undefined if the user calls 321 * the ::IoTHubDeviceClient_LL_Destroy function from within any callback.296 * the IoTHubDeviceClient_LL_Destroy function from within any callback. 322 297 * 323 298 * @return IOTHUB_CLIENT_OK upon success or an error code upon failure. … … 334 309 * 335 310 * @b NOTE: The application behavior is undefined if the user calls 336 * the ::IoTHubClient_LL_Destroy function from within any callback.311 * the IoTHubClient_LL_Destroy function from within any callback. 337 312 * 338 313 * @return IOTHUB_CLIENT_OK upon success or an error code upon failure. … … 374 349 * @param source pointer to the source for file content (can be NULL) 375 350 * @param size the size of the source in memory (if @p source is NULL then size needs to be 0). 351 * 352 * @warning Other _LL_ functions such as IoTHubDeviceClient_LL_SendEventAsync queue work to be performed later and do not block. IoTHubDeviceClient_LL_UploadToBlob 353 * will block however until the upload is completed or fails, which may take a while. 376 354 * 377 355 * @return IOTHUB_CLIENT_OK upon success or an error code upon failure. … … 388 366 * @param context Any data provided by the user to serve as context on getDataCallback. 389 367 * 368 * @warning Other _LL_ functions such as IoTHubDeviceClient_LL_SendEventAsync queue work to be performed later and do not block. IoTHubDeviceClient_LL_UploadMultipleBlocksToBlob 369 * will block however until the upload is completed or fails, which may take a while. 370 * 390 371 * @return IOTHUB_CLIENT_OK upon success or an error code upon failure. 391 372 */ -
azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/inc/iothub_message.h
r457 r464 192 192 * @param iotHubMessageHandle Handle to the message. 193 193 * 194 * @param key name of the property to set. Note that when sending messages via the HTTP transport, this value must not contain spaces. 195 * 196 * @param value of the property to set. 194 * @param key name of the property to set. Note that when sending messages via the HTTP transport, this value must not contain spaces. 195 * 196 * @param value of the property to set. 197 * 198 * @b NOTE: The accepted character sets for the key name and value parameters are dependent on different factors, such as the protocol 199 * being used. For more information on the character sets accepted by Azure IoT Hub, see 200 * <a href="https://docs.microsoft.com/azure/iot-hub/iot-hub-devguide-messages-construct">Create and read IoT Hub messages</a>. 197 201 * 198 202 * @return An @c IOTHUB_MESSAGE_RESULT value indicating the result of setting the property. … … 252 256 * @param correlationId Pointer to the memory location of the messageId 253 257 * 254 * @return Returns IOTHUB_MESSAGE_OK if the messageId was set successfully258 * @return Returns IOTHUB_MESSAGE_OK if the CorrelationId was set successfully 255 259 * or an error code otherwise. 256 260 */ … … 295 299 * @param outputName Pointer to the queue to output message to 296 300 * 297 * @return Returns IOTHUB_MESSAGE_OK if the DiagnosticDatawas set successfully301 * @return Returns IOTHUB_MESSAGE_OK if the outputName was set successfully 298 302 * or an error code otherwise. 299 303 */ … … 318 322 * @param inputName Pointer to the queue to input message to 319 323 * 320 * @return Returns IOTHUB_MESSAGE_OK if the DiagnosticDatawas set successfully324 * @return Returns IOTHUB_MESSAGE_OK if the inputName was set successfully 321 325 * or an error code otherwise. 322 326 */ … … 340 344 * @param connectionModuleId Pointer to the module ID of connector 341 345 * 342 * @return Returns IOTHUB_MESSAGE_OK if the DiagnosticDatawas set successfully346 * @return Returns IOTHUB_MESSAGE_OK if the connectionModuleId was set successfully 343 347 * or an error code otherwise. 344 348 */ 345 349 MOCKABLE_FUNCTION(, IOTHUB_MESSAGE_RESULT, IoTHubMessage_SetConnectionModuleId, IOTHUB_MESSAGE_HANDLE, iotHubMessageHandle, const char*, connectionModuleId); 346 350 347 348 351 /** 349 352 * @brief Gets the connection device ID from the IOTHUB_MESSAGE_HANDLE. No new memory is allocated, … … 356 359 */ 357 360 MOCKABLE_FUNCTION(, const char*, IoTHubMessage_GetConnectionDeviceId, IOTHUB_MESSAGE_HANDLE, iotHubMessageHandle); 361 362 /** 363 * @brief Sets the message creation time in UTC. 364 * 365 * @param iotHubMessageHandle Handle to the message. 366 * @param messageCreationTimeUtc Pointer to the message creation time as null-terminated string 367 * 368 * @return Returns IOTHUB_MESSAGE_OK if the messageCreationTimeUtc was set successfully 369 * or an error code otherwise. 370 */ 371 MOCKABLE_FUNCTION(, IOTHUB_MESSAGE_RESULT, IoTHubMessage_SetMessageCreationTimeUtcSystemProperty, IOTHUB_MESSAGE_HANDLE, iotHubMessageHandle, const char*, messageCreationTimeUtc); 372 373 /** 374 * @brief Gets the message creation time in UTC from the IOTHUB_MESSAGE_HANDLE. No new memory is allocated, 375 * the caller is not responsible for freeing the memory. The memory 376 * is valid until IoTHubMessage_Destroy is called on the message. 377 * 378 * @param iotHubMessageHandle Handle to the message. 379 * 380 * @return A const char* pointing to the message creation time in UTC. 381 */ 382 MOCKABLE_FUNCTION(, const char*, IoTHubMessage_GetMessageCreationTimeUtcSystemProperty, IOTHUB_MESSAGE_HANDLE, iotHubMessageHandle); 383 384 /** 385 * @brief Sets the message user id. CAUTION: SDK user should not call it directly, it is for internal use only. 386 * 387 * @param iotHubMessageHandle Handle to the message. 388 * @param userId Pointer to the message user id as null-terminated string 389 * 390 * @return Returns IOTHUB_MESSAGE_OK if the userId was set successfully or an error code otherwise. 391 */ 392 MOCKABLE_FUNCTION(, IOTHUB_MESSAGE_RESULT, IoTHubMessage_SetMessageUserIdSystemProperty, IOTHUB_MESSAGE_HANDLE, iotHubMessageHandle, const char*, userId); 393 394 /** 395 * @brief Gets the message user id from the IOTHUB_MESSAGE_HANDLE. No new memory is allocated, 396 * the caller is not responsible for freeing the memory. The memory 397 * is valid until IoTHubMessage_Destroy is called on the message. 398 * 399 * @param iotHubMessageHandle Handle to the message. 400 * 401 * @return A const char* pointing to the message user id. 402 */ 403 MOCKABLE_FUNCTION(, const char*, IoTHubMessage_GetMessageUserIdSystemProperty, IOTHUB_MESSAGE_HANDLE, iotHubMessageHandle); 358 404 359 405 /** -
azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/src/blob.c
r457 r464 13 13 #include "azure_c_shared_utility/azure_base64.h" 14 14 #include "azure_c_shared_utility/shared_util_options.h" 15 16 static const char blockListXmlBegin[] = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<BlockList>"; 17 static const char blockListXmlEnd[] = "</BlockList>"; 18 static const char blockListUriMarker[] = "&comp=blocklist"; 15 19 16 20 BLOB_RESULT Blob_UploadBlock( … … 132 136 } 133 137 138 139 // InvokeUserCallbackAndSendBlobs invokes the application's getDataCallbackEx as many time as callback requests and, for each call, 140 // sends the blob contents to the server. 141 static BLOB_RESULT InvokeUserCallbackAndSendBlobs(HTTPAPIEX_HANDLE httpApiExHandle, const char* relativePath, STRING_HANDLE blockIDList, IOTHUB_CLIENT_FILE_UPLOAD_GET_DATA_CALLBACK_EX getDataCallbackEx, void* context, unsigned int* httpStatus, BUFFER_HANDLE httpResponse) 142 { 143 BLOB_RESULT result; 144 145 /*Codes_SRS_BLOB_02_021: [ For every block returned by `getDataCallbackEx` the following operations shall happen: ]*/ 146 unsigned int blockID = 0; /* incremented for each new block */ 147 unsigned int isError = 0; /* set to 1 if a block upload fails or if getDataCallbackEx returns incorrect blocks to upload */ 148 unsigned int uploadOneMoreBlock = 1; /* set to 1 while getDataCallbackEx returns correct blocks to upload */ 149 unsigned char const * source = NULL; /* data set by getDataCallbackEx */ 150 size_t size = 0; /* source size set by getDataCallbackEx */ 151 IOTHUB_CLIENT_FILE_UPLOAD_GET_DATA_RESULT getDataReturnValue; 152 153 do 154 { 155 getDataReturnValue = getDataCallbackEx(FILE_UPLOAD_OK, &source, &size, context); 156 if (getDataReturnValue == IOTHUB_CLIENT_FILE_UPLOAD_GET_DATA_ABORT) 157 { 158 /*Codes_SRS_BLOB_99_004: [ If `getDataCallbackEx` returns `IOTHUB_CLIENT_FILE_UPLOAD_GET_DATA_RESULT_ABORT`, then `Blob_UploadMultipleBlocksFromSasUri` shall exit the loop and return `BLOB_ABORTED`. ]*/ 159 LogInfo("Upload to blob has been aborted by the user"); 160 uploadOneMoreBlock = 0; 161 result = BLOB_ABORTED; 162 } 163 else if (source == NULL || size == 0) 164 { 165 /*Codes_SRS_BLOB_99_002: [ If the size of the block returned by `getDataCallbackEx` is 0 or if the data is NULL, then `Blob_UploadMultipleBlocksFromSasUri` shall exit the loop. ]*/ 166 uploadOneMoreBlock = 0; 167 result = BLOB_OK; 168 } 169 else 170 { 171 if (size > BLOCK_SIZE) 172 { 173 /*Codes_SRS_BLOB_99_001: [ If the size of the block returned by `getDataCallbackEx` is bigger than 4MB, then `Blob_UploadMultipleBlocksFromSasUri` shall fail and return `BLOB_INVALID_ARG`. ]*/ 174 LogError("tried to upload block of size %lu, max allowed size is %d", (unsigned long)size, BLOCK_SIZE); 175 result = BLOB_INVALID_ARG; 176 isError = 1; 177 } 178 else if (blockID >= MAX_BLOCK_COUNT) 179 { 180 /*Codes_SRS_BLOB_99_003: [ If `getDataCallbackEx` returns more than 50000 blocks, then `Blob_UploadMultipleBlocksFromSasUri` shall fail and return `BLOB_INVALID_ARG`. ]*/ 181 LogError("unable to upload more than %lu blocks in one blob", (unsigned long)MAX_BLOCK_COUNT); 182 result = BLOB_INVALID_ARG; 183 isError = 1; 184 } 185 else 186 { 187 /*Codes_SRS_BLOB_02_023: [ Blob_UploadMultipleBlocksFromSasUri shall create a BUFFER_HANDLE from source and size parameters. ]*/ 188 BUFFER_HANDLE requestContent = BUFFER_create(source, size); 189 if (requestContent == NULL) 190 { 191 /*Codes_SRS_BLOB_02_033: [ If any previous operation that doesn't have an explicit failure description fails then Blob_UploadMultipleBlocksFromSasUri shall fail and return BLOB_ERROR ]*/ 192 LogError("unable to BUFFER_create"); 193 result = BLOB_ERROR; 194 isError = 1; 195 } 196 else 197 { 198 result = Blob_UploadBlock( 199 httpApiExHandle, 200 relativePath, 201 requestContent, 202 blockID, 203 blockIDList, 204 httpStatus, 205 httpResponse); 206 207 BUFFER_delete(requestContent); 208 } 209 210 /*Codes_SRS_BLOB_02_026: [ Otherwise, if HTTP response code is >=300 then Blob_UploadMultipleBlocksFromSasUri shall succeed and return BLOB_OK. ]*/ 211 if (result != BLOB_OK) 212 { 213 LogError("unable to Blob_UploadBlock. Returned value=%d", result); 214 isError = 1; 215 } 216 else if (*httpStatus >= 300) 217 { 218 LogError("unable to Blob_UploadBlock. Returned httpStatus=%u", (unsigned int)*httpStatus); 219 isError = 1; 220 } 221 } 222 blockID++; 223 } 224 } 225 while(uploadOneMoreBlock && !isError); 226 227 return result; 228 } 229 230 // SendBlockIdList to send an XML of uploaded blockIds to the server after the application's payload block(s) have been transfered. 231 static BLOB_RESULT SendBlockIdList(HTTPAPIEX_HANDLE httpApiExHandle, const char* relativePath, STRING_HANDLE blockIDList, unsigned int* httpStatus, BUFFER_HANDLE httpResponse) 232 { 233 BLOB_RESULT result; 234 235 /*complete the XML*/ 236 if (STRING_concat(blockIDList, blockListXmlEnd) != 0) 237 { 238 /*Codes_SRS_BLOB_02_033: [ If any previous operation that doesn't have an explicit failure description fails then Blob_UploadMultipleBlocksFromSasUri shall fail and return BLOB_ERROR ]*/ 239 LogError("failed to STRING_concat"); 240 result = BLOB_ERROR; 241 } 242 else 243 { 244 /*Codes_SRS_BLOB_02_029: [Blob_UploadMultipleBlocksFromSasUri shall construct a new relativePath from following string : base relativePath + "&comp=blocklist"]*/ 245 STRING_HANDLE newRelativePath = STRING_construct(relativePath); 246 if (newRelativePath == NULL) 247 { 248 /*Codes_SRS_BLOB_02_033: [ If any previous operation that doesn't have an explicit failure description fails then Blob_UploadMultipleBlocksFromSasUri shall fail and return BLOB_ERROR ]*/ 249 LogError("failed to STRING_construct"); 250 result = BLOB_ERROR; 251 } 252 else 253 { 254 if (STRING_concat(newRelativePath, blockListUriMarker) != 0) 255 { 256 /*Codes_SRS_BLOB_02_033: [ If any previous operation that doesn't have an explicit failure description fails then Blob_UploadMultipleBlocksFromSasUri shall fail and return BLOB_ERROR ]*/ 257 LogError("failed to STRING_concat"); 258 result = BLOB_ERROR; 259 } 260 else 261 { 262 /*Codes_SRS_BLOB_02_030: [ Blob_UploadMultipleBlocksFromSasUri shall call HTTPAPIEX_ExecuteRequest with a PUT operation, passing the new relativePath, httpStatus and httpResponse and the XML string as content. ]*/ 263 const char* s = STRING_c_str(blockIDList); 264 BUFFER_HANDLE blockIDListAsBuffer = BUFFER_create((const unsigned char*)s, strlen(s)); 265 if (blockIDListAsBuffer == NULL) 266 { 267 /*Codes_SRS_BLOB_02_033: [ If any previous operation that doesn't have an explicit failure description fails then Blob_UploadMultipleBlocksFromSasUri shall fail and return BLOB_ERROR ]*/ 268 LogError("failed to BUFFER_create"); 269 result = BLOB_ERROR; 270 } 271 else 272 { 273 if (HTTPAPIEX_ExecuteRequest( 274 httpApiExHandle, 275 HTTPAPI_REQUEST_PUT, 276 STRING_c_str(newRelativePath), 277 NULL, 278 blockIDListAsBuffer, 279 httpStatus, 280 NULL, 281 httpResponse 282 ) != HTTPAPIEX_OK) 283 { 284 /*Codes_SRS_BLOB_02_031: [ If HTTPAPIEX_ExecuteRequest fails then Blob_UploadMultipleBlocksFromSasUri shall fail and return BLOB_HTTP_ERROR. ]*/ 285 LogError("unable to HTTPAPIEX_ExecuteRequest"); 286 result = BLOB_HTTP_ERROR; 287 } 288 else 289 { 290 /*Codes_SRS_BLOB_02_032: [ Otherwise, Blob_UploadMultipleBlocksFromSasUri shall succeed and return BLOB_OK. ]*/ 291 result = BLOB_OK; 292 } 293 BUFFER_delete(blockIDListAsBuffer); 294 } 295 } 296 STRING_delete(newRelativePath); 297 } 298 } 299 300 return result; 301 } 302 303 134 304 BLOB_RESULT Blob_UploadMultipleBlocksFromSasUri(const char* SASURI, IOTHUB_CLIENT_FILE_UPLOAD_GET_DATA_CALLBACK_EX getDataCallbackEx, void* context, unsigned int* httpStatus, BUFFER_HANDLE httpResponse, const char* certificates, HTTP_PROXY_OPTIONS *proxyOptions) 135 305 { 136 306 BLOB_RESULT result; 307 const char* hostnameBegin; 308 STRING_HANDLE blockIDList = NULL; 309 HTTPAPIEX_HANDLE httpApiExHandle = NULL; 310 char* hostname = NULL; 311 137 312 /*Codes_SRS_BLOB_02_001: [ If SASURI is NULL then Blob_UploadMultipleBlocksFromSasUri shall fail and return BLOB_INVALID_ARG. ]*/ 138 if (SASURI == NULL) 139 { 140 LogError("parameter SASURI is NULL"); 313 /*Codes_SRS_BLOB_02_002: [ If getDataCallbackEx is NULL then Blob_UploadMultipleBlocksFromSasUri shall fail and return BLOB_INVALID_ARG. ]*/ 314 if ((SASURI == NULL) || (getDataCallbackEx == NULL)) 315 { 316 LogError("One or more required values is NULL, SASURI=%p, getDataCallbackEx=%p", SASURI, getDataCallbackEx); 141 317 result = BLOB_INVALID_ARG; 142 318 } 319 /*Codes_SRS_BLOB_02_017: [ Blob_UploadMultipleBlocksFromSasUri shall copy from SASURI the hostname to a new const char* ]*/ 320 /*to find the hostname, the following logic is applied:*/ 321 /*the hostname starts at the first character after "://"*/ 322 /*the hostname ends at the first character before the next "/" after "://"*/ 323 else if ((hostnameBegin = strstr(SASURI, "://")) == NULL) 324 { 325 /*Codes_SRS_BLOB_02_005: [ If the hostname cannot be determined, then Blob_UploadMultipleBlocksFromSasUri shall fail and return BLOB_INVALID_ARG. ]*/ 326 LogError("hostname cannot be determined"); 327 result = BLOB_INVALID_ARG; 328 } 143 329 else 144 330 { 145 /*Codes_SRS_BLOB_02_002: [ If getDataCallbackEx is NULL then Blob_UploadMultipleBlocksFromSasUri shall fail and return BLOB_INVALID_ARG. ]*/ 146 if (getDataCallbackEx == NULL) 147 { 148 LogError("IOTHUB_CLIENT_FILE_UPLOAD_GET_DATA_CALLBACK_EX getDataCallbackEx is NULL"); 331 hostnameBegin += 3; /*have to skip 3 characters which are "://"*/ 332 const char* relativePath = strchr(hostnameBegin, '/'); 333 if (relativePath == NULL) 334 { 335 /*Codes_SRS_BLOB_02_005: [ If the hostname cannot be determined, then Blob_UploadMultipleBlocksFromSasUri shall fail and return BLOB_INVALID_ARG. ]*/ 336 LogError("hostname cannot be determined"); 149 337 result = BLOB_INVALID_ARG; 150 338 } 151 /*the below define avoid a "condition always false" on some compilers*/152 339 else 153 340 { 154 /*Codes_SRS_BLOB_02_017: [ Blob_UploadMultipleBlocksFromSasUri shall copy from SASURI the hostname to a new const char* ]*/ 155 /*to find the hostname, the following logic is applied:*/ 156 /*the hostname starts at the first character after "://"*/ 157 /*the hostname ends at the first character before the next "/" after "://"*/ 158 const char* hostnameBegin = strstr(SASURI, "://"); 159 if (hostnameBegin == NULL) 160 { 161 /*Codes_SRS_BLOB_02_005: [ If the hostname cannot be determined, then Blob_UploadMultipleBlocksFromSasUri shall fail and return BLOB_INVALID_ARG. ]*/ 162 LogError("hostname cannot be determined"); 163 result = BLOB_INVALID_ARG; 341 size_t hostnameSize = relativePath - hostnameBegin; 342 if ((hostname = (char*)malloc(hostnameSize + 1)) == NULL) 343 { 344 /*Codes_SRS_BLOB_02_016: [ If the hostname copy cannot be made then then Blob_UploadMultipleBlocksFromSasUri shall fail and return BLOB_ERROR ]*/ 345 LogError("oom - out of memory"); 346 result = BLOB_ERROR; 164 347 } 165 348 else 166 349 { 167 hostnameBegin += 3; /*have to skip 3 characters which are "://"*/ 168 const char* hostnameEnd = strchr(hostnameBegin, '/'); 169 if (hostnameEnd == NULL) 170 { 171 /*Codes_SRS_BLOB_02_005: [ If the hostname cannot be determined, then Blob_UploadMultipleBlocksFromSasUri shall fail and return BLOB_INVALID_ARG. ]*/ 172 LogError("hostname cannot be determined"); 173 result = BLOB_INVALID_ARG; 174 } 175 else 176 { 177 size_t hostnameSize = hostnameEnd - hostnameBegin; 178 char* hostname = (char*)malloc(hostnameSize + 1); /*+1 because of '\0' at the end*/ 179 if (hostname == NULL) 180 { 181 /*Codes_SRS_BLOB_02_016: [ If the hostname copy cannot be made then then Blob_UploadMultipleBlocksFromSasUri shall fail and return BLOB_ERROR ]*/ 182 LogError("oom - out of memory"); 183 result = BLOB_ERROR; 184 } 185 else 186 { 187 HTTPAPIEX_HANDLE httpApiExHandle; 188 (void)memcpy(hostname, hostnameBegin, hostnameSize); 189 hostname[hostnameSize] = '\0'; 190 191 /*Codes_SRS_BLOB_02_018: [ Blob_UploadMultipleBlocksFromSasUri shall create a new HTTPAPI_EX_HANDLE by calling HTTPAPIEX_Create passing the hostname. ]*/ 192 httpApiExHandle = HTTPAPIEX_Create(hostname); 193 if (httpApiExHandle == NULL) 194 { 195 /*Codes_SRS_BLOB_02_007: [ If HTTPAPIEX_Create fails then Blob_UploadMultipleBlocksFromSasUri shall fail and return BLOB_ERROR. ]*/ 196 LogError("unable to create a HTTPAPIEX_HANDLE"); 197 result = BLOB_ERROR; 198 } 199 else 200 { 201 if ((certificates != NULL)&& (HTTPAPIEX_SetOption(httpApiExHandle, "TrustedCerts", certificates) == HTTPAPIEX_ERROR)) 202 { 203 LogError("failure in setting trusted certificates"); 204 result = BLOB_ERROR; 205 } 206 else if ((proxyOptions != NULL && proxyOptions->host_address != NULL) && HTTPAPIEX_SetOption(httpApiExHandle, OPTION_HTTP_PROXY, proxyOptions) == HTTPAPIEX_ERROR) 207 { 208 LogError("failure in setting proxy options"); 209 result = BLOB_ERROR; 210 } 211 else 212 { 213 /*Codes_SRS_BLOB_02_019: [ Blob_UploadMultipleBlocksFromSasUri shall compute the base relative path of the request from the SASURI parameter. ]*/ 214 const char* relativePath = hostnameEnd; /*this is where the relative path begins in the SasUri*/ 215 216 /*Codes_SRS_BLOB_02_028: [ Blob_UploadMultipleBlocksFromSasUri shall construct an XML string with the following content: ]*/ 217 STRING_HANDLE blockIDList = STRING_construct("<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<BlockList>"); /*the XML "build as we go"*/ 218 if (blockIDList == NULL) 219 { 220 /*Codes_SRS_BLOB_02_033: [ If any previous operation that doesn't have an explicit failure description fails then Blob_UploadMultipleBlocksFromSasUri shall fail and return BLOB_ERROR ]*/ 221 LogError("failed to STRING_construct"); 222 result = BLOB_HTTP_ERROR; 223 } 224 else 225 { 226 /*Codes_SRS_BLOB_02_021: [ For every block returned by `getDataCallbackEx` the following operations shall happen: ]*/ 227 unsigned int blockID = 0; /* incremented for each new block */ 228 unsigned int isError = 0; /* set to 1 if a block upload fails or if getDataCallbackEx returns incorrect blocks to upload */ 229 unsigned int uploadOneMoreBlock = 1; /* set to 1 while getDataCallbackEx returns correct blocks to upload */ 230 unsigned char const * source; /* data set by getDataCallbackEx */ 231 size_t size; /* source size set by getDataCallbackEx */ 232 IOTHUB_CLIENT_FILE_UPLOAD_GET_DATA_RESULT getDataReturnValue; 233 234 do 235 { 236 getDataReturnValue = getDataCallbackEx(FILE_UPLOAD_OK, &source, &size, context); 237 if (getDataReturnValue == IOTHUB_CLIENT_FILE_UPLOAD_GET_DATA_ABORT) 238 { 239 /*Codes_SRS_BLOB_99_004: [ If `getDataCallbackEx` returns `IOTHUB_CLIENT_FILE_UPLOAD_GET_DATA_RESULT_ABORT`, then `Blob_UploadMultipleBlocksFromSasUri` shall exit the loop and return `BLOB_ABORTED`. ]*/ 240 LogInfo("Upload to blob has been aborted by the user"); 241 uploadOneMoreBlock = 0; 242 result = BLOB_ABORTED; 243 } 244 else if (source == NULL || size == 0) 245 { 246 /*Codes_SRS_BLOB_99_002: [ If the size of the block returned by `getDataCallbackEx` is 0 or if the data is NULL, then `Blob_UploadMultipleBlocksFromSasUri` shall exit the loop. ]*/ 247 uploadOneMoreBlock = 0; 248 result = BLOB_OK; 249 } 250 else 251 { 252 if (size > BLOCK_SIZE) 253 { 254 /*Codes_SRS_BLOB_99_001: [ If the size of the block returned by `getDataCallbackEx` is bigger than 4MB, then `Blob_UploadMultipleBlocksFromSasUri` shall fail and return `BLOB_INVALID_ARG`. ]*/ 255 LogError("tried to upload block of size %lu, max allowed size is %d", (unsigned long)size, BLOCK_SIZE); 256 result = BLOB_INVALID_ARG; 257 isError = 1; 258 } 259 else if (blockID >= MAX_BLOCK_COUNT) 260 { 261 /*Codes_SRS_BLOB_99_003: [ If `getDataCallbackEx` returns more than 50000 blocks, then `Blob_UploadMultipleBlocksFromSasUri` shall fail and return `BLOB_INVALID_ARG`. ]*/ 262 LogError("unable to upload more than %lu blocks in one blob", (unsigned long)MAX_BLOCK_COUNT); 263 result = BLOB_INVALID_ARG; 264 isError = 1; 265 } 266 else 267 { 268 /*Codes_SRS_BLOB_02_023: [ Blob_UploadMultipleBlocksFromSasUri shall create a BUFFER_HANDLE from source and size parameters. ]*/ 269 BUFFER_HANDLE requestContent = BUFFER_create(source, size); 270 if (requestContent == NULL) 271 { 272 /*Codes_SRS_BLOB_02_033: [ If any previous operation that doesn't have an explicit failure description fails then Blob_UploadMultipleBlocksFromSasUri shall fail and return BLOB_ERROR ]*/ 273 LogError("unable to BUFFER_create"); 274 result = BLOB_ERROR; 275 isError = 1; 276 } 277 else 278 { 279 result = Blob_UploadBlock( 280 httpApiExHandle, 281 relativePath, 282 requestContent, 283 blockID, 284 blockIDList, 285 httpStatus, 286 httpResponse); 287 288 BUFFER_delete(requestContent); 289 } 290 291 /*Codes_SRS_BLOB_02_026: [ Otherwise, if HTTP response code is >=300 then Blob_UploadMultipleBlocksFromSasUri shall succeed and return BLOB_OK. ]*/ 292 if (result != BLOB_OK || *httpStatus >= 300) 293 { 294 LogError("unable to Blob_UploadBlock. Returned value=%d, httpStatus=%u", result, (unsigned int)*httpStatus); 295 isError = 1; 296 } 297 } 298 blockID++; 299 } 300 } 301 while(uploadOneMoreBlock && !isError); 302 303 if (isError || result != BLOB_OK) 304 { 305 /*do nothing, it will be reported "as is"*/ 306 } 307 else 308 { 309 /*complete the XML*/ 310 if (STRING_concat(blockIDList, "</BlockList>") != 0) 311 { 312 /*Codes_SRS_BLOB_02_033: [ If any previous operation that doesn't have an explicit failure description fails then Blob_UploadMultipleBlocksFromSasUri shall fail and return BLOB_ERROR ]*/ 313 LogError("failed to STRING_concat"); 314 result = BLOB_ERROR; 315 } 316 else 317 { 318 /*Codes_SRS_BLOB_02_029: [Blob_UploadMultipleBlocksFromSasUri shall construct a new relativePath from following string : base relativePath + "&comp=blocklist"]*/ 319 STRING_HANDLE newRelativePath = STRING_construct(relativePath); 320 if (newRelativePath == NULL) 321 { 322 /*Codes_SRS_BLOB_02_033: [ If any previous operation that doesn't have an explicit failure description fails then Blob_UploadMultipleBlocksFromSasUri shall fail and return BLOB_ERROR ]*/ 323 LogError("failed to STRING_construct"); 324 result = BLOB_ERROR; 325 } 326 else 327 { 328 if (STRING_concat(newRelativePath, "&comp=blocklist") != 0) 329 { 330 /*Codes_SRS_BLOB_02_033: [ If any previous operation that doesn't have an explicit failure description fails then Blob_UploadMultipleBlocksFromSasUri shall fail and return BLOB_ERROR ]*/ 331 LogError("failed to STRING_concat"); 332 result = BLOB_ERROR; 333 } 334 else 335 { 336 /*Codes_SRS_BLOB_02_030: [ Blob_UploadMultipleBlocksFromSasUri shall call HTTPAPIEX_ExecuteRequest with a PUT operation, passing the new relativePath, httpStatus and httpResponse and the XML string as content. ]*/ 337 const char* s = STRING_c_str(blockIDList); 338 BUFFER_HANDLE blockIDListAsBuffer = BUFFER_create((const unsigned char*)s, strlen(s)); 339 if (blockIDListAsBuffer == NULL) 340 { 341 /*Codes_SRS_BLOB_02_033: [ If any previous operation that doesn't have an explicit failure description fails then Blob_UploadMultipleBlocksFromSasUri shall fail and return BLOB_ERROR ]*/ 342 LogError("failed to BUFFER_create"); 343 result = BLOB_ERROR; 344 } 345 else 346 { 347 if (HTTPAPIEX_ExecuteRequest( 348 httpApiExHandle, 349 HTTPAPI_REQUEST_PUT, 350 STRING_c_str(newRelativePath), 351 NULL, 352 blockIDListAsBuffer, 353 httpStatus, 354 NULL, 355 httpResponse 356 ) != HTTPAPIEX_OK) 357 { 358 /*Codes_SRS_BLOB_02_031: [ If HTTPAPIEX_ExecuteRequest fails then Blob_UploadMultipleBlocksFromSasUri shall fail and return BLOB_HTTP_ERROR. ]*/ 359 LogError("unable to HTTPAPIEX_ExecuteRequest"); 360 result = BLOB_HTTP_ERROR; 361 } 362 else 363 { 364 /*Codes_SRS_BLOB_02_032: [ Otherwise, Blob_UploadMultipleBlocksFromSasUri shall succeed and return BLOB_OK. ]*/ 365 result = BLOB_OK; 366 } 367 BUFFER_delete(blockIDListAsBuffer); 368 } 369 } 370 STRING_delete(newRelativePath); 371 } 372 } 373 } 374 STRING_delete(blockIDList); 375 } 376 377 } 378 HTTPAPIEX_Destroy(httpApiExHandle); 379 } 380 free(hostname); 381 } 382 } 383 } 384 } 385 } 350 (void)memcpy(hostname, hostnameBegin, hostnameSize); 351 hostname[hostnameSize] = '\0'; 352 353 /*Codes_SRS_BLOB_02_018: [ Blob_UploadMultipleBlocksFromSasUri shall create a new HTTPAPI_EX_HANDLE by calling HTTPAPIEX_Create passing the hostname. ]*/ 354 httpApiExHandle = HTTPAPIEX_Create(hostname); 355 if (httpApiExHandle == NULL) 356 { 357 /*Codes_SRS_BLOB_02_007: [ If HTTPAPIEX_Create fails then Blob_UploadMultipleBlocksFromSasUri shall fail and return BLOB_ERROR. ]*/ 358 LogError("unable to create a HTTPAPIEX_HANDLE"); 359 result = BLOB_ERROR; 360 } 361 else if ((certificates != NULL) && (HTTPAPIEX_SetOption(httpApiExHandle, "TrustedCerts", certificates) == HTTPAPIEX_ERROR)) 362 { 363 LogError("failure in setting trusted certificates"); 364 result = BLOB_ERROR; 365 } 366 else if ((proxyOptions != NULL && proxyOptions->host_address != NULL) && HTTPAPIEX_SetOption(httpApiExHandle, OPTION_HTTP_PROXY, proxyOptions) == HTTPAPIEX_ERROR) 367 { 368 LogError("failure in setting proxy options"); 369 result = BLOB_ERROR; 370 } 371 /*Codes_SRS_BLOB_02_028: [ Blob_UploadMultipleBlocksFromSasUri shall construct an XML string with the following content: ]*/ 372 else if ((blockIDList = STRING_construct(blockListXmlBegin)) == NULL) 373 { 374 /*Codes_SRS_BLOB_02_033: [ If any previous operation that doesn't have an explicit failure description fails then Blob_UploadMultipleBlocksFromSasUri shall fail and return BLOB_ERROR ]*/ 375 LogError("failed to STRING_construct"); 376 result = BLOB_HTTP_ERROR; 377 } 378 else if ((result = InvokeUserCallbackAndSendBlobs(httpApiExHandle, relativePath, blockIDList, getDataCallbackEx, context, httpStatus, httpResponse)) != BLOB_OK) 379 { 380 LogError("Failed in invoking callback/sending blob step"); 381 } 382 else if (*httpStatus < 300) 383 { 384 // Per SRS_BLOB_02_026, it possible for us to have a result=BLOB_OK AND a non-success HTTP status code. 385 // In order to maintain back-compat with existing code, we will return the BLOB_OK to the caller but NOT invoke this final step. 386 result = SendBlockIdList(httpApiExHandle, relativePath, blockIDList, httpStatus, httpResponse); 387 } 388 } 389 } 390 } 391 392 HTTPAPIEX_Destroy(httpApiExHandle); 393 STRING_delete(blockIDList); 394 free(hostname); 395 386 396 return result; 387 397 } -
azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/src/iothub_client_authorization.c
r457 r464 31 31 char* device_id; 32 32 char* module_id; 33 size_t token_expiry_time_sec;33 uint64_t token_expiry_time_sec; 34 34 IOTHUB_CREDENTIAL_TYPE cred_type; 35 35 #ifdef USE_PROV_MODULE … … 38 38 } IOTHUB_AUTHORIZATION_DATA; 39 39 40 static int get_seconds_since_epoch( size_t* seconds)40 static int get_seconds_since_epoch(uint64_t* seconds) 41 41 { 42 42 int result; … … 49 49 else 50 50 { 51 *seconds = ( size_t)get_difftime(current_time, (time_t)0);51 *seconds = (uint64_t)get_difftime(current_time, (time_t)0); 52 52 result = 0; 53 53 } … … 384 384 } 385 385 386 char* IoTHubClient_Auth_Get_SasToken(IOTHUB_AUTHORIZATION_HANDLE handle, const char* scope, size_t expiry_time_relative_seconds, const char* key_name)386 char* IoTHubClient_Auth_Get_SasToken(IOTHUB_AUTHORIZATION_HANDLE handle, const char* scope, uint64_t expiry_time_relative_seconds, const char* key_name) 387 387 { 388 388 char* result; … … 400 400 #ifdef USE_PROV_MODULE 401 401 DEVICE_AUTH_CREDENTIAL_INFO dev_auth_cred; 402 size_t sec_since_epoch;402 uint64_t sec_since_epoch; 403 403 404 404 if (get_seconds_since_epoch(&sec_since_epoch) != 0) … … 410 410 { 411 411 memset(&dev_auth_cred, 0, sizeof(DEVICE_AUTH_CREDENTIAL_INFO)); 412 size_t expiry_time = sec_since_epoch + handle->token_expiry_time_sec;412 uint64_t expiry_time = sec_since_epoch + handle->token_expiry_time_sec; 413 413 dev_auth_cred.sas_info.expiry_seconds = expiry_time; 414 414 dev_auth_cred.sas_info.token_scope = scope; … … 465 465 { 466 466 STRING_HANDLE sas_token; 467 size_t sec_since_epoch;467 uint64_t sec_since_epoch; 468 468 469 469 /* Codes_SRS_IoTHub_Authorization_07_010: [ IoTHubClient_Auth_Get_SasToken` shall construct the expiration time using the handle->token_expiry_time_sec added to epoch time. ] */ … … 477 477 { 478 478 /* Codes_SRS_IoTHub_Authorization_07_011: [ IoTHubClient_Auth_Get_ConnString shall call SASToken_CreateString to construct the sas token. ] */ 479 size_t expiry_time = sec_since_epoch + handle->token_expiry_time_sec;479 uint64_t expiry_time = sec_since_epoch + handle->token_expiry_time_sec; 480 480 if ( (sas_token = SASToken_CreateString(handle->device_key, scope, key_name, expiry_time)) == NULL) 481 481 { … … 691 691 #endif 692 692 693 int IoTHubClient_Auth_Set_SasToken_Expiry(IOTHUB_AUTHORIZATION_HANDLE handle, size_t expiry_time_seconds)693 int IoTHubClient_Auth_Set_SasToken_Expiry(IOTHUB_AUTHORIZATION_HANDLE handle, uint64_t expiry_time_seconds) 694 694 { 695 695 int result; … … 713 713 } 714 714 715 size_t IoTHubClient_Auth_Get_SasToken_Expiry(IOTHUB_AUTHORIZATION_HANDLE handle)716 { 717 size_t result;715 uint64_t IoTHubClient_Auth_Get_SasToken_Expiry(IOTHUB_AUTHORIZATION_HANDLE handle) 716 { 717 uint64_t result; 718 718 if (handle == NULL) 719 719 { -
azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/src/iothub_client_core.c
r457 r464 26 26 27 27 #define DO_WORK_FREQ_DEFAULT 1 28 #define DO_WORK_MAXIMUM_ALLOWED_FREQUENCY 100 28 29 29 30 struct IOTHUB_QUEUE_CONTEXT_TAG; … … 1722 1723 { 1723 1724 /* Codes_SRS_IOTHUBCLIENT_41_003: [ The value for `OPTION_DO_WORK_FREQUENCY_IN_MS` shall be limited to 100 to follow SDK best practices by not reducing the DoWork frequency below 10 Hz ]*/ 1724 if (0 < * (unsigned int *)value && * (unsigned int *)value <= 100)1725 if (0 < * (unsigned int *)value && * (unsigned int *)value <= DO_WORK_MAXIMUM_ALLOWED_FREQUENCY) 1725 1726 { 1726 1727 /* Codes_SRS_IOTHUBCLIENT_41_004: [ If `currentMessageTimeout` is not greater than `do_work_freq_ms`, `IotHubClientCore_SetOption` shall return `IOTHUB_CLIENT_INVALID_ARG` ]*/ … … 1740 1741 { 1741 1742 result = IOTHUB_CLIENT_INVALID_ARG; 1742 LogError("Invalid value: OPTION_DO_WORK_FREQUENCY_IN_MS cannot exceed 100 ms. If you wish to reduce the frequency further, consider using the LL layer.");1743 LogError("Invalid value: OPTION_DO_WORK_FREQUENCY_IN_MS cannot exceed %d ms. If you wish to reduce the frequency further, consider using the LL layer.", DO_WORK_MAXIMUM_ALLOWED_FREQUENCY); 1743 1744 } 1744 1745 } -
azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/src/iothub_client_core_ll.c
r457 r464 2348 2348 else if (strcmp(optionName, OPTION_SAS_TOKEN_REFRESH_TIME) == 0 || strcmp(optionName, OPTION_SAS_TOKEN_LIFETIME) == 0) 2349 2349 { 2350 if (IoTHubClient_Auth_Set_SasToken_Expiry(handleData->authorization_module, *(size_t*)value) != 0) 2350 // API compat: while IoTHubClient_Auth_Set_SasToken_Expiry accepts uint64_t, we cannot change the public API. 2351 if (IoTHubClient_Auth_Set_SasToken_Expiry(handleData->authorization_module, (uint64_t)(*(size_t*)value)) != 0) 2351 2352 { 2352 2353 LogError("Failed setting the Token Expiry time"); -
azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/src/iothub_client_ll_uploadtoblob.c
r457 r464 437 437 else 438 438 { 439 size_t expiry = (size_t)(difftime(curr_time, 0) + 3600);439 uint64_t expiry = (uint64_t)(difftime(curr_time, 0) + 3600); 440 440 char* sas_token = IoTHubClient_Auth_Get_SasToken(upload_data->authorization_module, STRING_c_str(uri_resource), expiry, EMPTY_STRING); 441 441 if (sas_token == NULL) -
azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/src/iothub_message.c
r457 r464 34 34 IOTHUB_MESSAGE_DIAGNOSTIC_PROPERTY_DATA_HANDLE diagnosticData; 35 35 bool is_security_message; 36 char* creationTimeUtc; 37 char* userId; 36 38 }IOTHUB_MESSAGE_HANDLE_DATA; 37 39 38 static bool Contains OnlyUsAscii(const char* asciiValue)40 static bool ContainsValidUsAscii(const char* asciiValue) 39 41 { 40 42 bool result = true; … … 42 44 while (iterator != NULL && *iterator != '\0') 43 45 { 44 // Allow only printable ascii char46 // Union of all allowed ASCII characters for the different protocols (HTTPS, MQTT, AMQP) is [dec 32, dec 126]. 45 47 if (*iterator < ' ' || *iterator > '~') 46 48 { … … 50 52 iterator++; 51 53 } 52 return result; 53 } 54 55 /* Codes_SRS_IOTHUBMESSAGE_07_008: [ValidateAsciiCharactersFilter shall loop through the mapKey and mapValue strings to ensure that they only contain valid US-Ascii characters Ascii value 32 - 126.] */ 54 55 return result; 56 } 57 58 /* Codes_SRS_IOTHUBMESSAGE_07_008: [ValidateAsciiCharactersFilter shall loop through the mapKey and mapValue strings to ensure that they only contain valid US-Ascii characters.*/ 56 59 static int ValidateAsciiCharactersFilter(const char* mapKey, const char* mapValue) 57 60 { 58 61 int result; 59 if (!Contains OnlyUsAscii(mapKey) || !ContainsOnlyUsAscii(mapValue))62 if (!ContainsValidUsAscii(mapKey) || !ContainsValidUsAscii(mapValue)) 60 63 { 61 64 result = MU_FAILURE; … … 101 104 free(handleData->connectionModuleId); 102 105 free(handleData->connectionDeviceId); 106 free(handleData->creationTimeUtc); 107 free(handleData->userId); 103 108 free(handleData); 104 109 } … … 123 128 } 124 129 handleData->contentEncoding = tmp_encoding; 130 result = 0; 131 } 132 return result; 133 } 134 135 static int set_message_creation_time(IOTHUB_MESSAGE_HANDLE_DATA* handleData, const char* messageCreationTimeUtc) 136 { 137 int result; 138 char* tmp_message_creation_time; 139 140 if (handleData->creationTimeUtc != NULL) 141 { 142 free(handleData->creationTimeUtc); 143 handleData->creationTimeUtc = NULL; 144 } 145 146 if (mallocAndStrcpy_s(&tmp_message_creation_time, messageCreationTimeUtc) != 0) 147 { 148 LogError("Failed saving a copy of messageCreationTimeUtc"); 149 result = MU_FAILURE; 150 } 151 else 152 { 153 handleData->creationTimeUtc = tmp_message_creation_time; 154 result = 0; 155 } 156 return result; 157 } 158 159 static int set_message_user_id(IOTHUB_MESSAGE_HANDLE_DATA* handleData, const char* userId) 160 { 161 int result; 162 char* tmp_message_user_id; 163 164 if (handleData->userId != NULL) 165 { 166 free(handleData->userId); 167 handleData->userId = NULL; 168 } 169 170 if (mallocAndStrcpy_s(&tmp_message_user_id, userId) != 0) 171 { 172 LogError("Failed saving a copy of userId"); 173 result = MU_FAILURE; 174 } 175 else 176 { 177 handleData->userId = tmp_message_user_id; 125 178 result = 0; 126 179 } … … 349 402 result = NULL; 350 403 } 404 else if (source->creationTimeUtc != NULL && mallocAndStrcpy_s(&result->creationTimeUtc, source->creationTimeUtc) != 0) 405 { 406 LogError("unable to copy creationTimeUtc"); 407 DestroyMessageData(result); 408 result = NULL; 409 } 410 else if (source->userId != NULL && mallocAndStrcpy_s(&result->userId, source->userId) != 0) 411 { 412 LogError("unable to copy userId"); 413 DestroyMessageData(result); 414 result = NULL; 415 } 351 416 else if (source->connectionModuleId != NULL && mallocAndStrcpy_s(&result->connectionModuleId, source->connectionModuleId) != 0) 352 417 { … … 509 574 else 510 575 { 511 if (Map_AddOrUpdate(msg_handle->properties, key, value) != MAP_OK) 576 MAP_RESULT map_result = Map_AddOrUpdate(msg_handle->properties, key, value); 577 if (map_result == MAP_FILTER_REJECT) 578 { 579 LogError("Failure validating property as ASCII"); 580 result = IOTHUB_MESSAGE_INVALID_TYPE; 581 } 582 else if (map_result != MAP_OK) 512 583 { 513 584 LogError("Failure adding property to internal map"); … … 748 819 // Codes_SRS_IOTHUBMESSAGE_09_011: [IoTHubMessage_GetContentEncodingSystemProperty shall return the `contentEncoding` as a const char* ] 749 820 result = (const char*)handleData->contentEncoding; 821 } 822 823 return result; 824 } 825 826 IOTHUB_MESSAGE_RESULT IoTHubMessage_SetMessageCreationTimeUtcSystemProperty(IOTHUB_MESSAGE_HANDLE iotHubMessageHandle, const char* creationTimeUtc) 827 { 828 IOTHUB_MESSAGE_RESULT result; 829 830 if (iotHubMessageHandle == NULL || creationTimeUtc == NULL) 831 { 832 LogError("Invalid argument (iotHubMessageHandle=%p, creationTimeUtc=%p)", iotHubMessageHandle, creationTimeUtc); 833 result = IOTHUB_MESSAGE_INVALID_ARG; 834 } 835 else 836 { 837 if (set_message_creation_time(iotHubMessageHandle, creationTimeUtc) != 0) 838 { 839 LogError("Failed saving a copy of creationTimeUtc"); 840 result = IOTHUB_MESSAGE_ERROR; 841 } 842 else 843 { 844 result = IOTHUB_MESSAGE_OK; 845 } 846 } 847 return result; 848 } 849 850 const char* IoTHubMessage_GetMessageCreationTimeUtcSystemProperty(IOTHUB_MESSAGE_HANDLE iotHubMessageHandle) 851 { 852 const char* result; 853 854 if (iotHubMessageHandle == NULL) 855 { 856 LogError("Invalid argument (iotHubMessageHandle is NULL)"); 857 result = NULL; 858 } 859 else 860 { 861 IOTHUB_MESSAGE_HANDLE_DATA* handleData = iotHubMessageHandle; 862 result = (const char*)handleData->creationTimeUtc; 863 } 864 865 return result; 866 } 867 868 IOTHUB_MESSAGE_RESULT IoTHubMessage_SetMessageUserIdSystemProperty(IOTHUB_MESSAGE_HANDLE iotHubMessageHandle, const char* userId) 869 { 870 IOTHUB_MESSAGE_RESULT result; 871 872 if (iotHubMessageHandle == NULL || userId == NULL) 873 { 874 LogError("Invalid argument (iotHubMessageHandle=%p, userId=%p)", iotHubMessageHandle, userId); 875 result = IOTHUB_MESSAGE_INVALID_ARG; 876 } 877 else 878 { 879 if (set_message_user_id(iotHubMessageHandle, userId) != 0) 880 { 881 LogError("Failed saving a copy of userId"); 882 result = IOTHUB_MESSAGE_ERROR; 883 } 884 else 885 { 886 result = IOTHUB_MESSAGE_OK; 887 } 888 } 889 return result; 890 } 891 892 const char* IoTHubMessage_GetMessageUserIdSystemProperty(IOTHUB_MESSAGE_HANDLE iotHubMessageHandle) 893 { 894 const char* result; 895 896 if (iotHubMessageHandle == NULL) 897 { 898 LogError("Invalid argument (iotHubMessageHandle is NULL)"); 899 result = NULL; 900 } 901 else 902 { 903 IOTHUB_MESSAGE_HANDLE_DATA* handleData = iotHubMessageHandle; 904 result = (const char*)handleData->userId; 750 905 } 751 906 -
azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/src/iothubtransport_mqtt_common.c
r457 r464 82 82 83 83 static const char* MESSAGE_ID_PROPERTY = "mid"; 84 static const char* MESSAGE_CREATION_TIME_UTC = "ctime"; 85 static const char* MESSAGE_USER_ID = "uid"; 84 86 static const char* CORRELATION_ID_PROPERTY = "cid"; 85 87 static const char* CONTENT_TYPE_PROPERTY = "ct"; … … 200 202 MQTT_CLIENT_STATUS mqttClientStatus; 201 203 bool isDestroyCalled; 202 bool isRetryExpiredCallback Set;204 bool isRetryExpiredCallbackCalled; 203 205 bool device_twin_get_sent; 204 206 bool twin_resp_sub_recv; … … 274 276 } DEVICE_METHOD_INFO; 275 277 276 static void free_proxy_data(MQTTTRANSPORT_HANDLE_DATA* mqtt_transport_instance) 277 { 278 if (mqtt_transport_instance->http_proxy_hostname != NULL) 279 { 280 free(mqtt_transport_instance->http_proxy_hostname); 281 mqtt_transport_instance->http_proxy_hostname = NULL; 282 } 283 284 if (mqtt_transport_instance->http_proxy_username != NULL) 285 { 286 free(mqtt_transport_instance->http_proxy_username); 287 mqtt_transport_instance->http_proxy_username = NULL; 288 } 289 290 if (mqtt_transport_instance->http_proxy_password != NULL) 291 { 292 free(mqtt_transport_instance->http_proxy_password); 293 mqtt_transport_instance->http_proxy_password = NULL; 294 } 295 } 296 297 // Destroys xio transport associated with MQTT handle and resets appropriate state 278 // 279 // InternStrnicmp implements strnicmp. strnicmp isn't available on all platforms. 280 // 281 static int InternStrnicmp(const char* s1, const char* s2, size_t n) 282 { 283 int result; 284 285 if (s1 == NULL) 286 { 287 result = -1; 288 } 289 else if (s2 == NULL) 290 { 291 result = 1; 292 } 293 else 294 { 295 result = 0; 296 297 while (n-- && result == 0) 298 { 299 if (*s1 == 0) result = -1; 300 else if (*s2 == 0) result = 1; 301 else 302 { 303 304 result = TOLOWER(*s1) - TOLOWER(*s2); 305 ++s1; 306 ++s2; 307 } 308 } 309 } 310 return result; 311 } 312 313 // 314 // freeProxyData free()'s and resets proxy related settings of the mqtt_transport_instance. 315 // 316 static void freeProxyData(MQTTTRANSPORT_HANDLE_DATA* transport_data) 317 { 318 if (transport_data->http_proxy_hostname != NULL) 319 { 320 free(transport_data->http_proxy_hostname); 321 transport_data->http_proxy_hostname = NULL; 322 } 323 324 if (transport_data->http_proxy_username != NULL) 325 { 326 free(transport_data->http_proxy_username); 327 transport_data->http_proxy_username = NULL; 328 } 329 330 if (transport_data->http_proxy_password != NULL) 331 { 332 free(transport_data->http_proxy_password); 333 transport_data->http_proxy_password = NULL; 334 } 335 } 336 337 // 338 // DestroyXioTransport frees resources associated with MQTT handle and resets appropriate state 339 // 298 340 static void DestroyXioTransport(PMQTTTRANSPORT_HANDLE_DATA transport_data) 299 341 { 342 mqtt_client_clear_xio(transport_data->mqttClient); 300 343 xio_destroy(transport_data->xioTransport); 301 344 transport_data->xioTransport = NULL; 302 345 } 303 346 304 static void set_saved_tls_options(PMQTTTRANSPORT_HANDLE_DATA transport, OPTIONHANDLER_HANDLE new_options) 347 // 348 // setSavedTlsOptions saves off TLS specific options. This is used 349 // so that during a disconnection, we have these values available for next reconnection. 350 // 351 static void setSavedTlsOptions(PMQTTTRANSPORT_HANDLE_DATA transport, OPTIONHANDLER_HANDLE new_options) 305 352 { 306 353 if (transport->saved_tls_options != NULL) … … 311 358 } 312 359 313 static void free_transport_handle_data(MQTTTRANSPORT_HANDLE_DATA* transport_data) 360 // 361 // freeTransportHandleData free()'s 'the transport_data and all members that were allocated by it. 362 // 363 static void freeTransportHandleData(MQTTTRANSPORT_HANDLE_DATA* transport_data) 314 364 { 315 365 if (transport_data->mqttClient != NULL) 316 366 { 317 367 mqtt_client_deinit(transport_data->mqttClient); 368 transport_data->mqttClient = NULL; 318 369 } 319 370 … … 323 374 } 324 375 325 set _saved_tls_options(transport_data, NULL);376 setSavedTlsOptions(transport_data, NULL); 326 377 327 378 tickcounter_destroy(transport_data->msgTickCounter); 328 379 329 free _proxy_data(transport_data);380 freeProxyData(transport_data); 330 381 331 382 STRING_delete(transport_data->devicesAndModulesPath); … … 346 397 } 347 398 348 int IoTHubTransport_MQTT_Common_SetRetryPolicy(TRANSPORT_LL_HANDLE handle, IOTHUB_CLIENT_RETRY_POLICY retryPolicy, size_t retryTimeoutLimitInSeconds) 349 { 350 int result; 351 352 if (handle == NULL) 353 { 354 /* Codes_SRS_IOTHUB_TRANSPORT_MQTT_COMMON_25_041: [**If any handle is NULL then IoTHubTransport_MQTT_Common_SetRetryPolicy shall return resultant line.] */ 355 LogError("Invalid handle parameter. NULL."); 356 result = MU_FAILURE; 357 } 358 else 359 { 360 RETRY_CONTROL_HANDLE new_retry_control_handle; 361 362 // Codes_SRS_IOTHUB_TRANSPORT_MQTT_COMMON_09_006: [ IoTHubTransport_MQTT_Common_SetRetryPolicy shall set the retry logic by calling retry_control_create() with retry policy and retryTimeout as parameters] 363 // Codes_SRS_IOTHUB_TRANSPORT_MQTT_COMMON_09_009: [ If retry_control_create() fails then IoTHubTransport_MQTT_Common_SetRetryPolicy shall revert to previous retry policy and return non-zero value ] 364 if ((new_retry_control_handle = retry_control_create(retryPolicy, (unsigned int)retryTimeoutLimitInSeconds)) == NULL) 365 { 366 LogError("Failed creating new retry control handle"); 367 result = MU_FAILURE; 368 } 369 else 370 { 371 PMQTTTRANSPORT_HANDLE_DATA transport_data = (PMQTTTRANSPORT_HANDLE_DATA)handle; 372 RETRY_CONTROL_HANDLE previous_retry_control_handle = transport_data->retry_control_handle; 373 374 transport_data->retry_control_handle = new_retry_control_handle; 375 retry_control_destroy(previous_retry_control_handle); 376 377 /*Codes_SRS_IOTHUB_TRANSPORT_MQTT_COMMON_25_045: [**If retry logic for specified parameters of retry policy and retryTimeoutLimitInSeconds is created successfully then IoTHubTransport_MQTT_Common_SetRetryPolicy shall return 0]*/ 378 result = 0; 379 } 380 } 381 382 return result; 383 } 384 385 static uint16_t get_next_packet_id(PMQTTTRANSPORT_HANDLE_DATA transport_data) 399 // 400 // getNextPacketId gets the next Packet Id to use and increments internal counter. 401 // 402 static uint16_t getNextPacketId(PMQTTTRANSPORT_HANDLE_DATA transport_data) 386 403 { 387 404 if (transport_data->packetId + 1 >= USHRT_MAX) … … 397 414 398 415 #ifndef NO_LOGGING 399 static const char* retrieve_mqtt_return_codes(CONNECT_RETURN_CODE rtn_code) 416 // 417 // retrieveMqttReturnCodes returns friendly representation of connection code for logging purposes. 418 // 419 static const char* retrieveMqttReturnCodes(CONNECT_RETURN_CODE rtn_code) 400 420 { 401 421 switch (rtn_code) … … 420 440 #endif // NO_LOGGING 421 441 422 static int retrieve_device_method_rid_info(const char* resp_topic, STRING_HANDLE method_name, STRING_HANDLE request_id) 442 // 443 // retrievDeviceMethodRidInfo parses an incoming MQTT topic for a device method and retrieves the request ID it specifies. 444 // 445 static int retrievDeviceMethodRidInfo(const char* resp_topic, STRING_HANDLE method_name, STRING_HANDLE request_id) 423 446 { 424 447 int result; … … 484 507 } 485 508 486 static int parse_device_twin_topic_info(const char* resp_topic, bool* patch_msg, size_t* request_id, int* status_code) 509 // 510 // parseDeviceTwinTopicInfo parses information about a topic PUBLISH'd to this device/module. 511 // 512 static int parseDeviceTwinTopicInfo(const char* resp_topic, bool* patch_msg, size_t* request_id, int* status_code) 487 513 { 488 514 int result; … … 548 574 } 549 575 550 static int InternStrnicmp(const char* s1, const char* s2, size_t n) 551 { 552 int result; 553 554 if (s1 == NULL) result = -1; 555 else if (s2 == NULL) result = 1; 556 else 557 { 558 result = 0; 559 560 while (n-- && result == 0) 561 { 562 if (*s1 == 0) result = -1; 563 else if (*s2 == 0) result = 1; 564 else 565 { 566 567 result = TOLOWER(*s1) - TOLOWER(*s2); 568 ++s1; 569 ++s2; 570 } 571 } 572 } 573 return result; 574 } 575 576 static IOTHUB_IDENTITY_TYPE retrieve_topic_type(const char* topic_resp, const char* input_queue) 576 // 577 // retrieveTopicType translates an MQTT topic PUBLISH'd to this device/module into what type (e.g. twin, method, etc.) it represents. 578 // 579 static IOTHUB_IDENTITY_TYPE retrieveTopicType(const char* topic_resp, const char* input_queue) 577 580 { 578 581 IOTHUB_IDENTITY_TYPE type; … … 598 601 } 599 602 600 static void sendMsgComplete(IOTHUB_MESSAGE_LIST* iothubMsgList, PMQTTTRANSPORT_HANDLE_DATA transport_data, IOTHUB_CLIENT_CONFIRMATION_RESULT confirmResult) 603 // 604 // notifyApplicationOfSendMessageComplete lets application know that messages in the iothubMsgList have completed (or should be considered failed) with confirmResult status. 605 // 606 static void notifyApplicationOfSendMessageComplete(IOTHUB_MESSAGE_LIST* iothubMsgList, PMQTTTRANSPORT_HANDLE_DATA transport_data, IOTHUB_CLIENT_CONFIRMATION_RESULT confirmResult) 601 607 { 602 608 DLIST_ENTRY messageCompleted; … … 606 612 } 607 613 614 // 615 // addUserPropertiesTouMqttMessage translates application properties in iothub_message_handle (set by the application with IoTHubMessage_SetProperty e.g.) 616 // into a representation in the MQTT TOPIC topic_string. 617 // 608 618 static int addUserPropertiesTouMqttMessage(IOTHUB_MESSAGE_HANDLE iothub_message_handle, STRING_HANDLE topic_string, size_t* index_ptr, bool urlencode) 609 619 { … … 660 670 } 661 671 672 // 673 // addSystemPropertyToTopicString appends a given "system" property from iothub_message_handle (set by the application with APIs such as IoTHubMessage_SetMessageId, 674 // IoTHubMessage_SetContentTypeSystemProperty, etc.) onto the MQTT TOPIC topic_string. 675 // 662 676 static int addSystemPropertyToTopicString(STRING_HANDLE topic_string, size_t index, const char* property_key, const char* property_value, bool urlencode) 663 677 { … … 690 704 } 691 705 706 // 707 // addSystemPropertyToTopicString appends all "system" property from iothub_message_handle (set by the application with APIs such as IoTHubMessage_SetMessageId, 708 // IoTHubMessage_SetContentTypeSystemProperty, etc.) onto the MQTT TOPIC topic_string. 709 // 692 710 static int addSystemPropertiesTouMqttMessage(IOTHUB_MESSAGE_HANDLE iothub_message_handle, STRING_HANDLE topic_string, size_t* index_ptr, bool urlencode) 693 711 { … … 734 752 } 735 753 } 754 755 if (result == 0) 756 { 757 const char* message_creation_time_utc = IoTHubMessage_GetMessageCreationTimeUtcSystemProperty(iothub_message_handle); 758 if (message_creation_time_utc != NULL) 759 { 760 result = addSystemPropertyToTopicString(topic_string, index, MESSAGE_CREATION_TIME_UTC, message_creation_time_utc, urlencode); 761 index++; 762 } 763 } 764 736 765 if (result == 0) 737 766 { … … 754 783 } 755 784 785 // 786 // addDiagnosticPropertiesTouMqttMessage appends diagnostic data (as specified by IoTHubMessage_SetDiagnosticPropertyData) onto 787 // the MQTT topic topic_string. 788 // 756 789 static int addDiagnosticPropertiesTouMqttMessage(IOTHUB_MESSAGE_HANDLE iothub_message_handle, STRING_HANDLE topic_string, size_t* index_ptr) 757 790 { … … 821 854 } 822 855 823 856 // 857 // addPropertiesTouMqttMessage adds user, "system", and diagnostic messages onto MQTT topic string. Note that "system" properties is a 858 // construct of the SDK and IoT Hub. The MQTT protocol itself does not assign any significance to system and user properties (as opposed to AMQP). 859 // The IOTHUB_MESSAGE_HANDLE structure however does have well-known properties (e.g. IoTHubMessage_SetMessageId) that the SDK treats as system 860 // properties where we can automatically fill in the key value for in the key=value list. 861 // 824 862 static STRING_HANDLE addPropertiesTouMqttMessage(IOTHUB_MESSAGE_HANDLE iothub_message_handle, const char* eventTopic, bool urlencode) 825 863 { … … 868 906 } 869 907 870 static int publish_mqtt_telemetry_msg(PMQTTTRANSPORT_HANDLE_DATA transport_data, MQTT_MESSAGE_DETAILS_LIST* mqttMsgEntry, const unsigned char* payload, size_t len) 908 // 909 // publishTelemetryMsg invokes the umqtt layer to send a PUBLISH message. 910 // 911 static int publishTelemetryMsg(PMQTTTRANSPORT_HANDLE_DATA transport_data, MQTT_MESSAGE_DETAILS_LIST* mqttMsgEntry, const unsigned char* payload, size_t len) 871 912 { 872 913 int result; … … 912 953 } 913 954 914 static int publish_device_method_message(MQTTTRANSPORT_HANDLE_DATA* transport_data, int status_code, STRING_HANDLE request_id, const unsigned char* response, size_t response_size) 955 // 956 // publishDeviceMethodResponseMsg invokes the umqtt to send a PUBLISH message that contains device method call results. 957 // 958 static int publishDeviceMethodResponseMsg(MQTTTRANSPORT_HANDLE_DATA* transport_data, int status_code, STRING_HANDLE request_id, const unsigned char* response, size_t response_size) 915 959 { 916 960 int result; 917 uint16_t packet_id = get _next_packet_id(transport_data);961 uint16_t packet_id = getNextPacketId(transport_data); 918 962 919 963 STRING_HANDLE msg_topic = STRING_construct_sprintf(DEVICE_METHOD_RESPONSE_TOPIC, status_code, STRING_c_str(request_id)); … … 949 993 } 950 994 951 952 static void destroy_device_twin_get_message(MQTT_DEVICE_TWIN_ITEM* msg_entry) 995 // 996 // destroyDeviceTwinGetMsg frees msg_entry and any data associated with it. 997 // 998 static void destroyDeviceTwinGetMsg(MQTT_DEVICE_TWIN_ITEM* msg_entry) 953 999 { 954 1000 free(msg_entry); 955 1001 } 956 1002 957 static MQTT_DEVICE_TWIN_ITEM* create_device_twin_message(MQTTTRANSPORT_HANDLE_DATA* transport_data, DEVICE_TWIN_MSG_TYPE device_twin_msg_type, uint32_t iothub_msg_id) 1003 // 1004 // createDeviceTwinMsg allocates and fills in structure for MQTT_DEVICE_TWIN_ITEM. 1005 // 1006 static MQTT_DEVICE_TWIN_ITEM* createDeviceTwinMsg(MQTTTRANSPORT_HANDLE_DATA* transport_data, DEVICE_TWIN_MSG_TYPE device_twin_msg_type, uint32_t iothub_msg_id) 958 1007 { 959 1008 MQTT_DEVICE_TWIN_ITEM* result; … … 974 1023 memset(result, 0, sizeof(*result)); 975 1024 result->msgCreationTime = current_time; 976 result->packet_id = get _next_packet_id(transport_data);1025 result->packet_id = getNextPacketId(transport_data); 977 1026 result->iothub_msg_id = iothub_msg_id; 978 1027 result->device_twin_msg_type = device_twin_msg_type; … … 982 1031 } 983 1032 984 static int publish_device_twin_get_message(MQTTTRANSPORT_HANDLE_DATA* transport_data, MQTT_DEVICE_TWIN_ITEM* mqtt_info) 1033 // 1034 // publishDeviceTwinGetMsg invokes umqtt to PUBLISH a request to get the twin information. 1035 // 1036 static int publishDeviceTwinGetMsg(MQTTTRANSPORT_HANDLE_DATA* transport_data, MQTT_DEVICE_TWIN_ITEM* mqtt_info) 985 1037 { 986 1038 int result; … … 1020 1072 } 1021 1073 1074 // 1075 // sendPendingGetTwinRequests will send any queued up GetTwin requests during a DoWork loop. 1076 // 1022 1077 static void sendPendingGetTwinRequests(PMQTTTRANSPORT_HANDLE_DATA transportData) 1023 1078 { … … 1031 1086 (void)DList_RemoveEntryList(dev_twin_item); 1032 1087 1033 if (publish _device_twin_get_message(transportData, msg_entry) != 0)1088 if (publishDeviceTwinGetMsg(transportData, msg_entry) != 0) 1034 1089 { 1035 1090 LogError("Failed sending pending get twin request"); 1036 destroy _device_twin_get_message(msg_entry);1091 destroyDeviceTwinGetMsg(msg_entry); 1037 1092 } 1038 1093 else … … 1045 1100 } 1046 1101 1047 1102 // 1103 // removeExpiredTwinRequestsFromList removes any requests that have timed out. 1104 // 1048 1105 static void removeExpiredTwinRequestsFromList(PMQTTTRANSPORT_HANDLE_DATA transport_data, tickcounter_ms_t current_ms, DLIST_ENTRY* twin_list) 1049 1106 { 1050 1107 PDLIST_ENTRY list_item = twin_list->Flink; 1051 1108 1052 1109 while (list_item != twin_list) 1053 1110 { … … 1076 1133 { 1077 1134 (void)DList_RemoveEntryList(list_item); 1078 destroy _device_twin_get_message(msg_entry);1135 destroyDeviceTwinGetMsg(msg_entry); 1079 1136 } 1080 1137 … … 1084 1141 } 1085 1142 1143 // 1144 // removeExpiredTwinRequests removes any requests that have timed out, regardless of how the request invoked. 1145 // 1086 1146 static void removeExpiredTwinRequests(PMQTTTRANSPORT_HANDLE_DATA transport_data) 1087 1147 { … … 1095 1155 } 1096 1156 1097 static int publish_device_twin_message(MQTTTRANSPORT_HANDLE_DATA* transport_data, IOTHUB_DEVICE_TWIN* device_twin_info, MQTT_DEVICE_TWIN_ITEM* mqtt_info) 1157 // 1158 // publishDeviceTwinMsg invokes umqtt to PUBLISH a request for the twin. 1159 // 1160 static int publishDeviceTwinMsg(MQTTTRANSPORT_HANDLE_DATA* transport_data, IOTHUB_DEVICE_TWIN* device_twin_info, MQTT_DEVICE_TWIN_ITEM* mqtt_info) 1098 1161 { 1099 1162 int result; … … 1149 1212 } 1150 1213 1214 // 1215 // changeStateToSubscribeIfAllowed attempts to transition the state machine to subscribe, if our 1216 // current state will allow it. 1217 // This function does NOT immediately send the SUBSCRIBE however, instead setting things up 1218 // so the next time DoWork is invoked then the SUBSCRIBE will happen. 1219 // 1151 1220 static void changeStateToSubscribeIfAllowed(PMQTTTRANSPORT_HANDLE_DATA transport_data) 1152 1221 { … … 1160 1229 } 1161 1230 1231 // 1232 // subscribeToNotifyStateIfNeeded sets up to subscribe to the server. 1233 // 1162 1234 static int subscribeToNotifyStateIfNeeded(PMQTTTRANSPORT_HANDLE_DATA transport_data) 1163 1235 { … … 1191 1263 } 1192 1264 1193 1265 // 1266 // isSystemProperty returns whether a given property name in an MQTT TOPIC published to this device/module 1267 // is considered a "system". MQTT does not have a protocol defined concept of system properties. In this usage 1268 // it implies that the IOTHUB_MESSAGE_HANDLE has an API for direct manipulation of the property (e.g. IoTHubMessage_GetMessageId). 1269 // 1194 1270 static bool isSystemProperty(const char* tokenData) 1195 1271 { … … 1197 1273 size_t propCount = sizeof(sysPropList) / sizeof(sysPropList[0]); 1198 1274 size_t index = 0; 1275 size_t tokenDataLength = strlen(tokenData); 1276 1199 1277 for (index = 0; index < propCount; index++) 1200 1278 { 1201 if (memcmp(tokenData, sysPropList[index].propName, sysPropList[index].propLength) == 0) 1279 if (tokenDataLength >= sysPropList[index].propLength && 1280 memcmp(tokenData, sysPropList[index].propName, sysPropList[index].propLength) == 0) 1202 1281 { 1203 1282 result = true; … … 1208 1287 } 1209 1288 1210 // Codes_SRS_IOTHUB_TRANSPORT_MQTT_COMMON_31_061: [ If the message is sent to an input queue, `IoTHubTransport_MQTT_Common_DoWork` shall parse out to the input queue name and store it in the message with IoTHubMessage_SetInputName ] 1211 // Codes_SRS_IOTHUB_TRANSPORT_MQTT_COMMON_31_062: [ If IoTHubTransport_MQTT_Common_DoWork receives a malformatted inputQueue, it shall fail ] 1212 static int addInputNamePropertyToMessage(IOTHUB_MESSAGE_HANDLE IoTHubMessage, const char* topic_name) 1213 { 1289 // 1290 // addInputNamePropertyToMsg translates the input name (embedded in the MQTT topic name) into the IoTHubMessage handle 1291 // such that the application can call IoTHubMessage_GetInputName() to retrieve this. This is only currently used 1292 // in IoT Edge module to module message communication, so that this module receiving the message can know which module invoked in. 1293 // 1294 static int addInputNamePropertyToMsg(IOTHUB_MESSAGE_HANDLE IoTHubMessage, const char* topic_name) 1295 { 1296 // Codes_SRS_IOTHUB_TRANSPORT_MQTT_COMMON_31_061: [ If the message is sent to an input queue, `IoTHubTransport_MQTT_Common_DoWork` shall parse out to the input queue name and store it in the message with IoTHubMessage_SetInputName ] 1297 // Codes_SRS_IOTHUB_TRANSPORT_MQTT_COMMON_31_062: [ If IoTHubTransport_MQTT_Common_DoWork receives a malformatted inputQueue, it shall fail ] 1298 1214 1299 int result = MU_FAILURE; 1215 1300 int number_tokens_read = 0; … … 1261 1346 } 1262 1347 1348 // 1349 // setMqttMessagePropertyIfPossible attempts to translate a "system" property into the IOTHUB_MESSAGE_HANDLE that will be provided to the 1350 // application's callback. 1351 // 1263 1352 static int setMqttMessagePropertyIfPossible(IOTHUB_MESSAGE_HANDLE IoTHubMessage, const char* propName, const char* propValue, size_t nameLen) 1264 1353 { … … 1266 1355 int result = 0; 1267 1356 1357 if (nameLen > 5) 1358 { 1359 if (strcmp((const char*)&propName[nameLen - 5], MESSAGE_CREATION_TIME_UTC) == 0) 1360 { 1361 if (IoTHubMessage_SetMessageCreationTimeUtcSystemProperty(IoTHubMessage, propValue) != IOTHUB_MESSAGE_OK) 1362 { 1363 LogError("Failed to set IOTHUB_MESSAGE_HANDLE 'CreationTimeUtc' property."); 1364 result = MU_FAILURE; 1365 } 1366 return result; 1367 } 1368 } 1369 1268 1370 if (nameLen > 4) 1269 1371 { … … 1309 1411 return result; 1310 1412 } 1413 else if (strcmp((const char*)&propName[nameLen - 3], MESSAGE_USER_ID) == 0) 1414 { 1415 if (IoTHubMessage_SetMessageUserIdSystemProperty(IoTHubMessage, propValue) != IOTHUB_MESSAGE_OK) 1416 { 1417 LogError("Failed to set IOTHUB_MESSAGE_HANDLE 'userId' property."); 1418 result = MU_FAILURE; 1419 } 1420 return result; 1421 } 1311 1422 } 1312 1423 … … 1338 1449 } 1339 1450 1451 // 1452 // extractMqttProperties parses the MQTT topic PUBLISH'd to this device/module, retrieves properties and fills out the 1453 // IOTHUB_MESSAGE_HANDLE which will ultimately be delivered to the application callback. 1454 // 1340 1455 static int extractMqttProperties(IOTHUB_MESSAGE_HANDLE IoTHubMessage, const char* topic_name, bool urldecode) 1341 1456 { … … 1503 1618 } 1504 1619 1505 static void mqtt_notification_callback(MQTT_MESSAGE_HANDLE msgHandle, void* callbackCtx) 1506 { 1507 /* Tests_SRS_IOTHUB_MQTT_TRANSPORT_07_051: [ If msgHandle or callbackCtx is NULL, mqtt_notification_callback shall do nothing. ] */ 1508 if (msgHandle != NULL && callbackCtx != NULL) 1509 { 1510 /* Tests_SRS_IOTHUB_MQTT_TRANSPORT_07_052: [ mqtt_notification_callback shall extract the topic Name from the MQTT_MESSAGE_HANDLE. ] */ 1511 const char* topic_resp = mqttmessage_getTopicName(msgHandle); 1512 if (topic_resp == NULL) 1513 { 1514 LogError("Failure: NULL topic name encountered"); 1620 // 1621 // processTwinNotification processes device and module twin updates made by IoT Hub / IoT Edge. 1622 // 1623 static void processTwinNotification(PMQTTTRANSPORT_HANDLE_DATA transportData, MQTT_MESSAGE_HANDLE msgHandle, const char* topic_resp) 1624 { 1625 size_t request_id; 1626 int status_code; 1627 bool notification_msg; 1628 1629 if (parseDeviceTwinTopicInfo(topic_resp, ¬ification_msg, &request_id, &status_code) != 0) 1630 { 1631 LogError("Failure: parsing device topic info"); 1632 } 1633 else 1634 { 1635 const APP_PAYLOAD* payload = mqttmessage_getApplicationMsg(msgHandle); 1636 if (notification_msg) 1637 { 1638 transportData->transport_callbacks.twin_retrieve_prop_complete_cb(DEVICE_TWIN_UPDATE_PARTIAL, payload->message, payload->length, transportData->transport_ctx); 1515 1639 } 1516 1640 else 1517 1641 { 1518 PMQTTTRANSPORT_HANDLE_DATA transportData = (PMQTTTRANSPORT_HANDLE_DATA)callbackCtx; 1519 1520 IOTHUB_IDENTITY_TYPE type = retrieve_topic_type(topic_resp, STRING_c_str(transportData->topic_InputQueue)); 1521 if (type == IOTHUB_TYPE_DEVICE_TWIN) 1522 { 1523 size_t request_id; 1524 int status_code; 1525 bool notification_msg; 1526 if (parse_device_twin_topic_info(topic_resp, ¬ification_msg, &request_id, &status_code) != 0) 1527 { 1528 LogError("Failure: parsing device topic info"); 1529 } 1530 else 1531 { 1532 const APP_PAYLOAD* payload = mqttmessage_getApplicationMsg(msgHandle); 1533 if (notification_msg) 1642 PDLIST_ENTRY dev_twin_item = transportData->ack_waiting_queue.Flink; 1643 while (dev_twin_item != &transportData->ack_waiting_queue) 1644 { 1645 DLIST_ENTRY saveListEntry; 1646 saveListEntry.Flink = dev_twin_item->Flink; 1647 MQTT_DEVICE_TWIN_ITEM* msg_entry = containingRecord(dev_twin_item, MQTT_DEVICE_TWIN_ITEM, entry); 1648 if (request_id == msg_entry->packet_id) 1649 { 1650 (void)DList_RemoveEntryList(dev_twin_item); 1651 if (msg_entry->device_twin_msg_type == RETRIEVE_PROPERTIES) 1534 1652 { 1535 transportData->transport_callbacks.twin_retrieve_prop_complete_cb(DEVICE_TWIN_UPDATE_PARTIAL, payload->message, payload->length, transportData->transport_ctx); 1653 if (msg_entry->userCallback == NULL) 1654 { 1655 /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_054: [ If type is IOTHUB_TYPE_DEVICE_TWIN, then on success if msg_type is RETRIEVE_PROPERTIES then mqttNotificationCallback shall call IoTHubClientCore_LL_RetrievePropertyComplete... ] */ 1656 transportData->transport_callbacks.twin_retrieve_prop_complete_cb(DEVICE_TWIN_UPDATE_COMPLETE, payload->message, payload->length, transportData->transport_ctx); 1657 // Only after receiving device twin request should we start listening for patches. 1658 (void)subscribeToNotifyStateIfNeeded(transportData); 1659 } 1660 else 1661 { 1662 // This is a on-demand get twin request. 1663 msg_entry->userCallback(DEVICE_TWIN_UPDATE_COMPLETE, payload->message, payload->length, msg_entry->userContext); 1664 } 1536 1665 } 1537 1666 else 1538 1667 { 1539 PDLIST_ENTRY dev_twin_item = transportData->ack_waiting_queue.Flink; 1540 while (dev_twin_item != &transportData->ack_waiting_queue) 1541 { 1542 DLIST_ENTRY saveListEntry; 1543 saveListEntry.Flink = dev_twin_item->Flink; 1544 MQTT_DEVICE_TWIN_ITEM* msg_entry = containingRecord(dev_twin_item, MQTT_DEVICE_TWIN_ITEM, entry); 1545 if (request_id == msg_entry->packet_id) 1546 { 1547 (void)DList_RemoveEntryList(dev_twin_item); 1548 if (msg_entry->device_twin_msg_type == RETRIEVE_PROPERTIES) 1549 { 1550 if (msg_entry->userCallback == NULL) 1551 { 1552 /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_054: [ If type is IOTHUB_TYPE_DEVICE_TWIN, then on success if msg_type is RETRIEVE_PROPERTIES then mqtt_notification_callback shall call IoTHubClientCore_LL_RetrievePropertyComplete... ] */ 1553 transportData->transport_callbacks.twin_retrieve_prop_complete_cb(DEVICE_TWIN_UPDATE_COMPLETE, payload->message, payload->length, transportData->transport_ctx); 1554 // Only after receiving device twin request should we start listening for patches. 1555 (void)subscribeToNotifyStateIfNeeded(transportData); 1556 } 1557 else 1558 { 1559 // This is a on-demand get twin request. 1560 msg_entry->userCallback(DEVICE_TWIN_UPDATE_COMPLETE, payload->message, payload->length, msg_entry->userContext); 1561 } 1562 } 1563 else 1564 { 1565 /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_055: [ if device_twin_msg_type is not RETRIEVE_PROPERTIES then mqtt_notification_callback shall call IoTHubClientCore_LL_ReportedStateComplete ] */ 1566 transportData->transport_callbacks.twin_rpt_state_complete_cb(msg_entry->iothub_msg_id, status_code, transportData->transport_ctx); 1567 // Only after receiving device twin request should we start listening for patches. 1568 (void)subscribeToNotifyStateIfNeeded(transportData); 1569 } 1570 1571 destroy_device_twin_get_message(msg_entry); 1572 break; 1573 } 1574 dev_twin_item = saveListEntry.Flink; 1575 } 1668 /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_055: [ if device_twin_msg_type is not RETRIEVE_PROPERTIES then mqttNotificationCallback shall call IoTHubClientCore_LL_ReportedStateComplete ] */ 1669 transportData->transport_callbacks.twin_rpt_state_complete_cb(msg_entry->iothub_msg_id, status_code, transportData->transport_ctx); 1670 // Only after receiving device twin request should we start listening for patches. 1671 (void)subscribeToNotifyStateIfNeeded(transportData); 1576 1672 } 1577 } 1673 1674 destroyDeviceTwinGetMsg(msg_entry); 1675 break; 1676 } 1677 dev_twin_item = saveListEntry.Flink; 1678 } 1679 } 1680 } 1681 } 1682 1683 // 1684 // processDeviceMethodNotification processes a device and module method invocations made by IoT Hub / IoT Edge. 1685 // 1686 static void processDeviceMethodNotification(PMQTTTRANSPORT_HANDLE_DATA transportData, MQTT_MESSAGE_HANDLE msgHandle, const char* topic_resp) 1687 { 1688 STRING_HANDLE method_name = STRING_new(); 1689 if (method_name == NULL) 1690 { 1691 LogError("Failure: allocating method_name string value"); 1692 } 1693 else 1694 { 1695 DEVICE_METHOD_INFO* dev_method_info = malloc(sizeof(DEVICE_METHOD_INFO)); 1696 if (dev_method_info == NULL) 1697 { 1698 LogError("Failure: allocating DEVICE_METHOD_INFO object"); 1699 } 1700 else 1701 { 1702 dev_method_info->request_id = STRING_new(); 1703 if (dev_method_info->request_id == NULL) 1704 { 1705 LogError("Failure constructing request_id string"); 1706 free(dev_method_info); 1707 } 1708 else if (retrievDeviceMethodRidInfo(topic_resp, method_name, dev_method_info->request_id) != 0) 1709 { 1710 LogError("Failure: retrieve device topic info"); 1711 STRING_delete(dev_method_info->request_id); 1712 free(dev_method_info); 1713 } 1714 else 1715 { 1716 /* CodesSRS_IOTHUB_MQTT_TRANSPORT_07_053: [ If type is IOTHUB_TYPE_DEVICE_METHODS, then on success mqttNotificationCallback shall call IoTHubClientCore_LL_DeviceMethodComplete. ] */ 1717 const APP_PAYLOAD* payload = mqttmessage_getApplicationMsg(msgHandle); 1718 if (transportData->transport_callbacks.method_complete_cb(STRING_c_str(method_name), payload->message, payload->length, (void*)dev_method_info, transportData->transport_ctx) != 0) 1719 { 1720 LogError("Failure: IoTHubClientCore_LL_DeviceMethodComplete"); 1721 STRING_delete(dev_method_info->request_id); 1722 free(dev_method_info); 1723 } 1724 } 1725 } 1726 STRING_delete(method_name); 1727 } 1728 } 1729 1730 // 1731 // processIncomingMessageNotification processes both C2D messages and messages sent from one IoT Edge module into this module 1732 // 1733 static void processIncomingMessageNotification(PMQTTTRANSPORT_HANDLE_DATA transportData, MQTT_MESSAGE_HANDLE msgHandle, const char* topic_resp, IOTHUB_IDENTITY_TYPE type) 1734 { 1735 const APP_PAYLOAD* appPayload = mqttmessage_getApplicationMsg(msgHandle); 1736 IOTHUB_MESSAGE_HANDLE IoTHubMessage = IoTHubMessage_CreateFromByteArray(appPayload->message, appPayload->length); 1737 if (IoTHubMessage == NULL) 1738 { 1739 LogError("Failure: IotHub Message creation has failed."); 1740 } 1741 else if ((type == IOTHUB_TYPE_EVENT_QUEUE) && (addInputNamePropertyToMsg(IoTHubMessage, topic_resp) != 0)) 1742 { 1743 LogError("failure adding input name to property."); 1744 } 1745 else if (extractMqttProperties(IoTHubMessage, topic_resp, transportData->auto_url_encode_decode) != 0) 1746 { 1747 LogError("failure extracting mqtt properties."); 1748 } 1749 else 1750 { 1751 MESSAGE_CALLBACK_INFO* messageData = (MESSAGE_CALLBACK_INFO*)malloc(sizeof(MESSAGE_CALLBACK_INFO)); 1752 if (messageData == NULL) 1753 { 1754 LogError("malloc failed"); 1755 } 1756 else 1757 { 1758 messageData->messageHandle = IoTHubMessage; 1759 messageData->transportContext = NULL; 1760 1761 if (type == IOTHUB_TYPE_EVENT_QUEUE) 1762 { 1763 // Codes_SRS_IOTHUB_MQTT_TRANSPORT_31_065: [ If type is IOTHUB_TYPE_TELEMETRY and sent to an input queue, then on success `mqttNotificationCallback` shall call `IoTHubClient_LL_MessageCallback`. ] 1764 if (!transportData->transport_callbacks.msg_input_cb(messageData, transportData->transport_ctx)) 1765 { 1766 LogError("IoTHubClientCore_LL_MessageCallbackreturned false"); 1767 1768 IoTHubMessage_Destroy(IoTHubMessage); 1769 free(messageData); 1770 } 1771 } 1772 else 1773 { 1774 /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_056: [ If type is IOTHUB_TYPE_TELEMETRY, then on success mqttNotificationCallback shall call IoTHubClientCore_LL_MessageCallback. ] */ 1775 if (!transportData->transport_callbacks.msg_cb(messageData, transportData->transport_ctx)) 1776 { 1777 LogError("IoTHubClientCore_LL_MessageCallback returned false"); 1778 IoTHubMessage_Destroy(IoTHubMessage); 1779 free(messageData); 1780 } 1781 } 1782 } 1783 } 1784 } 1785 1786 // 1787 // mqttNotificationCallback processes incoming PUBLISH messages sent from Hub (or IoT Edge) to this device. 1788 // This function is invoked by umqtt. It determines what topic the PUBLISH was directed at (e.g. Device Twin, Method, etc.), 1789 // performs further parsing based on topic, and translates this call up to "iothub_client" layer for ultimate delivery to application callback. 1790 // 1791 static void mqttNotificationCallback(MQTT_MESSAGE_HANDLE msgHandle, void* callbackCtx) 1792 { 1793 /* Tests_SRS_IOTHUB_MQTT_TRANSPORT_07_051: [ If msgHandle or callbackCtx is NULL, mqttNotificationCallback shall do nothing. ] */ 1794 if (msgHandle != NULL && callbackCtx != NULL) 1795 { 1796 /* Tests_SRS_IOTHUB_MQTT_TRANSPORT_07_052: [ mqttNotificationCallback shall extract the topic Name from the MQTT_MESSAGE_HANDLE. ] */ 1797 const char* topic_resp = mqttmessage_getTopicName(msgHandle); 1798 if (topic_resp == NULL) 1799 { 1800 LogError("Failure: NULL topic name encountered"); 1801 } 1802 else 1803 { 1804 PMQTTTRANSPORT_HANDLE_DATA transportData = (PMQTTTRANSPORT_HANDLE_DATA)callbackCtx; 1805 1806 IOTHUB_IDENTITY_TYPE type = retrieveTopicType(topic_resp, STRING_c_str(transportData->topic_InputQueue)); 1807 if (type == IOTHUB_TYPE_DEVICE_TWIN) 1808 { 1809 processTwinNotification(transportData, msgHandle, topic_resp); 1578 1810 } 1579 1811 else if (type == IOTHUB_TYPE_DEVICE_METHODS) 1580 1812 { 1581 STRING_HANDLE method_name = STRING_new(); 1582 if (method_name == NULL) 1583 { 1584 LogError("Failure: allocating method_name string value"); 1585 } 1586 else 1587 { 1588 DEVICE_METHOD_INFO* dev_method_info = malloc(sizeof(DEVICE_METHOD_INFO)); 1589 if (dev_method_info == NULL) 1590 { 1591 LogError("Failure: allocating DEVICE_METHOD_INFO object"); 1592 } 1593 else 1594 { 1595 dev_method_info->request_id = STRING_new(); 1596 if (dev_method_info->request_id == NULL) 1597 { 1598 LogError("Failure constructing request_id string"); 1599 free(dev_method_info); 1600 } 1601 else if (retrieve_device_method_rid_info(topic_resp, method_name, dev_method_info->request_id) != 0) 1602 { 1603 LogError("Failure: retrieve device topic info"); 1604 STRING_delete(dev_method_info->request_id); 1605 free(dev_method_info); 1606 } 1607 else 1608 { 1609 /* CodesSRS_IOTHUB_MQTT_TRANSPORT_07_053: [ If type is IOTHUB_TYPE_DEVICE_METHODS, then on success mqtt_notification_callback shall call IoTHubClientCore_LL_DeviceMethodComplete. ] */ 1610 const APP_PAYLOAD* payload = mqttmessage_getApplicationMsg(msgHandle); 1611 if (transportData->transport_callbacks.method_complete_cb(STRING_c_str(method_name), payload->message, payload->length, (void*)dev_method_info, transportData->transport_ctx) != 0) 1612 { 1613 LogError("Failure: IoTHubClientCore_LL_DeviceMethodComplete"); 1614 STRING_delete(dev_method_info->request_id); 1615 free(dev_method_info); 1616 } 1617 } 1618 } 1619 STRING_delete(method_name); 1620 } 1813 processDeviceMethodNotification(transportData, msgHandle, topic_resp); 1621 1814 } 1622 1815 else 1623 1816 { 1624 const APP_PAYLOAD* appPayload = mqttmessage_getApplicationMsg(msgHandle); 1625 IOTHUB_MESSAGE_HANDLE IoTHubMessage = IoTHubMessage_CreateFromByteArray(appPayload->message, appPayload->length); 1626 if (IoTHubMessage == NULL) 1627 { 1628 LogError("Failure: IotHub Message creation has failed."); 1629 } 1630 else 1631 { 1632 if ((type == IOTHUB_TYPE_EVENT_QUEUE) && (addInputNamePropertyToMessage(IoTHubMessage, topic_resp) != 0)) 1633 { 1634 LogError("failure adding input name to property."); 1635 } 1636 // Will need to update this when the service has messages that can be rejected 1637 else if (extractMqttProperties(IoTHubMessage, topic_resp, transportData->auto_url_encode_decode) != 0) 1638 { 1639 LogError("failure extracting mqtt properties."); 1640 } 1641 else 1642 { 1643 MESSAGE_CALLBACK_INFO* messageData = (MESSAGE_CALLBACK_INFO*)malloc(sizeof(MESSAGE_CALLBACK_INFO)); 1644 if (messageData == NULL) 1645 { 1646 LogError("malloc failed"); 1647 } 1648 else 1649 { 1650 messageData->messageHandle = IoTHubMessage; 1651 messageData->transportContext = NULL; 1652 1653 if (type == IOTHUB_TYPE_EVENT_QUEUE) 1654 { 1655 // Codes_SRS_IOTHUB_MQTT_TRANSPORT_31_065: [ If type is IOTHUB_TYPE_TELEMETRY and sent to an input queue, then on success `mqtt_notification_callback` shall call `IoTHubClient_LL_MessageCallback`. ] 1656 if (!transportData->transport_callbacks.msg_input_cb(messageData, transportData->transport_ctx)) 1657 { 1658 LogError("IoTHubClientCore_LL_MessageCallbackreturned false"); 1659 1660 IoTHubMessage_Destroy(IoTHubMessage); 1661 free(messageData); 1662 } 1663 } 1664 else 1665 { 1666 /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_056: [ If type is IOTHUB_TYPE_TELEMETRY, then on success mqtt_notification_callback shall call IoTHubClientCore_LL_MessageCallback. ] */ 1667 if (!transportData->transport_callbacks.msg_cb(messageData, transportData->transport_ctx)) 1668 { 1669 LogError("IoTHubClientCore_LL_MessageCallback returned false"); 1670 IoTHubMessage_Destroy(IoTHubMessage); 1671 free(messageData); 1672 } 1673 } 1674 } 1675 } 1676 } 1677 } 1678 } 1679 } 1680 } 1681 1682 static void mqtt_operation_complete_callback(MQTT_CLIENT_HANDLE handle, MQTT_CLIENT_EVENT_RESULT actionResult, const void* msgInfo, void* callbackCtx) 1817 processIncomingMessageNotification(transportData, msgHandle, topic_resp, type); 1818 } 1819 } 1820 } 1821 } 1822 1823 // 1824 // mqttOperationCompleteCallback is invoked by umqtt when an operation initiated by the device completes. 1825 // Examples of device initiated operations include PUBLISH, CONNECT, and SUBSCRIBE. 1826 // 1827 static void mqttOperationCompleteCallback(MQTT_CLIENT_HANDLE handle, MQTT_CLIENT_EVENT_RESULT actionResult, const void* msgInfo, void* callbackCtx) 1683 1828 { 1684 1829 (void)handle; … … 1705 1850 { 1706 1851 (void)DList_RemoveEntryList(currentListEntry); //First remove the item from Waiting for Ack List. 1707 sendMsgComplete(mqttMsgEntry->iotHubMessageEntry, transport_data, IOTHUB_CLIENT_CONFIRMATION_OK);1852 notifyApplicationOfSendMessageComplete(mqttMsgEntry->iotHubMessageEntry, transport_data, IOTHUB_CLIENT_CONFIRMATION_OK); 1708 1853 free(mqttMsgEntry); 1709 1854 } … … 1753 1898 transport_data->isRecoverableError = false; 1754 1899 } 1755 LogError("Connection Not Accepted: 0x%x: %s", connack->returnCode, retrieve _mqtt_return_codes(connack->returnCode));1900 LogError("Connection Not Accepted: 0x%x: %s", connack->returnCode, retrieveMqttReturnCodes(connack->returnCode)); 1756 1901 transport_data->mqttClientStatus = MQTT_CLIENT_STATUS_PENDING_CLOSE; 1757 1902 transport_data->currPacketState = PACKET_TYPE_ERROR; … … 1822 1967 { 1823 1968 OPTIONHANDLER_HANDLE options = xio_retrieveoptions(transport_data->xioTransport); 1824 set _saved_tls_options(transport_data, options);1969 setSavedTlsOptions(transport_data, options); 1825 1970 DestroyXioTransport(transport_data); 1826 1971 } 1827 1972 } 1828 1973 1829 static void mqtt_disconnect_cb(void* ctx) 1974 // 1975 // processDisconnectCallback is a callback invoked by umqtt to signal that the disconnection has completed. 1976 // 1977 static void processDisconnectCallback(void* ctx) 1830 1978 { 1831 1979 if (ctx != NULL) … … 1836 1984 } 1837 1985 1986 // 1987 // DisconnectFromClient will tear down the existing MQTT connection, trying to gracefully send an MQTT DISCONNECT (with a timeout), 1988 // destroy the underlying xio for network communication, and update the transport_data state machine appropriately. 1989 // 1990 //NOTE: After a call to DisconnectFromClient, determine if appropriate to also call 1991 // transport_data->transport_callbacks.connection_status_cb(). 1838 1992 static void DisconnectFromClient(PMQTTTRANSPORT_HANDLE_DATA transport_data) 1839 1993 { … … 1843 1997 { 1844 1998 OPTIONHANDLER_HANDLE options = xio_retrieveoptions(transport_data->xioTransport); 1845 set _saved_tls_options(transport_data, options);1999 setSavedTlsOptions(transport_data, options); 1846 2000 } 1847 2001 // Ensure the disconnect message is sent … … 1849 2003 { 1850 2004 transport_data->disconnect_recv_flag = 0; 1851 (void)mqtt_client_disconnect(transport_data->mqttClient, mqtt_disconnect_cb, &transport_data->disconnect_recv_flag);2005 (void)mqtt_client_disconnect(transport_data->mqttClient, processDisconnectCallback, &transport_data->disconnect_recv_flag); 1852 2006 size_t disconnect_ctr = 0; 1853 2007 do … … 1866 2020 } 1867 2021 1868 static void mqtt_error_callback(MQTT_CLIENT_HANDLE handle, MQTT_CLIENT_EVENT_ERROR error, void* callbackCtx) 2022 // 2023 // processErrorCallback is invoked by umqtt when an error has occurred. 2024 // 2025 static void processErrorCallback(MQTT_CLIENT_HANDLE handle, MQTT_CLIENT_EVENT_ERROR error, void* callbackCtx) 1869 2026 { 1870 2027 (void)handle; … … 1935 2092 } 1936 2093 2094 // 2095 // SubscribeToMqttProtocol determines which topics we should SUBSCRIBE to, based on existing state, and then 2096 // invokes the underlying umqtt layer to send the SUBSCRIBE across the network. 2097 // 1937 2098 static void SubscribeToMqttProtocol(PMQTTTRANSPORT_HANDLE_DATA transport_data) 1938 2099 { … … 1941 2102 uint32_t topic_subscription = 0; 1942 2103 size_t subscribe_count = 0; 1943 uint16_t packet_id = get _next_packet_id(transport_data);2104 uint16_t packet_id = getNextPacketId(transport_data); 1944 2105 SUBSCRIBE_PAYLOAD subscribe[SUBSCRIBE_TOPIC_COUNT]; 1945 2106 if ((transport_data->topic_MqttMessage != NULL) && (SUBSCRIBE_TELEMETRY_TOPIC & transport_data->topics_ToSubscribe)) … … 2008 2169 } 2009 2170 2171 // 2172 // RetrieveMessagePayload translates the payload set by the application in messageHandle into payload/length for sending across the network. 2173 // 2010 2174 static bool RetrieveMessagePayload(IOTHUB_MESSAGE_HANDLE messageHandle, const unsigned char** payload, size_t* length) 2011 2175 { … … 2048 2212 } 2049 2213 2050 static void process_queued_ack_messages(PMQTTTRANSPORT_HANDLE_DATA transport_data) 2214 // 2215 // ProcessPendingTelemetryMessages examines each telemetry message the device/module has sent that hasn't yet been PUBACK'd. 2216 // For each message, it might: 2217 // * Ignore it, if its timeout has not yet been reached. 2218 // * Attempt to retry PUBLISH the message, if has remaining retries left. 2219 // * Stop attempting to send the message. This will result in tearing down the underlying MQTT/TCP connection because it indicates 2220 // something is wrong. 2221 // 2222 static void ProcessPendingTelemetryMessages(PMQTTTRANSPORT_HANDLE_DATA transport_data) 2051 2223 { 2052 2224 PDLIST_ENTRY current_entry = transport_data->telemetry_waitingForAck.Flink; … … 2063 2235 if (msg_detail_entry->retryCount >= MAX_SEND_RECOUNT_LIMIT) 2064 2236 { 2065 sendMsgComplete(msg_detail_entry->iotHubMessageEntry, transport_data, IOTHUB_CLIENT_CONFIRMATION_MESSAGE_TIMEOUT);2237 notifyApplicationOfSendMessageComplete(msg_detail_entry->iotHubMessageEntry, transport_data, IOTHUB_CLIENT_CONFIRMATION_MESSAGE_TIMEOUT); 2066 2238 (void)DList_RemoveEntryList(current_entry); 2067 2239 free(msg_detail_entry); 2068 2240 2069 2241 DisconnectFromClient(transport_data); 2242 if (!transport_data->isRetryExpiredCallbackCalled) // Only call once 2243 { 2244 transport_data->transport_callbacks.connection_status_cb(IOTHUB_CLIENT_CONNECTION_UNAUTHENTICATED, IOTHUB_CLIENT_CONNECTION_RETRY_EXPIRED, transport_data->transport_ctx); 2245 transport_data->isRetryExpiredCallbackCalled = true; 2246 } 2070 2247 } 2071 2248 else … … 2080 2257 { 2081 2258 (void)DList_RemoveEntryList(current_entry); 2082 sendMsgComplete(msg_detail_entry->iotHubMessageEntry, transport_data, IOTHUB_CLIENT_CONFIRMATION_ERROR);2259 notifyApplicationOfSendMessageComplete(msg_detail_entry->iotHubMessageEntry, transport_data, IOTHUB_CLIENT_CONFIRMATION_ERROR); 2083 2260 } 2084 2261 else 2085 2262 { 2086 if (publish _mqtt_telemetry_msg(transport_data, msg_detail_entry, messagePayload, messageLength) != 0)2263 if (publishTelemetryMsg(transport_data, msg_detail_entry, messagePayload, messageLength) != 0) 2087 2264 { 2088 2265 (void)DList_RemoveEntryList(current_entry); 2089 sendMsgComplete(msg_detail_entry->iotHubMessageEntry, transport_data, IOTHUB_CLIENT_CONFIRMATION_ERROR);2266 notifyApplicationOfSendMessageComplete(msg_detail_entry->iotHubMessageEntry, transport_data, IOTHUB_CLIENT_CONFIRMATION_ERROR); 2090 2267 free(msg_detail_entry); 2091 2268 } … … 2103 2280 } 2104 2281 2105 static int GetTransportProviderIfNecessary(PMQTTTRANSPORT_HANDLE_DATA transport_data) 2282 // 2283 // CreateTransportProviderIfNecessary will create the underlying xioTransport (which handles networking I/O) and 2284 // set its options, assuming the xioTransport does not already exist. 2285 // 2286 static int CreateTransportProviderIfNecessary(PMQTTTRANSPORT_HANDLE_DATA transport_data) 2106 2287 { 2107 2288 int result; … … 2138 2319 { 2139 2320 // The tlsio has the options, so our copy can be deleted 2140 set _saved_tls_options(transport_data, NULL);2321 setSavedTlsOptions(transport_data, NULL); 2141 2322 result = 0; 2142 2323 } … … 2167 2348 } 2168 2349 2350 // 2351 // buildClientId creates the MQTT ClientId of this device or module. 2352 // 2169 2353 static STRING_HANDLE buildClientId(const char* device_id, const char* module_id) 2170 2354 { … … 2179 2363 } 2180 2364 2365 // 2366 // buildConfigForUsernameStep2IfNeeded builds the MQTT username. IoT Hub uses the query string of the userName to optionally 2367 // specify SDK information, product information optionally specified by the application, and optionally the PnP ModelId. 2368 // 2181 2369 static int buildConfigForUsernameStep2IfNeeded(PMQTTTRANSPORT_HANDLE_DATA transport_data) 2182 2370 { … … 2191 2379 // TODO: The preview API version in SDK is only scoped to scenarios that require the modelId to be set. 2192 2380 // https://github.com/Azure/azure-iot-sdk-c/issues/1547 tracks removing this once non-preview API versions support modelId. 2193 const char* apiVersion = (modelId != NULL) ? IOTHUB_API_PREVIEW_VERSION :IOTHUB_API_VERSION;2381 const char* apiVersion = IOTHUB_API_VERSION; 2194 2382 const char* appSpecifiedProductInfo = transport_data->transport_callbacks.prod_info_cb(transport_data->transport_ctx); 2195 STRING_HANDLE productInfoEncoded = NULL; 2383 STRING_HANDLE productInfoEncoded = NULL; 2196 2384 2197 2385 if ((productInfoEncoded = URL_EncodeString((appSpecifiedProductInfo != NULL) ? appSpecifiedProductInfo : DEFAULT_IOTHUB_PRODUCT_IDENTIFIER)) == NULL) … … 2254 2442 } 2255 2443 2444 // 2445 // SendMqttConnectMsg sends the MQTT CONNECT message across the network. This function may also 2446 // perform security functionality for building up the required token (optionally invoking into DPS if configured to do so) 2447 // 2256 2448 static int SendMqttConnectMsg(PMQTTTRANSPORT_HANDLE_DATA transport_data) 2257 2449 { … … 2322 2514 options.qualityOfServiceValue = DELIVER_AT_LEAST_ONCE; 2323 2515 2324 if ( GetTransportProviderIfNecessary(transport_data) == 0)2516 if (CreateTransportProviderIfNecessary(transport_data) == 0) 2325 2517 { 2326 2518 transport_data->conn_attempted = true; … … 2333 2525 { 2334 2526 transport_data->currPacketState = CONNECT_TYPE; 2335 transport_data->isRetryExpiredCallback Set= false;2527 transport_data->isRetryExpiredCallbackCalled = false; 2336 2528 (void)tickcounter_get_current_ms(transport_data->msgTickCounter, &transport_data->mqtt_connect_time); 2337 2529 result = 0; … … 2353 2545 } 2354 2546 2355 static int InitializeConnection(PMQTTTRANSPORT_HANDLE_DATA transport_data) 2547 // 2548 // UpdateMqttConnectionStateIfNeeded is used for updating MQTT's underlying connection status during a DoWork loop. 2549 // Among this function's responsibilities: 2550 // * Attempt to establish an MQTT connection if one has not been already. 2551 // * Retries failed connection, if in the correct state. 2552 // * Processes deferred disconnect requests 2553 // * Checks timeouts, for instance on connection establishment time as well as SaS token lifetime (if SAS used) 2554 static int UpdateMqttConnectionStateIfNeeded(PMQTTTRANSPORT_HANDLE_DATA transport_data) 2356 2555 { 2357 2556 int result = 0; … … 2393 2592 { 2394 2593 // Set callback if retry expired 2395 if (!transport_data->isRetryExpiredCallback Set)2594 if (!transport_data->isRetryExpiredCallbackCalled) 2396 2595 { 2397 2596 transport_data->transport_callbacks.connection_status_cb(IOTHUB_CLIENT_CONNECTION_UNAUTHENTICATED, IOTHUB_CLIENT_CONNECTION_RETRY_EXPIRED, transport_data->transport_ctx); 2398 transport_data->isRetryExpiredCallback Set= true;2597 transport_data->isRetryExpiredCallbackCalled = true; 2399 2598 } 2400 2599 result = MU_FAILURE; … … 2443 2642 if (cred_type != IOTHUB_CREDENTIAL_TYPE_X509 && cred_type != IOTHUB_CREDENTIAL_TYPE_X509_ECC) 2444 2643 { 2445 size_t sas_token_expiry = IoTHubClient_Auth_Get_SasToken_Expiry(transport_data->authorization_module);2644 uint64_t sas_token_expiry = IoTHubClient_Auth_Get_SasToken_Expiry(transport_data->authorization_module); 2446 2645 if ((current_time - transport_data->mqtt_connect_time) / 1000 > (sas_token_expiry*SAS_REFRESH_MULTIPLIER)) 2447 2646 { … … 2494 2693 } 2495 2694 2695 // 2696 // buildMqttEventString creates the MQTT topic for this device (and optionally module) to PUBLISH telemetry to. 2697 // 2496 2698 static STRING_HANDLE buildMqttEventString(const char* device_id, const char* module_id) 2497 2699 { … … 2506 2708 } 2507 2709 2710 // 2711 // buildDevicesAndModulesPath builds the path used when generating a SaS token for this request. 2712 // 2508 2713 static STRING_HANDLE buildDevicesAndModulesPath(const IOTHUB_CLIENT_CONFIG* upperConfig, const char* moduleId) 2509 2714 { … … 2518 2723 } 2519 2724 2725 // 2726 // buildTopicMqttMsg builds the MQTT topic that is used for C2D messages sent to a device or module-to-module messages for a module running in IoT Edge 2727 // 2728 static STRING_HANDLE buildTopicMqttMsg(const char* device_id, const char* module_id) 2729 { 2730 if (module_id == NULL) 2731 { 2732 return STRING_construct_sprintf(TOPIC_DEVICE_MSG, device_id); 2733 } 2734 else 2735 { 2736 return STRING_construct_sprintf(TOPIC_DEVICE_MODULE_MSG, device_id, module_id); 2737 } 2738 } 2739 2740 // 2741 // checkModuleIdsEqual verifies that module Ids coming from different upper layers are equal. 2742 // 2743 static bool checkModuleIdsEqual(const char* transportModuleId, const char* deviceModuleId) 2744 { 2745 if ((transportModuleId != NULL) && (deviceModuleId == NULL)) 2746 { 2747 return false; 2748 } 2749 else if ((transportModuleId == NULL) && (deviceModuleId != NULL)) 2750 { 2751 return false; 2752 } 2753 else if ((transportModuleId == NULL) && (deviceModuleId == NULL)) 2754 { 2755 return true; 2756 } 2757 else 2758 { 2759 return (0 == strcmp(transportModuleId, deviceModuleId)); 2760 } 2761 } 2762 2763 // 2764 // InitializeTransportHandleData creates a MQTTTRANSPORT_HANDLE_DATA. 2765 // 2520 2766 static PMQTTTRANSPORT_HANDLE_DATA InitializeTransportHandleData(const IOTHUB_CLIENT_CONFIG* upperConfig, PDLIST_ENTRY waitingToSend, IOTHUB_AUTHORIZATION_HANDLE auth_module, const char* moduleId) 2521 2767 { … … 2531 2777 { 2532 2778 LogError("Invalid Argument: iotHubName is empty"); 2533 free _transport_handle_data(state);2779 freeTransportHandleData(state); 2534 2780 state = NULL; 2535 2781 } … … 2538 2784 { 2539 2785 LogError("Failed creating default retry control"); 2540 free _transport_handle_data(state);2786 freeTransportHandleData(state); 2541 2787 state = NULL; 2542 2788 } … … 2544 2790 { 2545 2791 LogError("failure constructing device_id."); 2546 free _transport_handle_data(state);2792 freeTransportHandleData(state); 2547 2793 state = NULL; 2548 2794 } … … 2550 2796 { 2551 2797 LogError("failure constructing module_id."); 2552 free _transport_handle_data(state);2798 freeTransportHandleData(state); 2553 2799 state = NULL; 2554 2800 } … … 2556 2802 { 2557 2803 LogError("failure constructing devicesPath."); 2558 free _transport_handle_data(state);2804 freeTransportHandleData(state); 2559 2805 state = NULL; 2560 2806 } … … 2564 2810 { 2565 2811 LogError("Could not create topic_MqttEvent for MQTT"); 2566 free _transport_handle_data(state);2812 freeTransportHandleData(state); 2567 2813 state = NULL; 2568 2814 } 2569 2815 else 2570 2816 { 2571 state->mqttClient = mqtt_client_init(mqtt _notification_callback, mqtt_operation_complete_callback, state, mqtt_error_callback, state);2817 state->mqttClient = mqtt_client_init(mqttNotificationCallback, mqttOperationCompleteCallback, state, processErrorCallback, state); 2572 2818 if (state->mqttClient == NULL) 2573 2819 { 2574 2820 LogError("failure initializing mqtt client."); 2575 free _transport_handle_data(state);2821 freeTransportHandleData(state); 2576 2822 state = NULL; 2577 2823 } … … 2591 2837 { 2592 2838 LogError("failure constructing host address."); 2593 free _transport_handle_data(state);2839 freeTransportHandleData(state); 2594 2840 state = NULL; 2595 2841 } 2596 2842 else if ((state->configPassedThroughUsername = buildConfigForUsernameStep1(upperConfig, moduleId)) == NULL) 2597 2843 { 2598 free _transport_handle_data(state);2844 freeTransportHandleData(state); 2599 2845 state = NULL; 2600 2846 } … … 2617 2863 2618 2864 state->isDestroyCalled = false; 2619 state->isRetryExpiredCallback Set= false;2865 state->isRetryExpiredCallbackCalled = false; 2620 2866 state->isRegistered = false; 2621 2867 state->device_twin_get_sent = false; … … 2641 2887 } 2642 2888 2889 // 2890 // ProcessSubackDoWork processes state transitions responding to a SUBACK packet. 2891 // This does NOT occur once we receive the SUBACK packet immediately; instead the work is 2892 // deferred to the DoWork loop. 2893 // 2894 static void ProcessSubackDoWork(PMQTTTRANSPORT_HANDLE_DATA transport_data) 2895 { 2896 if ((transport_data->topic_NotifyState != NULL || transport_data->topic_GetState != NULL) && 2897 !transport_data->device_twin_get_sent) 2898 { 2899 /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_055: [ IoTHubTransport_MQTT_Common_DoWork shall send a device twin get property message upon successfully retrieving a SUBACK on device twin topics. ] */ 2900 MQTT_DEVICE_TWIN_ITEM* mqtt_info; 2901 2902 if ((mqtt_info = createDeviceTwinMsg(transport_data, RETRIEVE_PROPERTIES, 0)) == NULL) 2903 { 2904 LogError("Failure: could not create message for twin get command"); 2905 } 2906 else if (publishDeviceTwinGetMsg(transport_data, mqtt_info) == 0) 2907 { 2908 transport_data->device_twin_get_sent = true; 2909 } 2910 else 2911 { 2912 LogError("Failure: sending device twin get command."); 2913 destroyDeviceTwinGetMsg(mqtt_info); 2914 } 2915 } 2916 2917 // Publish can be called now and in any event we need to transition out of this state. 2918 transport_data->currPacketState = PUBLISH_TYPE; 2919 } 2920 2921 // 2922 // ProcessPublishStateDoWork traverses all messages waiting to be sent and attempts to PUBLISH them. 2923 // 2924 static void ProcessPublishStateDoWork(PMQTTTRANSPORT_HANDLE_DATA transport_data) 2925 { 2926 PDLIST_ENTRY currentListEntry = transport_data->waitingToSend->Flink; 2927 /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_027: [IoTHubTransport_MQTT_Common_DoWork shall inspect the "waitingToSend" DLIST passed in config structure.] */ 2928 while (currentListEntry != transport_data->waitingToSend) 2929 { 2930 IOTHUB_MESSAGE_LIST* iothubMsgList = containingRecord(currentListEntry, IOTHUB_MESSAGE_LIST, entry); 2931 DLIST_ENTRY savedFromCurrentListEntry; 2932 savedFromCurrentListEntry.Flink = currentListEntry->Flink; 2933 2934 /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_027: [IoTHubTransport_MQTT_Common_DoWork shall inspect the "waitingToSend" DLIST passed in config structure.] */ 2935 size_t messageLength; 2936 const unsigned char* messagePayload = NULL; 2937 if (!RetrieveMessagePayload(iothubMsgList->messageHandle, &messagePayload, &messageLength)) 2938 { 2939 (void)(DList_RemoveEntryList(currentListEntry)); 2940 notifyApplicationOfSendMessageComplete(iothubMsgList, transport_data, IOTHUB_CLIENT_CONFIRMATION_ERROR); 2941 LogError("Failure result from IoTHubMessage_GetData"); 2942 } 2943 else 2944 { 2945 /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_029: [IoTHubTransport_MQTT_Common_DoWork shall create a MQTT_MESSAGE_HANDLE and pass this to a call to mqtt_client_publish.] */ 2946 MQTT_MESSAGE_DETAILS_LIST* mqttMsgEntry = (MQTT_MESSAGE_DETAILS_LIST*)malloc(sizeof(MQTT_MESSAGE_DETAILS_LIST)); 2947 if (mqttMsgEntry == NULL) 2948 { 2949 LogError("Allocation Error: Failure allocating MQTT Message Detail List."); 2950 } 2951 else 2952 { 2953 mqttMsgEntry->retryCount = 0; 2954 mqttMsgEntry->iotHubMessageEntry = iothubMsgList; 2955 mqttMsgEntry->packet_id = getNextPacketId(transport_data); 2956 if (publishTelemetryMsg(transport_data, mqttMsgEntry, messagePayload, messageLength) != 0) 2957 { 2958 (void)(DList_RemoveEntryList(currentListEntry)); 2959 notifyApplicationOfSendMessageComplete(iothubMsgList, transport_data, IOTHUB_CLIENT_CONFIRMATION_ERROR); 2960 free(mqttMsgEntry); 2961 } 2962 else 2963 { 2964 // Remove the message from the waiting queue ... 2965 (void)(DList_RemoveEntryList(currentListEntry)); 2966 // and add it to the ack queue 2967 DList_InsertTailList(&(transport_data->telemetry_waitingForAck), &(mqttMsgEntry->entry)); 2968 } 2969 } 2970 } 2971 currentListEntry = savedFromCurrentListEntry.Flink; 2972 } 2973 2974 if (transport_data->twin_resp_sub_recv) 2975 { 2976 sendPendingGetTwinRequests(transport_data); 2977 } 2978 } 2979 2643 2980 TRANSPORT_LL_HANDLE IoTHubTransport_MQTT_Common_Create(const IOTHUBTRANSPORT_CONFIG* config, MQTT_GET_IO_TRANSPORT get_io_transport, TRANSPORT_CALLBACKS_INFO* cb_info, void* ctx) 2644 2981 { … … 2741 3078 PDLIST_ENTRY currentEntry = DList_RemoveHeadList(&transport_data->telemetry_waitingForAck); 2742 3079 MQTT_MESSAGE_DETAILS_LIST* mqttMsgEntry = containingRecord(currentEntry, MQTT_MESSAGE_DETAILS_LIST, entry); 2743 sendMsgComplete(mqttMsgEntry->iotHubMessageEntry, transport_data, IOTHUB_CLIENT_CONFIRMATION_BECAUSE_DESTROY);3080 notifyApplicationOfSendMessageComplete(mqttMsgEntry->iotHubMessageEntry, transport_data, IOTHUB_CLIENT_CONFIRMATION_BECAUSE_DESTROY); 2744 3081 free(mqttMsgEntry); 2745 3082 } … … 2758 3095 } 2759 3096 2760 destroy _device_twin_get_message(mqtt_device_twin);3097 destroyDeviceTwinGetMsg(mqtt_device_twin); 2761 3098 } 2762 3099 while (!DList_IsListEmpty(&transport_data->pending_get_twin_queue)) … … 2768 3105 mqtt_device_twin->userCallback(DEVICE_TWIN_UPDATE_COMPLETE, NULL, 0, mqtt_device_twin->userContext); 2769 3106 2770 destroy _device_twin_get_message(mqtt_device_twin);3107 destroyDeviceTwinGetMsg(mqtt_device_twin); 2771 3108 } 2772 3109 2773 3110 /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_014: [IoTHubTransport_MQTT_Common_Destroy shall free all the resources currently in use.] */ 2774 3111 /* Codes_SRS_IOTHUB_TRANSPORT_MQTT_COMMON_01_012: [ `IoTHubTransport_MQTT_Common_Destroy` shall free the stored proxy options. ]*/ 2775 free _transport_handle_data(transport_data);3112 freeTransportHandleData(transport_data); 2776 3113 } 2777 3114 } … … 2860 3197 MQTT_DEVICE_TWIN_ITEM* mqtt_info; 2861 3198 2862 if ((mqtt_info = create _device_twin_message(transport_data, RETRIEVE_PROPERTIES, 0)) == NULL)3199 if ((mqtt_info = createDeviceTwinMsg(transport_data, RETRIEVE_PROPERTIES, 0)) == NULL) 2863 3200 { 2864 3201 LogError("Failed creating the device twin get request message"); … … 2869 3206 { 2870 3207 LogError("Failed setting the get twin request enqueue time"); 2871 destroy _device_twin_get_message(mqtt_info);3208 destroyDeviceTwinGetMsg(mqtt_info); 2872 3209 // Codes_SRS_IOTHUB_MQTT_TRANSPORT_09_003: [ If any failure occurs, IoTHubTransport_MQTT_Common_GetTwinAsync shall return IOTHUB_CLIENT_ERROR ] 2873 3210 result = IOTHUB_CLIENT_ERROR; … … 2949 3286 2950 3287 /*Codes_SRS_IOTHUB_MQTT_TRANSPORT_12_011 : [IoTHubTransport_MQTT_Common_Unsubscribe_DeviceMethod shall send the unsubscribe.]*/ 2951 if (mqtt_client_unsubscribe(transport_data->mqttClient, get _next_packet_id(transport_data), unsubscribe, 1) != 0)3288 if (mqtt_client_unsubscribe(transport_data->mqttClient, getNextPacketId(transport_data), unsubscribe, 1) != 0) 2952 3289 { 2953 3290 LogError("Failure calling mqtt_client_unsubscribe"); … … 2981 3318 else 2982 3319 { 2983 if (publish _device_method_message(transport_data, status, dev_method_info->request_id, response, respSize) != 0)3320 if (publishDeviceMethodResponseMsg(transport_data, status, dev_method_info->request_id, response, respSize) != 0) 2984 3321 { 2985 3322 /* Codes_SRS_IOTHUB_TRANSPORT_MQTT_COMMON_07_051: [ If any error is encountered, IoTHubTransport_MQTT_Common_DeviceMethod_Response shall return a non-zero value. ] */ … … 3004 3341 } 3005 3342 3006 static STRING_HANDLE buildTopicMqttMessage(const char* device_id, const char* module_id)3007 {3008 if (module_id == NULL)3009 {3010 return STRING_construct_sprintf(TOPIC_DEVICE_MSG, device_id);3011 }3012 else3013 {3014 return STRING_construct_sprintf(TOPIC_DEVICE_MODULE_MSG, device_id, module_id);3015 }3016 }3017 3018 3343 int IoTHubTransport_MQTT_Common_Subscribe(TRANSPORT_LL_HANDLE handle) 3019 3344 { … … 3029 3354 { 3030 3355 /* Code_SRS_IOTHUB_MQTT_TRANSPORT_07_016: [IoTHubTransport_MQTT_Common_Subscribe shall set a flag to enable mqtt_client_subscribe to be called to subscribe to the Message Topic.] */ 3031 transport_data->topic_MqttMessage = buildTopicMqttM essage(STRING_c_str(transport_data->device_id), STRING_c_str(transport_data->module_id));3356 transport_data->topic_MqttMessage = buildTopicMqttMsg(STRING_c_str(transport_data->device_id), STRING_c_str(transport_data->module_id)); 3032 3357 if (transport_data->topic_MqttMessage == NULL) 3033 3358 { … … 3055 3380 const char* unsubscribe[1]; 3056 3381 unsubscribe[0] = STRING_c_str(transport_data->topic_MqttMessage); 3057 if (mqtt_client_unsubscribe(transport_data->mqttClient, get _next_packet_id(transport_data), unsubscribe, 1) != 0)3382 if (mqtt_client_unsubscribe(transport_data->mqttClient, getNextPacketId(transport_data), unsubscribe, 1) != 0) 3058 3383 { 3059 3384 LogError("Failure calling mqtt_client_unsubscribe"); … … 3087 3412 if (item_type == IOTHUB_TYPE_DEVICE_TWIN && transport_data->twin_resp_sub_recv) 3088 3413 { 3089 MQTT_DEVICE_TWIN_ITEM* mqtt_info = create _device_twin_message(transport_data, REPORTED_STATE, iothub_item->device_twin->item_id);3414 MQTT_DEVICE_TWIN_ITEM* mqtt_info = createDeviceTwinMsg(transport_data, REPORTED_STATE, iothub_item->device_twin->item_id); 3090 3415 if (mqtt_info == NULL) 3091 3416 { … … 3099 3424 DList_InsertTailList(&transport_data->ack_waiting_queue, &mqtt_info->entry); 3100 3425 3101 if (publish _device_twin_message(transport_data, iothub_item->device_twin, mqtt_info) != 0)3426 if (publishDeviceTwinMsg(transport_data, iothub_item->device_twin, mqtt_info) != 0) 3102 3427 { 3103 3428 DList_RemoveEntryList(&mqtt_info->entry); … … 3135 3460 if (transport_data != NULL) 3136 3461 { 3137 if ( InitializeConnection(transport_data) == 0)3462 if (UpdateMqttConnectionStateIfNeeded(transport_data) == 0) 3138 3463 { 3139 3464 if (transport_data->mqttClientStatus == MQTT_CLIENT_STATUS_PENDING_CLOSE) … … 3148 3473 else if (transport_data->currPacketState == SUBACK_TYPE) 3149 3474 { 3150 if ((transport_data->topic_NotifyState != NULL || transport_data->topic_GetState != NULL) && 3151 !transport_data->device_twin_get_sent) 3152 { 3153 /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_055: [ IoTHubTransport_MQTT_Common_DoWork shall send a device twin get property message upon successfully retrieving a SUBACK on device twin topics. ] */ 3154 MQTT_DEVICE_TWIN_ITEM* mqtt_info; 3155 3156 if ((mqtt_info = create_device_twin_message(transport_data, RETRIEVE_PROPERTIES, 0)) == NULL) 3157 { 3158 LogError("Failure: could not create message for twin get command"); 3159 } 3160 else if (publish_device_twin_get_message(transport_data, mqtt_info) == 0) 3161 { 3162 transport_data->device_twin_get_sent = true; 3163 } 3164 else 3165 { 3166 LogError("Failure: sending device twin get property command."); 3167 destroy_device_twin_get_message(mqtt_info); 3168 } 3169 } 3170 // Publish can be called now 3171 transport_data->currPacketState = PUBLISH_TYPE; 3475 ProcessSubackDoWork(transport_data); 3172 3476 } 3173 3477 else if (transport_data->currPacketState == PUBLISH_TYPE) 3174 3478 { 3175 PDLIST_ENTRY currentListEntry = transport_data->waitingToSend->Flink; 3176 /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_027: [IoTHubTransport_MQTT_Common_DoWork shall inspect the "waitingToSend" DLIST passed in config structure.] */ 3177 while (currentListEntry != transport_data->waitingToSend) 3178 { 3179 IOTHUB_MESSAGE_LIST* iothubMsgList = containingRecord(currentListEntry, IOTHUB_MESSAGE_LIST, entry); 3180 DLIST_ENTRY savedFromCurrentListEntry; 3181 savedFromCurrentListEntry.Flink = currentListEntry->Flink; 3182 3183 /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_027: [IoTHubTransport_MQTT_Common_DoWork shall inspect the "waitingToSend" DLIST passed in config structure.] */ 3184 size_t messageLength; 3185 const unsigned char* messagePayload = NULL; 3186 if (!RetrieveMessagePayload(iothubMsgList->messageHandle, &messagePayload, &messageLength)) 3187 { 3188 (void)(DList_RemoveEntryList(currentListEntry)); 3189 sendMsgComplete(iothubMsgList, transport_data, IOTHUB_CLIENT_CONFIRMATION_ERROR); 3190 LogError("Failure result from IoTHubMessage_GetData"); 3191 } 3192 else 3193 { 3194 /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_029: [IoTHubTransport_MQTT_Common_DoWork shall create a MQTT_MESSAGE_HANDLE and pass this to a call to mqtt_client_publish.] */ 3195 MQTT_MESSAGE_DETAILS_LIST* mqttMsgEntry = (MQTT_MESSAGE_DETAILS_LIST*)malloc(sizeof(MQTT_MESSAGE_DETAILS_LIST)); 3196 if (mqttMsgEntry == NULL) 3197 { 3198 LogError("Allocation Error: Failure allocating MQTT Message Detail List."); 3199 } 3200 else 3201 { 3202 mqttMsgEntry->retryCount = 0; 3203 mqttMsgEntry->iotHubMessageEntry = iothubMsgList; 3204 mqttMsgEntry->packet_id = get_next_packet_id(transport_data); 3205 if (publish_mqtt_telemetry_msg(transport_data, mqttMsgEntry, messagePayload, messageLength) != 0) 3206 { 3207 (void)(DList_RemoveEntryList(currentListEntry)); 3208 sendMsgComplete(iothubMsgList, transport_data, IOTHUB_CLIENT_CONFIRMATION_ERROR); 3209 free(mqttMsgEntry); 3210 } 3211 else 3212 { 3213 // Remove the message from the waiting queue ... 3214 (void)(DList_RemoveEntryList(currentListEntry)); 3215 // and add it to the ack queue 3216 DList_InsertTailList(&(transport_data->telemetry_waitingForAck), &(mqttMsgEntry->entry)); 3217 } 3218 } 3219 } 3220 currentListEntry = savedFromCurrentListEntry.Flink; 3221 } 3222 3223 if (transport_data->twin_resp_sub_recv) 3224 { 3225 sendPendingGetTwinRequests(transport_data); 3226 } 3479 ProcessPublishStateDoWork(transport_data); 3227 3480 } 3228 3481 /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_030: [IoTHubTransport_MQTT_Common_DoWork shall call mqtt_client_dowork everytime it is called if it is connected.] */ … … 3231 3484 3232 3485 // Check the ack messages timeouts 3233 process_queued_ack_messages(transport_data);3486 ProcessPendingTelemetryMessages(transport_data); 3234 3487 removeExpiredTwinRequests(transport_data); 3235 3488 } 3236 3489 } 3237 3490 3491 int IoTHubTransport_MQTT_Common_SetRetryPolicy(TRANSPORT_LL_HANDLE handle, IOTHUB_CLIENT_RETRY_POLICY retryPolicy, size_t retryTimeoutLimitInSeconds) 3492 { 3493 int result; 3494 3495 if (handle == NULL) 3496 { 3497 /* Codes_SRS_IOTHUB_TRANSPORT_MQTT_COMMON_25_041: [**If any handle is NULL then IoTHubTransport_MQTT_Common_SetRetryPolicy shall return resultant line.] */ 3498 LogError("Invalid handle parameter. NULL."); 3499 result = MU_FAILURE; 3500 } 3501 else 3502 { 3503 RETRY_CONTROL_HANDLE new_retry_control_handle; 3504 3505 // Codes_SRS_IOTHUB_TRANSPORT_MQTT_COMMON_09_006: [ IoTHubTransport_MQTT_Common_SetRetryPolicy shall set the retry logic by calling retry_control_create() with retry policy and retryTimeout as parameters] 3506 // Codes_SRS_IOTHUB_TRANSPORT_MQTT_COMMON_09_009: [ If retry_control_create() fails then IoTHubTransport_MQTT_Common_SetRetryPolicy shall revert to previous retry policy and return non-zero value ] 3507 if ((new_retry_control_handle = retry_control_create(retryPolicy, (unsigned int)retryTimeoutLimitInSeconds)) == NULL) 3508 { 3509 LogError("Failed creating new retry control handle"); 3510 result = MU_FAILURE; 3511 } 3512 else 3513 { 3514 PMQTTTRANSPORT_HANDLE_DATA transport_data = (PMQTTTRANSPORT_HANDLE_DATA)handle; 3515 RETRY_CONTROL_HANDLE previous_retry_control_handle = transport_data->retry_control_handle; 3516 3517 transport_data->retry_control_handle = new_retry_control_handle; 3518 retry_control_destroy(previous_retry_control_handle); 3519 3520 /*Codes_SRS_IOTHUB_TRANSPORT_MQTT_COMMON_25_045: [**If retry logic for specified parameters of retry policy and retryTimeoutLimitInSeconds is created successfully then IoTHubTransport_MQTT_Common_SetRetryPolicy shall return 0]*/ 3521 result = 0; 3522 } 3523 } 3524 3525 return result; 3526 } 3527 3528 3238 3529 IOTHUB_CLIENT_RESULT IoTHubTransport_MQTT_Common_GetSendStatus(TRANSPORT_LL_HANDLE handle, IOTHUB_CLIENT_STATUS *iotHubClientStatus) 3239 3530 { … … 3242 3533 if (handle == NULL || iotHubClientStatus == NULL) 3243 3534 { 3244 /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_023: [IoTHubTransport_MQTT_Common_GetSendStatus shall return IOTHUB_CLIENT_INVALID_ARG if called with NULL parameter.] */3245 LogError("invalid arument.");3246 result = IOTHUB_CLIENT_INVALID_ARG;3247 } 3248 else 3249 { 3250 MQTTTRANSPORT_HANDLE_DATA* handleData = (MQTTTRANSPORT_HANDLE_DATA*)handle;3251 if (!DList_IsListEmpty(handleData->waitingToSend) || !DList_IsListEmpty(&(handleData->telemetry_waitingForAck)))3252 {3253 /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_025: [IoTHubTransport_MQTT_Common_GetSendStatus shall return IOTHUB_CLIENT_OK and status IOTHUB_CLIENT_SEND_STATUS_BUSY if there are currently event items to be sent or being sent.] */3254 *iotHubClientStatus = IOTHUB_CLIENT_SEND_STATUS_BUSY;3255 }3256 else3257 {3258 /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_024: [IoTHubTransport_MQTT_Common_GetSendStatus shall return IOTHUB_CLIENT_OK and status IOTHUB_CLIENT_SEND_STATUS_IDLE if there are currently no event items to be sent or being sent.] */3259 *iotHubClientStatus = IOTHUB_CLIENT_SEND_STATUS_IDLE;3260 }3261 result = IOTHUB_CLIENT_OK;3535 /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_023: [IoTHubTransport_MQTT_Common_GetSendStatus shall return IOTHUB_CLIENT_INVALID_ARG if called with NULL parameter.] */ 3536 LogError("invalid argument."); 3537 result = IOTHUB_CLIENT_INVALID_ARG; 3538 } 3539 else 3540 { 3541 MQTTTRANSPORT_HANDLE_DATA* handleData = (MQTTTRANSPORT_HANDLE_DATA*)handle; 3542 if (!DList_IsListEmpty(handleData->waitingToSend) || !DList_IsListEmpty(&(handleData->telemetry_waitingForAck))) 3543 { 3544 /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_025: [IoTHubTransport_MQTT_Common_GetSendStatus shall return IOTHUB_CLIENT_OK and status IOTHUB_CLIENT_SEND_STATUS_BUSY if there are currently event items to be sent or being sent.] */ 3545 *iotHubClientStatus = IOTHUB_CLIENT_SEND_STATUS_BUSY; 3546 } 3547 else 3548 { 3549 /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_024: [IoTHubTransport_MQTT_Common_GetSendStatus shall return IOTHUB_CLIENT_OK and status IOTHUB_CLIENT_SEND_STATUS_IDLE if there are currently no event items to be sent or being sent.] */ 3550 *iotHubClientStatus = IOTHUB_CLIENT_SEND_STATUS_IDLE; 3551 } 3552 result = IOTHUB_CLIENT_OK; 3262 3553 } 3263 3554 return result; … … 3423 3714 { 3424 3715 /* Codes_SRS_IOTHUB_TRANSPORT_MQTT_COMMON_01_009: [ When setting the proxy options succeeds any previously saved proxy options shall be freed. ]*/ 3425 free _proxy_data(transport_data);3716 freeProxyData(transport_data); 3426 3717 3427 3718 transport_data->http_proxy_hostname = copied_proxy_hostname; … … 3443 3734 3444 3735 /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_032: [IoTHubTransport_MQTT_Common_SetOption shall pass down the option to xio_setoption if the option parameter is not a known option string for the MQTT transport.] */ 3445 if ( GetTransportProviderIfNecessary(transport_data) == 0)3736 if (CreateTransportProviderIfNecessary(transport_data) == 0) 3446 3737 { 3447 3738 if (xio_setoption(transport_data->xioTransport, option, value) == 0) … … 3462 3753 } 3463 3754 return result; 3464 }3465 3466 static bool check_module_ids_equal(const char* transportModuleId, const char* deviceModuleId)3467 {3468 if ((transportModuleId != NULL) && (deviceModuleId == NULL))3469 {3470 return false;3471 }3472 else if ((transportModuleId == NULL) && (deviceModuleId != NULL))3473 {3474 return false;3475 }3476 else if ((transportModuleId == NULL) && (deviceModuleId == NULL))3477 {3478 return true;3479 }3480 else3481 {3482 return (0 == strcmp(transportModuleId, deviceModuleId));3483 }3484 3755 } 3485 3756 … … 3519 3790 result = NULL; 3520 3791 } 3521 else if (!check _module_ids_equal(STRING_c_str(transport_data->module_id), device->moduleId))3792 else if (!checkModuleIdsEqual(STRING_c_str(transport_data->module_id), device->moduleId)) 3522 3793 { 3523 3794 LogError("IoTHubTransport_MQTT_Common_Register: moduleId does not match."); … … 3650 3921 const char* unsubscribe[1]; 3651 3922 unsubscribe[0] = STRING_c_str(transport_data->topic_InputQueue); 3652 if (mqtt_client_unsubscribe(transport_data->mqttClient, get _next_packet_id(transport_data), unsubscribe, 1) != 0)3923 if (mqtt_client_unsubscribe(transport_data->mqttClient, getNextPacketId(transport_data), unsubscribe, 1) != 0) 3653 3924 { 3654 3925 LogError("Failure calling mqtt_client_unsubscribe"); -
azure_iot_hub_f767zi/trunk/azure_iot_sdk/provisioning_client/inc/azure_prov_client/prov_client_const.h
r457 r464 5 5 #define PROV_CLIENT_CONST_H 6 6 7 #define PROV_DEVICE_CLIENT_VERSION "1. 3.8"7 #define PROV_DEVICE_CLIENT_VERSION "1.6.0" 8 8 #define PROV_GET_THROTTLE_TIME 1 9 9 #define MAX_PROV_GET_THROTTLE_TIME 5*60 -
azure_iot_hub_f767zi/trunk/azure_iot_sdk/provisioning_client/inc/azure_prov_client/prov_device_client.h
r457 r464 26 26 #include "umock_c/umock_c_prod.h" 27 27 #include "azure_macro_utils/macro_utils.h" 28 #include "azure_c_shared_utility/const_defines.h" 28 29 #include "azure_prov_client/prov_transport.h" 29 30 … … 32 33 { 33 34 #endif 35 36 static STATIC_VAR_UNUSED const char* const PROV_OPTION_DO_WORK_FREQUENCY_IN_MS = "do_work_freq_ms"; 34 37 35 38 MOCKABLE_FUNCTION(, PROV_DEVICE_HANDLE, Prov_Device_Create, const char*, uri, const char*, scope_id, PROV_DEVICE_TRANSPORT_PROVIDER_FUNCTION, protocol); -
azure_iot_hub_f767zi/trunk/azure_iot_sdk/provisioning_client/inc/azure_prov_client/prov_device_ll_client.h
r457 r464 7 7 #include "umock_c/umock_c_prod.h" 8 8 #include "azure_macro_utils/macro_utils.h" 9 #include "azure_c_shared_utility/const_defines.h" 9 10 #include "azure_prov_client/prov_transport.h" 10 11 … … 43 44 MU_DEFINE_ENUM_WITHOUT_INVALID(PROV_DEVICE_REG_STATUS, PROV_DEVICE_REG_STATUS_VALUES); 44 45 45 static const char* const PROV_REGISTRATION_ID = "registration_id";46 static const char* const PROV_OPTION_LOG_TRACE = "logtrace";47 static const char* const PROV_OPTION_TIMEOUT = "provisioning_timeout";46 static STATIC_VAR_UNUSED const char* const PROV_REGISTRATION_ID = "registration_id"; 47 static STATIC_VAR_UNUSED const char* const PROV_OPTION_LOG_TRACE = "logtrace"; 48 static STATIC_VAR_UNUSED const char* const PROV_OPTION_TIMEOUT = "provisioning_timeout"; 48 49 49 50 typedef void(*PROV_DEVICE_CLIENT_REGISTER_DEVICE_CALLBACK)(PROV_DEVICE_RESULT register_result, const char* iothub_uri, const char* device_id, void* user_context); -
azure_iot_hub_f767zi/trunk/azure_iot_sdk/provisioning_client/src/prov_device_client.c
r457 r464 15 15 16 16 #define DO_WORK_FREQ_DEFAULT 1 17 18 static const char* const OPTION_DO_WORK_FREQUENCY_IN_MS = "do_work_freq_ms";19 17 20 18 typedef struct PROV_DEVICE_INSTANCE_TAG … … 260 258 { 261 259 /* Codes_SRS_PROV_DEVICE_CLIENT_41_001: [ If parameter `optionName` is `OPTION_DO_WORK_FREQUENCY_IN_MS` then `IoTHubClientCore_SetOption` shall set `do_work_freq_ms` parameter of `prov_device_instance` ] */ 262 if (strcmp( OPTION_DO_WORK_FREQUENCY_IN_MS, optionName) == 0)260 if (strcmp(PROV_OPTION_DO_WORK_FREQUENCY_IN_MS, optionName) == 0) 263 261 { 264 262 prov_device_instance->do_work_freq_ms = *((uint16_t *)value); -
azure_iot_hub_f767zi/trunk/azure_iot_sdk/provisioning_client/src/prov_device_ll_client.c
r457 r464 93 93 TICK_COUNTER_HANDLE tick_counter; 94 94 95 tickcounter_ms_t status_throttle;95 tickcounter_ms_t last_send_time_ms; 96 96 tickcounter_ms_t timeout_value; 97 uint32_t retry_after_value;97 size_t retry_after_ms; 98 98 99 99 uint8_t prov_timeout; … … 784 784 PROV_INSTANCE_INFO* prov_info = (PROV_INSTANCE_INFO*)user_ctx; 785 785 786 prov_info->retry_after_ value = retry_interval;786 prov_info->retry_after_ms = (size_t)retry_interval * 1000; // retry_interval is in seconds. 787 787 788 788 switch (transport_status) … … 880 880 /* Codes_SRS_PROV_CLIENT_07_028: [ CLIENT_STATE_READY is the initial state after the object is created which will send a uhttp_client_open call to the http endpoint. ] */ 881 881 result->prov_state = CLIENT_STATE_READY; 882 result->retry_after_ value = PROV_GET_THROTTLE_TIME;882 result->retry_after_ms = PROV_GET_THROTTLE_TIME * 1000; 883 883 result->prov_transport_protocol = protocol(); 884 884 result->error_reason = PROV_DEVICE_RESULT_OK; … … 931 931 { 932 932 // Ensure that we are passed the throttling time and send on the first send 933 (void)tickcounter_get_current_ms(result->tick_counter, &result-> status_throttle);934 result-> status_throttle += (result->retry_after_value * 1000);933 (void)tickcounter_get_current_ms(result->tick_counter, &result->last_send_time_ms); 934 result->last_send_time_ms += result->retry_after_ms; 935 935 } 936 936 } … … 1119 1119 if (prov_info->is_connected || prov_info->prov_state == CLIENT_STATE_ERROR) 1120 1120 { 1121 tickcounter_ms_t current_time = 0; 1122 1121 1123 switch (prov_info->prov_state) 1122 1124 { 1123 1125 case CLIENT_STATE_REGISTER_SEND: 1124 /* Codes_SRS_PROV_CLIENT_07_013: [ CLIENT_STATE_REGISTER_SEND which shall construct an initial call to the service with endorsement information ] */1125 if (prov_info->prov_transport_protocol->prov_transport_register(prov_info->transport_handle, prov_transport_process_json_reply, prov_transport_create_json_payload, prov_info) != 0)1126 {1127 LogError("Failure registering device");1128 if (prov_info->error_reason == PROV_DEVICE_RESULT_OK)1129 {1130 prov_info->error_reason = PROV_DEVICE_RESULT_TRANSPORT;1131 }1132 prov_info->prov_state = CLIENT_STATE_ERROR;1133 }1134 else1135 {1136 (void)tickcounter_get_current_ms(prov_info->tick_counter, &prov_info->timeout_value);1137 prov_info->prov_state = CLIENT_STATE_REGISTER_SENT;1138 }1139 break;1140 1141 case CLIENT_STATE_STATUS_SEND:1142 {1143 tickcounter_ms_t current_time = 0;1144 1126 if (tickcounter_get_current_ms(prov_info->tick_counter, ¤t_time) != 0) 1145 1127 { … … 1150 1132 else 1151 1133 { 1152 if ((current_time - prov_info->status_throttle) / 1000 > prov_info->retry_after_value) 1134 if ((current_time - prov_info->last_send_time_ms) > prov_info->retry_after_ms) 1135 { 1136 /* Codes_SRS_PROV_CLIENT_07_013: [ CLIENT_STATE_REGISTER_SEND which shall construct an initial call to the service with endorsement information ] */ 1137 if (prov_info->prov_transport_protocol->prov_transport_register(prov_info->transport_handle, prov_transport_process_json_reply, prov_transport_create_json_payload, prov_info) != 0) 1138 { 1139 LogError("Failure registering device"); 1140 if (prov_info->error_reason == PROV_DEVICE_RESULT_OK) 1141 { 1142 prov_info->error_reason = PROV_DEVICE_RESULT_TRANSPORT; 1143 } 1144 prov_info->prov_state = CLIENT_STATE_ERROR; 1145 } 1146 else 1147 { 1148 (void)tickcounter_get_current_ms(prov_info->tick_counter, &prov_info->timeout_value); 1149 prov_info->prov_state = CLIENT_STATE_REGISTER_SENT; 1150 } 1151 prov_info->last_send_time_ms = current_time; 1152 } 1153 } 1154 break; 1155 1156 case CLIENT_STATE_STATUS_SEND: 1157 { 1158 if (tickcounter_get_current_ms(prov_info->tick_counter, ¤t_time) != 0) 1159 { 1160 LogError("Failure getting the current time"); 1161 prov_info->error_reason = PROV_DEVICE_RESULT_ERROR; 1162 prov_info->prov_state = CLIENT_STATE_ERROR; 1163 } 1164 else 1165 { 1166 if ((current_time - prov_info->last_send_time_ms) > prov_info->retry_after_ms) 1153 1167 { 1154 1168 /* Codes_SRS_PROV_CLIENT_07_026: [ Upon receiving the reply of the CLIENT_STATE_URL_REQ_SEND message from iothub_client shall process the the reply of the CLIENT_STATE_URL_REQ_SEND state ] */ … … 1172 1186 } 1173 1187 } 1174 prov_info-> status_throttle= current_time;1188 prov_info->last_send_time_ms = current_time; 1175 1189 } 1176 1190 } … … 1183 1197 if (prov_info->prov_timeout > 0) 1184 1198 { 1185 tickcounter_ms_t current_time = 0;1186 1199 (void)tickcounter_get_current_ms(prov_info->tick_counter, ¤t_time); 1187 1200 if ((current_time - prov_info->timeout_value) / 1000 > prov_info->prov_timeout) … … 1279 1292 if (value == NULL) 1280 1293 { 1281 LogError("setting proxy options");1294 LogError("setting PROV_OPTION_TIMEOUT option"); 1282 1295 result = PROV_DEVICE_RESULT_ERROR; 1283 1296 } -
azure_iot_hub_f767zi/trunk/azure_iot_sdk/provisioning_client/src/prov_transport_mqtt_common.c
r457 r464 320 320 if (memcmp(MQTT_TOPIC_STATUS_PREFIX, topic_resp, status_pos) == 0) 321 321 { 322 // If the status code is > 429 then this is a transient error322 // If the status code is >= 429 then this is a transient error 323 323 long status_code = atol(topic_resp + status_pos); 324 324 if (status_code >= PROV_STATUS_CODE_TRANSIENT_ERROR) -
azure_iot_hub_f767zi/trunk/azure_iot_sdk/umqtt/inc/azure_umqtt_c/mqtt_client.h
r457 r464 49 49 typedef void(*ON_MQTT_DISCONNECTED_CALLBACK)(void* callbackCtx); 50 50 51 MOCKABLE_FUNCTION(, void, mqtt_client_clear_xio, MQTT_CLIENT_HANDLE, handle); 51 52 MOCKABLE_FUNCTION(, MQTT_CLIENT_HANDLE, mqtt_client_init, ON_MQTT_MESSAGE_RECV_CALLBACK, msgRecv, ON_MQTT_OPERATION_CALLBACK, opCallback, void*, opCallbackCtx, ON_MQTT_ERROR_CALLBACK, onErrorCallBack, void*, errorCBCtx); 52 53 MOCKABLE_FUNCTION(, void, mqtt_client_deinit, MQTT_CLIENT_HANDLE, handle); -
azure_iot_hub_f767zi/trunk/azure_iot_sdk/umqtt/inc/azure_umqtt_c/mqttconst.h
r457 r464 33 33 DISCONNECT_TYPE, 0xE0, \ 34 34 PACKET_TYPE_ERROR, 0xE1, /* 0xE1 was assigned because ENUM_2 needs it */ \ 35 UNKNOWN_TYPE, 0xE2 /* 0xE2 was assigned because ENUM_2 needs it */ 35 UNKNOWN_TYPE, 0xE2, /* 0xE2 was assigned because ENUM_2 needs it */ \ 36 PACKET_INVALID1_TYPE, 0x00, \ 37 PACKET_INVALID2_TYPE, 0xF0 36 38 37 39 MU_DEFINE_ENUM_2(CONTROL_PACKET_TYPE, CONTROL_PACKET_TYPE_VALUES) -
azure_iot_hub_f767zi/trunk/azure_iot_sdk/umqtt/src/mqtt_client.c
r457 r464 770 770 /*Codes_SRS_MQTT_CLIENT_07_028: [If the actionResult parameter is of type CONNECT_ACK then the msgInfo value shall be a CONNECT_ACK structure.]*/ 771 771 CONNECT_ACK connack = { 0 }; 772 connack.isSessionPresent = (byteutil_readByte(&iterator) == 0x1) ? true : false; 772 if (packetLength != 2) // CONNACK payload must be only 2 bytes 773 { 774 LogError("Invalid CONNACK packet."); 775 set_error_callback(mqtt_client, MQTT_CLIENT_COMMUNICATION_ERROR); 776 break; 777 } 778 779 uint8_t connect_acknowledge_flags = byteutil_readByte(&iterator); 780 if (connect_acknowledge_flags & 0xFE) // bits 7-1 must be zero 781 { 782 LogError("Invalid CONNACK packet."); 783 set_error_callback(mqtt_client, MQTT_CLIENT_COMMUNICATION_ERROR); 784 break; 785 } 786 787 connack.isSessionPresent = (connect_acknowledge_flags == 0x1) ? true : false; 773 788 uint8_t rc = byteutil_readByte(&iterator); 774 789 connack.returnCode = … … 802 817 case PUBCOMP_TYPE: 803 818 { 819 if (packetLength != 2) // PUBXXX payload must be only 2 bytes 820 { 821 LogError("Invalid packet length."); 822 set_error_callback(mqtt_client, MQTT_CLIENT_COMMUNICATION_ERROR); 823 break; 824 } 825 804 826 /*Codes_SRS_MQTT_CLIENT_07_029: [If the actionResult parameter are of types PUBACK_TYPE, PUBREC_TYPE, PUBREL_TYPE or PUBCOMP_TYPE then the msgInfo value shall be a PUBLISH_ACK structure.]*/ 805 827 MQTT_CLIENT_EVENT_RESULT action = (packet == PUBACK_TYPE) ? MQTT_CLIENT_ON_PUBLISH_ACK : … … 876 898 { 877 899 uint8_t qosRet = byteutil_readByte(&iterator); 900 if (qosRet & 0x7C) // SUBACK QOS bits 6-2 must be zero 901 { 902 LogError("Invalid SUBACK_TYPE packet."); 903 set_error_callback(mqtt_client, MQTT_CLIENT_COMMUNICATION_ERROR); 904 break; 905 } 878 906 suback.qosReturn[suback.qosCount++] = 879 907 (qosRet <= ((uint8_t)DELIVER_EXACTLY_ONCE)) ? … … 909 937 /*Codes_SRS_MQTT_CLIENT_07_031: [If the actionResult parameter is of type UNSUBACK_TYPE then the msgInfo value shall be a UNSUBSCRIBE_ACK structure.]*/ 910 938 UNSUBSCRIBE_ACK unsuback = { 0 }; 939 if (packetLength != 2) // UNSUBACK_TYPE payload must be only 2 bytes 940 { 941 LogError("Invalid UNSUBACK packet length."); 942 set_error_callback(mqtt_client, MQTT_CLIENT_COMMUNICATION_ERROR); 943 break; 944 } 945 911 946 unsuback.packetId = byteutil_read_uint16(&iterator, packetLength); 912 947 … … 943 978 { 944 979 LogError("recvCompleteCallback context failed."); 980 } 981 } 982 983 void mqtt_client_clear_xio(MQTT_CLIENT_HANDLE handle) 984 { 985 if (handle != NULL) 986 { 987 MQTT_CLIENT *mqtt_client = (MQTT_CLIENT *)handle; 988 989 // The upstream transport handle allocates and deallocates the xio handle. 990 // The reference to that xio handle is shared between this layer (mqtt layer) 991 // and the upstream layer. The clearing done here is to signal to this layer 992 // that the handle is no longer available to be used. This is different from 993 // deiniting the mqtt client in that we do not want an entire teardown, but 994 // only a possible re-upping of the xio in the future. 995 mqtt_client->xioHandle = NULL; 945 996 } 946 997 } -
azure_iot_hub_f767zi/trunk/azure_iot_sdk/umqtt/src/mqtt_codec.c
r457 r464 568 568 } 569 569 } 570 } 571 else if (codecData->remainLenIndex == (sizeof(codecData->storeRemainLen) / sizeof(codecData->storeRemainLen[0]))) 572 { 573 // The maximum number of bytes in the Remaining Length field is four 574 // This allows applications to send Control Packets of size up to 268,435,455 (256 MB). 575 // The representation of this number on the wire is: 0xFF, 0xFF, 0xFF, 0x7F. 576 577 // The last byte has exceed the max value of 0x7F 578 LogError("MQTT packet len is invalid"); 579 result = MU_FAILURE; 570 580 } 571 581 return result; … … 1067 1077 { 1068 1078 codec_Data->currPacket = processControlPacketType(iterator, &codec_Data->headerFlags); 1079 1080 // validate packet type and invalid reserved header flags 1081 switch (codec_Data->currPacket) 1082 { 1083 case PACKET_INVALID1_TYPE: 1084 case PACKET_INVALID2_TYPE: 1085 codec_Data->currPacket = PACKET_TYPE_ERROR; 1086 result = MU_FAILURE; 1087 break; 1088 1089 case CONNECT_TYPE: 1090 case CONNACK_TYPE: 1091 case PUBACK_TYPE: 1092 case PUBREC_TYPE: 1093 case PUBCOMP_TYPE: 1094 case SUBACK_TYPE: 1095 case UNSUBACK_TYPE: 1096 case PINGREQ_TYPE: 1097 case PINGRESP_TYPE: 1098 case DISCONNECT_TYPE: 1099 if (codec_Data->headerFlags & 0x0F) // flags must be all zeros 1100 { 1101 codec_Data->currPacket = PACKET_TYPE_ERROR; 1102 result = MU_FAILURE; 1103 } 1104 break; 1105 1106 case PUBREL_TYPE: 1107 case SUBSCRIBE_TYPE: 1108 case UNSUBSCRIBE_TYPE: 1109 if ((codec_Data->headerFlags & 0x0F) != 0x02) // only bit 1 must be set 1110 { 1111 codec_Data->currPacket = PACKET_TYPE_ERROR; 1112 result = MU_FAILURE; 1113 } 1114 break; 1115 1116 case PUBLISH_TYPE: 1117 case CONTROL_PACKET_TYPE_INVALID: 1118 case PACKET_TYPE_ERROR: 1119 case UNKNOWN_TYPE: 1120 break; 1121 } 1069 1122 } 1070 1123 else … … 1078 1131 else if (codec_Data->currPacket == PINGRESP_TYPE) 1079 1132 { 1080 /* Codes_SRS_MQTT_CODEC_07_034: [Upon a constructing a complete MQTT packet mqtt_codec_bytesReceived shall call the ON_PACKET_COMPLETE_CALLBACK function.] */ 1081 completePacketData(codec_Data); 1133 // PINGRESP must not have a payload 1134 if (((int8_t*)buffer)[index] == 0) 1135 { 1136 /* Codes_SRS_MQTT_CODEC_07_034: [Upon a constructing a complete MQTT packet mqtt_codec_bytesReceived shall call the ON_PACKET_COMPLETE_CALLBACK function.] */ 1137 completePacketData(codec_Data); 1138 } 1139 else 1140 { 1141 codec_Data->currPacket = PACKET_TYPE_ERROR; 1142 result = MU_FAILURE; 1143 } 1082 1144 } 1083 1145 }
Note:
See TracChangeset
for help on using the changeset viewer.